All of lore.kernel.org
 help / color / mirror / Atom feed
From: Nick Piggin <npiggin@kernel.dk>
To: "J. Bruce Fields" <bfields@fieldses.org>
Cc: Alexander Viro <viro@zeniv.linux.org.uk>,
	Nick Piggin <npiggin@gmail.com>,
	linux-nfs@vger.kernel.org, linux-fsdevel@vger.kernel.org
Subject: Re: [PATCH] nfsd4: allow __d_obtain_alias() to return unhashed dentries
Date: Mon, 13 Dec 2010 16:19:44 +1100	[thread overview]
Message-ID: <20101213051944.GA8688@amd> (raw)
In-Reply-To: <20101203223326.GB28763@fieldses.org>

On Fri, Dec 03, 2010 at 05:33:27PM -0500, J. Bruce Fields wrote:
> From: J. Bruce Fields <bfields@redhat.com>
> 
> Without this patch
> 
>        client$ mount -tnfs4 server:/export/ /mnt/
>        client$ tail -f /mnt/FOO
>        ...
>        server$ df -i /export
>        server$ rm /export/FOO
>        (^C the tail -f)
>        server$ df -i /export
>        server$ echo 2 >/proc/sys/vm/drop_caches
>        server$ df -i /export
> 
> the df's will show that the inode is not freed on the filesystem until
> the last step, when it could have been freed after killing the client's
> tail -f.  On-disk data won't be deallocated either, leading to possible
> spurious ENOSPC.
> 
> This occurs because when the client does the close, it arrives in a
> compound with a putfh and a close, processed like:
> 
>        - putfh: look up the filehandle.  The only alias found for the
>          inode will be DCACHE_UNHASHED alias referenced by the filp
>          associated with the nfsd open.  d_obtain_alias() doesn't like
>          this, so it creates a new DCACHE_DISCONECTED dentry and
>          returns that instead.
> 
> Nick Piggin suggested fixing this by allowing d_obtain_alias to return
> the unhashed dentry that is referenced by the filp, instead of making it
> create a new dentry.
> 
> Cc: Nick Piggin <npiggin@gmail.com>
> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
> ---
>  fs/dcache.c |    2 +-
>  1 files changed, 1 insertions(+), 1 deletions(-)
> 
> On Tue, Nov 30, 2010 at 12:00:16PM +1100, Nick Piggin wrote:
> > On Tue, Nov 30, 2010 at 6:32 AM, J. Bruce Fields <bfields@fieldses.org> wrote:
> > > On Mon, Nov 29, 2010 at 02:56:22PM +1100, Nick Piggin wrote:
> > >> On Tue, Nov 16, 2010 at 5:45 PM, Nick Piggin <npiggin@gmail.com> wrote:
> > >> > On Tue, Nov 16, 2010 at 4:48 AM, J. Bruce Fields <bfields@fieldses.org> wrote:
> > >> >> On Sat, Nov 13, 2010 at 10:53:12PM +1100, Nick Piggin wrote:
> > >> >>> Can you even put the link check into __d_find_alias?
> > >> >>>
> > >> >>> -               if (S_ISDIR(inode->i_mode) || !d_unhashed(alias)) {
> > >> >>> +               if (S_ISDIR(inode->i_mode) || !inode->i_nlink ||
> > >> >>> !d_unhashed(alias)) {
> > >> >>>
> > >> >>> Something like that?
> > >> >>
> > >> >> The immediate result of that would be for the close rpc (or any rpc's
> > >> >> sent after the file was unlinked) to fail with ESTALE.
> > >> >
> > >> > Why is that? Seems like it would be a bug, because a hashed dentry may
> > >> > be unhashed at any time concurrently to nfsd operation, so it should be
> > >> > able to tolerate that so long as it has a ref on the inode?
> > >>
> > >> Ping? Did you work out why nfs fails with ESTALE in that case? It seems
> > >> to work in my testing (and do the right thing with freeing the inode).
> > >
> > > Bah, sorry, I read too quickly, got the sense of the test backwards, and
> > > thought you were suggesting __d_find_alias() shouldn't return an alias
> > > in the i_nlink == 0 case!
> > >
> > > Yes, agreed, that should solve my problem.
> > 
> > OK, good.
> > 
> > > But what's the reason for the d_unhashed() check now?  Could we get rid
> > > of it entirely?
> > 
> > Well when the inode still has links I think we actually do want any new
> > references to go to hashed dentries. Definitely for d_splice_alias.
> 
> So here's a version with a changelog; objections?

Not sure where Al's hiding...

But I would like to update the comments, and perhaps even a new
add a new function here (or new flag to __d_find_alias).

AFAIKS, the callers are OK, however I suppose d_splice_alias and
d_materialise_unique should not have unlinked inodes at this point,
so at least a BUG_ON for them might be a good idea?

> 
> --b.
> 
> diff --git a/fs/dcache.c b/fs/dcache.c
> index 23702a9..afa8a0d 100644
> --- a/fs/dcache.c
> +++ b/fs/dcache.c
> @@ -368,7 +368,7 @@ static struct dentry * __d_find_alias(struct inode *inode, int want_discon)
>  		next = tmp->next;
>  		prefetch(next);
>  		alias = list_entry(tmp, struct dentry, d_alias);
> - 		if (S_ISDIR(inode->i_mode) || !d_unhashed(alias)) {
> +		if (S_ISDIR(inode->i_mode) || !inode->i_nlink || !d_unhashed(alias)) {
>  			if (IS_ROOT(alias) &&
>  			    (alias->d_flags & DCACHE_DISCONNECTED))
>  				discon_alias = alias;

WARNING: multiple messages have this Message-ID (diff)
From: Nick Piggin <npiggin@kernel.dk>
To: "J. Bruce Fields" <bfields@fieldses.org>
Cc: Alexander Viro <viro@zeniv.linux.org.uk>,
	Nick Piggin <npiggin@gmail.com>,
	linux-nfs@vger.kernel.org, linux-fsdevel@vger.kernel.org
Subject: Re: [PATCH] nfsd4: allow __d_obtain_alias() to return unhashed dentries
Date: Mon, 13 Dec 2010 16:19:44 +1100	[thread overview]
Message-ID: <20101213051944.GA8688@amd> (raw)
In-Reply-To: <20101203223326.GB28763@fieldses.org>

On Fri, Dec 03, 2010 at 05:33:27PM -0500, J. Bruce Fields wrote:
> From: J. Bruce Fields <bfields@redhat.com>
> 
> Without this patch
> 
>        client$ mount -tnfs4 server:/export/ /mnt/
>        client$ tail -f /mnt/FOO
>        ...
>        server$ df -i /export
>        server$ rm /export/FOO
>        (^C the tail -f)
>        server$ df -i /export
>        server$ echo 2 >/proc/sys/vm/drop_caches
>        server$ df -i /export
> 
> the df's will show that the inode is not freed on the filesystem until
> the last step, when it could have been freed after killing the client's
> tail -f.  On-disk data won't be deallocated either, leading to possible
> spurious ENOSPC.
> 
> This occurs because when the client does the close, it arrives in a
> compound with a putfh and a close, processed like:
> 
>        - putfh: look up the filehandle.  The only alias found for the
>          inode will be DCACHE_UNHASHED alias referenced by the filp
>          associated with the nfsd open.  d_obtain_alias() doesn't like
>          this, so it creates a new DCACHE_DISCONECTED dentry and
>          returns that instead.
> 
> Nick Piggin suggested fixing this by allowing d_obtain_alias to return
> the unhashed dentry that is referenced by the filp, instead of making it
> create a new dentry.
> 
> Cc: Nick Piggin <npiggin@gmail.com>
> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
> ---
>  fs/dcache.c |    2 +-
>  1 files changed, 1 insertions(+), 1 deletions(-)
> 
> On Tue, Nov 30, 2010 at 12:00:16PM +1100, Nick Piggin wrote:
> > On Tue, Nov 30, 2010 at 6:32 AM, J. Bruce Fields <bfields@fieldses.org> wrote:
> > > On Mon, Nov 29, 2010 at 02:56:22PM +1100, Nick Piggin wrote:
> > >> On Tue, Nov 16, 2010 at 5:45 PM, Nick Piggin <npiggin@gmail.com> wrote:
> > >> > On Tue, Nov 16, 2010 at 4:48 AM, J. Bruce Fields <bfields@fieldses.org> wrote:
> > >> >> On Sat, Nov 13, 2010 at 10:53:12PM +1100, Nick Piggin wrote:
> > >> >>> Can you even put the link check into __d_find_alias?
> > >> >>>
> > >> >>> -               if (S_ISDIR(inode->i_mode) || !d_unhashed(alias)) {
> > >> >>> +               if (S_ISDIR(inode->i_mode) || !inode->i_nlink ||
> > >> >>> !d_unhashed(alias)) {
> > >> >>>
> > >> >>> Something like that?
> > >> >>
> > >> >> The immediate result of that would be for the close rpc (or any rpc's
> > >> >> sent after the file was unlinked) to fail with ESTALE.
> > >> >
> > >> > Why is that? Seems like it would be a bug, because a hashed dentry may
> > >> > be unhashed at any time concurrently to nfsd operation, so it should be
> > >> > able to tolerate that so long as it has a ref on the inode?
> > >>
> > >> Ping? Did you work out why nfs fails with ESTALE in that case? It seems
> > >> to work in my testing (and do the right thing with freeing the inode).
> > >
> > > Bah, sorry, I read too quickly, got the sense of the test backwards, and
> > > thought you were suggesting __d_find_alias() shouldn't return an alias
> > > in the i_nlink == 0 case!
> > >
> > > Yes, agreed, that should solve my problem.
> > 
> > OK, good.
> > 
> > > But what's the reason for the d_unhashed() check now?  Could we get rid
> > > of it entirely?
> > 
> > Well when the inode still has links I think we actually do want any new
> > references to go to hashed dentries. Definitely for d_splice_alias.
> 
> So here's a version with a changelog; objections?

Not sure where Al's hiding...

But I would like to update the comments, and perhaps even a new
add a new function here (or new flag to __d_find_alias).

AFAIKS, the callers are OK, however I suppose d_splice_alias and
d_materialise_unique should not have unlinked inodes at this point,
so at least a BUG_ON for them might be a good idea?

> 
> --b.
> 
> diff --git a/fs/dcache.c b/fs/dcache.c
> index 23702a9..afa8a0d 100644
> --- a/fs/dcache.c
> +++ b/fs/dcache.c
> @@ -368,7 +368,7 @@ static struct dentry * __d_find_alias(struct inode *inode, int want_discon)
>  		next = tmp->next;
>  		prefetch(next);
>  		alias = list_entry(tmp, struct dentry, d_alias);
> - 		if (S_ISDIR(inode->i_mode) || !d_unhashed(alias)) {
> +		if (S_ISDIR(inode->i_mode) || !inode->i_nlink || !d_unhashed(alias)) {
>  			if (IS_ROOT(alias) &&
>  			    (alias->d_flags & DCACHE_DISCONNECTED))
>  				discon_alias = alias;
--
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

  reply	other threads:[~2010-12-13  5:19 UTC|newest]

Thread overview: 73+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-11-12 18:43 lifetime of DCACHE_DISCONECTED dentries J. Bruce Fields
2010-11-13 11:53 ` Nick Piggin
2010-11-13 11:53   ` Nick Piggin
2010-11-15 17:48   ` J. Bruce Fields
2010-11-15 17:48     ` J. Bruce Fields
2010-11-16  6:45     ` Nick Piggin
2010-11-16  6:45       ` Nick Piggin
2010-11-29  3:56       ` Nick Piggin
2010-11-29  3:56         ` Nick Piggin
2010-11-29 19:32         ` J. Bruce Fields
2010-11-29 19:32           ` J. Bruce Fields
2010-11-30  1:00           ` Nick Piggin
2010-11-30  1:00             ` Nick Piggin
2010-11-30 18:39             ` J. Bruce Fields
2010-11-30 18:39               ` J. Bruce Fields
2010-12-03 22:33             ` [PATCH] nfsd4: allow __d_obtain_alias() to return unhashed dentries J. Bruce Fields
2010-12-03 22:33               ` J. Bruce Fields
2010-12-13  5:19               ` Nick Piggin [this message]
2010-12-13  5:19                 ` Nick Piggin
2010-12-14 22:01                 ` J. Bruce Fields
2010-12-14 22:01                   ` J. Bruce Fields
2010-12-17 17:53                   ` [PATCH] fs/dcache: use standard list macro for d_find_alias J. Bruce Fields
2010-12-17 17:53                     ` J. Bruce Fields
2010-12-17 18:00                   ` [PATCH 2/2] fs/dcache: allow __d_obtain_alias() to return unhashed dentries J. Bruce Fields
2010-12-17 18:00                     ` J. Bruce Fields
2010-12-18  2:01                     ` Nick Piggin
2010-12-18  2:01                       ` Nick Piggin
2010-12-18 16:16                       ` J. Bruce Fields
2010-12-18 16:16                         ` J. Bruce Fields
2010-12-19 14:53                         ` Nick Piggin
2010-12-19 14:53                           ` Nick Piggin
2010-12-27 23:46                           ` [PATCH] " J. Bruce Fields
2010-12-27 23:46                             ` J. Bruce Fields
2011-01-18 20:45                             ` J. Bruce Fields
2011-01-18 20:45                               ` J. Bruce Fields
2011-01-18 22:02                               ` Nick Piggin
2011-01-18 22:02                                 ` Nick Piggin
2011-01-18 22:08                                 ` J. Bruce Fields
2011-01-18 22:08                                   ` J. Bruce Fields
2011-03-08 18:13                                   ` J. Bruce Fields
2011-03-08 18:13                                     ` J. Bruce Fields
2011-03-10 10:58                                     ` Al Viro
2011-03-10 10:58                                       ` Al Viro
2011-03-11  4:07                                       ` NeilBrown
2011-03-11  4:07                                         ` NeilBrown
2012-02-14 17:03                                         ` J. Bruce Fields
2012-02-14 17:03                                           ` J. Bruce Fields
2012-02-15 16:56                                           ` J. Bruce Fields
2012-02-15 16:56                                             ` J. Bruce Fields
2012-02-16  3:06                                             ` NeilBrown
2012-02-16  3:06                                               ` NeilBrown
2012-02-16 11:51                                               ` J. Bruce Fields
2012-02-16 11:51                                                 ` J. Bruce Fields
2012-02-16 16:08                                                 ` J. Bruce Fields
2012-02-16 16:08                                                   ` J. Bruce Fields
2012-02-16 22:30                                               ` J. Bruce Fields
2012-02-17 16:34                                                 ` Peng Tao
2012-02-17 16:34                                                   ` Peng Tao
2012-03-13 20:55                                                   ` J. Bruce Fields
2012-03-13 20:55                                                     ` J. Bruce Fields
2012-03-13 20:58                                                     ` [PATCH 1/2] vfs: stop d_splice_alias creating directory aliases J. Bruce Fields
2012-03-13 20:58                                                     ` [PATCH 2/2] vfs: remove unused __d_splice_alias argument J. Bruce Fields
2012-02-20  2:55                                                 ` [PATCH] fs/dcache: allow __d_obtain_alias() to return unhashed dentries NeilBrown
2012-02-20  2:55                                                   ` NeilBrown
2012-02-29 23:10                                                   ` J. Bruce Fields
2012-02-29 23:10                                                     ` J. Bruce Fields
2012-06-28 13:59                                         ` J. Bruce Fields
2012-06-28 13:59                                           ` J. Bruce Fields
2012-06-29 20:10                                           ` J. Bruce Fields
2012-06-29 20:10                                             ` J. Bruce Fields
2012-06-29 20:29                                             ` J. Bruce Fields
2012-06-29 20:29                                               ` J. Bruce Fields
2012-07-01 23:15                                               ` NeilBrown

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=20101213051944.GA8688@amd \
    --to=npiggin@kernel.dk \
    --cc=bfields@fieldses.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-nfs@vger.kernel.org \
    --cc=npiggin@gmail.com \
    --cc=viro@zeniv.linux.org.uk \
    /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.