]> CyberLeo.Net >> Repos - FreeBSD/releng/7.2.git/blob - sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_objset.c
Create releng/7.2 from stable/7 in preparation for 7.2-RELEASE.
[FreeBSD/releng/7.2.git] / sys / cddl / contrib / opensolaris / uts / common / fs / zfs / dmu_objset.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 2007 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25
26 #pragma ident   "%Z%%M% %I%     %E% SMI"
27
28 #include <sys/zfs_context.h>
29 #include <sys/dmu_objset.h>
30 #include <sys/dsl_dir.h>
31 #include <sys/dsl_dataset.h>
32 #include <sys/dsl_prop.h>
33 #include <sys/dsl_pool.h>
34 #include <sys/dsl_synctask.h>
35 #include <sys/dnode.h>
36 #include <sys/dbuf.h>
37 #include <sys/zvol.h>
38 #include <sys/dmu_tx.h>
39 #include <sys/zio_checksum.h>
40 #include <sys/zap.h>
41 #include <sys/zil.h>
42 #include <sys/dmu_impl.h>
43
44
45 spa_t *
46 dmu_objset_spa(objset_t *os)
47 {
48         return (os->os->os_spa);
49 }
50
51 zilog_t *
52 dmu_objset_zil(objset_t *os)
53 {
54         return (os->os->os_zil);
55 }
56
57 dsl_pool_t *
58 dmu_objset_pool(objset_t *os)
59 {
60         dsl_dataset_t *ds;
61
62         if ((ds = os->os->os_dsl_dataset) != NULL && ds->ds_dir)
63                 return (ds->ds_dir->dd_pool);
64         else
65                 return (spa_get_dsl(os->os->os_spa));
66 }
67
68 dsl_dataset_t *
69 dmu_objset_ds(objset_t *os)
70 {
71         return (os->os->os_dsl_dataset);
72 }
73
74 dmu_objset_type_t
75 dmu_objset_type(objset_t *os)
76 {
77         return (os->os->os_phys->os_type);
78 }
79
80 void
81 dmu_objset_name(objset_t *os, char *buf)
82 {
83         dsl_dataset_name(os->os->os_dsl_dataset, buf);
84 }
85
86 uint64_t
87 dmu_objset_id(objset_t *os)
88 {
89         dsl_dataset_t *ds = os->os->os_dsl_dataset;
90
91         return (ds ? ds->ds_object : 0);
92 }
93
94 static void
95 checksum_changed_cb(void *arg, uint64_t newval)
96 {
97         objset_impl_t *osi = arg;
98
99         /*
100          * Inheritance should have been done by now.
101          */
102         ASSERT(newval != ZIO_CHECKSUM_INHERIT);
103
104         osi->os_checksum = zio_checksum_select(newval, ZIO_CHECKSUM_ON_VALUE);
105 }
106
107 static void
108 compression_changed_cb(void *arg, uint64_t newval)
109 {
110         objset_impl_t *osi = arg;
111
112         /*
113          * Inheritance and range checking should have been done by now.
114          */
115         ASSERT(newval != ZIO_COMPRESS_INHERIT);
116
117         osi->os_compress = zio_compress_select(newval, ZIO_COMPRESS_ON_VALUE);
118 }
119
120 static void
121 copies_changed_cb(void *arg, uint64_t newval)
122 {
123         objset_impl_t *osi = arg;
124
125         /*
126          * Inheritance and range checking should have been done by now.
127          */
128         ASSERT(newval > 0);
129         ASSERT(newval <= spa_max_replication(osi->os_spa));
130
131         osi->os_copies = newval;
132 }
133
134 void
135 dmu_objset_byteswap(void *buf, size_t size)
136 {
137         objset_phys_t *osp = buf;
138
139         ASSERT(size == sizeof (objset_phys_t));
140         dnode_byteswap(&osp->os_meta_dnode);
141         byteswap_uint64_array(&osp->os_zil_header, sizeof (zil_header_t));
142         osp->os_type = BSWAP_64(osp->os_type);
143 }
144
145 int
146 dmu_objset_open_impl(spa_t *spa, dsl_dataset_t *ds, blkptr_t *bp,
147     objset_impl_t **osip)
148 {
149         objset_impl_t *winner, *osi;
150         int i, err, checksum;
151
152         osi = kmem_zalloc(sizeof (objset_impl_t), KM_SLEEP);
153         osi->os.os = osi;
154         osi->os_dsl_dataset = ds;
155         osi->os_spa = spa;
156         osi->os_rootbp = bp;
157         if (!BP_IS_HOLE(osi->os_rootbp)) {
158                 uint32_t aflags = ARC_WAIT;
159                 zbookmark_t zb;
160                 zb.zb_objset = ds ? ds->ds_object : 0;
161                 zb.zb_object = 0;
162                 zb.zb_level = -1;
163                 zb.zb_blkid = 0;
164
165                 dprintf_bp(osi->os_rootbp, "reading %s", "");
166                 err = arc_read(NULL, spa, osi->os_rootbp,
167                     dmu_ot[DMU_OT_OBJSET].ot_byteswap,
168                     arc_getbuf_func, &osi->os_phys_buf,
169                     ZIO_PRIORITY_SYNC_READ, ZIO_FLAG_CANFAIL, &aflags, &zb);
170                 if (err) {
171                         kmem_free(osi, sizeof (objset_impl_t));
172                         return (err);
173                 }
174                 osi->os_phys = osi->os_phys_buf->b_data;
175                 arc_release(osi->os_phys_buf, &osi->os_phys_buf);
176         } else {
177                 osi->os_phys_buf = arc_buf_alloc(spa, sizeof (objset_phys_t),
178                     &osi->os_phys_buf, ARC_BUFC_METADATA);
179                 osi->os_phys = osi->os_phys_buf->b_data;
180                 bzero(osi->os_phys, sizeof (objset_phys_t));
181         }
182
183         /*
184          * Note: the changed_cb will be called once before the register
185          * func returns, thus changing the checksum/compression from the
186          * default (fletcher2/off).  Snapshots don't need to know, and
187          * registering would complicate clone promotion.
188          */
189         if (ds && ds->ds_phys->ds_num_children == 0) {
190                 err = dsl_prop_register(ds, "checksum",
191                     checksum_changed_cb, osi);
192                 if (err == 0)
193                         err = dsl_prop_register(ds, "compression",
194                             compression_changed_cb, osi);
195                 if (err == 0)
196                         err = dsl_prop_register(ds, "copies",
197                             copies_changed_cb, osi);
198                 if (err) {
199                         VERIFY(arc_buf_remove_ref(osi->os_phys_buf,
200                             &osi->os_phys_buf) == 1);
201                         kmem_free(osi, sizeof (objset_impl_t));
202                         return (err);
203                 }
204         } else if (ds == NULL) {
205                 /* It's the meta-objset. */
206                 osi->os_checksum = ZIO_CHECKSUM_FLETCHER_4;
207                 osi->os_compress = ZIO_COMPRESS_LZJB;
208                 osi->os_copies = spa_max_replication(spa);
209         }
210
211         osi->os_zil = zil_alloc(&osi->os, &osi->os_phys->os_zil_header);
212
213         /*
214          * Metadata always gets compressed and checksummed.
215          * If the data checksum is multi-bit correctable, and it's not
216          * a ZBT-style checksum, then it's suitable for metadata as well.
217          * Otherwise, the metadata checksum defaults to fletcher4.
218          */
219         checksum = osi->os_checksum;
220
221         if (zio_checksum_table[checksum].ci_correctable &&
222             !zio_checksum_table[checksum].ci_zbt)
223                 osi->os_md_checksum = checksum;
224         else
225                 osi->os_md_checksum = ZIO_CHECKSUM_FLETCHER_4;
226         osi->os_md_compress = ZIO_COMPRESS_LZJB;
227
228         for (i = 0; i < TXG_SIZE; i++) {
229                 list_create(&osi->os_dirty_dnodes[i], sizeof (dnode_t),
230                     offsetof(dnode_t, dn_dirty_link[i]));
231                 list_create(&osi->os_free_dnodes[i], sizeof (dnode_t),
232                     offsetof(dnode_t, dn_dirty_link[i]));
233         }
234         list_create(&osi->os_dnodes, sizeof (dnode_t),
235             offsetof(dnode_t, dn_link));
236         list_create(&osi->os_downgraded_dbufs, sizeof (dmu_buf_impl_t),
237             offsetof(dmu_buf_impl_t, db_link));
238
239         mutex_init(&osi->os_lock, NULL, MUTEX_DEFAULT, NULL);
240         mutex_init(&osi->os_obj_lock, NULL, MUTEX_DEFAULT, NULL);
241
242         osi->os_meta_dnode = dnode_special_open(osi,
243             &osi->os_phys->os_meta_dnode, DMU_META_DNODE_OBJECT);
244
245         if (ds != NULL) {
246                 winner = dsl_dataset_set_user_ptr(ds, osi, dmu_objset_evict);
247                 if (winner) {
248                         dmu_objset_evict(ds, osi);
249                         osi = winner;
250                 }
251         }
252
253         *osip = osi;
254         return (0);
255 }
256
257 /* called from zpl */
258 int
259 dmu_objset_open(const char *name, dmu_objset_type_t type, int mode,
260     objset_t **osp)
261 {
262         dsl_dataset_t *ds;
263         int err;
264         objset_t *os;
265         objset_impl_t *osi;
266
267         os = kmem_alloc(sizeof (objset_t), KM_SLEEP);
268         err = dsl_dataset_open(name, mode, os, &ds);
269         if (err) {
270                 kmem_free(os, sizeof (objset_t));
271                 return (err);
272         }
273
274         osi = dsl_dataset_get_user_ptr(ds);
275         if (osi == NULL) {
276                 err = dmu_objset_open_impl(dsl_dataset_get_spa(ds),
277                     ds, &ds->ds_phys->ds_bp, &osi);
278                 if (err) {
279                         dsl_dataset_close(ds, mode, os);
280                         kmem_free(os, sizeof (objset_t));
281                         return (err);
282                 }
283         }
284
285         os->os = osi;
286         os->os_mode = mode;
287
288         if (type != DMU_OST_ANY && type != os->os->os_phys->os_type) {
289                 dmu_objset_close(os);
290                 return (EINVAL);
291         }
292         *osp = os;
293         return (0);
294 }
295
296 void
297 dmu_objset_close(objset_t *os)
298 {
299         dsl_dataset_close(os->os->os_dsl_dataset, os->os_mode, os);
300         kmem_free(os, sizeof (objset_t));
301 }
302
303 int
304 dmu_objset_evict_dbufs(objset_t *os, int try)
305 {
306         objset_impl_t *osi = os->os;
307         dnode_t *dn;
308
309         mutex_enter(&osi->os_lock);
310
311         /* process the mdn last, since the other dnodes have holds on it */
312         list_remove(&osi->os_dnodes, osi->os_meta_dnode);
313         list_insert_tail(&osi->os_dnodes, osi->os_meta_dnode);
314
315         /*
316          * Find the first dnode with holds.  We have to do this dance
317          * because dnode_add_ref() only works if you already have a
318          * hold.  If there are no holds then it has no dbufs so OK to
319          * skip.
320          */
321         for (dn = list_head(&osi->os_dnodes);
322             dn && refcount_is_zero(&dn->dn_holds);
323             dn = list_next(&osi->os_dnodes, dn))
324                 continue;
325         if (dn)
326                 dnode_add_ref(dn, FTAG);
327
328         while (dn) {
329                 dnode_t *next_dn = dn;
330
331                 do {
332                         next_dn = list_next(&osi->os_dnodes, next_dn);
333                 } while (next_dn && refcount_is_zero(&next_dn->dn_holds));
334                 if (next_dn)
335                         dnode_add_ref(next_dn, FTAG);
336
337                 mutex_exit(&osi->os_lock);
338                 if (dnode_evict_dbufs(dn, try)) {
339                         dnode_rele(dn, FTAG);
340                         if (next_dn)
341                                 dnode_rele(next_dn, FTAG);
342                         return (1);
343                 }
344                 dnode_rele(dn, FTAG);
345                 mutex_enter(&osi->os_lock);
346                 dn = next_dn;
347         }
348         mutex_exit(&osi->os_lock);
349         return (0);
350 }
351
352 void
353 dmu_objset_evict(dsl_dataset_t *ds, void *arg)
354 {
355         objset_impl_t *osi = arg;
356         objset_t os;
357         int i;
358
359         for (i = 0; i < TXG_SIZE; i++) {
360                 ASSERT(list_head(&osi->os_dirty_dnodes[i]) == NULL);
361                 ASSERT(list_head(&osi->os_free_dnodes[i]) == NULL);
362         }
363
364         if (ds && ds->ds_phys->ds_num_children == 0) {
365                 VERIFY(0 == dsl_prop_unregister(ds, "checksum",
366                     checksum_changed_cb, osi));
367                 VERIFY(0 == dsl_prop_unregister(ds, "compression",
368                     compression_changed_cb, osi));
369                 VERIFY(0 == dsl_prop_unregister(ds, "copies",
370                     copies_changed_cb, osi));
371         }
372
373         /*
374          * We should need only a single pass over the dnode list, since
375          * nothing can be added to the list at this point.
376          */
377         os.os = osi;
378         (void) dmu_objset_evict_dbufs(&os, 0);
379
380         ASSERT3P(list_head(&osi->os_dnodes), ==, osi->os_meta_dnode);
381         ASSERT3P(list_tail(&osi->os_dnodes), ==, osi->os_meta_dnode);
382         ASSERT3P(list_head(&osi->os_meta_dnode->dn_dbufs), ==, NULL);
383
384         dnode_special_close(osi->os_meta_dnode);
385         zil_free(osi->os_zil);
386
387         VERIFY(arc_buf_remove_ref(osi->os_phys_buf, &osi->os_phys_buf) == 1);
388         mutex_destroy(&osi->os_lock);
389         mutex_destroy(&osi->os_obj_lock);
390         kmem_free(osi, sizeof (objset_impl_t));
391 }
392
393 /* called from dsl for meta-objset */
394 objset_impl_t *
395 dmu_objset_create_impl(spa_t *spa, dsl_dataset_t *ds, blkptr_t *bp,
396     dmu_objset_type_t type, dmu_tx_t *tx)
397 {
398         objset_impl_t *osi;
399         dnode_t *mdn;
400
401         ASSERT(dmu_tx_is_syncing(tx));
402         VERIFY(0 == dmu_objset_open_impl(spa, ds, bp, &osi));
403         mdn = osi->os_meta_dnode;
404
405         dnode_allocate(mdn, DMU_OT_DNODE, 1 << DNODE_BLOCK_SHIFT,
406             DN_MAX_INDBLKSHIFT, DMU_OT_NONE, 0, tx);
407
408         /*
409          * We don't want to have to increase the meta-dnode's nlevels
410          * later, because then we could do it in quescing context while
411          * we are also accessing it in open context.
412          *
413          * This precaution is not necessary for the MOS (ds == NULL),
414          * because the MOS is only updated in syncing context.
415          * This is most fortunate: the MOS is the only objset that
416          * needs to be synced multiple times as spa_sync() iterates
417          * to convergence, so minimizing its dn_nlevels matters.
418          */
419         if (ds != NULL) {
420                 int levels = 1;
421
422                 /*
423                  * Determine the number of levels necessary for the meta-dnode
424                  * to contain DN_MAX_OBJECT dnodes.
425                  */
426                 while ((uint64_t)mdn->dn_nblkptr << (mdn->dn_datablkshift +
427                     (levels - 1) * (mdn->dn_indblkshift - SPA_BLKPTRSHIFT)) <
428                     DN_MAX_OBJECT * sizeof (dnode_phys_t))
429                         levels++;
430
431                 mdn->dn_next_nlevels[tx->tx_txg & TXG_MASK] =
432                     mdn->dn_nlevels = levels;
433         }
434
435         ASSERT(type != DMU_OST_NONE);
436         ASSERT(type != DMU_OST_ANY);
437         ASSERT(type < DMU_OST_NUMTYPES);
438         osi->os_phys->os_type = type;
439
440         dsl_dataset_dirty(ds, tx);
441
442         return (osi);
443 }
444
445 struct oscarg {
446         void (*userfunc)(objset_t *os, void *arg, dmu_tx_t *tx);
447         void *userarg;
448         dsl_dataset_t *clone_parent;
449         const char *lastname;
450         dmu_objset_type_t type;
451 };
452
453 /* ARGSUSED */
454 static int
455 dmu_objset_create_check(void *arg1, void *arg2, dmu_tx_t *tx)
456 {
457         dsl_dir_t *dd = arg1;
458         struct oscarg *oa = arg2;
459         objset_t *mos = dd->dd_pool->dp_meta_objset;
460         int err;
461         uint64_t ddobj;
462
463         err = zap_lookup(mos, dd->dd_phys->dd_child_dir_zapobj,
464             oa->lastname, sizeof (uint64_t), 1, &ddobj);
465         if (err != ENOENT)
466                 return (err ? err : EEXIST);
467
468         if (oa->clone_parent != NULL) {
469                 /*
470                  * You can't clone across pools.
471                  */
472                 if (oa->clone_parent->ds_dir->dd_pool != dd->dd_pool)
473                         return (EXDEV);
474
475                 /*
476                  * You can only clone snapshots, not the head datasets.
477                  */
478                 if (oa->clone_parent->ds_phys->ds_num_children == 0)
479                         return (EINVAL);
480         }
481         return (0);
482 }
483
484 static void
485 dmu_objset_create_sync(void *arg1, void *arg2, dmu_tx_t *tx)
486 {
487         dsl_dir_t *dd = arg1;
488         struct oscarg *oa = arg2;
489         dsl_dataset_t *ds;
490         blkptr_t *bp;
491         uint64_t dsobj;
492
493         ASSERT(dmu_tx_is_syncing(tx));
494
495         dsobj = dsl_dataset_create_sync(dd, oa->lastname,
496             oa->clone_parent, tx);
497
498         VERIFY(0 == dsl_dataset_open_obj(dd->dd_pool, dsobj, NULL,
499             DS_MODE_STANDARD | DS_MODE_READONLY, FTAG, &ds));
500         bp = dsl_dataset_get_blkptr(ds);
501         if (BP_IS_HOLE(bp)) {
502                 objset_impl_t *osi;
503
504                 /* This is an empty dmu_objset; not a clone. */
505                 osi = dmu_objset_create_impl(dsl_dataset_get_spa(ds),
506                     ds, bp, oa->type, tx);
507
508                 if (oa->userfunc)
509                         oa->userfunc(&osi->os, oa->userarg, tx);
510         }
511         dsl_dataset_close(ds, DS_MODE_STANDARD | DS_MODE_READONLY, FTAG);
512 }
513
514 int
515 dmu_objset_create(const char *name, dmu_objset_type_t type,
516     objset_t *clone_parent,
517     void (*func)(objset_t *os, void *arg, dmu_tx_t *tx), void *arg)
518 {
519         dsl_dir_t *pdd;
520         const char *tail;
521         int err = 0;
522         struct oscarg oa = { 0 };
523
524         ASSERT(strchr(name, '@') == NULL);
525         err = dsl_dir_open(name, FTAG, &pdd, &tail);
526         if (err)
527                 return (err);
528         if (tail == NULL) {
529                 dsl_dir_close(pdd, FTAG);
530                 return (EEXIST);
531         }
532
533         dprintf("name=%s\n", name);
534
535         oa.userfunc = func;
536         oa.userarg = arg;
537         oa.lastname = tail;
538         oa.type = type;
539         if (clone_parent != NULL) {
540                 /*
541                  * You can't clone to a different type.
542                  */
543                 if (clone_parent->os->os_phys->os_type != type) {
544                         dsl_dir_close(pdd, FTAG);
545                         return (EINVAL);
546                 }
547                 oa.clone_parent = clone_parent->os->os_dsl_dataset;
548         }
549         err = dsl_sync_task_do(pdd->dd_pool, dmu_objset_create_check,
550             dmu_objset_create_sync, pdd, &oa, 5);
551         dsl_dir_close(pdd, FTAG);
552         return (err);
553 }
554
555 int
556 dmu_objset_destroy(const char *name)
557 {
558         objset_t *os;
559         int error;
560
561         /*
562          * If it looks like we'll be able to destroy it, and there's
563          * an unplayed replay log sitting around, destroy the log.
564          * It would be nicer to do this in dsl_dataset_destroy_sync(),
565          * but the replay log objset is modified in open context.
566          */
567         error = dmu_objset_open(name, DMU_OST_ANY, DS_MODE_EXCLUSIVE, &os);
568         if (error == 0) {
569                 zil_destroy(dmu_objset_zil(os), B_FALSE);
570                 dmu_objset_close(os);
571         }
572
573         return (dsl_dataset_destroy(name));
574 }
575
576 int
577 dmu_objset_rollback(const char *name)
578 {
579         int err;
580         objset_t *os;
581
582         err = dmu_objset_open(name, DMU_OST_ANY,
583             DS_MODE_EXCLUSIVE | DS_MODE_INCONSISTENT, &os);
584         if (err == 0) {
585                 err = zil_suspend(dmu_objset_zil(os));
586                 if (err == 0)
587                         zil_resume(dmu_objset_zil(os));
588                 if (err == 0) {
589                         /* XXX uncache everything? */
590                         err = dsl_dataset_rollback(os->os->os_dsl_dataset);
591                 }
592                 dmu_objset_close(os);
593         }
594         return (err);
595 }
596
597 struct snaparg {
598         dsl_sync_task_group_t *dstg;
599         char *snapname;
600         char failed[MAXPATHLEN];
601 };
602
603 static int
604 dmu_objset_snapshot_one(char *name, void *arg)
605 {
606         struct snaparg *sn = arg;
607         objset_t *os;
608         dmu_objset_stats_t stat;
609         int err;
610
611         (void) strcpy(sn->failed, name);
612
613         err = dmu_objset_open(name, DMU_OST_ANY, DS_MODE_STANDARD, &os);
614         if (err != 0)
615                 return (err);
616
617         /*
618          * If the objset is in an inconsistent state, return busy.
619          */
620         dmu_objset_fast_stat(os, &stat);
621         if (stat.dds_inconsistent) {
622                 dmu_objset_close(os);
623                 return (EBUSY);
624         }
625
626         /*
627          * NB: we need to wait for all in-flight changes to get to disk,
628          * so that we snapshot those changes.  zil_suspend does this as
629          * a side effect.
630          */
631         err = zil_suspend(dmu_objset_zil(os));
632         if (err == 0) {
633                 dsl_sync_task_create(sn->dstg, dsl_dataset_snapshot_check,
634                     dsl_dataset_snapshot_sync, os, sn->snapname, 3);
635         } else {
636                 dmu_objset_close(os);
637         }
638
639         return (err);
640 }
641
642 int
643 dmu_objset_snapshot(char *fsname, char *snapname, boolean_t recursive)
644 {
645         dsl_sync_task_t *dst;
646         struct snaparg sn = { 0 };
647         char *cp;
648         spa_t *spa;
649         int err;
650
651         (void) strcpy(sn.failed, fsname);
652
653         cp = strchr(fsname, '/');
654         if (cp) {
655                 *cp = '\0';
656                 err = spa_open(fsname, &spa, FTAG);
657                 *cp = '/';
658         } else {
659                 err = spa_open(fsname, &spa, FTAG);
660         }
661         if (err)
662                 return (err);
663
664         sn.dstg = dsl_sync_task_group_create(spa_get_dsl(spa));
665         sn.snapname = snapname;
666
667         if (recursive) {
668                 err = dmu_objset_find(fsname,
669                     dmu_objset_snapshot_one, &sn, DS_FIND_CHILDREN);
670         } else {
671                 err = dmu_objset_snapshot_one(fsname, &sn);
672         }
673
674         if (err)
675                 goto out;
676
677         err = dsl_sync_task_group_wait(sn.dstg);
678
679         for (dst = list_head(&sn.dstg->dstg_tasks); dst;
680             dst = list_next(&sn.dstg->dstg_tasks, dst)) {
681                 objset_t *os = dst->dst_arg1;
682                 if (dst->dst_err)
683                         dmu_objset_name(os, sn.failed);
684                 zil_resume(dmu_objset_zil(os));
685                 dmu_objset_close(os);
686         }
687 out:
688         if (err)
689                 (void) strcpy(fsname, sn.failed);
690         dsl_sync_task_group_destroy(sn.dstg);
691         spa_close(spa, FTAG);
692         return (err);
693 }
694
695 static void
696 dmu_objset_sync_dnodes(list_t *list, dmu_tx_t *tx)
697 {
698         dnode_t *dn;
699
700         while (dn = list_head(list)) {
701                 ASSERT(dn->dn_object != DMU_META_DNODE_OBJECT);
702                 ASSERT(dn->dn_dbuf->db_data_pending);
703                 /*
704                  * Initialize dn_zio outside dnode_sync()
705                  * to accomodate meta-dnode
706                  */
707                 dn->dn_zio = dn->dn_dbuf->db_data_pending->dr_zio;
708                 ASSERT(dn->dn_zio);
709
710                 ASSERT3U(dn->dn_nlevels, <=, DN_MAX_LEVELS);
711                 list_remove(list, dn);
712                 dnode_sync(dn, tx);
713         }
714 }
715
716 /* ARGSUSED */
717 static void
718 ready(zio_t *zio, arc_buf_t *abuf, void *arg)
719 {
720         objset_impl_t *os = arg;
721         blkptr_t *bp = os->os_rootbp;
722         dnode_phys_t *dnp = &os->os_phys->os_meta_dnode;
723         int i;
724
725         /*
726          * Update rootbp fill count.
727          */
728         bp->blk_fill = 1;       /* count the meta-dnode */
729         for (i = 0; i < dnp->dn_nblkptr; i++)
730                 bp->blk_fill += dnp->dn_blkptr[i].blk_fill;
731 }
732
733 /* ARGSUSED */
734 static void
735 killer(zio_t *zio, arc_buf_t *abuf, void *arg)
736 {
737         objset_impl_t *os = arg;
738
739         ASSERT3U(zio->io_error, ==, 0);
740
741         BP_SET_TYPE(zio->io_bp, DMU_OT_OBJSET);
742         BP_SET_LEVEL(zio->io_bp, 0);
743
744         if (!DVA_EQUAL(BP_IDENTITY(zio->io_bp),
745             BP_IDENTITY(&zio->io_bp_orig))) {
746                 if (zio->io_bp_orig.blk_birth == os->os_synctx->tx_txg)
747                         dsl_dataset_block_kill(os->os_dsl_dataset,
748                             &zio->io_bp_orig, NULL, os->os_synctx);
749                 dsl_dataset_block_born(os->os_dsl_dataset, zio->io_bp,
750                     os->os_synctx);
751         }
752         arc_release(os->os_phys_buf, &os->os_phys_buf);
753 }
754
755 /* called from dsl */
756 void
757 dmu_objset_sync(objset_impl_t *os, zio_t *pio, dmu_tx_t *tx)
758 {
759         int txgoff;
760         zbookmark_t zb;
761         zio_t *zio;
762         list_t *list;
763         dbuf_dirty_record_t *dr;
764         int zio_flags;
765
766         dprintf_ds(os->os_dsl_dataset, "txg=%llu\n", tx->tx_txg);
767
768         ASSERT(dmu_tx_is_syncing(tx));
769         /* XXX the write_done callback should really give us the tx... */
770         os->os_synctx = tx;
771
772         if (os->os_dsl_dataset == NULL) {
773                 /*
774                  * This is the MOS.  If we have upgraded,
775                  * spa_max_replication() could change, so reset
776                  * os_copies here.
777                  */
778                 os->os_copies = spa_max_replication(os->os_spa);
779         }
780
781         /*
782          * Create the root block IO
783          */
784         zb.zb_objset = os->os_dsl_dataset ? os->os_dsl_dataset->ds_object : 0;
785         zb.zb_object = 0;
786         zb.zb_level = -1;
787         zb.zb_blkid = 0;
788         zio_flags = ZIO_FLAG_MUSTSUCCEED;
789         if (dmu_ot[DMU_OT_OBJSET].ot_metadata || zb.zb_level != 0)
790                 zio_flags |= ZIO_FLAG_METADATA;
791         if (BP_IS_OLDER(os->os_rootbp, tx->tx_txg))
792                 dsl_dataset_block_kill(os->os_dsl_dataset,
793                     os->os_rootbp, pio, tx);
794         zio = arc_write(pio, os->os_spa, os->os_md_checksum,
795             os->os_md_compress,
796             dmu_get_replication_level(os, &zb, DMU_OT_OBJSET),
797             tx->tx_txg, os->os_rootbp, os->os_phys_buf, ready, killer, os,
798             ZIO_PRIORITY_ASYNC_WRITE, zio_flags, &zb);
799
800         /*
801          * Sync meta-dnode - the parent IO for the sync is the root block
802          */
803         os->os_meta_dnode->dn_zio = zio;
804         dnode_sync(os->os_meta_dnode, tx);
805
806         txgoff = tx->tx_txg & TXG_MASK;
807
808         dmu_objset_sync_dnodes(&os->os_free_dnodes[txgoff], tx);
809         dmu_objset_sync_dnodes(&os->os_dirty_dnodes[txgoff], tx);
810
811         list = &os->os_meta_dnode->dn_dirty_records[txgoff];
812         while (dr = list_head(list)) {
813                 ASSERT(dr->dr_dbuf->db_level == 0);
814                 list_remove(list, dr);
815                 if (dr->dr_zio)
816                         zio_nowait(dr->dr_zio);
817         }
818         /*
819          * Free intent log blocks up to this tx.
820          */
821         zil_sync(os->os_zil, tx);
822         zio_nowait(zio);
823 }
824
825 void
826 dmu_objset_space(objset_t *os, uint64_t *refdbytesp, uint64_t *availbytesp,
827     uint64_t *usedobjsp, uint64_t *availobjsp)
828 {
829         dsl_dataset_space(os->os->os_dsl_dataset, refdbytesp, availbytesp,
830             usedobjsp, availobjsp);
831 }
832
833 uint64_t
834 dmu_objset_fsid_guid(objset_t *os)
835 {
836         return (dsl_dataset_fsid_guid(os->os->os_dsl_dataset));
837 }
838
839 void
840 dmu_objset_fast_stat(objset_t *os, dmu_objset_stats_t *stat)
841 {
842         stat->dds_type = os->os->os_phys->os_type;
843         if (os->os->os_dsl_dataset)
844                 dsl_dataset_fast_stat(os->os->os_dsl_dataset, stat);
845 }
846
847 void
848 dmu_objset_stats(objset_t *os, nvlist_t *nv)
849 {
850         ASSERT(os->os->os_dsl_dataset ||
851             os->os->os_phys->os_type == DMU_OST_META);
852
853         if (os->os->os_dsl_dataset != NULL)
854                 dsl_dataset_stats(os->os->os_dsl_dataset, nv);
855
856         dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_TYPE,
857             os->os->os_phys->os_type);
858 }
859
860 int
861 dmu_objset_is_snapshot(objset_t *os)
862 {
863         if (os->os->os_dsl_dataset != NULL)
864                 return (dsl_dataset_is_snapshot(os->os->os_dsl_dataset));
865         else
866                 return (B_FALSE);
867 }
868
869 int
870 dmu_snapshot_list_next(objset_t *os, int namelen, char *name,
871     uint64_t *idp, uint64_t *offp)
872 {
873         dsl_dataset_t *ds = os->os->os_dsl_dataset;
874         zap_cursor_t cursor;
875         zap_attribute_t attr;
876
877         if (ds->ds_phys->ds_snapnames_zapobj == 0)
878                 return (ENOENT);
879
880         zap_cursor_init_serialized(&cursor,
881             ds->ds_dir->dd_pool->dp_meta_objset,
882             ds->ds_phys->ds_snapnames_zapobj, *offp);
883
884         if (zap_cursor_retrieve(&cursor, &attr) != 0) {
885                 zap_cursor_fini(&cursor);
886                 return (ENOENT);
887         }
888
889         if (strlen(attr.za_name) + 1 > namelen) {
890                 zap_cursor_fini(&cursor);
891                 return (ENAMETOOLONG);
892         }
893
894         (void) strcpy(name, attr.za_name);
895         if (idp)
896                 *idp = attr.za_first_integer;
897         zap_cursor_advance(&cursor);
898         *offp = zap_cursor_serialize(&cursor);
899         zap_cursor_fini(&cursor);
900
901         return (0);
902 }
903
904 int
905 dmu_dir_list_next(objset_t *os, int namelen, char *name,
906     uint64_t *idp, uint64_t *offp)
907 {
908         dsl_dir_t *dd = os->os->os_dsl_dataset->ds_dir;
909         zap_cursor_t cursor;
910         zap_attribute_t attr;
911
912         /* there is no next dir on a snapshot! */
913         if (os->os->os_dsl_dataset->ds_object !=
914             dd->dd_phys->dd_head_dataset_obj)
915                 return (ENOENT);
916
917         zap_cursor_init_serialized(&cursor,
918             dd->dd_pool->dp_meta_objset,
919             dd->dd_phys->dd_child_dir_zapobj, *offp);
920
921         if (zap_cursor_retrieve(&cursor, &attr) != 0) {
922                 zap_cursor_fini(&cursor);
923                 return (ENOENT);
924         }
925
926         if (strlen(attr.za_name) + 1 > namelen) {
927                 zap_cursor_fini(&cursor);
928                 return (ENAMETOOLONG);
929         }
930
931         (void) strcpy(name, attr.za_name);
932         if (idp)
933                 *idp = attr.za_first_integer;
934         zap_cursor_advance(&cursor);
935         *offp = zap_cursor_serialize(&cursor);
936         zap_cursor_fini(&cursor);
937
938         return (0);
939 }
940
941 /*
942  * Find all objsets under name, and for each, call 'func(child_name, arg)'.
943  */
944 int
945 dmu_objset_find(char *name, int func(char *, void *), void *arg, int flags)
946 {
947         dsl_dir_t *dd;
948         objset_t *os;
949         uint64_t snapobj;
950         zap_cursor_t zc;
951         zap_attribute_t *attr;
952         char *child;
953         int do_self, err;
954
955         err = dsl_dir_open(name, FTAG, &dd, NULL);
956         if (err)
957                 return (err);
958
959         /* NB: the $MOS dir doesn't have a head dataset */
960         do_self = (dd->dd_phys->dd_head_dataset_obj != 0);
961         attr = kmem_alloc(sizeof (zap_attribute_t), KM_SLEEP);
962
963         /*
964          * Iterate over all children.
965          */
966         if (flags & DS_FIND_CHILDREN) {
967                 for (zap_cursor_init(&zc, dd->dd_pool->dp_meta_objset,
968                     dd->dd_phys->dd_child_dir_zapobj);
969                     zap_cursor_retrieve(&zc, attr) == 0;
970                     (void) zap_cursor_advance(&zc)) {
971                         ASSERT(attr->za_integer_length == sizeof (uint64_t));
972                         ASSERT(attr->za_num_integers == 1);
973
974                         /*
975                          * No separating '/' because parent's name ends in /.
976                          */
977                         child = kmem_alloc(MAXPATHLEN, KM_SLEEP);
978                         /* XXX could probably just use name here */
979                         dsl_dir_name(dd, child);
980                         (void) strcat(child, "/");
981                         (void) strcat(child, attr->za_name);
982                         err = dmu_objset_find(child, func, arg, flags);
983                         kmem_free(child, MAXPATHLEN);
984                         if (err)
985                                 break;
986                 }
987                 zap_cursor_fini(&zc);
988
989                 if (err) {
990                         dsl_dir_close(dd, FTAG);
991                         kmem_free(attr, sizeof (zap_attribute_t));
992                         return (err);
993                 }
994         }
995
996         /*
997          * Iterate over all snapshots.
998          */
999         if ((flags & DS_FIND_SNAPSHOTS) &&
1000             dmu_objset_open(name, DMU_OST_ANY,
1001             DS_MODE_STANDARD | DS_MODE_READONLY, &os) == 0) {
1002
1003                 snapobj = os->os->os_dsl_dataset->ds_phys->ds_snapnames_zapobj;
1004                 dmu_objset_close(os);
1005
1006                 for (zap_cursor_init(&zc, dd->dd_pool->dp_meta_objset, snapobj);
1007                     zap_cursor_retrieve(&zc, attr) == 0;
1008                     (void) zap_cursor_advance(&zc)) {
1009                         ASSERT(attr->za_integer_length == sizeof (uint64_t));
1010                         ASSERT(attr->za_num_integers == 1);
1011
1012                         child = kmem_alloc(MAXPATHLEN, KM_SLEEP);
1013                         /* XXX could probably just use name here */
1014                         dsl_dir_name(dd, child);
1015                         (void) strcat(child, "@");
1016                         (void) strcat(child, attr->za_name);
1017                         err = func(child, arg);
1018                         kmem_free(child, MAXPATHLEN);
1019                         if (err)
1020                                 break;
1021                 }
1022                 zap_cursor_fini(&zc);
1023         }
1024
1025         dsl_dir_close(dd, FTAG);
1026         kmem_free(attr, sizeof (zap_attribute_t));
1027
1028         if (err)
1029                 return (err);
1030
1031         /*
1032          * Apply to self if appropriate.
1033          */
1034         if (do_self)
1035                 err = func(name, arg);
1036         return (err);
1037 }