diff options
author | Trond Myklebust <trond.myklebust@primarydata.com> | 2015-02-23 18:51:32 -0500 |
---|---|---|
committer | Trond Myklebust <trond.myklebust@primarydata.com> | 2015-03-01 23:23:07 -0500 |
commit | fa9233699cc1dc236f4cf42245d13e40966938c5 (patch) | |
tree | 26928a81290415cc0a8db037664da087963965d8 /fs | |
parent | 1ae04b252351188cfa66af1b8b0628512a72dd7b (diff) |
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')
-rw-r--r-- | fs/nfs/dir.c | 16 |
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] == '.') { |