From patchwork Thu Oct 10 12:46:03 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Olga Kornievskaia X-Patchwork-Id: 11183441 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D458C14ED for ; Thu, 10 Oct 2019 12:46:28 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id B412B2067B for ; Thu, 10 Oct 2019 12:46:28 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="UgD5UUFk" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2387705AbfJJMq2 (ORCPT ); Thu, 10 Oct 2019 08:46:28 -0400 Received: from mail-io1-f67.google.com ([209.85.166.67]:39728 "EHLO mail-io1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1733051AbfJJMq2 (ORCPT ); Thu, 10 Oct 2019 08:46:28 -0400 Received: by mail-io1-f67.google.com with SMTP id a1so13331064ioc.6 for ; Thu, 10 Oct 2019 05:46:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=XsCVxoMR45LfMXA6Sd1k+7LRp9n+Zt/u7Ma/oGmC6xY=; b=UgD5UUFkXfFNBeSkdqNEJ21MO2+BCkGGDwBzhyGHf3+5zfxFQou7tAM+14IUvhXEEd WyjhkKk/StjZmkKKk5NYHtzceIVUifTFj6hvvjOdTI1Xb4srzBbQnVEjDBnVgXzSSZc4 1FEnj4Y8YnYWZHvzCEnB4c+Pjx7vQqOt1xktL06lUp25IMzmNaonO44ci0lOzL4ujVcG TH7NcX3ny6hAb0ujQDWuNKh35aHYcwvmIglMRUn980U2d4aJriPniD+X3yBjouTLk4qh ZVlizOkzaMGlYgccK5GaTDwp8F8U/O6njvpPRsZAvvyxUZhnPTLmINsyymmKCYu+1xS5 OIow== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=XsCVxoMR45LfMXA6Sd1k+7LRp9n+Zt/u7Ma/oGmC6xY=; b=LkWUO1IsOw4vs7aOFCafu4AfiekVB/yYT4+Z2J2+s1aD3j5fmcVwvuTzYBxUlf6t62 PAKfAP8Lkb4nbYA/OKPcsNJ3D3+YEhzeARLGdf/R350lbbTtIbUtXwlAbhm60XzAGys2 WCFJijdnJXzoG67kNzXPrUSO18Bk1OjSb+lJgLolIn/gtSP5B0ycn1Qmgf58TFL7brAz JRbSh+l9weOgRHb5k4lTp8JibC4ACRaob8EqRCLbuv0EjMJnnscSvdr5Gi3fmF0f0cBk xNAn7EUbR4ndkFX8HwVM1qf5o0FWjoaZo4qGsXCFcr0/TdQQwCqxMdnx1MuaNNXYpjfw GPJQ== X-Gm-Message-State: APjAAAWcROmFyvOPobC1npHA2F3FJvcgaC8zRtEI7MbqqdMSXzl4wIYp lDajjP3So8cCPoR1l2yrWaU= X-Google-Smtp-Source: APXvYqz/3dyRnlwY+927HZ4m4wKV8caSzW741RFx/WVHfsE0nql45Ry4RmfVLhMkUNkYMDsDp9N8JQ== X-Received: by 2002:a92:4047:: with SMTP id n68mr487587ila.56.1570711585904; Thu, 10 Oct 2019 05:46:25 -0700 (PDT) Received: from Olgas-MBP-201.attlocal.net (172-10-226-31.lightspeed.livnmi.sbcglobal.net. [172.10.226.31]) by smtp.gmail.com with ESMTPSA id r2sm1100930ilm.17.2019.10.10.05.46.24 (version=TLS1 cipher=AES128-SHA bits=128/128); Thu, 10 Oct 2019 05:46:25 -0700 (PDT) From: Olga Kornievskaia To: trond.myklebust@hammerspace.com, anna.schumaker@netapp.com, bfields@redhat.com Cc: linux-nfs@vger.kernel.org Subject: [PATCH v8 01/20] NFS NFSD: defining nl4_servers structure needed by both Date: Thu, 10 Oct 2019 08:46:03 -0400 Message-Id: <20191010124622.27812-2-olga.kornievskaia@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20191010124622.27812-1-olga.kornievskaia@gmail.com> References: <20191010124622.27812-1-olga.kornievskaia@gmail.com> Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Olga Kornievskaia These structures are needed by COPY_NOTIFY on the client and needed by the nfsd as well Reviewed-by: Jeff Layton Signed-off-by: Olga Kornievskaia --- include/linux/nfs4.h | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h index fd59904..5810e24 100644 --- a/include/linux/nfs4.h +++ b/include/linux/nfs4.h @@ -16,6 +16,7 @@ #include #include #include +#include enum nfs4_acl_whotype { NFS4_ACL_WHO_NAMED = 0, @@ -674,4 +675,27 @@ struct nfs4_op_map { } u; }; +struct nfs42_netaddr { + char netid[RPCBIND_MAXNETIDLEN]; + char addr[RPCBIND_MAXUADDRLEN + 1]; + u32 netid_len; + u32 addr_len; +}; + +enum netloc_type4 { + NL4_NAME = 1, + NL4_URL = 2, + NL4_NETADDR = 3, +}; + +struct nl4_server { + enum netloc_type4 nl4_type; + union { + struct { /* NL4_NAME, NL4_URL */ + int nl4_str_sz; + char nl4_str[NFS4_OPAQUE_LIMIT + 1]; + }; + struct nfs42_netaddr nl4_addr; /* NL4_NETADDR */ + } u; +}; #endif From patchwork Thu Oct 10 12:46:04 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Olga Kornievskaia X-Patchwork-Id: 11183443 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 22F191709 for ; Thu, 10 Oct 2019 12:46:29 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id EDF39208C3 for ; Thu, 10 Oct 2019 12:46:28 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="AZbPzijL" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1733051AbfJJMq2 (ORCPT ); Thu, 10 Oct 2019 08:46:28 -0400 Received: from mail-io1-f65.google.com ([209.85.166.65]:34917 "EHLO mail-io1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2387553AbfJJMq2 (ORCPT ); Thu, 10 Oct 2019 08:46:28 -0400 Received: by mail-io1-f65.google.com with SMTP id q10so13406657iop.2 for ; Thu, 10 Oct 2019 05:46:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=g+ikK+eN+K9cs7SnxmwH74dbB775ilOyU9w0euAc+l4=; b=AZbPzijLSF0TFyt2WCo+ljN9ELLUCR4K5Tot7rqmcNIpRBqGqdXUCuTKYFPiHTitJa OaNKJw5Awt/IX1dmIguQv2dWjTNGVIQDGhcw9ewF/JhpMLVE68rpt1UfoVTJoykiTFyV hsUp0mPeJ5Ln0vul2CGSIQy2pQSOlQN0eZaTbSqbpiVnqIsb+xIFUfgbjGZ/t+oNLaGB +5QsCcjSktc30tGsxyy2DQChT6nyzalTSJuwH7XOV3RqZb0ksVpwr5x3dRYyC4jA27UZ kvwyv5Xlmk0r45YvPQ16Qi2xKwp1vEy8am/2xsRr+NNG3xlVygmTaAve7yRMuhGVXz3F yDgw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=g+ikK+eN+K9cs7SnxmwH74dbB775ilOyU9w0euAc+l4=; b=mjz5wqn9irzpiW2hmVc1otPEoounc4dLaeCXKuwBFt5ei0Xegl/iDeEMQSBDA8DEYP DGuz+DOGSRw1g4fMKLomNLeJE/zhnzSDYt97avzauzClz1g5Jsg30PQnzMN+zWeJ8JU8 23PHmxPkoenhWRCgWNU9cFfTDSYM6IHswpI8XeLxUfml4dMYMC5HA2XjZknxRexJeDMI YuGCfANP0uMV0XfcGB8zXGXN4MclbhfcTvMpspzZum+HRd2La8v1UOOIGN+zQwre4ynH rGThUkWheKrZHVz/QAKYn2cZpy4/trrGZgSKbD8RrfIFBs1wq3t/t9DkAXJll4tOxgeW 0iiA== X-Gm-Message-State: APjAAAXPpT/gd3iJ1EbAZiCoJiztEpdpmu56lP2M7wVZrt9LBRFIGn1q /Bo++0Sz+y3xy2bZmTJhBus= X-Google-Smtp-Source: APXvYqwahg56i1gf48j1DTM5JL4K4dcJq7bhbzv0LfGQ/xjoaPUl6UydDM3LwFyKQkNkID2eyPTJ3A== X-Received: by 2002:a92:b604:: with SMTP id s4mr31919ili.28.1570711587184; Thu, 10 Oct 2019 05:46:27 -0700 (PDT) Received: from Olgas-MBP-201.attlocal.net (172-10-226-31.lightspeed.livnmi.sbcglobal.net. [172.10.226.31]) by smtp.gmail.com with ESMTPSA id r2sm1100930ilm.17.2019.10.10.05.46.25 (version=TLS1 cipher=AES128-SHA bits=128/128); Thu, 10 Oct 2019 05:46:26 -0700 (PDT) From: Olga Kornievskaia To: trond.myklebust@hammerspace.com, anna.schumaker@netapp.com, bfields@redhat.com Cc: linux-nfs@vger.kernel.org Subject: [PATCH v8 02/20] NFS: add COPY_NOTIFY operation Date: Thu, 10 Oct 2019 08:46:04 -0400 Message-Id: <20191010124622.27812-3-olga.kornievskaia@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20191010124622.27812-1-olga.kornievskaia@gmail.com> References: <20191010124622.27812-1-olga.kornievskaia@gmail.com> Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Olga Kornievskaia Try using the delegation stateid, then the open stateid. Only NL4_NETATTR, No support for NL4_NAME and NL4_URL. Allow only one source server address to be returned for now. To distinguish between same server copy offload ("intra") and a copy between different server ("inter"), do a check of server owner identity and also make sure server is capable of doing a copy offload. Signed-off-by: Andy Adamson Signed-off-by: Olga Kornievskaia --- fs/nfs/nfs42.h | 12 ++++ fs/nfs/nfs42proc.c | 91 ++++++++++++++++++++++++ fs/nfs/nfs42xdr.c | 178 ++++++++++++++++++++++++++++++++++++++++++++++ fs/nfs/nfs4_fs.h | 2 + fs/nfs/nfs4client.c | 2 +- fs/nfs/nfs4file.c | 20 +++++- fs/nfs/nfs4proc.c | 1 + fs/nfs/nfs4xdr.c | 1 + include/linux/nfs4.h | 1 + include/linux/nfs_fs_sb.h | 1 + include/linux/nfs_xdr.h | 16 +++++ 11 files changed, 323 insertions(+), 2 deletions(-) diff --git a/fs/nfs/nfs42.h b/fs/nfs/nfs42.h index 901cca7..4995731 100644 --- a/fs/nfs/nfs42.h +++ b/fs/nfs/nfs42.h @@ -13,6 +13,7 @@ #define PNFS_LAYOUTSTATS_MAXDEV (4) /* nfs4.2proc.c */ +#ifdef CONFIG_NFS_V4_2 int nfs42_proc_allocate(struct file *, loff_t, loff_t); ssize_t nfs42_proc_copy(struct file *, loff_t, struct file *, loff_t, size_t); int nfs42_proc_deallocate(struct file *, loff_t, loff_t); @@ -23,5 +24,16 @@ int nfs42_proc_layoutstats_generic(struct nfs_server *, int nfs42_proc_layouterror(struct pnfs_layout_segment *lseg, const struct nfs42_layout_error *errors, size_t n); +int nfs42_proc_copy_notify(struct file *, struct file *, + struct nfs42_copy_notify_res *); +static inline bool nfs42_files_from_same_server(struct file *in, + struct file *out) +{ + struct nfs_client *c_in = (NFS_SERVER(file_inode(in)))->nfs_client; + struct nfs_client *c_out = (NFS_SERVER(file_inode(out)))->nfs_client; + return nfs4_check_serverowner_major_id(c_in->cl_serverowner, + c_out->cl_serverowner); +} +#endif /* CONFIG_NFS_V4_2 */ #endif /* __LINUX_FS_NFS_NFS4_2_H */ diff --git a/fs/nfs/nfs42proc.c b/fs/nfs/nfs42proc.c index 5196bfa..6317dd8 100644 --- a/fs/nfs/nfs42proc.c +++ b/fs/nfs/nfs42proc.c @@ -3,6 +3,7 @@ * Copyright (c) 2014 Anna Schumaker */ #include +#include #include #include #include @@ -15,10 +16,30 @@ #include "pnfs.h" #include "nfs4session.h" #include "internal.h" +#include "delegation.h" #define NFSDBG_FACILITY NFSDBG_PROC static int nfs42_do_offload_cancel_async(struct file *dst, nfs4_stateid *std); +static void nfs42_set_netaddr(struct file *filep, struct nfs42_netaddr *naddr) +{ + struct nfs_client *clp = (NFS_SERVER(file_inode(filep)))->nfs_client; + unsigned short port = 2049; + + rcu_read_lock(); + naddr->netid_len = scnprintf(naddr->netid, + sizeof(naddr->netid), "%s", + rpc_peeraddr2str(clp->cl_rpcclient, + RPC_DISPLAY_NETID)); + naddr->addr_len = scnprintf(naddr->addr, + sizeof(naddr->addr), + "%s.%u.%u", + rpc_peeraddr2str(clp->cl_rpcclient, + RPC_DISPLAY_ADDR), + port >> 8, port & 255); + rcu_read_unlock(); +} + static int _nfs42_proc_fallocate(struct rpc_message *msg, struct file *filep, struct nfs_lock_context *lock, loff_t offset, loff_t len) { @@ -459,6 +480,76 @@ static int nfs42_do_offload_cancel_async(struct file *dst, return status; } +int _nfs42_proc_copy_notify(struct file *src, struct file *dst, + struct nfs42_copy_notify_args *args, + struct nfs42_copy_notify_res *res) +{ + struct nfs_server *src_server = NFS_SERVER(file_inode(src)); + struct rpc_message msg = { + .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_COPY_NOTIFY], + .rpc_argp = args, + .rpc_resp = res, + }; + int status; + struct nfs_open_context *ctx; + struct nfs_lock_context *l_ctx; + + ctx = get_nfs_open_context(nfs_file_open_context(src)); + l_ctx = nfs_get_lock_context(ctx); + if (IS_ERR(l_ctx)) + return PTR_ERR(l_ctx); + + status = nfs4_set_rw_stateid(&args->cna_src_stateid, ctx, l_ctx, + FMODE_READ); + nfs_put_lock_context(l_ctx); + if (status) + return status; + + status = nfs4_call_sync(src_server->client, src_server, &msg, + &args->cna_seq_args, &res->cnr_seq_res, 0); + if (status == -ENOTSUPP) + src_server->caps &= ~NFS_CAP_COPY_NOTIFY; + + put_nfs_open_context(nfs_file_open_context(src)); + return status; +} + +int nfs42_proc_copy_notify(struct file *src, struct file *dst, + struct nfs42_copy_notify_res *res) +{ + struct nfs_server *src_server = NFS_SERVER(file_inode(src)); + struct nfs42_copy_notify_args *args; + struct nfs4_exception exception = { + .inode = file_inode(src), + }; + int status; + + if (!(src_server->caps & NFS_CAP_COPY_NOTIFY)) + return -EOPNOTSUPP; + + args = kzalloc(sizeof(struct nfs42_copy_notify_args), GFP_NOFS); + if (args == NULL) + return -ENOMEM; + + args->cna_src_fh = NFS_FH(file_inode(src)), + args->cna_dst.nl4_type = NL4_NETADDR; + nfs42_set_netaddr(dst, &args->cna_dst.u.nl4_addr); + exception.stateid = &args->cna_src_stateid; + + do { + status = _nfs42_proc_copy_notify(src, dst, args, res); + if (status == -ENOTSUPP) { + status = -EOPNOTSUPP; + goto out; + } + status = nfs4_handle_exception(src_server, status, &exception); + } while (exception.retry); + +out: + kfree(args); + return status; +} + static loff_t _nfs42_proc_llseek(struct file *filep, struct nfs_lock_context *lock, loff_t offset, int whence) { diff --git a/fs/nfs/nfs42xdr.c b/fs/nfs/nfs42xdr.c index aed865a..ccabc0c 100644 --- a/fs/nfs/nfs42xdr.c +++ b/fs/nfs/nfs42xdr.c @@ -29,6 +29,16 @@ #define encode_offload_cancel_maxsz (op_encode_hdr_maxsz + \ XDR_QUADLEN(NFS4_STATEID_SIZE)) #define decode_offload_cancel_maxsz (op_decode_hdr_maxsz) +#define encode_copy_notify_maxsz (op_encode_hdr_maxsz + \ + XDR_QUADLEN(NFS4_STATEID_SIZE) + \ + 1 + /* nl4_type */ \ + 1 + XDR_QUADLEN(NFS4_OPAQUE_LIMIT)) +#define decode_copy_notify_maxsz (op_decode_hdr_maxsz + \ + 3 + /* cnr_lease_time */\ + XDR_QUADLEN(NFS4_STATEID_SIZE) + \ + 1 + /* Support 1 cnr_source_server */\ + 1 + /* nl4_type */ \ + 1 + XDR_QUADLEN(NFS4_OPAQUE_LIMIT)) #define encode_deallocate_maxsz (op_encode_hdr_maxsz + \ encode_fallocate_maxsz) #define decode_deallocate_maxsz (op_decode_hdr_maxsz) @@ -99,6 +109,12 @@ decode_sequence_maxsz + \ decode_putfh_maxsz + \ decode_offload_cancel_maxsz) +#define NFS4_enc_copy_notify_sz (compound_encode_hdr_maxsz + \ + encode_putfh_maxsz + \ + encode_copy_notify_maxsz) +#define NFS4_dec_copy_notify_sz (compound_decode_hdr_maxsz + \ + decode_putfh_maxsz + \ + decode_copy_notify_maxsz) #define NFS4_enc_deallocate_sz (compound_encode_hdr_maxsz + \ encode_sequence_maxsz + \ encode_putfh_maxsz + \ @@ -166,6 +182,26 @@ static void encode_allocate(struct xdr_stream *xdr, encode_fallocate(xdr, args); } +static void encode_nl4_server(struct xdr_stream *xdr, + const struct nl4_server *ns) +{ + encode_uint32(xdr, ns->nl4_type); + switch (ns->nl4_type) { + case NL4_NAME: + case NL4_URL: + encode_string(xdr, ns->u.nl4_str_sz, ns->u.nl4_str); + break; + case NL4_NETADDR: + encode_string(xdr, ns->u.nl4_addr.netid_len, + ns->u.nl4_addr.netid); + encode_string(xdr, ns->u.nl4_addr.addr_len, + ns->u.nl4_addr.addr); + break; + default: + WARN_ON_ONCE(1); + } +} + static void encode_copy(struct xdr_stream *xdr, const struct nfs42_copy_args *args, struct compound_hdr *hdr) @@ -191,6 +227,15 @@ static void encode_offload_cancel(struct xdr_stream *xdr, encode_nfs4_stateid(xdr, &args->osa_stateid); } +static void encode_copy_notify(struct xdr_stream *xdr, + const struct nfs42_copy_notify_args *args, + struct compound_hdr *hdr) +{ + encode_op_hdr(xdr, OP_COPY_NOTIFY, decode_copy_notify_maxsz, hdr); + encode_nfs4_stateid(xdr, &args->cna_src_stateid); + encode_nl4_server(xdr, &args->cna_dst); +} + static void encode_deallocate(struct xdr_stream *xdr, const struct nfs42_falloc_args *args, struct compound_hdr *hdr) @@ -355,6 +400,25 @@ static void nfs4_xdr_enc_offload_cancel(struct rpc_rqst *req, } /* + * Encode COPY_NOTIFY request + */ +static void nfs4_xdr_enc_copy_notify(struct rpc_rqst *req, + struct xdr_stream *xdr, + const void *data) +{ + const struct nfs42_copy_notify_args *args = data; + struct compound_hdr hdr = { + .minorversion = nfs4_xdr_minorversion(&args->cna_seq_args), + }; + + encode_compound_hdr(xdr, req, &hdr); + encode_sequence(xdr, &args->cna_seq_args, &hdr); + encode_putfh(xdr, args->cna_src_fh, &hdr); + encode_copy_notify(xdr, args, &hdr); + encode_nops(&hdr); +} + +/* * Encode DEALLOCATE request */ static void nfs4_xdr_enc_deallocate(struct rpc_rqst *req, @@ -490,6 +554,58 @@ static int decode_write_response(struct xdr_stream *xdr, return decode_verifier(xdr, &res->verifier.verifier); } +static int decode_nl4_server(struct xdr_stream *xdr, struct nl4_server *ns) +{ + struct nfs42_netaddr *naddr; + uint32_t dummy; + char *dummy_str; + __be32 *p; + int status; + + /* nl_type */ + p = xdr_inline_decode(xdr, 4); + if (unlikely(!p)) + return -EIO; + ns->nl4_type = be32_to_cpup(p); + switch (ns->nl4_type) { + case NL4_NAME: + case NL4_URL: + status = decode_opaque_inline(xdr, &dummy, &dummy_str); + if (unlikely(status)) + return status; + if (unlikely(dummy > NFS4_OPAQUE_LIMIT)) + return -EIO; + memcpy(&ns->u.nl4_str, dummy_str, dummy); + ns->u.nl4_str_sz = dummy; + break; + case NL4_NETADDR: + naddr = &ns->u.nl4_addr; + + /* netid string */ + status = decode_opaque_inline(xdr, &dummy, &dummy_str); + if (unlikely(status)) + return status; + if (unlikely(dummy > RPCBIND_MAXNETIDLEN)) + return -EIO; + naddr->netid_len = dummy; + memcpy(naddr->netid, dummy_str, naddr->netid_len); + + /* uaddr string */ + status = decode_opaque_inline(xdr, &dummy, &dummy_str); + if (unlikely(status)) + return status; + if (unlikely(dummy > RPCBIND_MAXUADDRLEN)) + return -EIO; + naddr->addr_len = dummy; + memcpy(naddr->addr, dummy_str, naddr->addr_len); + break; + default: + WARN_ON_ONCE(1); + return -EIO; + } + return 0; +} + static int decode_copy_requirements(struct xdr_stream *xdr, struct nfs42_copy_res *res) { __be32 *p; @@ -529,6 +645,42 @@ static int decode_offload_cancel(struct xdr_stream *xdr, return decode_op_hdr(xdr, OP_OFFLOAD_CANCEL); } +static int decode_copy_notify(struct xdr_stream *xdr, + struct nfs42_copy_notify_res *res) +{ + __be32 *p; + int status, count; + + status = decode_op_hdr(xdr, OP_COPY_NOTIFY); + if (status) + return status; + /* cnr_lease_time */ + p = xdr_inline_decode(xdr, 12); + if (unlikely(!p)) + return -EIO; + p = xdr_decode_hyper(p, &res->cnr_lease_time.seconds); + res->cnr_lease_time.nseconds = be32_to_cpup(p); + + status = decode_opaque_fixed(xdr, &res->cnr_stateid, NFS4_STATEID_SIZE); + if (unlikely(status)) + return -EIO; + + /* number of source addresses */ + p = xdr_inline_decode(xdr, 4); + if (unlikely(!p)) + return -EIO; + + count = be32_to_cpup(p); + if (count > 1) + pr_warn("NFS: %s: nsvr %d > Supported. Use first servers\n", + __func__, count); + + status = decode_nl4_server(xdr, &res->cnr_src); + if (unlikely(status)) + return -EIO; + return 0; +} + static int decode_deallocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res) { return decode_op_hdr(xdr, OP_DEALLOCATE); @@ -657,6 +809,32 @@ static int nfs4_xdr_dec_offload_cancel(struct rpc_rqst *rqstp, } /* + * Decode COPY_NOTIFY response + */ +static int nfs4_xdr_dec_copy_notify(struct rpc_rqst *rqstp, + struct xdr_stream *xdr, + void *data) +{ + struct nfs42_copy_notify_res *res = data; + struct compound_hdr hdr; + int status; + + status = decode_compound_hdr(xdr, &hdr); + if (status) + goto out; + status = decode_sequence(xdr, &res->cnr_seq_res, rqstp); + if (status) + goto out; + status = decode_putfh(xdr); + if (status) + goto out; + status = decode_copy_notify(xdr, res); + +out: + return status; +} + +/* * Decode DEALLOCATE request */ static int nfs4_xdr_dec_deallocate(struct rpc_rqst *rqstp, diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h index 16b2e5c..8e590b4 100644 --- a/fs/nfs/nfs4_fs.h +++ b/fs/nfs/nfs4_fs.h @@ -457,6 +457,8 @@ int nfs41_discover_server_trunking(struct nfs_client *clp, struct nfs_client **, const struct cred *); extern void nfs4_schedule_session_recovery(struct nfs4_session *, int); extern void nfs41_notify_server(struct nfs_client *); +bool nfs4_check_serverowner_major_id(struct nfs41_server_owner *o1, + struct nfs41_server_owner *o2); #else static inline void nfs4_schedule_session_recovery(struct nfs4_session *session, int err) { diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c index da62040..54aaf55 100644 --- a/fs/nfs/nfs4client.c +++ b/fs/nfs/nfs4client.c @@ -629,7 +629,7 @@ int nfs40_walk_client_list(struct nfs_client *new, /* * Returns true if the server major ids match */ -static bool +bool nfs4_check_serverowner_major_id(struct nfs41_server_owner *o1, struct nfs41_server_owner *o2) { diff --git a/fs/nfs/nfs4file.c b/fs/nfs/nfs4file.c index 339663d..686a6c4 100644 --- a/fs/nfs/nfs4file.c +++ b/fs/nfs/nfs4file.c @@ -133,6 +133,9 @@ 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) { + struct nfs42_copy_notify_res *cn_resp = NULL; + ssize_t ret; + /* Only offload copy if superblock is the same */ if (file_inode(file_in)->i_sb != file_inode(file_out)->i_sb) return -EXDEV; @@ -140,7 +143,22 @@ static ssize_t __nfs4_copy_file_range(struct file *file_in, loff_t pos_in, return -EOPNOTSUPP; if (file_inode(file_in) == file_inode(file_out)) return -EOPNOTSUPP; - return nfs42_proc_copy(file_in, pos_in, file_out, pos_out, count); + if (!nfs42_files_from_same_server(file_in, file_out)) { + cn_resp = kzalloc(sizeof(struct nfs42_copy_notify_res), + GFP_NOFS); + if (unlikely(cn_resp == NULL)) + return -ENOMEM; + + ret = nfs42_proc_copy_notify(file_in, file_out, cn_resp); + if (ret) { + ret = -EOPNOTSUPP; + goto out; + } + } + ret = nfs42_proc_copy(file_in, pos_in, file_out, pos_out, count); +out: + kfree(cn_resp); + return ret; } static ssize_t nfs4_copy_file_range(struct file *file_in, loff_t pos_in, diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 11eafcf..505045b 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -9899,6 +9899,7 @@ static bool nfs4_match_stateid(const nfs4_stateid *s1, | NFS_CAP_ALLOCATE | NFS_CAP_COPY | NFS_CAP_OFFLOAD_CANCEL + | NFS_CAP_COPY_NOTIFY | NFS_CAP_DEALLOCATE | NFS_CAP_SEEK | NFS_CAP_LAYOUTSTATS diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index ab07db0..2f9315d 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c @@ -7581,6 +7581,7 @@ int nfs4_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, PROC42(CLONE, enc_clone, dec_clone), PROC42(COPY, enc_copy, dec_copy), PROC42(OFFLOAD_CANCEL, enc_offload_cancel, dec_offload_cancel), + PROC42(COPY_NOTIFY, enc_copy_notify, dec_copy_notify), PROC(LOOKUPP, enc_lookupp, dec_lookupp), PROC42(LAYOUTERROR, enc_layouterror, dec_layouterror), }; diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h index 5810e24..5e7a526 100644 --- a/include/linux/nfs4.h +++ b/include/linux/nfs4.h @@ -537,6 +537,7 @@ enum { NFSPROC4_CLNT_CLONE, NFSPROC4_CLNT_COPY, NFSPROC4_CLNT_OFFLOAD_CANCEL, + NFSPROC4_CLNT_COPY_NOTIFY, NFSPROC4_CLNT_LOOKUPP, NFSPROC4_CLNT_LAYOUTERROR, diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h index a87fe85..e1c8748 100644 --- a/include/linux/nfs_fs_sb.h +++ b/include/linux/nfs_fs_sb.h @@ -276,5 +276,6 @@ struct nfs_server { #define NFS_CAP_COPY (1U << 24) #define NFS_CAP_OFFLOAD_CANCEL (1U << 25) #define NFS_CAP_LAYOUTERROR (1U << 26) +#define NFS_CAP_COPY_NOTIFY (1U << 27) #endif diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index 9b8324e..0a7af40 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h @@ -1463,6 +1463,22 @@ struct nfs42_offload_status_res { int osr_status; }; +struct nfs42_copy_notify_args { + struct nfs4_sequence_args cna_seq_args; + + struct nfs_fh *cna_src_fh; + nfs4_stateid cna_src_stateid; + struct nl4_server cna_dst; +}; + +struct nfs42_copy_notify_res { + struct nfs4_sequence_res cnr_seq_res; + + struct nfstime4 cnr_lease_time; + nfs4_stateid cnr_stateid; + struct nl4_server cnr_src; +}; + struct nfs42_seek_args { struct nfs4_sequence_args seq_args; From patchwork Thu Oct 10 12:46:05 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Olga Kornievskaia X-Patchwork-Id: 11183447 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 066CB1709 for ; Thu, 10 Oct 2019 12:46:32 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id D187A208C3 for ; Thu, 10 Oct 2019 12:46:31 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="MHJV3XZh" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2387838AbfJJMqb (ORCPT ); Thu, 10 Oct 2019 08:46:31 -0400 Received: from mail-io1-f67.google.com ([209.85.166.67]:39964 "EHLO mail-io1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2387553AbfJJMqb (ORCPT ); Thu, 10 Oct 2019 08:46:31 -0400 Received: by mail-io1-f67.google.com with SMTP id h144so13281728iof.7 for ; Thu, 10 Oct 2019 05:46:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=Obq2s/I8IROUITybj5QBlF9nrcnOtRzdlJGuACz59bo=; b=MHJV3XZhtHF6OY/Xm7asZJDK+aV1Bj1CcK+2DFZGIAQX5iCr+owUi87mrLs0QC6wOV 5YSsv6gcI2+7NTH5uKRh4XKglvb+hsS1EDkOPkOSiMcuPh9eDL5mNYejF4QSQeihkkr2 oKlQKzVn418FYMRfiq2L67N/sJ9XDv0za6hrm/jAzUU5Yv0h9ACPJ/I7dbwgKipqbPlF EftdpI+NXh+B4X/zW1+1HFPgWQPcYNVyuLz8U7Q8kyxMMq1ZboKqjjwp3HG9QIpxqNuR KyGp0sM0RBekTOPKL5Bk5gX80sdL+89yhYJoszuoCcfPw6GYYJylAVg9ESuDxUyabwxi cvbQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=Obq2s/I8IROUITybj5QBlF9nrcnOtRzdlJGuACz59bo=; b=Ndi8vN5wjILDVeaK2WIj6N+8AA/Lg+geTaoSicXYDO0c95uiglB9sNEjx3MdAZuNJU 93CCHZyQjQIEWbIWkALwPZhzIJmUFKlXNGWPQejgLaUY2PnWiBuj7Tmwo37C9Md0hTW3 i95cclD85lImDvmFmX5D/8EtFtuTVgvbVfc7srNR0/0bgq7do6Mchixe5vIub70hnNTj vDkKKBZF6YnKrNtLBcQ6kV0Yix37wgjnrICQvcVnrJlrVIYUUcQNj+ZwcubTs2HEONtj O3UqUihzAJngXSEWBtSoJQylljNtJZVHM/+Lr4HxC8h0FxmQYY3zz6hj2BjGPBrXCeV+ U39A== X-Gm-Message-State: APjAAAVc25dvHhTxmsGJ80LQXMfQ9ja8tCYOD4Ta1PGupOn7kXj7ts58 MlcQxDaSgehU+EJht+xO91c= X-Google-Smtp-Source: APXvYqxRKXkhn4sHlHH/3E+QwAJe4Qdy6g8dgMuYs9PLfMMVuwSClk7hoziY9TTBDS302zBOIZA9Cg== X-Received: by 2002:a92:1604:: with SMTP id r4mr432411ill.253.1570711588642; Thu, 10 Oct 2019 05:46:28 -0700 (PDT) Received: from Olgas-MBP-201.attlocal.net (172-10-226-31.lightspeed.livnmi.sbcglobal.net. [172.10.226.31]) by smtp.gmail.com with ESMTPSA id r2sm1100930ilm.17.2019.10.10.05.46.27 (version=TLS1 cipher=AES128-SHA bits=128/128); Thu, 10 Oct 2019 05:46:28 -0700 (PDT) From: Olga Kornievskaia To: trond.myklebust@hammerspace.com, anna.schumaker@netapp.com, bfields@redhat.com Cc: linux-nfs@vger.kernel.org Subject: [PATCH v8 03/20] NFS: add ca_source_server<> to COPY Date: Thu, 10 Oct 2019 08:46:05 -0400 Message-Id: <20191010124622.27812-4-olga.kornievskaia@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20191010124622.27812-1-olga.kornievskaia@gmail.com> References: <20191010124622.27812-1-olga.kornievskaia@gmail.com> Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Olga Kornievskaia Support only one source server address: the same address that the client and source server use. Signed-off-by: Andy Adamson Signed-off-by: Olga Kornievskaia --- fs/nfs/nfs42.h | 3 ++- fs/nfs/nfs42proc.c | 26 +++++++++++++++++--------- fs/nfs/nfs42xdr.c | 12 ++++++++++-- fs/nfs/nfs4file.c | 7 ++++++- include/linux/nfs_xdr.h | 1 + 5 files changed, 36 insertions(+), 13 deletions(-) diff --git a/fs/nfs/nfs42.h b/fs/nfs/nfs42.h index 4995731..02e3810 100644 --- a/fs/nfs/nfs42.h +++ b/fs/nfs/nfs42.h @@ -15,7 +15,8 @@ /* nfs4.2proc.c */ #ifdef CONFIG_NFS_V4_2 int nfs42_proc_allocate(struct file *, loff_t, loff_t); -ssize_t nfs42_proc_copy(struct file *, loff_t, struct file *, loff_t, size_t); +ssize_t nfs42_proc_copy(struct file *, loff_t, struct file *, loff_t, size_t, + struct nl4_server *, nfs4_stateid *); int nfs42_proc_deallocate(struct file *, loff_t, loff_t); loff_t nfs42_proc_llseek(struct file *, loff_t, int); int nfs42_proc_layoutstats_generic(struct nfs_server *, diff --git a/fs/nfs/nfs42proc.c b/fs/nfs/nfs42proc.c index 6317dd8..e34ade8 100644 --- a/fs/nfs/nfs42proc.c +++ b/fs/nfs/nfs42proc.c @@ -243,7 +243,9 @@ static ssize_t _nfs42_proc_copy(struct file *src, struct file *dst, struct nfs_lock_context *dst_lock, struct nfs42_copy_args *args, - struct nfs42_copy_res *res) + struct nfs42_copy_res *res, + struct nl4_server *nss, + nfs4_stateid *cnr_stateid) { struct rpc_message msg = { .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_COPY], @@ -257,11 +259,15 @@ static ssize_t _nfs42_proc_copy(struct file *src, size_t count = args->count; ssize_t status; - status = nfs4_set_rw_stateid(&args->src_stateid, src_lock->open_context, - src_lock, FMODE_READ); - if (status) - return status; - + if (nss) { + args->cp_src = nss; + nfs4_stateid_copy(&args->src_stateid, cnr_stateid); + } else { + status = nfs4_set_rw_stateid(&args->src_stateid, + src_lock->open_context, src_lock, FMODE_READ); + if (status) + return status; + } status = nfs_filemap_write_and_wait_range(file_inode(src)->i_mapping, pos_src, pos_src + (loff_t)count - 1); if (status) @@ -325,8 +331,9 @@ static ssize_t _nfs42_proc_copy(struct file *src, } ssize_t nfs42_proc_copy(struct file *src, loff_t pos_src, - struct file *dst, loff_t pos_dst, - size_t count) + struct file *dst, loff_t pos_dst, size_t count, + struct nl4_server *nss, + nfs4_stateid *cnr_stateid) { struct nfs_server *server = NFS_SERVER(file_inode(dst)); struct nfs_lock_context *src_lock; @@ -368,7 +375,8 @@ ssize_t nfs42_proc_copy(struct file *src, loff_t pos_src, inode_lock(file_inode(dst)); err = _nfs42_proc_copy(src, src_lock, dst, dst_lock, - &args, &res); + &args, &res, + nss, cnr_stateid); inode_unlock(file_inode(dst)); if (err >= 0) diff --git a/fs/nfs/nfs42xdr.c b/fs/nfs/nfs42xdr.c index ccabc0c..c03f324 100644 --- a/fs/nfs/nfs42xdr.c +++ b/fs/nfs/nfs42xdr.c @@ -21,7 +21,10 @@ #define encode_copy_maxsz (op_encode_hdr_maxsz + \ XDR_QUADLEN(NFS4_STATEID_SIZE) + \ XDR_QUADLEN(NFS4_STATEID_SIZE) + \ - 2 + 2 + 2 + 1 + 1 + 1) + 2 + 2 + 2 + 1 + 1 + 1 +\ + 1 + /* One cnr_source_server */\ + 1 + /* nl4_type */ \ + 1 + XDR_QUADLEN(NFS4_OPAQUE_LIMIT)) #define decode_copy_maxsz (op_decode_hdr_maxsz + \ NFS42_WRITE_RES_SIZE + \ 1 /* cr_consecutive */ + \ @@ -216,7 +219,12 @@ static void encode_copy(struct xdr_stream *xdr, encode_uint32(xdr, 1); /* consecutive = true */ encode_uint32(xdr, args->sync); - encode_uint32(xdr, 0); /* src server list */ + if (args->cp_src == NULL) { /* intra-ssc */ + encode_uint32(xdr, 0); /* no src server list */ + return; + } + encode_uint32(xdr, 1); /* supporting 1 server */ + encode_nl4_server(xdr, args->cp_src); } static void encode_offload_cancel(struct xdr_stream *xdr, diff --git a/fs/nfs/nfs4file.c b/fs/nfs/nfs4file.c index 686a6c4..b68b41b 100644 --- a/fs/nfs/nfs4file.c +++ b/fs/nfs/nfs4file.c @@ -134,6 +134,8 @@ static ssize_t __nfs4_copy_file_range(struct file *file_in, loff_t pos_in, size_t count, unsigned int flags) { struct nfs42_copy_notify_res *cn_resp = NULL; + struct nl4_server *nss = NULL; + nfs4_stateid *cnrs = NULL; ssize_t ret; /* Only offload copy if superblock is the same */ @@ -154,8 +156,11 @@ static ssize_t __nfs4_copy_file_range(struct file *file_in, loff_t pos_in, ret = -EOPNOTSUPP; goto out; } + nss = &cn_resp->cnr_src; + cnrs = &cn_resp->cnr_stateid; } - ret = nfs42_proc_copy(file_in, pos_in, file_out, pos_out, count); + ret = nfs42_proc_copy(file_in, pos_in, file_out, pos_out, count, + nss, cnrs); out: kfree(cn_resp); return ret; diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index 0a7af40..008faca 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h @@ -1435,6 +1435,7 @@ struct nfs42_copy_args { u64 count; bool sync; + struct nl4_server *cp_src; }; struct nfs42_write_res { From patchwork Thu Oct 10 12:46:06 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Olga Kornievskaia X-Patchwork-Id: 11183445 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 6935D1575 for ; Thu, 10 Oct 2019 12:46:31 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 4102D206B6 for ; Thu, 10 Oct 2019 12:46:31 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="d51mOtic" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2387834AbfJJMqa (ORCPT ); Thu, 10 Oct 2019 08:46:30 -0400 Received: from mail-io1-f65.google.com ([209.85.166.65]:37486 "EHLO mail-io1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2387801AbfJJMqa (ORCPT ); Thu, 10 Oct 2019 08:46:30 -0400 Received: by mail-io1-f65.google.com with SMTP id b19so13337168iob.4 for ; Thu, 10 Oct 2019 05:46:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=7IlITqP9Y6iPkUe+B4M9/X1/cAINLpB8Gc9iOTZo000=; b=d51mOticr9BERmj0f80diLODJXgbfIC/qKu/G1LG7e38O5QlA8WNF06NEBONz3qPEK 1OI1utPymrzqQaFMb3vdE22Gu3/V9scXhafADl29txtYtKx9hN30fvnEke2m8Ifp0JlC vRaWE2aLYnErnZoGPLF1ikFJGUV2xziLtVDjeFCTAgLdpaTi9QHOSQ+OxGJyi5U9AnF5 o8/wiicBuJJ8t4+zYMZWkecJhwZ2qb+AK7gpQlMdNYs8AbhLIW9CrsJllGK81eVn6u1t twQPIHXJ2KHPHLHTCKZcKoW+nx5W/yS3lCXTDWm8Vf3f9Vx2DZpGj5P/WlIpLdgyea8Y 644g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=7IlITqP9Y6iPkUe+B4M9/X1/cAINLpB8Gc9iOTZo000=; b=JSqGYfdrekzmseiThg64OyjVolS9cV+TkpsxjOH//UFZM7OanZ5r26SrLMc9k2mtLz hd5OTiTq03t4U2Xk9qZpLGXKKL18TRIeU/ZnnJ0WZpu1Rhh7OWhfyfHVBPPW1nz40c0j qaYUIPFkN/ZpibeswaZcU5YWLdEdKTTt3Onh9xU7JrsY+LBkGnahffIzM1hY6xLEg/e3 KzDohWvFPySpmfa3vjVASdnbxoXtftgtaXgi+TH9U2dP1B5CFLZPlPsL0+WhXQ2C7nMx w1bLwdwiZummh/ijOCI+bVBv49tGtcUXNEZwqrdBnFOsv2mFGsxF5OOISpVqiWr8E6W/ UZQw== X-Gm-Message-State: APjAAAWhlS3NAvW/DL8DaXZAWi9ofcXnkZ2jqAcBeMgVYKcy0Iqhkto2 EwU+VsquGVkF30wU52+PS04= X-Google-Smtp-Source: APXvYqxTHiK5QcWOfsKEfwl+bRXzioXY6PYM2yB52tHG7bkmVkz9cGLL+OwCubTVo0/VGpCtjLP+hg== X-Received: by 2002:a92:1f44:: with SMTP id i65mr15728ile.123.1570711589673; Thu, 10 Oct 2019 05:46:29 -0700 (PDT) Received: from Olgas-MBP-201.attlocal.net (172-10-226-31.lightspeed.livnmi.sbcglobal.net. [172.10.226.31]) by smtp.gmail.com with ESMTPSA id r2sm1100930ilm.17.2019.10.10.05.46.28 (version=TLS1 cipher=AES128-SHA bits=128/128); Thu, 10 Oct 2019 05:46:29 -0700 (PDT) From: Olga Kornievskaia To: trond.myklebust@hammerspace.com, anna.schumaker@netapp.com, bfields@redhat.com Cc: linux-nfs@vger.kernel.org Subject: [PATCH v8 04/20] NFS: inter ssc open Date: Thu, 10 Oct 2019 08:46:06 -0400 Message-Id: <20191010124622.27812-5-olga.kornievskaia@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20191010124622.27812-1-olga.kornievskaia@gmail.com> References: <20191010124622.27812-1-olga.kornievskaia@gmail.com> Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Olga Kornievskaia NFSv4.2 inter server to server copy requires the destination server to READ the data from the source server using the provided stateid and file handle. Given an NFSv4 stateid and filehandle from the COPY operaion, provide the destination server with an NFS client function to create a struct file suitable for the destiniation server to READ the data to be copied. Signed-off-by: Olga Kornievskaia Signed-off-by: Andy Adamson --- fs/nfs/nfs4_fs.h | 7 +++++ fs/nfs/nfs4file.c | 94 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ fs/nfs/nfs4proc.c | 5 ++- 3 files changed, 103 insertions(+), 3 deletions(-) diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h index 8e590b4..5f27942 100644 --- a/fs/nfs/nfs4_fs.h +++ b/fs/nfs/nfs4_fs.h @@ -311,6 +311,13 @@ extern int nfs4_set_rw_stateid(nfs4_stateid *stateid, const struct nfs_open_context *ctx, const struct nfs_lock_context *l_ctx, fmode_t fmode); +extern int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, + struct nfs_fattr *fattr, struct nfs4_label *label, + struct inode *inode); +extern int update_open_stateid(struct nfs4_state *state, + const nfs4_stateid *open_stateid, + const nfs4_stateid *deleg_stateid, + fmode_t fmode); extern int nfs4_proc_get_lease_time(struct nfs_client *clp, struct nfs_fsinfo *fsinfo); diff --git a/fs/nfs/nfs4file.c b/fs/nfs/nfs4file.c index b68b41b..1898262a 100644 --- a/fs/nfs/nfs4file.c +++ b/fs/nfs/nfs4file.c @@ -8,6 +8,7 @@ #include #include #include +#include #include "delegation.h" #include "internal.h" #include "iostat.h" @@ -286,6 +287,99 @@ static loff_t nfs42_remap_file_range(struct file *src_file, loff_t src_off, out: return ret < 0 ? ret : count; } + +static int read_name_gen = 1; +#define SSC_READ_NAME_BODY "ssc_read_%d" + +struct file * +nfs42_ssc_open(struct vfsmount *ss_mnt, struct nfs_fh *src_fh, + nfs4_stateid *stateid) +{ + struct nfs_fattr fattr; + struct file *filep, *res; + struct nfs_server *server; + struct inode *r_ino = NULL; + struct nfs_open_context *ctx; + struct nfs4_state_owner *sp; + char *read_name; + int len, status = 0; + + server = NFS_SERVER(ss_mnt->mnt_root->d_inode); + + nfs_fattr_init(&fattr); + + status = nfs4_proc_getattr(server, src_fh, &fattr, NULL, NULL); + if (status < 0) { + res = ERR_PTR(status); + goto out; + } + + res = ERR_PTR(-ENOMEM); + len = strlen(SSC_READ_NAME_BODY) + 16; + read_name = kzalloc(len, GFP_NOFS); + if (read_name == NULL) + goto out; + snprintf(read_name, len, SSC_READ_NAME_BODY, read_name_gen++); + + r_ino = nfs_fhget(ss_mnt->mnt_root->d_inode->i_sb, src_fh, &fattr, + NULL); + if (IS_ERR(r_ino)) { + res = ERR_CAST(r_ino); + goto out; + } + + filep = alloc_file_pseudo(r_ino, ss_mnt, read_name, FMODE_READ, + r_ino->i_fop); + if (IS_ERR(filep)) { + res = ERR_CAST(filep); + goto out; + } + filep->f_mode |= FMODE_READ; + + ctx = alloc_nfs_open_context(filep->f_path.dentry, filep->f_mode, + filep); + if (IS_ERR(ctx)) { + res = ERR_CAST(ctx); + goto out_filep; + } + + res = ERR_PTR(-EINVAL); + sp = nfs4_get_state_owner(server, ctx->cred, GFP_KERNEL); + if (sp == NULL) + goto out_ctx; + + ctx->state = nfs4_get_open_state(r_ino, sp); + if (ctx->state == NULL) + goto out_stateowner; + + set_bit(NFS_OPEN_STATE, &ctx->state->flags); + memcpy(&ctx->state->open_stateid.other, &stateid->other, + NFS4_STATEID_OTHER_SIZE); + update_open_stateid(ctx->state, stateid, NULL, filep->f_mode); + + nfs_file_set_open_context(filep, ctx); + put_nfs_open_context(ctx); + + file_ra_state_init(&filep->f_ra, filep->f_mapping->host->i_mapping); + res = filep; +out: + return res; +out_stateowner: + nfs4_put_state_owner(sp); +out_ctx: + put_nfs_open_context(ctx); +out_filep: + fput(filep); + goto out; +} +EXPORT_SYMBOL_GPL(nfs42_ssc_open); +void nfs42_ssc_close(struct file *filep) +{ + struct nfs_open_context *ctx = nfs_file_open_context(filep); + + ctx->state->flags = 0; +} +EXPORT_SYMBOL_GPL(nfs42_ssc_close); #endif /* CONFIG_NFS_V4_2 */ const struct file_operations nfs4_file_operations = { diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 505045b..f3a1f8d 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -91,7 +91,6 @@ static int _nfs4_recover_proc_open(struct nfs4_opendata *data); static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *); static void nfs_fixup_referral_attributes(struct nfs_fattr *fattr); -static int nfs4_proc_getattr(struct nfs_server *, struct nfs_fh *, struct nfs_fattr *, struct nfs4_label *label, struct inode *inode); static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr, struct nfs4_label *label, struct inode *inode); static int nfs4_do_setattr(struct inode *inode, const struct cred *cred, struct nfs_fattr *fattr, struct iattr *sattr, @@ -1718,7 +1717,7 @@ static void nfs_state_clear_delegation(struct nfs4_state *state) write_sequnlock(&state->seqlock); } -static int update_open_stateid(struct nfs4_state *state, +int update_open_stateid(struct nfs4_state *state, const nfs4_stateid *open_stateid, const nfs4_stateid *delegation, fmode_t fmode) @@ -4065,7 +4064,7 @@ static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, return nfs4_call_sync(server->client, server, &msg, &args.seq_args, &res.seq_res, 0); } -static int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, +int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr, struct nfs4_label *label, struct inode *inode) { From patchwork Thu Oct 10 12:46:07 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Olga Kornievskaia X-Patchwork-Id: 11183449 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 7929B14ED for ; Thu, 10 Oct 2019 12:46:32 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 585E4206B6 for ; Thu, 10 Oct 2019 12:46:32 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="bhtrq5wJ" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2387553AbfJJMqb (ORCPT ); Thu, 10 Oct 2019 08:46:31 -0400 Received: from mail-io1-f65.google.com ([209.85.166.65]:36041 "EHLO mail-io1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2387801AbfJJMqb (ORCPT ); Thu, 10 Oct 2019 08:46:31 -0400 Received: by mail-io1-f65.google.com with SMTP id b136so13349610iof.3 for ; Thu, 10 Oct 2019 05:46:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=RSgNzoy3u3Erm4dktIG0xJ/U54xZxUEXHfZZn0m200U=; b=bhtrq5wJEWuJrc0esHQ8kpTOlH/BQWQPsRD+KZYn2O8aMnUSXkee8UcWz+fzTlAlPo nEnK4qkWNyt3Cx0KdJOJlT9zDKB250FafLdRvRTc5MOTCrgvEIcWwOMnntEVAbwhOB5A VFkVWrdcmjcWdC7ybEe4BUUpt+L7q5u7zQR2ATuI3p3cuW+pJWkDifuyYwfcP+bYSrh6 wzvwIOffbV45kFZsdZfkdGmPbMXhgL5f0yC8XWRlHCmRz6hTXwGkqSHTEGOhkqsInXKL Z8pahe/X2jOLJYhurVJq4s6EWY4zoo33/wci81jCBV0wp23MvCon6TjSXayCKbK+q3ZE 4XKQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=RSgNzoy3u3Erm4dktIG0xJ/U54xZxUEXHfZZn0m200U=; b=YE8/1/VDM9UN4F5OMM1bSQbH4GdVnzB6LN6NIrBb3MPYdRiXm6lMv+XrgRIAcerOd3 4InlfB9ENHA6JkbQpqeVzQwOxy3ez3JAicMF3D1//Dm60HVwNKCy9sVFMo/MBK7Q5YGi yYHEm7o3rA3zJ8ZxPhDGAnOD5qexHHEGn/+VAfhBFUUIFQPVjI6jqtu5xajwbej5uL6I 7g+fQHq7V2UfeFI1BrIG8otl8MbDqk0BUwSlQ1E/L2QVZF96jhCOQI74FNAmuejeV1tm JjBDf1WAQ4aB0v6swyV/TwqPOIQv8YQ0F6lWXpYHgXmCRYFY+rEKBpOYAjsUaL9s5Kul ysaQ== X-Gm-Message-State: APjAAAWAVnWOvfupwHsrMELvGcbTYT7wIJt69LdXXm/zSlUdlu6Dbt5F PHFMDePaq6XbDFFRj+DFrbeGpM6J X-Google-Smtp-Source: APXvYqw3/R9ZMrYMDGQ2dVWY+3fYmc5fic09RSYgBaxOZUdkEUwfJMrskBMdef6Qq2IDMhU6q4J43Q== X-Received: by 2002:a92:38c9:: with SMTP id g70mr13678ilf.88.1570711590912; Thu, 10 Oct 2019 05:46:30 -0700 (PDT) Received: from Olgas-MBP-201.attlocal.net (172-10-226-31.lightspeed.livnmi.sbcglobal.net. [172.10.226.31]) by smtp.gmail.com with ESMTPSA id r2sm1100930ilm.17.2019.10.10.05.46.29 (version=TLS1 cipher=AES128-SHA bits=128/128); Thu, 10 Oct 2019 05:46:30 -0700 (PDT) From: Olga Kornievskaia To: trond.myklebust@hammerspace.com, anna.schumaker@netapp.com, bfields@redhat.com Cc: linux-nfs@vger.kernel.org Subject: [PATCH v8 05/20] NFS: skip recovery of copy open on dest server Date: Thu, 10 Oct 2019 08:46:07 -0400 Message-Id: <20191010124622.27812-6-olga.kornievskaia@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20191010124622.27812-1-olga.kornievskaia@gmail.com> References: <20191010124622.27812-1-olga.kornievskaia@gmail.com> Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Olga Kornievskaia Mark the open created for the source file on the destination server. Then if this open is going thru a recovery, then fail the recovery as we don't need to be recoving a "fake" open. We need to fail the ongoing READs and vfs_copy_file_range(). Signed-off-by: Olga Kornievskaia --- fs/nfs/nfs4_fs.h | 1 + fs/nfs/nfs4file.c | 1 + fs/nfs/nfs4state.c | 14 ++++++++++++++ 3 files changed, 16 insertions(+) diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h index 5f27942..814674f 100644 --- a/fs/nfs/nfs4_fs.h +++ b/fs/nfs/nfs4_fs.h @@ -168,6 +168,7 @@ enum { NFS_STATE_CHANGE_WAIT, /* A state changing operation is outstanding */ #ifdef CONFIG_NFS_V4_2 NFS_CLNT_DST_SSC_COPY_STATE, /* dst server open state on client*/ + NFS_SRV_SSC_COPY_STATE, /* ssc state on the dst server */ #endif /* CONFIG_NFS_V4_2 */ }; diff --git a/fs/nfs/nfs4file.c b/fs/nfs/nfs4file.c index 1898262a..a932fc9 100644 --- a/fs/nfs/nfs4file.c +++ b/fs/nfs/nfs4file.c @@ -352,6 +352,7 @@ struct file * if (ctx->state == NULL) goto out_stateowner; + set_bit(NFS_SRV_SSC_COPY_STATE, &ctx->state->flags); set_bit(NFS_OPEN_STATE, &ctx->state->flags); memcpy(&ctx->state->open_stateid.other, &stateid->other, NFS4_STATEID_OTHER_SIZE); diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index 0c6d53d..c45b300 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c @@ -1609,6 +1609,9 @@ static int nfs4_reclaim_open_state(struct nfs4_state_owner *sp, const struct nfs struct nfs4_state *state; unsigned int loop = 0; int status = 0; +#ifdef CONFIG_NFS_V4_2 + bool found_ssc_copy_state = false; +#endif /* CONFIG_NFS_V4_2 */ /* Note: we rely on the sp->so_states list being ordered * so that we always reclaim open(O_RDWR) and/or open(O_WRITE) @@ -1628,6 +1631,13 @@ static int nfs4_reclaim_open_state(struct nfs4_state_owner *sp, const struct nfs continue; if (state->state == 0) continue; +#ifdef CONFIG_NFS_V4_2 + if (test_bit(NFS_SRV_SSC_COPY_STATE, &state->flags)) { + nfs4_state_mark_recovery_failed(state, -EIO); + found_ssc_copy_state = true; + continue; + } +#endif /* CONFIG_NFS_V4_2 */ refcount_inc(&state->count); spin_unlock(&sp->so_lock); status = __nfs4_reclaim_open_state(sp, state, ops); @@ -1682,6 +1692,10 @@ static int nfs4_reclaim_open_state(struct nfs4_state_owner *sp, const struct nfs } raw_write_seqcount_end(&sp->so_reclaim_seqcount); spin_unlock(&sp->so_lock); +#ifdef CONFIG_NFS_V4_2 + if (found_ssc_copy_state) + return -EIO; +#endif /* CONFIG_NFS_V4_2 */ return 0; out_err: nfs4_put_open_state(state); From patchwork Thu Oct 10 12:46:08 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Olga Kornievskaia X-Patchwork-Id: 11183451 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id B80A314ED for ; Thu, 10 Oct 2019 12:46:33 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 9804D20B7C for ; Thu, 10 Oct 2019 12:46:33 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="rYcydWy5" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2387857AbfJJMqd (ORCPT ); Thu, 10 Oct 2019 08:46:33 -0400 Received: from mail-io1-f66.google.com ([209.85.166.66]:38054 "EHLO mail-io1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2387801AbfJJMqc (ORCPT ); Thu, 10 Oct 2019 08:46:32 -0400 Received: by mail-io1-f66.google.com with SMTP id u8so13325399iom.5 for ; Thu, 10 Oct 2019 05:46:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=9vl9z2Pnhs9wDkK71wWFdDuvprpW05FNT6IF65lu3YE=; b=rYcydWy5JrXcKoU4bIJsSa5duqj9WE2ZBAKLsiIO0V7seQtDF2YOTsR4tL26MuQbUN FsyZ36zTgWE6F0On/5sGj+niU3ztA/Tx6IRuZ1Z7T97bMiAJfbKH+58w7sv8ajNZkriG 3OEz25om9llbTJE/pmx1SKnK4Tt2b5wEW1kHqUPB2ZVzu0U1qZvi5mIS43BYQee3VJH8 oiqcqWTUlLr0huuSLykEPM9sdhVtp4uoWtO16maEj6OwMoor4cbVyGy9ZSRJNkzwZ9sN tvQJvrwHaW6A+TBPtBlCszxrf1rukU/stgXXi1aw4ZhQyRpx+2E+dRQxi4IR61CZW99k a97g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=9vl9z2Pnhs9wDkK71wWFdDuvprpW05FNT6IF65lu3YE=; b=IdNKT1PZnfo6gzuUHPbSd3+XYaHqvgvXHhXfCrt4GTI3CTN2mwoDBWVZSyWvIMl7Fr DKSyWwFutwfNE9L/nNHTOPT+K0+o32PbTmxMcAp4dO6fm4lp4XzwN0O3ATrxWlpalngY lqqxYF0umULaVnzam1uf5ti7UwdgrMAtS2zzhjVaEnSRagL+NSk8ssEKu+0h3dXdx8/5 Wfgd+DC6b+ykZBPmx35HrCZn8Xilv//VYZFnJZjANZgezhvFk8TEmz+aHsfHtlYxR+J7 j5dUuIM56EVpydEumXhNsps10yuO+lLHbMKWG0JUYbj4jejsm8E/TIBVou4FSi9f7n18 aOlg== X-Gm-Message-State: APjAAAUyIUaR1/nmsZfpkc1frxpFLV7jh3GXV6IR8AreO2Y+86HtfCzQ RFo0K0wA3T7Zg0sQ9Ypv/Bl2TPwy X-Google-Smtp-Source: APXvYqzD6nW3yGQBvj7HlvbQC2svn1jsYZWNYpkwS/TshIR3x06uQjzvdO/LG83pIVRqtYlHS+y8Aw== X-Received: by 2002:a92:1011:: with SMTP id y17mr421269ill.234.1570711592113; Thu, 10 Oct 2019 05:46:32 -0700 (PDT) Received: from Olgas-MBP-201.attlocal.net (172-10-226-31.lightspeed.livnmi.sbcglobal.net. [172.10.226.31]) by smtp.gmail.com with ESMTPSA id r2sm1100930ilm.17.2019.10.10.05.46.31 (version=TLS1 cipher=AES128-SHA bits=128/128); Thu, 10 Oct 2019 05:46:31 -0700 (PDT) From: Olga Kornievskaia To: trond.myklebust@hammerspace.com, anna.schumaker@netapp.com, bfields@redhat.com Cc: linux-nfs@vger.kernel.org Subject: [PATCH v8 06/20] NFS: for "inter" copy treat ESTALE as ENOTSUPP Date: Thu, 10 Oct 2019 08:46:08 -0400 Message-Id: <20191010124622.27812-7-olga.kornievskaia@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20191010124622.27812-1-olga.kornievskaia@gmail.com> References: <20191010124622.27812-1-olga.kornievskaia@gmail.com> Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Olga Kornievskaia If the client sends an "inter" copy to the destination server but it only supports "intra" copy, it can return ESTALE (since it doesn't know anything about the file handle from the other server and does not recognize the special case of "inter" copy). Translate this error as ENOTSUPP and also send OFFLOAD_CANCEL to the source server so that it can clean up state. Signed-off-by: Olga Kornievskaia --- fs/nfs/nfs42proc.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/fs/nfs/nfs42proc.c b/fs/nfs/nfs42proc.c index e34ade8..6ed5a16 100644 --- a/fs/nfs/nfs42proc.c +++ b/fs/nfs/nfs42proc.c @@ -391,6 +391,11 @@ ssize_t nfs42_proc_copy(struct file *src, loff_t pos_src, args.sync = true; dst_exception.retry = 1; continue; + } else if (err == -ESTALE && + !nfs42_files_from_same_server(src, dst)) { + nfs42_do_offload_cancel_async(src, &args.src_stateid); + err = -EOPNOTSUPP; + break; } err2 = nfs4_handle_exception(server, err, &src_exception); From patchwork Thu Oct 10 12:46:09 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Olga Kornievskaia X-Patchwork-Id: 11183453 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C36CE14ED for ; Thu, 10 Oct 2019 12:46:34 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id A3BCE20B7C for ; Thu, 10 Oct 2019 12:46:34 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="aIfDZBHq" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2387858AbfJJMqe (ORCPT ); Thu, 10 Oct 2019 08:46:34 -0400 Received: from mail-io1-f65.google.com ([209.85.166.65]:32859 "EHLO mail-io1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2387801AbfJJMqe (ORCPT ); Thu, 10 Oct 2019 08:46:34 -0400 Received: by mail-io1-f65.google.com with SMTP id z19so13416191ior.0 for ; Thu, 10 Oct 2019 05:46:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=x28Vl5d2oxzfE0+B3js0awQzQgdstOVsyD6DKTtZNjE=; b=aIfDZBHqKluYtejOu9S0tYmibqCeBacYSMkeTboO9JVno+FVOPRzlntfYSz/S++VqV c0KkD4Pe7lbS/8zuFcXVK3hKdrhksolKj3y8VKMKuhda1Yp5Rz7PWXxED9qYBfc80dch vD+ZvihRMlFxBPTiW0biJbo0H9m75otG7RSSzidfCtYUB+SUGG8fDNLqCyrmlYRZm3k8 FXoeEr8O8PqIuURKNz0Ohq/M8a19rvXE1IRcntYpBMSdrAQRgc2GWIQS5LgmreR09FS9 /vXEtZAC0gVtJkFkQGmMUoN0vg4s011AylgZbYCMTw0rt+lKkclaW1f4uOjnY2oi6u45 tOKg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=x28Vl5d2oxzfE0+B3js0awQzQgdstOVsyD6DKTtZNjE=; b=btsbVo//TxNdb7eLEwFYxYhWozLTB/t5A4Tv2QrEJc92T+nzsdkIQSRYgko+zZxCrd 13n72uiq8DTEKQg/PT6LlGKXtmsxeI9gWRdlvFhTY0QwOOWMsNtk8iT/dDsic3L7KuSz LL5rw5qR3JhHgaeze00hJFVnZ0f13sAYruZuZQxIfL9wtKUpNTnSR8c+a+U5syd9LZOr CsGqaoCbNad2ziMD4dWdd7v7WFLie4oWMZTa751QScJbnOfe0ttjdikpZMz68WfnVFa2 /6G1X9MCrlIE4RwslyyOr28vLQ0wALRSaK0yZcQGAD76WsoJGcikDpkhRcLRkh/Zh0Bt uFIQ== X-Gm-Message-State: APjAAAUkJqbjd8R0SMg3SrKpaO4nDnMu92TLJ+i/pVddJ2D3MRRmVkgz WwvTccvCX31fX3otCz2/aU37Z42G X-Google-Smtp-Source: APXvYqzZoATeli2B7siM8Z/kyDgnJUs9VKa8+yARpfZL9QylwLeOMNM6nhjJ8kDPIgpONyZMCSCK1w== X-Received: by 2002:a05:6638:928:: with SMTP id 8mr10130357jak.124.1570711593239; Thu, 10 Oct 2019 05:46:33 -0700 (PDT) Received: from Olgas-MBP-201.attlocal.net (172-10-226-31.lightspeed.livnmi.sbcglobal.net. [172.10.226.31]) by smtp.gmail.com with ESMTPSA id r2sm1100930ilm.17.2019.10.10.05.46.32 (version=TLS1 cipher=AES128-SHA bits=128/128); Thu, 10 Oct 2019 05:46:32 -0700 (PDT) From: Olga Kornievskaia To: trond.myklebust@hammerspace.com, anna.schumaker@netapp.com, bfields@redhat.com Cc: linux-nfs@vger.kernel.org Subject: [PATCH v8 07/20] NFS: COPY handle ERR_OFFLOAD_DENIED Date: Thu, 10 Oct 2019 08:46:09 -0400 Message-Id: <20191010124622.27812-8-olga.kornievskaia@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20191010124622.27812-1-olga.kornievskaia@gmail.com> References: <20191010124622.27812-1-olga.kornievskaia@gmail.com> Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Olga Kornievskaia If server sends ERR_OFFLOAD_DENIED error, the client must fall back on doing copy the normal way. Return ENOTSUPP to the vfs and fallback to regular copy. Signed-off-by: Olga Kornievskaia --- fs/nfs/nfs42proc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/nfs/nfs42proc.c b/fs/nfs/nfs42proc.c index 6ed5a16..50538b9 100644 --- a/fs/nfs/nfs42proc.c +++ b/fs/nfs/nfs42proc.c @@ -391,7 +391,8 @@ ssize_t nfs42_proc_copy(struct file *src, loff_t pos_src, args.sync = true; dst_exception.retry = 1; continue; - } else if (err == -ESTALE && + } else if ((err == -ESTALE || + err == -NFS4ERR_OFFLOAD_DENIED) && !nfs42_files_from_same_server(src, dst)) { nfs42_do_offload_cancel_async(src, &args.src_stateid); err = -EOPNOTSUPP; From patchwork Thu Oct 10 12:46:10 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Olga Kornievskaia X-Patchwork-Id: 11183455 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 4477A1575 for ; Thu, 10 Oct 2019 12:46:36 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 24EE620B7C for ; Thu, 10 Oct 2019 12:46:36 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="hCyciXC+" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2387861AbfJJMqf (ORCPT ); Thu, 10 Oct 2019 08:46:35 -0400 Received: from mail-io1-f66.google.com ([209.85.166.66]:39987 "EHLO mail-io1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2387801AbfJJMqf (ORCPT ); Thu, 10 Oct 2019 08:46:35 -0400 Received: by mail-io1-f66.google.com with SMTP id h144so13282390iof.7 for ; Thu, 10 Oct 2019 05:46:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=WGW8kqXq+lrOvaIN+hIGYmZGzJjyvdoT0qOGs5S/oPk=; b=hCyciXC+5OaCF5ZTkUj2oHxlRKjaA+kZGaSHBmFMJHHHj+rhQ6KCoCpo6CXcT6seij wrfHeUVzjTW1juuJ3ZVZfkAaMvRFQCXx9xcQTxB4qvt9dsIY1zqN9ZjXJ744m9pKW2V5 ZrLFA5Kyw89Lh0uO9GWt4/L/H4sC8ozPHNSdc7ivwf7UzQTU6mljKLWFWEctsv+Zg1Y9 hu6OXibRo+VXUFEfYVRHsyXENTsz15mHGjzEwA+85N08R4v0uMc0CUv0A1sR6or+Stk4 5IzQwVrSCd67V6GO97XXhk3pEV0ifiSftxtKvmrgBOXYJdPp/7R+jlpeTgVyUhxS3LI4 EFHQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=WGW8kqXq+lrOvaIN+hIGYmZGzJjyvdoT0qOGs5S/oPk=; b=JE6nN0I9XH8NDvC9ppnn18vKPw/5mL8U3ZKpXn7DX24hhBfak0AfP1XvdrK8zzGsEa ZvjXECMEZNGsC6mnWXrwv5Ea1km0tXhgKlzcjp+SkjVIadsX0c94CUoK6SveUuXOvrgj 3p+qjuxVVfdmKl/IRvSTB5F0TQGyPsnUzAQsjurPzyOsXeF7UNyZEKLj7feRDcclO2rm SI5bHSXyuRaZ8xSR5qh5M1IZac5Lze8PgKLC3CISWhiNMPAUSCy3U7OcFes6RkbrThzG CcN7RB/48gt8hq6iviu/iBYmMX9qVkAGRkH+AI7q3jk8PoAPXviq2kjMDZzkmZWArvS6 CXlg== X-Gm-Message-State: APjAAAUTSYgzLtIjSDEn0ujfp8AZf8ugHuYdX05MC3GzUaShtMNFB3Am k0QqjvPw2mk3Zc6+P8a83ko= X-Google-Smtp-Source: APXvYqzsIbUN1CvM/1ch7f3hlEstI5jY05pp6SHm2rg7Whm1viItcoDpt7vLAxzUNkXk1p1quDiD5A== X-Received: by 2002:a02:c646:: with SMTP id k6mr10452307jan.141.1570711594435; Thu, 10 Oct 2019 05:46:34 -0700 (PDT) Received: from Olgas-MBP-201.attlocal.net (172-10-226-31.lightspeed.livnmi.sbcglobal.net. [172.10.226.31]) by smtp.gmail.com with ESMTPSA id r2sm1100930ilm.17.2019.10.10.05.46.33 (version=TLS1 cipher=AES128-SHA bits=128/128); Thu, 10 Oct 2019 05:46:33 -0700 (PDT) From: Olga Kornievskaia To: trond.myklebust@hammerspace.com, anna.schumaker@netapp.com, bfields@redhat.com Cc: linux-nfs@vger.kernel.org Subject: [PATCH v8 08/20] NFS: also send OFFLOAD_CANCEL to source server Date: Thu, 10 Oct 2019 08:46:10 -0400 Message-Id: <20191010124622.27812-9-olga.kornievskaia@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20191010124622.27812-1-olga.kornievskaia@gmail.com> References: <20191010124622.27812-1-olga.kornievskaia@gmail.com> Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Olga Kornievskaia In case of copy is cancelled, also send OFFLOAD_CANCEL to the source server. Signed-off-by: Olga Kornievskaia --- fs/nfs/nfs42proc.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/fs/nfs/nfs42proc.c b/fs/nfs/nfs42proc.c index 50538b9..5d833f5 100644 --- a/fs/nfs/nfs42proc.c +++ b/fs/nfs/nfs42proc.c @@ -206,12 +206,14 @@ static int handle_async_copy(struct nfs42_copy_res *res, memcpy(&res->write_res.verifier, ©->verf, sizeof(copy->verf)); status = -copy->error; +out_free: kfree(copy); return status; out_cancel: nfs42_do_offload_cancel_async(dst, ©->stateid); - kfree(copy); - return status; + if (!nfs42_files_from_same_server(src, dst)) + nfs42_do_offload_cancel_async(src, src_stateid); + goto out_free; } static int process_copy_commit(struct file *dst, loff_t pos_dst, @@ -381,7 +383,8 @@ ssize_t nfs42_proc_copy(struct file *src, loff_t pos_src, if (err >= 0) break; - if (err == -ENOTSUPP) { + if (err == -ENOTSUPP && + nfs42_files_from_same_server(src, dst)) { err = -EOPNOTSUPP; break; } else if (err == -EAGAIN) { @@ -392,7 +395,8 @@ ssize_t nfs42_proc_copy(struct file *src, loff_t pos_src, dst_exception.retry = 1; continue; } else if ((err == -ESTALE || - err == -NFS4ERR_OFFLOAD_DENIED) && + err == -NFS4ERR_OFFLOAD_DENIED || + err == -ENOTSUPP) && !nfs42_files_from_same_server(src, dst)) { nfs42_do_offload_cancel_async(src, &args.src_stateid); err = -EOPNOTSUPP; From patchwork Thu Oct 10 12:46:11 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Olga Kornievskaia X-Patchwork-Id: 11183457 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 5C90D1575 for ; Thu, 10 Oct 2019 12:46:37 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 3BB2C2190F for ; Thu, 10 Oct 2019 12:46:37 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="diobS+m1" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2387853AbfJJMqg (ORCPT ); Thu, 10 Oct 2019 08:46:36 -0400 Received: from mail-io1-f68.google.com ([209.85.166.68]:41008 "EHLO mail-io1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2387801AbfJJMqg (ORCPT ); Thu, 10 Oct 2019 08:46:36 -0400 Received: by mail-io1-f68.google.com with SMTP id n26so13271827ioj.8 for ; Thu, 10 Oct 2019 05:46:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=gDbR4PUkDOJDj5ky2g1fhHAP2/+scIqy7aML0qKzZWk=; b=diobS+m1pjDhM9seM908LAuvvhlYJbU3dkS+/aKC0sHYQepK9nH43Qb3GI7rIPdUzh 77ExAK7VnzbM+OHTQyT9Le9Ahc+k+funYpLn0KQq1AhSNvUPt0B9n4s1mWt5anLfFy3L h7Fn+pWMHTiJDyLHQ3pVr5m6/n54X1bwANw2241WUcuEXGjHfp+LzfHEGdZIWtYd+dxH ZecwR5F4qscV40OxovVIMk5s3m5m2FLnysnZHesvkzgqG3phDDZLl1b0gn9zNMOXzb5o f7b4IJ4FTRebNAZAHoW3+et2s8ZAid64tJPS8OM9q7lWBvjRRLBO8V7pVEBVlWj1u2dQ 3O4w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=gDbR4PUkDOJDj5ky2g1fhHAP2/+scIqy7aML0qKzZWk=; b=OHQfnN1QkplXDR4EPqnjcHNZlTju1SaVamjI6f3a2XuFtUfow8ss8hzC2J1a5n+WyS fTb8ahg3VDVolNuV6epUCmYsc51vvgGNvsM5evnBDKaZOwKbx52cPdF9X4k8AqoFMzhI CPwrRZ+xoC3KXnhNUfiQ6QNGhLkUprQWD46obFLA7cqRnLvY9n4GFXB2s2MASnS8NDIr KD+tCKjKk9tsgUiigHAlcx77+UbVhoO8nKBHa5vSR/CqhXvX1oqgFZFvaqsFMkTpCJ2v iHr5fxXTOSPUvAG8BxLFHCJNWvoNvYlj9Iv48sNFFeRlay7vgHBgQSxp5PyPgYdEAOfu kE2w== X-Gm-Message-State: APjAAAWIABqYw7Z/0NVe695xWW4D0fOzlMvUkYvuAv8oRZ1khCHNkbvj skFVCKYqslkZRKznz+FAokA= X-Google-Smtp-Source: APXvYqxXgSrKvAI656cU8m+FafZXZAx63etBD7ryT3Nyedi2oyJMON4RsP8SDMiWrDIuEIHQqfBPIQ== X-Received: by 2002:a02:661d:: with SMTP id k29mr10192092jac.35.1570711595622; Thu, 10 Oct 2019 05:46:35 -0700 (PDT) Received: from Olgas-MBP-201.attlocal.net (172-10-226-31.lightspeed.livnmi.sbcglobal.net. [172.10.226.31]) by smtp.gmail.com with ESMTPSA id r2sm1100930ilm.17.2019.10.10.05.46.34 (version=TLS1 cipher=AES128-SHA bits=128/128); Thu, 10 Oct 2019 05:46:35 -0700 (PDT) From: Olga Kornievskaia To: trond.myklebust@hammerspace.com, anna.schumaker@netapp.com, bfields@redhat.com Cc: linux-nfs@vger.kernel.org Subject: [PATCH v8 09/20] NFS handle NFS4ERR_PARTNER_NO_AUTH error Date: Thu, 10 Oct 2019 08:46:11 -0400 Message-Id: <20191010124622.27812-10-olga.kornievskaia@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20191010124622.27812-1-olga.kornievskaia@gmail.com> References: <20191010124622.27812-1-olga.kornievskaia@gmail.com> Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Olga Kornievskaia When a destination server sends a READ to the source server it can get a NFS4ERR_PARTNER_NO_AUTH, which means a copy needs to be restarted. Signed-off-by: Olga Kornievskaia --- fs/nfs/nfs4proc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index f3a1f8d..a7a55d6 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -475,6 +475,7 @@ static int nfs4_do_handle_exception(struct nfs_server *server, case -NFS4ERR_ADMIN_REVOKED: case -NFS4ERR_EXPIRED: case -NFS4ERR_BAD_STATEID: + case -NFS4ERR_PARTNER_NO_AUTH: if (inode != NULL && stateid != NULL) { nfs_inode_find_state_and_recover(inode, stateid); From patchwork Thu Oct 10 12:46:12 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Olga Kornievskaia X-Patchwork-Id: 11183459 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id CE95F14ED for ; Thu, 10 Oct 2019 12:46:38 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id A59DD208C3 for ; Thu, 10 Oct 2019 12:46:38 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="pU6BUoud" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2387862AbfJJMqi (ORCPT ); Thu, 10 Oct 2019 08:46:38 -0400 Received: from mail-io1-f42.google.com ([209.85.166.42]:43708 "EHLO mail-io1-f42.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2387801AbfJJMqi (ORCPT ); Thu, 10 Oct 2019 08:46:38 -0400 Received: by mail-io1-f42.google.com with SMTP id v2so13283610iob.10 for ; Thu, 10 Oct 2019 05:46:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=hX/ShTw+WInz6eNey28QS29CxfiLdR8jG7cnwQx0M08=; b=pU6BUoudBfJEc5mQ+rzbGKRqDrpSd+ivhMTHRZVLh2eH4TZBGxSetSsA/j0d4ga+kt hkn/wvNAr7m0z6swORWWlEbOCvO4TuHietD5be0EuxUJZBwGRmF69G6eWGcp0LvdDmpX qDXnN19wKHCpoYg7KTu2Fu0API8pzj/oLDZU1Y5057Pb5KVBYiSSql3Q4/a1nmbdCulg UMQiTcVrlynPOUJx+OBDjDqPQxMZO4iT/M7YPCS6WCwgwumInVYkrCMilS79rYYUjqtc bsmSoN1fmALImnVxzQ8gqznyh3HWx78GY6WKswY/ofLLf5sf6KZpQjXvzXTaXSTdSo8q cZ+w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=hX/ShTw+WInz6eNey28QS29CxfiLdR8jG7cnwQx0M08=; b=TRyrW10BIm+NnTZKZ+JSvyX7LpXz01VZGqrfHBrBH/kkDoOcfyai+uWWesWqD8bYW1 hBdSxi5mdvqqvXIZDY8nkOgy9dphb4ZffpmBOwxBM40M5FeV1O2TEuWfX98VVMI4TFRf 1T1G6l758UbFDNfihX5c3I95SZa+fXTUDKjECWXFkDDbN/tfecc84pp+MDZkMZF1iPaA qK7U2rp+YSUAzENkxNZkHYrpMoK8lgfWkcjxs5HE0VqeM5id2Zs6pxRO/jrBFmfdM/gd ApqLNk48U1duIvybta5npmBtXMIaYWIa6dMzM1WirT8naN9elZw/q7RtYrcEtnnrbULv Oq0A== X-Gm-Message-State: APjAAAWZrA2OqNFRALnIPTs9g5X0EPjxG1DeURt9F882pWEZvh0oFJcN 394WHa85aKrz8vDs4wBF38Y= X-Google-Smtp-Source: APXvYqxaNZT1Me0v8Bz0RAaMR+bgdF11yYVeEBPnhj25yusFtuyOKNXb8mfYBMEMHjT101zUFYE7wQ== X-Received: by 2002:a92:9f0d:: with SMTP id u13mr9691ili.13.1570711596704; Thu, 10 Oct 2019 05:46:36 -0700 (PDT) Received: from Olgas-MBP-201.attlocal.net (172-10-226-31.lightspeed.livnmi.sbcglobal.net. [172.10.226.31]) by smtp.gmail.com with ESMTPSA id r2sm1100930ilm.17.2019.10.10.05.46.35 (version=TLS1 cipher=AES128-SHA bits=128/128); Thu, 10 Oct 2019 05:46:36 -0700 (PDT) From: Olga Kornievskaia To: trond.myklebust@hammerspace.com, anna.schumaker@netapp.com, bfields@redhat.com Cc: linux-nfs@vger.kernel.org Subject: [PATCH v8 10/20] NFS: handle source server reboot Date: Thu, 10 Oct 2019 08:46:12 -0400 Message-Id: <20191010124622.27812-11-olga.kornievskaia@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20191010124622.27812-1-olga.kornievskaia@gmail.com> References: <20191010124622.27812-1-olga.kornievskaia@gmail.com> Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Olga Kornievskaia When the source server reboots after a server-to-server copy was issued, we need to retry the copy from COPY_NOTIFY. We need to detect that the source server rebooted and there is a copy waiting on a destination server and wake it up. Signed-off-by: Olga Kornievskaia --- fs/nfs/nfs42proc.c | 68 ++++++++++++++++++++++++++++++++++---------------- fs/nfs/nfs4_fs.h | 1 + fs/nfs/nfs4file.c | 3 +++ fs/nfs/nfs4state.c | 26 +++++++++++++++---- include/linux/nfs_fs.h | 4 ++- 5 files changed, 75 insertions(+), 27 deletions(-) diff --git a/fs/nfs/nfs42proc.c b/fs/nfs/nfs42proc.c index 5d833f5..9c7feac 100644 --- a/fs/nfs/nfs42proc.c +++ b/fs/nfs/nfs42proc.c @@ -153,22 +153,26 @@ int nfs42_proc_deallocate(struct file *filep, loff_t offset, loff_t len) } static int handle_async_copy(struct nfs42_copy_res *res, - struct nfs_server *server, + struct nfs_server *dst_server, + struct nfs_server *src_server, struct file *src, struct file *dst, - nfs4_stateid *src_stateid) + nfs4_stateid *src_stateid, + bool *restart) { struct nfs4_copy_state *copy, *tmp_copy; int status = NFS4_OK; bool found_pending = false; - struct nfs_open_context *ctx = nfs_file_open_context(dst); + struct nfs_open_context *dst_ctx = nfs_file_open_context(dst); + struct nfs_open_context *src_ctx = nfs_file_open_context(src); copy = kzalloc(sizeof(struct nfs4_copy_state), GFP_NOFS); if (!copy) return -ENOMEM; - spin_lock(&server->nfs_client->cl_lock); - list_for_each_entry(tmp_copy, &server->nfs_client->pending_cb_stateids, + spin_lock(&dst_server->nfs_client->cl_lock); + list_for_each_entry(tmp_copy, + &dst_server->nfs_client->pending_cb_stateids, copies) { if (memcmp(&res->write_res.stateid, &tmp_copy->stateid, NFS4_STATEID_SIZE)) @@ -178,7 +182,7 @@ static int handle_async_copy(struct nfs42_copy_res *res, break; } if (found_pending) { - spin_unlock(&server->nfs_client->cl_lock); + spin_unlock(&dst_server->nfs_client->cl_lock); kfree(copy); copy = tmp_copy; goto out; @@ -186,19 +190,32 @@ 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; + copy->parent_dst_state = dst_ctx->state; + copy->parent_src_state = src_ctx->state; + + list_add_tail(©->copies, &dst_server->ss_copies); + spin_unlock(&dst_server->nfs_client->cl_lock); - list_add_tail(©->copies, &server->ss_copies); - spin_unlock(&server->nfs_client->cl_lock); + if (dst_server != src_server) { + spin_lock(&src_server->nfs_client->cl_lock); + list_add_tail(©->src_copies, &src_server->ss_copies); + spin_unlock(&src_server->nfs_client->cl_lock); + } status = wait_for_completion_interruptible(©->completion); - spin_lock(&server->nfs_client->cl_lock); + spin_lock(&dst_server->nfs_client->cl_lock); list_del_init(©->copies); - spin_unlock(&server->nfs_client->cl_lock); + spin_unlock(&dst_server->nfs_client->cl_lock); + if (dst_server != src_server) { + spin_lock(&src_server->nfs_client->cl_lock); + list_del_init(©->src_copies); + spin_unlock(&src_server->nfs_client->cl_lock); + } if (status == -ERESTARTSYS) { goto out_cancel; - } else if (copy->flags) { + } else if (copy->flags || copy->error == NFS4ERR_PARTNER_NO_AUTH) { status = -EAGAIN; + *restart = true; goto out_cancel; } out: @@ -247,7 +264,8 @@ static ssize_t _nfs42_proc_copy(struct file *src, struct nfs42_copy_args *args, struct nfs42_copy_res *res, struct nl4_server *nss, - nfs4_stateid *cnr_stateid) + nfs4_stateid *cnr_stateid, + bool *restart) { struct rpc_message msg = { .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_COPY], @@ -255,7 +273,9 @@ static ssize_t _nfs42_proc_copy(struct file *src, .rpc_resp = res, }; struct inode *dst_inode = file_inode(dst); - struct nfs_server *server = NFS_SERVER(dst_inode); + struct inode *src_inode = file_inode(src); + struct nfs_server *dst_server = NFS_SERVER(dst_inode); + struct nfs_server *src_server = NFS_SERVER(src_inode); loff_t pos_src = args->src_pos; loff_t pos_dst = args->dst_pos; size_t count = args->count; @@ -291,13 +311,15 @@ static ssize_t _nfs42_proc_copy(struct file *src, if (!res->commit_res.verf) return -ENOMEM; } + set_bit(NFS_CLNT_SRC_SSC_COPY_STATE, + &src_lock->open_context->state->flags); set_bit(NFS_CLNT_DST_SSC_COPY_STATE, &dst_lock->open_context->state->flags); - status = nfs4_call_sync(server->client, server, &msg, + status = nfs4_call_sync(dst_server->client, dst_server, &msg, &args->seq_args, &res->seq_res, 0); if (status == -ENOTSUPP) - server->caps &= ~NFS_CAP_COPY; + dst_server->caps &= ~NFS_CAP_COPY; if (status) goto out; @@ -309,8 +331,8 @@ static ssize_t _nfs42_proc_copy(struct file *src, } if (!res->synchronous) { - status = handle_async_copy(res, server, src, dst, - &args->src_stateid); + status = handle_async_copy(res, dst_server, src_server, src, + dst, &args->src_stateid, restart); if (status) return status; } @@ -358,6 +380,7 @@ ssize_t nfs42_proc_copy(struct file *src, loff_t pos_src, .stateid = &args.dst_stateid, }; ssize_t err, err2; + bool restart = false; src_lock = nfs_get_lock_context(nfs_file_open_context(src)); if (IS_ERR(src_lock)) @@ -378,7 +401,7 @@ ssize_t nfs42_proc_copy(struct file *src, loff_t pos_src, err = _nfs42_proc_copy(src, src_lock, dst, dst_lock, &args, &res, - nss, cnr_stateid); + nss, cnr_stateid, &restart); inode_unlock(file_inode(dst)); if (err >= 0) @@ -388,8 +411,11 @@ ssize_t nfs42_proc_copy(struct file *src, loff_t pos_src, err = -EOPNOTSUPP; break; } else if (err == -EAGAIN) { - dst_exception.retry = 1; - continue; + if (!restart) { + dst_exception.retry = 1; + continue; + } + break; } else if (err == -NFS4ERR_OFFLOAD_NO_REQS && !args.sync) { args.sync = true; dst_exception.retry = 1; diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h index 814674f..2122748 100644 --- a/fs/nfs/nfs4_fs.h +++ b/fs/nfs/nfs4_fs.h @@ -168,6 +168,7 @@ enum { NFS_STATE_CHANGE_WAIT, /* A state changing operation is outstanding */ #ifdef CONFIG_NFS_V4_2 NFS_CLNT_DST_SSC_COPY_STATE, /* dst server open state on client*/ + NFS_CLNT_SRC_SSC_COPY_STATE, /* src server open state on client*/ NFS_SRV_SSC_COPY_STATE, /* ssc state on the dst server */ #endif /* CONFIG_NFS_V4_2 */ }; diff --git a/fs/nfs/nfs4file.c b/fs/nfs/nfs4file.c index a932fc9..2af30b7 100644 --- a/fs/nfs/nfs4file.c +++ b/fs/nfs/nfs4file.c @@ -146,6 +146,7 @@ static ssize_t __nfs4_copy_file_range(struct file *file_in, loff_t pos_in, return -EOPNOTSUPP; if (file_inode(file_in) == file_inode(file_out)) return -EOPNOTSUPP; +retry: if (!nfs42_files_from_same_server(file_in, file_out)) { cn_resp = kzalloc(sizeof(struct nfs42_copy_notify_res), GFP_NOFS); @@ -164,6 +165,8 @@ static ssize_t __nfs4_copy_file_range(struct file *file_in, loff_t pos_in, nss, cnrs); out: kfree(cn_resp); + if (ret == -EAGAIN) + goto retry; return ret; } diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index c45b300..e799fbe 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c @@ -1556,16 +1556,32 @@ static void nfs42_complete_copies(struct nfs4_state_owner *sp, struct nfs4_state { struct nfs4_copy_state *copy; - if (!test_bit(NFS_CLNT_DST_SSC_COPY_STATE, &state->flags)) + if (!test_bit(NFS_CLNT_DST_SSC_COPY_STATE, &state->flags) && + !test_bit(NFS_CLNT_SRC_SSC_COPY_STATE, &state->flags)) return; spin_lock(&sp->so_server->nfs_client->cl_lock); list_for_each_entry(copy, &sp->so_server->ss_copies, copies) { - if (!nfs4_stateid_match_other(&state->stateid, ©->parent_state->stateid)) - continue; + if ((test_bit(NFS_CLNT_DST_SSC_COPY_STATE, &state->flags) && + !nfs4_stateid_match_other(&state->stateid, + ©->parent_dst_state->stateid))) + continue; copy->flags = 1; - complete(©->completion); - break; + if (test_and_clear_bit(NFS_CLNT_DST_SSC_COPY_STATE, + &state->flags)) { + clear_bit(NFS_CLNT_SRC_SSC_COPY_STATE, &state->flags); + complete(©->completion); + } + } + list_for_each_entry(copy, &sp->so_server->ss_copies, src_copies) { + if ((test_bit(NFS_CLNT_SRC_SSC_COPY_STATE, &state->flags) && + !nfs4_stateid_match_other(&state->stateid, + ©->parent_src_state->stateid))) + continue; + copy->flags = 1; + if (test_and_clear_bit(NFS_CLNT_DST_SSC_COPY_STATE, + &state->flags)) + complete(©->completion); } spin_unlock(&sp->so_server->nfs_client->cl_lock); } diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h index 570a60c..c06b1fd 100644 --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h @@ -189,13 +189,15 @@ struct nfs_inode { struct nfs4_copy_state { struct list_head copies; + struct list_head src_copies; nfs4_stateid stateid; struct completion completion; uint64_t count; struct nfs_writeverf verf; int error; int flags; - struct nfs4_state *parent_state; + struct nfs4_state *parent_src_state; + struct nfs4_state *parent_dst_state; }; /* From patchwork Thu Oct 10 12:46:13 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Olga Kornievskaia X-Patchwork-Id: 11183463 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id F245014ED for ; Thu, 10 Oct 2019 12:46:59 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id CA9C7206B6 for ; Thu, 10 Oct 2019 12:46:59 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="CL1+oQMs" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2387801AbfJJMq7 (ORCPT ); Thu, 10 Oct 2019 08:46:59 -0400 Received: from mail-io1-f65.google.com ([209.85.166.65]:42941 "EHLO mail-io1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2387594AbfJJMq7 (ORCPT ); Thu, 10 Oct 2019 08:46:59 -0400 Received: by mail-io1-f65.google.com with SMTP id n197so13264055iod.9 for ; Thu, 10 Oct 2019 05:46:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=Hshp1oYTyfoMLQ+k0J7lOTxVumPki+FPii/qZM5aFiM=; b=CL1+oQMsN76oSfwZVBht+iaUcD7wsqKhUj0GEXgDeCfYAU6NHI2S8QO1JKS23CxLxi +b+cnQBl0t4zRvJri4N1iNvOyBTU0JeFtPO2MnH+LXKH7aNeLAaAXEtb7VZD73bO6lJG LIJhX6gT9wEglfetxlzasxvv/+WF+YhJ/QU8aW7pDSNRCFkSl5RqU2MINRBOnrjJ+caB /WyXmbTuRoTpoBWMmDPKq4rS4+S8KTwELoffxuJppIrpuT2x9CmTrPJk5dr9xk6XyduY +MesG1mK+aiP+SyC6n0gVZ12iIH/wDss9f5a9RM5jfWlTvM7rp8xy6Brc5XNoaTU9LAL 1geA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=Hshp1oYTyfoMLQ+k0J7lOTxVumPki+FPii/qZM5aFiM=; b=TlntV+Pp9si+O3i96KWBVvqAAT9osvGdGRSjsSR2fIV0GdQzp9Us3TthqXa+mclyUf sgQIfOkPCirm5z6pRdqAQufJ9StNCeQscXwJqSSCmwI+5OQ1Ftco79xj/rVMR17wlA6h fcCus8WfW88vTlothhDY/TK0bz5FhRVC8FnOqYXgMXRG4dwkN1gtSnaLy61KIC0SL41E PTeGo+OvvY7BP0b0Nw4SouNnVk9Kv3k8FgEpCKRR2QQMTiNTrGkul6OecrhJ+8l9trMt wuw7tCsJqLBKF7ar11Zqvw8QwEqIoxiv3pjfAwWWyFelKA5/Uv6s4QOlGLYyNel8kgjn ua5A== X-Gm-Message-State: APjAAAWz2PRXwBG2QS5yDyFnAFCjoxjehuEIlvoclCoCYgIwU56QVNLU gTkGLdtESz+yIj2Sh3gXOg8= X-Google-Smtp-Source: APXvYqyioYCLMu4aJmSNPoFm9rht+TZWNZSaJlCfxU+3e28tcRgJTaPxxVvL04uF4yOA5cuobLjEdw== X-Received: by 2002:a5d:8b48:: with SMTP id c8mr10036698iot.64.1570711617953; Thu, 10 Oct 2019 05:46:57 -0700 (PDT) Received: from Olgas-MBP-201.attlocal.net (172-10-226-31.lightspeed.livnmi.sbcglobal.net. [172.10.226.31]) by smtp.gmail.com with ESMTPSA id r2sm1100930ilm.17.2019.10.10.05.46.37 (version=TLS1 cipher=AES128-SHA bits=128/128); Thu, 10 Oct 2019 05:46:37 -0700 (PDT) From: Olga Kornievskaia To: trond.myklebust@hammerspace.com, anna.schumaker@netapp.com, bfields@redhat.com Cc: linux-nfs@vger.kernel.org Subject: [PATCH v8 11/20] NFS based on file size issue sync copy or fallback to generic copy offload Date: Thu, 10 Oct 2019 08:46:13 -0400 Message-Id: <20191010124622.27812-12-olga.kornievskaia@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20191010124622.27812-1-olga.kornievskaia@gmail.com> References: <20191010124622.27812-1-olga.kornievskaia@gmail.com> Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Olga Kornievskaia For small file sizes, it make sense to issue a synchronous copy (and save an RPC callback operation). Also, for the inter copy offload, copy len must be larger than the cost of doing a mount between the destination and source server (14RPCs are sent during 4.x mount). Signed-off-by: Olga Kornievskaia --- fs/nfs/nfs42.h | 2 +- fs/nfs/nfs42proc.c | 4 ++-- fs/nfs/nfs4file.c | 16 +++++++++++++++- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/fs/nfs/nfs42.h b/fs/nfs/nfs42.h index 02e3810..c891af9 100644 --- a/fs/nfs/nfs42.h +++ b/fs/nfs/nfs42.h @@ -16,7 +16,7 @@ #ifdef CONFIG_NFS_V4_2 int nfs42_proc_allocate(struct file *, loff_t, loff_t); ssize_t nfs42_proc_copy(struct file *, loff_t, struct file *, loff_t, size_t, - struct nl4_server *, nfs4_stateid *); + struct nl4_server *, nfs4_stateid *, bool); int nfs42_proc_deallocate(struct file *, loff_t, loff_t); loff_t nfs42_proc_llseek(struct file *, loff_t, int); int nfs42_proc_layoutstats_generic(struct nfs_server *, diff --git a/fs/nfs/nfs42proc.c b/fs/nfs/nfs42proc.c index 9c7feac..aab6b7b 100644 --- a/fs/nfs/nfs42proc.c +++ b/fs/nfs/nfs42proc.c @@ -357,7 +357,7 @@ static ssize_t _nfs42_proc_copy(struct file *src, ssize_t nfs42_proc_copy(struct file *src, loff_t pos_src, struct file *dst, loff_t pos_dst, size_t count, struct nl4_server *nss, - nfs4_stateid *cnr_stateid) + nfs4_stateid *cnr_stateid, bool sync) { struct nfs_server *server = NFS_SERVER(file_inode(dst)); struct nfs_lock_context *src_lock; @@ -368,7 +368,7 @@ ssize_t nfs42_proc_copy(struct file *src, loff_t pos_src, .dst_fh = NFS_FH(file_inode(dst)), .dst_pos = pos_dst, .count = count, - .sync = false, + .sync = sync, }; struct nfs42_copy_res res; struct nfs4_exception src_exception = { diff --git a/fs/nfs/nfs4file.c b/fs/nfs/nfs4file.c index 2af30b7..8978325 100644 --- a/fs/nfs/nfs4file.c +++ b/fs/nfs/nfs4file.c @@ -138,6 +138,7 @@ static ssize_t __nfs4_copy_file_range(struct file *file_in, loff_t pos_in, struct nl4_server *nss = NULL; nfs4_stateid *cnrs = NULL; ssize_t ret; + bool sync = false; /* Only offload copy if superblock is the same */ if (file_inode(file_in)->i_sb != file_inode(file_out)->i_sb) @@ -146,8 +147,21 @@ static ssize_t __nfs4_copy_file_range(struct file *file_in, loff_t pos_in, return -EOPNOTSUPP; if (file_inode(file_in) == file_inode(file_out)) return -EOPNOTSUPP; + /* if the copy size if smaller than 2 RPC payloads, make it + * synchronous + */ + if (count <= 2 * NFS_SERVER(file_inode(file_in))->rsize) + sync = true; retry: if (!nfs42_files_from_same_server(file_in, file_out)) { + /* for inter copy, if copy size if smaller than 12 RPC + * payloads, fallback to traditional copy. There are + * 14 RPCs during an NFSv4.x mount between source/dest + * servers. + */ + if (sync || + count <= 14 * NFS_SERVER(file_inode(file_in))->rsize) + return -EOPNOTSUPP; cn_resp = kzalloc(sizeof(struct nfs42_copy_notify_res), GFP_NOFS); if (unlikely(cn_resp == NULL)) @@ -162,7 +176,7 @@ static ssize_t __nfs4_copy_file_range(struct file *file_in, loff_t pos_in, cnrs = &cn_resp->cnr_stateid; } ret = nfs42_proc_copy(file_in, pos_in, file_out, pos_out, count, - nss, cnrs); + nss, cnrs, sync); out: kfree(cn_resp); if (ret == -EAGAIN) From patchwork Thu Oct 10 12:46:14 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Olga Kornievskaia X-Patchwork-Id: 11183465 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id F02EF1575 for ; Thu, 10 Oct 2019 12:47:00 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id CB8F1206B6 for ; Thu, 10 Oct 2019 12:47:00 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="BIfRQ15m" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2387837AbfJJMrA (ORCPT ); Thu, 10 Oct 2019 08:47:00 -0400 Received: from mail-io1-f67.google.com ([209.85.166.67]:32955 "EHLO mail-io1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2387594AbfJJMrA (ORCPT ); Thu, 10 Oct 2019 08:47:00 -0400 Received: by mail-io1-f67.google.com with SMTP id z19so13419011ior.0 for ; Thu, 10 Oct 2019 05:46:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=DHogwM9yh21IPOZJm0MZ7NabpMkBthG6hKASAxm7swM=; b=BIfRQ15m7uVGjXBNUv+gYVGZbS24VQU9Cz47Tg/7FvAUuK1EB/dw0DG1vKgeMq1KEZ qImo8SoZ13VzSqtydDRjlBbk3BjuT0w8tKHCsI7TfJjdBsYdLcvQpSU2oZYetNuLkORf QiNx0daKvbQXJIBXVLcMIYZhHW1gi6keylp7t/B6j7XASxeonfgNDXHaYW/LERCTQPf1 mdsDh54HTKLI1K99AE0XInLwFLGn8RvsKzFS+zBesoR1MAbbOMxzs4qh6Epz5B8EJQCW I9G2/c0qFmvOiGFhONb86mJuLCn7pcWhahMYn2YmeNbSK1f6/6PVxzo4UYTZcSX4bEBg a1sQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=DHogwM9yh21IPOZJm0MZ7NabpMkBthG6hKASAxm7swM=; b=NhXDrScrhRKKfYZ1xCIRMQkPuU69NcX9k7oJEmUqxQH5+qF1vGR83uMyXSbGYjg6Iz asmsyDM6f+8cFFzOHy2SXgh8l/BxABB3sK3YdA8y9TQTpxr+RIRPPmRza55XmEVr/Brk Htyn/NRb3ei6ZxrSiyrApDqTtQoGRh8Lh6QQm6ToSn+MKD2pNcHRyKp7BFTAPEwp0bt1 6xXpy85YxrT0U7Id0mP0imYtCCkcf43fpYoLYBMef2UNp6Fsp80CJbJ4SuTWzhjfIkDq N6XXK7bXDVhkSfIt8UHodGA6TaLiHzKGvfGNtYbSC6Gp9YNbxlRJz273GKsp9e93+fKn Pylg== X-Gm-Message-State: APjAAAVhQ60fH6rQG2qQDiaUNouNKQFt/TJKEqi8qVs9F7spVjKlnleT 1TmgVhZjd6VMpQRf67Hizv8= X-Google-Smtp-Source: APXvYqxwNUP/2cPC0F5gVU3O1e1vpfVKnQVrzVwBACKoYxUz/3qduLH9DroETQ1vTbu5X69wqi2pmw== X-Received: by 2002:a6b:e415:: with SMTP id u21mr10064124iog.144.1570711619359; Thu, 10 Oct 2019 05:46:59 -0700 (PDT) Received: from Olgas-MBP-201.attlocal.net (172-10-226-31.lightspeed.livnmi.sbcglobal.net. [172.10.226.31]) by smtp.gmail.com with ESMTPSA id r2sm1100930ilm.17.2019.10.10.05.46.58 (version=TLS1 cipher=AES128-SHA bits=128/128); Thu, 10 Oct 2019 05:46:58 -0700 (PDT) From: Olga Kornievskaia To: trond.myklebust@hammerspace.com, anna.schumaker@netapp.com, bfields@redhat.com Cc: linux-nfs@vger.kernel.org Subject: [PATCH v8 12/20] NFS: replace cross device check in copy_file_range Date: Thu, 10 Oct 2019 08:46:14 -0400 Message-Id: <20191010124622.27812-13-olga.kornievskaia@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20191010124622.27812-1-olga.kornievskaia@gmail.com> References: <20191010124622.27812-1-olga.kornievskaia@gmail.com> Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Olga Kornievskaia Add a check to disallow cross file systems copy offload, both files are expected to be of NFS4.2+ type. Reviewed-by: Jeff Layton Reviewed-by: Matthew Wilcox Signed-off-by: Olga Kornievskaia --- fs/nfs/nfs4file.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/nfs/nfs4file.c b/fs/nfs/nfs4file.c index 8978325..e97813b 100644 --- a/fs/nfs/nfs4file.c +++ b/fs/nfs/nfs4file.c @@ -141,7 +141,7 @@ static ssize_t __nfs4_copy_file_range(struct file *file_in, loff_t pos_in, bool sync = false; /* Only offload copy if superblock is the same */ - if (file_inode(file_in)->i_sb != file_inode(file_out)->i_sb) + if (file_in->f_op != &nfs4_file_operations) return -EXDEV; if (!nfs_server_capable(file_inode(file_out), NFS_CAP_COPY)) return -EOPNOTSUPP; From patchwork Thu Oct 10 12:46:15 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Olga Kornievskaia X-Patchwork-Id: 11183467 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id F08D314ED for ; Thu, 10 Oct 2019 12:47:01 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id D0194206B6 for ; Thu, 10 Oct 2019 12:47:01 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="ApSOMcr1" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2387860AbfJJMrB (ORCPT ); Thu, 10 Oct 2019 08:47:01 -0400 Received: from mail-io1-f66.google.com ([209.85.166.66]:39848 "EHLO mail-io1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2387594AbfJJMrB (ORCPT ); Thu, 10 Oct 2019 08:47:01 -0400 Received: by mail-io1-f66.google.com with SMTP id a1so13334819ioc.6 for ; Thu, 10 Oct 2019 05:47:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=oYFP7LnHnffo4j/n4viWpRrrs/1IS/MsGu8QY/P3UN4=; b=ApSOMcr1yUQwVOzZymeBElC9ryUuopJvqSGcUe16g1XV2Nlk5P4irFpXf3f3cvdpeW PwbI0S5l7CxP9AalDESHrlAM5ktIdKBO6OIGp/ZzoWJP+knKjaecsQpHb57CNpin0dfm Sw2s7uSz2te118/CsFO88ddY1/1V8TOB80LHolKGWYiisOkWs4/rkxIE4b+rTZN4/jqX aqoYY9KQJLTpljRO3jejN8YgUwIecseLBJz/w+MBWFYRiP2uSZAYw/ct+GQHI+glF22q 07RC8K38SnxDO17FItkBAAcuLw4uPuVDCa0ZAEuL/sRvhFh2cpaeUPlC+KxoTiIv0+d/ TzXw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=oYFP7LnHnffo4j/n4viWpRrrs/1IS/MsGu8QY/P3UN4=; b=gCvXEBmAfLrQEYfqcjbTpUyYxgnkzQMlY/RavF9P0V9Ai+1kQDp2QS4YV415AKrv+h KmwvK8zxx+mucgsUa+UJdchV3FsgD7NcQKCWOw46MdQ7qqgnS77uB+nsMVCrb3FU1oPi v2SozkL1EiSshgKM4Ss720nZANPYjxuv9jFgA5pySl2cg1mavh/2shwCewYMXrykgx1N rC4gZoZMpcBZHCwQ1oBKHACeJJectB3tC+3YMbHDKjrtpUrsrYhqDNHCl/NcNZt8mMaK MLDfr65qgeRdf/o0QtrxuAFrSOgf7U0XZ7IJ3HLwI9vi09B/3OejnhCJbzZYeCS5aIO1 VtoQ== X-Gm-Message-State: APjAAAUNls7nTPrJK1GAnXAdjZgdn79VM/s6bAGs6FUY5aTaQW30rCW9 JFTaWY7DepjqBD8dKNa+l+A= X-Google-Smtp-Source: APXvYqxIRbX5LSqGFkMkvxYy+uS1Yr7qDt4+VjziBcXBFGuaDhGphHAqAMG5bR8DtqqzksokAtbjdw== X-Received: by 2002:a6b:16c4:: with SMTP id 187mr9887629iow.88.1570711620327; Thu, 10 Oct 2019 05:47:00 -0700 (PDT) Received: from Olgas-MBP-201.attlocal.net (172-10-226-31.lightspeed.livnmi.sbcglobal.net. [172.10.226.31]) by smtp.gmail.com with ESMTPSA id r2sm1100930ilm.17.2019.10.10.05.46.59 (version=TLS1 cipher=AES128-SHA bits=128/128); Thu, 10 Oct 2019 05:46:59 -0700 (PDT) From: Olga Kornievskaia To: trond.myklebust@hammerspace.com, anna.schumaker@netapp.com, bfields@redhat.com Cc: linux-nfs@vger.kernel.org Subject: [PATCH v8 13/20] NFSD fill-in netloc4 structure Date: Thu, 10 Oct 2019 08:46:15 -0400 Message-Id: <20191010124622.27812-14-olga.kornievskaia@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20191010124622.27812-1-olga.kornievskaia@gmail.com> References: <20191010124622.27812-1-olga.kornievskaia@gmail.com> Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Olga Kornievskaia nfs.4 defines nfs42_netaddr structure that represents netloc4. Populate needed fields from the sockaddr structure. This will be used by flexfiles and 4.2 inter copy Signed-off-by: Olga Kornievskaia --- fs/nfsd/nfsd.h | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/fs/nfsd/nfsd.h b/fs/nfsd/nfsd.h index af29475..687f8e1 100644 --- a/fs/nfsd/nfsd.h +++ b/fs/nfsd/nfsd.h @@ -19,6 +19,7 @@ #include #include #include +#include #include @@ -386,6 +387,37 @@ static inline bool nfsd4_spo_must_allow(struct svc_rqst *rqstp) extern const u32 nfsd_suppattrs[3][3]; +static inline u32 nfsd4_set_netaddr(struct sockaddr *addr, + struct nfs42_netaddr *netaddr) +{ + struct sockaddr_in *sin = (struct sockaddr_in *)addr; + struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)addr; + unsigned int port; + size_t ret_addr, ret_port; + + switch (addr->sa_family) { + case AF_INET: + port = ntohs(sin->sin_port); + sprintf(netaddr->netid, "tcp"); + netaddr->netid_len = 3; + break; + case AF_INET6: + port = ntohs(sin6->sin6_port); + sprintf(netaddr->netid, "tcp6"); + netaddr->netid_len = 4; + break; + default: + return nfserr_inval; + } + ret_addr = rpc_ntop(addr, netaddr->addr, sizeof(netaddr->addr)); + ret_port = snprintf(netaddr->addr + ret_addr, + RPCBIND_MAXUADDRLEN + 1 - ret_addr, + ".%u.%u", port >> 8, port & 0xff); + WARN_ON(ret_port >= RPCBIND_MAXUADDRLEN + 1 - ret_addr); + netaddr->addr_len = ret_addr + ret_port; + return 0; +} + static inline bool bmval_is_subset(const u32 *bm1, const u32 *bm2) { return !((bm1[0] & ~bm2[0]) || From patchwork Thu Oct 10 12:46:16 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Olga Kornievskaia X-Patchwork-Id: 11183469 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 9BECC14ED for ; Thu, 10 Oct 2019 12:47:03 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 7886D206B6 for ; Thu, 10 Oct 2019 12:47:03 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="WGuqhtGv" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2387835AbfJJMrD (ORCPT ); Thu, 10 Oct 2019 08:47:03 -0400 Received: from mail-io1-f67.google.com ([209.85.166.67]:32962 "EHLO mail-io1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2387594AbfJJMrC (ORCPT ); Thu, 10 Oct 2019 08:47:02 -0400 Received: by mail-io1-f67.google.com with SMTP id z19so13419252ior.0 for ; Thu, 10 Oct 2019 05:47:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=/NupQn80iXcPRsFgSHA/qnApzmOsUuVJ7pplKwsr+kQ=; b=WGuqhtGvuiuxjp6CyFeJvnGQKbi04AFXJC+hgBTbRSp97eQmDed1sowlyqRUr7rQQD 0upxh3QnFH/5P03p7DxPxfVQ04wzBDvZ5m0ZLVkON33EDIxhwlncaI+tqdjCKWyoodpx 6wwSLaBGkgs01+cIPOdkbPHA6XnrJbUjwp1hk9CckzqaU4H4DnXedRZZdUKjsD/RsvPf RoC46uoAnApqxZuDOW9AvGaZcE4ZFaN+BQwCX2hCy+gnXU0h+fRwME0dtihDeFSKmTuF ++2Hp5NSgRDKbnczJxkrkzRMZSICfhwoyWvGAnwlKEs4KHCqNYFJ8mNEVgnwlVt4k39h fJ1w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=/NupQn80iXcPRsFgSHA/qnApzmOsUuVJ7pplKwsr+kQ=; b=eaFSHyZsnKX872ljvE+6DdNFEMck8DZo0wQ9LeYFhZ85BXuSV18oXlZlbTzkgPamlV SQ+m7NQTa640ugSqNwSWUHebthommcIuf2307qTG4dC0V55RSelr0HyDzDqsBCbGvIRz FeB691nTiYH1w2wHWqhh+X09Rz/iwUqVsT6+or5iWwtwTcf58b2mdktavySoBD1k5+3t fIOI2M/SHk5nG1vnubX1Sl2PZysrLuvbPpcft/SZmRefOHxN4/4MlLBqr1h1+mQHh/1M pJr55K/ZY40R+FwPxGF0rxvsARgzF1iZg0K9PINjJNbzQZmynBQtl+RreLnbzFsEw9A0 id0w== X-Gm-Message-State: APjAAAVW6nJu/J4xIksKUxXopQ/2Y/xZIu8BoG/MuD6v34pmalIhHfz3 O2wSWTNDHY+DKPhBOIOYS2o= X-Google-Smtp-Source: APXvYqxbN5tUv6AyUydS+7t9WzMtbj5x5x1QIeiew+M7Cg0FDuhxqovzVbY0ioU37/OlKaygzmeAig== X-Received: by 2002:a5d:8156:: with SMTP id f22mr10260325ioo.234.1570711621616; Thu, 10 Oct 2019 05:47:01 -0700 (PDT) Received: from Olgas-MBP-201.attlocal.net (172-10-226-31.lightspeed.livnmi.sbcglobal.net. [172.10.226.31]) by smtp.gmail.com with ESMTPSA id r2sm1100930ilm.17.2019.10.10.05.47.00 (version=TLS1 cipher=AES128-SHA bits=128/128); Thu, 10 Oct 2019 05:47:01 -0700 (PDT) From: Olga Kornievskaia To: trond.myklebust@hammerspace.com, anna.schumaker@netapp.com, bfields@redhat.com Cc: linux-nfs@vger.kernel.org Subject: [PATCH v8 14/20] NFSD add ca_source_server<> to COPY Date: Thu, 10 Oct 2019 08:46:16 -0400 Message-Id: <20191010124622.27812-15-olga.kornievskaia@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20191010124622.27812-1-olga.kornievskaia@gmail.com> References: <20191010124622.27812-1-olga.kornievskaia@gmail.com> Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org Decode the ca_source_server list that's sent but only use the first one. Presence of non-zero list indicates an "inter" copy. Signed-off-by: Andy Adamson Signed-off-by: Olga Kornievskaia --- fs/nfsd/nfs4xdr.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- fs/nfsd/xdr4.h | 12 +++++----- 2 files changed, 71 insertions(+), 6 deletions(-) diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 533d0fc..a664c18 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -40,6 +40,7 @@ #include #include #include +#include #include "idmap.h" #include "acl.h" @@ -1744,10 +1745,47 @@ static __be32 nfsd4_decode_reclaim_complete(struct nfsd4_compoundargs *argp, str DECODE_TAIL; } +static __be32 nfsd4_decode_nl4_server(struct nfsd4_compoundargs *argp, + struct nl4_server *ns) +{ + DECODE_HEAD; + struct nfs42_netaddr *naddr; + + READ_BUF(4); + ns->nl4_type = be32_to_cpup(p++); + + /* currently support for 1 inter-server source server */ + switch (ns->nl4_type) { + case NL4_NETADDR: + naddr = &ns->u.nl4_addr; + + READ_BUF(4); + naddr->netid_len = be32_to_cpup(p++); + if (naddr->netid_len > RPCBIND_MAXNETIDLEN) + goto xdr_error; + + READ_BUF(naddr->netid_len + 4); /* 4 for uaddr len */ + COPYMEM(naddr->netid, naddr->netid_len); + + naddr->addr_len = be32_to_cpup(p++); + if (naddr->addr_len > RPCBIND_MAXUADDRLEN) + goto xdr_error; + + READ_BUF(naddr->addr_len); + COPYMEM(naddr->addr, naddr->addr_len); + break; + default: + goto xdr_error; + } + DECODE_TAIL; +} + static __be32 nfsd4_decode_copy(struct nfsd4_compoundargs *argp, struct nfsd4_copy *copy) { DECODE_HEAD; + struct nl4_server *ns_dummy; + int i, count; status = nfsd4_decode_stateid(argp, ©->cp_src_stateid); if (status) @@ -1762,7 +1800,32 @@ static __be32 nfsd4_decode_reclaim_complete(struct nfsd4_compoundargs *argp, str p = xdr_decode_hyper(p, ©->cp_count); p++; /* ca_consecutive: we always do consecutive copies */ copy->cp_synchronous = be32_to_cpup(p++); - /* tmp = be32_to_cpup(p); Source server list not supported */ + + count = be32_to_cpup(p++); + + copy->cp_intra = false; + if (count == 0) { /* intra-server copy */ + copy->cp_intra = true; + goto intra; + } + + /* decode all the supplied server addresses but use first */ + status = nfsd4_decode_nl4_server(argp, ©->cp_src); + if (status) + return status; + + ns_dummy = kmalloc(sizeof(struct nl4_server), GFP_KERNEL); + if (ns_dummy == NULL) + return nfserrno(-ENOMEM); + for (i = 0; i < count - 1; i++) { + status = nfsd4_decode_nl4_server(argp, ns_dummy); + if (status) { + kfree(ns_dummy); + return status; + } + } + kfree(ns_dummy); +intra: DECODE_TAIL; } diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h index f4737d6..e815a9c 100644 --- a/fs/nfsd/xdr4.h +++ b/fs/nfsd/xdr4.h @@ -518,11 +518,13 @@ struct nfsd42_write_res { struct nfsd4_copy { /* request */ - stateid_t cp_src_stateid; - stateid_t cp_dst_stateid; - u64 cp_src_pos; - u64 cp_dst_pos; - u64 cp_count; + stateid_t cp_src_stateid; + stateid_t cp_dst_stateid; + u64 cp_src_pos; + u64 cp_dst_pos; + u64 cp_count; + struct nl4_server cp_src; + bool cp_intra; /* both */ bool cp_synchronous; From patchwork Thu Oct 10 12:46:17 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Olga Kornievskaia X-Patchwork-Id: 11183471 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id BFD6E14ED for ; Thu, 10 Oct 2019 12:47:05 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 982ED206B6 for ; Thu, 10 Oct 2019 12:47:05 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="eqq6WxCu" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2387872AbfJJMrF (ORCPT ); Thu, 10 Oct 2019 08:47:05 -0400 Received: from mail-io1-f68.google.com ([209.85.166.68]:45174 "EHLO mail-io1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2387594AbfJJMrE (ORCPT ); Thu, 10 Oct 2019 08:47:04 -0400 Received: by mail-io1-f68.google.com with SMTP id c25so13233047iot.12 for ; Thu, 10 Oct 2019 05:47:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=07aZGDA+cLPH1KOOSyLBLamAyYdD/WVZ9jB6KzMf93c=; b=eqq6WxCuB4K7scUE/4K6UQZlOmciLYR9pPagH0hZma8hY5n7GgLEVr4zhAnbOyXXar yoKCrfXea+CE2SK1Qix3XVTOXV5lrDktCfHIfGr9zWRa/flXPdQcZJfhpncSMqL+oWxm QVT/Lq/O/xG/ciLiW7mkd9JMvGqWwH86D58phqJze95LE59O16EsWPeB8eECvnjC/LsF j6gj6Ba88RIWO+xi37iG9JUqEZfLNh9m9vqXsG29AuLbQlwWOUuFlZz0iwbEKJjejKp4 njA/LhjRBhLhigLkwvFtfOmwWhCz/7w6nDSsFo9tzWUZvOWoW/NeZdRd6d8OfO7mpZgZ BHeg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=07aZGDA+cLPH1KOOSyLBLamAyYdD/WVZ9jB6KzMf93c=; b=VWMCgvgbMvKEKk6vP18C0qezyCmTsWkZy1NS1+7Gx0k/lkqhSuPGFZXEd2O8FC4e7F fTbg14g/+/nGKpym9epMFdUh58qLT5Jryi5lsio/jvy0tblMWZy1TzMZMZfaOk0Q3PBI wM7e3ClJ/5AOvidxSleEcCq37ZrqyRVQSh+uBZX/k2Ndah/EaEnD1dnB5U4GMYCeW3Cr +p+fOtj2CURIhpyTwYmnB9/c85uiF710xHBHeJi6p8eqJE1EPXvI0gEyUEJQphtRXPYX HSPEJhJpMHvsg5ITLKGgNYnIb2+Z5O0UUWeA0ZdnXLxdr5BHiQO3VFVT3TrPr/8eB8ju 0V9Q== X-Gm-Message-State: APjAAAVbAdqVfkvTiXE7w9aGr0LSjCs3WjzceXULMs8yCyXdeAI9bH9c 0o3s9CgFxOHURxuQiYIA2kc= X-Google-Smtp-Source: APXvYqwFrsizpwo3prAUcZ7c2ep0M/G1ti7lXv9IlKrbLXL07v+MHUjZtLzt+sMKkN9lInHmbl4NWA== X-Received: by 2002:a5d:9ecc:: with SMTP id a12mr1498035ioe.195.1570711622787; Thu, 10 Oct 2019 05:47:02 -0700 (PDT) Received: from Olgas-MBP-201.attlocal.net (172-10-226-31.lightspeed.livnmi.sbcglobal.net. [172.10.226.31]) by smtp.gmail.com with ESMTPSA id r2sm1100930ilm.17.2019.10.10.05.47.01 (version=TLS1 cipher=AES128-SHA bits=128/128); Thu, 10 Oct 2019 05:47:02 -0700 (PDT) From: Olga Kornievskaia To: trond.myklebust@hammerspace.com, anna.schumaker@netapp.com, bfields@redhat.com Cc: linux-nfs@vger.kernel.org Subject: [PATCH v8 15/20] NFSD COPY_NOTIFY xdr Date: Thu, 10 Oct 2019 08:46:17 -0400 Message-Id: <20191010124622.27812-16-olga.kornievskaia@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20191010124622.27812-1-olga.kornievskaia@gmail.com> References: <20191010124622.27812-1-olga.kornievskaia@gmail.com> Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org Signed-off-by: Olga Kornievskaia --- fs/nfsd/nfs4proc.c | 28 +++++++++++++++++ fs/nfsd/nfs4xdr.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- fs/nfsd/xdr4.h | 13 ++++++++ 3 files changed, 129 insertions(+), 2 deletions(-) diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 4e3e77b..7fa694d 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -1338,6 +1338,13 @@ struct nfsd4_copy * } static __be32 +nfsd4_copy_notify(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, + union nfsd4_op_u *u) +{ + return nfserr_notsupp; +} + +static __be32 nfsd4_fallocate(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_fallocate *fallocate, int flags) { @@ -2290,6 +2297,21 @@ static inline u32 nfsd4_offload_status_rsize(struct svc_rqst *rqstp, 1 /* osr_complete<1> optional 0 for now */) * sizeof(__be32); } +static inline u32 nfsd4_copy_notify_rsize(struct svc_rqst *rqstp, + struct nfsd4_op *op) +{ + return (op_encode_hdr_size + + 3 /* cnr_lease_time */ + + 1 /* We support one cnr_source_server */ + + 1 /* cnr_stateid seq */ + + op_encode_stateid_maxsz /* cnr_stateid */ + + 1 /* num cnr_source_server*/ + + 1 /* nl4_type */ + + 1 /* nl4 size */ + + XDR_QUADLEN(NFS4_OPAQUE_LIMIT) /*nl4_loc + nl4_loc_sz */) + * sizeof(__be32); +} + #ifdef CONFIG_NFSD_PNFS static inline u32 nfsd4_getdeviceinfo_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op) { @@ -2714,6 +2736,12 @@ static inline u32 nfsd4_seek_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op) .op_name = "OP_OFFLOAD_CANCEL", .op_rsize_bop = nfsd4_only_status_rsize, }, + [OP_COPY_NOTIFY] = { + .op_func = nfsd4_copy_notify, + .op_flags = OP_MODIFIES_SOMETHING, + .op_name = "OP_COPY_NOTIFY", + .op_rsize_bop = nfsd4_copy_notify_rsize, + }, }; /** diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index a664c18..a7b8b81 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -1838,6 +1838,18 @@ static __be32 nfsd4_decode_nl4_server(struct nfsd4_compoundargs *argp, } static __be32 +nfsd4_decode_copy_notify(struct nfsd4_compoundargs *argp, + struct nfsd4_copy_notify *cn) +{ + int status; + + status = nfsd4_decode_stateid(argp, &cn->cpn_src_stateid); + if (status) + return status; + return nfsd4_decode_nl4_server(argp, &cn->cpn_dst); +} + +static __be32 nfsd4_decode_seek(struct nfsd4_compoundargs *argp, struct nfsd4_seek *seek) { DECODE_HEAD; @@ -1938,7 +1950,7 @@ static __be32 nfsd4_decode_nl4_server(struct nfsd4_compoundargs *argp, /* new operations for NFSv4.2 */ [OP_ALLOCATE] = (nfsd4_dec)nfsd4_decode_fallocate, [OP_COPY] = (nfsd4_dec)nfsd4_decode_copy, - [OP_COPY_NOTIFY] = (nfsd4_dec)nfsd4_decode_notsupp, + [OP_COPY_NOTIFY] = (nfsd4_dec)nfsd4_decode_copy_notify, [OP_DEALLOCATE] = (nfsd4_dec)nfsd4_decode_fallocate, [OP_IO_ADVISE] = (nfsd4_dec)nfsd4_decode_notsupp, [OP_LAYOUTERROR] = (nfsd4_dec)nfsd4_decode_notsupp, @@ -4318,6 +4330,46 @@ static __be32 nfsd4_encode_readv(struct nfsd4_compoundres *resp, } static __be32 +nfsd42_encode_nl4_server(struct nfsd4_compoundres *resp, struct nl4_server *ns) +{ + struct xdr_stream *xdr = &resp->xdr; + struct nfs42_netaddr *addr; + __be32 *p; + + p = xdr_reserve_space(xdr, 4); + *p++ = cpu_to_be32(ns->nl4_type); + + switch (ns->nl4_type) { + case NL4_NETADDR: + addr = &ns->u.nl4_addr; + + /* netid_len, netid, uaddr_len, uaddr (port included + * in RPCBIND_MAXUADDRLEN) + */ + p = xdr_reserve_space(xdr, + 4 /* netid len */ + + (XDR_QUADLEN(addr->netid_len) * 4) + + 4 /* uaddr len */ + + (XDR_QUADLEN(addr->addr_len) * 4)); + if (!p) + return nfserr_resource; + + *p++ = cpu_to_be32(addr->netid_len); + p = xdr_encode_opaque_fixed(p, addr->netid, + addr->netid_len); + *p++ = cpu_to_be32(addr->addr_len); + p = xdr_encode_opaque_fixed(p, addr->addr, + addr->addr_len); + break; + default: + WARN_ON_ONCE(ns->nl4_type != NL4_NETADDR); + return nfserr_inval; + } + + return 0; +} + +static __be32 nfsd4_encode_copy(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_copy *copy) { @@ -4351,6 +4403,40 @@ static __be32 nfsd4_encode_readv(struct nfsd4_compoundres *resp, } static __be32 +nfsd4_encode_copy_notify(struct nfsd4_compoundres *resp, __be32 nfserr, + struct nfsd4_copy_notify *cn) +{ + struct xdr_stream *xdr = &resp->xdr; + __be32 *p; + + if (nfserr) + return nfserr; + + /* 8 sec, 4 nsec */ + p = xdr_reserve_space(xdr, 12); + if (!p) + return nfserr_resource; + + /* cnr_lease_time */ + p = xdr_encode_hyper(p, cn->cpn_sec); + *p++ = cpu_to_be32(cn->cpn_nsec); + + /* cnr_stateid */ + nfserr = nfsd4_encode_stateid(xdr, &cn->cpn_cnr_stateid); + if (nfserr) + return nfserr; + + /* cnr_src.nl_nsvr */ + p = xdr_reserve_space(xdr, 4); + if (!p) + return nfserr_resource; + + *p++ = cpu_to_be32(1); + + return nfsd42_encode_nl4_server(resp, &cn->cpn_src); +} + +static __be32 nfsd4_encode_seek(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_seek *seek) { @@ -4447,7 +4533,7 @@ static __be32 nfsd4_encode_readv(struct nfsd4_compoundres *resp, /* NFSv4.2 operations */ [OP_ALLOCATE] = (nfsd4_enc)nfsd4_encode_noop, [OP_COPY] = (nfsd4_enc)nfsd4_encode_copy, - [OP_COPY_NOTIFY] = (nfsd4_enc)nfsd4_encode_noop, + [OP_COPY_NOTIFY] = (nfsd4_enc)nfsd4_encode_copy_notify, [OP_DEALLOCATE] = (nfsd4_enc)nfsd4_encode_noop, [OP_IO_ADVISE] = (nfsd4_enc)nfsd4_encode_noop, [OP_LAYOUTERROR] = (nfsd4_enc)nfsd4_encode_noop, diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h index e815a9c..8231fe0 100644 --- a/fs/nfsd/xdr4.h +++ b/fs/nfsd/xdr4.h @@ -570,6 +570,18 @@ struct nfsd4_offload_status { u32 status; }; +struct nfsd4_copy_notify { + /* request */ + stateid_t cpn_src_stateid; + struct nl4_server cpn_dst; + + /* response */ + stateid_t cpn_cnr_stateid; + u64 cpn_sec; + u32 cpn_nsec; + struct nl4_server cpn_src; +}; + struct nfsd4_op { int opnum; const struct nfsd4_operation * opdesc; @@ -629,6 +641,7 @@ struct nfsd4_op { struct nfsd4_clone clone; struct nfsd4_copy copy; struct nfsd4_offload_status offload_status; + struct nfsd4_copy_notify copy_notify; struct nfsd4_seek seek; } u; struct nfs4_replay * replay; From patchwork Thu Oct 10 12:46:18 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Olga Kornievskaia X-Patchwork-Id: 11183473 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 08D591575 for ; Thu, 10 Oct 2019 12:47:07 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id CD5222067B for ; Thu, 10 Oct 2019 12:47:06 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="jS9sjpKE" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2387897AbfJJMrG (ORCPT ); Thu, 10 Oct 2019 08:47:06 -0400 Received: from mail-io1-f66.google.com ([209.85.166.66]:36160 "EHLO mail-io1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2387870AbfJJMrG (ORCPT ); Thu, 10 Oct 2019 08:47:06 -0400 Received: by mail-io1-f66.google.com with SMTP id b136so13353443iof.3 for ; Thu, 10 Oct 2019 05:47:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=yHxb1F+IidAyncg2OgE/R5pq9YN+bBi0hLf8UvbYCLg=; b=jS9sjpKETjY8/pi0X73QEQB7f5lbb1Gl6bb5a68eRAQie/rbC0fOHxvX2pHTXSrr6y 7pC7VpuefJTXXGDuzn8jgxAD4/wZRiiKqUFQRK1s+TrFPC4RJr4tkBqN8xhrbKHNG67V ticmdQXnpSBQgz3rfWyE4cLyx9WivZZnOPoh5y13jvtpKcAr7HxJft/+8i0flfwvSf3g jZla+YZPodvHHlmr+5W2zwU2AP7Exr2f+uVkbyHXn3PqBCuyuv0toi/aPjdy2f33p8Mg IOuUmeTuSbDmO80kiEdGd08K9UPobsZ3HUykY5Gzr4j/LUbCp/CT+xxOkGYXJXEOZuBv I8Xg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=yHxb1F+IidAyncg2OgE/R5pq9YN+bBi0hLf8UvbYCLg=; b=fM+SK9SSnkoiuAqoVmDwhy8EHfznM7iiAd8gqIYyIRZobTZMuUeSYxahTuWXGkll5I +2FCR3PLXYILSW4yT7efD0NkuBh+I2X1q7e4df256EgzgByfFUf19xM+BQFlfIiV8uZk W87ebh+JM42APpUPw59Cl5gz4cFKu/0CZvFBItfgG3g8T+8KCQVTMTdTaBpNiENjNLcM w1Nrjhlp3g5uBaY4vnCKa8TAt/pUr7S67WmsLLTw0gcp6bGMc8kpDMkQ5za3zqfUVZUN UNu/18hvUcbju22NA83gFFECUAp9D8hACzNPq4d+kkQCCFXMAyvxGKY+amK3BUydABdo LZuQ== X-Gm-Message-State: APjAAAU6y5PiEJdcClpOV9ZHIJ5Il6efhX9QlLsyNLadnA8AS4j+zPuS 09yewef1FDTjnGtGCZh/Rho= X-Google-Smtp-Source: APXvYqzmlO2caAFv3cj37GoPibb89FwqNkpyGW2iDztqWFVXW3GJrotPL9MiDFRN4PsWzYqmrR//tQ== X-Received: by 2002:a05:6602:254a:: with SMTP id j10mr7597261ioe.43.1570711624240; Thu, 10 Oct 2019 05:47:04 -0700 (PDT) Received: from Olgas-MBP-201.attlocal.net (172-10-226-31.lightspeed.livnmi.sbcglobal.net. [172.10.226.31]) by smtp.gmail.com with ESMTPSA id r2sm1100930ilm.17.2019.10.10.05.47.03 (version=TLS1 cipher=AES128-SHA bits=128/128); Thu, 10 Oct 2019 05:47:03 -0700 (PDT) From: Olga Kornievskaia To: trond.myklebust@hammerspace.com, anna.schumaker@netapp.com, bfields@redhat.com Cc: linux-nfs@vger.kernel.org Subject: [PATCH v8 16/20] NFSD add COPY_NOTIFY operation Date: Thu, 10 Oct 2019 08:46:18 -0400 Message-Id: <20191010124622.27812-17-olga.kornievskaia@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20191010124622.27812-1-olga.kornievskaia@gmail.com> References: <20191010124622.27812-1-olga.kornievskaia@gmail.com> Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org Introducing the COPY_NOTIFY operation. Create a new unique stateid that will keep track of the copy state and the upcoming READs that will use that stateid. Each associated parent stateid has a list of copy notify stateids. A copy notify structure makes a copy of the parent stateid and a clientid and will use it to look up the parent stateid during the READ request (suggested by Trond Myklebust ). At nfs4_put_stid() time, we walk the list of the associated copy notify stateids and delete them. Laundromat thread will traverse globally stored copy notify stateid in idr and notice if any haven't been referenced in the lease period, if so, it'll remove them. Return single netaddr to advertise to the copy. Suggested-by: Trond Myklebust Signed-off-by: Olga Kornievskaia Signed-off-by: Andy Adamson --- fs/nfsd/nfs4proc.c | 58 +++++++++++++++++++++++----- fs/nfsd/nfs4state.c | 106 +++++++++++++++++++++++++++++++++++++++++++++++----- fs/nfsd/state.h | 31 +++++++++++++-- fs/nfsd/xdr4.h | 2 +- 4 files changed, 173 insertions(+), 24 deletions(-) diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 7fa694d..9400636 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -37,6 +37,7 @@ #include #include #include +#include #include "idmap.h" #include "cache.h" @@ -776,7 +777,7 @@ static __be32 nfsd4_do_lookupp(struct svc_rqst *rqstp, struct svc_fh *fh) /* check stateid */ status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->current_fh, &read->rd_stateid, RD_STATE, - &read->rd_nf); + &read->rd_nf, NULL); if (status) { dprintk("NFSD: nfsd4_read: couldn't process stateid!\n"); goto out; @@ -948,7 +949,7 @@ static __be32 nfsd4_do_lookupp(struct svc_rqst *rqstp, struct svc_fh *fh) if (setattr->sa_iattr.ia_valid & ATTR_SIZE) { status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->current_fh, &setattr->sa_stateid, - WR_STATE, NULL); + WR_STATE, NULL, NULL); if (status) { dprintk("NFSD: nfsd4_setattr: couldn't process stateid!\n"); return status; @@ -999,7 +1000,7 @@ static __be32 nfsd4_do_lookupp(struct svc_rqst *rqstp, struct svc_fh *fh) trace_nfsd_write_start(rqstp, &cstate->current_fh, write->wr_offset, cnt); status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->current_fh, - stateid, WR_STATE, &nf); + stateid, WR_STATE, &nf, NULL); if (status) { dprintk("NFSD: nfsd4_write: couldn't process stateid!\n"); return status; @@ -1034,14 +1035,14 @@ static __be32 nfsd4_do_lookupp(struct svc_rqst *rqstp, struct svc_fh *fh) return nfserr_nofilehandle; status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->save_fh, - src_stateid, RD_STATE, src); + src_stateid, RD_STATE, src, NULL); if (status) { dprintk("NFSD: %s: couldn't process src stateid!\n", __func__); goto out; } status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->current_fh, - dst_stateid, WR_STATE, dst); + dst_stateid, WR_STATE, dst, NULL); if (status) { dprintk("NFSD: %s: couldn't process dst stateid!\n", __func__); goto out_put_src; @@ -1220,7 +1221,7 @@ static void dup_copy_fields(struct nfsd4_copy *src, struct nfsd4_copy *dst) static void cleanup_async_copy(struct nfsd4_copy *copy) { - nfs4_free_cp_state(copy); + nfs4_free_copy_state(copy); nfsd_file_put(copy->nf_dst); nfsd_file_put(copy->nf_src); spin_lock(©->cp_clp->async_lock); @@ -1274,7 +1275,7 @@ static int nfsd4_do_async_copy(void *data) async_copy = kzalloc(sizeof(struct nfsd4_copy), GFP_KERNEL); if (!async_copy) goto out; - if (!nfs4_init_cp_state(nn, copy)) { + if (!nfs4_init_copy_state(nn, copy)) { kfree(async_copy); goto out; } @@ -1341,7 +1342,44 @@ struct nfsd4_copy * nfsd4_copy_notify(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, union nfsd4_op_u *u) { - return nfserr_notsupp; + struct nfsd4_copy_notify *cn = &u->copy_notify; + __be32 status; + struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id); + struct nfs4_stid *stid; + struct nfs4_cpntf_state *cps; + struct nfs4_client *clp = cstate->clp; + + status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->current_fh, + &cn->cpn_src_stateid, RD_STATE, NULL, + &stid); + if (status) + return status; + + cn->cpn_sec = nn->nfsd4_lease; + cn->cpn_nsec = 0; + + status = nfserrno(-ENOMEM); + cps = nfs4_alloc_init_cpntf_state(nn, stid); + if (!cps) + goto out; + memcpy(&cn->cpn_cnr_stateid, &cps->cp_stateid.stid, sizeof(stateid_t)); + memcpy(&cps->cp_p_stateid, &stid->sc_stateid, sizeof(stateid_t)); + memcpy(&cps->cp_p_clid, &clp->cl_clientid, sizeof(clientid_t)); + + /* For now, only return one server address in cpn_src, the + * address used by the client to connect to this server. + */ + cn->cpn_src.nl4_type = NL4_NETADDR; + status = nfsd4_set_netaddr((struct sockaddr *)&rqstp->rq_daddr, + &cn->cpn_src.u.nl4_addr); + WARN_ON_ONCE(status); + if (status) { + nfs4_put_cpntf_state(nn, cps); + goto out; + } +out: + nfs4_put_stid(stid); + return status; } static __be32 @@ -1353,7 +1391,7 @@ struct nfsd4_copy * status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->current_fh, &fallocate->falloc_stateid, - WR_STATE, &nf); + WR_STATE, &nf, NULL); if (status != nfs_ok) { dprintk("NFSD: nfsd4_fallocate: couldn't process stateid!\n"); return status; @@ -1412,7 +1450,7 @@ struct nfsd4_copy * status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->current_fh, &seek->seek_stateid, - RD_STATE, &nf); + RD_STATE, &nf, NULL); if (status) { dprintk("NFSD: nfsd4_seek: couldn't process stateid!\n"); return status; diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index c65aeaa..b7859b6 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -80,6 +80,7 @@ static bool check_for_locks(struct nfs4_file *fp, struct nfs4_lockowner *lowner); static void nfs4_free_ol_stateid(struct nfs4_stid *stid); void nfsd4_end_grace(struct nfsd_net *nn); +static void _free_cpntf_state_locked(struct nfsd_net *nn, struct nfs4_cpntf_state *cps); /* Locking: */ @@ -722,6 +723,7 @@ struct nfs4_stid *nfs4_alloc_stid(struct nfs4_client *cl, struct kmem_cache *sla /* Will be incremented before return to client: */ refcount_set(&stid->sc_count, 1); spin_lock_init(&stid->sc_lock); + INIT_LIST_HEAD(&stid->sc_cp_list); /* * It shouldn't be a problem to reuse an opaque stateid value. @@ -741,30 +743,76 @@ struct nfs4_stid *nfs4_alloc_stid(struct nfs4_client *cl, struct kmem_cache *sla /* * Create a unique stateid_t to represent each COPY. */ -int nfs4_init_cp_state(struct nfsd_net *nn, struct nfsd4_copy *copy) +static int nfs4_init_cp_state(struct nfsd_net *nn, copy_stateid_t *stid, + unsigned char sc_type) { int new_id; + stid->stid.si_opaque.so_clid.cl_boot = nn->boot_time; + stid->stid.si_opaque.so_clid.cl_id = nn->s2s_cp_cl_id; + stid->sc_type = sc_type; + idr_preload(GFP_KERNEL); spin_lock(&nn->s2s_cp_lock); - new_id = idr_alloc_cyclic(&nn->s2s_cp_stateids, copy, 0, 0, GFP_NOWAIT); + new_id = idr_alloc_cyclic(&nn->s2s_cp_stateids, stid, 0, 0, GFP_NOWAIT); + stid->stid.si_opaque.so_id = new_id; spin_unlock(&nn->s2s_cp_lock); idr_preload_end(); if (new_id < 0) return 0; - copy->cp_stateid.si_opaque.so_id = new_id; - copy->cp_stateid.si_opaque.so_clid.cl_boot = nn->boot_time; - copy->cp_stateid.si_opaque.so_clid.cl_id = nn->s2s_cp_cl_id; return 1; } -void nfs4_free_cp_state(struct nfsd4_copy *copy) +int nfs4_init_copy_state(struct nfsd_net *nn, struct nfsd4_copy *copy) +{ + return nfs4_init_cp_state(nn, ©->cp_stateid, NFS4_COPY_STID); +} + +struct nfs4_cpntf_state *nfs4_alloc_init_cpntf_state(struct nfsd_net *nn, + struct nfs4_stid *p_stid) +{ + struct nfs4_cpntf_state *cps; + + cps = kzalloc(sizeof(struct nfs4_cpntf_state), GFP_KERNEL); + if (!cps) + return NULL; + cps->cpntf_time = get_seconds(); + refcount_set(&cps->cp_stateid.sc_count, 1); + if (!nfs4_init_cp_state(nn, &cps->cp_stateid, NFS4_COPYNOTIFY_STID)) + goto out_free; + spin_lock(&nn->s2s_cp_lock); + list_add(&cps->cp_list, &p_stid->sc_cp_list); + spin_unlock(&nn->s2s_cp_lock); + return cps; +out_free: + kfree(cps); + return NULL; +} + +void nfs4_free_copy_state(struct nfsd4_copy *copy) { struct nfsd_net *nn; + WARN_ON_ONCE(copy->cp_stateid.sc_type != NFS4_COPY_STID); nn = net_generic(copy->cp_clp->net, nfsd_net_id); spin_lock(&nn->s2s_cp_lock); - idr_remove(&nn->s2s_cp_stateids, copy->cp_stateid.si_opaque.so_id); + idr_remove(&nn->s2s_cp_stateids, + copy->cp_stateid.stid.si_opaque.so_id); + spin_unlock(&nn->s2s_cp_lock); +} + +static void nfs4_free_cpntf_statelist(struct net *net, struct nfs4_stid *stid) +{ + struct nfs4_cpntf_state *cps; + struct nfsd_net *nn; + + nn = net_generic(net, nfsd_net_id); + spin_lock(&nn->s2s_cp_lock); + while (!list_empty(&stid->sc_cp_list)) { + cps = list_first_entry(&stid->sc_cp_list, + struct nfs4_cpntf_state, cp_list); + _free_cpntf_state_locked(nn, cps); + } spin_unlock(&nn->s2s_cp_lock); } @@ -915,6 +963,7 @@ static void block_delegations(struct knfsd_fh *fh) return; } idr_remove(&clp->cl_stateids, s->sc_stateid.si_opaque.so_id); + nfs4_free_cpntf_statelist(clp->net, s); spin_unlock(&clp->cl_lock); s->sc_free(s); if (fp) @@ -5210,6 +5259,9 @@ static bool clients_still_reclaiming(struct nfsd_net *nn) struct list_head *pos, *next, reaplist; time_t cutoff = get_seconds() - nn->nfsd4_lease; time_t t, new_timeo = nn->nfsd4_lease; + struct nfs4_cpntf_state *cps; + copy_stateid_t *cps_t; + int i; dprintk("NFSD: laundromat service - starting\n"); @@ -5220,6 +5272,17 @@ static bool clients_still_reclaiming(struct nfsd_net *nn) dprintk("NFSD: end of grace period\n"); nfsd4_end_grace(nn); INIT_LIST_HEAD(&reaplist); + + spin_lock(&nn->s2s_cp_lock); + idr_for_each_entry(&nn->s2s_cp_stateids, cps_t, i) { + cps = container_of(cps_t, struct nfs4_cpntf_state, cp_stateid); + if (cps->cp_stateid.sc_type == NFS4_COPYNOTIFY_STID && + !time_after((unsigned long)cps->cpntf_time, + (unsigned long)cutoff)) + _free_cpntf_state_locked(nn, cps); + } + spin_unlock(&nn->s2s_cp_lock); + spin_lock(&nn->client_lock); list_for_each_safe(pos, next, &nn->client_lru) { clp = list_entry(pos, struct nfs4_client, cl_lru); @@ -5595,6 +5658,24 @@ static __be32 nfsd4_validate_stateid(struct nfs4_client *cl, stateid_t *stateid) out: return status; } +static void +_free_cpntf_state_locked(struct nfsd_net *nn, struct nfs4_cpntf_state *cps) +{ + WARN_ON_ONCE(cps->cp_stateid.sc_type != NFS4_COPYNOTIFY_STID); + if (!refcount_dec_and_test(&cps->cp_stateid.sc_count)) + return; + list_del(&cps->cp_list); + idr_remove(&nn->s2s_cp_stateids, + cps->cp_stateid.stid.si_opaque.so_id); + kfree(cps); +} + +void nfs4_put_cpntf_state(struct nfsd_net *nn, struct nfs4_cpntf_state *cps) +{ + spin_lock(&nn->s2s_cp_lock); + _free_cpntf_state_locked(nn, cps); + spin_unlock(&nn->s2s_cp_lock); +} /* * Checks for stateid operations @@ -5602,7 +5683,8 @@ static __be32 nfsd4_validate_stateid(struct nfs4_client *cl, stateid_t *stateid) __be32 nfs4_preprocess_stateid_op(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct svc_fh *fhp, - stateid_t *stateid, int flags, struct nfsd_file **nfp) + stateid_t *stateid, int flags, struct nfsd_file **nfp, + struct nfs4_stid **cstid) { struct inode *ino = d_inode(fhp->fh_dentry); struct net *net = SVC_NET(rqstp); @@ -5651,8 +5733,12 @@ static __be32 nfsd4_validate_stateid(struct nfs4_client *cl, stateid_t *stateid) if (status == nfs_ok && nfp) status = nfs4_check_file(rqstp, fhp, s, nfp, flags); out: - if (s) - nfs4_put_stid(s); + if (s) { + if (!status && cstid) + *cstid = s; + else + nfs4_put_stid(s); + } return status; } diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h index 46f56af..967b937 100644 --- a/fs/nfsd/state.h +++ b/fs/nfsd/state.h @@ -56,6 +56,14 @@ stateid_opaque_t si_opaque; } stateid_t; +typedef struct { + stateid_t stid; +#define NFS4_COPY_STID 1 +#define NFS4_COPYNOTIFY_STID 2 + unsigned char sc_type; + refcount_t sc_count; +} copy_stateid_t; + #define STATEID_FMT "(%08x/%08x/%08x/%08x)" #define STATEID_VAL(s) \ (s)->si_opaque.so_clid.cl_boot, \ @@ -96,6 +104,7 @@ struct nfs4_stid { #define NFS4_REVOKED_DELEG_STID 16 #define NFS4_CLOSED_DELEG_STID 32 #define NFS4_LAYOUT_STID 64 + struct list_head sc_cp_list; unsigned char sc_type; stateid_t sc_stateid; spinlock_t sc_lock; @@ -104,6 +113,17 @@ struct nfs4_stid { void (*sc_free)(struct nfs4_stid *); }; +/* Keep a list of stateids issued by the COPY_NOTIFY, associate it with the + * parent OPEN/LOCK/DELEG stateid. + */ +struct nfs4_cpntf_state { + copy_stateid_t cp_stateid; + struct list_head cp_list; /* per parent nfs4_stid */ + stateid_t cp_p_stateid; /* copy of parent's stateid */ + clientid_t cp_p_clid; /* copy of parent's clid */ + time_t cpntf_time; /* last time stateid used */ +}; + /* * Represents a delegation stateid. The nfs4_client holds references to these * and they are put when it is being destroyed or when the delegation is @@ -617,14 +637,17 @@ struct nfsd4_blocked_lock { extern __be32 nfs4_preprocess_stateid_op(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct svc_fh *fhp, - stateid_t *stateid, int flags, struct nfsd_file **filp); + stateid_t *stateid, int flags, struct nfsd_file **filp, + struct nfs4_stid **cstid); __be32 nfsd4_lookup_stateid(struct nfsd4_compound_state *cstate, stateid_t *stateid, unsigned char typemask, struct nfs4_stid **s, struct nfsd_net *nn); struct nfs4_stid *nfs4_alloc_stid(struct nfs4_client *cl, struct kmem_cache *slab, void (*sc_free)(struct nfs4_stid *)); -int nfs4_init_cp_state(struct nfsd_net *nn, struct nfsd4_copy *copy); -void nfs4_free_cp_state(struct nfsd4_copy *copy); +int nfs4_init_copy_state(struct nfsd_net *nn, struct nfsd4_copy *copy); +void nfs4_free_copy_state(struct nfsd4_copy *copy); +struct nfs4_cpntf_state *nfs4_alloc_init_cpntf_state(struct nfsd_net *nn, + struct nfs4_stid *p_stid); void nfs4_unhash_stid(struct nfs4_stid *s); void nfs4_put_stid(struct nfs4_stid *s); void nfs4_inc_and_copy_stateid(stateid_t *dst, struct nfs4_stid *stid); @@ -654,6 +677,8 @@ extern struct nfs4_client_reclaim *nfs4_client_to_reclaim(struct xdr_netobj name extern void nfs4_put_copy(struct nfsd4_copy *copy); extern struct nfsd4_copy * find_async_copy(struct nfs4_client *clp, stateid_t *staetid); +extern void nfs4_put_cpntf_state(struct nfsd_net *nn, + struct nfs4_cpntf_state *cps); static inline void get_nfs4_file(struct nfs4_file *fi) { refcount_inc(&fi->fi_ref); diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h index 8231fe0..2937e06 100644 --- a/fs/nfsd/xdr4.h +++ b/fs/nfsd/xdr4.h @@ -542,7 +542,7 @@ struct nfsd4_copy { struct nfsd_file *nf_src; struct nfsd_file *nf_dst; - stateid_t cp_stateid; + copy_stateid_t cp_stateid; struct list_head copies; struct task_struct *copy_task; From patchwork Thu Oct 10 12:46:19 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Olga Kornievskaia X-Patchwork-Id: 11183475 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3A1671709 for ; Thu, 10 Oct 2019 12:47:07 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 119632067B for ; Thu, 10 Oct 2019 12:47:07 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="rZtdSS+C" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2387870AbfJJMrG (ORCPT ); Thu, 10 Oct 2019 08:47:06 -0400 Received: from mail-io1-f52.google.com ([209.85.166.52]:38027 "EHLO mail-io1-f52.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2387594AbfJJMrG (ORCPT ); Thu, 10 Oct 2019 08:47:06 -0400 Received: by mail-io1-f52.google.com with SMTP id u8so13328952iom.5 for ; Thu, 10 Oct 2019 05:47:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=vYUW9IXrqpkv9hIRguedc0baL1AlyP7Y6THvHazRWcw=; b=rZtdSS+CVQtS4XuzlJXhqZ9QxQAJuGLgsuxZmw3YmVHvBxAGPRffBh/qHlSGhppS2o LSLZi2O6gS0iAbo2MMe5dSe1LyJ3eHp629pBArHROvwGj7ibwGu0adios7G74xB/8XjP x1QOr0bjIn3G2iTQr9/O07iw2Q/r2jHvOO+BAZrl5J5Q1ffeYUFdPTqyc6GijuBDVU5F s+9J2QfUjCJoyx0aedk6dJ+2CGffVGZ0wHGYOR74kbPCSdoINtqYulfrmeeqRnXtpSgD tgp97dvIqfPCVHh1GFU+r+LYrVM0R7UyXltTuRyv2DvfLUBkaEWhi2h9MgLOm2qze5ma UBFg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=vYUW9IXrqpkv9hIRguedc0baL1AlyP7Y6THvHazRWcw=; b=AusDyp/fv2h5kN8+UWEpJwm7w7wnGptUtga8ooEjhoToe+DTj/RnRVe1VpVlQewUez 1FwBiPScNPV7fukHmkutQLkbXl0voS//366l9Koh5y9VPIE1M0AHTljbkQAd99OgZjQr uR9NupLzatdPEolqEVOxBsxP3e+eTBByOBCKR1ZgpUXldvtBUXbeOArF0IjbjzTLimt/ L5UKX7c8xGTzFRIbFe3s/E8UmLd5vt98fDG9zn/ksg9+bJlLjKksDVvfjINf6GCTaI89 AYNM7ZcmmpEGoTJIyRF+5V3fPwYs159OaQ3aHzXXHBsWcP0o43PIeDMJAUlCDkD5rq5+ INGw== X-Gm-Message-State: APjAAAUcA7ZUB+atVztoaT+ffJBVMnsGDvcvNgEkn8QxRVSpeFT1axQj 2iEMmoBsDOZw8wHK+UPujJo= X-Google-Smtp-Source: APXvYqxtT72mvrQjbMWQgcLTbLNo+U3dkVGfuDqLZdYZvQDwcji43JmeoEk5g4x2ACZPHJMyuXuQkA== X-Received: by 2002:a6b:f90f:: with SMTP id j15mr9151821iog.257.1570711625371; Thu, 10 Oct 2019 05:47:05 -0700 (PDT) Received: from Olgas-MBP-201.attlocal.net (172-10-226-31.lightspeed.livnmi.sbcglobal.net. [172.10.226.31]) by smtp.gmail.com with ESMTPSA id r2sm1100930ilm.17.2019.10.10.05.47.04 (version=TLS1 cipher=AES128-SHA bits=128/128); Thu, 10 Oct 2019 05:47:04 -0700 (PDT) From: Olga Kornievskaia To: trond.myklebust@hammerspace.com, anna.schumaker@netapp.com, bfields@redhat.com Cc: linux-nfs@vger.kernel.org Subject: [PATCH v8 17/20] NFSD check stateids against copy stateids Date: Thu, 10 Oct 2019 08:46:19 -0400 Message-Id: <20191010124622.27812-18-olga.kornievskaia@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20191010124622.27812-1-olga.kornievskaia@gmail.com> References: <20191010124622.27812-1-olga.kornievskaia@gmail.com> Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org Incoming stateid (used by a READ) could be a saved copy stateid. Using the provided stateid, look it up in the list of copy_notify stateids. If found, use the parent's stateid and parent's clid to look up the parent's stid to do the appropriate checks. Update the copy notify timestamp (cpntf_time) with current time this making it 'active' so that laundromat thread will not delete copy notify state. Signed-off-by: Olga Kornievskaia --- fs/nfsd/nfs4state.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 66 insertions(+), 8 deletions(-) diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index b7859b6..f0942bd 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -4534,7 +4534,8 @@ static __be32 nfsd4_check_seqid(struct nfsd4_compound_state *cstate, struct nfs4 static __be32 lookup_clientid(clientid_t *clid, struct nfsd4_compound_state *cstate, - struct nfsd_net *nn) + struct nfsd_net *nn, + bool sessions) { struct nfs4_client *found; @@ -4555,7 +4556,7 @@ static __be32 lookup_clientid(clientid_t *clid, */ WARN_ON_ONCE(cstate->session); spin_lock(&nn->client_lock); - found = find_confirmed_client(clid, false, nn); + found = find_confirmed_client(clid, sessions, nn); if (!found) { spin_unlock(&nn->client_lock); return nfserr_expired; @@ -4588,7 +4589,7 @@ static __be32 lookup_clientid(clientid_t *clid, if (open->op_file == NULL) return nfserr_jukebox; - status = lookup_clientid(clientid, cstate, nn); + status = lookup_clientid(clientid, cstate, nn, false); if (status) return status; clp = cstate->clp; @@ -5177,7 +5178,7 @@ void nfsd4_cleanup_open_state(struct nfsd4_compound_state *cstate, dprintk("process_renew(%08x/%08x): starting\n", clid->cl_boot, clid->cl_id); - status = lookup_clientid(clid, cstate, nn); + status = lookup_clientid(clid, cstate, nn, false); if (status) goto out; clp = cstate->clp; @@ -5579,7 +5580,8 @@ static __be32 nfsd4_validate_stateid(struct nfs4_client *cl, stateid_t *stateid) if (ZERO_STATEID(stateid) || ONE_STATEID(stateid) || CLOSE_STATEID(stateid)) return nfserr_bad_stateid; - status = lookup_clientid(&stateid->si_opaque.so_clid, cstate, nn); + status = lookup_clientid(&stateid->si_opaque.so_clid, cstate, nn, + false); if (status == nfserr_stale_clientid) { if (cstate->session) return nfserr_bad_stateid; @@ -5669,6 +5671,59 @@ static __be32 nfsd4_validate_stateid(struct nfs4_client *cl, stateid_t *stateid) cps->cp_stateid.stid.si_opaque.so_id); kfree(cps); } +/* + * A READ from an inter server to server COPY will have a + * copy stateid. Look up the copy notify stateid from the + * idr structure and take a reference on it. + */ +static __be32 _find_cpntf_state(struct nfsd_net *nn, stateid_t *st, + struct nfs4_cpntf_state **cps) +{ + copy_stateid_t *cps_t; + struct nfs4_cpntf_state *state = NULL; + + if (st->si_opaque.so_clid.cl_id != nn->s2s_cp_cl_id) + return nfserr_bad_stateid; + spin_lock(&nn->s2s_cp_lock); + cps_t = idr_find(&nn->s2s_cp_stateids, st->si_opaque.so_id); + if (cps_t) { + state = container_of(cps_t, struct nfs4_cpntf_state, + cp_stateid); + if (state->cp_stateid.sc_type != NFS4_COPYNOTIFY_STID) + return nfserr_bad_stateid; + refcount_inc(&state->cp_stateid.sc_count); + } + spin_unlock(&nn->s2s_cp_lock); + if (!state) + return nfserr_bad_stateid; + *cps = state; + return 0; +} + +static __be32 find_cpntf_state(struct nfsd_net *nn, stateid_t *st, + struct nfs4_stid **stid) +{ + __be32 status; + struct nfs4_cpntf_state *cps = NULL; + struct nfsd4_compound_state cstate; + + status = _find_cpntf_state(nn, st, &cps); + if (status) + return status; + + cps->cpntf_time = get_seconds(); + memset(&cstate, 0, sizeof(cstate)); + status = lookup_clientid(&cps->cp_p_clid, &cstate, nn, true); + if (status) + goto out; + status = nfsd4_lookup_stateid(&cstate, &cps->cp_p_stateid, + NFS4_DELEG_STID|NFS4_OPEN_STID|NFS4_LOCK_STID, + stid, nn); + put_client_renew(cstate.clp); +out: + nfs4_put_cpntf_state(nn, cps); + return status; +} void nfs4_put_cpntf_state(struct nfsd_net *nn, struct nfs4_cpntf_state *cps) { @@ -5706,6 +5761,8 @@ void nfs4_put_cpntf_state(struct nfsd_net *nn, struct nfs4_cpntf_state *cps) status = nfsd4_lookup_stateid(cstate, stateid, NFS4_DELEG_STID|NFS4_OPEN_STID|NFS4_LOCK_STID, &s, nn); + if (status == nfserr_bad_stateid) + status = find_cpntf_state(nn, stateid, &s); if (status) return status; status = nfsd4_stid_check_stateid_generation(stateid, s, @@ -6738,7 +6795,8 @@ static __be32 nfsd_test_lock(struct svc_rqst *rqstp, struct svc_fh *fhp, struct return nfserr_inval; if (!nfsd4_has_session(cstate)) { - status = lookup_clientid(&lockt->lt_clientid, cstate, nn); + status = lookup_clientid(&lockt->lt_clientid, cstate, nn, + false); if (status) goto out; } @@ -6922,7 +6980,7 @@ static __be32 nfsd_test_lock(struct svc_rqst *rqstp, struct svc_fh *fhp, struct dprintk("nfsd4_release_lockowner clientid: (%08x/%08x):\n", clid->cl_boot, clid->cl_id); - status = lookup_clientid(clid, cstate, nn); + status = lookup_clientid(clid, cstate, nn, false); if (status) return status; @@ -7069,7 +7127,7 @@ struct nfs4_client_reclaim * __be32 status; /* find clientid in conf_id_hashtbl */ - status = lookup_clientid(clid, cstate, nn); + status = lookup_clientid(clid, cstate, nn, false); if (status) return nfserr_reclaim_bad; From patchwork Thu Oct 10 12:46:20 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Olga Kornievskaia X-Patchwork-Id: 11183477 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 4C9F514ED for ; Thu, 10 Oct 2019 12:47:08 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 2D431206B6 for ; Thu, 10 Oct 2019 12:47:08 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Y/lLaUzS" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2387898AbfJJMrH (ORCPT ); Thu, 10 Oct 2019 08:47:07 -0400 Received: from mail-io1-f68.google.com ([209.85.166.68]:40110 "EHLO mail-io1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2387594AbfJJMrH (ORCPT ); Thu, 10 Oct 2019 08:47:07 -0400 Received: by mail-io1-f68.google.com with SMTP id h144so13285763iof.7 for ; Thu, 10 Oct 2019 05:47:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=K/pkfL3OkmDpVYTr56s33daAMPV/UA76RotHTowphBo=; b=Y/lLaUzSY7lpV7aI24VWcf8042gv6Uimxw8yFfMG9Qirrk9L3JRj0tf9cqlMpAHc2G w/sC3fj5G9tTlibhkL1BtJp7eb2z5G2jj7poYsABARgLYvoCkyqiF9tsPfnMQc2gocuy xejF1XvYbNZTTMC76j+p+9fWzBoPNMIMonUwYKjs4/Plwsk3Qhq16ra31UFd/B+9s8zi MGNEIcAqb2YV7GiMfbGdGCowj7bty2vRRSyHhwYyCkWSuj/AJM0B+LOZY3NasfpND8ad SF9vaeN1GncDeoDfVBLhxInbfaxeUfxxSXshSahH05zlMbpuTPMusbvTuzPe2jUbAv2w GcOg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=K/pkfL3OkmDpVYTr56s33daAMPV/UA76RotHTowphBo=; b=jwX/WmucXrJyQfrTgO/KWjqaVgqFFy/QVrJ76LIkikbfmNhtMsGOmB3HEUPfVdathl 6TtefWVDVkUbTwXNn5HKP49p2uU3GuQ/vyjcVeDhGpRamHQfrRdyr8Ec500jwiFcxaWj cgwjQshEBUx+POJGFrfIJSQOM2XMaKfw4SNRIZkBa5cPT4Et/aK+WHlo9EtsCoMMCZYn T+7GlNhCs6DOoFAfRiBmoO5d9lNeR3yd96PW/hbi1/CVv/QBTuOLqXFKgNcPYZv2fBaO oxgkp8g77zSat+ZtgUqcnksYITPiVWJwPNQ68cQk5Almfr9Jh4Pc2VtCs3fBYOv58veu RodA== X-Gm-Message-State: APjAAAWlk1ANBCunmPnc6fg+9LXMZan3+7y7A65Jpc95JcAsa7LV7n/7 EUuCru28o1B0Sneu+dS6jGp0hYLn X-Google-Smtp-Source: APXvYqxYBQnWy5dXsAa11VRu4dYCUalgEm2Ogp4+91mPKLTDkLWZ1CUF3H6A+3nx0ipUsP04iJiQmQ== X-Received: by 2002:a5d:9052:: with SMTP id v18mr1162615ioq.13.1570711626551; Thu, 10 Oct 2019 05:47:06 -0700 (PDT) Received: from Olgas-MBP-201.attlocal.net (172-10-226-31.lightspeed.livnmi.sbcglobal.net. [172.10.226.31]) by smtp.gmail.com with ESMTPSA id r2sm1100930ilm.17.2019.10.10.05.47.05 (version=TLS1 cipher=AES128-SHA bits=128/128); Thu, 10 Oct 2019 05:47:05 -0700 (PDT) From: Olga Kornievskaia To: trond.myklebust@hammerspace.com, anna.schumaker@netapp.com, bfields@redhat.com Cc: linux-nfs@vger.kernel.org Subject: [PATCH v8 18/20] NFSD generalize nfsd4_compound_state flag names Date: Thu, 10 Oct 2019 08:46:20 -0400 Message-Id: <20191010124622.27812-19-olga.kornievskaia@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20191010124622.27812-1-olga.kornievskaia@gmail.com> References: <20191010124622.27812-1-olga.kornievskaia@gmail.com> Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Olga Kornievskaia Allow for sid_flag field non-stateid use. Signed-off-by: Andy Adamson --- fs/nfsd/nfs4proc.c | 8 ++++---- fs/nfsd/nfs4state.c | 7 ++++--- fs/nfsd/xdr4.h | 6 +++--- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 9400636..3dfa7d7 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -531,9 +531,9 @@ static __be32 nfsd4_open_omfg(struct svc_rqst *rqstp, struct nfsd4_compound_stat return nfserr_restorefh; fh_dup2(&cstate->current_fh, &cstate->save_fh); - if (HAS_STATE_ID(cstate, SAVED_STATE_ID_FLAG)) { + if (HAS_CSTATE_FLAG(cstate, SAVED_STATE_ID_FLAG)) { memcpy(&cstate->current_stateid, &cstate->save_stateid, sizeof(stateid_t)); - SET_STATE_ID(cstate, CURRENT_STATE_ID_FLAG); + SET_CSTATE_FLAG(cstate, CURRENT_STATE_ID_FLAG); } return nfs_ok; } @@ -543,9 +543,9 @@ static __be32 nfsd4_open_omfg(struct svc_rqst *rqstp, struct nfsd4_compound_stat union nfsd4_op_u *u) { fh_dup2(&cstate->save_fh, &cstate->current_fh); - if (HAS_STATE_ID(cstate, CURRENT_STATE_ID_FLAG)) { + if (HAS_CSTATE_FLAG(cstate, CURRENT_STATE_ID_FLAG)) { memcpy(&cstate->save_stateid, &cstate->current_stateid, sizeof(stateid_t)); - SET_STATE_ID(cstate, SAVED_STATE_ID_FLAG); + SET_CSTATE_FLAG(cstate, SAVED_STATE_ID_FLAG); } return nfs_ok; } diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index f0942bd..1a84616 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -7925,7 +7925,8 @@ static int nfs4_state_create_net(struct net *net) static void get_stateid(struct nfsd4_compound_state *cstate, stateid_t *stateid) { - if (HAS_STATE_ID(cstate, CURRENT_STATE_ID_FLAG) && CURRENT_STATEID(stateid)) + if (HAS_CSTATE_FLAG(cstate, CURRENT_STATE_ID_FLAG) && + CURRENT_STATEID(stateid)) memcpy(stateid, &cstate->current_stateid, sizeof(stateid_t)); } @@ -7934,14 +7935,14 @@ static int nfs4_state_create_net(struct net *net) { if (cstate->minorversion) { memcpy(&cstate->current_stateid, stateid, sizeof(stateid_t)); - SET_STATE_ID(cstate, CURRENT_STATE_ID_FLAG); + SET_CSTATE_FLAG(cstate, CURRENT_STATE_ID_FLAG); } } void clear_current_stateid(struct nfsd4_compound_state *cstate) { - CLEAR_STATE_ID(cstate, CURRENT_STATE_ID_FLAG); + CLEAR_CSTATE_FLAG(cstate, CURRENT_STATE_ID_FLAG); } /* diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h index 2937e06..0b4fe07 100644 --- a/fs/nfsd/xdr4.h +++ b/fs/nfsd/xdr4.h @@ -46,9 +46,9 @@ #define CURRENT_STATE_ID_FLAG (1<<0) #define SAVED_STATE_ID_FLAG (1<<1) -#define SET_STATE_ID(c, f) ((c)->sid_flags |= (f)) -#define HAS_STATE_ID(c, f) ((c)->sid_flags & (f)) -#define CLEAR_STATE_ID(c, f) ((c)->sid_flags &= ~(f)) +#define SET_CSTATE_FLAG(c, f) ((c)->sid_flags |= (f)) +#define HAS_CSTATE_FLAG(c, f) ((c)->sid_flags & (f)) +#define CLEAR_CSTATE_FLAG(c, f) ((c)->sid_flags &= ~(f)) struct nfsd4_compound_state { struct svc_fh current_fh; From patchwork Thu Oct 10 12:46:21 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Olga Kornievskaia X-Patchwork-Id: 11183479 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id F23451575 for ; Thu, 10 Oct 2019 12:47:09 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id CB4FB206B6 for ; Thu, 10 Oct 2019 12:47:09 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="IPXfGMWB" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2387694AbfJJMrJ (ORCPT ); Thu, 10 Oct 2019 08:47:09 -0400 Received: from mail-io1-f65.google.com ([209.85.166.65]:40112 "EHLO mail-io1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1733171AbfJJMrJ (ORCPT ); Thu, 10 Oct 2019 08:47:09 -0400 Received: by mail-io1-f65.google.com with SMTP id h144so13285867iof.7 for ; Thu, 10 Oct 2019 05:47:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=KaC6tjgdNoDHICvXVMg+hFO14M1zzxbs9zHjh1ISx9g=; b=IPXfGMWBOga9vxUIZ8KLmxhArfWd5y3Zjej3vG6Gvg/jSrlyaNpPQKH5LIAOyZyE8g hu8ImmIUHLeNlrXodPpKIM8+0vTBqjBhyKQbFN3fU/K4jsQvZFDqxolMBFLyaPmmD+3v 6/MdyuPY8IK6t5dygxUhedIexTLsvoXFDf7mGg/2MUNH0252kfCZ+imAZ6C5PxuUgfrK DMH5IypgGyk9vDKLYBiKvanVbv1wJIgBagzhgw1YGfYI1qvOKdm2Eha1obdWN35xcWc6 4fLIaDh8RJZ67Lm8H4Ht52mCC+yn0O0AKMwX9vwbFq5fBi/QiBq85Os8ukxzNk2D5emR DW1w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=KaC6tjgdNoDHICvXVMg+hFO14M1zzxbs9zHjh1ISx9g=; b=oMKTG6cj3fKUlWDioYbMLQixMvw8+PLdCh1+Uo8NrExDg8Wl48Iari+ygJZ82klews Z7UbQXk6GyQSSQQWCz8SPii04J3lm6k36EOwPAXRRHAotZO3NZtMXiEFOjjaJmBkAKx2 AZHipqP4qlMXBjIGk5HuiTA0XnoS5frj2Hc7NdoGv3rpnDvBX6nw8vlEK5LKOPn6a8bl s+Flf4XyTcKPPStIiGFM63Vey7jA6zVp+HwKA8SBjmqlSLLumzII2/tZsAEO9U6q/2XA LII4XuDa4m/wIVkCgbcHMHCtLnONQEnRSjqMS+TJ7SopSzMx6t3yL1FtnzlHRBbhysEc pzcQ== X-Gm-Message-State: APjAAAVvHYdp8Xp8yYc6QI6yqoW1QOy3oAnLeIZkRPp2U+DA7do/9vWa 17S9hcrhh6WScZGdnLQ1LdI= X-Google-Smtp-Source: APXvYqxhYrnKcvp+dzbLgRhYsi4Tw+JyhTBa35cqA45G6IyVU/32O1yke8XdUDONZiqEtxAZm5SPRg== X-Received: by 2002:a92:83d5:: with SMTP id p82mr458032ilk.144.1570711627630; Thu, 10 Oct 2019 05:47:07 -0700 (PDT) Received: from Olgas-MBP-201.attlocal.net (172-10-226-31.lightspeed.livnmi.sbcglobal.net. [172.10.226.31]) by smtp.gmail.com with ESMTPSA id r2sm1100930ilm.17.2019.10.10.05.47.06 (version=TLS1 cipher=AES128-SHA bits=128/128); Thu, 10 Oct 2019 05:47:07 -0700 (PDT) From: Olga Kornievskaia To: trond.myklebust@hammerspace.com, anna.schumaker@netapp.com, bfields@redhat.com Cc: linux-nfs@vger.kernel.org Subject: [PATCH v8 19/20] NFSD: allow inter server COPY to have a STALE source server fh Date: Thu, 10 Oct 2019 08:46:21 -0400 Message-Id: <20191010124622.27812-20-olga.kornievskaia@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20191010124622.27812-1-olga.kornievskaia@gmail.com> References: <20191010124622.27812-1-olga.kornievskaia@gmail.com> Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org The inter server to server COPY source server filehandle is a foreign filehandle as the COPY is sent to the destination server. Signed-off-by: Olga Kornievskaia --- fs/nfsd/Kconfig | 10 ++++++++++ fs/nfsd/nfs4proc.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++---- fs/nfsd/nfsfh.h | 5 ++++- fs/nfsd/xdr4.h | 1 + 4 files changed, 68 insertions(+), 5 deletions(-) diff --git a/fs/nfsd/Kconfig b/fs/nfsd/Kconfig index 10cefb0..b7172a8 100644 --- a/fs/nfsd/Kconfig +++ b/fs/nfsd/Kconfig @@ -133,6 +133,16 @@ config NFSD_FLEXFILELAYOUT If unsure, say N. +config NFSD_V4_2_INTER_SSC + bool "NFSv4.2 inter server to server COPY" + depends on NFSD_V4 && NFS_V4_1 && NFS_V4_2 + help + This option enables support for NFSv4.2 inter server to + server copy where the destination server calls the NFSv4.2 + client to read the data to copy from the source server. + + If unsure, say N. + config NFSD_V4_SECURITY_LABEL bool "Provide Security Label support for NFSv4 server" depends on NFSD_V4 && SECURITY diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 3dfa7d7..dde42ea 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -504,12 +504,20 @@ static __be32 nfsd4_open_omfg(struct svc_rqst *rqstp, struct nfsd4_compound_stat union nfsd4_op_u *u) { struct nfsd4_putfh *putfh = &u->putfh; + __be32 ret; fh_put(&cstate->current_fh); cstate->current_fh.fh_handle.fh_size = putfh->pf_fhlen; memcpy(&cstate->current_fh.fh_handle.fh_base, putfh->pf_fhval, putfh->pf_fhlen); - return fh_verify(rqstp, &cstate->current_fh, 0, NFSD_MAY_BYPASS_GSS); + ret = fh_verify(rqstp, &cstate->current_fh, 0, NFSD_MAY_BYPASS_GSS); +#ifdef CONFIG_NFSD_V4_2_INTER_SSC + if (ret == nfserr_stale && putfh->no_verify) { + SET_FH_FLAG(&cstate->current_fh, NFSD4_FH_FOREIGN); + ret = 0; + } +#endif + return ret; } static __be32 @@ -1955,6 +1963,45 @@ static void svcxdr_init_encode(struct svc_rqst *rqstp, - rqstp->rq_auth_slack; } +#ifdef CONFIG_NFSD_V4_2_INTER_SSC +static void +check_if_stalefh_allowed(struct nfsd4_compoundargs *args) +{ + struct nfsd4_op *op, *current_op = NULL, *saved_op = NULL; + struct nfsd4_copy *copy; + struct nfsd4_putfh *putfh; + int i; + + /* traverse all operation and if it's a COPY compound, mark the + * source filehandle to skip verification + */ + for (i = 0; i < args->opcnt; i++) { + op = &args->ops[i]; + if (op->opnum == OP_PUTFH) + current_op = op; + else if (op->opnum == OP_SAVEFH) + saved_op = current_op; + else if (op->opnum == OP_RESTOREFH) + current_op = saved_op; + else if (op->opnum == OP_COPY) { + copy = (struct nfsd4_copy *)&op->u; + if (!saved_op) { + op->status = nfserr_nofilehandle; + return; + } + putfh = (struct nfsd4_putfh *)&saved_op->u; + if (!copy->cp_intra) + putfh->no_verify = true; + } + } +} +#else +static void +check_if_stalefh_allowed(struct nfsd4_compoundargs *args) +{ +} +#endif + /* * COMPOUND call. */ @@ -2003,6 +2050,7 @@ static void svcxdr_init_encode(struct svc_rqst *rqstp, resp->opcnt = 1; goto encode_op; } + check_if_stalefh_allowed(args); trace_nfsd_compound(rqstp, args->opcnt); while (!status && resp->opcnt < args->opcnt) { @@ -2018,13 +2066,14 @@ static void svcxdr_init_encode(struct svc_rqst *rqstp, op->status = nfsd4_open_omfg(rqstp, cstate, op); goto encode_op; } - - if (!current_fh->fh_dentry) { + if (!current_fh->fh_dentry && + !HAS_FH_FLAG(current_fh, NFSD4_FH_FOREIGN)) { if (!(op->opdesc->op_flags & ALLOWED_WITHOUT_FH)) { op->status = nfserr_nofilehandle; goto encode_op; } - } else if (current_fh->fh_export->ex_fslocs.migrated && + } else if (current_fh->fh_export && + current_fh->fh_export->ex_fslocs.migrated && !(op->opdesc->op_flags & ALLOWED_ON_ABSENT_FS)) { op->status = nfserr_moved; goto encode_op; diff --git a/fs/nfsd/nfsfh.h b/fs/nfsd/nfsfh.h index 755e256..b9c7568 100644 --- a/fs/nfsd/nfsfh.h +++ b/fs/nfsd/nfsfh.h @@ -35,7 +35,7 @@ static inline ino_t u32_to_ino_t(__u32 uino) bool fh_locked; /* inode locked by us */ bool fh_want_write; /* remount protection taken */ - + int fh_flags; /* FH flags */ #ifdef CONFIG_NFSD_V3 bool fh_post_saved; /* post-op attrs saved */ bool fh_pre_saved; /* pre-op attrs saved */ @@ -56,6 +56,9 @@ static inline ino_t u32_to_ino_t(__u32 uino) #endif /* CONFIG_NFSD_V3 */ } svc_fh; +#define NFSD4_FH_FOREIGN (1<<0) +#define SET_FH_FLAG(c, f) ((c)->fh_flags |= (f)) +#define HAS_FH_FLAG(c, f) ((c)->fh_flags & (f)) enum nfsd_fsid { FSID_DEV = 0, diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h index 0b4fe07..b16f602 100644 --- a/fs/nfsd/xdr4.h +++ b/fs/nfsd/xdr4.h @@ -221,6 +221,7 @@ struct nfsd4_lookup { struct nfsd4_putfh { u32 pf_fhlen; /* request */ char *pf_fhval; /* request */ + bool no_verify; /* represents foreigh fh */ }; struct nfsd4_open { From patchwork Thu Oct 10 12:46:22 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Olga Kornievskaia X-Patchwork-Id: 11183481 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id B4A2E1575 for ; Thu, 10 Oct 2019 12:47:10 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 83E4820B7C for ; Thu, 10 Oct 2019 12:47:10 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="oezBRUi8" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1733171AbfJJMrK (ORCPT ); Thu, 10 Oct 2019 08:47:10 -0400 Received: from mail-io1-f66.google.com ([209.85.166.66]:35070 "EHLO mail-io1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2387802AbfJJMrJ (ORCPT ); Thu, 10 Oct 2019 08:47:09 -0400 Received: by mail-io1-f66.google.com with SMTP id q10so13411260iop.2 for ; Thu, 10 Oct 2019 05:47:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=v9imY1M6ezwjeiXfTxtPv3ioweQ1g8KtmCIXfrxqQXc=; b=oezBRUi8vHTyE/Wan9SLWQPaarE8a0saYRCNAAI56OybFnvg695Cq886vbfs/PZ3un hefZ5RbUwRILQZOi/zTbv15+n74HdToJBU/6ZtQza9G+c/vhH8J64JV/VwJiyGdlWPVM p7qA3nG1Mrppv3nUt26HM5pY+o1Od17PP8HB2zC/13HKLmTAgBMUELLxXSDqk2o9gdla fDxFADhhe+VbL13TC8dGEOB0ajAc537IuWZIADA5g/RdV2jsdkPkLZddk9VI9WmAilxD dXnxpBaY5Fp5qd1lZFqcPI3T6kTwMqmEBDL5XmxXDkNoMHxiAjteAyvNWOaCFUU07zdF GTyw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=v9imY1M6ezwjeiXfTxtPv3ioweQ1g8KtmCIXfrxqQXc=; b=Gj5m26Vg+qoRbTYG2IlKCYP1ry1ntY6EuRYGav9ESyYMRhhOHUKmiiHhKWBl0N4HWv VsXdHDxoabiQdGKlVtKW6PLQHuPOiic3qP/lxHR9+3Td6KYF1g9SPHFnrVmOrYnhKYtV y/GqFTJa8sytbFb0IZyVQkhZIK9QyoUXXAyjAC57CrUKOusNaofweaozJlrSgBzlEqJb AkYAelrXt20Pk0H8OLvxNRcc/E6aUgZMpAUP7lyRkquoWUmYSxYwKtQBkgFoaehnLE0S bJcHBH/ebpZW82z4fxw+jDLWD5hHxOtOM+l8+BDElPcKnJaDPWR1ht28NpKfI2pWtld0 CPuQ== X-Gm-Message-State: APjAAAWIHIRdx/z22B4gdahZTQKCMd+ONZYzdcWuzvPGDNA/wvgR+0IS ekfg1vbHZkglLqNQamas1aJEZ3cH X-Google-Smtp-Source: APXvYqwLjS5yeS1OfoY8q1jIIMGPrEbNEok1liyEaNNjAh2OYP87plt6O/MHctV3kMKSnk7ZSrJFVA== X-Received: by 2002:a92:1784:: with SMTP id 4mr444423ilx.142.1570711628774; Thu, 10 Oct 2019 05:47:08 -0700 (PDT) Received: from Olgas-MBP-201.attlocal.net (172-10-226-31.lightspeed.livnmi.sbcglobal.net. [172.10.226.31]) by smtp.gmail.com with ESMTPSA id r2sm1100930ilm.17.2019.10.10.05.47.07 (version=TLS1 cipher=AES128-SHA bits=128/128); Thu, 10 Oct 2019 05:47:08 -0700 (PDT) From: Olga Kornievskaia To: trond.myklebust@hammerspace.com, anna.schumaker@netapp.com, bfields@redhat.com Cc: linux-nfs@vger.kernel.org Subject: [PATCH v8 20/20] NFSD add nfs4 inter ssc to nfsd4_copy Date: Thu, 10 Oct 2019 08:46:22 -0400 Message-Id: <20191010124622.27812-21-olga.kornievskaia@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20191010124622.27812-1-olga.kornievskaia@gmail.com> References: <20191010124622.27812-1-olga.kornievskaia@gmail.com> Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Olga Kornievskaia Given a universal address, mount the source server from the destination server. Use an internal mount. Call the NFS client nfs42_ssc_open to obtain the NFS struct file suitable for nfsd_copy_range. Ability to do "inter" server-to-server depends on the an nfsd kernel parameter "inter_copy_offload_enable". Signed-off-by: Olga Kornievskaia --- fs/nfsd/nfs4proc.c | 293 ++++++++++++++++++++++++++++++++++++++++++++++++---- fs/nfsd/nfs4state.c | 15 ++- fs/nfsd/nfssvc.c | 6 ++ fs/nfsd/state.h | 3 + fs/nfsd/xdr4.h | 5 + 5 files changed, 295 insertions(+), 27 deletions(-) diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index dde42ea..1675129 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -1143,6 +1143,208 @@ void nfsd4_shutdown_copy(struct nfs4_client *clp) while ((copy = nfsd4_get_copy(clp)) != NULL) nfsd4_stop_copy(copy); } +#ifdef CONFIG_NFSD_V4_2_INTER_SSC + +extern struct file *nfs42_ssc_open(struct vfsmount *ss_mnt, + struct nfs_fh *src_fh, + nfs4_stateid *stateid); +extern void nfs42_ssc_close(struct file *filep); + +extern void nfs_sb_deactive(struct super_block *sb); + +#define NFSD42_INTERSSC_MOUNTOPS "vers=4.2,addr=%s,sec=sys" + +/** + * Support one copy source server for now. + */ +static __be32 +nfsd4_interssc_connect(struct nl4_server *nss, struct svc_rqst *rqstp, + struct vfsmount **mount) +{ + struct file_system_type *type; + struct vfsmount *ss_mnt; + struct nfs42_netaddr *naddr; + struct sockaddr_storage tmp_addr; + size_t tmp_addrlen, match_netid_len = 3; + char *startsep = "", *endsep = "", *match_netid = "tcp"; + char *ipaddr, *dev_name, *raw_data; + int len, raw_len, status = -EINVAL; + + naddr = &nss->u.nl4_addr; + tmp_addrlen = rpc_uaddr2sockaddr(SVC_NET(rqstp), naddr->addr, + naddr->addr_len, + (struct sockaddr *)&tmp_addr, + sizeof(tmp_addr)); + if (tmp_addrlen == 0) + goto out_err; + + if (tmp_addr.ss_family == AF_INET6) { + startsep = "["; + endsep = "]"; + match_netid = "tcp6"; + match_netid_len = 4; + } + + if (naddr->netid_len != match_netid_len || + strncmp(naddr->netid, match_netid, naddr->netid_len)) + goto out_err; + + /* Construct the raw data for the vfs_kern_mount call */ + len = RPC_MAX_ADDRBUFLEN + 1; + ipaddr = kzalloc(len, GFP_KERNEL); + if (!ipaddr) + goto out_err; + + rpc_ntop((struct sockaddr *)&tmp_addr, ipaddr, len); + + /* 2 for ipv6 endsep and startsep. 3 for ":/" and trailing '/0'*/ + + raw_len = strlen(NFSD42_INTERSSC_MOUNTOPS) + strlen(ipaddr); + raw_data = kzalloc(raw_len, GFP_KERNEL); + if (!raw_data) + goto out_free_ipaddr; + + snprintf(raw_data, raw_len, NFSD42_INTERSSC_MOUNTOPS, ipaddr); + + status = -ENODEV; + type = get_fs_type("nfs"); + if (!type) + goto out_free_rawdata; + + /* Set the server: for the vfs_kern_mount call */ + dev_name = kzalloc(len + 5, GFP_KERNEL); + if (!dev_name) + goto out_free_rawdata; + snprintf(dev_name, len + 5, "%s%s%s:/", startsep, ipaddr, endsep); + + /* Use an 'internal' mount: SB_KERNMOUNT -> MNT_INTERNAL */ + ss_mnt = vfs_kern_mount(type, SB_KERNMOUNT, dev_name, raw_data); + module_put(type->owner); + if (IS_ERR(ss_mnt)) + goto out_free_devname; + + status = 0; + *mount = ss_mnt; + +out_free_devname: + kfree(dev_name); +out_free_rawdata: + kfree(raw_data); +out_free_ipaddr: + kfree(ipaddr); +out_err: + return status; +} + +static void +nfsd4_interssc_disconnect(struct vfsmount *ss_mnt) +{ + nfs_sb_deactive(ss_mnt->mnt_sb); + mntput(ss_mnt); +} + +/** + * nfsd4_setup_inter_ssc + * + * Verify COPY destination stateid. + * Connect to the source server with NFSv4.1. + * Create the source struct file for nfsd_copy_range. + * Called with COPY cstate: + * SAVED_FH: source filehandle + * CURRENT_FH: destination filehandle + * + * Returns errno (not nfserrxxx) + */ +static __be32 +nfsd4_setup_inter_ssc(struct svc_rqst *rqstp, + struct nfsd4_compound_state *cstate, + struct nfsd4_copy *copy, struct vfsmount **mount) +{ + struct svc_fh *s_fh = NULL; + stateid_t *s_stid = ©->cp_src_stateid; + __be32 status = -EINVAL; + + /* Verify the destination stateid and set dst struct file*/ + status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->current_fh, + ©->cp_dst_stateid, + WR_STATE, ©->nf_dst, NULL); + if (status) + goto out; + + status = nfsd4_interssc_connect(©->cp_src, rqstp, mount); + if (status) + goto out; + + s_fh = &cstate->save_fh; + + copy->c_fh.size = s_fh->fh_handle.fh_size; + memcpy(copy->c_fh.data, &s_fh->fh_handle.fh_base, copy->c_fh.size); + copy->stateid.seqid = s_stid->si_generation; + memcpy(copy->stateid.other, (void *)&s_stid->si_opaque, + sizeof(stateid_opaque_t)); + + status = 0; +out: + return status; +} + +static void +nfsd4_cleanup_inter_ssc(struct vfsmount *ss_mnt, struct nfsd_file *src, + struct nfsd_file *dst) +{ + nfs42_ssc_close(src->nf_file); + nfsd_file_put(src); + nfsd_file_put(dst); + mntput(ss_mnt); +} + +#else /* CONFIG_NFSD_V4_2_INTER_SSC */ + +static __be32 +nfsd4_setup_inter_ssc(struct svc_rqst *rqstp, + struct nfsd4_compound_state *cstate, + struct nfsd4_copy *copy, + struct vfsmount **mount) +{ + *mount = NULL; + return -EINVAL; +} + +static void +nfsd4_cleanup_inter_ssc(struct vfsmount *ss_mnt, struct nfsd_file *src, + struct nfsd_file *dst) +{ +} + +static void +nfsd4_interssc_disconnect(struct vfsmount *ss_mnt) +{ +} + +static struct file *nfs42_ssc_open(struct vfsmount *ss_mnt, + struct nfs_fh *src_fh, + nfs4_stateid *stateid) +{ + return NULL; +} +#endif /* CONFIG_NFSD_V4_2_INTER_SSC */ + +static __be32 +nfsd4_setup_intra_ssc(struct svc_rqst *rqstp, + struct nfsd4_compound_state *cstate, + struct nfsd4_copy *copy) +{ + return nfsd4_verify_copy(rqstp, cstate, ©->cp_src_stateid, + ©->nf_src, ©->cp_dst_stateid, + ©->nf_dst); +} + +static void +nfsd4_cleanup_intra_ssc(struct nfsd_file *src, struct nfsd_file *dst) +{ + nfsd_file_put(src); + nfsd_file_put(dst); +} static void nfsd4_cb_offload_release(struct nfsd4_callback *cb) { @@ -1208,12 +1410,16 @@ static __be32 nfsd4_do_copy(struct nfsd4_copy *copy, bool sync) status = nfs_ok; } - nfsd_file_put(copy->nf_src); - nfsd_file_put(copy->nf_dst); + if (!copy->cp_intra) /* Inter server SSC */ + nfsd4_cleanup_inter_ssc(copy->ss_mnt, copy->nf_src, + copy->nf_dst); + else + nfsd4_cleanup_intra_ssc(copy->nf_src, copy->nf_dst); + return status; } -static void dup_copy_fields(struct nfsd4_copy *src, struct nfsd4_copy *dst) +static int dup_copy_fields(struct nfsd4_copy *src, struct nfsd4_copy *dst) { dst->cp_src_pos = src->cp_src_pos; dst->cp_dst_pos = src->cp_dst_pos; @@ -1223,8 +1429,17 @@ static void dup_copy_fields(struct nfsd4_copy *src, struct nfsd4_copy *dst) memcpy(&dst->fh, &src->fh, sizeof(src->fh)); dst->cp_clp = src->cp_clp; dst->nf_dst = nfsd_file_get(src->nf_dst); - dst->nf_src = nfsd_file_get(src->nf_src); + dst->cp_intra = src->cp_intra; + if (src->cp_intra) /* for inter, file_src doesn't exist yet */ + dst->nf_src = nfsd_file_get(src->nf_src); + memcpy(&dst->cp_stateid, &src->cp_stateid, sizeof(src->cp_stateid)); + memcpy(&dst->cp_src, &src->cp_src, sizeof(struct nl4_server)); + memcpy(&dst->stateid, &src->stateid, sizeof(src->stateid)); + memcpy(&dst->c_fh, &src->c_fh, sizeof(src->c_fh)); + dst->ss_mnt = src->ss_mnt; + + return 0; } static void cleanup_async_copy(struct nfsd4_copy *copy) @@ -1243,7 +1458,25 @@ static int nfsd4_do_async_copy(void *data) struct nfsd4_copy *copy = (struct nfsd4_copy *)data; struct nfsd4_copy *cb_copy; + if (!copy->cp_intra) { /* Inter server SSC */ + copy->nf_src = kzalloc(sizeof(struct nfsd_file), GFP_KERNEL); + if (!copy->nf_src) { + copy->nfserr = nfserr_serverfault; + nfsd4_interssc_disconnect(copy->ss_mnt); + goto do_callback; + } + copy->nf_src->nf_file = nfs42_ssc_open(copy->ss_mnt, ©->c_fh, + ©->stateid); + if (IS_ERR(copy->nf_src->nf_file)) { + kfree(copy->nf_src); + copy->nfserr = nfserr_offload_denied; + nfsd4_interssc_disconnect(copy->ss_mnt); + goto do_callback; + } + } + copy->nfserr = nfsd4_do_copy(copy, 0); +do_callback: cb_copy = kzalloc(sizeof(struct nfsd4_copy), GFP_KERNEL); if (!cb_copy) goto out; @@ -1255,6 +1488,8 @@ static int nfsd4_do_async_copy(void *data) &nfsd4_cb_offload_ops, NFSPROC4_CLNT_CB_OFFLOAD); nfsd4_run_cb(&cb_copy->cp_cb); out: + if (!copy->cp_intra) + kfree(copy->nf_src); cleanup_async_copy(copy); return 0; } @@ -1267,11 +1502,20 @@ static int nfsd4_do_async_copy(void *data) __be32 status; struct nfsd4_copy *async_copy = NULL; - status = nfsd4_verify_copy(rqstp, cstate, ©->cp_src_stateid, - ©->nf_src, ©->cp_dst_stateid, - ©->nf_dst); - if (status) - goto out; + if (!copy->cp_intra) { /* Inter server SSC */ + if (!inter_copy_offload_enable || copy->cp_synchronous) { + status = nfserr_notsupp; + goto out; + } + status = nfsd4_setup_inter_ssc(rqstp, cstate, copy, + ©->ss_mnt); + if (status) + return nfserr_offload_denied; + } else { + status = nfsd4_setup_intra_ssc(rqstp, cstate, copy); + if (status) + return status; + } copy->cp_clp = cstate->clp; memcpy(©->fh, &cstate->current_fh.fh_handle, @@ -1282,15 +1526,15 @@ static int nfsd4_do_async_copy(void *data) status = nfserrno(-ENOMEM); async_copy = kzalloc(sizeof(struct nfsd4_copy), GFP_KERNEL); if (!async_copy) - goto out; - if (!nfs4_init_copy_state(nn, copy)) { - kfree(async_copy); - goto out; - } + goto out_err; + if (!nfs4_init_copy_state(nn, copy)) + goto out_err; refcount_set(&async_copy->refcount, 1); memcpy(©->cp_res.cb_stateid, ©->cp_stateid, sizeof(copy->cp_stateid)); - dup_copy_fields(copy, async_copy); + status = dup_copy_fields(copy, async_copy); + if (status) + goto out_err; async_copy->copy_task = kthread_create(nfsd4_do_async_copy, async_copy, "%s", "copy thread"); if (IS_ERR(async_copy->copy_task)) @@ -1301,12 +1545,16 @@ static int nfsd4_do_async_copy(void *data) spin_unlock(&async_copy->cp_clp->async_lock); wake_up_process(async_copy->copy_task); status = nfs_ok; - } else + } else { status = nfsd4_do_copy(copy, 1); + } out: return status; out_err: cleanup_async_copy(async_copy); + status = nfserrno(-ENOMEM); + if (!copy->cp_intra) + nfsd4_interssc_disconnect(copy->ss_mnt); goto out; } @@ -1317,7 +1565,7 @@ struct nfsd4_copy * spin_lock(&clp->async_lock); list_for_each_entry(copy, &clp->async_copies, copies) { - if (memcmp(©->cp_stateid, stateid, NFS4_STATEID_SIZE)) + if (memcmp(©->cp_stateid.stid, stateid, NFS4_STATEID_SIZE)) continue; refcount_inc(©->refcount); spin_unlock(&clp->async_lock); @@ -1333,17 +1581,18 @@ struct nfsd4_copy * union nfsd4_op_u *u) { struct nfsd4_offload_status *os = &u->offload_status; - __be32 status = 0; struct nfsd4_copy *copy; struct nfs4_client *clp = cstate->clp; copy = find_async_copy(clp, &os->stateid); - if (copy) + if (!copy) { + struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id); + + return manage_cpntf_state(nn, &os->stateid, clp, NULL); + } else nfsd4_stop_copy(copy); - else - status = nfserr_bad_stateid; - return status; + return nfs_ok; } static __be32 diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 1a84616..767ada7 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -5676,8 +5676,9 @@ static __be32 nfsd4_validate_stateid(struct nfs4_client *cl, stateid_t *stateid) * copy stateid. Look up the copy notify stateid from the * idr structure and take a reference on it. */ -static __be32 _find_cpntf_state(struct nfsd_net *nn, stateid_t *st, - struct nfs4_cpntf_state **cps) +__be32 manage_cpntf_state(struct nfsd_net *nn, stateid_t *st, + struct nfs4_client *clp, + struct nfs4_cpntf_state **cps) { copy_stateid_t *cps_t; struct nfs4_cpntf_state *state = NULL; @@ -5691,12 +5692,16 @@ static __be32 _find_cpntf_state(struct nfsd_net *nn, stateid_t *st, cp_stateid); if (state->cp_stateid.sc_type != NFS4_COPYNOTIFY_STID) return nfserr_bad_stateid; - refcount_inc(&state->cp_stateid.sc_count); + if (!clp) + refcount_inc(&state->cp_stateid.sc_count); + else + _free_cpntf_state_locked(nn, state); } spin_unlock(&nn->s2s_cp_lock); if (!state) return nfserr_bad_stateid; - *cps = state; + if (!clp && state) + *cps = state; return 0; } @@ -5707,7 +5712,7 @@ static __be32 find_cpntf_state(struct nfsd_net *nn, stateid_t *st, struct nfs4_cpntf_state *cps = NULL; struct nfsd4_compound_state cstate; - status = _find_cpntf_state(nn, st, &cps); + status = manage_cpntf_state(nn, st, NULL, &cps); if (status) return status; diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c index fdf7ed4..97bfee9 100644 --- a/fs/nfsd/nfssvc.c +++ b/fs/nfsd/nfssvc.c @@ -31,6 +31,12 @@ #define NFSDDBG_FACILITY NFSDDBG_SVC +bool inter_copy_offload_enable; +EXPORT_SYMBOL_GPL(inter_copy_offload_enable); +module_param(inter_copy_offload_enable, bool, 0644); +MODULE_PARM_DESC(inter_copy_offload_enable, + "Enable inter server to server copy offload. Default: false"); + extern struct svc_program nfsd_program; static int nfsd(void *vrqstp); #if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h index 967b937..3f57680 100644 --- a/fs/nfsd/state.h +++ b/fs/nfsd/state.h @@ -679,6 +679,9 @@ extern struct nfs4_client_reclaim *nfs4_client_to_reclaim(struct xdr_netobj name find_async_copy(struct nfs4_client *clp, stateid_t *staetid); extern void nfs4_put_cpntf_state(struct nfsd_net *nn, struct nfs4_cpntf_state *cps); +extern __be32 manage_cpntf_state(struct nfsd_net *nn, stateid_t *st, + struct nfs4_client *clp, + struct nfs4_cpntf_state **cps); static inline void get_nfs4_file(struct nfs4_file *fi) { refcount_inc(&fi->fi_ref); diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h index b16f602..db63d39 100644 --- a/fs/nfsd/xdr4.h +++ b/fs/nfsd/xdr4.h @@ -549,7 +549,12 @@ struct nfsd4_copy { struct task_struct *copy_task; refcount_t refcount; bool stopped; + + struct vfsmount *ss_mnt; + struct nfs_fh c_fh; + nfs4_stateid stateid; }; +extern bool inter_copy_offload_enable; struct nfsd4_seek { /* request */