Commit e4eaac06bcccb2a70bca6a2de9871882dce2aa14
Committed by
Al Viro
1 parent
79bf7c732b
Exists in
master
and in
20 other branches
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>
Showing 36 changed files with 110 additions and 12 deletions Side-by-side Diff
- fs/9p/vfs_inode.c
- fs/affs/namei.c
- fs/afs/dir.c
- fs/bfs/dir.c
- fs/btrfs/inode.c
- fs/ceph/dir.c
- fs/cifs/inode.c
- fs/coda/dir.c
- fs/ecryptfs/inode.c
- fs/exofs/namei.c
- fs/ext2/namei.c
- fs/ext3/namei.c
- fs/ext4/namei.c
- fs/fat/namei_msdos.c
- fs/fat/namei_vfat.c
- fs/fuse/dir.c
- fs/hfs/dir.c
- fs/hfsplus/dir.c
- fs/hostfs/hostfs_kern.c
- fs/hpfs/namei.c
- fs/jffs2/dir.c
- fs/jfs/namei.c
- fs/libfs.c
- fs/logfs/dir.c
- fs/minix/namei.c
- fs/namei.c
- fs/ncpfs/dir.c
- fs/nfs/dir.c
- fs/nilfs2/namei.c
- fs/ocfs2/namei.c
- fs/omfs/dir.c
- fs/reiserfs/namei.c
- fs/sysv/namei.c
- fs/ubifs/dir.c
- fs/udf/namei.c
- fs/ufs/namei.c
fs/9p/vfs_inode.c
... | ... | @@ -840,6 +840,9 @@ |
840 | 840 | struct p9_fid *newdirfid; |
841 | 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 | 846 | P9_DPRINTK(P9_DEBUG_VFS, "\n"); |
844 | 847 | retval = 0; |
845 | 848 | old_inode = old_dentry->d_inode; |
fs/affs/namei.c
... | ... | @@ -419,6 +419,9 @@ |
419 | 419 | struct buffer_head *bh = NULL; |
420 | 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 | 425 | pr_debug("AFFS: rename(old=%u,\"%*s\" to new=%u,\"%*s\")\n", |
423 | 426 | (u32)old_dir->i_ino, (int)old_dentry->d_name.len, old_dentry->d_name.name, |
424 | 427 | (u32)new_dir->i_ino, (int)new_dentry->d_name.len, new_dentry->d_name.name); |
fs/afs/dir.c
... | ... | @@ -1148,6 +1148,9 @@ |
1148 | 1148 | struct key *key; |
1149 | 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 | 1154 | vnode = AFS_FS_I(old_dentry->d_inode); |
1152 | 1155 | orig_dvnode = AFS_FS_I(old_dir); |
1153 | 1156 | new_dvnode = AFS_FS_I(new_dir); |
fs/bfs/dir.c
... | ... | @@ -224,6 +224,9 @@ |
224 | 224 | struct bfs_sb_info *info; |
225 | 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 | 230 | old_bh = new_bh = NULL; |
228 | 231 | old_inode = old_dentry->d_inode; |
229 | 232 | if (S_ISDIR(old_inode->i_mode)) |
fs/btrfs/inode.c
fs/ceph/dir.c
... | ... | @@ -869,6 +869,9 @@ |
869 | 869 | struct ceph_mds_request *req; |
870 | 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 | 875 | if (ceph_snap(old_dir) != ceph_snap(new_dir)) |
873 | 876 | return -EXDEV; |
874 | 877 | if (ceph_snap(old_dir) != CEPH_NOSNAP || |
fs/cifs/inode.c
... | ... | @@ -1571,6 +1571,9 @@ |
1571 | 1571 | FILE_UNIX_BASIC_INFO *info_buf_target; |
1572 | 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 | 1577 | cifs_sb = CIFS_SB(source_dir->i_sb); |
1575 | 1578 | tlink = cifs_sb_tlink(cifs_sb); |
1576 | 1579 | if (IS_ERR(tlink)) |
fs/coda/dir.c
... | ... | @@ -361,6 +361,9 @@ |
361 | 361 | int new_length = new_dentry->d_name.len; |
362 | 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 | 367 | error = venus_rename(old_dir->i_sb, coda_i2f(old_dir), |
365 | 368 | coda_i2f(new_dir), old_length, new_length, |
366 | 369 | (const char *) old_name, (const char *)new_name); |
fs/ecryptfs/inode.c
... | ... | @@ -573,6 +573,9 @@ |
573 | 573 | struct dentry *lower_new_dir_dentry; |
574 | 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 | 579 | lower_old_dentry = ecryptfs_dentry_to_lower(old_dentry); |
577 | 580 | lower_new_dentry = ecryptfs_dentry_to_lower(new_dentry); |
578 | 581 | dget(lower_old_dentry); |
fs/exofs/namei.c
fs/ext2/namei.c
fs/ext3/namei.c
... | ... | @@ -2298,6 +2298,9 @@ |
2298 | 2298 | struct ext3_dir_entry_2 * old_de, * new_de; |
2299 | 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 | 2304 | dquot_initialize(old_dir); |
2302 | 2305 | dquot_initialize(new_dir); |
2303 | 2306 |
fs/ext4/namei.c
... | ... | @@ -2352,6 +2352,9 @@ |
2352 | 2352 | struct ext4_dir_entry_2 *old_de, *new_de; |
2353 | 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 | 2358 | dquot_initialize(old_dir); |
2356 | 2359 | dquot_initialize(new_dir); |
2357 | 2360 |
fs/fat/namei_msdos.c
... | ... | @@ -459,6 +459,9 @@ |
459 | 459 | old_inode = old_dentry->d_inode; |
460 | 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 | 465 | err = fat_scan(old_dir, old_name, &old_sinfo); |
463 | 466 | if (err) { |
464 | 467 | err = -EIO; |
fs/fat/namei_vfat.c
... | ... | @@ -933,6 +933,9 @@ |
933 | 933 | int err, is_dir, update_dotdot, corrupt = 0; |
934 | 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 | 939 | old_sinfo.bh = sinfo.bh = dotdot_bh = NULL; |
937 | 940 | old_inode = old_dentry->d_inode; |
938 | 941 | new_inode = new_dentry->d_inode; |
fs/fuse/dir.c
... | ... | @@ -693,6 +693,10 @@ |
693 | 693 | struct fuse_rename_in inarg; |
694 | 694 | struct fuse_conn *fc = get_fuse_conn(olddir); |
695 | 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 | 700 | if (IS_ERR(req)) |
697 | 701 | return PTR_ERR(req); |
698 | 702 |
fs/hfs/dir.c
fs/hfsplus/dir.c
... | ... | @@ -469,10 +469,12 @@ |
469 | 469 | |
470 | 470 | /* Unlink destination if it already exists */ |
471 | 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 | 474 | res = hfsplus_rmdir(new_dir, new_dentry); |
474 | - else | |
475 | + } else { | |
475 | 476 | res = hfsplus_unlink(new_dir, new_dentry); |
477 | + } | |
476 | 478 | if (res) |
477 | 479 | return res; |
478 | 480 | } |
fs/hostfs/hostfs_kern.c
... | ... | @@ -738,6 +738,9 @@ |
738 | 738 | char *from_name, *to_name; |
739 | 739 | int err; |
740 | 740 | |
741 | + if (to->d_inode && S_ISDIR(to->d_inode->i_mode)) | |
742 | + dentry_unhash(to); | |
743 | + | |
741 | 744 | if ((from_name = dentry_name(from)) == NULL) |
742 | 745 | return -ENOMEM; |
743 | 746 | if ((to_name = dentry_name(to)) == NULL) { |
fs/hpfs/namei.c
... | ... | @@ -561,6 +561,10 @@ |
561 | 561 | struct buffer_head *bh; |
562 | 562 | struct fnode *fnode; |
563 | 563 | int err; |
564 | + | |
565 | + if (new_inode && S_ISDIR(new_inode->i_mode)) | |
566 | + dentry_unhash(new_dentry); | |
567 | + | |
564 | 568 | if ((err = hpfs_chk_name(new_name, &new_len))) return err; |
565 | 569 | err = 0; |
566 | 570 | hpfs_adjust_length(old_name, &old_len); |
fs/jffs2/dir.c
... | ... | @@ -786,6 +786,9 @@ |
786 | 786 | uint8_t type; |
787 | 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 | 792 | /* The VFS will check for us and prevent trying to rename a |
790 | 793 | * file over a directory and vice versa, but if it's a directory, |
791 | 794 | * the VFS can't check whether the victim is empty. The filesystem |
fs/jfs/namei.c
... | ... | @@ -1097,6 +1097,9 @@ |
1097 | 1097 | jfs_info("jfs_rename: %s %s", old_dentry->d_name.name, |
1098 | 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 | 1103 | dquot_initialize(old_dir); |
1101 | 1104 | dquot_initialize(new_dir); |
1102 | 1105 |
fs/libfs.c
... | ... | @@ -325,6 +325,9 @@ |
325 | 325 | struct inode *inode = old_dentry->d_inode; |
326 | 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 | 331 | if (!simple_empty(new_dentry)) |
329 | 332 | return -ENOTEMPTY; |
330 | 333 |
fs/logfs/dir.c
fs/minix/namei.c
fs/namei.c
... | ... | @@ -2950,12 +2950,7 @@ |
2950 | 2950 | * HOWEVER, it relies on the assumption that any object with ->lookup() |
2951 | 2951 | * has no more than 1 dentry. If "hybrid" objects will ever appear, |
2952 | 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, | |
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 | |
2953 | + * d) conversion from fhandle to dentry may come in the wrong moment - when | |
2959 | 2954 | * we are removing the target. Solution: we will have to grab ->i_mutex |
2960 | 2955 | * in the fhandle_to_dentry code. [FIXME - current nfsfh.c relies on |
2961 | 2956 | * ->i_mutex on parents, which works but leads to some truly excessive |
2962 | 2957 | |
... | ... | @@ -2986,11 +2981,8 @@ |
2986 | 2981 | mutex_lock(&target->i_mutex); |
2987 | 2982 | if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry)) |
2988 | 2983 | error = -EBUSY; |
2989 | - else { | |
2990 | - if (target) | |
2991 | - dentry_unhash(new_dentry); | |
2984 | + else | |
2992 | 2985 | error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry); |
2993 | - } | |
2994 | 2986 | if (target) { |
2995 | 2987 | if (!error) { |
2996 | 2988 | target->i_flags |= S_DEAD; |
fs/ncpfs/dir.c
... | ... | @@ -1141,6 +1141,9 @@ |
1141 | 1141 | old_dentry->d_parent->d_name.name, old_dentry->d_name.name, |
1142 | 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 | 1147 | ncp_age_dentry(server, old_dentry); |
1145 | 1148 | ncp_age_dentry(server, new_dentry); |
1146 | 1149 |
fs/nfs/dir.c
... | ... | @@ -1959,6 +1959,9 @@ |
1959 | 1959 | new_dentry->d_parent->d_name.name, new_dentry->d_name.name, |
1960 | 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 | 1966 | * For non-directories, check whether the target is busy and if so, |
1964 | 1967 | * make a copy of the dentry and then do a silly-rename. If the |
fs/nilfs2/namei.c
fs/ocfs2/namei.c
... | ... | @@ -1066,6 +1066,9 @@ |
1066 | 1066 | struct ocfs2_dir_lookup_result orphan_insert = { NULL, }; |
1067 | 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 | 1072 | /* At some point it might be nice to break this function up a |
1070 | 1073 | * bit. */ |
1071 | 1074 |
fs/omfs/dir.c
fs/reiserfs/namei.c
... | ... | @@ -1227,6 +1227,9 @@ |
1227 | 1227 | unsigned long savelink = 1; |
1228 | 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 | 1233 | /* three balancings: (1) old name removal, (2) new name insertion |
1231 | 1234 | and (3) maybe "save" link insertion |
1232 | 1235 | stat data updates: (1) old directory, |
fs/sysv/namei.c
fs/ubifs/dir.c
... | ... | @@ -978,6 +978,9 @@ |
978 | 978 | .dirtied_ino_d = ALIGN(old_inode_ui->data_len, 8) }; |
979 | 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 | 985 | * Budget request settings: deletion direntry, new direntry, removing |
983 | 986 | * the old inode, and changing old and new parent directory inodes. |
fs/udf/namei.c
... | ... | @@ -1083,6 +1083,9 @@ |
1083 | 1083 | struct kernel_lb_addr tloc; |
1084 | 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 | 1089 | ofi = udf_find_entry(old_dir, &old_dentry->d_name, &ofibh, &ocfi); |
1087 | 1090 | if (ofi) { |
1088 | 1091 | if (ofibh.sbh != ofibh.ebh) |
fs/ufs/namei.c
... | ... | @@ -284,6 +284,9 @@ |
284 | 284 | struct ufs_dir_entry *old_de; |
285 | 285 | int err = -ENOENT; |
286 | 286 | |
287 | + if (new_inode && S_ISDIR(new_inode->i_mode)) | |
288 | + dentry_unhash(new_dentry); | |
289 | + | |
287 | 290 | old_de = ufs_find_entry(old_dir, &old_dentry->d_name, &old_page); |
288 | 291 | if (!old_de) |
289 | 292 | goto out; |