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

ronnie sahlberg ronniesahlberg at gmail.com
Tue Aug 27 23:08:38 CEST 2013


ping?

this is version 2 of the patch

On Tue, Aug 20, 2013 at 7:46 PM, Ronnie Sahlberg
<ronniesahlberg at gmail.com> wrote:
> 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