]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.7-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 9 Jan 2013 19:17:14 +0000 (11:17 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 9 Jan 2013 19:17:14 +0000 (11:17 -0800)
added patches:
cifs-don-t-compare-uniqueids-in-cifs_prime_dcache-unless-server-inode-numbers-are-in-use.patch
cifs-rename-cifs_readdir_lookup-to-cifs_prime_dcache-and-make-it-void-return.patch

queue-3.7/cifs-don-t-compare-uniqueids-in-cifs_prime_dcache-unless-server-inode-numbers-are-in-use.patch [new file with mode: 0644]
queue-3.7/cifs-rename-cifs_readdir_lookup-to-cifs_prime_dcache-and-make-it-void-return.patch [new file with mode: 0644]
queue-3.7/series

diff --git a/queue-3.7/cifs-don-t-compare-uniqueids-in-cifs_prime_dcache-unless-server-inode-numbers-are-in-use.patch b/queue-3.7/cifs-don-t-compare-uniqueids-in-cifs_prime_dcache-unless-server-inode-numbers-are-in-use.patch
new file mode 100644 (file)
index 0000000..621f314
--- /dev/null
@@ -0,0 +1,62 @@
+From 2f2591a34db6c9361faa316c91a6e320cb4e6aee Mon Sep 17 00:00:00 2001
+From: Jeff Layton <jlayton@redhat.com>
+Date: Tue, 18 Dec 2012 06:35:10 -0500
+Subject: cifs: don't compare uniqueids in cifs_prime_dcache unless server inode numbers are in use
+
+From: Jeff Layton <jlayton@redhat.com>
+
+commit 2f2591a34db6c9361faa316c91a6e320cb4e6aee upstream.
+
+Oliver reported that commit cd60042c caused his cifs mounts to
+continually thrash through new inodes on readdir. His servers are not
+sending inode numbers (or he's not using them), and the new test in
+that function doesn't account for that sort of setup correctly.
+
+If we're not using server inode numbers, then assume that the inode
+attached to the dentry hasn't changed. Go ahead and update the
+attributes in place, but keep the same inode number.
+
+Reported-and-Tested-by: Oliver Mössinger <Oliver.Moessinger@ichaus.de>
+Signed-off-by: Jeff Layton <jlayton@redhat.com>
+Signed-off-by: Steve French <sfrench@us.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/cifs/readdir.c |   19 +++++++++++++++----
+ 1 file changed, 15 insertions(+), 4 deletions(-)
+
+--- a/fs/cifs/readdir.c
++++ b/fs/cifs/readdir.c
+@@ -78,6 +78,7 @@ cifs_prime_dcache(struct dentry *parent,
+       struct dentry *dentry, *alias;
+       struct inode *inode;
+       struct super_block *sb = parent->d_inode->i_sb;
++      struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
+       cFYI(1, "%s: for %s", __func__, name->name);
+@@ -91,10 +92,20 @@ cifs_prime_dcache(struct dentry *parent,
+               int err;
+               inode = dentry->d_inode;
+-              /* update inode in place if i_ino didn't change */
+-              if (inode && CIFS_I(inode)->uniqueid == fattr->cf_uniqueid) {
+-                      cifs_fattr_to_inode(inode, fattr);
+-                      goto out;
++              if (inode) {
++                      /*
++                       * If we're generating inode numbers, then we don't
++                       * want to clobber the existing one with the one that
++                       * the readdir code created.
++                       */
++                      if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM))
++                              fattr->cf_uniqueid = CIFS_I(inode)->uniqueid;
++
++                      /* update inode in place if i_ino didn't change */
++                      if (CIFS_I(inode)->uniqueid == fattr->cf_uniqueid) {
++                              cifs_fattr_to_inode(inode, fattr);
++                              goto out;
++                      }
+               }
+               err = d_invalidate(dentry);
+               dput(dentry);
diff --git a/queue-3.7/cifs-rename-cifs_readdir_lookup-to-cifs_prime_dcache-and-make-it-void-return.patch b/queue-3.7/cifs-rename-cifs_readdir_lookup-to-cifs_prime_dcache-and-make-it-void-return.patch
new file mode 100644 (file)
index 0000000..dea5729
--- /dev/null
@@ -0,0 +1,120 @@
+From eb1b3fa5cdb9c27bdec8f262acf757a06588eb2d Mon Sep 17 00:00:00 2001
+From: Jeff Layton <jlayton@redhat.com>
+Date: Mon, 3 Dec 2012 06:05:37 -0500
+Subject: cifs: rename cifs_readdir_lookup to cifs_prime_dcache and make it void return
+
+From: Jeff Layton <jlayton@redhat.com>
+
+commit eb1b3fa5cdb9c27bdec8f262acf757a06588eb2d upstream.
+
+The caller doesn't do anything with the dentry, so there's no point in
+holding a reference to it on return. Also cifs_prime_dcache better
+describes the actual purpose of the function.
+
+Signed-off-by: Jeff Layton <jlayton@redhat.com>
+Signed-off-by: Steve French <smfrench@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/cifs/readdir.c |   42 ++++++++++++++++++------------------------
+ 1 file changed, 18 insertions(+), 24 deletions(-)
+
+--- a/fs/cifs/readdir.c
++++ b/fs/cifs/readdir.c
+@@ -66,18 +66,20 @@ static inline void dump_cifs_file_struct
+ #endif /* DEBUG2 */
+ /*
++ * Attempt to preload the dcache with the results from the FIND_FIRST/NEXT
++ *
+  * Find the dentry that matches "name". If there isn't one, create one. If it's
+  * a negative dentry or the uniqueid changed, then drop it and recreate it.
+  */
+-static struct dentry *
+-cifs_readdir_lookup(struct dentry *parent, struct qstr *name,
++static void
++cifs_prime_dcache(struct dentry *parent, struct qstr *name,
+                   struct cifs_fattr *fattr)
+ {
+       struct dentry *dentry, *alias;
+       struct inode *inode;
+       struct super_block *sb = parent->d_inode->i_sb;
+-      cFYI(1, "For %s", name->name);
++      cFYI(1, "%s: for %s", __func__, name->name);
+       if (parent->d_op && parent->d_op->d_hash)
+               parent->d_op->d_hash(parent, parent->d_inode, name);
+@@ -87,37 +89,32 @@ cifs_readdir_lookup(struct dentry *paren
+       dentry = d_lookup(parent, name);
+       if (dentry) {
+               int err;
++
+               inode = dentry->d_inode;
+               /* update inode in place if i_ino didn't change */
+               if (inode && CIFS_I(inode)->uniqueid == fattr->cf_uniqueid) {
+                       cifs_fattr_to_inode(inode, fattr);
+-                      return dentry;
++                      goto out;
+               }
+               err = d_invalidate(dentry);
+               dput(dentry);
+               if (err)
+-                      return NULL;
++                      return;
+       }
+       dentry = d_alloc(parent, name);
+-      if (dentry == NULL)
+-              return NULL;
++      if (!dentry)
++              return;
+       inode = cifs_iget(sb, fattr);
+-      if (!inode) {
+-              dput(dentry);
+-              return NULL;
+-      }
++      if (!inode)
++              goto out;
+       alias = d_materialise_unique(dentry, inode);
+-      if (alias != NULL) {
+-              dput(dentry);
+-              if (IS_ERR(alias))
+-                      return NULL;
+-              dentry = alias;
+-      }
+-
+-      return dentry;
++      if (alias && !IS_ERR(alias))
++              dput(alias);
++out:
++      dput(dentry);
+ }
+ static void
+@@ -652,7 +649,6 @@ static int cifs_filldir(char *find_entry
+       struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
+       struct cifs_dirent de = { NULL, };
+       struct cifs_fattr fattr;
+-      struct dentry *dentry;
+       struct qstr name;
+       int rc = 0;
+       ino_t ino;
+@@ -723,13 +719,11 @@ static int cifs_filldir(char *find_entry
+                */
+               fattr.cf_flags |= CIFS_FATTR_NEED_REVAL;
+-      ino = cifs_uniqueid_to_ino_t(fattr.cf_uniqueid);
+-      dentry = cifs_readdir_lookup(file->f_dentry, &name, &fattr);
++      cifs_prime_dcache(file->f_dentry, &name, &fattr);
++      ino = cifs_uniqueid_to_ino_t(fattr.cf_uniqueid);
+       rc = filldir(dirent, name.name, name.len, file->f_pos, ino,
+                    fattr.cf_dtype);
+-
+-      dput(dentry);
+       return rc;
+ }
index 681637cd5e27c1d36d61a9bcaf7337806faa4222..b8b529b8fa4fd31d0b46fbf54b16a9747ddea3fc 100644 (file)
@@ -119,3 +119,5 @@ mm-limit-mmu_gather-batching-to-fix-soft-lockups-on-config_preempt.patch
 linux-kernel.h-fix-div_round_closest-with-unsigned-divisors.patch
 hid-add-apple-wireless-keyboard-2011-ansi-to-special-driver-list.patch
 can-do-not-call-dev_put-if-restart-timer-is-running-upon-close.patch
+cifs-rename-cifs_readdir_lookup-to-cifs_prime_dcache-and-make-it-void-return.patch
+cifs-don-t-compare-uniqueids-in-cifs_prime_dcache-unless-server-inode-numbers-are-in-use.patch