aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/target/loopback/tcm_loop.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2015-04-08 14:01:35 -0400
committerNicholas Bellinger <nab@linux-iscsi.org>2015-04-14 15:28:41 -0400
commit9ac8928e6a3e1ed02e632e45aa766129fe6b1802 (patch)
treeea516680cc5f811df862966bb43cfbe3e34dfb26 /drivers/target/loopback/tcm_loop.c
parent2c336e3a2e1728d9b3116422655832184dc7046c (diff)
target: simplify the target template registration API
Instead of calling target_fabric_configfs_init() + target_fabric_configfs_register() / target_fabric_configfs_deregister() target_fabric_configfs_free() from every target driver, rewrite the API so that we have simple register/unregister functions that operate on a const operations vector. This patch also fixes a memory leak in several target drivers. Several target drivers namely called target_fabric_configfs_deregister() without calling target_fabric_configfs_free(). A large part of this patch is based on earlier changes from Bart Van Assche <bart.vanassche@sandisk.com>. (v2: Add a new TF_CIT_SETUP_DRV macro so that the core configfs code can declare attributes as either core only or for drivers) Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'drivers/target/loopback/tcm_loop.c')
-rw-r--r--drivers/target/loopback/tcm_loop.c178
1 files changed, 49 insertions, 129 deletions
diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c
index 2114c1d2c9de..5b143d2c08f7 100644
--- a/drivers/target/loopback/tcm_loop.c
+++ b/drivers/target/loopback/tcm_loop.c
@@ -41,8 +41,7 @@
41 41
42#define to_tcm_loop_hba(hba) container_of(hba, struct tcm_loop_hba, dev) 42#define to_tcm_loop_hba(hba) container_of(hba, struct tcm_loop_hba, dev)
43 43
44/* Local pointer to allocated TCM configfs fabric module */ 44static const struct target_core_fabric_ops loop_ops;
45static struct target_fabric_configfs *tcm_loop_fabric_configfs;
46 45
47static struct workqueue_struct *tcm_loop_workqueue; 46static struct workqueue_struct *tcm_loop_workqueue;
48static struct kmem_cache *tcm_loop_cmd_cache; 47static struct kmem_cache *tcm_loop_cmd_cache;
@@ -1238,8 +1237,7 @@ static struct se_portal_group *tcm_loop_make_naa_tpg(
1238 /* 1237 /*
1239 * Register the tl_tpg as a emulated SAS TCM Target Endpoint 1238 * Register the tl_tpg as a emulated SAS TCM Target Endpoint
1240 */ 1239 */
1241 ret = core_tpg_register(&tcm_loop_fabric_configfs->tf_ops, 1240 ret = core_tpg_register(&loop_ops, wwn, &tl_tpg->tl_se_tpg, tl_tpg,
1242 wwn, &tl_tpg->tl_se_tpg, tl_tpg,
1243 TRANSPORT_TPG_TYPE_NORMAL); 1241 TRANSPORT_TPG_TYPE_NORMAL);
1244 if (ret < 0) 1242 if (ret < 0)
1245 return ERR_PTR(-ENOMEM); 1243 return ERR_PTR(-ENOMEM);
@@ -1387,129 +1385,51 @@ static struct configfs_attribute *tcm_loop_wwn_attrs[] = {
1387 1385
1388/* End items for tcm_loop_cit */ 1386/* End items for tcm_loop_cit */
1389 1387
1390static int tcm_loop_register_configfs(void) 1388static const struct target_core_fabric_ops loop_ops = {
1391{ 1389 .module = THIS_MODULE,
1392 struct target_fabric_configfs *fabric; 1390 .name = "loopback",
1393 int ret; 1391 .get_fabric_name = tcm_loop_get_fabric_name,
1394 /* 1392 .get_fabric_proto_ident = tcm_loop_get_fabric_proto_ident,
1395 * Set the TCM Loop HBA counter to zero 1393 .tpg_get_wwn = tcm_loop_get_endpoint_wwn,
1396 */ 1394 .tpg_get_tag = tcm_loop_get_tag,
1397 tcm_loop_hba_no_cnt = 0; 1395 .tpg_get_default_depth = tcm_loop_get_default_depth,
1398 /* 1396 .tpg_get_pr_transport_id = tcm_loop_get_pr_transport_id,
1399 * Register the top level struct config_item_type with TCM core 1397 .tpg_get_pr_transport_id_len = tcm_loop_get_pr_transport_id_len,
1400 */ 1398 .tpg_parse_pr_out_transport_id = tcm_loop_parse_pr_out_transport_id,
1401 fabric = target_fabric_configfs_init(THIS_MODULE, "loopback"); 1399 .tpg_check_demo_mode = tcm_loop_check_demo_mode,
1402 if (IS_ERR(fabric)) { 1400 .tpg_check_demo_mode_cache = tcm_loop_check_demo_mode_cache,
1403 pr_err("tcm_loop_register_configfs() failed!\n"); 1401 .tpg_check_demo_mode_write_protect =
1404 return PTR_ERR(fabric); 1402 tcm_loop_check_demo_mode_write_protect,
1405 } 1403 .tpg_check_prod_mode_write_protect =
1406 /* 1404 tcm_loop_check_prod_mode_write_protect,
1407 * Setup the fabric API of function pointers used by target_core_mod 1405 .tpg_check_prot_fabric_only = tcm_loop_check_prot_fabric_only,
1408 */ 1406 .tpg_alloc_fabric_acl = tcm_loop_tpg_alloc_fabric_acl,
1409 fabric->tf_ops.get_fabric_name = &tcm_loop_get_fabric_name; 1407 .tpg_release_fabric_acl = tcm_loop_tpg_release_fabric_acl,
1410 fabric->tf_ops.get_fabric_proto_ident = &tcm_loop_get_fabric_proto_ident; 1408 .tpg_get_inst_index = tcm_loop_get_inst_index,
1411 fabric->tf_ops.tpg_get_wwn = &tcm_loop_get_endpoint_wwn; 1409 .check_stop_free = tcm_loop_check_stop_free,
1412 fabric->tf_ops.tpg_get_tag = &tcm_loop_get_tag; 1410 .release_cmd = tcm_loop_release_cmd,
1413 fabric->tf_ops.tpg_get_default_depth = &tcm_loop_get_default_depth; 1411 .shutdown_session = tcm_loop_shutdown_session,
1414 fabric->tf_ops.tpg_get_pr_transport_id = &tcm_loop_get_pr_transport_id; 1412 .close_session = tcm_loop_close_session,
1415 fabric->tf_ops.tpg_get_pr_transport_id_len = 1413 .sess_get_index = tcm_loop_sess_get_index,
1416 &tcm_loop_get_pr_transport_id_len; 1414 .write_pending = tcm_loop_write_pending,
1417 fabric->tf_ops.tpg_parse_pr_out_transport_id = 1415 .write_pending_status = tcm_loop_write_pending_status,
1418 &tcm_loop_parse_pr_out_transport_id; 1416 .set_default_node_attributes = tcm_loop_set_default_node_attributes,
1419 fabric->tf_ops.tpg_check_demo_mode = &tcm_loop_check_demo_mode; 1417 .get_task_tag = tcm_loop_get_task_tag,
1420 fabric->tf_ops.tpg_check_demo_mode_cache = 1418 .get_cmd_state = tcm_loop_get_cmd_state,
1421 &tcm_loop_check_demo_mode_cache; 1419 .queue_data_in = tcm_loop_queue_data_in,
1422 fabric->tf_ops.tpg_check_demo_mode_write_protect = 1420 .queue_status = tcm_loop_queue_status,
1423 &tcm_loop_check_demo_mode_write_protect; 1421 .queue_tm_rsp = tcm_loop_queue_tm_rsp,
1424 fabric->tf_ops.tpg_check_prod_mode_write_protect = 1422 .aborted_task = tcm_loop_aborted_task,
1425 &tcm_loop_check_prod_mode_write_protect; 1423 .fabric_make_wwn = tcm_loop_make_scsi_hba,
1426 fabric->tf_ops.tpg_check_prot_fabric_only = 1424 .fabric_drop_wwn = tcm_loop_drop_scsi_hba,
1427 &tcm_loop_check_prot_fabric_only; 1425 .fabric_make_tpg = tcm_loop_make_naa_tpg,
1428 /* 1426 .fabric_drop_tpg = tcm_loop_drop_naa_tpg,
1429 * The TCM loopback fabric module runs in demo-mode to a local 1427 .fabric_post_link = tcm_loop_port_link,
1430 * virtual SCSI device, so fabric dependent initator ACLs are 1428 .fabric_pre_unlink = tcm_loop_port_unlink,
1431 * not required. 1429 .tfc_wwn_attrs = tcm_loop_wwn_attrs,
1432 */ 1430 .tfc_tpg_base_attrs = tcm_loop_tpg_attrs,
1433 fabric->tf_ops.tpg_alloc_fabric_acl = &tcm_loop_tpg_alloc_fabric_acl; 1431 .tfc_tpg_attrib_attrs = tcm_loop_tpg_attrib_attrs,
1434 fabric->tf_ops.tpg_release_fabric_acl = 1432};
1435 &tcm_loop_tpg_release_fabric_acl;
1436 fabric->tf_ops.tpg_get_inst_index = &tcm_loop_get_inst_index;
1437 /*
1438 * Used for setting up remaining TCM resources in process context
1439 */
1440 fabric->tf_ops.check_stop_free = &tcm_loop_check_stop_free;
1441 fabric->tf_ops.release_cmd = &tcm_loop_release_cmd;
1442 fabric->tf_ops.shutdown_session = &tcm_loop_shutdown_session;
1443 fabric->tf_ops.close_session = &tcm_loop_close_session;
1444 fabric->tf_ops.sess_get_index = &tcm_loop_sess_get_index;
1445 fabric->tf_ops.sess_get_initiator_sid = NULL;
1446 fabric->tf_ops.write_pending = &tcm_loop_write_pending;
1447 fabric->tf_ops.write_pending_status = &tcm_loop_write_pending_status;
1448 /*
1449 * Not used for TCM loopback
1450 */
1451 fabric->tf_ops.set_default_node_attributes =
1452 &tcm_loop_set_default_node_attributes;
1453 fabric->tf_ops.get_task_tag = &tcm_loop_get_task_tag;
1454 fabric->tf_ops.get_cmd_state = &tcm_loop_get_cmd_state;
1455 fabric->tf_ops.queue_data_in = &tcm_loop_queue_data_in;
1456 fabric->tf_ops.queue_status = &tcm_loop_queue_status;
1457 fabric->tf_ops.queue_tm_rsp = &tcm_loop_queue_tm_rsp;
1458 fabric->tf_ops.aborted_task = &tcm_loop_aborted_task;
1459
1460 /*
1461 * Setup function pointers for generic logic in target_core_fabric_configfs.c
1462 */
1463 fabric->tf_ops.fabric_make_wwn = &tcm_loop_make_scsi_hba;
1464 fabric->tf_ops.fabric_drop_wwn = &tcm_loop_drop_scsi_hba;
1465 fabric->tf_ops.fabric_make_tpg = &tcm_loop_make_naa_tpg;
1466 fabric->tf_ops.fabric_drop_tpg = &tcm_loop_drop_naa_tpg;
1467 /*
1468 * fabric_post_link() and fabric_pre_unlink() are used for
1469 * registration and release of TCM Loop Virtual SCSI LUNs.
1470 */
1471 fabric->tf_ops.fabric_post_link = &tcm_loop_port_link;
1472 fabric->tf_ops.fabric_pre_unlink = &tcm_loop_port_unlink;
1473 fabric->tf_ops.fabric_make_np = NULL;
1474 fabric->tf_ops.fabric_drop_np = NULL;
1475 /*
1476 * Setup default attribute lists for various fabric->tf_cit_tmpl
1477 */
1478 fabric->tf_cit_tmpl.tfc_wwn_cit.ct_attrs = tcm_loop_wwn_attrs;
1479 fabric->tf_cit_tmpl.tfc_tpg_base_cit.ct_attrs = tcm_loop_tpg_attrs;
1480 fabric->tf_cit_tmpl.tfc_tpg_attrib_cit.ct_attrs = tcm_loop_tpg_attrib_attrs;
1481 fabric->tf_cit_tmpl.tfc_tpg_param_cit.ct_attrs = NULL;
1482 fabric->tf_cit_tmpl.tfc_tpg_np_base_cit.ct_attrs = NULL;
1483 /*
1484 * Once fabric->tf_ops has been setup, now register the fabric for
1485 * use within TCM
1486 */
1487 ret = target_fabric_configfs_register(fabric);
1488 if (ret < 0) {
1489 pr_err("target_fabric_configfs_register() for"
1490 " TCM_Loop failed!\n");
1491 target_fabric_configfs_free(fabric);
1492 return -1;
1493 }
1494 /*
1495 * Setup our local pointer to *fabric.
1496 */
1497 tcm_loop_fabric_configfs = fabric;
1498 pr_debug("TCM_LOOP[0] - Set fabric ->"
1499 " tcm_loop_fabric_configfs\n");
1500 return 0;
1501}
1502
1503static void tcm_loop_deregister_configfs(void)
1504{
1505 if (!tcm_loop_fabric_configfs)
1506 return;
1507
1508 target_fabric_configfs_deregister(tcm_loop_fabric_configfs);
1509 tcm_loop_fabric_configfs = NULL;
1510 pr_debug("TCM_LOOP[0] - Cleared"
1511 " tcm_loop_fabric_configfs\n");
1512}
1513 1433
1514static int __init tcm_loop_fabric_init(void) 1434static int __init tcm_loop_fabric_init(void)
1515{ 1435{
@@ -1533,7 +1453,7 @@ static int __init tcm_loop_fabric_init(void)
1533 if (ret) 1453 if (ret)
1534 goto out_destroy_cache; 1454 goto out_destroy_cache;
1535 1455
1536 ret = tcm_loop_register_configfs(); 1456 ret = target_register_template(&loop_ops);
1537 if (ret) 1457 if (ret)
1538 goto out_release_core_bus; 1458 goto out_release_core_bus;
1539 1459
@@ -1551,7 +1471,7 @@ out:
1551 1471
1552static void __exit tcm_loop_fabric_exit(void) 1472static void __exit tcm_loop_fabric_exit(void)
1553{ 1473{
1554 tcm_loop_deregister_configfs(); 1474 target_unregister_template(&loop_ops);
1555 tcm_loop_release_core_bus(); 1475 tcm_loop_release_core_bus();
1556 kmem_cache_destroy(tcm_loop_cmd_cache); 1476 kmem_cache_destroy(tcm_loop_cmd_cache);
1557 destroy_workqueue(tcm_loop_workqueue); 1477 destroy_workqueue(tcm_loop_workqueue);