The branch main has been updated by des:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=8244dd326265867293b2286efc3d571f06ef0dab

commit 8244dd326265867293b2286efc3d571f06ef0dab
Author:     Dag-Erling Smørgrav <[email protected]>
AuthorDate: 2026-04-07 13:54:28 +0000
Commit:     Dag-Erling Smørgrav <[email protected]>
CommitDate: 2026-04-07 13:54:28 +0000

    tunefs: Better fix for arm64 alignment issues
    
    Rather than trust that the compiler will lay out the stack frame the
    way we expect it to, use a union to force the correct alignment.
    
    MFC after:      1 week
    Fixes:          616f47f176c3 ("tunefs: Fix alignment warning on arm64")
    Reviewed by:    kevans, mckusick
    Differential Revision:  https://reviews.freebsd.org/D56245
---
 sbin/tunefs/tunefs.c | 64 ++++++++++++++++++++++++++++++----------------------
 1 file changed, 37 insertions(+), 27 deletions(-)

diff --git a/sbin/tunefs/tunefs.c b/sbin/tunefs/tunefs.c
index 56f343a5a4db..56160dafce28 100644
--- a/sbin/tunefs/tunefs.c
+++ b/sbin/tunefs/tunefs.c
@@ -44,6 +44,7 @@
 #include <ufs/ffs/fs.h>
 #include <ufs/ufs/dir.h>
 
+#include <assert.h>
 #include <ctype.h>
 #include <err.h>
 #include <fcntl.h>
@@ -51,6 +52,7 @@
 #include <libufs.h>
 #include <mntopts.h>
 #include <paths.h>
+#include <stdalign.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdint.h>
@@ -72,6 +74,11 @@ static int journal_alloc(int64_t size);
 static void journal_clear(void);
 static void sbdirty(void);
 
+typedef union {
+       char buf[MAXBSIZE];
+       struct direct dir;
+} dirblock;
+
 int
 main(int argc, char *argv[])
 {
@@ -631,16 +638,17 @@ journal_balloc(void)
 static ino_t
 dir_search(ufs2_daddr_t blk, int bytes)
 {
-       char block[MAXBSIZE];
+       dirblock block;
        struct direct *dp;
        int off;
 
-       if (bread(&disk, fsbtodb(&sblock, blk), block, bytes) <= 0) {
+       if (bread(&disk, fsbtodb(&sblock, blk), &block, bytes) <= 0) {
                warn("Failed to read dir block");
                return (-1);
        }
        for (off = 0; off < bytes; off += dp->d_reclen) {
-               dp = (struct direct *)(uintptr_t)&block[off];
+               assert(off % alignof(struct direct) == 0);
+               dp = (struct direct *)(uintptr_t)(block.buf + off);
                if (dp->d_reclen == 0)
                        break;
                if (dp->d_ino == 0)
@@ -700,12 +708,13 @@ journal_findfile(void)
 }
 
 static void
-dir_clear_block(const char *block, off_t off)
+dir_clear_block(const dirblock *block, off_t off)
 {
        struct direct *dp;
 
        for (; off < sblock.fs_bsize; off += DIRBLKSIZ) {
-               dp = (struct direct *)(uintptr_t)&block[off];
+               assert(off % alignof(struct direct) == 0);
+               dp = (struct direct *)(uintptr_t)(block + off);
                dp->d_ino = 0;
                dp->d_reclen = DIRBLKSIZ;
                dp->d_type = DT_UNKNOWN;
@@ -721,21 +730,23 @@ static int
 dir_insert(ufs2_daddr_t blk, off_t off, ino_t ino)
 {
        struct direct *dp;
-       char block[MAXBSIZE];
+       dirblock block;
 
-       if (bread(&disk, fsbtodb(&sblock, blk), block, sblock.fs_bsize) <= 0) {
+       assert((size_t)sblock.fs_bsize <= sizeof(block));
+       if (bread(&disk, fsbtodb(&sblock, blk), &block, sblock.fs_bsize) <= 0) {
                warn("Failed to read dir block");
                return (-1);
        }
-       bzero(&block[off], sblock.fs_bsize - off);
-       dp = (struct direct *)(uintptr_t)&block[off];
+       assert(off % alignof(struct direct) == 0);
+       bzero(block.buf + off, sblock.fs_bsize - off);
+       dp = (struct direct *)(uintptr_t)(block.buf + off);
        dp->d_ino = ino;
        dp->d_reclen = DIRBLKSIZ;
        dp->d_type = DT_REG;
        dp->d_namlen = strlen(SUJ_FILE);
        bcopy(SUJ_FILE, &dp->d_name, strlen(SUJ_FILE));
-       dir_clear_block(block, off + DIRBLKSIZ);
-       if (bwrite(&disk, fsbtodb(&sblock, blk), block, sblock.fs_bsize) <= 0) {
+       dir_clear_block(&block, off + DIRBLKSIZ);
+       if (bwrite(&disk, fsbtodb(&sblock, blk), &block, sblock.fs_bsize) <= 0) 
{
                warn("Failed to write dir block");
                return (-1);
        }
@@ -749,15 +760,16 @@ dir_insert(ufs2_daddr_t blk, off_t off, ino_t ino)
 static int
 dir_extend(ufs2_daddr_t blk, ufs2_daddr_t nblk, off_t size, ino_t ino)
 {
-       char block[MAXBSIZE];
+       dirblock block;
 
-       if (bread(&disk, fsbtodb(&sblock, blk), block,
+       assert((size_t)sblock.fs_bsize <= sizeof(block));
+       if (bread(&disk, fsbtodb(&sblock, blk), &block,
            roundup(size, sblock.fs_fsize)) <= 0) {
                warn("Failed to read dir block");
                return (-1);
        }
-       dir_clear_block(block, size);
-       if (bwrite(&disk, fsbtodb(&sblock, nblk), block, sblock.fs_bsize)
+       dir_clear_block(&block, size);
+       if (bwrite(&disk, fsbtodb(&sblock, nblk), &block, sblock.fs_bsize)
            <= 0) {
                warn("Failed to write dir block");
                return (-1);
@@ -846,19 +858,17 @@ journal_insertfile(ino_t ino)
 static int
 indir_fill(ufs2_daddr_t blk, int level, int *resid)
 {
-       char indirbuf[MAXBSIZE];
-       ufs1_daddr_t *bap1;
-       ufs2_daddr_t *bap2;
+       union {
+               char buf[MAXBSIZE];
+               ufs1_daddr_t ufs1;
+               ufs2_daddr_t ufs2;
+       } indir = { 0 };
+       ufs1_daddr_t *bap1 = &indir.ufs1;
+       ufs2_daddr_t *bap2 = &indir.ufs2;
        ufs2_daddr_t nblk;
-       int ncnt;
-       int cnt;
-       int i;
+       int cnt = 0, ncnt;
 
-       bzero(indirbuf, sizeof(indirbuf));
-       bap1 = (ufs1_daddr_t *)(uintptr_t)indirbuf;
-       bap2 = (void *)bap1;
-       cnt = 0;
-       for (i = 0; i < NINDIR(&sblock) && *resid != 0; i++) {
+       for (int i = 0; i < NINDIR(&sblock) && *resid != 0; i++) {
                nblk = journal_balloc();
                if (nblk <= 0)
                        return (-1);
@@ -875,7 +885,7 @@ indir_fill(ufs2_daddr_t blk, int level, int *resid)
                } else 
                        (*resid)--;
        }
-       if (bwrite(&disk, fsbtodb(&sblock, blk), indirbuf,
+       if (bwrite(&disk, fsbtodb(&sblock, blk), indir.buf,
            sblock.fs_bsize) <= 0) {
                warn("Failed to write indirect");
                return (-1);

Reply via email to