From patchwork Mon Jul 14 05:14:05 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: NeilBrown X-Patchwork-Id: 4542541 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 21ECD9F295 for ; Mon, 14 Jul 2014 05:14:20 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 81C6020149 for ; Mon, 14 Jul 2014 05:14:19 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id B6B8A2014A for ; Mon, 14 Jul 2014 05:14:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752518AbaGNFOQ (ORCPT ); Mon, 14 Jul 2014 01:14:16 -0400 Received: from cantor2.suse.de ([195.135.220.15]:54675 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752321AbaGNFOQ (ORCPT ); Mon, 14 Jul 2014 01:14:16 -0400 Received: from relay1.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 111DAAC01; Mon, 14 Jul 2014 05:14:14 +0000 (UTC) Date: Mon, 14 Jul 2014 15:14:05 +1000 From: NeilBrown To: Trond Myklebust , Jeff Layton , Alexander Viro Cc: NFS Subject: [PATCH] NFS: nfs4_lookup_revalidate need to report STALE inodes. Message-ID: <20140714151405.2fa06dd7@notabene.brown> X-Mailer: Claws Mail 3.9.2 (GTK+ 2.24.22; x86_64-suse-linux-gnu) 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=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, T_TVD_MIME_EPI, 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 If an 'open' of a file in an NFSv4 filesystem finds that the dentry is in cache, but the inode is stale (on the server), the dentry will not be re-validated immediately and may cause ESTALE to be returned to user-space. For a non-create 'open', do_last() calls lookup_fast() and on success will eventually call may_open() which calls into nfs_permission(). If nfs_permission() makes the ACCESS call to the server it will get NFS4ERR_STALE, resulting in ESTALE from may_open() and thence from do_last(). The retry-on-ESTALE in filename_lookup() will repeat exactly the same process because nothing in this path will invalidate the dentry due to the inode being stale, so the ESTALE will be returned. lookup_fast() calls ->d_revalidate(), but for an OPEN on an NFSv4 filesystem, that will succeed for regular files: /* Let f_op->open() actually open (and revalidate) the file */ Unfortunately in the case of a STALE inode, f_op->open() never gets called. If we teach nfs4_lookup_revalidate() to report a failure on NFS_STALE() inodes, then the dentry will be invalidated and a full lookup will be attempted. The ESTALE errors go away. While I think this fix is correct, I'm not convinced that it is sufficient, particularly if lookupcache=none. The current code will fail an "open" is nfs_permission() fails, without having performed a LOOKUP. i.e. it will use the cache. nfs_lookup_revalidate will force a lookup before the permission check if NFS_MOUNT_LOOKUP_CACHE_NONE, but nfs4_lookup_revalidate will not. Signed-off-by: NeilBrown Acked-by: Jeff Layton diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 4a3d4ef76127..4f7414afca27 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -1563,6 +1563,8 @@ static int nfs4_lookup_revalidate(struct dentry *dentry, unsigned int flags) /* We cannot do exclusive creation on a positive dentry */ if (flags & LOOKUP_EXCL) goto no_open_dput; + if (NFS_STALE(inode)) + goto no_open_dput; /* Let f_op->open() actually open (and revalidate) the file */ ret = 1;