diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2020-07-08 13:13:54 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2020-08-18 07:18:41 +0200 |
commit | 80640fc8438237282c66063f72b6a3f8129d0e2f (patch) | |
tree | eb2d99bd8bd07fee803aea061ce7a3063cfbd81f | |
parent | telnet: Use rtems_shell_dup_current_env() (diff) | |
download | rtems-libbsd-80640fc8438237282c66063f72b6a3f8129d0e2f.tar.bz2 |
nfsclient: Next attempt to fix 64-bit targets5.1-freebsd-12
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.
-rw-r--r-- | rtemsbsd/nfsclient/nfs.c | 89 |
1 files changed, 27 insertions, 62 deletions
diff --git a/rtemsbsd/nfsclient/nfs.c b/rtemsbsd/nfsclient/nfs.c index d6f43305..3b8a5925 100644 --- a/rtemsbsd/nfsclient/nfs.c +++ b/rtemsbsd/nfsclient/nfs.c @@ -397,71 +397,36 @@ 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; @@ -493,7 +458,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 +2005,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 +2099,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 +2196,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)); |