Deleted Added
full compact
ctl_backend_block.c (267519) ctl_backend_block.c (267537)
1/*-
2 * Copyright (c) 2003 Silicon Graphics International Corp.
3 * Copyright (c) 2009-2011 Spectra Logic Corporation
4 * Copyright (c) 2012 The FreeBSD Foundation
5 * All rights reserved.
6 *
7 * Portions of this software were developed by Edward Tomasz Napierala
8 * under sponsorship from the FreeBSD Foundation.

--- 26 unchanged lines hidden (view full) ---

35 * $Id: //depot/users/kenm/FreeBSD-test2/sys/cam/ctl/ctl_backend_block.c#5 $
36 */
37/*
38 * CAM Target Layer driver backend for block devices.
39 *
40 * Author: Ken Merry <ken@FreeBSD.org>
41 */
42#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 2003 Silicon Graphics International Corp.
3 * Copyright (c) 2009-2011 Spectra Logic Corporation
4 * Copyright (c) 2012 The FreeBSD Foundation
5 * All rights reserved.
6 *
7 * Portions of this software were developed by Edward Tomasz Napierala
8 * under sponsorship from the FreeBSD Foundation.

--- 26 unchanged lines hidden (view full) ---

35 * $Id: //depot/users/kenm/FreeBSD-test2/sys/cam/ctl/ctl_backend_block.c#5 $
36 */
37/*
38 * CAM Target Layer driver backend for block devices.
39 *
40 * Author: Ken Merry <ken@FreeBSD.org>
41 */
42#include <sys/cdefs.h>
43__FBSDID("$FreeBSD: head/sys/cam/ctl/ctl_backend_block.c 267519 2014-06-15 20:14:11Z mav $");
43__FBSDID("$FreeBSD: head/sys/cam/ctl/ctl_backend_block.c 267537 2014-06-16 11:00:14Z mav $");
44
45#include <sys/param.h>
46#include <sys/systm.h>
47#include <sys/kernel.h>
48#include <sys/types.h>
49#include <sys/kthread.h>
50#include <sys/bio.h>
51#include <sys/fcntl.h>

--- 35 unchanged lines hidden (view full) ---

87#include <cam/ctl/ctl_ioctl.h>
88#include <cam/ctl/ctl_scsi_all.h>
89#include <cam/ctl/ctl_error.h>
90
91/*
92 * The idea here is that we'll allocate enough S/G space to hold a 1MB
93 * I/O. If we get an I/O larger than that, we'll split it.
94 */
44
45#include <sys/param.h>
46#include <sys/systm.h>
47#include <sys/kernel.h>
48#include <sys/types.h>
49#include <sys/kthread.h>
50#include <sys/bio.h>
51#include <sys/fcntl.h>

--- 35 unchanged lines hidden (view full) ---

87#include <cam/ctl/ctl_ioctl.h>
88#include <cam/ctl/ctl_scsi_all.h>
89#include <cam/ctl/ctl_error.h>
90
91/*
92 * The idea here is that we'll allocate enough S/G space to hold a 1MB
93 * I/O. If we get an I/O larger than that, we'll split it.
94 */
95#define CTLBLK_MAX_IO_SIZE (1024 * 1024)
95#define CTLBLK_HALF_IO_SIZE (512 * 1024)
96#define CTLBLK_MAX_IO_SIZE (CTLBLK_HALF_IO_SIZE * 2)
96#define CTLBLK_MAX_SEG MAXPHYS
97#define CTLBLK_MAX_SEG MAXPHYS
97#define CTLBLK_MAX_SEGS MAX(CTLBLK_MAX_IO_SIZE / CTLBLK_MAX_SEG, 1)
98#define CTLBLK_HALF_SEGS MAX(CTLBLK_HALF_IO_SIZE / CTLBLK_MAX_SEG, 1)
99#define CTLBLK_MAX_SEGS (CTLBLK_HALF_SEGS * 2)
98
99#ifdef CTLBLK_DEBUG
100#define DPRINTF(fmt, args...) \
101 printf("cbb(%s:%d): " fmt, __FUNCTION__, __LINE__, ##args)
102#else
103#define DPRINTF(fmt, args...) do {} while(0)
104#endif
105
106#define PRIV(io) \
107 ((struct ctl_ptr_len_flags *)&(io)->io_hdr.ctl_private[CTL_PRIV_BACKEND])
100
101#ifdef CTLBLK_DEBUG
102#define DPRINTF(fmt, args...) \
103 printf("cbb(%s:%d): " fmt, __FUNCTION__, __LINE__, ##args)
104#else
105#define DPRINTF(fmt, args...) do {} while(0)
106#endif
107
108#define PRIV(io) \
109 ((struct ctl_ptr_len_flags *)&(io)->io_hdr.ctl_private[CTL_PRIV_BACKEND])
110#define ARGS(io) \
111 ((struct ctl_lba_len_flags *)&(io)->io_hdr.ctl_private[CTL_PRIV_LBA_LEN])
108
109SDT_PROVIDER_DEFINE(cbb);
110
111typedef enum {
112 CTL_BE_BLOCK_LUN_UNCONFIGURED = 0x01,
113 CTL_BE_BLOCK_LUN_CONFIG_ERR = 0x02,
114 CTL_BE_BLOCK_LUN_WAITING = 0x04,
115 CTL_BE_BLOCK_LUN_MULTI_THREAD = 0x08

--- 191 unchanged lines hidden (view full) ---

307 duplicate_free = 0;
308
309 for (i = 0; i < beio->num_segs; i++) {
310 if (beio->sg_segs[i].addr == NULL)
311 duplicate_free++;
312
313 uma_zfree(beio->lun->lun_zone, beio->sg_segs[i].addr);
314 beio->sg_segs[i].addr = NULL;
112
113SDT_PROVIDER_DEFINE(cbb);
114
115typedef enum {
116 CTL_BE_BLOCK_LUN_UNCONFIGURED = 0x01,
117 CTL_BE_BLOCK_LUN_CONFIG_ERR = 0x02,
118 CTL_BE_BLOCK_LUN_WAITING = 0x04,
119 CTL_BE_BLOCK_LUN_MULTI_THREAD = 0x08

--- 191 unchanged lines hidden (view full) ---

311 duplicate_free = 0;
312
313 for (i = 0; i < beio->num_segs; i++) {
314 if (beio->sg_segs[i].addr == NULL)
315 duplicate_free++;
316
317 uma_zfree(beio->lun->lun_zone, beio->sg_segs[i].addr);
318 beio->sg_segs[i].addr = NULL;
319
320 /* For compare we had two equal S/G lists. */
321 if (ARGS(beio->io)->flags & CTL_LLF_COMPARE) {
322 uma_zfree(beio->lun->lun_zone,
323 beio->sg_segs[i + CTLBLK_HALF_SEGS].addr);
324 beio->sg_segs[i + CTLBLK_HALF_SEGS].addr = NULL;
325 }
315 }
316
317 if (duplicate_free > 0) {
318 printf("%s: %d duplicate frees out of %d segments\n", __func__,
319 duplicate_free, beio->num_segs);
320 }
321
322 uma_zfree(beio_zone, beio);

--- 18 unchanged lines hidden (view full) ---

341 beio->ds_trans_type,
342 /*now*/ NULL,
343 /*then*/&beio->ds_t0);
344
345 if (beio->beio_cont != NULL) {
346 beio->beio_cont(beio);
347 } else {
348 ctl_free_beio(beio);
326 }
327
328 if (duplicate_free > 0) {
329 printf("%s: %d duplicate frees out of %d segments\n", __func__,
330 duplicate_free, beio->num_segs);
331 }
332
333 uma_zfree(beio_zone, beio);

--- 18 unchanged lines hidden (view full) ---

352 beio->ds_trans_type,
353 /*now*/ NULL,
354 /*then*/&beio->ds_t0);
355
356 if (beio->beio_cont != NULL) {
357 beio->beio_cont(beio);
358 } else {
359 ctl_free_beio(beio);
349 ctl_done(io);
360 ctl_data_submit_done(io);
350 }
351}
352
353static int
354ctl_be_block_move_done(union ctl_io *io)
355{
356 struct ctl_be_block_io *beio;
357 struct ctl_be_block_lun *be_lun;
361 }
362}
363
364static int
365ctl_be_block_move_done(union ctl_io *io)
366{
367 struct ctl_be_block_io *beio;
368 struct ctl_be_block_lun *be_lun;
369 struct ctl_lba_len_flags *lbalen;
358#ifdef CTL_TIME_IO
359 struct bintime cur_bt;
370#ifdef CTL_TIME_IO
371 struct bintime cur_bt;
360#endif
372#endif
373 int i;
361
362 beio = (struct ctl_be_block_io *)PRIV(io)->ptr;
363 be_lun = beio->lun;
364
365 DPRINTF("entered\n");
366
367#ifdef CTL_TIME_IO
368 getbintime(&cur_bt);
369 bintime_sub(&cur_bt, &io->io_hdr.dma_start_bt);
370 bintime_add(&io->io_hdr.dma_bt, &cur_bt);
371 io->io_hdr.num_dmas++;
372#endif
374
375 beio = (struct ctl_be_block_io *)PRIV(io)->ptr;
376 be_lun = beio->lun;
377
378 DPRINTF("entered\n");
379
380#ifdef CTL_TIME_IO
381 getbintime(&cur_bt);
382 bintime_sub(&cur_bt, &io->io_hdr.dma_start_bt);
383 bintime_add(&io->io_hdr.dma_bt, &cur_bt);
384 io->io_hdr.num_dmas++;
385#endif
386 io->scsiio.kern_rel_offset += io->scsiio.kern_data_len;
373
374 /*
375 * We set status at this point for read commands, and write
376 * commands with errors.
377 */
387
388 /*
389 * We set status at this point for read commands, and write
390 * commands with errors.
391 */
378 if ((beio->bio_cmd == BIO_READ)
379 && (io->io_hdr.port_status == 0)
380 && ((io->io_hdr.flags & CTL_FLAG_ABORT) == 0)
381 && ((io->io_hdr.status & CTL_STATUS_MASK) == CTL_STATUS_NONE))
382 ctl_set_success(&io->scsiio);
392 if ((io->io_hdr.port_status == 0) &&
393 ((io->io_hdr.flags & CTL_FLAG_ABORT) == 0) &&
394 ((io->io_hdr.status & CTL_STATUS_MASK) == CTL_STATUS_NONE)) {
395 lbalen = ARGS(beio->io);
396 if (lbalen->flags & CTL_LLF_READ) {
397 ctl_set_success(&io->scsiio);
398 } else if (lbalen->flags & CTL_LLF_COMPARE) {
399 /* We have two data blocks ready for comparison. */
400 for (i = 0; i < beio->num_segs; i++) {
401 if (memcmp(beio->sg_segs[i].addr,
402 beio->sg_segs[i + CTLBLK_HALF_SEGS].addr,
403 beio->sg_segs[i].len) != 0)
404 break;
405 }
406 if (i < beio->num_segs)
407 ctl_set_sense(&io->scsiio,
408 /*current_error*/ 1,
409 /*sense_key*/ SSD_KEY_MISCOMPARE,
410 /*asc*/ 0x1D,
411 /*ascq*/ 0x00,
412 SSD_ELEM_NONE);
413 else
414 ctl_set_success(&io->scsiio);
415 }
416 }
383 else if ((io->io_hdr.port_status != 0)
384 && ((io->io_hdr.flags & CTL_FLAG_ABORT) == 0)
385 && ((io->io_hdr.status & CTL_STATUS_MASK) == CTL_STATUS_NONE)) {
386 /*
387 * For hardware error sense keys, the sense key
388 * specific value is defined to be a retry count,
389 * but we use it to pass back an internal FETD
390 * error code. XXX KDM Hopefully the FETD is only

--- 95 unchanged lines hidden (view full) ---

486 /*retry_count*/ 0xbad2);
487 } else
488 ctl_set_medium_error(&io->scsiio);
489 ctl_complete_beio(beio);
490 return;
491 }
492
493 /*
417 else if ((io->io_hdr.port_status != 0)
418 && ((io->io_hdr.flags & CTL_FLAG_ABORT) == 0)
419 && ((io->io_hdr.status & CTL_STATUS_MASK) == CTL_STATUS_NONE)) {
420 /*
421 * For hardware error sense keys, the sense key
422 * specific value is defined to be a retry count,
423 * but we use it to pass back an internal FETD
424 * error code. XXX KDM Hopefully the FETD is only

--- 95 unchanged lines hidden (view full) ---

520 /*retry_count*/ 0xbad2);
521 } else
522 ctl_set_medium_error(&io->scsiio);
523 ctl_complete_beio(beio);
524 return;
525 }
526
527 /*
494 * If this is a write, a flush or a delete, we're all done.
528 * If this is a write, a flush, a delete or verify, we're all done.
495 * If this is a read, we can now send the data to the user.
496 */
497 if ((beio->bio_cmd == BIO_WRITE)
498 || (beio->bio_cmd == BIO_FLUSH)
529 * If this is a read, we can now send the data to the user.
530 */
531 if ((beio->bio_cmd == BIO_WRITE)
532 || (beio->bio_cmd == BIO_FLUSH)
499 || (beio->bio_cmd == BIO_DELETE)) {
533 || (beio->bio_cmd == BIO_DELETE)
534 || (ARGS(io)->flags & CTL_LLF_VERIFY)) {
500 ctl_set_success(&io->scsiio);
501 ctl_complete_beio(beio);
502 } else {
503#ifdef CTL_TIME_IO
504 getbintime(&io->io_hdr.dma_start_bt);
505#endif
506 ctl_datamove(io);
507 }

--- 59 unchanged lines hidden (view full) ---

567 int error, i;
568
569 DPRINTF("entered\n");
570
571 file_data = &be_lun->backend.file;
572 io = beio->io;
573 flags = beio->bio_flags;
574
535 ctl_set_success(&io->scsiio);
536 ctl_complete_beio(beio);
537 } else {
538#ifdef CTL_TIME_IO
539 getbintime(&io->io_hdr.dma_start_bt);
540#endif
541 ctl_datamove(io);
542 }

--- 59 unchanged lines hidden (view full) ---

602 int error, i;
603
604 DPRINTF("entered\n");
605
606 file_data = &be_lun->backend.file;
607 io = beio->io;
608 flags = beio->bio_flags;
609
610 bzero(&xuio, sizeof(xuio));
575 if (beio->bio_cmd == BIO_READ) {
576 SDT_PROBE(cbb, kernel, read, file_start, 0, 0, 0, 0, 0);
611 if (beio->bio_cmd == BIO_READ) {
612 SDT_PROBE(cbb, kernel, read, file_start, 0, 0, 0, 0, 0);
613 xuio.uio_rw = UIO_READ;
577 } else {
578 SDT_PROBE(cbb, kernel, write, file_start, 0, 0, 0, 0, 0);
614 } else {
615 SDT_PROBE(cbb, kernel, write, file_start, 0, 0, 0, 0, 0);
579 }
580
581 bzero(&xuio, sizeof(xuio));
582 if (beio->bio_cmd == BIO_READ)
583 xuio.uio_rw = UIO_READ;
584 else
585 xuio.uio_rw = UIO_WRITE;
616 xuio.uio_rw = UIO_WRITE;
586
617 }
587 xuio.uio_offset = beio->io_offset;
588 xuio.uio_resid = beio->io_len;
589 xuio.uio_segflg = UIO_SYSSPACE;
590 xuio.uio_iov = beio->xiovecs;
591 xuio.uio_iovcnt = beio->num_segs;
592 xuio.uio_td = curthread;
593
594 for (i = 0, xiovec = xuio.uio_iov; i < xuio.uio_iovcnt; i++, xiovec++) {

--- 26 unchanged lines hidden (view full) ---

621 *
622 * So, to attempt to provide some barrier semantics in the
623 * BIO_ORDERED case, set both IO_DIRECT and IO_SYNC.
624 */
625 error = VOP_READ(be_lun->vn, &xuio, (flags & BIO_ORDERED) ?
626 (IO_DIRECT|IO_SYNC) : 0, file_data->cred);
627
628 VOP_UNLOCK(be_lun->vn, 0);
618 xuio.uio_offset = beio->io_offset;
619 xuio.uio_resid = beio->io_len;
620 xuio.uio_segflg = UIO_SYSSPACE;
621 xuio.uio_iov = beio->xiovecs;
622 xuio.uio_iovcnt = beio->num_segs;
623 xuio.uio_td = curthread;
624
625 for (i = 0, xiovec = xuio.uio_iov; i < xuio.uio_iovcnt; i++, xiovec++) {

--- 26 unchanged lines hidden (view full) ---

652 *
653 * So, to attempt to provide some barrier semantics in the
654 * BIO_ORDERED case, set both IO_DIRECT and IO_SYNC.
655 */
656 error = VOP_READ(be_lun->vn, &xuio, (flags & BIO_ORDERED) ?
657 (IO_DIRECT|IO_SYNC) : 0, file_data->cred);
658
659 VOP_UNLOCK(be_lun->vn, 0);
660 SDT_PROBE(cbb, kernel, read, file_done, 0, 0, 0, 0, 0);
629 } else {
630 struct mount *mountpoint;
631 int lock_flags;
632
633 (void)vn_start_write(be_lun->vn, &mountpoint, V_WAIT);
634
635 if (MNT_SHARED_WRITES(mountpoint)
636 || ((mountpoint == NULL)

--- 25 unchanged lines hidden (view full) ---

662 * So if we've got the BIO_ORDERED flag set, we want
663 * IO_SYNC in either the UFS or ZFS case.
664 */
665 error = VOP_WRITE(be_lun->vn, &xuio, (flags & BIO_ORDERED) ?
666 IO_SYNC : 0, file_data->cred);
667 VOP_UNLOCK(be_lun->vn, 0);
668
669 vn_finished_write(mountpoint);
661 } else {
662 struct mount *mountpoint;
663 int lock_flags;
664
665 (void)vn_start_write(be_lun->vn, &mountpoint, V_WAIT);
666
667 if (MNT_SHARED_WRITES(mountpoint)
668 || ((mountpoint == NULL)

--- 25 unchanged lines hidden (view full) ---

694 * So if we've got the BIO_ORDERED flag set, we want
695 * IO_SYNC in either the UFS or ZFS case.
696 */
697 error = VOP_WRITE(be_lun->vn, &xuio, (flags & BIO_ORDERED) ?
698 IO_SYNC : 0, file_data->cred);
699 VOP_UNLOCK(be_lun->vn, 0);
700
701 vn_finished_write(mountpoint);
702 SDT_PROBE(cbb, kernel, write, file_done, 0, 0, 0, 0, 0);
670 }
671
672 /*
673 * If we got an error, set the sense data to "MEDIUM ERROR" and
674 * return the I/O to the user.
675 */
676 if (error != 0) {
677 char path_str[32];

--- 10 unchanged lines hidden (view full) ---

688 ctl_complete_beio(beio);
689 return;
690 }
691
692 /*
693 * If this is a write, we're all done.
694 * If this is a read, we can now send the data to the user.
695 */
703 }
704
705 /*
706 * If we got an error, set the sense data to "MEDIUM ERROR" and
707 * return the I/O to the user.
708 */
709 if (error != 0) {
710 char path_str[32];

--- 10 unchanged lines hidden (view full) ---

721 ctl_complete_beio(beio);
722 return;
723 }
724
725 /*
726 * If this is a write, we're all done.
727 * If this is a read, we can now send the data to the user.
728 */
696 if (beio->bio_cmd == BIO_WRITE) {
729 if (ARGS(io)->flags & (CTL_LLF_WRITE | CTL_LLF_VERIFY)) {
697 ctl_set_success(&io->scsiio);
730 ctl_set_success(&io->scsiio);
698 SDT_PROBE(cbb, kernel, write, file_done, 0, 0, 0, 0, 0);
699 ctl_complete_beio(beio);
700 } else {
731 ctl_complete_beio(beio);
732 } else {
701 SDT_PROBE(cbb, kernel, read, file_done, 0, 0, 0, 0, 0);
702#ifdef CTL_TIME_IO
703 getbintime(&io->io_hdr.dma_start_bt);
704#endif
705 ctl_datamove(io);
706 }
707}
708
709static void

--- 220 unchanged lines hidden (view full) ---

930 uint64_t len_left, lba;
931 int i, seglen;
932 uint8_t *buf, *end;
933
934 DPRINTF("entered\n");
935
936 beio = (struct ctl_be_block_io *)PRIV(io)->ptr;
937 softc = be_lun->softc;
733#ifdef CTL_TIME_IO
734 getbintime(&io->io_hdr.dma_start_bt);
735#endif
736 ctl_datamove(io);
737 }
738}
739
740static void

--- 220 unchanged lines hidden (view full) ---

961 uint64_t len_left, lba;
962 int i, seglen;
963 uint8_t *buf, *end;
964
965 DPRINTF("entered\n");
966
967 beio = (struct ctl_be_block_io *)PRIV(io)->ptr;
968 softc = be_lun->softc;
938 lbalen = (struct ctl_lba_len_flags *)&io->io_hdr.ctl_private[CTL_PRIV_LBA_LEN];
969 lbalen = ARGS(beio->io);
939
940 if (lbalen->flags & ~(SWS_LBDATA | SWS_UNMAP) ||
941 (lbalen->flags & SWS_UNMAP && be_lun->unmap == NULL)) {
942 ctl_free_beio(beio);
943 ctl_set_invalid_field(&io->scsiio,
944 /*sks_valid*/ 1,
945 /*command*/ 1,
946 /*field*/ 1,

--- 203 unchanged lines hidden (view full) ---

1150 struct ctl_be_block_lun *be_lun;
1151 union ctl_io *io;
1152
1153 io = beio->io;
1154 be_lun = beio->lun;
1155 ctl_free_beio(beio);
1156 if (((io->io_hdr.status & CTL_STATUS_MASK) != CTL_STATUS_NONE)
1157 && ((io->io_hdr.status & CTL_STATUS_MASK) != CTL_SUCCESS)) {
970
971 if (lbalen->flags & ~(SWS_LBDATA | SWS_UNMAP) ||
972 (lbalen->flags & SWS_UNMAP && be_lun->unmap == NULL)) {
973 ctl_free_beio(beio);
974 ctl_set_invalid_field(&io->scsiio,
975 /*sks_valid*/ 1,
976 /*command*/ 1,
977 /*field*/ 1,

--- 203 unchanged lines hidden (view full) ---

1181 struct ctl_be_block_lun *be_lun;
1182 union ctl_io *io;
1183
1184 io = beio->io;
1185 be_lun = beio->lun;
1186 ctl_free_beio(beio);
1187 if (((io->io_hdr.status & CTL_STATUS_MASK) != CTL_STATUS_NONE)
1188 && ((io->io_hdr.status & CTL_STATUS_MASK) != CTL_SUCCESS)) {
1158 ctl_done(io);
1189 ctl_data_submit_done(io);
1159 return;
1160 }
1161
1190 return;
1191 }
1192
1162 io->scsiio.kern_rel_offset += io->scsiio.kern_data_len;
1163 io->io_hdr.status &= ~CTL_STATUS_MASK;
1164 io->io_hdr.status |= CTL_STATUS_NONE;
1165
1166 mtx_lock(&be_lun->lock);
1167 /*
1168 * XXX KDM make sure that links is okay to use at this point.
1169 * Otherwise, we either need to add another field to ctl_io_hdr,
1170 * or deal with resource allocation here.

--- 5 unchanged lines hidden (view full) ---

1176}
1177
1178static void
1179ctl_be_block_dispatch(struct ctl_be_block_lun *be_lun,
1180 union ctl_io *io)
1181{
1182 struct ctl_be_block_io *beio;
1183 struct ctl_be_block_softc *softc;
1193 io->io_hdr.status &= ~CTL_STATUS_MASK;
1194 io->io_hdr.status |= CTL_STATUS_NONE;
1195
1196 mtx_lock(&be_lun->lock);
1197 /*
1198 * XXX KDM make sure that links is okay to use at this point.
1199 * Otherwise, we either need to add another field to ctl_io_hdr,
1200 * or deal with resource allocation here.

--- 5 unchanged lines hidden (view full) ---

1206}
1207
1208static void
1209ctl_be_block_dispatch(struct ctl_be_block_lun *be_lun,
1210 union ctl_io *io)
1211{
1212 struct ctl_be_block_io *beio;
1213 struct ctl_be_block_softc *softc;
1184 struct ctl_lba_len *lbalen;
1214 struct ctl_lba_len_flags *lbalen;
1185 struct ctl_ptr_len_flags *bptrlen;
1186 uint64_t len_left, lbas;
1187 int i;
1188
1189 softc = be_lun->softc;
1190
1191 DPRINTF("entered\n");
1192
1215 struct ctl_ptr_len_flags *bptrlen;
1216 uint64_t len_left, lbas;
1217 int i;
1218
1219 softc = be_lun->softc;
1220
1221 DPRINTF("entered\n");
1222
1193 if ((io->io_hdr.flags & CTL_FLAG_DATA_MASK) == CTL_FLAG_DATA_IN) {
1194 SDT_PROBE(cbb, kernel, read, start, 0, 0, 0, 0, 0);
1195 } else {
1223 lbalen = ARGS(io);
1224 if (lbalen->flags & CTL_LLF_WRITE) {
1196 SDT_PROBE(cbb, kernel, write, start, 0, 0, 0, 0, 0);
1225 SDT_PROBE(cbb, kernel, write, start, 0, 0, 0, 0, 0);
1226 } else {
1227 SDT_PROBE(cbb, kernel, read, start, 0, 0, 0, 0, 0);
1197 }
1198
1199 beio = ctl_alloc_beio(softc);
1200 beio->io = io;
1201 beio->lun = be_lun;
1202 bptrlen = PRIV(io);
1203 bptrlen->ptr = (void *)beio;
1204

--- 21 unchanged lines hidden (view full) ---

1226 case CTL_TAG_UNTAGGED:
1227 case CTL_TAG_SIMPLE:
1228 case CTL_TAG_ACA:
1229 default:
1230 beio->ds_tag_type = DEVSTAT_TAG_SIMPLE;
1231 break;
1232 }
1233
1228 }
1229
1230 beio = ctl_alloc_beio(softc);
1231 beio->io = io;
1232 beio->lun = be_lun;
1233 bptrlen = PRIV(io);
1234 bptrlen->ptr = (void *)beio;
1235

--- 21 unchanged lines hidden (view full) ---

1257 case CTL_TAG_UNTAGGED:
1258 case CTL_TAG_SIMPLE:
1259 case CTL_TAG_ACA:
1260 default:
1261 beio->ds_tag_type = DEVSTAT_TAG_SIMPLE;
1262 break;
1263 }
1264
1234 /*
1235 * This path handles read and write only. The config write path
1236 * handles flush operations.
1237 */
1238 if ((io->io_hdr.flags & CTL_FLAG_DATA_MASK) == CTL_FLAG_DATA_IN) {
1239 beio->bio_cmd = BIO_READ;
1240 beio->ds_trans_type = DEVSTAT_READ;
1241 } else {
1265 if (lbalen->flags & CTL_LLF_WRITE) {
1242 beio->bio_cmd = BIO_WRITE;
1243 beio->ds_trans_type = DEVSTAT_WRITE;
1266 beio->bio_cmd = BIO_WRITE;
1267 beio->ds_trans_type = DEVSTAT_WRITE;
1268 } else {
1269 beio->bio_cmd = BIO_READ;
1270 beio->ds_trans_type = DEVSTAT_READ;
1244 }
1245
1271 }
1272
1246 lbalen = (struct ctl_lba_len *)&io->io_hdr.ctl_private[CTL_PRIV_LBA_LEN];
1247 DPRINTF("%s at LBA %jx len %u @%ju\n",
1248 (beio->bio_cmd == BIO_READ) ? "READ" : "WRITE",
1249 (uintmax_t)lbalen->lba, lbalen->len, bptrlen->len);
1273 DPRINTF("%s at LBA %jx len %u @%ju\n",
1274 (beio->bio_cmd == BIO_READ) ? "READ" : "WRITE",
1275 (uintmax_t)lbalen->lba, lbalen->len, bptrlen->len);
1250 lbas = MIN(lbalen->len - bptrlen->len,
1251 CTLBLK_MAX_IO_SIZE / be_lun->blocksize);
1276 if (lbalen->flags & CTL_LLF_COMPARE)
1277 lbas = CTLBLK_HALF_IO_SIZE;
1278 else
1279 lbas = CTLBLK_MAX_IO_SIZE;
1280 lbas = MIN(lbalen->len - bptrlen->len, lbas / be_lun->blocksize);
1252 beio->io_offset = (lbalen->lba + bptrlen->len) * be_lun->blocksize;
1253 beio->io_len = lbas * be_lun->blocksize;
1254 bptrlen->len += lbas;
1255
1256 for (i = 0, len_left = beio->io_len; len_left > 0; i++) {
1257 KASSERT(i < CTLBLK_MAX_SEGS, ("Too many segs (%d >= %d)",
1258 i, CTLBLK_MAX_SEGS));
1259
1260 /*
1261 * Setup the S/G entry for this chunk.
1262 */
1263 beio->sg_segs[i].len = min(CTLBLK_MAX_SEG, len_left);
1264 beio->sg_segs[i].addr = uma_zalloc(be_lun->lun_zone, M_WAITOK);
1265
1266 DPRINTF("segment %d addr %p len %zd\n", i,
1267 beio->sg_segs[i].addr, beio->sg_segs[i].len);
1268
1281 beio->io_offset = (lbalen->lba + bptrlen->len) * be_lun->blocksize;
1282 beio->io_len = lbas * be_lun->blocksize;
1283 bptrlen->len += lbas;
1284
1285 for (i = 0, len_left = beio->io_len; len_left > 0; i++) {
1286 KASSERT(i < CTLBLK_MAX_SEGS, ("Too many segs (%d >= %d)",
1287 i, CTLBLK_MAX_SEGS));
1288
1289 /*
1290 * Setup the S/G entry for this chunk.
1291 */
1292 beio->sg_segs[i].len = min(CTLBLK_MAX_SEG, len_left);
1293 beio->sg_segs[i].addr = uma_zalloc(be_lun->lun_zone, M_WAITOK);
1294
1295 DPRINTF("segment %d addr %p len %zd\n", i,
1296 beio->sg_segs[i].addr, beio->sg_segs[i].len);
1297
1298 /* Set up second segment for compare operation. */
1299 if (lbalen->flags & CTL_LLF_COMPARE) {
1300 beio->sg_segs[i + CTLBLK_HALF_SEGS].len =
1301 beio->sg_segs[i].len;
1302 beio->sg_segs[i + CTLBLK_HALF_SEGS].addr =
1303 uma_zalloc(be_lun->lun_zone, M_WAITOK);
1304 }
1305
1269 beio->num_segs++;
1270 len_left -= beio->sg_segs[i].len;
1271 }
1272 if (bptrlen->len < lbalen->len)
1273 beio->beio_cont = ctl_be_block_next;
1274 io->scsiio.be_move_done = ctl_be_block_move_done;
1306 beio->num_segs++;
1307 len_left -= beio->sg_segs[i].len;
1308 }
1309 if (bptrlen->len < lbalen->len)
1310 beio->beio_cont = ctl_be_block_next;
1311 io->scsiio.be_move_done = ctl_be_block_move_done;
1275 io->scsiio.kern_data_ptr = (uint8_t *)beio->sg_segs;
1312 /* For compare we have separate S/G lists for read and datamove. */
1313 if (lbalen->flags & CTL_LLF_COMPARE)
1314 io->scsiio.kern_data_ptr = (uint8_t *)&beio->sg_segs[CTLBLK_HALF_SEGS];
1315 else
1316 io->scsiio.kern_data_ptr = (uint8_t *)beio->sg_segs;
1276 io->scsiio.kern_data_len = beio->io_len;
1277 io->scsiio.kern_data_resid = 0;
1278 io->scsiio.kern_sg_entries = beio->num_segs;
1279 io->io_hdr.flags |= CTL_FLAG_ALLOCATED | CTL_FLAG_KDPTR_SGLIST;
1280
1281 /*
1282 * For the read case, we need to read the data into our buffers and
1283 * then we can send it back to the user. For the write case, we

--- 1228 unchanged lines hidden ---
1317 io->scsiio.kern_data_len = beio->io_len;
1318 io->scsiio.kern_data_resid = 0;
1319 io->scsiio.kern_sg_entries = beio->num_segs;
1320 io->io_hdr.flags |= CTL_FLAG_ALLOCATED | CTL_FLAG_KDPTR_SGLIST;
1321
1322 /*
1323 * For the read case, we need to read the data into our buffers and
1324 * then we can send it back to the user. For the write case, we

--- 1228 unchanged lines hidden ---