xfs
[Top] [All Lists]

[PATCH 3/4] xfs: Adding XFS_IOC_FIEMAPFS ioctl for use in xfs_spaceman

To: <xfs@xxxxxxxxxxx>
Subject: [PATCH 3/4] xfs: Adding XFS_IOC_FIEMAPFS ioctl for use in xfs_spaceman
From: Dhruvesh Rathore <adrscube@xxxxxxxxx>
Date: Thu, 29 Jan 2015 18:59:22 +0530
Delivered-to: xfs@xxxxxxxxxxx
Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=message-id:from:date:subject:to; bh=2FU32PgQBDWvigbLsBLoflXx7eeztsOlWM/xI5AXj00=; b=Fiq41HukHVDcAEZvjZv2wtriXYlikeEWwi1n7Jb8BERTU/TehhSHwjLqVEnqD0pieH RiaHu3WGSab0vx4DxnVTTahKfhm8AnPAaghFkr+6Roxqkr5t3tT/vqcroJgRrnCRA8NB tJIwx5qcZABt38hL387STKbryLCmouarKq5cCbJjDa/9ZOd8kbhfaU7DorQTINSn4I7i 0QFuxgA9MqDUDOzajZcYPQG/qRagcRCDSNiT/upUyYHIx7No1aTyG9/4oeBumdPxazN0 0waP9eSbN5hDhcS1uu1Ei2ysJ9Ly3mZ0K/f0DcYxvTSdrCVLFhXfMaN/bVI58k0E8nM2 MOiA==
This patch is concerned with the changes to be done in kernel space code for
turning FS_IOC_FIEMAPFS present in the earlier version of xfs_spaceman 
into an XFS specific ioctl called XFS_IOC_FIEMAPFS, which uses all existing
fiemap insfrastructure.
By introducing XFS_IOC_FIMEAPFS ioctl, it can be seperated from file based
fiemap commands and allows us to review it and push it as we need, making the
process much simpler.

----------------------------------------------------------------------------------------

Signed-off-by: Dhruvesh Rathore <dhruvesh_r@xxxxxxxxxxx>
Signed-off-by: Amey Ruikar <ameyruikar@xxxxxxxxx>
Signed-off-by: Somdeep Dey <somdeepdey10@xxxxxxxxx>
---
fs/ioctl.c              | 3  ++-
include/linux/fs.h      | 6  ++++++
fs/xfs/xfs_ioctl.c      | 55 +++++++++++++
fs/xfs/xfs_fs.h         | 1  +
4 files changed, 64 insertions(+), 1 deletion(-) 

--- a/fs/ioctl.c        2015-01-29 18:08:19.608874677 +0530
+++ b/fs/ioctl.c        2015-01-29 18:07:39.624876178 +0530

@@ -175,7 +175,7 @@
 }
 EXPORT_SYMBOL(fiemapfs_check_flags);
 
-static int fiemap_check_ranges(struct super_block *sb,
+int fiemap_check_ranges(struct super_block *sb,
                               u64 start, u64 len, u64 *new_len)
 {
        u64 maxbytes = (u64) sb->s_maxbytes;
@@ -196,6 +196,7 @@
 
        return 0;
 }
+EXPORT_SYMBOL(fiemap_check_ranges);
 
 static int ioctl_fiemap(struct file *filp, unsigned long arg)
 {

----------------------------------------------------------------------------------------

--- a/include/linux/fs.h        2015-01-29 18:00:44.716891762 +0530
+++ b/include/linux/fs.h        2015-01-29 17:59:34.532894398 +0530

@@ -1435,6 +1435,9 @@
  * VFS FS_IOC_FIEMAP helper definitions.
  */
 
+/* So that the fiemap access checks can't overflow on 32 bit machines. */
+#define FIEMAP_MAX_EXTENTS     (UINT_MAX / sizeof(struct fiemap_extent))
+
 struct fiemap_extent_info {
        unsigned int fi_flags;          /* Flags as passed from user */
        unsigned int fi_extents_mapped; /* Number of mapped extents */
@@ -1447,6 +1450,9 @@
 int fiemap_check_flags(struct fiemap_extent_info *fieinfo, u32 fs_flags);
 int fiemapfs_check_flags(struct fiemap_extent_info *fieinfo, u32 fs_flags);
 
+int fiemap_check_ranges(struct super_block *sb,
+                       u64 start, u64 len, u64 *new_len);
+
 /*
  * File types
  *

----------------------------------------------------------------------------------------

--- a/fs/xfs/xfs_ioctl.c        2015-01-29 17:55:05.452904504 +0530
+++ b/fs/xfs/xfs_ioctl.c        2015-01-29 17:50:40.852914441 +0530

@@ -1509,6 +1509,58 @@
        return error;
 }
 
+/*
+ * Mostly similar to ioctl_fiemap() function present
+ * in fs/ioctl.c
+ */
+static int
+xfs_ioctl_fiemapfs(
+       struct xfs_mount        *mp,
+       void                    __user *arg)
+{
+       struct fiemap           fiemap;
+       u64                     len;
+       int                     error;
+
+       struct fiemap __user *ufiemap = (struct fiemap __user *) arg;
+       struct fiemap_extent_info fieinfo = { 0, };
+
+       if (copy_from_user(&fiemap, ufiemap, sizeof(fiemap)))
+               return -EFAULT;
+
+       if (fiemap.fm_extent_count > FIEMAP_MAX_EXTENTS)
+               return -EINVAL;
+
+       error = fiemap_check_ranges(mp->m_super, fiemap.fm_start, 
fiemap.fm_length,
+                                       &len);
+       if (error)
+               return error;
+
+       fieinfo.fi_flags = fiemap.fm_flags;
+       fieinfo.fi_extents_max = fiemap.fm_extent_count;
+       fieinfo.fi_extents_start = ufiemap->fm_extents;
+
+       if (fiemap.fm_extent_count != 0 &&
+               !access_ok(VERIFY_WRITE, fieinfo.fi_extents_start,
+                       fieinfo.fi_extents_max * sizeof(struct fiemap_extent)))
+               return -EFAULT;
+
+       if (fiemap.fm_extent_count != 0 &&
+               (fiemap.fm_flags & FIEMAPFS_FLAG_FREESP_SIZE_HINT) &&
+               !access_ok(VERIFY_READ, fieinfo.fi_extents_start,
+                       sizeof(struct fiemap_extent)))
+               return -EFAULT;
+
+       error = mp->m_super->s_op->fiemapfs(mp->m_super, &fieinfo, 
fiemap.fm_start,
+                                               len);
+
+       fiemap.fm_flags = fieinfo.fi_flags;
+       fiemap.fm_mapped_extents = fieinfo.fi_extents_mapped;
+       if (copy_to_user(ufiemap, &fiemap, sizeof(fiemap)))
+               error = -EFAULT;
+
+       return error;
+}
 
 /*
  * Note: some of the ioctl's return positive numbers as a
@@ -1566,6 +1618,9 @@
                return 0;
        }
 
+       case XFS_IOC_FIEMAPFS:
+               return xfs_ioctl_fiemapfs(mp, arg);
+
        case XFS_IOC_FSBULKSTAT_SINGLE:
        case XFS_IOC_FSBULKSTAT:
        case XFS_IOC_FSINUMBERS:

----------------------------------------------------------------------------------------

--- a/fs/xfs/xfs_fs.h   2015-01-29 15:26:46.954401773 +0530
+++ b/fs/xfs/xfs_fs.h   2015-01-29 11:29:54.531652554 +0530

@@ -505,6 +505,7 @@
 #define XFS_IOC_DIOINFO        _IOR ('X', 30, struct dioattr)
 #define XFS_IOC_FSGETXATTR     _IOR ('X', 31, struct fsxattr)
 #define XFS_IOC_FSSETXATTR     _IOW ('X', 32, struct fsxattr)
+#define XFS_IOC_FIEMAPFS       _IOWR('X', 33, struct fiemap)
 #define XFS_IOC_ALLOCSP64      _IOW ('X', 36, struct xfs_flock64)
 #define XFS_IOC_FREESP64       _IOW ('X', 37, struct xfs_flock64)
 #define XFS_IOC_GETBMAP        _IOWR('X', 38, struct getbmap)

----------------------------------------------------------------------------------------

<Prev in Thread] Current Thread [Next in Thread>
  • [PATCH 3/4] xfs: Adding XFS_IOC_FIEMAPFS ioctl for use in xfs_spaceman, Dhruvesh Rathore <=