From patchwork Fri Nov 3 12:00:16 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Trond Myklebust X-Patchwork-Id: 10039923 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 269BF602DA for ; Fri, 3 Nov 2017 12:00:35 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 09D73287D0 for ; Fri, 3 Nov 2017 12:00:35 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id F2EE3295BA; Fri, 3 Nov 2017 12:00:34 +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.3 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI, RCVD_IN_SORBS_SPAM, T_DKIM_INVALID 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 8297B289C5 for ; Fri, 3 Nov 2017 12:00:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756156AbdKCMAd (ORCPT ); Fri, 3 Nov 2017 08:00:33 -0400 Received: from mail-io0-f196.google.com ([209.85.223.196]:44346 "EHLO mail-io0-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756154AbdKCMAb (ORCPT ); Fri, 3 Nov 2017 08:00:31 -0400 Received: by mail-io0-f196.google.com with SMTP id m16so5753229iod.1 for ; Fri, 03 Nov 2017 05:00:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=Vhvmjc1xNr7/mWV+2p7OreWS+0G1nzK0uv9VOFHv1rg=; b=TdFtPIxuLIQIvC7bCcbRAtEc3K9COs2cR5iS4Qs1It2guLTko/djFBeFBclhf9EV2v MJBlvCar7gNyBYVmDXRAvLeD/Yqb+wTJo8a88RdTLim8ceZWA5wBWqsZOlXaoNWKInsG yyRC0CKlSaaM5mxmB0EB+QEnjVboKRpU+DZxAPCOmrBcGQzNT0202iUHQXhU6Rmf+1tN 7/lEU3BRT3ceI3Fcq5/sVN6hADXmYi+szbBBnxK7k/xZmSWD39LjEcRZkk+6TtXjt5JL lMvFoVAAhzlfMIh9tslWZilF9mzHAvRo3kBXKI7cDniXbULHIvaw/1Zb5Vi/ipR/6Dqm nQMQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=Vhvmjc1xNr7/mWV+2p7OreWS+0G1nzK0uv9VOFHv1rg=; b=o05JODonEcWb8UwKwNwTGFzu7MkQmxdKRGH+720jtf922bKSpP/eMzudzytlKdjDim QaxVoYzwc8zrxdsPgLzOLDsdZH6ER6LLIc6SQ/YFlKwKwxQW6/qaBS5/UjMzmVxUCU7E jJ+qaT9B1JjJ3gIjkQy4/vCFaYc5R8XMoqrYitjnbSwc62AY5Sr1Uheh9xOmHYEEAnkD e0xl8pWbSPRKDstBiz3JiJy9qA/1u3F2W5CKnZ5G6DKcOVG67ThxspaiujY3eRZJWVLV j0r7OSt8TvZWfB+CpCN5fqBd8V/nJwDdnCg2rrvXQBcEevIe0FZPu26Sqo31LPJNdrzw nC0w== X-Gm-Message-State: AMCzsaXKhzHzg0e2jtuSgVOwEhGDpG+OPP7MRAfH86HFOdTy9chzaebK LQD+Sf/eFqTJrDvUdKUH/w== X-Google-Smtp-Source: ABhQp+S/FDjZyYa4soSvOldQJ5fh1jQZ/xuX+ld04647sw/ocu6jvqYj5vmsN4Cl5gsQMFNkUan+5g== X-Received: by 10.107.181.138 with SMTP id e132mr8333836iof.125.1509710430906; Fri, 03 Nov 2017 05:00:30 -0700 (PDT) Received: from localhost.localdomain (c-68-49-162-121.hsd1.mi.comcast.net. [68.49.162.121]) by smtp.gmail.com with ESMTPSA id k18sm2620923ioc.75.2017.11.03.05.00.29 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 03 Nov 2017 05:00:30 -0700 (PDT) From: Trond Myklebust To: bfields@fieldses.org Cc: linux-nfs@vger.kernel.org Subject: [PATCH v2 7/7] nfsd: Fix races with check_stateid_generation() Date: Fri, 3 Nov 2017 08:00:16 -0400 Message-Id: <20171103120016.6200-8-trond.myklebust@primarydata.com> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20171103120016.6200-7-trond.myklebust@primarydata.com> References: <20171103120016.6200-1-trond.myklebust@primarydata.com> <20171103120016.6200-2-trond.myklebust@primarydata.com> <20171103120016.6200-3-trond.myklebust@primarydata.com> <20171103120016.6200-4-trond.myklebust@primarydata.com> <20171103120016.6200-5-trond.myklebust@primarydata.com> <20171103120016.6200-6-trond.myklebust@primarydata.com> <20171103120016.6200-7-trond.myklebust@primarydata.com> MIME-Version: 1.0 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 The various functions that call check_stateid_generation() in order to compare a client-supplied stateid with the nfs4_stid state, usually need to atomically check for closed state. Those that perform the check after locking the st_mutex using nfsd4_lock_ol_stateid() should now be OK, but we do want to fix up the others. Signed-off-by: Trond Myklebust --- fs/nfsd/nfs4state.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index cbd6a10ddda2..6f552ca62415 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -4849,6 +4849,18 @@ static __be32 check_stateid_generation(stateid_t *in, stateid_t *ref, bool has_s return nfserr_old_stateid; } +static __be32 nfsd4_stid_check_stateid_generation(stateid_t *in, struct nfs4_stid *s, bool has_session) +{ + __be32 ret; + + spin_lock(&s->sc_lock); + ret = nfsd4_verify_open_stid(s); + if (ret == nfs_ok) + ret = check_stateid_generation(in, &s->sc_stateid, has_session); + spin_unlock(&s->sc_lock); + return ret; +} + static __be32 nfsd4_check_openowner_confirmed(struct nfs4_ol_stateid *ols) { if (ols->st_stateowner->so_is_open_owner && @@ -4877,7 +4889,7 @@ static __be32 nfsd4_validate_stateid(struct nfs4_client *cl, stateid_t *stateid) s = find_stateid_locked(cl, stateid); if (!s) goto out_unlock; - status = check_stateid_generation(stateid, &s->sc_stateid, 1); + status = nfsd4_stid_check_stateid_generation(stateid, s, 1); if (status) goto out_unlock; switch (s->sc_type) { @@ -5022,7 +5034,7 @@ nfs4_preprocess_stateid_op(struct svc_rqst *rqstp, &s, nn); if (status) return status; - status = check_stateid_generation(stateid, &s->sc_stateid, + status = nfsd4_stid_check_stateid_generation(stateid, s, nfsd4_has_session(cstate)); if (status) goto out; @@ -5115,6 +5127,7 @@ nfsd4_free_stateid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, s = find_stateid_locked(cl, stateid); if (!s) goto out_unlock; + spin_lock(&s->sc_lock); switch (s->sc_type) { case NFS4_DELEG_STID: ret = nfserr_locks_held; @@ -5126,11 +5139,13 @@ nfsd4_free_stateid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, ret = nfserr_locks_held; break; case NFS4_LOCK_STID: + spin_unlock(&s->sc_lock); atomic_inc(&s->sc_count); spin_unlock(&cl->cl_lock); ret = nfsd4_free_lock_stateid(stateid, s); goto out; case NFS4_REVOKED_DELEG_STID: + spin_unlock(&s->sc_lock); dp = delegstateid(s); list_del_init(&dp->dl_recall_lru); spin_unlock(&cl->cl_lock); @@ -5139,6 +5154,7 @@ nfsd4_free_stateid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, goto out; /* Default falls through and returns nfserr_bad_stateid */ } + spin_unlock(&s->sc_lock); out_unlock: spin_unlock(&cl->cl_lock); out: @@ -5418,7 +5434,7 @@ nfsd4_delegreturn(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, if (status) goto out; dp = delegstateid(s); - status = check_stateid_generation(stateid, &dp->dl_stid.sc_stateid, nfsd4_has_session(cstate)); + status = nfsd4_stid_check_stateid_generation(stateid, &dp->dl_stid, nfsd4_has_session(cstate)); if (status) goto put_stateid;