From patchwork Mon Jun 30 15:48:44 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff Layton X-Patchwork-Id: 4451221 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.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id BA3EC9F358 for ; Mon, 30 Jun 2014 15:51:01 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id B707620375 for ; Mon, 30 Jun 2014 15:51:00 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 7E82220380 for ; Mon, 30 Jun 2014 15:50:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754565AbaF3Pu4 (ORCPT ); Mon, 30 Jun 2014 11:50:56 -0400 Received: from mail-qa0-f53.google.com ([209.85.216.53]:36070 "EHLO mail-qa0-f53.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754563AbaF3Puy (ORCPT ); Mon, 30 Jun 2014 11:50:54 -0400 Received: by mail-qa0-f53.google.com with SMTP id j15so6669123qaq.12 for ; Mon, 30 Jun 2014 08:50:53 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=CjmwsNZS3X1DzSGNOjcqGpZvtHWat5xepmfhXdQEby8=; b=Jyt4roDr23kp7rCThgr/E6KH/XRRvW9VMsmSKdl2OnxfNT+LbW7d+LVtUkPc0SD3Al o1ac8tlxs5Z5GRc1tTcDl0ukIBnYGUIm3jNPX88rN0PEAEo+xHyconhZnwPYbyVqVQKT KIf0yl/3HFnszJhq7YEb9CbQzbm8Ih3EWvbjJmTgW4PNpVJgUpFXqzMWizAvHuoRKFtg tRg3kWl1oFUCvCZyuQRhOBUT0kSwSkzGAiOJN9gvvs2nC61X9kUr8g6GJ6FPsG3jzfNr 4rmwjTW6WRT0x2VKj1AP0TaEQtIykn+zO/LzN20F3bUEdV2B+Twrxh/iasQ9GD9WEjY9 SXEw== X-Gm-Message-State: ALoCoQlW+6eGQo5sK0jGhcDWRwBkNksFCTIexd8UMSa6uQ0nQ1UfCUY/85Ls93eugvSZqEtynVSc X-Received: by 10.229.90.196 with SMTP id j4mr2242789qcm.11.1404143453636; Mon, 30 Jun 2014 08:50:53 -0700 (PDT) Received: from tlielax.poochiereds.net ([2001:470:8:d63:3a60:77ff:fe93:a95d]) by mx.google.com with ESMTPSA id m1sm32584105qaz.27.2014.06.30.08.50.52 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 30 Jun 2014 08:50:52 -0700 (PDT) From: Jeff Layton To: bfields@fieldses.org Cc: linux-nfs@vger.kernel.org Subject: [PATCH v3 015/114] nfsd: Allow struct nfsd4_compound_state to cache the nfs4_client Date: Mon, 30 Jun 2014 11:48:44 -0400 Message-Id: <1404143423-24381-16-git-send-email-jlayton@primarydata.com> X-Mailer: git-send-email 1.9.3 In-Reply-To: <1404143423-24381-1-git-send-email-jlayton@primarydata.com> References: <1404143423-24381-1-git-send-email-jlayton@primarydata.com> 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, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=ham 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 We want to use the nfsd4_compound_state to cache the nfs4_client in order to optimise away extra lookups of the clid. In the v4.0 case, we use this to ensure that we only have to look up the client at most once per compound for each call into lookup_clientid. For v4.1+ we set the pointer in the cstate during SEQUENCE processing so we should never need to do a search for it. Signed-off-by: Trond Myklebust Reviewed-by: Christoph Hellwig --- fs/nfsd/nfs4state.c | 74 +++++++++++++++++++++++++++++++++++++---------------- fs/nfsd/xdr4.h | 1 + 2 files changed, 53 insertions(+), 22 deletions(-) diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index e9bb39ecebae..4d162a0e4c6d 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -189,6 +189,15 @@ static void put_client_renew_locked(struct nfs4_client *clp) renew_client_locked(clp); } +static void put_client_renew(struct nfs4_client *clp) +{ + struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id); + + spin_lock(&nn->client_lock); + put_client_renew_locked(clp); + spin_unlock(&nn->client_lock); +} + static __be32 nfsd4_get_session_locked(struct nfsd4_session *ses) { __be32 status; @@ -2395,6 +2404,7 @@ nfsd4_sequence(struct svc_rqst *rqstp, goto out_put_session; cstate->slot = slot; cstate->session = session; + cstate->clp = clp; /* Return the cached reply status and set cstate->status * for nfsd4_proc_compound processing */ status = nfsd4_replay_cache_entry(resp, seq); @@ -2429,6 +2439,7 @@ nfsd4_sequence(struct svc_rqst *rqstp, cstate->slot = slot; cstate->session = session; + cstate->clp = clp; out: switch (clp->cl_cb_state) { @@ -2465,7 +2476,8 @@ nfsd4_sequence_done(struct nfsd4_compoundres *resp) } /* Drop session reference that was taken in nfsd4_sequence() */ nfsd4_put_session(cs->session); - } + } else if (cs->clp) + put_client_renew(cs->clp); } __be32 @@ -2997,6 +3009,38 @@ static __be32 nfsd4_check_seqid(struct nfsd4_compound_state *cstate, struct nfs4 return nfserr_bad_seqid; } +static __be32 lookup_clientid(clientid_t *clid, + struct nfsd4_compound_state *cstate, + struct nfsd_net *nn) +{ + struct nfs4_client *found; + + if (cstate->clp) { + found = cstate->clp; + if (!same_clid(&found->cl_clientid, clid)) + return nfserr_stale_clientid; + return nfs_ok; + } + + if (STALE_CLIENTID(clid, nn)) + return nfserr_stale_clientid; + + /* + * For v4.1+ we get the client in the SEQUENCE op. If we don't have one + * cached already then we know this is for is for v4.0 and "sessions" + * will be false. + */ + WARN_ON_ONCE(cstate->session); + found = find_confirmed_client(clid, false, nn); + if (!found) + return nfserr_expired; + + /* Cache the nfs4_client in cstate! */ + cstate->clp = found; + atomic_inc(&found->cl_refcount); + return nfs_ok; +} + __be32 nfsd4_process_open1(struct nfsd4_compound_state *cstate, struct nfsd4_open *open, struct nfsd_net *nn) @@ -3509,18 +3553,6 @@ void nfsd4_cleanup_open_state(struct nfsd4_open *open, __be32 status) free_generic_stateid(open->op_stp); } -static __be32 lookup_clientid(clientid_t *clid, bool session, struct nfsd_net *nn, struct nfs4_client **clp) -{ - struct nfs4_client *found; - - if (STALE_CLIENTID(clid, nn)) - return nfserr_stale_clientid; - found = find_confirmed_client(clid, session, nn); - if (clp) - *clp = found; - return found ? nfs_ok : nfserr_expired; -} - __be32 nfsd4_renew(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, clientid_t *clid) @@ -3532,9 +3564,10 @@ nfsd4_renew(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, nfs4_lock_state(); dprintk("process_renew(%08x/%08x): starting\n", clid->cl_boot, clid->cl_id); - status = lookup_clientid(clid, cstate->minorversion, nn, &clp); + status = lookup_clientid(clid, cstate, nn); if (status) goto out; + clp = cstate->clp; status = nfserr_cb_path_down; if (!list_empty(&clp->cl_delegations) && clp->cl_cb_state != NFSD4_CB_UP) @@ -3797,22 +3830,19 @@ nfsd4_lookup_stateid(struct nfsd4_compound_state *cstate, stateid_t *stateid, unsigned char typemask, struct nfs4_stid **s, struct nfsd_net *nn) { - struct nfs4_client *cl; __be32 status; - bool sessions = cstate->minorversion != 0; if (ZERO_STATEID(stateid) || ONE_STATEID(stateid)) return nfserr_bad_stateid; - status = lookup_clientid(&stateid->si_opaque.so_clid, sessions, - nn, &cl); + status = lookup_clientid(&stateid->si_opaque.so_clid, cstate, nn); if (status == nfserr_stale_clientid) { - if (sessions) + if (cstate->session) return nfserr_bad_stateid; return nfserr_stale_stateid; } if (status) return status; - *s = find_stateid_by_type(cl, stateid, typemask); + *s = find_stateid_by_type(cstate->clp, stateid, typemask); if (!*s) return nfserr_bad_stateid; return nfs_ok; @@ -4662,7 +4692,7 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, nfs4_lock_state(); if (!nfsd4_has_session(cstate)) { - status = lookup_clientid(&lockt->lt_clientid, false, nn, NULL); + status = lookup_clientid(&lockt->lt_clientid, cstate, nn); if (status) goto out; } @@ -4831,7 +4861,7 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp, nfs4_lock_state(); - status = lookup_clientid(clid, cstate->minorversion, nn, NULL); + status = lookup_clientid(clid, cstate, nn); if (status) goto out; diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h index 7d8af164523b..312f6483a48e 100644 --- a/fs/nfsd/xdr4.h +++ b/fs/nfsd/xdr4.h @@ -55,6 +55,7 @@ struct nfsd4_compound_state { struct svc_fh current_fh; struct svc_fh save_fh; struct nfs4_stateowner *replay_owner; + struct nfs4_client *clp; /* For sessions DRC */ struct nfsd4_session *session; struct nfsd4_slot *slot;