Skip to content

Commit c03f8aa

Browse files
Lukas Czernertytso
authored andcommitted
ext4: use FIEMAP_EXTENT_LAST flag for last extent in fiemap
Currently we are not marking the extent as the last one (FIEMAP_EXTENT_LAST) if there is a hole at the end of the file. This is because we just do not check for it right now and continue searching for next extent. But at the point we hit the hole at the end of the file, it is too late. This commit adds check for the allocated block in subsequent extent and if there is no more extents (block = EXT_MAX_BLOCKS) just flag the current one as the last one. This behaviour has been spotted unintentionally by 252 xfstest, when the test hangs out, because of wrong loop condition. However on other filesystems (like xfs) it will exit anyway, because we notice the last extent flag and exit. With this patch xfstest 252 does not hang anymore, ext4 fiemap implementation still reports bad extent type in some cases, however this seems to be different issue. Signed-off-by: Lukas Czerner <[email protected]> Signed-off-by: "Theodore Ts'o" <[email protected]>
1 parent f17722f commit c03f8aa

File tree

2 files changed

+4
-6
lines changed

2 files changed

+4
-6
lines changed

fs/ext4/ext4_extents.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ struct ext4_ext_path {
125125
* positive retcode - signal for ext4_ext_walk_space(), see below
126126
* callback must return valid extent (passed or newly created)
127127
*/
128-
typedef int (*ext_prepare_callback)(struct inode *, struct ext4_ext_path *,
128+
typedef int (*ext_prepare_callback)(struct inode *, ext4_lblk_t,
129129
struct ext4_ext_cache *,
130130
struct ext4_extent *, void *);
131131

fs/ext4/extents.c

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1958,7 +1958,7 @@ static int ext4_ext_walk_space(struct inode *inode, ext4_lblk_t block,
19581958
err = -EIO;
19591959
break;
19601960
}
1961-
err = func(inode, path, &cbex, ex, cbdata);
1961+
err = func(inode, next, &cbex, ex, cbdata);
19621962
ext4_ext_drop_refs(path);
19631963

19641964
if (err < 0)
@@ -3914,14 +3914,13 @@ int ext4_convert_unwritten_extents(struct inode *inode, loff_t offset,
39143914
/*
39153915
* Callback function called for each extent to gather FIEMAP information.
39163916
*/
3917-
static int ext4_ext_fiemap_cb(struct inode *inode, struct ext4_ext_path *path,
3917+
static int ext4_ext_fiemap_cb(struct inode *inode, ext4_lblk_t next,
39183918
struct ext4_ext_cache *newex, struct ext4_extent *ex,
39193919
void *data)
39203920
{
39213921
__u64 logical;
39223922
__u64 physical;
39233923
__u64 length;
3924-
loff_t size;
39253924
__u32 flags = 0;
39263925
int ret = 0;
39273926
struct fiemap_extent_info *fieinfo = data;
@@ -4103,8 +4102,7 @@ static int ext4_ext_fiemap_cb(struct inode *inode, struct ext4_ext_path *path,
41034102
if (ex && ext4_ext_is_uninitialized(ex))
41044103
flags |= FIEMAP_EXTENT_UNWRITTEN;
41054104

4106-
size = i_size_read(inode);
4107-
if (logical + length >= size)
4105+
if (next == EXT_MAX_BLOCKS)
41084106
flags |= FIEMAP_EXTENT_LAST;
41094107

41104108
ret = fiemap_fill_next_extent(fieinfo, logical, physical,

0 commit comments

Comments
 (0)