diff options
author | Sage Weil <sage@newdream.net> | 2011-05-24 16:06:07 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2011-05-26 07:26:48 -0400 |
commit | e4eaac06bcccb2a70bca6a2de9871882dce2aa14 (patch) | |
tree | ca6736d96294cd6e65a1c3055718bfd5adc7336e /fs | |
parent | 79bf7c732b5ff75b96022ed9d29181afd3d2509c (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.c | 3 | ||||
-rw-r--r-- | fs/affs/namei.c | 3 | ||||
-rw-r--r-- | fs/afs/dir.c | 3 | ||||
-rw-r--r-- | fs/bfs/dir.c | 3 | ||||
-rw-r--r-- | fs/btrfs/inode.c | 3 | ||||
-rw-r--r-- | fs/ceph/dir.c | 3 | ||||
-rw-r--r-- | fs/cifs/inode.c | 3 | ||||
-rw-r--r-- | fs/coda/dir.c | 3 | ||||
-rw-r--r-- | fs/ecryptfs/inode.c | 3 | ||||
-rw-r--r-- | fs/exofs/namei.c | 3 | ||||
-rw-r--r-- | fs/ext2/namei.c | 3 | ||||
-rw-r--r-- | fs/ext3/namei.c | 3 | ||||
-rw-r--r-- | fs/ext4/namei.c | 3 | ||||
-rw-r--r-- | fs/fat/namei_msdos.c | 3 | ||||
-rw-r--r-- | fs/fat/namei_vfat.c | 3 | ||||
-rw-r--r-- | fs/fuse/dir.c | 4 | ||||
-rw-r--r-- | fs/hfs/dir.c | 3 | ||||
-rw-r--r-- | fs/hfsplus/dir.c | 6 | ||||
-rw-r--r-- | fs/hostfs/hostfs_kern.c | 3 | ||||
-rw-r--r-- | fs/hpfs/namei.c | 4 | ||||
-rw-r--r-- | fs/jffs2/dir.c | 3 | ||||
-rw-r--r-- | fs/jfs/namei.c | 3 | ||||
-rw-r--r-- | fs/libfs.c | 3 | ||||
-rw-r--r-- | fs/logfs/dir.c | 3 | ||||
-rw-r--r-- | fs/minix/namei.c | 3 | ||||
-rw-r--r-- | fs/namei.c | 12 | ||||
-rw-r--r-- | fs/ncpfs/dir.c | 3 | ||||
-rw-r--r-- | fs/nfs/dir.c | 3 | ||||
-rw-r--r-- | fs/nilfs2/namei.c | 3 | ||||
-rw-r--r-- | fs/ocfs2/namei.c | 3 | ||||
-rw-r--r-- | fs/omfs/dir.c | 3 | ||||
-rw-r--r-- | fs/reiserfs/namei.c | 3 | ||||
-rw-r--r-- | fs/sysv/namei.c | 3 | ||||
-rw-r--r-- | fs/ubifs/dir.c | 3 | ||||
-rw-r--r-- | fs/udf/namei.c | 3 | ||||
-rw-r--r-- | fs/ufs/namei.c | 3 |
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; |