diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index ecd77172bf0391e9ff8d9a817fcdef0f60731a8b..8d7f3e69ae29072c28a0760222fb9b7cebcbcd2b 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, struct p9_fid *newdirfid; struct p9_wstat wstat; + if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) + dentry_unhash(new_dentry); + P9_DPRINTK(P9_DEBUG_VFS, "\n"); retval = 0; old_inode = old_dentry->d_inode; diff --git a/fs/affs/namei.c b/fs/affs/namei.c index d087153d50523f7e79f13d599bffe4090234075c..03330e2e390c130ef055cf45547c36fa3f4917e9 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, struct buffer_head *bh = NULL; int retval; + if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) + dentry_unhash(new_dentry); + pr_debug("AFFS: rename(old=%u,\"%*s\" to new=%u,\"%*s\")\n", (u32)old_dir->i_ino, (int)old_dentry->d_name.len, old_dentry->d_name.name, (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 9a7f4142153431c9ca003c2271f233824b816436..2c4e051600420381e647f0d35810961e355d99f4 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, struct key *key; int ret; + if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) + dentry_unhash(new_dentry); + vnode = AFS_FS_I(old_dentry->d_inode); orig_dvnode = AFS_FS_I(old_dir); new_dvnode = AFS_FS_I(new_dir); diff --git a/fs/bfs/dir.c b/fs/bfs/dir.c index b14cebfd90477ead4b15f0c1583da6393c247de5..c7d1d06b0483e3713f491cdad1d4cc3ce91500fe 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, struct bfs_sb_info *info; int error = -ENOENT; + if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) + dentry_unhash(new_dentry); + old_bh = new_bh = NULL; old_inode = old_dentry->d_inode; if (S_ISDIR(old_inode->i_mode)) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index c692dad3de18215cdd151bf10540ecb797cb2752..3a33ae3ace5b1d3618ba7e7d8bd0229bc4943bdb 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, u64 root_objectid; int ret; + if (new_inode && S_ISDIR(new_dentry->d_inode->i_mode)) + dentry_unhash(new_dentry); + if (new_dir->i_ino == BTRFS_EMPTY_SUBVOL_DIR_OBJECTID) return -EPERM; diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c index d2e549023dedabb785985c25e3af5a2616bdd840..377b9640423543264531fe78c816eb496574d318 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, struct ceph_mds_request *req; int err; + if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) + dentry_unhash(new_dentry); + if (ceph_snap(old_dir) != ceph_snap(new_dir)) return -EXDEV; if (ceph_snap(old_dir) != CEPH_NOSNAP || diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index cee5896bcf56e414c72b586c1cd71ce9fd3dcdaf..18546b75f3843ab581c9e32f873d4a90220d0733 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, FILE_UNIX_BASIC_INFO *info_buf_target; int xid, rc, tmprc; + if (target_dentry->d_inode && S_ISDIR(target_dentry->d_inode->i_mode)) + dentry_unhash(target_dentry); + cifs_sb = CIFS_SB(source_dir->i_sb); tlink = cifs_sb_tlink(cifs_sb); if (IS_ERR(tlink)) diff --git a/fs/coda/dir.c b/fs/coda/dir.c index 9f72b75a1defd68aa70e0fdf4881ac75e2823b38..a46126fd57355642a832a43231b222ad4218b155 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, int new_length = new_dentry->d_name.len; int error; + if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) + dentry_unhash(new_dentry); + error = venus_rename(old_dir->i_sb, coda_i2f(old_dir), coda_i2f(new_dir), old_length, new_length, (const char *) old_name, (const char *)new_name); diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index c88612f0c1eb1304ce494debc5d3b7b7243f0fd6..227b409b8406b4bf4b70f4209cc49b8585d1bf4f 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, struct dentry *lower_new_dir_dentry; struct dentry *trap = NULL; + if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) + dentry_unhash(new_dentry); + lower_old_dentry = ecryptfs_dentry_to_lower(old_dentry); lower_new_dentry = ecryptfs_dentry_to_lower(new_dentry); dget(lower_old_dentry); diff --git a/fs/exofs/namei.c b/fs/exofs/namei.c index 0697175d1a38dafc4b84aec0a792db0cc9fa9a2f..de252e5acf057932c7ac0f68a41978ef77f90e57 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, struct exofs_dir_entry *old_de; int err = -ENOENT; + if (new_inode && S_ISDIR(new_inode->i_mode)) + dentry_unhash(new_dentry); + old_de = exofs_find_entry(old_dir, old_dentry, &old_page); if (!old_de) goto out; diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c index 7a5ad9762de9d262056222a93408e968a980ceb4..516c31dab97c08cbfa51ea6d3b2781c1edb84227 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, struct ext2_dir_entry_2 * old_de; int err = -ENOENT; + if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) + dentry_unhash(new_dentry); + dquot_initialize(old_dir); dquot_initialize(new_dir); diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c index 552f94d7cf3ddc7939de699e90ece9ef5679c785..f89b1d4c2fb524582bc836f99fff0b555d306cb0 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, struct ext3_dir_entry_2 * old_de, * new_de; int retval, flush_file = 0; + if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) + dentry_unhash(new_dentry); + dquot_initialize(old_dir); dquot_initialize(new_dir); diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index 957580daad78f09da3061f9a664865a473fe017c..792d06e811c15765dd49ee0f4d7a525a295466ff 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, struct ext4_dir_entry_2 *old_de, *new_de; int retval, force_da_alloc = 0; + if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) + dentry_unhash(new_dentry); + dquot_initialize(old_dir); dquot_initialize(new_dir); diff --git a/fs/fat/namei_msdos.c b/fs/fat/namei_msdos.c index 0c25cea64d241845df3751e81543f7e17fd89770..c3eccbd0203709c0ffdf798534a56847f67bce9a 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, old_inode = old_dentry->d_inode; new_inode = new_dentry->d_inode; + if (new_inode && S_ISDIR(new_inode->i_mode)) + dentry_unhash(new_dentry); + err = fat_scan(old_dir, old_name, &old_sinfo); if (err) { err = -EIO; diff --git a/fs/fat/namei_vfat.c b/fs/fat/namei_vfat.c index d7b9383bb9c2a4266c13fbfa41a4e719aac84bb5..e2466b2f8cf26c6842dbbb7517b9319a9658eb2a 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, int err, is_dir, update_dotdot, corrupt = 0; struct super_block *sb = old_dir->i_sb; + if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) + dentry_unhash(new_dentry); + old_sinfo.bh = sinfo.bh = dotdot_bh = NULL; old_inode = old_dentry->d_inode; new_inode = new_dentry->d_inode; diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 40d5c2ae4e73c35908c02c92573a3f2bc00426b6..e462a7a281bfb5b46565cf1dbbfdf6b65085f91c 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, struct fuse_rename_in inarg; struct fuse_conn *fc = get_fuse_conn(olddir); struct fuse_req *req = fuse_get_req(fc); + + if (newent->d_inode && S_ISDIR(newent->d_inode->i_mode)) + dentry_unhash(newent); + if (IS_ERR(req)) return PTR_ERR(req); diff --git a/fs/hfs/dir.c b/fs/hfs/dir.c index 616cfe02b601d27f574f2622d17b017fa43b5a49..1cb70cdba2c1dbf61cb5bbe47f6bba47d5a70d6b 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, /* Unlink destination if it already exists */ if (new_dentry->d_inode) { + if (S_ISDIR(new_dentry->d_inode->i_mode)) + dentry_unhash(new_dentry); + res = hfs_remove(new_dir, new_dentry); if (res) return res; diff --git a/fs/hfsplus/dir.c b/fs/hfsplus/dir.c index 23451a955aa0a7522e341d4ee33489d27b517007..b28835091dd084d9f1fae4709dafbc2cb1d7fc0b 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, /* Unlink destination if it already exists */ if (new_dentry->d_inode) { - if (S_ISDIR(new_dentry->d_inode->i_mode)) + if (S_ISDIR(new_dentry->d_inode->i_mode)) { + dentry_unhash(new_dentry); res = hfsplus_rmdir(new_dir, new_dentry); - else + } else { res = hfsplus_unlink(new_dir, new_dentry); + } if (res) return res; } diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c index 73ea3ba3e6581c6e4eba65cf9770a8c59ec84b7c..e6816b9e6903e0d80d4ab7505ad84b276ec12baa 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, char *from_name, *to_name; int err; + if (to->d_inode && S_ISDIR(to->d_inode->i_mode)) + dentry_unhash(to); + if ((from_name = dentry_name(from)) == NULL) return -ENOMEM; if ((to_name = dentry_name(to)) == NULL) { diff --git a/fs/hpfs/namei.c b/fs/hpfs/namei.c index b9fe158fd7ba52fad6650b2cc22d763429e90c5e..d3db95f51a4e339a49295dc819898bc1e0532ab5 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, struct buffer_head *bh; struct fnode *fnode; int err; + + if (new_inode && S_ISDIR(new_inode->i_mode)) + dentry_unhash(new_dentry); + if ((err = hpfs_chk_name(new_name, &new_len))) return err; err = 0; hpfs_adjust_length(old_name, &old_len); diff --git a/fs/jffs2/dir.c b/fs/jffs2/dir.c index 727d64439cd14bac3ede6486620082251ef00d49..05f73328b28b40bf1ba30952faa64e7568d53a43 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, uint8_t type; uint32_t now; + if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) + dentry_unhash(new_dentry); + /* The VFS will check for us and prevent trying to rename a * file over a directory and vice versa, but if it's a directory, * 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 0569daca86ad6829d913ba360fb463dcc7cfa4cb..865df16a6cf3b23d230ccfa14a1f45eaf900998a 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, jfs_info("jfs_rename: %s %s", old_dentry->d_name.name, new_dentry->d_name.name); + if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) + dentry_unhash(new_dentry); + dquot_initialize(old_dir); dquot_initialize(new_dir); diff --git a/fs/libfs.c b/fs/libfs.c index 1e2ba5a96b10974d26c9e2dc23c46d9ddd59f277..91a3710e0fe50921c106588eebd1783d56900af0 100644 --- a/fs/libfs.c +++ b/fs/libfs.c @@ -325,6 +325,9 @@ int simple_rename(struct inode *old_dir, struct dentry *old_dentry, struct inode *inode = old_dentry->d_inode; int they_are_dirs = S_ISDIR(old_dentry->d_inode->i_mode); + if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) + dentry_unhash(new_dentry); + if (!simple_empty(new_dentry)) return -ENOTEMPTY; diff --git a/fs/logfs/dir.c b/fs/logfs/dir.c index 2b32734cd31a3b3a5a3ab9ef5b7abbc7cb221c0f..f34c9cde9e94d0187462e22ca10cfcb52e2d1cd8 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, loff_t pos; int err; + if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) + dentry_unhash(new_dentry); + /* 1. locate source dd */ err = logfs_get_dd(old_dir, old_dentry, &dd, &pos); if (err) diff --git a/fs/minix/namei.c b/fs/minix/namei.c index 091626f5577de5ea0d82c43c5874fdd2cc494529..f60aed8db9c4f2d1885a51616b4b89963a9958a0 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, struct minix_dir_entry * old_de; int err = -ENOENT; + if (new_inode && S_ISDIR(new_inode->i_mode)) + dentry_unhash(new_dentry); + old_de = minix_find_entry(old_dentry, &old_page); if (!old_de) goto out; diff --git a/fs/namei.c b/fs/namei.c index 596edb5094a4e2d232c8d365f8a46d258cfc9398..787ebc8a200ade13bbacda2dc2c9a8c3897931db 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -2950,12 +2950,7 @@ SYSCALL_DEFINE2(link, const char __user *, oldname, const char __user *, newname * HOWEVER, it relies on the assumption that any object with ->lookup() * has no more than 1 dentry. If "hybrid" objects will ever appear, * we'd better make sure that there's no link(2) for them. - * d) some filesystems don't support opened-but-unlinked directories, - * either because of layout or because they are not ready to deal with - * all cases correctly. The latter will be fixed (taking this sort of - * stuff into VFS), but the former is not going away. Solution: the same - * trick as in rmdir(). - * e) conversion from fhandle to dentry may come in the wrong moment - when + * d) conversion from fhandle to dentry may come in the wrong moment - when * we are removing the target. Solution: we will have to grab ->i_mutex * in the fhandle_to_dentry code. [FIXME - current nfsfh.c relies on * ->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, mutex_lock(&target->i_mutex); if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry)) error = -EBUSY; - else { - if (target) - dentry_unhash(new_dentry); + else error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry); - } if (target) { if (!error) { target->i_flags |= S_DEAD; diff --git a/fs/ncpfs/dir.c b/fs/ncpfs/dir.c index 57336b7cb55e12ec5a556391ee1149431526a502..e3e646b06404dbce84b78d6c1d9df302d0e33dc1 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, old_dentry->d_parent->d_name.name, old_dentry->d_name.name, new_dentry->d_parent->d_name.name, new_dentry->d_name.name); + if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) + dentry_unhash(new_dentry); + ncp_age_dentry(server, old_dentry); ncp_age_dentry(server, new_dentry); diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 48483b562361526ffd5fb1f0664e3bd65355dcee..87daf79821868852ec3993d29b3266b1996a3705 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, new_dentry->d_parent->d_name.name, new_dentry->d_name.name, new_dentry->d_count); + if (new_inode && S_ISDIR(new_inode->i_mode)) + dentry_unhash(new_dentry); + /* * For non-directories, check whether the target is busy and if so, * 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 78306e6462e3ae71558e3c122f58c7e9d28750df..1102a5fbb7449c6769d6af85c048636f6cb8615b 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, struct nilfs_transaction_info ti; int err; + if (new_inode && S_ISDIR(new_inode->i_mode)) + dentry_unhash(new_dentry); + err = nilfs_transaction_begin(old_dir->i_sb, &ti, 1); if (unlikely(err)) return err; diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c index b017ebbaf3fab87e2709fbe74adb668eff12944f..f3582a6a6dac87595d0a3ccad45f0ed4d5c3b9a2 100644 --- a/fs/ocfs2/namei.c +++ b/fs/ocfs2/namei.c @@ -1066,6 +1066,9 @@ static int ocfs2_rename(struct inode *old_dir, struct ocfs2_dir_lookup_result orphan_insert = { NULL, }; struct ocfs2_dir_lookup_result target_insert = { NULL, }; + if (new_inode && S_ISDIR(new_inode->i_mode)) + dentry_unhash(new_dentry); + /* At some point it might be nice to break this function up a * bit. */ diff --git a/fs/omfs/dir.c b/fs/omfs/dir.c index 95ef4433d1a3d1d6ba8efc92be81fed5902c41b6..c368360c35a167be19592642f803dd4211f20b49 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, int err; if (new_inode) { + if (S_ISDIR(new_inode->i_mode)) + dentry_unhash(new_dentry); + /* overwriting existing file/dir */ err = omfs_remove(new_dir, new_dentry); if (err) diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c index 43e94f0f60baf4dfb74d4c0cceb7e8becbdbc7f4..76c8164d56513ace39925dd14ca1fdf64fe574f2 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, unsigned long savelink = 1; struct timespec ctime; + if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) + dentry_unhash(new_dentry); + /* three balancings: (1) old name removal, (2) new name insertion and (3) maybe "save" link insertion stat data updates: (1) old directory, diff --git a/fs/sysv/namei.c b/fs/sysv/namei.c index fac64ac31869a3656311bb81994dbcea15bedced..e2cc6756f3b1595600d8ae25f537b4e1b0b19855 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, struct sysv_dir_entry * old_de; int err = -ENOENT; + if (new_inode && S_ISDIR(new_inode->i_mode)) + dentry_unhash(new_dentry); + old_de = sysv_find_entry(old_dentry, &old_page); if (!old_de) goto out; diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c index 6ca9176c8f59f135e2b4c9a6d67abaf399f38060..d80810bb4c37d1fbff81c53998775186ccfa88ee 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, .dirtied_ino_d = ALIGN(old_inode_ui->data_len, 8) }; struct timespec time; + if (new_inode && S_ISDIR(new_inode->i_mode)) + dentry_unhash(new_dentry); + /* * Budget request settings: deletion direntry, new direntry, removing * the old inode, and changing old and new parent directory inodes. diff --git a/fs/udf/namei.c b/fs/udf/namei.c index b70f026302a5f8dc9bf089997d33b22dfb42c9b5..4d76594c2a8fbe33c9a088f74d03637b87c11bdb 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, struct kernel_lb_addr tloc; struct udf_inode_info *old_iinfo = UDF_I(old_inode); + if (new_inode && S_ISDIR(new_inode->i_mode)) + dentry_unhash(new_dentry); + ofi = udf_find_entry(old_dir, &old_dentry->d_name, &ofibh, &ocfi); if (ofi) { if (ofibh.sbh != ofibh.ebh) diff --git a/fs/ufs/namei.c b/fs/ufs/namei.c index 3a769d56c6891e6e5d2e93a77269336ece7a3cac..953ebdfc5bf7ea18d8d87e8ccd98697a90e798a7 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, struct ufs_dir_entry *old_de; int err = -ENOENT; + if (new_inode && S_ISDIR(new_inode->i_mode)) + dentry_unhash(new_dentry); + old_de = ufs_find_entry(old_dir, &old_dentry->d_name, &old_page); if (!old_de) goto out;