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 8 #include <linux/debugfs.h> 9 #include <linux/fs.h> 10 #include <linux/init.h> 11 #include <linux/kernel.h> 12 13 #include "nvmet.h" 14 #include "debugfs.h" 15 16 static struct dentry *nvmet_debugfs; 17 18 #define NVMET_DEBUGFS_ATTR(field) \ 19 static int field##_open(struct inode *inode, struct file *file) \ 20 { return single_open(file, field##_show, inode->i_private); } \ 21 \ 22 static const struct file_operations field##_fops = { \ 23 .open = field##_open, \ 24 .read = seq_read, \ 25 .release = single_release, \ 26 } 27 28 #define NVMET_DEBUGFS_RW_ATTR(field) \ 29 static int field##_open(struct inode *inode, struct file *file) \ 30 { return single_open(file, field##_show, inode->i_private); } \ 31 \ 32 static const struct file_operations field##_fops = { \ 33 .open = field##_open, \ 34 .read = seq_read, \ 35 .write = field##_write, \ 36 .release = single_release, \ 37 } 38 39 static int nvmet_ctrl_hostnqn_show(struct seq_file *m, void *p) 40 { 41 struct nvmet_ctrl *ctrl = m->private; 42 43 seq_puts(m, ctrl->hostnqn); 44 return 0; 45 } 46 NVMET_DEBUGFS_ATTR(nvmet_ctrl_hostnqn); 47 48 static int nvmet_ctrl_kato_show(struct seq_file *m, void *p) 49 { 50 struct nvmet_ctrl *ctrl = m->private; 51 52 seq_printf(m, "%d\n", ctrl->kato); 53 return 0; 54 } 55 NVMET_DEBUGFS_ATTR(nvmet_ctrl_kato); 56 57 static int nvmet_ctrl_port_show(struct seq_file *m, void *p) 58 { 59 struct nvmet_ctrl *ctrl = m->private; 60 61 seq_printf(m, "%d\n", le16_to_cpu(ctrl->port->disc_addr.portid)); 62 return 0; 63 } 64 NVMET_DEBUGFS_ATTR(nvmet_ctrl_port); 65 66 static const char *const csts_state_names[] = { 67 [NVME_CSTS_RDY] = "ready", 68 [NVME_CSTS_CFS] = "fatal", 69 [NVME_CSTS_NSSRO] = "reset", 70 [NVME_CSTS_SHST_OCCUR] = "shutdown", 71 [NVME_CSTS_SHST_CMPLT] = "completed", 72 [NVME_CSTS_PP] = "paused", 73 }; 74 75 static int nvmet_ctrl_state_show(struct seq_file *m, void *p) 76 { 77 struct nvmet_ctrl *ctrl = m->private; 78 bool sep = false; 79 int i; 80 81 for (i = 0; i < ARRAY_SIZE(csts_state_names); i++) { 82 int state = BIT(i); 83 84 if (!(ctrl->csts & state)) 85 continue; 86 if (sep) 87 seq_puts(m, "|"); 88 sep = true; 89 if (csts_state_names[state]) 90 seq_puts(m, csts_state_names[state]); 91 else 92 seq_printf(m, "%d", state); 93 } 94 if (sep) 95 seq_printf(m, "\n"); 96 return 0; 97 } 98 99 static ssize_t nvmet_ctrl_state_write(struct file *file, const char __user *buf, 100 size_t count, loff_t *ppos) 101 { 102 struct seq_file *m = file->private_data; 103 struct nvmet_ctrl *ctrl = m->private; 104 char reset[16]; 105 106 if (count >= sizeof(reset)) 107 return -EINVAL; 108 if (copy_from_user(reset, buf, count)) 109 return -EFAULT; 110 if (!memcmp(reset, "fatal", 5)) 111 nvmet_ctrl_fatal_error(ctrl); 112 else 113 return -EINVAL; 114 return count; 115 } 116 NVMET_DEBUGFS_RW_ATTR(nvmet_ctrl_state); 117 118 static int nvmet_ctrl_host_traddr_show(struct seq_file *m, void *p) 119 { 120 struct nvmet_ctrl *ctrl = m->private; 121 ssize_t size; 122 char buf[NVMF_TRADDR_SIZE + 1]; 123 124 size = nvmet_ctrl_host_traddr(ctrl, buf, NVMF_TRADDR_SIZE); 125 if (size < 0) { 126 buf[0] = '\0'; 127 size = 0; 128 } 129 buf[size] = '\0'; 130 seq_printf(m, "%s\n", buf); 131 return 0; 132 } 133 NVMET_DEBUGFS_ATTR(nvmet_ctrl_host_traddr); 134 135 #ifdef CONFIG_NVME_TARGET_TCP_TLS 136 static int nvmet_ctrl_tls_key_show(struct seq_file *m, void *p) 137 { 138 struct nvmet_ctrl *ctrl = m->private; 139 key_serial_t keyid = nvmet_queue_tls_keyid(ctrl->sqs[0]); 140 141 seq_printf(m, "%08x\n", keyid); 142 return 0; 143 } 144 NVMET_DEBUGFS_ATTR(nvmet_ctrl_tls_key); 145 146 static int nvmet_ctrl_tls_concat_show(struct seq_file *m, void *p) 147 { 148 struct nvmet_ctrl *ctrl = m->private; 149 150 seq_printf(m, "%d\n", ctrl->concat); 151 return 0; 152 } 153 NVMET_DEBUGFS_ATTR(nvmet_ctrl_tls_concat); 154 #endif 155 156 static const char *const nvmet_pr_type_names[] = { 157 [NVME_PR_WRITE_EXCLUSIVE] = "write_exclusive", 158 [NVME_PR_EXCLUSIVE_ACCESS] = "exclusive_access", 159 [NVME_PR_WRITE_EXCLUSIVE_REG_ONLY] = "write_exclusive_reg_only", 160 [NVME_PR_EXCLUSIVE_ACCESS_REG_ONLY] = "exclusive_access_reg_only", 161 [NVME_PR_WRITE_EXCLUSIVE_ALL_REGS] = "write_exclusive_all_regs", 162 [NVME_PR_EXCLUSIVE_ACCESS_ALL_REGS] = "exclusive_access_all_regs", 163 }; 164 165 static const char *nvmet_pr_type_to_str(enum nvme_pr_type type) 166 { 167 if (type < ARRAY_SIZE(nvmet_pr_type_names) && 168 nvmet_pr_type_names[type]) 169 return nvmet_pr_type_names[type]; 170 return "unknown"; 171 } 172 173 static const char *const nvmet_pr_notify_names[] = { 174 [NVME_PR_NOTIFY_BIT_REG_PREEMPTED] = "reg_preempted", 175 [NVME_PR_NOTIFY_BIT_RESV_RELEASED] = "resv_released", 176 [NVME_PR_NOTIFY_BIT_RESV_PREEMPTED] = "resv_preempted", 177 }; 178 179 static void nvmet_pr_notify_mask_to_str(struct seq_file *m, unsigned long mask) 180 { 181 bool sep = false; 182 int i; 183 184 if (!mask) { 185 seq_puts(m, "none"); 186 return; 187 } 188 189 for (i = 0; i < ARRAY_SIZE(nvmet_pr_notify_names); i++) { 190 if (!test_bit(i, &mask) || !nvmet_pr_notify_names[i]) 191 continue; 192 if (sep) 193 seq_putc(m, ','); 194 seq_puts(m, nvmet_pr_notify_names[i]); 195 sep = true; 196 } 197 } 198 199 static int nvmet_ns_pr_show(struct seq_file *m, void *p) 200 { 201 struct nvmet_ns *ns = m->private; 202 struct nvmet_pr *pr = &ns->pr; 203 struct nvmet_pr_registrant *holder, *reg; 204 205 seq_printf(m, "enable=%d\n", pr->enable); 206 if (!pr->enable) 207 return 0; 208 209 seq_printf(m, "generation=%u\n", atomic_read(&pr->generation)); 210 seq_puts(m, "notify_mask="); 211 nvmet_pr_notify_mask_to_str(m, pr->notify_mask); 212 seq_putc(m, '\n'); 213 214 rcu_read_lock(); 215 holder = rcu_dereference(pr->holder); 216 if (holder) { 217 seq_printf(m, "rtype=%s\n", 218 nvmet_pr_type_to_str(holder->rtype)); 219 seq_printf(m, "holder=%pUb,0x%llx\n", 220 &holder->hostid, holder->rkey); 221 } else { 222 seq_puts(m, "rtype=none\n"); 223 seq_puts(m, "holder=none\n"); 224 } 225 226 list_for_each_entry_rcu(reg, &pr->registrant_list, entry) { 227 seq_printf(m, "reg=%pUb,0x%llx\n", 228 ®->hostid, reg->rkey); 229 } 230 rcu_read_unlock(); 231 232 return 0; 233 } 234 NVMET_DEBUGFS_ATTR(nvmet_ns_pr); 235 236 void nvmet_debugfs_ns_setup(struct nvmet_ns *ns) 237 { 238 char name[16]; 239 struct dentry *parent = ns->subsys->debugfs_dir; 240 241 if (!parent) 242 return; 243 snprintf(name, sizeof(name), "ns%u", ns->nsid); 244 ns->debugfs_dir = debugfs_create_dir(name, parent); 245 if (IS_ERR(ns->debugfs_dir)) { 246 ns->debugfs_dir = NULL; 247 return; 248 } 249 debugfs_create_file("reservation", 0400, ns->debugfs_dir, ns, 250 &nvmet_ns_pr_fops); 251 } 252 253 void nvmet_debugfs_ns_free(struct nvmet_ns *ns) 254 { 255 debugfs_remove_recursive(ns->debugfs_dir); 256 ns->debugfs_dir = NULL; 257 } 258 259 int nvmet_debugfs_ctrl_setup(struct nvmet_ctrl *ctrl) 260 { 261 char name[32]; 262 struct dentry *parent = ctrl->subsys->debugfs_dir; 263 int ret; 264 265 if (!parent) 266 return -ENODEV; 267 snprintf(name, sizeof(name), "ctrl%d", ctrl->cntlid); 268 ctrl->debugfs_dir = debugfs_create_dir(name, parent); 269 if (IS_ERR(ctrl->debugfs_dir)) { 270 ret = PTR_ERR(ctrl->debugfs_dir); 271 ctrl->debugfs_dir = NULL; 272 return ret; 273 } 274 debugfs_create_file("port", S_IRUSR, ctrl->debugfs_dir, ctrl, 275 &nvmet_ctrl_port_fops); 276 debugfs_create_file("hostnqn", S_IRUSR, ctrl->debugfs_dir, ctrl, 277 &nvmet_ctrl_hostnqn_fops); 278 debugfs_create_file("kato", S_IRUSR, ctrl->debugfs_dir, ctrl, 279 &nvmet_ctrl_kato_fops); 280 debugfs_create_file("state", S_IRUSR | S_IWUSR, ctrl->debugfs_dir, ctrl, 281 &nvmet_ctrl_state_fops); 282 debugfs_create_file("host_traddr", S_IRUSR, ctrl->debugfs_dir, ctrl, 283 &nvmet_ctrl_host_traddr_fops); 284 #ifdef CONFIG_NVME_TARGET_TCP_TLS 285 debugfs_create_file("tls_concat", S_IRUSR, ctrl->debugfs_dir, ctrl, 286 &nvmet_ctrl_tls_concat_fops); 287 debugfs_create_file("tls_key", S_IRUSR, ctrl->debugfs_dir, ctrl, 288 &nvmet_ctrl_tls_key_fops); 289 #endif 290 return 0; 291 } 292 293 void nvmet_debugfs_ctrl_free(struct nvmet_ctrl *ctrl) 294 { 295 debugfs_remove_recursive(ctrl->debugfs_dir); 296 } 297 298 int nvmet_debugfs_subsys_setup(struct nvmet_subsys *subsys) 299 { 300 int ret = 0; 301 302 subsys->debugfs_dir = debugfs_create_dir(subsys->subsysnqn, 303 nvmet_debugfs); 304 if (IS_ERR(subsys->debugfs_dir)) { 305 ret = PTR_ERR(subsys->debugfs_dir); 306 subsys->debugfs_dir = NULL; 307 } 308 return ret; 309 } 310 311 void nvmet_debugfs_subsys_free(struct nvmet_subsys *subsys) 312 { 313 debugfs_remove_recursive(subsys->debugfs_dir); 314 } 315 316 int __init nvmet_init_debugfs(void) 317 { 318 struct dentry *parent; 319 320 parent = debugfs_create_dir("nvmet", NULL); 321 if (IS_ERR(parent)) { 322 pr_warn("%s: failed to create debugfs directory\n", "nvmet"); 323 return PTR_ERR(parent); 324 } 325 nvmet_debugfs = parent; 326 return 0; 327 } 328 329 void nvmet_exit_debugfs(void) 330 { 331 debugfs_remove_recursive(nvmet_debugfs); 332 } 333