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 04:17:52 +0100 [thread overview]
Message-ID: <20140418031752.GL18016@ZenIV.linux.org.uk> (raw)
In-Reply-To: <20140418024836.GK18016@ZenIV.linux.org.uk>
On Fri, Apr 18, 2014 at 03:48:37AM +0100, Al Viro wrote:
> 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().
Note that most of the places calling d_is_...() are protected by
the following: if we'd obtained dentry by __lookup_hash() and friends
*after* grabbing ->i_mutex on parent, we are fine - both positive-to-negative
and negative-to-positive are possible only with ->i_mutex held, so it
gives us a barrier.
AFAICS, there are two more tricky places: walk_component() doing
if (!inode)
goto out_path_put;
if (should_follow_link(path->dentry, follow)) {
with unpleasant consequences if the second test gives a false negative,
and similar for mountpoint_last().
Basically, we'd concentrated on RCU races back then, and missed the possibility
of non-RCU-but-without-i_mutex ones. Proposed fix follows:
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
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..8016827 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1542,7 +1542,7 @@ static inline int walk_component(struct nameidata *nd, struct path *path,
inode = path->dentry->d_inode;
}
err = -ENOENT;
- if (!inode)
+ if (!inode || d_is_negative(path->dentry))
goto out_path_put;
if (should_follow_link(path->dentry, follow)) {
@@ -2249,7 +2249,7 @@ mountpoint_last(struct nameidata *nd, struct path *path)
mutex_unlock(&dir->d_inode->i_mutex);
done:
- if (!dentry->d_inode) {
+ if (!dentry->d_inode || d_is_negative(dentry)) {
error = -ENOENT;
dput(dentry);
goto out;
@@ -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 3:17 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
2014-04-18 3:17 ` Al Viro [this message]
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=20140418031752.GL18016@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.