Print this page
NEX-6832 fcsm module's debug level default should be 0 (cstyle fix)
Reviewed by: Rob Gittins <rob.gittins@nexenta.com>
NEX-7503 backport illumos #7307
Reviewed by: Saso Kiselkov <saso.kiselkov@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Steve Peng <steve.peng@nexenta.com>
NEX-7048 COMSTAR MODE_SENSE support is broken
Reviewed by: Rob Gittins <rob.gittins@nexenta.com>
Reviewed by: Steve Peng <steve.peng@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-5428 Backout the 5.0 changes
NEX-2937 Continuous write_same starves all other commands
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
Reviewed by: Steve Peng <steve.peng@nexenta.com>
NEX-4707 memory leak in stmf_sbd`sbd_attach() on successful property lookup
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
Reviewed by: Marcel Telka <marcel.telka@nexenta.com>
NEX-3508 CLONE - Port NEX-2946 Add UNMAP/TRIM functionality to ZFS and illumos
Reviewed by: Josef Sipek <josef.sipek@nexenta.com>
Reviewed by: Alek Pinchuk <alek.pinchuk@nexenta.com>
Conflicts:
    usr/src/uts/common/io/scsi/targets/sd.c
    usr/src/uts/common/sys/scsi/targets/sddef.h
NEX-3111 Comstar does not pass cstyle and hdrchk
        Reviewed by: Jean McCormack <jean.mccormack@nexenta.com>
        Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
        Reviewed by: Tony Nguyen <tony.nguyen@nexenta.com>
NEX-3023 Panics and hangs when using write_same and compare_and_write
Review by: Bayard Bell <bayard.bell@nexenta.com>
Review by: Rick McNeal <rick.mcneal@nexenta.com>
Review by: Jean McCormack <jean.mccormack@nexenta.com>
Approved by: Jean McCormack <jean.mccormack@nexenta.com>
Related bug: NEX-2723 Kernel panic in xfer_completion code for write_same (0x93) and compare_and_write (0x89)
NEX-1965 Page fault at netbios_first_level_name_decode+0xbb
Support simultaneous compare_and_write operations for VAAI
Bug IDs SUP-505
                SUP-1768
                SUP-1928
Code Reviewers:
        Sarah Jelinek
        Jeffry Molanus
        Albert Lee
        Harold Shaw
NEX-988 itask_lu_[read|write]_time was inadvertently removed by the Illumos 3862 fix
re #12618 rb4053 Creating LU unconditionally enables write cache on backing store device
re #7936 rb3706 Support for COMSTAR/OEM
re #8002 rb3706 Allow setting iSCSI vendor ID via stmf_sbd.conf
re #11454 rb3750 Fix inconsistent vid/pid in stmf
Re #6790 backspace should perform delete on console
VAAI (XXX ATS support for COMSTAR, YYY Block-copy support for COMSTAR)

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/io/comstar/lu/stmf_sbd/sbd.c
          +++ new/usr/src/uts/common/io/comstar/lu/stmf_sbd/sbd.c
↓ open down ↓ 13 lines elided ↑ open up ↑
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  
  22   22  /*
  23   23   * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  24      - * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
  25   24   * Copyright (c) 2013 by Delphix. All rights reserved.
       25 + * Copyright 2016 Nexenta Systems, Inc. All rights reserved.
  26   26   */
  27   27  
  28      -#include <sys/sysmacros.h>
  29   28  #include <sys/conf.h>
       29 +#include <sys/list.h>
  30   30  #include <sys/file.h>
  31   31  #include <sys/ddi.h>
  32   32  #include <sys/sunddi.h>
  33   33  #include <sys/modctl.h>
  34   34  #include <sys/scsi/scsi.h>
  35   35  #include <sys/scsi/impl/scsi_reset_notify.h>
  36   36  #include <sys/disp.h>
  37   37  #include <sys/byteorder.h>
  38   38  #include <sys/pathname.h>
  39   39  #include <sys/atomic.h>
↓ open down ↓ 9 lines elided ↑ open up ↑
  49   49  #include <sys/stmf_sbd_ioctl.h>
  50   50  
  51   51  #include "stmf_sbd.h"
  52   52  #include "sbd_impl.h"
  53   53  
  54   54  #define SBD_IS_ZVOL(zvol)       (strncmp("/dev/zvol", zvol, 9))
  55   55  
  56   56  extern sbd_status_t sbd_pgr_meta_init(sbd_lu_t *sl);
  57   57  extern sbd_status_t sbd_pgr_meta_load(sbd_lu_t *sl);
  58   58  extern void sbd_pgr_reset(sbd_lu_t *sl);
       59 +extern int HardwareAcceleratedLocking;
       60 +extern int HardwareAcceleratedInit;
       61 +extern int HardwareAcceleratedMove;
       62 +extern uint8_t sbd_unmap_enable;
  59   63  
  60   64  static int sbd_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg,
  61   65      void **result);
  62   66  static int sbd_attach(dev_info_t *dip, ddi_attach_cmd_t cmd);
  63   67  static int sbd_detach(dev_info_t *dip, ddi_detach_cmd_t cmd);
  64   68  static int sbd_open(dev_t *devp, int flag, int otype, cred_t *credp);
  65   69  static int sbd_close(dev_t dev, int flag, int otype, cred_t *credp);
  66   70  static int stmf_sbd_ioctl(dev_t dev, int cmd, intptr_t data, int mode,
  67   71      cred_t *credp, int *rval);
  68   72  void sbd_lp_cb(stmf_lu_provider_t *lp, int cmd, void *arg, uint32_t flags);
↓ open down ↓ 33 lines elided ↑ open up ↑
 102  106  int sbd_zvolset(char *zvol_name, char *comstarprop);
 103  107  char sbd_ctoi(char c);
 104  108  void sbd_close_lu(sbd_lu_t *sl);
 105  109  
 106  110  static ldi_ident_t      sbd_zfs_ident;
 107  111  static stmf_lu_provider_t *sbd_lp;
 108  112  static sbd_lu_t         *sbd_lu_list = NULL;
 109  113  static kmutex_t         sbd_lock;
 110  114  static dev_info_t       *sbd_dip;
 111  115  static uint32_t         sbd_lu_count = 0;
      116 +uint8_t sbd_enable_unmap_sync = 0;
 112  117  
 113  118  /* Global property settings for the logical unit */
 114      -char sbd_vendor_id[]    = "SUN     ";
      119 +char sbd_vendor_id[]    = "NEXENTA ";
 115  120  char sbd_product_id[]   = "COMSTAR         ";
 116  121  char sbd_revision[]     = "1.0 ";
 117  122  char *sbd_mgmt_url = NULL;
 118  123  uint16_t sbd_mgmt_url_alloc_size = 0;
 119  124  krwlock_t sbd_global_prop_lock;
 120  125  
 121  126  static char sbd_name[] = "sbd";
 122  127  
 123  128  static struct cb_ops sbd_cb_ops = {
 124  129          sbd_open,                       /* open */
↓ open down ↓ 23 lines elided ↑ open up ↑
 148  153          nulldev,                /* identify */
 149  154          nulldev,                /* probe */
 150  155          sbd_attach,
 151  156          sbd_detach,
 152  157          nodev,                  /* reset */
 153  158          &sbd_cb_ops,
 154  159          NULL,                   /* bus_ops */
 155  160          NULL                    /* power */
 156  161  };
 157  162  
 158      -#define SBD_NAME        "COMSTAR SBD"
      163 +#ifdef DEBUG
      164 +#define SBD_NAME        "COMSTAR SBD+ " __DATE__ " " __TIME__ " DEBUG"
      165 +#else
      166 +#define SBD_NAME        "COMSTAR SBD+"
      167 +#endif
 159  168  
 160  169  static struct modldrv modldrv = {
 161  170          &mod_driverops,
 162  171          SBD_NAME,
 163  172          &sbd_ops
 164  173  };
 165  174  
 166  175  static struct modlinkage modlinkage = {
 167  176          MODREV_1,
 168  177          &modldrv,
↓ open down ↓ 18 lines elided ↑ open up ↑
 187  196          sbd_lp->lp_proxy_msg = sbd_proxy_msg;
 188  197          sbd_zfs_ident = ldi_ident_from_anon();
 189  198  
 190  199          if (stmf_register_lu_provider(sbd_lp) != STMF_SUCCESS) {
 191  200                  (void) mod_remove(&modlinkage);
 192  201                  stmf_free(sbd_lp);
 193  202                  return (EINVAL);
 194  203          }
 195  204          mutex_init(&sbd_lock, NULL, MUTEX_DRIVER, NULL);
 196  205          rw_init(&sbd_global_prop_lock, NULL, RW_DRIVER, NULL);
      206 +
      207 +        if (HardwareAcceleratedLocking == 0)
      208 +                cmn_err(CE_NOTE, "HardwareAcceleratedLocking Disabled");
      209 +        if (HardwareAcceleratedMove == 0)
      210 +                cmn_err(CE_NOTE, "HardwareAcceleratedMove  Disabled");
      211 +        if (HardwareAcceleratedInit == 0)
      212 +                cmn_err(CE_NOTE, "HardwareAcceleratedInit  Disabled");
      213 +
 197  214          return (0);
 198  215  }
 199  216  
 200  217  int
 201  218  _fini(void)
 202  219  {
 203  220          int ret;
 204  221  
 205  222          /*
 206  223           * If we have registered lus, then make sure they are all offline
↓ open down ↓ 58 lines elided ↑ open up ↑
 265  282          default:
 266  283                  return (DDI_FAILURE);
 267  284          }
 268  285  
 269  286          return (DDI_SUCCESS);
 270  287  }
 271  288  
 272  289  static int
 273  290  sbd_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
 274  291  {
      292 +        char    *prop;
      293 +
 275  294          switch (cmd) {
 276  295          case DDI_ATTACH:
 277  296                  sbd_dip = dip;
 278  297  
 279  298                  if (ddi_create_minor_node(dip, "admin", S_IFCHR, 0,
 280  299                      DDI_NT_STMF_LP, 0) != DDI_SUCCESS) {
 281  300                          break;
 282  301                  }
 283  302                  ddi_report_dev(dip);
      303 +
      304 +                if (ddi_prop_lookup_string(DDI_DEV_T_ANY, dip,
      305 +                    DDI_PROP_DONTPASS, "vendor-id", &prop) == DDI_SUCCESS) {
      306 +                        (void) snprintf(sbd_vendor_id, 9, "%s%8s", prop, "");
      307 +                        ddi_prop_free(prop);
      308 +                }
      309 +                if (ddi_prop_lookup_string(DDI_DEV_T_ANY, dip,
      310 +                    DDI_PROP_DONTPASS, "product-id", &prop) == DDI_SUCCESS) {
      311 +                        (void) snprintf(sbd_product_id, 17, "%s%16s", prop, "");
      312 +                        ddi_prop_free(prop);
      313 +                }
      314 +                if (ddi_prop_lookup_string(DDI_DEV_T_ANY, dip,
      315 +                    DDI_PROP_DONTPASS, "revision", &prop) == DDI_SUCCESS) {
      316 +                        (void) snprintf(sbd_revision, 5, "%s%4s", prop, "");
      317 +                        ddi_prop_free(prop);
      318 +                }
      319 +
 284  320                  return (DDI_SUCCESS);
 285  321          }
 286  322  
 287  323          return (DDI_FAILURE);
 288  324  }
 289  325  
 290  326  static int
 291  327  sbd_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
 292  328  {
 293  329          switch (cmd) {
↓ open down ↓ 17 lines elided ↑ open up ↑
 311  347  /* ARGSUSED */
 312  348  static int
 313  349  sbd_close(dev_t dev, int flag, int otype, cred_t *credp)
 314  350  {
 315  351          return (0);
 316  352  }
 317  353  
 318  354  /* ARGSUSED */
 319  355  static int
 320  356  stmf_sbd_ioctl(dev_t dev, int cmd, intptr_t data, int mode,
 321      -        cred_t *credp, int *rval)
      357 +    cred_t *credp, int *rval)
 322  358  {
 323  359          stmf_iocdata_t          *iocd;
 324  360          void                    *ibuf   = NULL;
 325  361          void                    *obuf   = NULL;
 326  362          sbd_lu_t                *nsl;
 327  363          int                     i;
 328  364          int                     ret;
 329  365  
 330  366          if (drv_priv(credp) != 0) {
 331  367                  return (EPERM);
↓ open down ↓ 1057 lines elided ↑ open up ↑
1389 1425          kmem_free(sli, sizeof (*sli) + s);
1390 1426          return (ret);
1391 1427  }
1392 1428  
1393 1429  /*
1394 1430   * Will scribble SL_UNMAP_ENABLED into sl_flags if we succeed.
1395 1431   */
1396 1432  static void
1397 1433  do_unmap_setup(sbd_lu_t *sl)
1398 1434  {
1399      -        ASSERT((sl->sl_flags & SL_UNMAP_ENABLED) == 0);
     1435 +        if (sbd_unmap_enable == 0) {
     1436 +                sl->sl_flags &= ~(SL_UNMAP_ENABLED);
     1437 +                return;
     1438 +        }
1400 1439  
1401 1440          if ((sl->sl_flags & SL_ZFS_META) == 0)
1402 1441                  return; /* No UNMAP for you. */
1403 1442  
1404 1443          sl->sl_flags |= SL_UNMAP_ENABLED;
1405 1444  }
1406 1445  
1407 1446  int
1408 1447  sbd_populate_and_register_lu(sbd_lu_t *sl, uint32_t *err_ret)
1409 1448  {
↓ open down ↓ 24 lines elided ↑ open up ↑
1434 1473                  lu->lu_proxy_reg_arg = sl->sl_data_filename;
1435 1474                  lu->lu_proxy_reg_arg_len = strlen(sl->sl_data_filename) + 1;
1436 1475          }
1437 1476          lu->lu_lp = sbd_lp;
1438 1477          lu->lu_task_alloc = sbd_task_alloc;
1439 1478          lu->lu_new_task = sbd_new_task;
1440 1479          lu->lu_dbuf_xfer_done = sbd_dbuf_xfer_done;
1441 1480          lu->lu_send_status_done = sbd_send_status_done;
1442 1481          lu->lu_task_free = sbd_task_free;
1443 1482          lu->lu_abort = sbd_abort;
     1483 +        lu->lu_task_poll = sbd_task_poll;
1444 1484          lu->lu_dbuf_free = sbd_dbuf_free;
1445 1485          lu->lu_ctl = sbd_ctl;
     1486 +        lu->lu_task_done = sbd_ats_remove_by_task;
1446 1487          lu->lu_info = sbd_info;
1447 1488          sl->sl_state = STMF_STATE_OFFLINE;
1448 1489  
1449 1490          if ((ret = stmf_register_lu(lu)) != STMF_SUCCESS) {
1450 1491                  stmf_trace(0, "Failed to register with framework, ret=%llx",
1451 1492                      ret);
1452 1493                  if (ret == STMF_ALREADY) {
1453 1494                          *err_ret = SBD_RET_GUID_ALREADY_REGISTERED;
1454 1495                  }
1455 1496                  return (EIO);
1456 1497          }
1457 1498  
     1499 +        /*
     1500 +         * setup the ATS (compare and write) lists to handle multiple
     1501 +         * ATS commands simultaneously
     1502 +         */
     1503 +        list_create(&sl->sl_ats_io_list, sizeof (ats_state_t),
     1504 +            offsetof(ats_state_t, as_next));
1458 1505          *err_ret = 0;
1459 1506          return (0);
1460 1507  }
1461 1508  
1462 1509  int
1463 1510  sbd_open_data_file(sbd_lu_t *sl, uint32_t *err_ret, int lu_size_valid,
1464 1511      int vp_valid, int keep_open)
1465 1512  {
1466 1513          int ret;
1467 1514          int flag;
↓ open down ↓ 86 lines elided ↑ open up ↑
1554 1601                                      SHARED_META_DATA_SIZE;
1555 1602                          } else {
1556 1603                                  *err_ret = SBD_RET_FILE_SIZE_ERROR;
1557 1604                                  ret = EINVAL;
1558 1605                                  goto odf_close_data_and_exit;
1559 1606                          }
1560 1607                  } else {
1561 1608                          sl->sl_lu_size = vattr.va_size;
1562 1609                  }
1563 1610          }
     1611 +
1564 1612          if (sl->sl_lu_size < SBD_MIN_LU_SIZE) {
1565 1613                  *err_ret = SBD_RET_FILE_SIZE_ERROR;
1566 1614                  ret = EINVAL;
1567 1615                  goto odf_close_data_and_exit;
1568 1616          }
1569 1617          if (sl->sl_lu_size &
1570 1618              ((((uint64_t)1) << sl->sl_data_blocksize_shift) - 1)) {
1571 1619                  *err_ret = SBD_RET_FILE_ALIGN_ERROR;
1572 1620                  ret = EINVAL;
1573 1621                  goto odf_close_data_and_exit;
↓ open down ↓ 256 lines elided ↑ open up ↑
1830 1878                  sl->sl_flags |= SL_PID_VALID;
1831 1879          }
1832 1880          if (slu->slu_rev_valid) {
1833 1881                  bcopy(slu->slu_rev, sl->sl_revision, 4);
1834 1882                  sl->sl_flags |= SL_REV_VALID;
1835 1883          }
1836 1884          if (slu->slu_write_protected) {
1837 1885                  sl->sl_flags |= SL_WRITE_PROTECTED;
1838 1886          }
1839 1887          if (slu->slu_blksize_valid) {
1840      -                if (!ISP2(slu->slu_blksize) ||
     1888 +                if ((slu->slu_blksize & (slu->slu_blksize - 1)) ||
1841 1889                      (slu->slu_blksize > (32 * 1024)) ||
1842 1890                      (slu->slu_blksize == 0)) {
1843 1891                          *err_ret = SBD_RET_INVALID_BLKSIZE;
1844 1892                          ret = EINVAL;
1845 1893                          goto scm_err_out;
1846 1894                  }
1847 1895                  while ((1 << sl->sl_data_blocksize_shift) != slu->slu_blksize) {
1848 1896                          sl->sl_data_blocksize_shift++;
1849 1897                  }
1850 1898          } else {
↓ open down ↓ 1139 lines elided ↑ open up ↑
2990 3038                  /* Once its locked, no need to grab mutex again */
2991 3039                  sl->sl_trans_op = SL_OP_NONE;
2992 3040          }
2993 3041          return (ret);
2994 3042  }
2995 3043  
2996 3044  sbd_status_t
2997 3045  sbd_data_read(sbd_lu_t *sl, struct scsi_task *task,
2998 3046      uint64_t offset, uint64_t size, uint8_t *buf)
2999 3047  {
3000      -        int ret;
     3048 +        int ret, ioflag = 0;
3001 3049          long resid;
     3050 +        hrtime_t xfer_start;
     3051 +        uint8_t op = task->task_cdb[0];
3002 3052  
3003 3053          if ((offset + size) > sl->sl_lu_size) {
3004 3054                  return (SBD_IO_PAST_EOF);
3005 3055          }
3006 3056  
3007 3057          offset += sl->sl_data_offset;
3008 3058  
     3059 +        /*
     3060 +         * Check to see if the command is READ(10), READ(12), or READ(16).
     3061 +         * If it is then check for bit 3 being set to indicate if Forced
     3062 +         * Unit Access is being requested. If so, the FSYNC flag will be set
     3063 +         * on the read.
     3064 +         */
     3065 +        if (((op == SCMD_READ_G1) || (op == SCMD_READ_G4) ||
     3066 +            (op == SCMD_READ_G5)) && (task->task_cdb[1] & BIT_3)) {
     3067 +                ioflag = FSYNC;
     3068 +        }
3009 3069          if ((offset + size) > sl->sl_data_readable_size) {
3010 3070                  uint64_t store_end;
3011 3071                  if (offset > sl->sl_data_readable_size) {
3012 3072                          bzero(buf, size);
3013 3073                          return (SBD_SUCCESS);
3014 3074                  }
3015 3075                  store_end = sl->sl_data_readable_size - offset;
3016 3076                  bzero(buf + store_end, size - store_end);
3017 3077                  size = store_end;
3018 3078          }
3019 3079  
     3080 +        xfer_start = gethrtime();
3020 3081          DTRACE_PROBE5(backing__store__read__start, sbd_lu_t *, sl,
3021 3082              uint8_t *, buf, uint64_t, size, uint64_t, offset,
3022 3083              scsi_task_t *, task);
3023 3084  
3024 3085          /*
3025 3086           * Don't proceed if the device has been closed
3026 3087           * This can occur on an access state change to standby or
3027 3088           * a delete. The writer lock is acquired before closing the
3028 3089           * lu.
3029 3090           */
3030 3091          rw_enter(&sl->sl_access_state_lock, RW_READER);
3031 3092          if ((sl->sl_flags & SL_MEDIA_LOADED) == 0) {
3032 3093                  rw_exit(&sl->sl_access_state_lock);
3033 3094                  return (SBD_FAILURE);
3034 3095          }
     3096 +
3035 3097          ret = vn_rdwr(UIO_READ, sl->sl_data_vp, (caddr_t)buf, (ssize_t)size,
3036      -            (offset_t)offset, UIO_SYSSPACE, 0, RLIM64_INFINITY, CRED(),
     3098 +            (offset_t)offset, UIO_SYSSPACE, ioflag, RLIM64_INFINITY, CRED(),
3037 3099              &resid);
3038 3100          rw_exit(&sl->sl_access_state_lock);
3039 3101  
     3102 +        stmf_lu_xfer_done(task, B_TRUE /* read */,
     3103 +            (gethrtime() - xfer_start));
3040 3104          DTRACE_PROBE6(backing__store__read__end, sbd_lu_t *, sl,
3041 3105              uint8_t *, buf, uint64_t, size, uint64_t, offset,
3042 3106              int, ret, scsi_task_t *, task);
3043 3107  
3044 3108  over_sl_data_read:
3045 3109          if (ret || resid) {
3046 3110                  stmf_trace(0, "UIO_READ failed, ret = %d, resid = %d", ret,
3047 3111                      resid);
3048 3112                  return (SBD_FAILURE);
3049 3113          }
↓ open down ↓ 2 lines elided ↑ open up ↑
3052 3116  }
3053 3117  
3054 3118  sbd_status_t
3055 3119  sbd_data_write(sbd_lu_t *sl, struct scsi_task *task,
3056 3120      uint64_t offset, uint64_t size, uint8_t *buf)
3057 3121  {
3058 3122          int ret;
3059 3123          long resid;
3060 3124          sbd_status_t sret = SBD_SUCCESS;
3061 3125          int ioflag;
     3126 +        hrtime_t xfer_start;
     3127 +        uint8_t op = task->task_cdb[0];
     3128 +        boolean_t fua_bit = B_FALSE;
3062 3129  
3063 3130          if ((offset + size) > sl->sl_lu_size) {
3064 3131                  return (SBD_IO_PAST_EOF);
3065 3132          }
3066 3133  
3067 3134          offset += sl->sl_data_offset;
3068 3135  
3069      -        if ((sl->sl_flags & SL_WRITEBACK_CACHE_DISABLE) &&
3070      -            (sl->sl_flags & SL_FLUSH_ON_DISABLED_WRITECACHE)) {
     3136 +        /*
     3137 +         * Check to see if the command is WRITE(10), WRITE(12), or WRITE(16).
     3138 +         * If it is then check for bit 3 being set to indicate if Forced
     3139 +         * Unit Access is being requested. If so, the FSYNC flag will be set
     3140 +         * on the write.
     3141 +         */
     3142 +        if (((op == SCMD_WRITE_G1) || (op == SCMD_WRITE_G4) ||
     3143 +            (op == SCMD_WRITE_G5)) && (task->task_cdb[1] & BIT_3)) {
     3144 +                fua_bit = B_TRUE;
     3145 +        }
     3146 +        if (((sl->sl_flags & SL_WRITEBACK_CACHE_DISABLE) &&
     3147 +            (sl->sl_flags & SL_FLUSH_ON_DISABLED_WRITECACHE)) || fua_bit) {
3071 3148                  ioflag = FSYNC;
3072 3149          } else {
3073 3150                  ioflag = 0;
3074 3151          }
3075 3152  
     3153 +        xfer_start = gethrtime();
3076 3154          DTRACE_PROBE5(backing__store__write__start, sbd_lu_t *, sl,
3077 3155              uint8_t *, buf, uint64_t, size, uint64_t, offset,
3078 3156              scsi_task_t *, task);
3079 3157  
3080 3158          /*
3081 3159           * Don't proceed if the device has been closed
3082 3160           * This can occur on an access state change to standby or
3083 3161           * a delete. The writer lock is acquired before closing the
3084 3162           * lu.
3085 3163           */
3086 3164          rw_enter(&sl->sl_access_state_lock, RW_READER);
3087 3165          if ((sl->sl_flags & SL_MEDIA_LOADED) == 0) {
3088 3166                  rw_exit(&sl->sl_access_state_lock);
3089 3167                  return (SBD_FAILURE);
3090 3168          }
3091 3169          ret = vn_rdwr(UIO_WRITE, sl->sl_data_vp, (caddr_t)buf, (ssize_t)size,
3092 3170              (offset_t)offset, UIO_SYSSPACE, ioflag, RLIM64_INFINITY, CRED(),
3093 3171              &resid);
3094 3172          rw_exit(&sl->sl_access_state_lock);
3095 3173  
     3174 +        stmf_lu_xfer_done(task, B_FALSE /* write */,
     3175 +            (gethrtime() - xfer_start));
3096 3176          DTRACE_PROBE6(backing__store__write__end, sbd_lu_t *, sl,
3097 3177              uint8_t *, buf, uint64_t, size, uint64_t, offset,
3098 3178              int, ret, scsi_task_t *, task);
3099 3179  
3100 3180          if ((ret == 0) && (resid == 0) &&
3101 3181              (sl->sl_flags & SL_WRITEBACK_CACHE_DISABLE) &&
3102 3182              (sl->sl_flags & SL_FLUSH_ON_DISABLED_WRITECACHE)) {
3103 3183                  sret = sbd_flush_data_cache(sl, 1);
3104 3184          }
3105 3185  over_sl_data_write:
3106      -
3107 3186          if ((ret || resid) || (sret != SBD_SUCCESS)) {
3108 3187                  return (SBD_FAILURE);
3109 3188          } else if ((offset + size) > sl->sl_data_readable_size) {
3110 3189                  uint64_t old_size, new_size;
3111 3190  
3112 3191                  do {
3113 3192                          old_size = sl->sl_data_readable_size;
3114 3193                          if ((offset + size) <= old_size)
3115 3194                                  break;
3116 3195                          new_size = offset + size;
↓ open down ↓ 515 lines elided ↑ open up ↑
3632 3711                  rc = nvlist_lookup_string(nv2, ZPROP_VALUE, &ptr);
3633 3712                  if (rc != 0) {
3634 3713                          cmn_err(CE_WARN, "couldn't get value");
3635 3714                  } else {
3636 3715                          *comstarprop = kmem_alloc(strlen(ptr) + 1,
3637 3716                              KM_SLEEP);
3638 3717                          (void) strcpy(*comstarprop, ptr);
3639 3718                  }
3640 3719          }
3641 3720  out:
3642      -        nvlist_free(nv);
     3721 +        if (nv != NULL)
     3722 +                nvlist_free(nv);
3643 3723          kmem_free((void *)(uintptr_t)zc->zc_nvlist_dst, size);
3644 3724          kmem_free(zc, sizeof (zfs_cmd_t));
3645 3725          (void) ldi_close(zfs_lh, FREAD|FWRITE, kcred);
3646 3726  
3647 3727          return (rc);
3648 3728  }
3649 3729  
3650 3730  int
3651 3731  sbd_zvolset(char *zvol_name, char *comstarprop)
3652 3732  {
↓ open down ↓ 29 lines elided ↑ open up ↑
3682 3762          if (packed)
3683 3763                  kmem_free(packed, len);
3684 3764  out:
3685 3765          nvlist_free(nv);
3686 3766          (void) ldi_close(zfs_lh, FREAD|FWRITE, kcred);
3687 3767          return (rc);
3688 3768  }
3689 3769  
3690 3770  /*
3691 3771   * Unmap a region in a volume.  Currently only supported for zvols.
     3772 + * The list of extents to be freed is passed in a dkioc_free_list_t
     3773 + * which the caller is responsible for destroying.
3692 3774   */
3693 3775  int
3694      -sbd_unmap(sbd_lu_t *sl, uint64_t offset, uint64_t length)
     3776 +sbd_unmap(sbd_lu_t *sl, dkioc_free_list_t *dfl)
3695 3777  {
3696 3778          vnode_t *vp;
3697      -        int unused;
3698      -        dkioc_free_t df;
     3779 +        int unused, ret;
3699 3780  
3700      -        /* Right now, we only support UNMAP on zvols. */
3701      -        if (!(sl->sl_flags & SL_ZFS_META))
3702      -                return (EIO);
     3781 +        /* Nothing to do */
     3782 +        if (dfl->dfl_num_exts == 0)
     3783 +                return (0);
3703 3784  
3704      -        df.df_flags = (sl->sl_flags & SL_WRITEBACK_CACHE_DISABLE) ?
     3785 +        /*
     3786 +         * TODO: unmap performance may be improved by not doing the synchronous
     3787 +         * removal of the blocks and writing of the metadata.  The
     3788 +         * transaction is in the zil so the state should be stable.
     3789 +         */
     3790 +        dfl->dfl_flags = (sl->sl_flags & SL_WRITEBACK_CACHE_DISABLE) ?
3705 3791              DF_WAIT_SYNC : 0;
3706      -        df.df_start = offset;
3707      -        df.df_length = length;
3708 3792  
3709 3793          /* Use the data vnode we have to send a fop_ioctl(). */
3710 3794          vp = sl->sl_data_vp;
3711 3795          if (vp == NULL) {
3712 3796                  cmn_err(CE_WARN, "Cannot unmap - no vnode pointer.");
3713 3797                  return (EIO);
3714 3798          }
3715 3799  
3716      -        return (VOP_IOCTL(vp, DKIOCFREE, (intptr_t)(&df), FKIOCTL, kcred,
3717      -            &unused, NULL));
     3800 +        ret = VOP_IOCTL(vp, DKIOCFREE, (intptr_t)dfl, FKIOCTL, kcred,
     3801 +            &unused, NULL);
     3802 +
     3803 +        return (ret);
     3804 +}
     3805 +
     3806 +/*
     3807 + * Check if this lu belongs to sbd or some other lu
     3808 + * provider. A simple check for one of the module
     3809 + * entry points is sufficient.
     3810 + */
     3811 +int
     3812 +sbd_is_valid_lu(stmf_lu_t *lu)
     3813 +{
     3814 +        if (lu->lu_new_task == sbd_new_task)
     3815 +                return (1);
     3816 +        return (0);
     3817 +}
     3818 +
     3819 +uint8_t
     3820 +sbd_get_lbasize_shift(stmf_lu_t *lu)
     3821 +{
     3822 +        sbd_lu_t *sl = (sbd_lu_t *)lu->lu_provider_private;
     3823 +
     3824 +        return (sl->sl_data_blocksize_shift);
3718 3825  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX