In serporidok use the same structures used to hand over to the XDR
encode/decode routines.  We must not mix packed and unpacked structures.

Close #4024.
---
 rtemsbsd/nfsclient/nfs.c | 94 +++++++++++++---------------------------
 1 file changed, 29 insertions(+), 65 deletions(-)

diff --git a/rtemsbsd/nfsclient/nfs.c b/rtemsbsd/nfsclient/nfs.c
index d6f43305..fa5409c9 100644
--- a/rtemsbsd/nfsclient/nfs.c
+++ b/rtemsbsd/nfsclient/nfs.c
@@ -397,84 +397,48 @@ DirInfo   dip;
 
 /* Macro for accessing serporid fields
  */
-#define SERP_ARGS(node) ((node)->serporid.serporid_u.serporid.arg_u)
-#define SERP_ATTR(node) ((node)->serporid.serporid_u.serporid.attributes)
-#define SERP_FILE(node) ((node)->serporid.serporid_u.serporid.file)
-
-/*
- * FIXME: The use of the serporid structure with several embedded unions to
- * split up the specific NFS request/response structures is quite a hack.  It
- * breaks on 64-bit targets due to the presence of pointer members which affect
- * the overall alignment.  Use a packed serporidok structure to hopefully fix
- * this issue.
- */
+#define SERP_ARGS(node) ((node)->serporid.serporid)
+#define SERP_ATTR(node) ((node)->serporid.serporid.attributes)
+#define SERP_FILE(node) ((node)->serporid.serporid.file)
 
 typedef struct serporidok {
        fattr                                   attributes;
-       nfs_fh                                  file;
        union   {
-               struct {
-                       filename        name;
-               }                                       diroparg;
-               struct {
-                       sattr           attributes;
-               }                                       sattrarg;
-               struct {
-                       uint32_t        offset;
-                       uint32_t        count;
-                       uint32_t        totalcount;
-               }                                       readarg;
-               struct {
-                       uint32_t        beginoffset;
-                       uint32_t        offset;
-                       uint32_t        totalcount;
-                       struct {
-                               uint32_t data_len;
-                               char* data_val;
-                       }                       data;
-               }                                       writearg;
-               struct {
-                       filename        name;
-                       sattr           attributes;
-               }                                       createarg;
-               struct {
-                       filename        name;
-                       diropargs       to;
-               }                                       renamearg;
-               struct {
-                       diropargs       to;
-               }                                       linkarg;
-               struct {
-                       filename        name;
-                       nfspath         to;
-                       sattr           attributes;
-               }                                       symlinkarg;
-               struct {
-                       nfscookie       cookie;
-                       uint32_t        count;
-               }                                       readdirarg;
-       }                                                       arg_u;
-} RTEMS_PACKED serporidok;
+               nfs_fh                          file;
+               diropargs                       diroparg;
+               sattrargs                       sattrarg;
+               readargs                        readarg;
+               writeargs                       writearg;
+               createargs                      createarg;
+               renameargs                      renamearg;
+               linkargs                        linkarg;
+               symlinkargs                     symlinkarg;
+               readdirargs                     readdirarg;
+       };
+} serporidok;
 
+/*
+ * The nfsstat is an enum, so has an integer alignment.  The serporid contains
+ * pointers, so has at least a pointer alignment.  The packed attribute ensures
+ * that there is no gap between the status and serporid members on 64-bit
+ * targets.
+ */
 typedef struct serporid {
        nfsstat                 status;
-       union   {
-               serporidok      serporid;
-       }                               serporid_u;
-} serporid;
+       serporidok              serporid;
+} RTEMS_PACKED serporid;
 
 /* an XDR routine to encode/decode the inverted diropres
  * into an nfsnodestat;
  *
- * NOTE: this routine only acts on
+ * NOTE: this routine only acts on:
  *   - 'serporid.status'
  *   - 'serporid.file'
  *   - 'serporid.attributes'
- * and leaves the 'arg_u' alone.
  *
  * The idea is that a 'diropres' is read into 'serporid'
  * which can then be used as an argument to subsequent
- * NFS-RPCs (after filling in the node's arg_u).
+ * NFS-RPCs (after filling in the additional node's args).
  */
 static bool_t
 xdr_serporidok(XDR *xdrs, serporidok *objp)
@@ -493,7 +457,7 @@ xdr_serporid(XDR *xdrs, serporid *objp)
          return FALSE;
     switch (objp->status) {
     case NFS_OK:
-         if (!xdr_serporidok(xdrs, &objp->serporid_u.serporid))
+         if (!xdr_serporidok(xdrs, &objp->serporid))
              return FALSE;
         break;
     default:
@@ -2040,7 +2004,7 @@ char                                      *dupname;
 
         rtems_clock_get_tod_timeval(&now);
 
-       SERP_ARGS(node).createarg.name                  = dupname;
+       SERP_ARGS(node).createarg.where.name            = dupname;
        SERP_ARGS(node).createarg.attributes.mode       = mode;
        SERP_ARGS(node).createarg.attributes.uid        = nfs->uid;
        SERP_ARGS(node).createarg.attributes.gid        = nfs->gid;
@@ -2134,7 +2098,7 @@ char                                      *dupname;
 
        rtems_clock_get_tod_timeval(&now);
 
-       SERP_ARGS(node).symlinkarg.name                 = dupname;
+       SERP_ARGS(node).symlinkarg.from.name                    = dupname;
        SERP_ARGS(node).symlinkarg.to                           = (nfspath) 
target;
 
        SERP_ARGS(node).symlinkarg.attributes.mode      = S_IFLNK | S_IRWXU | 
S_IRWXG | S_IRWXO;
@@ -2231,7 +2195,7 @@ static int nfs_rename(
                nfs_fh *toDirDst = &SERP_ARGS(oldParentNode).renamearg.to.dir;
                nfsstat status;
 
-               SERP_ARGS(oldParentNode).renamearg.name = oldNode->str;
+               SERP_ARGS(oldParentNode).renamearg.from.name = oldNode->str;
                SERP_ARGS(oldParentNode).renamearg.to.name = dupname;
                memcpy(toDirDst, toDirSrc, sizeof(*toDirDst));
 
-- 
2.26.2

_______________________________________________
devel mailing list
devel@rtems.org
http://lists.rtems.org/mailman/listinfo/devel

Reply via email to