Newer
Older
}
if (iap->ia_valid & ATTR_MODE) {
bmval1 |= FATTR4_WORD1_MODE;
*p++ = cpu_to_be32(iap->ia_mode & S_IALLUGO);
}
if (iap->ia_valid & ATTR_UID) {
bmval1 |= FATTR4_WORD1_OWNER;

Benny Halevy
committed
p = xdr_encode_opaque(p, owner_name, owner_namelen);
}
if (iap->ia_valid & ATTR_GID) {
bmval1 |= FATTR4_WORD1_OWNER_GROUP;

Benny Halevy
committed
p = xdr_encode_opaque(p, owner_group, owner_grouplen);
}
if (iap->ia_valid & ATTR_ATIME_SET) {
bmval1 |= FATTR4_WORD1_TIME_ACCESS_SET;
*p++ = cpu_to_be32(NFS4_SET_TO_CLIENT_TIME);
*p++ = cpu_to_be32(0);
*p++ = cpu_to_be32(iap->ia_atime.tv_sec);
*p++ = cpu_to_be32(iap->ia_atime.tv_nsec);
}
else if (iap->ia_valid & ATTR_ATIME) {
bmval1 |= FATTR4_WORD1_TIME_ACCESS_SET;
*p++ = cpu_to_be32(NFS4_SET_TO_SERVER_TIME);
}
if (iap->ia_valid & ATTR_MTIME_SET) {
bmval1 |= FATTR4_WORD1_TIME_MODIFY_SET;
*p++ = cpu_to_be32(NFS4_SET_TO_CLIENT_TIME);
*p++ = cpu_to_be32(0);
*p++ = cpu_to_be32(iap->ia_mtime.tv_sec);
*p++ = cpu_to_be32(iap->ia_mtime.tv_nsec);
}
else if (iap->ia_valid & ATTR_MTIME) {
bmval1 |= FATTR4_WORD1_TIME_MODIFY_SET;
*p++ = cpu_to_be32(NFS4_SET_TO_SERVER_TIME);
/*
* Now we backfill the bitmap and the attribute buffer length.
*/
if (len != ((char *)p - (char *)q) + 4) {
printk(KERN_ERR "NFS: Attr length error, %u != %Zu\n",
len, ((char *)p - (char *)q) + 4);
BUG();
}
len = (char *)p - (char *)q - 12;
*q++ = htonl(bmval0);
*q++ = htonl(bmval1);
static void encode_access(struct xdr_stream *xdr, u32 access, struct compound_hdr *hdr)
p = reserve_space(xdr, 8);
hdr->replen += decode_access_maxsz;
static void encode_close(struct xdr_stream *xdr, const struct nfs_closeargs *arg, struct compound_hdr *hdr)
p = reserve_space(xdr, 8+NFS4_STATEID_SIZE);
*p++ = cpu_to_be32(OP_CLOSE);
*p++ = cpu_to_be32(arg->seqid->sequence->counter);
xdr_encode_opaque_fixed(p, arg->stateid->data, NFS4_STATEID_SIZE);
hdr->replen += decode_close_maxsz;
static void encode_commit(struct xdr_stream *xdr, const struct nfs_writeargs *args, struct compound_hdr *hdr)
p = reserve_space(xdr, 16);
*p = cpu_to_be32(args->count);
hdr->replen += decode_commit_maxsz;
static void encode_create(struct xdr_stream *xdr, const struct nfs4_create_arg *create, struct compound_hdr *hdr)
p = reserve_space(xdr, 8);
*p = cpu_to_be32(create->ftype);
p = reserve_space(xdr, 4);
*p = cpu_to_be32(create->u.symlink.len);
xdr_write_pages(xdr, create->u.symlink.pages, 0, create->u.symlink.len);
p = reserve_space(xdr, 8);
*p++ = cpu_to_be32(create->u.device.specdata1);
*p = cpu_to_be32(create->u.device.specdata2);

Benny Halevy
committed
encode_string(xdr, create->name->len, create->name->name);
hdr->replen += decode_create_maxsz;
encode_attrs(xdr, create->attrs, create->server);
static void encode_getattr_one(struct xdr_stream *xdr, uint32_t bitmap, struct compound_hdr *hdr)
p = reserve_space(xdr, 12);
*p++ = cpu_to_be32(OP_GETATTR);
*p++ = cpu_to_be32(1);
hdr->replen += decode_getattr_maxsz;
static void encode_getattr_two(struct xdr_stream *xdr, uint32_t bm0, uint32_t bm1, struct compound_hdr *hdr)
p = reserve_space(xdr, 16);
*p++ = cpu_to_be32(OP_GETATTR);
*p++ = cpu_to_be32(2);
*p++ = cpu_to_be32(bm0);
hdr->replen += decode_getattr_maxsz;
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
static void
encode_getattr_three(struct xdr_stream *xdr,
uint32_t bm0, uint32_t bm1, uint32_t bm2,
struct compound_hdr *hdr)
{
__be32 *p;
p = reserve_space(xdr, 4);
*p = cpu_to_be32(OP_GETATTR);
if (bm2) {
p = reserve_space(xdr, 16);
*p++ = cpu_to_be32(3);
*p++ = cpu_to_be32(bm0);
*p++ = cpu_to_be32(bm1);
*p = cpu_to_be32(bm2);
} else if (bm1) {
p = reserve_space(xdr, 12);
*p++ = cpu_to_be32(2);
*p++ = cpu_to_be32(bm0);
*p = cpu_to_be32(bm1);
} else {
p = reserve_space(xdr, 8);
*p++ = cpu_to_be32(1);
*p = cpu_to_be32(bm0);
}
hdr->nops++;
hdr->replen += decode_getattr_maxsz;
}
static void encode_getfattr(struct xdr_stream *xdr, const u32* bitmask, struct compound_hdr *hdr)
encode_getattr_two(xdr, bitmask[0] & nfs4_fattr_bitmap[0],
bitmask[1] & nfs4_fattr_bitmap[1], hdr);
static void encode_fsinfo(struct xdr_stream *xdr, const u32* bitmask, struct compound_hdr *hdr)
encode_getattr_three(xdr,
bitmask[0] & nfs4_fsinfo_bitmap[0],
bitmask[1] & nfs4_fsinfo_bitmap[1],
bitmask[2] & nfs4_fsinfo_bitmap[2],
hdr);
static void encode_fs_locations(struct xdr_stream *xdr, const u32* bitmask, struct compound_hdr *hdr)
encode_getattr_two(xdr, bitmask[0] & nfs4_fs_locations_bitmap[0],
bitmask[1] & nfs4_fs_locations_bitmap[1], hdr);
static void encode_getfh(struct xdr_stream *xdr, struct compound_hdr *hdr)
p = reserve_space(xdr, 4);
hdr->replen += decode_getfh_maxsz;
static void encode_link(struct xdr_stream *xdr, const struct qstr *name, struct compound_hdr *hdr)
p = reserve_space(xdr, 8 + name->len);

Benny Halevy
committed
xdr_encode_opaque(p, name->name, name->len);
hdr->replen += decode_link_maxsz;
static inline int nfs4_lock_type(struct file_lock *fl, int block)
{
if ((fl->fl_type & (F_RDLCK|F_WRLCK|F_UNLCK)) == F_RDLCK)
return block ? NFS4_READW_LT : NFS4_READ_LT;
return block ? NFS4_WRITEW_LT : NFS4_WRITE_LT;
}
static inline uint64_t nfs4_lock_length(struct file_lock *fl)
{
if (fl->fl_end == OFFSET_MAX)
return ~(uint64_t)0;
return fl->fl_end - fl->fl_start + 1;
}
static void encode_lockowner(struct xdr_stream *xdr, const struct nfs_lowner *lowner)
{
__be32 *p;
p = reserve_space(xdr, 32);
p = xdr_encode_hyper(p, lowner->clientid);
*p++ = cpu_to_be32(20);
p = xdr_encode_opaque_fixed(p, "lock id:", 8);
*p++ = cpu_to_be32(lowner->s_dev);
xdr_encode_hyper(p, lowner->id);
}
/*
* opcode,type,reclaim,offset,length,new_lock_owner = 32
* open_seqid,open_stateid,lock_seqid,lock_owner.clientid, lock_owner.id = 40
*/
static void encode_lock(struct xdr_stream *xdr, const struct nfs_lock_args *args, struct compound_hdr *hdr)
p = reserve_space(xdr, 32);
*p++ = cpu_to_be32(OP_LOCK);
*p++ = cpu_to_be32(nfs4_lock_type(args->fl, args->block));
*p++ = cpu_to_be32(args->reclaim);
p = xdr_encode_hyper(p, args->fl->fl_start);
p = xdr_encode_hyper(p, nfs4_lock_length(args->fl));
*p = cpu_to_be32(args->new_lock_owner);
p = reserve_space(xdr, 4+NFS4_STATEID_SIZE+4);
*p++ = cpu_to_be32(args->open_seqid->sequence->counter);
p = xdr_encode_opaque_fixed(p, args->open_stateid->data, NFS4_STATEID_SIZE);
*p++ = cpu_to_be32(args->lock_seqid->sequence->counter);
encode_lockowner(xdr, &args->lock_owner);
p = reserve_space(xdr, NFS4_STATEID_SIZE+4);
p = xdr_encode_opaque_fixed(p, args->lock_stateid->data, NFS4_STATEID_SIZE);
*p = cpu_to_be32(args->lock_seqid->sequence->counter);
hdr->replen += decode_lock_maxsz;
static void encode_lockt(struct xdr_stream *xdr, const struct nfs_lockt_args *args, struct compound_hdr *hdr)
p = reserve_space(xdr, 24);
*p++ = cpu_to_be32(OP_LOCKT);
*p++ = cpu_to_be32(nfs4_lock_type(args->fl, 0));
p = xdr_encode_hyper(p, args->fl->fl_start);
p = xdr_encode_hyper(p, nfs4_lock_length(args->fl));
encode_lockowner(xdr, &args->lock_owner);
hdr->replen += decode_lockt_maxsz;
static void encode_locku(struct xdr_stream *xdr, const struct nfs_locku_args *args, struct compound_hdr *hdr)
p = reserve_space(xdr, 12+NFS4_STATEID_SIZE+16);
*p++ = cpu_to_be32(OP_LOCKU);
*p++ = cpu_to_be32(nfs4_lock_type(args->fl, 0));
*p++ = cpu_to_be32(args->seqid->sequence->counter);
p = xdr_encode_opaque_fixed(p, args->stateid->data, NFS4_STATEID_SIZE);
p = xdr_encode_hyper(p, args->fl->fl_start);
xdr_encode_hyper(p, nfs4_lock_length(args->fl));
hdr->replen += decode_locku_maxsz;
static void encode_release_lockowner(struct xdr_stream *xdr, const struct nfs_lowner *lowner, struct compound_hdr *hdr)
{
__be32 *p;
p = reserve_space(xdr, 4);
*p = cpu_to_be32(OP_RELEASE_LOCKOWNER);
encode_lockowner(xdr, lowner);
hdr->nops++;
hdr->replen += decode_release_lockowner_maxsz;
}
static void encode_lookup(struct xdr_stream *xdr, const struct qstr *name, struct compound_hdr *hdr)
p = reserve_space(xdr, 8 + len);

Benny Halevy
committed
xdr_encode_opaque(p, name->name, len);
hdr->replen += decode_lookup_maxsz;
static void encode_share_access(struct xdr_stream *xdr, fmode_t fmode)
p = reserve_space(xdr, 8);
switch (fmode & (FMODE_READ|FMODE_WRITE)) {
*p++ = cpu_to_be32(NFS4_SHARE_ACCESS_READ);
*p++ = cpu_to_be32(NFS4_SHARE_ACCESS_WRITE);
*p++ = cpu_to_be32(NFS4_SHARE_ACCESS_BOTH);
*p = cpu_to_be32(0); /* for linux, share_deny = 0 always */
}
static inline void encode_openhdr(struct xdr_stream *xdr, const struct nfs_openargs *arg)
{
/*
* opcode 4, seqid 4, share_access 4, share_deny 4, clientid 8, ownerlen 4,
* owner 4 = 32
*/
p = reserve_space(xdr, 8);
*p = cpu_to_be32(arg->seqid->sequence->counter);
encode_share_access(xdr, arg->fmode);
p = reserve_space(xdr, 32);
p = xdr_encode_hyper(p, arg->clientid);
*p++ = cpu_to_be32(20);
p = xdr_encode_opaque_fixed(p, "open id:", 8);
*p++ = cpu_to_be32(arg->server->s_dev);
}
static inline void encode_createmode(struct xdr_stream *xdr, const struct nfs_openargs *arg)
{
struct nfs_client *clp;
p = reserve_space(xdr, 4);
*p = cpu_to_be32(NFS4_CREATE_UNCHECKED);
encode_attrs(xdr, arg->u.attrs, arg->server);
break;
default:
clp = arg->server->nfs_client;
if (clp->cl_mvops->minor_version > 0) {
if (nfs4_has_persistent_session(clp)) {
*p = cpu_to_be32(NFS4_CREATE_GUARDED);
encode_attrs(xdr, arg->u.attrs, arg->server);
} else {
struct iattr dummy;
*p = cpu_to_be32(NFS4_CREATE_EXCLUSIVE4_1);
encode_nfs4_verifier(xdr, &arg->u.verifier);
dummy.ia_valid = 0;
encode_attrs(xdr, &dummy, arg->server);
}
} else {
*p = cpu_to_be32(NFS4_CREATE_EXCLUSIVE);
encode_nfs4_verifier(xdr, &arg->u.verifier);
}
}
}
static void encode_opentype(struct xdr_stream *xdr, const struct nfs_openargs *arg)
{
p = reserve_space(xdr, 4);
*p = cpu_to_be32(NFS4_OPEN_NOCREATE);
break;
default:
BUG_ON(arg->claim != NFS4_OPEN_CLAIM_NULL);
*p = cpu_to_be32(NFS4_OPEN_CREATE);
static inline void encode_delegation_type(struct xdr_stream *xdr, fmode_t delegation_type)
p = reserve_space(xdr, 4);
*p = cpu_to_be32(NFS4_OPEN_DELEGATE_NONE);
*p = cpu_to_be32(NFS4_OPEN_DELEGATE_READ);
*p = cpu_to_be32(NFS4_OPEN_DELEGATE_WRITE);
}
}
static inline void encode_claim_null(struct xdr_stream *xdr, const struct qstr *name)
{
p = reserve_space(xdr, 4);
*p = cpu_to_be32(NFS4_OPEN_CLAIM_NULL);
encode_string(xdr, name->len, name->name);
}
static inline void encode_claim_previous(struct xdr_stream *xdr, fmode_t type)
p = reserve_space(xdr, 4);
*p = cpu_to_be32(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)
{
p = reserve_space(xdr, 4+NFS4_STATEID_SIZE);
*p++ = cpu_to_be32(NFS4_OPEN_CLAIM_DELEGATE_CUR);
xdr_encode_opaque_fixed(p, stateid->data, NFS4_STATEID_SIZE);
encode_string(xdr, name->len, name->name);
}
static void encode_open(struct xdr_stream *xdr, const struct nfs_openargs *arg, struct compound_hdr *hdr)
{
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();
hdr->replen += decode_open_maxsz;
static void encode_open_confirm(struct xdr_stream *xdr, const struct nfs_open_confirmargs *arg, struct compound_hdr *hdr)
p = reserve_space(xdr, 4+NFS4_STATEID_SIZE+4);
p = xdr_encode_opaque_fixed(p, arg->stateid->data, NFS4_STATEID_SIZE);
*p = cpu_to_be32(arg->seqid->sequence->counter);
hdr->replen += decode_open_confirm_maxsz;
static void encode_open_downgrade(struct xdr_stream *xdr, const struct nfs_closeargs *arg, struct compound_hdr *hdr)
p = reserve_space(xdr, 4+NFS4_STATEID_SIZE+4);
p = xdr_encode_opaque_fixed(p, arg->stateid->data, NFS4_STATEID_SIZE);
*p = cpu_to_be32(arg->seqid->sequence->counter);
encode_share_access(xdr, arg->fmode);
hdr->replen += decode_open_downgrade_maxsz;
encode_putfh(struct xdr_stream *xdr, const struct nfs_fh *fh, struct compound_hdr *hdr)
p = reserve_space(xdr, 8 + len);

Benny Halevy
committed
xdr_encode_opaque(p, fh->data, len);
hdr->replen += decode_putfh_maxsz;
static void encode_putrootfh(struct xdr_stream *xdr, struct compound_hdr *hdr)
p = reserve_space(xdr, 4);
*p = cpu_to_be32(OP_PUTROOTFH);
hdr->replen += decode_putrootfh_maxsz;
static void encode_stateid(struct xdr_stream *xdr, const struct nfs_open_context *ctx, const struct nfs_lock_context *l_ctx, int zero_seqid)
p = reserve_space(xdr, NFS4_STATEID_SIZE);

Trond Myklebust
committed
nfs4_copy_stateid(&stateid, ctx->state, l_ctx->lockowner, l_ctx->pid);
if (zero_seqid)
stateid.stateid.seqid = 0;
xdr_encode_opaque_fixed(p, stateid.data, NFS4_STATEID_SIZE);
xdr_encode_opaque_fixed(p, zero_stateid.data, NFS4_STATEID_SIZE);
static void encode_read(struct xdr_stream *xdr, const struct nfs_readargs *args, struct compound_hdr *hdr)
p = reserve_space(xdr, 4);
encode_stateid(xdr, args->context, args->lock_context,
hdr->minorversion);
p = reserve_space(xdr, 12);
*p = cpu_to_be32(args->count);
hdr->replen += decode_read_maxsz;
static void encode_readdir(struct xdr_stream *xdr, const struct nfs4_readdir_arg *readdir, struct rpc_rqst *req, struct compound_hdr *hdr)
uint32_t attrs[2] = {
FATTR4_WORD0_RDATTR_ERROR,
FATTR4_WORD1_MOUNTED_ON_FILEID,
};
uint32_t dircount = readdir->count >> 1;
if (readdir->plus) {
attrs[0] |= FATTR4_WORD0_TYPE|FATTR4_WORD0_CHANGE|FATTR4_WORD0_SIZE|
FATTR4_WORD0_FSID|FATTR4_WORD0_FILEHANDLE|FATTR4_WORD0_FILEID;
attrs[1] |= FATTR4_WORD1_MODE|FATTR4_WORD1_NUMLINKS|FATTR4_WORD1_OWNER|
FATTR4_WORD1_OWNER_GROUP|FATTR4_WORD1_RAWDEV|
FATTR4_WORD1_SPACE_USED|FATTR4_WORD1_TIME_ACCESS|
FATTR4_WORD1_TIME_METADATA|FATTR4_WORD1_TIME_MODIFY;
/* Use mounted_on_fileid only if the server supports it */
if (!(readdir->bitmask[1] & FATTR4_WORD1_MOUNTED_ON_FILEID))
attrs[0] |= FATTR4_WORD0_FILEID;
p = reserve_space(xdr, 12+NFS4_VERIFIER_SIZE+20);
p = xdr_encode_hyper(p, readdir->cookie);
p = xdr_encode_opaque_fixed(p, readdir->verifier.data, NFS4_VERIFIER_SIZE);
*p++ = cpu_to_be32(dircount);
*p++ = cpu_to_be32(readdir->count);
*p++ = cpu_to_be32(2);
*p++ = cpu_to_be32(attrs[0] & readdir->bitmask[0]);
*p = cpu_to_be32(attrs[1] & readdir->bitmask[1]);
hdr->replen += decode_readdir_maxsz;
dprintk("%s: cookie = %Lu, verifier = %08x:%08x, bitmap = %08x:%08x\n",
__func__,
(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]);
static void encode_readlink(struct xdr_stream *xdr, const struct nfs4_readlink *readlink, struct rpc_rqst *req, struct compound_hdr *hdr)
p = reserve_space(xdr, 4);
*p = cpu_to_be32(OP_READLINK);
hdr->replen += decode_readlink_maxsz;
static void encode_remove(struct xdr_stream *xdr, const struct qstr *name, struct compound_hdr *hdr)
p = reserve_space(xdr, 8 + name->len);

Benny Halevy
committed
xdr_encode_opaque(p, name->name, name->len);
hdr->replen += decode_remove_maxsz;
static void encode_rename(struct xdr_stream *xdr, const struct qstr *oldname, const struct qstr *newname, struct compound_hdr *hdr)

Benny Halevy
committed
p = reserve_space(xdr, 4);
*p = cpu_to_be32(OP_RENAME);
encode_string(xdr, oldname->len, oldname->name);
encode_string(xdr, newname->len, newname->name);
hdr->replen += decode_rename_maxsz;
static void encode_renew(struct xdr_stream *xdr, clientid4 clid,
struct compound_hdr *hdr)
p = reserve_space(xdr, 12);
hdr->replen += decode_renew_maxsz;
encode_restorefh(struct xdr_stream *xdr, struct compound_hdr *hdr)
p = reserve_space(xdr, 4);
*p = cpu_to_be32(OP_RESTOREFH);
hdr->replen += decode_restorefh_maxsz;
}
encode_setacl(struct xdr_stream *xdr, struct nfs_setaclargs *arg, struct compound_hdr *hdr)
p = reserve_space(xdr, 4+NFS4_STATEID_SIZE);
xdr_encode_opaque_fixed(p, zero_stateid.data, NFS4_STATEID_SIZE);
p = reserve_space(xdr, 2*4);
*p = cpu_to_be32(FATTR4_WORD0_ACL);
p = reserve_space(xdr, 4);
*p = cpu_to_be32(arg->acl_len);
xdr_write_pages(xdr, arg->acl_pages, arg->acl_pgbase, arg->acl_len);
hdr->replen += decode_setacl_maxsz;
encode_savefh(struct xdr_stream *xdr, struct compound_hdr *hdr)
p = reserve_space(xdr, 4);
hdr->replen += decode_savefh_maxsz;
static void encode_setattr(struct xdr_stream *xdr, const struct nfs_setattrargs *arg, const struct nfs_server *server, struct compound_hdr *hdr)
p = reserve_space(xdr, 4+NFS4_STATEID_SIZE);
xdr_encode_opaque_fixed(p, arg->stateid.data, NFS4_STATEID_SIZE);
hdr->replen += decode_setattr_maxsz;
encode_attrs(xdr, arg->iap, server);
static void encode_setclientid(struct xdr_stream *xdr, const struct nfs4_setclientid *setclientid, struct compound_hdr *hdr)
p = reserve_space(xdr, 4 + NFS4_VERIFIER_SIZE);
xdr_encode_opaque_fixed(p, setclientid->sc_verifier->data, NFS4_VERIFIER_SIZE);
encode_string(xdr, setclientid->sc_name_len, setclientid->sc_name);
p = reserve_space(xdr, 4);
*p = cpu_to_be32(setclientid->sc_prog);
encode_string(xdr, setclientid->sc_netid_len, setclientid->sc_netid);
encode_string(xdr, setclientid->sc_uaddr_len, setclientid->sc_uaddr);
p = reserve_space(xdr, 4);
*p = cpu_to_be32(setclientid->sc_cb_ident);
hdr->replen += decode_setclientid_maxsz;
static void encode_setclientid_confirm(struct xdr_stream *xdr, const struct nfs4_setclientid_res *arg, struct compound_hdr *hdr)
p = reserve_space(xdr, 12 + NFS4_VERIFIER_SIZE);
*p++ = cpu_to_be32(OP_SETCLIENTID_CONFIRM);
p = xdr_encode_hyper(p, arg->clientid);
xdr_encode_opaque_fixed(p, arg->confirm.data, NFS4_VERIFIER_SIZE);
hdr->replen += decode_setclientid_confirm_maxsz;
static void encode_write(struct xdr_stream *xdr, const struct nfs_writeargs *args, struct compound_hdr *hdr)
p = reserve_space(xdr, 4);
encode_stateid(xdr, args->context, args->lock_context,
hdr->minorversion);
p = reserve_space(xdr, 16);
*p = cpu_to_be32(args->count);
xdr_write_pages(xdr, args->pages, args->pgbase, args->count);
hdr->replen += decode_write_maxsz;
static void encode_delegreturn(struct xdr_stream *xdr, const nfs4_stateid *stateid, struct compound_hdr *hdr)
p = reserve_space(xdr, 4+NFS4_STATEID_SIZE);
xdr_encode_opaque_fixed(p, stateid->data, NFS4_STATEID_SIZE);
hdr->replen += decode_delegreturn_maxsz;
static void encode_secinfo(struct xdr_stream *xdr, const struct qstr *name, struct compound_hdr *hdr)
{
int len = name->len;
__be32 *p;
p = reserve_space(xdr, 8 + len);
*p++ = cpu_to_be32(OP_SECINFO);
xdr_encode_opaque(p, name->name, len);
hdr->nops++;
hdr->replen += decode_secinfo_maxsz;
}
static void encode_exchange_id(struct xdr_stream *xdr,
struct nfs41_exchange_id_args *args,
struct compound_hdr *hdr)
{
__be32 *p;
char impl_name[NFS4_OPAQUE_LIMIT];
int len = 0;
p = reserve_space(xdr, 4 + sizeof(args->verifier->data));
xdr_encode_opaque_fixed(p, args->verifier->data, sizeof(args->verifier->data));
encode_string(xdr, args->id_len, args->id);
p = reserve_space(xdr, 12);
*p++ = cpu_to_be32(args->flags);
*p++ = cpu_to_be32(0); /* zero length state_protect4_a */
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
if (send_implementation_id &&
sizeof(CONFIG_NFS_V4_1_IMPLEMENTATION_ID_DOMAIN) > 1 &&
sizeof(CONFIG_NFS_V4_1_IMPLEMENTATION_ID_DOMAIN)
<= NFS4_OPAQUE_LIMIT + 1)
len = snprintf(impl_name, sizeof(impl_name), "%s %s %s %s",
utsname()->sysname, utsname()->release,
utsname()->version, utsname()->machine);
if (len > 0) {
*p = cpu_to_be32(1); /* implementation id array length=1 */
encode_string(xdr,
sizeof(CONFIG_NFS_V4_1_IMPLEMENTATION_ID_DOMAIN) - 1,
CONFIG_NFS_V4_1_IMPLEMENTATION_ID_DOMAIN);
encode_string(xdr, len, impl_name);
/* just send zeros for nii_date - the date is in nii_name */
p = reserve_space(xdr, 12);
p = xdr_encode_hyper(p, 0);
*p = cpu_to_be32(0);
} else
*p = cpu_to_be32(0); /* implementation id array length=0 */
hdr->nops++;
hdr->replen += decode_exchange_id_maxsz;
}
static void encode_create_session(struct xdr_stream *xdr,
struct nfs41_create_session_args *args,
struct compound_hdr *hdr)
{
__be32 *p;
char machine_name[NFS4_MAX_MACHINE_NAME_LEN];
uint32_t len;
struct nfs_client *clp = args->client;
u32 max_resp_sz_cached;
/*
* Assumes OPEN is the biggest non-idempotent compound.
* 2 is the verifier.
*/
max_resp_sz_cached = (NFS4_dec_open_sz + RPC_REPHDRSIZE +
RPC_MAX_AUTH_SIZE + 2) * XDR_UNIT;

Benny Halevy
committed
len = scnprintf(machine_name, sizeof(machine_name), "%s",
clp->cl_ipaddr);
p = reserve_space(xdr, 20 + 2*28 + 20 + len + 12);

Benny Halevy
committed
*p++ = cpu_to_be32(OP_CREATE_SESSION);
p = xdr_encode_hyper(p, clp->cl_clientid);
*p++ = cpu_to_be32(clp->cl_seqid); /*Sequence id */
*p++ = cpu_to_be32(args->flags); /*flags */
*p++ = cpu_to_be32(0); /* header padding size */
*p++ = cpu_to_be32(args->fc_attrs.max_rqst_sz); /* max req size */
*p++ = cpu_to_be32(args->fc_attrs.max_resp_sz); /* max resp size */
*p++ = cpu_to_be32(max_resp_sz_cached); /* Max resp sz cached */
*p++ = cpu_to_be32(args->fc_attrs.max_ops); /* max operations */
*p++ = cpu_to_be32(args->fc_attrs.max_reqs); /* max requests */
*p++ = cpu_to_be32(0); /* rdmachannel_attrs */
*p++ = cpu_to_be32(0); /* header padding size */
*p++ = cpu_to_be32(args->bc_attrs.max_rqst_sz); /* max req size */
*p++ = cpu_to_be32(args->bc_attrs.max_resp_sz); /* max resp size */
*p++ = cpu_to_be32(args->bc_attrs.max_resp_sz_cached); /* Max resp sz cached */
*p++ = cpu_to_be32(args->bc_attrs.max_ops); /* max operations */
*p++ = cpu_to_be32(args->bc_attrs.max_reqs); /* max requests */
*p++ = cpu_to_be32(0); /* rdmachannel_attrs */
*p++ = cpu_to_be32(args->cb_program); /* cb_program */
*p++ = cpu_to_be32(1);
*p++ = cpu_to_be32(RPC_AUTH_UNIX); /* auth_sys */
*p++ = cpu_to_be32((u32)clp->cl_boot_time.tv_nsec); /* stamp */

Benny Halevy
committed
p = xdr_encode_opaque(p, machine_name, len);
*p++ = cpu_to_be32(0); /* UID */
*p++ = cpu_to_be32(0); /* GID */
*p = cpu_to_be32(0); /* No more gids */
hdr->nops++;
hdr->replen += decode_create_session_maxsz;
}
static void encode_destroy_session(struct xdr_stream *xdr,
struct nfs4_session *session,
struct compound_hdr *hdr)
{
__be32 *p;
p = reserve_space(xdr, 4 + NFS4_MAX_SESSIONID_LEN);
*p++ = cpu_to_be32(OP_DESTROY_SESSION);
xdr_encode_opaque_fixed(p, session->sess_id.data, NFS4_MAX_SESSIONID_LEN);
hdr->nops++;
hdr->replen += decode_destroy_session_maxsz;
}
static void encode_reclaim_complete(struct xdr_stream *xdr,
struct nfs41_reclaim_complete_args *args,
struct compound_hdr *hdr)
{
__be32 *p;
p = reserve_space(xdr, 8);
*p++ = cpu_to_be32(OP_RECLAIM_COMPLETE);
*p++ = cpu_to_be32(args->one_fs);
hdr->nops++;
hdr->replen += decode_reclaim_complete_maxsz;
}
static void encode_sequence(struct xdr_stream *xdr,
const struct nfs4_sequence_args *args,
struct compound_hdr *hdr)
{
#if defined(CONFIG_NFS_V4_1)
struct nfs4_session *session = args->sa_session;
struct nfs4_slot_table *tp;
struct nfs4_slot *slot;
__be32 *p;
if (!session)
return;
tp = &session->fc_slot_table;
WARN_ON(args->sa_slotid == NFS4_MAX_SLOT_TABLE);
slot = tp->slots + args->sa_slotid;
p = reserve_space(xdr, 4 + NFS4_MAX_SESSIONID_LEN + 16);
/*
* Sessionid + seqid + slotid + max slotid + cache_this
*/
dprintk("%s: sessionid=%u:%u:%u:%u seqid=%d slotid=%d "
"max_slotid=%d cache_this=%d\n",
__func__,
((u32 *)session->sess_id.data)[0],
((u32 *)session->sess_id.data)[1],
((u32 *)session->sess_id.data)[2],
((u32 *)session->sess_id.data)[3],
slot->seq_nr, args->sa_slotid,
tp->highest_used_slotid, args->sa_cache_this);
p = xdr_encode_opaque_fixed(p, session->sess_id.data, NFS4_MAX_SESSIONID_LEN);
*p++ = cpu_to_be32(slot->seq_nr);
*p++ = cpu_to_be32(args->sa_slotid);
*p++ = cpu_to_be32(tp->highest_used_slotid);
*p = cpu_to_be32(args->sa_cache_this);
hdr->nops++;
hdr->replen += decode_sequence_maxsz;
#endif /* CONFIG_NFS_V4_1 */
}
#ifdef CONFIG_NFS_V4_1
static void
encode_getdevicelist(struct xdr_stream *xdr,
const struct nfs4_getdevicelist_args *args,
struct compound_hdr *hdr)
{
__be32 *p;
nfs4_verifier dummy = {
.data = "dummmmmy",
};
p = reserve_space(xdr, 20);
*p++ = cpu_to_be32(OP_GETDEVICELIST);
*p++ = cpu_to_be32(args->layoutclass);
*p++ = cpu_to_be32(NFS4_PNFS_GETDEVLIST_MAXNUM);
xdr_encode_hyper(p, 0ULL); /* cookie */
encode_nfs4_verifier(xdr, &dummy);
hdr->nops++;
hdr->replen += decode_getdevicelist_maxsz;
}
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
static void
encode_getdeviceinfo(struct xdr_stream *xdr,
const struct nfs4_getdeviceinfo_args *args,
struct compound_hdr *hdr)
{
__be32 *p;
p = reserve_space(xdr, 16 + NFS4_DEVICEID4_SIZE);
*p++ = cpu_to_be32(OP_GETDEVICEINFO);
p = xdr_encode_opaque_fixed(p, args->pdev->dev_id.data,
NFS4_DEVICEID4_SIZE);
*p++ = cpu_to_be32(args->pdev->layout_type);
*p++ = cpu_to_be32(args->pdev->pglen); /* gdia_maxcount */
*p++ = cpu_to_be32(0); /* bitmap length 0 */
hdr->nops++;
hdr->replen += decode_getdeviceinfo_maxsz;
}
static void
encode_layoutget(struct xdr_stream *xdr,
const struct nfs4_layoutget_args *args,
struct compound_hdr *hdr)
{
__be32 *p;
p = reserve_space(xdr, 44 + NFS4_STATEID_SIZE);
*p++ = cpu_to_be32(OP_LAYOUTGET);
*p++ = cpu_to_be32(0); /* Signal layout available */