From patchwork Fri Sep 4 17:29:38 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andy Adamson X-Patchwork-Id: 7125271 Return-Path: X-Original-To: patchwork-linux-nfs@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id CD1669F695 for ; Fri, 4 Sep 2015 17:30:19 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 7A33320842 for ; Fri, 4 Sep 2015 17:30:17 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 6EB91208A8 for ; Fri, 4 Sep 2015 17:30:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932892AbbIDRaJ (ORCPT ); Fri, 4 Sep 2015 13:30:09 -0400 Received: from mx144.netapp.com ([216.240.21.25]:6800 "EHLO mx144.netapp.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932689AbbIDRaI (ORCPT ); Fri, 4 Sep 2015 13:30:08 -0400 X-IronPort-AV: E=Sophos;i="5.17,470,1437462000"; d="scan'208";a="66200164" Received: from vmwexchts03-prd.hq.netapp.com ([10.122.105.31]) by mx144-out.netapp.com with ESMTP; 04 Sep 2015 10:30:07 -0700 Received: from smtp2.corp.netapp.com (10.57.159.114) by VMWEXCHTS03-PRD.hq.netapp.com (10.122.105.31) with Microsoft SMTP Server id 15.0.1076.9; Fri, 4 Sep 2015 10:30:07 -0700 Received: from rhel7-1-snap3.localdomain (dros-16.vpn.netapp.com [10.55.64.65]) by smtp2.corp.netapp.com (8.13.1/8.13.1/NTAP-1.6) with ESMTP id t84HTqKY021957; Fri, 4 Sep 2015 10:30:06 -0700 (PDT) From: To: CC: , , , Olga Kornievskaia Subject: [PATCH Version 2 16/16] NFSD: extra stateid checking in read for interserver copy Date: Fri, 4 Sep 2015 13:29:38 -0400 Message-ID: <1441387778-16465-17-git-send-email-andros@netapp.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1441387778-16465-1-git-send-email-andros@netapp.com> References: <1441387778-16465-1-git-send-email-andros@netapp.com> MIME-Version: 1.0 Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Olga Kornievskaia Expand stateid structure to store a mark signifying this stateid is a COPY stateid and special to pass stateid check on READ operation coming from a different clientid. In COPY_NOTIFY, mark the stateid stored under the clientid as 'special' by setting boolean is_copy field to true. If we received a READ and check for the stateid fails, we need to look for the stateid under all other clientid structures and their corresponding stateid lists. Make sure the stateid was previously marked for use READ from a COPY operation. Signed-off-by: Olga Kornievskaia --- fs/nfsd/nfs4proc.c | 15 ++++++++++++++- fs/nfsd/nfs4state.c | 30 +++++++++++++++++++++++------- fs/nfsd/state.h | 8 ++++++++ 3 files changed, 45 insertions(+), 8 deletions(-) diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 4d3b37d..27677f2 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -1398,6 +1398,7 @@ nfsd4_copy_notify(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct file *src = NULL; struct nfs42_netaddr *naddr; struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id); + struct nfs4_stid *stid = NULL; status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->current_fh, @@ -1412,7 +1413,19 @@ nfsd4_copy_notify(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, * connections from the destination e.g. what is returned in cpn_src, * to verify READ from dest server. */ - + /* mark the original open stateid special */ + status = nfserr_bad_stateid; + stid = find_stateid_by_type(cstate->session->se_client, + &cp_notify->cpn_src_stateid, NFS4_DELEG_STID|NFS4_OPEN_STID| + NFS4_LOCK_STID); + if (stid) { + /* cnp_src_stateid is used for reply cnr_stateid */ + stid->is_copy = 1; + nfs4_put_stid(stid); + } else { + dprintk("NFSD: %s can't find cpn_src_stateid\n", __func__); + goto out; + } /** * For now, only return one source server address, the address used * by the client in the static cpn_src. diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 96de0d3..3f7e849 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -1809,12 +1809,6 @@ same_verf(nfs4_verifier *v1, nfs4_verifier *v2) return 0 == memcmp(v1->data, v2->data, sizeof(v1->data)); } -static int -same_clid(clientid_t *cl1, clientid_t *cl2) -{ - return (cl1->cl_boot == cl2->cl_boot) && (cl1->cl_id == cl2->cl_id); -} - static bool groups_equal(struct group_info *g1, struct group_info *g2) { int i; @@ -1916,7 +1910,7 @@ find_stateid_locked(struct nfs4_client *cl, stateid_t *t) return ret; } -static struct nfs4_stid * +struct nfs4_stid * find_stateid_by_type(struct nfs4_client *cl, stateid_t *t, char typemask) { struct nfs4_stid *s; @@ -4670,6 +4664,28 @@ nfs4_preprocess_stateid_op(struct svc_rqst *rqstp, status = nfsd4_lookup_stateid(cstate, stateid, NFS4_DELEG_STID|NFS4_OPEN_STID|NFS4_LOCK_STID, &s, nn); + if (status == nfserr_bad_stateid) { + /** if clientid in rd_stateid is different from current, + * find corresponding clientid and look for stateid there + */ + struct nfs4_client *clp = NULL; + + spin_lock(&nn->client_lock); + list_for_each_entry(clp, &nn->client_lru, cl_lru) { + if (same_clid(&clp->cl_clientid, + &stateid->si_opaque.so_clid)) { + + s = find_stateid_by_type(clp, stateid, + NFS4_DELEG_STID|NFS4_OPEN_STID| + NFS4_LOCK_STID); + if (s && s->is_copy) + dprintk("%s COPY stateid\n", __func__); + status = nfs_ok; + break; + } + } + spin_unlock(&nn->client_lock); + } if (status) return status; status = check_stateid_generation(stateid, &s->sc_stateid, diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h index d3e81ce..5c98514 100644 --- a/fs/nfsd/state.h +++ b/fs/nfsd/state.h @@ -94,6 +94,7 @@ struct nfs4_stid { #define NFS4_REVOKED_DELEG_STID 16 #define NFS4_CLOSED_DELEG_STID 32 #define NFS4_LAYOUT_STID 64 + bool is_copy; unsigned char sc_type; stateid_t sc_stateid; struct nfs4_client *sc_client; @@ -583,6 +584,13 @@ enum nfsd4_cb_op { struct nfsd4_compound_state; struct nfsd_net; +static inline int same_clid(clientid_t *cl1, clientid_t *cl2) +{ + return (cl1->cl_boot == cl2->cl_boot) && (cl1->cl_id == cl2->cl_id); +} + +extern struct nfs4_stid *find_stateid_by_type(struct nfs4_client *cl, + stateid_t *t, char typemask); 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);