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