Changeset View
Changeset View
Standalone View
Standalone View
sys/cam/ctl/ctl_backend_block.c
Show First 20 Lines • Show All 72 Lines • ▼ Show 20 Lines | |||||
#include <sys/filedesc.h> | #include <sys/filedesc.h> | ||||
#include <sys/filio.h> | #include <sys/filio.h> | ||||
#include <sys/proc.h> | #include <sys/proc.h> | ||||
#include <sys/pcpu.h> | #include <sys/pcpu.h> | ||||
#include <sys/module.h> | #include <sys/module.h> | ||||
#include <sys/sdt.h> | #include <sys/sdt.h> | ||||
#include <sys/devicestat.h> | #include <sys/devicestat.h> | ||||
#include <sys/sysctl.h> | #include <sys/sysctl.h> | ||||
#include <sys/nv.h> | |||||
#include <sys/dnv.h> | |||||
#include <geom/geom.h> | #include <geom/geom.h> | ||||
#include <cam/cam.h> | #include <cam/cam.h> | ||||
#include <cam/scsi/scsi_all.h> | #include <cam/scsi/scsi_all.h> | ||||
#include <cam/scsi/scsi_da.h> | #include <cam/scsi/scsi_da.h> | ||||
#include <cam/ctl/ctl_io.h> | #include <cam/ctl/ctl_io.h> | ||||
#include <cam/ctl/ctl.h> | #include <cam/ctl/ctl.h> | ||||
▲ Show 20 Lines • Show All 1,723 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
static int | static int | ||||
ctl_be_block_open_file(struct ctl_be_block_lun *be_lun, struct ctl_lun_req *req) | ctl_be_block_open_file(struct ctl_be_block_lun *be_lun, struct ctl_lun_req *req) | ||||
{ | { | ||||
struct ctl_be_lun *cbe_lun; | struct ctl_be_lun *cbe_lun; | ||||
struct ctl_be_block_filedata *file_data; | struct ctl_be_block_filedata *file_data; | ||||
struct ctl_lun_create_params *params; | struct ctl_lun_create_params *params; | ||||
char *value; | const char *value; | ||||
struct vattr vattr; | struct vattr vattr; | ||||
off_t ps, pss, po, pos, us, uss, uo, uos; | off_t ps, pss, po, pos, us, uss, uo, uos; | ||||
int error; | int error; | ||||
cbe_lun = &be_lun->cbe_lun; | cbe_lun = &be_lun->cbe_lun; | ||||
file_data = &be_lun->backend.file; | file_data = &be_lun->backend.file; | ||||
params = &be_lun->params; | params = &be_lun->params; | ||||
Show All 33 Lines | else | ||||
cbe_lun->blocksize = 512; | cbe_lun->blocksize = 512; | ||||
be_lun->size_blocks = be_lun->size_bytes / cbe_lun->blocksize; | be_lun->size_blocks = be_lun->size_bytes / cbe_lun->blocksize; | ||||
cbe_lun->maxlba = (be_lun->size_blocks == 0) ? | cbe_lun->maxlba = (be_lun->size_blocks == 0) ? | ||||
0 : (be_lun->size_blocks - 1); | 0 : (be_lun->size_blocks - 1); | ||||
us = ps = vattr.va_blocksize; | us = ps = vattr.va_blocksize; | ||||
uo = po = 0; | uo = po = 0; | ||||
value = ctl_get_opt(&cbe_lun->options, "pblocksize"); | value = dnvlist_get_string(cbe_lun->options, "pblocksize", NULL); | ||||
if (value != NULL) | if (value != NULL) | ||||
ctl_expand_number(value, &ps); | ctl_expand_number(value, &ps); | ||||
value = ctl_get_opt(&cbe_lun->options, "pblockoffset"); | value = dnvlist_get_string(cbe_lun->options, "pblockoffset", NULL); | ||||
if (value != NULL) | if (value != NULL) | ||||
ctl_expand_number(value, &po); | ctl_expand_number(value, &po); | ||||
pss = ps / cbe_lun->blocksize; | pss = ps / cbe_lun->blocksize; | ||||
pos = po / cbe_lun->blocksize; | pos = po / cbe_lun->blocksize; | ||||
if ((pss > 0) && (pss * cbe_lun->blocksize == ps) && (pss >= pos) && | if ((pss > 0) && (pss * cbe_lun->blocksize == ps) && (pss >= pos) && | ||||
((pss & (pss - 1)) == 0) && (pos * cbe_lun->blocksize == po)) { | ((pss & (pss - 1)) == 0) && (pos * cbe_lun->blocksize == po)) { | ||||
cbe_lun->pblockexp = fls(pss) - 1; | cbe_lun->pblockexp = fls(pss) - 1; | ||||
cbe_lun->pblockoff = (pss - pos) % pss; | cbe_lun->pblockoff = (pss - pos) % pss; | ||||
} | } | ||||
value = ctl_get_opt(&cbe_lun->options, "ublocksize"); | value = dnvlist_get_string(cbe_lun->options, "ublocksize", NULL); | ||||
if (value != NULL) | if (value != NULL) | ||||
ctl_expand_number(value, &us); | ctl_expand_number(value, &us); | ||||
value = ctl_get_opt(&cbe_lun->options, "ublockoffset"); | value = dnvlist_get_string(cbe_lun->options, "ublockoffset", NULL); | ||||
if (value != NULL) | if (value != NULL) | ||||
ctl_expand_number(value, &uo); | ctl_expand_number(value, &uo); | ||||
uss = us / cbe_lun->blocksize; | uss = us / cbe_lun->blocksize; | ||||
uos = uo / cbe_lun->blocksize; | uos = uo / cbe_lun->blocksize; | ||||
if ((uss > 0) && (uss * cbe_lun->blocksize == us) && (uss >= uos) && | if ((uss > 0) && (uss * cbe_lun->blocksize == us) && (uss >= uos) && | ||||
((uss & (uss - 1)) == 0) && (uos * cbe_lun->blocksize == uo)) { | ((uss & (uss - 1)) == 0) && (uos * cbe_lun->blocksize == uo)) { | ||||
cbe_lun->ublockexp = fls(uss) - 1; | cbe_lun->ublockexp = fls(uss) - 1; | ||||
cbe_lun->ublockoff = (uss - uos) % uss; | cbe_lun->ublockoff = (uss - uos) % uss; | ||||
Show All 16 Lines | |||||
static int | static int | ||||
ctl_be_block_open_dev(struct ctl_be_block_lun *be_lun, struct ctl_lun_req *req) | ctl_be_block_open_dev(struct ctl_be_block_lun *be_lun, struct ctl_lun_req *req) | ||||
{ | { | ||||
struct ctl_be_lun *cbe_lun = &be_lun->cbe_lun; | struct ctl_be_lun *cbe_lun = &be_lun->cbe_lun; | ||||
struct ctl_lun_create_params *params; | struct ctl_lun_create_params *params; | ||||
struct cdevsw *csw; | struct cdevsw *csw; | ||||
struct cdev *dev; | struct cdev *dev; | ||||
char *value; | const char *value; | ||||
int error, atomic, maxio, ref, unmap, tmp; | int error, atomic, maxio, ref, unmap, tmp; | ||||
off_t ps, pss, po, pos, us, uss, uo, uos, otmp; | off_t ps, pss, po, pos, us, uss, uo, uos, otmp; | ||||
params = &be_lun->params; | params = &be_lun->params; | ||||
be_lun->dev_type = CTL_BE_BLOCK_DEV; | be_lun->dev_type = CTL_BE_BLOCK_DEV; | ||||
csw = devvn_refthread(be_lun->vn, &dev, &ref); | csw = devvn_refthread(be_lun->vn, &dev, &ref); | ||||
if (csw == NULL) | if (csw == NULL) | ||||
▲ Show 20 Lines • Show All 99 Lines • ▼ Show 20 Lines | else { | ||||
error = csw->d_ioctl(dev, DIOCGSTRIPEOFFSET, (caddr_t)&po, | error = csw->d_ioctl(dev, DIOCGSTRIPEOFFSET, (caddr_t)&po, | ||||
FREAD, curthread); | FREAD, curthread); | ||||
if (error) | if (error) | ||||
po = 0; | po = 0; | ||||
} | } | ||||
us = ps; | us = ps; | ||||
uo = po; | uo = po; | ||||
value = ctl_get_opt(&cbe_lun->options, "pblocksize"); | value = dnvlist_get_string(cbe_lun->options, "pblocksize", NULL); | ||||
if (value != NULL) | if (value != NULL) | ||||
ctl_expand_number(value, &ps); | ctl_expand_number(value, &ps); | ||||
value = ctl_get_opt(&cbe_lun->options, "pblockoffset"); | value = dnvlist_get_string(cbe_lun->options, "pblockoffset", NULL); | ||||
if (value != NULL) | if (value != NULL) | ||||
ctl_expand_number(value, &po); | ctl_expand_number(value, &po); | ||||
pss = ps / cbe_lun->blocksize; | pss = ps / cbe_lun->blocksize; | ||||
pos = po / cbe_lun->blocksize; | pos = po / cbe_lun->blocksize; | ||||
if ((pss > 0) && (pss * cbe_lun->blocksize == ps) && (pss >= pos) && | if ((pss > 0) && (pss * cbe_lun->blocksize == ps) && (pss >= pos) && | ||||
((pss & (pss - 1)) == 0) && (pos * cbe_lun->blocksize == po)) { | ((pss & (pss - 1)) == 0) && (pos * cbe_lun->blocksize == po)) { | ||||
cbe_lun->pblockexp = fls(pss) - 1; | cbe_lun->pblockexp = fls(pss) - 1; | ||||
cbe_lun->pblockoff = (pss - pos) % pss; | cbe_lun->pblockoff = (pss - pos) % pss; | ||||
} | } | ||||
value = ctl_get_opt(&cbe_lun->options, "ublocksize"); | value = dnvlist_get_string(cbe_lun->options, "ublocksize", NULL); | ||||
if (value != NULL) | if (value != NULL) | ||||
ctl_expand_number(value, &us); | ctl_expand_number(value, &us); | ||||
value = ctl_get_opt(&cbe_lun->options, "ublockoffset"); | value = dnvlist_get_string(cbe_lun->options, "ublockoffset", NULL); | ||||
if (value != NULL) | if (value != NULL) | ||||
ctl_expand_number(value, &uo); | ctl_expand_number(value, &uo); | ||||
uss = us / cbe_lun->blocksize; | uss = us / cbe_lun->blocksize; | ||||
uos = uo / cbe_lun->blocksize; | uos = uo / cbe_lun->blocksize; | ||||
if ((uss > 0) && (uss * cbe_lun->blocksize == us) && (uss >= uos) && | if ((uss > 0) && (uss * cbe_lun->blocksize == us) && (uss >= uos) && | ||||
((uss & (uss - 1)) == 0) && (uos * cbe_lun->blocksize == uo)) { | ((uss & (uss - 1)) == 0) && (uos * cbe_lun->blocksize == uo)) { | ||||
cbe_lun->ublockexp = fls(uss) - 1; | cbe_lun->ublockexp = fls(uss) - 1; | ||||
cbe_lun->ublockoff = (uss - uos) % uss; | cbe_lun->ublockoff = (uss - uos) % uss; | ||||
} | } | ||||
cbe_lun->atomicblock = atomic / cbe_lun->blocksize; | cbe_lun->atomicblock = atomic / cbe_lun->blocksize; | ||||
cbe_lun->opttxferlen = maxio / cbe_lun->blocksize; | cbe_lun->opttxferlen = maxio / cbe_lun->blocksize; | ||||
if (be_lun->dispatch == ctl_be_block_dispatch_zvol) { | if (be_lun->dispatch == ctl_be_block_dispatch_zvol) { | ||||
unmap = 1; | unmap = 1; | ||||
} else { | } else { | ||||
struct diocgattr_arg arg; | struct diocgattr_arg arg; | ||||
strlcpy(arg.name, "GEOM::candelete", sizeof(arg.name)); | strlcpy(arg.name, "GEOM::candelete", sizeof(arg.name)); | ||||
arg.len = sizeof(arg.value.i); | arg.len = sizeof(arg.value.i); | ||||
error = csw->d_ioctl(dev, DIOCGATTR, (caddr_t)&arg, FREAD, | error = csw->d_ioctl(dev, DIOCGATTR, (caddr_t)&arg, FREAD, | ||||
curthread); | curthread); | ||||
unmap = (error == 0) ? arg.value.i : 0; | unmap = (error == 0) ? arg.value.i : 0; | ||||
} | } | ||||
value = ctl_get_opt(&cbe_lun->options, "unmap"); | value = dnvlist_get_string(cbe_lun->options, "unmap", NULL); | ||||
if (value != NULL) | if (value != NULL) | ||||
unmap = (strcmp(value, "on") == 0); | unmap = (strcmp(value, "on") == 0); | ||||
if (unmap) | if (unmap) | ||||
cbe_lun->flags |= CTL_LUN_FLAG_UNMAP; | cbe_lun->flags |= CTL_LUN_FLAG_UNMAP; | ||||
else | else | ||||
cbe_lun->flags &= ~CTL_LUN_FLAG_UNMAP; | cbe_lun->flags &= ~CTL_LUN_FLAG_UNMAP; | ||||
dev_relthread(dev, ref); | dev_relthread(dev, ref); | ||||
Show All 33 Lines | ctl_be_block_close(struct ctl_be_block_lun *be_lun) | ||||
return (0); | return (0); | ||||
} | } | ||||
static int | static int | ||||
ctl_be_block_open(struct ctl_be_block_lun *be_lun, struct ctl_lun_req *req) | ctl_be_block_open(struct ctl_be_block_lun *be_lun, struct ctl_lun_req *req) | ||||
{ | { | ||||
struct ctl_be_lun *cbe_lun = &be_lun->cbe_lun; | struct ctl_be_lun *cbe_lun = &be_lun->cbe_lun; | ||||
struct nameidata nd; | struct nameidata nd; | ||||
char *value; | const char *value; | ||||
int error, flags; | int error, flags; | ||||
error = 0; | error = 0; | ||||
if (rootvnode == NULL) { | if (rootvnode == NULL) { | ||||
snprintf(req->error_str, sizeof(req->error_str), | snprintf(req->error_str, sizeof(req->error_str), | ||||
"Root filesystem is not mounted"); | "Root filesystem is not mounted"); | ||||
return (1); | return (1); | ||||
} | } | ||||
pwd_ensure_dirs(); | pwd_ensure_dirs(); | ||||
value = ctl_get_opt(&cbe_lun->options, "file"); | value = dnvlist_get_string(cbe_lun->options, "file", NULL); | ||||
if (value == NULL) { | if (value == NULL) { | ||||
snprintf(req->error_str, sizeof(req->error_str), | snprintf(req->error_str, sizeof(req->error_str), | ||||
"no file argument specified"); | "no file argument specified"); | ||||
return (1); | return (1); | ||||
} | } | ||||
free(be_lun->dev_path, M_CTLBLK); | free(be_lun->dev_path, M_CTLBLK); | ||||
be_lun->dev_path = strdup(value, M_CTLBLK); | be_lun->dev_path = strdup(value, M_CTLBLK); | ||||
flags = FREAD; | flags = FREAD; | ||||
value = ctl_get_opt(&cbe_lun->options, "readonly"); | value = dnvlist_get_string(cbe_lun->options, "readonly", NULL); | ||||
if (value != NULL) { | if (value != NULL) { | ||||
if (strcmp(value, "on") != 0) | if (strcmp(value, "on") != 0) | ||||
flags |= FWRITE; | flags |= FWRITE; | ||||
} else if (cbe_lun->lun_type == T_DIRECT) | } else if (cbe_lun->lun_type == T_DIRECT) | ||||
flags |= FWRITE; | flags |= FWRITE; | ||||
again: | again: | ||||
NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, be_lun->dev_path, curthread); | NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, be_lun->dev_path, curthread); | ||||
▲ Show 20 Lines • Show All 42 Lines • ▼ Show 20 Lines | again: | ||||
} | } | ||||
VOP_UNLOCK(be_lun->vn, 0); | VOP_UNLOCK(be_lun->vn, 0); | ||||
if (error != 0) | if (error != 0) | ||||
ctl_be_block_close(be_lun); | ctl_be_block_close(be_lun); | ||||
cbe_lun->serseq = CTL_LUN_SERSEQ_OFF; | cbe_lun->serseq = CTL_LUN_SERSEQ_OFF; | ||||
if (be_lun->dispatch != ctl_be_block_dispatch_dev) | if (be_lun->dispatch != ctl_be_block_dispatch_dev) | ||||
cbe_lun->serseq = CTL_LUN_SERSEQ_READ; | cbe_lun->serseq = CTL_LUN_SERSEQ_READ; | ||||
value = ctl_get_opt(&cbe_lun->options, "serseq"); | value = dnvlist_get_string(cbe_lun->options, "serseq", NULL); | ||||
if (value != NULL && strcmp(value, "on") == 0) | if (value != NULL && strcmp(value, "on") == 0) | ||||
cbe_lun->serseq = CTL_LUN_SERSEQ_ON; | cbe_lun->serseq = CTL_LUN_SERSEQ_ON; | ||||
else if (value != NULL && strcmp(value, "read") == 0) | else if (value != NULL && strcmp(value, "read") == 0) | ||||
cbe_lun->serseq = CTL_LUN_SERSEQ_READ; | cbe_lun->serseq = CTL_LUN_SERSEQ_READ; | ||||
else if (value != NULL && strcmp(value, "off") == 0) | else if (value != NULL && strcmp(value, "off") == 0) | ||||
cbe_lun->serseq = CTL_LUN_SERSEQ_OFF; | cbe_lun->serseq = CTL_LUN_SERSEQ_OFF; | ||||
return (0); | return (0); | ||||
} | } | ||||
static int | static int | ||||
ctl_be_block_create(struct ctl_be_block_softc *softc, struct ctl_lun_req *req) | ctl_be_block_create(struct ctl_be_block_softc *softc, struct ctl_lun_req *req) | ||||
{ | { | ||||
struct ctl_be_lun *cbe_lun; | struct ctl_be_lun *cbe_lun; | ||||
struct ctl_be_block_lun *be_lun; | struct ctl_be_block_lun *be_lun; | ||||
struct ctl_lun_create_params *params; | struct ctl_lun_create_params *params; | ||||
char num_thread_str[16]; | char num_thread_str[16]; | ||||
char tmpstr[32]; | char tmpstr[32]; | ||||
char *value; | const char *value; | ||||
int retval, num_threads; | int retval, num_threads; | ||||
int tmp_num_threads; | int tmp_num_threads; | ||||
params = &req->reqdata.create; | params = &req->reqdata.create; | ||||
retval = 0; | retval = 0; | ||||
req->status = CTL_LUN_OK; | req->status = CTL_LUN_OK; | ||||
be_lun = malloc(sizeof(*be_lun), M_CTLBLK, M_ZERO | M_WAITOK); | be_lun = malloc(sizeof(*be_lun), M_CTLBLK, M_ZERO | M_WAITOK); | ||||
cbe_lun = &be_lun->cbe_lun; | cbe_lun = &be_lun->cbe_lun; | ||||
cbe_lun->be_lun = be_lun; | cbe_lun->be_lun = be_lun; | ||||
be_lun->params = req->reqdata.create; | be_lun->params = req->reqdata.create; | ||||
be_lun->softc = softc; | be_lun->softc = softc; | ||||
STAILQ_INIT(&be_lun->input_queue); | STAILQ_INIT(&be_lun->input_queue); | ||||
STAILQ_INIT(&be_lun->config_read_queue); | STAILQ_INIT(&be_lun->config_read_queue); | ||||
STAILQ_INIT(&be_lun->config_write_queue); | STAILQ_INIT(&be_lun->config_write_queue); | ||||
STAILQ_INIT(&be_lun->datamove_queue); | STAILQ_INIT(&be_lun->datamove_queue); | ||||
sprintf(be_lun->lunname, "cblk%d", softc->num_luns); | sprintf(be_lun->lunname, "cblk%d", softc->num_luns); | ||||
mtx_init(&be_lun->io_lock, "cblk io lock", NULL, MTX_DEF); | mtx_init(&be_lun->io_lock, "cblk io lock", NULL, MTX_DEF); | ||||
mtx_init(&be_lun->queue_lock, "cblk queue lock", NULL, MTX_DEF); | mtx_init(&be_lun->queue_lock, "cblk queue lock", NULL, MTX_DEF); | ||||
ctl_init_opts(&cbe_lun->options, | cbe_lun->options = nvlist_clone(req->args_nvl); | ||||
req->num_be_args, req->kern_be_args); | |||||
be_lun->lun_zone = uma_zcreate(be_lun->lunname, CTLBLK_MAX_SEG, | be_lun->lun_zone = uma_zcreate(be_lun->lunname, CTLBLK_MAX_SEG, | ||||
NULL, NULL, NULL, NULL, /*align*/ 0, /*flags*/0); | NULL, NULL, NULL, NULL, /*align*/ 0, /*flags*/0); | ||||
if (be_lun->lun_zone == NULL) { | if (be_lun->lun_zone == NULL) { | ||||
snprintf(req->error_str, sizeof(req->error_str), | snprintf(req->error_str, sizeof(req->error_str), | ||||
"error allocating UMA zone"); | "error allocating UMA zone"); | ||||
goto bailout_error; | goto bailout_error; | ||||
} | } | ||||
if (params->flags & CTL_LUN_FLAG_DEV_TYPE) | if (params->flags & CTL_LUN_FLAG_DEV_TYPE) | ||||
cbe_lun->lun_type = params->device_type; | cbe_lun->lun_type = params->device_type; | ||||
else | else | ||||
cbe_lun->lun_type = T_DIRECT; | cbe_lun->lun_type = T_DIRECT; | ||||
be_lun->flags = CTL_BE_BLOCK_LUN_UNCONFIGURED; | be_lun->flags = CTL_BE_BLOCK_LUN_UNCONFIGURED; | ||||
cbe_lun->flags = 0; | cbe_lun->flags = 0; | ||||
value = ctl_get_opt(&cbe_lun->options, "ha_role"); | value = dnvlist_get_string(cbe_lun->options, "ha_role", NULL); | ||||
if (value != NULL) { | if (value != NULL) { | ||||
if (strcmp(value, "primary") == 0) | if (strcmp(value, "primary") == 0) | ||||
cbe_lun->flags |= CTL_LUN_FLAG_PRIMARY; | cbe_lun->flags |= CTL_LUN_FLAG_PRIMARY; | ||||
} else if (control_softc->flags & CTL_FLAG_ACTIVE_SHELF) | } else if (control_softc->flags & CTL_FLAG_ACTIVE_SHELF) | ||||
cbe_lun->flags |= CTL_LUN_FLAG_PRIMARY; | cbe_lun->flags |= CTL_LUN_FLAG_PRIMARY; | ||||
if (cbe_lun->lun_type == T_DIRECT || | if (cbe_lun->lun_type == T_DIRECT || | ||||
cbe_lun->lun_type == T_CDROM) { | cbe_lun->lun_type == T_CDROM) { | ||||
Show All 16 Lines | if ((cbe_lun->flags & CTL_LUN_FLAG_PRIMARY) || | ||||
req->status = CTL_LUN_WARNING; | req->status = CTL_LUN_WARNING; | ||||
} | } | ||||
} | } | ||||
num_threads = cbb_num_threads; | num_threads = cbb_num_threads; | ||||
} else { | } else { | ||||
num_threads = 1; | num_threads = 1; | ||||
} | } | ||||
value = ctl_get_opt(&cbe_lun->options, "num_threads"); | value = dnvlist_get_string(cbe_lun->options, "num_threads", NULL); | ||||
if (value != NULL) { | if (value != NULL) { | ||||
tmp_num_threads = strtol(value, NULL, 0); | tmp_num_threads = strtol(value, NULL, 0); | ||||
/* | /* | ||||
* We don't let the user specify less than one | * We don't let the user specify less than one | ||||
* thread, but hope he's clueful enough not to | * thread, but hope he's clueful enough not to | ||||
* specify 1000 threads. | * specify 1000 threads. | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 148 Lines • ▼ Show 20 Lines | bailout_error: | ||||
if (be_lun->io_taskqueue != NULL) | if (be_lun->io_taskqueue != NULL) | ||||
taskqueue_free(be_lun->io_taskqueue); | taskqueue_free(be_lun->io_taskqueue); | ||||
ctl_be_block_close(be_lun); | ctl_be_block_close(be_lun); | ||||
if (be_lun->dev_path != NULL) | if (be_lun->dev_path != NULL) | ||||
free(be_lun->dev_path, M_CTLBLK); | free(be_lun->dev_path, M_CTLBLK); | ||||
if (be_lun->lun_zone != NULL) | if (be_lun->lun_zone != NULL) | ||||
uma_zdestroy(be_lun->lun_zone); | uma_zdestroy(be_lun->lun_zone); | ||||
ctl_free_opts(&cbe_lun->options); | nvlist_destroy(cbe_lun->options); | ||||
mtx_destroy(&be_lun->queue_lock); | mtx_destroy(&be_lun->queue_lock); | ||||
mtx_destroy(&be_lun->io_lock); | mtx_destroy(&be_lun->io_lock); | ||||
free(be_lun, M_CTLBLK); | free(be_lun, M_CTLBLK); | ||||
return (retval); | return (retval); | ||||
} | } | ||||
static int | static int | ||||
▲ Show 20 Lines • Show All 67 Lines • ▼ Show 20 Lines | ctl_be_block_rm(struct ctl_be_block_softc *softc, struct ctl_lun_req *req) | ||||
taskqueue_drain_all(be_lun->io_taskqueue); | taskqueue_drain_all(be_lun->io_taskqueue); | ||||
taskqueue_free(be_lun->io_taskqueue); | taskqueue_free(be_lun->io_taskqueue); | ||||
if (be_lun->disk_stats != NULL) | if (be_lun->disk_stats != NULL) | ||||
devstat_remove_entry(be_lun->disk_stats); | devstat_remove_entry(be_lun->disk_stats); | ||||
uma_zdestroy(be_lun->lun_zone); | uma_zdestroy(be_lun->lun_zone); | ||||
ctl_free_opts(&cbe_lun->options); | nvlist_destroy(cbe_lun->options); | ||||
free(be_lun->dev_path, M_CTLBLK); | free(be_lun->dev_path, M_CTLBLK); | ||||
mtx_destroy(&be_lun->queue_lock); | mtx_destroy(&be_lun->queue_lock); | ||||
mtx_destroy(&be_lun->io_lock); | mtx_destroy(&be_lun->io_lock); | ||||
free(be_lun, M_CTLBLK); | free(be_lun, M_CTLBLK); | ||||
req->status = CTL_LUN_OK; | req->status = CTL_LUN_OK; | ||||
return (0); | return (0); | ||||
bailout_error: | bailout_error: | ||||
req->status = CTL_LUN_ERROR; | req->status = CTL_LUN_ERROR; | ||||
return (0); | return (0); | ||||
} | } | ||||
static int | static int | ||||
ctl_be_block_modify(struct ctl_be_block_softc *softc, struct ctl_lun_req *req) | ctl_be_block_modify(struct ctl_be_block_softc *softc, struct ctl_lun_req *req) | ||||
{ | { | ||||
struct ctl_lun_modify_params *params; | struct ctl_lun_modify_params *params; | ||||
struct ctl_be_block_lun *be_lun; | struct ctl_be_block_lun *be_lun; | ||||
struct ctl_be_lun *cbe_lun; | struct ctl_be_lun *cbe_lun; | ||||
char *value; | const char *value; | ||||
uint64_t oldsize; | uint64_t oldsize; | ||||
int error, wasprim; | int error, wasprim; | ||||
params = &req->reqdata.modify; | params = &req->reqdata.modify; | ||||
mtx_lock(&softc->lock); | mtx_lock(&softc->lock); | ||||
STAILQ_FOREACH(be_lun, &softc->lun_list, links) { | STAILQ_FOREACH(be_lun, &softc->lun_list, links) { | ||||
if (be_lun->cbe_lun.lun_id == params->lun_id) | if (be_lun->cbe_lun.lun_id == params->lun_id) | ||||
break; | break; | ||||
} | } | ||||
mtx_unlock(&softc->lock); | mtx_unlock(&softc->lock); | ||||
if (be_lun == NULL) { | if (be_lun == NULL) { | ||||
snprintf(req->error_str, sizeof(req->error_str), | snprintf(req->error_str, sizeof(req->error_str), | ||||
"LUN %u is not managed by the block backend", | "LUN %u is not managed by the block backend", | ||||
params->lun_id); | params->lun_id); | ||||
goto bailout_error; | goto bailout_error; | ||||
} | } | ||||
cbe_lun = &be_lun->cbe_lun; | cbe_lun = &be_lun->cbe_lun; | ||||
if (params->lun_size_bytes != 0) | if (params->lun_size_bytes != 0) | ||||
be_lun->params.lun_size_bytes = params->lun_size_bytes; | be_lun->params.lun_size_bytes = params->lun_size_bytes; | ||||
ctl_update_opts(&cbe_lun->options, req->num_be_args, req->kern_be_args); | |||||
nvlist_destroy(cbe_lun->options); | |||||
cbe_lun->options = nvlist_clone(req->args_nvl); | |||||
wasprim = (cbe_lun->flags & CTL_LUN_FLAG_PRIMARY); | wasprim = (cbe_lun->flags & CTL_LUN_FLAG_PRIMARY); | ||||
value = ctl_get_opt(&cbe_lun->options, "ha_role"); | value = dnvlist_get_string(cbe_lun->options, "ha_role", NULL); | ||||
if (value != NULL) { | if (value != NULL) { | ||||
if (strcmp(value, "primary") == 0) | if (strcmp(value, "primary") == 0) | ||||
cbe_lun->flags |= CTL_LUN_FLAG_PRIMARY; | cbe_lun->flags |= CTL_LUN_FLAG_PRIMARY; | ||||
else | else | ||||
cbe_lun->flags &= ~CTL_LUN_FLAG_PRIMARY; | cbe_lun->flags &= ~CTL_LUN_FLAG_PRIMARY; | ||||
} else if (control_softc->flags & CTL_FLAG_ACTIVE_SHELF) | } else if (control_softc->flags & CTL_FLAG_ACTIVE_SHELF) | ||||
cbe_lun->flags |= CTL_LUN_FLAG_PRIMARY; | cbe_lun->flags |= CTL_LUN_FLAG_PRIMARY; | ||||
else | else | ||||
▲ Show 20 Lines • Show All 301 Lines • Show Last 20 Lines |