summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDarrick J. Wong <djwong@kernel.org>2026-01-20 18:06:51 -0800
committerDarrick J. Wong <djwong@kernel.org>2026-01-20 18:06:51 -0800
commit8b85dc4090e1c72c6d42acd823514cce67cd54fc (patch)
treebf0bf3a641b5120a37a0bad63877125967861309
parentc0e719cb36672b69a06da65ac4ec71e9a599dff5 (diff)
xfs: check if an open file is on the health monitored fs
Create a new ioctl for the healthmon file that checks that a given fd points to the same filesystem that the healthmon file is monitoring. This allows xfs_healer to check that when it reopens a mountpoint to perform repairs, the file that it gets matches the filesystem that generated the corruption report. (Note that xfs_healer doesn't maintain an open fd to a filesystem that it's monitoring so that it doesn't pin the mount.) Signed-off-by: "Darrick J. Wong" <djwong@kernel.org> Reviewed-by: Christoph Hellwig <hch@lst.de>
-rw-r--r--fs/xfs/libxfs/xfs_fs.h12
-rw-r--r--fs/xfs/xfs_healthmon.c34
2 files changed, 45 insertions, 1 deletions
diff --git a/fs/xfs/libxfs/xfs_fs.h b/fs/xfs/libxfs/xfs_fs.h
index 4ec1b2aede97..a01303c5de6c 100644
--- a/fs/xfs/libxfs/xfs_fs.h
+++ b/fs/xfs/libxfs/xfs_fs.h
@@ -1152,6 +1152,15 @@ struct xfs_health_monitor {
#define XFS_HEALTH_MONITOR_FMT_V0 (0)
/*
+ * Check that a given fd points to the same filesystem that the health monitor
+ * is monitoring.
+ */
+struct xfs_health_file_on_monitored_fs {
+ __s32 fd;
+ __u32 flags; /* zero for now */
+};
+
+/*
* ioctl commands that are used by Linux filesystems
*/
#define XFS_IOC_GETXFLAGS FS_IOC_GETFLAGS
@@ -1191,7 +1200,8 @@ struct xfs_health_monitor {
#define XFS_IOC_SCRUBV_METADATA _IOWR('X', 64, struct xfs_scrub_vec_head)
#define XFS_IOC_RTGROUP_GEOMETRY _IOWR('X', 65, struct xfs_rtgroup_geometry)
#define XFS_IOC_HEALTH_MONITOR _IOW ('X', 68, struct xfs_health_monitor)
-
+#define XFS_IOC_HEALTH_FD_ON_MONITORED_FS \
+ _IOW ('X', 69, struct xfs_health_file_on_monitored_fs)
/*
* ioctl commands that replace IRIX syssgi()'s
*/
diff --git a/fs/xfs/xfs_healthmon.c b/fs/xfs/xfs_healthmon.c
index 4a8cbd879322..3030fa93c1e5 100644
--- a/fs/xfs/xfs_healthmon.c
+++ b/fs/xfs/xfs_healthmon.c
@@ -1090,6 +1090,38 @@ xfs_healthmon_reconfigure(
return 0;
}
+/* Does the fd point to the same filesystem as the one we're monitoring? */
+STATIC long
+xfs_healthmon_file_on_monitored_fs(
+ struct file *file,
+ unsigned int cmd,
+ void __user *arg)
+{
+ struct xfs_health_file_on_monitored_fs hms;
+ struct xfs_healthmon *hm = file->private_data;
+ struct inode *hms_inode;
+
+ if (copy_from_user(&hms, arg, sizeof(hms)))
+ return -EFAULT;
+
+ if (hms.flags)
+ return -EINVAL;
+
+ CLASS(fd, hms_fd)(hms.fd);
+ if (fd_empty(hms_fd))
+ return -EBADF;
+
+ hms_inode = file_inode(fd_file(hms_fd));
+ mutex_lock(&hm->lock);
+ if (hm->mount_cookie != (uintptr_t)hms_inode->i_sb) {
+ mutex_unlock(&hm->lock);
+ return -ESTALE;
+ }
+
+ mutex_unlock(&hm->lock);
+ return 0;
+}
+
/* Handle ioctls for the health monitoring thread. */
STATIC long
xfs_healthmon_ioctl(
@@ -1102,6 +1134,8 @@ xfs_healthmon_ioctl(
switch (cmd) {
case XFS_IOC_HEALTH_MONITOR:
return xfs_healthmon_reconfigure(file, cmd, arg);
+ case XFS_IOC_HEALTH_FD_ON_MONITORED_FS:
+ return xfs_healthmon_file_on_monitored_fs(file, cmd, arg);
default:
break;
}