On Wed, Apr 14, 2021 at 03:47:08PM +0200, Karel Zak wrote: > On Wed, Apr 14, 2021 at 10:33:38AM +0900, Naohiro Aota wrote: > > +#define ASSERT(x) assert(x) > > Really? ;-) > > > +typedef uint64_t u64; > > +typedef uint64_t sector_t; > > +typedef uint8_t u8; > > I do not see a reason for u64 and u8 here. Yep, these are here just to make it easy to copy the code from kernel. But this code won't change so much, so I can drop these. > > + > > +#ifdef HAVE_LINUX_BLKZONED_H > > +static int sb_write_pointer(int fd, struct blk_zone *zones, u64 *wp_ret) > > +{ > > + bool empty[BTRFS_NR_SB_LOG_ZONES]; > > + bool full[BTRFS_NR_SB_LOG_ZONES]; > > + sector_t sector; > > + > > + ASSERT(zones[0].type != BLK_ZONE_TYPE_CONVENTIONAL && > > + zones[1].type != BLK_ZONE_TYPE_CONVENTIONAL); > > assert() I will use it. > ... > > + for (i = 0; i < BTRFS_NR_SB_LOG_ZONES; i++) { > > + u64 bytenr; > > + > > + bytenr = ((zones[i].start + zones[i].len) > > + << SECTOR_SHIFT) - BTRFS_SUPER_INFO_SIZE; > > + > > + ret = pread64(fd, buf[i], BTRFS_SUPER_INFO_SIZE, > > + bytenr); > > please, use > > ptr = blkid_probe_get_buffer(pr, BTRFS_SUPER_INFO_SIZE, bytenr); > > the library will care about the buffer and reuse it. It's also > important to keep blkid_do_wipe() usable. Sure. I'll use it. > > + if (ret != BTRFS_SUPER_INFO_SIZE) > > + return -EIO; > > + super[i] = (struct btrfs_super_block *)&buf[i]; > > super[i] = (struct btrfs_super_block *) ptr; > > > + } > > + > > + if (super[0]->generation > super[1]->generation) > > + sector = zones[1].start; > > + else > > + sector = zones[0].start; > > + } else if (!full[0] && (empty[1] || full[1])) { > > + sector = zones[0].wp; > > + } else if (full[0]) { > > + sector = zones[1].wp; > > + } else { > > + return -EUCLEAN; > > + } > > + *wp_ret = sector << SECTOR_SHIFT; > > + return 0; > > +} > > + > > +static int sb_log_offset(blkid_probe pr, uint64_t *bytenr_ret) > > +{ > > + uint32_t zone_num = 0; > > + uint32_t zone_size_sector; > > + struct blk_zone_report *rep; > > + struct blk_zone *zones; > > + size_t rep_size; > > + int ret; > > + uint64_t wp; > > + > > + zone_size_sector = pr->zone_size >> SECTOR_SHIFT; > > + > > + rep_size = sizeof(struct blk_zone_report) + sizeof(struct blk_zone) * 2; > > + rep = malloc(rep_size); > > + if (!rep) > > + return -errno; > > + > > + memset(rep, 0, rep_size); > > + rep->sector = zone_num * zone_size_sector; > > + rep->nr_zones = 2; > > what about to add to lib/blkdev.c a new function: > > struct blk_zone_report *blkdev_get_zonereport(int fd, uint64 sector, int nzones); > > and call this function from your sb_log_offset() as well as from blkid_do_wipe()? > > Anyway, calloc() is better than malloc()+memset(). Indeed. I will do so. > > + if (zones[0].type == BLK_ZONE_TYPE_CONVENTIONAL) { > > + *bytenr_ret = zones[0].start << SECTOR_SHIFT; > > + ret = 0; > > + goto out; > > + } else if (zones[1].type == BLK_ZONE_TYPE_CONVENTIONAL) { > > + *bytenr_ret = zones[1].start << SECTOR_SHIFT; > > + ret = 0; > > + goto out; > > + } > > what about: > > for (i = 0; i < BTRFS_NR_SB_LOG_ZONES; i++) { > if (zones[i].type == BLK_ZONE_TYPE_CONVENTIONAL) { > *bytenr_ret = zones[i].start << SECTOR_SHIFT; > ret = 0; > goto out; > } > } Yes, this looks cleaner. Thanks. > > > > Karel > > -- > Karel Zak <kzak@xxxxxxxxxx> > http://karelzak.blogspot.com >