diff options
Diffstat (limited to 'net/sunrpc/debugfs.c')
| -rw-r--r-- | net/sunrpc/debugfs.c | 52 |
1 files changed, 29 insertions, 23 deletions
diff --git a/net/sunrpc/debugfs.c b/net/sunrpc/debugfs.c index e811f390f9f6..82962f7e6e88 100644 --- a/net/sunrpc/debugfs.c +++ b/net/sunrpc/debugfs.c | |||
| @@ -129,48 +129,52 @@ static const struct file_operations tasks_fops = { | |||
| 129 | .release = tasks_release, | 129 | .release = tasks_release, |
| 130 | }; | 130 | }; |
| 131 | 131 | ||
| 132 | int | 132 | void |
| 133 | rpc_clnt_debugfs_register(struct rpc_clnt *clnt) | 133 | rpc_clnt_debugfs_register(struct rpc_clnt *clnt) |
| 134 | { | 134 | { |
| 135 | int len, err; | 135 | int len; |
| 136 | char name[24]; /* enough for "../../rpc_xprt/ + 8 hex digits + NULL */ | 136 | char name[24]; /* enough for "../../rpc_xprt/ + 8 hex digits + NULL */ |
| 137 | struct rpc_xprt *xprt; | ||
| 137 | 138 | ||
| 138 | /* Already registered? */ | 139 | /* Already registered? */ |
| 139 | if (clnt->cl_debugfs) | 140 | if (clnt->cl_debugfs || !rpc_clnt_dir) |
| 140 | return 0; | 141 | return; |
| 141 | 142 | ||
| 142 | len = snprintf(name, sizeof(name), "%x", clnt->cl_clid); | 143 | len = snprintf(name, sizeof(name), "%x", clnt->cl_clid); |
| 143 | if (len >= sizeof(name)) | 144 | if (len >= sizeof(name)) |
| 144 | return -EINVAL; | 145 | return; |
| 145 | 146 | ||
| 146 | /* make the per-client dir */ | 147 | /* make the per-client dir */ |
| 147 | clnt->cl_debugfs = debugfs_create_dir(name, rpc_clnt_dir); | 148 | clnt->cl_debugfs = debugfs_create_dir(name, rpc_clnt_dir); |
| 148 | if (!clnt->cl_debugfs) | 149 | if (!clnt->cl_debugfs) |
| 149 | return -ENOMEM; | 150 | return; |
| 150 | 151 | ||
| 151 | /* make tasks file */ | 152 | /* make tasks file */ |
| 152 | err = -ENOMEM; | ||
| 153 | if (!debugfs_create_file("tasks", S_IFREG | S_IRUSR, clnt->cl_debugfs, | 153 | if (!debugfs_create_file("tasks", S_IFREG | S_IRUSR, clnt->cl_debugfs, |
| 154 | clnt, &tasks_fops)) | 154 | clnt, &tasks_fops)) |
| 155 | goto out_err; | 155 | goto out_err; |
| 156 | 156 | ||
| 157 | err = -EINVAL; | ||
| 158 | rcu_read_lock(); | 157 | rcu_read_lock(); |
| 158 | xprt = rcu_dereference(clnt->cl_xprt); | ||
| 159 | /* no "debugfs" dentry? Don't bother with the symlink. */ | ||
| 160 | if (!xprt->debugfs) { | ||
| 161 | rcu_read_unlock(); | ||
| 162 | return; | ||
| 163 | } | ||
| 159 | len = snprintf(name, sizeof(name), "../../rpc_xprt/%s", | 164 | len = snprintf(name, sizeof(name), "../../rpc_xprt/%s", |
| 160 | rcu_dereference(clnt->cl_xprt)->debugfs->d_name.name); | 165 | xprt->debugfs->d_name.name); |
| 161 | rcu_read_unlock(); | 166 | rcu_read_unlock(); |
| 167 | |||
| 162 | if (len >= sizeof(name)) | 168 | if (len >= sizeof(name)) |
| 163 | goto out_err; | 169 | goto out_err; |
| 164 | 170 | ||
| 165 | err = -ENOMEM; | ||
| 166 | if (!debugfs_create_symlink("xprt", clnt->cl_debugfs, name)) | 171 | if (!debugfs_create_symlink("xprt", clnt->cl_debugfs, name)) |
| 167 | goto out_err; | 172 | goto out_err; |
| 168 | 173 | ||
| 169 | return 0; | 174 | return; |
| 170 | out_err: | 175 | out_err: |
| 171 | debugfs_remove_recursive(clnt->cl_debugfs); | 176 | debugfs_remove_recursive(clnt->cl_debugfs); |
| 172 | clnt->cl_debugfs = NULL; | 177 | clnt->cl_debugfs = NULL; |
| 173 | return err; | ||
| 174 | } | 178 | } |
| 175 | 179 | ||
| 176 | void | 180 | void |
| @@ -226,33 +230,33 @@ static const struct file_operations xprt_info_fops = { | |||
| 226 | .release = xprt_info_release, | 230 | .release = xprt_info_release, |
| 227 | }; | 231 | }; |
| 228 | 232 | ||
| 229 | int | 233 | void |
| 230 | rpc_xprt_debugfs_register(struct rpc_xprt *xprt) | 234 | rpc_xprt_debugfs_register(struct rpc_xprt *xprt) |
| 231 | { | 235 | { |
| 232 | int len, id; | 236 | int len, id; |
| 233 | static atomic_t cur_id; | 237 | static atomic_t cur_id; |
| 234 | char name[9]; /* 8 hex digits + NULL term */ | 238 | char name[9]; /* 8 hex digits + NULL term */ |
| 235 | 239 | ||
| 240 | if (!rpc_xprt_dir) | ||
| 241 | return; | ||
| 242 | |||
| 236 | id = (unsigned int)atomic_inc_return(&cur_id); | 243 | id = (unsigned int)atomic_inc_return(&cur_id); |
| 237 | 244 | ||
| 238 | len = snprintf(name, sizeof(name), "%x", id); | 245 | len = snprintf(name, sizeof(name), "%x", id); |
| 239 | if (len >= sizeof(name)) | 246 | if (len >= sizeof(name)) |
| 240 | return -EINVAL; | 247 | return; |
| 241 | 248 | ||
| 242 | /* make the per-client dir */ | 249 | /* make the per-client dir */ |
| 243 | xprt->debugfs = debugfs_create_dir(name, rpc_xprt_dir); | 250 | xprt->debugfs = debugfs_create_dir(name, rpc_xprt_dir); |
| 244 | if (!xprt->debugfs) | 251 | if (!xprt->debugfs) |
| 245 | return -ENOMEM; | 252 | return; |
| 246 | 253 | ||
| 247 | /* make tasks file */ | 254 | /* make tasks file */ |
| 248 | if (!debugfs_create_file("info", S_IFREG | S_IRUSR, xprt->debugfs, | 255 | if (!debugfs_create_file("info", S_IFREG | S_IRUSR, xprt->debugfs, |
| 249 | xprt, &xprt_info_fops)) { | 256 | xprt, &xprt_info_fops)) { |
| 250 | debugfs_remove_recursive(xprt->debugfs); | 257 | debugfs_remove_recursive(xprt->debugfs); |
| 251 | xprt->debugfs = NULL; | 258 | xprt->debugfs = NULL; |
| 252 | return -ENOMEM; | ||
| 253 | } | 259 | } |
| 254 | |||
| 255 | return 0; | ||
| 256 | } | 260 | } |
| 257 | 261 | ||
| 258 | void | 262 | void |
| @@ -266,14 +270,17 @@ void __exit | |||
| 266 | sunrpc_debugfs_exit(void) | 270 | sunrpc_debugfs_exit(void) |
| 267 | { | 271 | { |
| 268 | debugfs_remove_recursive(topdir); | 272 | debugfs_remove_recursive(topdir); |
| 273 | topdir = NULL; | ||
| 274 | rpc_clnt_dir = NULL; | ||
| 275 | rpc_xprt_dir = NULL; | ||
| 269 | } | 276 | } |
| 270 | 277 | ||
| 271 | int __init | 278 | void __init |
| 272 | sunrpc_debugfs_init(void) | 279 | sunrpc_debugfs_init(void) |
| 273 | { | 280 | { |
| 274 | topdir = debugfs_create_dir("sunrpc", NULL); | 281 | topdir = debugfs_create_dir("sunrpc", NULL); |
| 275 | if (!topdir) | 282 | if (!topdir) |
| 276 | goto out; | 283 | return; |
| 277 | 284 | ||
| 278 | rpc_clnt_dir = debugfs_create_dir("rpc_clnt", topdir); | 285 | rpc_clnt_dir = debugfs_create_dir("rpc_clnt", topdir); |
| 279 | if (!rpc_clnt_dir) | 286 | if (!rpc_clnt_dir) |
| @@ -283,10 +290,9 @@ sunrpc_debugfs_init(void) | |||
| 283 | if (!rpc_xprt_dir) | 290 | if (!rpc_xprt_dir) |
| 284 | goto out_remove; | 291 | goto out_remove; |
| 285 | 292 | ||
| 286 | return 0; | 293 | return; |
| 287 | out_remove: | 294 | out_remove: |
| 288 | debugfs_remove_recursive(topdir); | 295 | debugfs_remove_recursive(topdir); |
| 289 | topdir = NULL; | 296 | topdir = NULL; |
| 290 | out: | 297 | rpc_clnt_dir = NULL; |
| 291 | return -ENOMEM; | ||
| 292 | } | 298 | } |
