📄 nfs4xdr.c
字号:
/* * a PATHCONF request */static int nfs4_xdr_enc_pathconf(struct rpc_rqst *req, __be32 *p, const struct nfs4_pathconf_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_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, __be32 *p, const struct nfs4_statfs_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 == 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, __be32 *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, __be32 *p, struct nfs_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, __be32 *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, __be32 *p, struct nfs_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, __be32 *p, const struct nfs4_delegreturnargs *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->fhandle); if (status != 0) goto out; status = encode_delegreturn(&xdr, args->stateid); if (status != 0) goto out; status = encode_getfattr(&xdr, args->bitmask);out: return status;}/* * Encode FS_LOCATIONS request */static int nfs4_xdr_enc_fs_locations(struct rpc_rqst *req, __be32 *p, struct nfs4_fs_locations_arg *args){ struct xdr_stream xdr; struct compound_hdr hdr = { .nops = 3, }; struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth; int replen; int status; xdr_init_encode(&xdr, &req->rq_snd_buf, p); encode_compound_hdr(&xdr, &hdr); if ((status = encode_putfh(&xdr, args->dir_fh)) != 0) goto out; if ((status = encode_lookup(&xdr, args->name)) != 0) goto out; if ((status = encode_fs_locations(&xdr, args->bitmask)) != 0) goto out; /* set up reply * toplevel_status + OP_PUTFH + status * + OP_LOOKUP + status + OP_GETATTR + status = 7 */ replen = (RPC_REPHDRSIZE + auth->au_rslack + 7) << 2; xdr_inline_pages(&req->rq_rcv_buf, replen, &args->page, 0, PAGE_SIZE);out: 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 (unlikely(!p)) { \ dprintk("nfs: %s: prematurely hit end of receive" \ " buffer\n", __FUNCTION__); \ dprintk("nfs: %s: xdr->p=%p, bytes=%u, xdr->end=%p\n", \ __FUNCTION__, xdr->p, nbytes, xdr->end); \ return -EIO; \ } \} while (0)static int decode_opaque_inline(struct xdr_stream *xdr, unsigned int *len, char **string){ __be32 *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){ __be32 *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){ __be32 *p; uint32_t opnum; int32_t nfserr; READ_BUF(8); READ32(opnum); if (opnum != expected) { dprintk("nfs: Server returned operation" " %d but we issued a request for %d\n", opnum, expected); return -EIO; } READ32(nfserr); if (nfserr != NFS_OK) return -nfs4_stat_to_errno(nfserr); return 0;}/* Dummy routine */static int decode_ace(struct xdr_stream *xdr, void *ace, struct nfs_client *clp){ __be32 *p; unsigned int 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; __be32 *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, __be32 **savep){ __be32 *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){ __be32 *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){ __be32 *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){ __be32 *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){ __be32 *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){ __be32 *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 nfs_fsid *fsid){ __be32 *p; fsid->major = 0; fsid->minor = 0; if (unlikely(bitmap[0] & (FATTR4_WORD0_FSID - 1U))) return -EIO; if (likely(bitmap[0] & FATTR4_WORD0_FSID)) { READ_BUF(16); READ64(fsid->major); READ64(fsid->minor); bitmap[0] &= ~FATTR4_WORD0_FSID; } dprintk("%s: fsid=(0x%Lx/0x%Lx)\n", __FUNCTION__, (unsigned long long)fsid->major, (unsigned long long)fsid->minor); return 0;}static int decode_attr_lease_time(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res){ __be32 *p; *res = 60; if (unlikely(bitmap[0] & (FATTR4_WORD0_LEASE_TIME - 1U))) return -EIO; if (likely(bitmap[0] & FATTR4_WORD0_LEASE_TIME)) { READ_BUF(4); READ32(*res); bitmap[0] &= ~FATTR4_WORD0_LEASE_TIME; } dprintk("%s: file size=%u\n", __FUNCTION__, (unsigned int)*res); return 0;}static int decode_attr_aclsupport(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res){ __be32 *p; *res = ACL4_SUPPORT_ALLOW_ACL|ACL4_SUPPORT_DENY_ACL; if (unlikely(bitmap[0] & (FATTR4_WORD0_ACLSUPPORT - 1U))) return -EIO; if (likely(bitmap[0] & FATTR4_WORD0_ACLSUPPORT)) { READ_BUF(4); READ32(*res); bitmap[0] &= ~FATTR4_WORD0_ACLSUPPORT; } dprintk("%s: ACLs supported=%u\n", __FUNCTION__, (unsigned int)*res); return 0;}static int decode_attr_fileid(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *fileid){ __be32 *p; *fileid = 0; if (unlikely(bitmap[0] & (FATTR4_WORD0_FILEID - 1U))) return -EIO; if (likely(bitmap[0] & FATTR4_WORD0_FILEID)) { READ_BUF(8); READ64(*fileid); bitmap[0] &= ~FATTR4_WORD0_FILEID; } dprintk("%s: fileid=%Lu\n", __FUNCTION__, (unsigned long long)*fileid); return 0;}static int decode_attr_mounted_on_fileid(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *fileid){ __be32 *p; *fileid = 0; if (unlikely(bitmap[1] & (FATTR4_WORD1_MOUNTED_ON_FILEID - 1U))) return -EIO; if (likely(bitmap[1] & FATTR4_WORD1_MOUNTED_ON_FILEID)) { READ_BUF(8); READ64(*fileid); bitmap[1] &= ~FATTR4_WORD1_MOUNTED_ON_FILEID; } dprintk("%s: fileid=%Lu\n", __FUNCTION__, (unsigned long long)*fileid); return 0;}static int decode_attr_files_avail(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res){ __be32 *p; int status = 0; *res = 0; if (unlikely(bitmap[0] & (FATTR4_WORD0_FILES_AVAIL - 1U))) return -EIO; if (likely(bitmap[0] & FATTR4_WORD0_FILES_AVAIL)) { READ_BUF(8); READ64(*res); bitmap[0] &= ~FATTR4_WORD0_FILES_AVAIL; } dprintk("%s: files avail=%Lu\n", __FUNCTION__, (unsigned long long)*res); return status;}static int decode_attr_files_free(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res){ __be32 *p; int status = 0; *res = 0; if (unlikely(bitmap[0] & (FATTR4_WORD0_F
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -