Skip to content

Commit 15638d5

Browse files
Christoph Hellwigaxboe
authored andcommitted
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: 31f0656 ("block: introduce blkdev_report_zones_cached()") Signed-off-by: Christoph Hellwig <[email protected]> Reviewed-by: Damien Le Moal <[email protected]> Reviewed-by: Bart Van Assche <[email protected]> Signed-off-by: Jens Axboe <[email protected]>
1 parent c6886cf commit 15638d5

2 files changed

Lines changed: 22 additions & 5 deletions

File tree

block/blk-zoned.c

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -899,6 +899,19 @@ static int blkdev_report_zone_fallback(struct block_device *bdev,
899899
return blkdev_do_report_zones(bdev, sector, 1, &args);
900900
}
901901

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+
902915
/**
903916
* blkdev_get_zone_info - Get a single zone information from cached data
904917
* @bdev: Target block device
@@ -932,6 +945,9 @@ int blkdev_get_zone_info(struct block_device *bdev, sector_t sector,
932945
memset(zone, 0, sizeof(*zone));
933946
sector = ALIGN_DOWN(sector, zone_sectors);
934947

948+
if (!blkdev_has_cached_report_zones(bdev))
949+
return blkdev_report_zone_fallback(bdev, sector, zone);
950+
935951
rcu_read_lock();
936952
zones_cond = rcu_dereference(disk->zones_cond);
937953
if (!disk->zone_wplugs_hash || !zones_cond) {
@@ -1035,11 +1051,7 @@ int blkdev_report_zones_cached(struct block_device *bdev, sector_t sector,
10351051
if (!nr_zones || sector >= capacity)
10361052
return 0;
10371053

1038-
/*
1039-
* If we do not have any zone write plug resources, fallback to using
1040-
* the regular zone report.
1041-
*/
1042-
if (!disk_need_zone_resources(disk)) {
1054+
if (!blkdev_has_cached_report_zones(bdev)) {
10431055
struct blk_report_zones_args args = {
10441056
.cb = cb,
10451057
.data = data,
@@ -1115,6 +1127,7 @@ static void blk_zone_reset_all_bio_endio(struct bio *bio)
11151127
for (sector = 0; sector < capacity;
11161128
sector += bdev_zone_sectors(bio->bi_bdev))
11171129
disk_zone_set_cond(disk, sector, BLK_ZONE_COND_EMPTY);
1130+
clear_bit(GD_ZONE_APPEND_USED, &disk->state);
11181131
}
11191132

11201133
static void blk_zone_finish_bio_endio(struct bio *bio)
@@ -1474,6 +1487,9 @@ static void blk_zone_wplug_handle_native_zone_append(struct bio *bio)
14741487
struct blk_zone_wplug *zwplug;
14751488
unsigned long flags;
14761489

1490+
if (!test_bit(GD_ZONE_APPEND_USED, &disk->state))
1491+
set_bit(GD_ZONE_APPEND_USED, &disk->state);
1492+
14771493
/*
14781494
* We have native support for zone append operations, so we are not
14791495
* going to handle @bio through plugging. However, we may already have a

include/linux/blkdev.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@ struct gendisk {
173173
#define GD_ADDED 4
174174
#define GD_SUPPRESS_PART_SCAN 5
175175
#define GD_OWNS_QUEUE 6
176+
#define GD_ZONE_APPEND_USED 7
176177

177178
struct mutex open_mutex; /* open/close mutex */
178179
unsigned open_partitions; /* number of open partitions */

0 commit comments

Comments
 (0)