debugfs.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. #include <linux/ceph/ceph_debug.h>
  2. #include <linux/device.h>
  3. #include <linux/slab.h>
  4. #include <linux/module.h>
  5. #include <linux/ctype.h>
  6. #include <linux/debugfs.h>
  7. #include <linux/seq_file.h>
  8. #include <linux/ceph/libceph.h>
  9. #include <linux/ceph/mon_client.h>
  10. #include <linux/ceph/auth.h>
  11. #include <linux/ceph/debugfs.h>
  12. #include "super.h"
  13. #ifdef CONFIG_DEBUG_FS
  14. #include "mds_client.h"
  15. static int mdsmap_show(struct seq_file *s, void *p)
  16. {
  17. int i;
  18. struct ceph_fs_client *fsc = s->private;
  19. if (fsc->mdsc == NULL || fsc->mdsc->mdsmap == NULL)
  20. return 0;
  21. seq_printf(s, "epoch %d\n", fsc->mdsc->mdsmap->m_epoch);
  22. seq_printf(s, "root %d\n", fsc->mdsc->mdsmap->m_root);
  23. seq_printf(s, "session_timeout %d\n",
  24. fsc->mdsc->mdsmap->m_session_timeout);
  25. seq_printf(s, "session_autoclose %d\n",
  26. fsc->mdsc->mdsmap->m_session_autoclose);
  27. for (i = 0; i < fsc->mdsc->mdsmap->m_max_mds; i++) {
  28. struct ceph_entity_addr *addr =
  29. &fsc->mdsc->mdsmap->m_info[i].addr;
  30. int state = fsc->mdsc->mdsmap->m_info[i].state;
  31. seq_printf(s, "\tmds%d\t%s\t(%s)\n", i,
  32. ceph_pr_addr(&addr->in_addr),
  33. ceph_mds_state_name(state));
  34. }
  35. return 0;
  36. }
  37. /*
  38. * mdsc debugfs
  39. */
  40. static int mdsc_show(struct seq_file *s, void *p)
  41. {
  42. struct ceph_fs_client *fsc = s->private;
  43. struct ceph_mds_client *mdsc = fsc->mdsc;
  44. struct ceph_mds_request *req;
  45. struct rb_node *rp;
  46. int pathlen;
  47. u64 pathbase;
  48. char *path;
  49. mutex_lock(&mdsc->mutex);
  50. for (rp = rb_first(&mdsc->request_tree); rp; rp = rb_next(rp)) {
  51. req = rb_entry(rp, struct ceph_mds_request, r_node);
  52. if (req->r_request && req->r_session)
  53. seq_printf(s, "%lld\tmds%d\t", req->r_tid,
  54. req->r_session->s_mds);
  55. else if (!req->r_request)
  56. seq_printf(s, "%lld\t(no request)\t", req->r_tid);
  57. else
  58. seq_printf(s, "%lld\t(no session)\t", req->r_tid);
  59. seq_printf(s, "%s", ceph_mds_op_name(req->r_op));
  60. if (req->r_got_unsafe)
  61. seq_printf(s, "\t(unsafe)");
  62. else
  63. seq_printf(s, "\t");
  64. if (req->r_inode) {
  65. seq_printf(s, " #%llx", ceph_ino(req->r_inode));
  66. } else if (req->r_dentry) {
  67. path = ceph_mdsc_build_path(req->r_dentry, &pathlen,
  68. &pathbase, 0);
  69. if (IS_ERR(path))
  70. path = NULL;
  71. spin_lock(&req->r_dentry->d_lock);
  72. seq_printf(s, " #%llx/%.*s (%s)",
  73. ceph_ino(req->r_dentry->d_parent->d_inode),
  74. req->r_dentry->d_name.len,
  75. req->r_dentry->d_name.name,
  76. path ? path : "");
  77. spin_unlock(&req->r_dentry->d_lock);
  78. kfree(path);
  79. } else if (req->r_path1) {
  80. seq_printf(s, " #%llx/%s", req->r_ino1.ino,
  81. req->r_path1);
  82. }
  83. if (req->r_old_dentry) {
  84. path = ceph_mdsc_build_path(req->r_old_dentry, &pathlen,
  85. &pathbase, 0);
  86. if (IS_ERR(path))
  87. path = NULL;
  88. spin_lock(&req->r_old_dentry->d_lock);
  89. seq_printf(s, " #%llx/%.*s (%s)",
  90. ceph_ino(req->r_old_dentry->d_parent->d_inode),
  91. req->r_old_dentry->d_name.len,
  92. req->r_old_dentry->d_name.name,
  93. path ? path : "");
  94. spin_unlock(&req->r_old_dentry->d_lock);
  95. kfree(path);
  96. } else if (req->r_path2) {
  97. if (req->r_ino2.ino)
  98. seq_printf(s, " #%llx/%s", req->r_ino2.ino,
  99. req->r_path2);
  100. else
  101. seq_printf(s, " %s", req->r_path2);
  102. }
  103. seq_printf(s, "\n");
  104. }
  105. mutex_unlock(&mdsc->mutex);
  106. return 0;
  107. }
  108. static int caps_show(struct seq_file *s, void *p)
  109. {
  110. struct ceph_fs_client *fsc = s->private;
  111. int total, avail, used, reserved, min;
  112. ceph_reservation_status(fsc, &total, &avail, &used, &reserved, &min);
  113. seq_printf(s, "total\t\t%d\n"
  114. "avail\t\t%d\n"
  115. "used\t\t%d\n"
  116. "reserved\t%d\n"
  117. "min\t%d\n",
  118. total, avail, used, reserved, min);
  119. return 0;
  120. }
  121. static int dentry_lru_show(struct seq_file *s, void *ptr)
  122. {
  123. struct ceph_fs_client *fsc = s->private;
  124. struct ceph_mds_client *mdsc = fsc->mdsc;
  125. struct ceph_dentry_info *di;
  126. spin_lock(&mdsc->dentry_lru_lock);
  127. list_for_each_entry(di, &mdsc->dentry_lru, lru) {
  128. struct dentry *dentry = di->dentry;
  129. seq_printf(s, "%p %p\t%.*s\n",
  130. di, dentry, dentry->d_name.len, dentry->d_name.name);
  131. }
  132. spin_unlock(&mdsc->dentry_lru_lock);
  133. return 0;
  134. }
  135. CEPH_DEFINE_SHOW_FUNC(mdsmap_show)
  136. CEPH_DEFINE_SHOW_FUNC(mdsc_show)
  137. CEPH_DEFINE_SHOW_FUNC(caps_show)
  138. CEPH_DEFINE_SHOW_FUNC(dentry_lru_show)
  139. /*
  140. * debugfs
  141. */
  142. static int congestion_kb_set(void *data, u64 val)
  143. {
  144. struct ceph_fs_client *fsc = (struct ceph_fs_client *)data;
  145. fsc->mount_options->congestion_kb = (int)val;
  146. return 0;
  147. }
  148. static int congestion_kb_get(void *data, u64 *val)
  149. {
  150. struct ceph_fs_client *fsc = (struct ceph_fs_client *)data;
  151. *val = (u64)fsc->mount_options->congestion_kb;
  152. return 0;
  153. }
  154. DEFINE_SIMPLE_ATTRIBUTE(congestion_kb_fops, congestion_kb_get,
  155. congestion_kb_set, "%llu\n");
  156. void ceph_fs_debugfs_cleanup(struct ceph_fs_client *fsc)
  157. {
  158. dout("ceph_fs_debugfs_cleanup\n");
  159. debugfs_remove(fsc->debugfs_bdi);
  160. debugfs_remove(fsc->debugfs_congestion_kb);
  161. debugfs_remove(fsc->debugfs_mdsmap);
  162. debugfs_remove(fsc->debugfs_caps);
  163. debugfs_remove(fsc->debugfs_mdsc);
  164. debugfs_remove(fsc->debugfs_dentry_lru);
  165. }
  166. int ceph_fs_debugfs_init(struct ceph_fs_client *fsc)
  167. {
  168. char name[100];
  169. int err = -ENOMEM;
  170. dout("ceph_fs_debugfs_init\n");
  171. fsc->debugfs_congestion_kb =
  172. debugfs_create_file("writeback_congestion_kb",
  173. 0600,
  174. fsc->client->debugfs_dir,
  175. fsc,
  176. &congestion_kb_fops);
  177. if (!fsc->debugfs_congestion_kb)
  178. goto out;
  179. snprintf(name, sizeof(name), "../../bdi/%s",
  180. dev_name(fsc->backing_dev_info.dev));
  181. fsc->debugfs_bdi =
  182. debugfs_create_symlink("bdi",
  183. fsc->client->debugfs_dir,
  184. name);
  185. if (!fsc->debugfs_bdi)
  186. goto out;
  187. fsc->debugfs_mdsmap = debugfs_create_file("mdsmap",
  188. 0600,
  189. fsc->client->debugfs_dir,
  190. fsc,
  191. &mdsmap_show_fops);
  192. if (!fsc->debugfs_mdsmap)
  193. goto out;
  194. fsc->debugfs_mdsc = debugfs_create_file("mdsc",
  195. 0600,
  196. fsc->client->debugfs_dir,
  197. fsc,
  198. &mdsc_show_fops);
  199. if (!fsc->debugfs_mdsc)
  200. goto out;
  201. fsc->debugfs_caps = debugfs_create_file("caps",
  202. 0400,
  203. fsc->client->debugfs_dir,
  204. fsc,
  205. &caps_show_fops);
  206. if (!fsc->debugfs_caps)
  207. goto out;
  208. fsc->debugfs_dentry_lru = debugfs_create_file("dentry_lru",
  209. 0600,
  210. fsc->client->debugfs_dir,
  211. fsc,
  212. &dentry_lru_show_fops);
  213. if (!fsc->debugfs_dentry_lru)
  214. goto out;
  215. return 0;
  216. out:
  217. ceph_fs_debugfs_cleanup(fsc);
  218. return err;
  219. }
  220. #else /* CONFIG_DEBUG_FS */
  221. int ceph_fs_debugfs_init(struct ceph_fs_client *fsc)
  222. {
  223. return 0;
  224. }
  225. void ceph_fs_debugfs_cleanup(struct ceph_fs_client *fsc)
  226. {
  227. }
  228. #endif /* CONFIG_DEBUG_FS */