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. > + > +#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() ... > + 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. > + 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(). > + 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; } } Karel -- Karel Zak <kzak@xxxxxxxxxx> http://karelzak.blogspot.com