xfs
[Top] [All Lists]

[PATCH 2/6] fiemap: add fe_phys_length and EXTENT_PHYS_LENGTH flag

To: linux-fsdevel@xxxxxxxxxxxxxxx
Subject: [PATCH 2/6] fiemap: add fe_phys_length and EXTENT_PHYS_LENGTH flag
From: David Sterba <dsterba@xxxxxxx>
Date: Wed, 30 Jul 2014 19:18:36 +0200
Cc: David Sterba <dsterba@xxxxxxx>, adilger@xxxxxxxxx, hch@xxxxxxxxxxxxx, mfasheh@xxxxxxxx, viro@xxxxxxxxxxxxxxxxxx, david@xxxxxxxxxxxxx, xfs@xxxxxxxxxxx, linux-nilfs@xxxxxxxxxxxxxxx, ocfs2-devel@xxxxxxxxxxxxxx, linux-ext4@xxxxxxxxxxxxxxx, linux-btrfs@xxxxxxxxxxxxxxx
Delivered-to: xfs@xxxxxxxxxxx
In-reply-to: <cover.1406739708.git.dsterba@xxxxxxx>
References: <cover.1406739708.git.dsterba@xxxxxxx>
Add a new member to fiemap_extent that represents the physical extent
length. This value is undefined if the flag EXTENT_PHYS_LENGTH is not
set.

No functional change to existing fiemap users.

Signed-off-by: David Sterba <dsterba@xxxxxxx>
---
 fs/btrfs/extent_io.c        |  2 +-
 fs/ext4/extents.c           |  4 ++--
 fs/ext4/inline.c            |  2 +-
 fs/gfs2/inode.c             |  2 +-
 fs/ioctl.c                  | 13 ++++++++-----
 fs/nilfs2/inode.c           |  8 +++++---
 fs/ocfs2/extent_map.c       |  4 ++--
 fs/xfs/xfs_iops.c           |  2 +-
 include/linux/fs.h          |  2 +-
 include/uapi/linux/fiemap.h |  6 +++++-
 10 files changed, 27 insertions(+), 18 deletions(-)

diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index a389820d158b..c85da2e54ce7 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -4357,7 +4357,7 @@ int extent_fiemap(struct inode *inode, struct 
fiemap_extent_info *fieinfo,
                        end = 1;
                }
                ret = fiemap_fill_next_extent(fieinfo, em_start, disko,
-                                             em_len, flags);
+                                             em_len, 0, flags);
                if (ret)
                        goto out_free;
        }
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index 4da228a0e6d0..a194024e96a2 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -2253,7 +2253,7 @@ static int ext4_fill_fiemap_extents(struct inode *inode,
                                (__u64)es.es_lblk << blksize_bits,
                                (__u64)es.es_pblk << blksize_bits,
                                (__u64)es.es_len << blksize_bits,
-                               flags);
+                               0, flags);
                        if (err < 0)
                                break;
                        if (err == 1) {
@@ -5125,7 +5125,7 @@ static int ext4_xattr_fiemap(struct inode *inode,
 
        if (physical)
                error = fiemap_fill_next_extent(fieinfo, 0, physical,
-                                               length, flags);
+                                               length, 0, flags);
        return (error < 0 ? error : 0);
 }
 
diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c
index 645205d8ada6..16f93d8100db 100644
--- a/fs/ext4/inline.c
+++ b/fs/ext4/inline.c
@@ -1825,7 +1825,7 @@ int ext4_inline_data_fiemap(struct inode *inode,
 
        if (physical)
                error = fiemap_fill_next_extent(fieinfo, 0, physical,
-                                               length, flags);
+                                               length, 0, flags);
        brelse(iloc.bh);
 out:
        up_read(&EXT4_I(inode)->xattr_sem);
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index e62e59477884..d0d35557ab5f 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -1931,7 +1931,7 @@ static int gfs2_fiemap(struct inode *inode, struct 
fiemap_extent_info *fieinfo,
                        len = size - start;
                if (start < size)
                        ret = fiemap_fill_next_extent(fieinfo, start, phys,
-                                                     len, flags);
+                                                     len, 0, flags);
                if (ret == 1)
                        ret = 0;
        } else {
diff --git a/fs/ioctl.c b/fs/ioctl.c
index 8ac3fad36192..127551c70b0a 100644
--- a/fs/ioctl.c
+++ b/fs/ioctl.c
@@ -70,6 +70,7 @@ static int ioctl_fibmap(struct file *filp, int __user *p)
  * @logical:   Extent logical start offset, in bytes
  * @phys:      Extent physical start offset, in bytes
  * @len:       Extent length, in bytes
+ * @phys_len:   Physical extent length in bytes
  * @flags:     FIEMAP_EXTENT flags that describe this extent
  *
  * Called from file system ->fiemap callback. Will populate extent
@@ -83,7 +84,7 @@ static int ioctl_fibmap(struct file *filp, int __user *p)
 #define SET_NO_UNMOUNTED_IO_FLAGS      (FIEMAP_EXTENT_DATA_ENCRYPTED)
 #define SET_NOT_ALIGNED_FLAGS  
(FIEMAP_EXTENT_DATA_TAIL|FIEMAP_EXTENT_DATA_INLINE)
 int fiemap_fill_next_extent(struct fiemap_extent_info *fieinfo, u64 logical,
-                           u64 phys, u64 len, u32 flags)
+                           u64 phys, u64 len, u64 phys_len, u32 flags)
 {
        struct fiemap_extent extent;
        struct fiemap_extent __user *dest = fieinfo->fi_extents_start;
@@ -109,6 +110,7 @@ int fiemap_fill_next_extent(struct fiemap_extent_info 
*fieinfo, u64 logical,
        extent.fe_physical = phys;
        extent.fe_length = len;
        extent.fe_flags = flags;
+       extent.fe_phys_length = phys_len;
 
        dest += fieinfo->fi_extents_mapped;
        if (copy_to_user(dest, &extent, sizeof(extent)))
@@ -318,10 +320,11 @@ int __generic_block_fiemap(struct inode *inode,
                                flags = FIEMAP_EXTENT_MERGED|FIEMAP_EXTENT_LAST;
                                ret = fiemap_fill_next_extent(fieinfo, logical,
                                                              phys, size,
-                                                             flags);
+                                                             0, flags);
                        } else if (size) {
                                ret = fiemap_fill_next_extent(fieinfo, logical,
-                                                             phys, size, 
flags);
+                                                             phys, size,
+                                                             0, flags);
                                size = 0;
                        }
 
@@ -347,7 +350,7 @@ int __generic_block_fiemap(struct inode *inode,
                        if (start_blk > last_blk && !whole_file) {
                                ret = fiemap_fill_next_extent(fieinfo, logical,
                                                              phys, size,
-                                                             flags);
+                                                             0, flags);
                                break;
                        }
 
@@ -358,7 +361,7 @@ int __generic_block_fiemap(struct inode *inode,
                        if (size) {
                                ret = fiemap_fill_next_extent(fieinfo, logical,
                                                              phys, size,
-                                                             flags);
+                                                             0, flags);
                                if (ret)
                                        break;
                        }
diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c
index 6252b173a465..a99e6d093f11 100644
--- a/fs/nilfs2/inode.c
+++ b/fs/nilfs2/inode.c
@@ -1017,7 +1017,8 @@ int nilfs_fiemap(struct inode *inode, struct 
fiemap_extent_info *fieinfo,
                        if (size) {
                                /* End of the current extent */
                                ret = fiemap_fill_next_extent(
-                                       fieinfo, logical, phys, size, flags);
+                                       fieinfo, logical, phys, size, 0,
+                                       flags);
                                if (ret)
                                        break;
                        }
@@ -1067,7 +1068,8 @@ int nilfs_fiemap(struct inode *inode, struct 
fiemap_extent_info *fieinfo,
                                        flags |= FIEMAP_EXTENT_LAST;
 
                                ret = fiemap_fill_next_extent(
-                                       fieinfo, logical, phys, size, flags);
+                                       fieinfo, logical, phys, size,
+                                       0, flags);
                                if (ret)
                                        break;
                                size = 0;
@@ -1083,7 +1085,7 @@ int nilfs_fiemap(struct inode *inode, struct 
fiemap_extent_info *fieinfo,
                                        /* Terminate the current extent */
                                        ret = fiemap_fill_next_extent(
                                                fieinfo, logical, phys, size,
-                                               flags);
+                                               0, flags);
                                        if (ret || blkoff > end_blkoff)
                                                break;
 
diff --git a/fs/ocfs2/extent_map.c b/fs/ocfs2/extent_map.c
index 767370b656ca..cb0276908155 100644
--- a/fs/ocfs2/extent_map.c
+++ b/fs/ocfs2/extent_map.c
@@ -736,7 +736,7 @@ static int ocfs2_fiemap_inline(struct inode *inode, struct 
buffer_head *di_bh,
                                         id2.i_data.id_data);
 
                ret = fiemap_fill_next_extent(fieinfo, 0, phys, id_count,
-                                             flags);
+                                             0, flags);
                if (ret < 0)
                        return ret;
        }
@@ -809,7 +809,7 @@ int ocfs2_fiemap(struct inode *inode, struct 
fiemap_extent_info *fieinfo,
                virt_bytes = (u64)le32_to_cpu(rec.e_cpos) << 
osb->s_clustersize_bits;
 
                ret = fiemap_fill_next_extent(fieinfo, virt_bytes, phys_bytes,
-                                             len_bytes, fe_flags);
+                                             len_bytes, 0, fe_flags);
                if (ret)
                        break;
 
diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c
index 205613a06068..5a7c1f6d1189 100644
--- a/fs/xfs/xfs_iops.c
+++ b/fs/xfs/xfs_iops.c
@@ -1030,7 +1030,7 @@ xfs_fiemap_format(
                fiemap_flags |= FIEMAP_EXTENT_LAST;
 
        error = fiemap_fill_next_extent(fieinfo, logical, physical,
-                                       length, fiemap_flags);
+                                       length, 0, fiemap_flags);
        if (error > 0) {
                error = 0;
                *full = 1;      /* user array now full */
diff --git a/include/linux/fs.h b/include/linux/fs.h
index e11d60cc867b..609e1d72c3e0 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1412,7 +1412,7 @@ struct fiemap_extent_info {
                                                        fiemap_extent array */
 };
 int fiemap_fill_next_extent(struct fiemap_extent_info *info, u64 logical,
-                           u64 phys, u64 len, u32 flags);
+                           u64 phys, u64 len, u64 phys_len, u32 flags);
 int fiemap_check_flags(struct fiemap_extent_info *fieinfo, u32 fs_flags);
 
 /*
diff --git a/include/uapi/linux/fiemap.h b/include/uapi/linux/fiemap.h
index 93abfcd9ac47..ed52d3f7821d 100644
--- a/include/uapi/linux/fiemap.h
+++ b/include/uapi/linux/fiemap.h
@@ -19,7 +19,9 @@ struct fiemap_extent {
        __u64 fe_physical; /* physical offset in bytes for the start
                            * of the extent from the beginning of the disk */
        __u64 fe_length;   /* length in bytes for this extent */
-       __u64 fe_reserved64[2];
+       __u64 fe_phys_length; /* physical length in bytes, may be different from
+                               * fe_length, is valid if PHYS_LENGTH flag set */
+       __u64 fe_reserved64;
        __u32 fe_flags;    /* FIEMAP_EXTENT_* flags for this extent */
        __u32 fe_reserved[3];
 };
@@ -50,6 +52,8 @@ struct fiemap {
                                                    * Sets EXTENT_UNKNOWN. */
 #define FIEMAP_EXTENT_ENCODED          0x00000008 /* Data can not be read
                                                    * while fs is unmounted */
+#define FIEMAP_EXTENT_PHYS_LENGTH      0x00000010 /* Physical length of extent
+                                                   * not the same as logical */
 #define FIEMAP_EXTENT_DATA_ENCRYPTED   0x00000080 /* Data is encrypted by fs.
                                                    * Sets EXTENT_ENCODED */
 #define FIEMAP_EXTENT_NOT_ALIGNED      0x00000100 /* Extent offsets may not be
-- 
1.8.4.5

<Prev in Thread] Current Thread [Next in Thread>