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/ceph/mon_client.c | |
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/ceph/mon_client.c')
-rw-r--r-- | fs/ceph/mon_client.c | 67 |
1 files changed, 47 insertions, 20 deletions
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 | ||