ext4: split _ext4_fiemap
authorChristoph Hellwig <hch@lst.de>
Sat, 23 May 2020 07:30:08 +0000 (09:30 +0200)
committerTheodore Ts'o <tytso@mit.edu>
Thu, 4 Jun 2020 03:16:54 +0000 (23:16 -0400)
The fiemap and EXT4_IOC_GET_ES_CACHE cases share almost no code, so split
them into entirely separate functions.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Ritesh Harjani <riteshh@linux.ibm.com>
Reviewed-by: Jan Kara <jack@suse.cz>
Link: https://lore.kernel.org/r/20200523073016.2944131-2-hch@lst.de
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
fs/ext4/extents.c

index 844773d..9e90f32 100644 (file)
@@ -4884,11 +4884,9 @@ static int ext4_fiemap_check_ranges(struct inode *inode, u64 start, u64 *len)
        return 0;
 }
 
-static int _ext4_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
-                       __u64 start, __u64 len, bool from_es_cache)
+int ext4_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
+               u64 start, u64 len)
 {
-       ext4_lblk_t start_blk;
-       u32 ext4_fiemap_flags = FIEMAP_FLAG_SYNC | FIEMAP_FLAG_XATTR;
        int error = 0;
 
        if (fieinfo->fi_flags & FIEMAP_FLAG_CACHE) {
@@ -4898,10 +4896,7 @@ static int _ext4_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
                fieinfo->fi_flags &= ~FIEMAP_FLAG_CACHE;
        }
 
-       if (from_es_cache)
-               ext4_fiemap_flags &= FIEMAP_FLAG_XATTR;
-
-       if (fiemap_check_flags(fieinfo, ext4_fiemap_flags))
+       if (fiemap_check_flags(fieinfo, FIEMAP_FLAG_SYNC | FIEMAP_FLAG_XATTR))
                return -EBADR;
 
        /*
@@ -4915,40 +4910,20 @@ static int _ext4_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
 
        if (fieinfo->fi_flags & FIEMAP_FLAG_XATTR) {
                fieinfo->fi_flags &= ~FIEMAP_FLAG_XATTR;
-               error = iomap_fiemap(inode, fieinfo, start, len,
-                                    &ext4_iomap_xattr_ops);
-       } else if (!from_es_cache) {
-               error = iomap_fiemap(inode, fieinfo, start, len,
-                                    &ext4_iomap_report_ops);
-       } else {
-               ext4_lblk_t len_blks;
-               __u64 last_blk;
-
-               start_blk = start >> inode->i_sb->s_blocksize_bits;
-               last_blk = (start + len - 1) >> inode->i_sb->s_blocksize_bits;
-               if (last_blk >= EXT_MAX_BLOCKS)
-                       last_blk = EXT_MAX_BLOCKS-1;
-               len_blks = ((ext4_lblk_t) last_blk) - start_blk + 1;
-
-               /*
-                * Walk the extent tree gathering extent information
-                * and pushing extents back to the user.
-                */
-               error = ext4_fill_es_cache_info(inode, start_blk, len_blks,
-                                               fieinfo);
+               return iomap_fiemap(inode, fieinfo, start, len,
+                                   &ext4_iomap_xattr_ops);
        }
-       return error;
-}
 
-int ext4_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
-               __u64 start, __u64 len)
-{
-       return _ext4_fiemap(inode, fieinfo, start, len, false);
+       return iomap_fiemap(inode, fieinfo, start, len, &ext4_iomap_report_ops);
 }
 
 int ext4_get_es_cache(struct inode *inode, struct fiemap_extent_info *fieinfo,
                      __u64 start, __u64 len)
 {
+       ext4_lblk_t start_blk, len_blks;
+       __u64 last_blk;
+       int error = 0;
+
        if (ext4_has_inline_data(inode)) {
                int has_inline;
 
@@ -4959,9 +4934,32 @@ int ext4_get_es_cache(struct inode *inode, struct fiemap_extent_info *fieinfo,
                        return 0;
        }
 
-       return _ext4_fiemap(inode, fieinfo, start, len, true);
-}
+       if (fieinfo->fi_flags & FIEMAP_FLAG_CACHE) {
+               error = ext4_ext_precache(inode);
+               if (error)
+                       return error;
+               fieinfo->fi_flags &= ~FIEMAP_FLAG_CACHE;
+       }
+
+       if (fiemap_check_flags(fieinfo, FIEMAP_FLAG_SYNC))
+               return -EBADR;
 
+       error = ext4_fiemap_check_ranges(inode, start, &len);
+       if (error)
+               return error;
+
+       start_blk = start >> inode->i_sb->s_blocksize_bits;
+       last_blk = (start + len - 1) >> inode->i_sb->s_blocksize_bits;
+       if (last_blk >= EXT_MAX_BLOCKS)
+               last_blk = EXT_MAX_BLOCKS-1;
+       len_blks = ((ext4_lblk_t) last_blk) - start_blk + 1;
+
+       /*
+        * Walk the extent tree gathering extent information
+        * and pushing extents back to the user.
+        */
+       return ext4_fill_es_cache_info(inode, start_blk, len_blks, fieinfo);
+}
 
 /*
  * ext4_access_path: