From patchwork Mon Aug 4 06:24:00 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: NeilBrown X-Patchwork-Id: 4667161 Return-Path: X-Original-To: patchwork-linux-nfs@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id B2C339F38C for ; Mon, 4 Aug 2014 06:25:20 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id CE7112021F for ; Mon, 4 Aug 2014 06:25:19 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 617C62021A for ; Mon, 4 Aug 2014 06:25:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751307AbaHDGZQ (ORCPT ); Mon, 4 Aug 2014 02:25:16 -0400 Received: from cantor2.suse.de ([195.135.220.15]:52682 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751053AbaHDGZQ (ORCPT ); Mon, 4 Aug 2014 02:25:16 -0400 Received: from relay1.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 4AE65AAF3; Mon, 4 Aug 2014 06:25:14 +0000 (UTC) From: NeilBrown To: Trond Myklebust Date: Mon, 04 Aug 2014 16:24:00 +1000 Subject: [PATCH 1/2] NFS: fix two problems in lookup_revalidate in RCU-walk Cc: linux-nfs@vger.kernel.org, kbuild test robot Message-ID: <20140804062400.7621.10041.stgit@notabene.brown> In-Reply-To: <20140804062225.7621.70050.stgit@notabene.brown> References: <20140804062225.7621.70050.stgit@notabene.brown> User-Agent: StGit/0.16 MIME-Version: 1.0 Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org X-Spam-Status: No, score=-7.6 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, 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 1/ rcu_dereference isn't correct: that field isn't RCU protected. It could potentially change at any time so ACCESS_ONCE might be justified. changes to ->d_parent are protected by ->d_seq. However that isn't always checked after ->d_revalidate is called, so it is safest to keep the double-check that ->d_parent hasn't changed at the end of these functions. 2/ in nfs4_lookup_revalidate, "->d_parent" was forgotten. So 'parent' was not the parent of 'dentry'. This fails safe is the context is that dentry->d_inode is NULL, and the result of parent->d_inode being NULL is that ECHILD is returned, which is always safe. Reported-by: kbuild test robot Signed-off-by: NeilBrown --- fs/nfs/dir.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-nfs" 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/nfs/dir.c b/fs/nfs/dir.c index e754d205ea54..0295f78f2976 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -1102,7 +1102,7 @@ static int nfs_lookup_revalidate(struct dentry *dentry, unsigned int flags) int error; if (flags & LOOKUP_RCU) { - parent = rcu_dereference(dentry->d_parent); + parent = ACCESS_ONCE(dentry->d_parent); dir = ACCESS_ONCE(parent->d_inode); if (!dir) return -ECHILD; @@ -1184,7 +1184,7 @@ out_set_verifier: nfs_advise_use_readdirplus(dir); out_valid_noent: if (flags & LOOKUP_RCU) { - if (parent != rcu_dereference(dentry->d_parent)) + if (parent != ACCESS_ONCE(dentry->d_parent)) return -ECHILD; } else dput(parent); @@ -1585,7 +1585,7 @@ static int nfs4_lookup_revalidate(struct dentry *dentry, unsigned int flags) struct inode *dir; if (flags & LOOKUP_RCU) { - parent = rcu_dereference(dentry); + parent = ACCESS_ONCE(dentry->d_parent); dir = ACCESS_ONCE(parent->d_inode); if (!dir) return -ECHILD; @@ -1599,7 +1599,7 @@ static int nfs4_lookup_revalidate(struct dentry *dentry, unsigned int flags) ret = -ECHILD; if (!(flags & LOOKUP_RCU)) dput(parent); - else if (parent != rcu_dereference(dentry)) + else if (parent != ACCESS_ONCE(dentry->d_parent)) return -ECHILD; goto out; }