diff options
author | Trond Myklebust <trond.myklebust@primarydata.com> | 2018-04-09 01:11:18 +0300 |
---|---|---|
committer | Trond Myklebust <trond.myklebust@hammerspace.com> | 2018-05-31 22:02:16 +0300 |
commit | 59a707b0d42ecf6326ed3846af629602bdf2ff08 (patch) | |
tree | 7ce132bc615d3a18e552020db1054ded43f030f6 /fs/nfs/dir.c | |
parent | 821a868a2316de95250d3069a7b8025ec24154a6 (diff) | |
download | linux-59a707b0d42ecf6326ed3846af629602bdf2ff08.tar.xz |
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.c | 18 |
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); |