aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ext4/extents.c49
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
3720next_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
3752found_mapped_buffer: 3771found_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;