mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2024-12-27 03:19:35 +03:00
Conserve stack in dsl_scan_visit()
The dsl_scan_visit() function is a little heavy weight taking 464 bytes on the stack. This can be easily reduced for little cost by moving zap_cursor_t and zap_attribute_t off the stack and on to the heap. After this change dsl_scan_visit() has been reduced in size by 320 bytes. This change was made to reduce stack usage in the dsl_scan_sync() callpath which is recursive and has been observed to overflow the stack. Issue #174
This commit is contained in:
parent
b81c4ac9af
commit
40a39e1103
@ -1328,8 +1328,8 @@ static void
|
|||||||
dsl_scan_visit(dsl_scan_t *scn, dmu_tx_t *tx)
|
dsl_scan_visit(dsl_scan_t *scn, dmu_tx_t *tx)
|
||||||
{
|
{
|
||||||
dsl_pool_t *dp = scn->scn_dp;
|
dsl_pool_t *dp = scn->scn_dp;
|
||||||
zap_cursor_t zc;
|
zap_cursor_t *zc;
|
||||||
zap_attribute_t za;
|
zap_attribute_t *za;
|
||||||
|
|
||||||
if (scn->scn_phys.scn_ddt_bookmark.ddb_class <=
|
if (scn->scn_phys.scn_ddt_bookmark.ddb_class <=
|
||||||
scn->scn_phys.scn_ddt_class_max) {
|
scn->scn_phys.scn_ddt_class_max) {
|
||||||
@ -1377,24 +1377,26 @@ dsl_scan_visit(dsl_scan_t *scn, dmu_tx_t *tx)
|
|||||||
* bookmark so we don't think that we're still trying to resume.
|
* bookmark so we don't think that we're still trying to resume.
|
||||||
*/
|
*/
|
||||||
bzero(&scn->scn_phys.scn_bookmark, sizeof (zbookmark_t));
|
bzero(&scn->scn_phys.scn_bookmark, sizeof (zbookmark_t));
|
||||||
|
zc = kmem_alloc(sizeof(zap_cursor_t), KM_SLEEP);
|
||||||
|
za = kmem_alloc(sizeof(zap_attribute_t), KM_SLEEP);
|
||||||
|
|
||||||
/* keep pulling things out of the zap-object-as-queue */
|
/* keep pulling things out of the zap-object-as-queue */
|
||||||
while (zap_cursor_init(&zc, dp->dp_meta_objset,
|
while (zap_cursor_init(zc, dp->dp_meta_objset,
|
||||||
scn->scn_phys.scn_queue_obj),
|
scn->scn_phys.scn_queue_obj),
|
||||||
zap_cursor_retrieve(&zc, &za) == 0) {
|
zap_cursor_retrieve(zc, za) == 0) {
|
||||||
dsl_dataset_t *ds;
|
dsl_dataset_t *ds;
|
||||||
uint64_t dsobj;
|
uint64_t dsobj;
|
||||||
|
|
||||||
dsobj = strtonum(za.za_name, NULL);
|
dsobj = strtonum(za->za_name, NULL);
|
||||||
VERIFY3U(0, ==, zap_remove_int(dp->dp_meta_objset,
|
VERIFY3U(0, ==, zap_remove_int(dp->dp_meta_objset,
|
||||||
scn->scn_phys.scn_queue_obj, dsobj, tx));
|
scn->scn_phys.scn_queue_obj, dsobj, tx));
|
||||||
|
|
||||||
/* Set up min/max txg */
|
/* Set up min/max txg */
|
||||||
VERIFY3U(0, ==, dsl_dataset_hold_obj(dp, dsobj, FTAG, &ds));
|
VERIFY3U(0, ==, dsl_dataset_hold_obj(dp, dsobj, FTAG, &ds));
|
||||||
if (za.za_first_integer != 0) {
|
if (za->za_first_integer != 0) {
|
||||||
scn->scn_phys.scn_cur_min_txg =
|
scn->scn_phys.scn_cur_min_txg =
|
||||||
MAX(scn->scn_phys.scn_min_txg,
|
MAX(scn->scn_phys.scn_min_txg,
|
||||||
za.za_first_integer);
|
za->za_first_integer);
|
||||||
} else {
|
} else {
|
||||||
scn->scn_phys.scn_cur_min_txg =
|
scn->scn_phys.scn_cur_min_txg =
|
||||||
MAX(scn->scn_phys.scn_min_txg,
|
MAX(scn->scn_phys.scn_min_txg,
|
||||||
@ -1404,11 +1406,14 @@ dsl_scan_visit(dsl_scan_t *scn, dmu_tx_t *tx)
|
|||||||
dsl_dataset_rele(ds, FTAG);
|
dsl_dataset_rele(ds, FTAG);
|
||||||
|
|
||||||
dsl_scan_visitds(scn, dsobj, tx);
|
dsl_scan_visitds(scn, dsobj, tx);
|
||||||
zap_cursor_fini(&zc);
|
zap_cursor_fini(zc);
|
||||||
if (scn->scn_pausing)
|
if (scn->scn_pausing)
|
||||||
return;
|
goto out;
|
||||||
}
|
}
|
||||||
zap_cursor_fini(&zc);
|
zap_cursor_fini(zc);
|
||||||
|
out:
|
||||||
|
kmem_free(za, sizeof(zap_attribute_t));
|
||||||
|
kmem_free(zc, sizeof(zap_cursor_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
Loading…
Reference in New Issue
Block a user