From patchwork Mon Jul 8 19:23: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: 11035701 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E4A82138D for ; Mon, 8 Jul 2019 19:23:53 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D432F2847B for ; Mon, 8 Jul 2019 19:23:53 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C6B7A28516; Mon, 8 Jul 2019 19:23:53 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4F6A12847B for ; Mon, 8 Jul 2019 19:23:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731530AbfGHTXw (ORCPT ); Mon, 8 Jul 2019 15:23:52 -0400 Received: from mail-io1-f67.google.com ([209.85.166.67]:34420 "EHLO mail-io1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729193AbfGHTXw (ORCPT ); Mon, 8 Jul 2019 15:23:52 -0400 Received: by mail-io1-f67.google.com with SMTP id k8so37939995iot.1 for ; Mon, 08 Jul 2019 12:23:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=4IoPYbY7faRXqYApBCuNXczxAha8aebK68IvZnRULGY=; b=VqOw8xLbTyJPb0GgFh2C016YP0I4+RW53FzhOS6Tfi08g26rO9e7Vj+BuhMokQsgnL oQ34Y2IAkmGCLCi+Kl75B9BWFOG37nOndVhG+lPLwDNhsmsMssEffXY2UamkK4yd07av ylpxr6OAD4lCCYQIXfPYZa5UOqfrmfLVA9nxUhdVZo9XulH7BVBOUMul2j1mn6RQWCkO WgQ9uR3I+Ruq6+cCMETgmWflsz+3LXbgGMhOcHNUziHfDLJRc7yOsgi93NGXCOrpUtsK ZH8s5Th2GnqrXaUsHM3QDJjkrGkhSsqWCg3zb6t8UJ/tOKOpJvb9LQGl+JC2oNs/i0ku 30LQ== 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=4IoPYbY7faRXqYApBCuNXczxAha8aebK68IvZnRULGY=; b=EvpIPplqkFuC4Zm0+O3JRXmYDiHx5I8pGA3R6/lRb9nhZM917aalwl7sD27yMpFCbS H5/m9a72eIjTTgzfX6LEE3LCXtjrfqcfqPKsEWOyTAoVm5F81p179qULHJeybFKZBbqq l80d0P8J6Ax0VKbKIi0REa+KlZZFbB9GJvGNHaZ+r+XXEa3q3hCIYuqrXlXJYoEDA8hX slY/8Ql8AiEuwuyMgEYcQ1VeI98N/uWJt57OwI7zitSgFttdcnFLKi4Vjm7HI1+oehXJ qHIdIOLhZnGWlVUYMoKQ1/r8UdMp2yjEFbpFVnh2U3fVcXoSMrsVQc65agrZUNKTwZPC 72IA== X-Gm-Message-State: APjAAAXiydnQYkCWIdKK7z1ILu85BVC6M701onGpdAqgnDb/XsN+YGeG a0OR9hz02UPpg7PRO6+YgaE= X-Google-Smtp-Source: APXvYqxly6UJvhCnQ0MOSYaH6mDmNDaLFrOwKrQUvebMkTKey3ymvR47Z2a0H0mEtaSlV95XCh2UhQ== X-Received: by 2002:a6b:bec7:: with SMTP id o190mr19719765iof.158.1562613831708; Mon, 08 Jul 2019 12:23:51 -0700 (PDT) Received: from Olgas-MBP-201.attlocal.net (172-10-226-31.lightspeed.livnmi.sbcglobal.net. [172.10.226.31]) by smtp.gmail.com with ESMTPSA id v3sm9212841iom.53.2019.07.08.12.23.50 (version=TLS1 cipher=AES128-SHA bits=128/128); Mon, 08 Jul 2019 12:23:51 -0700 (PDT) From: Olga Kornievskaia To: bfields@redhat.com Cc: linux-nfs@vger.kernel.org Subject: [PATCH v4 1/8] NFSD fill-in netloc4 structure Date: Mon, 8 Jul 2019 15:23:45 -0400 Message-Id: <20190708192352.12614-2-olga.kornievskaia@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20190708192352.12614-1-olga.kornievskaia@gmail.com> References: <20190708192352.12614-1-olga.kornievskaia@gmail.com> Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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 24187b5..8f4fc50 100644 --- a/fs/nfsd/nfsd.h +++ b/fs/nfsd/nfsd.h @@ -19,6 +19,7 @@ #include #include #include +#include #include @@ -375,6 +376,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 Jul 8 19:23: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: 11035703 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id DAE88138D for ; Mon, 8 Jul 2019 19:23:54 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CAE9D2847B for ; Mon, 8 Jul 2019 19:23:54 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id BF7F328516; Mon, 8 Jul 2019 19:23:54 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 564582847B for ; Mon, 8 Jul 2019 19:23:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2390460AbfGHTXx (ORCPT ); Mon, 8 Jul 2019 15:23:53 -0400 Received: from mail-io1-f65.google.com ([209.85.166.65]:40111 "EHLO mail-io1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729193AbfGHTXx (ORCPT ); Mon, 8 Jul 2019 15:23:53 -0400 Received: by mail-io1-f65.google.com with SMTP id h6so29634901iom.7 for ; Mon, 08 Jul 2019 12:23:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=zi+IwbtumV5UCUL+b2Yo7pz3+p+fyC4kJRneYtlgiV4=; b=cn0zYQRv7ITo0ZWtqwZb4PoVyAuBzN2wdS8oZWizk14kOVEdExid6t1IxBlOJhGNVG 5QjvGA/SMzZCqxe08fO7ztuihOo1jdwp6y3N+HJ8zRNLWEGlS6mbx/F3FltWrNRmaAMh AzJjS0WVJtOQvJmG6jUnbfsfchZYyWyQyswmSRq66sVFbPdWMnPe7WBCVLnCuNBtgJzd pAwne/d96wCeKdyj8HzXtFMzddBfdb7iWBWxP+9K3KlvpV1vKSHJ6WWywmgc769uICHD 0uof1OC8B8cMORkzsBkXIKblHYtA7c7f0g+75xfyiJljv2s85nw0zPOb3z9t96TC42T9 35Ww== 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=zi+IwbtumV5UCUL+b2Yo7pz3+p+fyC4kJRneYtlgiV4=; b=jNhYAQSy2Jegu8jlgbq33J45gAm+oI/1X1b7TyjzkrD3C0gQyBbU6ie5IbpahwcZwk yc/00XBIq4+k+bl9RV1/NkQXNCHZB27ZezwzEh12i0WKgoL/eJNK13LWeuKGu2MsU03M CcPvcPenitvrtjZQwLhdEApI1dJGa2HUdDgvxzj7e3jFTYq+MbJ0Z17CuxHyEkCaoFdi kCJtwEssmEV1K/etDy090VbpQ13lo5QTw8JAuVv3Jf8Cspm5TpRjayMXYApywYogmfqI n0OvoSQCIQ17IJONsmGOM8zgknELwZBzTVK5SQCWQRXw98qYuqodQOsymZ81EoIZ+svF BNFA== X-Gm-Message-State: APjAAAWjT/h53uwO3xciGT70zuu/bX30iSbcXfHoxcFR8LRQL9ptyE8X iPZlw1MjxSWmaiRmlcIZpH0= X-Google-Smtp-Source: APXvYqy93vcofDZTumreSXjH2ju3+tQMN5oTXYn90qqXxzOe9lKVKy0lddjEGJfoKlNzff3EDut0kg== X-Received: by 2002:a6b:8bd1:: with SMTP id n200mr21751916iod.134.1562613832619; Mon, 08 Jul 2019 12:23:52 -0700 (PDT) Received: from Olgas-MBP-201.attlocal.net (172-10-226-31.lightspeed.livnmi.sbcglobal.net. [172.10.226.31]) by smtp.gmail.com with ESMTPSA id v3sm9212841iom.53.2019.07.08.12.23.51 (version=TLS1 cipher=AES128-SHA bits=128/128); Mon, 08 Jul 2019 12:23:52 -0700 (PDT) From: Olga Kornievskaia To: bfields@redhat.com Cc: linux-nfs@vger.kernel.org Subject: [PATCH v4 2/8] NFSD add ca_source_server<> to COPY Date: Mon, 8 Jul 2019 15:23:46 -0400 Message-Id: <20190708192352.12614-3-olga.kornievskaia@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20190708192352.12614-1-olga.kornievskaia@gmail.com> References: <20190708192352.12614-1-olga.kornievskaia@gmail.com> Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Olga Kornievskaia 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 | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- fs/nfsd/xdr4.h | 12 +++++---- 2 files changed, 80 insertions(+), 7 deletions(-) diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 52c4f6d..15f53bb 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,11 +1745,58 @@ 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_NAME: + case NL4_URL: + READ_BUF(4); + ns->u.nl4_str_sz = be32_to_cpup(p++); + if (ns->u.nl4_str_sz > NFS4_OPAQUE_LIMIT) + goto xdr_error; + + READ_BUF(ns->u.nl4_str_sz); + COPYMEM(ns->u.nl4_str, + ns->u.nl4_str_sz); + break; + case NL4_NETADDR: + naddr = &ns->u.nl4_addr; + + READ_BUF(4); + naddr->netid_len = be32_to_cpup(p++); + if (naddr->netid_len > RPCBIND_MAXNETIDLEN) + goto xdr_error; + + READ_BUF(naddr->netid_len + 4); /* 4 for uaddr len */ + COPYMEM(naddr->netid, naddr->netid_len); + + naddr->addr_len = be32_to_cpup(p++); + if (naddr->addr_len > RPCBIND_MAXUADDRLEN) + goto xdr_error; + + READ_BUF(naddr->addr_len); + COPYMEM(naddr->addr, naddr->addr_len); + break; + default: + goto xdr_error; + } + DECODE_TAIL; +} + static __be32 nfsd4_decode_copy(struct nfsd4_compoundargs *argp, struct nfsd4_copy *copy) { DECODE_HEAD; - unsigned int tmp; + struct nl4_server *ns_dummy; + int i, count; status = nfsd4_decode_stateid(argp, ©->cp_src_stateid); if (status) @@ -1763,8 +1811,31 @@ static __be32 nfsd4_decode_reclaim_complete(struct nfsd4_compoundargs *argp, str p = xdr_decode_hyper(p, ©->cp_count); p++; /* ca_consecutive: we always do consecutive copies */ copy->cp_synchronous = be32_to_cpup(p++); - tmp = be32_to_cpup(p); /* Source server list not supported */ + count = be32_to_cpup(p++); + copy->cp_intra = false; + if (count == 0) { /* intra-server copy */ + copy->cp_intra = true; + goto intra; + } + + /* decode all the supplied server addresses but use first */ + status = nfsd4_decode_nl4_server(argp, ©->cp_src); + if (status) + return status; + + ns_dummy = kmalloc(sizeof(struct nl4_server), GFP_KERNEL); + if (ns_dummy == NULL) + return nfserrno(-ENOMEM); + for (i = 0; i < count - 1; i++) { + status = nfsd4_decode_nl4_server(argp, ns_dummy); + if (status) { + kfree(ns_dummy); + return status; + } + } + kfree(ns_dummy); +intra: DECODE_TAIL; } diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h index feeb6d4..513c9ff 100644 --- a/fs/nfsd/xdr4.h +++ b/fs/nfsd/xdr4.h @@ -516,11 +516,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 Jul 8 19:23: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: 11035705 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id DAA8E112C for ; Mon, 8 Jul 2019 19:23:55 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CB2F42847B for ; Mon, 8 Jul 2019 19:23:55 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id BFC4628516; Mon, 8 Jul 2019 19:23:55 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4A2C42847B for ; Mon, 8 Jul 2019 19:23:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731567AbfGHTXy (ORCPT ); Mon, 8 Jul 2019 15:23:54 -0400 Received: from mail-io1-f66.google.com ([209.85.166.66]:37934 "EHLO mail-io1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731545AbfGHTXy (ORCPT ); Mon, 8 Jul 2019 15:23:54 -0400 Received: by mail-io1-f66.google.com with SMTP id j6so37872951ioa.5 for ; Mon, 08 Jul 2019 12:23:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=jOGnRdmnKEVxYoAacsG8HHMnQ37g5MRdn9njQ6D0VUM=; b=KYujh9t9Uj+yFHgE90MT6p7EnOdlZGOcvdmVcrbx4u50hE5viVaoiN5qFxYEErdBAn kINlvRUByHmA0MtE+Am0ASIbPuANkyetYAGPy7moilF/63kP8mpJ9PMDfcpHBuQiJCQV Zb4RuQEg16p4vCDcmQKy4e1RdgkEwMd2wxuJ8Hj52TNr3LxFAL8ktQpGn5ataVoL78C+ hpODmcg45tnvNP83vfGPmh9iON4dG74xolvHKxESISSPGG4mHoTJqI8g5uuok0rj/+qQ 1bpCmbcua+EfTAJKNnG/kAP1p15AZVwurGc3UReqoBPMOFAN+LvitCbtwk1XtT7VnGH0 1vPA== 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=jOGnRdmnKEVxYoAacsG8HHMnQ37g5MRdn9njQ6D0VUM=; b=OS5I2rhpXIG0FmUCwGKGwgT0DM0/x2mMTp0BItpHEMei/cw/0ClwRBTQTb3FfpJ4jv 5sPk/n36/j6P5+gh6gmxquxa2mT3ArJnek0fgbOIx+JtdxhnErsMOc/NVSWWQbWWoMop uF+MiAhGZbRs6Z1l5DDt9rM+LFjtsykTdoEN5Ft/m998rKBzmuPo60hOV1S2fHhdsIoF Gg4VUP3kLlYb9cj5mGBy3bZRpg0KOm8xvKAtlVFaGlJI+0QGTk9JFr+YoMYqkjDXPZZE vXFXCs3P2QACm+jaWH2iPIsOKadFnLZgIR8nwXSJ6Tevbk2TsWTN8/OSHyiye0fElCGm JpqA== X-Gm-Message-State: APjAAAVGNU+DuTw6x/5pPkDcET+vfJrdX9kphWXv9hyhzqrRsNva5kEA /BJGxSG/V1hycDtzw5yYPAk= X-Google-Smtp-Source: APXvYqwI9kgfEwF/QTYAwvm7UCz9i5JsN4iPDZ32Nk9H8pmekyZDGt0e3tIhMLqQuny83WL43mIQgw== X-Received: by 2002:a6b:bbc1:: with SMTP id l184mr576996iof.232.1562613833424; Mon, 08 Jul 2019 12:23:53 -0700 (PDT) Received: from Olgas-MBP-201.attlocal.net (172-10-226-31.lightspeed.livnmi.sbcglobal.net. [172.10.226.31]) by smtp.gmail.com with ESMTPSA id v3sm9212841iom.53.2019.07.08.12.23.52 (version=TLS1 cipher=AES128-SHA bits=128/128); Mon, 08 Jul 2019 12:23:52 -0700 (PDT) From: Olga Kornievskaia To: bfields@redhat.com Cc: linux-nfs@vger.kernel.org Subject: [PATCH v4 3/8] NFSD return nfs4_stid in nfs4_preprocess_stateid_op Date: Mon, 8 Jul 2019 15:23:47 -0400 Message-Id: <20190708192352.12614-4-olga.kornievskaia@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20190708192352.12614-1-olga.kornievskaia@gmail.com> References: <20190708192352.12614-1-olga.kornievskaia@gmail.com> Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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 | 17 ++++++++++------- fs/nfsd/nfs4state.c | 8 ++++++-- fs/nfsd/state.h | 3 ++- 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 8beda99..cfd8767 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -782,7 +782,8 @@ static __be32 nfsd4_do_lookupp(struct svc_rqst *rqstp, struct svc_fh *fh) /* check stateid */ status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->current_fh, &read->rd_stateid, RD_STATE, - &read->rd_filp, &read->rd_tmp_file); + &read->rd_filp, &read->rd_tmp_file, + NULL); if (status) { dprintk("NFSD: nfsd4_read: couldn't process stateid!\n"); goto out; @@ -954,7 +955,7 @@ static __be32 nfsd4_do_lookupp(struct svc_rqst *rqstp, struct svc_fh *fh) if (setattr->sa_iattr.ia_valid & ATTR_SIZE) { status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->current_fh, &setattr->sa_stateid, - WR_STATE, NULL, NULL); + WR_STATE, NULL, NULL, NULL); if (status) { dprintk("NFSD: nfsd4_setattr: couldn't process stateid!\n"); return status; @@ -1005,7 +1006,7 @@ static __be32 nfsd4_do_lookupp(struct svc_rqst *rqstp, struct svc_fh *fh) trace_nfsd_write_start(rqstp, &cstate->current_fh, write->wr_offset, cnt); status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->current_fh, - stateid, WR_STATE, &filp, NULL); + stateid, WR_STATE, &filp, NULL, NULL); if (status) { dprintk("NFSD: nfsd4_write: couldn't process stateid!\n"); return status; @@ -1040,14 +1041,16 @@ static __be32 nfsd4_do_lookupp(struct svc_rqst *rqstp, struct svc_fh *fh) return nfserr_nofilehandle; status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->save_fh, - src_stateid, RD_STATE, src, NULL); + src_stateid, RD_STATE, src, NULL, + NULL); if (status) { dprintk("NFSD: %s: couldn't process src stateid!\n", __func__); goto out; } status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->current_fh, - dst_stateid, WR_STATE, dst, NULL); + dst_stateid, WR_STATE, dst, NULL, + NULL); if (status) { dprintk("NFSD: %s: couldn't process dst stateid!\n", __func__); goto out_put_src; @@ -1351,7 +1354,7 @@ struct nfsd4_copy * status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->current_fh, &fallocate->falloc_stateid, - WR_STATE, &file, NULL); + WR_STATE, &file, NULL, NULL); if (status != nfs_ok) { dprintk("NFSD: nfsd4_fallocate: couldn't process stateid!\n"); return status; @@ -1410,7 +1413,7 @@ struct nfsd4_copy * status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->current_fh, &seek->seek_stateid, - RD_STATE, &file, NULL); + RD_STATE, &file, NULL, NULL); if (status) { dprintk("NFSD: nfsd4_seek: couldn't process stateid!\n"); return status; diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 618e660..05c0295 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -5187,7 +5187,8 @@ static __be32 nfsd4_validate_stateid(struct nfs4_client *cl, stateid_t *stateid) __be32 nfs4_preprocess_stateid_op(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct svc_fh *fhp, - stateid_t *stateid, int flags, struct file **filpp, bool *tmp_file) + stateid_t *stateid, int flags, struct file **filpp, + bool *tmp_file, struct nfs4_stid **cstid) { struct inode *ino = d_inode(fhp->fh_dentry); struct net *net = SVC_NET(rqstp); @@ -5238,8 +5239,11 @@ static __be32 nfsd4_validate_stateid(struct nfs4_client *cl, stateid_t *stateid) if (!status && filpp) status = nfs4_check_file(rqstp, fhp, s, filpp, tmp_file, flags); out: - if (s) + if (s) { + if (!status && cstid) + *cstid = s; nfs4_put_stid(s); + } return status; } diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h index 0b74d37..5da9cc3 100644 --- a/fs/nfsd/state.h +++ b/fs/nfsd/state.h @@ -607,7 +607,8 @@ struct nfsd4_blocked_lock { extern __be32 nfs4_preprocess_stateid_op(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct svc_fh *fhp, - stateid_t *stateid, int flags, struct file **filp, bool *tmp_file); + stateid_t *stateid, int flags, struct file **filp, + bool *tmp_file, struct nfs4_stid **cstid); __be32 nfsd4_lookup_stateid(struct nfsd4_compound_state *cstate, stateid_t *stateid, unsigned char typemask, struct nfs4_stid **s, struct nfsd_net *nn); From patchwork Mon Jul 8 19:23: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: 11035709 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 0DC4A17EF for ; Mon, 8 Jul 2019 19:23:57 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id F08AD2847B for ; Mon, 8 Jul 2019 19:23:56 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E4D44284D4; Mon, 8 Jul 2019 19:23:56 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id DA9182852A for ; Mon, 8 Jul 2019 19:23:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731545AbfGHTXz (ORCPT ); Mon, 8 Jul 2019 15:23:55 -0400 Received: from mail-io1-f68.google.com ([209.85.166.68]:34430 "EHLO mail-io1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729193AbfGHTXz (ORCPT ); Mon, 8 Jul 2019 15:23:55 -0400 Received: by mail-io1-f68.google.com with SMTP id k8so37940243iot.1 for ; Mon, 08 Jul 2019 12:23:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=EewZApHLc588H4Ea5m+9tmJ+XVi3uZzWMPFUZWyb8T0=; b=pMLNBEgx4hHgK1NRnO5t74x1qMpN+c7fcsvDXS+kkImNcEdfg8zxc6WAWecJXxJwva EtxIOTAeOpM//ZqKUA7/cWZ4U9zs4a8pJ8IMKwD1HKbA73vmG26XQIa5w0osjJJJE/Wo 5RtW7VkLJBGu+jN7+4R2MwvhEKu1mvVPTff0Q6ZSuhpQ6WHlkqRflBkGa3QGm9ZbMd95 pcDWHz15KKgHT/iVDcTKC/nFeNZiuaau3fDP/EHuBwgBzm0ur4ivf8SrGG9+kUuFZ2Ky XzIP/XvC9WtXQE1IeMBaOaS/JPts13PVdJQ/+e40n1UsDHnfjLcS6NmWxJ4w2W1jHszg uJxg== 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=EewZApHLc588H4Ea5m+9tmJ+XVi3uZzWMPFUZWyb8T0=; b=Z6Nomebvn9ngb23WJvNEwuYmc36opOe7vwosUnWnV3dv4rXGT1S3v5FnM0ghvNvPcU hrB0uHUnCjuPYWmP+kGUlZx/UFpE7UPsGrAetgJXsShh6sryF2B4r313PCqE5ov28/QO BqVTxmwa1mGpuWNAZ6Vfz3wreAnC2R7nob4m9kjDcDZ7KnOVcItfUvPfBBYkNfPk2/oc aIJWDRkt/VvYaP56//IginbY1HTpE6KiILofF/B5Z7OhzbSMSrotVBWrkir847IQaRzH gki20RILj4wXrNQQF51TnafZfePkarBtEDdktcUH2VQ34Z8KohRjkJO44vAHA99nsNtO Xn1A== X-Gm-Message-State: APjAAAWS5+V1KIrZAQDmt+1rWd5tol5q6pmsaF73LmR2h4l/kw8CsEQl R/bYgqoJxFHyIOEoaXvQxzw= X-Google-Smtp-Source: APXvYqzD6j0X3koevW3DT76Sft0Y420rpu6lTYJsU/98g2K4PJ4ng6HhfrhLh/WtdGY22EwLcjt8pA== X-Received: by 2002:a5e:8209:: with SMTP id l9mr2451071iom.303.1562613834119; Mon, 08 Jul 2019 12:23:54 -0700 (PDT) Received: from Olgas-MBP-201.attlocal.net (172-10-226-31.lightspeed.livnmi.sbcglobal.net. [172.10.226.31]) by smtp.gmail.com with ESMTPSA id v3sm9212841iom.53.2019.07.08.12.23.53 (version=TLS1 cipher=AES128-SHA bits=128/128); Mon, 08 Jul 2019 12:23:53 -0700 (PDT) From: Olga Kornievskaia To: bfields@redhat.com Cc: linux-nfs@vger.kernel.org Subject: [PATCH v4 4/8] NFSD add COPY_NOTIFY operation Date: Mon, 8 Jul 2019 15:23:48 -0400 Message-Id: <20190708192352.12614-5-olga.kornievskaia@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20190708192352.12614-1-olga.kornievskaia@gmail.com> References: <20190708192352.12614-1-olga.kornievskaia@gmail.com> Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Olga Kornievskaia 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. Keep it in the list associated with parent stateid. Return single netaddr to advertise to the copy. Signed-off-by: Andy Adamson Signed-off-by: Olga Kornievskaia --- fs/nfsd/nfs4proc.c | 71 +++++++++++++++++++++++++++++++++++---- fs/nfsd/nfs4state.c | 64 +++++++++++++++++++++++++++++++---- fs/nfsd/nfs4xdr.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++-- fs/nfsd/state.h | 18 ++++++++-- fs/nfsd/xdr4.h | 13 +++++++ 5 files changed, 247 insertions(+), 16 deletions(-) diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index cfd8767..c39fa72 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" @@ -1033,7 +1034,8 @@ static __be32 nfsd4_do_lookupp(struct svc_rqst *rqstp, struct svc_fh *fh) static __be32 nfsd4_verify_copy(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, stateid_t *src_stateid, struct file **src, - stateid_t *dst_stateid, struct file **dst) + stateid_t *dst_stateid, struct file **dst, + struct nfs4_stid **stid) { __be32 status; @@ -1050,7 +1052,7 @@ static __be32 nfsd4_do_lookupp(struct svc_rqst *rqstp, struct svc_fh *fh) status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->current_fh, dst_stateid, WR_STATE, dst, NULL, - NULL); + stid); if (status) { dprintk("NFSD: %s: couldn't process dst stateid!\n", __func__); goto out_put_src; @@ -1081,7 +1083,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; @@ -1228,7 +1230,7 @@ static void dup_copy_fields(struct nfsd4_copy *src, struct nfsd4_copy *dst) static void cleanup_async_copy(struct nfsd4_copy *copy) { - nfs4_free_cp_state(copy); + nfs4_free_copy_state(copy); fput(copy->file_dst); fput(copy->file_src); spin_lock(©->cp_clp->async_lock); @@ -1268,7 +1270,7 @@ static int nfsd4_do_async_copy(void *data) status = nfsd4_verify_copy(rqstp, cstate, ©->cp_src_stateid, ©->file_src, ©->cp_dst_stateid, - ©->file_dst); + ©->file_dst, NULL); if (status) goto out; @@ -1282,7 +1284,7 @@ static int nfsd4_do_async_copy(void *data) async_copy = kzalloc(sizeof(struct nfsd4_copy), GFP_KERNEL); if (!async_copy) goto out; - if (!nfs4_init_cp_state(nn, copy)) { + if (!nfs4_init_copy_state(nn, copy)) { kfree(async_copy); goto out; } @@ -1346,6 +1348,42 @@ struct nfsd4_copy * } static __be32 +nfsd4_copy_notify(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, + union nfsd4_op_u *u) +{ + 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; + + status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->current_fh, + &cn->cpn_src_stateid, RD_STATE, NULL, + NULL, &stid); + if (status) + return status; + + cn->cpn_sec = nn->nfsd4_lease; + cn->cpn_nsec = 0; + + status = nfserrno(-ENOMEM); + cps = nfs4_alloc_init_cpntf_state(nn, stid); + if (!cps) + return status; + memcpy(&cn->cpn_cnr_stateid, &cps->cp_stateid, sizeof(stateid_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); + + return status; +} + +static __be32 nfsd4_fallocate(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_fallocate *fallocate, int flags) { @@ -2298,6 +2336,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) { @@ -2722,6 +2775,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/nfs4state.c b/fs/nfsd/nfs4state.c index 05c0295..2555eb9 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -707,6 +707,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. @@ -726,24 +727,53 @@ 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, void *ptr, stateid_t *stid) { int new_id; 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, ptr, 0, 0, GFP_NOWAIT); 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; + stid->si_opaque.so_id = new_id; + stid->si_opaque.so_clid.cl_boot = nn->boot_time; + stid->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, copy, ©->cp_stateid); +} + +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; + if (!nfs4_init_cp_state(nn, cps, &cps->cp_stateid)) + goto out_free; + cps->cp_p_stid = p_stid; + cps->cp_active = false; + cps->cp_timeout = jiffies + (nn->nfsd4_lease * HZ); + INIT_LIST_HEAD(&cps->cp_list); + 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; @@ -753,6 +783,27 @@ void nfs4_free_cp_state(struct nfsd4_copy *copy) 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); + + might_sleep(); + + 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); + list_del(&cps->cp_list); + idr_remove(&nn->s2s_cp_stateids, + cps->cp_stateid.si_opaque.so_id); + kfree(cps); + } + spin_unlock(&nn->s2s_cp_lock); +} + static struct nfs4_ol_stateid * nfs4_alloc_open_stateid(struct nfs4_client *clp) { struct nfs4_stid *stid; @@ -901,6 +952,7 @@ static void block_delegations(struct knfsd_fh *fh) } idr_remove(&clp->cl_stateids, s->sc_stateid.si_opaque.so_id); spin_unlock(&clp->cl_lock); + nfs4_free_cpntf_statelist(clp->net, s); s->sc_free(s); if (fp) put_nfs4_file(fp); diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 15f53bb..ed37528 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -1847,6 +1847,22 @@ 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; + status = nfsd4_decode_nl4_server(argp, &cn->cpn_dst); + if (status) + return status; + + return status; +} + +static __be32 nfsd4_decode_seek(struct nfsd4_compoundargs *argp, struct nfsd4_seek *seek) { DECODE_HEAD; @@ -1947,7 +1963,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, @@ -4336,6 +4352,45 @@ 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(ns->nl4_type != NL4_NETADDR); + } + + return 0; +} + +static __be32 nfsd4_encode_copy(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_copy *copy) { @@ -4369,6 +4424,44 @@ 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); + + nfserr = nfsd42_encode_nl4_server(resp, &cn->cpn_src); + if (nfserr) + return nfserr; + + return nfserr; +} + +static __be32 nfsd4_encode_seek(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_seek *seek) { @@ -4465,7 +4558,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/state.h b/fs/nfsd/state.h index 5da9cc3..106ed56 100644 --- a/fs/nfsd/state.h +++ b/fs/nfsd/state.h @@ -95,6 +95,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; @@ -103,6 +104,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 { + stateid_t cp_stateid; + struct list_head cp_list; /* per parent nfs4_stid */ + struct nfs4_stid *cp_p_stid; /* pointer to parent */ + bool cp_active; /* has the copy started */ + unsigned long cp_timeout; /* copy timeout */ +}; + /* * 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 @@ -614,8 +626,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); diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h index 513c9ff..bade8e5 100644 --- a/fs/nfsd/xdr4.h +++ b/fs/nfsd/xdr4.h @@ -568,6 +568,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; @@ -627,6 +639,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 Jul 8 19:23: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: 11035707 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id DC71A112C for ; Mon, 8 Jul 2019 19:23:56 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CA4AF284D4 for ; Mon, 8 Jul 2019 19:23:56 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id BD0E628516; Mon, 8 Jul 2019 19:23:56 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 61A502847B for ; Mon, 8 Jul 2019 19:23:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2391647AbfGHTX4 (ORCPT ); Mon, 8 Jul 2019 15:23:56 -0400 Received: from mail-io1-f65.google.com ([209.85.166.65]:47056 "EHLO mail-io1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729193AbfGHTXz (ORCPT ); Mon, 8 Jul 2019 15:23:55 -0400 Received: by mail-io1-f65.google.com with SMTP id i10so37785006iol.13 for ; Mon, 08 Jul 2019 12:23:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=1DYhl4o2u4Qt+0cLmr6alwIbXlZunWsjLZGLHFbDjDQ=; b=AOXz4f7GVLDHMoI09FZzd6eaga+YYExapPd7Cg6cOsSxvzQiwuvbSVTEAAd3bqUK2r m+sdiSEaFxd4ngHYU0+nlgotVxqhUhzE1pOWvrQ1MVTwJELOUtTWTnhzalXDcAz+y7St /5KgNEaDq5TXzyWw+59F30u1WeRJ4sMqkBeKfCS8GU5zQWEXQVlEAFaNfpbC4TMcHSkA Fo2lhA55d//l3Rlx7ugPhv0c38zVp/gE8xnQHJ5Ca65LlL8Hl+q8y1mM1Lb/H3jD+u/Y YcU/J5IANVB0mx49Tomlw3CGRhKCpHLWdxQbBr6kXu/oHCqJGuch/Au6u8LnInueaCMs Bc9g== 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=1DYhl4o2u4Qt+0cLmr6alwIbXlZunWsjLZGLHFbDjDQ=; b=IHuFSuQa0+rHeNOnYN/H2jTeNLYvBhYeVVYfU3T7XBbghEbEUgo+Z2RSy5SrbQtgjs 8UKJytjEsXc+URyoiRjf69Nncb7KyksYyzRYwkINZQOxyxn34IkTM280lfL67lLpGG4c CPCc5gx9nhmcqNcw2l68Y80cWJL/0F+AOMZovnF8mCM6OvYixPRG3zUAklIuoyhCYlXq OQhCLERm0nPubga4bXTJTEdSmyYKFWZpZggY/MrlC9PrOM9u6s33caquBCJpBgvWQZXv 7ZJIh8BeDgKf8LhMPgv6Iz27okzipAp16LkcT4MSwxGuv0/ZNzvhHS1hh0kP48KRPnrp OApw== X-Gm-Message-State: APjAAAXpm9SAiZsiZ7oBwODoz0WFETLHLznPacTsKuvLgJgKtNgi5ij1 pbnnU12AKhCj/Ama7hSjJ8U= X-Google-Smtp-Source: APXvYqz7otUBYuLx6MMIxaPiZ4LJ2dDznIwYGZBLFTeDYQQqvNNJN/zHmu0Zfsv2I2xWY5LLH1vPZQ== X-Received: by 2002:a6b:c9d8:: with SMTP id z207mr20061886iof.184.1562613835127; Mon, 08 Jul 2019 12:23:55 -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 v3sm9212841iom.53.2019.07.08.12.23.54 (version=TLS1 cipher=AES128-SHA bits=128/128); Mon, 08 Jul 2019 12:23:54 -0700 (PDT) From: Olga Kornievskaia To: bfields@redhat.com Cc: linux-nfs@vger.kernel.org Subject: [PATCH v4 5/8] NFSD check stateids against copy stateids Date: Mon, 8 Jul 2019 15:23:49 -0400 Message-Id: <20190708192352.12614-6-olga.kornievskaia@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20190708192352.12614-1-olga.kornievskaia@gmail.com> References: <20190708192352.12614-1-olga.kornievskaia@gmail.com> Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Incoming stateid (used by a READ) could be a saved copy stateid. On first use make it active and check that the copy has started within the allowable lease time. Signed-off-by: Olga Kornievskaia --- fs/nfsd/nfs4state.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 2555eb9..b786625 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -5232,6 +5232,49 @@ static __be32 nfsd4_validate_stateid(struct nfs4_client *cl, stateid_t *stateid) return 0; } +/* + * A READ from an inter server to server COPY will have a + * copy stateid. Return the parent nfs4_stid. + */ +static __be32 _find_cpntf_state(struct nfsd_net *nn, stateid_t *st, + struct nfs4_cpntf_state **cps) +{ + 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); + state = idr_find(&nn->s2s_cp_stateids, st->si_opaque.so_id); + if (state) + refcount_inc(&state->cp_p_stid->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; + + status = _find_cpntf_state(nn, st, &cps); + if (status) + return status; + + /* Did the inter server to server copy start in time? */ + if (cps->cp_active == false && !time_after(cps->cp_timeout, jiffies)) { + nfs4_put_stid(cps->cp_p_stid); + return nfserr_partner_no_auth; + } else + cps->cp_active = true; + + *stid = cps->cp_p_stid; + + return nfs_ok; +} /* * Checks for stateid operations @@ -5264,6 +5307,8 @@ static __be32 nfsd4_validate_stateid(struct nfs4_client *cl, stateid_t *stateid) 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, From patchwork Mon Jul 8 19:23: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: 11035711 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id F24F0112C for ; Mon, 8 Jul 2019 19:23:57 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id DF7642847B for ; Mon, 8 Jul 2019 19:23:57 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id D29DA28516; Mon, 8 Jul 2019 19:23:57 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7087C2847B for ; Mon, 8 Jul 2019 19:23:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2391646AbfGHTX5 (ORCPT ); Mon, 8 Jul 2019 15:23:57 -0400 Received: from mail-io1-f46.google.com ([209.85.166.46]:42134 "EHLO mail-io1-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729193AbfGHTX4 (ORCPT ); Mon, 8 Jul 2019 15:23:56 -0400 Received: by mail-io1-f46.google.com with SMTP id u19so37818080ior.9 for ; Mon, 08 Jul 2019 12:23:56 -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=VBSbGO+lScidIvOtah0lpAqaf38piEyOCBDn6NrMdtI=; b=rKRZ4hhRE7g2R/LpfQkAiyiWEj/VO+miG9pZ1dYCE45FIgWoOvUq+YogvBU8NNy/H+ jn8pS34UhUNBFUP12AA8KmppKYTxOHIDBIH2s53Ogq3GiklGW5Eyh9D1TLIzWT2RMlRT PVWiKLljlpNPqrQIzLfQEI7DYCshftN6Om1rx8R1mXx+iVIgnTzkdmgTF6oi86sgjhqc 1ygIc4JhSpCM2GbsLLLVGmA5Jw8iDLoeSJ6USkQ02tnkhwPo7wcYmt8daLePBnOeYh3X egbkFLig819cG2188htHfY3cxumNFQB8gB+VRhI+2L2/5jjW3stI4uBTdOiBCLrbRpPL HjeA== 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=VBSbGO+lScidIvOtah0lpAqaf38piEyOCBDn6NrMdtI=; b=fxdUz/Ed7LXrYGSlJ7GF9ufsfhUQtK5Qz7asVDzClO84BLn3Mp777DqqHIuGIKk1cE PieC+Vvr21soYGhrcOxah3toIGjfgI/OlTlPIuollSYDLp6AseaozK42RH2OYzkKaSoS nnqJ1pqQuFUSYC4xb2f4RjFsKxmpNmbbT0ifyX4Hq9KlGEhapc+tSgMwoLg3qb6EPJXx c5Mzqk1wfS823j557sAOxYfSWRKqGo6UMGDbkRc177BjrQCRbQjCejZBKhrqLhhUTtMZ xJTDspzIb6XpKLXsrAxqT6Oek/F5kQmyb7EhsIhCZ9CKVWrMDJ7XqTZSupzZenM6BcFr UCZg== X-Gm-Message-State: APjAAAWEXykuTB3MG4LUvUB0Eu4y9dn3Ozv/pWJhLkgin5QbyH8KUzu2 WIpdM05fbwz7XZitMdIm+pA= X-Google-Smtp-Source: APXvYqwuRgUMlt/5QebFu2DGdiMaefZSh/u4X/w19eoJTPPGC6BDv/7uxz8iz2neAvRj8ZACm2MSmg== X-Received: by 2002:a5e:8913:: with SMTP id k19mr3699980ioj.155.1562613836149; Mon, 08 Jul 2019 12:23: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 v3sm9212841iom.53.2019.07.08.12.23.55 (version=TLS1 cipher=AES128-SHA bits=128/128); Mon, 08 Jul 2019 12:23:55 -0700 (PDT) From: Olga Kornievskaia To: bfields@redhat.com Cc: linux-nfs@vger.kernel.org Subject: [PATCH v4 6/8] NFSD generalize nfsd4_compound_state flag names Date: Mon, 8 Jul 2019 15:23:50 -0400 Message-Id: <20190708192352.12614-7-olga.kornievskaia@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20190708192352.12614-1-olga.kornievskaia@gmail.com> References: <20190708192352.12614-1-olga.kornievskaia@gmail.com> Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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 c39fa72..8c2273e 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 b786625..d7f4b96 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -7466,7 +7466,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)); } @@ -7475,14 +7476,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 bade8e5..9d7318c 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 Jul 8 19:23: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: 11035713 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 39E73112C for ; Mon, 8 Jul 2019 19:23:59 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2AC6228396 for ; Mon, 8 Jul 2019 19:23:59 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 1F2D2284D4; Mon, 8 Jul 2019 19:23:59 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 981BC28396 for ; Mon, 8 Jul 2019 19:23:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2391653AbfGHTX6 (ORCPT ); Mon, 8 Jul 2019 15:23:58 -0400 Received: from mail-io1-f68.google.com ([209.85.166.68]:34440 "EHLO mail-io1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729193AbfGHTX6 (ORCPT ); Mon, 8 Jul 2019 15:23:58 -0400 Received: by mail-io1-f68.google.com with SMTP id k8so37940521iot.1 for ; Mon, 08 Jul 2019 12:23: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=Sknz4OyGK6wIft4IFNA/PN7brpN8OWGiEywebLIHXKQ=; b=Cv3P9G8dbCF50tdkmhmip7B0oGmdrDhDx2Qi2yajF1uWPN6axW26gj5Qtve9pebuSW VgTT9ZrvfL4cZ3yrjtddcUrguOLNmOVac1rVCeP1fLc9ZFZ4OBH7AKn3rSTHO4b+ndg+ gdNq8PbqBpls5VvjVy/FAg+q1kn6Vp/EJUdAWDNM1+ik/8VbtvA5tXNHnwBeN251wQsJ ugmTRGnj2o2l9d1HwA04K6Q27+hPfwWCAEFDJejXEiCcrWLALCgnN27na5CBuBaAWqxe roWHYFA6uq8bnGSREsJR3gX5gyN/UXhb3Prnh5GhKuFJUWeOkaxkdslDrEhx0Jpd4uWv /3XA== 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=Sknz4OyGK6wIft4IFNA/PN7brpN8OWGiEywebLIHXKQ=; b=rPJdXqFGOldyJV3wy+q65HRw4dLB+MvoIFd53NlnOiAIeWNgA891r8Bpq2KueY4viT nOWCRtJTiLEPuX9l25ocoOW5U3Z4PCBlru2p6x2MKlCVRq77HBzRSz3gAQka7OBp4ge4 0V28mtk5EoD4LoWHEPWQGDA6Jp9Az6sHqjhp+eSTwethRHfmTnzd1z6GXtE4WMhhQ4Ze rv5TGI7wo3y7WYesIFnJe5mZ0tyyKZUI8MHH8t6S6afI7F+8g4lH5sBegwmL69D90Cli s8tsyNrUdAg9YIra/R8+pOP7BtDGFJLGJSwrIxLw0dSiqMfnFL3w2NsJkeUsEPm+vxuO gOog== X-Gm-Message-State: APjAAAU/FnFFts/anX5Q1qQNx+Xr6NUb8r7GdDHmv7jaqzmngQsTEBUH l6SUxmA8kbKfyfhS6CM8tXY= X-Google-Smtp-Source: APXvYqzvPt+bDh1ZGykOG8ttYNuPwdYzRhJCQiqnbQdMRLQsT2JJrS02L2KLtUUYCNFXzbgFXXBiTQ== X-Received: by 2002:a5d:88c6:: with SMTP id i6mr10308417iol.107.1562613836857; Mon, 08 Jul 2019 12:23: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 v3sm9212841iom.53.2019.07.08.12.23.56 (version=TLS1 cipher=AES128-SHA bits=128/128); Mon, 08 Jul 2019 12:23:56 -0700 (PDT) From: Olga Kornievskaia To: bfields@redhat.com Cc: linux-nfs@vger.kernel.org Subject: [PATCH v4 7/8] NFSD: allow inter server COPY to have a STALE source server fh Date: Mon, 8 Jul 2019 15:23:51 -0400 Message-Id: <20190708192352.12614-8-olga.kornievskaia@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20190708192352.12614-1-olga.kornievskaia@gmail.com> References: <20190708192352.12614-1-olga.kornievskaia@gmail.com> Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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 | 53 +++++++++++++++++++++++++++++++++++++++++++++++++---- fs/nfsd/nfsfh.h | 5 ++++- fs/nfsd/xdr4.h | 1 + 4 files changed, 64 insertions(+), 5 deletions(-) diff --git a/fs/nfsd/Kconfig b/fs/nfsd/Kconfig index d25f6bb..bef3a58 100644 --- a/fs/nfsd/Kconfig +++ b/fs/nfsd/Kconfig @@ -132,6 +132,16 @@ config NFSD_FLEXFILELAYOUT If unsure, say N. +config NFSD_V4_2_INTER_SSC + bool "NFSv4.2 inter server to server COPY" + depends on NFSD_V4 && NFS_V4_1 && NFS_V4_2 + help + This option enables support for NFSv4.2 inter server to + server copy where the destination server calls the NFSv4.2 + client to read the data to copy from the source server. + + If unsure, say N. + config NFSD_V4_SECURITY_LABEL bool "Provide Security Label support for NFSv4 server" depends on NFSD_V4 && SECURITY diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 8c2273e..1039528 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,41 @@ static void svcxdr_init_encode(struct svc_rqst *rqstp, - rqstp->rq_auth_slack; } +#ifdef CONFIG_NFSD_V4_2_INTER_SSC +static void +check_if_stalefh_allowed(struct nfsd4_compoundargs *args) +{ + struct nfsd4_op *op, *current_op, *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; + putfh = (struct nfsd4_putfh *)&saved_op->u; + if (!copy->cp_intra) + putfh->no_verify = true; + } + } +} +#else +static void +check_if_stalefh_allowed(struct nfsd4_compoundargs *args) +{ +} +#endif + /* * COMPOUND call. */ @@ -2004,6 +2047,7 @@ static void svcxdr_init_encode(struct svc_rqst *rqstp, resp->opcnt = 1; goto encode_op; } + check_if_stalefh_allowed(args); trace_nfsd_compound(rqstp, args->opcnt); while (!status && resp->opcnt < args->opcnt) { @@ -2019,13 +2063,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 9d7318c..fbd18d6 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 Jul 8 19:23: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: 11035715 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id A590C138D for ; Mon, 8 Jul 2019 19:24:00 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9584328396 for ; Mon, 8 Jul 2019 19:24:00 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8A5EC28516; Mon, 8 Jul 2019 19:24:00 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8CE5E28396 for ; Mon, 8 Jul 2019 19:23:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729193AbfGHTX7 (ORCPT ); Mon, 8 Jul 2019 15:23:59 -0400 Received: from mail-io1-f67.google.com ([209.85.166.67]:33521 "EHLO mail-io1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2391648AbfGHTX6 (ORCPT ); Mon, 8 Jul 2019 15:23:58 -0400 Received: by mail-io1-f67.google.com with SMTP id z3so22897859iog.0 for ; Mon, 08 Jul 2019 12:23: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=8sqvMxlp2D+jQ/VXN4IOhBMluKUVq5nSCwQ2e2pASyQ=; b=Yu8WhmRebQ7BTaJ2SPSLQPcJYaZCeGeUbZAXEro9cuRGLGMNeZG5PdYraGc0KthsMV xyrKTg26UXqQMbCoYEB68FlUfGvsgPTLc/gDvePpX5/k6kK7K6sbOAN/ELGbNhuq2Qdw 6ubnaD+EfQm/q87b0loH6S49mFZXDuhjx1g85I2npiCyfdNB0tOc9f1dACBjHzKD/1SL O5As7gjTuKkSvnzLebVbYZ62yVaRHfmOyBWJoyeQ/ThV6scTKR+UsWh+zyvVxMgPUBGM tIWe15XedT0eav3DJYgNS7QnFSM4ZKRXVp+BM+W5FES5bMs0+1juyBlzRRGol4mgKw4I wecQ== 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=8sqvMxlp2D+jQ/VXN4IOhBMluKUVq5nSCwQ2e2pASyQ=; b=ZSmOLtFc17c6t/nMPF09VWp7MF5bmw9xOmKyZiuok7LE0bse9INRANjQJL8Wab/Fy9 wWhWLxO2ZEJM86qiKZVmFu/BIGMOpcjOuAYcAMXuzjLZCHeEMBwylbN3c4yTpUfZlPIq L8IIS+5GW3hK4j5cINJjX6SPUQkWzbz+gLeUH/pg6w6mPS0yNpA7Kcezx7AK7Kv6Ccz3 TFNai2YvBPW0UvyikxhfmlyNTb1X09XnDk2mBeJW8zY/+FQfXv85SKUKtvsnizssDeFz o9zl7+eMTQyKcEz1zTIoMZx8pV0CrHXT357dXGNqQniBcDQiRA6QepfdFVHyc3h5x7mn WAhQ== X-Gm-Message-State: APjAAAVx2a8wukghyUCmE4Y9moXrK/ux8qQBHuEqHUt7qcRpcj3EBPVS eOhQ/nAlHPo2/Kqqo8ol6jc= X-Google-Smtp-Source: APXvYqxfQkYyE/tPUWVCWm+BdB2Gprdyyjb9UfufEMDLIXIjZ7YW3Eu1Ptvt8H+dnFYhHKv73Xy0uQ== X-Received: by 2002:a5d:9d58:: with SMTP id k24mr20395923iok.116.1562613837590; Mon, 08 Jul 2019 12:23: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 v3sm9212841iom.53.2019.07.08.12.23.56 (version=TLS1 cipher=AES128-SHA bits=128/128); Mon, 08 Jul 2019 12:23:57 -0700 (PDT) From: Olga Kornievskaia To: bfields@redhat.com Cc: linux-nfs@vger.kernel.org Subject: [PATCH v4 8/8] NFSD add nfs4 inter ssc to nfsd4_copy Date: Mon, 8 Jul 2019 15:23:52 -0400 Message-Id: <20190708192352.12614-9-olga.kornievskaia@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20190708192352.12614-1-olga.kornievskaia@gmail.com> References: <20190708192352.12614-1-olga.kornievskaia@gmail.com> Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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_enabled". Signed-off-by: Olga Kornievskaia --- fs/nfsd/nfs4proc.c | 291 ++++++++++++++++++++++++++++++++++++++++++++++++---- fs/nfsd/nfs4state.c | 17 ++- fs/nfsd/nfssvc.c | 6 ++ fs/nfsd/state.h | 4 + fs/nfsd/xdr4.h | 5 + 5 files changed, 299 insertions(+), 24 deletions(-) diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 1039528..caf046f 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -1153,6 +1153,209 @@ void nfsd4_shutdown_copy(struct nfs4_client *clp) while ((copy = nfsd4_get_copy(clp)) != NULL) nfsd4_stop_copy(copy); } +#ifdef CONFIG_NFSD_V4_2_INTER_SSC + +extern struct file *nfs42_ssc_open(struct vfsmount *ss_mnt, + struct nfs_fh *src_fh, + nfs4_stateid *stateid); +extern void nfs42_ssc_close(struct file *filep); + +extern void nfs_sb_deactive(struct super_block *sb); + +#define NFSD42_INTERSSC_MOUNTOPS "vers=4.2,addr=%s,sec=sys" + +/** + * Support one copy source server for now. + */ +static __be32 +nfsd4_interssc_connect(struct nl4_server *nss, struct svc_rqst *rqstp, + struct vfsmount **mount) +{ + struct file_system_type *type; + struct vfsmount *ss_mnt; + struct nfs42_netaddr *naddr; + struct sockaddr_storage tmp_addr; + size_t tmp_addrlen, match_netid_len = 3; + char *startsep = "", *endsep = "", *match_netid = "tcp"; + char *ipaddr, *dev_name, *raw_data; + int len, raw_len, status = -EINVAL; + + naddr = &nss->u.nl4_addr; + tmp_addrlen = rpc_uaddr2sockaddr(SVC_NET(rqstp), naddr->addr, + naddr->addr_len, + (struct sockaddr *)&tmp_addr, + sizeof(tmp_addr)); + if (tmp_addrlen == 0) + goto out_err; + + if (tmp_addr.ss_family == AF_INET6) { + startsep = "["; + endsep = "]"; + match_netid = "tcp6"; + match_netid_len = 4; + } + + if (naddr->netid_len != match_netid_len || + strncmp(naddr->netid, match_netid, naddr->netid_len)) + goto out_err; + + /* Construct the raw data for the vfs_kern_mount call */ + len = RPC_MAX_ADDRBUFLEN + 1; + ipaddr = kzalloc(len, GFP_KERNEL); + if (!ipaddr) + goto out_err; + + rpc_ntop((struct sockaddr *)&tmp_addr, ipaddr, len); + + /* 2 for ipv6 endsep and startsep. 3 for ":/" and trailing '/0'*/ + + raw_len = strlen(NFSD42_INTERSSC_MOUNTOPS) + strlen(ipaddr); + raw_data = kzalloc(raw_len, GFP_KERNEL); + if (!raw_data) + goto out_free_ipaddr; + + snprintf(raw_data, raw_len, NFSD42_INTERSSC_MOUNTOPS, ipaddr); + + status = -ENODEV; + type = get_fs_type("nfs"); + if (!type) + goto out_free_rawdata; + + /* Set the server: for the vfs_kern_mount call */ + dev_name = kzalloc(len + 5, GFP_KERNEL); + if (!dev_name) + goto out_free_rawdata; + snprintf(dev_name, len + 5, "%s%s%s:/", startsep, ipaddr, endsep); + + /* Use an 'internal' mount: SB_KERNMOUNT -> MNT_INTERNAL */ + ss_mnt = vfs_kern_mount(type, SB_KERNMOUNT, dev_name, raw_data); + module_put(type->owner); + if (IS_ERR(ss_mnt)) + goto out_free_devname; + + status = 0; + *mount = ss_mnt; + +out_free_devname: + kfree(dev_name); +out_free_rawdata: + kfree(raw_data); +out_free_ipaddr: + kfree(ipaddr); +out_err: + return status; +} + +static void +nfsd4_interssc_disconnect(struct vfsmount *ss_mnt) +{ + nfs_sb_deactive(ss_mnt->mnt_sb); + mntput(ss_mnt); +} + +/** + * nfsd4_setup_inter_ssc + * + * Verify COPY destination stateid. + * Connect to the source server with NFSv4.1. + * Create the source struct file for nfsd_copy_range. + * Called with COPY cstate: + * SAVED_FH: source filehandle + * CURRENT_FH: destination filehandle + * + * Returns errno (not nfserrxxx) + */ +static __be32 +nfsd4_setup_inter_ssc(struct svc_rqst *rqstp, + struct nfsd4_compound_state *cstate, + struct nfsd4_copy *copy, struct vfsmount **mount) +{ + struct svc_fh *s_fh = NULL; + stateid_t *s_stid = ©->cp_src_stateid; + __be32 status = -EINVAL; + + /* Verify the destination stateid and set dst struct file*/ + status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->current_fh, + ©->cp_dst_stateid, + WR_STATE, ©->file_dst, NULL, + NULL); + if (status) + goto out; + + status = nfsd4_interssc_connect(©->cp_src, rqstp, mount); + if (status) + goto out; + + s_fh = &cstate->save_fh; + + copy->c_fh.size = s_fh->fh_handle.fh_size; + memcpy(copy->c_fh.data, &s_fh->fh_handle.fh_base, copy->c_fh.size); + copy->stateid.seqid = s_stid->si_generation; + memcpy(copy->stateid.other, (void *)&s_stid->si_opaque, + sizeof(stateid_opaque_t)); + + status = 0; +out: + return status; +} + +static void +nfsd4_cleanup_inter_ssc(struct vfsmount *ss_mnt, struct file *src, + struct file *dst) +{ + nfs42_ssc_close(src); + fput(src); + fput(dst); + mntput(ss_mnt); +} + +#else /* CONFIG_NFSD_V4_2_INTER_SSC */ + +static __be32 +nfsd4_setup_inter_ssc(struct svc_rqst *rqstp, + struct nfsd4_compound_state *cstate, + struct nfsd4_copy *copy, + struct vfsmount **mount) +{ + *mount = NULL; + return -EINVAL; +} + +static void +nfsd4_cleanup_inter_ssc(struct vfsmount *ss_mnt, struct file *src, + struct file *dst) +{ +} + +static void +nfsd4_interssc_disconnect(struct vfsmount *ss_mnt) +{ +} + +static struct file *nfs42_ssc_open(struct vfsmount *ss_mnt, + struct nfs_fh *src_fh, + nfs4_stateid *stateid) +{ + return NULL; +} +#endif /* CONFIG_NFSD_V4_2_INTER_SSC */ + +static __be32 +nfsd4_setup_intra_ssc(struct svc_rqst *rqstp, + struct nfsd4_compound_state *cstate, + struct nfsd4_copy *copy) +{ + return nfsd4_verify_copy(rqstp, cstate, ©->cp_src_stateid, + ©->file_src, ©->cp_dst_stateid, + ©->file_dst, NULL); +} + +static void +nfsd4_cleanup_intra_ssc(struct file *src, struct file *dst) +{ + fput(src); + fput(dst); +} static void nfsd4_cb_offload_release(struct nfsd4_callback *cb) { @@ -1217,12 +1420,16 @@ static __be32 nfsd4_do_copy(struct nfsd4_copy *copy, bool sync) status = nfs_ok; } - fput(copy->file_src); - fput(copy->file_dst); + if (!copy->cp_intra) /* Inter server SSC */ + nfsd4_cleanup_inter_ssc(copy->ss_mnt, copy->file_src, + copy->file_dst); + else + nfsd4_cleanup_intra_ssc(copy->file_src, copy->file_dst); + return status; } -static void dup_copy_fields(struct nfsd4_copy *src, struct nfsd4_copy *dst) +static int dup_copy_fields(struct nfsd4_copy *src, struct nfsd4_copy *dst) { dst->cp_src_pos = src->cp_src_pos; dst->cp_dst_pos = src->cp_dst_pos; @@ -1232,8 +1439,17 @@ static void dup_copy_fields(struct nfsd4_copy *src, struct nfsd4_copy *dst) memcpy(&dst->fh, &src->fh, sizeof(src->fh)); dst->cp_clp = src->cp_clp; dst->file_dst = get_file(src->file_dst); - dst->file_src = get_file(src->file_src); + dst->cp_intra = src->cp_intra; + if (src->cp_intra) /* for inter, file_src doesn't exist yet */ + dst->file_src = get_file(src->file_src); memcpy(&dst->cp_stateid, &src->cp_stateid, sizeof(src->cp_stateid)); + memcpy(&dst->cp_src, &src->cp_src, sizeof(struct nl4_server)); + memcpy(&dst->stateid, &src->stateid, sizeof(src->stateid)); + memcpy(&dst->c_fh, &src->c_fh, sizeof(src->c_fh)); + dst->ss_mnt = src->ss_mnt; + + return 0; + } static void cleanup_async_copy(struct nfsd4_copy *copy) @@ -1252,7 +1468,18 @@ static int nfsd4_do_async_copy(void *data) struct nfsd4_copy *copy = (struct nfsd4_copy *)data; struct nfsd4_copy *cb_copy; + if (!copy->cp_intra) { /* Inter server SSC */ + copy->file_src = nfs42_ssc_open(copy->ss_mnt, ©->c_fh, + ©->stateid); + if (IS_ERR(copy->file_src)) { + copy->nfserr = nfserr_offload_denied; + nfsd4_interssc_disconnect(copy->ss_mnt); + goto do_callback; + } + } + copy->nfserr = nfsd4_do_copy(copy, 0); +do_callback: cb_copy = kzalloc(sizeof(struct nfsd4_copy), GFP_KERNEL); if (!cb_copy) goto out; @@ -1276,11 +1503,20 @@ static int nfsd4_do_async_copy(void *data) __be32 status; struct nfsd4_copy *async_copy = NULL; - status = nfsd4_verify_copy(rqstp, cstate, ©->cp_src_stateid, - ©->file_src, ©->cp_dst_stateid, - ©->file_dst, NULL); - if (status) - goto out; + if (!copy->cp_intra) { /* Inter server SSC */ + if (!inter_copy_offload_enable || copy->cp_synchronous) { + status = nfserr_notsupp; + goto out; + } + status = nfsd4_setup_inter_ssc(rqstp, cstate, copy, + ©->ss_mnt); + if (status) + return nfserr_offload_denied; + } else { + status = nfsd4_setup_intra_ssc(rqstp, cstate, copy); + if (status) + return status; + } copy->cp_clp = cstate->clp; memcpy(©->fh, &cstate->current_fh.fh_handle, @@ -1291,15 +1527,15 @@ static int nfsd4_do_async_copy(void *data) status = nfserrno(-ENOMEM); async_copy = kzalloc(sizeof(struct nfsd4_copy), GFP_KERNEL); if (!async_copy) - goto out; - if (!nfs4_init_copy_state(nn, copy)) { - kfree(async_copy); - goto out; - } + goto out_err; + if (!nfs4_init_copy_state(nn, copy)) + goto out_err; refcount_set(&async_copy->refcount, 1); memcpy(©->cp_res.cb_stateid, ©->cp_stateid, sizeof(copy->cp_stateid)); - dup_copy_fields(copy, async_copy); + status = dup_copy_fields(copy, async_copy); + if (status) + goto out_err; async_copy->copy_task = kthread_create(nfsd4_do_async_copy, async_copy, "%s", "copy thread"); if (IS_ERR(async_copy->copy_task)) @@ -1310,13 +1546,17 @@ 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); - goto out; + status = nfserrno(-ENOMEM); + if (!copy->cp_intra) + nfsd4_interssc_disconnect(copy->ss_mnt); + goto out_err; } struct nfsd4_copy * @@ -1342,15 +1582,24 @@ struct nfsd4_copy * union nfsd4_op_u *u) { struct nfsd4_offload_status *os = &u->offload_status; - __be32 status = 0; + __be32 status = nfserr_bad_stateid; struct nfsd4_copy *copy; struct nfs4_client *clp = cstate->clp; + struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id); copy = find_async_copy(clp, &os->stateid); - if (copy) + if (!copy) { + struct nfs4_cpntf_state *cps = NULL; + + status = find_internal_cpntf_state(nn, &os->stateid, &cps); + if (status) + return status; + if (cps) { + free_cpntf_state(nn, &os->stateid, cps); + return nfs_ok; + } + } else nfsd4_stop_copy(copy); - else - status = nfserr_bad_stateid; return status; } diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index d7f4b96..c1a0695 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -5232,12 +5232,23 @@ static __be32 nfsd4_validate_stateid(struct nfs4_client *cl, stateid_t *stateid) return 0; } +void free_cpntf_state(struct nfsd_net *nn, stateid_t *st, + struct nfs4_cpntf_state *cps) +{ + spin_lock(&nn->s2s_cp_lock); + list_del(&cps->cp_list); + idr_remove(&nn->s2s_cp_stateids, cps->cp_stateid.si_opaque.so_id); + nfs4_put_stid(cps->cp_p_stid); + kfree(cps); + spin_unlock(&nn->s2s_cp_lock); +} + /* * A READ from an inter server to server COPY will have a * copy stateid. Return the parent nfs4_stid. */ -static __be32 _find_cpntf_state(struct nfsd_net *nn, stateid_t *st, - struct nfs4_cpntf_state **cps) +__be32 find_internal_cpntf_state(struct nfsd_net *nn, stateid_t *st, + struct nfs4_cpntf_state **cps) { struct nfs4_cpntf_state *state = NULL; @@ -5260,7 +5271,7 @@ static __be32 find_cpntf_state(struct nfsd_net *nn, stateid_t *st, __be32 status; struct nfs4_cpntf_state *cps = NULL; - status = _find_cpntf_state(nn, st, &cps); + status = find_internal_cpntf_state(nn, st, &cps); if (status) return status; diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c index 18d94ea..033bfcb 100644 --- a/fs/nfsd/nfssvc.c +++ b/fs/nfsd/nfssvc.c @@ -30,6 +30,12 @@ #define NFSDDBG_FACILITY NFSDDBG_SVC +bool inter_copy_offload_enable; +EXPORT_SYMBOL_GPL(inter_copy_offload_enable); +module_param(inter_copy_offload_enable, bool, 0644); +MODULE_PARM_DESC(inter_copy_offload_enable, + "Enable inter server to server copy offload. Default: false"); + extern struct svc_program nfsd_program; static int nfsd(void *vrqstp); #if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h index 106ed56..7026e2a 100644 --- a/fs/nfsd/state.h +++ b/fs/nfsd/state.h @@ -659,6 +659,10 @@ 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 __be32 find_internal_cpntf_state(struct nfsd_net *nn, stateid_t *st, + struct nfs4_cpntf_state **cps); +extern void free_cpntf_state(struct nfsd_net *nn, stateid_t *st, + 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 fbd18d6..bb2f8e5 100644 --- a/fs/nfsd/xdr4.h +++ b/fs/nfsd/xdr4.h @@ -547,7 +547,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 */