Message ID | 20240407072123.3484300-1-chao@kernel.org (mailing list archive) |
---|---|
State | Accepted |
Commit | 0f9b12142be1af8555cfe53c6fbecb8e60a40dac |
Headers | show |
Series | [f2fs-dev,v7] f2fs: fix zoned block device information initialization | expand |
On Sun, Apr 7, 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> > --- > v7: > - check f2fs_sb_has_blkzoned() instead of multiple-device condition > in f2fs_remount(). > 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 ba6288e870c5..fdf358c7f808 100644 > --- a/fs/f2fs/super.c > +++ b/fs/f2fs/super.c > @@ -2324,6 +2324,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_sb_has_blkzoned(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); > > @@ -3866,11 +3877,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)) > @@ -4191,6 +4215,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 > > Reviewed-by: Daeho Jeong <daehojeong@google.com> > > _______________________________________________ > Linux-f2fs-devel mailing list > Linux-f2fs-devel@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
Hello: This patch was applied to jaegeuk/f2fs.git (dev) by Jaegeuk Kim <jaegeuk@kernel.org>: On Sun, 7 Apr 2024 15:21:23 +0800 you 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. > > [...] Here is the summary with links: - [f2fs-dev,v7] f2fs: fix zoned block device information initialization https://git.kernel.org/jaegeuk/f2fs/c/0f9b12142be1 You are awesome, thank you!
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 ba6288e870c5..fdf358c7f808 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -2324,6 +2324,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_sb_has_blkzoned(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); @@ -3866,11 +3877,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)) @@ -4191,6 +4215,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)