aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/nfsd/nfs4state.c40
1 files changed, 14 insertions, 26 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 7694fb8aae35..67e03b5d0d83 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -1988,14 +1988,11 @@ laundromat_main(void *not_used)
1988 queue_delayed_work(laundry_wq, &laundromat_work, t*HZ); 1988 queue_delayed_work(laundry_wq, &laundromat_work, t*HZ);
1989} 1989}
1990 1990
1991/* search ownerid_hashtbl[] and close_lru for stateid owner
1992 * (stateid->si_stateownerid)
1993 */
1994static struct nfs4_stateowner * 1991static struct nfs4_stateowner *
1995find_openstateowner_id(u32 st_id, int flags) { 1992search_close_lru(u32 st_id, int flags)
1993{
1996 struct nfs4_stateowner *local = NULL; 1994 struct nfs4_stateowner *local = NULL;
1997 1995
1998 dprintk("NFSD: find_openstateowner_id %d\n", st_id);
1999 if (flags & CLOSE_STATE) { 1996 if (flags & CLOSE_STATE) {
2000 list_for_each_entry(local, &close_lru, so_close_lru) { 1997 list_for_each_entry(local, &close_lru, so_close_lru) {
2001 if (local->so_id == st_id) 1998 if (local->so_id == st_id)
@@ -2193,13 +2190,19 @@ nfs4_preprocess_seqid_op(struct svc_fh *current_fh, u32 seqid, stateid_t *statei
2193 * We return BAD_STATEID if filehandle doesn't match stateid, 2190 * We return BAD_STATEID if filehandle doesn't match stateid,
2194 * the confirmed flag is incorrecly set, or the generation 2191 * the confirmed flag is incorrecly set, or the generation
2195 * number is incorrect. 2192 * number is incorrect.
2196 * If there is no entry in the openfile table for this id,
2197 * we can't always return BAD_STATEID;
2198 * this might be a retransmitted CLOSE which has arrived after
2199 * the openfile has been released.
2200 */ 2193 */
2201 if (!(stp = find_stateid(stateid, flags))) 2194 stp = find_stateid(stateid, flags);
2202 goto no_nfs4_stateid; 2195 if (stp == NULL) {
2196 /*
2197 * Also, we should make sure this isn't just the result of
2198 * a replayed close:
2199 */
2200 sop = search_close_lru(stateid->si_stateownerid, flags);
2201 if (sop == NULL)
2202 return nfserr_bad_stateid;
2203 *sopp = sop;
2204 goto check_replay;
2205 }
2203 2206
2204 status = nfserr_bad_stateid; 2207 status = nfserr_bad_stateid;
2205 2208
@@ -2263,21 +2266,6 @@ nfs4_preprocess_seqid_op(struct svc_fh *current_fh, u32 seqid, stateid_t *statei
2263 2266
2264out: 2267out:
2265 return status; 2268 return status;
2266
2267no_nfs4_stateid:
2268
2269 /*
2270 * We determine whether this is a bad stateid or a replay,
2271 * starting by trying to look up the stateowner.
2272 * If stateowner is not found - stateid is bad.
2273 */
2274 if (!(sop = find_openstateowner_id(stateid->si_stateownerid, flags))) {
2275 printk("NFSD: preprocess_seqid_op: no stateowner or nfs4_stateid!\n");
2276 status = nfserr_bad_stateid;
2277 goto out;
2278 }
2279 *sopp = sop;
2280
2281check_replay: 2269check_replay:
2282 if (seqid == sop->so_seqid - 1) { 2270 if (seqid == sop->so_seqid - 1) {
2283 printk("NFSD: preprocess_seqid_op: retransmission?\n"); 2271 printk("NFSD: preprocess_seqid_op: retransmission?\n");