Update linux-zpios to use updated DMU API
The DMU API has been modified to remove the dmu_objset_open, and dmu_objset_close functions. Now you must explicitly *_create an objset, then *_own it, *_disown it when not in use, and *_destroy it when your through. All and all I like the API much better. Additionally, while I was here I moved the zpios_cmd_t off the stack because previous analysis showed it was very stack heavy.
This commit is contained in:
parent
541bbe3109
commit
21690470e3
|
@ -40,7 +40,7 @@
|
||||||
|
|
||||||
static spl_class *zpios_class;
|
static spl_class *zpios_class;
|
||||||
static spl_device *zpios_device;
|
static spl_device *zpios_device;
|
||||||
|
static char *zpios_tag = "zpios_tag";
|
||||||
|
|
||||||
static
|
static
|
||||||
int zpios_upcall(char *path, char *phase, run_args_t *run_args, int rc)
|
int zpios_upcall(char *path, char *phase, run_args_t *run_args, int rc)
|
||||||
|
@ -161,26 +161,35 @@ zpios_dmu_setup(run_args_t *run_args)
|
||||||
{
|
{
|
||||||
zpios_time_t *t = &(run_args->stats.cr_time);
|
zpios_time_t *t = &(run_args->stats.cr_time);
|
||||||
objset_t *os;
|
objset_t *os;
|
||||||
|
char name[32];
|
||||||
uint64_t obj = 0ULL;
|
uint64_t obj = 0ULL;
|
||||||
int i, rc = 0;
|
int i, rc = 0, rc2;
|
||||||
|
|
||||||
(void)zpios_upcall(run_args->pre, PHASE_PRE_CREATE, run_args, 0);
|
(void)zpios_upcall(run_args->pre, PHASE_PRE_CREATE, run_args, 0);
|
||||||
t->start = zpios_timespec_now();
|
t->start = zpios_timespec_now();
|
||||||
|
|
||||||
rc = dmu_objset_open(run_args->pool, DMU_OST_ZFS, DS_MODE_USER, &os);
|
(void)snprintf(name, 32, "%s/id_%d", run_args->pool, run_args->id);
|
||||||
|
rc = dmu_objset_create(name, DMU_OST_OTHER, 0, NULL, NULL);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
zpios_print(run_args->file, "Error dmu_objset_open() "
|
zpios_print(run_args->file, "Error dmu_objset_create(%s, ...) "
|
||||||
"failed: %d\n", rc);
|
"failed: %d\n", name, rc);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rc = dmu_objset_own(name, DMU_OST_OTHER, 0, zpios_tag, &os);
|
||||||
|
if (rc) {
|
||||||
|
zpios_print(run_args->file, "Error dmu_objset_own(%s, ...) "
|
||||||
|
"failed: %d\n", name, rc);
|
||||||
|
goto out_destroy;
|
||||||
|
}
|
||||||
|
|
||||||
if (!(run_args->flags & DMU_FPP)) {
|
if (!(run_args->flags & DMU_FPP)) {
|
||||||
obj = zpios_dmu_object_create(run_args, os);
|
obj = zpios_dmu_object_create(run_args, os);
|
||||||
if (obj == 0) {
|
if (obj == 0) {
|
||||||
rc = -EBADF;
|
rc = -EBADF;
|
||||||
zpios_print(run_args->file, "Error zpios_dmu_"
|
zpios_print(run_args->file, "Error zpios_dmu_"
|
||||||
"object_create() failed, %d\n", rc);
|
"object_create() failed, %d\n", rc);
|
||||||
goto out;
|
goto out_destroy;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,6 +222,13 @@ zpios_dmu_setup(run_args_t *run_args)
|
||||||
}
|
}
|
||||||
|
|
||||||
run_args->os = os;
|
run_args->os = os;
|
||||||
|
out_destroy:
|
||||||
|
if (rc) {
|
||||||
|
rc2 = dmu_objset_destroy(name, B_FALSE);
|
||||||
|
if (rc2)
|
||||||
|
zpios_print(run_args->file, "Error dmu_objset_destroy"
|
||||||
|
"(%s, ...) failed: %d\n", name, rc2);
|
||||||
|
}
|
||||||
out:
|
out:
|
||||||
t->stop = zpios_timespec_now();
|
t->stop = zpios_timespec_now();
|
||||||
t->delta = zpios_timespec_sub(t->stop, t->start);
|
t->delta = zpios_timespec_sub(t->stop, t->start);
|
||||||
|
@ -340,15 +356,18 @@ zpios_get_work_item(run_args_t *run_args, dmu_obj_t *obj, __u64 *offset,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
zpios_remove_objects(run_args_t *run_args)
|
zpios_remove_objset(run_args_t *run_args)
|
||||||
{
|
{
|
||||||
zpios_time_t *t = &(run_args->stats.rm_time);
|
zpios_time_t *t = &(run_args->stats.rm_time);
|
||||||
zpios_region_t *region;
|
zpios_region_t *region;
|
||||||
|
char name[32];
|
||||||
int rc = 0, i;
|
int rc = 0, i;
|
||||||
|
|
||||||
(void)zpios_upcall(run_args->pre, PHASE_PRE_REMOVE, run_args, 0);
|
(void)zpios_upcall(run_args->pre, PHASE_PRE_REMOVE, run_args, 0);
|
||||||
t->start = zpios_timespec_now();
|
t->start = zpios_timespec_now();
|
||||||
|
|
||||||
|
(void)snprintf(name, 32, "%s/id_%d", run_args->pool, run_args->id);
|
||||||
|
|
||||||
if (run_args->flags & DMU_REMOVE) {
|
if (run_args->flags & DMU_REMOVE) {
|
||||||
if (run_args->flags & DMU_FPP) {
|
if (run_args->flags & DMU_FPP) {
|
||||||
for (i = 0; i < run_args->region_count; i++) {
|
for (i = 0; i < run_args->region_count; i++) {
|
||||||
|
@ -373,7 +392,14 @@ zpios_remove_objects(run_args_t *run_args)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dmu_objset_close(run_args->os);
|
dmu_objset_disown(run_args->os, zpios_tag);
|
||||||
|
|
||||||
|
if (run_args->flags & DMU_REMOVE) {
|
||||||
|
rc = dmu_objset_destroy(name, B_FALSE);
|
||||||
|
if (rc)
|
||||||
|
zpios_print(run_args->file, "Error dmu_objset_destroy"
|
||||||
|
"(%s, ...) failed: %d\n", name, rc);
|
||||||
|
}
|
||||||
|
|
||||||
t->stop = zpios_timespec_now();
|
t->stop = zpios_timespec_now();
|
||||||
t->delta = zpios_timespec_sub(t->stop, t->start);
|
t->delta = zpios_timespec_sub(t->stop, t->start);
|
||||||
|
@ -843,7 +869,7 @@ zpios_do_one_run(struct file *file, zpios_cmd_t *kcmd,
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
rc = zpios_threads_run(run_args);
|
rc = zpios_threads_run(run_args);
|
||||||
zpios_remove_objects(run_args);
|
zpios_remove_objset(run_args);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
|
@ -1009,61 +1035,71 @@ zpios_ioctl_cfg(struct file *file, unsigned long arg)
|
||||||
static int
|
static int
|
||||||
zpios_ioctl_cmd(struct file *file, unsigned long arg)
|
zpios_ioctl_cmd(struct file *file, unsigned long arg)
|
||||||
{
|
{
|
||||||
zpios_cmd_t kcmd;
|
zpios_cmd_t *kcmd;
|
||||||
int rc = -EINVAL;
|
|
||||||
void *data = NULL;
|
void *data = NULL;
|
||||||
|
int rc = -EINVAL;
|
||||||
|
|
||||||
rc = copy_from_user(&kcmd, (zpios_cfg_t *)arg, sizeof(kcmd));
|
kcmd = kmem_alloc(sizeof(zpios_cmd_t), KM_SLEEP);
|
||||||
if (rc) {
|
if (kcmd == NULL) {
|
||||||
zpios_print(file, "Unable to copy command structure "
|
zpios_print(file, "Unable to kmem_alloc() %ld byte for "
|
||||||
"from user to kernel memory, %d\n", rc);
|
"zpios_cmd_t\n", sizeof(zpios_cmd_t));
|
||||||
return -EFAULT;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (kcmd.cmd_magic != ZPIOS_CMD_MAGIC) {
|
|
||||||
zpios_print(file, "Bad command magic 0x%x != 0x%x\n",
|
|
||||||
kcmd.cmd_magic, ZPIOS_CFG_MAGIC);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Allocate memory for any opaque data the caller needed to pass on */
|
|
||||||
if (kcmd.cmd_data_size > 0) {
|
|
||||||
data = (void *)vmem_alloc(kcmd.cmd_data_size, KM_SLEEP);
|
|
||||||
if (data == NULL) {
|
|
||||||
zpios_print(file, "Unable to vmem_alloc() %ld "
|
|
||||||
"bytes for data buffer\n",
|
|
||||||
(long)kcmd.cmd_data_size);
|
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rc = copy_from_user(kcmd, (zpios_cfg_t *)arg, sizeof(zpios_cmd_t));
|
||||||
|
if (rc) {
|
||||||
|
zpios_print(file, "Unable to copy command structure "
|
||||||
|
"from user to kernel memory, %d\n", rc);
|
||||||
|
goto out_cmd;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (kcmd->cmd_magic != ZPIOS_CMD_MAGIC) {
|
||||||
|
zpios_print(file, "Bad command magic 0x%x != 0x%x\n",
|
||||||
|
kcmd->cmd_magic, ZPIOS_CFG_MAGIC);
|
||||||
|
rc = -EINVAL;
|
||||||
|
goto out_cmd;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate memory for any opaque data the caller needed to pass on */
|
||||||
|
if (kcmd->cmd_data_size > 0) {
|
||||||
|
data = (void *)vmem_alloc(kcmd->cmd_data_size, KM_SLEEP);
|
||||||
|
if (data == NULL) {
|
||||||
|
zpios_print(file, "Unable to vmem_alloc() %ld "
|
||||||
|
"bytes for data buffer\n",
|
||||||
|
(long)kcmd->cmd_data_size);
|
||||||
|
rc = -ENOMEM;
|
||||||
|
goto out_cmd;
|
||||||
|
}
|
||||||
|
|
||||||
rc = copy_from_user(data, (void *)(arg + offsetof(zpios_cmd_t,
|
rc = copy_from_user(data, (void *)(arg + offsetof(zpios_cmd_t,
|
||||||
cmd_data_str)), kcmd.cmd_data_size);
|
cmd_data_str)), kcmd->cmd_data_size);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
zpios_print(file, "Unable to copy data buffer "
|
zpios_print(file, "Unable to copy data buffer "
|
||||||
"from user to kernel memory, %d\n", rc);
|
"from user to kernel memory, %d\n", rc);
|
||||||
vmem_free(data, kcmd.cmd_data_size);
|
goto out_data;
|
||||||
return -EFAULT;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = zpios_do_one_run(file, &kcmd, kcmd.cmd_data_size, data);
|
rc = zpios_do_one_run(file, kcmd, kcmd->cmd_data_size, data);
|
||||||
|
|
||||||
if (data != NULL) {
|
if (data != NULL) {
|
||||||
/* If the test failed do not print out the stats */
|
/* If the test failed do not print out the stats */
|
||||||
if (rc)
|
if (rc)
|
||||||
goto cleanup;
|
goto out_data;
|
||||||
|
|
||||||
rc = copy_to_user((void *)(arg + offsetof(zpios_cmd_t,
|
rc = copy_to_user((void *)(arg + offsetof(zpios_cmd_t,
|
||||||
cmd_data_str)), data, kcmd.cmd_data_size);
|
cmd_data_str)), data, kcmd->cmd_data_size);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
zpios_print(file, "Unable to copy data buffer "
|
zpios_print(file, "Unable to copy data buffer "
|
||||||
"from kernel to user memory, %d\n", rc);
|
"from kernel to user memory, %d\n", rc);
|
||||||
rc = -EFAULT;
|
rc = -EFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
cleanup:
|
out_data:
|
||||||
vmem_free(data, kcmd.cmd_data_size);
|
vmem_free(data, kcmd->cmd_data_size);
|
||||||
}
|
}
|
||||||
|
out_cmd:
|
||||||
|
kmem_free(kcmd, sizeof(zpios_cmd_t));
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue