Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

libceph: DEFINE_RB_FUNCS macro

Given

struct foo {
u64 id;
struct rb_node bar_node;
};

generate insert_bar(), erase_bar() and lookup_bar() functions with

DEFINE_RB_FUNCS(bar, struct foo, id, bar_node)

The key is assumed to be an integer (u64, int, etc), compared with
< and >. nodefld has to be initialized with RB_CLEAR_NODE().

Start using it for MDS, MON and OSD requests and OSD sessions.

Signed-off-by: Ilya Dryomov <idryomov@gmail.com>

+88 -172
+13 -41
fs/ceph/mds_client.c
··· 567 567 kfree(req); 568 568 } 569 569 570 + DEFINE_RB_FUNCS(request, struct ceph_mds_request, r_tid, r_node) 571 + 570 572 /* 571 573 * lookup session, bump ref if found. 572 574 * 573 575 * called under mdsc->mutex. 574 576 */ 575 - static struct ceph_mds_request *__lookup_request(struct ceph_mds_client *mdsc, 576 - u64 tid) 577 + static struct ceph_mds_request * 578 + lookup_get_request(struct ceph_mds_client *mdsc, u64 tid) 577 579 { 578 580 struct ceph_mds_request *req; 579 - struct rb_node *n = mdsc->request_tree.rb_node; 580 581 581 - while (n) { 582 - req = rb_entry(n, struct ceph_mds_request, r_node); 583 - if (tid < req->r_tid) 584 - n = n->rb_left; 585 - else if (tid > req->r_tid) 586 - n = n->rb_right; 587 - else { 588 - ceph_mdsc_get_request(req); 589 - return req; 590 - } 591 - } 592 - return NULL; 593 - } 582 + req = lookup_request(&mdsc->request_tree, tid); 583 + if (req) 584 + ceph_mdsc_get_request(req); 594 585 595 - static void __insert_request(struct ceph_mds_client *mdsc, 596 - struct ceph_mds_request *new) 597 - { 598 - struct rb_node **p = &mdsc->request_tree.rb_node; 599 - struct rb_node *parent = NULL; 600 - struct ceph_mds_request *req = NULL; 601 - 602 - while (*p) { 603 - parent = *p; 604 - req = rb_entry(parent, struct ceph_mds_request, r_node); 605 - if (new->r_tid < req->r_tid) 606 - p = &(*p)->rb_left; 607 - else if (new->r_tid > req->r_tid) 608 - p = &(*p)->rb_right; 609 - else 610 - BUG(); 611 - } 612 - 613 - rb_link_node(&new->r_node, parent, p); 614 - rb_insert_color(&new->r_node, &mdsc->request_tree); 586 + return req; 615 587 } 616 588 617 589 /* ··· 602 630 req->r_num_caps); 603 631 dout("__register_request %p tid %lld\n", req, req->r_tid); 604 632 ceph_mdsc_get_request(req); 605 - __insert_request(mdsc, req); 633 + insert_request(&mdsc->request_tree, req); 606 634 607 635 req->r_uid = current_fsuid(); 608 636 req->r_gid = current_fsgid(); ··· 635 663 } 636 664 } 637 665 638 - rb_erase(&req->r_node, &mdsc->request_tree); 639 - RB_CLEAR_NODE(&req->r_node); 666 + erase_request(&mdsc->request_tree, req); 640 667 641 668 if (req->r_unsafe_dir && req->r_got_unsafe) { 642 669 struct ceph_inode_info *ci = ceph_inode(req->r_unsafe_dir); ··· 1693 1722 INIT_LIST_HEAD(&req->r_unsafe_target_item); 1694 1723 req->r_fmode = -1; 1695 1724 kref_init(&req->r_kref); 1725 + RB_CLEAR_NODE(&req->r_node); 1696 1726 INIT_LIST_HEAD(&req->r_wait); 1697 1727 init_completion(&req->r_completion); 1698 1728 init_completion(&req->r_safe_completion); ··· 2386 2414 /* get request, session */ 2387 2415 tid = le64_to_cpu(msg->hdr.tid); 2388 2416 mutex_lock(&mdsc->mutex); 2389 - req = __lookup_request(mdsc, tid); 2417 + req = lookup_get_request(mdsc, tid); 2390 2418 if (!req) { 2391 2419 dout("handle_reply on unknown tid %llu\n", tid); 2392 2420 mutex_unlock(&mdsc->mutex); ··· 2576 2604 fwd_seq = ceph_decode_32(&p); 2577 2605 2578 2606 mutex_lock(&mdsc->mutex); 2579 - req = __lookup_request(mdsc, tid); 2607 + req = lookup_get_request(mdsc, tid); 2580 2608 if (!req) { 2581 2609 dout("forward tid %llu to mds%d - req dne\n", tid, next_mds); 2582 2610 goto out; /* dup reply? */
+57
include/linux/ceph/libceph.h
··· 180 180 (off >> PAGE_SHIFT); 181 181 } 182 182 183 + /* 184 + * These are not meant to be generic - an integer key is assumed. 185 + */ 186 + #define DEFINE_RB_INSDEL_FUNCS(name, type, keyfld, nodefld) \ 187 + static void insert_##name(struct rb_root *root, type *t) \ 188 + { \ 189 + struct rb_node **n = &root->rb_node; \ 190 + struct rb_node *parent = NULL; \ 191 + \ 192 + BUG_ON(!RB_EMPTY_NODE(&t->nodefld)); \ 193 + \ 194 + while (*n) { \ 195 + type *cur = rb_entry(*n, type, nodefld); \ 196 + \ 197 + parent = *n; \ 198 + if (t->keyfld < cur->keyfld) \ 199 + n = &(*n)->rb_left; \ 200 + else if (t->keyfld > cur->keyfld) \ 201 + n = &(*n)->rb_right; \ 202 + else \ 203 + BUG(); \ 204 + } \ 205 + \ 206 + rb_link_node(&t->nodefld, parent, n); \ 207 + rb_insert_color(&t->nodefld, root); \ 208 + } \ 209 + static void erase_##name(struct rb_root *root, type *t) \ 210 + { \ 211 + BUG_ON(RB_EMPTY_NODE(&t->nodefld)); \ 212 + rb_erase(&t->nodefld, root); \ 213 + RB_CLEAR_NODE(&t->nodefld); \ 214 + } 215 + 216 + #define DEFINE_RB_LOOKUP_FUNC(name, type, keyfld, nodefld) \ 217 + static type *lookup_##name(struct rb_root *root, \ 218 + typeof(((type *)0)->keyfld) key) \ 219 + { \ 220 + struct rb_node *n = root->rb_node; \ 221 + \ 222 + while (n) { \ 223 + type *cur = rb_entry(n, type, nodefld); \ 224 + \ 225 + if (key < cur->keyfld) \ 226 + n = n->rb_left; \ 227 + else if (key > cur->keyfld) \ 228 + n = n->rb_right; \ 229 + else \ 230 + return cur; \ 231 + } \ 232 + \ 233 + return NULL; \ 234 + } 235 + 236 + #define DEFINE_RB_FUNCS(name, type, keyfld, nodefld) \ 237 + DEFINE_RB_INSDEL_FUNCS(name, type, keyfld, nodefld) \ 238 + DEFINE_RB_LOOKUP_FUNC(name, type, keyfld, nodefld) 239 + 183 240 extern struct kmem_cache *ceph_inode_cachep; 184 241 extern struct kmem_cache *ceph_cap_cachep; 185 242 extern struct kmem_cache *ceph_cap_flush_cachep;
+8 -44
net/ceph/mon_client.c
··· 478 478 /* 479 479 * generic requests (currently statfs, mon_get_version) 480 480 */ 481 - static struct ceph_mon_generic_request *__lookup_generic_req( 482 - struct ceph_mon_client *monc, u64 tid) 483 - { 484 - struct ceph_mon_generic_request *req; 485 - struct rb_node *n = monc->generic_request_tree.rb_node; 486 - 487 - while (n) { 488 - req = rb_entry(n, struct ceph_mon_generic_request, node); 489 - if (tid < req->tid) 490 - n = n->rb_left; 491 - else if (tid > req->tid) 492 - n = n->rb_right; 493 - else 494 - return req; 495 - } 496 - return NULL; 497 - } 498 - 499 - static void __insert_generic_request(struct ceph_mon_client *monc, 500 - struct ceph_mon_generic_request *new) 501 - { 502 - struct rb_node **p = &monc->generic_request_tree.rb_node; 503 - struct rb_node *parent = NULL; 504 - struct ceph_mon_generic_request *req = NULL; 505 - 506 - while (*p) { 507 - parent = *p; 508 - req = rb_entry(parent, struct ceph_mon_generic_request, node); 509 - if (new->tid < req->tid) 510 - p = &(*p)->rb_left; 511 - else if (new->tid > req->tid) 512 - p = &(*p)->rb_right; 513 - else 514 - BUG(); 515 - } 516 - 517 - rb_link_node(&new->node, parent, p); 518 - rb_insert_color(&new->node, &monc->generic_request_tree); 519 - } 481 + DEFINE_RB_FUNCS(generic_request, struct ceph_mon_generic_request, tid, node) 520 482 521 483 static void release_generic_request(struct kref *kref) 522 484 { ··· 513 551 struct ceph_msg *m; 514 552 515 553 mutex_lock(&monc->mutex); 516 - req = __lookup_generic_req(monc, tid); 554 + req = lookup_generic_request(&monc->generic_request_tree, tid); 517 555 if (!req) { 518 556 dout("get_generic_reply %lld dne\n", tid); 519 557 *skip = 1; ··· 540 578 /* register request */ 541 579 req->tid = tid != 0 ? tid : ++monc->last_tid; 542 580 req->request->hdr.tid = cpu_to_le64(req->tid); 543 - __insert_generic_request(monc, req); 581 + insert_generic_request(&monc->generic_request_tree, req); 544 582 ceph_con_send(&monc->con, ceph_msg_get(req->request)); 545 583 mutex_unlock(&monc->mutex); 546 584 547 585 err = wait_for_completion_interruptible(&req->completion); 548 586 549 587 mutex_lock(&monc->mutex); 550 - rb_erase(&req->node, &monc->generic_request_tree); 588 + erase_generic_request(&monc->generic_request_tree, req); 551 589 552 590 if (!err) 553 591 err = req->result; ··· 581 619 dout("handle_statfs_reply %p tid %llu\n", msg, tid); 582 620 583 621 mutex_lock(&monc->mutex); 584 - req = __lookup_generic_req(monc, tid); 622 + req = lookup_generic_request(&monc->generic_request_tree, tid); 585 623 if (req) { 586 624 *(struct ceph_statfs *)req->buf = reply->st; 587 625 req->result = 0; ··· 613 651 return -ENOMEM; 614 652 615 653 kref_init(&req->kref); 654 + RB_CLEAR_NODE(&req->node); 616 655 req->buf = buf; 617 656 init_completion(&req->completion); 618 657 ··· 659 696 goto bad; 660 697 661 698 mutex_lock(&monc->mutex); 662 - req = __lookup_generic_req(monc, handle); 699 + req = lookup_generic_request(&monc->generic_request_tree, handle); 663 700 if (req) { 664 701 *(u64 *)req->buf = ceph_decode_64(&p); 665 702 req->result = 0; ··· 695 732 return -ENOMEM; 696 733 697 734 kref_init(&req->kref); 735 + RB_CLEAR_NODE(&req->node); 698 736 req->buf = newest; 699 737 init_completion(&req->completion); 700 738
+10 -87
net/ceph/osd_client.c
··· 875 875 /* 876 876 * We keep osd requests in an rbtree, sorted by ->r_tid. 877 877 */ 878 - static void __insert_request(struct ceph_osd_client *osdc, 879 - struct ceph_osd_request *new) 880 - { 881 - struct rb_node **p = &osdc->requests.rb_node; 882 - struct rb_node *parent = NULL; 883 - struct ceph_osd_request *req = NULL; 884 - 885 - while (*p) { 886 - parent = *p; 887 - req = rb_entry(parent, struct ceph_osd_request, r_node); 888 - if (new->r_tid < req->r_tid) 889 - p = &(*p)->rb_left; 890 - else if (new->r_tid > req->r_tid) 891 - p = &(*p)->rb_right; 892 - else 893 - BUG(); 894 - } 895 - 896 - rb_link_node(&new->r_node, parent, p); 897 - rb_insert_color(&new->r_node, &osdc->requests); 898 - } 899 - 900 - static struct ceph_osd_request *__lookup_request(struct ceph_osd_client *osdc, 901 - u64 tid) 902 - { 903 - struct ceph_osd_request *req; 904 - struct rb_node *n = osdc->requests.rb_node; 905 - 906 - while (n) { 907 - req = rb_entry(n, struct ceph_osd_request, r_node); 908 - if (tid < req->r_tid) 909 - n = n->rb_left; 910 - else if (tid > req->r_tid) 911 - n = n->rb_right; 912 - else 913 - return req; 914 - } 915 - return NULL; 916 - } 878 + DEFINE_RB_FUNCS(request, struct ceph_osd_request, r_tid, r_node) 917 879 918 880 static struct ceph_osd_request * 919 881 __lookup_request_ge(struct ceph_osd_client *osdc, ··· 1063 1101 } 1064 1102 } 1065 1103 1104 + DEFINE_RB_FUNCS(osd, struct ceph_osd, o_osd, o_node) 1105 + 1066 1106 /* 1067 1107 * remove an osd from our map 1068 1108 */ ··· 1075 1111 WARN_ON(!list_empty(&osd->o_linger_requests)); 1076 1112 1077 1113 list_del_init(&osd->o_osd_lru); 1078 - rb_erase(&osd->o_node, &osdc->osds); 1079 - RB_CLEAR_NODE(&osd->o_node); 1114 + erase_osd(&osdc->osds, osd); 1080 1115 } 1081 1116 1082 1117 static void remove_osd(struct ceph_osd_client *osdc, struct ceph_osd *osd) ··· 1151 1188 return 0; 1152 1189 } 1153 1190 1154 - static void __insert_osd(struct ceph_osd_client *osdc, struct ceph_osd *new) 1155 - { 1156 - struct rb_node **p = &osdc->osds.rb_node; 1157 - struct rb_node *parent = NULL; 1158 - struct ceph_osd *osd = NULL; 1159 - 1160 - dout("__insert_osd %p osd%d\n", new, new->o_osd); 1161 - while (*p) { 1162 - parent = *p; 1163 - osd = rb_entry(parent, struct ceph_osd, o_node); 1164 - if (new->o_osd < osd->o_osd) 1165 - p = &(*p)->rb_left; 1166 - else if (new->o_osd > osd->o_osd) 1167 - p = &(*p)->rb_right; 1168 - else 1169 - BUG(); 1170 - } 1171 - 1172 - rb_link_node(&new->o_node, parent, p); 1173 - rb_insert_color(&new->o_node, &osdc->osds); 1174 - } 1175 - 1176 - static struct ceph_osd *__lookup_osd(struct ceph_osd_client *osdc, int o) 1177 - { 1178 - struct ceph_osd *osd; 1179 - struct rb_node *n = osdc->osds.rb_node; 1180 - 1181 - while (n) { 1182 - osd = rb_entry(n, struct ceph_osd, o_node); 1183 - if (o < osd->o_osd) 1184 - n = n->rb_left; 1185 - else if (o > osd->o_osd) 1186 - n = n->rb_right; 1187 - else 1188 - return osd; 1189 - } 1190 - return NULL; 1191 - } 1192 - 1193 1191 static void __schedule_osd_timeout(struct ceph_osd_client *osdc) 1194 1192 { 1195 1193 schedule_delayed_work(&osdc->timeout_work, ··· 1172 1248 req->r_tid = ++osdc->last_tid; 1173 1249 req->r_request->hdr.tid = cpu_to_le64(req->r_tid); 1174 1250 dout("__register_request %p tid %lld\n", req, req->r_tid); 1175 - __insert_request(osdc, req); 1251 + insert_request(&osdc->requests, req); 1176 1252 ceph_osdc_get_request(req); 1177 1253 osdc->num_requests++; 1178 1254 if (osdc->num_requests == 1) { ··· 1194 1270 } 1195 1271 1196 1272 dout("__unregister_request %p tid %lld\n", req, req->r_tid); 1197 - rb_erase(&req->r_node, &osdc->requests); 1198 - RB_CLEAR_NODE(&req->r_node); 1273 + erase_request(&osdc->requests, req); 1199 1274 osdc->num_requests--; 1200 1275 1201 1276 if (req->r_osd) { ··· 1405 1482 req->r_osd = NULL; 1406 1483 } 1407 1484 1408 - req->r_osd = __lookup_osd(osdc, o); 1485 + req->r_osd = lookup_osd(&osdc->osds, o); 1409 1486 if (!req->r_osd && o >= 0) { 1410 1487 err = -ENOMEM; 1411 1488 req->r_osd = create_osd(osdc, o); ··· 1415 1492 } 1416 1493 1417 1494 dout("map_request osd %p is osd%d\n", req->r_osd, o); 1418 - __insert_osd(osdc, req->r_osd); 1495 + insert_osd(&osdc->osds, req->r_osd); 1419 1496 1420 1497 ceph_con_open(&req->r_osd->o_con, 1421 1498 CEPH_ENTITY_TYPE_OSD, o, ··· 1745 1822 /* lookup */ 1746 1823 down_read(&osdc->map_sem); 1747 1824 mutex_lock(&osdc->request_mutex); 1748 - req = __lookup_request(osdc, tid); 1825 + req = lookup_request(&osdc->requests, tid); 1749 1826 if (req == NULL) { 1750 1827 dout("handle_reply tid %llu dne\n", tid); 1751 1828 goto bad_mutex; ··· 2803 2880 2804 2881 tid = le64_to_cpu(hdr->tid); 2805 2882 mutex_lock(&osdc->request_mutex); 2806 - req = __lookup_request(osdc, tid); 2883 + req = lookup_request(&osdc->requests, tid); 2807 2884 if (!req) { 2808 2885 dout("%s osd%d tid %llu unknown, skipping\n", __func__, 2809 2886 osd->o_osd, tid);