Hi,

This is amd64 only, it contains some i386 pieces, but those are
incomplete.

With the diff, install uses ffs2 for the filesystems created during
install. All boot loaders (except the floppy one) contain support for
loading a kernel from ffs2.

To test, create a snapshot (see release(8)) with this diff and use it
to install a new system. You could also use the snap at
www.drijf.net/openbsd/66. Note that it is unsigned.

Note that when you manually create an fs, it still will be ffs1 by
default. That is to not disturb other platforms. Use -O2 for ffs2.

Please test and provide feedback. One think you should see is that the
newfs is much faster and fsck as well, since ffs2 creates inodes
lazily and thus has much less inodes to check in the typical case.

        -Otto

PS: the snap was built without the new boot version numbers.

Index: distrib/amd64/common/install.md
===================================================================
RCS file: /cvs/src/distrib/amd64/common/install.md,v
retrieving revision 1.55
diff -u -p -r1.55 install.md
--- distrib/amd64/common/install.md     28 Jul 2017 18:15:44 -0000      1.55
+++ distrib/amd64/common/install.md     20 Feb 2020 12:36:11 -0000
@@ -34,6 +34,8 @@
 MDXAPERTURE=2
 MDXDM=y
 NCPU=$(sysctl -n hw.ncpufound)
+MDFSOPT=-O2
+MDROOTFSOPT=-O2
 
 if dmesg | grep -q 'efifb0 at mainbus0'; then
        MDEFI=y
Index: distrib/miniroot/install.sub
===================================================================
RCS file: /cvs/src/distrib/miniroot/install.sub,v
retrieving revision 1.1147
diff -u -p -r1.1147 install.sub
--- distrib/miniroot/install.sub        2 Feb 2020 20:33:52 -0000       1.1147
+++ distrib/miniroot/install.sub        20 Feb 2020 12:36:11 -0000
@@ -507,7 +507,7 @@ configure_disk() {
 
                        # Use machine-dependent newfs options for the root
                        # partition if defined.
-                       _opt=
+                       _opt=$MDFSOPT
                        [[ $_mp == / ]] && _opt=$MDROOTFSOPT
 
                        newfs -q $_opt ${_pp##/dev/}
@@ -3328,6 +3328,7 @@ umount -af >/dev/null 2>&1
 #
 # The following variables can be provided if required:
 #      MDEFI       - set to 'y' on archs that support GPT partitioning
+#      MDFSOPT     - newfs options for non-root partitions
 #      MDROOTFSOPT - newfs options for the root partition
 #      MDSETS      - list of files to add to DEFAULT and ALLSETS
 #      MDSANESETS  - list of files to add to SANESETS
Index: sys/arch/amd64/stand/biosboot/biosboot.S
===================================================================
RCS file: /cvs/src/sys/arch/amd64/stand/biosboot/biosboot.S,v
retrieving revision 1.7
diff -u -p -r1.7 biosboot.S
--- sys/arch/amd64/stand/biosboot/biosboot.S    5 Jul 2011 17:38:54 -0000       
1.7
+++ sys/arch/amd64/stand/biosboot/biosboot.S    20 Feb 2020 12:36:32 -0000
@@ -108,6 +108,9 @@
  *                     While this can be calculated as
  *                     howmany(di_size, fs_bsize) it takes us too
  *                     many code bytes to do it.
+ * blkskew     uint8t  the skew used to parse di_db[]. this is set to four by
+ *                     installboot for ffs2 (due to 64-bit blocks) and should
+ *                     be zero for ffs1.
  *
  * All of these are patched directly into the code where they are used
  * (once only, each), to save space.
@@ -121,7 +124,7 @@
  */
 
        .globl  inodeblk, inodedbl, fs_bsize_p, fsbtodb, p_offset, nblocks
-       .globl  fs_bsize_s, force_chs
+       .globl  fs_bsize_s, force_chs, blkskew
        .type   inodeblk, @function
        .type   inodedbl, @function
        .type   fs_bsize_p, @function
@@ -130,6 +133,7 @@
        .type   p_offset, @function
        .type   nblocks, @function
        .type   force_chs, @function
+       .type   blkskew, @function
 
 
 /* Clobbers %ax, maybe more */
@@ -460,6 +464,8 @@ load_blocks:
 
        /* Get the next filesystem block number into %eax */
        lodsl                   /* %eax = *(%si++), make sure 0x66 0xad */
+blkskew = .+2
+       addw    $0x90, %si      /* adjust %si if needed (for ffs2) */
 
        pushal                          /* Save all 32-bit registers */
 
Index: sys/arch/amd64/stand/boot/Makefile
===================================================================
RCS file: /cvs/src/sys/arch/amd64/stand/boot/Makefile,v
retrieving revision 1.44
diff -u -p -r1.44 Makefile
--- sys/arch/amd64/stand/boot/Makefile  28 Nov 2019 00:17:10 -0000      1.44
+++ sys/arch/amd64/stand/boot/Makefile  20 Feb 2020 12:36:32 -0000
@@ -40,6 +40,9 @@ SRCS+=        close.c closeall.c cons.c cread.c
        fstat.c lseek.c open.c read.c readdir.c stat.c
 SRCS+= elf32.c elf64.c loadfile.c arc4.c
 SRCS+= ufs.c
+.if empty(COPTS:M-DFDBOOT)
+SRCS+= ufs2.c
+.endif
 .if ${SOFTRAID:L} == "yes"
 SRCS+= aes_xts.c bcrypt_pbkdf.c blowfish.c explicit_bzero.c hmac_sha1.c \
        pkcs5_pbkdf2.c rijndael.c sha1.c sha2.c softraid.c
Index: sys/arch/amd64/stand/boot/conf.c
===================================================================
RCS file: /cvs/src/sys/arch/amd64/stand/boot/conf.c,v
retrieving revision 1.49
diff -u -p -r1.49 conf.c
--- sys/arch/amd64/stand/boot/conf.c    29 Oct 2019 02:55:50 -0000      1.49
+++ sys/arch/amd64/stand/boot/conf.c    20 Feb 2020 12:36:32 -0000
@@ -30,6 +30,7 @@
 #include <netinet/in.h>
 #include <libsa.h>
 #include <lib/libsa/ufs.h>
+#include <lib/libsa/ufs2.h>
 #ifdef notdef
 #include <lib/libsa/cd9660.h>
 #include <lib/libsa/fat.h>
@@ -40,7 +41,7 @@
 #include <biosdev.h>
 #include <dev/cons.h>
 
-const char version[] = "3.46";
+const char version[] = "3.47";
 int    debug = 1;
 
 
@@ -64,6 +65,10 @@ int nibprobes = nitems(probe_list);
 struct fs_ops file_system[] = {
        { ufs_open,    ufs_close,    ufs_read,    ufs_write,    ufs_seek,
          ufs_stat,    ufs_readdir,  ufs_fchmod },
+#ifndef FDBOOT
+       { ufs2_open,   ufs2_close,   ufs2_read,   ufs2_write,   ufs2_seek,
+         ufs2_stat,   ufs2_readdir, ufs2_fchmod },
+#endif
 #ifdef notdef
        { fat_open,    fat_close,    fat_read,    fat_write,    fat_seek,
          fat_stat,    fat_readdir    },
Index: sys/arch/amd64/stand/cdboot/Makefile
===================================================================
RCS file: /cvs/src/sys/arch/amd64/stand/cdboot/Makefile,v
retrieving revision 1.39
diff -u -p -r1.39 Makefile
--- sys/arch/amd64/stand/cdboot/Makefile        28 Nov 2019 00:17:10 -0000      
1.39
+++ sys/arch/amd64/stand/cdboot/Makefile        20 Feb 2020 12:36:32 -0000
@@ -31,7 +31,7 @@ SRCS+=        alloc.c exit.c getchar.c hexdump.
 SRCS+= close.c closeall.c dev.c disklabel.c dkcksum.c fchmod.c fstat.c \
        lseek.c open.c read.c stat.c cread.c readdir.c cons.c \
        loadfile.c arc4.c elf32.c elf64.c
-SRCS+= ufs.c cd9660.c
+SRCS+= ufs.c ufs2.c cd9660.c
 SRCS+= aes_xts.c bcrypt_pbkdf.c blowfish.c explicit_bzero.c hmac_sha1.c \
        pkcs5_pbkdf2.c rijndael.c sha1.c sha2.c softraid.c
 
Index: sys/arch/amd64/stand/cdboot/conf.c
===================================================================
RCS file: /cvs/src/sys/arch/amd64/stand/cdboot/conf.c,v
retrieving revision 1.43
diff -u -p -r1.43 conf.c
--- sys/arch/amd64/stand/cdboot/conf.c  29 Oct 2019 02:55:50 -0000      1.43
+++ sys/arch/amd64/stand/cdboot/conf.c  20 Feb 2020 12:36:32 -0000
@@ -31,6 +31,7 @@
 #include <netinet/in.h>
 #include <libsa.h>
 #include <lib/libsa/ufs.h>
+#include <lib/libsa/ufs2.h>
 #include <lib/libsa/cd9660.h>
 #ifdef notdef
 #include <lib/libsa/fat.h>
@@ -41,7 +42,7 @@
 #include <biosdev.h>
 #include <dev/cons.h>
 
-const char version[] = "3.45";
+const char version[] = "3.46";
 int    debug = 1;
 
 
@@ -66,6 +67,8 @@ struct fs_ops file_system[] = {
          cd9660_stat, cd9660_readdir },
        { ufs_open,    ufs_close,    ufs_read,    ufs_write,    ufs_seek,
          ufs_stat,    ufs_readdir,  ufs_fchmod },
+       { ufs2_open,   ufs2_close,   ufs2_read,   ufs2_write,   ufs2_seek,
+         ufs2_stat,   ufs2_readdir, ufs2_fchmod },
 #ifdef notdef
        { tftp_open,   tftp_close,   tftp_read,   tftp_write,   tftp_seek,
          tftp_stat,   tftp_readdir   },
Index: sys/arch/amd64/stand/efi32/Makefile.common
===================================================================
RCS file: /cvs/src/sys/arch/amd64/stand/efi32/Makefile.common,v
retrieving revision 1.4
diff -u -p -r1.4 Makefile.common
--- sys/arch/amd64/stand/efi32/Makefile.common  28 Nov 2019 00:17:10 -0000      
1.4
+++ sys/arch/amd64/stand/efi32/Makefile.common  20 Feb 2020 12:36:32 -0000
@@ -38,7 +38,7 @@ SRCS+=        alloc.c ctime.c exit.c getchar.c 
        strtol.c strtoll.c
 SRCS+= close.c closeall.c cons.c cread.c dev.c disklabel.c dkcksum.c fchmod.c \
        fstat.c lseek.c open.c read.c readdir.c stat.c
-SRCS+= ufs.c cd9660.c
+SRCS+= ufs.c ufs2.c cd9660.c
 .if ${SOFTRAID:L} == "yes"
 SRCS+= aes_xts.c bcrypt_pbkdf.c blowfish.c explicit_bzero.c hmac_sha1.c \
        pkcs5_pbkdf2.c rijndael.c sha1.c sha2.c softraid.c
Index: sys/arch/amd64/stand/efi32/conf.c
===================================================================
RCS file: /cvs/src/sys/arch/amd64/stand/efi32/conf.c,v
retrieving revision 1.6
diff -u -p -r1.6 conf.c
--- sys/arch/amd64/stand/efi32/conf.c   29 Oct 2019 02:55:50 -0000      1.6
+++ sys/arch/amd64/stand/efi32/conf.c   20 Feb 2020 12:36:32 -0000
@@ -30,6 +30,7 @@
 #include <sys/disklabel.h>
 #include <libsa.h>
 #include <lib/libsa/ufs.h>
+#include <lib/libsa/ufs2.h>
 #include <lib/libsa/tftp.h>
 #include <lib/libsa/cd9660.h>
 #include <dev/cons.h>
@@ -39,7 +40,7 @@
 #include "efidev.h"
 #include "efipxe.h"
 
-const char version[] = "3.47";
+const char version[] = "3.48";
 
 #ifdef EFI_DEBUG
 int    debug = 0;
@@ -67,6 +68,8 @@ struct fs_ops file_system[] = {
          tftp_stat,   tftp_readdir   },
        { ufs_open,    ufs_close,    ufs_read,    ufs_write,    ufs_seek,
          ufs_stat,    ufs_readdir,  ufs_fchmod },
+       { ufs2_open,   ufs2_close,   ufs2_read,   ufs2_write,   ufs2_seek,
+         ufs2_stat,   ufs2_readdir, ufs2_fchmod },
        { cd9660_open, cd9660_close, cd9660_read, cd9660_write, cd9660_seek,
          cd9660_stat, cd9660_readdir },
 #ifdef notdef
Index: sys/arch/amd64/stand/efi64/Makefile.common
===================================================================
RCS file: /cvs/src/sys/arch/amd64/stand/efi64/Makefile.common,v
retrieving revision 1.4
diff -u -p -r1.4 Makefile.common
--- sys/arch/amd64/stand/efi64/Makefile.common  28 Nov 2019 00:17:11 -0000      
1.4
+++ sys/arch/amd64/stand/efi64/Makefile.common  20 Feb 2020 12:36:32 -0000
@@ -38,7 +38,7 @@ SRCS+=        alloc.c ctime.c exit.c getchar.c 
        strtol.c strtoll.c
 SRCS+= close.c closeall.c cons.c cread.c dev.c disklabel.c dkcksum.c fchmod.c \
        fstat.c lseek.c open.c read.c readdir.c stat.c
-SRCS+= ufs.c cd9660.c
+SRCS+= ufs.c ufs2.c cd9660.c
 .if ${SOFTRAID:L} == "yes"
 SRCS+= aes_xts.c bcrypt_pbkdf.c blowfish.c explicit_bzero.c hmac_sha1.c \
        pkcs5_pbkdf2.c rijndael.c sha1.c sha2.c softraid.c
Index: sys/arch/amd64/stand/efi64/conf.c
===================================================================
RCS file: /cvs/src/sys/arch/amd64/stand/efi64/conf.c,v
retrieving revision 1.5
diff -u -p -r1.5 conf.c
--- sys/arch/amd64/stand/efi64/conf.c   29 Oct 2019 02:55:50 -0000      1.5
+++ sys/arch/amd64/stand/efi64/conf.c   20 Feb 2020 12:36:32 -0000
@@ -30,6 +30,7 @@
 #include <sys/disklabel.h>
 #include <libsa.h>
 #include <lib/libsa/ufs.h>
+#include <lib/libsa/ufs2.h>
 #include <lib/libsa/tftp.h>
 #include <lib/libsa/cd9660.h>
 #include <dev/cons.h>
@@ -39,7 +40,7 @@
 #include "efidev.h"
 #include "efipxe.h"
 
-const char version[] = "3.47";
+const char version[] = "3.48";
 
 #ifdef EFI_DEBUG
 int    debug = 0;
@@ -67,6 +68,8 @@ struct fs_ops file_system[] = {
          tftp_stat,   tftp_readdir   },
        { ufs_open,    ufs_close,    ufs_read,    ufs_write,    ufs_seek,
          ufs_stat,    ufs_readdir,  ufs_fchmod },
+       { ufs2_open,   ufs2_close,   ufs2_read,   ufs2_write,   ufs2_seek,
+         ufs2_stat,   ufs2_readdir, ufs2_fchmod },
        { cd9660_open, cd9660_close, cd9660_read, cd9660_write, cd9660_seek,
          cd9660_stat, cd9660_readdir },
 #ifdef notdef
Index: sys/arch/amd64/stand/efiboot/Makefile.common
===================================================================
RCS file: /cvs/src/sys/arch/amd64/stand/efiboot/Makefile.common,v
retrieving revision 1.19
diff -u -p -r1.19 Makefile.common
--- sys/arch/amd64/stand/efiboot/Makefile.common        28 Nov 2019 00:17:11 
-0000      1.19
+++ sys/arch/amd64/stand/efiboot/Makefile.common        20 Feb 2020 12:36:32 
-0000
@@ -38,7 +38,7 @@ SRCS+=        alloc.c ctime.c exit.c getchar.c 
        strtol.c strtoll.c
 SRCS+= close.c closeall.c cons.c cread.c dev.c disklabel.c dkcksum.c \
        fchmod.c fstat.c lseek.c open.c read.c readdir.c stat.c
-SRCS+= ufs.c cd9660.c
+SRCS+= ufs.c ufs2.c cd9660.c
 .if ${SOFTRAID:L} == "yes"
 SRCS+= aes_xts.c bcrypt_pbkdf.c blowfish.c explicit_bzero.c hmac_sha1.c \
        pkcs5_pbkdf2.c rijndael.c sha1.c sha2.c softraid.c
Index: sys/arch/amd64/stand/efiboot/conf.c
===================================================================
RCS file: /cvs/src/sys/arch/amd64/stand/efiboot/conf.c,v
retrieving revision 1.25
diff -u -p -r1.25 conf.c
--- sys/arch/amd64/stand/efiboot/conf.c 29 Nov 2019 16:16:19 -0000      1.25
+++ sys/arch/amd64/stand/efiboot/conf.c 20 Feb 2020 12:36:32 -0000
@@ -30,6 +30,7 @@
 #include <sys/disklabel.h>
 #include <libsa.h>
 #include <lib/libsa/ufs.h>
+#include <lib/libsa/ufs2.h>
 #include <lib/libsa/tftp.h>
 #include <lib/libsa/cd9660.h>
 #include <dev/cons.h>
@@ -39,7 +40,7 @@
 #include "efidev.h"
 #include "efipxe.h"
 
-const char version[] = "3.48";
+const char version[] = "3.49";
 
 #ifdef EFI_DEBUG
 int    debug = 0;
@@ -67,6 +68,8 @@ struct fs_ops file_system[] = {
          tftp_stat,   tftp_readdir   },
        { ufs_open,    ufs_close,    ufs_read,    ufs_write,    ufs_seek,
          ufs_stat,    ufs_readdir,  ufs_fchmod },
+       { ufs2_open,   ufs2_close,   ufs2_read,   ufs2_write,   ufs2_seek,
+         ufs2_stat,   ufs2_readdir, ufs2_fchmod },
        { cd9660_open, cd9660_close, cd9660_read, cd9660_write, cd9660_seek,
          cd9660_stat, cd9660_readdir },
 #ifdef notdef
Index: sys/arch/amd64/stand/pxeboot/Makefile
===================================================================
RCS file: /cvs/src/sys/arch/amd64/stand/pxeboot/Makefile,v
retrieving revision 1.37
diff -u -p -r1.37 Makefile
--- sys/arch/amd64/stand/pxeboot/Makefile       28 Nov 2019 00:17:11 -0000      
1.37
+++ sys/arch/amd64/stand/pxeboot/Makefile       20 Feb 2020 12:36:32 -0000
@@ -40,7 +40,7 @@ SRCS+=        close.c closeall.c dev.c disklabe
        loadfile.c arc4.c elf32.c elf64.c
 SRCS+= ether.c net.c netif.c rpc.c
 SRCS+= bootp.c bootparam.c
-SRCS+= ufs.c nfs.c tftp.c
+SRCS+= ufs.c ufs2.c nfs.c tftp.c
 
 .PATH: ${S}/lib/libkern/arch/amd64 ${S}/lib/libkern
 SRCS+= divdi3.c moddi3.c qdivrem.c udivdi3.c umoddi3.c
Index: sys/arch/amd64/stand/pxeboot/conf.c
===================================================================
RCS file: /cvs/src/sys/arch/amd64/stand/pxeboot/conf.c,v
retrieving revision 1.47
diff -u -p -r1.47 conf.c
--- sys/arch/amd64/stand/pxeboot/conf.c 29 Oct 2019 02:55:51 -0000      1.47
+++ sys/arch/amd64/stand/pxeboot/conf.c 20 Feb 2020 12:36:32 -0000
@@ -31,6 +31,7 @@
 #include <netinet/in.h>
 #include <libsa.h>
 #include <lib/libsa/ufs.h>
+#include <lib/libsa/ufs2.h>
 #ifdef notdef
 #include <lib/libsa/cd9660.h>
 #include <lib/libsa/fat.h>
@@ -43,7 +44,7 @@
 #include "pxeboot.h"
 #include "pxe_net.h"
 
-const char version[] = "3.45";
+const char version[] = "3.46";
 int    debug = 0;
 
 void (*sa_cleanup)(void) = pxe_shutdown;
@@ -76,6 +77,8 @@ int nfsname = nitems(fs_name);
 struct fs_ops file_system[] = {
        { ufs_open,    ufs_close,    ufs_read,    ufs_write,    ufs_seek,
          ufs_stat,    ufs_readdir,  ufs_fchmod },
+       { ufs2_open,   ufs2_close,   ufs2_read,   ufs2_write,   ufs2_seek,
+         ufs2_stat,   ufs2_readdir, ufs2_fchmod },
        { tftp_open,   tftp_close,   tftp_read,   tftp_write,   tftp_seek,
          tftp_stat,   tftp_readdir   },
        { nfs_open,    nfs_close,    nfs_read,    nfs_write,    nfs_seek,
Index: sys/arch/i386/stand/biosboot/biosboot.S
===================================================================
RCS file: /cvs/src/sys/arch/i386/stand/biosboot/biosboot.S,v
retrieving revision 1.41
diff -u -p -r1.41 biosboot.S
--- sys/arch/i386/stand/biosboot/biosboot.S     5 Jul 2011 17:38:54 -0000       
1.41
+++ sys/arch/i386/stand/biosboot/biosboot.S     20 Feb 2020 12:36:32 -0000
@@ -108,6 +108,9 @@
  *                     While this can be calculated as
  *                     howmany(di_size, fs_bsize) it takes us too
  *                     many code bytes to do it.
+ * blkskew     uint8t  the skew used to parse di_db[]. this is set to four by
+ *                     installboot for ffs2 (due to 64-bit blocks) and should
+ *                     be zero for ffs1.
  *
  * All of these are patched directly into the code where they are used
  * (once only, each), to save space.
@@ -121,7 +124,7 @@
  */
 
        .globl  inodeblk, inodedbl, fs_bsize_p, fsbtodb, p_offset, nblocks
-       .globl  fs_bsize_s, force_chs
+       .globl  fs_bsize_s, force_chs, blkskew
        .type   inodeblk, @function
        .type   inodedbl, @function
        .type   fs_bsize_p, @function
@@ -130,6 +133,7 @@
        .type   p_offset, @function
        .type   nblocks, @function
        .type   force_chs, @function
+       .type   blkskew, @function
 
 
 /* Clobbers %ax, maybe more */
@@ -460,6 +464,8 @@ load_blocks:
 
        /* Get the next filesystem block number into %eax */
        lodsl                   /* %eax = *(%si++), make sure 0x66 0xad */
+blkskew = .+2
+       addw    $0x90, %si      /* adjust %si if needed (for ffs2) */
 
        pushal                          /* Save all 32-bit registers */
 
Index: sys/lib/libsa/ufs2.h
===================================================================
RCS file: /cvs/src/sys/lib/libsa/ufs2.h,v
retrieving revision 1.1
diff -u -p -r1.1 ufs2.h
--- sys/lib/libsa/ufs2.h        16 Apr 2014 22:33:03 -0000      1.1
+++ sys/lib/libsa/ufs2.h        20 Feb 2020 12:36:33 -0000
@@ -36,3 +36,4 @@ int   ufs2_write(struct open_file *, void 
 int    ufs2_stat(struct open_file *, struct stat *);
 int    ufs2_readdir(struct open_file *, char *);
 off_t  ufs2_seek(struct open_file *, off_t, int);
+int    ufs2_fchmod(struct open_file *, mode_t);
Index: usr.sbin/installboot/i386_installboot.c
===================================================================
RCS file: /cvs/src/usr.sbin/installboot/i386_installboot.c,v
retrieving revision 1.33
diff -u -p -r1.33 i386_installboot.c
--- usr.sbin/installboot/i386_installboot.c     2 Sep 2019 16:36:12 -0000       
1.33
+++ usr.sbin/installboot/i386_installboot.c     20 Feb 2020 12:36:34 -0000
@@ -2,6 +2,7 @@
 /*     $NetBSD: installboot.c,v 1.5 1995/11/17 23:23:50 gwr Exp $ */
 
 /*
+ * Copyright (c) 2013 Pedro Martelletto
  * Copyright (c) 2011 Joel Sing <js...@openbsd.org>
  * Copyright (c) 2003 Tom Cosgrove <tom.cosgr...@arches-consulting.com>
  * Copyright (c) 1997 Michael Shalayeff
@@ -82,6 +83,7 @@ struct sym_data pbr_symbols[] = {
        {"_inodeblk",   4},
        {"_inodedbl",   4},
        {"_nblocks",    2},
+       {"_blkskew",    1},
        {NULL}
 };
 
@@ -90,6 +92,10 @@ static u_int findopenbsd(int, struct dis
 static int     getbootparams(char *, int, struct disklabel *);
 static char    *loadproto(char *, long *);
 static int     gpt_chk_mbr(struct dos_partition *, u_int64_t);
+static int     sbchk(struct fs *, daddr_t);
+static void    sbread(int, daddr_t, struct fs **, char *);
+
+static const daddr_t sbtry[] = SBLOCKSEARCH;
 
 /*
  * Read information about /boot's inode and filesystem parameters, then
@@ -662,11 +668,13 @@ getbootparams(char *boot, int devfd, str
        struct fs       *fs;
        char            *sblock, *buf;
        u_int           blk, *ap;
-       struct ufs1_dinode *ip;
+       struct ufs1_dinode      *ip1;
+       struct ufs2_dinode      *ip2;
        int             ndb;
        int             mib[3];
        size_t          size;
        dev_t           dev;
+       int             skew;
 
        /*
         * Open 2nd-level boot program and record enough details about
@@ -723,19 +731,10 @@ getbootparams(char *boot, int devfd, str
        pp = &dl->d_partitions[DISKPART(fsb.st_dev)];
        close(fd);
 
-       /* Read superblock. */
        if ((sblock = malloc(SBSIZE)) == NULL)
                err(1, NULL);
 
-       devread(devfd, sblock, DL_SECTOBLK(dl, pp->p_offset) + SBLOCK,
-           SBSIZE, "superblock");
-       fs = (struct fs *)sblock;
-
-       /* Sanity-check super-block. */
-       if (fs->fs_magic != FS_MAGIC)
-               errx(1, "Bad magic number in superblock");
-       if (fs->fs_inopb <= 0)
-               err(1, "Bad inopb=%d in superblock", fs->fs_inopb);
+       sbread(devfd, DL_SECTOBLK(dl, pp->p_offset), &fs, sblock);
 
        /* Read inode. */
        if ((buf = malloc(fs->fs_bsize)) == NULL)
@@ -743,15 +742,26 @@ getbootparams(char *boot, int devfd, str
 
        blk = fsbtodb(fs, ino_to_fsba(fs, fsb.st_ino));
 
-       devread(devfd, buf, DL_SECTOBLK(dl, pp->p_offset) + blk,
-           fs->fs_bsize, "inode");
-       ip = (struct ufs1_dinode *)(buf) + ino_to_fsbo(fs, fsb.st_ino);
-
        /*
         * Have the inode.  Figure out how many filesystem blocks (not disk
         * sectors) there are for biosboot to load.
         */
-       ndb = howmany(ip->di_size, fs->fs_bsize);
+       devread(devfd, buf, DL_SECTOBLK(dl, pp->p_offset) + blk,
+           fs->fs_bsize, "inode");
+       if (fs->fs_magic == FS_UFS2_MAGIC) {
+               ip2 = (struct ufs2_dinode *)(buf) +
+                   ino_to_fsbo(fs, fsb.st_ino);
+               ndb = howmany(ip2->di_size, fs->fs_bsize);
+               ap = (u_int *)ip2->di_db;
+               skew = sizeof(u_int32_t);
+       } else {
+               ip1 = (struct ufs1_dinode *)(buf) +
+                   ino_to_fsbo(fs, fsb.st_ino);
+               ndb = howmany(ip1->di_size, fs->fs_bsize);
+               ap = (u_int *)ip1->di_db;
+               skew = 0;
+       }
+
        if (ndb <= 0)
                errx(1, "No blocks to load");
 
@@ -778,10 +788,10 @@ getbootparams(char *boot, int devfd, str
        sym_set_value(pbr_symbols, "_p_offset", pp->p_offset);
        sym_set_value(pbr_symbols, "_inodeblk",
            ino_to_fsba(fs, fsb.st_ino));
-       ap = ip->di_db;
        sym_set_value(pbr_symbols, "_inodedbl",
            ((((char *)ap) - buf) + INODEOFF));
        sym_set_value(pbr_symbols, "_nblocks", ndb);
+       sym_set_value(pbr_symbols, "_blkskew", skew);
 
        if (verbose) {
                fprintf(stderr, "%s is %d blocks x %d bytes\n",
@@ -792,6 +802,8 @@ getbootparams(char *boot, int devfd, str
                    pp->p_offset,
                    ino_to_fsba(fs, fsb.st_ino),
                    (unsigned int)((((char *)ap) - buf) + INODEOFF));
+               fprintf(stderr, "expecting %d-bit fs blocks (skew %d)\n",
+                   skew ? 64 : 32, skew);
        }
 
        free (sblock);
@@ -880,4 +892,73 @@ pbr_set_symbols(char *fname, char *proto
 
                free(nl);
        }
+}
+
+static int
+sbchk(struct fs *fs, daddr_t sbloc)
+{
+       if (verbose)
+               warnx("looking for superblock at %lld", sbloc);
+
+       if (fs->fs_magic != FS_UFS2_MAGIC && fs->fs_magic != FS_UFS1_MAGIC) {
+               if (verbose)
+                       warnx("bad superblock magic 0x%x", fs->fs_magic);
+               return (0);
+       }
+
+       /*
+        * Looking for an FFS1 file system at SBLOCK_UFS2 will find the
+        * wrong superblock for file systems with 64k block size.
+        */
+       if (fs->fs_magic == FS_UFS1_MAGIC && sbloc == SBLOCK_UFS2) {
+               if (verbose)
+                       warnx("skipping ffs1 superblock at %lld", sbloc);
+               return (0);
+       }
+
+       if (fs->fs_bsize <= 0 ||
+           fs->fs_bsize < sizeof(struct fs) ||
+           fs->fs_bsize > MAXBSIZE) {
+               if (verbose)
+                       warnx("invalid superblock block size %d",
+                           fs->fs_bsize);
+               return (0);
+       }
+
+       if (fs->fs_sbsize <= 0 || fs->fs_sbsize > SBSIZE) {
+               if (verbose)
+                       warnx("invalid superblock size %d", fs->fs_sbsize);
+               return (0);
+       }
+
+       if (fs->fs_inopb <= 0) {
+               if (verbose)
+                       warnx("invalid superblock inodes/block %d",
+                           fs->fs_inopb);
+               return (0);
+       }
+
+       if (verbose)
+               warnx("found valid %s superblock",
+                   fs->fs_magic == FS_UFS2_MAGIC ? "ffs2" : "ffs1");
+
+       return (1);
+}
+
+static void
+sbread(int fd, daddr_t poffset, struct fs **fs, char *sblock)
+{
+       int i;
+       daddr_t sboff;
+
+       for (i = 0; sbtry[i] != -1; i++) {
+               sboff = sbtry[i] / DEV_BSIZE;
+               devread(fd, sblock, poffset + sboff, SBSIZE, "superblock");
+               *fs = (struct fs *)sblock;
+               if (sbchk(*fs, sbtry[i]))
+                       break;
+       }
+
+       if (sbtry[i] == -1)
+               errx(1, "couldn't find ffs superblock");
 }
Index: usr.sbin/installboot/i386_softraid.c
===================================================================
RCS file: /cvs/src/usr.sbin/installboot/i386_softraid.c,v
retrieving revision 1.12
diff -u -p -r1.12 i386_softraid.c
--- usr.sbin/installboot/i386_softraid.c        2 Sep 2019 16:36:12 -0000       
1.12
+++ usr.sbin/installboot/i386_softraid.c        20 Feb 2020 12:36:34 -0000
@@ -190,6 +190,7 @@ sr_install_bootldr(int devfd, char *dev)
        sym_set_value(pbr_symbols, "_inodeblk", inodeblk);
        sym_set_value(pbr_symbols, "_inodedbl", inodedbl);
        sym_set_value(pbr_symbols, "_nblocks", nblocks);
+       sym_set_value(pbr_symbols, "_blkskew", 0);
 
        if (verbose)
                fprintf(stderr, "%s is %d blocks x %d bytes\n",

Reply via email to