From: Amir Goldstein <amir73il@gmail.com>
To: Miklos Szeredi <miklos@szeredi.hu>
Cc: Vivek Goyal <vgoyal@redhat.com>,
Al Viro <viro@zeniv.linux.org.uk>,
overlayfs <linux-unionfs@vger.kernel.org>,
linux-fsdevel <linux-fsdevel@vger.kernel.org>
Subject: Re: [PATCH v3 1/4] ovl: use insert_inode_locked4() to hash a newly created inode
Date: Thu, 17 May 2018 11:58:49 +0300 [thread overview]
Message-ID: <CAOQ4uxh-2Hitha8_01jNqO5qd=wuX8cmqsCcz5Fhr7mP8sk2NQ@mail.gmail.com> (raw)
In-Reply-To: <20180517085305.GA23785@veci.piliscsaba.redhat.com>
On Thu, May 17, 2018 at 11:53 AM, Miklos Szeredi <miklos@szeredi.hu> wrote:
> On Thu, May 17, 2018 at 10:10:58AM +0200, Miklos Szeredi wrote:
>>
>> Not the only reason: we don't want inode allocation to fail after
>> successful creation. Solution: add a preallocated inode argument to
>> ovl_get_inode() and deal with allocation failure there.
>
> Here's a patch to split a helper out of iget5_locked() that takes a preallocated
> inode. It makes the whole thing more readable, IMO, regardless of overlayfs's
> needs.
>
That looks good. I'll use that.
One suggestion below.
Thanks,
Amir.
>
> ---
> diff --git a/fs/inode.c b/fs/inode.c
> index 13ceb98c3bd3..bb79e3f96147 100644
> --- a/fs/inode.c
> +++ b/fs/inode.c
> @@ -1002,6 +1002,52 @@ void unlock_two_nondirectories(struct inode *inode1, struct inode *inode2)
> }
> EXPORT_SYMBOL(unlock_two_nondirectories);
>
> +struct inode *iget5_prealloc(struct inode *inode,
> + struct super_block *sb, unsigned long hashval,
Maybe no need to pass in @sb...
> + int (*test)(struct inode *, void *),
> + int (*set)(struct inode *, void *), void *data)
> +{
> + struct hlist_head *head = inode_hashtable + hash(sb, hashval);
> + struct inode *old;
> +
> +again:
> + spin_lock(&inode_hash_lock);
> + old = find_inode(sb, head, test, data);
> + if (unlikely(old)) {
> + /*
> + * Uhhuh, somebody else created the same inode under us.
> + * Use the old inode instead of the preallocated one.
> + */
> + spin_unlock(&inode_hash_lock);
> + wait_on_inode(old);
> + if (unlikely(inode_unhashed(old))) {
> + iput(old);
> + goto again;
> + }
> + return old;
> + }
> +
> + if (unlikely(set(inode, data))) {
> + inode = NULL;
> + goto unlock;
> + }
> +
> + /*
> + * Return the locked inode with I_NEW set, the
> + * caller is responsible for filling in the contents
> + */
> + spin_lock(&inode->i_lock);
> + inode->i_state = I_NEW;
> + hlist_add_head(&inode->i_hash, head);
> + spin_unlock(&inode->i_lock);
> + inode_sb_list_add(inode);
> +unlock:
> + spin_unlock(&inode_hash_lock);
> +
> + return inode;
> +}
> +EXPORT_SYMBOL(iget5_prealloc);
> +
> /**
> * iget5_locked - obtain an inode from a mounted file system
> * @sb: super block of file system
> @@ -1026,66 +1072,18 @@ struct inode *iget5_locked(struct super_block *sb, unsigned long hashval,
> int (*test)(struct inode *, void *),
> int (*set)(struct inode *, void *), void *data)
> {
> - struct hlist_head *head = inode_hashtable + hash(sb, hashval);
> - struct inode *inode;
> -again:
> - spin_lock(&inode_hash_lock);
> - inode = find_inode(sb, head, test, data);
> - spin_unlock(&inode_hash_lock);
> + struct inode *inode = ilookup5(sb, hashval, test, data);
>
> - if (inode) {
> - wait_on_inode(inode);
> - if (unlikely(inode_unhashed(inode))) {
> - iput(inode);
> - goto again;
> - }
> - return inode;
> - }
> -
> - inode = alloc_inode(sb);
> - if (inode) {
> - struct inode *old;
> -
> - spin_lock(&inode_hash_lock);
> - /* We released the lock, so.. */
> - old = find_inode(sb, head, test, data);
> - if (!old) {
> - if (set(inode, data))
> - goto set_failed;
> -
> - spin_lock(&inode->i_lock);
> - inode->i_state = I_NEW;
> - hlist_add_head(&inode->i_hash, head);
> - spin_unlock(&inode->i_lock);
> - inode_sb_list_add(inode);
> - spin_unlock(&inode_hash_lock);
> -
> - /* Return the locked inode with I_NEW set, the
> - * caller is responsible for filling in the contents
> - */
> - return inode;
> - }
> + if (!inode) {
> + struct inode *new = alloc_inode(sb);
>
> - /*
> - * Uhhuh, somebody else created the same inode under
> - * us. Use the old inode instead of the one we just
> - * allocated.
> - */
> - spin_unlock(&inode_hash_lock);
> - destroy_inode(inode);
> - inode = old;
> - wait_on_inode(inode);
> - if (unlikely(inode_unhashed(inode))) {
> - iput(inode);
> - goto again;
> + if (new) {
> + inode = iget5_prealloc(new, sb, hashval, test, set, data);
> + if (inode != new)
> + destroy_inode(new);
> }
> }
> return inode;
> -
> -set_failed:
> - spin_unlock(&inode_hash_lock);
> - destroy_inode(inode);
> - return NULL;
> }
> EXPORT_SYMBOL(iget5_locked);
>
next prev parent reply other threads:[~2018-05-17 8:58 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-05-15 10:26 [PATCH v3 0/4] Overlayfs mkdir related fixes Amir Goldstein
2018-05-15 10:26 ` [PATCH v3 1/4] ovl: use insert_inode_locked4() to hash a newly created inode Amir Goldstein
2018-05-15 13:23 ` Vivek Goyal
2018-05-15 13:37 ` Amir Goldstein
2018-05-16 8:34 ` Miklos Szeredi
2018-05-16 9:51 ` Amir Goldstein
2018-05-16 10:14 ` Miklos Szeredi
2018-05-16 11:03 ` Amir Goldstein
2018-05-17 6:03 ` Amir Goldstein
2018-05-17 8:10 ` Miklos Szeredi
2018-05-17 8:45 ` Amir Goldstein
2018-05-17 8:53 ` Miklos Szeredi
2018-05-17 8:58 ` Amir Goldstein [this message]
2018-05-17 9:07 ` Miklos Szeredi
2018-05-17 16:14 ` Amir Goldstein
2018-05-15 10:26 ` [PATCH v3 2/4] ovl: relax WARN_ON() real inode attributes mismatch Amir Goldstein
2018-05-15 12:48 ` Vivek Goyal
2018-05-15 12:55 ` Amir Goldstein
2018-05-16 10:29 ` Miklos Szeredi
2018-05-16 11:06 ` Amir Goldstein
2018-05-16 11:18 ` Miklos Szeredi
2018-05-16 13:46 ` Amir Goldstein
2018-05-15 10:26 ` [PATCH v3 3/4] ovl: create helper ovl_create_temp() Amir Goldstein
2018-05-16 10:41 ` Miklos Szeredi
2018-05-16 11:15 ` Amir Goldstein
2018-05-16 11:37 ` Miklos Szeredi
2018-05-15 10:26 ` [PATCH v3 4/4] ovl: make ovl_create_real() cope with vfs_mkdir() safely Amir Goldstein
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='CAOQ4uxh-2Hitha8_01jNqO5qd=wuX8cmqsCcz5Fhr7mP8sk2NQ@mail.gmail.com' \
--to=amir73il@gmail.com \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-unionfs@vger.kernel.org \
--cc=miklos@szeredi.hu \
--cc=vgoyal@redhat.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 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).