[PATCH 25/29] xfs: report verity failures through the health system

Darrick J. Wong
2024-03-30T00:42:35Z

From: Darrick J. Wong <djwong@kernel.org>

Record verity failures and report them through the health system.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
fs/xfs/libxfs/xfs_fs.h | 1 +
fs/xfs/libxfs/xfs_health.h | 4 +++-
fs/xfs/xfs_fsverity.c | 11 +++++++++++
fs/xfs/xfs_health.c | 1 +
4 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/fs/xfs/libxfs/xfs_fs.h b/fs/xfs/libxfs/xfs_fs.h
index af45a246eb1c1..d22f3423ddc76 100644
--- a/fs/xfs/libxfs/xfs_fs.h
+++ b/fs/xfs/libxfs/xfs_fs.h
@@ -426,6 +426,7 @@ struct xfs_bulkstat {
#define XFS_BS_SICK_SYMLINK (1 << 6) /* symbolic link remote target */
#define XFS_BS_SICK_PARENT (1 << 7) /* parent pointers */
#define XFS_BS_SICK_DIRTREE (1 << 8) /* directory tree structure */
+#define XFS_BS_SICK_DATA (1 << 9) /* file data */

/*
* Project quota id helpers (previously projid was 16bit only
diff --git a/fs/xfs/libxfs/xfs_health.h b/fs/xfs/libxfs/xfs_health.h
index 89b80e957917e..0f8533335e25f 100644
--- a/fs/xfs/libxfs/xfs_health.h
+++ b/fs/xfs/libxfs/xfs_health.h
@@ -105,6 +105,7 @@ struct xfs_rtgroup;
/* Don't propagate sick status to ag health summary during inactivation */
#define XFS_SICK_INO_FORGET (1 << 12)
#define XFS_SICK_INO_DIRTREE (1 << 13) /* directory tree structure */
+#define XFS_SICK_INO_DATA (1 << 14) /* file data */

/* Primary evidence of health problems in a given group. */
#define XFS_SICK_FS_PRIMARY (XFS_SICK_FS_COUNTERS | \
@@ -143,7 +144,8 @@ struct xfs_rtgroup;
XFS_SICK_INO_XATTR | \
XFS_SICK_INO_SYMLINK | \
XFS_SICK_INO_PARENT | \
- XFS_SICK_INO_DIRTREE)
+ XFS_SICK_INO_DIRTREE | \
+ XFS_SICK_INO_DATA)

#define XFS_SICK_INO_ZAPPED (XFS_SICK_INO_BMBTD_ZAPPED | \
XFS_SICK_INO_BMBTA_ZAPPED | \
diff --git a/fs/xfs/xfs_fsverity.c b/fs/xfs/xfs_fsverity.c
index 2806466ceaeab..bfa5c70beec24 100644
--- a/fs/xfs/xfs_fsverity.c
+++ b/fs/xfs/xfs_fsverity.c
@@ -21,6 +21,7 @@
#include "xfs_quota.h"
#include "xfs_fsverity.h"
#include "xfs_icache.h"
+#include "xfs_health.h"
#include <linux/fsverity.h>

/*
@@ -773,6 +774,15 @@ xfs_fsverity_drop_merkle(
block->context = NULL;
}

+static void
+xfs_fsverity_fail_validation(
+ struct inode *inode,
+ loff_t pos,
+ size_t len)
+{
+ xfs_inode_mark_sick(XFS_I(inode), XFS_SICK_INO_DATA);
+}
+
const struct fsverity_operations xfs_fsverity_ops = {
.begin_enable_verity = xfs_fsverity_begin_enable,
.end_enable_verity = xfs_fsverity_end_enable,
@@ -780,4 +790,5 @@ const struct fsverity_operations xfs_fsverity_ops = {
.read_merkle_tree_block = xfs_fsverity_read_merkle,
.write_merkle_tree_block = xfs_fsverity_write_merkle,
.drop_merkle_tree_block = xfs_fsverity_drop_merkle,
+ .fail_validation = xfs_fsverity_fail_validation,
};
diff --git a/fs/xfs/xfs_health.c b/fs/xfs/xfs_health.c
index 33059d979857a..ce7385c207d37 100644
--- a/fs/xfs/xfs_health.c
+++ b/fs/xfs/xfs_health.c
@@ -591,6 +591,7 @@ static const struct ioctl_sick_map ino_map[] = {
{ XFS_SICK_INO_DIR_ZAPPED, XFS_BS_SICK_DIR },
{ XFS_SICK_INO_SYMLINK_ZAPPED, XFS_BS_SICK_SYMLINK },
{ XFS_SICK_INO_DIRTREE, XFS_BS_SICK_DIRTREE },
+ { XFS_SICK_INO_DATA, XFS_BS_SICK_DATA },
{ 0, 0 },
};