diff options
author | J. Bruce Fields <bfields@redhat.com> | 2011-09-06 15:19:46 -0400 |
---|---|---|
committer | J. Bruce Fields <bfields@redhat.com> | 2011-09-13 18:27:35 -0400 |
commit | c0a5d93efbbb79117bdf7f5f81fba9d679c35dfa (patch) | |
tree | 64b16c9c11fce73e3be9e64c6188fc8ad7f280dc /fs/nfsd/nfs4state.c | |
parent | 4d71ab8751c1d749f9fdf84ec094989adf579493 (diff) |
nfsd4: split preprocess_seqid, cleanup
Move most of this into helper functions. Also move the non-CONFIRM case
into caller, providing a helper function for that purpose.
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'fs/nfsd/nfs4state.c')
-rw-r--r-- | fs/nfsd/nfs4state.c | 87 |
1 files changed, 45 insertions, 42 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index aa088bc3b169..ad20bbf0a1f8 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
@@ -3253,7 +3253,6 @@ __be32 nfs4_validate_stateid(stateid_t *stateid, bool has_session) | |||
3253 | if (!stp) | 3253 | if (!stp) |
3254 | goto out; | 3254 | goto out; |
3255 | status = nfserr_bad_stateid; | 3255 | status = nfserr_bad_stateid; |
3256 | |||
3257 | if (stp->st_stateowner->so_is_open_owner | 3256 | if (stp->st_stateowner->so_is_open_owner |
3258 | && !openowner(stp->st_stateowner)->oo_confirmed) | 3257 | && !openowner(stp->st_stateowner)->oo_confirmed) |
3259 | goto out; | 3258 | goto out; |
@@ -3418,6 +3417,29 @@ setlkflg (int type) | |||
3418 | RD_STATE : WR_STATE; | 3417 | RD_STATE : WR_STATE; |
3419 | } | 3418 | } |
3420 | 3419 | ||
3420 | static __be32 nfs4_nospecial_stateid_checks(stateid_t *stateid) | ||
3421 | { | ||
3422 | if (ZERO_STATEID(stateid) || ONE_STATEID(stateid)) | ||
3423 | return nfserr_bad_stateid; | ||
3424 | if (STALE_STATEID(stateid)) | ||
3425 | return nfserr_stale_stateid; | ||
3426 | return nfs_ok; | ||
3427 | } | ||
3428 | |||
3429 | static __be32 nfs4_seqid_op_checks(struct nfsd4_compound_state *cstate, stateid_t *stateid, u32 seqid, struct nfs4_stateid *stp) | ||
3430 | { | ||
3431 | struct svc_fh *current_fh = &cstate->current_fh; | ||
3432 | struct nfs4_stateowner *sop = stp->st_stateowner; | ||
3433 | __be32 status; | ||
3434 | |||
3435 | if (nfs4_check_fh(current_fh, stp)) | ||
3436 | return nfserr_bad_stateid; | ||
3437 | status = nfsd4_check_seqid(cstate, sop, seqid); | ||
3438 | if (status) | ||
3439 | return status; | ||
3440 | return check_stateid_generation(stateid, &stp->st_stateid, nfsd4_has_session(cstate)); | ||
3441 | } | ||
3442 | |||
3421 | /* | 3443 | /* |
3422 | * Checks for sequence id mutating operations. | 3444 | * Checks for sequence id mutating operations. |
3423 | */ | 3445 | */ |
@@ -3426,54 +3448,36 @@ nfs4_preprocess_seqid_op(struct nfsd4_compound_state *cstate, u32 seqid, | |||
3426 | stateid_t *stateid, int flags, | 3448 | stateid_t *stateid, int flags, |
3427 | struct nfs4_stateid **stpp) | 3449 | struct nfs4_stateid **stpp) |
3428 | { | 3450 | { |
3429 | struct nfs4_stateowner *sop; | ||
3430 | struct svc_fh *current_fh = &cstate->current_fh; | ||
3431 | __be32 status; | 3451 | __be32 status; |
3432 | 3452 | ||
3433 | dprintk("NFSD: %s: seqid=%d stateid = " STATEID_FMT "\n", __func__, | 3453 | dprintk("NFSD: %s: seqid=%d stateid = " STATEID_FMT "\n", __func__, |
3434 | seqid, STATEID_VAL(stateid)); | 3454 | seqid, STATEID_VAL(stateid)); |
3435 | 3455 | ||
3436 | *stpp = NULL; | 3456 | *stpp = NULL; |
3437 | 3457 | status = nfs4_nospecial_stateid_checks(stateid); | |
3438 | if (ZERO_STATEID(stateid) || ONE_STATEID(stateid)) { | 3458 | if (status) |
3439 | dprintk("NFSD: preprocess_seqid_op: magic stateid!\n"); | 3459 | return status; |
3440 | return nfserr_bad_stateid; | ||
3441 | } | ||
3442 | |||
3443 | if (STALE_STATEID(stateid)) | ||
3444 | return nfserr_stale_stateid; | ||
3445 | |||
3446 | /* | ||
3447 | * We return BAD_STATEID if filehandle doesn't match stateid, | ||
3448 | * the confirmed flag is incorrecly set, or the generation | ||
3449 | * number is incorrect. | ||
3450 | */ | ||
3451 | *stpp = find_stateid_by_type(stateid, flags); | 3460 | *stpp = find_stateid_by_type(stateid, flags); |
3452 | if (*stpp == NULL) | 3461 | if (*stpp == NULL) |
3453 | return nfserr_expired; | 3462 | return nfserr_expired; |
3463 | cstate->replay_owner = (*stpp)->st_stateowner; | ||
3464 | renew_client((*stpp)->st_stateowner->so_client); | ||
3454 | 3465 | ||
3455 | sop = (*stpp)->st_stateowner; | 3466 | return nfs4_seqid_op_checks(cstate, stateid, seqid, *stpp); |
3456 | cstate->replay_owner = sop; | 3467 | } |
3457 | 3468 | ||
3458 | if (nfs4_check_fh(current_fh, *stpp)) { | 3469 | static __be32 nfs4_preprocess_confirmed_seqid_op(struct nfsd4_compound_state *cstate, u32 seqid, stateid_t *stateid, struct nfs4_stateid **stpp) |
3459 | dprintk("NFSD: preprocess_seqid_op: fh-stateid mismatch!\n"); | 3470 | { |
3460 | return nfserr_bad_stateid; | 3471 | __be32 status; |
3461 | } | 3472 | struct nfs4_openowner *oo; |
3462 | 3473 | ||
3463 | status = nfsd4_check_seqid(cstate, sop, seqid); | 3474 | status = nfs4_preprocess_seqid_op(cstate, seqid, stateid, |
3475 | OPEN_STATE, stpp); | ||
3464 | if (status) | 3476 | if (status) |
3465 | return status; | 3477 | return status; |
3466 | 3478 | oo = openowner((*stpp)->st_stateowner); | |
3467 | if (sop->so_is_open_owner && !openowner(sop)->oo_confirmed | 3479 | if (!oo->oo_confirmed) |
3468 | && !(flags & CONFIRM)) { | ||
3469 | dprintk("NFSD: preprocess_seqid_op: stateowner not" | ||
3470 | " confirmed yet!\n"); | ||
3471 | return nfserr_bad_stateid; | 3480 | return nfserr_bad_stateid; |
3472 | } | ||
3473 | status = check_stateid_generation(stateid, &(*stpp)->st_stateid, nfsd4_has_session(cstate)); | ||
3474 | if (status) | ||
3475 | return status; | ||
3476 | renew_client(sop->so_client); | ||
3477 | return nfs_ok; | 3481 | return nfs_ok; |
3478 | } | 3482 | } |
3479 | 3483 | ||
@@ -3497,7 +3501,7 @@ nfsd4_open_confirm(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
3497 | 3501 | ||
3498 | status = nfs4_preprocess_seqid_op(cstate, | 3502 | status = nfs4_preprocess_seqid_op(cstate, |
3499 | oc->oc_seqid, &oc->oc_req_stateid, | 3503 | oc->oc_seqid, &oc->oc_req_stateid, |
3500 | CONFIRM | OPEN_STATE, &stp); | 3504 | OPEN_STATE, &stp); |
3501 | if (status) | 3505 | if (status) |
3502 | goto out; | 3506 | goto out; |
3503 | oo = openowner(stp->st_stateowner); | 3507 | oo = openowner(stp->st_stateowner); |
@@ -3557,8 +3561,8 @@ nfsd4_open_downgrade(struct svc_rqst *rqstp, | |||
3557 | return nfserr_inval; | 3561 | return nfserr_inval; |
3558 | 3562 | ||
3559 | nfs4_lock_state(); | 3563 | nfs4_lock_state(); |
3560 | status = nfs4_preprocess_seqid_op(cstate, od->od_seqid, | 3564 | status = nfs4_preprocess_confirmed_seqid_op(cstate, od->od_seqid, |
3561 | &od->od_stateid, OPEN_STATE, &stp); | 3565 | &od->od_stateid, &stp); |
3562 | if (status) | 3566 | if (status) |
3563 | goto out; | 3567 | goto out; |
3564 | status = nfserr_inval; | 3568 | status = nfserr_inval; |
@@ -3602,9 +3606,8 @@ nfsd4_close(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
3602 | 3606 | ||
3603 | nfs4_lock_state(); | 3607 | nfs4_lock_state(); |
3604 | /* check close_lru for replay */ | 3608 | /* check close_lru for replay */ |
3605 | status = nfs4_preprocess_seqid_op(cstate, close->cl_seqid, | 3609 | status = nfs4_preprocess_confirmed_seqid_op(cstate, close->cl_seqid, |
3606 | &close->cl_stateid, | 3610 | &close->cl_stateid, &stp); |
3607 | OPEN_STATE, &stp); | ||
3608 | if (stp == NULL && status == nfserr_expired) { | 3611 | if (stp == NULL && status == nfserr_expired) { |
3609 | /* | 3612 | /* |
3610 | * Also, we should make sure this isn't just the result of | 3613 | * Also, we should make sure this isn't just the result of |
@@ -3963,10 +3966,10 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
3963 | goto out; | 3966 | goto out; |
3964 | 3967 | ||
3965 | /* validate and update open stateid and open seqid */ | 3968 | /* validate and update open stateid and open seqid */ |
3966 | status = nfs4_preprocess_seqid_op(cstate, | 3969 | status = nfs4_preprocess_confirmed_seqid_op(cstate, |
3967 | lock->lk_new_open_seqid, | 3970 | lock->lk_new_open_seqid, |
3968 | &lock->lk_new_open_stateid, | 3971 | &lock->lk_new_open_stateid, |
3969 | OPEN_STATE, &open_stp); | 3972 | &open_stp); |
3970 | if (status) | 3973 | if (status) |
3971 | goto out; | 3974 | goto out; |
3972 | open_sop = openowner(open_stp->st_stateowner); | 3975 | open_sop = openowner(open_stp->st_stateowner); |