* [PATCH 00/18] clean up VFS dentry_hash (mis)behavior
@ 2011-05-10 4:43 Sage Weil
2011-05-10 4:43 ` [PATCH 01/18] vfs: dentry_unhash immediately prior to rmdir Sage Weil
` (18 more replies)
0 siblings, 19 replies; 26+ messages in thread
From: Sage Weil @ 2011-05-10 4:43 UTC (permalink / raw)
To: viro, hch, linux-fsdevel; +Cc: Sage Weil
Hi Al, Christoph, everyone,
This patch series aims to make the VFS less paranoid about fs behavior
when it comes to rmdir and dentry hashing. There are a few old/simple
file systems that can't handle references to directories that are
removed from the namespace (e.g. mkdir t ; cd t ; rmdir ../t). To keep
them happy, the dentry_unhash() helper is called prior to rmdir and
vfs_rename_dir (if the target is an existing directory) to unhash it,
even though this is unnecessary for most of the file systems people
actually use. The original idea was that a lazy fs can
if (!d_unhashed(dir))
return -EBUSY;
In reality, the most common file systems don't want/need this (and, in
fact, I can't find any that actually do).
This patch set cleans up the VFS behavior by removing _all_ unhashing
behavior by pushing it down into the file systems, where it can either
be left alone (to preserve old behavior) or removed. There is also a
patch that strips out some useless (presumably historic) refcount
twiddling in dentry_unhash.
The VFS unhashing behavior already causes weird behavior with rename
(currently masked by existing d_revalidate implementations in a very
fragile way; see Miklos' patch, #7), and is one roadblock preventing
ceph from managing the consistently of the dcache in a non-racy way.
I included patches to remove the pushed-down calls from a few of the
more commonly used file systems. I'm sure it can also be removed from
others, but I'd prefer to defer to those maintainers' judgement.
Al, Christoph, please let me know if this looks like a reasonable
cleanup, and/or if there is anything you'd like to see before this (or
something like it) can be merged.
Thanks!
sage
Miklos Szeredi (1):
vfs: fix vfs_rename_dir for FS_RENAME_DOES_D_MOVE filesystems
Sage Weil (17):
vfs: dentry_unhash immediately prior to rmdir
vfs: remove dget() from dentry_unhash()
vfs: push dentry_unhash on rmdir into file systems
vfs: push dentry_unhash on rename_dir into file systems
vfs: update dentry_unhash() comment
libfs: drop unneeded dentry_unhash
ceph: remove unnecessary dentry_unhash calls
xfs: remove unnecessary dentry_unhash from rmdir/rename_dir
btrfs: remove unnecessary dentry_unhash in rmdir/rename_dir
ext4: remove unnecessary dentry_unhash on rmdir/rename_dir
ext3: remove unnecessary dentry_unhash on rmdir/rename_dir
ext2: remove unnecessary dentry_unhash on rmdir/rename_dir
nfs: remove unnecessary dentry_unhash on rmdir/rename_dir
exofs: remove unnecessary dentry_unhash on rmdir/rename_dir
ocfs2: remove unnecessary dentry_unhash on rmdir/rename_dir
gfs2: remove unnecessary dentry_unhash on rmdir/rename_dir
cifs: remove unnecessary dentry_unhash on rmdir/rename_dir
fs/9p/vfs_inode.c | 4 ++++
fs/affs/namei.c | 5 +++++
fs/afs/dir.c | 5 +++++
fs/autofs4/root.c | 2 ++
fs/bfs/dir.c | 3 +++
fs/coda/dir.c | 5 +++++
fs/configfs/dir.c | 2 ++
fs/ecryptfs/inode.c | 5 +++++
fs/fat/namei_msdos.c | 5 +++++
fs/fat/namei_vfat.c | 5 +++++
fs/fuse/dir.c | 6 ++++++
fs/hfs/dir.c | 6 ++++++
fs/hfsplus/dir.c | 8 ++++++--
fs/hostfs/hostfs_kern.c | 5 +++++
fs/hpfs/namei.c | 9 ++++++---
fs/jffs2/dir.c | 5 +++++
fs/jfs/namei.c | 5 +++++
fs/logfs/dir.c | 5 +++++
fs/minix/namei.c | 5 +++++
fs/namei.c | 21 ++++++---------------
fs/ncpfs/dir.c | 5 +++++
fs/nilfs2/namei.c | 5 +++++
fs/omfs/dir.c | 11 +++++++++--
fs/reiserfs/namei.c | 5 +++++
fs/reiserfs/xattr.c | 1 -
fs/sysv/namei.c | 5 +++++
fs/ubifs/dir.c | 5 +++++
fs/udf/namei.c | 5 +++++
fs/ufs/namei.c | 5 +++++
29 files changed, 140 insertions(+), 23 deletions(-)
^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH 01/18] vfs: dentry_unhash immediately prior to rmdir
2011-05-10 4:43 [PATCH 00/18] clean up VFS dentry_hash (mis)behavior Sage Weil
@ 2011-05-10 4:43 ` Sage Weil
2011-05-10 8:12 ` Christoph Hellwig
2011-05-10 4:43 ` [PATCH 02/18] vfs: remove dget() from dentry_unhash() Sage Weil
` (17 subsequent siblings)
18 siblings, 1 reply; 26+ messages in thread
From: Sage Weil @ 2011-05-10 4:43 UTC (permalink / raw)
To: viro, hch, linux-fsdevel; +Cc: Sage Weil
This presumes that there is no reason to unhash a dentry if we fail because
it is a mountpoint or the LSM check fails, and that the LSM checks do not
depend on the dentry being unhashed.
Signed-off-by: Sage Weil <sage@newdream.net>
---
fs/namei.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/fs/namei.c b/fs/namei.c
index 54fc993..d71c035 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -2664,24 +2664,24 @@ int vfs_rmdir(struct inode *dir, struct dentry *dentry)
return -EPERM;
mutex_lock(&dentry->d_inode->i_mutex);
- dentry_unhash(dentry);
if (d_mountpoint(dentry))
error = -EBUSY;
else {
error = security_inode_rmdir(dir, dentry);
if (!error) {
+ dentry_unhash(dentry);
error = dir->i_op->rmdir(dir, dentry);
if (!error) {
dentry->d_inode->i_flags |= S_DEAD;
dont_mount(dentry);
}
+ dput(dentry);
}
}
mutex_unlock(&dentry->d_inode->i_mutex);
if (!error) {
d_delete(dentry);
}
- dput(dentry);
return error;
}
--
1.7.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 02/18] vfs: remove dget() from dentry_unhash()
2011-05-10 4:43 [PATCH 00/18] clean up VFS dentry_hash (mis)behavior Sage Weil
2011-05-10 4:43 ` [PATCH 01/18] vfs: dentry_unhash immediately prior to rmdir Sage Weil
@ 2011-05-10 4:43 ` Sage Weil
2011-05-10 4:43 ` [PATCH 03/18] vfs: push dentry_unhash on rmdir into file systems Sage Weil
` (16 subsequent siblings)
18 siblings, 0 replies; 26+ messages in thread
From: Sage Weil @ 2011-05-10 4:43 UTC (permalink / raw)
To: viro, hch, linux-fsdevel; +Cc: Sage Weil
This serves no useful purpose that I can discern. All callers (rename,
rmdir) hold their own reference to the dentry.
A quick audit of all file systems showed no relevant checks on the value
of d_count in vfs_rmdir/vfs_rename_dir paths.
Signed-off-by: Sage Weil <sage@newdream.net>
---
fs/hpfs/namei.c | 3 ---
fs/namei.c | 5 +----
fs/reiserfs/xattr.c | 1 -
3 files changed, 1 insertions(+), 8 deletions(-)
diff --git a/fs/hpfs/namei.c b/fs/hpfs/namei.c
index d5f8c8a..b1c72a9 100644
--- a/fs/hpfs/namei.c
+++ b/fs/hpfs/namei.c
@@ -414,7 +414,6 @@ again:
mutex_unlock(&hpfs_i(inode)->i_parent_mutex);
dentry_unhash(dentry);
if (!d_unhashed(dentry)) {
- dput(dentry);
hpfs_unlock(dir->i_sb);
return -ENOSPC;
}
@@ -422,7 +421,6 @@ again:
!S_ISREG(inode->i_mode) ||
get_write_access(inode)) {
d_rehash(dentry);
- dput(dentry);
} else {
struct iattr newattrs;
/*printk("HPFS: truncating file before delete.\n");*/
@@ -430,7 +428,6 @@ again:
newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME;
err = notify_change(dentry, &newattrs);
put_write_access(inode);
- dput(dentry);
if (!err)
goto again;
}
diff --git a/fs/namei.c b/fs/namei.c
index d71c035..058302a 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -2645,10 +2645,9 @@ SYSCALL_DEFINE2(mkdir, const char __user *, pathname, int, mode)
*/
void dentry_unhash(struct dentry *dentry)
{
- dget(dentry);
shrink_dcache_parent(dentry);
spin_lock(&dentry->d_lock);
- if (dentry->d_count == 2)
+ if (dentry->d_count == 1)
__d_drop(dentry);
spin_unlock(&dentry->d_lock);
}
@@ -2675,7 +2674,6 @@ int vfs_rmdir(struct inode *dir, struct dentry *dentry)
dentry->d_inode->i_flags |= S_DEAD;
dont_mount(dentry);
}
- dput(dentry);
}
}
mutex_unlock(&dentry->d_inode->i_mutex);
@@ -3102,7 +3100,6 @@ static int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
mutex_unlock(&target->i_mutex);
if (d_unhashed(new_dentry))
d_rehash(new_dentry);
- dput(new_dentry);
}
if (!error)
if (!(old_dir->i_sb->s_type->fs_flags & FS_RENAME_DOES_D_MOVE))
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c
index 47d2a44..50f1abc 100644
--- a/fs/reiserfs/xattr.c
+++ b/fs/reiserfs/xattr.c
@@ -105,7 +105,6 @@ static int xattr_rmdir(struct inode *dir, struct dentry *dentry)
mutex_unlock(&dentry->d_inode->i_mutex);
if (!error)
d_delete(dentry);
- dput(dentry);
return error;
}
--
1.7.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 03/18] vfs: push dentry_unhash on rmdir into file systems
2011-05-10 4:43 [PATCH 00/18] clean up VFS dentry_hash (mis)behavior Sage Weil
2011-05-10 4:43 ` [PATCH 01/18] vfs: dentry_unhash immediately prior to rmdir Sage Weil
2011-05-10 4:43 ` [PATCH 02/18] vfs: remove dget() from dentry_unhash() Sage Weil
@ 2011-05-10 4:43 ` Sage Weil
2011-05-10 4:43 ` [PATCH 04/18] vfs: push dentry_unhash on rename_dir " Sage Weil
` (15 subsequent siblings)
18 siblings, 0 replies; 26+ messages in thread
From: Sage Weil @ 2011-05-10 4:43 UTC (permalink / raw)
To: viro, hch, linux-fsdevel; +Cc: Sage Weil
Only a few file systems need this. Start by pushing it down into each
fs rmdir method so it can be dealt with on a per-fs basis.
This does not change behavior for any in-tree file systems.
Signed-off-by: Sage Weil <sage@newdream.net>
---
fs/9p/vfs_inode.c | 1 +
fs/affs/namei.c | 2 ++
fs/afs/dir.c | 2 ++
fs/autofs4/root.c | 2 ++
fs/btrfs/inode.c | 2 ++
fs/ceph/dir.c | 3 +++
fs/cifs/inode.c | 2 ++
fs/coda/dir.c | 2 ++
fs/configfs/dir.c | 2 ++
fs/ecryptfs/inode.c | 2 ++
fs/exofs/namei.c | 2 ++
fs/ext2/namei.c | 2 ++
fs/ext3/namei.c | 2 ++
fs/ext4/namei.c | 2 ++
fs/fat/namei_msdos.c | 2 ++
fs/fat/namei_vfat.c | 2 ++
fs/fuse/dir.c | 2 ++
fs/gfs2/ops_inode.c | 2 ++
fs/hfs/dir.c | 3 +++
fs/hfsplus/dir.c | 2 ++
fs/hostfs/hostfs_kern.c | 2 ++
fs/hpfs/namei.c | 2 ++
fs/jffs2/dir.c | 2 ++
fs/jfs/namei.c | 2 ++
fs/libfs.c | 2 ++
fs/logfs/dir.c | 2 ++
fs/minix/namei.c | 2 ++
fs/namei.c | 1 -
fs/ncpfs/dir.c | 2 ++
fs/nfs/dir.c | 2 ++
fs/nilfs2/namei.c | 2 ++
fs/ocfs2/namei.c | 3 +++
fs/omfs/dir.c | 8 ++++++--
fs/reiserfs/namei.c | 2 ++
fs/sysv/namei.c | 2 ++
fs/ubifs/dir.c | 2 ++
fs/udf/namei.c | 2 ++
fs/ufs/namei.c | 2 ++
fs/xfs/linux-2.6/xfs_iops.c | 3 +++
39 files changed, 83 insertions(+), 3 deletions(-)
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
index 7f6c677..ecd7717 100644
--- a/fs/9p/vfs_inode.c
+++ b/fs/9p/vfs_inode.c
@@ -814,6 +814,7 @@ int v9fs_vfs_unlink(struct inode *i, struct dentry *d)
int v9fs_vfs_rmdir(struct inode *i, struct dentry *d)
{
+ dentry_unhash(d);
return v9fs_remove(i, d, 1);
}
diff --git a/fs/affs/namei.c b/fs/affs/namei.c
index e3e9efc..d087153 100644
--- a/fs/affs/namei.c
+++ b/fs/affs/namei.c
@@ -320,6 +320,8 @@ affs_rmdir(struct inode *dir, struct dentry *dentry)
dentry->d_inode->i_ino,
(int)dentry->d_name.len, dentry->d_name.name);
+ dentry_unhash(dentry);
+
return affs_remove_header(dentry);
}
diff --git a/fs/afs/dir.c b/fs/afs/dir.c
index 20c106f..9a7f414 100644
--- a/fs/afs/dir.c
+++ b/fs/afs/dir.c
@@ -845,6 +845,8 @@ static int afs_rmdir(struct inode *dir, struct dentry *dentry)
_enter("{%x:%u},{%s}",
dvnode->fid.vid, dvnode->fid.vnode, dentry->d_name.name);
+ dentry_unhash(dentry);
+
ret = -ENAMETOOLONG;
if (dentry->d_name.len >= AFSNAMEMAX)
goto error;
diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c
index f55ae23..87d95a8 100644
--- a/fs/autofs4/root.c
+++ b/fs/autofs4/root.c
@@ -583,6 +583,8 @@ static int autofs4_dir_unlink(struct inode *dir, struct dentry *dentry)
if (!autofs4_oz_mode(sbi) && !capable(CAP_SYS_ADMIN))
return -EACCES;
+ dentry_unhash(dentry);
+
if (atomic_dec_and_test(&ino->count)) {
p_ino = autofs4_dentry_ino(dentry->d_parent);
if (p_ino && dentry->d_parent != dentry)
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 7cd8ab0..c692dad 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -3062,6 +3062,8 @@ static int btrfs_rmdir(struct inode *dir, struct dentry *dentry)
inode->i_ino == BTRFS_FIRST_FREE_OBJECTID)
return -ENOTEMPTY;
+ dentry_unhash(dentry);
+
trans = __unlink_start_trans(dir, dentry);
if (IS_ERR(trans))
return PTR_ERR(trans);
diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c
index 1a867a3..d2e5490 100644
--- a/fs/ceph/dir.c
+++ b/fs/ceph/dir.c
@@ -827,6 +827,9 @@ static int ceph_unlink(struct inode *dir, struct dentry *dentry)
int err = -EROFS;
int op;
+ if ((dentry->d_inode->i_mode & S_IFMT) == S_IFDIR)
+ dentry_unhash(dentry);
+
if (ceph_snap(dir) == CEPH_SNAPDIR) {
/* rmdir .snap/foo is RMSNAP */
dout("rmsnap dir %p '%.*s' dn %p\n", dir, dentry->d_name.len,
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 8852470..cee5896 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -1461,6 +1461,8 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry)
cFYI(1, "cifs_rmdir, inode = 0x%p", inode);
+ dentry_unhash(direntry);
+
xid = GetXid();
full_path = build_path_from_dentry(direntry);
diff --git a/fs/coda/dir.c b/fs/coda/dir.c
index 2b8dae4..9f72b75 100644
--- a/fs/coda/dir.c
+++ b/fs/coda/dir.c
@@ -336,6 +336,8 @@ static int coda_rmdir(struct inode *dir, struct dentry *de)
int len = de->d_name.len;
int error;
+ dentry_unhash(de);
+
error = venus_rmdir(dir->i_sb, coda_i2f(dir), name, len);
if (!error) {
/* VFS may delete the child */
diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c
index 3313dd1..9908c20 100644
--- a/fs/configfs/dir.c
+++ b/fs/configfs/dir.c
@@ -1355,6 +1355,8 @@ static int configfs_rmdir(struct inode *dir, struct dentry *dentry)
struct module *subsys_owner = NULL, *dead_item_owner = NULL;
int ret;
+ dentry_unhash(dentry);
+
if (dentry->d_parent == configfs_sb->s_root)
return -EPERM;
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c
index 4d4cc6a..c88612f 100644
--- a/fs/ecryptfs/inode.c
+++ b/fs/ecryptfs/inode.c
@@ -521,6 +521,8 @@ static int ecryptfs_rmdir(struct inode *dir, struct dentry *dentry)
struct dentry *lower_dir_dentry;
int rc;
+ dentry_unhash(dentry);
+
lower_dentry = ecryptfs_dentry_to_lower(dentry);
dget(dentry);
lower_dir_dentry = lock_parent(lower_dentry);
diff --git a/fs/exofs/namei.c b/fs/exofs/namei.c
index 4d70db1..0697175 100644
--- a/fs/exofs/namei.c
+++ b/fs/exofs/namei.c
@@ -227,6 +227,8 @@ static int exofs_rmdir(struct inode *dir, struct dentry *dentry)
struct inode *inode = dentry->d_inode;
int err = -ENOTEMPTY;
+ dentry_unhash(dentry);
+
if (exofs_empty_dir(inode)) {
err = exofs_unlink(dir, dentry);
if (!err) {
diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c
index ed5c5d4..7a5ad97 100644
--- a/fs/ext2/namei.c
+++ b/fs/ext2/namei.c
@@ -296,6 +296,8 @@ static int ext2_rmdir (struct inode * dir, struct dentry *dentry)
struct inode * inode = dentry->d_inode;
int err = -ENOTEMPTY;
+ dentry_unhash(dentry);
+
if (ext2_empty_dir(inode)) {
err = ext2_unlink(dir, dentry);
if (!err) {
diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c
index 32f3b86..552f94d 100644
--- a/fs/ext3/namei.c
+++ b/fs/ext3/namei.c
@@ -2074,6 +2074,8 @@ static int ext3_rmdir (struct inode * dir, struct dentry *dentry)
struct ext3_dir_entry_2 * de;
handle_t *handle;
+ dentry_unhash(dentry);
+
/* Initialize quotas before so that eventual writes go in
* separate transaction */
dquot_initialize(dir);
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index 67fd0b0..957580d 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -2123,6 +2123,8 @@ static int ext4_rmdir(struct inode *dir, struct dentry *dentry)
struct ext4_dir_entry_2 *de;
handle_t *handle;
+ dentry_unhash(dentry);
+
/* Initialize quotas before so that eventual writes go in
* separate transaction */
dquot_initialize(dir);
diff --git a/fs/fat/namei_msdos.c b/fs/fat/namei_msdos.c
index 7114990..0c25cea 100644
--- a/fs/fat/namei_msdos.c
+++ b/fs/fat/namei_msdos.c
@@ -326,6 +326,8 @@ static int msdos_rmdir(struct inode *dir, struct dentry *dentry)
struct fat_slot_info sinfo;
int err;
+ dentry_unhash(dentry);
+
lock_super(sb);
/*
* Check whether the directory is not in use, then check
diff --git a/fs/fat/namei_vfat.c b/fs/fat/namei_vfat.c
index adae3fb..d7b9383 100644
--- a/fs/fat/namei_vfat.c
+++ b/fs/fat/namei_vfat.c
@@ -824,6 +824,8 @@ static int vfat_rmdir(struct inode *dir, struct dentry *dentry)
struct fat_slot_info sinfo;
int err;
+ dentry_unhash(dentry);
+
lock_super(sb);
err = fat_dir_empty(inode);
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index c6ba49b..40d5c2a 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -667,6 +667,8 @@ static int fuse_rmdir(struct inode *dir, struct dentry *entry)
if (IS_ERR(req))
return PTR_ERR(req);
+ dentry_unhash(entry);
+
req->in.h.opcode = FUSE_RMDIR;
req->in.h.nodeid = get_node_id(dir);
req->in.numargs = 1;
diff --git a/fs/gfs2/ops_inode.c b/fs/gfs2/ops_inode.c
index 09e436a..1645664 100644
--- a/fs/gfs2/ops_inode.c
+++ b/fs/gfs2/ops_inode.c
@@ -572,6 +572,8 @@ static int gfs2_rmdir(struct inode *dir, struct dentry *dentry)
struct gfs2_holder ri_gh;
int error;
+ dentry_unhash(dentry);
+
error = gfs2_rindex_hold(sdp, &ri_gh);
if (error)
return error;
diff --git a/fs/hfs/dir.c b/fs/hfs/dir.c
index b4d70b1..616cfe0 100644
--- a/fs/hfs/dir.c
+++ b/fs/hfs/dir.c
@@ -253,6 +253,9 @@ static int hfs_remove(struct inode *dir, struct dentry *dentry)
struct inode *inode = dentry->d_inode;
int res;
+ if (S_ISDIR(inode->i_mode))
+ dentry_unhash(dentry);
+
if (S_ISDIR(inode->i_mode) && inode->i_size != 2)
return -ENOTEMPTY;
res = hfs_cat_delete(inode->i_ino, dir, &dentry->d_name);
diff --git a/fs/hfsplus/dir.c b/fs/hfsplus/dir.c
index 4df5059..23451a9 100644
--- a/fs/hfsplus/dir.c
+++ b/fs/hfsplus/dir.c
@@ -370,6 +370,8 @@ static int hfsplus_rmdir(struct inode *dir, struct dentry *dentry)
struct inode *inode = dentry->d_inode;
int res;
+ dentry_unhash(dentry);
+
if (inode->i_size != 2)
return -ENOTEMPTY;
diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c
index 2638c83..73ea3ba 100644
--- a/fs/hostfs/hostfs_kern.c
+++ b/fs/hostfs/hostfs_kern.c
@@ -683,6 +683,8 @@ int hostfs_rmdir(struct inode *ino, struct dentry *dentry)
char *file;
int err;
+ dentry_unhash(dentry);
+
if ((file = dentry_name(dentry)) == NULL)
return -ENOMEM;
err = do_rmdir(file);
diff --git a/fs/hpfs/namei.c b/fs/hpfs/namei.c
index b1c72a9..b9fe158 100644
--- a/fs/hpfs/namei.c
+++ b/fs/hpfs/namei.c
@@ -461,6 +461,8 @@ static int hpfs_rmdir(struct inode *dir, struct dentry *dentry)
int err;
int r;
+ dentry_unhash(dentry);
+
hpfs_adjust_length(name, &len);
hpfs_lock(dir->i_sb);
mutex_lock(&hpfs_i(inode)->i_parent_mutex);
diff --git a/fs/jffs2/dir.c b/fs/jffs2/dir.c
index 82faddd..727d644 100644
--- a/fs/jffs2/dir.c
+++ b/fs/jffs2/dir.c
@@ -609,6 +609,8 @@ static int jffs2_rmdir (struct inode *dir_i, struct dentry *dentry)
int ret;
uint32_t now = get_seconds();
+ dentry_unhash(dentry);
+
for (fd = f->dents ; fd; fd = fd->next) {
if (fd->ino)
return -ENOTEMPTY;
diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c
index eaaf2b5..0569dac 100644
--- a/fs/jfs/namei.c
+++ b/fs/jfs/namei.c
@@ -360,6 +360,8 @@ static int jfs_rmdir(struct inode *dip, struct dentry *dentry)
jfs_info("jfs_rmdir: dip:0x%p name:%s", dip, dentry->d_name.name);
+ dentry_unhash(dentry);
+
/* Init inode for quota operations. */
dquot_initialize(dip);
dquot_initialize(ip);
diff --git a/fs/libfs.c b/fs/libfs.c
index c88eab5..1e2ba5a 100644
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -311,6 +311,8 @@ int simple_rmdir(struct inode *dir, struct dentry *dentry)
if (!simple_empty(dentry))
return -ENOTEMPTY;
+ dentry_unhash(dentry);
+
drop_nlink(dentry->d_inode);
simple_unlink(dir, dentry);
drop_nlink(dir);
diff --git a/fs/logfs/dir.c b/fs/logfs/dir.c
index 9ed89d1..2b32734 100644
--- a/fs/logfs/dir.c
+++ b/fs/logfs/dir.c
@@ -273,6 +273,8 @@ static int logfs_rmdir(struct inode *dir, struct dentry *dentry)
{
struct inode *inode = dentry->d_inode;
+ dentry_unhash(dentry);
+
if (!logfs_empty_dir(inode))
return -ENOTEMPTY;
diff --git a/fs/minix/namei.c b/fs/minix/namei.c
index 6e6777f..091626f 100644
--- a/fs/minix/namei.c
+++ b/fs/minix/namei.c
@@ -168,6 +168,8 @@ static int minix_rmdir(struct inode * dir, struct dentry *dentry)
struct inode * inode = dentry->d_inode;
int err = -ENOTEMPTY;
+ dentry_unhash(dentry);
+
if (minix_empty_dir(inode)) {
err = minix_unlink(dir, dentry);
if (!err) {
diff --git a/fs/namei.c b/fs/namei.c
index 058302a..ef5d195 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -2668,7 +2668,6 @@ int vfs_rmdir(struct inode *dir, struct dentry *dentry)
else {
error = security_inode_rmdir(dir, dentry);
if (!error) {
- dentry_unhash(dentry);
error = dir->i_op->rmdir(dir, dentry);
if (!error) {
dentry->d_inode->i_flags |= S_DEAD;
diff --git a/fs/ncpfs/dir.c b/fs/ncpfs/dir.c
index f6946bb..57336b7 100644
--- a/fs/ncpfs/dir.c
+++ b/fs/ncpfs/dir.c
@@ -1033,6 +1033,8 @@ static int ncp_rmdir(struct inode *dir, struct dentry *dentry)
DPRINTK("ncp_rmdir: removing %s/%s\n",
dentry->d_parent->d_name.name, dentry->d_name.name);
+ dentry_unhash(dentry);
+
error = -EBUSY;
if (!d_unhashed(dentry))
goto out;
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 7237672..48483b5 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -1748,6 +1748,8 @@ static int nfs_rmdir(struct inode *dir, struct dentry *dentry)
dfprintk(VFS, "NFS: rmdir(%s/%ld), %s\n",
dir->i_sb->s_id, dir->i_ino, dentry->d_name.name);
+ dentry_unhash(dentry);
+
error = NFS_PROTO(dir)->rmdir(dir, &dentry->d_name);
/* Ensure the VFS deletes this inode */
if (error == 0 && dentry->d_inode != NULL)
diff --git a/fs/nilfs2/namei.c b/fs/nilfs2/namei.c
index 546849b..78306e6 100644
--- a/fs/nilfs2/namei.c
+++ b/fs/nilfs2/namei.c
@@ -334,6 +334,8 @@ static int nilfs_rmdir(struct inode *dir, struct dentry *dentry)
struct nilfs_transaction_info ti;
int err;
+ dentry_unhash(dentry);
+
err = nilfs_transaction_begin(dir->i_sb, &ti, 0);
if (err)
return err;
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c
index e5d738c..b017ebb 100644
--- a/fs/ocfs2/namei.c
+++ b/fs/ocfs2/namei.c
@@ -810,6 +810,9 @@ static int ocfs2_unlink(struct inode *dir,
(unsigned long long)OCFS2_I(dir)->ip_blkno,
(unsigned long long)OCFS2_I(inode)->ip_blkno);
+ if (S_ISDIR(inode->i_mode))
+ dentry_unhash(dentry);
+
dquot_initialize(dir);
BUG_ON(dentry->d_parent->d_inode != dir);
diff --git a/fs/omfs/dir.c b/fs/omfs/dir.c
index de4ff29..95ef443 100644
--- a/fs/omfs/dir.c
+++ b/fs/omfs/dir.c
@@ -240,8 +240,12 @@ static int omfs_remove(struct inode *dir, struct dentry *dentry)
struct inode *inode = dentry->d_inode;
int ret;
- if (S_ISDIR(inode->i_mode) && !omfs_dir_is_empty(inode))
- return -ENOTEMPTY;
+
+ if (S_ISDIR(inode->i_mode)) {
+ dentry_unhash(dentry);
+ if (!omfs_dir_is_empty(inode))
+ return -ENOTEMPTY;
+ }
ret = omfs_delete_entry(dentry);
if (ret)
diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c
index 1186626..43e94f0 100644
--- a/fs/reiserfs/namei.c
+++ b/fs/reiserfs/namei.c
@@ -831,6 +831,8 @@ static int reiserfs_rmdir(struct inode *dir, struct dentry *dentry)
INITIALIZE_PATH(path);
struct reiserfs_dir_entry de;
+ dentry_unhash(dentry);
+
/* we will be doing 2 balancings and update 2 stat data, we change quotas
* of the owner of the directory and of the owner of the parent directory.
* The quota structure is possibly deleted only on last iput => outside
diff --git a/fs/sysv/namei.c b/fs/sysv/namei.c
index e474fbc..fac64ac 100644
--- a/fs/sysv/namei.c
+++ b/fs/sysv/namei.c
@@ -196,6 +196,8 @@ static int sysv_rmdir(struct inode * dir, struct dentry * dentry)
struct inode *inode = dentry->d_inode;
int err = -ENOTEMPTY;
+ dentry_unhash(dentry);
+
if (sysv_empty_dir(inode)) {
err = sysv_unlink(dir, dentry);
if (!err) {
diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c
index 7217d67..6ca9176 100644
--- a/fs/ubifs/dir.c
+++ b/fs/ubifs/dir.c
@@ -656,6 +656,8 @@ static int ubifs_rmdir(struct inode *dir, struct dentry *dentry)
struct ubifs_inode *dir_ui = ubifs_inode(dir);
struct ubifs_budget_req req = { .mod_dent = 1, .dirtied_ino = 2 };
+ dentry_unhash(dentry);
+
/*
* Budget request settings: deletion direntry, deletion inode and
* changing the parent inode. If budgeting fails, go ahead anyway
diff --git a/fs/udf/namei.c b/fs/udf/namei.c
index f1dce84..b70f026 100644
--- a/fs/udf/namei.c
+++ b/fs/udf/namei.c
@@ -783,6 +783,8 @@ static int udf_rmdir(struct inode *dir, struct dentry *dentry)
struct fileIdentDesc *fi, cfi;
struct kernel_lb_addr tloc;
+ dentry_unhash(dentry);
+
retval = -ENOENT;
fi = udf_find_entry(dir, &dentry->d_name, &fibh, &cfi);
if (!fi)
diff --git a/fs/ufs/namei.c b/fs/ufs/namei.c
index 29309e2..3a769d5 100644
--- a/fs/ufs/namei.c
+++ b/fs/ufs/namei.c
@@ -258,6 +258,8 @@ static int ufs_rmdir (struct inode * dir, struct dentry *dentry)
struct inode * inode = dentry->d_inode;
int err= -ENOTEMPTY;
+ dentry_unhash(dentry);
+
lock_ufs(dir->i_sb);
if (ufs_empty_dir (inode)) {
err = ufs_unlink(dir, dentry);
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c
index dd21784..2fc16f0 100644
--- a/fs/xfs/linux-2.6/xfs_iops.c
+++ b/fs/xfs/linux-2.6/xfs_iops.c
@@ -330,6 +330,9 @@ xfs_vn_unlink(
struct xfs_name name;
int error;
+ if (S_ISDIR(dentry->d_inode->i_mode))
+ dentry_unhash(dentry);
+
xfs_dentry_to_name(&name, dentry);
error = -xfs_remove(XFS_I(dir), &name, XFS_I(dentry->d_inode));
--
1.7.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 04/18] vfs: push dentry_unhash on rename_dir into file systems
2011-05-10 4:43 [PATCH 00/18] clean up VFS dentry_hash (mis)behavior Sage Weil
` (2 preceding siblings ...)
2011-05-10 4:43 ` [PATCH 03/18] vfs: push dentry_unhash on rmdir into file systems Sage Weil
@ 2011-05-10 4:43 ` Sage Weil
2011-05-10 4:43 ` [PATCH 05/18] vfs: update dentry_unhash() comment Sage Weil
` (14 subsequent siblings)
18 siblings, 0 replies; 26+ messages in thread
From: Sage Weil @ 2011-05-10 4:43 UTC (permalink / raw)
To: viro, hch, linux-fsdevel; +Cc: Sage Weil
Only a few file systems need this. Start by pushing it down into each
rename method so that it can be dealt with on a per-fs basis.
Signed-off-by: Sage Weil <sage@newdream.net>
---
fs/9p/vfs_inode.c | 3 +++
fs/affs/namei.c | 3 +++
fs/afs/dir.c | 3 +++
fs/bfs/dir.c | 3 +++
fs/btrfs/inode.c | 3 +++
fs/ceph/dir.c | 3 +++
fs/cifs/inode.c | 3 +++
fs/coda/dir.c | 3 +++
fs/ecryptfs/inode.c | 3 +++
fs/exofs/namei.c | 3 +++
fs/ext2/namei.c | 3 +++
fs/ext3/namei.c | 3 +++
fs/ext4/namei.c | 3 +++
fs/fat/namei_msdos.c | 3 +++
fs/fat/namei_vfat.c | 3 +++
fs/fuse/dir.c | 4 ++++
fs/gfs2/ops_inode.c | 3 +++
fs/hfs/dir.c | 3 +++
fs/hfsplus/dir.c | 6 ++++--
fs/hostfs/hostfs_kern.c | 3 +++
fs/hpfs/namei.c | 4 ++++
fs/jffs2/dir.c | 3 +++
fs/jfs/namei.c | 3 +++
fs/libfs.c | 3 +++
fs/logfs/dir.c | 3 +++
fs/minix/namei.c | 3 +++
fs/namei.c | 5 +----
fs/ncpfs/dir.c | 3 +++
fs/nfs/dir.c | 3 +++
fs/nilfs2/namei.c | 3 +++
fs/ocfs2/namei.c | 3 +++
fs/omfs/dir.c | 3 +++
fs/reiserfs/namei.c | 3 +++
fs/sysv/namei.c | 3 +++
fs/ubifs/dir.c | 3 +++
fs/udf/namei.c | 3 +++
fs/ufs/namei.c | 3 +++
fs/xfs/linux-2.6/xfs_iops.c | 3 +++
38 files changed, 115 insertions(+), 6 deletions(-)
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
index ecd7717..8d7f3e6 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 d087153..03330e2 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 9a7f414..2c4e051 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 b14cebf..c7d1d06 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 c692dad..3a33ae3 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 d2e5490..377b964 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 cee5896..18546b7 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 9f72b75..a46126f 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 c88612f..227b409 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 0697175..de252e5 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 7a5ad97..516c31d 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 552f94d..f89b1d4 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 957580d..792d06e 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 0c25cea..c3eccbd 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 d7b9383..e2466b2 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 40d5c2a..e462a7a 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/gfs2/ops_inode.c b/fs/gfs2/ops_inode.c
index 1645664..4bf862c 100644
--- a/fs/gfs2/ops_inode.c
+++ b/fs/gfs2/ops_inode.c
@@ -743,6 +743,9 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
int error;
if (ndentry->d_inode) {
+ if (S_ISDIR(ndentry->d_inode->i_mode))
+ dentry_unhash(ndentry);
+
nip = GFS2_I(ndentry->d_inode);
if (ip == nip)
return 0;
diff --git a/fs/hfs/dir.c b/fs/hfs/dir.c
index 616cfe0..1cb70cd 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 23451a9..b288350 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 73ea3ba..e6816b9 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 b9fe158..d3db95f 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 727d644..05f7332 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 0569dac..865df16 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 1e2ba5a..91a3710 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 2b32734..f34c9cd 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 091626f..f60aed8 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 ef5d195..dc1e103 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -3086,11 +3086,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 57336b7..e3e646b 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 48483b5..87daf79 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 78306e6..1102a5f 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 b017ebb..f3582a6 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 95ef443..c368360 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 43e94f0..76c8164 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 fac64ac..e2cc675 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 6ca9176..d80810b 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 b70f026..4d76594 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 3a769d5..953ebdf 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;
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c
index 2fc16f0..f791485 100644
--- a/fs/xfs/linux-2.6/xfs_iops.c
+++ b/fs/xfs/linux-2.6/xfs_iops.c
@@ -395,6 +395,9 @@ xfs_vn_rename(
struct xfs_name oname;
struct xfs_name nname;
+ if (ndentry->d_inode && S_ISDIR(ndentry->d_inode->i_mode))
+ dentry_unhash(ndentry);
+
xfs_dentry_to_name(&oname, odentry);
xfs_dentry_to_name(&nname, ndentry);
--
1.7.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 05/18] vfs: update dentry_unhash() comment
2011-05-10 4:43 [PATCH 00/18] clean up VFS dentry_hash (mis)behavior Sage Weil
` (3 preceding siblings ...)
2011-05-10 4:43 ` [PATCH 04/18] vfs: push dentry_unhash on rename_dir " Sage Weil
@ 2011-05-10 4:43 ` Sage Weil
2011-05-10 4:43 ` [PATCH 06/18] libfs: drop unneeded dentry_unhash Sage Weil
` (13 subsequent siblings)
18 siblings, 0 replies; 26+ messages in thread
From: Sage Weil @ 2011-05-10 4:43 UTC (permalink / raw)
To: viro, hch, linux-fsdevel; +Cc: Sage Weil
The helper is now only called by file systems, not the VFS.
Signed-off-by: Sage Weil <sage@newdream.net>
---
fs/namei.c | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/fs/namei.c b/fs/namei.c
index dc1e103..057f25a 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -2629,10 +2629,10 @@ SYSCALL_DEFINE2(mkdir, const char __user *, pathname, int, mode)
}
/*
- * We try to drop the dentry early: we should have
- * a usage count of 2 if we're the only user of this
- * dentry, and if that is true (possibly after pruning
- * the dcache), then we drop the dentry now.
+ * The dentry_unhash() helper will try to drop the dentry early: we
+ * should have a usage count of 2 if we're the only user of this
+ * dentry, and if that is true (possibly after pruning the dcache),
+ * then we drop the dentry now.
*
* A low-level filesystem can, if it choses, legally
* do a
--
1.7.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 06/18] libfs: drop unneeded dentry_unhash
2011-05-10 4:43 [PATCH 00/18] clean up VFS dentry_hash (mis)behavior Sage Weil
` (4 preceding siblings ...)
2011-05-10 4:43 ` [PATCH 05/18] vfs: update dentry_unhash() comment Sage Weil
@ 2011-05-10 4:43 ` Sage Weil
2011-05-10 4:43 ` [PATCH 07/18] vfs: fix vfs_rename_dir for FS_RENAME_DOES_D_MOVE filesystems Sage Weil
` (12 subsequent siblings)
18 siblings, 0 replies; 26+ messages in thread
From: Sage Weil @ 2011-05-10 4:43 UTC (permalink / raw)
To: viro, hch, linux-fsdevel; +Cc: Sage Weil
There are no libfs issues with dangling references to empty directories.
Signed-off-by: Sage Weil <sage@newdream.net>
---
fs/libfs.c | 5 -----
1 files changed, 0 insertions(+), 5 deletions(-)
diff --git a/fs/libfs.c b/fs/libfs.c
index 91a3710..c88eab5 100644
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -311,8 +311,6 @@ int simple_rmdir(struct inode *dir, struct dentry *dentry)
if (!simple_empty(dentry))
return -ENOTEMPTY;
- dentry_unhash(dentry);
-
drop_nlink(dentry->d_inode);
simple_unlink(dir, dentry);
drop_nlink(dir);
@@ -325,9 +323,6 @@ 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;
--
1.7.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 07/18] vfs: fix vfs_rename_dir for FS_RENAME_DOES_D_MOVE filesystems
2011-05-10 4:43 [PATCH 00/18] clean up VFS dentry_hash (mis)behavior Sage Weil
` (5 preceding siblings ...)
2011-05-10 4:43 ` [PATCH 06/18] libfs: drop unneeded dentry_unhash Sage Weil
@ 2011-05-10 4:43 ` Sage Weil
2011-05-10 4:43 ` [PATCH 08/18] ceph: remove unnecessary dentry_unhash calls Sage Weil
` (11 subsequent siblings)
18 siblings, 0 replies; 26+ messages in thread
From: Sage Weil @ 2011-05-10 4:43 UTC (permalink / raw)
To: viro, hch, linux-fsdevel; +Cc: Miklos Szeredi, Miklos Szeredi
From: Miklos Szeredi <miklos@suse.cz>
vfs_rename_dir() doesn't properly account for filesystems with
FS_RENAME_DOES_D_MOVE. If new_dentry has a target inode attached, it
unhashes the new_dentry prior to the rename() iop and rehashes it after,
but doesn't account for the possibility that rename() may have swapped
{old,new}_dentry. For FS_RENAME_DOES_D_MOVE filesystems, it rehashes
new_dentry (now the old renamed-from name, which d_move() expected to go
away), such that a subsequent lookup will find it. Currently all
FS_RENAME_DOES_D_MOVE filesystems compensate for this by failing in
d_revalidate.
The bug was introduced by: commit 349457ccf2592c14bdf13b6706170ae2e94931b1
"[PATCH] Allow file systems to manually d_move() inside of ->rename()"
Fix by not rehashing the new dentry. Rehashing used to be needed by
d_move() but isn't anymore.
Reported-by: Sage Weil <sage@newdream.net>
Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
---
fs/namei.c | 2 --
1 files changed, 0 insertions(+), 2 deletions(-)
diff --git a/fs/namei.c b/fs/namei.c
index 057f25a..2195730 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -3094,8 +3094,6 @@ static int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
dont_mount(new_dentry);
}
mutex_unlock(&target->i_mutex);
- if (d_unhashed(new_dentry))
- d_rehash(new_dentry);
}
if (!error)
if (!(old_dir->i_sb->s_type->fs_flags & FS_RENAME_DOES_D_MOVE))
--
1.7.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 08/18] ceph: remove unnecessary dentry_unhash calls
2011-05-10 4:43 [PATCH 00/18] clean up VFS dentry_hash (mis)behavior Sage Weil
` (6 preceding siblings ...)
2011-05-10 4:43 ` [PATCH 07/18] vfs: fix vfs_rename_dir for FS_RENAME_DOES_D_MOVE filesystems Sage Weil
@ 2011-05-10 4:43 ` Sage Weil
2011-05-10 4:43 ` [PATCH 09/18] xfs: remove unnecessary dentry_unhash from rmdir/rename_dir Sage Weil
` (10 subsequent siblings)
18 siblings, 0 replies; 26+ messages in thread
From: Sage Weil @ 2011-05-10 4:43 UTC (permalink / raw)
To: viro, hch, linux-fsdevel; +Cc: Sage Weil
Ceph does not need these, and they screw up our use of the dcache as a
consistent cache.
Signed-off-by: Sage Weil <sage@newdream.net>
---
fs/ceph/dir.c | 6 ------
1 files changed, 0 insertions(+), 6 deletions(-)
diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c
index 377b964..1a867a3 100644
--- a/fs/ceph/dir.c
+++ b/fs/ceph/dir.c
@@ -827,9 +827,6 @@ static int ceph_unlink(struct inode *dir, struct dentry *dentry)
int err = -EROFS;
int op;
- if ((dentry->d_inode->i_mode & S_IFMT) == S_IFDIR)
- dentry_unhash(dentry);
-
if (ceph_snap(dir) == CEPH_SNAPDIR) {
/* rmdir .snap/foo is RMSNAP */
dout("rmsnap dir %p '%.*s' dn %p\n", dir, dentry->d_name.len,
@@ -869,9 +866,6 @@ 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 ||
--
1.7.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 09/18] xfs: remove unnecessary dentry_unhash from rmdir/rename_dir
2011-05-10 4:43 [PATCH 00/18] clean up VFS dentry_hash (mis)behavior Sage Weil
` (7 preceding siblings ...)
2011-05-10 4:43 ` [PATCH 08/18] ceph: remove unnecessary dentry_unhash calls Sage Weil
@ 2011-05-10 4:43 ` Sage Weil
2011-05-10 4:43 ` [PATCH 10/18] btrfs: remove unnecessary dentry_unhash in rmdir/rename_dir Sage Weil
` (9 subsequent siblings)
18 siblings, 0 replies; 26+ messages in thread
From: Sage Weil @ 2011-05-10 4:43 UTC (permalink / raw)
To: viro, hch, linux-fsdevel; +Cc: Sage Weil
XFS has no problems with references to unlinked directories.
Signed-off-by: Sage Weil <sage@newdream.net>
---
fs/xfs/linux-2.6/xfs_iops.c | 6 ------
1 files changed, 0 insertions(+), 6 deletions(-)
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c
index f791485..dd21784 100644
--- a/fs/xfs/linux-2.6/xfs_iops.c
+++ b/fs/xfs/linux-2.6/xfs_iops.c
@@ -330,9 +330,6 @@ xfs_vn_unlink(
struct xfs_name name;
int error;
- if (S_ISDIR(dentry->d_inode->i_mode))
- dentry_unhash(dentry);
-
xfs_dentry_to_name(&name, dentry);
error = -xfs_remove(XFS_I(dir), &name, XFS_I(dentry->d_inode));
@@ -395,9 +392,6 @@ xfs_vn_rename(
struct xfs_name oname;
struct xfs_name nname;
- if (ndentry->d_inode && S_ISDIR(ndentry->d_inode->i_mode))
- dentry_unhash(ndentry);
-
xfs_dentry_to_name(&oname, odentry);
xfs_dentry_to_name(&nname, ndentry);
--
1.7.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 10/18] btrfs: remove unnecessary dentry_unhash in rmdir/rename_dir
2011-05-10 4:43 [PATCH 00/18] clean up VFS dentry_hash (mis)behavior Sage Weil
` (8 preceding siblings ...)
2011-05-10 4:43 ` [PATCH 09/18] xfs: remove unnecessary dentry_unhash from rmdir/rename_dir Sage Weil
@ 2011-05-10 4:43 ` Sage Weil
2011-05-10 4:43 ` [PATCH 11/18] ext4: remove unnecessary dentry_unhash on rmdir/rename_dir Sage Weil
` (8 subsequent siblings)
18 siblings, 0 replies; 26+ messages in thread
From: Sage Weil @ 2011-05-10 4:43 UTC (permalink / raw)
To: viro, hch, linux-fsdevel; +Cc: Sage Weil, Chris Mason, linux-btrfs
Btrfs has no problems with lingering references to unlinked directory
inodes.
CC: Chris Mason <chris.mason@oracle.com>
CC: linux-btrfs@vger.kernel.org
Signed-off-by: Sage Weil <sage@newdream.net>
---
fs/btrfs/inode.c | 5 -----
1 files changed, 0 insertions(+), 5 deletions(-)
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 3a33ae3..7cd8ab0 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -3062,8 +3062,6 @@ static int btrfs_rmdir(struct inode *dir, struct dentry *dentry)
inode->i_ino == BTRFS_FIRST_FREE_OBJECTID)
return -ENOTEMPTY;
- dentry_unhash(dentry);
-
trans = __unlink_start_trans(dir, dentry);
if (IS_ERR(trans))
return PTR_ERR(trans);
@@ -6994,9 +6992,6 @@ 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;
--
1.7.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 11/18] ext4: remove unnecessary dentry_unhash on rmdir/rename_dir
2011-05-10 4:43 [PATCH 00/18] clean up VFS dentry_hash (mis)behavior Sage Weil
` (9 preceding siblings ...)
2011-05-10 4:43 ` [PATCH 10/18] btrfs: remove unnecessary dentry_unhash in rmdir/rename_dir Sage Weil
@ 2011-05-10 4:43 ` Sage Weil
2011-05-10 4:43 ` [PATCH 12/18] ext3: " Sage Weil
` (7 subsequent siblings)
18 siblings, 0 replies; 26+ messages in thread
From: Sage Weil @ 2011-05-10 4:43 UTC (permalink / raw)
To: viro, hch, linux-fsdevel
Cc: Sage Weil, Theodore Ts'o, Andreas Dilger, linux-ext4
ext4 has no problems with lingering references to unlinked directory
inodes.
CC: "Theodore Ts'o" <tytso@mit.edu>
CC: Andreas Dilger <adilger.kernel@dilger.ca>
CC: linux-ext4@vger.kernel.org
Signed-off-by: Sage Weil <sage@newdream.net>
---
fs/ext4/namei.c | 5 -----
1 files changed, 0 insertions(+), 5 deletions(-)
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index 792d06e..67fd0b0 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -2123,8 +2123,6 @@ static int ext4_rmdir(struct inode *dir, struct dentry *dentry)
struct ext4_dir_entry_2 *de;
handle_t *handle;
- dentry_unhash(dentry);
-
/* Initialize quotas before so that eventual writes go in
* separate transaction */
dquot_initialize(dir);
@@ -2352,9 +2350,6 @@ 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);
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 12/18] ext3: remove unnecessary dentry_unhash on rmdir/rename_dir
2011-05-10 4:43 [PATCH 00/18] clean up VFS dentry_hash (mis)behavior Sage Weil
` (10 preceding siblings ...)
2011-05-10 4:43 ` [PATCH 11/18] ext4: remove unnecessary dentry_unhash on rmdir/rename_dir Sage Weil
@ 2011-05-10 4:43 ` Sage Weil
2011-05-10 4:43 ` [PATCH 13/18] ext2: " Sage Weil
` (6 subsequent siblings)
18 siblings, 0 replies; 26+ messages in thread
From: Sage Weil @ 2011-05-10 4:43 UTC (permalink / raw)
To: viro, hch, linux-fsdevel
Cc: Sage Weil, Jan Kara, Andrew Morton, Andreas Dilger, linux-ext4
ext3 has no problems with lingering references to unlinked directory
inodes.
CC: Jan Kara <jack@suse.cz>
CC: Andrew Morton <akpm@linux-foundation.org>
CC: Andreas Dilger <adilger.kernel@dilger.ca>
CC: linux-ext4@vger.kernel.org
Signed-off-by: Sage Weil <sage@newdream.net>
---
fs/ext3/namei.c | 5 -----
1 files changed, 0 insertions(+), 5 deletions(-)
diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c
index f89b1d4..32f3b86 100644
--- a/fs/ext3/namei.c
+++ b/fs/ext3/namei.c
@@ -2074,8 +2074,6 @@ static int ext3_rmdir (struct inode * dir, struct dentry *dentry)
struct ext3_dir_entry_2 * de;
handle_t *handle;
- dentry_unhash(dentry);
-
/* Initialize quotas before so that eventual writes go in
* separate transaction */
dquot_initialize(dir);
@@ -2298,9 +2296,6 @@ 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);
--
1.7.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 13/18] ext2: remove unnecessary dentry_unhash on rmdir/rename_dir
2011-05-10 4:43 [PATCH 00/18] clean up VFS dentry_hash (mis)behavior Sage Weil
` (11 preceding siblings ...)
2011-05-10 4:43 ` [PATCH 12/18] ext3: " Sage Weil
@ 2011-05-10 4:43 ` Sage Weil
[not found] ` <1305002616-16782-1-git-send-email-sage-BnTBU8nroG7k1uMJSBkQmQ@public.gmane.org>
` (5 subsequent siblings)
18 siblings, 0 replies; 26+ messages in thread
From: Sage Weil @ 2011-05-10 4:43 UTC (permalink / raw)
To: viro, hch, linux-fsdevel; +Cc: Sage Weil, Jan Kara, linux-ext4
ext2 has no problems with lingering references to unlinked directory
inodes.
CC: Jan Kara <jack@suse.cz>
CC: linux-ext4@vger.kernel.org
Signed-off-by: Sage Weil <sage@newdream.net>
---
fs/ext2/namei.c | 5 -----
1 files changed, 0 insertions(+), 5 deletions(-)
diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c
index 516c31d..ed5c5d4 100644
--- a/fs/ext2/namei.c
+++ b/fs/ext2/namei.c
@@ -296,8 +296,6 @@ static int ext2_rmdir (struct inode * dir, struct dentry *dentry)
struct inode * inode = dentry->d_inode;
int err = -ENOTEMPTY;
- dentry_unhash(dentry);
-
if (ext2_empty_dir(inode)) {
err = ext2_unlink(dir, dentry);
if (!err) {
@@ -320,9 +318,6 @@ 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);
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 14/18] nfs: remove unnecessary dentry_unhash on rmdir/rename_dir
[not found] ` <1305002616-16782-1-git-send-email-sage-BnTBU8nroG7k1uMJSBkQmQ@public.gmane.org>
@ 2011-05-10 4:43 ` Sage Weil
0 siblings, 0 replies; 26+ messages in thread
From: Sage Weil @ 2011-05-10 4:43 UTC (permalink / raw)
To: viro-3bDd1+5oDREiFSDQTTA3OLVCufUGDwFn, hch-jcswGhMUV9g,
linux-fsdevel-u79uwXL29TY76Z2rM5mHXA
Cc: Sage Weil, Trond Myklebust, linux-nfs-u79uwXL29TY76Z2rM5mHXA
NFS has no problems with lingering references to unlinked directory
inodes.
CC: Trond Myklebust <Trond.Myklebust-HgOvQuBEEgTQT0dZR+AlfA@public.gmane.org>
CC: linux-nfs-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Signed-off-by: Sage Weil <sage-BnTBU8nroG7k1uMJSBkQmQ@public.gmane.org>
---
fs/nfs/dir.c | 5 -----
1 files changed, 0 insertions(+), 5 deletions(-)
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 87daf79..7237672 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -1748,8 +1748,6 @@ static int nfs_rmdir(struct inode *dir, struct dentry *dentry)
dfprintk(VFS, "NFS: rmdir(%s/%ld), %s\n",
dir->i_sb->s_id, dir->i_ino, dentry->d_name.name);
- dentry_unhash(dentry);
-
error = NFS_PROTO(dir)->rmdir(dir, &dentry->d_name);
/* Ensure the VFS deletes this inode */
if (error == 0 && dentry->d_inode != NULL)
@@ -1959,9 +1957,6 @@ 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
--
1.7.1
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 15/18] exofs: remove unnecessary dentry_unhash on rmdir/rename_dir
2011-05-10 4:43 [PATCH 00/18] clean up VFS dentry_hash (mis)behavior Sage Weil
` (13 preceding siblings ...)
[not found] ` <1305002616-16782-1-git-send-email-sage-BnTBU8nroG7k1uMJSBkQmQ@public.gmane.org>
@ 2011-05-10 4:43 ` Sage Weil
2011-05-11 12:53 ` Boaz Harrosh
2011-05-10 4:43 ` [PATCH 16/18] ocfs2: " Sage Weil
` (3 subsequent siblings)
18 siblings, 1 reply; 26+ messages in thread
From: Sage Weil @ 2011-05-10 4:43 UTC (permalink / raw)
To: viro, hch, linux-fsdevel; +Cc: Sage Weil, Boaz Harrosh, Benny Halevy, osd-dev
Exofs has no problems with lingering references to unlinked directory
inodes.
CC: Boaz Harrosh <bharrosh@panasas.com>
CC: Benny Halevy <bhalevy@panasas.com>
CC: osd-dev@open-osd.org
Signed-off-by: Sage Weil <sage@newdream.net>
---
fs/exofs/namei.c | 5 -----
1 files changed, 0 insertions(+), 5 deletions(-)
diff --git a/fs/exofs/namei.c b/fs/exofs/namei.c
index de252e5..4d70db1 100644
--- a/fs/exofs/namei.c
+++ b/fs/exofs/namei.c
@@ -227,8 +227,6 @@ static int exofs_rmdir(struct inode *dir, struct dentry *dentry)
struct inode *inode = dentry->d_inode;
int err = -ENOTEMPTY;
- dentry_unhash(dentry);
-
if (exofs_empty_dir(inode)) {
err = exofs_unlink(dir, dentry);
if (!err) {
@@ -251,9 +249,6 @@ 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;
--
1.7.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 16/18] ocfs2: remove unnecessary dentry_unhash on rmdir/rename_dir
2011-05-10 4:43 [PATCH 00/18] clean up VFS dentry_hash (mis)behavior Sage Weil
` (14 preceding siblings ...)
2011-05-10 4:43 ` [PATCH 15/18] exofs: " Sage Weil
@ 2011-05-10 4:43 ` Sage Weil
2011-05-10 20:24 ` Joel Becker
2011-05-10 4:43 ` [PATCH 17/18] gfs2: " Sage Weil
` (2 subsequent siblings)
18 siblings, 1 reply; 26+ messages in thread
From: Sage Weil @ 2011-05-10 4:43 UTC (permalink / raw)
To: viro, hch, linux-fsdevel; +Cc: Sage Weil, Mark Fasheh, Joel Becker, ocfs2-devel
Ocfs2 has no issues with lingering references to unlinked directory inodes.
CC: Mark Fasheh <mfasheh@suse.com>
CC: Joel Becker <jlbec@evilplan.org>
CC: ocfs2-devel@oss.oracle.com
Signed-off-by: Sage Weil <sage@newdream.net>
---
fs/ocfs2/namei.c | 6 ------
1 files changed, 0 insertions(+), 6 deletions(-)
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c
index f3582a6..e5d738c 100644
--- a/fs/ocfs2/namei.c
+++ b/fs/ocfs2/namei.c
@@ -810,9 +810,6 @@ static int ocfs2_unlink(struct inode *dir,
(unsigned long long)OCFS2_I(dir)->ip_blkno,
(unsigned long long)OCFS2_I(inode)->ip_blkno);
- if (S_ISDIR(inode->i_mode))
- dentry_unhash(dentry);
-
dquot_initialize(dir);
BUG_ON(dentry->d_parent->d_inode != dir);
@@ -1066,9 +1063,6 @@ 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. */
--
1.7.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 17/18] gfs2: remove unnecessary dentry_unhash on rmdir/rename_dir
2011-05-10 4:43 [PATCH 00/18] clean up VFS dentry_hash (mis)behavior Sage Weil
` (15 preceding siblings ...)
2011-05-10 4:43 ` [PATCH 16/18] ocfs2: " Sage Weil
@ 2011-05-10 4:43 ` Sage Weil
2011-05-10 8:45 ` Steven Whitehouse
2011-05-10 4:43 ` [PATCH 18/18] cifs: " Sage Weil
2011-05-11 10:06 ` [PATCH 00/18] clean up VFS dentry_hash (mis)behavior Christoph Hellwig
18 siblings, 1 reply; 26+ messages in thread
From: Sage Weil @ 2011-05-10 4:43 UTC (permalink / raw)
To: viro, hch, linux-fsdevel; +Cc: Sage Weil, Steven Whitehouse, cluster-devel
Gfs2 has no issues with lingering references to unlinked directory
inodes.
CC: Steven Whitehouse <swhiteho@redhat.com>
CC: cluster-devel@redhat.com
Signed-off-by: Sage Weil <sage@newdream.net>
---
fs/gfs2/ops_inode.c | 5 -----
1 files changed, 0 insertions(+), 5 deletions(-)
diff --git a/fs/gfs2/ops_inode.c b/fs/gfs2/ops_inode.c
index 4bf862c..09e436a 100644
--- a/fs/gfs2/ops_inode.c
+++ b/fs/gfs2/ops_inode.c
@@ -572,8 +572,6 @@ static int gfs2_rmdir(struct inode *dir, struct dentry *dentry)
struct gfs2_holder ri_gh;
int error;
- dentry_unhash(dentry);
-
error = gfs2_rindex_hold(sdp, &ri_gh);
if (error)
return error;
@@ -743,9 +741,6 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
int error;
if (ndentry->d_inode) {
- if (S_ISDIR(ndentry->d_inode->i_mode))
- dentry_unhash(ndentry);
-
nip = GFS2_I(ndentry->d_inode);
if (ip == nip)
return 0;
--
1.7.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 18/18] cifs: remove unnecessary dentry_unhash on rmdir/rename_dir
2011-05-10 4:43 [PATCH 00/18] clean up VFS dentry_hash (mis)behavior Sage Weil
` (16 preceding siblings ...)
2011-05-10 4:43 ` [PATCH 17/18] gfs2: " Sage Weil
@ 2011-05-10 4:43 ` Sage Weil
2011-05-11 10:06 ` [PATCH 00/18] clean up VFS dentry_hash (mis)behavior Christoph Hellwig
18 siblings, 0 replies; 26+ messages in thread
From: Sage Weil @ 2011-05-10 4:43 UTC (permalink / raw)
To: viro, hch, linux-fsdevel; +Cc: Sage Weil, Steve French, linux-cifs
Cifs has no problems with lingering references to unlinked directory
inodes.
CC: Steve French <sfrench@samba.org>
CC: linux-cifs@vger.kernel.org
Signed-off-by: Sage Weil <sage@newdream.net>
---
fs/cifs/inode.c | 5 -----
1 files changed, 0 insertions(+), 5 deletions(-)
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 18546b7..8852470 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -1461,8 +1461,6 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry)
cFYI(1, "cifs_rmdir, inode = 0x%p", inode);
- dentry_unhash(direntry);
-
xid = GetXid();
full_path = build_path_from_dentry(direntry);
@@ -1571,9 +1569,6 @@ 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))
--
1.7.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* Re: [PATCH 01/18] vfs: dentry_unhash immediately prior to rmdir
2011-05-10 4:43 ` [PATCH 01/18] vfs: dentry_unhash immediately prior to rmdir Sage Weil
@ 2011-05-10 8:12 ` Christoph Hellwig
0 siblings, 0 replies; 26+ messages in thread
From: Christoph Hellwig @ 2011-05-10 8:12 UTC (permalink / raw)
To: Sage Weil; +Cc: viro, hch, linux-fsdevel
> - dentry_unhash(dentry);
> if (d_mountpoint(dentry))
> error = -EBUSY;
> else {
> error = security_inode_rmdir(dir, dentry);
> if (!error) {
> + dentry_unhash(dentry);
> error = dir->i_op->rmdir(dir, dentry);
> if (!error) {
> dentry->d_inode->i_flags |= S_DEAD;
> dont_mount(dentry);
> }
> + dput(dentry);
> }
> }
> mutex_unlock(&dentry->d_inode->i_mutex);
> if (!error) {
> d_delete(dentry);
> }
> - dput(dentry);
>
> return error;
It would be nice if you could throw in a patch later in the series to
clean up the code flow, e.g.
error = -EBUSY;
if (d_mountpoint(dentry))
goto out;
error = security_inode_rmdir(dir, dentry);
if (error)
goto out;
dentry_unhash(dentry);
error = dir->i_op->rmdir(dir, dentry);
if (!error) {
dentry->d_inode->i_flags |= S_DEAD;
dont_mount(dentry);
}
dput(dentry);
out:
mutex_unlock(&dentry->d_inode->i_mutex);
if (!error)
d_delete(dentry);
return error;
}
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 17/18] gfs2: remove unnecessary dentry_unhash on rmdir/rename_dir
2011-05-10 4:43 ` [PATCH 17/18] gfs2: " Sage Weil
@ 2011-05-10 8:45 ` Steven Whitehouse
2011-05-10 15:47 ` Sage Weil
0 siblings, 1 reply; 26+ messages in thread
From: Steven Whitehouse @ 2011-05-10 8:45 UTC (permalink / raw)
To: Sage Weil; +Cc: viro, hch, linux-fsdevel, cluster-devel
Hi,
On Mon, 2011-05-09 at 21:43 -0700, Sage Weil wrote:
> Gfs2 has no issues with lingering references to unlinked directory
> inodes.
>
> CC: Steven Whitehouse <swhiteho@redhat.com>
> CC: cluster-devel@redhat.com
> Signed-off-by: Sage Weil <sage@newdream.net>
> ---
> fs/gfs2/ops_inode.c | 5 -----
> 1 files changed, 0 insertions(+), 5 deletions(-)
>
> diff --git a/fs/gfs2/ops_inode.c b/fs/gfs2/ops_inode.c
> index 4bf862c..09e436a 100644
> --- a/fs/gfs2/ops_inode.c
> +++ b/fs/gfs2/ops_inode.c
> @@ -572,8 +572,6 @@ static int gfs2_rmdir(struct inode *dir, struct dentry *dentry)
> struct gfs2_holder ri_gh;
> int error;
>
> - dentry_unhash(dentry);
> -
> error = gfs2_rindex_hold(sdp, &ri_gh);
> if (error)
> return error;
> @@ -743,9 +741,6 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
> int error;
>
> if (ndentry->d_inode) {
> - if (S_ISDIR(ndentry->d_inode->i_mode))
> - dentry_unhash(ndentry);
> -
> nip = GFS2_I(ndentry->d_inode);
> if (ip == nip)
> return 0;
I recently posted some patches to this area of code, and I was intending
to push them into my GFS2 -nmw tree today, so I wonder if you could
simplify this by not adding the dentry_unhash into gfs2 in the first
place, which would then ensure no conflicts between the two patch sets?
Steve.
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 17/18] gfs2: remove unnecessary dentry_unhash on rmdir/rename_dir
2011-05-10 8:45 ` Steven Whitehouse
@ 2011-05-10 15:47 ` Sage Weil
0 siblings, 0 replies; 26+ messages in thread
From: Sage Weil @ 2011-05-10 15:47 UTC (permalink / raw)
To: Steven Whitehouse; +Cc: viro, hch, linux-fsdevel, cluster-devel
On Tue, 10 May 2011, Steven Whitehouse wrote:
> Hi,
>
> On Mon, 2011-05-09 at 21:43 -0700, Sage Weil wrote:
> > Gfs2 has no issues with lingering references to unlinked directory
> > inodes.
> >
> > CC: Steven Whitehouse <swhiteho@redhat.com>
> > CC: cluster-devel@redhat.com
> > Signed-off-by: Sage Weil <sage@newdream.net>
> > ---
> > fs/gfs2/ops_inode.c | 5 -----
> > 1 files changed, 0 insertions(+), 5 deletions(-)
> >
> > diff --git a/fs/gfs2/ops_inode.c b/fs/gfs2/ops_inode.c
> > index 4bf862c..09e436a 100644
> > --- a/fs/gfs2/ops_inode.c
> > +++ b/fs/gfs2/ops_inode.c
> > @@ -572,8 +572,6 @@ static int gfs2_rmdir(struct inode *dir, struct dentry *dentry)
> > struct gfs2_holder ri_gh;
> > int error;
> >
> > - dentry_unhash(dentry);
> > -
> > error = gfs2_rindex_hold(sdp, &ri_gh);
> > if (error)
> > return error;
> > @@ -743,9 +741,6 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
> > int error;
> >
> > if (ndentry->d_inode) {
> > - if (S_ISDIR(ndentry->d_inode->i_mode))
> > - dentry_unhash(ndentry);
> > -
> > nip = GFS2_I(ndentry->d_inode);
> > if (ip == nip)
> > return 0;
>
> I recently posted some patches to this area of code, and I was intending
> to push them into my GFS2 -nmw tree today, so I wonder if you could
> simplify this by not adding the dentry_unhash into gfs2 in the first
> place, which would then ensure no conflicts between the two patch sets?
Sure, no problem!
sage
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 16/18] ocfs2: remove unnecessary dentry_unhash on rmdir/rename_dir
2011-05-10 4:43 ` [PATCH 16/18] ocfs2: " Sage Weil
@ 2011-05-10 20:24 ` Joel Becker
0 siblings, 0 replies; 26+ messages in thread
From: Joel Becker @ 2011-05-10 20:24 UTC (permalink / raw)
To: Sage Weil; +Cc: viro, hch, linux-fsdevel, Mark Fasheh, ocfs2-devel
On Mon, May 09, 2011 at 09:43:34PM -0700, Sage Weil wrote:
> Ocfs2 has no issues with lingering references to unlinked directory inodes.
>
> CC: Mark Fasheh <mfasheh@suse.com>
> CC: Joel Becker <jlbec@evilplan.org>
> CC: ocfs2-devel@oss.oracle.com
> Signed-off-by: Sage Weil <sage@newdream.net>
> ---
> fs/ocfs2/namei.c | 6 ------
> 1 files changed, 0 insertions(+), 6 deletions(-)
>
> diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c
> index f3582a6..e5d738c 100644
> --- a/fs/ocfs2/namei.c
> +++ b/fs/ocfs2/namei.c
> @@ -810,9 +810,6 @@ static int ocfs2_unlink(struct inode *dir,
> (unsigned long long)OCFS2_I(dir)->ip_blkno,
> (unsigned long long)OCFS2_I(inode)->ip_blkno);
>
> - if (S_ISDIR(inode->i_mode))
> - dentry_unhash(dentry);
> -
I'm wary about this. If ocfs2_unlink/ocfs2_rename fail,
d_delete is not called. Also, d_delete doesn't always clear it. I
worry that we'll have a dentry that can be traversed even though its
state in the cluster is bad or unknown.
However, I think our d_revalidate checks should correctly catch
these cases. If we get to the point of doing actual work, we've
assuredly told other nodes to forget about this directory. So I'll
tentatively Ack this, and hope it doesn't explode ;-)
Acked-by: Joel Becker <jlbec@evilplan.org>
--
"I inject pure kryptonite into my brain.
It improves my kung fu, and it eases the pain."
http://www.jlbec.org/
jlbec@evilplan.org
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 00/18] clean up VFS dentry_hash (mis)behavior
2011-05-10 4:43 [PATCH 00/18] clean up VFS dentry_hash (mis)behavior Sage Weil
` (17 preceding siblings ...)
2011-05-10 4:43 ` [PATCH 18/18] cifs: " Sage Weil
@ 2011-05-11 10:06 ` Christoph Hellwig
2011-05-11 17:18 ` Sage Weil
18 siblings, 1 reply; 26+ messages in thread
From: Christoph Hellwig @ 2011-05-11 10:06 UTC (permalink / raw)
To: Sage Weil; +Cc: viro, hch, linux-fsdevel
The whole series looks good to me, but I think life would be a lot
easier for many filesystem if we didn't even bother to push down
the calls for filesystems that don't need it.
You can skip it for XFS with my ACK if you want.
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 15/18] exofs: remove unnecessary dentry_unhash on rmdir/rename_dir
2011-05-10 4:43 ` [PATCH 15/18] exofs: " Sage Weil
@ 2011-05-11 12:53 ` Boaz Harrosh
0 siblings, 0 replies; 26+ messages in thread
From: Boaz Harrosh @ 2011-05-11 12:53 UTC (permalink / raw)
To: Sage Weil; +Cc: viro, hch, linux-fsdevel, Benny Halevy, osd-dev
On 05/10/2011 07:43 AM, Sage Weil wrote:
> Exofs has no problems with lingering references to unlinked directory
> inodes.
>
> CC: Boaz Harrosh <bharrosh@panasas.com>
> CC: Benny Halevy <bhalevy@panasas.com>
> CC: osd-dev@open-osd.org
> Signed-off-by: Sage Weil <sage@newdream.net>
Acked-by: Boaz Harrosh <bharrosh@panasas.com>
Sounds good, Thanks
> ---
> fs/exofs/namei.c | 5 -----
> 1 files changed, 0 insertions(+), 5 deletions(-)
>
> diff --git a/fs/exofs/namei.c b/fs/exofs/namei.c
> index de252e5..4d70db1 100644
> --- a/fs/exofs/namei.c
> +++ b/fs/exofs/namei.c
> @@ -227,8 +227,6 @@ static int exofs_rmdir(struct inode *dir, struct dentry *dentry)
> struct inode *inode = dentry->d_inode;
> int err = -ENOTEMPTY;
>
> - dentry_unhash(dentry);
> -
> if (exofs_empty_dir(inode)) {
> err = exofs_unlink(dir, dentry);
> if (!err) {
> @@ -251,9 +249,6 @@ 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;
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 00/18] clean up VFS dentry_hash (mis)behavior
2011-05-11 10:06 ` [PATCH 00/18] clean up VFS dentry_hash (mis)behavior Christoph Hellwig
@ 2011-05-11 17:18 ` Sage Weil
0 siblings, 0 replies; 26+ messages in thread
From: Sage Weil @ 2011-05-11 17:18 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: viro, linux-fsdevel
On Wed, 11 May 2011, Christoph Hellwig wrote:
> The whole series looks good to me, but I think life would be a lot
> easier for many filesystem if we didn't even bother to push down
> the calls for filesystems that don't need it.
>
> You can skip it for XFS with my ACK if you want.
Thanks. I'll drop the XFS pushdowns. I can drop file systems from the
pushdowns as well, but I'd rather hear from the maintainers first. :)
sage
^ permalink raw reply [flat|nested] 26+ messages in thread
end of thread, other threads:[~2011-05-11 17:17 UTC | newest]
Thread overview: 26+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-05-10 4:43 [PATCH 00/18] clean up VFS dentry_hash (mis)behavior Sage Weil
2011-05-10 4:43 ` [PATCH 01/18] vfs: dentry_unhash immediately prior to rmdir Sage Weil
2011-05-10 8:12 ` Christoph Hellwig
2011-05-10 4:43 ` [PATCH 02/18] vfs: remove dget() from dentry_unhash() Sage Weil
2011-05-10 4:43 ` [PATCH 03/18] vfs: push dentry_unhash on rmdir into file systems Sage Weil
2011-05-10 4:43 ` [PATCH 04/18] vfs: push dentry_unhash on rename_dir " Sage Weil
2011-05-10 4:43 ` [PATCH 05/18] vfs: update dentry_unhash() comment Sage Weil
2011-05-10 4:43 ` [PATCH 06/18] libfs: drop unneeded dentry_unhash Sage Weil
2011-05-10 4:43 ` [PATCH 07/18] vfs: fix vfs_rename_dir for FS_RENAME_DOES_D_MOVE filesystems Sage Weil
2011-05-10 4:43 ` [PATCH 08/18] ceph: remove unnecessary dentry_unhash calls Sage Weil
2011-05-10 4:43 ` [PATCH 09/18] xfs: remove unnecessary dentry_unhash from rmdir/rename_dir Sage Weil
2011-05-10 4:43 ` [PATCH 10/18] btrfs: remove unnecessary dentry_unhash in rmdir/rename_dir Sage Weil
2011-05-10 4:43 ` [PATCH 11/18] ext4: remove unnecessary dentry_unhash on rmdir/rename_dir Sage Weil
2011-05-10 4:43 ` [PATCH 12/18] ext3: " Sage Weil
2011-05-10 4:43 ` [PATCH 13/18] ext2: " Sage Weil
[not found] ` <1305002616-16782-1-git-send-email-sage-BnTBU8nroG7k1uMJSBkQmQ@public.gmane.org>
2011-05-10 4:43 ` [PATCH 14/18] nfs: " Sage Weil
2011-05-10 4:43 ` [PATCH 15/18] exofs: " Sage Weil
2011-05-11 12:53 ` Boaz Harrosh
2011-05-10 4:43 ` [PATCH 16/18] ocfs2: " Sage Weil
2011-05-10 20:24 ` Joel Becker
2011-05-10 4:43 ` [PATCH 17/18] gfs2: " Sage Weil
2011-05-10 8:45 ` Steven Whitehouse
2011-05-10 15:47 ` Sage Weil
2011-05-10 4:43 ` [PATCH 18/18] cifs: " Sage Weil
2011-05-11 10:06 ` [PATCH 00/18] clean up VFS dentry_hash (mis)behavior Christoph Hellwig
2011-05-11 17:18 ` Sage Weil
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).