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 --- |