| .. | .. |
|---|
| 1 | 1 | // SPDX-License-Identifier: GPL-2.0 |
|---|
| 2 | | -/** |
|---|
| 2 | +/* |
|---|
| 3 | 3 | * debugfs interface for sunrpc |
|---|
| 4 | 4 | * |
|---|
| 5 | 5 | * (c) 2014 Jeff Layton <jlayton@primarydata.com> |
|---|
| .. | .. |
|---|
| 11 | 11 | #include "netns.h" |
|---|
| 12 | 12 | |
|---|
| 13 | 13 | static struct dentry *topdir; |
|---|
| 14 | | -static struct dentry *rpc_fault_dir; |
|---|
| 15 | 14 | static struct dentry *rpc_clnt_dir; |
|---|
| 16 | 15 | static struct dentry *rpc_xprt_dir; |
|---|
| 17 | 16 | |
|---|
| .. | .. |
|---|
| 33 | 32 | |
|---|
| 34 | 33 | seq_printf(f, "%5u %04x %6d 0x%x 0x%x %8ld %ps %sv%u %s a:%ps q:%s\n", |
|---|
| 35 | 34 | task->tk_pid, task->tk_flags, task->tk_status, |
|---|
| 36 | | - clnt->cl_clid, xid, task->tk_timeout, task->tk_ops, |
|---|
| 35 | + clnt->cl_clid, xid, rpc_task_timeout(task), task->tk_ops, |
|---|
| 37 | 36 | clnt->cl_program->name, clnt->cl_vers, rpc_proc_name(task), |
|---|
| 38 | 37 | task->tk_action, rpc_waitq); |
|---|
| 39 | 38 | return 0; |
|---|
| .. | .. |
|---|
| 118 | 117 | .release = tasks_release, |
|---|
| 119 | 118 | }; |
|---|
| 120 | 119 | |
|---|
| 120 | +static int do_xprt_debugfs(struct rpc_clnt *clnt, struct rpc_xprt *xprt, void *numv) |
|---|
| 121 | +{ |
|---|
| 122 | + int len; |
|---|
| 123 | + char name[24]; /* enough for "../../rpc_xprt/ + 8 hex digits + NULL */ |
|---|
| 124 | + char link[9]; /* enough for 8 hex digits + NULL */ |
|---|
| 125 | + int *nump = numv; |
|---|
| 126 | + |
|---|
| 127 | + if (IS_ERR_OR_NULL(xprt->debugfs)) |
|---|
| 128 | + return 0; |
|---|
| 129 | + len = snprintf(name, sizeof(name), "../../rpc_xprt/%s", |
|---|
| 130 | + xprt->debugfs->d_name.name); |
|---|
| 131 | + if (len >= sizeof(name)) |
|---|
| 132 | + return -1; |
|---|
| 133 | + if (*nump == 0) |
|---|
| 134 | + strcpy(link, "xprt"); |
|---|
| 135 | + else { |
|---|
| 136 | + len = snprintf(link, sizeof(link), "xprt%d", *nump); |
|---|
| 137 | + if (len >= sizeof(link)) |
|---|
| 138 | + return -1; |
|---|
| 139 | + } |
|---|
| 140 | + debugfs_create_symlink(link, clnt->cl_debugfs, name); |
|---|
| 141 | + (*nump)++; |
|---|
| 142 | + return 0; |
|---|
| 143 | +} |
|---|
| 144 | + |
|---|
| 121 | 145 | void |
|---|
| 122 | 146 | rpc_clnt_debugfs_register(struct rpc_clnt *clnt) |
|---|
| 123 | 147 | { |
|---|
| 124 | 148 | int len; |
|---|
| 125 | | - char name[24]; /* enough for "../../rpc_xprt/ + 8 hex digits + NULL */ |
|---|
| 126 | | - struct rpc_xprt *xprt; |
|---|
| 127 | | - |
|---|
| 128 | | - /* Already registered? */ |
|---|
| 129 | | - if (clnt->cl_debugfs || !rpc_clnt_dir) |
|---|
| 130 | | - return; |
|---|
| 149 | + char name[9]; /* enough for 8 hex digits + NULL */ |
|---|
| 150 | + int xprtnum = 0; |
|---|
| 131 | 151 | |
|---|
| 132 | 152 | len = snprintf(name, sizeof(name), "%x", clnt->cl_clid); |
|---|
| 133 | 153 | if (len >= sizeof(name)) |
|---|
| .. | .. |
|---|
| 135 | 155 | |
|---|
| 136 | 156 | /* make the per-client dir */ |
|---|
| 137 | 157 | clnt->cl_debugfs = debugfs_create_dir(name, rpc_clnt_dir); |
|---|
| 138 | | - if (!clnt->cl_debugfs) |
|---|
| 139 | | - return; |
|---|
| 140 | 158 | |
|---|
| 141 | 159 | /* make tasks file */ |
|---|
| 142 | | - if (!debugfs_create_file("tasks", S_IFREG | 0400, clnt->cl_debugfs, |
|---|
| 143 | | - clnt, &tasks_fops)) |
|---|
| 144 | | - goto out_err; |
|---|
| 160 | + debugfs_create_file("tasks", S_IFREG | 0400, clnt->cl_debugfs, clnt, |
|---|
| 161 | + &tasks_fops); |
|---|
| 145 | 162 | |
|---|
| 146 | | - rcu_read_lock(); |
|---|
| 147 | | - xprt = rcu_dereference(clnt->cl_xprt); |
|---|
| 148 | | - /* no "debugfs" dentry? Don't bother with the symlink. */ |
|---|
| 149 | | - if (!xprt->debugfs) { |
|---|
| 150 | | - rcu_read_unlock(); |
|---|
| 151 | | - return; |
|---|
| 152 | | - } |
|---|
| 153 | | - len = snprintf(name, sizeof(name), "../../rpc_xprt/%s", |
|---|
| 154 | | - xprt->debugfs->d_name.name); |
|---|
| 155 | | - rcu_read_unlock(); |
|---|
| 156 | | - |
|---|
| 157 | | - if (len >= sizeof(name)) |
|---|
| 158 | | - goto out_err; |
|---|
| 159 | | - |
|---|
| 160 | | - if (!debugfs_create_symlink("xprt", clnt->cl_debugfs, name)) |
|---|
| 161 | | - goto out_err; |
|---|
| 162 | | - |
|---|
| 163 | | - return; |
|---|
| 164 | | -out_err: |
|---|
| 165 | | - debugfs_remove_recursive(clnt->cl_debugfs); |
|---|
| 166 | | - clnt->cl_debugfs = NULL; |
|---|
| 163 | + rpc_clnt_iterate_for_each_xprt(clnt, do_xprt_debugfs, &xprtnum); |
|---|
| 167 | 164 | } |
|---|
| 168 | 165 | |
|---|
| 169 | 166 | void |
|---|
| .. | .. |
|---|
| 226 | 223 | static atomic_t cur_id; |
|---|
| 227 | 224 | char name[9]; /* 8 hex digits + NULL term */ |
|---|
| 228 | 225 | |
|---|
| 229 | | - if (!rpc_xprt_dir) |
|---|
| 230 | | - return; |
|---|
| 231 | | - |
|---|
| 232 | 226 | id = (unsigned int)atomic_inc_return(&cur_id); |
|---|
| 233 | 227 | |
|---|
| 234 | 228 | len = snprintf(name, sizeof(name), "%x", id); |
|---|
| .. | .. |
|---|
| 237 | 231 | |
|---|
| 238 | 232 | /* make the per-client dir */ |
|---|
| 239 | 233 | xprt->debugfs = debugfs_create_dir(name, rpc_xprt_dir); |
|---|
| 240 | | - if (!xprt->debugfs) |
|---|
| 241 | | - return; |
|---|
| 242 | 234 | |
|---|
| 243 | 235 | /* make tasks file */ |
|---|
| 244 | | - if (!debugfs_create_file("info", S_IFREG | 0400, xprt->debugfs, |
|---|
| 245 | | - xprt, &xprt_info_fops)) { |
|---|
| 246 | | - debugfs_remove_recursive(xprt->debugfs); |
|---|
| 247 | | - xprt->debugfs = NULL; |
|---|
| 248 | | - } |
|---|
| 236 | + debugfs_create_file("info", S_IFREG | 0400, xprt->debugfs, xprt, |
|---|
| 237 | + &xprt_info_fops); |
|---|
| 249 | 238 | |
|---|
| 250 | 239 | atomic_set(&xprt->inject_disconnect, rpc_inject_disconnect); |
|---|
| 251 | 240 | } |
|---|
| .. | .. |
|---|
| 308 | 297 | .release = fault_release, |
|---|
| 309 | 298 | }; |
|---|
| 310 | 299 | |
|---|
| 311 | | -static struct dentry * |
|---|
| 312 | | -inject_fault_dir(struct dentry *topdir) |
|---|
| 313 | | -{ |
|---|
| 314 | | - struct dentry *faultdir; |
|---|
| 315 | | - |
|---|
| 316 | | - faultdir = debugfs_create_dir("inject_fault", topdir); |
|---|
| 317 | | - if (!faultdir) |
|---|
| 318 | | - return NULL; |
|---|
| 319 | | - |
|---|
| 320 | | - if (!debugfs_create_file("disconnect", S_IFREG | 0400, faultdir, |
|---|
| 321 | | - NULL, &fault_disconnect_fops)) |
|---|
| 322 | | - return NULL; |
|---|
| 323 | | - |
|---|
| 324 | | - return faultdir; |
|---|
| 325 | | -} |
|---|
| 326 | | - |
|---|
| 327 | 300 | void __exit |
|---|
| 328 | 301 | sunrpc_debugfs_exit(void) |
|---|
| 329 | 302 | { |
|---|
| 330 | 303 | debugfs_remove_recursive(topdir); |
|---|
| 331 | 304 | topdir = NULL; |
|---|
| 332 | | - rpc_fault_dir = NULL; |
|---|
| 333 | 305 | rpc_clnt_dir = NULL; |
|---|
| 334 | 306 | rpc_xprt_dir = NULL; |
|---|
| 335 | 307 | } |
|---|
| .. | .. |
|---|
| 337 | 309 | void __init |
|---|
| 338 | 310 | sunrpc_debugfs_init(void) |
|---|
| 339 | 311 | { |
|---|
| 340 | | - topdir = debugfs_create_dir("sunrpc", NULL); |
|---|
| 341 | | - if (!topdir) |
|---|
| 342 | | - return; |
|---|
| 312 | + struct dentry *rpc_fault_dir; |
|---|
| 343 | 313 | |
|---|
| 344 | | - rpc_fault_dir = inject_fault_dir(topdir); |
|---|
| 345 | | - if (!rpc_fault_dir) |
|---|
| 346 | | - goto out_remove; |
|---|
| 314 | + topdir = debugfs_create_dir("sunrpc", NULL); |
|---|
| 347 | 315 | |
|---|
| 348 | 316 | rpc_clnt_dir = debugfs_create_dir("rpc_clnt", topdir); |
|---|
| 349 | | - if (!rpc_clnt_dir) |
|---|
| 350 | | - goto out_remove; |
|---|
| 351 | 317 | |
|---|
| 352 | 318 | rpc_xprt_dir = debugfs_create_dir("rpc_xprt", topdir); |
|---|
| 353 | | - if (!rpc_xprt_dir) |
|---|
| 354 | | - goto out_remove; |
|---|
| 355 | 319 | |
|---|
| 356 | | - return; |
|---|
| 357 | | -out_remove: |
|---|
| 358 | | - debugfs_remove_recursive(topdir); |
|---|
| 359 | | - topdir = NULL; |
|---|
| 360 | | - rpc_fault_dir = NULL; |
|---|
| 361 | | - rpc_clnt_dir = NULL; |
|---|
| 320 | + rpc_fault_dir = debugfs_create_dir("inject_fault", topdir); |
|---|
| 321 | + |
|---|
| 322 | + debugfs_create_file("disconnect", S_IFREG | 0400, rpc_fault_dir, NULL, |
|---|
| 323 | + &fault_disconnect_fops); |
|---|
| 362 | 324 | } |
|---|