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