ctl_backend_block.c (268150) | ctl_backend_block.c (268151) |
---|---|
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: stable/10/sys/cam/ctl/ctl_backend_block.c 268150 2014-07-02 10:43:53Z mav $"); | 43__FBSDID("$FreeBSD: stable/10/sys/cam/ctl/ctl_backend_block.c 268151 2014-07-02 10:45:31Z mav $"); |
44 45#include <opt_kdtrace.h> 46 47#include <sys/param.h> 48#include <sys/systm.h> 49#include <sys/kernel.h> 50#include <sys/types.h> 51#include <sys/kthread.h> --- 37 unchanged lines hidden (view full) --- 89#include <cam/ctl/ctl_ioctl.h> 90#include <cam/ctl/ctl_scsi_all.h> 91#include <cam/ctl/ctl_error.h> 92 93/* 94 * The idea here is that we'll allocate enough S/G space to hold a 1MB 95 * I/O. If we get an I/O larger than that, we'll split it. 96 */ | 44 45#include <opt_kdtrace.h> 46 47#include <sys/param.h> 48#include <sys/systm.h> 49#include <sys/kernel.h> 50#include <sys/types.h> 51#include <sys/kthread.h> --- 37 unchanged lines hidden (view full) --- 89#include <cam/ctl/ctl_ioctl.h> 90#include <cam/ctl/ctl_scsi_all.h> 91#include <cam/ctl/ctl_error.h> 92 93/* 94 * The idea here is that we'll allocate enough S/G space to hold a 1MB 95 * I/O. If we get an I/O larger than that, we'll split it. 96 */ |
97#define CTLBLK_MAX_IO_SIZE (1024 * 1024) | 97#define CTLBLK_HALF_IO_SIZE (512 * 1024) 98#define CTLBLK_MAX_IO_SIZE (CTLBLK_HALF_IO_SIZE * 2) |
98#define CTLBLK_MAX_SEG MAXPHYS | 99#define CTLBLK_MAX_SEG MAXPHYS |
99#define CTLBLK_MAX_SEGS MAX(CTLBLK_MAX_IO_SIZE / CTLBLK_MAX_SEG, 1) | 100#define CTLBLK_HALF_SEGS MAX(CTLBLK_HALF_IO_SIZE / CTLBLK_MAX_SEG, 1) 101#define CTLBLK_MAX_SEGS (CTLBLK_HALF_SEGS * 2) |
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]) | 102 103#ifdef CTLBLK_DEBUG 104#define DPRINTF(fmt, args...) \ 105 printf("cbb(%s:%d): " fmt, __FUNCTION__, __LINE__, ##args) 106#else 107#define DPRINTF(fmt, args...) do {} while(0) 108#endif 109 110#define PRIV(io) \ 111 ((struct ctl_ptr_len_flags *)&(io)->io_hdr.ctl_private[CTL_PRIV_BACKEND]) |
112#define ARGS(io) \ 113 ((struct ctl_lba_len_flags *)&(io)->io_hdr.ctl_private[CTL_PRIV_LBA_LEN]) |
|
110 111SDT_PROVIDER_DEFINE(cbb); 112 113typedef enum { 114 CTL_BE_BLOCK_LUN_UNCONFIGURED = 0x01, 115 CTL_BE_BLOCK_LUN_CONFIG_ERR = 0x02, 116 CTL_BE_BLOCK_LUN_WAITING = 0x04, 117 CTL_BE_BLOCK_LUN_MULTI_THREAD = 0x08 --- 191 unchanged lines hidden (view full) --- 309 duplicate_free = 0; 310 311 for (i = 0; i < beio->num_segs; i++) { 312 if (beio->sg_segs[i].addr == NULL) 313 duplicate_free++; 314 315 uma_zfree(beio->lun->lun_zone, beio->sg_segs[i].addr); 316 beio->sg_segs[i].addr = NULL; | 114 115SDT_PROVIDER_DEFINE(cbb); 116 117typedef enum { 118 CTL_BE_BLOCK_LUN_UNCONFIGURED = 0x01, 119 CTL_BE_BLOCK_LUN_CONFIG_ERR = 0x02, 120 CTL_BE_BLOCK_LUN_WAITING = 0x04, 121 CTL_BE_BLOCK_LUN_MULTI_THREAD = 0x08 --- 191 unchanged lines hidden (view full) --- 313 duplicate_free = 0; 314 315 for (i = 0; i < beio->num_segs; i++) { 316 if (beio->sg_segs[i].addr == NULL) 317 duplicate_free++; 318 319 uma_zfree(beio->lun->lun_zone, beio->sg_segs[i].addr); 320 beio->sg_segs[i].addr = NULL; |
321 322 /* For compare we had two equal S/G lists. */ 323 if (ARGS(beio->io)->flags & CTL_LLF_COMPARE) { 324 uma_zfree(beio->lun->lun_zone, 325 beio->sg_segs[i + CTLBLK_HALF_SEGS].addr); 326 beio->sg_segs[i + CTLBLK_HALF_SEGS].addr = NULL; 327 } |
|
317 } 318 319 if (duplicate_free > 0) { 320 printf("%s: %d duplicate frees out of %d segments\n", __func__, 321 duplicate_free, beio->num_segs); 322 } 323 324 uma_zfree(beio_zone, beio); --- 18 unchanged lines hidden (view full) --- 343 beio->ds_trans_type, 344 /*now*/ NULL, 345 /*then*/&beio->ds_t0); 346 347 if (beio->beio_cont != NULL) { 348 beio->beio_cont(beio); 349 } else { 350 ctl_free_beio(beio); | 328 } 329 330 if (duplicate_free > 0) { 331 printf("%s: %d duplicate frees out of %d segments\n", __func__, 332 duplicate_free, beio->num_segs); 333 } 334 335 uma_zfree(beio_zone, beio); --- 18 unchanged lines hidden (view full) --- 354 beio->ds_trans_type, 355 /*now*/ NULL, 356 /*then*/&beio->ds_t0); 357 358 if (beio->beio_cont != NULL) { 359 beio->beio_cont(beio); 360 } else { 361 ctl_free_beio(beio); |
351 ctl_done(io); | 362 ctl_data_submit_done(io); |
352 } 353} 354 355static int 356ctl_be_block_move_done(union ctl_io *io) 357{ 358 struct ctl_be_block_io *beio; 359 struct ctl_be_block_lun *be_lun; | 363 } 364} 365 366static int 367ctl_be_block_move_done(union ctl_io *io) 368{ 369 struct ctl_be_block_io *beio; 370 struct ctl_be_block_lun *be_lun; |
371 struct ctl_lba_len_flags *lbalen; |
|
360#ifdef CTL_TIME_IO 361 struct bintime cur_bt; | 372#ifdef CTL_TIME_IO 373 struct bintime cur_bt; |
362#endif | 374#endif 375 int i; |
363 364 beio = (struct ctl_be_block_io *)PRIV(io)->ptr; 365 be_lun = beio->lun; 366 367 DPRINTF("entered\n"); 368 369#ifdef CTL_TIME_IO 370 getbintime(&cur_bt); 371 bintime_sub(&cur_bt, &io->io_hdr.dma_start_bt); 372 bintime_add(&io->io_hdr.dma_bt, &cur_bt); 373 io->io_hdr.num_dmas++; 374#endif | 376 377 beio = (struct ctl_be_block_io *)PRIV(io)->ptr; 378 be_lun = beio->lun; 379 380 DPRINTF("entered\n"); 381 382#ifdef CTL_TIME_IO 383 getbintime(&cur_bt); 384 bintime_sub(&cur_bt, &io->io_hdr.dma_start_bt); 385 bintime_add(&io->io_hdr.dma_bt, &cur_bt); 386 io->io_hdr.num_dmas++; 387#endif |
388 io->scsiio.kern_rel_offset += io->scsiio.kern_data_len; |
|
375 376 /* 377 * We set status at this point for read commands, and write 378 * commands with errors. 379 */ | 389 390 /* 391 * We set status at this point for read commands, and write 392 * commands with errors. 393 */ |
380 if ((beio->bio_cmd == BIO_READ) 381 && (io->io_hdr.port_status == 0) 382 && ((io->io_hdr.flags & CTL_FLAG_ABORT) == 0) 383 && ((io->io_hdr.status & CTL_STATUS_MASK) == CTL_STATUS_NONE)) 384 ctl_set_success(&io->scsiio); | 394 if ((io->io_hdr.port_status == 0) && 395 ((io->io_hdr.flags & CTL_FLAG_ABORT) == 0) && 396 ((io->io_hdr.status & CTL_STATUS_MASK) == CTL_STATUS_NONE)) { 397 lbalen = ARGS(beio->io); 398 if (lbalen->flags & CTL_LLF_READ) { 399 ctl_set_success(&io->scsiio); 400 } else if (lbalen->flags & CTL_LLF_COMPARE) { 401 /* We have two data blocks ready for comparison. */ 402 for (i = 0; i < beio->num_segs; i++) { 403 if (memcmp(beio->sg_segs[i].addr, 404 beio->sg_segs[i + CTLBLK_HALF_SEGS].addr, 405 beio->sg_segs[i].len) != 0) 406 break; 407 } 408 if (i < beio->num_segs) 409 ctl_set_sense(&io->scsiio, 410 /*current_error*/ 1, 411 /*sense_key*/ SSD_KEY_MISCOMPARE, 412 /*asc*/ 0x1D, 413 /*ascq*/ 0x00, 414 SSD_ELEM_NONE); 415 else 416 ctl_set_success(&io->scsiio); 417 } 418 } |
385 else if ((io->io_hdr.port_status != 0) 386 && ((io->io_hdr.flags & CTL_FLAG_ABORT) == 0) 387 && ((io->io_hdr.status & CTL_STATUS_MASK) == CTL_STATUS_NONE)) { 388 /* 389 * For hardware error sense keys, the sense key 390 * specific value is defined to be a retry count, 391 * but we use it to pass back an internal FETD 392 * error code. XXX KDM Hopefully the FETD is only --- 95 unchanged lines hidden (view full) --- 488 /*retry_count*/ 0xbad2); 489 } else 490 ctl_set_medium_error(&io->scsiio); 491 ctl_complete_beio(beio); 492 return; 493 } 494 495 /* | 419 else if ((io->io_hdr.port_status != 0) 420 && ((io->io_hdr.flags & CTL_FLAG_ABORT) == 0) 421 && ((io->io_hdr.status & CTL_STATUS_MASK) == CTL_STATUS_NONE)) { 422 /* 423 * For hardware error sense keys, the sense key 424 * specific value is defined to be a retry count, 425 * but we use it to pass back an internal FETD 426 * error code. XXX KDM Hopefully the FETD is only --- 95 unchanged lines hidden (view full) --- 522 /*retry_count*/ 0xbad2); 523 } else 524 ctl_set_medium_error(&io->scsiio); 525 ctl_complete_beio(beio); 526 return; 527 } 528 529 /* |
496 * If this is a write, a flush or a delete, we're all done. | 530 * If this is a write, a flush, a delete or verify, we're all done. |
497 * If this is a read, we can now send the data to the user. 498 */ 499 if ((beio->bio_cmd == BIO_WRITE) 500 || (beio->bio_cmd == BIO_FLUSH) | 531 * If this is a read, we can now send the data to the user. 532 */ 533 if ((beio->bio_cmd == BIO_WRITE) 534 || (beio->bio_cmd == BIO_FLUSH) |
501 || (beio->bio_cmd == BIO_DELETE)) { | 535 || (beio->bio_cmd == BIO_DELETE) 536 || (ARGS(io)->flags & CTL_LLF_VERIFY)) { |
502 ctl_set_success(&io->scsiio); 503 ctl_complete_beio(beio); 504 } else { 505#ifdef CTL_TIME_IO 506 getbintime(&io->io_hdr.dma_start_bt); 507#endif 508 ctl_datamove(io); 509 } --- 59 unchanged lines hidden (view full) --- 569 int error, i; 570 571 DPRINTF("entered\n"); 572 573 file_data = &be_lun->backend.file; 574 io = beio->io; 575 flags = beio->bio_flags; 576 | 537 ctl_set_success(&io->scsiio); 538 ctl_complete_beio(beio); 539 } else { 540#ifdef CTL_TIME_IO 541 getbintime(&io->io_hdr.dma_start_bt); 542#endif 543 ctl_datamove(io); 544 } --- 59 unchanged lines hidden (view full) --- 604 int error, i; 605 606 DPRINTF("entered\n"); 607 608 file_data = &be_lun->backend.file; 609 io = beio->io; 610 flags = beio->bio_flags; 611 |
612 bzero(&xuio, sizeof(xuio)); |
|
577 if (beio->bio_cmd == BIO_READ) { 578 SDT_PROBE(cbb, kernel, read, file_start, 0, 0, 0, 0, 0); | 613 if (beio->bio_cmd == BIO_READ) { 614 SDT_PROBE(cbb, kernel, read, file_start, 0, 0, 0, 0, 0); |
615 xuio.uio_rw = UIO_READ; |
|
579 } else { 580 SDT_PROBE(cbb, kernel, write, file_start, 0, 0, 0, 0, 0); | 616 } else { 617 SDT_PROBE(cbb, kernel, write, file_start, 0, 0, 0, 0, 0); |
581 } 582 583 bzero(&xuio, sizeof(xuio)); 584 if (beio->bio_cmd == BIO_READ) 585 xuio.uio_rw = UIO_READ; 586 else | |
587 xuio.uio_rw = UIO_WRITE; | 618 xuio.uio_rw = UIO_WRITE; |
588 | 619 } |
589 xuio.uio_offset = beio->io_offset; 590 xuio.uio_resid = beio->io_len; 591 xuio.uio_segflg = UIO_SYSSPACE; 592 xuio.uio_iov = beio->xiovecs; 593 xuio.uio_iovcnt = beio->num_segs; 594 xuio.uio_td = curthread; 595 596 for (i = 0, xiovec = xuio.uio_iov; i < xuio.uio_iovcnt; i++, xiovec++) { --- 26 unchanged lines hidden (view full) --- 623 * 624 * So, to attempt to provide some barrier semantics in the 625 * BIO_ORDERED case, set both IO_DIRECT and IO_SYNC. 626 */ 627 error = VOP_READ(be_lun->vn, &xuio, (flags & BIO_ORDERED) ? 628 (IO_DIRECT|IO_SYNC) : 0, file_data->cred); 629 630 VOP_UNLOCK(be_lun->vn, 0); | 620 xuio.uio_offset = beio->io_offset; 621 xuio.uio_resid = beio->io_len; 622 xuio.uio_segflg = UIO_SYSSPACE; 623 xuio.uio_iov = beio->xiovecs; 624 xuio.uio_iovcnt = beio->num_segs; 625 xuio.uio_td = curthread; 626 627 for (i = 0, xiovec = xuio.uio_iov; i < xuio.uio_iovcnt; i++, xiovec++) { --- 26 unchanged lines hidden (view full) --- 654 * 655 * So, to attempt to provide some barrier semantics in the 656 * BIO_ORDERED case, set both IO_DIRECT and IO_SYNC. 657 */ 658 error = VOP_READ(be_lun->vn, &xuio, (flags & BIO_ORDERED) ? 659 (IO_DIRECT|IO_SYNC) : 0, file_data->cred); 660 661 VOP_UNLOCK(be_lun->vn, 0); |
662 SDT_PROBE(cbb, kernel, read, file_done, 0, 0, 0, 0, 0); |
|
631 } else { 632 struct mount *mountpoint; 633 int lock_flags; 634 635 (void)vn_start_write(be_lun->vn, &mountpoint, V_WAIT); 636 637 if (MNT_SHARED_WRITES(mountpoint) 638 || ((mountpoint == NULL) --- 25 unchanged lines hidden (view full) --- 664 * So if we've got the BIO_ORDERED flag set, we want 665 * IO_SYNC in either the UFS or ZFS case. 666 */ 667 error = VOP_WRITE(be_lun->vn, &xuio, (flags & BIO_ORDERED) ? 668 IO_SYNC : 0, file_data->cred); 669 VOP_UNLOCK(be_lun->vn, 0); 670 671 vn_finished_write(mountpoint); | 663 } else { 664 struct mount *mountpoint; 665 int lock_flags; 666 667 (void)vn_start_write(be_lun->vn, &mountpoint, V_WAIT); 668 669 if (MNT_SHARED_WRITES(mountpoint) 670 || ((mountpoint == NULL) --- 25 unchanged lines hidden (view full) --- 696 * So if we've got the BIO_ORDERED flag set, we want 697 * IO_SYNC in either the UFS or ZFS case. 698 */ 699 error = VOP_WRITE(be_lun->vn, &xuio, (flags & BIO_ORDERED) ? 700 IO_SYNC : 0, file_data->cred); 701 VOP_UNLOCK(be_lun->vn, 0); 702 703 vn_finished_write(mountpoint); |
704 SDT_PROBE(cbb, kernel, write, file_done, 0, 0, 0, 0, 0); |
|
672 } 673 674 /* 675 * If we got an error, set the sense data to "MEDIUM ERROR" and 676 * return the I/O to the user. 677 */ 678 if (error != 0) { 679 char path_str[32]; --- 10 unchanged lines hidden (view full) --- 690 ctl_complete_beio(beio); 691 return; 692 } 693 694 /* 695 * If this is a write, we're all done. 696 * If this is a read, we can now send the data to the user. 697 */ | 705 } 706 707 /* 708 * If we got an error, set the sense data to "MEDIUM ERROR" and 709 * return the I/O to the user. 710 */ 711 if (error != 0) { 712 char path_str[32]; --- 10 unchanged lines hidden (view full) --- 723 ctl_complete_beio(beio); 724 return; 725 } 726 727 /* 728 * If this is a write, we're all done. 729 * If this is a read, we can now send the data to the user. 730 */ |
698 if (beio->bio_cmd == BIO_WRITE) { | 731 if (ARGS(io)->flags & (CTL_LLF_WRITE | CTL_LLF_VERIFY)) { |
699 ctl_set_success(&io->scsiio); | 732 ctl_set_success(&io->scsiio); |
700 SDT_PROBE(cbb, kernel, write, file_done, 0, 0, 0, 0, 0); | |
701 ctl_complete_beio(beio); 702 } else { | 733 ctl_complete_beio(beio); 734 } else { |
703 SDT_PROBE(cbb, kernel, read, file_done, 0, 0, 0, 0, 0); | |
704#ifdef CTL_TIME_IO 705 getbintime(&io->io_hdr.dma_start_bt); 706#endif 707 ctl_datamove(io); 708 } 709} 710 711static void --- 220 unchanged lines hidden (view full) --- 932 uint64_t len_left, lba; 933 int i, seglen; 934 uint8_t *buf, *end; 935 936 DPRINTF("entered\n"); 937 938 beio = (struct ctl_be_block_io *)PRIV(io)->ptr; 939 softc = be_lun->softc; | 735#ifdef CTL_TIME_IO 736 getbintime(&io->io_hdr.dma_start_bt); 737#endif 738 ctl_datamove(io); 739 } 740} 741 742static void --- 220 unchanged lines hidden (view full) --- 963 uint64_t len_left, lba; 964 int i, seglen; 965 uint8_t *buf, *end; 966 967 DPRINTF("entered\n"); 968 969 beio = (struct ctl_be_block_io *)PRIV(io)->ptr; 970 softc = be_lun->softc; |
940 lbalen = (struct ctl_lba_len_flags *)&io->io_hdr.ctl_private[CTL_PRIV_LBA_LEN]; | 971 lbalen = ARGS(beio->io); |
941 942 if (lbalen->flags & ~(SWS_LBDATA | SWS_UNMAP) || 943 (lbalen->flags & SWS_UNMAP && be_lun->unmap == NULL)) { 944 ctl_free_beio(beio); 945 ctl_set_invalid_field(&io->scsiio, 946 /*sks_valid*/ 1, 947 /*command*/ 1, 948 /*field*/ 1, --- 203 unchanged lines hidden (view full) --- 1152 struct ctl_be_block_lun *be_lun; 1153 union ctl_io *io; 1154 1155 io = beio->io; 1156 be_lun = beio->lun; 1157 ctl_free_beio(beio); 1158 if (((io->io_hdr.status & CTL_STATUS_MASK) != CTL_STATUS_NONE) 1159 && ((io->io_hdr.status & CTL_STATUS_MASK) != CTL_SUCCESS)) { | 972 973 if (lbalen->flags & ~(SWS_LBDATA | SWS_UNMAP) || 974 (lbalen->flags & SWS_UNMAP && be_lun->unmap == NULL)) { 975 ctl_free_beio(beio); 976 ctl_set_invalid_field(&io->scsiio, 977 /*sks_valid*/ 1, 978 /*command*/ 1, 979 /*field*/ 1, --- 203 unchanged lines hidden (view full) --- 1183 struct ctl_be_block_lun *be_lun; 1184 union ctl_io *io; 1185 1186 io = beio->io; 1187 be_lun = beio->lun; 1188 ctl_free_beio(beio); 1189 if (((io->io_hdr.status & CTL_STATUS_MASK) != CTL_STATUS_NONE) 1190 && ((io->io_hdr.status & CTL_STATUS_MASK) != CTL_SUCCESS)) { |
1160 ctl_done(io); | 1191 ctl_data_submit_done(io); |
1161 return; 1162 } 1163 | 1192 return; 1193 } 1194 |
1164 io->scsiio.kern_rel_offset += io->scsiio.kern_data_len; | |
1165 io->io_hdr.status &= ~CTL_STATUS_MASK; 1166 io->io_hdr.status |= CTL_STATUS_NONE; 1167 1168 mtx_lock(&be_lun->lock); 1169 /* 1170 * XXX KDM make sure that links is okay to use at this point. 1171 * Otherwise, we either need to add another field to ctl_io_hdr, 1172 * or deal with resource allocation here. --- 5 unchanged lines hidden (view full) --- 1178} 1179 1180static void 1181ctl_be_block_dispatch(struct ctl_be_block_lun *be_lun, 1182 union ctl_io *io) 1183{ 1184 struct ctl_be_block_io *beio; 1185 struct ctl_be_block_softc *softc; | 1195 io->io_hdr.status &= ~CTL_STATUS_MASK; 1196 io->io_hdr.status |= CTL_STATUS_NONE; 1197 1198 mtx_lock(&be_lun->lock); 1199 /* 1200 * XXX KDM make sure that links is okay to use at this point. 1201 * Otherwise, we either need to add another field to ctl_io_hdr, 1202 * or deal with resource allocation here. --- 5 unchanged lines hidden (view full) --- 1208} 1209 1210static void 1211ctl_be_block_dispatch(struct ctl_be_block_lun *be_lun, 1212 union ctl_io *io) 1213{ 1214 struct ctl_be_block_io *beio; 1215 struct ctl_be_block_softc *softc; |
1186 struct ctl_lba_len *lbalen; | 1216 struct ctl_lba_len_flags *lbalen; |
1187 struct ctl_ptr_len_flags *bptrlen; 1188 uint64_t len_left, lbas; 1189 int i; 1190 1191 softc = be_lun->softc; 1192 1193 DPRINTF("entered\n"); 1194 | 1217 struct ctl_ptr_len_flags *bptrlen; 1218 uint64_t len_left, lbas; 1219 int i; 1220 1221 softc = be_lun->softc; 1222 1223 DPRINTF("entered\n"); 1224 |
1195 if ((io->io_hdr.flags & CTL_FLAG_DATA_MASK) == CTL_FLAG_DATA_IN) { 1196 SDT_PROBE(cbb, kernel, read, start, 0, 0, 0, 0, 0); 1197 } else { | 1225 lbalen = ARGS(io); 1226 if (lbalen->flags & CTL_LLF_WRITE) { |
1198 SDT_PROBE(cbb, kernel, write, start, 0, 0, 0, 0, 0); | 1227 SDT_PROBE(cbb, kernel, write, start, 0, 0, 0, 0, 0); |
1228 } else { 1229 SDT_PROBE(cbb, kernel, read, start, 0, 0, 0, 0, 0); |
|
1199 } 1200 1201 beio = ctl_alloc_beio(softc); 1202 beio->io = io; 1203 beio->lun = be_lun; 1204 bptrlen = PRIV(io); 1205 bptrlen->ptr = (void *)beio; 1206 --- 21 unchanged lines hidden (view full) --- 1228 case CTL_TAG_UNTAGGED: 1229 case CTL_TAG_SIMPLE: 1230 case CTL_TAG_ACA: 1231 default: 1232 beio->ds_tag_type = DEVSTAT_TAG_SIMPLE; 1233 break; 1234 } 1235 | 1230 } 1231 1232 beio = ctl_alloc_beio(softc); 1233 beio->io = io; 1234 beio->lun = be_lun; 1235 bptrlen = PRIV(io); 1236 bptrlen->ptr = (void *)beio; 1237 --- 21 unchanged lines hidden (view full) --- 1259 case CTL_TAG_UNTAGGED: 1260 case CTL_TAG_SIMPLE: 1261 case CTL_TAG_ACA: 1262 default: 1263 beio->ds_tag_type = DEVSTAT_TAG_SIMPLE; 1264 break; 1265 } 1266 |
1236 /* 1237 * This path handles read and write only. The config write path 1238 * handles flush operations. 1239 */ 1240 if ((io->io_hdr.flags & CTL_FLAG_DATA_MASK) == CTL_FLAG_DATA_IN) { 1241 beio->bio_cmd = BIO_READ; 1242 beio->ds_trans_type = DEVSTAT_READ; 1243 } else { | 1267 if (lbalen->flags & CTL_LLF_WRITE) { |
1244 beio->bio_cmd = BIO_WRITE; 1245 beio->ds_trans_type = DEVSTAT_WRITE; | 1268 beio->bio_cmd = BIO_WRITE; 1269 beio->ds_trans_type = DEVSTAT_WRITE; |
1270 } else { 1271 beio->bio_cmd = BIO_READ; 1272 beio->ds_trans_type = DEVSTAT_READ; |
|
1246 } 1247 | 1273 } 1274 |
1248 lbalen = (struct ctl_lba_len *)&io->io_hdr.ctl_private[CTL_PRIV_LBA_LEN]; | |
1249 DPRINTF("%s at LBA %jx len %u @%ju\n", 1250 (beio->bio_cmd == BIO_READ) ? "READ" : "WRITE", 1251 (uintmax_t)lbalen->lba, lbalen->len, bptrlen->len); | 1275 DPRINTF("%s at LBA %jx len %u @%ju\n", 1276 (beio->bio_cmd == BIO_READ) ? "READ" : "WRITE", 1277 (uintmax_t)lbalen->lba, lbalen->len, bptrlen->len); |
1252 lbas = MIN(lbalen->len - bptrlen->len, 1253 CTLBLK_MAX_IO_SIZE / be_lun->blocksize); | 1278 if (lbalen->flags & CTL_LLF_COMPARE) 1279 lbas = CTLBLK_HALF_IO_SIZE; 1280 else 1281 lbas = CTLBLK_MAX_IO_SIZE; 1282 lbas = MIN(lbalen->len - bptrlen->len, lbas / be_lun->blocksize); |
1254 beio->io_offset = (lbalen->lba + bptrlen->len) * be_lun->blocksize; 1255 beio->io_len = lbas * be_lun->blocksize; 1256 bptrlen->len += lbas; 1257 1258 for (i = 0, len_left = beio->io_len; len_left > 0; i++) { 1259 KASSERT(i < CTLBLK_MAX_SEGS, ("Too many segs (%d >= %d)", 1260 i, CTLBLK_MAX_SEGS)); 1261 1262 /* 1263 * Setup the S/G entry for this chunk. 1264 */ 1265 beio->sg_segs[i].len = min(CTLBLK_MAX_SEG, len_left); 1266 beio->sg_segs[i].addr = uma_zalloc(be_lun->lun_zone, M_WAITOK); 1267 1268 DPRINTF("segment %d addr %p len %zd\n", i, 1269 beio->sg_segs[i].addr, beio->sg_segs[i].len); 1270 | 1283 beio->io_offset = (lbalen->lba + bptrlen->len) * be_lun->blocksize; 1284 beio->io_len = lbas * be_lun->blocksize; 1285 bptrlen->len += lbas; 1286 1287 for (i = 0, len_left = beio->io_len; len_left > 0; i++) { 1288 KASSERT(i < CTLBLK_MAX_SEGS, ("Too many segs (%d >= %d)", 1289 i, CTLBLK_MAX_SEGS)); 1290 1291 /* 1292 * Setup the S/G entry for this chunk. 1293 */ 1294 beio->sg_segs[i].len = min(CTLBLK_MAX_SEG, len_left); 1295 beio->sg_segs[i].addr = uma_zalloc(be_lun->lun_zone, M_WAITOK); 1296 1297 DPRINTF("segment %d addr %p len %zd\n", i, 1298 beio->sg_segs[i].addr, beio->sg_segs[i].len); 1299 |
1300 /* Set up second segment for compare operation. */ 1301 if (lbalen->flags & CTL_LLF_COMPARE) { 1302 beio->sg_segs[i + CTLBLK_HALF_SEGS].len = 1303 beio->sg_segs[i].len; 1304 beio->sg_segs[i + CTLBLK_HALF_SEGS].addr = 1305 uma_zalloc(be_lun->lun_zone, M_WAITOK); 1306 } 1307 |
|
1271 beio->num_segs++; 1272 len_left -= beio->sg_segs[i].len; 1273 } 1274 if (bptrlen->len < lbalen->len) 1275 beio->beio_cont = ctl_be_block_next; 1276 io->scsiio.be_move_done = ctl_be_block_move_done; | 1308 beio->num_segs++; 1309 len_left -= beio->sg_segs[i].len; 1310 } 1311 if (bptrlen->len < lbalen->len) 1312 beio->beio_cont = ctl_be_block_next; 1313 io->scsiio.be_move_done = ctl_be_block_move_done; |
1277 io->scsiio.kern_data_ptr = (uint8_t *)beio->sg_segs; | 1314 /* For compare we have separate S/G lists for read and datamove. */ 1315 if (lbalen->flags & CTL_LLF_COMPARE) 1316 io->scsiio.kern_data_ptr = (uint8_t *)&beio->sg_segs[CTLBLK_HALF_SEGS]; 1317 else 1318 io->scsiio.kern_data_ptr = (uint8_t *)beio->sg_segs; |
1278 io->scsiio.kern_data_len = beio->io_len; 1279 io->scsiio.kern_data_resid = 0; 1280 io->scsiio.kern_sg_entries = beio->num_segs; 1281 io->io_hdr.flags |= CTL_FLAG_ALLOCATED | CTL_FLAG_KDPTR_SGLIST; 1282 1283 /* 1284 * For the read case, we need to read the data into our buffers and 1285 * then we can send it back to the user. For the write case, we --- 1228 unchanged lines hidden --- | 1319 io->scsiio.kern_data_len = beio->io_len; 1320 io->scsiio.kern_data_resid = 0; 1321 io->scsiio.kern_sg_entries = beio->num_segs; 1322 io->io_hdr.flags |= CTL_FLAG_ALLOCATED | CTL_FLAG_KDPTR_SGLIST; 1323 1324 /* 1325 * For the read case, we need to read the data into our buffers and 1326 * then we can send it back to the user. For the write case, we --- 1228 unchanged lines hidden --- |