From patchwork Fri Sep 6 19: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: 11135913 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 C6BB11593 for ; Fri, 6 Sep 2019 19:46:36 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id A68A62178F for ; Fri, 6 Sep 2019 19:46:36 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="GFSRuB94" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2392220AbfIFTqg (ORCPT ); Fri, 6 Sep 2019 15:46:36 -0400 Received: from mail-io1-f67.google.com ([209.85.166.67]:46775 "EHLO mail-io1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727053AbfIFTqf (ORCPT ); Fri, 6 Sep 2019 15:46:35 -0400 Received: by mail-io1-f67.google.com with SMTP id x4so15339598iog.13 for ; Fri, 06 Sep 2019 12:46:35 -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=GFSRuB945LVXBRtETQnhpmD7dDdy5iAMuEcvtZGMkDsgYSTOXkCHJvnKSvuj5oDmrj 11F8YeR25K5kCklyKpngpJJvQa2v28bND0KYopUEGhyOteaPQSJe7xgpEg9Ao2wxG9hg 08ht5G/LhyTD056BMBkzte0B97z0hUm7XsBPjU5pNUrVdr0RNj4NWJq8GSsRwnpFM2Oe cHErImOX9BuUfYLYv4jAhu3UeOtMthprkEI0kRlWg8AWVOr4FXLqxTsSbQ1tZP7ENuJ/ WCylfENidxaYUDffEJtzMDvAXEJwIfGyUMoENrATAbGTZIfP94a7WXL5oHZfAZEb4wYl YMhg== 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=ZwMKo6viPpNnDa1JkywG4BI9hnQZVMeuKimXdlLC0TfJH+0aC0W55HAPRaebN3ajCw sXp7t7WpsIR4tHRvTEBN4Sid2xqjDD+TGiLRqxhLJ8YjVekID/QLtMguoAQ48rl2NQXP caXHOyyhJ48t6oU2iYlbmdlfW9u18KG9qcJnXaIW3ZjvZFCFN6OdzNai9QyXP79AyniN bmpi3df3vEHZ+Vtk4lHTPxWjQV3F8EOQw6zqFjmDnd8soEm3O4EY1vfzWQ7hmXl2Ct56 moX0c1z3DdTu0b6xfVolHCikiO7NQYKhEG79lMXxV5/2yUdK3DNWIYA5K5tZan7n/lsf Yhyw== X-Gm-Message-State: APjAAAVIIAfMeTSasv2c/Kbk418+1VCUd/Rh0OSq9fWHP/Groy1NoTqE 1p7mp7WPbIbfgB4oa7AhZD8= X-Google-Smtp-Source: APXvYqwStMexRbSxYR+IhbevuxEfHIYRwH5jGAWJwOLSKLc1mx/dV/gXzfho/nv7uCMYiOM5SB3koQ== X-Received: by 2002:a6b:7215:: with SMTP id n21mr2254400ioc.238.1567799195059; Fri, 06 Sep 2019 12: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 i14sm5118085ioi.47.2019.09.06.12.46.34 (version=TLS1 cipher=AES128-SHA bits=128/128); Fri, 06 Sep 2019 12:46:34 -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 v6 01/19] NFS NFSD: defining nl4_servers structure needed by both Date: Fri, 6 Sep 2019 15:46:13 -0400 Message-Id: <20190906194631.3216-2-olga.kornievskaia@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20190906194631.3216-1-olga.kornievskaia@gmail.com> References: <20190906194631.3216-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 Fri Sep 6 19: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: 11135915 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 941A11398 for ; Fri, 6 Sep 2019 19:46:38 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 61AD22070C for ; Fri, 6 Sep 2019 19:46:38 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="o6THaawX" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2392240AbfIFTqh (ORCPT ); Fri, 6 Sep 2019 15:46:37 -0400 Received: from mail-io1-f44.google.com ([209.85.166.44]:37174 "EHLO mail-io1-f44.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727053AbfIFTqh (ORCPT ); Fri, 6 Sep 2019 15:46:37 -0400 Received: by mail-io1-f44.google.com with SMTP id r4so15426414iop.4 for ; Fri, 06 Sep 2019 12: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=c+qzd1t04M9iw91XTGhGIlq5TiPOqNPPuvUxmNaerE4=; b=o6THaawXrWuqK6EmSt1LW33lH9OaK8NozOgodA+q8gKBOpUtHs/YUf8nSyOvsXpKrZ /ZQgfxocnTDBtVnuXfgYxFBQPsZ3hNy+2hImumLRshvMDtsid09abbIm3DKA5UugEAuP X5B2Anp8zCWA/7ZsIAlXjN/Wsyb+ETwvZhJTNfldVUdj2daavhbN2PQvIKBgSonYdPBA rEZ9xL0GRvIEWI1FvJdoai9aeHaQkMu6EpamHHFPrNyY1lHLAV0DVBcqB1Rx6arUIYpw OH+7ihXzVK5rnUGMlFlPzgKkedB6uXpYKMuNI1K9f9YAkkUN+FkODoD8zEtMXQ7UdCNS SIFg== 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=c+qzd1t04M9iw91XTGhGIlq5TiPOqNPPuvUxmNaerE4=; b=gnLH+DNfUGUSJwsvq2HGJrm1ipwYLsABDX/B8HaTYzfiSxmLz/n3M6MGkA7NbKExgs eIoiqkIiRV53a4CGFyfGcfXgzND6bp0tvbtzmetYP+gy5T34RWOPfn5yMHMh3alfkHsG 8Ada8vk7LNLa7SJT9uNasBm+18AL97oId9picgwX7KTR6g2t0jKbx82L1BEQ82PI6xrO If6b8LhKQtnRR7XER4qOe9MC112f1V0RhPjfpB85oHgiBdVjFpgB31mZbON9rU8zx3xy clbxeUY5mhhGS+7+adsOumXmeYm/14x5HUgapbGrVCBp16n3aKAS+BU5lYlEbs5bVoFq 9xnw== X-Gm-Message-State: APjAAAVMqSg5CgdAC0FRh2qqVSsN1CgGhsO84le3SiN0diO4va4lRf6z g8kOVXSX02mJTedSWQipxws= X-Google-Smtp-Source: APXvYqwOQmx1HyUeVoCXG3H+7fBucjsxijQKi4ej5nsmkl+ZuS/xTlfcRIiZEOeBGclWIK8mcE/UFg== X-Received: by 2002:a6b:b8c3:: with SMTP id i186mr7247840iof.194.1567799196067; Fri, 06 Sep 2019 12: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 i14sm5118085ioi.47.2019.09.06.12.46.35 (version=TLS1 cipher=AES128-SHA bits=128/128); Fri, 06 Sep 2019 12: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 v6 02/19] NFS: add COPY_NOTIFY operation Date: Fri, 6 Sep 2019 15:46:14 -0400 Message-Id: <20190906194631.3216-3-olga.kornievskaia@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20190906194631.3216-1-olga.kornievskaia@gmail.com> References: <20190906194631.3216-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 ecfaf4b..5311def 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -9853,6 +9853,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 46a8d63..d76c772 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 Fri Sep 6 19: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: 11135917 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 C633214ED for ; Fri, 6 Sep 2019 19:46:39 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 9C4FB20838 for ; Fri, 6 Sep 2019 19:46:39 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="LsG6kqRB" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2392248AbfIFTqi (ORCPT ); Fri, 6 Sep 2019 15:46:38 -0400 Received: from mail-io1-f67.google.com ([209.85.166.67]:35821 "EHLO mail-io1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2392221AbfIFTqi (ORCPT ); Fri, 6 Sep 2019 15:46:38 -0400 Received: by mail-io1-f67.google.com with SMTP id f4so14693069ion.2 for ; Fri, 06 Sep 2019 12: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=Obq2s/I8IROUITybj5QBlF9nrcnOtRzdlJGuACz59bo=; b=LsG6kqRBQYXTc2rxg7IZT3xEqd42N6NIED7R96KN77UWrZ+yj7POfAY5lI0Gzlxqk3 5Or0GBZCyR6Dddwsm4SnI+l3u/aKZA4TBPiuaVddv9aZ1/se/ZOc8tpVxChCAzuWVOP3 5rh/F/0ebauJKkHxIDFuhjpKQ3mgVgnynnaK9lkx931q2jJi7w5G2Z5k5zVIj8hWsUbs vhs+QsMglk8at6K2wTEoHGmzdRvdRaSK9iUTDAh/OV5ZXGxD3gjDiiJwnX3s7121L9tc xjr1DVTWnV8IeU6n3D2UKwFnCe+2Kx9mAg4xpjPJNvyuzdcDB8LWBYmm/4CnXhOIqpMr KB3Q== 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=eV+dN1uzvY3okwX5Q2d9boKfqrRoWHXavMrHDCceQJFP8TXX8AYW/hix6xWxbquFmI 1yXdhsm9JKfw9PdQla/eKyGtADp8oWw6kTnGD2NDOerPzBy+vY1ejsDw+mJyO+eP5+wB oCstSwLPyHrOP9UhPbbgYVJs5vKYoo63Sc8n6TD5Ztif0BEXSi5HSeyjouTacxIT+Ggw O3Ve1xIcfHwM5ylj0XBb0LwcGZlyIzMU4DDdM9gRLhx4gytwbzfgrzOmZaJXBrarauQ4 XWrx9CTKbVpMQ9PZ+u3R/aI3SNVF7VF4TyVJT6efB/KQnAJdgHGtalvyEb6qj8SeJeud jJvw== X-Gm-Message-State: APjAAAU3ziT/wluk8xTLYcERxZlatKPT/11tHjkGmZZf3uw2VNYGZjK5 omINeaPq+cBPJRv6zOgx4Z4= X-Google-Smtp-Source: APXvYqy42zH+XLPEgrscgjDtWytJkEIeI2doKKrkeR9IR61d548ejLjs6+Wk1i8Dhvbt84pR2ONsZw== X-Received: by 2002:a02:a909:: with SMTP id n9mr11570477jam.57.1567799197098; Fri, 06 Sep 2019 12:46:37 -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 i14sm5118085ioi.47.2019.09.06.12.46.36 (version=TLS1 cipher=AES128-SHA bits=128/128); Fri, 06 Sep 2019 12: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 v6 03/19] NFS: add ca_source_server<> to COPY Date: Fri, 6 Sep 2019 15:46:15 -0400 Message-Id: <20190906194631.3216-4-olga.kornievskaia@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20190906194631.3216-1-olga.kornievskaia@gmail.com> References: <20190906194631.3216-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 Fri Sep 6 19: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: 11135919 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 258BD1593 for ; Fri, 6 Sep 2019 19:46:40 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 043F520838 for ; Fri, 6 Sep 2019 19:46:40 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="bUwu4sk+" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2392221AbfIFTqj (ORCPT ); Fri, 6 Sep 2019 15:46:39 -0400 Received: from mail-io1-f65.google.com ([209.85.166.65]:41443 "EHLO mail-io1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727053AbfIFTqj (ORCPT ); Fri, 6 Sep 2019 15:46:39 -0400 Received: by mail-io1-f65.google.com with SMTP id r26so15344877ioh.8 for ; Fri, 06 Sep 2019 12:46:38 -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=qbMlSBpf06q9f17aggELxyyLLTxlNI3h6Qh/Z4qZNW4=; b=bUwu4sk+0MImOxqv79lWM1M6IyvQRdSROOTwn+LEs4r8SCvAXGMw0aOKgMIrONlI/G ASRQrQgcMbNPQeOmGZjIyzCrJQ25QbERiyyf9FMFdkhKF/mf7phavv3/tqJLL+DnSXxL 56giWW0Ich5diR0ZWfF0sJ4lhY5iZxxcNOvgKF09+kp6c9miF62jnXkrh81UrWSUvAld c+3zlPeM0Lyeck9Jq8y4Nk/mwT2jCh9k7rGk9T9cJQpW+WuuLHodDYT0ut2xKv5DSkjM 84o4FMvPq61EJdRveCwwt4BgDgYHL9DD/7FG/ZunbDmeByuUfbiPwiS4OxXT5JKm6hU3 X92g== 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=qbMlSBpf06q9f17aggELxyyLLTxlNI3h6Qh/Z4qZNW4=; b=NYXFih2egvj4xlGqHmUFVR2p3zlTytlP3iopXkWM64ut7YMkOgimD0NH+ZsA9zH4EM 9QaccDqGJOXIbeqTjuqI0UYXEG1nEd/pidE7AYFGwZWJFGqbvm7uzCHH5Hv5D3FXiOo4 2fZE7aNcQupU+u5P//5heZlz9mdYtBc239OPETIt4r6CUnxasEKSITmAJWUUEu85asWa gKXqWthxnZZmhQGePJ/xhmRVzjsg/5i+rVx9cqqW8hOFssiMKNd/Y9SWp0ZRmuHumpWT V8IbOmh0upc0JYsacB83LcTda61NZIdbONbGp4HPxCu5rBIXfQzt4G0AqO148kbHQNzs p1nw== X-Gm-Message-State: APjAAAVnsSzgMUlfUMivE+kD1w+ULaXjvzhZ5bUMz2YBQMU/SmvRYypV 1vuuag0XuZdpgca+HBv9VpI= X-Google-Smtp-Source: APXvYqyRcwEGbaHiIfWvFRr2EWCdyNN4Zy2jYSCbj8+UindlFghkglKfjFtPAY4EvhsmmlipazhmrA== X-Received: by 2002:a02:a516:: with SMTP id e22mr11859833jam.77.1567799198190; Fri, 06 Sep 2019 12:46:38 -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 i14sm5118085ioi.47.2019.09.06.12.46.37 (version=TLS1 cipher=AES128-SHA bits=128/128); Fri, 06 Sep 2019 12: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 v6 04/19] NFS: also send OFFLOAD_CANCEL to source server Date: Fri, 6 Sep 2019 15:46:16 -0400 Message-Id: <20190906194631.3216-5-olga.kornievskaia@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20190906194631.3216-1-olga.kornievskaia@gmail.com> References: <20190906194631.3216-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 | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/fs/nfs/nfs42proc.c b/fs/nfs/nfs42proc.c index e34ade8..bbf7c1e 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, From patchwork Fri Sep 6 19: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: 11135921 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 268AB1398 for ; Fri, 6 Sep 2019 19:46:41 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id F160D20838 for ; Fri, 6 Sep 2019 19:46:40 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="g+WjSQFv" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2392349AbfIFTqk (ORCPT ); Fri, 6 Sep 2019 15:46:40 -0400 Received: from mail-io1-f66.google.com ([209.85.166.66]:40353 "EHLO mail-io1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727053AbfIFTqk (ORCPT ); Fri, 6 Sep 2019 15:46:40 -0400 Received: by mail-io1-f66.google.com with SMTP id h144so15381010iof.7 for ; Fri, 06 Sep 2019 12:46:39 -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=nUiJA7pzR4QkYh2b5I6Ld0az+4QHqkg6mc9NxtzqC7w=; b=g+WjSQFvGuk3oDnMKLRzi+xax49MypDaEJoDSbGCZtK4scF/61p72yHe61T8aaR9l3 lqvIXa2hnZP4kboRozX6QQufhQFw/8OQlC+yU+OFBI3JPKXaefaQQYXq56Juk+vhEhmS 3K/rWMyThOJG7xgwMbvdKKO1pfxaAAFNuGHYEI0mBh0a7mWAv/1aEu+qWJev4+KIp0El wRYUkiq73DRhXj8+EPhjCG2o99sG9QhN85SclqAHhXeVyLBTGH/KGvnfpxEK9GNu/JZ8 uI31BP1h9MekMU7G/dK8YuEy4j9Z+N8fDg3QoHMU2BmyXcAt8NtV2qX6enPir7tUvr4D zwGQ== 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=nUiJA7pzR4QkYh2b5I6Ld0az+4QHqkg6mc9NxtzqC7w=; b=bYBsaU1lQN3ESPvAp+7paV9VMjBLq5fOw7MTUdCDkNVHK7WHrfX2IZ9EsjNI3jKNfd dgUyzII3+xy5LeDvDoS2GPONhuRtDqG3sYRt19i/BorjUkEqU9Yw+GSIgdynwAENmcHR dD7ZK9MQYzN/nXWkWzi1Cag0cA35e1lZxDF8u1Hh2+FHoRugOb6jBh6NMwzJH4wUv/W8 1lU9dVzl5iRmn7nd0j9NNYVWQEpZnITbUj8xxX26Yis2sqt289QmocD1i678sbABXbAc BvYJVLScrMZCQ8WbpFrtKUjpj70hGIxw8KGvmFbXrsI0ISN0EbHDxEe1Yj+Eu6gz5IRd 8t0A== X-Gm-Message-State: APjAAAV3Pg2Ot/aIOyKcszVE1bHP4ipjNrj9zjTQm3Tap/NDzH4V5F/C aqpyvQhb4ygj7KL7rfHvfcY= X-Google-Smtp-Source: APXvYqxFYD30/nH7tCPnwtg8xX4DwUzxv1DjRo83JU6i3S3biAn8/e1nIunkse2Kpz1ChRQmQ0de9g== X-Received: by 2002:a6b:bcc4:: with SMTP id m187mr12993766iof.16.1567799199108; Fri, 06 Sep 2019 12:46:39 -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 i14sm5118085ioi.47.2019.09.06.12.46.38 (version=TLS1 cipher=AES128-SHA bits=128/128); Fri, 06 Sep 2019 12:46:38 -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 v6 05/19] NFS: inter ssc open Date: Fri, 6 Sep 2019 15:46:17 -0400 Message-Id: <20190906194631.3216-6-olga.kornievskaia@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20190906194631.3216-1-olga.kornievskaia@gmail.com> References: <20190906194631.3216-1-olga.kornievskaia@gmail.com> Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org 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 5311def..7ea446b 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, @@ -1713,7 +1712,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) @@ -4026,7 +4025,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 Fri Sep 6 19: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: 11135923 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 20F1E1398 for ; Fri, 6 Sep 2019 19:46:42 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 0188820838 for ; Fri, 6 Sep 2019 19:46:42 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="CE0zowZy" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2392361AbfIFTql (ORCPT ); Fri, 6 Sep 2019 15:46:41 -0400 Received: from mail-io1-f65.google.com ([209.85.166.65]:45901 "EHLO mail-io1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727053AbfIFTql (ORCPT ); Fri, 6 Sep 2019 15:46:41 -0400 Received: by mail-io1-f65.google.com with SMTP id f12so15340625iog.12 for ; Fri, 06 Sep 2019 12:46:40 -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=67LNqASa/4OalrIFRXKZ3VWKnxUt0Iof65Y5SdHMQ6w=; b=CE0zowZyXGXFO7ACiVpuinIZg4fk74WgVYXanDUsh40ReVJqxo0DJF2n3XAl4Tbeg9 dq8ajpHGRJJe4whAUGB0fMEWpsi4Txdc9O8P7afVsY997NfwaYiDj9Xi+gjNEBMNNUl9 OlOCzTGoFlbnjIWGkEd+T3FSdU9JvIZM8svUF3HBNJYWbU8DwtxRboTCAuPe1VnQQ5+t tLonv0YrsZY6nipP/M/sBVHn+Nx+4yBOIgRe5x2DvTt2dko0c/GMefwiBjLfpHA4/7rP ZVEBIiO6mKE6YBf5TuFWdTxZGYo1HvxVEPmNn2Sfgywz7HXc93X3At52pZq6xpXduUf+ /suQ== 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=67LNqASa/4OalrIFRXKZ3VWKnxUt0Iof65Y5SdHMQ6w=; b=dHHF8IeKdoOV1z3nmM+u754rCwIIgB4JuIhy+Fj5rx7QPsisdOxR9uLKED56+Gw/Xa pdEBSkLpw80HJjxK11VoLHzMjN1Y2pL3EAQb0uM6bI4TyurCxRHXVgUpfvmvcKgsAuid 2kdrrLEhdqyYoJvBLiYyQ3Dy7fTnpf1bZxqOn9ahwueEIcrKr93lx7GPzLRuhqy1wkNn AP195ZZz8a+pwfBcy1Hxp7b6uY4t/cXW1q9pBh4VaYAW6DpBTQLj1o4ldpkVmR0e8DNC bLHFeWbcTDrREqXxFTdqYkR02cmJRQG4rXJKN0dT5W7+/JXl5+1A2j8O7YUqzQM1NP0Z j2Zw== X-Gm-Message-State: APjAAAW9+4kXMPkx8AUOQB3tVgGEIonHa+7lr2wIMxf1DNSqFLcHFYIS tyuu0FQ5rc9RqPbiz+nS6TA= X-Google-Smtp-Source: APXvYqz/0y+Hhrv/xrvSbaWXuuLn6F5GWt9Dk7txNiEiUl6YCVR0d2275LWDIasBA1/1U2jUYhcuFQ== X-Received: by 2002:a02:c546:: with SMTP id g6mr11999268jaj.59.1567799200144; Fri, 06 Sep 2019 12:46:40 -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 i14sm5118085ioi.47.2019.09.06.12.46.39 (version=TLS1 cipher=AES128-SHA bits=128/128); Fri, 06 Sep 2019 12:46:39 -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 v6 06/19] NFS: skip recovery of copy open on dest server Date: Fri, 6 Sep 2019 15:46:18 -0400 Message-Id: <20190906194631.3216-7-olga.kornievskaia@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20190906194631.3216-1-olga.kornievskaia@gmail.com> References: <20190906194631.3216-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 e239451..f205037 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 Fri Sep 6 19: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: 11135925 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 967C61398 for ; Fri, 6 Sep 2019 19:46:43 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 77A402070C for ; Fri, 6 Sep 2019 19:46:43 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="nlC9WqpG" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2392414AbfIFTqm (ORCPT ); Fri, 6 Sep 2019 15:46:42 -0400 Received: from mail-io1-f66.google.com ([209.85.166.66]:46801 "EHLO mail-io1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727053AbfIFTqm (ORCPT ); Fri, 6 Sep 2019 15:46:42 -0400 Received: by mail-io1-f66.google.com with SMTP id x4so15340322iog.13 for ; Fri, 06 Sep 2019 12:46:41 -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=s6AarPquzkHm5tiN4Chfneb8capNztVCqvBC79jNDEI=; b=nlC9WqpGDCwS/rZm7rnEjPob+OQAoo5sI0Ike+xY3Nkg6WUk0z6LnomJsjM1rzpS32 heA5VXzKvoWFcJNe2AO/lfciWkGgYRkWy3S3zrv5PfsI/Di5p+R9EZrmhRcgu4qud9Br XKrnlf0ia0Zgyv+UNPQHmMJ4xqokbYODqfqnn4DW7Bn/YRWB0auA097PhzlP/qb7Apdg qlzzS+dNoMdkqCoiNy52BU+4UJteW+gPkk5/zyeEK9bSU+gSN5HIh95ObLhXjPwJ4Z1g tLAxK0t4Dp6tG6dgHlpDIO2PgTIbXKdPcqUapfs48fh7rjnAGjaZeAgsOF/wZDCFrWW5 SQmQ== 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=s6AarPquzkHm5tiN4Chfneb8capNztVCqvBC79jNDEI=; b=FBDanI+XeyYkdyzwW5NQ6DJBEaaAC3dNBt0OPzjlnnh9duskGnHkVZyKgPUG662xIO xH/4B3LqN723Z/U3kmAzYqbGWNWLwpWti16dIh2md2EXgUfPrJbQho82L0MXflS1+MZ5 cIKFPWW/UOM0cJAznEMINW+2Y+niQWhNk6YMjQ94dCCAa+dfeu4e6KdpjCLuPldO7Ljn p/LpQPcz6mx95/6jfEuFdtImnaaD5jtOCSlLsPJzFYpWZ0JW+tFSWnDnCX7iA6RX2Qha cvFG5WzjbZwfPwewZi2UkJy99GxpsZCr2MSojiBuR0Wf31MsmTjXAQLVThP6Q7nQVOC8 ZTEQ== X-Gm-Message-State: APjAAAV3DvTu8vCYjFUD8vsac3PJnzZdkZwOLev+8rJuucVzOHEQFOqe TMNMDaoWBWQQm8cM6fd4EtzmodVA8UQ= X-Google-Smtp-Source: APXvYqwhBd7u88D3/j9c7KO+l13CC9q6nPPTidJRVQT+f2WXTAs1B7eBsCI2pBmJuCjmc/ePS1TtEg== X-Received: by 2002:a02:7044:: with SMTP id f65mr12084078jac.37.1567799201214; Fri, 06 Sep 2019 12:46:41 -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 i14sm5118085ioi.47.2019.09.06.12.46.40 (version=TLS1 cipher=AES128-SHA bits=128/128); Fri, 06 Sep 2019 12:46:40 -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 v6 07/19] NFS: for "inter" copy treat ESTALE as ENOTSUPP Date: Fri, 6 Sep 2019 15:46:19 -0400 Message-Id: <20190906194631.3216-8-olga.kornievskaia@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20190906194631.3216-1-olga.kornievskaia@gmail.com> References: <20190906194631.3216-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 bbf7c1e..f8ebd77 100644 --- a/fs/nfs/nfs42proc.c +++ b/fs/nfs/nfs42proc.c @@ -393,6 +393,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 Fri Sep 6 19: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: 11135927 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 1322C14ED for ; Fri, 6 Sep 2019 19:46:44 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id E869020838 for ; Fri, 6 Sep 2019 19:46:43 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="AJ+6oI8A" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727053AbfIFTqn (ORCPT ); Fri, 6 Sep 2019 15:46:43 -0400 Received: from mail-io1-f67.google.com ([209.85.166.67]:32927 "EHLO mail-io1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2392364AbfIFTqn (ORCPT ); Fri, 6 Sep 2019 15:46:43 -0400 Received: by mail-io1-f67.google.com with SMTP id m11so15469746ioo.0 for ; Fri, 06 Sep 2019 12:46:42 -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=OMSnhxhLm9jAGT4vNx3iX0q57Vtf9G2yxU8MZWSWriQ=; b=AJ+6oI8AxoCVtperw48ywjEiKV7Nr8FpahrRokJJT+UrQ9atAkAEeq8CoKeZSmAphM tZ55WgDTLaFNV1M7g5W70ENU21s+vVZ3oPaFUsXYbbDPz4ueuD5qH/A5WRB4p80nyO0v QSWPzczdjLvob2kEyesoofJgbUwxEgP5Ro98Jw4jidT0PpD82A+8mFYNiKZycZsz2sxZ U5DOPaeD01amlEumSUiuooHdloVWW9W8pr1QQ2+k9O7TfPATmniRurvw4ilEhuVJ01mT Ob7kMNB5RW/xduk3VrgZo55YhKr5JLJtpU/hoTNTufF+M3rTZq2id8dwqUq0E8RZ9oks tR+A== 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=OMSnhxhLm9jAGT4vNx3iX0q57Vtf9G2yxU8MZWSWriQ=; b=lqk2cPwszmMb20DdqEKoQiZnRXGrOCBCUy45PMEUye0cJgHtXJv82rKM/NRwUAuZkF 9H+CmXT73YqXYXzzNMG76QLwAb+VRkR7XuSp3y0o4/sBOzTlNOPFs2K+1zIWhIW4wH+Z R50Fv4X1l6G8OXAjhCF3r+QFeshAmqTwUBHgxjJ9KEiXNqpT/iR/r/7MDgDyB7OaRZBG vJo2GgNHQ51m6K3x2nusl7/BzwLT489peb4ZW5JDT251Iz0Pf44yw4qJAcxI2UAwXzED 5RYzKYc2c+OgrIO+rZjc0GwEJAFFh1AJZPZYsnWuSMEZj3PSNKbmdiitE0Nd7NszmeLT DHbg== X-Gm-Message-State: APjAAAUSs9zp+Nf2+kgfIyAewXhirsWdBeJuaU3QVBBPNafaaOrZ9Dva D19jALJLctB2Cko7soLJ5B7hgsOUITY= X-Google-Smtp-Source: APXvYqx/z1hSw4+ZKCKigYmnRRHx9D1VNUfLUzGH34a+8LX9ShMwcEEEg12lNkp1L2lc4UMlVYfh9A== X-Received: by 2002:a5e:a80a:: with SMTP id c10mr1814936ioa.122.1567799202252; Fri, 06 Sep 2019 12:46:42 -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 i14sm5118085ioi.47.2019.09.06.12.46.41 (version=TLS1 cipher=AES128-SHA bits=128/128); Fri, 06 Sep 2019 12:46:41 -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 v6 08/19] NFS: COPY handle ERR_OFFLOAD_DENIED Date: Fri, 6 Sep 2019 15:46:20 -0400 Message-Id: <20190906194631.3216-9-olga.kornievskaia@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20190906194631.3216-1-olga.kornievskaia@gmail.com> References: <20190906194631.3216-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 f8ebd77..705fe69 100644 --- a/fs/nfs/nfs42proc.c +++ b/fs/nfs/nfs42proc.c @@ -393,7 +393,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 Fri Sep 6 19: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: 11135929 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 7839714ED for ; Fri, 6 Sep 2019 19:46:45 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 500F420838 for ; Fri, 6 Sep 2019 19:46:45 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="c3Czm2n8" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2392508AbfIFTqo (ORCPT ); Fri, 6 Sep 2019 15:46:44 -0400 Received: from mail-io1-f44.google.com ([209.85.166.44]:40252 "EHLO mail-io1-f44.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2392364AbfIFTqo (ORCPT ); Fri, 6 Sep 2019 15:46:44 -0400 Received: by mail-io1-f44.google.com with SMTP id h144so15381463iof.7 for ; Fri, 06 Sep 2019 12:46:43 -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=YOpZxdO0uo3j46VJ/Z3oyEDDiR1vrehjo839BfCp3Vg=; b=c3Czm2n8G/9B3mIWkCCTUjgLZHvUVS0aXsHRncZEc94BMqX5Bs6mnPdXUtDVuJQGHX WZn3fCZojukQdazdhyMXRfgO3Z5QMwcW4XyljiZzfUFQQRxLpWqv58WY5u6airGO+YEj cfosKNuIpIUedPbAgufqae4MQvOs0naDNDWgraJMFJJirs4uAC92UmB0EfqbEZ7WyO1u y4DgEcSKx6n/9p6RKueRBeRPEqd3VcUtKSwaocPI9OdBIaT1cNC4kBIEZnyvrUosWG3P YoYdbW0taSPnfDNgBB7Bg0MQx1C0L3QfiEGBeNT3bhtuXsaKZwpbb0wfMHAK22YRDvrH S+4g== 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=YOpZxdO0uo3j46VJ/Z3oyEDDiR1vrehjo839BfCp3Vg=; b=KRwF0P94E0cqxTIWMsp2/iepwr3ejkaNa7lYj/rcvEVvDhKav6ANYj4UpUWlPAVbJT WWW9GCKb6M764JgdSgXYtxkp180lv25cO8uoUbFrAtXqsd8P/6mBPA0PtSNPanNAVu+n 0eqXb6n6YUKORpuQmZ8gBe69D35CovScbKO2y8K6AHDsaCteZG9ga0basPNAH1q8hfE1 xuaJRxF86HAY3y3FkNTC/jBcaU5riMh0KDL8gLwd3prx+yufL7/uj8O6dIPmbHh9v3pB C51QdfgBhe40wuhUhFq/sm2Cw4U1bQwHbLP/4Dcj23UVgzmzm3ojm4CcRvLqH+RLIIGX gPYA== X-Gm-Message-State: APjAAAXCGpKyaRvCL62qlvZFVKMUb2vD3TuIvurb68WgW3STrfyq2mqm qC4025JYkBkHIHvadghJhEap04lez9w= X-Google-Smtp-Source: APXvYqwMwbLcDviwaY3gDRGRGWjsrLOQQbX4ZwcNz+0UCh42S4Epu89xft46VVYDnMs8vldxKQpANg== X-Received: by 2002:a6b:f80a:: with SMTP id o10mr2273899ioh.148.1567799203376; Fri, 06 Sep 2019 12:46:43 -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 i14sm5118085ioi.47.2019.09.06.12.46.42 (version=TLS1 cipher=AES128-SHA bits=128/128); Fri, 06 Sep 2019 12:46:42 -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 v6 09/19] NFS: handle source server reboot Date: Fri, 6 Sep 2019 15:46:21 -0400 Message-Id: <20190906194631.3216-10-olga.kornievskaia@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20190906194631.3216-1-olga.kornievskaia@gmail.com> References: <20190906194631.3216-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 | 15 ++++++++--- include/linux/nfs_fs.h | 3 ++- 5 files changed, 64 insertions(+), 26 deletions(-) diff --git a/fs/nfs/nfs42proc.c b/fs/nfs/nfs42proc.c index 705fe69..918dd78 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(©->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(©->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) { 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) @@ -387,8 +410,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 f205037..ad8bc31 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c @@ -1556,15 +1556,22 @@ 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_SRC_SSC_COPY_STATE, &state->flags) && + !nfs4_stateid_match_other(&state->stateid, + ©->parent_src_state->stateid)) || + (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); + if (test_bit(NFS_CLNT_DST_SSC_COPY_STATE, &state->flags)) + complete(©->completion); break; } spin_unlock(&sp->so_server->nfs_client->cl_lock); diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h index 0a11712..6ff1ec7 100644 --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h @@ -195,7 +195,8 @@ struct nfs4_copy_state { 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 Fri Sep 6 19: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: 11135931 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 526991398 for ; Fri, 6 Sep 2019 19:46:46 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 33E3F20838 for ; Fri, 6 Sep 2019 19:46:46 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="gf1SQzbX" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2392363AbfIFTqp (ORCPT ); Fri, 6 Sep 2019 15:46:45 -0400 Received: from mail-io1-f68.google.com ([209.85.166.68]:46813 "EHLO mail-io1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2392364AbfIFTqp (ORCPT ); Fri, 6 Sep 2019 15:46:45 -0400 Received: by mail-io1-f68.google.com with SMTP id x4so15340713iog.13 for ; Fri, 06 Sep 2019 12:46:45 -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=iqb1sMJUZdYvSisERxCuRomsMh4ef2iO2SKKCvgRqNY=; b=gf1SQzbXY5KP0xRsp66vYlnOBb/sonhm4bSQpyz9wz0lPr4WXziT8ay4YsJkd0Ha9M asva1rgLKCwsQxhL4/09D4NAbHYQfCHxlt5ygi1n1uWClXAhKj8nrQQ/ARo2Go0/w8cT fpmN7/aaR0TrlIN9FLZZGY1uKDH5nVLqi0IW8dmZaRuCMlMBno3RhKhArpF1BYpKz70i XZV5dXsFvfnh36jt+f8HW/gQvMlY2JoZCHZrJsWcF4tzRMMyhJUuR31ozqSvhq6Bhat+ uZrCM0/pV0nxRAlPRor1NO7bIqTHLWTCnQC2QKL7YeIcbKXUM47y1KSm1pDZS5rma/p/ GbHw== 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=iqb1sMJUZdYvSisERxCuRomsMh4ef2iO2SKKCvgRqNY=; b=lQdBldU5P1QUPxJ33i0q7+IuXPtu0B0UiM33Te7CddPfX6mFuLrabk4NjwyX2VkBm9 cYIXdk71ou+pzaOF231isxtMppE63fDyhiznCKVZl5O4nnFEgDYoqrVHi+HMkS1dxEhq nCALeZnY8BM9qtjhB+hJNI6Z7z7fvhaP1izC7fFqQxfwW3sjqOUK9mYHWWa/JUa5K4yr XFNuJBK73mwFdYeBWKH1QxpRzCN5DZw8mDn3zofBFauI/FeDlF9s1GUaQV+8iXp6jSad hjXuGeVn8VpK1/nEBOiu9kIsKntaBxWv+Mu6r9ro3fiLokPUjYB04f/6Y5f7Gm/fmvQi 8Zyg== X-Gm-Message-State: APjAAAXxbDsUa41hTS5sg8chGGMUn6qf0GrAsUWyYt8rkXX/CJYjmNMw gS4TnwZ8qNhoV3zmEseVIIGtcDPBBTQ= X-Google-Smtp-Source: APXvYqzIK4GYoTXFPGkziwj0AJdBuG4KytUffdUfDuK9PsR+imrr+KpsNMNT/7Qifpt82dVycqjWLQ== X-Received: by 2002:a5d:8919:: with SMTP id b25mr1745048ion.123.1567799204600; Fri, 06 Sep 2019 12:46:44 -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 i14sm5118085ioi.47.2019.09.06.12.46.43 (version=TLS1 cipher=AES128-SHA bits=128/128); Fri, 06 Sep 2019 12:46:44 -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 v6 10/19] NFS: replace cross device check in copy_file_range Date: Fri, 6 Sep 2019 15:46:22 -0400 Message-Id: <20190906194631.3216-11-olga.kornievskaia@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20190906194631.3216-1-olga.kornievskaia@gmail.com> References: <20190906194631.3216-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 2af30b7..37b13cf 100644 --- a/fs/nfs/nfs4file.c +++ b/fs/nfs/nfs4file.c @@ -140,7 +140,7 @@ static ssize_t __nfs4_copy_file_range(struct file *file_in, loff_t pos_in, ssize_t ret; /* 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 Fri Sep 6 19:46:23 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Olga Kornievskaia X-Patchwork-Id: 11135933 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 C4F8A1593 for ; Fri, 6 Sep 2019 19:46:47 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id A55B620838 for ; Fri, 6 Sep 2019 19:46:47 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="jDbrpG/D" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2392509AbfIFTqq (ORCPT ); Fri, 6 Sep 2019 15:46:46 -0400 Received: from mail-io1-f67.google.com ([209.85.166.67]:45925 "EHLO mail-io1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2392364AbfIFTqq (ORCPT ); Fri, 6 Sep 2019 15:46:46 -0400 Received: by mail-io1-f67.google.com with SMTP id f12so15341274iog.12 for ; Fri, 06 Sep 2019 12:46:46 -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=jDbrpG/DuFLTBs765iu9l69XllXeLOL/F0ipjh4ACio2/EgnISw3Vq2MzoYKK04L0K BkviwOB3AwZUaWkqcRU0SzDD6F+auJEt6Gq5pI3myk2M8kObrrBFjg+pX79CUhV16Pag N9eX/QKwBTkpUE5ZKVYvKKgDUHIFaSOz0q2aXZ4FaF/ouqlbkIWXIemepYPGP9oyOiA/ moX6efuJ7YMHqWFFz2pgQv1n6jjPcZayMQAl1gX4kkdct88cnYAYHA14fni0JKm57DgJ OL3fqfyhnTT+B6YqerYPtJYeq+TFacjK9FMHJG2JmZ6F/DX9zxx36zw0CsiBwfdbm/Ra 6KSw== 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=HDWAQq+IUa1ChGIWDUR1faidbuJtp9Rdywk/7B+yYXw5ST8LmrRrv1UxVpGNvY5f0I jNo/RkuSjS3SKBy8rJwx0YXfIVf1fg71x+v21rEN6c13/P9a/WS2uKTCLiYj1LU+RZ+D BC/B/Y+6t5HauEJtT0vOwtL3oCmihbw72+xF/5lizvjBpquPAe42cM1BKkFdOUsTkkEP rxjgWMg9TXDNtIrXjwK0jzz7kBLRr4ZcCyXjTIirZwtHYZM1Eyjn6jGiMun88yFajx1p HuWdemxk07P/hAZFIhBKWq03u4Jp0z5WykY02UT4xdytaNhpZaWuPpWBo5ex8jRvvc6/ 4CuA== X-Gm-Message-State: APjAAAUu5kxoJ/5Pyme4M7FDGmaiuCoWDErvo+nyzPhtu7O+SVrlvrO1 qVCZrYXaHfFXvr48EULWJXo= X-Google-Smtp-Source: APXvYqztxOm055zPL2mqo+7RDPoI7BKnRREIQsoOTooIh0Trx01+q8HgajEOteUbTNDlIOOLTlrXWQ== X-Received: by 2002:a02:a403:: with SMTP id c3mr11338349jal.93.1567799205572; Fri, 06 Sep 2019 12:46:45 -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 i14sm5118085ioi.47.2019.09.06.12.46.44 (version=TLS1 cipher=AES128-SHA bits=128/128); Fri, 06 Sep 2019 12:46:45 -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 v6 11/19] NFSD fill-in netloc4 structure Date: Fri, 6 Sep 2019 15:46:23 -0400 Message-Id: <20190906194631.3216-12-olga.kornievskaia@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20190906194631.3216-1-olga.kornievskaia@gmail.com> References: <20190906194631.3216-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 Fri Sep 6 19:46:24 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Olga Kornievskaia X-Patchwork-Id: 11135935 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 849C014ED for ; Fri, 6 Sep 2019 19:46:48 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 6285620838 for ; Fri, 6 Sep 2019 19:46:48 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="pNTTzHJw" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2392530AbfIFTqr (ORCPT ); Fri, 6 Sep 2019 15:46:47 -0400 Received: from mail-io1-f67.google.com ([209.85.166.67]:34835 "EHLO mail-io1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2392364AbfIFTqr (ORCPT ); Fri, 6 Sep 2019 15:46:47 -0400 Received: by mail-io1-f67.google.com with SMTP id f4so14694148ion.2 for ; Fri, 06 Sep 2019 12:46:47 -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=XL+yl/IdkZ6v8a9Bn/wwa3yKd1v2tHt/DxTYczYrYOw=; b=pNTTzHJwCgWlHmiE8DHFzPkm27VvVifOfwJ4a7Tl+PxqbMW4+NeQlz60pOytkXqq02 NMAVMJBk77Y5QS1jY4AnbAGd3JSNNL72r0H0U7b7TTb+0ydqmW2XNLt5H+irRDGxLt1W gtJ8cBjeaW6XnlIv+8ndQstrfvjbGNwxP3aJRAM0BKWRe1eyDJWRd2hTH5l5k8To7iMI RabdqTxRKAMfM/NzOR3EsbHfudRtk7RLtZl+5I/fGKoxBYhDlPIpDL3uijqxFK17IVps D5sAGElTES8jnsxBMMK8NwhIVPZcV50eMZUtyBiJShzTTFmy4oADgoLYK0D8pvPmFpaH ZGgg== 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=XL+yl/IdkZ6v8a9Bn/wwa3yKd1v2tHt/DxTYczYrYOw=; b=Sn09VmMHG/SP9hls3Vne91Fgr5CwOeW6tY9HxfsOW4Q1tlqH+yzF7Lagzdhyu4X8j5 LW3PcpFl3llXKczygUxJZYSJj28I5HbOlH9G3MTPQv3hcW5xgvRnk3scGBkwsHDemsol 8p7sjbl5dt0WvXn/hFrLYkq0V2Xbnmyh1aLwdjL6ARaCjMS9YfK4YRy0BnKJ5l9IclQu ufmi8ndS3byjiYlXZ2R1XfyEj4i5ZH8SejkgOgVnhrB/Fpy9dTG/4G5mpZN544VszVIm aQVM3UNbgj2YXl4HtQi3rk52H/oZiSuai7GIArIIFY1nq+0qi90QDGQNupaJNLOstmW5 IvpA== X-Gm-Message-State: APjAAAXpPAGiLM5PHuiEZ4UvQ3pBZqbF36WpwXgPGYd5N1rQsgjOM1QF bhe6KNLihei+u6WZ/6eeDZM= X-Google-Smtp-Source: APXvYqw65dprFjRsWkUyZmzMTp7eMnTLxVkYQGpNxVYlUr7fnoAXPugDy/eCFVr+LZ7sbcHK+qT/0A== X-Received: by 2002:a02:9a12:: with SMTP id b18mr11639326jal.70.1567799206567; Fri, 06 Sep 2019 12:46:46 -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 i14sm5118085ioi.47.2019.09.06.12.46.45 (version=TLS1 cipher=AES128-SHA bits=128/128); Fri, 06 Sep 2019 12:46:46 -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 v6 12/19] NFSD add ca_source_server<> to COPY Date: Fri, 6 Sep 2019 15:46:24 -0400 Message-Id: <20190906194631.3216-13-olga.kornievskaia@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20190906194631.3216-1-olga.kornievskaia@gmail.com> References: <20190906194631.3216-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 | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- fs/nfsd/xdr4.h | 12 ++++++----- 2 files changed, 69 insertions(+), 7 deletions(-) diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 4428118..4059a09 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" @@ -1732,11 +1733,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; - unsigned int tmp; + struct nl4_server *ns_dummy; + int i, count; status = nfsd4_decode_stateid(argp, ©->cp_src_stateid); if (status) @@ -1751,8 +1788,31 @@ 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 d64c870..dedc316 100644 --- a/fs/nfsd/xdr4.h +++ b/fs/nfsd/xdr4.h @@ -519,11 +519,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 Fri Sep 6 19:46:25 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Olga Kornievskaia X-Patchwork-Id: 11135937 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 D08411398 for ; Fri, 6 Sep 2019 19:46:49 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id A8C6720838 for ; Fri, 6 Sep 2019 19:46:49 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="IIaHXPuk" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2393126AbfIFTqt (ORCPT ); Fri, 6 Sep 2019 15:46:49 -0400 Received: from mail-io1-f68.google.com ([209.85.166.68]:43534 "EHLO mail-io1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2392364AbfIFTqs (ORCPT ); Fri, 6 Sep 2019 15:46:48 -0400 Received: by mail-io1-f68.google.com with SMTP id u185so15333316iod.10 for ; Fri, 06 Sep 2019 12:46:48 -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=zC59tALfmdN9jaU/KWaxLujie6gIK8PIpn0ojbDfP7w=; b=IIaHXPuk3w5sO1kNiIwp1tdst4TEpHLjVVrqcnX1mdYflUHfmaXYmf1F1LwbZubIpU DA6TgPZQ2SQ0haX1VQsuRk5rsRlYPd9OTMv2+UZmHBZ9Dl6/4fwGDN7nSM5UjHPlRDrB X3wsS56LtlYtzqLYcP+0n1qgISiJYsuLKcQAcG50I96QM1h5KhTBF6eKtfitCOmHAdWl KBuXPZ51O2geZewlJtV3vtz7WhYCaixh0RHErh+zrD8Mw71UruoVStPbE9giFnQ0ny54 9MvxfHS+/5QJB6/rPpy6nunHjwbZD1N8E0Nhe6WiNsfsjtfviI9v8HfJWU4X0RU7OOrM hxeQ== 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=zC59tALfmdN9jaU/KWaxLujie6gIK8PIpn0ojbDfP7w=; b=gUy+ruTc1uagH0njbqunBLxmHZZmPQjShdsUDwgeJmBeanGA9ePb4Y6FgwQlYZP+pT cqyDHfi1eYMdv/7IdlKZ1xO9unmxd9nc0/PRODG6+X4wnyocuRjJ6+8mYE9NgRfzpOtq 21V0Oat51SzAVC5jzPUIGeD0aso2JPdR8hJUiM+SU3+qcklF3OzurUhgSNgmzpq7WTpR 4QNgIXQolNj5Ybeq9H/HpTo78b2eAv3XOt6dbKhg/6FNJMTVG4wZzcatbUH0IYT3967u RBJa1JkTHwXndEcRvMmzcojBP8O3alWLv1sTMviKETvL/lq+t+sv7cz5NG7j4NaCSgtq jMlg== X-Gm-Message-State: APjAAAV0A3YPTBjPTjz7OkP5PtprvItbtGO7wpjLG4YNvYahY9X8dCgy N4S9w5RCgpO4Q11n+UwjuRs= X-Google-Smtp-Source: APXvYqxgkDT5SUr0YUf/0Ab/TGKlFo4OqG0h5RMk8xRK23YqRps4sKJcrhD0+EoCVtdXXksKUDZuGA== X-Received: by 2002:a6b:9203:: with SMTP id u3mr12394078iod.3.1567799207774; Fri, 06 Sep 2019 12:46:47 -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 i14sm5118085ioi.47.2019.09.06.12.46.46 (version=TLS1 cipher=AES128-SHA bits=128/128); Fri, 06 Sep 2019 12:46:47 -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 v6 13/19] NFSD return nfs4_stid in nfs4_preprocess_stateid_op Date: Fri, 6 Sep 2019 15:46:25 -0400 Message-Id: <20190906194631.3216-14-olga.kornievskaia@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20190906194631.3216-1-olga.kornievskaia@gmail.com> References: <20190906194631.3216-1-olga.kornievskaia@gmail.com> Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org Needed for copy to add nfs4_cp_state to the nfs4_stid. Signed-off-by: Andy Adamson Signed-off-by: Olga Kornievskaia --- fs/nfsd/nfs4proc.c | 24 ++++++++++++++---------- fs/nfsd/nfs4state.c | 11 ++++++++--- fs/nfsd/state.h | 3 ++- 3 files changed, 24 insertions(+), 14 deletions(-) diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 8beda99..38f15f6 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -782,7 +782,8 @@ 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_filp, &read->rd_tmp_file); + &read->rd_filp, &read->rd_tmp_file, + NULL); if (status) { dprintk("NFSD: nfsd4_read: couldn't process stateid!\n"); goto out; @@ -954,7 +955,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, NULL); + WR_STATE, NULL, NULL, NULL); if (status) { dprintk("NFSD: nfsd4_setattr: couldn't process stateid!\n"); return status; @@ -1005,7 +1006,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, &filp, NULL); + stateid, WR_STATE, &filp, NULL, NULL); if (status) { dprintk("NFSD: nfsd4_write: couldn't process stateid!\n"); return status; @@ -1032,7 +1033,8 @@ static __be32 nfsd4_do_lookupp(struct svc_rqst *rqstp, struct svc_fh *fh) static __be32 nfsd4_verify_copy(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, stateid_t *src_stateid, struct file **src, - stateid_t *dst_stateid, struct file **dst) + stateid_t *dst_stateid, struct file **dst, + struct nfs4_stid **stid) { __be32 status; @@ -1040,14 +1042,16 @@ 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, NULL); + src_stateid, RD_STATE, src, NULL, + 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, NULL); + dst_stateid, WR_STATE, dst, NULL, + stid); if (status) { dprintk("NFSD: %s: couldn't process dst stateid!\n", __func__); goto out_put_src; @@ -1078,7 +1082,7 @@ static __be32 nfsd4_do_lookupp(struct svc_rqst *rqstp, struct svc_fh *fh) __be32 status; status = nfsd4_verify_copy(rqstp, cstate, &clone->cl_src_stateid, &src, - &clone->cl_dst_stateid, &dst); + &clone->cl_dst_stateid, &dst, NULL); if (status) goto out; @@ -1265,7 +1269,7 @@ static int nfsd4_do_async_copy(void *data) status = nfsd4_verify_copy(rqstp, cstate, ©->cp_src_stateid, ©->file_src, ©->cp_dst_stateid, - ©->file_dst); + ©->file_dst, NULL); if (status) goto out; @@ -1351,7 +1355,7 @@ struct nfsd4_copy * status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->current_fh, &fallocate->falloc_stateid, - WR_STATE, &file, NULL); + WR_STATE, &file, NULL, NULL); if (status != nfs_ok) { dprintk("NFSD: nfsd4_fallocate: couldn't process stateid!\n"); return status; @@ -1410,7 +1414,7 @@ struct nfsd4_copy * status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->current_fh, &seek->seek_stateid, - RD_STATE, &file, NULL); + RD_STATE, &file, NULL, 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 7857942..78926c6 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -5583,7 +5583,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 file **filpp, bool *tmp_file) + stateid_t *stateid, int flags, struct file **filpp, + bool *tmp_file, struct nfs4_stid **cstid) { struct inode *ino = d_inode(fhp->fh_dentry); struct net *net = SVC_NET(rqstp); @@ -5634,8 +5635,12 @@ static __be32 nfsd4_validate_stateid(struct nfs4_client *cl, stateid_t *stateid) if (!status && filpp) status = nfs4_check_file(rqstp, fhp, s, filpp, tmp_file, 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 5dbd169..25c7a45 100644 --- a/fs/nfsd/state.h +++ b/fs/nfsd/state.h @@ -616,7 +616,8 @@ 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 file **filp, bool *tmp_file); + stateid_t *stateid, int flags, struct file **filp, + bool *tmp_file, 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); From patchwork Fri Sep 6 19:46:26 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Olga Kornievskaia X-Patchwork-Id: 11135939 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 13F9214ED for ; Fri, 6 Sep 2019 19:46:51 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id DDF1D2070C for ; Fri, 6 Sep 2019 19:46:50 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="RYfv86vA" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2393172AbfIFTqu (ORCPT ); Fri, 6 Sep 2019 15:46:50 -0400 Received: from mail-io1-f65.google.com ([209.85.166.65]:42974 "EHLO mail-io1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2392364AbfIFTqu (ORCPT ); Fri, 6 Sep 2019 15:46:50 -0400 Received: by mail-io1-f65.google.com with SMTP id n197so15380321iod.9 for ; Fri, 06 Sep 2019 12:46:49 -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/AuVBYq4w5K9xS+7EFoEvr1FMTN2qGliNQcl3JnTRQ=; b=RYfv86vAv80mi/fQv2+kbz9+PF+mvqQYQZtEiM836X/s+JIY4rXtGlvlimvsrIUjhQ nAOXMkv62PdWil7V4zf+DF99d4FaBC7xaa4B7OX5vAi/l3SwmlNeTdtYhWmYH8lbSwO2 iWYfuZB1d6u3RlNEahaKi6YkkycYAeeRXF0XW6KUgxFa9erEEflr3pCU9w03tDqdd1KS 5bb24Foccf3jRz0j4WYXePrc7i/pALOCcnagnrXgT328tbGGIhkeR8nhJ17naouFHutk C0qHEyZUT/LLWAyww1neRUmNziTavypnmufBo73tVlfey30mWaaMpfeDxis6c2hZ91/m XmEw== 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/AuVBYq4w5K9xS+7EFoEvr1FMTN2qGliNQcl3JnTRQ=; b=LSwUVewgvkYTHYS8mCesQnSXcTWmrDjvAf8UhkOSDlIqedeXfhnqetkhnKWPfLKj54 M0FIo6PEsxl/wUsKhnNTnRR3A98qei3cQPPaab78Oi8csb5U2yUWDIq2jOHbXXRps3r8 yQ/K21bzmvLfy9ehR/15ZxW9E8DMuxOXDep5rFX2ShAKM13oW2cnMhIN20Xhafi8RBNd Pbfw2KcvvFTYisfzf93ttid7iqIYn9LRZoh5fjQJb5Y0inyvV4vqt6zp47pPqaMqbpSb o/+SK8Hpxhu2YIkv++4fxTLvjO1OHcbb/ydHkwribIe/dHfkml1xo/e5m6I3iFTSFzUN TKSw== X-Gm-Message-State: APjAAAUsa+380Dn8bXQcMYiQakirHSQOeSE3/DV0dYod2kgpAvzIrfQn 5pPsWWzkT4fCYjPyDtY82N0= X-Google-Smtp-Source: APXvYqy+GksA7Dg2ck8ujilT7FuiJYgK1uFkvSylrDFdDqdZ2hHvaMaWRhv2ndfWwW8wn4pAC7lfQw== X-Received: by 2002:a02:7f8a:: with SMTP id r132mr11893101jac.46.1567799208980; Fri, 06 Sep 2019 12:46:48 -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 i14sm5118085ioi.47.2019.09.06.12.46.47 (version=TLS1 cipher=AES128-SHA bits=128/128); Fri, 06 Sep 2019 12:46:48 -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 v6 14/19] NFSD COPY_NOTIFY xdr Date: Fri, 6 Sep 2019 15:46:26 -0400 Message-Id: <20190906194631.3216-15-olga.kornievskaia@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20190906194631.3216-1-olga.kornievskaia@gmail.com> References: <20190906194631.3216-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 38f15f6..3a2805d 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -1347,6 +1347,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) { @@ -2299,6 +2306,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) { @@ -2723,6 +2745,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 4059a09..81cf049 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -1824,6 +1824,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; @@ -1924,7 +1936,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, @@ -4313,6 +4325,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) { @@ -4346,6 +4398,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) { @@ -4442,7 +4528,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 dedc316..c497032 100644 --- a/fs/nfsd/xdr4.h +++ b/fs/nfsd/xdr4.h @@ -571,6 +571,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; @@ -630,6 +642,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 Fri Sep 6 19:46:27 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Olga Kornievskaia X-Patchwork-Id: 11135941 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 9AB2414ED for ; Fri, 6 Sep 2019 19:46:52 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 68B2320838 for ; Fri, 6 Sep 2019 19:46:52 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="jObOz3Gf" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2393078AbfIFTqv (ORCPT ); Fri, 6 Sep 2019 15:46:51 -0400 Received: from mail-io1-f67.google.com ([209.85.166.67]:45944 "EHLO mail-io1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2392364AbfIFTqv (ORCPT ); Fri, 6 Sep 2019 15:46:51 -0400 Received: by mail-io1-f67.google.com with SMTP id f12so15341851iog.12 for ; Fri, 06 Sep 2019 12:46:50 -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=9VIDxMI6U3xv9/xxZMII64SqEquU7pBjEsftQ5mpIsY=; b=jObOz3GfJSfV55Ye4tdq0Tvy8tfiy8dY7NKp7aAYmNpAVm59h1qd0cxx4HYWhhQ3on OZafznJ4DHbj43ZzYsSrlsX3JosfSRifLrfoPLwnb6xnp9WRLMpznVMMtn+kvuSfb0KD SzaGYP7F7ZBXN2TmUZAvdtFhVyljR/15yIFMna+N7Thj9tvasw6fIlxSSQElBugbkbR6 uJdNLNMKA+K9zzq4D17/ogCxGwFE69B7VGbGr+0q6qGYGOYYjItfbk7t9v8AEEo/1Yz1 LlfanKpIKg78XlNyzSKT+b95poQQop1NVTeefSL3nXzWhWlrnaQGdlxIAs/ZrNULLyxV 8aUA== 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=9VIDxMI6U3xv9/xxZMII64SqEquU7pBjEsftQ5mpIsY=; b=KYuAkQPTiIlPAQeIyc0073gbrpWjkgayx1imzQOoIqqIpmCQ8a0SmgLDYlGO95R/Gh gCzTi0MWYqsUk1poqFexoUrq+wu0JTQ7dHsdcdAhsZaEZtWnRmn2CNq3FEl/iGRQfRju vJQBKilluEkK4rItqLG9i38rhNlCc5XvXUpx5EA0rqQI23A0gi+kwmwdG7/BZxLRhpfO hiCHT6E8ljvc5p6BvIlzB+YAUcZOB63xeHnsKErPU4JElPp6pNyD0XeXcb2VGcaNPGi2 F7oA3hvjfwkvRsAClGmy1yT3Y1CWvfhO9SiiUgYBqbipAPSL88hoIxrHDKdAsF4RBTuI qwZw== X-Gm-Message-State: APjAAAVujA4K+1opWaUtSDtZDMJBhXkSUMGfVYggPYTw3u/8GJKjsmJ/ Bly6hnoOWRfo1Qvo0JTMHjo= X-Google-Smtp-Source: APXvYqxoaKLyvJ25U//TSP2n/8qagzlUWjeZy+13/VUOzCD8cfbicStsWjMRZSUn4eOhphJqsr6gVg== X-Received: by 2002:a6b:ee17:: with SMTP id i23mr11889354ioh.168.1567799210252; Fri, 06 Sep 2019 12:46:50 -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 i14sm5118085ioi.47.2019.09.06.12.46.49 (version=TLS1 cipher=AES128-SHA bits=128/128); Fri, 06 Sep 2019 12:46:49 -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 v6 15/19] NFSD add COPY_NOTIFY operation Date: Fri, 6 Sep 2019 15:46:27 -0400 Message-Id: <20190906194631.3216-16-olga.kornievskaia@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20190906194631.3216-1-olga.kornievskaia@gmail.com> References: <20190906194631.3216-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 | 44 ++++++++++++++++++-- fs/nfsd/nfs4state.c | 118 ++++++++++++++++++++++++++++++++++++++++++++++++---- fs/nfsd/state.h | 28 ++++++++++++- fs/nfsd/xdr4.h | 2 +- 4 files changed, 178 insertions(+), 14 deletions(-) diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 3a2805d..e220c43 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" @@ -1229,7 +1230,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); fput(copy->file_dst); fput(copy->file_src); spin_lock(©->cp_clp->async_lock); @@ -1283,7 +1284,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; } @@ -1350,7 +1351,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, + 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 diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 78926c6..a6405c7 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -79,6 +79,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: */ @@ -720,6 +721,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. @@ -739,30 +741,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); } @@ -913,6 +961,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) @@ -2901,6 +2950,26 @@ static bool client_has_openowners(struct nfs4_client *clp) return false; } +static bool client_has_copy_notifies(struct nfs4_client *clp) +{ + struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id); + copy_stateid_t *cps_t; + struct nfs4_cpntf_state *cps; + int i; + + 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 && + same_clid(&cps->cp_p_clid, &clp->cl_clientid)) { + spin_unlock(&nn->s2s_cp_lock); + return true; + } + } + spin_unlock(&nn->s2s_cp_lock); + return false; +} + static bool client_has_state(struct nfs4_client *clp) { return client_has_openowners(clp) @@ -2909,7 +2978,8 @@ static bool client_has_state(struct nfs4_client *clp) #endif || !list_empty(&clp->cl_delegations) || !list_empty(&clp->cl_sessions) - || !list_empty(&clp->async_copies); + || !list_empty(&clp->async_copies) + || client_has_copy_notifies(clp); } static __be32 copy_impl_id(struct nfs4_client *clp, @@ -5187,6 +5257,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"); @@ -5197,6 +5270,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); @@ -5576,6 +5660,24 @@ static __be32 nfsd4_validate_stateid(struct nfs4_client *cl, stateid_t *stateid) return 0; } +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 diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h index 25c7a45..127c929 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 @@ -623,8 +643,10 @@ __be32 nfsd4_lookup_stateid(struct nfsd4_compound_state *cstate, 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 +676,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 c497032..c6c8b43 100644 --- a/fs/nfsd/xdr4.h +++ b/fs/nfsd/xdr4.h @@ -543,7 +543,7 @@ struct nfsd4_copy { struct file *file_src; struct file *file_dst; - stateid_t cp_stateid; + copy_stateid_t cp_stateid; struct list_head copies; struct task_struct *copy_task; From patchwork Fri Sep 6 19:46:28 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Olga Kornievskaia X-Patchwork-Id: 11135943 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 82E521398 for ; Fri, 6 Sep 2019 19:46:54 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 63D2D20838 for ; Fri, 6 Sep 2019 19:46:54 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="InG6o2HF" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2393173AbfIFTqx (ORCPT ); Fri, 6 Sep 2019 15:46:53 -0400 Received: from mail-io1-f67.google.com ([209.85.166.67]:46841 "EHLO mail-io1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2392364AbfIFTqx (ORCPT ); Fri, 6 Sep 2019 15:46:53 -0400 Received: by mail-io1-f67.google.com with SMTP id x4so15341525iog.13 for ; Fri, 06 Sep 2019 12:46:52 -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=lVGTrlWs/L4QetDhL2+g8xf8K9u7vUZMRANa1taGawM=; b=InG6o2HFORk8g0ANQpFRUkCJrs7oi5L0rJS/SvvR7mCR/y1JXKmC73OJfqbVbco/pr UolV65jZB0F8eiZgpOkOCWX9ADuKN40RogipunX08sFGeyEvZdV8i3rkgnLMCe6jlvyn uKIysnZBkYcerVRsH4aZ1iQJdOuawzSBl6DXP8Xrvn1E/xUtybfgVQ73Qt3qJUFX5/w5 cJFb6h7C1twuaoWINnAoLKYNyJyJpWNZocbnl6Nc2H5/wXswdJjQJ9ou1AOx7Ewzm5XM Bm9SWR8+2RUmv9guOATAEOdUax0R/4BbxzT2GJnyko07DS9qVOezR4EJHHDvh7uutw4X OElA== 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=lVGTrlWs/L4QetDhL2+g8xf8K9u7vUZMRANa1taGawM=; b=N1d08DvslpkXrPQGwJoYXMplveuRA7xPYrUMqb7VHIWk5lZLevkj0DuhrbUQeU1HuF nopH3Hmdui2NmxLdyWJbbni9mbB9PzevbyIaCjZs6gX/6jYwnyY3M7BXgzVxD/NtBUXp EFAwZgQRX52YcsF0u9pFJ42nlKfL1bUmCgvAGsLfmOkrCcMYEde5tS68YZM3DwMpgsmr 4mcEniHKIQ+mSqI7q+jOjtuvxMCFo55tkgs6gUanrWzvfTPM6KlmP9m67txWXJCEizWY tqDJTKU6Q6FfG5tPDjDZgDKAqn1lLD67sN42f+aMiFL5+GE1k0uKHgpfQgc5Maw8HoHw +pJw== X-Gm-Message-State: APjAAAW48uDKyr0iGKLHuKA4lHFFpshAvPd6r+j/mejwOPZ2+8/bmT4q k5d0E+SjdLEghCUwAFLXyEg= X-Google-Smtp-Source: APXvYqyltziu4w8XJe9fCvIg4en0094vh/pStrS4ym5+VinxUj8SXQz3MQPBM90aWvp5i95tMmtUbg== X-Received: by 2002:a02:6616:: with SMTP id k22mr11618576jac.129.1567799211589; Fri, 06 Sep 2019 12:46:51 -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 i14sm5118085ioi.47.2019.09.06.12.46.50 (version=TLS1 cipher=AES128-SHA bits=128/128); Fri, 06 Sep 2019 12:46:51 -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 v6 16/19] NFSD check stateids against copy stateids Date: Fri, 6 Sep 2019 15:46:28 -0400 Message-Id: <20190906194631.3216-17-olga.kornievskaia@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20190906194631.3216-1-olga.kornievskaia@gmail.com> References: <20190906194631.3216-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 a6405c7..1bce9d6 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -4532,7 +4532,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; @@ -4553,7 +4554,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; @@ -4586,7 +4587,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; @@ -5175,7 +5176,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; @@ -5577,7 +5578,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; @@ -5671,6 +5673,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) { @@ -5710,6 +5765,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, @@ -6742,7 +6799,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; } @@ -6926,7 +6984,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 Fri Sep 6 19:46:29 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Olga Kornievskaia X-Patchwork-Id: 11135945 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 AC1AD1731 for ; Fri, 6 Sep 2019 19:46:54 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 8D6AE214E0 for ; Fri, 6 Sep 2019 19:46:54 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="qIexWDcv" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2392364AbfIFTqy (ORCPT ); Fri, 6 Sep 2019 15:46:54 -0400 Received: from mail-io1-f43.google.com ([209.85.166.43]:40287 "EHLO mail-io1-f43.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2393209AbfIFTqx (ORCPT ); Fri, 6 Sep 2019 15:46:53 -0400 Received: by mail-io1-f43.google.com with SMTP id h144so15382560iof.7 for ; Fri, 06 Sep 2019 12:46:53 -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=XqllJiCq3cCmwUoY54G0UqLI2GuOcXJI7qJi9mxJt1Y=; b=qIexWDcvP6tiNjznk5C8mJnGRl3SjmWAJ0UopQYXsgru172JaULB+B146cYx+k8O+H vIRuSTmk98E+SxR9yz1cXC5EvMS2qFW7gdzgTLRJ3+jUWOkO1he9UJ6AdtlrJxbBU2/e 471JNan6OajvcgfNATLQCg09bFyAVEbO6CikQtUnEfTgcU/iEhUA4FfSwH85B/SzJZ3X W8QrRWpHXkBwDcdHAWzZhS9NYKaNDGjoQ8sRf/Cd5ZoFxhKVppLMHPG8gZeoqYwi90Ph ovNNaJtyw5vHFrBqxV8ux4m4OeW7mSedMN28ES6ztNkdmLk5fPdFIZaobQnWDqfhmGQS N5aQ== 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=XqllJiCq3cCmwUoY54G0UqLI2GuOcXJI7qJi9mxJt1Y=; b=SHT/B8o9M07Xln997jSEcWhE3olsqlweOF8XVkH/skIAUDOH1LOR+/De/A4eeY9q6r fySK5m6qhLNTBEu3etMFuPPu4klCowtDW32Ls5vZRk/d9QWfW2t0WoOINTGrqqWUcclq RirZ6c1sVGiOfS+HX9bo5QnyIWS5puSx4kL2fX/YxeOhIPOqjHeeGMyE4jW6MDA4HjMk WjFOgp5zpwaPhU4pASl7L7brf2nqfWBlnSwPrKmzQpA81oOmheGrofRrPgV5liU5NLLL 4fIfGN+IJNbogBMdTAJAc6DMW0MuYYogHJCPGonTDmIDeHB9ncNKSUUClx6sgDmE9KVA J5lQ== X-Gm-Message-State: APjAAAX0s2rBrrTqC7OQi5Qf2HmkqqDyGoUwjVlXghk8bJgd9B1tgRG8 I77gumuKhel5aL8IJCkY/Xk= X-Google-Smtp-Source: APXvYqyD1Yp6CA8JgruJizixFJtnTYt1HqtLEekxC/OM5aeme+cpHGhnQeXED/F/Ef0ZC+usIabdeQ== X-Received: by 2002:a05:6602:259a:: with SMTP id p26mr11842118ioo.65.1567799212653; Fri, 06 Sep 2019 12:46:52 -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 i14sm5118085ioi.47.2019.09.06.12.46.51 (version=TLS1 cipher=AES128-SHA bits=128/128); Fri, 06 Sep 2019 12:46:52 -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 v6 17/19] NFSD generalize nfsd4_compound_state flag names Date: Fri, 6 Sep 2019 15:46:29 -0400 Message-Id: <20190906194631.3216-18-olga.kornievskaia@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20190906194631.3216-1-olga.kornievskaia@gmail.com> References: <20190906194631.3216-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 e220c43..c38a0ef 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 1bce9d6..b3c1068 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 c6c8b43..687f81d 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 Fri Sep 6 19:46:30 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Olga Kornievskaia X-Patchwork-Id: 11135947 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 C72361398 for ; Fri, 6 Sep 2019 19:46:55 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id A77F82070C for ; Fri, 6 Sep 2019 19:46:55 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="aAGj2E8M" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2393289AbfIFTqz (ORCPT ); Fri, 6 Sep 2019 15:46:55 -0400 Received: from mail-io1-f65.google.com ([209.85.166.65]:41510 "EHLO mail-io1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2393209AbfIFTqy (ORCPT ); Fri, 6 Sep 2019 15:46:54 -0400 Received: by mail-io1-f65.google.com with SMTP id r26so15346762ioh.8 for ; Fri, 06 Sep 2019 12:46:54 -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=Wrf1mM3hYk6bIx7wQdOBtYrAyIjcBJxmNQmBMLNLE9I=; b=aAGj2E8Mkta1/i1AxZrIOcE5AFA4rGonXElEhFfvtWLc3KbGHjMxBNjCx9djyePGmZ CeHX38V5BKcbK/71bnZJMRw/QLrLT2nt15Gj8nUlvjGETZGVWd6uHLDQvRtDjWAQDiwK wLbR4H/zqSpTHIlP7Cr4N2h0Vp6TEIW4euxvk1Vg7A1XHGs53kShgHDgOZlZLJN58naL BOnvku7rUxUUGrXj56neDQBBGh3hf2AMKS60bDEb/zKsfpSVbF+xU5ZzGb9cz5+ym9ys bxIiccPlCnU1vMHovmiE6YTCdmBgm9R/XyOIG+btmXiqXzn4yiTRARRlEKQFmpP4JzVv mseQ== 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=Wrf1mM3hYk6bIx7wQdOBtYrAyIjcBJxmNQmBMLNLE9I=; b=AJmOABCGSnIkrwlt6qCy5ru3DUM3tfWC1gf3IMutY7s5qUnMtY8avbq+cIEC3mTcBK IQrG69z81Bdvj4xjt4twCosLCCy6AoOAKKHPBINH1zUQZLmOcJGg+pfDpJRYDR3kvKwe NbLPwa4WhXbSSYrS0A/Xntu8uYqlU8bM+tYk1h5vLoDFR7P7xLGr8cXMzBLO7RiMBiki 4Ng95fWn/If0pkthg538oc2cHeIPcDQVpJcgSMiGYtgjw3/j0llDSJQgZtEUDMFxMFVB yExxNiVnJyoivCcv0G4c1MVzbRxx1FxFlki0gPbdoynKGhLLfehkrnd7I80zi7B1pYy3 Lefg== X-Gm-Message-State: APjAAAVDarZVRAyLN+CzOw5Ynq904f8eqi0fDp3/j38G1EPYlybT3gyp RQW9e4R9n70S7sOrw3a+f3U= X-Google-Smtp-Source: APXvYqx+7QKFpy9+QaD+gBHoJi2mryW9ZWU9mrdtv2Ifim4hFwuN1pHgUymfXxuvNMwwcCaEVXyW2Q== X-Received: by 2002:a6b:5b07:: with SMTP id v7mr5120062ioh.76.1567799213623; Fri, 06 Sep 2019 12:46:53 -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 i14sm5118085ioi.47.2019.09.06.12.46.52 (version=TLS1 cipher=AES128-SHA bits=128/128); Fri, 06 Sep 2019 12:46:53 -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 v6 18/19] NFSD: allow inter server COPY to have a STALE source server fh Date: Fri, 6 Sep 2019 15:46:30 -0400 Message-Id: <20190906194631.3216-19-olga.kornievskaia@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20190906194631.3216-1-olga.kornievskaia@gmail.com> References: <20190906194631.3216-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 | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++---- fs/nfsd/nfsfh.h | 5 ++++- fs/nfsd/xdr4.h | 1 + 4 files changed, 70 insertions(+), 5 deletions(-) diff --git a/fs/nfsd/Kconfig b/fs/nfsd/Kconfig index d25f6bb..bef3a58 100644 --- a/fs/nfsd/Kconfig +++ b/fs/nfsd/Kconfig @@ -132,6 +132,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 c38a0ef..69dd53b 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 @@ -1964,6 +1972,45 @@ static void svcxdr_init_encode(struct svc_rqst *rqstp, - rqstp->rq_auth_slack; } +#ifdef CONFIG_NFSD_V4_2_INTER_SSC +static __be32 +check_if_stalefh_allowed(struct nfsd4_compoundargs *args) +{ + struct nfsd4_op *op, *current_op, *saved_op; + 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) + return nfserr_nofilehandle; + putfh = (struct nfsd4_putfh *)&saved_op->u; + if (!copy->cp_intra) + putfh->no_verify = true; + } + } + return nfs_ok; +} +#else +static __be32 +check_if_stalefh_allowed(struct nfsd4_compoundargs *args) +{ + return nfs_ok; +} +#endif + /* * COMPOUND call. */ @@ -2012,6 +2059,9 @@ static void svcxdr_init_encode(struct svc_rqst *rqstp, resp->opcnt = 1; goto encode_op; } + status = check_if_stalefh_allowed(args); + if (status) + goto out; trace_nfsd_compound(rqstp, args->opcnt); while (!status && resp->opcnt < args->opcnt) { @@ -2027,13 +2077,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 687f81d..d76f9be 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 Fri Sep 6 19:46:31 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Olga Kornievskaia X-Patchwork-Id: 11135949 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 7C9D31398 for ; Fri, 6 Sep 2019 19:46:57 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 4997420838 for ; Fri, 6 Sep 2019 19:46:57 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="b8NUmN+0" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2393369AbfIFTq4 (ORCPT ); Fri, 6 Sep 2019 15:46:56 -0400 Received: from mail-io1-f65.google.com ([209.85.166.65]:36446 "EHLO mail-io1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2393209AbfIFTq4 (ORCPT ); Fri, 6 Sep 2019 15:46:56 -0400 Received: by mail-io1-f65.google.com with SMTP id b136so15448672iof.3 for ; Fri, 06 Sep 2019 12:46:55 -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=Hw7EEson4lr9e9xXEDrCChix2/WmB8PJh8Eq35qGpZw=; b=b8NUmN+041XbIC1CN1qdDXhnJLZQ4JQFYfUku+rRlDmw/bl97lqlE+Q4p0t49c8d1J FTQtqDxhjSydGpmc6RC0FBp8znjsiO4wbtWgUWKUbaxlpC1fvVAU9q2q35tBkx6PiIKw EHFCm8BM0iwNWtSFwD8ETwt2f5cDNhk2jaiOP3Me79CXlhVB9nFKVO3NhujdcCL3ZZS/ 3XsW9XfT2s2iVKMQYb9QVXpbdwBNp1Kn9eP33NEtA8VXLqqimZlXjU4hUgYad1B+6K19 elrbyLBLvAND0FZSoalLQ2VNUssu+Lsv+8YBlsY0c9lnllNmeO3qSvfX0vEIlTQIzD1M Rztw== 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=Hw7EEson4lr9e9xXEDrCChix2/WmB8PJh8Eq35qGpZw=; b=dXL2kjFrOE8c5U5XjQdD/C8m0J2c880g5pX78crHteZ2ZLlvMgOunLuXRGS1XgKwNv x5LobB2mtI9CCEXbnWYpyPUlchzVvTYsFRydpO7RtkkLlHjfGAGIG0EFEBWZ9hzdUIq2 irV3yvtjiWDRBAO/DdUgSrDULZ7/tdbLkTvQu18oVrg+FIrY0BgBPCVL8bzQjHr6t6L1 dJNZ642qS/q2LIGRye5p9QqRL6npwe1lZnmqy7rHUUzVEjFTzN9Eq0nfFHt8IFtm34Vp xBZW4zfQVGDZDTIcxdMDhVTXG2ibd4p61+PAcLAJNEjgCppuK9Wy1vCqNhis04/dUpSY RdkQ== X-Gm-Message-State: APjAAAU8lIla3RVZxMjwdlhkSFrgITh1wKeZCtRyRnBaQ5GEL6J+MjyP lEV7zuayjjEfmLC1ydPE0eY= X-Google-Smtp-Source: APXvYqwldYsFM/lQ3kWk+PMI9N+6vTUf+GLUJ4htKAd2x0bQeZZQheLLTQFztdefWXEX7Oe6bZZHuA== X-Received: by 2002:a5d:84c8:: with SMTP id z8mr1143923ior.214.1567799214904; Fri, 06 Sep 2019 12:46:54 -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 i14sm5118085ioi.47.2019.09.06.12.46.53 (version=TLS1 cipher=AES128-SHA bits=128/128); Fri, 06 Sep 2019 12:46:54 -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 v6 19/19] NFSD add nfs4 inter ssc to nfsd4_copy Date: Fri, 6 Sep 2019 15:46:31 -0400 Message-Id: <20190906194631.3216-20-olga.kornievskaia@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20190906194631.3216-1-olga.kornievskaia@gmail.com> References: <20190906194631.3216-1-olga.kornievskaia@gmail.com> Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org 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 | 285 ++++++++++++++++++++++++++++++++++++++++++++++++---- fs/nfsd/nfs4state.c | 15 ++- fs/nfsd/nfssvc.c | 6 ++ fs/nfsd/state.h | 3 + fs/nfsd/xdr4.h | 5 + 5 files changed, 287 insertions(+), 27 deletions(-) diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 69dd53b..630e94d 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -1153,6 +1153,209 @@ 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, ©->file_dst, NULL, + 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 file *src, + struct file *dst) +{ + nfs42_ssc_close(src); + fput(src); + fput(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 file *src, + struct 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, + ©->file_src, ©->cp_dst_stateid, + ©->file_dst, NULL); +} + +static void +nfsd4_cleanup_intra_ssc(struct file *src, struct file *dst) +{ + fput(src); + fput(dst); +} static void nfsd4_cb_offload_release(struct nfsd4_callback *cb) { @@ -1217,12 +1420,16 @@ static __be32 nfsd4_do_copy(struct nfsd4_copy *copy, bool sync) status = nfs_ok; } - fput(copy->file_src); - fput(copy->file_dst); + if (!copy->cp_intra) /* Inter server SSC */ + nfsd4_cleanup_inter_ssc(copy->ss_mnt, copy->file_src, + copy->file_dst); + else + nfsd4_cleanup_intra_ssc(copy->file_src, copy->file_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; @@ -1232,8 +1439,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->file_dst = get_file(src->file_dst); - dst->file_src = get_file(src->file_src); + dst->cp_intra = src->cp_intra; + if (src->cp_intra) /* for inter, file_src doesn't exist yet */ + dst->file_src = get_file(src->file_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) @@ -1252,7 +1468,18 @@ 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->file_src = nfs42_ssc_open(copy->ss_mnt, ©->c_fh, + ©->stateid); + if (IS_ERR(copy->file_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; @@ -1276,11 +1503,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, - ©->file_src, ©->cp_dst_stateid, - ©->file_dst, NULL); - 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, @@ -1291,15 +1527,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)) @@ -1310,12 +1546,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; } @@ -1326,7 +1566,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); @@ -1342,17 +1582,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 b3c1068..6ca391e 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -5678,8 +5678,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; @@ -5693,12 +5694,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; } @@ -5709,7 +5714,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 18d94ea..033bfcb 100644 --- a/fs/nfsd/nfssvc.c +++ b/fs/nfsd/nfssvc.c @@ -30,6 +30,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 127c929..6a9e4fd 100644 --- a/fs/nfsd/state.h +++ b/fs/nfsd/state.h @@ -678,6 +678,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 d76f9be..75b884f 100644 --- a/fs/nfsd/xdr4.h +++ b/fs/nfsd/xdr4.h @@ -550,7 +550,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 */