X-Git-Url: https://git.camperquake.de/gitweb.cgi?a=blobdiff_plain;f=module%2Fzfs%2Fdmu_traverse.c;h=376f60f828b6cca1eeb2e91abc1cc3d2eb766676;hb=5b7e5b5ab980ecfce7381820a1b952dc1af5a7bb;hp=023f90e12e342999aa8c3a767b076de8f755f047;hpb=572e285762521df27fe5b026f409ba1a21abb7ac;p=zfs.git diff --git a/module/zfs/dmu_traverse.c b/module/zfs/dmu_traverse.c index 023f90e..376f60f 100644 --- a/module/zfs/dmu_traverse.c +++ b/module/zfs/dmu_traverse.c @@ -356,24 +356,28 @@ static int traverse_impl(spa_t *spa, dsl_dataset_t *ds, blkptr_t *rootbp, uint64_t txg_start, int flags, blkptr_cb_t func, void *arg) { - traverse_data_t td; - prefetch_data_t pd = { 0 }; - zbookmark_t czb; + traverse_data_t *td; + prefetch_data_t *pd; + zbookmark_t *czb; int err; - td.td_spa = spa; - td.td_objset = ds ? ds->ds_object : 0; - td.td_rootbp = rootbp; - td.td_min_txg = txg_start; - td.td_func = func; - td.td_arg = arg; - td.td_pfd = &pd; - td.td_flags = flags; + td = kmem_alloc(sizeof(traverse_data_t), KM_PUSHPAGE); + pd = kmem_zalloc(sizeof(prefetch_data_t), KM_PUSHPAGE); + czb = kmem_alloc(sizeof(zbookmark_t), KM_PUSHPAGE); + + td->td_spa = spa; + td->td_objset = ds ? ds->ds_object : 0; + td->td_rootbp = rootbp; + td->td_min_txg = txg_start; + td->td_func = func; + td->td_arg = arg; + td->td_pfd = pd; + td->td_flags = flags; - pd.pd_blks_max = zfs_pd_blks_max; - pd.pd_flags = flags; - mutex_init(&pd.pd_mtx, NULL, MUTEX_DEFAULT, NULL); - cv_init(&pd.pd_cv, NULL, CV_DEFAULT, NULL); + pd->pd_blks_max = zfs_pd_blks_max; + pd->pd_flags = flags; + mutex_init(&pd->pd_mtx, NULL, MUTEX_DEFAULT, NULL); + cv_init(&pd->pd_cv, NULL, CV_DEFAULT, NULL); /* See comment on ZIL traversal in dsl_scan_visitds. */ if (ds != NULL && !dsl_dataset_is_snapshot(ds)) { @@ -383,27 +387,31 @@ traverse_impl(spa_t *spa, dsl_dataset_t *ds, blkptr_t *rootbp, if (err) return (err); - traverse_zil(&td, &os->os_zil_header); + traverse_zil(td, &os->os_zil_header); } if (!(flags & TRAVERSE_PREFETCH) || 0 == taskq_dispatch(system_taskq, traverse_prefetch_thread, - &td, TQ_NOQUEUE)) - pd.pd_exited = B_TRUE; + td, TQ_NOQUEUE)) + pd->pd_exited = B_TRUE; - SET_BOOKMARK(&czb, td.td_objset, + SET_BOOKMARK(czb, td->td_objset, ZB_ROOT_OBJECT, ZB_ROOT_LEVEL, ZB_ROOT_BLKID); - err = traverse_visitbp(&td, NULL, NULL, rootbp, &czb); + err = traverse_visitbp(td, NULL, NULL, rootbp, czb); - mutex_enter(&pd.pd_mtx); - pd.pd_cancel = B_TRUE; - cv_broadcast(&pd.pd_cv); - while (!pd.pd_exited) - cv_wait(&pd.pd_cv, &pd.pd_mtx); - mutex_exit(&pd.pd_mtx); + mutex_enter(&pd->pd_mtx); + pd->pd_cancel = B_TRUE; + cv_broadcast(&pd->pd_cv); + while (!pd->pd_exited) + cv_wait(&pd->pd_cv, &pd->pd_mtx); + mutex_exit(&pd->pd_mtx); - mutex_destroy(&pd.pd_mtx); - cv_destroy(&pd.pd_cv); + mutex_destroy(&pd->pd_mtx); + cv_destroy(&pd->pd_cv); + + kmem_free(czb, sizeof(zbookmark_t)); + kmem_free(pd, sizeof(struct prefetch_data)); + kmem_free(td, sizeof(struct traverse_data)); return (err); } @@ -480,3 +488,11 @@ traverse_pool(spa_t *spa, uint64_t txg_start, int flags, err = 0; return (err != 0 ? err : lasterr); } + +#if defined(_KERNEL) && defined(HAVE_SPL) +EXPORT_SYMBOL(traverse_dataset); +EXPORT_SYMBOL(traverse_pool); + +module_param(zfs_pd_blks_max, int, 0644); +MODULE_PARM_DESC(zfs_pd_blks_max, "Max number of blocks to prefetch"); +#endif