NFS: Don't revalidate the directory permissions on a lookup failure
There should be no reason to expect the directory permissions to change
just because the directory contents changed or a negative lookup timed
out. So let's avoid doing a full call to nfs_mark_for_revalidate() in
that case.
Furthermore, if this is a negative dentry, and we haven't actually done
a new lookup, then we have no reason yet to believe the directory has
changed at all. So let's remove the gratuitous directory inode
invalidation altogether when called from
nfs_lookup_revalidate_negative().
Reported-by: Geert Jansen <gerardu@amazon.com>
Fixes: 5ceb9d7fda
("NFS: Refactor nfs_lookup_revalidate()")
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
This commit is contained in:
parent
f0940f4b32
commit
82e7ca1334
20
fs/nfs/dir.c
20
fs/nfs/dir.c
@ -1401,6 +1401,15 @@ int nfs_lookup_verify_inode(struct inode *inode, unsigned int flags)
|
||||
goto out;
|
||||
}
|
||||
|
||||
static void nfs_mark_dir_for_revalidate(struct inode *inode)
|
||||
{
|
||||
struct nfs_inode *nfsi = NFS_I(inode);
|
||||
|
||||
spin_lock(&inode->i_lock);
|
||||
nfsi->cache_validity |= NFS_INO_REVAL_PAGECACHE;
|
||||
spin_unlock(&inode->i_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
* We judge how long we want to trust negative
|
||||
* dentries by looking at the parent inode mtime.
|
||||
@ -1435,7 +1444,6 @@ nfs_lookup_revalidate_done(struct inode *dir, struct dentry *dentry,
|
||||
__func__, dentry);
|
||||
return 1;
|
||||
case 0:
|
||||
nfs_mark_for_revalidate(dir);
|
||||
if (inode && S_ISDIR(inode->i_mode)) {
|
||||
/* Purge readdir caches. */
|
||||
nfs_zap_caches(inode);
|
||||
@ -1525,6 +1533,13 @@ nfs_lookup_revalidate_dentry(struct inode *dir, struct dentry *dentry,
|
||||
nfs_free_fattr(fattr);
|
||||
nfs_free_fhandle(fhandle);
|
||||
nfs4_label_free(label);
|
||||
|
||||
/*
|
||||
* If the lookup failed despite the dentry change attribute being
|
||||
* a match, then we should revalidate the directory cache.
|
||||
*/
|
||||
if (!ret && nfs_verify_change_attribute(dir, dentry->d_time))
|
||||
nfs_mark_dir_for_revalidate(dir);
|
||||
return nfs_lookup_revalidate_done(dir, dentry, inode, ret);
|
||||
}
|
||||
|
||||
@ -1567,7 +1582,7 @@ nfs_do_lookup_revalidate(struct inode *dir, struct dentry *dentry,
|
||||
error = nfs_lookup_verify_inode(inode, flags);
|
||||
if (error) {
|
||||
if (error == -ESTALE)
|
||||
nfs_zap_caches(dir);
|
||||
nfs_mark_dir_for_revalidate(dir);
|
||||
goto out_bad;
|
||||
}
|
||||
nfs_advise_use_readdirplus(dir);
|
||||
@ -2064,7 +2079,6 @@ nfs_add_or_obtain(struct dentry *dentry, struct nfs_fh *fhandle,
|
||||
dput(parent);
|
||||
return d;
|
||||
out_error:
|
||||
nfs_mark_for_revalidate(dir);
|
||||
d = ERR_PTR(error);
|
||||
goto out;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user