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>
This commit is contained in:
Darrick J. Wong 2026-01-20 18:06:51 -08:00
parent c0e719cb36
commit 8b85dc4090
2 changed files with 45 additions and 1 deletions

View File

@ -1151,6 +1151,15 @@ struct xfs_health_monitor {
/* Initial return format version */
#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
*/
@ -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
*/

View File

@ -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;
}