diff options
Diffstat (limited to 'fs/nfsd/nfs4state.c')
-rw-r--r-- | fs/nfsd/nfs4state.c | 41 |
1 files changed, 21 insertions, 20 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index a47bf884726f..8edc9ad63ea6 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
@@ -2456,6 +2456,16 @@ static const struct lock_manager_operations nfsd_lease_mng_ops = { | |||
2456 | .lm_change = nfsd_change_deleg_cb, | 2456 | .lm_change = nfsd_change_deleg_cb, |
2457 | }; | 2457 | }; |
2458 | 2458 | ||
2459 | static __be32 nfsd4_check_seqid(struct nfsd4_compound_state *cstate, struct nfs4_stateowner *so, u32 seqid) | ||
2460 | { | ||
2461 | if (nfsd4_has_session(cstate)) | ||
2462 | return nfs_ok; | ||
2463 | if (seqid == so->so_seqid - 1) | ||
2464 | return nfserr_replay_me; | ||
2465 | if (seqid == so->so_seqid) | ||
2466 | return nfs_ok; | ||
2467 | return nfserr_bad_seqid; | ||
2468 | } | ||
2459 | 2469 | ||
2460 | __be32 | 2470 | __be32 |
2461 | nfsd4_process_open1(struct nfsd4_compound_state *cstate, | 2471 | nfsd4_process_open1(struct nfsd4_compound_state *cstate, |
@@ -2465,6 +2475,7 @@ nfsd4_process_open1(struct nfsd4_compound_state *cstate, | |||
2465 | struct nfs4_client *clp = NULL; | 2475 | struct nfs4_client *clp = NULL; |
2466 | unsigned int strhashval; | 2476 | unsigned int strhashval; |
2467 | struct nfs4_stateowner *sop = NULL; | 2477 | struct nfs4_stateowner *sop = NULL; |
2478 | __be32 status; | ||
2468 | 2479 | ||
2469 | if (!check_name(open->op_owner)) | 2480 | if (!check_name(open->op_owner)) |
2470 | return nfserr_inval; | 2481 | return nfserr_inval; |
@@ -2482,9 +2493,6 @@ nfsd4_process_open1(struct nfsd4_compound_state *cstate, | |||
2482 | return nfserr_expired; | 2493 | return nfserr_expired; |
2483 | goto renew; | 2494 | goto renew; |
2484 | } | 2495 | } |
2485 | /* When sessions are used, skip open sequenceid processing */ | ||
2486 | if (nfsd4_has_session(cstate)) | ||
2487 | goto renew; | ||
2488 | if (!sop->so_confirmed) { | 2496 | if (!sop->so_confirmed) { |
2489 | /* Replace unconfirmed owners without checking for replay. */ | 2497 | /* Replace unconfirmed owners without checking for replay. */ |
2490 | clp = sop->so_client; | 2498 | clp = sop->so_client; |
@@ -2492,10 +2500,9 @@ nfsd4_process_open1(struct nfsd4_compound_state *cstate, | |||
2492 | open->op_stateowner = NULL; | 2500 | open->op_stateowner = NULL; |
2493 | goto renew; | 2501 | goto renew; |
2494 | } | 2502 | } |
2495 | if (open->op_seqid == sop->so_seqid - 1) | 2503 | status = nfsd4_check_seqid(cstate, sop, open->op_seqid); |
2496 | return nfserr_replay_me; | 2504 | if (status) |
2497 | if (open->op_seqid != sop->so_seqid) | 2505 | return status; |
2498 | return nfserr_bad_seqid; | ||
2499 | renew: | 2506 | renew: |
2500 | if (open->op_stateowner == NULL) { | 2507 | if (open->op_stateowner == NULL) { |
2501 | sop = alloc_init_open_stateowner(strhashval, clp, open); | 2508 | sop = alloc_init_open_stateowner(strhashval, clp, open); |
@@ -3411,7 +3418,10 @@ nfs4_preprocess_seqid_op(struct nfsd4_compound_state *cstate, u32 seqid, | |||
3411 | if (sop == NULL) | 3418 | if (sop == NULL) |
3412 | return nfserr_expired; | 3419 | return nfserr_expired; |
3413 | cstate->replay_owner = sop; | 3420 | cstate->replay_owner = sop; |
3414 | goto check_replay; | 3421 | status = nfsd4_check_seqid(cstate, sop, seqid); |
3422 | if (status) | ||
3423 | return status; | ||
3424 | return nfserr_bad_seqid; | ||
3415 | } | 3425 | } |
3416 | 3426 | ||
3417 | *stpp = stp; | 3427 | *stpp = stp; |
@@ -3423,8 +3433,9 @@ nfs4_preprocess_seqid_op(struct nfsd4_compound_state *cstate, u32 seqid, | |||
3423 | return nfserr_bad_stateid; | 3433 | return nfserr_bad_stateid; |
3424 | } | 3434 | } |
3425 | 3435 | ||
3426 | if (!nfsd4_has_session(cstate) && seqid != sop->so_seqid) | 3436 | status = nfsd4_check_seqid(cstate, sop, seqid); |
3427 | goto check_replay; | 3437 | if (status) |
3438 | return status; | ||
3428 | 3439 | ||
3429 | if (sop->so_confirmed && flags & CONFIRM) { | 3440 | if (sop->so_confirmed && flags & CONFIRM) { |
3430 | dprintk("NFSD: preprocess_seqid_op: expected" | 3441 | dprintk("NFSD: preprocess_seqid_op: expected" |
@@ -3441,16 +3452,6 @@ nfs4_preprocess_seqid_op(struct nfsd4_compound_state *cstate, u32 seqid, | |||
3441 | return status; | 3452 | return status; |
3442 | renew_client(sop->so_client); | 3453 | renew_client(sop->so_client); |
3443 | return nfs_ok; | 3454 | return nfs_ok; |
3444 | |||
3445 | check_replay: | ||
3446 | if (seqid == sop->so_seqid - 1) { | ||
3447 | dprintk("NFSD: preprocess_seqid_op: retransmission?\n"); | ||
3448 | /* indicate replay to calling function */ | ||
3449 | return nfserr_replay_me; | ||
3450 | } | ||
3451 | dprintk("NFSD: preprocess_seqid_op: bad seqid (expected %d, got %d)\n", | ||
3452 | sop->so_seqid, seqid); | ||
3453 | return nfserr_bad_seqid; | ||
3454 | } | 3455 | } |
3455 | 3456 | ||
3456 | __be32 | 3457 | __be32 |