From patchwork Thu Sep 28 17:28:31 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Olga Kornievskaia X-Patchwork-Id: 9976455 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 55AF56034B for ; Thu, 28 Sep 2017 17:28:48 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3D979296C1 for ; Thu, 28 Sep 2017 17:28:48 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 32BF5296CE; Thu, 28 Sep 2017 17:28: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 55952296C1 for ; Thu, 28 Sep 2017 17:28:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752235AbdI1R2o (ORCPT ); Thu, 28 Sep 2017 13:28:44 -0400 Received: from mx142.netapp.com ([216.240.21.19]:46321 "EHLO mx142.netapp.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752177AbdI1R2n (ORCPT ); Thu, 28 Sep 2017 13:28:43 -0400 X-IronPort-AV: E=Sophos;i="5.42,450,1500966000"; d="scan'208";a="214025450" Received: from vmwexchts04-prd.hq.netapp.com ([10.122.105.32]) by mx142-out.netapp.com with ESMTP; 28 Sep 2017 10:01:41 -0700 Received: from smtp1.corp.netapp.com (10.122.76.128) by VMWEXCHTS04-PRD.hq.netapp.com (10.122.105.32) with Microsoft SMTP Server (TLS) id 15.0.1263.5; Thu, 28 Sep 2017 10:28:42 -0700 Received: from Olgas-MBP-107.vpn.netapp.com (olgas-mbp-107.vpn.netapp.com [10.55.75.185]) by smtp1.corp.netapp.com (8.14.9+Sun/8.13.1/NTAP-1.6) with ESMTP id v8SHSdE5002733; Thu, 28 Sep 2017 10:28:42 -0700 (PDT) From: Olga Kornievskaia To: , CC: Subject: [PATCH v4 03/11] NFS recover from destination server reboot for copies Date: Thu, 28 Sep 2017 13:28:31 -0400 Message-ID: <20170928172839.50741-4-kolga@netapp.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20170928172839.50741-1-kolga@netapp.com> References: <20170928172839.50741-1-kolga@netapp.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 Mark the destination state to indicate a server-side copy is happening. On detecting a reboot and recovering open state check if any state is engaged in a server-side copy, if so, find the copy and mark it and then signal the waiting thread. Upon wakeup, if copy was marked then propage EAGAIN to the nfsd_copy_file_range and restart the copy from scratch (no partial state is being queried at this point). Signed-off-by: Olga Kornievskaia --- fs/nfs/nfs42proc.c | 16 +++++++++++++--- fs/nfs/nfs4_fs.h | 4 ++++ fs/nfs/nfs4file.c | 9 +++++++-- fs/nfs/nfs4state.c | 15 +++++++++++++++ include/linux/nfs_fs.h | 2 ++ 5 files changed, 41 insertions(+), 5 deletions(-) diff --git a/fs/nfs/nfs42proc.c b/fs/nfs/nfs42proc.c index 2064d11..378d774 100644 --- a/fs/nfs/nfs42proc.c +++ b/fs/nfs/nfs42proc.c @@ -140,6 +140,7 @@ static int handle_async_copy(struct nfs42_copy_res *res, struct nfs4_copy_state *copy; int status = NFS4_OK; bool found_pending = false; + struct nfs_open_context *ctx = nfs_file_open_context(dst); spin_lock(&server->nfs_client->cl_lock); list_for_each_entry(copy, &server->nfs_client->pending_cb_stateids, @@ -163,6 +164,7 @@ static int handle_async_copy(struct nfs42_copy_res *res, } memcpy(©->stateid, &res->write_res.stateid, NFS4_STATEID_SIZE); init_completion(©->completion); + copy->parent_state = ctx->state; list_add_tail(©->copies, &server->ss_copies); spin_unlock(&server->nfs_client->cl_lock); @@ -172,9 +174,10 @@ static int handle_async_copy(struct nfs42_copy_res *res, list_del_init(©->copies); spin_unlock(&server->nfs_client->cl_lock); if (status == -ERESTARTSYS) { - nfs42_do_offload_cancel_async(dst, ©->stateid); - kfree(copy); - return status; + goto out_cancel; + } else if (copy->flags) { + status = -EAGAIN; + goto out_cancel; } out: *ret_count = copy->count; @@ -184,6 +187,10 @@ static int handle_async_copy(struct nfs42_copy_res *res, kfree(copy); return status; +out_cancel: + nfs42_do_offload_cancel_async(dst, ©->stateid); + kfree(copy); + return status; } static ssize_t _nfs42_proc_copy(struct file *src, @@ -231,6 +238,9 @@ static ssize_t _nfs42_proc_copy(struct file *src, if (!res->commit_res.verf) return -ENOMEM; } + set_bit(NFS_CLNT_DST_SSC_COPY_STATE, + &dst_lock->open_context->state->flags); + status = nfs4_call_sync(server->client, server, &msg, &args->seq_args, &res->seq_res, 0); if (status == -ENOTSUPP) diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h index 5edb161..2ea141c 100644 --- a/fs/nfs/nfs4_fs.h +++ b/fs/nfs/nfs4_fs.h @@ -161,6 +161,10 @@ enum { NFS_STATE_POSIX_LOCKS, /* Posix locks are supported */ NFS_STATE_RECOVERY_FAILED, /* OPEN stateid state recovery failed */ NFS_STATE_MAY_NOTIFY_LOCK, /* server may CB_NOTIFY_LOCK */ +#ifdef CONFIG_NFS_V4_2 + NFS_CLNT_DST_SSC_COPY_STATE, /* dst server open state on client*/ +#endif /* CONFIG_NFS_V4_2 */ + }; struct nfs4_state { diff --git a/fs/nfs/nfs4file.c b/fs/nfs/nfs4file.c index 0efba77..881b819 100644 --- a/fs/nfs/nfs4file.c +++ b/fs/nfs/nfs4file.c @@ -133,10 +133,15 @@ static ssize_t nfs4_copy_file_range(struct file *file_in, loff_t pos_in, struct file *file_out, loff_t pos_out, size_t count, unsigned int flags) { + ssize_t ret; + if (file_inode(file_in) == file_inode(file_out)) return -EINVAL; - - return nfs42_proc_copy(file_in, pos_in, file_out, pos_out, count); +retry: + ret = nfs42_proc_copy(file_in, pos_in, file_out, pos_out, count); + if (ret == -EAGAIN) + goto retry; + return ret; } static loff_t nfs4_file_llseek(struct file *filep, loff_t offset, int whence) diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index 0378e225..0f14800 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c @@ -1546,6 +1546,21 @@ static int nfs4_reclaim_open_state(struct nfs4_state_owner *sp, const struct nfs &state->flags); nfs4_put_open_state(state); spin_lock(&sp->so_lock); +#ifdef CONFIG_NFS_V4_2 + if (test_bit(NFS_CLNT_DST_SSC_COPY_STATE, &state->flags)) { + struct nfs4_copy_state *copy; + + spin_lock(&sp->so_server->nfs_client->cl_lock); + list_for_each_entry(copy, &sp->so_server->ss_copies, copies) { + if (memcmp(&state->stateid.other, ©->parent_state->stateid.other, NFS4_STATEID_SIZE)) + continue; + copy->flags = 1; + complete(©->completion); + break; + } + spin_unlock(&sp->so_server->nfs_client->cl_lock); + } +#endif /* CONFIG_NFS_V4_2 */ goto restart; } } diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h index 580a8d9..85fcd8f 100644 --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h @@ -190,6 +190,8 @@ struct nfs4_copy_state { uint64_t count; struct nfs_writeverf verf; int error; + int flags; + struct nfs4_state *parent_state; }; /*