📄 nfs4xdr.c
字号:
* Encode a READLINK request */static int nfs4_xdr_enc_readlink(struct rpc_rqst *req, uint32_t *p, const struct nfs4_readlink *args){ struct xdr_stream xdr; struct compound_hdr hdr = { .nops = 2, }; int status; xdr_init_encode(&xdr, &req->rq_snd_buf, p); encode_compound_hdr(&xdr, &hdr); status = encode_putfh(&xdr, args->fh); if(status) goto out; status = encode_readlink(&xdr, args, req);out: return status;}/* * Encode a READDIR request */static int nfs4_xdr_enc_readdir(struct rpc_rqst *req, uint32_t *p, const struct nfs4_readdir_arg *args){ struct xdr_stream xdr; struct compound_hdr hdr = { .nops = 2, }; int status; xdr_init_encode(&xdr, &req->rq_snd_buf, p); encode_compound_hdr(&xdr, &hdr); status = encode_putfh(&xdr, args->fh); if(status) goto out; status = encode_readdir(&xdr, args, req);out: return status;}/* * Encode a READ request */static int nfs4_xdr_enc_read(struct rpc_rqst *req, uint32_t *p, struct nfs_readargs *args){ struct rpc_auth *auth = req->rq_task->tk_auth; struct xdr_stream xdr; struct compound_hdr hdr = { .nops = 2, }; int replen, status; xdr_init_encode(&xdr, &req->rq_snd_buf, p); encode_compound_hdr(&xdr, &hdr); status = encode_putfh(&xdr, args->fh); if (status) goto out; status = encode_read(&xdr, args); if (status) goto out; /* set up reply kvec * toplevel status + taglen=0 + rescount + OP_PUTFH + status * + OP_READ + status + eof + datalen = 9 */ replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS4_dec_read_sz) << 2; xdr_inline_pages(&req->rq_rcv_buf, replen, args->pages, args->pgbase, args->count);out: return status;}/* * Encode an SETATTR request */static int nfs4_xdr_enc_setattr(struct rpc_rqst *req, uint32_t *p, struct nfs_setattrargs *args){ struct xdr_stream xdr; struct compound_hdr hdr = { .nops = 3, }; int status; xdr_init_encode(&xdr, &req->rq_snd_buf, p); encode_compound_hdr(&xdr, &hdr); status = encode_putfh(&xdr, args->fh); if(status) goto out; status = encode_setattr(&xdr, args, args->server); if(status) goto out; status = encode_getfattr(&xdr, args->bitmask);out: return status;}/* * Encode a WRITE request */static int nfs4_xdr_enc_write(struct rpc_rqst *req, uint32_t *p, struct nfs_writeargs *args){ struct xdr_stream xdr; struct compound_hdr hdr = { .nops = 2, }; int status; xdr_init_encode(&xdr, &req->rq_snd_buf, p); encode_compound_hdr(&xdr, &hdr); status = encode_putfh(&xdr, args->fh); if (status) goto out; status = encode_write(&xdr, args);out: return status;}/* * a COMMIT request */static int nfs4_xdr_enc_commit(struct rpc_rqst *req, uint32_t *p, struct nfs_writeargs *args){ struct xdr_stream xdr; struct compound_hdr hdr = { .nops = 2, }; int status; xdr_init_encode(&xdr, &req->rq_snd_buf, p); encode_compound_hdr(&xdr, &hdr); status = encode_putfh(&xdr, args->fh); if (status) goto out; status = encode_commit(&xdr, args);out: return status;}/* * FSINFO request */static int nfs4_xdr_enc_fsinfo(struct rpc_rqst *req, uint32_t *p, struct nfs4_fsinfo_arg *args){ struct xdr_stream xdr; struct compound_hdr hdr = { .nops = 2, }; int status; xdr_init_encode(&xdr, &req->rq_snd_buf, p); encode_compound_hdr(&xdr, &hdr); status = encode_putfh(&xdr, args->fh); if (!status) status = encode_fsinfo(&xdr, args->bitmask); return status;}/* * a PATHCONF request */static int nfs4_xdr_enc_pathconf(struct rpc_rqst *req, uint32_t *p, const struct nfs4_pathconf_arg *args){ extern u32 nfs4_pathconf_bitmap[2]; struct xdr_stream xdr; struct compound_hdr hdr = { .nops = 2, }; int status; xdr_init_encode(&xdr, &req->rq_snd_buf, p); encode_compound_hdr(&xdr, &hdr); status = encode_putfh(&xdr, args->fh); if (!status) status = encode_getattr_one(&xdr, args->bitmask[0] & nfs4_pathconf_bitmap[0]); return status;}/* * a STATFS request */static int nfs4_xdr_enc_statfs(struct rpc_rqst *req, uint32_t *p, const struct nfs4_statfs_arg *args){ extern u32 nfs4_statfs_bitmap[]; struct xdr_stream xdr; struct compound_hdr hdr = { .nops = 2, }; int status; xdr_init_encode(&xdr, &req->rq_snd_buf, p); encode_compound_hdr(&xdr, &hdr); status = encode_putfh(&xdr, args->fh); if (status == 0) status = encode_getattr_two(&xdr, args->bitmask[0] & nfs4_statfs_bitmap[0], args->bitmask[1] & nfs4_statfs_bitmap[1]); return status;}/* * GETATTR_BITMAP request */static int nfs4_xdr_enc_server_caps(struct rpc_rqst *req, uint32_t *p, const struct nfs_fh *fhandle){ struct xdr_stream xdr; struct compound_hdr hdr = { .nops = 2, }; int status; xdr_init_encode(&xdr, &req->rq_snd_buf, p); encode_compound_hdr(&xdr, &hdr); status = encode_putfh(&xdr, fhandle); if (status == 0) status = encode_getattr_one(&xdr, FATTR4_WORD0_SUPPORTED_ATTRS| FATTR4_WORD0_LINK_SUPPORT| FATTR4_WORD0_SYMLINK_SUPPORT| FATTR4_WORD0_ACLSUPPORT); return status;}/* * a RENEW request */static int nfs4_xdr_enc_renew(struct rpc_rqst *req, uint32_t *p, struct nfs4_client *clp){ struct xdr_stream xdr; struct compound_hdr hdr = { .nops = 1, }; xdr_init_encode(&xdr, &req->rq_snd_buf, p); encode_compound_hdr(&xdr, &hdr); return encode_renew(&xdr, clp);}/* * a SETCLIENTID request */static int nfs4_xdr_enc_setclientid(struct rpc_rqst *req, uint32_t *p, struct nfs4_setclientid *sc){ struct xdr_stream xdr; struct compound_hdr hdr = { .nops = 1, }; xdr_init_encode(&xdr, &req->rq_snd_buf, p); encode_compound_hdr(&xdr, &hdr); return encode_setclientid(&xdr, sc);}/* * a SETCLIENTID_CONFIRM request */static int nfs4_xdr_enc_setclientid_confirm(struct rpc_rqst *req, uint32_t *p, struct nfs4_client *clp){ struct xdr_stream xdr; struct compound_hdr hdr = { .nops = 3, }; const u32 lease_bitmap[2] = { FATTR4_WORD0_LEASE_TIME, 0 }; int status; xdr_init_encode(&xdr, &req->rq_snd_buf, p); encode_compound_hdr(&xdr, &hdr); status = encode_setclientid_confirm(&xdr, clp); if (!status) status = encode_putrootfh(&xdr); if (!status) status = encode_fsinfo(&xdr, lease_bitmap); return status;}/* * DELEGRETURN request */static int nfs4_xdr_enc_delegreturn(struct rpc_rqst *req, uint32_t *p, const struct nfs4_delegreturnargs *args){ struct xdr_stream xdr; struct compound_hdr hdr = { .nops = 2, }; int status; xdr_init_encode(&xdr, &req->rq_snd_buf, p); encode_compound_hdr(&xdr, &hdr); if ((status = encode_putfh(&xdr, args->fhandle)) == 0) status = encode_delegreturn(&xdr, args->stateid); return status;}/* * START OF "GENERIC" DECODE ROUTINES. * These may look a little ugly since they are imported from a "generic" * set of XDR encode/decode routines which are intended to be shared by * all of our NFSv4 implementations (OpenBSD, MacOS X...). * * If the pain of reading these is too great, it should be a straightforward * task to translate them into Linux-specific versions which are more * consistent with the style used in NFSv2/v3... */#define READ32(x) (x) = ntohl(*p++)#define READ64(x) do { \ (x) = (u64)ntohl(*p++) << 32; \ (x) |= ntohl(*p++); \} while (0)#define READTIME(x) do { \ p++; \ (x.tv_sec) = ntohl(*p++); \ (x.tv_nsec) = ntohl(*p++); \} while (0)#define COPYMEM(x,nbytes) do { \ memcpy((x), p, nbytes); \ p += XDR_QUADLEN(nbytes); \} while (0)#define READ_BUF(nbytes) do { \ p = xdr_inline_decode(xdr, nbytes); \ if (!p) { \ printk(KERN_WARNING "%s: reply buffer overflowed in line %d.", \ __FUNCTION__, __LINE__); \ return -EIO; \ } \} while (0)static int decode_opaque_inline(struct xdr_stream *xdr, uint32_t *len, char **string){ uint32_t *p; READ_BUF(4); READ32(*len); READ_BUF(*len); *string = (char *)p; return 0;}static int decode_compound_hdr(struct xdr_stream *xdr, struct compound_hdr *hdr){ uint32_t *p; READ_BUF(8); READ32(hdr->status); READ32(hdr->taglen); READ_BUF(hdr->taglen + 4); hdr->tag = (char *)p; p += XDR_QUADLEN(hdr->taglen); READ32(hdr->nops); return 0;}static int decode_op_hdr(struct xdr_stream *xdr, enum nfs_opnum4 expected){ uint32_t *p; uint32_t opnum; int32_t nfserr; READ_BUF(8); READ32(opnum); if (opnum != expected) { printk(KERN_NOTICE "nfs4_decode_op_hdr: Server returned operation" " %d but we issued a request for %d\n", opnum, expected); return -EIO; } READ32(nfserr); if (nfserr != NFS_OK) return -nfs_stat_to_errno(nfserr); return 0;}/* Dummy routine */static int decode_ace(struct xdr_stream *xdr, void *ace, struct nfs4_client *clp){ uint32_t *p; uint32_t strlen; char *str; READ_BUF(12); return decode_opaque_inline(xdr, &strlen, &str);}static int decode_attr_bitmap(struct xdr_stream *xdr, uint32_t *bitmap){ uint32_t bmlen, *p; READ_BUF(4); READ32(bmlen); bitmap[0] = bitmap[1] = 0; READ_BUF((bmlen << 2)); if (bmlen > 0) { READ32(bitmap[0]); if (bmlen > 1) READ32(bitmap[1]); } return 0;}static inline int decode_attr_length(struct xdr_stream *xdr, uint32_t *attrlen, uint32_t **savep){ uint32_t *p; READ_BUF(4); READ32(*attrlen); *savep = xdr->p; return 0;}static int decode_attr_supported(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *bitmask){ if (likely(bitmap[0] & FATTR4_WORD0_SUPPORTED_ATTRS)) { decode_attr_bitmap(xdr, bitmask); bitmap[0] &= ~FATTR4_WORD0_SUPPORTED_ATTRS; } else bitmask[0] = bitmask[1] = 0; dprintk("%s: bitmask=0x%x%x\n", __FUNCTION__, bitmask[0], bitmask[1]); return 0;}static int decode_attr_type(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *type){ uint32_t *p; *type = 0; if (unlikely(bitmap[0] & (FATTR4_WORD0_TYPE - 1U))) return -EIO; if (likely(bitmap[0] & FATTR4_WORD0_TYPE)) { READ_BUF(4); READ32(*type); if (*type < NF4REG || *type > NF4NAMEDATTR) { dprintk("%s: bad type %d\n", __FUNCTION__, *type); return -EIO; } bitmap[0] &= ~FATTR4_WORD0_TYPE; } dprintk("%s: type=0%o\n", __FUNCTION__, nfs_type2fmt[*type].nfs2type); return 0;}static int decode_attr_change(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *change){ uint32_t *p; *change = 0; if (unlikely(bitmap[0] & (FATTR4_WORD0_CHANGE - 1U))) return -EIO; if (likely(bitmap[0] & FATTR4_WORD0_CHANGE)) { READ_BUF(8); READ64(*change); bitmap[0] &= ~FATTR4_WORD0_CHANGE; } dprintk("%s: change attribute=%Lu\n", __FUNCTION__, (unsigned long long)*change); return 0;}static int decode_attr_size(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *size){ uint32_t *p; *size = 0; if (unlikely(bitmap[0] & (FATTR4_WORD0_SIZE - 1U))) return -EIO; if (likely(bitmap[0] & FATTR4_WORD0_SIZE)) { READ_BUF(8); READ64(*size); bitmap[0] &= ~FATTR4_WORD0_SIZE; } dprintk("%s: file size=%Lu\n", __FUNCTION__, (unsigned long long)*size); return 0;}static int decode_attr_link_support(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res){ uint32_t *p; *res = 0; if (unlikely(bitmap[0] & (FATTR4_WORD0_LINK_SUPPORT - 1U))) return -EIO; if (likely(bitmap[0] & FATTR4_WORD0_LINK_SUPPORT)) { READ_BUF(4); READ32(*res); bitmap[0] &= ~FATTR4_WORD0_LINK_SUPPORT; } dprintk("%s: link support=%s\n", __FUNCTION__, *res == 0 ? "false" : "true"); return 0;}static int decode_attr_symlink_support(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res){ uint32_t *p; *res = 0; if (unlikely(bitmap[0] & (FATTR4_WORD0_SYMLINK_SUPPORT - 1U))) return -EIO; if (likely(bitmap[0] & FATTR4_WORD0_SYMLINK_SUPPORT)) { READ_BUF(4); READ32(*res); bitmap[0] &= ~FATTR4_WORD0_SYMLINK_SUPPORT; } dprintk("%s: symlink support=%s\n", __FUNCTION__, *res == 0 ? "false" : "true"); return 0;}static int decode_attr_fsid(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs4_fsid *fsid)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -