From patchwork Mon Nov 6 20:28:03 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Trond Myklebust X-Patchwork-Id: 10044405 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 04A546032D for ; Mon, 6 Nov 2017 20:28:24 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id EBF6029FDB for ; Mon, 6 Nov 2017 20:28:23 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E0D8429FE3; Mon, 6 Nov 2017 20:28:23 +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 D2AF529FDE for ; Mon, 6 Nov 2017 20:28:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932813AbdKFU2V (ORCPT ); Mon, 6 Nov 2017 15:28:21 -0500 Received: from mail-it0-f67.google.com ([209.85.214.67]:53727 "EHLO mail-it0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932830AbdKFU2U (ORCPT ); Mon, 6 Nov 2017 15:28:20 -0500 Received: by mail-it0-f67.google.com with SMTP id n195so6600212itg.2 for ; Mon, 06 Nov 2017 12:28:20 -0800 (PST) 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=T/tVxfXW9M4UIegNC1MfkmDSoFfPb3sxbV9S9v0EqFk=; b=XlANaAIitKF9ChHCp2Q5lUr60AEbckZjEEZ15tiFV5ROcPZ3aALk+bSJ4QbmmHvc1c RtsR+F1Y08h5JX0wIpYZjbRp1IgjNppjFoAU79gk+gTukEL6lQu/Z8XiNCwzNx3dBKYe uyA0w2veAgWmtRfd2srOLK2RShnxksUCbYSc+iksOmIPQrpd1GSFTf7pZV3zTrcQhMek VHC3a5iOHauI7uOEV3/0YyjLYtwoClpfaZAezkNhiuBzz6dKZVMcTsbLnwU/UV9ykKiR neIcE+uKarS4+QeHllbmftn/UKt9zGkz0vXlS8NrzAggg5m1HAYWh5HShd5lt0iDyxY7 ItNw== 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=T/tVxfXW9M4UIegNC1MfkmDSoFfPb3sxbV9S9v0EqFk=; b=MdBc0stkuJ3z/HDUWqB136zRynNLLSVvmaQTHMew4QpXyOnHpjirJSFv3JC+3K1kia kAppX+2HgtVRqXZFXU6ylor/5ZJRpgwVG0ASZqlr0jg4Ip3OSbuU8ce0hwS3ZiO1knDp npZ4HD3L8279vfwxZ7ItNAwNLWIBy1/4pIsIrv1OlTQdM/pNQbdF8DWiYuxDxIz94tRW 4gkX6du6beeCkJgzK7UaqYc/DC0r4Nh7nVX2jqR3BkRgv5n8q9m9Vg6baGwyMJkEShwA SmyY4FPxv020sKavzpTNGQZ+Ox3c/BnTQRCGBjmVGWCGP0WyqneXf7unzaVv+hA61A73 tLNA== X-Gm-Message-State: AJaThX4gnPy53i8UxLG+ZD5nE39cs31eNKl8ByPzobnvDwP8T+A7HnWD Gm9HgjbjBVIiqk4DUw1V4g== X-Google-Smtp-Source: ABhQp+T61Xyr78u+GQtJJSwolKfCA1StL3syMwZCH8lIkL49SPxggCVkl/A315ggtECrZZ3dqzrGUQ== X-Received: by 10.36.173.72 with SMTP id a8mr10404693itj.89.1510000099688; Mon, 06 Nov 2017 12:28:19 -0800 (PST) Received: from localhost.localdomain (c-68-49-162-121.hsd1.mi.comcast.net. [68.49.162.121]) by smtp.gmail.com with ESMTPSA id v5sm5897373iog.78.2017.11.06.12.28.18 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Mon, 06 Nov 2017 12:28:18 -0800 (PST) From: Trond Myklebust To: Benjamin Coddington , Anna Schumaker Cc: linux-nfs@vger.kernel.org Subject: [PATCH v8 03/11] NFSv4: Fix open create exclusive when the server reboots Date: Mon, 6 Nov 2017 15:28:03 -0500 Message-Id: <20171106202811.70202-4-trond.myklebust@primarydata.com> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20171106202811.70202-3-trond.myklebust@primarydata.com> References: <20171106202811.70202-1-trond.myklebust@primarydata.com> <20171106202811.70202-2-trond.myklebust@primarydata.com> <20171106202811.70202-3-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 If the server that does not implement NFSv4.1 persistent session semantics reboots while we are performing an exclusive create, then the return value of NFS4ERR_DELAY when we replay the open during the grace period causes us to lose the verifier. When the grace period expires, and we present a new verifier, the server will then correctly reply NFS4ERR_EXIST. This commit ensures that we always present the same verifier when replaying the OPEN. Reported-by: Tigran Mkrtchyan Signed-off-by: Trond Myklebust --- fs/nfs/nfs4proc.c | 41 ++++++++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index f44eef8c92fe..3309ee35e73c 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -1088,6 +1088,12 @@ struct nfs4_opendata { int rpc_status; }; +struct nfs4_open_createattrs { + struct nfs4_label *label; + struct iattr *sattr; + const __u32 verf[2]; +}; + static bool nfs4_clear_cap_atomic_open_v1(struct nfs_server *server, int err, struct nfs4_exception *exception) { @@ -1157,8 +1163,7 @@ static void nfs4_init_opendata_res(struct nfs4_opendata *p) static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry, struct nfs4_state_owner *sp, fmode_t fmode, int flags, - const struct iattr *attrs, - struct nfs4_label *label, + const struct nfs4_open_createattrs *c, enum open_claim_type4 claim, gfp_t gfp_mask) { @@ -1166,6 +1171,7 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry, struct inode *dir = d_inode(parent); struct nfs_server *server = NFS_SERVER(dir); struct nfs_seqid *(*alloc_seqid)(struct nfs_seqid_counter *, gfp_t); + struct nfs4_label *label = (c != NULL) ? c->label : NULL; struct nfs4_opendata *p; p = kzalloc(sizeof(*p), gfp_mask); @@ -1231,15 +1237,11 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry, case NFS4_OPEN_CLAIM_DELEG_PREV_FH: p->o_arg.fh = NFS_FH(d_inode(dentry)); } - if (attrs != NULL && attrs->ia_valid != 0) { - __u32 verf[2]; - + if (c != NULL && c->sattr != NULL && c->sattr->ia_valid != 0) { p->o_arg.u.attrs = &p->attrs; - memcpy(&p->attrs, attrs, sizeof(p->attrs)); + memcpy(&p->attrs, c->sattr, sizeof(p->attrs)); - verf[0] = jiffies; - verf[1] = current->pid; - memcpy(p->o_arg.u.verifier.data, verf, + memcpy(p->o_arg.u.verifier.data, c->verf, sizeof(p->o_arg.u.verifier.data)); } p->c_arg.fh = &p->o_res.fh; @@ -1892,7 +1894,7 @@ static struct nfs4_opendata *nfs4_open_recoverdata_alloc(struct nfs_open_context struct nfs4_opendata *opendata; opendata = nfs4_opendata_alloc(ctx->dentry, state->owner, 0, 0, - NULL, NULL, claim, GFP_NOFS); + NULL, claim, GFP_NOFS); if (opendata == NULL) return ERR_PTR(-ENOMEM); opendata->state = state; @@ -2823,8 +2825,7 @@ static int _nfs4_open_and_get_state(struct nfs4_opendata *opendata, static int _nfs4_do_open(struct inode *dir, struct nfs_open_context *ctx, int flags, - struct iattr *sattr, - struct nfs4_label *label, + const struct nfs4_open_createattrs *c, int *opened) { struct nfs4_state_owner *sp; @@ -2836,6 +2837,8 @@ static int _nfs4_do_open(struct inode *dir, struct nfs4_threshold **ctx_th = &ctx->mdsthreshold; fmode_t fmode = ctx->mode & (FMODE_READ|FMODE_WRITE|FMODE_EXEC); enum open_claim_type4 claim = NFS4_OPEN_CLAIM_NULL; + struct iattr *sattr = c->sattr; + struct nfs4_label *label = c->label; struct nfs4_label *olabel = NULL; int status; @@ -2854,8 +2857,8 @@ static int _nfs4_do_open(struct inode *dir, status = -ENOMEM; if (d_really_is_positive(dentry)) claim = NFS4_OPEN_CLAIM_FH; - opendata = nfs4_opendata_alloc(dentry, sp, fmode, flags, sattr, - label, claim, GFP_KERNEL); + opendata = nfs4_opendata_alloc(dentry, sp, fmode, flags, + c, claim, GFP_KERNEL); if (opendata == NULL) goto err_put_state_owner; @@ -2936,10 +2939,18 @@ static struct nfs4_state *nfs4_do_open(struct inode *dir, struct nfs_server *server = NFS_SERVER(dir); struct nfs4_exception exception = { }; struct nfs4_state *res; + struct nfs4_open_createattrs c = { + .label = label, + .sattr = sattr, + .verf = { + [0] = (__u32)jiffies, + [1] = (__u32)current->pid, + }, + }; int status; do { - status = _nfs4_do_open(dir, ctx, flags, sattr, label, opened); + status = _nfs4_do_open(dir, ctx, flags, &c, opened); res = ctx->state; trace_nfs4_open_file(ctx, flags, status); if (status == 0)