OSDN Git Service

xfs: wire up the v5 inumbers ioctl
authorDarrick J. Wong <darrick.wong@oracle.com>
Thu, 4 Jul 2019 03:36:28 +0000 (20:36 -0700)
committerDarrick J. Wong <darrick.wong@oracle.com>
Thu, 4 Jul 2019 03:36:28 +0000 (20:36 -0700)
Wire up the v5 INUMBERS ioctl.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Brian Foster <bfoster@redhat.com>
fs/xfs/libxfs/xfs_fs.h
fs/xfs/xfs_ioctl.c
fs/xfs/xfs_ioctl32.c
fs/xfs/xfs_ondisk.h

index 960f354..aa4918a 100644 (file)
@@ -478,6 +478,13 @@ struct xfs_bulkstat_req {
 #define XFS_BULKSTAT_REQ_SIZE(nr)      (sizeof(struct xfs_bulkstat_req) + \
                                         (nr) * sizeof(struct xfs_bulkstat))
 
+struct xfs_inumbers_req {
+       struct xfs_bulk_ireq    hdr;
+       struct xfs_inumbers     inumbers[];
+};
+#define XFS_INUMBERS_REQ_SIZE(nr)      (sizeof(struct xfs_inumbers_req) + \
+                                        (nr) * sizeof(struct xfs_inumbers))
+
 /*
  * Error injection.
  */
@@ -780,6 +787,7 @@ struct xfs_scrub_metadata {
 #define XFS_IOC_GOINGDOWN           _IOR ('X', 125, uint32_t)
 #define XFS_IOC_FSGEOMETRY          _IOR ('X', 126, struct xfs_fsop_geom)
 #define XFS_IOC_BULKSTAT            _IOR ('X', 127, struct xfs_bulkstat_req)
+#define XFS_IOC_INUMBERS            _IOR ('X', 128, struct xfs_inumbers_req)
 /*     XFS_IOC_GETFSUUID ---------- deprecated 140      */
 
 
index cab6832..ae7b743 100644 (file)
@@ -914,6 +914,56 @@ out_teardown:
 }
 
 STATIC int
+xfs_inumbers_fmt(
+       struct xfs_ibulk                *breq,
+       const struct xfs_inumbers       *igrp)
+{
+       if (copy_to_user(breq->ubuffer, igrp, sizeof(struct xfs_inumbers)))
+               return -EFAULT;
+       return xfs_ibulk_advance(breq, sizeof(struct xfs_inumbers));
+}
+
+/* Handle the v5 inumbers ioctl. */
+STATIC int
+xfs_ioc_inumbers(
+       struct xfs_mount                *mp,
+       unsigned int                    cmd,
+       struct xfs_inumbers_req __user  *arg)
+{
+       struct xfs_bulk_ireq            hdr;
+       struct xfs_ibulk                breq = {
+               .mp                     = mp,
+       };
+       int                             error;
+
+       if (!capable(CAP_SYS_ADMIN))
+               return -EPERM;
+
+       if (XFS_FORCED_SHUTDOWN(mp))
+               return -EIO;
+
+       if (copy_from_user(&hdr, &arg->hdr, sizeof(hdr)))
+               return -EFAULT;
+
+       error = xfs_bulk_ireq_setup(mp, &hdr, &breq, arg->inumbers);
+       if (error == XFS_ITER_ABORT)
+               goto out_teardown;
+       if (error < 0)
+               return error;
+
+       error = xfs_inumbers(&breq, xfs_inumbers_fmt);
+       if (error)
+               return error;
+
+out_teardown:
+       xfs_bulk_ireq_teardown(&hdr, &breq);
+       if (copy_to_user(&arg->hdr, &hdr, sizeof(hdr)))
+               return -EFAULT;
+
+       return 0;
+}
+
+STATIC int
 xfs_ioc_fsgeometry(
        struct xfs_mount        *mp,
        void                    __user *arg,
@@ -2079,6 +2129,8 @@ xfs_file_ioctl(
 
        case XFS_IOC_BULKSTAT:
                return xfs_ioc_bulkstat(mp, cmd, arg);
+       case XFS_IOC_INUMBERS:
+               return xfs_ioc_inumbers(mp, cmd, arg);
 
        case XFS_IOC_FSGEOMETRY_V1:
                return xfs_ioc_fsgeometry(mp, arg, 3);
index a98a505..7fcf756 100644 (file)
@@ -575,6 +575,7 @@ xfs_file_compat_ioctl(
        case FS_IOC_GETFSMAP:
        case XFS_IOC_SCRUB_METADATA:
        case XFS_IOC_BULKSTAT:
+       case XFS_IOC_INUMBERS:
                return xfs_file_ioctl(filp, cmd, p);
 #if !defined(BROKEN_X86_ALIGNMENT) || defined(CONFIG_X86_X32)
        /*
index 954484c..b6701b4 100644 (file)
@@ -150,6 +150,7 @@ xfs_check_ondisk_structs(void)
        XFS_CHECK_STRUCT_SIZE(struct xfs_bulkstat,              192);
        XFS_CHECK_STRUCT_SIZE(struct xfs_inumbers,              24);
        XFS_CHECK_STRUCT_SIZE(struct xfs_bulkstat_req,          64);
+       XFS_CHECK_STRUCT_SIZE(struct xfs_inumbers_req,          64);
 }
 
 #endif /* __XFS_ONDISK_H */