summaryrefslogtreecommitdiff
path: root/fs/nfs/dir.c
diff options
context:
space:
mode:
authorTrond Myklebust <trond.myklebust@primarydata.com>2018-04-08 18:11:18 -0400
committerTrond Myklebust <trond.myklebust@hammerspace.com>2018-05-31 15:02:16 -0400
commit59a707b0d42ecf6326ed3846af629602bdf2ff08 (patch)
tree7ce132bc615d3a18e552020db1054ded43f030f6 /fs/nfs/dir.c
parent821a868a2316de95250d3069a7b8025ec24154a6 (diff)
NFS: Ensure we revalidate the inode correctly after remove or rename
We may need to revalidate the change attribute, ctime and the nlinks count. Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Diffstat (limited to 'fs/nfs/dir.c')
-rw-r--r--fs/nfs/dir.c18
1 files changed, 14 insertions, 4 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index b315f53b3aec..978a22ea962c 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -1284,11 +1284,13 @@ static void nfs_drop_nlink(struct inode *inode)
{
spin_lock(&inode->i_lock);
/* drop the inode if we're reasonably sure this is the last link */
- if (inode->i_nlink == 1)
- clear_nlink(inode);
+ if (inode->i_nlink > 0)
+ drop_nlink(inode);
+ NFS_I(inode)->attr_gencount = nfs_inc_attr_generation_counter();
NFS_I(inode)->cache_validity |= NFS_INO_INVALID_CHANGE
| NFS_INO_INVALID_CTIME
- | NFS_INO_INVALID_OTHER;
+ | NFS_INO_INVALID_OTHER
+ | NFS_INO_REVAL_FORCED;
spin_unlock(&inode->i_lock);
}
@@ -2050,7 +2052,15 @@ int nfs_rename(struct inode *old_dir, struct dentry *old_dentry,
} else
error = task->tk_status;
rpc_put_task(task);
- nfs_mark_for_revalidate(old_inode);
+ /* Ensure the inode attributes are revalidated */
+ if (error == 0) {
+ spin_lock(&old_inode->i_lock);
+ NFS_I(old_inode)->attr_gencount = nfs_inc_attr_generation_counter();
+ NFS_I(old_inode)->cache_validity |= NFS_INO_INVALID_CHANGE
+ | NFS_INO_INVALID_CTIME
+ | NFS_INO_REVAL_FORCED;
+ spin_unlock(&old_inode->i_lock);
+ }
out:
if (rehash)
d_rehash(rehash);