From: "J. Bruce Fields" <bfields-uC3wQj2KruNg9hUCZPvPmw@public.gmane.org> To: Nick Piggin <npiggin-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> Cc: Alexander Viro <viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn@public.gmane.org>, Nick Piggin <npiggin-tSWWG44O7X1aa/9Udqfwiw@public.gmane.org>, linux-nfs-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, linux-fsdevel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org Subject: Re: [PATCH] fs/dcache: allow __d_obtain_alias() to return unhashed dentries Date: Tue, 18 Jan 2011 17:08:17 -0500 [thread overview] Message-ID: <20110118220817.GF10903@fieldses.org> (raw) In-Reply-To: <AANLkTikL2CDSWQJ1QH_Y4G-j70Vd=VesNMMnYTmMGHC9-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org> On Wed, Jan 19, 2011 at 09:02:59AM +1100, Nick Piggin wrote: > On Wed, Jan 19, 2011 at 7:45 AM, J. Bruce Fields <bfields-uC3wQj2KruMpug/h7KTFAQ@public.gmane.orgg> wrote: > > @@ -1521,6 +1521,28 @@ struct dentry * d_alloc_root(struct inode * root_inode) > > } > > EXPORT_SYMBOL(d_alloc_root); > > > > +static struct dentry * __d_find_any_alias(struct inode *inode) > > +{ > > + struct dentry *alias; > > + > > + if (list_empty(&inode->i_dentry)) > > + return NULL; > > + alias = list_first_entry(&inode->i_dentry, struct dentry, d_alias); > > + __dget(alias); > > + return alias; > > +} > > + > > +static struct dentry * d_find_any_alias(struct inode *inode) > > +{ > > + struct dentry *de; > > + > > + spin_lock(&inode->i_lock); > > Yes, i_dentry/d_alias is protected by i_lock, so it looks fine. OK, thanks; I'm assuming it's OK to re-add your ack in that case. Al, could you apply? (Or if this should go in through an nfsd tree, or some other way, let me know.) --b. From: J. Bruce Fields <bfields-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> Date: Fri, 17 Dec 2010 09:05:04 -0500 Subject: [PATCH] fs/dcache: allow __d_obtain_alias() to return unhashed dentries Without this patch, inodes are not promptly freed on last close of an unlinked file by an nfs client: 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 this, so it creates a new DCACHE_DISCONECTED dentry and returns that instead. - close: closes the existing filp, which is destroyed immediately by dput() since it's DCACHE_UNHASHED. - end of the compound: release the reference to the current filehandle, and dput() the new DCACHE_DISCONECTED dentry, which gets put on the unused list instead of being destroyed immediately. 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. Leave __d_find_alias() alone to avoid changing behavior of other callers. Also nfsd doesn't need all the checks of __d_find_alias(); any dentry, hashed or unhashed, disconnected or not, should work. Acked-by: Nick Piggin <npiggin-tSWWG44O7X1aa/9Udqfwiw@public.gmane.org> Signed-off-by: J. Bruce Fields <bfields-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> --- fs/dcache.c | 26 ++++++++++++++++++++++++-- 1 files changed, 24 insertions(+), 2 deletions(-) diff --git a/fs/dcache.c b/fs/dcache.c index 9f493ee..2849258 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -1521,6 +1521,28 @@ struct dentry * d_alloc_root(struct inode * root_inode) } EXPORT_SYMBOL(d_alloc_root); +static struct dentry * __d_find_any_alias(struct inode *inode) +{ + struct dentry *alias; + + if (list_empty(&inode->i_dentry)) + return NULL; + alias = list_first_entry(&inode->i_dentry, struct dentry, d_alias); + __dget(alias); + return alias; +} + +static struct dentry * d_find_any_alias(struct inode *inode) +{ + struct dentry *de; + + spin_lock(&inode->i_lock); + de = __d_find_any_alias(inode); + spin_unlock(&inode->i_lock); + return de; +} + + /** * d_obtain_alias - find or allocate a dentry for a given inode * @inode: inode to allocate the dentry for @@ -1550,7 +1572,7 @@ struct dentry *d_obtain_alias(struct inode *inode) if (IS_ERR(inode)) return ERR_CAST(inode); - res = d_find_alias(inode); + res = d_find_any_alias(inode); if (res) goto out_iput; @@ -1563,7 +1585,7 @@ struct dentry *d_obtain_alias(struct inode *inode) spin_lock(&inode->i_lock); - res = __d_find_alias(inode, 0); + res = __d_find_any_alias(inode); if (res) { spin_unlock(&inode->i_lock); dput(tmp); -- 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
WARNING: multiple messages have this Message-ID (diff)
From: "J. Bruce Fields" <bfields@fieldses.org> To: Nick Piggin <npiggin@gmail.com> Cc: Alexander Viro <viro@zeniv.linux.org.uk>, Nick Piggin <npiggin@kernel.dk>, linux-nfs@vger.kernel.org, linux-fsdevel@vger.kernel.org Subject: Re: [PATCH] fs/dcache: allow __d_obtain_alias() to return unhashed dentries Date: Tue, 18 Jan 2011 17:08:17 -0500 [thread overview] Message-ID: <20110118220817.GF10903@fieldses.org> (raw) In-Reply-To: <AANLkTikL2CDSWQJ1QH_Y4G-j70Vd=VesNMMnYTmMGHC9@mail.gmail.com> On Wed, Jan 19, 2011 at 09:02:59AM +1100, Nick Piggin wrote: > On Wed, Jan 19, 2011 at 7:45 AM, J. Bruce Fields <bfields@fieldses.org> wrote: > > @@ -1521,6 +1521,28 @@ struct dentry * d_alloc_root(struct inode * root_inode) > > } > > EXPORT_SYMBOL(d_alloc_root); > > > > +static struct dentry * __d_find_any_alias(struct inode *inode) > > +{ > > + struct dentry *alias; > > + > > + if (list_empty(&inode->i_dentry)) > > + return NULL; > > + alias = list_first_entry(&inode->i_dentry, struct dentry, d_alias); > > + __dget(alias); > > + return alias; > > +} > > + > > +static struct dentry * d_find_any_alias(struct inode *inode) > > +{ > > + struct dentry *de; > > + > > + spin_lock(&inode->i_lock); > > Yes, i_dentry/d_alias is protected by i_lock, so it looks fine. OK, thanks; I'm assuming it's OK to re-add your ack in that case. Al, could you apply? (Or if this should go in through an nfsd tree, or some other way, let me know.) --b. From: J. Bruce Fields <bfields@redhat.com> Date: Fri, 17 Dec 2010 09:05:04 -0500 Subject: [PATCH] fs/dcache: allow __d_obtain_alias() to return unhashed dentries Without this patch, inodes are not promptly freed on last close of an unlinked file by an nfs client: 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 this, so it creates a new DCACHE_DISCONECTED dentry and returns that instead. - close: closes the existing filp, which is destroyed immediately by dput() since it's DCACHE_UNHASHED. - end of the compound: release the reference to the current filehandle, and dput() the new DCACHE_DISCONECTED dentry, which gets put on the unused list instead of being destroyed immediately. 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. Leave __d_find_alias() alone to avoid changing behavior of other callers. Also nfsd doesn't need all the checks of __d_find_alias(); any dentry, hashed or unhashed, disconnected or not, should work. Acked-by: Nick Piggin <npiggin@kernel.dk> Signed-off-by: J. Bruce Fields <bfields@redhat.com> --- fs/dcache.c | 26 ++++++++++++++++++++++++-- 1 files changed, 24 insertions(+), 2 deletions(-) diff --git a/fs/dcache.c b/fs/dcache.c index 9f493ee..2849258 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -1521,6 +1521,28 @@ struct dentry * d_alloc_root(struct inode * root_inode) } EXPORT_SYMBOL(d_alloc_root); +static struct dentry * __d_find_any_alias(struct inode *inode) +{ + struct dentry *alias; + + if (list_empty(&inode->i_dentry)) + return NULL; + alias = list_first_entry(&inode->i_dentry, struct dentry, d_alias); + __dget(alias); + return alias; +} + +static struct dentry * d_find_any_alias(struct inode *inode) +{ + struct dentry *de; + + spin_lock(&inode->i_lock); + de = __d_find_any_alias(inode); + spin_unlock(&inode->i_lock); + return de; +} + + /** * d_obtain_alias - find or allocate a dentry for a given inode * @inode: inode to allocate the dentry for @@ -1550,7 +1572,7 @@ struct dentry *d_obtain_alias(struct inode *inode) if (IS_ERR(inode)) return ERR_CAST(inode); - res = d_find_alias(inode); + res = d_find_any_alias(inode); if (res) goto out_iput; @@ -1563,7 +1585,7 @@ struct dentry *d_obtain_alias(struct inode *inode) spin_lock(&inode->i_lock); - res = __d_find_alias(inode, 0); + res = __d_find_any_alias(inode); if (res) { spin_unlock(&inode->i_lock); dput(tmp); -- 1.7.1
next prev parent reply other threads:[~2011-01-18 22:08 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 [not found] ` <20101115174837.GB10044-uC3wQj2KruNg9hUCZPvPmw@public.gmane.org> 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 [not found] ` <20101129193248.GA9897-uC3wQj2KruNg9hUCZPvPmw@public.gmane.org> 2010-11-30 1:00 ` Nick Piggin 2010-11-30 1:00 ` Nick Piggin [not found] ` <AANLkTikwzDJ_q65==uxDsAhp3h8bU7Rkt7U9gVgRAK0D-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org> 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 2010-12-13 5:19 ` Nick Piggin 2010-12-14 22:01 ` J. Bruce Fields 2010-12-14 22:01 ` J. Bruce Fields [not found] ` <20101214220102.GM24828-uC3wQj2KruNg9hUCZPvPmw@public.gmane.org> 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 [not found] ` <20101218161609.GA22150-uC3wQj2KruNg9hUCZPvPmw@public.gmane.org> 2010-12-19 14:53 ` Nick Piggin 2010-12-19 14:53 ` Nick Piggin [not found] ` <AANLkTingRv_gtRSctGzMfYrKg02M_sKj97HSQPRm_mA_-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org> 2010-12-27 23:46 ` [PATCH] " J. Bruce Fields 2010-12-27 23:46 ` J. Bruce Fields [not found] ` <20101227234641.GA22248-uC3wQj2KruNg9hUCZPvPmw@public.gmane.org> 2011-01-18 20:45 ` J. Bruce Fields 2011-01-18 20:45 ` J. Bruce Fields [not found] ` <20110118204509.GA10903-uC3wQj2KruNg9hUCZPvPmw@public.gmane.org> 2011-01-18 22:02 ` Nick Piggin 2011-01-18 22:02 ` Nick Piggin [not found] ` <AANLkTikL2CDSWQJ1QH_Y4G-j70Vd=VesNMMnYTmMGHC9-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org> 2011-01-18 22:08 ` J. Bruce Fields [this message] 2011-01-18 22:08 ` J. Bruce Fields [not found] ` <20110118220817.GF10903-uC3wQj2KruNg9hUCZPvPmw@public.gmane.org> 2011-03-08 18:13 ` J. Bruce Fields 2011-03-08 18:13 ` J. Bruce Fields [not found] ` <20110308181320.GA15566-uC3wQj2KruNg9hUCZPvPmw@public.gmane.org> 2011-03-10 10:58 ` Al Viro 2011-03-10 10:58 ` Al Viro [not found] ` <20110310105821.GE22723-3bDd1+5oDREiFSDQTTA3OLVCufUGDwFn@public.gmane.org> 2011-03-11 4:07 ` NeilBrown 2011-03-11 4:07 ` NeilBrown [not found] ` <20110311150749.2fa2be66-wvvUuzkyo1EYVZTmpyfIwg@public.gmane.org> 2012-02-14 17:03 ` J. Bruce Fields 2012-02-14 17:03 ` J. Bruce Fields [not found] ` <20120214170300.GA4309-uC3wQj2KruNg9hUCZPvPmw@public.gmane.org> 2012-02-15 16:56 ` J. Bruce Fields 2012-02-15 16:56 ` J. Bruce Fields [not found] ` <20120215165633.GE12490-uC3wQj2KruNg9hUCZPvPmw@public.gmane.org> 2012-02-16 3:06 ` NeilBrown 2012-02-16 3:06 ` NeilBrown [not found] ` <20120216140603.08cb4900-wvvUuzkyo1EYVZTmpyfIwg@public.gmane.org> 2012-02-16 11:51 ` J. Bruce Fields 2012-02-16 11:51 ` J. Bruce Fields [not found] ` <20120216115133.GA20279-uC3wQj2KruNg9hUCZPvPmw@public.gmane.org> 2012-02-16 16:08 ` J. Bruce Fields 2012-02-16 16:08 ` J. Bruce Fields 2012-02-16 22:30 ` J. Bruce Fields [not found] ` <20120216223011.GA23997-uC3wQj2KruNg9hUCZPvPmw@public.gmane.org> 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 [not found] ` <20120220135537.3078e20b-wvvUuzkyo1EYVZTmpyfIwg@public.gmane.org> 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 [not found] ` <20120628135927.GA6406-uC3wQj2KruNg9hUCZPvPmw@public.gmane.org> 2012-06-29 20:10 ` J. Bruce Fields 2012-06-29 20:10 ` J. Bruce Fields [not found] ` <20120629201034.GA17103-uC3wQj2KruNg9hUCZPvPmw@public.gmane.org> 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=20110118220817.GF10903@fieldses.org \ --to=bfields-uc3wqj2krung9huczpvpmw@public.gmane.org \ --cc=linux-fsdevel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \ --cc=linux-nfs-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \ --cc=npiggin-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org \ --cc=npiggin-tSWWG44O7X1aa/9Udqfwiw@public.gmane.org \ --cc=viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn@public.gmane.org \ /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: linkBe 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.