debugfs.c 7.7 KB
Newer Older
1
// SPDX-License-Identifier: GPL-2.0
2
#include <linux/ceph/ceph_debug.h>
S
Sage Weil 已提交
3

S
Sage Weil 已提交
4
#include <linux/device.h>
5
#include <linux/slab.h>
S
Sage Weil 已提交
6 7 8 9 10
#include <linux/module.h>
#include <linux/ctype.h>
#include <linux/debugfs.h>
#include <linux/seq_file.h>

11 12 13 14
#include <linux/ceph/libceph.h>
#include <linux/ceph/mon_client.h>
#include <linux/ceph/auth.h>
#include <linux/ceph/debugfs.h>
S
Sage Weil 已提交
15

R
Randy Dunlap 已提交
16 17
#include "super.h"

18 19
#ifdef CONFIG_DEBUG_FS

20
#include "mds_client.h"
S
Sage Weil 已提交
21 22 23 24

static int mdsmap_show(struct seq_file *s, void *p)
{
	int i;
25
	struct ceph_fs_client *fsc = s->private;
26
	struct ceph_mdsmap *mdsmap;
S
Sage Weil 已提交
27

28
	if (!fsc->mdsc || !fsc->mdsc->mdsmap)
S
Sage Weil 已提交
29
		return 0;
30 31 32 33 34 35 36 37 38
	mdsmap = fsc->mdsc->mdsmap;
	seq_printf(s, "epoch %d\n", mdsmap->m_epoch);
	seq_printf(s, "root %d\n", mdsmap->m_root);
	seq_printf(s, "max_mds %d\n", mdsmap->m_max_mds);
	seq_printf(s, "session_timeout %d\n", mdsmap->m_session_timeout);
	seq_printf(s, "session_autoclose %d\n", mdsmap->m_session_autoclose);
	for (i = 0; i < mdsmap->m_num_mds; i++) {
		struct ceph_entity_addr *addr = &mdsmap->m_info[i].addr;
		int state = mdsmap->m_info[i].state;
39 40
		seq_printf(s, "\tmds%d\t%s\t(%s)\n", i,
			       ceph_pr_addr(&addr->in_addr),
S
Sage Weil 已提交
41 42 43 44 45
			       ceph_mds_state_name(state));
	}
	return 0;
}

46 47 48
/*
 * mdsc debugfs
 */
S
Sage Weil 已提交
49 50
static int mdsc_show(struct seq_file *s, void *p)
{
51 52
	struct ceph_fs_client *fsc = s->private;
	struct ceph_mds_client *mdsc = fsc->mdsc;
S
Sage Weil 已提交
53 54
	struct ceph_mds_request *req;
	struct rb_node *rp;
S
Sage Weil 已提交
55 56 57 58 59
	int pathlen;
	u64 pathbase;
	char *path;

	mutex_lock(&mdsc->mutex);
S
Sage Weil 已提交
60 61
	for (rp = rb_first(&mdsc->request_tree); rp; rp = rb_next(rp)) {
		req = rb_entry(rp, struct ceph_mds_request, r_node);
S
Sage Weil 已提交
62

S
Sage Weil 已提交
63 64 65 66
		if (req->r_request && req->r_session)
			seq_printf(s, "%lld\tmds%d\t", req->r_tid,
				   req->r_session->s_mds);
		else if (!req->r_request)
S
Sage Weil 已提交
67
			seq_printf(s, "%lld\t(no request)\t", req->r_tid);
S
Sage Weil 已提交
68 69
		else
			seq_printf(s, "%lld\t(no session)\t", req->r_tid);
S
Sage Weil 已提交
70 71 72

		seq_printf(s, "%s", ceph_mds_op_name(req->r_op));

73
		if (test_bit(CEPH_MDS_R_GOT_UNSAFE, &req->r_req_flags))
74
			seq_puts(s, "\t(unsafe)");
S
Sage Weil 已提交
75
		else
76
			seq_puts(s, "\t");
S
Sage Weil 已提交
77 78 79 80 81 82

		if (req->r_inode) {
			seq_printf(s, " #%llx", ceph_ino(req->r_inode));
		} else if (req->r_dentry) {
			path = ceph_mdsc_build_path(req->r_dentry, &pathlen,
						    &pathbase, 0);
83 84
			if (IS_ERR(path))
				path = NULL;
S
Sage Weil 已提交
85
			spin_lock(&req->r_dentry->d_lock);
A
Al Viro 已提交
86
			seq_printf(s, " #%llx/%pd (%s)",
87
				   ceph_ino(d_inode(req->r_dentry->d_parent)),
A
Al Viro 已提交
88
				   req->r_dentry,
S
Sage Weil 已提交
89 90 91 92 93 94
				   path ? path : "");
			spin_unlock(&req->r_dentry->d_lock);
			kfree(path);
		} else if (req->r_path1) {
			seq_printf(s, " #%llx/%s", req->r_ino1.ino,
				   req->r_path1);
95 96
		} else {
			seq_printf(s, " #%llx", req->r_ino1.ino);
S
Sage Weil 已提交
97 98 99 100 101
		}

		if (req->r_old_dentry) {
			path = ceph_mdsc_build_path(req->r_old_dentry, &pathlen,
						    &pathbase, 0);
102 103
			if (IS_ERR(path))
				path = NULL;
S
Sage Weil 已提交
104
			spin_lock(&req->r_old_dentry->d_lock);
A
Al Viro 已提交
105
			seq_printf(s, " #%llx/%pd (%s)",
106 107
				   req->r_old_dentry_dir ?
				   ceph_ino(req->r_old_dentry_dir) : 0,
A
Al Viro 已提交
108
				   req->r_old_dentry,
S
Sage Weil 已提交
109 110 111
				   path ? path : "");
			spin_unlock(&req->r_old_dentry->d_lock);
			kfree(path);
112
		} else if (req->r_path2 && req->r_op != CEPH_MDS_OP_SYMLINK) {
S
Sage Weil 已提交
113 114 115 116 117 118 119
			if (req->r_ino2.ino)
				seq_printf(s, " #%llx/%s", req->r_ino2.ino,
					   req->r_path2);
			else
				seq_printf(s, " %s", req->r_path2);
		}

120
		seq_puts(s, "\n");
S
Sage Weil 已提交
121 122 123 124 125 126 127 128
	}
	mutex_unlock(&mdsc->mutex);

	return 0;
}

static int caps_show(struct seq_file *s, void *p)
{
129
	struct ceph_fs_client *fsc = s->private;
130
	int total, avail, used, reserved, min;
S
Sage Weil 已提交
131

132
	ceph_reservation_status(fsc, &total, &avail, &used, &reserved, &min);
S
Sage Weil 已提交
133
	seq_printf(s, "total\t\t%d\n"
134 135 136 137 138
		   "avail\t\t%d\n"
		   "used\t\t%d\n"
		   "reserved\t%d\n"
		   "min\t%d\n",
		   total, avail, used, reserved, min);
S
Sage Weil 已提交
139 140 141 142 143
	return 0;
}

static int dentry_lru_show(struct seq_file *s, void *ptr)
{
144 145
	struct ceph_fs_client *fsc = s->private;
	struct ceph_mds_client *mdsc = fsc->mdsc;
S
Sage Weil 已提交
146 147 148 149 150
	struct ceph_dentry_info *di;

	spin_lock(&mdsc->dentry_lru_lock);
	list_for_each_entry(di, &mdsc->dentry_lru, lru) {
		struct dentry *dentry = di->dentry;
A
Al Viro 已提交
151 152
		seq_printf(s, "%p %p\t%pd\n",
			   di, dentry, dentry);
S
Sage Weil 已提交
153 154 155 156 157 158
	}
	spin_unlock(&mdsc->dentry_lru_lock);

	return 0;
}

J
John Spray 已提交
159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194
static int mds_sessions_show(struct seq_file *s, void *ptr)
{
	struct ceph_fs_client *fsc = s->private;
	struct ceph_mds_client *mdsc = fsc->mdsc;
	struct ceph_auth_client *ac = fsc->client->monc.auth;
	struct ceph_options *opt = fsc->client->options;
	int mds = -1;

	mutex_lock(&mdsc->mutex);

	/* The 'num' portion of an 'entity name' */
	seq_printf(s, "global_id %llu\n", ac->global_id);

	/* The -o name mount argument */
	seq_printf(s, "name \"%s\"\n", opt->name ? opt->name : "");

	/* The list of MDS session rank+state */
	for (mds = 0; mds < mdsc->max_sessions; mds++) {
		struct ceph_mds_session *session =
			__ceph_lookup_mds_session(mdsc, mds);
		if (!session) {
			continue;
		}
		mutex_unlock(&mdsc->mutex);
		seq_printf(s, "mds.%d %s\n",
				session->s_mds,
				ceph_session_state_name(session->s_state));

		ceph_put_mds_session(session);
		mutex_lock(&mdsc->mutex);
	}
	mutex_unlock(&mdsc->mutex);

	return 0;
}

195 196 197 198
CEPH_DEFINE_SHOW_FUNC(mdsmap_show)
CEPH_DEFINE_SHOW_FUNC(mdsc_show)
CEPH_DEFINE_SHOW_FUNC(caps_show)
CEPH_DEFINE_SHOW_FUNC(dentry_lru_show)
J
John Spray 已提交
199
CEPH_DEFINE_SHOW_FUNC(mds_sessions_show)
200

S
Sage Weil 已提交
201

202 203 204
/*
 * debugfs
 */
Y
Yehuda Sadeh 已提交
205 206
static int congestion_kb_set(void *data, u64 val)
{
207
	struct ceph_fs_client *fsc = (struct ceph_fs_client *)data;
Y
Yehuda Sadeh 已提交
208

209
	fsc->mount_options->congestion_kb = (int)val;
Y
Yehuda Sadeh 已提交
210 211 212 213 214
	return 0;
}

static int congestion_kb_get(void *data, u64 *val)
{
215
	struct ceph_fs_client *fsc = (struct ceph_fs_client *)data;
Y
Yehuda Sadeh 已提交
216

217
	*val = (u64)fsc->mount_options->congestion_kb;
Y
Yehuda Sadeh 已提交
218 219 220 221 222 223
	return 0;
}

DEFINE_SIMPLE_ATTRIBUTE(congestion_kb_fops, congestion_kb_get,
			congestion_kb_set, "%llu\n");

S
Sage Weil 已提交
224

225
void ceph_fs_debugfs_cleanup(struct ceph_fs_client *fsc)
S
Sage Weil 已提交
226
{
227 228 229 230
	dout("ceph_fs_debugfs_cleanup\n");
	debugfs_remove(fsc->debugfs_bdi);
	debugfs_remove(fsc->debugfs_congestion_kb);
	debugfs_remove(fsc->debugfs_mdsmap);
J
John Spray 已提交
231
	debugfs_remove(fsc->debugfs_mds_sessions);
232 233 234
	debugfs_remove(fsc->debugfs_caps);
	debugfs_remove(fsc->debugfs_mdsc);
	debugfs_remove(fsc->debugfs_dentry_lru);
S
Sage Weil 已提交
235 236
}

237
int ceph_fs_debugfs_init(struct ceph_fs_client *fsc)
S
Sage Weil 已提交
238
{
239 240
	char name[100];
	int err = -ENOMEM;
S
Sage Weil 已提交
241

242
	dout("ceph_fs_debugfs_init\n");
243
	BUG_ON(!fsc->client->debugfs_dir);
244 245 246 247 248 249 250
	fsc->debugfs_congestion_kb =
		debugfs_create_file("writeback_congestion_kb",
				    0600,
				    fsc->client->debugfs_dir,
				    fsc,
				    &congestion_kb_fops);
	if (!fsc->debugfs_congestion_kb)
S
Sage Weil 已提交
251 252
		goto out;

253
	snprintf(name, sizeof(name), "../../bdi/%s",
254
		 dev_name(fsc->sb->s_bdi->dev));
255 256 257 258 259
	fsc->debugfs_bdi =
		debugfs_create_symlink("bdi",
				       fsc->client->debugfs_dir,
				       name);
	if (!fsc->debugfs_bdi)
S
Sage Weil 已提交
260 261
		goto out;

262
	fsc->debugfs_mdsmap = debugfs_create_file("mdsmap",
263
					0400,
264 265
					fsc->client->debugfs_dir,
					fsc,
S
Sage Weil 已提交
266
					&mdsmap_show_fops);
267
	if (!fsc->debugfs_mdsmap)
S
Sage Weil 已提交
268 269
		goto out;

J
John Spray 已提交
270
	fsc->debugfs_mds_sessions = debugfs_create_file("mds_sessions",
271
					0400,
J
John Spray 已提交
272 273 274 275 276 277
					fsc->client->debugfs_dir,
					fsc,
					&mds_sessions_show_fops);
	if (!fsc->debugfs_mds_sessions)
		goto out;

278
	fsc->debugfs_mdsc = debugfs_create_file("mdsc",
279
						0400,
280 281 282 283
						fsc->client->debugfs_dir,
						fsc,
						&mdsc_show_fops);
	if (!fsc->debugfs_mdsc)
S
Sage Weil 已提交
284 285
		goto out;

286
	fsc->debugfs_caps = debugfs_create_file("caps",
S
Sage Weil 已提交
287
						   0400,
288 289
						   fsc->client->debugfs_dir,
						   fsc,
S
Sage Weil 已提交
290
						   &caps_show_fops);
291
	if (!fsc->debugfs_caps)
S
Sage Weil 已提交
292 293
		goto out;

294
	fsc->debugfs_dentry_lru = debugfs_create_file("dentry_lru",
295
					0400,
296 297 298 299
					fsc->client->debugfs_dir,
					fsc,
					&dentry_lru_show_fops);
	if (!fsc->debugfs_dentry_lru)
Y
Yehuda Sadeh 已提交
300 301
		goto out;

S
Sage Weil 已提交
302 303 304
	return 0;

out:
305 306
	ceph_fs_debugfs_cleanup(fsc);
	return err;
S
Sage Weil 已提交
307 308 309
}


S
Sage Weil 已提交
310
#else  /* CONFIG_DEBUG_FS */
311

312
int ceph_fs_debugfs_init(struct ceph_fs_client *fsc)
313 314 315 316
{
	return 0;
}

317
void ceph_fs_debugfs_cleanup(struct ceph_fs_client *fsc)
318 319 320
{
}

S
Sage Weil 已提交
321
#endif  /* CONFIG_DEBUG_FS */