From: Francois Dupoux <2386566-fdupoux@users.noreply.gitlab.com>
Date: Sun, 1 Feb 2026 11:29:45 +0000
Subject: Support for xfs features up to linux 6.18

(cherry picked from commit fa3b8cd479a215f42f1543103054dfebb973e83a)
---
 src/fs_xfs.c | 28 ++++++++++++++++++++++++++++
 src/fs_xfs.h | 14 ++++++++++++--
 2 files changed, 40 insertions(+), 2 deletions(-)

diff --git a/src/fs_xfs.c b/src/fs_xfs.c
index e8c34d5..0983b6c 100644
--- a/src/fs_xfs.c
+++ b/src/fs_xfs.c
@@ -273,6 +273,34 @@ int xfs_mkfs(cdico *d, char *partition, char *fsoptions, char *mkfslabel, char *
         strlcatf(mkfsopts, sizeof(mkfsopts), " -i nrext64=%d ", (int)optval);
     }
 
+    // Determine if the "exchange range" option should be enabled
+    if (xfstoolsver >= PROGVER(6,10,0))
+    {
+        optval = !!(sb_features_incompat & XFS_SB_FEAT_INCOMPAT_EXCHRANGE);
+        strlcatf(mkfsopts, sizeof(mkfsopts), " -i exchange=%d ", (int)optval);
+    }
+
+    // Determine if the "directory parent pointers" option should be enabled
+    if (xfstoolsver >= PROGVER(6,10,0))
+    {
+        optval = !!(sb_features_incompat & XFS_SB_FEAT_INCOMPAT_PARENT);
+        strlcatf(mkfsopts, sizeof(mkfsopts), " -n parent=%d ", (int)optval);
+    }
+
+    // Determine if the "metadata directory" option should be enabled
+    if (xfstoolsver >= PROGVER(6,13,0))
+    {
+        optval = !!(sb_features_incompat & XFS_SB_FEAT_INCOMPAT_METADIR);
+        strlcatf(mkfsopts, sizeof(mkfsopts), " -m metadir=%d ", (int)optval);
+    }
+
+    // Determine if the "zoned" option should be enabled
+    if (xfstoolsver >= PROGVER(6,15,0))
+    {
+        optval = !!(sb_features_incompat & XFS_SB_FEAT_INCOMPAT_ZONED);
+        strlcatf(mkfsopts, sizeof(mkfsopts), " -r zoned=%d ", (int)optval);
+    }
+
     // ---- mkfsopt from command line
     strlcatf(mkfsopts, sizeof(mkfsopts), " %s ", fsoptions);
 
diff --git a/src/fs_xfs.h b/src/fs_xfs.h
index 99461ce..279e645 100644
--- a/src/fs_xfs.h
+++ b/src/fs_xfs.h
@@ -65,7 +65,7 @@ typedef uint64_t      xfs_ufsize_t;   /* unsigned bytes in a file */
 
 typedef int32_t       xfs_suminfo_t;  /* type of bitmap summary info */
 typedef int32_t       xfs_rtword_t;   /* word type for bitmap manipulations */
- 
+
 typedef int64_t       xfs_lsn_t;      /* log sequence number */
 typedef int32_t       xfs_tid_t;      /* transaction identifier */
 
@@ -192,6 +192,11 @@ struct xfs_sb
 #define XFS_SB_FEAT_INCOMPAT_BIGTIME      (1 << 3)  /* large timestamps */
 #define XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR  (1 << 4)  /* needs xfs_repair */
 #define XFS_SB_FEAT_INCOMPAT_NREXT64      (1 << 5)  /* large extent counters */
+#define XFS_SB_FEAT_INCOMPAT_EXCHRANGE    (1 << 6)  /* exchangerange supported */
+#define XFS_SB_FEAT_INCOMPAT_PARENT       (1 << 7)  /* parent pointers */
+#define XFS_SB_FEAT_INCOMPAT_METADIR      (1 << 8)  /* metadata dir tree */
+#define XFS_SB_FEAT_INCOMPAT_ZONED        (1 << 9)  /* zoned RT allocator */
+#define XFS_SB_FEAT_INCOMPAT_ZONE_GAPS    (1 << 10) /* RTGs have LBA gaps */
 
 // features supported by the current fsarchiver version
 #define FSA_XFS_FEATURE_COMPAT_SUPP       (u64)(0)
@@ -204,7 +209,12 @@ struct xfs_sb
                                                 XFS_SB_FEAT_INCOMPAT_META_UUID|\
                                                 XFS_SB_FEAT_INCOMPAT_BIGTIME|\
                                                 XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR|\
-                                                XFS_SB_FEAT_INCOMPAT_NREXT64)
+                                                XFS_SB_FEAT_INCOMPAT_NREXT64|\
+                                                XFS_SB_FEAT_INCOMPAT_EXCHRANGE|\
+                                                XFS_SB_FEAT_INCOMPAT_PARENT|\
+                                                XFS_SB_FEAT_INCOMPAT_METADIR|\
+                                                XFS_SB_FEAT_INCOMPAT_ZONED|\
+                                                XFS_SB_FEAT_INCOMPAT_ZONE_GAPS)
 #define FSA_XFS_FEATURE_LOG_INCOMPAT_SUPP (u64)(0)
 
 #endif // __FS_XFS_H__
