parallel lookups machinery, part 4 (and last)
authorAl Viro <viro@zeniv.linux.org.uk>
Fri, 15 Apr 2016 07:33:13 +0000 (03:33 -0400)
committerAl Viro <viro@zeniv.linux.org.uk>
Mon, 2 May 2016 23:49:27 +0000 (19:49 -0400)
commitd9171b9345261e0d941d92fdda5672b5db67f968
tree233065eea867fee5f67823e72678923b14cb8a3b
parent94bdd655caba2080ae81d83d756d325abdffcb9f
parallel lookups machinery, part 4 (and last)

If we *do* run into an in-lookup match, we need to wait for it to
cease being in-lookup.  Fortunately, we do have unused space in
in-lookup dentries - d_lru is never looked at until it stops being
in-lookup.

So we can stash a pointer to wait_queue_head from stack frame of
the caller of ->lookup().  Some precautions are needed while
waiting, but it's not that hard - we do hold a reference to dentry
we are waiting for, so it can't go away.  If it's found to be
in-lookup the wait_queue_head is still alive and will remain so
at least while ->d_lock is held.  Moreover, the condition we
are waiting for becomes true at the same point where everything
on that wq gets woken up, so we can just add ourselves to the
queue once.

d_alloc_parallel() gets a pointer to wait_queue_head_t from its
caller; lookup_slow() adjusted, d_add_ci() taught to use
d_alloc_parallel() if the dentry passed to it happens to be
in-lookup one (i.e. if it's been called from the parallel lookup).

That's pretty much it - all that remains is to switch ->i_mutex
to rwsem and have lookup_slow() take it shared.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
fs/dcache.c
fs/namei.c
include/linux/dcache.h