Created
February 22, 2019 23:43
-
-
Save sdimitro/87f3a672ba9ae92fb7fa3140f9930d00 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
static int | |
bpobj_iterate_impl(bpobj_t *initial_bpo, bpobj_itor_t func, void *arg, | |
dmu_tx_t *tx, boolean_t free) | |
{ | |
int err = 0; | |
list_t stack; | |
list_create(&stack, sizeof (bpobj_info_t), | |
offsetof(bpobj_info_t, bpi_node)); | |
list_insert_head(&stack, bpi_alloc(initial_bpo, NULL, 0, 0)); | |
for (bpobj_info_t *bpi = list_head(&stack); | |
bpi != NULL; bpi = list_head(&stack)) { | |
bpobj_t *bpo = bpi->bpi_bpo; | |
mutex_enter(&bpo->bpo_lock); | |
ASSERT(bpobj_is_open(bpo)); | |
if (free) | |
dmu_buf_will_dirty(bpo->bpo_dbuf, tx); | |
if (bpi->bpi_visited == B_FALSE) { | |
err = bpobj_iterate_blkptrs(bpi, func, arg, tx, free); | |
bpi->bpi_visited = B_TRUE; | |
if (err != 0) | |
goto out; | |
// XXX: chec has_subobjs etc.. set bpi_unprocessed_subobjs here | |
bpi->bpi_unprocessed_subobjs = bpo->bpo_phys->bpo_num_subobjs; | |
} else if (bpi->bpi_visited && bpi->bpi_unprocessed_subobjs == 0) { | |
/* | |
* If there are no entries, there should | |
* be no bytes. | |
*/ | |
if (bpobj_is_empty(bpo)) { | |
ASSERT0(bpo->bpo_phys->bpo_bytes); | |
ASSERT0(bpo->bpo_phys->bpo_comp); | |
ASSERT0(bpo->bpo_phys->bpo_uncomp); | |
} | |
if (free && (bpi->bpi_parent != NULL)) { | |
bpobj_t *p = bpi->bpi_parent->bpi_bpo; | |
ASSERT0(bpo->bpo_phys->bpo_num_blkptrs); | |
ASSERT3U(p->bpo_phys->bpo_num_subobjs, >, 0); | |
ASSERT3U(bpi->bpi_index, ==, | |
p->bpo_phys->bpo_num_subobjs - 1); | |
VERIFY0(dmu_free_range(p->bpo_os, | |
p->bpo_phys->bpo_subobjs, | |
bpi->bpi_index * sizeof (uint64_t), | |
sizeof (uint64_t), tx)); | |
/* eliminate the empty subobj */ | |
if (bpo->bpo_havesubobj && | |
bpo->bpo_phys->bpo_subobjs != 0) { | |
ASSERT0(bpo->bpo_phys->bpo_num_subobjs); | |
err = dmu_object_free(bpo->bpo_os, | |
bpo->bpo_phys->bpo_subobjs, tx); | |
if (err) | |
break; | |
dmu_buf_will_dirty(bpo->bpo_dbuf, tx); | |
bpo->bpo_phys->bpo_subobjs = 0; | |
} | |
err = dmu_object_free(p->bpo_os, | |
bpi->bpi_object, tx); | |
if (err) | |
break; | |
} | |
mutex_exit(&bpo->bpo_lock); | |
if (bpi->bpi_parent != NULL) { | |
bpobj_close(bpo); | |
} | |
list_remove(&stack, bpi); | |
kmem_free(bpi, sizeof (bpobj_info_t)); | |
} else { | |
ASSERT(bpo->bpo_havecomp); | |
/* Add the last subobj to stack. */ | |
int64_t i = bpi->bpi_unprocessed_subobjs - 1; | |
uint64_t offset = i * sizeof (uint64_t); | |
uint64_t obj_from_sublist; | |
err = dmu_read(bpo->bpo_os, bpo->bpo_phys->bpo_subobjs, | |
offset, sizeof (uint64_t), &obj_from_sublist, | |
DMU_READ_PREFETCH); | |
bpobj_t *sublist = kmem_alloc(sizeof (bpobj_t), | |
KM_SLEEP); | |
err = bpobj_open(sublist, bpo->bpo_os, obj_from_sublist); | |
if (err) | |
break; | |
if (free) | |
dmu_buf_will_dirty(sublist->bpo_dbuf, tx); | |
list_insert_head(&stack, bpi_alloc(sublist, bpi, | |
obj_from_sublist, i)); | |
bpi->bpi_unprocessed_subobjs--; | |
} | |
} | |
out: | |
if (err != 0) | |
bpobj_iterate_cleanup(&stack); | |
ASSERT(list_is_empty(&stack)); | |
list_destroy(&stack); | |
return (err); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment