X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=fs%2Fnfsd%2Fnfs4proc.c;h=6c23964e6155e7357e1c8bbf738c80bff5492f75;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=55835414fa411f28a6f90531216afe3d16c9e5f7;hpb=87fc8d1bb10cd459024a742c6a10961fefcef18f;p=linux-2.6.git diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 55835414f..6c23964e6 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -161,9 +161,6 @@ do_open_fhandle(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_ } -/* - * nfs4_unlock_state() called in encode - */ static inline int nfsd4_open(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open) { @@ -182,7 +179,6 @@ nfsd4_open(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open if (open->op_create && open->op_claim_type != NFS4_OPEN_CLAIM_NULL) return nfserr_inval; - open->op_stateowner = NULL; nfs4_lock_state(); /* check seqid for replay. set nfs4_owner */ @@ -201,7 +197,7 @@ nfsd4_open(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open status = NFSERR_REPLAY_ME; } if (status) - return status; + goto out; if (open->op_claim_type == NFS4_OPEN_CLAIM_NULL) { /* * This block of code will (1) set CURRENT_FH to the file being opened, @@ -211,7 +207,7 @@ nfsd4_open(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open */ status = do_open_lookup(rqstp, current_fh, open); if (status) - return status; + goto out; } else if (open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS) { /* * The CURRENT_FH is already set to the file being opened. This @@ -221,10 +217,11 @@ nfsd4_open(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open */ status = do_open_fhandle(rqstp, current_fh, open); if (status) - return status; + goto out; } else { 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 @@ -232,9 +229,11 @@ 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. */ status = nfsd4_process_open2(rqstp, current_fh, open); - if (status) - return status; - return 0; +out: + if (open->op_stateowner) + nfs4_get_stateowner(open->op_stateowner); + nfs4_unlock_state(); + return status; } /* @@ -268,7 +267,7 @@ nfsd4_putrootfh(struct svc_rqst *rqstp, struct svc_fh *current_fh) status = exp_pseudoroot(rqstp->rq_client, current_fh, &rqstp->rq_chandle); if (!status) - status = nfsd_setuser(rqstp, current_fh->fh_export); + status = nfserrno(nfsd_setuser(rqstp, current_fh->fh_export)); return status; } @@ -461,24 +460,9 @@ nfsd4_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_loo return nfsd_lookup(rqstp, current_fh, lookup->lo_name, lookup->lo_len, current_fh); } -static inline int -access_bits_permit_read(unsigned long access_bmap) -{ - return test_bit(NFS4_SHARE_ACCESS_READ, &access_bmap) || - test_bit(NFS4_SHARE_ACCESS_BOTH, &access_bmap); -} - -static inline int -access_bits_permit_write(unsigned long access_bmap) -{ - return test_bit(NFS4_SHARE_ACCESS_WRITE, &access_bmap) || - test_bit(NFS4_SHARE_ACCESS_BOTH, &access_bmap); -} - static inline int nfsd4_read(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_read *read) { - struct nfs4_stateid *stp; int status; /* no need to check permission - this will be done in nfsd_read() */ @@ -510,15 +494,10 @@ nfsd4_read(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_read } /* check stateid */ if ((status = nfs4_preprocess_stateid_op(current_fh, &read->rd_stateid, - CHECK_FH | RDWR_STATE, &stp))) { + CHECK_FH | RD_STATE))) { dprintk("NFSD: nfsd4_read: couldn't process stateid!\n"); goto out; } - status = nfserr_openmode; - if (!access_bits_permit_read(stp->st_access_bmap)) { - dprintk("NFSD: nfsd4_read: file not opened for read!\n"); - goto out; - } status = nfs_ok; out: nfs4_unlock_state(); @@ -606,7 +585,6 @@ nfsd4_rename(struct svc_rqst *rqstp, struct svc_fh *current_fh, static inline int nfsd4_setattr(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_setattr *setattr) { - struct nfs4_stateid *stp; int status = nfs_ok; if (nfs4_in_grace()) @@ -627,15 +605,10 @@ nfsd4_setattr(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_se nfs4_lock_state(); if ((status = nfs4_preprocess_stateid_op(current_fh, &setattr->sa_stateid, - CHECK_FH | RDWR_STATE, &stp))) { + CHECK_FH | WR_STATE))) { dprintk("NFSD: nfsd4_setattr: couldn't process stateid!\n"); goto out_unlock; } - status = nfserr_openmode; - if (!access_bits_permit_write(stp->st_access_bmap)) { - dprintk("NFSD: nfsd4_setattr: not opened for write!\n"); - goto out_unlock; - } nfs4_unlock_state(); } status = nfs_ok; @@ -655,7 +628,6 @@ out_unlock: static inline int nfsd4_write(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_write *write) { - struct nfs4_stateid *stp; stateid_t *stateid = &write->wr_stateid; u32 *p; int status = nfs_ok; @@ -678,18 +650,13 @@ nfsd4_write(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_writ goto zero_stateid; } if ((status = nfs4_preprocess_stateid_op(current_fh, stateid, - CHECK_FH | RDWR_STATE, &stp))) { + CHECK_FH | WR_STATE))) { dprintk("NFSD: nfsd4_write: couldn't process stateid!\n"); goto out; } - status = nfserr_openmode; - if (!access_bits_permit_write(stp->st_access_bmap)) { - dprintk("NFSD: nfsd4_write: file not open for write!\n"); - goto out; - } - zero_stateid: + nfs4_unlock_state(); write->wr_bytes_written = write->wr_buflen; write->wr_how_written = write->wr_stable_how; @@ -785,6 +752,7 @@ nfsd4_proc_compound(struct svc_rqst *rqstp, struct nfsd4_op *op; struct svc_fh *current_fh = NULL; struct svc_fh *save_fh = NULL; + struct nfs4_stateowner *replay_owner = NULL; int slack_space; /* in words, not bytes! */ int status; @@ -864,9 +832,7 @@ nfsd4_proc_compound(struct svc_rqst *rqstp, break; case OP_CLOSE: op->status = nfsd4_close(rqstp, current_fh, &op->u.close); - if (op->u.close.cl_stateowner) - op->replay = - &op->u.close.cl_stateowner->so_replay; + replay_owner = op->u.close.cl_stateowner; break; case OP_COMMIT: op->status = nfsd4_commit(rqstp, current_fh, &op->u.commit); @@ -874,6 +840,9 @@ nfsd4_proc_compound(struct svc_rqst *rqstp, case OP_CREATE: op->status = nfsd4_create(rqstp, current_fh, &op->u.create); break; + case OP_DELEGRETURN: + op->status = nfsd4_delegreturn(rqstp, current_fh, &op->u.delegreturn); + break; case OP_GETATTR: op->status = nfsd4_getattr(rqstp, current_fh, &op->u.getattr); break; @@ -885,18 +854,14 @@ nfsd4_proc_compound(struct svc_rqst *rqstp, break; case OP_LOCK: op->status = nfsd4_lock(rqstp, current_fh, &op->u.lock); - if (op->u.lock.lk_stateowner) - op->replay = - &op->u.lock.lk_stateowner->so_replay; + replay_owner = op->u.lock.lk_stateowner; break; case OP_LOCKT: op->status = nfsd4_lockt(rqstp, current_fh, &op->u.lockt); break; case OP_LOCKU: op->status = nfsd4_locku(rqstp, current_fh, &op->u.locku); - if (op->u.locku.lu_stateowner) - op->replay = - &op->u.locku.lu_stateowner->so_replay; + replay_owner = op->u.locku.lu_stateowner; break; case OP_LOOKUP: op->status = nfsd4_lookup(rqstp, current_fh, &op->u.lookup); @@ -911,21 +876,15 @@ nfsd4_proc_compound(struct svc_rqst *rqstp, break; case OP_OPEN: op->status = nfsd4_open(rqstp, current_fh, &op->u.open); - if (op->u.open.op_stateowner) - op->replay = - &op->u.open.op_stateowner->so_replay; + replay_owner = op->u.open.op_stateowner; break; case OP_OPEN_CONFIRM: op->status = nfsd4_open_confirm(rqstp, current_fh, &op->u.open_confirm); - if (op->u.open_confirm.oc_stateowner) - op->replay = - &op->u.open_confirm.oc_stateowner->so_replay; + replay_owner = op->u.open_confirm.oc_stateowner; break; case OP_OPEN_DOWNGRADE: op->status = nfsd4_open_downgrade(rqstp, current_fh, &op->u.open_downgrade); - if (op->u.open_downgrade.od_stateowner) - op->replay = - &op->u.open_downgrade.od_stateowner->so_replay; + replay_owner = op->u.open_downgrade.od_stateowner; break; case OP_PUTFH: op->status = nfsd4_putfh(rqstp, current_fh, &op->u.putfh); @@ -984,12 +943,17 @@ nfsd4_proc_compound(struct svc_rqst *rqstp, encode_op: if (op->status == NFSERR_REPLAY_ME) { + op->replay = &replay_owner->so_replay; nfsd4_encode_replay(resp, op); status = op->status = op->replay->rp_status; } else { nfsd4_encode_operation(resp, op); status = op->status; } + if (replay_owner && (replay_owner != (void *)(-1))) { + nfs4_put_stateowner(replay_owner); + replay_owner = NULL; + } } out: