diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/btrfs/disk-io.c | 9 | ||||
-rw-r--r-- | fs/btrfs/extent_io.c | 8 | ||||
-rw-r--r-- | fs/btrfs/inode.c | 33 | ||||
-rw-r--r-- | fs/btrfs/ordered-data.c | 1 |
4 files changed, 31 insertions, 20 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 86e84a8579e3..7ce3f83c5dd6 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -1011,9 +1011,16 @@ void btrfs_unplug_io_fn(struct backing_dev_info *bdi, struct page *page) | |||
1011 | spin_lock(&em_tree->lock); | 1011 | spin_lock(&em_tree->lock); |
1012 | em = lookup_extent_mapping(em_tree, offset, PAGE_CACHE_SIZE); | 1012 | em = lookup_extent_mapping(em_tree, offset, PAGE_CACHE_SIZE); |
1013 | spin_unlock(&em_tree->lock); | 1013 | spin_unlock(&em_tree->lock); |
1014 | if (!em) | 1014 | if (!em) { |
1015 | __unplug_io_fn(bdi, page); | ||
1015 | return; | 1016 | return; |
1017 | } | ||
1016 | 1018 | ||
1019 | if (em->block_start >= EXTENT_MAP_LAST_BYTE) { | ||
1020 | free_extent_map(em); | ||
1021 | __unplug_io_fn(bdi, page); | ||
1022 | return; | ||
1023 | } | ||
1017 | offset = offset - em->start; | 1024 | offset = offset - em->start; |
1018 | btrfs_unplug_page(&BTRFS_I(inode)->root->fs_info->mapping_tree, | 1025 | btrfs_unplug_page(&BTRFS_I(inode)->root->fs_info->mapping_tree, |
1019 | em->block_start + offset, page); | 1026 | em->block_start + offset, page); |
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 9965993748d0..e3547a992d5c 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c | |||
@@ -1949,18 +1949,18 @@ printk("2bad mapping end %Lu cur %Lu\n", end, cur); | |||
1949 | cur + iosize - 1); | 1949 | cur + iosize - 1); |
1950 | } | 1950 | } |
1951 | if (!ret) { | 1951 | if (!ret) { |
1952 | unsigned long nr = (last_byte >> PAGE_CACHE_SHIFT) + 1; | 1952 | unsigned long pnr = (last_byte >> PAGE_CACHE_SHIFT) + 1; |
1953 | nr -= page->index; | 1953 | pnr -= page->index; |
1954 | ret = submit_extent_page(READ, tree, page, | 1954 | ret = submit_extent_page(READ, tree, page, |
1955 | sector, iosize, page_offset, | 1955 | sector, iosize, page_offset, |
1956 | bdev, bio, nr, | 1956 | bdev, bio, pnr, |
1957 | end_bio_extent_readpage, mirror_num); | 1957 | end_bio_extent_readpage, mirror_num); |
1958 | nr++; | ||
1958 | } | 1959 | } |
1959 | if (ret) | 1960 | if (ret) |
1960 | SetPageError(page); | 1961 | SetPageError(page); |
1961 | cur = cur + iosize; | 1962 | cur = cur + iosize; |
1962 | page_offset += iosize; | 1963 | page_offset += iosize; |
1963 | nr++; | ||
1964 | } | 1964 | } |
1965 | if (!nr) { | 1965 | if (!nr) { |
1966 | if (!PageError(page)) | 1966 | if (!PageError(page)) |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 28e667052ec3..0e90315ea803 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -611,22 +611,25 @@ int btrfs_readpage_io_hook(struct page *page, u64 start, u64 end) | |||
611 | btrfs_test_flag(inode, NODATASUM)) | 611 | btrfs_test_flag(inode, NODATASUM)) |
612 | return 0; | 612 | return 0; |
613 | 613 | ||
614 | /* | ||
615 | * It is possible there is an ordered extent that has | ||
616 | * not yet finished for this range in the file. If so, | ||
617 | * that extent will have a csum cached, and it will insert | ||
618 | * the sum after all the blocks in the extent are fully | ||
619 | * on disk. So, look for an ordered extent and use the | ||
620 | * sum if found. We have to do this before looking in the | ||
621 | * btree because csum items are pre-inserted based on | ||
622 | * the file size. btrfs_lookup_csum might find an item | ||
623 | * that still hasn't been fully filled. | ||
624 | */ | ||
625 | ret = btrfs_find_ordered_sum(inode, start, &csum); | ||
626 | if (ret == 0) | ||
627 | goto found; | ||
628 | |||
629 | ret = 0; | ||
614 | path = btrfs_alloc_path(); | 630 | path = btrfs_alloc_path(); |
615 | mutex_lock(&BTRFS_I(inode)->csum_mutex); | ||
616 | item = btrfs_lookup_csum(NULL, root, path, inode->i_ino, start, 0); | 631 | item = btrfs_lookup_csum(NULL, root, path, inode->i_ino, start, 0); |
617 | if (IS_ERR(item)) { | 632 | if (IS_ERR(item)) { |
618 | /* | ||
619 | * It is possible there is an ordered extent that has | ||
620 | * not yet finished for this range in the file. If so, | ||
621 | * that extent will have a csum cached, and it will insert | ||
622 | * the sum after all the blocks in the extent are fully | ||
623 | * on disk. So, look for an ordered extent and use the | ||
624 | * sum if found. | ||
625 | */ | ||
626 | ret = btrfs_find_ordered_sum(inode, start, &csum); | ||
627 | if (ret == 0) | ||
628 | goto found; | ||
629 | |||
630 | ret = PTR_ERR(item); | 633 | ret = PTR_ERR(item); |
631 | /* a csum that isn't present is a preallocated region. */ | 634 | /* a csum that isn't present is a preallocated region. */ |
632 | if (ret == -ENOENT || ret == -EFBIG) | 635 | if (ret == -ENOENT || ret == -EFBIG) |
@@ -641,7 +644,6 @@ int btrfs_readpage_io_hook(struct page *page, u64 start, u64 end) | |||
641 | found: | 644 | found: |
642 | set_state_private(io_tree, start, csum); | 645 | set_state_private(io_tree, start, csum); |
643 | out: | 646 | out: |
644 | mutex_unlock(&BTRFS_I(inode)->csum_mutex); | ||
645 | if (path) | 647 | if (path) |
646 | btrfs_free_path(path); | 648 | btrfs_free_path(path); |
647 | return ret; | 649 | return ret; |
@@ -1375,7 +1377,7 @@ again: | |||
1375 | } | 1377 | } |
1376 | if (!PageUptodate(page)) { | 1378 | if (!PageUptodate(page)) { |
1377 | ret = -EIO; | 1379 | ret = -EIO; |
1378 | goto out; | 1380 | goto out_unlock; |
1379 | } | 1381 | } |
1380 | } | 1382 | } |
1381 | wait_on_page_writeback(page); | 1383 | wait_on_page_writeback(page); |
@@ -1406,6 +1408,7 @@ again: | |||
1406 | set_page_dirty(page); | 1408 | set_page_dirty(page); |
1407 | unlock_extent(io_tree, page_start, page_end, GFP_NOFS); | 1409 | unlock_extent(io_tree, page_start, page_end, GFP_NOFS); |
1408 | 1410 | ||
1411 | out_unlock: | ||
1409 | unlock_page(page); | 1412 | unlock_page(page); |
1410 | page_cache_release(page); | 1413 | page_cache_release(page); |
1411 | out: | 1414 | out: |
diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c index b695f5b29c45..e42fd233e04c 100644 --- a/fs/btrfs/ordered-data.c +++ b/fs/btrfs/ordered-data.c | |||
@@ -557,6 +557,7 @@ int btrfs_find_ordered_sum(struct inode *inode, u64 offset, u32 *sum) | |||
557 | } | 557 | } |
558 | out: | 558 | out: |
559 | mutex_unlock(&tree->mutex); | 559 | mutex_unlock(&tree->mutex); |
560 | btrfs_put_ordered_extent(ordered); | ||
560 | return ret; | 561 | return ret; |
561 | } | 562 | } |
562 | 563 | ||