linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Miklos Szeredi <miklos@szeredi.hu>
To: Amir Goldstein <amir73il@gmail.com>
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 10:53:05 +0200	[thread overview]
Message-ID: <20180517085305.GA23785@veci.piliscsaba.redhat.com> (raw)
In-Reply-To: <CAJfpegtC=FHdHAr5WKoMpX+aBTsMQB9Ffv0NfFouuSA3M08sqQ@mail.gmail.com>

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.

Thanks,
Miklos

---
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,
+			     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);
 

  parent reply	other threads:[~2018-05-17  8:53 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 [this message]
2018-05-17  8:58             ` Amir Goldstein
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=20180517085305.GA23785@veci.piliscsaba.redhat.com \
    --to=miklos@szeredi.hu \
    --cc=amir73il@gmail.com \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-unionfs@vger.kernel.org \
    --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).