Commit e4eaac06 authored by Sage Weil's avatar Sage Weil Committed by Al Viro

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: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarSage Weil <sage@newdream.net>
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 79bf7c73
...@@ -840,6 +840,9 @@ v9fs_vfs_rename(struct inode *old_dir, struct dentry *old_dentry, ...@@ -840,6 +840,9 @@ v9fs_vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
struct p9_fid *newdirfid; struct p9_fid *newdirfid;
struct p9_wstat wstat; 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"); P9_DPRINTK(P9_DEBUG_VFS, "\n");
retval = 0; retval = 0;
old_inode = old_dentry->d_inode; old_inode = old_dentry->d_inode;
......
...@@ -419,6 +419,9 @@ affs_rename(struct inode *old_dir, struct dentry *old_dentry, ...@@ -419,6 +419,9 @@ affs_rename(struct inode *old_dir, struct dentry *old_dentry,
struct buffer_head *bh = NULL; struct buffer_head *bh = NULL;
int retval; 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", 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)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); (u32)new_dir->i_ino, (int)new_dentry->d_name.len, new_dentry->d_name.name);
......
...@@ -1148,6 +1148,9 @@ static int afs_rename(struct inode *old_dir, struct dentry *old_dentry, ...@@ -1148,6 +1148,9 @@ static int afs_rename(struct inode *old_dir, struct dentry *old_dentry,
struct key *key; struct key *key;
int ret; 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); vnode = AFS_FS_I(old_dentry->d_inode);
orig_dvnode = AFS_FS_I(old_dir); orig_dvnode = AFS_FS_I(old_dir);
new_dvnode = AFS_FS_I(new_dir); new_dvnode = AFS_FS_I(new_dir);
......
...@@ -224,6 +224,9 @@ static int bfs_rename(struct inode *old_dir, struct dentry *old_dentry, ...@@ -224,6 +224,9 @@ static int bfs_rename(struct inode *old_dir, struct dentry *old_dentry,
struct bfs_sb_info *info; struct bfs_sb_info *info;
int error = -ENOENT; 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_bh = new_bh = NULL;
old_inode = old_dentry->d_inode; old_inode = old_dentry->d_inode;
if (S_ISDIR(old_inode->i_mode)) if (S_ISDIR(old_inode->i_mode))
......
...@@ -6994,6 +6994,9 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry, ...@@ -6994,6 +6994,9 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry,
u64 root_objectid; u64 root_objectid;
int ret; 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) if (new_dir->i_ino == BTRFS_EMPTY_SUBVOL_DIR_OBJECTID)
return -EPERM; return -EPERM;
......
...@@ -869,6 +869,9 @@ static int ceph_rename(struct inode *old_dir, struct dentry *old_dentry, ...@@ -869,6 +869,9 @@ static int ceph_rename(struct inode *old_dir, struct dentry *old_dentry,
struct ceph_mds_request *req; struct ceph_mds_request *req;
int err; 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)) if (ceph_snap(old_dir) != ceph_snap(new_dir))
return -EXDEV; return -EXDEV;
if (ceph_snap(old_dir) != CEPH_NOSNAP || if (ceph_snap(old_dir) != CEPH_NOSNAP ||
......
...@@ -1571,6 +1571,9 @@ int cifs_rename(struct inode *source_dir, struct dentry *source_dentry, ...@@ -1571,6 +1571,9 @@ int cifs_rename(struct inode *source_dir, struct dentry *source_dentry,
FILE_UNIX_BASIC_INFO *info_buf_target; FILE_UNIX_BASIC_INFO *info_buf_target;
int xid, rc, tmprc; 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); cifs_sb = CIFS_SB(source_dir->i_sb);
tlink = cifs_sb_tlink(cifs_sb); tlink = cifs_sb_tlink(cifs_sb);
if (IS_ERR(tlink)) if (IS_ERR(tlink))
......
...@@ -361,6 +361,9 @@ static int coda_rename(struct inode *old_dir, struct dentry *old_dentry, ...@@ -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 new_length = new_dentry->d_name.len;
int error; 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), error = venus_rename(old_dir->i_sb, coda_i2f(old_dir),
coda_i2f(new_dir), old_length, new_length, coda_i2f(new_dir), old_length, new_length,
(const char *) old_name, (const char *)new_name); (const char *) old_name, (const char *)new_name);
......
...@@ -573,6 +573,9 @@ ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry, ...@@ -573,6 +573,9 @@ ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry,
struct dentry *lower_new_dir_dentry; struct dentry *lower_new_dir_dentry;
struct dentry *trap = NULL; 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_old_dentry = ecryptfs_dentry_to_lower(old_dentry);
lower_new_dentry = ecryptfs_dentry_to_lower(new_dentry); lower_new_dentry = ecryptfs_dentry_to_lower(new_dentry);
dget(lower_old_dentry); dget(lower_old_dentry);
......
...@@ -251,6 +251,9 @@ static int exofs_rename(struct inode *old_dir, struct dentry *old_dentry, ...@@ -251,6 +251,9 @@ static int exofs_rename(struct inode *old_dir, struct dentry *old_dentry,
struct exofs_dir_entry *old_de; struct exofs_dir_entry *old_de;
int err = -ENOENT; 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); old_de = exofs_find_entry(old_dir, old_dentry, &old_page);
if (!old_de) if (!old_de)
goto out; goto out;
......
...@@ -320,6 +320,9 @@ static int ext2_rename (struct inode * old_dir, struct dentry * old_dentry, ...@@ -320,6 +320,9 @@ static int ext2_rename (struct inode * old_dir, struct dentry * old_dentry,
struct ext2_dir_entry_2 * old_de; struct ext2_dir_entry_2 * old_de;
int err = -ENOENT; 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(old_dir);
dquot_initialize(new_dir); dquot_initialize(new_dir);
......
...@@ -2298,6 +2298,9 @@ static int ext3_rename (struct inode * old_dir, struct dentry *old_dentry, ...@@ -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; struct ext3_dir_entry_2 * old_de, * new_de;
int retval, flush_file = 0; 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(old_dir);
dquot_initialize(new_dir); dquot_initialize(new_dir);
......
...@@ -2352,6 +2352,9 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry, ...@@ -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; struct ext4_dir_entry_2 *old_de, *new_de;
int retval, force_da_alloc = 0; 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(old_dir);
dquot_initialize(new_dir); dquot_initialize(new_dir);
......
...@@ -459,6 +459,9 @@ static int do_msdos_rename(struct inode *old_dir, unsigned char *old_name, ...@@ -459,6 +459,9 @@ static int do_msdos_rename(struct inode *old_dir, unsigned char *old_name,
old_inode = old_dentry->d_inode; old_inode = old_dentry->d_inode;
new_inode = new_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); err = fat_scan(old_dir, old_name, &old_sinfo);
if (err) { if (err) {
err = -EIO; err = -EIO;
......
...@@ -933,6 +933,9 @@ static int vfat_rename(struct inode *old_dir, struct dentry *old_dentry, ...@@ -933,6 +933,9 @@ static int vfat_rename(struct inode *old_dir, struct dentry *old_dentry,
int err, is_dir, update_dotdot, corrupt = 0; int err, is_dir, update_dotdot, corrupt = 0;
struct super_block *sb = old_dir->i_sb; 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_sinfo.bh = sinfo.bh = dotdot_bh = NULL;
old_inode = old_dentry->d_inode; old_inode = old_dentry->d_inode;
new_inode = new_dentry->d_inode; new_inode = new_dentry->d_inode;
......
...@@ -693,6 +693,10 @@ static int fuse_rename(struct inode *olddir, struct dentry *oldent, ...@@ -693,6 +693,10 @@ static int fuse_rename(struct inode *olddir, struct dentry *oldent,
struct fuse_rename_in inarg; struct fuse_rename_in inarg;
struct fuse_conn *fc = get_fuse_conn(olddir); struct fuse_conn *fc = get_fuse_conn(olddir);
struct fuse_req *req = fuse_get_req(fc); 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)) if (IS_ERR(req))
return PTR_ERR(req); return PTR_ERR(req);
......
...@@ -286,6 +286,9 @@ static int hfs_rename(struct inode *old_dir, struct dentry *old_dentry, ...@@ -286,6 +286,9 @@ static int hfs_rename(struct inode *old_dir, struct dentry *old_dentry,
/* Unlink destination if it already exists */ /* Unlink destination if it already exists */
if (new_dentry->d_inode) { 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); res = hfs_remove(new_dir, new_dentry);
if (res) if (res)
return res; return res;
......
...@@ -469,10 +469,12 @@ static int hfsplus_rename(struct inode *old_dir, struct dentry *old_dentry, ...@@ -469,10 +469,12 @@ static int hfsplus_rename(struct inode *old_dir, struct dentry *old_dentry,
/* Unlink destination if it already exists */ /* Unlink destination if it already exists */
if (new_dentry->d_inode) { 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); res = hfsplus_rmdir(new_dir, new_dentry);
else } else {
res = hfsplus_unlink(new_dir, new_dentry); res = hfsplus_unlink(new_dir, new_dentry);
}
if (res) if (res)
return res; return res;
} }
......
...@@ -738,6 +738,9 @@ int hostfs_rename(struct inode *from_ino, struct dentry *from, ...@@ -738,6 +738,9 @@ int hostfs_rename(struct inode *from_ino, struct dentry *from,
char *from_name, *to_name; char *from_name, *to_name;
int err; int err;
if (to->d_inode && S_ISDIR(to->d_inode->i_mode))
dentry_unhash(to);
if ((from_name = dentry_name(from)) == NULL) if ((from_name = dentry_name(from)) == NULL)
return -ENOMEM; return -ENOMEM;
if ((to_name = dentry_name(to)) == NULL) { if ((to_name = dentry_name(to)) == NULL) {
......
...@@ -561,6 +561,10 @@ static int hpfs_rename(struct inode *old_dir, struct dentry *old_dentry, ...@@ -561,6 +561,10 @@ static int hpfs_rename(struct inode *old_dir, struct dentry *old_dentry,
struct buffer_head *bh; struct buffer_head *bh;
struct fnode *fnode; struct fnode *fnode;
int err; 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; if ((err = hpfs_chk_name(new_name, &new_len))) return err;
err = 0; err = 0;
hpfs_adjust_length(old_name, &old_len); hpfs_adjust_length(old_name, &old_len);
......
...@@ -786,6 +786,9 @@ static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry, ...@@ -786,6 +786,9 @@ static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry,
uint8_t type; uint8_t type;
uint32_t now; 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 /* 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, * 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 * the VFS can't check whether the victim is empty. The filesystem
......
...@@ -1097,6 +1097,9 @@ static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry, ...@@ -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, jfs_info("jfs_rename: %s %s", old_dentry->d_name.name,
new_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(old_dir);
dquot_initialize(new_dir); dquot_initialize(new_dir);
......
...@@ -325,6 +325,9 @@ int simple_rename(struct inode *old_dir, struct dentry *old_dentry, ...@@ -325,6 +325,9 @@ int simple_rename(struct inode *old_dir, struct dentry *old_dentry,
struct inode *inode = old_dentry->d_inode; struct inode *inode = old_dentry->d_inode;
int they_are_dirs = S_ISDIR(old_dentry->d_inode->i_mode); 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)) if (!simple_empty(new_dentry))
return -ENOTEMPTY; return -ENOTEMPTY;
......
...@@ -624,6 +624,9 @@ static int logfs_rename_cross(struct inode *old_dir, struct dentry *old_dentry, ...@@ -624,6 +624,9 @@ static int logfs_rename_cross(struct inode *old_dir, struct dentry *old_dentry,
loff_t pos; loff_t pos;
int err; int err;
if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode))
dentry_unhash(new_dentry);
/* 1. locate source dd */ /* 1. locate source dd */
err = logfs_get_dd(old_dir, old_dentry, &dd, &pos); err = logfs_get_dd(old_dir, old_dentry, &dd, &pos);
if (err) if (err)
......
...@@ -192,6 +192,9 @@ static int minix_rename(struct inode * old_dir, struct dentry *old_dentry, ...@@ -192,6 +192,9 @@ static int minix_rename(struct inode * old_dir, struct dentry *old_dentry,
struct minix_dir_entry * old_de; struct minix_dir_entry * old_de;
int err = -ENOENT; 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); old_de = minix_find_entry(old_dentry, &old_page);
if (!old_de) if (!old_de)
goto out; goto out;
......
...@@ -2950,12 +2950,7 @@ SYSCALL_DEFINE2(link, const char __user *, oldname, const char __user *, newname ...@@ -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() * HOWEVER, it relies on the assumption that any object with ->lookup()
* has no more than 1 dentry. If "hybrid" objects will ever appear, * 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. * we'd better make sure that there's no link(2) for them.
* d) some filesystems don't support opened-but-unlinked directories, * d) conversion from fhandle to dentry may come in the wrong moment - when
* 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
* we are removing the target. Solution: we will have to grab ->i_mutex * 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 * in the fhandle_to_dentry code. [FIXME - current nfsfh.c relies on
* ->i_mutex on parents, which works but leads to some truly excessive * ->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,11 +2981,8 @@ static int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
mutex_lock(&target->i_mutex); mutex_lock(&target->i_mutex);
if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry)) if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry))
error = -EBUSY; error = -EBUSY;
else { else
if (target)
dentry_unhash(new_dentry);
error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry); error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
}
if (target) { if (target) {
if (!error) { if (!error) {
target->i_flags |= S_DEAD; target->i_flags |= S_DEAD;
......
...@@ -1141,6 +1141,9 @@ static int ncp_rename(struct inode *old_dir, struct dentry *old_dentry, ...@@ -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, old_dentry->d_parent->d_name.name, old_dentry->d_name.name,
new_dentry->d_parent->d_name.name, new_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, old_dentry);
ncp_age_dentry(server, new_dentry); ncp_age_dentry(server, new_dentry);
......
...@@ -1959,6 +1959,9 @@ static int nfs_rename(struct inode *old_dir, struct dentry *old_dentry, ...@@ -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_parent->d_name.name, new_dentry->d_name.name,
new_dentry->d_count); 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, * 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 * make a copy of the dentry and then do a silly-rename. If the
......
...@@ -371,6 +371,9 @@ static int nilfs_rename(struct inode *old_dir, struct dentry *old_dentry, ...@@ -371,6 +371,9 @@ static int nilfs_rename(struct inode *old_dir, struct dentry *old_dentry,
struct nilfs_transaction_info ti; struct nilfs_transaction_info ti;
int err; 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); err = nilfs_transaction_begin(old_dir->i_sb, &ti, 1);
if (unlikely(err)) if (unlikely(err))
return err; return err;
......
...@@ -1066,6 +1066,9 @@ static int ocfs2_rename(struct inode *old_dir, ...@@ -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 orphan_insert = { NULL, };
struct ocfs2_dir_lookup_result target_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 /* At some point it might be nice to break this function up a
* bit. */ * bit. */
......
...@@ -382,6 +382,9 @@ static int omfs_rename(struct inode *old_dir, struct dentry *old_dentry, ...@@ -382,6 +382,9 @@ static int omfs_rename(struct inode *old_dir, struct dentry *old_dentry,
int err; int err;
if (new_inode) { if (new_inode) {
if (S_ISDIR(new_inode->i_mode))
dentry_unhash(new_dentry);
/* overwriting existing file/dir */ /* overwriting existing file/dir */
err = omfs_remove(new_dir, new_dentry); err = omfs_remove(new_dir, new_dentry);
if (err) if (err)
......
...@@ -1227,6 +1227,9 @@ static int reiserfs_rename(struct inode *old_dir, struct dentry *old_dentry, ...@@ -1227,6 +1227,9 @@ static int reiserfs_rename(struct inode *old_dir, struct dentry *old_dentry,
unsigned long savelink = 1; unsigned long savelink = 1;
struct timespec ctime; 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 /* three balancings: (1) old name removal, (2) new name insertion
and (3) maybe "save" link insertion and (3) maybe "save" link insertion
stat data updates: (1) old directory, stat data updates: (1) old directory,
......
...@@ -224,6 +224,9 @@ static int sysv_rename(struct inode * old_dir, struct dentry * old_dentry, ...@@ -224,6 +224,9 @@ static int sysv_rename(struct inode * old_dir, struct dentry * old_dentry,
struct sysv_dir_entry * old_de; struct sysv_dir_entry * old_de;
int err = -ENOENT; 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); old_de = sysv_find_entry(old_dentry, &old_page);
if (!old_de) if (!old_de)
goto out; goto out;
......
...@@ -978,6 +978,9 @@ static int ubifs_rename(struct inode *old_dir, struct dentry *old_dentry, ...@@ -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) }; .dirtied_ino_d = ALIGN(old_inode_ui->data_len, 8) };
struct timespec time; struct timespec time;
if (new_inode && S_ISDIR(new_inode->i_mode))
dentry_unhash(new_dentry);
/* /*
* Budget request settings: deletion direntry, new direntry, removing * Budget request settings: deletion direntry, new direntry, removing
* the old inode, and changing old and new parent directory inodes. * the old inode, and changing old and new parent directory inodes.
......
...@@ -1083,6 +1083,9 @@ static int udf_rename(struct inode *old_dir, struct dentry *old_dentry, ...@@ -1083,6 +1083,9 @@ static int udf_rename(struct inode *old_dir, struct dentry *old_dentry,
struct kernel_lb_addr tloc; struct kernel_lb_addr tloc;
struct udf_inode_info *old_iinfo = UDF_I(old_inode); 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); ofi = udf_find_entry(old_dir, &old_dentry->d_name, &ofibh, &ocfi);
if (ofi) { if (ofi) {
if (ofibh.sbh != ofibh.ebh) if (ofibh.sbh != ofibh.ebh)
......
...@@ -284,6 +284,9 @@ static int ufs_rename(struct inode *old_dir, struct dentry *old_dentry, ...@@ -284,6 +284,9 @@ static int ufs_rename(struct inode *old_dir, struct dentry *old_dentry,
struct ufs_dir_entry *old_de; struct ufs_dir_entry *old_de;
int err = -ENOENT; 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); old_de = ufs_find_entry(old_dir, &old_dentry->d_name, &old_page);
if (!old_de) if (!old_de)
goto out; goto out;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment