From: Al Viro <viro@ZenIV.linux.org.uk>
To: Lin Ming <minggr@gmail.com>
Cc: David Howells <dhowells@redhat.com>,
linux-fsdevel@vger.kernel.org, Hugh Dickins <hughd@google.com>,
Linus Torvalds <torvalds@linux-foundation.org>
Subject: Re: panic in do_last()
Date: Fri, 18 Apr 2014 03:48:37 +0100 [thread overview]
Message-ID: <20140418024836.GK18016@ZenIV.linux.org.uk> (raw)
In-Reply-To: <20140418023822.GI18016@ZenIV.linux.org.uk>
On Fri, Apr 18, 2014 at 03:38:22AM +0100, Al Viro wrote:
> Aha, so my guess in another posting was correct. OK...
>
> So it's not about RCU case at all - if dentry changes under us
> in lazy mode, we'll simply fail when we get to checking d_seq. It's
> non-lazy case + transition from negative to positive that causes the
> trouble.
>
> Another piece of breakage in there is should_follow_link() directly
> afterwards - there the problem is with false negatives. I.e. we
> see new dentry->d_inode, but not the new dentry->d_flags.
>
> I wonder if the right fix would be simply
> if (!inode || d_is_negative(dentry))
> bailing out unless both updates are seen. Probably cheaper than any
> games with barriers...
Crap... No, it's a bit trickier - we start with clearing all flags,
so if we see the _intermediate_ d_flags and new d_inode, we'll sail
past the check. Which would leave us with correct inode, but might
give us a false negative in should_follow_link().
Hmm... How about the following, then?
diff --git a/fs/dcache.c b/fs/dcache.c
index 40707d8..494a9def 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -1647,8 +1647,7 @@ static void __d_instantiate(struct dentry *dentry, struct inode *inode)
unsigned add_flags = d_flags_for_inode(inode);
spin_lock(&dentry->d_lock);
- dentry->d_flags &= ~DCACHE_ENTRY_TYPE;
- dentry->d_flags |= add_flags;
+ __d_set_type(dentry, add_flags);
if (inode)
hlist_add_head(&dentry->d_alias, &inode->i_dentry);
dentry->d_inode = inode;
diff --git a/fs/namei.c b/fs/namei.c
index c6157c8..7560db7 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -2994,7 +2994,7 @@ retry_lookup:
finish_lookup:
/* we _can_ be in RCU mode here */
error = -ENOENT;
- if (d_is_negative(path->dentry)) {
+ if (!inode || d_is_negative(path->dentry)) {
path_to_nameidata(path, nd);
goto out;
}
next prev parent reply other threads:[~2014-04-18 2:48 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-04-18 1:14 panic in do_last() Lin Ming
2014-04-18 1:57 ` Al Viro
2014-04-18 2:17 ` Al Viro
2014-04-18 2:22 ` Lin Ming
2014-04-18 2:35 ` Lin Ming
2014-04-18 2:42 ` Al Viro
[not found] ` <CAF1ivSbqM2LorrED3MvgKBDxA9sLz_RkOEPwAfvYYmL5C9K0vA@mail.gmail.com>
2014-04-18 2:38 ` Al Viro
2014-04-18 2:48 ` Al Viro [this message]
2014-04-18 3:17 ` Al Viro
2014-04-18 3:40 ` Lin Ming
2014-04-18 15:11 ` Lin Ming
2014-04-22 17:51 ` Lin Ming
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=20140418024836.GK18016@ZenIV.linux.org.uk \
--to=viro@zeniv.linux.org.uk \
--cc=dhowells@redhat.com \
--cc=hughd@google.com \
--cc=linux-fsdevel@vger.kernel.org \
--cc=minggr@gmail.com \
--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.