• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*******************************************************************************
2 * Filename: target_core_fabric_configfs.c
3  *
4  * This file contains generic fabric module configfs infrastructure for
5  * TCM v4.x code
6  *
7  * Copyright (c) 2010,2011 Rising Tide Systems
8  * Copyright (c) 2010,2011 Linux-iSCSI.org
9  *
10  * Copyright (c) Nicholas A. Bellinger <nab@linux-iscsi.org>
11 *
12  * This program is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License as published by
14  * the Free Software Foundation; either version 2 of the License, or
15  * (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  ****************************************************************************/
22 
23 #include <linux/module.h>
24 #include <linux/moduleparam.h>
25 #include <generated/utsrelease.h>
26 #include <linux/utsname.h>
27 #include <linux/init.h>
28 #include <linux/fs.h>
29 #include <linux/namei.h>
30 #include <linux/slab.h>
31 #include <linux/types.h>
32 #include <linux/delay.h>
33 #include <linux/unistd.h>
34 #include <linux/string.h>
35 #include <linux/syscalls.h>
36 #include <linux/configfs.h>
37 
38 #include <target/target_core_base.h>
39 #include <target/target_core_fabric.h>
40 #include <target/target_core_fabric_configfs.h>
41 #include <target/target_core_configfs.h>
42 #include <target/configfs_macros.h>
43 
44 #include "target_core_internal.h"
45 #include "target_core_alua.h"
46 #include "target_core_pr.h"
47 
48 #define TF_CIT_SETUP(_name, _item_ops, _group_ops, _attrs)		\
49 static void target_fabric_setup_##_name##_cit(struct target_fabric_configfs *tf) \
50 {									\
51 	struct target_fabric_configfs_template *tfc = &tf->tf_cit_tmpl;	\
52 	struct config_item_type *cit = &tfc->tfc_##_name##_cit;		\
53 									\
54 	cit->ct_item_ops = _item_ops;					\
55 	cit->ct_group_ops = _group_ops;					\
56 	cit->ct_attrs = _attrs;						\
57 	cit->ct_owner = tf->tf_module;					\
58 	pr_debug("Setup generic %s\n", __stringify(_name));		\
59 }
60 
61 /* Start of tfc_tpg_mappedlun_cit */
62 
target_fabric_mappedlun_link(struct config_item * lun_acl_ci,struct config_item * lun_ci)63 static int target_fabric_mappedlun_link(
64 	struct config_item *lun_acl_ci,
65 	struct config_item *lun_ci)
66 {
67 	struct se_dev_entry *deve;
68 	struct se_lun *lun = container_of(to_config_group(lun_ci),
69 			struct se_lun, lun_group);
70 	struct se_lun_acl *lacl = container_of(to_config_group(lun_acl_ci),
71 			struct se_lun_acl, se_lun_group);
72 	struct se_portal_group *se_tpg;
73 	struct config_item *nacl_ci, *tpg_ci, *tpg_ci_s, *wwn_ci, *wwn_ci_s;
74 	int ret = 0, lun_access;
75 
76 	if (lun->lun_link_magic != SE_LUN_LINK_MAGIC) {
77 		pr_err("Bad lun->lun_link_magic, not a valid lun_ci pointer:"
78 			" %p to struct lun: %p\n", lun_ci, lun);
79 		return -EFAULT;
80 	}
81 	/*
82 	 * Ensure that the source port exists
83 	 */
84 	if (!lun->lun_sep || !lun->lun_sep->sep_tpg) {
85 		pr_err("Source se_lun->lun_sep or lun->lun_sep->sep"
86 				"_tpg does not exist\n");
87 		return -EINVAL;
88 	}
89 	se_tpg = lun->lun_sep->sep_tpg;
90 
91 	nacl_ci = &lun_acl_ci->ci_parent->ci_group->cg_item;
92 	tpg_ci = &nacl_ci->ci_group->cg_item;
93 	wwn_ci = &tpg_ci->ci_group->cg_item;
94 	tpg_ci_s = &lun_ci->ci_parent->ci_group->cg_item;
95 	wwn_ci_s = &tpg_ci_s->ci_group->cg_item;
96 	/*
97 	 * Make sure the SymLink is going to the same $FABRIC/$WWN/tpgt_$TPGT
98 	 */
99 	if (strcmp(config_item_name(wwn_ci), config_item_name(wwn_ci_s))) {
100 		pr_err("Illegal Initiator ACL SymLink outside of %s\n",
101 			config_item_name(wwn_ci));
102 		return -EINVAL;
103 	}
104 	if (strcmp(config_item_name(tpg_ci), config_item_name(tpg_ci_s))) {
105 		pr_err("Illegal Initiator ACL Symlink outside of %s"
106 			" TPGT: %s\n", config_item_name(wwn_ci),
107 			config_item_name(tpg_ci));
108 		return -EINVAL;
109 	}
110 	/*
111 	 * If this struct se_node_acl was dynamically generated with
112 	 * tpg_1/attrib/generate_node_acls=1, use the existing deve->lun_flags,
113 	 * which be will write protected (READ-ONLY) when
114 	 * tpg_1/attrib/demo_mode_write_protect=1
115 	 */
116 	spin_lock_irq(&lacl->se_lun_nacl->device_list_lock);
117 	deve = lacl->se_lun_nacl->device_list[lacl->mapped_lun];
118 	if (deve->lun_flags & TRANSPORT_LUNFLAGS_INITIATOR_ACCESS)
119 		lun_access = deve->lun_flags;
120 	else
121 		lun_access =
122 			(se_tpg->se_tpg_tfo->tpg_check_prod_mode_write_protect(
123 				se_tpg)) ? TRANSPORT_LUNFLAGS_READ_ONLY :
124 					   TRANSPORT_LUNFLAGS_READ_WRITE;
125 	spin_unlock_irq(&lacl->se_lun_nacl->device_list_lock);
126 	/*
127 	 * Determine the actual mapped LUN value user wants..
128 	 *
129 	 * This value is what the SCSI Initiator actually sees the
130 	 * iscsi/$IQN/$TPGT/lun/lun_* as on their SCSI Initiator Ports.
131 	 */
132 	ret = core_dev_add_initiator_node_lun_acl(se_tpg, lacl,
133 			lun->unpacked_lun, lun_access);
134 
135 	return (ret < 0) ? -EINVAL : 0;
136 }
137 
target_fabric_mappedlun_unlink(struct config_item * lun_acl_ci,struct config_item * lun_ci)138 static int target_fabric_mappedlun_unlink(
139 	struct config_item *lun_acl_ci,
140 	struct config_item *lun_ci)
141 {
142 	struct se_lun *lun;
143 	struct se_lun_acl *lacl = container_of(to_config_group(lun_acl_ci),
144 			struct se_lun_acl, se_lun_group);
145 	struct se_node_acl *nacl = lacl->se_lun_nacl;
146 	struct se_dev_entry *deve = nacl->device_list[lacl->mapped_lun];
147 	struct se_portal_group *se_tpg;
148 	/*
149 	 * Determine if the underlying MappedLUN has already been released..
150 	 */
151 	if (!deve->se_lun)
152 		return 0;
153 
154 	lun = container_of(to_config_group(lun_ci), struct se_lun, lun_group);
155 	se_tpg = lun->lun_sep->sep_tpg;
156 
157 	core_dev_del_initiator_node_lun_acl(se_tpg, lun, lacl);
158 	return 0;
159 }
160 
161 CONFIGFS_EATTR_STRUCT(target_fabric_mappedlun, se_lun_acl);
162 #define TCM_MAPPEDLUN_ATTR(_name, _mode)				\
163 static struct target_fabric_mappedlun_attribute target_fabric_mappedlun_##_name = \
164 	__CONFIGFS_EATTR(_name, _mode,					\
165 	target_fabric_mappedlun_show_##_name,				\
166 	target_fabric_mappedlun_store_##_name);
167 
target_fabric_mappedlun_show_write_protect(struct se_lun_acl * lacl,char * page)168 static ssize_t target_fabric_mappedlun_show_write_protect(
169 	struct se_lun_acl *lacl,
170 	char *page)
171 {
172 	struct se_node_acl *se_nacl = lacl->se_lun_nacl;
173 	struct se_dev_entry *deve;
174 	ssize_t len;
175 
176 	spin_lock_irq(&se_nacl->device_list_lock);
177 	deve = se_nacl->device_list[lacl->mapped_lun];
178 	len = sprintf(page, "%d\n",
179 			(deve->lun_flags & TRANSPORT_LUNFLAGS_READ_ONLY) ?
180 			1 : 0);
181 	spin_unlock_irq(&se_nacl->device_list_lock);
182 
183 	return len;
184 }
185 
target_fabric_mappedlun_store_write_protect(struct se_lun_acl * lacl,const char * page,size_t count)186 static ssize_t target_fabric_mappedlun_store_write_protect(
187 	struct se_lun_acl *lacl,
188 	const char *page,
189 	size_t count)
190 {
191 	struct se_node_acl *se_nacl = lacl->se_lun_nacl;
192 	struct se_portal_group *se_tpg = se_nacl->se_tpg;
193 	unsigned long op;
194 
195 	if (strict_strtoul(page, 0, &op))
196 		return -EINVAL;
197 
198 	if ((op != 1) && (op != 0))
199 		return -EINVAL;
200 
201 	core_update_device_list_access(lacl->mapped_lun, (op) ?
202 			TRANSPORT_LUNFLAGS_READ_ONLY :
203 			TRANSPORT_LUNFLAGS_READ_WRITE,
204 			lacl->se_lun_nacl);
205 
206 	pr_debug("%s_ConfigFS: Changed Initiator ACL: %s"
207 		" Mapped LUN: %u Write Protect bit to %s\n",
208 		se_tpg->se_tpg_tfo->get_fabric_name(),
209 		lacl->initiatorname, lacl->mapped_lun, (op) ? "ON" : "OFF");
210 
211 	return count;
212 
213 }
214 
215 TCM_MAPPEDLUN_ATTR(write_protect, S_IRUGO | S_IWUSR);
216 
217 CONFIGFS_EATTR_OPS(target_fabric_mappedlun, se_lun_acl, se_lun_group);
218 
target_fabric_mappedlun_release(struct config_item * item)219 static void target_fabric_mappedlun_release(struct config_item *item)
220 {
221 	struct se_lun_acl *lacl = container_of(to_config_group(item),
222 				struct se_lun_acl, se_lun_group);
223 	struct se_portal_group *se_tpg = lacl->se_lun_nacl->se_tpg;
224 
225 	core_dev_free_initiator_node_lun_acl(se_tpg, lacl);
226 }
227 
228 static struct configfs_attribute *target_fabric_mappedlun_attrs[] = {
229 	&target_fabric_mappedlun_write_protect.attr,
230 	NULL,
231 };
232 
233 static struct configfs_item_operations target_fabric_mappedlun_item_ops = {
234 	.release		= target_fabric_mappedlun_release,
235 	.show_attribute		= target_fabric_mappedlun_attr_show,
236 	.store_attribute	= target_fabric_mappedlun_attr_store,
237 	.allow_link		= target_fabric_mappedlun_link,
238 	.drop_link		= target_fabric_mappedlun_unlink,
239 };
240 
241 TF_CIT_SETUP(tpg_mappedlun, &target_fabric_mappedlun_item_ops, NULL,
242 		target_fabric_mappedlun_attrs);
243 
244 /* End of tfc_tpg_mappedlun_cit */
245 
246 /* Start of tfc_tpg_mappedlun_port_cit */
247 
target_core_mappedlun_stat_mkdir(struct config_group * group,const char * name)248 static struct config_group *target_core_mappedlun_stat_mkdir(
249 	struct config_group *group,
250 	const char *name)
251 {
252 	return ERR_PTR(-ENOSYS);
253 }
254 
target_core_mappedlun_stat_rmdir(struct config_group * group,struct config_item * item)255 static void target_core_mappedlun_stat_rmdir(
256 	struct config_group *group,
257 	struct config_item *item)
258 {
259 	return;
260 }
261 
262 static struct configfs_group_operations target_fabric_mappedlun_stat_group_ops = {
263 	.make_group		= target_core_mappedlun_stat_mkdir,
264 	.drop_item		= target_core_mappedlun_stat_rmdir,
265 };
266 
267 TF_CIT_SETUP(tpg_mappedlun_stat, NULL, &target_fabric_mappedlun_stat_group_ops,
268 		NULL);
269 
270 /* End of tfc_tpg_mappedlun_port_cit */
271 
272 /* Start of tfc_tpg_nacl_attrib_cit */
273 
274 CONFIGFS_EATTR_OPS(target_fabric_nacl_attrib, se_node_acl, acl_attrib_group);
275 
276 static struct configfs_item_operations target_fabric_nacl_attrib_item_ops = {
277 	.show_attribute		= target_fabric_nacl_attrib_attr_show,
278 	.store_attribute	= target_fabric_nacl_attrib_attr_store,
279 };
280 
281 TF_CIT_SETUP(tpg_nacl_attrib, &target_fabric_nacl_attrib_item_ops, NULL, NULL);
282 
283 /* End of tfc_tpg_nacl_attrib_cit */
284 
285 /* Start of tfc_tpg_nacl_auth_cit */
286 
287 CONFIGFS_EATTR_OPS(target_fabric_nacl_auth, se_node_acl, acl_auth_group);
288 
289 static struct configfs_item_operations target_fabric_nacl_auth_item_ops = {
290 	.show_attribute		= target_fabric_nacl_auth_attr_show,
291 	.store_attribute	= target_fabric_nacl_auth_attr_store,
292 };
293 
294 TF_CIT_SETUP(tpg_nacl_auth, &target_fabric_nacl_auth_item_ops, NULL, NULL);
295 
296 /* End of tfc_tpg_nacl_auth_cit */
297 
298 /* Start of tfc_tpg_nacl_param_cit */
299 
300 CONFIGFS_EATTR_OPS(target_fabric_nacl_param, se_node_acl, acl_param_group);
301 
302 static struct configfs_item_operations target_fabric_nacl_param_item_ops = {
303 	.show_attribute		= target_fabric_nacl_param_attr_show,
304 	.store_attribute	= target_fabric_nacl_param_attr_store,
305 };
306 
307 TF_CIT_SETUP(tpg_nacl_param, &target_fabric_nacl_param_item_ops, NULL, NULL);
308 
309 /* End of tfc_tpg_nacl_param_cit */
310 
311 /* Start of tfc_tpg_nacl_base_cit */
312 
313 CONFIGFS_EATTR_OPS(target_fabric_nacl_base, se_node_acl, acl_group);
314 
target_fabric_make_mappedlun(struct config_group * group,const char * name)315 static struct config_group *target_fabric_make_mappedlun(
316 	struct config_group *group,
317 	const char *name)
318 {
319 	struct se_node_acl *se_nacl = container_of(group,
320 			struct se_node_acl, acl_group);
321 	struct se_portal_group *se_tpg = se_nacl->se_tpg;
322 	struct target_fabric_configfs *tf = se_tpg->se_tpg_wwn->wwn_tf;
323 	struct se_lun_acl *lacl;
324 	struct config_item *acl_ci;
325 	struct config_group *lacl_cg = NULL, *ml_stat_grp = NULL;
326 	char *buf;
327 	unsigned long mapped_lun;
328 	int ret = 0;
329 
330 	acl_ci = &group->cg_item;
331 	if (!acl_ci) {
332 		pr_err("Unable to locatel acl_ci\n");
333 		return NULL;
334 	}
335 
336 	buf = kzalloc(strlen(name) + 1, GFP_KERNEL);
337 	if (!buf) {
338 		pr_err("Unable to allocate memory for name buf\n");
339 		return ERR_PTR(-ENOMEM);
340 	}
341 	snprintf(buf, strlen(name) + 1, "%s", name);
342 	/*
343 	 * Make sure user is creating iscsi/$IQN/$TPGT/acls/$INITIATOR/lun_$ID.
344 	 */
345 	if (strstr(buf, "lun_") != buf) {
346 		pr_err("Unable to locate \"lun_\" from buf: %s"
347 			" name: %s\n", buf, name);
348 		ret = -EINVAL;
349 		goto out;
350 	}
351 	/*
352 	 * Determine the Mapped LUN value.  This is what the SCSI Initiator
353 	 * Port will actually see.
354 	 */
355 	if (strict_strtoul(buf + 4, 0, &mapped_lun) || mapped_lun > UINT_MAX) {
356 		ret = -EINVAL;
357 		goto out;
358 	}
359 	if (mapped_lun > (TRANSPORT_MAX_LUNS_PER_TPG-1)) {
360 		pr_err("Mapped LUN: %lu exceeds TRANSPORT_MAX_LUNS_PER_TPG"
361 			"-1: %u for Target Portal Group: %u\n", mapped_lun,
362 			TRANSPORT_MAX_LUNS_PER_TPG-1,
363 			se_tpg->se_tpg_tfo->tpg_get_tag(se_tpg));
364 		ret = -EINVAL;
365 		goto out;
366 	}
367 
368 	lacl = core_dev_init_initiator_node_lun_acl(se_tpg, se_nacl,
369 			mapped_lun, &ret);
370 	if (!lacl) {
371 		ret = -EINVAL;
372 		goto out;
373 	}
374 
375 	lacl_cg = &lacl->se_lun_group;
376 	lacl_cg->default_groups = kzalloc(sizeof(struct config_group) * 2,
377 				GFP_KERNEL);
378 	if (!lacl_cg->default_groups) {
379 		pr_err("Unable to allocate lacl_cg->default_groups\n");
380 		ret = -ENOMEM;
381 		goto out;
382 	}
383 
384 	config_group_init_type_name(&lacl->se_lun_group, name,
385 			&TF_CIT_TMPL(tf)->tfc_tpg_mappedlun_cit);
386 	config_group_init_type_name(&lacl->ml_stat_grps.stat_group,
387 			"statistics", &TF_CIT_TMPL(tf)->tfc_tpg_mappedlun_stat_cit);
388 	lacl_cg->default_groups[0] = &lacl->ml_stat_grps.stat_group;
389 	lacl_cg->default_groups[1] = NULL;
390 
391 	ml_stat_grp = &lacl->ml_stat_grps.stat_group;
392 	ml_stat_grp->default_groups = kzalloc(sizeof(struct config_group) * 3,
393 				GFP_KERNEL);
394 	if (!ml_stat_grp->default_groups) {
395 		pr_err("Unable to allocate ml_stat_grp->default_groups\n");
396 		ret = -ENOMEM;
397 		goto out;
398 	}
399 	target_stat_setup_mappedlun_default_groups(lacl);
400 
401 	kfree(buf);
402 	return &lacl->se_lun_group;
403 out:
404 	if (lacl_cg)
405 		kfree(lacl_cg->default_groups);
406 	kfree(buf);
407 	return ERR_PTR(ret);
408 }
409 
target_fabric_drop_mappedlun(struct config_group * group,struct config_item * item)410 static void target_fabric_drop_mappedlun(
411 	struct config_group *group,
412 	struct config_item *item)
413 {
414 	struct se_lun_acl *lacl = container_of(to_config_group(item),
415 			struct se_lun_acl, se_lun_group);
416 	struct config_item *df_item;
417 	struct config_group *lacl_cg = NULL, *ml_stat_grp = NULL;
418 	int i;
419 
420 	ml_stat_grp = &lacl->ml_stat_grps.stat_group;
421 	for (i = 0; ml_stat_grp->default_groups[i]; i++) {
422 		df_item = &ml_stat_grp->default_groups[i]->cg_item;
423 		ml_stat_grp->default_groups[i] = NULL;
424 		config_item_put(df_item);
425 	}
426 	kfree(ml_stat_grp->default_groups);
427 
428 	lacl_cg = &lacl->se_lun_group;
429 	for (i = 0; lacl_cg->default_groups[i]; i++) {
430 		df_item = &lacl_cg->default_groups[i]->cg_item;
431 		lacl_cg->default_groups[i] = NULL;
432 		config_item_put(df_item);
433 	}
434 	kfree(lacl_cg->default_groups);
435 
436 	config_item_put(item);
437 }
438 
target_fabric_nacl_base_release(struct config_item * item)439 static void target_fabric_nacl_base_release(struct config_item *item)
440 {
441 	struct se_node_acl *se_nacl = container_of(to_config_group(item),
442 			struct se_node_acl, acl_group);
443 	struct se_portal_group *se_tpg = se_nacl->se_tpg;
444 	struct target_fabric_configfs *tf = se_tpg->se_tpg_wwn->wwn_tf;
445 
446 	tf->tf_ops.fabric_drop_nodeacl(se_nacl);
447 }
448 
449 static struct configfs_item_operations target_fabric_nacl_base_item_ops = {
450 	.release		= target_fabric_nacl_base_release,
451 	.show_attribute		= target_fabric_nacl_base_attr_show,
452 	.store_attribute	= target_fabric_nacl_base_attr_store,
453 };
454 
455 static struct configfs_group_operations target_fabric_nacl_base_group_ops = {
456 	.make_group		= target_fabric_make_mappedlun,
457 	.drop_item		= target_fabric_drop_mappedlun,
458 };
459 
460 TF_CIT_SETUP(tpg_nacl_base, &target_fabric_nacl_base_item_ops,
461 		&target_fabric_nacl_base_group_ops, NULL);
462 
463 /* End of tfc_tpg_nacl_base_cit */
464 
465 /* Start of tfc_node_fabric_stats_cit */
466 /*
467  * This is used as a placeholder for struct se_node_acl->acl_fabric_stat_group
468  * to allow fabrics access to ->acl_fabric_stat_group->default_groups[]
469  */
470 TF_CIT_SETUP(tpg_nacl_stat, NULL, NULL, NULL);
471 
472 /* End of tfc_wwn_fabric_stats_cit */
473 
474 /* Start of tfc_tpg_nacl_cit */
475 
target_fabric_make_nodeacl(struct config_group * group,const char * name)476 static struct config_group *target_fabric_make_nodeacl(
477 	struct config_group *group,
478 	const char *name)
479 {
480 	struct se_portal_group *se_tpg = container_of(group,
481 			struct se_portal_group, tpg_acl_group);
482 	struct target_fabric_configfs *tf = se_tpg->se_tpg_wwn->wwn_tf;
483 	struct se_node_acl *se_nacl;
484 	struct config_group *nacl_cg;
485 
486 	if (!tf->tf_ops.fabric_make_nodeacl) {
487 		pr_err("tf->tf_ops.fabric_make_nodeacl is NULL\n");
488 		return ERR_PTR(-ENOSYS);
489 	}
490 
491 	se_nacl = tf->tf_ops.fabric_make_nodeacl(se_tpg, group, name);
492 	if (IS_ERR(se_nacl))
493 		return ERR_CAST(se_nacl);
494 
495 	nacl_cg = &se_nacl->acl_group;
496 	nacl_cg->default_groups = se_nacl->acl_default_groups;
497 	nacl_cg->default_groups[0] = &se_nacl->acl_attrib_group;
498 	nacl_cg->default_groups[1] = &se_nacl->acl_auth_group;
499 	nacl_cg->default_groups[2] = &se_nacl->acl_param_group;
500 	nacl_cg->default_groups[3] = &se_nacl->acl_fabric_stat_group;
501 	nacl_cg->default_groups[4] = NULL;
502 
503 	config_group_init_type_name(&se_nacl->acl_group, name,
504 			&TF_CIT_TMPL(tf)->tfc_tpg_nacl_base_cit);
505 	config_group_init_type_name(&se_nacl->acl_attrib_group, "attrib",
506 			&TF_CIT_TMPL(tf)->tfc_tpg_nacl_attrib_cit);
507 	config_group_init_type_name(&se_nacl->acl_auth_group, "auth",
508 			&TF_CIT_TMPL(tf)->tfc_tpg_nacl_auth_cit);
509 	config_group_init_type_name(&se_nacl->acl_param_group, "param",
510 			&TF_CIT_TMPL(tf)->tfc_tpg_nacl_param_cit);
511 	config_group_init_type_name(&se_nacl->acl_fabric_stat_group,
512 			"fabric_statistics",
513 			&TF_CIT_TMPL(tf)->tfc_tpg_nacl_stat_cit);
514 
515 	return &se_nacl->acl_group;
516 }
517 
target_fabric_drop_nodeacl(struct config_group * group,struct config_item * item)518 static void target_fabric_drop_nodeacl(
519 	struct config_group *group,
520 	struct config_item *item)
521 {
522 	struct se_node_acl *se_nacl = container_of(to_config_group(item),
523 			struct se_node_acl, acl_group);
524 	struct config_item *df_item;
525 	struct config_group *nacl_cg;
526 	int i;
527 
528 	nacl_cg = &se_nacl->acl_group;
529 	for (i = 0; nacl_cg->default_groups[i]; i++) {
530 		df_item = &nacl_cg->default_groups[i]->cg_item;
531 		nacl_cg->default_groups[i] = NULL;
532 		config_item_put(df_item);
533 	}
534 	/*
535 	 * struct se_node_acl free is done in target_fabric_nacl_base_release()
536 	 */
537 	config_item_put(item);
538 }
539 
540 static struct configfs_group_operations target_fabric_nacl_group_ops = {
541 	.make_group	= target_fabric_make_nodeacl,
542 	.drop_item	= target_fabric_drop_nodeacl,
543 };
544 
545 TF_CIT_SETUP(tpg_nacl, NULL, &target_fabric_nacl_group_ops, NULL);
546 
547 /* End of tfc_tpg_nacl_cit */
548 
549 /* Start of tfc_tpg_np_base_cit */
550 
551 CONFIGFS_EATTR_OPS(target_fabric_np_base, se_tpg_np, tpg_np_group);
552 
target_fabric_np_base_release(struct config_item * item)553 static void target_fabric_np_base_release(struct config_item *item)
554 {
555 	struct se_tpg_np *se_tpg_np = container_of(to_config_group(item),
556 				struct se_tpg_np, tpg_np_group);
557 	struct se_portal_group *se_tpg = se_tpg_np->tpg_np_parent;
558 	struct target_fabric_configfs *tf = se_tpg->se_tpg_wwn->wwn_tf;
559 
560 	tf->tf_ops.fabric_drop_np(se_tpg_np);
561 }
562 
563 static struct configfs_item_operations target_fabric_np_base_item_ops = {
564 	.release		= target_fabric_np_base_release,
565 	.show_attribute		= target_fabric_np_base_attr_show,
566 	.store_attribute	= target_fabric_np_base_attr_store,
567 };
568 
569 TF_CIT_SETUP(tpg_np_base, &target_fabric_np_base_item_ops, NULL, NULL);
570 
571 /* End of tfc_tpg_np_base_cit */
572 
573 /* Start of tfc_tpg_np_cit */
574 
target_fabric_make_np(struct config_group * group,const char * name)575 static struct config_group *target_fabric_make_np(
576 	struct config_group *group,
577 	const char *name)
578 {
579 	struct se_portal_group *se_tpg = container_of(group,
580 				struct se_portal_group, tpg_np_group);
581 	struct target_fabric_configfs *tf = se_tpg->se_tpg_wwn->wwn_tf;
582 	struct se_tpg_np *se_tpg_np;
583 
584 	if (!tf->tf_ops.fabric_make_np) {
585 		pr_err("tf->tf_ops.fabric_make_np is NULL\n");
586 		return ERR_PTR(-ENOSYS);
587 	}
588 
589 	se_tpg_np = tf->tf_ops.fabric_make_np(se_tpg, group, name);
590 	if (!se_tpg_np || IS_ERR(se_tpg_np))
591 		return ERR_PTR(-EINVAL);
592 
593 	se_tpg_np->tpg_np_parent = se_tpg;
594 	config_group_init_type_name(&se_tpg_np->tpg_np_group, name,
595 			&TF_CIT_TMPL(tf)->tfc_tpg_np_base_cit);
596 
597 	return &se_tpg_np->tpg_np_group;
598 }
599 
target_fabric_drop_np(struct config_group * group,struct config_item * item)600 static void target_fabric_drop_np(
601 	struct config_group *group,
602 	struct config_item *item)
603 {
604 	/*
605 	 * struct se_tpg_np is released via target_fabric_np_base_release()
606 	 */
607 	config_item_put(item);
608 }
609 
610 static struct configfs_group_operations target_fabric_np_group_ops = {
611 	.make_group	= &target_fabric_make_np,
612 	.drop_item	= &target_fabric_drop_np,
613 };
614 
615 TF_CIT_SETUP(tpg_np, NULL, &target_fabric_np_group_ops, NULL);
616 
617 /* End of tfc_tpg_np_cit */
618 
619 /* Start of tfc_tpg_port_cit */
620 
621 CONFIGFS_EATTR_STRUCT(target_fabric_port, se_lun);
622 #define TCM_PORT_ATTR(_name, _mode)					\
623 static struct target_fabric_port_attribute target_fabric_port_##_name =	\
624 	__CONFIGFS_EATTR(_name, _mode,					\
625 	target_fabric_port_show_attr_##_name,				\
626 	target_fabric_port_store_attr_##_name);
627 
628 #define TCM_PORT_ATTOR_RO(_name)					\
629 	__CONFIGFS_EATTR_RO(_name,					\
630 	target_fabric_port_show_attr_##_name);
631 
632 /*
633  * alua_tg_pt_gp
634  */
target_fabric_port_show_attr_alua_tg_pt_gp(struct se_lun * lun,char * page)635 static ssize_t target_fabric_port_show_attr_alua_tg_pt_gp(
636 	struct se_lun *lun,
637 	char *page)
638 {
639 	if (!lun || !lun->lun_sep)
640 		return -ENODEV;
641 
642 	return core_alua_show_tg_pt_gp_info(lun->lun_sep, page);
643 }
644 
target_fabric_port_store_attr_alua_tg_pt_gp(struct se_lun * lun,const char * page,size_t count)645 static ssize_t target_fabric_port_store_attr_alua_tg_pt_gp(
646 	struct se_lun *lun,
647 	const char *page,
648 	size_t count)
649 {
650 	if (!lun || !lun->lun_sep)
651 		return -ENODEV;
652 
653 	return core_alua_store_tg_pt_gp_info(lun->lun_sep, page, count);
654 }
655 
656 TCM_PORT_ATTR(alua_tg_pt_gp, S_IRUGO | S_IWUSR);
657 
658 /*
659  * alua_tg_pt_offline
660  */
target_fabric_port_show_attr_alua_tg_pt_offline(struct se_lun * lun,char * page)661 static ssize_t target_fabric_port_show_attr_alua_tg_pt_offline(
662 	struct se_lun *lun,
663 	char *page)
664 {
665 	if (!lun || !lun->lun_sep)
666 		return -ENODEV;
667 
668 	return core_alua_show_offline_bit(lun, page);
669 }
670 
target_fabric_port_store_attr_alua_tg_pt_offline(struct se_lun * lun,const char * page,size_t count)671 static ssize_t target_fabric_port_store_attr_alua_tg_pt_offline(
672 	struct se_lun *lun,
673 	const char *page,
674 	size_t count)
675 {
676 	if (!lun || !lun->lun_sep)
677 		return -ENODEV;
678 
679 	return core_alua_store_offline_bit(lun, page, count);
680 }
681 
682 TCM_PORT_ATTR(alua_tg_pt_offline, S_IRUGO | S_IWUSR);
683 
684 /*
685  * alua_tg_pt_status
686  */
target_fabric_port_show_attr_alua_tg_pt_status(struct se_lun * lun,char * page)687 static ssize_t target_fabric_port_show_attr_alua_tg_pt_status(
688 	struct se_lun *lun,
689 	char *page)
690 {
691 	if (!lun || !lun->lun_sep)
692 		return -ENODEV;
693 
694 	return core_alua_show_secondary_status(lun, page);
695 }
696 
target_fabric_port_store_attr_alua_tg_pt_status(struct se_lun * lun,const char * page,size_t count)697 static ssize_t target_fabric_port_store_attr_alua_tg_pt_status(
698 	struct se_lun *lun,
699 	const char *page,
700 	size_t count)
701 {
702 	if (!lun || !lun->lun_sep)
703 		return -ENODEV;
704 
705 	return core_alua_store_secondary_status(lun, page, count);
706 }
707 
708 TCM_PORT_ATTR(alua_tg_pt_status, S_IRUGO | S_IWUSR);
709 
710 /*
711  * alua_tg_pt_write_md
712  */
target_fabric_port_show_attr_alua_tg_pt_write_md(struct se_lun * lun,char * page)713 static ssize_t target_fabric_port_show_attr_alua_tg_pt_write_md(
714 	struct se_lun *lun,
715 	char *page)
716 {
717 	if (!lun || !lun->lun_sep)
718 		return -ENODEV;
719 
720 	return core_alua_show_secondary_write_metadata(lun, page);
721 }
722 
target_fabric_port_store_attr_alua_tg_pt_write_md(struct se_lun * lun,const char * page,size_t count)723 static ssize_t target_fabric_port_store_attr_alua_tg_pt_write_md(
724 	struct se_lun *lun,
725 	const char *page,
726 	size_t count)
727 {
728 	if (!lun || !lun->lun_sep)
729 		return -ENODEV;
730 
731 	return core_alua_store_secondary_write_metadata(lun, page, count);
732 }
733 
734 TCM_PORT_ATTR(alua_tg_pt_write_md, S_IRUGO | S_IWUSR);
735 
736 
737 static struct configfs_attribute *target_fabric_port_attrs[] = {
738 	&target_fabric_port_alua_tg_pt_gp.attr,
739 	&target_fabric_port_alua_tg_pt_offline.attr,
740 	&target_fabric_port_alua_tg_pt_status.attr,
741 	&target_fabric_port_alua_tg_pt_write_md.attr,
742 	NULL,
743 };
744 
745 CONFIGFS_EATTR_OPS(target_fabric_port, se_lun, lun_group);
746 
target_fabric_port_link(struct config_item * lun_ci,struct config_item * se_dev_ci)747 static int target_fabric_port_link(
748 	struct config_item *lun_ci,
749 	struct config_item *se_dev_ci)
750 {
751 	struct config_item *tpg_ci;
752 	struct se_device *dev;
753 	struct se_lun *lun = container_of(to_config_group(lun_ci),
754 				struct se_lun, lun_group);
755 	struct se_lun *lun_p;
756 	struct se_portal_group *se_tpg;
757 	struct se_subsystem_dev *se_dev = container_of(
758 				to_config_group(se_dev_ci), struct se_subsystem_dev,
759 				se_dev_group);
760 	struct target_fabric_configfs *tf;
761 	int ret;
762 
763 	tpg_ci = &lun_ci->ci_parent->ci_group->cg_item;
764 	se_tpg = container_of(to_config_group(tpg_ci),
765 				struct se_portal_group, tpg_group);
766 	tf = se_tpg->se_tpg_wwn->wwn_tf;
767 
768 	if (lun->lun_se_dev !=  NULL) {
769 		pr_err("Port Symlink already exists\n");
770 		return -EEXIST;
771 	}
772 
773 	dev = se_dev->se_dev_ptr;
774 	if (!dev) {
775 		pr_err("Unable to locate struct se_device pointer from"
776 			" %s\n", config_item_name(se_dev_ci));
777 		ret = -ENODEV;
778 		goto out;
779 	}
780 	if (dev->dev_link_magic != SE_DEV_LINK_MAGIC) {
781 		pr_err("Bad dev->dev_link_magic, not a valid se_dev_ci pointer:"
782 			" %p to struct se_device: %p\n", se_dev_ci, dev);
783 		return -EFAULT;
784 	}
785 
786 	lun_p = core_dev_add_lun(se_tpg, dev->se_hba, dev,
787 				lun->unpacked_lun);
788 	if (IS_ERR(lun_p)) {
789 		pr_err("core_dev_add_lun() failed\n");
790 		ret = PTR_ERR(lun_p);
791 		goto out;
792 	}
793 
794 	if (tf->tf_ops.fabric_post_link) {
795 		/*
796 		 * Call the optional fabric_post_link() to allow a
797 		 * fabric module to setup any additional state once
798 		 * core_dev_add_lun() has been called..
799 		 */
800 		tf->tf_ops.fabric_post_link(se_tpg, lun);
801 	}
802 
803 	return 0;
804 out:
805 	return ret;
806 }
807 
target_fabric_port_unlink(struct config_item * lun_ci,struct config_item * se_dev_ci)808 static int target_fabric_port_unlink(
809 	struct config_item *lun_ci,
810 	struct config_item *se_dev_ci)
811 {
812 	struct se_lun *lun = container_of(to_config_group(lun_ci),
813 				struct se_lun, lun_group);
814 	struct se_portal_group *se_tpg = lun->lun_sep->sep_tpg;
815 	struct target_fabric_configfs *tf = se_tpg->se_tpg_wwn->wwn_tf;
816 
817 	if (tf->tf_ops.fabric_pre_unlink) {
818 		/*
819 		 * Call the optional fabric_pre_unlink() to allow a
820 		 * fabric module to release any additional stat before
821 		 * core_dev_del_lun() is called.
822 		*/
823 		tf->tf_ops.fabric_pre_unlink(se_tpg, lun);
824 	}
825 
826 	core_dev_del_lun(se_tpg, lun->unpacked_lun);
827 	return 0;
828 }
829 
830 static struct configfs_item_operations target_fabric_port_item_ops = {
831 	.show_attribute		= target_fabric_port_attr_show,
832 	.store_attribute	= target_fabric_port_attr_store,
833 	.allow_link		= target_fabric_port_link,
834 	.drop_link		= target_fabric_port_unlink,
835 };
836 
837 TF_CIT_SETUP(tpg_port, &target_fabric_port_item_ops, NULL, target_fabric_port_attrs);
838 
839 /* End of tfc_tpg_port_cit */
840 
841 /* Start of tfc_tpg_port_stat_cit */
842 
target_core_port_stat_mkdir(struct config_group * group,const char * name)843 static struct config_group *target_core_port_stat_mkdir(
844 	struct config_group *group,
845 	const char *name)
846 {
847 	return ERR_PTR(-ENOSYS);
848 }
849 
target_core_port_stat_rmdir(struct config_group * group,struct config_item * item)850 static void target_core_port_stat_rmdir(
851 	struct config_group *group,
852 	struct config_item *item)
853 {
854 	return;
855 }
856 
857 static struct configfs_group_operations target_fabric_port_stat_group_ops = {
858 	.make_group		= target_core_port_stat_mkdir,
859 	.drop_item		= target_core_port_stat_rmdir,
860 };
861 
862 TF_CIT_SETUP(tpg_port_stat, NULL, &target_fabric_port_stat_group_ops, NULL);
863 
864 /* End of tfc_tpg_port_stat_cit */
865 
866 /* Start of tfc_tpg_lun_cit */
867 
target_fabric_make_lun(struct config_group * group,const char * name)868 static struct config_group *target_fabric_make_lun(
869 	struct config_group *group,
870 	const char *name)
871 {
872 	struct se_lun *lun;
873 	struct se_portal_group *se_tpg = container_of(group,
874 			struct se_portal_group, tpg_lun_group);
875 	struct target_fabric_configfs *tf = se_tpg->se_tpg_wwn->wwn_tf;
876 	struct config_group *lun_cg = NULL, *port_stat_grp = NULL;
877 	unsigned long unpacked_lun;
878 	int errno;
879 
880 	if (strstr(name, "lun_") != name) {
881 		pr_err("Unable to locate \'_\" in"
882 				" \"lun_$LUN_NUMBER\"\n");
883 		return ERR_PTR(-EINVAL);
884 	}
885 	if (strict_strtoul(name + 4, 0, &unpacked_lun) || unpacked_lun > UINT_MAX)
886 		return ERR_PTR(-EINVAL);
887 
888 	lun = core_get_lun_from_tpg(se_tpg, unpacked_lun);
889 	if (!lun)
890 		return ERR_PTR(-EINVAL);
891 
892 	lun_cg = &lun->lun_group;
893 	lun_cg->default_groups = kzalloc(sizeof(struct config_group) * 2,
894 				GFP_KERNEL);
895 	if (!lun_cg->default_groups) {
896 		pr_err("Unable to allocate lun_cg->default_groups\n");
897 		return ERR_PTR(-ENOMEM);
898 	}
899 
900 	config_group_init_type_name(&lun->lun_group, name,
901 			&TF_CIT_TMPL(tf)->tfc_tpg_port_cit);
902 	config_group_init_type_name(&lun->port_stat_grps.stat_group,
903 			"statistics", &TF_CIT_TMPL(tf)->tfc_tpg_port_stat_cit);
904 	lun_cg->default_groups[0] = &lun->port_stat_grps.stat_group;
905 	lun_cg->default_groups[1] = NULL;
906 
907 	port_stat_grp = &lun->port_stat_grps.stat_group;
908 	port_stat_grp->default_groups =  kzalloc(sizeof(struct config_group) * 3,
909 				GFP_KERNEL);
910 	if (!port_stat_grp->default_groups) {
911 		pr_err("Unable to allocate port_stat_grp->default_groups\n");
912 		errno = -ENOMEM;
913 		goto out;
914 	}
915 	target_stat_setup_port_default_groups(lun);
916 
917 	return &lun->lun_group;
918 out:
919 	if (lun_cg)
920 		kfree(lun_cg->default_groups);
921 	return ERR_PTR(errno);
922 }
923 
target_fabric_drop_lun(struct config_group * group,struct config_item * item)924 static void target_fabric_drop_lun(
925 	struct config_group *group,
926 	struct config_item *item)
927 {
928 	struct se_lun *lun = container_of(to_config_group(item),
929 				struct se_lun, lun_group);
930 	struct config_item *df_item;
931 	struct config_group *lun_cg, *port_stat_grp;
932 	int i;
933 
934 	port_stat_grp = &lun->port_stat_grps.stat_group;
935 	for (i = 0; port_stat_grp->default_groups[i]; i++) {
936 		df_item = &port_stat_grp->default_groups[i]->cg_item;
937 		port_stat_grp->default_groups[i] = NULL;
938 		config_item_put(df_item);
939 	}
940 	kfree(port_stat_grp->default_groups);
941 
942 	lun_cg = &lun->lun_group;
943 	for (i = 0; lun_cg->default_groups[i]; i++) {
944 		df_item = &lun_cg->default_groups[i]->cg_item;
945 		lun_cg->default_groups[i] = NULL;
946 		config_item_put(df_item);
947 	}
948 	kfree(lun_cg->default_groups);
949 
950 	config_item_put(item);
951 }
952 
953 static struct configfs_group_operations target_fabric_lun_group_ops = {
954 	.make_group	= &target_fabric_make_lun,
955 	.drop_item	= &target_fabric_drop_lun,
956 };
957 
958 TF_CIT_SETUP(tpg_lun, NULL, &target_fabric_lun_group_ops, NULL);
959 
960 /* End of tfc_tpg_lun_cit */
961 
962 /* Start of tfc_tpg_attrib_cit */
963 
964 CONFIGFS_EATTR_OPS(target_fabric_tpg_attrib, se_portal_group, tpg_attrib_group);
965 
966 static struct configfs_item_operations target_fabric_tpg_attrib_item_ops = {
967 	.show_attribute		= target_fabric_tpg_attrib_attr_show,
968 	.store_attribute	= target_fabric_tpg_attrib_attr_store,
969 };
970 
971 TF_CIT_SETUP(tpg_attrib, &target_fabric_tpg_attrib_item_ops, NULL, NULL);
972 
973 /* End of tfc_tpg_attrib_cit */
974 
975 /* Start of tfc_tpg_param_cit */
976 
977 CONFIGFS_EATTR_OPS(target_fabric_tpg_param, se_portal_group, tpg_param_group);
978 
979 static struct configfs_item_operations target_fabric_tpg_param_item_ops = {
980 	.show_attribute		= target_fabric_tpg_param_attr_show,
981 	.store_attribute	= target_fabric_tpg_param_attr_store,
982 };
983 
984 TF_CIT_SETUP(tpg_param, &target_fabric_tpg_param_item_ops, NULL, NULL);
985 
986 /* End of tfc_tpg_param_cit */
987 
988 /* Start of tfc_tpg_base_cit */
989 /*
990  * For use with TF_TPG_ATTR() and TF_TPG_ATTR_RO()
991  */
992 CONFIGFS_EATTR_OPS(target_fabric_tpg, se_portal_group, tpg_group);
993 
target_fabric_tpg_release(struct config_item * item)994 static void target_fabric_tpg_release(struct config_item *item)
995 {
996 	struct se_portal_group *se_tpg = container_of(to_config_group(item),
997 			struct se_portal_group, tpg_group);
998 	struct se_wwn *wwn = se_tpg->se_tpg_wwn;
999 	struct target_fabric_configfs *tf = wwn->wwn_tf;
1000 
1001 	tf->tf_ops.fabric_drop_tpg(se_tpg);
1002 }
1003 
1004 static struct configfs_item_operations target_fabric_tpg_base_item_ops = {
1005 	.release		= target_fabric_tpg_release,
1006 	.show_attribute		= target_fabric_tpg_attr_show,
1007 	.store_attribute	= target_fabric_tpg_attr_store,
1008 };
1009 
1010 TF_CIT_SETUP(tpg_base, &target_fabric_tpg_base_item_ops, NULL, NULL);
1011 
1012 /* End of tfc_tpg_base_cit */
1013 
1014 /* Start of tfc_tpg_cit */
1015 
target_fabric_make_tpg(struct config_group * group,const char * name)1016 static struct config_group *target_fabric_make_tpg(
1017 	struct config_group *group,
1018 	const char *name)
1019 {
1020 	struct se_wwn *wwn = container_of(group, struct se_wwn, wwn_group);
1021 	struct target_fabric_configfs *tf = wwn->wwn_tf;
1022 	struct se_portal_group *se_tpg;
1023 
1024 	if (!tf->tf_ops.fabric_make_tpg) {
1025 		pr_err("tf->tf_ops.fabric_make_tpg is NULL\n");
1026 		return ERR_PTR(-ENOSYS);
1027 	}
1028 
1029 	se_tpg = tf->tf_ops.fabric_make_tpg(wwn, group, name);
1030 	if (!se_tpg || IS_ERR(se_tpg))
1031 		return ERR_PTR(-EINVAL);
1032 	/*
1033 	 * Setup default groups from pre-allocated se_tpg->tpg_default_groups
1034 	 */
1035 	se_tpg->tpg_group.default_groups = se_tpg->tpg_default_groups;
1036 	se_tpg->tpg_group.default_groups[0] = &se_tpg->tpg_lun_group;
1037 	se_tpg->tpg_group.default_groups[1] = &se_tpg->tpg_np_group;
1038 	se_tpg->tpg_group.default_groups[2] = &se_tpg->tpg_acl_group;
1039 	se_tpg->tpg_group.default_groups[3] = &se_tpg->tpg_attrib_group;
1040 	se_tpg->tpg_group.default_groups[4] = &se_tpg->tpg_param_group;
1041 	se_tpg->tpg_group.default_groups[5] = NULL;
1042 
1043 	config_group_init_type_name(&se_tpg->tpg_group, name,
1044 			&TF_CIT_TMPL(tf)->tfc_tpg_base_cit);
1045 	config_group_init_type_name(&se_tpg->tpg_lun_group, "lun",
1046 			&TF_CIT_TMPL(tf)->tfc_tpg_lun_cit);
1047 	config_group_init_type_name(&se_tpg->tpg_np_group, "np",
1048 			&TF_CIT_TMPL(tf)->tfc_tpg_np_cit);
1049 	config_group_init_type_name(&se_tpg->tpg_acl_group, "acls",
1050 			&TF_CIT_TMPL(tf)->tfc_tpg_nacl_cit);
1051 	config_group_init_type_name(&se_tpg->tpg_attrib_group, "attrib",
1052 			&TF_CIT_TMPL(tf)->tfc_tpg_attrib_cit);
1053 	config_group_init_type_name(&se_tpg->tpg_param_group, "param",
1054 			&TF_CIT_TMPL(tf)->tfc_tpg_param_cit);
1055 
1056 	return &se_tpg->tpg_group;
1057 }
1058 
target_fabric_drop_tpg(struct config_group * group,struct config_item * item)1059 static void target_fabric_drop_tpg(
1060 	struct config_group *group,
1061 	struct config_item *item)
1062 {
1063 	struct se_portal_group *se_tpg = container_of(to_config_group(item),
1064 				struct se_portal_group, tpg_group);
1065 	struct config_group *tpg_cg = &se_tpg->tpg_group;
1066 	struct config_item *df_item;
1067 	int i;
1068 	/*
1069 	 * Release default groups, but do not release tpg_cg->default_groups
1070 	 * memory as it is statically allocated at se_tpg->tpg_default_groups.
1071 	 */
1072 	for (i = 0; tpg_cg->default_groups[i]; i++) {
1073 		df_item = &tpg_cg->default_groups[i]->cg_item;
1074 		tpg_cg->default_groups[i] = NULL;
1075 		config_item_put(df_item);
1076 	}
1077 
1078 	config_item_put(item);
1079 }
1080 
target_fabric_release_wwn(struct config_item * item)1081 static void target_fabric_release_wwn(struct config_item *item)
1082 {
1083 	struct se_wwn *wwn = container_of(to_config_group(item),
1084 				struct se_wwn, wwn_group);
1085 	struct target_fabric_configfs *tf = wwn->wwn_tf;
1086 
1087 	tf->tf_ops.fabric_drop_wwn(wwn);
1088 }
1089 
1090 static struct configfs_item_operations target_fabric_tpg_item_ops = {
1091 	.release	= target_fabric_release_wwn,
1092 };
1093 
1094 static struct configfs_group_operations target_fabric_tpg_group_ops = {
1095 	.make_group	= target_fabric_make_tpg,
1096 	.drop_item	= target_fabric_drop_tpg,
1097 };
1098 
1099 TF_CIT_SETUP(tpg, &target_fabric_tpg_item_ops, &target_fabric_tpg_group_ops,
1100 		NULL);
1101 
1102 /* End of tfc_tpg_cit */
1103 
1104 /* Start of tfc_wwn_fabric_stats_cit */
1105 /*
1106  * This is used as a placeholder for struct se_wwn->fabric_stat_group
1107  * to allow fabrics access to ->fabric_stat_group->default_groups[]
1108  */
1109 TF_CIT_SETUP(wwn_fabric_stats, NULL, NULL, NULL);
1110 
1111 /* End of tfc_wwn_fabric_stats_cit */
1112 
1113 /* Start of tfc_wwn_cit */
1114 
target_fabric_make_wwn(struct config_group * group,const char * name)1115 static struct config_group *target_fabric_make_wwn(
1116 	struct config_group *group,
1117 	const char *name)
1118 {
1119 	struct target_fabric_configfs *tf = container_of(group,
1120 				struct target_fabric_configfs, tf_group);
1121 	struct se_wwn *wwn;
1122 
1123 	if (!tf->tf_ops.fabric_make_wwn) {
1124 		pr_err("tf->tf_ops.fabric_make_wwn is NULL\n");
1125 		return ERR_PTR(-ENOSYS);
1126 	}
1127 
1128 	wwn = tf->tf_ops.fabric_make_wwn(tf, group, name);
1129 	if (!wwn || IS_ERR(wwn))
1130 		return ERR_PTR(-EINVAL);
1131 
1132 	wwn->wwn_tf = tf;
1133 	/*
1134 	 * Setup default groups from pre-allocated wwn->wwn_default_groups
1135 	 */
1136 	wwn->wwn_group.default_groups = wwn->wwn_default_groups;
1137 	wwn->wwn_group.default_groups[0] = &wwn->fabric_stat_group;
1138 	wwn->wwn_group.default_groups[1] = NULL;
1139 
1140 	config_group_init_type_name(&wwn->wwn_group, name,
1141 			&TF_CIT_TMPL(tf)->tfc_tpg_cit);
1142 	config_group_init_type_name(&wwn->fabric_stat_group, "fabric_statistics",
1143 			&TF_CIT_TMPL(tf)->tfc_wwn_fabric_stats_cit);
1144 
1145 	return &wwn->wwn_group;
1146 }
1147 
target_fabric_drop_wwn(struct config_group * group,struct config_item * item)1148 static void target_fabric_drop_wwn(
1149 	struct config_group *group,
1150 	struct config_item *item)
1151 {
1152 	struct se_wwn *wwn = container_of(to_config_group(item),
1153 				struct se_wwn, wwn_group);
1154 	struct config_item *df_item;
1155 	struct config_group *cg = &wwn->wwn_group;
1156 	int i;
1157 
1158 	for (i = 0; cg->default_groups[i]; i++) {
1159 		df_item = &cg->default_groups[i]->cg_item;
1160 		cg->default_groups[i] = NULL;
1161 		config_item_put(df_item);
1162 	}
1163 
1164 	config_item_put(item);
1165 }
1166 
1167 static struct configfs_group_operations target_fabric_wwn_group_ops = {
1168 	.make_group	= target_fabric_make_wwn,
1169 	.drop_item	= target_fabric_drop_wwn,
1170 };
1171 /*
1172  * For use with TF_WWN_ATTR() and TF_WWN_ATTR_RO()
1173  */
1174 CONFIGFS_EATTR_OPS(target_fabric_wwn, target_fabric_configfs, tf_group);
1175 
1176 static struct configfs_item_operations target_fabric_wwn_item_ops = {
1177 	.show_attribute		= target_fabric_wwn_attr_show,
1178 	.store_attribute	= target_fabric_wwn_attr_store,
1179 };
1180 
1181 TF_CIT_SETUP(wwn, &target_fabric_wwn_item_ops, &target_fabric_wwn_group_ops, NULL);
1182 
1183 /* End of tfc_wwn_cit */
1184 
1185 /* Start of tfc_discovery_cit */
1186 
1187 CONFIGFS_EATTR_OPS(target_fabric_discovery, target_fabric_configfs,
1188 		tf_disc_group);
1189 
1190 static struct configfs_item_operations target_fabric_discovery_item_ops = {
1191 	.show_attribute		= target_fabric_discovery_attr_show,
1192 	.store_attribute	= target_fabric_discovery_attr_store,
1193 };
1194 
1195 TF_CIT_SETUP(discovery, &target_fabric_discovery_item_ops, NULL, NULL);
1196 
1197 /* End of tfc_discovery_cit */
1198 
target_fabric_setup_cits(struct target_fabric_configfs * tf)1199 int target_fabric_setup_cits(struct target_fabric_configfs *tf)
1200 {
1201 	target_fabric_setup_discovery_cit(tf);
1202 	target_fabric_setup_wwn_cit(tf);
1203 	target_fabric_setup_wwn_fabric_stats_cit(tf);
1204 	target_fabric_setup_tpg_cit(tf);
1205 	target_fabric_setup_tpg_base_cit(tf);
1206 	target_fabric_setup_tpg_port_cit(tf);
1207 	target_fabric_setup_tpg_port_stat_cit(tf);
1208 	target_fabric_setup_tpg_lun_cit(tf);
1209 	target_fabric_setup_tpg_np_cit(tf);
1210 	target_fabric_setup_tpg_np_base_cit(tf);
1211 	target_fabric_setup_tpg_attrib_cit(tf);
1212 	target_fabric_setup_tpg_param_cit(tf);
1213 	target_fabric_setup_tpg_nacl_cit(tf);
1214 	target_fabric_setup_tpg_nacl_base_cit(tf);
1215 	target_fabric_setup_tpg_nacl_attrib_cit(tf);
1216 	target_fabric_setup_tpg_nacl_auth_cit(tf);
1217 	target_fabric_setup_tpg_nacl_param_cit(tf);
1218 	target_fabric_setup_tpg_nacl_stat_cit(tf);
1219 	target_fabric_setup_tpg_mappedlun_cit(tf);
1220 	target_fabric_setup_tpg_mappedlun_stat_cit(tf);
1221 
1222 	return 0;
1223 }
1224