aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd/nfs4state.c
diff options
context:
space:
mode:
authorJ. Bruce Fields <bfields@redhat.com>2011-09-06 15:19:46 -0400
committerJ. Bruce Fields <bfields@redhat.com>2011-09-13 18:27:35 -0400
commitc0a5d93efbbb79117bdf7f5f81fba9d679c35dfa (patch)
tree64b16c9c11fce73e3be9e64c6188fc8ad7f280dc /fs/nfsd/nfs4state.c
parent4d71ab8751c1d749f9fdf84ec094989adf579493 (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.c87
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
3420static __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
3429static __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)) { 3469static __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);