initial commit
[freebsd-arm:freebsd-arm.git] / cddl / contrib / opensolaris / uts / common / fs / zfs / zvol.c
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
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) 2006 Pawel Jakub Dawidek <pjd@FreeBSD.org>
23  * All rights reserved.
24  */
25 /*
26  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
27  * Use is subject to license terms.
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 ZFS-specific devfsadm link generator.
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/kernel.h>
47 #include <sys/errno.h>
48 #include <sys/uio.h>
49 #include <sys/bio.h>
50 #include <sys/buf.h>
51 #include <sys/kmem.h>
52 #include <sys/conf.h>
53 #include <sys/cmn_err.h>
54 #include <sys/stat.h>
55 #include <sys/zap.h>
56 #include <sys/spa.h>
57 #include <sys/zio.h>
58 #include <sys/dmu_traverse.h>
59 #include <sys/dnode.h>
60 #include <sys/dsl_dataset.h>
61 #include <sys/dsl_prop.h>
62 #include <sys/dkio.h>
63 #include <sys/byteorder.h>
64 #include <sys/sunddi.h>
65 #include <sys/dirent.h>
66 #include <sys/policy.h>
67 #include <sys/fs/zfs.h>
68 #include <sys/zfs_ioctl.h>
69 #include <sys/zil.h>
70 #include <sys/refcount.h>
71 #include <sys/zfs_znode.h>
72 #include <sys/zfs_rlock.h>
73 #include <sys/vdev_impl.h>
74 #include <sys/zvol.h>
75 #include <geom/geom.h>
76
77 #include "zfs_namecheck.h"
78
79 #define ZVOL_DUMPSIZE   "dumpsize"
80
81 struct g_class zfs_zvol_class = {
82         .name = "ZFS::ZVOL",
83         .version = G_VERSION,
84 };
85
86 DECLARE_GEOM_CLASS(zfs_zvol_class, zfs_zvol);
87
88 /*
89  * This lock protects the zvol_state structure from being modified
90  * while it's being used, e.g. an open that comes in before a create
91  * finishes.  It also protects temporary opens of the dataset so that,
92  * e.g., an open doesn't get a spurious EBUSY.
93  */
94 static kmutex_t zvol_state_lock;
95 static uint32_t zvol_minors;
96
97 #define NUM_EXTENTS     ((SPA_MAXBLOCKSIZE) / sizeof (zvol_extent_t))
98
99 typedef struct zvol_extent {
100         dva_t           ze_dva;         /* dva associated with this extent */
101         uint64_t        ze_stride;      /* extent stride */
102         uint64_t        ze_size;        /* number of blocks in extent */
103 } zvol_extent_t;
104
105 /*
106  * The list of extents associated with the dump device
107  */
108 typedef struct zvol_ext_list {
109         zvol_extent_t           zl_extents[NUM_EXTENTS];
110         struct zvol_ext_list    *zl_next;
111 } zvol_ext_list_t;
112
113 /*
114  * The in-core state of each volume.
115  */
116 typedef struct zvol_state {
117         char            zv_name[MAXPATHLEN]; /* pool/dd name */
118         uint64_t        zv_volsize;     /* amount of space we advertise */
119         uint64_t        zv_volblocksize; /* volume block size */
120         struct g_provider *zv_provider; /* GEOM provider */
121         uint8_t         zv_min_bs;      /* minimum addressable block shift */
122         uint8_t         zv_flags;       /* readonly; dumpified */
123         objset_t        *zv_objset;     /* objset handle */
124         uint32_t        zv_mode;        /* DS_MODE_* flags at open time */
125         uint32_t        zv_total_opens; /* total open count */
126         zilog_t         *zv_zilog;      /* ZIL handle */
127         zvol_ext_list_t *zv_list;       /* List of extents for dump */
128         uint64_t        zv_txg_assign;  /* txg to assign during ZIL replay */
129         znode_t         zv_znode;       /* for range locking */
130         int             zv_state;
131         struct bio_queue_head zv_queue;
132         struct mtx      zv_queue_mtx;   /* zv_queue mutex */
133 } zvol_state_t;
134
135 /*
136  * zvol specific flags
137  */
138 #define ZVOL_RDONLY     0x1
139 #define ZVOL_DUMPIFIED  0x2
140 #define ZVOL_EXCL       0x4
141
142 /*
143  * zvol maximum transfer in one DMU tx.
144  */
145 int zvol_maxphys = DMU_MAX_ACCESS/2;
146
147 extern int zfs_set_prop_nvlist(const char *, nvlist_t *);
148 static int zvol_get_data(void *arg, lr_write_t *lr, char *buf, zio_t *zio);
149 static int zvol_dumpify(zvol_state_t *zv);
150 static int zvol_dump_fini(zvol_state_t *zv);
151 static int zvol_dump_init(zvol_state_t *zv, boolean_t resize);
152
153 static void
154 zvol_size_changed(zvol_state_t *zv, major_t maj)
155 {
156         struct g_provider *pp;
157
158         g_topology_assert();
159
160         pp = zv->zv_provider;
161         if (pp == NULL)
162                 return;
163         if (zv->zv_volsize == pp->mediasize)
164                 return;
165         /*
166          * Changing provider size is not really supported by GEOM, but it
167          * should be safe when provider is closed.
168          */
169         if (zv->zv_total_opens > 0)
170                 return;
171         pp->mediasize = zv->zv_volsize;
172 }
173
174 int
175 zvol_check_volsize(uint64_t volsize, uint64_t blocksize)
176 {
177         if (volsize == 0)
178                 return (EINVAL);
179
180         if (volsize % blocksize != 0)
181                 return (EINVAL);
182
183 #ifdef _ILP32
184         if (volsize - 1 > SPEC_MAXOFFSET_T)
185                 return (EOVERFLOW);
186 #endif
187         return (0);
188 }
189
190 int
191 zvol_check_volblocksize(uint64_t volblocksize)
192 {
193         if (volblocksize < SPA_MINBLOCKSIZE ||
194             volblocksize > SPA_MAXBLOCKSIZE ||
195             !ISP2(volblocksize))
196                 return (EDOM);
197
198         return (0);
199 }
200
201 static void
202 zvol_readonly_changed_cb(void *arg, uint64_t newval)
203 {
204         zvol_state_t *zv = arg;
205
206         if (newval)
207                 zv->zv_flags |= ZVOL_RDONLY;
208         else
209                 zv->zv_flags &= ~ZVOL_RDONLY;
210 }
211
212 int
213 zvol_get_stats(objset_t *os, nvlist_t *nv)
214 {
215         int error;
216         dmu_object_info_t doi;
217         uint64_t val;
218
219
220         error = zap_lookup(os, ZVOL_ZAP_OBJ, "size", 8, 1, &val);
221         if (error)
222                 return (error);
223
224         dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_VOLSIZE, val);
225
226         error = dmu_object_info(os, ZVOL_OBJ, &doi);
227
228         if (error == 0) {
229                 dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_VOLBLOCKSIZE,
230                     doi.doi_data_block_size);
231         }
232
233         return (error);
234 }
235
236 static zvol_state_t *
237 zvol_minor_lookup(const char *name)
238 {
239         struct g_provider *pp;
240         struct g_geom *gp;
241
242         g_topology_assert();
243         ASSERT(MUTEX_HELD(&zvol_state_lock));
244
245         LIST_FOREACH(gp, &zfs_zvol_class.geom, geom) {
246                 LIST_FOREACH(pp, &gp->provider, provider) {
247                         if (strcmp(pp->name + sizeof(ZVOL_DEV_DIR), name) == 0)
248                                 return (pp->private);
249                 }
250         }
251
252         return (NULL);
253 }
254
255 static int
256 zvol_access(struct g_provider *pp, int acr, int acw, int ace)
257 {
258         zvol_state_t *zv;
259
260         g_topology_assert();
261         mutex_enter(&zvol_state_lock);
262
263         zv = pp->private;
264         if (zv == NULL) {
265                 if (acr <= 0 && acw <= 0 && ace <= 0)
266                         return (0);
267                 mutex_exit(&zvol_state_lock);
268                 return (pp->error);
269         }
270
271         ASSERT(zv->zv_objset != NULL);
272
273         if (acw > 0 &&
274             ((zv->zv_flags & ZVOL_RDONLY) ||
275              (zv->zv_mode & DS_MODE_READONLY))) {
276                 mutex_exit(&zvol_state_lock);
277                 return (EROFS);
278         }
279
280         zv->zv_total_opens += acr + acw + ace;
281         zvol_size_changed(zv, 0);
282
283         mutex_exit(&zvol_state_lock);
284
285         return (0);
286 }
287
288 /*
289  * zvol_log_write() handles synchronous writes using TX_WRITE ZIL transactions.
290  *
291  * We store data in the log buffers if it's small enough.
292  * Otherwise we will later flush the data out via dmu_sync().
293  */
294 ssize_t zvol_immediate_write_sz = 32768;
295
296 static void
297 zvol_log_write(zvol_state_t *zv, dmu_tx_t *tx, offset_t off, ssize_t len)
298 {
299         uint32_t blocksize = zv->zv_volblocksize;
300         lr_write_t *lr;
301
302         while (len) {
303                 ssize_t nbytes = MIN(len, blocksize - P2PHASE(off, blocksize));
304                 itx_t *itx = zil_itx_create(TX_WRITE, sizeof (*lr));
305
306                 itx->itx_wr_state =
307                     len > zvol_immediate_write_sz ?  WR_INDIRECT : WR_NEED_COPY;
308                 itx->itx_private = zv;
309                 lr = (lr_write_t *)&itx->itx_lr;
310                 lr->lr_foid = ZVOL_OBJ;
311                 lr->lr_offset = off;
312                 lr->lr_length = nbytes;
313                 lr->lr_blkoff = off - P2ALIGN_TYPED(off, blocksize, uint64_t);
314                 BP_ZERO(&lr->lr_blkptr);
315
316                 (void) zil_itx_assign(zv->zv_zilog, itx, tx);
317                 len -= nbytes;
318                 off += nbytes;
319         }
320 }
321
322 static void
323 zvol_start(struct bio *bp)
324 {
325         zvol_state_t *zv;
326
327         switch (bp->bio_cmd) {
328         case BIO_READ:
329         case BIO_WRITE:
330         case BIO_FLUSH:
331                 zv = bp->bio_to->private;
332                 ASSERT(zv != NULL);
333                 mtx_lock(&zv->zv_queue_mtx);
334                 bioq_insert_tail(&zv->zv_queue, bp);
335                 wakeup_one(&zv->zv_queue);
336                 mtx_unlock(&zv->zv_queue_mtx);
337                 break;
338         case BIO_GETATTR:
339                 if (g_handleattr_int(bp, "ZFS::iszvol", 1))
340                         break;
341                 /* FALLTHROUGH */
342         case BIO_DELETE:
343         default:
344                 g_io_deliver(bp, EOPNOTSUPP);
345                 break;
346         }
347 }
348
349 static void
350 zvol_serve_one(zvol_state_t *zv, struct bio *bp)
351 {
352         uint64_t off, volsize;
353         size_t size, resid;
354         char *addr;
355         objset_t *os;
356         rl_t *rl;
357         int error = 0;
358         boolean_t reading;
359
360         off = bp->bio_offset;
361         volsize = zv->zv_volsize;
362
363         os = zv->zv_objset;
364         ASSERT(os != NULL);
365
366         addr = bp->bio_data;
367         resid = bp->bio_length;
368
369         error = 0;
370
371         /*
372          * There must be no buffer changes when doing a dmu_sync() because
373          * we can't change the data whilst calculating the checksum.
374          * A better approach than a per zvol rwlock would be to lock ranges.
375          */
376         reading = (bp->bio_cmd == BIO_READ);
377         rl = zfs_range_lock(&zv->zv_znode, off, resid,
378             reading ? RL_READER : RL_WRITER);
379
380         while (resid != 0 && off < volsize) {
381
382                 size = MIN(resid, zvol_maxphys); /* zvol_maxphys per tx */
383
384                 if (size > volsize - off)       /* don't write past the end */
385                         size = volsize - off;
386
387                 if (reading) {
388                         error = dmu_read(os, ZVOL_OBJ, off, size, addr);
389                 } else {
390                         dmu_tx_t *tx = dmu_tx_create(os);
391                         dmu_tx_hold_write(tx, ZVOL_OBJ, off, size);
392                         error = dmu_tx_assign(tx, TXG_WAIT);
393                         if (error) {
394                                 dmu_tx_abort(tx);
395                         } else {
396                                 dmu_write(os, ZVOL_OBJ, off, size, addr, tx);
397                                 zvol_log_write(zv, tx, off, size);
398                                 dmu_tx_commit(tx);
399                         }
400                 }
401                 if (error) {
402                         /* convert checksum errors into IO errors */
403                         if (error == ECKSUM)
404                                 error = EIO;
405                         break;
406                 }
407                 off += size;
408                 addr += size;
409                 resid -= size;
410         }
411         zfs_range_unlock(rl);
412
413         bp->bio_completed = bp->bio_length - resid;
414         if (bp->bio_completed < bp->bio_length)
415                 bp->bio_error = (off > volsize ? EINVAL : error);
416 }
417
418 static void
419 zvol_worker(void *arg)
420 {
421         zvol_state_t *zv;
422         struct bio *bp;
423
424         thread_lock(curthread);
425         sched_prio(curthread, PRIBIO);
426         thread_unlock(curthread);
427
428         zv = arg;
429         for (;;) {
430                 mtx_lock(&zv->zv_queue_mtx);
431                 bp = bioq_takefirst(&zv->zv_queue);
432                 if (bp == NULL) {
433                         if (zv->zv_state == 1) {
434                                 zv->zv_state = 2;
435                                 wakeup(&zv->zv_state);
436                                 mtx_unlock(&zv->zv_queue_mtx);
437                                 kthread_exit();
438                         }
439                         msleep(&zv->zv_queue, &zv->zv_queue_mtx, PRIBIO | PDROP,
440                             "zvol:io", 0);
441                         continue;
442                 }
443                 mtx_unlock(&zv->zv_queue_mtx);
444                 switch (bp->bio_cmd) {
445                 case BIO_FLUSH:
446                         break;
447                 case BIO_READ:
448                 case BIO_WRITE:
449                         zvol_serve_one(zv, bp);
450                         break;
451                 }
452
453                 if (bp->bio_cmd == BIO_FLUSH && !zil_disable)
454                         zil_commit(zv->zv_zilog, UINT64_MAX, ZVOL_OBJ);
455
456                 g_io_deliver(bp, bp->bio_error);
457         }
458 }
459
460 void
461 zvol_init_extent(zvol_extent_t *ze, blkptr_t *bp)
462 {
463         ze->ze_dva = bp->blk_dva[0];    /* structure assignment */
464         ze->ze_stride = 0;
465         ze->ze_size = 1;
466 }
467
468 /* extent mapping arg */
469 struct maparg {
470         zvol_ext_list_t *ma_list;
471         zvol_extent_t   *ma_extent;
472         int             ma_gang;
473 };
474
475 /*ARGSUSED*/
476 static int
477 zvol_map_block(traverse_blk_cache_t *bc, spa_t *spa, void *arg)
478 {
479         zbookmark_t *zb = &bc->bc_bookmark;
480         blkptr_t *bp = &bc->bc_blkptr;
481         void *data = bc->bc_data;
482         dnode_phys_t *dnp = bc->bc_dnode;
483         struct maparg *ma = (struct maparg *)arg;
484         uint64_t stride;
485
486         /* If there is an error, then keep trying to make progress */
487         if (bc->bc_errno)
488                 return (ERESTART);
489
490 #ifdef ZFS_DEBUG
491         if (zb->zb_level == -1) {
492                 ASSERT3U(BP_GET_TYPE(bp), ==, DMU_OT_OBJSET);
493                 ASSERT3U(BP_GET_LEVEL(bp), ==, 0);
494         } else {
495                 ASSERT3U(BP_GET_TYPE(bp), ==, dnp->dn_type);
496                 ASSERT3U(BP_GET_LEVEL(bp), ==, zb->zb_level);
497         }
498
499         if (zb->zb_level > 0) {
500                 uint64_t fill = 0;
501                 blkptr_t *bpx, *bpend;
502
503                 for (bpx = data, bpend = bpx + BP_GET_LSIZE(bp) / sizeof (*bpx);
504                     bpx < bpend; bpx++) {
505                         if (bpx->blk_birth != 0) {
506                                 fill += bpx->blk_fill;
507                         } else {
508                                 ASSERT(bpx->blk_fill == 0);
509                         }
510                 }
511                 ASSERT3U(fill, ==, bp->blk_fill);
512         }
513
514         if (zb->zb_level == 0 && dnp->dn_type == DMU_OT_DNODE) {
515                 uint64_t fill = 0;
516                 dnode_phys_t *dnx, *dnend;
517
518                 for (dnx = data, dnend = dnx + (BP_GET_LSIZE(bp)>>DNODE_SHIFT);
519                     dnx < dnend; dnx++) {
520                         if (dnx->dn_type != DMU_OT_NONE)
521                                 fill++;
522                 }
523                 ASSERT3U(fill, ==, bp->blk_fill);
524         }
525 #endif
526
527         if (zb->zb_level || dnp->dn_type == DMU_OT_DNODE)
528                 return (0);
529
530         /* Abort immediately if we have encountered gang blocks */
531         if (BP_IS_GANG(bp)) {
532                 ma->ma_gang++;
533                 return (EINTR);
534         }
535
536         /* first time? */
537         if (ma->ma_extent->ze_size == 0) {
538                 zvol_init_extent(ma->ma_extent, bp);
539                 return (0);
540         }
541
542         stride = (DVA_GET_OFFSET(&bp->blk_dva[0])) -
543             ((DVA_GET_OFFSET(&ma->ma_extent->ze_dva)) +
544             (ma->ma_extent->ze_size - 1) * (ma->ma_extent->ze_stride));
545         if (DVA_GET_VDEV(BP_IDENTITY(bp)) ==
546             DVA_GET_VDEV(&ma->ma_extent->ze_dva)) {
547                 if (ma->ma_extent->ze_stride == 0) {
548                         /* second block in this extent */
549                         ma->ma_extent->ze_stride = stride;
550                         ma->ma_extent->ze_size++;
551                         return (0);
552                 } else if (ma->ma_extent->ze_stride == stride) {
553                         /*
554                          * the block we allocated has the same
555                          * stride
556                          */
557                         ma->ma_extent->ze_size++;
558                         return (0);
559                 }
560         }
561
562         /*
563          * dtrace -n 'zfs-dprintf
564          * /stringof(arg0) == "zvol.c"/
565          * {
566          *      printf("%s: %s", stringof(arg1), stringof(arg3))
567          * } '
568          */
569         dprintf("ma_extent 0x%lx mrstride 0x%lx stride %lx\n",
570             ma->ma_extent->ze_size, ma->ma_extent->ze_stride, stride);
571         dprintf_bp(bp, "%s", "next blkptr:");
572         /* start a new extent */
573         if (ma->ma_extent == &ma->ma_list->zl_extents[NUM_EXTENTS - 1]) {
574                 ma->ma_list->zl_next = kmem_zalloc(sizeof (zvol_ext_list_t),
575                     KM_SLEEP);
576                 ma->ma_list = ma->ma_list->zl_next;
577                 ma->ma_extent = &ma->ma_list->zl_extents[0];
578         } else {
579                 ma->ma_extent++;
580         }
581         zvol_init_extent(ma->ma_extent, bp);
582         return (0);
583 }
584
585 /* ARGSUSED */
586 void
587 zvol_create_cb(objset_t *os, void *arg, cred_t *cr, dmu_tx_t *tx)
588 {
589         zfs_creat_t *zct = arg;
590         nvlist_t *nvprops = zct->zct_props;
591         int error;
592         uint64_t volblocksize, volsize;
593
594         VERIFY(nvlist_lookup_uint64(nvprops,
595             zfs_prop_to_name(ZFS_PROP_VOLSIZE), &volsize) == 0);
596         if (nvlist_lookup_uint64(nvprops,
597             zfs_prop_to_name(ZFS_PROP_VOLBLOCKSIZE), &volblocksize) != 0)
598                 volblocksize = zfs_prop_default_numeric(ZFS_PROP_VOLBLOCKSIZE);
599
600         /*
601          * These properties must be removed from the list so the generic
602          * property setting step won't apply to them.
603          */
604         VERIFY(nvlist_remove_all(nvprops,
605             zfs_prop_to_name(ZFS_PROP_VOLSIZE)) == 0);
606         (void) nvlist_remove_all(nvprops,
607             zfs_prop_to_name(ZFS_PROP_VOLBLOCKSIZE));
608
609         error = dmu_object_claim(os, ZVOL_OBJ, DMU_OT_ZVOL, volblocksize,
610             DMU_OT_NONE, 0, tx);
611         ASSERT(error == 0);
612
613         error = zap_create_claim(os, ZVOL_ZAP_OBJ, DMU_OT_ZVOL_PROP,
614             DMU_OT_NONE, 0, tx);
615         ASSERT(error == 0);
616
617         error = zap_update(os, ZVOL_ZAP_OBJ, "size", 8, 1, &volsize, tx);
618         ASSERT(error == 0);
619 }
620
621 /*
622  * Replay a TX_WRITE ZIL transaction that didn't get committed
623  * after a system failure
624  */
625 static int
626 zvol_replay_write(zvol_state_t *zv, lr_write_t *lr, boolean_t byteswap)
627 {
628         objset_t *os = zv->zv_objset;
629         char *data = (char *)(lr + 1);  /* data follows lr_write_t */
630         uint64_t off = lr->lr_offset;
631         uint64_t len = lr->lr_length;
632         dmu_tx_t *tx;
633         int error;
634
635         if (byteswap)
636                 byteswap_uint64_array(lr, sizeof (*lr));
637
638         tx = dmu_tx_create(os);
639         dmu_tx_hold_write(tx, ZVOL_OBJ, off, len);
640         error = dmu_tx_assign(tx, zv->zv_txg_assign);
641         if (error) {
642                 dmu_tx_abort(tx);
643         } else {
644                 dmu_write(os, ZVOL_OBJ, off, len, data, tx);
645                 dmu_tx_commit(tx);
646         }
647
648         return (error);
649 }
650
651 /* ARGSUSED */
652 static int
653 zvol_replay_err(zvol_state_t *zv, lr_t *lr, boolean_t byteswap)
654 {
655         return (ENOTSUP);
656 }
657
658 /*
659  * Callback vectors for replaying records.
660  * Only TX_WRITE is needed for zvol.
661  */
662 zil_replay_func_t *zvol_replay_vector[TX_MAX_TYPE] = {
663         zvol_replay_err,        /* 0 no such transaction type */
664         zvol_replay_err,        /* TX_CREATE */
665         zvol_replay_err,        /* TX_MKDIR */
666         zvol_replay_err,        /* TX_MKXATTR */
667         zvol_replay_err,        /* TX_SYMLINK */
668         zvol_replay_err,        /* TX_REMOVE */
669         zvol_replay_err,        /* TX_RMDIR */
670         zvol_replay_err,        /* TX_LINK */
671         zvol_replay_err,        /* TX_RENAME */
672         zvol_replay_write,      /* TX_WRITE */
673         zvol_replay_err,        /* TX_TRUNCATE */
674         zvol_replay_err,        /* TX_SETATTR */
675         zvol_replay_err,        /* TX_ACL */
676 };
677
678 /*
679  * reconstruct dva that gets us to the desired offset (offset
680  * is in bytes)
681  */
682 int
683 zvol_get_dva(zvol_state_t *zv, uint64_t offset, dva_t *dva)
684 {
685         zvol_ext_list_t *zl;
686         zvol_extent_t   *ze;
687         int             idx;
688         uint64_t        tmp;
689
690         if ((zl = zv->zv_list) == NULL)
691                 return (EIO);
692         idx = 0;
693         ze =  &zl->zl_extents[0];
694         while (offset >= ze->ze_size * zv->zv_volblocksize) {
695                 offset -= ze->ze_size * zv->zv_volblocksize;
696
697                 if (idx == NUM_EXTENTS - 1) {
698                         /* we've reached the end of this array */
699                         ASSERT(zl->zl_next != NULL);
700                         if (zl->zl_next == NULL)
701                                 return (-1);
702                         zl = zl->zl_next;
703                         ze = &zl->zl_extents[0];
704                         idx = 0;
705                 } else {
706                         ze++;
707                         idx++;
708                 }
709         }
710         DVA_SET_VDEV(dva, DVA_GET_VDEV(&ze->ze_dva));
711         tmp = DVA_GET_OFFSET((&ze->ze_dva));
712         tmp += (ze->ze_stride * (offset / zv->zv_volblocksize));
713         DVA_SET_OFFSET(dva, tmp);
714         return (0);
715 }
716
717 static void
718 zvol_free_extents(zvol_state_t *zv)
719 {
720         zvol_ext_list_t *zl;
721         zvol_ext_list_t *tmp;
722
723         if (zv->zv_list != NULL) {
724                 zl = zv->zv_list;
725                 while (zl != NULL) {
726                         tmp = zl->zl_next;
727                         kmem_free(zl, sizeof (zvol_ext_list_t));
728                         zl = tmp;
729                 }
730                 zv->zv_list = NULL;
731         }
732 }
733
734 int
735 zvol_get_lbas(zvol_state_t *zv)
736 {
737         struct maparg   ma;
738         zvol_ext_list_t *zl;
739         zvol_extent_t   *ze;
740         uint64_t        blocks = 0;
741         int             err;
742
743         ma.ma_list = zl = kmem_zalloc(sizeof (zvol_ext_list_t), KM_SLEEP);
744         ma.ma_extent = &ma.ma_list->zl_extents[0];
745         ma.ma_gang = 0;
746         zv->zv_list = ma.ma_list;
747
748         err = traverse_zvol(zv->zv_objset, ADVANCE_PRE, zvol_map_block, &ma);
749         if (err == EINTR && ma.ma_gang) {
750                 /*
751                  * We currently don't support dump devices when the pool
752                  * is so fragmented that our allocation has resulted in
753                  * gang blocks.
754                  */
755                 zvol_free_extents(zv);
756                 return (EFRAGS);
757         }
758         ASSERT3U(err, ==, 0);
759
760         ze = &zl->zl_extents[0];
761         while (ze) {
762                 blocks += ze->ze_size;
763                 if (ze == &zl->zl_extents[NUM_EXTENTS - 1]) {
764                         zl = zl->zl_next;
765                         ze = &zl->zl_extents[0];
766                 } else {
767                         ze++;
768                 }
769         }
770         if (blocks != (zv->zv_volsize / zv->zv_volblocksize)) {
771                 zvol_free_extents(zv);
772                 return (EIO);
773         }
774
775         return (0);
776 }
777
778 /*
779  * Create a minor node (plus a whole lot more) for the specified volume.
780  */
781 int
782 zvol_create_minor(const char *name, major_t maj)
783 {
784         struct g_provider *pp;
785         struct g_geom *gp;
786         zvol_state_t *zv;
787         objset_t *os;
788         dmu_object_info_t doi;
789         uint64_t volsize;
790         int ds_mode = DS_MODE_OWNER;
791         int error;
792
793         DROP_GIANT();
794         g_topology_lock();
795         mutex_enter(&zvol_state_lock);
796
797         if ((zv = zvol_minor_lookup(name)) != NULL) {
798                 error = EEXIST;
799                 goto end;
800         }
801
802         if (strchr(name, '@') != 0)
803                 ds_mode |= DS_MODE_READONLY;
804
805         error = dmu_objset_open(name, DMU_OST_ZVOL, ds_mode, &os);
806         if (error)
807                 goto end;
808
809         error = zap_lookup(os, ZVOL_ZAP_OBJ, "size", 8, 1, &volsize);
810         if (error) {
811                 dmu_objset_close(os);
812                 goto end;
813         }
814
815         gp = g_new_geomf(&zfs_zvol_class, "zfs::zvol::%s", name);
816         gp->start = zvol_start;
817         gp->access = zvol_access;
818         pp = g_new_providerf(gp, "%s/%s", ZVOL_DEV_DIR, name);
819         pp->mediasize = volsize;
820         pp->sectorsize = DEV_BSIZE;
821
822         zv = kmem_zalloc(sizeof(*zv), KM_SLEEP);
823         (void) strcpy(zv->zv_name, name);
824         zv->zv_min_bs = DEV_BSHIFT;
825         zv->zv_provider = pp;
826         zv->zv_volsize = pp->mediasize;
827         zv->zv_objset = os;
828         zv->zv_mode = ds_mode;
829         zv->zv_zilog = zil_open(os, zvol_get_data);
830         mutex_init(&zv->zv_znode.z_range_lock, NULL, MUTEX_DEFAULT, NULL);
831         avl_create(&zv->zv_znode.z_range_avl, zfs_range_compare,
832             sizeof (rl_t), offsetof(rl_t, r_node));
833         /* get and cache the blocksize */
834         error = dmu_object_info(os, ZVOL_OBJ, &doi);
835         ASSERT(error == 0);
836         zv->zv_volblocksize = doi.doi_data_block_size;
837
838         zil_replay(os, zv, &zv->zv_txg_assign, zvol_replay_vector, NULL);
839
840         /* XXX this should handle the possible i/o error */
841         VERIFY(dsl_prop_register(dmu_objset_ds(zv->zv_objset),
842             "readonly", zvol_readonly_changed_cb, zv) == 0);
843
844         pp->private = zv;
845         g_error_provider(pp, 0);
846
847         bioq_init(&zv->zv_queue);
848         mtx_init(&zv->zv_queue_mtx, "zvol", NULL, MTX_DEF);
849         zv->zv_state = 0;
850         kproc_kthread_add(zvol_worker, zv, &zfsproc, NULL, 0, 0, "zfskern",
851             "zvol %s", pp->name + strlen(ZVOL_DEV_DIR) + 1);
852
853         zvol_minors++;
854 end:
855         mutex_exit(&zvol_state_lock);
856         g_topology_unlock();
857         PICKUP_GIANT();
858
859         return (error);
860 }
861
862 /*
863  * Remove minor node for the specified volume.
864  */
865 int
866 zvol_remove_minor(const char *name)
867 {
868         struct g_provider *pp;
869         zvol_state_t *zv;
870         int error = 0;
871
872         DROP_GIANT();
873         g_topology_lock();
874         mutex_enter(&zvol_state_lock);
875
876         if ((zv = zvol_minor_lookup(name)) == NULL) {
877                 error = ENXIO;
878                 goto end;
879         }
880
881         if (zv->zv_total_opens != 0) {
882                 error = EBUSY;
883                 goto end;
884         }
885
886         VERIFY(dsl_prop_unregister(dmu_objset_ds(zv->zv_objset),
887             "readonly", zvol_readonly_changed_cb, zv) == 0);
888
889         mtx_lock(&zv->zv_queue_mtx);
890         zv->zv_state = 1;
891         wakeup_one(&zv->zv_queue);
892         while (zv->zv_state != 2)
893                 msleep(&zv->zv_state, &zv->zv_queue_mtx, 0, "zvol:w", 0);
894         mtx_unlock(&zv->zv_queue_mtx);
895         mtx_destroy(&zv->zv_queue_mtx);
896
897         pp = zv->zv_provider;
898         pp->private = NULL;
899         g_wither_geom(pp->geom, ENXIO);
900
901         zil_close(zv->zv_zilog);
902         zv->zv_zilog = NULL;
903         dmu_objset_close(zv->zv_objset);
904         zv->zv_objset = NULL;
905         avl_destroy(&zv->zv_znode.z_range_avl);
906         mutex_destroy(&zv->zv_znode.z_range_lock);
907
908         kmem_free(zv, sizeof(*zv));
909
910         zvol_minors--;
911 end:
912         mutex_exit(&zvol_state_lock);
913         g_topology_unlock();
914         PICKUP_GIANT();
915
916         return (error);
917 }
918
919 int
920 zvol_prealloc(zvol_state_t *zv)
921 {
922         objset_t *os = zv->zv_objset;
923         dmu_tx_t *tx;
924         void *data;
925         uint64_t refd, avail, usedobjs, availobjs;
926         uint64_t resid = zv->zv_volsize;
927         uint64_t off = 0;
928
929         /* Check the space usage before attempting to allocate the space */
930         dmu_objset_space(os, &refd, &avail, &usedobjs, &availobjs);
931         if (avail < zv->zv_volsize)
932                 return (ENOSPC);
933
934         /* Free old extents if they exist */
935         zvol_free_extents(zv);
936
937         /* allocate the blocks by writing each one */
938         data = kmem_zalloc(SPA_MAXBLOCKSIZE, KM_SLEEP);
939
940         while (resid != 0) {
941                 int error;
942                 uint64_t bytes = MIN(resid, SPA_MAXBLOCKSIZE);
943
944                 tx = dmu_tx_create(os);
945                 dmu_tx_hold_write(tx, ZVOL_OBJ, off, bytes);
946                 error = dmu_tx_assign(tx, TXG_WAIT);
947                 if (error) {
948                         dmu_tx_abort(tx);
949                         kmem_free(data, SPA_MAXBLOCKSIZE);
950                         (void) dmu_free_long_range(os, ZVOL_OBJ, 0, off);
951                         return (error);
952                 }
953                 dmu_write(os, ZVOL_OBJ, off, bytes, data, tx);
954                 dmu_tx_commit(tx);
955                 off += bytes;
956                 resid -= bytes;
957         }
958         kmem_free(data, SPA_MAXBLOCKSIZE);
959         txg_wait_synced(dmu_objset_pool(os), 0);
960
961         return (0);
962 }
963
964 int
965 zvol_update_volsize(zvol_state_t *zv, major_t maj, uint64_t volsize)
966 {
967         dmu_tx_t *tx;
968         int error;
969
970         ASSERT(MUTEX_HELD(&zvol_state_lock));
971
972         tx = dmu_tx_create(zv->zv_objset);
973         dmu_tx_hold_zap(tx, ZVOL_ZAP_OBJ, TRUE, NULL);
974         error = dmu_tx_assign(tx, TXG_WAIT);
975         if (error) {
976                 dmu_tx_abort(tx);
977                 return (error);
978         }
979
980         error = zap_update(zv->zv_objset, ZVOL_ZAP_OBJ, "size", 8, 1,
981             &volsize, tx);
982         dmu_tx_commit(tx);
983
984         if (error == 0)
985                 error = dmu_free_long_range(zv->zv_objset,
986                     ZVOL_OBJ, volsize, DMU_OBJECT_END);
987
988         /*
989          * If we are using a faked-up state (zv_provider == NULL) then don't
990          * try to update the in-core zvol state.
991          */
992         if (error == 0 && zv->zv_provider) {
993                 zv->zv_volsize = volsize;
994                 zvol_size_changed(zv, maj);
995         }
996         return (error);
997 }
998
999 int
1000 zvol_set_volsize(const char *name, major_t maj, uint64_t volsize)
1001 {
1002         zvol_state_t *zv;
1003         int error;
1004         dmu_object_info_t doi;
1005         uint64_t old_volsize = 0ULL;
1006         zvol_state_t state = { 0 };
1007
1008         DROP_GIANT();
1009         g_topology_lock();
1010         mutex_enter(&zvol_state_lock);
1011
1012         if ((zv = zvol_minor_lookup(name)) == NULL) {
1013                 /*
1014                  * If we are doing a "zfs clone -o volsize=", then the
1015                  * minor node won't exist yet.
1016                  */
1017                 error = dmu_objset_open(name, DMU_OST_ZVOL, DS_MODE_OWNER,
1018                     &state.zv_objset);
1019                 if (error != 0)
1020                         goto out;
1021                 zv = &state;
1022         }
1023         old_volsize = zv->zv_volsize;
1024
1025         if ((error = dmu_object_info(zv->zv_objset, ZVOL_OBJ, &doi)) != 0 ||
1026             (error = zvol_check_volsize(volsize,
1027             doi.doi_data_block_size)) != 0)
1028                 goto out;
1029
1030         if (zv->zv_flags & ZVOL_RDONLY || (zv->zv_mode & DS_MODE_READONLY)) {
1031                 error = EROFS;
1032                 goto out;
1033         }
1034
1035         error = zvol_update_volsize(zv, maj, volsize);
1036
1037 #if 0
1038         /*
1039          * Reinitialize the dump area to the new size. If we
1040          * failed to resize the dump area then restore the it back to
1041          * it's original size.
1042          */
1043         if (error == 0 && zv->zv_flags & ZVOL_DUMPIFIED) {
1044                 if ((error = zvol_dumpify(zv)) != 0 ||
1045                     (error = dumpvp_resize()) != 0) {
1046                         (void) zvol_update_volsize(zv, maj, old_volsize);
1047                         error = zvol_dumpify(zv);
1048                 }
1049         }
1050 #endif
1051
1052 out:
1053         if (state.zv_objset)
1054                 dmu_objset_close(state.zv_objset);
1055
1056         mutex_exit(&zvol_state_lock);
1057         g_topology_unlock();
1058         PICKUP_GIANT();
1059
1060         return (error);
1061 }
1062
1063 int
1064 zvol_set_volblocksize(const char *name, uint64_t volblocksize)
1065 {
1066         zvol_state_t *zv;
1067         dmu_tx_t *tx;
1068         int error;
1069
1070         DROP_GIANT();
1071         g_topology_lock();
1072         mutex_enter(&zvol_state_lock);
1073
1074         if ((zv = zvol_minor_lookup(name)) == NULL) {
1075                 error = ENXIO;
1076                 goto end;
1077         }
1078         if (zv->zv_flags & ZVOL_RDONLY || (zv->zv_mode & DS_MODE_READONLY)) {
1079                 error = EROFS;
1080                 goto end;
1081         }
1082
1083         tx = dmu_tx_create(zv->zv_objset);
1084         dmu_tx_hold_bonus(tx, ZVOL_OBJ);
1085         error = dmu_tx_assign(tx, TXG_WAIT);
1086         if (error) {
1087                 dmu_tx_abort(tx);
1088         } else {
1089                 error = dmu_object_set_blocksize(zv->zv_objset, ZVOL_OBJ,
1090                     volblocksize, 0, tx);
1091                 if (error == ENOTSUP)
1092                         error = EBUSY;
1093                 dmu_tx_commit(tx);
1094         }
1095 end:
1096         mutex_exit(&zvol_state_lock);
1097         g_topology_unlock();
1098         PICKUP_GIANT();
1099
1100         return (error);
1101 }
1102
1103 void
1104 zvol_get_done(dmu_buf_t *db, void *vzgd)
1105 {
1106         zgd_t *zgd = (zgd_t *)vzgd;
1107         rl_t *rl = zgd->zgd_rl;
1108
1109         dmu_buf_rele(db, vzgd);
1110         zfs_range_unlock(rl);
1111         zil_add_block(zgd->zgd_zilog, zgd->zgd_bp);
1112         kmem_free(zgd, sizeof (zgd_t));
1113 }
1114
1115 /*
1116  * Get data to generate a TX_WRITE intent log record.
1117  */
1118 static int
1119 zvol_get_data(void *arg, lr_write_t *lr, char *buf, zio_t *zio)
1120 {
1121         zvol_state_t *zv = arg;
1122         objset_t *os = zv->zv_objset;
1123         dmu_buf_t *db;
1124         rl_t *rl;
1125         zgd_t *zgd;
1126         uint64_t boff;                  /* block starting offset */
1127         int dlen = lr->lr_length;       /* length of user data */
1128         int error;
1129
1130         ASSERT(zio);
1131         ASSERT(dlen != 0);
1132
1133         /*
1134          * Write records come in two flavors: immediate and indirect.
1135          * For small writes it's cheaper to store the data with the
1136          * log record (immediate); for large writes it's cheaper to
1137          * sync the data and get a pointer to it (indirect) so that
1138          * we don't have to write the data twice.
1139          */
1140         if (buf != NULL) /* immediate write */
1141                 return (dmu_read(os, ZVOL_OBJ, lr->lr_offset, dlen, buf));
1142
1143         zgd = (zgd_t *)kmem_alloc(sizeof (zgd_t), KM_SLEEP);
1144         zgd->zgd_zilog = zv->zv_zilog;
1145         zgd->zgd_bp = &lr->lr_blkptr;
1146
1147         /*
1148          * Lock the range of the block to ensure that when the data is
1149          * written out and its checksum is being calculated that no other
1150          * thread can change the block.
1151          */
1152         boff = P2ALIGN_TYPED(lr->lr_offset, zv->zv_volblocksize, uint64_t);
1153         rl = zfs_range_lock(&zv->zv_znode, boff, zv->zv_volblocksize,
1154             RL_READER);
1155         zgd->zgd_rl = rl;
1156
1157         VERIFY(0 == dmu_buf_hold(os, ZVOL_OBJ, lr->lr_offset, zgd, &db));
1158         error = dmu_sync(zio, db, &lr->lr_blkptr,
1159             lr->lr_common.lrc_txg, zvol_get_done, zgd);
1160         if (error == 0)
1161                 zil_add_block(zv->zv_zilog, &lr->lr_blkptr);
1162         /*
1163          * If we get EINPROGRESS, then we need to wait for a
1164          * write IO initiated by dmu_sync() to complete before
1165          * we can release this dbuf.  We will finish everything
1166          * up in the zvol_get_done() callback.
1167          */
1168         if (error == EINPROGRESS)
1169                 return (0);
1170         dmu_buf_rele(db, zgd);
1171         zfs_range_unlock(rl);
1172         kmem_free(zgd, sizeof (zgd_t));
1173         return (error);
1174 }
1175
1176 int
1177 zvol_busy(void)
1178 {
1179         return (zvol_minors != 0);
1180 }
1181
1182 void
1183 zvol_init(void)
1184 {
1185         mutex_init(&zvol_state_lock, NULL, MUTEX_DEFAULT, NULL);
1186         ZFS_LOG(1, "ZVOL Initialized.");
1187 }
1188
1189 void
1190 zvol_fini(void)
1191 {
1192         mutex_destroy(&zvol_state_lock);
1193         ZFS_LOG(1, "ZVOL Deinitialized.");
1194 }
1195
1196 static boolean_t
1197 zvol_is_swap(zvol_state_t *zv)
1198 {
1199         vnode_t *vp;
1200         boolean_t ret = B_FALSE;
1201         char *devpath;
1202         size_t devpathlen;
1203         int error;
1204
1205 #if 0
1206         devpathlen = strlen(ZVOL_FULL_DEV_DIR) + strlen(zv->zv_name) + 1;
1207         devpath = kmem_alloc(devpathlen, KM_SLEEP);
1208         (void) sprintf(devpath, "%s%s", ZVOL_FULL_DEV_DIR, zv->zv_name);
1209         error = lookupname(devpath, UIO_SYSSPACE, FOLLOW, NULLVPP, &vp);
1210         kmem_free(devpath, devpathlen);
1211
1212         ret = !error && IS_SWAPVP(common_specvp(vp));
1213
1214         if (vp != NULL)
1215                 VN_RELE(vp);
1216 #endif
1217
1218         return (ret);
1219 }
1220
1221 static int
1222 zvol_dump_init(zvol_state_t *zv, boolean_t resize)
1223 {
1224         dmu_tx_t *tx;
1225         int error = 0;
1226         objset_t *os = zv->zv_objset;
1227         nvlist_t *nv = NULL;
1228         uint64_t checksum, compress, refresrv;
1229
1230         ASSERT(MUTEX_HELD(&zvol_state_lock));
1231
1232         tx = dmu_tx_create(os);
1233         dmu_tx_hold_zap(tx, ZVOL_ZAP_OBJ, TRUE, NULL);
1234         error = dmu_tx_assign(tx, TXG_WAIT);
1235         if (error) {
1236                 dmu_tx_abort(tx);
1237                 return (error);
1238         }
1239
1240         /*
1241          * If we are resizing the dump device then we only need to
1242          * update the refreservation to match the newly updated
1243          * zvolsize. Otherwise, we save off the original state of the
1244          * zvol so that we can restore them if the zvol is ever undumpified.
1245          */
1246         if (resize) {
1247                 error = zap_update(os, ZVOL_ZAP_OBJ,
1248                     zfs_prop_to_name(ZFS_PROP_REFRESERVATION), 8, 1,
1249                     &zv->zv_volsize, tx);
1250         } else {
1251                 error = dsl_prop_get_integer(zv->zv_name,
1252                     zfs_prop_to_name(ZFS_PROP_COMPRESSION), &compress, NULL);
1253                 error = error ? error : dsl_prop_get_integer(zv->zv_name,
1254                     zfs_prop_to_name(ZFS_PROP_CHECKSUM), &checksum, NULL);
1255                 error = error ? error : dsl_prop_get_integer(zv->zv_name,
1256                     zfs_prop_to_name(ZFS_PROP_REFRESERVATION), &refresrv, NULL);
1257
1258                 error = error ? error : zap_update(os, ZVOL_ZAP_OBJ,
1259                     zfs_prop_to_name(ZFS_PROP_COMPRESSION), 8, 1,
1260                     &compress, tx);
1261                 error = error ? error : zap_update(os, ZVOL_ZAP_OBJ,
1262                     zfs_prop_to_name(ZFS_PROP_CHECKSUM), 8, 1, &checksum, tx);
1263                 error = error ? error : zap_update(os, ZVOL_ZAP_OBJ,
1264                     zfs_prop_to_name(ZFS_PROP_REFRESERVATION), 8, 1,
1265                     &refresrv, tx);
1266         }
1267         dmu_tx_commit(tx);
1268
1269         /* Truncate the file */
1270         if (!error)
1271                 error = dmu_free_long_range(zv->zv_objset,
1272                     ZVOL_OBJ, 0, DMU_OBJECT_END);
1273
1274         if (error)
1275                 return (error);
1276
1277         /*
1278          * We only need update the zvol's property if we are initializing
1279          * the dump area for the first time.
1280          */
1281         if (!resize) {
1282                 VERIFY(nvlist_alloc(&nv, NV_UNIQUE_NAME, KM_SLEEP) == 0);
1283                 VERIFY(nvlist_add_uint64(nv,
1284                     zfs_prop_to_name(ZFS_PROP_REFRESERVATION), 0) == 0);
1285                 VERIFY(nvlist_add_uint64(nv,
1286                     zfs_prop_to_name(ZFS_PROP_COMPRESSION),
1287                     ZIO_COMPRESS_OFF) == 0);
1288                 VERIFY(nvlist_add_uint64(nv,
1289                     zfs_prop_to_name(ZFS_PROP_CHECKSUM),
1290                     ZIO_CHECKSUM_OFF) == 0);
1291
1292                 error = zfs_set_prop_nvlist(zv->zv_name, nv);
1293                 nvlist_free(nv);
1294
1295                 if (error)
1296                         return (error);
1297         }
1298
1299         /* Allocate the space for the dump */
1300         error = zvol_prealloc(zv);
1301         return (error);
1302 }
1303
1304 static int
1305 zvol_dumpify(zvol_state_t *zv)
1306 {
1307         int error = 0;
1308         uint64_t dumpsize = 0;
1309         dmu_tx_t *tx;
1310         objset_t *os = zv->zv_objset;
1311
1312         if (zv->zv_flags & ZVOL_RDONLY || (zv->zv_mode & DS_MODE_READONLY))
1313                 return (EROFS);
1314
1315         /*
1316          * We do not support swap devices acting as dump devices.
1317          */
1318         if (zvol_is_swap(zv))
1319                 return (ENOTSUP);
1320
1321         if (zap_lookup(zv->zv_objset, ZVOL_ZAP_OBJ, ZVOL_DUMPSIZE,
1322             8, 1, &dumpsize) != 0 || dumpsize != zv->zv_volsize) {
1323                 boolean_t resize = (dumpsize > 0) ? B_TRUE : B_FALSE;
1324
1325                 if ((error = zvol_dump_init(zv, resize)) != 0) {
1326                         (void) zvol_dump_fini(zv);
1327                         return (error);
1328                 }
1329         }
1330
1331         /*
1332          * Build up our lba mapping.
1333          */
1334         error = zvol_get_lbas(zv);
1335         if (error) {
1336                 (void) zvol_dump_fini(zv);
1337                 return (error);
1338         }
1339
1340         tx = dmu_tx_create(os);
1341         dmu_tx_hold_zap(tx, ZVOL_ZAP_OBJ, TRUE, NULL);
1342         error = dmu_tx_assign(tx, TXG_WAIT);
1343         if (error) {
1344                 dmu_tx_abort(tx);
1345                 (void) zvol_dump_fini(zv);
1346                 return (error);
1347         }
1348
1349         zv->zv_flags |= ZVOL_DUMPIFIED;
1350         error = zap_update(os, ZVOL_ZAP_OBJ, ZVOL_DUMPSIZE, 8, 1,
1351             &zv->zv_volsize, tx);
1352         dmu_tx_commit(tx);
1353
1354         if (error) {
1355                 (void) zvol_dump_fini(zv);
1356                 return (error);
1357         }
1358
1359         txg_wait_synced(dmu_objset_pool(os), 0);
1360         return (0);
1361 }
1362
1363 static int
1364 zvol_dump_fini(zvol_state_t *zv)
1365 {
1366         dmu_tx_t *tx;
1367         objset_t *os = zv->zv_objset;
1368         nvlist_t *nv;
1369         int error = 0;
1370         uint64_t checksum, compress, refresrv;
1371
1372         /*
1373          * Attempt to restore the zvol back to its pre-dumpified state.
1374          * This is a best-effort attempt as it's possible that not all
1375          * of these properties were initialized during the dumpify process
1376          * (i.e. error during zvol_dump_init).
1377          */
1378
1379         tx = dmu_tx_create(os);
1380         dmu_tx_hold_zap(tx, ZVOL_ZAP_OBJ, TRUE, NULL);
1381         error = dmu_tx_assign(tx, TXG_WAIT);
1382         if (error) {
1383                 dmu_tx_abort(tx);
1384                 return (error);
1385         }
1386         (void) zap_remove(os, ZVOL_ZAP_OBJ, ZVOL_DUMPSIZE, tx);
1387         dmu_tx_commit(tx);
1388
1389         (void) zap_lookup(zv->zv_objset, ZVOL_ZAP_OBJ,
1390             zfs_prop_to_name(ZFS_PROP_CHECKSUM), 8, 1, &checksum);
1391         (void) zap_lookup(zv->zv_objset, ZVOL_ZAP_OBJ,
1392             zfs_prop_to_name(ZFS_PROP_COMPRESSION), 8, 1, &compress);
1393         (void) zap_lookup(zv->zv_objset, ZVOL_ZAP_OBJ,
1394             zfs_prop_to_name(ZFS_PROP_REFRESERVATION), 8, 1, &refresrv);
1395
1396         VERIFY(nvlist_alloc(&nv, NV_UNIQUE_NAME, KM_SLEEP) == 0);
1397         (void) nvlist_add_uint64(nv,
1398             zfs_prop_to_name(ZFS_PROP_CHECKSUM), checksum);
1399         (void) nvlist_add_uint64(nv,
1400             zfs_prop_to_name(ZFS_PROP_COMPRESSION), compress);
1401         (void) nvlist_add_uint64(nv,
1402             zfs_prop_to_name(ZFS_PROP_REFRESERVATION), refresrv);
1403         (void) zfs_set_prop_nvlist(zv->zv_name, nv);
1404         nvlist_free(nv);
1405
1406         zvol_free_extents(zv);
1407         zv->zv_flags &= ~ZVOL_DUMPIFIED;
1408         (void) dmu_free_long_range(os, ZVOL_OBJ, 0, DMU_OBJECT_END);
1409
1410         return (0);
1411 }