Commit 415ddd59 authored by Neil Brown's avatar Neil Brown Committed by Linus Torvalds

[PATCH] nfsd4: take a reference to preserve stateowner through xdr replay code

Take a reference to preserve the stateowner through the xdr replay code, and
simplify nfsd4_proc_compound a little.
Signed-off-by: default avatarJ. Bruce Fields <bfields@citi.umich.edu>
Signed-off-by: default avatarNeil Brown <neilb@cse.unsw.edu.au>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent d384d7c2
...@@ -201,7 +201,7 @@ nfsd4_open(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open ...@@ -201,7 +201,7 @@ nfsd4_open(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open
status = NFSERR_REPLAY_ME; status = NFSERR_REPLAY_ME;
} }
if (status) if (status)
return status; goto out;
if (open->op_claim_type == NFS4_OPEN_CLAIM_NULL) { if (open->op_claim_type == NFS4_OPEN_CLAIM_NULL) {
/* /*
* This block of code will (1) set CURRENT_FH to the file being opened, * This block of code will (1) set CURRENT_FH to the file being opened,
...@@ -211,7 +211,7 @@ nfsd4_open(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open ...@@ -211,7 +211,7 @@ nfsd4_open(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open
*/ */
status = do_open_lookup(rqstp, current_fh, open); status = do_open_lookup(rqstp, current_fh, open);
if (status) if (status)
return status; goto out;
} else if (open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS) { } else if (open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS) {
/* /*
* The CURRENT_FH is already set to the file being opened. This * The CURRENT_FH is already set to the file being opened. This
...@@ -221,10 +221,11 @@ nfsd4_open(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open ...@@ -221,10 +221,11 @@ nfsd4_open(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open
*/ */
status = do_open_fhandle(rqstp, current_fh, open); status = do_open_fhandle(rqstp, current_fh, open);
if (status) if (status)
return status; goto out;
} else { } else {
printk("NFSD: unsupported OPEN claim type\n"); printk("NFSD: unsupported OPEN claim type\n");
return nfserr_inval; status = nfserr_inval;
goto out;
} }
/* /*
* nfsd4_process_open2() does the actual opening of the file. If * nfsd4_process_open2() does the actual opening of the file. If
...@@ -232,9 +233,10 @@ nfsd4_open(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open ...@@ -232,9 +233,10 @@ nfsd4_open(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open
* set, (2) sets open->op_stateid, (3) sets open->op_delegation. * set, (2) sets open->op_stateid, (3) sets open->op_delegation.
*/ */
status = nfsd4_process_open2(rqstp, current_fh, open); status = nfsd4_process_open2(rqstp, current_fh, open);
if (status) out:
return status; if (open->op_stateowner)
return 0; nfs4_get_stateowner(open->op_stateowner);
return status;
} }
/* /*
...@@ -785,6 +787,7 @@ nfsd4_proc_compound(struct svc_rqst *rqstp, ...@@ -785,6 +787,7 @@ nfsd4_proc_compound(struct svc_rqst *rqstp,
struct nfsd4_op *op; struct nfsd4_op *op;
struct svc_fh *current_fh = NULL; struct svc_fh *current_fh = NULL;
struct svc_fh *save_fh = NULL; struct svc_fh *save_fh = NULL;
struct nfs4_stateowner *replay_owner = NULL;
int slack_space; /* in words, not bytes! */ int slack_space; /* in words, not bytes! */
int status; int status;
...@@ -864,9 +867,7 @@ nfsd4_proc_compound(struct svc_rqst *rqstp, ...@@ -864,9 +867,7 @@ nfsd4_proc_compound(struct svc_rqst *rqstp,
break; break;
case OP_CLOSE: case OP_CLOSE:
op->status = nfsd4_close(rqstp, current_fh, &op->u.close); op->status = nfsd4_close(rqstp, current_fh, &op->u.close);
if (op->u.close.cl_stateowner) replay_owner = op->u.close.cl_stateowner;
op->replay =
&op->u.close.cl_stateowner->so_replay;
break; break;
case OP_COMMIT: case OP_COMMIT:
op->status = nfsd4_commit(rqstp, current_fh, &op->u.commit); op->status = nfsd4_commit(rqstp, current_fh, &op->u.commit);
...@@ -885,18 +886,14 @@ nfsd4_proc_compound(struct svc_rqst *rqstp, ...@@ -885,18 +886,14 @@ nfsd4_proc_compound(struct svc_rqst *rqstp,
break; break;
case OP_LOCK: case OP_LOCK:
op->status = nfsd4_lock(rqstp, current_fh, &op->u.lock); op->status = nfsd4_lock(rqstp, current_fh, &op->u.lock);
if (op->u.lock.lk_stateowner) replay_owner = op->u.lock.lk_stateowner;
op->replay =
&op->u.lock.lk_stateowner->so_replay;
break; break;
case OP_LOCKT: case OP_LOCKT:
op->status = nfsd4_lockt(rqstp, current_fh, &op->u.lockt); op->status = nfsd4_lockt(rqstp, current_fh, &op->u.lockt);
break; break;
case OP_LOCKU: case OP_LOCKU:
op->status = nfsd4_locku(rqstp, current_fh, &op->u.locku); op->status = nfsd4_locku(rqstp, current_fh, &op->u.locku);
if (op->u.locku.lu_stateowner) replay_owner = op->u.locku.lu_stateowner;
op->replay =
&op->u.locku.lu_stateowner->so_replay;
break; break;
case OP_LOOKUP: case OP_LOOKUP:
op->status = nfsd4_lookup(rqstp, current_fh, &op->u.lookup); op->status = nfsd4_lookup(rqstp, current_fh, &op->u.lookup);
...@@ -911,21 +908,15 @@ nfsd4_proc_compound(struct svc_rqst *rqstp, ...@@ -911,21 +908,15 @@ nfsd4_proc_compound(struct svc_rqst *rqstp,
break; break;
case OP_OPEN: case OP_OPEN:
op->status = nfsd4_open(rqstp, current_fh, &op->u.open); op->status = nfsd4_open(rqstp, current_fh, &op->u.open);
if (op->u.open.op_stateowner) replay_owner = op->u.open.op_stateowner;
op->replay =
&op->u.open.op_stateowner->so_replay;
break; break;
case OP_OPEN_CONFIRM: case OP_OPEN_CONFIRM:
op->status = nfsd4_open_confirm(rqstp, current_fh, &op->u.open_confirm); op->status = nfsd4_open_confirm(rqstp, current_fh, &op->u.open_confirm);
if (op->u.open_confirm.oc_stateowner) replay_owner = op->u.open_confirm.oc_stateowner;
op->replay =
&op->u.open_confirm.oc_stateowner->so_replay;
break; break;
case OP_OPEN_DOWNGRADE: case OP_OPEN_DOWNGRADE:
op->status = nfsd4_open_downgrade(rqstp, current_fh, &op->u.open_downgrade); op->status = nfsd4_open_downgrade(rqstp, current_fh, &op->u.open_downgrade);
if (op->u.open_downgrade.od_stateowner) replay_owner = op->u.open_downgrade.od_stateowner;
op->replay =
&op->u.open_downgrade.od_stateowner->so_replay;
break; break;
case OP_PUTFH: case OP_PUTFH:
op->status = nfsd4_putfh(rqstp, current_fh, &op->u.putfh); op->status = nfsd4_putfh(rqstp, current_fh, &op->u.putfh);
...@@ -984,12 +975,17 @@ nfsd4_proc_compound(struct svc_rqst *rqstp, ...@@ -984,12 +975,17 @@ nfsd4_proc_compound(struct svc_rqst *rqstp,
encode_op: encode_op:
if (op->status == NFSERR_REPLAY_ME) { if (op->status == NFSERR_REPLAY_ME) {
op->replay = &replay_owner->so_replay;
nfsd4_encode_replay(resp, op); nfsd4_encode_replay(resp, op);
status = op->status = op->replay->rp_status; status = op->status = op->replay->rp_status;
} else { } else {
nfsd4_encode_operation(resp, op); nfsd4_encode_operation(resp, op);
status = op->status; status = op->status;
} }
if (replay_owner && (replay_owner != (void *)(-1))) {
nfs4_put_stateowner(replay_owner);
replay_owner = NULL;
}
} }
out: out:
......
...@@ -1750,6 +1750,8 @@ nfsd4_open_confirm(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfs ...@@ -1750,6 +1750,8 @@ nfsd4_open_confirm(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfs
status = nfs_ok; status = nfs_ok;
first_state(sop->so_client); first_state(sop->so_client);
out: out:
if (oc->oc_stateowner)
nfs4_get_stateowner(oc->oc_stateowner);
return status; return status;
} }
...@@ -1827,6 +1829,8 @@ nfsd4_open_downgrade(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct n ...@@ -1827,6 +1829,8 @@ nfsd4_open_downgrade(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct n
memcpy(&od->od_stateid, &stp->st_stateid, sizeof(stateid_t)); memcpy(&od->od_stateid, &stp->st_stateid, sizeof(stateid_t));
status = nfs_ok; status = nfs_ok;
out: out:
if (od->od_stateowner)
nfs4_get_stateowner(od->od_stateowner);
return status; return status;
} }
...@@ -1861,6 +1865,8 @@ nfsd4_close(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_clos ...@@ -1861,6 +1865,8 @@ nfsd4_close(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_clos
/* release_state_owner() calls nfsd_close() if needed */ /* release_state_owner() calls nfsd_close() if needed */
release_state_owner(stp, &close->cl_stateowner, OPEN_STATE); release_state_owner(stp, &close->cl_stateowner, OPEN_STATE);
out: out:
if (close->cl_stateowner)
nfs4_get_stateowner(close->cl_stateowner);
return status; return status;
} }
...@@ -2161,6 +2167,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock ...@@ -2161,6 +2167,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock
if ((lock_stp = alloc_init_lock_stateid(lock->lk_stateowner, if ((lock_stp = alloc_init_lock_stateid(lock->lk_stateowner,
fp, open_stp)) == NULL) { fp, open_stp)) == NULL) {
release_stateowner(lock->lk_stateowner); release_stateowner(lock->lk_stateowner);
lock->lk_stateowner = NULL;
goto out; goto out;
} }
/* bump the open seqid used to create the lock */ /* bump the open seqid used to create the lock */
...@@ -2259,6 +2266,8 @@ nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock ...@@ -2259,6 +2266,8 @@ nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock
release_state_owner(lock_stp, &lock->lk_stateowner, LOCK_STATE); release_state_owner(lock_stp, &lock->lk_stateowner, LOCK_STATE);
} }
out: out:
if (lock->lk_stateowner)
nfs4_get_stateowner(lock->lk_stateowner);
return status; return status;
} }
...@@ -2410,6 +2419,8 @@ nfsd4_locku(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock ...@@ -2410,6 +2419,8 @@ nfsd4_locku(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock
memcpy(&locku->lu_stateid, &stp->st_stateid, sizeof(stateid_t)); memcpy(&locku->lu_stateid, &stp->st_stateid, sizeof(stateid_t));
out: out:
if (locku->lu_stateowner)
nfs4_get_stateowner(locku->lu_stateowner);
return status; return status;
out_nfserr: out_nfserr:
......
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