diff options
author | Jeff Layton <jlayton@redhat.com> | 2012-03-21 09:52:02 -0400 |
---|---|---|
committer | J. Bruce Fields <bfields@redhat.com> | 2012-03-26 11:49:47 -0400 |
commit | a52d726bbd928164609e6abc4dc967e819dbf09c (patch) | |
tree | 604df65589a95311ab297f80ce377e82525ce597 /fs/nfsd/nfs4state.c | |
parent | 1df00640c9111c881633d9b219f18e66c52599ec (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.c | 45 |
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 | |||
2816 | nfs4_set_claim_prev(struct nfsd4_open *open, bool has_session) | 2817 | nfs4_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. */ |
4509 | static struct nfs4_client_reclaim * | 4504 | static struct nfs4_client_reclaim * |
4510 | nfs4_find_reclaim_client(clientid_t *clid) | 4505 | nfsd4_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 | ||
4524 | static int | ||
4525 | nfsd4_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 |
4540 | nfs4_check_open_reclaim(clientid_t *clid) | 4544 | nfs4_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 |