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

Configure Feed

Select the types of activity you want to include in your feed.

Merge git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending

Pull target updates from Nicholas Bellinger:
"This series contains post merge qla_target.c / tcm_qla2xxx bugfixes
from the past weeks, including the patch to allow target-core to use
an optional session shutdown callback to help address an active I/O
shutdown bug in tcm_qla2xxx code (Joern).

Also included is a target regression bugfix releated to explict ALUA
target port group CDB emulation that is CC'ed to stable (Roland)."

* git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending:
qla2xxx: Remove version.h header file inclusion
tcm_qla2xxx: Handle malformed wwn strings properly
tcm_qla2xxx: tcm_qla2xxx_handle_tmr() can be static
qla2xxx: Don't leak commands we give up on in qlt_do_work()
qla2xxx: Don't crash if we can't find cmd for failed CTIO
tcm_qla2xxx: Don't insert nacls without sessions into the btree
target: Return error to initiator if SET TARGET PORT GROUPS emulation fails
tcm_qla2xxx: Clear session s_id + loop_id earlier during shutdown
tcm_qla2xxx: Convert to TFO->put_session() usage
target: Add TFO->put_session() caller for HW fabric session shutdown

+74 -104
+5 -6
drivers/scsi/qla2xxx/qla_target.c
··· 26 26 #include <linux/module.h> 27 27 #include <linux/init.h> 28 28 #include <linux/types.h> 29 - #include <linux/version.h> 30 29 #include <linux/blkdev.h> 31 30 #include <linux/interrupt.h> 32 31 #include <linux/pci.h> ··· 2476 2477 } 2477 2478 2478 2479 cmd = qlt_ctio_to_cmd(vha, handle, ctio); 2479 - if (cmd == NULL) { 2480 - if (status != CTIO_SUCCESS) 2481 - qlt_term_ctio_exchange(vha, ctio, NULL, status); 2480 + if (cmd == NULL) 2482 2481 return; 2483 - } 2482 + 2484 2483 se_cmd = &cmd->se_cmd; 2485 2484 tfo = se_cmd->se_tfo; 2486 2485 ··· 2724 2727 out_term: 2725 2728 ql_dbg(ql_dbg_tgt_mgt, vha, 0xf020, "Terminating work cmd %p", cmd); 2726 2729 /* 2727 - * cmd has not sent to target yet, so pass NULL as the second argument 2730 + * cmd has not sent to target yet, so pass NULL as the second 2731 + * argument to qlt_send_term_exchange() and free the memory here. 2728 2732 */ 2729 2733 spin_lock_irqsave(&ha->hardware_lock, flags); 2730 2734 qlt_send_term_exchange(vha, NULL, &cmd->atio, 1); 2735 + kmem_cache_free(qla_tgt_cmd_cachep, cmd); 2731 2736 spin_unlock_irqrestore(&ha->hardware_lock, flags); 2732 2737 if (sess) 2733 2738 ha->tgt.tgt_ops->put_sess(sess);
-1
drivers/scsi/qla2xxx/qla_target.h
··· 919 919 #define QLA_TGT_XMIT_STATUS 2 920 920 #define QLA_TGT_XMIT_ALL (QLA_TGT_XMIT_STATUS|QLA_TGT_XMIT_DATA) 921 921 922 - #include <linux/version.h> 923 922 924 923 extern struct qla_tgt_data qla_target; 925 924 /*
+58 -94
drivers/scsi/qla2xxx/tcm_qla2xxx.c
··· 137 137 */ 138 138 static int tcm_qla2xxx_npiv_extract_wwn(const char *ns, u64 *nm) 139 139 { 140 - unsigned int i, j, value; 140 + unsigned int i, j; 141 141 u8 wwn[8]; 142 142 143 143 memset(wwn, 0, sizeof(wwn)); 144 144 145 145 /* Validate and store the new name */ 146 146 for (i = 0, j = 0; i < 16; i++) { 147 + int value; 148 + 147 149 value = hex_to_bin(*ns++); 148 150 if (value >= 0) 149 151 j = (j << 4) | value; ··· 654 652 /* 655 653 * Called from qla_target.c:qlt_issue_task_mgmt() 656 654 */ 657 - int tcm_qla2xxx_handle_tmr(struct qla_tgt_mgmt_cmd *mcmd, uint32_t lun, 658 - uint8_t tmr_func, uint32_t tag) 655 + static int tcm_qla2xxx_handle_tmr(struct qla_tgt_mgmt_cmd *mcmd, uint32_t lun, 656 + uint8_t tmr_func, uint32_t tag) 659 657 { 660 658 struct qla_tgt_sess *sess = mcmd->sess; 661 659 struct se_cmd *se_cmd = &mcmd->se_cmd; ··· 764 762 struct target_fabric_configfs *tcm_qla2xxx_fabric_configfs; 765 763 struct target_fabric_configfs *tcm_qla2xxx_npiv_fabric_configfs; 766 764 767 - static int tcm_qla2xxx_setup_nacl_from_rport( 768 - struct se_portal_group *se_tpg, 769 - struct se_node_acl *se_nacl, 770 - struct tcm_qla2xxx_lport *lport, 771 - struct tcm_qla2xxx_nacl *nacl, 772 - u64 rport_wwnn) 773 - { 774 - struct scsi_qla_host *vha = lport->qla_vha; 775 - struct Scsi_Host *sh = vha->host; 776 - struct fc_host_attrs *fc_host = shost_to_fc_host(sh); 777 - struct fc_rport *rport; 778 - unsigned long flags; 779 - void *node; 780 - int rc; 781 - 782 - /* 783 - * Scan the existing rports, and create a session for the 784 - * explict NodeACL is an matching rport->node_name already 785 - * exists. 786 - */ 787 - spin_lock_irqsave(sh->host_lock, flags); 788 - list_for_each_entry(rport, &fc_host->rports, peers) { 789 - if (rport_wwnn != rport->node_name) 790 - continue; 791 - 792 - pr_debug("Located existing rport_wwpn and rport->node_name: 0x%016LX, port_id: 0x%04x\n", 793 - rport->node_name, rport->port_id); 794 - nacl->nport_id = rport->port_id; 795 - 796 - spin_unlock_irqrestore(sh->host_lock, flags); 797 - 798 - spin_lock_irqsave(&vha->hw->hardware_lock, flags); 799 - node = btree_lookup32(&lport->lport_fcport_map, rport->port_id); 800 - if (node) { 801 - rc = btree_update32(&lport->lport_fcport_map, 802 - rport->port_id, se_nacl); 803 - } else { 804 - rc = btree_insert32(&lport->lport_fcport_map, 805 - rport->port_id, se_nacl, 806 - GFP_ATOMIC); 807 - } 808 - spin_unlock_irqrestore(&vha->hw->hardware_lock, flags); 809 - 810 - if (rc) { 811 - pr_err("Unable to insert se_nacl into fcport_map"); 812 - WARN_ON(rc > 0); 813 - return rc; 814 - } 815 - 816 - pr_debug("Inserted into fcport_map: %p for WWNN: 0x%016LX, port_id: 0x%08x\n", 817 - se_nacl, rport_wwnn, nacl->nport_id); 818 - 819 - return 1; 820 - } 821 - spin_unlock_irqrestore(sh->host_lock, flags); 822 - 823 - return 0; 824 - } 825 - 765 + static void tcm_qla2xxx_clear_sess_lookup(struct tcm_qla2xxx_lport *, 766 + struct tcm_qla2xxx_nacl *, struct qla_tgt_sess *); 826 767 /* 827 768 * Expected to be called with struct qla_hw_data->hardware_lock held 828 769 */ ··· 787 842 788 843 pr_debug("Removed from fcport_map: %p for WWNN: 0x%016LX, port_id: 0x%06x\n", 789 844 se_nacl, nacl->nport_wwnn, nacl->nport_id); 845 + /* 846 + * Now clear the se_nacl and session pointers from our HW lport lookup 847 + * table mapping for this initiator's fabric S_ID and LOOP_ID entries. 848 + * 849 + * This is done ahead of callbacks into tcm_qla2xxx_free_session() -> 850 + * target_wait_for_sess_cmds() before the session waits for outstanding 851 + * I/O to complete, to avoid a race between session shutdown execution 852 + * and incoming ATIOs or TMRs picking up a stale se_node_act reference. 853 + */ 854 + tcm_qla2xxx_clear_sess_lookup(lport, nacl, sess); 855 + } 856 + 857 + static void tcm_qla2xxx_release_session(struct kref *kref) 858 + { 859 + struct se_session *se_sess = container_of(kref, 860 + struct se_session, sess_kref); 861 + 862 + qlt_unreg_sess(se_sess->fabric_sess_ptr); 863 + } 864 + 865 + static void tcm_qla2xxx_put_session(struct se_session *se_sess) 866 + { 867 + struct qla_tgt_sess *sess = se_sess->fabric_sess_ptr; 868 + struct qla_hw_data *ha = sess->vha->hw; 869 + unsigned long flags; 870 + 871 + spin_lock_irqsave(&ha->hardware_lock, flags); 872 + kref_put(&se_sess->sess_kref, tcm_qla2xxx_release_session); 873 + spin_unlock_irqrestore(&ha->hardware_lock, flags); 790 874 } 791 875 792 876 static void tcm_qla2xxx_put_sess(struct qla_tgt_sess *sess) 793 877 { 794 - target_put_session(sess->se_sess); 878 + tcm_qla2xxx_put_session(sess->se_sess); 795 879 } 796 880 797 881 static void tcm_qla2xxx_shutdown_sess(struct qla_tgt_sess *sess) ··· 833 859 struct config_group *group, 834 860 const char *name) 835 861 { 836 - struct se_wwn *se_wwn = se_tpg->se_tpg_wwn; 837 - struct tcm_qla2xxx_lport *lport = container_of(se_wwn, 838 - struct tcm_qla2xxx_lport, lport_wwn); 839 862 struct se_node_acl *se_nacl, *se_nacl_new; 840 863 struct tcm_qla2xxx_nacl *nacl; 841 864 u64 wwnn; 842 865 u32 qla2xxx_nexus_depth; 843 - int rc; 844 866 845 867 if (tcm_qla2xxx_parse_wwn(name, &wwnn, 1) < 0) 846 868 return ERR_PTR(-EINVAL); ··· 863 893 nacl = container_of(se_nacl, struct tcm_qla2xxx_nacl, se_node_acl); 864 894 nacl->nport_wwnn = wwnn; 865 895 tcm_qla2xxx_format_wwn(&nacl->nport_name[0], TCM_QLA2XXX_NAMELEN, wwnn); 866 - /* 867 - * Setup a se_nacl handle based on an a matching struct fc_rport setup 868 - * via drivers/scsi/qla2xxx/qla_init.c:qla2x00_reg_remote_port() 869 - */ 870 - rc = tcm_qla2xxx_setup_nacl_from_rport(se_tpg, se_nacl, lport, 871 - nacl, wwnn); 872 - if (rc < 0) { 873 - tcm_qla2xxx_release_fabric_acl(se_tpg, se_nacl_new); 874 - return ERR_PTR(rc); 875 - } 876 896 877 897 return se_nacl; 878 898 } ··· 1350 1390 nacl->qla_tgt_sess, new_se_nacl, new_se_nacl->initiatorname); 1351 1391 } 1352 1392 1393 + /* 1394 + * Should always be called with qla_hw_data->hardware_lock held. 1395 + */ 1396 + static void tcm_qla2xxx_clear_sess_lookup(struct tcm_qla2xxx_lport *lport, 1397 + struct tcm_qla2xxx_nacl *nacl, struct qla_tgt_sess *sess) 1398 + { 1399 + struct se_session *se_sess = sess->se_sess; 1400 + unsigned char be_sid[3]; 1401 + 1402 + be_sid[0] = sess->s_id.b.domain; 1403 + be_sid[1] = sess->s_id.b.area; 1404 + be_sid[2] = sess->s_id.b.al_pa; 1405 + 1406 + tcm_qla2xxx_set_sess_by_s_id(lport, NULL, nacl, se_sess, 1407 + sess, be_sid); 1408 + tcm_qla2xxx_set_sess_by_loop_id(lport, NULL, nacl, se_sess, 1409 + sess, sess->loop_id); 1410 + } 1411 + 1353 1412 static void tcm_qla2xxx_free_session(struct qla_tgt_sess *sess) 1354 1413 { 1355 1414 struct qla_tgt *tgt = sess->tgt; ··· 1377 1398 struct se_node_acl *se_nacl; 1378 1399 struct tcm_qla2xxx_lport *lport; 1379 1400 struct tcm_qla2xxx_nacl *nacl; 1380 - unsigned char be_sid[3]; 1381 - unsigned long flags; 1382 1401 1383 1402 BUG_ON(in_interrupt()); 1384 1403 ··· 1396 1419 return; 1397 1420 } 1398 1421 target_wait_for_sess_cmds(se_sess, 0); 1399 - /* 1400 - * And now clear the se_nacl and session pointers from our HW lport 1401 - * mappings for fabric S_ID and LOOP_ID. 1402 - */ 1403 - memset(&be_sid, 0, 3); 1404 - be_sid[0] = sess->s_id.b.domain; 1405 - be_sid[1] = sess->s_id.b.area; 1406 - be_sid[2] = sess->s_id.b.al_pa; 1407 - 1408 - spin_lock_irqsave(&ha->hardware_lock, flags); 1409 - tcm_qla2xxx_set_sess_by_s_id(lport, NULL, nacl, se_sess, 1410 - sess, be_sid); 1411 - tcm_qla2xxx_set_sess_by_loop_id(lport, NULL, nacl, se_sess, 1412 - sess, sess->loop_id); 1413 - spin_unlock_irqrestore(&ha->hardware_lock, flags); 1414 1422 1415 1423 transport_deregister_session_configfs(sess->se_sess); 1416 1424 transport_deregister_session(sess->se_sess); ··· 1693 1731 .new_cmd_map = NULL, 1694 1732 .check_stop_free = tcm_qla2xxx_check_stop_free, 1695 1733 .release_cmd = tcm_qla2xxx_release_cmd, 1734 + .put_session = tcm_qla2xxx_put_session, 1696 1735 .shutdown_session = tcm_qla2xxx_shutdown_session, 1697 1736 .close_session = tcm_qla2xxx_close_session, 1698 1737 .sess_get_index = tcm_qla2xxx_sess_get_index, ··· 1742 1779 .tpg_release_fabric_acl = tcm_qla2xxx_release_fabric_acl, 1743 1780 .tpg_get_inst_index = tcm_qla2xxx_tpg_get_inst_index, 1744 1781 .release_cmd = tcm_qla2xxx_release_cmd, 1782 + .put_session = tcm_qla2xxx_put_session, 1745 1783 .shutdown_session = tcm_qla2xxx_shutdown_session, 1746 1784 .close_session = tcm_qla2xxx_close_session, 1747 1785 .sess_get_index = tcm_qla2xxx_sess_get_index,
+3 -2
drivers/target/target_core_alua.c
··· 374 374 375 375 out: 376 376 transport_kunmap_data_sg(cmd); 377 - target_complete_cmd(cmd, GOOD); 378 - return 0; 377 + if (!rc) 378 + target_complete_cmd(cmd, GOOD); 379 + return rc; 379 380 } 380 381 381 382 static inline int core_alua_state_nonoptimized(
+7 -1
drivers/target/target_core_transport.c
··· 315 315 } 316 316 EXPORT_SYMBOL(transport_register_session); 317 317 318 - static void target_release_session(struct kref *kref) 318 + void target_release_session(struct kref *kref) 319 319 { 320 320 struct se_session *se_sess = container_of(kref, 321 321 struct se_session, sess_kref); ··· 332 332 333 333 void target_put_session(struct se_session *se_sess) 334 334 { 335 + struct se_portal_group *tpg = se_sess->se_tpg; 336 + 337 + if (tpg->se_tpg_tfo->put_session != NULL) { 338 + tpg->se_tpg_tfo->put_session(se_sess); 339 + return; 340 + } 335 341 kref_put(&se_sess->sess_kref, target_release_session); 336 342 } 337 343 EXPORT_SYMBOL(target_put_session);
+1
include/target/target_core_fabric.h
··· 47 47 */ 48 48 int (*check_stop_free)(struct se_cmd *); 49 49 void (*release_cmd)(struct se_cmd *); 50 + void (*put_session)(struct se_session *); 50 51 /* 51 52 * Called with spin_lock_bh(struct se_portal_group->session_lock held. 52 53 */