0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #include <linux/module.h>
0017 #include <linux/moduleparam.h>
0018 #include <generated/utsrelease.h>
0019 #include <linux/utsname.h>
0020 #include <linux/init.h>
0021 #include <linux/slab.h>
0022 #include <linux/kthread.h>
0023 #include <linux/types.h>
0024 #include <linux/string.h>
0025 #include <linux/configfs.h>
0026 #include <linux/kernel.h>
0027 #include <linux/ctype.h>
0028 #include <asm/unaligned.h>
0029 #include <scsi/libfc.h>
0030
0031 #include <target/target_core_base.h>
0032 #include <target/target_core_fabric.h>
0033
0034 #include "tcm_fc.h"
0035
0036 static LIST_HEAD(ft_wwn_list);
0037 DEFINE_MUTEX(ft_lport_lock);
0038
0039 unsigned int ft_debug_logging;
0040 module_param_named(debug_logging, ft_debug_logging, int, S_IRUGO|S_IWUSR);
0041 MODULE_PARM_DESC(debug_logging, "a bit mask of logging levels");
0042
0043
0044
0045
0046
0047
0048
0049 static ssize_t ft_parse_wwn(const char *name, u64 *wwn, int strict)
0050 {
0051 const char *cp;
0052 char c;
0053 u32 byte = 0;
0054 u32 pos = 0;
0055 u32 err;
0056 int val;
0057
0058 *wwn = 0;
0059 for (cp = name; cp < &name[FT_NAMELEN - 1]; cp++) {
0060 c = *cp;
0061 if (c == '\n' && cp[1] == '\0')
0062 continue;
0063 if (strict && pos++ == 2 && byte++ < 7) {
0064 pos = 0;
0065 if (c == ':')
0066 continue;
0067 err = 1;
0068 goto fail;
0069 }
0070 if (c == '\0') {
0071 err = 2;
0072 if (strict && byte != 8)
0073 goto fail;
0074 return cp - name;
0075 }
0076 err = 3;
0077 val = hex_to_bin(c);
0078 if (val < 0 || (strict && isupper(c)))
0079 goto fail;
0080 *wwn = (*wwn << 4) | val;
0081 }
0082 err = 4;
0083 fail:
0084 pr_debug("err %u len %zu pos %u byte %u\n",
0085 err, cp - name, pos, byte);
0086 return -1;
0087 }
0088
0089 ssize_t ft_format_wwn(char *buf, size_t len, u64 wwn)
0090 {
0091 u8 b[8];
0092
0093 put_unaligned_be64(wwn, b);
0094 return snprintf(buf, len,
0095 "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x",
0096 b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7]);
0097 }
0098
0099 static ssize_t ft_wwn_show(void *arg, char *buf)
0100 {
0101 u64 *wwn = arg;
0102 ssize_t len;
0103
0104 len = ft_format_wwn(buf, PAGE_SIZE - 2, *wwn);
0105 buf[len++] = '\n';
0106 return len;
0107 }
0108
0109 static ssize_t ft_wwn_store(void *arg, const char *buf, size_t len)
0110 {
0111 ssize_t ret;
0112 u64 wwn;
0113
0114 ret = ft_parse_wwn(buf, &wwn, 0);
0115 if (ret > 0)
0116 *(u64 *)arg = wwn;
0117 return ret;
0118 }
0119
0120
0121
0122
0123
0124 static ssize_t ft_nacl_port_name_show(struct config_item *item, char *page)
0125 {
0126 struct se_node_acl *se_nacl = acl_to_nacl(item);
0127 struct ft_node_acl *acl = container_of(se_nacl,
0128 struct ft_node_acl, se_node_acl);
0129
0130 return ft_wwn_show(&acl->node_auth.port_name, page);
0131 }
0132
0133 static ssize_t ft_nacl_port_name_store(struct config_item *item,
0134 const char *page, size_t count)
0135 {
0136 struct se_node_acl *se_nacl = acl_to_nacl(item);
0137 struct ft_node_acl *acl = container_of(se_nacl,
0138 struct ft_node_acl, se_node_acl);
0139
0140 return ft_wwn_store(&acl->node_auth.port_name, page, count);
0141 }
0142
0143 static ssize_t ft_nacl_node_name_show(struct config_item *item,
0144 char *page)
0145 {
0146 struct se_node_acl *se_nacl = acl_to_nacl(item);
0147 struct ft_node_acl *acl = container_of(se_nacl,
0148 struct ft_node_acl, se_node_acl);
0149
0150 return ft_wwn_show(&acl->node_auth.node_name, page);
0151 }
0152
0153 static ssize_t ft_nacl_node_name_store(struct config_item *item,
0154 const char *page, size_t count)
0155 {
0156 struct se_node_acl *se_nacl = acl_to_nacl(item);
0157 struct ft_node_acl *acl = container_of(se_nacl,
0158 struct ft_node_acl, se_node_acl);
0159
0160 return ft_wwn_store(&acl->node_auth.node_name, page, count);
0161 }
0162
0163 CONFIGFS_ATTR(ft_nacl_, node_name);
0164 CONFIGFS_ATTR(ft_nacl_, port_name);
0165
0166 static ssize_t ft_nacl_tag_show(struct config_item *item,
0167 char *page)
0168 {
0169 return snprintf(page, PAGE_SIZE, "%s", acl_to_nacl(item)->acl_tag);
0170 }
0171
0172 static ssize_t ft_nacl_tag_store(struct config_item *item,
0173 const char *page, size_t count)
0174 {
0175 struct se_node_acl *se_nacl = acl_to_nacl(item);
0176 int ret;
0177
0178 ret = core_tpg_set_initiator_node_tag(se_nacl->se_tpg, se_nacl, page);
0179
0180 if (ret < 0)
0181 return ret;
0182 return count;
0183 }
0184
0185 CONFIGFS_ATTR(ft_nacl_, tag);
0186
0187 static struct configfs_attribute *ft_nacl_base_attrs[] = {
0188 &ft_nacl_attr_port_name,
0189 &ft_nacl_attr_node_name,
0190 &ft_nacl_attr_tag,
0191 NULL,
0192 };
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202 static int ft_init_nodeacl(struct se_node_acl *nacl, const char *name)
0203 {
0204 struct ft_node_acl *acl =
0205 container_of(nacl, struct ft_node_acl, se_node_acl);
0206 u64 wwpn;
0207
0208 if (ft_parse_wwn(name, &wwpn, 1) < 0)
0209 return -EINVAL;
0210
0211 acl->node_auth.port_name = wwpn;
0212 return 0;
0213 }
0214
0215
0216
0217
0218 static struct se_portal_group *ft_add_tpg(struct se_wwn *wwn, const char *name)
0219 {
0220 struct ft_lport_wwn *ft_wwn;
0221 struct ft_tpg *tpg;
0222 struct workqueue_struct *wq;
0223 unsigned long index;
0224 int ret;
0225
0226 pr_debug("tcm_fc: add tpg %s\n", name);
0227
0228
0229
0230
0231 if (strstr(name, "tpgt_") != name)
0232 return NULL;
0233
0234 ret = kstrtoul(name + 5, 10, &index);
0235 if (ret)
0236 return NULL;
0237 if (index > UINT_MAX)
0238 return NULL;
0239
0240 if ((index != 1)) {
0241 pr_err("Error, a single TPG=1 is used for HW port mappings\n");
0242 return ERR_PTR(-ENOSYS);
0243 }
0244
0245 ft_wwn = container_of(wwn, struct ft_lport_wwn, se_wwn);
0246 tpg = kzalloc(sizeof(*tpg), GFP_KERNEL);
0247 if (!tpg)
0248 return NULL;
0249 tpg->index = index;
0250 tpg->lport_wwn = ft_wwn;
0251 INIT_LIST_HEAD(&tpg->lun_list);
0252
0253 wq = alloc_workqueue("tcm_fc", 0, 1);
0254 if (!wq) {
0255 kfree(tpg);
0256 return NULL;
0257 }
0258
0259 ret = core_tpg_register(wwn, &tpg->se_tpg, SCSI_PROTOCOL_FCP);
0260 if (ret < 0) {
0261 destroy_workqueue(wq);
0262 kfree(tpg);
0263 return NULL;
0264 }
0265 tpg->workqueue = wq;
0266
0267 mutex_lock(&ft_lport_lock);
0268 ft_wwn->tpg = tpg;
0269 mutex_unlock(&ft_lport_lock);
0270
0271 return &tpg->se_tpg;
0272 }
0273
0274 static void ft_del_tpg(struct se_portal_group *se_tpg)
0275 {
0276 struct ft_tpg *tpg = container_of(se_tpg, struct ft_tpg, se_tpg);
0277 struct ft_lport_wwn *ft_wwn = tpg->lport_wwn;
0278
0279 pr_debug("del tpg %s\n",
0280 config_item_name(&tpg->se_tpg.tpg_group.cg_item));
0281
0282 destroy_workqueue(tpg->workqueue);
0283
0284
0285 synchronize_rcu();
0286
0287 mutex_lock(&ft_lport_lock);
0288 ft_wwn->tpg = NULL;
0289 if (tpg->tport) {
0290 tpg->tport->tpg = NULL;
0291 tpg->tport = NULL;
0292 }
0293 mutex_unlock(&ft_lport_lock);
0294
0295 core_tpg_deregister(se_tpg);
0296 kfree(tpg);
0297 }
0298
0299
0300
0301
0302
0303
0304
0305 struct ft_tpg *ft_lport_find_tpg(struct fc_lport *lport)
0306 {
0307 struct ft_lport_wwn *ft_wwn;
0308
0309 list_for_each_entry(ft_wwn, &ft_wwn_list, ft_wwn_node) {
0310 if (ft_wwn->wwpn == lport->wwpn)
0311 return ft_wwn->tpg;
0312 }
0313 return NULL;
0314 }
0315
0316
0317
0318
0319
0320
0321
0322
0323
0324 static struct se_wwn *ft_add_wwn(
0325 struct target_fabric_configfs *tf,
0326 struct config_group *group,
0327 const char *name)
0328 {
0329 struct ft_lport_wwn *ft_wwn;
0330 struct ft_lport_wwn *old_ft_wwn;
0331 u64 wwpn;
0332
0333 pr_debug("add wwn %s\n", name);
0334 if (ft_parse_wwn(name, &wwpn, 1) < 0)
0335 return NULL;
0336 ft_wwn = kzalloc(sizeof(*ft_wwn), GFP_KERNEL);
0337 if (!ft_wwn)
0338 return NULL;
0339 ft_wwn->wwpn = wwpn;
0340
0341 mutex_lock(&ft_lport_lock);
0342 list_for_each_entry(old_ft_wwn, &ft_wwn_list, ft_wwn_node) {
0343 if (old_ft_wwn->wwpn == wwpn) {
0344 mutex_unlock(&ft_lport_lock);
0345 kfree(ft_wwn);
0346 return NULL;
0347 }
0348 }
0349 list_add_tail(&ft_wwn->ft_wwn_node, &ft_wwn_list);
0350 ft_format_wwn(ft_wwn->name, sizeof(ft_wwn->name), wwpn);
0351 mutex_unlock(&ft_lport_lock);
0352
0353 return &ft_wwn->se_wwn;
0354 }
0355
0356 static void ft_del_wwn(struct se_wwn *wwn)
0357 {
0358 struct ft_lport_wwn *ft_wwn = container_of(wwn,
0359 struct ft_lport_wwn, se_wwn);
0360
0361 pr_debug("del wwn %s\n", ft_wwn->name);
0362 mutex_lock(&ft_lport_lock);
0363 list_del(&ft_wwn->ft_wwn_node);
0364 mutex_unlock(&ft_lport_lock);
0365
0366 kfree(ft_wwn);
0367 }
0368
0369 static ssize_t ft_wwn_version_show(struct config_item *item, char *page)
0370 {
0371 return sprintf(page, "TCM FC " FT_VERSION " on %s/%s on "
0372 ""UTS_RELEASE"\n", utsname()->sysname, utsname()->machine);
0373 }
0374
0375 CONFIGFS_ATTR_RO(ft_wwn_, version);
0376
0377 static struct configfs_attribute *ft_wwn_attrs[] = {
0378 &ft_wwn_attr_version,
0379 NULL,
0380 };
0381
0382 static inline struct ft_tpg *ft_tpg(struct se_portal_group *se_tpg)
0383 {
0384 return container_of(se_tpg, struct ft_tpg, se_tpg);
0385 }
0386
0387 static char *ft_get_fabric_wwn(struct se_portal_group *se_tpg)
0388 {
0389 return ft_tpg(se_tpg)->lport_wwn->name;
0390 }
0391
0392 static u16 ft_get_tag(struct se_portal_group *se_tpg)
0393 {
0394
0395
0396
0397
0398 return ft_tpg(se_tpg)->index;
0399 }
0400
0401 static int ft_check_false(struct se_portal_group *se_tpg)
0402 {
0403 return 0;
0404 }
0405
0406 static void ft_set_default_node_attr(struct se_node_acl *se_nacl)
0407 {
0408 }
0409
0410 static u32 ft_tpg_get_inst_index(struct se_portal_group *se_tpg)
0411 {
0412 return ft_tpg(se_tpg)->index;
0413 }
0414
0415 static const struct target_core_fabric_ops ft_fabric_ops = {
0416 .module = THIS_MODULE,
0417 .fabric_name = "fc",
0418 .node_acl_size = sizeof(struct ft_node_acl),
0419 .tpg_get_wwn = ft_get_fabric_wwn,
0420 .tpg_get_tag = ft_get_tag,
0421 .tpg_check_demo_mode = ft_check_false,
0422 .tpg_check_demo_mode_cache = ft_check_false,
0423 .tpg_check_demo_mode_write_protect = ft_check_false,
0424 .tpg_check_prod_mode_write_protect = ft_check_false,
0425 .tpg_get_inst_index = ft_tpg_get_inst_index,
0426 .check_stop_free = ft_check_stop_free,
0427 .release_cmd = ft_release_cmd,
0428 .close_session = ft_sess_close,
0429 .sess_get_index = ft_sess_get_index,
0430 .sess_get_initiator_sid = NULL,
0431 .write_pending = ft_write_pending,
0432 .set_default_node_attributes = ft_set_default_node_attr,
0433 .get_cmd_state = ft_get_cmd_state,
0434 .queue_data_in = ft_queue_data_in,
0435 .queue_status = ft_queue_status,
0436 .queue_tm_rsp = ft_queue_tm_resp,
0437 .aborted_task = ft_aborted_task,
0438
0439
0440
0441
0442 .fabric_make_wwn = &ft_add_wwn,
0443 .fabric_drop_wwn = &ft_del_wwn,
0444 .fabric_make_tpg = &ft_add_tpg,
0445 .fabric_drop_tpg = &ft_del_tpg,
0446 .fabric_init_nodeacl = &ft_init_nodeacl,
0447
0448 .tfc_wwn_attrs = ft_wwn_attrs,
0449 .tfc_tpg_nacl_base_attrs = ft_nacl_base_attrs,
0450 };
0451
0452 static struct notifier_block ft_notifier = {
0453 .notifier_call = ft_lport_notify
0454 };
0455
0456 static int __init ft_init(void)
0457 {
0458 int ret;
0459
0460 ret = target_register_template(&ft_fabric_ops);
0461 if (ret)
0462 goto out;
0463
0464 ret = fc_fc4_register_provider(FC_TYPE_FCP, &ft_prov);
0465 if (ret)
0466 goto out_unregister_template;
0467
0468 blocking_notifier_chain_register(&fc_lport_notifier_head, &ft_notifier);
0469 fc_lport_iterate(ft_lport_add, NULL);
0470 return 0;
0471
0472 out_unregister_template:
0473 target_unregister_template(&ft_fabric_ops);
0474 out:
0475 return ret;
0476 }
0477
0478 static void __exit ft_exit(void)
0479 {
0480 blocking_notifier_chain_unregister(&fc_lport_notifier_head,
0481 &ft_notifier);
0482 fc_fc4_deregister_provider(FC_TYPE_FCP, &ft_prov);
0483 fc_lport_iterate(ft_lport_del, NULL);
0484 target_unregister_template(&ft_fabric_ops);
0485 synchronize_rcu();
0486 }
0487
0488 MODULE_DESCRIPTION("FC TCM fabric driver " FT_VERSION);
0489 MODULE_LICENSE("GPL");
0490 module_init(ft_init);
0491 module_exit(ft_exit);