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) {
|