aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorNeilBrown <neilb@cse.unsw.edu.au>2005-07-07 20:59:25 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-07-07 21:24:10 -0400
commitf8816512fcfde986326a2eb0f5a58e463d9904d8 (patch)
tree3f79b8c23a393c119e0de31294c2843d7bd3b01e /fs
parent52fd004e296ac07cde820af9e3139d47dda03cf8 (diff)
[PATCH] nfsd4: clarify close_lru handling
The handling of close_lru in preprocess_stateid_op was a source of some confusion here recently. Try to make the logic a little clearer, by renaming find_openstateowner_id to make its purpose clearer and untangling some unnecessarily complicated goto's. Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu> Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs')
-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");