On 2019/8/21 12:47, Shin'ichiro Kawasaki wrote:
> To prepare for write pointer consistency check by fsck, add
> f2fs_report_zones() helper function which calls REPORT ZONE command to
> get write pointer status. The function is added to lib/libf2fs_zoned
> which gathers zoned block device related functions.
> 
> To check write pointer consistency with f2fs meta data, fsck needs to
> refer both of reported zone information and f2fs super block structure
> "f2fs_sb_info". However, libf2fs_zoned does not import f2fs_sb_info. To
> keep f2fs_sb_info structure out of libf2fs_zoned, provide a callback
> function in fsck to f2fs_report_zones() and call it for each zone.
> 
> Signed-off-by: Shin'ichiro Kawasaki <shinichiro.kawas...@wdc.com>
> ---
>  include/f2fs_fs.h   |  2 ++
>  lib/libf2fs_zoned.c | 57 +++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 59 insertions(+)
> 
> diff --git a/include/f2fs_fs.h b/include/f2fs_fs.h
> index 0d9a036..abadd1b 100644
> --- a/include/f2fs_fs.h
> +++ b/include/f2fs_fs.h
> @@ -1279,6 +1279,8 @@ blk_zone_cond_str(struct blk_zone *blkz)
>  
>  extern int f2fs_get_zoned_model(int);
>  extern int f2fs_get_zone_blocks(int);
> +typedef int (report_zones_cb_t)(int i, struct blk_zone *blkz, void *opaque);
> +extern int f2fs_report_zones(int, report_zones_cb_t *, void *);
>  extern int f2fs_check_zones(int);
>  extern int f2fs_reset_zones(int);
>  
> diff --git a/lib/libf2fs_zoned.c b/lib/libf2fs_zoned.c
> index af00b44..fc4974f 100644
> --- a/lib/libf2fs_zoned.c
> +++ b/lib/libf2fs_zoned.c
> @@ -193,6 +193,57 @@ int f2fs_get_zone_blocks(int i)
>  
>  #define F2FS_REPORT_ZONES_BUFSZ      524288
>  
> +int f2fs_report_zones(int j, report_zones_cb_t *report_zones_cb, void 
> *opaque)
> +{
> +     struct device_info *dev = c.devices + j;
> +     struct blk_zone_report *rep;
> +     struct blk_zone *blkz;
> +     unsigned int i, n = 0;
> +     u_int64_t total_sectors = (dev->total_sectors * c.sector_size) >> 9;

Hi Shin'ichiro,

Could we use SECTOR_SHIFT instead?

> +     u_int64_t sector = 0;
> +     int ret = -1;
> +
> +     rep = malloc(F2FS_REPORT_ZONES_BUFSZ);
> +     if (!rep) {
> +             ERR_MSG("No memory for report zones\n");
> +             return -ENOMEM;
> +     }
> +
> +     while (sector < total_sectors) {
> +
> +             /* Get zone info */
> +             rep->sector = sector;
> +             rep->nr_zones = (F2FS_REPORT_ZONES_BUFSZ - sizeof(struct 
> blk_zone_report))
> +                     / sizeof(struct blk_zone);
> +
> +             ret = ioctl(dev->fd, BLKREPORTZONE, rep);
> +             if (ret != 0) {
> +                     ret = -errno;
> +                     ERR_MSG("ioctl BLKREPORTZONE failed\n");
It's minor, it will be better to print errno here, since I didn't see we print
error no from caller.

> +                     goto out;
> +             }
> +
> +             if (!rep->nr_zones) {
> +                     ret = -EIO;
> +                     ERR_MSG("Unexpected ioctl BLKREPORTZONE result\n");
> +                     goto out;
> +             }
> +
> +             blkz = (struct blk_zone *)(rep + 1);
> +             for (i = 0; i < rep->nr_zones && sector < total_sectors; i++) {

The condition looks like that block zones in rep may across end-of-device? Will
this really happen?

So I mean will "i < rep->nr_zones" be enough?

Thanks,

> +                     ret = report_zones_cb(n, blkz, opaque);
> +                     if (ret)
> +                             goto out;
> +                     sector = blk_zone_sector(blkz) + blk_zone_length(blkz);
> +                     n++;
> +                     blkz++;
> +             }
> +     }
> +out:
> +     free(rep);
> +     return ret;
> +}
> +
>  int f2fs_check_zones(int j)
>  {
>       struct device_info *dev = c.devices + j;
> @@ -372,6 +423,12 @@ out:
>  
>  #else
>  
> +int f2fs_report_zones(int j, report_zones_cb_t *report_zones_cb, void 
> *opaque)
> +{
> +     ERR_MSG("%d: Zoned block devices are not supported\n", i);
> +     return -1;
> +}
> +
>  int f2fs_get_zoned_model(int i)
>  {
>       struct device_info *dev = c.devices + i;
> 


_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

Reply via email to