Print this page
2882 implement libzfs_core
2883 changing "canmount" property to "on" should not always remount dataset
2900 "zfs snapshot" should be able to create multiple, arbitrary snapshots at once
Reviewed by: George Wilson <george.wilson@delphix.com>
Reviewed by: Chris Siden <christopher.siden@delphix.com>
Reviewed by: Garrett D'Amore <garrett@damore.org>
Reviewed by: Bill Pijewski <wdp@joyent.com>
Reviewed by: Dan Kruchinin <dan.kruchinin@gmail.com>


   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  23  *
  24  * Portions Copyright 2010 Robert Milkowski
  25  *
  26  * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.

  27  */
  28 
  29 /*
  30  * ZFS volume emulation driver.
  31  *
  32  * Makes a DMU object look like a volume of arbitrary size, up to 2^64 bytes.
  33  * Volumes are accessed through the symbolic links named:
  34  *
  35  * /dev/zvol/dsk/<pool_name>/<dataset_name>
  36  * /dev/zvol/rdsk/<pool_name>/<dataset_name>
  37  *
  38  * These links are created by the /dev filesystem (sdev_zvolops.c).
  39  * Volumes are persistent through reboot.  No user command needs to be
  40  * run before opening and using a device.
  41  */
  42 
  43 #include <sys/types.h>
  44 #include <sys/param.h>
  45 #include <sys/errno.h>
  46 #include <sys/uio.h>


 118         zilog_t         *zv_zilog;      /* ZIL handle */
 119         list_t          zv_extents;     /* List of extents for dump */
 120         znode_t         zv_znode;       /* for range locking */
 121         dmu_buf_t       *zv_dbuf;       /* bonus handle */
 122 } zvol_state_t;
 123 
 124 /*
 125  * zvol specific flags
 126  */
 127 #define ZVOL_RDONLY     0x1
 128 #define ZVOL_DUMPIFIED  0x2
 129 #define ZVOL_EXCL       0x4
 130 #define ZVOL_WCE        0x8
 131 
 132 /*
 133  * zvol maximum transfer in one DMU tx.
 134  */
 135 int zvol_maxphys = DMU_MAX_ACCESS/2;
 136 
 137 extern int zfs_set_prop_nvlist(const char *, zprop_source_t,
 138     nvlist_t *, nvlist_t **);
 139 static int zvol_remove_zv(zvol_state_t *);
 140 static int zvol_get_data(void *arg, lr_write_t *lr, char *buf, zio_t *zio);
 141 static int zvol_dumpify(zvol_state_t *zv);
 142 static int zvol_dump_fini(zvol_state_t *zv);
 143 static int zvol_dump_init(zvol_state_t *zv, boolean_t resize);
 144 
 145 static void
 146 zvol_size_changed(uint64_t volsize, major_t maj, minor_t min)
 147 {
 148         dev_t dev = makedevice(maj, min);
 149 
 150         VERIFY(ddi_prop_update_int64(dev, zfs_dip,
 151             "Size", volsize) == DDI_SUCCESS);
 152         VERIFY(ddi_prop_update_int64(dev, zfs_dip,
 153             "Nblocks", lbtodb(volsize)) == DDI_SUCCESS);
 154 
 155         /* Notify specfs to invalidate the cached size */
 156         spec_size_invalidate(dev, VBLK);
 157         spec_size_invalidate(dev, VCHR);
 158 }


1868         }
1869 
1870         /* Allocate the space for the dump */
1871         error = zvol_prealloc(zv);
1872         return (error);
1873 }
1874 
1875 static int
1876 zvol_dumpify(zvol_state_t *zv)
1877 {
1878         int error = 0;
1879         uint64_t dumpsize = 0;
1880         dmu_tx_t *tx;
1881         objset_t *os = zv->zv_objset;
1882 
1883         if (zv->zv_flags & ZVOL_RDONLY)
1884                 return (EROFS);
1885 
1886         if (zap_lookup(zv->zv_objset, ZVOL_ZAP_OBJ, ZVOL_DUMPSIZE,
1887             8, 1, &dumpsize) != 0 || dumpsize != zv->zv_volsize) {
1888                 boolean_t resize = (dumpsize > 0) ? B_TRUE : B_FALSE;
1889 
1890                 if ((error = zvol_dump_init(zv, resize)) != 0) {
1891                         (void) zvol_dump_fini(zv);
1892                         return (error);
1893                 }
1894         }
1895 
1896         /*
1897          * Build up our lba mapping.
1898          */
1899         error = zvol_get_lbas(zv);
1900         if (error) {
1901                 (void) zvol_dump_fini(zv);
1902                 return (error);
1903         }
1904 
1905         tx = dmu_tx_create(os);
1906         dmu_tx_hold_zap(tx, ZVOL_ZAP_OBJ, TRUE, NULL);
1907         error = dmu_tx_assign(tx, TXG_WAIT);
1908         if (error) {




   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  23  *
  24  * Portions Copyright 2010 Robert Milkowski
  25  *
  26  * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
  27  * Copyright (c) 2012 by Delphix. All rights reserved.
  28  */
  29 
  30 /*
  31  * ZFS volume emulation driver.
  32  *
  33  * Makes a DMU object look like a volume of arbitrary size, up to 2^64 bytes.
  34  * Volumes are accessed through the symbolic links named:
  35  *
  36  * /dev/zvol/dsk/<pool_name>/<dataset_name>
  37  * /dev/zvol/rdsk/<pool_name>/<dataset_name>
  38  *
  39  * These links are created by the /dev filesystem (sdev_zvolops.c).
  40  * Volumes are persistent through reboot.  No user command needs to be
  41  * run before opening and using a device.
  42  */
  43 
  44 #include <sys/types.h>
  45 #include <sys/param.h>
  46 #include <sys/errno.h>
  47 #include <sys/uio.h>


 119         zilog_t         *zv_zilog;      /* ZIL handle */
 120         list_t          zv_extents;     /* List of extents for dump */
 121         znode_t         zv_znode;       /* for range locking */
 122         dmu_buf_t       *zv_dbuf;       /* bonus handle */
 123 } zvol_state_t;
 124 
 125 /*
 126  * zvol specific flags
 127  */
 128 #define ZVOL_RDONLY     0x1
 129 #define ZVOL_DUMPIFIED  0x2
 130 #define ZVOL_EXCL       0x4
 131 #define ZVOL_WCE        0x8
 132 
 133 /*
 134  * zvol maximum transfer in one DMU tx.
 135  */
 136 int zvol_maxphys = DMU_MAX_ACCESS/2;
 137 
 138 extern int zfs_set_prop_nvlist(const char *, zprop_source_t,
 139     nvlist_t *, nvlist_t *);
 140 static int zvol_remove_zv(zvol_state_t *);
 141 static int zvol_get_data(void *arg, lr_write_t *lr, char *buf, zio_t *zio);
 142 static int zvol_dumpify(zvol_state_t *zv);
 143 static int zvol_dump_fini(zvol_state_t *zv);
 144 static int zvol_dump_init(zvol_state_t *zv, boolean_t resize);
 145 
 146 static void
 147 zvol_size_changed(uint64_t volsize, major_t maj, minor_t min)
 148 {
 149         dev_t dev = makedevice(maj, min);
 150 
 151         VERIFY(ddi_prop_update_int64(dev, zfs_dip,
 152             "Size", volsize) == DDI_SUCCESS);
 153         VERIFY(ddi_prop_update_int64(dev, zfs_dip,
 154             "Nblocks", lbtodb(volsize)) == DDI_SUCCESS);
 155 
 156         /* Notify specfs to invalidate the cached size */
 157         spec_size_invalidate(dev, VBLK);
 158         spec_size_invalidate(dev, VCHR);
 159 }


1869         }
1870 
1871         /* Allocate the space for the dump */
1872         error = zvol_prealloc(zv);
1873         return (error);
1874 }
1875 
1876 static int
1877 zvol_dumpify(zvol_state_t *zv)
1878 {
1879         int error = 0;
1880         uint64_t dumpsize = 0;
1881         dmu_tx_t *tx;
1882         objset_t *os = zv->zv_objset;
1883 
1884         if (zv->zv_flags & ZVOL_RDONLY)
1885                 return (EROFS);
1886 
1887         if (zap_lookup(zv->zv_objset, ZVOL_ZAP_OBJ, ZVOL_DUMPSIZE,
1888             8, 1, &dumpsize) != 0 || dumpsize != zv->zv_volsize) {
1889                 boolean_t resize = (dumpsize > 0);
1890 
1891                 if ((error = zvol_dump_init(zv, resize)) != 0) {
1892                         (void) zvol_dump_fini(zv);
1893                         return (error);
1894                 }
1895         }
1896 
1897         /*
1898          * Build up our lba mapping.
1899          */
1900         error = zvol_get_lbas(zv);
1901         if (error) {
1902                 (void) zvol_dump_fini(zv);
1903                 return (error);
1904         }
1905 
1906         tx = dmu_tx_create(os);
1907         dmu_tx_hold_zap(tx, ZVOL_ZAP_OBJ, TRUE, NULL);
1908         error = dmu_tx_assign(tx, TXG_WAIT);
1909         if (error) {