Thu May 27 06:54:45 2021 UTC ()
add bi-endian support to the libsa ufs reader and enable it in efiboot.

ffs frontends to "ufs.c" now also define ufs_dinode_swap, ufs_indp_swap,
and FS_MAGIC (moved from ufs.c #if segments.)  these are used to call
the right (32/64 bit) ffsv1/v2 version.

ufs.c 'struct file' gains f_swapped member.  accessors for d_magic,
d_reclen, and d_ino are introduced (they need to be swapped.)  sfter
reading an inode from disk, read_inode() may call ufs_dinode_swap().
indirect block number and caches may be swapped.

error handling in ffs_find_superblock() is cleaned up.  (size is slightly
reduced on some ports with this part.)

defaults for new defines added to ufs.c.  (XXX: we build ufs.c but i think
all the consumers don't use it, and we can stop building it.)

LFS support is not included.

add a cut-down copy of ffs_bswap.c from the kernel.

also enable bi-endian disklabel support in efiboot.

most ports build and sizes compared for platforms that don't enable this
code and all but one saw reduced code size.  booted several platforms with
new boot code.


(mrg)
diff -r1.94 -r1.95 src/sys/lib/libsa/Makefile
diff -r0 -r1.1 src/sys/lib/libsa/ffs_bswap.c
diff -r1.7 -r1.8 src/sys/lib/libsa/ffsv1.c
diff -r1.7 -r1.8 src/sys/lib/libsa/ffsv2.c
diff -r1.14 -r1.15 src/sys/lib/libsa/lfsv1.c
diff -r1.14 -r1.15 src/sys/lib/libsa/lfsv2.c
diff -r1.79 -r1.80 src/sys/lib/libsa/ufs.c
diff -r1.10 -r1.11 src/sys/lib/libsa/ufs.h
diff -r1.20 -r1.21 src/sys/stand/efiboot/Makefile.efiboot
diff -r1.24 -r1.25 src/sys/stand/efiboot/version

cvs diff -r1.94 -r1.95 src/sys/lib/libsa/Makefile (expand / switch to context diff)
--- src/sys/lib/libsa/Makefile 2021/05/17 08:50:36 1.94
+++ src/sys/lib/libsa/Makefile 2021/05/27 06:54:44 1.95
@@ -1,4 +1,4 @@
-#	$NetBSD: Makefile,v 1.94 2021/05/17 08:50:36 mrg Exp $
+#	$NetBSD: Makefile,v 1.95 2021/05/27 06:54:44 mrg Exp $
 
 LIB=	sa
 LIBISPRIVATE?= yes
@@ -80,7 +80,7 @@
 SRCS+=		byteorder.c
 .endif
 
-SRCS+=	ffsv1.c ffsv2.c
+SRCS+=	ffsv1.c ffsv2.c ffs_bswap.c
 SRCS+=	lfsv1.c lfsv2.c
 SRCS+=	cd9660.c
 SRCS+=	ustarfs.c

File Added: src/sys/lib/libsa/ffs_bswap.c
/*	$NetBSD: ffs_bswap.c,v 1.1 2021/05/27 06:54:44 mrg Exp $	*/

/*
 * Copyright (c) 1998 Manuel Bouyer.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

/*
 * This copy is a minimal version for libsa and it's ufs.c.  The unused
 * functions are removed, and additional swapping is performed on the
 * di_extb, di_db, and di_ib arrays.
 */

#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ffs_bswap.c,v 1.1 2021/05/27 06:54:44 mrg Exp $");

#include <sys/param.h>
#include <lib/libkern/libkern.h>

#include <ufs/ufs/dinode.h>
#include <ufs/ufs/quota.h>
#include <ufs/ufs/ufs_bswap.h>
#include <ufs/ffs/fs.h>
#include <ufs/ffs/ffs_extern.h>

static void
libsa_ffs_csumtotal_swap(const struct csum_total *o, struct csum_total *n)
{
	n->cs_ndir = bswap64(o->cs_ndir);
	n->cs_nbfree = bswap64(o->cs_nbfree);
	n->cs_nifree = bswap64(o->cs_nifree);
	n->cs_nffree = bswap64(o->cs_nffree);
}

void
ffs_sb_swap(const struct fs *o, struct fs *n)
{
	size_t i;
	const u_int32_t *o32;
	u_int32_t *n32;

	/*
	 * In order to avoid a lot of lines, as the first N fields (52)
	 * of the superblock up to fs_fmod are u_int32_t, we just loop
	 * here to convert them.
	 */
	o32 = (const u_int32_t *)o;
	n32 = (u_int32_t *)n;
	for (i = 0; i < offsetof(struct fs, fs_fmod) / sizeof(u_int32_t); i++)
		n32[i] = bswap32(o32[i]);

	n->fs_swuid = bswap64(o->fs_swuid);
	n->fs_cgrotor = bswap32(o->fs_cgrotor); /* Unused */
	n->fs_old_cpc = bswap32(o->fs_old_cpc);

	/* These fields overlap with a possible location for the
	 * historic FS_DYNAMICPOSTBLFMT postbl table, and with the
	 * first half of the historic FS_42POSTBLFMT postbl table.
	 */
	n->fs_maxbsize = bswap32(o->fs_maxbsize);
	/* XXX journal */
	n->fs_quota_magic = bswap32(o->fs_quota_magic);
	for (i = 0; i < MAXQUOTAS; i++)
		n->fs_quotafile[i] = bswap64(o->fs_quotafile[i]);
	n->fs_sblockloc = bswap64(o->fs_sblockloc);
	libsa_ffs_csumtotal_swap(&o->fs_cstotal, &n->fs_cstotal);
	n->fs_time = bswap64(o->fs_time);
	n->fs_size = bswap64(o->fs_size);
	n->fs_dsize = bswap64(o->fs_dsize);
	n->fs_csaddr = bswap64(o->fs_csaddr);
	n->fs_pendingblocks = bswap64(o->fs_pendingblocks);
	n->fs_pendinginodes = bswap32(o->fs_pendinginodes);

	/* These fields overlap with the second half of the
	 * historic FS_42POSTBLFMT postbl table
	 */
	for (i = 0; i < FSMAXSNAP; i++)
		n->fs_snapinum[i] = bswap32(o->fs_snapinum[i]);
	n->fs_avgfilesize = bswap32(o->fs_avgfilesize);
	n->fs_avgfpdir = bswap32(o->fs_avgfpdir);
	/* fs_sparecon[28] - ignore for now */
	n->fs_flags = bswap32(o->fs_flags);
	n->fs_contigsumsize = bswap32(o->fs_contigsumsize);
	n->fs_maxsymlinklen = bswap32(o->fs_maxsymlinklen);
	n->fs_old_inodefmt = bswap32(o->fs_old_inodefmt);
	n->fs_maxfilesize = bswap64(o->fs_maxfilesize);
	n->fs_qbmask = bswap64(o->fs_qbmask);
	n->fs_qfmask = bswap64(o->fs_qfmask);
	n->fs_state = bswap32(o->fs_state);
	n->fs_old_postblformat = bswap32(o->fs_old_postblformat);
	n->fs_old_nrpos = bswap32(o->fs_old_nrpos);
	n->fs_old_postbloff = bswap32(o->fs_old_postbloff);
	n->fs_old_rotbloff = bswap32(o->fs_old_rotbloff);

	n->fs_magic = bswap32(o->fs_magic);
}

void
ffs_dinode1_swap(struct ufs1_dinode *o, struct ufs1_dinode *n)
{
	size_t i;

	n->di_mode = bswap16(o->di_mode);
	n->di_nlink = bswap16(o->di_nlink);
	n->di_oldids[0] = bswap16(o->di_oldids[0]);
	n->di_oldids[1] = bswap16(o->di_oldids[1]);
	n->di_size = bswap64(o->di_size);
	n->di_atime = bswap32(o->di_atime);
	n->di_atimensec = bswap32(o->di_atimensec);
	n->di_mtime = bswap32(o->di_mtime);
	n->di_mtimensec = bswap32(o->di_mtimensec);
	n->di_ctime = bswap32(o->di_ctime);
	n->di_ctimensec = bswap32(o->di_ctimensec);
	/* Swap these here, unlike kernel version .*/
	for (i = 0; i < UFS_NDADDR; i++)
		n->di_db[i] = bswap32(o->di_db[i]);
	for (i = 0; i < UFS_NIADDR; i++)
		n->di_ib[i] = bswap32(o->di_ib[i]);
	n->di_flags = bswap32(o->di_flags);
	n->di_blocks = bswap32(o->di_blocks);
	n->di_gen = bswap32(o->di_gen);
	n->di_uid = bswap32(o->di_uid);
	n->di_gid = bswap32(o->di_gid);
}

void
ffs_dinode2_swap(struct ufs2_dinode *o, struct ufs2_dinode *n)
{
	size_t i;

	n->di_mode = bswap16(o->di_mode);
	n->di_nlink = bswap16(o->di_nlink);
	n->di_uid = bswap32(o->di_uid);
	n->di_gid = bswap32(o->di_gid);
	n->di_blksize = bswap32(o->di_blksize);
	n->di_size = bswap64(o->di_size);
	n->di_blocks = bswap64(o->di_blocks);
	n->di_atime = bswap64(o->di_atime);
	n->di_atimensec = bswap32(o->di_atimensec);
	n->di_mtime = bswap64(o->di_mtime);
	n->di_mtimensec = bswap32(o->di_mtimensec);
	n->di_ctime = bswap64(o->di_ctime);
	n->di_ctimensec = bswap32(o->di_ctimensec);
	n->di_birthtime = bswap64(o->di_birthtime);
	n->di_birthnsec = bswap32(o->di_birthnsec);
	n->di_gen = bswap32(o->di_gen);
	n->di_kernflags = bswap32(o->di_kernflags);
	n->di_flags = bswap32(o->di_flags);
	n->di_extsize = bswap32(o->di_extsize);
	/* Swap these here, unlike kernel version .*/
	for (i = 0; i < UFS_NXADDR; i++)
		n->di_extb[i] = bswap64(o->di_extb[i]);
	for (i = 0; i < UFS_NDADDR; i++)
		n->di_db[i] = bswap64(o->di_db[i]);
	for (i = 0; i < UFS_NIADDR; i++)
		n->di_ib[i] = bswap64(o->di_ib[i]);
}

cvs diff -r1.7 -r1.8 src/sys/lib/libsa/ffsv1.c (expand / switch to context diff)
--- src/sys/lib/libsa/ffsv1.c 2019/06/24 13:58:24 1.7
+++ src/sys/lib/libsa/ffsv1.c 2021/05/27 06:54:44 1.8
@@ -1,4 +1,4 @@
-/* $NetBSD: ffsv1.c,v 1.7 2019/06/24 13:58:24 pgoyette Exp $ */
+/* $NetBSD: ffsv1.c,v 1.8 2021/05/27 06:54:44 mrg Exp $ */
 
 #define LIBSA_FFSv1
 
@@ -13,7 +13,11 @@
 #endif
 
 #define ufs_dinode	ufs1_dinode
+#define ufs_dinode_swap	ffs_dinode1_swap
+#define ufs_indp_swap	bswap32
 #define indp_t		int32_t
+
+#define FS_MAGIC FS_UFS1_MAGIC
 
 #if 0
 #define	FSMOD	"wapbl/ufs/ffs"

cvs diff -r1.7 -r1.8 src/sys/lib/libsa/ffsv2.c (expand / switch to context diff)
--- src/sys/lib/libsa/ffsv2.c 2019/06/24 13:58:24 1.7
+++ src/sys/lib/libsa/ffsv2.c 2021/05/27 06:54:44 1.8
@@ -1,4 +1,4 @@
-/* $NetBSD: ffsv2.c,v 1.7 2019/06/24 13:58:24 pgoyette Exp $ */
+/* $NetBSD: ffsv2.c,v 1.8 2021/05/27 06:54:44 mrg Exp $ */
 
 #define LIBSA_FFSv2
 
@@ -13,7 +13,11 @@
 #endif
 
 #define ufs_dinode	ufs2_dinode
+#define ufs_dinode_swap	ffs_dinode2_swap
+#define ufs_indp_swap	bswap64
 #define indp_t		int64_t
+
+#define FS_MAGIC FS_UFS2_MAGIC
 
 #if 0
 #define	FSMOD	"wapbl/ufs/ffs"

cvs diff -r1.14 -r1.15 src/sys/lib/libsa/lfsv1.c (expand / switch to context diff)
--- src/sys/lib/libsa/lfsv1.c 2015/08/12 18:28:01 1.14
+++ src/sys/lib/libsa/lfsv1.c 2021/05/27 06:54:44 1.15
@@ -1,4 +1,4 @@
-/* $NetBSD: lfsv1.c,v 1.14 2015/08/12 18:28:01 dholland Exp $ */
+/* $NetBSD: lfsv1.c,v 1.15 2021/05/27 06:54:44 mrg Exp $ */
 
 #define	LIBSA_LFS
 #define	REQUIRED_LFS_VERSION	1
@@ -24,6 +24,8 @@
 #define ufs_lblkno(a, b)	lfs_lblkno((a), (b))
 #define dblksize(a, b, c)	lfs_dblksize((a), (b), (c))
 #define	FSBTODB(fs, daddr)	(daddr)		/* LFSv1 uses sectors for addresses */
+
+#define FS_MAGIC		LFS_MAGIC
 
 #define	FSMOD			"lfs"
 

cvs diff -r1.14 -r1.15 src/sys/lib/libsa/lfsv2.c (expand / switch to context diff)
--- src/sys/lib/libsa/lfsv2.c 2015/08/12 18:28:01 1.14
+++ src/sys/lib/libsa/lfsv2.c 2021/05/27 06:54:44 1.15
@@ -1,4 +1,4 @@
-/* $NetBSD: lfsv2.c,v 1.14 2015/08/12 18:28:01 dholland Exp $ */
+/* $NetBSD: lfsv2.c,v 1.15 2021/05/27 06:54:44 mrg Exp $ */
 
 #define	LIBSA_LFS
 #define	REQUIRED_LFS_VERSION	2
@@ -28,6 +28,8 @@
 #define ufs_lblkno(a, b)	lfs_lblkno((a), (b))
 #define dblksize(a, b, c)	lfs_dblksize((a), (b), (c))
 #define FSBTODB(a, b)		LFS_FSBTODB((a), (b))
+
+#define FS_MAGIC		LFS_MAGIC
 
 #define	FSMOD			"lfs"
 

cvs diff -r1.79 -r1.80 src/sys/lib/libsa/ufs.c (expand / switch to context diff)
--- src/sys/lib/libsa/ufs.c 2021/05/12 08:45:28 1.79
+++ src/sys/lib/libsa/ufs.c 2021/05/27 06:54:44 1.80
@@ -1,4 +1,4 @@
-/*	$NetBSD: ufs.c,v 1.79 2021/05/12 08:45:28 mrg Exp $	*/
+/*	$NetBSD: ufs.c,v 1.80 2021/05/27 06:54:44 mrg Exp $	*/
 
 /*-
  * Copyright (c) 1993
@@ -100,6 +100,8 @@
 #endif
 
 #ifdef LIBSA_LFS
+/* Do not (yet) support FFS_EI on LFS. */
+#undef LIBSA_FFS_EI
 /*
  * In-core LFS superblock - just the on-disk one.
  */
@@ -124,13 +126,11 @@
 #define fs_maxsymlinklen lfs_dlfs_u.u_32.dlfs_maxsymlinklen
 #define lfs_version	lfs_dlfs_u.u_32.dlfs_version
 
-#define FS_MAGIC	LFS_MAGIC
 #define SBLOCKSIZE	LFS_SBPAD
 #define SBLOCKOFFSET	LFS_LABELPAD
 #else
 /* NB ufs2 doesn't use the common superblock code... */
 typedef struct fs FS;
-#define FS_MAGIC	FS_UFS1_MAGIC
 #define SBLOCKOFFSET	SBLOCK_UFS1
 #endif
 
@@ -156,6 +156,9 @@
 #ifndef FSBTODB
 #define FSBTODB(fs, indp) FFS_FSBTODB(fs, indp)
 #endif
+#ifndef FS_MAGIC
+#define FS_MAGIC FS_UFS1_MAGIC
+#endif
 #ifndef UFS_NINDIR
 #define UFS_NINDIR FFS_NINDIR
 #endif
@@ -165,6 +168,12 @@
 #ifndef ufs_lblkno
 #define ufs_lblkno ffs_lblkno
 #endif
+#ifndef ufs_dinode_swap
+#define ufs_dinode_swap ffs_dinode1_swap
+#endif
+#ifndef ufs_indp_swap
+#define ufs_indp_swap bswap32
+#endif
 
 /*
  * To avoid having a lot of filesystem-block sized buffers lurking (which
@@ -192,6 +201,9 @@
 	char		*f_buf;		/* buffer for data block */
 	size_t		f_buf_size;	/* size of data block */
 	daddr_t		f_buf_blkno;	/* block number of data block */
+#if defined(LIBSA_FFS_EI)
+	bool		f_swapped;	/* FFS is other endian */
+#endif
 };
 
 static int read_inode(ino32_t, struct open_file *);
@@ -202,7 +214,53 @@
 static void ffs_oldfscompat(FS *);
 #endif
 
+static __inline__ bool
+ffs_is_magic(FS *fs)
+{
+	return fs->fs_magic == FS_MAGIC;
+}
 
+static __inline__ void
+ffs_fix_magic_swapped(struct file *fp, FS *fs)
+{
+#ifdef LIBSA_FFS_EI
+	fp->f_swapped = fs->fs_magic == bswap32(FS_MAGIC);
+	if (fp->f_swapped)
+{
+		ffs_sb_swap(fs, fs);
+}
+#endif
+}
+
+#ifdef LIBSA_FFS_EI
+static __inline__ bool
+ffs_swapped(struct file *fp)
+{
+	return fp->f_swapped;
+}
+#endif
+
+static __inline__ uint16_t
+ffs_get_reclen(struct file *fp, struct direct *dp)
+{
+#ifdef LIBSA_FFS_EI
+	if (ffs_swapped(fp))
+		return bswap16(dp->d_reclen);
+#endif
+	return dp->d_reclen;
+}
+
+static __inline__ uint32_t
+ffs_get_ino(struct file *fp, struct direct *dp)
+{
+#ifdef LIBSA_FFS_EI
+	if (ffs_swapped(fp))
+		return bswap32(dp->d_ino);
+#endif
+	return dp->d_ino;
+}
+
+
 #ifdef LIBSA_LFS
 /*
  * Find an inode's block.  Look it up in the ifile.  Whee!
@@ -291,7 +349,11 @@
 	fp->f_di = *dip;
 #else
 	fp->f_di = ((struct ufs_dinode *)buf)[ino_to_fsbo(fs, inumber)];
+#ifdef LIBSA_FFS_EI
+	if (ffs_swapped(fp))
+		ufs_dinode_swap(&fp->f_di, &fp->f_di);
 #endif
+#endif
 
 	/*
 	 * Clear out the old buffers
@@ -387,15 +449,30 @@
 			return rc;
 		if (rsize != (size_t)fs->fs_bsize)
 			return EIO;
-		ind_block_num = buf[file_block >> level];
+#ifdef LIBSA_FFS_EI
+		if (ffs_swapped(fp))
+			ind_block_num = ufs_indp_swap(buf[file_block >> level]);
+		else
+#endif
+			ind_block_num = buf[file_block >> level];
 		if (level == 0)
 			break;
 		file_block &= (1 << level) - 1;
 	}
 
 	/* Save the part of the block that contains this sector */
-	memcpy(fp->f_ind_cache, &buf[file_block & ~IND_CACHE_MASK],
-	    IND_CACHE_SZ * sizeof fp->f_ind_cache[0]);
+#if defined(LIBSA_FFS_EI)
+	if (ffs_swapped(fp)) {
+		size_t i;
+
+		for (i = 0; i < IND_CACHE_SZ; i++) {
+			fp->f_ind_cache[i] = ufs_indp_swap(
+			    buf[(file_block & ~IND_CACHE_MASK) + i]);
+		}
+	} else
+#endif
+		memcpy(fp->f_ind_cache, &buf[file_block & ~IND_CACHE_MASK],
+		    IND_CACHE_SZ * sizeof fp->f_ind_cache[0]);
 	fp->f_ind_cache_block = ind_cache;
 
 	*disk_block_p = ind_block_num;
@@ -487,10 +564,11 @@
 
 		dp = (struct direct *)buf;
 		edp = (struct direct *)(buf + buf_size);
-		for (;dp < edp; dp = (void *)((char *)dp + dp->d_reclen)) {
-			if (dp->d_reclen <= 0)
+		for (; dp < edp;
+		     dp = (void *)((char *)dp + ffs_get_reclen(fp, dp))) {
+			if (ffs_get_reclen(fp, dp) <= 0)
 				break;
-			if (dp->d_ino == (ino32_t)0)
+			if (ffs_get_ino(fp, dp) == (ino32_t)0)
 				continue;
 #if BYTE_ORDER == LITTLE_ENDIAN
 			if (fp->f_fs->fs_maxsymlinklen <= 0)
@@ -501,7 +579,7 @@
 			if (namlen == length &&
 			    !memcmp(name, dp->d_name, length)) {
 				/* found entry */
-				*inumber_p = dp->d_ino;
+				*inumber_p = ffs_get_ino(fp, dp);
 				return 0;
 			}
 		}
@@ -513,6 +591,7 @@
 static __inline__ int
 ffs_find_superblock(struct open_file *f, FS *fs)
 {
+	struct file *fp = (struct file *)f->f_fsdata;
 	int rc;
 	size_t buf_size;
 #ifdef LIBSA_FFSv2
@@ -522,14 +601,16 @@
 	for (i = 0; sblock_try[i] != -1; i++) {
 		rc = DEV_STRATEGY(f->f_dev)(f->f_devdata, F_READ,
 		    sblock_try[i] / DEV_BSIZE, SBLOCKSIZE, fs, &buf_size);
-		if (rc != 0 || buf_size != SBLOCKSIZE)
+		if (rc)
 			return rc;
+		if (buf_size != SBLOCKSIZE)
+			return EINVAL;
+		ffs_fix_magic_swapped(fp, fs);
 		if (fs->fs_sblockloc != sblock_try[i])
 			/* an alternate superblock - try again */
 			continue;
-		if (fs->fs_magic == FS_UFS2_MAGIC) {
+		if (ffs_is_magic(fs))
 			return 0;
-		}
 	}
 	return EINVAL;
 #else /* LIBSA_FFSv2 */
@@ -537,12 +618,17 @@
 		SBLOCKOFFSET / DEV_BSIZE, SBLOCKSIZE, fs, &buf_size);
 	if (rc)
 		return rc;
-	if (buf_size != SBLOCKSIZE ||
+	if (buf_size != SBLOCKSIZE)
+		return EINVAL;
+	ffs_fix_magic_swapped(fp, fs);
+
 #ifdef LIBSA_LFS
-	    fs->lfs_version != REQUIRED_LFS_VERSION ||
+	if (fs->lfs_version != REQUIRED_LFS_VERSION)
+		return EINVAL;
 #endif
-	    fs->fs_magic != FS_MAGIC)
+	if (!ffs_is_magic(fs))
 		return EINVAL;
+
 	return 0;
 #endif /* !LIBSA_FFSv2 */
 }
@@ -915,9 +1001,10 @@
 		dp = (struct direct *)buf;
 		edp = (struct direct *)(buf + buf_size);
 
-		for (; dp < edp; dp = (void *)((char *)dp + dp->d_reclen)) {
+		for (; dp < edp;
+		     dp = (void *)((char *)dp + ffs_get_reclen(fp, dp))) {
 			const char *t;
-			if (dp->d_ino ==  0)
+			if (ffs_get_ino(fp, dp) == 0)
 				continue;
 
 			if (dp->d_type >= NELEM(typestr) ||
@@ -936,7 +1023,7 @@
 				goto out;
 			}
 			lsadd(&names, pattern, dp->d_name, strlen(dp->d_name),
-			    dp->d_ino, t);
+			    ffs_get_ino(fp, dp), t);
 		}
 		fp->f_seekp += buf_size;
 	}

cvs diff -r1.10 -r1.11 src/sys/lib/libsa/ufs.h (expand / switch to context diff)
--- src/sys/lib/libsa/ufs.h 2011/12/25 06:09:08 1.10
+++ src/sys/lib/libsa/ufs.h 2021/05/27 06:54:44 1.11
@@ -1,4 +1,4 @@
-/*	$NetBSD: ufs.h,v 1.10 2011/12/25 06:09:08 tsutsui Exp $	*/
+/*	$NetBSD: ufs.h,v 1.11 2021/05/27 06:54:44 mrg Exp $	*/
 
 /*-
  * Copyright (c) 1993
@@ -34,3 +34,11 @@
 FS_DEF(ufs);
 FS_DEF(ffsv1);
 FS_DEF(ffsv2);
+
+/* in libsa's ffs_bswap.c */
+struct fs;
+struct ufs1_dinode;
+struct ufs2_dinode;
+void ffs_sb_swap(const struct fs *, struct fs *);
+void ffs_dinode1_swap(struct ufs1_dinode *, struct ufs1_dinode *);
+void ffs_dinode2_swap(struct ufs2_dinode *, struct ufs2_dinode *);

cvs diff -r1.20 -r1.21 src/sys/stand/efiboot/Makefile.efiboot (expand / switch to context diff)
--- src/sys/stand/efiboot/Makefile.efiboot 2021/05/04 19:07:19 1.20
+++ src/sys/stand/efiboot/Makefile.efiboot 2021/05/27 06:54:45 1.21
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile.efiboot,v 1.20 2021/05/04 19:07:19 jmcneill Exp $
+# $NetBSD: Makefile.efiboot,v 1.21 2021/05/27 06:54:45 mrg Exp $
 
 S=		${.CURDIR}/../../..
 
@@ -80,6 +80,8 @@
 #CPPFLAGS+= -DSUPPORT_NFS
 CPPFLAGS+= -DSUPPORT_TFTP
 CPPFLAGS+= -DLIBSA_ENABLE_LS_OP
+CPPFLAGS+= -DLIBSA_FFS_EI
+CPPFLAGS+= -DLIBSA_DISKLABEL_EI
 
 #CPPFLAGS+= -DEFIBOOT_DEBUG
 #CPPFLAGS+= -DARP_DEBUG

cvs diff -r1.24 -r1.25 src/sys/stand/efiboot/version (expand / switch to context diff)
--- src/sys/stand/efiboot/version 2021/05/26 09:42:36 1.24
+++ src/sys/stand/efiboot/version 2021/05/27 06:54:45 1.25
@@ -1,4 +1,4 @@
-$NetBSD: version,v 1.24 2021/05/26 09:42:36 mrg Exp $
+$NetBSD: version,v 1.25 2021/05/27 06:54:45 mrg Exp $
 
 NOTE ANY CHANGES YOU MAKE TO THE EFI BOOTLOADER HERE.  The format of this
 file is important - make sure the entries are appended on end, last item
@@ -28,3 +28,4 @@
 2.5:	Recognize the EFI system partion as fstype MSDOS.
 2.6:	Disable ACPI support when booting big endian kernels.
 2.7:	Add basic support for booting from RAID1 volumes.
+2.8:	Add bi-endian disklabel and FFS support.