Skip to content

Commit 6c5dee1

Browse files
damien-lemoalmartinkpetersen
authored andcommitted
scsi: sd: sd_zbc: Fix ZBC disk initialization
Make sure to call sd_zbc_init_disk() when the sdkp->zoned field is known, that is, once sd_read_block_characteristics() is executed in sd_revalidate_disk(), so that host-aware disks also get initialized. To do so, move sd_zbc_init_disk() call in sd_zbc_revalidate_zones() and make sure to execute it for all zoned disks, including for host-aware disks used as regular disks as these disk zoned model may be changed back to BLK_ZONED_HA when partitions are deleted. Link: https://lore.kernel.org/r/[email protected] Fixes: 5795eb4 ("scsi: sd_zbc: emulate ZONE_APPEND commands") Cc: <[email protected]> # v5.8+ Reported-by: Borislav Petkov <[email protected]> Tested-by: Borislav Petkov <[email protected]> Reviewed-by: Johannes Thumshirn <[email protected]> Reviewed-by: Christoph Hellwig <[email protected]> Signed-off-by: Damien Le Moal <[email protected]> Signed-off-by: Martin K. Petersen <[email protected]>
1 parent 27ba3e8 commit 6c5dee1

File tree

3 files changed

+35
-35
lines changed

3 files changed

+35
-35
lines changed

drivers/scsi/sd.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3410,10 +3410,6 @@ static int sd_probe(struct device *dev)
34103410
sdkp->first_scan = 1;
34113411
sdkp->max_medium_access_timeouts = SD_MAX_MEDIUM_TIMEOUTS;
34123412

3413-
error = sd_zbc_init_disk(sdkp);
3414-
if (error)
3415-
goto out_free_index;
3416-
34173413
sd_revalidate_disk(gd);
34183414

34193415
gd->flags = GENHD_FL_EXT_DEVT;

drivers/scsi/sd.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,6 @@ static inline int sd_is_zoned(struct scsi_disk *sdkp)
215215

216216
#ifdef CONFIG_BLK_DEV_ZONED
217217

218-
int sd_zbc_init_disk(struct scsi_disk *sdkp);
219218
void sd_zbc_release_disk(struct scsi_disk *sdkp);
220219
int sd_zbc_read_zones(struct scsi_disk *sdkp, unsigned char *buffer);
221220
int sd_zbc_revalidate_zones(struct scsi_disk *sdkp);
@@ -231,11 +230,6 @@ blk_status_t sd_zbc_prepare_zone_append(struct scsi_cmnd *cmd, sector_t *lba,
231230

232231
#else /* CONFIG_BLK_DEV_ZONED */
233232

234-
static inline int sd_zbc_init_disk(struct scsi_disk *sdkp)
235-
{
236-
return 0;
237-
}
238-
239233
static inline void sd_zbc_release_disk(struct scsi_disk *sdkp) {}
240234

241235
static inline int sd_zbc_read_zones(struct scsi_disk *sdkp,

drivers/scsi/sd_zbc.c

Lines changed: 35 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -651,6 +651,28 @@ static void sd_zbc_print_zones(struct scsi_disk *sdkp)
651651
sdkp->zone_blocks);
652652
}
653653

654+
static int sd_zbc_init_disk(struct scsi_disk *sdkp)
655+
{
656+
sdkp->zones_wp_offset = NULL;
657+
spin_lock_init(&sdkp->zones_wp_offset_lock);
658+
sdkp->rev_wp_offset = NULL;
659+
mutex_init(&sdkp->rev_mutex);
660+
INIT_WORK(&sdkp->zone_wp_offset_work, sd_zbc_update_wp_offset_workfn);
661+
sdkp->zone_wp_update_buf = kzalloc(SD_BUF_SIZE, GFP_KERNEL);
662+
if (!sdkp->zone_wp_update_buf)
663+
return -ENOMEM;
664+
665+
return 0;
666+
}
667+
668+
void sd_zbc_release_disk(struct scsi_disk *sdkp)
669+
{
670+
kvfree(sdkp->zones_wp_offset);
671+
sdkp->zones_wp_offset = NULL;
672+
kfree(sdkp->zone_wp_update_buf);
673+
sdkp->zone_wp_update_buf = NULL;
674+
}
675+
654676
static void sd_zbc_revalidate_zones_cb(struct gendisk *disk)
655677
{
656678
struct scsi_disk *sdkp = scsi_disk(disk);
@@ -667,6 +689,19 @@ int sd_zbc_revalidate_zones(struct scsi_disk *sdkp)
667689
u32 max_append;
668690
int ret = 0;
669691

692+
/*
693+
* For all zoned disks, initialize zone append emulation data if not
694+
* already done. This is necessary also for host-aware disks used as
695+
* regular disks due to the presence of partitions as these partitions
696+
* may be deleted and the disk zoned model changed back from
697+
* BLK_ZONED_NONE to BLK_ZONED_HA.
698+
*/
699+
if (sd_is_zoned(sdkp) && !sdkp->zone_wp_update_buf) {
700+
ret = sd_zbc_init_disk(sdkp);
701+
if (ret)
702+
return ret;
703+
}
704+
670705
/*
671706
* There is nothing to do for regular disks, including host-aware disks
672707
* that have partitions.
@@ -768,28 +803,3 @@ int sd_zbc_read_zones(struct scsi_disk *sdkp, unsigned char *buf)
768803

769804
return ret;
770805
}
771-
772-
int sd_zbc_init_disk(struct scsi_disk *sdkp)
773-
{
774-
if (!sd_is_zoned(sdkp))
775-
return 0;
776-
777-
sdkp->zones_wp_offset = NULL;
778-
spin_lock_init(&sdkp->zones_wp_offset_lock);
779-
sdkp->rev_wp_offset = NULL;
780-
mutex_init(&sdkp->rev_mutex);
781-
INIT_WORK(&sdkp->zone_wp_offset_work, sd_zbc_update_wp_offset_workfn);
782-
sdkp->zone_wp_update_buf = kzalloc(SD_BUF_SIZE, GFP_KERNEL);
783-
if (!sdkp->zone_wp_update_buf)
784-
return -ENOMEM;
785-
786-
return 0;
787-
}
788-
789-
void sd_zbc_release_disk(struct scsi_disk *sdkp)
790-
{
791-
kvfree(sdkp->zones_wp_offset);
792-
sdkp->zones_wp_offset = NULL;
793-
kfree(sdkp->zone_wp_update_buf);
794-
sdkp->zone_wp_update_buf = NULL;
795-
}

0 commit comments

Comments
 (0)