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: 4+ 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-11 9:04 ` Damien Le Moal [this message]
2026-11-10 21:23 ` [PATCH 2/2] scsi: scsi_debug: reset protection information on zone reset Tal Zussman
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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®