Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge patch series "add virtual remote fabric"

Dmitry Bogdanov <d.bogdanov@yadro.com> says:

The patchset is based on 6.4/scsi-staging branch.

The first 11 patches are just a refactoring to reduce code duplication
in fabric drivers. They make several callouts be optional in fabric
ops. Make a default implementation of the optional ops and remove
such implementations in the fabric drivers.

The last patch is a new virtual remote fabric driver. It has a
valueble sence with patchset "scsi: target: make RTPI an TPG
identifier" to configure RPTI on remote/tpgt_x same as on tpgt_y on
other nodes in a storage cluster. That allows to report the same ports
in RTPG from each node and to have a clusterwide tpg/acl/lun view in
kernel.

Link: https://lore.kernel.org/r/20230313181110.20566-1-d.bogdanov@yadro.com
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>

+361 -315
-33
drivers/infiniband/ulp/srpt/ib_srpt.c
··· 3300 3300 return 1; 3301 3301 } 3302 3302 3303 - static int srpt_check_false(struct se_portal_group *se_tpg) 3304 - { 3305 - return 0; 3306 - } 3307 - 3308 3303 static struct srpt_port *srpt_tpg_to_sport(struct se_portal_group *tpg) 3309 3304 { 3310 3305 return tpg->se_tpg_wwn->priv; ··· 3325 3330 } 3326 3331 3327 3332 static u16 srpt_get_tag(struct se_portal_group *tpg) 3328 - { 3329 - return 1; 3330 - } 3331 - 3332 - static u32 srpt_tpg_get_inst_index(struct se_portal_group *se_tpg) 3333 3333 { 3334 3334 return 1; 3335 3335 } ··· 3366 3376 struct srpt_rdma_ch *ch = se_sess->fabric_sess_ptr; 3367 3377 3368 3378 srpt_disconnect_ch_sync(ch); 3369 - } 3370 - 3371 - /** 3372 - * srpt_sess_get_index - return the value of scsiAttIntrPortIndex (SCSI-MIB) 3373 - * @se_sess: SCSI target session. 3374 - * 3375 - * A quote from RFC 4455 (SCSI-MIB) about this MIB object: 3376 - * This object represents an arbitrary integer used to uniquely identify a 3377 - * particular attached remote initiator port to a particular SCSI target port 3378 - * within a particular SCSI target device within a particular SCSI instance. 3379 - */ 3380 - static u32 srpt_sess_get_index(struct se_session *se_sess) 3381 - { 3382 - return 0; 3383 - } 3384 - 3385 - static void srpt_set_default_node_attrs(struct se_node_acl *nacl) 3386 - { 3387 3379 } 3388 3380 3389 3381 /* Note: only used from inside debug printk's by the TCM core. */ ··· 3838 3866 .fabric_name = "srpt", 3839 3867 .tpg_get_wwn = srpt_get_fabric_wwn, 3840 3868 .tpg_get_tag = srpt_get_tag, 3841 - .tpg_check_demo_mode = srpt_check_false, 3842 3869 .tpg_check_demo_mode_cache = srpt_check_true, 3843 3870 .tpg_check_demo_mode_write_protect = srpt_check_true, 3844 - .tpg_check_prod_mode_write_protect = srpt_check_false, 3845 - .tpg_get_inst_index = srpt_tpg_get_inst_index, 3846 3871 .release_cmd = srpt_release_cmd, 3847 3872 .check_stop_free = srpt_check_stop_free, 3848 3873 .close_session = srpt_close_session, 3849 - .sess_get_index = srpt_sess_get_index, 3850 3874 .sess_get_initiator_sid = NULL, 3851 3875 .write_pending = srpt_write_pending, 3852 - .set_default_node_attributes = srpt_set_default_node_attrs, 3853 3876 .get_cmd_state = srpt_get_tcm_cmd_state, 3854 3877 .queue_data_in = srpt_queue_data_in, 3855 3878 .queue_status = srpt_queue_status,
-20
drivers/scsi/elx/efct/efct_lio.c
··· 285 285 return tpg->tpg_attrib.prod_mode_write_protect; 286 286 } 287 287 288 - static u32 efct_lio_tpg_get_inst_index(struct se_portal_group *se_tpg) 289 - { 290 - return 1; 291 - } 292 - 293 288 static int efct_lio_check_stop_free(struct se_cmd *se_cmd) 294 289 { 295 290 struct efct_scsi_tgt_io *ocp = ··· 348 353 } 349 354 350 355 efc_node_post_shutdown(node, NULL); 351 - } 352 - 353 - static u32 efct_lio_sess_get_index(struct se_session *se_sess) 354 - { 355 - return 0; 356 - } 357 - 358 - static void efct_lio_set_default_node_attrs(struct se_node_acl *nacl) 359 - { 360 356 } 361 357 362 358 static int efct_lio_get_cmd_state(struct se_cmd *cmd) ··· 1593 1607 .tpg_check_demo_mode_cache = efct_lio_check_demo_mode_cache, 1594 1608 .tpg_check_demo_mode_write_protect = efct_lio_check_demo_write_protect, 1595 1609 .tpg_check_prod_mode_write_protect = efct_lio_check_prod_write_protect, 1596 - .tpg_get_inst_index = efct_lio_tpg_get_inst_index, 1597 1610 .check_stop_free = efct_lio_check_stop_free, 1598 1611 .aborted_task = efct_lio_aborted_task, 1599 1612 .release_cmd = efct_lio_release_cmd, 1600 1613 .close_session = efct_lio_close_session, 1601 - .sess_get_index = efct_lio_sess_get_index, 1602 1614 .write_pending = efct_lio_write_pending, 1603 - .set_default_node_attributes = efct_lio_set_default_node_attrs, 1604 1615 .get_cmd_state = efct_lio_get_cmd_state, 1605 1616 .queue_data_in = efct_lio_queue_data_in, 1606 1617 .queue_status = efct_lio_queue_status, ··· 1627 1644 efct_lio_npiv_check_demo_write_protect, 1628 1645 .tpg_check_prod_mode_write_protect = 1629 1646 efct_lio_npiv_check_prod_write_protect, 1630 - .tpg_get_inst_index = efct_lio_tpg_get_inst_index, 1631 1647 .check_stop_free = efct_lio_check_stop_free, 1632 1648 .aborted_task = efct_lio_aborted_task, 1633 1649 .release_cmd = efct_lio_release_cmd, 1634 1650 .close_session = efct_lio_close_session, 1635 - .sess_get_index = efct_lio_sess_get_index, 1636 1651 .write_pending = efct_lio_write_pending, 1637 - .set_default_node_attributes = efct_lio_set_default_node_attrs, 1638 1652 .get_cmd_state = efct_lio_get_cmd_state, 1639 1653 .queue_data_in = efct_lio_queue_data_in, 1640 1654 .queue_status = efct_lio_queue_status,
-30
drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
··· 3698 3698 return 1; 3699 3699 } 3700 3700 3701 - static int ibmvscsis_check_false(struct se_portal_group *se_tpg) 3702 - { 3703 - return 0; 3704 - } 3705 - 3706 - static u32 ibmvscsis_tpg_get_inst_index(struct se_portal_group *se_tpg) 3707 - { 3708 - return 1; 3709 - } 3710 - 3711 3701 static int ibmvscsis_check_stop_free(struct se_cmd *se_cmd) 3712 3702 { 3713 3703 return target_put_sess_cmd(se_cmd); ··· 3714 3724 list_move_tail(&cmd->list, &vscsi->waiting_rsp); 3715 3725 ibmvscsis_send_messages(vscsi); 3716 3726 spin_unlock_bh(&vscsi->intr_lock); 3717 - } 3718 - 3719 - static u32 ibmvscsis_sess_get_index(struct se_session *se_sess) 3720 - { 3721 - return 0; 3722 3727 } 3723 3728 3724 3729 static int ibmvscsis_write_pending(struct se_cmd *se_cmd) ··· 3747 3762 * object execution queue. 3748 3763 */ 3749 3764 target_execute_cmd(se_cmd); 3750 - return 0; 3751 - } 3752 - 3753 - static void ibmvscsis_set_default_node_attrs(struct se_node_acl *nacl) 3754 - { 3755 - } 3756 - 3757 - static int ibmvscsis_get_cmd_state(struct se_cmd *se_cmd) 3758 - { 3759 3765 return 0; 3760 3766 } 3761 3767 ··· 3958 3982 .tpg_get_default_depth = ibmvscsis_get_default_depth, 3959 3983 .tpg_check_demo_mode = ibmvscsis_check_true, 3960 3984 .tpg_check_demo_mode_cache = ibmvscsis_check_true, 3961 - .tpg_check_demo_mode_write_protect = ibmvscsis_check_false, 3962 - .tpg_check_prod_mode_write_protect = ibmvscsis_check_false, 3963 - .tpg_get_inst_index = ibmvscsis_tpg_get_inst_index, 3964 3985 .check_stop_free = ibmvscsis_check_stop_free, 3965 3986 .release_cmd = ibmvscsis_release_cmd, 3966 - .sess_get_index = ibmvscsis_sess_get_index, 3967 3987 .write_pending = ibmvscsis_write_pending, 3968 - .set_default_node_attributes = ibmvscsis_set_default_node_attrs, 3969 - .get_cmd_state = ibmvscsis_get_cmd_state, 3970 3988 .queue_data_in = ibmvscsis_queue_data_in, 3971 3989 .queue_status = ibmvscsis_queue_status, 3972 3990 .queue_tm_rsp = ibmvscsis_queue_tm_rsp,
-14
drivers/scsi/qla2xxx/tcm_qla2xxx.c
··· 377 377 tcm_qla2xxx_put_sess(sess); 378 378 } 379 379 380 - static u32 tcm_qla2xxx_sess_get_index(struct se_session *se_sess) 381 - { 382 - return 0; 383 - } 384 - 385 380 static int tcm_qla2xxx_write_pending(struct se_cmd *se_cmd) 386 381 { 387 382 struct qla_tgt_cmd *cmd = container_of(se_cmd, ··· 414 419 * the SGL mappings into PCIe memory for incoming FCP WRITE data. 415 420 */ 416 421 return qlt_rdy_to_xfer(cmd); 417 - } 418 - 419 - static void tcm_qla2xxx_set_default_node_attrs(struct se_node_acl *nacl) 420 - { 421 - return; 422 422 } 423 423 424 424 static int tcm_qla2xxx_get_cmd_state(struct se_cmd *se_cmd) ··· 1801 1811 .check_stop_free = tcm_qla2xxx_check_stop_free, 1802 1812 .release_cmd = tcm_qla2xxx_release_cmd, 1803 1813 .close_session = tcm_qla2xxx_close_session, 1804 - .sess_get_index = tcm_qla2xxx_sess_get_index, 1805 1814 .sess_get_initiator_sid = NULL, 1806 1815 .write_pending = tcm_qla2xxx_write_pending, 1807 - .set_default_node_attributes = tcm_qla2xxx_set_default_node_attrs, 1808 1816 .get_cmd_state = tcm_qla2xxx_get_cmd_state, 1809 1817 .queue_data_in = tcm_qla2xxx_queue_data_in, 1810 1818 .queue_status = tcm_qla2xxx_queue_status, ··· 1840 1852 .check_stop_free = tcm_qla2xxx_check_stop_free, 1841 1853 .release_cmd = tcm_qla2xxx_release_cmd, 1842 1854 .close_session = tcm_qla2xxx_close_session, 1843 - .sess_get_index = tcm_qla2xxx_sess_get_index, 1844 1855 .sess_get_initiator_sid = NULL, 1845 1856 .write_pending = tcm_qla2xxx_write_pending, 1846 - .set_default_node_attributes = tcm_qla2xxx_set_default_node_attrs, 1847 1857 .get_cmd_state = tcm_qla2xxx_get_cmd_state, 1848 1858 .queue_data_in = tcm_qla2xxx_queue_data_in, 1849 1859 .queue_status = tcm_qla2xxx_queue_status,
+1
drivers/target/Kconfig
··· 47 47 source "drivers/target/tcm_fc/Kconfig" 48 48 source "drivers/target/iscsi/Kconfig" 49 49 source "drivers/target/sbp/Kconfig" 50 + source "drivers/target/tcm_remote/Kconfig" 50 51 51 52 endif
+1
drivers/target/Makefile
··· 30 30 obj-$(CONFIG_TCM_FC) += tcm_fc/ 31 31 obj-$(CONFIG_ISCSI_TARGET) += iscsi/ 32 32 obj-$(CONFIG_SBP_TARGET) += sbp/ 33 + obj-$(CONFIG_REMOTE_TARGET) += tcm_remote/
-41
drivers/target/loopback/tcm_loop.c
··· 480 480 return 1; 481 481 } 482 482 483 - static int tcm_loop_check_demo_mode_cache(struct se_portal_group *se_tpg) 484 - { 485 - return 0; 486 - } 487 - 488 - /* 489 - * Allow I_T Nexus full READ-WRITE access without explict Initiator Node ACLs for 490 - * local virtual Linux/SCSI LLD passthrough into VM hypervisor guest 491 - */ 492 - static int tcm_loop_check_demo_mode_write_protect(struct se_portal_group *se_tpg) 493 - { 494 - return 0; 495 - } 496 - 497 - /* 498 - * Because TCM_Loop does not use explict ACLs and MappedLUNs, this will 499 - * never be called for TCM_Loop by target_core_fabric_configfs.c code. 500 - * It has been added here as a nop for target_fabric_tf_ops_check() 501 - */ 502 - static int tcm_loop_check_prod_mode_write_protect(struct se_portal_group *se_tpg) 503 - { 504 - return 0; 505 - } 506 - 507 483 static int tcm_loop_check_prot_fabric_only(struct se_portal_group *se_tpg) 508 484 { 509 485 struct tcm_loop_tpg *tl_tpg = container_of(se_tpg, struct tcm_loop_tpg, ··· 487 511 return tl_tpg->tl_fabric_prot_type; 488 512 } 489 513 490 - static u32 tcm_loop_get_inst_index(struct se_portal_group *se_tpg) 491 - { 492 - return 1; 493 - } 494 - 495 514 static u32 tcm_loop_sess_get_index(struct se_session *se_sess) 496 515 { 497 516 return 1; 498 - } 499 - 500 - static void tcm_loop_set_default_node_attributes(struct se_node_acl *se_acl) 501 - { 502 - return; 503 517 } 504 518 505 519 static int tcm_loop_get_cmd_state(struct se_cmd *se_cmd) ··· 1090 1124 .tpg_get_wwn = tcm_loop_get_endpoint_wwn, 1091 1125 .tpg_get_tag = tcm_loop_get_tag, 1092 1126 .tpg_check_demo_mode = tcm_loop_check_demo_mode, 1093 - .tpg_check_demo_mode_cache = tcm_loop_check_demo_mode_cache, 1094 - .tpg_check_demo_mode_write_protect = 1095 - tcm_loop_check_demo_mode_write_protect, 1096 - .tpg_check_prod_mode_write_protect = 1097 - tcm_loop_check_prod_mode_write_protect, 1098 1127 .tpg_check_prot_fabric_only = tcm_loop_check_prot_fabric_only, 1099 - .tpg_get_inst_index = tcm_loop_get_inst_index, 1100 1128 .check_stop_free = tcm_loop_check_stop_free, 1101 1129 .release_cmd = tcm_loop_release_cmd, 1102 1130 .sess_get_index = tcm_loop_sess_get_index, 1103 1131 .write_pending = tcm_loop_write_pending, 1104 - .set_default_node_attributes = tcm_loop_set_default_node_attributes, 1105 1132 .get_cmd_state = tcm_loop_get_cmd_state, 1106 1133 .queue_data_in = tcm_loop_queue_data_in, 1107 1134 .queue_status = tcm_loop_queue_status,
-31
drivers/target/sbp/sbp_target.c
··· 1673 1673 return 1; 1674 1674 } 1675 1675 1676 - static int sbp_check_false(struct se_portal_group *se_tpg) 1677 - { 1678 - return 0; 1679 - } 1680 - 1681 1676 static char *sbp_get_fabric_wwn(struct se_portal_group *se_tpg) 1682 1677 { 1683 1678 struct sbp_tpg *tpg = container_of(se_tpg, struct sbp_tpg, se_tpg); ··· 1687 1692 return tpg->tport_tpgt; 1688 1693 } 1689 1694 1690 - static u32 sbp_tpg_get_inst_index(struct se_portal_group *se_tpg) 1691 - { 1692 - return 1; 1693 - } 1694 - 1695 1695 static void sbp_release_cmd(struct se_cmd *se_cmd) 1696 1696 { 1697 1697 struct sbp_target_request *req = container_of(se_cmd, 1698 1698 struct sbp_target_request, se_cmd); 1699 1699 1700 1700 sbp_free_request(req); 1701 - } 1702 - 1703 - static u32 sbp_sess_get_index(struct se_session *se_sess) 1704 - { 1705 - return 0; 1706 1701 } 1707 1702 1708 1703 static int sbp_write_pending(struct se_cmd *se_cmd) ··· 1715 1730 } 1716 1731 1717 1732 target_execute_cmd(se_cmd); 1718 - return 0; 1719 - } 1720 - 1721 - static void sbp_set_default_node_attrs(struct se_node_acl *nacl) 1722 - { 1723 - return; 1724 - } 1725 - 1726 - static int sbp_get_cmd_state(struct se_cmd *se_cmd) 1727 - { 1728 1733 return 0; 1729 1734 } 1730 1735 ··· 2256 2281 .tpg_get_tag = sbp_get_tag, 2257 2282 .tpg_check_demo_mode = sbp_check_true, 2258 2283 .tpg_check_demo_mode_cache = sbp_check_true, 2259 - .tpg_check_demo_mode_write_protect = sbp_check_false, 2260 - .tpg_check_prod_mode_write_protect = sbp_check_false, 2261 - .tpg_get_inst_index = sbp_tpg_get_inst_index, 2262 2284 .release_cmd = sbp_release_cmd, 2263 - .sess_get_index = sbp_sess_get_index, 2264 2285 .write_pending = sbp_write_pending, 2265 - .set_default_node_attributes = sbp_set_default_node_attrs, 2266 - .get_cmd_state = sbp_get_cmd_state, 2267 2286 .queue_data_in = sbp_queue_data_in, 2268 2287 .queue_status = sbp_queue_status, 2269 2288 .queue_tm_rsp = sbp_queue_tm_rsp,
+61 -33
drivers/target/target_core_configfs.c
··· 335 335 /*############################################################################## 336 336 // Start functions called by external Target Fabrics Modules 337 337 //############################################################################*/ 338 + static int target_disable_feature(struct se_portal_group *se_tpg) 339 + { 340 + return 0; 341 + } 342 + 343 + static u32 target_default_get_inst_index(struct se_portal_group *se_tpg) 344 + { 345 + return 1; 346 + } 347 + 348 + static u32 target_default_sess_get_index(struct se_session *se_sess) 349 + { 350 + return 0; 351 + } 352 + 353 + static void target_set_default_node_attributes(struct se_node_acl *se_acl) 354 + { 355 + } 356 + 357 + static int target_default_get_cmd_state(struct se_cmd *se_cmd) 358 + { 359 + return 0; 360 + } 338 361 339 362 static int target_fabric_tf_ops_check(const struct target_core_fabric_ops *tfo) 340 363 { ··· 385 362 pr_err("Missing tfo->tpg_get_tag()\n"); 386 363 return -EINVAL; 387 364 } 388 - if (!tfo->tpg_check_demo_mode) { 389 - pr_err("Missing tfo->tpg_check_demo_mode()\n"); 390 - return -EINVAL; 391 - } 392 - if (!tfo->tpg_check_demo_mode_cache) { 393 - pr_err("Missing tfo->tpg_check_demo_mode_cache()\n"); 394 - return -EINVAL; 395 - } 396 - if (!tfo->tpg_check_demo_mode_write_protect) { 397 - pr_err("Missing tfo->tpg_check_demo_mode_write_protect()\n"); 398 - return -EINVAL; 399 - } 400 - if (!tfo->tpg_check_prod_mode_write_protect) { 401 - pr_err("Missing tfo->tpg_check_prod_mode_write_protect()\n"); 402 - return -EINVAL; 403 - } 404 - if (!tfo->tpg_get_inst_index) { 405 - pr_err("Missing tfo->tpg_get_inst_index()\n"); 406 - return -EINVAL; 407 - } 408 365 if (!tfo->release_cmd) { 409 366 pr_err("Missing tfo->release_cmd()\n"); 410 367 return -EINVAL; 411 368 } 412 - if (!tfo->sess_get_index) { 413 - pr_err("Missing tfo->sess_get_index()\n"); 414 - return -EINVAL; 415 - } 416 369 if (!tfo->write_pending) { 417 370 pr_err("Missing tfo->write_pending()\n"); 418 - return -EINVAL; 419 - } 420 - if (!tfo->set_default_node_attributes) { 421 - pr_err("Missing tfo->set_default_node_attributes()\n"); 422 - return -EINVAL; 423 - } 424 - if (!tfo->get_cmd_state) { 425 - pr_err("Missing tfo->get_cmd_state()\n"); 426 371 return -EINVAL; 427 372 } 428 373 if (!tfo->queue_data_in) { ··· 438 447 return 0; 439 448 } 440 449 450 + static void target_set_default_ops(struct target_core_fabric_ops *tfo) 451 + { 452 + if (!tfo->tpg_check_demo_mode) 453 + tfo->tpg_check_demo_mode = target_disable_feature; 454 + 455 + if (!tfo->tpg_check_demo_mode_cache) 456 + tfo->tpg_check_demo_mode_cache = target_disable_feature; 457 + 458 + if (!tfo->tpg_check_demo_mode_write_protect) 459 + tfo->tpg_check_demo_mode_write_protect = target_disable_feature; 460 + 461 + if (!tfo->tpg_check_prod_mode_write_protect) 462 + tfo->tpg_check_prod_mode_write_protect = target_disable_feature; 463 + 464 + if (!tfo->tpg_get_inst_index) 465 + tfo->tpg_get_inst_index = target_default_get_inst_index; 466 + 467 + if (!tfo->sess_get_index) 468 + tfo->sess_get_index = target_default_sess_get_index; 469 + 470 + if (!tfo->set_default_node_attributes) 471 + tfo->set_default_node_attributes = target_set_default_node_attributes; 472 + 473 + if (!tfo->get_cmd_state) 474 + tfo->get_cmd_state = target_default_get_cmd_state; 475 + } 476 + 441 477 int target_register_template(const struct target_core_fabric_ops *fo) 442 478 { 479 + struct target_core_fabric_ops *tfo; 443 480 struct target_fabric_configfs *tf; 444 481 int ret; 445 482 ··· 480 461 pr_err("%s: could not allocate memory!\n", __func__); 481 462 return -ENOMEM; 482 463 } 464 + tfo = kzalloc(sizeof(struct target_core_fabric_ops), GFP_KERNEL); 465 + if (!tfo) { 466 + kfree(tf); 467 + pr_err("%s: could not allocate memory!\n", __func__); 468 + return -ENOMEM; 469 + } 470 + memcpy(tfo, fo, sizeof(*tfo)); 471 + target_set_default_ops(tfo); 483 472 484 473 INIT_LIST_HEAD(&tf->tf_list); 485 474 atomic_set(&tf->tf_access_cnt, 0); 486 - tf->tf_ops = fo; 475 + tf->tf_ops = tfo; 487 476 target_fabric_setup_cits(tf); 488 477 489 478 mutex_lock(&g_tf_lock); ··· 519 492 */ 520 493 rcu_barrier(); 521 494 kfree(t->tf_tpg_base_cit.ct_attrs); 495 + kfree(t->tf_ops); 522 496 kfree(t); 523 497 return; 524 498 }
-1
drivers/target/tcm_fc/tcm_fc.h
··· 146 146 int ft_queue_status(struct se_cmd *); 147 147 int ft_queue_data_in(struct se_cmd *); 148 148 int ft_write_pending(struct se_cmd *); 149 - int ft_get_cmd_state(struct se_cmd *); 150 149 void ft_queue_tm_resp(struct se_cmd *); 151 150 void ft_aborted_task(struct se_cmd *); 152 151
-5
drivers/target/tcm_fc/tfc_cmd.c
··· 223 223 return 0; 224 224 } 225 225 226 - int ft_get_cmd_state(struct se_cmd *se_cmd) 227 - { 228 - return 0; 229 - } 230 - 231 226 /* 232 227 * FC sequence response handler for follow-on sequences (data) and aborts. 233 228 */
-15
drivers/target/tcm_fc/tfc_conf.c
··· 398 398 return ft_tpg(se_tpg)->index; 399 399 } 400 400 401 - static int ft_check_false(struct se_portal_group *se_tpg) 402 - { 403 - return 0; 404 - } 405 - 406 - static void ft_set_default_node_attr(struct se_node_acl *se_nacl) 407 - { 408 - } 409 - 410 401 static u32 ft_tpg_get_inst_index(struct se_portal_group *se_tpg) 411 402 { 412 403 return ft_tpg(se_tpg)->index; ··· 409 418 .node_acl_size = sizeof(struct ft_node_acl), 410 419 .tpg_get_wwn = ft_get_fabric_wwn, 411 420 .tpg_get_tag = ft_get_tag, 412 - .tpg_check_demo_mode = ft_check_false, 413 - .tpg_check_demo_mode_cache = ft_check_false, 414 - .tpg_check_demo_mode_write_protect = ft_check_false, 415 - .tpg_check_prod_mode_write_protect = ft_check_false, 416 421 .tpg_get_inst_index = ft_tpg_get_inst_index, 417 422 .check_stop_free = ft_check_stop_free, 418 423 .release_cmd = ft_release_cmd, ··· 416 429 .sess_get_index = ft_sess_get_index, 417 430 .sess_get_initiator_sid = NULL, 418 431 .write_pending = ft_write_pending, 419 - .set_default_node_attributes = ft_set_default_node_attr, 420 - .get_cmd_state = ft_get_cmd_state, 421 432 .queue_data_in = ft_queue_data_in, 422 433 .queue_status = ft_queue_status, 423 434 .queue_tm_rsp = ft_queue_tm_resp,
+8
drivers/target/tcm_remote/Kconfig
··· 1 + # SPDX-License-Identifier: GPL-2.0-only 2 + config REMOTE_TARGET 3 + tristate "TCM Virtual Remote target" 4 + depends on SCSI 5 + help 6 + Say Y here to enable the TCM Virtual Remote fabric 7 + That fabric is a dummy fabric to tell TCM about configuration 8 + of TPG/ACL/LUN on peer nodes in a cluster.
+2
drivers/target/tcm_remote/Makefile
··· 1 + # SPDX-License-Identifier: GPL-2.0-only 2 + obj-$(CONFIG_REMOTE_TARGET) += tcm_remote.o
+268
drivers/target/tcm_remote/tcm_remote.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + 3 + #include <linux/module.h> 4 + #include <linux/moduleparam.h> 5 + #include <linux/init.h> 6 + #include <linux/slab.h> 7 + #include <linux/types.h> 8 + #include <linux/configfs.h> 9 + #include <scsi/scsi.h> 10 + #include <scsi/scsi_tcq.h> 11 + #include <scsi/scsi_host.h> 12 + #include <scsi/scsi_device.h> 13 + #include <scsi/scsi_cmnd.h> 14 + 15 + #include <target/target_core_base.h> 16 + #include <target/target_core_fabric.h> 17 + 18 + #include "tcm_remote.h" 19 + 20 + static inline struct tcm_remote_tpg *remote_tpg(struct se_portal_group *se_tpg) 21 + { 22 + return container_of(se_tpg, struct tcm_remote_tpg, remote_se_tpg); 23 + } 24 + 25 + static char *tcm_remote_get_endpoint_wwn(struct se_portal_group *se_tpg) 26 + { 27 + /* 28 + * Return the passed NAA identifier for the Target Port 29 + */ 30 + return &remote_tpg(se_tpg)->remote_hba->remote_wwn_address[0]; 31 + } 32 + 33 + static u16 tcm_remote_get_tag(struct se_portal_group *se_tpg) 34 + { 35 + /* 36 + * This Tag is used when forming SCSI Name identifier in EVPD=1 0x83 37 + * to represent the SCSI Target Port. 38 + */ 39 + return remote_tpg(se_tpg)->remote_tpgt; 40 + } 41 + 42 + static int tcm_remote_dummy_cmd_fn(struct se_cmd *se_cmd) 43 + { 44 + return 0; 45 + } 46 + 47 + static void tcm_remote_dummy_cmd_void_fn(struct se_cmd *se_cmd) 48 + { 49 + 50 + } 51 + 52 + static char *tcm_remote_dump_proto_id(struct tcm_remote_hba *remote_hba) 53 + { 54 + switch (remote_hba->remote_proto_id) { 55 + case SCSI_PROTOCOL_SAS: 56 + return "SAS"; 57 + case SCSI_PROTOCOL_SRP: 58 + return "SRP"; 59 + case SCSI_PROTOCOL_FCP: 60 + return "FCP"; 61 + case SCSI_PROTOCOL_ISCSI: 62 + return "iSCSI"; 63 + default: 64 + break; 65 + } 66 + 67 + return "Unknown"; 68 + } 69 + 70 + static int tcm_remote_port_link( 71 + struct se_portal_group *se_tpg, 72 + struct se_lun *lun) 73 + { 74 + pr_debug("TCM_Remote_ConfigFS: Port Link LUN %lld Successful\n", 75 + lun->unpacked_lun); 76 + return 0; 77 + } 78 + 79 + static void tcm_remote_port_unlink( 80 + struct se_portal_group *se_tpg, 81 + struct se_lun *lun) 82 + { 83 + pr_debug("TCM_Remote_ConfigFS: Port Unlink LUN %lld Successful\n", 84 + lun->unpacked_lun); 85 + } 86 + 87 + static struct se_portal_group *tcm_remote_make_tpg( 88 + struct se_wwn *wwn, 89 + const char *name) 90 + { 91 + struct tcm_remote_hba *remote_hba = container_of(wwn, 92 + struct tcm_remote_hba, remote_hba_wwn); 93 + struct tcm_remote_tpg *remote_tpg; 94 + unsigned long tpgt; 95 + int ret; 96 + 97 + if (strstr(name, "tpgt_") != name) { 98 + pr_err("Unable to locate \"tpgt_#\" directory group\n"); 99 + return ERR_PTR(-EINVAL); 100 + } 101 + if (kstrtoul(name + 5, 10, &tpgt)) 102 + return ERR_PTR(-EINVAL); 103 + 104 + if (tpgt >= TL_TPGS_PER_HBA) { 105 + pr_err("Passed tpgt: %lu exceeds TL_TPGS_PER_HBA: %u\n", 106 + tpgt, TL_TPGS_PER_HBA); 107 + return ERR_PTR(-EINVAL); 108 + } 109 + remote_tpg = &remote_hba->remote_hba_tpgs[tpgt]; 110 + remote_tpg->remote_hba = remote_hba; 111 + remote_tpg->remote_tpgt = tpgt; 112 + /* 113 + * Register the remote_tpg as a emulated TCM Target Endpoint 114 + */ 115 + ret = core_tpg_register(wwn, &remote_tpg->remote_se_tpg, 116 + remote_hba->remote_proto_id); 117 + if (ret < 0) 118 + return ERR_PTR(-ENOMEM); 119 + 120 + pr_debug("TCM_Remote_ConfigFS: Allocated Emulated %s Target Port %s,t,0x%04lx\n", 121 + tcm_remote_dump_proto_id(remote_hba), 122 + config_item_name(&wwn->wwn_group.cg_item), tpgt); 123 + return &remote_tpg->remote_se_tpg; 124 + } 125 + 126 + static void tcm_remote_drop_tpg(struct se_portal_group *se_tpg) 127 + { 128 + struct se_wwn *wwn = se_tpg->se_tpg_wwn; 129 + struct tcm_remote_tpg *remote_tpg = container_of(se_tpg, 130 + struct tcm_remote_tpg, remote_se_tpg); 131 + struct tcm_remote_hba *remote_hba; 132 + unsigned short tpgt; 133 + 134 + remote_hba = remote_tpg->remote_hba; 135 + tpgt = remote_tpg->remote_tpgt; 136 + 137 + /* 138 + * Deregister the remote_tpg as a emulated TCM Target Endpoint 139 + */ 140 + core_tpg_deregister(se_tpg); 141 + 142 + remote_tpg->remote_hba = NULL; 143 + remote_tpg->remote_tpgt = 0; 144 + 145 + pr_debug("TCM_Remote_ConfigFS: Deallocated Emulated %s Target Port %s,t,0x%04x\n", 146 + tcm_remote_dump_proto_id(remote_hba), 147 + config_item_name(&wwn->wwn_group.cg_item), tpgt); 148 + } 149 + 150 + static struct se_wwn *tcm_remote_make_wwn( 151 + struct target_fabric_configfs *tf, 152 + struct config_group *group, 153 + const char *name) 154 + { 155 + struct tcm_remote_hba *remote_hba; 156 + char *ptr; 157 + int ret, off = 0; 158 + 159 + remote_hba = kzalloc(sizeof(*remote_hba), GFP_KERNEL); 160 + if (!remote_hba) 161 + return ERR_PTR(-ENOMEM); 162 + 163 + /* 164 + * Determine the emulated Protocol Identifier and Target Port Name 165 + * based on the incoming configfs directory name. 166 + */ 167 + ptr = strstr(name, "naa."); 168 + if (ptr) { 169 + remote_hba->remote_proto_id = SCSI_PROTOCOL_SAS; 170 + goto check_len; 171 + } 172 + ptr = strstr(name, "fc."); 173 + if (ptr) { 174 + remote_hba->remote_proto_id = SCSI_PROTOCOL_FCP; 175 + off = 3; /* Skip over "fc." */ 176 + goto check_len; 177 + } 178 + ptr = strstr(name, "0x"); 179 + if (ptr) { 180 + remote_hba->remote_proto_id = SCSI_PROTOCOL_SRP; 181 + off = 2; /* Skip over "0x" */ 182 + goto check_len; 183 + } 184 + ptr = strstr(name, "iqn."); 185 + if (!ptr) { 186 + pr_err("Unable to locate prefix for emulated Target Port: %s\n", 187 + name); 188 + ret = -EINVAL; 189 + goto out; 190 + } 191 + remote_hba->remote_proto_id = SCSI_PROTOCOL_ISCSI; 192 + 193 + check_len: 194 + if (strlen(name) >= TL_WWN_ADDR_LEN) { 195 + pr_err("Emulated NAA %s Address: %s, exceeds max: %d\n", 196 + name, tcm_remote_dump_proto_id(remote_hba), TL_WWN_ADDR_LEN); 197 + ret = -EINVAL; 198 + goto out; 199 + } 200 + snprintf(&remote_hba->remote_wwn_address[0], TL_WWN_ADDR_LEN, "%s", &name[off]); 201 + 202 + pr_debug("TCM_Remote_ConfigFS: Allocated emulated Target %s Address: %s\n", 203 + tcm_remote_dump_proto_id(remote_hba), name); 204 + return &remote_hba->remote_hba_wwn; 205 + out: 206 + kfree(remote_hba); 207 + return ERR_PTR(ret); 208 + } 209 + 210 + static void tcm_remote_drop_wwn(struct se_wwn *wwn) 211 + { 212 + struct tcm_remote_hba *remote_hba = container_of(wwn, 213 + struct tcm_remote_hba, remote_hba_wwn); 214 + 215 + pr_debug("TCM_Remote_ConfigFS: Deallocating emulated Target %s Address: %s\n", 216 + tcm_remote_dump_proto_id(remote_hba), 217 + remote_hba->remote_wwn_address); 218 + kfree(remote_hba); 219 + } 220 + 221 + static ssize_t tcm_remote_wwn_version_show(struct config_item *item, char *page) 222 + { 223 + return sprintf(page, "TCM Remote Fabric module %s\n", TCM_REMOTE_VERSION); 224 + } 225 + 226 + CONFIGFS_ATTR_RO(tcm_remote_wwn_, version); 227 + 228 + static struct configfs_attribute *tcm_remote_wwn_attrs[] = { 229 + &tcm_remote_wwn_attr_version, 230 + NULL, 231 + }; 232 + 233 + static const struct target_core_fabric_ops remote_ops = { 234 + .module = THIS_MODULE, 235 + .fabric_name = "remote", 236 + .tpg_get_wwn = tcm_remote_get_endpoint_wwn, 237 + .tpg_get_tag = tcm_remote_get_tag, 238 + .check_stop_free = tcm_remote_dummy_cmd_fn, 239 + .release_cmd = tcm_remote_dummy_cmd_void_fn, 240 + .write_pending = tcm_remote_dummy_cmd_fn, 241 + .queue_data_in = tcm_remote_dummy_cmd_fn, 242 + .queue_status = tcm_remote_dummy_cmd_fn, 243 + .queue_tm_rsp = tcm_remote_dummy_cmd_void_fn, 244 + .aborted_task = tcm_remote_dummy_cmd_void_fn, 245 + .fabric_make_wwn = tcm_remote_make_wwn, 246 + .fabric_drop_wwn = tcm_remote_drop_wwn, 247 + .fabric_make_tpg = tcm_remote_make_tpg, 248 + .fabric_drop_tpg = tcm_remote_drop_tpg, 249 + .fabric_post_link = tcm_remote_port_link, 250 + .fabric_pre_unlink = tcm_remote_port_unlink, 251 + .tfc_wwn_attrs = tcm_remote_wwn_attrs, 252 + }; 253 + 254 + static int __init tcm_remote_fabric_init(void) 255 + { 256 + return target_register_template(&remote_ops); 257 + } 258 + 259 + static void __exit tcm_remote_fabric_exit(void) 260 + { 261 + target_unregister_template(&remote_ops); 262 + } 263 + 264 + MODULE_DESCRIPTION("TCM virtual remote target"); 265 + MODULE_AUTHOR("Dmitry Bogdanov <d.bogdanov@yadro.com>"); 266 + MODULE_LICENSE("GPL"); 267 + module_init(tcm_remote_fabric_init); 268 + module_exit(tcm_remote_fabric_exit);
+20
drivers/target/tcm_remote/tcm_remote.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + #include <linux/types.h> 3 + #include <linux/device.h> 4 + 5 + #define TCM_REMOTE_VERSION "v0.1" 6 + #define TL_WWN_ADDR_LEN 256 7 + #define TL_TPGS_PER_HBA 32 8 + 9 + struct tcm_remote_tpg { 10 + unsigned short remote_tpgt; 11 + struct se_portal_group remote_se_tpg; 12 + struct tcm_remote_hba *remote_hba; 13 + }; 14 + 15 + struct tcm_remote_hba { 16 + u8 remote_proto_id; 17 + unsigned char remote_wwn_address[TL_WWN_ADDR_LEN]; 18 + struct tcm_remote_tpg remote_hba_tpgs[TL_TPGS_PER_HBA]; 19 + struct se_wwn remote_hba_wwn; 20 + };
-31
drivers/usb/gadget/function/f_tcm.c
··· 1253 1253 return 1; 1254 1254 } 1255 1255 1256 - static int usbg_check_false(struct se_portal_group *se_tpg) 1257 - { 1258 - return 0; 1259 - } 1260 - 1261 1256 static char *usbg_get_fabric_wwn(struct se_portal_group *se_tpg) 1262 1257 { 1263 1258 struct usbg_tpg *tpg = container_of(se_tpg, ··· 1269 1274 return tpg->tport_tpgt; 1270 1275 } 1271 1276 1272 - static u32 usbg_tpg_get_inst_index(struct se_portal_group *se_tpg) 1273 - { 1274 - return 1; 1275 - } 1276 - 1277 1277 static void usbg_release_cmd(struct se_cmd *se_cmd) 1278 1278 { 1279 1279 struct usbg_cmd *cmd = container_of(se_cmd, struct usbg_cmd, ··· 1277 1287 1278 1288 kfree(cmd->data_buf); 1279 1289 target_free_tag(se_sess, se_cmd); 1280 - } 1281 - 1282 - static u32 usbg_sess_get_index(struct se_session *se_sess) 1283 - { 1284 - return 0; 1285 - } 1286 - 1287 - static void usbg_set_default_node_attrs(struct se_node_acl *nacl) 1288 - { 1289 - } 1290 - 1291 - static int usbg_get_cmd_state(struct se_cmd *se_cmd) 1292 - { 1293 - return 0; 1294 1290 } 1295 1291 1296 1292 static void usbg_queue_tm_rsp(struct se_cmd *se_cmd) ··· 1667 1691 .tpg_get_wwn = usbg_get_fabric_wwn, 1668 1692 .tpg_get_tag = usbg_get_tag, 1669 1693 .tpg_check_demo_mode = usbg_check_true, 1670 - .tpg_check_demo_mode_cache = usbg_check_false, 1671 - .tpg_check_demo_mode_write_protect = usbg_check_false, 1672 - .tpg_check_prod_mode_write_protect = usbg_check_false, 1673 - .tpg_get_inst_index = usbg_tpg_get_inst_index, 1674 1694 .release_cmd = usbg_release_cmd, 1675 - .sess_get_index = usbg_sess_get_index, 1676 1695 .sess_get_initiator_sid = NULL, 1677 1696 .write_pending = usbg_send_write_request, 1678 - .set_default_node_attributes = usbg_set_default_node_attrs, 1679 - .get_cmd_state = usbg_get_cmd_state, 1680 1697 .queue_data_in = usbg_send_read_response, 1681 1698 .queue_status = usbg_send_status_response, 1682 1699 .queue_tm_rsp = usbg_queue_tm_rsp,
-31
drivers/vhost/scsi.c
··· 294 294 return 1; 295 295 } 296 296 297 - static int vhost_scsi_check_false(struct se_portal_group *se_tpg) 298 - { 299 - return 0; 300 - } 301 - 302 297 static char *vhost_scsi_get_fabric_wwn(struct se_portal_group *se_tpg) 303 298 { 304 299 struct vhost_scsi_tpg *tpg = container_of(se_tpg, ··· 316 321 struct vhost_scsi_tpg, se_tpg); 317 322 318 323 return tpg->tv_fabric_prot_type; 319 - } 320 - 321 - static u32 vhost_scsi_tpg_get_inst_index(struct se_portal_group *se_tpg) 322 - { 323 - return 1; 324 324 } 325 325 326 326 static void vhost_scsi_release_cmd_res(struct se_cmd *se_cmd) ··· 368 378 } 369 379 } 370 380 371 - static u32 vhost_scsi_sess_get_index(struct se_session *se_sess) 372 - { 373 - return 0; 374 - } 375 - 376 381 static int vhost_scsi_write_pending(struct se_cmd *se_cmd) 377 382 { 378 383 /* Go ahead and process the write immediately */ 379 384 target_execute_cmd(se_cmd); 380 - return 0; 381 - } 382 - 383 - static void vhost_scsi_set_default_node_attrs(struct se_node_acl *nacl) 384 - { 385 - return; 386 - } 387 - 388 - static int vhost_scsi_get_cmd_state(struct se_cmd *se_cmd) 389 - { 390 385 return 0; 391 386 } 392 387 ··· 2435 2460 .tpg_get_tag = vhost_scsi_get_tpgt, 2436 2461 .tpg_check_demo_mode = vhost_scsi_check_true, 2437 2462 .tpg_check_demo_mode_cache = vhost_scsi_check_true, 2438 - .tpg_check_demo_mode_write_protect = vhost_scsi_check_false, 2439 - .tpg_check_prod_mode_write_protect = vhost_scsi_check_false, 2440 2463 .tpg_check_prot_fabric_only = vhost_scsi_check_prot_fabric_only, 2441 - .tpg_get_inst_index = vhost_scsi_tpg_get_inst_index, 2442 2464 .release_cmd = vhost_scsi_release_cmd, 2443 2465 .check_stop_free = vhost_scsi_check_stop_free, 2444 - .sess_get_index = vhost_scsi_sess_get_index, 2445 2466 .sess_get_initiator_sid = NULL, 2446 2467 .write_pending = vhost_scsi_write_pending, 2447 - .set_default_node_attributes = vhost_scsi_set_default_node_attrs, 2448 - .get_cmd_state = vhost_scsi_get_cmd_state, 2449 2468 .queue_data_in = vhost_scsi_queue_data_in, 2450 2469 .queue_status = vhost_scsi_queue_status, 2451 2470 .queue_tm_rsp = vhost_scsi_queue_tm_rsp,
-30
drivers/xen/xen-scsiback.c
··· 1406 1406 kfree(tport); 1407 1407 } 1408 1408 1409 - static u32 scsiback_tpg_get_inst_index(struct se_portal_group *se_tpg) 1410 - { 1411 - return 1; 1412 - } 1413 - 1414 1409 static int scsiback_check_stop_free(struct se_cmd *se_cmd) 1415 1410 { 1416 1411 return transport_generic_free_cmd(se_cmd, 0); ··· 1416 1421 target_free_tag(se_cmd->se_sess, se_cmd); 1417 1422 } 1418 1423 1419 - static u32 scsiback_sess_get_index(struct se_session *se_sess) 1420 - { 1421 - return 0; 1422 - } 1423 - 1424 1424 static int scsiback_write_pending(struct se_cmd *se_cmd) 1425 1425 { 1426 1426 /* Go ahead and process the write immediately */ 1427 1427 target_execute_cmd(se_cmd); 1428 1428 1429 - return 0; 1430 - } 1431 - 1432 - static void scsiback_set_default_node_attrs(struct se_node_acl *nacl) 1433 - { 1434 - } 1435 - 1436 - static int scsiback_get_cmd_state(struct se_cmd *se_cmd) 1437 - { 1438 1429 return 0; 1439 1430 } 1440 1431 ··· 1803 1822 return 1; 1804 1823 } 1805 1824 1806 - static int scsiback_check_false(struct se_portal_group *se_tpg) 1807 - { 1808 - return 0; 1809 - } 1810 - 1811 1825 static const struct target_core_fabric_ops scsiback_ops = { 1812 1826 .module = THIS_MODULE, 1813 1827 .fabric_name = "xen-pvscsi", ··· 1810 1834 .tpg_get_tag = scsiback_get_tag, 1811 1835 .tpg_check_demo_mode = scsiback_check_true, 1812 1836 .tpg_check_demo_mode_cache = scsiback_check_true, 1813 - .tpg_check_demo_mode_write_protect = scsiback_check_false, 1814 - .tpg_check_prod_mode_write_protect = scsiback_check_false, 1815 - .tpg_get_inst_index = scsiback_tpg_get_inst_index, 1816 1837 .check_stop_free = scsiback_check_stop_free, 1817 1838 .release_cmd = scsiback_release_cmd, 1818 - .sess_get_index = scsiback_sess_get_index, 1819 1839 .sess_get_initiator_sid = NULL, 1820 1840 .write_pending = scsiback_write_pending, 1821 - .set_default_node_attributes = scsiback_set_default_node_attrs, 1822 - .get_cmd_state = scsiback_get_cmd_state, 1823 1841 .queue_data_in = scsiback_queue_data_in, 1824 1842 .queue_status = scsiback_queue_status, 1825 1843 .queue_tm_rsp = scsiback_queue_tm_rsp,