Commit 0f442aa2 authored by J. Bruce Fields's avatar J. Bruce Fields Committed by Linus Torvalds

[PATCH] nfsd4: simplify process-open1 logic

nfsd4_process_open1 is very highly nested; flatten it out a bit.

Also, the preceding comment, which just outlines the logic, seems redundant.
Signed-off-by: default avatarJ. Bruce Fields <bfields@citi.umich.edu>
Signed-off-by: default avatarNeil Brown <neilb@suse.de>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 375c5547
......@@ -1429,90 +1429,61 @@ static struct lock_manager_operations nfsd_lease_mng_ops = {
};
/*
* nfsd4_process_open1()
* lookup stateowner.
* found:
* check confirmed
* confirmed:
* check seqid
* not confirmed:
* delete owner
* create new owner
* notfound:
* verify clientid
* create new owner
*
* called with nfs4_lock_state() held.
*/
int
nfsd4_process_open1(struct nfsd4_open *open)
{
int status;
clientid_t *clientid = &open->op_clientid;
struct nfs4_client *clp = NULL;
unsigned int strhashval;
struct nfs4_stateowner *sop = NULL;
status = nfserr_inval;
if (!check_name(open->op_owner))
goto out;
return nfserr_inval;
if (STALE_CLIENTID(&open->op_clientid))
return nfserr_stale_clientid;
strhashval = ownerstr_hashval(clientid->cl_id, open->op_owner);
sop = find_openstateowner_str(strhashval, open);
if (sop) {
open->op_stateowner = sop;
if (!sop->so_confirmed) {
/* Replace any unconfirmed stateowner without
* even checking for replays */
clp = sop->so_client;
release_stateowner(sop);
} else if (open->op_seqid == sop->so_seqid) {
/* normal case */
goto renew;
} else if (open->op_seqid == sop->so_seqid - 1) {
/* replay */
if (sop->so_replay.rp_buflen)
return NFSERR_REPLAY_ME;
else {
/* The original OPEN failed so spectacularly
* that we don't even have replay data saved!
* Therefore, we have no choice but to continue
* processing this OPEN; presumably, we'll
* fail again for the same reason.
*/
dprintk("nfsd4_process_open1:"
" replay with no replay cache\n");
goto renew;
}
} else {
status = nfserr_bad_seqid;
goto out;
}
} else {
/* nfs4_stateowner not found.
* Verify clientid and instantiate new nfs4_stateowner.
* If verify fails this is presumably the result of the
* client's lease expiring.
*/
status = nfserr_expired;
open->op_stateowner = sop;
if (!sop) {
/* Make sure the client's lease hasn't expired. */
clp = find_confirmed_client(clientid);
if (clp == NULL)
goto out;
return nfserr_expired;
goto renew;
}
status = nfserr_resource;
sop = alloc_init_open_stateowner(strhashval, clp, open);
if (sop == NULL)
goto out;
open->op_stateowner = sop;
if (!sop->so_confirmed) {
/* Replace unconfirmed owners without checking for replay. */
clp = sop->so_client;
release_stateowner(sop);
open->op_stateowner = NULL;
goto renew;
}
if (open->op_seqid == sop->so_seqid - 1) {
if (sop->so_replay.rp_buflen)
return NFSERR_REPLAY_ME;
/* The original OPEN failed so spectacularly
* that we don't even have replay data saved!
* Therefore, we have no choice but to continue
* processing this OPEN; presumably, we'll
* fail again for the same reason.
*/
dprintk("nfsd4_process_open1: replay with no replay cache\n");
goto renew;
}
if (open->op_seqid != sop->so_seqid)
return nfserr_bad_seqid;
renew:
status = nfs_ok;
if (open->op_stateowner == NULL) {
sop = alloc_init_open_stateowner(strhashval, clp, open);
if (sop == NULL)
return nfserr_resource;
open->op_stateowner = sop;
}
list_del_init(&sop->so_close_lru);
renew_client(sop->so_client);
out:
return status;
return nfs_ok;
}
static inline int
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment