All of lore.kernel.org
 help / color / mirror / Atom feed
From: Brian Foster <bfoster@redhat.com>
To: Niels de Vos <ndevos@redhat.com>
Cc: Miklos Szeredi <miklos@szeredi.hu>,
	fuse-devel@lists.sourceforge.net, linux-kernel@vger.kernel.org
Subject: Re: [fuse-devel] [PATCH] fuse: fix occasional dentry leak when readdirplus is used
Date: Tue, 16 Jul 2013 09:15:16 -0400	[thread overview]
Message-ID: <51E54764.4070106@redhat.com> (raw)
In-Reply-To: <20130716103939.GL18803@ndevos-laptop.usersys.redhat.com>

On 07/16/2013 06:39 AM, Niels de Vos wrote:
> On Mon, Jul 15, 2013 at 04:08:22PM -0400, Brian Foster wrote:
>> On 07/15/2013 08:59 AM, Niels de Vos wrote:
...
> 
>>> ---
>>>  fs/fuse/dir.c |    4 +++-
>>>  1 files changed, 3 insertions(+), 1 deletions(-)
>>>
>>> diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
>>> index 0eda527..da67a15 100644
>>> --- a/fs/fuse/dir.c
>>> +++ b/fs/fuse/dir.c
>>> @@ -1246,7 +1246,9 @@ static int fuse_direntplus_link(struct file *file,
>>>  		if (err)
>>>  			goto out;
>>>  		dput(dentry);
>>> -		dentry = NULL;
>>> +	} else if (dentry) {
>>> +		/* this dentry does not have a d_inode, just drop it */
>>> +		dput(dentry);
>>>  	}
>>
>> I'm not really familiar with the dcache code, but is it appropriate to
>> also d_invalidate() the dentry in this case (as the previous code block
>> does)? Perhaps Miklos or somebody more familiar with dcache can confirm...
> 
> I do not *think* d_invalidate() is needed. The vmcores I have seem where 
> this BUG() happened, only have dentry->d_flags = 0x18 which translates 
> to (DCACHE_OP_DELETE | DCACHE_OP_PRUNE) and d_subdirs as an empty list.  
> d_invalidate() only calls __d_drop(), which only does something when the 
> dentry is hashed.
> 

I ran a little experiment to invoke a d_lookup() after the
fuse_direntplus_link() function has done its work in this particular
case. I do receive the newly allocated dentry.

Subsequently, I hacked __d_lookup_rcu() to continue iterating the list
after finding an entry to check for duplicates and print a message. What
I see is that after the dput() (via a subsequent lookup resulting from a
getxattr call), the negative dentry is still hashed and on the list (my
printk() kicks in after the existing d_unhashed() check). The flags for
both dentries are
(DCACHE_OP_REVALIDATE|DCACHE_REFERENCED|DCACHE_RCUACCESS). I'm not aware
of the steps involved in the original reproducer, but the simple
multi-mount test leads to this state. Running a d_invalidate() clears it
up. So perhaps it's required in some cases and not all.

That said, some of those flags seem to simply specify whether a dentry
op handler is defined for the particular operation or not.

> I am not sure if a dentry can be hashed, but still does not have a valid 
> non-NULL d_inode. If that is the case, d_invalidate() should indeed be 
> called.
> 

I'm not sure why it would need to have a valid inode. A dentry with a
NULL inode is valid, no? I think the question is whether the above state
(multiple, hashed dentries) can be valid for whatever reason. It
certainly looks suspicious.

Brian

> Thanks,
> Niels
> 
>> Brian
>>
>>>  
>>>  	dentry = d_alloc(parent, &name);
>>>
>>
> 


  reply	other threads:[~2013-07-16 13:18 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-07-15 12:59 [PATCH] fuse: fix occasional dentry leak when readdirplus is used Niels de Vos
2013-07-15 20:08 ` [fuse-devel] " Brian Foster
2013-07-16 10:39   ` Niels de Vos
2013-07-16 13:15     ` Brian Foster [this message]
2013-07-16 16:14       ` Miklos Szeredi
2013-07-16 17:43         ` Brian Foster
2013-07-17 11:20         ` Niels de Vos
2013-07-17 13:04           ` Miklos Szeredi

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=51E54764.4070106@redhat.com \
    --to=bfoster@redhat.com \
    --cc=fuse-devel@lists.sourceforge.net \
    --cc=linux-kernel@vger.kernel.org \
    --cc=miklos@szeredi.hu \
    --cc=ndevos@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.