git: c49043eacb14 - main - makefs: Support st_flags even on Linux

From: Jessica Clarke <jrtc27_at_FreeBSD.org>
Date: Tue, 06 May 2025 16:58:34 UTC
The branch main has been updated by jrtc27:

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

commit c49043eacb14c951b0675eb4d37b81d4b02b949f
Author:     Jessica Clarke <jrtc27@FreeBSD.org>
AuthorDate: 2025-05-06 16:58:09 +0000
Commit:     Jessica Clarke <jrtc27@FreeBSD.org>
CommitDate: 2025-05-06 16:58:09 +0000

    makefs: Support st_flags even on Linux
    
    Linux's struct stat does not have an st_flags member, but we still want
    to be able to create FreeBSD disk images with non-zero st_flags. Add a
    replacement member to struct fsinode to store it on Linux.
    
    Note that we add a fallback definition of HAVE_STRUCT_STAT_ST_FLAGS for
    makefs.h since etdump reaches into makefs and won't have it defined in
    its CFLAGS like makefs itself does, and on FreeBSD we don't provide an
    nbtool_config.h.
    
    Note also that strtofflags is currently a stub on Linux so this doesn't
    yet properly mirror the mtree, but that will change in a future commit.
    
    Reviewed by:    emaste, markj
    Differential Revision:  https://reviews.freebsd.org/D50078
---
 usr.sbin/makefs/ffs.c    |  8 ++------
 usr.sbin/makefs/makefs.h | 15 +++++++++++++++
 usr.sbin/makefs/mtree.c  |  6 ++----
 usr.sbin/makefs/walk.c   |  6 ++----
 4 files changed, 21 insertions(+), 14 deletions(-)

diff --git a/usr.sbin/makefs/ffs.c b/usr.sbin/makefs/ffs.c
index aa5574c5201f..34a0f8a67497 100644
--- a/usr.sbin/makefs/ffs.c
+++ b/usr.sbin/makefs/ffs.c
@@ -685,9 +685,7 @@ ffs_build_dinode1(struct ufs1_dinode *dinp, dirbuf_t *dbufp, fsnode *cur,
 	dinp->di_mode = cur->inode->st.st_mode;
 	dinp->di_nlink = cur->inode->nlink;
 	dinp->di_size = cur->inode->st.st_size;
-#if HAVE_STRUCT_STAT_ST_FLAGS
-	dinp->di_flags = cur->inode->st.st_flags;
-#endif
+	dinp->di_flags = FSINODE_ST_FLAGS(*cur->inode);
 	dinp->di_gen = random();
 	dinp->di_uid = cur->inode->st.st_uid;
 	dinp->di_gid = cur->inode->st.st_gid;
@@ -733,9 +731,7 @@ ffs_build_dinode2(struct ufs2_dinode *dinp, dirbuf_t *dbufp, fsnode *cur,
 	dinp->di_mode = cur->inode->st.st_mode;
 	dinp->di_nlink = cur->inode->nlink;
 	dinp->di_size = cur->inode->st.st_size;
-#if HAVE_STRUCT_STAT_ST_FLAGS
-	dinp->di_flags = cur->inode->st.st_flags;
-#endif
+	dinp->di_flags = FSINODE_ST_FLAGS(*cur->inode);
 	dinp->di_gen = random();
 	dinp->di_uid = cur->inode->st.st_uid;
 	dinp->di_gid = cur->inode->st.st_gid;
diff --git a/usr.sbin/makefs/makefs.h b/usr.sbin/makefs/makefs.h
index db0addc4bc94..62c7e430a00c 100644
--- a/usr.sbin/makefs/makefs.h
+++ b/usr.sbin/makefs/makefs.h
@@ -40,6 +40,12 @@
 #ifndef	_MAKEFS_H
 #define	_MAKEFS_H
 
+#if HAVE_NBTOOL_CONFIG_H
+#include "nbtool_config.h"
+#else
+#define	HAVE_STRUCT_STAT_ST_FLAGS	1
+#endif
+
 #include <sys/stat.h>
 #include <err.h>
 
@@ -85,8 +91,17 @@ typedef struct {
 	enum fi_flags	 flags;		/* flags used by fs specific code */
 	void		*param;		/* for use by individual fs impls */
 	struct stat	 st;		/* stat entry */
+#if !HAVE_STRUCT_STAT_ST_FLAGS
+	uint32_t	 st_flags;	/* stand-in for st.st_flags */
+#endif
 } fsinode;
 
+#if HAVE_STRUCT_STAT_ST_FLAGS
+#define	FSINODE_ST_FLAGS(inode)	(inode).st.st_flags
+#else
+#define	FSINODE_ST_FLAGS(inode)	(inode).st_flags
+#endif
+
 typedef struct _fsnode {
 	struct _fsnode	*parent;	/* parent (NULL if root) */
 	struct _fsnode	*child;		/* child (if type == S_IFDIR) */
diff --git a/usr.sbin/makefs/mtree.c b/usr.sbin/makefs/mtree.c
index fddc32b85322..83e207b07402 100644
--- a/usr.sbin/makefs/mtree.c
+++ b/usr.sbin/makefs/mtree.c
@@ -533,13 +533,11 @@ read_mtree_keywords(FILE *fp, fsnode *node)
 					break;
 				}
 				flset = flclr = 0;
-#if HAVE_STRUCT_STAT_ST_FLAGS
 				if (!strtofflags(&value, &flset, &flclr)) {
-					st->st_flags &= ~flclr;
-					st->st_flags |= flset;
+					FSINODE_ST_FLAGS(*node->inode) &= ~flclr;
+					FSINODE_ST_FLAGS(*node->inode) |= flset;
 				} else
 					error = errno;
-#endif
 			} else
 				error = ENOSYS;
 			break;
diff --git a/usr.sbin/makefs/walk.c b/usr.sbin/makefs/walk.c
index fe1fe8df80db..b2afa9e78094 100644
--- a/usr.sbin/makefs/walk.c
+++ b/usr.sbin/makefs/walk.c
@@ -530,14 +530,12 @@ apply_specentry(const char *dir, NODE *specnode, fsnode *dirnode)
 		    dirnode->inode->st.st_uid, specnode->st_uid);
 		dirnode->inode->st.st_uid = specnode->st_uid;
 	}
-#if HAVE_STRUCT_STAT_ST_FLAGS
 	if (specnode->flags & F_FLAGS) {
 		ASEPRINT("flags", "%#lX",
-		    (unsigned long)dirnode->inode->st.st_flags,
+		    (unsigned long)FSINODE_ST_FLAGS(*dirnode->inode),
 		    (unsigned long)specnode->st_flags);
-		dirnode->inode->st.st_flags = specnode->st_flags;
+		FSINODE_ST_FLAGS(*dirnode->inode) = specnode->st_flags;
 	}
-#endif
 /*	if (specnode->flags & F_DEV) {
 		ASEPRINT("rdev", "%#llx",
 		    (unsigned long long)dirnode->inode->st.st_rdev,