configfs.c 24 KB

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