From patchwork Fri Feb 17 17:32:09 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Trond Myklebust X-Patchwork-Id: 9580437 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 D28D36042F for ; Fri, 17 Feb 2017 17:32:16 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C2F20286B0 for ; Fri, 17 Feb 2017 17:32:16 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B43FB28758; Fri, 17 Feb 2017 17:32:16 +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 EDF25286B0 for ; Fri, 17 Feb 2017 17:32:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S934203AbdBQRcP (ORCPT ); Fri, 17 Feb 2017 12:32:15 -0500 Received: from mail-oi0-f67.google.com ([209.85.218.67]:33525 "EHLO mail-oi0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S934360AbdBQRcO (ORCPT ); Fri, 17 Feb 2017 12:32:14 -0500 Received: by mail-oi0-f67.google.com with SMTP id s131so2307620oie.0 for ; Fri, 17 Feb 2017 09:32:14 -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; bh=Hlh394eP4URg8/lOF9vy+KDrnQQD9QxFvz1xTsHkGRU=; b=eDbng/et1vdKXI+LXH0p+2qT/GfcydB0EBajrbIycybvX7iO7ADYO3OuDfXLYkoPsn NDH69tvA4P0JSL0NsXFxoYyDttRRkrqG7I0KQxLD0E6q1aevof2G5e+NnBlCMvgB1TqM +3P/4g6s5dAVxBmGE37rQUyp3IeVuylXRoc2KXPRA5eqgvJj+shEVZkpHIMbRWDWbvE5 TukpZ3I3wevw2fooOvCSKvCYJfZ/qiBJ2Lx/uMNAtR+G42q8YIK1zPS7eREOe6piU+bl V0uOXHTb4HPHlgz2nPbMuklKnLFMgWEV5fMv6cla22hSo1Jq2sCU1skLMDZyGkJ5aVYw 428w== 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; bh=Hlh394eP4URg8/lOF9vy+KDrnQQD9QxFvz1xTsHkGRU=; b=mP/Ht0i8lvwWj6zirpZkWGLLlOuT4OPhn8o9HiK53RuLoByrix4id1sAnnYl4epyi0 XVeJssi5/WtcEBkN39qKTv3zv4R/n/8XHz3B59e/0/XAxVY1daU80yYKVvNuL+Lk8/oX MhrbLG3zaCPv4I7Uq40FXNbcgJ3ZrGfZ8FWJNZ/qF3+RPVEIlXyElDN6Kwc/EhiWQ1ve uUbAqc2vmBjMrOQI0zIzLc2ROFDdG8hmQV5JL0emogt51fyXBgryUiZz27qJK2yxzjG1 zvAqQy0x1Gw+EVVZG9g4OM2MwpxU4wA8VFpuRXIENrVEV071P4P3TmCRf9eg+0qbRErj CO3w== X-Gm-Message-State: AMke39nzSHsviDXLhSOCrL1+YLtowv+apgwO1PS3ybzvgLm5KGWgSWX+KBmn+cvgZXENbw== X-Received: by 10.107.174.7 with SMTP id x7mr7755720ioe.35.1487352733373; Fri, 17 Feb 2017 09:32:13 -0800 (PST) Received: from localhost.localdomain ([50.124.63.84]) by smtp.gmail.com with ESMTPSA id e126sm817807itb.18.2017.02.17.09.32.11 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 17 Feb 2017 09:32:12 -0800 (PST) From: Trond Myklebust To: Olga Kornievskaia Cc: linux-nfs@vger.kernel.org Subject: [PATCH v2] NFSv4: Fix reboot recovery in copy offload Date: Fri, 17 Feb 2017 12:32:09 -0500 Message-Id: <20170217173209.17502-1-trond.myklebust@primarydata.com> X-Mailer: git-send-email 2.9.3 In-Reply-To: References: 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 Copy offload code needs to be hooked into the code for handling NFS4ERR_BAD_STATEID by ensuring that we set the "stateid" field in struct nfs4_exception. Reported-by: Olga Kornievskaia Fixes: 2e72448b07dc3 ("NFS: Add COPY nfs operation") Signed-off-by: Trond Myklebust --- fs/nfs/nfs42proc.c | 67 +++++++++++++++++++++++++++++++++--------------------- 1 file changed, 41 insertions(+), 26 deletions(-) diff --git a/fs/nfs/nfs42proc.c b/fs/nfs/nfs42proc.c index d12ff9385f49..1f8bfffc9f04 100644 --- a/fs/nfs/nfs42proc.c +++ b/fs/nfs/nfs42proc.c @@ -128,20 +128,13 @@ int nfs42_proc_deallocate(struct file *filep, loff_t offset, loff_t len) return err; } -static ssize_t _nfs42_proc_copy(struct file *src, loff_t pos_src, +static ssize_t _nfs42_proc_copy(struct file *src, struct nfs_lock_context *src_lock, - struct file *dst, loff_t pos_dst, + struct file *dst, struct nfs_lock_context *dst_lock, - size_t count) + struct nfs42_copy_args *args, + struct nfs42_copy_res *res) { - struct nfs42_copy_args args = { - .src_fh = NFS_FH(file_inode(src)), - .src_pos = pos_src, - .dst_fh = NFS_FH(file_inode(dst)), - .dst_pos = pos_dst, - .count = count, - }; - struct nfs42_copy_res res; struct rpc_message msg = { .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_COPY], .rpc_argp = &args, @@ -149,9 +142,12 @@ static ssize_t _nfs42_proc_copy(struct file *src, loff_t pos_src, }; struct inode *dst_inode = file_inode(dst); struct nfs_server *server = NFS_SERVER(dst_inode); + loff_t pos_src = args->src_pos; + loff_t pos_dst = args->dst_pos; + size_t count = args->count; int status; - status = nfs4_set_rw_stateid(&args.src_stateid, src_lock->open_context, + status = nfs4_set_rw_stateid(&args->src_stateid, src_lock->open_context, src_lock, FMODE_READ); if (status) return status; @@ -161,7 +157,7 @@ static ssize_t _nfs42_proc_copy(struct file *src, loff_t pos_src, if (status) return status; - status = nfs4_set_rw_stateid(&args.dst_stateid, dst_lock->open_context, + status = nfs4_set_rw_stateid(&args->dst_stateid, dst_lock->open_context, dst_lock, FMODE_WRITE); if (status) return status; @@ -171,22 +167,22 @@ static ssize_t _nfs42_proc_copy(struct file *src, loff_t pos_src, return status; status = nfs4_call_sync(server->client, server, &msg, - &args.seq_args, &res.seq_res, 0); + &args->seq_args, &res->seq_res, 0); if (status == -ENOTSUPP) server->caps &= ~NFS_CAP_COPY; if (status) return status; - if (res.write_res.verifier.committed != NFS_FILE_SYNC) { - status = nfs_commit_file(dst, &res.write_res.verifier.verifier); + if (res->write_res.verifier.committed != NFS_FILE_SYNC) { + status = nfs_commit_file(dst, &res->write_res.verifier.verifier); if (status) return status; } truncate_pagecache_range(dst_inode, pos_dst, - pos_dst + res.write_res.count); + pos_dst + res->write_res.count); - return res.write_res.count; + return res->write_res.count; } ssize_t nfs42_proc_copy(struct file *src, loff_t pos_src, @@ -196,8 +192,22 @@ ssize_t nfs42_proc_copy(struct file *src, loff_t pos_src, struct nfs_server *server = NFS_SERVER(file_inode(dst)); struct nfs_lock_context *src_lock; struct nfs_lock_context *dst_lock; - struct nfs4_exception src_exception = { }; - struct nfs4_exception dst_exception = { }; + struct nfs42_copy_args args = { + .src_fh = NFS_FH(file_inode(src)), + .src_pos = pos_src, + .dst_fh = NFS_FH(file_inode(dst)), + .dst_pos = pos_dst, + .count = count, + }; + struct nfs42_copy_res res; + struct nfs4_exception src_exception = { + .inode = file_inode(src), + .stateid = &args.src_stateid, + }; + struct nfs4_exception dst_exception = { + .inode = file_inode(dst), + .stateid = &args.dst_stateid, + }; ssize_t err, err2; if (!nfs_server_capable(file_inode(dst), NFS_CAP_COPY)) @@ -207,7 +217,6 @@ ssize_t nfs42_proc_copy(struct file *src, loff_t pos_src, if (IS_ERR(src_lock)) return PTR_ERR(src_lock); - src_exception.inode = file_inode(src); src_exception.state = src_lock->open_context->state; dst_lock = nfs_get_lock_context(nfs_file_open_context(dst)); @@ -216,25 +225,31 @@ ssize_t nfs42_proc_copy(struct file *src, loff_t pos_src, goto out_put_src_lock; } - dst_exception.inode = file_inode(dst); dst_exception.state = dst_lock->open_context->state; - do { + for (;;) { inode_lock(file_inode(dst)); - err = _nfs42_proc_copy(src, pos_src, src_lock, - dst, pos_dst, dst_lock, count); + err = _nfs42_proc_copy(src, src_lock, + dst, dst_lock, + &args, &res); inode_unlock(file_inode(dst)); + if (err >= 0) + break; if (err == -ENOTSUPP) { err = -EOPNOTSUPP; break; } err2 = nfs4_handle_exception(server, err, &src_exception); + if (src_exception.retry) + continue; err = nfs4_handle_exception(server, err, &dst_exception); if (!err) err = err2; - } while (src_exception.retry || dst_exception.retry); + if (!dst_exception.retry) + break; + } nfs_put_lock_context(dst_lock); out_put_src_lock: