/* 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
*/
#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
*/
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(
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;
}