Skip to content

Commit 82e7ca1

Browse files
Trond Myklebustamschuma-ntap
authored andcommitted
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: 5ceb9d7 ("NFS: Refactor nfs_lookup_revalidate()") Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
1 parent f0940f4 commit 82e7ca1

1 file changed

Lines changed: 17 additions & 3 deletions

File tree

fs/nfs/dir.c

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1401,6 +1401,15 @@ int nfs_lookup_verify_inode(struct inode *inode, unsigned int flags)
14011401
goto out;
14021402
}
14031403

1404+
static void nfs_mark_dir_for_revalidate(struct inode *inode)
1405+
{
1406+
struct nfs_inode *nfsi = NFS_I(inode);
1407+
1408+
spin_lock(&inode->i_lock);
1409+
nfsi->cache_validity |= NFS_INO_REVAL_PAGECACHE;
1410+
spin_unlock(&inode->i_lock);
1411+
}
1412+
14041413
/*
14051414
* We judge how long we want to trust negative
14061415
* dentries by looking at the parent inode mtime.
@@ -1435,7 +1444,6 @@ nfs_lookup_revalidate_done(struct inode *dir, struct dentry *dentry,
14351444
__func__, dentry);
14361445
return 1;
14371446
case 0:
1438-
nfs_mark_for_revalidate(dir);
14391447
if (inode && S_ISDIR(inode->i_mode)) {
14401448
/* Purge readdir caches. */
14411449
nfs_zap_caches(inode);
@@ -1525,6 +1533,13 @@ nfs_lookup_revalidate_dentry(struct inode *dir, struct dentry *dentry,
15251533
nfs_free_fattr(fattr);
15261534
nfs_free_fhandle(fhandle);
15271535
nfs4_label_free(label);
1536+
1537+
/*
1538+
* If the lookup failed despite the dentry change attribute being
1539+
* a match, then we should revalidate the directory cache.
1540+
*/
1541+
if (!ret && nfs_verify_change_attribute(dir, dentry->d_time))
1542+
nfs_mark_dir_for_revalidate(dir);
15281543
return nfs_lookup_revalidate_done(dir, dentry, inode, ret);
15291544
}
15301545

@@ -1567,7 +1582,7 @@ nfs_do_lookup_revalidate(struct inode *dir, struct dentry *dentry,
15671582
error = nfs_lookup_verify_inode(inode, flags);
15681583
if (error) {
15691584
if (error == -ESTALE)
1570-
nfs_zap_caches(dir);
1585+
nfs_mark_dir_for_revalidate(dir);
15711586
goto out_bad;
15721587
}
15731588
nfs_advise_use_readdirplus(dir);
@@ -2064,7 +2079,6 @@ nfs_add_or_obtain(struct dentry *dentry, struct nfs_fh *fhandle,
20642079
dput(parent);
20652080
return d;
20662081
out_error:
2067-
nfs_mark_for_revalidate(dir);
20682082
d = ERR_PTR(error);
20692083
goto out;
20702084
}

0 commit comments

Comments
 (0)