Date: Tue, 07 Apr 2026 13:54:44 +0000 From: Dag-Erling=?utf-8?Q? Sm=C3=B8rg?=rav <des@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Subject: git: 8244dd326265 - main - tunefs: Better fix for arm64 alignment issues Message-ID: <69d50ca4.3aa01.23788f2e@gitrepo.freebsd.org>
index | next in thread | raw e-mail
The branch main has been updated by des: URL: https://cgit.FreeBSD.org/src/commit/?id=8244dd326265867293b2286efc3d571f06ef0dab commit 8244dd326265867293b2286efc3d571f06ef0dab Author: Dag-Erling Smørgrav <des@FreeBSD.org> AuthorDate: 2026-04-07 13:54:28 +0000 Commit: Dag-Erling Smørgrav <des@FreeBSD.org> 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);home | help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?69d50ca4.3aa01.23788f2e>
