aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd/nfs4state.c
diff options
context:
space:
mode:
authorJeff Layton <jlayton@redhat.com>2012-03-21 09:52:02 -0400
committerJ. Bruce Fields <bfields@redhat.com>2012-03-26 11:49:47 -0400
commita52d726bbd928164609e6abc4dc967e819dbf09c (patch)
tree604df65589a95311ab297f80ce377e82525ce597 /fs/nfsd/nfs4state.c
parent1df00640c9111c881633d9b219f18e66c52599ec (diff)
nfsd: convert nfs4_client->cl_cb_flags to a generic flags field
We'll need a way to flag the nfs4_client as already being recorded on stable storage so that we don't continually upcall. Currently, that's recorded in the cl_firststate field of the client struct. Using an entire u32 to store a flag is rather wasteful though. The cl_cb_flags field is only using 2 bits right now, so repurpose that to a generic flags field. Rename NFSD4_CLIENT_KILL to NFSD4_CLIENT_CB_KILL to make it evident that it's part of the callback flags. Add a mask that we can use for existing checks that look to see whether any flags are set, so that the new flags don't interfere. Convert all references to cl_firstate to the NFSD4_CLIENT_STABLE flag, and add a new NFSD4_CLIENT_RECLAIM_COMPLETE flag. Signed-off-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'fs/nfsd/nfs4state.c')
-rw-r--r--fs/nfsd/nfs4state.c45
1 files changed, 28 insertions, 17 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index a0a2b535b0e0..8be612abd0d7 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -2069,7 +2069,8 @@ nfsd4_reclaim_complete(struct svc_rqst *rqstp, struct nfsd4_compound_state *csta
2069 2069
2070 nfs4_lock_state(); 2070 nfs4_lock_state();
2071 status = nfserr_complete_already; 2071 status = nfserr_complete_already;
2072 if (cstate->session->se_client->cl_firststate) 2072 if (test_and_set_bit(NFSD4_CLIENT_RECLAIM_COMPLETE,
2073 &cstate->session->se_client->cl_flags))
2073 goto out; 2074 goto out;
2074 2075
2075 status = nfserr_stale_clientid; 2076 status = nfserr_stale_clientid;
@@ -2816,12 +2817,6 @@ static void
2816nfs4_set_claim_prev(struct nfsd4_open *open, bool has_session) 2817nfs4_set_claim_prev(struct nfsd4_open *open, bool has_session)
2817{ 2818{
2818 open->op_openowner->oo_flags |= NFS4_OO_CONFIRMED; 2819 open->op_openowner->oo_flags |= NFS4_OO_CONFIRMED;
2819 /*
2820 * On a 4.1+ client, we don't create a state record for a client
2821 * until it performs RECLAIM_COMPLETE:
2822 */
2823 if (!has_session)
2824 open->op_openowner->oo_owner.so_client->cl_firststate = 1;
2825} 2820}
2826 2821
2827/* Should we give out recallable state?: */ 2822/* Should we give out recallable state?: */
@@ -4462,7 +4457,7 @@ nfs4_has_reclaimed_state(const char *name, bool use_exchange_id)
4462 clp = find_confirmed_client_by_str(name, strhashval); 4457 clp = find_confirmed_client_by_str(name, strhashval);
4463 if (!clp) 4458 if (!clp)
4464 return 0; 4459 return 0;
4465 return clp->cl_firststate; 4460 return test_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags);
4466} 4461}
4467 4462
4468/* 4463/*
@@ -4507,18 +4502,11 @@ nfs4_release_reclaim(void)
4507/* 4502/*
4508 * called from OPEN, CLAIM_PREVIOUS with a new clientid. */ 4503 * called from OPEN, CLAIM_PREVIOUS with a new clientid. */
4509static struct nfs4_client_reclaim * 4504static struct nfs4_client_reclaim *
4510nfs4_find_reclaim_client(clientid_t *clid) 4505nfsd4_find_reclaim_client(struct nfs4_client *clp)
4511{ 4506{
4512 unsigned int strhashval; 4507 unsigned int strhashval;
4513 struct nfs4_client *clp;
4514 struct nfs4_client_reclaim *crp = NULL; 4508 struct nfs4_client_reclaim *crp = NULL;
4515 4509
4516
4517 /* find clientid in conf_id_hashtbl */
4518 clp = find_confirmed_client(clid);
4519 if (clp == NULL)
4520 return NULL;
4521
4522 dprintk("NFSD: nfs4_find_reclaim_client for %.*s with recdir %s\n", 4510 dprintk("NFSD: nfs4_find_reclaim_client for %.*s with recdir %s\n",
4523 clp->cl_name.len, clp->cl_name.data, 4511 clp->cl_name.len, clp->cl_name.data,
4524 clp->cl_recdir); 4512 clp->cl_recdir);
@@ -4533,13 +4521,36 @@ nfs4_find_reclaim_client(clientid_t *clid)
4533 return NULL; 4521 return NULL;
4534} 4522}
4535 4523
4524static int
4525nfsd4_client_record_check(struct nfs4_client *clp)
4526{
4527 /* did we already find that this client is stable? */
4528 if (test_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags))
4529 return 0;
4530
4531 /* look for it in the reclaim hashtable otherwise */
4532 if (nfsd4_find_reclaim_client(clp)) {
4533 set_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags);
4534 return 0;
4535 }
4536
4537 return -ENOENT;
4538}
4539
4536/* 4540/*
4537* Called from OPEN. Look for clientid in reclaim list. 4541* Called from OPEN. Look for clientid in reclaim list.
4538*/ 4542*/
4539__be32 4543__be32
4540nfs4_check_open_reclaim(clientid_t *clid) 4544nfs4_check_open_reclaim(clientid_t *clid)
4541{ 4545{
4542 return nfs4_find_reclaim_client(clid) ? nfs_ok : nfserr_reclaim_bad; 4546 struct nfs4_client *clp;
4547
4548 /* find clientid in conf_id_hashtbl */
4549 clp = find_confirmed_client(clid);
4550 if (clp == NULL)
4551 return nfserr_reclaim_bad;
4552
4553 return nfsd4_client_record_check(clp) ? nfserr_reclaim_bad : nfs_ok;
4543} 4554}
4544 4555
4545#ifdef CONFIG_NFSD_FAULT_INJECTION 4556#ifdef CONFIG_NFSD_FAULT_INJECTION