From: Al Viro <viro@ZenIV.linux.org.uk>
To: Linus Torvalds <torvalds@linux-foundation.org>
Cc: linux-fsdevel@vger.kernel.org, npiggin@kernel.dk
Subject: Re: ->d_lock FUBAR (was Re: Linux 3.0-rc6)
Date: Wed, 13 Jul 2011 02:39:36 +0100 [thread overview]
Message-ID: <20110713013936.GL11013@ZenIV.linux.org.uk> (raw)
In-Reply-To: <20110713005634.GK11013@ZenIV.linux.org.uk>
On Wed, Jul 13, 2011 at 01:56:34AM +0100, Al Viro wrote:
> Nick, could you please describe the locking rules you had in mind for
> ->d_lock? unlazy_walk() (aka nameidata_dentry_drop_rcu()) can probably
> be dealt with by checking d_seq twice, once before locking the child.
> Then we could be sure that it's still a child of parent and will stay
> so as long as parent's ->d_lock is held, and thus the ordering would
> stay stable...
As the matter of fact, can we ever get there with IS_ROOT(dentry)?
AFAICS, that should be impossible - dentry->d_seq would have to be
changed by whatever had torn it off the tree and we would have
buggered off on __d_rcu_to_refcount() failing...
AFAICS, the only way to get there would be with mountpoint crossing
returning a symlink with symlink already killed by rename() somehow
(call in walk_component()). The first part should be impossible -
symlinks can't be mounted/bound on anything (and if it would be
possible, we'd trigger that BUG_ON() if symlink was still alive,
anyway).
So here's what I want to do to unlazy_walk(); it'll almost certainly
leave other problems with ->d_lock, but at least it'll take care of
that one:
Make sure that child is still a child of parent before nested locking
of child->d_lock in unlazy_walk(); otherwise we are risking a violation
of locking order and deadlocks.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
diff --git a/fs/namei.c b/fs/namei.c
index 0223c41..5c867dd 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -433,6 +433,8 @@ static int unlazy_walk(struct nameidata *nd, struct dentry *dentry)
goto err_parent;
BUG_ON(nd->inode != parent->d_inode);
} else {
+ if (dentry->d_parent != parent)
+ goto err_parent;
spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED);
if (!__d_rcu_to_refcount(dentry, nd->seq))
goto err_child;
next prev parent reply other threads:[~2011-07-13 1:39 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-07-04 23:09 Linux 3.0-rc6 Linus Torvalds
2011-07-06 15:27 ` Arkadiusz Miśkiewicz
2011-07-11 6:03 ` Al Viro
2011-07-12 23:48 ` ->d_lock FUBAR (was Re: Linux 3.0-rc6) Al Viro
2011-07-13 0:04 ` Linus Torvalds
2011-07-13 0:56 ` Al Viro
2011-07-13 1:39 ` Al Viro [this message]
2011-07-13 2:40 ` Linus Torvalds
2011-07-13 2:59 ` Al Viro
2011-07-13 3:22 ` Al Viro
2011-07-13 3:56 ` Linus Torvalds
2011-07-14 7:21 ` Al Viro
2011-07-15 4:58 ` Al Viro
2011-07-13 1:48 ` Linus Torvalds
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=20110713013936.GL11013@ZenIV.linux.org.uk \
--to=viro@zeniv.linux.org.uk \
--cc=linux-fsdevel@vger.kernel.org \
--cc=npiggin@kernel.dk \
--cc=torvalds@linux-foundation.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: 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.