debugfs.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * DebugFS interface for the NVMe target.
  4. * Copyright (c) 2022-2024 Shadow
  5. * Copyright (c) 2024 SUSE LLC
  6. */
  7. #include <linux/debugfs.h>
  8. #include <linux/fs.h>
  9. #include <linux/init.h>
  10. #include <linux/kernel.h>
  11. #include "nvmet.h"
  12. #include "debugfs.h"
  13. static struct dentry *nvmet_debugfs;
  14. #define NVMET_DEBUGFS_ATTR(field) \
  15. static int field##_open(struct inode *inode, struct file *file) \
  16. { return single_open(file, field##_show, inode->i_private); } \
  17. \
  18. static const struct file_operations field##_fops = { \
  19. .open = field##_open, \
  20. .read = seq_read, \
  21. .release = single_release, \
  22. }
  23. #define NVMET_DEBUGFS_RW_ATTR(field) \
  24. static int field##_open(struct inode *inode, struct file *file) \
  25. { return single_open(file, field##_show, inode->i_private); } \
  26. \
  27. static const struct file_operations field##_fops = { \
  28. .open = field##_open, \
  29. .read = seq_read, \
  30. .write = field##_write, \
  31. .release = single_release, \
  32. }
  33. static int nvmet_ctrl_hostnqn_show(struct seq_file *m, void *p)
  34. {
  35. struct nvmet_ctrl *ctrl = m->private;
  36. seq_puts(m, ctrl->hostnqn);
  37. return 0;
  38. }
  39. NVMET_DEBUGFS_ATTR(nvmet_ctrl_hostnqn);
  40. static int nvmet_ctrl_kato_show(struct seq_file *m, void *p)
  41. {
  42. struct nvmet_ctrl *ctrl = m->private;
  43. seq_printf(m, "%d\n", ctrl->kato);
  44. return 0;
  45. }
  46. NVMET_DEBUGFS_ATTR(nvmet_ctrl_kato);
  47. static int nvmet_ctrl_port_show(struct seq_file *m, void *p)
  48. {
  49. struct nvmet_ctrl *ctrl = m->private;
  50. seq_printf(m, "%d\n", le16_to_cpu(ctrl->port->disc_addr.portid));
  51. return 0;
  52. }
  53. NVMET_DEBUGFS_ATTR(nvmet_ctrl_port);
  54. static const char *const csts_state_names[] = {
  55. [NVME_CSTS_RDY] = "ready",
  56. [NVME_CSTS_CFS] = "fatal",
  57. [NVME_CSTS_NSSRO] = "reset",
  58. [NVME_CSTS_SHST_OCCUR] = "shutdown",
  59. [NVME_CSTS_SHST_CMPLT] = "completed",
  60. [NVME_CSTS_PP] = "paused",
  61. };
  62. static int nvmet_ctrl_state_show(struct seq_file *m, void *p)
  63. {
  64. struct nvmet_ctrl *ctrl = m->private;
  65. bool sep = false;
  66. int i;
  67. for (i = 0; i < ARRAY_SIZE(csts_state_names); i++) {
  68. int state = BIT(i);
  69. if (!(ctrl->csts & state))
  70. continue;
  71. if (sep)
  72. seq_puts(m, "|");
  73. sep = true;
  74. if (csts_state_names[state])
  75. seq_puts(m, csts_state_names[state]);
  76. else
  77. seq_printf(m, "%d", state);
  78. }
  79. if (sep)
  80. seq_printf(m, "\n");
  81. return 0;
  82. }
  83. static ssize_t nvmet_ctrl_state_write(struct file *file, const char __user *buf,
  84. size_t count, loff_t *ppos)
  85. {
  86. struct seq_file *m = file->private_data;
  87. struct nvmet_ctrl *ctrl = m->private;
  88. char reset[16];
  89. if (count >= sizeof(reset))
  90. return -EINVAL;
  91. if (copy_from_user(reset, buf, count))
  92. return -EFAULT;
  93. if (!memcmp(reset, "fatal", 5))
  94. nvmet_ctrl_fatal_error(ctrl);
  95. else
  96. return -EINVAL;
  97. return count;
  98. }
  99. NVMET_DEBUGFS_RW_ATTR(nvmet_ctrl_state);
  100. static int nvmet_ctrl_host_traddr_show(struct seq_file *m, void *p)
  101. {
  102. struct nvmet_ctrl *ctrl = m->private;
  103. ssize_t size;
  104. char buf[NVMF_TRADDR_SIZE + 1];
  105. size = nvmet_ctrl_host_traddr(ctrl, buf, NVMF_TRADDR_SIZE);
  106. if (size < 0) {
  107. buf[0] = '\0';
  108. size = 0;
  109. }
  110. buf[size] = '\0';
  111. seq_printf(m, "%s\n", buf);
  112. return 0;
  113. }
  114. NVMET_DEBUGFS_ATTR(nvmet_ctrl_host_traddr);
  115. #ifdef CONFIG_NVME_TARGET_TCP_TLS
  116. static int nvmet_ctrl_tls_key_show(struct seq_file *m, void *p)
  117. {
  118. struct nvmet_ctrl *ctrl = m->private;
  119. key_serial_t keyid = nvmet_queue_tls_keyid(ctrl->sqs[0]);
  120. seq_printf(m, "%08x\n", keyid);
  121. return 0;
  122. }
  123. NVMET_DEBUGFS_ATTR(nvmet_ctrl_tls_key);
  124. static int nvmet_ctrl_tls_concat_show(struct seq_file *m, void *p)
  125. {
  126. struct nvmet_ctrl *ctrl = m->private;
  127. seq_printf(m, "%d\n", ctrl->concat);
  128. return 0;
  129. }
  130. NVMET_DEBUGFS_ATTR(nvmet_ctrl_tls_concat);
  131. #endif
  132. int nvmet_debugfs_ctrl_setup(struct nvmet_ctrl *ctrl)
  133. {
  134. char name[32];
  135. struct dentry *parent = ctrl->subsys->debugfs_dir;
  136. int ret;
  137. if (!parent)
  138. return -ENODEV;
  139. snprintf(name, sizeof(name), "ctrl%d", ctrl->cntlid);
  140. ctrl->debugfs_dir = debugfs_create_dir(name, parent);
  141. if (IS_ERR(ctrl->debugfs_dir)) {
  142. ret = PTR_ERR(ctrl->debugfs_dir);
  143. ctrl->debugfs_dir = NULL;
  144. return ret;
  145. }
  146. debugfs_create_file("port", S_IRUSR, ctrl->debugfs_dir, ctrl,
  147. &nvmet_ctrl_port_fops);
  148. debugfs_create_file("hostnqn", S_IRUSR, ctrl->debugfs_dir, ctrl,
  149. &nvmet_ctrl_hostnqn_fops);
  150. debugfs_create_file("kato", S_IRUSR, ctrl->debugfs_dir, ctrl,
  151. &nvmet_ctrl_kato_fops);
  152. debugfs_create_file("state", S_IRUSR | S_IWUSR, ctrl->debugfs_dir, ctrl,
  153. &nvmet_ctrl_state_fops);
  154. debugfs_create_file("host_traddr", S_IRUSR, ctrl->debugfs_dir, ctrl,
  155. &nvmet_ctrl_host_traddr_fops);
  156. #ifdef CONFIG_NVME_TARGET_TCP_TLS
  157. debugfs_create_file("tls_concat", S_IRUSR, ctrl->debugfs_dir, ctrl,
  158. &nvmet_ctrl_tls_concat_fops);
  159. debugfs_create_file("tls_key", S_IRUSR, ctrl->debugfs_dir, ctrl,
  160. &nvmet_ctrl_tls_key_fops);
  161. #endif
  162. return 0;
  163. }
  164. void nvmet_debugfs_ctrl_free(struct nvmet_ctrl *ctrl)
  165. {
  166. debugfs_remove_recursive(ctrl->debugfs_dir);
  167. }
  168. int nvmet_debugfs_subsys_setup(struct nvmet_subsys *subsys)
  169. {
  170. int ret = 0;
  171. subsys->debugfs_dir = debugfs_create_dir(subsys->subsysnqn,
  172. nvmet_debugfs);
  173. if (IS_ERR(subsys->debugfs_dir)) {
  174. ret = PTR_ERR(subsys->debugfs_dir);
  175. subsys->debugfs_dir = NULL;
  176. }
  177. return ret;
  178. }
  179. void nvmet_debugfs_subsys_free(struct nvmet_subsys *subsys)
  180. {
  181. debugfs_remove_recursive(subsys->debugfs_dir);
  182. }
  183. int __init nvmet_init_debugfs(void)
  184. {
  185. struct dentry *parent;
  186. parent = debugfs_create_dir("nvmet", NULL);
  187. if (IS_ERR(parent)) {
  188. pr_warn("%s: failed to create debugfs directory\n", "nvmet");
  189. return PTR_ERR(parent);
  190. }
  191. nvmet_debugfs = parent;
  192. return 0;
  193. }
  194. void nvmet_exit_debugfs(void)
  195. {
  196. debugfs_remove_recursive(nvmet_debugfs);
  197. }