.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /******************************************************************************* |
---|
2 | 3 | * Filename: target_core_device.c (based on iscsi_target_device.c) |
---|
3 | 4 | * |
---|
.. | .. |
---|
7 | 8 | * (c) Copyright 2003-2013 Datera, Inc. |
---|
8 | 9 | * |
---|
9 | 10 | * Nicholas A. Bellinger <nab@kernel.org> |
---|
10 | | - * |
---|
11 | | - * This program is free software; you can redistribute it and/or modify |
---|
12 | | - * it under the terms of the GNU General Public License as published by |
---|
13 | | - * the Free Software Foundation; either version 2 of the License, or |
---|
14 | | - * (at your option) any later version. |
---|
15 | | - * |
---|
16 | | - * This program is distributed in the hope that it will be useful, |
---|
17 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
18 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
19 | | - * GNU General Public License for more details. |
---|
20 | | - * |
---|
21 | | - * You should have received a copy of the GNU General Public License |
---|
22 | | - * along with this program; if not, write to the Free Software |
---|
23 | | - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
---|
24 | 11 | * |
---|
25 | 12 | ******************************************************************************/ |
---|
26 | 13 | |
---|
.. | .. |
---|
58 | 45 | struct se_device *g_lun0_dev; |
---|
59 | 46 | |
---|
60 | 47 | sense_reason_t |
---|
61 | | -transport_lookup_cmd_lun(struct se_cmd *se_cmd, u64 unpacked_lun) |
---|
| 48 | +transport_lookup_cmd_lun(struct se_cmd *se_cmd) |
---|
62 | 49 | { |
---|
63 | 50 | struct se_lun *se_lun = NULL; |
---|
64 | 51 | struct se_session *se_sess = se_cmd->se_sess; |
---|
.. | .. |
---|
67 | 54 | sense_reason_t ret = TCM_NO_SENSE; |
---|
68 | 55 | |
---|
69 | 56 | rcu_read_lock(); |
---|
70 | | - deve = target_nacl_find_deve(nacl, unpacked_lun); |
---|
| 57 | + deve = target_nacl_find_deve(nacl, se_cmd->orig_fe_lun); |
---|
71 | 58 | if (deve) { |
---|
72 | 59 | atomic_long_inc(&deve->total_cmds); |
---|
73 | 60 | |
---|
.. | .. |
---|
87 | 74 | |
---|
88 | 75 | se_cmd->se_lun = se_lun; |
---|
89 | 76 | se_cmd->pr_res_key = deve->pr_res_key; |
---|
90 | | - se_cmd->orig_fe_lun = unpacked_lun; |
---|
91 | 77 | se_cmd->se_cmd_flags |= SCF_SE_LUN_CMD; |
---|
92 | 78 | se_cmd->lun_ref_active = true; |
---|
93 | 79 | |
---|
.. | .. |
---|
95 | 81 | deve->lun_access_ro) { |
---|
96 | 82 | pr_err("TARGET_CORE[%s]: Detected WRITE_PROTECTED LUN" |
---|
97 | 83 | " Access for 0x%08llx\n", |
---|
98 | | - se_cmd->se_tfo->get_fabric_name(), |
---|
99 | | - unpacked_lun); |
---|
| 84 | + se_cmd->se_tfo->fabric_name, |
---|
| 85 | + se_cmd->orig_fe_lun); |
---|
100 | 86 | rcu_read_unlock(); |
---|
101 | 87 | ret = TCM_WRITE_PROTECTED; |
---|
102 | 88 | goto ref_dev; |
---|
.. | .. |
---|
111 | 97 | * REPORT_LUNS, et al to be returned when no active |
---|
112 | 98 | * MappedLUN=0 exists for this Initiator Port. |
---|
113 | 99 | */ |
---|
114 | | - if (unpacked_lun != 0) { |
---|
| 100 | + if (se_cmd->orig_fe_lun != 0) { |
---|
115 | 101 | pr_err("TARGET_CORE[%s]: Detected NON_EXISTENT_LUN" |
---|
116 | | - " Access for 0x%08llx\n", |
---|
117 | | - se_cmd->se_tfo->get_fabric_name(), |
---|
118 | | - unpacked_lun); |
---|
| 102 | + " Access for 0x%08llx from %s\n", |
---|
| 103 | + se_cmd->se_tfo->fabric_name, |
---|
| 104 | + se_cmd->orig_fe_lun, |
---|
| 105 | + nacl->initiatorname); |
---|
119 | 106 | return TCM_NON_EXISTENT_LUN; |
---|
120 | 107 | } |
---|
121 | 108 | |
---|
122 | 109 | se_lun = se_sess->se_tpg->tpg_virt_lun0; |
---|
123 | 110 | se_cmd->se_lun = se_sess->se_tpg->tpg_virt_lun0; |
---|
124 | | - se_cmd->orig_fe_lun = 0; |
---|
125 | 111 | se_cmd->se_cmd_flags |= SCF_SE_LUN_CMD; |
---|
126 | 112 | |
---|
127 | 113 | percpu_ref_get(&se_lun->lun_ref); |
---|
.. | .. |
---|
157 | 143 | } |
---|
158 | 144 | EXPORT_SYMBOL(transport_lookup_cmd_lun); |
---|
159 | 145 | |
---|
160 | | -int transport_lookup_tmr_lun(struct se_cmd *se_cmd, u64 unpacked_lun) |
---|
| 146 | +int transport_lookup_tmr_lun(struct se_cmd *se_cmd) |
---|
161 | 147 | { |
---|
162 | 148 | struct se_dev_entry *deve; |
---|
163 | 149 | struct se_lun *se_lun = NULL; |
---|
.. | .. |
---|
167 | 153 | unsigned long flags; |
---|
168 | 154 | |
---|
169 | 155 | rcu_read_lock(); |
---|
170 | | - deve = target_nacl_find_deve(nacl, unpacked_lun); |
---|
| 156 | + deve = target_nacl_find_deve(nacl, se_cmd->orig_fe_lun); |
---|
171 | 157 | if (deve) { |
---|
172 | 158 | se_lun = rcu_dereference(deve->se_lun); |
---|
173 | 159 | |
---|
.. | .. |
---|
178 | 164 | |
---|
179 | 165 | se_cmd->se_lun = se_lun; |
---|
180 | 166 | se_cmd->pr_res_key = deve->pr_res_key; |
---|
181 | | - se_cmd->orig_fe_lun = unpacked_lun; |
---|
182 | 167 | se_cmd->se_cmd_flags |= SCF_SE_LUN_CMD; |
---|
183 | 168 | se_cmd->lun_ref_active = true; |
---|
184 | 169 | } |
---|
.. | .. |
---|
187 | 172 | |
---|
188 | 173 | if (!se_lun) { |
---|
189 | 174 | pr_debug("TARGET_CORE[%s]: Detected NON_EXISTENT_LUN" |
---|
190 | | - " Access for 0x%08llx\n", |
---|
191 | | - se_cmd->se_tfo->get_fabric_name(), |
---|
192 | | - unpacked_lun); |
---|
| 175 | + " Access for 0x%08llx for %s\n", |
---|
| 176 | + se_cmd->se_tfo->fabric_name, |
---|
| 177 | + se_cmd->orig_fe_lun, |
---|
| 178 | + nacl->initiatorname); |
---|
193 | 179 | return -ENODEV; |
---|
194 | 180 | } |
---|
195 | 181 | se_cmd->se_dev = rcu_dereference_raw(se_lun->lun_se_dev); |
---|
.. | .. |
---|
237 | 223 | if (!lun) { |
---|
238 | 224 | pr_err("%s device entries device pointer is" |
---|
239 | 225 | " NULL, but Initiator has access.\n", |
---|
240 | | - tpg->se_tpg_tfo->get_fabric_name()); |
---|
| 226 | + tpg->se_tpg_tfo->fabric_name); |
---|
241 | 227 | continue; |
---|
242 | 228 | } |
---|
243 | 229 | if (lun->lun_rtpi != rtpi) |
---|
.. | .. |
---|
404 | 390 | return 0; |
---|
405 | 391 | } |
---|
406 | 392 | |
---|
407 | | -/* |
---|
408 | | - * Called with se_node_acl->lun_entry_mutex held. |
---|
409 | | - */ |
---|
410 | 393 | void core_disable_device_list_for_node( |
---|
411 | 394 | struct se_lun *lun, |
---|
412 | 395 | struct se_dev_entry *orig, |
---|
.. | .. |
---|
418 | 401 | * reference to se_device->dev_group. |
---|
419 | 402 | */ |
---|
420 | 403 | struct se_device *dev = rcu_dereference_raw(lun->lun_se_dev); |
---|
| 404 | + |
---|
| 405 | + lockdep_assert_held(&nacl->lun_entry_mutex); |
---|
| 406 | + |
---|
421 | 407 | /* |
---|
422 | 408 | * If the MappedLUN entry is being disabled, the entry in |
---|
423 | 409 | * lun->lun_deve_list must be removed now before clearing the |
---|
.. | .. |
---|
571 | 557 | return rc; |
---|
572 | 558 | |
---|
573 | 559 | pr_debug("%s_TPG[%u]_LUN[%llu] - Activated %s Logical Unit from" |
---|
574 | | - " CORE HBA: %u\n", tpg->se_tpg_tfo->get_fabric_name(), |
---|
| 560 | + " CORE HBA: %u\n", tpg->se_tpg_tfo->fabric_name, |
---|
575 | 561 | tpg->se_tpg_tfo->tpg_get_tag(tpg), lun->unpacked_lun, |
---|
576 | | - tpg->se_tpg_tfo->get_fabric_name(), dev->se_hba->hba_id); |
---|
| 562 | + tpg->se_tpg_tfo->fabric_name, dev->se_hba->hba_id); |
---|
577 | 563 | /* |
---|
578 | 564 | * Update LUN maps for dynamically added initiators when |
---|
579 | 565 | * generate_node_acl is enabled. |
---|
.. | .. |
---|
604 | 590 | struct se_lun *lun) |
---|
605 | 591 | { |
---|
606 | 592 | pr_debug("%s_TPG[%u]_LUN[%llu] - Deactivating %s Logical Unit from" |
---|
607 | | - " device object\n", tpg->se_tpg_tfo->get_fabric_name(), |
---|
| 593 | + " device object\n", tpg->se_tpg_tfo->fabric_name, |
---|
608 | 594 | tpg->se_tpg_tfo->tpg_get_tag(tpg), lun->unpacked_lun, |
---|
609 | | - tpg->se_tpg_tfo->get_fabric_name()); |
---|
| 595 | + tpg->se_tpg_tfo->fabric_name); |
---|
610 | 596 | |
---|
611 | 597 | core_tpg_remove_lun(tpg, lun); |
---|
612 | 598 | } |
---|
.. | .. |
---|
621 | 607 | |
---|
622 | 608 | if (strlen(nacl->initiatorname) >= TRANSPORT_IQN_LEN) { |
---|
623 | 609 | pr_err("%s InitiatorName exceeds maximum size.\n", |
---|
624 | | - tpg->se_tpg_tfo->get_fabric_name()); |
---|
| 610 | + tpg->se_tpg_tfo->fabric_name); |
---|
625 | 611 | *ret = -EOVERFLOW; |
---|
626 | 612 | return NULL; |
---|
627 | 613 | } |
---|
.. | .. |
---|
664 | 650 | return -EINVAL; |
---|
665 | 651 | |
---|
666 | 652 | pr_debug("%s_TPG[%hu]_LUN[%llu->%llu] - Added %s ACL for " |
---|
667 | | - " InitiatorNode: %s\n", tpg->se_tpg_tfo->get_fabric_name(), |
---|
| 653 | + " InitiatorNode: %s\n", tpg->se_tpg_tfo->fabric_name, |
---|
668 | 654 | tpg->se_tpg_tfo->tpg_get_tag(tpg), lun->unpacked_lun, lacl->mapped_lun, |
---|
669 | 655 | lun_access_ro ? "RO" : "RW", |
---|
670 | 656 | nacl->initiatorname); |
---|
.. | .. |
---|
697 | 683 | |
---|
698 | 684 | pr_debug("%s_TPG[%hu]_LUN[%llu] - Removed ACL for" |
---|
699 | 685 | " InitiatorNode: %s Mapped LUN: %llu\n", |
---|
700 | | - tpg->se_tpg_tfo->get_fabric_name(), |
---|
| 686 | + tpg->se_tpg_tfo->fabric_name, |
---|
701 | 687 | tpg->se_tpg_tfo->tpg_get_tag(tpg), lun->unpacked_lun, |
---|
702 | 688 | nacl->initiatorname, lacl->mapped_lun); |
---|
703 | 689 | |
---|
.. | .. |
---|
709 | 695 | struct se_lun_acl *lacl) |
---|
710 | 696 | { |
---|
711 | 697 | pr_debug("%s_TPG[%hu] - Freeing ACL for %s InitiatorNode: %s" |
---|
712 | | - " Mapped LUN: %llu\n", tpg->se_tpg_tfo->get_fabric_name(), |
---|
| 698 | + " Mapped LUN: %llu\n", tpg->se_tpg_tfo->fabric_name, |
---|
713 | 699 | tpg->se_tpg_tfo->tpg_get_tag(tpg), |
---|
714 | | - tpg->se_tpg_tfo->get_fabric_name(), |
---|
| 700 | + tpg->se_tpg_tfo->fabric_name, |
---|
715 | 701 | lacl->se_lun_nacl->initiatorname, lacl->mapped_lun); |
---|
716 | 702 | |
---|
717 | 703 | kfree(lacl); |
---|
.. | .. |
---|
720 | 706 | static void scsi_dump_inquiry(struct se_device *dev) |
---|
721 | 707 | { |
---|
722 | 708 | struct t10_wwn *wwn = &dev->t10_wwn; |
---|
723 | | - char buf[17]; |
---|
724 | | - int i, device_type; |
---|
| 709 | + int device_type = dev->transport->get_device_type(dev); |
---|
| 710 | + |
---|
725 | 711 | /* |
---|
726 | 712 | * Print Linux/SCSI style INQUIRY formatting to the kernel ring buffer |
---|
727 | 713 | */ |
---|
728 | | - for (i = 0; i < 8; i++) |
---|
729 | | - if (wwn->vendor[i] >= 0x20) |
---|
730 | | - buf[i] = wwn->vendor[i]; |
---|
731 | | - else |
---|
732 | | - buf[i] = ' '; |
---|
733 | | - buf[i] = '\0'; |
---|
734 | | - pr_debug(" Vendor: %s\n", buf); |
---|
735 | | - |
---|
736 | | - for (i = 0; i < 16; i++) |
---|
737 | | - if (wwn->model[i] >= 0x20) |
---|
738 | | - buf[i] = wwn->model[i]; |
---|
739 | | - else |
---|
740 | | - buf[i] = ' '; |
---|
741 | | - buf[i] = '\0'; |
---|
742 | | - pr_debug(" Model: %s\n", buf); |
---|
743 | | - |
---|
744 | | - for (i = 0; i < 4; i++) |
---|
745 | | - if (wwn->revision[i] >= 0x20) |
---|
746 | | - buf[i] = wwn->revision[i]; |
---|
747 | | - else |
---|
748 | | - buf[i] = ' '; |
---|
749 | | - buf[i] = '\0'; |
---|
750 | | - pr_debug(" Revision: %s\n", buf); |
---|
751 | | - |
---|
752 | | - device_type = dev->transport->get_device_type(dev); |
---|
| 714 | + pr_debug(" Vendor: %-" __stringify(INQUIRY_VENDOR_LEN) "s\n", |
---|
| 715 | + wwn->vendor); |
---|
| 716 | + pr_debug(" Model: %-" __stringify(INQUIRY_MODEL_LEN) "s\n", |
---|
| 717 | + wwn->model); |
---|
| 718 | + pr_debug(" Revision: %-" __stringify(INQUIRY_REVISION_LEN) "s\n", |
---|
| 719 | + wwn->revision); |
---|
753 | 720 | pr_debug(" Type: %s ", scsi_device_type(device_type)); |
---|
754 | 721 | } |
---|
755 | 722 | |
---|
.. | .. |
---|
757 | 724 | { |
---|
758 | 725 | struct se_device *dev; |
---|
759 | 726 | struct se_lun *xcopy_lun; |
---|
| 727 | + int i; |
---|
760 | 728 | |
---|
761 | 729 | dev = hba->backend->ops->alloc_device(hba, name); |
---|
762 | 730 | if (!dev) |
---|
763 | 731 | return NULL; |
---|
764 | 732 | |
---|
| 733 | + dev->queues = kcalloc(nr_cpu_ids, sizeof(*dev->queues), GFP_KERNEL); |
---|
| 734 | + if (!dev->queues) { |
---|
| 735 | + dev->transport->free_device(dev); |
---|
| 736 | + return NULL; |
---|
| 737 | + } |
---|
| 738 | + |
---|
| 739 | + dev->queue_cnt = nr_cpu_ids; |
---|
| 740 | + for (i = 0; i < dev->queue_cnt; i++) { |
---|
| 741 | + INIT_LIST_HEAD(&dev->queues[i].state_list); |
---|
| 742 | + spin_lock_init(&dev->queues[i].lock); |
---|
| 743 | + } |
---|
| 744 | + |
---|
765 | 745 | dev->se_hba = hba; |
---|
766 | 746 | dev->transport = hba->backend->ops; |
---|
| 747 | + dev->transport_flags = dev->transport->transport_flags_default; |
---|
767 | 748 | dev->prot_length = sizeof(struct t10_pi_tuple); |
---|
768 | 749 | dev->hba_index = hba->hba_index; |
---|
769 | 750 | |
---|
770 | 751 | INIT_LIST_HEAD(&dev->dev_sep_list); |
---|
771 | 752 | INIT_LIST_HEAD(&dev->dev_tmr_list); |
---|
772 | 753 | INIT_LIST_HEAD(&dev->delayed_cmd_list); |
---|
773 | | - INIT_LIST_HEAD(&dev->state_list); |
---|
774 | 754 | INIT_LIST_HEAD(&dev->qf_cmd_list); |
---|
775 | | - spin_lock_init(&dev->execute_task_lock); |
---|
776 | 755 | spin_lock_init(&dev->delayed_cmd_lock); |
---|
777 | 756 | spin_lock_init(&dev->dev_reservation_lock); |
---|
778 | 757 | spin_lock_init(&dev->se_port_lock); |
---|
.. | .. |
---|
791 | 770 | spin_lock_init(&dev->t10_alua.lba_map_lock); |
---|
792 | 771 | |
---|
793 | 772 | INIT_WORK(&dev->delayed_cmd_work, target_do_delayed_work); |
---|
| 773 | + mutex_init(&dev->lun_reset_mutex); |
---|
794 | 774 | |
---|
795 | 775 | dev->t10_wwn.t10_dev = dev; |
---|
796 | 776 | dev->t10_alua.t10_dev = dev; |
---|
.. | .. |
---|
801 | 781 | dev->dev_attrib.emulate_fua_write = 1; |
---|
802 | 782 | dev->dev_attrib.emulate_fua_read = 1; |
---|
803 | 783 | dev->dev_attrib.emulate_write_cache = DA_EMULATE_WRITE_CACHE; |
---|
804 | | - dev->dev_attrib.emulate_ua_intlck_ctrl = DA_EMULATE_UA_INTLLCK_CTRL; |
---|
| 784 | + dev->dev_attrib.emulate_ua_intlck_ctrl = TARGET_UA_INTLCK_CTRL_CLEAR; |
---|
805 | 785 | dev->dev_attrib.emulate_tas = DA_EMULATE_TAS; |
---|
806 | 786 | dev->dev_attrib.emulate_tpu = DA_EMULATE_TPU; |
---|
807 | 787 | dev->dev_attrib.emulate_tpws = DA_EMULATE_TPWS; |
---|
808 | 788 | dev->dev_attrib.emulate_caw = DA_EMULATE_CAW; |
---|
809 | 789 | dev->dev_attrib.emulate_3pc = DA_EMULATE_3PC; |
---|
| 790 | + dev->dev_attrib.emulate_pr = DA_EMULATE_PR; |
---|
810 | 791 | dev->dev_attrib.pi_prot_type = TARGET_DIF_TYPE0_PROT; |
---|
811 | 792 | dev->dev_attrib.enforce_pr_isids = DA_ENFORCE_PR_ISIDS; |
---|
812 | 793 | dev->dev_attrib.force_pr_aptpl = DA_FORCE_PR_APTPL; |
---|
.. | .. |
---|
824 | 805 | |
---|
825 | 806 | xcopy_lun = &dev->xcopy_lun; |
---|
826 | 807 | rcu_assign_pointer(xcopy_lun->lun_se_dev, dev); |
---|
827 | | - init_completion(&xcopy_lun->lun_ref_comp); |
---|
828 | 808 | init_completion(&xcopy_lun->lun_shutdown_comp); |
---|
829 | 809 | INIT_LIST_HEAD(&xcopy_lun->lun_deve_list); |
---|
830 | 810 | INIT_LIST_HEAD(&xcopy_lun->lun_dev_link); |
---|
831 | 811 | mutex_init(&xcopy_lun->lun_tg_pt_md_mutex); |
---|
832 | 812 | xcopy_lun->lun_tpg = &xcopy_pt_tpg; |
---|
| 813 | + |
---|
| 814 | + /* Preload the default INQUIRY const values */ |
---|
| 815 | + strlcpy(dev->t10_wwn.vendor, "LIO-ORG", sizeof(dev->t10_wwn.vendor)); |
---|
| 816 | + strlcpy(dev->t10_wwn.model, dev->transport->inquiry_prod, |
---|
| 817 | + sizeof(dev->t10_wwn.model)); |
---|
| 818 | + strlcpy(dev->t10_wwn.revision, dev->transport->inquiry_rev, |
---|
| 819 | + sizeof(dev->t10_wwn.revision)); |
---|
833 | 820 | |
---|
834 | 821 | return dev; |
---|
835 | 822 | } |
---|
.. | .. |
---|
856 | 843 | attrib->unmap_granularity = q->limits.discard_granularity / block_size; |
---|
857 | 844 | attrib->unmap_granularity_alignment = q->limits.discard_alignment / |
---|
858 | 845 | block_size; |
---|
859 | | - attrib->unmap_zeroes_data = (q->limits.max_write_zeroes_sectors); |
---|
860 | 846 | return true; |
---|
861 | 847 | } |
---|
862 | 848 | EXPORT_SYMBOL(target_configure_unmap_from_queue); |
---|
.. | .. |
---|
881 | 867 | EXPORT_SYMBOL(target_to_linux_sector); |
---|
882 | 868 | |
---|
883 | 869 | struct devices_idr_iter { |
---|
884 | | - struct config_item *prev_item; |
---|
885 | 870 | int (*fn)(struct se_device *dev, void *data); |
---|
886 | 871 | void *data; |
---|
887 | 872 | }; |
---|
.. | .. |
---|
891 | 876 | { |
---|
892 | 877 | struct devices_idr_iter *iter = data; |
---|
893 | 878 | struct se_device *dev = p; |
---|
| 879 | + struct config_item *item; |
---|
894 | 880 | int ret; |
---|
895 | | - |
---|
896 | | - config_item_put(iter->prev_item); |
---|
897 | | - iter->prev_item = NULL; |
---|
898 | 881 | |
---|
899 | 882 | /* |
---|
900 | 883 | * We add the device early to the idr, so it can be used |
---|
.. | .. |
---|
905 | 888 | if (!target_dev_configured(dev)) |
---|
906 | 889 | return 0; |
---|
907 | 890 | |
---|
908 | | - iter->prev_item = config_item_get_unless_zero(&dev->dev_group.cg_item); |
---|
909 | | - if (!iter->prev_item) |
---|
| 891 | + item = config_item_get_unless_zero(&dev->dev_group.cg_item); |
---|
| 892 | + if (!item) |
---|
910 | 893 | return 0; |
---|
911 | 894 | mutex_unlock(&device_mutex); |
---|
912 | 895 | |
---|
913 | 896 | ret = iter->fn(dev, iter->data); |
---|
| 897 | + config_item_put(item); |
---|
914 | 898 | |
---|
915 | 899 | mutex_lock(&device_mutex); |
---|
916 | 900 | return ret; |
---|
.. | .. |
---|
933 | 917 | mutex_lock(&device_mutex); |
---|
934 | 918 | ret = idr_for_each(&devices_idr, target_devices_idr_iter, &iter); |
---|
935 | 919 | mutex_unlock(&device_mutex); |
---|
936 | | - config_item_put(iter.prev_item); |
---|
937 | 920 | return ret; |
---|
938 | 921 | } |
---|
939 | 922 | |
---|
.. | .. |
---|
989 | 972 | goto out_destroy_device; |
---|
990 | 973 | |
---|
991 | 974 | /* |
---|
992 | | - * Startup the struct se_device processing thread |
---|
993 | | - */ |
---|
994 | | - dev->tmr_wq = alloc_workqueue("tmr-%s", WQ_MEM_RECLAIM | WQ_UNBOUND, 1, |
---|
995 | | - dev->transport->name); |
---|
996 | | - if (!dev->tmr_wq) { |
---|
997 | | - pr_err("Unable to create tmr workqueue for %s\n", |
---|
998 | | - dev->transport->name); |
---|
999 | | - ret = -ENOMEM; |
---|
1000 | | - goto out_free_alua; |
---|
1001 | | - } |
---|
1002 | | - |
---|
1003 | | - /* |
---|
1004 | 975 | * Setup work_queue for QUEUE_FULL |
---|
1005 | 976 | */ |
---|
1006 | 977 | INIT_WORK(&dev->qf_work_queue, target_qf_do_work); |
---|
1007 | | - |
---|
1008 | | - /* |
---|
1009 | | - * Preload the initial INQUIRY const values if we are doing |
---|
1010 | | - * anything virtual (IBLOCK, FILEIO, RAMDISK), but not for TCM/pSCSI |
---|
1011 | | - * passthrough because this is being provided by the backend LLD. |
---|
1012 | | - */ |
---|
1013 | | - if (!(dev->transport->transport_flags & TRANSPORT_FLAG_PASSTHROUGH)) { |
---|
1014 | | - strncpy(&dev->t10_wwn.vendor[0], "LIO-ORG", 8); |
---|
1015 | | - strncpy(&dev->t10_wwn.model[0], |
---|
1016 | | - dev->transport->inquiry_prod, 16); |
---|
1017 | | - strncpy(&dev->t10_wwn.revision[0], |
---|
1018 | | - dev->transport->inquiry_rev, 4); |
---|
1019 | | - } |
---|
1020 | 978 | |
---|
1021 | 979 | scsi_dump_inquiry(dev); |
---|
1022 | 980 | |
---|
.. | .. |
---|
1028 | 986 | |
---|
1029 | 987 | return 0; |
---|
1030 | 988 | |
---|
1031 | | -out_free_alua: |
---|
1032 | | - core_alua_free_lu_gp_mem(dev); |
---|
1033 | 989 | out_destroy_device: |
---|
1034 | 990 | dev->transport->destroy_device(dev); |
---|
1035 | 991 | out_free_index: |
---|
.. | .. |
---|
1048 | 1004 | WARN_ON(!list_empty(&dev->dev_sep_list)); |
---|
1049 | 1005 | |
---|
1050 | 1006 | if (target_dev_configured(dev)) { |
---|
1051 | | - destroy_workqueue(dev->tmr_wq); |
---|
1052 | | - |
---|
1053 | 1007 | dev->transport->destroy_device(dev); |
---|
1054 | 1008 | |
---|
1055 | 1009 | mutex_lock(&device_mutex); |
---|
.. | .. |
---|
1069 | 1023 | if (dev->transport->free_prot) |
---|
1070 | 1024 | dev->transport->free_prot(dev); |
---|
1071 | 1025 | |
---|
| 1026 | + kfree(dev->queues); |
---|
1072 | 1027 | dev->transport->free_device(dev); |
---|
1073 | 1028 | } |
---|
1074 | 1029 | |
---|
.. | .. |
---|
1140 | 1095 | } |
---|
1141 | 1096 | |
---|
1142 | 1097 | /* |
---|
| 1098 | + * With emulate_pr disabled, all reservation requests should fail, |
---|
| 1099 | + * regardless of whether or not TRANSPORT_FLAG_PASSTHROUGH_PGR is set. |
---|
| 1100 | + */ |
---|
| 1101 | + if (!dev->dev_attrib.emulate_pr && |
---|
| 1102 | + ((cdb[0] == PERSISTENT_RESERVE_IN) || |
---|
| 1103 | + (cdb[0] == PERSISTENT_RESERVE_OUT) || |
---|
| 1104 | + (cdb[0] == RELEASE || cdb[0] == RELEASE_10) || |
---|
| 1105 | + (cdb[0] == RESERVE || cdb[0] == RESERVE_10))) { |
---|
| 1106 | + return TCM_UNSUPPORTED_SCSI_OPCODE; |
---|
| 1107 | + } |
---|
| 1108 | + |
---|
| 1109 | + /* |
---|
1143 | 1110 | * For PERSISTENT RESERVE IN/OUT, RELEASE, and RESERVE we need to |
---|
1144 | 1111 | * emulate the response, since tcmu does not have the information |
---|
1145 | 1112 | * required to process these commands. |
---|
1146 | 1113 | */ |
---|
1147 | | - if (!(dev->transport->transport_flags & |
---|
| 1114 | + if (!(dev->transport_flags & |
---|
1148 | 1115 | TRANSPORT_FLAG_PASSTHROUGH_PGR)) { |
---|
1149 | 1116 | if (cdb[0] == PERSISTENT_RESERVE_IN) { |
---|
1150 | 1117 | cmd->execute_cmd = target_scsi3_emulate_pr_in; |
---|