configfs.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998
  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 == 0xffffffff)
  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_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_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_, version);
  571. static struct configfs_attribute *nvmet_subsys_attrs[] = {
  572. &nvmet_subsys_attr_attr_allow_any_host,
  573. &nvmet_subsys_attr_version,
  574. NULL,
  575. };
  576. /*
  577. * Subsystem structures & folder operation functions below
  578. */
  579. static void nvmet_subsys_release(struct config_item *item)
  580. {
  581. struct nvmet_subsys *subsys = to_subsys(item);
  582. nvmet_subsys_del_ctrls(subsys);
  583. nvmet_subsys_put(subsys);
  584. }
  585. static struct configfs_item_operations nvmet_subsys_item_ops = {
  586. .release = nvmet_subsys_release,
  587. };
  588. static struct config_item_type nvmet_subsys_type = {
  589. .ct_item_ops = &nvmet_subsys_item_ops,
  590. .ct_attrs = nvmet_subsys_attrs,
  591. .ct_owner = THIS_MODULE,
  592. };
  593. static struct config_group *nvmet_subsys_make(struct config_group *group,
  594. const char *name)
  595. {
  596. struct nvmet_subsys *subsys;
  597. if (sysfs_streq(name, NVME_DISC_SUBSYS_NAME)) {
  598. pr_err("can't create discovery subsystem through configfs\n");
  599. return ERR_PTR(-EINVAL);
  600. }
  601. subsys = nvmet_subsys_alloc(name, NVME_NQN_NVME);
  602. if (!subsys)
  603. return ERR_PTR(-ENOMEM);
  604. config_group_init_type_name(&subsys->group, name, &nvmet_subsys_type);
  605. config_group_init_type_name(&subsys->namespaces_group,
  606. "namespaces", &nvmet_namespaces_type);
  607. configfs_add_default_group(&subsys->namespaces_group, &subsys->group);
  608. config_group_init_type_name(&subsys->allowed_hosts_group,
  609. "allowed_hosts", &nvmet_allowed_hosts_type);
  610. configfs_add_default_group(&subsys->allowed_hosts_group,
  611. &subsys->group);
  612. return &subsys->group;
  613. }
  614. static struct configfs_group_operations nvmet_subsystems_group_ops = {
  615. .make_group = nvmet_subsys_make,
  616. };
  617. static struct config_item_type nvmet_subsystems_type = {
  618. .ct_group_ops = &nvmet_subsystems_group_ops,
  619. .ct_owner = THIS_MODULE,
  620. };
  621. static ssize_t nvmet_referral_enable_show(struct config_item *item,
  622. char *page)
  623. {
  624. return snprintf(page, PAGE_SIZE, "%d\n", to_nvmet_port(item)->enabled);
  625. }
  626. static ssize_t nvmet_referral_enable_store(struct config_item *item,
  627. const char *page, size_t count)
  628. {
  629. struct nvmet_port *parent = to_nvmet_port(item->ci_parent->ci_parent);
  630. struct nvmet_port *port = to_nvmet_port(item);
  631. bool enable;
  632. if (strtobool(page, &enable))
  633. goto inval;
  634. if (enable)
  635. nvmet_referral_enable(parent, port);
  636. else
  637. nvmet_referral_disable(port);
  638. return count;
  639. inval:
  640. pr_err("Invalid value '%s' for enable\n", page);
  641. return -EINVAL;
  642. }
  643. CONFIGFS_ATTR(nvmet_referral_, enable);
  644. /*
  645. * Discovery Service subsystem definitions
  646. */
  647. static struct configfs_attribute *nvmet_referral_attrs[] = {
  648. &nvmet_attr_addr_adrfam,
  649. &nvmet_attr_addr_portid,
  650. &nvmet_attr_addr_treq,
  651. &nvmet_attr_addr_traddr,
  652. &nvmet_attr_addr_trsvcid,
  653. &nvmet_attr_addr_trtype,
  654. &nvmet_referral_attr_enable,
  655. NULL,
  656. };
  657. static void nvmet_referral_release(struct config_item *item)
  658. {
  659. struct nvmet_port *port = to_nvmet_port(item);
  660. nvmet_referral_disable(port);
  661. kfree(port);
  662. }
  663. static struct configfs_item_operations nvmet_referral_item_ops = {
  664. .release = nvmet_referral_release,
  665. };
  666. static struct config_item_type nvmet_referral_type = {
  667. .ct_owner = THIS_MODULE,
  668. .ct_attrs = nvmet_referral_attrs,
  669. .ct_item_ops = &nvmet_referral_item_ops,
  670. };
  671. static struct config_group *nvmet_referral_make(
  672. struct config_group *group, const char *name)
  673. {
  674. struct nvmet_port *port;
  675. port = kzalloc(sizeof(*port), GFP_KERNEL);
  676. if (!port)
  677. return ERR_PTR(-ENOMEM);
  678. INIT_LIST_HEAD(&port->entry);
  679. config_group_init_type_name(&port->group, name, &nvmet_referral_type);
  680. return &port->group;
  681. }
  682. static struct configfs_group_operations nvmet_referral_group_ops = {
  683. .make_group = nvmet_referral_make,
  684. };
  685. static struct config_item_type nvmet_referrals_type = {
  686. .ct_owner = THIS_MODULE,
  687. .ct_group_ops = &nvmet_referral_group_ops,
  688. };
  689. /*
  690. * Ports definitions.
  691. */
  692. static void nvmet_port_release(struct config_item *item)
  693. {
  694. struct nvmet_port *port = to_nvmet_port(item);
  695. kfree(port);
  696. }
  697. static struct configfs_attribute *nvmet_port_attrs[] = {
  698. &nvmet_attr_addr_adrfam,
  699. &nvmet_attr_addr_treq,
  700. &nvmet_attr_addr_traddr,
  701. &nvmet_attr_addr_trsvcid,
  702. &nvmet_attr_addr_trtype,
  703. NULL,
  704. };
  705. static struct configfs_item_operations nvmet_port_item_ops = {
  706. .release = nvmet_port_release,
  707. };
  708. static struct config_item_type nvmet_port_type = {
  709. .ct_attrs = nvmet_port_attrs,
  710. .ct_item_ops = &nvmet_port_item_ops,
  711. .ct_owner = THIS_MODULE,
  712. };
  713. static struct config_group *nvmet_ports_make(struct config_group *group,
  714. const char *name)
  715. {
  716. struct nvmet_port *port;
  717. u16 portid;
  718. if (kstrtou16(name, 0, &portid))
  719. return ERR_PTR(-EINVAL);
  720. port = kzalloc(sizeof(*port), GFP_KERNEL);
  721. if (!port)
  722. return ERR_PTR(-ENOMEM);
  723. INIT_LIST_HEAD(&port->entry);
  724. INIT_LIST_HEAD(&port->subsystems);
  725. INIT_LIST_HEAD(&port->referrals);
  726. port->disc_addr.portid = cpu_to_le16(portid);
  727. config_group_init_type_name(&port->group, name, &nvmet_port_type);
  728. config_group_init_type_name(&port->subsys_group,
  729. "subsystems", &nvmet_port_subsys_type);
  730. configfs_add_default_group(&port->subsys_group, &port->group);
  731. config_group_init_type_name(&port->referrals_group,
  732. "referrals", &nvmet_referrals_type);
  733. configfs_add_default_group(&port->referrals_group, &port->group);
  734. return &port->group;
  735. }
  736. static struct configfs_group_operations nvmet_ports_group_ops = {
  737. .make_group = nvmet_ports_make,
  738. };
  739. static struct config_item_type nvmet_ports_type = {
  740. .ct_group_ops = &nvmet_ports_group_ops,
  741. .ct_owner = THIS_MODULE,
  742. };
  743. static struct config_group nvmet_subsystems_group;
  744. static struct config_group nvmet_ports_group;
  745. static void nvmet_host_release(struct config_item *item)
  746. {
  747. struct nvmet_host *host = to_host(item);
  748. kfree(host);
  749. }
  750. static struct configfs_item_operations nvmet_host_item_ops = {
  751. .release = nvmet_host_release,
  752. };
  753. static struct config_item_type nvmet_host_type = {
  754. .ct_item_ops = &nvmet_host_item_ops,
  755. .ct_owner = THIS_MODULE,
  756. };
  757. static struct config_group *nvmet_hosts_make_group(struct config_group *group,
  758. const char *name)
  759. {
  760. struct nvmet_host *host;
  761. host = kzalloc(sizeof(*host), GFP_KERNEL);
  762. if (!host)
  763. return ERR_PTR(-ENOMEM);
  764. config_group_init_type_name(&host->group, name, &nvmet_host_type);
  765. return &host->group;
  766. }
  767. static struct configfs_group_operations nvmet_hosts_group_ops = {
  768. .make_group = nvmet_hosts_make_group,
  769. };
  770. static struct config_item_type nvmet_hosts_type = {
  771. .ct_group_ops = &nvmet_hosts_group_ops,
  772. .ct_owner = THIS_MODULE,
  773. };
  774. static struct config_group nvmet_hosts_group;
  775. static struct config_item_type nvmet_root_type = {
  776. .ct_owner = THIS_MODULE,
  777. };
  778. static struct configfs_subsystem nvmet_configfs_subsystem = {
  779. .su_group = {
  780. .cg_item = {
  781. .ci_namebuf = "nvmet",
  782. .ci_type = &nvmet_root_type,
  783. },
  784. },
  785. };
  786. int __init nvmet_init_configfs(void)
  787. {
  788. int ret;
  789. config_group_init(&nvmet_configfs_subsystem.su_group);
  790. mutex_init(&nvmet_configfs_subsystem.su_mutex);
  791. config_group_init_type_name(&nvmet_subsystems_group,
  792. "subsystems", &nvmet_subsystems_type);
  793. configfs_add_default_group(&nvmet_subsystems_group,
  794. &nvmet_configfs_subsystem.su_group);
  795. config_group_init_type_name(&nvmet_ports_group,
  796. "ports", &nvmet_ports_type);
  797. configfs_add_default_group(&nvmet_ports_group,
  798. &nvmet_configfs_subsystem.su_group);
  799. config_group_init_type_name(&nvmet_hosts_group,
  800. "hosts", &nvmet_hosts_type);
  801. configfs_add_default_group(&nvmet_hosts_group,
  802. &nvmet_configfs_subsystem.su_group);
  803. ret = configfs_register_subsystem(&nvmet_configfs_subsystem);
  804. if (ret) {
  805. pr_err("configfs_register_subsystem: %d\n", ret);
  806. return ret;
  807. }
  808. return 0;
  809. }
  810. void __exit nvmet_exit_configfs(void)
  811. {
  812. configfs_unregister_subsystem(&nvmet_configfs_subsystem);
  813. }