svn commit: r287502 - in projects/clang-trunk: contrib/llvm/tools/lldb sys/cam/ctl sys/dev/drm2/i915 sys/dev/e1000 sys/kern sys/sys usr.bin/procstat usr.sbin/ctladm usr.sbin/ctld usr.sbin/sesutil

Dimitry Andric dim at FreeBSD.org
Sun Sep 6 12:02:31 UTC 2015


Author: dim
Date: Sun Sep  6 12:02:28 2015
New Revision: 287502
URL: https://svnweb.freebsd.org/changeset/base/287502

Log:
  Merge ^/head r287490 through r287501.

Modified:
  projects/clang-trunk/contrib/llvm/tools/lldb/FREEBSD-Xlist
  projects/clang-trunk/sys/cam/ctl/ctl.c
  projects/clang-trunk/sys/cam/ctl/ctl.h
  projects/clang-trunk/sys/cam/ctl/ctl_backend.c
  projects/clang-trunk/sys/cam/ctl/ctl_backend.h
  projects/clang-trunk/sys/cam/ctl/ctl_backend_block.c
  projects/clang-trunk/sys/cam/ctl/ctl_backend_ramdisk.c
  projects/clang-trunk/sys/cam/ctl/ctl_private.h
  projects/clang-trunk/sys/dev/drm2/i915/intel_drv.h
  projects/clang-trunk/sys/dev/drm2/i915/intel_ringbuffer.h
  projects/clang-trunk/sys/dev/drm2/i915/intel_sdvo_regs.h
  projects/clang-trunk/sys/dev/e1000/e1000_80003es2lan.c
  projects/clang-trunk/sys/dev/e1000/e1000_82540.c
  projects/clang-trunk/sys/dev/e1000/e1000_82541.c
  projects/clang-trunk/sys/dev/e1000/e1000_82542.c
  projects/clang-trunk/sys/dev/e1000/e1000_82543.c
  projects/clang-trunk/sys/dev/e1000/e1000_82571.h
  projects/clang-trunk/sys/dev/e1000/e1000_82575.c
  projects/clang-trunk/sys/dev/e1000/e1000_82575.h
  projects/clang-trunk/sys/dev/e1000/e1000_api.c
  projects/clang-trunk/sys/dev/e1000/e1000_api.h
  projects/clang-trunk/sys/dev/e1000/e1000_defines.h
  projects/clang-trunk/sys/dev/e1000/e1000_hw.h
  projects/clang-trunk/sys/dev/e1000/e1000_i210.c
  projects/clang-trunk/sys/dev/e1000/e1000_i210.h
  projects/clang-trunk/sys/dev/e1000/e1000_ich8lan.c
  projects/clang-trunk/sys/dev/e1000/e1000_ich8lan.h
  projects/clang-trunk/sys/dev/e1000/e1000_mac.c
  projects/clang-trunk/sys/dev/e1000/e1000_mac.h
  projects/clang-trunk/sys/dev/e1000/e1000_nvm.c
  projects/clang-trunk/sys/dev/e1000/e1000_nvm.h
  projects/clang-trunk/sys/dev/e1000/e1000_osdep.h
  projects/clang-trunk/sys/dev/e1000/e1000_phy.c
  projects/clang-trunk/sys/dev/e1000/e1000_regs.h
  projects/clang-trunk/sys/dev/e1000/if_em.c
  projects/clang-trunk/sys/dev/e1000/if_em.h
  projects/clang-trunk/sys/dev/e1000/if_igb.c
  projects/clang-trunk/sys/kern/vfs_cache.c
  projects/clang-trunk/sys/kern/vfs_hash.c
  projects/clang-trunk/sys/kern/vfs_subr.c
  projects/clang-trunk/sys/sys/vnode.h
  projects/clang-trunk/usr.bin/procstat/procstat_kstack.c
  projects/clang-trunk/usr.sbin/ctladm/ctladm.8
  projects/clang-trunk/usr.sbin/ctladm/ctladm.c
  projects/clang-trunk/usr.sbin/ctld/ctld.c
  projects/clang-trunk/usr.sbin/ctld/ctld.h
  projects/clang-trunk/usr.sbin/ctld/kernel.c
  projects/clang-trunk/usr.sbin/sesutil/sesutil.c
Directory Properties:
  projects/clang-trunk/   (props changed)
  projects/clang-trunk/contrib/llvm/   (props changed)
  projects/clang-trunk/contrib/llvm/tools/lldb/   (props changed)
  projects/clang-trunk/sys/   (props changed)
  projects/clang-trunk/usr.bin/procstat/   (props changed)

Modified: projects/clang-trunk/contrib/llvm/tools/lldb/FREEBSD-Xlist
==============================================================================
--- projects/clang-trunk/contrib/llvm/tools/lldb/FREEBSD-Xlist	Sun Sep  6 11:48:50 2015	(r287501)
+++ projects/clang-trunk/contrib/llvm/tools/lldb/FREEBSD-Xlist	Sun Sep  6 12:02:28 2015	(r287502)
@@ -3,6 +3,7 @@
 .clang-format
 .gitignore
 CMakeLists.txt
+CODE_OWNERS.txt
 INSTALL.txt
 Makefile
 cmake/
@@ -27,6 +28,7 @@ include/lldb/Host/msvc/
 include/lldb/Host/windows/
 include/lldb/Makefile
 lib/
+lit/
 lldb.xcodeproj/
 lldb.xcworkspace/
 resources/
@@ -46,12 +48,15 @@ source/Expression/CMakeLists.txt
 source/Expression/Makefile
 source/Host/CMakeLists.txt
 source/Host/Makefile
+source/Host/android/
 source/Host/common/Makefile
 source/Host/freebsd/Makefile
 source/Host/linux/
 source/Host/macosx/
 source/Host/posix/Makefile
 source/Host/windows/
+source/Initialization/CMakeLists.txt
+source/Initialization/Makefile
 source/Interpreter/CMakeLists.txt
 source/Interpreter/Makefile
 source/Makefile
@@ -62,8 +67,18 @@ source/Plugins/ABI/MacOSX-arm64/CMakeLis
 source/Plugins/ABI/MacOSX-arm64/Makefile
 source/Plugins/ABI/MacOSX-i386/CMakeLists.txt
 source/Plugins/ABI/MacOSX-i386/Makefile
+source/Plugins/ABI/SysV-arm/CMakeLists.txt
+source/Plugins/ABI/SysV-arm/Makefile
+source/Plugins/ABI/SysV-arm64/CMakeLists.txt
+source/Plugins/ABI/SysV-arm64/Makefile
 source/Plugins/ABI/SysV-hexagon/CMakeLists.txt
 source/Plugins/ABI/SysV-hexagon/Makefile
+source/Plugins/ABI/SysV-i386/CMakeLists.txt
+source/Plugins/ABI/SysV-i386/Makefile
+source/Plugins/ABI/SysV-mips/CMakeLists.txt
+source/Plugins/ABI/SysV-mips/Makefile
+source/Plugins/ABI/SysV-mips64/CMakeLists.txt
+source/Plugins/ABI/SysV-mips64/Makefile
 source/Plugins/ABI/SysV-ppc/CMakeLists.txt
 source/Plugins/ABI/SysV-ppc/Makefile
 source/Plugins/ABI/SysV-ppc64/CMakeLists.txt
@@ -88,6 +103,10 @@ source/Plugins/Instruction/ARM/Makefile
 source/Plugins/Instruction/ARM64/CMakeLists.txt
 source/Plugins/Instruction/ARM64/Makefile
 source/Plugins/Instruction/CMakeLists.txt
+source/Plugins/Instruction/MIPS/CMakeLists.txt
+source/Plugins/Instruction/MIPS/Makefile
+source/Plugins/Instruction/MIPS64/CMakeLists.txt
+source/Plugins/Instruction/MIPS64/Makefile
 source/Plugins/InstrumentationRuntime/AddressSanitizer/CMakeLists.txt
 source/Plugins/InstrumentationRuntime/AddressSanitizer/Makefile
 source/Plugins/InstrumentationRuntime/CMakeLists.txt
@@ -99,6 +118,9 @@ source/Plugins/LanguageRuntime/CPlusPlus
 source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/CMakeLists.txt
 source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/Makefile
 source/Plugins/LanguageRuntime/ObjC/
+source/Plugins/LanguageRuntime/RenderScript/CMakeLists.txt
+source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/CMakeLists.txt
+source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/Makefile
 source/Plugins/Makefile
 source/Plugins/MemoryHistory/CMakeLists.txt
 source/Plugins/MemoryHistory/asan/CMakeLists.txt
@@ -117,6 +139,7 @@ source/Plugins/ObjectFile/PECOFF/
 source/Plugins/OperatingSystem/CMakeLists.txt
 source/Plugins/OperatingSystem/Python/CMakeLists.txt
 source/Plugins/OperatingSystem/Python/Makefile
+source/Plugins/Platform/Android/
 source/Plugins/Platform/CMakeLists.txt
 source/Plugins/Platform/FreeBSD/CMakeLists.txt
 source/Plugins/Platform/FreeBSD/Makefile
@@ -168,6 +191,7 @@ source/Utility/Makefile
 test/
 tools/CMakeLists.txt
 tools/Makefile
+tools/argdumper/CMakeLists.txt
 tools/darwin-debug/
 tools/darwin-threads/
 tools/debugserver/
@@ -180,7 +204,9 @@ tools/lldb-mi/CMakeLists.txt
 tools/lldb-mi/Makefile
 tools/lldb-mi/lldb-Info.plist
 tools/lldb-perf/
-tools/lldb-platform/CMakeLists.txt
-tools/lldb-platform/Makefile
+tools/lldb-platform/
+tools/lldb-server/CMakeLists.txt
+tools/lldb-server/Makefile
+unittests/
 utils/
 www/

Modified: projects/clang-trunk/sys/cam/ctl/ctl.c
==============================================================================
--- projects/clang-trunk/sys/cam/ctl/ctl.c	Sun Sep  6 11:48:50 2015	(r287501)
+++ projects/clang-trunk/sys/cam/ctl/ctl.c	Sun Sep  6 12:02:28 2015	(r287502)
@@ -4001,7 +4001,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;
 
@@ -4167,21 +4167,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();
@@ -6274,7 +6259,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 */
@@ -6297,7 +6282,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 */
@@ -10530,15 +10515,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:
@@ -10765,7 +10751,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: projects/clang-trunk/sys/cam/ctl/ctl.h
==============================================================================
--- projects/clang-trunk/sys/cam/ctl/ctl.h	Sun Sep  6 11:48:50 2015	(r287501)
+++ projects/clang-trunk/sys/cam/ctl/ctl.h	Sun Sep  6 12:02:28 2015	(r287502)
@@ -208,6 +208,8 @@ typedef STAILQ_HEAD(ctl_options, ctl_opt
 
 struct ctl_be_arg;
 void ctl_init_opts(ctl_options_t *opts, int num_args, struct ctl_be_arg *args);
+void ctl_update_opts(ctl_options_t *opts, int num_args,
+    struct ctl_be_arg *args);
 void ctl_free_opts(ctl_options_t *opts);
 char * ctl_get_opt(ctl_options_t *opts, const char *name);
 int ctl_expand_number(const char *buf, uint64_t *num);

Modified: projects/clang-trunk/sys/cam/ctl/ctl_backend.c
==============================================================================
--- projects/clang-trunk/sys/cam/ctl/ctl_backend.c	Sun Sep  6 11:48:50 2015	(r287501)
+++ projects/clang-trunk/sys/cam/ctl/ctl_backend.c	Sun Sep  6 12:02:28 2015	(r287502)
@@ -185,15 +185,48 @@ ctl_init_opts(ctl_options_t *opts, int n
 		if ((args[i].flags & CTL_BEARG_ASCII) == 0)
 			continue;
 		opt = malloc(sizeof(*opt), M_CTL, M_WAITOK);
-		opt->name = malloc(strlen(args[i].kname) + 1, M_CTL, M_WAITOK);
-		strcpy(opt->name, args[i].kname);
-		opt->value = malloc(strlen(args[i].kvalue) + 1, M_CTL, M_WAITOK);
-		strcpy(opt->value, args[i].kvalue);
+		opt->name = strdup(args[i].kname, M_CTL);
+		opt->value = strdup(args[i].kvalue, M_CTL);
 		STAILQ_INSERT_TAIL(opts, opt, links);
 	}
 }
 
 void
+ctl_update_opts(ctl_options_t *opts, int num_args, struct ctl_be_arg *args)
+{
+	struct ctl_option *opt;
+	int i;
+
+	for (i = 0; i < num_args; i++) {
+		if ((args[i].flags & CTL_BEARG_RD) == 0)
+			continue;
+		if ((args[i].flags & CTL_BEARG_ASCII) == 0)
+			continue;
+		STAILQ_FOREACH(opt, opts, links) {
+			if (strcmp(opt->name, args[i].kname) == 0)
+				break;
+		}
+		if (args[i].kvalue != NULL &&
+		    ((char *)args[i].kvalue)[0] != 0) {
+			if (opt) {
+				free(opt->value, M_CTL);
+				opt->value = strdup(args[i].kvalue, M_CTL);
+			} else {
+				opt = malloc(sizeof(*opt), M_CTL, M_WAITOK);
+				opt->name = strdup(args[i].kname, M_CTL);
+				opt->value = strdup(args[i].kvalue, M_CTL);
+				STAILQ_INSERT_TAIL(opts, opt, links);
+			}
+		} else if (opt) {
+			STAILQ_REMOVE(opts, opt, ctl_option, links);
+			free(opt->name, M_CTL);
+			free(opt->value, M_CTL);
+			free(opt, M_CTL);
+		}
+	}
+}
+
+void
 ctl_free_opts(ctl_options_t *opts)
 {
 	struct ctl_option *opt;

Modified: projects/clang-trunk/sys/cam/ctl/ctl_backend.h
==============================================================================
--- projects/clang-trunk/sys/cam/ctl/ctl_backend.h	Sun Sep  6 11:48:50 2015	(r287501)
+++ projects/clang-trunk/sys/cam/ctl/ctl_backend.h	Sun Sep  6 12:02:28 2015	(r287502)
@@ -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: projects/clang-trunk/sys/cam/ctl/ctl_backend_block.c
==============================================================================
--- projects/clang-trunk/sys/cam/ctl/ctl_backend_block.c	Sun Sep  6 11:48:50 2015	(r287501)
+++ projects/clang-trunk/sys/cam/ctl/ctl_backend_block.c	Sun Sep  6 12:02:28 2015	(r287502)
@@ -116,7 +116,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 {
@@ -167,18 +166,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;
@@ -768,7 +760,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);
@@ -788,8 +780,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);
@@ -810,14 +802,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);
@@ -928,7 +920,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)
@@ -946,8 +938,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);
@@ -1003,7 +995,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;
@@ -1013,7 +1005,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;
@@ -1055,11 +1047,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,
@@ -1111,7 +1103,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;
@@ -1158,6 +1150,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;
 
@@ -1165,8 +1158,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;
@@ -1195,6 +1188,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;
@@ -1221,8 +1215,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;
 
@@ -1236,27 +1230,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);
 
@@ -1268,16 +1262,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) {
@@ -1462,6 +1456,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;
@@ -1516,9 +1511,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++) {
@@ -1663,13 +1658,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.
@@ -1739,6 +1734,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;
@@ -1747,6 +1743,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;
 
@@ -1755,6 +1752,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) {
@@ -1779,19 +1778,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
@@ -1800,59 +1791,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;
@@ -1875,6 +1870,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)
@@ -1884,6 +1880,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) {
@@ -1920,7 +1917,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 "
@@ -1935,7 +1932,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);
@@ -1960,6 +1957,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);
@@ -1974,36 +1974,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;
@@ -2016,11 +2016,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);
 }
@@ -2028,10 +2030,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) {
@@ -2050,6 +2052,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;
 
@@ -2070,36 +2075,47 @@ 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);
 	}
-
 	pwd_ensure_dirs();
 
- 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
@@ -2108,28 +2124,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. */
@@ -2146,12 +2158,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];
@@ -2164,10 +2187,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);
@@ -2177,12 +2199,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");
@@ -2190,46 +2210,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;

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


More information about the svn-src-projects mailing list