[stgt] [PATCH] Make the backing-store modules shared objects that are loaded at runtime

Ronnie Sahlberg ronniesahlberg at gmail.com
Wed Aug 21 04:46:03 CEST 2013


Dynamically loaded bs_*.so files can only bind to and use functions from
other shared objects and not from the main executable.
Since all bs_*.c backends use helper functions from bs.c
turn it into a shared library libtgt_bs.so
Additionally move some additional functions that the backend modules need
to libtgt_bs.so

Change five backing stores  bs_aio/null/rbd/rdwr/ssc into shared objec
and install them under $(PREFIX)/lib/tgtd/backing-store.

Leave the sixth backend bs_sg.c as a built in module. The reason is because
this backend does not need additional dependencies and also since it
would require most of spc.c to become part of the shared library and by
extension this would then pull in almost all of TGTD into the shared library.

When tgtd is starting, have it traverse the directory for backing stores and
automatically load and initialize all backing stores files that are found.

This allows for example to distribute bs_aio.so as a separate package
since it has additional dependencies (libaio) that tgtd itself does not have
Similarly for bs_rbd.so.
This means that core TGTD can be distributed with minimal dependencies
and backends that add additional dependencies can be distributed separately.

Signed-off-by: Ronnie Sahlberg <ronniesahlberg at gmail.com>
---
 usr/Makefile  |   39 ++++++++++++----
 usr/bs.c      |  139 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 usr/bs.h      |   16 +++++++
 usr/bs_aio.c  |   11 +++--
 usr/bs_null.c |    2 +-
 usr/bs_rbd.c  |    9 ++--
 usr/bs_rdwr.c |   13 +++---
 usr/bs_sg.c   |   45 ++++++++++++++++--
 usr/bs_ssc.c  |   86 ++++++++++++++++++-----------------
 usr/mmc.c     |   75 ++++++++++++++++---------------
 usr/sbc.c     |   21 +++++----
 usr/scsi.c    |   31 +++----------
 usr/smc.c     |    9 ++--
 usr/spc.c     |   65 +++++++++++----------------
 usr/spc.h     |    2 -
 usr/ssc.c     |    3 +-
 usr/target.c  |   43 ------------------
 usr/tgtd.c    |    1 +
 usr/tgtd.h    |   10 +----
 usr/util.c    |   47 -------------------
 usr/util.h    |    3 +-
 21 files changed, 380 insertions(+), 290 deletions(-)
 create mode 100644 usr/bs.h

diff --git a/usr/Makefile b/usr/Makefile
index 453eb1a..dc19f26 100644
--- a/usr/Makefile
+++ b/usr/Makefile
@@ -1,4 +1,5 @@
 sbindir ?= $(PREFIX)/sbin
+libdir ?= $(PREFIX)/lib/tgtd
 
 ifneq ($(shell test -e /usr/include/linux/signalfd.h && echo 1),)
 CFLAGS += -DUSE_SIGNALFD
@@ -14,14 +15,12 @@ TGTD_OBJS += $(addprefix iscsi/, conn.o param.o session.o \
 TGTD_OBJS += bs_rdwr.o
 
 ifneq ($(CEPH_RBD),)
-TGTD_OBJS += bs_rbd.o
-LIBS += -lrados -lrbd
+BS_OBJS += bs_rbd.so
 endif
 
 ifneq ($(shell test -e /usr/include/sys/eventfd.h && test -e /usr/include/libaio.h && echo 1),)
 CFLAGS += -DUSE_EVENTFD
-TGTD_OBJS += bs_aio.o
-LIBS += -laio
+BS_OBJS += bs_aio.so
 endif
 
 ifneq ($(ISCSI_RDMA),)
@@ -40,25 +39,31 @@ CFLAGS += -g -O2 -fno-strict-aliasing
 endif
 CFLAGS += -Wall -Wstrict-prototypes -fPIC
 CFLAGS += -DTGT_VERSION=\"$(VERSION)$(EXTRAVERSION)\"
+CFLAGS += -DBSDIR=\"$(DESTDIR)$(libdir)/backing-store\"
 
 LIBS += -lpthread
 
 PROGRAMS += tgtd tgtadm tgtimg
 TGTD_OBJS += tgtd.o mgmt.o target.o scsi.o log.o driver.o util.o work.o \
 		concat_buf.o parser.o spc.o sbc.o mmc.o osd.o scc.o smc.o \
-		ssc.o bs_ssc.o libssc.o \
-		bs_null.o bs_sg.o bs.o libcrc32c.o
+		ssc.o bs_sg.o libcrc32c.o
+LIBTGT_OBJS = bs.o
+
+BS_OBJS += bs_null.so bs_rdwr.so bs_ssc.so
 
 TGTD_DEP = $(TGTD_OBJS:.o=.d)
 
 .PHONY:all
-all: $(PROGRAMS)
+all: libtgt_bs.so $(PROGRAMS) $(BS_OBJS) 
 
 tgtd: $(TGTD_OBJS)
-	$(CC) $^ -o $@ $(LIBS)
+	$(CC) $^ -o $@ $(LIBS) libtgt_bs.so
 
 -include $(TGTD_DEP)
 
+libtgt_bs.so: $(LIBTGT_OBJS)
+	$(CC) -shared -fPIC -DPIC $^ -o $@  -ldl
+
 TGTADM_OBJS = tgtadm.o concat_buf.o
 TGTADM_DEP = $(TGTADM_OBJS:.o=.d)
 
@@ -79,11 +84,27 @@ tgtimg: $(TGTIMG_OBJS)
 	$(CC) -c $(CFLAGS) $*.c -o $*.o
 	@$(CC) -MM $(CFLAGS) -MF $*.d -MT $*.o $*.c
 
+%.so: %.c
+	$(CC) -shared $(CFLAGS) $*.c -o $*.so
+
+bs_aio.so: bs_aio.c
+	$(CC) -shared $(CFLAGS) bs_aio.c -o bs_aio.so -laio
+
+bs_rbd.so: bs_rbd.c
+	$(CC) -shared $(CFLAGS) bs_rbd.c -o bs_rbd.so -lrados -lrbd
+
+bs_ssc.so: bs_ssc.c
+	$(CC) -shared $(CFLAGS) bs_ssc.c -o bs_ssc.so libssc.o libcrc32c.o
+
 .PHONY: install
 install: $(PROGRAMS)
 	install -d -m 755 $(DESTDIR)$(sbindir)
 	install -m 755 $(PROGRAMS) $(DESTDIR)$(sbindir)
+	install -d -m 755 $(DESTDIR)$(libdir)/backing-store
+	install -m 755 $(BS_OBJS) $(DESTDIR)$(libdir)/backing-store
+	install -m 755 libtgt_bs.so $(DESTDIR)$(libdir)
+	ldconfig $(DESTDIR)$(libdir)
 
 .PHONY: clean
 clean:
-	rm -f *.[od] $(PROGRAMS) iscsi/*.[od] ibmvio/*.[od] fc/*.[od]
+	rm -f *.[od] *.so $(PROGRAMS) iscsi/*.[od] ibmvio/*.[od] fc/*.[od]
diff --git a/usr/bs.c b/usr/bs.c
index 65c332e..279c6f0 100644
--- a/usr/bs.c
+++ b/usr/bs.c
@@ -19,6 +19,9 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  * 02110-1301 USA
  */
+#define _GNU_SOURCE
+#include <dirent.h>
+#include <dlfcn.h>
 #include <errno.h>
 #include <string.h>
 #include <inttypes.h>
@@ -27,11 +30,17 @@
 #include <stdlib.h>
 #include <unistd.h>
 #include <fcntl.h>
+#include <linux/fs.h>
 #include <signal.h>
+#include <stdio.h>
 #include <syscall.h>
-#include <sys/types.h>
 #include <sys/epoll.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
 #include <linux/types.h>
+#include <unistd.h>
+
 
 #include "list.h"
 #include "tgtd.h"
@@ -309,8 +318,51 @@ destroy_cond_mutex:
 
 int bs_init(void)
 {
+	DIR *dir;
 	int ret;
 
+	dir = opendir(BSDIR);
+	if (dir == NULL) {
+		eprintf("could not open backing-store module directory %s\n",
+			BSDIR); 
+	} else {
+		struct dirent *dirent;
+		void *handle;
+		while ((dirent = readdir(dir))) {
+			char *soname;
+			void (*register_bs_module)(void);
+
+			if (dirent->d_name[0] == '.') {
+				continue;
+			}
+
+			ret = asprintf(&soname, "%s/%s", BSDIR,
+					dirent->d_name);
+			if (ret == -1) {
+				eprintf("out of memory\n");
+				continue;
+			}
+			handle = dlopen(soname, RTLD_NOW|RTLD_LOCAL);
+			if (handle == NULL) {
+				eprintf("failed to dlopen backing-store "
+					"module %s error %s \n",
+					soname, dlerror());
+				free(soname);
+				continue;
+			}
+			register_bs_module = dlsym(handle, "register_bs_module");
+			if (register_bs_module == NULL) {
+				eprintf("could not find register_bs_module "
+					"symbol in module %s\n",
+					soname);
+				free(soname);
+				continue;
+			}
+			register_bs_module();
+			free(soname);
+		}
+		closedir(dir);
+	}
 	ret = bs_init_signalfd();
 	if (!ret) {
 		eprintf("use signalfd notification\n");
@@ -412,3 +464,88 @@ int bs_thread_cmd_submit(struct scsi_cmd *cmd)
 
 	return 0;
 }
+
+void bs_update_lbppbe(struct scsi_lu *lu, int blksize)
+{
+	lu->attrs.lbppbe = 0;
+	while (blksize > (1U << lu->blk_shift)) {
+		lu->attrs.lbppbe++;
+		blksize >>= 1;
+	}
+}
+
+int bs_backed_file_open(char *path, int oflag, uint64_t *size,
+			uint32_t *blksize)
+{
+	int fd, err;
+	struct stat64 st;
+
+	fd = open(path, oflag);
+	if (fd < 0) {
+		eprintf("Could not open %s, %m\n", path);
+		return fd;
+	}
+
+	err = fstat64(fd, &st);
+	if (err < 0) {
+		eprintf("Cannot get stat %d, %m\n", fd);
+		goto close_fd;
+	}
+
+	if (S_ISREG(st.st_mode)) {
+		*size = st.st_size;
+		if (blksize)
+			*blksize = st.st_blksize;
+	} else if (S_ISBLK(st.st_mode)) {
+		err = ioctl(fd, BLKGETSIZE64, size);
+		if (err < 0) {
+			eprintf("Cannot get size, %m\n");
+			goto close_fd;
+		}
+	} else {
+		eprintf("Cannot use this mode %x\n", st.st_mode);
+		err = -EINVAL;
+		goto close_fd;
+	}
+
+	return fd;
+
+close_fd:
+	close(fd);
+	return err;
+}
+
+struct mode_pg *bs_find_mode_page(struct scsi_lu *lu, uint8_t pcode,
+			       uint8_t subpcode)
+{
+	struct mode_pg *pg;
+
+	list_for_each_entry(pg, &lu->mode_pages, mode_pg_siblings) {
+		if (pg->pcode == pcode && pg->subpcode == subpcode)
+			return pg;
+	}
+	return NULL;
+}
+
+void bs_sense_data_build(struct scsi_cmd *cmd, uint8_t key, uint16_t asc)
+{
+
+	if (cmd->dev->attrs.sense_format) {
+		/* descriptor format */
+		cmd->sense_buffer[0] = 0x72;  /* current, not deferred */
+		cmd->sense_buffer[1] = key;
+		cmd->sense_buffer[2] = (asc >> 8) & 0xff;
+		cmd->sense_buffer[3] = asc & 0xff;
+		cmd->sense_len = 8;
+	} else {
+		/* fixed format */
+		int len = 0xa;
+		cmd->sense_buffer[0] = 0x70;  /* current, not deferred */
+		cmd->sense_buffer[2] = key;
+		cmd->sense_buffer[7] = len;
+		cmd->sense_buffer[12] = (asc >> 8) & 0xff;
+		cmd->sense_buffer[13] = asc & 0xff;
+		cmd->sense_len = len + 8;
+	}
+}
+
diff --git a/usr/bs.h b/usr/bs.h
new file mode 100644
index 0000000..e266c2c
--- /dev/null
+++ b/usr/bs.h
@@ -0,0 +1,16 @@
+#ifndef __BS_H
+#define __BS_H
+
+#include <inttypes.h>
+
+extern int bs_init(void);
+
+extern int bs_backed_file_open(char *path, int oflag, uint64_t *size,
+			       uint32_t *blksize);
+extern struct mode_pg *bs_find_mode_page(struct scsi_lu *lu,
+					 uint8_t pcode, uint8_t subpcode);
+extern void bs_sense_data_build(struct scsi_cmd *cmd, uint8_t key,
+				uint16_t asc);
+extern void bs_update_lbppbe(struct scsi_lu *lu, int blksize);
+
+#endif
diff --git a/usr/bs_aio.c b/usr/bs_aio.c
index c0cbadd..fb3eb2d 100644
--- a/usr/bs_aio.c
+++ b/usr/bs_aio.c
@@ -38,6 +38,7 @@
 #include "tgtd.h"
 #include "target.h"
 #include "scsi.h"
+#include "bs.h"
 
 #ifndef O_DIRECT
 #define O_DIRECT 040000
@@ -254,7 +255,7 @@ static void bs_aio_complete_one(struct io_event *ep)
 	if (likely(ep->res == length))
 		result = SAM_STAT_GOOD;
 	else {
-		sense_data_build(cmd, MEDIUM_ERROR, 0);
+		bs_sense_data_build(cmd, MEDIUM_ERROR, 0);
 		result = SAM_STAT_CHECK_CONDITION;
 	}
 	dprintf("cmd: %p\n", cmd);
@@ -341,13 +342,13 @@ static int bs_aio_open(struct scsi_lu *lu, char *path, int *fd, uint64_t *size)
 
 	eprintf("open %s, RW, O_DIRECT for tgt:%d lun:%"PRId64 "\n",
 		path, info->lu->tgt->tid, info->lu->lun);
-	*fd = backed_file_open(path, O_RDWR|O_LARGEFILE|O_DIRECT, size,
+	*fd = bs_backed_file_open(path, O_RDWR|O_LARGEFILE|O_DIRECT, size,
 				&blksize);
 	/* If we get access denied, try opening the file in readonly mode */
 	if (*fd == -1 && (errno == EACCES || errno == EROFS)) {
 		eprintf("open %s, READONLY, O_DIRECT for tgt:%d lun:%"PRId64 "\n",
 			path, info->lu->tgt->tid, info->lu->lun);
-		*fd = backed_file_open(path, O_RDONLY|O_LARGEFILE|O_DIRECT,
+		*fd = bs_backed_file_open(path, O_RDONLY|O_LARGEFILE|O_DIRECT,
 				       size, &blksize);
 		lu->attrs.readonly = 1;
 	}
@@ -362,7 +363,7 @@ static int bs_aio_open(struct scsi_lu *lu, char *path, int *fd, uint64_t *size)
 		path, info->lu->tgt->tid, info->lu->lun);
 
 	if (!lu->attrs.no_auto_lbppbe)
-		update_lbppbe(lu, blksize);
+		bs_update_lbppbe(lu, blksize);
 
 	return 0;
 
@@ -414,7 +415,7 @@ static struct backingstore_template aio_bst = {
 	.bs_cmd_submit  	= bs_aio_cmd_submit,
 };
 
-__attribute__((constructor)) static void bs_rdwr_constructor(void)
+void register_bs_module(void)
 {
 	register_backingstore_template(&aio_bst);
 }
diff --git a/usr/bs_null.c b/usr/bs_null.c
index d463f18..4dbe144 100644
--- a/usr/bs_null.c
+++ b/usr/bs_null.c
@@ -56,7 +56,7 @@ static struct backingstore_template null_bst = {
 	.bs_cmd_submit		= bs_null_cmd_submit,
 };
 
-__attribute__((constructor)) static void bs_null_constructor(void)
+void register_bs_module(void)
 {
 	register_backingstore_template(&null_bst);
 }
diff --git a/usr/bs_rbd.c b/usr/bs_rbd.c
index b09090b..496f0a9 100644
--- a/usr/bs_rbd.c
+++ b/usr/bs_rbd.c
@@ -35,6 +35,7 @@
 #include <linux/fs.h>
 #include <sys/epoll.h>
 
+#include "bs.h"
 #include "list.h"
 #include "util.h"
 #include "tgtd.h"
@@ -250,7 +251,7 @@ write:
 			 * it would be better not to access to pg
 			 * directy.
 			 */
-			pg = find_mode_page(cmd->dev, 0x08, 0);
+			pg = bs_find_mode_page(cmd->dev, 0x08, 0);
 			if (pg == NULL) {
 				result = SAM_STAT_CHECK_CONDITION;
 				key = ILLEGAL_REQUEST;
@@ -407,7 +408,7 @@ verify:
 	if (result != SAM_STAT_GOOD) {
 		eprintf("io error %p %x %d %d %" PRIu64 ", %m\n",
 			cmd, cmd->scb[0], ret, length, offset);
-		sense_data_build(cmd, key, asc);
+		bs_sense_data_build(cmd, key, asc);
 	}
 }
 
@@ -460,7 +461,7 @@ static int bs_rbd_open(struct scsi_lu *lu, char *path, int *fd, uint64_t *size)
 	blksize = inf.obj_size;
 
 	if (!lu->attrs.no_auto_lbppbe)
-		update_lbppbe(lu, blksize);
+		bs_update_lbppbe(lu, blksize);
 
 	return 0;
 }
@@ -529,7 +530,7 @@ static struct backingstore_template rbd_bst = {
 	.bs_oflags_supported    = O_SYNC | O_DIRECT,
 };
 
-static __attribute__((constructor)) void bs_rbd_constructor(void)
+void register_bs_module(void)
 {
 	register_backingstore_template(&rbd_bst);
 }
diff --git a/usr/bs_rdwr.c b/usr/bs_rdwr.c
index 47d2d99..723ce64 100644
--- a/usr/bs_rdwr.c
+++ b/usr/bs_rdwr.c
@@ -40,6 +40,7 @@
 #include "scsi.h"
 #include "spc.h"
 #include "bs_thread.h"
+#include "bs.h"
 
 static void set_medium_error(int *result, uint8_t *key, uint16_t *asc)
 {
@@ -197,7 +198,7 @@ write:
 			 * it would be better not to access to pg
 			 * directy.
 			 */
-			pg = find_mode_page(cmd->dev, 0x08, 0);
+			pg = bs_find_mode_page(cmd->dev, 0x08, 0);
 			if (pg == NULL) {
 				result = SAM_STAT_CHECK_CONDITION;
 				key = ILLEGAL_REQUEST;
@@ -368,7 +369,7 @@ verify:
 	if (result != SAM_STAT_GOOD) {
 		eprintf("io error %p %x %d %d %" PRIu64 ", %m\n",
 			cmd, cmd->scb[0], ret, length, offset);
-		sense_data_build(cmd, key, asc);
+		bs_sense_data_build(cmd, key, asc);
 	}
 }
 
@@ -376,11 +377,11 @@ static int bs_rdwr_open(struct scsi_lu *lu, char *path, int *fd, uint64_t *size)
 {
 	uint32_t blksize = 0;
 
-	*fd = backed_file_open(path, O_RDWR|O_LARGEFILE|lu->bsoflags, size,
+	*fd = bs_backed_file_open(path, O_RDWR|O_LARGEFILE|lu->bsoflags, size,
 				&blksize);
 	/* If we get access denied, try opening the file in readonly mode */
 	if (*fd == -1 && (errno == EACCES || errno == EROFS)) {
-		*fd = backed_file_open(path, O_RDONLY|O_LARGEFILE|lu->bsoflags,
+		*fd = bs_backed_file_open(path, O_RDONLY|O_LARGEFILE|lu->bsoflags,
 				       size, &blksize);
 		lu->attrs.readonly = 1;
 	}
@@ -388,7 +389,7 @@ static int bs_rdwr_open(struct scsi_lu *lu, char *path, int *fd, uint64_t *size)
 		return *fd;
 
 	if (!lu->attrs.no_auto_lbppbe)
-		update_lbppbe(lu, blksize);
+		bs_update_lbppbe(lu, blksize);
 
 	return 0;
 }
@@ -423,7 +424,7 @@ static struct backingstore_template rdwr_bst = {
 	.bs_oflags_supported    = O_SYNC | O_DIRECT,
 };
 
-__attribute__((constructor)) static void bs_rdwr_constructor(void)
+void register_bs_module(void)
 {
 	register_backingstore_template(&rdwr_bst);
 }
diff --git a/usr/bs_sg.c b/usr/bs_sg.c
index 5f1e687..cecf45c 100644
--- a/usr/bs_sg.c
+++ b/usr/bs_sg.c
@@ -44,6 +44,7 @@
 #include "scsi.h"
 #include "spc.h"
 #include "tgtadm_error.h"
+#include "bs.h"
 
 #define BS_SG_RESVD_SZ  (512 * 1024)
 
@@ -106,7 +107,7 @@ static int bs_sg_rw(int host_no, struct scsi_cmd *cmd)
 	scsi_set_in_resid_by_actual(cmd, 0);
 	scsi_set_out_resid_by_actual(cmd, 0);
 
-	sense_data_build(cmd, key, asc);
+	bs_sense_data_build(cmd, key, asc);
 	return SAM_STAT_CHECK_CONDITION;
 }
 
@@ -117,7 +118,7 @@ static int set_cmd_failed(struct scsi_cmd *cmd)
 	uint8_t key = MEDIUM_ERROR;
 
 	scsi_set_result(cmd, result);
-	sense_data_build(cmd, key, asc);
+	bs_sense_data_build(cmd, key, asc);
 
 	return result;
 }
@@ -420,19 +421,53 @@ static int init_sg_device(int fd)
 	return 0;
 }
 
+/*
+ * Used by bs_sg for CDB passthrough to STGT LUNs
+ */
+static int sg_cmd_perform_passthrough(int tid, struct scsi_cmd *cmd)
+{
+	int result;
+
+	dprintf("%p %x %" PRIx64 " PT\n", cmd, cmd->scb[0], cmd->dev_id);
+
+	result = cmd->dev->dev_type_template.cmd_passthrough(tid, cmd);
+
+	dprintf("%" PRIx64 " %x %p %p %" PRIu64 " %u %u %d %d\n",
+		cmd->tag, cmd->scb[0], scsi_get_out_buffer(cmd),
+		scsi_get_in_buffer(cmd), cmd->offset,
+		scsi_get_out_length(cmd), scsi_get_in_length(cmd),
+		result, cmd_async(cmd));
+
+	set_cmd_processed(cmd);
+	if (!cmd_async(cmd))
+		target_cmd_io_done(cmd, result);
+
+	return 0;
+}
+
+/*
+ * Used by struct scsi_lu->cmd_done() for bs_sg (passthrough) completion
+ */
+static void sg_cmd_done_passthrough(struct target *target, struct scsi_cmd *cmd)
+{
+	dprintf("%p %p %u %u\n", scsi_get_out_buffer(cmd),
+		scsi_get_in_buffer(cmd), scsi_get_out_length(cmd),
+		scsi_get_in_length(cmd));
+}
+
 static tgtadm_err bs_sg_init(struct scsi_lu *lu)
 {
 	/*
 	 * Setup struct scsi_lu->cmd_perform() passthrough pointer
 	 * (if available) for the underlying device type.
 	 */
-	lu->cmd_perform = &target_cmd_perform_passthrough;
+	lu->cmd_perform = &sg_cmd_perform_passthrough;
 
 	/*
 	 * Setup struct scsi_lu->cmd_done() passthrough pointer using
-	 * usr/target.c:__cmd_done_passthrough().
+	 * sg_cmd_done_passthrough().
 	 */
-	lu->cmd_done = &__cmd_done_passthrough;
+	lu->cmd_done = &sg_cmd_done_passthrough;
 	return TGTADM_SUCCESS;
 }
 
diff --git a/usr/bs_ssc.c b/usr/bs_ssc.c
index 117e274..67cf128 100644
--- a/usr/bs_ssc.c
+++ b/usr/bs_ssc.c
@@ -39,6 +39,7 @@
 #include "bs_ssc.h"
 #include "ssc.h"
 #include "libssc.h"
+#include "bs.h"
 
 #define SENSE_FILEMARK	0x80
 #define SENSE_EOM	0x40
@@ -49,7 +50,7 @@ static void ssc_sense_data_build(struct scsi_cmd *cmd, uint8_t key,
 {
 	/* TODO: support descriptor format */
 
-	sense_data_build(cmd, key, asc);
+	bs_sense_data_build(cmd, key, asc);
 	if (info_len) {
 		memcpy(cmd->sense_buffer + 3, info, 4);
 		cmd->sense_buffer[0] |= 0x80;
@@ -166,14 +167,14 @@ static int append_blk(struct scsi_cmd *cmd, uint8_t *data,
 	ret = ssc_write_blkhdr(fd, curr, curr->curr);
 	if (ret) {
 		eprintf("Rewrite of blk header failed: %m\n");
-		sense_data_build(cmd, MEDIUM_ERROR, ASC_WRITE_ERROR);
+		bs_sense_data_build(cmd, MEDIUM_ERROR, ASC_WRITE_ERROR);
 		return SAM_STAT_CHECK_CONDITION;
 	}
 	/* Write new EOD blk header */
 	ret = ssc_write_blkhdr(fd, eod, eod->curr);
 	if (ret) {
 		eprintf("Write of EOD blk header failed: %m\n");
-		sense_data_build(cmd, MEDIUM_ERROR, ASC_WRITE_ERROR);
+		bs_sense_data_build(cmd, MEDIUM_ERROR, ASC_WRITE_ERROR);
 		return SAM_STAT_CHECK_CONDITION;
 	}
 
@@ -183,7 +184,7 @@ static int append_blk(struct scsi_cmd *cmd, uint8_t *data,
 			       curr->curr + SSC_BLK_HDR_SIZE);
 		if (ret != size) {
 			eprintf("Write of data failed: %m\n");
-			sense_data_build(cmd, MEDIUM_ERROR, ASC_WRITE_ERROR);
+			bs_sense_data_build(cmd, MEDIUM_ERROR, ASC_WRITE_ERROR);
 			return SAM_STAT_CHECK_CONDITION;
 		}
 	}
@@ -201,7 +202,7 @@ static int space_filemark_reverse(struct scsi_cmd *cmd, int32_t count)
 
 again:
 	if (!h->prev) {
-		sense_data_build(cmd, NO_SENSE, ASC_BOM);
+		bs_sense_data_build(cmd, NO_SENSE, ASC_BOM);
 		return SAM_STAT_CHECK_CONDITION;
 	}
 
@@ -209,8 +210,8 @@ again:
 		count--;
 
 	if (skip_prev_header(cmd->dev)) {
-		sense_data_build(cmd, MEDIUM_ERROR,
-				 ASC_MEDIUM_FORMAT_CORRUPT);
+		bs_sense_data_build(cmd, MEDIUM_ERROR,
+				    ASC_MEDIUM_FORMAT_CORRUPT);
 		return SAM_STAT_CHECK_CONDITION;
 	}
 
@@ -227,7 +228,7 @@ static int space_filemark_forward(struct scsi_cmd *cmd, int32_t count)
 
 again:
 	if (h->blk_type == BLK_EOD) {
-		sense_data_build(cmd, NO_SENSE, ASC_END_OF_DATA);
+		bs_sense_data_build(cmd, NO_SENSE, ASC_END_OF_DATA);
 		return SAM_STAT_CHECK_CONDITION;
 	}
 
@@ -235,8 +236,8 @@ again:
 		count--;
 
 	if (skip_next_header(cmd->dev)) {
-		sense_data_build(cmd, MEDIUM_ERROR,
-				 ASC_MEDIUM_FORMAT_CORRUPT);
+		bs_sense_data_build(cmd, MEDIUM_ERROR,
+				    ASC_MEDIUM_FORMAT_CORRUPT);
 		return SAM_STAT_CHECK_CONDITION;
 	}
 
@@ -276,27 +277,27 @@ static int space_blocks(struct scsi_cmd *cmd, int32_t count)
 	while (count != 0) {
 		if (count > 0) {
 			if (skip_next_header(cmd->dev)) {
-				sense_data_build(cmd, MEDIUM_ERROR,
-						ASC_MEDIUM_FORMAT_CORRUPT);
+				bs_sense_data_build(cmd, MEDIUM_ERROR,
+						    ASC_MEDIUM_FORMAT_CORRUPT);
 				return SAM_STAT_CHECK_CONDITION;
 			}
 			if (h->blk_type == BLK_EOD) {
-				sense_data_build(cmd, NO_SENSE,
-						ASC_END_OF_DATA);
+				bs_sense_data_build(cmd, NO_SENSE,
+						    ASC_END_OF_DATA);
 				return SAM_STAT_CHECK_CONDITION;
 			}
 			count--;
 		} else {
 			if (skip_prev_header(cmd->dev)) {
-				sense_data_build(cmd, MEDIUM_ERROR,
-						ASC_MEDIUM_FORMAT_CORRUPT);
+				bs_sense_data_build(cmd, MEDIUM_ERROR,
+						    ASC_MEDIUM_FORMAT_CORRUPT);
 				return SAM_STAT_CHECK_CONDITION;
 			}
 			if (h->blk_type == BLK_BOT) {
 				/* Can't leave at BOT */
 				skip_next_header(cmd->dev);
 
-				sense_data_build(cmd, NO_SENSE, ASC_BOM);
+				bs_sense_data_build(cmd, NO_SENSE, ASC_BOM);
 				return SAM_STAT_CHECK_CONDITION;
 			}
 			count++;
@@ -323,8 +324,8 @@ static int resp_var_read(struct scsi_cmd *cmd, uint8_t *buf, uint32_t length,
 		put_unaligned_be32(val, info);
 
 		if (h->blk_type == BLK_EOD)
-			sense_data_build(cmd, 0x40 | BLANK_CHECK,
-					 NO_ADDITIONAL_SENSE);
+			bs_sense_data_build(cmd, 0x40 | BLANK_CHECK,
+					    NO_ADDITIONAL_SENSE);
 		else if (h->blk_type == BLK_FILEMARK)
 			ssc_sense_data_build(cmd, NO_SENSE | SENSE_FILEMARK,
 					     ASC_MARK, info, sizeof(info));
@@ -351,7 +352,7 @@ static int resp_var_read(struct scsi_cmd *cmd, uint8_t *buf, uint32_t length,
 
 	ret = pread64(cmd->dev->fd, buf, length, h->curr + SSC_BLK_HDR_SIZE);
 	if (ret != length) {
-		sense_data_build(cmd, MEDIUM_ERROR, ASC_READ_ERROR);
+		bs_sense_data_build(cmd, MEDIUM_ERROR, ASC_READ_ERROR);
 		result = SAM_STAT_CHECK_CONDITION;
 		goto out;
 	}
@@ -360,7 +361,7 @@ static int resp_var_read(struct scsi_cmd *cmd, uint8_t *buf, uint32_t length,
 skip_and_out:
 	ret = skip_next_header(cmd->dev);
 	if (ret) {
-		sense_data_build(cmd, MEDIUM_ERROR, ASC_MEDIUM_FORMAT_CORRUPT);
+		bs_sense_data_build(cmd, MEDIUM_ERROR, ASC_MEDIUM_FORMAT_CORRUPT);
 		result = SAM_STAT_CHECK_CONDITION;
 	}
 out:
@@ -398,7 +399,7 @@ static int resp_fixed_read(struct scsi_cmd *cmd, uint8_t *buf, uint32_t length,
 		if (block_length != h->blk_sz) {
 			eprintf("block size mismatch %d vs %d\n",
 				block_length, h->blk_sz);
-			sense_data_build(cmd, MEDIUM_ERROR,
+			bs_sense_data_build(cmd, MEDIUM_ERROR,
 						ASC_MEDIUM_FORMAT_CORRUPT);
 			result = SAM_STAT_CHECK_CONDITION;
 			goto out;
@@ -409,7 +410,7 @@ static int resp_fixed_read(struct scsi_cmd *cmd, uint8_t *buf, uint32_t length,
 		if (block_length != residue) {
 			eprintf("Could only read %d bytes, not %d\n",
 					(int)residue, block_length);
-			sense_data_build(cmd, MEDIUM_ERROR, ASC_READ_ERROR);
+			bs_sense_data_build(cmd, MEDIUM_ERROR, ASC_READ_ERROR);
 			result = SAM_STAT_CHECK_CONDITION;
 			goto out;
 		}
@@ -418,7 +419,7 @@ static int resp_fixed_read(struct scsi_cmd *cmd, uint8_t *buf, uint32_t length,
 
 		if (skip_next_header(cmd->dev)) {
 			eprintf("Could not read next header\n");
-			sense_data_build(cmd, MEDIUM_ERROR,
+			bs_sense_data_build(cmd, MEDIUM_ERROR,
 						ASC_MEDIUM_FORMAT_CORRUPT);
 			result = SAM_STAT_CHECK_CONDITION;
 			goto out;
@@ -455,8 +456,9 @@ static void tape_rdwr_request(struct scsi_cmd *cmd)
 	case REZERO_UNIT:
 		dprintf("**** Rewind ****\n");
 		if (resp_rewind(cmd->dev)) {
-			sense_data_build(cmd,
-				MEDIUM_ERROR, ASC_SEQUENTIAL_POSITION_ERR);
+			bs_sense_data_build(cmd,
+					    MEDIUM_ERROR,
+					    ASC_SEQUENTIAL_POSITION_ERR);
 			result = SAM_STAT_CHECK_CONDITION;
 		}
 		break;
@@ -478,8 +480,8 @@ static void tape_rdwr_request(struct scsi_cmd *cmd)
 		sti = cmd->scb[1] & 2;
 
 		if (fixed && sti) {
-			sense_data_build(cmd, ILLEGAL_REQUEST,
-						ASC_INVALID_FIELD_IN_CDB);
+			bs_sense_data_build(cmd, ILLEGAL_REQUEST,
+					    ASC_INVALID_FIELD_IN_CDB);
 			result = SAM_STAT_CHECK_CONDITION;
 			break;
 		}
@@ -515,8 +517,8 @@ static void tape_rdwr_request(struct scsi_cmd *cmd)
 		for (i = 0, ret = 0; i < count; i++) {
 			if (append_blk(cmd, buf, block_length,
 				       block_length, BLK_UNCOMPRESS_DATA)) {
-				sense_data_build(cmd, MEDIUM_ERROR,
-						ASC_WRITE_ERROR);
+				bs_sense_data_build(cmd, MEDIUM_ERROR,
+						    ASC_WRITE_ERROR);
 				result = SAM_STAT_CHECK_CONDITION;
 				break;
 			}
@@ -531,14 +533,14 @@ static void tape_rdwr_request(struct scsi_cmd *cmd)
 
 		/* Check for end of media */
 		if (current_size(cmd) > ssc->mam.max_capacity) {
-			sense_data_build(cmd, NO_SENSE|SENSE_EOM,
-						NO_ADDITIONAL_SENSE);
+			bs_sense_data_build(cmd, NO_SENSE|SENSE_EOM,
+					    NO_ADDITIONAL_SENSE);
 			result = SAM_STAT_CHECK_CONDITION;
 			break;
 		}
 
 		if (ret != length) {
-			sense_data_build(cmd, MEDIUM_ERROR, ASC_WRITE_ERROR);
+			bs_sense_data_build(cmd, MEDIUM_ERROR, ASC_WRITE_ERROR);
 			result = SAM_STAT_CHECK_CONDITION;
 		}
 		break;
@@ -556,14 +558,14 @@ static void tape_rdwr_request(struct scsi_cmd *cmd)
 		} else if (code == 3) { /* End of data */
 			while (h->blk_type != BLK_EOD)
 				if (skip_next_header(cmd->dev)) {
-					sense_data_build(cmd, MEDIUM_ERROR,
-						ASC_MEDIUM_FORMAT_CORRUPT);
+					bs_sense_data_build(cmd, MEDIUM_ERROR,
+					    ASC_MEDIUM_FORMAT_CORRUPT);
 					result = SAM_STAT_CHECK_CONDITION;
 					break;
 				}
 		} else { /* Unsupported */
-			sense_data_build(cmd, ILLEGAL_REQUEST,
-						ASC_INVALID_FIELD_IN_CDB);
+			bs_sense_data_build(cmd, ILLEGAL_REQUEST,
+					    ASC_INVALID_FIELD_IN_CDB);
 			result = SAM_STAT_CHECK_CONDITION;
 		}
 		break;
@@ -588,15 +590,15 @@ static void tape_rdwr_request(struct scsi_cmd *cmd)
 			memset(data, 0, 32);
 			data[0] = 32;
 		} else {
-			sense_data_build(cmd, ILLEGAL_REQUEST,
-						ASC_INVALID_FIELD_IN_CDB);
+			bs_sense_data_build(cmd, ILLEGAL_REQUEST,
+					    ASC_INVALID_FIELD_IN_CDB);
 			result = SAM_STAT_CHECK_CONDITION;
 		}
 		break;
 	}
 	default:
 		eprintf("Unknown op code - should never see this\n");
-		sense_data_build(cmd, ILLEGAL_REQUEST, ASC_INVALID_OP_CODE);
+		bs_sense_data_build(cmd, ILLEGAL_REQUEST, ASC_INVALID_OP_CODE);
 		result = SAM_STAT_CHECK_CONDITION;
 		break;
 	}
@@ -626,7 +628,7 @@ static int bs_ssc_open(struct scsi_lu *lu, char *path, int *fd, uint64_t *size)
 
 	ssc = dtype_priv(lu);
 
-	*fd = backed_file_open(path, O_RDWR | O_LARGEFILE, size, NULL);
+	*fd = bs_backed_file_open(path, O_RDWR | O_LARGEFILE, size, NULL);
 	if (*fd < 0) {
 		eprintf("Could not open %s %m\n", path);
 		return *fd;
@@ -702,7 +704,7 @@ static struct backingstore_template ssc_bst = {
 	.bs_cmd_submit		= bs_thread_cmd_submit,
 };
 
-__attribute__((constructor)) static void bs_ssc_constructor(void)
+void register_bs_module(void)
 {
 	register_backingstore_template(&ssc_bst);
 }
diff --git a/usr/mmc.c b/usr/mmc.c
index 768fe91..75ddce8 100644
--- a/usr/mmc.c
+++ b/usr/mmc.c
@@ -45,6 +45,7 @@
 #include "scsi.h"
 #include "spc.h"
 #include "tgtadm_error.h"
+#include "bs.h"
 
 #define MMC_BLK_SHIFT 11
 
@@ -66,7 +67,7 @@ static int mmc_rw(int host_no, struct scsi_cmd *cmd)
 
 	if (mmc->current_profile == PROFILE_NO_PROFILE) {
 		scsi_set_in_resid_by_actual(cmd, 0);
-		sense_data_build(cmd, NOT_READY, ASC_MEDIUM_NOT_PRESENT);
+		bs_sense_data_build(cmd, NOT_READY, ASC_MEDIUM_NOT_PRESENT);
 		return SAM_STAT_CHECK_CONDITION;
 	}
 
@@ -78,8 +79,8 @@ static int mmc_rw(int host_no, struct scsi_cmd *cmd)
 		case WRITE_12:
 		case WRITE_16:
 			scsi_set_in_resid_by_actual(cmd, 0);
-			sense_data_build(cmd, ILLEGAL_REQUEST,
-					 ASC_INCOMPATIBLE_FORMAT);
+			bs_sense_data_build(cmd, ILLEGAL_REQUEST,
+					    ASC_INCOMPATIBLE_FORMAT);
 			return SAM_STAT_CHECK_CONDITION;
 		}
 		break;
@@ -90,8 +91,8 @@ static int mmc_rw(int host_no, struct scsi_cmd *cmd)
 		case READ_12:
 		case READ_16:
 			scsi_set_in_resid_by_actual(cmd, 0);
-			sense_data_build(cmd, ILLEGAL_REQUEST,
-					 ASC_LBA_OUT_OF_RANGE);
+			bs_sense_data_build(cmd, ILLEGAL_REQUEST,
+					    ASC_LBA_OUT_OF_RANGE);
 			return SAM_STAT_CHECK_CONDITION;
 		}
 		break;
@@ -115,7 +116,8 @@ static int mmc_rw(int host_no, struct scsi_cmd *cmd)
 		else
 			scsi_set_in_resid_by_actual(cmd, 0);
 
-		sense_data_build(cmd, ILLEGAL_REQUEST, ASC_LUN_NOT_SUPPORTED);
+		bs_sense_data_build(cmd, ILLEGAL_REQUEST,
+				    ASC_LUN_NOT_SUPPORTED);
 		return SAM_STAT_CHECK_CONDITION;
 	} else {
 		if ((mmc->current_profile == PROFILE_DVD_PLUS_R) &&
@@ -136,7 +138,7 @@ static int mmc_read_capacity(int host_no, struct scsi_cmd *cmd)
 
 	if (mmc->current_profile == PROFILE_NO_PROFILE) {
 		scsi_set_in_resid_by_actual(cmd, 0);
-		sense_data_build(cmd, NOT_READY, ASC_MEDIUM_NOT_PRESENT);
+		bs_sense_data_build(cmd, NOT_READY, ASC_MEDIUM_NOT_PRESENT);
 		return SAM_STAT_CHECK_CONDITION;
 	}
 
@@ -168,14 +170,14 @@ static int mmc_read_toc(int host_no, struct scsi_cmd *cmd)
 
 	if (!cmd->dev->attrs.online) {
 		scsi_set_in_resid_by_actual(cmd, 0);
-		sense_data_build(cmd, NOT_READY, ASC_MEDIUM_NOT_PRESENT);
+		bs_sense_data_build(cmd, NOT_READY, ASC_MEDIUM_NOT_PRESENT);
 		return SAM_STAT_CHECK_CONDITION;
 	}
 
 	if (mmc->current_profile == PROFILE_NO_PROFILE) {
 		/* a blank disk has no tracks */
 		scsi_set_in_resid_by_actual(cmd, 0);
-		sense_data_build(cmd, NOT_READY, ASC_INVALID_FIELD_IN_CDB);
+		bs_sense_data_build(cmd, NOT_READY, ASC_INVALID_FIELD_IN_CDB);
 		return SAM_STAT_CHECK_CONDITION;
 	}
 
@@ -198,8 +200,8 @@ static int mmc_read_toc(int host_no, struct scsi_cmd *cmd)
 			   track 1.
 			*/
 			scsi_set_in_resid_by_actual(cmd, 0);
-			sense_data_build(cmd, NOT_READY,
-					 ASC_INVALID_FIELD_IN_CDB);
+			bs_sense_data_build(cmd, NOT_READY,
+					    ASC_INVALID_FIELD_IN_CDB);
 			return SAM_STAT_CHECK_CONDITION;
 		}
 
@@ -270,7 +272,7 @@ static int mmc_read_toc(int host_no, struct scsi_cmd *cmd)
 		eprintf("read_toc: format %x not implemented\n", toc_format);
 
 		scsi_set_in_resid_by_actual(cmd, 0);
-		sense_data_build(cmd, NOT_READY, ASC_INVALID_FIELD_IN_CDB);
+		bs_sense_data_build(cmd, NOT_READY, ASC_INVALID_FIELD_IN_CDB);
 		return SAM_STAT_CHECK_CONDITION;
 	}
 
@@ -299,7 +301,7 @@ static int mmc_read_disc_information(int host_no, struct scsi_cmd *cmd)
 
 	if (mmc->current_profile == PROFILE_NO_PROFILE) {
 		scsi_set_in_resid_by_actual(cmd, 0);
-		sense_data_build(cmd, NOT_READY, ASC_MEDIUM_NOT_PRESENT);
+		bs_sense_data_build(cmd, NOT_READY, ASC_MEDIUM_NOT_PRESENT);
 		return SAM_STAT_CHECK_CONDITION;
 	}
 
@@ -451,7 +453,7 @@ static int mmc_read_disc_information(int host_no, struct scsi_cmd *cmd)
 	default:
 		/* we do not understand/support this command for this profile */
 		scsi_set_in_resid_by_actual(cmd, 0);
-		sense_data_build(cmd, NOT_READY, ASC_INVALID_FIELD_IN_CDB);
+		bs_sense_data_build(cmd, NOT_READY, ASC_INVALID_FIELD_IN_CDB);
 		return SAM_STAT_CHECK_CONDITION;
 	}
 
@@ -1165,7 +1167,7 @@ static unsigned char *track_type_lba(struct scsi_cmd *cmd, unsigned char *data,
 
 	/* we do not understand/support this profile */
 	scsi_set_in_resid_by_actual(cmd, 0);
-	sense_data_build(cmd, NOT_READY, ASC_INVALID_FIELD_IN_CDB);
+	bs_sense_data_build(cmd, NOT_READY, ASC_INVALID_FIELD_IN_CDB);
 	return NULL;
 }
 
@@ -1179,8 +1181,8 @@ static unsigned char *track_type_track(struct scsi_cmd *cmd,
 	case PROFILE_DVD_PLUS_R:
 		if (!lba) {
 			scsi_set_in_resid_by_actual(cmd, 0);
-			sense_data_build(cmd, NOT_READY,
-					 ASC_INVALID_FIELD_IN_CDB);
+			bs_sense_data_build(cmd, NOT_READY,
+					    ASC_INVALID_FIELD_IN_CDB);
 			return NULL;
 		}
 
@@ -1258,8 +1260,8 @@ static unsigned char *track_type_track(struct scsi_cmd *cmd,
 		/* we only have one track */
 		if (lba != 1) {
 			scsi_set_in_resid_by_actual(cmd, 0);
-			sense_data_build(cmd, NOT_READY,
-					 ASC_INVALID_FIELD_IN_CDB);
+			bs_sense_data_build(cmd, NOT_READY,
+					    ASC_INVALID_FIELD_IN_CDB);
 			return NULL;
 		}
 
@@ -1333,7 +1335,7 @@ static unsigned char *track_type_track(struct scsi_cmd *cmd,
 
 	/* we do not understand/support this profile */
 	scsi_set_in_resid_by_actual(cmd, 0);
-	sense_data_build(cmd, NOT_READY, ASC_INVALID_FIELD_IN_CDB);
+	bs_sense_data_build(cmd, NOT_READY, ASC_INVALID_FIELD_IN_CDB);
 	return NULL;
 }
 
@@ -1363,7 +1365,7 @@ static int mmc_read_track_information(int host_no, struct scsi_cmd *cmd)
 
 	if (mmc->current_profile == PROFILE_NO_PROFILE) {
 		scsi_set_in_resid_by_actual(cmd, 0);
-		sense_data_build(cmd, NOT_READY, ASC_MEDIUM_NOT_PRESENT);
+		bs_sense_data_build(cmd, NOT_READY, ASC_MEDIUM_NOT_PRESENT);
 		return SAM_STAT_CHECK_CONDITION;
 	}
 
@@ -1398,7 +1400,7 @@ static int mmc_read_track_information(int host_no, struct scsi_cmd *cmd)
 
 	/* we do not understand this track type */
 	scsi_set_in_resid_by_actual(cmd, 0);
-	sense_data_build(cmd, NOT_READY, ASC_INVALID_FIELD_IN_CDB);
+	bs_sense_data_build(cmd, NOT_READY, ASC_INVALID_FIELD_IN_CDB);
 	return SAM_STAT_CHECK_CONDITION;
 }
 
@@ -1415,11 +1417,12 @@ static int mmc_read_buffer_capacity(int host_no, struct scsi_cmd *cmd)
 	switch (mmc->current_profile) {
 	case PROFILE_NO_PROFILE:
 		scsi_set_in_resid_by_actual(cmd, 0);
-		sense_data_build(cmd, NOT_READY, ASC_MEDIUM_NOT_PRESENT);
+		bs_sense_data_build(cmd, NOT_READY, ASC_MEDIUM_NOT_PRESENT);
 		return SAM_STAT_CHECK_CONDITION;
 	case PROFILE_DVD_ROM:
 		scsi_set_in_resid_by_actual(cmd, 0);
-		sense_data_build(cmd, ILLEGAL_REQUEST, ASC_IMCOMPATIBLE_FORMAT);
+		bs_sense_data_build(cmd, ILLEGAL_REQUEST,
+				    ASC_IMCOMPATIBLE_FORMAT);
 		return SAM_STAT_CHECK_CONDITION;
 	case PROFILE_DVD_PLUS_R:
 		/* data length */
@@ -1453,7 +1456,7 @@ static int mmc_read_buffer_capacity(int host_no, struct scsi_cmd *cmd)
 	}
 
 	scsi_set_in_resid_by_actual(cmd, 0);
-	sense_data_build(cmd, MEDIUM_ERROR, ASC_INVALID_FIELD_IN_CDB);
+	bs_sense_data_build(cmd, MEDIUM_ERROR, ASC_INVALID_FIELD_IN_CDB);
 	return SAM_STAT_CHECK_CONDITION;
 }
 
@@ -1463,7 +1466,7 @@ static int mmc_synchronize_cache(int host_no, struct scsi_cmd *cmd)
 
 	if (mmc->current_profile == PROFILE_NO_PROFILE) {
 		scsi_set_in_resid_by_actual(cmd, 0);
-		sense_data_build(cmd, NOT_READY, ASC_MEDIUM_NOT_PRESENT);
+		bs_sense_data_build(cmd, NOT_READY, ASC_MEDIUM_NOT_PRESENT);
 		return SAM_STAT_CHECK_CONDITION;
 	}
 
@@ -1621,7 +1624,7 @@ static unsigned char *perf_type_write_speed(struct scsi_cmd *cmd,
 
 	/* we do not understand/support this command */
 	scsi_set_in_resid_by_actual(cmd, 0);
-	sense_data_build(cmd, NOT_READY, ASC_INVALID_FIELD_IN_CDB);
+	bs_sense_data_build(cmd, NOT_READY, ASC_INVALID_FIELD_IN_CDB);
 	return NULL;
 }
 
@@ -1643,7 +1646,7 @@ static unsigned char *perf_type_perf_data(struct scsi_cmd *cmd,
 	/* all other values for tolerance are reserved */
 	if (tolerance != 0x02) {
 		scsi_set_in_resid_by_actual(cmd, 0);
-		sense_data_build(cmd, NOT_READY, ASC_INVALID_FIELD_IN_CDB);
+		bs_sense_data_build(cmd, NOT_READY, ASC_INVALID_FIELD_IN_CDB);
 		return NULL;
 	}
 
@@ -1661,7 +1664,7 @@ static unsigned char *perf_type_perf_data(struct scsi_cmd *cmd,
 	case 3:
 		/* reserved */
 		scsi_set_in_resid_by_actual(cmd, 0);
-		sense_data_build(cmd, NOT_READY, ASC_INVALID_FIELD_IN_CDB);
+		bs_sense_data_build(cmd, NOT_READY, ASC_INVALID_FIELD_IN_CDB);
 		return NULL;
 	}
 
@@ -1769,7 +1772,7 @@ static int mmc_get_performance(int host_no, struct scsi_cmd *cmd)
 	}
 	/* we do not understand/support this command */
 	scsi_set_in_resid_by_actual(cmd, 0);
-	sense_data_build(cmd, NOT_READY, ASC_INVALID_FIELD_IN_CDB);
+	bs_sense_data_build(cmd, NOT_READY, ASC_INVALID_FIELD_IN_CDB);
 	return SAM_STAT_CHECK_CONDITION;
 }
 
@@ -1802,7 +1805,7 @@ static unsigned char *dvd_format_phys_info(struct scsi_cmd *cmd,
 	if (layer) {
 		/* we only support single layer disks */
 		scsi_set_in_resid_by_actual(cmd, 0);
-		sense_data_build(cmd, NOT_READY, ASC_INVALID_FIELD_IN_CDB);
+		bs_sense_data_build(cmd, NOT_READY, ASC_INVALID_FIELD_IN_CDB);
 		return NULL;
 	}
 
@@ -1928,7 +1931,7 @@ static unsigned char *dvd_format_phys_info(struct scsi_cmd *cmd,
 		break;
 	default:
 		scsi_set_in_resid_by_actual(cmd, 0);
-		sense_data_build(cmd, NOT_READY, ASC_MEDIUM_NOT_PRESENT);
+		bs_sense_data_build(cmd, NOT_READY, ASC_MEDIUM_NOT_PRESENT);
 		return NULL;
 	}
 
@@ -1960,7 +1963,7 @@ static unsigned char *dvd_format_adip_info(struct scsi_cmd *cmd,
 		break;
 	default:
 		scsi_set_in_resid_by_actual(cmd, 0);
-		sense_data_build(cmd, NOT_READY, ASC_MEDIUM_NOT_PRESENT);
+		bs_sense_data_build(cmd, NOT_READY, ASC_MEDIUM_NOT_PRESENT);
 		return NULL;
 	}
 
@@ -2050,7 +2053,7 @@ static unsigned char *dvd_format_copyright_info(struct scsi_cmd *cmd,
 	if (layer) {
 		/* we only support single layer disks */
 		scsi_set_in_resid_by_actual(cmd, 0);
-		sense_data_build(cmd, NOT_READY, ASC_INVALID_FIELD_IN_CDB);
+		bs_sense_data_build(cmd, NOT_READY, ASC_INVALID_FIELD_IN_CDB);
 		return NULL;
 	}
 
@@ -2118,7 +2121,7 @@ static int mmc_read_dvd_structure(int host_no, struct scsi_cmd *cmd)
 
 	if (mmc->current_profile == PROFILE_NO_PROFILE) {
 		scsi_set_in_resid_by_actual(cmd, 0);
-		sense_data_build(cmd, NOT_READY, ASC_MEDIUM_NOT_PRESENT);
+		bs_sense_data_build(cmd, NOT_READY, ASC_MEDIUM_NOT_PRESENT);
 		return SAM_STAT_CHECK_CONDITION;
 	}
 
@@ -2155,7 +2158,7 @@ static int mmc_read_dvd_structure(int host_no, struct scsi_cmd *cmd)
 
 	/* we do not understand this format */
 	scsi_set_in_resid_by_actual(cmd, 0);
-	sense_data_build(cmd, NOT_READY, ASC_INVALID_FIELD_IN_CDB);
+	bs_sense_data_build(cmd, NOT_READY, ASC_INVALID_FIELD_IN_CDB);
 	return SAM_STAT_CHECK_CONDITION;
 }
 
diff --git a/usr/sbc.c b/usr/sbc.c
index c4f012c..24625fd 100644
--- a/usr/sbc.c
+++ b/usr/sbc.c
@@ -44,6 +44,7 @@
 #include "scsi.h"
 #include "spc.h"
 #include "tgtadm_error.h"
+#include "bs.h"
 
 #define DEFAULT_BLK_SHIFT 9
 
@@ -76,7 +77,7 @@ static int sbc_mode_page_update(struct scsi_cmd *cmd, uint8_t *data, int *change
 	if (data[0] & 0x40)
 		subpcode = data[1];
 
-	pg = find_mode_page(cmd->dev, pcode, subpcode);
+	pg = bs_find_mode_page(cmd->dev, pcode, subpcode);
 	if (pg == NULL)
 		return 1;
 
@@ -181,7 +182,7 @@ static int sbc_format_unit(int host_no, struct scsi_cmd *cmd)
 	return SAM_STAT_GOOD;
 
 sense:
-	sense_data_build(cmd, key, asc);
+	bs_sense_data_build(cmd, key, asc);
 	return SAM_STAT_CHECK_CONDITION;
 }
 
@@ -235,7 +236,7 @@ sense:
 	scsi_set_in_resid_by_actual(cmd, 0);
 	scsi_set_out_resid_by_actual(cmd, 0);
 
-	sense_data_build(cmd, key, asc);
+	bs_sense_data_build(cmd, key, asc);
 	return SAM_STAT_CHECK_CONDITION;
 }
 
@@ -395,7 +396,7 @@ sense:
 	scsi_set_in_resid_by_actual(cmd, 0);
 	scsi_set_out_resid_by_actual(cmd, 0);
 
-	sense_data_build(cmd, key, asc);
+	bs_sense_data_build(cmd, key, asc);
 	return SAM_STAT_CHECK_CONDITION;
 }
 
@@ -453,7 +454,7 @@ overflow:
 	return SAM_STAT_GOOD;
 sense:
 	scsi_set_in_resid_by_actual(cmd, 0);
-	sense_data_build(cmd, key, asc);
+	bs_sense_data_build(cmd, key, asc);
 	return SAM_STAT_CHECK_CONDITION;
 }
 
@@ -519,7 +520,7 @@ static int sbc_verify(int host_no, struct scsi_cmd *cmd)
 
 sense:
 	scsi_set_in_resid_by_actual(cmd, 0);
-	sense_data_build(cmd, key, asc);
+	bs_sense_data_build(cmd, key, asc);
 	return SAM_STAT_CHECK_CONDITION;
 }
 
@@ -566,7 +567,7 @@ static int sbc_readcapacity16(int host_no, struct scsi_cmd *cmd)
 	return SAM_STAT_GOOD;
 
 sense:
-	sense_data_build(cmd, key, asc);
+	bs_sense_data_build(cmd, key, asc);
 	return SAM_STAT_CHECK_CONDITION;
 }
 
@@ -643,7 +644,7 @@ static int sbc_getlbastatus(int host_no, struct scsi_cmd *cmd)
 	return SAM_STAT_GOOD;
 
 sense:
-	sense_data_build(cmd, key, asc);
+	bs_sense_data_build(cmd, key, asc);
 	return SAM_STAT_CHECK_CONDITION;
 }
 
@@ -667,7 +668,7 @@ static int sbc_service_action(int host_no, struct scsi_cmd *cmd)
 
 	if (!service_action) {
 		scsi_set_in_resid_by_actual(cmd, 0);
-		sense_data_build(cmd, ILLEGAL_REQUEST,
+		bs_sense_data_build(cmd, ILLEGAL_REQUEST,
 				ASC_INVALID_FIELD_IN_CDB);
 		return SAM_STAT_CHECK_CONDITION;
 	}
@@ -710,7 +711,7 @@ static int sbc_sync_cache(int host_no, struct scsi_cmd *cmd)
 	}
 
 sense:
-	sense_data_build(cmd, key, asc);
+	bs_sense_data_build(cmd, key, asc);
 	return SAM_STAT_CHECK_CONDITION;
 }
 
diff --git a/usr/scsi.c b/usr/scsi.c
index 2636a5c..5606b5b 100644
--- a/usr/scsi.c
+++ b/usr/scsi.c
@@ -37,6 +37,7 @@
 #include "driver.h"
 #include "scsi.h"
 #include "spc.h"
+#include "bs.h"
 
 static unsigned char scsi_command_size[8] = {6, 10, 10, 12, 16, 12, 10, 10};
 
@@ -275,28 +276,6 @@ const unsigned char *get_scsi_cdb_usage_data(unsigned char op, unsigned char sa)
 	return usage;
 }
 
-void sense_data_build(struct scsi_cmd *cmd, uint8_t key, uint16_t asc)
-{
-
-	if (cmd->dev->attrs.sense_format) {
-		/* descriptor format */
-		cmd->sense_buffer[0] = 0x72;  /* current, not deferred */
-		cmd->sense_buffer[1] = key;
-		cmd->sense_buffer[2] = (asc >> 8) & 0xff;
-		cmd->sense_buffer[3] = asc & 0xff;
-		cmd->sense_len = 8;
-	} else {
-		/* fixed format */
-		int len = 0xa;
-		cmd->sense_buffer[0] = 0x70;  /* current, not deferred */
-		cmd->sense_buffer[2] = key;
-		cmd->sense_buffer[7] = len;
-		cmd->sense_buffer[12] = (asc >> 8) & 0xff;
-		cmd->sense_buffer[13] = asc & 0xff;
-		cmd->sense_len = len + 8;
-	}
-}
-
 #define        TGT_INVALID_DEV_ID      ~0ULL
 
 static uint64_t __scsi_get_devid(uint8_t *p)
@@ -448,7 +427,7 @@ int scsi_cmd_perform(int host_no, struct scsi_cmd *cmd)
 		 * We don't support ACA. SAM-3 and SAM-4 say that a
 		 * logical unit MAY support ACA.
 		 */
-		sense_data_build(cmd,
+		bs_sense_data_build(cmd,
 				 ILLEGAL_REQUEST, ASC_INVALID_FIELD_IN_CDB);
 		return SAM_STAT_CHECK_CONDITION;
 	}
@@ -458,10 +437,12 @@ int scsi_cmd_perform(int host_no, struct scsi_cmd *cmd)
 		case INQUIRY:
 			break;
 		case REQUEST_SENSE:
-			sense_data_build(cmd, ILLEGAL_REQUEST, ASC_LUN_NOT_SUPPORTED);
+			bs_sense_data_build(cmd, ILLEGAL_REQUEST,
+					    ASC_LUN_NOT_SUPPORTED);
 			return SAM_STAT_GOOD;
 		default:
-			sense_data_build(cmd, ILLEGAL_REQUEST, ASC_LUN_NOT_SUPPORTED);
+			bs_sense_data_build(cmd, ILLEGAL_REQUEST,
+					    ASC_LUN_NOT_SUPPORTED);
 			return SAM_STAT_CHECK_CONDITION;
 		}
 	}
diff --git a/usr/smc.c b/usr/smc.c
index 910b532..ca5e054 100644
--- a/usr/smc.c
+++ b/usr/smc.c
@@ -47,6 +47,7 @@
 #include "parser.h"
 #include "smc.h"
 #include "media.h"
+#include "bs.h"
 
 static int check_slot_removable(struct slot *s)
 {
@@ -396,7 +397,7 @@ sense:
 	if (data)
 		free(data);
 	scsi_set_in_resid_by_actual(cmd, 0);
-	sense_data_build(cmd, key, asc);
+	bs_sense_data_build(cmd, key, asc);
 	return SAM_STAT_CHECK_CONDITION;
 }
 
@@ -487,7 +488,7 @@ static int smc_move_medium(int host_no, struct scsi_cmd *cmd)
 
 sense:
 	scsi_set_in_resid_by_actual(cmd, 0);
-	sense_data_build(cmd, key, asc);
+	bs_sense_data_build(cmd, key, asc);
 	return SAM_STAT_CHECK_CONDITION;
 }
 
@@ -627,7 +628,7 @@ static tgtadm_err add_slt(struct scsi_lu *lu, struct tmp_param *tmp)
 	int qnty_save;
 	int i;
 
-	pg = find_mode_page(lu, 0x1d, 0);
+	pg = bs_find_mode_page(lu, 0x1d, 0);
 	if (!pg) {
 		dprintf("Failed to find Element Address Assignment mode pg\n");
 		return TGTADM_UNKNOWN_ERR;
@@ -694,7 +695,7 @@ static tgtadm_err config_slot(struct scsi_lu *lu, struct tmp_param *tmp)
 	switch(tmp->element_type) {
 	case ELEMENT_MEDIUM_TRANSPORT:
 		/* If medium has more than one side, set the 'rotate' bit */
-		m = find_mode_page(lu, 0x1e, 0);
+		m = bs_find_mode_page(lu, 0x1e, 0);
 		if (m) {
 			m->mode_data[0] = (tmp->sides > 1) ? 1 : 0;
 			adm_err = TGTADM_SUCCESS;
diff --git a/usr/spc.c b/usr/spc.c
index 15077ca..c8dc937 100644
--- a/usr/spc.c
+++ b/usr/spc.c
@@ -35,6 +35,7 @@
 #include "tgtadm_error.h"
 #include "scsi.h"
 #include "spc.h"
+#include "bs.h"
 
 #define INQUIRY_EVPD	0x01
 
@@ -317,7 +318,7 @@ int spc_inquiry(int host_no, struct scsi_cmd *cmd)
 	return SAM_STAT_GOOD;
 sense:
 	scsi_set_in_resid_by_actual(cmd, 0);
-	sense_data_build(cmd, key, asc);
+	bs_sense_data_build(cmd, key, asc);
 	return SAM_STAT_CHECK_CONDITION;
 }
 
@@ -364,7 +365,7 @@ int spc_report_luns(int host_no, struct scsi_cmd *cmd)
 	return SAM_STAT_GOOD;
 sense:
 	scsi_set_in_resid_by_actual(cmd, 0);
-	sense_data_build(cmd, key, asc);
+	bs_sense_data_build(cmd, key, asc);
 	return SAM_STAT_CHECK_CONDITION;
 }
 
@@ -389,11 +390,11 @@ int spc_start_stop(int host_no, struct scsi_cmd *cmd)
 		if (lu_prevent_removal(cmd->dev)) {
 			if (cmd->dev->attrs.online) {
 				/*  online == media is present */
-				sense_data_build(cmd, ILLEGAL_REQUEST,
+				bs_sense_data_build(cmd, ILLEGAL_REQUEST,
 					ASC_MEDIUM_REMOVAL_PREVENTED);
 			} else {
 				/* !online == media is not present */
-				sense_data_build(cmd, NOT_READY,
+				bs_sense_data_build(cmd, NOT_READY,
 				ASC_MEDIUM_REMOVAL_PREVENTED);
 			}
 			return SAM_STAT_CHECK_CONDITION;
@@ -415,9 +416,9 @@ int spc_test_unit(int host_no, struct scsi_cmd *cmd)
 	if (cmd->dev->attrs.online)
 		return SAM_STAT_GOOD;
 	if (cmd->dev->attrs.removable)
-		sense_data_build(cmd, NOT_READY, ASC_MEDIUM_NOT_PRESENT);
+		bs_sense_data_build(cmd, NOT_READY, ASC_MEDIUM_NOT_PRESENT);
 	else
-		sense_data_build(cmd, NOT_READY, ASC_BECOMING_READY);
+		bs_sense_data_build(cmd, NOT_READY, ASC_BECOMING_READY);
 
 	return SAM_STAT_CHECK_CONDITION;
 }
@@ -506,7 +507,7 @@ int spc_mode_select(int host_no, struct scsi_cmd *cmd,
 
 		pcode = data[offset] & 0x3f;
 
-		pg = find_mode_page(cmd->dev, pcode, 0);
+		pg = bs_find_mode_page(cmd->dev, pcode, 0);
 		if (!pg)
 			goto sense;
 
@@ -547,26 +548,14 @@ int spc_mode_select(int host_no, struct scsi_cmd *cmd,
 	return SAM_STAT_GOOD;
 sense:
 	scsi_set_in_resid_by_actual(cmd, 0);
-	sense_data_build(cmd, key, asc);
+	bs_sense_data_build(cmd, key, asc);
 	return SAM_STAT_CHECK_CONDITION;
 }
 
-struct mode_pg *find_mode_page(struct scsi_lu *lu, uint8_t pcode,
-			       uint8_t subpcode)
-{
-	struct mode_pg *pg;
-
-	list_for_each_entry(pg, &lu->mode_pages, mode_pg_siblings) {
-		if (pg->pcode == pcode && pg->subpcode == subpcode)
-			return pg;
-	}
-	return NULL;
-}
-
 int set_mode_page_changeable_mask(struct scsi_lu *lu, uint8_t pcode,
 				  uint8_t subpcode, uint8_t *mask)
 {
-	struct mode_pg *pg = find_mode_page(lu, pcode, subpcode);
+	struct mode_pg *pg = bs_find_mode_page(lu, pcode, subpcode);
 
 	if (pg) {
 		memcpy(pg->mode_data + pg->pcode_size, mask, pg->pcode_size);
@@ -693,7 +682,7 @@ int spc_mode_sense(int host_no, struct scsi_cmd *cmd)
 						      pctrl);
 		}
 	} else {
-		pg = find_mode_page(cmd->dev, pcode, subpcode);
+		pg = bs_find_mode_page(cmd->dev, pcode, subpcode);
 		if (!pg)
 			goto sense;
 		actual_len += build_mode_page(data + actual_len, pg,
@@ -717,7 +706,7 @@ int spc_mode_sense(int host_no, struct scsi_cmd *cmd)
 	return SAM_STAT_GOOD;
 sense:
 	scsi_set_in_resid_by_actual(cmd, 0);
-	sense_data_build(cmd, key, asc);
+	bs_sense_data_build(cmd, key, asc);
 	return SAM_STAT_CHECK_CONDITION;
 }
 
@@ -909,7 +898,7 @@ int spc_report_supported_opcodes(int host_no, struct scsi_cmd *cmd)
 
 sense:
 	scsi_set_in_resid_by_actual(cmd, 0);
-	sense_data_build(cmd, key, asc);
+	bs_sense_data_build(cmd, key, asc);
 	return SAM_STAT_CHECK_CONDITION;
 }
 
@@ -941,7 +930,7 @@ int spc_send_diagnostics(int host_no, struct scsi_cmd *cmd)
 	return SAM_STAT_GOOD;
 sense:
 	scsi_set_in_resid_by_actual(cmd, 0);
-	sense_data_build(cmd, key, asc);
+	bs_sense_data_build(cmd, key, asc);
 	return SAM_STAT_CHECK_CONDITION;
 }
 
@@ -962,7 +951,7 @@ int spc_service_action(int host_no, struct scsi_cmd *cmd)
 
 	if (!service_action) {
 		scsi_set_in_resid_by_actual(cmd, 0);
-		sense_data_build(cmd, ILLEGAL_REQUEST,
+		bs_sense_data_build(cmd, ILLEGAL_REQUEST,
 				ASC_INVALID_FIELD_IN_CDB);
 		return SAM_STAT_CHECK_CONDITION;
 	}
@@ -1021,7 +1010,7 @@ static int spc_pr_read_keys(int host_no, struct scsi_cmd *cmd)
 	return SAM_STAT_GOOD;
 sense:
 	scsi_set_in_resid_by_actual(cmd, 0);
-	sense_data_build(cmd, key, asc);
+	bs_sense_data_build(cmd, key, asc);
 	return SAM_STAT_CHECK_CONDITION;
 }
 
@@ -1071,7 +1060,7 @@ static int spc_pr_read_reservation(int host_no, struct scsi_cmd *cmd)
 	return SAM_STAT_GOOD;
 sense:
 	scsi_set_in_resid_by_actual(cmd, 0);
-	sense_data_build(cmd, key, asc);
+	bs_sense_data_build(cmd, key, asc);
 	return SAM_STAT_CHECK_CONDITION;
 }
 
@@ -1113,7 +1102,7 @@ static int spc_pr_report_capabilities(int host_no, struct scsi_cmd *cmd)
 	return SAM_STAT_GOOD;
 sense:
 	scsi_set_in_resid_by_actual(cmd, 0);
-	sense_data_build(cmd, key, asc);
+	bs_sense_data_build(cmd, key, asc);
 	return SAM_STAT_CHECK_CONDITION;
 }
 
@@ -1304,7 +1293,7 @@ static int spc_pr_register(int host_no, struct scsi_cmd *cmd)
 	return SAM_STAT_GOOD;
 sense:
 	scsi_set_in_resid_by_actual(cmd, 0);
-	sense_data_build(cmd, key, asc);
+	bs_sense_data_build(cmd, key, asc);
 	return SAM_STAT_CHECK_CONDITION;
 }
 
@@ -1361,7 +1350,7 @@ static int spc_pr_reserve(int host_no, struct scsi_cmd *cmd)
 	return SAM_STAT_GOOD;
 sense:
 	scsi_set_in_resid_by_actual(cmd, 0);
-	sense_data_build(cmd, key, asc);
+	bs_sense_data_build(cmd, key, asc);
 	return SAM_STAT_CHECK_CONDITION;
 }
 
@@ -1432,7 +1421,7 @@ static int spc_pr_release(int host_no, struct scsi_cmd *cmd)
 	return SAM_STAT_GOOD;
 sense:
 	scsi_set_in_resid_by_actual(cmd, 0);
-	sense_data_build(cmd, key, asc);
+	bs_sense_data_build(cmd, key, asc);
 	return SAM_STAT_CHECK_CONDITION;
 }
 
@@ -1481,7 +1470,7 @@ static int spc_pr_clear(int host_no, struct scsi_cmd *cmd)
 	return SAM_STAT_GOOD;
 sense:
 	scsi_set_in_resid_by_actual(cmd, 0);
-	sense_data_build(cmd, key, asc);
+	bs_sense_data_build(cmd, key, asc);
 	return SAM_STAT_CHECK_CONDITION;
 }
 
@@ -1571,7 +1560,7 @@ static int spc_pr_preempt(int host_no, struct scsi_cmd *cmd)
 	return SAM_STAT_GOOD;
 sense:
 	scsi_set_in_resid_by_actual(cmd, 0);
-	sense_data_build(cmd, key, asc);
+	bs_sense_data_build(cmd, key, asc);
 	return SAM_STAT_CHECK_CONDITION;
 }
 
@@ -1654,7 +1643,7 @@ found:
 	return SAM_STAT_GOOD;
 sense:
 	scsi_set_in_resid_by_actual(cmd, 0);
-	sense_data_build(cmd, key, asc);
+	bs_sense_data_build(cmd, key, asc);
 	return SAM_STAT_CHECK_CONDITION;
 }
 
@@ -1715,7 +1704,7 @@ int spc_request_sense(int host_no, struct scsi_cmd *cmd)
 	alloc_len = (uint32_t)cmd->scb[4];
 	alloc_len = min_t(uint32_t, alloc_len, scsi_get_in_length(cmd));
 
-	sense_data_build(cmd, NO_SENSE, NO_ADDITIONAL_SENSE);
+	bs_sense_data_build(cmd, NO_SENSE, NO_ADDITIONAL_SENSE);
 
 	actual_len = spc_memcpy(scsi_get_in_buffer(cmd), &alloc_len,
 				cmd->sense_buffer, cmd->sense_len);
@@ -1780,7 +1769,7 @@ tgtadm_err add_mode_page(struct scsi_lu *lu, char *p)
 		case 2:
 			size = strtol(p, NULL, 0);
 
-			pg = find_mode_page(lu, pcode, subpcode);
+			pg = bs_find_mode_page(lu, pcode, subpcode);
 			if (pg) {
 				list_del(&pg->mode_pg_siblings);
 				free(pg);
@@ -1857,7 +1846,7 @@ int spc_illegal_op(int host_no, struct scsi_cmd *cmd)
 {
 	dump_cdb(cmd);
 	scsi_set_in_resid_by_actual(cmd, 0);
-	sense_data_build(cmd, ILLEGAL_REQUEST, ASC_INVALID_OP_CODE);
+	bs_sense_data_build(cmd, ILLEGAL_REQUEST, ASC_INVALID_OP_CODE);
 	return SAM_STAT_CHECK_CONDITION;
 }
 
diff --git a/usr/spc.h b/usr/spc.h
index 0c537e1..dd84e22 100644
--- a/usr/spc.h
+++ b/usr/spc.h
@@ -24,8 +24,6 @@ extern int spc_mode_sense(int host_no, struct scsi_cmd *cmd);
 extern tgtadm_err add_mode_page(struct scsi_lu *lu, char *params);
 extern int set_mode_page_changeable_mask(struct scsi_lu *lu, uint8_t pcode,
 					 uint8_t subpcode, uint8_t *mask);
-extern struct mode_pg *find_mode_page(struct scsi_lu *lu,
-				      uint8_t pcode, uint8_t subpcode);
 extern int spc_mode_select(int host_no, struct scsi_cmd *cmd,
 			   int (*update)(struct scsi_cmd *, uint8_t *, int *));
 extern struct vpd *alloc_vpd(uint16_t size);
diff --git a/usr/ssc.c b/usr/ssc.c
index 60c6926..b861f6a 100644
--- a/usr/ssc.c
+++ b/usr/ssc.c
@@ -34,6 +34,7 @@
 #include "spc.h"
 #include "ssc.h"
 #include "tgtadm_error.h"
+#include "bs.h"
 
 #define GRANULARITY	9
 
@@ -127,7 +128,7 @@ sense:
 	scsi_set_in_resid_by_actual(cmd, 0);
 	scsi_set_out_resid_by_actual(cmd, 0);
 
-	sense_data_build(cmd, key, asc);
+	bs_sense_data_build(cmd, key, asc);
 	return SAM_STAT_CHECK_CONDITION;
 }
 
diff --git a/usr/target.c b/usr/target.c
index b1729b3..524a075 100644
--- a/usr/target.c
+++ b/usr/target.c
@@ -1165,30 +1165,6 @@ int target_cmd_perform(int tid, struct scsi_cmd *cmd)
 	return 0;
 }
 
-/*
- * Used by bs_sg for CDB passthrough to STGT LUNs
- */
-int target_cmd_perform_passthrough(int tid, struct scsi_cmd *cmd)
-{
-	int result;
-
-	dprintf("%p %x %" PRIx64 " PT\n", cmd, cmd->scb[0], cmd->dev_id);
-
-	result = cmd->dev->dev_type_template.cmd_passthrough(tid, cmd);
-
-	dprintf("%" PRIx64 " %x %p %p %" PRIu64 " %u %u %d %d\n",
-		cmd->tag, cmd->scb[0], scsi_get_out_buffer(cmd),
-		scsi_get_in_buffer(cmd), cmd->offset,
-		scsi_get_out_length(cmd), scsi_get_in_length(cmd),
-		result, cmd_async(cmd));
-
-	set_cmd_processed(cmd);
-	if (!cmd_async(cmd))
-		target_cmd_io_done(cmd, result);
-
-	return 0;
-}
-
 void target_cmd_io_done(struct scsi_cmd *cmd, int result)
 {
 	enum data_direction cmd_dir = scsi_get_data_dir(cmd);
@@ -1269,16 +1245,6 @@ static void __cmd_done(struct target *target, struct scsi_cmd *cmd)
 	post_cmd_done(q);
 }
 
-/*
- * Used by struct scsi_lu->cmd_done() for bs_sg (passthrough) completion
- */
-void __cmd_done_passthrough(struct target *target, struct scsi_cmd *cmd)
-{
-	dprintf("%p %p %u %u\n", scsi_get_out_buffer(cmd),
-		scsi_get_in_buffer(cmd), scsi_get_out_length(cmd),
-		scsi_get_in_length(cmd));
-}
-
 void target_cmd_done(struct scsi_cmd *cmd)
 {
 	struct mgmt_req *mreq;
@@ -2411,15 +2377,6 @@ tgtadm_err lld_show(struct concat_buf *b)
 	return TGTADM_SUCCESS;
 }
 
-void update_lbppbe(struct scsi_lu *lu, int blksize)
-{
-	lu->attrs.lbppbe = 0;
-	while (blksize > (1U << lu->blk_shift)) {
-		lu->attrs.lbppbe++;
-		blksize >>= 1;
-	}
-}
-
 int is_system_available(void)
 {
 	return (sys_state == TGT_SYSTEM_READY);
diff --git a/usr/tgtd.c b/usr/tgtd.c
index f985510..46152d2 100644
--- a/usr/tgtd.c
+++ b/usr/tgtd.c
@@ -42,6 +42,7 @@
 #include "driver.h"
 #include "work.h"
 #include "util.h"
+#include "bs.h"
 
 unsigned long pagesize, pageshift;
 
diff --git a/usr/tgtd.h b/usr/tgtd.h
index 484e6e9..0455d65 100644
--- a/usr/tgtd.h
+++ b/usr/tgtd.h
@@ -232,8 +232,7 @@ struct scsi_lu {
 	 */
 	int (*cmd_perform)(int, struct scsi_cmd *);
 	/*
-	 * Used internally for usr/target.c:__cmd_done() and with
-	 * passthrough CMD processing with __cmd_done_passthrough()
+	 * Used internally for usr/target.c:__cmd_done()
 	 */
 	void (*cmd_done)(struct target *, struct scsi_cmd *);
 };
@@ -299,9 +298,7 @@ extern void tgt_remove_sched_event(struct event_data *evt);
 extern int tgt_event_modify(int fd, int events);
 extern int target_cmd_queue(int tid, struct scsi_cmd *cmd);
 extern int target_cmd_perform(int tid, struct scsi_cmd *cmd);
-extern int target_cmd_perform_passthrough(int tid, struct scsi_cmd *cmd);
 extern void target_cmd_done(struct scsi_cmd *cmd);
-extern void __cmd_done_passthrough(struct target *target, struct scsi_cmd *cmd);
 
 extern enum mgmt_req_result target_mgmt_request(int tid, uint64_t itn_id,
 						uint64_t req_id, int function,
@@ -321,7 +318,6 @@ extern int lu_prevent_removal(struct scsi_lu *lu);
 
 extern uint64_t scsi_get_devid(int lid, uint8_t *pdu);
 extern int scsi_cmd_perform(int host_no, struct scsi_cmd *cmd);
-extern void sense_data_build(struct scsi_cmd *cmd, uint8_t key, uint16_t asc);
 extern uint64_t scsi_rw_offset(uint8_t *scb);
 extern uint32_t scsi_rw_count(uint8_t *scb);
 extern int scsi_is_io_opcode(unsigned char op);
@@ -374,8 +370,6 @@ extern int lld_init_one(int lld_index);
 
 extern int setup_param(char *name, int (*parser)(char *));
 
-extern int bs_init(void);
-
 struct event_data {
 	union {
 		event_handler_t handler;
@@ -393,8 +387,6 @@ int call_program(const char *cmd,
 		    void (*callback)(void *data, int result), void *data,
 		    char *output, int op_len, int flags);
 
-void update_lbppbe(struct scsi_lu *lu, int blksize);
-
 struct service_action *
 find_service_action(struct service_action *service_action,
 		    uint32_t action);
diff --git a/usr/util.c b/usr/util.c
index 1500dec..79c4952 100644
--- a/usr/util.c
+++ b/usr/util.c
@@ -19,17 +19,10 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  * 02110-1301 USA
  */
-#include <errno.h>
-#include <fcntl.h>
 #include <inttypes.h>
-#include <unistd.h>
 #include <stdio.h>
 #include <string.h>
 #include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/ioctl.h>
-#include <linux/fs.h>
-#include <sys/sysmacros.h>
 
 #include "log.h"
 #include "util.h"
@@ -82,46 +75,6 @@ int chrdev_open(char *modname, char *devpath, uint8_t minor, int *fd)
 	return 0;
 }
 
-int backed_file_open(char *path, int oflag, uint64_t *size, uint32_t *blksize)
-{
-	int fd, err;
-	struct stat64 st;
-
-	fd = open(path, oflag);
-	if (fd < 0) {
-		eprintf("Could not open %s, %m\n", path);
-		return fd;
-	}
-
-	err = fstat64(fd, &st);
-	if (err < 0) {
-		eprintf("Cannot get stat %d, %m\n", fd);
-		goto close_fd;
-	}
-
-	if (S_ISREG(st.st_mode)) {
-		*size = st.st_size;
-		if (blksize)
-			*blksize = st.st_blksize;
-	} else if (S_ISBLK(st.st_mode)) {
-		err = ioctl(fd, BLKGETSIZE64, size);
-		if (err < 0) {
-			eprintf("Cannot get size, %m\n");
-			goto close_fd;
-		}
-	} else {
-		eprintf("Cannot use this mode %x\n", st.st_mode);
-		err = -EINVAL;
-		goto close_fd;
-	}
-
-	return fd;
-
-close_fd:
-	close(fd);
-	return err;
-}
-
 int set_non_blocking(int fd)
 {
 	int err;
diff --git a/usr/util.h b/usr/util.h
index d01d58b..0601b18 100644
--- a/usr/util.h
+++ b/usr/util.h
@@ -62,8 +62,7 @@
 
 extern int get_blk_shift(unsigned int size);
 extern int chrdev_open(char *modname, char *devpath, uint8_t minor, int *fd);
-extern int backed_file_open(char *path, int oflag, uint64_t *size,
-				uint32_t *blksize);
+
 extern int set_non_blocking(int fd);
 extern int str_to_open_flags(char *buf);
 extern char *open_flags_to_str(char *dest, int flags);
-- 
1.7.3.1

--
To unsubscribe from this list: send the line "unsubscribe stgt" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html



More information about the stgt mailing list