scsi: sd_zbc: Avoid that resetting a zone fails sporadically
authorBart Van Assche <bart.vanassche@wdc.com>
Tue, 17 Apr 2018 01:04:41 +0000 (18:04 -0700)
committerMartin K. Petersen <martin.petersen@oracle.com>
Thu, 19 Apr 2018 04:04:10 +0000 (00:04 -0400)
commitccce20fc7968d546fb1e8e147bf5cdc8afc4278a
tree03eb832a953db5bfb9801adb4e6a08a25494c6b1
parent505aa4b6a8834a2300971c5220c380c3271ebde3
scsi: sd_zbc: Avoid that resetting a zone fails sporadically

Since SCSI scanning occurs asynchronously, since sd_revalidate_disk() is
called from sd_probe_async() and since sd_revalidate_disk() calls
sd_zbc_read_zones() it can happen that sd_zbc_read_zones() is called
concurrently with blkdev_report_zones() and/or blkdev_reset_zones().  That can
cause these functions to fail with -EIO because sd_zbc_read_zones() e.g. sets
q->nr_zones to zero before restoring it to the actual value, even if no drive
characteristics have changed.  Avoid that this can happen by making the
following changes:

- Protect the code that updates zone information with blk_queue_enter()
  and blk_queue_exit().
- Modify sd_zbc_setup_seq_zones_bitmap() and sd_zbc_setup() such that
  these functions do not modify struct scsi_disk before all zone
  information has been obtained.

Note: since commit 055f6e18e08f ("block: Make q_usage_counter also track
legacy requests"; kernel v4.15) the request queue freezing mechanism also
affects legacy request queues.

Fixes: 89d947561077 ("sd: Implement support for ZBC devices")
Signed-off-by: Bart Van Assche <bart.vanassche@wdc.com>
Cc: Jens Axboe <axboe@kernel.dk>
Cc: Damien Le Moal <damien.lemoal@wdc.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Hannes Reinecke <hare@suse.com>
Cc: stable@vger.kernel.org # v4.16
Reviewed-by: Damien Le Moal <damien.lemoal@wdc.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/sd_zbc.c
include/linux/blkdev.h