linux/fs/ceph/debugfs.c
<<
>>
Prefs
   1#include <linux/ceph/ceph_debug.h>
   2
   3#include <linux/device.h>
   4#include <linux/slab.h>
   5#include <linux/module.h>
   6#include <linux/ctype.h>
   7#include <linux/debugfs.h>
   8#include <linux/seq_file.h>
   9
  10#include <linux/ceph/libceph.h>
  11#include <linux/ceph/mon_client.h>
  12#include <linux/ceph/auth.h>
  13#include <linux/ceph/debugfs.h>
  14
  15#include "super.h"
  16
  17#ifdef CONFIG_DEBUG_FS
  18
  19#include "mds_client.h"
  20
  21static int mdsmap_show(struct seq_file *s, void *p)
  22{
  23        int i;
  24        struct ceph_fs_client *fsc = s->private;
  25        struct ceph_mdsmap *mdsmap;
  26
  27        if (fsc->mdsc == NULL || fsc->mdsc->mdsmap == NULL)
  28                return 0;
  29        mdsmap = fsc->mdsc->mdsmap;
  30        seq_printf(s, "epoch %d\n", mdsmap->m_epoch);
  31        seq_printf(s, "root %d\n", mdsmap->m_root);
  32        seq_printf(s, "max_mds %d\n", mdsmap->m_max_mds);
  33        seq_printf(s, "session_timeout %d\n", mdsmap->m_session_timeout);
  34        seq_printf(s, "session_autoclose %d\n", mdsmap->m_session_autoclose);
  35        for (i = 0; i < mdsmap->m_num_mds; i++) {
  36                struct ceph_entity_addr *addr = &mdsmap->m_info[i].addr;
  37                int state = mdsmap->m_info[i].state;
  38                seq_printf(s, "\tmds%d\t%s\t(%s)\n", i,
  39                               ceph_pr_addr(&addr->in_addr),
  40                               ceph_mds_state_name(state));
  41        }
  42        return 0;
  43}
  44
  45/*
  46 * mdsc debugfs
  47 */
  48static int mdsc_show(struct seq_file *s, void *p)
  49{
  50        struct ceph_fs_client *fsc = s->private;
  51        struct ceph_mds_client *mdsc = fsc->mdsc;
  52        struct ceph_mds_request *req;
  53        struct rb_node *rp;
  54        int pathlen;
  55        u64 pathbase;
  56        char *path;
  57
  58        mutex_lock(&mdsc->mutex);
  59        for (rp = rb_first(&mdsc->request_tree); rp; rp = rb_next(rp)) {
  60                req = rb_entry(rp, struct ceph_mds_request, r_node);
  61
  62                if (req->r_request && req->r_session)
  63                        seq_printf(s, "%lld\tmds%d\t", req->r_tid,
  64                                   req->r_session->s_mds);
  65                else if (!req->r_request)
  66                        seq_printf(s, "%lld\t(no request)\t", req->r_tid);
  67                else
  68                        seq_printf(s, "%lld\t(no session)\t", req->r_tid);
  69
  70                seq_printf(s, "%s", ceph_mds_op_name(req->r_op));
  71
  72                if (test_bit(CEPH_MDS_R_GOT_UNSAFE, &req->r_req_flags))
  73                        seq_puts(s, "\t(unsafe)");
  74                else
  75                        seq_puts(s, "\t");
  76
  77                if (req->r_inode) {
  78                        seq_printf(s, " #%llx", ceph_ino(req->r_inode));
  79                } else if (req->r_dentry) {
  80                        path = ceph_mdsc_build_path(req->r_dentry, &pathlen,
  81                                                    &pathbase, 0);
  82                        if (IS_ERR(path))
  83                                path = NULL;
  84                        spin_lock(&req->r_dentry->d_lock);
  85                        seq_printf(s, " #%llx/%pd (%s)",
  86                                   ceph_ino(d_inode(req->r_dentry->d_parent)),
  87                                   req->r_dentry,
  88                                   path ? path : "");
  89                        spin_unlock(&req->r_dentry->d_lock);
  90                        kfree(path);
  91                } else if (req->r_path1) {
  92                        seq_printf(s, " #%llx/%s", req->r_ino1.ino,
  93                                   req->r_path1);
  94                } else {
  95                        seq_printf(s, " #%llx", req->r_ino1.ino);
  96                }
  97
  98                if (req->r_old_dentry) {
  99                        path = ceph_mdsc_build_path(req->r_old_dentry, &pathlen,
 100                                                    &pathbase, 0);
 101                        if (IS_ERR(path))
 102                                path = NULL;
 103                        spin_lock(&req->r_old_dentry->d_lock);
 104                        seq_printf(s, " #%llx/%pd (%s)",
 105                                   req->r_old_dentry_dir ?
 106                                   ceph_ino(req->r_old_dentry_dir) : 0,
 107                                   req->r_old_dentry,
 108                                   path ? path : "");
 109                        spin_unlock(&req->r_old_dentry->d_lock);
 110                        kfree(path);
 111                } else if (req->r_path2 && req->r_op != CEPH_MDS_OP_SYMLINK) {
 112                        if (req->r_ino2.ino)
 113                                seq_printf(s, " #%llx/%s", req->r_ino2.ino,
 114                                           req->r_path2);
 115                        else
 116                                seq_printf(s, " %s", req->r_path2);
 117                }
 118
 119                seq_puts(s, "\n");
 120        }
 121        mutex_unlock(&mdsc->mutex);
 122
 123        return 0;
 124}
 125
 126static int caps_show(struct seq_file *s, void *p)
 127{
 128        struct ceph_fs_client *fsc = s->private;
 129        int total, avail, used, reserved, min;
 130
 131        ceph_reservation_status(fsc, &total, &avail, &used, &reserved, &min);
 132        seq_printf(s, "total\t\t%d\n"
 133                   "avail\t\t%d\n"
 134                   "used\t\t%d\n"
 135                   "reserved\t%d\n"
 136                   "min\t%d\n",
 137                   total, avail, used, reserved, min);
 138        return 0;
 139}
 140
 141static int dentry_lru_show(struct seq_file *s, void *ptr)
 142{
 143        struct ceph_fs_client *fsc = s->private;
 144        struct ceph_mds_client *mdsc = fsc->mdsc;
 145        struct ceph_dentry_info *di;
 146
 147        spin_lock(&mdsc->dentry_lru_lock);
 148        list_for_each_entry(di, &mdsc->dentry_lru, lru) {
 149                struct dentry *dentry = di->dentry;
 150                seq_printf(s, "%p %p\t%pd\n",
 151                           di, dentry, dentry);
 152        }
 153        spin_unlock(&mdsc->dentry_lru_lock);
 154
 155        return 0;
 156}
 157
 158static int mds_sessions_show(struct seq_file *s, void *ptr)
 159{
 160        struct ceph_fs_client *fsc = s->private;
 161        struct ceph_mds_client *mdsc = fsc->mdsc;
 162        struct ceph_auth_client *ac = fsc->client->monc.auth;
 163        struct ceph_options *opt = fsc->client->options;
 164        int mds = -1;
 165
 166        mutex_lock(&mdsc->mutex);
 167
 168        /* The 'num' portion of an 'entity name' */
 169        seq_printf(s, "global_id %llu\n", ac->global_id);
 170
 171        /* The -o name mount argument */
 172        seq_printf(s, "name \"%s\"\n", opt->name ? opt->name : "");
 173
 174        /* The list of MDS session rank+state */
 175        for (mds = 0; mds < mdsc->max_sessions; mds++) {
 176                struct ceph_mds_session *session =
 177                        __ceph_lookup_mds_session(mdsc, mds);
 178                if (!session) {
 179                        continue;
 180                }
 181                mutex_unlock(&mdsc->mutex);
 182                seq_printf(s, "mds.%d %s\n",
 183                                session->s_mds,
 184                                ceph_session_state_name(session->s_state));
 185
 186                ceph_put_mds_session(session);
 187                mutex_lock(&mdsc->mutex);
 188        }
 189        mutex_unlock(&mdsc->mutex);
 190
 191        return 0;
 192}
 193
 194CEPH_DEFINE_SHOW_FUNC(mdsmap_show)
 195CEPH_DEFINE_SHOW_FUNC(mdsc_show)
 196CEPH_DEFINE_SHOW_FUNC(caps_show)
 197CEPH_DEFINE_SHOW_FUNC(dentry_lru_show)
 198CEPH_DEFINE_SHOW_FUNC(mds_sessions_show)
 199
 200
 201/*
 202 * debugfs
 203 */
 204static int congestion_kb_set(void *data, u64 val)
 205{
 206        struct ceph_fs_client *fsc = (struct ceph_fs_client *)data;
 207
 208        fsc->mount_options->congestion_kb = (int)val;
 209        return 0;
 210}
 211
 212static int congestion_kb_get(void *data, u64 *val)
 213{
 214        struct ceph_fs_client *fsc = (struct ceph_fs_client *)data;
 215
 216        *val = (u64)fsc->mount_options->congestion_kb;
 217        return 0;
 218}
 219
 220DEFINE_SIMPLE_ATTRIBUTE(congestion_kb_fops, congestion_kb_get,
 221                        congestion_kb_set, "%llu\n");
 222
 223
 224void ceph_fs_debugfs_cleanup(struct ceph_fs_client *fsc)
 225{
 226        dout("ceph_fs_debugfs_cleanup\n");
 227        debugfs_remove(fsc->debugfs_bdi);
 228        debugfs_remove(fsc->debugfs_congestion_kb);
 229        debugfs_remove(fsc->debugfs_mdsmap);
 230        debugfs_remove(fsc->debugfs_mds_sessions);
 231        debugfs_remove(fsc->debugfs_caps);
 232        debugfs_remove(fsc->debugfs_mdsc);
 233        debugfs_remove(fsc->debugfs_dentry_lru);
 234}
 235
 236int ceph_fs_debugfs_init(struct ceph_fs_client *fsc)
 237{
 238        char name[100];
 239        int err = -ENOMEM;
 240
 241        dout("ceph_fs_debugfs_init\n");
 242        BUG_ON(!fsc->client->debugfs_dir);
 243        fsc->debugfs_congestion_kb =
 244                debugfs_create_file("writeback_congestion_kb",
 245                                    0600,
 246                                    fsc->client->debugfs_dir,
 247                                    fsc,
 248                                    &congestion_kb_fops);
 249        if (!fsc->debugfs_congestion_kb)
 250                goto out;
 251
 252        snprintf(name, sizeof(name), "../../bdi/%s",
 253                 dev_name(fsc->sb->s_bdi->dev));
 254        fsc->debugfs_bdi =
 255                debugfs_create_symlink("bdi",
 256                                       fsc->client->debugfs_dir,
 257                                       name);
 258        if (!fsc->debugfs_bdi)
 259                goto out;
 260
 261        fsc->debugfs_mdsmap = debugfs_create_file("mdsmap",
 262                                        0600,
 263                                        fsc->client->debugfs_dir,
 264                                        fsc,
 265                                        &mdsmap_show_fops);
 266        if (!fsc->debugfs_mdsmap)
 267                goto out;
 268
 269        fsc->debugfs_mds_sessions = debugfs_create_file("mds_sessions",
 270                                        0600,
 271                                        fsc->client->debugfs_dir,
 272                                        fsc,
 273                                        &mds_sessions_show_fops);
 274        if (!fsc->debugfs_mds_sessions)
 275                goto out;
 276
 277        fsc->debugfs_mdsc = debugfs_create_file("mdsc",
 278                                                0600,
 279                                                fsc->client->debugfs_dir,
 280                                                fsc,
 281                                                &mdsc_show_fops);
 282        if (!fsc->debugfs_mdsc)
 283                goto out;
 284
 285        fsc->debugfs_caps = debugfs_create_file("caps",
 286                                                   0400,
 287                                                   fsc->client->debugfs_dir,
 288                                                   fsc,
 289                                                   &caps_show_fops);
 290        if (!fsc->debugfs_caps)
 291                goto out;
 292
 293        fsc->debugfs_dentry_lru = debugfs_create_file("dentry_lru",
 294                                        0600,
 295                                        fsc->client->debugfs_dir,
 296                                        fsc,
 297                                        &dentry_lru_show_fops);
 298        if (!fsc->debugfs_dentry_lru)
 299                goto out;
 300
 301        return 0;
 302
 303out:
 304        ceph_fs_debugfs_cleanup(fsc);
 305        return err;
 306}
 307
 308
 309#else  /* CONFIG_DEBUG_FS */
 310
 311int ceph_fs_debugfs_init(struct ceph_fs_client *fsc)
 312{
 313        return 0;
 314}
 315
 316void ceph_fs_debugfs_cleanup(struct ceph_fs_client *fsc)
 317{
 318}
 319
 320#endif  /* CONFIG_DEBUG_FS */
 321