svn commit: r350378 - in head/sys/cam: ctl scsi
Alexander Motin
mav at FreeBSD.org
Sat Jul 27 17:27:27 UTC 2019
Author: mav
Date: Sat Jul 27 17:27:26 2019
New Revision: 350378
URL: https://svnweb.freebsd.org/changeset/base/350378
Log:
Allow WRITE SAME handle more then 2^^32 blocks.
If not limited by write_same_max_lba option, split operation into several
2^^31 blocks chunks in a loop. For large disks it may take a while, so
setting write_same_max_lba may be useful to avoid timeouts.
While there, fix build with CAM_CTL_DEBUG.
MFC after: 2 weeks
Modified:
head/sys/cam/ctl/ctl.c
head/sys/cam/scsi/scsi_all.h
Modified: head/sys/cam/ctl/ctl.c
==============================================================================
--- head/sys/cam/ctl/ctl.c Sat Jul 27 17:24:19 2019 (r350377)
+++ head/sys/cam/ctl/ctl.c Sat Jul 27 17:27:26 2019 (r350378)
@@ -1438,7 +1438,7 @@ ctl_isc_event_handler(ctl_ha_channel channel, ctl_ha_e
return;
}
- CTL_DEBUG_PRINT(("CTL: msg_type %d\n", msg->msg_type));
+ CTL_DEBUG_PRINT(("CTL: msg_type %d\n", msg->hdr.msg_type));
switch (msg->hdr.msg_type) {
case CTL_MSG_SERIALIZE:
io = ctl_alloc_io(softc->othersc_pool);
@@ -5685,12 +5685,36 @@ ctl_write_buffer(struct ctl_scsiio *ctsio)
return (CTL_RETVAL_COMPLETE);
}
+static int
+ctl_write_same_cont(union ctl_io *io)
+{
+ struct ctl_lun *lun = CTL_LUN(io);
+ struct ctl_scsiio *ctsio;
+ struct ctl_lba_len_flags *lbalen;
+ int retval;
+
+ ctsio = &io->scsiio;
+ ctsio->io_hdr.status = CTL_STATUS_NONE;
+ lbalen = (struct ctl_lba_len_flags *)
+ &ctsio->io_hdr.ctl_private[CTL_PRIV_LBA_LEN];
+ lbalen->lba += lbalen->len;
+ if ((lun->be_lun->maxlba + 1) - lbalen->lba <= UINT32_MAX) {
+ ctsio->io_hdr.flags &= ~CTL_FLAG_IO_CONT;
+ lbalen->len = (lun->be_lun->maxlba + 1) - lbalen->lba;
+ }
+
+ CTL_DEBUG_PRINT(("ctl_write_same_cont: calling config_write()\n"));
+ retval = lun->backend->config_write((union ctl_io *)ctsio);
+ return (retval);
+}
+
int
ctl_write_same(struct ctl_scsiio *ctsio)
{
struct ctl_lun *lun = CTL_LUN(ctsio);
struct ctl_lba_len_flags *lbalen;
- uint64_t lba;
+ const char *val;
+ uint64_t lba, ival;
uint32_t num_blocks;
int len, retval;
uint8_t byte2;
@@ -5754,17 +5778,25 @@ ctl_write_same(struct ctl_scsiio *ctsio)
/* Zero number of blocks means "to the last logical block" */
if (num_blocks == 0) {
- if ((lun->be_lun->maxlba + 1) - lba > UINT32_MAX) {
+ ival = UINT64_MAX;
+ val = dnvlist_get_string(lun->be_lun->options,
+ "write_same_max_lba", NULL);
+ if (val != NULL)
+ ctl_expand_number(val, &ival);
+ if ((lun->be_lun->maxlba + 1) - lba > ival) {
ctl_set_invalid_field(ctsio,
- /*sks_valid*/ 0,
- /*command*/ 1,
- /*field*/ 0,
- /*bit_valid*/ 0,
- /*bit*/ 0);
+ /*sks_valid*/ 1, /*command*/ 1,
+ /*field*/ ctsio->cdb[0] == WRITE_SAME_10 ? 7 : 10,
+ /*bit_valid*/ 0, /*bit*/ 0);
ctl_done((union ctl_io *)ctsio);
return (CTL_RETVAL_COMPLETE);
}
- num_blocks = (lun->be_lun->maxlba + 1) - lba;
+ if ((lun->be_lun->maxlba + 1) - lba > UINT32_MAX) {
+ ctsio->io_hdr.flags |= CTL_FLAG_IO_CONT;
+ ctsio->io_cont = ctl_write_same_cont;
+ num_blocks = 1 << 31;
+ } else
+ num_blocks = (lun->be_lun->maxlba + 1) - lba;
}
len = lun->be_lun->blocksize;
@@ -9876,6 +9908,8 @@ ctl_inquiry_evpd_block_limits(struct ctl_scsiio *ctsio
if (val != NULL)
ctl_expand_number(val, &ival);
scsi_u64to8b(ival, bl_ptr->max_write_same_length);
+ if (lun->be_lun->maxlba + 1 > ival)
+ bl_ptr->flags |= SVPD_BL_WSNZ;
}
ctl_set_success(ctsio);
@@ -11322,7 +11356,7 @@ ctl_failover_lun(union ctl_io *rio)
uint32_t targ_lun;
targ_lun = rio->io_hdr.nexus.targ_mapped_lun;
- CTL_DEBUG_PRINT(("FAILOVER for lun %ju\n", targ_lun));
+ CTL_DEBUG_PRINT(("FAILOVER for lun %u\n", targ_lun));
/* Find and lock the LUN. */
mtx_lock(&softc->ctl_lock);
Modified: head/sys/cam/scsi/scsi_all.h
==============================================================================
--- head/sys/cam/scsi/scsi_all.h Sat Jul 27 17:24:19 2019 (r350377)
+++ head/sys/cam/scsi/scsi_all.h Sat Jul 27 17:27:26 2019 (r350378)
@@ -2886,7 +2886,7 @@ struct scsi_vpd_logical_block_prov
};
/*
- * Block Limits VDP Page based on SBC-4 Revision 2
+ * Block Limits VDP Page based on SBC-4 Revision 17
*/
struct scsi_vpd_block_limits
{
@@ -2896,7 +2896,8 @@ struct scsi_vpd_block_limits
u_int8_t page_length[2];
#define SVPD_BL_PL_BASIC 0x10
#define SVPD_BL_PL_TP 0x3C
- u_int8_t reserved1;
+ u_int8_t flags;
+#define SVPD_BL_WSNZ 0x01
u_int8_t max_cmp_write_len;
u_int8_t opt_txfer_len_grain[2];
u_int8_t max_txfer_len[4];
More information about the svn-src-all
mailing list