Skip to content

Commit

Permalink
Handle some taskq_create() failures.
Browse files Browse the repository at this point in the history
This commit attempts to handle taskq_create() failures and propagate
the error in the following functions:

	dsl_pool_open()
		dsl_pool_init()
		dsl_pool_create()

	zil_open()
		zfs_sb_setup()
		zvol_first_open()

Failures of taskq_create() were already handled in zvol_init().

The other major user of taskq_create() in which there is no error handling
is txg_dispatch_callbacks().
  • Loading branch information
dweeezil committed Apr 3, 2014
1 parent 4d8c78c commit 1070e6f
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 5 deletions.
23 changes: 21 additions & 2 deletions module/zfs/dsl_pool.c
Expand Up @@ -170,6 +170,14 @@ dsl_pool_open_impl(spa_t *spa, uint64_t txg)

dp->dp_iput_taskq = taskq_create("zfs_iput_taskq", 1, minclsyspri,
1, 4, 0);
#ifdef _KERNEL
if (IS_ERR(dp->dp_iput_taskq)) {
dsl_pool_t *rval = (dsl_pool_t *)dp->dp_iput_taskq;
kmem_free(dp, sizeof (dsl_pool_t));
printk(KERN_INFO "%s: taskq_create() failed\n", FTAG);
return (rval);
}
#endif

return (dp);
}
Expand All @@ -180,6 +188,10 @@ dsl_pool_init(spa_t *spa, uint64_t txg, dsl_pool_t **dpp)
int err;
dsl_pool_t *dp = dsl_pool_open_impl(spa, txg);

#ifdef _KERNEL
if (IS_ERR(dp))
return (PTR_ERR(dp));
#endif
err = dmu_objset_open_impl(spa, NULL, &dp->dp_meta_rootbp,
&dp->dp_meta_objset);
if (err != 0)
Expand Down Expand Up @@ -323,12 +335,19 @@ dsl_pool_t *
dsl_pool_create(spa_t *spa, nvlist_t *zplprops, uint64_t txg)
{
int err;
dsl_pool_t *dp = dsl_pool_open_impl(spa, txg);
dmu_tx_t *tx = dmu_tx_create_assigned(dp, txg);
dsl_pool_t *dp;
dmu_tx_t *tx;
objset_t *os;
dsl_dataset_t *ds;
uint64_t obj;

dp = dsl_pool_open_impl(spa, txg);
#ifdef KERNEL
if (IS_ERR(dp))
return (dp);
#endif
tx = dmu_tx_create_assigned(dp, txg);

rrw_enter(&dp->dp_config_rwlock, RW_WRITER, FTAG);

/* create and open the MOS (meta-objset) */
Expand Down
9 changes: 9 additions & 0 deletions module/zfs/spa.c
Expand Up @@ -3507,6 +3507,9 @@ spa_create(const char *pool, nvlist_t *nvroot, nvlist_t *props,
spa_config_exit(spa, SCL_ALL, FTAG);

if (error != 0) {
#ifdef _KERNEL
out:
#endif
spa_unload(spa);
spa_deactivate(spa);
spa_remove(spa);
Expand Down Expand Up @@ -3546,6 +3549,12 @@ spa_create(const char *pool, nvlist_t *nvroot, nvlist_t *props,

spa->spa_is_initializing = B_TRUE;
spa->spa_dsl_pool = dp = dsl_pool_create(spa, zplprops, txg);
#ifdef _KERNEL
if (IS_ERR(dp)) {
error = PTR_ERR(dp);
goto out;
}
#endif
spa->spa_meta_objset = dp->dp_meta_objset;
spa->spa_is_initializing = B_FALSE;

Expand Down
4 changes: 4 additions & 0 deletions module/zfs/zfs_vfsops.c
Expand Up @@ -816,6 +816,10 @@ zfs_sb_setup(zfs_sb_t *zsb, boolean_t mounting)
mutex_exit(&zsb->z_os->os_user_ptr_lock);

zsb->z_log = zil_open(zsb->z_os, zfs_get_data);
if (IS_ERR(zsb->z_log)) {
zfs_unregister_callbacks(zsb);
return (PTR_ERR(zsb->z_log));
}

/*
* If we are not mounting (ie: online recv), then we don't
Expand Down
6 changes: 6 additions & 0 deletions module/zfs/zil.c
Expand Up @@ -1877,6 +1877,12 @@ zil_open(objset_t *os, zil_get_data_t *get_data)
zilog->zl_get_data = get_data;
zilog->zl_clean_taskq = taskq_create("zil_clean", 1, minclsyspri,
2, 2, TASKQ_PREPOPULATE);
#ifdef _KERNEL
if (IS_ERR(zilog->zl_clean_taskq)) {
printk(KERN_INFO "%s: taskq_create() failed\n", FTAG);
return ((zilog_t *)zilog->zl_clean_taskq);
}
#endif

return (zilog);
}
Expand Down
10 changes: 7 additions & 3 deletions module/zfs/zvol.c
Expand Up @@ -966,6 +966,10 @@ zvol_first_open(zvol_state_t *zv)
set_capacity(zv->zv_disk, volsize >> 9);
zv->zv_volsize = volsize;
zv->zv_zilog = zil_open(os, zvol_get_data);
if (IS_ERR(zv->zv_zilog)) {
error = PTR_ERR(zv->zv_zilog);
goto out_mutex;
}

VERIFY(dsl_prop_get_integer(zv->zv_name, "readonly", &ro, NULL) == 0);
if (ro || dmu_objset_is_snapshot(os) ||
Expand Down Expand Up @@ -1643,9 +1647,9 @@ zvol_init(void)

zvol_taskq = taskq_create(ZVOL_DRIVER, zvol_threads, maxclsyspri,
zvol_threads, INT_MAX, TASKQ_PREPOPULATE);
if (zvol_taskq == NULL) {
printk(KERN_INFO "ZFS: taskq_create() failed\n");
error = -ENOMEM;
if (zvol_taskq == NULL || IS_ERR(zvol_taskq)) {
printk(KERN_INFO "ZFS: %s: taskq_create() failed\n", FTAG);
error = SET_ERROR(ENOMEM);
goto out1;
}

Expand Down

0 comments on commit 1070e6f

Please sign in to comment.