From patchwork Mon Apr 2 21:12:45 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Frank Sorenson X-Patchwork-Id: 10320399 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id C348360247 for ; Mon, 2 Apr 2018 21:12:48 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A70E8288BF for ; Mon, 2 Apr 2018 21:12:48 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 99C7428921; Mon, 2 Apr 2018 21:12:48 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2B443288BF for ; Mon, 2 Apr 2018 21:12:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753322AbeDBVMr (ORCPT ); Mon, 2 Apr 2018 17:12:47 -0400 Received: from mail-it0-f67.google.com ([209.85.214.67]:54424 "EHLO mail-it0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753253AbeDBVMq (ORCPT ); Mon, 2 Apr 2018 17:12:46 -0400 Received: by mail-it0-f67.google.com with SMTP id h143-v6so20524579ita.4 for ; Mon, 02 Apr 2018 14:12:46 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:to:from:subject:message-id:date:user-agent :mime-version:content-language:content-transfer-encoding; bh=Yhp2iBMtg7Q+XBErk4gBMbEN3ZX/JU+51abdfZ4ZPLc=; b=RgOB9m7phq5ReiCJNlyr/dvBQtOK+L1SJJhHPW4X54PbSdfknKzNg2CmHDI+RyJS6p 1YfNgRfH/juBMX+9ZT9J637Vb3s1/F5f0FPA63xsixE2G3wbNTujyWLSMTojrg/WbafE 9zudZ+avsCkUfZhict35q/FPdwum+Ui9tDP/8ZsjctmROhOThFyDcUcHCM1xe6w93qZm Qk8TlSoM1aFnwtddalUqbFbR7N8+C+vq1zjwLoeOrVJ9dUWrHjd+PeyOYxG7xvKdWjxS sjnb0a7SooAgBSnMgKClMpqgX573iSbf+uNHQc15nDN/2PwO5xPOgaD9u300StUuRqc8 TlDg== X-Gm-Message-State: ALQs6tChREWqQ2e6m5iVTIF6Pa0canw6VIIyrYmebr6GVYNNhI+z/PUu uYsSYieqZ5JCu4WSBbGuojPsgHPYCAc= X-Google-Smtp-Source: AIpwx49yCj/8+JTOn43HbtSZMPMXWgCCYrsnWOzzmC34c2Eb11IZlrAGqxrVhH5OmFV4PzFA/hBlaw== X-Received: by 2002:a24:41ca:: with SMTP id b71-v6mr2596939itd.7.1522703566212; Mon, 02 Apr 2018 14:12:46 -0700 (PDT) Received: from hut.sorensonfamily.com (198-0-247-150-static.hfc.comcastbusiness.net. [198.0.247.150]) by smtp.gmail.com with ESMTPSA id 17sm579330iom.73.2018.04.02.14.12.45 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 02 Apr 2018 14:12:45 -0700 (PDT) To: linux-nfs@vger.kernel.org From: Frank Sorenson Subject: [PATCH] NFS: advance nfs_entry cookie only after decoding completes successfully Message-ID: <6ce3a0df-b9f1-e839-4e55-097f2f3b8c2b@redhat.com> Date: Mon, 2 Apr 2018 16:12:45 -0500 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.5.0 MIME-Version: 1.0 Content-Language: en-US Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Author: Frank Sorenson Date: 2018-04-02 15:56:02 -0500 NFS: advance nfs_entry cookie only after decoding completes successfully In nfs[34]_decode_dirent, the cookie is advanced as soon as it is read, but decoding may still fail later in the function, returning an error. Because the cookie has been advanced, the failing entry is not re-requested from the server, resulting in a missing directory entry. In addition, nfs v3 and v4 read the cookie at different locations in the xdr_stream, so the behavior of the two can be inconsistent. Fix these by reading the cookie into a temporary variable, and only advancing the cookie once the entire entry has been decoded from the xdr_stream successfully. Signed-off-by: Frank Sorenson --- fs/nfs/nfs3xdr.c | 7 +++++-- fs/nfs/nfs4xdr.c | 7 +++++-- 2 files changed, 10 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/nfs3xdr.c b/fs/nfs/nfs3xdr.c index 6cd33bd5da87..09ee36dd8426 100644 --- a/fs/nfs/nfs3xdr.c +++ b/fs/nfs/nfs3xdr.c @@ -1997,6 +1997,7 @@ int nfs3_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, struct nfs_entry old = *entry; __be32 *p; int error; + u64 new_cookie; p = xdr_inline_decode(xdr, 4); if (unlikely(p == NULL)) @@ -2019,8 +2020,7 @@ int nfs3_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, if (unlikely(error)) return error; - entry->prev_cookie = entry->cookie; - error = decode_cookie3(xdr, &entry->cookie); + error = decode_cookie3(xdr, &new_cookie); if (unlikely(error)) return error; @@ -2054,6 +2054,9 @@ int nfs3_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, zero_nfs_fh3(entry->fh); } + entry->prev_cookie = entry->cookie; + entry->cookie = new_cookie; + return 0; out_overflow: diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index 65c9c4175145..1d7119a25c3a 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c @@ -7536,6 +7536,7 @@ int nfs4_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, unsigned int savep; uint32_t bitmap[3] = {0}; uint32_t len; + uint64_t new_cookie; __be32 *p = xdr_inline_decode(xdr, 4); if (unlikely(!p)) goto out_overflow; @@ -7552,8 +7553,7 @@ int nfs4_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, p = xdr_inline_decode(xdr, 12); if (unlikely(!p)) goto out_overflow; - entry->prev_cookie = entry->cookie; - p = xdr_decode_hyper(p, &entry->cookie); + p = xdr_decode_hyper(p, &new_cookie); entry->len = be32_to_cpup(p); p = xdr_inline_decode(xdr, entry->len); @@ -7587,6 +7587,9 @@ int nfs4_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, if (entry->fattr->valid & NFS_ATTR_FATTR_TYPE) entry->d_type = nfs_umode_to_dtype(entry->fattr->mode); + entry->prev_cookie = entry->cookie; + entry->cookie = new_cookie; + return 0; out_overflow: