From patchwork Mon Sep 16 21:13:35 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Olga Kornievskaia X-Patchwork-Id: 11147849 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 D5BB5912 for ; Mon, 16 Sep 2019 21:13:59 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id B554B2067B for ; Mon, 16 Sep 2019 21:13:59 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="ccK1AHn5" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2387878AbfIPVN7 (ORCPT ); Mon, 16 Sep 2019 17:13:59 -0400 Received: from mail-io1-f67.google.com ([209.85.166.67]:34008 "EHLO mail-io1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2389144AbfIPVN7 (ORCPT ); Mon, 16 Sep 2019 17:13:59 -0400 Received: by mail-io1-f67.google.com with SMTP id q1so2563432ion.1 for ; Mon, 16 Sep 2019 14:13:57 -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=ccK1AHn5Y/Bmi0KjKNneF6oVHZf5lsH8U7MDwAPbfOVLiSaLtZN8h1GsO2d+lkxvtZ Yq3VE81/Za8J1K2DwBdCzwkiQ83BY62dtS/RkNZAuREoncX6+Bg60qJmH86CxJaUa1lh zbxZTFHLJEa86X3cZ4W8qdi5xIc1CbLg6o37b+xaPbTXJ/2upmFDaRUjKJSCtjZ5Gaz2 pdTg3bxNyW/D6VyvNPxmKmyry4M3mNfxBWzeOISiszKgOcHWVzcdeYDYhnZxRErcVIMh QU0WL0/MR7eoP4yvjMuI0rVpX5e8F7ZF4jeuKsuvxGCYwm7XM//GV0R2kwnC0Tch9VVg AkVg== 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=gXHk/eBJTmI9imgFcOzM9qHvq2ZiTwf242z81EOet1PdxoWN3IY/H6Ad7pzo6MEiKX 3unBZXO9HusqgMhw7dSmSNm6HTl9VPb54CNa5wEtbMaJuYCsCV8tzTPxxg9tIMTIm+zS PPVRkMIawZ6eIs4rZLnsR+BWHYEcwkOn+XcT+STH95sImqncMJv6J/PqlMxbPWjdXlEc +0SeIL68bP6mPJXjEqdMFWkxUh8vY6iYO20zzMNdUpI4IgqwAACOJHThszdhQTPT+kZK sQr9lbZwSrmyRUfxdG0R9m1hT3Enae+3djG9PATFUHvRCrY/T1wbVghlViB0+3ByDOIr vnuw== X-Gm-Message-State: APjAAAVC5kH/h/WXAOROpGJ64T0cSz3NR1k6Vlo5tJdRxuDjBnLvbbM3 pL731/AMzTpwq5WhgUf2hvONmAhK X-Google-Smtp-Source: APXvYqwXPAtCPJvFyuWsViK3rXfHoWLS4NvRXRXLB2F72XmyIQjOdlXGEP0YuAYCT0MfSfXQZkAJDg== X-Received: by 2002:a02:7810:: with SMTP id p16mr5989jac.55.1568668436615; Mon, 16 Sep 2019 14:13:56 -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 l186sm71853ioa.54.2019.09.16.14.13.55 (version=TLS1 cipher=AES128-SHA bits=128/128); Mon, 16 Sep 2019 14:13:56 -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 v7 01/19] NFS NFSD: defining nl4_servers structure needed by both Date: Mon, 16 Sep 2019 17:13:35 -0400 Message-Id: <20190916211353.18802-2-olga.kornievskaia@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20190916211353.18802-1-olga.kornievskaia@gmail.com> References: <20190916211353.18802-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 Mon Sep 16 21:13:36 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Olga Kornievskaia X-Patchwork-Id: 11147851 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 152961747 for ; Mon, 16 Sep 2019 21:14:00 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id DF3E32171F for ; Mon, 16 Sep 2019 21:13:59 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="a+TVedqO" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2389144AbfIPVN7 (ORCPT ); Mon, 16 Sep 2019 17:13:59 -0400 Received: from mail-io1-f65.google.com ([209.85.166.65]:35883 "EHLO mail-io1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727941AbfIPVN7 (ORCPT ); Mon, 16 Sep 2019 17:13:59 -0400 Received: by mail-io1-f65.google.com with SMTP id b136so2524989iof.3 for ; Mon, 16 Sep 2019 14:13:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=2YnaVC3AD8vJZij0BFQ0JAl69x73rDKuvmn2Wq8r6Gs=; b=a+TVedqOGxwRmgFq5qveX1GiYjat9sDg5ABwD5QQUORksl7SxLSKC+evUk6Ep6V6Ur p5zViPkOm+scli/7TkhA+iYt4EkndPN/dKMOADx2VlZZHoaaNCGMAYOix6ybpLqL8MXc o40NKXP92Hn8h+1PJ4NThyD7SM21SYhd5FjkawaTKtaS8A9WB1ezHBCEB6I57Y4IoKdN h8pDTDL69ptUkj7sCWTponpfxZGPCkA6pBpDCQWj/ZidaiPWM0tI+ImlYdkBWpFNIiVI GkFpmjwUhaHuUgMJcLSS0mBPWPIb0YELnNriuybe11L3JYtAbdmMKpY4JmmsPSY6iYkT jR7Q== 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=2YnaVC3AD8vJZij0BFQ0JAl69x73rDKuvmn2Wq8r6Gs=; b=HSrK74zZH+NvkoCtbO+z3K5m6hsqm37wxz2e5yKjy77EBFZWior5Ew56fFgtPwvOo6 xfDK1B/BaMN/Q6bVkM2Z25WjM+wBA7FeY1VKuNP6Ay2O8gb6DWvqelV9rQe9z/PWq+Ve pO/ZzPJ4f6gqFp/rlNOGzSGBCiQwJSBXiMj6AGXlJRcXbZdNmsJdTYIC+8+r1U/Alnln pxTkobfbgKyGy3BnojDXdGIWF/ByyZJjeEmzar8f7+yzzxTJs3hCjP/WTyb+aDahgr/k M+Y4A4G2NsMkg/UqBLeZqwv/bRrKakxS266FZ5Ez4bq+eqExqSG8RYAxMnIAKtKwmktr mg7Q== X-Gm-Message-State: APjAAAXcQiVotFeqytFGBSw3NAIkKrabDXVHbMDVa5tpo01U0WTAoCSz Y5aqkyw1sYR3KnML4DYCa3c= X-Google-Smtp-Source: APXvYqz8hyYPpMHHbPe5He5v5ciwCYV4MMHCGvD5fK9TfqElRJZjiboI/1BGaow4YJ2+mjhyFDN/lA== X-Received: by 2002:a6b:ec16:: with SMTP id c22mr341229ioh.185.1568668437735; Mon, 16 Sep 2019 14:13:57 -0700 (PDT) Received: from Olgas-MBP-201.attlocal.net (172-10-226-31.lightspeed.livnmi.sbcglobal.net. [172.10.226.31]) by smtp.gmail.com with ESMTPSA id l186sm71853ioa.54.2019.09.16.14.13.56 (version=TLS1 cipher=AES128-SHA bits=128/128); Mon, 16 Sep 2019 14:13:57 -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 v7 02/19] NFS: add COPY_NOTIFY operation Date: Mon, 16 Sep 2019 17:13:36 -0400 Message-Id: <20190916211353.18802-3-olga.kornievskaia@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20190916211353.18802-1-olga.kornievskaia@gmail.com> References: <20190916211353.18802-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 d778dad..bd37fff 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 616393a..6741ad4 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 96db471..8d845ef 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 39896af..1012cbe 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -9799,6 +9799,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 Mon Sep 16 21:13:37 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Olga Kornievskaia X-Patchwork-Id: 11147853 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 3C144912 for ; Mon, 16 Sep 2019 21:14:02 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 11C152067B for ; Mon, 16 Sep 2019 21:14:02 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="IfSBCHCI" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2391497AbfIPVOB (ORCPT ); Mon, 16 Sep 2019 17:14:01 -0400 Received: from mail-io1-f65.google.com ([209.85.166.65]:33267 "EHLO mail-io1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727941AbfIPVOB (ORCPT ); Mon, 16 Sep 2019 17:14:01 -0400 Received: by mail-io1-f65.google.com with SMTP id m11so2570415ioo.0 for ; Mon, 16 Sep 2019 14:13:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=YMyVf3I47kNKbA6GqxE4gvBgqowMm+G+DipklXenmZE=; b=IfSBCHCIQJeZQfTzUoB+13w61WzUzZaS9dqlAMMz7pin3jq08myNg6hDtyVfh+zACW iu2TQRpD6HzpmbMTBOgsr/jbwWRdJLCkXwv16bK+wnBc+1bbv0P8dgzYNB2A+HVnTDDV pnWZaE3twGKl4QVbqjPMDb2btFimB+jXGUPUA3HVjkB54XLoT78ACLGLWRqpDPwqigei jUva2POs70hHavp9WyXD0OJGf8+9Yb2CVbQmNC1xOM8hgM0OKa7ah0FcuFGBYdM7FTST 7mMBwmu+2AQzF+sjgKyRWsWHPuApaim2bBXOV2Ine6Pn4bme2R6iGfF43vRTgxl2rt9t j6uw== 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=YMyVf3I47kNKbA6GqxE4gvBgqowMm+G+DipklXenmZE=; b=ul/+1ekLqIkUDrQJX1vHz9Ufv6KdS32jkiGpSEnfgKuOY7BuPchUw+DmNo/fE3VVKz wKjvMD3f60iNwX49QY4CcXeNVvZieQaZRKPaFCB+EyP6kT/fJKUsT9sNJgvu+DnQ2T66 HchtnP5/E5J2xHWCQMgJQyVtO5hzCO3wFWzUr0doxz24hYemIpNxYqUwGP+3T3X83DcE /bgPb7M3vZ+2FIe3Kh0F5BWbrex58pdR3AG24Pw/2nDlm1nq/7UPNCfr3d/YGXxxnQNE eVQvPC35cG4uwas9toIsgj0oAuNXMt5zWngKA4Q4UL3TAJnCp+mP2y2f8fLNDmmRuz3/ 9cgA== X-Gm-Message-State: APjAAAXH6dFHMjZUcAao/jQUF0GPFykRUJVuZKSmEp8PCEGMlwxR1icP 0dFD8ofpy6zpkpN7wg6k2a4= X-Google-Smtp-Source: APXvYqwCmjjJTUVDK24dw8yTzMZW9vCDcb7oIuEV9FxUAy2x/Cmel6CRDi0RyR286HhpqlQio/6m4g== X-Received: by 2002:a5e:960f:: with SMTP id a15mr358669ioq.13.1568668438742; Mon, 16 Sep 2019 14:13:58 -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 l186sm71853ioa.54.2019.09.16.14.13.57 (version=TLS1 cipher=AES128-SHA bits=128/128); Mon, 16 Sep 2019 14:13:58 -0700 (PDT) From: Olga Kornievskaia To: trond.myklebust@hammerspace.com, anna.schumaker@netapp.com, bfields@redhat.com Cc: linux-nfs@vger.kernel.org Subject: [PATCH v7 03/19] NFS: add ca_source_server<> to COPY Date: Mon, 16 Sep 2019 17:13:37 -0400 Message-Id: <20190916211353.18802-4-olga.kornievskaia@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20190916211353.18802-1-olga.kornievskaia@gmail.com> References: <20190916211353.18802-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 8d845ef..1bec960 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 Mon Sep 16 21:13:38 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Olga Kornievskaia X-Patchwork-Id: 11147855 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 975C617E6 for ; Mon, 16 Sep 2019 21:14:02 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 76515214AF for ; Mon, 16 Sep 2019 21:14:02 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="dxGtWr82" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727941AbfIPVOB (ORCPT ); Mon, 16 Sep 2019 17:14:01 -0400 Received: from mail-io1-f68.google.com ([209.85.166.68]:33271 "EHLO mail-io1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2391483AbfIPVOB (ORCPT ); Mon, 16 Sep 2019 17:14:01 -0400 Received: by mail-io1-f68.google.com with SMTP id m11so2570495ioo.0 for ; Mon, 16 Sep 2019 14:14:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=qbMlSBpf06q9f17aggELxyyLLTxlNI3h6Qh/Z4qZNW4=; b=dxGtWr82ZO9cHrDcGx77NwbtjyHT56xC84BFTBT69bVsOUPl1zCwG+pI+HgGFdejio z2noynA5OzVrSFvcfx/SnQRLpgqM9oK1TYZ9GGzlmDWhi/pqbHeNwEcR/QGzRFZRBfrq lY5bxQI/sN3kr+QZ7V7sltSr9LdS4QfWtjzbFxD+E9jD9F8WRfp+9iGGuh/l3/rxcqK4 vnRHRRKX4jEk82JQBBb5XRm+ALX0GMAy8Aq/2jAHO7I6Pb2EwMGe5yBTkSUj3cSN0g6+ 8d2k32dgiBrbnjw34NyD6dkbToDCGs9Hltb4z3YJSg2Wm1LYqH5pqZJLajgXGDFmggcj AtKA== 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=pntJQ7MxO9BCX3nEYza+UPHeFkZL35pQomgpHgQVtbX4LaYIPr7/UwJenzC4s8TOTr 0kc/dxXxX3Mb5B/9dkIfBeRiN0/7bDpXr4HlEppSxRA9TOLyvrUVn5dd9sJUo7BRPJtH 3ah9ca7jNL6yXTNFvDL4eFmKjOFWaWV/2dd9TDJHUUAoFBO8mxmhBo3vb12OEaHU3rx+ snPjwnHA/af6FQX0xz4EMOgYYmQJ03FsaA9Tyr6Py1dy88BL+pjsI61Ud/3/Z6q6kh3m z7hAsMxIZTOEc9s/BzKCEYh9jGdOY/BbpjDeryPLoKDGrlU7pgmObC0U+/JU6pe9Z1Yn ciyg== X-Gm-Message-State: APjAAAWonIHLD/hiG2ySXe0JFGgfEgT3CK8C9CtKz7DU8iqxnmJ5HRA9 h/eeEPRcn/qzFnaKhE0RrZsItFJY X-Google-Smtp-Source: APXvYqw33LhG0yhYMdQQcpRT/gjZp/+IBi/rB8fCoZATwfX2Ep4Qv8UPivzFzyGiOnePXbICpuhF+A== X-Received: by 2002:a5d:8e0e:: with SMTP id e14mr291760iod.211.1568668439709; Mon, 16 Sep 2019 14:13:59 -0700 (PDT) Received: from Olgas-MBP-201.attlocal.net (172-10-226-31.lightspeed.livnmi.sbcglobal.net. [172.10.226.31]) by smtp.gmail.com with ESMTPSA id l186sm71853ioa.54.2019.09.16.14.13.58 (version=TLS1 cipher=AES128-SHA bits=128/128); Mon, 16 Sep 2019 14:13:59 -0700 (PDT) From: Olga Kornievskaia To: trond.myklebust@hammerspace.com, anna.schumaker@netapp.com, bfields@redhat.com Cc: linux-nfs@vger.kernel.org Subject: [PATCH v7 04/19] NFS: also send OFFLOAD_CANCEL to source server Date: Mon, 16 Sep 2019 17:13:38 -0400 Message-Id: <20190916211353.18802-5-olga.kornievskaia@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20190916211353.18802-1-olga.kornievskaia@gmail.com> References: <20190916211353.18802-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 Mon Sep 16 21:13:39 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Olga Kornievskaia X-Patchwork-Id: 11147857 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 D574D184E for ; Mon, 16 Sep 2019 21:14:02 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id B463F2067B for ; Mon, 16 Sep 2019 21:14:02 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="SJIlmB+D" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2391483AbfIPVOC (ORCPT ); Mon, 16 Sep 2019 17:14:02 -0400 Received: from mail-io1-f68.google.com ([209.85.166.68]:46356 "EHLO mail-io1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2391481AbfIPVOB (ORCPT ); Mon, 16 Sep 2019 17:14:01 -0400 Received: by mail-io1-f68.google.com with SMTP id d17so2346889ios.13 for ; Mon, 16 Sep 2019 14:14:01 -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=HsoXM+mEYIMjXOh8kTXzl2qJg6dzdkI/oW/I1UQipp4=; b=SJIlmB+DYrxkY7q+oq7jcEruRdTvuifvDydFPuo3KOnGrFEHdqCMVPGsqUtyhP8vQi vWeoNASbtsOKm+0bl1TI32HqZdV0lMGQWvOoVXZbtP9A0NB3lc305Kjda7k62AzyofDZ 5Q6VAQflFzfWtjBWmxZzRxHH9TowY29rh0FP+vwSNs+WdAaVJKIkLM77on1UMGMZyA9Q srMc/kD7DtI75FtvhWe7ldACCYJXJfWPlDBXshos2BzuFkXtDyPagbTctHC5/Pu9r3fJ Gu8jJbpTdkXRinvce0jBsXl5xfafq1b7hTnqASxHpPbLdsEhse2CdcDj/11Zinptl6bv 09Uw== 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=HsoXM+mEYIMjXOh8kTXzl2qJg6dzdkI/oW/I1UQipp4=; b=J+I9eGB1OC742Gg3wZpq7M4WgT5TrCbruRCO4DNjMroaRNQEbNo3hfbgoLY/eTGYA6 cVjq7PjC24mCOjTiQ6dB8G/e2UpzI6dTQGlJaEcDYzpvDw0Blv95ldoEQdMekRBWTz0s hsLU53AXjsJJdlMlG01yKu3Gu54fsngHJm3H30TnjkUlLszAP5f/crszT/hx35cfjJnd vd/sGeg5yg5bpI8tQx2jGUR8xcOBTtijaCnI0ASidiG6RCd36lsbIyvSicyX41mBW9Wr 4aVPTFgbmqxpdUTNSwXdnrcsO6Jzrqd5wf3zGBcc4U/f0yNqgyiPwCzCIpchjaiL7/WJ 6joQ== X-Gm-Message-State: APjAAAWZfhN7jnp8y1w/6X34TagJiyDBZJUAU7bxu7h1iy9p+O7l/0M/ x27qpDc+Ls7yHdrWogbwXZt6yMMN X-Google-Smtp-Source: APXvYqxS2hlmn4NDavV4k/MJN5SwufMrJJts00ffNfEkAZgj1qwoJg4DuBIrurhmfOPmnptQc89wOA== X-Received: by 2002:a6b:bd42:: with SMTP id n63mr372428iof.53.1568668440753; Mon, 16 Sep 2019 14:14:00 -0700 (PDT) Received: from Olgas-MBP-201.attlocal.net (172-10-226-31.lightspeed.livnmi.sbcglobal.net. [172.10.226.31]) by smtp.gmail.com with ESMTPSA id l186sm71853ioa.54.2019.09.16.14.13.59 (version=TLS1 cipher=AES128-SHA bits=128/128); Mon, 16 Sep 2019 14:14:00 -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 v7 05/19] NFS: inter ssc open Date: Mon, 16 Sep 2019 17:13:39 -0400 Message-Id: <20190916211353.18802-6-olga.kornievskaia@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20190916211353.18802-1-olga.kornievskaia@gmail.com> References: <20190916211353.18802-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 bd37fff..8b9f039 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 1bec960..d9ca8af 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 1012cbe..b783699 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, @@ -1705,7 +1704,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) @@ -3997,7 +3996,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 Mon Sep 16 21:13:40 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Olga Kornievskaia X-Patchwork-Id: 11147859 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 9692A912 for ; Mon, 16 Sep 2019 21:14:03 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 76613214AF for ; Mon, 16 Sep 2019 21:14:03 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="CTDSCxYQ" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2391496AbfIPVOC (ORCPT ); Mon, 16 Sep 2019 17:14:02 -0400 Received: from mail-io1-f53.google.com ([209.85.166.53]:41892 "EHLO mail-io1-f53.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2391481AbfIPVOC (ORCPT ); Mon, 16 Sep 2019 17:14:02 -0400 Received: by mail-io1-f53.google.com with SMTP id r26so2427494ioh.8 for ; Mon, 16 Sep 2019 14:14:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=TywW2nZeTmjCJvvuYq8EMw8fV30prBCgTawZutPeTms=; b=CTDSCxYQLtkf8041+TdY3XzY1GuxN69dyymnJyXzi+iltH99I0KG0oVECPb81AyLqT boMz5aqGqTwZh+7S4BbzKbGtQGHB67SzsHn+mGqNowhrI2yyueoWBbJoQQdTOtyV5d9U RvRWqyBGQo4v4WHt6psxcLzIKBgo+udpSN+4GFfBqSujIXek4eNQ1aPMmUYNbaZ88AEw VxvH9XIm3qowAvt3lYo4txCWgBx3WusAHUKItt6RasZOVkk9LKEECA7vaZlgqC+a6H0p bm68GawtKQ0cLJyhS66F9YQXMDe8AIJYFcHMvN/uDdjtJaVGwWgRBedAxsPjX849/0WT UArw== 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=TywW2nZeTmjCJvvuYq8EMw8fV30prBCgTawZutPeTms=; b=SkqGRWgmaj+e+/OaKdS4paJflXWXaYkhjuTJhBNnvfhJqnEDL03Rlx/sAgQ6fkZf+Z Vnn1cgldeCgqIfXjNiUlx/Cyq8bRfqhJyxMkOsj4r38mkNKBZETte3S0arrNHRtYd+YP A4va11Q3xeF2uR4N2Cx30vRI9JQD1D+A5rcS1X81FsZF3dJ3K9iMU3NjqAaWyrikvm6V KfW/MQHmFeXRj3Wfo8pawtiJuNgW5swOCW8bQPR0nWJiWjpjfC7wh/OdqfKl56fQZ7Nf 5VtgF7IygUcUZDtk8eM90nIhO4j/ijAnfvET1+u/D36s+5TN8zSZM+xJc9bFusK/tXM9 m3xw== X-Gm-Message-State: APjAAAUmS+OHdB17glpLtH8m/KAQyqgyBsZ/x5ZJKyBey6t8gdypTopT 5BGCwWeKzXxYi3y3H5hf1dnNOg5D X-Google-Smtp-Source: APXvYqwqTVS5O/BirzQZH3vZK8D3yJm4P3ZW7MpI5RKGVZh7ei1Vv9ehO3DDXkO0yjiLjgGxCvnR0A== X-Received: by 2002:a5d:964f:: with SMTP id d15mr375990ios.230.1568668441698; Mon, 16 Sep 2019 14:14:01 -0700 (PDT) Received: from Olgas-MBP-201.attlocal.net (172-10-226-31.lightspeed.livnmi.sbcglobal.net. [172.10.226.31]) by smtp.gmail.com with ESMTPSA id l186sm71853ioa.54.2019.09.16.14.14.00 (version=TLS1 cipher=AES128-SHA bits=128/128); Mon, 16 Sep 2019 14:14:01 -0700 (PDT) From: Olga Kornievskaia To: trond.myklebust@hammerspace.com, anna.schumaker@netapp.com, bfields@redhat.com Cc: linux-nfs@vger.kernel.org Subject: [PATCH v7 06/19] NFS: skip recovery of copy open on dest server Date: Mon, 16 Sep 2019 17:13:40 -0400 Message-Id: <20190916211353.18802-7-olga.kornievskaia@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20190916211353.18802-1-olga.kornievskaia@gmail.com> References: <20190916211353.18802-1-olga.kornievskaia@gmail.com> Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org 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 8b9f039..f1a7f40 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 d9ca8af..b0dbb59 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 9afd051..e06a63f 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c @@ -1606,6 +1606,9 @@ static int nfs4_reclaim_open_state(struct nfs4_state_owner *sp, const struct nfs { struct nfs4_state *state; 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) @@ -1625,6 +1628,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); @@ -1671,6 +1681,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 Mon Sep 16 21:13:41 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Olga Kornievskaia X-Patchwork-Id: 11147861 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 7E072912 for ; Mon, 16 Sep 2019 21:14:04 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 5E3F5214AF for ; Mon, 16 Sep 2019 21:14:04 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="grQowfsu" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2391481AbfIPVOD (ORCPT ); Mon, 16 Sep 2019 17:14:03 -0400 Received: from mail-io1-f65.google.com ([209.85.166.65]:40309 "EHLO mail-io1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2391553AbfIPVOD (ORCPT ); Mon, 16 Sep 2019 17:14:03 -0400 Received: by mail-io1-f65.google.com with SMTP id h144so2452151iof.7 for ; Mon, 16 Sep 2019 14:14:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=s6AarPquzkHm5tiN4Chfneb8capNztVCqvBC79jNDEI=; b=grQowfsuSETsBNARBvpNy4U2XSnDgoY70VvHmQL+Od+9KQqGJXh1sQVrNsQEaCt2CI gXynMATsSiDm4OIQSR3t2gow5BD7+i3OsXZN2r9wjd4EPfbxn4nIU/oXZr/vvhwxToVs KQwM1vICN/1Af93UCL3mIq6eszRAjVNAoZsThuTa+pvKp0FnFQ73KoojsyVpvkN1JFiY WV7MpbGlhDhdWyamGyGVxqdtuHJX5GRb5Lfai1Sn1Jo1K7JtlH9GNy89zJAK2w2w24rN lMfCqAUhBzQ4ZT5WVuadEXujKlI9HqeotwdwwoiIehuXH6L3K5XwW8lH96Y2p1E1wNUc hGNA== 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=QnVK/2DtWxeWsULArtElIOVM0FY+9y4WvNP77EkNCL2Hnv+UZTZKSGC4+xsIRjTtZu alDaMbyHx3iTTks4dmizjC7dxXLo8ldMXRgUnIRq+ZS3lxF5ON57eLvmKaN2qDLp5Yqy 35F+hLn2y4+dK4xHvpBsxVFaoEDcMg1d793/xslAcuQg+RfRXMt5NKbU9H+vMtm0jAQ6 ce25sHn8sUZbi4cYWlc6kw4Coo8eCNSziEfcSFG1g0hyry0MzH643gh4toj4sr/HWv2D xy4XmylPtW2Zr6Qxkacu1jz5E8qFSTOKE7ync+w1sAQ1J0sAyKVmXoewaa0pDG6/KQQ8 P/7g== X-Gm-Message-State: APjAAAU+ZOWHXzwHDesUkUlAj5szr2Qd2Fi7Q7DrwrPL1u1zhraFxx3r 1aHa4jrbBAId0bNHGdPU+14= X-Google-Smtp-Source: APXvYqx21CIM51irABO4Pik97Y01EhTNuXLIOb4/aRciDSC1KFoQt7KmqG3mdmXWV+6k7V0VQa6BJA== X-Received: by 2002:a6b:5b0a:: with SMTP id v10mr412973ioh.80.1568668442544; Mon, 16 Sep 2019 14:14:02 -0700 (PDT) Received: from Olgas-MBP-201.attlocal.net (172-10-226-31.lightspeed.livnmi.sbcglobal.net. [172.10.226.31]) by smtp.gmail.com with ESMTPSA id l186sm71853ioa.54.2019.09.16.14.14.01 (version=TLS1 cipher=AES128-SHA bits=128/128); Mon, 16 Sep 2019 14:14:02 -0700 (PDT) From: Olga Kornievskaia To: trond.myklebust@hammerspace.com, anna.schumaker@netapp.com, bfields@redhat.com Cc: linux-nfs@vger.kernel.org Subject: [PATCH v7 07/19] NFS: for "inter" copy treat ESTALE as ENOTSUPP Date: Mon, 16 Sep 2019 17:13:41 -0400 Message-Id: <20190916211353.18802-8-olga.kornievskaia@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20190916211353.18802-1-olga.kornievskaia@gmail.com> References: <20190916211353.18802-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 Mon Sep 16 21:13:42 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Olga Kornievskaia X-Patchwork-Id: 11147863 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 A0A21912 for ; Mon, 16 Sep 2019 21:14:05 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 7FFE3214AF for ; Mon, 16 Sep 2019 21:14:05 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="C06Y5NQ/" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2391556AbfIPVOE (ORCPT ); Mon, 16 Sep 2019 17:14:04 -0400 Received: from mail-io1-f67.google.com ([209.85.166.67]:44102 "EHLO mail-io1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2391553AbfIPVOE (ORCPT ); Mon, 16 Sep 2019 17:14:04 -0400 Received: by mail-io1-f67.google.com with SMTP id j4so2379753iog.11 for ; Mon, 16 Sep 2019 14:14:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=OMSnhxhLm9jAGT4vNx3iX0q57Vtf9G2yxU8MZWSWriQ=; b=C06Y5NQ/yRI6FRYi4g4Tywc4Zwck84tN7rpN+e+x81RtbTtyUirdiohgfWuzt8BkWB KxSrs8P6appBirUjG2YxO/ebkw3ewAvG4FeixIKYFoPJnSD/yEyDTKA8l2zW3zOoMFSd PDCj6m9+9at9gHu3kdFT/JdpGdkwowrecsyHwT2gy83dytyih7MO5bSfJHKicbwJIC2+ EUc6CrF63j07H2oolPS+pgQUwx1Kw74VMP+Ht8Tbt7p4sAm/gAvlpgw4DZknw5Gq/0uy BzNPYQPJK7blwXSrLQi7FW6zm+u2+Rq1uo3B1FkJlCpVC6cvfTtnSlz9LHutWHimmfSc 0RnA== 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=tPjDyTTno4k+pOYT5x4eK3eljWtCtzxzFq3v8R2GkpkBtcEcakZ8HTus2FXE4Ju2Ng OFjiqrXV6PqnSY+8qMq2TYoL12Ne+5PQ1/V4lzyH/QGaTlEl2DKaarDQOVnnRTK4PY4L xTJCxv5DQcfrM7SZKsGu/hRL3DbKzhVrzbRy9g4wXEnBaDv0IpG5+8ul/tzdt3KeYTYL V4iY32ZBDuE27AYaMJMXglmI4Tqf3bF53i9Aib3p9XhMeN0YFY2fw7l522gxgxIdTh8R 0RGJoIKVwS+9kMuG+OF0zFsl0580YugGTIU3kll/PKq03v24SJLg6n/aQel/VFcAJAlB 1J8g== X-Gm-Message-State: APjAAAWUIEUaF6fnbSo/B/vq0B/3emYwZqEurCKRUrzOG0DH7mSn6nBo BZMwu/e4yhzTJ7/EFUJzySw= X-Google-Smtp-Source: APXvYqy7VXkbqDW+MPnfUFQ+VtRlvsMg8PobW5sL9GcqEghhsQa1RH1On4LvWsfYUbCmbHhGTsfa2Q== X-Received: by 2002:a5e:d50a:: with SMTP id e10mr329921iom.273.1568668443589; Mon, 16 Sep 2019 14:14:03 -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 l186sm71853ioa.54.2019.09.16.14.14.02 (version=TLS1 cipher=AES128-SHA bits=128/128); Mon, 16 Sep 2019 14:14:03 -0700 (PDT) From: Olga Kornievskaia To: trond.myklebust@hammerspace.com, anna.schumaker@netapp.com, bfields@redhat.com Cc: linux-nfs@vger.kernel.org Subject: [PATCH v7 08/19] NFS: COPY handle ERR_OFFLOAD_DENIED Date: Mon, 16 Sep 2019 17:13:42 -0400 Message-Id: <20190916211353.18802-9-olga.kornievskaia@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20190916211353.18802-1-olga.kornievskaia@gmail.com> References: <20190916211353.18802-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 Mon Sep 16 21:13:43 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Olga Kornievskaia X-Patchwork-Id: 11147865 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 87F9C1747 for ; Mon, 16 Sep 2019 21:14:06 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 5DC17214AF for ; Mon, 16 Sep 2019 21:14:06 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="SpOMjbX0" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2391580AbfIPVOF (ORCPT ); Mon, 16 Sep 2019 17:14:05 -0400 Received: from mail-io1-f67.google.com ([209.85.166.67]:40962 "EHLO mail-io1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2391571AbfIPVOF (ORCPT ); Mon, 16 Sep 2019 17:14:05 -0400 Received: by mail-io1-f67.google.com with SMTP id r26so2427782ioh.8 for ; Mon, 16 Sep 2019 14:14:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=u1LqSI0Dzdvw08DyYFFREUIyIIfvPEwHlIRWLh7nRb8=; b=SpOMjbX0Vgg3jIZVh3/EWsyC8cjAGHCqyfohV0/02tcGuryScQzkVgE5CnSTLSim/f jb20vMC3h/bAK9jI0qmYXU3/IFxAT1muwpRw/mkVmkb4qikKSvQcPDzFbTJQwKWDcuaT 2HY7ggHD9acdHQOgmxaiyo8EUGjv/52e0xgkOqcS4r0VZahXYSr5nLUM8CSF+cIiLNns 7ZYN19QxjuscpPM+aMWerb0tO3qgFIaIFRnhfcJadXsCU8+NbpszBvf3nSnRZ76BsLkW 5nUBL3QnQL+VnfXwp6Ts3joQi9a15LjfU4XXv0s4ylqL2qs71/pX+Pq5qO/8vTn8ym7P RzDw== 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=u1LqSI0Dzdvw08DyYFFREUIyIIfvPEwHlIRWLh7nRb8=; b=ErPmsf0b9EvC8hSham0ZOmv6SxPZiFjXj/dw+coh7xtz7ZMd2yFOC1YeXvqyDiHQVs 6EzUiDmXfywTBd0UDlschhwoBvT+EZz/2Fsexskgzyo+ogR85k57rjbZOsLeoT1TIipj L/NBh09ydMxyvJMJabHMR1T6TuvNu8wHd8S41MbaMfJyOac0z9pGGcaE9UI+5243V04X 98vbORnpxnqyP52PVi2LCFqCr14KueVN3EfRNc2ca9ku5mloFbYM3U0igiT5eQuwN/nl fE93NAeKml2BdLH6ILtrVVuHW5FpWnA4y3zghNskZvkE+xW617nSP/k/uPbTIIN+cJI2 8THQ== X-Gm-Message-State: APjAAAWaJckv4xbCudM5nVeSMcvQxGlw5SjTVu61yZ+ZQtHMohJdOOEC BrRkeoXwWIw8DI6IXM5t2i8= X-Google-Smtp-Source: APXvYqwKhMcZjOrz/RjMm6Y5aUYaHkhXqrNS+JMya0XKo9evMr2EyZP8hdLRgbsbPw1z2RgMGFMpFg== X-Received: by 2002:a5d:9410:: with SMTP id v16mr402887ion.10.1568668444524; Mon, 16 Sep 2019 14:14:04 -0700 (PDT) Received: from Olgas-MBP-201.attlocal.net (172-10-226-31.lightspeed.livnmi.sbcglobal.net. [172.10.226.31]) by smtp.gmail.com with ESMTPSA id l186sm71853ioa.54.2019.09.16.14.14.03 (version=TLS1 cipher=AES128-SHA bits=128/128); Mon, 16 Sep 2019 14:14:04 -0700 (PDT) From: Olga Kornievskaia To: trond.myklebust@hammerspace.com, anna.schumaker@netapp.com, bfields@redhat.com Cc: linux-nfs@vger.kernel.org Subject: [PATCH v7 09/19] NFS: handle source server reboot Date: Mon, 16 Sep 2019 17:13:43 -0400 Message-Id: <20190916211353.18802-10-olga.kornievskaia@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20190916211353.18802-1-olga.kornievskaia@gmail.com> References: <20190916211353.18802-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 f1a7f40..fec976e 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 b0dbb59..d02b25d 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 e06a63f..881ce7b 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c @@ -1554,15 +1554,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 Mon Sep 16 21:13:44 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Olga Kornievskaia X-Patchwork-Id: 11147867 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 37FA01747 for ; Mon, 16 Sep 2019 21:14:07 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 1823A214AF for ; Mon, 16 Sep 2019 21:14:07 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="p5ta7e1q" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2391571AbfIPVOG (ORCPT ); Mon, 16 Sep 2019 17:14:06 -0400 Received: from mail-io1-f65.google.com ([209.85.166.65]:38655 "EHLO mail-io1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2391553AbfIPVOG (ORCPT ); Mon, 16 Sep 2019 17:14:06 -0400 Received: by mail-io1-f65.google.com with SMTP id k5so2491258iol.5 for ; Mon, 16 Sep 2019 14:14:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=xOmeAPOzWbIw5m5L6jFu4S4E7KzwKfjPqHcj37yrr3s=; b=p5ta7e1quI8iF19PBnRx4OBluVx3q7gDUNNYWBhnZuX04vo5iF0BJxlvWjYFm1Edzo OsAe2sf0J0PPpuhDgKBBUMuyFi0UyptF3sOoFlEbbKT03hBcnwS3VBo1liDWGjfAN5mF 7rjjBgs+74a8uIPqXTB1CAIJnjyi7RF7Y5q1+WjJY5c88PjE5w09pB1CncOZgGnVAiPV 6oij6bf3awvjgGXL552retaujP6KU4JauURmUInjd+Bu+VPi8SHn2dmA80ZntQHHjYNF 13ulZKyI0RHQB66WbCa4Hq7QGiKI8VVLaczV0lBdCf4ZXEaGlLAQbWljNSaAjs/1NKMr Vwlw== 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=xOmeAPOzWbIw5m5L6jFu4S4E7KzwKfjPqHcj37yrr3s=; b=QGUkTA6f0JswzSYSta8iMwb/C72Ow2bvWf11Tlja00RziVj8ZhuhE76GUwXLdPcCOe pceJvGK6cQd7J6ghSeDmlFhHsrxjBkjpQ45jCsbxg1DAqL68Y1/BMffbQLm+eBd2YMtp vZwKp+beNzhLN3XeFk+2z7ntNX6Lg2KIk/VeuCF/0YWyraV2V7grrVJEFgmMSQhnfePG gNZ75Qn3pgJ4xzeJBxdA6HADc2sIV3rSWPPHYp8aIhuwiaNtuYzKZf7akBuBXWHADgo8 lUqk/v/QNLSVivfiyGx38zTI1yccOB0UaqMGzC5XVGeC1F+2kyHkw8142TndCMTT1xgG sLPA== X-Gm-Message-State: APjAAAV0eErwaIfE2xWXs6mMybc2H/AuUAIGbwrOteuP9vhPWDeDu4aP /TmBquaAy4HsgTXaKt00rGs= X-Google-Smtp-Source: APXvYqxjn2Z/hBM3uHlvX4oRTw5/aKy8Db+hRogrryVzVbs21g9QDZ2kX2SEXNxRih99LY35GvvAAg== X-Received: by 2002:a02:c901:: with SMTP id t1mr21057jao.13.1568668445425; Mon, 16 Sep 2019 14:14:05 -0700 (PDT) Received: from Olgas-MBP-201.attlocal.net (172-10-226-31.lightspeed.livnmi.sbcglobal.net. [172.10.226.31]) by smtp.gmail.com with ESMTPSA id l186sm71853ioa.54.2019.09.16.14.14.04 (version=TLS1 cipher=AES128-SHA bits=128/128); Mon, 16 Sep 2019 14:14:04 -0700 (PDT) From: Olga Kornievskaia To: trond.myklebust@hammerspace.com, anna.schumaker@netapp.com, bfields@redhat.com Cc: linux-nfs@vger.kernel.org Subject: [PATCH v7 10/19] NFS: replace cross device check in copy_file_range Date: Mon, 16 Sep 2019 17:13:44 -0400 Message-Id: <20190916211353.18802-11-olga.kornievskaia@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20190916211353.18802-1-olga.kornievskaia@gmail.com> References: <20190916211353.18802-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 d02b25d..bf70dee 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 Mon Sep 16 21:13:45 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Olga Kornievskaia X-Patchwork-Id: 11147869 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 38489912 for ; Mon, 16 Sep 2019 21:14:08 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 16F33214AF for ; Mon, 16 Sep 2019 21:14:08 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="WJWM3dvQ" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2391615AbfIPVOH (ORCPT ); Mon, 16 Sep 2019 17:14:07 -0400 Received: from mail-io1-f68.google.com ([209.85.166.68]:33293 "EHLO mail-io1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2391553AbfIPVOH (ORCPT ); Mon, 16 Sep 2019 17:14:07 -0400 Received: by mail-io1-f68.google.com with SMTP id m11so2571147ioo.0 for ; Mon, 16 Sep 2019 14:14:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=oYFP7LnHnffo4j/n4viWpRrrs/1IS/MsGu8QY/P3UN4=; b=WJWM3dvQcA2GyESkcyElRntWZsT+MqkeLdL+6WSL2iloesJeAzuDZlJ/cJEVe9lrMF xxdX5taBiptyA0kbyQ5pJRyzcTBAhcQKVhTLl/ywoMlL6XQalXms9VFrJgRUj270HR1W g9+v5IqNf67QY8Va0vG7K9TdPOk98wDWq+wsNUVkQprrM2MbqZPl5CKMS4HXwmyvBpO3 qP7nwLsHC0kQtYXby7G16YEkXB8OBQTFUEuRyODJWX8ua+6MsIWhfUDd7S1fWuoC835q xI8nH9GmvbZ/MYBcBYrSBVouzsk0Ody15irVkSI+zhUXtqaNbManNaLint9GyrQ+/Pi+ AZpQ== 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=e1aTDqwxckJ9ZytTf46ziqzNScbfdTbfif3fafk2Gra6tAgH0gM4bTWdmth4tLqjHX r88+C6TCP1nyQaVXOBzrJ9xEi898DOYXsIFAFxcPR4PVVZJ2EY4LW00I0NzUWaaqrWhd k96emf3gl0zDcJEd8VSm2scgAswDEpyuCBuKImpe6BqPPFmmwPR/21EZ1Bg9tQ5zsz+3 EQznH3KkLHpL3WDTDCTJenVeyMJUWLsFA/b4gIUjHn0Qlcot5gYGMYo1D+KljTRth3dG EgaueXJvwNFYjQJMAn6Gj1kVlGN4ZarwZOcXOZLn8uoJP56+PdQCbQo6w+fBpMNqfU7t R1Kw== X-Gm-Message-State: APjAAAXywV1tsPspTtEX4aknrNkRFW5zqn07427k9ztbNqYeKBZL9cRp mf4xsJ/XuWouay+8L3aCYB9Ii3LO X-Google-Smtp-Source: APXvYqztMnETTEpFOi4+BK8o8yR8N5DQPhN42BW+iBThEUpxOY0CtdsoDElXwUSfV1ET2m4iKvB/dQ== X-Received: by 2002:a5e:8219:: with SMTP id l25mr344831iom.177.1568668446409; Mon, 16 Sep 2019 14:14:06 -0700 (PDT) Received: from Olgas-MBP-201.attlocal.net (172-10-226-31.lightspeed.livnmi.sbcglobal.net. [172.10.226.31]) by smtp.gmail.com with ESMTPSA id l186sm71853ioa.54.2019.09.16.14.14.05 (version=TLS1 cipher=AES128-SHA bits=128/128); Mon, 16 Sep 2019 14:14:05 -0700 (PDT) From: Olga Kornievskaia To: trond.myklebust@hammerspace.com, anna.schumaker@netapp.com, bfields@redhat.com Cc: linux-nfs@vger.kernel.org Subject: [PATCH v7 11/19] NFSD fill-in netloc4 structure Date: Mon, 16 Sep 2019 17:13:45 -0400 Message-Id: <20190916211353.18802-12-olga.kornievskaia@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20190916211353.18802-1-olga.kornievskaia@gmail.com> References: <20190916211353.18802-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 Mon Sep 16 21:13:46 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Olga Kornievskaia X-Patchwork-Id: 11147871 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 4B61B1747 for ; Mon, 16 Sep 2019 21:14:09 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 2ABB9214AF for ; Mon, 16 Sep 2019 21:14:09 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="X3E8XE7h" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2391618AbfIPVOI (ORCPT ); Mon, 16 Sep 2019 17:14:08 -0400 Received: from mail-io1-f65.google.com ([209.85.166.65]:45110 "EHLO mail-io1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2391553AbfIPVOI (ORCPT ); Mon, 16 Sep 2019 17:14:08 -0400 Received: by mail-io1-f65.google.com with SMTP id f12so2369190iog.12 for ; Mon, 16 Sep 2019 14:14:07 -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=gxw4egQCQ9TVeNqggHC+3R7BB/vNpgZgy5w9tRLKXgk=; b=X3E8XE7hwfgTsXRyb4bVokQr0mkv5xZxJeWQSVXPJx/Y2VRCiTNwsg12nVH8cKg/rY Fxgf5zgePy9DAWQ8mPz8ehQrKTjJ2/vqbNzHSGnuRLZnlW2bC2ERhpAxtL4TkvdnHLhx 6ooS3d4vCxxi3MBgY/GsNaPpRv7IKz/Fjq1od2e8O+z4doua2mGn/o0665F5g5Uld/1g zfPZ9SRJrf3vaVH372sI2/c6y6SaBlgCEUSuWr+EJyq9D4dLzFGXeap8M6RNF2jf1qV6 sQYlt6k6rb23WZTCvSrAeUFVBrj5M5psm1XIou9HkspFzSA7Z6HVpMhrRNYYkWoQ6O2t Q9iA== 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=gxw4egQCQ9TVeNqggHC+3R7BB/vNpgZgy5w9tRLKXgk=; b=qLk4qYjScv9tvxxEHc920HMWXuK9CF5cDaMaaJ2ZjVu6YvIB7JxNvMSLXlCBVkVXEs CMi4mxt7R29ifG0HA39svEN7/a6Th53Ow5LjWlcR+WKiupC87wTeod002++ow09pU1EZ gLjDR7SQf1KRl0wtvGQkWjIBheqePe2IpRabkgwTw7hW/0wP+gCc+Atv0faYkR2CCdzP X/c2ouNynNrqglfsSRo95uvu/KM5bEBTcwXaqGIzeXBoKlKwWVuoYZOLJv14a7OnHp7d U26NCwBMn1eHcz52iQ1PR8ZK4YBXgw/zxh5oMCuxmVAARKi8FY6GhE/C4Gd1HSlecGvL jMWA== X-Gm-Message-State: APjAAAUJh53Friu4KDEdezs6BvTNnqaW0mpoQ+Z/Fs9NSpJX/0f9UUrx QuTFnem+nkxyLmnyxDflX2KLTQl8 X-Google-Smtp-Source: APXvYqzKCNOCFMImv9Sd4eXu2TXMdMVgZ00paKyGHEKMWjAZhu2eOUART1l8/D3+9SDjP8pR7P3TaA== X-Received: by 2002:a5e:8902:: with SMTP id k2mr382986ioj.49.1568668447434; Mon, 16 Sep 2019 14:14:07 -0700 (PDT) Received: from Olgas-MBP-201.attlocal.net (172-10-226-31.lightspeed.livnmi.sbcglobal.net. [172.10.226.31]) by smtp.gmail.com with ESMTPSA id l186sm71853ioa.54.2019.09.16.14.14.06 (version=TLS1 cipher=AES128-SHA bits=128/128); Mon, 16 Sep 2019 14:14:06 -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 v7 12/19] NFSD add ca_source_server<> to COPY Date: Mon, 16 Sep 2019 17:13:46 -0400 Message-Id: <20190916211353.18802-13-olga.kornievskaia@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20190916211353.18802-1-olga.kornievskaia@gmail.com> References: <20190916211353.18802-1-olga.kornievskaia@gmail.com> Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org Decode the ca_source_server list that's sent but only use the first one. Presence of non-zero list indicates an "inter" copy. Signed-off-by: Andy Adamson Signed-off-by: Olga Kornievskaia --- fs/nfsd/nfs4xdr.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- fs/nfsd/xdr4.h | 12 +++++----- 2 files changed, 71 insertions(+), 6 deletions(-) diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index c1fc264..3eccc81 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -40,6 +40,7 @@ #include #include #include +#include #include "idmap.h" #include "acl.h" @@ -1744,10 +1745,47 @@ static __be32 nfsd4_decode_reclaim_complete(struct nfsd4_compoundargs *argp, str DECODE_TAIL; } +static __be32 nfsd4_decode_nl4_server(struct nfsd4_compoundargs *argp, + struct nl4_server *ns) +{ + DECODE_HEAD; + struct nfs42_netaddr *naddr; + + READ_BUF(4); + ns->nl4_type = be32_to_cpup(p++); + + /* currently support for 1 inter-server source server */ + switch (ns->nl4_type) { + case NL4_NETADDR: + naddr = &ns->u.nl4_addr; + + READ_BUF(4); + naddr->netid_len = be32_to_cpup(p++); + if (naddr->netid_len > RPCBIND_MAXNETIDLEN) + goto xdr_error; + + READ_BUF(naddr->netid_len + 4); /* 4 for uaddr len */ + COPYMEM(naddr->netid, naddr->netid_len); + + naddr->addr_len = be32_to_cpup(p++); + if (naddr->addr_len > RPCBIND_MAXUADDRLEN) + goto xdr_error; + + READ_BUF(naddr->addr_len); + COPYMEM(naddr->addr, naddr->addr_len); + break; + default: + goto xdr_error; + } + DECODE_TAIL; +} + static __be32 nfsd4_decode_copy(struct nfsd4_compoundargs *argp, struct nfsd4_copy *copy) { DECODE_HEAD; + struct nl4_server *ns_dummy; + int i, count; status = nfsd4_decode_stateid(argp, ©->cp_src_stateid); if (status) @@ -1762,7 +1800,32 @@ static __be32 nfsd4_decode_reclaim_complete(struct nfsd4_compoundargs *argp, str p = xdr_decode_hyper(p, ©->cp_count); p++; /* ca_consecutive: we always do consecutive copies */ copy->cp_synchronous = be32_to_cpup(p++); - /* tmp = be32_to_cpup(p); Source server list not supported */ + + count = be32_to_cpup(p++); + + copy->cp_intra = false; + if (count == 0) { /* intra-server copy */ + copy->cp_intra = true; + goto intra; + } + + /* decode all the supplied server addresses but use first */ + status = nfsd4_decode_nl4_server(argp, ©->cp_src); + if (status) + return status; + + ns_dummy = kmalloc(sizeof(struct nl4_server), GFP_KERNEL); + if (ns_dummy == NULL) + return nfserrno(-ENOMEM); + for (i = 0; i < count - 1; i++) { + status = nfsd4_decode_nl4_server(argp, ns_dummy); + if (status) { + kfree(ns_dummy); + return status; + } + } + kfree(ns_dummy); +intra: DECODE_TAIL; } diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h index f4737d6..e815a9c 100644 --- a/fs/nfsd/xdr4.h +++ b/fs/nfsd/xdr4.h @@ -518,11 +518,13 @@ struct nfsd42_write_res { struct nfsd4_copy { /* request */ - stateid_t cp_src_stateid; - stateid_t cp_dst_stateid; - u64 cp_src_pos; - u64 cp_dst_pos; - u64 cp_count; + stateid_t cp_src_stateid; + stateid_t cp_dst_stateid; + u64 cp_src_pos; + u64 cp_dst_pos; + u64 cp_count; + struct nl4_server cp_src; + bool cp_intra; /* both */ bool cp_synchronous; From patchwork Mon Sep 16 21:13:47 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Olga Kornievskaia X-Patchwork-Id: 11147873 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 7C57B912 for ; Mon, 16 Sep 2019 21:14:10 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 51475214AF for ; Mon, 16 Sep 2019 21:14:10 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="ji9ii9Hc" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2391679AbfIPVOJ (ORCPT ); Mon, 16 Sep 2019 17:14:09 -0400 Received: from mail-io1-f68.google.com ([209.85.166.68]:44122 "EHLO mail-io1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2391664AbfIPVOJ (ORCPT ); Mon, 16 Sep 2019 17:14:09 -0400 Received: by mail-io1-f68.google.com with SMTP id j4so2380239iog.11 for ; Mon, 16 Sep 2019 14:14:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=TfW6tXQ8tUdc6Mp+z/yRFlFQYYquXAi5hBJpsjLZkxw=; b=ji9ii9HcXD+WwKqsaK/pSL4fjJura9rHNSoGaDQYpLpE63MXlFpDrDzUEQalJriag5 wNsFHKJ7mxRP9hqHqzS+j9Ettm6QVhLl4VdSdVKiBx+OalFFOYzY7R1mJGcvAYho9Eyx F6OI947XQguN74KlrjA3IG6X78c5zXoPqKot5nPAtM7TqG25DmMu9SDfPCWYqRsyNyQ3 nEf8Nh7dJiq/POixeJHyNBIv7Nj7MsabdWAwSQcwxh47EpA4oGvAmXE2XTb9vLRbJ1VR L2FgOi74GuloJ8IK0ckcO9JsOHPZyKanflinQ7E6ua/1I9XGYlFKQeIlTwsywPL/Rrz1 CRJg== 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=TfW6tXQ8tUdc6Mp+z/yRFlFQYYquXAi5hBJpsjLZkxw=; b=iJf2zNA96761gj91YQCAKLlRSDqZUVoA0MZxc+Dz0m0Jum8HydmVd1UPYtvX5hyZjZ 8Cf7Wh9lTc1LpOiKhbcPE52JzevpzkzJaC81AtEJWB5LDtPijUJqzB9f5hfrCjKbMw7z e6Mc7DBzAKlrlEPobShqBoy3gGYJhYTP2zDPYqzLffkNNUaqjn08gs4LpQfJSw4OGMRC UpM5KWevnVGp5+cp6+f0AGQp5paUHEdHspE25k0M09RhoMfDCCwUQ0/Dvdqu/PsaQQFR UscWdxLsH0WOYZFnExJAqTYIacb85FR/QtnkvNgczR9D4jIAlxvs5F/CuqJyERNsCYaL gfwg== X-Gm-Message-State: APjAAAUkUwsDLIqX79mcrRB3msOxkVK4Wb4lt2W0InDbOqiXTpq7HQuL WdmcR510TmYW7H7C2MZQ1QA= X-Google-Smtp-Source: APXvYqzYQgMIBKlbmWXk9jKSxSq2Hv3U+bZL7rWhtuXjVBlinFnA1A/ipX3jc7LQuYRfHNtK2ol8VA== X-Received: by 2002:a6b:640f:: with SMTP id t15mr356475iog.71.1568668448390; Mon, 16 Sep 2019 14:14:08 -0700 (PDT) Received: from Olgas-MBP-201.attlocal.net (172-10-226-31.lightspeed.livnmi.sbcglobal.net. [172.10.226.31]) by smtp.gmail.com with ESMTPSA id l186sm71853ioa.54.2019.09.16.14.14.07 (version=TLS1 cipher=AES128-SHA bits=128/128); Mon, 16 Sep 2019 14:14:07 -0700 (PDT) From: Olga Kornievskaia To: trond.myklebust@hammerspace.com, anna.schumaker@netapp.com, bfields@redhat.com Cc: linux-nfs@vger.kernel.org Subject: [PATCH v7 13/19] NFSD return nfs4_stid in nfs4_preprocess_stateid_op Date: Mon, 16 Sep 2019 17:13:47 -0400 Message-Id: <20190916211353.18802-14-olga.kornievskaia@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20190916211353.18802-1-olga.kornievskaia@gmail.com> References: <20190916211353.18802-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 | 21 +++++++++++---------- fs/nfsd/nfs4state.c | 11 ++++++++--- fs/nfsd/state.h | 3 ++- 3 files changed, 21 insertions(+), 14 deletions(-) diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 4e3e77b..6c0d216 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -776,7 +776,7 @@ static __be32 nfsd4_do_lookupp(struct svc_rqst *rqstp, struct svc_fh *fh) /* check stateid */ status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->current_fh, &read->rd_stateid, RD_STATE, - &read->rd_nf); + &read->rd_nf, NULL); if (status) { dprintk("NFSD: nfsd4_read: couldn't process stateid!\n"); goto out; @@ -948,7 +948,7 @@ static __be32 nfsd4_do_lookupp(struct svc_rqst *rqstp, struct svc_fh *fh) if (setattr->sa_iattr.ia_valid & ATTR_SIZE) { status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->current_fh, &setattr->sa_stateid, - WR_STATE, NULL); + WR_STATE, NULL, NULL); if (status) { dprintk("NFSD: nfsd4_setattr: couldn't process stateid!\n"); return status; @@ -999,7 +999,7 @@ static __be32 nfsd4_do_lookupp(struct svc_rqst *rqstp, struct svc_fh *fh) trace_nfsd_write_start(rqstp, &cstate->current_fh, write->wr_offset, cnt); status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->current_fh, - stateid, WR_STATE, &nf); + stateid, WR_STATE, &nf, NULL); if (status) { dprintk("NFSD: nfsd4_write: couldn't process stateid!\n"); return status; @@ -1026,7 +1026,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 nfsd_file **src, - stateid_t *dst_stateid, struct nfsd_file **dst) + stateid_t *dst_stateid, struct nfsd_file **dst, + struct nfs4_stid **stid) { __be32 status; @@ -1034,14 +1035,14 @@ static __be32 nfsd4_do_lookupp(struct svc_rqst *rqstp, struct svc_fh *fh) return nfserr_nofilehandle; status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->save_fh, - src_stateid, RD_STATE, src); + src_stateid, RD_STATE, src, NULL); if (status) { dprintk("NFSD: %s: couldn't process src stateid!\n", __func__); goto out; } status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->current_fh, - dst_stateid, WR_STATE, dst); + dst_stateid, WR_STATE, dst, stid); if (status) { dprintk("NFSD: %s: couldn't process dst stateid!\n", __func__); goto out_put_src; @@ -1072,7 +1073,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; @@ -1260,7 +1261,7 @@ static int nfsd4_do_async_copy(void *data) status = nfsd4_verify_copy(rqstp, cstate, ©->cp_src_stateid, ©->nf_src, ©->cp_dst_stateid, - ©->nf_dst); + ©->nf_dst, NULL); if (status) goto out; @@ -1346,7 +1347,7 @@ struct nfsd4_copy * status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->current_fh, &fallocate->falloc_stateid, - WR_STATE, &nf); + WR_STATE, &nf, NULL); if (status != nfs_ok) { dprintk("NFSD: nfsd4_fallocate: couldn't process stateid!\n"); return status; @@ -1405,7 +1406,7 @@ struct nfsd4_copy * status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->current_fh, &seek->seek_stateid, - RD_STATE, &nf); + RD_STATE, &nf, NULL); if (status) { dprintk("NFSD: nfsd4_seek: couldn't process stateid!\n"); return status; diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index da1093d..78e03af 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -5584,7 +5584,8 @@ static __be32 nfsd4_validate_stateid(struct nfs4_client *cl, stateid_t *stateid) __be32 nfs4_preprocess_stateid_op(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct svc_fh *fhp, - stateid_t *stateid, int flags, struct nfsd_file **nfp) + stateid_t *stateid, int flags, struct nfsd_file **nfp, + struct nfs4_stid **cstid) { struct inode *ino = d_inode(fhp->fh_dentry); struct net *net = SVC_NET(rqstp); @@ -5633,8 +5634,12 @@ static __be32 nfsd4_validate_stateid(struct nfs4_client *cl, stateid_t *stateid) if (status == nfs_ok && nfp) status = nfs4_check_file(rqstp, fhp, s, nfp, flags); out: - if (s) - nfs4_put_stid(s); + if (s) { + if (!status && cstid) + *cstid = s; + else + nfs4_put_stid(s); + } return status; } diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h index 46f56af..d9e7cbd 100644 --- a/fs/nfsd/state.h +++ b/fs/nfsd/state.h @@ -617,7 +617,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 nfsd_file **filp); + stateid_t *stateid, int flags, struct nfsd_file **filp, + struct nfs4_stid **cstid); __be32 nfsd4_lookup_stateid(struct nfsd4_compound_state *cstate, stateid_t *stateid, unsigned char typemask, struct nfs4_stid **s, struct nfsd_net *nn); From patchwork Mon Sep 16 21:13:48 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Olga Kornievskaia X-Patchwork-Id: 11147875 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 1E81B17E6 for ; Mon, 16 Sep 2019 21:14:11 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id E7A41214AF for ; Mon, 16 Sep 2019 21:14:10 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="vgeS23Bu" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2391664AbfIPVOK (ORCPT ); Mon, 16 Sep 2019 17:14:10 -0400 Received: from mail-io1-f65.google.com ([209.85.166.65]:40977 "EHLO mail-io1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2391594AbfIPVOK (ORCPT ); Mon, 16 Sep 2019 17:14:10 -0400 Received: by mail-io1-f65.google.com with SMTP id r26so2428198ioh.8 for ; Mon, 16 Sep 2019 14:14:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=hjAJTKN2Wr909eRk4xvtUyAslhnEEJ+P1ZIFM0yaDRI=; b=vgeS23BurDTFBecbxcL1JBbghsCYZzqkVvqZuDoEJuW/boP0xOXyNwkoEGArNi2AHJ 610H0IcNYi1AsM8nXq+/2XE8/fQArw+1td1orzhWIDIjeK3hpZNSZTWISFHccXcv7KDr rM4rQNESlC/R5YhcHZuCqQLKCIgke+qx8eZWNvcIFu9lZtFvQOzAcLZaqmx/LiS+287H pIm6RpcNs+hQta8dFBYhkMXf88Ttv80sAc/7ltAdA2OMiZ3jMx4eoc4nyyme6jaHo9kZ +IDA9mm1UyvB6YSmNHGHhpv2wxOQDcYXzJiyt6RFHINTiSrmZIdOD4/4Cv6bj4ADjRk+ 6d8w== 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=hjAJTKN2Wr909eRk4xvtUyAslhnEEJ+P1ZIFM0yaDRI=; b=E9QAUmb9P2lnH3CxmMneVkVCmdcTMmMbHIUzGe99J1FE0RSAGi7GhD1Umy1SXhwnzW Vntu9sLPX6Gbb/0qNpU137MTmOFi9Zn/1+fZaW1ZoUwC8im5nU9yeFrVX8Ai8mcd8UAD vu7nrqI9OnNzJHfD7eC3RskJpFK+uqGpiOLisxuUBdNag8zoZz0TV3YkpT2QzNPVQlHQ 4uaZm85/MFHLnQr2RmJ26dhot3EjoxN9XeJwmTbLsTdsT/lajXNJIoIz/8x0Zmb5WHaT kw2Qpter0H+UXni1KIY/3+eoo6bpueLRHAWoLE+y30oSeDwNB1b800mcy6EcLL50nUhD LIcQ== X-Gm-Message-State: APjAAAXB+2PoXgMfMWxYhEqzL2uRcFva0NYBtr7r3lVKNlz9smxjQXuR agE2qum2P0s5mkOXATxy2u8= X-Google-Smtp-Source: APXvYqy0OPTRvg3NKHK1S22pg0achUvVKRbPL0uaYb9kHDR7Xu3nScxQYwSLacrkkDOsAKvbYP7oTQ== X-Received: by 2002:a5d:964f:: with SMTP id d15mr376587ios.230.1568668449244; Mon, 16 Sep 2019 14:14:09 -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 l186sm71853ioa.54.2019.09.16.14.14.08 (version=TLS1 cipher=AES128-SHA bits=128/128); Mon, 16 Sep 2019 14:14:08 -0700 (PDT) From: Olga Kornievskaia To: trond.myklebust@hammerspace.com, anna.schumaker@netapp.com, bfields@redhat.com Cc: linux-nfs@vger.kernel.org Subject: [PATCH v7 14/19] NFSD COPY_NOTIFY xdr Date: Mon, 16 Sep 2019 17:13:48 -0400 Message-Id: <20190916211353.18802-15-olga.kornievskaia@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20190916211353.18802-1-olga.kornievskaia@gmail.com> References: <20190916211353.18802-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 6c0d216..05519a2 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -1339,6 +1339,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) { @@ -2291,6 +2298,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) { @@ -2715,6 +2737,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 3eccc81..ab6ca65 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -1838,6 +1838,18 @@ static __be32 nfsd4_decode_nl4_server(struct nfsd4_compoundargs *argp, } static __be32 +nfsd4_decode_copy_notify(struct nfsd4_compoundargs *argp, + struct nfsd4_copy_notify *cn) +{ + int status; + + status = nfsd4_decode_stateid(argp, &cn->cpn_src_stateid); + if (status) + return status; + return nfsd4_decode_nl4_server(argp, &cn->cpn_dst); +} + +static __be32 nfsd4_decode_seek(struct nfsd4_compoundargs *argp, struct nfsd4_seek *seek) { DECODE_HEAD; @@ -1938,7 +1950,7 @@ static __be32 nfsd4_decode_nl4_server(struct nfsd4_compoundargs *argp, /* new operations for NFSv4.2 */ [OP_ALLOCATE] = (nfsd4_dec)nfsd4_decode_fallocate, [OP_COPY] = (nfsd4_dec)nfsd4_decode_copy, - [OP_COPY_NOTIFY] = (nfsd4_dec)nfsd4_decode_notsupp, + [OP_COPY_NOTIFY] = (nfsd4_dec)nfsd4_decode_copy_notify, [OP_DEALLOCATE] = (nfsd4_dec)nfsd4_decode_fallocate, [OP_IO_ADVISE] = (nfsd4_dec)nfsd4_decode_notsupp, [OP_LAYOUTERROR] = (nfsd4_dec)nfsd4_decode_notsupp, @@ -4323,6 +4335,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) { @@ -4356,6 +4408,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) { @@ -4452,7 +4538,7 @@ static __be32 nfsd4_encode_readv(struct nfsd4_compoundres *resp, /* NFSv4.2 operations */ [OP_ALLOCATE] = (nfsd4_enc)nfsd4_encode_noop, [OP_COPY] = (nfsd4_enc)nfsd4_encode_copy, - [OP_COPY_NOTIFY] = (nfsd4_enc)nfsd4_encode_noop, + [OP_COPY_NOTIFY] = (nfsd4_enc)nfsd4_encode_copy_notify, [OP_DEALLOCATE] = (nfsd4_enc)nfsd4_encode_noop, [OP_IO_ADVISE] = (nfsd4_enc)nfsd4_encode_noop, [OP_LAYOUTERROR] = (nfsd4_enc)nfsd4_encode_noop, diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h index e815a9c..8231fe0 100644 --- a/fs/nfsd/xdr4.h +++ b/fs/nfsd/xdr4.h @@ -570,6 +570,18 @@ struct nfsd4_offload_status { u32 status; }; +struct nfsd4_copy_notify { + /* request */ + stateid_t cpn_src_stateid; + struct nl4_server cpn_dst; + + /* response */ + stateid_t cpn_cnr_stateid; + u64 cpn_sec; + u32 cpn_nsec; + struct nl4_server cpn_src; +}; + struct nfsd4_op { int opnum; const struct nfsd4_operation * opdesc; @@ -629,6 +641,7 @@ struct nfsd4_op { struct nfsd4_clone clone; struct nfsd4_copy copy; struct nfsd4_offload_status offload_status; + struct nfsd4_copy_notify copy_notify; struct nfsd4_seek seek; } u; struct nfs4_replay * replay; From patchwork Mon Sep 16 21:13:49 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Olga Kornievskaia X-Patchwork-Id: 11147879 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 5B69B1747 for ; Mon, 16 Sep 2019 21:14:14 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 30119214AF for ; Mon, 16 Sep 2019 21:14:14 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="YkJ7lawx" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2391726AbfIPVON (ORCPT ); Mon, 16 Sep 2019 17:14:13 -0400 Received: from mail-io1-f65.google.com ([209.85.166.65]:35921 "EHLO mail-io1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2391714AbfIPVON (ORCPT ); Mon, 16 Sep 2019 17:14:13 -0400 Received: by mail-io1-f65.google.com with SMTP id b136so2526206iof.3 for ; Mon, 16 Sep 2019 14:14:10 -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=Fo4Jqs/usI+OFiQc9c0IKLBn6AoUCJ8bT53gbW7MXbI=; b=YkJ7lawx5GiTvmq4FJZZ4XmPDxnmwNC8O57rQDfTQxYFwx2LC+aYcjTqTdyBXH+TXB 3Tq6nrW7T8jwEMtRoN34W6MVhVRgchGqKDl1ye3zhS8Q2Z3DdUP1icn4OQHqEU0YAJ5k G6gYTnF15wtjXepMJ/vgJrxz9menj/uC8ipkFyDoSlDBoWRZpTHYvt5Up+Yin8jt5DnY 5y2kudKrvS59ub7nf9yaovcWWCPwn+qnK7UMmcMDWXmrZ26s04yaVN8jkPL4IjizsE+y RZTGP5GxU6ZhUEo+pSrRjs5aPGL0nuAKXba329fr8pP9MR8dwMQY9FOOI+9vD5Kt5cIJ GmUA== 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=Fo4Jqs/usI+OFiQc9c0IKLBn6AoUCJ8bT53gbW7MXbI=; b=KU0mgdC9sJXuBCN1TdlaiCAUI0FEoNeIRleM296ZMzDRSuL0brkhu7t97VNYayk8g0 0Lg0fZFUM7q3AJWBJKK9kVSmRnSmBWMjOf1brXxxJCelN4XJO1mZ0USsFPCRqhSCNima GH/d5tugFGxMTzpSYVN5zaMg+KzeEmPKAf0DHqOg6+dqjTcIP+h1ndcOfU4noiSyjSaw N9EHF9JlKUJf4B5uG55GEnrClqF7IATWCy+N+1FKVU4vFGzFVnyas7ujBPwpCmFbw6t3 mCaFt0CeQZukswLVKgFGdCGtq8qSKSeLVXy5qWFTKWyAi7ReT6rGHEBAaHKZF9L3AkHd 3UEw== X-Gm-Message-State: APjAAAWPWrwsMjGirj3ZqObMMDktchDQfoV1GVEhExrb7Il0mlceN5zV WsKr47aI+7gnVoKUJYcJacM= X-Google-Smtp-Source: APXvYqyBnTUcvdBbP694EvKygKQ3FPy7uiSYXM4Ia58xzu5HZeRY4bR8rENsomxFZXzr6XRLM+BCKg== X-Received: by 2002:a5e:9911:: with SMTP id t17mr329498ioj.283.1568668450336; Mon, 16 Sep 2019 14:14:10 -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 l186sm71853ioa.54.2019.09.16.14.14.09 (version=TLS1 cipher=AES128-SHA bits=128/128); Mon, 16 Sep 2019 14:14:09 -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 v7 15/19] NFSD add COPY_NOTIFY operation Date: Mon, 16 Sep 2019 17:13:49 -0400 Message-Id: <20190916211353.18802-16-olga.kornievskaia@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20190916211353.18802-1-olga.kornievskaia@gmail.com> References: <20190916211353.18802-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 05519a2..75ecdbd 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" @@ -1221,7 +1222,7 @@ static void dup_copy_fields(struct nfsd4_copy *src, struct nfsd4_copy *dst) static void cleanup_async_copy(struct nfsd4_copy *copy) { - nfs4_free_cp_state(copy); + nfs4_free_copy_state(copy); nfsd_file_put(copy->nf_dst); nfsd_file_put(copy->nf_src); spin_lock(©->cp_clp->async_lock); @@ -1275,7 +1276,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; } @@ -1342,7 +1343,44 @@ struct nfsd4_copy * nfsd4_copy_notify(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, union nfsd4_op_u *u) { - return nfserr_notsupp; + struct nfsd4_copy_notify *cn = &u->copy_notify; + __be32 status; + struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id); + struct nfs4_stid *stid; + struct nfs4_cpntf_state *cps; + struct nfs4_client *clp = cstate->clp; + + status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->current_fh, + &cn->cpn_src_stateid, RD_STATE, NULL, + &stid); + if (status) + return status; + + cn->cpn_sec = nn->nfsd4_lease; + cn->cpn_nsec = 0; + + status = nfserrno(-ENOMEM); + cps = nfs4_alloc_init_cpntf_state(nn, stid); + if (!cps) + goto out; + memcpy(&cn->cpn_cnr_stateid, &cps->cp_stateid.stid, sizeof(stateid_t)); + memcpy(&cps->cp_p_stateid, &stid->sc_stateid, sizeof(stateid_t)); + memcpy(&cps->cp_p_clid, &clp->cl_clientid, sizeof(clientid_t)); + + /* For now, only return one server address in cpn_src, the + * address used by the client to connect to this server. + */ + cn->cpn_src.nl4_type = NL4_NETADDR; + status = nfsd4_set_netaddr((struct sockaddr *)&rqstp->rq_daddr, + &cn->cpn_src.u.nl4_addr); + WARN_ON_ONCE(status); + if (status) { + nfs4_put_cpntf_state(nn, cps); + goto out; + } +out: + nfs4_put_stid(stid); + return status; } static __be32 diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 78e03af..857133f 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -80,6 +80,7 @@ static bool check_for_locks(struct nfs4_file *fp, struct nfs4_lockowner *lowner); static void nfs4_free_ol_stateid(struct nfs4_stid *stid); void nfsd4_end_grace(struct nfsd_net *nn); +static void _free_cpntf_state_locked(struct nfsd_net *nn, struct nfs4_cpntf_state *cps); /* Locking: */ @@ -722,6 +723,7 @@ struct nfs4_stid *nfs4_alloc_stid(struct nfs4_client *cl, struct kmem_cache *sla /* Will be incremented before return to client: */ refcount_set(&stid->sc_count, 1); spin_lock_init(&stid->sc_lock); + INIT_LIST_HEAD(&stid->sc_cp_list); /* * It shouldn't be a problem to reuse an opaque stateid value. @@ -741,30 +743,76 @@ struct nfs4_stid *nfs4_alloc_stid(struct nfs4_client *cl, struct kmem_cache *sla /* * Create a unique stateid_t to represent each COPY. */ -int nfs4_init_cp_state(struct nfsd_net *nn, struct nfsd4_copy *copy) +static int nfs4_init_cp_state(struct nfsd_net *nn, copy_stateid_t *stid, + unsigned char sc_type) { int new_id; + stid->stid.si_opaque.so_clid.cl_boot = nn->boot_time; + stid->stid.si_opaque.so_clid.cl_id = nn->s2s_cp_cl_id; + stid->sc_type = sc_type; + idr_preload(GFP_KERNEL); spin_lock(&nn->s2s_cp_lock); - new_id = idr_alloc_cyclic(&nn->s2s_cp_stateids, copy, 0, 0, GFP_NOWAIT); + new_id = idr_alloc_cyclic(&nn->s2s_cp_stateids, stid, 0, 0, GFP_NOWAIT); + stid->stid.si_opaque.so_id = new_id; spin_unlock(&nn->s2s_cp_lock); idr_preload_end(); if (new_id < 0) return 0; - copy->cp_stateid.si_opaque.so_id = new_id; - copy->cp_stateid.si_opaque.so_clid.cl_boot = nn->boot_time; - copy->cp_stateid.si_opaque.so_clid.cl_id = nn->s2s_cp_cl_id; return 1; } -void nfs4_free_cp_state(struct nfsd4_copy *copy) +int nfs4_init_copy_state(struct nfsd_net *nn, struct nfsd4_copy *copy) +{ + return nfs4_init_cp_state(nn, ©->cp_stateid, NFS4_COPY_STID); +} + +struct nfs4_cpntf_state *nfs4_alloc_init_cpntf_state(struct nfsd_net *nn, + struct nfs4_stid *p_stid) +{ + struct nfs4_cpntf_state *cps; + + cps = kzalloc(sizeof(struct nfs4_cpntf_state), GFP_KERNEL); + if (!cps) + return NULL; + cps->cpntf_time = get_seconds(); + refcount_set(&cps->cp_stateid.sc_count, 1); + if (!nfs4_init_cp_state(nn, &cps->cp_stateid, NFS4_COPYNOTIFY_STID)) + goto out_free; + spin_lock(&nn->s2s_cp_lock); + list_add(&cps->cp_list, &p_stid->sc_cp_list); + spin_unlock(&nn->s2s_cp_lock); + return cps; +out_free: + kfree(cps); + return NULL; +} + +void nfs4_free_copy_state(struct nfsd4_copy *copy) { struct nfsd_net *nn; + WARN_ON_ONCE(copy->cp_stateid.sc_type != NFS4_COPY_STID); nn = net_generic(copy->cp_clp->net, nfsd_net_id); spin_lock(&nn->s2s_cp_lock); - idr_remove(&nn->s2s_cp_stateids, copy->cp_stateid.si_opaque.so_id); + idr_remove(&nn->s2s_cp_stateids, + copy->cp_stateid.stid.si_opaque.so_id); + spin_unlock(&nn->s2s_cp_lock); +} + +static void nfs4_free_cpntf_statelist(struct net *net, struct nfs4_stid *stid) +{ + struct nfs4_cpntf_state *cps; + struct nfsd_net *nn; + + nn = net_generic(net, nfsd_net_id); + spin_lock(&nn->s2s_cp_lock); + while (!list_empty(&stid->sc_cp_list)) { + cps = list_first_entry(&stid->sc_cp_list, + struct nfs4_cpntf_state, cp_list); + _free_cpntf_state_locked(nn, cps); + } spin_unlock(&nn->s2s_cp_lock); } @@ -915,6 +963,7 @@ static void block_delegations(struct knfsd_fh *fh) return; } idr_remove(&clp->cl_stateids, s->sc_stateid.si_opaque.so_id); + nfs4_free_cpntf_statelist(clp->net, s); spin_unlock(&clp->cl_lock); s->sc_free(s); if (fp) @@ -2906,6 +2955,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) @@ -2914,7 +2983,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, @@ -5192,6 +5262,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"); @@ -5202,6 +5275,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); @@ -5577,6 +5661,24 @@ static __be32 nfsd4_validate_stateid(struct nfs4_client *cl, stateid_t *stateid) out: return status; } +static void +_free_cpntf_state_locked(struct nfsd_net *nn, struct nfs4_cpntf_state *cps) +{ + WARN_ON_ONCE(cps->cp_stateid.sc_type != NFS4_COPYNOTIFY_STID); + if (!refcount_dec_and_test(&cps->cp_stateid.sc_count)) + return; + list_del(&cps->cp_list); + idr_remove(&nn->s2s_cp_stateids, + cps->cp_stateid.stid.si_opaque.so_id); + kfree(cps); +} + +void nfs4_put_cpntf_state(struct nfsd_net *nn, struct nfs4_cpntf_state *cps) +{ + spin_lock(&nn->s2s_cp_lock); + _free_cpntf_state_locked(nn, cps); + spin_unlock(&nn->s2s_cp_lock); +} /* * Checks for stateid operations diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h index d9e7cbd..967b937 100644 --- a/fs/nfsd/state.h +++ b/fs/nfsd/state.h @@ -56,6 +56,14 @@ stateid_opaque_t si_opaque; } stateid_t; +typedef struct { + stateid_t stid; +#define NFS4_COPY_STID 1 +#define NFS4_COPYNOTIFY_STID 2 + unsigned char sc_type; + refcount_t sc_count; +} copy_stateid_t; + #define STATEID_FMT "(%08x/%08x/%08x/%08x)" #define STATEID_VAL(s) \ (s)->si_opaque.so_clid.cl_boot, \ @@ -96,6 +104,7 @@ struct nfs4_stid { #define NFS4_REVOKED_DELEG_STID 16 #define NFS4_CLOSED_DELEG_STID 32 #define NFS4_LAYOUT_STID 64 + struct list_head sc_cp_list; unsigned char sc_type; stateid_t sc_stateid; spinlock_t sc_lock; @@ -104,6 +113,17 @@ struct nfs4_stid { void (*sc_free)(struct nfs4_stid *); }; +/* Keep a list of stateids issued by the COPY_NOTIFY, associate it with the + * parent OPEN/LOCK/DELEG stateid. + */ +struct nfs4_cpntf_state { + copy_stateid_t cp_stateid; + struct list_head cp_list; /* per parent nfs4_stid */ + stateid_t cp_p_stateid; /* copy of parent's stateid */ + clientid_t cp_p_clid; /* copy of parent's clid */ + time_t cpntf_time; /* last time stateid used */ +}; + /* * Represents a delegation stateid. The nfs4_client holds references to these * and they are put when it is being destroyed or when the delegation is @@ -624,8 +644,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); @@ -655,6 +677,8 @@ extern struct nfs4_client_reclaim *nfs4_client_to_reclaim(struct xdr_netobj name extern void nfs4_put_copy(struct nfsd4_copy *copy); extern struct nfsd4_copy * find_async_copy(struct nfs4_client *clp, stateid_t *staetid); +extern void nfs4_put_cpntf_state(struct nfsd_net *nn, + struct nfs4_cpntf_state *cps); static inline void get_nfs4_file(struct nfs4_file *fi) { refcount_inc(&fi->fi_ref); diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h index 8231fe0..2937e06 100644 --- a/fs/nfsd/xdr4.h +++ b/fs/nfsd/xdr4.h @@ -542,7 +542,7 @@ struct nfsd4_copy { struct nfsd_file *nf_src; struct nfsd_file *nf_dst; - stateid_t cp_stateid; + copy_stateid_t cp_stateid; struct list_head copies; struct task_struct *copy_task; From patchwork Mon Sep 16 21:13:50 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Olga Kornievskaia X-Patchwork-Id: 11147881 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 917A1184E for ; Mon, 16 Sep 2019 21:14:14 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 6551021670 for ; Mon, 16 Sep 2019 21:14:14 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="hpopZXUp" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2391730AbfIPVON (ORCPT ); Mon, 16 Sep 2019 17:14:13 -0400 Received: from mail-io1-f48.google.com ([209.85.166.48]:38242 "EHLO mail-io1-f48.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2391727AbfIPVON (ORCPT ); Mon, 16 Sep 2019 17:14:13 -0400 Received: by mail-io1-f48.google.com with SMTP id k5so2491854iol.5 for ; Mon, 16 Sep 2019 14:14:11 -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=Ggh0X7K6RiNd+ssWBMJ19hAXMZFj9oik6gRkgHkQxTI=; b=hpopZXUpD807gFBom7UbJ7Nmu9deaqqNXua0qGHElEPRUP0ZjBqIq3mmBYCw+XgWV3 6Nvj0An0LRo5xhi5sgtz/zHwLXpIrIqCaqh7pVXXt3SzMN36a4NLn0RDwIrhbtf6UCGI 2OHeYLQw4cmTUBt1gdqJDRWKUI7lTCYE6yIfrjlL+j7TZegdanW2Q4yYEkAoKbm8rFTV Wnzqv5wvLJQRWTepDrYH7Cij6MaaDcKN9XioBLEEg5c2ZMZnwanDJZMIkwBw5r3Jv9FJ hLxXNxdNG5bPIGu6U9SjHXx+r+PyHH41WceUZjHvvY3MfhZrx47l+0Xs1gVowSoZU5ES 4omg== 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=Ggh0X7K6RiNd+ssWBMJ19hAXMZFj9oik6gRkgHkQxTI=; b=RrM2K9Y2kw1+cFUnEsmcf8/ztdCNO2lhP63VUsRgCuYI52Y3Q5883yW8ch0rZvz0I2 Jfcag1++82fytsfsTcNBsYZIKl81xPrmEJkwz9loie0JyMEqFajN8weWt/t+tGXNIWuY 9BYpNX8hAvgapL9cMaCjbzFwGv5QgleO7QHD86mU8yjFazsXDYtKuobI4jzhVJ94VTtk /bWhxAt/SE+AIyWqrDbAA55VadBnZSrNNb+dh3YMAH5ZxXNcJw7woF2axPc84ZfXZoKJ lg0pVFUSd1cM+G0CH6+gEWSjVmGRn+WznL+Jr7zl06pxeHuBkFtdqRQSf9ZKOFCgssCp 92Rw== X-Gm-Message-State: APjAAAU9yXAoOtQwoOCdjwR2Xg0iikGE2YMboqHBc5WpE05T56PxHAUi OnTrcCRuCvknHe3xGHhNMzE= X-Google-Smtp-Source: APXvYqzoeXakh6WPGR6rLAR46JtydFQr+n/yCEqrVlEGatN4pwx33Mu2oJludP1wuCp7Ov2e76+TjA== X-Received: by 2002:a5d:9410:: with SMTP id v16mr403389ion.10.1568668451367; Mon, 16 Sep 2019 14:14:11 -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 l186sm71853ioa.54.2019.09.16.14.14.10 (version=TLS1 cipher=AES128-SHA bits=128/128); Mon, 16 Sep 2019 14:14:10 -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 v7 16/19] NFSD check stateids against copy stateids Date: Mon, 16 Sep 2019 17:13:50 -0400 Message-Id: <20190916211353.18802-17-olga.kornievskaia@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20190916211353.18802-1-olga.kornievskaia@gmail.com> References: <20190916211353.18802-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 857133f..062c0c4 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -4537,7 +4537,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; @@ -4558,7 +4559,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; @@ -4591,7 +4592,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; @@ -5180,7 +5181,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; @@ -5582,7 +5583,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; @@ -5672,6 +5674,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) { @@ -5709,6 +5764,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, @@ -6741,7 +6798,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; } @@ -6925,7 +6983,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; @@ -7072,7 +7130,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 Mon Sep 16 21:13:51 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Olga Kornievskaia X-Patchwork-Id: 11147877 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 15765912 for ; Mon, 16 Sep 2019 21:14:14 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id E7550214AF for ; Mon, 16 Sep 2019 21:14:13 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="aGaEI/U8" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2391594AbfIPVON (ORCPT ); Mon, 16 Sep 2019 17:14:13 -0400 Received: from mail-io1-f68.google.com ([209.85.166.68]:35221 "EHLO mail-io1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2391726AbfIPVON (ORCPT ); Mon, 16 Sep 2019 17:14:13 -0400 Received: by mail-io1-f68.google.com with SMTP id q10so2534013iop.2 for ; Mon, 16 Sep 2019 14:14:12 -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=FkJA5NZVA3SfnZ9SpaIKC970zxZFIqt+2LS0HGfJkFM=; b=aGaEI/U846Un/LOj/dsdEYNaCz/YG7OimKyXrggszWFRGPYvJCfhXE3J6TxZXIIkDs ejKA55lRCvRPZz1h8J7cbhjrDuMteacFFz6Did424MxHMstCIU3eCxKhTxd1/1bDFYC+ EeYXZDfyrUsATehCQgnW2mRMIf/R0WtYOs1qs5URFvOHOp/jn4eGVC1qPWWe8HWhM9gz 5iFPM6LBn7mvOUoNANaO+7udl10J2Cnz6Rf47LDoxIAVVQJbfcLd2BoNuAXcJMS1x96W gSxiZP9KfW5SuocfuDq5odNCCG4u2f3IilnpFyp3CuM8GKNB6gbFCoSWLCljPyRttDtd d85A== 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=FkJA5NZVA3SfnZ9SpaIKC970zxZFIqt+2LS0HGfJkFM=; b=Vu8Gy/y0qBr14MdxZ7sBO6/FwjYnmk71oCsj2k1OweGyI2VJqYmfuprOc/9vwmFo7c AV0w/CJt8YwzSiUR1Q7SXPo/1e/pEvEIJXG6ISa5TRDp1Vzj/IH3fa5aSE31+mCLZg8D LaJ87c43+VxoH5th1khZrc4esUhf4ozvxdjlH2XnTL20DbuVvJnwcpgwagB8zzb6Wfsz wkWh9z8qQg0Ck7sJX7su992knTeTS6EypZ/bW21JQnvQjtpOLrDCpveWADJ/jBhH2Ha8 H+jzG9psdYNR3VEAb8/HEMoZSGqVbGwTXTKFsFU+NA4ZPsr92lY8zFHumN9UJSxmRvoa qwgw== X-Gm-Message-State: APjAAAUySV9gjINK4e4Zv8YqF1QGQr4TL7sK5yZNC8rJDmmSEGBYYMKS QdM2rTD6rm9tK79tC7iLvdw= X-Google-Smtp-Source: APXvYqyALkxOyPSGHhdWe6O6OX0i+qahVpFmfm8FUyZQqk0t6C05wBAFKm8ubT0cVwjtpDW/l4h8oA== X-Received: by 2002:a6b:ec16:: with SMTP id c22mr342384ioh.185.1568668452377; Mon, 16 Sep 2019 14:14:12 -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 l186sm71853ioa.54.2019.09.16.14.14.11 (version=TLS1 cipher=AES128-SHA bits=128/128); Mon, 16 Sep 2019 14:14:11 -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 v7 17/19] NFSD generalize nfsd4_compound_state flag names Date: Mon, 16 Sep 2019 17:13:51 -0400 Message-Id: <20190916211353.18802-18-olga.kornievskaia@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20190916211353.18802-1-olga.kornievskaia@gmail.com> References: <20190916211353.18802-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 75ecdbd..90d0b67 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 062c0c4..81c52282 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -7928,7 +7928,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)); } @@ -7937,14 +7938,14 @@ static int nfs4_state_create_net(struct net *net) { if (cstate->minorversion) { memcpy(&cstate->current_stateid, stateid, sizeof(stateid_t)); - SET_STATE_ID(cstate, CURRENT_STATE_ID_FLAG); + SET_CSTATE_FLAG(cstate, CURRENT_STATE_ID_FLAG); } } void clear_current_stateid(struct nfsd4_compound_state *cstate) { - CLEAR_STATE_ID(cstate, CURRENT_STATE_ID_FLAG); + CLEAR_CSTATE_FLAG(cstate, CURRENT_STATE_ID_FLAG); } /* diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h index 2937e06..0b4fe07 100644 --- a/fs/nfsd/xdr4.h +++ b/fs/nfsd/xdr4.h @@ -46,9 +46,9 @@ #define CURRENT_STATE_ID_FLAG (1<<0) #define SAVED_STATE_ID_FLAG (1<<1) -#define SET_STATE_ID(c, f) ((c)->sid_flags |= (f)) -#define HAS_STATE_ID(c, f) ((c)->sid_flags & (f)) -#define CLEAR_STATE_ID(c, f) ((c)->sid_flags &= ~(f)) +#define SET_CSTATE_FLAG(c, f) ((c)->sid_flags |= (f)) +#define HAS_CSTATE_FLAG(c, f) ((c)->sid_flags & (f)) +#define CLEAR_CSTATE_FLAG(c, f) ((c)->sid_flags &= ~(f)) struct nfsd4_compound_state { struct svc_fh current_fh; From patchwork Mon Sep 16 21:13:52 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Olga Kornievskaia X-Patchwork-Id: 11147883 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 086CD1747 for ; Mon, 16 Sep 2019 21:14:16 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id D019B214AF for ; Mon, 16 Sep 2019 21:14:15 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="DH7oi9IW" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2391728AbfIPVOP (ORCPT ); Mon, 16 Sep 2019 17:14:15 -0400 Received: from mail-io1-f66.google.com ([209.85.166.66]:40355 "EHLO mail-io1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2391714AbfIPVOO (ORCPT ); Mon, 16 Sep 2019 17:14:14 -0400 Received: by mail-io1-f66.google.com with SMTP id h144so2453312iof.7 for ; Mon, 16 Sep 2019 14:14:13 -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=6OkpC9E05WzvbRfFRBqu0Uaj19M1WruuZAYSCLwXsQY=; b=DH7oi9IWqDfJeguC1iImkQWaw2MHscEUHX8FsxZxJn2aHIMAmZEc4AncwQT3bYRLOE yYDf0CDz9l4GRPYrtWOu6stL26vkxyyyZbY5/3NSRLahAPk6c6yzyKQ5MtmOwc8AsXI4 9cyimmUQN2P5TD/aVZbE+F0+8E4MNZXzLK39UmjY9HpI75W6RUXrloySqVBrMq1Hbvut Aciq4Q9xnIEBXe1TRcvK7HD/TiP+wdWvtLbzi2fmGpEBX4iSklhYd4hUYBCFCXJeo7Me 8+xn3g362fEn5aPAV0no2+N5P2mGq2bIGL5RS/mJ5IklZLkMHwEfrxRaV5j6VLcsTOLZ fq1Q== 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=6OkpC9E05WzvbRfFRBqu0Uaj19M1WruuZAYSCLwXsQY=; b=COSDSZW6FCbLrKODwe2kKTQ06Z7jRrIK51zzoksS78T2biTrbkNSL1u0nNfA/0aPQY /yMCBbvQ5bDybLSu1KKUoRl/WXOVIlO61MhmtAfUE3Ct875sVG1WKi9zbNwMCVW7YiWA Uhys6/44/vBkIBDrRMRKvrMEb2hExWEnDNj4K/HTZ78v+v4NX08IX61wCQkXXMyjP4Dt rUNAlvO7IdbHkl3KGQBYpn4ctb1993EoIQYwq11H/t+0v7m+dm4PP+PulFgHV5H7ZVbx n1DvFvZM+rNKQ8FuqHxxf3N3j7PHIxdcy/zNBuYXFD1POlRgYZ2qdapcHw7PBFDokoT6 XjXQ== X-Gm-Message-State: APjAAAVt1GPgMl30GLWCAhOgrWnjm864eB6cygQ2Y9xGh2u5dm72C6lt X3YNTz2PdQvX2N+EqryCC2E1good X-Google-Smtp-Source: APXvYqzuJNpOSl9Pjo/4nSveEE3fZpLE7chQrmq0mNob9/tEyfCZgyBO8bq7+LsLDCQ07it4niUo1g== X-Received: by 2002:a5d:9842:: with SMTP id p2mr429075ios.226.1568668453328; Mon, 16 Sep 2019 14:14:13 -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 l186sm71853ioa.54.2019.09.16.14.14.12 (version=TLS1 cipher=AES128-SHA bits=128/128); Mon, 16 Sep 2019 14:14:12 -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 v7 18/19] NFSD: allow inter server COPY to have a STALE source server fh Date: Mon, 16 Sep 2019 17:13:52 -0400 Message-Id: <20190916211353.18802-19-olga.kornievskaia@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20190916211353.18802-1-olga.kornievskaia@gmail.com> References: <20190916211353.18802-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 10cefb0..b7172a8 100644 --- a/fs/nfsd/Kconfig +++ b/fs/nfsd/Kconfig @@ -133,6 +133,16 @@ config NFSD_FLEXFILELAYOUT If unsure, say N. +config NFSD_V4_2_INTER_SSC + bool "NFSv4.2 inter server to server COPY" + depends on NFSD_V4 && NFS_V4_1 && NFS_V4_2 + help + This option enables support for NFSv4.2 inter server to + server copy where the destination server calls the NFSv4.2 + client to read the data to copy from the source server. + + If unsure, say N. + config NFSD_V4_SECURITY_LABEL bool "Provide Security Label support for NFSv4 server" depends on NFSD_V4 && SECURITY diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 90d0b67..7574ba7 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 @@ -1956,6 +1964,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. */ @@ -2004,6 +2051,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) { @@ -2019,13 +2069,14 @@ static void svcxdr_init_encode(struct svc_rqst *rqstp, op->status = nfsd4_open_omfg(rqstp, cstate, op); goto encode_op; } - - if (!current_fh->fh_dentry) { + if (!current_fh->fh_dentry && + !HAS_FH_FLAG(current_fh, NFSD4_FH_FOREIGN)) { if (!(op->opdesc->op_flags & ALLOWED_WITHOUT_FH)) { op->status = nfserr_nofilehandle; goto encode_op; } - } else if (current_fh->fh_export->ex_fslocs.migrated && + } else if (current_fh->fh_export && + current_fh->fh_export->ex_fslocs.migrated && !(op->opdesc->op_flags & ALLOWED_ON_ABSENT_FS)) { op->status = nfserr_moved; goto encode_op; diff --git a/fs/nfsd/nfsfh.h b/fs/nfsd/nfsfh.h index 755e256..b9c7568 100644 --- a/fs/nfsd/nfsfh.h +++ b/fs/nfsd/nfsfh.h @@ -35,7 +35,7 @@ static inline ino_t u32_to_ino_t(__u32 uino) bool fh_locked; /* inode locked by us */ bool fh_want_write; /* remount protection taken */ - + int fh_flags; /* FH flags */ #ifdef CONFIG_NFSD_V3 bool fh_post_saved; /* post-op attrs saved */ bool fh_pre_saved; /* pre-op attrs saved */ @@ -56,6 +56,9 @@ static inline ino_t u32_to_ino_t(__u32 uino) #endif /* CONFIG_NFSD_V3 */ } svc_fh; +#define NFSD4_FH_FOREIGN (1<<0) +#define SET_FH_FLAG(c, f) ((c)->fh_flags |= (f)) +#define HAS_FH_FLAG(c, f) ((c)->fh_flags & (f)) enum nfsd_fsid { FSID_DEV = 0, diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h index 0b4fe07..b16f602 100644 --- a/fs/nfsd/xdr4.h +++ b/fs/nfsd/xdr4.h @@ -221,6 +221,7 @@ struct nfsd4_lookup { struct nfsd4_putfh { u32 pf_fhlen; /* request */ char *pf_fhval; /* request */ + bool no_verify; /* represents foreigh fh */ }; struct nfsd4_open { From patchwork Mon Sep 16 21:13:53 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Olga Kornievskaia X-Patchwork-Id: 11147885 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 C739B1747 for ; Mon, 16 Sep 2019 21:14:16 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 914B1214AF for ; Mon, 16 Sep 2019 21:14:16 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="UeKTKQVq" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2391714AbfIPVOP (ORCPT ); Mon, 16 Sep 2019 17:14:15 -0400 Received: from mail-io1-f67.google.com ([209.85.166.67]:46410 "EHLO mail-io1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2391731AbfIPVOP (ORCPT ); Mon, 16 Sep 2019 17:14:15 -0400 Received: by mail-io1-f67.google.com with SMTP id d17so2348192ios.13 for ; Mon, 16 Sep 2019 14:14:14 -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=TELUJ9R0qZYczDtbSrqJlCMlqtu9N2RwLrQYRSTeNlo=; b=UeKTKQVq56dFTT5QV+vHOEkkpzkcrDM2TZ0n1Nrbv9Azag4suWMn1/DnuvkP9/5tZ+ qMjqIqjXW4JbuFe+gdmEV2sZPIeBjddtHW7RZVdEHxatsbG2TwO14TZMVMJY14DioBAy Xg4Q+A5YbOOExv07JMsY3rthsGKoi5VbXDC4cqnfCCSVnwPx+ha5aD//Ub/2w2kFvMoM le/DLNcSXch+/F2cAy9z+eZuE/Qqvpx++j2eqF9oXYVhcDfmhbSA6hqmNU4xBOcnrKmu /8c+WEG5v/h36t1i8jMW3OQhajc57AHS79DRRDoePl8susM8Y6kMLZFv30KMAiy5wgqM QnGQ== 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=TELUJ9R0qZYczDtbSrqJlCMlqtu9N2RwLrQYRSTeNlo=; b=qiGOkyZNgqM+izhIZWpWMZM3aTi9N0gRjtabjDg8Ar5l5wZLjI3lqber61gN2weCSR JH1XxHrVTRi/SouSubG2oSKSXs0CJTcjKmhI3kvY3FOdoPDaW3cCQ/eymLgymZsqK7MG rj2oKGvFzmivjOJxrsciwJj6JqTrjRoVDnBaS+znESVOd7SCEzMxQku0wUjR+E5zYS/x LNHa5cunMgAMh4nmxCIu1XnAoa+pXhg0yRmLYLGSbfUlT7XjBE4jfq1VkrmU0GavXvpe ODKmgH3PIWF5JtbXfF5kEMoPOC8tHexfGU2bRwcXpl83AZCjsHgdSQw4gHo2FYKvf3gW KQMA== X-Gm-Message-State: APjAAAVMT01GmJNFs50E3+xKL9/wIvG18vcQDkwZJkTDbg8VEBHJiFFt +kImf2rJTOvHsjTTandkoaQ= X-Google-Smtp-Source: APXvYqxeiVhYZDPkuN7vTH/qIjxn3aN2azh2wmzvBM0XEtro3+b7Adq5nk/rA7AYvSi1RpbV5uf60g== X-Received: by 2002:a5d:8455:: with SMTP id w21mr343199ior.201.1568668454219; Mon, 16 Sep 2019 14:14:14 -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 l186sm71853ioa.54.2019.09.16.14.14.13 (version=TLS1 cipher=AES128-SHA bits=128/128); Mon, 16 Sep 2019 14:14:13 -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 v7 19/19] NFSD add nfs4 inter ssc to nfsd4_copy Date: Mon, 16 Sep 2019 17:13:53 -0400 Message-Id: <20190916211353.18802-20-olga.kornievskaia@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20190916211353.18802-1-olga.kornievskaia@gmail.com> References: <20190916211353.18802-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 | 284 ++++++++++++++++++++++++++++++++++++++++++++++++---- fs/nfsd/nfs4state.c | 15 ++- fs/nfsd/nfssvc.c | 6 ++ fs/nfsd/state.h | 3 + fs/nfsd/xdr4.h | 5 + 5 files changed, 286 insertions(+), 27 deletions(-) diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 7574ba7..006d502 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -1144,6 +1144,208 @@ void nfsd4_shutdown_copy(struct nfs4_client *clp) while ((copy = nfsd4_get_copy(clp)) != NULL) nfsd4_stop_copy(copy); } +#ifdef CONFIG_NFSD_V4_2_INTER_SSC + +extern struct file *nfs42_ssc_open(struct vfsmount *ss_mnt, + struct nfs_fh *src_fh, + nfs4_stateid *stateid); +extern void nfs42_ssc_close(struct file *filep); + +extern void nfs_sb_deactive(struct super_block *sb); + +#define NFSD42_INTERSSC_MOUNTOPS "vers=4.2,addr=%s,sec=sys" + +/** + * Support one copy source server for now. + */ +static __be32 +nfsd4_interssc_connect(struct nl4_server *nss, struct svc_rqst *rqstp, + struct vfsmount **mount) +{ + struct file_system_type *type; + struct vfsmount *ss_mnt; + struct nfs42_netaddr *naddr; + struct sockaddr_storage tmp_addr; + size_t tmp_addrlen, match_netid_len = 3; + char *startsep = "", *endsep = "", *match_netid = "tcp"; + char *ipaddr, *dev_name, *raw_data; + int len, raw_len, status = -EINVAL; + + naddr = &nss->u.nl4_addr; + tmp_addrlen = rpc_uaddr2sockaddr(SVC_NET(rqstp), naddr->addr, + naddr->addr_len, + (struct sockaddr *)&tmp_addr, + sizeof(tmp_addr)); + if (tmp_addrlen == 0) + goto out_err; + + if (tmp_addr.ss_family == AF_INET6) { + startsep = "["; + endsep = "]"; + match_netid = "tcp6"; + match_netid_len = 4; + } + + if (naddr->netid_len != match_netid_len || + strncmp(naddr->netid, match_netid, naddr->netid_len)) + goto out_err; + + /* Construct the raw data for the vfs_kern_mount call */ + len = RPC_MAX_ADDRBUFLEN + 1; + ipaddr = kzalloc(len, GFP_KERNEL); + if (!ipaddr) + goto out_err; + + rpc_ntop((struct sockaddr *)&tmp_addr, ipaddr, len); + + /* 2 for ipv6 endsep and startsep. 3 for ":/" and trailing '/0'*/ + + raw_len = strlen(NFSD42_INTERSSC_MOUNTOPS) + strlen(ipaddr); + raw_data = kzalloc(raw_len, GFP_KERNEL); + if (!raw_data) + goto out_free_ipaddr; + + snprintf(raw_data, raw_len, NFSD42_INTERSSC_MOUNTOPS, ipaddr); + + status = -ENODEV; + type = get_fs_type("nfs"); + if (!type) + goto out_free_rawdata; + + /* Set the server: for the vfs_kern_mount call */ + dev_name = kzalloc(len + 5, GFP_KERNEL); + if (!dev_name) + goto out_free_rawdata; + snprintf(dev_name, len + 5, "%s%s%s:/", startsep, ipaddr, endsep); + + /* Use an 'internal' mount: SB_KERNMOUNT -> MNT_INTERNAL */ + ss_mnt = vfs_kern_mount(type, SB_KERNMOUNT, dev_name, raw_data); + module_put(type->owner); + if (IS_ERR(ss_mnt)) + goto out_free_devname; + + status = 0; + *mount = ss_mnt; + +out_free_devname: + kfree(dev_name); +out_free_rawdata: + kfree(raw_data); +out_free_ipaddr: + kfree(ipaddr); +out_err: + return status; +} + +static void +nfsd4_interssc_disconnect(struct vfsmount *ss_mnt) +{ + nfs_sb_deactive(ss_mnt->mnt_sb); + mntput(ss_mnt); +} + +/** + * nfsd4_setup_inter_ssc + * + * Verify COPY destination stateid. + * Connect to the source server with NFSv4.1. + * Create the source struct file for nfsd_copy_range. + * Called with COPY cstate: + * SAVED_FH: source filehandle + * CURRENT_FH: destination filehandle + * + * Returns errno (not nfserrxxx) + */ +static __be32 +nfsd4_setup_inter_ssc(struct svc_rqst *rqstp, + struct nfsd4_compound_state *cstate, + struct nfsd4_copy *copy, struct vfsmount **mount) +{ + struct svc_fh *s_fh = NULL; + stateid_t *s_stid = ©->cp_src_stateid; + __be32 status = -EINVAL; + + /* Verify the destination stateid and set dst struct file*/ + status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->current_fh, + ©->cp_dst_stateid, + WR_STATE, ©->nf_dst, NULL); + if (status) + goto out; + + status = nfsd4_interssc_connect(©->cp_src, rqstp, mount); + if (status) + goto out; + + s_fh = &cstate->save_fh; + + copy->c_fh.size = s_fh->fh_handle.fh_size; + memcpy(copy->c_fh.data, &s_fh->fh_handle.fh_base, copy->c_fh.size); + copy->stateid.seqid = s_stid->si_generation; + memcpy(copy->stateid.other, (void *)&s_stid->si_opaque, + sizeof(stateid_opaque_t)); + + status = 0; +out: + return status; +} + +static void +nfsd4_cleanup_inter_ssc(struct vfsmount *ss_mnt, struct nfsd_file *src, + struct nfsd_file *dst) +{ + nfs42_ssc_close(src->nf_file); + nfsd_file_put(src); + nfsd_file_put(dst); + mntput(ss_mnt); +} + +#else /* CONFIG_NFSD_V4_2_INTER_SSC */ + +static __be32 +nfsd4_setup_inter_ssc(struct svc_rqst *rqstp, + struct nfsd4_compound_state *cstate, + struct nfsd4_copy *copy, + struct vfsmount **mount) +{ + *mount = NULL; + return -EINVAL; +} + +static void +nfsd4_cleanup_inter_ssc(struct vfsmount *ss_mnt, struct 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, + ©->nf_src, ©->cp_dst_stateid, + ©->nf_dst, NULL); +} + +static void +nfsd4_cleanup_intra_ssc(struct nfsd_file *src, struct nfsd_file *dst) +{ + nfsd_file_put(src); + nfsd_file_put(dst); +} static void nfsd4_cb_offload_release(struct nfsd4_callback *cb) { @@ -1209,12 +1411,16 @@ static __be32 nfsd4_do_copy(struct nfsd4_copy *copy, bool sync) status = nfs_ok; } - nfsd_file_put(copy->nf_src); - nfsd_file_put(copy->nf_dst); + if (!copy->cp_intra) /* Inter server SSC */ + nfsd4_cleanup_inter_ssc(copy->ss_mnt, copy->nf_src, + copy->nf_dst); + else + nfsd4_cleanup_intra_ssc(copy->nf_src, copy->nf_dst); + return status; } -static void dup_copy_fields(struct nfsd4_copy *src, struct nfsd4_copy *dst) +static int dup_copy_fields(struct nfsd4_copy *src, struct nfsd4_copy *dst) { dst->cp_src_pos = src->cp_src_pos; dst->cp_dst_pos = src->cp_dst_pos; @@ -1224,8 +1430,17 @@ static void dup_copy_fields(struct nfsd4_copy *src, struct nfsd4_copy *dst) memcpy(&dst->fh, &src->fh, sizeof(src->fh)); dst->cp_clp = src->cp_clp; dst->nf_dst = nfsd_file_get(src->nf_dst); - dst->nf_src = nfsd_file_get(src->nf_src); + dst->cp_intra = src->cp_intra; + if (src->cp_intra) /* for inter, file_src doesn't exist yet */ + dst->nf_src = nfsd_file_get(src->nf_src); + memcpy(&dst->cp_stateid, &src->cp_stateid, sizeof(src->cp_stateid)); + memcpy(&dst->cp_src, &src->cp_src, sizeof(struct nl4_server)); + memcpy(&dst->stateid, &src->stateid, sizeof(src->stateid)); + memcpy(&dst->c_fh, &src->c_fh, sizeof(src->c_fh)); + dst->ss_mnt = src->ss_mnt; + + return 0; } static void cleanup_async_copy(struct nfsd4_copy *copy) @@ -1244,7 +1459,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->nf_src->nf_file = nfs42_ssc_open(copy->ss_mnt, ©->c_fh, + ©->stateid); + if (IS_ERR(copy->nf_src)) { + copy->nfserr = nfserr_offload_denied; + nfsd4_interssc_disconnect(copy->ss_mnt); + goto do_callback; + } + } + copy->nfserr = nfsd4_do_copy(copy, 0); +do_callback: cb_copy = kzalloc(sizeof(struct nfsd4_copy), GFP_KERNEL); if (!cb_copy) goto out; @@ -1268,11 +1494,20 @@ static int nfsd4_do_async_copy(void *data) __be32 status; struct nfsd4_copy *async_copy = NULL; - status = nfsd4_verify_copy(rqstp, cstate, ©->cp_src_stateid, - ©->nf_src, ©->cp_dst_stateid, - ©->nf_dst, 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, @@ -1283,15 +1518,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)) @@ -1302,12 +1537,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; } @@ -1318,7 +1557,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); @@ -1334,17 +1573,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 81c52282..0a70a82 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -5679,8 +5679,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; @@ -5694,12 +5695,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; } @@ -5710,7 +5715,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 3caaf56..e093c81 100644 --- a/fs/nfsd/nfssvc.c +++ b/fs/nfsd/nfssvc.c @@ -31,6 +31,12 @@ #define NFSDDBG_FACILITY NFSDDBG_SVC +bool inter_copy_offload_enable; +EXPORT_SYMBOL_GPL(inter_copy_offload_enable); +module_param(inter_copy_offload_enable, bool, 0644); +MODULE_PARM_DESC(inter_copy_offload_enable, + "Enable inter server to server copy offload. Default: false"); + extern struct svc_program nfsd_program; static int nfsd(void *vrqstp); #if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h index 967b937..3f57680 100644 --- a/fs/nfsd/state.h +++ b/fs/nfsd/state.h @@ -679,6 +679,9 @@ extern struct nfs4_client_reclaim *nfs4_client_to_reclaim(struct xdr_netobj name find_async_copy(struct nfs4_client *clp, stateid_t *staetid); extern void nfs4_put_cpntf_state(struct nfsd_net *nn, struct nfs4_cpntf_state *cps); +extern __be32 manage_cpntf_state(struct nfsd_net *nn, stateid_t *st, + struct nfs4_client *clp, + struct nfs4_cpntf_state **cps); static inline void get_nfs4_file(struct nfs4_file *fi) { refcount_inc(&fi->fi_ref); diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h index b16f602..db63d39 100644 --- a/fs/nfsd/xdr4.h +++ b/fs/nfsd/xdr4.h @@ -549,7 +549,12 @@ struct nfsd4_copy { struct task_struct *copy_task; refcount_t refcount; bool stopped; + + struct vfsmount *ss_mnt; + struct nfs_fh c_fh; + nfs4_stateid stateid; }; +extern bool inter_copy_offload_enable; struct nfsd4_seek { /* request */