mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
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

  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®