1 /******************************************************************************* 2 * This file contains the main functions related to Initiator Node Attributes. 3 * 4 * (c) Copyright 2007-2013 Datera, Inc. 5 * 6 * Author: Nicholas A. Bellinger <nab@linux-iscsi.org> 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 ******************************************************************************/ 18 19 #include <target/target_core_base.h> 20 21 #include "iscsi_target_core.h" 22 #include "iscsi_target_device.h" 23 #include "iscsi_target_tpg.h" 24 #include "iscsi_target_util.h" 25 #include "iscsi_target_nodeattrib.h" 26 27 static inline char *iscsit_na_get_initiatorname( 28 struct iscsi_node_acl *nacl) 29 { 30 struct se_node_acl *se_nacl = &nacl->se_node_acl; 31 32 return &se_nacl->initiatorname[0]; 33 } 34 35 void iscsit_set_default_node_attribues( 36 struct iscsi_node_acl *acl) 37 { 38 struct iscsi_node_attrib *a = &acl->node_attrib; 39 40 a->dataout_timeout = NA_DATAOUT_TIMEOUT; 41 a->dataout_timeout_retries = NA_DATAOUT_TIMEOUT_RETRIES; 42 a->nopin_timeout = NA_NOPIN_TIMEOUT; 43 a->nopin_response_timeout = NA_NOPIN_RESPONSE_TIMEOUT; 44 a->random_datain_pdu_offsets = NA_RANDOM_DATAIN_PDU_OFFSETS; 45 a->random_datain_seq_offsets = NA_RANDOM_DATAIN_SEQ_OFFSETS; 46 a->random_r2t_offsets = NA_RANDOM_R2T_OFFSETS; 47 a->default_erl = NA_DEFAULT_ERL; 48 } 49 50 int iscsit_na_dataout_timeout( 51 struct iscsi_node_acl *acl, 52 u32 dataout_timeout) 53 { 54 struct iscsi_node_attrib *a = &acl->node_attrib; 55 56 if (dataout_timeout > NA_DATAOUT_TIMEOUT_MAX) { 57 pr_err("Requested DataOut Timeout %u larger than" 58 " maximum %u\n", dataout_timeout, 59 NA_DATAOUT_TIMEOUT_MAX); 60 return -EINVAL; 61 } else if (dataout_timeout < NA_DATAOUT_TIMEOUT_MIX) { 62 pr_err("Requested DataOut Timeout %u smaller than" 63 " minimum %u\n", dataout_timeout, 64 NA_DATAOUT_TIMEOUT_MIX); 65 return -EINVAL; 66 } 67 68 a->dataout_timeout = dataout_timeout; 69 pr_debug("Set DataOut Timeout to %u for Initiator Node" 70 " %s\n", a->dataout_timeout, iscsit_na_get_initiatorname(acl)); 71 72 return 0; 73 } 74 75 int iscsit_na_dataout_timeout_retries( 76 struct iscsi_node_acl *acl, 77 u32 dataout_timeout_retries) 78 { 79 struct iscsi_node_attrib *a = &acl->node_attrib; 80 81 if (dataout_timeout_retries > NA_DATAOUT_TIMEOUT_RETRIES_MAX) { 82 pr_err("Requested DataOut Timeout Retries %u larger" 83 " than maximum %u", dataout_timeout_retries, 84 NA_DATAOUT_TIMEOUT_RETRIES_MAX); 85 return -EINVAL; 86 } else if (dataout_timeout_retries < NA_DATAOUT_TIMEOUT_RETRIES_MIN) { 87 pr_err("Requested DataOut Timeout Retries %u smaller" 88 " than minimum %u", dataout_timeout_retries, 89 NA_DATAOUT_TIMEOUT_RETRIES_MIN); 90 return -EINVAL; 91 } 92 93 a->dataout_timeout_retries = dataout_timeout_retries; 94 pr_debug("Set DataOut Timeout Retries to %u for" 95 " Initiator Node %s\n", a->dataout_timeout_retries, 96 iscsit_na_get_initiatorname(acl)); 97 98 return 0; 99 } 100 101 int iscsit_na_nopin_timeout( 102 struct iscsi_node_acl *acl, 103 u32 nopin_timeout) 104 { 105 struct iscsi_node_attrib *a = &acl->node_attrib; 106 struct iscsi_session *sess; 107 struct iscsi_conn *conn; 108 struct se_node_acl *se_nacl = &a->nacl->se_node_acl; 109 struct se_session *se_sess; 110 u32 orig_nopin_timeout = a->nopin_timeout; 111 112 if (nopin_timeout > NA_NOPIN_TIMEOUT_MAX) { 113 pr_err("Requested NopIn Timeout %u larger than maximum" 114 " %u\n", nopin_timeout, NA_NOPIN_TIMEOUT_MAX); 115 return -EINVAL; 116 } else if ((nopin_timeout < NA_NOPIN_TIMEOUT_MIN) && 117 (nopin_timeout != 0)) { 118 pr_err("Requested NopIn Timeout %u smaller than" 119 " minimum %u and not 0\n", nopin_timeout, 120 NA_NOPIN_TIMEOUT_MIN); 121 return -EINVAL; 122 } 123 124 a->nopin_timeout = nopin_timeout; 125 pr_debug("Set NopIn Timeout to %u for Initiator" 126 " Node %s\n", a->nopin_timeout, 127 iscsit_na_get_initiatorname(acl)); 128 /* 129 * Reenable disabled nopin_timeout timer for all iSCSI connections. 130 */ 131 if (!orig_nopin_timeout) { 132 spin_lock_bh(&se_nacl->nacl_sess_lock); 133 se_sess = se_nacl->nacl_sess; 134 if (se_sess) { 135 sess = se_sess->fabric_sess_ptr; 136 137 spin_lock(&sess->conn_lock); 138 list_for_each_entry(conn, &sess->sess_conn_list, 139 conn_list) { 140 if (conn->conn_state != 141 TARG_CONN_STATE_LOGGED_IN) 142 continue; 143 144 spin_lock(&conn->nopin_timer_lock); 145 __iscsit_start_nopin_timer(conn); 146 spin_unlock(&conn->nopin_timer_lock); 147 } 148 spin_unlock(&sess->conn_lock); 149 } 150 spin_unlock_bh(&se_nacl->nacl_sess_lock); 151 } 152 153 return 0; 154 } 155 156 int iscsit_na_nopin_response_timeout( 157 struct iscsi_node_acl *acl, 158 u32 nopin_response_timeout) 159 { 160 struct iscsi_node_attrib *a = &acl->node_attrib; 161 162 if (nopin_response_timeout > NA_NOPIN_RESPONSE_TIMEOUT_MAX) { 163 pr_err("Requested NopIn Response Timeout %u larger" 164 " than maximum %u\n", nopin_response_timeout, 165 NA_NOPIN_RESPONSE_TIMEOUT_MAX); 166 return -EINVAL; 167 } else if (nopin_response_timeout < NA_NOPIN_RESPONSE_TIMEOUT_MIN) { 168 pr_err("Requested NopIn Response Timeout %u smaller" 169 " than minimum %u\n", nopin_response_timeout, 170 NA_NOPIN_RESPONSE_TIMEOUT_MIN); 171 return -EINVAL; 172 } 173 174 a->nopin_response_timeout = nopin_response_timeout; 175 pr_debug("Set NopIn Response Timeout to %u for" 176 " Initiator Node %s\n", a->nopin_timeout, 177 iscsit_na_get_initiatorname(acl)); 178 179 return 0; 180 } 181 182 int iscsit_na_random_datain_pdu_offsets( 183 struct iscsi_node_acl *acl, 184 u32 random_datain_pdu_offsets) 185 { 186 struct iscsi_node_attrib *a = &acl->node_attrib; 187 188 if (random_datain_pdu_offsets != 0 && random_datain_pdu_offsets != 1) { 189 pr_err("Requested Random DataIN PDU Offsets: %u not" 190 " 0 or 1\n", random_datain_pdu_offsets); 191 return -EINVAL; 192 } 193 194 a->random_datain_pdu_offsets = random_datain_pdu_offsets; 195 pr_debug("Set Random DataIN PDU Offsets to %u for" 196 " Initiator Node %s\n", a->random_datain_pdu_offsets, 197 iscsit_na_get_initiatorname(acl)); 198 199 return 0; 200 } 201 202 int iscsit_na_random_datain_seq_offsets( 203 struct iscsi_node_acl *acl, 204 u32 random_datain_seq_offsets) 205 { 206 struct iscsi_node_attrib *a = &acl->node_attrib; 207 208 if (random_datain_seq_offsets != 0 && random_datain_seq_offsets != 1) { 209 pr_err("Requested Random DataIN Sequence Offsets: %u" 210 " not 0 or 1\n", random_datain_seq_offsets); 211 return -EINVAL; 212 } 213 214 a->random_datain_seq_offsets = random_datain_seq_offsets; 215 pr_debug("Set Random DataIN Sequence Offsets to %u for" 216 " Initiator Node %s\n", a->random_datain_seq_offsets, 217 iscsit_na_get_initiatorname(acl)); 218 219 return 0; 220 } 221 222 int iscsit_na_random_r2t_offsets( 223 struct iscsi_node_acl *acl, 224 u32 random_r2t_offsets) 225 { 226 struct iscsi_node_attrib *a = &acl->node_attrib; 227 228 if (random_r2t_offsets != 0 && random_r2t_offsets != 1) { 229 pr_err("Requested Random R2T Offsets: %u not" 230 " 0 or 1\n", random_r2t_offsets); 231 return -EINVAL; 232 } 233 234 a->random_r2t_offsets = random_r2t_offsets; 235 pr_debug("Set Random R2T Offsets to %u for" 236 " Initiator Node %s\n", a->random_r2t_offsets, 237 iscsit_na_get_initiatorname(acl)); 238 239 return 0; 240 } 241 242 int iscsit_na_default_erl( 243 struct iscsi_node_acl *acl, 244 u32 default_erl) 245 { 246 struct iscsi_node_attrib *a = &acl->node_attrib; 247 248 if (default_erl != 0 && default_erl != 1 && default_erl != 2) { 249 pr_err("Requested default ERL: %u not 0, 1, or 2\n", 250 default_erl); 251 return -EINVAL; 252 } 253 254 a->default_erl = default_erl; 255 pr_debug("Set use ERL0 flag to %u for Initiator" 256 " Node %s\n", a->default_erl, 257 iscsit_na_get_initiatorname(acl)); 258 259 return 0; 260 } 261