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 v4 06/10] scsi: scsi_debug: Enforce physical block alignment of zoned writes
Date: Fri, 18 Sep 2026 08:29:17 +0200 [thread overview]
Message-ID: <20260918062910.1709791-18-cassel@kernel.org> (raw)
In-Reply-To: <20260918062910.1709791-12-cassel@kernel.org>
ZBC-3 r06 (T10/BSR INCITS 579), 4.5.3.3.2 Write access pattern
requirements for sequential write required zones, states:
The device server terminates with CHECK CONDITION status, with the
sense key set to ILLEGAL REQUEST, and the additional sense code set
to UNALIGNED WRITE COMMAND a write command, other than an entire
medium write same command, that specifies:
a) the starting LBA in a sequential write required zone set to a
value that is not equal to the write pointer for that sequential
write required zone; or
b) an ending LBA that is not equal to the last logical block within
a physical block (see SBC-5).
That is why sd_zbc_read_zones() sets the zone_write_granularity queue
limit to the physical block size of a host-managed device, exposing the
constraint to user space.
check_zbc_access_params() implements condition a) but not condition b):
it verifies that a write to a sequential write required zone starts at
the write pointer of the zone, but never validates the ending LBA. As a
consequence, when scsi_debug emulates a host-managed device whose
physical block size is larger than its logical block size, for instance
with zbc=managed sector_size=512 physblk_exp=3, a write of a single
logical block at the write pointer of a sequential zone is accepted and
advances the write pointer by one logical block. The write pointer is
then no longer a multiple of the zone_write_granularity reported for the
device, so nothing can write at it at the granularity that was
advertised, and the zone can only be used again after being reset.
Implement condition b) as well, with the same sense data as the write
pointer check, as the standard gives both conditions the same sense key
and additional sense code. The exclusion of an entire medium write same
command needs no special case: such a command spans the whole medium, so
it is already terminated with WRITE BOUNDARY VIOLATION by the preceding
check.
The check is placed in check_zbc_access_params(), which every command
that advances a zone write pointer reaches first: WRITE, WRITE SCATTERED
and WRITE SAME. Reads return earlier in the function and are unaffected.
Sequential write preferred zones, which are emulated for host-aware
devices with zbc=aware, are left alone: writes to them are not required
to be sequential, and Linux does not restrict the write granularity of
host-aware devices.
With the default physblk_exp=0, the physical block size equals the
logical block size and the new check is a no-op.
Assisted-by: LLM
Fixes: f0d1cf9378bd ("scsi: scsi_debug: Add ZBC zone commands")
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
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
Before this patch, a one logical block WRITE(16) at the write pointer of
an empty sequential write required zone completes with GOOD status and
leaves the write pointer at LBA 0x18001, which is not a multiple of the
4096 byte zone_write_granularity reported for the device. After it, the
same command is terminated with ILLEGAL REQUEST / UNALIGNED WRITE
COMMAND and the zone is left EMPTY, while an aligned eight block write
is still accepted.
Compared to the version reviewed in v1, the only change is that the new
mk_sense_buffer() call uses the combined UNALIGNED_WRITE_COMMAND sense
code, as this is based on 7.4/scsi-staging.
---
drivers/scsi/scsi_debug.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index 170d5c944b61..a4db282ac971 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -3980,6 +3980,16 @@ static int check_zbc_access_params(struct scsi_cmnd *scp,
UNALIGNED_WRITE_COMMAND);
return check_condition_result;
}
+ /*
+ * Writes must end on a physical block boundary, that is, the
+ * transfer length must be a multiple of the physical block
+ * size.
+ */
+ if (!IS_ALIGNED(lba + num, 1U << sdebug_physblk_exp)) {
+ mk_sense_buffer(scp, ILLEGAL_REQUEST,
+ UNALIGNED_WRITE_COMMAND);
+ return check_condition_result;
+ }
}
/* Handle implicit open of closed and empty zones */
--
2.55.0
next prev parent reply other threads:[~2026-09-18 6:29 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-18 6:29 [PATCH v4 00/10] scsi: scsi_debug: fix zoned write validation Niklas Cassel
2026-09-18 6:29 ` [PATCH v4 01/10] scsi: scsi_debug: Refuse a zoned device with a non-zero lowest aligned LBA Niklas Cassel
2026-09-18 9:26 ` Damien Le Moal
2026-09-18 6:29 ` [PATCH v4 02/10] scsi: scsi_debug: Make atomic writes and ZBC emulation mutually exclusive Niklas Cassel
2026-09-18 7:21 ` John Garry
2026-09-18 9:26 ` Damien Le Moal
2026-09-18 6:29 ` [PATCH v4 03/10] scsi: scsi_debug: Take the zone metadata lock before the data lock Niklas Cassel
2026-09-18 9:28 ` Damien Le Moal
2026-09-18 6:29 ` [PATCH v4 04/10] scsi: scsi_debug: Evaluate scsi_debug_lbp() only once Niklas Cassel
2026-09-18 9:29 ` Damien Le Moal
2026-09-18 6:29 ` [PATCH v4 05/10] scsi: scsi_debug: Report the residual of a write Niklas Cassel
2026-09-18 6:29 ` Niklas Cassel [this message]
2026-09-18 6:29 ` [PATCH v4 07/10] scsi: scsi_debug: Do not write a partial physical block to a zoned device Niklas Cassel
2026-09-18 9:31 ` Damien Le Moal
2026-09-18 10:25 ` Niklas Cassel
2026-09-18 6:29 ` [PATCH v4 08/10] scsi: scsi_debug: Advance the write pointer over the data written Niklas Cassel
2026-09-18 6:29 ` [PATCH v4 09/10] scsi: scsi_debug: Map the region written by WRITE ATOMIC (16) Niklas Cassel
2026-09-18 7:29 ` John Garry
2026-09-18 8:09 ` Niklas Cassel
2026-09-18 6:29 ` [PATCH v4 10/10] scsi: scsi_debug: Validate the access parameters of " Niklas Cassel
2026-09-18 7:33 ` John Garry
2026-09-18 7:53 ` Niklas Cassel
2026-09-18 8:19 ` John Garry
2026-09-18 8:55 ` Niklas Cassel
2026-09-18 9:32 ` 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=20260918062910.1709791-18-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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox