1 // SPDX-License-Identifier: GPL-2.0
2 #include <linux/ceph/ceph_debug.h>
3
4 #include <linux/device.h>
5 #include <linux/slab.h>
6 #include <linux/module.h>
7 #include <linux/ctype.h>
8 #include <linux/debugfs.h>
9 #include <linux/seq_file.h>
10 #include <linux/math64.h>
11 #include <linux/ktime.h>
12 #include <linux/atomic.h>
13
14 #include <linux/ceph/libceph.h>
15 #include <linux/ceph/mon_client.h>
16 #include <linux/ceph/auth.h>
17 #include <linux/ceph/debugfs.h>
18 #include <linux/ceph/decode.h>
19
20 #include "super.h"
21
22 #ifdef CONFIG_DEBUG_FS
23
24 #include "mds_client.h"
25 #include "metric.h"
26 #include "subvolume_metrics.h"
27
28 /**
29 * struct ceph_session_feature_desc - Maps feature bits to names for debugfs
30 * @bit: Feature bit number from enum ceph_feature_type (see mds_client.h)
31 * @name: Human-readable feature name for debugfs output
32 *
33 * Used by metric_features_show() to display negotiated session features.
34 */
35 struct ceph_session_feature_desc {
36 unsigned int bit;
37 const char *name;
38 };
39
40 static const struct ceph_session_feature_desc ceph_session_feature_table[] = {
41 { CEPHFS_FEATURE_METRIC_COLLECT, "METRIC_COLLECT" },
42 { CEPHFS_FEATURE_REPLY_ENCODING, "REPLY_ENCODING" },
43 { CEPHFS_FEATURE_RECLAIM_CLIENT, "RECLAIM_CLIENT" },
44 { CEPHFS_FEATURE_LAZY_CAP_WANTED, "LAZY_CAP_WANTED" },
45 { CEPHFS_FEATURE_MULTI_RECONNECT, "MULTI_RECONNECT" },
46 { CEPHFS_FEATURE_DELEG_INO, "DELEG_INO" },
47 { CEPHFS_FEATURE_ALTERNATE_NAME, "ALTERNATE_NAME" },
48 { CEPHFS_FEATURE_NOTIFY_SESSION_STATE, "NOTIFY_SESSION_STATE" },
49 { CEPHFS_FEATURE_OP_GETVXATTR, "OP_GETVXATTR" },
50 { CEPHFS_FEATURE_32BITS_RETRY_FWD, "32BITS_RETRY_FWD" },
51 { CEPHFS_FEATURE_NEW_SNAPREALM_INFO, "NEW_SNAPREALM_INFO" },
52 { CEPHFS_FEATURE_HAS_OWNER_UIDGID, "HAS_OWNER_UIDGID" },
53 { CEPHFS_FEATURE_MDS_AUTH_CAPS_CHECK, "MDS_AUTH_CAPS_CHECK" },
54 { CEPHFS_FEATURE_SUBVOLUME_METRICS, "SUBVOLUME_METRICS" },
55 };
56
mdsmap_show(struct seq_file * s,void * p)57 static int mdsmap_show(struct seq_file *s, void *p)
58 {
59 int i;
60 struct ceph_fs_client *fsc = s->private;
61 struct ceph_mdsmap *mdsmap;
62
63 if (!fsc->mdsc || !fsc->mdsc->mdsmap)
64 return 0;
65 mdsmap = fsc->mdsc->mdsmap;
66 seq_printf(s, "epoch %d\n", mdsmap->m_epoch);
67 seq_printf(s, "root %d\n", mdsmap->m_root);
68 seq_printf(s, "max_mds %d\n", mdsmap->m_max_mds);
69 seq_printf(s, "session_timeout %d\n", mdsmap->m_session_timeout);
70 seq_printf(s, "session_autoclose %d\n", mdsmap->m_session_autoclose);
71 for (i = 0; i < mdsmap->possible_max_rank; i++) {
72 struct ceph_entity_addr *addr = &mdsmap->m_info[i].addr;
73 int state = mdsmap->m_info[i].state;
74 seq_printf(s, "\tmds%d\t%s\t(%s)\n", i,
75 ceph_pr_addr(addr),
76 ceph_mds_state_name(state));
77 }
78 return 0;
79 }
80
81 /*
82 * mdsc debugfs
83 */
mdsc_show(struct seq_file * s,void * p)84 static int mdsc_show(struct seq_file *s, void *p)
85 {
86 struct ceph_fs_client *fsc = s->private;
87 struct ceph_mds_client *mdsc = fsc->mdsc;
88 struct ceph_mds_request *req;
89 struct rb_node *rp;
90 char *path;
91
92 mutex_lock(&mdsc->mutex);
93 for (rp = rb_first(&mdsc->request_tree); rp; rp = rb_next(rp)) {
94 req = rb_entry(rp, struct ceph_mds_request, r_node);
95
96 if (req->r_request && req->r_session)
97 seq_printf(s, "%lld\tmds%d\t", req->r_tid,
98 req->r_session->s_mds);
99 else if (!req->r_request)
100 seq_printf(s, "%lld\t(no request)\t", req->r_tid);
101 else
102 seq_printf(s, "%lld\t(no session)\t", req->r_tid);
103
104 seq_printf(s, "%s", ceph_mds_op_name(req->r_op));
105
106 if (test_bit(CEPH_MDS_R_GOT_UNSAFE, &req->r_req_flags))
107 seq_puts(s, "\t(unsafe)");
108 else
109 seq_puts(s, "\t");
110
111 if (req->r_inode) {
112 seq_printf(s, " #%llx", ceph_ino(req->r_inode));
113 } else if (req->r_dentry) {
114 struct ceph_path_info path_info = {0};
115 path = ceph_mdsc_build_path(mdsc, req->r_dentry, &path_info, 0);
116 if (IS_ERR(path))
117 path = NULL;
118 spin_lock(&req->r_dentry->d_lock);
119 seq_printf(s, " #%llx/%pd (%s)",
120 ceph_ino(d_inode(req->r_dentry->d_parent)),
121 req->r_dentry,
122 path ? path : "");
123 spin_unlock(&req->r_dentry->d_lock);
124 ceph_mdsc_free_path_info(&path_info);
125 } else if (req->r_path1) {
126 seq_printf(s, " #%llx/%s", req->r_ino1.ino,
127 req->r_path1);
128 } else {
129 seq_printf(s, " #%llx", req->r_ino1.ino);
130 }
131
132 if (req->r_old_dentry) {
133 struct ceph_path_info path_info = {0};
134 path = ceph_mdsc_build_path(mdsc, req->r_old_dentry, &path_info, 0);
135 if (IS_ERR(path))
136 path = NULL;
137 spin_lock(&req->r_old_dentry->d_lock);
138 seq_printf(s, " #%llx/%pd (%s)",
139 req->r_old_dentry_dir ?
140 ceph_ino(req->r_old_dentry_dir) : 0,
141 req->r_old_dentry,
142 path ? path : "");
143 spin_unlock(&req->r_old_dentry->d_lock);
144 ceph_mdsc_free_path_info(&path_info);
145 } else if (req->r_path2 && req->r_op != CEPH_MDS_OP_SYMLINK) {
146 if (req->r_ino2.ino)
147 seq_printf(s, " #%llx/%s", req->r_ino2.ino,
148 req->r_path2);
149 else
150 seq_printf(s, " %s", req->r_path2);
151 }
152
153 seq_puts(s, "\n");
154 }
155 mutex_unlock(&mdsc->mutex);
156
157 return 0;
158 }
159
160 #define CEPH_LAT_METRIC_SHOW(name, total, avg, min, max, sq) { \
161 s64 _total, _avg, _min, _max, _sq, _st; \
162 _avg = ktime_to_us(avg); \
163 _min = ktime_to_us(min == KTIME_MAX ? 0 : min); \
164 _max = ktime_to_us(max); \
165 _total = total - 1; \
166 _sq = _total > 0 ? DIV64_U64_ROUND_CLOSEST(sq, _total) : 0; \
167 _st = int_sqrt64(_sq); \
168 _st = ktime_to_us(_st); \
169 seq_printf(s, "%-14s%-12lld%-16lld%-16lld%-16lld%lld\n", \
170 name, total, _avg, _min, _max, _st); \
171 }
172
173 #define CEPH_SZ_METRIC_SHOW(name, total, avg, min, max, sum) { \
174 u64 _min = min == U64_MAX ? 0 : min; \
175 seq_printf(s, "%-14s%-12lld%-16llu%-16llu%-16llu%llu\n", \
176 name, total, avg, _min, max, sum); \
177 }
178
metrics_file_show(struct seq_file * s,void * p)179 static int metrics_file_show(struct seq_file *s, void *p)
180 {
181 struct ceph_fs_client *fsc = s->private;
182 struct ceph_client_metric *m = &fsc->mdsc->metric;
183
184 seq_printf(s, "item total\n");
185 seq_printf(s, "------------------------------------------\n");
186 seq_printf(s, "%-35s%lld\n", "total inodes",
187 percpu_counter_sum(&m->total_inodes));
188 seq_printf(s, "%-35s%lld\n", "opened files",
189 atomic64_read(&m->opened_files));
190 seq_printf(s, "%-35s%lld\n", "pinned i_caps",
191 atomic64_read(&m->total_caps));
192 seq_printf(s, "%-35s%lld\n", "opened inodes",
193 percpu_counter_sum(&m->opened_inodes));
194 return 0;
195 }
196
197 static const char * const metric_str[] = {
198 "read",
199 "write",
200 "metadata",
201 "copyfrom"
202 };
metrics_latency_show(struct seq_file * s,void * p)203 static int metrics_latency_show(struct seq_file *s, void *p)
204 {
205 struct ceph_fs_client *fsc = s->private;
206 struct ceph_client_metric *cm = &fsc->mdsc->metric;
207 struct ceph_metric *m;
208 s64 total, avg, min, max, sq;
209 int i;
210
211 seq_printf(s, "item total avg_lat(us) min_lat(us) max_lat(us) stdev(us)\n");
212 seq_printf(s, "-----------------------------------------------------------------------------------\n");
213
214 for (i = 0; i < METRIC_MAX; i++) {
215 m = &cm->metric[i];
216 spin_lock(&m->lock);
217 total = m->total;
218 avg = m->latency_avg;
219 min = m->latency_min;
220 max = m->latency_max;
221 sq = m->latency_sq_sum;
222 spin_unlock(&m->lock);
223 CEPH_LAT_METRIC_SHOW(metric_str[i], total, avg, min, max, sq);
224 }
225
226 return 0;
227 }
228
metrics_size_show(struct seq_file * s,void * p)229 static int metrics_size_show(struct seq_file *s, void *p)
230 {
231 struct ceph_fs_client *fsc = s->private;
232 struct ceph_client_metric *cm = &fsc->mdsc->metric;
233 struct ceph_metric *m;
234 s64 total;
235 u64 sum, avg, min, max;
236 int i;
237
238 seq_printf(s, "item total avg_sz(bytes) min_sz(bytes) max_sz(bytes) total_sz(bytes)\n");
239 seq_printf(s, "----------------------------------------------------------------------------------------\n");
240
241 for (i = 0; i < METRIC_MAX; i++) {
242 /* skip 'metadata' as it doesn't use the size metric */
243 if (i == METRIC_METADATA)
244 continue;
245 m = &cm->metric[i];
246 spin_lock(&m->lock);
247 total = m->total;
248 sum = m->size_sum;
249 avg = total > 0 ? DIV64_U64_ROUND_CLOSEST(sum, total) : 0;
250 min = m->size_min;
251 max = m->size_max;
252 spin_unlock(&m->lock);
253 CEPH_SZ_METRIC_SHOW(metric_str[i], total, avg, min, max, sum);
254 }
255
256 return 0;
257 }
258
metrics_caps_show(struct seq_file * s,void * p)259 static int metrics_caps_show(struct seq_file *s, void *p)
260 {
261 struct ceph_fs_client *fsc = s->private;
262 struct ceph_client_metric *m = &fsc->mdsc->metric;
263 int nr_caps = 0;
264
265 seq_printf(s, "item total miss hit\n");
266 seq_printf(s, "-------------------------------------------------\n");
267
268 seq_printf(s, "%-14s%-16lld%-16lld%lld\n", "d_lease",
269 atomic64_read(&m->total_dentries),
270 percpu_counter_sum(&m->d_lease_mis),
271 percpu_counter_sum(&m->d_lease_hit));
272
273 nr_caps = atomic64_read(&m->total_caps);
274 seq_printf(s, "%-14s%-16d%-16lld%lld\n", "caps", nr_caps,
275 percpu_counter_sum(&m->i_caps_mis),
276 percpu_counter_sum(&m->i_caps_hit));
277
278 return 0;
279 }
280
caps_show_cb(struct inode * inode,int mds,void * p)281 static int caps_show_cb(struct inode *inode, int mds, void *p)
282 {
283 struct ceph_inode_info *ci = ceph_inode(inode);
284 struct seq_file *s = p;
285 struct ceph_cap *cap;
286
287 spin_lock(&ci->i_ceph_lock);
288 cap = __get_cap_for_mds(ci, mds);
289 if (cap)
290 seq_printf(s, "0x%-17llx%-3d%-17s%-17s\n", ceph_ino(inode),
291 cap->session->s_mds,
292 ceph_cap_string(cap->issued),
293 ceph_cap_string(cap->implemented));
294 spin_unlock(&ci->i_ceph_lock);
295 return 0;
296 }
297
caps_show(struct seq_file * s,void * p)298 static int caps_show(struct seq_file *s, void *p)
299 {
300 struct ceph_fs_client *fsc = s->private;
301 struct ceph_mds_client *mdsc = fsc->mdsc;
302 int total, avail, used, reserved, min, i;
303 struct cap_wait *cw;
304
305 ceph_reservation_status(fsc, &total, &avail, &used, &reserved, &min);
306 seq_printf(s, "total\t\t%d\n"
307 "avail\t\t%d\n"
308 "used\t\t%d\n"
309 "reserved\t%d\n"
310 "min\t\t%d\n\n",
311 total, avail, used, reserved, min);
312 seq_printf(s, "ino mds issued implemented\n");
313 seq_printf(s, "--------------------------------------------------\n");
314
315 mutex_lock(&mdsc->mutex);
316 for (i = 0; i < mdsc->max_sessions; i++) {
317 struct ceph_mds_session *session;
318
319 session = __ceph_lookup_mds_session(mdsc, i);
320 if (!session)
321 continue;
322 mutex_unlock(&mdsc->mutex);
323 mutex_lock(&session->s_mutex);
324 ceph_iterate_session_caps(session, caps_show_cb, s);
325 mutex_unlock(&session->s_mutex);
326 ceph_put_mds_session(session);
327 mutex_lock(&mdsc->mutex);
328 }
329 mutex_unlock(&mdsc->mutex);
330
331 seq_printf(s, "\n\nWaiters:\n--------\n");
332 seq_printf(s, "tgid ino need want\n");
333 seq_printf(s, "-----------------------------------------------------\n");
334
335 spin_lock(&mdsc->caps_list_lock);
336 list_for_each_entry(cw, &mdsc->cap_wait_list, list) {
337 seq_printf(s, "%-13d0x%-17llx%-17s%-17s\n", cw->tgid, cw->ino,
338 ceph_cap_string(cw->need),
339 ceph_cap_string(cw->want));
340 }
341 spin_unlock(&mdsc->caps_list_lock);
342
343 return 0;
344 }
345
mds_sessions_show(struct seq_file * s,void * ptr)346 static int mds_sessions_show(struct seq_file *s, void *ptr)
347 {
348 struct ceph_fs_client *fsc = s->private;
349 struct ceph_mds_client *mdsc = fsc->mdsc;
350 struct ceph_auth_client *ac = fsc->client->monc.auth;
351 struct ceph_options *opt = fsc->client->options;
352 int mds;
353
354 mutex_lock(&mdsc->mutex);
355
356 /* The 'num' portion of an 'entity name' */
357 seq_printf(s, "global_id %llu\n", ac->global_id);
358
359 /* The -o name mount argument */
360 seq_printf(s, "name \"%s\"\n", opt->name ? opt->name : "");
361
362 /* The list of MDS session rank+state */
363 for (mds = 0; mds < mdsc->max_sessions; mds++) {
364 struct ceph_mds_session *session =
365 __ceph_lookup_mds_session(mdsc, mds);
366 if (!session) {
367 continue;
368 }
369 mutex_unlock(&mdsc->mutex);
370 seq_printf(s, "mds.%d %s\n",
371 session->s_mds,
372 ceph_session_state_name(session->s_state));
373
374 ceph_put_mds_session(session);
375 mutex_lock(&mdsc->mutex);
376 }
377 mutex_unlock(&mdsc->mutex);
378
379 return 0;
380 }
381
status_show(struct seq_file * s,void * p)382 static int status_show(struct seq_file *s, void *p)
383 {
384 struct ceph_fs_client *fsc = s->private;
385 struct ceph_entity_inst *inst = &fsc->client->msgr.inst;
386 struct ceph_entity_addr *client_addr = ceph_client_addr(fsc->client);
387
388 seq_printf(s, "instance: %s.%lld %s/%u\n", ENTITY_NAME(inst->name),
389 ceph_pr_addr(client_addr), le32_to_cpu(client_addr->nonce));
390 seq_printf(s, "blocklisted: %s\n", str_true_false(fsc->blocklisted));
391
392 return 0;
393 }
394
subvolume_metrics_show(struct seq_file * s,void * p)395 static int subvolume_metrics_show(struct seq_file *s, void *p)
396 {
397 struct ceph_fs_client *fsc = s->private;
398 struct ceph_mds_client *mdsc = fsc->mdsc;
399 struct ceph_subvol_metric_snapshot *snapshot = NULL;
400 u32 nr = 0;
401 u64 total_sent = 0;
402 u64 nonzero_sends = 0;
403 u32 i;
404
405 if (!mdsc) {
406 seq_puts(s, "mds client unavailable\n");
407 return 0;
408 }
409
410 mutex_lock(&mdsc->subvol_metrics_last_mutex);
411 if (mdsc->subvol_metrics_last && mdsc->subvol_metrics_last_nr) {
412 nr = mdsc->subvol_metrics_last_nr;
413 snapshot = kmemdup_array(mdsc->subvol_metrics_last, nr,
414 sizeof(*snapshot), GFP_KERNEL);
415 if (!snapshot)
416 nr = 0;
417 }
418 total_sent = mdsc->subvol_metrics_sent;
419 nonzero_sends = mdsc->subvol_metrics_nonzero_sends;
420 mutex_unlock(&mdsc->subvol_metrics_last_mutex);
421
422 seq_puts(s, "Last sent subvolume metrics:\n");
423 if (!nr) {
424 seq_puts(s, " (none)\n");
425 } else {
426 seq_puts(s, " subvol_id rd_ops wr_ops rd_bytes wr_bytes rd_lat_us wr_lat_us\n");
427 for (i = 0; i < nr; i++) {
428 const struct ceph_subvol_metric_snapshot *e = &snapshot[i];
429
430 seq_printf(s, " %-18llu %-9llu %-9llu %-14llu %-14llu %-14llu %-14llu\n",
431 e->subvolume_id,
432 e->read_ops, e->write_ops,
433 e->read_bytes, e->write_bytes,
434 e->read_latency_us, e->write_latency_us);
435 }
436 }
437 kfree(snapshot);
438
439 seq_puts(s, "\nStatistics:\n");
440 seq_printf(s, " entries_sent: %llu\n", total_sent);
441 seq_printf(s, " non_zero_sends: %llu\n", nonzero_sends);
442
443 seq_puts(s, "\nPending (unsent) subvolume metrics:\n");
444 ceph_subvolume_metrics_dump(&mdsc->subvol_metrics, s);
445 return 0;
446 }
447
448 DEFINE_SHOW_ATTRIBUTE(mdsmap);
449 DEFINE_SHOW_ATTRIBUTE(mdsc);
450 DEFINE_SHOW_ATTRIBUTE(caps);
451 DEFINE_SHOW_ATTRIBUTE(mds_sessions);
452 DEFINE_SHOW_ATTRIBUTE(status);
453 DEFINE_SHOW_ATTRIBUTE(metrics_file);
454 DEFINE_SHOW_ATTRIBUTE(metrics_latency);
455 DEFINE_SHOW_ATTRIBUTE(metrics_size);
456 DEFINE_SHOW_ATTRIBUTE(metrics_caps);
457 DEFINE_SHOW_ATTRIBUTE(subvolume_metrics);
458
metric_features_show(struct seq_file * s,void * p)459 static int metric_features_show(struct seq_file *s, void *p)
460 {
461 struct ceph_fs_client *fsc = s->private;
462 struct ceph_mds_client *mdsc = fsc->mdsc;
463 unsigned long session_features = 0;
464 bool have_session = false;
465 bool metric_collect = false;
466 bool subvol_support = false;
467 bool metrics_enabled = false;
468 bool subvol_enabled = false;
469 int i;
470
471 if (!mdsc) {
472 seq_puts(s, "mds client unavailable\n");
473 return 0;
474 }
475
476 mutex_lock(&mdsc->mutex);
477 if (mdsc->metric.session) {
478 have_session = true;
479 session_features = mdsc->metric.session->s_features;
480 }
481 mutex_unlock(&mdsc->mutex);
482
483 if (have_session) {
484 metric_collect =
485 test_bit(CEPHFS_FEATURE_METRIC_COLLECT,
486 &session_features);
487 subvol_support =
488 test_bit(CEPHFS_FEATURE_SUBVOLUME_METRICS,
489 &session_features);
490 }
491
492 metrics_enabled = !disable_send_metrics && have_session && metric_collect;
493 subvol_enabled = metrics_enabled && subvol_support;
494
495 seq_printf(s,
496 "metrics_enabled: %s (disable_send_metrics=%d, session=%s, metric_collect=%s)\n",
497 metrics_enabled ? "yes" : "no",
498 disable_send_metrics ? 1 : 0,
499 have_session ? "yes" : "no",
500 metric_collect ? "yes" : "no");
501 seq_printf(s, "subvolume_metrics_enabled: %s\n",
502 subvol_enabled ? "yes" : "no");
503 seq_printf(s, "session_feature_bits: 0x%lx\n", session_features);
504
505 if (!have_session) {
506 seq_puts(s, "(no active MDS session for metrics)\n");
507 return 0;
508 }
509
510 for (i = 0; i < ARRAY_SIZE(ceph_session_feature_table); i++) {
511 const struct ceph_session_feature_desc *desc =
512 &ceph_session_feature_table[i];
513 bool set = test_bit(desc->bit, &session_features);
514
515 seq_printf(s, " %-24s : %s\n", desc->name,
516 set ? "yes" : "no");
517 }
518
519 return 0;
520 }
521
522 DEFINE_SHOW_ATTRIBUTE(metric_features);
523
524 /*
525 * debugfs
526 */
congestion_kb_set(void * data,u64 val)527 static int congestion_kb_set(void *data, u64 val)
528 {
529 struct ceph_fs_client *fsc = (struct ceph_fs_client *)data;
530
531 fsc->mount_options->congestion_kb = (int)val;
532 return 0;
533 }
534
congestion_kb_get(void * data,u64 * val)535 static int congestion_kb_get(void *data, u64 *val)
536 {
537 struct ceph_fs_client *fsc = (struct ceph_fs_client *)data;
538
539 *val = (u64)fsc->mount_options->congestion_kb;
540 return 0;
541 }
542
543 DEFINE_SIMPLE_ATTRIBUTE(congestion_kb_fops, congestion_kb_get,
544 congestion_kb_set, "%llu\n");
545
546
ceph_fs_debugfs_cleanup(struct ceph_fs_client * fsc)547 void ceph_fs_debugfs_cleanup(struct ceph_fs_client *fsc)
548 {
549 doutc(fsc->client, "begin\n");
550 debugfs_remove(fsc->debugfs_bdi);
551 debugfs_remove(fsc->debugfs_congestion_kb);
552 debugfs_remove(fsc->debugfs_mdsmap);
553 debugfs_remove(fsc->debugfs_mds_sessions);
554 debugfs_remove(fsc->debugfs_caps);
555 debugfs_remove(fsc->debugfs_status);
556 debugfs_remove(fsc->debugfs_mdsc);
557 debugfs_remove(fsc->debugfs_subvolume_metrics);
558 debugfs_remove_recursive(fsc->debugfs_metrics_dir);
559 doutc(fsc->client, "done\n");
560 }
561
ceph_fs_debugfs_init(struct ceph_fs_client * fsc)562 void ceph_fs_debugfs_init(struct ceph_fs_client *fsc)
563 {
564 char name[NAME_MAX];
565
566 doutc(fsc->client, "begin\n");
567 fsc->debugfs_congestion_kb =
568 debugfs_create_file("writeback_congestion_kb",
569 0600,
570 fsc->client->debugfs_dir,
571 fsc,
572 &congestion_kb_fops);
573
574 snprintf(name, sizeof(name), "../../bdi/%s",
575 bdi_dev_name(fsc->sb->s_bdi));
576 fsc->debugfs_bdi =
577 debugfs_create_symlink("bdi",
578 fsc->client->debugfs_dir,
579 name);
580
581 fsc->debugfs_mdsmap = debugfs_create_file("mdsmap",
582 0400,
583 fsc->client->debugfs_dir,
584 fsc,
585 &mdsmap_fops);
586
587 fsc->debugfs_mds_sessions = debugfs_create_file("mds_sessions",
588 0400,
589 fsc->client->debugfs_dir,
590 fsc,
591 &mds_sessions_fops);
592
593 fsc->debugfs_mdsc = debugfs_create_file("mdsc",
594 0400,
595 fsc->client->debugfs_dir,
596 fsc,
597 &mdsc_fops);
598
599 fsc->debugfs_caps = debugfs_create_file("caps",
600 0400,
601 fsc->client->debugfs_dir,
602 fsc,
603 &caps_fops);
604
605 fsc->debugfs_status = debugfs_create_file("status",
606 0400,
607 fsc->client->debugfs_dir,
608 fsc,
609 &status_fops);
610
611 fsc->debugfs_metrics_dir = debugfs_create_dir("metrics",
612 fsc->client->debugfs_dir);
613
614 debugfs_create_file("file", 0400, fsc->debugfs_metrics_dir, fsc,
615 &metrics_file_fops);
616 debugfs_create_file("latency", 0400, fsc->debugfs_metrics_dir, fsc,
617 &metrics_latency_fops);
618 debugfs_create_file("size", 0400, fsc->debugfs_metrics_dir, fsc,
619 &metrics_size_fops);
620 debugfs_create_file("caps", 0400, fsc->debugfs_metrics_dir, fsc,
621 &metrics_caps_fops);
622 debugfs_create_file("metric_features", 0400, fsc->debugfs_metrics_dir,
623 fsc, &metric_features_fops);
624 fsc->debugfs_subvolume_metrics =
625 debugfs_create_file("subvolumes", 0400,
626 fsc->debugfs_metrics_dir, fsc,
627 &subvolume_metrics_fops);
628 doutc(fsc->client, "done\n");
629 }
630
631
632 #else /* CONFIG_DEBUG_FS */
633
ceph_fs_debugfs_init(struct ceph_fs_client * fsc)634 void ceph_fs_debugfs_init(struct ceph_fs_client *fsc)
635 {
636 }
637
ceph_fs_debugfs_cleanup(struct ceph_fs_client * fsc)638 void ceph_fs_debugfs_cleanup(struct ceph_fs_client *fsc)
639 {
640 }
641
642 #endif /* CONFIG_DEBUG_FS */
643