diff options
Diffstat (limited to 'fs/btrfs/extent_io.c')
-rw-r--r-- | fs/btrfs/extent_io.c | 149 |
1 files changed, 99 insertions, 50 deletions
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 5106008f5e28..1ff438fd5bc2 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c | |||
@@ -359,6 +359,24 @@ do_insert: | |||
359 | return NULL; | 359 | return NULL; |
360 | } | 360 | } |
361 | 361 | ||
362 | /** | ||
363 | * __etree_search - searche @tree for an entry that contains @offset. Such | ||
364 | * entry would have entry->start <= offset && entry->end >= offset. | ||
365 | * | ||
366 | * @tree - the tree to search | ||
367 | * @offset - offset that should fall within an entry in @tree | ||
368 | * @next_ret - pointer to the first entry whose range ends after @offset | ||
369 | * @prev - pointer to the first entry whose range begins before @offset | ||
370 | * @p_ret - pointer where new node should be anchored (used when inserting an | ||
371 | * entry in the tree) | ||
372 | * @parent_ret - points to entry which would have been the parent of the entry, | ||
373 | * containing @offset | ||
374 | * | ||
375 | * This function returns a pointer to the entry that contains @offset byte | ||
376 | * address. If no such entry exists, then NULL is returned and the other | ||
377 | * pointer arguments to the function are filled, otherwise the found entry is | ||
378 | * returned and other pointers are left untouched. | ||
379 | */ | ||
362 | static struct rb_node *__etree_search(struct extent_io_tree *tree, u64 offset, | 380 | static struct rb_node *__etree_search(struct extent_io_tree *tree, u64 offset, |
363 | struct rb_node **next_ret, | 381 | struct rb_node **next_ret, |
364 | struct rb_node **prev_ret, | 382 | struct rb_node **prev_ret, |
@@ -504,9 +522,11 @@ static int insert_state(struct extent_io_tree *tree, | |||
504 | { | 522 | { |
505 | struct rb_node *node; | 523 | struct rb_node *node; |
506 | 524 | ||
507 | if (end < start) | 525 | if (end < start) { |
508 | WARN(1, KERN_ERR "BTRFS: end < start %llu %llu\n", | 526 | btrfs_err(tree->fs_info, |
509 | end, start); | 527 | "insert state: end < start %llu %llu", end, start); |
528 | WARN_ON(1); | ||
529 | } | ||
510 | state->start = start; | 530 | state->start = start; |
511 | state->end = end; | 531 | state->end = end; |
512 | 532 | ||
@@ -516,7 +536,8 @@ static int insert_state(struct extent_io_tree *tree, | |||
516 | if (node) { | 536 | if (node) { |
517 | struct extent_state *found; | 537 | struct extent_state *found; |
518 | found = rb_entry(node, struct extent_state, rb_node); | 538 | found = rb_entry(node, struct extent_state, rb_node); |
519 | pr_err("BTRFS: found node %llu %llu on insert of %llu %llu\n", | 539 | btrfs_err(tree->fs_info, |
540 | "found node %llu %llu on insert of %llu %llu", | ||
520 | found->start, found->end, start, end); | 541 | found->start, found->end, start, end); |
521 | return -EEXIST; | 542 | return -EEXIST; |
522 | } | 543 | } |
@@ -1537,8 +1558,8 @@ out: | |||
1537 | } | 1558 | } |
1538 | 1559 | ||
1539 | /** | 1560 | /** |
1540 | * find_first_clear_extent_bit - finds the first range that has @bits not set | 1561 | * find_first_clear_extent_bit - find the first range that has @bits not set. |
1541 | * and that starts after @start | 1562 | * This range could start before @start. |
1542 | * | 1563 | * |
1543 | * @tree - the tree to search | 1564 | * @tree - the tree to search |
1544 | * @start - the offset at/after which the found extent should start | 1565 | * @start - the offset at/after which the found extent should start |
@@ -1578,12 +1599,52 @@ void find_first_clear_extent_bit(struct extent_io_tree *tree, u64 start, | |||
1578 | goto out; | 1599 | goto out; |
1579 | } | 1600 | } |
1580 | } | 1601 | } |
1602 | /* | ||
1603 | * At this point 'node' either contains 'start' or start is | ||
1604 | * before 'node' | ||
1605 | */ | ||
1581 | state = rb_entry(node, struct extent_state, rb_node); | 1606 | state = rb_entry(node, struct extent_state, rb_node); |
1582 | if (in_range(start, state->start, state->end - state->start + 1) && | 1607 | |
1583 | (state->state & bits)) { | 1608 | if (in_range(start, state->start, state->end - state->start + 1)) { |
1584 | start = state->end + 1; | 1609 | if (state->state & bits) { |
1610 | /* | ||
1611 | * |--range with bits sets--| | ||
1612 | * | | ||
1613 | * start | ||
1614 | */ | ||
1615 | start = state->end + 1; | ||
1616 | } else { | ||
1617 | /* | ||
1618 | * 'start' falls within a range that doesn't | ||
1619 | * have the bits set, so take its start as | ||
1620 | * the beginning of the desired range | ||
1621 | * | ||
1622 | * |--range with bits cleared----| | ||
1623 | * | | ||
1624 | * start | ||
1625 | */ | ||
1626 | *start_ret = state->start; | ||
1627 | break; | ||
1628 | } | ||
1585 | } else { | 1629 | } else { |
1586 | *start_ret = start; | 1630 | /* |
1631 | * |---prev range---|---hole/unset---|---node range---| | ||
1632 | * | | ||
1633 | * start | ||
1634 | * | ||
1635 | * or | ||
1636 | * | ||
1637 | * |---hole/unset--||--first node--| | ||
1638 | * 0 | | ||
1639 | * start | ||
1640 | */ | ||
1641 | if (prev) { | ||
1642 | state = rb_entry(prev, struct extent_state, | ||
1643 | rb_node); | ||
1644 | *start_ret = state->end + 1; | ||
1645 | } else { | ||
1646 | *start_ret = 0; | ||
1647 | } | ||
1587 | break; | 1648 | break; |
1588 | } | 1649 | } |
1589 | } | 1650 | } |
@@ -1719,10 +1780,10 @@ static noinline int lock_delalloc_pages(struct inode *inode, | |||
1719 | */ | 1780 | */ |
1720 | EXPORT_FOR_TESTS | 1781 | EXPORT_FOR_TESTS |
1721 | noinline_for_stack bool find_lock_delalloc_range(struct inode *inode, | 1782 | noinline_for_stack bool find_lock_delalloc_range(struct inode *inode, |
1722 | struct extent_io_tree *tree, | ||
1723 | struct page *locked_page, u64 *start, | 1783 | struct page *locked_page, u64 *start, |
1724 | u64 *end) | 1784 | u64 *end) |
1725 | { | 1785 | { |
1786 | struct extent_io_tree *tree = &BTRFS_I(inode)->io_tree; | ||
1726 | u64 max_bytes = BTRFS_MAX_EXTENT_SIZE; | 1787 | u64 max_bytes = BTRFS_MAX_EXTENT_SIZE; |
1727 | u64 delalloc_start; | 1788 | u64 delalloc_start; |
1728 | u64 delalloc_end; | 1789 | u64 delalloc_end; |
@@ -2800,12 +2861,11 @@ static inline void btrfs_io_bio_init(struct btrfs_io_bio *btrfs_bio) | |||
2800 | * never fail. We're returning a bio right now but you can call btrfs_io_bio | 2861 | * never fail. We're returning a bio right now but you can call btrfs_io_bio |
2801 | * for the appropriate container_of magic | 2862 | * for the appropriate container_of magic |
2802 | */ | 2863 | */ |
2803 | struct bio *btrfs_bio_alloc(struct block_device *bdev, u64 first_byte) | 2864 | struct bio *btrfs_bio_alloc(u64 first_byte) |
2804 | { | 2865 | { |
2805 | struct bio *bio; | 2866 | struct bio *bio; |
2806 | 2867 | ||
2807 | bio = bio_alloc_bioset(GFP_NOFS, BIO_MAX_PAGES, &btrfs_bioset); | 2868 | bio = bio_alloc_bioset(GFP_NOFS, BIO_MAX_PAGES, &btrfs_bioset); |
2808 | bio_set_dev(bio, bdev); | ||
2809 | bio->bi_iter.bi_sector = first_byte >> 9; | 2869 | bio->bi_iter.bi_sector = first_byte >> 9; |
2810 | btrfs_io_bio_init(btrfs_io_bio(bio)); | 2870 | btrfs_io_bio_init(btrfs_io_bio(bio)); |
2811 | return bio; | 2871 | return bio; |
@@ -2916,7 +2976,8 @@ static int submit_extent_page(unsigned int opf, struct extent_io_tree *tree, | |||
2916 | } | 2976 | } |
2917 | } | 2977 | } |
2918 | 2978 | ||
2919 | bio = btrfs_bio_alloc(bdev, offset); | 2979 | bio = btrfs_bio_alloc(offset); |
2980 | bio_set_dev(bio, bdev); | ||
2920 | bio_add_page(bio, page, page_size, pg_offset); | 2981 | bio_add_page(bio, page, page_size, pg_offset); |
2921 | bio->bi_end_io = end_io_func; | 2982 | bio->bi_end_io = end_io_func; |
2922 | bio->bi_private = tree; | 2983 | bio->bi_private = tree; |
@@ -3204,21 +3265,10 @@ static inline void contiguous_readpages(struct extent_io_tree *tree, | |||
3204 | unsigned long *bio_flags, | 3265 | unsigned long *bio_flags, |
3205 | u64 *prev_em_start) | 3266 | u64 *prev_em_start) |
3206 | { | 3267 | { |
3207 | struct inode *inode; | 3268 | struct btrfs_inode *inode = BTRFS_I(pages[0]->mapping->host); |
3208 | struct btrfs_ordered_extent *ordered; | ||
3209 | int index; | 3269 | int index; |
3210 | 3270 | ||
3211 | inode = pages[0]->mapping->host; | 3271 | btrfs_lock_and_flush_ordered_range(tree, inode, start, end, NULL); |
3212 | while (1) { | ||
3213 | lock_extent(tree, start, end); | ||
3214 | ordered = btrfs_lookup_ordered_range(BTRFS_I(inode), start, | ||
3215 | end - start + 1); | ||
3216 | if (!ordered) | ||
3217 | break; | ||
3218 | unlock_extent(tree, start, end); | ||
3219 | btrfs_start_ordered_extent(inode, ordered, 1); | ||
3220 | btrfs_put_ordered_extent(ordered); | ||
3221 | } | ||
3222 | 3272 | ||
3223 | for (index = 0; index < nr_pages; index++) { | 3273 | for (index = 0; index < nr_pages; index++) { |
3224 | __do_readpage(tree, pages[index], btrfs_get_extent, em_cached, | 3274 | __do_readpage(tree, pages[index], btrfs_get_extent, em_cached, |
@@ -3234,22 +3284,12 @@ static int __extent_read_full_page(struct extent_io_tree *tree, | |||
3234 | unsigned long *bio_flags, | 3284 | unsigned long *bio_flags, |
3235 | unsigned int read_flags) | 3285 | unsigned int read_flags) |
3236 | { | 3286 | { |
3237 | struct inode *inode = page->mapping->host; | 3287 | struct btrfs_inode *inode = BTRFS_I(page->mapping->host); |
3238 | struct btrfs_ordered_extent *ordered; | ||
3239 | u64 start = page_offset(page); | 3288 | u64 start = page_offset(page); |
3240 | u64 end = start + PAGE_SIZE - 1; | 3289 | u64 end = start + PAGE_SIZE - 1; |
3241 | int ret; | 3290 | int ret; |
3242 | 3291 | ||
3243 | while (1) { | 3292 | btrfs_lock_and_flush_ordered_range(tree, inode, start, end, NULL); |
3244 | lock_extent(tree, start, end); | ||
3245 | ordered = btrfs_lookup_ordered_range(BTRFS_I(inode), start, | ||
3246 | PAGE_SIZE); | ||
3247 | if (!ordered) | ||
3248 | break; | ||
3249 | unlock_extent(tree, start, end); | ||
3250 | btrfs_start_ordered_extent(inode, ordered, 1); | ||
3251 | btrfs_put_ordered_extent(ordered); | ||
3252 | } | ||
3253 | 3293 | ||
3254 | ret = __do_readpage(tree, page, get_extent, NULL, bio, mirror_num, | 3294 | ret = __do_readpage(tree, page, get_extent, NULL, bio, mirror_num, |
3255 | bio_flags, read_flags, NULL); | 3295 | bio_flags, read_flags, NULL); |
@@ -3290,7 +3330,6 @@ static noinline_for_stack int writepage_delalloc(struct inode *inode, | |||
3290 | struct page *page, struct writeback_control *wbc, | 3330 | struct page *page, struct writeback_control *wbc, |
3291 | u64 delalloc_start, unsigned long *nr_written) | 3331 | u64 delalloc_start, unsigned long *nr_written) |
3292 | { | 3332 | { |
3293 | struct extent_io_tree *tree = &BTRFS_I(inode)->io_tree; | ||
3294 | u64 page_end = delalloc_start + PAGE_SIZE - 1; | 3333 | u64 page_end = delalloc_start + PAGE_SIZE - 1; |
3295 | bool found; | 3334 | bool found; |
3296 | u64 delalloc_to_write = 0; | 3335 | u64 delalloc_to_write = 0; |
@@ -3300,8 +3339,7 @@ static noinline_for_stack int writepage_delalloc(struct inode *inode, | |||
3300 | 3339 | ||
3301 | 3340 | ||
3302 | while (delalloc_end < page_end) { | 3341 | while (delalloc_end < page_end) { |
3303 | found = find_lock_delalloc_range(inode, tree, | 3342 | found = find_lock_delalloc_range(inode, page, |
3304 | page, | ||
3305 | &delalloc_start, | 3343 | &delalloc_start, |
3306 | &delalloc_end); | 3344 | &delalloc_end); |
3307 | if (!found) { | 3345 | if (!found) { |
@@ -3310,7 +3348,6 @@ static noinline_for_stack int writepage_delalloc(struct inode *inode, | |||
3310 | } | 3348 | } |
3311 | ret = btrfs_run_delalloc_range(inode, page, delalloc_start, | 3349 | ret = btrfs_run_delalloc_range(inode, page, delalloc_start, |
3312 | delalloc_end, &page_started, nr_written, wbc); | 3350 | delalloc_end, &page_started, nr_written, wbc); |
3313 | /* File system has been set read-only */ | ||
3314 | if (ret) { | 3351 | if (ret) { |
3315 | SetPageError(page); | 3352 | SetPageError(page); |
3316 | /* | 3353 | /* |
@@ -4542,6 +4579,8 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, | |||
4542 | struct btrfs_path *path; | 4579 | struct btrfs_path *path; |
4543 | struct btrfs_root *root = BTRFS_I(inode)->root; | 4580 | struct btrfs_root *root = BTRFS_I(inode)->root; |
4544 | struct fiemap_cache cache = { 0 }; | 4581 | struct fiemap_cache cache = { 0 }; |
4582 | struct ulist *roots; | ||
4583 | struct ulist *tmp_ulist; | ||
4545 | int end = 0; | 4584 | int end = 0; |
4546 | u64 em_start = 0; | 4585 | u64 em_start = 0; |
4547 | u64 em_len = 0; | 4586 | u64 em_len = 0; |
@@ -4555,6 +4594,13 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, | |||
4555 | return -ENOMEM; | 4594 | return -ENOMEM; |
4556 | path->leave_spinning = 1; | 4595 | path->leave_spinning = 1; |
4557 | 4596 | ||
4597 | roots = ulist_alloc(GFP_KERNEL); | ||
4598 | tmp_ulist = ulist_alloc(GFP_KERNEL); | ||
4599 | if (!roots || !tmp_ulist) { | ||
4600 | ret = -ENOMEM; | ||
4601 | goto out_free_ulist; | ||
4602 | } | ||
4603 | |||
4558 | start = round_down(start, btrfs_inode_sectorsize(inode)); | 4604 | start = round_down(start, btrfs_inode_sectorsize(inode)); |
4559 | len = round_up(max, btrfs_inode_sectorsize(inode)) - start; | 4605 | len = round_up(max, btrfs_inode_sectorsize(inode)) - start; |
4560 | 4606 | ||
@@ -4565,8 +4611,7 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, | |||
4565 | ret = btrfs_lookup_file_extent(NULL, root, path, | 4611 | ret = btrfs_lookup_file_extent(NULL, root, path, |
4566 | btrfs_ino(BTRFS_I(inode)), -1, 0); | 4612 | btrfs_ino(BTRFS_I(inode)), -1, 0); |
4567 | if (ret < 0) { | 4613 | if (ret < 0) { |
4568 | btrfs_free_path(path); | 4614 | goto out_free_ulist; |
4569 | return ret; | ||
4570 | } else { | 4615 | } else { |
4571 | WARN_ON(!ret); | 4616 | WARN_ON(!ret); |
4572 | if (ret == 1) | 4617 | if (ret == 1) |
@@ -4675,7 +4720,7 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, | |||
4675 | */ | 4720 | */ |
4676 | ret = btrfs_check_shared(root, | 4721 | ret = btrfs_check_shared(root, |
4677 | btrfs_ino(BTRFS_I(inode)), | 4722 | btrfs_ino(BTRFS_I(inode)), |
4678 | bytenr); | 4723 | bytenr, roots, tmp_ulist); |
4679 | if (ret < 0) | 4724 | if (ret < 0) |
4680 | goto out_free; | 4725 | goto out_free; |
4681 | if (ret) | 4726 | if (ret) |
@@ -4718,9 +4763,13 @@ out_free: | |||
4718 | ret = emit_last_fiemap_cache(fieinfo, &cache); | 4763 | ret = emit_last_fiemap_cache(fieinfo, &cache); |
4719 | free_extent_map(em); | 4764 | free_extent_map(em); |
4720 | out: | 4765 | out: |
4721 | btrfs_free_path(path); | ||
4722 | unlock_extent_cached(&BTRFS_I(inode)->io_tree, start, start + len - 1, | 4766 | unlock_extent_cached(&BTRFS_I(inode)->io_tree, start, start + len - 1, |
4723 | &cached_state); | 4767 | &cached_state); |
4768 | |||
4769 | out_free_ulist: | ||
4770 | btrfs_free_path(path); | ||
4771 | ulist_free(roots); | ||
4772 | ulist_free(tmp_ulist); | ||
4724 | return ret; | 4773 | return ret; |
4725 | } | 4774 | } |
4726 | 4775 | ||
@@ -4808,7 +4857,7 @@ __alloc_extent_buffer(struct btrfs_fs_info *fs_info, u64 start, | |||
4808 | eb->bflags = 0; | 4857 | eb->bflags = 0; |
4809 | rwlock_init(&eb->lock); | 4858 | rwlock_init(&eb->lock); |
4810 | atomic_set(&eb->blocking_readers, 0); | 4859 | atomic_set(&eb->blocking_readers, 0); |
4811 | atomic_set(&eb->blocking_writers, 0); | 4860 | eb->blocking_writers = 0; |
4812 | eb->lock_nested = false; | 4861 | eb->lock_nested = false; |
4813 | init_waitqueue_head(&eb->write_lock_wq); | 4862 | init_waitqueue_head(&eb->write_lock_wq); |
4814 | init_waitqueue_head(&eb->read_lock_wq); | 4863 | init_waitqueue_head(&eb->read_lock_wq); |
@@ -4827,10 +4876,10 @@ __alloc_extent_buffer(struct btrfs_fs_info *fs_info, u64 start, | |||
4827 | BUG_ON(len > MAX_INLINE_EXTENT_BUFFER_SIZE); | 4876 | BUG_ON(len > MAX_INLINE_EXTENT_BUFFER_SIZE); |
4828 | 4877 | ||
4829 | #ifdef CONFIG_BTRFS_DEBUG | 4878 | #ifdef CONFIG_BTRFS_DEBUG |
4830 | atomic_set(&eb->spinning_writers, 0); | 4879 | eb->spinning_writers = 0; |
4831 | atomic_set(&eb->spinning_readers, 0); | 4880 | atomic_set(&eb->spinning_readers, 0); |
4832 | atomic_set(&eb->read_locks, 0); | 4881 | atomic_set(&eb->read_locks, 0); |
4833 | atomic_set(&eb->write_locks, 0); | 4882 | eb->write_locks = 0; |
4834 | #endif | 4883 | #endif |
4835 | 4884 | ||
4836 | return eb; | 4885 | return eb; |