474 return (0);
475 }
476
477 void
478 dsl_dir_destroy_sync(void *arg1, void *tag, dmu_tx_t *tx)
479 {
480 dsl_dir_t *dd = arg1;
481 objset_t *mos = dd->dd_pool->dp_meta_objset;
482 uint64_t obj;
483 dd_used_t t;
484
485 ASSERT(RW_WRITE_HELD(&dd->dd_pool->dp_config_rwlock));
486 ASSERT(dd->dd_phys->dd_head_dataset_obj == 0);
487
488 /*
489 * Remove our reservation. The impl() routine avoids setting the
490 * actual property, which would require the (already destroyed) ds.
491 */
492 dsl_dir_set_reservation_sync_impl(dd, 0, tx);
493
494 ASSERT3U(dd->dd_phys->dd_used_bytes, ==, 0);
495 ASSERT3U(dd->dd_phys->dd_reserved, ==, 0);
496 for (t = 0; t < DD_USED_NUM; t++)
497 ASSERT3U(dd->dd_phys->dd_used_breakdown[t], ==, 0);
498
499 VERIFY(0 == zap_destroy(mos, dd->dd_phys->dd_child_dir_zapobj, tx));
500 VERIFY(0 == zap_destroy(mos, dd->dd_phys->dd_props_zapobj, tx));
501 VERIFY(0 == dsl_deleg_destroy(mos, dd->dd_phys->dd_deleg_zapobj, tx));
502 VERIFY(0 == zap_remove(mos,
503 dd->dd_parent->dd_phys->dd_child_dir_zapobj, dd->dd_myname, tx));
504
505 obj = dd->dd_object;
506 dsl_dir_close(dd, tag);
507 VERIFY(0 == dmu_object_free(mos, obj, tx));
508 }
509
510 boolean_t
511 dsl_dir_is_clone(dsl_dir_t *dd)
512 {
513 return (dd->dd_phys->dd_origin_obj &&
514 (dd->dd_pool->dp_origin_snap == NULL ||
515 dd->dd_phys->dd_origin_obj !=
516 dd->dd_pool->dp_origin_snap->ds_object));
517 }
568 dmu_buf_add_ref(dd->dd_dbuf, dd);
569 }
570 }
571
572 static int64_t
573 parent_delta(dsl_dir_t *dd, uint64_t used, int64_t delta)
574 {
575 uint64_t old_accounted = MAX(used, dd->dd_phys->dd_reserved);
576 uint64_t new_accounted = MAX(used + delta, dd->dd_phys->dd_reserved);
577 return (new_accounted - old_accounted);
578 }
579
580 void
581 dsl_dir_sync(dsl_dir_t *dd, dmu_tx_t *tx)
582 {
583 ASSERT(dmu_tx_is_syncing(tx));
584
585 dmu_buf_will_dirty(dd->dd_dbuf, tx);
586
587 mutex_enter(&dd->dd_lock);
588 ASSERT3U(dd->dd_tempreserved[tx->tx_txg&TXG_MASK], ==, 0);
589 dprintf_dd(dd, "txg=%llu towrite=%lluK\n", tx->tx_txg,
590 dd->dd_space_towrite[tx->tx_txg&TXG_MASK] / 1024);
591 dd->dd_space_towrite[tx->tx_txg&TXG_MASK] = 0;
592 mutex_exit(&dd->dd_lock);
593
594 /* release the hold from dsl_dir_dirty */
595 dmu_buf_rele(dd->dd_dbuf, dd);
596 }
597
598 static uint64_t
599 dsl_dir_space_towrite(dsl_dir_t *dd)
600 {
601 uint64_t space = 0;
602 int i;
603
604 ASSERT(MUTEX_HELD(&dd->dd_lock));
605
606 for (i = 0; i < TXG_SIZE; i++) {
607 space += dd->dd_space_towrite[i&TXG_MASK];
608 ASSERT3U(dd->dd_space_towrite[i&TXG_MASK], >=, 0);
1317 dd->dd_phys->dd_used_bytes,
1318 dd->dd_phys->dd_compressed_bytes,
1319 dd->dd_phys->dd_uncompressed_bytes, tx);
1320
1321 if (dd->dd_phys->dd_reserved > dd->dd_phys->dd_used_bytes) {
1322 uint64_t unused_rsrv = dd->dd_phys->dd_reserved -
1323 dd->dd_phys->dd_used_bytes;
1324
1325 dsl_dir_diduse_space(dd->dd_parent, DD_USED_CHILD_RSRV,
1326 -unused_rsrv, 0, 0, tx);
1327 dsl_dir_diduse_space(ra->newparent, DD_USED_CHILD_RSRV,
1328 unused_rsrv, 0, 0, tx);
1329 }
1330 }
1331
1332 dmu_buf_will_dirty(dd->dd_dbuf, tx);
1333
1334 /* remove from old parent zapobj */
1335 err = zap_remove(mos, dd->dd_parent->dd_phys->dd_child_dir_zapobj,
1336 dd->dd_myname, tx);
1337 ASSERT3U(err, ==, 0);
1338
1339 (void) strcpy(dd->dd_myname, ra->mynewname);
1340 dsl_dir_close(dd->dd_parent, dd);
1341 dd->dd_phys->dd_parent_obj = ra->newparent->dd_object;
1342 VERIFY(0 == dsl_dir_open_obj(dd->dd_pool,
1343 ra->newparent->dd_object, NULL, dd, &dd->dd_parent));
1344
1345 /* add to new parent zapobj */
1346 err = zap_add(mos, ra->newparent->dd_phys->dd_child_dir_zapobj,
1347 dd->dd_myname, 8, 1, &dd->dd_object, tx);
1348 ASSERT3U(err, ==, 0);
1349
1350 }
1351
1352 int
1353 dsl_dir_rename(dsl_dir_t *dd, const char *newname)
1354 {
1355 struct renamearg ra;
1356 int err;
1357
1358 /* new parent should exist */
1359 err = dsl_dir_open(newname, FTAG, &ra.newparent, &ra.mynewname);
1360 if (err)
1361 return (err);
1362
1363 /* can't rename to different pool */
1364 if (dd->dd_pool != ra.newparent->dd_pool) {
1365 err = ENXIO;
1366 goto out;
1367 }
1368
|
474 return (0);
475 }
476
477 void
478 dsl_dir_destroy_sync(void *arg1, void *tag, dmu_tx_t *tx)
479 {
480 dsl_dir_t *dd = arg1;
481 objset_t *mos = dd->dd_pool->dp_meta_objset;
482 uint64_t obj;
483 dd_used_t t;
484
485 ASSERT(RW_WRITE_HELD(&dd->dd_pool->dp_config_rwlock));
486 ASSERT(dd->dd_phys->dd_head_dataset_obj == 0);
487
488 /*
489 * Remove our reservation. The impl() routine avoids setting the
490 * actual property, which would require the (already destroyed) ds.
491 */
492 dsl_dir_set_reservation_sync_impl(dd, 0, tx);
493
494 ASSERT0(dd->dd_phys->dd_used_bytes);
495 ASSERT0(dd->dd_phys->dd_reserved);
496 for (t = 0; t < DD_USED_NUM; t++)
497 ASSERT0(dd->dd_phys->dd_used_breakdown[t]);
498
499 VERIFY(0 == zap_destroy(mos, dd->dd_phys->dd_child_dir_zapobj, tx));
500 VERIFY(0 == zap_destroy(mos, dd->dd_phys->dd_props_zapobj, tx));
501 VERIFY(0 == dsl_deleg_destroy(mos, dd->dd_phys->dd_deleg_zapobj, tx));
502 VERIFY(0 == zap_remove(mos,
503 dd->dd_parent->dd_phys->dd_child_dir_zapobj, dd->dd_myname, tx));
504
505 obj = dd->dd_object;
506 dsl_dir_close(dd, tag);
507 VERIFY(0 == dmu_object_free(mos, obj, tx));
508 }
509
510 boolean_t
511 dsl_dir_is_clone(dsl_dir_t *dd)
512 {
513 return (dd->dd_phys->dd_origin_obj &&
514 (dd->dd_pool->dp_origin_snap == NULL ||
515 dd->dd_phys->dd_origin_obj !=
516 dd->dd_pool->dp_origin_snap->ds_object));
517 }
568 dmu_buf_add_ref(dd->dd_dbuf, dd);
569 }
570 }
571
572 static int64_t
573 parent_delta(dsl_dir_t *dd, uint64_t used, int64_t delta)
574 {
575 uint64_t old_accounted = MAX(used, dd->dd_phys->dd_reserved);
576 uint64_t new_accounted = MAX(used + delta, dd->dd_phys->dd_reserved);
577 return (new_accounted - old_accounted);
578 }
579
580 void
581 dsl_dir_sync(dsl_dir_t *dd, dmu_tx_t *tx)
582 {
583 ASSERT(dmu_tx_is_syncing(tx));
584
585 dmu_buf_will_dirty(dd->dd_dbuf, tx);
586
587 mutex_enter(&dd->dd_lock);
588 ASSERT0(dd->dd_tempreserved[tx->tx_txg&TXG_MASK]);
589 dprintf_dd(dd, "txg=%llu towrite=%lluK\n", tx->tx_txg,
590 dd->dd_space_towrite[tx->tx_txg&TXG_MASK] / 1024);
591 dd->dd_space_towrite[tx->tx_txg&TXG_MASK] = 0;
592 mutex_exit(&dd->dd_lock);
593
594 /* release the hold from dsl_dir_dirty */
595 dmu_buf_rele(dd->dd_dbuf, dd);
596 }
597
598 static uint64_t
599 dsl_dir_space_towrite(dsl_dir_t *dd)
600 {
601 uint64_t space = 0;
602 int i;
603
604 ASSERT(MUTEX_HELD(&dd->dd_lock));
605
606 for (i = 0; i < TXG_SIZE; i++) {
607 space += dd->dd_space_towrite[i&TXG_MASK];
608 ASSERT3U(dd->dd_space_towrite[i&TXG_MASK], >=, 0);
1317 dd->dd_phys->dd_used_bytes,
1318 dd->dd_phys->dd_compressed_bytes,
1319 dd->dd_phys->dd_uncompressed_bytes, tx);
1320
1321 if (dd->dd_phys->dd_reserved > dd->dd_phys->dd_used_bytes) {
1322 uint64_t unused_rsrv = dd->dd_phys->dd_reserved -
1323 dd->dd_phys->dd_used_bytes;
1324
1325 dsl_dir_diduse_space(dd->dd_parent, DD_USED_CHILD_RSRV,
1326 -unused_rsrv, 0, 0, tx);
1327 dsl_dir_diduse_space(ra->newparent, DD_USED_CHILD_RSRV,
1328 unused_rsrv, 0, 0, tx);
1329 }
1330 }
1331
1332 dmu_buf_will_dirty(dd->dd_dbuf, tx);
1333
1334 /* remove from old parent zapobj */
1335 err = zap_remove(mos, dd->dd_parent->dd_phys->dd_child_dir_zapobj,
1336 dd->dd_myname, tx);
1337 ASSERT0(err);
1338
1339 (void) strcpy(dd->dd_myname, ra->mynewname);
1340 dsl_dir_close(dd->dd_parent, dd);
1341 dd->dd_phys->dd_parent_obj = ra->newparent->dd_object;
1342 VERIFY(0 == dsl_dir_open_obj(dd->dd_pool,
1343 ra->newparent->dd_object, NULL, dd, &dd->dd_parent));
1344
1345 /* add to new parent zapobj */
1346 err = zap_add(mos, ra->newparent->dd_phys->dd_child_dir_zapobj,
1347 dd->dd_myname, 8, 1, &dd->dd_object, tx);
1348 ASSERT0(err);
1349
1350 }
1351
1352 int
1353 dsl_dir_rename(dsl_dir_t *dd, const char *newname)
1354 {
1355 struct renamearg ra;
1356 int err;
1357
1358 /* new parent should exist */
1359 err = dsl_dir_open(newname, FTAG, &ra.newparent, &ra.mynewname);
1360 if (err)
1361 return (err);
1362
1363 /* can't rename to different pool */
1364 if (dd->dd_pool != ra.newparent->dd_pool) {
1365 err = ENXIO;
1366 goto out;
1367 }
1368
|