CTL changes required for iSCSI target, most notably LUN remapping
and a mechanism to allow CTL frontends for retrieving LUN options. Reviewed by: ken (earlier version)
This commit is contained in:
parent
83b6a67e66
commit
81a2151d5c
@ -894,8 +894,13 @@ ctl_isc_event_handler(ctl_ha_channel channel, ctl_ha_event event, int param)
|
||||
struct ctl_lun *lun;
|
||||
struct ctl_page_index *page_index;
|
||||
struct copan_aps_subpage *current_sp;
|
||||
uint32_t targ_lun;
|
||||
|
||||
lun = ctl_softc->ctl_luns[msg_info.hdr.nexus.targ_lun];
|
||||
targ_lun = msg_info.hdr.nexus.targ_lun;
|
||||
if (msg_info.hdr.nexus.lun_map_fn != NULL)
|
||||
targ_lun = msg_info.hdr.nexus.lun_map_fn(msg_info.hdr.nexus.lun_map_arg, targ_lun);
|
||||
|
||||
lun = ctl_softc->ctl_luns[targ_lun];
|
||||
page_index = &lun->mode_pages.index[index_to_aps_page];
|
||||
current_sp = (struct copan_aps_subpage *)
|
||||
(page_index->page_data +
|
||||
@ -1098,6 +1103,7 @@ ctl_init(void)
|
||||
mtx_unlock(&softc->ctl_lock);
|
||||
return (error);
|
||||
}
|
||||
if (bootverbose)
|
||||
printf("ctl: CAM Target Layer loaded\n");
|
||||
|
||||
/*
|
||||
@ -1194,6 +1200,7 @@ ctl_shutdown(void)
|
||||
free(control_softc, M_DEVBUF);
|
||||
control_softc = NULL;
|
||||
|
||||
if (bootverbose)
|
||||
printf("ctl: CAM Target Layer unloaded\n");
|
||||
}
|
||||
|
||||
@ -1678,12 +1685,16 @@ ctl_serialize_other_sc_cmd(struct ctl_scsiio *ctsio, int have_lock)
|
||||
union ctl_ha_msg msg_info;
|
||||
struct ctl_lun *lun;
|
||||
int retval = 0;
|
||||
uint32_t targ_lun;
|
||||
|
||||
ctl_softc = control_softc;
|
||||
if (have_lock == 0)
|
||||
mtx_lock(&ctl_softc->ctl_lock);
|
||||
|
||||
lun = ctl_softc->ctl_luns[ctsio->io_hdr.nexus.targ_lun];
|
||||
targ_lun = ctsio->io_hdr.nexus.targ_lun;
|
||||
if (ctsio->io_hdr.nexus.lun_map_fn != NULL)
|
||||
targ_lun = ctsio->io_hdr.nexus.lun_map_fn(ctsio->io_hdr.nexus.lun_map_arg, targ_lun);
|
||||
lun = ctl_softc->ctl_luns[targ_lun];
|
||||
if (lun==NULL)
|
||||
{
|
||||
/*
|
||||
@ -2980,6 +2991,7 @@ ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
|
||||
struct sbuf *sb;
|
||||
struct ctl_lun *lun;
|
||||
struct ctl_lun_list *list;
|
||||
struct ctl_be_lun_option *opt;
|
||||
|
||||
list = (struct ctl_lun_list *)addr;
|
||||
|
||||
@ -3097,17 +3109,16 @@ ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
|
||||
if (retval != 0)
|
||||
break;
|
||||
|
||||
if (lun->backend->lun_info == NULL) {
|
||||
retval = sbuf_printf(sb, "</lun>\n");
|
||||
if (lun->backend->lun_info != NULL) {
|
||||
retval = lun->backend->lun_info(lun->be_lun->be_lun, sb);
|
||||
if (retval != 0)
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
|
||||
retval =lun->backend->lun_info(lun->be_lun->be_lun, sb);
|
||||
|
||||
STAILQ_FOREACH(opt, &lun->be_lun->options, links) {
|
||||
retval = sbuf_printf(sb, "<%s>%s</%s>", opt->name, opt->value, opt->name);
|
||||
if (retval != 0)
|
||||
break;
|
||||
}
|
||||
|
||||
retval = sbuf_printf(sb, "</lun>\n");
|
||||
|
||||
@ -4432,9 +4443,14 @@ ctl_free_lun(struct ctl_lun *lun)
|
||||
*/
|
||||
for (io = (union ctl_io *)STAILQ_FIRST(&softc->rtr_queue); io != NULL;
|
||||
io = next_io) {
|
||||
uint32_t targ_lun;
|
||||
|
||||
next_io = (union ctl_io *)STAILQ_NEXT(&io->io_hdr, links);
|
||||
targ_lun = io->io_hdr.nexus.targ_lun;
|
||||
if (io->io_hdr.nexus.lun_map_fn != NULL)
|
||||
targ_lun = io->io_hdr.nexus.lun_map_fn(io->io_hdr.nexus.lun_map_arg, targ_lun);
|
||||
if ((io->io_hdr.nexus.targ_target.id == lun->target.id)
|
||||
&& (io->io_hdr.nexus.targ_lun == lun->lun))
|
||||
&& (targ_lun == lun->lun))
|
||||
STAILQ_REMOVE(&softc->rtr_queue, &io->io_hdr,
|
||||
ctl_io_hdr, links);
|
||||
}
|
||||
@ -8247,12 +8263,16 @@ ctl_hndl_per_res_out_on_other_sc(union ctl_ha_msg *msg)
|
||||
struct ctl_lun *lun;
|
||||
struct ctl_softc *softc;
|
||||
int i;
|
||||
uint32_t targ_lun;
|
||||
|
||||
softc = control_softc;
|
||||
|
||||
mtx_lock(&softc->ctl_lock);
|
||||
|
||||
lun = softc->ctl_luns[msg->hdr.nexus.targ_lun];
|
||||
targ_lun = msg->hdr.nexus.targ_lun;
|
||||
if (msg->hdr.nexus.lun_map_fn != NULL)
|
||||
targ_lun = msg->hdr.nexus.lun_map_fn(msg->hdr.nexus.lun_map_arg, targ_lun);
|
||||
lun = softc->ctl_luns[targ_lun];
|
||||
switch(msg->pr.pr_info.action) {
|
||||
case CTL_PR_REG_KEY:
|
||||
if (!lun->per_res[msg->pr.pr_info.residx].registered) {
|
||||
@ -8601,7 +8621,7 @@ ctl_report_luns(struct ctl_scsiio *ctsio)
|
||||
int num_luns, retval;
|
||||
uint32_t alloc_len, lun_datalen;
|
||||
int num_filled, well_known;
|
||||
uint32_t initidx;
|
||||
uint32_t initidx, targ_lun_id, lun_id;
|
||||
|
||||
retval = CTL_RETVAL_COMPLETE;
|
||||
well_known = 0;
|
||||
@ -8662,63 +8682,47 @@ ctl_report_luns(struct ctl_scsiio *ctsio)
|
||||
lun_data = (struct scsi_report_luns_data *)ctsio->kern_data_ptr;
|
||||
ctsio->kern_sg_entries = 0;
|
||||
|
||||
if (lun_datalen < alloc_len) {
|
||||
ctsio->residual = alloc_len - lun_datalen;
|
||||
ctsio->kern_data_len = lun_datalen;
|
||||
ctsio->kern_total_len = lun_datalen;
|
||||
} else {
|
||||
ctsio->residual = 0;
|
||||
ctsio->kern_data_len = alloc_len;
|
||||
ctsio->kern_total_len = alloc_len;
|
||||
}
|
||||
ctsio->kern_data_resid = 0;
|
||||
ctsio->kern_rel_offset = 0;
|
||||
ctsio->kern_sg_entries = 0;
|
||||
|
||||
initidx = ctl_get_initindex(&ctsio->io_hdr.nexus);
|
||||
|
||||
/*
|
||||
* We set this to the actual data length, regardless of how much
|
||||
* space we actually have to return results. If the user looks at
|
||||
* this value, he'll know whether or not he allocated enough space
|
||||
* and reissue the command if necessary. We don't support well
|
||||
* known logical units, so if the user asks for that, return none.
|
||||
*/
|
||||
scsi_ulto4b(lun_datalen - 8, lun_data->length);
|
||||
|
||||
mtx_lock(&control_softc->ctl_lock);
|
||||
for (num_filled = 0, lun = STAILQ_FIRST(&control_softc->lun_list);
|
||||
(lun != NULL) && (num_filled < num_luns);
|
||||
lun = STAILQ_NEXT(lun, links)) {
|
||||
for (targ_lun_id = 0, num_filled = 0; targ_lun_id < CTL_MAX_LUNS && num_filled < num_luns; targ_lun_id++) {
|
||||
lun_id = targ_lun_id;
|
||||
if (ctsio->io_hdr.nexus.lun_map_fn != NULL)
|
||||
lun_id = ctsio->io_hdr.nexus.lun_map_fn(ctsio->io_hdr.nexus.lun_map_arg, lun_id);
|
||||
if (lun_id >= CTL_MAX_LUNS)
|
||||
continue;
|
||||
lun = control_softc->ctl_luns[lun_id];
|
||||
if (lun == NULL)
|
||||
continue;
|
||||
|
||||
if (lun->lun <= 0xff) {
|
||||
if (targ_lun_id <= 0xff) {
|
||||
/*
|
||||
* Peripheral addressing method, bus number 0.
|
||||
*/
|
||||
lun_data->luns[num_filled].lundata[0] =
|
||||
RPL_LUNDATA_ATYP_PERIPH;
|
||||
lun_data->luns[num_filled].lundata[1] = lun->lun;
|
||||
lun_data->luns[num_filled].lundata[1] = targ_lun_id;
|
||||
num_filled++;
|
||||
} else if (lun->lun <= 0x3fff) {
|
||||
} else if (targ_lun_id <= 0x3fff) {
|
||||
/*
|
||||
* Flat addressing method.
|
||||
*/
|
||||
lun_data->luns[num_filled].lundata[0] =
|
||||
RPL_LUNDATA_ATYP_FLAT |
|
||||
(lun->lun & RPL_LUNDATA_FLAT_LUN_MASK);
|
||||
(targ_lun_id & RPL_LUNDATA_FLAT_LUN_MASK);
|
||||
#ifdef OLDCTLHEADERS
|
||||
(SRLD_ADDR_FLAT << SRLD_ADDR_SHIFT) |
|
||||
(lun->lun & SRLD_BUS_LUN_MASK);
|
||||
(targ_lun_id & SRLD_BUS_LUN_MASK);
|
||||
#endif
|
||||
lun_data->luns[num_filled].lundata[1] =
|
||||
#ifdef OLDCTLHEADERS
|
||||
lun->lun >> SRLD_BUS_LUN_BITS;
|
||||
targ_lun_id >> SRLD_BUS_LUN_BITS;
|
||||
#endif
|
||||
lun->lun >> RPL_LUNDATA_FLAT_LUN_BITS;
|
||||
targ_lun_id >> RPL_LUNDATA_FLAT_LUN_BITS;
|
||||
num_filled++;
|
||||
} else {
|
||||
printf("ctl_report_luns: bogus LUN number %jd, "
|
||||
"skipping\n", (intmax_t)lun->lun);
|
||||
"skipping\n", (intmax_t)targ_lun_id);
|
||||
}
|
||||
/*
|
||||
* According to SPC-3, rev 14 section 6.21:
|
||||
@ -8742,6 +8746,35 @@ ctl_report_luns(struct ctl_scsiio *ctsio)
|
||||
}
|
||||
mtx_unlock(&control_softc->ctl_lock);
|
||||
|
||||
/*
|
||||
* It's quite possible that we've returned fewer LUNs than we allocated
|
||||
* space for. Trim it.
|
||||
*/
|
||||
lun_datalen = sizeof(*lun_data) +
|
||||
(num_filled * sizeof(struct scsi_report_luns_lundata));
|
||||
|
||||
if (lun_datalen < alloc_len) {
|
||||
ctsio->residual = alloc_len - lun_datalen;
|
||||
ctsio->kern_data_len = lun_datalen;
|
||||
ctsio->kern_total_len = lun_datalen;
|
||||
} else {
|
||||
ctsio->residual = 0;
|
||||
ctsio->kern_data_len = alloc_len;
|
||||
ctsio->kern_total_len = alloc_len;
|
||||
}
|
||||
ctsio->kern_data_resid = 0;
|
||||
ctsio->kern_rel_offset = 0;
|
||||
ctsio->kern_sg_entries = 0;
|
||||
|
||||
/*
|
||||
* We set this to the actual data length, regardless of how much
|
||||
* space we actually have to return results. If the user looks at
|
||||
* this value, he'll know whether or not he allocated enough space
|
||||
* and reissue the command if necessary. We don't support well
|
||||
* known logical units, so if the user asks for that, return none.
|
||||
*/
|
||||
scsi_ulto4b(lun_datalen - 8, lun_data->length);
|
||||
|
||||
/*
|
||||
* We can only return SCSI_STATUS_CHECK_COND when we can't satisfy
|
||||
* this request.
|
||||
@ -9077,6 +9110,14 @@ ctl_inquiry_evpd_devid(struct ctl_scsiio *ctsio, int alloc_len)
|
||||
int devid_len;
|
||||
|
||||
ctl_softc = control_softc;
|
||||
|
||||
mtx_lock(&ctl_softc->ctl_lock);
|
||||
fe = ctl_softc->ctl_ports[ctl_port_idx(ctsio->io_hdr.nexus.targ_port)];
|
||||
mtx_unlock(&ctl_softc->ctl_lock);
|
||||
|
||||
if (fe->devid != NULL)
|
||||
return ((fe->devid)(ctsio, alloc_len));
|
||||
|
||||
lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
|
||||
|
||||
devid_len = sizeof(struct scsi_vpd_device_id) +
|
||||
@ -9130,8 +9171,6 @@ ctl_inquiry_evpd_devid(struct ctl_scsiio *ctsio, int alloc_len)
|
||||
|
||||
mtx_lock(&ctl_softc->ctl_lock);
|
||||
|
||||
fe = ctl_softc->ctl_ports[ctl_port_idx(ctsio->io_hdr.nexus.targ_port)];
|
||||
|
||||
/*
|
||||
* For Fibre channel,
|
||||
*/
|
||||
@ -10350,7 +10389,7 @@ ctl_scsiio_precheck(struct ctl_softc *ctl_softc, struct ctl_scsiio *ctsio)
|
||||
struct ctl_lun *lun;
|
||||
struct ctl_cmd_entry *entry;
|
||||
uint8_t opcode;
|
||||
uint32_t initidx;
|
||||
uint32_t initidx, targ_lun;
|
||||
int retval;
|
||||
|
||||
retval = 0;
|
||||
@ -10361,9 +10400,12 @@ ctl_scsiio_precheck(struct ctl_softc *ctl_softc, struct ctl_scsiio *ctsio)
|
||||
|
||||
mtx_lock(&ctl_softc->ctl_lock);
|
||||
|
||||
if ((ctsio->io_hdr.nexus.targ_lun < CTL_MAX_LUNS)
|
||||
&& (ctl_softc->ctl_luns[ctsio->io_hdr.nexus.targ_lun] != NULL)) {
|
||||
lun = ctl_softc->ctl_luns[ctsio->io_hdr.nexus.targ_lun];
|
||||
targ_lun = ctsio->io_hdr.nexus.targ_lun;
|
||||
if (ctsio->io_hdr.nexus.lun_map_fn != NULL)
|
||||
targ_lun = ctsio->io_hdr.nexus.lun_map_fn(ctsio->io_hdr.nexus.lun_map_arg, targ_lun);
|
||||
if ((targ_lun < CTL_MAX_LUNS)
|
||||
&& (ctl_softc->ctl_luns[targ_lun] != NULL)) {
|
||||
lun = ctl_softc->ctl_luns[targ_lun];
|
||||
/*
|
||||
* If the LUN is invalid, pretend that it doesn't exist.
|
||||
* It will go away as soon as all pending I/O has been
|
||||
@ -10403,6 +10445,7 @@ ctl_scsiio_precheck(struct ctl_softc *ctl_softc, struct ctl_scsiio *ctsio)
|
||||
ctl_set_unsupported_lun(ctsio);
|
||||
mtx_unlock(&ctl_softc->ctl_lock);
|
||||
ctl_done((union ctl_io *)ctsio);
|
||||
CTL_DEBUG_PRINT(("ctl_scsiio_precheck: bailing out due to invalid LUN\n"));
|
||||
goto bailout;
|
||||
} else {
|
||||
/*
|
||||
@ -10769,6 +10812,7 @@ ctl_abort_task(union ctl_io *io)
|
||||
char printbuf[128];
|
||||
#endif
|
||||
int found;
|
||||
uint32_t targ_lun;
|
||||
|
||||
ctl_softc = control_softc;
|
||||
found = 0;
|
||||
@ -10776,9 +10820,12 @@ ctl_abort_task(union ctl_io *io)
|
||||
/*
|
||||
* Look up the LUN.
|
||||
*/
|
||||
if ((io->io_hdr.nexus.targ_lun < CTL_MAX_LUNS)
|
||||
&& (ctl_softc->ctl_luns[io->io_hdr.nexus.targ_lun] != NULL))
|
||||
lun = ctl_softc->ctl_luns[io->io_hdr.nexus.targ_lun];
|
||||
targ_lun = io->io_hdr.nexus.targ_lun;
|
||||
if (io->io_hdr.nexus.lun_map_fn != NULL)
|
||||
targ_lun = io->io_hdr.nexus.lun_map_fn(io->io_hdr.nexus.lun_map_arg, targ_lun);
|
||||
if ((targ_lun < CTL_MAX_LUNS)
|
||||
&& (ctl_softc->ctl_luns[targ_lun] != NULL))
|
||||
lun = ctl_softc->ctl_luns[targ_lun];
|
||||
else
|
||||
goto bailout;
|
||||
|
||||
@ -10968,6 +11015,8 @@ ctl_run_task_queue(struct ctl_softc *ctl_softc)
|
||||
int retval;
|
||||
|
||||
targ_lun = io->io_hdr.nexus.targ_lun;
|
||||
if (io->io_hdr.nexus.lun_map_fn != NULL)
|
||||
targ_lun = io->io_hdr.nexus.lun_map_fn(io->io_hdr.nexus.lun_map_arg, targ_lun);
|
||||
|
||||
if ((targ_lun < CTL_MAX_LUNS)
|
||||
&& (ctl_softc->ctl_luns[targ_lun] != NULL))
|
||||
@ -11042,7 +11091,7 @@ ctl_run_task_queue(struct ctl_softc *ctl_softc)
|
||||
(uintmax_t)io->io_hdr.nexus.initid.id,
|
||||
io->io_hdr.nexus.targ_port,
|
||||
(uintmax_t)io->io_hdr.nexus.targ_target.id,
|
||||
io->io_hdr.nexus.targ_lun,
|
||||
io->io_hdr.nexus.targ_lun /* XXX */,
|
||||
(io->io_hdr.io_type == CTL_IO_TASK) ?
|
||||
io->taskio.tag_num : io->scsiio.tag_num);
|
||||
STAILQ_REMOVE(&ctl_softc->task_queue, &io->io_hdr,
|
||||
@ -11066,10 +11115,14 @@ ctl_handle_isc(union ctl_io *io)
|
||||
int free_io;
|
||||
struct ctl_lun *lun;
|
||||
struct ctl_softc *ctl_softc;
|
||||
uint32_t targ_lun;
|
||||
|
||||
ctl_softc = control_softc;
|
||||
|
||||
lun = ctl_softc->ctl_luns[io->io_hdr.nexus.targ_lun];
|
||||
targ_lun = io->io_hdr.nexus.targ_lun;
|
||||
if (io->io_hdr.nexus.lun_map_fn != NULL)
|
||||
targ_lun = io->io_hdr.nexus.lun_map_fn(io->io_hdr.nexus.lun_map_arg, targ_lun);
|
||||
lun = ctl_softc->ctl_luns[targ_lun];
|
||||
|
||||
switch (io->io_hdr.msg_type) {
|
||||
case CTL_MSG_SERIALIZE:
|
||||
@ -12625,7 +12678,7 @@ ctl_queue_sense(union ctl_io *io)
|
||||
{
|
||||
struct ctl_lun *lun;
|
||||
struct ctl_softc *ctl_softc;
|
||||
uint32_t initidx;
|
||||
uint32_t initidx, targ_lun;
|
||||
|
||||
ctl_softc = control_softc;
|
||||
|
||||
@ -12644,9 +12697,12 @@ ctl_queue_sense(union ctl_io *io)
|
||||
* If we don't have a LUN for this, just toss the sense
|
||||
* information.
|
||||
*/
|
||||
if ((io->io_hdr.nexus.targ_lun < CTL_MAX_LUNS)
|
||||
&& (ctl_softc->ctl_luns[io->io_hdr.nexus.targ_lun] != NULL))
|
||||
lun = ctl_softc->ctl_luns[io->io_hdr.nexus.targ_lun];
|
||||
targ_lun = io->io_hdr.nexus.targ_lun;
|
||||
if (io->io_hdr.nexus.lun_map_fn != NULL)
|
||||
targ_lun = io->io_hdr.nexus.lun_map_fn(io->io_hdr.nexus.lun_map_arg, targ_lun);
|
||||
if ((targ_lun < CTL_MAX_LUNS)
|
||||
&& (ctl_softc->ctl_luns[targ_lun] != NULL))
|
||||
lun = ctl_softc->ctl_luns[targ_lun];
|
||||
else
|
||||
goto bailout;
|
||||
|
||||
@ -13047,6 +13103,8 @@ ctl_isc_start(struct ctl_ha_component *c, ctl_ha_state state)
|
||||
{
|
||||
ctl_ha_comp_status ret = CTL_HA_COMP_STATUS_OK;
|
||||
|
||||
printf("%s: go\n", __func__);
|
||||
|
||||
// UNKNOWN->HA or UNKNOWN->SINGLE (bootstrap)
|
||||
if (c->state == CTL_HA_STATE_UNKNOWN ) {
|
||||
ctl_is_single = 0;
|
||||
|
@ -52,6 +52,7 @@ typedef enum {
|
||||
CTL_PORT_SCSI = 0x02,
|
||||
CTL_PORT_IOCTL = 0x04,
|
||||
CTL_PORT_INTERNAL = 0x08,
|
||||
CTL_PORT_ISCSI = 0x10,
|
||||
CTL_PORT_ALL = 0xff,
|
||||
CTL_PORT_ISC = 0x100 // FC port for inter-shelf communication
|
||||
} ctl_port_type;
|
||||
|
@ -173,6 +173,12 @@ typedef void (*be_lun_config_t)(void *be_lun,
|
||||
* The links field is for CTL internal use only, and should not be used by
|
||||
* the backend.
|
||||
*/
|
||||
struct ctl_be_lun_option {
|
||||
STAILQ_ENTRY(ctl_be_lun_option) links;
|
||||
char *name;
|
||||
char *value;
|
||||
};
|
||||
|
||||
struct ctl_be_lun {
|
||||
uint8_t lun_type; /* passed to CTL */
|
||||
ctl_backend_lun_flags flags; /* passed to CTL */
|
||||
@ -187,6 +193,7 @@ struct ctl_be_lun {
|
||||
be_lun_config_t lun_config_status; /* passed to CTL */
|
||||
struct ctl_backend_driver *be; /* passed to CTL */
|
||||
void *ctl_lun; /* used by CTL */
|
||||
STAILQ_HEAD(, ctl_be_lun_option) options; /* passed to CTL */
|
||||
STAILQ_ENTRY(ctl_be_lun) links; /* used by CTL */
|
||||
};
|
||||
|
||||
|
@ -1639,6 +1639,7 @@ 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);
|
||||
|
||||
@ -1740,6 +1741,16 @@ ctl_be_block_create(struct ctl_be_block_softc *softc, struct ctl_lun_req *req)
|
||||
}
|
||||
|
||||
num_threads = tmp_num_threads;
|
||||
} 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -491,7 +491,7 @@ ctl_backend_ramdisk_create(struct ctl_be_ramdisk_softc *softc,
|
||||
struct ctl_lun_create_params *params;
|
||||
uint32_t blocksize;
|
||||
char tmpstr[32];
|
||||
int retval;
|
||||
int i, retval;
|
||||
|
||||
retval = 0;
|
||||
params = &req->reqdata.create;
|
||||
@ -509,6 +509,7 @@ ctl_backend_ramdisk_create(struct ctl_be_ramdisk_softc *softc,
|
||||
sizeof(*be_lun));
|
||||
goto bailout_error;
|
||||
}
|
||||
STAILQ_INIT(&be_lun->ctl_be_lun.options);
|
||||
|
||||
if (params->flags & CTL_LUN_FLAG_DEV_TYPE)
|
||||
be_lun->ctl_be_lun.lun_type = params->device_type;
|
||||
@ -545,6 +546,17 @@ ctl_backend_ramdisk_create(struct ctl_be_ramdisk_softc *softc,
|
||||
|
||||
be_lun->softc = softc;
|
||||
|
||||
for (i = 0; i < req->num_be_args; i++) {
|
||||
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);
|
||||
}
|
||||
|
||||
be_lun->flags = CTL_BE_RAMDISK_LUN_UNCONFIGURED;
|
||||
be_lun->ctl_be_lun.flags = CTL_LUN_FLAG_PRIMARY;
|
||||
be_lun->ctl_be_lun.be_lun = be_lun;
|
||||
|
@ -49,6 +49,9 @@ typedef enum {
|
||||
typedef void (*port_func_t)(void *onoff_arg);
|
||||
typedef int (*targ_func_t)(void *arg, struct ctl_id targ_id);
|
||||
typedef int (*lun_func_t)(void *arg, struct ctl_id targ_id, int lun_id);
|
||||
typedef int (*fe_ioctl_t)(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
|
||||
struct thread *td);
|
||||
typedef int (*fe_devid_t)(struct ctl_scsiio *ctsio, int alloc_len);
|
||||
|
||||
/*
|
||||
* The ctl_frontend structure is the registration mechanism between a FETD
|
||||
@ -213,6 +216,8 @@ struct ctl_frontend {
|
||||
targ_func_t targ_disable; /* passed to CTL */
|
||||
lun_func_t lun_enable; /* passed to CTL */
|
||||
lun_func_t lun_disable; /* passed to CTL */
|
||||
fe_ioctl_t ioctl; /* passed to CTL */
|
||||
fe_devid_t devid; /* passed to CTL */
|
||||
void *targ_lun_arg; /* passed to CTL */
|
||||
void (*fe_datamove)(union ctl_io *io); /* passed to CTL */
|
||||
void (*fe_done)(union ctl_io *io); /* passed to CTL */
|
||||
|
@ -204,6 +204,8 @@ struct ctl_nexus {
|
||||
uint32_t targ_port; /* Target port, filled in by PORT */
|
||||
struct ctl_id targ_target; /* Destination target */
|
||||
uint32_t targ_lun; /* Destination lun */
|
||||
uint32_t (*lun_map_fn)(void *arg, uint32_t lun);
|
||||
void *lun_map_arg;
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
|
Loading…
x
Reference in New Issue
Block a user