File Index
Files and directories
Sign in
FILE

iscsi_target_tpg.c

File preview with syntax highlighting.

linux-6.19.14/drivers/target/iscsi/iscsi_target_tpg.c C
  1// SPDX-License-Identifier: GPL-2.0-or-later
  2/*******************************************************************************
  3 * This file contains iSCSI Target Portal Group related functions.
  4 *
  5 * (c) Copyright 2007-2013 Datera, Inc.
  6 *
  7 * Author: Nicholas A. Bellinger <nab@linux-iscsi.org>
  8 *
  9 ******************************************************************************/
 10
 11#include <linux/slab.h>
 12#include <target/target_core_base.h>
 13#include <target/target_core_fabric.h>
 14#include <target/iscsi/iscsi_target_core.h>
 15#include "iscsi_target_erl0.h"
 16#include "iscsi_target_login.h"
 17#include "iscsi_target_nodeattrib.h"
 18#include "iscsi_target_tpg.h"
 19#include "iscsi_target_util.h"
 20#include "iscsi_target.h"
 21#include "iscsi_target_parameters.h"
 22
 23#include <target/iscsi/iscsi_transport.h>
 24
 25struct iscsi_portal_group *iscsit_alloc_portal_group(struct iscsi_tiqn *tiqn, u16 tpgt)
 26{
 27	struct iscsi_portal_group *tpg;
 28
 29	tpg = kzalloc(sizeof(struct iscsi_portal_group), GFP_KERNEL);
 30	if (!tpg) {
 31		pr_err("Unable to allocate struct iscsi_portal_group\n");
 32		return NULL;
 33	}
 34
 35	tpg->tpgt = tpgt;
 36	tpg->tpg_state = TPG_STATE_FREE;
 37	tpg->tpg_tiqn = tiqn;
 38	INIT_LIST_HEAD(&tpg->tpg_gnp_list);
 39	INIT_LIST_HEAD(&tpg->tpg_list);
 40	mutex_init(&tpg->tpg_access_lock);
 41	sema_init(&tpg->np_login_sem, 1);
 42	spin_lock_init(&tpg->tpg_state_lock);
 43	spin_lock_init(&tpg->tpg_np_lock);
 44
 45	return tpg;
 46}
 47
 48static void iscsit_set_default_tpg_attribs(struct iscsi_portal_group *);
 49
 50int iscsit_load_discovery_tpg(void)
 51{
 52	struct iscsi_param *param;
 53	struct iscsi_portal_group *tpg;
 54	int ret;
 55
 56	tpg = iscsit_alloc_portal_group(NULL, 1);
 57	if (!tpg) {
 58		pr_err("Unable to allocate struct iscsi_portal_group\n");
 59		return -1;
 60	}
 61	/*
 62	 * Save iscsi_ops pointer for special case discovery TPG that
 63	 * doesn't exist as se_wwn->wwn_group within configfs.
 64	 */
 65	tpg->tpg_se_tpg.se_tpg_tfo = &iscsi_ops;
 66	ret = core_tpg_register(NULL, &tpg->tpg_se_tpg, -1);
 67	if (ret < 0) {
 68		kfree(tpg);
 69		return -1;
 70	}
 71
 72	tpg->sid = 1; /* First Assigned LIO Session ID */
 73	iscsit_set_default_tpg_attribs(tpg);
 74
 75	if (iscsi_create_default_params(&tpg->param_list) < 0)
 76		goto out;
 77	/*
 78	 * By default we disable authentication for discovery sessions,
 79	 * this can be changed with:
 80	 *
 81	 * /sys/kernel/config/target/iscsi/discovery_auth/enforce_discovery_auth
 82	 */
 83	param = iscsi_find_param_from_key(AUTHMETHOD, tpg->param_list);
 84	if (!param)
 85		goto free_pl_out;
 86
 87	if (iscsi_update_param_value(param, "CHAP,None") < 0)
 88		goto free_pl_out;
 89
 90	tpg->tpg_attrib.authentication = 0;
 91
 92	spin_lock(&tpg->tpg_state_lock);
 93	tpg->tpg_state  = TPG_STATE_ACTIVE;
 94	spin_unlock(&tpg->tpg_state_lock);
 95
 96	iscsit_global->discovery_tpg = tpg;
 97	pr_debug("CORE[0] - Allocated Discovery TPG\n");
 98
 99	return 0;
100free_pl_out:
101	iscsi_release_param_list(tpg->param_list);
102out:
103	if (tpg->sid == 1)
104		core_tpg_deregister(&tpg->tpg_se_tpg);
105	kfree(tpg);
106	return -1;
107}
108
109void iscsit_release_discovery_tpg(void)
110{
111	struct iscsi_portal_group *tpg = iscsit_global->discovery_tpg;
112
113	if (!tpg)
114		return;
115
116	iscsi_release_param_list(tpg->param_list);
117	core_tpg_deregister(&tpg->tpg_se_tpg);
118
119	kfree(tpg);
120	iscsit_global->discovery_tpg = NULL;
121}
122
123struct iscsi_portal_group *iscsit_get_tpg_from_np(
124	struct iscsi_tiqn *tiqn,
125	struct iscsi_np *np,
126	struct iscsi_tpg_np **tpg_np_out)
127{
128	struct iscsi_portal_group *tpg = NULL;
129	struct iscsi_tpg_np *tpg_np;
130
131	spin_lock(&tiqn->tiqn_tpg_lock);
132	list_for_each_entry(tpg, &tiqn->tiqn_tpg_list, tpg_list) {
133
134		spin_lock(&tpg->tpg_state_lock);
135		if (tpg->tpg_state != TPG_STATE_ACTIVE) {
136			spin_unlock(&tpg->tpg_state_lock);
137			continue;
138		}
139		spin_unlock(&tpg->tpg_state_lock);
140
141		spin_lock(&tpg->tpg_np_lock);
142		list_for_each_entry(tpg_np, &tpg->tpg_gnp_list, tpg_np_list) {
143			if (tpg_np->tpg_np == np) {
144				*tpg_np_out = tpg_np;
145				kref_get(&tpg_np->tpg_np_kref);
146				spin_unlock(&tpg->tpg_np_lock);
147				spin_unlock(&tiqn->tiqn_tpg_lock);
148				return tpg;
149			}
150		}
151		spin_unlock(&tpg->tpg_np_lock);
152	}
153	spin_unlock(&tiqn->tiqn_tpg_lock);
154
155	return NULL;
156}
157
158int iscsit_get_tpg(
159	struct iscsi_portal_group *tpg)
160{
161	return mutex_lock_interruptible(&tpg->tpg_access_lock);
162}
163
164void iscsit_put_tpg(struct iscsi_portal_group *tpg)
165{
166	mutex_unlock(&tpg->tpg_access_lock);
167}
168
169static void iscsit_clear_tpg_np_login_thread(
170	struct iscsi_tpg_np *tpg_np,
171	struct iscsi_portal_group *tpg,
172	bool shutdown)
173{
174	if (!tpg_np->tpg_np) {
175		pr_err("struct iscsi_tpg_np->tpg_np is NULL!\n");
176		return;
177	}
178
179	if (shutdown)
180		tpg_np->tpg_np->enabled = false;
181	iscsit_reset_np_thread(tpg_np->tpg_np, tpg_np, tpg, shutdown);
182}
183
184static void iscsit_clear_tpg_np_login_threads(
185	struct iscsi_portal_group *tpg,
186	bool shutdown)
187{
188	struct iscsi_tpg_np *tpg_np;
189
190	spin_lock(&tpg->tpg_np_lock);
191	list_for_each_entry(tpg_np, &tpg->tpg_gnp_list, tpg_np_list) {
192		if (!tpg_np->tpg_np) {
193			pr_err("struct iscsi_tpg_np->tpg_np is NULL!\n");
194			continue;
195		}
196		spin_unlock(&tpg->tpg_np_lock);
197		iscsit_clear_tpg_np_login_thread(tpg_np, tpg, shutdown);
198		spin_lock(&tpg->tpg_np_lock);
199	}
200	spin_unlock(&tpg->tpg_np_lock);
201}
202
203static void iscsit_set_default_tpg_attribs(struct iscsi_portal_group *tpg)
204{
205	struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
206
207	a->authentication = TA_AUTHENTICATION;
208	a->login_timeout = TA_LOGIN_TIMEOUT;
209	a->default_cmdsn_depth = TA_DEFAULT_CMDSN_DEPTH;
210	a->generate_node_acls = TA_GENERATE_NODE_ACLS;
211	a->cache_dynamic_acls = TA_CACHE_DYNAMIC_ACLS;
212	a->demo_mode_write_protect = TA_DEMO_MODE_WRITE_PROTECT;
213	a->prod_mode_write_protect = TA_PROD_MODE_WRITE_PROTECT;
214	a->demo_mode_discovery = TA_DEMO_MODE_DISCOVERY;
215	a->default_erl = TA_DEFAULT_ERL;
216	a->t10_pi = TA_DEFAULT_T10_PI;
217	a->fabric_prot_type = TA_DEFAULT_FABRIC_PROT_TYPE;
218	a->tpg_enabled_sendtargets = TA_DEFAULT_TPG_ENABLED_SENDTARGETS;
219	a->login_keys_workaround = TA_DEFAULT_LOGIN_KEYS_WORKAROUND;
220}
221
222int iscsit_tpg_add_portal_group(struct iscsi_tiqn *tiqn, struct iscsi_portal_group *tpg)
223{
224	if (tpg->tpg_state != TPG_STATE_FREE) {
225		pr_err("Unable to add iSCSI Target Portal Group: %d"
226			" while not in TPG_STATE_FREE state.\n", tpg->tpgt);
227		return -EEXIST;
228	}
229	iscsit_set_default_tpg_attribs(tpg);
230
231	if (iscsi_create_default_params(&tpg->param_list) < 0)
232		goto err_out;
233
234	tpg->tpg_attrib.tpg = tpg;
235
236	spin_lock(&tpg->tpg_state_lock);
237	tpg->tpg_state	= TPG_STATE_INACTIVE;
238	spin_unlock(&tpg->tpg_state_lock);
239
240	spin_lock(&tiqn->tiqn_tpg_lock);
241	list_add_tail(&tpg->tpg_list, &tiqn->tiqn_tpg_list);
242	tiqn->tiqn_ntpgs++;
243	pr_debug("CORE[%s]_TPG[%hu] - Added iSCSI Target Portal Group\n",
244			tiqn->tiqn, tpg->tpgt);
245	spin_unlock(&tiqn->tiqn_tpg_lock);
246
247	return 0;
248err_out:
249	if (tpg->param_list) {
250		iscsi_release_param_list(tpg->param_list);
251		tpg->param_list = NULL;
252	}
253	return -ENOMEM;
254}
255
256int iscsit_tpg_del_portal_group(
257	struct iscsi_tiqn *tiqn,
258	struct iscsi_portal_group *tpg,
259	int force)
260{
261	u8 old_state = tpg->tpg_state;
262
263	spin_lock(&tpg->tpg_state_lock);
264	tpg->tpg_state = TPG_STATE_INACTIVE;
265	spin_unlock(&tpg->tpg_state_lock);
266
267	if (iscsit_release_sessions_for_tpg(tpg, force) < 0) {
268		pr_err("Unable to delete iSCSI Target Portal Group:"
269			" %hu while active sessions exist, and force=0\n",
270			tpg->tpgt);
271		tpg->tpg_state = old_state;
272		return -EPERM;
273	}
274
275	if (tpg->param_list) {
276		iscsi_release_param_list(tpg->param_list);
277		tpg->param_list = NULL;
278	}
279
280	core_tpg_deregister(&tpg->tpg_se_tpg);
281
282	spin_lock(&tpg->tpg_state_lock);
283	tpg->tpg_state = TPG_STATE_FREE;
284	spin_unlock(&tpg->tpg_state_lock);
285
286	spin_lock(&tiqn->tiqn_tpg_lock);
287	tiqn->tiqn_ntpgs--;
288	list_del(&tpg->tpg_list);
289	spin_unlock(&tiqn->tiqn_tpg_lock);
290
291	pr_debug("CORE[%s]_TPG[%hu] - Deleted iSCSI Target Portal Group\n",
292			tiqn->tiqn, tpg->tpgt);
293
294	kfree(tpg);
295	return 0;
296}
297
298int iscsit_tpg_enable_portal_group(struct iscsi_portal_group *tpg)
299{
300	struct iscsi_param *param;
301	struct iscsi_tiqn *tiqn = tpg->tpg_tiqn;
302	int ret;
303
304	if (tpg->tpg_state == TPG_STATE_ACTIVE) {
305		pr_err("iSCSI target portal group: %hu is already"
306			" active, ignoring request.\n", tpg->tpgt);
307		return -EINVAL;
308	}
309	/*
310	 * Make sure that AuthMethod does not contain None as an option
311	 * unless explictly disabled.  Set the default to CHAP if authentication
312	 * is enforced (as per default), and remove the NONE option.
313	 */
314	param = iscsi_find_param_from_key(AUTHMETHOD, tpg->param_list);
315	if (!param)
316		return -EINVAL;
317
318	if (tpg->tpg_attrib.authentication) {
319		if (!strcmp(param->value, NONE)) {
320			ret = iscsi_update_param_value(param, CHAP);
321			if (ret)
322				goto err;
323		}
324
325		ret = iscsit_ta_authentication(tpg, 1);
326		if (ret < 0)
327			goto err;
328	}
329
330	spin_lock(&tpg->tpg_state_lock);
331	tpg->tpg_state = TPG_STATE_ACTIVE;
332	spin_unlock(&tpg->tpg_state_lock);
333
334	spin_lock(&tiqn->tiqn_tpg_lock);
335	tiqn->tiqn_active_tpgs++;
336	pr_debug("iSCSI_TPG[%hu] - Enabled iSCSI Target Portal Group\n",
337			tpg->tpgt);
338	spin_unlock(&tiqn->tiqn_tpg_lock);
339
340	return 0;
341
342err:
343	return ret;
344}
345
346int iscsit_tpg_disable_portal_group(struct iscsi_portal_group *tpg, int force)
347{
348	struct iscsi_tiqn *tiqn;
349	u8 old_state = tpg->tpg_state;
350
351	spin_lock(&tpg->tpg_state_lock);
352	if (tpg->tpg_state == TPG_STATE_INACTIVE) {
353		pr_err("iSCSI Target Portal Group: %hu is already"
354			" inactive, ignoring request.\n", tpg->tpgt);
355		spin_unlock(&tpg->tpg_state_lock);
356		return -EINVAL;
357	}
358	tpg->tpg_state = TPG_STATE_INACTIVE;
359	spin_unlock(&tpg->tpg_state_lock);
360
361	iscsit_clear_tpg_np_login_threads(tpg, false);
362
363	if (iscsit_release_sessions_for_tpg(tpg, force) < 0) {
364		spin_lock(&tpg->tpg_state_lock);
365		tpg->tpg_state = old_state;
366		spin_unlock(&tpg->tpg_state_lock);
367		pr_err("Unable to disable iSCSI Target Portal Group:"
368			" %hu while active sessions exist, and force=0\n",
369			tpg->tpgt);
370		return -EPERM;
371	}
372
373	tiqn = tpg->tpg_tiqn;
374	if (!tiqn || (tpg == iscsit_global->discovery_tpg))
375		return 0;
376
377	spin_lock(&tiqn->tiqn_tpg_lock);
378	tiqn->tiqn_active_tpgs--;
379	pr_debug("iSCSI_TPG[%hu] - Disabled iSCSI Target Portal Group\n",
380			tpg->tpgt);
381	spin_unlock(&tiqn->tiqn_tpg_lock);
382
383	return 0;
384}
385
386struct iscsi_node_attrib *iscsit_tpg_get_node_attrib(
387	struct iscsit_session *sess)
388{
389	struct se_session *se_sess = sess->se_sess;
390	struct se_node_acl *se_nacl = se_sess->se_node_acl;
391	struct iscsi_node_acl *acl = to_iscsi_nacl(se_nacl);
392
393	return &acl->node_attrib;
394}
395
396struct iscsi_tpg_np *iscsit_tpg_locate_child_np(
397	struct iscsi_tpg_np *tpg_np,
398	int network_transport)
399{
400	struct iscsi_tpg_np *tpg_np_child, *tpg_np_child_tmp;
401
402	spin_lock(&tpg_np->tpg_np_parent_lock);
403	list_for_each_entry_safe(tpg_np_child, tpg_np_child_tmp,
404			&tpg_np->tpg_np_parent_list, tpg_np_child_list) {
405		if (tpg_np_child->tpg_np->np_network_transport ==
406				network_transport) {
407			spin_unlock(&tpg_np->tpg_np_parent_lock);
408			return tpg_np_child;
409		}
410	}
411	spin_unlock(&tpg_np->tpg_np_parent_lock);
412
413	return NULL;
414}
415
416static bool iscsit_tpg_check_network_portal(
417	struct iscsi_tiqn *tiqn,
418	struct sockaddr_storage *sockaddr,
419	int network_transport)
420{
421	struct iscsi_portal_group *tpg;
422	struct iscsi_tpg_np *tpg_np;
423	struct iscsi_np *np;
424	bool match = false;
425
426	spin_lock(&tiqn->tiqn_tpg_lock);
427	list_for_each_entry(tpg, &tiqn->tiqn_tpg_list, tpg_list) {
428
429		spin_lock(&tpg->tpg_np_lock);
430		list_for_each_entry(tpg_np, &tpg->tpg_gnp_list, tpg_np_list) {
431			np = tpg_np->tpg_np;
432
433			match = iscsit_check_np_match(sockaddr, np,
434						network_transport);
435			if (match)
436				break;
437		}
438		spin_unlock(&tpg->tpg_np_lock);
439
440		if (match)
441			break;
442	}
443	spin_unlock(&tiqn->tiqn_tpg_lock);
444
445	return match;
446}
447
448struct iscsi_tpg_np *iscsit_tpg_add_network_portal(
449	struct iscsi_portal_group *tpg,
450	struct sockaddr_storage *sockaddr,
451	struct iscsi_tpg_np *tpg_np_parent,
452	int network_transport)
453{
454	struct iscsi_np *np;
455	struct iscsi_tpg_np *tpg_np;
456
457	if (!tpg_np_parent) {
458		if (iscsit_tpg_check_network_portal(tpg->tpg_tiqn, sockaddr,
459				network_transport)) {
460			pr_err("Network Portal: %pISc already exists on a"
461				" different TPG on %s\n", sockaddr,
462				tpg->tpg_tiqn->tiqn);
463			return ERR_PTR(-EEXIST);
464		}
465	}
466
467	tpg_np = kzalloc(sizeof(struct iscsi_tpg_np), GFP_KERNEL);
468	if (!tpg_np) {
469		pr_err("Unable to allocate memory for"
470				" struct iscsi_tpg_np.\n");
471		return ERR_PTR(-ENOMEM);
472	}
473
474	np = iscsit_add_np(sockaddr, network_transport);
475	if (IS_ERR(np)) {
476		kfree(tpg_np);
477		return ERR_CAST(np);
478	}
479
480	INIT_LIST_HEAD(&tpg_np->tpg_np_list);
481	INIT_LIST_HEAD(&tpg_np->tpg_np_child_list);
482	INIT_LIST_HEAD(&tpg_np->tpg_np_parent_list);
483	spin_lock_init(&tpg_np->tpg_np_parent_lock);
484	init_completion(&tpg_np->tpg_np_comp);
485	kref_init(&tpg_np->tpg_np_kref);
486	tpg_np->tpg_np		= np;
487	tpg_np->tpg		= tpg;
488
489	spin_lock(&tpg->tpg_np_lock);
490	list_add_tail(&tpg_np->tpg_np_list, &tpg->tpg_gnp_list);
491	tpg->num_tpg_nps++;
492	if (tpg->tpg_tiqn)
493		tpg->tpg_tiqn->tiqn_num_tpg_nps++;
494	spin_unlock(&tpg->tpg_np_lock);
495
496	if (tpg_np_parent) {
497		tpg_np->tpg_np_parent = tpg_np_parent;
498		spin_lock(&tpg_np_parent->tpg_np_parent_lock);
499		list_add_tail(&tpg_np->tpg_np_child_list,
500			&tpg_np_parent->tpg_np_parent_list);
501		spin_unlock(&tpg_np_parent->tpg_np_parent_lock);
502	}
503
504	pr_debug("CORE[%s] - Added Network Portal: %pISpc,%hu on %s\n",
505		tpg->tpg_tiqn->tiqn, &np->np_sockaddr, tpg->tpgt,
506		np->np_transport->name);
507
508	return tpg_np;
509}
510
511static int iscsit_tpg_release_np(
512	struct iscsi_tpg_np *tpg_np,
513	struct iscsi_portal_group *tpg,
514	struct iscsi_np *np)
515{
516	iscsit_clear_tpg_np_login_thread(tpg_np, tpg, true);
517
518	pr_debug("CORE[%s] - Removed Network Portal: %pISpc,%hu on %s\n",
519		tpg->tpg_tiqn->tiqn, &np->np_sockaddr, tpg->tpgt,
520		np->np_transport->name);
521
522	tpg_np->tpg_np = NULL;
523	tpg_np->tpg = NULL;
524	kfree(tpg_np);
525	/*
526	 * iscsit_del_np() will shutdown struct iscsi_np when last TPG reference is released.
527	 */
528	return iscsit_del_np(np);
529}
530
531int iscsit_tpg_del_network_portal(
532	struct iscsi_portal_group *tpg,
533	struct iscsi_tpg_np *tpg_np)
534{
535	struct iscsi_np *np;
536	struct iscsi_tpg_np *tpg_np_child, *tpg_np_child_tmp;
537	int ret = 0;
538
539	np = tpg_np->tpg_np;
540	if (!np) {
541		pr_err("Unable to locate struct iscsi_np from"
542				" struct iscsi_tpg_np\n");
543		return -EINVAL;
544	}
545
546	if (!tpg_np->tpg_np_parent) {
547		/*
548		 * We are the parent tpg network portal.  Release all of the
549		 * child tpg_np's (eg: the non ISCSI_TCP ones) on our parent
550		 * list first.
551		 */
552		list_for_each_entry_safe(tpg_np_child, tpg_np_child_tmp,
553				&tpg_np->tpg_np_parent_list,
554				tpg_np_child_list) {
555			ret = iscsit_tpg_del_network_portal(tpg, tpg_np_child);
556			if (ret < 0)
557				pr_err("iscsit_tpg_del_network_portal()"
558					" failed: %d\n", ret);
559		}
560	} else {
561		/*
562		 * We are not the parent ISCSI_TCP tpg network portal.  Release
563		 * our own network portals from the child list.
564		 */
565		spin_lock(&tpg_np->tpg_np_parent->tpg_np_parent_lock);
566		list_del(&tpg_np->tpg_np_child_list);
567		spin_unlock(&tpg_np->tpg_np_parent->tpg_np_parent_lock);
568	}
569
570	spin_lock(&tpg->tpg_np_lock);
571	list_del(&tpg_np->tpg_np_list);
572	tpg->num_tpg_nps--;
573	if (tpg->tpg_tiqn)
574		tpg->tpg_tiqn->tiqn_num_tpg_nps--;
575	spin_unlock(&tpg->tpg_np_lock);
576
577	return iscsit_tpg_release_np(tpg_np, tpg, np);
578}
579
580int iscsit_ta_authentication(struct iscsi_portal_group *tpg, u32 authentication)
581{
582	unsigned char buf1[256], buf2[256], *none = NULL;
583	int len;
584	struct iscsi_param *param;
585	struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
586
587	if ((authentication != 1) && (authentication != 0)) {
588		pr_err("Illegal value for authentication parameter:"
589			" %u, ignoring request.\n", authentication);
590		return -EINVAL;
591	}
592
593	memset(buf1, 0, sizeof(buf1));
594	memset(buf2, 0, sizeof(buf2));
595
596	param = iscsi_find_param_from_key(AUTHMETHOD, tpg->param_list);
597	if (!param)
598		return -EINVAL;
599
600	if (authentication) {
601		snprintf(buf1, sizeof(buf1), "%s", param->value);
602		none = strstr(buf1, NONE);
603		if (!none)
604			goto out;
605		if (!strncmp(none + 4, ",", 1)) {
606			if (!strcmp(buf1, none))
607				sprintf(buf2, "%s", none+5);
608			else {
609				none--;
610				*none = '\0';
611				len = sprintf(buf2, "%s", buf1);
612				none += 5;
613				sprintf(buf2 + len, "%s", none);
614			}
615		} else {
616			none--;
617			*none = '\0';
618			sprintf(buf2, "%s", buf1);
619		}
620		if (iscsi_update_param_value(param, buf2) < 0)
621			return -EINVAL;
622	} else {
623		snprintf(buf1, sizeof(buf1), "%s", param->value);
624		none = strstr(buf1, NONE);
625		if (none)
626			goto out;
627		strlcat(buf1, "," NONE, sizeof(buf1));
628		if (iscsi_update_param_value(param, buf1) < 0)
629			return -EINVAL;
630	}
631
632out:
633	a->authentication = authentication;
634	pr_debug("%s iSCSI Authentication Methods for TPG: %hu.\n",
635		a->authentication ? "Enforcing" : "Disabling", tpg->tpgt);
636
637	return 0;
638}
639
640int iscsit_ta_login_timeout(
641	struct iscsi_portal_group *tpg,
642	u32 login_timeout)
643{
644	struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
645
646	if (login_timeout > TA_LOGIN_TIMEOUT_MAX) {
647		pr_err("Requested Login Timeout %u larger than maximum"
648			" %u\n", login_timeout, TA_LOGIN_TIMEOUT_MAX);
649		return -EINVAL;
650	} else if (login_timeout < TA_LOGIN_TIMEOUT_MIN) {
651		pr_err("Requested Logout Timeout %u smaller than"
652			" minimum %u\n", login_timeout, TA_LOGIN_TIMEOUT_MIN);
653		return -EINVAL;
654	}
655
656	a->login_timeout = login_timeout;
657	pr_debug("Set Logout Timeout to %u for Target Portal Group"
658		" %hu\n", a->login_timeout, tpg->tpgt);
659
660	return 0;
661}
662
663int iscsit_ta_generate_node_acls(
664	struct iscsi_portal_group *tpg,
665	u32 flag)
666{
667	struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
668
669	if ((flag != 0) && (flag != 1)) {
670		pr_err("Illegal value %d\n", flag);
671		return -EINVAL;
672	}
673
674	a->generate_node_acls = flag;
675	pr_debug("iSCSI_TPG[%hu] - Generate Initiator Portal Group ACLs: %s\n",
676		tpg->tpgt, (a->generate_node_acls) ? "Enabled" : "Disabled");
677
678	if (flag == 1 && a->cache_dynamic_acls == 0) {
679		pr_debug("Explicitly setting cache_dynamic_acls=1 when "
680			"generate_node_acls=1\n");
681		a->cache_dynamic_acls = 1;
682	}
683
684	return 0;
685}
686
687int iscsit_ta_default_cmdsn_depth(
688	struct iscsi_portal_group *tpg,
689	u32 tcq_depth)
690{
691	struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
692
693	if (tcq_depth > TA_DEFAULT_CMDSN_DEPTH_MAX) {
694		pr_err("Requested Default Queue Depth: %u larger"
695			" than maximum %u\n", tcq_depth,
696				TA_DEFAULT_CMDSN_DEPTH_MAX);
697		return -EINVAL;
698	} else if (tcq_depth < TA_DEFAULT_CMDSN_DEPTH_MIN) {
699		pr_err("Requested Default Queue Depth: %u smaller"
700			" than minimum %u\n", tcq_depth,
701				TA_DEFAULT_CMDSN_DEPTH_MIN);
702		return -EINVAL;
703	}
704
705	a->default_cmdsn_depth = tcq_depth;
706	pr_debug("iSCSI_TPG[%hu] - Set Default CmdSN TCQ Depth to %u\n",
707		tpg->tpgt, a->default_cmdsn_depth);
708
709	return 0;
710}
711
712int iscsit_ta_cache_dynamic_acls(
713	struct iscsi_portal_group *tpg,
714	u32 flag)
715{
716	struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
717
718	if ((flag != 0) && (flag != 1)) {
719		pr_err("Illegal value %d\n", flag);
720		return -EINVAL;
721	}
722
723	if (a->generate_node_acls == 1 && flag == 0) {
724		pr_debug("Skipping cache_dynamic_acls=0 when"
725			" generate_node_acls=1\n");
726		return 0;
727	}
728
729	a->cache_dynamic_acls = flag;
730	pr_debug("iSCSI_TPG[%hu] - Cache Dynamic Initiator Portal Group"
731		" ACLs %s\n", tpg->tpgt, (a->cache_dynamic_acls) ?
732		"Enabled" : "Disabled");
733
734	return 0;
735}
736
737int iscsit_ta_demo_mode_write_protect(
738	struct iscsi_portal_group *tpg,
739	u32 flag)
740{
741	struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
742
743	if ((flag != 0) && (flag != 1)) {
744		pr_err("Illegal value %d\n", flag);
745		return -EINVAL;
746	}
747
748	a->demo_mode_write_protect = flag;
749	pr_debug("iSCSI_TPG[%hu] - Demo Mode Write Protect bit: %s\n",
750		tpg->tpgt, (a->demo_mode_write_protect) ? "ON" : "OFF");
751
752	return 0;
753}
754
755int iscsit_ta_prod_mode_write_protect(
756	struct iscsi_portal_group *tpg,
757	u32 flag)
758{
759	struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
760
761	if ((flag != 0) && (flag != 1)) {
762		pr_err("Illegal value %d\n", flag);
763		return -EINVAL;
764	}
765
766	a->prod_mode_write_protect = flag;
767	pr_debug("iSCSI_TPG[%hu] - Production Mode Write Protect bit:"
768		" %s\n", tpg->tpgt, (a->prod_mode_write_protect) ?
769		"ON" : "OFF");
770
771	return 0;
772}
773
774int iscsit_ta_demo_mode_discovery(
775	struct iscsi_portal_group *tpg,
776	u32 flag)
777{
778	struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
779
780	if ((flag != 0) && (flag != 1)) {
781		pr_err("Illegal value %d\n", flag);
782		return -EINVAL;
783	}
784
785	a->demo_mode_discovery = flag;
786	pr_debug("iSCSI_TPG[%hu] - Demo Mode Discovery bit:"
787		" %s\n", tpg->tpgt, (a->demo_mode_discovery) ?
788		"ON" : "OFF");
789
790	return 0;
791}
792
793int iscsit_ta_default_erl(
794	struct iscsi_portal_group *tpg,
795	u32 default_erl)
796{
797	struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
798
799	if ((default_erl != 0) && (default_erl != 1) && (default_erl != 2)) {
800		pr_err("Illegal value for default_erl: %u\n", default_erl);
801		return -EINVAL;
802	}
803
804	a->default_erl = default_erl;
805	pr_debug("iSCSI_TPG[%hu] - DefaultERL: %u\n", tpg->tpgt, a->default_erl);
806
807	return 0;
808}
809
810int iscsit_ta_t10_pi(
811	struct iscsi_portal_group *tpg,
812	u32 flag)
813{
814	struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
815
816	if ((flag != 0) && (flag != 1)) {
817		pr_err("Illegal value %d\n", flag);
818		return -EINVAL;
819	}
820
821	a->t10_pi = flag;
822	pr_debug("iSCSI_TPG[%hu] - T10 Protection information bit:"
823		" %s\n", tpg->tpgt, (a->t10_pi) ?
824		"ON" : "OFF");
825
826	return 0;
827}
828
829int iscsit_ta_fabric_prot_type(
830	struct iscsi_portal_group *tpg,
831	u32 prot_type)
832{
833	struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
834
835	if ((prot_type != 0) && (prot_type != 1) && (prot_type != 3)) {
836		pr_err("Illegal value for fabric_prot_type: %u\n", prot_type);
837		return -EINVAL;
838	}
839
840	a->fabric_prot_type = prot_type;
841	pr_debug("iSCSI_TPG[%hu] - T10 Fabric Protection Type: %u\n",
842		 tpg->tpgt, prot_type);
843
844	return 0;
845}
846
847int iscsit_ta_tpg_enabled_sendtargets(
848	struct iscsi_portal_group *tpg,
849	u32 flag)
850{
851	struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
852
853	if ((flag != 0) && (flag != 1)) {
854		pr_err("Illegal value %d\n", flag);
855		return -EINVAL;
856	}
857
858	a->tpg_enabled_sendtargets = flag;
859	pr_debug("iSCSI_TPG[%hu] - TPG enabled bit required for SendTargets:"
860		" %s\n", tpg->tpgt, (a->tpg_enabled_sendtargets) ? "ON" : "OFF");
861
862	return 0;
863}
864
865int iscsit_ta_login_keys_workaround(
866	struct iscsi_portal_group *tpg,
867	u32 flag)
868{
869	struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
870
871	if ((flag != 0) && (flag != 1)) {
872		pr_err("Illegal value %d\n", flag);
873		return -EINVAL;
874	}
875
876	a->login_keys_workaround = flag;
877	pr_debug("iSCSI_TPG[%hu] - TPG enabled bit for login keys workaround: %s ",
878		tpg->tpgt, (a->login_keys_workaround) ? "ON" : "OFF");
879
880	return 0;
881}
~/ Read-only file preview.