aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/nfs/dir.c11
1 files changed, 6 insertions, 5 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index ce8cb926526b..a46a74654488 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -1155,11 +1155,14 @@ static int nfs_dentry_delete(const struct dentry *dentry)
1155 1155
1156} 1156}
1157 1157
1158/* Ensure that we revalidate inode->i_nlink */
1158static void nfs_drop_nlink(struct inode *inode) 1159static void nfs_drop_nlink(struct inode *inode)
1159{ 1160{
1160 spin_lock(&inode->i_lock); 1161 spin_lock(&inode->i_lock);
1161 if (inode->i_nlink > 0) 1162 /* drop the inode if we're reasonably sure this is the last link */
1162 drop_nlink(inode); 1163 if (inode->i_nlink == 1)
1164 clear_nlink(inode);
1165 NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ATTR;
1163 spin_unlock(&inode->i_lock); 1166 spin_unlock(&inode->i_lock);
1164} 1167}
1165 1168
@@ -1174,8 +1177,8 @@ static void nfs_dentry_iput(struct dentry *dentry, struct inode *inode)
1174 NFS_I(inode)->cache_validity |= NFS_INO_INVALID_DATA; 1177 NFS_I(inode)->cache_validity |= NFS_INO_INVALID_DATA;
1175 1178
1176 if (dentry->d_flags & DCACHE_NFSFS_RENAMED) { 1179 if (dentry->d_flags & DCACHE_NFSFS_RENAMED) {
1177 drop_nlink(inode);
1178 nfs_complete_unlink(dentry, inode); 1180 nfs_complete_unlink(dentry, inode);
1181 nfs_drop_nlink(inode);
1179 } 1182 }
1180 iput(inode); 1183 iput(inode);
1181} 1184}
@@ -1646,10 +1649,8 @@ static int nfs_safe_remove(struct dentry *dentry)
1646 if (inode != NULL) { 1649 if (inode != NULL) {
1647 NFS_PROTO(inode)->return_delegation(inode); 1650 NFS_PROTO(inode)->return_delegation(inode);
1648 error = NFS_PROTO(dir)->remove(dir, &dentry->d_name); 1651 error = NFS_PROTO(dir)->remove(dir, &dentry->d_name);
1649 /* The VFS may want to delete this inode */
1650 if (error == 0) 1652 if (error == 0)
1651 nfs_drop_nlink(inode); 1653 nfs_drop_nlink(inode);
1652 nfs_mark_for_revalidate(inode);
1653 } else 1654 } else
1654 error = NFS_PROTO(dir)->remove(dir, &dentry->d_name); 1655 error = NFS_PROTO(dir)->remove(dir, &dentry->d_name);
1655 if (error == -ENOENT) 1656 if (error == -ENOENT)