configfs.c 31 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276
  1. /*
  2. * Configfs interface for the NVMe target.
  3. * Copyright (c) 2015-2016 HGST, a Western Digital Company.
  4. *
  5. * This program is free software; you can redistribute it and/or modify it
  6. * under the terms and conditions of the GNU General Public License,
  7. * version 2, as published by the Free Software Foundation.
  8. *
  9. * This program is distributed in the hope it will be useful, but WITHOUT
  10. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  12. * more details.
  13. */
  14. #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  15. #include <linux/kernel.h>
  16. #include <linux/module.h>
  17. #include <linux/slab.h>
  18. #include <linux/stat.h>
  19. #include <linux/ctype.h>
  20. #include "nvmet.h"
  21. static const struct config_item_type nvmet_host_type;
  22. static const struct config_item_type nvmet_subsys_type;
  23. static const struct nvmet_transport_name {
  24. u8 type;
  25. const char *name;
  26. } nvmet_transport_names[] = {
  27. { NVMF_TRTYPE_RDMA, "rdma" },
  28. { NVMF_TRTYPE_FC, "fc" },
  29. { NVMF_TRTYPE_LOOP, "loop" },
  30. };
  31. /*
  32. * nvmet_port Generic ConfigFS definitions.
  33. * Used in any place in the ConfigFS tree that refers to an address.
  34. */
  35. static ssize_t nvmet_addr_adrfam_show(struct config_item *item,
  36. char *page)
  37. {
  38. switch (to_nvmet_port(item)->disc_addr.adrfam) {
  39. case NVMF_ADDR_FAMILY_IP4:
  40. return sprintf(page, "ipv4\n");
  41. case NVMF_ADDR_FAMILY_IP6:
  42. return sprintf(page, "ipv6\n");
  43. case NVMF_ADDR_FAMILY_IB:
  44. return sprintf(page, "ib\n");
  45. case NVMF_ADDR_FAMILY_FC:
  46. return sprintf(page, "fc\n");
  47. default:
  48. return sprintf(page, "\n");
  49. }
  50. }
  51. static ssize_t nvmet_addr_adrfam_store(struct config_item *item,
  52. const char *page, size_t count)
  53. {
  54. struct nvmet_port *port = to_nvmet_port(item);
  55. if (port->enabled) {
  56. pr_err("Cannot modify address while enabled\n");
  57. pr_err("Disable the address before modifying\n");
  58. return -EACCES;
  59. }
  60. if (sysfs_streq(page, "ipv4")) {
  61. port->disc_addr.adrfam = NVMF_ADDR_FAMILY_IP4;
  62. } else if (sysfs_streq(page, "ipv6")) {
  63. port->disc_addr.adrfam = NVMF_ADDR_FAMILY_IP6;
  64. } else if (sysfs_streq(page, "ib")) {
  65. port->disc_addr.adrfam = NVMF_ADDR_FAMILY_IB;
  66. } else if (sysfs_streq(page, "fc")) {
  67. port->disc_addr.adrfam = NVMF_ADDR_FAMILY_FC;
  68. } else {
  69. pr_err("Invalid value '%s' for adrfam\n", page);
  70. return -EINVAL;
  71. }
  72. return count;
  73. }
  74. CONFIGFS_ATTR(nvmet_, addr_adrfam);
  75. static ssize_t nvmet_addr_portid_show(struct config_item *item,
  76. char *page)
  77. {
  78. struct nvmet_port *port = to_nvmet_port(item);
  79. return snprintf(page, PAGE_SIZE, "%d\n",
  80. le16_to_cpu(port->disc_addr.portid));
  81. }
  82. static ssize_t nvmet_addr_portid_store(struct config_item *item,
  83. const char *page, size_t count)
  84. {
  85. struct nvmet_port *port = to_nvmet_port(item);
  86. u16 portid = 0;
  87. if (kstrtou16(page, 0, &portid)) {
  88. pr_err("Invalid value '%s' for portid\n", page);
  89. return -EINVAL;
  90. }
  91. if (port->enabled) {
  92. pr_err("Cannot modify address while enabled\n");
  93. pr_err("Disable the address before modifying\n");
  94. return -EACCES;
  95. }
  96. port->disc_addr.portid = cpu_to_le16(portid);
  97. return count;
  98. }
  99. CONFIGFS_ATTR(nvmet_, addr_portid);
  100. static ssize_t nvmet_addr_traddr_show(struct config_item *item,
  101. char *page)
  102. {
  103. struct nvmet_port *port = to_nvmet_port(item);
  104. return snprintf(page, PAGE_SIZE, "%s\n",
  105. port->disc_addr.traddr);
  106. }
  107. static ssize_t nvmet_addr_traddr_store(struct config_item *item,
  108. const char *page, size_t count)
  109. {
  110. struct nvmet_port *port = to_nvmet_port(item);
  111. if (count > NVMF_TRADDR_SIZE) {
  112. pr_err("Invalid value '%s' for traddr\n", page);
  113. return -EINVAL;
  114. }
  115. if (port->enabled) {
  116. pr_err("Cannot modify address while enabled\n");
  117. pr_err("Disable the address before modifying\n");
  118. return -EACCES;
  119. }
  120. if (sscanf(page, "%s\n", port->disc_addr.traddr) != 1)
  121. return -EINVAL;
  122. return count;
  123. }
  124. CONFIGFS_ATTR(nvmet_, addr_traddr);
  125. static ssize_t nvmet_addr_treq_show(struct config_item *item,
  126. char *page)
  127. {
  128. switch (to_nvmet_port(item)->disc_addr.treq) {
  129. case NVMF_TREQ_NOT_SPECIFIED:
  130. return sprintf(page, "not specified\n");
  131. case NVMF_TREQ_REQUIRED:
  132. return sprintf(page, "required\n");
  133. case NVMF_TREQ_NOT_REQUIRED:
  134. return sprintf(page, "not required\n");
  135. default:
  136. return sprintf(page, "\n");
  137. }
  138. }
  139. static ssize_t nvmet_addr_treq_store(struct config_item *item,
  140. const char *page, size_t count)
  141. {
  142. struct nvmet_port *port = to_nvmet_port(item);
  143. if (port->enabled) {
  144. pr_err("Cannot modify address while enabled\n");
  145. pr_err("Disable the address before modifying\n");
  146. return -EACCES;
  147. }
  148. if (sysfs_streq(page, "not specified")) {
  149. port->disc_addr.treq = NVMF_TREQ_NOT_SPECIFIED;
  150. } else if (sysfs_streq(page, "required")) {
  151. port->disc_addr.treq = NVMF_TREQ_REQUIRED;
  152. } else if (sysfs_streq(page, "not required")) {
  153. port->disc_addr.treq = NVMF_TREQ_NOT_REQUIRED;
  154. } else {
  155. pr_err("Invalid value '%s' for treq\n", page);
  156. return -EINVAL;
  157. }
  158. return count;
  159. }
  160. CONFIGFS_ATTR(nvmet_, addr_treq);
  161. static ssize_t nvmet_addr_trsvcid_show(struct config_item *item,
  162. char *page)
  163. {
  164. struct nvmet_port *port = to_nvmet_port(item);
  165. return snprintf(page, PAGE_SIZE, "%s\n",
  166. port->disc_addr.trsvcid);
  167. }
  168. static ssize_t nvmet_addr_trsvcid_store(struct config_item *item,
  169. const char *page, size_t count)
  170. {
  171. struct nvmet_port *port = to_nvmet_port(item);
  172. if (count > NVMF_TRSVCID_SIZE) {
  173. pr_err("Invalid value '%s' for trsvcid\n", page);
  174. return -EINVAL;
  175. }
  176. if (port->enabled) {
  177. pr_err("Cannot modify address while enabled\n");
  178. pr_err("Disable the address before modifying\n");
  179. return -EACCES;
  180. }
  181. if (sscanf(page, "%s\n", port->disc_addr.trsvcid) != 1)
  182. return -EINVAL;
  183. return count;
  184. }
  185. CONFIGFS_ATTR(nvmet_, addr_trsvcid);
  186. static ssize_t nvmet_param_inline_data_size_show(struct config_item *item,
  187. char *page)
  188. {
  189. struct nvmet_port *port = to_nvmet_port(item);
  190. return snprintf(page, PAGE_SIZE, "%d\n", port->inline_data_size);
  191. }
  192. static ssize_t nvmet_param_inline_data_size_store(struct config_item *item,
  193. const char *page, size_t count)
  194. {
  195. struct nvmet_port *port = to_nvmet_port(item);
  196. int ret;
  197. if (port->enabled) {
  198. pr_err("Cannot modify inline_data_size while port enabled\n");
  199. pr_err("Disable the port before modifying\n");
  200. return -EACCES;
  201. }
  202. ret = kstrtoint(page, 0, &port->inline_data_size);
  203. if (ret) {
  204. pr_err("Invalid value '%s' for inline_data_size\n", page);
  205. return -EINVAL;
  206. }
  207. return count;
  208. }
  209. CONFIGFS_ATTR(nvmet_, param_inline_data_size);
  210. static ssize_t nvmet_addr_trtype_show(struct config_item *item,
  211. char *page)
  212. {
  213. struct nvmet_port *port = to_nvmet_port(item);
  214. int i;
  215. for (i = 0; i < ARRAY_SIZE(nvmet_transport_names); i++) {
  216. if (port->disc_addr.trtype != nvmet_transport_names[i].type)
  217. continue;
  218. return sprintf(page, "%s\n", nvmet_transport_names[i].name);
  219. }
  220. return sprintf(page, "\n");
  221. }
  222. static void nvmet_port_init_tsas_rdma(struct nvmet_port *port)
  223. {
  224. port->disc_addr.tsas.rdma.qptype = NVMF_RDMA_QPTYPE_CONNECTED;
  225. port->disc_addr.tsas.rdma.prtype = NVMF_RDMA_PRTYPE_NOT_SPECIFIED;
  226. port->disc_addr.tsas.rdma.cms = NVMF_RDMA_CMS_RDMA_CM;
  227. }
  228. static ssize_t nvmet_addr_trtype_store(struct config_item *item,
  229. const char *page, size_t count)
  230. {
  231. struct nvmet_port *port = to_nvmet_port(item);
  232. int i;
  233. if (port->enabled) {
  234. pr_err("Cannot modify address while enabled\n");
  235. pr_err("Disable the address before modifying\n");
  236. return -EACCES;
  237. }
  238. for (i = 0; i < ARRAY_SIZE(nvmet_transport_names); i++) {
  239. if (sysfs_streq(page, nvmet_transport_names[i].name))
  240. goto found;
  241. }
  242. pr_err("Invalid value '%s' for trtype\n", page);
  243. return -EINVAL;
  244. found:
  245. memset(&port->disc_addr.tsas, 0, NVMF_TSAS_SIZE);
  246. port->disc_addr.trtype = nvmet_transport_names[i].type;
  247. if (port->disc_addr.trtype == NVMF_TRTYPE_RDMA)
  248. nvmet_port_init_tsas_rdma(port);
  249. return count;
  250. }
  251. CONFIGFS_ATTR(nvmet_, addr_trtype);
  252. /*
  253. * Namespace structures & file operation functions below
  254. */
  255. static ssize_t nvmet_ns_device_path_show(struct config_item *item, char *page)
  256. {
  257. return sprintf(page, "%s\n", to_nvmet_ns(item)->device_path);
  258. }
  259. static ssize_t nvmet_ns_device_path_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. size_t len;
  265. int ret;
  266. mutex_lock(&subsys->lock);
  267. ret = -EBUSY;
  268. if (ns->enabled)
  269. goto out_unlock;
  270. ret = -EINVAL;
  271. len = strcspn(page, "\n");
  272. if (!len)
  273. goto out_unlock;
  274. kfree(ns->device_path);
  275. ret = -ENOMEM;
  276. ns->device_path = kstrndup(page, len, GFP_KERNEL);
  277. if (!ns->device_path)
  278. goto out_unlock;
  279. mutex_unlock(&subsys->lock);
  280. return count;
  281. out_unlock:
  282. mutex_unlock(&subsys->lock);
  283. return ret;
  284. }
  285. CONFIGFS_ATTR(nvmet_ns_, device_path);
  286. static ssize_t nvmet_ns_device_uuid_show(struct config_item *item, char *page)
  287. {
  288. return sprintf(page, "%pUb\n", &to_nvmet_ns(item)->uuid);
  289. }
  290. static ssize_t nvmet_ns_device_uuid_store(struct config_item *item,
  291. const char *page, size_t count)
  292. {
  293. struct nvmet_ns *ns = to_nvmet_ns(item);
  294. struct nvmet_subsys *subsys = ns->subsys;
  295. int ret = 0;
  296. mutex_lock(&subsys->lock);
  297. if (ns->enabled) {
  298. ret = -EBUSY;
  299. goto out_unlock;
  300. }
  301. if (uuid_parse(page, &ns->uuid))
  302. ret = -EINVAL;
  303. out_unlock:
  304. mutex_unlock(&subsys->lock);
  305. return ret ? ret : count;
  306. }
  307. CONFIGFS_ATTR(nvmet_ns_, device_uuid);
  308. static ssize_t nvmet_ns_device_nguid_show(struct config_item *item, char *page)
  309. {
  310. return sprintf(page, "%pUb\n", &to_nvmet_ns(item)->nguid);
  311. }
  312. static ssize_t nvmet_ns_device_nguid_store(struct config_item *item,
  313. const char *page, size_t count)
  314. {
  315. struct nvmet_ns *ns = to_nvmet_ns(item);
  316. struct nvmet_subsys *subsys = ns->subsys;
  317. u8 nguid[16];
  318. const char *p = page;
  319. int i;
  320. int ret = 0;
  321. mutex_lock(&subsys->lock);
  322. if (ns->enabled) {
  323. ret = -EBUSY;
  324. goto out_unlock;
  325. }
  326. for (i = 0; i < 16; i++) {
  327. if (p + 2 > page + count) {
  328. ret = -EINVAL;
  329. goto out_unlock;
  330. }
  331. if (!isxdigit(p[0]) || !isxdigit(p[1])) {
  332. ret = -EINVAL;
  333. goto out_unlock;
  334. }
  335. nguid[i] = (hex_to_bin(p[0]) << 4) | hex_to_bin(p[1]);
  336. p += 2;
  337. if (*p == '-' || *p == ':')
  338. p++;
  339. }
  340. memcpy(&ns->nguid, nguid, sizeof(nguid));
  341. out_unlock:
  342. mutex_unlock(&subsys->lock);
  343. return ret ? ret : count;
  344. }
  345. CONFIGFS_ATTR(nvmet_ns_, device_nguid);
  346. static ssize_t nvmet_ns_ana_grpid_show(struct config_item *item, char *page)
  347. {
  348. return sprintf(page, "%u\n", to_nvmet_ns(item)->anagrpid);
  349. }
  350. static ssize_t nvmet_ns_ana_grpid_store(struct config_item *item,
  351. const char *page, size_t count)
  352. {
  353. struct nvmet_ns *ns = to_nvmet_ns(item);
  354. u32 oldgrpid, newgrpid;
  355. int ret;
  356. ret = kstrtou32(page, 0, &newgrpid);
  357. if (ret)
  358. return ret;
  359. if (newgrpid < 1 || newgrpid > NVMET_MAX_ANAGRPS)
  360. return -EINVAL;
  361. down_write(&nvmet_ana_sem);
  362. oldgrpid = ns->anagrpid;
  363. nvmet_ana_group_enabled[newgrpid]++;
  364. ns->anagrpid = newgrpid;
  365. nvmet_ana_group_enabled[oldgrpid]--;
  366. nvmet_ana_chgcnt++;
  367. up_write(&nvmet_ana_sem);
  368. nvmet_send_ana_event(ns->subsys, NULL);
  369. return count;
  370. }
  371. CONFIGFS_ATTR(nvmet_ns_, ana_grpid);
  372. static ssize_t nvmet_ns_enable_show(struct config_item *item, char *page)
  373. {
  374. return sprintf(page, "%d\n", to_nvmet_ns(item)->enabled);
  375. }
  376. static ssize_t nvmet_ns_enable_store(struct config_item *item,
  377. const char *page, size_t count)
  378. {
  379. struct nvmet_ns *ns = to_nvmet_ns(item);
  380. bool enable;
  381. int ret = 0;
  382. if (strtobool(page, &enable))
  383. return -EINVAL;
  384. if (enable)
  385. ret = nvmet_ns_enable(ns);
  386. else
  387. nvmet_ns_disable(ns);
  388. return ret ? ret : count;
  389. }
  390. CONFIGFS_ATTR(nvmet_ns_, enable);
  391. static ssize_t nvmet_ns_buffered_io_show(struct config_item *item, char *page)
  392. {
  393. return sprintf(page, "%d\n", to_nvmet_ns(item)->buffered_io);
  394. }
  395. static ssize_t nvmet_ns_buffered_io_store(struct config_item *item,
  396. const char *page, size_t count)
  397. {
  398. struct nvmet_ns *ns = to_nvmet_ns(item);
  399. bool val;
  400. if (strtobool(page, &val))
  401. return -EINVAL;
  402. mutex_lock(&ns->subsys->lock);
  403. if (ns->enabled) {
  404. pr_err("disable ns before setting buffered_io value.\n");
  405. mutex_unlock(&ns->subsys->lock);
  406. return -EINVAL;
  407. }
  408. ns->buffered_io = val;
  409. mutex_unlock(&ns->subsys->lock);
  410. return count;
  411. }
  412. CONFIGFS_ATTR(nvmet_ns_, buffered_io);
  413. static struct configfs_attribute *nvmet_ns_attrs[] = {
  414. &nvmet_ns_attr_device_path,
  415. &nvmet_ns_attr_device_nguid,
  416. &nvmet_ns_attr_device_uuid,
  417. &nvmet_ns_attr_ana_grpid,
  418. &nvmet_ns_attr_enable,
  419. &nvmet_ns_attr_buffered_io,
  420. NULL,
  421. };
  422. static void nvmet_ns_release(struct config_item *item)
  423. {
  424. struct nvmet_ns *ns = to_nvmet_ns(item);
  425. nvmet_ns_free(ns);
  426. }
  427. static struct configfs_item_operations nvmet_ns_item_ops = {
  428. .release = nvmet_ns_release,
  429. };
  430. static const struct config_item_type nvmet_ns_type = {
  431. .ct_item_ops = &nvmet_ns_item_ops,
  432. .ct_attrs = nvmet_ns_attrs,
  433. .ct_owner = THIS_MODULE,
  434. };
  435. static struct config_group *nvmet_ns_make(struct config_group *group,
  436. const char *name)
  437. {
  438. struct nvmet_subsys *subsys = namespaces_to_subsys(&group->cg_item);
  439. struct nvmet_ns *ns;
  440. int ret;
  441. u32 nsid;
  442. ret = kstrtou32(name, 0, &nsid);
  443. if (ret)
  444. goto out;
  445. ret = -EINVAL;
  446. if (nsid == 0 || nsid == NVME_NSID_ALL)
  447. goto out;
  448. ret = -ENOMEM;
  449. ns = nvmet_ns_alloc(subsys, nsid);
  450. if (!ns)
  451. goto out;
  452. config_group_init_type_name(&ns->group, name, &nvmet_ns_type);
  453. pr_info("adding nsid %d to subsystem %s\n", nsid, subsys->subsysnqn);
  454. return &ns->group;
  455. out:
  456. return ERR_PTR(ret);
  457. }
  458. static struct configfs_group_operations nvmet_namespaces_group_ops = {
  459. .make_group = nvmet_ns_make,
  460. };
  461. static const struct config_item_type nvmet_namespaces_type = {
  462. .ct_group_ops = &nvmet_namespaces_group_ops,
  463. .ct_owner = THIS_MODULE,
  464. };
  465. static int nvmet_port_subsys_allow_link(struct config_item *parent,
  466. struct config_item *target)
  467. {
  468. struct nvmet_port *port = to_nvmet_port(parent->ci_parent);
  469. struct nvmet_subsys *subsys;
  470. struct nvmet_subsys_link *link, *p;
  471. int ret;
  472. if (target->ci_type != &nvmet_subsys_type) {
  473. pr_err("can only link subsystems into the subsystems dir.!\n");
  474. return -EINVAL;
  475. }
  476. subsys = to_subsys(target);
  477. link = kmalloc(sizeof(*link), GFP_KERNEL);
  478. if (!link)
  479. return -ENOMEM;
  480. link->subsys = subsys;
  481. down_write(&nvmet_config_sem);
  482. ret = -EEXIST;
  483. list_for_each_entry(p, &port->subsystems, entry) {
  484. if (p->subsys == subsys)
  485. goto out_free_link;
  486. }
  487. if (list_empty(&port->subsystems)) {
  488. ret = nvmet_enable_port(port);
  489. if (ret)
  490. goto out_free_link;
  491. }
  492. list_add_tail(&link->entry, &port->subsystems);
  493. nvmet_genctr++;
  494. up_write(&nvmet_config_sem);
  495. return 0;
  496. out_free_link:
  497. up_write(&nvmet_config_sem);
  498. kfree(link);
  499. return ret;
  500. }
  501. static void nvmet_port_subsys_drop_link(struct config_item *parent,
  502. struct config_item *target)
  503. {
  504. struct nvmet_port *port = to_nvmet_port(parent->ci_parent);
  505. struct nvmet_subsys *subsys = to_subsys(target);
  506. struct nvmet_subsys_link *p;
  507. down_write(&nvmet_config_sem);
  508. list_for_each_entry(p, &port->subsystems, entry) {
  509. if (p->subsys == subsys)
  510. goto found;
  511. }
  512. up_write(&nvmet_config_sem);
  513. return;
  514. found:
  515. list_del(&p->entry);
  516. nvmet_genctr++;
  517. if (list_empty(&port->subsystems))
  518. nvmet_disable_port(port);
  519. up_write(&nvmet_config_sem);
  520. kfree(p);
  521. }
  522. static struct configfs_item_operations nvmet_port_subsys_item_ops = {
  523. .allow_link = nvmet_port_subsys_allow_link,
  524. .drop_link = nvmet_port_subsys_drop_link,
  525. };
  526. static const struct config_item_type nvmet_port_subsys_type = {
  527. .ct_item_ops = &nvmet_port_subsys_item_ops,
  528. .ct_owner = THIS_MODULE,
  529. };
  530. static int nvmet_allowed_hosts_allow_link(struct config_item *parent,
  531. struct config_item *target)
  532. {
  533. struct nvmet_subsys *subsys = to_subsys(parent->ci_parent);
  534. struct nvmet_host *host;
  535. struct nvmet_host_link *link, *p;
  536. int ret;
  537. if (target->ci_type != &nvmet_host_type) {
  538. pr_err("can only link hosts into the allowed_hosts directory!\n");
  539. return -EINVAL;
  540. }
  541. host = to_host(target);
  542. link = kmalloc(sizeof(*link), GFP_KERNEL);
  543. if (!link)
  544. return -ENOMEM;
  545. link->host = host;
  546. down_write(&nvmet_config_sem);
  547. ret = -EINVAL;
  548. if (subsys->allow_any_host) {
  549. pr_err("can't add hosts when allow_any_host is set!\n");
  550. goto out_free_link;
  551. }
  552. ret = -EEXIST;
  553. list_for_each_entry(p, &subsys->hosts, entry) {
  554. if (!strcmp(nvmet_host_name(p->host), nvmet_host_name(host)))
  555. goto out_free_link;
  556. }
  557. list_add_tail(&link->entry, &subsys->hosts);
  558. nvmet_genctr++;
  559. up_write(&nvmet_config_sem);
  560. return 0;
  561. out_free_link:
  562. up_write(&nvmet_config_sem);
  563. kfree(link);
  564. return ret;
  565. }
  566. static void nvmet_allowed_hosts_drop_link(struct config_item *parent,
  567. struct config_item *target)
  568. {
  569. struct nvmet_subsys *subsys = to_subsys(parent->ci_parent);
  570. struct nvmet_host *host = to_host(target);
  571. struct nvmet_host_link *p;
  572. down_write(&nvmet_config_sem);
  573. list_for_each_entry(p, &subsys->hosts, entry) {
  574. if (!strcmp(nvmet_host_name(p->host), nvmet_host_name(host)))
  575. goto found;
  576. }
  577. up_write(&nvmet_config_sem);
  578. return;
  579. found:
  580. list_del(&p->entry);
  581. nvmet_genctr++;
  582. up_write(&nvmet_config_sem);
  583. kfree(p);
  584. }
  585. static struct configfs_item_operations nvmet_allowed_hosts_item_ops = {
  586. .allow_link = nvmet_allowed_hosts_allow_link,
  587. .drop_link = nvmet_allowed_hosts_drop_link,
  588. };
  589. static const struct config_item_type nvmet_allowed_hosts_type = {
  590. .ct_item_ops = &nvmet_allowed_hosts_item_ops,
  591. .ct_owner = THIS_MODULE,
  592. };
  593. static ssize_t nvmet_subsys_attr_allow_any_host_show(struct config_item *item,
  594. char *page)
  595. {
  596. return snprintf(page, PAGE_SIZE, "%d\n",
  597. to_subsys(item)->allow_any_host);
  598. }
  599. static ssize_t nvmet_subsys_attr_allow_any_host_store(struct config_item *item,
  600. const char *page, size_t count)
  601. {
  602. struct nvmet_subsys *subsys = to_subsys(item);
  603. bool allow_any_host;
  604. int ret = 0;
  605. if (strtobool(page, &allow_any_host))
  606. return -EINVAL;
  607. down_write(&nvmet_config_sem);
  608. if (allow_any_host && !list_empty(&subsys->hosts)) {
  609. pr_err("Can't set allow_any_host when explicit hosts are set!\n");
  610. ret = -EINVAL;
  611. goto out_unlock;
  612. }
  613. subsys->allow_any_host = allow_any_host;
  614. out_unlock:
  615. up_write(&nvmet_config_sem);
  616. return ret ? ret : count;
  617. }
  618. CONFIGFS_ATTR(nvmet_subsys_, attr_allow_any_host);
  619. static ssize_t nvmet_subsys_attr_version_show(struct config_item *item,
  620. char *page)
  621. {
  622. struct nvmet_subsys *subsys = to_subsys(item);
  623. if (NVME_TERTIARY(subsys->ver))
  624. return snprintf(page, PAGE_SIZE, "%d.%d.%d\n",
  625. (int)NVME_MAJOR(subsys->ver),
  626. (int)NVME_MINOR(subsys->ver),
  627. (int)NVME_TERTIARY(subsys->ver));
  628. else
  629. return snprintf(page, PAGE_SIZE, "%d.%d\n",
  630. (int)NVME_MAJOR(subsys->ver),
  631. (int)NVME_MINOR(subsys->ver));
  632. }
  633. static ssize_t nvmet_subsys_attr_version_store(struct config_item *item,
  634. const char *page, size_t count)
  635. {
  636. struct nvmet_subsys *subsys = to_subsys(item);
  637. int major, minor, tertiary = 0;
  638. int ret;
  639. ret = sscanf(page, "%d.%d.%d\n", &major, &minor, &tertiary);
  640. if (ret != 2 && ret != 3)
  641. return -EINVAL;
  642. down_write(&nvmet_config_sem);
  643. subsys->ver = NVME_VS(major, minor, tertiary);
  644. up_write(&nvmet_config_sem);
  645. return count;
  646. }
  647. CONFIGFS_ATTR(nvmet_subsys_, attr_version);
  648. static ssize_t nvmet_subsys_attr_serial_show(struct config_item *item,
  649. char *page)
  650. {
  651. struct nvmet_subsys *subsys = to_subsys(item);
  652. return snprintf(page, PAGE_SIZE, "%llx\n", subsys->serial);
  653. }
  654. static ssize_t nvmet_subsys_attr_serial_store(struct config_item *item,
  655. const char *page, size_t count)
  656. {
  657. struct nvmet_subsys *subsys = to_subsys(item);
  658. down_write(&nvmet_config_sem);
  659. sscanf(page, "%llx\n", &subsys->serial);
  660. up_write(&nvmet_config_sem);
  661. return count;
  662. }
  663. CONFIGFS_ATTR(nvmet_subsys_, attr_serial);
  664. static struct configfs_attribute *nvmet_subsys_attrs[] = {
  665. &nvmet_subsys_attr_attr_allow_any_host,
  666. &nvmet_subsys_attr_attr_version,
  667. &nvmet_subsys_attr_attr_serial,
  668. NULL,
  669. };
  670. /*
  671. * Subsystem structures & folder operation functions below
  672. */
  673. static void nvmet_subsys_release(struct config_item *item)
  674. {
  675. struct nvmet_subsys *subsys = to_subsys(item);
  676. nvmet_subsys_del_ctrls(subsys);
  677. nvmet_subsys_put(subsys);
  678. }
  679. static struct configfs_item_operations nvmet_subsys_item_ops = {
  680. .release = nvmet_subsys_release,
  681. };
  682. static const struct config_item_type nvmet_subsys_type = {
  683. .ct_item_ops = &nvmet_subsys_item_ops,
  684. .ct_attrs = nvmet_subsys_attrs,
  685. .ct_owner = THIS_MODULE,
  686. };
  687. static struct config_group *nvmet_subsys_make(struct config_group *group,
  688. const char *name)
  689. {
  690. struct nvmet_subsys *subsys;
  691. if (sysfs_streq(name, NVME_DISC_SUBSYS_NAME)) {
  692. pr_err("can't create discovery subsystem through configfs\n");
  693. return ERR_PTR(-EINVAL);
  694. }
  695. subsys = nvmet_subsys_alloc(name, NVME_NQN_NVME);
  696. if (!subsys)
  697. return ERR_PTR(-ENOMEM);
  698. config_group_init_type_name(&subsys->group, name, &nvmet_subsys_type);
  699. config_group_init_type_name(&subsys->namespaces_group,
  700. "namespaces", &nvmet_namespaces_type);
  701. configfs_add_default_group(&subsys->namespaces_group, &subsys->group);
  702. config_group_init_type_name(&subsys->allowed_hosts_group,
  703. "allowed_hosts", &nvmet_allowed_hosts_type);
  704. configfs_add_default_group(&subsys->allowed_hosts_group,
  705. &subsys->group);
  706. return &subsys->group;
  707. }
  708. static struct configfs_group_operations nvmet_subsystems_group_ops = {
  709. .make_group = nvmet_subsys_make,
  710. };
  711. static const struct config_item_type nvmet_subsystems_type = {
  712. .ct_group_ops = &nvmet_subsystems_group_ops,
  713. .ct_owner = THIS_MODULE,
  714. };
  715. static ssize_t nvmet_referral_enable_show(struct config_item *item,
  716. char *page)
  717. {
  718. return snprintf(page, PAGE_SIZE, "%d\n", to_nvmet_port(item)->enabled);
  719. }
  720. static ssize_t nvmet_referral_enable_store(struct config_item *item,
  721. const char *page, size_t count)
  722. {
  723. struct nvmet_port *parent = to_nvmet_port(item->ci_parent->ci_parent);
  724. struct nvmet_port *port = to_nvmet_port(item);
  725. bool enable;
  726. if (strtobool(page, &enable))
  727. goto inval;
  728. if (enable)
  729. nvmet_referral_enable(parent, port);
  730. else
  731. nvmet_referral_disable(port);
  732. return count;
  733. inval:
  734. pr_err("Invalid value '%s' for enable\n", page);
  735. return -EINVAL;
  736. }
  737. CONFIGFS_ATTR(nvmet_referral_, enable);
  738. /*
  739. * Discovery Service subsystem definitions
  740. */
  741. static struct configfs_attribute *nvmet_referral_attrs[] = {
  742. &nvmet_attr_addr_adrfam,
  743. &nvmet_attr_addr_portid,
  744. &nvmet_attr_addr_treq,
  745. &nvmet_attr_addr_traddr,
  746. &nvmet_attr_addr_trsvcid,
  747. &nvmet_attr_addr_trtype,
  748. &nvmet_referral_attr_enable,
  749. NULL,
  750. };
  751. static void nvmet_referral_release(struct config_item *item)
  752. {
  753. struct nvmet_port *port = to_nvmet_port(item);
  754. nvmet_referral_disable(port);
  755. kfree(port);
  756. }
  757. static struct configfs_item_operations nvmet_referral_item_ops = {
  758. .release = nvmet_referral_release,
  759. };
  760. static const struct config_item_type nvmet_referral_type = {
  761. .ct_owner = THIS_MODULE,
  762. .ct_attrs = nvmet_referral_attrs,
  763. .ct_item_ops = &nvmet_referral_item_ops,
  764. };
  765. static struct config_group *nvmet_referral_make(
  766. struct config_group *group, const char *name)
  767. {
  768. struct nvmet_port *port;
  769. port = kzalloc(sizeof(*port), GFP_KERNEL);
  770. if (!port)
  771. return ERR_PTR(-ENOMEM);
  772. INIT_LIST_HEAD(&port->entry);
  773. config_group_init_type_name(&port->group, name, &nvmet_referral_type);
  774. return &port->group;
  775. }
  776. static struct configfs_group_operations nvmet_referral_group_ops = {
  777. .make_group = nvmet_referral_make,
  778. };
  779. static const struct config_item_type nvmet_referrals_type = {
  780. .ct_owner = THIS_MODULE,
  781. .ct_group_ops = &nvmet_referral_group_ops,
  782. };
  783. static struct {
  784. enum nvme_ana_state state;
  785. const char *name;
  786. } nvmet_ana_state_names[] = {
  787. { NVME_ANA_OPTIMIZED, "optimized" },
  788. { NVME_ANA_NONOPTIMIZED, "non-optimized" },
  789. { NVME_ANA_INACCESSIBLE, "inaccessible" },
  790. { NVME_ANA_PERSISTENT_LOSS, "persistent-loss" },
  791. { NVME_ANA_CHANGE, "change" },
  792. };
  793. static ssize_t nvmet_ana_group_ana_state_show(struct config_item *item,
  794. char *page)
  795. {
  796. struct nvmet_ana_group *grp = to_ana_group(item);
  797. enum nvme_ana_state state = grp->port->ana_state[grp->grpid];
  798. int i;
  799. for (i = 0; i < ARRAY_SIZE(nvmet_ana_state_names); i++) {
  800. if (state != nvmet_ana_state_names[i].state)
  801. continue;
  802. return sprintf(page, "%s\n", nvmet_ana_state_names[i].name);
  803. }
  804. return sprintf(page, "\n");
  805. }
  806. static ssize_t nvmet_ana_group_ana_state_store(struct config_item *item,
  807. const char *page, size_t count)
  808. {
  809. struct nvmet_ana_group *grp = to_ana_group(item);
  810. int i;
  811. for (i = 0; i < ARRAY_SIZE(nvmet_ana_state_names); i++) {
  812. if (sysfs_streq(page, nvmet_ana_state_names[i].name))
  813. goto found;
  814. }
  815. pr_err("Invalid value '%s' for ana_state\n", page);
  816. return -EINVAL;
  817. found:
  818. down_write(&nvmet_ana_sem);
  819. grp->port->ana_state[grp->grpid] = nvmet_ana_state_names[i].state;
  820. nvmet_ana_chgcnt++;
  821. up_write(&nvmet_ana_sem);
  822. nvmet_port_send_ana_event(grp->port);
  823. return count;
  824. }
  825. CONFIGFS_ATTR(nvmet_ana_group_, ana_state);
  826. static struct configfs_attribute *nvmet_ana_group_attrs[] = {
  827. &nvmet_ana_group_attr_ana_state,
  828. NULL,
  829. };
  830. static void nvmet_ana_group_release(struct config_item *item)
  831. {
  832. struct nvmet_ana_group *grp = to_ana_group(item);
  833. if (grp == &grp->port->ana_default_group)
  834. return;
  835. down_write(&nvmet_ana_sem);
  836. grp->port->ana_state[grp->grpid] = NVME_ANA_INACCESSIBLE;
  837. nvmet_ana_group_enabled[grp->grpid]--;
  838. up_write(&nvmet_ana_sem);
  839. nvmet_port_send_ana_event(grp->port);
  840. kfree(grp);
  841. }
  842. static struct configfs_item_operations nvmet_ana_group_item_ops = {
  843. .release = nvmet_ana_group_release,
  844. };
  845. static const struct config_item_type nvmet_ana_group_type = {
  846. .ct_item_ops = &nvmet_ana_group_item_ops,
  847. .ct_attrs = nvmet_ana_group_attrs,
  848. .ct_owner = THIS_MODULE,
  849. };
  850. static struct config_group *nvmet_ana_groups_make_group(
  851. struct config_group *group, const char *name)
  852. {
  853. struct nvmet_port *port = ana_groups_to_port(&group->cg_item);
  854. struct nvmet_ana_group *grp;
  855. u32 grpid;
  856. int ret;
  857. ret = kstrtou32(name, 0, &grpid);
  858. if (ret)
  859. goto out;
  860. ret = -EINVAL;
  861. if (grpid <= 1 || grpid > NVMET_MAX_ANAGRPS)
  862. goto out;
  863. ret = -ENOMEM;
  864. grp = kzalloc(sizeof(*grp), GFP_KERNEL);
  865. if (!grp)
  866. goto out;
  867. grp->port = port;
  868. grp->grpid = grpid;
  869. down_write(&nvmet_ana_sem);
  870. nvmet_ana_group_enabled[grpid]++;
  871. up_write(&nvmet_ana_sem);
  872. nvmet_port_send_ana_event(grp->port);
  873. config_group_init_type_name(&grp->group, name, &nvmet_ana_group_type);
  874. return &grp->group;
  875. out:
  876. return ERR_PTR(ret);
  877. }
  878. static struct configfs_group_operations nvmet_ana_groups_group_ops = {
  879. .make_group = nvmet_ana_groups_make_group,
  880. };
  881. static const struct config_item_type nvmet_ana_groups_type = {
  882. .ct_group_ops = &nvmet_ana_groups_group_ops,
  883. .ct_owner = THIS_MODULE,
  884. };
  885. /*
  886. * Ports definitions.
  887. */
  888. static void nvmet_port_release(struct config_item *item)
  889. {
  890. struct nvmet_port *port = to_nvmet_port(item);
  891. kfree(port->ana_state);
  892. kfree(port);
  893. }
  894. static struct configfs_attribute *nvmet_port_attrs[] = {
  895. &nvmet_attr_addr_adrfam,
  896. &nvmet_attr_addr_treq,
  897. &nvmet_attr_addr_traddr,
  898. &nvmet_attr_addr_trsvcid,
  899. &nvmet_attr_addr_trtype,
  900. &nvmet_attr_param_inline_data_size,
  901. NULL,
  902. };
  903. static struct configfs_item_operations nvmet_port_item_ops = {
  904. .release = nvmet_port_release,
  905. };
  906. static const struct config_item_type nvmet_port_type = {
  907. .ct_attrs = nvmet_port_attrs,
  908. .ct_item_ops = &nvmet_port_item_ops,
  909. .ct_owner = THIS_MODULE,
  910. };
  911. static struct config_group *nvmet_ports_make(struct config_group *group,
  912. const char *name)
  913. {
  914. struct nvmet_port *port;
  915. u16 portid;
  916. u32 i;
  917. if (kstrtou16(name, 0, &portid))
  918. return ERR_PTR(-EINVAL);
  919. port = kzalloc(sizeof(*port), GFP_KERNEL);
  920. if (!port)
  921. return ERR_PTR(-ENOMEM);
  922. port->ana_state = kcalloc(NVMET_MAX_ANAGRPS + 1,
  923. sizeof(*port->ana_state), GFP_KERNEL);
  924. if (!port->ana_state) {
  925. kfree(port);
  926. return ERR_PTR(-ENOMEM);
  927. }
  928. for (i = 1; i <= NVMET_MAX_ANAGRPS; i++) {
  929. if (i == NVMET_DEFAULT_ANA_GRPID)
  930. port->ana_state[1] = NVME_ANA_OPTIMIZED;
  931. else
  932. port->ana_state[i] = NVME_ANA_INACCESSIBLE;
  933. }
  934. INIT_LIST_HEAD(&port->entry);
  935. INIT_LIST_HEAD(&port->subsystems);
  936. INIT_LIST_HEAD(&port->referrals);
  937. port->inline_data_size = -1; /* < 0 == let the transport choose */
  938. port->disc_addr.portid = cpu_to_le16(portid);
  939. config_group_init_type_name(&port->group, name, &nvmet_port_type);
  940. config_group_init_type_name(&port->subsys_group,
  941. "subsystems", &nvmet_port_subsys_type);
  942. configfs_add_default_group(&port->subsys_group, &port->group);
  943. config_group_init_type_name(&port->referrals_group,
  944. "referrals", &nvmet_referrals_type);
  945. configfs_add_default_group(&port->referrals_group, &port->group);
  946. config_group_init_type_name(&port->ana_groups_group,
  947. "ana_groups", &nvmet_ana_groups_type);
  948. configfs_add_default_group(&port->ana_groups_group, &port->group);
  949. port->ana_default_group.port = port;
  950. port->ana_default_group.grpid = NVMET_DEFAULT_ANA_GRPID;
  951. config_group_init_type_name(&port->ana_default_group.group,
  952. __stringify(NVMET_DEFAULT_ANA_GRPID),
  953. &nvmet_ana_group_type);
  954. configfs_add_default_group(&port->ana_default_group.group,
  955. &port->ana_groups_group);
  956. return &port->group;
  957. }
  958. static struct configfs_group_operations nvmet_ports_group_ops = {
  959. .make_group = nvmet_ports_make,
  960. };
  961. static const struct config_item_type nvmet_ports_type = {
  962. .ct_group_ops = &nvmet_ports_group_ops,
  963. .ct_owner = THIS_MODULE,
  964. };
  965. static struct config_group nvmet_subsystems_group;
  966. static struct config_group nvmet_ports_group;
  967. static void nvmet_host_release(struct config_item *item)
  968. {
  969. struct nvmet_host *host = to_host(item);
  970. kfree(host);
  971. }
  972. static struct configfs_item_operations nvmet_host_item_ops = {
  973. .release = nvmet_host_release,
  974. };
  975. static const struct config_item_type nvmet_host_type = {
  976. .ct_item_ops = &nvmet_host_item_ops,
  977. .ct_owner = THIS_MODULE,
  978. };
  979. static struct config_group *nvmet_hosts_make_group(struct config_group *group,
  980. const char *name)
  981. {
  982. struct nvmet_host *host;
  983. host = kzalloc(sizeof(*host), GFP_KERNEL);
  984. if (!host)
  985. return ERR_PTR(-ENOMEM);
  986. config_group_init_type_name(&host->group, name, &nvmet_host_type);
  987. return &host->group;
  988. }
  989. static struct configfs_group_operations nvmet_hosts_group_ops = {
  990. .make_group = nvmet_hosts_make_group,
  991. };
  992. static const struct config_item_type nvmet_hosts_type = {
  993. .ct_group_ops = &nvmet_hosts_group_ops,
  994. .ct_owner = THIS_MODULE,
  995. };
  996. static struct config_group nvmet_hosts_group;
  997. static const struct config_item_type nvmet_root_type = {
  998. .ct_owner = THIS_MODULE,
  999. };
  1000. static struct configfs_subsystem nvmet_configfs_subsystem = {
  1001. .su_group = {
  1002. .cg_item = {
  1003. .ci_namebuf = "nvmet",
  1004. .ci_type = &nvmet_root_type,
  1005. },
  1006. },
  1007. };
  1008. int __init nvmet_init_configfs(void)
  1009. {
  1010. int ret;
  1011. config_group_init(&nvmet_configfs_subsystem.su_group);
  1012. mutex_init(&nvmet_configfs_subsystem.su_mutex);
  1013. config_group_init_type_name(&nvmet_subsystems_group,
  1014. "subsystems", &nvmet_subsystems_type);
  1015. configfs_add_default_group(&nvmet_subsystems_group,
  1016. &nvmet_configfs_subsystem.su_group);
  1017. config_group_init_type_name(&nvmet_ports_group,
  1018. "ports", &nvmet_ports_type);
  1019. configfs_add_default_group(&nvmet_ports_group,
  1020. &nvmet_configfs_subsystem.su_group);
  1021. config_group_init_type_name(&nvmet_hosts_group,
  1022. "hosts", &nvmet_hosts_type);
  1023. configfs_add_default_group(&nvmet_hosts_group,
  1024. &nvmet_configfs_subsystem.su_group);
  1025. ret = configfs_register_subsystem(&nvmet_configfs_subsystem);
  1026. if (ret) {
  1027. pr_err("configfs_register_subsystem: %d\n", ret);
  1028. return ret;
  1029. }
  1030. return 0;
  1031. }
  1032. void __exit nvmet_exit_configfs(void)
  1033. {
  1034. configfs_unregister_subsystem(&nvmet_configfs_subsystem);
  1035. }