xfs: prevent lockdep false positive in xfs_iget_cache_miss
[safe/jmp/linux-2.6] / fs / exec.c
index 3ef9cf9..0dd60a0 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -51,6 +51,7 @@
 #include <linux/audit.h>
 #include <linux/tracehook.h>
 #include <linux/kmod.h>
+#include <linux/fsnotify.h>
 
 #include <asm/uaccess.h>
 #include <asm/mmu_context.h>
@@ -98,7 +99,7 @@ static inline void put_binfmt(struct linux_binfmt * fmt)
  *
  * Also note that we take the address to load from from the file itself.
  */
-asmlinkage long sys_uselib(const char __user * library)
+SYSCALL_DEFINE1(uselib, const char __user *, library)
 {
        struct file *file;
        struct nameidata nd;
@@ -132,6 +133,8 @@ asmlinkage long sys_uselib(const char __user * library)
        if (IS_ERR(file))
                goto out;
 
+       fsnotify_open(file->f_path.dentry);
+
        error = -ENOEXEC;
        if(file->f_op) {
                struct linux_binfmt * fmt;
@@ -229,13 +232,13 @@ static void flush_arg_page(struct linux_binprm *bprm, unsigned long pos,
 
 static int __bprm_mm_init(struct linux_binprm *bprm)
 {
-       int err = -ENOMEM;
+       int err;
        struct vm_area_struct *vma = NULL;
        struct mm_struct *mm = bprm->mm;
 
        bprm->vma = vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
        if (!vma)
-               goto err;
+               return -ENOMEM;
 
        down_write(&mm->mmap_sem);
        vma->vm_mm = mm;
@@ -248,28 +251,20 @@ static int __bprm_mm_init(struct linux_binprm *bprm)
         */
        vma->vm_end = STACK_TOP_MAX;
        vma->vm_start = vma->vm_end - PAGE_SIZE;
-
        vma->vm_flags = VM_STACK_FLAGS;
        vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
        err = insert_vm_struct(mm, vma);
-       if (err) {
-               up_write(&mm->mmap_sem);
+       if (err)
                goto err;
-       }
 
        mm->stack_vm = mm->total_vm = 1;
        up_write(&mm->mmap_sem);
-
        bprm->p = vma->vm_end - sizeof(void *);
-
        return 0;
-
 err:
-       if (vma) {
-               bprm->vma = NULL;
-               kmem_cache_free(vm_area_cachep, vma);
-       }
-
+       up_write(&mm->mmap_sem);
+       bprm->vma = NULL;
+       kmem_cache_free(vm_area_cachep, vma);
        return err;
 }
 
@@ -684,6 +679,8 @@ struct file *open_exec(const char *name)
        if (IS_ERR(file))
                return file;
 
+       fsnotify_open(file->f_path.dentry);
+
        err = deny_write_access(file);
        if (err) {
                fput(file);
@@ -1689,7 +1686,7 @@ int get_dumpable(struct mm_struct *mm)
        return (ret >= 2) ? 2 : ret;
 }
 
-int do_coredump(long signr, int exit_code, struct pt_regs * regs)
+void do_coredump(long signr, int exit_code, struct pt_regs *regs)
 {
        struct core_state core_state;
        char corename[CORENAME_MAX_SIZE + 1];
@@ -1773,6 +1770,11 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs)
 
        if (ispipe) {
                helper_argv = argv_split(GFP_KERNEL, corename+1, &helper_argc);
+               if (!helper_argv) {
+                       printk(KERN_WARNING "%s failed to allocate memory\n",
+                              __func__);
+                       goto fail_unlock;
+               }
                /* Terminate the string before the first option */
                delimit = strchr(corename, ' ');
                if (delimit)
@@ -1840,5 +1842,5 @@ fail_unlock:
        put_cred(cred);
        coredump_finish(mm);
 fail:
-       return retval;
+       return;
 }