debugfs.c 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  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_puts(s, "\t(unsafe)");
  62. else
  63. seq_puts(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/%pd (%s)",
  73. ceph_ino(d_inode(req->r_dentry->d_parent)),
  74. req->r_dentry,
  75. path ? path : "");
  76. spin_unlock(&req->r_dentry->d_lock);
  77. kfree(path);
  78. } else if (req->r_path1) {
  79. seq_printf(s, " #%llx/%s", req->r_ino1.ino,
  80. req->r_path1);
  81. } else {
  82. seq_printf(s, " #%llx", req->r_ino1.ino);
  83. }
  84. if (req->r_old_dentry) {
  85. path = ceph_mdsc_build_path(req->r_old_dentry, &pathlen,
  86. &pathbase, 0);
  87. if (IS_ERR(path))
  88. path = NULL;
  89. spin_lock(&req->r_old_dentry->d_lock);
  90. seq_printf(s, " #%llx/%pd (%s)",
  91. req->r_old_dentry_dir ?
  92. ceph_ino(req->r_old_dentry_dir) : 0,
  93. req->r_old_dentry,
  94. path ? path : "");
  95. spin_unlock(&req->r_old_dentry->d_lock);
  96. kfree(path);
  97. } else if (req->r_path2) {
  98. if (req->r_ino2.ino)
  99. seq_printf(s, " #%llx/%s", req->r_ino2.ino,
  100. req->r_path2);
  101. else
  102. seq_printf(s, " %s", req->r_path2);
  103. }
  104. seq_puts(s, "\n");
  105. }
  106. mutex_unlock(&mdsc->mutex);
  107. return 0;
  108. }
  109. static int caps_show(struct seq_file *s, void *p)
  110. {
  111. struct ceph_fs_client *fsc = s->private;
  112. int total, avail, used, reserved, min;
  113. ceph_reservation_status(fsc, &total, &avail, &used, &reserved, &min);
  114. seq_printf(s, "total\t\t%d\n"
  115. "avail\t\t%d\n"
  116. "used\t\t%d\n"
  117. "reserved\t%d\n"
  118. "min\t%d\n",
  119. total, avail, used, reserved, min);
  120. return 0;
  121. }
  122. static int dentry_lru_show(struct seq_file *s, void *ptr)
  123. {
  124. struct ceph_fs_client *fsc = s->private;
  125. struct ceph_mds_client *mdsc = fsc->mdsc;
  126. struct ceph_dentry_info *di;
  127. spin_lock(&mdsc->dentry_lru_lock);
  128. list_for_each_entry(di, &mdsc->dentry_lru, lru) {
  129. struct dentry *dentry = di->dentry;
  130. seq_printf(s, "%p %p\t%pd\n",
  131. di, dentry, dentry);
  132. }
  133. spin_unlock(&mdsc->dentry_lru_lock);
  134. return 0;
  135. }
  136. static int mds_sessions_show(struct seq_file *s, void *ptr)
  137. {
  138. struct ceph_fs_client *fsc = s->private;
  139. struct ceph_mds_client *mdsc = fsc->mdsc;
  140. struct ceph_auth_client *ac = fsc->client->monc.auth;
  141. struct ceph_options *opt = fsc->client->options;
  142. int mds = -1;
  143. mutex_lock(&mdsc->mutex);
  144. /* The 'num' portion of an 'entity name' */
  145. seq_printf(s, "global_id %llu\n", ac->global_id);
  146. /* The -o name mount argument */
  147. seq_printf(s, "name \"%s\"\n", opt->name ? opt->name : "");
  148. /* The list of MDS session rank+state */
  149. for (mds = 0; mds < mdsc->max_sessions; mds++) {
  150. struct ceph_mds_session *session =
  151. __ceph_lookup_mds_session(mdsc, mds);
  152. if (!session) {
  153. continue;
  154. }
  155. mutex_unlock(&mdsc->mutex);
  156. seq_printf(s, "mds.%d %s\n",
  157. session->s_mds,
  158. ceph_session_state_name(session->s_state));
  159. ceph_put_mds_session(session);
  160. mutex_lock(&mdsc->mutex);
  161. }
  162. mutex_unlock(&mdsc->mutex);
  163. return 0;
  164. }
  165. CEPH_DEFINE_SHOW_FUNC(mdsmap_show)
  166. CEPH_DEFINE_SHOW_FUNC(mdsc_show)
  167. CEPH_DEFINE_SHOW_FUNC(caps_show)
  168. CEPH_DEFINE_SHOW_FUNC(dentry_lru_show)
  169. CEPH_DEFINE_SHOW_FUNC(mds_sessions_show)
  170. /*
  171. * debugfs
  172. */
  173. static int congestion_kb_set(void *data, u64 val)
  174. {
  175. struct ceph_fs_client *fsc = (struct ceph_fs_client *)data;
  176. fsc->mount_options->congestion_kb = (int)val;
  177. return 0;
  178. }
  179. static int congestion_kb_get(void *data, u64 *val)
  180. {
  181. struct ceph_fs_client *fsc = (struct ceph_fs_client *)data;
  182. *val = (u64)fsc->mount_options->congestion_kb;
  183. return 0;
  184. }
  185. DEFINE_SIMPLE_ATTRIBUTE(congestion_kb_fops, congestion_kb_get,
  186. congestion_kb_set, "%llu\n");
  187. void ceph_fs_debugfs_cleanup(struct ceph_fs_client *fsc)
  188. {
  189. dout("ceph_fs_debugfs_cleanup\n");
  190. debugfs_remove(fsc->debugfs_bdi);
  191. debugfs_remove(fsc->debugfs_congestion_kb);
  192. debugfs_remove(fsc->debugfs_mdsmap);
  193. debugfs_remove(fsc->debugfs_mds_sessions);
  194. debugfs_remove(fsc->debugfs_caps);
  195. debugfs_remove(fsc->debugfs_mdsc);
  196. debugfs_remove(fsc->debugfs_dentry_lru);
  197. }
  198. int ceph_fs_debugfs_init(struct ceph_fs_client *fsc)
  199. {
  200. char name[100];
  201. int err = -ENOMEM;
  202. dout("ceph_fs_debugfs_init\n");
  203. BUG_ON(!fsc->client->debugfs_dir);
  204. fsc->debugfs_congestion_kb =
  205. debugfs_create_file("writeback_congestion_kb",
  206. 0600,
  207. fsc->client->debugfs_dir,
  208. fsc,
  209. &congestion_kb_fops);
  210. if (!fsc->debugfs_congestion_kb)
  211. goto out;
  212. snprintf(name, sizeof(name), "../../bdi/%s",
  213. dev_name(fsc->backing_dev_info.dev));
  214. fsc->debugfs_bdi =
  215. debugfs_create_symlink("bdi",
  216. fsc->client->debugfs_dir,
  217. name);
  218. if (!fsc->debugfs_bdi)
  219. goto out;
  220. fsc->debugfs_mdsmap = debugfs_create_file("mdsmap",
  221. 0600,
  222. fsc->client->debugfs_dir,
  223. fsc,
  224. &mdsmap_show_fops);
  225. if (!fsc->debugfs_mdsmap)
  226. goto out;
  227. fsc->debugfs_mds_sessions = debugfs_create_file("mds_sessions",
  228. 0600,
  229. fsc->client->debugfs_dir,
  230. fsc,
  231. &mds_sessions_show_fops);
  232. if (!fsc->debugfs_mds_sessions)
  233. goto out;
  234. fsc->debugfs_mdsc = debugfs_create_file("mdsc",
  235. 0600,
  236. fsc->client->debugfs_dir,
  237. fsc,
  238. &mdsc_show_fops);
  239. if (!fsc->debugfs_mdsc)
  240. goto out;
  241. fsc->debugfs_caps = debugfs_create_file("caps",
  242. 0400,
  243. fsc->client->debugfs_dir,
  244. fsc,
  245. &caps_show_fops);
  246. if (!fsc->debugfs_caps)
  247. goto out;
  248. fsc->debugfs_dentry_lru = debugfs_create_file("dentry_lru",
  249. 0600,
  250. fsc->client->debugfs_dir,
  251. fsc,
  252. &dentry_lru_show_fops);
  253. if (!fsc->debugfs_dentry_lru)
  254. goto out;
  255. return 0;
  256. out:
  257. ceph_fs_debugfs_cleanup(fsc);
  258. return err;
  259. }
  260. #else /* CONFIG_DEBUG_FS */
  261. int ceph_fs_debugfs_init(struct ceph_fs_client *fsc)
  262. {
  263. return 0;
  264. }
  265. void ceph_fs_debugfs_cleanup(struct ceph_fs_client *fsc)
  266. {
  267. }
  268. #endif /* CONFIG_DEBUG_FS */