aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/extent_io.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2008-02-01 14:51:59 -0500
committerChris Mason <chris.mason@oracle.com>2008-09-25 11:04:00 -0400
commit80ea96b1f3bd2431e0d71c9df6ab45c3de0c5840 (patch)
tree5071d30eba0f51c529a99bd16caa96dfe3c50cee /fs/btrfs/extent_io.c
parent4529ba495c6fd0d79247784d0df55ae6512fa883 (diff)
Btrfs: Add a lookup cache to the extent state tree
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/extent_io.c')
-rw-r--r--fs/btrfs/extent_io.c57
1 files changed, 40 insertions, 17 deletions
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index 624aabc3e6f2..5f2fbf2054f2 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -90,6 +90,7 @@ void extent_io_tree_init(struct extent_io_tree *tree,
90 tree->mapping = mapping; 90 tree->mapping = mapping;
91 INIT_LIST_HEAD(&tree->buffer_lru); 91 INIT_LIST_HEAD(&tree->buffer_lru);
92 tree->lru_size = 0; 92 tree->lru_size = 0;
93 tree->last = NULL;
93} 94}
94EXPORT_SYMBOL(extent_io_tree_init); 95EXPORT_SYMBOL(extent_io_tree_init);
95 96
@@ -158,16 +159,23 @@ static struct rb_node *tree_insert(struct rb_root *root, u64 offset,
158 return NULL; 159 return NULL;
159} 160}
160 161
161static struct rb_node *__tree_search(struct rb_root *root, u64 offset, 162static struct rb_node *__etree_search(struct extent_io_tree *tree, u64 offset,
162 struct rb_node **prev_ret, 163 struct rb_node **prev_ret,
163 struct rb_node **next_ret) 164 struct rb_node **next_ret)
164{ 165{
166 struct rb_root *root = &tree->state;
165 struct rb_node * n = root->rb_node; 167 struct rb_node * n = root->rb_node;
166 struct rb_node *prev = NULL; 168 struct rb_node *prev = NULL;
167 struct rb_node *orig_prev = NULL; 169 struct rb_node *orig_prev = NULL;
168 struct tree_entry *entry; 170 struct tree_entry *entry;
169 struct tree_entry *prev_entry = NULL; 171 struct tree_entry *prev_entry = NULL;
170 172
173 if (tree->last) {
174 struct extent_state *state;
175 state = tree->last;
176 if (state->start <= offset && offset <= state->end)
177 return &tree->last->rb_node;
178 }
171 while(n) { 179 while(n) {
172 entry = rb_entry(n, struct tree_entry, rb_node); 180 entry = rb_entry(n, struct tree_entry, rb_node);
173 prev = n; 181 prev = n;
@@ -177,8 +185,10 @@ static struct rb_node *__tree_search(struct rb_root *root, u64 offset,
177 n = n->rb_left; 185 n = n->rb_left;
178 else if (offset > entry->end) 186 else if (offset > entry->end)
179 n = n->rb_right; 187 n = n->rb_right;
180 else 188 else {
189 tree->last = rb_entry(n, struct extent_state, rb_node);
181 return n; 190 return n;
191 }
182 } 192 }
183 193
184 if (prev_ret) { 194 if (prev_ret) {
@@ -202,14 +212,20 @@ static struct rb_node *__tree_search(struct rb_root *root, u64 offset,
202 return NULL; 212 return NULL;
203} 213}
204 214
205static inline struct rb_node *tree_search(struct rb_root *root, u64 offset) 215static inline struct rb_node *tree_search(struct extent_io_tree *tree,
216 u64 offset)
206{ 217{
207 struct rb_node *prev = NULL; 218 struct rb_node *prev = NULL;
208 struct rb_node *ret; 219 struct rb_node *ret;
209 220
210 ret = __tree_search(root, offset, &prev, NULL); 221 ret = __etree_search(tree, offset, &prev, NULL);
211 if (!ret) 222 if (!ret) {
223 if (prev) {
224 tree->last = rb_entry(prev, struct extent_state,
225 rb_node);
226 }
212 return prev; 227 return prev;
228 }
213 return ret; 229 return ret;
214} 230}
215 231
@@ -238,6 +254,8 @@ static int merge_state(struct extent_io_tree *tree,
238 other->state == state->state) { 254 other->state == state->state) {
239 state->start = other->start; 255 state->start = other->start;
240 other->tree = NULL; 256 other->tree = NULL;
257 if (tree->last == other)
258 tree->last = NULL;
241 rb_erase(&other->rb_node, &tree->state); 259 rb_erase(&other->rb_node, &tree->state);
242 free_extent_state(other); 260 free_extent_state(other);
243 } 261 }
@@ -249,6 +267,8 @@ static int merge_state(struct extent_io_tree *tree,
249 other->state == state->state) { 267 other->state == state->state) {
250 other->start = state->start; 268 other->start = state->start;
251 state->tree = NULL; 269 state->tree = NULL;
270 if (tree->last == state)
271 tree->last = NULL;
252 rb_erase(&state->rb_node, &tree->state); 272 rb_erase(&state->rb_node, &tree->state);
253 free_extent_state(state); 273 free_extent_state(state);
254 } 274 }
@@ -311,6 +331,7 @@ static int insert_state(struct extent_io_tree *tree,
311 return -EEXIST; 331 return -EEXIST;
312 } 332 }
313 state->tree = tree; 333 state->tree = tree;
334 tree->last = state;
314 merge_state(tree, state); 335 merge_state(tree, state);
315 return 0; 336 return 0;
316} 337}
@@ -375,6 +396,8 @@ static int clear_state_bit(struct extent_io_tree *tree,
375 wake_up(&state->wq); 396 wake_up(&state->wq);
376 if (delete || state->state == 0) { 397 if (delete || state->state == 0) {
377 if (state->tree) { 398 if (state->tree) {
399 if (tree->last == state)
400 tree->last = NULL;
378 rb_erase(&state->rb_node, &tree->state); 401 rb_erase(&state->rb_node, &tree->state);
379 state->tree = NULL; 402 state->tree = NULL;
380 free_extent_state(state); 403 free_extent_state(state);
@@ -422,7 +445,7 @@ again:
422 * this search will find the extents that end after 445 * this search will find the extents that end after
423 * our range starts 446 * our range starts
424 */ 447 */
425 node = tree_search(&tree->state, start); 448 node = tree_search(tree, start);
426 if (!node) 449 if (!node)
427 goto out; 450 goto out;
428 state = rb_entry(node, struct extent_state, rb_node); 451 state = rb_entry(node, struct extent_state, rb_node);
@@ -533,7 +556,7 @@ again:
533 * this search will find all the extents that end after 556 * this search will find all the extents that end after
534 * our range starts 557 * our range starts
535 */ 558 */
536 node = tree_search(&tree->state, start); 559 node = tree_search(tree, start);
537 if (!node) 560 if (!node)
538 break; 561 break;
539 562
@@ -612,7 +635,7 @@ again:
612 * this search will find all the extents that end after 635 * this search will find all the extents that end after
613 * our range starts. 636 * our range starts.
614 */ 637 */
615 node = tree_search(&tree->state, start); 638 node = tree_search(tree, start);
616 if (!node) { 639 if (!node) {
617 err = insert_state(tree, prealloc, start, end, bits); 640 err = insert_state(tree, prealloc, start, end, bits);
618 prealloc = NULL; 641 prealloc = NULL;
@@ -915,7 +938,7 @@ int find_first_extent_bit(struct extent_io_tree *tree, u64 start,
915 * this search will find all the extents that end after 938 * this search will find all the extents that end after
916 * our range starts. 939 * our range starts.
917 */ 940 */
918 node = tree_search(&tree->state, start); 941 node = tree_search(tree, start);
919 if (!node || IS_ERR(node)) { 942 if (!node || IS_ERR(node)) {
920 goto out; 943 goto out;
921 } 944 }
@@ -953,7 +976,7 @@ u64 find_lock_delalloc_range(struct extent_io_tree *tree,
953 * our range starts. 976 * our range starts.
954 */ 977 */
955search_again: 978search_again:
956 node = tree_search(&tree->state, cur_start); 979 node = tree_search(tree, cur_start);
957 if (!node || IS_ERR(node)) { 980 if (!node || IS_ERR(node)) {
958 *end = (u64)-1; 981 *end = (u64)-1;
959 goto out; 982 goto out;
@@ -1041,7 +1064,7 @@ u64 count_range_bits(struct extent_io_tree *tree,
1041 * this search will find all the extents that end after 1064 * this search will find all the extents that end after
1042 * our range starts. 1065 * our range starts.
1043 */ 1066 */
1044 node = tree_search(&tree->state, cur_start); 1067 node = tree_search(tree, cur_start);
1045 if (!node || IS_ERR(node)) { 1068 if (!node || IS_ERR(node)) {
1046 goto out; 1069 goto out;
1047 } 1070 }
@@ -1142,7 +1165,7 @@ int set_state_private(struct extent_io_tree *tree, u64 start, u64 private)
1142 * this search will find all the extents that end after 1165 * this search will find all the extents that end after
1143 * our range starts. 1166 * our range starts.
1144 */ 1167 */
1145 node = tree_search(&tree->state, start); 1168 node = tree_search(tree, start);
1146 if (!node || IS_ERR(node)) { 1169 if (!node || IS_ERR(node)) {
1147 ret = -ENOENT; 1170 ret = -ENOENT;
1148 goto out; 1171 goto out;
@@ -1169,7 +1192,7 @@ int get_state_private(struct extent_io_tree *tree, u64 start, u64 *private)
1169 * this search will find all the extents that end after 1192 * this search will find all the extents that end after
1170 * our range starts. 1193 * our range starts.
1171 */ 1194 */
1172 node = tree_search(&tree->state, start); 1195 node = tree_search(tree, start);
1173 if (!node || IS_ERR(node)) { 1196 if (!node || IS_ERR(node)) {
1174 ret = -ENOENT; 1197 ret = -ENOENT;
1175 goto out; 1198 goto out;
@@ -1200,7 +1223,7 @@ int test_range_bit(struct extent_io_tree *tree, u64 start, u64 end,
1200 unsigned long flags; 1223 unsigned long flags;
1201 1224
1202 spin_lock_irqsave(&tree->lock, flags); 1225 spin_lock_irqsave(&tree->lock, flags);
1203 node = tree_search(&tree->state, start); 1226 node = tree_search(tree, start);
1204 while (node && start <= end) { 1227 while (node && start <= end) {
1205 state = rb_entry(node, struct extent_state, rb_node); 1228 state = rb_entry(node, struct extent_state, rb_node);
1206 1229
@@ -1348,7 +1371,7 @@ static int end_bio_extent_writepage(struct bio *bio,
1348 spin_lock_irqsave(&tree->lock, flags); 1371 spin_lock_irqsave(&tree->lock, flags);
1349 if (!state || state->end != end) { 1372 if (!state || state->end != end) {
1350 state = NULL; 1373 state = NULL;
1351 node = __tree_search(&tree->state, start, NULL, NULL); 1374 node = __etree_search(tree, start, NULL, NULL);
1352 if (node) { 1375 if (node) {
1353 state = rb_entry(node, struct extent_state, 1376 state = rb_entry(node, struct extent_state,
1354 rb_node); 1377 rb_node);
@@ -1468,7 +1491,7 @@ static int end_bio_extent_readpage(struct bio *bio,
1468 spin_lock_irqsave(&tree->lock, flags); 1491 spin_lock_irqsave(&tree->lock, flags);
1469 if (!state || state->end != end) { 1492 if (!state || state->end != end) {
1470 state = NULL; 1493 state = NULL;
1471 node = __tree_search(&tree->state, start, NULL, NULL); 1494 node = __etree_search(tree, start, NULL, NULL);
1472 if (node) { 1495 if (node) {
1473 state = rb_entry(node, struct extent_state, 1496 state = rb_entry(node, struct extent_state,
1474 rb_node); 1497 rb_node);
@@ -1631,7 +1654,7 @@ static int submit_one_bio(int rw, struct bio *bio)
1631 end = start + bvec->bv_len - 1; 1654 end = start + bvec->bv_len - 1;
1632 1655
1633 spin_lock_irq(&tree->lock); 1656 spin_lock_irq(&tree->lock);
1634 node = __tree_search(&tree->state, start, NULL, NULL); 1657 node = __etree_search(tree, start, NULL, NULL);
1635 BUG_ON(!node); 1658 BUG_ON(!node);
1636 state = rb_entry(node, struct extent_state, rb_node); 1659 state = rb_entry(node, struct extent_state, rb_node);
1637 while(state->end < end) { 1660 while(state->end < end) {