diff options
author | Christoph Hellwig <hch@lst.de> | 2015-04-08 14:01:35 -0400 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2015-04-14 15:28:41 -0400 |
commit | 9ac8928e6a3e1ed02e632e45aa766129fe6b1802 (patch) | |
tree | ea516680cc5f811df862966bb43cfbe3e34dfb26 /drivers/target/loopback/tcm_loop.c | |
parent | 2c336e3a2e1728d9b3116422655832184dc7046c (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.c | 178 |
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 */ | 44 | static const struct target_core_fabric_ops loop_ops; |
45 | static struct target_fabric_configfs *tcm_loop_fabric_configfs; | ||
46 | 45 | ||
47 | static struct workqueue_struct *tcm_loop_workqueue; | 46 | static struct workqueue_struct *tcm_loop_workqueue; |
48 | static struct kmem_cache *tcm_loop_cmd_cache; | 47 | static 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 | ||
1390 | static int tcm_loop_register_configfs(void) | 1388 | static 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 | |||
1503 | static 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 | ||
1514 | static int __init tcm_loop_fabric_init(void) | 1434 | static 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 | ||
1552 | static void __exit tcm_loop_fabric_exit(void) | 1472 | static 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); |