linux-nfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jeff Layton <jlayton@primarydata.com>
To: bfields@fieldses.org
Cc: linux-nfs@vger.kernel.org, hch@infradead.org,
	Trond Myklebust <trond.myklebust@primarydata.com>
Subject: [PATCH 05/37] nfsd: Protect unconfirmed client creation using client_lock
Date: Wed, 30 Jul 2014 08:27:06 -0400	[thread overview]
Message-ID: <1406723258-8512-6-git-send-email-jlayton@primarydata.com> (raw)
In-Reply-To: <1406723258-8512-1-git-send-email-jlayton@primarydata.com>

From: Trond Myklebust <trond.myklebust@primarydata.com>

...instead of relying on the client_mutex.

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
---
 fs/nfsd/nfs4state.c | 33 ++++++++++++++++++++++-----------
 1 file changed, 22 insertions(+), 11 deletions(-)

diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 4b42cb95e315..f149e30475db 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -1923,7 +1923,7 @@ add_to_unconfirmed(struct nfs4_client *clp)
 	add_clp_to_name_tree(clp, &nn->unconf_name_tree);
 	idhashval = clientid_hashval(clp->cl_clientid.cl_id);
 	list_add(&clp->cl_idhash, &nn->unconf_id_hashtbl[idhashval]);
-	renew_client(clp);
+	renew_client_locked(clp);
 }
 
 static void
@@ -1937,7 +1937,7 @@ move_to_confirmed(struct nfs4_client *clp)
 	rb_erase(&clp->cl_namenode, &nn->unconf_name_tree);
 	add_clp_to_name_tree(clp, &nn->conf_name_tree);
 	set_bit(NFSD4_CLIENT_CONFIRMED, &clp->cl_flags);
-	renew_client(clp);
+	renew_client_locked(clp);
 }
 
 static struct nfs4_client *
@@ -1950,7 +1950,7 @@ find_client_in_id_table(struct list_head *tbl, clientid_t *clid, bool sessions)
 		if (same_clid(&clp->cl_clientid, clid)) {
 			if ((bool)clp->cl_minorversion != sessions)
 				return NULL;
-			renew_client(clp);
+			renew_client_locked(clp);
 			return clp;
 		}
 	}
@@ -2152,7 +2152,8 @@ nfsd4_exchange_id(struct svc_rqst *rqstp,
 		  struct nfsd4_compound_state *cstate,
 		  struct nfsd4_exchange_id *exid)
 {
-	struct nfs4_client *unconf, *conf, *new;
+	struct nfs4_client *conf, *new;
+	struct nfs4_client *unconf = NULL;
 	__be32 status;
 	char			addr_str[INET6_ADDRSTRLEN];
 	nfs4_verifier		verf = exid->verifier;
@@ -2187,6 +2188,7 @@ nfsd4_exchange_id(struct svc_rqst *rqstp,
 
 	/* Cases below refer to rfc 5661 section 18.35.4: */
 	nfs4_lock_state();
+	spin_lock(&nn->client_lock);
 	conf = find_confirmed_client_by_name(&exid->clname, nn);
 	if (conf) {
 		bool creds_match = same_creds(&conf->cl_cred, &rqstp->rq_cred);
@@ -2218,7 +2220,6 @@ nfsd4_exchange_id(struct svc_rqst *rqstp,
 				status = nfserr_clid_inuse;
 				goto out;
 			}
-			expire_client(conf);
 			goto out_new;
 		}
 		if (verfs_match) { /* case 2 */
@@ -2226,6 +2227,7 @@ nfsd4_exchange_id(struct svc_rqst *rqstp,
 			goto out_copy;
 		}
 		/* case 5, client reboot */
+		conf = NULL;
 		goto out_new;
 	}
 
@@ -2236,17 +2238,18 @@ nfsd4_exchange_id(struct svc_rqst *rqstp,
 
 	unconf  = find_unconfirmed_client_by_name(&exid->clname, nn);
 	if (unconf) /* case 4, possible retry or client restart */
-		expire_client(unconf);
+		unhash_client_locked(unconf);
 
 	/* case 1 (normal case) */
 out_new:
+	if (conf)
+		unhash_client_locked(conf);
 	new->cl_minorversion = cstate->minorversion;
 	new->cl_mach_cred = (exid->spa_how == SP4_MACH_CRED);
 
 	gen_clid(new, nn);
 	add_to_unconfirmed(new);
-	conf = new;
-	new = NULL;
+	swap(new, conf);
 out_copy:
 	exid->clientid.cl_boot = conf->cl_clientid.cl_boot;
 	exid->clientid.cl_id = conf->cl_clientid.cl_id;
@@ -2259,9 +2262,12 @@ out_copy:
 	status = nfs_ok;
 
 out:
+	spin_unlock(&nn->client_lock);
 	nfs4_unlock_state();
 	if (new)
-		free_client(new);
+		expire_client(new);
+	if (unconf)
+		expire_client(unconf);
 	return status;
 }
 
@@ -2900,7 +2906,8 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 {
 	struct xdr_netobj 	clname = setclid->se_name;
 	nfs4_verifier		clverifier = setclid->se_verf;
-	struct nfs4_client	*conf, *unconf, *new;
+	struct nfs4_client	*conf, *new;
+	struct nfs4_client	*unconf = NULL;
 	__be32 			status;
 	struct nfsd_net		*nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
 
@@ -2909,6 +2916,7 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 		return nfserr_jukebox;
 	/* Cases below refer to rfc 3530 section 14.2.33: */
 	nfs4_lock_state();
+	spin_lock(&nn->client_lock);
 	conf = find_confirmed_client_by_name(&clname, nn);
 	if (conf) {
 		/* case 0: */
@@ -2926,7 +2934,7 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 	}
 	unconf = find_unconfirmed_client_by_name(&clname, nn);
 	if (unconf)
-		expire_client(unconf);
+		unhash_client_locked(unconf);
 	if (conf && same_verf(&conf->cl_verifier, &clverifier))
 		/* case 1: probable callback update */
 		copy_clid(new, conf);
@@ -2941,9 +2949,12 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 	new = NULL;
 	status = nfs_ok;
 out:
+	spin_unlock(&nn->client_lock);
 	nfs4_unlock_state();
 	if (new)
 		free_client(new);
+	if (unconf)
+		expire_client(unconf);
 	return status;
 }
 
-- 
1.9.3


  parent reply	other threads:[~2014-07-30 12:27 UTC|newest]

Thread overview: 47+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-07-30 12:27 [PATCH 00/37] nfsd: remaining client_mutex removal patches Jeff Layton
2014-07-30 12:27 ` [PATCH 01/37] nfsd: Ensure struct nfs4_client is unhashed before we try to destroy it Jeff Layton
2014-07-30 12:27 ` [PATCH 02/37] nfsd: Ensure that the laundromat unhashes the client before releasing locks Jeff Layton
2014-07-30 12:27 ` [PATCH 03/37] nfsd: Don't require client_lock in free_client Jeff Layton
2014-07-30 12:27 ` [PATCH 04/37] nfsd: Move create_client() call outside the lock Jeff Layton
2014-07-30 12:27 ` Jeff Layton [this message]
2014-07-30 12:27 ` [PATCH 06/37] nfsd: Protect session creation and client confirm using client_lock Jeff Layton
2014-07-30 12:27 ` [PATCH 07/37] nfsd: Protect nfsd4_destroy_clientid " Jeff Layton
2014-07-30 12:27 ` [PATCH 08/37] nfsd: Ensure lookup_clientid() takes client_lock Jeff Layton
2014-07-30 12:27 ` [PATCH 09/37] nfsd: Add lockdep assertions to document the nfs4_client/session locking Jeff Layton
2014-08-04 21:18   ` J. Bruce Fields
2014-07-30 12:27 ` [PATCH 10/37] nfsd: protect the close_lru list and oo_last_closed_stid with client_lock Jeff Layton
2014-07-30 12:27 ` [PATCH 11/37] nfsd: move unhash_client_locked call into mark_client_expired_locked Jeff Layton
2014-07-30 12:27 ` [PATCH 12/37] nfsd: don't destroy client if mark_client_expired_locked fails Jeff Layton
2014-07-30 12:27 ` [PATCH 13/37] nfsd: don't destroy clients that are busy Jeff Layton
2014-07-30 12:27 ` [PATCH 14/37] nfsd: protect clid and verifier generation with client_lock Jeff Layton
2014-07-30 12:27 ` [PATCH 15/37] nfsd: abstract out the get and set routines into the fault injection ops Jeff Layton
2014-07-30 12:27 ` [PATCH 16/37] nfsd: add a forget_clients "get" routine with proper locking Jeff Layton
2014-07-30 12:27 ` [PATCH 17/37] nfsd: add a forget_client set_clnt routine Jeff Layton
2014-07-30 12:27 ` [PATCH 18/37] nfsd: add nfsd_inject_forget_clients Jeff Layton
2014-07-30 12:27 ` [PATCH 19/37] nfsd: add a list_head arg to nfsd_foreach_client_lock Jeff Layton
2014-07-30 12:27 ` [PATCH 20/37] nfsd: add more granular locking to forget_locks fault injector Jeff Layton
2014-07-30 12:27 ` [PATCH 21/37] nfsd: add more granular locking to forget_openowners " Jeff Layton
2014-07-30 12:27 ` [PATCH 22/37] nfsd: add more granular locking to *_delegations fault injectors Jeff Layton
2014-07-30 12:27 ` [PATCH 23/37] nfsd: remove old fault injection infrastructure Jeff Layton
2014-07-30 12:27 ` [PATCH 24/37] nfsd: Remove nfs4_lock_state(): nfs4_preprocess_stateid_op() Jeff Layton
2014-07-30 12:27 ` [PATCH 25/37] nfsd: Remove nfs4_lock_state(): nfsd4_test_stateid/nfsd4_free_stateid Jeff Layton
2014-07-30 12:27 ` [PATCH 26/37] nfsd: Remove nfs4_lock_state(): nfsd4_release_lockowner Jeff Layton
2014-07-30 12:27 ` [PATCH 27/37] nfsd: Remove nfs4_lock_state(): nfsd4_lock/locku/lockt() Jeff Layton
2014-07-30 12:27 ` [PATCH 28/37] nfsd: Remove nfs4_lock_state(): nfsd4_open_downgrade + nfsd4_close Jeff Layton
2014-07-30 12:27 ` [PATCH 29/37] nfsd: Remove nfs4_lock_state(): nfsd4_delegreturn() Jeff Layton
2014-07-30 12:27 ` [PATCH 30/37] nfsd: Remove nfs4_lock_state(): nfsd4_open and nfsd4_open_confirm Jeff Layton
2014-07-30 12:27 ` [PATCH 31/37] nfsd: Remove nfs4_lock_state(): exchange_id, create/destroy_session() Jeff Layton
2014-07-30 12:27 ` [PATCH 32/37] nfsd: Remove nfs4_lock_state(): setclientid, setclientid_confirm, renew Jeff Layton
2014-07-30 12:27 ` [PATCH 33/37] nfsd: Remove nfs4_lock_state(): reclaim_complete() Jeff Layton
2014-07-30 12:27 ` [PATCH 34/37] nfsd: remove nfs4_lock_state: nfs4_laundromat Jeff Layton
2014-07-30 12:27 ` [PATCH 35/37] nfsd: remove nfs4_lock_state: nfs4_state_shutdown_net Jeff Layton
2014-07-30 12:27 ` [PATCH 36/37] nfsd: remove the client_mutex and the nfs4_lock/unlock_state wrappers Jeff Layton
2014-08-01 11:20   ` Jeff Layton
2014-08-05 19:08     ` J. Bruce Fields
2014-07-30 12:27 ` [PATCH 37/37] nfsd: add some comments to the nfsd4 object definitions Jeff Layton
2014-08-05 15:36   ` J. Bruce Fields
2014-08-05 17:01     ` Jeff Layton
2014-08-05 18:56       ` J. Bruce Fields
2014-08-05 19:13   ` [PATCH v2] " Jeff Layton
2014-08-05 20:29     ` J. Bruce Fields
2014-08-01 20:48 ` [PATCH 00/37] nfsd: remaining client_mutex removal patches J. Bruce Fields

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1406723258-8512-6-git-send-email-jlayton@primarydata.com \
    --to=jlayton@primarydata.com \
    --cc=bfields@fieldses.org \
    --cc=hch@infradead.org \
    --cc=linux-nfs@vger.kernel.org \
    --cc=trond.myklebust@primarydata.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).