All of lore.kernel.org
 help / color / mirror / Atom feed
From: Niklas Cassel <cassel@kernel.org>
To: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>,
	"Martin K. Petersen" <mkp@kernel.org>
Cc: linux-scsi@vger.kernel.org, Damien Le Moal <dlemoal@kernel.org>,
	John Garry <john.garry@linux.dev>,
	Niklas Cassel <cassel@kernel.org>
Subject: [PATCH v2 1/4] scsi: scsi_debug: Do not advance the write pointer of a failed write
Date: Thu, 17 Sep 2026 13:03:18 +0200	[thread overview]
Message-ID: <20260917110316.1104863-7-cassel@kernel.org> (raw)
In-Reply-To: <20260917110316.1104863-6-cassel@kernel.org>

resp_write_dt0() and resp_write_scat() advance the write pointer of a
sequential write required zone by the transfer length of the command
before looking at what do_device_access() returned. It returns -1 when
the data direction of the command does not match the operation, and a
short byte count when the data-out buffer is smaller than the transfer
length, both of which an initiator can produce with SG_IO.

The zone state then describes more data than is on the medium, and a
write at the position where the data really ends is terminated with
UNALIGNED WRITE COMMAND, because the write pointer has moved beyond it.
The zone has to be reset before it can be written to again.

Leave the write pointer alone unless all of the data was written. A host
that retries the command writes at the write pointer, where whatever the
failed command did write begins, so the retry overwrites it.

Advancing over the data that was written instead would be no better,
because do_device_access() copies one logical block at a time and stops
at the first short copy, so it can report a byte count that is not a
multiple of the physical block size. That would leave the write pointer
in the middle of a physical block, and ZBC requires a write to a
sequential write required zone to end on a physical block boundary, so
no write can leave a real device with such a write pointer.

resp_write_same() does not need the same treatment, as it writes with
memmove() and cannot fail part way through.

Assisted-by: LLM
Fixes: f0d1cf9378bd ("scsi: scsi_debug: Add ZBC zone commands")
Signed-off-by: Niklas Cassel <cassel@kernel.org>
---
Tested with:

  modprobe scsi_debug zbc=managed sector_size=512 physblk_exp=3 \
      zone_size_mb=8 dev_size_mb=128 zone_nr_conv=2

issuing WRITE(16) with sg_raw so that the data-out buffer is shorter
than the transfer length and do_device_access() returns a short count.
Sixteen logical blocks with a buffer of twelve, and eight blocks with a
buffer of one, both leave the write pointer where it was, and the full
sixteen block write then succeeds from there. Before this patch both
advanced the write pointer by the full transfer length, and a write at
the end of the data that had actually been written was then terminated
with UNALIGNED WRITE COMMAND.
---
 drivers/scsi/scsi_debug.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index 6941809dfdb7..3ce2dbdff177 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -5150,8 +5150,8 @@ static int resp_write_dt0(struct scsi_cmnd *scp, struct sdebug_dev_info *devip)
 	if (unlikely(scsi_debug_lbp()))
 		map_region(sip, lba, num);
 
-	/* If ZBC zone then bump its write pointer */
-	if (sdebug_dev_is_zoned(devip))
+	/* If ZBC zone then bump its write pointer, if all data was written */
+	if (sdebug_dev_is_zoned(devip) && ret == num * sdebug_sector_size)
 		zbc_inc_wp(devip, lba, num);
 	if (meta_data_locked)
 		sdeb_meta_write_unlock(sip);
@@ -5314,8 +5314,8 @@ static int resp_write_scat(struct scsi_cmnd *scp,
 		 * writes behaviour as possible.
 		 */
 		ret = do_device_access(sip, scp, sg_off, lba, num, group, true, true);
-		/* If ZBC zone then bump its write pointer */
-		if (sdebug_dev_is_zoned(devip))
+		/* If ZBC zone then bump its write pointer, if all data was written */
+		if (sdebug_dev_is_zoned(devip) && ret == num_by)
 			zbc_inc_wp(devip, lba, num);
 		if (unlikely(scsi_debug_lbp()))
 			map_region(sip, lba, num);
-- 
2.55.0


  reply	other threads:[~2026-09-17 11:03 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-17 11:03 [PATCH v2 0/4] scsi: scsi_debug: fix zoned write validation Niklas Cassel
2026-09-17 11:03 ` Niklas Cassel [this message]
2026-09-17 11:17   ` [PATCH v2 1/4] scsi: scsi_debug: Do not advance the write pointer of a failed write sashiko-bot
2026-09-17 12:21     ` Niklas Cassel
2026-09-17 13:00   ` Damien Le Moal
2026-09-17 11:03 ` [PATCH v2 2/4] scsi: scsi_debug: Enforce physical block alignment of zoned writes Niklas Cassel
2026-09-17 11:03 ` [PATCH v2 3/4] scsi: scsi_debug: Map the region written by WRITE ATOMIC (16) Niklas Cassel
2026-09-17 11:20   ` sashiko-bot
2026-09-17 13:04   ` Damien Le Moal
2026-09-17 11:03 ` [PATCH v2 4/4] scsi: scsi_debug: Validate zone access for " Niklas Cassel
2026-09-17 13:03   ` Damien Le Moal

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=20260917110316.1104863-7-cassel@kernel.org \
    --to=cassel@kernel.org \
    --cc=James.Bottomley@HansenPartnership.com \
    --cc=dlemoal@kernel.org \
    --cc=john.garry@linux.dev \
    --cc=linux-scsi@vger.kernel.org \
    --cc=mkp@kernel.org \
    /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.