* [PATCH v2 1/2] f2fs: zone: fix to calculate first_zoned_segno correctly
@ 2025-03-25 8:06 Chao Yu
2025-03-25 8:06 ` [PATCH v2 2/2] f2fs: zone: fix to avoid inconsistence in between SIT and SSA Chao Yu
` (3 more replies)
0 siblings, 4 replies; 7+ messages in thread
From: Chao Yu @ 2025-03-25 8:06 UTC (permalink / raw)
To: jaegeuk; +Cc: linux-f2fs-devel, linux-kernel, Chao Yu, Daeho Jeong
A zoned device can has both conventional zones and sequential zones,
so we should not treat first segment of zoned device as first_zoned_segno,
instead, we need to check zone type for each zone during traversing zoned
device to find first_zoned_segno.
Otherwise, for below case, first_zoned_segno will be 0, which could be
wrong.
create_null_blk 512 2 1024 1024
mkfs.f2fs -m /dev/nullb0
Fixes: 9703d69d9d15 ("f2fs: support file pinning for zoned devices")
Cc: Daeho Jeong <daehojeong@google.com>
Signed-off-by: Chao Yu <chao@kernel.org>
---
v2:
- traverse w/ zone unit in get_first_zoned_segno()
fs/f2fs/f2fs.h | 18 +++++++++++++-----
fs/f2fs/segment.c | 2 +-
fs/f2fs/super.c | 37 +++++++++++++++++++++++++++++++++----
3 files changed, 47 insertions(+), 10 deletions(-)
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index ca884e39a5ff..3dea037faa55 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -4630,12 +4630,16 @@ F2FS_FEATURE_FUNCS(readonly, RO);
F2FS_FEATURE_FUNCS(device_alias, DEVICE_ALIAS);
#ifdef CONFIG_BLK_DEV_ZONED
-static inline bool f2fs_blkz_is_seq(struct f2fs_sb_info *sbi, int devi,
- block_t blkaddr)
+static inline bool f2fs_zone_is_seq(struct f2fs_sb_info *sbi, int devi,
+ unsigned int zone)
{
- unsigned int zno = blkaddr / sbi->blocks_per_blkz;
+ return test_bit(zone, FDEV(devi).blkz_seq);
+}
- return test_bit(zno, FDEV(devi).blkz_seq);
+static inline bool f2fs_blkz_is_seq(struct f2fs_sb_info *sbi, int devi,
+ block_t blkaddr)
+{
+ return f2fs_zone_is_seq(sbi, devi, blkaddr / sbi->blocks_per_blkz);
}
#endif
@@ -4711,9 +4715,13 @@ static inline bool f2fs_valid_pinned_area(struct f2fs_sb_info *sbi,
block_t blkaddr)
{
if (f2fs_sb_has_blkzoned(sbi)) {
+#ifdef CONFIG_BLK_DEV_ZONED
int devi = f2fs_target_device_index(sbi, blkaddr);
- return !bdev_is_zoned(FDEV(devi).bdev);
+ return !f2fs_blkz_is_seq(sbi, devi, blkaddr);
+#else
+ return true;
+#endif
}
return true;
}
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index 396ef71f41e3..dc360b4b0569 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -3311,7 +3311,7 @@ int f2fs_allocate_pinning_section(struct f2fs_sb_info *sbi)
if (f2fs_sb_has_blkzoned(sbi) && err == -EAGAIN && gc_required) {
f2fs_down_write(&sbi->gc_lock);
- err = f2fs_gc_range(sbi, 0, GET_SEGNO(sbi, FDEV(0).end_blk),
+ err = f2fs_gc_range(sbi, 0, sbi->first_zoned_segno - 1,
true, ZONED_PIN_SEC_REQUIRED_COUNT);
f2fs_up_write(&sbi->gc_lock);
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 011925ee54f8..9a42a1323f42 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -4307,12 +4307,33 @@ static void f2fs_record_error_work(struct work_struct *work)
static inline unsigned int get_first_zoned_segno(struct f2fs_sb_info *sbi)
{
+#ifdef CONFIG_BLK_DEV_ZONED
+ unsigned int zoneno, total_zones;
int devi;
- for (devi = 0; devi < sbi->s_ndevs; devi++)
- if (bdev_is_zoned(FDEV(devi).bdev))
- return GET_SEGNO(sbi, FDEV(devi).start_blk);
- return 0;
+ if (!f2fs_sb_has_blkzoned(sbi))
+ return NULL_SEGNO;
+
+ for (devi = 0; devi < sbi->s_ndevs; devi++) {
+ if (!bdev_is_zoned(FDEV(devi).bdev))
+ continue;
+
+ total_zones = GET_ZONE_FROM_SEG(sbi, FDEV(devi).total_segments);
+
+ for (zoneno = 0; zoneno < total_zones; zoneno++) {
+ unsigned int segs, blks;
+
+ if (!f2fs_zone_is_seq(sbi, devi, zoneno))
+ continue;
+
+ segs = GET_SEG_FROM_SEC(sbi,
+ zoneno * sbi->secs_per_zone);
+ blks = SEGS_TO_BLKS(sbi, segs);
+ return GET_SEGNO(sbi, FDEV(devi).start_blk + blks);
+ }
+ }
+#endif
+ return NULL_SEGNO;
}
static int f2fs_scan_devices(struct f2fs_sb_info *sbi)
@@ -4349,6 +4370,14 @@ static int f2fs_scan_devices(struct f2fs_sb_info *sbi)
#endif
for (i = 0; i < max_devices; i++) {
+ if (max_devices == 1) {
+ FDEV(i).total_segments =
+ le32_to_cpu(raw_super->segment_count_main);
+ FDEV(i).start_blk = 0;
+ FDEV(i).end_blk = FDEV(i).total_segments *
+ BLKS_PER_SEG(sbi);
+ }
+
if (i == 0)
FDEV(0).bdev_file = sbi->sb->s_bdev_file;
else if (!RDEV(i).path[0])
--
2.48.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v2 2/2] f2fs: zone: fix to avoid inconsistence in between SIT and SSA
2025-03-25 8:06 [PATCH v2 1/2] f2fs: zone: fix to calculate first_zoned_segno correctly Chao Yu
@ 2025-03-25 8:06 ` Chao Yu
2025-03-25 22:33 ` [f2fs-dev] [PATCH v2 1/2] f2fs: zone: fix to calculate first_zoned_segno correctly Daeho Jeong
` (2 subsequent siblings)
3 siblings, 0 replies; 7+ messages in thread
From: Chao Yu @ 2025-03-25 8:06 UTC (permalink / raw)
To: jaegeuk; +Cc: linux-f2fs-devel, linux-kernel, Chao Yu, Daeho Jeong
w/ below testcase, it will cause inconsistence in between SIT and SSA.
create_null_blk 512 2 1024 1024
mkfs.f2fs -m /dev/nullb0
mount /dev/nullb0 /mnt/f2fs/
touch /mnt/f2fs/file
f2fs_io pinfile set /mnt/f2fs/file
fallocate -l 4GiB /mnt/f2fs/file
F2FS-fs (nullb0): Inconsistent segment (0) type [1, 0] in SSA and SIT
CPU: 5 UID: 0 PID: 2398 Comm: fallocate Tainted: G O 6.13.0-rc1 #84
Tainted: [O]=OOT_MODULE
Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006
Call Trace:
<TASK>
dump_stack_lvl+0xb3/0xd0
dump_stack+0x14/0x20
f2fs_handle_critical_error+0x18c/0x220 [f2fs]
f2fs_stop_checkpoint+0x38/0x50 [f2fs]
do_garbage_collect+0x674/0x6e0 [f2fs]
f2fs_gc_range+0x12b/0x230 [f2fs]
f2fs_allocate_pinning_section+0x5c/0x150 [f2fs]
f2fs_expand_inode_data+0x1cc/0x3c0 [f2fs]
f2fs_fallocate+0x3c3/0x410 [f2fs]
vfs_fallocate+0x15f/0x4b0
__x64_sys_fallocate+0x4a/0x80
x64_sys_call+0x15e8/0x1b80
do_syscall_64+0x68/0x130
entry_SYSCALL_64_after_hwframe+0x67/0x6f
RIP: 0033:0x7f9dba5197ca
F2FS-fs (nullb0): Stopped filesystem due to reason: 4
The reason is f2fs_gc_range() may try to migrate block in curseg, however,
its SSA block is not uptodate due to the last summary block data is still
in cache of curseg.
In this patch, we add a condition in f2fs_gc_range() to check whether
section is opened or not, and skip block migration for opened section.
Fixes: 9703d69d9d15 ("f2fs: support file pinning for zoned devices")
Reviewed-by: Daeho Jeong <daehojeong@google.com>
Cc: Daeho Jeong <daehojeong@google.com>
Signed-off-by: Chao Yu <chao@kernel.org>
---
v2:
- add rvb tag from Daeho
fs/f2fs/gc.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
index 2b8f9239bede..8b5a55b72264 100644
--- a/fs/f2fs/gc.c
+++ b/fs/f2fs/gc.c
@@ -2066,6 +2066,9 @@ int f2fs_gc_range(struct f2fs_sb_info *sbi,
.iroot = RADIX_TREE_INIT(gc_list.iroot, GFP_NOFS),
};
+ if (IS_CURSEC(sbi, GET_SEC_FROM_SEG(sbi, segno)))
+ continue;
+
do_garbage_collect(sbi, segno, &gc_list, FG_GC, true, false);
put_gc_inode(&gc_list);
--
2.48.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [f2fs-dev] [PATCH v2 1/2] f2fs: zone: fix to calculate first_zoned_segno correctly
2025-03-25 8:06 [PATCH v2 1/2] f2fs: zone: fix to calculate first_zoned_segno correctly Chao Yu
2025-03-25 8:06 ` [PATCH v2 2/2] f2fs: zone: fix to avoid inconsistence in between SIT and SSA Chao Yu
@ 2025-03-25 22:33 ` Daeho Jeong
2025-03-28 3:29 ` Jaegeuk Kim
2025-04-10 4:10 ` [f2fs-dev] " patchwork-bot+f2fs
3 siblings, 0 replies; 7+ messages in thread
From: Daeho Jeong @ 2025-03-25 22:33 UTC (permalink / raw)
To: Chao Yu; +Cc: jaegeuk, Daeho Jeong, linux-kernel, linux-f2fs-devel
On Tue, Mar 25, 2025 at 1:09 AM Chao Yu via Linux-f2fs-devel
<linux-f2fs-devel@lists.sourceforge.net> wrote:
>
> A zoned device can has both conventional zones and sequential zones,
> so we should not treat first segment of zoned device as first_zoned_segno,
> instead, we need to check zone type for each zone during traversing zoned
> device to find first_zoned_segno.
>
> Otherwise, for below case, first_zoned_segno will be 0, which could be
> wrong.
>
> create_null_blk 512 2 1024 1024
> mkfs.f2fs -m /dev/nullb0
>
> Fixes: 9703d69d9d15 ("f2fs: support file pinning for zoned devices")
> Cc: Daeho Jeong <daehojeong@google.com>
> Signed-off-by: Chao Yu <chao@kernel.org>
> ---
> v2:
> - traverse w/ zone unit in get_first_zoned_segno()
> fs/f2fs/f2fs.h | 18 +++++++++++++-----
> fs/f2fs/segment.c | 2 +-
> fs/f2fs/super.c | 37 +++++++++++++++++++++++++++++++++----
> 3 files changed, 47 insertions(+), 10 deletions(-)
>
> diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
> index ca884e39a5ff..3dea037faa55 100644
> --- a/fs/f2fs/f2fs.h
> +++ b/fs/f2fs/f2fs.h
> @@ -4630,12 +4630,16 @@ F2FS_FEATURE_FUNCS(readonly, RO);
> F2FS_FEATURE_FUNCS(device_alias, DEVICE_ALIAS);
>
> #ifdef CONFIG_BLK_DEV_ZONED
> -static inline bool f2fs_blkz_is_seq(struct f2fs_sb_info *sbi, int devi,
> - block_t blkaddr)
> +static inline bool f2fs_zone_is_seq(struct f2fs_sb_info *sbi, int devi,
> + unsigned int zone)
> {
> - unsigned int zno = blkaddr / sbi->blocks_per_blkz;
> + return test_bit(zone, FDEV(devi).blkz_seq);
> +}
>
> - return test_bit(zno, FDEV(devi).blkz_seq);
> +static inline bool f2fs_blkz_is_seq(struct f2fs_sb_info *sbi, int devi,
> + block_t blkaddr)
> +{
> + return f2fs_zone_is_seq(sbi, devi, blkaddr / sbi->blocks_per_blkz);
> }
> #endif
>
> @@ -4711,9 +4715,13 @@ static inline bool f2fs_valid_pinned_area(struct f2fs_sb_info *sbi,
> block_t blkaddr)
> {
> if (f2fs_sb_has_blkzoned(sbi)) {
> +#ifdef CONFIG_BLK_DEV_ZONED
> int devi = f2fs_target_device_index(sbi, blkaddr);
>
> - return !bdev_is_zoned(FDEV(devi).bdev);
> + return !f2fs_blkz_is_seq(sbi, devi, blkaddr);
> +#else
> + return true;
> +#endif
> }
> return true;
> }
> diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
> index 396ef71f41e3..dc360b4b0569 100644
> --- a/fs/f2fs/segment.c
> +++ b/fs/f2fs/segment.c
> @@ -3311,7 +3311,7 @@ int f2fs_allocate_pinning_section(struct f2fs_sb_info *sbi)
>
> if (f2fs_sb_has_blkzoned(sbi) && err == -EAGAIN && gc_required) {
> f2fs_down_write(&sbi->gc_lock);
> - err = f2fs_gc_range(sbi, 0, GET_SEGNO(sbi, FDEV(0).end_blk),
> + err = f2fs_gc_range(sbi, 0, sbi->first_zoned_segno - 1,
> true, ZONED_PIN_SEC_REQUIRED_COUNT);
> f2fs_up_write(&sbi->gc_lock);
>
> diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
> index 011925ee54f8..9a42a1323f42 100644
> --- a/fs/f2fs/super.c
> +++ b/fs/f2fs/super.c
> @@ -4307,12 +4307,33 @@ static void f2fs_record_error_work(struct work_struct *work)
>
> static inline unsigned int get_first_zoned_segno(struct f2fs_sb_info *sbi)
> {
> +#ifdef CONFIG_BLK_DEV_ZONED
> + unsigned int zoneno, total_zones;
> int devi;
>
> - for (devi = 0; devi < sbi->s_ndevs; devi++)
> - if (bdev_is_zoned(FDEV(devi).bdev))
> - return GET_SEGNO(sbi, FDEV(devi).start_blk);
> - return 0;
> + if (!f2fs_sb_has_blkzoned(sbi))
> + return NULL_SEGNO;
> +
> + for (devi = 0; devi < sbi->s_ndevs; devi++) {
> + if (!bdev_is_zoned(FDEV(devi).bdev))
> + continue;
> +
> + total_zones = GET_ZONE_FROM_SEG(sbi, FDEV(devi).total_segments);
> +
> + for (zoneno = 0; zoneno < total_zones; zoneno++) {
> + unsigned int segs, blks;
> +
> + if (!f2fs_zone_is_seq(sbi, devi, zoneno))
> + continue;
> +
> + segs = GET_SEG_FROM_SEC(sbi,
> + zoneno * sbi->secs_per_zone);
> + blks = SEGS_TO_BLKS(sbi, segs);
> + return GET_SEGNO(sbi, FDEV(devi).start_blk + blks);
> + }
> + }
> +#endif
> + return NULL_SEGNO;
> }
>
> static int f2fs_scan_devices(struct f2fs_sb_info *sbi)
> @@ -4349,6 +4370,14 @@ static int f2fs_scan_devices(struct f2fs_sb_info *sbi)
> #endif
>
> for (i = 0; i < max_devices; i++) {
> + if (max_devices == 1) {
> + FDEV(i).total_segments =
> + le32_to_cpu(raw_super->segment_count_main);
> + FDEV(i).start_blk = 0;
> + FDEV(i).end_blk = FDEV(i).total_segments *
> + BLKS_PER_SEG(sbi);
> + }
> +
> if (i == 0)
> FDEV(0).bdev_file = sbi->sb->s_bdev_file;
> else if (!RDEV(i).path[0])
> --
> 2.48.1
>
Reviewed-by: Daeho Jeong <daehojeong@google.com>
Thanks.
>
>
> _______________________________________________
> Linux-f2fs-devel mailing list
> Linux-f2fs-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2 1/2] f2fs: zone: fix to calculate first_zoned_segno correctly
2025-03-25 8:06 [PATCH v2 1/2] f2fs: zone: fix to calculate first_zoned_segno correctly Chao Yu
2025-03-25 8:06 ` [PATCH v2 2/2] f2fs: zone: fix to avoid inconsistence in between SIT and SSA Chao Yu
2025-03-25 22:33 ` [f2fs-dev] [PATCH v2 1/2] f2fs: zone: fix to calculate first_zoned_segno correctly Daeho Jeong
@ 2025-03-28 3:29 ` Jaegeuk Kim
2025-03-28 4:02 ` Chao Yu
2025-03-31 5:41 ` Chao Yu
2025-04-10 4:10 ` [f2fs-dev] " patchwork-bot+f2fs
3 siblings, 2 replies; 7+ messages in thread
From: Jaegeuk Kim @ 2025-03-28 3:29 UTC (permalink / raw)
To: Chao Yu; +Cc: linux-f2fs-devel, linux-kernel, Daeho Jeong
It seems this patch breaks the multi-partition cases.
On 03/25, Chao Yu wrote:
> A zoned device can has both conventional zones and sequential zones,
> so we should not treat first segment of zoned device as first_zoned_segno,
> instead, we need to check zone type for each zone during traversing zoned
> device to find first_zoned_segno.
>
> Otherwise, for below case, first_zoned_segno will be 0, which could be
> wrong.
>
> create_null_blk 512 2 1024 1024
> mkfs.f2fs -m /dev/nullb0
>
> Fixes: 9703d69d9d15 ("f2fs: support file pinning for zoned devices")
> Cc: Daeho Jeong <daehojeong@google.com>
> Signed-off-by: Chao Yu <chao@kernel.org>
> ---
> v2:
> - traverse w/ zone unit in get_first_zoned_segno()
> fs/f2fs/f2fs.h | 18 +++++++++++++-----
> fs/f2fs/segment.c | 2 +-
> fs/f2fs/super.c | 37 +++++++++++++++++++++++++++++++++----
> 3 files changed, 47 insertions(+), 10 deletions(-)
>
> diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
> index ca884e39a5ff..3dea037faa55 100644
> --- a/fs/f2fs/f2fs.h
> +++ b/fs/f2fs/f2fs.h
> @@ -4630,12 +4630,16 @@ F2FS_FEATURE_FUNCS(readonly, RO);
> F2FS_FEATURE_FUNCS(device_alias, DEVICE_ALIAS);
>
> #ifdef CONFIG_BLK_DEV_ZONED
> -static inline bool f2fs_blkz_is_seq(struct f2fs_sb_info *sbi, int devi,
> - block_t blkaddr)
> +static inline bool f2fs_zone_is_seq(struct f2fs_sb_info *sbi, int devi,
> + unsigned int zone)
> {
> - unsigned int zno = blkaddr / sbi->blocks_per_blkz;
> + return test_bit(zone, FDEV(devi).blkz_seq);
> +}
>
> - return test_bit(zno, FDEV(devi).blkz_seq);
> +static inline bool f2fs_blkz_is_seq(struct f2fs_sb_info *sbi, int devi,
> + block_t blkaddr)
> +{
> + return f2fs_zone_is_seq(sbi, devi, blkaddr / sbi->blocks_per_blkz);
> }
> #endif
>
> @@ -4711,9 +4715,13 @@ static inline bool f2fs_valid_pinned_area(struct f2fs_sb_info *sbi,
> block_t blkaddr)
> {
> if (f2fs_sb_has_blkzoned(sbi)) {
> +#ifdef CONFIG_BLK_DEV_ZONED
> int devi = f2fs_target_device_index(sbi, blkaddr);
>
> - return !bdev_is_zoned(FDEV(devi).bdev);
> + return !f2fs_blkz_is_seq(sbi, devi, blkaddr);
> +#else
> + return true;
> +#endif
> }
> return true;
> }
> diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
> index 396ef71f41e3..dc360b4b0569 100644
> --- a/fs/f2fs/segment.c
> +++ b/fs/f2fs/segment.c
> @@ -3311,7 +3311,7 @@ int f2fs_allocate_pinning_section(struct f2fs_sb_info *sbi)
>
> if (f2fs_sb_has_blkzoned(sbi) && err == -EAGAIN && gc_required) {
> f2fs_down_write(&sbi->gc_lock);
> - err = f2fs_gc_range(sbi, 0, GET_SEGNO(sbi, FDEV(0).end_blk),
> + err = f2fs_gc_range(sbi, 0, sbi->first_zoned_segno - 1,
> true, ZONED_PIN_SEC_REQUIRED_COUNT);
> f2fs_up_write(&sbi->gc_lock);
>
> diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
> index 011925ee54f8..9a42a1323f42 100644
> --- a/fs/f2fs/super.c
> +++ b/fs/f2fs/super.c
> @@ -4307,12 +4307,33 @@ static void f2fs_record_error_work(struct work_struct *work)
>
> static inline unsigned int get_first_zoned_segno(struct f2fs_sb_info *sbi)
> {
> +#ifdef CONFIG_BLK_DEV_ZONED
> + unsigned int zoneno, total_zones;
> int devi;
>
> - for (devi = 0; devi < sbi->s_ndevs; devi++)
> - if (bdev_is_zoned(FDEV(devi).bdev))
> - return GET_SEGNO(sbi, FDEV(devi).start_blk);
> - return 0;
> + if (!f2fs_sb_has_blkzoned(sbi))
> + return NULL_SEGNO;
> +
> + for (devi = 0; devi < sbi->s_ndevs; devi++) {
> + if (!bdev_is_zoned(FDEV(devi).bdev))
> + continue;
> +
> + total_zones = GET_ZONE_FROM_SEG(sbi, FDEV(devi).total_segments);
> +
> + for (zoneno = 0; zoneno < total_zones; zoneno++) {
> + unsigned int segs, blks;
> +
> + if (!f2fs_zone_is_seq(sbi, devi, zoneno))
> + continue;
> +
> + segs = GET_SEG_FROM_SEC(sbi,
> + zoneno * sbi->secs_per_zone);
> + blks = SEGS_TO_BLKS(sbi, segs);
> + return GET_SEGNO(sbi, FDEV(devi).start_blk + blks);
> + }
> + }
> +#endif
> + return NULL_SEGNO;
> }
>
> static int f2fs_scan_devices(struct f2fs_sb_info *sbi)
> @@ -4349,6 +4370,14 @@ static int f2fs_scan_devices(struct f2fs_sb_info *sbi)
> #endif
>
> for (i = 0; i < max_devices; i++) {
> + if (max_devices == 1) {
> + FDEV(i).total_segments =
> + le32_to_cpu(raw_super->segment_count_main);
> + FDEV(i).start_blk = 0;
> + FDEV(i).end_blk = FDEV(i).total_segments *
> + BLKS_PER_SEG(sbi);
> + }
> +
> if (i == 0)
> FDEV(0).bdev_file = sbi->sb->s_bdev_file;
> else if (!RDEV(i).path[0])
> --
> 2.48.1
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2 1/2] f2fs: zone: fix to calculate first_zoned_segno correctly
2025-03-28 3:29 ` Jaegeuk Kim
@ 2025-03-28 4:02 ` Chao Yu
2025-03-31 5:41 ` Chao Yu
1 sibling, 0 replies; 7+ messages in thread
From: Chao Yu @ 2025-03-28 4:02 UTC (permalink / raw)
To: Jaegeuk Kim; +Cc: chao, linux-f2fs-devel, linux-kernel, Daeho Jeong
On 2025/3/28 11:29, Jaegeuk Kim wrote:
> It seems this patch breaks the multi-partition cases.
Let me take a look.
Thanks,
>
> On 03/25, Chao Yu wrote:
>> A zoned device can has both conventional zones and sequential zones,
>> so we should not treat first segment of zoned device as first_zoned_segno,
>> instead, we need to check zone type for each zone during traversing zoned
>> device to find first_zoned_segno.
>>
>> Otherwise, for below case, first_zoned_segno will be 0, which could be
>> wrong.
>>
>> create_null_blk 512 2 1024 1024
>> mkfs.f2fs -m /dev/nullb0
>>
>> Fixes: 9703d69d9d15 ("f2fs: support file pinning for zoned devices")
>> Cc: Daeho Jeong <daehojeong@google.com>
>> Signed-off-by: Chao Yu <chao@kernel.org>
>> ---
>> v2:
>> - traverse w/ zone unit in get_first_zoned_segno()
>> fs/f2fs/f2fs.h | 18 +++++++++++++-----
>> fs/f2fs/segment.c | 2 +-
>> fs/f2fs/super.c | 37 +++++++++++++++++++++++++++++++++----
>> 3 files changed, 47 insertions(+), 10 deletions(-)
>>
>> diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
>> index ca884e39a5ff..3dea037faa55 100644
>> --- a/fs/f2fs/f2fs.h
>> +++ b/fs/f2fs/f2fs.h
>> @@ -4630,12 +4630,16 @@ F2FS_FEATURE_FUNCS(readonly, RO);
>> F2FS_FEATURE_FUNCS(device_alias, DEVICE_ALIAS);
>>
>> #ifdef CONFIG_BLK_DEV_ZONED
>> -static inline bool f2fs_blkz_is_seq(struct f2fs_sb_info *sbi, int devi,
>> - block_t blkaddr)
>> +static inline bool f2fs_zone_is_seq(struct f2fs_sb_info *sbi, int devi,
>> + unsigned int zone)
>> {
>> - unsigned int zno = blkaddr / sbi->blocks_per_blkz;
>> + return test_bit(zone, FDEV(devi).blkz_seq);
>> +}
>>
>> - return test_bit(zno, FDEV(devi).blkz_seq);
>> +static inline bool f2fs_blkz_is_seq(struct f2fs_sb_info *sbi, int devi,
>> + block_t blkaddr)
>> +{
>> + return f2fs_zone_is_seq(sbi, devi, blkaddr / sbi->blocks_per_blkz);
>> }
>> #endif
>>
>> @@ -4711,9 +4715,13 @@ static inline bool f2fs_valid_pinned_area(struct f2fs_sb_info *sbi,
>> block_t blkaddr)
>> {
>> if (f2fs_sb_has_blkzoned(sbi)) {
>> +#ifdef CONFIG_BLK_DEV_ZONED
>> int devi = f2fs_target_device_index(sbi, blkaddr);
>>
>> - return !bdev_is_zoned(FDEV(devi).bdev);
>> + return !f2fs_blkz_is_seq(sbi, devi, blkaddr);
>> +#else
>> + return true;
>> +#endif
>> }
>> return true;
>> }
>> diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
>> index 396ef71f41e3..dc360b4b0569 100644
>> --- a/fs/f2fs/segment.c
>> +++ b/fs/f2fs/segment.c
>> @@ -3311,7 +3311,7 @@ int f2fs_allocate_pinning_section(struct f2fs_sb_info *sbi)
>>
>> if (f2fs_sb_has_blkzoned(sbi) && err == -EAGAIN && gc_required) {
>> f2fs_down_write(&sbi->gc_lock);
>> - err = f2fs_gc_range(sbi, 0, GET_SEGNO(sbi, FDEV(0).end_blk),
>> + err = f2fs_gc_range(sbi, 0, sbi->first_zoned_segno - 1,
>> true, ZONED_PIN_SEC_REQUIRED_COUNT);
>> f2fs_up_write(&sbi->gc_lock);
>>
>> diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
>> index 011925ee54f8..9a42a1323f42 100644
>> --- a/fs/f2fs/super.c
>> +++ b/fs/f2fs/super.c
>> @@ -4307,12 +4307,33 @@ static void f2fs_record_error_work(struct work_struct *work)
>>
>> static inline unsigned int get_first_zoned_segno(struct f2fs_sb_info *sbi)
>> {
>> +#ifdef CONFIG_BLK_DEV_ZONED
>> + unsigned int zoneno, total_zones;
>> int devi;
>>
>> - for (devi = 0; devi < sbi->s_ndevs; devi++)
>> - if (bdev_is_zoned(FDEV(devi).bdev))
>> - return GET_SEGNO(sbi, FDEV(devi).start_blk);
>> - return 0;
>> + if (!f2fs_sb_has_blkzoned(sbi))
>> + return NULL_SEGNO;
>> +
>> + for (devi = 0; devi < sbi->s_ndevs; devi++) {
>> + if (!bdev_is_zoned(FDEV(devi).bdev))
>> + continue;
>> +
>> + total_zones = GET_ZONE_FROM_SEG(sbi, FDEV(devi).total_segments);
>> +
>> + for (zoneno = 0; zoneno < total_zones; zoneno++) {
>> + unsigned int segs, blks;
>> +
>> + if (!f2fs_zone_is_seq(sbi, devi, zoneno))
>> + continue;
>> +
>> + segs = GET_SEG_FROM_SEC(sbi,
>> + zoneno * sbi->secs_per_zone);
>> + blks = SEGS_TO_BLKS(sbi, segs);
>> + return GET_SEGNO(sbi, FDEV(devi).start_blk + blks);
>> + }
>> + }
>> +#endif
>> + return NULL_SEGNO;
>> }
>>
>> static int f2fs_scan_devices(struct f2fs_sb_info *sbi)
>> @@ -4349,6 +4370,14 @@ static int f2fs_scan_devices(struct f2fs_sb_info *sbi)
>> #endif
>>
>> for (i = 0; i < max_devices; i++) {
>> + if (max_devices == 1) {
>> + FDEV(i).total_segments =
>> + le32_to_cpu(raw_super->segment_count_main);
>> + FDEV(i).start_blk = 0;
>> + FDEV(i).end_blk = FDEV(i).total_segments *
>> + BLKS_PER_SEG(sbi);
>> + }
>> +
>> if (i == 0)
>> FDEV(0).bdev_file = sbi->sb->s_bdev_file;
>> else if (!RDEV(i).path[0])
>> --
>> 2.48.1
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2 1/2] f2fs: zone: fix to calculate first_zoned_segno correctly
2025-03-28 3:29 ` Jaegeuk Kim
2025-03-28 4:02 ` Chao Yu
@ 2025-03-31 5:41 ` Chao Yu
1 sibling, 0 replies; 7+ messages in thread
From: Chao Yu @ 2025-03-31 5:41 UTC (permalink / raw)
To: Jaegeuk Kim; +Cc: chao, linux-f2fs-devel, linux-kernel, Daeho Jeong
On 3/28/25 11:29, Jaegeuk Kim wrote:
> It seems this patch breaks the multi-partition cases.
Which case did you test w/ this patch?
Thanks,
>
> On 03/25, Chao Yu wrote:
>> A zoned device can has both conventional zones and sequential zones,
>> so we should not treat first segment of zoned device as first_zoned_segno,
>> instead, we need to check zone type for each zone during traversing zoned
>> device to find first_zoned_segno.
>>
>> Otherwise, for below case, first_zoned_segno will be 0, which could be
>> wrong.
>>
>> create_null_blk 512 2 1024 1024
>> mkfs.f2fs -m /dev/nullb0
>>
>> Fixes: 9703d69d9d15 ("f2fs: support file pinning for zoned devices")
>> Cc: Daeho Jeong <daehojeong@google.com>
>> Signed-off-by: Chao Yu <chao@kernel.org>
>> ---
>> v2:
>> - traverse w/ zone unit in get_first_zoned_segno()
>> fs/f2fs/f2fs.h | 18 +++++++++++++-----
>> fs/f2fs/segment.c | 2 +-
>> fs/f2fs/super.c | 37 +++++++++++++++++++++++++++++++++----
>> 3 files changed, 47 insertions(+), 10 deletions(-)
>>
>> diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
>> index ca884e39a5ff..3dea037faa55 100644
>> --- a/fs/f2fs/f2fs.h
>> +++ b/fs/f2fs/f2fs.h
>> @@ -4630,12 +4630,16 @@ F2FS_FEATURE_FUNCS(readonly, RO);
>> F2FS_FEATURE_FUNCS(device_alias, DEVICE_ALIAS);
>>
>> #ifdef CONFIG_BLK_DEV_ZONED
>> -static inline bool f2fs_blkz_is_seq(struct f2fs_sb_info *sbi, int devi,
>> - block_t blkaddr)
>> +static inline bool f2fs_zone_is_seq(struct f2fs_sb_info *sbi, int devi,
>> + unsigned int zone)
>> {
>> - unsigned int zno = blkaddr / sbi->blocks_per_blkz;
>> + return test_bit(zone, FDEV(devi).blkz_seq);
>> +}
>>
>> - return test_bit(zno, FDEV(devi).blkz_seq);
>> +static inline bool f2fs_blkz_is_seq(struct f2fs_sb_info *sbi, int devi,
>> + block_t blkaddr)
>> +{
>> + return f2fs_zone_is_seq(sbi, devi, blkaddr / sbi->blocks_per_blkz);
>> }
>> #endif
>>
>> @@ -4711,9 +4715,13 @@ static inline bool f2fs_valid_pinned_area(struct f2fs_sb_info *sbi,
>> block_t blkaddr)
>> {
>> if (f2fs_sb_has_blkzoned(sbi)) {
>> +#ifdef CONFIG_BLK_DEV_ZONED
>> int devi = f2fs_target_device_index(sbi, blkaddr);
>>
>> - return !bdev_is_zoned(FDEV(devi).bdev);
>> + return !f2fs_blkz_is_seq(sbi, devi, blkaddr);
>> +#else
>> + return true;
>> +#endif
>> }
>> return true;
>> }
>> diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
>> index 396ef71f41e3..dc360b4b0569 100644
>> --- a/fs/f2fs/segment.c
>> +++ b/fs/f2fs/segment.c
>> @@ -3311,7 +3311,7 @@ int f2fs_allocate_pinning_section(struct f2fs_sb_info *sbi)
>>
>> if (f2fs_sb_has_blkzoned(sbi) && err == -EAGAIN && gc_required) {
>> f2fs_down_write(&sbi->gc_lock);
>> - err = f2fs_gc_range(sbi, 0, GET_SEGNO(sbi, FDEV(0).end_blk),
>> + err = f2fs_gc_range(sbi, 0, sbi->first_zoned_segno - 1,
>> true, ZONED_PIN_SEC_REQUIRED_COUNT);
>> f2fs_up_write(&sbi->gc_lock);
>>
>> diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
>> index 011925ee54f8..9a42a1323f42 100644
>> --- a/fs/f2fs/super.c
>> +++ b/fs/f2fs/super.c
>> @@ -4307,12 +4307,33 @@ static void f2fs_record_error_work(struct work_struct *work)
>>
>> static inline unsigned int get_first_zoned_segno(struct f2fs_sb_info *sbi)
>> {
>> +#ifdef CONFIG_BLK_DEV_ZONED
>> + unsigned int zoneno, total_zones;
>> int devi;
>>
>> - for (devi = 0; devi < sbi->s_ndevs; devi++)
>> - if (bdev_is_zoned(FDEV(devi).bdev))
>> - return GET_SEGNO(sbi, FDEV(devi).start_blk);
>> - return 0;
>> + if (!f2fs_sb_has_blkzoned(sbi))
>> + return NULL_SEGNO;
>> +
>> + for (devi = 0; devi < sbi->s_ndevs; devi++) {
>> + if (!bdev_is_zoned(FDEV(devi).bdev))
>> + continue;
>> +
>> + total_zones = GET_ZONE_FROM_SEG(sbi, FDEV(devi).total_segments);
>> +
>> + for (zoneno = 0; zoneno < total_zones; zoneno++) {
>> + unsigned int segs, blks;
>> +
>> + if (!f2fs_zone_is_seq(sbi, devi, zoneno))
>> + continue;
>> +
>> + segs = GET_SEG_FROM_SEC(sbi,
>> + zoneno * sbi->secs_per_zone);
>> + blks = SEGS_TO_BLKS(sbi, segs);
>> + return GET_SEGNO(sbi, FDEV(devi).start_blk + blks);
>> + }
>> + }
>> +#endif
>> + return NULL_SEGNO;
>> }
>>
>> static int f2fs_scan_devices(struct f2fs_sb_info *sbi)
>> @@ -4349,6 +4370,14 @@ static int f2fs_scan_devices(struct f2fs_sb_info *sbi)
>> #endif
>>
>> for (i = 0; i < max_devices; i++) {
>> + if (max_devices == 1) {
>> + FDEV(i).total_segments =
>> + le32_to_cpu(raw_super->segment_count_main);
>> + FDEV(i).start_blk = 0;
>> + FDEV(i).end_blk = FDEV(i).total_segments *
>> + BLKS_PER_SEG(sbi);
>> + }
>> +
>> if (i == 0)
>> FDEV(0).bdev_file = sbi->sb->s_bdev_file;
>> else if (!RDEV(i).path[0])
>> --
>> 2.48.1
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [f2fs-dev] [PATCH v2 1/2] f2fs: zone: fix to calculate first_zoned_segno correctly
2025-03-25 8:06 [PATCH v2 1/2] f2fs: zone: fix to calculate first_zoned_segno correctly Chao Yu
` (2 preceding siblings ...)
2025-03-28 3:29 ` Jaegeuk Kim
@ 2025-04-10 4:10 ` patchwork-bot+f2fs
3 siblings, 0 replies; 7+ messages in thread
From: patchwork-bot+f2fs @ 2025-04-10 4:10 UTC (permalink / raw)
To: Chao Yu; +Cc: jaegeuk, daehojeong, linux-kernel, linux-f2fs-devel
Hello:
This series was applied to jaegeuk/f2fs.git (dev)
by Jaegeuk Kim <jaegeuk@kernel.org>:
On Tue, 25 Mar 2025 16:06:45 +0800 you wrote:
> A zoned device can has both conventional zones and sequential zones,
> so we should not treat first segment of zoned device as first_zoned_segno,
> instead, we need to check zone type for each zone during traversing zoned
> device to find first_zoned_segno.
>
> Otherwise, for below case, first_zoned_segno will be 0, which could be
> wrong.
>
> [...]
Here is the summary with links:
- [f2fs-dev,v2,1/2] f2fs: zone: fix to calculate first_zoned_segno correctly
(no matching commit)
- [f2fs-dev,v2,2/2] f2fs: zone: fix to avoid inconsistence in between SIT and SSA
https://git.kernel.org/jaegeuk/f2fs/c/773704c1ef96
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2025-04-10 4:10 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-03-25 8:06 [PATCH v2 1/2] f2fs: zone: fix to calculate first_zoned_segno correctly Chao Yu
2025-03-25 8:06 ` [PATCH v2 2/2] f2fs: zone: fix to avoid inconsistence in between SIT and SSA Chao Yu
2025-03-25 22:33 ` [f2fs-dev] [PATCH v2 1/2] f2fs: zone: fix to calculate first_zoned_segno correctly Daeho Jeong
2025-03-28 3:29 ` Jaegeuk Kim
2025-03-28 4:02 ` Chao Yu
2025-03-31 5:41 ` Chao Yu
2025-04-10 4:10 ` [f2fs-dev] " patchwork-bot+f2fs
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox