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