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; |
