diff --git a/sys/cam/ctl/ctl_backend.c b/sys/cam/ctl/ctl_backend.c index 5234c4a32076..16e43eb660bc 100644 --- a/sys/cam/ctl/ctl_backend.c +++ b/sys/cam/ctl/ctl_backend.c @@ -173,6 +173,45 @@ ctl_backend_find(char *backend_name) return (NULL); } -/* - * vim: ts=8 - */ +void +ctl_init_opts(struct ctl_be_lun *be_lun, struct ctl_lun_req *req) +{ + struct ctl_be_lun_option *opt; + int i; + + STAILQ_INIT(&be_lun->options); + for (i = 0; i < req->num_be_args; i++) { + opt = malloc(sizeof(*opt), M_CTL, M_WAITOK); + opt->name = malloc(strlen(req->kern_be_args[i].kname) + 1, M_CTL, M_WAITOK); + strcpy(opt->name, req->kern_be_args[i].kname); + opt->value = malloc(strlen(req->kern_be_args[i].kvalue) + 1, M_CTL, M_WAITOK); + strcpy(opt->value, req->kern_be_args[i].kvalue); + STAILQ_INSERT_TAIL(&be_lun->options, opt, links); + } +} + +void +ctl_free_opts(struct ctl_be_lun *be_lun) +{ + struct ctl_be_lun_option *opt; + + while ((opt = STAILQ_FIRST(&be_lun->options)) != NULL) { + STAILQ_REMOVE_HEAD(&be_lun->options, links); + free(opt->name, M_CTL); + free(opt->value, M_CTL); + free(opt, M_CTL); + } +} + +char * +ctl_get_opt(struct ctl_be_lun *be_lun, const char *name) +{ + struct ctl_be_lun_option *opt; + + STAILQ_FOREACH(opt, &be_lun->options, links) { + if (strcmp(opt->name, name) == 0) { + return (opt->value); + } + } + return (NULL); +} diff --git a/sys/cam/ctl/ctl_backend.h b/sys/cam/ctl/ctl_backend.h index ad93119afc97..640a7f990e21 100644 --- a/sys/cam/ctl/ctl_backend.h +++ b/sys/cam/ctl/ctl_backend.h @@ -301,6 +301,14 @@ int ctl_lun_online(struct ctl_be_lun *be_lun); */ void ctl_lun_capacity_changed(struct ctl_be_lun *be_lun); +/* + * KPI to manipulate LUN options + */ +struct ctl_lun_req; +void ctl_init_opts(struct ctl_be_lun *be_lun, struct ctl_lun_req *req); +void ctl_free_opts(struct ctl_be_lun *be_lun); +char * ctl_get_opt(struct ctl_be_lun *be_lun, const char *name); + #endif /* _KERNEL */ #endif /* _CTL_BACKEND_H_ */ diff --git a/sys/cam/ctl/ctl_backend_block.c b/sys/cam/ctl/ctl_backend_block.c index a5b01592e346..cedc2d660487 100644 --- a/sys/cam/ctl/ctl_backend_block.c +++ b/sys/cam/ctl/ctl_backend_block.c @@ -1822,9 +1822,12 @@ ctl_be_block_create(struct ctl_be_block_softc *softc, struct ctl_lun_req *req) struct ctl_be_block_lun *be_lun; struct ctl_lun_create_params *params; struct ctl_be_arg *file_arg; + char num_thread_str[16]; char tmpstr[32]; + char *value; int retval, num_threads, unmap; int i; + int tmp_num_threads; params = &req->reqdata.create; retval = 0; @@ -1839,9 +1842,9 @@ ctl_be_block_create(struct ctl_be_block_softc *softc, struct ctl_lun_req *req) STAILQ_INIT(&be_lun->input_queue); STAILQ_INIT(&be_lun->config_write_queue); STAILQ_INIT(&be_lun->datamove_queue); - STAILQ_INIT(&be_lun->ctl_be_lun.options); sprintf(be_lun->lunname, "cblk%d", softc->num_luns); mtx_init(&be_lun->lock, be_lun->lunname, NULL, MTX_DEF); + ctl_init_opts(&be_lun->ctl_be_lun, req); be_lun->lun_zone = uma_zcreate(be_lun->lunname, CTLBLK_MAX_SEG, NULL, NULL, NULL, NULL, /*align*/ 0, /*flags*/0); @@ -1914,50 +1917,27 @@ ctl_be_block_create(struct ctl_be_block_softc *softc, struct ctl_lun_req *req) * XXX This searching loop might be refactored to be combined with * the loop above, */ - unmap = 0; - for (i = 0; i < req->num_be_args; i++) { - if (strcmp(req->kern_be_args[i].kname, "num_threads") == 0) { - struct ctl_be_arg *thread_arg; - char num_thread_str[16]; - int tmp_num_threads; + value = ctl_get_opt(&be_lun->ctl_be_lun, "num_threads"); + if (value != NULL) { + tmp_num_threads = strtol(value, NULL, 0); - - thread_arg = &req->kern_be_args[i]; - - strlcpy(num_thread_str, (char *)thread_arg->kvalue, - min(thread_arg->vallen, - sizeof(num_thread_str))); - - tmp_num_threads = strtol(num_thread_str, NULL, 0); - - /* - * We don't let the user specify less than one - * thread, but hope he's clueful enough not to - * specify 1000 threads. - */ - if (tmp_num_threads < 1) { - snprintf(req->error_str, sizeof(req->error_str), - "%s: invalid number of threads %s", - __func__, num_thread_str); - goto bailout_error; - } - - num_threads = tmp_num_threads; - } else if (strcmp(req->kern_be_args[i].kname, "unmap") == 0 && - strcmp(req->kern_be_args[i].kvalue, "on") == 0) { - unmap = 1; - } else if (strcmp(req->kern_be_args[i].kname, "file") != 0 && - strcmp(req->kern_be_args[i].kname, "dev") != 0) { - struct ctl_be_lun_option *opt; - - opt = malloc(sizeof(*opt), M_CTLBLK, M_WAITOK); - opt->name = malloc(strlen(req->kern_be_args[i].kname) + 1, M_CTLBLK, M_WAITOK); - strcpy(opt->name, req->kern_be_args[i].kname); - opt->value = malloc(strlen(req->kern_be_args[i].kvalue) + 1, M_CTLBLK, M_WAITOK); - strcpy(opt->value, req->kern_be_args[i].kvalue); - STAILQ_INSERT_TAIL(&be_lun->ctl_be_lun.options, opt, links); + /* + * We don't let the user specify less than one + * thread, but hope he's clueful enough not to + * specify 1000 threads. + */ + if (tmp_num_threads < 1) { + snprintf(req->error_str, sizeof(req->error_str), + "%s: invalid number of threads %s", + __func__, num_thread_str); + goto bailout_error; } + num_threads = tmp_num_threads; } + unmap = 0; + value = ctl_get_opt(&be_lun->ctl_be_lun, "unmap"); + if (value != NULL && strcmp(value, "on") == 0) + unmap = 1; be_lun->flags = CTL_BE_BLOCK_LUN_UNCONFIGURED; be_lun->ctl_be_lun.flags = CTL_LUN_FLAG_PRIMARY; @@ -2120,6 +2100,7 @@ ctl_be_block_create(struct ctl_be_block_softc *softc, struct ctl_lun_req *req) free(be_lun->dev_path, M_CTLBLK); if (be_lun->lun_zone != NULL) uma_zdestroy(be_lun->lun_zone); + ctl_free_opts(&be_lun->ctl_be_lun); mtx_destroy(&be_lun->lock); free(be_lun, M_CTLBLK); @@ -2206,6 +2187,7 @@ ctl_be_block_rm(struct ctl_be_block_softc *softc, struct ctl_lun_req *req) uma_zdestroy(be_lun->lun_zone); + ctl_free_opts(&be_lun->ctl_be_lun); free(be_lun->dev_path, M_CTLBLK); free(be_lun, M_CTLBLK); diff --git a/sys/cam/ctl/ctl_backend_ramdisk.c b/sys/cam/ctl/ctl_backend_ramdisk.c index 57c470e9ce34..7547665cc39c 100644 --- a/sys/cam/ctl/ctl_backend_ramdisk.c +++ b/sys/cam/ctl/ctl_backend_ramdisk.c @@ -502,6 +502,7 @@ ctl_backend_ramdisk_rm(struct ctl_be_ramdisk_softc *softc, if (retval == 0) { taskqueue_drain(be_lun->io_taskqueue, &be_lun->io_task); taskqueue_free(be_lun->io_taskqueue); + ctl_free_opts(&be_lun->ctl_be_lun); mtx_destroy(&be_lun->lock); free(be_lun, M_RAMDISK); } @@ -523,8 +524,9 @@ ctl_backend_ramdisk_create(struct ctl_be_ramdisk_softc *softc, struct ctl_be_ramdisk_lun *be_lun; struct ctl_lun_create_params *params; uint32_t blocksize; + char *value; char tmpstr[32]; - int i, retval, unmap; + int retval, unmap; retval = 0; params = &req->reqdata.create; @@ -543,7 +545,7 @@ ctl_backend_ramdisk_create(struct ctl_be_ramdisk_softc *softc, goto bailout_error; } sprintf(be_lun->lunname, "cram%d", softc->num_luns); - STAILQ_INIT(&be_lun->ctl_be_lun.options); + ctl_init_opts(&be_lun->ctl_be_lun, req); if (params->flags & CTL_LUN_FLAG_DEV_TYPE) be_lun->ctl_be_lun.lun_type = params->device_type; @@ -581,21 +583,9 @@ ctl_backend_ramdisk_create(struct ctl_be_ramdisk_softc *softc, be_lun->softc = softc; unmap = 0; - for (i = 0; i < req->num_be_args; i++) { - if (strcmp(req->kern_be_args[i].kname, "unmap") == 0 && - strcmp(req->kern_be_args[i].kvalue, "on") == 0) { - unmap = 1; - } else { - struct ctl_be_lun_option *opt; - - opt = malloc(sizeof(*opt), M_RAMDISK, M_WAITOK); - opt->name = malloc(strlen(req->kern_be_args[i].kname) + 1, M_RAMDISK, M_WAITOK); - strcpy(opt->name, req->kern_be_args[i].kname); - opt->value = malloc(strlen(req->kern_be_args[i].kvalue) + 1, M_RAMDISK, M_WAITOK); - strcpy(opt->value, req->kern_be_args[i].kvalue); - STAILQ_INSERT_TAIL(&be_lun->ctl_be_lun.options, opt, links); - } - } + value = ctl_get_opt(&be_lun->ctl_be_lun, "unmap"); + if (value != NULL && strcmp(value, "on") == 0) + unmap = 1; be_lun->flags = CTL_BE_RAMDISK_LUN_UNCONFIGURED; be_lun->ctl_be_lun.flags = CTL_LUN_FLAG_PRIMARY; @@ -728,6 +718,7 @@ ctl_backend_ramdisk_create(struct ctl_be_ramdisk_softc *softc, if (be_lun->io_taskqueue != NULL) { taskqueue_free(be_lun->io_taskqueue); } + ctl_free_opts(&be_lun->ctl_be_lun); mtx_destroy(&be_lun->lock); free(be_lun, M_RAMDISK); } diff --git a/sys/cam/ctl/ctl_frontend_iscsi.c b/sys/cam/ctl/ctl_frontend_iscsi.c index fbe46b40a5c4..2277178520e1 100644 --- a/sys/cam/ctl/ctl_frontend_iscsi.c +++ b/sys/cam/ctl/ctl_frontend_iscsi.c @@ -2312,22 +2312,18 @@ cfiscsi_lun_enable(void *arg, struct ctl_id target_id, int lun_id) { struct cfiscsi_softc *softc; struct cfiscsi_target *ct; - struct ctl_be_lun_option *opt; const char *target = NULL, *target_alias = NULL; const char *lun = NULL; unsigned long tmp; softc = (struct cfiscsi_softc *)arg; - STAILQ_FOREACH(opt, - &control_softc->ctl_luns[lun_id]->be_lun->options, links) { - if (strcmp(opt->name, "cfiscsi_target") == 0) - target = opt->value; - else if (strcmp(opt->name, "cfiscsi_target_alias") == 0) - target_alias = opt->value; - else if (strcmp(opt->name, "cfiscsi_lun") == 0) - lun = opt->value; - } + target = ctl_get_opt(control_softc->ctl_luns[lun_id]->be_lun, + "cfiscsi_target"); + target_alias = ctl_get_opt(control_softc->ctl_luns[lun_id]->be_lun, + "cfiscsi_target)alias"); + lun = ctl_get_opt(control_softc->ctl_luns[lun_id]->be_lun, + "cfiscsi_lun"); if (target == NULL && lun == NULL) return (0);