Re: Is VFS behavior fine?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, 02 Jul 2008, Artem Bityutskiy wrote:
> The result of it was that the '->delete_inode()' operation for
> the 'xxx' directory inode is not called. It is not called even
> after 'cd /'. However, if we do not do the 'touch tmp' command
> (which actually fails), '->delete_inode()' _is_ called for 'xxx'.

This certainly doesn't sound right.

<snip>

> The 'tmp' dentry is freed eventually because of unmount or
> memory pressure, but not earlier than that. So the deleted
> inodes may be kept for really long time. Is this OK?

No, deleted dentries should go away immediately, or if they are still
referenced, then they are unhashed, and go away once the reference
disappears.

In this situation however, it seems that the unhashed dentry managed
to acquire a child, which keeps it from being finally killed.  The VFS
shouldn't allow this to happen.

> I may just say that I fixed this in UBIFS by not calling
> 'd_splice_alias()' for not found dentries if the parent
> directory inode has 'n_link' = 0. However, ext[23] always
> call 'd_splice_alias()' for not found direntries (passing
> NULL as the 'inode' parameter).
> 
> Again, I am not 100% sure this is the right fix, because
> I suspect this should be "fixed" in VFS. I tried to do this
> and I have a small VFS patch, but it is probably incorrect.

The correct fix IMO is to make lookup return ENOENT on an IS_DEADDIR()
inode, before even trying to create the child dentry.

Untested patch attached.

Miklos

----
Subject: vfs: fix lookup on deleted directory

From: Miklos Szeredi <mszeredi@xxxxxxx>

Lookup can install a child dentry for a deleted directory.  This keeps
the directory alive even after all external references have gone away.

Fix this by returning ENOENT for all lookups on a S_DEAD directory
before creating a child dentry.

Reported-by: Artem Bityutskiy <Artem.Bityutskiy@xxxxxxxxx>
Signed-off-by: Miklos Szeredi <mszeredi@xxxxxxx>
---
 fs/namei.c |   19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

Index: linux-2.6/fs/namei.c
===================================================================
--- linux-2.6.orig/fs/namei.c	2008-07-01 22:28:42.000000000 +0200
+++ linux-2.6/fs/namei.c	2008-07-02 12:57:27.000000000 +0200
@@ -519,7 +519,14 @@ static struct dentry * real_lookup(struc
 	 */
 	result = d_lookup(parent, name);
 	if (!result) {
-		struct dentry * dentry = d_alloc(parent, name);
+		struct dentry *dentry;
+
+		/* Don't create child dentry for a dead directory. */
+		result = ERR_PTR(-ENOENT);
+		if (IS_DEADDIR(dir))
+			goto out_unlock;
+
+		dentry = d_alloc(parent, name);
 		result = ERR_PTR(-ENOMEM);
 		if (dentry) {
 			result = dir->i_op->lookup(dir, dentry, nd);
@@ -528,6 +535,7 @@ static struct dentry * real_lookup(struc
 			else
 				result = dentry;
 		}
+out_unlock:
 		mutex_unlock(&dir->i_mutex);
 		return result;
 	}
@@ -1317,7 +1325,14 @@ static struct dentry *__lookup_hash(stru
 
 	dentry = cached_lookup(base, name, nd);
 	if (!dentry) {
-		struct dentry *new = d_alloc(base, name);
+		struct dentry *new;
+
+		/* Don't create child dentry for a dead directory. */
+		dentry = ERR_PTR(-ENOENT);
+		if (IS_DEADDIR(inode))
+			goto out;
+
+		new = d_alloc(base, name);
 		dentry = ERR_PTR(-ENOMEM);
 		if (!new)
 			goto out;
--
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [Samba]     [Device Mapper]     [CEPH Development]
  Powered by Linux