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