]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
locking fix for namei.c fwd from Joe Korty
authorChris Wright <chrisw@sous-sol.org>
Mon, 19 Jun 2006 19:12:09 +0000 (12:12 -0700)
committerChris Wright <chrisw@sous-sol.org>
Mon, 19 Jun 2006 19:12:09 +0000 (12:12 -0700)
queue-2.6.16/fs-namei.c-call-to-file_permission-under-a-spinlock-in-do_lookup_path.patch [new file with mode: 0644]
queue-2.6.16/series

diff --git a/queue-2.6.16/fs-namei.c-call-to-file_permission-under-a-spinlock-in-do_lookup_path.patch b/queue-2.6.16/fs-namei.c-call-to-file_permission-under-a-spinlock-in-do_lookup_path.patch
new file mode 100644 (file)
index 0000000..8a2e2e3
--- /dev/null
@@ -0,0 +1,97 @@
+From stable-bounces@linux.kernel.org  Tue Jun  6 08:23:00 2006
+Date: Tue, 6 Jun 2006 11:19:35 -0400
+From: Joe Korty <joe.korty@ccur.com>
+To: stable@kernel.org
+Cc: 
+Subject: fs/namei.c: Call to file_permission() under a spinlock in do_lookup_path()
+
+From: Trond Myklebust <Trond.Myklebust@netapp.com>
+
+We're presently running lock_kernel() under fs_lock via nfs's ->permission
+handler.  That's a ranking bug and sometimes a sleep-in-spinlock bug.  This
+problem was introduced in the openat() patchset.
+
+We should not need to hold the current->fs->lock for a codepath that doesn't
+use current->fs.
+
+[vsu@altlinux.ru: fix error path]
+Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
+Cc: Al Viro <viro@ftp.linux.org.uk>
+Signed-off-by: Sergey Vlasov <vsu@altlinux.ru>
+Signed-off-by: Andrew Morton <akpm@osdl.org>
+Signed-off-by: Linus Torvalds <torvalds@osdl.org>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+---
+
+ fs/namei.c |   19 ++++++++++---------
+ 1 file changed, 10 insertions(+), 9 deletions(-)
+
+--- linux-2.6.16.20.orig/fs/namei.c
++++ linux-2.6.16.20/fs/namei.c
+@@ -1077,8 +1077,8 @@ static int fastcall do_path_lookup(int d
+       nd->flags = flags;
+       nd->depth = 0;
+-      read_lock(&current->fs->lock);
+       if (*name=='/') {
++              read_lock(&current->fs->lock);
+               if (current->fs->altroot && !(nd->flags & LOOKUP_NOALT)) {
+                       nd->mnt = mntget(current->fs->altrootmnt);
+                       nd->dentry = dget(current->fs->altroot);
+@@ -1089,33 +1089,35 @@ static int fastcall do_path_lookup(int d
+               }
+               nd->mnt = mntget(current->fs->rootmnt);
+               nd->dentry = dget(current->fs->root);
++              read_unlock(&current->fs->lock);
+       } else if (dfd == AT_FDCWD) {
++              read_lock(&current->fs->lock);
+               nd->mnt = mntget(current->fs->pwdmnt);
+               nd->dentry = dget(current->fs->pwd);
++              read_unlock(&current->fs->lock);
+       } else {
+               struct dentry *dentry;
+               file = fget_light(dfd, &fput_needed);
+               retval = -EBADF;
+               if (!file)
+-                      goto unlock_fail;
++                      goto out_fail;
+               dentry = file->f_dentry;
+               retval = -ENOTDIR;
+               if (!S_ISDIR(dentry->d_inode->i_mode))
+-                      goto fput_unlock_fail;
++                      goto fput_fail;
+               retval = file_permission(file, MAY_EXEC);
+               if (retval)
+-                      goto fput_unlock_fail;
++                      goto fput_fail;
+               nd->mnt = mntget(file->f_vfsmnt);
+               nd->dentry = dget(dentry);
+               fput_light(file, fput_needed);
+       }
+-      read_unlock(&current->fs->lock);
+       current->total_link_count = 0;
+       retval = link_path_walk(name, nd);
+ out:
+@@ -1124,13 +1126,12 @@ out:
+                               nd->dentry->d_inode))
+               audit_inode(name, nd->dentry->d_inode, flags);
+       }
++out_fail:
+       return retval;
+-fput_unlock_fail:
++fput_fail:
+       fput_light(file, fput_needed);
+-unlock_fail:
+-      read_unlock(&current->fs->lock);
+-      return retval;
++      goto out_fail;
+ }
+ int fastcall path_lookup(const char *name, unsigned int flags,
index b729df0eb97d8e913614ec803882f9a05603612f..ed2de98304c14d112a6e2c392ea2033d3a08d6c8 100644 (file)
@@ -5,3 +5,4 @@ sparc64-fix-missing-fold-at-end-of-checksums.patch
 missed-error-checking-for-intent-s-filp-in-open_namei.patch
 tmpfs-time-granularity-fix-for-time-going-backwards.patch
 serial-parport_serial-should-depend-on-serial_8250_pci.patch
+fs-namei.c-call-to-file_permission-under-a-spinlock-in-do_lookup_path.patch