Skip to content

Commit 5ec094c

Browse files
author
J. Bruce Fields
committed
nfsd4: extend state lock over seqid replay logic
There are currently a couple races in the seqid replay code: a retransmission could come while we're still encoding the original reply, or a new seqid-mutating call could come as we're encoding a replay. So, extend the state lock over the encoding (both encoding of a replayed reply and caching of the original encoded reply). I really hate doing this, and previously added the stateowner reference-counting code to avoid it (which was insufficient)--but I don't see a less complicated alternative at the moment. Signed-off-by: J. Bruce Fields <[email protected]>
1 parent 9072d5c commit 5ec094c

File tree

2 files changed

+11
-6
lines changed

2 files changed

+11
-6
lines changed

fs/nfsd/nfs4proc.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -408,8 +408,8 @@ nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
408408
if (open->op_stateowner) {
409409
nfs4_get_stateowner(open->op_stateowner);
410410
cstate->replay_owner = open->op_stateowner;
411-
}
412-
nfs4_unlock_state();
411+
} else
412+
nfs4_unlock_state();
413413
return status;
414414
}
415415

@@ -1227,6 +1227,7 @@ nfsd4_proc_compound(struct svc_rqst *rqstp,
12271227
be32_to_cpu(status));
12281228

12291229
if (cstate->replay_owner) {
1230+
nfs4_unlock_state();
12301231
nfs4_put_stateowner(cstate->replay_owner);
12311232
cstate->replay_owner = NULL;
12321233
}

fs/nfsd/nfs4state.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3501,7 +3501,8 @@ nfsd4_open_confirm(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
35013501

35023502
nfsd4_create_clid_dir(sop->so_client);
35033503
out:
3504-
nfs4_unlock_state();
3504+
if (!cstate->replay_owner)
3505+
nfs4_unlock_state();
35053506
return status;
35063507
}
35073508

@@ -3568,7 +3569,8 @@ nfsd4_open_downgrade(struct svc_rqst *rqstp,
35683569
memcpy(&od->od_stateid, &stp->st_stateid, sizeof(stateid_t));
35693570
status = nfs_ok;
35703571
out:
3571-
nfs4_unlock_state();
3572+
if (!cstate->replay_owner)
3573+
nfs4_unlock_state();
35723574
return status;
35733575
}
35743576

@@ -3609,7 +3611,8 @@ nfsd4_close(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
36093611
if (list_empty(&so->so_stateids))
36103612
move_to_close_lru(so);
36113613
out:
3612-
nfs4_unlock_state();
3614+
if (!cstate->replay_owner)
3615+
nfs4_unlock_state();
36133616
return status;
36143617
}
36153618

@@ -4071,7 +4074,8 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
40714074
out:
40724075
if (status && lock->lk_is_new && lock_sop)
40734076
release_lockowner(lock_sop);
4074-
nfs4_unlock_state();
4077+
if (!cstate->replay_owner)
4078+
nfs4_unlock_state();
40754079
return status;
40764080
}
40774081

0 commit comments

Comments
 (0)