]> err.no Git - linux-2.6/blobdiff - fs/proc/task_mmu.c
Merge branch 'upstream-net26' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik...
[linux-2.6] / fs / proc / task_mmu.c
index ae4d3f2c8cb2dc1b629e3d7e356fb269421fd47d..4206454734e09d464d34a5c5a3bd86a6b51cfa9d 100644 (file)
@@ -75,7 +75,7 @@ int task_statm(struct mm_struct *mm, int *shared, int *text,
        return mm->total_vm;
 }
 
-int proc_exe_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt)
+int proc_exe_link(struct inode *inode, struct path *path)
 {
        struct vm_area_struct * vma;
        int result = -ENOENT;
@@ -98,8 +98,8 @@ int proc_exe_link(struct inode *inode, struct dentry **dentry, struct vfsmount *
        }
 
        if (vma) {
-               *mnt = mntget(vma->vm_file->f_path.mnt);
-               *dentry = dget(vma->vm_file->f_path.dentry);
+               *path = vma->vm_file->f_path;
+               path_get(&vma->vm_file->f_path);
                result = 0;
        }
 
@@ -271,7 +271,7 @@ static int show_map(struct seq_file *m, void *v)
         */
        if (file) {
                pad_len_spaces(m, len);
-               seq_path(m, file->f_path.mnt, file->f_path.dentry, "\n");
+               seq_path(m, &file->f_path, "\n");
        } else {
                const char *name = arch_vma_name(vma);
                if (!name) {
@@ -531,7 +531,7 @@ struct pagemapread {
 #define PM_RESERVED_BITS    3
 #define PM_RESERVED_OFFSET  (64 - PM_RESERVED_BITS)
 #define PM_RESERVED_MASK    (((1LL<<PM_RESERVED_BITS)-1) << PM_RESERVED_OFFSET)
-#define PM_SPECIAL(nr)      (((nr) << PM_RESERVED_OFFSET) | PM_RESERVED_MASK)
+#define PM_SPECIAL(nr)      (((nr) << PM_RESERVED_OFFSET) & PM_RESERVED_MASK)
 #define PM_NOT_PRESENT      PM_SPECIAL(1LL)
 #define PM_SWAP             PM_SPECIAL(2LL)
 #define PM_END_OF_BUFFER    1
@@ -640,17 +640,17 @@ static ssize_t pagemap_read(struct file *file, char __user *buf,
 
        ret = -EACCES;
        if (!ptrace_may_attach(task))
-               goto out;
+               goto out_task;
 
        ret = -EINVAL;
        /* file position must be aligned */
        if (*ppos % PM_ENTRY_BYTES)
-               goto out;
+               goto out_task;
 
        ret = 0;
        mm = get_task_mm(task);
        if (!mm)
-               goto out;
+               goto out_task;
 
        ret = -ENOMEM;
        uaddr = (unsigned long)buf & PAGE_MASK;
@@ -658,7 +658,7 @@ static ssize_t pagemap_read(struct file *file, char __user *buf,
        pagecount = (PAGE_ALIGN(uend) - uaddr) / PAGE_SIZE;
        pages = kmalloc(pagecount * sizeof(struct page *), GFP_KERNEL);
        if (!pages)
-               goto out_task;
+               goto out_mm;
 
        down_read(&current->mm->mmap_sem);
        ret = get_user_pages(current, current->mm, uaddr, pagecount,
@@ -668,6 +668,12 @@ static ssize_t pagemap_read(struct file *file, char __user *buf,
        if (ret < 0)
                goto out_free;
 
+       if (ret != pagecount) {
+               pagecount = ret;
+               ret = -EFAULT;
+               goto out_pages;
+       }
+
        pm.out = buf;
        pm.end = buf + count;
 
@@ -699,15 +705,17 @@ static ssize_t pagemap_read(struct file *file, char __user *buf,
                        ret = pm.out - buf;
        }
 
+out_pages:
        for (; pagecount; pagecount--) {
                page = pages[pagecount-1];
                if (!PageReserved(page))
                        SetPageDirty(page);
                page_cache_release(page);
        }
-       mmput(mm);
 out_free:
        kfree(pages);
+out_mm:
+       mmput(mm);
 out_task:
        put_task_struct(task);
 out: