Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

block: fix cached zone reporting after zone append was used

No zone plugs are allocated when a zone is opened by calling Zone Append
on it. This makes the cached zone reporting report incorrectly empty
zones if the file system is unmounted and report zones is called after
that, e.g. by xfstests test cases using the scratch device.

Fix this by recording if zone append was used on a device, and disable
cached reporting for the device until a ZONE_RESET_ALL happens that
guarantees all zones are empty.

We could probably do even better using a per-zone flag, but the practical
use cache for zone reporting after the initial mount are rather limited,
so let's keep things simple for now.

Fixes: 31f0656a4ab7 ("block: introduce blkdev_report_zones_cached()")
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
Reviewed-by: Bart Van Assche <bvanassche@acm.org>
Signed-off-by: Jens Axboe <axboe@kernel.dk>

authored by

Christoph Hellwig and committed by
Jens Axboe
15638d52 c6886cf6

+22 -5
+21 -5
block/blk-zoned.c
··· 899 899 return blkdev_do_report_zones(bdev, sector, 1, &args); 900 900 } 901 901 902 + /* 903 + * For devices that natively support zone append operations, we do not use zone 904 + * write plugging for zone append writes, which makes the zone condition 905 + * tracking invalid once zone append was used. In that case fall back to a 906 + * regular report zones to get correct information. 907 + */ 908 + static inline bool blkdev_has_cached_report_zones(struct block_device *bdev) 909 + { 910 + return disk_need_zone_resources(bdev->bd_disk) && 911 + (bdev_emulates_zone_append(bdev) || 912 + !test_bit(GD_ZONE_APPEND_USED, &bdev->bd_disk->state)); 913 + } 914 + 902 915 /** 903 916 * blkdev_get_zone_info - Get a single zone information from cached data 904 917 * @bdev: Target block device ··· 944 931 945 932 memset(zone, 0, sizeof(*zone)); 946 933 sector = ALIGN_DOWN(sector, zone_sectors); 934 + 935 + if (!blkdev_has_cached_report_zones(bdev)) 936 + return blkdev_report_zone_fallback(bdev, sector, zone); 947 937 948 938 rcu_read_lock(); 949 939 zones_cond = rcu_dereference(disk->zones_cond); ··· 1051 1035 if (!nr_zones || sector >= capacity) 1052 1036 return 0; 1053 1037 1054 - /* 1055 - * If we do not have any zone write plug resources, fallback to using 1056 - * the regular zone report. 1057 - */ 1058 - if (!disk_need_zone_resources(disk)) { 1038 + if (!blkdev_has_cached_report_zones(bdev)) { 1059 1039 struct blk_report_zones_args args = { 1060 1040 .cb = cb, 1061 1041 .data = data, ··· 1127 1115 for (sector = 0; sector < capacity; 1128 1116 sector += bdev_zone_sectors(bio->bi_bdev)) 1129 1117 disk_zone_set_cond(disk, sector, BLK_ZONE_COND_EMPTY); 1118 + clear_bit(GD_ZONE_APPEND_USED, &disk->state); 1130 1119 } 1131 1120 1132 1121 static void blk_zone_finish_bio_endio(struct bio *bio) ··· 1486 1473 struct gendisk *disk = bio->bi_bdev->bd_disk; 1487 1474 struct blk_zone_wplug *zwplug; 1488 1475 unsigned long flags; 1476 + 1477 + if (!test_bit(GD_ZONE_APPEND_USED, &disk->state)) 1478 + set_bit(GD_ZONE_APPEND_USED, &disk->state); 1489 1479 1490 1480 /* 1491 1481 * We have native support for zone append operations, so we are not
+1
include/linux/blkdev.h
··· 173 173 #define GD_ADDED 4 174 174 #define GD_SUPPRESS_PART_SCAN 5 175 175 #define GD_OWNS_QUEUE 6 176 + #define GD_ZONE_APPEND_USED 7 176 177 177 178 struct mutex open_mutex; /* open/close mutex */ 178 179 unsigned open_partitions; /* number of open partitions */