]> www.infradead.org Git - users/hch/misc.git/commitdiff
NFSD: Rework encoding and decoding of nfsd4_deviceid
authorSergey Bashirov <sergeybashirov@gmail.com>
Mon, 21 Jul 2025 14:48:55 +0000 (17:48 +0300)
committerChuck Lever <chuck.lever@oracle.com>
Sun, 21 Sep 2025 23:24:50 +0000 (19:24 -0400)
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>
fs/nfsd/blocklayoutxdr.c
fs/nfsd/flexfilelayoutxdr.c
fs/nfsd/nfs4layouts.c
fs/nfsd/nfs4xdr.c
fs/nfsd/xdr4.h

index bcf21fde9120776daf4a4fa8c19740499fdba4f7..18de37ff289166d2cb7b2bf61d290cfd450bcc2e 100644 (file)
@@ -29,8 +29,7 @@ nfsd4_block_encode_layoutget(struct xdr_stream *xdr,
        *p++ = cpu_to_be32(len);
        *p++ = cpu_to_be32(1);          /* we always return a single extent */
 
-       p = xdr_encode_opaque_fixed(p, &b->vol_id,
-                       sizeof(struct nfsd4_deviceid));
+       p = svcxdr_encode_deviceid4(p, &b->vol_id);
        p = xdr_encode_hyper(p, b->foff);
        p = xdr_encode_hyper(p, b->len);
        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++) {
                struct pnfs_block_extent bex;
 
-               memcpy(&bex.vol_id, p, sizeof(struct nfsd4_deviceid));
-               p += XDR_QUADLEN(sizeof(struct nfsd4_deviceid));
-
+               p = svcxdr_decode_deviceid4(p, &bex.vol_id);
                p = xdr_decode_hyper(p, &bex.foff);
                if (bex.foff & (block_size - 1)) {
                        goto fail;
index aeb71c10ff1b963fdc3370a7d8f15cc14769c4d9..f9f7e38cba13fb53850cc57a4ad31c789dcb042d 100644 (file)
@@ -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 data server */
 
-       p = xdr_encode_opaque_fixed(p, &fl->deviceid,
-                       sizeof(struct nfsd4_deviceid));
+       p = svcxdr_encode_deviceid4(p, &fl->deviceid);
 
        *p++ = cpu_to_be32(1);                  /* efficiency */
 
index aea905fcaf87aa1c11481f04b819ab3a41cf19c5..683bd1130afe298f9df774684192c89f68102b72 100644 (file)
@@ -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->generation = device_generation;
-       id->pad = 0;
        return 0;
 }
 
index ea91bad4eee2cdcee6fd8f1d93c5f155dcd38172..2acc9abee668f33d2a273f91c2998282eeda069c 100644 (file)
@@ -587,18 +587,6 @@ nfsd4_decode_state_owner4(struct nfsd4_compoundargs *argp,
 }
 
 #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
 nfsd4_decode_layoutupdate4(struct nfsd4_compoundargs *argp,
@@ -1783,7 +1771,7 @@ nfsd4_decode_getdeviceinfo(struct nfsd4_compoundargs *argp,
        __be32 status;
 
        memset(gdev, 0, sizeof(*gdev));
-       status = nfsd4_decode_deviceid4(argp, &gdev->gd_devid);
+       status = nfsd4_decode_deviceid4(argp->xdr, &gdev->gd_devid);
        if (status)
                return status;
        if (xdr_stream_decode_u32(argp->xdr, &gdev->gd_layout_type) < 0)
index a23bc56051caf5d61788f1aaef078cba0cb7e0cb..e65b552bf5f5ab416dd70f800cf1240b1b60f263 100644 (file)
@@ -595,9 +595,43 @@ struct nfsd4_reclaim_complete {
 struct nfsd4_deviceid {
        u64                     fsid_idx;
        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 {
        u32                     iomode;
        u64                     offset;