configfs.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020
  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. }