Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 5 Oct 2015 08:51:21 +0000 (UTC)
From:      Alexander Motin <mav@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   svn commit: r288727 - stable/10/sys/cam/ctl
Message-ID:  <201510050851.t958pLUl015183@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mav
Date: Mon Oct  5 08:51:20 2015
New Revision: 288727
URL: https://svnweb.freebsd.org/changeset/base/288727

Log:
  MFC r287499: Move setting of media parameters inside open routines.
  
  This is preparation for possibility to open/close media several times
  per LUN life cycle.  While there, rename variables to reduce confusion.
  As additional bonus this allows to open read-only media, such as ZFS
  snapshots.

Modified:
  stable/10/sys/cam/ctl/ctl.c
  stable/10/sys/cam/ctl/ctl_backend.h
  stable/10/sys/cam/ctl/ctl_backend_block.c
  stable/10/sys/cam/ctl/ctl_backend_ramdisk.c
  stable/10/sys/cam/ctl/ctl_private.h
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/cam/ctl/ctl.c
==============================================================================
--- stable/10/sys/cam/ctl/ctl.c	Mon Oct  5 08:50:15 2015	(r288726)
+++ stable/10/sys/cam/ctl/ctl.c	Mon Oct  5 08:51:20 2015	(r288727)
@@ -4003,7 +4003,7 @@ ctl_alloc_lun(struct ctl_softc *ctl_soft
 	struct ctl_lun *nlun, *lun;
 	struct scsi_vpd_id_descriptor *desc;
 	struct scsi_vpd_id_t10 *t10id;
-	const char *eui, *naa, *scsiname, *vendor, *value;
+	const char *eui, *naa, *scsiname, *vendor;
 	int lun_number, i, lun_malloced;
 	int devidlen, idlen1, idlen2 = 0, len;
 
@@ -4169,21 +4169,6 @@ ctl_alloc_lun(struct ctl_softc *ctl_soft
 	if (be_lun->flags & CTL_LUN_FLAG_PRIMARY)
 		lun->flags |= CTL_LUN_PRIMARY_SC;
 
-	value = ctl_get_opt(&be_lun->options, "readonly");
-	if (value != NULL && strcmp(value, "on") == 0)
-		lun->flags |= CTL_LUN_READONLY;
-
-	lun->serseq = CTL_LUN_SERSEQ_OFF;
-	if (be_lun->flags & CTL_LUN_FLAG_SERSEQ_READ)
-		lun->serseq = CTL_LUN_SERSEQ_READ;
-	value = ctl_get_opt(&be_lun->options, "serseq");
-	if (value != NULL && strcmp(value, "on") == 0)
-		lun->serseq = CTL_LUN_SERSEQ_ON;
-	else if (value != NULL && strcmp(value, "read") == 0)
-		lun->serseq = CTL_LUN_SERSEQ_READ;
-	else if (value != NULL && strcmp(value, "off") == 0)
-		lun->serseq = CTL_LUN_SERSEQ_OFF;
-
 	lun->ctl_softc = ctl_softc;
 #ifdef CTL_TIME_IO
 	lun->last_busy = getsbinuptime();
@@ -6276,7 +6261,7 @@ ctl_mode_sense(struct ctl_scsiio *ctsio)
 		header->datalen = MIN(total_len - 1, 254);
 		if (control_dev == 0) {
 			header->dev_specific = 0x10; /* DPOFUA */
-			if ((lun->flags & CTL_LUN_READONLY) ||
+			if ((lun->be_lun->flags & CTL_LUN_FLAG_READONLY) ||
 			    (lun->mode_pages.control_page[CTL_PAGE_CURRENT]
 			    .eca_and_aen & SCP_SWP) != 0)
 				    header->dev_specific |= 0x80; /* WP */
@@ -6299,7 +6284,7 @@ ctl_mode_sense(struct ctl_scsiio *ctsio)
 		scsi_ulto2b(datalen, header->datalen);
 		if (control_dev == 0) {
 			header->dev_specific = 0x10; /* DPOFUA */
-			if ((lun->flags & CTL_LUN_READONLY) ||
+			if ((lun->be_lun->flags & CTL_LUN_FLAG_READONLY) ||
 			    (lun->mode_pages.control_page[CTL_PAGE_CURRENT]
 			    .eca_and_aen & SCP_SWP) != 0)
 				    header->dev_specific |= 0x80; /* WP */
@@ -10532,15 +10517,16 @@ ctl_check_for_blockage(struct ctl_lun *l
 		return (CTL_ACTION_BLOCK);
 	case CTL_SER_EXTENT:
 		return (ctl_extent_check(ooa_io, pending_io,
-		    (lun->serseq == CTL_LUN_SERSEQ_ON)));
+		    (lun->be_lun && lun->be_lun->serseq == CTL_LUN_SERSEQ_ON)));
 	case CTL_SER_EXTENTOPT:
 		if ((lun->mode_pages.control_page[CTL_PAGE_CURRENT].queue_flags
 		    & SCP_QUEUE_ALG_MASK) != SCP_QUEUE_ALG_UNRESTRICTED)
 			return (ctl_extent_check(ooa_io, pending_io,
-			    (lun->serseq == CTL_LUN_SERSEQ_ON)));
+			    (lun->be_lun &&
+			     lun->be_lun->serseq == CTL_LUN_SERSEQ_ON)));
 		return (CTL_ACTION_PASS);
 	case CTL_SER_EXTENTSEQ:
-		if (lun->serseq != CTL_LUN_SERSEQ_OFF)
+		if (lun->be_lun && lun->be_lun->serseq != CTL_LUN_SERSEQ_OFF)
 			return (ctl_extent_check_seq(ooa_io, pending_io));
 		return (CTL_ACTION_PASS);
 	case CTL_SER_PASS:
@@ -10767,7 +10753,8 @@ ctl_scsiio_lun_check(struct ctl_lun *lun
 	}
 
 	if (entry->pattern & CTL_LUN_PAT_WRITE) {
-		if (lun->flags & CTL_LUN_READONLY) {
+		if (lun->be_lun &&
+		    lun->be_lun->flags & CTL_LUN_FLAG_READONLY) {
 			ctl_set_sense(ctsio, /*current_error*/ 1,
 			    /*sense_key*/ SSD_KEY_DATA_PROTECT,
 			    /*asc*/ 0x27, /*ascq*/ 0x01, SSD_ELEM_NONE);

Modified: stable/10/sys/cam/ctl/ctl_backend.h
==============================================================================
--- stable/10/sys/cam/ctl/ctl_backend.h	Mon Oct  5 08:50:15 2015	(r288726)
+++ stable/10/sys/cam/ctl/ctl_backend.h	Mon Oct  5 08:51:20 2015	(r288727)
@@ -86,9 +86,15 @@ typedef enum {
 	CTL_LUN_FLAG_DEV_TYPE		= 0x40,
 	CTL_LUN_FLAG_UNMAP		= 0x80,
 	CTL_LUN_FLAG_OFFLINE		= 0x100,
-	CTL_LUN_FLAG_SERSEQ_READ	= 0x200
+	CTL_LUN_FLAG_READONLY		= 0x200
 } ctl_backend_lun_flags;
 
+typedef enum {
+	CTL_LUN_SERSEQ_OFF,
+	CTL_LUN_SERSEQ_READ,
+	CTL_LUN_SERSEQ_ON
+} ctl_lun_serseq;
+
 #ifdef _KERNEL
 
 #define CTL_BACKEND_DECLARE(name, driver) \
@@ -195,6 +201,7 @@ typedef void (*be_lun_config_t)(void *be
 struct ctl_be_lun {
 	uint8_t			lun_type;	/* passed to CTL */
 	ctl_backend_lun_flags	flags;		/* passed to CTL */
+	ctl_lun_serseq		serseq;		/* passed to CTL */
 	void			*be_lun;	/* passed to CTL */
 	uint64_t		maxlba;		/* passed to CTL */
 	uint32_t		blocksize;	/* passed to CTL */

Modified: stable/10/sys/cam/ctl/ctl_backend_block.c
==============================================================================
--- stable/10/sys/cam/ctl/ctl_backend_block.c	Mon Oct  5 08:50:15 2015	(r288726)
+++ stable/10/sys/cam/ctl/ctl_backend_block.c	Mon Oct  5 08:51:20 2015	(r288727)
@@ -118,7 +118,6 @@ typedef enum {
 	CTL_BE_BLOCK_LUN_UNCONFIGURED	= 0x01,
 	CTL_BE_BLOCK_LUN_CONFIG_ERR	= 0x02,
 	CTL_BE_BLOCK_LUN_WAITING	= 0x04,
-	CTL_BE_BLOCK_LUN_MULTI_THREAD	= 0x08
 } ctl_be_block_lun_flags;
 
 typedef enum {
@@ -169,18 +168,11 @@ struct ctl_be_block_lun {
 	uma_zone_t lun_zone;
 	uint64_t size_blocks;
 	uint64_t size_bytes;
-	uint32_t blocksize;
-	uint16_t pblockexp;
-	uint16_t pblockoff;
-	uint16_t ublockexp;
-	uint16_t ublockoff;
-	uint32_t atomicblock;
-	uint32_t opttxferlen;
 	struct ctl_be_block_softc *softc;
 	struct devstat *disk_stats;
 	ctl_be_block_lun_flags flags;
 	STAILQ_ENTRY(ctl_be_block_lun) links;
-	struct ctl_be_lun ctl_be_lun;
+	struct ctl_be_lun cbe_lun;
 	struct taskqueue *io_taskqueue;
 	struct task io_task;
 	int num_threads;
@@ -771,7 +763,7 @@ ctl_be_block_gls_file(struct ctl_be_bloc
 
 	DPRINTF("entered\n");
 
-	off = roff = ((off_t)lbalen->lba) * be_lun->blocksize;
+	off = roff = ((off_t)lbalen->lba) * be_lun->cbe_lun.blocksize;
 	vn_lock(be_lun->vn, LK_SHARED | LK_RETRY);
 	error = VOP_IOCTL(be_lun->vn, FIOSEEKHOLE, &off,
 	    0, curthread->td_ucred, curthread);
@@ -791,8 +783,8 @@ ctl_be_block_gls_file(struct ctl_be_bloc
 
 	data = (struct scsi_get_lba_status_data *)io->scsiio.kern_data_ptr;
 	scsi_u64to8b(lbalen->lba, data->descr[0].addr);
-	scsi_ulto4b(MIN(UINT32_MAX, off / be_lun->blocksize - lbalen->lba),
-	    data->descr[0].length);
+	scsi_ulto4b(MIN(UINT32_MAX, off / be_lun->cbe_lun.blocksize -
+	    lbalen->lba), data->descr[0].length);
 	data->descr[0].status = status;
 
 	ctl_complete_beio(beio);
@@ -813,14 +805,14 @@ ctl_be_block_getattr_file(struct ctl_be_
 	if (strcmp(attrname, "blocksused") == 0) {
 		error = VOP_GETATTR(be_lun->vn, &vattr, curthread->td_ucred);
 		if (error == 0)
-			val = vattr.va_bytes / be_lun->blocksize;
+			val = vattr.va_bytes / be_lun->cbe_lun.blocksize;
 	}
 	if (strcmp(attrname, "blocksavail") == 0 &&
 	    (be_lun->vn->v_iflag & VI_DOOMED) == 0) {
 		error = VFS_STATFS(be_lun->vn->v_mount, &statfs);
 		if (error == 0)
 			val = statfs.f_bavail * statfs.f_bsize /
-			    be_lun->blocksize;
+			    be_lun->cbe_lun.blocksize;
 	}
 	VOP_UNLOCK(be_lun->vn, 0);
 	return (val);
@@ -931,7 +923,7 @@ ctl_be_block_gls_zvol(struct ctl_be_bloc
 
 	DPRINTF("entered\n");
 
-	off = roff = ((off_t)lbalen->lba) * be_lun->blocksize;
+	off = roff = ((off_t)lbalen->lba) * be_lun->cbe_lun.blocksize;
 	error = (*dev_data->csw->d_ioctl)(dev_data->cdev, FIOSEEKHOLE,
 	    (caddr_t)&off, FREAD, curthread);
 	if (error == 0 && off > roff)
@@ -949,8 +941,8 @@ ctl_be_block_gls_zvol(struct ctl_be_bloc
 
 	data = (struct scsi_get_lba_status_data *)io->scsiio.kern_data_ptr;
 	scsi_u64to8b(lbalen->lba, data->descr[0].addr);
-	scsi_ulto4b(MIN(UINT32_MAX, off / be_lun->blocksize - lbalen->lba),
-	    data->descr[0].length);
+	scsi_ulto4b(MIN(UINT32_MAX, off / be_lun->cbe_lun.blocksize -
+	    lbalen->lba), data->descr[0].length);
 	data->descr[0].status = status;
 
 	ctl_complete_beio(beio);
@@ -1006,7 +998,7 @@ ctl_be_block_unmap_dev_range(struct ctl_
 	uint64_t maxlen;
 
 	dev_data = &be_lun->backend.dev;
-	maxlen = LONG_MAX - (LONG_MAX % be_lun->blocksize);
+	maxlen = LONG_MAX - (LONG_MAX % be_lun->cbe_lun.blocksize);
 	while (len > 0) {
 		bio = g_alloc_bio();
 		bio->bio_cmd	    = BIO_DELETE;
@@ -1016,7 +1008,7 @@ ctl_be_block_unmap_dev_range(struct ctl_
 		bio->bio_data	    = 0;
 		bio->bio_done	    = ctl_be_block_biodone;
 		bio->bio_caller1    = beio;
-		bio->bio_pblkno     = off / be_lun->blocksize;
+		bio->bio_pblkno     = off / be_lun->cbe_lun.blocksize;
 
 		off += bio->bio_length;
 		len -= bio->bio_length;
@@ -1058,11 +1050,11 @@ ctl_be_block_unmap_dev(struct ctl_be_blo
 		end = buf + ptrlen->len / sizeof(*buf);
 		for (; buf < end; buf++) {
 			len = (uint64_t)scsi_4btoul(buf->length) *
-			    be_lun->blocksize;
+			    be_lun->cbe_lun.blocksize;
 			beio->io_len += len;
 			ctl_be_block_unmap_dev_range(be_lun, beio,
-			    scsi_8btou64(buf->lba) * be_lun->blocksize, len,
-			    (end - buf < 2) ? TRUE : FALSE);
+			    scsi_8btou64(buf->lba) * be_lun->cbe_lun.blocksize,
+			    len, (end - buf < 2) ? TRUE : FALSE);
 		}
 	} else
 		ctl_be_block_unmap_dev_range(be_lun, beio,
@@ -1114,7 +1106,7 @@ ctl_be_block_dispatch_dev(struct ctl_be_
 			bio->bio_offset = cur_offset;
 			bio->bio_data = cur_ptr;
 			bio->bio_done = ctl_be_block_biodone;
-			bio->bio_pblkno = cur_offset / be_lun->blocksize;
+			bio->bio_pblkno = cur_offset / be_lun->cbe_lun.blocksize;
 
 			cur_offset += bio->bio_length;
 			cur_ptr += bio->bio_length;
@@ -1161,6 +1153,7 @@ static void
 ctl_be_block_cw_dispatch_sync(struct ctl_be_block_lun *be_lun,
 			    union ctl_io *io)
 {
+	struct ctl_be_lun *cbe_lun = &be_lun->cbe_lun;
 	struct ctl_be_block_io *beio;
 	struct ctl_lba_len_flags *lbalen;
 
@@ -1168,8 +1161,8 @@ ctl_be_block_cw_dispatch_sync(struct ctl
 	beio = (struct ctl_be_block_io *)PRIV(io)->ptr;
 	lbalen = (struct ctl_lba_len_flags *)&io->io_hdr.ctl_private[CTL_PRIV_LBA_LEN];
 
-	beio->io_len = lbalen->len * be_lun->blocksize;
-	beio->io_offset = lbalen->lba * be_lun->blocksize;
+	beio->io_len = lbalen->len * cbe_lun->blocksize;
+	beio->io_offset = lbalen->lba * cbe_lun->blocksize;
 	beio->io_arg = (lbalen->flags & SSC_IMMED) != 0;
 	beio->bio_cmd = BIO_FLUSH;
 	beio->ds_trans_type = DEVSTAT_NO_DATA;
@@ -1198,6 +1191,7 @@ static void
 ctl_be_block_cw_dispatch_ws(struct ctl_be_block_lun *be_lun,
 			    union ctl_io *io)
 {
+	struct ctl_be_lun *cbe_lun = &be_lun->cbe_lun;
 	struct ctl_be_block_io *beio;
 	struct ctl_lba_len_flags *lbalen;
 	uint64_t len_left, lba;
@@ -1224,8 +1218,8 @@ ctl_be_block_cw_dispatch_ws(struct ctl_b
 	}
 
 	if (lbalen->flags & (SWS_UNMAP | SWS_ANCHOR)) {
-		beio->io_offset = lbalen->lba * be_lun->blocksize;
-		beio->io_len = (uint64_t)lbalen->len * be_lun->blocksize;
+		beio->io_offset = lbalen->lba * cbe_lun->blocksize;
+		beio->io_len = (uint64_t)lbalen->len * cbe_lun->blocksize;
 		beio->bio_cmd = BIO_DELETE;
 		beio->ds_trans_type = DEVSTAT_FREE;
 
@@ -1239,27 +1233,27 @@ ctl_be_block_cw_dispatch_ws(struct ctl_b
 	DPRINTF("WRITE SAME at LBA %jx len %u\n",
 	       (uintmax_t)lbalen->lba, lbalen->len);
 
-	pb = be_lun->blocksize << be_lun->pblockexp;
-	if (be_lun->pblockoff > 0)
-		pbo = pb - be_lun->blocksize * be_lun->pblockoff;
+	pb = cbe_lun->blocksize << be_lun->cbe_lun.pblockexp;
+	if (be_lun->cbe_lun.pblockoff > 0)
+		pbo = pb - cbe_lun->blocksize * be_lun->cbe_lun.pblockoff;
 	else
 		pbo = 0;
-	len_left = (uint64_t)lbalen->len * be_lun->blocksize;
+	len_left = (uint64_t)lbalen->len * cbe_lun->blocksize;
 	for (i = 0, lba = 0; i < CTLBLK_MAX_SEGS && len_left > 0; i++) {
 
 		/*
 		 * Setup the S/G entry for this chunk.
 		 */
 		seglen = MIN(CTLBLK_MAX_SEG, len_left);
-		if (pb > be_lun->blocksize) {
-			adj = ((lbalen->lba + lba) * be_lun->blocksize +
+		if (pb > cbe_lun->blocksize) {
+			adj = ((lbalen->lba + lba) * cbe_lun->blocksize +
 			    seglen - pbo) % pb;
 			if (seglen > adj)
 				seglen -= adj;
 			else
-				seglen -= seglen % be_lun->blocksize;
+				seglen -= seglen % cbe_lun->blocksize;
 		} else
-			seglen -= seglen % be_lun->blocksize;
+			seglen -= seglen % cbe_lun->blocksize;
 		beio->sg_segs[i].len = seglen;
 		beio->sg_segs[i].addr = uma_zalloc(be_lun->lun_zone, M_WAITOK);
 
@@ -1271,16 +1265,16 @@ ctl_be_block_cw_dispatch_ws(struct ctl_b
 
 		buf = beio->sg_segs[i].addr;
 		end = buf + seglen;
-		for (; buf < end; buf += be_lun->blocksize) {
-			memcpy(buf, io->scsiio.kern_data_ptr, be_lun->blocksize);
+		for (; buf < end; buf += cbe_lun->blocksize) {
+			memcpy(buf, io->scsiio.kern_data_ptr, cbe_lun->blocksize);
 			if (lbalen->flags & SWS_LBDATA)
 				scsi_ulto4b(lbalen->lba + lba, buf);
 			lba++;
 		}
 	}
 
-	beio->io_offset = lbalen->lba * be_lun->blocksize;
-	beio->io_len = lba * be_lun->blocksize;
+	beio->io_offset = lbalen->lba * cbe_lun->blocksize;
+	beio->io_len = lba * cbe_lun->blocksize;
 
 	/* We can not do all in one run. Correct and schedule rerun. */
 	if (len_left > 0) {
@@ -1465,6 +1459,7 @@ static void
 ctl_be_block_dispatch(struct ctl_be_block_lun *be_lun,
 			   union ctl_io *io)
 {
+	struct ctl_be_lun *cbe_lun = &be_lun->cbe_lun;
 	struct ctl_be_block_io *beio;
 	struct ctl_be_block_softc *softc;
 	struct ctl_lba_len_flags *lbalen;
@@ -1519,9 +1514,9 @@ ctl_be_block_dispatch(struct ctl_be_bloc
 		lbas = CTLBLK_HALF_IO_SIZE;
 	else
 		lbas = CTLBLK_MAX_IO_SIZE;
-	lbas = MIN(lbalen->len - bptrlen->len, lbas / be_lun->blocksize);
-	beio->io_offset = (lbalen->lba + bptrlen->len) * be_lun->blocksize;
-	beio->io_len = lbas * be_lun->blocksize;
+	lbas = MIN(lbalen->len - bptrlen->len, lbas / cbe_lun->blocksize);
+	beio->io_offset = (lbalen->lba + bptrlen->len) * cbe_lun->blocksize;
+	beio->io_len = lbas * cbe_lun->blocksize;
 	bptrlen->len += lbas;
 
 	for (i = 0, len_left = beio->io_len; len_left > 0; i++) {
@@ -1666,13 +1661,13 @@ static int
 ctl_be_block_submit(union ctl_io *io)
 {
 	struct ctl_be_block_lun *be_lun;
-	struct ctl_be_lun *ctl_be_lun;
+	struct ctl_be_lun *cbe_lun;
 
 	DPRINTF("entered\n");
 
-	ctl_be_lun = (struct ctl_be_lun *)io->io_hdr.ctl_private[
+	cbe_lun = (struct ctl_be_lun *)io->io_hdr.ctl_private[
 		CTL_PRIV_BACKEND_LUN].ptr;
-	be_lun = (struct ctl_be_block_lun *)ctl_be_lun->be_lun;
+	be_lun = (struct ctl_be_block_lun *)cbe_lun->be_lun;
 
 	/*
 	 * Make sure we only get SCSI I/O.
@@ -1742,6 +1737,7 @@ ctl_be_block_ioctl(struct cdev *dev, u_l
 static int
 ctl_be_block_open_file(struct ctl_be_block_lun *be_lun, struct ctl_lun_req *req)
 {
+	struct ctl_be_lun *cbe_lun;
 	struct ctl_be_block_filedata *file_data;
 	struct ctl_lun_create_params *params;
 	char			     *value;
@@ -1750,6 +1746,7 @@ ctl_be_block_open_file(struct ctl_be_blo
 	int			      error;
 
 	error = 0;
+	cbe_lun = &be_lun->cbe_lun;
 	file_data = &be_lun->backend.file;
 	params = &be_lun->params;
 
@@ -1758,6 +1755,8 @@ ctl_be_block_open_file(struct ctl_be_blo
 	be_lun->lun_flush = ctl_be_block_flush_file;
 	be_lun->get_lba_status = ctl_be_block_gls_file;
 	be_lun->getattr = ctl_be_block_getattr_file;
+	be_lun->unmap = NULL;
+	cbe_lun->flags &= ~CTL_LUN_FLAG_UNMAP;
 
 	error = VOP_GETATTR(be_lun->vn, &vattr, curthread->td_ucred);
 	if (error != 0) {
@@ -1782,19 +1781,11 @@ ctl_be_block_open_file(struct ctl_be_blo
 		}
 	}
 
-
 	file_data->cred = crhold(curthread->td_ucred);
 	if (params->lun_size_bytes != 0)
 		be_lun->size_bytes = params->lun_size_bytes;
 	else
 		be_lun->size_bytes = vattr.va_size;
-	/*
-	 * We set the multi thread flag for file operations because all
-	 * filesystems (in theory) are capable of allowing multiple readers
-	 * of a file at once.  So we want to get the maximum possible
-	 * concurrency.
-	 */
-	be_lun->flags |= CTL_BE_BLOCK_LUN_MULTI_THREAD;
 
 	/*
 	 * For files we can use any logical block size.  Prefer 512 bytes
@@ -1803,59 +1794,63 @@ ctl_be_block_open_file(struct ctl_be_blo
 	 * logical block size -- report it as physical block size.
 	 */
 	if (params->blocksize_bytes != 0)
-		be_lun->blocksize = params->blocksize_bytes;
+		cbe_lun->blocksize = params->blocksize_bytes;
 	else
-		be_lun->blocksize = 512;
+		cbe_lun->blocksize = 512;
+	be_lun->size_blocks = be_lun->size_bytes / cbe_lun->blocksize;
+	cbe_lun->maxlba = (be_lun->size_blocks == 0) ?
+	    0 : (be_lun->size_blocks - 1);
 
 	us = ps = vattr.va_blocksize;
 	uo = po = 0;
 
-	value = ctl_get_opt(&be_lun->ctl_be_lun.options, "pblocksize");
+	value = ctl_get_opt(&cbe_lun->options, "pblocksize");
 	if (value != NULL)
 		ctl_expand_number(value, &ps);
-	value = ctl_get_opt(&be_lun->ctl_be_lun.options, "pblockoffset");
+	value = ctl_get_opt(&cbe_lun->options, "pblockoffset");
 	if (value != NULL)
 		ctl_expand_number(value, &po);
-	pss = ps / be_lun->blocksize;
-	pos = po / be_lun->blocksize;
-	if ((pss > 0) && (pss * be_lun->blocksize == ps) && (pss >= pos) &&
-	    ((pss & (pss - 1)) == 0) && (pos * be_lun->blocksize == po)) {
-		be_lun->pblockexp = fls(pss) - 1;
-		be_lun->pblockoff = (pss - pos) % pss;
+	pss = ps / cbe_lun->blocksize;
+	pos = po / cbe_lun->blocksize;
+	if ((pss > 0) && (pss * cbe_lun->blocksize == ps) && (pss >= pos) &&
+	    ((pss & (pss - 1)) == 0) && (pos * cbe_lun->blocksize == po)) {
+		cbe_lun->pblockexp = fls(pss) - 1;
+		cbe_lun->pblockoff = (pss - pos) % pss;
 	}
 
-	value = ctl_get_opt(&be_lun->ctl_be_lun.options, "ublocksize");
+	value = ctl_get_opt(&cbe_lun->options, "ublocksize");
 	if (value != NULL)
 		ctl_expand_number(value, &us);
-	value = ctl_get_opt(&be_lun->ctl_be_lun.options, "ublockoffset");
+	value = ctl_get_opt(&cbe_lun->options, "ublockoffset");
 	if (value != NULL)
 		ctl_expand_number(value, &uo);
-	uss = us / be_lun->blocksize;
-	uos = uo / be_lun->blocksize;
-	if ((uss > 0) && (uss * be_lun->blocksize == us) && (uss >= uos) &&
-	    ((uss & (uss - 1)) == 0) && (uos * be_lun->blocksize == uo)) {
-		be_lun->ublockexp = fls(uss) - 1;
-		be_lun->ublockoff = (uss - uos) % uss;
+	uss = us / cbe_lun->blocksize;
+	uos = uo / cbe_lun->blocksize;
+	if ((uss > 0) && (uss * cbe_lun->blocksize == us) && (uss >= uos) &&
+	    ((uss & (uss - 1)) == 0) && (uos * cbe_lun->blocksize == uo)) {
+		cbe_lun->ublockexp = fls(uss) - 1;
+		cbe_lun->ublockoff = (uss - uos) % uss;
 	}
 
 	/*
 	 * Sanity check.  The media size has to be at least one
 	 * sector long.
 	 */
-	if (be_lun->size_bytes < be_lun->blocksize) {
+	if (be_lun->size_bytes < cbe_lun->blocksize) {
 		error = EINVAL;
 		snprintf(req->error_str, sizeof(req->error_str),
 			 "file %s size %ju < block size %u", be_lun->dev_path,
-			 (uintmax_t)be_lun->size_bytes, be_lun->blocksize);
+			 (uintmax_t)be_lun->size_bytes, cbe_lun->blocksize);
 	}
 
-	be_lun->opttxferlen = CTLBLK_MAX_IO_SIZE / be_lun->blocksize;
+	cbe_lun->opttxferlen = CTLBLK_MAX_IO_SIZE / cbe_lun->blocksize;
 	return (error);
 }
 
 static int
 ctl_be_block_open_dev(struct ctl_be_block_lun *be_lun, struct ctl_lun_req *req)
 {
+	struct ctl_be_lun *cbe_lun = &be_lun->cbe_lun;
 	struct ctl_lun_create_params *params;
 	struct vattr		      vattr;
 	struct cdev		     *dev;
@@ -1878,6 +1873,7 @@ ctl_be_block_open_dev(struct ctl_be_bloc
 		atomic = maxio = CTLBLK_MAX_IO_SIZE;
 	} else {
 		be_lun->dispatch = ctl_be_block_dispatch_dev;
+		be_lun->get_lba_status = NULL;
 		atomic = 0;
 		maxio = be_lun->backend.dev.cdev->si_iosize_max;
 		if (maxio <= 0)
@@ -1887,6 +1883,7 @@ ctl_be_block_open_dev(struct ctl_be_bloc
 	}
 	be_lun->lun_flush = ctl_be_block_flush_dev;
 	be_lun->getattr = ctl_be_block_getattr_dev;
+	be_lun->unmap = ctl_be_block_unmap_dev;
 
 	error = VOP_GETATTR(be_lun->vn, &vattr, NOCRED);
 	if (error) {
@@ -1923,7 +1920,7 @@ ctl_be_block_open_dev(struct ctl_be_bloc
 	if ((params->blocksize_bytes != 0) &&
 	    (params->blocksize_bytes >= tmp)) {
 		if (params->blocksize_bytes % tmp == 0) {
-			be_lun->blocksize = params->blocksize_bytes;
+			cbe_lun->blocksize = params->blocksize_bytes;
 		} else {
 			snprintf(req->error_str, sizeof(req->error_str),
 				 "requested blocksize %u is not an even "
@@ -1938,7 +1935,7 @@ ctl_be_block_open_dev(struct ctl_be_bloc
 			 "blocksize %u", params->blocksize_bytes, tmp);
 		return (EINVAL);
 	} else
-		be_lun->blocksize = tmp;
+		cbe_lun->blocksize = tmp;
 
 	error = devsw->d_ioctl(dev, DIOCGMEDIASIZE, (caddr_t)&otmp, FREAD,
 			       curthread);
@@ -1963,6 +1960,9 @@ ctl_be_block_open_dev(struct ctl_be_bloc
 		be_lun->size_bytes = params->lun_size_bytes;
 	} else
 		be_lun->size_bytes = otmp;
+	be_lun->size_blocks = be_lun->size_bytes / cbe_lun->blocksize;
+	cbe_lun->maxlba = (be_lun->size_blocks == 0) ?
+	    0 : (be_lun->size_blocks - 1);
 
 	error = devsw->d_ioctl(dev, DIOCGSTRIPESIZE,
 			       (caddr_t)&ps, FREAD, curthread);
@@ -1977,36 +1977,36 @@ ctl_be_block_open_dev(struct ctl_be_bloc
 	us = ps;
 	uo = po;
 
-	value = ctl_get_opt(&be_lun->ctl_be_lun.options, "pblocksize");
+	value = ctl_get_opt(&cbe_lun->options, "pblocksize");
 	if (value != NULL)
 		ctl_expand_number(value, &ps);
-	value = ctl_get_opt(&be_lun->ctl_be_lun.options, "pblockoffset");
+	value = ctl_get_opt(&cbe_lun->options, "pblockoffset");
 	if (value != NULL)
 		ctl_expand_number(value, &po);
-	pss = ps / be_lun->blocksize;
-	pos = po / be_lun->blocksize;
-	if ((pss > 0) && (pss * be_lun->blocksize == ps) && (pss >= pos) &&
-	    ((pss & (pss - 1)) == 0) && (pos * be_lun->blocksize == po)) {
-		be_lun->pblockexp = fls(pss) - 1;
-		be_lun->pblockoff = (pss - pos) % pss;
+	pss = ps / cbe_lun->blocksize;
+	pos = po / cbe_lun->blocksize;
+	if ((pss > 0) && (pss * cbe_lun->blocksize == ps) && (pss >= pos) &&
+	    ((pss & (pss - 1)) == 0) && (pos * cbe_lun->blocksize == po)) {
+		cbe_lun->pblockexp = fls(pss) - 1;
+		cbe_lun->pblockoff = (pss - pos) % pss;
 	}
 
-	value = ctl_get_opt(&be_lun->ctl_be_lun.options, "ublocksize");
+	value = ctl_get_opt(&cbe_lun->options, "ublocksize");
 	if (value != NULL)
 		ctl_expand_number(value, &us);
-	value = ctl_get_opt(&be_lun->ctl_be_lun.options, "ublockoffset");
+	value = ctl_get_opt(&cbe_lun->options, "ublockoffset");
 	if (value != NULL)
 		ctl_expand_number(value, &uo);
-	uss = us / be_lun->blocksize;
-	uos = uo / be_lun->blocksize;
-	if ((uss > 0) && (uss * be_lun->blocksize == us) && (uss >= uos) &&
-	    ((uss & (uss - 1)) == 0) && (uos * be_lun->blocksize == uo)) {
-		be_lun->ublockexp = fls(uss) - 1;
-		be_lun->ublockoff = (uss - uos) % uss;
+	uss = us / cbe_lun->blocksize;
+	uos = uo / cbe_lun->blocksize;
+	if ((uss > 0) && (uss * cbe_lun->blocksize == us) && (uss >= uos) &&
+	    ((uss & (uss - 1)) == 0) && (uos * cbe_lun->blocksize == uo)) {
+		cbe_lun->ublockexp = fls(uss) - 1;
+		cbe_lun->ublockoff = (uss - uos) % uss;
 	}
 
-	be_lun->atomicblock = atomic / be_lun->blocksize;
-	be_lun->opttxferlen = maxio / be_lun->blocksize;
+	cbe_lun->atomicblock = atomic / cbe_lun->blocksize;
+	cbe_lun->opttxferlen = maxio / cbe_lun->blocksize;
 
 	if (be_lun->dispatch == ctl_be_block_dispatch_zvol) {
 		unmap = 1;
@@ -2019,11 +2019,13 @@ ctl_be_block_open_dev(struct ctl_be_bloc
 		    (caddr_t)&arg, FREAD, curthread);
 		unmap = (error == 0) ? arg.value.i : 0;
 	}
-	value = ctl_get_opt(&be_lun->ctl_be_lun.options, "unmap");
+	value = ctl_get_opt(&cbe_lun->options, "unmap");
 	if (value != NULL)
 		unmap = (strcmp(value, "on") == 0);
 	if (unmap)
-		be_lun->unmap = ctl_be_block_unmap_dev;
+		cbe_lun->flags |= CTL_LUN_FLAG_UNMAP;
+	else
+		cbe_lun->flags &= ~CTL_LUN_FLAG_UNMAP;
 
 	return (0);
 }
@@ -2031,10 +2033,10 @@ ctl_be_block_open_dev(struct ctl_be_bloc
 static int
 ctl_be_block_close(struct ctl_be_block_lun *be_lun)
 {
-	DROP_GIANT();
-	if (be_lun->vn) {
-		int flags = FREAD | FWRITE;
+	struct ctl_be_lun *cbe_lun = &be_lun->cbe_lun;
+	int flags;
 
+	if (be_lun->vn) {
 		switch (be_lun->dev_type) {
 		case CTL_BE_BLOCK_DEV:
 			if (be_lun->backend.dev.csw) {
@@ -2053,6 +2055,9 @@ ctl_be_block_close(struct ctl_be_block_l
 			break;
 		}
 
+		flags = FREAD;
+		if ((cbe_lun->flags & CTL_LUN_FLAG_READONLY) == 0)
+			flags |= FWRITE;
 		(void)vn_close(be_lun->vn, flags, NOCRED, curthread);
 		be_lun->vn = NULL;
 
@@ -2073,31 +2078,24 @@ ctl_be_block_close(struct ctl_be_block_l
 		}
 		be_lun->dev_type = CTL_BE_BLOCK_NONE;
 	}
-	PICKUP_GIANT();
-
 	return (0);
 }
 
 static int
 ctl_be_block_open(struct ctl_be_block_softc *softc,
-		       struct ctl_be_block_lun *be_lun, struct ctl_lun_req *req)
+		  struct ctl_be_block_lun *be_lun, struct ctl_lun_req *req)
 {
+	struct ctl_be_lun *cbe_lun = &be_lun->cbe_lun;
 	struct nameidata nd;
-	int		 flags;
-	int		 error;
+	char		*value;
+	int		 error, flags;
 
-	/*
-	 * XXX KDM allow a read-only option?
-	 */
-	flags = FREAD | FWRITE;
 	error = 0;
-
 	if (rootvnode == NULL) {
 		snprintf(req->error_str, sizeof(req->error_str),
 			 "Root filesystem is not mounted");
 		return (1);
 	}
-
 	if (!curthread->td_proc->p_fd->fd_cdir) {
 		curthread->td_proc->p_fd->fd_cdir = rootvnode;
 		VREF(rootvnode);
@@ -2111,9 +2109,27 @@ ctl_be_block_open(struct ctl_be_block_so
 		VREF(rootvnode);
 	}
 
- again:
+	value = ctl_get_opt(&cbe_lun->options, "file");
+	if (value == NULL) {
+		snprintf(req->error_str, sizeof(req->error_str),
+			 "no file argument specified");
+		return (1);
+	}
+	free(be_lun->dev_path, M_CTLBLK);
+	be_lun->dev_path = strdup(value, M_CTLBLK);
+
+	flags = FREAD;
+	value = ctl_get_opt(&cbe_lun->options, "readonly");
+	if (value == NULL || strcmp(value, "on") != 0)
+		flags |= FWRITE;
+
+again:
 	NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, be_lun->dev_path, curthread);
 	error = vn_open(&nd, &flags, 0, NULL);
+	if ((error == EROFS || error == EACCES) && (flags & FWRITE)) {
+		flags &= ~FWRITE;
+		goto again;
+	}
 	if (error) {
 		/*
 		 * This is the only reasonable guess we can make as far as
@@ -2122,28 +2138,24 @@ ctl_be_block_open(struct ctl_be_block_so
 		 * full path.
 		 */
 		if (be_lun->dev_path[0] != '/') {
-			char *dev_path = "/dev/";
 			char *dev_name;
 
-			/* Try adding device path at beginning of name */
-			dev_name = malloc(strlen(be_lun->dev_path)
-					+ strlen(dev_path) + 1,
-					  M_CTLBLK, M_WAITOK);
-			if (dev_name) {
-				sprintf(dev_name, "%s%s", dev_path,
-					be_lun->dev_path);
-				free(be_lun->dev_path, M_CTLBLK);
-				be_lun->dev_path = dev_name;
-				goto again;
-			}
+			asprintf(&dev_name, M_CTLBLK, "/dev/%s",
+				be_lun->dev_path);
+			free(be_lun->dev_path, M_CTLBLK);
+			be_lun->dev_path = dev_name;
+			goto again;
 		}
 		snprintf(req->error_str, sizeof(req->error_str),
 		    "error opening %s: %d", be_lun->dev_path, error);
 		return (error);
 	}
+	if (flags & FWRITE)
+		cbe_lun->flags &= ~CTL_LUN_FLAG_READONLY;
+	else
+		cbe_lun->flags |= CTL_LUN_FLAG_READONLY;
 
 	NDFREE(&nd, NDF_ONLY_PNBUF);
-		
 	be_lun->vn = nd.ni_vp;
 
 	/* We only support disks and files. */
@@ -2160,12 +2172,23 @@ ctl_be_block_open(struct ctl_be_block_so
 
 	if (error != 0)
 		ctl_be_block_close(be_lun);
+	cbe_lun->serseq = CTL_LUN_SERSEQ_OFF;
+	if (be_lun->dispatch != ctl_be_block_dispatch_dev)
+		cbe_lun->serseq = CTL_LUN_SERSEQ_READ;
+	value = ctl_get_opt(&cbe_lun->options, "serseq");
+	if (value != NULL && strcmp(value, "on") == 0)
+		cbe_lun->serseq = CTL_LUN_SERSEQ_ON;
+	else if (value != NULL && strcmp(value, "read") == 0)
+		cbe_lun->serseq = CTL_LUN_SERSEQ_READ;
+	else if (value != NULL && strcmp(value, "off") == 0)
+		cbe_lun->serseq = CTL_LUN_SERSEQ_OFF;
 	return (0);
 }
 
 static int
 ctl_be_block_create(struct ctl_be_block_softc *softc, struct ctl_lun_req *req)
 {
+	struct ctl_be_lun *cbe_lun;
 	struct ctl_be_block_lun *be_lun;
 	struct ctl_lun_create_params *params;
 	char num_thread_str[16];
@@ -2178,10 +2201,9 @@ ctl_be_block_create(struct ctl_be_block_
 	retval = 0;
 	req->status = CTL_LUN_OK;
 
-	num_threads = cbb_num_threads;
-
 	be_lun = malloc(sizeof(*be_lun), M_CTLBLK, M_ZERO | M_WAITOK);
-
+	cbe_lun = &be_lun->cbe_lun;
+	cbe_lun->be_lun = be_lun;
 	be_lun->params = req->reqdata.create;
 	be_lun->softc = softc;
 	STAILQ_INIT(&be_lun->input_queue);
@@ -2191,12 +2213,10 @@ ctl_be_block_create(struct ctl_be_block_
 	sprintf(be_lun->lunname, "cblk%d", softc->num_luns);
 	mtx_init(&be_lun->io_lock, "cblk io lock", NULL, MTX_DEF);
 	mtx_init(&be_lun->queue_lock, "cblk queue lock", NULL, MTX_DEF);
-	ctl_init_opts(&be_lun->ctl_be_lun.options,
+	ctl_init_opts(&cbe_lun->options,
 	    req->num_be_args, req->kern_be_args);
-
 	be_lun->lun_zone = uma_zcreate(be_lun->lunname, CTLBLK_MAX_SEG,
 	    NULL, NULL, NULL, NULL, /*align*/ 0, /*flags*/0);
-
 	if (be_lun->lun_zone == NULL) {
 		snprintf(req->error_str, sizeof(req->error_str),
 			 "error allocating UMA zone");
@@ -2204,46 +2224,29 @@ ctl_be_block_create(struct ctl_be_block_
 	}
 
 	if (params->flags & CTL_LUN_FLAG_DEV_TYPE)
-		be_lun->ctl_be_lun.lun_type = params->device_type;
+		cbe_lun->lun_type = params->device_type;
 	else
-		be_lun->ctl_be_lun.lun_type = T_DIRECT;
+		cbe_lun->lun_type = T_DIRECT;
+	be_lun->flags = CTL_BE_BLOCK_LUN_UNCONFIGURED;
+	cbe_lun->flags = CTL_LUN_FLAG_PRIMARY;
 
-	if (be_lun->ctl_be_lun.lun_type == T_DIRECT) {
-		value = ctl_get_opt(&be_lun->ctl_be_lun.options, "file");
-		if (value == NULL) {
-			snprintf(req->error_str, sizeof(req->error_str),
-				 "no file argument specified");
-			goto bailout_error;
-		}
-		be_lun->dev_path = strdup(value, M_CTLBLK);
+	if (cbe_lun->lun_type == T_DIRECT) {
 		be_lun->size_bytes = params->lun_size_bytes;
 		if (params->blocksize_bytes != 0)
-			be_lun->blocksize = params->blocksize_bytes;
+			cbe_lun->blocksize = params->blocksize_bytes;
 		else
-			be_lun->blocksize = 512;
+			cbe_lun->blocksize = 512;
+		be_lun->size_blocks = be_lun->size_bytes / cbe_lun->blocksize;
+		cbe_lun->maxlba = (be_lun->size_blocks == 0) ?
+		    0 : (be_lun->size_blocks - 1);
 
 		retval = ctl_be_block_open(softc, be_lun, req);
-		be_lun->size_blocks = be_lun->size_bytes / be_lun->blocksize;
 		if (retval != 0) {
 			retval = 0;
 			req->status = CTL_LUN_WARNING;
 		}
+		num_threads = cbb_num_threads;
 	} else {
-		/*
-		 * For processor devices, we don't have any size.
-		 */
-		be_lun->blocksize = 0;
-		be_lun->pblockexp = 0;
-		be_lun->pblockoff = 0;
-		be_lun->ublockexp = 0;
-		be_lun->ublockoff = 0;
-		be_lun->size_blocks = 0;
-		be_lun->size_bytes = 0;
-		be_lun->ctl_be_lun.maxlba = 0;
-
-		/*
-		 * Default to just 1 thread for processor devices.
-		 */
 		num_threads = 1;
 	}
 
@@ -2251,7 +2254,7 @@ ctl_be_block_create(struct ctl_be_block_
 	 * XXX This searching loop might be refactored to be combined with
 	 * the loop above,
 	 */
-	value = ctl_get_opt(&be_lun->ctl_be_lun.options, "num_threads");
+	value = ctl_get_opt(&cbe_lun->options, "num_threads");
 	if (value != NULL) {
 		tmp_num_threads = strtol(value, NULL, 0);
 
@@ -2269,67 +2272,46 @@ ctl_be_block_create(struct ctl_be_block_
 		num_threads = tmp_num_threads;
 	}
 
-	be_lun->flags = CTL_BE_BLOCK_LUN_UNCONFIGURED;
-	be_lun->ctl_be_lun.flags = CTL_LUN_FLAG_PRIMARY;
 	if (be_lun->vn == NULL)
-		be_lun->ctl_be_lun.flags |= CTL_LUN_FLAG_OFFLINE;
-	if (be_lun->unmap != NULL)
-		be_lun->ctl_be_lun.flags |= CTL_LUN_FLAG_UNMAP;
-	if (be_lun->dispatch != ctl_be_block_dispatch_dev)
-		be_lun->ctl_be_lun.flags |= CTL_LUN_FLAG_SERSEQ_READ;
-	be_lun->ctl_be_lun.be_lun = be_lun;
-	be_lun->ctl_be_lun.maxlba = (be_lun->size_blocks == 0) ?
-	    0 : (be_lun->size_blocks - 1);
-	be_lun->ctl_be_lun.blocksize = be_lun->blocksize;
-	be_lun->ctl_be_lun.pblockexp = be_lun->pblockexp;
-	be_lun->ctl_be_lun.pblockoff = be_lun->pblockoff;
-	be_lun->ctl_be_lun.ublockexp = be_lun->ublockexp;
-	be_lun->ctl_be_lun.ublockoff = be_lun->ublockoff;
-	be_lun->ctl_be_lun.atomicblock = be_lun->atomicblock;
-	be_lun->ctl_be_lun.opttxferlen = be_lun->opttxferlen;
+		cbe_lun->flags |= CTL_LUN_FLAG_OFFLINE;
 	/* Tell the user the blocksize we ended up using */
 	params->lun_size_bytes = be_lun->size_bytes;
-	params->blocksize_bytes = be_lun->blocksize;
+	params->blocksize_bytes = cbe_lun->blocksize;
 	if (params->flags & CTL_LUN_FLAG_ID_REQ) {
-		be_lun->ctl_be_lun.req_lun_id = params->req_lun_id;
-		be_lun->ctl_be_lun.flags |= CTL_LUN_FLAG_ID_REQ;
+		cbe_lun->req_lun_id = params->req_lun_id;
+		cbe_lun->flags |= CTL_LUN_FLAG_ID_REQ;
 	} else
-		be_lun->ctl_be_lun.req_lun_id = 0;
+		cbe_lun->req_lun_id = 0;
 
-	be_lun->ctl_be_lun.lun_shutdown = ctl_be_block_lun_shutdown;
-	be_lun->ctl_be_lun.lun_config_status =
-		ctl_be_block_lun_config_status;
-	be_lun->ctl_be_lun.be = &ctl_be_block_driver;
+	cbe_lun->lun_shutdown = ctl_be_block_lun_shutdown;
+	cbe_lun->lun_config_status = ctl_be_block_lun_config_status;
+	cbe_lun->be = &ctl_be_block_driver;
 
 	if ((params->flags & CTL_LUN_FLAG_SERIAL_NUM) == 0) {
 		snprintf(tmpstr, sizeof(tmpstr), "MYSERIAL%4d",
 			 softc->num_luns);
-		strncpy((char *)be_lun->ctl_be_lun.serial_num, tmpstr,
-			MIN(sizeof(be_lun->ctl_be_lun.serial_num),
-			sizeof(tmpstr)));
+		strncpy((char *)cbe_lun->serial_num, tmpstr,
+			MIN(sizeof(cbe_lun->serial_num), sizeof(tmpstr)));
 
 		/* Tell the user what we used for a serial number */
 		strncpy((char *)params->serial_num, tmpstr,
 			MIN(sizeof(params->serial_num), sizeof(tmpstr)));
 	} else { 
-		strncpy((char *)be_lun->ctl_be_lun.serial_num,
-			params->serial_num,
-			MIN(sizeof(be_lun->ctl_be_lun.serial_num),
+		strncpy((char *)cbe_lun->serial_num, params->serial_num,
+			MIN(sizeof(cbe_lun->serial_num),
 			sizeof(params->serial_num)));
 	}
 	if ((params->flags & CTL_LUN_FLAG_DEVID) == 0) {
 		snprintf(tmpstr, sizeof(tmpstr), "MYDEVID%4d", softc->num_luns);
-		strncpy((char *)be_lun->ctl_be_lun.device_id, tmpstr,
-			MIN(sizeof(be_lun->ctl_be_lun.device_id),
-			sizeof(tmpstr)));
+		strncpy((char *)cbe_lun->device_id, tmpstr,
+			MIN(sizeof(cbe_lun->device_id), sizeof(tmpstr)));
 
 		/* Tell the user what we used for a device ID */
 		strncpy((char *)params->device_id, tmpstr,
 			MIN(sizeof(params->device_id), sizeof(tmpstr)));
 	} else {
-		strncpy((char *)be_lun->ctl_be_lun.device_id,
-			params->device_id,
-			MIN(sizeof(be_lun->ctl_be_lun.device_id),
+		strncpy((char *)cbe_lun->device_id, params->device_id,
+			MIN(sizeof(cbe_lun->device_id),
 			    sizeof(params->device_id)));
 	}
 
@@ -2375,7 +2357,7 @@ ctl_be_block_create(struct ctl_be_block_
 
 	mtx_unlock(&softc->lock);
 
-	retval = ctl_add_lun(&be_lun->ctl_be_lun);
+	retval = ctl_add_lun(&be_lun->cbe_lun);
 	if (retval != 0) {
 		mtx_lock(&softc->lock);
 		STAILQ_REMOVE(&softc->lun_list, be_lun, ctl_be_block_lun,
@@ -2413,15 +2395,15 @@ ctl_be_block_create(struct ctl_be_block_
 		mtx_unlock(&softc->lock);
 		goto bailout_error;
 	} else {
-		params->req_lun_id = be_lun->ctl_be_lun.lun_id;
+		params->req_lun_id = cbe_lun->lun_id;
 	}
 
 	mtx_unlock(&softc->lock);
 
 	be_lun->disk_stats = devstat_new_entry("cbb", params->req_lun_id,
-					       be_lun->blocksize,
+					       cbe_lun->blocksize,
 					       DEVSTAT_ALL_SUPPORTED,
-					       be_lun->ctl_be_lun.lun_type
+					       cbe_lun->lun_type
 					       | DEVSTAT_TYPE_IF_OTHER,
 					       DEVSTAT_PRIORITY_OTHER);
 
@@ -2437,7 +2419,7 @@ bailout_error:
 		free(be_lun->dev_path, M_CTLBLK);
 	if (be_lun->lun_zone != NULL)
 		uma_zdestroy(be_lun->lun_zone);
-	ctl_free_opts(&be_lun->ctl_be_lun.options);
+	ctl_free_opts(&cbe_lun->options);
 	mtx_destroy(&be_lun->queue_lock);
 	mtx_destroy(&be_lun->io_lock);
 	free(be_lun, M_CTLBLK);
@@ -2459,7 +2441,7 @@ ctl_be_block_rm(struct ctl_be_block_soft
 	be_lun = NULL;
 
 	STAILQ_FOREACH(be_lun, &softc->lun_list, links) {
-		if (be_lun->ctl_be_lun.lun_id == params->lun_id)
+		if (be_lun->cbe_lun.lun_id == params->lun_id)
 			break;
 	}
 	mtx_unlock(&softc->lock);
@@ -2471,7 +2453,7 @@ ctl_be_block_rm(struct ctl_be_block_soft
 		goto bailout_error;
 	}
 
-	retval = ctl_disable_lun(&be_lun->ctl_be_lun);
+	retval = ctl_disable_lun(&be_lun->cbe_lun);
 
 	if (retval != 0) {
 		snprintf(req->error_str, sizeof(req->error_str),
@@ -2481,7 +2463,7 @@ ctl_be_block_rm(struct ctl_be_block_soft

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201510050851.t958pLUl015183>