aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/extent_map.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/extent_map.c')
-rw-r--r--fs/btrfs/extent_map.c147
1 files changed, 112 insertions, 35 deletions
diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c
index d378edf0964e..a9c7419615b9 100644
--- a/fs/btrfs/extent_map.c
+++ b/fs/btrfs/extent_map.c
@@ -30,9 +30,6 @@ struct tree_entry {
30 30
31#define EXTENT_IOBITS (EXTENT_LOCKED | EXTENT_WRITEBACK) 31#define EXTENT_IOBITS (EXTENT_LOCKED | EXTENT_WRITEBACK)
32 32
33static LIST_HEAD(all_states);
34spinlock_t state_lock = SPIN_LOCK_UNLOCKED;
35
36void __init extent_map_init(void) 33void __init extent_map_init(void)
37{ 34{
38 extent_map_cache = kmem_cache_create("extent_map", 35 extent_map_cache = kmem_cache_create("extent_map",
@@ -49,15 +46,6 @@ void __init extent_map_init(void)
49 46
50void __exit extent_map_exit(void) 47void __exit extent_map_exit(void)
51{ 48{
52 while(!list_empty(&all_states)) {
53 struct extent_state *state;
54 struct list_head *cur = all_states.next;
55 state = list_entry(cur, struct extent_state, list);
56 printk("found leaked state %Lu %Lu state %d in_tree %d\n",
57 state->start, state->end, state->state, state->in_tree);
58 list_del(&state->list);
59 kfree(state);
60 }
61 if (extent_map_cache) 49 if (extent_map_cache)
62 kmem_cache_destroy(extent_map_cache); 50 kmem_cache_destroy(extent_map_cache);
63 if (extent_state_cache) 51 if (extent_state_cache)
@@ -69,6 +57,7 @@ void extent_map_tree_init(struct extent_map_tree *tree,
69{ 57{
70 tree->map.rb_node = NULL; 58 tree->map.rb_node = NULL;
71 tree->state.rb_node = NULL; 59 tree->state.rb_node = NULL;
60 tree->fill_delalloc = NULL;
72 rwlock_init(&tree->lock); 61 rwlock_init(&tree->lock);
73 tree->mapping = mapping; 62 tree->mapping = mapping;
74} 63}
@@ -106,9 +95,6 @@ struct extent_state *alloc_extent_state(gfp_t mask)
106 state->in_tree = 0; 95 state->in_tree = 0;
107 atomic_set(&state->refs, 1); 96 atomic_set(&state->refs, 1);
108 init_waitqueue_head(&state->wq); 97 init_waitqueue_head(&state->wq);
109 spin_lock_irq(&state_lock);
110 list_add(&state->list, &all_states);
111 spin_unlock_irq(&state_lock);
112 return state; 98 return state;
113} 99}
114EXPORT_SYMBOL(alloc_extent_state); 100EXPORT_SYMBOL(alloc_extent_state);
@@ -117,9 +103,6 @@ void free_extent_state(struct extent_state *state)
117{ 103{
118 if (atomic_dec_and_test(&state->refs)) { 104 if (atomic_dec_and_test(&state->refs)) {
119 WARN_ON(state->in_tree); 105 WARN_ON(state->in_tree);
120 spin_lock_irq(&state_lock);
121 list_del_init(&state->list);
122 spin_unlock_irq(&state_lock);
123 kmem_cache_free(extent_state_cache, state); 106 kmem_cache_free(extent_state_cache, state);
124 } 107 }
125} 108}
@@ -369,7 +352,7 @@ static int insert_state(struct extent_map_tree *tree,
369 if (node) { 352 if (node) {
370 struct extent_state *found; 353 struct extent_state *found;
371 found = rb_entry(node, struct extent_state, rb_node); 354 found = rb_entry(node, struct extent_state, rb_node);
372printk("found node %Lu %Lu on insert of %Lu %Lu\n", found->start, found->end, start, end); 355 printk("found node %Lu %Lu on insert of %Lu %Lu\n", found->start, found->end, start, end);
373 free_extent_state(state); 356 free_extent_state(state);
374 return -EEXIST; 357 return -EEXIST;
375 } 358 }
@@ -408,7 +391,7 @@ static int split_state(struct extent_map_tree *tree, struct extent_state *orig,
408 if (node) { 391 if (node) {
409 struct extent_state *found; 392 struct extent_state *found;
410 found = rb_entry(node, struct extent_state, rb_node); 393 found = rb_entry(node, struct extent_state, rb_node);
411printk("found node %Lu %Lu on insert of %Lu %Lu\n", found->start, found->end, prealloc->start, prealloc->end); 394 printk("found node %Lu %Lu on insert of %Lu %Lu\n", found->start, found->end, prealloc->start, prealloc->end);
412 free_extent_state(prealloc); 395 free_extent_state(prealloc);
413 return -EEXIST; 396 return -EEXIST;
414 } 397 }
@@ -792,10 +775,20 @@ int set_extent_dirty(struct extent_map_tree *tree, u64 start, u64 end,
792} 775}
793EXPORT_SYMBOL(set_extent_dirty); 776EXPORT_SYMBOL(set_extent_dirty);
794 777
778int set_extent_delalloc(struct extent_map_tree *tree, u64 start, u64 end,
779 gfp_t mask)
780{
781 return set_extent_bit(tree, start, end,
782 EXTENT_DELALLOC | EXTENT_DIRTY, 0, NULL,
783 mask);
784}
785EXPORT_SYMBOL(set_extent_delalloc);
786
795int clear_extent_dirty(struct extent_map_tree *tree, u64 start, u64 end, 787int clear_extent_dirty(struct extent_map_tree *tree, u64 start, u64 end,
796 gfp_t mask) 788 gfp_t mask)
797{ 789{
798 return clear_extent_bit(tree, start, end, EXTENT_DIRTY, 0, 0, mask); 790 return clear_extent_bit(tree, start, end,
791 EXTENT_DIRTY | EXTENT_DELALLOC, 0, 0, mask);
799} 792}
800EXPORT_SYMBOL(clear_extent_dirty); 793EXPORT_SYMBOL(clear_extent_dirty);
801 794
@@ -922,6 +915,62 @@ int set_range_writeback(struct extent_map_tree *tree, u64 start, u64 end)
922} 915}
923EXPORT_SYMBOL(set_range_writeback); 916EXPORT_SYMBOL(set_range_writeback);
924 917
918u64 find_lock_delalloc_range(struct extent_map_tree *tree,
919 u64 start, u64 lock_start, u64 *end, u64 max_bytes)
920{
921 struct rb_node *node;
922 struct extent_state *state;
923 u64 cur_start = start;
924 u64 found = 0;
925 u64 total_bytes = 0;
926
927 write_lock_irq(&tree->lock);
928 /*
929 * this search will find all the extents that end after
930 * our range starts.
931 */
932search_again:
933 node = tree_search(&tree->state, cur_start);
934 if (!node || IS_ERR(node)) {
935 goto out;
936 }
937
938 while(1) {
939 state = rb_entry(node, struct extent_state, rb_node);
940 if (state->start != cur_start) {
941 goto out;
942 }
943 if (!(state->state & EXTENT_DELALLOC)) {
944 goto out;
945 }
946 if (state->start >= lock_start) {
947 if (state->state & EXTENT_LOCKED) {
948 DEFINE_WAIT(wait);
949 atomic_inc(&state->refs);
950 write_unlock_irq(&tree->lock);
951 schedule();
952 write_lock_irq(&tree->lock);
953 finish_wait(&state->wq, &wait);
954 free_extent_state(state);
955 goto search_again;
956 }
957 state->state |= EXTENT_LOCKED;
958 }
959 found++;
960 *end = state->end;
961 cur_start = state->end + 1;
962 node = rb_next(node);
963 if (!node)
964 break;
965 total_bytes = state->end - state->start + 1;
966 if (total_bytes >= max_bytes)
967 break;
968 }
969out:
970 write_unlock_irq(&tree->lock);
971 return found;
972}
973
925/* 974/*
926 * helper function to lock both pages and extents in the tree. 975 * helper function to lock both pages and extents in the tree.
927 * pages must be locked first. 976 * pages must be locked first.
@@ -1285,6 +1334,7 @@ int extent_read_full_page(struct extent_map_tree *tree, struct page *page,
1285 if (!PagePrivate(page)) { 1334 if (!PagePrivate(page)) {
1286 SetPagePrivate(page); 1335 SetPagePrivate(page);
1287 set_page_private(page, 1); 1336 set_page_private(page, 1);
1337 WARN_ON(!page->mapping->a_ops->invalidatepage);
1288 page_cache_get(page); 1338 page_cache_get(page);
1289 } 1339 }
1290 1340
@@ -1384,7 +1434,10 @@ int extent_write_full_page(struct extent_map_tree *tree, struct page *page,
1384 size_t blocksize; 1434 size_t blocksize;
1385 loff_t i_size = i_size_read(inode); 1435 loff_t i_size = i_size_read(inode);
1386 unsigned long end_index = i_size >> PAGE_CACHE_SHIFT; 1436 unsigned long end_index = i_size >> PAGE_CACHE_SHIFT;
1437 u64 nr_delalloc;
1438 u64 delalloc_end;
1387 1439
1440 WARN_ON(!PageLocked(page));
1388 if (page->index > end_index) { 1441 if (page->index > end_index) {
1389 clear_extent_dirty(tree, start, page_end, GFP_NOFS); 1442 clear_extent_dirty(tree, start, page_end, GFP_NOFS);
1390 unlock_page(page); 1443 unlock_page(page);
@@ -1400,11 +1453,34 @@ int extent_write_full_page(struct extent_map_tree *tree, struct page *page,
1400 if (!PagePrivate(page)) { 1453 if (!PagePrivate(page)) {
1401 SetPagePrivate(page); 1454 SetPagePrivate(page);
1402 set_page_private(page, 1); 1455 set_page_private(page, 1);
1456 WARN_ON(!page->mapping->a_ops->invalidatepage);
1403 page_cache_get(page); 1457 page_cache_get(page);
1404 } 1458 }
1405 1459
1406 end = page_end;
1407 lock_extent(tree, start, page_end, GFP_NOFS); 1460 lock_extent(tree, start, page_end, GFP_NOFS);
1461 nr_delalloc = find_lock_delalloc_range(tree, start, page_end + 1,
1462 &delalloc_end,
1463 128 * 1024 * 1024);
1464 if (nr_delalloc) {
1465 tree->fill_delalloc(inode, start, delalloc_end);
1466 if (delalloc_end >= page_end + 1) {
1467 clear_extent_bit(tree, page_end + 1, delalloc_end,
1468 EXTENT_LOCKED | EXTENT_DELALLOC,
1469 1, 0, GFP_NOFS);
1470 }
1471 clear_extent_bit(tree, start, page_end, EXTENT_DELALLOC,
1472 0, 0, GFP_NOFS);
1473 if (test_range_bit(tree, start, page_end, EXTENT_DELALLOC, 0)) {
1474 printk("found delalloc bits after clear extent_bit\n");
1475 }
1476 } else if (test_range_bit(tree, start, page_end, EXTENT_DELALLOC, 0)) {
1477 printk("found delalloc bits after find_delalloc_range returns 0\n");
1478 }
1479
1480 end = page_end;
1481 if (test_range_bit(tree, start, page_end, EXTENT_DELALLOC, 0)) {
1482 printk("found delalloc bits after lock_extent\n");
1483 }
1408 1484
1409 if (last_byte <= start) { 1485 if (last_byte <= start) {
1410 clear_extent_dirty(tree, start, page_end, GFP_NOFS); 1486 clear_extent_dirty(tree, start, page_end, GFP_NOFS);
@@ -1419,7 +1495,7 @@ int extent_write_full_page(struct extent_map_tree *tree, struct page *page,
1419 clear_extent_dirty(tree, cur, page_end, GFP_NOFS); 1495 clear_extent_dirty(tree, cur, page_end, GFP_NOFS);
1420 break; 1496 break;
1421 } 1497 }
1422 em = get_extent(inode, page, page_offset, cur, end, 1); 1498 em = get_extent(inode, page, page_offset, cur, end, 0);
1423 if (IS_ERR(em) || !em) { 1499 if (IS_ERR(em) || !em) {
1424 SetPageError(page); 1500 SetPageError(page);
1425 break; 1501 break;
@@ -1507,6 +1583,7 @@ int extent_commit_write(struct extent_map_tree *tree,
1507 if (!PagePrivate(page)) { 1583 if (!PagePrivate(page)) {
1508 SetPagePrivate(page); 1584 SetPagePrivate(page);
1509 set_page_private(page, 1); 1585 set_page_private(page, 1);
1586 WARN_ON(!page->mapping->a_ops->invalidatepage);
1510 page_cache_get(page); 1587 page_cache_get(page);
1511 } 1588 }
1512 1589
@@ -1543,6 +1620,7 @@ int extent_prepare_write(struct extent_map_tree *tree,
1543 if (!PagePrivate(page)) { 1620 if (!PagePrivate(page)) {
1544 SetPagePrivate(page); 1621 SetPagePrivate(page);
1545 set_page_private(page, 1); 1622 set_page_private(page, 1);
1623 WARN_ON(!page->mapping->a_ops->invalidatepage);
1546 page_cache_get(page); 1624 page_cache_get(page);
1547 } 1625 }
1548 block_start = (page_start + from) & ~((u64)blocksize - 1); 1626 block_start = (page_start + from) & ~((u64)blocksize - 1);
@@ -1628,29 +1706,28 @@ int try_release_extent_mapping(struct extent_map_tree *tree, struct page *page)
1628 u64 start = page->index << PAGE_CACHE_SHIFT; 1706 u64 start = page->index << PAGE_CACHE_SHIFT;
1629 u64 end = start + PAGE_CACHE_SIZE - 1; 1707 u64 end = start + PAGE_CACHE_SIZE - 1;
1630 u64 orig_start = start; 1708 u64 orig_start = start;
1709 int ret = 1;
1631 1710
1632 while (start <= end) { 1711 while (start <= end) {
1633 em = lookup_extent_mapping(tree, start, end); 1712 em = lookup_extent_mapping(tree, start, end);
1634 if (!em || IS_ERR(em)) 1713 if (!em || IS_ERR(em))
1635 break; 1714 break;
1636 if (test_range_bit(tree, em->start, em->end, 1715 if (!test_range_bit(tree, em->start, em->end,
1637 EXTENT_LOCKED, 0)) { 1716 EXTENT_LOCKED, 0)) {
1717 remove_extent_mapping(tree, em);
1718 /* once for the rb tree */
1638 free_extent_map(em); 1719 free_extent_map(em);
1639 start = em->end + 1;
1640printk("range still locked %Lu %Lu\n", em->start, em->end);
1641 break;
1642 } 1720 }
1643 remove_extent_mapping(tree, em);
1644 start = em->end + 1; 1721 start = em->end + 1;
1645 /* once for the rb tree */
1646 free_extent_map(em);
1647 /* once for us */ 1722 /* once for us */
1648 free_extent_map(em); 1723 free_extent_map(em);
1649 } 1724 }
1650 WARN_ON(test_range_bit(tree, orig_start, end, EXTENT_WRITEBACK, 0)); 1725 if (test_range_bit(tree, orig_start, end, EXTENT_LOCKED, 0))
1651 clear_extent_bit(tree, orig_start, end, EXTENT_UPTODATE, 1726 ret = 0;
1652 1, 1, GFP_NOFS); 1727 else
1653 return 1; 1728 clear_extent_bit(tree, orig_start, end, EXTENT_UPTODATE,
1729 1, 1, GFP_NOFS);
1730 return ret;
1654} 1731}
1655EXPORT_SYMBOL(try_release_extent_mapping); 1732EXPORT_SYMBOL(try_release_extent_mapping);
1656 1733