iscsi_target_nodeattrib.c 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  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. #include <target/target_core_base.h>
  19. #include <target/iscsi/iscsi_target_core.h>
  20. #include "iscsi_target_device.h"
  21. #include "iscsi_target_tpg.h"
  22. #include "iscsi_target_util.h"
  23. #include "iscsi_target_nodeattrib.h"
  24. static inline char *iscsit_na_get_initiatorname(
  25. struct iscsi_node_acl *nacl)
  26. {
  27. struct se_node_acl *se_nacl = &nacl->se_node_acl;
  28. return &se_nacl->initiatorname[0];
  29. }
  30. void iscsit_set_default_node_attribues(
  31. struct iscsi_node_acl *acl,
  32. struct iscsi_portal_group *tpg)
  33. {
  34. struct iscsi_node_attrib *a = &acl->node_attrib;
  35. a->dataout_timeout = NA_DATAOUT_TIMEOUT;
  36. a->dataout_timeout_retries = NA_DATAOUT_TIMEOUT_RETRIES;
  37. a->nopin_timeout = NA_NOPIN_TIMEOUT;
  38. a->nopin_response_timeout = NA_NOPIN_RESPONSE_TIMEOUT;
  39. a->random_datain_pdu_offsets = NA_RANDOM_DATAIN_PDU_OFFSETS;
  40. a->random_datain_seq_offsets = NA_RANDOM_DATAIN_SEQ_OFFSETS;
  41. a->random_r2t_offsets = NA_RANDOM_R2T_OFFSETS;
  42. a->default_erl = tpg->tpg_attrib.default_erl;
  43. }
  44. int iscsit_na_dataout_timeout(
  45. struct iscsi_node_acl *acl,
  46. u32 dataout_timeout)
  47. {
  48. struct iscsi_node_attrib *a = &acl->node_attrib;
  49. if (dataout_timeout > NA_DATAOUT_TIMEOUT_MAX) {
  50. pr_err("Requested DataOut Timeout %u larger than"
  51. " maximum %u\n", dataout_timeout,
  52. NA_DATAOUT_TIMEOUT_MAX);
  53. return -EINVAL;
  54. } else if (dataout_timeout < NA_DATAOUT_TIMEOUT_MIX) {
  55. pr_err("Requested DataOut Timeout %u smaller than"
  56. " minimum %u\n", dataout_timeout,
  57. NA_DATAOUT_TIMEOUT_MIX);
  58. return -EINVAL;
  59. }
  60. a->dataout_timeout = dataout_timeout;
  61. pr_debug("Set DataOut Timeout to %u for Initiator Node"
  62. " %s\n", a->dataout_timeout, iscsit_na_get_initiatorname(acl));
  63. return 0;
  64. }
  65. int iscsit_na_dataout_timeout_retries(
  66. struct iscsi_node_acl *acl,
  67. u32 dataout_timeout_retries)
  68. {
  69. struct iscsi_node_attrib *a = &acl->node_attrib;
  70. if (dataout_timeout_retries > NA_DATAOUT_TIMEOUT_RETRIES_MAX) {
  71. pr_err("Requested DataOut Timeout Retries %u larger"
  72. " than maximum %u", dataout_timeout_retries,
  73. NA_DATAOUT_TIMEOUT_RETRIES_MAX);
  74. return -EINVAL;
  75. } else if (dataout_timeout_retries < NA_DATAOUT_TIMEOUT_RETRIES_MIN) {
  76. pr_err("Requested DataOut Timeout Retries %u smaller"
  77. " than minimum %u", dataout_timeout_retries,
  78. NA_DATAOUT_TIMEOUT_RETRIES_MIN);
  79. return -EINVAL;
  80. }
  81. a->dataout_timeout_retries = dataout_timeout_retries;
  82. pr_debug("Set DataOut Timeout Retries to %u for"
  83. " Initiator Node %s\n", a->dataout_timeout_retries,
  84. iscsit_na_get_initiatorname(acl));
  85. return 0;
  86. }
  87. int iscsit_na_nopin_timeout(
  88. struct iscsi_node_acl *acl,
  89. u32 nopin_timeout)
  90. {
  91. struct iscsi_node_attrib *a = &acl->node_attrib;
  92. struct iscsi_session *sess;
  93. struct iscsi_conn *conn;
  94. struct se_node_acl *se_nacl = &a->nacl->se_node_acl;
  95. struct se_session *se_sess;
  96. u32 orig_nopin_timeout = a->nopin_timeout;
  97. if (nopin_timeout > NA_NOPIN_TIMEOUT_MAX) {
  98. pr_err("Requested NopIn Timeout %u larger than maximum"
  99. " %u\n", nopin_timeout, NA_NOPIN_TIMEOUT_MAX);
  100. return -EINVAL;
  101. } else if ((nopin_timeout < NA_NOPIN_TIMEOUT_MIN) &&
  102. (nopin_timeout != 0)) {
  103. pr_err("Requested NopIn Timeout %u smaller than"
  104. " minimum %u and not 0\n", nopin_timeout,
  105. NA_NOPIN_TIMEOUT_MIN);
  106. return -EINVAL;
  107. }
  108. a->nopin_timeout = nopin_timeout;
  109. pr_debug("Set NopIn Timeout to %u for Initiator"
  110. " Node %s\n", a->nopin_timeout,
  111. iscsit_na_get_initiatorname(acl));
  112. /*
  113. * Reenable disabled nopin_timeout timer for all iSCSI connections.
  114. */
  115. if (!orig_nopin_timeout) {
  116. spin_lock_bh(&se_nacl->nacl_sess_lock);
  117. se_sess = se_nacl->nacl_sess;
  118. if (se_sess) {
  119. sess = se_sess->fabric_sess_ptr;
  120. spin_lock(&sess->conn_lock);
  121. list_for_each_entry(conn, &sess->sess_conn_list,
  122. conn_list) {
  123. if (conn->conn_state !=
  124. TARG_CONN_STATE_LOGGED_IN)
  125. continue;
  126. spin_lock(&conn->nopin_timer_lock);
  127. __iscsit_start_nopin_timer(conn);
  128. spin_unlock(&conn->nopin_timer_lock);
  129. }
  130. spin_unlock(&sess->conn_lock);
  131. }
  132. spin_unlock_bh(&se_nacl->nacl_sess_lock);
  133. }
  134. return 0;
  135. }
  136. int iscsit_na_nopin_response_timeout(
  137. struct iscsi_node_acl *acl,
  138. u32 nopin_response_timeout)
  139. {
  140. struct iscsi_node_attrib *a = &acl->node_attrib;
  141. if (nopin_response_timeout > NA_NOPIN_RESPONSE_TIMEOUT_MAX) {
  142. pr_err("Requested NopIn Response Timeout %u larger"
  143. " than maximum %u\n", nopin_response_timeout,
  144. NA_NOPIN_RESPONSE_TIMEOUT_MAX);
  145. return -EINVAL;
  146. } else if (nopin_response_timeout < NA_NOPIN_RESPONSE_TIMEOUT_MIN) {
  147. pr_err("Requested NopIn Response Timeout %u smaller"
  148. " than minimum %u\n", nopin_response_timeout,
  149. NA_NOPIN_RESPONSE_TIMEOUT_MIN);
  150. return -EINVAL;
  151. }
  152. a->nopin_response_timeout = nopin_response_timeout;
  153. pr_debug("Set NopIn Response Timeout to %u for"
  154. " Initiator Node %s\n", a->nopin_timeout,
  155. iscsit_na_get_initiatorname(acl));
  156. return 0;
  157. }
  158. int iscsit_na_random_datain_pdu_offsets(
  159. struct iscsi_node_acl *acl,
  160. u32 random_datain_pdu_offsets)
  161. {
  162. struct iscsi_node_attrib *a = &acl->node_attrib;
  163. if (random_datain_pdu_offsets != 0 && random_datain_pdu_offsets != 1) {
  164. pr_err("Requested Random DataIN PDU Offsets: %u not"
  165. " 0 or 1\n", random_datain_pdu_offsets);
  166. return -EINVAL;
  167. }
  168. a->random_datain_pdu_offsets = random_datain_pdu_offsets;
  169. pr_debug("Set Random DataIN PDU Offsets to %u for"
  170. " Initiator Node %s\n", a->random_datain_pdu_offsets,
  171. iscsit_na_get_initiatorname(acl));
  172. return 0;
  173. }
  174. int iscsit_na_random_datain_seq_offsets(
  175. struct iscsi_node_acl *acl,
  176. u32 random_datain_seq_offsets)
  177. {
  178. struct iscsi_node_attrib *a = &acl->node_attrib;
  179. if (random_datain_seq_offsets != 0 && random_datain_seq_offsets != 1) {
  180. pr_err("Requested Random DataIN Sequence Offsets: %u"
  181. " not 0 or 1\n", random_datain_seq_offsets);
  182. return -EINVAL;
  183. }
  184. a->random_datain_seq_offsets = random_datain_seq_offsets;
  185. pr_debug("Set Random DataIN Sequence Offsets to %u for"
  186. " Initiator Node %s\n", a->random_datain_seq_offsets,
  187. iscsit_na_get_initiatorname(acl));
  188. return 0;
  189. }
  190. int iscsit_na_random_r2t_offsets(
  191. struct iscsi_node_acl *acl,
  192. u32 random_r2t_offsets)
  193. {
  194. struct iscsi_node_attrib *a = &acl->node_attrib;
  195. if (random_r2t_offsets != 0 && random_r2t_offsets != 1) {
  196. pr_err("Requested Random R2T Offsets: %u not"
  197. " 0 or 1\n", random_r2t_offsets);
  198. return -EINVAL;
  199. }
  200. a->random_r2t_offsets = random_r2t_offsets;
  201. pr_debug("Set Random R2T Offsets to %u for"
  202. " Initiator Node %s\n", a->random_r2t_offsets,
  203. iscsit_na_get_initiatorname(acl));
  204. return 0;
  205. }
  206. int iscsit_na_default_erl(
  207. struct iscsi_node_acl *acl,
  208. u32 default_erl)
  209. {
  210. struct iscsi_node_attrib *a = &acl->node_attrib;
  211. if (default_erl != 0 && default_erl != 1 && default_erl != 2) {
  212. pr_err("Requested default ERL: %u not 0, 1, or 2\n",
  213. default_erl);
  214. return -EINVAL;
  215. }
  216. a->default_erl = default_erl;
  217. pr_debug("Set use ERL0 flag to %u for Initiator"
  218. " Node %s\n", a->default_erl,
  219. iscsit_na_get_initiatorname(acl));
  220. return 0;
  221. }