aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorSage Weil <sage@newdream.net>2011-05-24 16:06:06 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2011-05-26 07:26:47 -0400
commit79bf7c732b5ff75b96022ed9d29181afd3d2509c (patch)
tree74b8cc690f9a37fff02d0685464e1c695a25ef94 /fs
parent64252c75a2196a0cf1e0d3777143ecfe0e3ae650 (diff)
vfs: push dentry_unhash on rmdir into file systems
Only a few file systems need this. Start by pushing it down into each fs rmdir method (except gfs2 and xfs) so it can be dealt with on a per-fs basis. This does not change behavior for any in-tree file systems. Acked-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Sage Weil <sage@newdream.net> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs')
-rw-r--r--fs/9p/vfs_inode.c1
-rw-r--r--fs/affs/namei.c2
-rw-r--r--fs/afs/dir.c2
-rw-r--r--fs/autofs4/root.c2
-rw-r--r--fs/btrfs/inode.c2
-rw-r--r--fs/ceph/dir.c3
-rw-r--r--fs/cifs/inode.c2
-rw-r--r--fs/coda/dir.c2
-rw-r--r--fs/configfs/dir.c2
-rw-r--r--fs/ecryptfs/inode.c2
-rw-r--r--fs/exofs/namei.c2
-rw-r--r--fs/ext2/namei.c2
-rw-r--r--fs/ext3/namei.c2
-rw-r--r--fs/ext4/namei.c2
-rw-r--r--fs/fat/namei_msdos.c2
-rw-r--r--fs/fat/namei_vfat.c2
-rw-r--r--fs/fuse/dir.c2
-rw-r--r--fs/hfs/dir.c3
-rw-r--r--fs/hfsplus/dir.c2
-rw-r--r--fs/hostfs/hostfs_kern.c2
-rw-r--r--fs/hpfs/namei.c2
-rw-r--r--fs/jffs2/dir.c2
-rw-r--r--fs/jfs/namei.c2
-rw-r--r--fs/libfs.c2
-rw-r--r--fs/logfs/dir.c2
-rw-r--r--fs/minix/namei.c2
-rw-r--r--fs/namei.c1
-rw-r--r--fs/ncpfs/dir.c2
-rw-r--r--fs/nfs/dir.c2
-rw-r--r--fs/nilfs2/namei.c2
-rw-r--r--fs/ocfs2/namei.c3
-rw-r--r--fs/omfs/dir.c8
-rw-r--r--fs/reiserfs/namei.c2
-rw-r--r--fs/sysv/namei.c2
-rw-r--r--fs/ubifs/dir.c2
-rw-r--r--fs/udf/namei.c2
-rw-r--r--fs/ufs/namei.c2
37 files changed, 78 insertions, 3 deletions
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
index 7f6c67703195..ecd77172bf03 100644
--- a/fs/9p/vfs_inode.c
+++ b/fs/9p/vfs_inode.c
@@ -814,6 +814,7 @@ int v9fs_vfs_unlink(struct inode *i, struct dentry *d)
814 814
815int v9fs_vfs_rmdir(struct inode *i, struct dentry *d) 815int v9fs_vfs_rmdir(struct inode *i, struct dentry *d)
816{ 816{
817 dentry_unhash(d);
817 return v9fs_remove(i, d, 1); 818 return v9fs_remove(i, d, 1);
818} 819}
819 820
diff --git a/fs/affs/namei.c b/fs/affs/namei.c
index e3e9efc1fdd8..d087153d5052 100644
--- a/fs/affs/namei.c
+++ b/fs/affs/namei.c
@@ -320,6 +320,8 @@ affs_rmdir(struct inode *dir, struct dentry *dentry)
320 dentry->d_inode->i_ino, 320 dentry->d_inode->i_ino,
321 (int)dentry->d_name.len, dentry->d_name.name); 321 (int)dentry->d_name.len, dentry->d_name.name);
322 322
323 dentry_unhash(dentry);
324
323 return affs_remove_header(dentry); 325 return affs_remove_header(dentry);
324} 326}
325 327
diff --git a/fs/afs/dir.c b/fs/afs/dir.c
index 20c106f24927..9a7f41421534 100644
--- a/fs/afs/dir.c
+++ b/fs/afs/dir.c
@@ -845,6 +845,8 @@ static int afs_rmdir(struct inode *dir, struct dentry *dentry)
845 _enter("{%x:%u},{%s}", 845 _enter("{%x:%u},{%s}",
846 dvnode->fid.vid, dvnode->fid.vnode, dentry->d_name.name); 846 dvnode->fid.vid, dvnode->fid.vnode, dentry->d_name.name);
847 847
848 dentry_unhash(dentry);
849
848 ret = -ENAMETOOLONG; 850 ret = -ENAMETOOLONG;
849 if (dentry->d_name.len >= AFSNAMEMAX) 851 if (dentry->d_name.len >= AFSNAMEMAX)
850 goto error; 852 goto error;
diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c
index f55ae23b137e..87d95a8cddbc 100644
--- a/fs/autofs4/root.c
+++ b/fs/autofs4/root.c
@@ -583,6 +583,8 @@ static int autofs4_dir_unlink(struct inode *dir, struct dentry *dentry)
583 if (!autofs4_oz_mode(sbi) && !capable(CAP_SYS_ADMIN)) 583 if (!autofs4_oz_mode(sbi) && !capable(CAP_SYS_ADMIN))
584 return -EACCES; 584 return -EACCES;
585 585
586 dentry_unhash(dentry);
587
586 if (atomic_dec_and_test(&ino->count)) { 588 if (atomic_dec_and_test(&ino->count)) {
587 p_ino = autofs4_dentry_ino(dentry->d_parent); 589 p_ino = autofs4_dentry_ino(dentry->d_parent);
588 if (p_ino && dentry->d_parent != dentry) 590 if (p_ino && dentry->d_parent != dentry)
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 7cd8ab0ef04d..c692dad3de18 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -3062,6 +3062,8 @@ static int btrfs_rmdir(struct inode *dir, struct dentry *dentry)
3062 inode->i_ino == BTRFS_FIRST_FREE_OBJECTID) 3062 inode->i_ino == BTRFS_FIRST_FREE_OBJECTID)
3063 return -ENOTEMPTY; 3063 return -ENOTEMPTY;
3064 3064
3065 dentry_unhash(dentry);
3066
3065 trans = __unlink_start_trans(dir, dentry); 3067 trans = __unlink_start_trans(dir, dentry);
3066 if (IS_ERR(trans)) 3068 if (IS_ERR(trans))
3067 return PTR_ERR(trans); 3069 return PTR_ERR(trans);
diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c
index 1a867a3601ae..d2e549023ded 100644
--- a/fs/ceph/dir.c
+++ b/fs/ceph/dir.c
@@ -827,6 +827,9 @@ static int ceph_unlink(struct inode *dir, struct dentry *dentry)
827 int err = -EROFS; 827 int err = -EROFS;
828 int op; 828 int op;
829 829
830 if ((dentry->d_inode->i_mode & S_IFMT) == S_IFDIR)
831 dentry_unhash(dentry);
832
830 if (ceph_snap(dir) == CEPH_SNAPDIR) { 833 if (ceph_snap(dir) == CEPH_SNAPDIR) {
831 /* rmdir .snap/foo is RMSNAP */ 834 /* rmdir .snap/foo is RMSNAP */
832 dout("rmsnap dir %p '%.*s' dn %p\n", dir, dentry->d_name.len, 835 dout("rmsnap dir %p '%.*s' dn %p\n", dir, dentry->d_name.len,
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 8852470b4fbb..cee5896bcf56 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -1461,6 +1461,8 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry)
1461 1461
1462 cFYI(1, "cifs_rmdir, inode = 0x%p", inode); 1462 cFYI(1, "cifs_rmdir, inode = 0x%p", inode);
1463 1463
1464 dentry_unhash(direntry);
1465
1464 xid = GetXid(); 1466 xid = GetXid();
1465 1467
1466 full_path = build_path_from_dentry(direntry); 1468 full_path = build_path_from_dentry(direntry);
diff --git a/fs/coda/dir.c b/fs/coda/dir.c
index 2b8dae4d121e..9f72b75a1def 100644
--- a/fs/coda/dir.c
+++ b/fs/coda/dir.c
@@ -336,6 +336,8 @@ static int coda_rmdir(struct inode *dir, struct dentry *de)
336 int len = de->d_name.len; 336 int len = de->d_name.len;
337 int error; 337 int error;
338 338
339 dentry_unhash(de);
340
339 error = venus_rmdir(dir->i_sb, coda_i2f(dir), name, len); 341 error = venus_rmdir(dir->i_sb, coda_i2f(dir), name, len);
340 if (!error) { 342 if (!error) {
341 /* VFS may delete the child */ 343 /* VFS may delete the child */
diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c
index 3313dd19f543..9908c20bb1a5 100644
--- a/fs/configfs/dir.c
+++ b/fs/configfs/dir.c
@@ -1355,6 +1355,8 @@ static int configfs_rmdir(struct inode *dir, struct dentry *dentry)
1355 struct module *subsys_owner = NULL, *dead_item_owner = NULL; 1355 struct module *subsys_owner = NULL, *dead_item_owner = NULL;
1356 int ret; 1356 int ret;
1357 1357
1358 dentry_unhash(dentry);
1359
1358 if (dentry->d_parent == configfs_sb->s_root) 1360 if (dentry->d_parent == configfs_sb->s_root)
1359 return -EPERM; 1361 return -EPERM;
1360 1362
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c
index 4d4cc6a90cd5..c88612f0c1eb 100644
--- a/fs/ecryptfs/inode.c
+++ b/fs/ecryptfs/inode.c
@@ -521,6 +521,8 @@ static int ecryptfs_rmdir(struct inode *dir, struct dentry *dentry)
521 struct dentry *lower_dir_dentry; 521 struct dentry *lower_dir_dentry;
522 int rc; 522 int rc;
523 523
524 dentry_unhash(dentry);
525
524 lower_dentry = ecryptfs_dentry_to_lower(dentry); 526 lower_dentry = ecryptfs_dentry_to_lower(dentry);
525 dget(dentry); 527 dget(dentry);
526 lower_dir_dentry = lock_parent(lower_dentry); 528 lower_dir_dentry = lock_parent(lower_dentry);
diff --git a/fs/exofs/namei.c b/fs/exofs/namei.c
index 4d70db110cfc..0697175d1a38 100644
--- a/fs/exofs/namei.c
+++ b/fs/exofs/namei.c
@@ -227,6 +227,8 @@ static int exofs_rmdir(struct inode *dir, struct dentry *dentry)
227 struct inode *inode = dentry->d_inode; 227 struct inode *inode = dentry->d_inode;
228 int err = -ENOTEMPTY; 228 int err = -ENOTEMPTY;
229 229
230 dentry_unhash(dentry);
231
230 if (exofs_empty_dir(inode)) { 232 if (exofs_empty_dir(inode)) {
231 err = exofs_unlink(dir, dentry); 233 err = exofs_unlink(dir, dentry);
232 if (!err) { 234 if (!err) {
diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c
index ed5c5d496ee9..7a5ad9762de9 100644
--- a/fs/ext2/namei.c
+++ b/fs/ext2/namei.c
@@ -296,6 +296,8 @@ static int ext2_rmdir (struct inode * dir, struct dentry *dentry)
296 struct inode * inode = dentry->d_inode; 296 struct inode * inode = dentry->d_inode;
297 int err = -ENOTEMPTY; 297 int err = -ENOTEMPTY;
298 298
299 dentry_unhash(dentry);
300
299 if (ext2_empty_dir(inode)) { 301 if (ext2_empty_dir(inode)) {
300 err = ext2_unlink(dir, dentry); 302 err = ext2_unlink(dir, dentry);
301 if (!err) { 303 if (!err) {
diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c
index 32f3b8695859..552f94d7cf3d 100644
--- a/fs/ext3/namei.c
+++ b/fs/ext3/namei.c
@@ -2074,6 +2074,8 @@ static int ext3_rmdir (struct inode * dir, struct dentry *dentry)
2074 struct ext3_dir_entry_2 * de; 2074 struct ext3_dir_entry_2 * de;
2075 handle_t *handle; 2075 handle_t *handle;
2076 2076
2077 dentry_unhash(dentry);
2078
2077 /* Initialize quotas before so that eventual writes go in 2079 /* Initialize quotas before so that eventual writes go in
2078 * separate transaction */ 2080 * separate transaction */
2079 dquot_initialize(dir); 2081 dquot_initialize(dir);
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index 67fd0b025858..957580daad78 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -2123,6 +2123,8 @@ static int ext4_rmdir(struct inode *dir, struct dentry *dentry)
2123 struct ext4_dir_entry_2 *de; 2123 struct ext4_dir_entry_2 *de;
2124 handle_t *handle; 2124 handle_t *handle;
2125 2125
2126 dentry_unhash(dentry);
2127
2126 /* Initialize quotas before so that eventual writes go in 2128 /* Initialize quotas before so that eventual writes go in
2127 * separate transaction */ 2129 * separate transaction */
2128 dquot_initialize(dir); 2130 dquot_initialize(dir);
diff --git a/fs/fat/namei_msdos.c b/fs/fat/namei_msdos.c
index 711499040eb6..0c25cea64d24 100644
--- a/fs/fat/namei_msdos.c
+++ b/fs/fat/namei_msdos.c
@@ -326,6 +326,8 @@ static int msdos_rmdir(struct inode *dir, struct dentry *dentry)
326 struct fat_slot_info sinfo; 326 struct fat_slot_info sinfo;
327 int err; 327 int err;
328 328
329 dentry_unhash(dentry);
330
329 lock_super(sb); 331 lock_super(sb);
330 /* 332 /*
331 * Check whether the directory is not in use, then check 333 * Check whether the directory is not in use, then check
diff --git a/fs/fat/namei_vfat.c b/fs/fat/namei_vfat.c
index adae3fb7451a..d7b9383bb9c2 100644
--- a/fs/fat/namei_vfat.c
+++ b/fs/fat/namei_vfat.c
@@ -824,6 +824,8 @@ static int vfat_rmdir(struct inode *dir, struct dentry *dentry)
824 struct fat_slot_info sinfo; 824 struct fat_slot_info sinfo;
825 int err; 825 int err;
826 826
827 dentry_unhash(dentry);
828
827 lock_super(sb); 829 lock_super(sb);
828 830
829 err = fat_dir_empty(inode); 831 err = fat_dir_empty(inode);
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index c6ba49bd95b3..40d5c2ae4e73 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -667,6 +667,8 @@ static int fuse_rmdir(struct inode *dir, struct dentry *entry)
667 if (IS_ERR(req)) 667 if (IS_ERR(req))
668 return PTR_ERR(req); 668 return PTR_ERR(req);
669 669
670 dentry_unhash(entry);
671
670 req->in.h.opcode = FUSE_RMDIR; 672 req->in.h.opcode = FUSE_RMDIR;
671 req->in.h.nodeid = get_node_id(dir); 673 req->in.h.nodeid = get_node_id(dir);
672 req->in.numargs = 1; 674 req->in.numargs = 1;
diff --git a/fs/hfs/dir.c b/fs/hfs/dir.c
index b4d70b13be92..616cfe02b601 100644
--- a/fs/hfs/dir.c
+++ b/fs/hfs/dir.c
@@ -253,6 +253,9 @@ static int hfs_remove(struct inode *dir, struct dentry *dentry)
253 struct inode *inode = dentry->d_inode; 253 struct inode *inode = dentry->d_inode;
254 int res; 254 int res;
255 255
256 if (S_ISDIR(inode->i_mode))
257 dentry_unhash(dentry);
258
256 if (S_ISDIR(inode->i_mode) && inode->i_size != 2) 259 if (S_ISDIR(inode->i_mode) && inode->i_size != 2)
257 return -ENOTEMPTY; 260 return -ENOTEMPTY;
258 res = hfs_cat_delete(inode->i_ino, dir, &dentry->d_name); 261 res = hfs_cat_delete(inode->i_ino, dir, &dentry->d_name);
diff --git a/fs/hfsplus/dir.c b/fs/hfsplus/dir.c
index 4df5059c25da..23451a955aa0 100644
--- a/fs/hfsplus/dir.c
+++ b/fs/hfsplus/dir.c
@@ -370,6 +370,8 @@ static int hfsplus_rmdir(struct inode *dir, struct dentry *dentry)
370 struct inode *inode = dentry->d_inode; 370 struct inode *inode = dentry->d_inode;
371 int res; 371 int res;
372 372
373 dentry_unhash(dentry);
374
373 if (inode->i_size != 2) 375 if (inode->i_size != 2)
374 return -ENOTEMPTY; 376 return -ENOTEMPTY;
375 377
diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c
index 2638c834ed28..73ea3ba3e658 100644
--- a/fs/hostfs/hostfs_kern.c
+++ b/fs/hostfs/hostfs_kern.c
@@ -683,6 +683,8 @@ int hostfs_rmdir(struct inode *ino, struct dentry *dentry)
683 char *file; 683 char *file;
684 int err; 684 int err;
685 685
686 dentry_unhash(dentry);
687
686 if ((file = dentry_name(dentry)) == NULL) 688 if ((file = dentry_name(dentry)) == NULL)
687 return -ENOMEM; 689 return -ENOMEM;
688 err = do_rmdir(file); 690 err = do_rmdir(file);
diff --git a/fs/hpfs/namei.c b/fs/hpfs/namei.c
index b1c72a92c14e..b9fe158fd7ba 100644
--- a/fs/hpfs/namei.c
+++ b/fs/hpfs/namei.c
@@ -461,6 +461,8 @@ static int hpfs_rmdir(struct inode *dir, struct dentry *dentry)
461 int err; 461 int err;
462 int r; 462 int r;
463 463
464 dentry_unhash(dentry);
465
464 hpfs_adjust_length(name, &len); 466 hpfs_adjust_length(name, &len);
465 hpfs_lock(dir->i_sb); 467 hpfs_lock(dir->i_sb);
466 mutex_lock(&hpfs_i(inode)->i_parent_mutex); 468 mutex_lock(&hpfs_i(inode)->i_parent_mutex);
diff --git a/fs/jffs2/dir.c b/fs/jffs2/dir.c
index 82faddd1f321..727d64439cd1 100644
--- a/fs/jffs2/dir.c
+++ b/fs/jffs2/dir.c
@@ -609,6 +609,8 @@ static int jffs2_rmdir (struct inode *dir_i, struct dentry *dentry)
609 int ret; 609 int ret;
610 uint32_t now = get_seconds(); 610 uint32_t now = get_seconds();
611 611
612 dentry_unhash(dentry);
613
612 for (fd = f->dents ; fd; fd = fd->next) { 614 for (fd = f->dents ; fd; fd = fd->next) {
613 if (fd->ino) 615 if (fd->ino)
614 return -ENOTEMPTY; 616 return -ENOTEMPTY;
diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c
index eaaf2b511e89..0569daca86ad 100644
--- a/fs/jfs/namei.c
+++ b/fs/jfs/namei.c
@@ -360,6 +360,8 @@ static int jfs_rmdir(struct inode *dip, struct dentry *dentry)
360 360
361 jfs_info("jfs_rmdir: dip:0x%p name:%s", dip, dentry->d_name.name); 361 jfs_info("jfs_rmdir: dip:0x%p name:%s", dip, dentry->d_name.name);
362 362
363 dentry_unhash(dentry);
364
363 /* Init inode for quota operations. */ 365 /* Init inode for quota operations. */
364 dquot_initialize(dip); 366 dquot_initialize(dip);
365 dquot_initialize(ip); 367 dquot_initialize(ip);
diff --git a/fs/libfs.c b/fs/libfs.c
index c88eab55aec9..1e2ba5a96b10 100644
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -311,6 +311,8 @@ int simple_rmdir(struct inode *dir, struct dentry *dentry)
311 if (!simple_empty(dentry)) 311 if (!simple_empty(dentry))
312 return -ENOTEMPTY; 312 return -ENOTEMPTY;
313 313
314 dentry_unhash(dentry);
315
314 drop_nlink(dentry->d_inode); 316 drop_nlink(dentry->d_inode);
315 simple_unlink(dir, dentry); 317 simple_unlink(dir, dentry);
316 drop_nlink(dir); 318 drop_nlink(dir);
diff --git a/fs/logfs/dir.c b/fs/logfs/dir.c
index 9ed89d1663f8..2b32734cd31a 100644
--- a/fs/logfs/dir.c
+++ b/fs/logfs/dir.c
@@ -273,6 +273,8 @@ static int logfs_rmdir(struct inode *dir, struct dentry *dentry)
273{ 273{
274 struct inode *inode = dentry->d_inode; 274 struct inode *inode = dentry->d_inode;
275 275
276 dentry_unhash(dentry);
277
276 if (!logfs_empty_dir(inode)) 278 if (!logfs_empty_dir(inode))
277 return -ENOTEMPTY; 279 return -ENOTEMPTY;
278 280
diff --git a/fs/minix/namei.c b/fs/minix/namei.c
index 6e6777f1b4b2..091626f5577d 100644
--- a/fs/minix/namei.c
+++ b/fs/minix/namei.c
@@ -168,6 +168,8 @@ static int minix_rmdir(struct inode * dir, struct dentry *dentry)
168 struct inode * inode = dentry->d_inode; 168 struct inode * inode = dentry->d_inode;
169 int err = -ENOTEMPTY; 169 int err = -ENOTEMPTY;
170 170
171 dentry_unhash(dentry);
172
171 if (minix_empty_dir(inode)) { 173 if (minix_empty_dir(inode)) {
172 err = minix_unlink(dir, dentry); 174 err = minix_unlink(dir, dentry);
173 if (!err) { 175 if (!err) {
diff --git a/fs/namei.c b/fs/namei.c
index 8d11187a18d7..596edb5094a4 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -2568,7 +2568,6 @@ int vfs_rmdir(struct inode *dir, struct dentry *dentry)
2568 else { 2568 else {
2569 error = security_inode_rmdir(dir, dentry); 2569 error = security_inode_rmdir(dir, dentry);
2570 if (!error) { 2570 if (!error) {
2571 dentry_unhash(dentry);
2572 error = dir->i_op->rmdir(dir, dentry); 2571 error = dir->i_op->rmdir(dir, dentry);
2573 if (!error) { 2572 if (!error) {
2574 dentry->d_inode->i_flags |= S_DEAD; 2573 dentry->d_inode->i_flags |= S_DEAD;
diff --git a/fs/ncpfs/dir.c b/fs/ncpfs/dir.c
index f6946bb5cb55..57336b7cb55e 100644
--- a/fs/ncpfs/dir.c
+++ b/fs/ncpfs/dir.c
@@ -1033,6 +1033,8 @@ static int ncp_rmdir(struct inode *dir, struct dentry *dentry)
1033 DPRINTK("ncp_rmdir: removing %s/%s\n", 1033 DPRINTK("ncp_rmdir: removing %s/%s\n",
1034 dentry->d_parent->d_name.name, dentry->d_name.name); 1034 dentry->d_parent->d_name.name, dentry->d_name.name);
1035 1035
1036 dentry_unhash(dentry);
1037
1036 error = -EBUSY; 1038 error = -EBUSY;
1037 if (!d_unhashed(dentry)) 1039 if (!d_unhashed(dentry))
1038 goto out; 1040 goto out;
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 7237672216c8..48483b562361 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -1748,6 +1748,8 @@ static int nfs_rmdir(struct inode *dir, struct dentry *dentry)
1748 dfprintk(VFS, "NFS: rmdir(%s/%ld), %s\n", 1748 dfprintk(VFS, "NFS: rmdir(%s/%ld), %s\n",
1749 dir->i_sb->s_id, dir->i_ino, dentry->d_name.name); 1749 dir->i_sb->s_id, dir->i_ino, dentry->d_name.name);
1750 1750
1751 dentry_unhash(dentry);
1752
1751 error = NFS_PROTO(dir)->rmdir(dir, &dentry->d_name); 1753 error = NFS_PROTO(dir)->rmdir(dir, &dentry->d_name);
1752 /* Ensure the VFS deletes this inode */ 1754 /* Ensure the VFS deletes this inode */
1753 if (error == 0 && dentry->d_inode != NULL) 1755 if (error == 0 && dentry->d_inode != NULL)
diff --git a/fs/nilfs2/namei.c b/fs/nilfs2/namei.c
index 546849b3e88f..78306e6462e3 100644
--- a/fs/nilfs2/namei.c
+++ b/fs/nilfs2/namei.c
@@ -334,6 +334,8 @@ static int nilfs_rmdir(struct inode *dir, struct dentry *dentry)
334 struct nilfs_transaction_info ti; 334 struct nilfs_transaction_info ti;
335 int err; 335 int err;
336 336
337 dentry_unhash(dentry);
338
337 err = nilfs_transaction_begin(dir->i_sb, &ti, 0); 339 err = nilfs_transaction_begin(dir->i_sb, &ti, 0);
338 if (err) 340 if (err)
339 return err; 341 return err;
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c
index e5d738cd9cc0..b017ebbaf3fa 100644
--- a/fs/ocfs2/namei.c
+++ b/fs/ocfs2/namei.c
@@ -810,6 +810,9 @@ static int ocfs2_unlink(struct inode *dir,
810 (unsigned long long)OCFS2_I(dir)->ip_blkno, 810 (unsigned long long)OCFS2_I(dir)->ip_blkno,
811 (unsigned long long)OCFS2_I(inode)->ip_blkno); 811 (unsigned long long)OCFS2_I(inode)->ip_blkno);
812 812
813 if (S_ISDIR(inode->i_mode))
814 dentry_unhash(dentry);
815
813 dquot_initialize(dir); 816 dquot_initialize(dir);
814 817
815 BUG_ON(dentry->d_parent->d_inode != dir); 818 BUG_ON(dentry->d_parent->d_inode != dir);
diff --git a/fs/omfs/dir.c b/fs/omfs/dir.c
index de4ff29f1e05..95ef4433d1a3 100644
--- a/fs/omfs/dir.c
+++ b/fs/omfs/dir.c
@@ -240,8 +240,12 @@ static int omfs_remove(struct inode *dir, struct dentry *dentry)
240 struct inode *inode = dentry->d_inode; 240 struct inode *inode = dentry->d_inode;
241 int ret; 241 int ret;
242 242
243 if (S_ISDIR(inode->i_mode) && !omfs_dir_is_empty(inode)) 243
244 return -ENOTEMPTY; 244 if (S_ISDIR(inode->i_mode)) {
245 dentry_unhash(dentry);
246 if (!omfs_dir_is_empty(inode))
247 return -ENOTEMPTY;
248 }
245 249
246 ret = omfs_delete_entry(dentry); 250 ret = omfs_delete_entry(dentry);
247 if (ret) 251 if (ret)
diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c
index 118662690cdf..43e94f0f60ba 100644
--- a/fs/reiserfs/namei.c
+++ b/fs/reiserfs/namei.c
@@ -831,6 +831,8 @@ static int reiserfs_rmdir(struct inode *dir, struct dentry *dentry)
831 INITIALIZE_PATH(path); 831 INITIALIZE_PATH(path);
832 struct reiserfs_dir_entry de; 832 struct reiserfs_dir_entry de;
833 833
834 dentry_unhash(dentry);
835
834 /* we will be doing 2 balancings and update 2 stat data, we change quotas 836 /* we will be doing 2 balancings and update 2 stat data, we change quotas
835 * of the owner of the directory and of the owner of the parent directory. 837 * of the owner of the directory and of the owner of the parent directory.
836 * The quota structure is possibly deleted only on last iput => outside 838 * The quota structure is possibly deleted only on last iput => outside
diff --git a/fs/sysv/namei.c b/fs/sysv/namei.c
index e474fbcf8bde..fac64ac31869 100644
--- a/fs/sysv/namei.c
+++ b/fs/sysv/namei.c
@@ -196,6 +196,8 @@ static int sysv_rmdir(struct inode * dir, struct dentry * dentry)
196 struct inode *inode = dentry->d_inode; 196 struct inode *inode = dentry->d_inode;
197 int err = -ENOTEMPTY; 197 int err = -ENOTEMPTY;
198 198
199 dentry_unhash(dentry);
200
199 if (sysv_empty_dir(inode)) { 201 if (sysv_empty_dir(inode)) {
200 err = sysv_unlink(dir, dentry); 202 err = sysv_unlink(dir, dentry);
201 if (!err) { 203 if (!err) {
diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c
index 7217d67a80a6..6ca9176c8f59 100644
--- a/fs/ubifs/dir.c
+++ b/fs/ubifs/dir.c
@@ -656,6 +656,8 @@ static int ubifs_rmdir(struct inode *dir, struct dentry *dentry)
656 struct ubifs_inode *dir_ui = ubifs_inode(dir); 656 struct ubifs_inode *dir_ui = ubifs_inode(dir);
657 struct ubifs_budget_req req = { .mod_dent = 1, .dirtied_ino = 2 }; 657 struct ubifs_budget_req req = { .mod_dent = 1, .dirtied_ino = 2 };
658 658
659 dentry_unhash(dentry);
660
659 /* 661 /*
660 * Budget request settings: deletion direntry, deletion inode and 662 * Budget request settings: deletion direntry, deletion inode and
661 * changing the parent inode. If budgeting fails, go ahead anyway 663 * changing the parent inode. If budgeting fails, go ahead anyway
diff --git a/fs/udf/namei.c b/fs/udf/namei.c
index f1dce848ef96..b70f026302a5 100644
--- a/fs/udf/namei.c
+++ b/fs/udf/namei.c
@@ -783,6 +783,8 @@ static int udf_rmdir(struct inode *dir, struct dentry *dentry)
783 struct fileIdentDesc *fi, cfi; 783 struct fileIdentDesc *fi, cfi;
784 struct kernel_lb_addr tloc; 784 struct kernel_lb_addr tloc;
785 785
786 dentry_unhash(dentry);
787
786 retval = -ENOENT; 788 retval = -ENOENT;
787 fi = udf_find_entry(dir, &dentry->d_name, &fibh, &cfi); 789 fi = udf_find_entry(dir, &dentry->d_name, &fibh, &cfi);
788 if (!fi) 790 if (!fi)
diff --git a/fs/ufs/namei.c b/fs/ufs/namei.c
index 29309e25417f..3a769d56c689 100644
--- a/fs/ufs/namei.c
+++ b/fs/ufs/namei.c
@@ -258,6 +258,8 @@ static int ufs_rmdir (struct inode * dir, struct dentry *dentry)
258 struct inode * inode = dentry->d_inode; 258 struct inode * inode = dentry->d_inode;
259 int err= -ENOTEMPTY; 259 int err= -ENOTEMPTY;
260 260
261 dentry_unhash(dentry);
262
261 lock_ufs(dir->i_sb); 263 lock_ufs(dir->i_sb);
262 if (ufs_empty_dir (inode)) { 264 if (ufs_empty_dir (inode)) {
263 err = ufs_unlink(dir, dentry); 265 err = ufs_unlink(dir, dentry);