diff options
author | Sage Weil <sage@newdream.net> | 2011-05-24 16:06:06 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2011-05-26 07:26:47 -0400 |
commit | 79bf7c732b5ff75b96022ed9d29181afd3d2509c (patch) | |
tree | 74b8cc690f9a37fff02d0685464e1c695a25ef94 | |
parent | 64252c75a2196a0cf1e0d3777143ecfe0e3ae650 (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>
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 | ||
815 | int v9fs_vfs_rmdir(struct inode *i, struct dentry *d) | 815 | int 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); |