Message ID | 20240328072136.3023135-1-chao@kernel.org (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | [f2fs-dev,v6] f2fs: fix zoned block device information initialization | expand |
On Thu, Mar 28, 2024 at 12:23 AM Chao Yu <chao@kernel.org> wrote: > > From: Wenjie Qi <qwjhust@gmail.com> > > If the max open zones of zoned devices are less than > the active logs of F2FS, the device may error due to > insufficient zone resources when multiple active logs > are being written at the same time. > > Signed-off-by: Wenjie Qi <qwjhust@gmail.com> > Signed-off-by: Chao Yu <chao@kernel.org> > --- > v6: > - add check condition to avoid remount failure. > fs/f2fs/f2fs.h | 1 + > fs/f2fs/super.c | 27 +++++++++++++++++++++++++++ > 2 files changed, 28 insertions(+) > > diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h > index 0550929dc6e5..694f8a52cb84 100644 > --- a/fs/f2fs/f2fs.h > +++ b/fs/f2fs/f2fs.h > @@ -1559,6 +1559,7 @@ struct f2fs_sb_info { > > #ifdef CONFIG_BLK_DEV_ZONED > unsigned int blocks_per_blkz; /* F2FS blocks per zone */ > + unsigned int max_open_zones; /* max open zone resources of the zoned device */ > #endif > > /* for node-related operations */ > diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c > index 7c45929671ad..642540782471 100644 > --- a/fs/f2fs/super.c > +++ b/fs/f2fs/super.c > @@ -2326,6 +2326,17 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data) > if (err) > goto restore_opts; > > +#ifdef CONFIG_BLK_DEV_ZONED > + if (f2fs_is_multi_device(sbi) && Why do we check multiple devices' condition here? Thanks, > + sbi->max_open_zones < F2FS_OPTION(sbi).active_logs) { > + f2fs_err(sbi, > + "zoned: max open zones %u is too small, need at least %u open zones", > + sbi->max_open_zones, F2FS_OPTION(sbi).active_logs); > + err = -EINVAL; > + goto restore_opts; > + } > +#endif > + > /* flush outstanding errors before changing fs state */ > flush_work(&sbi->s_error_work); > > @@ -3868,11 +3879,24 @@ static int init_blkz_info(struct f2fs_sb_info *sbi, int devi) > sector_t nr_sectors = bdev_nr_sectors(bdev); > struct f2fs_report_zones_args rep_zone_arg; > u64 zone_sectors; > + unsigned int max_open_zones; > int ret; > > if (!f2fs_sb_has_blkzoned(sbi)) > return 0; > > + if (bdev_is_zoned(FDEV(devi).bdev)) { > + max_open_zones = bdev_max_open_zones(bdev); > + if (max_open_zones && (max_open_zones < sbi->max_open_zones)) > + sbi->max_open_zones = max_open_zones; > + if (sbi->max_open_zones < F2FS_OPTION(sbi).active_logs) { > + f2fs_err(sbi, > + "zoned: max open zones %u is too small, need at least %u open zones", > + sbi->max_open_zones, F2FS_OPTION(sbi).active_logs); > + return -EINVAL; > + } > + } > + > zone_sectors = bdev_zone_sectors(bdev); > if (sbi->blocks_per_blkz && sbi->blocks_per_blkz != > SECTOR_TO_BLOCK(zone_sectors)) > @@ -4186,6 +4210,9 @@ static int f2fs_scan_devices(struct f2fs_sb_info *sbi) > > logical_blksize = bdev_logical_block_size(sbi->sb->s_bdev); > sbi->aligned_blksize = true; > +#ifdef CONFIG_BLK_DEV_ZONED > + sbi->max_open_zones = UINT_MAX; > +#endif > > for (i = 0; i < max_devices; i++) { > if (i == 0) > -- > 2.40.1 > > > > _______________________________________________ > Linux-f2fs-devel mailing list > Linux-f2fs-devel@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
On 2024/4/5 2:20, Daeho Jeong wrote: > On Thu, Mar 28, 2024 at 12:23 AM Chao Yu <chao@kernel.org> wrote: >> >> From: Wenjie Qi <qwjhust@gmail.com> >> >> If the max open zones of zoned devices are less than >> the active logs of F2FS, the device may error due to >> insufficient zone resources when multiple active logs >> are being written at the same time. >> >> Signed-off-by: Wenjie Qi <qwjhust@gmail.com> >> Signed-off-by: Chao Yu <chao@kernel.org> >> --- >> v6: >> - add check condition to avoid remount failure. >> fs/f2fs/f2fs.h | 1 + >> fs/f2fs/super.c | 27 +++++++++++++++++++++++++++ >> 2 files changed, 28 insertions(+) >> >> diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h >> index 0550929dc6e5..694f8a52cb84 100644 >> --- a/fs/f2fs/f2fs.h >> +++ b/fs/f2fs/f2fs.h >> @@ -1559,6 +1559,7 @@ struct f2fs_sb_info { >> >> #ifdef CONFIG_BLK_DEV_ZONED >> unsigned int blocks_per_blkz; /* F2FS blocks per zone */ >> + unsigned int max_open_zones; /* max open zone resources of the zoned device */ >> #endif >> >> /* for node-related operations */ >> diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c >> index 7c45929671ad..642540782471 100644 >> --- a/fs/f2fs/super.c >> +++ b/fs/f2fs/super.c >> @@ -2326,6 +2326,17 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data) >> if (err) >> goto restore_opts; >> >> +#ifdef CONFIG_BLK_DEV_ZONED >> + if (f2fs_is_multi_device(sbi) && > > Why do we check multiple devices' condition here? Oh, it needs to check f2fs_sb_has_blkzoned(), right? Thanks, > > Thanks, > >> + sbi->max_open_zones < F2FS_OPTION(sbi).active_logs) { >> + f2fs_err(sbi, >> + "zoned: max open zones %u is too small, need at least %u open zones", >> + sbi->max_open_zones, F2FS_OPTION(sbi).active_logs); >> + err = -EINVAL; >> + goto restore_opts; >> + } >> +#endif >> + >> /* flush outstanding errors before changing fs state */ >> flush_work(&sbi->s_error_work); >> >> @@ -3868,11 +3879,24 @@ static int init_blkz_info(struct f2fs_sb_info *sbi, int devi) >> sector_t nr_sectors = bdev_nr_sectors(bdev); >> struct f2fs_report_zones_args rep_zone_arg; >> u64 zone_sectors; >> + unsigned int max_open_zones; >> int ret; >> >> if (!f2fs_sb_has_blkzoned(sbi)) >> return 0; >> >> + if (bdev_is_zoned(FDEV(devi).bdev)) { >> + max_open_zones = bdev_max_open_zones(bdev); >> + if (max_open_zones && (max_open_zones < sbi->max_open_zones)) >> + sbi->max_open_zones = max_open_zones; >> + if (sbi->max_open_zones < F2FS_OPTION(sbi).active_logs) { >> + f2fs_err(sbi, >> + "zoned: max open zones %u is too small, need at least %u open zones", >> + sbi->max_open_zones, F2FS_OPTION(sbi).active_logs); >> + return -EINVAL; >> + } >> + } >> + >> zone_sectors = bdev_zone_sectors(bdev); >> if (sbi->blocks_per_blkz && sbi->blocks_per_blkz != >> SECTOR_TO_BLOCK(zone_sectors)) >> @@ -4186,6 +4210,9 @@ static int f2fs_scan_devices(struct f2fs_sb_info *sbi) >> >> logical_blksize = bdev_logical_block_size(sbi->sb->s_bdev); >> sbi->aligned_blksize = true; >> +#ifdef CONFIG_BLK_DEV_ZONED >> + sbi->max_open_zones = UINT_MAX; >> +#endif >> >> for (i = 0; i < max_devices; i++) { >> if (i == 0) >> -- >> 2.40.1 >> >> >> >> _______________________________________________ >> Linux-f2fs-devel mailing list >> Linux-f2fs-devel@lists.sourceforge.net >> https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 0550929dc6e5..694f8a52cb84 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -1559,6 +1559,7 @@ struct f2fs_sb_info { #ifdef CONFIG_BLK_DEV_ZONED unsigned int blocks_per_blkz; /* F2FS blocks per zone */ + unsigned int max_open_zones; /* max open zone resources of the zoned device */ #endif /* for node-related operations */ diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 7c45929671ad..642540782471 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -2326,6 +2326,17 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data) if (err) goto restore_opts; +#ifdef CONFIG_BLK_DEV_ZONED + if (f2fs_is_multi_device(sbi) && + sbi->max_open_zones < F2FS_OPTION(sbi).active_logs) { + f2fs_err(sbi, + "zoned: max open zones %u is too small, need at least %u open zones", + sbi->max_open_zones, F2FS_OPTION(sbi).active_logs); + err = -EINVAL; + goto restore_opts; + } +#endif + /* flush outstanding errors before changing fs state */ flush_work(&sbi->s_error_work); @@ -3868,11 +3879,24 @@ static int init_blkz_info(struct f2fs_sb_info *sbi, int devi) sector_t nr_sectors = bdev_nr_sectors(bdev); struct f2fs_report_zones_args rep_zone_arg; u64 zone_sectors; + unsigned int max_open_zones; int ret; if (!f2fs_sb_has_blkzoned(sbi)) return 0; + if (bdev_is_zoned(FDEV(devi).bdev)) { + max_open_zones = bdev_max_open_zones(bdev); + if (max_open_zones && (max_open_zones < sbi->max_open_zones)) + sbi->max_open_zones = max_open_zones; + if (sbi->max_open_zones < F2FS_OPTION(sbi).active_logs) { + f2fs_err(sbi, + "zoned: max open zones %u is too small, need at least %u open zones", + sbi->max_open_zones, F2FS_OPTION(sbi).active_logs); + return -EINVAL; + } + } + zone_sectors = bdev_zone_sectors(bdev); if (sbi->blocks_per_blkz && sbi->blocks_per_blkz != SECTOR_TO_BLOCK(zone_sectors)) @@ -4186,6 +4210,9 @@ static int f2fs_scan_devices(struct f2fs_sb_info *sbi) logical_blksize = bdev_logical_block_size(sbi->sb->s_bdev); sbi->aligned_blksize = true; +#ifdef CONFIG_BLK_DEV_ZONED + sbi->max_open_zones = UINT_MAX; +#endif for (i = 0; i < max_devices; i++) { if (i == 0)