Adding write_same16 to CAM Target Layer

Kenneth D. Merry ken at freebsd.org
Fri Mar 28 19:04:35 UTC 2014


On Wed, Mar 26, 2014 at 11:44:32 +0530, bharat singh wrote:
> Hello,
> 
> I am trying to add write_same16 (block zero) support to my FC stack.
> This i am trying to achieve by adding a hook in CTL layer, reading
> start_LBA and no of blocks to fill with 0.
> 
> struct ctl_scsiio {
> >-------struct ctl_io_hdr io_hdr;>------/* common to all I/O types */
> >-------uint32_t   ext_sg_entries;>-----/* 0 = no S/G list, > 0 = num
> entries */
> >-------uint8_t>   *ext_data_ptr;>------/* data buffer or S/G list */
> >-------uint32_t   ext_data_len;>-------/* Data transfer length */
> >-------uint32_t   ext_data_filled;>----/* Amount of data filled so far */
> >-------uint32_t   kern_sg_entries;>----/* 0 = no S/G list, > 0 = num
> entries */
> >-------uint32_t   rem_sg_entries;>-----/* 0 = no S/G list, > 0 = num
> entries */
> >-------uint8_t    *kern_data_ptr;>-----/* data buffer or S/G list */
> >-------uint32_t   kern_data_len;>------/* Length of this S/G list/buffer */
> >-------uint32_t   kern_total_len;>-----/* Total length of this transaction
> */
> >-------uint32_t   kern_data_resid;>----/* Length left to transfer after
> this*/
> >-------uint32_t   kern_rel_offset;>----/* Byte Offset of this transfer */
> >-------struct     scsi_sense_data sense_data;>-/* sense data */
> >-------uint8_t>   sense_len;>-->-------/* Returned sense length */
> >-------uint8_t>   scsi_status;>>-------/* SCSI status byte */
> >-------uint8_t>   sense_residual;>-----/* sense residual length */
> >-------uint32_t   residual;>--->-------/* data residual length */
> >-------uint32_t   tag_num;>---->-------/* tag number */
> >-------ctl_tag_type tag_type;>->-------/* simple, ordered, head of
> queue,etc.*/
> >-------uint8_t    cdb_len;>---->-------/* CDB length */
> >-------uint8_t>   cdb[CTL_MAX_CDBLEN];>/* CDB */
> >-------int>----   (*be_move_done)(union ctl_io *io); /* called by fe */
> >-------int        (*io_cont)(union ctl_io *io); /* to continue processing
> */
> >-------uint32_t   ctl_lun_masking_disabled; /* Disable lun mask checks for
> ctladm calls */
> };
> 
> For write_same16 initiators will send a block of 0s with start_LBA and no
> of blocks. Assuming that I am trying to:
> datalen = blocksize * num_blocks;
> uint8_t * databuf = malloc(datalen);
> bzero(databuf, 0, datalen);
> ctsio->kern_data_ptr = dataptr;
> ctsio->kern_data_len = datalen;
> lbalen.lba = lba;
> lbalen.len = num_blocks;
> memcpy(ctsio->io_hdr.ctl_private[CTL_PRIV_LBA_LEN].bytes, &lbalen,
> sizeof(lbalen));
> ret = lun->backend->data_submit((union ctl_io *)ctsio);
> 
> but it's failing in ISP layer with data overflow. My initiator is sending
> 2048 blocks of size 512B each and a payload of 512 bytes in data-out buffer.
> isp0: isp_target_start_ctio: [0x120154] data overflow by 1048064 bytes
> (1:3:0:1): WRITE SAME(16). CDB: 93 00 00 00 00 00 00 1f e8 00 00 00 08 00
> 00 00
> 
> Have any one done changes to the CTL read/write path, am I missing
> something regarding buffer population.
> Thanks for the help in advance.

What back end are you using?  The block backend, or are you writing your
own?

In the case of the block backend, it is expecting to do its own memory
allocation and then call ctl_datamove() to trigger the DMA.

In this case, you're doing a malloc, but if you're going to the block
backend the data buffer will get overwritten.

As for why you're getting an overrun, the amount of the overrun is 1048064
bytes.  That is 512 less than 1048576.  Is your blocksize and number of
blocks set correctly?  It looks like datalen is probably 512, but your
initiator is sending 1MB.

Ken
-- 
Kenneth Merry
ken at FreeBSD.ORG


More information about the freebsd-scsi mailing list