From patchwork Thu May 7 18:43:43 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Al Viro X-Patchwork-Id: 6360481 Return-Path: X-Original-To: patchwork-linux-fsdevel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 461FB9F373 for ; Thu, 7 May 2015 18:44:22 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 707BC202EB for ; Thu, 7 May 2015 18:44:21 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 8B72B202A1 for ; Thu, 7 May 2015 18:44:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751809AbbEGSnr (ORCPT ); Thu, 7 May 2015 14:43:47 -0400 Received: from zeniv.linux.org.uk ([195.92.253.2]:53024 "EHLO ZenIV.linux.org.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751060AbbEGSnq (ORCPT ); Thu, 7 May 2015 14:43:46 -0400 Received: from viro by ZenIV.linux.org.uk with local (Exim 4.76 #1 (Red Hat Linux)) id 1YqQlr-0003i4-95; Thu, 07 May 2015 18:43:43 +0000 Date: Thu, 7 May 2015 19:43:43 +0100 From: Al Viro To: Steven Rostedt Cc: David Howells , LKML , linux-fsdevel@vger.kernel.org Subject: Re: [PATCH] VFS: Add back check for !inode in walk_component() Message-ID: <20150507184343.GF889@ZenIV.linux.org.uk> References: <20150507125241.4da739ac@gandalf.local.home> <20150507172834.GD889@ZenIV.linux.org.uk> <20150507133935.2d2e3181@gandalf.local.home> <20150507181335.GE889@ZenIV.linux.org.uk> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20150507181335.GE889@ZenIV.linux.org.uk> User-Agent: Mutt/1.5.21 (2010-09-15) Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP On Thu, May 07, 2015 at 07:13:35PM +0100, Al Viro wrote: > On Thu, May 07, 2015 at 01:39:35PM -0400, Steven Rostedt wrote: > > I had them printed in my previous traces. The flags were 0x200088, and > > they were 0 just before the call. > > Not dentry->d_flags, nd->flags. Most interesting part is bit 6 in those > (LOOKUP_RCU, 0x40). > > As for creation... I think I see what might be going on: > > A: finds a negative dentry, picks NULL ->d_inode from it and whatever > ->d_seq it had. > B: d_instantiate(): sets ->d_inode non-NULL, ->d_flags accordingly and > bumps ->d_seq. > A: fetches ->d_flags, sees non-negative, assumes ->d_inode is non-NULL. > > In reality, the last assumption should've been "->d_inode is non-NULL or > we have a stale ->d_seq and will end up discarding that fscker anyway". > > Hmm... Smells like we ought to [snip] Actually, could you try the following on top of -rc2? --- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/fs/namei.c b/fs/namei.c index 4a8d998b..421e597 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -1415,6 +1415,7 @@ static int lookup_fast(struct nameidata *nd, */ if (nd->flags & LOOKUP_RCU) { unsigned seq; + bool negative; dentry = __d_lookup_rcu(parent, &nd->last, &seq); if (!dentry) goto unlazy; @@ -1424,8 +1425,11 @@ static int lookup_fast(struct nameidata *nd, * the dentry name information from lookup. */ *inode = dentry->d_inode; + negative = d_is_negative(dentry); if (read_seqcount_retry(&dentry->d_seq, seq)) return -ECHILD; + if (negative) + return -ENOENT; /* * This sequence count validates that the parent had no @@ -1472,9 +1476,13 @@ unlazy: goto need_lookup; } - path->mnt = mnt; - path->dentry = dentry; - err = follow_managed(path, nd->flags); + if (unlikely(d_is_negative(dentry))) { + err = -ENOENT; + } else { + path->mnt = mnt; + path->dentry = dentry; + err = follow_managed(path, nd->flags); + } if (unlikely(err < 0)) { path_put_conditional(path, nd); return err; @@ -1583,10 +1591,10 @@ static inline int walk_component(struct nameidata *nd, struct path *path, goto out_err; inode = path->dentry->d_inode; + err = -ENOENT; + if (d_is_negative(path->dentry)) + goto out_path_put; } - err = -ENOENT; - if (d_is_negative(path->dentry)) - goto out_path_put; if (should_follow_link(path->dentry, follow)) { if (nd->flags & LOOKUP_RCU) { @@ -3036,14 +3044,13 @@ retry_lookup: BUG_ON(nd->flags & LOOKUP_RCU); inode = path->dentry->d_inode; -finish_lookup: - /* we _can_ be in RCU mode here */ error = -ENOENT; if (d_is_negative(path->dentry)) { path_to_nameidata(path, nd); goto out; } - +finish_lookup: + /* we _can_ be in RCU mode here */ if (should_follow_link(path->dentry, !symlink_ok)) { if (nd->flags & LOOKUP_RCU) { if (unlikely(nd->path.mnt != path->mnt ||