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

Dan Mick dan.mick at inktank.com
Wed Sep 4 17:40:46 CEST 2013


Tomo: are we waiting for anything in particular about this patch?  I'd 
love to see it applied.  Can I help test or verify something?

On 8/27/2013 2:08 PM, ronnie sahlberg wrote:
> 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