Skip to content

Commit 47c6099

Browse files
sbashirogregkh
authored andcommitted
NFSD: Rework encoding and decoding of nfsd4_deviceid
[ Upstream commit 832738e ] 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 <[email protected]> Signed-off-by: Chuck Lever <[email protected]> Stable-dep-of: d68886b ("NFSD: Fix last write offset handling in layoutcommit") Signed-off-by: Sasha Levin <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 5def53c commit 47c6099

File tree

5 files changed

+39
-22
lines changed

5 files changed

+39
-22
lines changed

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
@@ -566,18 +566,6 @@ nfsd4_decode_state_owner4(struct nfsd4_compoundargs *argp,
566566
}
567567

568568
#ifdef CONFIG_NFSD_PNFS
569-
static __be32
570-
nfsd4_decode_deviceid4(struct nfsd4_compoundargs *argp,
571-
struct nfsd4_deviceid *devid)
572-
{
573-
__be32 *p;
574-
575-
p = xdr_inline_decode(argp->xdr, NFS4_DEVICEID4_SIZE);
576-
if (!p)
577-
return nfserr_bad_xdr;
578-
memcpy(devid, p, sizeof(*devid));
579-
return nfs_ok;
580-
}
581569

582570
static __be32
583571
nfsd4_decode_layoutupdate4(struct nfsd4_compoundargs *argp,
@@ -1762,7 +1750,7 @@ nfsd4_decode_getdeviceinfo(struct nfsd4_compoundargs *argp,
17621750
__be32 status;
17631751

17641752
memset(gdev, 0, sizeof(*gdev));
1765-
status = nfsd4_decode_deviceid4(argp, &gdev->gd_devid);
1753+
status = nfsd4_decode_deviceid4(argp->xdr, &gdev->gd_devid);
17661754
if (status)
17671755
return status;
17681756
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
@@ -596,9 +596,43 @@ struct nfsd4_reclaim_complete {
596596
struct nfsd4_deviceid {
597597
u64 fsid_idx;
598598
u32 generation;
599-
u32 pad;
600599
};
601600

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

0 commit comments

Comments
 (0)