diff options
author | Sage Weil <sage@newdream.net> | 2010-02-15 17:47:28 -0500 |
---|---|---|
committer | Sage Weil <sage@newdream.net> | 2010-02-17 01:01:10 -0500 |
commit | 85ff03f6bfef7d5b59ab3aefd4773f497ffad8a4 (patch) | |
tree | ef0a700d68f87b84ebb235c2ed7aae69c7414a8d /fs | |
parent | a105f00cf17d711e876b3dc67e15f9a89b7de5a3 (diff) |
ceph: use rbtree for mon statfs requests
An rbtree is lighter weight, particularly given we will generally have
very few in-flight statfs requests.
Signed-off-by: Sage Weil <sage@newdream.net>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/ceph/debugfs.c | 14 | ||||
-rw-r--r-- | fs/ceph/mon_client.c | 67 | ||||
-rw-r--r-- | fs/ceph/mon_client.h | 5 |
3 files changed, 54 insertions, 32 deletions
diff --git a/fs/ceph/debugfs.c b/fs/ceph/debugfs.c index cd5dd805e4be..b58bd9188692 100644 --- a/fs/ceph/debugfs.c +++ b/fs/ceph/debugfs.c | |||
@@ -112,9 +112,8 @@ static int monc_show(struct seq_file *s, void *p) | |||
112 | { | 112 | { |
113 | struct ceph_client *client = s->private; | 113 | struct ceph_client *client = s->private; |
114 | struct ceph_mon_statfs_request *req; | 114 | struct ceph_mon_statfs_request *req; |
115 | u64 nexttid = 0; | ||
116 | int got; | ||
117 | struct ceph_mon_client *monc = &client->monc; | 115 | struct ceph_mon_client *monc = &client->monc; |
116 | struct rb_node *rp; | ||
118 | 117 | ||
119 | mutex_lock(&monc->mutex); | 118 | mutex_lock(&monc->mutex); |
120 | 119 | ||
@@ -125,17 +124,12 @@ static int monc_show(struct seq_file *s, void *p) | |||
125 | if (monc->want_next_osdmap) | 124 | if (monc->want_next_osdmap) |
126 | seq_printf(s, "want next osdmap\n"); | 125 | seq_printf(s, "want next osdmap\n"); |
127 | 126 | ||
128 | while (nexttid < monc->last_tid) { | 127 | for (rp = rb_first(&monc->statfs_request_tree); rp; rp = rb_next(rp)) { |
129 | got = radix_tree_gang_lookup(&monc->statfs_request_tree, | 128 | req = rb_entry(rp, struct ceph_mon_statfs_request, node); |
130 | (void **)&req, nexttid, 1); | ||
131 | if (got == 0) | ||
132 | break; | ||
133 | nexttid = req->tid + 1; | ||
134 | |||
135 | seq_printf(s, "%lld statfs\n", req->tid); | 129 | seq_printf(s, "%lld statfs\n", req->tid); |
136 | } | 130 | } |
137 | mutex_unlock(&monc->mutex); | ||
138 | 131 | ||
132 | mutex_unlock(&monc->mutex); | ||
139 | return 0; | 133 | return 0; |
140 | } | 134 | } |
141 | 135 | ||
diff --git a/fs/ceph/mon_client.c b/fs/ceph/mon_client.c index fec41a0eff86..542276e60798 100644 --- a/fs/ceph/mon_client.c +++ b/fs/ceph/mon_client.c | |||
@@ -343,6 +343,46 @@ out: | |||
343 | /* | 343 | /* |
344 | * statfs | 344 | * statfs |
345 | */ | 345 | */ |
346 | static struct ceph_mon_statfs_request *__lookup_statfs( | ||
347 | struct ceph_mon_client *monc, u64 tid) | ||
348 | { | ||
349 | struct ceph_mon_statfs_request *req; | ||
350 | struct rb_node *n = monc->statfs_request_tree.rb_node; | ||
351 | |||
352 | while (n) { | ||
353 | req = rb_entry(n, struct ceph_mon_statfs_request, node); | ||
354 | if (tid < req->tid) | ||
355 | n = n->rb_left; | ||
356 | else if (tid > req->tid) | ||
357 | n = n->rb_right; | ||
358 | else | ||
359 | return req; | ||
360 | } | ||
361 | return NULL; | ||
362 | } | ||
363 | |||
364 | static void __insert_statfs(struct ceph_mon_client *monc, | ||
365 | struct ceph_mon_statfs_request *new) | ||
366 | { | ||
367 | struct rb_node **p = &monc->statfs_request_tree.rb_node; | ||
368 | struct rb_node *parent = NULL; | ||
369 | struct ceph_mon_statfs_request *req = NULL; | ||
370 | |||
371 | while (*p) { | ||
372 | parent = *p; | ||
373 | req = rb_entry(parent, struct ceph_mon_statfs_request, node); | ||
374 | if (new->tid < req->tid) | ||
375 | p = &(*p)->rb_left; | ||
376 | else if (new->tid > req->tid) | ||
377 | p = &(*p)->rb_right; | ||
378 | else | ||
379 | BUG(); | ||
380 | } | ||
381 | |||
382 | rb_link_node(&new->node, parent, p); | ||
383 | rb_insert_color(&new->node, &monc->statfs_request_tree); | ||
384 | } | ||
385 | |||
346 | static void handle_statfs_reply(struct ceph_mon_client *monc, | 386 | static void handle_statfs_reply(struct ceph_mon_client *monc, |
347 | struct ceph_msg *msg) | 387 | struct ceph_msg *msg) |
348 | { | 388 | { |
@@ -356,7 +396,7 @@ static void handle_statfs_reply(struct ceph_mon_client *monc, | |||
356 | dout("handle_statfs_reply %p tid %llu\n", msg, tid); | 396 | dout("handle_statfs_reply %p tid %llu\n", msg, tid); |
357 | 397 | ||
358 | mutex_lock(&monc->mutex); | 398 | mutex_lock(&monc->mutex); |
359 | req = radix_tree_lookup(&monc->statfs_request_tree, tid); | 399 | req = __lookup_statfs(monc, tid); |
360 | if (req) { | 400 | if (req) { |
361 | *req->buf = reply->st; | 401 | *req->buf = reply->st; |
362 | req->result = 0; | 402 | req->result = 0; |
@@ -416,11 +456,7 @@ int ceph_monc_do_statfs(struct ceph_mon_client *monc, struct ceph_statfs *buf) | |||
416 | req.tid = ++monc->last_tid; | 456 | req.tid = ++monc->last_tid; |
417 | req.last_attempt = jiffies; | 457 | req.last_attempt = jiffies; |
418 | req.delay = BASE_DELAY_INTERVAL; | 458 | req.delay = BASE_DELAY_INTERVAL; |
419 | if (radix_tree_insert(&monc->statfs_request_tree, req.tid, &req) < 0) { | 459 | __insert_statfs(monc, &req); |
420 | mutex_unlock(&monc->mutex); | ||
421 | pr_err("ENOMEM in do_statfs\n"); | ||
422 | return -ENOMEM; | ||
423 | } | ||
424 | monc->num_statfs_requests++; | 460 | monc->num_statfs_requests++; |
425 | mutex_unlock(&monc->mutex); | 461 | mutex_unlock(&monc->mutex); |
426 | 462 | ||
@@ -430,7 +466,7 @@ int ceph_monc_do_statfs(struct ceph_mon_client *monc, struct ceph_statfs *buf) | |||
430 | err = wait_for_completion_interruptible(&req.completion); | 466 | err = wait_for_completion_interruptible(&req.completion); |
431 | 467 | ||
432 | mutex_lock(&monc->mutex); | 468 | mutex_lock(&monc->mutex); |
433 | radix_tree_delete(&monc->statfs_request_tree, req.tid); | 469 | rb_erase(&req.node, &monc->statfs_request_tree); |
434 | monc->num_statfs_requests--; | 470 | monc->num_statfs_requests--; |
435 | ceph_msgpool_resv(&monc->msgpool_statfs_reply, -1); | 471 | ceph_msgpool_resv(&monc->msgpool_statfs_reply, -1); |
436 | mutex_unlock(&monc->mutex); | 472 | mutex_unlock(&monc->mutex); |
@@ -445,20 +481,11 @@ int ceph_monc_do_statfs(struct ceph_mon_client *monc, struct ceph_statfs *buf) | |||
445 | */ | 481 | */ |
446 | static void __resend_statfs(struct ceph_mon_client *monc) | 482 | static void __resend_statfs(struct ceph_mon_client *monc) |
447 | { | 483 | { |
448 | u64 next_tid = 0; | ||
449 | int got; | ||
450 | int did = 0; | ||
451 | struct ceph_mon_statfs_request *req; | 484 | struct ceph_mon_statfs_request *req; |
485 | struct rb_node *p; | ||
452 | 486 | ||
453 | while (1) { | 487 | for (p = rb_first(&monc->statfs_request_tree); p; p = rb_next(p)) { |
454 | got = radix_tree_gang_lookup(&monc->statfs_request_tree, | 488 | req = rb_entry(p, struct ceph_mon_statfs_request, node); |
455 | (void **)&req, | ||
456 | next_tid, 1); | ||
457 | if (got == 0) | ||
458 | break; | ||
459 | did++; | ||
460 | next_tid = req->tid + 1; | ||
461 | |||
462 | send_statfs(monc, req); | 489 | send_statfs(monc, req); |
463 | } | 490 | } |
464 | } | 491 | } |
@@ -578,7 +605,7 @@ int ceph_monc_init(struct ceph_mon_client *monc, struct ceph_client *cl) | |||
578 | monc->sub_sent = 0; | 605 | monc->sub_sent = 0; |
579 | 606 | ||
580 | INIT_DELAYED_WORK(&monc->delayed_work, delayed_work); | 607 | INIT_DELAYED_WORK(&monc->delayed_work, delayed_work); |
581 | INIT_RADIX_TREE(&monc->statfs_request_tree, GFP_NOFS); | 608 | monc->statfs_request_tree = RB_ROOT; |
582 | monc->num_statfs_requests = 0; | 609 | monc->num_statfs_requests = 0; |
583 | monc->last_tid = 0; | 610 | monc->last_tid = 0; |
584 | 611 | ||
diff --git a/fs/ceph/mon_client.h b/fs/ceph/mon_client.h index 5ca8e48d4379..b958ad5afa06 100644 --- a/fs/ceph/mon_client.h +++ b/fs/ceph/mon_client.h | |||
@@ -2,7 +2,7 @@ | |||
2 | #define _FS_CEPH_MON_CLIENT_H | 2 | #define _FS_CEPH_MON_CLIENT_H |
3 | 3 | ||
4 | #include <linux/completion.h> | 4 | #include <linux/completion.h> |
5 | #include <linux/radix-tree.h> | 5 | #include <linux/rbtree.h> |
6 | 6 | ||
7 | #include "messenger.h" | 7 | #include "messenger.h" |
8 | #include "msgpool.h" | 8 | #include "msgpool.h" |
@@ -45,6 +45,7 @@ struct ceph_mon_request { | |||
45 | */ | 45 | */ |
46 | struct ceph_mon_statfs_request { | 46 | struct ceph_mon_statfs_request { |
47 | u64 tid; | 47 | u64 tid; |
48 | struct rb_node node; | ||
48 | int result; | 49 | int result; |
49 | struct ceph_statfs *buf; | 50 | struct ceph_statfs *buf; |
50 | struct completion completion; | 51 | struct completion completion; |
@@ -75,7 +76,7 @@ struct ceph_mon_client { | |||
75 | struct ceph_msgpool msgpool_auth_reply; | 76 | struct ceph_msgpool msgpool_auth_reply; |
76 | 77 | ||
77 | /* pending statfs requests */ | 78 | /* pending statfs requests */ |
78 | struct radix_tree_root statfs_request_tree; | 79 | struct rb_root statfs_request_tree; |
79 | int num_statfs_requests; | 80 | int num_statfs_requests; |
80 | u64 last_tid; | 81 | u64 last_tid; |
81 | 82 | ||