aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/nfs/dir.c19
-rw-r--r--fs/nfs/unlink.c7
-rw-r--r--include/linux/nfs_fs.h1
3 files changed, 21 insertions, 6 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index d8149e916dd7..187caa47dad9 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -1694,12 +1694,19 @@ int nfs_rmdir(struct inode *dir, struct dentry *dentry)
1694 dir->i_sb->s_id, dir->i_ino, dentry->d_name.name); 1694 dir->i_sb->s_id, dir->i_ino, dentry->d_name.name);
1695 1695
1696 trace_nfs_rmdir_enter(dir, dentry); 1696 trace_nfs_rmdir_enter(dir, dentry);
1697 error = NFS_PROTO(dir)->rmdir(dir, &dentry->d_name); 1697 if (dentry->d_inode) {
1698 /* Ensure the VFS deletes this inode */ 1698 nfs_wait_on_sillyrename(dentry);
1699 if (error == 0 && dentry->d_inode != NULL) 1699 error = NFS_PROTO(dir)->rmdir(dir, &dentry->d_name);
1700 clear_nlink(dentry->d_inode); 1700 /* Ensure the VFS deletes this inode */
1701 else if (error == -ENOENT) 1701 switch (error) {
1702 nfs_dentry_handle_enoent(dentry); 1702 case 0:
1703 clear_nlink(dentry->d_inode);
1704 break;
1705 case -ENOENT:
1706 nfs_dentry_handle_enoent(dentry);
1707 }
1708 } else
1709 error = NFS_PROTO(dir)->rmdir(dir, &dentry->d_name);
1703 trace_nfs_rmdir_exit(dir, dentry, error); 1710 trace_nfs_rmdir_exit(dir, dentry, error);
1704 1711
1705 return error; 1712 return error;
diff --git a/fs/nfs/unlink.c b/fs/nfs/unlink.c
index 2c1485d18419..bb939edd4c99 100644
--- a/fs/nfs/unlink.c
+++ b/fs/nfs/unlink.c
@@ -207,6 +207,13 @@ out_free:
207 return ret; 207 return ret;
208} 208}
209 209
210void nfs_wait_on_sillyrename(struct dentry *dentry)
211{
212 struct nfs_inode *nfsi = NFS_I(dentry->d_inode);
213
214 wait_event(nfsi->waitqueue, atomic_read(&nfsi->silly_count) <= 1);
215}
216
210void nfs_block_sillyrename(struct dentry *dentry) 217void nfs_block_sillyrename(struct dentry *dentry)
211{ 218{
212 struct nfs_inode *nfsi = NFS_I(dentry->d_inode); 219 struct nfs_inode *nfsi = NFS_I(dentry->d_inode);
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
index 7125cef74164..3ea4cde8701c 100644
--- a/include/linux/nfs_fs.h
+++ b/include/linux/nfs_fs.h
@@ -524,6 +524,7 @@ static inline void nfs4_label_free(void *label) {}
524 * linux/fs/nfs/unlink.c 524 * linux/fs/nfs/unlink.c
525 */ 525 */
526extern void nfs_complete_unlink(struct dentry *dentry, struct inode *); 526extern void nfs_complete_unlink(struct dentry *dentry, struct inode *);
527extern void nfs_wait_on_sillyrename(struct dentry *dentry);
527extern void nfs_block_sillyrename(struct dentry *dentry); 528extern void nfs_block_sillyrename(struct dentry *dentry);
528extern void nfs_unblock_sillyrename(struct dentry *dentry); 529extern void nfs_unblock_sillyrename(struct dentry *dentry);
529extern int nfs_sillyrename(struct inode *dir, struct dentry *dentry); 530extern int nfs_sillyrename(struct inode *dir, struct dentry *dentry);