summaryrefslogtreecommitdiffstats
path: root/fs/nfs/dir.c
diff options
context:
space:
mode:
authorTrond Myklebust <trond.myklebust@primarydata.com>2015-02-24 00:51:32 +0100
committerTrond Myklebust <trond.myklebust@primarydata.com>2015-03-02 05:23:07 +0100
commitfa9233699cc1dc236f4cf42245d13e40966938c5 (patch)
tree26928a81290415cc0a8db037664da087963965d8 /fs/nfs/dir.c
parentNFSv3: Use the readdir fileid as the mounted-on-fileid (diff)
downloadlinux-fa9233699cc1dc236f4cf42245d13e40966938c5.tar.xz
linux-fa9233699cc1dc236f4cf42245d13e40966938c5.zip
NFS: Don't require a filehandle to refresh the inode in nfs_prime_dcache()
If the server does not return a valid set of attributes that we can use to either create a file or refresh the inode, then there is no value in calling nfs_prime_dcache(). However if we're just refreshing the inode using the attributes that the server returned, then it shouldn't matter whether or not we have a filehandle, as long as we check the fsid+fileid combination. Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Diffstat (limited to 'fs/nfs/dir.c')
-rw-r--r--fs/nfs/dir.c16
1 files changed, 13 insertions, 3 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 4ad7fff9ccaf..c19e16f0b2d0 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -408,14 +408,22 @@ static int xdr_decode(nfs_readdir_descriptor_t *desc,
return 0;
}
+/* Match file and dirent using either filehandle or fileid
+ * Note: caller is responsible for checking the fsid
+ */
static
int nfs_same_file(struct dentry *dentry, struct nfs_entry *entry)
{
+ struct nfs_inode *nfsi;
+
if (dentry->d_inode == NULL)
goto different;
- if (nfs_compare_fh(entry->fh, NFS_FH(dentry->d_inode)) != 0)
- goto different;
- return 1;
+
+ nfsi = NFS_I(dentry->d_inode);
+ if (entry->fattr->fileid == nfsi->fileid)
+ return 1;
+ if (nfs_compare_fh(entry->fh, &nfsi->fh) == 0)
+ return 1;
different:
return 0;
}
@@ -469,6 +477,8 @@ void nfs_prime_dcache(struct dentry *parent, struct nfs_entry *entry)
struct inode *inode;
int status;
+ if (!(entry->fattr->valid & NFS_ATTR_FATTR_FILEID))
+ return;
if (!(entry->fattr->valid & NFS_ATTR_FATTR_FSID))
return;
if (filename.name[0] == '.') {