The helper function blk_zone_wp_offset() is called from disk_zone_wplug_sync_wp_offset(), and again called from blk_revalidate_seq_zone() right after the call to disk_zone_wplug_sync_wp_offset(). Change disk_zone_wplug_sync_wp_offset() to return the wp_offset it used for updating the target zone write plug to avoid this double call. With this change, blk_zone_wp_offset() can be open coded directly in disk_zone_wplug_sync_wp_offset(). This open-coding introduces 2 changes: handle the BLK_COND_ZONE_ACTIVE case, and return UINT_MAX as the wp_offset for a full zone, since the write pointer of full zones is invalid. For the case where a zone does not have a zone write plug, disk_zone_wplug_sync_wp_offset() does nothing and returns 0. This in turn leads to blk_revalidate_seq_zone() to immediately return, which is exactly what we want (because there is no need to attempt removing a zone write plug that does not exist). Signed-off-by: Damien Le Moal --- block/blk-zoned.c | 64 +++++++++++++++++++++++------------------------ 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/block/blk-zoned.c b/block/blk-zoned.c index c5226bcaaa94..2f4e45638601 100644 --- a/block/blk-zoned.c +++ b/block/blk-zoned.c @@ -794,46 +794,48 @@ static void disk_zone_wplug_set_wp_offset(struct gendisk *disk, disk_remove_zone_wplug(disk, zwplug); } -static unsigned int blk_zone_wp_offset(struct blk_zone *zone) -{ - switch (zone->cond) { - case BLK_ZONE_COND_IMP_OPEN: - case BLK_ZONE_COND_EXP_OPEN: - case BLK_ZONE_COND_CLOSED: - return zone->wp - zone->start; - case BLK_ZONE_COND_FULL: - return zone->len; - case BLK_ZONE_COND_EMPTY: - return 0; - case BLK_ZONE_COND_NOT_WP: - case BLK_ZONE_COND_OFFLINE: - case BLK_ZONE_COND_READONLY: - default: - /* - * Conventional, offline and read-only zones do not have a valid - * write pointer. - */ - return UINT_MAX; - } -} - -static void disk_zone_wplug_sync_wp_offset(struct gendisk *disk, - struct blk_zone *zone) +static unsigned int disk_zone_wplug_sync_wp_offset(struct gendisk *disk, + struct blk_zone *zone) { struct blk_zone_wplug *zwplug; unsigned long flags; + unsigned int wp_offset; zwplug = disk_get_zone_wplug(disk, zone->start); if (!zwplug) - return; + return 0; spin_lock_irqsave(&zwplug->lock, flags); - if (zwplug->flags & BLK_ZONE_WPLUG_NEED_WP_UPDATE) - disk_zone_wplug_set_wp_offset(disk, zwplug, - blk_zone_wp_offset(zone)); + if (zwplug->flags & BLK_ZONE_WPLUG_NEED_WP_UPDATE) { + switch (zone->cond) { + case BLK_ZONE_COND_IMP_OPEN: + case BLK_ZONE_COND_EXP_OPEN: + case BLK_ZONE_COND_CLOSED: + case BLK_ZONE_COND_ACTIVE: + wp_offset = zone->wp - zone->start; + break; + case BLK_ZONE_COND_EMPTY: + wp_offset = 0; + break; + case BLK_ZONE_COND_FULL: + case BLK_ZONE_COND_NOT_WP: + case BLK_ZONE_COND_OFFLINE: + case BLK_ZONE_COND_READONLY: + default: + /* + * Conventional, full, offline and read-only zones do + * not have a valid write pointer. + */ + wp_offset = UINT_MAX; + break; + } + disk_zone_wplug_set_wp_offset(disk, zwplug, wp_offset); + } spin_unlock_irqrestore(&zwplug->lock, flags); disk_put_zone_wplug(zwplug); + + return wp_offset; } /** @@ -2095,9 +2097,7 @@ static int blk_revalidate_seq_zone(struct blk_zone *zone, unsigned int idx, if (!queue_emulates_zone_append(disk->queue) || !disk->zone_wplugs_hash) return 0; - disk_zone_wplug_sync_wp_offset(disk, zone); - - wp_offset = blk_zone_wp_offset(zone); + wp_offset = disk_zone_wplug_sync_wp_offset(disk, zone); if (!wp_offset || wp_offset >= zone->capacity) return 0; -- 2.51.1