diff options
author | Sage Weil <sage@newdream.net> | 2010-02-15 17:37:55 -0500 |
---|---|---|
committer | Sage Weil <sage@newdream.net> | 2010-02-17 01:01:09 -0500 |
commit | a105f00cf17d711e876b3dc67e15f9a89b7de5a3 (patch) | |
tree | 59c4b280aa92e9910670ee7fd274f21bc3659a04 | |
parent | 44ca18f2682eb1cfbed153849adedb79e3e19790 (diff) |
ceph: use rbtree for snap_realms
Switch from radix tree to rbtree for snap realms. This is much more
appropriate given that realm keys are few and far between.
Signed-off-by: Sage Weil <sage@newdream.net>
-rw-r--r-- | fs/ceph/mds_client.c | 16 | ||||
-rw-r--r-- | fs/ceph/mds_client.h | 3 | ||||
-rw-r--r-- | fs/ceph/snap.c | 51 | ||||
-rw-r--r-- | fs/ceph/super.h | 2 |
4 files changed, 48 insertions, 24 deletions
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index 81840d6b68a4..02834cecc3a0 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c | |||
@@ -2097,9 +2097,8 @@ static void send_mds_reconnect(struct ceph_mds_client *mdsc, int mds) | |||
2097 | { | 2097 | { |
2098 | struct ceph_mds_session *session = NULL; | 2098 | struct ceph_mds_session *session = NULL; |
2099 | struct ceph_msg *reply; | 2099 | struct ceph_msg *reply; |
2100 | struct rb_node *p; | ||
2100 | int err; | 2101 | int err; |
2101 | int got; | ||
2102 | u64 next_snap_ino = 0; | ||
2103 | struct ceph_pagelist *pagelist; | 2102 | struct ceph_pagelist *pagelist; |
2104 | 2103 | ||
2105 | pr_info("reconnect to recovering mds%d\n", mds); | 2104 | pr_info("reconnect to recovering mds%d\n", mds); |
@@ -2155,14 +2154,10 @@ static void send_mds_reconnect(struct ceph_mds_client *mdsc, int mds) | |||
2155 | * parent for all of our realms. If the mds has any newer info, | 2154 | * parent for all of our realms. If the mds has any newer info, |
2156 | * it will tell us. | 2155 | * it will tell us. |
2157 | */ | 2156 | */ |
2158 | next_snap_ino = 0; | 2157 | for (p = rb_first(&mdsc->snap_realms); p; p = rb_next(p)) { |
2159 | while (1) { | 2158 | struct ceph_snap_realm *realm = |
2160 | struct ceph_snap_realm *realm; | 2159 | rb_entry(p, struct ceph_snap_realm, node); |
2161 | struct ceph_mds_snaprealm_reconnect sr_rec; | 2160 | struct ceph_mds_snaprealm_reconnect sr_rec; |
2162 | got = radix_tree_gang_lookup(&mdsc->snap_realms, | ||
2163 | (void **)&realm, next_snap_ino, 1); | ||
2164 | if (!got) | ||
2165 | break; | ||
2166 | 2161 | ||
2167 | dout(" adding snap realm %llx seq %lld parent %llx\n", | 2162 | dout(" adding snap realm %llx seq %lld parent %llx\n", |
2168 | realm->ino, realm->seq, realm->parent_ino); | 2163 | realm->ino, realm->seq, realm->parent_ino); |
@@ -2172,7 +2167,6 @@ static void send_mds_reconnect(struct ceph_mds_client *mdsc, int mds) | |||
2172 | err = ceph_pagelist_append(pagelist, &sr_rec, sizeof(sr_rec)); | 2167 | err = ceph_pagelist_append(pagelist, &sr_rec, sizeof(sr_rec)); |
2173 | if (err) | 2168 | if (err) |
2174 | goto fail; | 2169 | goto fail; |
2175 | next_snap_ino = realm->ino + 1; | ||
2176 | } | 2170 | } |
2177 | 2171 | ||
2178 | send: | 2172 | send: |
@@ -2603,7 +2597,7 @@ int ceph_mdsc_init(struct ceph_mds_client *mdsc, struct ceph_client *client) | |||
2603 | mdsc->max_sessions = 0; | 2597 | mdsc->max_sessions = 0; |
2604 | mdsc->stopping = 0; | 2598 | mdsc->stopping = 0; |
2605 | init_rwsem(&mdsc->snap_rwsem); | 2599 | init_rwsem(&mdsc->snap_rwsem); |
2606 | INIT_RADIX_TREE(&mdsc->snap_realms, GFP_NOFS); | 2600 | mdsc->snap_realms = RB_ROOT; |
2607 | INIT_LIST_HEAD(&mdsc->snap_empty); | 2601 | INIT_LIST_HEAD(&mdsc->snap_empty); |
2608 | spin_lock_init(&mdsc->snap_empty_lock); | 2602 | spin_lock_init(&mdsc->snap_empty_lock); |
2609 | mdsc->last_tid = 0; | 2603 | mdsc->last_tid = 0; |
diff --git a/fs/ceph/mds_client.h b/fs/ceph/mds_client.h index 98f09cd06006..9d6b90173879 100644 --- a/fs/ceph/mds_client.h +++ b/fs/ceph/mds_client.h | |||
@@ -5,7 +5,6 @@ | |||
5 | #include <linux/kref.h> | 5 | #include <linux/kref.h> |
6 | #include <linux/list.h> | 6 | #include <linux/list.h> |
7 | #include <linux/mutex.h> | 7 | #include <linux/mutex.h> |
8 | #include <linux/radix-tree.h> | ||
9 | #include <linux/rbtree.h> | 8 | #include <linux/rbtree.h> |
10 | #include <linux/spinlock.h> | 9 | #include <linux/spinlock.h> |
11 | 10 | ||
@@ -246,7 +245,7 @@ struct ceph_mds_client { | |||
246 | * should be destroyed. | 245 | * should be destroyed. |
247 | */ | 246 | */ |
248 | struct rw_semaphore snap_rwsem; | 247 | struct rw_semaphore snap_rwsem; |
249 | struct radix_tree_root snap_realms; | 248 | struct rb_root snap_realms; |
250 | struct list_head snap_empty; | 249 | struct list_head snap_empty; |
251 | spinlock_t snap_empty_lock; /* protect snap_empty */ | 250 | spinlock_t snap_empty_lock; /* protect snap_empty */ |
252 | 251 | ||
diff --git a/fs/ceph/snap.c b/fs/ceph/snap.c index dcf18d92130a..49d0c4c59d81 100644 --- a/fs/ceph/snap.c +++ b/fs/ceph/snap.c | |||
@@ -1,6 +1,5 @@ | |||
1 | #include "ceph_debug.h" | 1 | #include "ceph_debug.h" |
2 | 2 | ||
3 | #include <linux/radix-tree.h> | ||
4 | #include <linux/sort.h> | 3 | #include <linux/sort.h> |
5 | 4 | ||
6 | #include "super.h" | 5 | #include "super.h" |
@@ -77,6 +76,28 @@ void ceph_get_snap_realm(struct ceph_mds_client *mdsc, | |||
77 | atomic_inc(&realm->nref); | 76 | atomic_inc(&realm->nref); |
78 | } | 77 | } |
79 | 78 | ||
79 | static void __insert_snap_realm(struct rb_root *root, | ||
80 | struct ceph_snap_realm *new) | ||
81 | { | ||
82 | struct rb_node **p = &root->rb_node; | ||
83 | struct rb_node *parent = NULL; | ||
84 | struct ceph_snap_realm *r = NULL; | ||
85 | |||
86 | while (*p) { | ||
87 | parent = *p; | ||
88 | r = rb_entry(parent, struct ceph_snap_realm, node); | ||
89 | if (new->ino < r->ino) | ||
90 | p = &(*p)->rb_left; | ||
91 | else if (new->ino > r->ino) | ||
92 | p = &(*p)->rb_right; | ||
93 | else | ||
94 | BUG(); | ||
95 | } | ||
96 | |||
97 | rb_link_node(&new->node, parent, p); | ||
98 | rb_insert_color(&new->node, root); | ||
99 | } | ||
100 | |||
80 | /* | 101 | /* |
81 | * create and get the realm rooted at @ino and bump its ref count. | 102 | * create and get the realm rooted at @ino and bump its ref count. |
82 | * | 103 | * |
@@ -92,8 +113,6 @@ static struct ceph_snap_realm *ceph_create_snap_realm( | |||
92 | if (!realm) | 113 | if (!realm) |
93 | return ERR_PTR(-ENOMEM); | 114 | return ERR_PTR(-ENOMEM); |
94 | 115 | ||
95 | radix_tree_insert(&mdsc->snap_realms, ino, realm); | ||
96 | |||
97 | atomic_set(&realm->nref, 0); /* tree does not take a ref */ | 116 | atomic_set(&realm->nref, 0); /* tree does not take a ref */ |
98 | realm->ino = ino; | 117 | realm->ino = ino; |
99 | INIT_LIST_HEAD(&realm->children); | 118 | INIT_LIST_HEAD(&realm->children); |
@@ -101,24 +120,34 @@ static struct ceph_snap_realm *ceph_create_snap_realm( | |||
101 | INIT_LIST_HEAD(&realm->empty_item); | 120 | INIT_LIST_HEAD(&realm->empty_item); |
102 | INIT_LIST_HEAD(&realm->inodes_with_caps); | 121 | INIT_LIST_HEAD(&realm->inodes_with_caps); |
103 | spin_lock_init(&realm->inodes_with_caps_lock); | 122 | spin_lock_init(&realm->inodes_with_caps_lock); |
123 | __insert_snap_realm(&mdsc->snap_realms, realm); | ||
104 | dout("create_snap_realm %llx %p\n", realm->ino, realm); | 124 | dout("create_snap_realm %llx %p\n", realm->ino, realm); |
105 | return realm; | 125 | return realm; |
106 | } | 126 | } |
107 | 127 | ||
108 | /* | 128 | /* |
109 | * find and get (if found) the realm rooted at @ino and bump its ref count. | 129 | * lookup the realm rooted at @ino. |
110 | * | 130 | * |
111 | * caller must hold snap_rwsem for write. | 131 | * caller must hold snap_rwsem for write. |
112 | */ | 132 | */ |
113 | struct ceph_snap_realm *ceph_lookup_snap_realm(struct ceph_mds_client *mdsc, | 133 | struct ceph_snap_realm *ceph_lookup_snap_realm(struct ceph_mds_client *mdsc, |
114 | u64 ino) | 134 | u64 ino) |
115 | { | 135 | { |
116 | struct ceph_snap_realm *realm; | 136 | struct rb_node *n = mdsc->snap_realms.rb_node; |
117 | 137 | struct ceph_snap_realm *r; | |
118 | realm = radix_tree_lookup(&mdsc->snap_realms, ino); | 138 | |
119 | if (realm) | 139 | while (n) { |
120 | dout("lookup_snap_realm %llx %p\n", realm->ino, realm); | 140 | r = rb_entry(n, struct ceph_snap_realm, node); |
121 | return realm; | 141 | if (ino < r->ino) |
142 | n = n->rb_left; | ||
143 | else if (ino > r->ino) | ||
144 | n = n->rb_right; | ||
145 | else { | ||
146 | dout("lookup_snap_realm %llx %p\n", r->ino, r); | ||
147 | return r; | ||
148 | } | ||
149 | } | ||
150 | return NULL; | ||
122 | } | 151 | } |
123 | 152 | ||
124 | static void __put_snap_realm(struct ceph_mds_client *mdsc, | 153 | static void __put_snap_realm(struct ceph_mds_client *mdsc, |
@@ -132,7 +161,7 @@ static void __destroy_snap_realm(struct ceph_mds_client *mdsc, | |||
132 | { | 161 | { |
133 | dout("__destroy_snap_realm %p %llx\n", realm, realm->ino); | 162 | dout("__destroy_snap_realm %p %llx\n", realm, realm->ino); |
134 | 163 | ||
135 | radix_tree_delete(&mdsc->snap_realms, realm->ino); | 164 | rb_erase(&realm->node, &mdsc->snap_realms); |
136 | 165 | ||
137 | if (realm->parent) { | 166 | if (realm->parent) { |
138 | list_del_init(&realm->child_item); | 167 | list_del_init(&realm->child_item); |
diff --git a/fs/ceph/super.h b/fs/ceph/super.h index b2adfccbab98..1f3928785e12 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h | |||
@@ -656,6 +656,8 @@ static inline void ceph_put_snap_context(struct ceph_snap_context *sc) | |||
656 | struct ceph_snap_realm { | 656 | struct ceph_snap_realm { |
657 | u64 ino; | 657 | u64 ino; |
658 | atomic_t nref; | 658 | atomic_t nref; |
659 | struct rb_node node; | ||
660 | |||
659 | u64 created, seq; | 661 | u64 created, seq; |
660 | u64 parent_ino; | 662 | u64 parent_ino; |
661 | u64 parent_since; /* snapid when our current parent became so */ | 663 | u64 parent_since; /* snapid when our current parent became so */ |