Skip to content

Commit 832738e

Browse files
sbashirochucklever
authored andcommitted
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>
1 parent c97b737 commit 832738e

5 files changed

Lines changed: 39 additions & 22 deletions

File tree

fs/nfsd/blocklayoutxdr.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,7 @@ nfsd4_block_encode_layoutget(struct xdr_stream *xdr,
2929
*p++ = cpu_to_be32(len);
3030
*p++ = cpu_to_be32(1); /* we always return a single extent */
3131

32-
p = xdr_encode_opaque_fixed(p, &b->vol_id,
33-
sizeof(struct nfsd4_deviceid));
32+
p = svcxdr_encode_deviceid4(p, &b->vol_id);
3433
p = xdr_encode_hyper(p, b->foff);
3534
p = xdr_encode_hyper(p, b->len);
3635
p = xdr_encode_hyper(p, b->soff);
@@ -156,9 +155,7 @@ nfsd4_block_decode_layoutupdate(__be32 *p, u32 len, struct iomap **iomapp,
156155
for (i = 0; i < nr_iomaps; i++) {
157156
struct pnfs_block_extent bex;
158157

159-
memcpy(&bex.vol_id, p, sizeof(struct nfsd4_deviceid));
160-
p += XDR_QUADLEN(sizeof(struct nfsd4_deviceid));
161-
158+
p = svcxdr_decode_deviceid4(p, &bex.vol_id);
162159
p = xdr_decode_hyper(p, &bex.foff);
163160
if (bex.foff & (block_size - 1)) {
164161
goto fail;

fs/nfsd/flexfilelayoutxdr.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,7 @@ nfsd4_ff_encode_layoutget(struct xdr_stream *xdr,
5454
*p++ = cpu_to_be32(1); /* single mirror */
5555
*p++ = cpu_to_be32(1); /* single data server */
5656

57-
p = xdr_encode_opaque_fixed(p, &fl->deviceid,
58-
sizeof(struct nfsd4_deviceid));
57+
p = svcxdr_encode_deviceid4(p, &fl->deviceid);
5958

6059
*p++ = cpu_to_be32(1); /* efficiency */
6160

fs/nfsd/nfs4layouts.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,6 @@ nfsd4_set_deviceid(struct nfsd4_deviceid *id, const struct svc_fh *fhp,
120120

121121
id->fsid_idx = fhp->fh_export->ex_devid_map->idx;
122122
id->generation = device_generation;
123-
id->pad = 0;
124123
return 0;
125124
}
126125

fs/nfsd/nfs4xdr.c

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -587,18 +587,6 @@ nfsd4_decode_state_owner4(struct nfsd4_compoundargs *argp,
587587
}
588588

589589
#ifdef CONFIG_NFSD_PNFS
590-
static __be32
591-
nfsd4_decode_deviceid4(struct nfsd4_compoundargs *argp,
592-
struct nfsd4_deviceid *devid)
593-
{
594-
__be32 *p;
595-
596-
p = xdr_inline_decode(argp->xdr, NFS4_DEVICEID4_SIZE);
597-
if (!p)
598-
return nfserr_bad_xdr;
599-
memcpy(devid, p, sizeof(*devid));
600-
return nfs_ok;
601-
}
602590

603591
static __be32
604592
nfsd4_decode_layoutupdate4(struct nfsd4_compoundargs *argp,
@@ -1783,7 +1771,7 @@ nfsd4_decode_getdeviceinfo(struct nfsd4_compoundargs *argp,
17831771
__be32 status;
17841772

17851773
memset(gdev, 0, sizeof(*gdev));
1786-
status = nfsd4_decode_deviceid4(argp, &gdev->gd_devid);
1774+
status = nfsd4_decode_deviceid4(argp->xdr, &gdev->gd_devid);
17871775
if (status)
17881776
return status;
17891777
if (xdr_stream_decode_u32(argp->xdr, &gdev->gd_layout_type) < 0)

fs/nfsd/xdr4.h

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -595,9 +595,43 @@ struct nfsd4_reclaim_complete {
595595
struct nfsd4_deviceid {
596596
u64 fsid_idx;
597597
u32 generation;
598-
u32 pad;
599598
};
600599

600+
static inline __be32 *
601+
svcxdr_encode_deviceid4(__be32 *p, const struct nfsd4_deviceid *devid)
602+
{
603+
__be64 *q = (__be64 *)p;
604+
605+
*q = (__force __be64)devid->fsid_idx;
606+
p += 2;
607+
*p++ = (__force __be32)devid->generation;
608+
*p++ = xdr_zero;
609+
return p;
610+
}
611+
612+
static inline __be32 *
613+
svcxdr_decode_deviceid4(__be32 *p, struct nfsd4_deviceid *devid)
614+
{
615+
__be64 *q = (__be64 *)p;
616+
617+
devid->fsid_idx = (__force u64)(*q);
618+
p += 2;
619+
devid->generation = (__force u32)(*p++);
620+
p++; /* NFSD does not use the remaining octets */
621+
return p;
622+
}
623+
624+
static inline __be32
625+
nfsd4_decode_deviceid4(struct xdr_stream *xdr, struct nfsd4_deviceid *devid)
626+
{
627+
__be32 *p = xdr_inline_decode(xdr, NFS4_DEVICEID4_SIZE);
628+
629+
if (unlikely(!p))
630+
return nfserr_bad_xdr;
631+
svcxdr_decode_deviceid4(p, devid);
632+
return nfs_ok;
633+
}
634+
601635
struct nfsd4_layout_seg {
602636
u32 iomode;
603637
u64 offset;

0 commit comments

Comments
 (0)