MCPcopy Create free account
hub / github.com/F-Stack/f-stack / bpobj_iterate_impl

Function bpobj_iterate_impl

freebsd/contrib/openzfs/module/zfs/bpobj.c:351–511  ·  view source on GitHub ↗

* Given an initial bpo, start by freeing the BPs that are directly referenced * by that bpo. If the bpo has subobjs, read in its last subobj and push the * subobj to our stack. By popping items off our stack, eventually we will * encounter a bpo that has no subobjs. We can free its bpobj_info_t, and if * requested also free the now-empty bpo from disk and decrement * its parent's subobj coun

Source from the content-addressed store, hash-verified

349 * visiting its last subobj until they too have no more subobjs, and so on.
350 */
351static int
352bpobj_iterate_impl(bpobj_t *initial_bpo, bpobj_itor_t func, void *arg,
353 dmu_tx_t *tx, boolean_t free, uint64_t *bpobj_size)
354{
355 list_t stack;
356 bpobj_info_t *bpi;
357 int err = 0;
358
359 /*
360 * Create a "stack" for us to work with without worrying about
361 * stack overflows. Initialize it with the initial_bpo.
362 */
363 list_create(&stack, sizeof (bpobj_info_t),
364 offsetof(bpobj_info_t, bpi_node));
365 mutex_enter(&initial_bpo->bpo_lock);
366
367 if (bpobj_size != NULL)
368 *bpobj_size = initial_bpo->bpo_phys->bpo_num_blkptrs;
369
370 list_insert_head(&stack, bpi_alloc(initial_bpo, NULL, 0));
371
372 while ((bpi = list_head(&stack)) != NULL) {
373 bpobj_t *bpo = bpi->bpi_bpo;
374
375 ASSERT3P(bpo, !=, NULL);
376 ASSERT(MUTEX_HELD(&bpo->bpo_lock));
377 ASSERT(bpobj_is_open(bpo));
378
379 if (free)
380 dmu_buf_will_dirty(bpo->bpo_dbuf, tx);
381
382 if (bpi->bpi_visited == B_FALSE) {
383 err = bpobj_iterate_blkptrs(bpi, func, arg, 0, tx,
384 free);
385 bpi->bpi_visited = B_TRUE;
386 if (err != 0)
387 break;
388 }
389 /*
390 * We've finished with this bpo's directly-referenced BP's and
391 * it has no more unprocessed subobjs. We can free its
392 * bpobj_info_t (unless it is the topmost, initial_bpo).
393 * If we are freeing from disk, we can also do that.
394 */
395 if (bpi->bpi_unprocessed_subobjs == 0) {
396 /*
397 * If there are no entries, there should
398 * be no bytes.
399 */
400 if (bpobj_is_empty_impl(bpo)) {
401 ASSERT0(bpo->bpo_phys->bpo_bytes);
402 ASSERT0(bpo->bpo_phys->bpo_comp);
403 ASSERT0(bpo->bpo_phys->bpo_uncomp);
404 }
405
406 /* The initial_bpo has no parent and is not closed. */
407 if (bpi->bpi_parent != NULL) {
408 if (free) {

Callers 2

bpobj_iterateFunction · 0.85
bpobj_iterate_nofreeFunction · 0.85

Calls 15

mutex_enterFunction · 0.85
bpi_allocFunction · 0.85
bpobj_is_openFunction · 0.85
dmu_buf_will_dirtyFunction · 0.85
bpobj_iterate_blkptrsFunction · 0.85
bpobj_is_empty_implFunction · 0.85
dmu_buf_is_dirtyFunction · 0.85
dmu_free_rangeFunction · 0.85
dmu_object_freeFunction · 0.85
mutex_exitFunction · 0.85
bpobj_closeFunction · 0.85
dmu_readFunction · 0.85

Tested by

no test coverage detected