1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright (c) 2003 Silicon Graphics International Corp.
5 * Copyright (c) 2009-2011 Spectra Logic Corporation
6 * Copyright (c) 2012,2021 The FreeBSD Foundation
7 * Copyright (c) 2014-2021 Alexander Motin <[email protected]>
8 * All rights reserved.
9 *
10 * Portions of this software were developed by Edward Tomasz Napierala
11 * under sponsorship from the FreeBSD Foundation.
12 *
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
15 * are met:
16 * 1. Redistributions of source code must retain the above copyright
17 * notice, this list of conditions, and the following disclaimer,
18 * without modification.
19 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
20 * substantially similar to the "NO WARRANTY" disclaimer below
21 * ("Disclaimer") and any redistribution must be conditioned upon
22 * including a substantially similar Disclaimer requirement for further
23 * binary redistribution.
24 *
25 * NO WARRANTY
26 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
29 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
34 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
35 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 * POSSIBILITY OF SUCH DAMAGES.
37 *
38 * $Id: //depot/users/kenm/FreeBSD-test2/sys/cam/ctl/ctl_backend_block.c#5 $
39 */
40 /*
41 * CAM Target Layer driver backend for block devices.
42 *
43 * Author: Ken Merry <[email protected]>
44 */
45 #include <sys/cdefs.h>
46 __FBSDID("$FreeBSD$");
47
48 #include <sys/param.h>
49 #include <sys/systm.h>
50 #include <sys/kernel.h>
51 #include <sys/types.h>
52 #include <sys/kthread.h>
53 #include <sys/bio.h>
54 #include <sys/fcntl.h>
55 #include <sys/limits.h>
56 #include <sys/lock.h>
57 #include <sys/mutex.h>
58 #include <sys/condvar.h>
59 #include <sys/malloc.h>
60 #include <sys/conf.h>
61 #include <sys/ioccom.h>
62 #include <sys/queue.h>
63 #include <sys/sbuf.h>
64 #include <sys/endian.h>
65 #include <sys/uio.h>
66 #include <sys/buf.h>
67 #include <sys/taskqueue.h>
68 #include <sys/vnode.h>
69 #include <sys/namei.h>
70 #include <sys/mount.h>
71 #include <sys/disk.h>
72 #include <sys/fcntl.h>
73 #include <sys/filedesc.h>
74 #include <sys/filio.h>
75 #include <sys/proc.h>
76 #include <sys/pcpu.h>
77 #include <sys/module.h>
78 #include <sys/sdt.h>
79 #include <sys/devicestat.h>
80 #include <sys/sysctl.h>
81 #include <sys/nv.h>
82 #include <sys/dnv.h>
83 #include <sys/sx.h>
84
85 #include <geom/geom.h>
86
87 #include <cam/cam.h>
88 #include <cam/scsi/scsi_all.h>
89 #include <cam/scsi/scsi_da.h>
90 #include <cam/ctl/ctl_io.h>
91 #include <cam/ctl/ctl.h>
92 #include <cam/ctl/ctl_backend.h>
93 #include <cam/ctl/ctl_ioctl.h>
94 #include <cam/ctl/ctl_ha.h>
95 #include <cam/ctl/ctl_scsi_all.h>
96 #include <cam/ctl/ctl_private.h>
97 #include <cam/ctl/ctl_error.h>
98
99 /*
100 * The idea here is to allocate enough S/G space to handle at least 1MB I/Os.
101 * On systems with small maxphys it can be 8 128KB segments. On large systems
102 * it can be up to 8 1MB segments. I/Os larger than that we'll split.
103 */
104 #define CTLBLK_MAX_SEGS 8
105 #define CTLBLK_HALF_SEGS (CTLBLK_MAX_SEGS / 2)
106 #define CTLBLK_MIN_SEG (128 * 1024)
107 #define CTLBLK_MAX_SEG MIN(1024 * 1024, MAX(CTLBLK_MIN_SEG, maxphys))
108 #define CTLBLK_MAX_IO_SIZE (CTLBLK_MAX_SEG * CTLBLK_MAX_SEGS)
109
110 #ifdef CTLBLK_DEBUG
111 #define DPRINTF(fmt, args...) \
112 printf("cbb(%s:%d): " fmt, __FUNCTION__, __LINE__, ##args)
113 #else
114 #define DPRINTF(fmt, args...) do {} while(0)
115 #endif
116
117 #define PRIV(io) \
118 ((struct ctl_ptr_len_flags *)&(io)->io_hdr.ctl_private[CTL_PRIV_BACKEND])
119 #define ARGS(io) \
120 ((struct ctl_lba_len_flags *)&(io)->io_hdr.ctl_private[CTL_PRIV_LBA_LEN])
121
122 SDT_PROVIDER_DEFINE(cbb);
123
124 typedef enum {
125 CTL_BE_BLOCK_LUN_UNCONFIGURED = 0x01,
126 CTL_BE_BLOCK_LUN_WAITING = 0x04,
127 } ctl_be_block_lun_flags;
128
129 typedef enum {
130 CTL_BE_BLOCK_NONE,
131 CTL_BE_BLOCK_DEV,
132 CTL_BE_BLOCK_FILE
133 } ctl_be_block_type;
134
135 struct ctl_be_block_filedata {
136 struct ucred *cred;
137 };
138
139 union ctl_be_block_bedata {
140 struct ctl_be_block_filedata file;
141 };
142
143 struct ctl_be_block_io;
144 struct ctl_be_block_lun;
145
146 typedef void (*cbb_dispatch_t)(struct ctl_be_block_lun *be_lun,
147 struct ctl_be_block_io *beio);
148 typedef uint64_t (*cbb_getattr_t)(struct ctl_be_block_lun *be_lun,
149 const char *attrname);
150
151 /*
152 * Backend LUN structure. There is a 1:1 mapping between a block device
153 * and a backend block LUN, and between a backend block LUN and a CTL LUN.
154 */
155 struct ctl_be_block_lun {
156 struct ctl_be_lun cbe_lun; /* Must be first element. */
157 struct ctl_lun_create_params params;
158 char *dev_path;
159 ctl_be_block_type dev_type;
160 struct vnode *vn;
161 union ctl_be_block_bedata backend;
162 cbb_dispatch_t dispatch;
163 cbb_dispatch_t lun_flush;
164 cbb_dispatch_t unmap;
165 cbb_dispatch_t get_lba_status;
166 cbb_getattr_t getattr;
167 uint64_t size_blocks;
168 uint64_t size_bytes;
169 struct ctl_be_block_softc *softc;
170 struct devstat *disk_stats;
171 ctl_be_block_lun_flags flags;
172 SLIST_ENTRY(ctl_be_block_lun) links;
173 struct taskqueue *io_taskqueue;
174 struct task io_task;
175 int num_threads;
176 STAILQ_HEAD(, ctl_io_hdr) input_queue;
177 STAILQ_HEAD(, ctl_io_hdr) config_read_queue;
178 STAILQ_HEAD(, ctl_io_hdr) config_write_queue;
179 STAILQ_HEAD(, ctl_io_hdr) datamove_queue;
180 struct mtx_padalign io_lock;
181 struct mtx_padalign queue_lock;
182 };
183
184 /*
185 * Overall softc structure for the block backend module.
186 */
187 struct ctl_be_block_softc {
188 struct sx modify_lock;
189 struct mtx lock;
190 int num_luns;
191 SLIST_HEAD(, ctl_be_block_lun) lun_list;
192 uma_zone_t beio_zone;
193 uma_zone_t bufmin_zone;
194 uma_zone_t bufmax_zone;
195 };
196
197 static struct ctl_be_block_softc backend_block_softc;
198
199 /*
200 * Per-I/O information.
201 */
202 struct ctl_be_block_io {
203 union ctl_io *io;
204 struct ctl_sg_entry sg_segs[CTLBLK_MAX_SEGS];
205 struct iovec xiovecs[CTLBLK_MAX_SEGS];
206 int refcnt;
207 int bio_cmd;
208 int two_sglists;
209 int num_segs;
210 int num_bios_sent;
211 int num_bios_done;
212 int send_complete;
213 int first_error;
214 uint64_t first_error_offset;
215 struct bintime ds_t0;
216 devstat_tag_type ds_tag_type;
217 devstat_trans_flags ds_trans_type;
218 uint64_t io_len;
219 uint64_t io_offset;
220 int io_arg;
221 struct ctl_be_block_softc *softc;
222 struct ctl_be_block_lun *lun;
223 void (*beio_cont)(struct ctl_be_block_io *beio); /* to continue processing */
224 };
225
226 extern struct ctl_softc *control_softc;
227
228 static int cbb_num_threads = 32;
229 SYSCTL_NODE(_kern_cam_ctl, OID_AUTO, block, CTLFLAG_RD | CTLFLAG_MPSAFE, 0,
230 "CAM Target Layer Block Backend");
231 SYSCTL_INT(_kern_cam_ctl_block, OID_AUTO, num_threads, CTLFLAG_RWTUN,
232 &cbb_num_threads, 0, "Number of threads per backing file");
233
234 static struct ctl_be_block_io *ctl_alloc_beio(struct ctl_be_block_softc *softc);
235 static void ctl_free_beio(struct ctl_be_block_io *beio);
236 static void ctl_complete_beio(struct ctl_be_block_io *beio);
237 static int ctl_be_block_move_done(union ctl_io *io, bool samethr);
238 static void ctl_be_block_biodone(struct bio *bio);
239 static void ctl_be_block_flush_file(struct ctl_be_block_lun *be_lun,
240 struct ctl_be_block_io *beio);
241 static void ctl_be_block_dispatch_file(struct ctl_be_block_lun *be_lun,
242 struct ctl_be_block_io *beio);
243 static void ctl_be_block_gls_file(struct ctl_be_block_lun *be_lun,
244 struct ctl_be_block_io *beio);
245 static uint64_t ctl_be_block_getattr_file(struct ctl_be_block_lun *be_lun,
246 const char *attrname);
247 static void ctl_be_block_flush_dev(struct ctl_be_block_lun *be_lun,
248 struct ctl_be_block_io *beio);
249 static void ctl_be_block_unmap_dev(struct ctl_be_block_lun *be_lun,
250 struct ctl_be_block_io *beio);
251 static void ctl_be_block_dispatch_dev(struct ctl_be_block_lun *be_lun,
252 struct ctl_be_block_io *beio);
253 static uint64_t ctl_be_block_getattr_dev(struct ctl_be_block_lun *be_lun,
254 const char *attrname);
255 static void ctl_be_block_cr_dispatch(struct ctl_be_block_lun *be_lun,
256 union ctl_io *io);
257 static void ctl_be_block_cw_dispatch(struct ctl_be_block_lun *be_lun,
258 union ctl_io *io);
259 static void ctl_be_block_dispatch(struct ctl_be_block_lun *be_lun,
260 union ctl_io *io);
261 static void ctl_be_block_worker(void *context, int pending);
262 static int ctl_be_block_submit(union ctl_io *io);
263 static int ctl_be_block_ioctl(struct cdev *dev, u_long cmd, caddr_t addr,
264 int flag, struct thread *td);
265 static int ctl_be_block_open_file(struct ctl_be_block_lun *be_lun,
266 struct ctl_lun_req *req);
267 static int ctl_be_block_open_dev(struct ctl_be_block_lun *be_lun,
268 struct ctl_lun_req *req);
269 static int ctl_be_block_close(struct ctl_be_block_lun *be_lun);
270 static int ctl_be_block_open(struct ctl_be_block_lun *be_lun,
271 struct ctl_lun_req *req);
272 static int ctl_be_block_create(struct ctl_be_block_softc *softc,
273 struct ctl_lun_req *req);
274 static int ctl_be_block_rm(struct ctl_be_block_softc *softc,
275 struct ctl_lun_req *req);
276 static int ctl_be_block_modify(struct ctl_be_block_softc *softc,
277 struct ctl_lun_req *req);
278 static void ctl_be_block_lun_shutdown(struct ctl_be_lun *cbe_lun);
279 static int ctl_be_block_config_write(union ctl_io *io);
280 static int ctl_be_block_config_read(union ctl_io *io);
281 static int ctl_be_block_lun_info(struct ctl_be_lun *cbe_lun, struct sbuf *sb);
282 static uint64_t ctl_be_block_lun_attr(struct ctl_be_lun *cbe_lun, const char *attrname);
283 static int ctl_be_block_init(void);
284 static int ctl_be_block_shutdown(void);
285
286 static struct ctl_backend_driver ctl_be_block_driver =
287 {
288 .name = "block",
289 .flags = CTL_BE_FLAG_HAS_CONFIG,
290 .init = ctl_be_block_init,
291 .shutdown = ctl_be_block_shutdown,
292 .data_submit = ctl_be_block_submit,
293 .config_read = ctl_be_block_config_read,
294 .config_write = ctl_be_block_config_write,
295 .ioctl = ctl_be_block_ioctl,
296 .lun_info = ctl_be_block_lun_info,
297 .lun_attr = ctl_be_block_lun_attr
298 };
299
300 MALLOC_DEFINE(M_CTLBLK, "ctlblock", "Memory used for CTL block backend");
301 CTL_BACKEND_DECLARE(cbb, ctl_be_block_driver);
302
303 static void
ctl_alloc_seg(struct ctl_be_block_softc * softc,struct ctl_sg_entry * sg,size_t len)304 ctl_alloc_seg(struct ctl_be_block_softc *softc, struct ctl_sg_entry *sg,
305 size_t len)
306 {
307
308 if (len <= CTLBLK_MIN_SEG) {
309 sg->addr = uma_zalloc(softc->bufmin_zone, M_WAITOK);
310 } else {
311 KASSERT(len <= CTLBLK_MAX_SEG,
312 ("Too large alloc %zu > %lu", len, CTLBLK_MAX_SEG));
313 sg->addr = uma_zalloc(softc->bufmax_zone, M_WAITOK);
314 }
315 sg->len = len;
316 }
317
318 static void
ctl_free_seg(struct ctl_be_block_softc * softc,struct ctl_sg_entry * sg)319 ctl_free_seg(struct ctl_be_block_softc *softc, struct ctl_sg_entry *sg)
320 {
321
322 if (sg->len <= CTLBLK_MIN_SEG) {
323 uma_zfree(softc->bufmin_zone, sg->addr);
324 } else {
325 KASSERT(sg->len <= CTLBLK_MAX_SEG,
326 ("Too large free %zu > %lu", sg->len, CTLBLK_MAX_SEG));
327 uma_zfree(softc->bufmax_zone, sg->addr);
328 }
329 }
330
331 static struct ctl_be_block_io *
ctl_alloc_beio(struct ctl_be_block_softc * softc)332 ctl_alloc_beio(struct ctl_be_block_softc *softc)
333 {
334 struct ctl_be_block_io *beio;
335
336 beio = uma_zalloc(softc->beio_zone, M_WAITOK | M_ZERO);
337 beio->softc = softc;
338 beio->refcnt = 1;
339 return (beio);
340 }
341
342 static void
ctl_real_free_beio(struct ctl_be_block_io * beio)343 ctl_real_free_beio(struct ctl_be_block_io *beio)
344 {
345 struct ctl_be_block_softc *softc = beio->softc;
346 int i;
347
348 for (i = 0; i < beio->num_segs; i++) {
349 ctl_free_seg(softc, &beio->sg_segs[i]);
350
351 /* For compare we had two equal S/G lists. */
352 if (beio->two_sglists) {
353 ctl_free_seg(softc,
354 &beio->sg_segs[i + CTLBLK_HALF_SEGS]);
355 }
356 }
357
358 uma_zfree(softc->beio_zone, beio);
359 }
360
361 static void
ctl_refcnt_beio(void * arg,int diff)362 ctl_refcnt_beio(void *arg, int diff)
363 {
364 struct ctl_be_block_io *beio = arg;
365
366 if (atomic_fetchadd_int(&beio->refcnt, diff) + diff == 0)
367 ctl_real_free_beio(beio);
368 }
369
370 static void
ctl_free_beio(struct ctl_be_block_io * beio)371 ctl_free_beio(struct ctl_be_block_io *beio)
372 {
373
374 ctl_refcnt_beio(beio, -1);
375 }
376
377 static void
ctl_complete_beio(struct ctl_be_block_io * beio)378 ctl_complete_beio(struct ctl_be_block_io *beio)
379 {
380 union ctl_io *io = beio->io;
381
382 if (beio->beio_cont != NULL) {
383 beio->beio_cont(beio);
384 } else {
385 ctl_free_beio(beio);
386 ctl_data_submit_done(io);
387 }
388 }
389
390 static size_t
cmp(uint8_t * a,uint8_t * b,size_t size)391 cmp(uint8_t *a, uint8_t *b, size_t size)
392 {
393 size_t i;
394
395 for (i = 0; i < size; i++) {
396 if (a[i] != b[i])
397 break;
398 }
399 return (i);
400 }
401
402 static void
ctl_be_block_compare(union ctl_io * io)403 ctl_be_block_compare(union ctl_io *io)
404 {
405 struct ctl_be_block_io *beio;
406 uint64_t off, res;
407 int i;
408 uint8_t info[8];
409
410 beio = (struct ctl_be_block_io *)PRIV(io)->ptr;
411 off = 0;
412 for (i = 0; i < beio->num_segs; i++) {
413 res = cmp(beio->sg_segs[i].addr,
414 beio->sg_segs[i + CTLBLK_HALF_SEGS].addr,
415 beio->sg_segs[i].len);
416 off += res;
417 if (res < beio->sg_segs[i].len)
418 break;
419 }
420 if (i < beio->num_segs) {
421 scsi_u64to8b(off, info);
422 ctl_set_sense(&io->scsiio, /*current_error*/ 1,
423 /*sense_key*/ SSD_KEY_MISCOMPARE,
424 /*asc*/ 0x1D, /*ascq*/ 0x00,
425 /*type*/ SSD_ELEM_INFO,
426 /*size*/ sizeof(info), /*data*/ &info,
427 /*type*/ SSD_ELEM_NONE);
428 } else
429 ctl_set_success(&io->scsiio);
430 }
431
432 static int
ctl_be_block_move_done(union ctl_io * io,bool samethr)433 ctl_be_block_move_done(union ctl_io *io, bool samethr)
434 {
435 struct ctl_be_block_io *beio;
436 struct ctl_be_block_lun *be_lun;
437 struct ctl_lba_len_flags *lbalen;
438
439 beio = (struct ctl_be_block_io *)PRIV(io)->ptr;
440
441 DPRINTF("entered\n");
442 io->scsiio.kern_rel_offset += io->scsiio.kern_data_len;
443
444 /*
445 * We set status at this point for read and compare commands.
446 */
447 if ((io->io_hdr.flags & CTL_FLAG_ABORT) == 0 &&
448 (io->io_hdr.status & CTL_STATUS_MASK) == CTL_STATUS_NONE) {
449 lbalen = ARGS(io);
450 if (lbalen->flags & CTL_LLF_READ) {
451 ctl_set_success(&io->scsiio);
452 } else if (lbalen->flags & CTL_LLF_COMPARE) {
453 /* We have two data blocks ready for comparison. */
454 ctl_be_block_compare(io);
455 }
456 }
457
458 /*
459 * If this is a read, or a write with errors, it is done.
460 */
461 if ((beio->bio_cmd == BIO_READ)
462 || ((io->io_hdr.flags & CTL_FLAG_ABORT) != 0)
463 || ((io->io_hdr.status & CTL_STATUS_MASK) != CTL_STATUS_NONE)) {
464 ctl_complete_beio(beio);
465 return (0);
466 }
467
468 /*
469 * At this point, we have a write and the DMA completed successfully.
470 * If we were called synchronously in the original thread then just
471 * dispatch, otherwise we now have to queue it to the task queue to
472 * execute the backend I/O. That is because we do blocking
473 * memory allocations, and in the file backing case, blocking I/O.
474 * This move done routine is generally called in the SIM's
475 * interrupt context, and therefore we cannot block.
476 */
477 be_lun = (struct ctl_be_block_lun *)CTL_BACKEND_LUN(io);
478 if (samethr) {
479 be_lun->dispatch(be_lun, beio);
480 } else {
481 mtx_lock(&be_lun->queue_lock);
482 STAILQ_INSERT_TAIL(&be_lun->datamove_queue, &io->io_hdr, links);
483 mtx_unlock(&be_lun->queue_lock);
484 taskqueue_enqueue(be_lun->io_taskqueue, &be_lun->io_task);
485 }
486 return (0);
487 }
488
489 static void
ctl_be_block_biodone(struct bio * bio)490 ctl_be_block_biodone(struct bio *bio)
491 {
492 struct ctl_be_block_io *beio = bio->bio_caller1;
493 struct ctl_be_block_lun *be_lun = beio->lun;
494 struct ctl_be_lun *cbe_lun = &be_lun->cbe_lun;
495 union ctl_io *io;
496 int error;
497
498 io = beio->io;
499
500 DPRINTF("entered\n");
501
502 error = bio->bio_error;
503 mtx_lock(&be_lun->io_lock);
504 if (error != 0 &&
505 (beio->first_error == 0 ||
506 bio->bio_offset < beio->first_error_offset)) {
507 beio->first_error = error;
508 beio->first_error_offset = bio->bio_offset;
509 }
510
511 beio->num_bios_done++;
512
513 /*
514 * XXX KDM will this cause WITNESS to complain? Holding a lock
515 * during the free might cause it to complain.
516 */
517 g_destroy_bio(bio);
518
519 /*
520 * If the send complete bit isn't set, or we aren't the last I/O to
521 * complete, then we're done.
522 */
523 if ((beio->send_complete == 0)
524 || (beio->num_bios_done < beio->num_bios_sent)) {
525 mtx_unlock(&be_lun->io_lock);
526 return;
527 }
528
529 /*
530 * At this point, we've verified that we are the last I/O to
531 * complete, so it's safe to drop the lock.
532 */
533 devstat_end_transaction(beio->lun->disk_stats, beio->io_len,
534 beio->ds_tag_type, beio->ds_trans_type,
535 /*now*/ NULL, /*then*/&beio->ds_t0);
536 mtx_unlock(&be_lun->io_lock);
537
538 /*
539 * If there are any errors from the backing device, we fail the
540 * entire I/O with a medium error.
541 */
542 error = beio->first_error;
543 if (error != 0) {
544 if (error == EOPNOTSUPP) {
545 ctl_set_invalid_opcode(&io->scsiio);
546 } else if (error == ENOSPC || error == EDQUOT) {
547 ctl_set_space_alloc_fail(&io->scsiio);
548 } else if (error == EROFS || error == EACCES) {
549 ctl_set_hw_write_protected(&io->scsiio);
550 } else if (beio->bio_cmd == BIO_FLUSH) {
551 /* XXX KDM is there is a better error here? */
552 ctl_set_internal_failure(&io->scsiio,
553 /*sks_valid*/ 1,
554 /*retry_count*/ 0xbad2);
555 } else {
556 ctl_set_medium_error(&io->scsiio,
557 beio->bio_cmd == BIO_READ);
558 }
559 ctl_complete_beio(beio);
560 return;
561 }
562
563 /*
564 * If this is a write, a flush, a delete or verify, we're all done.
565 * If this is a read, we can now send the data to the user.
566 */
567 if ((beio->bio_cmd == BIO_WRITE)
568 || (beio->bio_cmd == BIO_FLUSH)
569 || (beio->bio_cmd == BIO_DELETE)
570 || (ARGS(io)->flags & CTL_LLF_VERIFY)) {
571 ctl_set_success(&io->scsiio);
572 ctl_complete_beio(beio);
573 } else {
574 if ((ARGS(io)->flags & CTL_LLF_READ) &&
575 beio->beio_cont == NULL) {
576 ctl_set_success(&io->scsiio);
577 if (cbe_lun->serseq >= CTL_LUN_SERSEQ_SOFT)
578 ctl_serseq_done(io);
579 }
580 ctl_datamove(io);
581 }
582 }
583
584 static void
ctl_be_block_flush_file(struct ctl_be_block_lun * be_lun,struct ctl_be_block_io * beio)585 ctl_be_block_flush_file(struct ctl_be_block_lun *be_lun,
586 struct ctl_be_block_io *beio)
587 {
588 union ctl_io *io = beio->io;
589 struct mount *mountpoint;
590 int error;
591
592 DPRINTF("entered\n");
593
594 binuptime(&beio->ds_t0);
595 devstat_start_transaction(beio->lun->disk_stats, &beio->ds_t0);
596
597 (void) vn_start_write(be_lun->vn, &mountpoint, V_WAIT);
598
599 vn_lock(be_lun->vn, vn_lktype_write(mountpoint, be_lun->vn) |
600 LK_RETRY);
601 error = VOP_FSYNC(be_lun->vn, beio->io_arg ? MNT_NOWAIT : MNT_WAIT,
602 curthread);
603 VOP_UNLOCK(be_lun->vn);
604
605 vn_finished_write(mountpoint);
606
607 mtx_lock(&be_lun->io_lock);
608 devstat_end_transaction(beio->lun->disk_stats, beio->io_len,
609 beio->ds_tag_type, beio->ds_trans_type,
610 /*now*/ NULL, /*then*/&beio->ds_t0);
611 mtx_unlock(&be_lun->io_lock);
612
613 if (error == 0)
614 ctl_set_success(&io->scsiio);
615 else {
616 /* XXX KDM is there is a better error here? */
617 ctl_set_internal_failure(&io->scsiio,
618 /*sks_valid*/ 1,
619 /*retry_count*/ 0xbad1);
620 }
621
622 ctl_complete_beio(beio);
623 }
624
625 SDT_PROBE_DEFINE1(cbb, , read, file_start, "uint64_t");
626 SDT_PROBE_DEFINE1(cbb, , write, file_start, "uint64_t");
627 SDT_PROBE_DEFINE1(cbb, , read, file_done,"uint64_t");
628 SDT_PROBE_DEFINE1(cbb, , write, file_done, "uint64_t");
629
630 static void
ctl_be_block_dispatch_file(struct ctl_be_block_lun * be_lun,struct ctl_be_block_io * beio)631 ctl_be_block_dispatch_file(struct ctl_be_block_lun *be_lun,
632 struct ctl_be_block_io *beio)
633 {
634 struct ctl_be_lun *cbe_lun = &be_lun->cbe_lun;
635 struct ctl_be_block_filedata *file_data;
636 union ctl_io *io;
637 struct uio xuio;
638 struct iovec *xiovec;
639 size_t s;
640 int error, flags, i;
641
642 DPRINTF("entered\n");
643
644 file_data = &be_lun->backend.file;
645 io = beio->io;
646 flags = 0;
647 if (ARGS(io)->flags & CTL_LLF_DPO)
648 flags |= IO_DIRECT;
649 if (beio->bio_cmd == BIO_WRITE && ARGS(io)->flags & CTL_LLF_FUA)
650 flags |= IO_SYNC;
651
652 bzero(&xuio, sizeof(xuio));
653 if (beio->bio_cmd == BIO_READ) {
654 SDT_PROBE0(cbb, , read, file_start);
655 xuio.uio_rw = UIO_READ;
656 } else {
657 SDT_PROBE0(cbb, , write, file_start);
658 xuio.uio_rw = UIO_WRITE;
659 }
660 xuio.uio_offset = beio->io_offset;
661 xuio.uio_resid = beio->io_len;
662 xuio.uio_segflg = UIO_SYSSPACE;
663 xuio.uio_iov = beio->xiovecs;
664 xuio.uio_iovcnt = beio->num_segs;
665 xuio.uio_td = curthread;
666
667 for (i = 0, xiovec = xuio.uio_iov; i < xuio.uio_iovcnt; i++, xiovec++) {
668 xiovec->iov_base = beio->sg_segs[i].addr;
669 xiovec->iov_len = beio->sg_segs[i].len;
670 }
671
672 binuptime(&beio->ds_t0);
673 devstat_start_transaction(beio->lun->disk_stats, &beio->ds_t0);
674
675 if (beio->bio_cmd == BIO_READ) {
676 vn_lock(be_lun->vn, LK_SHARED | LK_RETRY);
677
678 if (beio->beio_cont == NULL &&
679 cbe_lun->serseq == CTL_LUN_SERSEQ_SOFT)
680 ctl_serseq_done(io);
681 /*
682 * UFS pays attention to IO_DIRECT for reads. If the
683 * DIRECTIO option is configured into the kernel, it calls
684 * ffs_rawread(). But that only works for single-segment
685 * uios with user space addresses. In our case, with a
686 * kernel uio, it still reads into the buffer cache, but it
687 * will just try to release the buffer from the cache later
688 * on in ffs_read().
689 *
690 * ZFS does not pay attention to IO_DIRECT for reads.
691 *
692 * UFS does not pay attention to IO_SYNC for reads.
693 *
694 * ZFS pays attention to IO_SYNC (which translates into the
695 * Solaris define FRSYNC for zfs_read()) for reads. It
696 * attempts to sync the file before reading.
697 */
698 error = VOP_READ(be_lun->vn, &xuio, flags, file_data->cred);
699
700 VOP_UNLOCK(be_lun->vn);
701 SDT_PROBE0(cbb, , read, file_done);
702 if (error == 0 && xuio.uio_resid > 0) {
703 /*
704 * If we red less then requested (EOF), then
705 * we should clean the rest of the buffer.
706 */
707 s = beio->io_len - xuio.uio_resid;
708 for (i = 0; i < beio->num_segs; i++) {
709 if (s >= beio->sg_segs[i].len) {
710 s -= beio->sg_segs[i].len;
711 continue;
712 }
713 bzero((uint8_t *)beio->sg_segs[i].addr + s,
714 beio->sg_segs[i].len - s);
715 s = 0;
716 }
717 }
718 } else {
719 struct mount *mountpoint;
720
721 (void)vn_start_write(be_lun->vn, &mountpoint, V_WAIT);
722 vn_lock(be_lun->vn, vn_lktype_write(mountpoint,
723 be_lun->vn) | LK_RETRY);
724
725 /*
726 * UFS pays attention to IO_DIRECT for writes. The write
727 * is done asynchronously. (Normally the write would just
728 * get put into cache.
729 *
730 * UFS pays attention to IO_SYNC for writes. It will
731 * attempt to write the buffer out synchronously if that
732 * flag is set.
733 *
734 * ZFS does not pay attention to IO_DIRECT for writes.
735 *
736 * ZFS pays attention to IO_SYNC (a.k.a. FSYNC or FRSYNC)
737 * for writes. It will flush the transaction from the
738 * cache before returning.
739 */
740 error = VOP_WRITE(be_lun->vn, &xuio, flags, file_data->cred);
741 VOP_UNLOCK(be_lun->vn);
742
743 vn_finished_write(mountpoint);
744 SDT_PROBE0(cbb, , write, file_done);
745 }
746
747 mtx_lock(&be_lun->io_lock);
748 devstat_end_transaction(beio->lun->disk_stats, beio->io_len,
749 beio->ds_tag_type, beio->ds_trans_type,
750 /*now*/ NULL, /*then*/&beio->ds_t0);
751 mtx_unlock(&be_lun->io_lock);
752
753 /*
754 * If we got an error, set the sense data to "MEDIUM ERROR" and
755 * return the I/O to the user.
756 */
757 if (error != 0) {
758 if (error == ENOSPC || error == EDQUOT) {
759 ctl_set_space_alloc_fail(&io->scsiio);
760 } else if (error == EROFS || error == EACCES) {
761 ctl_set_hw_write_protected(&io->scsiio);
762 } else {
763 ctl_set_medium_error(&io->scsiio,
764 beio->bio_cmd == BIO_READ);
765 }
766 ctl_complete_beio(beio);
767 return;
768 }
769
770 /*
771 * If this is a write or a verify, we're all done.
772 * If this is a read, we can now send the data to the user.
773 */
774 if ((beio->bio_cmd == BIO_WRITE) ||
775 (ARGS(io)->flags & CTL_LLF_VERIFY)) {
776 ctl_set_success(&io->scsiio);
777 ctl_complete_beio(beio);
778 } else {
779 if ((ARGS(io)->flags & CTL_LLF_READ) &&
780 beio->beio_cont == NULL) {
781 ctl_set_success(&io->scsiio);
782 if (cbe_lun->serseq > CTL_LUN_SERSEQ_SOFT)
783 ctl_serseq_done(io);
784 }
785 ctl_datamove(io);
786 }
787 }
788
789 static void
ctl_be_block_gls_file(struct ctl_be_block_lun * be_lun,struct ctl_be_block_io * beio)790 ctl_be_block_gls_file(struct ctl_be_block_lun *be_lun,
791 struct ctl_be_block_io *beio)
792 {
793 union ctl_io *io = beio->io;
794 struct ctl_lba_len_flags *lbalen = ARGS(io);
795 struct scsi_get_lba_status_data *data;
796 off_t roff, off;
797 int error, status;
798
799 DPRINTF("entered\n");
800
801 off = roff = ((off_t)lbalen->lba) * be_lun->cbe_lun.blocksize;
802 vn_lock(be_lun->vn, LK_SHARED | LK_RETRY);
803 error = VOP_IOCTL(be_lun->vn, FIOSEEKHOLE, &off,
804 0, curthread->td_ucred, curthread);
805 if (error == 0 && off > roff)
806 status = 0; /* mapped up to off */
807 else {
808 error = VOP_IOCTL(be_lun->vn, FIOSEEKDATA, &off,
809 0, curthread->td_ucred, curthread);
810 if (error == 0 && off > roff)
811 status = 1; /* deallocated up to off */
812 else {
813 status = 0; /* unknown up to the end */
814 off = be_lun->size_bytes;
815 }
816 }
817 VOP_UNLOCK(be_lun->vn);
818
819 data = (struct scsi_get_lba_status_data *)io->scsiio.kern_data_ptr;
820 scsi_u64to8b(lbalen->lba, data->descr[0].addr);
821 scsi_ulto4b(MIN(UINT32_MAX, off / be_lun->cbe_lun.blocksize -
822 lbalen->lba), data->descr[0].length);
823 data->descr[0].status = status;
824
825 ctl_complete_beio(beio);
826 }
827
828 static uint64_t
ctl_be_block_getattr_file(struct ctl_be_block_lun * be_lun,const char * attrname)829 ctl_be_block_getattr_file(struct ctl_be_block_lun *be_lun, const char *attrname)
830 {
831 struct vattr vattr;
832 struct statfs statfs;
833 uint64_t val;
834 int error;
835
836 val = UINT64_MAX;
837 if (be_lun->vn == NULL)
838 return (val);
839 vn_lock(be_lun->vn, LK_SHARED | LK_RETRY);
840 if (strcmp(attrname, "blocksused") == 0) {
841 error = VOP_GETATTR(be_lun->vn, &vattr, curthread->td_ucred);
842 if (error == 0)
843 val = vattr.va_bytes / be_lun->cbe_lun.blocksize;
844 }
845 if (strcmp(attrname, "blocksavail") == 0 &&
846 !VN_IS_DOOMED(be_lun->vn)) {
847 error = VFS_STATFS(be_lun->vn->v_mount, &statfs);
848 if (error == 0)
849 val = statfs.f_bavail * statfs.f_bsize /
850 be_lun->cbe_lun.blocksize;
851 }
852 VOP_UNLOCK(be_lun->vn);
853 return (val);
854 }
855
856 static void
ctl_be_block_dispatch_zvol(struct ctl_be_block_lun * be_lun,struct ctl_be_block_io * beio)857 ctl_be_block_dispatch_zvol(struct ctl_be_block_lun *be_lun,
858 struct ctl_be_block_io *beio)
859 {
860 struct ctl_be_lun *cbe_lun = &be_lun->cbe_lun;
861 union ctl_io *io;
862 struct cdevsw *csw;
863 struct cdev *dev;
864 struct uio xuio;
865 struct iovec *xiovec;
866 int error, flags, i, ref;
867
868 DPRINTF("entered\n");
869
870 io = beio->io;
871 flags = 0;
872 if (ARGS(io)->flags & CTL_LLF_DPO)
873 flags |= IO_DIRECT;
874 if (beio->bio_cmd == BIO_WRITE && ARGS(io)->flags & CTL_LLF_FUA)
875 flags |= IO_SYNC;
876
877 bzero(&xuio, sizeof(xuio));
878 if (beio->bio_cmd == BIO_READ) {
879 SDT_PROBE0(cbb, , read, file_start);
880 xuio.uio_rw = UIO_READ;
881 } else {
882 SDT_PROBE0(cbb, , write, file_start);
883 xuio.uio_rw = UIO_WRITE;
884 }
885 xuio.uio_offset = beio->io_offset;
886 xuio.uio_resid = beio->io_len;
887 xuio.uio_segflg = UIO_SYSSPACE;
888 xuio.uio_iov = beio->xiovecs;
889 xuio.uio_iovcnt = beio->num_segs;
890 xuio.uio_td = curthread;
891
892 for (i = 0, xiovec = xuio.uio_iov; i < xuio.uio_iovcnt; i++, xiovec++) {
893 xiovec->iov_base = beio->sg_segs[i].addr;
894 xiovec->iov_len = beio->sg_segs[i].len;
895 }
896
897 binuptime(&beio->ds_t0);
898 devstat_start_transaction(beio->lun->disk_stats, &beio->ds_t0);
899
900 csw = devvn_refthread(be_lun->vn, &dev, &ref);
901 if (csw) {
902 if (beio->bio_cmd == BIO_READ) {
903 if (beio->beio_cont == NULL &&
904 cbe_lun->serseq == CTL_LUN_SERSEQ_SOFT)
905 ctl_serseq_done(io);
906 error = csw->d_read(dev, &xuio, flags);
907 } else
908 error = csw->d_write(dev, &xuio, flags);
909 dev_relthread(dev, ref);
910 } else
911 error = ENXIO;
912
913 if (beio->bio_cmd == BIO_READ)
914 SDT_PROBE0(cbb, , read, file_done);
915 else
916 SDT_PROBE0(cbb, , write, file_done);
917
918 mtx_lock(&be_lun->io_lock);
919 devstat_end_transaction(beio->lun->disk_stats, beio->io_len,
920 beio->ds_tag_type, beio->ds_trans_type,
921 /*now*/ NULL, /*then*/&beio->ds_t0);
922 mtx_unlock(&be_lun->io_lock);
923
924 /*
925 * If we got an error, set the sense data to "MEDIUM ERROR" and
926 * return the I/O to the user.
927 */
928 if (error != 0) {
929 if (error == ENOSPC || error == EDQUOT) {
930 ctl_set_space_alloc_fail(&io->scsiio);
931 } else if (error == EROFS || error == EACCES) {
932 ctl_set_hw_write_protected(&io->scsiio);
933 } else {
934 ctl_set_medium_error(&io->scsiio,
935 beio->bio_cmd == BIO_READ);
936 }
937 ctl_complete_beio(beio);
938 return;
939 }
940
941 /*
942 * If this is a write or a verify, we're all done.
943 * If this is a read, we can now send the data to the user.
944 */
945 if ((beio->bio_cmd == BIO_WRITE) ||
946 (ARGS(io)->flags & CTL_LLF_VERIFY)) {
947 ctl_set_success(&io->scsiio);
948 ctl_complete_beio(beio);
949 } else {
950 if ((ARGS(io)->flags & CTL_LLF_READ) &&
951 beio->beio_cont == NULL) {
952 ctl_set_success(&io->scsiio);
953 if (cbe_lun->serseq > CTL_LUN_SERSEQ_SOFT)
954 ctl_serseq_done(io);
955 }
956 ctl_datamove(io);
957 }
958 }
959
960 static void
ctl_be_block_gls_zvol(struct ctl_be_block_lun * be_lun,struct ctl_be_block_io * beio)961 ctl_be_block_gls_zvol(struct ctl_be_block_lun *be_lun,
962 struct ctl_be_block_io *beio)
963 {
964 union ctl_io *io = beio->io;
965 struct cdevsw *csw;
966 struct cdev *dev;
967 struct ctl_lba_len_flags *lbalen = ARGS(io);
968 struct scsi_get_lba_status_data *data;
969 off_t roff, off;
970 int error, ref, status;
971
972 DPRINTF("entered\n");
973
974 csw = devvn_refthread(be_lun->vn, &dev, &ref);
975 if (csw == NULL) {
976 status = 0; /* unknown up to the end */
977 off = be_lun->size_bytes;
978 goto done;
979 }
980 off = roff = ((off_t)lbalen->lba) * be_lun->cbe_lun.blocksize;
981 error = csw->d_ioctl(dev, FIOSEEKHOLE, (caddr_t)&off, FREAD,
982 curthread);
983 if (error == 0 && off > roff)
984 status = 0; /* mapped up to off */
985 else {
986 error = csw->d_ioctl(dev, FIOSEEKDATA, (caddr_t)&off, FREAD,
987 curthread);
988 if (error == 0 && off > roff)
989 status = 1; /* deallocated up to off */
990 else {
991 status = 0; /* unknown up to the end */
992 off = be_lun->size_bytes;
993 }
994 }
995 dev_relthread(dev, ref);
996
997 done:
998 data = (struct scsi_get_lba_status_data *)io->scsiio.kern_data_ptr;
999 scsi_u64to8b(lbalen->lba, data->descr[0].addr);
1000 scsi_ulto4b(MIN(UINT32_MAX, off / be_lun->cbe_lun.blocksize -
1001 lbalen->lba), data->descr[0].length);
1002 data->descr[0].status = status;
1003
1004 ctl_complete_beio(beio);
1005 }
1006
1007 static void
ctl_be_block_flush_dev(struct ctl_be_block_lun * be_lun,struct ctl_be_block_io * beio)1008 ctl_be_block_flush_dev(struct ctl_be_block_lun *be_lun,
1009 struct ctl_be_block_io *beio)
1010 {
1011 struct bio *bio;
1012 struct cdevsw *csw;
1013 struct cdev *dev;
1014 int ref;
1015
1016 DPRINTF("entered\n");
1017
1018 /* This can't fail, it's a blocking allocation. */
1019 bio = g_alloc_bio();
1020
1021 bio->bio_cmd = BIO_FLUSH;
1022 bio->bio_offset = 0;
1023 bio->bio_data = 0;
1024 bio->bio_done = ctl_be_block_biodone;
1025 bio->bio_caller1 = beio;
1026 bio->bio_pblkno = 0;
1027
1028 /*
1029 * We don't need to acquire the LUN lock here, because we are only
1030 * sending one bio, and so there is no other context to synchronize
1031 * with.
1032 */
1033 beio->num_bios_sent = 1;
1034 beio->send_complete = 1;
1035
1036 binuptime(&beio->ds_t0);
1037 devstat_start_transaction(be_lun->disk_stats, &beio->ds_t0);
1038
1039 csw = devvn_refthread(be_lun->vn, &dev, &ref);
1040 if (csw) {
1041 bio->bio_dev = dev;
1042 csw->d_strategy(bio);
1043 dev_relthread(dev, ref);
1044 } else {
1045 bio->bio_error = ENXIO;
1046 ctl_be_block_biodone(bio);
1047 }
1048 }
1049
1050 static void
ctl_be_block_unmap_dev_range(struct ctl_be_block_lun * be_lun,struct ctl_be_block_io * beio,uint64_t off,uint64_t len,int last)1051 ctl_be_block_unmap_dev_range(struct ctl_be_block_lun *be_lun,
1052 struct ctl_be_block_io *beio,
1053 uint64_t off, uint64_t len, int last)
1054 {
1055 struct bio *bio;
1056 uint64_t maxlen;
1057 struct cdevsw *csw;
1058 struct cdev *dev;
1059 int ref;
1060
1061 csw = devvn_refthread(be_lun->vn, &dev, &ref);
1062 maxlen = LONG_MAX - (LONG_MAX % be_lun->cbe_lun.blocksize);
1063 while (len > 0) {
1064 bio = g_alloc_bio();
1065 bio->bio_cmd = BIO_DELETE;
1066 bio->bio_dev = dev;
1067 bio->bio_offset = off;
1068 bio->bio_length = MIN(len, maxlen);
1069 bio->bio_data = 0;
1070 bio->bio_done = ctl_be_block_biodone;
1071 bio->bio_caller1 = beio;
1072 bio->bio_pblkno = off / be_lun->cbe_lun.blocksize;
1073
1074 off += bio->bio_length;
1075 len -= bio->bio_length;
1076
1077 mtx_lock(&be_lun->io_lock);
1078 beio->num_bios_sent++;
1079 if (last && len == 0)
1080 beio->send_complete = 1;
1081 mtx_unlock(&be_lun->io_lock);
1082
1083 if (csw) {
1084 csw->d_strategy(bio);
1085 } else {
1086 bio->bio_error = ENXIO;
1087 ctl_be_block_biodone(bio);
1088 }
1089 }
1090 if (csw)
1091 dev_relthread(dev, ref);
1092 }
1093
1094 static void
ctl_be_block_unmap_dev(struct ctl_be_block_lun * be_lun,struct ctl_be_block_io * beio)1095 ctl_be_block_unmap_dev(struct ctl_be_block_lun *be_lun,
1096 struct ctl_be_block_io *beio)
1097 {
1098 union ctl_io *io;
1099 struct ctl_ptr_len_flags *ptrlen;
1100 struct scsi_unmap_desc *buf, *end;
1101 uint64_t len;
1102
1103 io = beio->io;
1104
1105 DPRINTF("entered\n");
1106
1107 binuptime(&beio->ds_t0);
1108 devstat_start_transaction(be_lun->disk_stats, &beio->ds_t0);
1109
1110 if (beio->io_offset == -1) {
1111 beio->io_len = 0;
1112 ptrlen = (struct ctl_ptr_len_flags *)&io->io_hdr.ctl_private[CTL_PRIV_LBA_LEN];
1113 buf = (struct scsi_unmap_desc *)ptrlen->ptr;
1114 end = buf + ptrlen->len / sizeof(*buf);
1115 for (; buf < end; buf++) {
1116 len = (uint64_t)scsi_4btoul(buf->length) *
1117 be_lun->cbe_lun.blocksize;
1118 beio->io_len += len;
1119 ctl_be_block_unmap_dev_range(be_lun, beio,
1120 scsi_8btou64(buf->lba) * be_lun->cbe_lun.blocksize,
1121 len, (end - buf < 2) ? TRUE : FALSE);
1122 }
1123 } else
1124 ctl_be_block_unmap_dev_range(be_lun, beio,
1125 beio->io_offset, beio->io_len, TRUE);
1126 }
1127
1128 static void
ctl_be_block_dispatch_dev(struct ctl_be_block_lun * be_lun,struct ctl_be_block_io * beio)1129 ctl_be_block_dispatch_dev(struct ctl_be_block_lun *be_lun,
1130 struct ctl_be_block_io *beio)
1131 {
1132 TAILQ_HEAD(, bio) queue = TAILQ_HEAD_INITIALIZER(queue);
1133 struct bio *bio;
1134 struct cdevsw *csw;
1135 struct cdev *dev;
1136 off_t cur_offset;
1137 int i, max_iosize, ref;
1138
1139 DPRINTF("entered\n");
1140 csw = devvn_refthread(be_lun->vn, &dev, &ref);
1141
1142 /*
1143 * We have to limit our I/O size to the maximum supported by the
1144 * backend device.
1145 */
1146 if (csw) {
1147 max_iosize = dev->si_iosize_max;
1148 if (max_iosize <= 0)
1149 max_iosize = DFLTPHYS;
1150 } else
1151 max_iosize = maxphys;
1152
1153 cur_offset = beio->io_offset;
1154 for (i = 0; i < beio->num_segs; i++) {
1155 size_t cur_size;
1156 uint8_t *cur_ptr;
1157
1158 cur_size = beio->sg_segs[i].len;
1159 cur_ptr = beio->sg_segs[i].addr;
1160
1161 while (cur_size > 0) {
1162 /* This can't fail, it's a blocking allocation. */
1163 bio = g_alloc_bio();
1164
1165 KASSERT(bio != NULL, ("g_alloc_bio() failed!\n"));
1166
1167 bio->bio_cmd = beio->bio_cmd;
1168 bio->bio_dev = dev;
1169 bio->bio_caller1 = beio;
1170 bio->bio_length = min(cur_size, max_iosize);
1171 bio->bio_offset = cur_offset;
1172 bio->bio_data = cur_ptr;
1173 bio->bio_done = ctl_be_block_biodone;
1174 bio->bio_pblkno = cur_offset / be_lun->cbe_lun.blocksize;
1175
1176 cur_offset += bio->bio_length;
1177 cur_ptr += bio->bio_length;
1178 cur_size -= bio->bio_length;
1179
1180 TAILQ_INSERT_TAIL(&queue, bio, bio_queue);
1181 beio->num_bios_sent++;
1182 }
1183 }
1184 beio->send_complete = 1;
1185 binuptime(&beio->ds_t0);
1186 devstat_start_transaction(be_lun->disk_stats, &beio->ds_t0);
1187
1188 /*
1189 * Fire off all allocated requests!
1190 */
1191 while ((bio = TAILQ_FIRST(&queue)) != NULL) {
1192 TAILQ_REMOVE(&queue, bio, bio_queue);
1193 if (csw)
1194 csw->d_strategy(bio);
1195 else {
1196 bio->bio_error = ENXIO;
1197 ctl_be_block_biodone(bio);
1198 }
1199 }
1200 if (csw)
1201 dev_relthread(dev, ref);
1202 }
1203
1204 static uint64_t
ctl_be_block_getattr_dev(struct ctl_be_block_lun * be_lun,const char * attrname)1205 ctl_be_block_getattr_dev(struct ctl_be_block_lun *be_lun, const char *attrname)
1206 {
1207 struct diocgattr_arg arg;
1208 struct cdevsw *csw;
1209 struct cdev *dev;
1210 int error, ref;
1211
1212 csw = devvn_refthread(be_lun->vn, &dev, &ref);
1213 if (csw == NULL)
1214 return (UINT64_MAX);
1215 strlcpy(arg.name, attrname, sizeof(arg.name));
1216 arg.len = sizeof(arg.value.off);
1217 if (csw->d_ioctl) {
1218 error = csw->d_ioctl(dev, DIOCGATTR, (caddr_t)&arg, FREAD,
1219 curthread);
1220 } else
1221 error = ENODEV;
1222 dev_relthread(dev, ref);
1223 if (error != 0)
1224 return (UINT64_MAX);
1225 return (arg.value.off);
1226 }
1227
1228 static void
ctl_be_block_cw_dispatch_sync(struct ctl_be_block_lun * be_lun,union ctl_io * io)1229 ctl_be_block_cw_dispatch_sync(struct ctl_be_block_lun *be_lun,
1230 union ctl_io *io)
1231 {
1232 struct ctl_be_lun *cbe_lun = &be_lun->cbe_lun;
1233 struct ctl_be_block_io *beio;
1234 struct ctl_lba_len_flags *lbalen;
1235
1236 DPRINTF("entered\n");
1237 beio = (struct ctl_be_block_io *)PRIV(io)->ptr;
1238 lbalen = (struct ctl_lba_len_flags *)&io->io_hdr.ctl_private[CTL_PRIV_LBA_LEN];
1239
1240 beio->io_len = lbalen->len * cbe_lun->blocksize;
1241 beio->io_offset = lbalen->lba * cbe_lun->blocksize;
1242 beio->io_arg = (lbalen->flags & SSC_IMMED) != 0;
1243 beio->bio_cmd = BIO_FLUSH;
1244 beio->ds_trans_type = DEVSTAT_NO_DATA;
1245 DPRINTF("SYNC\n");
1246 be_lun->lun_flush(be_lun, beio);
1247 }
1248
1249 static void
ctl_be_block_cw_done_ws(struct ctl_be_block_io * beio)1250 ctl_be_block_cw_done_ws(struct ctl_be_block_io *beio)
1251 {
1252 union ctl_io *io;
1253
1254 io = beio->io;
1255 ctl_free_beio(beio);
1256 if ((io->io_hdr.flags & CTL_FLAG_ABORT) ||
1257 ((io->io_hdr.status & CTL_STATUS_MASK) != CTL_STATUS_NONE &&
1258 (io->io_hdr.status & CTL_STATUS_MASK) != CTL_SUCCESS)) {
1259 ctl_config_write_done(io);
1260 return;
1261 }
1262
1263 ctl_be_block_config_write(io);
1264 }
1265
1266 static void
ctl_be_block_cw_dispatch_ws(struct ctl_be_block_lun * be_lun,union ctl_io * io)1267 ctl_be_block_cw_dispatch_ws(struct ctl_be_block_lun *be_lun,
1268 union ctl_io *io)
1269 {
1270 struct ctl_be_block_softc *softc = be_lun->softc;
1271 struct ctl_be_lun *cbe_lun = &be_lun->cbe_lun;
1272 struct ctl_be_block_io *beio;
1273 struct ctl_lba_len_flags *lbalen;
1274 uint64_t len_left, lba;
1275 uint32_t pb, pbo, adj;
1276 int i, seglen;
1277 uint8_t *buf, *end;
1278
1279 DPRINTF("entered\n");
1280
1281 beio = (struct ctl_be_block_io *)PRIV(io)->ptr;
1282 lbalen = ARGS(io);
1283
1284 if (lbalen->flags & ~(SWS_LBDATA | SWS_UNMAP | SWS_ANCHOR | SWS_NDOB) ||
1285 (lbalen->flags & (SWS_UNMAP | SWS_ANCHOR) && be_lun->unmap == NULL)) {
1286 ctl_free_beio(beio);
1287 ctl_set_invalid_field(&io->scsiio,
1288 /*sks_valid*/ 1,
1289 /*command*/ 1,
1290 /*field*/ 1,
1291 /*bit_valid*/ 0,
1292 /*bit*/ 0);
1293 ctl_config_write_done(io);
1294 return;
1295 }
1296
1297 if (lbalen->flags & (SWS_UNMAP | SWS_ANCHOR)) {
1298 beio->io_offset = lbalen->lba * cbe_lun->blocksize;
1299 beio->io_len = (uint64_t)lbalen->len * cbe_lun->blocksize;
1300 beio->bio_cmd = BIO_DELETE;
1301 beio->ds_trans_type = DEVSTAT_FREE;
1302
1303 be_lun->unmap(be_lun, beio);
1304 return;
1305 }
1306
1307 beio->bio_cmd = BIO_WRITE;
1308 beio->ds_trans_type = DEVSTAT_WRITE;
1309
1310 DPRINTF("WRITE SAME at LBA %jx len %u\n",
1311 (uintmax_t)lbalen->lba, lbalen->len);
1312
1313 pb = cbe_lun->blocksize << be_lun->cbe_lun.pblockexp;
1314 if (be_lun->cbe_lun.pblockoff > 0)
1315 pbo = pb - cbe_lun->blocksize * be_lun->cbe_lun.pblockoff;
1316 else
1317 pbo = 0;
1318 len_left = (uint64_t)lbalen->len * cbe_lun->blocksize;
1319 for (i = 0, lba = 0; i < CTLBLK_MAX_SEGS && len_left > 0; i++) {
1320 /*
1321 * Setup the S/G entry for this chunk.
1322 */
1323 seglen = MIN(CTLBLK_MAX_SEG, len_left);
1324 if (pb > cbe_lun->blocksize) {
1325 adj = ((lbalen->lba + lba) * cbe_lun->blocksize +
1326 seglen - pbo) % pb;
1327 if (seglen > adj)
1328 seglen -= adj;
1329 else
1330 seglen -= seglen % cbe_lun->blocksize;
1331 } else
1332 seglen -= seglen % cbe_lun->blocksize;
1333 ctl_alloc_seg(softc, &beio->sg_segs[i], seglen);
1334
1335 DPRINTF("segment %d addr %p len %zd\n", i,
1336 beio->sg_segs[i].addr, beio->sg_segs[i].len);
1337
1338 beio->num_segs++;
1339 len_left -= seglen;
1340
1341 buf = beio->sg_segs[i].addr;
1342 end = buf + seglen;
1343 for (; buf < end; buf += cbe_lun->blocksize) {
1344 if (lbalen->flags & SWS_NDOB) {
1345 memset(buf, 0, cbe_lun->blocksize);
1346 } else {
1347 memcpy(buf, io->scsiio.kern_data_ptr,
1348 cbe_lun->blocksize);
1349 }
1350 if (lbalen->flags & SWS_LBDATA)
1351 scsi_ulto4b(lbalen->lba + lba, buf);
1352 lba++;
1353 }
1354 }
1355
1356 beio->io_offset = lbalen->lba * cbe_lun->blocksize;
1357 beio->io_len = lba * cbe_lun->blocksize;
1358
1359 /* We can not do all in one run. Correct and schedule rerun. */
1360 if (len_left > 0) {
1361 lbalen->lba += lba;
1362 lbalen->len -= lba;
1363 beio->beio_cont = ctl_be_block_cw_done_ws;
1364 }
1365
1366 be_lun->dispatch(be_lun, beio);
1367 }
1368
1369 static void
ctl_be_block_cw_dispatch_unmap(struct ctl_be_block_lun * be_lun,union ctl_io * io)1370 ctl_be_block_cw_dispatch_unmap(struct ctl_be_block_lun *be_lun,
1371 union ctl_io *io)
1372 {
1373 struct ctl_be_block_io *beio;
1374 struct ctl_ptr_len_flags *ptrlen;
1375
1376 DPRINTF("entered\n");
1377
1378 beio = (struct ctl_be_block_io *)PRIV(io)->ptr;
1379 ptrlen = (struct ctl_ptr_len_flags *)&io->io_hdr.ctl_private[CTL_PRIV_LBA_LEN];
1380
1381 if ((ptrlen->flags & ~SU_ANCHOR) != 0 || be_lun->unmap == NULL) {
1382 ctl_free_beio(beio);
1383 ctl_set_invalid_field(&io->scsiio,
1384 /*sks_valid*/ 0,
1385 /*command*/ 1,
1386 /*field*/ 0,
1387 /*bit_valid*/ 0,
1388 /*bit*/ 0);
1389 ctl_config_write_done(io);
1390 return;
1391 }
1392
1393 beio->io_len = 0;
1394 beio->io_offset = -1;
1395 beio->bio_cmd = BIO_DELETE;
1396 beio->ds_trans_type = DEVSTAT_FREE;
1397 DPRINTF("UNMAP\n");
1398 be_lun->unmap(be_lun, beio);
1399 }
1400
1401 static void
ctl_be_block_cr_done(struct ctl_be_block_io * beio)1402 ctl_be_block_cr_done(struct ctl_be_block_io *beio)
1403 {
1404 union ctl_io *io;
1405
1406 io = beio->io;
1407 ctl_free_beio(beio);
1408 ctl_config_read_done(io);
1409 }
1410
1411 static void
ctl_be_block_cr_dispatch(struct ctl_be_block_lun * be_lun,union ctl_io * io)1412 ctl_be_block_cr_dispatch(struct ctl_be_block_lun *be_lun,
1413 union ctl_io *io)
1414 {
1415 struct ctl_be_block_io *beio;
1416 struct ctl_be_block_softc *softc;
1417
1418 DPRINTF("entered\n");
1419
1420 softc = be_lun->softc;
1421 beio = ctl_alloc_beio(softc);
1422 beio->io = io;
1423 beio->lun = be_lun;
1424 beio->beio_cont = ctl_be_block_cr_done;
1425 PRIV(io)->ptr = (void *)beio;
1426
1427 switch (io->scsiio.cdb[0]) {
1428 case SERVICE_ACTION_IN: /* GET LBA STATUS */
1429 beio->bio_cmd = -1;
1430 beio->ds_trans_type = DEVSTAT_NO_DATA;
1431 beio->ds_tag_type = DEVSTAT_TAG_ORDERED;
1432 beio->io_len = 0;
1433 if (be_lun->get_lba_status)
1434 be_lun->get_lba_status(be_lun, beio);
1435 else
1436 ctl_be_block_cr_done(beio);
1437 break;
1438 default:
1439 panic("Unhandled CDB type %#x", io->scsiio.cdb[0]);
1440 break;
1441 }
1442 }
1443
1444 static void
ctl_be_block_cw_done(struct ctl_be_block_io * beio)1445 ctl_be_block_cw_done(struct ctl_be_block_io *beio)
1446 {
1447 union ctl_io *io;
1448
1449 io = beio->io;
1450 ctl_free_beio(beio);
1451 ctl_config_write_done(io);
1452 }
1453
1454 static void
ctl_be_block_cw_dispatch(struct ctl_be_block_lun * be_lun,union ctl_io * io)1455 ctl_be_block_cw_dispatch(struct ctl_be_block_lun *be_lun,
1456 union ctl_io *io)
1457 {
1458 struct ctl_be_block_io *beio;
1459 struct ctl_be_block_softc *softc;
1460
1461 DPRINTF("entered\n");
1462
1463 softc = be_lun->softc;
1464 beio = ctl_alloc_beio(softc);
1465 beio->io = io;
1466 beio->lun = be_lun;
1467 beio->beio_cont = ctl_be_block_cw_done;
1468 switch (io->scsiio.tag_type) {
1469 case CTL_TAG_ORDERED:
1470 beio->ds_tag_type = DEVSTAT_TAG_ORDERED;
1471 break;
1472 case CTL_TAG_HEAD_OF_QUEUE:
1473 beio->ds_tag_type = DEVSTAT_TAG_HEAD;
1474 break;
1475 case CTL_TAG_UNTAGGED:
1476 case CTL_TAG_SIMPLE:
1477 case CTL_TAG_ACA:
1478 default:
1479 beio->ds_tag_type = DEVSTAT_TAG_SIMPLE;
1480 break;
1481 }
1482 PRIV(io)->ptr = (void *)beio;
1483
1484 switch (io->scsiio.cdb[0]) {
1485 case SYNCHRONIZE_CACHE:
1486 case SYNCHRONIZE_CACHE_16:
1487 ctl_be_block_cw_dispatch_sync(be_lun, io);
1488 break;
1489 case WRITE_SAME_10:
1490 case WRITE_SAME_16:
1491 ctl_be_block_cw_dispatch_ws(be_lun, io);
1492 break;
1493 case UNMAP:
1494 ctl_be_block_cw_dispatch_unmap(be_lun, io);
1495 break;
1496 default:
1497 panic("Unhandled CDB type %#x", io->scsiio.cdb[0]);
1498 break;
1499 }
1500 }
1501
1502 SDT_PROBE_DEFINE1(cbb, , read, start, "uint64_t");
1503 SDT_PROBE_DEFINE1(cbb, , write, start, "uint64_t");
1504 SDT_PROBE_DEFINE1(cbb, , read, alloc_done, "uint64_t");
1505 SDT_PROBE_DEFINE1(cbb, , write, alloc_done, "uint64_t");
1506
1507 static void
ctl_be_block_next(struct ctl_be_block_io * beio)1508 ctl_be_block_next(struct ctl_be_block_io *beio)
1509 {
1510 struct ctl_be_block_lun *be_lun;
1511 union ctl_io *io;
1512
1513 io = beio->io;
1514 be_lun = beio->lun;
1515 ctl_free_beio(beio);
1516 if ((io->io_hdr.flags & CTL_FLAG_ABORT) ||
1517 ((io->io_hdr.status & CTL_STATUS_MASK) != CTL_STATUS_NONE &&
1518 (io->io_hdr.status & CTL_STATUS_MASK) != CTL_SUCCESS)) {
1519 ctl_data_submit_done(io);
1520 return;
1521 }
1522
1523 io->io_hdr.status &= ~CTL_STATUS_MASK;
1524 io->io_hdr.status |= CTL_STATUS_NONE;
1525
1526 mtx_lock(&be_lun->queue_lock);
1527 STAILQ_INSERT_TAIL(&be_lun->input_queue, &io->io_hdr, links);
1528 mtx_unlock(&be_lun->queue_lock);
1529 taskqueue_enqueue(be_lun->io_taskqueue, &be_lun->io_task);
1530 }
1531
1532 static void
ctl_be_block_dispatch(struct ctl_be_block_lun * be_lun,union ctl_io * io)1533 ctl_be_block_dispatch(struct ctl_be_block_lun *be_lun,
1534 union ctl_io *io)
1535 {
1536 struct ctl_be_lun *cbe_lun = &be_lun->cbe_lun;
1537 struct ctl_be_block_io *beio;
1538 struct ctl_be_block_softc *softc;
1539 struct ctl_lba_len_flags *lbalen;
1540 struct ctl_ptr_len_flags *bptrlen;
1541 uint64_t len_left, lbas;
1542 int i;
1543
1544 softc = be_lun->softc;
1545
1546 DPRINTF("entered\n");
1547
1548 lbalen = ARGS(io);
1549 if (lbalen->flags & CTL_LLF_WRITE) {
1550 SDT_PROBE0(cbb, , write, start);
1551 } else {
1552 SDT_PROBE0(cbb, , read, start);
1553 }
1554
1555 beio = ctl_alloc_beio(softc);
1556 beio->io = io;
1557 beio->lun = be_lun;
1558 bptrlen = PRIV(io);
1559 bptrlen->ptr = (void *)beio;
1560
1561 switch (io->scsiio.tag_type) {
1562 case CTL_TAG_ORDERED:
1563 beio->ds_tag_type = DEVSTAT_TAG_ORDERED;
1564 break;
1565 case CTL_TAG_HEAD_OF_QUEUE:
1566 beio->ds_tag_type = DEVSTAT_TAG_HEAD;
1567 break;
1568 case CTL_TAG_UNTAGGED:
1569 case CTL_TAG_SIMPLE:
1570 case CTL_TAG_ACA:
1571 default:
1572 beio->ds_tag_type = DEVSTAT_TAG_SIMPLE;
1573 break;
1574 }
1575
1576 if (lbalen->flags & CTL_LLF_WRITE) {
1577 beio->bio_cmd = BIO_WRITE;
1578 beio->ds_trans_type = DEVSTAT_WRITE;
1579 } else {
1580 beio->bio_cmd = BIO_READ;
1581 beio->ds_trans_type = DEVSTAT_READ;
1582 }
1583
1584 DPRINTF("%s at LBA %jx len %u @%ju\n",
1585 (beio->bio_cmd == BIO_READ) ? "READ" : "WRITE",
1586 (uintmax_t)lbalen->lba, lbalen->len, bptrlen->len);
1587 lbas = CTLBLK_MAX_IO_SIZE;
1588 if (lbalen->flags & CTL_LLF_COMPARE) {
1589 beio->two_sglists = 1;
1590 lbas /= 2;
1591 }
1592 lbas = MIN(lbalen->len - bptrlen->len, lbas / cbe_lun->blocksize);
1593 beio->io_offset = (lbalen->lba + bptrlen->len) * cbe_lun->blocksize;
1594 beio->io_len = lbas * cbe_lun->blocksize;
1595 bptrlen->len += lbas;
1596
1597 for (i = 0, len_left = beio->io_len; len_left > 0; i++) {
1598 KASSERT(i < CTLBLK_MAX_SEGS, ("Too many segs (%d >= %d)",
1599 i, CTLBLK_MAX_SEGS));
1600
1601 /*
1602 * Setup the S/G entry for this chunk.
1603 */
1604 ctl_alloc_seg(softc, &beio->sg_segs[i],
1605 MIN(CTLBLK_MAX_SEG, len_left));
1606
1607 DPRINTF("segment %d addr %p len %zd\n", i,
1608 beio->sg_segs[i].addr, beio->sg_segs[i].len);
1609
1610 /* Set up second segment for compare operation. */
1611 if (beio->two_sglists) {
1612 ctl_alloc_seg(softc,
1613 &beio->sg_segs[i + CTLBLK_HALF_SEGS],
1614 beio->sg_segs[i].len);
1615 }
1616
1617 beio->num_segs++;
1618 len_left -= beio->sg_segs[i].len;
1619 }
1620 if (bptrlen->len < lbalen->len)
1621 beio->beio_cont = ctl_be_block_next;
1622 io->scsiio.be_move_done = ctl_be_block_move_done;
1623 /* For compare we have separate S/G lists for read and datamove. */
1624 if (beio->two_sglists)
1625 io->scsiio.kern_data_ptr = (uint8_t *)&beio->sg_segs[CTLBLK_HALF_SEGS];
1626 else
1627 io->scsiio.kern_data_ptr = (uint8_t *)beio->sg_segs;
1628 io->scsiio.kern_data_len = beio->io_len;
1629 io->scsiio.kern_sg_entries = beio->num_segs;
1630 io->scsiio.kern_data_ref = ctl_refcnt_beio;
1631 io->scsiio.kern_data_arg = beio;
1632 io->io_hdr.flags |= CTL_FLAG_ALLOCATED;
1633
1634 /*
1635 * For the read case, we need to read the data into our buffers and
1636 * then we can send it back to the user. For the write case, we
1637 * need to get the data from the user first.
1638 */
1639 if (beio->bio_cmd == BIO_READ) {
1640 SDT_PROBE0(cbb, , read, alloc_done);
1641 be_lun->dispatch(be_lun, beio);
1642 } else {
1643 SDT_PROBE0(cbb, , write, alloc_done);
1644 ctl_datamove(io);
1645 }
1646 }
1647
1648 static void
ctl_be_block_worker(void * context,int pending)1649 ctl_be_block_worker(void *context, int pending)
1650 {
1651 struct ctl_be_block_lun *be_lun = (struct ctl_be_block_lun *)context;
1652 struct ctl_be_lun *cbe_lun = &be_lun->cbe_lun;
1653 union ctl_io *io;
1654 struct ctl_be_block_io *beio;
1655
1656 DPRINTF("entered\n");
1657 /*
1658 * Fetch and process I/Os from all queues. If we detect LUN
1659 * CTL_LUN_FLAG_NO_MEDIA status here -- it is result of a race,
1660 * so make response maximally opaque to not confuse initiator.
1661 */
1662 for (;;) {
1663 mtx_lock(&be_lun->queue_lock);
1664 io = (union ctl_io *)STAILQ_FIRST(&be_lun->datamove_queue);
1665 if (io != NULL) {
1666 DPRINTF("datamove queue\n");
1667 STAILQ_REMOVE_HEAD(&be_lun->datamove_queue, links);
1668 mtx_unlock(&be_lun->queue_lock);
1669 beio = (struct ctl_be_block_io *)PRIV(io)->ptr;
1670 if (cbe_lun->flags & CTL_LUN_FLAG_NO_MEDIA) {
1671 ctl_set_busy(&io->scsiio);
1672 ctl_complete_beio(beio);
1673 continue;
1674 }
1675 be_lun->dispatch(be_lun, beio);
1676 continue;
1677 }
1678 io = (union ctl_io *)STAILQ_FIRST(&be_lun->config_write_queue);
1679 if (io != NULL) {
1680 DPRINTF("config write queue\n");
1681 STAILQ_REMOVE_HEAD(&be_lun->config_write_queue, links);
1682 mtx_unlock(&be_lun->queue_lock);
1683 if (cbe_lun->flags & CTL_LUN_FLAG_NO_MEDIA) {
1684 ctl_set_busy(&io->scsiio);
1685 ctl_config_write_done(io);
1686 continue;
1687 }
1688 ctl_be_block_cw_dispatch(be_lun, io);
1689 continue;
1690 }
1691 io = (union ctl_io *)STAILQ_FIRST(&be_lun->config_read_queue);
1692 if (io != NULL) {
1693 DPRINTF("config read queue\n");
1694 STAILQ_REMOVE_HEAD(&be_lun->config_read_queue, links);
1695 mtx_unlock(&be_lun->queue_lock);
1696 if (cbe_lun->flags & CTL_LUN_FLAG_NO_MEDIA) {
1697 ctl_set_busy(&io->scsiio);
1698 ctl_config_read_done(io);
1699 continue;
1700 }
1701 ctl_be_block_cr_dispatch(be_lun, io);
1702 continue;
1703 }
1704 io = (union ctl_io *)STAILQ_FIRST(&be_lun->input_queue);
1705 if (io != NULL) {
1706 DPRINTF("input queue\n");
1707 STAILQ_REMOVE_HEAD(&be_lun->input_queue, links);
1708 mtx_unlock(&be_lun->queue_lock);
1709 if (cbe_lun->flags & CTL_LUN_FLAG_NO_MEDIA) {
1710 ctl_set_busy(&io->scsiio);
1711 ctl_data_submit_done(io);
1712 continue;
1713 }
1714 ctl_be_block_dispatch(be_lun, io);
1715 continue;
1716 }
1717
1718 /*
1719 * If we get here, there is no work left in the queues, so
1720 * just break out and let the task queue go to sleep.
1721 */
1722 mtx_unlock(&be_lun->queue_lock);
1723 break;
1724 }
1725 }
1726
1727 /*
1728 * Entry point from CTL to the backend for I/O. We queue everything to a
1729 * work thread, so this just puts the I/O on a queue and wakes up the
1730 * thread.
1731 */
1732 static int
ctl_be_block_submit(union ctl_io * io)1733 ctl_be_block_submit(union ctl_io *io)
1734 {
1735 struct ctl_be_block_lun *be_lun;
1736
1737 DPRINTF("entered\n");
1738
1739 be_lun = (struct ctl_be_block_lun *)CTL_BACKEND_LUN(io);
1740
1741 KASSERT(io->io_hdr.io_type == CTL_IO_SCSI,
1742 ("%s: unexpected I/O type %x", __func__, io->io_hdr.io_type));
1743
1744 PRIV(io)->len = 0;
1745
1746 mtx_lock(&be_lun->queue_lock);
1747 STAILQ_INSERT_TAIL(&be_lun->input_queue, &io->io_hdr, links);
1748 mtx_unlock(&be_lun->queue_lock);
1749 taskqueue_enqueue(be_lun->io_taskqueue, &be_lun->io_task);
1750
1751 return (CTL_RETVAL_COMPLETE);
1752 }
1753
1754 static int
ctl_be_block_ioctl(struct cdev * dev,u_long cmd,caddr_t addr,int flag,struct thread * td)1755 ctl_be_block_ioctl(struct cdev *dev, u_long cmd, caddr_t addr,
1756 int flag, struct thread *td)
1757 {
1758 struct ctl_be_block_softc *softc = &backend_block_softc;
1759 int error;
1760
1761 error = 0;
1762 switch (cmd) {
1763 case CTL_LUN_REQ: {
1764 struct ctl_lun_req *lun_req;
1765
1766 lun_req = (struct ctl_lun_req *)addr;
1767
1768 switch (lun_req->reqtype) {
1769 case CTL_LUNREQ_CREATE:
1770 error = ctl_be_block_create(softc, lun_req);
1771 break;
1772 case CTL_LUNREQ_RM:
1773 error = ctl_be_block_rm(softc, lun_req);
1774 break;
1775 case CTL_LUNREQ_MODIFY:
1776 error = ctl_be_block_modify(softc, lun_req);
1777 break;
1778 default:
1779 lun_req->status = CTL_LUN_ERROR;
1780 snprintf(lun_req->error_str, sizeof(lun_req->error_str),
1781 "invalid LUN request type %d",
1782 lun_req->reqtype);
1783 break;
1784 }
1785 break;
1786 }
1787 default:
1788 error = ENOTTY;
1789 break;
1790 }
1791
1792 return (error);
1793 }
1794
1795 static int
ctl_be_block_open_file(struct ctl_be_block_lun * be_lun,struct ctl_lun_req * req)1796 ctl_be_block_open_file(struct ctl_be_block_lun *be_lun, struct ctl_lun_req *req)
1797 {
1798 struct ctl_be_lun *cbe_lun;
1799 struct ctl_be_block_filedata *file_data;
1800 struct ctl_lun_create_params *params;
1801 const char *value;
1802 struct vattr vattr;
1803 off_t ps, pss, po, pos, us, uss, uo, uos;
1804 int error;
1805
1806 cbe_lun = &be_lun->cbe_lun;
1807 file_data = &be_lun->backend.file;
1808 params = &be_lun->params;
1809
1810 be_lun->dev_type = CTL_BE_BLOCK_FILE;
1811 be_lun->dispatch = ctl_be_block_dispatch_file;
1812 be_lun->lun_flush = ctl_be_block_flush_file;
1813 be_lun->get_lba_status = ctl_be_block_gls_file;
1814 be_lun->getattr = ctl_be_block_getattr_file;
1815 be_lun->unmap = NULL;
1816 cbe_lun->flags &= ~CTL_LUN_FLAG_UNMAP;
1817
1818 error = VOP_GETATTR(be_lun->vn, &vattr, curthread->td_ucred);
1819 if (error != 0) {
1820 snprintf(req->error_str, sizeof(req->error_str),
1821 "error calling VOP_GETATTR() for file %s",
1822 be_lun->dev_path);
1823 return (error);
1824 }
1825
1826 file_data->cred = crhold(curthread->td_ucred);
1827 if (params->lun_size_bytes != 0)
1828 be_lun->size_bytes = params->lun_size_bytes;
1829 else
1830 be_lun->size_bytes = vattr.va_size;
1831
1832 /*
1833 * For files we can use any logical block size. Prefer 512 bytes
1834 * for compatibility reasons. If file's vattr.va_blocksize
1835 * (preferred I/O block size) is bigger and multiple to chosen
1836 * logical block size -- report it as physical block size.
1837 */
1838 if (params->blocksize_bytes != 0)
1839 cbe_lun->blocksize = params->blocksize_bytes;
1840 else if (cbe_lun->lun_type == T_CDROM)
1841 cbe_lun->blocksize = 2048;
1842 else
1843 cbe_lun->blocksize = 512;
1844 be_lun->size_blocks = be_lun->size_bytes / cbe_lun->blocksize;
1845 cbe_lun->maxlba = (be_lun->size_blocks == 0) ?
1846 0 : (be_lun->size_blocks - 1);
1847
1848 us = ps = vattr.va_blocksize;
1849 uo = po = 0;
1850
1851 value = dnvlist_get_string(cbe_lun->options, "pblocksize", NULL);
1852 if (value != NULL)
1853 ctl_expand_number(value, &ps);
1854 value = dnvlist_get_string(cbe_lun->options, "pblockoffset", NULL);
1855 if (value != NULL)
1856 ctl_expand_number(value, &po);
1857 pss = ps / cbe_lun->blocksize;
1858 pos = po / cbe_lun->blocksize;
1859 if ((pss > 0) && (pss * cbe_lun->blocksize == ps) && (pss >= pos) &&
1860 ((pss & (pss - 1)) == 0) && (pos * cbe_lun->blocksize == po)) {
1861 cbe_lun->pblockexp = fls(pss) - 1;
1862 cbe_lun->pblockoff = (pss - pos) % pss;
1863 }
1864
1865 value = dnvlist_get_string(cbe_lun->options, "ublocksize", NULL);
1866 if (value != NULL)
1867 ctl_expand_number(value, &us);
1868 value = dnvlist_get_string(cbe_lun->options, "ublockoffset", NULL);
1869 if (value != NULL)
1870 ctl_expand_number(value, &uo);
1871 uss = us / cbe_lun->blocksize;
1872 uos = uo / cbe_lun->blocksize;
1873 if ((uss > 0) && (uss * cbe_lun->blocksize == us) && (uss >= uos) &&
1874 ((uss & (uss - 1)) == 0) && (uos * cbe_lun->blocksize == uo)) {
1875 cbe_lun->ublockexp = fls(uss) - 1;
1876 cbe_lun->ublockoff = (uss - uos) % uss;
1877 }
1878
1879 /*
1880 * Sanity check. The media size has to be at least one
1881 * sector long.
1882 */
1883 if (be_lun->size_bytes < cbe_lun->blocksize) {
1884 error = EINVAL;
1885 snprintf(req->error_str, sizeof(req->error_str),
1886 "file %s size %ju < block size %u", be_lun->dev_path,
1887 (uintmax_t)be_lun->size_bytes, cbe_lun->blocksize);
1888 }
1889
1890 cbe_lun->opttxferlen = CTLBLK_MAX_IO_SIZE / cbe_lun->blocksize;
1891 return (error);
1892 }
1893
1894 static int
ctl_be_block_open_dev(struct ctl_be_block_lun * be_lun,struct ctl_lun_req * req)1895 ctl_be_block_open_dev(struct ctl_be_block_lun *be_lun, struct ctl_lun_req *req)
1896 {
1897 struct ctl_be_lun *cbe_lun = &be_lun->cbe_lun;
1898 struct ctl_lun_create_params *params;
1899 struct cdevsw *csw;
1900 struct cdev *dev;
1901 const char *value;
1902 int error, atomic, maxio, ref, unmap, tmp;
1903 off_t ps, pss, po, pos, us, uss, uo, uos, otmp;
1904
1905 params = &be_lun->params;
1906
1907 be_lun->dev_type = CTL_BE_BLOCK_DEV;
1908 csw = devvn_refthread(be_lun->vn, &dev, &ref);
1909 if (csw == NULL)
1910 return (ENXIO);
1911 if (strcmp(csw->d_name, "zvol") == 0) {
1912 be_lun->dispatch = ctl_be_block_dispatch_zvol;
1913 be_lun->get_lba_status = ctl_be_block_gls_zvol;
1914 atomic = maxio = CTLBLK_MAX_IO_SIZE;
1915 } else {
1916 be_lun->dispatch = ctl_be_block_dispatch_dev;
1917 be_lun->get_lba_status = NULL;
1918 atomic = 0;
1919 maxio = dev->si_iosize_max;
1920 if (maxio <= 0)
1921 maxio = DFLTPHYS;
1922 if (maxio > CTLBLK_MAX_SEG)
1923 maxio = CTLBLK_MAX_SEG;
1924 }
1925 be_lun->lun_flush = ctl_be_block_flush_dev;
1926 be_lun->getattr = ctl_be_block_getattr_dev;
1927 be_lun->unmap = ctl_be_block_unmap_dev;
1928
1929 if (!csw->d_ioctl) {
1930 dev_relthread(dev, ref);
1931 snprintf(req->error_str, sizeof(req->error_str),
1932 "no d_ioctl for device %s!", be_lun->dev_path);
1933 return (ENODEV);
1934 }
1935
1936 error = csw->d_ioctl(dev, DIOCGSECTORSIZE, (caddr_t)&tmp, FREAD,
1937 curthread);
1938 if (error) {
1939 dev_relthread(dev, ref);
1940 snprintf(req->error_str, sizeof(req->error_str),
1941 "error %d returned for DIOCGSECTORSIZE ioctl "
1942 "on %s!", error, be_lun->dev_path);
1943 return (error);
1944 }
1945
1946 /*
1947 * If the user has asked for a blocksize that is greater than the
1948 * backing device's blocksize, we can do it only if the blocksize
1949 * the user is asking for is an even multiple of the underlying
1950 * device's blocksize.
1951 */
1952 if ((params->blocksize_bytes != 0) &&
1953 (params->blocksize_bytes >= tmp)) {
1954 if (params->blocksize_bytes % tmp == 0) {
1955 cbe_lun->blocksize = params->blocksize_bytes;
1956 } else {
1957 dev_relthread(dev, ref);
1958 snprintf(req->error_str, sizeof(req->error_str),
1959 "requested blocksize %u is not an even "
1960 "multiple of backing device blocksize %u",
1961 params->blocksize_bytes, tmp);
1962 return (EINVAL);
1963 }
1964 } else if (params->blocksize_bytes != 0) {
1965 dev_relthread(dev, ref);
1966 snprintf(req->error_str, sizeof(req->error_str),
1967 "requested blocksize %u < backing device "
1968 "blocksize %u", params->blocksize_bytes, tmp);
1969 return (EINVAL);
1970 } else if (cbe_lun->lun_type == T_CDROM)
1971 cbe_lun->blocksize = MAX(tmp, 2048);
1972 else
1973 cbe_lun->blocksize = tmp;
1974
1975 error = csw->d_ioctl(dev, DIOCGMEDIASIZE, (caddr_t)&otmp, FREAD,
1976 curthread);
1977 if (error) {
1978 dev_relthread(dev, ref);
1979 snprintf(req->error_str, sizeof(req->error_str),
1980 "error %d returned for DIOCGMEDIASIZE "
1981 " ioctl on %s!", error,
1982 be_lun->dev_path);
1983 return (error);
1984 }
1985
1986 if (params->lun_size_bytes != 0) {
1987 if (params->lun_size_bytes > otmp) {
1988 dev_relthread(dev, ref);
1989 snprintf(req->error_str, sizeof(req->error_str),
1990 "requested LUN size %ju > backing device "
1991 "size %ju",
1992 (uintmax_t)params->lun_size_bytes,
1993 (uintmax_t)otmp);
1994 return (EINVAL);
1995 }
1996
1997 be_lun->size_bytes = params->lun_size_bytes;
1998 } else
1999 be_lun->size_bytes = otmp;
2000 be_lun->size_blocks = be_lun->size_bytes / cbe_lun->blocksize;
2001 cbe_lun->maxlba = (be_lun->size_blocks == 0) ?
2002 0 : (be_lun->size_blocks - 1);
2003
2004 error = csw->d_ioctl(dev, DIOCGSTRIPESIZE, (caddr_t)&ps, FREAD,
2005 curthread);
2006 if (error)
2007 ps = po = 0;
2008 else {
2009 error = csw->d_ioctl(dev, DIOCGSTRIPEOFFSET, (caddr_t)&po,
2010 FREAD, curthread);
2011 if (error)
2012 po = 0;
2013 }
2014 us = ps;
2015 uo = po;
2016
2017 value = dnvlist_get_string(cbe_lun->options, "pblocksize", NULL);
2018 if (value != NULL)
2019 ctl_expand_number(value, &ps);
2020 value = dnvlist_get_string(cbe_lun->options, "pblockoffset", NULL);
2021 if (value != NULL)
2022 ctl_expand_number(value, &po);
2023 pss = ps / cbe_lun->blocksize;
2024 pos = po / cbe_lun->blocksize;
2025 if ((pss > 0) && (pss * cbe_lun->blocksize == ps) && (pss >= pos) &&
2026 ((pss & (pss - 1)) == 0) && (pos * cbe_lun->blocksize == po)) {
2027 cbe_lun->pblockexp = fls(pss) - 1;
2028 cbe_lun->pblockoff = (pss - pos) % pss;
2029 }
2030
2031 value = dnvlist_get_string(cbe_lun->options, "ublocksize", NULL);
2032 if (value != NULL)
2033 ctl_expand_number(value, &us);
2034 value = dnvlist_get_string(cbe_lun->options, "ublockoffset", NULL);
2035 if (value != NULL)
2036 ctl_expand_number(value, &uo);
2037 uss = us / cbe_lun->blocksize;
2038 uos = uo / cbe_lun->blocksize;
2039 if ((uss > 0) && (uss * cbe_lun->blocksize == us) && (uss >= uos) &&
2040 ((uss & (uss - 1)) == 0) && (uos * cbe_lun->blocksize == uo)) {
2041 cbe_lun->ublockexp = fls(uss) - 1;
2042 cbe_lun->ublockoff = (uss - uos) % uss;
2043 }
2044
2045 cbe_lun->atomicblock = atomic / cbe_lun->blocksize;
2046 cbe_lun->opttxferlen = maxio / cbe_lun->blocksize;
2047
2048 if (be_lun->dispatch == ctl_be_block_dispatch_zvol) {
2049 unmap = 1;
2050 } else {
2051 struct diocgattr_arg arg;
2052
2053 strlcpy(arg.name, "GEOM::candelete", sizeof(arg.name));
2054 arg.len = sizeof(arg.value.i);
2055 error = csw->d_ioctl(dev, DIOCGATTR, (caddr_t)&arg, FREAD,
2056 curthread);
2057 unmap = (error == 0) ? arg.value.i : 0;
2058 }
2059 value = dnvlist_get_string(cbe_lun->options, "unmap", NULL);
2060 if (value != NULL)
2061 unmap = (strcmp(value, "on") == 0);
2062 if (unmap)
2063 cbe_lun->flags |= CTL_LUN_FLAG_UNMAP;
2064 else
2065 cbe_lun->flags &= ~CTL_LUN_FLAG_UNMAP;
2066
2067 dev_relthread(dev, ref);
2068 return (0);
2069 }
2070
2071 static int
ctl_be_block_close(struct ctl_be_block_lun * be_lun)2072 ctl_be_block_close(struct ctl_be_block_lun *be_lun)
2073 {
2074 struct ctl_be_lun *cbe_lun = &be_lun->cbe_lun;
2075 int flags;
2076
2077 if (be_lun->vn) {
2078 flags = FREAD;
2079 if ((cbe_lun->flags & CTL_LUN_FLAG_READONLY) == 0)
2080 flags |= FWRITE;
2081 (void)vn_close(be_lun->vn, flags, NOCRED, curthread);
2082 be_lun->vn = NULL;
2083
2084 switch (be_lun->dev_type) {
2085 case CTL_BE_BLOCK_DEV:
2086 break;
2087 case CTL_BE_BLOCK_FILE:
2088 if (be_lun->backend.file.cred != NULL) {
2089 crfree(be_lun->backend.file.cred);
2090 be_lun->backend.file.cred = NULL;
2091 }
2092 break;
2093 case CTL_BE_BLOCK_NONE:
2094 break;
2095 default:
2096 panic("Unexpected backend type %d", be_lun->dev_type);
2097 break;
2098 }
2099 be_lun->dev_type = CTL_BE_BLOCK_NONE;
2100 }
2101 return (0);
2102 }
2103
2104 static int
ctl_be_block_open(struct ctl_be_block_lun * be_lun,struct ctl_lun_req * req)2105 ctl_be_block_open(struct ctl_be_block_lun *be_lun, struct ctl_lun_req *req)
2106 {
2107 struct ctl_be_lun *cbe_lun = &be_lun->cbe_lun;
2108 struct nameidata nd;
2109 const char *value;
2110 int error, flags;
2111
2112 error = 0;
2113 if (rootvnode == NULL) {
2114 snprintf(req->error_str, sizeof(req->error_str),
2115 "Root filesystem is not mounted");
2116 return (1);
2117 }
2118 pwd_ensure_dirs();
2119
2120 value = dnvlist_get_string(cbe_lun->options, "file", NULL);
2121 if (value == NULL) {
2122 snprintf(req->error_str, sizeof(req->error_str),
2123 "no file argument specified");
2124 return (1);
2125 }
2126 free(be_lun->dev_path, M_CTLBLK);
2127 be_lun->dev_path = strdup(value, M_CTLBLK);
2128
2129 flags = FREAD;
2130 value = dnvlist_get_string(cbe_lun->options, "readonly", NULL);
2131 if (value != NULL) {
2132 if (strcmp(value, "on") != 0)
2133 flags |= FWRITE;
2134 } else if (cbe_lun->lun_type == T_DIRECT)
2135 flags |= FWRITE;
2136
2137 again:
2138 NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, be_lun->dev_path, curthread);
2139 error = vn_open(&nd, &flags, 0, NULL);
2140 if ((error == EROFS || error == EACCES) && (flags & FWRITE)) {
2141 flags &= ~FWRITE;
2142 goto again;
2143 }
2144 if (error) {
2145 /*
2146 * This is the only reasonable guess we can make as far as
2147 * path if the user doesn't give us a fully qualified path.
2148 * If they want to specify a file, they need to specify the
2149 * full path.
2150 */
2151 if (be_lun->dev_path[0] != '/') {
2152 char *dev_name;
2153
2154 asprintf(&dev_name, M_CTLBLK, "/dev/%s",
2155 be_lun->dev_path);
2156 free(be_lun->dev_path, M_CTLBLK);
2157 be_lun->dev_path = dev_name;
2158 goto again;
2159 }
2160 snprintf(req->error_str, sizeof(req->error_str),
2161 "error opening %s: %d", be_lun->dev_path, error);
2162 return (error);
2163 }
2164 if (flags & FWRITE)
2165 cbe_lun->flags &= ~CTL_LUN_FLAG_READONLY;
2166 else
2167 cbe_lun->flags |= CTL_LUN_FLAG_READONLY;
2168
2169 NDFREE(&nd, NDF_ONLY_PNBUF);
2170 be_lun->vn = nd.ni_vp;
2171
2172 /* We only support disks and files. */
2173 if (vn_isdisk_error(be_lun->vn, &error)) {
2174 error = ctl_be_block_open_dev(be_lun, req);
2175 } else if (be_lun->vn->v_type == VREG) {
2176 error = ctl_be_block_open_file(be_lun, req);
2177 } else {
2178 error = EINVAL;
2179 snprintf(req->error_str, sizeof(req->error_str),
2180 "%s is not a disk or plain file", be_lun->dev_path);
2181 }
2182 VOP_UNLOCK(be_lun->vn);
2183
2184 if (error != 0)
2185 ctl_be_block_close(be_lun);
2186 cbe_lun->serseq = CTL_LUN_SERSEQ_OFF;
2187 if (be_lun->dispatch != ctl_be_block_dispatch_dev)
2188 cbe_lun->serseq = CTL_LUN_SERSEQ_SOFT;
2189 value = dnvlist_get_string(cbe_lun->options, "serseq", NULL);
2190 if (value != NULL && strcmp(value, "on") == 0)
2191 cbe_lun->serseq = CTL_LUN_SERSEQ_ON;
2192 else if (value != NULL && strcmp(value, "read") == 0)
2193 cbe_lun->serseq = CTL_LUN_SERSEQ_READ;
2194 else if (value != NULL && strcmp(value, "soft") == 0)
2195 cbe_lun->serseq = CTL_LUN_SERSEQ_SOFT;
2196 else if (value != NULL && strcmp(value, "off") == 0)
2197 cbe_lun->serseq = CTL_LUN_SERSEQ_OFF;
2198 return (0);
2199 }
2200
2201 static int
ctl_be_block_create(struct ctl_be_block_softc * softc,struct ctl_lun_req * req)2202 ctl_be_block_create(struct ctl_be_block_softc *softc, struct ctl_lun_req *req)
2203 {
2204 struct ctl_be_lun *cbe_lun;
2205 struct ctl_be_block_lun *be_lun;
2206 struct ctl_lun_create_params *params;
2207 char num_thread_str[16];
2208 char tmpstr[32];
2209 const char *value;
2210 int retval, num_threads;
2211 int tmp_num_threads;
2212
2213 params = &req->reqdata.create;
2214 retval = 0;
2215 req->status = CTL_LUN_OK;
2216
2217 be_lun = malloc(sizeof(*be_lun), M_CTLBLK, M_ZERO | M_WAITOK);
2218 cbe_lun = &be_lun->cbe_lun;
2219 be_lun->params = req->reqdata.create;
2220 be_lun->softc = softc;
2221 STAILQ_INIT(&be_lun->input_queue);
2222 STAILQ_INIT(&be_lun->config_read_queue);
2223 STAILQ_INIT(&be_lun->config_write_queue);
2224 STAILQ_INIT(&be_lun->datamove_queue);
2225 mtx_init(&be_lun->io_lock, "ctlblock io", NULL, MTX_DEF);
2226 mtx_init(&be_lun->queue_lock, "ctlblock queue", NULL, MTX_DEF);
2227 cbe_lun->options = nvlist_clone(req->args_nvl);
2228
2229 if (params->flags & CTL_LUN_FLAG_DEV_TYPE)
2230 cbe_lun->lun_type = params->device_type;
2231 else
2232 cbe_lun->lun_type = T_DIRECT;
2233 be_lun->flags = 0;
2234 cbe_lun->flags = 0;
2235 value = dnvlist_get_string(cbe_lun->options, "ha_role", NULL);
2236 if (value != NULL) {
2237 if (strcmp(value, "primary") == 0)
2238 cbe_lun->flags |= CTL_LUN_FLAG_PRIMARY;
2239 } else if (control_softc->flags & CTL_FLAG_ACTIVE_SHELF)
2240 cbe_lun->flags |= CTL_LUN_FLAG_PRIMARY;
2241
2242 if (cbe_lun->lun_type == T_DIRECT ||
2243 cbe_lun->lun_type == T_CDROM) {
2244 be_lun->size_bytes = params->lun_size_bytes;
2245 if (params->blocksize_bytes != 0)
2246 cbe_lun->blocksize = params->blocksize_bytes;
2247 else if (cbe_lun->lun_type == T_CDROM)
2248 cbe_lun->blocksize = 2048;
2249 else
2250 cbe_lun->blocksize = 512;
2251 be_lun->size_blocks = be_lun->size_bytes / cbe_lun->blocksize;
2252 cbe_lun->maxlba = (be_lun->size_blocks == 0) ?
2253 0 : (be_lun->size_blocks - 1);
2254
2255 if ((cbe_lun->flags & CTL_LUN_FLAG_PRIMARY) ||
2256 control_softc->ha_mode == CTL_HA_MODE_SER_ONLY) {
2257 retval = ctl_be_block_open(be_lun, req);
2258 if (retval != 0) {
2259 retval = 0;
2260 req->status = CTL_LUN_WARNING;
2261 }
2262 }
2263 num_threads = cbb_num_threads;
2264 } else {
2265 num_threads = 1;
2266 }
2267
2268 value = dnvlist_get_string(cbe_lun->options, "num_threads", NULL);
2269 if (value != NULL) {
2270 tmp_num_threads = strtol(value, NULL, 0);
2271
2272 /*
2273 * We don't let the user specify less than one
2274 * thread, but hope he's clueful enough not to
2275 * specify 1000 threads.
2276 */
2277 if (tmp_num_threads < 1) {
2278 snprintf(req->error_str, sizeof(req->error_str),
2279 "invalid number of threads %s",
2280 num_thread_str);
2281 goto bailout_error;
2282 }
2283 num_threads = tmp_num_threads;
2284 }
2285
2286 if (be_lun->vn == NULL)
2287 cbe_lun->flags |= CTL_LUN_FLAG_NO_MEDIA;
2288 /* Tell the user the blocksize we ended up using */
2289 params->lun_size_bytes = be_lun->size_bytes;
2290 params->blocksize_bytes = cbe_lun->blocksize;
2291 if (params->flags & CTL_LUN_FLAG_ID_REQ) {
2292 cbe_lun->req_lun_id = params->req_lun_id;
2293 cbe_lun->flags |= CTL_LUN_FLAG_ID_REQ;
2294 } else
2295 cbe_lun->req_lun_id = 0;
2296
2297 cbe_lun->lun_shutdown = ctl_be_block_lun_shutdown;
2298 cbe_lun->be = &ctl_be_block_driver;
2299
2300 if ((params->flags & CTL_LUN_FLAG_SERIAL_NUM) == 0) {
2301 snprintf(tmpstr, sizeof(tmpstr), "MYSERIAL%04d",
2302 softc->num_luns);
2303 strncpy((char *)cbe_lun->serial_num, tmpstr,
2304 MIN(sizeof(cbe_lun->serial_num), sizeof(tmpstr)));
2305
2306 /* Tell the user what we used for a serial number */
2307 strncpy((char *)params->serial_num, tmpstr,
2308 MIN(sizeof(params->serial_num), sizeof(tmpstr)));
2309 } else {
2310 strncpy((char *)cbe_lun->serial_num, params->serial_num,
2311 MIN(sizeof(cbe_lun->serial_num),
2312 sizeof(params->serial_num)));
2313 }
2314 if ((params->flags & CTL_LUN_FLAG_DEVID) == 0) {
2315 snprintf(tmpstr, sizeof(tmpstr), "MYDEVID%04d", softc->num_luns);
2316 strncpy((char *)cbe_lun->device_id, tmpstr,
2317 MIN(sizeof(cbe_lun->device_id), sizeof(tmpstr)));
2318
2319 /* Tell the user what we used for a device ID */
2320 strncpy((char *)params->device_id, tmpstr,
2321 MIN(sizeof(params->device_id), sizeof(tmpstr)));
2322 } else {
2323 strncpy((char *)cbe_lun->device_id, params->device_id,
2324 MIN(sizeof(cbe_lun->device_id),
2325 sizeof(params->device_id)));
2326 }
2327
2328 TASK_INIT(&be_lun->io_task, /*priority*/0, ctl_be_block_worker, be_lun);
2329
2330 be_lun->io_taskqueue = taskqueue_create("ctlblocktq", M_WAITOK,
2331 taskqueue_thread_enqueue, /*context*/&be_lun->io_taskqueue);
2332
2333 if (be_lun->io_taskqueue == NULL) {
2334 snprintf(req->error_str, sizeof(req->error_str),
2335 "unable to create taskqueue");
2336 goto bailout_error;
2337 }
2338
2339 /*
2340 * Note that we start the same number of threads by default for
2341 * both the file case and the block device case. For the file
2342 * case, we need multiple threads to allow concurrency, because the
2343 * vnode interface is designed to be a blocking interface. For the
2344 * block device case, ZFS zvols at least will block the caller's
2345 * context in many instances, and so we need multiple threads to
2346 * overcome that problem. Other block devices don't need as many
2347 * threads, but they shouldn't cause too many problems.
2348 *
2349 * If the user wants to just have a single thread for a block
2350 * device, he can specify that when the LUN is created, or change
2351 * the tunable/sysctl to alter the default number of threads.
2352 */
2353 retval = taskqueue_start_threads_in_proc(&be_lun->io_taskqueue,
2354 /*num threads*/num_threads,
2355 /*priority*/PUSER,
2356 /*proc*/control_softc->ctl_proc,
2357 /*thread name*/"block");
2358
2359 if (retval != 0)
2360 goto bailout_error;
2361
2362 be_lun->num_threads = num_threads;
2363
2364 retval = ctl_add_lun(&be_lun->cbe_lun);
2365 if (retval != 0) {
2366 snprintf(req->error_str, sizeof(req->error_str),
2367 "ctl_add_lun() returned error %d, see dmesg for "
2368 "details", retval);
2369 retval = 0;
2370 goto bailout_error;
2371 }
2372
2373 be_lun->disk_stats = devstat_new_entry("cbb", cbe_lun->lun_id,
2374 cbe_lun->blocksize,
2375 DEVSTAT_ALL_SUPPORTED,
2376 cbe_lun->lun_type
2377 | DEVSTAT_TYPE_IF_OTHER,
2378 DEVSTAT_PRIORITY_OTHER);
2379
2380 mtx_lock(&softc->lock);
2381 softc->num_luns++;
2382 SLIST_INSERT_HEAD(&softc->lun_list, be_lun, links);
2383 mtx_unlock(&softc->lock);
2384
2385 params->req_lun_id = cbe_lun->lun_id;
2386
2387 return (retval);
2388
2389 bailout_error:
2390 req->status = CTL_LUN_ERROR;
2391
2392 if (be_lun->io_taskqueue != NULL)
2393 taskqueue_free(be_lun->io_taskqueue);
2394 ctl_be_block_close(be_lun);
2395 if (be_lun->dev_path != NULL)
2396 free(be_lun->dev_path, M_CTLBLK);
2397 nvlist_destroy(cbe_lun->options);
2398 mtx_destroy(&be_lun->queue_lock);
2399 mtx_destroy(&be_lun->io_lock);
2400 free(be_lun, M_CTLBLK);
2401
2402 return (retval);
2403 }
2404
2405 static int
ctl_be_block_rm(struct ctl_be_block_softc * softc,struct ctl_lun_req * req)2406 ctl_be_block_rm(struct ctl_be_block_softc *softc, struct ctl_lun_req *req)
2407 {
2408 struct ctl_lun_rm_params *params;
2409 struct ctl_be_block_lun *be_lun;
2410 struct ctl_be_lun *cbe_lun;
2411 int retval;
2412
2413 params = &req->reqdata.rm;
2414
2415 sx_xlock(&softc->modify_lock);
2416 mtx_lock(&softc->lock);
2417 SLIST_FOREACH(be_lun, &softc->lun_list, links) {
2418 if (be_lun->cbe_lun.lun_id == params->lun_id) {
2419 SLIST_REMOVE(&softc->lun_list, be_lun,
2420 ctl_be_block_lun, links);
2421 softc->num_luns--;
2422 break;
2423 }
2424 }
2425 mtx_unlock(&softc->lock);
2426 sx_xunlock(&softc->modify_lock);
2427 if (be_lun == NULL) {
2428 snprintf(req->error_str, sizeof(req->error_str),
2429 "LUN %u is not managed by the block backend",
2430 params->lun_id);
2431 goto bailout_error;
2432 }
2433 cbe_lun = &be_lun->cbe_lun;
2434
2435 if (be_lun->vn != NULL) {
2436 cbe_lun->flags |= CTL_LUN_FLAG_NO_MEDIA;
2437 ctl_lun_no_media(cbe_lun);
2438 taskqueue_drain_all(be_lun->io_taskqueue);
2439 ctl_be_block_close(be_lun);
2440 }
2441
2442 mtx_lock(&softc->lock);
2443 be_lun->flags |= CTL_BE_BLOCK_LUN_WAITING;
2444 mtx_unlock(&softc->lock);
2445
2446 retval = ctl_remove_lun(cbe_lun);
2447 if (retval != 0) {
2448 snprintf(req->error_str, sizeof(req->error_str),
2449 "error %d returned from ctl_remove_lun() for "
2450 "LUN %d", retval, params->lun_id);
2451 mtx_lock(&softc->lock);
2452 be_lun->flags &= ~CTL_BE_BLOCK_LUN_WAITING;
2453 mtx_unlock(&softc->lock);
2454 goto bailout_error;
2455 }
2456
2457 mtx_lock(&softc->lock);
2458 while ((be_lun->flags & CTL_BE_BLOCK_LUN_UNCONFIGURED) == 0) {
2459 retval = msleep(be_lun, &softc->lock, PCATCH, "ctlblockrm", 0);
2460 if (retval == EINTR)
2461 break;
2462 }
2463 be_lun->flags &= ~CTL_BE_BLOCK_LUN_WAITING;
2464 if (be_lun->flags & CTL_BE_BLOCK_LUN_UNCONFIGURED) {
2465 mtx_unlock(&softc->lock);
2466 free(be_lun, M_CTLBLK);
2467 } else {
2468 mtx_unlock(&softc->lock);
2469 return (EINTR);
2470 }
2471
2472 req->status = CTL_LUN_OK;
2473 return (0);
2474
2475 bailout_error:
2476 req->status = CTL_LUN_ERROR;
2477 return (0);
2478 }
2479
2480 static int
ctl_be_block_modify(struct ctl_be_block_softc * softc,struct ctl_lun_req * req)2481 ctl_be_block_modify(struct ctl_be_block_softc *softc, struct ctl_lun_req *req)
2482 {
2483 struct ctl_lun_modify_params *params;
2484 struct ctl_be_block_lun *be_lun;
2485 struct ctl_be_lun *cbe_lun;
2486 const char *value;
2487 uint64_t oldsize;
2488 int error, wasprim;
2489
2490 params = &req->reqdata.modify;
2491
2492 sx_xlock(&softc->modify_lock);
2493 mtx_lock(&softc->lock);
2494 SLIST_FOREACH(be_lun, &softc->lun_list, links) {
2495 if (be_lun->cbe_lun.lun_id == params->lun_id)
2496 break;
2497 }
2498 mtx_unlock(&softc->lock);
2499 if (be_lun == NULL) {
2500 snprintf(req->error_str, sizeof(req->error_str),
2501 "LUN %u is not managed by the block backend",
2502 params->lun_id);
2503 goto bailout_error;
2504 }
2505 cbe_lun = &be_lun->cbe_lun;
2506
2507 if (params->lun_size_bytes != 0)
2508 be_lun->params.lun_size_bytes = params->lun_size_bytes;
2509
2510 if (req->args_nvl != NULL) {
2511 nvlist_destroy(cbe_lun->options);
2512 cbe_lun->options = nvlist_clone(req->args_nvl);
2513 }
2514
2515 wasprim = (cbe_lun->flags & CTL_LUN_FLAG_PRIMARY);
2516 value = dnvlist_get_string(cbe_lun->options, "ha_role", NULL);
2517 if (value != NULL) {
2518 if (strcmp(value, "primary") == 0)
2519 cbe_lun->flags |= CTL_LUN_FLAG_PRIMARY;
2520 else
2521 cbe_lun->flags &= ~CTL_LUN_FLAG_PRIMARY;
2522 } else if (control_softc->flags & CTL_FLAG_ACTIVE_SHELF)
2523 cbe_lun->flags |= CTL_LUN_FLAG_PRIMARY;
2524 else
2525 cbe_lun->flags &= ~CTL_LUN_FLAG_PRIMARY;
2526 if (wasprim != (cbe_lun->flags & CTL_LUN_FLAG_PRIMARY)) {
2527 if (cbe_lun->flags & CTL_LUN_FLAG_PRIMARY)
2528 ctl_lun_primary(cbe_lun);
2529 else
2530 ctl_lun_secondary(cbe_lun);
2531 }
2532
2533 oldsize = be_lun->size_blocks;
2534 if ((cbe_lun->flags & CTL_LUN_FLAG_PRIMARY) ||
2535 control_softc->ha_mode == CTL_HA_MODE_SER_ONLY) {
2536 if (be_lun->vn == NULL)
2537 error = ctl_be_block_open(be_lun, req);
2538 else if (vn_isdisk_error(be_lun->vn, &error))
2539 error = ctl_be_block_open_dev(be_lun, req);
2540 else if (be_lun->vn->v_type == VREG) {
2541 vn_lock(be_lun->vn, LK_SHARED | LK_RETRY);
2542 error = ctl_be_block_open_file(be_lun, req);
2543 VOP_UNLOCK(be_lun->vn);
2544 } else
2545 error = EINVAL;
2546 if ((cbe_lun->flags & CTL_LUN_FLAG_NO_MEDIA) &&
2547 be_lun->vn != NULL) {
2548 cbe_lun->flags &= ~CTL_LUN_FLAG_NO_MEDIA;
2549 ctl_lun_has_media(cbe_lun);
2550 } else if ((cbe_lun->flags & CTL_LUN_FLAG_NO_MEDIA) == 0 &&
2551 be_lun->vn == NULL) {
2552 cbe_lun->flags |= CTL_LUN_FLAG_NO_MEDIA;
2553 ctl_lun_no_media(cbe_lun);
2554 }
2555 cbe_lun->flags &= ~CTL_LUN_FLAG_EJECTED;
2556 } else {
2557 if (be_lun->vn != NULL) {
2558 cbe_lun->flags |= CTL_LUN_FLAG_NO_MEDIA;
2559 ctl_lun_no_media(cbe_lun);
2560 taskqueue_drain_all(be_lun->io_taskqueue);
2561 error = ctl_be_block_close(be_lun);
2562 } else
2563 error = 0;
2564 }
2565 if (be_lun->size_blocks != oldsize)
2566 ctl_lun_capacity_changed(cbe_lun);
2567
2568 /* Tell the user the exact size we ended up using */
2569 params->lun_size_bytes = be_lun->size_bytes;
2570
2571 sx_xunlock(&softc->modify_lock);
2572 req->status = error ? CTL_LUN_WARNING : CTL_LUN_OK;
2573 return (0);
2574
2575 bailout_error:
2576 sx_xunlock(&softc->modify_lock);
2577 req->status = CTL_LUN_ERROR;
2578 return (0);
2579 }
2580
2581 static void
ctl_be_block_lun_shutdown(struct ctl_be_lun * cbe_lun)2582 ctl_be_block_lun_shutdown(struct ctl_be_lun *cbe_lun)
2583 {
2584 struct ctl_be_block_lun *be_lun = (struct ctl_be_block_lun *)cbe_lun;
2585 struct ctl_be_block_softc *softc = be_lun->softc;
2586
2587 taskqueue_drain_all(be_lun->io_taskqueue);
2588 taskqueue_free(be_lun->io_taskqueue);
2589 if (be_lun->disk_stats != NULL)
2590 devstat_remove_entry(be_lun->disk_stats);
2591 nvlist_destroy(be_lun->cbe_lun.options);
2592 free(be_lun->dev_path, M_CTLBLK);
2593 mtx_destroy(&be_lun->queue_lock);
2594 mtx_destroy(&be_lun->io_lock);
2595
2596 mtx_lock(&softc->lock);
2597 be_lun->flags |= CTL_BE_BLOCK_LUN_UNCONFIGURED;
2598 if (be_lun->flags & CTL_BE_BLOCK_LUN_WAITING)
2599 wakeup(be_lun);
2600 else
2601 free(be_lun, M_CTLBLK);
2602 mtx_unlock(&softc->lock);
2603 }
2604
2605 static int
ctl_be_block_config_write(union ctl_io * io)2606 ctl_be_block_config_write(union ctl_io *io)
2607 {
2608 struct ctl_be_block_lun *be_lun;
2609 struct ctl_be_lun *cbe_lun;
2610 int retval;
2611
2612 DPRINTF("entered\n");
2613
2614 cbe_lun = CTL_BACKEND_LUN(io);
2615 be_lun = (struct ctl_be_block_lun *)cbe_lun;
2616
2617 retval = 0;
2618 switch (io->scsiio.cdb[0]) {
2619 case SYNCHRONIZE_CACHE:
2620 case SYNCHRONIZE_CACHE_16:
2621 case WRITE_SAME_10:
2622 case WRITE_SAME_16:
2623 case UNMAP:
2624 /*
2625 * The upper level CTL code will filter out any CDBs with
2626 * the immediate bit set and return the proper error.
2627 *
2628 * We don't really need to worry about what LBA range the
2629 * user asked to be synced out. When they issue a sync
2630 * cache command, we'll sync out the whole thing.
2631 */
2632 mtx_lock(&be_lun->queue_lock);
2633 STAILQ_INSERT_TAIL(&be_lun->config_write_queue, &io->io_hdr,
2634 links);
2635 mtx_unlock(&be_lun->queue_lock);
2636 taskqueue_enqueue(be_lun->io_taskqueue, &be_lun->io_task);
2637 break;
2638 case START_STOP_UNIT: {
2639 struct scsi_start_stop_unit *cdb;
2640 struct ctl_lun_req req;
2641
2642 cdb = (struct scsi_start_stop_unit *)io->scsiio.cdb;
2643 if ((cdb->how & SSS_PC_MASK) != 0) {
2644 ctl_set_success(&io->scsiio);
2645 ctl_config_write_done(io);
2646 break;
2647 }
2648 if (cdb->how & SSS_START) {
2649 if ((cdb->how & SSS_LOEJ) && be_lun->vn == NULL) {
2650 retval = ctl_be_block_open(be_lun, &req);
2651 cbe_lun->flags &= ~CTL_LUN_FLAG_EJECTED;
2652 if (retval == 0) {
2653 cbe_lun->flags &= ~CTL_LUN_FLAG_NO_MEDIA;
2654 ctl_lun_has_media(cbe_lun);
2655 } else {
2656 cbe_lun->flags |= CTL_LUN_FLAG_NO_MEDIA;
2657 ctl_lun_no_media(cbe_lun);
2658 }
2659 }
2660 ctl_start_lun(cbe_lun);
2661 } else {
2662 ctl_stop_lun(cbe_lun);
2663 if (cdb->how & SSS_LOEJ) {
2664 cbe_lun->flags |= CTL_LUN_FLAG_NO_MEDIA;
2665 cbe_lun->flags |= CTL_LUN_FLAG_EJECTED;
2666 ctl_lun_ejected(cbe_lun);
2667 if (be_lun->vn != NULL)
2668 ctl_be_block_close(be_lun);
2669 }
2670 }
2671
2672 ctl_set_success(&io->scsiio);
2673 ctl_config_write_done(io);
2674 break;
2675 }
2676 case PREVENT_ALLOW:
2677 ctl_set_success(&io->scsiio);
2678 ctl_config_write_done(io);
2679 break;
2680 default:
2681 ctl_set_invalid_opcode(&io->scsiio);
2682 ctl_config_write_done(io);
2683 retval = CTL_RETVAL_COMPLETE;
2684 break;
2685 }
2686
2687 return (retval);
2688 }
2689
2690 static int
ctl_be_block_config_read(union ctl_io * io)2691 ctl_be_block_config_read(union ctl_io *io)
2692 {
2693 struct ctl_be_block_lun *be_lun;
2694 int retval = 0;
2695
2696 DPRINTF("entered\n");
2697
2698 be_lun = (struct ctl_be_block_lun *)CTL_BACKEND_LUN(io);
2699
2700 switch (io->scsiio.cdb[0]) {
2701 case SERVICE_ACTION_IN:
2702 if (io->scsiio.cdb[1] == SGLS_SERVICE_ACTION) {
2703 mtx_lock(&be_lun->queue_lock);
2704 STAILQ_INSERT_TAIL(&be_lun->config_read_queue,
2705 &io->io_hdr, links);
2706 mtx_unlock(&be_lun->queue_lock);
2707 taskqueue_enqueue(be_lun->io_taskqueue,
2708 &be_lun->io_task);
2709 retval = CTL_RETVAL_QUEUED;
2710 break;
2711 }
2712 ctl_set_invalid_field(&io->scsiio,
2713 /*sks_valid*/ 1,
2714 /*command*/ 1,
2715 /*field*/ 1,
2716 /*bit_valid*/ 1,
2717 /*bit*/ 4);
2718 ctl_config_read_done(io);
2719 retval = CTL_RETVAL_COMPLETE;
2720 break;
2721 default:
2722 ctl_set_invalid_opcode(&io->scsiio);
2723 ctl_config_read_done(io);
2724 retval = CTL_RETVAL_COMPLETE;
2725 break;
2726 }
2727
2728 return (retval);
2729 }
2730
2731 static int
ctl_be_block_lun_info(struct ctl_be_lun * cbe_lun,struct sbuf * sb)2732 ctl_be_block_lun_info(struct ctl_be_lun *cbe_lun, struct sbuf *sb)
2733 {
2734 struct ctl_be_block_lun *lun = (struct ctl_be_block_lun *)cbe_lun;
2735 int retval;
2736
2737 retval = sbuf_printf(sb, "\t<num_threads>");
2738 if (retval != 0)
2739 goto bailout;
2740 retval = sbuf_printf(sb, "%d", lun->num_threads);
2741 if (retval != 0)
2742 goto bailout;
2743 retval = sbuf_printf(sb, "</num_threads>\n");
2744
2745 bailout:
2746 return (retval);
2747 }
2748
2749 static uint64_t
ctl_be_block_lun_attr(struct ctl_be_lun * cbe_lun,const char * attrname)2750 ctl_be_block_lun_attr(struct ctl_be_lun *cbe_lun, const char *attrname)
2751 {
2752 struct ctl_be_block_lun *lun = (struct ctl_be_block_lun *)cbe_lun;
2753
2754 if (lun->getattr == NULL)
2755 return (UINT64_MAX);
2756 return (lun->getattr(lun, attrname));
2757 }
2758
2759 static int
ctl_be_block_init(void)2760 ctl_be_block_init(void)
2761 {
2762 struct ctl_be_block_softc *softc = &backend_block_softc;
2763
2764 sx_init(&softc->modify_lock, "ctlblock modify");
2765 mtx_init(&softc->lock, "ctlblock", NULL, MTX_DEF);
2766 softc->beio_zone = uma_zcreate("beio", sizeof(struct ctl_be_block_io),
2767 NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
2768 softc->bufmin_zone = uma_zcreate("ctlblockmin", CTLBLK_MIN_SEG,
2769 NULL, NULL, NULL, NULL, /*align*/ 0, /*flags*/0);
2770 if (CTLBLK_MIN_SEG < CTLBLK_MAX_SEG)
2771 softc->bufmax_zone = uma_zcreate("ctlblockmax", CTLBLK_MAX_SEG,
2772 NULL, NULL, NULL, NULL, /*align*/ 0, /*flags*/0);
2773 SLIST_INIT(&softc->lun_list);
2774 return (0);
2775 }
2776
2777 static int
ctl_be_block_shutdown(void)2778 ctl_be_block_shutdown(void)
2779 {
2780 struct ctl_be_block_softc *softc = &backend_block_softc;
2781 struct ctl_be_block_lun *lun;
2782
2783 mtx_lock(&softc->lock);
2784 while ((lun = SLIST_FIRST(&softc->lun_list)) != NULL) {
2785 SLIST_REMOVE_HEAD(&softc->lun_list, links);
2786 softc->num_luns--;
2787 /*
2788 * Drop our lock here. Since ctl_remove_lun() can call
2789 * back into us, this could potentially lead to a recursive
2790 * lock of the same mutex, which would cause a hang.
2791 */
2792 mtx_unlock(&softc->lock);
2793 ctl_remove_lun(&lun->cbe_lun);
2794 mtx_lock(&softc->lock);
2795 }
2796 mtx_unlock(&softc->lock);
2797 uma_zdestroy(softc->bufmin_zone);
2798 if (CTLBLK_MIN_SEG < CTLBLK_MAX_SEG)
2799 uma_zdestroy(softc->bufmax_zone);
2800 uma_zdestroy(softc->beio_zone);
2801 mtx_destroy(&softc->lock);
2802 sx_destroy(&softc->modify_lock);
2803 return (0);
2804 }
2805