Deleted Added
full compact
43c43
< __FBSDID("$FreeBSD: head/sys/cam/ctl/ctl_backend_block.c 267519 2014-06-15 20:14:11Z mav $");
---
> __FBSDID("$FreeBSD: head/sys/cam/ctl/ctl_backend_block.c 267537 2014-06-16 11:00:14Z mav $");
95c95,96
< #define CTLBLK_MAX_IO_SIZE (1024 * 1024)
---
> #define CTLBLK_HALF_IO_SIZE (512 * 1024)
> #define CTLBLK_MAX_IO_SIZE (CTLBLK_HALF_IO_SIZE * 2)
97c98,99
< #define CTLBLK_MAX_SEGS MAX(CTLBLK_MAX_IO_SIZE / CTLBLK_MAX_SEG, 1)
---
> #define CTLBLK_HALF_SEGS MAX(CTLBLK_HALF_IO_SIZE / CTLBLK_MAX_SEG, 1)
> #define CTLBLK_MAX_SEGS (CTLBLK_HALF_SEGS * 2)
107a110,111
> #define ARGS(io) \
> ((struct ctl_lba_len_flags *)&(io)->io_hdr.ctl_private[CTL_PRIV_LBA_LEN])
314a319,325
>
> /* For compare we had two equal S/G lists. */
> if (ARGS(beio->io)->flags & CTL_LLF_COMPARE) {
> uma_zfree(beio->lun->lun_zone,
> beio->sg_segs[i + CTLBLK_HALF_SEGS].addr);
> beio->sg_segs[i + CTLBLK_HALF_SEGS].addr = NULL;
> }
349c360
< ctl_done(io);
---
> ctl_data_submit_done(io);
357a369
> struct ctl_lba_len_flags *lbalen;
360c372,373
< #endif
---
> #endif
> int i;
372a386
> io->scsiio.kern_rel_offset += io->scsiio.kern_data_len;
378,382c392,416
< if ((beio->bio_cmd == BIO_READ)
< && (io->io_hdr.port_status == 0)
< && ((io->io_hdr.flags & CTL_FLAG_ABORT) == 0)
< && ((io->io_hdr.status & CTL_STATUS_MASK) == CTL_STATUS_NONE))
< ctl_set_success(&io->scsiio);
---
> if ((io->io_hdr.port_status == 0) &&
> ((io->io_hdr.flags & CTL_FLAG_ABORT) == 0) &&
> ((io->io_hdr.status & CTL_STATUS_MASK) == CTL_STATUS_NONE)) {
> lbalen = ARGS(beio->io);
> if (lbalen->flags & CTL_LLF_READ) {
> ctl_set_success(&io->scsiio);
> } else if (lbalen->flags & CTL_LLF_COMPARE) {
> /* We have two data blocks ready for comparison. */
> for (i = 0; i < beio->num_segs; i++) {
> if (memcmp(beio->sg_segs[i].addr,
> beio->sg_segs[i + CTLBLK_HALF_SEGS].addr,
> beio->sg_segs[i].len) != 0)
> break;
> }
> if (i < beio->num_segs)
> ctl_set_sense(&io->scsiio,
> /*current_error*/ 1,
> /*sense_key*/ SSD_KEY_MISCOMPARE,
> /*asc*/ 0x1D,
> /*ascq*/ 0x00,
> SSD_ELEM_NONE);
> else
> ctl_set_success(&io->scsiio);
> }
> }
494c528
< * If this is a write, a flush or a delete, we're all done.
---
> * If this is a write, a flush, a delete or verify, we're all done.
499c533,534
< || (beio->bio_cmd == BIO_DELETE)) {
---
> || (beio->bio_cmd == BIO_DELETE)
> || (ARGS(io)->flags & CTL_LLF_VERIFY)) {
574a610
> bzero(&xuio, sizeof(xuio));
576a613
> xuio.uio_rw = UIO_READ;
579,584d615
< }
<
< bzero(&xuio, sizeof(xuio));
< if (beio->bio_cmd == BIO_READ)
< xuio.uio_rw = UIO_READ;
< else
586c617
<
---
> }
628a660
> SDT_PROBE(cbb, kernel, read, file_done, 0, 0, 0, 0, 0);
669a702
> SDT_PROBE(cbb, kernel, write, file_done, 0, 0, 0, 0, 0);
696c729
< if (beio->bio_cmd == BIO_WRITE) {
---
> if (ARGS(io)->flags & (CTL_LLF_WRITE | CTL_LLF_VERIFY)) {
698d730
< SDT_PROBE(cbb, kernel, write, file_done, 0, 0, 0, 0, 0);
701d732
< SDT_PROBE(cbb, kernel, read, file_done, 0, 0, 0, 0, 0);
938c969
< lbalen = (struct ctl_lba_len_flags *)&io->io_hdr.ctl_private[CTL_PRIV_LBA_LEN];
---
> lbalen = ARGS(beio->io);
1158c1189
< ctl_done(io);
---
> ctl_data_submit_done(io);
1162d1192
< io->scsiio.kern_rel_offset += io->scsiio.kern_data_len;
1184c1214
< struct ctl_lba_len *lbalen;
---
> struct ctl_lba_len_flags *lbalen;
1193,1195c1223,1224
< if ((io->io_hdr.flags & CTL_FLAG_DATA_MASK) == CTL_FLAG_DATA_IN) {
< SDT_PROBE(cbb, kernel, read, start, 0, 0, 0, 0, 0);
< } else {
---
> lbalen = ARGS(io);
> if (lbalen->flags & CTL_LLF_WRITE) {
1196a1226,1227
> } else {
> SDT_PROBE(cbb, kernel, read, start, 0, 0, 0, 0, 0);
1234,1241c1265
< /*
< * This path handles read and write only. The config write path
< * handles flush operations.
< */
< if ((io->io_hdr.flags & CTL_FLAG_DATA_MASK) == CTL_FLAG_DATA_IN) {
< beio->bio_cmd = BIO_READ;
< beio->ds_trans_type = DEVSTAT_READ;
< } else {
---
> if (lbalen->flags & CTL_LLF_WRITE) {
1243a1268,1270
> } else {
> beio->bio_cmd = BIO_READ;
> beio->ds_trans_type = DEVSTAT_READ;
1246d1272
< lbalen = (struct ctl_lba_len *)&io->io_hdr.ctl_private[CTL_PRIV_LBA_LEN];
1250,1251c1276,1280
< lbas = MIN(lbalen->len - bptrlen->len,
< CTLBLK_MAX_IO_SIZE / be_lun->blocksize);
---
> if (lbalen->flags & CTL_LLF_COMPARE)
> lbas = CTLBLK_HALF_IO_SIZE;
> else
> lbas = CTLBLK_MAX_IO_SIZE;
> lbas = MIN(lbalen->len - bptrlen->len, lbas / be_lun->blocksize);
1268a1298,1305
> /* Set up second segment for compare operation. */
> if (lbalen->flags & CTL_LLF_COMPARE) {
> beio->sg_segs[i + CTLBLK_HALF_SEGS].len =
> beio->sg_segs[i].len;
> beio->sg_segs[i + CTLBLK_HALF_SEGS].addr =
> uma_zalloc(be_lun->lun_zone, M_WAITOK);
> }
>
1275c1312,1316
< io->scsiio.kern_data_ptr = (uint8_t *)beio->sg_segs;
---
> /* For compare we have separate S/G lists for read and datamove. */
> if (lbalen->flags & CTL_LLF_COMPARE)
> io->scsiio.kern_data_ptr = (uint8_t *)&beio->sg_segs[CTLBLK_HALF_SEGS];
> else
> io->scsiio.kern_data_ptr = (uint8_t *)beio->sg_segs;