diff options
-rw-r--r-- | fs/ext4/extents.c | 49 |
1 files changed, 35 insertions, 14 deletions
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 4e2bdc26b85c..ca62d748cc65 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c | |||
@@ -3688,6 +3688,7 @@ static int ext4_ext_fiemap_cb(struct inode *inode, struct ext4_ext_path *path, | |||
3688 | pgoff_t last_offset; | 3688 | pgoff_t last_offset; |
3689 | pgoff_t offset; | 3689 | pgoff_t offset; |
3690 | pgoff_t index; | 3690 | pgoff_t index; |
3691 | pgoff_t start_index = 0; | ||
3691 | struct page **pages = NULL; | 3692 | struct page **pages = NULL; |
3692 | struct buffer_head *bh = NULL; | 3693 | struct buffer_head *bh = NULL; |
3693 | struct buffer_head *head = NULL; | 3694 | struct buffer_head *head = NULL; |
@@ -3714,39 +3715,57 @@ out: | |||
3714 | kfree(pages); | 3715 | kfree(pages); |
3715 | return EXT_CONTINUE; | 3716 | return EXT_CONTINUE; |
3716 | } | 3717 | } |
3718 | index = 0; | ||
3717 | 3719 | ||
3720 | next_page: | ||
3718 | /* Try to find the 1st mapped buffer. */ | 3721 | /* Try to find the 1st mapped buffer. */ |
3719 | end = ((__u64)pages[0]->index << PAGE_SHIFT) >> | 3722 | end = ((__u64)pages[index]->index << PAGE_SHIFT) >> |
3720 | blksize_bits; | 3723 | blksize_bits; |
3721 | if (!page_has_buffers(pages[0])) | 3724 | if (!page_has_buffers(pages[index])) |
3722 | goto out; | 3725 | goto out; |
3723 | head = page_buffers(pages[0]); | 3726 | head = page_buffers(pages[index]); |
3724 | if (!head) | 3727 | if (!head) |
3725 | goto out; | 3728 | goto out; |
3726 | 3729 | ||
3730 | index++; | ||
3727 | bh = head; | 3731 | bh = head; |
3728 | do { | 3732 | do { |
3729 | if (buffer_mapped(bh)) { | 3733 | if (end >= newex->ec_block + |
3734 | newex->ec_len) | ||
3735 | /* The buffer is out of | ||
3736 | * the request range. | ||
3737 | */ | ||
3738 | goto out; | ||
3739 | |||
3740 | if (buffer_mapped(bh) && | ||
3741 | end >= newex->ec_block) { | ||
3742 | start_index = index - 1; | ||
3730 | /* get the 1st mapped buffer. */ | 3743 | /* get the 1st mapped buffer. */ |
3731 | if (end > newex->ec_block + | ||
3732 | newex->ec_len) | ||
3733 | /* The buffer is out of | ||
3734 | * the request range. | ||
3735 | */ | ||
3736 | goto out; | ||
3737 | goto found_mapped_buffer; | 3744 | goto found_mapped_buffer; |
3738 | } | 3745 | } |
3746 | |||
3739 | bh = bh->b_this_page; | 3747 | bh = bh->b_this_page; |
3740 | end++; | 3748 | end++; |
3741 | } while (bh != head); | 3749 | } while (bh != head); |
3742 | 3750 | ||
3743 | /* No mapped buffer found. */ | 3751 | /* No mapped buffer in the range found in this page, |
3744 | goto out; | 3752 | * We need to look up next page. |
3753 | */ | ||
3754 | if (index >= ret) { | ||
3755 | /* There is no page left, but we need to limit | ||
3756 | * newex->ec_len. | ||
3757 | */ | ||
3758 | newex->ec_len = end - newex->ec_block; | ||
3759 | goto out; | ||
3760 | } | ||
3761 | goto next_page; | ||
3745 | } else { | 3762 | } else { |
3746 | /*Find contiguous delayed buffers. */ | 3763 | /*Find contiguous delayed buffers. */ |
3747 | if (ret > 0 && pages[0]->index == last_offset) | 3764 | if (ret > 0 && pages[0]->index == last_offset) |
3748 | head = page_buffers(pages[0]); | 3765 | head = page_buffers(pages[0]); |
3749 | bh = head; | 3766 | bh = head; |
3767 | index = 1; | ||
3768 | start_index = 0; | ||
3750 | } | 3769 | } |
3751 | 3770 | ||
3752 | found_mapped_buffer: | 3771 | found_mapped_buffer: |
@@ -3769,7 +3788,7 @@ found_mapped_buffer: | |||
3769 | end++; | 3788 | end++; |
3770 | } while (bh != head); | 3789 | } while (bh != head); |
3771 | 3790 | ||
3772 | for (index = 1; index < ret; index++) { | 3791 | for (; index < ret; index++) { |
3773 | if (!page_has_buffers(pages[index])) { | 3792 | if (!page_has_buffers(pages[index])) { |
3774 | bh = NULL; | 3793 | bh = NULL; |
3775 | break; | 3794 | break; |
@@ -3779,8 +3798,10 @@ found_mapped_buffer: | |||
3779 | bh = NULL; | 3798 | bh = NULL; |
3780 | break; | 3799 | break; |
3781 | } | 3800 | } |
3801 | |||
3782 | if (pages[index]->index != | 3802 | if (pages[index]->index != |
3783 | pages[0]->index + index) { | 3803 | pages[start_index]->index + index |
3804 | - start_index) { | ||
3784 | /* Blocks are not contiguous. */ | 3805 | /* Blocks are not contiguous. */ |
3785 | bh = NULL; | 3806 | bh = NULL; |
3786 | break; | 3807 | break; |