Print this page
    
10567 lofi should support basic EFI ioctl()s
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/uts/common/io/lofi.c
          +++ new/usr/src/uts/common/io/lofi.c
   1    1  /*
   2    2   * CDDL HEADER START
   3    3   *
   4    4   * The contents of this file are subject to the terms of the
   5    5   * Common Development and Distribution License (the "License").
   6    6   * You may not use this file except in compliance with the License.
   7    7   *
   8    8   * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9    9   * or http://www.opensolaris.org/os/licensing.
  10   10   * See the License for the specific language governing permissions
  11   11   * and limitations under the License.
  12   12   *
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  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   * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
  23   23   *
  24   24   * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
  25   25   * Copyright (c) 2016 Andrey Sokolov
  26   26   * Copyright 2016 Toomas Soome <tsoome@me.com>
  27   27   * Copyright 2019 Joyent, Inc.
  28   28   */
  29   29  
  30   30  /*
  31   31   * lofi (loopback file) driver - allows you to attach a file to a device,
  32   32   * which can then be accessed through that device. The simple model is that
  33   33   * you tell lofi to open a file, and then use the block device you get as
  34   34   * you would any block device. lofi translates access to the block device
  35   35   * into I/O on the underlying file. This is mostly useful for
  36   36   * mounting images of filesystems.
  37   37   *
  38   38   * lofi is controlled through /dev/lofictl - this is the only device exported
  39   39   * during attach, and is instance number 0. lofiadm communicates with lofi
  40   40   * through ioctls on this device. When a file is attached to lofi, block and
  41   41   * character devices are exported in /dev/lofi and /dev/rlofi. These devices
  42   42   * are identified by lofi instance number, and the instance number is also used
  43   43   * as the name in /dev/lofi.
  44   44   *
  45   45   * Virtual disks, or, labeled lofi, implements virtual disk support to
  46   46   * support partition table and related tools. Such mappings will cause
  47   47   * block and character devices to be exported in /dev/dsk and /dev/rdsk
  48   48   * directories.
  49   49   *
  50   50   * To support virtual disks, the instance number space is divided to two
  51   51   * parts, upper part for instance number and lower part for minor number
  52   52   * space to identify partitions and slices. The virtual disk support is
  53   53   * implemented by stacking cmlb module. For virtual disks, the partition
  54   54   * related ioctl calls are routed to cmlb module. Compression and encryption
  55   55   * is not supported for virtual disks.
  56   56   *
  57   57   * Mapped devices are tracked with state structures handled with
  58   58   * ddi_soft_state(9F) for simplicity.
  59   59   *
  60   60   * A file attached to lofi is opened when attached and not closed until
  61   61   * explicitly detached from lofi. This seems more sensible than deferring
  62   62   * the open until the /dev/lofi device is opened, for a number of reasons.
  63   63   * One is that any failure is likely to be noticed by the person (or script)
  64   64   * running lofiadm. Another is that it would be a security problem if the
  65   65   * file was replaced by another one after being added but before being opened.
  66   66   *
  67   67   * The only hard part about lofi is the ioctls. In order to support things
  68   68   * like 'newfs' on a lofi device, it needs to support certain disk ioctls.
  69   69   * So it has to fake disk geometry and partition information. More may need
  70   70   * to be faked if your favorite utility doesn't work and you think it should
  71   71   * (fdformat doesn't work because it really wants to know the type of floppy
  72   72   * controller to talk to, and that didn't seem easy to fake. Or possibly even
  73   73   * necessary, since we have mkfs_pcfs now).
  74   74   *
  75   75   * Normally, a lofi device cannot be detached if it is open (i.e. busy).  To
  76   76   * support simulation of hotplug events, an optional force flag is provided.
  77   77   * If a lofi device is open when a force detach is requested, then the
  78   78   * underlying file is closed and any subsequent operations return EIO.  When the
  79   79   * device is closed for the last time, it will be cleaned up at that time.  In
  80   80   * addition, the DKIOCSTATE ioctl will return DKIO_DEV_GONE when the device is
  81   81   * detached but not removed.
  82   82   *
  83   83   * If detach was requested and lofi device is not open, we will perform
  84   84   * unmap and remove the lofi instance.
  85   85   *
  86   86   * If the lofi device is open and the li_cleanup is set on ioctl request,
  87   87   * we set ls_cleanup flag to notify the cleanup is requested, and the
  88   88   * last lofi_close will perform the unmapping and this lofi instance will be
  89   89   * removed.
  90   90   *
  91   91   * If the lofi device is open and the li_force is set on ioctl request,
  92   92   * we set ls_cleanup flag to notify the cleanup is requested,
  93   93   * we also set ls_vp_closereq to notify IO tasks to return EIO on new
  94   94   * IO requests and wait in process IO count to become 0, indicating there
  95   95   * are no more IO requests. Since ls_cleanup is set, the last lofi_close
  96   96   * will perform unmap and this lofi instance will be removed.
  97   97   * See also lofi_unmap_file() for details.
  98   98   *
  99   99   * Once ls_cleanup is set for the instance, we do not allow lofi_open()
 100  100   * calls to succeed and can have last lofi_close() to remove the instance.
 101  101   *
 102  102   * Known problems:
 103  103   *
 104  104   *      UFS logging. Mounting a UFS filesystem image "logging"
 105  105   *      works for basic copy testing but wedges during a build of ON through
 106  106   *      that image. Some deadlock in lufs holding the log mutex and then
 107  107   *      getting stuck on a buf. So for now, don't do that.
 108  108   *
 109  109   *      Direct I/O. Since the filesystem data is being cached in the buffer
 110  110   *      cache, _and_ again in the underlying filesystem, it's tempting to
 111  111   *      enable direct I/O on the underlying file. Don't, because that deadlocks.
 112  112   *      I think to fix the cache-twice problem we might need filesystem support.
 113  113   *
 114  114   * Interesting things to do:
 115  115   *
 116  116   *      Allow multiple files for each device. A poor-man's metadisk, basically.
 117  117   *
 118  118   *      Pass-through ioctls on block devices. You can (though it's not
 119  119   *      documented), give lofi a block device as a file name. Then we shouldn't
 120  120   *      need to fake a geometry, however, it may be relevant if you're replacing
 121  121   *      metadisk, or using lofi to get crypto.
 122  122   *      It makes sense to do lofiadm -c aes -a /dev/dsk/c0t0d0s4 /dev/lofi/1
 123  123   *      and then in /etc/vfstab have an entry for /dev/lofi/1 as /export/home.
 124  124   *      In fact this even makes sense if you have lofi "above" metadisk.
 125  125   *
 126  126   * Encryption:
 127  127   *      Each lofi device can have its own symmetric key and cipher.
 128  128   *      They are passed to us by lofiadm(1m) in the correct format for use
 129  129   *      with the misc/kcf crypto_* routines.
 130  130   *
 131  131   *      Each block has its own IV, that is calculated in lofi_blk_mech(), based
 132  132   *      on the "master" key held in the lsp and the block number of the buffer.
 133  133   */
 134  134  
 135  135  #include <sys/types.h>
 136  136  #include <netinet/in.h>
 137  137  #include <sys/sysmacros.h>
 138  138  #include <sys/uio.h>
 139  139  #include <sys/kmem.h>
 140  140  #include <sys/cred.h>
 141  141  #include <sys/mman.h>
 142  142  #include <sys/errno.h>
 143  143  #include <sys/aio_req.h>
 144  144  #include <sys/stat.h>
 145  145  #include <sys/file.h>
 146  146  #include <sys/modctl.h>
 147  147  #include <sys/conf.h>
 148  148  #include <sys/debug.h>
 149  149  #include <sys/vnode.h>
 150  150  #include <sys/lofi.h>
 151  151  #include <sys/lofi_impl.h>      /* for cache structure */
 152  152  #include <sys/fcntl.h>
 153  153  #include <sys/pathname.h>
 154  154  #include <sys/filio.h>
 155  155  #include <sys/fdio.h>
 156  156  #include <sys/open.h>
 157  157  #include <sys/disp.h>
 158  158  #include <vm/seg_map.h>
 159  159  #include <sys/ddi.h>
 160  160  #include <sys/sunddi.h>
  
    | 
      ↓ open down ↓ | 
    160 lines elided | 
    
      ↑ open up ↑ | 
  
 161  161  #include <sys/zmod.h>
 162  162  #include <sys/id_space.h>
 163  163  #include <sys/mkdev.h>
 164  164  #include <sys/crypto/common.h>
 165  165  #include <sys/crypto/api.h>
 166  166  #include <sys/rctl.h>
 167  167  #include <sys/vtoc.h>
 168  168  #include <sys/scsi/scsi.h>      /* for DTYPE_DIRECT */
 169  169  #include <sys/scsi/impl/uscsi.h>
 170  170  #include <sys/sysevent/dev.h>
      171 +#include <sys/efi_partition.h>
      172 +#include <sys/note.h>
 171  173  #include <LzmaDec.h>
 172  174  
 173  175  #define NBLOCKS_PROP_NAME       "Nblocks"
 174  176  #define SIZE_PROP_NAME          "Size"
 175  177  #define ZONE_PROP_NAME          "zone"
 176  178  
 177  179  #define SETUP_C_DATA(cd, buf, len)              \
 178  180          (cd).cd_format = CRYPTO_DATA_RAW;       \
 179  181          (cd).cd_offset = 0;                     \
 180  182          (cd).cd_miscdata = NULL;                \
 181  183          (cd).cd_length = (len);                 \
 182  184          (cd).cd_raw.iov_base = (buf);           \
 183  185          (cd).cd_raw.iov_len = (len);
 184  186  
 185  187  #define UIO_CHECK(uio)  \
 186  188          if (((uio)->uio_loffset % DEV_BSIZE) != 0 || \
 187  189              ((uio)->uio_resid % DEV_BSIZE) != 0) { \
 188  190                  return (EINVAL); \
 189  191          }
 190  192  
 191  193  #define LOFI_TIMEOUT    30
 192  194  
 193  195  static void *lofi_statep;
 194  196  static kmutex_t lofi_lock;              /* state lock */
 195  197  static id_space_t *lofi_id;             /* lofi ID values */
 196  198  static list_t lofi_list;
 197  199  static zone_key_t lofi_zone_key;
 198  200  
 199  201  /*
 200  202   * Because lofi_taskq_nthreads limits the actual swamping of the device, the
 201  203   * maxalloc parameter (lofi_taskq_maxalloc) should be tuned conservatively
 202  204   * high.  If we want to be assured that the underlying device is always busy,
 203  205   * we must be sure that the number of bytes enqueued when the number of
 204  206   * enqueued tasks exceeds maxalloc is sufficient to keep the device busy for
 205  207   * the duration of the sleep time in taskq_ent_alloc().  That is, lofi should
 206  208   * set maxalloc to be the maximum throughput (in bytes per second) of the
 207  209   * underlying device divided by the minimum I/O size.  We assume a realistic
 208  210   * maximum throughput of one hundred megabytes per second; we set maxalloc on
 209  211   * the lofi task queue to be 104857600 divided by DEV_BSIZE.
 210  212   */
 211  213  static int lofi_taskq_maxalloc = 104857600 / DEV_BSIZE;
 212  214  static int lofi_taskq_nthreads = 4;     /* # of taskq threads per device */
 213  215  
 214  216  const char lofi_crypto_magic[6] = LOFI_CRYPTO_MAGIC;
 215  217  
 216  218  /*
 217  219   * To avoid decompressing data in a compressed segment multiple times
 218  220   * when accessing small parts of a segment's data, we cache and reuse
 219  221   * the uncompressed segment's data.
 220  222   *
 221  223   * A single cached segment is sufficient to avoid lots of duplicate
 222  224   * segment decompress operations. A small cache size also reduces the
 223  225   * memory footprint.
 224  226   *
 225  227   * lofi_max_comp_cache is the maximum number of decompressed data segments
 226  228   * cached for each compressed lofi image. It can be set to 0 to disable
 227  229   * caching.
 228  230   */
 229  231  
 230  232  uint32_t lofi_max_comp_cache = 1;
 231  233  
 232  234  static int gzip_decompress(void *src, size_t srclen, void *dst,
 233  235          size_t *destlen, int level);
 234  236  
 235  237  static int lzma_decompress(void *src, size_t srclen, void *dst,
 236  238          size_t *dstlen, int level);
 237  239  
 238  240  lofi_compress_info_t lofi_compress_table[LOFI_COMPRESS_FUNCTIONS] = {
 239  241          {gzip_decompress,       NULL,   6,      "gzip"}, /* default */
 240  242          {gzip_decompress,       NULL,   6,      "gzip-6"},
 241  243          {gzip_decompress,       NULL,   9,      "gzip-9"},
 242  244          {lzma_decompress,       NULL,   0,      "lzma"}
 243  245  };
 244  246  
 245  247  static void lofi_strategy_task(void *);
 246  248  static int lofi_tg_rdwr(dev_info_t *, uchar_t, void *, diskaddr_t,
 247  249      size_t, void *);
 248  250  static int lofi_tg_getinfo(dev_info_t *, int, void *, void *);
 249  251  
 250  252  struct cmlb_tg_ops lofi_tg_ops = {
 251  253          TG_DK_OPS_VERSION_1,
 252  254          lofi_tg_rdwr,
 253  255          lofi_tg_getinfo
 254  256  };
 255  257  
 256  258  /*ARGSUSED*/
 257  259  static void
 258  260  *SzAlloc(void *p, size_t size)
 259  261  {
 260  262          return (kmem_alloc(size, KM_SLEEP));
 261  263  }
 262  264  
 263  265  /*ARGSUSED*/
 264  266  static void
 265  267  SzFree(void *p, void *address, size_t size)
 266  268  {
 267  269          kmem_free(address, size);
 268  270  }
 269  271  
 270  272  static ISzAlloc g_Alloc = { SzAlloc, SzFree };
 271  273  
 272  274  /*
 273  275   * Free data referenced by the linked list of cached uncompressed
 274  276   * segments.
 275  277   */
 276  278  static void
 277  279  lofi_free_comp_cache(struct lofi_state *lsp)
 278  280  {
 279  281          struct lofi_comp_cache *lc;
 280  282  
 281  283          while ((lc = list_remove_head(&lsp->ls_comp_cache)) != NULL) {
 282  284                  kmem_free(lc->lc_data, lsp->ls_uncomp_seg_sz);
 283  285                  kmem_free(lc, sizeof (struct lofi_comp_cache));
 284  286                  lsp->ls_comp_cache_count--;
 285  287          }
 286  288          ASSERT(lsp->ls_comp_cache_count == 0);
 287  289  }
 288  290  
 289  291  static int
 290  292  is_opened(struct lofi_state *lsp)
 291  293  {
 292  294          int i;
 293  295          boolean_t last = B_TRUE;
 294  296  
 295  297          ASSERT(MUTEX_HELD(&lofi_lock));
 296  298          for (i = 0; i < LOFI_PART_MAX; i++) {
 297  299                  if (lsp->ls_open_lyr[i]) {
 298  300                          last = B_FALSE;
 299  301                          break;
 300  302                  }
 301  303          }
 302  304  
 303  305          for (i = 0; last && (i < OTYP_LYR); i++) {
 304  306                  if (lsp->ls_open_reg[i]) {
 305  307                          last = B_FALSE;
 306  308                  }
 307  309          }
 308  310  
 309  311          return (!last);
 310  312  }
 311  313  
 312  314  static void
 313  315  lofi_set_cleanup(struct lofi_state *lsp)
 314  316  {
 315  317          ASSERT(MUTEX_HELD(&lofi_lock));
 316  318  
 317  319          lsp->ls_cleanup = B_TRUE;
 318  320  
 319  321          /* wake up any threads waiting on dkiocstate */
 320  322          cv_broadcast(&lsp->ls_vp_cv);
 321  323  }
 322  324  
 323  325  static void
 324  326  lofi_free_crypto(struct lofi_state *lsp)
 325  327  {
 326  328          ASSERT(MUTEX_HELD(&lofi_lock));
 327  329  
 328  330          if (lsp->ls_crypto_enabled) {
 329  331                  /*
 330  332                   * Clean up the crypto state so that it doesn't hang around
 331  333                   * in memory after we are done with it.
 332  334                   */
 333  335                  if (lsp->ls_key.ck_data != NULL) {
 334  336                          bzero(lsp->ls_key.ck_data,
 335  337                              CRYPTO_BITS2BYTES(lsp->ls_key.ck_length));
 336  338                          kmem_free(lsp->ls_key.ck_data,
 337  339                              CRYPTO_BITS2BYTES(lsp->ls_key.ck_length));
 338  340                          lsp->ls_key.ck_data = NULL;
 339  341                          lsp->ls_key.ck_length = 0;
 340  342                  }
 341  343  
 342  344                  if (lsp->ls_mech.cm_param != NULL) {
 343  345                          kmem_free(lsp->ls_mech.cm_param,
 344  346                              lsp->ls_mech.cm_param_len);
 345  347                          lsp->ls_mech.cm_param = NULL;
 346  348                          lsp->ls_mech.cm_param_len = 0;
 347  349                  }
 348  350  
 349  351                  if (lsp->ls_iv_mech.cm_param != NULL) {
 350  352                          kmem_free(lsp->ls_iv_mech.cm_param,
 351  353                              lsp->ls_iv_mech.cm_param_len);
 352  354                          lsp->ls_iv_mech.cm_param = NULL;
 353  355                          lsp->ls_iv_mech.cm_param_len = 0;
 354  356                  }
 355  357  
 356  358                  mutex_destroy(&lsp->ls_crypto_lock);
 357  359          }
 358  360  }
 359  361  
 360  362  /* ARGSUSED */
 361  363  static int
 362  364  lofi_tg_rdwr(dev_info_t *dip, uchar_t cmd, void *bufaddr, diskaddr_t start,
 363  365      size_t length, void *tg_cookie)
 364  366  {
 365  367          struct lofi_state *lsp;
 366  368          buf_t   *bp;
 367  369          int     instance;
 368  370          int     rv = 0;
 369  371  
 370  372          instance = ddi_get_instance(dip);
 371  373          if (instance == 0)      /* control node does not have disk */
 372  374                  return (ENXIO);
 373  375  
 374  376          lsp = ddi_get_soft_state(lofi_statep, instance);
 375  377  
 376  378          if (lsp == NULL)
 377  379                  return (ENXIO);
 378  380  
 379  381          if (cmd != TG_READ && cmd != TG_WRITE)
 380  382                  return (EINVAL);
 381  383  
 382  384          /*
 383  385           * Make sure the mapping is set up by checking lsp->ls_vp_ready.
 384  386           */
 385  387          mutex_enter(&lsp->ls_vp_lock);
 386  388          while (lsp->ls_vp_ready == B_FALSE)
 387  389                  cv_wait(&lsp->ls_vp_cv, &lsp->ls_vp_lock);
 388  390          mutex_exit(&lsp->ls_vp_lock);
 389  391  
 390  392          if (P2PHASE(length, (1U << lsp->ls_lbshift)) != 0) {
 391  393                  /* We can only transfer whole blocks at a time! */
 392  394                  return (EINVAL);
 393  395          }
 394  396  
 395  397          bp = getrbuf(KM_SLEEP);
 396  398  
 397  399          if (cmd == TG_READ) {
 398  400                  bp->b_flags = B_READ;
 399  401          } else {
 400  402                  if (lsp->ls_readonly == B_TRUE) {
 401  403                          freerbuf(bp);
 402  404                          return (EROFS);
 403  405                  }
 404  406                  bp->b_flags = B_WRITE;
 405  407          }
 406  408  
 407  409          bp->b_un.b_addr = bufaddr;
 408  410          bp->b_bcount = length;
 409  411          bp->b_lblkno = start;
 410  412          bp->b_private = NULL;
 411  413          bp->b_edev = lsp->ls_dev;
 412  414  
 413  415          if (lsp->ls_kstat) {
 414  416                  mutex_enter(lsp->ls_kstat->ks_lock);
 415  417                  kstat_waitq_enter(KSTAT_IO_PTR(lsp->ls_kstat));
 416  418                  mutex_exit(lsp->ls_kstat->ks_lock);
 417  419          }
 418  420          (void) taskq_dispatch(lsp->ls_taskq, lofi_strategy_task, bp, KM_SLEEP);
 419  421          (void) biowait(bp);
 420  422  
 421  423          rv = geterror(bp);
 422  424          freerbuf(bp);
 423  425          return (rv);
 424  426  }
 425  427  
 426  428  /*
 427  429   * Get device geometry info for cmlb.
 428  430   *
 429  431   * We have mapped disk image as virtual block device and have to report
 430  432   * physical/virtual geometry to cmlb.
 431  433   *
 432  434   * So we have two principal cases:
 433  435   * 1. Uninitialised image without any existing labels,
 434  436   *    for this case we fabricate the data based on mapped image.
 435  437   * 2. Image with existing label information.
 436  438   *    Since we have no information how the image was created (it may be
 437  439   *    dump from some physical device), we need to rely on label information
 438  440   *    from image, or we get "corrupted label" errors.
 439  441   *    NOTE: label can be MBR, MBR+SMI, GPT
 440  442   */
 441  443  static int
 442  444  lofi_tg_getinfo(dev_info_t *dip, int cmd, void *arg, void *tg_cookie)
 443  445  {
 444  446          struct lofi_state *lsp;
 445  447          int instance;
 446  448          int ashift;
 447  449  
 448  450          _NOTE(ARGUNUSED(tg_cookie));
 449  451          instance = ddi_get_instance(dip);
 450  452          if (instance == 0)              /* control device has no storage */
 451  453                  return (ENXIO);
 452  454  
 453  455          lsp = ddi_get_soft_state(lofi_statep, instance);
 454  456  
 455  457          if (lsp == NULL)
 456  458                  return (ENXIO);
 457  459  
 458  460          /*
 459  461           * Make sure the mapping is set up by checking lsp->ls_vp_ready.
 460  462           *
 461  463           * When mapping is created, new lofi instance is created and
 462  464           * lofi_attach() will call cmlb_attach() as part of the procedure
 463  465           * to set the mapping up. This chain of events will happen in
 464  466           * the same thread.
 465  467           * Since cmlb_attach() will call lofi_tg_getinfo to get
 466  468           * capacity, we return error on that call if cookie is set,
 467  469           * otherwise lofi_attach will be stuck as the mapping is not yet
 468  470           * finalized and lofi is not yet ready.
 469  471           * Note, such error is not fatal for cmlb, as the label setup
 470  472           * will be finalized when cmlb_validate() is called.
 471  473           */
 472  474          mutex_enter(&lsp->ls_vp_lock);
 473  475          if (tg_cookie != NULL && lsp->ls_vp_ready == B_FALSE) {
 474  476                  mutex_exit(&lsp->ls_vp_lock);
 475  477                  return (ENXIO);
 476  478          }
 477  479          while (lsp->ls_vp_ready == B_FALSE)
 478  480                  cv_wait(&lsp->ls_vp_cv, &lsp->ls_vp_lock);
 479  481          mutex_exit(&lsp->ls_vp_lock);
 480  482  
 481  483          ashift = lsp->ls_lbshift;
 482  484  
 483  485          switch (cmd) {
 484  486          case TG_GETPHYGEOM: {
 485  487                  cmlb_geom_t *geomp = arg;
 486  488  
 487  489                  geomp->g_capacity       =
 488  490                      (lsp->ls_vp_size - lsp->ls_crypto_offset) >> ashift;
 489  491                  geomp->g_nsect          = lsp->ls_dkg.dkg_nsect;
 490  492                  geomp->g_nhead          = lsp->ls_dkg.dkg_nhead;
 491  493                  geomp->g_acyl           = lsp->ls_dkg.dkg_acyl;
 492  494                  geomp->g_ncyl           = lsp->ls_dkg.dkg_ncyl;
 493  495                  geomp->g_secsize        = (1U << ashift);
 494  496                  geomp->g_intrlv         = lsp->ls_dkg.dkg_intrlv;
 495  497                  geomp->g_rpm            = lsp->ls_dkg.dkg_rpm;
 496  498                  return (0);
 497  499          }
 498  500  
 499  501          case TG_GETCAPACITY:
 500  502                  *(diskaddr_t *)arg =
 501  503                      (lsp->ls_vp_size - lsp->ls_crypto_offset) >> ashift;
 502  504                  return (0);
 503  505  
 504  506          case TG_GETBLOCKSIZE:
 505  507                  *(uint32_t *)arg = (1U << ashift);
 506  508                  return (0);
 507  509  
 508  510          case TG_GETATTR: {
 509  511                  tg_attribute_t *tgattr = arg;
 510  512  
 511  513                  tgattr->media_is_writable = !lsp->ls_readonly;
 512  514                  tgattr->media_is_solid_state = B_FALSE;
 513  515                  tgattr->media_is_rotational = B_FALSE;
 514  516                  return (0);
 515  517          }
 516  518  
 517  519          default:
 518  520                  return (EINVAL);
 519  521          }
 520  522  }
 521  523  
 522  524  static void
 523  525  lofi_destroy(struct lofi_state *lsp, cred_t *credp)
 524  526  {
 525  527          int id = LOFI_MINOR2ID(getminor(lsp->ls_dev));
 526  528          int i;
 527  529  
 528  530          ASSERT(MUTEX_HELD(&lofi_lock));
 529  531  
 530  532          /*
 531  533           * Before we can start to release the other resources,
 532  534           * make sure we have all tasks completed and taskq removed.
 533  535           */
 534  536          if (lsp->ls_taskq != NULL) {
 535  537                  taskq_destroy(lsp->ls_taskq);
 536  538                  lsp->ls_taskq = NULL;
 537  539          }
 538  540  
 539  541          list_remove(&lofi_list, lsp);
 540  542  
 541  543          lofi_free_crypto(lsp);
 542  544  
 543  545          /*
 544  546           * Free pre-allocated compressed buffers
 545  547           */
 546  548          if (lsp->ls_comp_bufs != NULL) {
 547  549                  for (i = 0; i < lofi_taskq_nthreads; i++) {
 548  550                          if (lsp->ls_comp_bufs[i].bufsize > 0)
 549  551                                  kmem_free(lsp->ls_comp_bufs[i].buf,
 550  552                                      lsp->ls_comp_bufs[i].bufsize);
 551  553                  }
 552  554                  kmem_free(lsp->ls_comp_bufs,
 553  555                      sizeof (struct compbuf) * lofi_taskq_nthreads);
 554  556          }
 555  557  
 556  558          if (lsp->ls_vp != NULL) {
 557  559                  (void) VOP_PUTPAGE(lsp->ls_vp, 0, 0, B_FREE, credp, NULL);
 558  560                  (void) VOP_CLOSE(lsp->ls_vp, lsp->ls_openflag,
 559  561                      1, 0, credp, NULL);
 560  562                  VN_RELE(lsp->ls_vp);
 561  563          }
 562  564          if (lsp->ls_stacked_vp != lsp->ls_vp)
 563  565                  VN_RELE(lsp->ls_stacked_vp);
 564  566          lsp->ls_vp = lsp->ls_stacked_vp = NULL;
 565  567  
 566  568          if (lsp->ls_kstat != NULL) {
 567  569                  kstat_delete(lsp->ls_kstat);
 568  570                  lsp->ls_kstat = NULL;
 569  571          }
 570  572  
 571  573          /*
 572  574           * Free cached decompressed segment data
 573  575           */
 574  576          lofi_free_comp_cache(lsp);
 575  577          list_destroy(&lsp->ls_comp_cache);
 576  578  
 577  579          if (lsp->ls_uncomp_seg_sz > 0) {
 578  580                  kmem_free(lsp->ls_comp_index_data, lsp->ls_comp_index_data_sz);
 579  581                  lsp->ls_uncomp_seg_sz = 0;
 580  582          }
 581  583  
 582  584          rctl_decr_lofi(lsp->ls_zone.zref_zone, 1);
 583  585          zone_rele_ref(&lsp->ls_zone, ZONE_REF_LOFI);
 584  586  
 585  587          mutex_destroy(&lsp->ls_comp_cache_lock);
 586  588          mutex_destroy(&lsp->ls_comp_bufs_lock);
 587  589          mutex_destroy(&lsp->ls_kstat_lock);
 588  590          mutex_destroy(&lsp->ls_vp_lock);
 589  591          cv_destroy(&lsp->ls_vp_cv);
 590  592          lsp->ls_vp_ready = B_FALSE;
 591  593          lsp->ls_vp_closereq = B_FALSE;
 592  594  
 593  595          ASSERT(ddi_get_soft_state(lofi_statep, id) == lsp);
 594  596          (void) ndi_devi_offline(lsp->ls_dip, NDI_DEVI_REMOVE);
 595  597          id_free(lofi_id, id);
 596  598  }
 597  599  
 598  600  static void
 599  601  lofi_free_dev(struct lofi_state *lsp)
 600  602  {
 601  603          ASSERT(MUTEX_HELD(&lofi_lock));
 602  604  
 603  605          if (lsp->ls_cmlbhandle != NULL) {
 604  606                  cmlb_invalidate(lsp->ls_cmlbhandle, 0);
 605  607                  cmlb_detach(lsp->ls_cmlbhandle, 0);
 606  608                  cmlb_free_handle(&lsp->ls_cmlbhandle);
 607  609                  lsp->ls_cmlbhandle = NULL;
 608  610          }
 609  611          (void) ddi_prop_remove_all(lsp->ls_dip);
 610  612          ddi_remove_minor_node(lsp->ls_dip, NULL);
 611  613  }
 612  614  
 613  615  /*ARGSUSED*/
 614  616  static void
 615  617  lofi_zone_shutdown(zoneid_t zoneid, void *arg)
 616  618  {
 617  619          struct lofi_state *lsp;
 618  620          struct lofi_state *next;
 619  621  
 620  622          mutex_enter(&lofi_lock);
 621  623  
 622  624          for (lsp = list_head(&lofi_list); lsp != NULL; lsp = next) {
 623  625  
 624  626                  /* lofi_destroy() frees lsp */
 625  627                  next = list_next(&lofi_list, lsp);
 626  628  
 627  629                  if (lsp->ls_zone.zref_zone->zone_id != zoneid)
 628  630                          continue;
 629  631  
 630  632                  /*
 631  633                   * No in-zone processes are running, but something has this
 632  634                   * open.  It's either a global zone process, or a lofi
 633  635                   * mount.  In either case we set ls_cleanup so the last
 634  636                   * user destroys the device.
 635  637                   */
 636  638                  if (is_opened(lsp)) {
 637  639                          lofi_set_cleanup(lsp);
 638  640                  } else {
 639  641                          lofi_free_dev(lsp);
 640  642                          lofi_destroy(lsp, kcred);
 641  643                  }
 642  644          }
 643  645  
 644  646          mutex_exit(&lofi_lock);
 645  647  }
 646  648  
 647  649  /*ARGSUSED*/
 648  650  static int
 649  651  lofi_open(dev_t *devp, int flag, int otyp, struct cred *credp)
 650  652  {
 651  653          int id;
 652  654          minor_t part;
 653  655          uint64_t mask;
 654  656          diskaddr_t nblks;
 655  657          diskaddr_t lba;
 656  658          boolean_t ndelay;
 657  659  
 658  660          struct lofi_state *lsp;
 659  661  
 660  662          if (otyp >= OTYPCNT)
 661  663                  return (EINVAL);
 662  664  
 663  665          ndelay = (flag & (FNDELAY | FNONBLOCK)) ? B_TRUE : B_FALSE;
 664  666  
 665  667          /*
 666  668           * lofiadm -a /dev/lofi/1 gets us here.
 667  669           */
 668  670          if (mutex_owner(&lofi_lock) == curthread)
 669  671                  return (EINVAL);
 670  672  
 671  673          mutex_enter(&lofi_lock);
 672  674  
 673  675          id = LOFI_MINOR2ID(getminor(*devp));
 674  676          part = LOFI_PART(getminor(*devp));
 675  677          mask = (1U << part);
 676  678  
 677  679          /* master control device */
 678  680          if (id == 0) {
 679  681                  mutex_exit(&lofi_lock);
 680  682                  return (0);
 681  683          }
 682  684  
 683  685          /* otherwise, the mapping should already exist */
 684  686          lsp = ddi_get_soft_state(lofi_statep, id);
 685  687          if (lsp == NULL) {
 686  688                  mutex_exit(&lofi_lock);
 687  689                  return (EINVAL);
 688  690          }
 689  691  
 690  692          if (lsp->ls_cleanup == B_TRUE) {
 691  693                  mutex_exit(&lofi_lock);
 692  694                  return (ENXIO);
 693  695          }
 694  696  
 695  697          if (lsp->ls_vp == NULL) {
 696  698                  mutex_exit(&lofi_lock);
 697  699                  return (ENXIO);
 698  700          }
 699  701  
 700  702          if (lsp->ls_readonly && (flag & FWRITE)) {
 701  703                  mutex_exit(&lofi_lock);
 702  704                  return (EROFS);
 703  705          }
 704  706  
 705  707          if ((lsp->ls_open_excl) & (mask)) {
 706  708                  mutex_exit(&lofi_lock);
 707  709                  return (EBUSY);
 708  710          }
 709  711  
 710  712          if (flag & FEXCL) {
 711  713                  if (lsp->ls_open_lyr[part]) {
 712  714                          mutex_exit(&lofi_lock);
 713  715                          return (EBUSY);
 714  716                  }
 715  717                  for (int i = 0; i < OTYP_LYR; i++) {
 716  718                          if (lsp->ls_open_reg[i] & mask) {
 717  719                                  mutex_exit(&lofi_lock);
 718  720                                  return (EBUSY);
 719  721                          }
 720  722                  }
 721  723          }
 722  724  
 723  725          if (lsp->ls_cmlbhandle != NULL) {
 724  726                  if (cmlb_validate(lsp->ls_cmlbhandle, 0, 0) != 0) {
 725  727                          /*
 726  728                           * non-blocking opens are allowed to succeed to
 727  729                           * support format and fdisk to create partitioning.
 728  730                           */
 729  731                          if (!ndelay) {
 730  732                                  mutex_exit(&lofi_lock);
 731  733                                  return (ENXIO);
 732  734                          }
 733  735                  } else if (cmlb_partinfo(lsp->ls_cmlbhandle, part, &nblks, &lba,
 734  736                      NULL, NULL, 0) == 0) {
 735  737                          if ((!nblks) && ((!ndelay) || (otyp != OTYP_CHR))) {
 736  738                                  mutex_exit(&lofi_lock);
 737  739                                  return (ENXIO);
 738  740                          }
 739  741                  } else if (!ndelay) {
 740  742                          mutex_exit(&lofi_lock);
 741  743                          return (ENXIO);
 742  744                  }
 743  745          }
 744  746  
 745  747          if (otyp == OTYP_LYR) {
 746  748                  lsp->ls_open_lyr[part]++;
 747  749          } else {
 748  750                  lsp->ls_open_reg[otyp] |= mask;
 749  751          }
 750  752          if (flag & FEXCL) {
 751  753                  lsp->ls_open_excl |= mask;
 752  754          }
 753  755  
 754  756          mutex_exit(&lofi_lock);
 755  757          return (0);
 756  758  }
 757  759  
 758  760  /*ARGSUSED*/
 759  761  static int
 760  762  lofi_close(dev_t dev, int flag, int otyp, struct cred *credp)
 761  763  {
 762  764          minor_t part;
 763  765          int id;
 764  766          uint64_t mask;
 765  767          struct lofi_state *lsp;
 766  768  
 767  769          id = LOFI_MINOR2ID(getminor(dev));
 768  770          part = LOFI_PART(getminor(dev));
 769  771          mask = (1U << part);
 770  772  
 771  773          mutex_enter(&lofi_lock);
 772  774          lsp = ddi_get_soft_state(lofi_statep, id);
 773  775          if (lsp == NULL) {
 774  776                  mutex_exit(&lofi_lock);
 775  777                  return (EINVAL);
 776  778          }
 777  779  
 778  780          if (id == 0) {
 779  781                  mutex_exit(&lofi_lock);
 780  782                  return (0);
 781  783          }
 782  784  
 783  785          if (lsp->ls_open_excl & mask)
 784  786                  lsp->ls_open_excl &= ~mask;
 785  787  
 786  788          if (otyp == OTYP_LYR) {
 787  789                  lsp->ls_open_lyr[part]--;
 788  790          } else {
 789  791                  lsp->ls_open_reg[otyp] &= ~mask;
 790  792          }
 791  793  
 792  794          /*
 793  795           * If we forcibly closed the underlying device (li_force), or
 794  796           * asked for cleanup (li_cleanup), finish up if we're the last
 795  797           * out of the door.
 796  798           */
 797  799          if (!is_opened(lsp) &&
 798  800              (lsp->ls_cleanup == B_TRUE || lsp->ls_vp == NULL)) {
 799  801                  lofi_free_dev(lsp);
 800  802                  lofi_destroy(lsp, credp);
 801  803          }
 802  804  
 803  805          mutex_exit(&lofi_lock);
 804  806          return (0);
 805  807  }
 806  808  
 807  809  /*
 808  810   * Sets the mechanism's initialization vector (IV) if one is needed.
 809  811   * The IV is computed from the data block number.  lsp->ls_mech is
 810  812   * altered so that:
 811  813   *      lsp->ls_mech.cm_param_len is set to the IV len.
 812  814   *      lsp->ls_mech.cm_param is set to the IV.
 813  815   */
 814  816  static int
 815  817  lofi_blk_mech(struct lofi_state *lsp, longlong_t lblkno)
 816  818  {
 817  819          int     ret;
 818  820          crypto_data_t cdata;
 819  821          char    *iv;
 820  822          size_t  iv_len;
 821  823          size_t  min;
 822  824          void    *data;
 823  825          size_t  datasz;
 824  826  
 825  827          ASSERT(MUTEX_HELD(&lsp->ls_crypto_lock));
 826  828  
 827  829          if (lsp == NULL)
 828  830                  return (CRYPTO_DEVICE_ERROR);
 829  831  
 830  832          /* lsp->ls_mech.cm_param{_len} has already been set for static iv */
 831  833          if (lsp->ls_iv_type == IVM_NONE) {
 832  834                  return (CRYPTO_SUCCESS);
 833  835          }
 834  836  
 835  837          /*
 836  838           * if kmem already alloced from previous call and it's the same size
 837  839           * we need now, just recycle it; allocate new kmem only if we have to
 838  840           */
 839  841          if (lsp->ls_mech.cm_param == NULL ||
 840  842              lsp->ls_mech.cm_param_len != lsp->ls_iv_len) {
 841  843                  iv_len = lsp->ls_iv_len;
 842  844                  iv = kmem_zalloc(iv_len, KM_SLEEP);
 843  845          } else {
 844  846                  iv_len = lsp->ls_mech.cm_param_len;
 845  847                  iv = lsp->ls_mech.cm_param;
 846  848                  bzero(iv, iv_len);
 847  849          }
 848  850  
 849  851          switch (lsp->ls_iv_type) {
 850  852          case IVM_ENC_BLKNO:
 851  853                  /* iv is not static, lblkno changes each time */
 852  854                  data = &lblkno;
 853  855                  datasz = sizeof (lblkno);
 854  856                  break;
 855  857          default:
 856  858                  data = 0;
 857  859                  datasz = 0;
 858  860                  break;
 859  861          }
 860  862  
 861  863          /*
 862  864           * write blkno into the iv buffer padded on the left in case
 863  865           * blkno ever grows bigger than its current longlong_t size
 864  866           * or a variation other than blkno is used for the iv data
 865  867           */
 866  868          min = MIN(datasz, iv_len);
 867  869          bcopy(data, iv + (iv_len - min), min);
 868  870  
 869  871          /* encrypt the data in-place to get the IV */
 870  872          SETUP_C_DATA(cdata, iv, iv_len);
 871  873  
 872  874          ret = crypto_encrypt(&lsp->ls_iv_mech, &cdata, &lsp->ls_key,
 873  875              NULL, NULL, NULL);
 874  876          if (ret != CRYPTO_SUCCESS) {
 875  877                  cmn_err(CE_WARN, "failed to create iv for block %lld: (0x%x)",
 876  878                      lblkno, ret);
 877  879                  if (lsp->ls_mech.cm_param != iv)
 878  880                          kmem_free(iv, iv_len);
 879  881  
 880  882                  return (ret);
 881  883          }
 882  884  
 883  885          /* clean up the iv from the last computation */
 884  886          if (lsp->ls_mech.cm_param != NULL && lsp->ls_mech.cm_param != iv)
 885  887                  kmem_free(lsp->ls_mech.cm_param, lsp->ls_mech.cm_param_len);
 886  888  
 887  889          lsp->ls_mech.cm_param_len = iv_len;
 888  890          lsp->ls_mech.cm_param = iv;
 889  891  
 890  892          return (CRYPTO_SUCCESS);
 891  893  }
 892  894  
 893  895  /*
 894  896   * Performs encryption and decryption of a chunk of data of size "len",
 895  897   * one DEV_BSIZE block at a time.  "len" is assumed to be a multiple of
 896  898   * DEV_BSIZE.
 897  899   */
 898  900  static int
 899  901  lofi_crypto(struct lofi_state *lsp, struct buf *bp, caddr_t plaintext,
 900  902      caddr_t ciphertext, size_t len, boolean_t op_encrypt)
 901  903  {
 902  904          crypto_data_t cdata;
 903  905          crypto_data_t wdata;
 904  906          int ret;
 905  907          longlong_t lblkno = bp->b_lblkno;
 906  908  
 907  909          mutex_enter(&lsp->ls_crypto_lock);
 908  910  
 909  911          /*
 910  912           * though we could encrypt/decrypt entire "len" chunk of data, we need
 911  913           * to break it into DEV_BSIZE pieces to capture blkno incrementing
 912  914           */
 913  915          SETUP_C_DATA(cdata, plaintext, len);
 914  916          cdata.cd_length = DEV_BSIZE;
 915  917          if (ciphertext != NULL) {               /* not in-place crypto */
 916  918                  SETUP_C_DATA(wdata, ciphertext, len);
 917  919                  wdata.cd_length = DEV_BSIZE;
 918  920          }
 919  921  
 920  922          do {
 921  923                  ret = lofi_blk_mech(lsp, lblkno);
 922  924                  if (ret != CRYPTO_SUCCESS)
 923  925                          continue;
 924  926  
 925  927                  if (op_encrypt) {
 926  928                          ret = crypto_encrypt(&lsp->ls_mech, &cdata,
 927  929                              &lsp->ls_key, NULL,
 928  930                              ((ciphertext != NULL) ? &wdata : NULL), NULL);
 929  931                  } else {
 930  932                          ret = crypto_decrypt(&lsp->ls_mech, &cdata,
 931  933                              &lsp->ls_key, NULL,
 932  934                              ((ciphertext != NULL) ? &wdata : NULL), NULL);
 933  935                  }
 934  936  
 935  937                  cdata.cd_offset += DEV_BSIZE;
 936  938                  if (ciphertext != NULL)
 937  939                          wdata.cd_offset += DEV_BSIZE;
 938  940                  lblkno++;
 939  941          } while (ret == CRYPTO_SUCCESS && cdata.cd_offset < len);
 940  942  
 941  943          mutex_exit(&lsp->ls_crypto_lock);
 942  944  
 943  945          if (ret != CRYPTO_SUCCESS) {
 944  946                  cmn_err(CE_WARN, "%s failed for block %lld:  (0x%x)",
 945  947                      op_encrypt ? "crypto_encrypt()" : "crypto_decrypt()",
 946  948                      lblkno, ret);
 947  949          }
 948  950  
 949  951          return (ret);
 950  952  }
 951  953  
 952  954  #define RDWR_RAW        1
 953  955  #define RDWR_BCOPY      2
 954  956  
 955  957  static int
 956  958  lofi_rdwr(caddr_t bufaddr, offset_t offset, struct buf *bp,
 957  959      struct lofi_state *lsp, size_t len, int method, caddr_t bcopy_locn)
 958  960  {
 959  961          ssize_t resid;
 960  962          int isread;
 961  963          int error;
 962  964  
 963  965          /*
 964  966           * Handles reads/writes for both plain and encrypted lofi
 965  967           * Note:  offset is already shifted by lsp->ls_crypto_offset
 966  968           * when it gets here.
 967  969           */
 968  970  
 969  971          isread = bp->b_flags & B_READ;
 970  972          if (isread) {
 971  973                  if (method == RDWR_BCOPY) {
 972  974                          /* DO NOT update bp->b_resid for bcopy */
 973  975                          bcopy(bcopy_locn, bufaddr, len);
 974  976                          error = 0;
 975  977                  } else {                /* RDWR_RAW */
 976  978                          error = vn_rdwr(UIO_READ, lsp->ls_vp, bufaddr, len,
 977  979                              offset, UIO_SYSSPACE, 0, RLIM64_INFINITY, kcred,
 978  980                              &resid);
 979  981                          bp->b_resid = resid;
 980  982                  }
 981  983                  if (lsp->ls_crypto_enabled && error == 0) {
 982  984                          if (lofi_crypto(lsp, bp, bufaddr, NULL, len,
 983  985                              B_FALSE) != CRYPTO_SUCCESS) {
 984  986                                  /*
 985  987                                   * XXX: original code didn't set residual
 986  988                                   * back to len because no error was expected
 987  989                                   * from bcopy() if encryption is not enabled
 988  990                                   */
 989  991                                  if (method != RDWR_BCOPY)
 990  992                                          bp->b_resid = len;
 991  993                                  error = EIO;
 992  994                          }
 993  995                  }
 994  996                  return (error);
 995  997          } else {
 996  998                  void *iobuf = bufaddr;
 997  999  
 998 1000                  if (lsp->ls_crypto_enabled) {
 999 1001                          /* don't do in-place crypto to keep bufaddr intact */
1000 1002                          iobuf = kmem_alloc(len, KM_SLEEP);
1001 1003                          if (lofi_crypto(lsp, bp, bufaddr, iobuf, len,
1002 1004                              B_TRUE) != CRYPTO_SUCCESS) {
1003 1005                                  kmem_free(iobuf, len);
1004 1006                                  if (method != RDWR_BCOPY)
1005 1007                                          bp->b_resid = len;
1006 1008                                  return (EIO);
1007 1009                          }
1008 1010                  }
1009 1011                  if (method == RDWR_BCOPY) {
1010 1012                          /* DO NOT update bp->b_resid for bcopy */
1011 1013                          bcopy(iobuf, bcopy_locn, len);
1012 1014                          error = 0;
1013 1015                  } else {                /* RDWR_RAW */
1014 1016                          error = vn_rdwr(UIO_WRITE, lsp->ls_vp, iobuf, len,
1015 1017                              offset, UIO_SYSSPACE, 0, RLIM64_INFINITY, kcred,
1016 1018                              &resid);
1017 1019                          bp->b_resid = resid;
1018 1020                  }
1019 1021                  if (lsp->ls_crypto_enabled) {
1020 1022                          kmem_free(iobuf, len);
1021 1023                  }
1022 1024                  return (error);
1023 1025          }
1024 1026  }
1025 1027  
1026 1028  static int
1027 1029  lofi_mapped_rdwr(caddr_t bufaddr, offset_t offset, struct buf *bp,
1028 1030      struct lofi_state *lsp)
1029 1031  {
1030 1032          int error;
1031 1033          offset_t alignedoffset, mapoffset;
1032 1034          size_t  xfersize;
1033 1035          int     isread;
1034 1036          int     smflags;
1035 1037          caddr_t mapaddr;
1036 1038          size_t  len;
1037 1039          enum seg_rw srw;
1038 1040          int     save_error;
1039 1041  
1040 1042          /*
1041 1043           * Note:  offset is already shifted by lsp->ls_crypto_offset
1042 1044           * when it gets here.
1043 1045           */
1044 1046          if (lsp->ls_crypto_enabled)
1045 1047                  ASSERT(lsp->ls_vp_comp_size == lsp->ls_vp_size);
1046 1048  
1047 1049          /*
1048 1050           * segmap always gives us an 8K (MAXBSIZE) chunk, aligned on
1049 1051           * an 8K boundary, but the buf transfer address may not be
1050 1052           * aligned on more than a 512-byte boundary (we don't enforce
1051 1053           * that even though we could). This matters since the initial
1052 1054           * part of the transfer may not start at offset 0 within the
1053 1055           * segmap'd chunk. So we have to compensate for that with
1054 1056           * 'mapoffset'. Subsequent chunks always start off at the
1055 1057           * beginning, and the last is capped by b_resid
1056 1058           *
1057 1059           * Visually, where "|" represents page map boundaries:
1058 1060           *   alignedoffset (mapaddr begins at this segmap boundary)
1059 1061           *    |   offset (from beginning of file)
1060 1062           *    |    |       len
1061 1063           *    v    v        v
1062 1064           * ===|====X========|====...======|========X====|====
1063 1065           *         /-------------...---------------/
1064 1066           *              ^ bp->b_bcount/bp->b_resid at start
1065 1067           *    /----/--------/----...------/--------/
1066 1068           *      ^       ^       ^   ^           ^
1067 1069           *      |       |       |   |           nth xfersize (<= MAXBSIZE)
1068 1070           *      |       |       2nd thru n-1st xfersize (= MAXBSIZE)
1069 1071           *      |       1st xfersize (<= MAXBSIZE)
1070 1072           *    mapoffset (offset into 1st segmap, non-0 1st time, 0 thereafter)
1071 1073           *
1072 1074           * Notes: "alignedoffset" is "offset" rounded down to nearest
1073 1075           * MAXBSIZE boundary.  "len" is next page boundary of size
1074 1076           * PAGESIZE after "alignedoffset".
1075 1077           */
1076 1078          mapoffset = offset & MAXBOFFSET;
1077 1079          alignedoffset = offset - mapoffset;
1078 1080          bp->b_resid = bp->b_bcount;
1079 1081          isread = bp->b_flags & B_READ;
1080 1082          srw = isread ? S_READ : S_WRITE;
1081 1083          do {
1082 1084                  xfersize = MIN(lsp->ls_vp_comp_size - offset,
1083 1085                      MIN(MAXBSIZE - mapoffset, bp->b_resid));
1084 1086                  len = roundup(mapoffset + xfersize, PAGESIZE);
1085 1087                  mapaddr = segmap_getmapflt(segkmap, lsp->ls_vp,
1086 1088                      alignedoffset, MAXBSIZE, 1, srw);
1087 1089                  /*
1088 1090                   * Now fault in the pages. This lets us check
1089 1091                   * for errors before we reference mapaddr and
1090 1092                   * try to resolve the fault in bcopy (which would
1091 1093                   * panic instead). And this can easily happen,
1092 1094                   * particularly if you've lofi'd a file over NFS
1093 1095                   * and someone deletes the file on the server.
1094 1096                   */
1095 1097                  error = segmap_fault(kas.a_hat, segkmap, mapaddr,
1096 1098                      len, F_SOFTLOCK, srw);
1097 1099                  if (error) {
1098 1100                          (void) segmap_release(segkmap, mapaddr, 0);
1099 1101                          if (FC_CODE(error) == FC_OBJERR)
1100 1102                                  error = FC_ERRNO(error);
1101 1103                          else
1102 1104                                  error = EIO;
1103 1105                          break;
1104 1106                  }
1105 1107                  /* error may be non-zero for encrypted lofi */
1106 1108                  error = lofi_rdwr(bufaddr, 0, bp, lsp, xfersize,
1107 1109                      RDWR_BCOPY, mapaddr + mapoffset);
1108 1110                  if (error == 0) {
1109 1111                          bp->b_resid -= xfersize;
1110 1112                          bufaddr += xfersize;
1111 1113                          offset += xfersize;
1112 1114                  }
1113 1115                  smflags = 0;
1114 1116                  if (isread) {
1115 1117                          smflags |= SM_FREE;
1116 1118                          /*
1117 1119                           * If we're reading an entire page starting
1118 1120                           * at a page boundary, there's a good chance
1119 1121                           * we won't need it again. Put it on the
1120 1122                           * head of the freelist.
1121 1123                           */
1122 1124                          if (mapoffset == 0 && xfersize == MAXBSIZE)
1123 1125                                  smflags |= SM_DONTNEED;
1124 1126                  } else {
1125 1127                          /*
1126 1128                           * Write back good pages, it is okay to
1127 1129                           * always release asynchronous here as we'll
1128 1130                           * follow with VOP_FSYNC for B_SYNC buffers.
1129 1131                           */
1130 1132                          if (error == 0)
1131 1133                                  smflags |= SM_WRITE | SM_ASYNC;
1132 1134                  }
1133 1135                  (void) segmap_fault(kas.a_hat, segkmap, mapaddr,
1134 1136                      len, F_SOFTUNLOCK, srw);
1135 1137                  save_error = segmap_release(segkmap, mapaddr, smflags);
1136 1138                  if (error == 0)
1137 1139                          error = save_error;
1138 1140                  /* only the first map may start partial */
1139 1141                  mapoffset = 0;
1140 1142                  alignedoffset += MAXBSIZE;
1141 1143          } while ((error == 0) && (bp->b_resid > 0) &&
1142 1144              (offset < lsp->ls_vp_comp_size));
1143 1145  
1144 1146          return (error);
1145 1147  }
1146 1148  
1147 1149  /*
1148 1150   * Check if segment seg_index is present in the decompressed segment
1149 1151   * data cache.
1150 1152   *
1151 1153   * Returns a pointer to the decompressed segment data cache entry if
1152 1154   * found, and NULL when decompressed data for this segment is not yet
1153 1155   * cached.
1154 1156   */
1155 1157  static struct lofi_comp_cache *
1156 1158  lofi_find_comp_data(struct lofi_state *lsp, uint64_t seg_index)
1157 1159  {
1158 1160          struct lofi_comp_cache *lc;
1159 1161  
1160 1162          ASSERT(MUTEX_HELD(&lsp->ls_comp_cache_lock));
1161 1163  
1162 1164          for (lc = list_head(&lsp->ls_comp_cache); lc != NULL;
1163 1165              lc = list_next(&lsp->ls_comp_cache, lc)) {
1164 1166                  if (lc->lc_index == seg_index) {
1165 1167                          /*
1166 1168                           * Decompressed segment data was found in the
1167 1169                           * cache.
1168 1170                           *
1169 1171                           * The cache uses an LRU replacement strategy;
1170 1172                           * move the entry to head of list.
1171 1173                           */
1172 1174                          list_remove(&lsp->ls_comp_cache, lc);
1173 1175                          list_insert_head(&lsp->ls_comp_cache, lc);
1174 1176                          return (lc);
1175 1177                  }
1176 1178          }
1177 1179          return (NULL);
1178 1180  }
1179 1181  
1180 1182  /*
1181 1183   * Add the data for a decompressed segment at segment index
1182 1184   * seg_index to the cache of the decompressed segments.
1183 1185   *
1184 1186   * Returns a pointer to the cache element structure in case
1185 1187   * the data was added to the cache; returns NULL when the data
1186 1188   * wasn't cached.
1187 1189   */
1188 1190  static struct lofi_comp_cache *
1189 1191  lofi_add_comp_data(struct lofi_state *lsp, uint64_t seg_index,
1190 1192      uchar_t *data)
1191 1193  {
1192 1194          struct lofi_comp_cache *lc;
1193 1195  
1194 1196          ASSERT(MUTEX_HELD(&lsp->ls_comp_cache_lock));
1195 1197  
1196 1198          while (lsp->ls_comp_cache_count > lofi_max_comp_cache) {
1197 1199                  lc = list_remove_tail(&lsp->ls_comp_cache);
1198 1200                  ASSERT(lc != NULL);
1199 1201                  kmem_free(lc->lc_data, lsp->ls_uncomp_seg_sz);
1200 1202                  kmem_free(lc, sizeof (struct lofi_comp_cache));
1201 1203                  lsp->ls_comp_cache_count--;
1202 1204          }
1203 1205  
1204 1206          /*
1205 1207           * Do not cache when disabled by tunable variable
1206 1208           */
1207 1209          if (lofi_max_comp_cache == 0)
1208 1210                  return (NULL);
1209 1211  
1210 1212          /*
1211 1213           * When the cache has not yet reached the maximum allowed
1212 1214           * number of segments, allocate a new cache element.
1213 1215           * Otherwise the cache is full; reuse the last list element
1214 1216           * (LRU) for caching the decompressed segment data.
1215 1217           *
1216 1218           * The cache element for the new decompressed segment data is
1217 1219           * added to the head of the list.
1218 1220           */
1219 1221          if (lsp->ls_comp_cache_count < lofi_max_comp_cache) {
1220 1222                  lc = kmem_alloc(sizeof (struct lofi_comp_cache), KM_SLEEP);
1221 1223                  lc->lc_data = NULL;
1222 1224                  list_insert_head(&lsp->ls_comp_cache, lc);
1223 1225                  lsp->ls_comp_cache_count++;
1224 1226          } else {
1225 1227                  lc = list_remove_tail(&lsp->ls_comp_cache);
1226 1228                  if (lc == NULL)
1227 1229                          return (NULL);
1228 1230                  list_insert_head(&lsp->ls_comp_cache, lc);
1229 1231          }
1230 1232  
1231 1233          /*
1232 1234           * Free old uncompressed segment data when reusing a cache
1233 1235           * entry.
1234 1236           */
1235 1237          if (lc->lc_data != NULL)
1236 1238                  kmem_free(lc->lc_data, lsp->ls_uncomp_seg_sz);
1237 1239  
1238 1240          lc->lc_data = data;
1239 1241          lc->lc_index = seg_index;
1240 1242          return (lc);
1241 1243  }
1242 1244  
1243 1245  
1244 1246  /*ARGSUSED*/
1245 1247  static int
1246 1248  gzip_decompress(void *src, size_t srclen, void *dst,
1247 1249      size_t *dstlen, int level)
1248 1250  {
1249 1251          ASSERT(*dstlen >= srclen);
1250 1252  
1251 1253          if (z_uncompress(dst, dstlen, src, srclen) != Z_OK)
1252 1254                  return (-1);
1253 1255          return (0);
1254 1256  }
1255 1257  
1256 1258  #define LZMA_HEADER_SIZE        (LZMA_PROPS_SIZE + 8)
1257 1259  /*ARGSUSED*/
1258 1260  static int
1259 1261  lzma_decompress(void *src, size_t srclen, void *dst,
1260 1262      size_t *dstlen, int level)
1261 1263  {
1262 1264          size_t insizepure;
1263 1265          void *actual_src;
1264 1266          ELzmaStatus status;
1265 1267  
1266 1268          insizepure = srclen - LZMA_HEADER_SIZE;
1267 1269          actual_src = (void *)((Byte *)src + LZMA_HEADER_SIZE);
1268 1270  
1269 1271          if (LzmaDecode((Byte *)dst, (size_t *)dstlen,
1270 1272              (const Byte *)actual_src, &insizepure,
1271 1273              (const Byte *)src, LZMA_PROPS_SIZE, LZMA_FINISH_ANY, &status,
1272 1274              &g_Alloc) != SZ_OK) {
1273 1275                  return (-1);
1274 1276          }
1275 1277          return (0);
1276 1278  }
1277 1279  
1278 1280  /*
1279 1281   * This is basically what strategy used to be before we found we
1280 1282   * needed task queues.
1281 1283   */
1282 1284  static void
1283 1285  lofi_strategy_task(void *arg)
1284 1286  {
1285 1287          struct buf *bp = (struct buf *)arg;
1286 1288          int error;
1287 1289          int syncflag = 0;
1288 1290          struct lofi_state *lsp;
1289 1291          offset_t offset;
1290 1292          caddr_t bufaddr;
1291 1293          size_t  len;
1292 1294          size_t  xfersize;
1293 1295          boolean_t bufinited = B_FALSE;
1294 1296  
1295 1297          lsp = ddi_get_soft_state(lofi_statep,
1296 1298              LOFI_MINOR2ID(getminor(bp->b_edev)));
1297 1299  
1298 1300          if (lsp == NULL) {
1299 1301                  error = ENXIO;
1300 1302                  goto errout;
1301 1303          }
1302 1304          if (lsp->ls_kstat) {
1303 1305                  mutex_enter(lsp->ls_kstat->ks_lock);
1304 1306                  kstat_waitq_to_runq(KSTAT_IO_PTR(lsp->ls_kstat));
1305 1307                  mutex_exit(lsp->ls_kstat->ks_lock);
1306 1308          }
1307 1309  
1308 1310          mutex_enter(&lsp->ls_vp_lock);
1309 1311          lsp->ls_vp_iocount++;
1310 1312          mutex_exit(&lsp->ls_vp_lock);
1311 1313  
1312 1314          bp_mapin(bp);
1313 1315          bufaddr = bp->b_un.b_addr;
1314 1316          offset = (bp->b_lblkno + (diskaddr_t)(uintptr_t)bp->b_private)
1315 1317              << lsp->ls_lbshift; /* offset within file */
1316 1318          if (lsp->ls_crypto_enabled) {
1317 1319                  /* encrypted data really begins after crypto header */
1318 1320                  offset += lsp->ls_crypto_offset;
1319 1321          }
1320 1322          len = bp->b_bcount;
1321 1323          bufinited = B_TRUE;
1322 1324  
1323 1325          if (lsp->ls_vp == NULL || lsp->ls_vp_closereq) {
1324 1326                  error = EIO;
1325 1327                  goto errout;
1326 1328          }
1327 1329  
1328 1330          /*
1329 1331           * If we're writing and the buffer was not B_ASYNC
1330 1332           * we'll follow up with a VOP_FSYNC() to force any
1331 1333           * asynchronous I/O to stable storage.
1332 1334           */
1333 1335          if (!(bp->b_flags & B_READ) && !(bp->b_flags & B_ASYNC))
1334 1336                  syncflag = FSYNC;
1335 1337  
1336 1338          /*
1337 1339           * We used to always use vn_rdwr here, but we cannot do that because
1338 1340           * we might decide to read or write from the the underlying
1339 1341           * file during this call, which would be a deadlock because
1340 1342           * we have the rw_lock. So instead we page, unless it's not
1341 1343           * mapable or it's a character device or it's an encrypted lofi.
1342 1344           */
1343 1345          if ((lsp->ls_vp->v_flag & VNOMAP) || (lsp->ls_vp->v_type == VCHR) ||
1344 1346              lsp->ls_crypto_enabled) {
1345 1347                  error = lofi_rdwr(bufaddr, offset, bp, lsp, len, RDWR_RAW,
1346 1348                      NULL);
1347 1349          } else if (lsp->ls_uncomp_seg_sz == 0) {
1348 1350                  error = lofi_mapped_rdwr(bufaddr, offset, bp, lsp);
1349 1351          } else {
1350 1352                  uchar_t *compressed_seg = NULL, *cmpbuf;
1351 1353                  uchar_t *uncompressed_seg = NULL;
1352 1354                  lofi_compress_info_t *li;
1353 1355                  size_t oblkcount;
1354 1356                  ulong_t seglen;
1355 1357                  uint64_t sblkno, eblkno, cmpbytes;
1356 1358                  uint64_t uncompressed_seg_index;
1357 1359                  struct lofi_comp_cache *lc;
1358 1360                  offset_t sblkoff, eblkoff;
1359 1361                  u_offset_t salign, ealign;
1360 1362                  u_offset_t sdiff;
1361 1363                  uint32_t comp_data_sz;
1362 1364                  uint64_t i;
1363 1365                  int j;
1364 1366  
1365 1367                  /*
1366 1368                   * From here on we're dealing primarily with compressed files
1367 1369                   */
1368 1370                  ASSERT(!lsp->ls_crypto_enabled);
1369 1371  
1370 1372                  /*
1371 1373                   * Compressed files can only be read from and
1372 1374                   * not written to
1373 1375                   */
1374 1376                  if (!(bp->b_flags & B_READ)) {
1375 1377                          bp->b_resid = bp->b_bcount;
1376 1378                          error = EROFS;
1377 1379                          goto done;
1378 1380                  }
1379 1381  
1380 1382                  ASSERT(lsp->ls_comp_algorithm_index >= 0);
1381 1383                  li = &lofi_compress_table[lsp->ls_comp_algorithm_index];
1382 1384                  /*
1383 1385                   * Compute starting and ending compressed segment numbers
1384 1386                   * We use only bitwise operations avoiding division and
1385 1387                   * modulus because we enforce the compression segment size
1386 1388                   * to a power of 2
1387 1389                   */
1388 1390                  sblkno = offset >> lsp->ls_comp_seg_shift;
1389 1391                  sblkoff = offset & (lsp->ls_uncomp_seg_sz - 1);
1390 1392                  eblkno = (offset + bp->b_bcount) >> lsp->ls_comp_seg_shift;
1391 1393                  eblkoff = (offset + bp->b_bcount) & (lsp->ls_uncomp_seg_sz - 1);
1392 1394  
1393 1395                  /*
1394 1396                   * Check the decompressed segment cache.
1395 1397                   *
1396 1398                   * The cache is used only when the requested data
1397 1399                   * is within a segment. Requests that cross
1398 1400                   * segment boundaries bypass the cache.
1399 1401                   */
1400 1402                  if (sblkno == eblkno ||
1401 1403                      (sblkno + 1 == eblkno && eblkoff == 0)) {
1402 1404                          /*
1403 1405                           * Request doesn't cross a segment boundary,
1404 1406                           * now check the cache.
1405 1407                           */
1406 1408                          mutex_enter(&lsp->ls_comp_cache_lock);
1407 1409                          lc = lofi_find_comp_data(lsp, sblkno);
1408 1410                          if (lc != NULL) {
1409 1411                                  /*
1410 1412                                   * We've found the decompressed segment
1411 1413                                   * data in the cache; reuse it.
1412 1414                                   */
1413 1415                                  bcopy(lc->lc_data + sblkoff, bufaddr,
1414 1416                                      bp->b_bcount);
1415 1417                                  mutex_exit(&lsp->ls_comp_cache_lock);
1416 1418                                  bp->b_resid = 0;
1417 1419                                  error = 0;
1418 1420                                  goto done;
1419 1421                          }
1420 1422                          mutex_exit(&lsp->ls_comp_cache_lock);
1421 1423                  }
1422 1424  
1423 1425                  /*
1424 1426                   * Align start offset to block boundary for segmap
1425 1427                   */
1426 1428                  salign = lsp->ls_comp_seg_index[sblkno];
1427 1429                  sdiff = salign & (DEV_BSIZE - 1);
1428 1430                  salign -= sdiff;
1429 1431                  if (eblkno >= (lsp->ls_comp_index_sz - 1)) {
1430 1432                          /*
1431 1433                           * We're dealing with the last segment of
1432 1434                           * the compressed file -- the size of this
1433 1435                           * segment *may not* be the same as the
1434 1436                           * segment size for the file
1435 1437                           */
1436 1438                          eblkoff = (offset + bp->b_bcount) &
1437 1439                              (lsp->ls_uncomp_last_seg_sz - 1);
1438 1440                          ealign = lsp->ls_vp_comp_size;
1439 1441                  } else {
1440 1442                          ealign = lsp->ls_comp_seg_index[eblkno + 1];
1441 1443                  }
1442 1444  
1443 1445                  /*
1444 1446                   * Preserve original request paramaters
1445 1447                   */
1446 1448                  oblkcount = bp->b_bcount;
1447 1449  
1448 1450                  /*
1449 1451                   * Assign the calculated parameters
1450 1452                   */
1451 1453                  comp_data_sz = ealign - salign;
1452 1454                  bp->b_bcount = comp_data_sz;
1453 1455  
1454 1456                  /*
1455 1457                   * Buffers to hold compressed segments are pre-allocated
1456 1458                   * on a per-thread basis. Find a pre-allocated buffer
1457 1459                   * that is not currently in use and mark it for use.
1458 1460                   */
1459 1461                  mutex_enter(&lsp->ls_comp_bufs_lock);
1460 1462                  for (j = 0; j < lofi_taskq_nthreads; j++) {
1461 1463                          if (lsp->ls_comp_bufs[j].inuse == 0) {
1462 1464                                  lsp->ls_comp_bufs[j].inuse = 1;
1463 1465                                  break;
1464 1466                          }
1465 1467                  }
1466 1468  
1467 1469                  mutex_exit(&lsp->ls_comp_bufs_lock);
1468 1470                  ASSERT(j < lofi_taskq_nthreads);
1469 1471  
1470 1472                  /*
1471 1473                   * If the pre-allocated buffer size does not match
1472 1474                   * the size of the I/O request, re-allocate it with
1473 1475                   * the appropriate size
1474 1476                   */
1475 1477                  if (lsp->ls_comp_bufs[j].bufsize < bp->b_bcount) {
1476 1478                          if (lsp->ls_comp_bufs[j].bufsize > 0)
1477 1479                                  kmem_free(lsp->ls_comp_bufs[j].buf,
1478 1480                                      lsp->ls_comp_bufs[j].bufsize);
1479 1481                          lsp->ls_comp_bufs[j].buf = kmem_alloc(bp->b_bcount,
1480 1482                              KM_SLEEP);
1481 1483                          lsp->ls_comp_bufs[j].bufsize = bp->b_bcount;
1482 1484                  }
1483 1485                  compressed_seg = lsp->ls_comp_bufs[j].buf;
1484 1486  
1485 1487                  /*
1486 1488                   * Map in the calculated number of blocks
1487 1489                   */
1488 1490                  error = lofi_mapped_rdwr((caddr_t)compressed_seg, salign,
1489 1491                      bp, lsp);
1490 1492  
1491 1493                  bp->b_bcount = oblkcount;
1492 1494                  bp->b_resid = oblkcount;
1493 1495                  if (error != 0)
1494 1496                          goto done;
1495 1497  
1496 1498                  /*
1497 1499                   * decompress compressed blocks start
1498 1500                   */
1499 1501                  cmpbuf = compressed_seg + sdiff;
1500 1502                  for (i = sblkno; i <= eblkno; i++) {
1501 1503                          ASSERT(i < lsp->ls_comp_index_sz - 1);
1502 1504                          uchar_t *useg;
1503 1505  
1504 1506                          /*
1505 1507                           * The last segment is special in that it is
1506 1508                           * most likely not going to be the same
1507 1509                           * (uncompressed) size as the other segments.
1508 1510                           */
1509 1511                          if (i == (lsp->ls_comp_index_sz - 2)) {
1510 1512                                  seglen = lsp->ls_uncomp_last_seg_sz;
1511 1513                          } else {
1512 1514                                  seglen = lsp->ls_uncomp_seg_sz;
1513 1515                          }
1514 1516  
1515 1517                          /*
1516 1518                           * Each of the segment index entries contains
1517 1519                           * the starting block number for that segment.
1518 1520                           * The number of compressed bytes in a segment
1519 1521                           * is thus the difference between the starting
1520 1522                           * block number of this segment and the starting
1521 1523                           * block number of the next segment.
1522 1524                           */
1523 1525                          cmpbytes = lsp->ls_comp_seg_index[i + 1] -
1524 1526                              lsp->ls_comp_seg_index[i];
1525 1527  
1526 1528                          /*
1527 1529                           * The first byte in a compressed segment is a flag
1528 1530                           * that indicates whether this segment is compressed
1529 1531                           * at all.
1530 1532                           *
1531 1533                           * The variable 'useg' is used (instead of
1532 1534                           * uncompressed_seg) in this loop to keep a
1533 1535                           * reference to the uncompressed segment.
1534 1536                           *
1535 1537                           * N.B. If 'useg' is replaced with uncompressed_seg,
1536 1538                           * it leads to memory leaks and heap corruption in
1537 1539                           * corner cases where compressed segments lie
1538 1540                           * adjacent to uncompressed segments.
1539 1541                           */
1540 1542                          if (*cmpbuf == UNCOMPRESSED) {
1541 1543                                  useg = cmpbuf + SEGHDR;
1542 1544                          } else {
1543 1545                                  if (uncompressed_seg == NULL)
1544 1546                                          uncompressed_seg =
1545 1547                                              kmem_alloc(lsp->ls_uncomp_seg_sz,
1546 1548                                              KM_SLEEP);
1547 1549                                  useg = uncompressed_seg;
1548 1550                                  uncompressed_seg_index = i;
1549 1551  
1550 1552                                  if (li->l_decompress((cmpbuf + SEGHDR),
1551 1553                                      (cmpbytes - SEGHDR), uncompressed_seg,
1552 1554                                      &seglen, li->l_level) != 0) {
1553 1555                                          error = EIO;
1554 1556                                          goto done;
1555 1557                                  }
1556 1558                          }
1557 1559  
1558 1560                          /*
1559 1561                           * Determine how much uncompressed data we
1560 1562                           * have to copy and copy it
1561 1563                           */
1562 1564                          xfersize = lsp->ls_uncomp_seg_sz - sblkoff;
1563 1565                          if (i == eblkno)
1564 1566                                  xfersize -= (lsp->ls_uncomp_seg_sz - eblkoff);
1565 1567  
1566 1568                          bcopy((useg + sblkoff), bufaddr, xfersize);
1567 1569  
1568 1570                          cmpbuf += cmpbytes;
1569 1571                          bufaddr += xfersize;
1570 1572                          bp->b_resid -= xfersize;
1571 1573                          sblkoff = 0;
1572 1574  
1573 1575                          if (bp->b_resid == 0)
1574 1576                                  break;
1575 1577                  } /* decompress compressed blocks ends */
1576 1578  
1577 1579                  /*
1578 1580                   * Skip to done if there is no uncompressed data to cache
1579 1581                   */
1580 1582                  if (uncompressed_seg == NULL)
1581 1583                          goto done;
1582 1584  
1583 1585                  /*
1584 1586                   * Add the data for the last decompressed segment to
1585 1587                   * the cache.
1586 1588                   *
1587 1589                   * In case the uncompressed segment data was added to (and
1588 1590                   * is referenced by) the cache, make sure we don't free it
1589 1591                   * here.
1590 1592                   */
1591 1593                  mutex_enter(&lsp->ls_comp_cache_lock);
1592 1594                  if ((lc = lofi_add_comp_data(lsp, uncompressed_seg_index,
1593 1595                      uncompressed_seg)) != NULL) {
1594 1596                          uncompressed_seg = NULL;
1595 1597                  }
1596 1598                  mutex_exit(&lsp->ls_comp_cache_lock);
1597 1599  
1598 1600  done:
1599 1601                  if (compressed_seg != NULL) {
1600 1602                          mutex_enter(&lsp->ls_comp_bufs_lock);
1601 1603                          lsp->ls_comp_bufs[j].inuse = 0;
1602 1604                          mutex_exit(&lsp->ls_comp_bufs_lock);
1603 1605                  }
1604 1606                  if (uncompressed_seg != NULL)
1605 1607                          kmem_free(uncompressed_seg, lsp->ls_uncomp_seg_sz);
1606 1608          } /* end of handling compressed files */
1607 1609  
1608 1610          if ((error == 0) && (syncflag != 0))
1609 1611                  error = VOP_FSYNC(lsp->ls_vp, syncflag, kcred, NULL);
1610 1612  
1611 1613  errout:
1612 1614          if (bufinited && lsp->ls_kstat) {
1613 1615                  size_t n_done = bp->b_bcount - bp->b_resid;
1614 1616                  kstat_io_t *kioptr;
1615 1617  
1616 1618                  mutex_enter(lsp->ls_kstat->ks_lock);
1617 1619                  kioptr = KSTAT_IO_PTR(lsp->ls_kstat);
1618 1620                  if (bp->b_flags & B_READ) {
1619 1621                          kioptr->nread += n_done;
1620 1622                          kioptr->reads++;
1621 1623                  } else {
1622 1624                          kioptr->nwritten += n_done;
1623 1625                          kioptr->writes++;
1624 1626                  }
1625 1627                  kstat_runq_exit(kioptr);
1626 1628                  mutex_exit(lsp->ls_kstat->ks_lock);
1627 1629          }
1628 1630  
1629 1631          mutex_enter(&lsp->ls_vp_lock);
1630 1632          if (--lsp->ls_vp_iocount == 0)
1631 1633                  cv_broadcast(&lsp->ls_vp_cv);
1632 1634          mutex_exit(&lsp->ls_vp_lock);
1633 1635  
1634 1636          bioerror(bp, error);
1635 1637          biodone(bp);
1636 1638  }
1637 1639  
1638 1640  static int
1639 1641  lofi_strategy(struct buf *bp)
1640 1642  {
1641 1643          struct lofi_state *lsp;
1642 1644          offset_t        offset;
1643 1645          minor_t         part;
1644 1646          diskaddr_t      p_lba;
1645 1647          diskaddr_t      p_nblks;
1646 1648          int             shift;
1647 1649  
1648 1650          /*
1649 1651           * We cannot just do I/O here, because the current thread
1650 1652           * _might_ end up back in here because the underlying filesystem
1651 1653           * wants a buffer, which eventually gets into bio_recycle and
1652 1654           * might call into lofi to write out a delayed-write buffer.
1653 1655           * This is bad if the filesystem above lofi is the same as below.
1654 1656           *
1655 1657           * We could come up with a complex strategy using threads to
1656 1658           * do the I/O asynchronously, or we could use task queues. task
1657 1659           * queues were incredibly easy so they win.
1658 1660           */
1659 1661  
1660 1662          lsp = ddi_get_soft_state(lofi_statep,
1661 1663              LOFI_MINOR2ID(getminor(bp->b_edev)));
1662 1664          part = LOFI_PART(getminor(bp->b_edev));
1663 1665  
1664 1666          if (lsp == NULL) {
1665 1667                  bioerror(bp, ENXIO);
1666 1668                  biodone(bp);
1667 1669                  return (0);
1668 1670          }
1669 1671  
1670 1672          /* Check if we are closing. */
1671 1673          mutex_enter(&lsp->ls_vp_lock);
1672 1674          if (lsp->ls_vp == NULL || lsp->ls_vp_closereq) {
1673 1675                  mutex_exit(&lsp->ls_vp_lock);
1674 1676                  bioerror(bp, EIO);
1675 1677                  biodone(bp);
1676 1678                  return (0);
1677 1679          }
1678 1680          mutex_exit(&lsp->ls_vp_lock);
1679 1681  
1680 1682          shift = lsp->ls_lbshift;
1681 1683          p_lba = 0;
1682 1684          p_nblks = lsp->ls_vp_size >> shift;
1683 1685  
1684 1686          if (lsp->ls_cmlbhandle != NULL) {
1685 1687                  if (cmlb_partinfo(lsp->ls_cmlbhandle, part, &p_nblks, &p_lba,
1686 1688                      NULL, NULL, 0)) {
1687 1689                          bioerror(bp, ENXIO);
1688 1690                          biodone(bp);
1689 1691                          return (0);
1690 1692                  }
1691 1693          }
1692 1694  
1693 1695          /* start block past partition end? */
1694 1696          if (bp->b_lblkno > p_nblks) {
1695 1697                  bioerror(bp, ENXIO);
1696 1698                  biodone(bp);
1697 1699                  return (0);
1698 1700          }
1699 1701  
1700 1702          offset = (bp->b_lblkno+p_lba) << shift; /* offset within file */
1701 1703  
1702 1704          mutex_enter(&lsp->ls_vp_lock);
1703 1705          if (lsp->ls_crypto_enabled) {
1704 1706                  /* encrypted data really begins after crypto header */
1705 1707                  offset += lsp->ls_crypto_offset;
1706 1708          }
1707 1709  
1708 1710          /* make sure we will not pass the file or partition size */
1709 1711          if (offset == lsp->ls_vp_size ||
1710 1712              offset == (((p_lba + p_nblks) << shift) + lsp->ls_crypto_offset)) {
1711 1713                  /* EOF */
1712 1714                  if ((bp->b_flags & B_READ) != 0) {
1713 1715                          bp->b_resid = bp->b_bcount;
1714 1716                          bioerror(bp, 0);
1715 1717                  } else {
1716 1718                          /* writes should fail */
1717 1719                          bioerror(bp, ENXIO);
1718 1720                  }
1719 1721                  biodone(bp);
1720 1722                  mutex_exit(&lsp->ls_vp_lock);
1721 1723                  return (0);
1722 1724          }
1723 1725          if ((offset > lsp->ls_vp_size) ||
1724 1726              (offset > (((p_lba + p_nblks) << shift) + lsp->ls_crypto_offset)) ||
1725 1727              ((offset + bp->b_bcount) > ((p_lba + p_nblks) << shift))) {
1726 1728                  bioerror(bp, ENXIO);
1727 1729                  biodone(bp);
1728 1730                  mutex_exit(&lsp->ls_vp_lock);
1729 1731                  return (0);
1730 1732          }
1731 1733  
1732 1734          mutex_exit(&lsp->ls_vp_lock);
1733 1735  
  
    | 
      ↓ open down ↓ | 
    1553 lines elided | 
    
      ↑ open up ↑ | 
  
1734 1736          if (lsp->ls_kstat) {
1735 1737                  mutex_enter(lsp->ls_kstat->ks_lock);
1736 1738                  kstat_waitq_enter(KSTAT_IO_PTR(lsp->ls_kstat));
1737 1739                  mutex_exit(lsp->ls_kstat->ks_lock);
1738 1740          }
1739 1741          bp->b_private = (void *)(uintptr_t)p_lba;       /* partition start */
1740 1742          (void) taskq_dispatch(lsp->ls_taskq, lofi_strategy_task, bp, KM_SLEEP);
1741 1743          return (0);
1742 1744  }
1743 1745  
1744      -/*ARGSUSED2*/
1745 1746  static int
1746 1747  lofi_read(dev_t dev, struct uio *uio, struct cred *credp)
1747 1748  {
     1749 +        _NOTE(ARGUNUSED(credp));
     1750 +
1748 1751          if (getminor(dev) == 0)
1749 1752                  return (EINVAL);
1750 1753          UIO_CHECK(uio);
1751 1754          return (physio(lofi_strategy, NULL, dev, B_READ, minphys, uio));
1752 1755  }
1753 1756  
1754      -/*ARGSUSED2*/
1755 1757  static int
1756 1758  lofi_write(dev_t dev, struct uio *uio, struct cred *credp)
1757 1759  {
     1760 +        _NOTE(ARGUNUSED(credp));
     1761 +
1758 1762          if (getminor(dev) == 0)
1759 1763                  return (EINVAL);
1760 1764          UIO_CHECK(uio);
1761 1765          return (physio(lofi_strategy, NULL, dev, B_WRITE, minphys, uio));
1762 1766  }
1763 1767  
     1768 +static int
     1769 +lofi_urw(struct lofi_state *lsp, uint16_t fmode, diskaddr_t off, size_t size,
     1770 +    intptr_t arg, int flag, cred_t *credp)
     1771 +{
     1772 +        struct uio uio;
     1773 +        iovec_t iov;
     1774 +
     1775 +        /*
     1776 +         * 1024 * 1024 apes cmlb_tg_max_efi_xfer as a reasonable max.
     1777 +         */
     1778 +        if (size == 0 || size > 1024 * 1024 ||
     1779 +            (size % (1 << lsp->ls_lbshift)) != 0)
     1780 +                return (EINVAL);
     1781 +
     1782 +        iov.iov_base = (void *)arg;
     1783 +        iov.iov_len = size;
     1784 +        uio.uio_iov = &iov;
     1785 +        uio.uio_iovcnt = 1;
     1786 +        uio.uio_loffset = off;
     1787 +        uio.uio_segflg = (flag & FKIOCTL) ? UIO_SYSSPACE : UIO_USERSPACE;
     1788 +        uio.uio_llimit = MAXOFFSET_T;
     1789 +        uio.uio_resid = size;
     1790 +        uio.uio_fmode = fmode;
     1791 +        uio.uio_extflg = 0;
     1792 +
     1793 +        return (fmode == FREAD ?
     1794 +            lofi_read(lsp->ls_dev, &uio, credp) :
     1795 +            lofi_write(lsp->ls_dev, &uio, credp));
     1796 +}
     1797 +
1764 1798  /*ARGSUSED2*/
1765 1799  static int
1766 1800  lofi_aread(dev_t dev, struct aio_req *aio, struct cred *credp)
1767 1801  {
1768 1802          if (getminor(dev) == 0)
1769 1803                  return (EINVAL);
1770 1804          UIO_CHECK(aio->aio_uio);
1771 1805          return (aphysio(lofi_strategy, anocancel, dev, B_READ, minphys, aio));
1772 1806  }
1773 1807  
1774 1808  /*ARGSUSED2*/
1775 1809  static int
1776 1810  lofi_awrite(dev_t dev, struct aio_req *aio, struct cred *credp)
1777 1811  {
1778 1812          if (getminor(dev) == 0)
1779 1813                  return (EINVAL);
1780 1814          UIO_CHECK(aio->aio_uio);
1781 1815          return (aphysio(lofi_strategy, anocancel, dev, B_WRITE, minphys, aio));
1782 1816  }
1783 1817  
1784 1818  /*ARGSUSED*/
1785 1819  static int
1786 1820  lofi_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result)
1787 1821  {
1788 1822          struct lofi_state *lsp;
1789 1823          dev_t   dev = (dev_t)arg;
1790 1824          int instance;
1791 1825  
1792 1826          instance = LOFI_MINOR2ID(getminor(dev));
1793 1827          switch (infocmd) {
1794 1828          case DDI_INFO_DEVT2DEVINFO:
1795 1829                  lsp = ddi_get_soft_state(lofi_statep, instance);
1796 1830                  if (lsp == NULL)
1797 1831                          return (DDI_FAILURE);
1798 1832                  *result = lsp->ls_dip;
1799 1833                  return (DDI_SUCCESS);
1800 1834          case DDI_INFO_DEVT2INSTANCE:
1801 1835                  *result = (void *) (intptr_t)instance;
1802 1836                  return (DDI_SUCCESS);
1803 1837          }
1804 1838          return (DDI_FAILURE);
1805 1839  }
1806 1840  
1807 1841  static int
1808 1842  lofi_create_minor_nodes(struct lofi_state *lsp, boolean_t labeled)
1809 1843  {
1810 1844          int error = 0;
1811 1845          int instance = ddi_get_instance(lsp->ls_dip);
1812 1846  
1813 1847          if (labeled == B_TRUE) {
1814 1848                  cmlb_alloc_handle(&lsp->ls_cmlbhandle);
1815 1849                  error = cmlb_attach(lsp->ls_dip, &lofi_tg_ops, DTYPE_DIRECT,
1816 1850                      B_FALSE, B_FALSE, DDI_NT_BLOCK_CHAN,
1817 1851                      CMLB_CREATE_P0_MINOR_NODE, lsp->ls_cmlbhandle, (void *)1);
1818 1852  
1819 1853                  if (error != DDI_SUCCESS) {
1820 1854                          cmlb_free_handle(&lsp->ls_cmlbhandle);
1821 1855                          lsp->ls_cmlbhandle = NULL;
1822 1856                          error = ENXIO;
1823 1857                  }
1824 1858          } else {
1825 1859                  /* create minor nodes */
1826 1860                  error = ddi_create_minor_node(lsp->ls_dip, LOFI_BLOCK_NODE,
1827 1861                      S_IFBLK, LOFI_ID2MINOR(instance), DDI_PSEUDO, 0);
1828 1862                  if (error == DDI_SUCCESS) {
1829 1863                          error = ddi_create_minor_node(lsp->ls_dip,
1830 1864                              LOFI_CHAR_NODE, S_IFCHR, LOFI_ID2MINOR(instance),
1831 1865                              DDI_PSEUDO, 0);
1832 1866                          if (error != DDI_SUCCESS) {
1833 1867                                  ddi_remove_minor_node(lsp->ls_dip,
1834 1868                                      LOFI_BLOCK_NODE);
1835 1869                                  error = ENXIO;
1836 1870                          }
1837 1871                  } else
1838 1872                          error = ENXIO;
1839 1873          }
1840 1874          return (error);
1841 1875  }
1842 1876  
1843 1877  static int
1844 1878  lofi_zone_bind(struct lofi_state *lsp)
1845 1879  {
1846 1880          int error = 0;
1847 1881  
1848 1882          mutex_enter(&curproc->p_lock);
1849 1883          if ((error = rctl_incr_lofi(curproc, curproc->p_zone, 1)) != 0) {
1850 1884                  mutex_exit(&curproc->p_lock);
1851 1885                  return (error);
1852 1886          }
1853 1887          mutex_exit(&curproc->p_lock);
1854 1888  
1855 1889          if (ddi_prop_update_string(DDI_DEV_T_NONE, lsp->ls_dip, ZONE_PROP_NAME,
1856 1890              (char *)curproc->p_zone->zone_name) != DDI_PROP_SUCCESS) {
1857 1891                  rctl_decr_lofi(curproc->p_zone, 1);
1858 1892                  error = EINVAL;
1859 1893          } else {
1860 1894                  zone_init_ref(&lsp->ls_zone);
1861 1895                  zone_hold_ref(curzone, &lsp->ls_zone, ZONE_REF_LOFI);
1862 1896          }
1863 1897          return (error);
1864 1898  }
1865 1899  
1866 1900  static void
1867 1901  lofi_zone_unbind(struct lofi_state *lsp)
1868 1902  {
1869 1903          (void) ddi_prop_remove(DDI_DEV_T_NONE, lsp->ls_dip, ZONE_PROP_NAME);
1870 1904          rctl_decr_lofi(curproc->p_zone, 1);
1871 1905          zone_rele_ref(&lsp->ls_zone, ZONE_REF_LOFI);
1872 1906  }
1873 1907  
1874 1908  static int
1875 1909  lofi_online_dev(dev_info_t *dip)
1876 1910  {
1877 1911          boolean_t labeled;
1878 1912          int     error;
1879 1913          int     instance = ddi_get_instance(dip);
1880 1914          struct lofi_state *lsp;
1881 1915  
1882 1916          labeled = B_FALSE;
1883 1917          if (ddi_prop_exists(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, "labeled"))
1884 1918                  labeled = B_TRUE;
1885 1919  
1886 1920          /* lsp alloc+init, soft state is freed in lofi_detach */
1887 1921          error = ddi_soft_state_zalloc(lofi_statep, instance);
1888 1922          if (error == DDI_FAILURE) {
1889 1923                  return (ENOMEM);
1890 1924          }
1891 1925  
1892 1926          lsp = ddi_get_soft_state(lofi_statep, instance);
1893 1927          lsp->ls_dip = dip;
1894 1928  
1895 1929          if ((error = lofi_zone_bind(lsp)) != 0)
1896 1930                  goto err;
1897 1931  
1898 1932          cv_init(&lsp->ls_vp_cv, NULL, CV_DRIVER, NULL);
1899 1933          mutex_init(&lsp->ls_comp_cache_lock, NULL, MUTEX_DRIVER, NULL);
1900 1934          mutex_init(&lsp->ls_comp_bufs_lock, NULL, MUTEX_DRIVER, NULL);
1901 1935          mutex_init(&lsp->ls_kstat_lock, NULL, MUTEX_DRIVER, NULL);
1902 1936          mutex_init(&lsp->ls_vp_lock, NULL, MUTEX_DRIVER, NULL);
1903 1937  
1904 1938          if ((error = lofi_create_minor_nodes(lsp, labeled)) != 0) {
1905 1939                  lofi_zone_unbind(lsp);
1906 1940                  goto lerr;
1907 1941          }
1908 1942  
1909 1943          /* driver handles kernel-issued IOCTLs */
1910 1944          if (ddi_prop_create(DDI_DEV_T_NONE, dip, DDI_PROP_CANSLEEP,
1911 1945              DDI_KERNEL_IOCTL, NULL, 0) != DDI_PROP_SUCCESS) {
1912 1946                  error = DDI_FAILURE;
1913 1947                  goto merr;
1914 1948          }
1915 1949  
1916 1950          lsp->ls_kstat = kstat_create_zone(LOFI_DRIVER_NAME, instance,
1917 1951              NULL, "disk", KSTAT_TYPE_IO, 1, 0, getzoneid());
1918 1952          if (lsp->ls_kstat == NULL) {
1919 1953                  (void) ddi_prop_remove(DDI_DEV_T_NONE, lsp->ls_dip,
1920 1954                      DDI_KERNEL_IOCTL);
1921 1955                  error = ENOMEM;
1922 1956                  goto merr;
1923 1957          }
1924 1958  
1925 1959          lsp->ls_kstat->ks_lock = &lsp->ls_kstat_lock;
1926 1960          kstat_zone_add(lsp->ls_kstat, GLOBAL_ZONEID);
1927 1961          kstat_install(lsp->ls_kstat);
1928 1962          return (DDI_SUCCESS);
1929 1963  merr:
1930 1964          if (lsp->ls_cmlbhandle != NULL) {
1931 1965                  cmlb_detach(lsp->ls_cmlbhandle, 0);
1932 1966                  cmlb_free_handle(&lsp->ls_cmlbhandle);
1933 1967          }
1934 1968          ddi_remove_minor_node(dip, NULL);
1935 1969          lofi_zone_unbind(lsp);
1936 1970  lerr:
1937 1971          mutex_destroy(&lsp->ls_comp_cache_lock);
1938 1972          mutex_destroy(&lsp->ls_comp_bufs_lock);
1939 1973          mutex_destroy(&lsp->ls_kstat_lock);
1940 1974          mutex_destroy(&lsp->ls_vp_lock);
1941 1975          cv_destroy(&lsp->ls_vp_cv);
1942 1976  err:
1943 1977          ddi_soft_state_free(lofi_statep, instance);
1944 1978          return (error);
1945 1979  }
1946 1980  
1947 1981  static int
1948 1982  lofi_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
1949 1983  {
1950 1984          int     rv;
1951 1985          int     instance = ddi_get_instance(dip);
1952 1986          struct lofi_state *lsp;
1953 1987  
1954 1988          if (cmd != DDI_ATTACH)
1955 1989                  return (DDI_FAILURE);
1956 1990  
1957 1991          /*
1958 1992           * Instance 0 is control instance, attaching control instance
1959 1993           * will set the lofi up and ready.
1960 1994           */
1961 1995          if (instance == 0) {
1962 1996                  rv = ddi_soft_state_zalloc(lofi_statep, 0);
1963 1997                  if (rv == DDI_FAILURE) {
1964 1998                          return (DDI_FAILURE);
1965 1999                  }
1966 2000                  lsp = ddi_get_soft_state(lofi_statep, instance);
1967 2001                  rv = ddi_create_minor_node(dip, LOFI_CTL_NODE, S_IFCHR, 0,
1968 2002                      DDI_PSEUDO, 0);
1969 2003                  if (rv == DDI_FAILURE) {
1970 2004                          ddi_soft_state_free(lofi_statep, 0);
1971 2005                          return (DDI_FAILURE);
1972 2006                  }
1973 2007                  /* driver handles kernel-issued IOCTLs */
1974 2008                  if (ddi_prop_create(DDI_DEV_T_NONE, dip, DDI_PROP_CANSLEEP,
1975 2009                      DDI_KERNEL_IOCTL, NULL, 0) != DDI_PROP_SUCCESS) {
1976 2010                          ddi_remove_minor_node(dip, NULL);
1977 2011                          ddi_soft_state_free(lofi_statep, 0);
1978 2012                          return (DDI_FAILURE);
1979 2013                  }
1980 2014  
1981 2015                  zone_key_create(&lofi_zone_key, NULL, lofi_zone_shutdown, NULL);
1982 2016  
1983 2017                  lsp->ls_dip = dip;
1984 2018          } else {
1985 2019                  if (lofi_online_dev(dip) == DDI_FAILURE)
1986 2020                          return (DDI_FAILURE);
1987 2021          }
1988 2022  
1989 2023          ddi_report_dev(dip);
1990 2024          return (DDI_SUCCESS);
1991 2025  }
1992 2026  
1993 2027  static int
1994 2028  lofi_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
1995 2029  {
1996 2030          struct lofi_state *lsp;
1997 2031          int instance = ddi_get_instance(dip);
1998 2032  
1999 2033          if (cmd != DDI_DETACH)
2000 2034                  return (DDI_FAILURE);
2001 2035  
2002 2036          /*
2003 2037           * If the instance is not 0, release state.
2004 2038           * The instance 0 is control device, we can not detach it
2005 2039           * before other instances are detached.
2006 2040           */
2007 2041          if (instance != 0) {
2008 2042                  lsp = ddi_get_soft_state(lofi_statep, instance);
2009 2043                  if (lsp != NULL && lsp->ls_vp_ready == B_FALSE) {
2010 2044                          ddi_soft_state_free(lofi_statep, instance);
2011 2045                          return (DDI_SUCCESS);
2012 2046                  } else
2013 2047                          return (DDI_FAILURE);
2014 2048          }
2015 2049          mutex_enter(&lofi_lock);
2016 2050  
2017 2051          if (!list_is_empty(&lofi_list)) {
2018 2052                  mutex_exit(&lofi_lock);
2019 2053                  return (DDI_FAILURE);
2020 2054          }
2021 2055  
2022 2056          ddi_remove_minor_node(dip, NULL);
2023 2057          ddi_prop_remove_all(dip);
2024 2058  
2025 2059          mutex_exit(&lofi_lock);
2026 2060  
2027 2061          if (zone_key_delete(lofi_zone_key) != 0)
2028 2062                  cmn_err(CE_WARN, "failed to delete zone key");
2029 2063  
2030 2064          ddi_soft_state_free(lofi_statep, 0);
2031 2065  
2032 2066          return (DDI_SUCCESS);
2033 2067  }
2034 2068  
2035 2069  /*
2036 2070   * With the addition of encryption, we must be careful that encryption key is
2037 2071   * wiped before kernel's data structures are freed so it cannot accidentally
2038 2072   * slip out to userland through uninitialized data elsewhere.
2039 2073   */
2040 2074  static void
2041 2075  free_lofi_ioctl(struct lofi_ioctl *klip)
2042 2076  {
2043 2077          /* Make sure this encryption key doesn't stick around */
2044 2078          bzero(klip->li_key, sizeof (klip->li_key));
2045 2079          kmem_free(klip, sizeof (struct lofi_ioctl));
2046 2080  }
2047 2081  
2048 2082  /*
2049 2083   * These two functions simplify the rest of the ioctls that need to copyin/out
2050 2084   * the lofi_ioctl structure.
2051 2085   */
2052 2086  int
2053 2087  copy_in_lofi_ioctl(const struct lofi_ioctl *ulip, struct lofi_ioctl **klipp,
2054 2088      int flag)
2055 2089  {
2056 2090          struct lofi_ioctl *klip;
2057 2091          int     error;
2058 2092  
2059 2093          klip = *klipp = kmem_alloc(sizeof (struct lofi_ioctl), KM_SLEEP);
2060 2094          error = ddi_copyin(ulip, klip, sizeof (struct lofi_ioctl), flag);
2061 2095          if (error)
2062 2096                  goto err;
2063 2097  
2064 2098          /* ensure NULL termination */
2065 2099          klip->li_filename[MAXPATHLEN-1] = '\0';
2066 2100          klip->li_devpath[MAXPATHLEN-1] = '\0';
2067 2101          klip->li_algorithm[MAXALGLEN-1] = '\0';
2068 2102          klip->li_cipher[CRYPTO_MAX_MECH_NAME-1] = '\0';
2069 2103          klip->li_iv_cipher[CRYPTO_MAX_MECH_NAME-1] = '\0';
2070 2104  
2071 2105          if (klip->li_id > L_MAXMIN32) {
2072 2106                  error = EINVAL;
2073 2107                  goto err;
2074 2108          }
2075 2109  
2076 2110          return (0);
2077 2111  
2078 2112  err:
2079 2113          free_lofi_ioctl(klip);
2080 2114          return (error);
2081 2115  }
2082 2116  
2083 2117  int
2084 2118  copy_out_lofi_ioctl(const struct lofi_ioctl *klip, struct lofi_ioctl *ulip,
2085 2119      int flag)
2086 2120  {
2087 2121          int     error;
2088 2122  
2089 2123          /*
2090 2124           * NOTE: Do NOT copy the crypto_key_t "back" to userland.
2091 2125           * This ensures that an attacker can't trivially find the
2092 2126           * key for a mapping just by issuing the ioctl.
2093 2127           *
2094 2128           * It can still be found by poking around in kmem with mdb(1),
2095 2129           * but there is no point in making it easy when the info isn't
2096 2130           * of any use in this direction anyway.
2097 2131           *
2098 2132           * Either way we don't actually have the raw key stored in
2099 2133           * a form that we can get it anyway, since we just used it
2100 2134           * to create a ctx template and didn't keep "the original".
2101 2135           */
2102 2136          error = ddi_copyout(klip, ulip, sizeof (struct lofi_ioctl), flag);
2103 2137          if (error)
2104 2138                  return (EFAULT);
2105 2139          return (0);
2106 2140  }
2107 2141  
2108 2142  static int
2109 2143  lofi_access(struct lofi_state *lsp)
2110 2144  {
2111 2145          ASSERT(MUTEX_HELD(&lofi_lock));
2112 2146          if (INGLOBALZONE(curproc) || lsp->ls_zone.zref_zone == curzone)
2113 2147                  return (0);
2114 2148          return (EPERM);
2115 2149  }
2116 2150  
2117 2151  /*
2118 2152   * Find the lofi state for the given filename. We compare by vnode to
2119 2153   * allow the global zone visibility into NGZ lofi nodes.
2120 2154   */
2121 2155  static int
2122 2156  file_to_lofi_nocheck(char *filename, boolean_t readonly,
2123 2157      struct lofi_state **lspp)
2124 2158  {
2125 2159          struct lofi_state *lsp;
2126 2160          vnode_t *vp = NULL;
2127 2161          int err = 0;
2128 2162          int rdfiles = 0;
2129 2163  
2130 2164          ASSERT(MUTEX_HELD(&lofi_lock));
2131 2165  
2132 2166          if ((err = lookupname(filename, UIO_SYSSPACE, FOLLOW,
2133 2167              NULLVPP, &vp)) != 0)
2134 2168                  goto out;
2135 2169  
2136 2170          if (vp->v_type == VREG) {
2137 2171                  vnode_t *realvp;
2138 2172                  if (VOP_REALVP(vp, &realvp, NULL) == 0) {
2139 2173                          VN_HOLD(realvp);
2140 2174                          VN_RELE(vp);
2141 2175                          vp = realvp;
2142 2176                  }
2143 2177          }
2144 2178  
2145 2179          for (lsp = list_head(&lofi_list); lsp != NULL;
2146 2180              lsp = list_next(&lofi_list, lsp)) {
2147 2181                  if (lsp->ls_vp == vp) {
2148 2182                          if (lspp != NULL)
2149 2183                                  *lspp = lsp;
2150 2184                          if (lsp->ls_readonly) {
2151 2185                                  rdfiles++;
2152 2186                                  /* Skip if '-r' is specified */
2153 2187                                  if (readonly)
2154 2188                                          continue;
2155 2189                          }
2156 2190                          goto out;
2157 2191                  }
2158 2192          }
2159 2193  
2160 2194          err = ENOENT;
2161 2195  
2162 2196          /*
2163 2197           * If a filename is given as an argument for lofi_unmap, we shouldn't
2164 2198           * allow unmap if there are multiple read-only lofi devices associated
2165 2199           * with this file.
2166 2200           */
2167 2201          if (lspp != NULL) {
2168 2202                  if (rdfiles == 1)
2169 2203                          err = 0;
2170 2204                  else if (rdfiles > 1)
2171 2205                          err = EBUSY;
2172 2206          }
2173 2207  
2174 2208  out:
2175 2209          if (vp != NULL)
2176 2210                  VN_RELE(vp);
2177 2211          return (err);
2178 2212  }
2179 2213  
2180 2214  /*
2181 2215   * Find the minor for the given filename, checking the zone can access
2182 2216   * it.
2183 2217   */
2184 2218  static int
2185 2219  file_to_lofi(char *filename, boolean_t readonly, struct lofi_state **lspp)
2186 2220  {
2187 2221          int err = 0;
2188 2222  
2189 2223          ASSERT(MUTEX_HELD(&lofi_lock));
2190 2224  
2191 2225          if ((err = file_to_lofi_nocheck(filename, readonly, lspp)) != 0)
2192 2226                  return (err);
2193 2227  
2194 2228          if ((err = lofi_access(*lspp)) != 0)
2195 2229                  return (err);
2196 2230  
2197 2231          return (0);
2198 2232  }
2199 2233  
2200 2234  /*
2201 2235   * Fakes up a disk geometry based on the size of the file. This is needed
2202 2236   * to support newfs on traditional lofi device, but also will provide
2203 2237   * geometry hint for cmlb.
2204 2238   */
2205 2239  static void
2206 2240  fake_disk_geometry(struct lofi_state *lsp)
2207 2241  {
2208 2242          u_offset_t dsize = lsp->ls_vp_size - lsp->ls_crypto_offset;
2209 2243  
2210 2244          /* dk_geom - see dkio(7I) */
2211 2245          /*
2212 2246           * dkg_ncyl _could_ be set to one here (one big cylinder with gobs
2213 2247           * of sectors), but that breaks programs like fdisk which want to
2214 2248           * partition a disk by cylinder. With one cylinder, you can't create
2215 2249           * an fdisk partition and put pcfs on it for testing (hard to pick
2216 2250           * a number between one and one).
2217 2251           *
2218 2252           * The cheezy floppy test is an attempt to not have too few cylinders
2219 2253           * for a small file, or so many on a big file that you waste space
2220 2254           * for backup superblocks or cylinder group structures.
2221 2255           */
2222 2256          bzero(&lsp->ls_dkg, sizeof (lsp->ls_dkg));
2223 2257          if (dsize < (2 * 1024 * 1024)) /* floppy? */
2224 2258                  lsp->ls_dkg.dkg_ncyl = dsize / (100 * 1024);
2225 2259          else
2226 2260                  lsp->ls_dkg.dkg_ncyl = dsize / (300 * 1024);
2227 2261          /* in case file file is < 100k */
2228 2262          if (lsp->ls_dkg.dkg_ncyl == 0)
2229 2263                  lsp->ls_dkg.dkg_ncyl = 1;
2230 2264  
2231 2265          lsp->ls_dkg.dkg_pcyl = lsp->ls_dkg.dkg_ncyl;
2232 2266          lsp->ls_dkg.dkg_nhead = 1;
2233 2267          lsp->ls_dkg.dkg_rpm = 7200;
2234 2268  
2235 2269          lsp->ls_dkg.dkg_nsect = dsize /
2236 2270              (lsp->ls_dkg.dkg_ncyl << lsp->ls_pbshift);
2237 2271  }
2238 2272  
2239 2273  /*
2240 2274   * build vtoc - see dkio(7I)
2241 2275   *
2242 2276   * Fakes one big partition based on the size of the file. This is needed
2243 2277   * because we allow newfs'ing the traditional lofi device and newfs will
2244 2278   * do several disk ioctls to figure out the geometry and partition information.
2245 2279   * It uses that information to determine the parameters to pass to mkfs.
2246 2280   */
2247 2281  static void
2248 2282  fake_disk_vtoc(struct lofi_state *lsp, struct vtoc *vt)
2249 2283  {
2250 2284          bzero(vt, sizeof (struct vtoc));
2251 2285          vt->v_sanity = VTOC_SANE;
2252 2286          vt->v_version = V_VERSION;
2253 2287          (void) strncpy(vt->v_volume, LOFI_DRIVER_NAME,
2254 2288              sizeof (vt->v_volume));
2255 2289          vt->v_sectorsz = 1 << lsp->ls_pbshift;
2256 2290          vt->v_nparts = 1;
2257 2291          vt->v_part[0].p_tag = V_UNASSIGNED;
2258 2292  
2259 2293          /*
2260 2294           * A compressed file is read-only, other files can
2261 2295           * be read-write
2262 2296           */
2263 2297          if (lsp->ls_uncomp_seg_sz > 0) {
2264 2298                  vt->v_part[0].p_flag = V_UNMNT | V_RONLY;
2265 2299          } else {
2266 2300                  vt->v_part[0].p_flag = V_UNMNT;
2267 2301          }
2268 2302          vt->v_part[0].p_start = (daddr_t)0;
2269 2303          /*
2270 2304           * The partition size cannot just be the number of sectors, because
2271 2305           * that might not end on a cylinder boundary. And if that's the case,
2272 2306           * newfs/mkfs will print a scary warning. So just figure the size
2273 2307           * based on the number of cylinders and sectors/cylinder.
2274 2308           */
2275 2309          vt->v_part[0].p_size = lsp->ls_dkg.dkg_pcyl *
2276 2310              lsp->ls_dkg.dkg_nsect * lsp->ls_dkg.dkg_nhead;
2277 2311  }
2278 2312  
2279 2313  /*
2280 2314   * build dk_cinfo - see dkio(7I)
2281 2315   */
2282 2316  static void
2283 2317  fake_disk_info(dev_t dev, struct dk_cinfo *ci)
2284 2318  {
2285 2319          bzero(ci, sizeof (struct dk_cinfo));
2286 2320          (void) strlcpy(ci->dki_cname, LOFI_DRIVER_NAME, sizeof (ci->dki_cname));
2287 2321          ci->dki_ctype = DKC_SCSI_CCS;
2288 2322          (void) strlcpy(ci->dki_dname, LOFI_DRIVER_NAME, sizeof (ci->dki_dname));
2289 2323          ci->dki_unit = LOFI_MINOR2ID(getminor(dev));
2290 2324          ci->dki_partition = LOFI_PART(getminor(dev));
2291 2325          /*
2292 2326           * newfs uses this to set maxcontig. Must not be < 16, or it
2293 2327           * will be 0 when newfs multiplies it by DEV_BSIZE and divides
2294 2328           * it by the block size. Then tunefs doesn't work because
2295 2329           * maxcontig is 0.
2296 2330           */
2297 2331          ci->dki_maxtransfer = 16;
2298 2332  }
2299 2333  
2300 2334  /*
2301 2335   * map in a compressed file
2302 2336   *
2303 2337   * Read in the header and the index that follows.
2304 2338   *
2305 2339   * The header is as follows -
2306 2340   *
2307 2341   * Signature (name of the compression algorithm)
2308 2342   * Compression segment size (a multiple of 512)
2309 2343   * Number of index entries
2310 2344   * Size of the last block
2311 2345   * The array containing the index entries
2312 2346   *
2313 2347   * The header information is always stored in
2314 2348   * network byte order on disk.
2315 2349   */
2316 2350  static int
2317 2351  lofi_map_compressed_file(struct lofi_state *lsp, char *buf)
2318 2352  {
2319 2353          uint32_t index_sz, header_len, i;
2320 2354          ssize_t resid;
2321 2355          enum uio_rw rw;
2322 2356          char *tbuf = buf;
2323 2357          int error;
2324 2358  
2325 2359          /* The signature has already been read */
2326 2360          tbuf += sizeof (lsp->ls_comp_algorithm);
2327 2361          bcopy(tbuf, &(lsp->ls_uncomp_seg_sz), sizeof (lsp->ls_uncomp_seg_sz));
2328 2362          lsp->ls_uncomp_seg_sz = ntohl(lsp->ls_uncomp_seg_sz);
2329 2363  
2330 2364          /*
2331 2365           * The compressed segment size must be a power of 2
2332 2366           */
2333 2367          if (lsp->ls_uncomp_seg_sz < DEV_BSIZE ||
2334 2368              !ISP2(lsp->ls_uncomp_seg_sz))
2335 2369                  return (EINVAL);
2336 2370  
2337 2371          for (i = 0; !((lsp->ls_uncomp_seg_sz >> i) & 1); i++)
2338 2372                  ;
2339 2373  
2340 2374          lsp->ls_comp_seg_shift = i;
2341 2375  
2342 2376          tbuf += sizeof (lsp->ls_uncomp_seg_sz);
2343 2377          bcopy(tbuf, &(lsp->ls_comp_index_sz), sizeof (lsp->ls_comp_index_sz));
2344 2378          lsp->ls_comp_index_sz = ntohl(lsp->ls_comp_index_sz);
2345 2379  
2346 2380          tbuf += sizeof (lsp->ls_comp_index_sz);
2347 2381          bcopy(tbuf, &(lsp->ls_uncomp_last_seg_sz),
2348 2382              sizeof (lsp->ls_uncomp_last_seg_sz));
2349 2383          lsp->ls_uncomp_last_seg_sz = ntohl(lsp->ls_uncomp_last_seg_sz);
2350 2384  
2351 2385          /*
2352 2386           * Compute the total size of the uncompressed data
2353 2387           * for use in fake_disk_geometry and other calculations.
2354 2388           * Disk geometry has to be faked with respect to the
2355 2389           * actual uncompressed data size rather than the
2356 2390           * compressed file size.
2357 2391           */
2358 2392          lsp->ls_vp_size =
2359 2393              (u_offset_t)(lsp->ls_comp_index_sz - 2) * lsp->ls_uncomp_seg_sz
2360 2394              + lsp->ls_uncomp_last_seg_sz;
2361 2395  
2362 2396          /*
2363 2397           * Index size is rounded up to DEV_BSIZE for ease
2364 2398           * of segmapping
2365 2399           */
2366 2400          index_sz = sizeof (*lsp->ls_comp_seg_index) * lsp->ls_comp_index_sz;
2367 2401          header_len = sizeof (lsp->ls_comp_algorithm) +
2368 2402              sizeof (lsp->ls_uncomp_seg_sz) +
2369 2403              sizeof (lsp->ls_comp_index_sz) +
2370 2404              sizeof (lsp->ls_uncomp_last_seg_sz);
2371 2405          lsp->ls_comp_offbase = header_len + index_sz;
2372 2406  
2373 2407          index_sz += header_len;
2374 2408          index_sz = roundup(index_sz, DEV_BSIZE);
2375 2409  
2376 2410          lsp->ls_comp_index_data = kmem_alloc(index_sz, KM_SLEEP);
2377 2411          lsp->ls_comp_index_data_sz = index_sz;
2378 2412  
2379 2413          /*
2380 2414           * Read in the index -- this has a side-effect
2381 2415           * of reading in the header as well
2382 2416           */
2383 2417          rw = UIO_READ;
2384 2418          error = vn_rdwr(rw, lsp->ls_vp, lsp->ls_comp_index_data, index_sz,
2385 2419              0, UIO_SYSSPACE, 0, RLIM64_INFINITY, kcred, &resid);
2386 2420  
2387 2421          if (error != 0)
2388 2422                  return (error);
2389 2423  
2390 2424          /* Skip the header, this is where the index really begins */
2391 2425          lsp->ls_comp_seg_index =
2392 2426              /*LINTED*/
2393 2427              (uint64_t *)(lsp->ls_comp_index_data + header_len);
2394 2428  
2395 2429          /*
2396 2430           * Now recompute offsets in the index to account for
2397 2431           * the header length
2398 2432           */
2399 2433          for (i = 0; i < lsp->ls_comp_index_sz; i++) {
2400 2434                  lsp->ls_comp_seg_index[i] = lsp->ls_comp_offbase +
2401 2435                      BE_64(lsp->ls_comp_seg_index[i]);
2402 2436          }
2403 2437  
2404 2438          return (error);
2405 2439  }
2406 2440  
2407 2441  static int
2408 2442  lofi_init_crypto(struct lofi_state *lsp, struct lofi_ioctl *klip)
2409 2443  {
2410 2444          struct crypto_meta chead;
2411 2445          char buf[DEV_BSIZE];
2412 2446          ssize_t resid;
2413 2447          char *marker;
2414 2448          int error;
2415 2449          int ret;
2416 2450          int i;
2417 2451  
2418 2452          if (!klip->li_crypto_enabled)
2419 2453                  return (0);
2420 2454  
2421 2455          /*
2422 2456           * All current algorithms have a max of 448 bits.
2423 2457           */
2424 2458          if (klip->li_iv_len > CRYPTO_BITS2BYTES(512))
2425 2459                  return (EINVAL);
2426 2460  
2427 2461          if (CRYPTO_BITS2BYTES(klip->li_key_len) > sizeof (klip->li_key))
2428 2462                  return (EINVAL);
2429 2463  
2430 2464          lsp->ls_crypto_enabled = klip->li_crypto_enabled;
2431 2465  
2432 2466          mutex_init(&lsp->ls_crypto_lock, NULL, MUTEX_DRIVER, NULL);
2433 2467  
2434 2468          lsp->ls_mech.cm_type = crypto_mech2id(klip->li_cipher);
2435 2469          if (lsp->ls_mech.cm_type == CRYPTO_MECH_INVALID) {
2436 2470                  cmn_err(CE_WARN, "invalid cipher %s requested for %s",
2437 2471                      klip->li_cipher, klip->li_filename);
2438 2472                  return (EINVAL);
2439 2473          }
2440 2474  
2441 2475          /* this is just initialization here */
2442 2476          lsp->ls_mech.cm_param = NULL;
2443 2477          lsp->ls_mech.cm_param_len = 0;
2444 2478  
2445 2479          lsp->ls_iv_type = klip->li_iv_type;
2446 2480          lsp->ls_iv_mech.cm_type = crypto_mech2id(klip->li_iv_cipher);
2447 2481          if (lsp->ls_iv_mech.cm_type == CRYPTO_MECH_INVALID) {
2448 2482                  cmn_err(CE_WARN, "invalid iv cipher %s requested"
2449 2483                      " for %s", klip->li_iv_cipher, klip->li_filename);
2450 2484                  return (EINVAL);
2451 2485          }
2452 2486  
2453 2487          /* iv mech must itself take a null iv */
2454 2488          lsp->ls_iv_mech.cm_param = NULL;
2455 2489          lsp->ls_iv_mech.cm_param_len = 0;
2456 2490          lsp->ls_iv_len = klip->li_iv_len;
2457 2491  
2458 2492          /*
2459 2493           * Create ctx using li_cipher & the raw li_key after checking
2460 2494           * that it isn't a weak key.
2461 2495           */
2462 2496          lsp->ls_key.ck_format = CRYPTO_KEY_RAW;
2463 2497          lsp->ls_key.ck_length = klip->li_key_len;
2464 2498          lsp->ls_key.ck_data = kmem_alloc(
2465 2499              CRYPTO_BITS2BYTES(lsp->ls_key.ck_length), KM_SLEEP);
2466 2500          bcopy(klip->li_key, lsp->ls_key.ck_data,
2467 2501              CRYPTO_BITS2BYTES(lsp->ls_key.ck_length));
2468 2502  
2469 2503          ret = crypto_key_check(&lsp->ls_mech, &lsp->ls_key);
2470 2504          if (ret != CRYPTO_SUCCESS) {
2471 2505                  cmn_err(CE_WARN, "weak key check failed for cipher "
2472 2506                      "%s on file %s (0x%x)", klip->li_cipher,
2473 2507                      klip->li_filename, ret);
2474 2508                  return (EINVAL);
2475 2509          }
2476 2510  
2477 2511          error = vn_rdwr(UIO_READ, lsp->ls_vp, buf, DEV_BSIZE,
2478 2512              CRYOFF, UIO_SYSSPACE, 0, RLIM64_INFINITY, kcred, &resid);
2479 2513          if (error != 0)
2480 2514                  return (error);
2481 2515  
2482 2516          /*
2483 2517           * This is the case where the header in the lofi image is already
2484 2518           * initialized to indicate it is encrypted.
2485 2519           */
2486 2520          if (strncmp(buf, lofi_crypto_magic, sizeof (lofi_crypto_magic)) == 0) {
2487 2521                  /*
2488 2522                   * The encryption header information is laid out this way:
2489 2523                   *      6 bytes:        hex "CFLOFI"
2490 2524                   *      2 bytes:        version = 0 ... for now
2491 2525                   *      96 bytes:       reserved1 (not implemented yet)
2492 2526                   *      4 bytes:        data_sector = 2 ... for now
2493 2527                   *      more...         not implemented yet
2494 2528                   */
2495 2529  
2496 2530                  marker = buf;
2497 2531  
2498 2532                  /* copy the magic */
2499 2533                  bcopy(marker, lsp->ls_crypto.magic,
2500 2534                      sizeof (lsp->ls_crypto.magic));
2501 2535                  marker += sizeof (lsp->ls_crypto.magic);
2502 2536  
2503 2537                  /* read the encryption version number */
2504 2538                  bcopy(marker, &(lsp->ls_crypto.version),
2505 2539                      sizeof (lsp->ls_crypto.version));
2506 2540                  lsp->ls_crypto.version = ntohs(lsp->ls_crypto.version);
2507 2541                  marker += sizeof (lsp->ls_crypto.version);
2508 2542  
2509 2543                  /* read a chunk of reserved data */
2510 2544                  bcopy(marker, lsp->ls_crypto.reserved1,
2511 2545                      sizeof (lsp->ls_crypto.reserved1));
2512 2546                  marker += sizeof (lsp->ls_crypto.reserved1);
2513 2547  
2514 2548                  /* read block number where encrypted data begins */
2515 2549                  bcopy(marker, &(lsp->ls_crypto.data_sector),
2516 2550                      sizeof (lsp->ls_crypto.data_sector));
2517 2551                  lsp->ls_crypto.data_sector = ntohl(lsp->ls_crypto.data_sector);
2518 2552                  marker += sizeof (lsp->ls_crypto.data_sector);
2519 2553  
2520 2554                  /* and ignore the rest until it is implemented */
2521 2555  
2522 2556                  lsp->ls_crypto_offset = lsp->ls_crypto.data_sector * DEV_BSIZE;
2523 2557                  return (0);
2524 2558          }
2525 2559  
2526 2560          /*
2527 2561           * We've requested encryption, but no magic was found, so it must be
2528 2562           * a new image.
2529 2563           */
2530 2564  
2531 2565          for (i = 0; i < sizeof (struct crypto_meta); i++) {
2532 2566                  if (buf[i] != '\0')
2533 2567                          return (EINVAL);
2534 2568          }
2535 2569  
2536 2570          marker = buf;
2537 2571          bcopy(lofi_crypto_magic, marker, sizeof (lofi_crypto_magic));
2538 2572          marker += sizeof (lofi_crypto_magic);
2539 2573          chead.version = htons(LOFI_CRYPTO_VERSION);
2540 2574          bcopy(&(chead.version), marker, sizeof (chead.version));
2541 2575          marker += sizeof (chead.version);
2542 2576          marker += sizeof (chead.reserved1);
2543 2577          chead.data_sector = htonl(LOFI_CRYPTO_DATA_SECTOR);
2544 2578          bcopy(&(chead.data_sector), marker, sizeof (chead.data_sector));
2545 2579  
2546 2580          /* write the header */
2547 2581          error = vn_rdwr(UIO_WRITE, lsp->ls_vp, buf, DEV_BSIZE,
2548 2582              CRYOFF, UIO_SYSSPACE, 0, RLIM64_INFINITY, kcred, &resid);
2549 2583          if (error != 0)
2550 2584                  return (error);
2551 2585  
2552 2586          /* fix things up so it looks like we read this info */
2553 2587          bcopy(lofi_crypto_magic, lsp->ls_crypto.magic,
2554 2588              sizeof (lofi_crypto_magic));
2555 2589          lsp->ls_crypto.version = LOFI_CRYPTO_VERSION;
2556 2590          lsp->ls_crypto.data_sector = LOFI_CRYPTO_DATA_SECTOR;
2557 2591          lsp->ls_crypto_offset = lsp->ls_crypto.data_sector * DEV_BSIZE;
2558 2592          return (0);
2559 2593  }
2560 2594  
2561 2595  /*
2562 2596   * Check to see if the passed in signature is a valid one.  If it is
2563 2597   * valid, return the index into lofi_compress_table.
2564 2598   *
2565 2599   * Return -1 if it is invalid
2566 2600   */
2567 2601  static int
2568 2602  lofi_compress_select(const char *signature)
2569 2603  {
2570 2604          int i;
2571 2605  
2572 2606          for (i = 0; i < LOFI_COMPRESS_FUNCTIONS; i++) {
2573 2607                  if (strcmp(lofi_compress_table[i].l_name, signature) == 0)
2574 2608                          return (i);
2575 2609          }
2576 2610  
2577 2611          return (-1);
2578 2612  }
2579 2613  
2580 2614  static int
2581 2615  lofi_init_compress(struct lofi_state *lsp)
2582 2616  {
2583 2617          char buf[DEV_BSIZE];
2584 2618          int compress_index;
2585 2619          ssize_t resid;
2586 2620          int error;
2587 2621  
2588 2622          error = vn_rdwr(UIO_READ, lsp->ls_vp, buf, DEV_BSIZE, 0, UIO_SYSSPACE,
2589 2623              0, RLIM64_INFINITY, kcred, &resid);
2590 2624  
2591 2625          if (error != 0)
2592 2626                  return (error);
2593 2627  
2594 2628          if ((compress_index = lofi_compress_select(buf)) == -1)
2595 2629                  return (0);
2596 2630  
2597 2631          /* compression and encryption are mutually exclusive */
2598 2632          if (lsp->ls_crypto_enabled)
2599 2633                  return (ENOTSUP);
2600 2634  
2601 2635          /* initialize compression info for compressed lofi */
2602 2636          lsp->ls_comp_algorithm_index = compress_index;
2603 2637          (void) strlcpy(lsp->ls_comp_algorithm,
2604 2638              lofi_compress_table[compress_index].l_name,
2605 2639              sizeof (lsp->ls_comp_algorithm));
2606 2640  
2607 2641          /* Finally setup per-thread pre-allocated buffers */
2608 2642          lsp->ls_comp_bufs = kmem_zalloc(lofi_taskq_nthreads *
2609 2643              sizeof (struct compbuf), KM_SLEEP);
2610 2644  
2611 2645          return (lofi_map_compressed_file(lsp, buf));
2612 2646  }
2613 2647  
2614 2648  /*
2615 2649   * Allocate new or proposed id from lofi_id.
2616 2650   *
2617 2651   * Special cases for proposed id:
2618 2652   * 0: not allowed, 0 is id for control device.
2619 2653   * -1: allocate first usable id from lofi_id.
2620 2654   * any other value is proposed value from userland
2621 2655   *
2622 2656   * returns DDI_SUCCESS or errno.
2623 2657   */
2624 2658  static int
2625 2659  lofi_alloc_id(int *idp)
2626 2660  {
2627 2661          int id, error = DDI_SUCCESS;
2628 2662  
2629 2663          if (*idp == -1) {
2630 2664                  id = id_allocff_nosleep(lofi_id);
2631 2665                  if (id == -1) {
2632 2666                          error = EAGAIN;
2633 2667                          goto err;
2634 2668                  }
2635 2669          } else if (*idp == 0) {
2636 2670                  error = EINVAL;
2637 2671                  goto err;
2638 2672          } else if (*idp > ((1 << (L_BITSMINOR - LOFI_CMLB_SHIFT)) - 1)) {
2639 2673                  error = ERANGE;
2640 2674                  goto err;
2641 2675          } else {
2642 2676                  if (ddi_get_soft_state(lofi_statep, *idp) != NULL) {
2643 2677                          error = EEXIST;
2644 2678                          goto err;
2645 2679                  }
2646 2680  
2647 2681                  id = id_alloc_specific_nosleep(lofi_id, *idp);
2648 2682                  if (id == -1) {
2649 2683                          error = EAGAIN;
2650 2684                          goto err;
2651 2685                  }
2652 2686          }
2653 2687          *idp = id;
2654 2688  err:
2655 2689          return (error);
2656 2690  }
2657 2691  
2658 2692  static int
2659 2693  lofi_create_dev(struct lofi_ioctl *klip)
2660 2694  {
2661 2695          dev_info_t *parent, *child;
2662 2696          struct lofi_state *lsp = NULL;
2663 2697          char namebuf[MAXNAMELEN];
2664 2698          int error, circ;
2665 2699  
2666 2700          /* get control device */
2667 2701          lsp = ddi_get_soft_state(lofi_statep, 0);
2668 2702          parent = ddi_get_parent(lsp->ls_dip);
2669 2703  
2670 2704          if ((error = lofi_alloc_id((int *)&klip->li_id)))
2671 2705                  return (error);
2672 2706  
2673 2707          (void) snprintf(namebuf, sizeof (namebuf), LOFI_DRIVER_NAME "@%d",
2674 2708              klip->li_id);
2675 2709  
2676 2710          ndi_devi_enter(parent, &circ);
2677 2711          child = ndi_devi_findchild(parent, namebuf);
2678 2712          ndi_devi_exit(parent, circ);
2679 2713  
2680 2714          if (child == NULL) {
2681 2715                  child = ddi_add_child(parent, LOFI_DRIVER_NAME,
2682 2716                      (pnode_t)DEVI_SID_NODEID, klip->li_id);
2683 2717                  if ((error = ddi_prop_update_int(DDI_DEV_T_NONE, child,
2684 2718                      "instance", klip->li_id)) != DDI_PROP_SUCCESS)
2685 2719                          goto err;
2686 2720  
2687 2721                  if (klip->li_labeled == B_TRUE) {
2688 2722                          if ((error = ddi_prop_create(DDI_DEV_T_NONE, child,
2689 2723                              DDI_PROP_CANSLEEP, "labeled", 0, 0))
2690 2724                              != DDI_PROP_SUCCESS)
2691 2725                                  goto err;
2692 2726                  }
2693 2727  
2694 2728                  if ((error = ndi_devi_online(child, NDI_ONLINE_ATTACH))
2695 2729                      != NDI_SUCCESS)
2696 2730                          goto err;
2697 2731          } else {
2698 2732                  id_free(lofi_id, klip->li_id);
2699 2733                  error = EEXIST;
2700 2734                  return (error);
2701 2735          }
2702 2736  
2703 2737          goto done;
2704 2738  
2705 2739  err:
2706 2740          ddi_prop_remove_all(child);
2707 2741          (void) ndi_devi_offline(child, NDI_DEVI_REMOVE);
2708 2742          id_free(lofi_id, klip->li_id);
2709 2743  done:
2710 2744  
2711 2745          return (error);
2712 2746  }
2713 2747  
2714 2748  static void
2715 2749  lofi_create_inquiry(struct lofi_state *lsp, struct scsi_inquiry *inq)
2716 2750  {
2717 2751          char *p = NULL;
2718 2752  
2719 2753          (void) strlcpy(inq->inq_vid, LOFI_DRIVER_NAME, sizeof (inq->inq_vid));
2720 2754  
2721 2755          mutex_enter(&lsp->ls_vp_lock);
2722 2756          if (lsp->ls_vp != NULL)
2723 2757                  p = strrchr(lsp->ls_vp->v_path, '/');
2724 2758          if (p != NULL)
2725 2759                  (void) strncpy(inq->inq_pid, p + 1, sizeof (inq->inq_pid));
2726 2760          mutex_exit(&lsp->ls_vp_lock);
2727 2761          (void) strlcpy(inq->inq_revision, "1.0", sizeof (inq->inq_revision));
2728 2762  }
2729 2763  
2730 2764  /*
2731 2765   * copy devlink name from event cache
2732 2766   */
2733 2767  static void
2734 2768  lofi_copy_devpath(struct lofi_ioctl *klip)
2735 2769  {
2736 2770          int     error;
2737 2771          char    namebuf[MAXNAMELEN], *str;
2738 2772          clock_t ticks;
2739 2773          nvlist_t *nvl = NULL;
2740 2774  
2741 2775          if (klip->li_labeled == B_TRUE)
2742 2776                  klip->li_devpath[0] = '\0';
2743 2777          else {
2744 2778                  /* no need to wait for messages */
2745 2779                  (void) snprintf(klip->li_devpath, sizeof (klip->li_devpath),
2746 2780                      "/dev/" LOFI_CHAR_NAME "/%d", klip->li_id);
2747 2781                  return;
2748 2782          }
2749 2783  
2750 2784          (void) snprintf(namebuf, sizeof (namebuf), "%d", klip->li_id);
2751 2785          ticks = ddi_get_lbolt() + LOFI_TIMEOUT * drv_usectohz(1000000);
2752 2786  
2753 2787          mutex_enter(&lofi_devlink_cache.ln_lock);
2754 2788          error = nvlist_lookup_nvlist(lofi_devlink_cache.ln_data, namebuf, &nvl);
2755 2789          while (error != 0) {
2756 2790                  error = cv_timedwait(&lofi_devlink_cache.ln_cv,
2757 2791                      &lofi_devlink_cache.ln_lock, ticks);
2758 2792                  if (error == -1)
2759 2793                          break;
2760 2794                  error = nvlist_lookup_nvlist(lofi_devlink_cache.ln_data,
2761 2795                      namebuf, &nvl);
2762 2796          }
2763 2797  
2764 2798          if (nvl != NULL) {
2765 2799                  if (nvlist_lookup_string(nvl, DEV_NAME, &str) == 0) {
2766 2800                          (void) strlcpy(klip->li_devpath, str,
2767 2801                              sizeof (klip->li_devpath));
2768 2802                  }
2769 2803          }
2770 2804          mutex_exit(&lofi_devlink_cache.ln_lock);
2771 2805  }
2772 2806  
2773 2807  /*
2774 2808   * map a file to a minor number. Return the minor number.
2775 2809   */
2776 2810  static int
2777 2811  lofi_map_file(dev_t dev, struct lofi_ioctl *ulip, int pickminor,
2778 2812      int *rvalp, struct cred *credp, int ioctl_flag)
2779 2813  {
2780 2814          int     id = -1;
2781 2815          struct lofi_state *lsp = NULL;
2782 2816          struct lofi_ioctl *klip;
2783 2817          int     error;
2784 2818          struct vnode *vp = NULL;
2785 2819          vattr_t vattr;
2786 2820          int     flag;
2787 2821          char    namebuf[MAXNAMELEN];
2788 2822  
2789 2823          error = copy_in_lofi_ioctl(ulip, &klip, ioctl_flag);
2790 2824          if (error != 0)
2791 2825                  return (error);
2792 2826  
2793 2827          mutex_enter(&lofi_lock);
2794 2828  
2795 2829          if (file_to_lofi_nocheck(klip->li_filename, klip->li_readonly,
2796 2830              NULL) == 0) {
2797 2831                  error = EBUSY;
2798 2832                  goto err;
2799 2833          }
2800 2834  
2801 2835          flag = FREAD | FWRITE | FOFFMAX | FEXCL;
2802 2836          error = vn_open(klip->li_filename, UIO_SYSSPACE, flag, 0, &vp, 0, 0);
2803 2837          if (error) {
2804 2838                  /* try read-only */
2805 2839                  flag &= ~FWRITE;
2806 2840                  error = vn_open(klip->li_filename, UIO_SYSSPACE, flag, 0,
2807 2841                      &vp, 0, 0);
2808 2842                  if (error)
2809 2843                          goto err;
2810 2844          }
2811 2845  
2812 2846          if (!V_ISLOFIABLE(vp->v_type)) {
2813 2847                  error = EINVAL;
2814 2848                  goto err;
2815 2849          }
2816 2850  
2817 2851          vattr.va_mask = AT_SIZE;
2818 2852          error = VOP_GETATTR(vp, &vattr, 0, credp, NULL);
2819 2853          if (error)
2820 2854                  goto err;
2821 2855  
2822 2856          /* the file needs to be a multiple of the block size */
2823 2857          if ((vattr.va_size % DEV_BSIZE) != 0) {
2824 2858                  error = EINVAL;
2825 2859                  goto err;
2826 2860          }
2827 2861  
2828 2862          if (pickminor) {
2829 2863                  klip->li_id = (uint32_t)-1;
2830 2864          }
2831 2865          if ((error = lofi_create_dev(klip)) != 0)
2832 2866                  goto err;
2833 2867  
2834 2868          id = klip->li_id;
2835 2869          lsp = ddi_get_soft_state(lofi_statep, id);
2836 2870          if (lsp == NULL)
2837 2871                  goto err;
2838 2872  
2839 2873          /*
2840 2874           * from this point lofi_destroy() is used to clean up on error
2841 2875           * make sure the basic data is set
2842 2876           */
2843 2877          list_insert_tail(&lofi_list, lsp);
2844 2878          lsp->ls_dev = makedevice(getmajor(dev), LOFI_ID2MINOR(id));
2845 2879  
2846 2880          list_create(&lsp->ls_comp_cache, sizeof (struct lofi_comp_cache),
2847 2881              offsetof(struct lofi_comp_cache, lc_list));
2848 2882  
2849 2883          /*
2850 2884           * save open mode so file can be closed properly and vnode counts
2851 2885           * updated correctly.
2852 2886           */
2853 2887          lsp->ls_openflag = flag;
2854 2888  
2855 2889          lsp->ls_vp = vp;
2856 2890          lsp->ls_stacked_vp = vp;
2857 2891  
2858 2892          lsp->ls_vp_size = vattr.va_size;
2859 2893          lsp->ls_vp_comp_size = lsp->ls_vp_size;
2860 2894  
2861 2895          /*
2862 2896           * Try to handle stacked lofs vnodes.
2863 2897           */
2864 2898          if (vp->v_type == VREG) {
2865 2899                  vnode_t *realvp;
2866 2900  
2867 2901                  if (VOP_REALVP(vp, &realvp, NULL) == 0) {
2868 2902                          /*
2869 2903                           * We need to use the realvp for uniqueness
2870 2904                           * checking, but keep the stacked vp for
2871 2905                           * LOFI_GET_FILENAME display.
2872 2906                           */
2873 2907                          VN_HOLD(realvp);
2874 2908                          lsp->ls_vp = realvp;
2875 2909                  }
2876 2910          }
2877 2911  
2878 2912          lsp->ls_lbshift = highbit(DEV_BSIZE) - 1;
2879 2913          lsp->ls_pbshift = lsp->ls_lbshift;
2880 2914  
2881 2915          lsp->ls_readonly = klip->li_readonly;
2882 2916          lsp->ls_uncomp_seg_sz = 0;
2883 2917          lsp->ls_comp_algorithm[0] = '\0';
2884 2918          lsp->ls_crypto_offset = 0;
2885 2919  
2886 2920          (void) snprintf(namebuf, sizeof (namebuf), "%s_taskq_%d",
2887 2921              LOFI_DRIVER_NAME, id);
2888 2922          lsp->ls_taskq = taskq_create_proc(namebuf, lofi_taskq_nthreads,
2889 2923              minclsyspri, 1, lofi_taskq_maxalloc, curzone->zone_zsched, 0);
2890 2924  
2891 2925          if ((error = lofi_init_crypto(lsp, klip)) != 0)
2892 2926                  goto err;
2893 2927  
2894 2928          if ((error = lofi_init_compress(lsp)) != 0)
2895 2929                  goto err;
2896 2930  
2897 2931          fake_disk_geometry(lsp);
2898 2932  
2899 2933          /* For unlabeled lofi add Nblocks and Size */
2900 2934          if (klip->li_labeled == B_FALSE) {
2901 2935                  error = ddi_prop_update_int64(lsp->ls_dev, lsp->ls_dip,
2902 2936                      SIZE_PROP_NAME, lsp->ls_vp_size - lsp->ls_crypto_offset);
2903 2937                  if (error != DDI_PROP_SUCCESS) {
2904 2938                          error = EINVAL;
2905 2939                          goto err;
2906 2940                  }
2907 2941                  error = ddi_prop_update_int64(lsp->ls_dev, lsp->ls_dip,
2908 2942                      NBLOCKS_PROP_NAME,
2909 2943                      (lsp->ls_vp_size - lsp->ls_crypto_offset) / DEV_BSIZE);
2910 2944                  if (error != DDI_PROP_SUCCESS) {
2911 2945                          error = EINVAL;
2912 2946                          goto err;
2913 2947                  }
2914 2948          }
2915 2949  
2916 2950          /*
2917 2951           * Notify we are ready to rock.
2918 2952           */
2919 2953          mutex_enter(&lsp->ls_vp_lock);
2920 2954          lsp->ls_vp_ready = B_TRUE;
2921 2955          cv_broadcast(&lsp->ls_vp_cv);
2922 2956          mutex_exit(&lsp->ls_vp_lock);
2923 2957          mutex_exit(&lofi_lock);
2924 2958  
2925 2959          lofi_copy_devpath(klip);
2926 2960  
2927 2961          if (rvalp)
2928 2962                  *rvalp = id;
2929 2963          (void) copy_out_lofi_ioctl(klip, ulip, ioctl_flag);
2930 2964          free_lofi_ioctl(klip);
2931 2965          return (0);
2932 2966  
2933 2967  err:
2934 2968          if (lsp != NULL) {
2935 2969                  lofi_destroy(lsp, credp);
2936 2970          } else {
2937 2971                  if (vp != NULL) {
2938 2972                          (void) VOP_PUTPAGE(vp, 0, 0, B_FREE, credp, NULL);
2939 2973                          (void) VOP_CLOSE(vp, flag, 1, 0, credp, NULL);
2940 2974                          VN_RELE(vp);
2941 2975                  }
2942 2976          }
2943 2977  
2944 2978          mutex_exit(&lofi_lock);
2945 2979          free_lofi_ioctl(klip);
2946 2980          return (error);
2947 2981  }
2948 2982  
2949 2983  /*
2950 2984   * unmap a file.
2951 2985   */
2952 2986  static int
2953 2987  lofi_unmap_file(struct lofi_ioctl *ulip, int byfilename,
2954 2988      struct cred *credp, int ioctl_flag)
2955 2989  {
2956 2990          struct lofi_state *lsp;
2957 2991          struct lofi_ioctl *klip;
2958 2992          char namebuf[MAXNAMELEN];
2959 2993          int err;
2960 2994  
2961 2995          err = copy_in_lofi_ioctl(ulip, &klip, ioctl_flag);
2962 2996          if (err != 0)
2963 2997                  return (err);
2964 2998  
2965 2999          mutex_enter(&lofi_lock);
2966 3000          if (byfilename) {
2967 3001                  if ((err = file_to_lofi(klip->li_filename, klip->li_readonly,
2968 3002                      &lsp)) != 0) {
2969 3003                          goto done;
2970 3004                  }
2971 3005          } else if (klip->li_id == 0) {
2972 3006                  err = ENXIO;
2973 3007                  goto done;
2974 3008          } else {
2975 3009                  lsp = ddi_get_soft_state(lofi_statep, klip->li_id);
2976 3010          }
2977 3011  
2978 3012          if (lsp == NULL || lsp->ls_vp == NULL || lofi_access(lsp) != 0) {
2979 3013                  err = ENXIO;
2980 3014                  goto done;
2981 3015          }
2982 3016  
2983 3017          klip->li_id = LOFI_MINOR2ID(getminor(lsp->ls_dev));
2984 3018          (void) snprintf(namebuf, sizeof (namebuf), "%u", klip->li_id);
2985 3019  
2986 3020          /*
2987 3021           * If it's still held open, we'll do one of three things:
2988 3022           *
2989 3023           * If no flag is set, just return EBUSY.
2990 3024           *
2991 3025           * If the 'cleanup' flag is set, unmap and remove the device when
2992 3026           * the last user finishes.
2993 3027           *
2994 3028           * If the 'force' flag is set, then we forcibly close the underlying
2995 3029           * file.  Subsequent operations will fail, and the DKIOCSTATE ioctl
2996 3030           * will return DKIO_DEV_GONE.  When the device is last closed, the
2997 3031           * device will be cleaned up appropriately.
2998 3032           *
2999 3033           * This is complicated by the fact that we may have outstanding
3000 3034           * dispatched I/Os.  Rather than having a single mutex to serialize all
3001 3035           * I/O, we keep a count of the number of outstanding I/O requests
3002 3036           * (ls_vp_iocount), as well as a flag to indicate that no new I/Os
3003 3037           * should be dispatched (ls_vp_closereq).
3004 3038           *
3005 3039           * We set the flag, wait for the number of outstanding I/Os to reach 0,
3006 3040           * and then close the underlying vnode.
3007 3041           */
3008 3042          if (is_opened(lsp)) {
3009 3043                  if (klip->li_force) {
3010 3044                          /* Mark the device for cleanup. */
3011 3045                          lofi_set_cleanup(lsp);
3012 3046                          mutex_enter(&lsp->ls_vp_lock);
3013 3047                          lsp->ls_vp_closereq = B_TRUE;
3014 3048                          /* Wake up any threads waiting on dkiocstate. */
3015 3049                          cv_broadcast(&lsp->ls_vp_cv);
3016 3050                          while (lsp->ls_vp_iocount > 0)
3017 3051                                  cv_wait(&lsp->ls_vp_cv, &lsp->ls_vp_lock);
3018 3052                          mutex_exit(&lsp->ls_vp_lock);
3019 3053                  } else if (klip->li_cleanup) {
3020 3054                          lofi_set_cleanup(lsp);
3021 3055                  } else {
3022 3056                          err = EBUSY;
3023 3057                  }
3024 3058          } else {
3025 3059                  lofi_free_dev(lsp);
3026 3060                  lofi_destroy(lsp, credp);
3027 3061          }
3028 3062  
3029 3063          /* Remove name from devlink cache */
3030 3064          mutex_enter(&lofi_devlink_cache.ln_lock);
3031 3065          (void) nvlist_remove_all(lofi_devlink_cache.ln_data, namebuf);
3032 3066          mutex_exit(&lofi_devlink_cache.ln_lock);
3033 3067  done:
3034 3068          mutex_exit(&lofi_lock);
3035 3069          if (err == 0)
3036 3070                  (void) copy_out_lofi_ioctl(klip, ulip, ioctl_flag);
3037 3071          free_lofi_ioctl(klip);
3038 3072          return (err);
3039 3073  }
3040 3074  
3041 3075  /*
3042 3076   * get the filename given the minor number, or the minor number given
3043 3077   * the name.
3044 3078   */
3045 3079  /*ARGSUSED*/
3046 3080  static int
3047 3081  lofi_get_info(dev_t dev, struct lofi_ioctl *ulip, int which,
3048 3082      struct cred *credp, int ioctl_flag)
3049 3083  {
3050 3084          struct lofi_ioctl *klip;
3051 3085          struct lofi_state *lsp;
3052 3086          int     error;
3053 3087  
3054 3088          error = copy_in_lofi_ioctl(ulip, &klip, ioctl_flag);
3055 3089          if (error != 0)
3056 3090                  return (error);
3057 3091  
3058 3092          switch (which) {
3059 3093          case LOFI_GET_FILENAME:
3060 3094                  if (klip->li_id == 0) {
3061 3095                          free_lofi_ioctl(klip);
3062 3096                          return (EINVAL);
3063 3097                  }
3064 3098  
3065 3099                  mutex_enter(&lofi_lock);
3066 3100                  lsp = ddi_get_soft_state(lofi_statep, klip->li_id);
3067 3101                  if (lsp == NULL || lofi_access(lsp) != 0) {
3068 3102                          mutex_exit(&lofi_lock);
3069 3103                          free_lofi_ioctl(klip);
3070 3104                          return (ENXIO);
3071 3105                  }
3072 3106  
3073 3107                  /*
3074 3108                   * This may fail if, for example, we're trying to look
3075 3109                   * up a zoned NFS path from the global zone.
3076 3110                   */
3077 3111                  if (vnodetopath(NULL, lsp->ls_stacked_vp, klip->li_filename,
3078 3112                      sizeof (klip->li_filename), CRED()) != 0) {
3079 3113                          (void) strlcpy(klip->li_filename, "?",
3080 3114                              sizeof (klip->li_filename));
3081 3115                  }
3082 3116  
3083 3117                  klip->li_readonly = lsp->ls_readonly;
3084 3118                  klip->li_labeled = lsp->ls_cmlbhandle != NULL;
3085 3119  
3086 3120                  (void) strlcpy(klip->li_algorithm, lsp->ls_comp_algorithm,
3087 3121                      sizeof (klip->li_algorithm));
3088 3122                  klip->li_crypto_enabled = lsp->ls_crypto_enabled;
3089 3123                  mutex_exit(&lofi_lock);
3090 3124  
3091 3125                  lofi_copy_devpath(klip);
3092 3126                  error = copy_out_lofi_ioctl(klip, ulip, ioctl_flag);
3093 3127                  free_lofi_ioctl(klip);
3094 3128                  return (error);
3095 3129          case LOFI_GET_MINOR:
3096 3130                  mutex_enter(&lofi_lock);
3097 3131                  error = file_to_lofi(klip->li_filename,
3098 3132                      klip->li_readonly, &lsp);
3099 3133                  if (error != 0) {
3100 3134                          mutex_exit(&lofi_lock);
3101 3135                          free_lofi_ioctl(klip);
3102 3136                          return (error);
3103 3137                  }
3104 3138                  klip->li_id = LOFI_MINOR2ID(getminor(lsp->ls_dev));
3105 3139  
3106 3140                  klip->li_readonly = lsp->ls_readonly;
3107 3141                  klip->li_labeled = lsp->ls_cmlbhandle != NULL;
3108 3142                  mutex_exit(&lofi_lock);
3109 3143  
3110 3144                  lofi_copy_devpath(klip);
3111 3145                  error = copy_out_lofi_ioctl(klip, ulip, ioctl_flag);
3112 3146  
3113 3147                  free_lofi_ioctl(klip);
3114 3148                  return (error);
3115 3149          case LOFI_CHECK_COMPRESSED:
3116 3150                  mutex_enter(&lofi_lock);
3117 3151                  error = file_to_lofi(klip->li_filename,
3118 3152                      klip->li_readonly, &lsp);
3119 3153                  if (error != 0) {
3120 3154                          mutex_exit(&lofi_lock);
3121 3155                          free_lofi_ioctl(klip);
3122 3156                          return (error);
3123 3157                  }
3124 3158  
3125 3159                  klip->li_id = LOFI_MINOR2ID(getminor(lsp->ls_dev));
3126 3160                  (void) strlcpy(klip->li_algorithm, lsp->ls_comp_algorithm,
3127 3161                      sizeof (klip->li_algorithm));
3128 3162  
3129 3163                  mutex_exit(&lofi_lock);
3130 3164                  error = copy_out_lofi_ioctl(klip, ulip, ioctl_flag);
3131 3165                  free_lofi_ioctl(klip);
3132 3166                  return (error);
3133 3167          default:
3134 3168                  free_lofi_ioctl(klip);
3135 3169                  return (EINVAL);
3136 3170          }
3137 3171  }
3138 3172  
3139 3173  static int
3140 3174  uscsi_is_inquiry(intptr_t arg, int flag, union scsi_cdb *cdb,
3141 3175      struct uscsi_cmd *uscmd)
3142 3176  {
3143 3177          int rval;
3144 3178  
3145 3179  #ifdef  _MULTI_DATAMODEL
3146 3180          switch (ddi_model_convert_from(flag & FMODELS)) {
3147 3181          case DDI_MODEL_ILP32: {
3148 3182                  struct uscsi_cmd32 ucmd32;
3149 3183  
3150 3184                  if (ddi_copyin((void *)arg, &ucmd32, sizeof (ucmd32), flag)) {
3151 3185                          rval = EFAULT;
3152 3186                          goto err;
3153 3187                  }
3154 3188                  uscsi_cmd32touscsi_cmd((&ucmd32), uscmd);
3155 3189                  break;
3156 3190          }
3157 3191          case DDI_MODEL_NONE:
3158 3192                  if (ddi_copyin((void *)arg, uscmd, sizeof (*uscmd), flag)) {
3159 3193                          rval = EFAULT;
3160 3194                          goto err;
3161 3195                  }
3162 3196                  break;
3163 3197          default:
3164 3198                  rval = EFAULT;
3165 3199                  goto err;
3166 3200          }
3167 3201  #else
3168 3202          if (ddi_copyin((void *)arg, uscmd, sizeof (*uscmd), flag)) {
3169 3203                  rval = EFAULT;
3170 3204                  goto err;
3171 3205          }
3172 3206  #endif  /* _MULTI_DATAMODEL */
3173 3207          if (ddi_copyin(uscmd->uscsi_cdb, cdb, uscmd->uscsi_cdblen, flag)) {
3174 3208                  rval = EFAULT;
3175 3209                  goto err;
3176 3210          }
3177 3211          if (cdb->scc_cmd == SCMD_INQUIRY) {
  
    | 
      ↓ open down ↓ | 
    1404 lines elided | 
    
      ↑ open up ↑ | 
  
3178 3212                  return (0);
3179 3213          }
3180 3214  err:
3181 3215          return (rval);
3182 3216  }
3183 3217  
3184 3218  static int
3185 3219  lofi_ioctl(dev_t dev, int cmd, intptr_t arg, int flag, cred_t *credp,
3186 3220      int *rvalp)
3187 3221  {
3188      -        int     error;
     3222 +        int error;
3189 3223          enum dkio_state dkstate;
3190 3224          struct lofi_state *lsp;
3191      -        int     id;
     3225 +        dk_efi_t user_efi;
     3226 +        int id;
3192 3227  
3193 3228          id = LOFI_MINOR2ID(getminor(dev));
3194 3229  
3195 3230          /* lofi ioctls only apply to the master device */
3196 3231          if (id == 0) {
3197 3232                  struct lofi_ioctl *lip = (struct lofi_ioctl *)arg;
3198 3233  
3199 3234                  /*
3200 3235                   * the query command only need read-access - i.e., normal
3201 3236                   * users are allowed to do those on the ctl device as
3202 3237                   * long as they can open it read-only.
3203 3238                   */
3204 3239                  switch (cmd) {
3205 3240                  case LOFI_MAP_FILE:
3206 3241                          if ((flag & FWRITE) == 0)
3207 3242                                  return (EPERM);
3208 3243                          return (lofi_map_file(dev, lip, 1, rvalp, credp, flag));
3209 3244                  case LOFI_MAP_FILE_MINOR:
3210 3245                          if ((flag & FWRITE) == 0)
3211 3246                                  return (EPERM);
3212 3247                          return (lofi_map_file(dev, lip, 0, rvalp, credp, flag));
3213 3248                  case LOFI_UNMAP_FILE:
3214 3249                          if ((flag & FWRITE) == 0)
3215 3250                                  return (EPERM);
3216 3251                          return (lofi_unmap_file(lip, 1, credp, flag));
3217 3252                  case LOFI_UNMAP_FILE_MINOR:
3218 3253                          if ((flag & FWRITE) == 0)
3219 3254                                  return (EPERM);
3220 3255                          return (lofi_unmap_file(lip, 0, credp, flag));
3221 3256                  case LOFI_GET_FILENAME:
3222 3257                          return (lofi_get_info(dev, lip, LOFI_GET_FILENAME,
3223 3258                              credp, flag));
3224 3259                  case LOFI_GET_MINOR:
3225 3260                          return (lofi_get_info(dev, lip, LOFI_GET_MINOR,
3226 3261                              credp, flag));
3227 3262  
3228 3263                  /*
3229 3264                   * This API made limited sense when this value was fixed
3230 3265                   * at LOFI_MAX_FILES.  However, its use to iterate
3231 3266                   * across all possible devices in lofiadm means we don't
3232 3267                   * want to return L_MAXMIN, but the highest
3233 3268                   * *allocated* id.
3234 3269                   */
3235 3270                  case LOFI_GET_MAXMINOR:
3236 3271                          id = 0;
3237 3272  
3238 3273                          mutex_enter(&lofi_lock);
3239 3274  
3240 3275                          for (lsp = list_head(&lofi_list); lsp != NULL;
3241 3276                              lsp = list_next(&lofi_list, lsp)) {
3242 3277                                  int i;
3243 3278                                  if (lofi_access(lsp) != 0)
3244 3279                                          continue;
3245 3280  
3246 3281                                  i = ddi_get_instance(lsp->ls_dip);
3247 3282                                  if (i > id)
3248 3283                                          id = i;
3249 3284                          }
3250 3285  
3251 3286                          mutex_exit(&lofi_lock);
3252 3287  
3253 3288                          error = ddi_copyout(&id, &lip->li_id,
3254 3289                              sizeof (id), flag);
3255 3290                          if (error)
3256 3291                                  return (EFAULT);
3257 3292                          return (0);
3258 3293  
3259 3294                  case LOFI_CHECK_COMPRESSED:
3260 3295                          return (lofi_get_info(dev, lip, LOFI_CHECK_COMPRESSED,
3261 3296                              credp, flag));
3262 3297                  default:
3263 3298                          return (EINVAL);
3264 3299                  }
3265 3300          }
3266 3301  
3267 3302          mutex_enter(&lofi_lock);
3268 3303          lsp = ddi_get_soft_state(lofi_statep, id);
3269 3304          if (lsp == NULL || lsp->ls_cleanup) {
3270 3305                  mutex_exit(&lofi_lock);
3271 3306                  return (ENXIO);
3272 3307          }
3273 3308          mutex_exit(&lofi_lock);
3274 3309  
3275 3310          if (ddi_prop_exists(DDI_DEV_T_ANY, lsp->ls_dip, DDI_PROP_DONTPASS,
3276 3311              "labeled") == 1) {
3277 3312                  error = cmlb_ioctl(lsp->ls_cmlbhandle, dev, cmd, arg, flag,
3278 3313                      credp, rvalp, 0);
3279 3314                  if (error != ENOTTY)
3280 3315                          return (error);
3281 3316          }
3282 3317  
3283 3318          /*
3284 3319           * We explicitly allow DKIOCSTATE, but all other ioctls should fail with
3285 3320           * EIO as if the device was no longer present.
3286 3321           */
3287 3322          if (lsp->ls_vp == NULL && cmd != DKIOCSTATE)
3288 3323                  return (EIO);
3289 3324  
3290 3325          /* these are for faking out utilities like newfs */
3291 3326          switch (cmd) {
3292 3327          case DKIOCGMEDIAINFO:
3293 3328          case DKIOCGMEDIAINFOEXT: {
3294 3329                  struct dk_minfo_ext media_info;
3295 3330                  int shift = lsp->ls_lbshift;
3296 3331                  int size;
3297 3332  
3298 3333                  if (cmd == DKIOCGMEDIAINFOEXT) {
3299 3334                          media_info.dki_pbsize = 1U << lsp->ls_pbshift;
3300 3335                          size = sizeof (struct dk_minfo_ext);
3301 3336                  } else {
3302 3337                          size = sizeof (struct dk_minfo);
3303 3338                  }
3304 3339  
3305 3340                  media_info.dki_media_type = DK_FIXED_DISK;
3306 3341                  media_info.dki_lbsize = 1U << shift;
3307 3342                  media_info.dki_capacity =
3308 3343                      (lsp->ls_vp_size - lsp->ls_crypto_offset) >> shift;
3309 3344  
3310 3345                  if (ddi_copyout(&media_info, (void *)arg, size, flag))
3311 3346                          return (EFAULT);
3312 3347                  return (0);
3313 3348          }
3314 3349          case DKIOCREMOVABLE: {
3315 3350                  int i = 0;
3316 3351                  if (ddi_copyout(&i, (caddr_t)arg, sizeof (int), flag))
3317 3352                          return (EFAULT);
3318 3353                  return (0);
3319 3354          }
3320 3355  
3321 3356          case DKIOCGVTOC: {
3322 3357                  struct vtoc vt;
3323 3358                  fake_disk_vtoc(lsp, &vt);
3324 3359  
3325 3360                  switch (ddi_model_convert_from(flag & FMODELS)) {
3326 3361                  case DDI_MODEL_ILP32: {
3327 3362                          struct vtoc32 vtoc32;
3328 3363  
3329 3364                          vtoctovtoc32(vt, vtoc32);
3330 3365                          if (ddi_copyout(&vtoc32, (void *)arg,
3331 3366                              sizeof (struct vtoc32), flag))
3332 3367                                  return (EFAULT);
3333 3368                          break;
3334 3369                          }
3335 3370  
3336 3371                  case DDI_MODEL_NONE:
3337 3372                          if (ddi_copyout(&vt, (void *)arg,
3338 3373                              sizeof (struct vtoc), flag))
3339 3374                                  return (EFAULT);
3340 3375                          break;
3341 3376                  }
3342 3377                  return (0);
3343 3378          }
3344 3379          case DKIOCINFO: {
3345 3380                  struct dk_cinfo ci;
3346 3381                  fake_disk_info(dev, &ci);
3347 3382                  if (ddi_copyout(&ci, (void *)arg, sizeof (ci), flag))
3348 3383                          return (EFAULT);
3349 3384                  return (0);
3350 3385          }
3351 3386          case DKIOCG_VIRTGEOM:
3352 3387          case DKIOCG_PHYGEOM:
3353 3388          case DKIOCGGEOM:
3354 3389                  error = ddi_copyout(&lsp->ls_dkg, (void *)arg,
3355 3390                      sizeof (struct dk_geom), flag);
3356 3391                  if (error)
3357 3392                          return (EFAULT);
3358 3393                  return (0);
3359 3394          case DKIOCSTATE:
3360 3395                  /*
3361 3396                   * Normally, lofi devices are always in the INSERTED state.  If
3362 3397                   * a device is forcefully unmapped, then the device transitions
3363 3398                   * to the DKIO_DEV_GONE state.
3364 3399                   */
3365 3400                  if (ddi_copyin((void *)arg, &dkstate, sizeof (dkstate),
3366 3401                      flag) != 0)
3367 3402                          return (EFAULT);
3368 3403  
3369 3404                  mutex_enter(&lsp->ls_vp_lock);
3370 3405                  while (((dkstate == DKIO_INSERTED && lsp->ls_vp != NULL) ||
3371 3406                      (dkstate == DKIO_DEV_GONE && lsp->ls_vp == NULL)) &&
3372 3407                      !lsp->ls_cleanup) {
3373 3408                          /*
3374 3409                           * By virtue of having the device open, we know that
3375 3410                           * 'lsp' will remain valid when we return.
3376 3411                           */
3377 3412                          if (!cv_wait_sig(&lsp->ls_vp_cv, &lsp->ls_vp_lock)) {
3378 3413                                  mutex_exit(&lsp->ls_vp_lock);
3379 3414                                  return (EINTR);
3380 3415                          }
3381 3416                  }
3382 3417  
3383 3418                  dkstate = (!lsp->ls_cleanup && lsp->ls_vp != NULL ?
3384 3419                      DKIO_INSERTED : DKIO_DEV_GONE);
3385 3420                  mutex_exit(&lsp->ls_vp_lock);
3386 3421  
3387 3422                  if (ddi_copyout(&dkstate, (void *)arg,
3388 3423                      sizeof (dkstate), flag) != 0)
3389 3424                          return (EFAULT);
3390 3425                  return (0);
3391 3426          case USCSICMD: {
3392 3427                  struct uscsi_cmd uscmd;
3393 3428                  union scsi_cdb cdb;
3394 3429  
3395 3430                  if (uscsi_is_inquiry(arg, flag, &cdb, &uscmd) == 0) {
3396 3431                          struct scsi_inquiry inq = {0};
3397 3432  
3398 3433                          lofi_create_inquiry(lsp, &inq);
3399 3434                          if (ddi_copyout(&inq, uscmd.uscsi_bufaddr,
3400 3435                              uscmd.uscsi_buflen, flag) != 0)
3401 3436                                  return (EFAULT);
3402 3437                          return (0);
3403 3438                  } else if (cdb.scc_cmd == SCMD_READ_CAPACITY) {
3404 3439                          struct scsi_capacity capacity;
3405 3440  
3406 3441                          capacity.capacity =
3407 3442                              BE_32((lsp->ls_vp_size - lsp->ls_crypto_offset) >>
3408 3443                              lsp->ls_lbshift);
3409 3444                          capacity.lbasize = BE_32(1 << lsp->ls_lbshift);
3410 3445                          if (ddi_copyout(&capacity, uscmd.uscsi_bufaddr,
3411 3446                              uscmd.uscsi_buflen, flag) != 0)
3412 3447                                  return (EFAULT);
3413 3448                          return (0);
3414 3449                  }
3415 3450  
3416 3451                  uscmd.uscsi_rqstatus = 0xff;
3417 3452  #ifdef  _MULTI_DATAMODEL
3418 3453                  switch (ddi_model_convert_from(flag & FMODELS)) {
3419 3454                  case DDI_MODEL_ILP32: {
3420 3455                          struct uscsi_cmd32 ucmd32;
3421 3456                          uscsi_cmdtouscsi_cmd32((&uscmd), (&ucmd32));
3422 3457                          if (ddi_copyout(&ucmd32, (void *)arg, sizeof (ucmd32),
3423 3458                              flag) != 0)
3424 3459                                  return (EFAULT);
3425 3460                          break;
3426 3461                  }
3427 3462                  case DDI_MODEL_NONE:
3428 3463                          if (ddi_copyout(&uscmd, (void *)arg, sizeof (uscmd),
3429 3464                              flag) != 0)
3430 3465                                  return (EFAULT);
  
    | 
      ↓ open down ↓ | 
    229 lines elided | 
    
      ↑ open up ↑ | 
  
3431 3466                          break;
3432 3467                  default:
3433 3468                          return (EFAULT);
3434 3469                  }
3435 3470  #else
3436 3471                  if (ddi_copyout(&uscmd, (void *)arg, sizeof (uscmd), flag) != 0)
3437 3472                          return (EFAULT);
3438 3473  #endif  /* _MULTI_DATAMODEL */
3439 3474                  return (0);
3440 3475          }
     3476 +
     3477 +        case DKIOCGMBOOT:
     3478 +                return (lofi_urw(lsp, FREAD, 0, 1 << lsp->ls_lbshift,
     3479 +                    arg, flag, credp));
     3480 +
     3481 +        case DKIOCSMBOOT:
     3482 +                return (lofi_urw(lsp, FWRITE, 0, 1 << lsp->ls_lbshift,
     3483 +                    arg, flag, credp));
     3484 +
     3485 +        case DKIOCGETEFI:
     3486 +                if (ddi_copyin((void *)arg, &user_efi,
     3487 +                    sizeof (dk_efi_t), flag) != 0)
     3488 +                        return (EFAULT);
     3489 +
     3490 +                return (lofi_urw(lsp, FREAD,
     3491 +                    user_efi.dki_lba * (1 << lsp->ls_lbshift),
     3492 +                    user_efi.dki_length, (intptr_t)user_efi.dki_data,
     3493 +                    flag, credp));
     3494 +
     3495 +        case DKIOCSETEFI:
     3496 +                if (ddi_copyin((void *)arg, &user_efi,
     3497 +                    sizeof (dk_efi_t), flag) != 0)
     3498 +                        return (EFAULT);
     3499 +
     3500 +                return (lofi_urw(lsp, FWRITE,
     3501 +                    user_efi.dki_lba * (1 << lsp->ls_lbshift),
     3502 +                    user_efi.dki_length, (intptr_t)user_efi.dki_data,
     3503 +                    flag, credp));
     3504 +
3441 3505          default:
3442 3506  #ifdef DEBUG
3443 3507                  cmn_err(CE_WARN, "lofi_ioctl: %d is not implemented\n", cmd);
3444 3508  #endif  /* DEBUG */
3445 3509                  return (ENOTTY);
3446 3510          }
3447 3511  }
3448 3512  
3449 3513  static int
3450 3514  lofi_prop_op(dev_t dev, dev_info_t *dip, ddi_prop_op_t prop_op, int mod_flags,
3451 3515      char *name, caddr_t valuep, int *lengthp)
3452 3516  {
3453 3517          struct lofi_state *lsp;
3454 3518          int rc;
3455 3519  
3456 3520          lsp = ddi_get_soft_state(lofi_statep, ddi_get_instance(dip));
3457 3521          if (lsp == NULL) {
3458 3522                  return (ddi_prop_op(dev, dip, prop_op, mod_flags,
3459 3523                      name, valuep, lengthp));
3460 3524          }
3461 3525  
3462 3526          rc = cmlb_prop_op(lsp->ls_cmlbhandle, dev, dip, prop_op, mod_flags,
3463 3527              name, valuep, lengthp, LOFI_PART(getminor(dev)), NULL);
3464 3528          if (rc == DDI_PROP_SUCCESS)
3465 3529                  return (rc);
3466 3530  
3467 3531          return (ddi_prop_op(DDI_DEV_T_ANY, dip, prop_op, mod_flags,
3468 3532              name, valuep, lengthp));
3469 3533  }
3470 3534  
3471 3535  static struct cb_ops lofi_cb_ops = {
3472 3536          lofi_open,              /* open */
3473 3537          lofi_close,             /* close */
3474 3538          lofi_strategy,          /* strategy */
3475 3539          nodev,                  /* print */
3476 3540          nodev,                  /* dump */
3477 3541          lofi_read,              /* read */
3478 3542          lofi_write,             /* write */
3479 3543          lofi_ioctl,             /* ioctl */
3480 3544          nodev,                  /* devmap */
3481 3545          nodev,                  /* mmap */
3482 3546          nodev,                  /* segmap */
3483 3547          nochpoll,               /* poll */
3484 3548          lofi_prop_op,           /* prop_op */
3485 3549          0,                      /* streamtab  */
3486 3550          D_64BIT | D_NEW | D_MP, /* Driver compatibility flag */
3487 3551          CB_REV,
3488 3552          lofi_aread,
3489 3553          lofi_awrite
3490 3554  };
3491 3555  
3492 3556  static struct dev_ops lofi_ops = {
3493 3557          DEVO_REV,               /* devo_rev, */
3494 3558          0,                      /* refcnt  */
3495 3559          lofi_info,              /* info */
3496 3560          nulldev,                /* identify */
3497 3561          nulldev,                /* probe */
3498 3562          lofi_attach,            /* attach */
3499 3563          lofi_detach,            /* detach */
3500 3564          nodev,                  /* reset */
3501 3565          &lofi_cb_ops,           /* driver operations */
3502 3566          NULL,                   /* no bus operations */
3503 3567          NULL,                   /* power */
3504 3568          ddi_quiesce_not_needed, /* quiesce */
3505 3569  };
3506 3570  
3507 3571  static struct modldrv modldrv = {
3508 3572          &mod_driverops,
3509 3573          "loopback file driver",
3510 3574          &lofi_ops,
3511 3575  };
3512 3576  
3513 3577  static struct modlinkage modlinkage = {
3514 3578          MODREV_1,
3515 3579          &modldrv,
3516 3580          NULL
3517 3581  };
3518 3582  
3519 3583  int
3520 3584  _init(void)
3521 3585  {
3522 3586          int error;
3523 3587  
3524 3588          list_create(&lofi_list, sizeof (struct lofi_state),
3525 3589              offsetof(struct lofi_state, ls_list));
3526 3590  
3527 3591          error = ddi_soft_state_init((void **)&lofi_statep,
3528 3592              sizeof (struct lofi_state), 0);
3529 3593          if (error) {
3530 3594                  list_destroy(&lofi_list);
3531 3595                  return (error);
3532 3596          }
3533 3597  
3534 3598          /*
3535 3599           * The minor number is stored as id << LOFI_CMLB_SHIFT as
3536 3600           * we need to reserve space for cmlb minor numbers.
3537 3601           * This will leave out 4096 id values on 32bit kernel, which should
3538 3602           * still suffice.
3539 3603           */
3540 3604          lofi_id = id_space_create("lofi_id", 1,
3541 3605              (1 << (L_BITSMINOR - LOFI_CMLB_SHIFT)));
3542 3606  
3543 3607          if (lofi_id == NULL) {
3544 3608                  ddi_soft_state_fini((void **)&lofi_statep);
3545 3609                  list_destroy(&lofi_list);
3546 3610                  return (DDI_FAILURE);
3547 3611          }
3548 3612  
3549 3613          mutex_init(&lofi_lock, NULL, MUTEX_DRIVER, NULL);
3550 3614  
3551 3615          error = mod_install(&modlinkage);
3552 3616  
3553 3617          if (error) {
3554 3618                  id_space_destroy(lofi_id);
3555 3619                  mutex_destroy(&lofi_lock);
3556 3620                  ddi_soft_state_fini((void **)&lofi_statep);
3557 3621                  list_destroy(&lofi_list);
3558 3622          }
3559 3623  
3560 3624          return (error);
3561 3625  }
3562 3626  
3563 3627  int
3564 3628  _fini(void)
3565 3629  {
3566 3630          int     error;
3567 3631  
3568 3632          mutex_enter(&lofi_lock);
3569 3633  
3570 3634          if (!list_is_empty(&lofi_list)) {
3571 3635                  mutex_exit(&lofi_lock);
3572 3636                  return (EBUSY);
3573 3637          }
3574 3638  
3575 3639          mutex_exit(&lofi_lock);
3576 3640  
3577 3641          error = mod_remove(&modlinkage);
3578 3642          if (error)
3579 3643                  return (error);
3580 3644  
3581 3645          mutex_destroy(&lofi_lock);
3582 3646          id_space_destroy(lofi_id);
3583 3647          ddi_soft_state_fini((void **)&lofi_statep);
3584 3648          list_destroy(&lofi_list);
3585 3649  
3586 3650          return (error);
3587 3651  }
3588 3652  
3589 3653  int
3590 3654  _info(struct modinfo *modinfop)
3591 3655  {
3592 3656          return (mod_info(&modlinkage, modinfop));
3593 3657  }
  
    | 
      ↓ open down ↓ | 
    143 lines elided | 
    
      ↑ open up ↑ | 
  
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX