0001
0002
0003
0004
0005 #include <linux/sunrpc/svc.h>
0006 #include <linux/nfs4.h>
0007
0008 #include "nfsd.h"
0009 #include "flexfilelayoutxdr.h"
0010
0011 #define NFSDDBG_FACILITY NFSDDBG_PNFS
0012
0013 struct ff_idmap {
0014 char buf[11];
0015 int len;
0016 };
0017
0018 __be32
0019 nfsd4_ff_encode_layoutget(struct xdr_stream *xdr,
0020 struct nfsd4_layoutget *lgp)
0021 {
0022 struct pnfs_ff_layout *fl = lgp->lg_content;
0023 int len, mirror_len, ds_len, fh_len;
0024 __be32 *p;
0025
0026
0027
0028
0029
0030 struct ff_idmap uid;
0031 struct ff_idmap gid;
0032
0033 fh_len = 4 + fl->fh.size;
0034
0035 uid.len = sprintf(uid.buf, "%u", from_kuid(&init_user_ns, fl->uid));
0036 gid.len = sprintf(gid.buf, "%u", from_kgid(&init_user_ns, fl->gid));
0037
0038
0039 ds_len = 20 + sizeof(stateid_opaque_t) + 4 + fh_len +
0040 8 + uid.len + 8 + gid.len;
0041
0042 mirror_len = 4 + ds_len;
0043
0044
0045 len = 20 + mirror_len;
0046
0047 p = xdr_reserve_space(xdr, sizeof(__be32) + len);
0048 if (!p)
0049 return nfserr_toosmall;
0050
0051 *p++ = cpu_to_be32(len);
0052 p = xdr_encode_hyper(p, 0);
0053
0054 *p++ = cpu_to_be32(1);
0055 *p++ = cpu_to_be32(1);
0056
0057 p = xdr_encode_opaque_fixed(p, &fl->deviceid,
0058 sizeof(struct nfsd4_deviceid));
0059
0060 *p++ = cpu_to_be32(1);
0061
0062 *p++ = cpu_to_be32(fl->stateid.si_generation);
0063 p = xdr_encode_opaque_fixed(p, &fl->stateid.si_opaque,
0064 sizeof(stateid_opaque_t));
0065
0066 *p++ = cpu_to_be32(1);
0067 p = xdr_encode_opaque(p, fl->fh.data, fl->fh.size);
0068
0069 p = xdr_encode_opaque(p, uid.buf, uid.len);
0070 p = xdr_encode_opaque(p, gid.buf, gid.len);
0071
0072 *p++ = cpu_to_be32(fl->flags);
0073 *p++ = cpu_to_be32(0);
0074
0075 return 0;
0076 }
0077
0078 __be32
0079 nfsd4_ff_encode_getdeviceinfo(struct xdr_stream *xdr,
0080 struct nfsd4_getdeviceinfo *gdp)
0081 {
0082 struct pnfs_ff_device_addr *da = gdp->gd_device;
0083 int len;
0084 int ver_len;
0085 int addr_len;
0086 __be32 *p;
0087
0088
0089 addr_len = 16 + da->netaddr.netid_len + da->netaddr.addr_len;
0090 ver_len = 20;
0091
0092 len = 4 + ver_len + 4 + addr_len;
0093
0094 p = xdr_reserve_space(xdr, len + sizeof(__be32));
0095 if (!p)
0096 return nfserr_resource;
0097
0098
0099
0100
0101
0102 *p++ = cpu_to_be32(len);
0103 *p++ = cpu_to_be32(1);
0104 p = xdr_encode_opaque(p, da->netaddr.netid, da->netaddr.netid_len);
0105 p = xdr_encode_opaque(p, da->netaddr.addr, da->netaddr.addr_len);
0106
0107 *p++ = cpu_to_be32(1);
0108
0109 *p++ = cpu_to_be32(da->version);
0110 *p++ = cpu_to_be32(da->minor_version);
0111 *p++ = cpu_to_be32(da->rsize);
0112 *p++ = cpu_to_be32(da->wsize);
0113 *p++ = cpu_to_be32(da->tightly_coupled);
0114
0115 return 0;
0116 }