📄 nfs4xdr.c
字号:
RESERVE_SPACE(4); switch(arg->open_flags & O_EXCL) { case 0: WRITE32(NFS4_CREATE_UNCHECKED); encode_attrs(xdr, arg->u.attrs, arg->server); break; default: WRITE32(NFS4_CREATE_EXCLUSIVE); encode_nfs4_verifier(xdr, &arg->u.verifier); }}static void encode_opentype(struct xdr_stream *xdr, const struct nfs_openargs *arg){ __be32 *p; RESERVE_SPACE(4); switch (arg->open_flags & O_CREAT) { case 0: WRITE32(NFS4_OPEN_NOCREATE); break; default: BUG_ON(arg->claim != NFS4_OPEN_CLAIM_NULL); WRITE32(NFS4_OPEN_CREATE); encode_createmode(xdr, arg); }}static inline void encode_delegation_type(struct xdr_stream *xdr, int delegation_type){ __be32 *p; RESERVE_SPACE(4); switch (delegation_type) { case 0: WRITE32(NFS4_OPEN_DELEGATE_NONE); break; case FMODE_READ: WRITE32(NFS4_OPEN_DELEGATE_READ); break; case FMODE_WRITE|FMODE_READ: WRITE32(NFS4_OPEN_DELEGATE_WRITE); break; default: BUG(); }}static inline void encode_claim_null(struct xdr_stream *xdr, const struct qstr *name){ __be32 *p; RESERVE_SPACE(4); WRITE32(NFS4_OPEN_CLAIM_NULL); encode_string(xdr, name->len, name->name);}static inline void encode_claim_previous(struct xdr_stream *xdr, int type){ __be32 *p; RESERVE_SPACE(4); WRITE32(NFS4_OPEN_CLAIM_PREVIOUS); encode_delegation_type(xdr, type);}static inline void encode_claim_delegate_cur(struct xdr_stream *xdr, const struct qstr *name, const nfs4_stateid *stateid){ __be32 *p; RESERVE_SPACE(4+NFS4_STATEID_SIZE); WRITE32(NFS4_OPEN_CLAIM_DELEGATE_CUR); WRITEMEM(stateid->data, NFS4_STATEID_SIZE); encode_string(xdr, name->len, name->name);}static int encode_open(struct xdr_stream *xdr, const struct nfs_openargs *arg){ encode_openhdr(xdr, arg); encode_opentype(xdr, arg); switch (arg->claim) { case NFS4_OPEN_CLAIM_NULL: encode_claim_null(xdr, arg->name); break; case NFS4_OPEN_CLAIM_PREVIOUS: encode_claim_previous(xdr, arg->u.delegation_type); break; case NFS4_OPEN_CLAIM_DELEGATE_CUR: encode_claim_delegate_cur(xdr, arg->name, &arg->u.delegation); break; default: BUG(); } return 0;}static int encode_open_confirm(struct xdr_stream *xdr, const struct nfs_open_confirmargs *arg){ __be32 *p; RESERVE_SPACE(4+NFS4_STATEID_SIZE+4); WRITE32(OP_OPEN_CONFIRM); WRITEMEM(arg->stateid->data, NFS4_STATEID_SIZE); WRITE32(arg->seqid->sequence->counter); return 0;}static int encode_open_downgrade(struct xdr_stream *xdr, const struct nfs_closeargs *arg){ __be32 *p; RESERVE_SPACE(4+NFS4_STATEID_SIZE+4); WRITE32(OP_OPEN_DOWNGRADE); WRITEMEM(arg->stateid->data, NFS4_STATEID_SIZE); WRITE32(arg->seqid->sequence->counter); encode_share_access(xdr, arg->open_flags); return 0;}static intencode_putfh(struct xdr_stream *xdr, const struct nfs_fh *fh){ int len = fh->size; __be32 *p; RESERVE_SPACE(8 + len); WRITE32(OP_PUTFH); WRITE32(len); WRITEMEM(fh->data, len); return 0;}static int encode_putrootfh(struct xdr_stream *xdr){ __be32 *p; RESERVE_SPACE(4); WRITE32(OP_PUTROOTFH); return 0;}static void encode_stateid(struct xdr_stream *xdr, const struct nfs_open_context *ctx){ nfs4_stateid stateid; __be32 *p; RESERVE_SPACE(NFS4_STATEID_SIZE); if (ctx->state != NULL) { nfs4_copy_stateid(&stateid, ctx->state, ctx->lockowner); WRITEMEM(stateid.data, NFS4_STATEID_SIZE); } else WRITEMEM(zero_stateid.data, NFS4_STATEID_SIZE);}static int encode_read(struct xdr_stream *xdr, const struct nfs_readargs *args){ __be32 *p; RESERVE_SPACE(4); WRITE32(OP_READ); encode_stateid(xdr, args->context); RESERVE_SPACE(12); WRITE64(args->offset); WRITE32(args->count); return 0;}static int encode_readdir(struct xdr_stream *xdr, const struct nfs4_readdir_arg *readdir, struct rpc_rqst *req){ uint32_t attrs[2] = { FATTR4_WORD0_RDATTR_ERROR|FATTR4_WORD0_FILEID, FATTR4_WORD1_MOUNTED_ON_FILEID, }; __be32 *p; RESERVE_SPACE(12+NFS4_VERIFIER_SIZE+20); WRITE32(OP_READDIR); WRITE64(readdir->cookie); WRITEMEM(readdir->verifier.data, NFS4_VERIFIER_SIZE); WRITE32(readdir->count >> 1); /* We're not doing readdirplus */ WRITE32(readdir->count); WRITE32(2); /* Switch to mounted_on_fileid if the server supports it */ if (readdir->bitmask[1] & FATTR4_WORD1_MOUNTED_ON_FILEID) attrs[0] &= ~FATTR4_WORD0_FILEID; else attrs[1] &= ~FATTR4_WORD1_MOUNTED_ON_FILEID; WRITE32(attrs[0] & readdir->bitmask[0]); WRITE32(attrs[1] & readdir->bitmask[1]); dprintk("%s: cookie = %Lu, verifier = 0x%x%x, bitmap = 0x%x%x\n", __FUNCTION__, (unsigned long long)readdir->cookie, ((u32 *)readdir->verifier.data)[0], ((u32 *)readdir->verifier.data)[1], attrs[0] & readdir->bitmask[0], attrs[1] & readdir->bitmask[1]); return 0;}static int encode_readlink(struct xdr_stream *xdr, const struct nfs4_readlink *readlink, struct rpc_rqst *req){ __be32 *p; RESERVE_SPACE(4); WRITE32(OP_READLINK); return 0;}static int encode_remove(struct xdr_stream *xdr, const struct qstr *name){ __be32 *p; RESERVE_SPACE(8 + name->len); WRITE32(OP_REMOVE); WRITE32(name->len); WRITEMEM(name->name, name->len); return 0;}static int encode_rename(struct xdr_stream *xdr, const struct qstr *oldname, const struct qstr *newname){ __be32 *p; RESERVE_SPACE(8 + oldname->len); WRITE32(OP_RENAME); WRITE32(oldname->len); WRITEMEM(oldname->name, oldname->len); RESERVE_SPACE(4 + newname->len); WRITE32(newname->len); WRITEMEM(newname->name, newname->len); return 0;}static int encode_renew(struct xdr_stream *xdr, const struct nfs_client *client_stateid){ __be32 *p; RESERVE_SPACE(12); WRITE32(OP_RENEW); WRITE64(client_stateid->cl_clientid); return 0;}static intencode_restorefh(struct xdr_stream *xdr){ __be32 *p; RESERVE_SPACE(4); WRITE32(OP_RESTOREFH); return 0;}static intencode_setacl(struct xdr_stream *xdr, struct nfs_setaclargs *arg){ __be32 *p; RESERVE_SPACE(4+NFS4_STATEID_SIZE); WRITE32(OP_SETATTR); WRITEMEM(zero_stateid.data, NFS4_STATEID_SIZE); RESERVE_SPACE(2*4); WRITE32(1); WRITE32(FATTR4_WORD0_ACL); if (arg->acl_len % 4) return -EINVAL; RESERVE_SPACE(4); WRITE32(arg->acl_len); xdr_write_pages(xdr, arg->acl_pages, arg->acl_pgbase, arg->acl_len); return 0;}static intencode_savefh(struct xdr_stream *xdr){ __be32 *p; RESERVE_SPACE(4); WRITE32(OP_SAVEFH); return 0;}static int encode_setattr(struct xdr_stream *xdr, const struct nfs_setattrargs *arg, const struct nfs_server *server){ int status; __be32 *p; RESERVE_SPACE(4+NFS4_STATEID_SIZE); WRITE32(OP_SETATTR); WRITEMEM(arg->stateid.data, NFS4_STATEID_SIZE); if ((status = encode_attrs(xdr, arg->iap, server))) return status; return 0;}static int encode_setclientid(struct xdr_stream *xdr, const struct nfs4_setclientid *setclientid){ __be32 *p; RESERVE_SPACE(4 + NFS4_VERIFIER_SIZE); WRITE32(OP_SETCLIENTID); WRITEMEM(setclientid->sc_verifier->data, NFS4_VERIFIER_SIZE); encode_string(xdr, setclientid->sc_name_len, setclientid->sc_name); RESERVE_SPACE(4); WRITE32(setclientid->sc_prog); encode_string(xdr, setclientid->sc_netid_len, setclientid->sc_netid); encode_string(xdr, setclientid->sc_uaddr_len, setclientid->sc_uaddr); RESERVE_SPACE(4); WRITE32(setclientid->sc_cb_ident); return 0;}static int encode_setclientid_confirm(struct xdr_stream *xdr, const struct nfs_client *client_state){ __be32 *p; RESERVE_SPACE(12 + NFS4_VERIFIER_SIZE); WRITE32(OP_SETCLIENTID_CONFIRM); WRITE64(client_state->cl_clientid); WRITEMEM(client_state->cl_confirm.data, NFS4_VERIFIER_SIZE); return 0;}static int encode_write(struct xdr_stream *xdr, const struct nfs_writeargs *args){ __be32 *p; RESERVE_SPACE(4); WRITE32(OP_WRITE); encode_stateid(xdr, args->context); RESERVE_SPACE(16); WRITE64(args->offset); WRITE32(args->stable); WRITE32(args->count); xdr_write_pages(xdr, args->pages, args->pgbase, args->count); return 0;}static int encode_delegreturn(struct xdr_stream *xdr, const nfs4_stateid *stateid){ __be32 *p; RESERVE_SPACE(4+NFS4_STATEID_SIZE); WRITE32(OP_DELEGRETURN); WRITEMEM(stateid->data, NFS4_STATEID_SIZE); return 0;}/* * END OF "GENERIC" ENCODE ROUTINES. *//* * Encode an ACCESS request */static int nfs4_xdr_enc_access(struct rpc_rqst *req, __be32 *p, const struct nfs4_accessargs *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 != 0) goto out; status = encode_access(&xdr, args->access); if (status != 0) goto out; status = encode_getfattr(&xdr, args->bitmask);out: return status;}/* * Encode LOOKUP request */static int nfs4_xdr_enc_lookup(struct rpc_rqst *req, __be32 *p, const struct nfs4_lookup_arg *args){ struct xdr_stream xdr; struct compound_hdr hdr = { .nops = 4, }; 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_getfh(&xdr)) != 0) goto out; status = encode_getfattr(&xdr, args->bitmask);out: return status;}/* * Encode LOOKUP_ROOT request */static int nfs4_xdr_enc_lookup_root(struct rpc_rqst *req, __be32 *p, const struct nfs4_lookup_root_arg *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); if ((status = encode_putrootfh(&xdr)) != 0) goto out; if ((status = encode_getfh(&xdr)) == 0) status = encode_getfattr(&xdr, args->bitmask);out: return status;}/* * Encode REMOVE request */static int nfs4_xdr_enc_remove(struct rpc_rqst *req, __be32 *p, const struct nfs_removeargs *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); if ((status = encode_putfh(&xdr, args->fh)) != 0) goto out; if ((status = encode_remove(&xdr, &args->name)) != 0) goto out; status = encode_getfattr(&xdr, args->bitmask);out: return status;}/* * Encode RENAME request */static int nfs4_xdr_enc_rename(struct rpc_rqst *req, __be32 *p, const struct nfs4_rename_arg *args){ struct xdr_stream xdr; struct compound_hdr hdr = { .nops = 7, }; int status; xdr_init_encode(&xdr, &req->rq_snd_buf, p); encode_compound_hdr(&xdr, &hdr); if ((status = encode_putfh(&xdr, args->old_dir)) != 0) goto out; if ((status = encode_savefh(&xdr)) != 0) goto out; if ((status = encode_putfh(&xdr, args->new_dir)) != 0) goto out; if ((status = encode_rename(&xdr, args->old_name, args->new_name)) != 0) goto out; if ((status = encode_getfattr(&xdr, args->bitmask)) != 0) goto out; if ((status = encode_restorefh(&xdr)) != 0) goto out; status = encode_getfattr(&xdr, args->bitmask);out: return status;}/*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -