Skip to content

Commit 1dd8d47

Browse files
lxbszidryomov
authored andcommitted
ceph: metrics for opened files, pinned caps and opened inodes
In client for each inode, it may have many opened files and may have been pinned in more than one MDS servers. And some inodes are idle, which have no any opened files. This patch will show these metrics in the debugfs, likes: item total ----------------------------------------- opened files / total inodes 14 / 5 pinned i_caps / total inodes 7 / 5 opened inodes / total inodes 3 / 5 Will send these metrics to ceph, which will be used by the `fs top`, later. [ jlayton: drop unrelated hunk, count hashed inodes instead of allocated ones ] URL: https://tracker.ceph.com/issues/47005 Signed-off-by: Xiubo Li <[email protected]> Signed-off-by: Jeff Layton <[email protected]> Signed-off-by: Ilya Dryomov <[email protected]>
1 parent 2678da8 commit 1dd8d47

File tree

5 files changed

+74
-3
lines changed

5 files changed

+74
-3
lines changed

fs/ceph/caps.c

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4283,13 +4283,30 @@ void __ceph_touch_fmode(struct ceph_inode_info *ci,
42834283

42844284
void ceph_get_fmode(struct ceph_inode_info *ci, int fmode, int count)
42854285
{
4286-
int i;
4286+
struct ceph_mds_client *mdsc = ceph_sb_to_mdsc(ci->vfs_inode.i_sb);
42874287
int bits = (fmode << 1) | 1;
4288+
bool is_opened = false;
4289+
int i;
4290+
4291+
if (count == 1)
4292+
atomic64_inc(&mdsc->metric.opened_files);
4293+
42884294
spin_lock(&ci->i_ceph_lock);
42894295
for (i = 0; i < CEPH_FILE_MODE_BITS; i++) {
42904296
if (bits & (1 << i))
42914297
ci->i_nr_by_mode[i] += count;
4298+
4299+
/*
4300+
* If any of the mode ref is larger than 1,
4301+
* that means it has been already opened by
4302+
* others. Just skip checking the PIN ref.
4303+
*/
4304+
if (i && ci->i_nr_by_mode[i] > 1)
4305+
is_opened = true;
42924306
}
4307+
4308+
if (!is_opened)
4309+
percpu_counter_inc(&mdsc->metric.opened_inodes);
42934310
spin_unlock(&ci->i_ceph_lock);
42944311
}
42954312

@@ -4300,15 +4317,32 @@ void ceph_get_fmode(struct ceph_inode_info *ci, int fmode, int count)
43004317
*/
43014318
void ceph_put_fmode(struct ceph_inode_info *ci, int fmode, int count)
43024319
{
4303-
int i;
4320+
struct ceph_mds_client *mdsc = ceph_sb_to_mdsc(ci->vfs_inode.i_sb);
43044321
int bits = (fmode << 1) | 1;
4322+
bool is_closed = true;
4323+
int i;
4324+
4325+
if (count == 1)
4326+
atomic64_dec(&mdsc->metric.opened_files);
4327+
43054328
spin_lock(&ci->i_ceph_lock);
43064329
for (i = 0; i < CEPH_FILE_MODE_BITS; i++) {
43074330
if (bits & (1 << i)) {
43084331
BUG_ON(ci->i_nr_by_mode[i] < count);
43094332
ci->i_nr_by_mode[i] -= count;
43104333
}
4334+
4335+
/*
4336+
* If any of the mode ref is not 0 after
4337+
* decreased, that means it is still opened
4338+
* by others. Just skip checking the PIN ref.
4339+
*/
4340+
if (i && ci->i_nr_by_mode[i])
4341+
is_closed = false;
43114342
}
4343+
4344+
if (is_closed)
4345+
percpu_counter_dec(&mdsc->metric.opened_inodes);
43124346
spin_unlock(&ci->i_ceph_lock);
43134347
}
43144348

fs/ceph/debugfs.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,17 @@ static int metric_show(struct seq_file *s, void *p)
148148
int nr_caps = 0;
149149
s64 total, sum, avg, min, max, sq;
150150

151+
sum = percpu_counter_sum(&m->total_inodes);
152+
seq_printf(s, "item total\n");
153+
seq_printf(s, "------------------------------------------\n");
154+
seq_printf(s, "%-35s%lld / %lld\n", "opened files / total inodes",
155+
atomic64_read(&m->opened_files), sum);
156+
seq_printf(s, "%-35s%lld / %lld\n", "pinned i_caps / total inodes",
157+
atomic64_read(&m->total_caps), sum);
158+
seq_printf(s, "%-35s%lld / %lld\n", "opened inodes / total inodes",
159+
percpu_counter_sum(&m->opened_inodes), sum);
160+
161+
seq_printf(s, "\n");
151162
seq_printf(s, "item total avg_lat(us) min_lat(us) max_lat(us) stdev(us)\n");
152163
seq_printf(s, "-----------------------------------------------------------------------------------\n");
153164

fs/ceph/inode.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,13 @@ static void ceph_inode_work(struct work_struct *work);
4242
static int ceph_set_ino_cb(struct inode *inode, void *data)
4343
{
4444
struct ceph_inode_info *ci = ceph_inode(inode);
45+
struct ceph_mds_client *mdsc = ceph_sb_to_mdsc(inode->i_sb);
4546

4647
ci->i_vino = *(struct ceph_vino *)data;
4748
inode->i_ino = ceph_vino_to_ino_t(ci->i_vino);
4849
inode_set_iversion_raw(inode, 0);
50+
percpu_counter_inc(&mdsc->metric.total_inodes);
51+
4952
return 0;
5053
}
5154

@@ -538,11 +541,14 @@ void ceph_free_inode(struct inode *inode)
538541
void ceph_evict_inode(struct inode *inode)
539542
{
540543
struct ceph_inode_info *ci = ceph_inode(inode);
544+
struct ceph_mds_client *mdsc = ceph_sb_to_mdsc(inode->i_sb);
541545
struct ceph_inode_frag *frag;
542546
struct rb_node *n;
543547

544548
dout("evict_inode %p ino %llx.%llx\n", inode, ceph_vinop(inode));
545549

550+
percpu_counter_dec(&mdsc->metric.total_inodes);
551+
546552
truncate_inode_pages_final(&inode->i_data);
547553
clear_inode(inode);
548554

@@ -558,7 +564,6 @@ void ceph_evict_inode(struct inode *inode)
558564
* caps in i_snap_caps.
559565
*/
560566
if (ci->i_snap_realm) {
561-
struct ceph_mds_client *mdsc = ceph_sb_to_mdsc(inode->i_sb);
562567
if (ceph_snap(inode) == CEPH_NOSNAP) {
563568
struct ceph_snap_realm *realm = ci->i_snap_realm;
564569
dout(" dropping residual ref to snap realm %p\n",

fs/ceph/metric.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,11 +192,23 @@ int ceph_metric_init(struct ceph_client_metric *m)
192192
m->total_metadatas = 0;
193193
m->metadata_latency_sum = 0;
194194

195+
atomic64_set(&m->opened_files, 0);
196+
ret = percpu_counter_init(&m->opened_inodes, 0, GFP_KERNEL);
197+
if (ret)
198+
goto err_opened_inodes;
199+
ret = percpu_counter_init(&m->total_inodes, 0, GFP_KERNEL);
200+
if (ret)
201+
goto err_total_inodes;
202+
195203
m->session = NULL;
196204
INIT_DELAYED_WORK(&m->delayed_work, metric_delayed_work);
197205

198206
return 0;
199207

208+
err_total_inodes:
209+
percpu_counter_destroy(&m->opened_inodes);
210+
err_opened_inodes:
211+
percpu_counter_destroy(&m->i_caps_mis);
200212
err_i_caps_mis:
201213
percpu_counter_destroy(&m->i_caps_hit);
202214
err_i_caps_hit:
@@ -212,6 +224,8 @@ void ceph_metric_destroy(struct ceph_client_metric *m)
212224
if (!m)
213225
return;
214226

227+
percpu_counter_destroy(&m->total_inodes);
228+
percpu_counter_destroy(&m->opened_inodes);
215229
percpu_counter_destroy(&m->i_caps_mis);
216230
percpu_counter_destroy(&m->i_caps_hit);
217231
percpu_counter_destroy(&m->d_lease_mis);

fs/ceph/metric.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,13 @@ struct ceph_client_metric {
115115
ktime_t metadata_latency_min;
116116
ktime_t metadata_latency_max;
117117

118+
/* The total number of directories and files that are opened */
119+
atomic64_t opened_files;
120+
121+
/* The total number of inodes that have opened files or directories */
122+
struct percpu_counter opened_inodes;
123+
struct percpu_counter total_inodes;
124+
118125
struct ceph_mds_session *session;
119126
struct delayed_work delayed_work; /* delayed work */
120127
};

0 commit comments

Comments
 (0)