configfs.c 24 KB

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