All of lore.kernel.org
 help / color / mirror / Atom feed
From: "J. R. Okajima" <hooanon05g@gmail.com>
To: Al Viro <viro@ZenIV.linux.org.uk>
Cc: linux-fsdevel@vger.kernel.org
Subject: Re: Q. hlist_bl_add_head_rcu() in d_alloc_parallel()
Date: Sun, 19 Jun 2016 14:24:44 +0900	[thread overview]
Message-ID: <2123.1466313884@jrobl> (raw)
In-Reply-To: <20160617221614.GE14480@ZenIV.linux.org.uk>


Al Viro:
> Huh?  If you have two processes reaching that insertion into the in-lookup
> hash, whoever gets the hlist_bl_lock() first wins; the loser will find
> the instance added by the winner and bugger off with it.  RCU is completely
> unrelated to that.  It's about the search in *primary* hash.

Ok, forget about rcu_barrier.

----------------------------------------

> 	look for match in in-lookup hash
> 	if found
> 		unlock the chain
> 		wait for the match to cease being in-lookup
> 		drop the match
> 		goto retry	[see below]
> 	insert new into in-lookup hash

The actual matching test which corresponds to above pseudo-code (if
found) is this (from v4.7-rc3).

	dentry->d_name.hash != hash
	dentry->d_parent != parent
	d_unhashed(dentry)
	name (length and string)

I am afraid this d_unhashed() test is racy.
Here is what I am guessing.

- two processes try opening the same file
- the both enter the hlist_bl_lock protected loop in d_alloc_parallel()

- the winner puts the new dentry into in-lookup hash
  + here d_unhashed(dentry) would still return true.
- then the winner process will call ->atomic_open or ->lookup. finally
  d_add() and rehash will be called and the dentry will be moved to the
  primary hash.
  + here d_unhashed(dentry) would return false.

As soon as the winner calls hlist_bl_unlock(), the looser starts
d_in_lookup_hash loop and find the dentry which the winner added.

- the looser (or we should call processB) do the tests
	dentry->d_name.hash != hash
	dentry->d_parent != parent
	d_unhashed(dentry)
- if processA has already called d_add and rehash, then this
  d_unhashed() test would return false, and processB will throw away his
  own 'new' dentry and return the found one.
- if processA has NOT called d_add and rehash yet (due to the schedule
  timing), then this d_unhashed() test would return true, and processB
  will simply skip the found dentry.
  in this case, processB will add his own 'new' dentry into in-lookup
  hash and return it.

Finally this race between these two
- d_add and rehash via ->atomic_open or ->lookup
- d_unhashed test in d_alloc_parallel
leads to the duplicated dentries (same named dentry under the same
parent).

Do you think it can happen?


J. R. Okajima

  parent reply	other threads:[~2016-06-19  5:24 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-06-17 20:50 Q. hlist_bl_add_head_rcu() in d_alloc_parallel() J. R. Okajima
2016-06-17 22:16 ` Al Viro
2016-06-17 22:56   ` Al Viro
2016-06-19  5:24   ` J. R. Okajima [this message]
2016-06-19 16:55     ` Al Viro
2016-06-20  4:34       ` J. R. Okajima
2016-06-20  5:35         ` Al Viro
2016-06-20 14:51           ` Al Viro
2016-06-20 17:14             ` [git pull] vfs fixes Al Viro
2016-06-23  1:19           ` Q. hlist_bl_add_head_rcu() in d_alloc_parallel() J. R. Okajima
2016-06-23  2:58             ` Al Viro
2016-06-24  5:57               ` Linus Torvalds
2016-06-25 22:54                 ` Al Viro
2016-06-26  1:25                   ` Linus Torvalds
2016-06-29  8:17                     ` Al Viro
2016-06-29  9:22                       ` Hekuang

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=2123.1466313884@jrobl \
    --to=hooanon05g@gmail.com \
    --cc=linux-fsdevel@vger.kernel.org \
    --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.