From: Damien Le Moal <dlemoal@kernel.org>
To: Tal Zussman <tz2294@columbia.edu>,
"James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>,
"Martin K. Petersen" <mkp@kernel.org>,
Douglas Gilbert <dgilbert@interlog.com>
Cc: linux-scsi@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH 1/2] scsi: scsi_debug: wrap around the store when zeroing a reset zone
Date: Wed, 11 Nov 2026 18:04:40 +0900 [thread overview]
Message-ID: <23a6d8be-d4af-4cf9-bf48-8ab7272abc1e@kernel.org> (raw)
In-Reply-To: <20261110-scsi-debug-zone-reset-v1-1-28cb9184b5ea@columbia.edu>
On 2026/11/11 6:23, Tal Zussman wrote:
> zbc_rwp_zone() zeroes the blocks of a zone that is reset, using the
> start of the zone as an offset into the store. With virtual_gb set, the
> device and its zones can extend past the end of the store, which is
> only dev_size_mb in size. Writes wrap around in do_device_access(), but
> the memset() doesn't, so resetting a zone that has been written to can
> write past the end of the store.
>
> On a device whose fifth zone starts exactly at the end of the store,
> write to that zone and reset it:
>
> # modprobe scsi_debug zbc=managed sector_size=4096 dev_size_mb=16 \
> virtual_gb=1 zone_size_mb=4
> # dd if=/dev/urandom of=/dev/sda bs=1M count=1 seek=16 oflag=direct
> # blkzone reset -o 32768 -c 1 /dev/sda
>
> The memset() starts at the first byte past the store, in the guard page
> after the vmalloc'ed area, for the 1 MiB that was written:
>
> BUG: unable to handle page fault for address: ffffc90002c00000
> Oops: Oops: 0002 [#1] SMP KASAN NOPTI
> RIP: 0010:memset_orig+0x33/0xb0
> RDX: 0000000000100000 RSI: 0000000000000000 RDI: ffffc90002c00000
> Call Trace:
> zbc_rwp_zone+0x1a7/0x2a0 [scsi_debug]
> resp_rwp_zone+0x19c/0x450 [scsi_debug]
> schedule_resp+0x2dd/0xbc0 [scsi_debug]
> scsi_debug_queuecommand+0x1286/0x2950 [scsi_debug]
> scsi_queue_rq+0x1d74/0x3200
> blk_mq_dispatch_rq_list+0x3ad/0x23c0
>
> The command never completes, so the reset returns EIO to userspace and
> the device is unusable afterwards.
>
> Zero the blocks in a helper that wraps around at the end of the store,
> and that stops after one pass over it for a zone that is larger than
> the store.
>
> Fixes: f0d1cf9378bd ("scsi: scsi_debug: Add ZBC zone commands")
> Signed-off-by: Tal Zussman <tz2294@columbia.edu>
> ---
> drivers/scsi/scsi_debug.c | 26 ++++++++++++++++++++++++--
> 1 file changed, 24 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
> index a922c8318a2f..1c27ea0f9b69 100644
> --- a/drivers/scsi/scsi_debug.c
> +++ b/drivers/scsi/scsi_debug.c
> @@ -6612,6 +6612,29 @@ static int resp_finish_zone(struct scsi_cmnd *scp,
> return res;
> }
>
> +/*
> + * Zero the blocks of a zone that is being reset. The store can be smaller
> + * than the device, so wrap around at its end like do_device_access() does.
> + */
> +static void zbc_zero_blocks(struct sdeb_store_info *sip, sector_t lba,
> + sector_t num)
> +{
> + /* One pass over the store zeroes all of it */
> + num = min_t(sector_t, num, sdebug_store_sectors);
Why do you need to do this in a loop?
You can certainly calculate the total number of blocks that need zeroing and do
a single memset, no? What am I missing here?
> +
> + while (num) {
> + sector_t block = lba;
> + u32 n;
> +
> + block = sector_div(block, sdebug_store_sectors);
> + n = min_t(sector_t, num, sdebug_store_sectors - block);
> + memset(sip->storep + block * sdebug_sector_size, 0,
> + (size_t)n * sdebug_sector_size);
> + lba += n;
> + num -= n;
> + }
> +}
> +
> static void zbc_rwp_zone(struct sdebug_dev_info *devip,
> struct sdeb_zone_state *zsp)
> {
> @@ -6629,8 +6652,7 @@ static void zbc_rwp_zone(struct sdebug_dev_info *devip,
> devip->nr_closed--;
>
> if (zsp->z_wp > zsp->z_start)
> - memset(sip->storep + zsp->z_start * sdebug_sector_size, 0,
> - (zsp->z_wp - zsp->z_start) * sdebug_sector_size);
> + zbc_zero_blocks(sip, zsp->z_start, zsp->z_wp - zsp->z_start);
>
> zsp->z_non_seq_resource = false;
> zsp->z_wp = zsp->z_start;
>
--
Damien Le Moal
Western Digital Research
next prev parent reply other threads:[~2026-11-11 9:04 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-10 21:23 [PATCH 0/2] scsi: scsi_debug: fix zone reset with virtual_gb and DIX Tal Zussman
2026-11-10 21:23 ` [PATCH 1/2] scsi: scsi_debug: wrap around the store when zeroing a reset zone Tal Zussman
2026-11-10 21:36 ` sashiko-bot
2026-11-11 9:04 ` Damien Le Moal [this message]
2026-11-11 18:49 ` Tal Zussman
2026-11-10 21:23 ` [PATCH 2/2] scsi: scsi_debug: reset protection information on zone reset Tal Zussman
2026-11-10 21:34 ` sashiko-bot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=23a6d8be-d4af-4cf9-bf48-8ab7272abc1e@kernel.org \
--to=dlemoal@kernel.org \
--cc=James.Bottomley@HansenPartnership.com \
--cc=dgilbert@interlog.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-scsi@vger.kernel.org \
--cc=mkp@kernel.org \
--cc=tz2294@columbia.edu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.