blob: e9e917cc6441913326316e75cc42dab99cf353c3 [file] [log] [blame]
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001/*******************************************************************************
2* Filename: target_core_fabric_configfs.c
3 *
4 * This file contains generic fabric module configfs infrastructure for
5 * TCM v4.x code
6 *
Nicholas Bellinger4c762512013-09-05 15:29:12 -07007 * (c) Copyright 2010-2013 Datera, Inc.
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08008 *
Nicholas Bellingerfd9a11d2012-11-09 14:51:48 -08009 * Nicholas A. Bellinger <nab@linux-iscsi.org>
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -080010*
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>
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -080024#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>
Christoph Hellwigc4795fb2011-11-16 09:46:48 -050037#include <target/target_core_fabric.h>
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -080038
Christoph Hellwige26d99a2011-11-14 12:30:30 -050039#include "target_core_internal.h"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -080040#include "target_core_alua.h"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -080041#include "target_core_pr.h"
42
43#define TF_CIT_SETUP(_name, _item_ops, _group_ops, _attrs) \
44static void target_fabric_setup_##_name##_cit(struct target_fabric_configfs *tf) \
45{ \
Christoph Hellwig968ebe72015-05-03 08:50:55 +020046 struct config_item_type *cit = &tf->tf_##_name##_cit; \
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -080047 \
48 cit->ct_item_ops = _item_ops; \
49 cit->ct_group_ops = _group_ops; \
50 cit->ct_attrs = _attrs; \
Christoph Hellwig0dc2e8d2015-05-03 08:50:54 +020051 cit->ct_owner = tf->tf_ops->module; \
Andy Grover6708bb22011-06-08 10:36:43 -070052 pr_debug("Setup generic %s\n", __stringify(_name)); \
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -080053}
54
Christoph Hellwig9ac89282015-04-08 20:01:35 +020055#define TF_CIT_SETUP_DRV(_name, _item_ops, _group_ops) \
56static void target_fabric_setup_##_name##_cit(struct target_fabric_configfs *tf) \
57{ \
Christoph Hellwig968ebe72015-05-03 08:50:55 +020058 struct config_item_type *cit = &tf->tf_##_name##_cit; \
Christoph Hellwigef0caf82015-05-03 08:50:53 +020059 struct configfs_attribute **attrs = tf->tf_ops->tfc_##_name##_attrs; \
Christoph Hellwig9ac89282015-04-08 20:01:35 +020060 \
61 cit->ct_item_ops = _item_ops; \
62 cit->ct_group_ops = _group_ops; \
63 cit->ct_attrs = attrs; \
Christoph Hellwig0dc2e8d2015-05-03 08:50:54 +020064 cit->ct_owner = tf->tf_ops->module; \
Christoph Hellwig9ac89282015-04-08 20:01:35 +020065 pr_debug("Setup generic %s\n", __stringify(_name)); \
66}
67
Nicholas Bellinger9ae0e9ad2017-06-01 03:11:18 -070068static struct configfs_item_operations target_fabric_port_item_ops;
69
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -080070/* Start of tfc_tpg_mappedlun_cit */
71
72static 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;
Nicholas Bellinger9ae0e9ad2017-06-01 03:11:18 -070077 struct se_lun *lun;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -080078 struct se_lun_acl *lacl = container_of(to_config_group(lun_acl_ci),
79 struct se_lun_acl, se_lun_group);
80 struct se_portal_group *se_tpg;
81 struct config_item *nacl_ci, *tpg_ci, *tpg_ci_s, *wwn_ci, *wwn_ci_s;
Andy Grover03a68b42016-02-25 15:14:32 -080082 bool lun_access_ro;
Nicholas Bellinger0ff87542012-12-04 23:43:57 -080083
Nicholas Bellinger9ae0e9ad2017-06-01 03:11:18 -070084 if (!lun_ci->ci_type ||
85 lun_ci->ci_type->ct_item_ops != &target_fabric_port_item_ops) {
86 pr_err("Bad lun_ci, not a valid lun_ci pointer: %p\n", lun_ci);
Nicholas Bellinger0ff87542012-12-04 23:43:57 -080087 return -EFAULT;
88 }
Nicholas Bellinger9ae0e9ad2017-06-01 03:11:18 -070089 lun = container_of(to_config_group(lun_ci), struct se_lun, lun_group);
90
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -080091 /*
92 * Ensure that the source port exists
93 */
Christoph Hellwigadf653f2015-05-25 21:33:08 -070094 if (!lun->lun_se_dev) {
95 pr_err("Source se_lun->lun_se_dev does not exist\n");
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -080096 return -EINVAL;
97 }
Nicholas Bellinger49cb77e2017-03-27 16:12:43 -070098 if (lun->lun_shutdown) {
99 pr_err("Unable to create mappedlun symlink because"
100 " lun->lun_shutdown=true\n");
101 return -EINVAL;
102 }
Christoph Hellwigadf653f2015-05-25 21:33:08 -0700103 se_tpg = lun->lun_tpg;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800104
105 nacl_ci = &lun_acl_ci->ci_parent->ci_group->cg_item;
106 tpg_ci = &nacl_ci->ci_group->cg_item;
107 wwn_ci = &tpg_ci->ci_group->cg_item;
108 tpg_ci_s = &lun_ci->ci_parent->ci_group->cg_item;
109 wwn_ci_s = &tpg_ci_s->ci_group->cg_item;
110 /*
111 * Make sure the SymLink is going to the same $FABRIC/$WWN/tpgt_$TPGT
112 */
113 if (strcmp(config_item_name(wwn_ci), config_item_name(wwn_ci_s))) {
Andy Grover6708bb22011-06-08 10:36:43 -0700114 pr_err("Illegal Initiator ACL SymLink outside of %s\n",
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800115 config_item_name(wwn_ci));
116 return -EINVAL;
117 }
118 if (strcmp(config_item_name(tpg_ci), config_item_name(tpg_ci_s))) {
Andy Grover6708bb22011-06-08 10:36:43 -0700119 pr_err("Illegal Initiator ACL Symlink outside of %s"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800120 " TPGT: %s\n", config_item_name(wwn_ci),
121 config_item_name(tpg_ci));
122 return -EINVAL;
123 }
124 /*
125 * If this struct se_node_acl was dynamically generated with
Andy Grover03a68b42016-02-25 15:14:32 -0800126 * tpg_1/attrib/generate_node_acls=1, use the existing
127 * deve->lun_access_ro value, which will be true when
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800128 * tpg_1/attrib/demo_mode_write_protect=1
129 */
Nicholas Bellinger29a05de2015-03-22 20:42:19 -0700130 rcu_read_lock();
131 deve = target_nacl_find_deve(lacl->se_lun_nacl, lacl->mapped_lun);
132 if (deve)
Andy Grover03a68b42016-02-25 15:14:32 -0800133 lun_access_ro = deve->lun_access_ro;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800134 else
Andy Grover03a68b42016-02-25 15:14:32 -0800135 lun_access_ro =
Andy Grovere3d6f902011-07-19 08:55:10 +0000136 (se_tpg->se_tpg_tfo->tpg_check_prod_mode_write_protect(
Andy Grover03a68b42016-02-25 15:14:32 -0800137 se_tpg)) ? true : false;
Nicholas Bellinger29a05de2015-03-22 20:42:19 -0700138 rcu_read_unlock();
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800139 /*
140 * Determine the actual mapped LUN value user wants..
141 *
142 * This value is what the SCSI Initiator actually sees the
Nicholas Bellinger6bb82612015-05-10 19:31:10 -0700143 * $FABRIC/$WWPN/$TPGT/lun/lun_* as on their SCSI Initiator Ports.
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800144 */
Andy Grover03a68b42016-02-25 15:14:32 -0800145 return core_dev_add_initiator_node_lun_acl(se_tpg, lacl, lun, lun_access_ro);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800146}
147
Andrzej Pietrasiewicze16769d2016-11-28 13:22:42 +0100148static void target_fabric_mappedlun_unlink(
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800149 struct config_item *lun_acl_ci,
150 struct config_item *lun_ci)
151{
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800152 struct se_lun_acl *lacl = container_of(to_config_group(lun_acl_ci),
153 struct se_lun_acl, se_lun_group);
Nicholas Bellinger29a05de2015-03-22 20:42:19 -0700154 struct se_lun *lun = container_of(to_config_group(lun_ci),
155 struct se_lun, lun_group);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800156
Andrzej Pietrasiewicze16769d2016-11-28 13:22:42 +0100157 core_dev_del_initiator_node_lun_acl(lun, lacl);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800158}
159
Christoph Hellwig2eafd722015-10-03 15:32:55 +0200160static struct se_lun_acl *item_to_lun_acl(struct config_item *item)
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800161{
Christoph Hellwig2eafd722015-10-03 15:32:55 +0200162 return container_of(to_config_group(item), struct se_lun_acl,
163 se_lun_group);
164}
165
166static ssize_t target_fabric_mappedlun_write_protect_show(
167 struct config_item *item, char *page)
168{
169 struct se_lun_acl *lacl = item_to_lun_acl(item);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800170 struct se_node_acl *se_nacl = lacl->se_lun_nacl;
171 struct se_dev_entry *deve;
Nicholas Bellinger29a05de2015-03-22 20:42:19 -0700172 ssize_t len = 0;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800173
Nicholas Bellinger29a05de2015-03-22 20:42:19 -0700174 rcu_read_lock();
175 deve = target_nacl_find_deve(se_nacl, lacl->mapped_lun);
176 if (deve) {
Andy Grover03a68b42016-02-25 15:14:32 -0800177 len = sprintf(page, "%d\n", deve->lun_access_ro);
Nicholas Bellinger29a05de2015-03-22 20:42:19 -0700178 }
179 rcu_read_unlock();
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800180
181 return len;
182}
183
Christoph Hellwig2eafd722015-10-03 15:32:55 +0200184static ssize_t target_fabric_mappedlun_write_protect_store(
185 struct config_item *item, const char *page, size_t count)
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800186{
Christoph Hellwig2eafd722015-10-03 15:32:55 +0200187 struct se_lun_acl *lacl = item_to_lun_acl(item);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800188 struct se_node_acl *se_nacl = lacl->se_lun_nacl;
189 struct se_portal_group *se_tpg = se_nacl->se_tpg;
Andy Grover03a68b42016-02-25 15:14:32 -0800190 unsigned long wp;
Jingoo Han57103d72013-07-19 16:22:19 +0900191 int ret;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800192
Andy Grover03a68b42016-02-25 15:14:32 -0800193 ret = kstrtoul(page, 0, &wp);
Jingoo Han57103d72013-07-19 16:22:19 +0900194 if (ret)
195 return ret;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800196
Andy Grover03a68b42016-02-25 15:14:32 -0800197 if ((wp != 1) && (wp != 0))
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800198 return -EINVAL;
199
Andy Grover03a68b42016-02-25 15:14:32 -0800200 /* wp=1 means lun_access_ro=true */
201 core_update_device_list_access(lacl->mapped_lun, wp, lacl->se_lun_nacl);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800202
Andy Grover6708bb22011-06-08 10:36:43 -0700203 pr_debug("%s_ConfigFS: Changed Initiator ACL: %s"
Hannes Reineckef2d30682015-06-10 08:41:22 +0200204 " Mapped LUN: %llu Write Protect bit to %s\n",
Andy Grovere3d6f902011-07-19 08:55:10 +0000205 se_tpg->se_tpg_tfo->get_fabric_name(),
Andy Grover03a68b42016-02-25 15:14:32 -0800206 se_nacl->initiatorname, lacl->mapped_lun, (wp) ? "ON" : "OFF");
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800207
208 return count;
209
210}
211
Christoph Hellwig2eafd722015-10-03 15:32:55 +0200212CONFIGFS_ATTR(target_fabric_mappedlun_, write_protect);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800213
Christoph Hellwig2eafd722015-10-03 15:32:55 +0200214static struct configfs_attribute *target_fabric_mappedlun_attrs[] = {
215 &target_fabric_mappedlun_attr_write_protect,
216 NULL,
217};
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800218
Nicholas Bellinger1f6fe7c2011-02-09 15:34:54 -0800219static void target_fabric_mappedlun_release(struct config_item *item)
220{
221 struct se_lun_acl *lacl = container_of(to_config_group(item),
222 struct se_lun_acl, se_lun_group);
223 struct se_portal_group *se_tpg = lacl->se_lun_nacl->se_tpg;
224
225 core_dev_free_initiator_node_lun_acl(se_tpg, lacl);
226}
227
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800228static struct configfs_item_operations target_fabric_mappedlun_item_ops = {
Nicholas Bellinger1f6fe7c2011-02-09 15:34:54 -0800229 .release = target_fabric_mappedlun_release,
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800230 .allow_link = target_fabric_mappedlun_link,
231 .drop_link = target_fabric_mappedlun_unlink,
232};
233
234TF_CIT_SETUP(tpg_mappedlun, &target_fabric_mappedlun_item_ops, NULL,
235 target_fabric_mappedlun_attrs);
236
237/* End of tfc_tpg_mappedlun_cit */
238
Nicholas Bellinger12d2338422011-03-14 04:06:11 -0700239/* Start of tfc_tpg_mappedlun_port_cit */
240
241static struct config_group *target_core_mappedlun_stat_mkdir(
242 struct config_group *group,
243 const char *name)
244{
245 return ERR_PTR(-ENOSYS);
246}
247
248static void target_core_mappedlun_stat_rmdir(
249 struct config_group *group,
250 struct config_item *item)
251{
252 return;
253}
254
255static struct configfs_group_operations target_fabric_mappedlun_stat_group_ops = {
256 .make_group = target_core_mappedlun_stat_mkdir,
257 .drop_item = target_core_mappedlun_stat_rmdir,
258};
259
260TF_CIT_SETUP(tpg_mappedlun_stat, NULL, &target_fabric_mappedlun_stat_group_ops,
261 NULL);
262
263/* End of tfc_tpg_mappedlun_port_cit */
264
Christoph Hellwig2eafd722015-10-03 15:32:55 +0200265TF_CIT_SETUP_DRV(tpg_nacl_attrib, NULL, NULL);
266TF_CIT_SETUP_DRV(tpg_nacl_auth, NULL, NULL);
267TF_CIT_SETUP_DRV(tpg_nacl_param, NULL, NULL);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800268
269/* Start of tfc_tpg_nacl_base_cit */
270
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800271static struct config_group *target_fabric_make_mappedlun(
272 struct config_group *group,
273 const char *name)
274{
275 struct se_node_acl *se_nacl = container_of(group,
276 struct se_node_acl, acl_group);
277 struct se_portal_group *se_tpg = se_nacl->se_tpg;
278 struct target_fabric_configfs *tf = se_tpg->se_tpg_wwn->wwn_tf;
Joern Engelda0abae2014-09-02 17:49:57 -0400279 struct se_lun_acl *lacl = NULL;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800280 char *buf;
Hannes Reineckef2d30682015-06-10 08:41:22 +0200281 unsigned long long mapped_lun;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800282 int ret = 0;
283
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800284 buf = kzalloc(strlen(name) + 1, GFP_KERNEL);
Andy Grover6708bb22011-06-08 10:36:43 -0700285 if (!buf) {
286 pr_err("Unable to allocate memory for name buf\n");
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800287 return ERR_PTR(-ENOMEM);
288 }
289 snprintf(buf, strlen(name) + 1, "%s", name);
290 /*
291 * Make sure user is creating iscsi/$IQN/$TPGT/acls/$INITIATOR/lun_$ID.
292 */
293 if (strstr(buf, "lun_") != buf) {
Andy Grover6708bb22011-06-08 10:36:43 -0700294 pr_err("Unable to locate \"lun_\" from buf: %s"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800295 " name: %s\n", buf, name);
296 ret = -EINVAL;
297 goto out;
298 }
299 /*
300 * Determine the Mapped LUN value. This is what the SCSI Initiator
301 * Port will actually see.
302 */
Hannes Reineckef2d30682015-06-10 08:41:22 +0200303 ret = kstrtoull(buf + 4, 0, &mapped_lun);
Jingoo Han57103d72013-07-19 16:22:19 +0900304 if (ret)
305 goto out;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800306
Nicholas Bellingerfcf29482013-02-18 18:00:33 -0800307 lacl = core_dev_init_initiator_node_lun_acl(se_tpg, se_nacl,
308 mapped_lun, &ret);
Andy Grover6708bb22011-06-08 10:36:43 -0700309 if (!lacl) {
Nicholas Bellinger12d2338422011-03-14 04:06:11 -0700310 ret = -EINVAL;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800311 goto out;
Nicholas Bellinger12d2338422011-03-14 04:06:11 -0700312 }
313
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800314 config_group_init_type_name(&lacl->se_lun_group, name,
Christoph Hellwig968ebe72015-05-03 08:50:55 +0200315 &tf->tf_tpg_mappedlun_cit);
Christoph Hellwig1ae16022016-02-26 11:02:14 +0100316
Nicholas Bellinger12d2338422011-03-14 04:06:11 -0700317 config_group_init_type_name(&lacl->ml_stat_grps.stat_group,
Christoph Hellwig968ebe72015-05-03 08:50:55 +0200318 "statistics", &tf->tf_tpg_mappedlun_stat_cit);
Christoph Hellwig1ae16022016-02-26 11:02:14 +0100319 configfs_add_default_group(&lacl->ml_stat_grps.stat_group,
320 &lacl->se_lun_group);
Nicholas Bellinger12d2338422011-03-14 04:06:11 -0700321
Nicholas Bellinger12d2338422011-03-14 04:06:11 -0700322 target_stat_setup_mappedlun_default_groups(lacl);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800323
324 kfree(buf);
325 return &lacl->se_lun_group;
326out:
Joern Engelda0abae2014-09-02 17:49:57 -0400327 kfree(lacl);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800328 kfree(buf);
329 return ERR_PTR(ret);
330}
331
332static void target_fabric_drop_mappedlun(
333 struct config_group *group,
334 struct config_item *item)
335{
Nicholas Bellinger12d2338422011-03-14 04:06:11 -0700336 struct se_lun_acl *lacl = container_of(to_config_group(item),
337 struct se_lun_acl, se_lun_group);
Nicholas Bellinger12d2338422011-03-14 04:06:11 -0700338
Christoph Hellwig1ae16022016-02-26 11:02:14 +0100339 configfs_remove_default_groups(&lacl->ml_stat_grps.stat_group);
340 configfs_remove_default_groups(&lacl->se_lun_group);
Nicholas Bellinger12d2338422011-03-14 04:06:11 -0700341
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800342 config_item_put(item);
Nicholas Bellinger1f6fe7c2011-02-09 15:34:54 -0800343}
344
345static void target_fabric_nacl_base_release(struct config_item *item)
346{
347 struct se_node_acl *se_nacl = container_of(to_config_group(item),
348 struct se_node_acl, acl_group);
Nicholas Bellinger1f6fe7c2011-02-09 15:34:54 -0800349
Christoph Hellwigce7043f2016-03-29 13:03:33 +0200350 configfs_remove_default_groups(&se_nacl->acl_fabric_stat_group);
Christoph Hellwigc7d6a802015-04-13 19:51:14 +0200351 core_tpg_del_initiator_node_acl(se_nacl);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800352}
353
354static struct configfs_item_operations target_fabric_nacl_base_item_ops = {
Nicholas Bellinger1f6fe7c2011-02-09 15:34:54 -0800355 .release = target_fabric_nacl_base_release,
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800356};
357
358static struct configfs_group_operations target_fabric_nacl_base_group_ops = {
359 .make_group = target_fabric_make_mappedlun,
360 .drop_item = target_fabric_drop_mappedlun,
361};
362
Christoph Hellwig9ac89282015-04-08 20:01:35 +0200363TF_CIT_SETUP_DRV(tpg_nacl_base, &target_fabric_nacl_base_item_ops,
364 &target_fabric_nacl_base_group_ops);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800365
366/* End of tfc_tpg_nacl_base_cit */
367
Nicholas Bellinger12d2338422011-03-14 04:06:11 -0700368/* Start of tfc_node_fabric_stats_cit */
369/*
370 * This is used as a placeholder for struct se_node_acl->acl_fabric_stat_group
371 * to allow fabrics access to ->acl_fabric_stat_group->default_groups[]
372 */
373TF_CIT_SETUP(tpg_nacl_stat, NULL, NULL, NULL);
374
375/* End of tfc_wwn_fabric_stats_cit */
376
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800377/* Start of tfc_tpg_nacl_cit */
378
379static struct config_group *target_fabric_make_nodeacl(
380 struct config_group *group,
381 const char *name)
382{
383 struct se_portal_group *se_tpg = container_of(group,
384 struct se_portal_group, tpg_acl_group);
385 struct target_fabric_configfs *tf = se_tpg->se_tpg_wwn->wwn_tf;
386 struct se_node_acl *se_nacl;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800387
Christoph Hellwigc7d6a802015-04-13 19:51:14 +0200388 se_nacl = core_tpg_add_initiator_node_acl(se_tpg, name);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800389 if (IS_ERR(se_nacl))
Thomas Meyere1750ba2011-08-01 23:58:18 +0200390 return ERR_CAST(se_nacl);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800391
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800392 config_group_init_type_name(&se_nacl->acl_group, name,
Christoph Hellwig968ebe72015-05-03 08:50:55 +0200393 &tf->tf_tpg_nacl_base_cit);
Christoph Hellwig1ae16022016-02-26 11:02:14 +0100394
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800395 config_group_init_type_name(&se_nacl->acl_attrib_group, "attrib",
Christoph Hellwig968ebe72015-05-03 08:50:55 +0200396 &tf->tf_tpg_nacl_attrib_cit);
Christoph Hellwig1ae16022016-02-26 11:02:14 +0100397 configfs_add_default_group(&se_nacl->acl_attrib_group,
398 &se_nacl->acl_group);
399
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800400 config_group_init_type_name(&se_nacl->acl_auth_group, "auth",
Christoph Hellwig968ebe72015-05-03 08:50:55 +0200401 &tf->tf_tpg_nacl_auth_cit);
Christoph Hellwig1ae16022016-02-26 11:02:14 +0100402 configfs_add_default_group(&se_nacl->acl_auth_group,
403 &se_nacl->acl_group);
404
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800405 config_group_init_type_name(&se_nacl->acl_param_group, "param",
Christoph Hellwig968ebe72015-05-03 08:50:55 +0200406 &tf->tf_tpg_nacl_param_cit);
Christoph Hellwig1ae16022016-02-26 11:02:14 +0100407 configfs_add_default_group(&se_nacl->acl_param_group,
408 &se_nacl->acl_group);
409
Nicholas Bellinger12d2338422011-03-14 04:06:11 -0700410 config_group_init_type_name(&se_nacl->acl_fabric_stat_group,
Christoph Hellwig968ebe72015-05-03 08:50:55 +0200411 "fabric_statistics", &tf->tf_tpg_nacl_stat_cit);
Christoph Hellwig1ae16022016-02-26 11:02:14 +0100412 configfs_add_default_group(&se_nacl->acl_fabric_stat_group,
413 &se_nacl->acl_group);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800414
Christoph Hellwige6e202e2016-03-29 13:03:34 +0200415 if (tf->tf_ops->fabric_init_nodeacl) {
416 int ret = tf->tf_ops->fabric_init_nodeacl(se_nacl, name);
417 if (ret) {
418 configfs_remove_default_groups(&se_nacl->acl_fabric_stat_group);
419 core_tpg_del_initiator_node_acl(se_nacl);
420 return ERR_PTR(ret);
421 }
422 }
423
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800424 return &se_nacl->acl_group;
425}
426
427static void target_fabric_drop_nodeacl(
428 struct config_group *group,
429 struct config_item *item)
430{
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800431 struct se_node_acl *se_nacl = container_of(to_config_group(item),
432 struct se_node_acl, acl_group);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800433
Christoph Hellwig1ae16022016-02-26 11:02:14 +0100434 configfs_remove_default_groups(&se_nacl->acl_group);
435
Nicholas Bellinger1f6fe7c2011-02-09 15:34:54 -0800436 /*
437 * struct se_node_acl free is done in target_fabric_nacl_base_release()
438 */
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800439 config_item_put(item);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800440}
441
442static struct configfs_group_operations target_fabric_nacl_group_ops = {
443 .make_group = target_fabric_make_nodeacl,
444 .drop_item = target_fabric_drop_nodeacl,
445};
446
447TF_CIT_SETUP(tpg_nacl, NULL, &target_fabric_nacl_group_ops, NULL);
448
449/* End of tfc_tpg_nacl_cit */
450
451/* Start of tfc_tpg_np_base_cit */
452
Nicholas Bellinger1f6fe7c2011-02-09 15:34:54 -0800453static void target_fabric_np_base_release(struct config_item *item)
454{
455 struct se_tpg_np *se_tpg_np = container_of(to_config_group(item),
456 struct se_tpg_np, tpg_np_group);
457 struct se_portal_group *se_tpg = se_tpg_np->tpg_np_parent;
458 struct target_fabric_configfs *tf = se_tpg->se_tpg_wwn->wwn_tf;
459
Christoph Hellwigef0caf82015-05-03 08:50:53 +0200460 tf->tf_ops->fabric_drop_np(se_tpg_np);
Nicholas Bellinger1f6fe7c2011-02-09 15:34:54 -0800461}
462
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800463static struct configfs_item_operations target_fabric_np_base_item_ops = {
Nicholas Bellinger1f6fe7c2011-02-09 15:34:54 -0800464 .release = target_fabric_np_base_release,
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800465};
466
Christoph Hellwig9ac89282015-04-08 20:01:35 +0200467TF_CIT_SETUP_DRV(tpg_np_base, &target_fabric_np_base_item_ops, NULL);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800468
469/* End of tfc_tpg_np_base_cit */
470
471/* Start of tfc_tpg_np_cit */
472
473static struct config_group *target_fabric_make_np(
474 struct config_group *group,
475 const char *name)
476{
477 struct se_portal_group *se_tpg = container_of(group,
478 struct se_portal_group, tpg_np_group);
479 struct target_fabric_configfs *tf = se_tpg->se_tpg_wwn->wwn_tf;
480 struct se_tpg_np *se_tpg_np;
481
Christoph Hellwigef0caf82015-05-03 08:50:53 +0200482 if (!tf->tf_ops->fabric_make_np) {
Andy Grover6708bb22011-06-08 10:36:43 -0700483 pr_err("tf->tf_ops.fabric_make_np is NULL\n");
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800484 return ERR_PTR(-ENOSYS);
485 }
486
Christoph Hellwigef0caf82015-05-03 08:50:53 +0200487 se_tpg_np = tf->tf_ops->fabric_make_np(se_tpg, group, name);
Andy Grover6708bb22011-06-08 10:36:43 -0700488 if (!se_tpg_np || IS_ERR(se_tpg_np))
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800489 return ERR_PTR(-EINVAL);
490
Nicholas Bellinger1f6fe7c2011-02-09 15:34:54 -0800491 se_tpg_np->tpg_np_parent = se_tpg;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800492 config_group_init_type_name(&se_tpg_np->tpg_np_group, name,
Christoph Hellwig968ebe72015-05-03 08:50:55 +0200493 &tf->tf_tpg_np_base_cit);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800494
495 return &se_tpg_np->tpg_np_group;
496}
497
498static void target_fabric_drop_np(
499 struct config_group *group,
500 struct config_item *item)
501{
Nicholas Bellinger1f6fe7c2011-02-09 15:34:54 -0800502 /*
503 * struct se_tpg_np is released via target_fabric_np_base_release()
504 */
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800505 config_item_put(item);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800506}
507
508static struct configfs_group_operations target_fabric_np_group_ops = {
509 .make_group = &target_fabric_make_np,
510 .drop_item = &target_fabric_drop_np,
511};
512
513TF_CIT_SETUP(tpg_np, NULL, &target_fabric_np_group_ops, NULL);
514
515/* End of tfc_tpg_np_cit */
516
517/* Start of tfc_tpg_port_cit */
518
Christoph Hellwig2eafd722015-10-03 15:32:55 +0200519static struct se_lun *item_to_lun(struct config_item *item)
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800520{
Christoph Hellwig2eafd722015-10-03 15:32:55 +0200521 return container_of(to_config_group(item), struct se_lun,
522 lun_group);
523}
524
525static ssize_t target_fabric_port_alua_tg_pt_gp_show(struct config_item *item,
526 char *page)
527{
528 struct se_lun *lun = item_to_lun(item);
529
Christoph Hellwigadf653f2015-05-25 21:33:08 -0700530 if (!lun || !lun->lun_se_dev)
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800531 return -ENODEV;
532
Christoph Hellwigadf653f2015-05-25 21:33:08 -0700533 return core_alua_show_tg_pt_gp_info(lun, page);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800534}
535
Christoph Hellwig2eafd722015-10-03 15:32:55 +0200536static ssize_t target_fabric_port_alua_tg_pt_gp_store(struct config_item *item,
537 const char *page, size_t count)
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800538{
Christoph Hellwig2eafd722015-10-03 15:32:55 +0200539 struct se_lun *lun = item_to_lun(item);
540
Christoph Hellwigadf653f2015-05-25 21:33:08 -0700541 if (!lun || !lun->lun_se_dev)
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800542 return -ENODEV;
543
Christoph Hellwigadf653f2015-05-25 21:33:08 -0700544 return core_alua_store_tg_pt_gp_info(lun, page, count);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800545}
546
Christoph Hellwig2eafd722015-10-03 15:32:55 +0200547static ssize_t target_fabric_port_alua_tg_pt_offline_show(
548 struct config_item *item, char *page)
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800549{
Christoph Hellwig2eafd722015-10-03 15:32:55 +0200550 struct se_lun *lun = item_to_lun(item);
551
Christoph Hellwigadf653f2015-05-25 21:33:08 -0700552 if (!lun || !lun->lun_se_dev)
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800553 return -ENODEV;
554
555 return core_alua_show_offline_bit(lun, page);
556}
557
Christoph Hellwig2eafd722015-10-03 15:32:55 +0200558static ssize_t target_fabric_port_alua_tg_pt_offline_store(
559 struct config_item *item, const char *page, size_t count)
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800560{
Christoph Hellwig2eafd722015-10-03 15:32:55 +0200561 struct se_lun *lun = item_to_lun(item);
562
Christoph Hellwigadf653f2015-05-25 21:33:08 -0700563 if (!lun || !lun->lun_se_dev)
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800564 return -ENODEV;
565
566 return core_alua_store_offline_bit(lun, page, count);
567}
568
Christoph Hellwig2eafd722015-10-03 15:32:55 +0200569static ssize_t target_fabric_port_alua_tg_pt_status_show(
570 struct config_item *item, char *page)
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800571{
Christoph Hellwig2eafd722015-10-03 15:32:55 +0200572 struct se_lun *lun = item_to_lun(item);
573
Christoph Hellwigadf653f2015-05-25 21:33:08 -0700574 if (!lun || !lun->lun_se_dev)
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800575 return -ENODEV;
576
577 return core_alua_show_secondary_status(lun, page);
578}
579
Christoph Hellwig2eafd722015-10-03 15:32:55 +0200580static ssize_t target_fabric_port_alua_tg_pt_status_store(
581 struct config_item *item, const char *page, size_t count)
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800582{
Christoph Hellwig2eafd722015-10-03 15:32:55 +0200583 struct se_lun *lun = item_to_lun(item);
584
Christoph Hellwigadf653f2015-05-25 21:33:08 -0700585 if (!lun || !lun->lun_se_dev)
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800586 return -ENODEV;
587
588 return core_alua_store_secondary_status(lun, page, count);
589}
590
Christoph Hellwig2eafd722015-10-03 15:32:55 +0200591static ssize_t target_fabric_port_alua_tg_pt_write_md_show(
592 struct config_item *item, char *page)
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800593{
Christoph Hellwig2eafd722015-10-03 15:32:55 +0200594 struct se_lun *lun = item_to_lun(item);
595
Christoph Hellwigadf653f2015-05-25 21:33:08 -0700596 if (!lun || !lun->lun_se_dev)
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800597 return -ENODEV;
598
599 return core_alua_show_secondary_write_metadata(lun, page);
600}
601
Christoph Hellwig2eafd722015-10-03 15:32:55 +0200602static ssize_t target_fabric_port_alua_tg_pt_write_md_store(
603 struct config_item *item, const char *page, size_t count)
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800604{
Christoph Hellwig2eafd722015-10-03 15:32:55 +0200605 struct se_lun *lun = item_to_lun(item);
606
Christoph Hellwigadf653f2015-05-25 21:33:08 -0700607 if (!lun || !lun->lun_se_dev)
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800608 return -ENODEV;
609
610 return core_alua_store_secondary_write_metadata(lun, page, count);
611}
612
Christoph Hellwig2eafd722015-10-03 15:32:55 +0200613CONFIGFS_ATTR(target_fabric_port_, alua_tg_pt_gp);
614CONFIGFS_ATTR(target_fabric_port_, alua_tg_pt_offline);
615CONFIGFS_ATTR(target_fabric_port_, alua_tg_pt_status);
616CONFIGFS_ATTR(target_fabric_port_, alua_tg_pt_write_md);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800617
618static struct configfs_attribute *target_fabric_port_attrs[] = {
Christoph Hellwig2eafd722015-10-03 15:32:55 +0200619 &target_fabric_port_attr_alua_tg_pt_gp,
620 &target_fabric_port_attr_alua_tg_pt_offline,
621 &target_fabric_port_attr_alua_tg_pt_status,
622 &target_fabric_port_attr_alua_tg_pt_write_md,
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800623 NULL,
624};
625
Nicholas Bellingerc17cd242017-06-01 03:10:53 -0700626extern struct configfs_item_operations target_core_dev_item_ops;
627
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800628static int target_fabric_port_link(
629 struct config_item *lun_ci,
630 struct config_item *se_dev_ci)
631{
632 struct config_item *tpg_ci;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800633 struct se_lun *lun = container_of(to_config_group(lun_ci),
634 struct se_lun, lun_group);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800635 struct se_portal_group *se_tpg;
Nicholas Bellingerc17cd242017-06-01 03:10:53 -0700636 struct se_device *dev;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800637 struct target_fabric_configfs *tf;
638 int ret;
639
Nicholas Bellingerc17cd242017-06-01 03:10:53 -0700640 if (!se_dev_ci->ci_type ||
641 se_dev_ci->ci_type->ct_item_ops != &target_core_dev_item_ops) {
642 pr_err("Bad se_dev_ci, not a valid se_dev_ci pointer: %p\n", se_dev_ci);
Nicholas Bellinger0ff87542012-12-04 23:43:57 -0800643 return -EFAULT;
644 }
Nicholas Bellingerc17cd242017-06-01 03:10:53 -0700645 dev = container_of(to_config_group(se_dev_ci), struct se_device, dev_group);
Nicholas Bellinger0ff87542012-12-04 23:43:57 -0800646
Nicholas Bellingerfaa06ab2013-01-31 14:56:12 -0800647 if (!(dev->dev_flags & DF_CONFIGURED)) {
648 pr_err("se_device not configured yet, cannot port link\n");
649 return -ENODEV;
650 }
651
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800652 tpg_ci = &lun_ci->ci_parent->ci_group->cg_item;
653 se_tpg = container_of(to_config_group(tpg_ci),
654 struct se_portal_group, tpg_group);
655 tf = se_tpg->se_tpg_wwn->wwn_tf;
656
657 if (lun->lun_se_dev != NULL) {
Andy Grover6708bb22011-06-08 10:36:43 -0700658 pr_err("Port Symlink already exists\n");
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800659 return -EEXIST;
660 }
661
Nicholas Bellinger6bb82612015-05-10 19:31:10 -0700662 ret = core_dev_add_lun(se_tpg, dev, lun);
663 if (ret) {
664 pr_err("core_dev_add_lun() failed: %d\n", ret);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800665 goto out;
666 }
667
Christoph Hellwigef0caf82015-05-03 08:50:53 +0200668 if (tf->tf_ops->fabric_post_link) {
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800669 /*
670 * Call the optional fabric_post_link() to allow a
671 * fabric module to setup any additional state once
672 * core_dev_add_lun() has been called..
673 */
Christoph Hellwigef0caf82015-05-03 08:50:53 +0200674 tf->tf_ops->fabric_post_link(se_tpg, lun);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800675 }
676
677 return 0;
678out:
679 return ret;
680}
681
Andrzej Pietrasiewicze16769d2016-11-28 13:22:42 +0100682static void target_fabric_port_unlink(
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800683 struct config_item *lun_ci,
684 struct config_item *se_dev_ci)
685{
686 struct se_lun *lun = container_of(to_config_group(lun_ci),
687 struct se_lun, lun_group);
Christoph Hellwigadf653f2015-05-25 21:33:08 -0700688 struct se_portal_group *se_tpg = lun->lun_tpg;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800689 struct target_fabric_configfs *tf = se_tpg->se_tpg_wwn->wwn_tf;
690
Christoph Hellwigef0caf82015-05-03 08:50:53 +0200691 if (tf->tf_ops->fabric_pre_unlink) {
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800692 /*
693 * Call the optional fabric_pre_unlink() to allow a
694 * fabric module to release any additional stat before
695 * core_dev_del_lun() is called.
696 */
Christoph Hellwigef0caf82015-05-03 08:50:53 +0200697 tf->tf_ops->fabric_pre_unlink(se_tpg, lun);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800698 }
699
Andy Grovercd9d7cb2014-06-30 16:39:44 -0700700 core_dev_del_lun(se_tpg, lun);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800701}
702
Nicholas Bellinger6bb82612015-05-10 19:31:10 -0700703static void target_fabric_port_release(struct config_item *item)
704{
705 struct se_lun *lun = container_of(to_config_group(item),
706 struct se_lun, lun_group);
707
708 kfree_rcu(lun, rcu_head);
709}
710
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800711static struct configfs_item_operations target_fabric_port_item_ops = {
Nicholas Bellinger6bb82612015-05-10 19:31:10 -0700712 .release = target_fabric_port_release,
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800713 .allow_link = target_fabric_port_link,
714 .drop_link = target_fabric_port_unlink,
715};
716
717TF_CIT_SETUP(tpg_port, &target_fabric_port_item_ops, NULL, target_fabric_port_attrs);
718
719/* End of tfc_tpg_port_cit */
720
Nicholas Bellinger12d2338422011-03-14 04:06:11 -0700721/* Start of tfc_tpg_port_stat_cit */
722
723static struct config_group *target_core_port_stat_mkdir(
724 struct config_group *group,
725 const char *name)
726{
727 return ERR_PTR(-ENOSYS);
728}
729
730static void target_core_port_stat_rmdir(
731 struct config_group *group,
732 struct config_item *item)
733{
734 return;
735}
736
737static struct configfs_group_operations target_fabric_port_stat_group_ops = {
738 .make_group = target_core_port_stat_mkdir,
739 .drop_item = target_core_port_stat_rmdir,
740};
741
742TF_CIT_SETUP(tpg_port_stat, NULL, &target_fabric_port_stat_group_ops, NULL);
743
744/* End of tfc_tpg_port_stat_cit */
745
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800746/* Start of tfc_tpg_lun_cit */
747
748static struct config_group *target_fabric_make_lun(
749 struct config_group *group,
750 const char *name)
751{
752 struct se_lun *lun;
753 struct se_portal_group *se_tpg = container_of(group,
754 struct se_portal_group, tpg_lun_group);
755 struct target_fabric_configfs *tf = se_tpg->se_tpg_wwn->wwn_tf;
Hannes Reineckef2d30682015-06-10 08:41:22 +0200756 unsigned long long unpacked_lun;
Nicholas Bellinger12d2338422011-03-14 04:06:11 -0700757 int errno;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800758
759 if (strstr(name, "lun_") != name) {
Andy Grover6708bb22011-06-08 10:36:43 -0700760 pr_err("Unable to locate \'_\" in"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800761 " \"lun_$LUN_NUMBER\"\n");
762 return ERR_PTR(-EINVAL);
763 }
Hannes Reineckef2d30682015-06-10 08:41:22 +0200764 errno = kstrtoull(name + 4, 0, &unpacked_lun);
Jingoo Han57103d72013-07-19 16:22:19 +0900765 if (errno)
766 return ERR_PTR(errno);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800767
Nicholas Bellinger6bb82612015-05-10 19:31:10 -0700768 lun = core_tpg_alloc_lun(se_tpg, unpacked_lun);
769 if (IS_ERR(lun))
770 return ERR_CAST(lun);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800771
772 config_group_init_type_name(&lun->lun_group, name,
Christoph Hellwig968ebe72015-05-03 08:50:55 +0200773 &tf->tf_tpg_port_cit);
Christoph Hellwig1ae16022016-02-26 11:02:14 +0100774
Nicholas Bellinger12d2338422011-03-14 04:06:11 -0700775 config_group_init_type_name(&lun->port_stat_grps.stat_group,
Christoph Hellwig968ebe72015-05-03 08:50:55 +0200776 "statistics", &tf->tf_tpg_port_stat_cit);
Christoph Hellwig1ae16022016-02-26 11:02:14 +0100777 configfs_add_default_group(&lun->port_stat_grps.stat_group,
778 &lun->lun_group);
Nicholas Bellinger12d2338422011-03-14 04:06:11 -0700779
Nicholas Bellinger12d2338422011-03-14 04:06:11 -0700780 target_stat_setup_port_default_groups(lun);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800781
782 return &lun->lun_group;
783}
784
785static void target_fabric_drop_lun(
786 struct config_group *group,
787 struct config_item *item)
788{
Nicholas Bellinger12d2338422011-03-14 04:06:11 -0700789 struct se_lun *lun = container_of(to_config_group(item),
790 struct se_lun, lun_group);
Nicholas Bellinger12d2338422011-03-14 04:06:11 -0700791
Christoph Hellwig1ae16022016-02-26 11:02:14 +0100792 configfs_remove_default_groups(&lun->port_stat_grps.stat_group);
793 configfs_remove_default_groups(&lun->lun_group);
Nicholas Bellinger12d2338422011-03-14 04:06:11 -0700794
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800795 config_item_put(item);
796}
797
798static 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
803TF_CIT_SETUP(tpg_lun, NULL, &target_fabric_lun_group_ops, NULL);
804
805/* End of tfc_tpg_lun_cit */
806
Christoph Hellwig2eafd722015-10-03 15:32:55 +0200807TF_CIT_SETUP_DRV(tpg_attrib, NULL, NULL);
808TF_CIT_SETUP_DRV(tpg_auth, NULL, NULL);
809TF_CIT_SETUP_DRV(tpg_param, NULL, NULL);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800810
811/* Start of tfc_tpg_base_cit */
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800812
Nicholas Bellinger1f6fe7c2011-02-09 15:34:54 -0800813static void target_fabric_tpg_release(struct config_item *item)
814{
815 struct se_portal_group *se_tpg = container_of(to_config_group(item),
816 struct se_portal_group, tpg_group);
817 struct se_wwn *wwn = se_tpg->se_tpg_wwn;
818 struct target_fabric_configfs *tf = wwn->wwn_tf;
819
Christoph Hellwigef0caf82015-05-03 08:50:53 +0200820 tf->tf_ops->fabric_drop_tpg(se_tpg);
Nicholas Bellinger1f6fe7c2011-02-09 15:34:54 -0800821}
822
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800823static struct configfs_item_operations target_fabric_tpg_base_item_ops = {
Nicholas Bellinger1f6fe7c2011-02-09 15:34:54 -0800824 .release = target_fabric_tpg_release,
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800825};
826
Christoph Hellwig9ac89282015-04-08 20:01:35 +0200827TF_CIT_SETUP_DRV(tpg_base, &target_fabric_tpg_base_item_ops, NULL);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800828
829/* End of tfc_tpg_base_cit */
830
831/* Start of tfc_tpg_cit */
832
833static struct config_group *target_fabric_make_tpg(
834 struct config_group *group,
835 const char *name)
836{
837 struct se_wwn *wwn = container_of(group, struct se_wwn, wwn_group);
838 struct target_fabric_configfs *tf = wwn->wwn_tf;
839 struct se_portal_group *se_tpg;
840
Christoph Hellwigef0caf82015-05-03 08:50:53 +0200841 if (!tf->tf_ops->fabric_make_tpg) {
842 pr_err("tf->tf_ops->fabric_make_tpg is NULL\n");
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800843 return ERR_PTR(-ENOSYS);
844 }
845
Christoph Hellwigef0caf82015-05-03 08:50:53 +0200846 se_tpg = tf->tf_ops->fabric_make_tpg(wwn, group, name);
Andy Grover6708bb22011-06-08 10:36:43 -0700847 if (!se_tpg || IS_ERR(se_tpg))
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800848 return ERR_PTR(-EINVAL);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800849
850 config_group_init_type_name(&se_tpg->tpg_group, name,
Christoph Hellwig968ebe72015-05-03 08:50:55 +0200851 &tf->tf_tpg_base_cit);
Christoph Hellwig1ae16022016-02-26 11:02:14 +0100852
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800853 config_group_init_type_name(&se_tpg->tpg_lun_group, "lun",
Christoph Hellwig968ebe72015-05-03 08:50:55 +0200854 &tf->tf_tpg_lun_cit);
Christoph Hellwig1ae16022016-02-26 11:02:14 +0100855 configfs_add_default_group(&se_tpg->tpg_lun_group,
856 &se_tpg->tpg_group);
857
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800858 config_group_init_type_name(&se_tpg->tpg_np_group, "np",
Christoph Hellwig968ebe72015-05-03 08:50:55 +0200859 &tf->tf_tpg_np_cit);
Christoph Hellwig1ae16022016-02-26 11:02:14 +0100860 configfs_add_default_group(&se_tpg->tpg_np_group,
861 &se_tpg->tpg_group);
862
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800863 config_group_init_type_name(&se_tpg->tpg_acl_group, "acls",
Christoph Hellwig968ebe72015-05-03 08:50:55 +0200864 &tf->tf_tpg_nacl_cit);
Christoph Hellwig1ae16022016-02-26 11:02:14 +0100865 configfs_add_default_group(&se_tpg->tpg_acl_group,
866 &se_tpg->tpg_group);
867
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800868 config_group_init_type_name(&se_tpg->tpg_attrib_group, "attrib",
Christoph Hellwig968ebe72015-05-03 08:50:55 +0200869 &tf->tf_tpg_attrib_cit);
Christoph Hellwig1ae16022016-02-26 11:02:14 +0100870 configfs_add_default_group(&se_tpg->tpg_attrib_group,
871 &se_tpg->tpg_group);
872
Nicholas Bellingere4b512e2013-06-19 18:37:00 -0700873 config_group_init_type_name(&se_tpg->tpg_auth_group, "auth",
Christoph Hellwig968ebe72015-05-03 08:50:55 +0200874 &tf->tf_tpg_auth_cit);
Christoph Hellwig1ae16022016-02-26 11:02:14 +0100875 configfs_add_default_group(&se_tpg->tpg_auth_group,
876 &se_tpg->tpg_group);
877
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800878 config_group_init_type_name(&se_tpg->tpg_param_group, "param",
Christoph Hellwig968ebe72015-05-03 08:50:55 +0200879 &tf->tf_tpg_param_cit);
Christoph Hellwig1ae16022016-02-26 11:02:14 +0100880 configfs_add_default_group(&se_tpg->tpg_param_group,
881 &se_tpg->tpg_group);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800882
883 return &se_tpg->tpg_group;
884}
885
886static void target_fabric_drop_tpg(
887 struct config_group *group,
888 struct config_item *item)
889{
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800890 struct se_portal_group *se_tpg = container_of(to_config_group(item),
891 struct se_portal_group, tpg_group);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800892
Christoph Hellwig1ae16022016-02-26 11:02:14 +0100893 configfs_remove_default_groups(&se_tpg->tpg_group);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800894 config_item_put(item);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800895}
896
Nicholas Bellinger1f6fe7c2011-02-09 15:34:54 -0800897static void target_fabric_release_wwn(struct config_item *item)
898{
899 struct se_wwn *wwn = container_of(to_config_group(item),
900 struct se_wwn, wwn_group);
901 struct target_fabric_configfs *tf = wwn->wwn_tf;
902
Christoph Hellwig839559e2016-03-29 13:03:35 +0200903 configfs_remove_default_groups(&wwn->fabric_stat_group);
Christoph Hellwigef0caf82015-05-03 08:50:53 +0200904 tf->tf_ops->fabric_drop_wwn(wwn);
Nicholas Bellinger1f6fe7c2011-02-09 15:34:54 -0800905}
906
907static struct configfs_item_operations target_fabric_tpg_item_ops = {
908 .release = target_fabric_release_wwn,
909};
910
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800911static struct configfs_group_operations target_fabric_tpg_group_ops = {
912 .make_group = target_fabric_make_tpg,
913 .drop_item = target_fabric_drop_tpg,
914};
915
Nicholas Bellinger1f6fe7c2011-02-09 15:34:54 -0800916TF_CIT_SETUP(tpg, &target_fabric_tpg_item_ops, &target_fabric_tpg_group_ops,
917 NULL);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800918
919/* End of tfc_tpg_cit */
920
Nicholas Bellinger12d2338422011-03-14 04:06:11 -0700921/* Start of tfc_wwn_fabric_stats_cit */
922/*
923 * This is used as a placeholder for struct se_wwn->fabric_stat_group
924 * to allow fabrics access to ->fabric_stat_group->default_groups[]
925 */
926TF_CIT_SETUP(wwn_fabric_stats, NULL, NULL, NULL);
927
928/* End of tfc_wwn_fabric_stats_cit */
929
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800930/* Start of tfc_wwn_cit */
931
932static struct config_group *target_fabric_make_wwn(
933 struct config_group *group,
934 const char *name)
935{
936 struct target_fabric_configfs *tf = container_of(group,
937 struct target_fabric_configfs, tf_group);
938 struct se_wwn *wwn;
939
Christoph Hellwigef0caf82015-05-03 08:50:53 +0200940 if (!tf->tf_ops->fabric_make_wwn) {
Andy Grover6708bb22011-06-08 10:36:43 -0700941 pr_err("tf->tf_ops.fabric_make_wwn is NULL\n");
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800942 return ERR_PTR(-ENOSYS);
943 }
944
Christoph Hellwigef0caf82015-05-03 08:50:53 +0200945 wwn = tf->tf_ops->fabric_make_wwn(tf, group, name);
Andy Grover6708bb22011-06-08 10:36:43 -0700946 if (!wwn || IS_ERR(wwn))
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800947 return ERR_PTR(-EINVAL);
948
949 wwn->wwn_tf = tf;
Nicholas Bellinger12d2338422011-03-14 04:06:11 -0700950
Christoph Hellwig968ebe72015-05-03 08:50:55 +0200951 config_group_init_type_name(&wwn->wwn_group, name, &tf->tf_tpg_cit);
Christoph Hellwig1ae16022016-02-26 11:02:14 +0100952
Nicholas Bellinger12d2338422011-03-14 04:06:11 -0700953 config_group_init_type_name(&wwn->fabric_stat_group, "fabric_statistics",
Christoph Hellwig968ebe72015-05-03 08:50:55 +0200954 &tf->tf_wwn_fabric_stats_cit);
Christoph Hellwig1ae16022016-02-26 11:02:14 +0100955 configfs_add_default_group(&wwn->fabric_stat_group, &wwn->wwn_group);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800956
Christoph Hellwig839559e2016-03-29 13:03:35 +0200957 if (tf->tf_ops->add_wwn_groups)
958 tf->tf_ops->add_wwn_groups(wwn);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800959 return &wwn->wwn_group;
960}
961
962static void target_fabric_drop_wwn(
963 struct config_group *group,
964 struct config_item *item)
965{
Nicholas Bellinger12d2338422011-03-14 04:06:11 -0700966 struct se_wwn *wwn = container_of(to_config_group(item),
967 struct se_wwn, wwn_group);
Nicholas Bellinger12d2338422011-03-14 04:06:11 -0700968
Christoph Hellwig1ae16022016-02-26 11:02:14 +0100969 configfs_remove_default_groups(&wwn->wwn_group);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800970 config_item_put(item);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800971}
972
973static struct configfs_group_operations target_fabric_wwn_group_ops = {
974 .make_group = target_fabric_make_wwn,
975 .drop_item = target_fabric_drop_wwn,
976};
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800977
Christoph Hellwig2eafd722015-10-03 15:32:55 +0200978TF_CIT_SETUP_DRV(wwn, NULL, &target_fabric_wwn_group_ops);
979TF_CIT_SETUP_DRV(discovery, NULL, NULL);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800980
981int target_fabric_setup_cits(struct target_fabric_configfs *tf)
982{
983 target_fabric_setup_discovery_cit(tf);
984 target_fabric_setup_wwn_cit(tf);
Nicholas Bellinger12d2338422011-03-14 04:06:11 -0700985 target_fabric_setup_wwn_fabric_stats_cit(tf);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800986 target_fabric_setup_tpg_cit(tf);
987 target_fabric_setup_tpg_base_cit(tf);
988 target_fabric_setup_tpg_port_cit(tf);
Nicholas Bellinger12d2338422011-03-14 04:06:11 -0700989 target_fabric_setup_tpg_port_stat_cit(tf);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800990 target_fabric_setup_tpg_lun_cit(tf);
991 target_fabric_setup_tpg_np_cit(tf);
992 target_fabric_setup_tpg_np_base_cit(tf);
993 target_fabric_setup_tpg_attrib_cit(tf);
Nicholas Bellingere4b512e2013-06-19 18:37:00 -0700994 target_fabric_setup_tpg_auth_cit(tf);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800995 target_fabric_setup_tpg_param_cit(tf);
996 target_fabric_setup_tpg_nacl_cit(tf);
997 target_fabric_setup_tpg_nacl_base_cit(tf);
998 target_fabric_setup_tpg_nacl_attrib_cit(tf);
999 target_fabric_setup_tpg_nacl_auth_cit(tf);
1000 target_fabric_setup_tpg_nacl_param_cit(tf);
Nicholas Bellinger12d2338422011-03-14 04:06:11 -07001001 target_fabric_setup_tpg_nacl_stat_cit(tf);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001002 target_fabric_setup_tpg_mappedlun_cit(tf);
Nicholas Bellinger12d2338422011-03-14 04:06:11 -07001003 target_fabric_setup_tpg_mappedlun_stat_cit(tf);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001004
1005 return 0;
1006}