From 4aba12dc19a95626eb7fa1df2d19c5235c2bc848 Mon Sep 17 00:00:00 2001
From: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
Date: Sat, 22 Nov 2025 21:12:23 +0100
Subject: [PATCH] configure: check for FS_IOC_READ_VERITY_METADATA availability
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Commit 6bfa843b4435334ac073e42950b48d8bacb54977 ("mke2fs: enable
copying of fs-verity metadata") introduced support for reading
fs-verity metadata, which requires using the
FS_IOC_READ_VERITY_METADATA.

The code is conditionally compiled when the kernel headers have
<linux/fsverity.h> available. Unfortunately, this check is not
sufficient: <linux/fsverity.h> was introduced in Linux 5.10, but the
FS_IOC_READ_VERITY_METADATA was not introduced before 5.12, so if one
is using 5.10 or 5.11 kernel headers, the build fails with:

./../misc/create_inode.c: In function ‘copy_fs_verity_data’:
./../misc/create_inode.c:589:10: error: variable ‘arg’ has initializer but incomplete type
  589 |   struct fsverity_read_metadata_arg arg = {
      |          ^~~~~~~~~~~~~~~~~~~~~~~~~~
[...]
./../misc/create_inode.c:600:20: error: ‘FS_IOC_READ_VERITY_METADATA’ undeclared (first use in this function)
  600 |   size = ioctl(fd, FS_IOC_READ_VERITY_METADATA, &arg);
      |                    ^~~~~~~~~~~~~~~~~~~~~~~~~~~

This commit therefore extends the configure.ac check to ensure that
not only <linux/fsverity.h> exists but also that it defines the
FS_IOC_READ_VERITY_METADATA ioctl.

Closes: https://github.com/tytso/e2fsprogs/pull/256
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
---
 configure           | 38 ++++++++++++++++++++++++++++++++++++++
 configure.ac        | 18 ++++++++++++++++++
 misc/create_inode.c |  6 +++---
 3 files changed, 59 insertions(+), 3 deletions(-)

diff --git a/configure b/configure
index e7f59bee..ddfc752a 100755
--- a/configure
+++ b/configure
@@ -16823,6 +16823,44 @@ case "$host_os" in
 esac
 
 
+if test "${ac_cv_header_linux_fsverity_h}" = "yes"; then
+   { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for FS_IOC_READ_VERITY_METADATA ioctl" >&5
+printf %s "checking for FS_IOC_READ_VERITY_METADATA ioctl... " >&6; }
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <linux/fsverity.h>
+#ifndef FS_IOC_READ_VERITY_METADATA
+# error "FS_IOC_READ_VERITY_METADATA not available"
+#endif
+
+int
+main (void)
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"
+then :
+
+
+printf "%s\n" "#define HAVE_FS_IOC_READ_VERITY_METADATA 1" >>confdefs.h
+
+   { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
+
+else case e in #(
+  e)
+   { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+    ;;
+esac
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+fi
+
 test -d lib || mkdir lib
 test -d include || mkdir include
 test -d include/linux || mkdir include/linux
diff --git a/configure.ac b/configure.ac
index a0171163..3e5586a3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1997,6 +1997,24 @@ OS_IO_FILE=""
 esac]
 AC_SUBST(OS_IO_FILE)
 
+dnl Check for fsverity ioctl
+if test "${ac_cv_header_linux_fsverity_h}" = "yes"; then
+   AC_MSG_CHECKING([for FS_IOC_READ_VERITY_METADATA ioctl])
+   AC_PREPROC_IFELSE(
+   [AC_LANG_PROGRAM([[
+#include <linux/fsverity.h>
+#ifndef FS_IOC_READ_VERITY_METADATA
+# error "FS_IOC_READ_VERITY_METADATA not available"
+#endif
+]], [])], [
+   AC_DEFINE([HAVE_FS_IOC_READ_VERITY_METADATA], [1], [Define to 1 if FS_IOC_READ_VERITY_METADATA ioctl is available])
+   AC_MSG_RESULT([yes])
+   ],
+   [
+   AC_MSG_RESULT([no])
+   ])
+fi
+
 dnl
 dnl Make our output files, being sure that we create the some miscellaneous 
 dnl directories
diff --git a/misc/create_inode.c b/misc/create_inode.c
index 624efc03..a7918873 100644
--- a/misc/create_inode.c
+++ b/misc/create_inode.c
@@ -30,7 +30,7 @@
 #ifdef HAVE_SYS_SYSMACROS_H
 #include <sys/sysmacros.h>
 #endif
-#ifdef HAVE_LINUX_FSVERITY_H
+#if defined(HAVE_LINUX_FSVERITY_H) && defined(HAVE_FS_IOC_READ_VERITY_METADATA)
 #include <linux/fsverity.h>
 #include <linux/fs.h>
 #endif
@@ -569,7 +569,7 @@ out:
 }
 #endif /* FS_IOC_FIEMAP */
 
-#ifdef HAVE_LINUX_FSVERITY_H
+#if defined(HAVE_LINUX_FSVERITY_H) && defined(HAVE_FS_IOC_READ_VERITY_METADATA)
 static inline off_t round_up(off_t n, off_t blksz, off_t bias)
 {
   return ((n - bias + (blksz - 1)) & ~(blksz - 1)) + bias;
@@ -738,7 +738,7 @@ static errcode_t copy_file(ext2_filsys fs, int fd, struct stat *statbuf,
 		err = copy_file_chunk(fs, fd, e2_file, 0, statbuf->st_size, buf,
 				      zerobuf);
 
-#ifdef HAVE_LINUX_FSVERITY_H
+#if defined(HAVE_LINUX_FSVERITY_H) && defined(HAVE_FS_IOC_READ_VERITY_METADATA)
 	if (!err && (flags & EXT4_VERITY_FL))
 		err = copy_fs_verity(fs, fd, e2_file, statbuf->st_size);
 #endif
-- 
2.34.1

