* [PATCH 1/2] ext4: Fix fsmap end of range reporting with bigalloc
@ 2025-08-05 8:30 Ojaswin Mujoo
2025-08-05 8:30 ` [PATCH 2/2] ext4: Fix reserved gdt blocks handling in fsmap Ojaswin Mujoo
` (2 more replies)
0 siblings, 3 replies; 5+ messages in thread
From: Ojaswin Mujoo @ 2025-08-05 8:30 UTC (permalink / raw)
To: linux-ext4, Theodore Ts'o
Cc: Ritesh Harjani, Zhang Yi, linux-kernel, Darrick J . Wong,
linux-fsdevel, Disha Goel
With bigalloc enabled, the logic to report last extent has a bug since
we try to use cluster units instead of block units. This can cause an issue
where extra incorrect entries might be returned back to the user. This was
flagged by generic/365 with 64k bs and -O bigalloc.
** Details of issue **
The issue was noticed on 5G 64k blocksize FS with -O bigalloc which has
only 1 bg.
$ xfs_io -c "fsmap -d" /mnt/scratch
0: 253:48 [0..127]: static fs metadata 128 /* sb */
1: 253:48 [128..255]: special 102:1 128 /* gdt */
3: 253:48 [256..383]: special 102:3 128 /* block bitmap */
4: 253:48 [384..2303]: unknown 1920 /* flex bg empty space */
5: 253:48 [2304..2431]: special 102:4 128 /* inode bitmap */
6: 253:48 [2432..4351]: unknown 1920 /* flex bg empty space */
7: 253:48 [4352..6911]: inodes 2560
8: 253:48 [6912..538623]: unknown 531712
9: 253:48 [538624..10485759]: free space 9947136
The issue can be seen with:
$ xfs_io -c "fsmap -d 0 3" /mnt/scratch
0: 253:48 [0..127]: static fs metadata 128
1: 253:48 [384..2047]: unknown 1664
Only the first entry was expected to be returned but we get 2. This is
because:
ext4_getfsmap_datadev()
first_cluster, last_cluster = 0
...
info->gfi_last = true;
ext4_getfsmap_datadev_helper(sb, end_ag, last_cluster + 1, 0, info);
fsb = C2B(1) = 16
fslen = 0
...
/* Merge in any relevant extents from the meta_list */
list_for_each_entry_safe(p, tmp, &info->gfi_meta_list, fmr_list) {
...
// since fsb = 16, considers all metadata which starts before 16 blockno
iter 1: error = ext4_getfsmap_helper(sb, info, p); // p = sb (0,1), nop
info->gfi_next_fsblk = 1
iter 2: error = ext4_getfsmap_helper(sb, info, p); // p = gdt (1,2), nop
info->gfi_next_fsblk = 2
iter 3: error = ext4_getfsmap_helper(sb, info, p); // p = blk bitmap (2,3), nop
info->gfi_next_fsblk = 3
iter 4: error = ext4_getfsmap_helper(sb, info, p); // p = ino bitmap (18,19)
if (rec_blk > info->gfi_next_fsblk) { // (18 > 3)
// emits an extra entry ** BUG **
}
}
Fix this by directly calling ext4_getfsmap_datadev() with a dummy record
that has fmr_physical set to (end_fsb + 1) instead of last_cluster + 1. By
using the block instead of cluster we get the correct behavior.
Replacing ext4_getfsmap_datadev_helper() with ext4_getfsmap_helper() is
okay since the gfi_lastfree and metadata checks in
ext4_getfsmap_datadev_helper() are anyways redundant when we only want to
emit the last allocated block of the range, as we have already taken care
of emitting metadata and any last free blocks.
Reported-by: Disha Goel <disgoel@linux.ibm.com>
Fixes: 4a622e4d477b ("ext4: fix FS_IOC_GETFSMAP handling")
Signed-off-by: Ojaswin Mujoo <ojaswin@linux.ibm.com>
---
fs/ext4/fsmap.c | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/fs/ext4/fsmap.c b/fs/ext4/fsmap.c
index 383c6edea6dd..9d63c39f6077 100644
--- a/fs/ext4/fsmap.c
+++ b/fs/ext4/fsmap.c
@@ -526,6 +526,7 @@ static int ext4_getfsmap_datadev(struct super_block *sb,
ext4_group_t end_ag;
ext4_grpblk_t first_cluster;
ext4_grpblk_t last_cluster;
+ struct ext4_fsmap irec;
int error = 0;
bofs = le32_to_cpu(sbi->s_es->s_first_data_block);
@@ -609,10 +610,18 @@ static int ext4_getfsmap_datadev(struct super_block *sb,
goto err;
}
- /* Report any gaps at the end of the bg */
+ /*
+ * The dummy record below will cause ext4_getfsmap_helper() to report
+ * any allocated blocks at the end of the range.
+ */
+ irec.fmr_device = 0;
+ irec.fmr_physical = end_fsb + 1;
+ irec.fmr_length = 0;
+ irec.fmr_owner = EXT4_FMR_OWN_FREE;
+ irec.fmr_flags = 0;
+
info->gfi_last = true;
- error = ext4_getfsmap_datadev_helper(sb, end_ag, last_cluster + 1,
- 0, info);
+ error = ext4_getfsmap_helper(sb, info, &irec);
if (error)
goto err;
--
2.49.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 2/2] ext4: Fix reserved gdt blocks handling in fsmap
2025-08-05 8:30 [PATCH 1/2] ext4: Fix fsmap end of range reporting with bigalloc Ojaswin Mujoo
@ 2025-08-05 8:30 ` Ojaswin Mujoo
2025-08-07 19:58 ` Darrick J. Wong
2025-08-07 19:57 ` [PATCH 1/2] ext4: Fix fsmap end of range reporting with bigalloc Darrick J. Wong
2025-08-14 14:48 ` Theodore Ts'o
2 siblings, 1 reply; 5+ messages in thread
From: Ojaswin Mujoo @ 2025-08-05 8:30 UTC (permalink / raw)
To: linux-ext4, Theodore Ts'o
Cc: Ritesh Harjani, Zhang Yi, linux-kernel, Darrick J . Wong,
linux-fsdevel
In some cases like small FSes with no meta_bg and where the resize doesn't
need extra gdt blocks as it can fit in the current one,
s_reserved_gdt_blocks is set as 0, which causes fsmap to emit a 0 length
entry, which is incorrect.
$ mkfs.ext4 -b 65536 -O bigalloc /dev/sda 5G
$ mount /dev/sda /mnt/scratch
$ xfs_io -c "fsmap -d" /mnt/scartch
0: 253:48 [0..127]: static fs metadata 128
1: 253:48 [128..255]: special 102:1 128
2: 253:48 [256..255]: special 102:2 0 <---- 0 len entry
3: 253:48 [256..383]: special 102:3 128
Fix this by adding a check for this case.
Fixes: 0c9ec4beecac ("ext4: support GETFSMAP ioctls")
Signed-off-by: Ojaswin Mujoo <ojaswin@linux.ibm.com>
---
fs/ext4/fsmap.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/fs/ext4/fsmap.c b/fs/ext4/fsmap.c
index 9d63c39f6077..91185c40f755 100644
--- a/fs/ext4/fsmap.c
+++ b/fs/ext4/fsmap.c
@@ -393,6 +393,14 @@ static unsigned int ext4_getfsmap_find_sb(struct super_block *sb,
/* Reserved GDT blocks */
if (!ext4_has_feature_meta_bg(sb) || metagroup < first_meta_bg) {
len = le16_to_cpu(sbi->s_es->s_reserved_gdt_blocks);
+
+ /*
+ * mkfs.ext4 can set s_reserved_gdt_blocks as 0 in some cases,
+ * check for that.
+ */
+ if (!len)
+ return 0;
+
error = ext4_getfsmap_fill(meta_list, fsb, len,
EXT4_FMR_OWN_RESV_GDT);
if (error)
--
2.49.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH 1/2] ext4: Fix fsmap end of range reporting with bigalloc
2025-08-05 8:30 [PATCH 1/2] ext4: Fix fsmap end of range reporting with bigalloc Ojaswin Mujoo
2025-08-05 8:30 ` [PATCH 2/2] ext4: Fix reserved gdt blocks handling in fsmap Ojaswin Mujoo
@ 2025-08-07 19:57 ` Darrick J. Wong
2025-08-14 14:48 ` Theodore Ts'o
2 siblings, 0 replies; 5+ messages in thread
From: Darrick J. Wong @ 2025-08-07 19:57 UTC (permalink / raw)
To: Ojaswin Mujoo
Cc: linux-ext4, Theodore Ts'o, Ritesh Harjani, Zhang Yi,
linux-kernel, linux-fsdevel, Disha Goel
On Tue, Aug 05, 2025 at 02:00:30PM +0530, Ojaswin Mujoo wrote:
> With bigalloc enabled, the logic to report last extent has a bug since
> we try to use cluster units instead of block units. This can cause an issue
> where extra incorrect entries might be returned back to the user. This was
> flagged by generic/365 with 64k bs and -O bigalloc.
>
> ** Details of issue **
>
> The issue was noticed on 5G 64k blocksize FS with -O bigalloc which has
> only 1 bg.
>
> $ xfs_io -c "fsmap -d" /mnt/scratch
>
> 0: 253:48 [0..127]: static fs metadata 128 /* sb */
> 1: 253:48 [128..255]: special 102:1 128 /* gdt */
> 3: 253:48 [256..383]: special 102:3 128 /* block bitmap */
> 4: 253:48 [384..2303]: unknown 1920 /* flex bg empty space */
> 5: 253:48 [2304..2431]: special 102:4 128 /* inode bitmap */
> 6: 253:48 [2432..4351]: unknown 1920 /* flex bg empty space */
> 7: 253:48 [4352..6911]: inodes 2560
> 8: 253:48 [6912..538623]: unknown 531712
> 9: 253:48 [538624..10485759]: free space 9947136
>
> The issue can be seen with:
>
> $ xfs_io -c "fsmap -d 0 3" /mnt/scratch
>
> 0: 253:48 [0..127]: static fs metadata 128
> 1: 253:48 [384..2047]: unknown 1664
>
> Only the first entry was expected to be returned but we get 2. This is
> because:
>
> ext4_getfsmap_datadev()
> first_cluster, last_cluster = 0
> ...
> info->gfi_last = true;
> ext4_getfsmap_datadev_helper(sb, end_ag, last_cluster + 1, 0, info);
> fsb = C2B(1) = 16
> fslen = 0
> ...
> /* Merge in any relevant extents from the meta_list */
> list_for_each_entry_safe(p, tmp, &info->gfi_meta_list, fmr_list) {
> ...
> // since fsb = 16, considers all metadata which starts before 16 blockno
> iter 1: error = ext4_getfsmap_helper(sb, info, p); // p = sb (0,1), nop
> info->gfi_next_fsblk = 1
> iter 2: error = ext4_getfsmap_helper(sb, info, p); // p = gdt (1,2), nop
> info->gfi_next_fsblk = 2
> iter 3: error = ext4_getfsmap_helper(sb, info, p); // p = blk bitmap (2,3), nop
> info->gfi_next_fsblk = 3
> iter 4: error = ext4_getfsmap_helper(sb, info, p); // p = ino bitmap (18,19)
> if (rec_blk > info->gfi_next_fsblk) { // (18 > 3)
> // emits an extra entry ** BUG **
> }
> }
>
> Fix this by directly calling ext4_getfsmap_datadev() with a dummy record
> that has fmr_physical set to (end_fsb + 1) instead of last_cluster + 1. By
> using the block instead of cluster we get the correct behavior.
>
> Replacing ext4_getfsmap_datadev_helper() with ext4_getfsmap_helper() is
> okay since the gfi_lastfree and metadata checks in
> ext4_getfsmap_datadev_helper() are anyways redundant when we only want to
> emit the last allocated block of the range, as we have already taken care
> of emitting metadata and any last free blocks.
>
> Reported-by: Disha Goel <disgoel@linux.ibm.com>
> Fixes: 4a622e4d477b ("ext4: fix FS_IOC_GETFSMAP handling")
> Signed-off-by: Ojaswin Mujoo <ojaswin@linux.ibm.com>
Looks fine to me
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
--D
> ---
> fs/ext4/fsmap.c | 15 ++++++++++++---
> 1 file changed, 12 insertions(+), 3 deletions(-)
>
> diff --git a/fs/ext4/fsmap.c b/fs/ext4/fsmap.c
> index 383c6edea6dd..9d63c39f6077 100644
> --- a/fs/ext4/fsmap.c
> +++ b/fs/ext4/fsmap.c
> @@ -526,6 +526,7 @@ static int ext4_getfsmap_datadev(struct super_block *sb,
> ext4_group_t end_ag;
> ext4_grpblk_t first_cluster;
> ext4_grpblk_t last_cluster;
> + struct ext4_fsmap irec;
> int error = 0;
>
> bofs = le32_to_cpu(sbi->s_es->s_first_data_block);
> @@ -609,10 +610,18 @@ static int ext4_getfsmap_datadev(struct super_block *sb,
> goto err;
> }
>
> - /* Report any gaps at the end of the bg */
> + /*
> + * The dummy record below will cause ext4_getfsmap_helper() to report
> + * any allocated blocks at the end of the range.
> + */
> + irec.fmr_device = 0;
> + irec.fmr_physical = end_fsb + 1;
> + irec.fmr_length = 0;
> + irec.fmr_owner = EXT4_FMR_OWN_FREE;
> + irec.fmr_flags = 0;
> +
> info->gfi_last = true;
> - error = ext4_getfsmap_datadev_helper(sb, end_ag, last_cluster + 1,
> - 0, info);
> + error = ext4_getfsmap_helper(sb, info, &irec);
> if (error)
> goto err;
>
> --
> 2.49.0
>
>
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 2/2] ext4: Fix reserved gdt blocks handling in fsmap
2025-08-05 8:30 ` [PATCH 2/2] ext4: Fix reserved gdt blocks handling in fsmap Ojaswin Mujoo
@ 2025-08-07 19:58 ` Darrick J. Wong
0 siblings, 0 replies; 5+ messages in thread
From: Darrick J. Wong @ 2025-08-07 19:58 UTC (permalink / raw)
To: Ojaswin Mujoo
Cc: linux-ext4, Theodore Ts'o, Ritesh Harjani, Zhang Yi,
linux-kernel, linux-fsdevel
On Tue, Aug 05, 2025 at 02:00:31PM +0530, Ojaswin Mujoo wrote:
> In some cases like small FSes with no meta_bg and where the resize doesn't
> need extra gdt blocks as it can fit in the current one,
> s_reserved_gdt_blocks is set as 0, which causes fsmap to emit a 0 length
> entry, which is incorrect.
>
> $ mkfs.ext4 -b 65536 -O bigalloc /dev/sda 5G
> $ mount /dev/sda /mnt/scratch
> $ xfs_io -c "fsmap -d" /mnt/scartch
>
> 0: 253:48 [0..127]: static fs metadata 128
> 1: 253:48 [128..255]: special 102:1 128
> 2: 253:48 [256..255]: special 102:2 0 <---- 0 len entry
> 3: 253:48 [256..383]: special 102:3 128
>
> Fix this by adding a check for this case.
>
> Fixes: 0c9ec4beecac ("ext4: support GETFSMAP ioctls")
> Signed-off-by: Ojaswin Mujoo <ojaswin@linux.ibm.com>
I had no idea that this could be zero, so....
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
--D
> ---
> fs/ext4/fsmap.c | 8 ++++++++
> 1 file changed, 8 insertions(+)
>
> diff --git a/fs/ext4/fsmap.c b/fs/ext4/fsmap.c
> index 9d63c39f6077..91185c40f755 100644
> --- a/fs/ext4/fsmap.c
> +++ b/fs/ext4/fsmap.c
> @@ -393,6 +393,14 @@ static unsigned int ext4_getfsmap_find_sb(struct super_block *sb,
> /* Reserved GDT blocks */
> if (!ext4_has_feature_meta_bg(sb) || metagroup < first_meta_bg) {
> len = le16_to_cpu(sbi->s_es->s_reserved_gdt_blocks);
> +
> + /*
> + * mkfs.ext4 can set s_reserved_gdt_blocks as 0 in some cases,
> + * check for that.
> + */
> + if (!len)
> + return 0;
> +
> error = ext4_getfsmap_fill(meta_list, fsb, len,
> EXT4_FMR_OWN_RESV_GDT);
> if (error)
> --
> 2.49.0
>
>
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 1/2] ext4: Fix fsmap end of range reporting with bigalloc
2025-08-05 8:30 [PATCH 1/2] ext4: Fix fsmap end of range reporting with bigalloc Ojaswin Mujoo
2025-08-05 8:30 ` [PATCH 2/2] ext4: Fix reserved gdt blocks handling in fsmap Ojaswin Mujoo
2025-08-07 19:57 ` [PATCH 1/2] ext4: Fix fsmap end of range reporting with bigalloc Darrick J. Wong
@ 2025-08-14 14:48 ` Theodore Ts'o
2 siblings, 0 replies; 5+ messages in thread
From: Theodore Ts'o @ 2025-08-14 14:48 UTC (permalink / raw)
To: Ext4 Developers List, Ojaswin Mujoo
Cc: Theodore Ts'o, Ritesh Harjani, Zhang Yi, linux-kernel,
Darrick J . Wong, linux-fsdevel, Disha Goel
On Tue, 05 Aug 2025 14:00:30 +0530, Ojaswin Mujoo wrote:
> With bigalloc enabled, the logic to report last extent has a bug since
> we try to use cluster units instead of block units. This can cause an issue
> where extra incorrect entries might be returned back to the user. This was
> flagged by generic/365 with 64k bs and -O bigalloc.
>
> ** Details of issue **
>
> [...]
Applied, thanks!
[1/2] ext4: Fix fsmap end of range reporting with bigalloc
commit: bae76c035bf0852844151e68098c9b7cd63ef238
[2/2] ext4: Fix reserved gdt blocks handling in fsmap
commit: 3ffbdd1f1165f1b2d6a94d1b1aabef57120deaf7
Best regards,
--
Theodore Ts'o <tytso@mit.edu>
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2025-08-14 14:49 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-08-05 8:30 [PATCH 1/2] ext4: Fix fsmap end of range reporting with bigalloc Ojaswin Mujoo
2025-08-05 8:30 ` [PATCH 2/2] ext4: Fix reserved gdt blocks handling in fsmap Ojaswin Mujoo
2025-08-07 19:58 ` Darrick J. Wong
2025-08-07 19:57 ` [PATCH 1/2] ext4: Fix fsmap end of range reporting with bigalloc Darrick J. Wong
2025-08-14 14:48 ` Theodore Ts'o
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).