configfs.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918
  1. /*
  2. * Configfs interface for the NVMe target.
  3. * Copyright (c) 2015-2016 HGST, a Western Digital Company.
  4. *
  5. * This program is free software; you can redistribute it and/or modify it
  6. * under the terms and conditions of the GNU General Public License,
  7. * version 2, as published by the Free Software Foundation.
  8. *
  9. * This program is distributed in the hope it will be useful, but WITHOUT
  10. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  12. * more details.
  13. */
  14. #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  15. #include <linux/kernel.h>
  16. #include <linux/module.h>
  17. #include <linux/slab.h>
  18. #include <linux/stat.h>
  19. #include <linux/ctype.h>
  20. #include "nvmet.h"
  21. static struct config_item_type nvmet_host_type;
  22. static struct config_item_type nvmet_subsys_type;
  23. /*
  24. * nvmet_port Generic ConfigFS definitions.
  25. * Used in any place in the ConfigFS tree that refers to an address.
  26. */
  27. static ssize_t nvmet_addr_adrfam_show(struct config_item *item,
  28. char *page)
  29. {
  30. switch (to_nvmet_port(item)->disc_addr.adrfam) {
  31. case NVMF_ADDR_FAMILY_IP4:
  32. return sprintf(page, "ipv4\n");
  33. case NVMF_ADDR_FAMILY_IP6:
  34. return sprintf(page, "ipv6\n");
  35. case NVMF_ADDR_FAMILY_IB:
  36. return sprintf(page, "ib\n");
  37. default:
  38. return sprintf(page, "\n");
  39. }
  40. }
  41. static ssize_t nvmet_addr_adrfam_store(struct config_item *item,
  42. const char *page, size_t count)
  43. {
  44. struct nvmet_port *port = to_nvmet_port(item);
  45. if (port->enabled) {
  46. pr_err("Cannot modify address while enabled\n");
  47. pr_err("Disable the address before modifying\n");
  48. return -EACCES;
  49. }
  50. if (sysfs_streq(page, "ipv4")) {
  51. port->disc_addr.adrfam = NVMF_ADDR_FAMILY_IP4;
  52. } else if (sysfs_streq(page, "ipv6")) {
  53. port->disc_addr.adrfam = NVMF_ADDR_FAMILY_IP6;
  54. } else if (sysfs_streq(page, "ib")) {
  55. port->disc_addr.adrfam = NVMF_ADDR_FAMILY_IB;
  56. } else {
  57. pr_err("Invalid value '%s' for adrfam\n", page);
  58. return -EINVAL;
  59. }
  60. return count;
  61. }
  62. CONFIGFS_ATTR(nvmet_, addr_adrfam);
  63. static ssize_t nvmet_addr_portid_show(struct config_item *item,
  64. char *page)
  65. {
  66. struct nvmet_port *port = to_nvmet_port(item);
  67. return snprintf(page, PAGE_SIZE, "%d\n",
  68. le16_to_cpu(port->disc_addr.portid));
  69. }
  70. static ssize_t nvmet_addr_portid_store(struct config_item *item,
  71. const char *page, size_t count)
  72. {
  73. struct nvmet_port *port = to_nvmet_port(item);
  74. u16 portid = 0;
  75. if (kstrtou16(page, 0, &portid)) {
  76. pr_err("Invalid value '%s' for portid\n", page);
  77. return -EINVAL;
  78. }
  79. if (port->enabled) {
  80. pr_err("Cannot modify address while enabled\n");
  81. pr_err("Disable the address before modifying\n");
  82. return -EACCES;
  83. }
  84. port->disc_addr.portid = cpu_to_le16(portid);
  85. return count;
  86. }
  87. CONFIGFS_ATTR(nvmet_, addr_portid);
  88. static ssize_t nvmet_addr_traddr_show(struct config_item *item,
  89. char *page)
  90. {
  91. struct nvmet_port *port = to_nvmet_port(item);
  92. return snprintf(page, PAGE_SIZE, "%s\n",
  93. port->disc_addr.traddr);
  94. }
  95. static ssize_t nvmet_addr_traddr_store(struct config_item *item,
  96. const char *page, size_t count)
  97. {
  98. struct nvmet_port *port = to_nvmet_port(item);
  99. if (count > NVMF_TRADDR_SIZE) {
  100. pr_err("Invalid value '%s' for traddr\n", page);
  101. return -EINVAL;
  102. }
  103. if (port->enabled) {
  104. pr_err("Cannot modify address while enabled\n");
  105. pr_err("Disable the address before modifying\n");
  106. return -EACCES;
  107. }
  108. return snprintf(port->disc_addr.traddr,
  109. sizeof(port->disc_addr.traddr), "%s", page);
  110. }
  111. CONFIGFS_ATTR(nvmet_, addr_traddr);
  112. static ssize_t nvmet_addr_treq_show(struct config_item *item,
  113. char *page)
  114. {
  115. switch (to_nvmet_port(item)->disc_addr.treq) {
  116. case NVMF_TREQ_NOT_SPECIFIED:
  117. return sprintf(page, "not specified\n");
  118. case NVMF_TREQ_REQUIRED:
  119. return sprintf(page, "required\n");
  120. case NVMF_TREQ_NOT_REQUIRED:
  121. return sprintf(page, "not required\n");
  122. default:
  123. return sprintf(page, "\n");
  124. }
  125. }
  126. static ssize_t nvmet_addr_treq_store(struct config_item *item,
  127. const char *page, size_t count)
  128. {
  129. struct nvmet_port *port = to_nvmet_port(item);
  130. if (port->enabled) {
  131. pr_err("Cannot modify address while enabled\n");
  132. pr_err("Disable the address before modifying\n");
  133. return -EACCES;
  134. }
  135. if (sysfs_streq(page, "not specified")) {
  136. port->disc_addr.treq = NVMF_TREQ_NOT_SPECIFIED;
  137. } else if (sysfs_streq(page, "required")) {
  138. port->disc_addr.treq = NVMF_TREQ_REQUIRED;
  139. } else if (sysfs_streq(page, "not required")) {
  140. port->disc_addr.treq = NVMF_TREQ_NOT_REQUIRED;
  141. } else {
  142. pr_err("Invalid value '%s' for treq\n", page);
  143. return -EINVAL;
  144. }
  145. return count;
  146. }
  147. CONFIGFS_ATTR(nvmet_, addr_treq);
  148. static ssize_t nvmet_addr_trsvcid_show(struct config_item *item,
  149. char *page)
  150. {
  151. struct nvmet_port *port = to_nvmet_port(item);
  152. return snprintf(page, PAGE_SIZE, "%s\n",
  153. port->disc_addr.trsvcid);
  154. }
  155. static ssize_t nvmet_addr_trsvcid_store(struct config_item *item,
  156. const char *page, size_t count)
  157. {
  158. struct nvmet_port *port = to_nvmet_port(item);
  159. if (count > NVMF_TRSVCID_SIZE) {
  160. pr_err("Invalid value '%s' for trsvcid\n", page);
  161. return -EINVAL;
  162. }
  163. if (port->enabled) {
  164. pr_err("Cannot modify address while enabled\n");
  165. pr_err("Disable the address before modifying\n");
  166. return -EACCES;
  167. }
  168. return snprintf(port->disc_addr.trsvcid,
  169. sizeof(port->disc_addr.trsvcid), "%s", page);
  170. }
  171. CONFIGFS_ATTR(nvmet_, addr_trsvcid);
  172. static ssize_t nvmet_addr_trtype_show(struct config_item *item,
  173. char *page)
  174. {
  175. switch (to_nvmet_port(item)->disc_addr.trtype) {
  176. case NVMF_TRTYPE_RDMA:
  177. return sprintf(page, "rdma\n");
  178. case NVMF_TRTYPE_LOOP:
  179. return sprintf(page, "loop\n");
  180. default:
  181. return sprintf(page, "\n");
  182. }
  183. }
  184. static void nvmet_port_init_tsas_rdma(struct nvmet_port *port)
  185. {
  186. port->disc_addr.trtype = NVMF_TRTYPE_RDMA;
  187. memset(&port->disc_addr.tsas.rdma, 0, NVMF_TSAS_SIZE);
  188. port->disc_addr.tsas.rdma.qptype = NVMF_RDMA_QPTYPE_CONNECTED;
  189. port->disc_addr.tsas.rdma.prtype = NVMF_RDMA_PRTYPE_NOT_SPECIFIED;
  190. port->disc_addr.tsas.rdma.cms = NVMF_RDMA_CMS_RDMA_CM;
  191. }
  192. static void nvmet_port_init_tsas_loop(struct nvmet_port *port)
  193. {
  194. port->disc_addr.trtype = NVMF_TRTYPE_LOOP;
  195. memset(&port->disc_addr.tsas, 0, NVMF_TSAS_SIZE);
  196. }
  197. static ssize_t nvmet_addr_trtype_store(struct config_item *item,
  198. const char *page, size_t count)
  199. {
  200. struct nvmet_port *port = to_nvmet_port(item);
  201. if (port->enabled) {
  202. pr_err("Cannot modify address while enabled\n");
  203. pr_err("Disable the address before modifying\n");
  204. return -EACCES;
  205. }
  206. if (sysfs_streq(page, "rdma")) {
  207. nvmet_port_init_tsas_rdma(port);
  208. } else if (sysfs_streq(page, "loop")) {
  209. nvmet_port_init_tsas_loop(port);
  210. } else {
  211. pr_err("Invalid value '%s' for trtype\n", page);
  212. return -EINVAL;
  213. }
  214. return count;
  215. }
  216. CONFIGFS_ATTR(nvmet_, addr_trtype);
  217. /*
  218. * Namespace structures & file operation functions below
  219. */
  220. static ssize_t nvmet_ns_device_path_show(struct config_item *item, char *page)
  221. {
  222. return sprintf(page, "%s\n", to_nvmet_ns(item)->device_path);
  223. }
  224. static ssize_t nvmet_ns_device_path_store(struct config_item *item,
  225. const char *page, size_t count)
  226. {
  227. struct nvmet_ns *ns = to_nvmet_ns(item);
  228. struct nvmet_subsys *subsys = ns->subsys;
  229. int ret;
  230. mutex_lock(&subsys->lock);
  231. ret = -EBUSY;
  232. if (ns->enabled)
  233. goto out_unlock;
  234. kfree(ns->device_path);
  235. ret = -ENOMEM;
  236. ns->device_path = kstrdup(page, GFP_KERNEL);
  237. if (!ns->device_path)
  238. goto out_unlock;
  239. mutex_unlock(&subsys->lock);
  240. return count;
  241. out_unlock:
  242. mutex_unlock(&subsys->lock);
  243. return ret;
  244. }
  245. CONFIGFS_ATTR(nvmet_ns_, device_path);
  246. static ssize_t nvmet_ns_device_nguid_show(struct config_item *item, char *page)
  247. {
  248. return sprintf(page, "%pUb\n", &to_nvmet_ns(item)->nguid);
  249. }
  250. static ssize_t nvmet_ns_device_nguid_store(struct config_item *item,
  251. const char *page, size_t count)
  252. {
  253. struct nvmet_ns *ns = to_nvmet_ns(item);
  254. struct nvmet_subsys *subsys = ns->subsys;
  255. u8 nguid[16];
  256. const char *p = page;
  257. int i;
  258. int ret = 0;
  259. mutex_lock(&subsys->lock);
  260. if (ns->enabled) {
  261. ret = -EBUSY;
  262. goto out_unlock;
  263. }
  264. for (i = 0; i < 16; i++) {
  265. if (p + 2 > page + count) {
  266. ret = -EINVAL;
  267. goto out_unlock;
  268. }
  269. if (!isxdigit(p[0]) || !isxdigit(p[1])) {
  270. ret = -EINVAL;
  271. goto out_unlock;
  272. }
  273. nguid[i] = (hex_to_bin(p[0]) << 4) | hex_to_bin(p[1]);
  274. p += 2;
  275. if (*p == '-' || *p == ':')
  276. p++;
  277. }
  278. memcpy(&ns->nguid, nguid, sizeof(nguid));
  279. out_unlock:
  280. mutex_unlock(&subsys->lock);
  281. return ret ? ret : count;
  282. }
  283. CONFIGFS_ATTR(nvmet_ns_, device_nguid);
  284. static ssize_t nvmet_ns_enable_show(struct config_item *item, char *page)
  285. {
  286. return sprintf(page, "%d\n", to_nvmet_ns(item)->enabled);
  287. }
  288. static ssize_t nvmet_ns_enable_store(struct config_item *item,
  289. const char *page, size_t count)
  290. {
  291. struct nvmet_ns *ns = to_nvmet_ns(item);
  292. bool enable;
  293. int ret = 0;
  294. if (strtobool(page, &enable))
  295. return -EINVAL;
  296. if (enable)
  297. ret = nvmet_ns_enable(ns);
  298. else
  299. nvmet_ns_disable(ns);
  300. return ret ? ret : count;
  301. }
  302. CONFIGFS_ATTR(nvmet_ns_, enable);
  303. static struct configfs_attribute *nvmet_ns_attrs[] = {
  304. &nvmet_ns_attr_device_path,
  305. &nvmet_ns_attr_device_nguid,
  306. &nvmet_ns_attr_enable,
  307. NULL,
  308. };
  309. static void nvmet_ns_release(struct config_item *item)
  310. {
  311. struct nvmet_ns *ns = to_nvmet_ns(item);
  312. nvmet_ns_free(ns);
  313. }
  314. static struct configfs_item_operations nvmet_ns_item_ops = {
  315. .release = nvmet_ns_release,
  316. };
  317. static struct config_item_type nvmet_ns_type = {
  318. .ct_item_ops = &nvmet_ns_item_ops,
  319. .ct_attrs = nvmet_ns_attrs,
  320. .ct_owner = THIS_MODULE,
  321. };
  322. static struct config_group *nvmet_ns_make(struct config_group *group,
  323. const char *name)
  324. {
  325. struct nvmet_subsys *subsys = namespaces_to_subsys(&group->cg_item);
  326. struct nvmet_ns *ns;
  327. int ret;
  328. u32 nsid;
  329. ret = kstrtou32(name, 0, &nsid);
  330. if (ret)
  331. goto out;
  332. ret = -EINVAL;
  333. if (nsid == 0 || nsid == 0xffffffff)
  334. goto out;
  335. ret = -ENOMEM;
  336. ns = nvmet_ns_alloc(subsys, nsid);
  337. if (!ns)
  338. goto out;
  339. config_group_init_type_name(&ns->group, name, &nvmet_ns_type);
  340. pr_info("adding nsid %d to subsystem %s\n", nsid, subsys->subsysnqn);
  341. return &ns->group;
  342. out:
  343. return ERR_PTR(ret);
  344. }
  345. static struct configfs_group_operations nvmet_namespaces_group_ops = {
  346. .make_group = nvmet_ns_make,
  347. };
  348. static struct config_item_type nvmet_namespaces_type = {
  349. .ct_group_ops = &nvmet_namespaces_group_ops,
  350. .ct_owner = THIS_MODULE,
  351. };
  352. static int nvmet_port_subsys_allow_link(struct config_item *parent,
  353. struct config_item *target)
  354. {
  355. struct nvmet_port *port = to_nvmet_port(parent->ci_parent);
  356. struct nvmet_subsys *subsys;
  357. struct nvmet_subsys_link *link, *p;
  358. int ret;
  359. if (target->ci_type != &nvmet_subsys_type) {
  360. pr_err("can only link subsystems into the subsystems dir.!\n");
  361. return -EINVAL;
  362. }
  363. subsys = to_subsys(target);
  364. link = kmalloc(sizeof(*link), GFP_KERNEL);
  365. if (!link)
  366. return -ENOMEM;
  367. link->subsys = subsys;
  368. down_write(&nvmet_config_sem);
  369. ret = -EEXIST;
  370. list_for_each_entry(p, &port->subsystems, entry) {
  371. if (p->subsys == subsys)
  372. goto out_free_link;
  373. }
  374. if (list_empty(&port->subsystems)) {
  375. ret = nvmet_enable_port(port);
  376. if (ret)
  377. goto out_free_link;
  378. }
  379. list_add_tail(&link->entry, &port->subsystems);
  380. nvmet_genctr++;
  381. up_write(&nvmet_config_sem);
  382. return 0;
  383. out_free_link:
  384. up_write(&nvmet_config_sem);
  385. kfree(link);
  386. return ret;
  387. }
  388. static int nvmet_port_subsys_drop_link(struct config_item *parent,
  389. struct config_item *target)
  390. {
  391. struct nvmet_port *port = to_nvmet_port(parent->ci_parent);
  392. struct nvmet_subsys *subsys = to_subsys(target);
  393. struct nvmet_subsys_link *p;
  394. down_write(&nvmet_config_sem);
  395. list_for_each_entry(p, &port->subsystems, entry) {
  396. if (p->subsys == subsys)
  397. goto found;
  398. }
  399. up_write(&nvmet_config_sem);
  400. return -EINVAL;
  401. found:
  402. list_del(&p->entry);
  403. nvmet_genctr++;
  404. if (list_empty(&port->subsystems))
  405. nvmet_disable_port(port);
  406. up_write(&nvmet_config_sem);
  407. kfree(p);
  408. return 0;
  409. }
  410. static struct configfs_item_operations nvmet_port_subsys_item_ops = {
  411. .allow_link = nvmet_port_subsys_allow_link,
  412. .drop_link = nvmet_port_subsys_drop_link,
  413. };
  414. static struct config_item_type nvmet_port_subsys_type = {
  415. .ct_item_ops = &nvmet_port_subsys_item_ops,
  416. .ct_owner = THIS_MODULE,
  417. };
  418. static int nvmet_allowed_hosts_allow_link(struct config_item *parent,
  419. struct config_item *target)
  420. {
  421. struct nvmet_subsys *subsys = to_subsys(parent->ci_parent);
  422. struct nvmet_host *host;
  423. struct nvmet_host_link *link, *p;
  424. int ret;
  425. if (target->ci_type != &nvmet_host_type) {
  426. pr_err("can only link hosts into the allowed_hosts directory!\n");
  427. return -EINVAL;
  428. }
  429. host = to_host(target);
  430. link = kmalloc(sizeof(*link), GFP_KERNEL);
  431. if (!link)
  432. return -ENOMEM;
  433. link->host = host;
  434. down_write(&nvmet_config_sem);
  435. ret = -EINVAL;
  436. if (subsys->allow_any_host) {
  437. pr_err("can't add hosts when allow_any_host is set!\n");
  438. goto out_free_link;
  439. }
  440. ret = -EEXIST;
  441. list_for_each_entry(p, &subsys->hosts, entry) {
  442. if (!strcmp(nvmet_host_name(p->host), nvmet_host_name(host)))
  443. goto out_free_link;
  444. }
  445. list_add_tail(&link->entry, &subsys->hosts);
  446. nvmet_genctr++;
  447. up_write(&nvmet_config_sem);
  448. return 0;
  449. out_free_link:
  450. up_write(&nvmet_config_sem);
  451. kfree(link);
  452. return ret;
  453. }
  454. static int nvmet_allowed_hosts_drop_link(struct config_item *parent,
  455. struct config_item *target)
  456. {
  457. struct nvmet_subsys *subsys = to_subsys(parent->ci_parent);
  458. struct nvmet_host *host = to_host(target);
  459. struct nvmet_host_link *p;
  460. down_write(&nvmet_config_sem);
  461. list_for_each_entry(p, &subsys->hosts, entry) {
  462. if (!strcmp(nvmet_host_name(p->host), nvmet_host_name(host)))
  463. goto found;
  464. }
  465. up_write(&nvmet_config_sem);
  466. return -EINVAL;
  467. found:
  468. list_del(&p->entry);
  469. nvmet_genctr++;
  470. up_write(&nvmet_config_sem);
  471. kfree(p);
  472. return 0;
  473. }
  474. static struct configfs_item_operations nvmet_allowed_hosts_item_ops = {
  475. .allow_link = nvmet_allowed_hosts_allow_link,
  476. .drop_link = nvmet_allowed_hosts_drop_link,
  477. };
  478. static struct config_item_type nvmet_allowed_hosts_type = {
  479. .ct_item_ops = &nvmet_allowed_hosts_item_ops,
  480. .ct_owner = THIS_MODULE,
  481. };
  482. static ssize_t nvmet_subsys_attr_allow_any_host_show(struct config_item *item,
  483. char *page)
  484. {
  485. return snprintf(page, PAGE_SIZE, "%d\n",
  486. to_subsys(item)->allow_any_host);
  487. }
  488. static ssize_t nvmet_subsys_attr_allow_any_host_store(struct config_item *item,
  489. const char *page, size_t count)
  490. {
  491. struct nvmet_subsys *subsys = to_subsys(item);
  492. bool allow_any_host;
  493. int ret = 0;
  494. if (strtobool(page, &allow_any_host))
  495. return -EINVAL;
  496. down_write(&nvmet_config_sem);
  497. if (allow_any_host && !list_empty(&subsys->hosts)) {
  498. pr_err("Can't set allow_any_host when explicit hosts are set!\n");
  499. ret = -EINVAL;
  500. goto out_unlock;
  501. }
  502. subsys->allow_any_host = allow_any_host;
  503. out_unlock:
  504. up_write(&nvmet_config_sem);
  505. return ret ? ret : count;
  506. }
  507. CONFIGFS_ATTR(nvmet_subsys_, attr_allow_any_host);
  508. static struct configfs_attribute *nvmet_subsys_attrs[] = {
  509. &nvmet_subsys_attr_attr_allow_any_host,
  510. NULL,
  511. };
  512. /*
  513. * Subsystem structures & folder operation functions below
  514. */
  515. static void nvmet_subsys_release(struct config_item *item)
  516. {
  517. struct nvmet_subsys *subsys = to_subsys(item);
  518. nvmet_subsys_put(subsys);
  519. }
  520. static struct configfs_item_operations nvmet_subsys_item_ops = {
  521. .release = nvmet_subsys_release,
  522. };
  523. static struct config_item_type nvmet_subsys_type = {
  524. .ct_item_ops = &nvmet_subsys_item_ops,
  525. .ct_attrs = nvmet_subsys_attrs,
  526. .ct_owner = THIS_MODULE,
  527. };
  528. static struct config_group *nvmet_subsys_make(struct config_group *group,
  529. const char *name)
  530. {
  531. struct nvmet_subsys *subsys;
  532. if (sysfs_streq(name, NVME_DISC_SUBSYS_NAME)) {
  533. pr_err("can't create discovery subsystem through configfs\n");
  534. return ERR_PTR(-EINVAL);
  535. }
  536. subsys = nvmet_subsys_alloc(name, NVME_NQN_NVME);
  537. if (!subsys)
  538. return ERR_PTR(-ENOMEM);
  539. config_group_init_type_name(&subsys->group, name, &nvmet_subsys_type);
  540. config_group_init_type_name(&subsys->namespaces_group,
  541. "namespaces", &nvmet_namespaces_type);
  542. configfs_add_default_group(&subsys->namespaces_group, &subsys->group);
  543. config_group_init_type_name(&subsys->allowed_hosts_group,
  544. "allowed_hosts", &nvmet_allowed_hosts_type);
  545. configfs_add_default_group(&subsys->allowed_hosts_group,
  546. &subsys->group);
  547. return &subsys->group;
  548. }
  549. static struct configfs_group_operations nvmet_subsystems_group_ops = {
  550. .make_group = nvmet_subsys_make,
  551. };
  552. static struct config_item_type nvmet_subsystems_type = {
  553. .ct_group_ops = &nvmet_subsystems_group_ops,
  554. .ct_owner = THIS_MODULE,
  555. };
  556. static ssize_t nvmet_referral_enable_show(struct config_item *item,
  557. char *page)
  558. {
  559. return snprintf(page, PAGE_SIZE, "%d\n", to_nvmet_port(item)->enabled);
  560. }
  561. static ssize_t nvmet_referral_enable_store(struct config_item *item,
  562. const char *page, size_t count)
  563. {
  564. struct nvmet_port *parent = to_nvmet_port(item->ci_parent->ci_parent);
  565. struct nvmet_port *port = to_nvmet_port(item);
  566. bool enable;
  567. if (strtobool(page, &enable))
  568. goto inval;
  569. if (enable)
  570. nvmet_referral_enable(parent, port);
  571. else
  572. nvmet_referral_disable(port);
  573. return count;
  574. inval:
  575. pr_err("Invalid value '%s' for enable\n", page);
  576. return -EINVAL;
  577. }
  578. CONFIGFS_ATTR(nvmet_referral_, enable);
  579. /*
  580. * Discovery Service subsystem definitions
  581. */
  582. static struct configfs_attribute *nvmet_referral_attrs[] = {
  583. &nvmet_attr_addr_adrfam,
  584. &nvmet_attr_addr_portid,
  585. &nvmet_attr_addr_treq,
  586. &nvmet_attr_addr_traddr,
  587. &nvmet_attr_addr_trsvcid,
  588. &nvmet_attr_addr_trtype,
  589. &nvmet_referral_attr_enable,
  590. NULL,
  591. };
  592. static void nvmet_referral_release(struct config_item *item)
  593. {
  594. struct nvmet_port *port = to_nvmet_port(item);
  595. nvmet_referral_disable(port);
  596. kfree(port);
  597. }
  598. static struct configfs_item_operations nvmet_referral_item_ops = {
  599. .release = nvmet_referral_release,
  600. };
  601. static struct config_item_type nvmet_referral_type = {
  602. .ct_owner = THIS_MODULE,
  603. .ct_attrs = nvmet_referral_attrs,
  604. .ct_item_ops = &nvmet_referral_item_ops,
  605. };
  606. static struct config_group *nvmet_referral_make(
  607. struct config_group *group, const char *name)
  608. {
  609. struct nvmet_port *port;
  610. port = kzalloc(sizeof(*port), GFP_KERNEL);
  611. if (!port)
  612. return ERR_PTR(-ENOMEM);
  613. INIT_LIST_HEAD(&port->entry);
  614. config_group_init_type_name(&port->group, name, &nvmet_referral_type);
  615. return &port->group;
  616. }
  617. static struct configfs_group_operations nvmet_referral_group_ops = {
  618. .make_group = nvmet_referral_make,
  619. };
  620. static struct config_item_type nvmet_referrals_type = {
  621. .ct_owner = THIS_MODULE,
  622. .ct_group_ops = &nvmet_referral_group_ops,
  623. };
  624. /*
  625. * Ports definitions.
  626. */
  627. static void nvmet_port_release(struct config_item *item)
  628. {
  629. struct nvmet_port *port = to_nvmet_port(item);
  630. kfree(port);
  631. }
  632. static struct configfs_attribute *nvmet_port_attrs[] = {
  633. &nvmet_attr_addr_adrfam,
  634. &nvmet_attr_addr_treq,
  635. &nvmet_attr_addr_traddr,
  636. &nvmet_attr_addr_trsvcid,
  637. &nvmet_attr_addr_trtype,
  638. NULL,
  639. };
  640. static struct configfs_item_operations nvmet_port_item_ops = {
  641. .release = nvmet_port_release,
  642. };
  643. static struct config_item_type nvmet_port_type = {
  644. .ct_attrs = nvmet_port_attrs,
  645. .ct_item_ops = &nvmet_port_item_ops,
  646. .ct_owner = THIS_MODULE,
  647. };
  648. static struct config_group *nvmet_ports_make(struct config_group *group,
  649. const char *name)
  650. {
  651. struct nvmet_port *port;
  652. u16 portid;
  653. if (kstrtou16(name, 0, &portid))
  654. return ERR_PTR(-EINVAL);
  655. port = kzalloc(sizeof(*port), GFP_KERNEL);
  656. if (!port)
  657. return ERR_PTR(-ENOMEM);
  658. INIT_LIST_HEAD(&port->entry);
  659. INIT_LIST_HEAD(&port->subsystems);
  660. INIT_LIST_HEAD(&port->referrals);
  661. port->disc_addr.portid = cpu_to_le16(portid);
  662. config_group_init_type_name(&port->group, name, &nvmet_port_type);
  663. config_group_init_type_name(&port->subsys_group,
  664. "subsystems", &nvmet_port_subsys_type);
  665. configfs_add_default_group(&port->subsys_group, &port->group);
  666. config_group_init_type_name(&port->referrals_group,
  667. "referrals", &nvmet_referrals_type);
  668. configfs_add_default_group(&port->referrals_group, &port->group);
  669. return &port->group;
  670. }
  671. static struct configfs_group_operations nvmet_ports_group_ops = {
  672. .make_group = nvmet_ports_make,
  673. };
  674. static struct config_item_type nvmet_ports_type = {
  675. .ct_group_ops = &nvmet_ports_group_ops,
  676. .ct_owner = THIS_MODULE,
  677. };
  678. static struct config_group nvmet_subsystems_group;
  679. static struct config_group nvmet_ports_group;
  680. static void nvmet_host_release(struct config_item *item)
  681. {
  682. struct nvmet_host *host = to_host(item);
  683. kfree(host);
  684. }
  685. static struct configfs_item_operations nvmet_host_item_ops = {
  686. .release = nvmet_host_release,
  687. };
  688. static struct config_item_type nvmet_host_type = {
  689. .ct_item_ops = &nvmet_host_item_ops,
  690. .ct_owner = THIS_MODULE,
  691. };
  692. static struct config_group *nvmet_hosts_make_group(struct config_group *group,
  693. const char *name)
  694. {
  695. struct nvmet_host *host;
  696. host = kzalloc(sizeof(*host), GFP_KERNEL);
  697. if (!host)
  698. return ERR_PTR(-ENOMEM);
  699. config_group_init_type_name(&host->group, name, &nvmet_host_type);
  700. return &host->group;
  701. }
  702. static struct configfs_group_operations nvmet_hosts_group_ops = {
  703. .make_group = nvmet_hosts_make_group,
  704. };
  705. static struct config_item_type nvmet_hosts_type = {
  706. .ct_group_ops = &nvmet_hosts_group_ops,
  707. .ct_owner = THIS_MODULE,
  708. };
  709. static struct config_group nvmet_hosts_group;
  710. static struct config_item_type nvmet_root_type = {
  711. .ct_owner = THIS_MODULE,
  712. };
  713. static struct configfs_subsystem nvmet_configfs_subsystem = {
  714. .su_group = {
  715. .cg_item = {
  716. .ci_namebuf = "nvmet",
  717. .ci_type = &nvmet_root_type,
  718. },
  719. },
  720. };
  721. int __init nvmet_init_configfs(void)
  722. {
  723. int ret;
  724. config_group_init(&nvmet_configfs_subsystem.su_group);
  725. mutex_init(&nvmet_configfs_subsystem.su_mutex);
  726. config_group_init_type_name(&nvmet_subsystems_group,
  727. "subsystems", &nvmet_subsystems_type);
  728. configfs_add_default_group(&nvmet_subsystems_group,
  729. &nvmet_configfs_subsystem.su_group);
  730. config_group_init_type_name(&nvmet_ports_group,
  731. "ports", &nvmet_ports_type);
  732. configfs_add_default_group(&nvmet_ports_group,
  733. &nvmet_configfs_subsystem.su_group);
  734. config_group_init_type_name(&nvmet_hosts_group,
  735. "hosts", &nvmet_hosts_type);
  736. configfs_add_default_group(&nvmet_hosts_group,
  737. &nvmet_configfs_subsystem.su_group);
  738. ret = configfs_register_subsystem(&nvmet_configfs_subsystem);
  739. if (ret) {
  740. pr_err("configfs_register_subsystem: %d\n", ret);
  741. return ret;
  742. }
  743. return 0;
  744. }
  745. void __exit nvmet_exit_configfs(void)
  746. {
  747. configfs_unregister_subsystem(&nvmet_configfs_subsystem);
  748. }