summaryrefslogtreecommitdiffstats
path: root/sys/cam
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2015-02-01 21:50:28 +0000
committermav <mav@FreeBSD.org>2015-02-01 21:50:28 +0000
commit8adb86862b914637b98b57e7708b6d2171e108e1 (patch)
tree73947d5774a365e2dbdf24d9296d66ac4cb8e566 /sys/cam
parent034497915685715efafad305dcd278c391b06ee4 (diff)
downloadFreeBSD-src-8adb86862b914637b98b57e7708b6d2171e108e1.zip
FreeBSD-src-8adb86862b914637b98b57e7708b6d2171e108e1.tar.gz
CTL LUN mapping rewrite.
Replace iSCSI-specific LUN mapping mechanism with new one, working for any ports. By default all ports are created without LUN mapping, exposing all CTL LUNs as before. But, if needed, LUN mapping can be manually set on per-port basis via ctladm. For its iSCSI ports ctld does it via ioctl(2). The next step will be to teach ctld to work with FibreChannel ports also. Respecting additional flexibility of the new mechanism, ctl.conf now allows alternative syntax for LUN definition. LUNs can now be defined in global context, and then referenced from targets by unique name, as needed. It allows same LUN to be exposed several times via multiple targets. While there, increase limit for LUNs per target in ctld from 256 to 1024. Some initiators do not support LUNs above 255, but that is not our problem. Discussed with: trasz MFC after: 2 weeks Relnotes: yes Sponsored by: iXsystems, Inc.
Diffstat (limited to 'sys/cam')
-rw-r--r--sys/cam/ctl/ctl.c173
-rw-r--r--sys/cam/ctl/ctl_frontend.c1
-rw-r--r--sys/cam/ctl/ctl_frontend.h3
-rw-r--r--sys/cam/ctl/ctl_frontend_iscsi.c99
-rw-r--r--sys/cam/ctl/ctl_frontend_iscsi.h1
-rw-r--r--sys/cam/ctl/ctl_ioctl.h7
-rw-r--r--sys/cam/ctl/ctl_private.h7
-rw-r--r--sys/cam/ctl/ctl_tpc_local.c52
8 files changed, 178 insertions, 165 deletions
diff --git a/sys/cam/ctl/ctl.c b/sys/cam/ctl/ctl.c
index fb66b45..e6305aa 100644
--- a/sys/cam/ctl/ctl.c
+++ b/sys/cam/ctl/ctl.c
@@ -398,12 +398,11 @@ static int ctl_ioctl_fill_ooa(struct ctl_lun *lun, uint32_t *cur_fill_num,
struct ctl_ooa_entry *kern_entries);
static int ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
struct thread *td);
-static uint32_t ctl_map_lun(struct ctl_softc *softc, int port_num, uint32_t lun);
-static uint32_t ctl_map_lun_back(struct ctl_softc *softc, int port_num, uint32_t lun);
static int ctl_alloc_lun(struct ctl_softc *ctl_softc, struct ctl_lun *lun,
struct ctl_be_lun *be_lun, struct ctl_id target_id);
static int ctl_free_lun(struct ctl_lun *lun);
static void ctl_create_lun(struct ctl_be_lun *be_lun);
+static struct ctl_port * ctl_io_port(struct ctl_io_hdr *io_hdr);
/**
static void ctl_failover_change_pages(struct ctl_softc *softc,
struct ctl_scsiio *ctsio, int master);
@@ -3411,6 +3410,7 @@ ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
struct ctl_lun_list *list;
struct ctl_option *opt;
int j;
+ uint32_t plun;
list = (struct ctl_lun_list *)addr;
@@ -3491,6 +3491,18 @@ ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
break;
}
+ if (port->lun_map != NULL) {
+ sbuf_printf(sb, "\t<lun_map>on</lun_map>\n");
+ for (j = 0; j < CTL_MAX_LUNS; j++) {
+ plun = ctl_lun_map_from_port(port, j);
+ if (plun >= CTL_MAX_LUNS)
+ continue;
+ sbuf_printf(sb,
+ "\t<lun id=\"%u\">%u</lun>\n",
+ j, plun);
+ }
+ }
+
for (j = 0; j < CTL_MAX_INIT_PER_PORT; j++) {
if (port->wwpn_iid[j].in_use == 0 ||
(port->wwpn_iid[j].wwpn == 0 &&
@@ -3538,6 +3550,38 @@ ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
sbuf_delete(sb);
break;
}
+ case CTL_LUN_MAP: {
+ struct ctl_lun_map *lm = (struct ctl_lun_map *)addr;
+ struct ctl_port *port;
+
+ mtx_lock(&softc->ctl_lock);
+ if (lm->port >= CTL_MAX_PORTS ||
+ (port = softc->ctl_ports[lm->port]) == NULL) {
+ mtx_unlock(&softc->ctl_lock);
+ return (ENXIO);
+ }
+ if (lm->plun < CTL_MAX_LUNS) {
+ if (lm->lun == UINT32_MAX)
+ retval = ctl_lun_map_unset(port, lm->plun);
+ else if (lm->lun < CTL_MAX_LUNS &&
+ softc->ctl_luns[lm->lun] != NULL)
+ retval = ctl_lun_map_set(port, lm->plun, lm->lun);
+ else {
+ mtx_unlock(&softc->ctl_lock);
+ return (ENXIO);
+ }
+ } else if (lm->plun == UINT32_MAX) {
+ if (lm->lun == UINT32_MAX)
+ retval = ctl_lun_map_deinit(port);
+ else
+ retval = ctl_lun_map_init(port);
+ } else {
+ mtx_unlock(&softc->ctl_lock);
+ return (ENXIO);
+ }
+ mtx_unlock(&softc->ctl_lock);
+ break;
+ }
default: {
/* XXX KDM should we fix this? */
#if 0
@@ -3602,35 +3646,106 @@ ctl_port_idx(int port_num)
return(port_num - CTL_MAX_PORTS);
}
-static uint32_t
-ctl_map_lun(struct ctl_softc *softc, int port_num, uint32_t lun_id)
+int
+ctl_lun_map_init(struct ctl_port *port)
+{
+ uint32_t i;
+
+ if (port->lun_map == NULL)
+ port->lun_map = malloc(sizeof(uint32_t) * CTL_MAX_LUNS,
+ M_CTL, M_NOWAIT);
+ if (port->lun_map == NULL)
+ return (ENOMEM);
+ for (i = 0; i < CTL_MAX_LUNS; i++)
+ port->lun_map[i] = UINT32_MAX;
+ return (0);
+}
+
+int
+ctl_lun_map_deinit(struct ctl_port *port)
+{
+
+ if (port->lun_map == NULL)
+ return (0);
+ free(port->lun_map, M_CTL);
+ port->lun_map = NULL;
+ return (0);
+}
+
+int
+ctl_lun_map_set(struct ctl_port *port, uint32_t plun, uint32_t glun)
+{
+ int status;
+
+ if (port->lun_map == NULL) {
+ status = ctl_lun_map_init(port);
+ if (status != 0)
+ return (status);
+ }
+ port->lun_map[plun] = glun;
+ return (0);
+}
+
+int
+ctl_lun_map_unset(struct ctl_port *port, uint32_t plun)
+{
+
+ if (port->lun_map == NULL)
+ return (0);
+ port->lun_map[plun] = UINT32_MAX;
+ return (0);
+}
+
+int
+ctl_lun_map_unsetg(struct ctl_port *port, uint32_t glun)
+{
+ int i;
+
+ if (port->lun_map == NULL)
+ return (0);
+ for (i = 0; i < CTL_MAX_LUNS; i++) {
+ if (port->lun_map[i] == glun)
+ port->lun_map[i] = UINT32_MAX;
+ }
+ return (0);
+}
+
+uint32_t
+ctl_lun_map_from_port(struct ctl_port *port, uint32_t lun_id)
{
- struct ctl_port *port;
- port = softc->ctl_ports[ctl_port_idx(port_num)];
if (port == NULL)
return (UINT32_MAX);
- if (port->lun_map == NULL)
+ if (port->lun_map == NULL || lun_id >= CTL_MAX_LUNS)
return (lun_id);
- return (port->lun_map(port->targ_lun_arg, lun_id));
+ return (port->lun_map[lun_id]);
}
-static uint32_t
-ctl_map_lun_back(struct ctl_softc *softc, int port_num, uint32_t lun_id)
+uint32_t
+ctl_lun_map_to_port(struct ctl_port *port, uint32_t lun_id)
{
- struct ctl_port *port;
uint32_t i;
- port = softc->ctl_ports[ctl_port_idx(port_num)];
+ if (port == NULL)
+ return (UINT32_MAX);
if (port->lun_map == NULL)
return (lun_id);
for (i = 0; i < CTL_MAX_LUNS; i++) {
- if (port->lun_map(port->targ_lun_arg, i) == lun_id)
+ if (port->lun_map[i] == lun_id)
return (i);
}
return (UINT32_MAX);
}
+static struct ctl_port *
+ctl_io_port(struct ctl_io_hdr *io_hdr)
+{
+ int port_num;
+
+ port_num = io_hdr->nexus.targ_port;
+ return (control_softc->ctl_ports[ctl_port_idx(port_num)]);
+}
+
/*
* Note: This only works for bitmask sizes that are at least 32 bits, and
* that are a power of 2.
@@ -4676,9 +4791,7 @@ static int
ctl_free_lun(struct ctl_lun *lun)
{
struct ctl_softc *softc;
-#if 0
struct ctl_port *port;
-#endif
struct ctl_lun *nlun;
int i;
@@ -4686,6 +4799,9 @@ ctl_free_lun(struct ctl_lun *lun)
mtx_assert(&softc->ctl_lock, MA_OWNED);
+ STAILQ_FOREACH(port, &softc->port_list, links)
+ ctl_lun_map_unsetg(port, lun->lun);
+
STAILQ_REMOVE(&softc->lun_list, lun, ctl_lun, links);
ctl_clear_mask(softc->ctl_lun_mask, lun->lun);
@@ -7343,8 +7459,7 @@ ctl_report_tagret_port_groups(struct ctl_scsiio *ctsio)
STAILQ_FOREACH(port, &softc->port_list, links) {
if ((port->status & CTL_PORT_STATUS_ONLINE) == 0)
continue;
- if (ctl_map_lun_back(softc, port->targ_port, lun->lun) >=
- CTL_MAX_LUNS)
+ if (ctl_lun_map_to_port(port, lun->lun) >= CTL_MAX_LUNS)
continue;
num_target_ports++;
}
@@ -7417,8 +7532,7 @@ ctl_report_tagret_port_groups(struct ctl_scsiio *ctsio)
STAILQ_FOREACH(port, &softc->port_list, links) {
if ((port->status & CTL_PORT_STATUS_ONLINE) == 0)
continue;
- if (ctl_map_lun_back(softc, port->targ_port, lun->lun)
- >= CTL_MAX_LUNS)
+ if (ctl_lun_map_to_port(port, lun->lun) >= CTL_MAX_LUNS)
continue;
p = port->targ_port % CTL_MAX_PORTS + g * CTL_MAX_PORTS;
scsi_ulto2b(p, tpg_desc->descriptors[pc].
@@ -9260,6 +9374,7 @@ ctl_report_luns(struct ctl_scsiio *ctsio)
struct scsi_report_luns *cdb;
struct scsi_report_luns_data *lun_data;
struct ctl_lun *lun, *request_lun;
+ struct ctl_port *port;
int num_luns, retval;
uint32_t alloc_len, lun_datalen;
int num_filled, well_known;
@@ -9316,6 +9431,7 @@ ctl_report_luns(struct ctl_scsiio *ctsio)
request_lun = (struct ctl_lun *)
ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
+ port = ctl_io_port(&ctsio->io_hdr);
lun_datalen = sizeof(*lun_data) +
(num_luns * sizeof(struct scsi_report_luns_lundata));
@@ -9328,8 +9444,7 @@ ctl_report_luns(struct ctl_scsiio *ctsio)
mtx_lock(&softc->ctl_lock);
for (targ_lun_id = 0, num_filled = 0; targ_lun_id < CTL_MAX_LUNS && num_filled < num_luns; targ_lun_id++) {
- lun_id = ctl_map_lun(softc, ctsio->io_hdr.nexus.targ_port,
- targ_lun_id);
+ lun_id = ctl_lun_map_from_port(port, targ_lun_id);
if (lun_id >= CTL_MAX_LUNS)
continue;
lun = softc->ctl_luns[lun_id];
@@ -10014,8 +10129,7 @@ ctl_inquiry_evpd_scsi_ports(struct ctl_scsiio *ctsio, int alloc_len)
if ((port->status & CTL_PORT_STATUS_ONLINE) == 0)
continue;
if (lun != NULL &&
- ctl_map_lun_back(softc, port->targ_port, lun->lun) >=
- CTL_MAX_LUNS)
+ ctl_lun_map_to_port(port, lun->lun) >= CTL_MAX_LUNS)
continue;
num_target_ports++;
if (port->init_devid)
@@ -10068,8 +10182,7 @@ ctl_inquiry_evpd_scsi_ports(struct ctl_scsiio *ctsio, int alloc_len)
if ((port->status & CTL_PORT_STATUS_ONLINE) == 0)
continue;
if (lun != NULL &&
- ctl_map_lun_back(softc, port->targ_port, lun->lun)
- >= CTL_MAX_LUNS)
+ ctl_lun_map_to_port(port, lun->lun) >= CTL_MAX_LUNS)
continue;
p = port->targ_port % CTL_MAX_PORTS + g * CTL_MAX_PORTS;
scsi_ulto2b(p, pd->relative_port_id);
@@ -13745,6 +13858,7 @@ int
ctl_queue_sense(union ctl_io *io)
{
struct ctl_lun *lun;
+ struct ctl_port *port;
struct ctl_softc *softc;
uint32_t initidx, targ_lun;
@@ -13765,8 +13879,8 @@ ctl_queue_sense(union ctl_io *io)
* If we don't have a LUN for this, just toss the sense
* information.
*/
- targ_lun = io->io_hdr.nexus.targ_lun;
- targ_lun = ctl_map_lun(softc, io->io_hdr.nexus.targ_port, targ_lun);
+ port = ctl_io_port(&ctsio->io_hdr);
+ targ_lun = ctl_lun_map_from_port(port, io->io_hdr.nexus.targ_lun);
if ((targ_lun < CTL_MAX_LUNS)
&& (softc->ctl_luns[targ_lun] != NULL))
lun = softc->ctl_luns[targ_lun];
@@ -13806,6 +13920,7 @@ bailout:
int
ctl_queue(union ctl_io *io)
{
+ struct ctl_port *port;
CTL_DEBUG_PRINT(("ctl_queue cdb[0]=%02X\n", io->scsiio.cdb[0]));
@@ -13815,9 +13930,9 @@ ctl_queue(union ctl_io *io)
#endif /* CTL_TIME_IO */
/* Map FE-specific LUN ID into global one. */
+ port = ctl_io_port(&io->io_hdr);
io->io_hdr.nexus.targ_mapped_lun =
- ctl_map_lun(control_softc, io->io_hdr.nexus.targ_port,
- io->io_hdr.nexus.targ_lun);
+ ctl_lun_map_from_port(port, io->io_hdr.nexus.targ_lun);
switch (io->io_hdr.io_type) {
case CTL_IO_SCSI:
diff --git a/sys/cam/ctl/ctl_frontend.c b/sys/cam/ctl/ctl_frontend.c
index 982675e..c38e527 100644
--- a/sys/cam/ctl/ctl_frontend.c
+++ b/sys/cam/ctl/ctl_frontend.c
@@ -234,6 +234,7 @@ ctl_port_deregister(struct ctl_port *port)
ctl_pool_free(pool);
ctl_free_opts(&port->options);
+ ctl_lun_map_deinit(port);
free(port->port_devid, M_CTL);
port->port_devid = NULL;
free(port->target_devid, M_CTL);
diff --git a/sys/cam/ctl/ctl_frontend.h b/sys/cam/ctl/ctl_frontend.h
index 06ae5a1..f1cc1c4 100644
--- a/sys/cam/ctl/ctl_frontend.h
+++ b/sys/cam/ctl/ctl_frontend.h
@@ -51,7 +51,6 @@ typedef void (*fe_shutdown_t)(void);
typedef void (*port_func_t)(void *onoff_arg);
typedef int (*port_info_func_t)(void *onoff_arg, struct sbuf *sb);
typedef int (*lun_func_t)(void *arg, struct ctl_id targ_id, int lun_id);
-typedef uint32_t (*lun_map_func_t)(void *arg, uint32_t lun_id);
typedef int (*fe_ioctl_t)(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
struct thread *td);
@@ -226,7 +225,7 @@ struct ctl_port {
void *onoff_arg; /* passed to CTL */
lun_func_t lun_enable; /* passed to CTL */
lun_func_t lun_disable; /* passed to CTL */
- lun_map_func_t lun_map; /* passed to CTL */
+ uint32_t *lun_map; /* 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 */
diff --git a/sys/cam/ctl/ctl_frontend_iscsi.c b/sys/cam/ctl/ctl_frontend_iscsi.c
index 99d698b..a922d5b 100644
--- a/sys/cam/ctl/ctl_frontend_iscsi.c
+++ b/sys/cam/ctl/ctl_frontend_iscsi.c
@@ -151,7 +151,6 @@ static int cfiscsi_lun_enable(void *arg,
struct ctl_id target_id, int lun_id);
static int cfiscsi_lun_disable(void *arg,
struct ctl_id target_id, int lun_id);
-static uint32_t cfiscsi_lun_map(void *arg, uint32_t lun);
static int cfiscsi_ioctl(struct cdev *dev,
u_long cmd, caddr_t addr, int flag, struct thread *td);
static void cfiscsi_datamove(union ctl_io *io);
@@ -2031,7 +2030,6 @@ cfiscsi_ioctl_port_create(struct ctl_req *req)
port->onoff_arg = ct;
port->lun_enable = cfiscsi_lun_enable;
port->lun_disable = cfiscsi_lun_disable;
- port->lun_map = cfiscsi_lun_map;
port->targ_lun_arg = ct;
port->fe_datamove = cfiscsi_datamove;
port->fe_done = cfiscsi_done;
@@ -2081,7 +2079,7 @@ cfiscsi_ioctl_port_create(struct ctl_req *req)
free(port->target_devid, M_CFISCSI);
req->status = CTL_LUN_ERROR;
snprintf(req->error_str, sizeof(req->error_str),
- "ctl_frontend_register() failed with error %d", retval);
+ "ctl_port_register() failed with error %d", retval);
return;
}
done:
@@ -2259,7 +2257,6 @@ cfiscsi_target_find_or_create(struct cfiscsi_softc *softc, const char *name,
const char *alias)
{
struct cfiscsi_target *ct, *newct;
- int i;
if (name[0] == '\0' || strlen(name) >= CTL_ISCSI_NAME_LEN)
return (NULL);
@@ -2277,9 +2274,6 @@ cfiscsi_target_find_or_create(struct cfiscsi_softc *softc, const char *name,
return (ct);
}
- for (i = 0; i < CTL_MAX_LUNS; i++)
- newct->ct_luns[i] = UINT32_MAX;
-
strlcpy(newct->ct_name, name, sizeof(newct->ct_name));
if (alias != NULL)
strlcpy(newct->ct_alias, alias, sizeof(newct->ct_alias));
@@ -2294,108 +2288,17 @@ cfiscsi_target_find_or_create(struct cfiscsi_softc *softc, const char *name,
return (newct);
}
-/*
- * Takes LUN from the target space and returns LUN from the CTL space.
- */
-static uint32_t
-cfiscsi_lun_map(void *arg, uint32_t lun)
-{
- struct cfiscsi_target *ct = arg;
-
- if (lun >= CTL_MAX_LUNS) {
- CFISCSI_DEBUG("requested lun number %d is higher "
- "than maximum %d", lun, CTL_MAX_LUNS - 1);
- return (UINT32_MAX);
- }
- return (ct->ct_luns[lun]);
-}
-
-static int
-cfiscsi_target_set_lun(struct cfiscsi_target *ct,
- unsigned long lun_id, unsigned long ctl_lun_id)
-{
-
- if (lun_id >= CTL_MAX_LUNS) {
- CFISCSI_WARN("requested lun number %ld is higher "
- "than maximum %d", lun_id, CTL_MAX_LUNS - 1);
- return (-1);
- }
-
- if (ct->ct_luns[lun_id] < CTL_MAX_LUNS) {
- /*
- * CTL calls cfiscsi_lun_enable() twice for each LUN - once
- * when the LUN is created, and a second time just before
- * the port is brought online; don't emit warnings
- * for that case.
- */
- if (ct->ct_luns[lun_id] == ctl_lun_id)
- return (0);
- CFISCSI_WARN("lun %ld already allocated", lun_id);
- return (-1);
- }
-
-#if 0
- CFISCSI_DEBUG("adding mapping for lun %ld, target %s "
- "to ctl lun %ld", lun_id, ct->ct_name, ctl_lun_id);
-#endif
-
- ct->ct_luns[lun_id] = ctl_lun_id;
-
- return (0);
-}
-
static int
cfiscsi_lun_enable(void *arg, struct ctl_id target_id, int lun_id)
{
- struct cfiscsi_softc *softc;
- struct cfiscsi_target *ct;
- const char *target = NULL;
- const char *lun = NULL;
- unsigned long tmp;
-
- ct = (struct cfiscsi_target *)arg;
- softc = ct->ct_softc;
-
- target = ctl_get_opt(&control_softc->ctl_luns[lun_id]->be_lun->options,
- "cfiscsi_target");
- lun = ctl_get_opt(&control_softc->ctl_luns[lun_id]->be_lun->options,
- "cfiscsi_lun");
- if (target == NULL && lun == NULL)
- return (0);
-
- if (target == NULL || lun == NULL) {
- CFISCSI_WARN("lun added with cfiscsi_target, but without "
- "cfiscsi_lun, or the other way around; ignoring");
- return (0);
- }
-
- if (strcmp(target, ct->ct_name) != 0)
- return (0);
-
- tmp = strtoul(lun, NULL, 10);
- cfiscsi_target_set_lun(ct, tmp, lun_id);
return (0);
}
static int
cfiscsi_lun_disable(void *arg, struct ctl_id target_id, int lun_id)
{
- struct cfiscsi_softc *softc;
- struct cfiscsi_target *ct;
- int i;
-
- ct = (struct cfiscsi_target *)arg;
- softc = ct->ct_softc;
- mtx_lock(&softc->lock);
- for (i = 0; i < CTL_MAX_LUNS; i++) {
- if (ct->ct_luns[i] != lun_id)
- continue;
- ct->ct_luns[i] = UINT32_MAX;
- break;
- }
- mtx_unlock(&softc->lock);
return (0);
}
diff --git a/sys/cam/ctl/ctl_frontend_iscsi.h b/sys/cam/ctl/ctl_frontend_iscsi.h
index 5000f4c..02fd34e 100644
--- a/sys/cam/ctl/ctl_frontend_iscsi.h
+++ b/sys/cam/ctl/ctl_frontend_iscsi.h
@@ -38,7 +38,6 @@
struct cfiscsi_target {
TAILQ_ENTRY(cfiscsi_target) ct_next;
- uint32_t ct_luns[CTL_MAX_LUNS];
struct cfiscsi_softc *ct_softc;
volatile u_int ct_refcount;
char ct_name[CTL_ISCSI_NAME_LEN];
diff --git a/sys/cam/ctl/ctl_ioctl.h b/sys/cam/ctl/ctl_ioctl.h
index 3093efd..532953f 100644
--- a/sys/cam/ctl/ctl_ioctl.h
+++ b/sys/cam/ctl/ctl_ioctl.h
@@ -805,6 +805,12 @@ struct ctl_iscsi {
/* passed to userland */
};
+struct ctl_lun_map {
+ uint32_t port;
+ uint32_t plun;
+ uint32_t lun;
+};
+
#define CTL_IO _IOWR(CTL_MINOR, 0x00, union ctl_io)
#define CTL_ENABLE_PORT _IOW(CTL_MINOR, 0x04, struct ctl_port_entry)
#define CTL_DISABLE_PORT _IOW(CTL_MINOR, 0x05, struct ctl_port_entry)
@@ -832,6 +838,7 @@ struct ctl_iscsi {
#define CTL_ISCSI _IOWR(CTL_MINOR, 0x25, struct ctl_iscsi)
#define CTL_PORT_REQ _IOWR(CTL_MINOR, 0x26, struct ctl_req)
#define CTL_PORT_LIST _IOWR(CTL_MINOR, 0x27, struct ctl_lun_list)
+#define CTL_LUN_MAP _IOW(CTL_MINOR, 0x28, struct ctl_lun_map)
#endif /* _CTL_IOCTL_H_ */
diff --git a/sys/cam/ctl/ctl_private.h b/sys/cam/ctl/ctl_private.h
index 7bedf10..ffcb063 100644
--- a/sys/cam/ctl/ctl_private.h
+++ b/sys/cam/ctl/ctl_private.h
@@ -492,6 +492,13 @@ extern const struct ctl_cmd_entry ctl_cmd_table[256];
uint32_t ctl_get_initindex(struct ctl_nexus *nexus);
uint32_t ctl_get_resindex(struct ctl_nexus *nexus);
uint32_t ctl_port_idx(int port_num);
+int ctl_lun_map_init(struct ctl_port *port);
+int ctl_lun_map_deinit(struct ctl_port *port);
+int ctl_lun_map_set(struct ctl_port *port, uint32_t plun, uint32_t glun);
+int ctl_lun_map_unset(struct ctl_port *port, uint32_t plun);
+int ctl_lun_map_unsetg(struct ctl_port *port, uint32_t glun);
+uint32_t ctl_lun_map_from_port(struct ctl_port *port, uint32_t plun);
+uint32_t ctl_lun_map_to_port(struct ctl_port *port, uint32_t glun);
int ctl_pool_create(struct ctl_softc *ctl_softc, const char *pool_name,
uint32_t total_ctl_io, void **npool);
void ctl_pool_free(struct ctl_io_pool *pool);
diff --git a/sys/cam/ctl/ctl_tpc_local.c b/sys/cam/ctl/ctl_tpc_local.c
index 63360fe..a254418 100644
--- a/sys/cam/ctl/ctl_tpc_local.c
+++ b/sys/cam/ctl/ctl_tpc_local.c
@@ -314,48 +314,30 @@ tpcl_resolve(struct ctl_softc *softc, int init_port,
struct scsi_ec_cscd_id *cscdid;
struct ctl_port *port;
struct ctl_lun *lun;
- uint64_t lunid = UINT64_MAX, l;
- int i;
+ uint64_t lunid = UINT64_MAX;
if (cscd->type_code != EC_CSCD_ID)
return (lunid);
cscdid = (struct scsi_ec_cscd_id *)cscd;
mtx_lock(&softc->ctl_lock);
- if (init_port >= 0) {
+ if (init_port >= 0)
port = softc->ctl_ports[ctl_port_idx(init_port)];
- if (port == NULL || port->lun_map == NULL)
- init_port = -1;
- }
- if (init_port < 0) {
- STAILQ_FOREACH(lun, &softc->lun_list, links) {
- if (lun->lun_devid == NULL)
- continue;
- if (scsi_devid_match(lun->lun_devid->data,
- lun->lun_devid->len, &cscdid->codeset,
- cscdid->length + 4) == 0) {
- lunid = lun->lun;
- if (ss && lun->be_lun)
- *ss = lun->be_lun->blocksize;
- break;
- }
- }
- } else {
- for (i = 0; i < CTL_MAX_LUNS; i++) {
- l = port->lun_map(port->targ_lun_arg, i);
- if (l >= CTL_MAX_LUNS)
- continue;
- lun = softc->ctl_luns[l];
- if (lun == NULL || lun->lun_devid == NULL)
- continue;
- if (scsi_devid_match(lun->lun_devid->data,
- lun->lun_devid->len, &cscdid->codeset,
- cscdid->length + 4) == 0) {
- lunid = lun->lun;
- if (ss && lun->be_lun)
- *ss = lun->be_lun->blocksize;
- break;
- }
+ else
+ port = NULL;
+ STAILQ_FOREACH(lun, &softc->lun_list, links) {
+ if (port != NULL &&
+ ctl_lun_map_to_port(port, lun->lun) >= CTL_MAX_LUNS)
+ continue;
+ if (lun->lun_devid == NULL)
+ continue;
+ if (scsi_devid_match(lun->lun_devid->data,
+ lun->lun_devid->len, &cscdid->codeset,
+ cscdid->length + 4) == 0) {
+ lunid = lun->lun;
+ if (ss && lun->be_lun)
+ *ss = lun->be_lun->blocksize;
+ break;
}
}
mtx_unlock(&softc->ctl_lock);
OpenPOWER on IntegriCloud