Commit 2f2591a3 authored by Jeff Layton's avatar Jeff Layton Committed by Steve French

cifs: don't compare uniqueids in cifs_prime_dcache unless server inode numbers are in use

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.

Cc: <stable@vger.kernel.org> # v3.5+
Reported-and-Tested-by: default avatarOliver Mössinger <Oliver.Moessinger@ichaus.de>
Signed-off-by: default avatarJeff Layton <jlayton@redhat.com>
Signed-off-by: default avatarSteve French <sfrench@us.ibm.com>
parent 8367224b
...@@ -78,6 +78,7 @@ cifs_prime_dcache(struct dentry *parent, struct qstr *name, ...@@ -78,6 +78,7 @@ cifs_prime_dcache(struct dentry *parent, struct qstr *name,
struct dentry *dentry, *alias; struct dentry *dentry, *alias;
struct inode *inode; struct inode *inode;
struct super_block *sb = parent->d_inode->i_sb; 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); cFYI(1, "%s: for %s", __func__, name->name);
...@@ -91,10 +92,20 @@ cifs_prime_dcache(struct dentry *parent, struct qstr *name, ...@@ -91,10 +92,20 @@ cifs_prime_dcache(struct dentry *parent, struct qstr *name,
int err; int err;
inode = dentry->d_inode; inode = dentry->d_inode;
/* update inode in place if i_ino didn't change */ if (inode) {
if (inode && CIFS_I(inode)->uniqueid == fattr->cf_uniqueid) { /*
cifs_fattr_to_inode(inode, fattr); * If we're generating inode numbers, then we don't
goto out; * 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); err = d_invalidate(dentry);
dput(dentry); dput(dentry);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment