mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-04 10:12:16 +09:00
NFS: Don't revalidate the directory permissions on a lookup failure
[ Upstream commit82e7ca1334] 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> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
faa48b23d0
commit
dd756d05be
20
fs/nfs/dir.c
20
fs/nfs/dir.c
@@ -1202,6 +1202,15 @@ out_force:
|
||||
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.
|
||||
@@ -1236,7 +1245,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);
|
||||
@@ -1326,6 +1334,13 @@ out:
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -1368,7 +1383,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);
|
||||
@@ -1865,7 +1880,6 @@ out:
|
||||
dput(parent);
|
||||
return d;
|
||||
out_error:
|
||||
nfs_mark_for_revalidate(dir);
|
||||
d = ERR_PTR(error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user