aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorSage Weil <sage@newdream.net>2011-05-24 16:06:07 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2011-05-26 07:26:48 -0400
commite4eaac06bcccb2a70bca6a2de9871882dce2aa14 (patch)
treeca6736d96294cd6e65a1c3055718bfd5adc7336e /fs
parent79bf7c732b5ff75b96022ed9d29181afd3d2509c (diff)
vfs: push dentry_unhash on rename_dir into file systems
Only a few file systems need this. Start by pushing it down into each rename method (except gfs2 and xfs) so that it can be dealt with on a per-fs basis. 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.c3
-rw-r--r--fs/affs/namei.c3
-rw-r--r--fs/afs/dir.c3
-rw-r--r--fs/bfs/dir.c3
-rw-r--r--fs/btrfs/inode.c3
-rw-r--r--fs/ceph/dir.c3
-rw-r--r--fs/cifs/inode.c3
-rw-r--r--fs/coda/dir.c3
-rw-r--r--fs/ecryptfs/inode.c3
-rw-r--r--fs/exofs/namei.c3
-rw-r--r--fs/ext2/namei.c3
-rw-r--r--fs/ext3/namei.c3
-rw-r--r--fs/ext4/namei.c3
-rw-r--r--fs/fat/namei_msdos.c3
-rw-r--r--fs/fat/namei_vfat.c3
-rw-r--r--fs/fuse/dir.c4
-rw-r--r--fs/hfs/dir.c3
-rw-r--r--fs/hfsplus/dir.c6
-rw-r--r--fs/hostfs/hostfs_kern.c3
-rw-r--r--fs/hpfs/namei.c4
-rw-r--r--fs/jffs2/dir.c3
-rw-r--r--fs/jfs/namei.c3
-rw-r--r--fs/libfs.c3
-rw-r--r--fs/logfs/dir.c3
-rw-r--r--fs/minix/namei.c3
-rw-r--r--fs/namei.c12
-rw-r--r--fs/ncpfs/dir.c3
-rw-r--r--fs/nfs/dir.c3
-rw-r--r--fs/nilfs2/namei.c3
-rw-r--r--fs/ocfs2/namei.c3
-rw-r--r--fs/omfs/dir.c3
-rw-r--r--fs/reiserfs/namei.c3
-rw-r--r--fs/sysv/namei.c3
-rw-r--r--fs/ubifs/dir.c3
-rw-r--r--fs/udf/namei.c3
-rw-r--r--fs/ufs/namei.c3
36 files changed, 110 insertions, 12 deletions
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
index ecd77172bf03..8d7f3e69ae29 100644
--- a/fs/9p/vfs_inode.c
+++ b/fs/9p/vfs_inode.c
@@ -840,6 +840,9 @@ v9fs_vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
840 struct p9_fid *newdirfid; 840 struct p9_fid *newdirfid;
841 struct p9_wstat wstat; 841 struct p9_wstat wstat;
842 842
843 if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode))
844 dentry_unhash(new_dentry);
845
843 P9_DPRINTK(P9_DEBUG_VFS, "\n"); 846 P9_DPRINTK(P9_DEBUG_VFS, "\n");
844 retval = 0; 847 retval = 0;
845 old_inode = old_dentry->d_inode; 848 old_inode = old_dentry->d_inode;
diff --git a/fs/affs/namei.c b/fs/affs/namei.c
index d087153d5052..03330e2e390c 100644
--- a/fs/affs/namei.c
+++ b/fs/affs/namei.c
@@ -419,6 +419,9 @@ affs_rename(struct inode *old_dir, struct dentry *old_dentry,
419 struct buffer_head *bh = NULL; 419 struct buffer_head *bh = NULL;
420 int retval; 420 int retval;
421 421
422 if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode))
423 dentry_unhash(new_dentry);
424
422 pr_debug("AFFS: rename(old=%u,\"%*s\" to new=%u,\"%*s\")\n", 425 pr_debug("AFFS: rename(old=%u,\"%*s\" to new=%u,\"%*s\")\n",
423 (u32)old_dir->i_ino, (int)old_dentry->d_name.len, old_dentry->d_name.name, 426 (u32)old_dir->i_ino, (int)old_dentry->d_name.len, old_dentry->d_name.name,
424 (u32)new_dir->i_ino, (int)new_dentry->d_name.len, new_dentry->d_name.name); 427 (u32)new_dir->i_ino, (int)new_dentry->d_name.len, new_dentry->d_name.name);
diff --git a/fs/afs/dir.c b/fs/afs/dir.c
index 9a7f41421534..2c4e05160042 100644
--- a/fs/afs/dir.c
+++ b/fs/afs/dir.c
@@ -1148,6 +1148,9 @@ static int afs_rename(struct inode *old_dir, struct dentry *old_dentry,
1148 struct key *key; 1148 struct key *key;
1149 int ret; 1149 int ret;
1150 1150
1151 if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode))
1152 dentry_unhash(new_dentry);
1153
1151 vnode = AFS_FS_I(old_dentry->d_inode); 1154 vnode = AFS_FS_I(old_dentry->d_inode);
1152 orig_dvnode = AFS_FS_I(old_dir); 1155 orig_dvnode = AFS_FS_I(old_dir);
1153 new_dvnode = AFS_FS_I(new_dir); 1156 new_dvnode = AFS_FS_I(new_dir);
diff --git a/fs/bfs/dir.c b/fs/bfs/dir.c
index b14cebfd9047..c7d1d06b0483 100644
--- a/fs/bfs/dir.c
+++ b/fs/bfs/dir.c
@@ -224,6 +224,9 @@ static int bfs_rename(struct inode *old_dir, struct dentry *old_dentry,
224 struct bfs_sb_info *info; 224 struct bfs_sb_info *info;
225 int error = -ENOENT; 225 int error = -ENOENT;
226 226
227 if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode))
228 dentry_unhash(new_dentry);
229
227 old_bh = new_bh = NULL; 230 old_bh = new_bh = NULL;
228 old_inode = old_dentry->d_inode; 231 old_inode = old_dentry->d_inode;
229 if (S_ISDIR(old_inode->i_mode)) 232 if (S_ISDIR(old_inode->i_mode))
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index c692dad3de18..3a33ae3ace5b 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -6994,6 +6994,9 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry,
6994 u64 root_objectid; 6994 u64 root_objectid;
6995 int ret; 6995 int ret;
6996 6996
6997 if (new_inode && S_ISDIR(new_dentry->d_inode->i_mode))
6998 dentry_unhash(new_dentry);
6999
6997 if (new_dir->i_ino == BTRFS_EMPTY_SUBVOL_DIR_OBJECTID) 7000 if (new_dir->i_ino == BTRFS_EMPTY_SUBVOL_DIR_OBJECTID)
6998 return -EPERM; 7001 return -EPERM;
6999 7002
diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c
index d2e549023ded..377b96404235 100644
--- a/fs/ceph/dir.c
+++ b/fs/ceph/dir.c
@@ -869,6 +869,9 @@ static int ceph_rename(struct inode *old_dir, struct dentry *old_dentry,
869 struct ceph_mds_request *req; 869 struct ceph_mds_request *req;
870 int err; 870 int err;
871 871
872 if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode))
873 dentry_unhash(new_dentry);
874
872 if (ceph_snap(old_dir) != ceph_snap(new_dir)) 875 if (ceph_snap(old_dir) != ceph_snap(new_dir))
873 return -EXDEV; 876 return -EXDEV;
874 if (ceph_snap(old_dir) != CEPH_NOSNAP || 877 if (ceph_snap(old_dir) != CEPH_NOSNAP ||
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index cee5896bcf56..18546b75f384 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -1571,6 +1571,9 @@ int cifs_rename(struct inode *source_dir, struct dentry *source_dentry,
1571 FILE_UNIX_BASIC_INFO *info_buf_target; 1571 FILE_UNIX_BASIC_INFO *info_buf_target;
1572 int xid, rc, tmprc; 1572 int xid, rc, tmprc;
1573 1573
1574 if (target_dentry->d_inode && S_ISDIR(target_dentry->d_inode->i_mode))
1575 dentry_unhash(target_dentry);
1576
1574 cifs_sb = CIFS_SB(source_dir->i_sb); 1577 cifs_sb = CIFS_SB(source_dir->i_sb);
1575 tlink = cifs_sb_tlink(cifs_sb); 1578 tlink = cifs_sb_tlink(cifs_sb);
1576 if (IS_ERR(tlink)) 1579 if (IS_ERR(tlink))
diff --git a/fs/coda/dir.c b/fs/coda/dir.c
index 9f72b75a1def..a46126fd5735 100644
--- a/fs/coda/dir.c
+++ b/fs/coda/dir.c
@@ -361,6 +361,9 @@ static int coda_rename(struct inode *old_dir, struct dentry *old_dentry,
361 int new_length = new_dentry->d_name.len; 361 int new_length = new_dentry->d_name.len;
362 int error; 362 int error;
363 363
364 if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode))
365 dentry_unhash(new_dentry);
366
364 error = venus_rename(old_dir->i_sb, coda_i2f(old_dir), 367 error = venus_rename(old_dir->i_sb, coda_i2f(old_dir),
365 coda_i2f(new_dir), old_length, new_length, 368 coda_i2f(new_dir), old_length, new_length,
366 (const char *) old_name, (const char *)new_name); 369 (const char *) old_name, (const char *)new_name);
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c
index c88612f0c1eb..227b409b8406 100644
--- a/fs/ecryptfs/inode.c
+++ b/fs/ecryptfs/inode.c
@@ -573,6 +573,9 @@ ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry,
573 struct dentry *lower_new_dir_dentry; 573 struct dentry *lower_new_dir_dentry;
574 struct dentry *trap = NULL; 574 struct dentry *trap = NULL;
575 575
576 if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode))
577 dentry_unhash(new_dentry);
578
576 lower_old_dentry = ecryptfs_dentry_to_lower(old_dentry); 579 lower_old_dentry = ecryptfs_dentry_to_lower(old_dentry);
577 lower_new_dentry = ecryptfs_dentry_to_lower(new_dentry); 580 lower_new_dentry = ecryptfs_dentry_to_lower(new_dentry);
578 dget(lower_old_dentry); 581 dget(lower_old_dentry);
diff --git a/fs/exofs/namei.c b/fs/exofs/namei.c
index 0697175d1a38..de252e5acf05 100644
--- a/fs/exofs/namei.c
+++ b/fs/exofs/namei.c
@@ -251,6 +251,9 @@ static int exofs_rename(struct inode *old_dir, struct dentry *old_dentry,
251 struct exofs_dir_entry *old_de; 251 struct exofs_dir_entry *old_de;
252 int err = -ENOENT; 252 int err = -ENOENT;
253 253
254 if (new_inode && S_ISDIR(new_inode->i_mode))
255 dentry_unhash(new_dentry);
256
254 old_de = exofs_find_entry(old_dir, old_dentry, &old_page); 257 old_de = exofs_find_entry(old_dir, old_dentry, &old_page);
255 if (!old_de) 258 if (!old_de)
256 goto out; 259 goto out;
diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c
index 7a5ad9762de9..516c31dab97c 100644
--- a/fs/ext2/namei.c
+++ b/fs/ext2/namei.c
@@ -320,6 +320,9 @@ static int ext2_rename (struct inode * old_dir, struct dentry * old_dentry,
320 struct ext2_dir_entry_2 * old_de; 320 struct ext2_dir_entry_2 * old_de;
321 int err = -ENOENT; 321 int err = -ENOENT;
322 322
323 if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode))
324 dentry_unhash(new_dentry);
325
323 dquot_initialize(old_dir); 326 dquot_initialize(old_dir);
324 dquot_initialize(new_dir); 327 dquot_initialize(new_dir);
325 328
diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c
index 552f94d7cf3d..f89b1d4c2fb5 100644
--- a/fs/ext3/namei.c
+++ b/fs/ext3/namei.c
@@ -2298,6 +2298,9 @@ static int ext3_rename (struct inode * old_dir, struct dentry *old_dentry,
2298 struct ext3_dir_entry_2 * old_de, * new_de; 2298 struct ext3_dir_entry_2 * old_de, * new_de;
2299 int retval, flush_file = 0; 2299 int retval, flush_file = 0;
2300 2300
2301 if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode))
2302 dentry_unhash(new_dentry);
2303
2301 dquot_initialize(old_dir); 2304 dquot_initialize(old_dir);
2302 dquot_initialize(new_dir); 2305 dquot_initialize(new_dir);
2303 2306
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index 957580daad78..792d06e811c1 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -2352,6 +2352,9 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry,
2352 struct ext4_dir_entry_2 *old_de, *new_de; 2352 struct ext4_dir_entry_2 *old_de, *new_de;
2353 int retval, force_da_alloc = 0; 2353 int retval, force_da_alloc = 0;
2354 2354
2355 if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode))
2356 dentry_unhash(new_dentry);
2357
2355 dquot_initialize(old_dir); 2358 dquot_initialize(old_dir);
2356 dquot_initialize(new_dir); 2359 dquot_initialize(new_dir);
2357 2360
diff --git a/fs/fat/namei_msdos.c b/fs/fat/namei_msdos.c
index 0c25cea64d24..c3eccbd02037 100644
--- a/fs/fat/namei_msdos.c
+++ b/fs/fat/namei_msdos.c
@@ -459,6 +459,9 @@ static int do_msdos_rename(struct inode *old_dir, unsigned char *old_name,
459 old_inode = old_dentry->d_inode; 459 old_inode = old_dentry->d_inode;
460 new_inode = new_dentry->d_inode; 460 new_inode = new_dentry->d_inode;
461 461
462 if (new_inode && S_ISDIR(new_inode->i_mode))
463 dentry_unhash(new_dentry);
464
462 err = fat_scan(old_dir, old_name, &old_sinfo); 465 err = fat_scan(old_dir, old_name, &old_sinfo);
463 if (err) { 466 if (err) {
464 err = -EIO; 467 err = -EIO;
diff --git a/fs/fat/namei_vfat.c b/fs/fat/namei_vfat.c
index d7b9383bb9c2..e2466b2f8cf2 100644
--- a/fs/fat/namei_vfat.c
+++ b/fs/fat/namei_vfat.c
@@ -933,6 +933,9 @@ static int vfat_rename(struct inode *old_dir, struct dentry *old_dentry,
933 int err, is_dir, update_dotdot, corrupt = 0; 933 int err, is_dir, update_dotdot, corrupt = 0;
934 struct super_block *sb = old_dir->i_sb; 934 struct super_block *sb = old_dir->i_sb;
935 935
936 if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode))
937 dentry_unhash(new_dentry);
938
936 old_sinfo.bh = sinfo.bh = dotdot_bh = NULL; 939 old_sinfo.bh = sinfo.bh = dotdot_bh = NULL;
937 old_inode = old_dentry->d_inode; 940 old_inode = old_dentry->d_inode;
938 new_inode = new_dentry->d_inode; 941 new_inode = new_dentry->d_inode;
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index 40d5c2ae4e73..e462a7a281bf 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -693,6 +693,10 @@ static int fuse_rename(struct inode *olddir, struct dentry *oldent,
693 struct fuse_rename_in inarg; 693 struct fuse_rename_in inarg;
694 struct fuse_conn *fc = get_fuse_conn(olddir); 694 struct fuse_conn *fc = get_fuse_conn(olddir);
695 struct fuse_req *req = fuse_get_req(fc); 695 struct fuse_req *req = fuse_get_req(fc);
696
697 if (newent->d_inode && S_ISDIR(newent->d_inode->i_mode))
698 dentry_unhash(newent);
699
696 if (IS_ERR(req)) 700 if (IS_ERR(req))
697 return PTR_ERR(req); 701 return PTR_ERR(req);
698 702
diff --git a/fs/hfs/dir.c b/fs/hfs/dir.c
index 616cfe02b601..1cb70cdba2c1 100644
--- a/fs/hfs/dir.c
+++ b/fs/hfs/dir.c
@@ -286,6 +286,9 @@ static int hfs_rename(struct inode *old_dir, struct dentry *old_dentry,
286 286
287 /* Unlink destination if it already exists */ 287 /* Unlink destination if it already exists */
288 if (new_dentry->d_inode) { 288 if (new_dentry->d_inode) {
289 if (S_ISDIR(new_dentry->d_inode->i_mode))
290 dentry_unhash(new_dentry);
291
289 res = hfs_remove(new_dir, new_dentry); 292 res = hfs_remove(new_dir, new_dentry);
290 if (res) 293 if (res)
291 return res; 294 return res;
diff --git a/fs/hfsplus/dir.c b/fs/hfsplus/dir.c
index 23451a955aa0..b28835091dd0 100644
--- a/fs/hfsplus/dir.c
+++ b/fs/hfsplus/dir.c
@@ -469,10 +469,12 @@ static int hfsplus_rename(struct inode *old_dir, struct dentry *old_dentry,
469 469
470 /* Unlink destination if it already exists */ 470 /* Unlink destination if it already exists */
471 if (new_dentry->d_inode) { 471 if (new_dentry->d_inode) {
472 if (S_ISDIR(new_dentry->d_inode->i_mode)) 472 if (S_ISDIR(new_dentry->d_inode->i_mode)) {
473 dentry_unhash(new_dentry);
473 res = hfsplus_rmdir(new_dir, new_dentry); 474 res = hfsplus_rmdir(new_dir, new_dentry);
474 else 475 } else {
475 res = hfsplus_unlink(new_dir, new_dentry); 476 res = hfsplus_unlink(new_dir, new_dentry);
477 }
476 if (res) 478 if (res)
477 return res; 479 return res;
478 } 480 }
diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c
index 73ea3ba3e658..e6816b9e6903 100644
--- a/fs/hostfs/hostfs_kern.c
+++ b/fs/hostfs/hostfs_kern.c
@@ -738,6 +738,9 @@ int hostfs_rename(struct inode *from_ino, struct dentry *from,
738 char *from_name, *to_name; 738 char *from_name, *to_name;
739 int err; 739 int err;
740 740
741 if (to->d_inode && S_ISDIR(to->d_inode->i_mode))
742 dentry_unhash(to);
743
741 if ((from_name = dentry_name(from)) == NULL) 744 if ((from_name = dentry_name(from)) == NULL)
742 return -ENOMEM; 745 return -ENOMEM;
743 if ((to_name = dentry_name(to)) == NULL) { 746 if ((to_name = dentry_name(to)) == NULL) {
diff --git a/fs/hpfs/namei.c b/fs/hpfs/namei.c
index b9fe158fd7ba..d3db95f51a4e 100644
--- a/fs/hpfs/namei.c
+++ b/fs/hpfs/namei.c
@@ -561,6 +561,10 @@ static int hpfs_rename(struct inode *old_dir, struct dentry *old_dentry,
561 struct buffer_head *bh; 561 struct buffer_head *bh;
562 struct fnode *fnode; 562 struct fnode *fnode;
563 int err; 563 int err;
564
565 if (new_inode && S_ISDIR(new_inode->i_mode))
566 dentry_unhash(new_dentry);
567
564 if ((err = hpfs_chk_name(new_name, &new_len))) return err; 568 if ((err = hpfs_chk_name(new_name, &new_len))) return err;
565 err = 0; 569 err = 0;
566 hpfs_adjust_length(old_name, &old_len); 570 hpfs_adjust_length(old_name, &old_len);
diff --git a/fs/jffs2/dir.c b/fs/jffs2/dir.c
index 727d64439cd1..05f73328b28b 100644
--- a/fs/jffs2/dir.c
+++ b/fs/jffs2/dir.c
@@ -786,6 +786,9 @@ static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry,
786 uint8_t type; 786 uint8_t type;
787 uint32_t now; 787 uint32_t now;
788 788
789 if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode))
790 dentry_unhash(new_dentry);
791
789 /* The VFS will check for us and prevent trying to rename a 792 /* The VFS will check for us and prevent trying to rename a
790 * file over a directory and vice versa, but if it's a directory, 793 * file over a directory and vice versa, but if it's a directory,
791 * the VFS can't check whether the victim is empty. The filesystem 794 * the VFS can't check whether the victim is empty. The filesystem
diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c
index 0569daca86ad..865df16a6cf3 100644
--- a/fs/jfs/namei.c
+++ b/fs/jfs/namei.c
@@ -1097,6 +1097,9 @@ static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry,
1097 jfs_info("jfs_rename: %s %s", old_dentry->d_name.name, 1097 jfs_info("jfs_rename: %s %s", old_dentry->d_name.name,
1098 new_dentry->d_name.name); 1098 new_dentry->d_name.name);
1099 1099
1100 if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode))
1101 dentry_unhash(new_dentry);
1102
1100 dquot_initialize(old_dir); 1103 dquot_initialize(old_dir);
1101 dquot_initialize(new_dir); 1104 dquot_initialize(new_dir);
1102 1105
diff --git a/fs/libfs.c b/fs/libfs.c
index 1e2ba5a96b10..91a3710e0fe5 100644
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -325,6 +325,9 @@ int simple_rename(struct inode *old_dir, struct dentry *old_dentry,
325 struct inode *inode = old_dentry->d_inode; 325 struct inode *inode = old_dentry->d_inode;
326 int they_are_dirs = S_ISDIR(old_dentry->d_inode->i_mode); 326 int they_are_dirs = S_ISDIR(old_dentry->d_inode->i_mode);
327 327
328 if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode))
329 dentry_unhash(new_dentry);
330
328 if (!simple_empty(new_dentry)) 331 if (!simple_empty(new_dentry))
329 return -ENOTEMPTY; 332 return -ENOTEMPTY;
330 333
diff --git a/fs/logfs/dir.c b/fs/logfs/dir.c
index 2b32734cd31a..f34c9cde9e94 100644
--- a/fs/logfs/dir.c
+++ b/fs/logfs/dir.c
@@ -624,6 +624,9 @@ static int logfs_rename_cross(struct inode *old_dir, struct dentry *old_dentry,
624 loff_t pos; 624 loff_t pos;
625 int err; 625 int err;
626 626
627 if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode))
628 dentry_unhash(new_dentry);
629
627 /* 1. locate source dd */ 630 /* 1. locate source dd */
628 err = logfs_get_dd(old_dir, old_dentry, &dd, &pos); 631 err = logfs_get_dd(old_dir, old_dentry, &dd, &pos);
629 if (err) 632 if (err)
diff --git a/fs/minix/namei.c b/fs/minix/namei.c
index 091626f5577d..f60aed8db9c4 100644
--- a/fs/minix/namei.c
+++ b/fs/minix/namei.c
@@ -192,6 +192,9 @@ static int minix_rename(struct inode * old_dir, struct dentry *old_dentry,
192 struct minix_dir_entry * old_de; 192 struct minix_dir_entry * old_de;
193 int err = -ENOENT; 193 int err = -ENOENT;
194 194
195 if (new_inode && S_ISDIR(new_inode->i_mode))
196 dentry_unhash(new_dentry);
197
195 old_de = minix_find_entry(old_dentry, &old_page); 198 old_de = minix_find_entry(old_dentry, &old_page);
196 if (!old_de) 199 if (!old_de)
197 goto out; 200 goto out;
diff --git a/fs/namei.c b/fs/namei.c
index 596edb5094a4..787ebc8a200a 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -2950,12 +2950,7 @@ SYSCALL_DEFINE2(link, const char __user *, oldname, const char __user *, newname
2950 * HOWEVER, it relies on the assumption that any object with ->lookup() 2950 * HOWEVER, it relies on the assumption that any object with ->lookup()
2951 * has no more than 1 dentry. If "hybrid" objects will ever appear, 2951 * has no more than 1 dentry. If "hybrid" objects will ever appear,
2952 * we'd better make sure that there's no link(2) for them. 2952 * we'd better make sure that there's no link(2) for them.
2953 * d) some filesystems don't support opened-but-unlinked directories, 2953 * d) conversion from fhandle to dentry may come in the wrong moment - when
2954 * either because of layout or because they are not ready to deal with
2955 * all cases correctly. The latter will be fixed (taking this sort of
2956 * stuff into VFS), but the former is not going away. Solution: the same
2957 * trick as in rmdir().
2958 * e) conversion from fhandle to dentry may come in the wrong moment - when
2959 * we are removing the target. Solution: we will have to grab ->i_mutex 2954 * we are removing the target. Solution: we will have to grab ->i_mutex
2960 * in the fhandle_to_dentry code. [FIXME - current nfsfh.c relies on 2955 * in the fhandle_to_dentry code. [FIXME - current nfsfh.c relies on
2961 * ->i_mutex on parents, which works but leads to some truly excessive 2956 * ->i_mutex on parents, which works but leads to some truly excessive
@@ -2986,11 +2981,8 @@ static int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
2986 mutex_lock(&target->i_mutex); 2981 mutex_lock(&target->i_mutex);
2987 if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry)) 2982 if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry))
2988 error = -EBUSY; 2983 error = -EBUSY;
2989 else { 2984 else
2990 if (target)
2991 dentry_unhash(new_dentry);
2992 error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry); 2985 error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
2993 }
2994 if (target) { 2986 if (target) {
2995 if (!error) { 2987 if (!error) {
2996 target->i_flags |= S_DEAD; 2988 target->i_flags |= S_DEAD;
diff --git a/fs/ncpfs/dir.c b/fs/ncpfs/dir.c
index 57336b7cb55e..e3e646b06404 100644
--- a/fs/ncpfs/dir.c
+++ b/fs/ncpfs/dir.c
@@ -1141,6 +1141,9 @@ static int ncp_rename(struct inode *old_dir, struct dentry *old_dentry,
1141 old_dentry->d_parent->d_name.name, old_dentry->d_name.name, 1141 old_dentry->d_parent->d_name.name, old_dentry->d_name.name,
1142 new_dentry->d_parent->d_name.name, new_dentry->d_name.name); 1142 new_dentry->d_parent->d_name.name, new_dentry->d_name.name);
1143 1143
1144 if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode))
1145 dentry_unhash(new_dentry);
1146
1144 ncp_age_dentry(server, old_dentry); 1147 ncp_age_dentry(server, old_dentry);
1145 ncp_age_dentry(server, new_dentry); 1148 ncp_age_dentry(server, new_dentry);
1146 1149
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 48483b562361..87daf7982186 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -1959,6 +1959,9 @@ static int nfs_rename(struct inode *old_dir, struct dentry *old_dentry,
1959 new_dentry->d_parent->d_name.name, new_dentry->d_name.name, 1959 new_dentry->d_parent->d_name.name, new_dentry->d_name.name,
1960 new_dentry->d_count); 1960 new_dentry->d_count);
1961 1961
1962 if (new_inode && S_ISDIR(new_inode->i_mode))
1963 dentry_unhash(new_dentry);
1964
1962 /* 1965 /*
1963 * For non-directories, check whether the target is busy and if so, 1966 * For non-directories, check whether the target is busy and if so,
1964 * make a copy of the dentry and then do a silly-rename. If the 1967 * make a copy of the dentry and then do a silly-rename. If the
diff --git a/fs/nilfs2/namei.c b/fs/nilfs2/namei.c
index 78306e6462e3..1102a5fbb744 100644
--- a/fs/nilfs2/namei.c
+++ b/fs/nilfs2/namei.c
@@ -371,6 +371,9 @@ static int nilfs_rename(struct inode *old_dir, struct dentry *old_dentry,
371 struct nilfs_transaction_info ti; 371 struct nilfs_transaction_info ti;
372 int err; 372 int err;
373 373
374 if (new_inode && S_ISDIR(new_inode->i_mode))
375 dentry_unhash(new_dentry);
376
374 err = nilfs_transaction_begin(old_dir->i_sb, &ti, 1); 377 err = nilfs_transaction_begin(old_dir->i_sb, &ti, 1);
375 if (unlikely(err)) 378 if (unlikely(err))
376 return err; 379 return err;
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c
index b017ebbaf3fa..f3582a6a6dac 100644
--- a/fs/ocfs2/namei.c
+++ b/fs/ocfs2/namei.c
@@ -1066,6 +1066,9 @@ static int ocfs2_rename(struct inode *old_dir,
1066 struct ocfs2_dir_lookup_result orphan_insert = { NULL, }; 1066 struct ocfs2_dir_lookup_result orphan_insert = { NULL, };
1067 struct ocfs2_dir_lookup_result target_insert = { NULL, }; 1067 struct ocfs2_dir_lookup_result target_insert = { NULL, };
1068 1068
1069 if (new_inode && S_ISDIR(new_inode->i_mode))
1070 dentry_unhash(new_dentry);
1071
1069 /* At some point it might be nice to break this function up a 1072 /* At some point it might be nice to break this function up a
1070 * bit. */ 1073 * bit. */
1071 1074
diff --git a/fs/omfs/dir.c b/fs/omfs/dir.c
index 95ef4433d1a3..c368360c35a1 100644
--- a/fs/omfs/dir.c
+++ b/fs/omfs/dir.c
@@ -382,6 +382,9 @@ static int omfs_rename(struct inode *old_dir, struct dentry *old_dentry,
382 int err; 382 int err;
383 383
384 if (new_inode) { 384 if (new_inode) {
385 if (S_ISDIR(new_inode->i_mode))
386 dentry_unhash(new_dentry);
387
385 /* overwriting existing file/dir */ 388 /* overwriting existing file/dir */
386 err = omfs_remove(new_dir, new_dentry); 389 err = omfs_remove(new_dir, new_dentry);
387 if (err) 390 if (err)
diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c
index 43e94f0f60ba..76c8164d5651 100644
--- a/fs/reiserfs/namei.c
+++ b/fs/reiserfs/namei.c
@@ -1227,6 +1227,9 @@ static int reiserfs_rename(struct inode *old_dir, struct dentry *old_dentry,
1227 unsigned long savelink = 1; 1227 unsigned long savelink = 1;
1228 struct timespec ctime; 1228 struct timespec ctime;
1229 1229
1230 if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode))
1231 dentry_unhash(new_dentry);
1232
1230 /* three balancings: (1) old name removal, (2) new name insertion 1233 /* three balancings: (1) old name removal, (2) new name insertion
1231 and (3) maybe "save" link insertion 1234 and (3) maybe "save" link insertion
1232 stat data updates: (1) old directory, 1235 stat data updates: (1) old directory,
diff --git a/fs/sysv/namei.c b/fs/sysv/namei.c
index fac64ac31869..e2cc6756f3b1 100644
--- a/fs/sysv/namei.c
+++ b/fs/sysv/namei.c
@@ -224,6 +224,9 @@ static int sysv_rename(struct inode * old_dir, struct dentry * old_dentry,
224 struct sysv_dir_entry * old_de; 224 struct sysv_dir_entry * old_de;
225 int err = -ENOENT; 225 int err = -ENOENT;
226 226
227 if (new_inode && S_ISDIR(new_inode->i_mode))
228 dentry_unhash(new_dentry);
229
227 old_de = sysv_find_entry(old_dentry, &old_page); 230 old_de = sysv_find_entry(old_dentry, &old_page);
228 if (!old_de) 231 if (!old_de)
229 goto out; 232 goto out;
diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c
index 6ca9176c8f59..d80810bb4c37 100644
--- a/fs/ubifs/dir.c
+++ b/fs/ubifs/dir.c
@@ -978,6 +978,9 @@ static int ubifs_rename(struct inode *old_dir, struct dentry *old_dentry,
978 .dirtied_ino_d = ALIGN(old_inode_ui->data_len, 8) }; 978 .dirtied_ino_d = ALIGN(old_inode_ui->data_len, 8) };
979 struct timespec time; 979 struct timespec time;
980 980
981 if (new_inode && S_ISDIR(new_inode->i_mode))
982 dentry_unhash(new_dentry);
983
981 /* 984 /*
982 * Budget request settings: deletion direntry, new direntry, removing 985 * Budget request settings: deletion direntry, new direntry, removing
983 * the old inode, and changing old and new parent directory inodes. 986 * the old inode, and changing old and new parent directory inodes.
diff --git a/fs/udf/namei.c b/fs/udf/namei.c
index b70f026302a5..4d76594c2a8f 100644
--- a/fs/udf/namei.c
+++ b/fs/udf/namei.c
@@ -1083,6 +1083,9 @@ static int udf_rename(struct inode *old_dir, struct dentry *old_dentry,
1083 struct kernel_lb_addr tloc; 1083 struct kernel_lb_addr tloc;
1084 struct udf_inode_info *old_iinfo = UDF_I(old_inode); 1084 struct udf_inode_info *old_iinfo = UDF_I(old_inode);
1085 1085
1086 if (new_inode && S_ISDIR(new_inode->i_mode))
1087 dentry_unhash(new_dentry);
1088
1086 ofi = udf_find_entry(old_dir, &old_dentry->d_name, &ofibh, &ocfi); 1089 ofi = udf_find_entry(old_dir, &old_dentry->d_name, &ofibh, &ocfi);
1087 if (ofi) { 1090 if (ofi) {
1088 if (ofibh.sbh != ofibh.ebh) 1091 if (ofibh.sbh != ofibh.ebh)
diff --git a/fs/ufs/namei.c b/fs/ufs/namei.c
index 3a769d56c689..953ebdfc5bf7 100644
--- a/fs/ufs/namei.c
+++ b/fs/ufs/namei.c
@@ -284,6 +284,9 @@ static int ufs_rename(struct inode *old_dir, struct dentry *old_dentry,
284 struct ufs_dir_entry *old_de; 284 struct ufs_dir_entry *old_de;
285 int err = -ENOENT; 285 int err = -ENOENT;
286 286
287 if (new_inode && S_ISDIR(new_inode->i_mode))
288 dentry_unhash(new_dentry);
289
287 old_de = ufs_find_entry(old_dir, &old_dentry->d_name, &old_page); 290 old_de = ufs_find_entry(old_dir, &old_dentry->d_name, &old_page);
288 if (!old_de) 291 if (!old_de)
289 goto out; 292 goto out;