patch-2.3.27 linux/fs/proc/mem.c

Next file: linux/fs/proc/net.c
Previous file: linux/fs/proc/link.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.26/linux/fs/proc/mem.c linux/fs/proc/mem.c
@@ -1,355 +0,0 @@
-/*
- *  linux/fs/proc/mem.c
- *
- *  Copyright (C) 1991, 1992  Linus Torvalds
- */
-
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/proc_fs.h>
-#include <linux/highmem.h>
-
-#include <asm/page.h>
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/pgtable.h>
-
-/*
- * mem_write isn't really a good idea right now. It needs
- * to check a lot more: if the process we try to write to 
- * dies in the middle right now, mem_write will overwrite
- * kernel memory.. This disables it altogether.
- */
-#define mem_write NULL
-
-static int check_range(struct mm_struct * mm, unsigned long addr, int count)
-{
-	struct vm_area_struct *vma;
-	int retval;
-
-	vma = find_vma(mm, addr);
-	if (!vma)
-		return -EACCES;
-	if (vma->vm_start > addr)
-		return -EACCES;
-	if (!(vma->vm_flags & VM_READ))
-		return -EACCES;
-	while ((retval = vma->vm_end - addr) < count) {
-		struct vm_area_struct *next = vma->vm_next;
-		if (!next)
-			break;
-		if (vma->vm_end != next->vm_start)
-			break;
-		if (!(next->vm_flags & VM_READ))
-			break;
-		vma = next;
-	}
-	if (retval > count)
-		retval = count;
-	return retval;
-}
-
-static struct task_struct * get_task(int pid)
-{
-	struct task_struct * tsk = current;
-
-	if (pid != tsk->pid) {
-		tsk = find_task_by_pid(pid);
-
-		/* Allow accesses only under the same circumstances
-		 * that we would allow ptrace to work.
-		 */
-		if (tsk) {
-			if (!(tsk->flags & PF_PTRACED)
-			    || tsk->state != TASK_STOPPED
-			    || tsk->p_pptr != current)
-				tsk = NULL;
-		}
-	}
-	return tsk;
-}
-
-static ssize_t mem_read(struct file * file, char * buf,
-			size_t count, loff_t *ppos)
-{
-	struct inode * inode = file->f_dentry->d_inode;
-	pgd_t *page_dir;
-	pmd_t *page_middle;
-	pte_t pte;
-	struct page * page;
-	struct task_struct * tsk;
-	unsigned long addr;
-	unsigned long maddr; /* temporary mapped address */
-	char *tmp;
-	ssize_t scount, i;
-
-	read_lock(&tasklist_lock);
-	tsk = get_task(inode->i_ino >> 16);
-	read_unlock(&tasklist_lock);	/* FIXME: This should really be done only afetr not using tsk any more!!! */
-	if (!tsk)
-		return -ESRCH;
-	addr = *ppos;
-	scount = check_range(tsk->mm, addr, count);
-	if (scount < 0)
-		return scount;
-	tmp = buf;
-	while (scount > 0) {
-		if (signal_pending(current))
-			break;
-		page_dir = pgd_offset(tsk->mm,addr);
-		if (pgd_none(*page_dir))
-			break;
-		if (pgd_bad(*page_dir)) {
-			pgd_ERROR(*page_dir);
-			pgd_clear(page_dir);
-			break;
-		}
-		page_middle = pmd_offset(page_dir,addr);
-		if (pmd_none(*page_middle))
-			break;
-		if (pmd_bad(*page_middle)) {
-			pmd_ERROR(*page_middle);
-			pmd_clear(page_middle);
-			break;
-		}
-		pte = *pte_offset(page_middle,addr);
-		if (!pte_present(pte))
-			break;
-		page = pte_page(pte);
-		i = PAGE_SIZE-(addr & ~PAGE_MASK);
-		if (i > scount)
-			i = scount;
-		maddr = kmap(page, KM_READ);
-		copy_to_user(tmp, (char *)maddr + (addr & ~PAGE_MASK), i);
-		kunmap(maddr, KM_READ);
-		addr += i;
-		tmp += i;
-		scount -= i;
-	}
-	*ppos = addr;
-	return tmp-buf;
-}
-
-#ifndef mem_write
-
-static ssize_t mem_write(struct file * file, char * buf,
-			 size_t count, loff_t *ppos)
-{
-	struct inode * inode = file->f_dentry->d_inode;
-	pgd_t *page_dir;
-	pmd_t *page_middle;
-	pte_t pte;
-	struct page * page;
-	struct task_struct * tsk;
-	unsigned long addr;
-	unsigned long maddr; /* temporary mapped address */
-	char *tmp;
-	long i;
-
-	addr = *ppos;
-	tsk = get_task(inode->i_ino >> 16);
-	if (!tsk)
-		return -ESRCH;
-	tmp = buf;
-	while (count > 0) {
-		if (signal_pending(current))
-			break;
-		page_dir = pgd_offset(tsk,addr);
-		if (pgd_none(*page_dir))
-			break;
-		if (pgd_bad(*page_dir)) {
-			pgd_ERROR(*page_dir);
-			pgd_clear(page_dir);
-			break;
-		}
-		page_middle = pmd_offset(page_dir,addr);
-		if (pmd_none(*page_middle))
-			break;
-		if (pmd_bad(*page_middle)) {
-			pmd_ERROR(*page_middle);
-			pmd_clear(page_middle);
-			break;
-		}
-		pte = *pte_offset(page_middle,addr);
-		if (!pte_present(pte))
-			break;
-		if (!pte_write(pte))
-			break;
-		page = pte_page(pte);
-		i = PAGE_SIZE-(addr & ~PAGE_MASK);
-		if (i > count)
-			i = count;
-		maddr = kmap(page, KM_WRITE);
-		copy_from_user((char *)maddr + (addr & ~PAGE_MASK), tmp, i);
-		kunmap(maddr, KM_WRITE);
-		addr += i;
-		tmp += i;
-		count -= i;
-	}
-	*ppos = addr;
-	if (tmp != buf)
-		return tmp-buf;
-	if (signal_pending(current))
-		return -ERESTARTSYS;
-	return 0;
-}
-
-#endif
-
-static long long mem_lseek(struct file * file, long long offset, int orig)
-{
-	switch (orig) {
-		case 0:
-			file->f_pos = offset;
-			return file->f_pos;
-		case 1:
-			file->f_pos += offset;
-			return file->f_pos;
-		default:
-			return -EINVAL;
-	}
-}
-
-/*
- * This isn't really reliable by any means..
- */
-int mem_mmap(struct file * file, struct vm_area_struct * vma)
-{
-	struct task_struct *tsk;
-	pgd_t *src_dir, *dest_dir;
-	pmd_t *src_middle, *dest_middle;
-	pte_t *src_table, *dest_table;
-	unsigned long stmp, etmp, dtmp, mapnr;
-	struct vm_area_struct *src_vma = NULL;
-	struct inode *inode = file->f_dentry->d_inode;
-	
-	/* Get the source's task information */
-
-	tsk = get_task(inode->i_ino >> 16);
-
-	if (!tsk)
-		return -ESRCH;
-
-	/* Ensure that we have a valid source area.  (Has to be mmap'ed and
-	 have valid page information.)  We can't map shared memory at the
-	 moment because working out the vm_area_struct & nattach stuff isn't
-	 worth it. */
-
-	src_vma = tsk->mm->mmap;
-	stmp = vma->vm_pgoff << PAGE_SHIFT;
-	etmp = stmp + vma->vm_end - vma->vm_start;
-	while (stmp < etmp) {
-		while (src_vma && stmp > src_vma->vm_end)
-			src_vma = src_vma->vm_next;
-		if (!src_vma || (src_vma->vm_flags & VM_SHM))
-			return -EINVAL;
-
-		src_dir = pgd_offset(tsk->mm, stmp);
-		if (pgd_none(*src_dir))
-			return -EINVAL;
-		if (pgd_bad(*src_dir)) {
-			pgd_ERROR(*src_dir);
-			return -EINVAL;
-		}
-		src_middle = pmd_offset(src_dir, stmp);
-		if (pmd_none(*src_middle))
-			return -EINVAL;
-		if (pmd_bad(*src_middle)) {
-			pmd_ERROR(*src_middle);
-			return -EINVAL;
-		}
-		src_table = pte_offset(src_middle, stmp);
-		if (pte_none(*src_table))
-			return -EINVAL;
-
-		if (stmp < src_vma->vm_start) {
-			if (!(src_vma->vm_flags & VM_GROWSDOWN))
-				return -EINVAL;
-			if (src_vma->vm_end - stmp > current->rlim[RLIMIT_STACK].rlim_cur)
-				return -EINVAL;
-		}
-		stmp += PAGE_SIZE;
-	}
-
-	src_vma = tsk->mm->mmap;
-	stmp    = vma->vm_pgoff << PAGE_SHIFT;
-	dtmp    = vma->vm_start;
-
-	flush_cache_range(vma->vm_mm, vma->vm_start, vma->vm_end);
-	flush_cache_range(src_vma->vm_mm, src_vma->vm_start, src_vma->vm_end);
-	while (dtmp < vma->vm_end) {
-		while (src_vma && stmp > src_vma->vm_end)
-			src_vma = src_vma->vm_next;
-
-		src_dir = pgd_offset(tsk->mm, stmp);
-		src_middle = pmd_offset(src_dir, stmp);
-		src_table = pte_offset(src_middle, stmp);
-
-		dest_dir = pgd_offset(current->mm, dtmp);
-		dest_middle = pmd_alloc(dest_dir, dtmp);
-		if (!dest_middle)
-			return -ENOMEM;
-		dest_table = pte_alloc(dest_middle, dtmp);
-		if (!dest_table)
-			return -ENOMEM;
-
-		if (!pte_present(*src_table))
-			handle_mm_fault(tsk, src_vma, stmp, 1);
-
-		if ((vma->vm_flags & VM_WRITE) && !pte_write(*src_table))
-			handle_mm_fault(tsk, src_vma, stmp, 1);
-
-		set_pte(src_table, pte_mkdirty(*src_table));
-		set_pte(dest_table, *src_table);
-		mapnr = pte_pagenr(*src_table);
-		if (mapnr < max_mapnr)
-			get_page(mem_map + pte_pagenr(*src_table));
-
-		stmp += PAGE_SIZE;
-		dtmp += PAGE_SIZE;
-	}
-
-	flush_tlb_range(vma->vm_mm, vma->vm_start, vma->vm_end);
-	flush_tlb_range(src_vma->vm_mm, src_vma->vm_start, src_vma->vm_end);
-	return 0;
-}
-
-static struct file_operations proc_mem_operations = {
-	mem_lseek,
-	mem_read,
-	mem_write,
-	NULL,		/* mem_readdir */
-	NULL,		/* mem_poll */
-	NULL,		/* mem_ioctl */
-	mem_mmap,	/* mmap */
-	NULL,		/* no special open code */
-	NULL,		/* flush */
-	NULL,		/* no special release code */
-	NULL		/* can't fsync */
-};
-
-struct inode_operations proc_mem_inode_operations = {
-	&proc_mem_operations,	/* default base directory file-ops */
-	NULL,			/* create */
-	NULL,			/* lookup */
-	NULL,			/* link */
-	NULL,			/* unlink */
-	NULL,			/* symlink */
-	NULL,			/* mkdir */
-	NULL,			/* rmdir */
-	NULL,			/* mknod */
-	NULL,			/* rename */
-	NULL,			/* readlink */
-	NULL,			/* follow_link */
-	NULL,			/* get_block */
-	NULL,			/* readpage */
-	NULL,			/* writepage */
-	NULL,			/* flushpage */
-	NULL,			/* truncate */
-	proc_permission,	/* permission */
-	NULL,			/* smap */
-	NULL			/* revalidate */
-};

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)