mirror of https://github.com/torvalds/linux.git
NFSD: Rework encoding and decoding of nfsd4_deviceid
Compilers may optimize the layout of C structures, so we should not rely on sizeof struct and memcpy to encode and decode XDR structures. The byte order of the fields should also be taken into account. This patch adds the correct functions to handle the deviceid4 structure and removes the pad field, which is currently not used by NFSD, from the runtime state. The server's byte order is preserved because the deviceid4 blob on the wire is only used as a cookie by the client. Signed-off-by: Sergey Bashirov <sergeybashirov@gmail.com> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
This commit is contained in:
parent
c97b737ef8
commit
832738e4b3
|
|
@ -29,8 +29,7 @@ nfsd4_block_encode_layoutget(struct xdr_stream *xdr,
|
||||||
*p++ = cpu_to_be32(len);
|
*p++ = cpu_to_be32(len);
|
||||||
*p++ = cpu_to_be32(1); /* we always return a single extent */
|
*p++ = cpu_to_be32(1); /* we always return a single extent */
|
||||||
|
|
||||||
p = xdr_encode_opaque_fixed(p, &b->vol_id,
|
p = svcxdr_encode_deviceid4(p, &b->vol_id);
|
||||||
sizeof(struct nfsd4_deviceid));
|
|
||||||
p = xdr_encode_hyper(p, b->foff);
|
p = xdr_encode_hyper(p, b->foff);
|
||||||
p = xdr_encode_hyper(p, b->len);
|
p = xdr_encode_hyper(p, b->len);
|
||||||
p = xdr_encode_hyper(p, b->soff);
|
p = xdr_encode_hyper(p, b->soff);
|
||||||
|
|
@ -156,9 +155,7 @@ nfsd4_block_decode_layoutupdate(__be32 *p, u32 len, struct iomap **iomapp,
|
||||||
for (i = 0; i < nr_iomaps; i++) {
|
for (i = 0; i < nr_iomaps; i++) {
|
||||||
struct pnfs_block_extent bex;
|
struct pnfs_block_extent bex;
|
||||||
|
|
||||||
memcpy(&bex.vol_id, p, sizeof(struct nfsd4_deviceid));
|
p = svcxdr_decode_deviceid4(p, &bex.vol_id);
|
||||||
p += XDR_QUADLEN(sizeof(struct nfsd4_deviceid));
|
|
||||||
|
|
||||||
p = xdr_decode_hyper(p, &bex.foff);
|
p = xdr_decode_hyper(p, &bex.foff);
|
||||||
if (bex.foff & (block_size - 1)) {
|
if (bex.foff & (block_size - 1)) {
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
|
||||||
|
|
@ -54,8 +54,7 @@ nfsd4_ff_encode_layoutget(struct xdr_stream *xdr,
|
||||||
*p++ = cpu_to_be32(1); /* single mirror */
|
*p++ = cpu_to_be32(1); /* single mirror */
|
||||||
*p++ = cpu_to_be32(1); /* single data server */
|
*p++ = cpu_to_be32(1); /* single data server */
|
||||||
|
|
||||||
p = xdr_encode_opaque_fixed(p, &fl->deviceid,
|
p = svcxdr_encode_deviceid4(p, &fl->deviceid);
|
||||||
sizeof(struct nfsd4_deviceid));
|
|
||||||
|
|
||||||
*p++ = cpu_to_be32(1); /* efficiency */
|
*p++ = cpu_to_be32(1); /* efficiency */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -120,7 +120,6 @@ nfsd4_set_deviceid(struct nfsd4_deviceid *id, const struct svc_fh *fhp,
|
||||||
|
|
||||||
id->fsid_idx = fhp->fh_export->ex_devid_map->idx;
|
id->fsid_idx = fhp->fh_export->ex_devid_map->idx;
|
||||||
id->generation = device_generation;
|
id->generation = device_generation;
|
||||||
id->pad = 0;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -587,18 +587,6 @@ nfsd4_decode_state_owner4(struct nfsd4_compoundargs *argp,
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_NFSD_PNFS
|
#ifdef CONFIG_NFSD_PNFS
|
||||||
static __be32
|
|
||||||
nfsd4_decode_deviceid4(struct nfsd4_compoundargs *argp,
|
|
||||||
struct nfsd4_deviceid *devid)
|
|
||||||
{
|
|
||||||
__be32 *p;
|
|
||||||
|
|
||||||
p = xdr_inline_decode(argp->xdr, NFS4_DEVICEID4_SIZE);
|
|
||||||
if (!p)
|
|
||||||
return nfserr_bad_xdr;
|
|
||||||
memcpy(devid, p, sizeof(*devid));
|
|
||||||
return nfs_ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
static __be32
|
static __be32
|
||||||
nfsd4_decode_layoutupdate4(struct nfsd4_compoundargs *argp,
|
nfsd4_decode_layoutupdate4(struct nfsd4_compoundargs *argp,
|
||||||
|
|
@ -1783,7 +1771,7 @@ nfsd4_decode_getdeviceinfo(struct nfsd4_compoundargs *argp,
|
||||||
__be32 status;
|
__be32 status;
|
||||||
|
|
||||||
memset(gdev, 0, sizeof(*gdev));
|
memset(gdev, 0, sizeof(*gdev));
|
||||||
status = nfsd4_decode_deviceid4(argp, &gdev->gd_devid);
|
status = nfsd4_decode_deviceid4(argp->xdr, &gdev->gd_devid);
|
||||||
if (status)
|
if (status)
|
||||||
return status;
|
return status;
|
||||||
if (xdr_stream_decode_u32(argp->xdr, &gdev->gd_layout_type) < 0)
|
if (xdr_stream_decode_u32(argp->xdr, &gdev->gd_layout_type) < 0)
|
||||||
|
|
|
||||||
|
|
@ -595,9 +595,43 @@ struct nfsd4_reclaim_complete {
|
||||||
struct nfsd4_deviceid {
|
struct nfsd4_deviceid {
|
||||||
u64 fsid_idx;
|
u64 fsid_idx;
|
||||||
u32 generation;
|
u32 generation;
|
||||||
u32 pad;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static inline __be32 *
|
||||||
|
svcxdr_encode_deviceid4(__be32 *p, const struct nfsd4_deviceid *devid)
|
||||||
|
{
|
||||||
|
__be64 *q = (__be64 *)p;
|
||||||
|
|
||||||
|
*q = (__force __be64)devid->fsid_idx;
|
||||||
|
p += 2;
|
||||||
|
*p++ = (__force __be32)devid->generation;
|
||||||
|
*p++ = xdr_zero;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline __be32 *
|
||||||
|
svcxdr_decode_deviceid4(__be32 *p, struct nfsd4_deviceid *devid)
|
||||||
|
{
|
||||||
|
__be64 *q = (__be64 *)p;
|
||||||
|
|
||||||
|
devid->fsid_idx = (__force u64)(*q);
|
||||||
|
p += 2;
|
||||||
|
devid->generation = (__force u32)(*p++);
|
||||||
|
p++; /* NFSD does not use the remaining octets */
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline __be32
|
||||||
|
nfsd4_decode_deviceid4(struct xdr_stream *xdr, struct nfsd4_deviceid *devid)
|
||||||
|
{
|
||||||
|
__be32 *p = xdr_inline_decode(xdr, NFS4_DEVICEID4_SIZE);
|
||||||
|
|
||||||
|
if (unlikely(!p))
|
||||||
|
return nfserr_bad_xdr;
|
||||||
|
svcxdr_decode_deviceid4(p, devid);
|
||||||
|
return nfs_ok;
|
||||||
|
}
|
||||||
|
|
||||||
struct nfsd4_layout_seg {
|
struct nfsd4_layout_seg {
|
||||||
u32 iomode;
|
u32 iomode;
|
||||||
u64 offset;
|
u64 offset;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue