aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ext4/extents.c187
1 files changed, 148 insertions, 39 deletions
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index d16f6b5a140b..9ea1bc64ca6d 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -3775,6 +3775,7 @@ int ext4_convert_unwritten_extents(struct inode *inode, loff_t offset,
3775 } 3775 }
3776 return ret > 0 ? ret2 : ret; 3776 return ret > 0 ? ret2 : ret;
3777} 3777}
3778
3778/* 3779/*
3779 * Callback function called for each extent to gather FIEMAP information. 3780 * Callback function called for each extent to gather FIEMAP information.
3780 */ 3781 */
@@ -3782,38 +3783,162 @@ static int ext4_ext_fiemap_cb(struct inode *inode, struct ext4_ext_path *path,
3782 struct ext4_ext_cache *newex, struct ext4_extent *ex, 3783 struct ext4_ext_cache *newex, struct ext4_extent *ex,
3783 void *data) 3784 void *data)
3784{ 3785{
3785 struct fiemap_extent_info *fieinfo = data;
3786 unsigned char blksize_bits = inode->i_sb->s_blocksize_bits;
3787 __u64 logical; 3786 __u64 logical;
3788 __u64 physical; 3787 __u64 physical;
3789 __u64 length; 3788 __u64 length;
3789 loff_t size;
3790 __u32 flags = 0; 3790 __u32 flags = 0;
3791 int error; 3791 int ret = 0;
3792 struct fiemap_extent_info *fieinfo = data;
3793 unsigned char blksize_bits;
3792 3794
3793 logical = (__u64)newex->ec_block << blksize_bits; 3795 blksize_bits = inode->i_sb->s_blocksize_bits;
3796 logical = (__u64)newex->ec_block << blksize_bits;
3794 3797
3795 if (newex->ec_start == 0) { 3798 if (newex->ec_start == 0) {
3796 pgoff_t offset; 3799 /*
3797 struct page *page; 3800 * No extent in extent-tree contains block @newex->ec_start,
3801 * then the block may stay in 1)a hole or 2)delayed-extent.
3802 *
3803 * Holes or delayed-extents are processed as follows.
3804 * 1. lookup dirty pages with specified range in pagecache.
3805 * If no page is got, then there is no delayed-extent and
3806 * return with EXT_CONTINUE.
3807 * 2. find the 1st mapped buffer,
3808 * 3. check if the mapped buffer is both in the request range
3809 * and a delayed buffer. If not, there is no delayed-extent,
3810 * then return.
3811 * 4. a delayed-extent is found, the extent will be collected.
3812 */
3813 ext4_lblk_t end = 0;
3814 pgoff_t last_offset;
3815 pgoff_t offset;
3816 pgoff_t index;
3817 struct page **pages = NULL;
3798 struct buffer_head *bh = NULL; 3818 struct buffer_head *bh = NULL;
3819 struct buffer_head *head = NULL;
3820 unsigned int nr_pages = PAGE_SIZE / sizeof(struct page *);
3821
3822 pages = kmalloc(PAGE_SIZE, GFP_KERNEL);
3823 if (pages == NULL)
3824 return -ENOMEM;
3799 3825
3800 offset = logical >> PAGE_SHIFT; 3826 offset = logical >> PAGE_SHIFT;
3801 page = find_get_page(inode->i_mapping, offset); 3827repeat:
3802 if (!page || !page_has_buffers(page)) 3828 last_offset = offset;
3803 return EXT_CONTINUE; 3829 head = NULL;
3830 ret = find_get_pages_tag(inode->i_mapping, &offset,
3831 PAGECACHE_TAG_DIRTY, nr_pages, pages);
3832
3833 if (!(flags & FIEMAP_EXTENT_DELALLOC)) {
3834 /* First time, try to find a mapped buffer. */
3835 if (ret == 0) {
3836out:
3837 for (index = 0; index < ret; index++)
3838 page_cache_release(pages[index]);
3839 /* just a hole. */
3840 kfree(pages);
3841 return EXT_CONTINUE;
3842 }
3804 3843
3805 bh = page_buffers(page); 3844 /* Try to find the 1st mapped buffer. */
3845 end = ((__u64)pages[0]->index << PAGE_SHIFT) >>
3846 blksize_bits;
3847 if (!page_has_buffers(pages[0]))
3848 goto out;
3849 head = page_buffers(pages[0]);
3850 if (!head)
3851 goto out;
3806 3852
3807 if (!bh) 3853 bh = head;
3808 return EXT_CONTINUE; 3854 do {
3855 if (buffer_mapped(bh)) {
3856 /* get the 1st mapped buffer. */
3857 if (end > newex->ec_block +
3858 newex->ec_len)
3859 /* The buffer is out of
3860 * the request range.
3861 */
3862 goto out;
3863 goto found_mapped_buffer;
3864 }
3865 bh = bh->b_this_page;
3866 end++;
3867 } while (bh != head);
3809 3868
3810 if (buffer_delay(bh)) { 3869 /* No mapped buffer found. */
3811 flags |= FIEMAP_EXTENT_DELALLOC; 3870 goto out;
3812 page_cache_release(page);
3813 } else { 3871 } else {
3814 page_cache_release(page); 3872 /*Find contiguous delayed buffers. */
3815 return EXT_CONTINUE; 3873 if (ret > 0 && pages[0]->index == last_offset)
3874 head = page_buffers(pages[0]);
3875 bh = head;
3876 }
3877
3878found_mapped_buffer:
3879 if (bh != NULL && buffer_delay(bh)) {
3880 /* 1st or contiguous delayed buffer found. */
3881 if (!(flags & FIEMAP_EXTENT_DELALLOC)) {
3882 /*
3883 * 1st delayed buffer found, record
3884 * the start of extent.
3885 */
3886 flags |= FIEMAP_EXTENT_DELALLOC;
3887 newex->ec_block = end;
3888 logical = (__u64)end << blksize_bits;
3889 }
3890 /* Find contiguous delayed buffers. */
3891 do {
3892 if (!buffer_delay(bh))
3893 goto found_delayed_extent;
3894 bh = bh->b_this_page;
3895 end++;
3896 } while (bh != head);
3897
3898 for (index = 1; index < ret; index++) {
3899 if (!page_has_buffers(pages[index])) {
3900 bh = NULL;
3901 break;
3902 }
3903 head = page_buffers(pages[index]);
3904 if (!head) {
3905 bh = NULL;
3906 break;
3907 }
3908 if (pages[index]->index !=
3909 pages[0]->index + index) {
3910 /* Blocks are not contiguous. */
3911 bh = NULL;
3912 break;
3913 }
3914 bh = head;
3915 do {
3916 if (!buffer_delay(bh))
3917 /* Delayed-extent ends. */
3918 goto found_delayed_extent;
3919 bh = bh->b_this_page;
3920 end++;
3921 } while (bh != head);
3922 }
3923 } else if (!(flags & FIEMAP_EXTENT_DELALLOC))
3924 /* a hole found. */
3925 goto out;
3926
3927found_delayed_extent:
3928 newex->ec_len = min(end - newex->ec_block,
3929 (ext4_lblk_t)EXT_INIT_MAX_LEN);
3930 if (ret == nr_pages && bh != NULL &&
3931 newex->ec_len < EXT_INIT_MAX_LEN &&
3932 buffer_delay(bh)) {
3933 /* Have not collected an extent and continue. */
3934 for (index = 0; index < ret; index++)
3935 page_cache_release(pages[index]);
3936 goto repeat;
3816 } 3937 }
3938
3939 for (index = 0; index < ret; index++)
3940 page_cache_release(pages[index]);
3941 kfree(pages);
3817 } 3942 }
3818 3943
3819 physical = (__u64)newex->ec_start << blksize_bits; 3944 physical = (__u64)newex->ec_start << blksize_bits;
@@ -3822,32 +3947,16 @@ static int ext4_ext_fiemap_cb(struct inode *inode, struct ext4_ext_path *path,
3822 if (ex && ext4_ext_is_uninitialized(ex)) 3947 if (ex && ext4_ext_is_uninitialized(ex))
3823 flags |= FIEMAP_EXTENT_UNWRITTEN; 3948 flags |= FIEMAP_EXTENT_UNWRITTEN;
3824 3949
3825 /* 3950 size = i_size_read(inode);
3826 * If this extent reaches EXT_MAX_BLOCK, it must be last. 3951 if (logical + length >= size)
3827 *
3828 * Or if ext4_ext_next_allocated_block is EXT_MAX_BLOCK,
3829 * this also indicates no more allocated blocks.
3830 *
3831 * XXX this might miss a single-block extent at EXT_MAX_BLOCK
3832 */
3833 if (ext4_ext_next_allocated_block(path) == EXT_MAX_BLOCK ||
3834 newex->ec_block + newex->ec_len - 1 == EXT_MAX_BLOCK) {
3835 loff_t size = i_size_read(inode);
3836 loff_t bs = EXT4_BLOCK_SIZE(inode->i_sb);
3837
3838 flags |= FIEMAP_EXTENT_LAST; 3952 flags |= FIEMAP_EXTENT_LAST;
3839 if ((flags & FIEMAP_EXTENT_DELALLOC) &&
3840 logical+length > size)
3841 length = (size - logical + bs - 1) & ~(bs-1);
3842 }
3843 3953
3844 error = fiemap_fill_next_extent(fieinfo, logical, physical, 3954 ret = fiemap_fill_next_extent(fieinfo, logical, physical,
3845 length, flags); 3955 length, flags);
3846 if (error < 0) 3956 if (ret < 0)
3847 return error; 3957 return ret;
3848 if (error == 1) 3958 if (ret == 1)
3849 return EXT_BREAK; 3959 return EXT_BREAK;
3850
3851 return EXT_CONTINUE; 3960 return EXT_CONTINUE;
3852} 3961}
3853 3962