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