diff options
-rw-r--r-- | fs/nfs/dir.c | 11 |
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 */ | ||
1158 | static void nfs_drop_nlink(struct inode *inode) | 1159 | static 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) |