Skip to content

Commit

Permalink
7606 dmu_objset_find_dp() takes a long time while importing pool
Browse files Browse the repository at this point in the history
Reviewed by: Steve Gonczi <steve.gonczi@delphix.com>
Reviewed by: George Wilson <george.wilson@delphix.com>
Reviewed by: Prashanth Sreenivasa <prashksp@gmail.com>
Approved by: Gordon Ross <gordon.w.ross@gmail.com>
  • Loading branch information
ahrens committed Nov 30, 2016
1 parent 25b5cdf commit 7588687
Showing 1 changed file with 24 additions and 5 deletions.
29 changes: 24 additions & 5 deletions usr/src/uts/common/fs/zfs/dmu_objset.c
Original file line number Diff line number Diff line change
Expand Up @@ -1705,6 +1705,7 @@ typedef struct dmu_objset_find_ctx {
taskq_t *dc_tq;
dsl_pool_t *dc_dp;
uint64_t dc_ddobj;
char *dc_ddname; /* last component of ddobj's name */
int (*dc_func)(dsl_pool_t *, dsl_dataset_t *, void *);
void *dc_arg;
int dc_flags;
Expand All @@ -1716,7 +1717,6 @@ static void
dmu_objset_find_dp_impl(dmu_objset_find_ctx_t *dcp)
{
dsl_pool_t *dp = dcp->dc_dp;
dmu_objset_find_ctx_t *child_dcp;
dsl_dir_t *dd;
dsl_dataset_t *ds;
zap_cursor_t zc;
Expand All @@ -1728,7 +1728,12 @@ dmu_objset_find_dp_impl(dmu_objset_find_ctx_t *dcp)
if (*dcp->dc_error != 0)
goto out;

err = dsl_dir_hold_obj(dp, dcp->dc_ddobj, NULL, FTAG, &dd);
/*
* Note: passing the name (dc_ddname) here is optional, but it
* improves performance because we don't need to call
* zap_value_search() to determine the name.
*/
err = dsl_dir_hold_obj(dp, dcp->dc_ddobj, dcp->dc_ddname, FTAG, &dd);
if (err != 0)
goto out;

Expand All @@ -1753,9 +1758,11 @@ dmu_objset_find_dp_impl(dmu_objset_find_ctx_t *dcp)
sizeof (uint64_t));
ASSERT3U(attr->za_num_integers, ==, 1);

child_dcp = kmem_alloc(sizeof (*child_dcp), KM_SLEEP);
dmu_objset_find_ctx_t *child_dcp =
kmem_alloc(sizeof (*child_dcp), KM_SLEEP);
*child_dcp = *dcp;
child_dcp->dc_ddobj = attr->za_first_integer;
child_dcp->dc_ddname = spa_strdup(attr->za_name);
if (dcp->dc_tq != NULL)
(void) taskq_dispatch(dcp->dc_tq,
dmu_objset_find_dp_cb, child_dcp, TQ_SLEEP);
Expand Down Expand Up @@ -1798,16 +1805,25 @@ dmu_objset_find_dp_impl(dmu_objset_find_ctx_t *dcp)
}
}

dsl_dir_rele(dd, FTAG);
kmem_free(attr, sizeof (zap_attribute_t));

if (err != 0)
if (err != 0) {
dsl_dir_rele(dd, FTAG);
goto out;
}

/*
* Apply to self.
*/
err = dsl_dataset_hold_obj(dp, thisobj, FTAG, &ds);

/*
* Note: we hold the dir while calling dsl_dataset_hold_obj() so
* that the dir will remain cached, and we won't have to re-instantiate
* it (which could be expensive due to finding its name via
* zap_value_search()).
*/
dsl_dir_rele(dd, FTAG);
if (err != 0)
goto out;
err = dcp->dc_func(dp, ds, dcp->dc_arg);
Expand All @@ -1822,6 +1838,8 @@ dmu_objset_find_dp_impl(dmu_objset_find_ctx_t *dcp)
mutex_exit(dcp->dc_error_lock);
}

if (dcp->dc_ddname != NULL)
spa_strfree(dcp->dc_ddname);
kmem_free(dcp, sizeof (*dcp));
}

Expand Down Expand Up @@ -1866,6 +1884,7 @@ dmu_objset_find_dp(dsl_pool_t *dp, uint64_t ddobj,
dcp->dc_tq = NULL;
dcp->dc_dp = dp;
dcp->dc_ddobj = ddobj;
dcp->dc_ddname = NULL;
dcp->dc_func = func;
dcp->dc_arg = arg;
dcp->dc_flags = flags;
Expand Down

0 comments on commit 7588687

Please sign in to comment.