X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=fs%2Fnfsd%2Fnfs4proc.c;h=55835414fa411f28a6f90531216afe3d16c9e5f7;hb=c7b5ebbddf7bcd3651947760f423e3783bbe6573;hp=d8765a09327f09a5eb080bd73012f564bbf4346b;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index d8765a093..55835414f 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -52,6 +52,7 @@ #include #include #include +#include #define NFSDDBG_FACILITY NFSDDBG_PROC @@ -135,9 +136,11 @@ do_open_fhandle(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_ { int status; - dprintk("NFSD: do_open_fhandle\n"); + /* Only reclaims from previously confirmed clients are valid */ + if ((status = nfs4_check_open_reclaim(&open->op_clientid))) + return status; - /* we don't know the target directory, and therefore can not + /* We don't know the target directory, and therefore can not * set the change info */ @@ -172,8 +175,7 @@ nfsd4_open(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open if (nfs4_in_grace() && open->op_claim_type != NFS4_OPEN_CLAIM_PREVIOUS) return nfserr_grace; - if (nfs4_in_no_grace() && - open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS) + if (!nfs4_in_grace() && open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS) return nfserr_no_grace; /* This check required by spec. */ @@ -318,7 +320,7 @@ nfsd4_commit(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_com return status; } -static inline int +static int nfsd4_create(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_create *create) { struct svc_fh resfh; @@ -389,7 +391,7 @@ nfsd4_create(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_cre break; default: - BUG(); + status = nfserr_badtype; } if (!status) { @@ -435,7 +437,7 @@ nfsd4_link(struct svc_rqst *rqstp, struct svc_fh *current_fh, return status; } -static inline int +static int nfsd4_lookupp(struct svc_rqst *rqstp, struct svc_fh *current_fh) { struct svc_fh tmp_fh; @@ -619,7 +621,7 @@ nfsd4_setattr(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_se status = nfserr_bad_stateid; if (ZERO_STATEID(&setattr->sa_stateid) || ONE_STATEID(&setattr->sa_stateid)) { dprintk("NFSD: nfsd4_setattr: magic stateid!\n"); - return status; + goto out; } nfs4_lock_state(); @@ -627,17 +629,25 @@ nfsd4_setattr(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_se &setattr->sa_stateid, CHECK_FH | RDWR_STATE, &stp))) { dprintk("NFSD: nfsd4_setattr: couldn't process stateid!\n"); - goto out; + 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; + goto out_unlock; } nfs4_unlock_state(); } - return (nfsd_setattr(rqstp, current_fh, &setattr->sa_iattr, 0, (time_t)0)); + status = nfs_ok; + if (setattr->sa_acl != NULL) + status = nfsd4_set_nfs4_acl(rqstp, current_fh, setattr->sa_acl); + if (status) + goto out; + status = nfsd_setattr(rqstp, current_fh, &setattr->sa_iattr, + 0, (time_t)0); out: + return status; +out_unlock: nfs4_unlock_state(); return status; } @@ -773,13 +783,20 @@ nfsd4_proc_compound(struct svc_rqst *rqstp, struct nfsd4_compoundres *resp) { struct nfsd4_op *op; - struct svc_fh current_fh; - struct svc_fh save_fh; + struct svc_fh *current_fh = NULL; + struct svc_fh *save_fh = NULL; int slack_space; /* in words, not bytes! */ int status; - fh_init(¤t_fh, NFS4_FHSIZE); - fh_init(&save_fh, NFS4_FHSIZE); + status = nfserr_resource; + current_fh = kmalloc(sizeof(*current_fh), GFP_KERNEL); + if (current_fh == NULL) + goto out; + fh_init(current_fh, NFS4_FHSIZE); + save_fh = kmalloc(sizeof(*save_fh), GFP_KERNEL); + if (save_fh == NULL) + goto out; + fh_init(save_fh, NFS4_FHSIZE); resp->xbuf = &rqstp->rq_res; resp->p = rqstp->rq_res.head[0].iov_base + rqstp->rq_res.head[0].iov_len; @@ -831,7 +848,7 @@ nfsd4_proc_compound(struct svc_rqst *rqstp, * SETATTR NOFILEHANDLE error handled in nfsd4_setattr * due to required returned bitmap argument */ - if ((!current_fh.fh_dentry) && + if ((!current_fh->fh_dentry) && !((op->opnum == OP_PUTFH) || (op->opnum == OP_PUTROOTFH) || (op->opnum == OP_SETCLIENTID) || (op->opnum == OP_SETCLIENTID_CONFIRM) || @@ -843,105 +860,105 @@ nfsd4_proc_compound(struct svc_rqst *rqstp, } switch (op->opnum) { case OP_ACCESS: - op->status = nfsd4_access(rqstp, ¤t_fh, &op->u.access); + op->status = nfsd4_access(rqstp, current_fh, &op->u.access); break; case OP_CLOSE: - op->status = nfsd4_close(rqstp, ¤t_fh, &op->u.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; break; case OP_COMMIT: - op->status = nfsd4_commit(rqstp, ¤t_fh, &op->u.commit); + op->status = nfsd4_commit(rqstp, current_fh, &op->u.commit); break; case OP_CREATE: - op->status = nfsd4_create(rqstp, ¤t_fh, &op->u.create); + op->status = nfsd4_create(rqstp, current_fh, &op->u.create); break; case OP_GETATTR: - op->status = nfsd4_getattr(rqstp, ¤t_fh, &op->u.getattr); + op->status = nfsd4_getattr(rqstp, current_fh, &op->u.getattr); break; case OP_GETFH: - op->status = nfsd4_getfh(¤t_fh, &op->u.getfh); + op->status = nfsd4_getfh(current_fh, &op->u.getfh); break; case OP_LINK: - op->status = nfsd4_link(rqstp, ¤t_fh, &save_fh, &op->u.link); + op->status = nfsd4_link(rqstp, current_fh, save_fh, &op->u.link); break; case OP_LOCK: - op->status = nfsd4_lock(rqstp, ¤t_fh, &op->u.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; break; case OP_LOCKT: - op->status = nfsd4_lockt(rqstp, ¤t_fh, &op->u.lockt); + op->status = nfsd4_lockt(rqstp, current_fh, &op->u.lockt); break; case OP_LOCKU: - op->status = nfsd4_locku(rqstp, ¤t_fh, &op->u.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; break; case OP_LOOKUP: - op->status = nfsd4_lookup(rqstp, ¤t_fh, &op->u.lookup); + op->status = nfsd4_lookup(rqstp, current_fh, &op->u.lookup); break; case OP_LOOKUPP: - op->status = nfsd4_lookupp(rqstp, ¤t_fh); + op->status = nfsd4_lookupp(rqstp, current_fh); break; case OP_NVERIFY: - op->status = nfsd4_verify(rqstp, ¤t_fh, &op->u.nverify); + op->status = nfsd4_verify(rqstp, current_fh, &op->u.nverify); if (op->status == nfserr_not_same) op->status = nfs_ok; break; case OP_OPEN: - op->status = nfsd4_open(rqstp, ¤t_fh, &op->u.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; break; case OP_OPEN_CONFIRM: - op->status = nfsd4_open_confirm(rqstp, ¤t_fh, &op->u.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; break; case OP_OPEN_DOWNGRADE: - op->status = nfsd4_open_downgrade(rqstp, ¤t_fh, &op->u.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; break; case OP_PUTFH: - op->status = nfsd4_putfh(rqstp, ¤t_fh, &op->u.putfh); + op->status = nfsd4_putfh(rqstp, current_fh, &op->u.putfh); break; case OP_PUTROOTFH: - op->status = nfsd4_putrootfh(rqstp, ¤t_fh); + op->status = nfsd4_putrootfh(rqstp, current_fh); break; case OP_READ: - op->status = nfsd4_read(rqstp, ¤t_fh, &op->u.read); + op->status = nfsd4_read(rqstp, current_fh, &op->u.read); break; case OP_READDIR: - op->status = nfsd4_readdir(rqstp, ¤t_fh, &op->u.readdir); + op->status = nfsd4_readdir(rqstp, current_fh, &op->u.readdir); break; case OP_READLINK: - op->status = nfsd4_readlink(rqstp, ¤t_fh, &op->u.readlink); + op->status = nfsd4_readlink(rqstp, current_fh, &op->u.readlink); break; case OP_REMOVE: - op->status = nfsd4_remove(rqstp, ¤t_fh, &op->u.remove); + op->status = nfsd4_remove(rqstp, current_fh, &op->u.remove); break; case OP_RENAME: - op->status = nfsd4_rename(rqstp, ¤t_fh, &save_fh, &op->u.rename); + op->status = nfsd4_rename(rqstp, current_fh, save_fh, &op->u.rename); break; case OP_RENEW: op->status = nfsd4_renew(&op->u.renew); break; case OP_RESTOREFH: - op->status = nfsd4_restorefh(¤t_fh, &save_fh); + op->status = nfsd4_restorefh(current_fh, save_fh); break; case OP_SAVEFH: - op->status = nfsd4_savefh(¤t_fh, &save_fh); + op->status = nfsd4_savefh(current_fh, save_fh); break; case OP_SETATTR: - op->status = nfsd4_setattr(rqstp, ¤t_fh, &op->u.setattr); + op->status = nfsd4_setattr(rqstp, current_fh, &op->u.setattr); break; case OP_SETCLIENTID: op->status = nfsd4_setclientid(rqstp, &op->u.setclientid); @@ -950,12 +967,12 @@ nfsd4_proc_compound(struct svc_rqst *rqstp, op->status = nfsd4_setclientid_confirm(rqstp, &op->u.setclientid_confirm); break; case OP_VERIFY: - op->status = nfsd4_verify(rqstp, ¤t_fh, &op->u.verify); + op->status = nfsd4_verify(rqstp, current_fh, &op->u.verify); if (op->status == nfserr_same) op->status = nfs_ok; break; case OP_WRITE: - op->status = nfsd4_write(rqstp, ¤t_fh, &op->u.write); + op->status = nfsd4_write(rqstp, current_fh, &op->u.write); break; case OP_RELEASE_LOCKOWNER: op->status = nfsd4_release_lockowner(rqstp, &op->u.release_lockowner); @@ -976,22 +993,13 @@ encode_op: } out: - if (args->ops != args->iops) { - kfree(args->ops); - args->ops = args->iops; - } - if (args->tmpp) { - kfree(args->tmpp); - args->tmpp = NULL; - } - while (args->to_free) { - struct tmpbuf *tb = args->to_free; - args->to_free = tb->next; - kfree(tb->buf); - kfree(tb); - } - fh_put(¤t_fh); - fh_put(&save_fh); + nfsd4_release_compoundargs(args); + if (current_fh) + fh_put(current_fh); + kfree(current_fh); + if (save_fh) + fh_put(save_fh); + kfree(save_fh); return status; }