ext4: split _ext4_fiemap

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>
This commit is contained in:
Christoph Hellwig 2020-05-23 09:30:08 +02:00 committed by Theodore Ts'o
parent 328e24ae14
commit 03a5ed24c9
1 changed files with 35 additions and 37 deletions

View 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: