📄 nfs4xdr.c
字号:
{ DECODE_HEAD; READ_BUF(4); READ32(link->li_namelen); READ_BUF(link->li_namelen); SAVEMEM(link->li_name, link->li_namelen); if ((status = check_filename(link->li_name, link->li_namelen, nfserr_inval))) return status; DECODE_TAIL;}static __be32nfsd4_decode_lock(struct nfsd4_compoundargs *argp, struct nfsd4_lock *lock){ DECODE_HEAD; lock->lk_replay_owner = NULL; /* * type, reclaim(boolean), offset, length, new_lock_owner(boolean) */ READ_BUF(28); READ32(lock->lk_type); if ((lock->lk_type < NFS4_READ_LT) || (lock->lk_type > NFS4_WRITEW_LT)) goto xdr_error; READ32(lock->lk_reclaim); READ64(lock->lk_offset); READ64(lock->lk_length); READ32(lock->lk_is_new); if (lock->lk_is_new) { READ_BUF(36); READ32(lock->lk_new_open_seqid); READ32(lock->lk_new_open_stateid.si_generation); COPYMEM(&lock->lk_new_open_stateid.si_opaque, sizeof(stateid_opaque_t)); READ32(lock->lk_new_lock_seqid); COPYMEM(&lock->lk_new_clientid, sizeof(clientid_t)); READ32(lock->lk_new_owner.len); READ_BUF(lock->lk_new_owner.len); READMEM(lock->lk_new_owner.data, lock->lk_new_owner.len); } else { READ_BUF(20); READ32(lock->lk_old_lock_stateid.si_generation); COPYMEM(&lock->lk_old_lock_stateid.si_opaque, sizeof(stateid_opaque_t)); READ32(lock->lk_old_lock_seqid); } DECODE_TAIL;}static __be32nfsd4_decode_lockt(struct nfsd4_compoundargs *argp, struct nfsd4_lockt *lockt){ DECODE_HEAD; READ_BUF(32); READ32(lockt->lt_type); if((lockt->lt_type < NFS4_READ_LT) || (lockt->lt_type > NFS4_WRITEW_LT)) goto xdr_error; READ64(lockt->lt_offset); READ64(lockt->lt_length); COPYMEM(&lockt->lt_clientid, 8); READ32(lockt->lt_owner.len); READ_BUF(lockt->lt_owner.len); READMEM(lockt->lt_owner.data, lockt->lt_owner.len); DECODE_TAIL;}static __be32nfsd4_decode_locku(struct nfsd4_compoundargs *argp, struct nfsd4_locku *locku){ DECODE_HEAD; locku->lu_stateowner = NULL; READ_BUF(24 + sizeof(stateid_t)); READ32(locku->lu_type); if ((locku->lu_type < NFS4_READ_LT) || (locku->lu_type > NFS4_WRITEW_LT)) goto xdr_error; READ32(locku->lu_seqid); READ32(locku->lu_stateid.si_generation); COPYMEM(&locku->lu_stateid.si_opaque, sizeof(stateid_opaque_t)); READ64(locku->lu_offset); READ64(locku->lu_length); DECODE_TAIL;}static __be32nfsd4_decode_lookup(struct nfsd4_compoundargs *argp, struct nfsd4_lookup *lookup){ DECODE_HEAD; READ_BUF(4); READ32(lookup->lo_len); READ_BUF(lookup->lo_len); SAVEMEM(lookup->lo_name, lookup->lo_len); if ((status = check_filename(lookup->lo_name, lookup->lo_len, nfserr_noent))) return status; DECODE_TAIL;}static __be32nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open){ DECODE_HEAD; memset(open->op_bmval, 0, sizeof(open->op_bmval)); open->op_iattr.ia_valid = 0; open->op_stateowner = NULL; /* seqid, share_access, share_deny, clientid, ownerlen */ READ_BUF(16 + sizeof(clientid_t)); READ32(open->op_seqid); READ32(open->op_share_access); READ32(open->op_share_deny); COPYMEM(&open->op_clientid, sizeof(clientid_t)); READ32(open->op_owner.len); /* owner, open_flag */ READ_BUF(open->op_owner.len + 4); SAVEMEM(open->op_owner.data, open->op_owner.len); READ32(open->op_create); switch (open->op_create) { case NFS4_OPEN_NOCREATE: break; case NFS4_OPEN_CREATE: READ_BUF(4); READ32(open->op_createmode); switch (open->op_createmode) { case NFS4_CREATE_UNCHECKED: case NFS4_CREATE_GUARDED: if ((status = nfsd4_decode_fattr(argp, open->op_bmval, &open->op_iattr, &open->op_acl))) goto out; break; case NFS4_CREATE_EXCLUSIVE: READ_BUF(8); COPYMEM(open->op_verf.data, 8); break; default: goto xdr_error; } break; default: goto xdr_error; } /* open_claim */ READ_BUF(4); READ32(open->op_claim_type); switch (open->op_claim_type) { case NFS4_OPEN_CLAIM_NULL: case NFS4_OPEN_CLAIM_DELEGATE_PREV: READ_BUF(4); READ32(open->op_fname.len); READ_BUF(open->op_fname.len); SAVEMEM(open->op_fname.data, open->op_fname.len); if ((status = check_filename(open->op_fname.data, open->op_fname.len, nfserr_inval))) return status; break; case NFS4_OPEN_CLAIM_PREVIOUS: READ_BUF(4); READ32(open->op_delegate_type); break; case NFS4_OPEN_CLAIM_DELEGATE_CUR: READ_BUF(sizeof(stateid_t) + 4); COPYMEM(&open->op_delegate_stateid, sizeof(stateid_t)); READ32(open->op_fname.len); READ_BUF(open->op_fname.len); SAVEMEM(open->op_fname.data, open->op_fname.len); if ((status = check_filename(open->op_fname.data, open->op_fname.len, nfserr_inval))) return status; break; default: goto xdr_error; } DECODE_TAIL;}static __be32nfsd4_decode_open_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_open_confirm *open_conf){ DECODE_HEAD; open_conf->oc_stateowner = NULL; READ_BUF(4 + sizeof(stateid_t)); READ32(open_conf->oc_req_stateid.si_generation); COPYMEM(&open_conf->oc_req_stateid.si_opaque, sizeof(stateid_opaque_t)); READ32(open_conf->oc_seqid); DECODE_TAIL;}static __be32nfsd4_decode_open_downgrade(struct nfsd4_compoundargs *argp, struct nfsd4_open_downgrade *open_down){ DECODE_HEAD; open_down->od_stateowner = NULL; READ_BUF(12 + sizeof(stateid_t)); READ32(open_down->od_stateid.si_generation); COPYMEM(&open_down->od_stateid.si_opaque, sizeof(stateid_opaque_t)); READ32(open_down->od_seqid); READ32(open_down->od_share_access); READ32(open_down->od_share_deny); DECODE_TAIL;}static __be32nfsd4_decode_putfh(struct nfsd4_compoundargs *argp, struct nfsd4_putfh *putfh){ DECODE_HEAD; READ_BUF(4); READ32(putfh->pf_fhlen); if (putfh->pf_fhlen > NFS4_FHSIZE) goto xdr_error; READ_BUF(putfh->pf_fhlen); SAVEMEM(putfh->pf_fhval, putfh->pf_fhlen); DECODE_TAIL;}static __be32nfsd4_decode_read(struct nfsd4_compoundargs *argp, struct nfsd4_read *read){ DECODE_HEAD; READ_BUF(sizeof(stateid_t) + 12); READ32(read->rd_stateid.si_generation); COPYMEM(&read->rd_stateid.si_opaque, sizeof(stateid_opaque_t)); READ64(read->rd_offset); READ32(read->rd_length); DECODE_TAIL;}static __be32nfsd4_decode_readdir(struct nfsd4_compoundargs *argp, struct nfsd4_readdir *readdir){ DECODE_HEAD; READ_BUF(24); READ64(readdir->rd_cookie); COPYMEM(readdir->rd_verf.data, sizeof(readdir->rd_verf.data)); READ32(readdir->rd_dircount); /* just in case you needed a useless field... */ READ32(readdir->rd_maxcount); if ((status = nfsd4_decode_bitmap(argp, readdir->rd_bmval))) goto out; DECODE_TAIL;}static __be32nfsd4_decode_remove(struct nfsd4_compoundargs *argp, struct nfsd4_remove *remove){ DECODE_HEAD; READ_BUF(4); READ32(remove->rm_namelen); READ_BUF(remove->rm_namelen); SAVEMEM(remove->rm_name, remove->rm_namelen); if ((status = check_filename(remove->rm_name, remove->rm_namelen, nfserr_noent))) return status; DECODE_TAIL;}static __be32nfsd4_decode_rename(struct nfsd4_compoundargs *argp, struct nfsd4_rename *rename){ DECODE_HEAD; READ_BUF(4); READ32(rename->rn_snamelen); READ_BUF(rename->rn_snamelen + 4); SAVEMEM(rename->rn_sname, rename->rn_snamelen); READ32(rename->rn_tnamelen); READ_BUF(rename->rn_tnamelen); SAVEMEM(rename->rn_tname, rename->rn_tnamelen); if ((status = check_filename(rename->rn_sname, rename->rn_snamelen, nfserr_noent))) return status; if ((status = check_filename(rename->rn_tname, rename->rn_tnamelen, nfserr_inval))) return status; DECODE_TAIL;}static __be32nfsd4_decode_renew(struct nfsd4_compoundargs *argp, clientid_t *clientid){ DECODE_HEAD; READ_BUF(sizeof(clientid_t)); COPYMEM(clientid, sizeof(clientid_t)); DECODE_TAIL;}static __be32nfsd4_decode_secinfo(struct nfsd4_compoundargs *argp, struct nfsd4_secinfo *secinfo){ DECODE_HEAD; READ_BUF(4); READ32(secinfo->si_namelen); READ_BUF(secinfo->si_namelen); SAVEMEM(secinfo->si_name, secinfo->si_namelen); status = check_filename(secinfo->si_name, secinfo->si_namelen, nfserr_noent); if (status) return status; DECODE_TAIL;}static __be32nfsd4_decode_setattr(struct nfsd4_compoundargs *argp, struct nfsd4_setattr *setattr){ DECODE_HEAD; READ_BUF(sizeof(stateid_t)); READ32(setattr->sa_stateid.si_generation); COPYMEM(&setattr->sa_stateid.si_opaque, sizeof(stateid_opaque_t)); if ((status = nfsd4_decode_fattr(argp, setattr->sa_bmval, &setattr->sa_iattr, &setattr->sa_acl))) goto out; DECODE_TAIL;}static __be32nfsd4_decode_setclientid(struct nfsd4_compoundargs *argp, struct nfsd4_setclientid *setclientid){ DECODE_HEAD; READ_BUF(12); COPYMEM(setclientid->se_verf.data, 8); READ32(setclientid->se_namelen); READ_BUF(setclientid->se_namelen + 8); SAVEMEM(setclientid->se_name, setclientid->se_namelen); READ32(setclientid->se_callback_prog); READ32(setclientid->se_callback_netid_len); READ_BUF(setclientid->se_callback_netid_len + 4); SAVEMEM(setclientid->se_callback_netid_val, setclientid->se_callback_netid_len); READ32(setclientid->se_callback_addr_len); READ_BUF(setclientid->se_callback_addr_len + 4); SAVEMEM(setclientid->se_callback_addr_val, setclientid->se_callback_addr_len); READ32(setclientid->se_callback_ident); DECODE_TAIL;}static __be32nfsd4_decode_setclientid_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_setclientid_confirm *scd_c){ DECODE_HEAD; READ_BUF(8 + sizeof(nfs4_verifier)); COPYMEM(&scd_c->sc_clientid, 8); COPYMEM(&scd_c->sc_confirm, sizeof(nfs4_verifier)); DECODE_TAIL;}/* Also used for NVERIFY */static __be32nfsd4_decode_verify(struct nfsd4_compoundargs *argp, struct nfsd4_verify *verify){#if 0 struct nfsd4_compoundargs save = { .p = argp->p, .end = argp->end, .rqstp = argp->rqstp, }; u32 ve_bmval[2]; struct iattr ve_iattr; /* request */ struct nfs4_acl *ve_acl; /* request */#endif DECODE_HEAD; if ((status = nfsd4_decode_bitmap(argp, verify->ve_bmval))) goto out; /* For convenience's sake, we compare raw xdr'd attributes in * nfsd4_proc_verify; however we still decode here just to return * correct error in case of bad xdr. */#if 0 status = nfsd4_decode_fattr(ve_bmval, &ve_iattr, &ve_acl); if (status == nfserr_inval) { status = nfserrno(status); goto out; }#endif READ_BUF(4); READ32(verify->ve_attrlen); READ_BUF(verify->ve_attrlen); SAVEMEM(verify->ve_attrval, verify->ve_attrlen); DECODE_TAIL;}static __be32nfsd4_decode_write(struct nfsd4_compoundargs *argp, struct nfsd4_write *write){ int avail; int v; int len; DECODE_HEAD; READ_BUF(sizeof(stateid_opaque_t) + 20); READ32(write->wr_stateid.si_generation); COPYMEM(&write->wr_stateid.si_opaque, sizeof(stateid_opaque_t)); READ64(write->wr_offset); READ32(write->wr_stable_how); if (write->wr_stable_how > 2) goto xdr_error; READ32(write->wr_buflen); /* Sorry .. no magic macros for this.. * * READ_BUF(write->wr_buflen); * SAVEMEM(write->wr_buf, write->wr_buflen); */ avail = (char*)argp->end - (char*)argp->p; if (avail + argp->pagelen < write->wr_buflen) { dprintk("NFSD: xdr error (%s:%d)\n", __FILE__, __LINE__); goto xdr_error; } argp->rqstp->rq_vec[0].iov_base = p; argp->rqstp->rq_vec[0].iov_len = avail; v = 0; len = write->wr_buflen; while (len > argp->rqstp->rq_vec[v].iov_len) { len -= argp->rqstp->rq_vec[v].iov_len; v++; argp->rqstp->rq_vec[v].iov_base = page_address(argp->pagelist[0]); argp->pagelist++; if (argp->pagelen >= PAGE_SIZE) { argp->rqstp->rq_vec[v].iov_len = PAGE_SIZE; argp->pagelen -= PAGE_SIZE; } else { argp->rqstp->rq_vec[v].iov_len = argp->pagelen; argp->pagelen -= len; } } argp->end = (__be32*) (argp->rqstp->rq_vec[v].iov_base + argp->rqstp->rq_vec[v].iov_len); argp->p = (__be32*) (argp->rqstp->rq_vec[v].iov_base + (XDR_QUADLEN(len) << 2)); argp->rqstp->rq_vec[v].iov_len = len; write->wr_vlen = v+1; DECODE_TAIL;}static __be32nfsd4_decode_release_lockowner(struct nfsd4_compoundargs *argp, struct nfsd4_release_lockowner *rlockowner){ DECODE_HEAD; READ_BUF(12); COPYMEM(&rlockowner->rl_clientid, sizeof(clientid_t)); READ32(rlockowner->rl_owner.len); READ_BUF(rlockowner->rl_owner.len); READMEM(rlockowner->rl_owner.data, rlockowner->rl_owner.len); DECODE_TAIL;}static __be32nfsd4_decode_compound(struct nfsd4_compoundargs *argp){ DECODE_HEAD; struct nfsd4_op *op; int i; /* * XXX: According to spec, we should check the tag * for UTF-8 compliance. I'm postponing this for * now because it seems that some clients do use * binary tags. */ READ_BUF(4); READ32(argp->taglen); READ_BUF(argp->taglen + 8); SAVEMEM(argp->tag, argp->taglen); READ32(argp->minorversion); READ32(argp->opcnt); if (argp->taglen > NFSD4_MAX_TAGLEN) goto xdr_error; if (argp->opcnt > 100) goto xdr_error; if (argp->opcnt > ARRAY_SIZE(argp->iops)) { argp->ops = kmalloc(argp->opcnt * sizeof(*argp->ops), GFP_KERNEL); if (!argp->ops) { argp->ops = argp->iops; dprintk("nfsd: couldn't allocate room for COMPOUND\n"); goto xdr_error; } } for (i = 0; i < argp->opcnt; i++) { op = &argp->ops[i]; op->replay = NULL; /* * We can't use READ_BUF() here because we need to handle * a missing opcode as an OP_WRITE + 1. So we need to check * to see if we're truly at the end of our buffer or if there * is another page we need to flip to. */ if (argp->p == argp->end) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -