aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/inline.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ext4/inline.c')
-rw-r--r--fs/ext4/inline.c35
1 files changed, 23 insertions, 12 deletions
diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c
index 3ea62695abce..4b143febf21f 100644
--- a/fs/ext4/inline.c
+++ b/fs/ext4/inline.c
@@ -811,8 +811,11 @@ static int ext4_da_convert_inline_data_to_extent(struct address_space *mapping,
811 ret = __block_write_begin(page, 0, inline_size, 811 ret = __block_write_begin(page, 0, inline_size,
812 ext4_da_get_block_prep); 812 ext4_da_get_block_prep);
813 if (ret) { 813 if (ret) {
814 up_read(&EXT4_I(inode)->xattr_sem);
815 unlock_page(page);
816 page_cache_release(page);
814 ext4_truncate_failed_write(inode); 817 ext4_truncate_failed_write(inode);
815 goto out; 818 return ret;
816 } 819 }
817 820
818 SetPageDirty(page); 821 SetPageDirty(page);
@@ -870,6 +873,12 @@ retry_journal:
870 goto out_journal; 873 goto out_journal;
871 } 874 }
872 875
876 /*
877 * We cannot recurse into the filesystem as the transaction
878 * is already started.
879 */
880 flags |= AOP_FLAG_NOFS;
881
873 if (ret == -ENOSPC) { 882 if (ret == -ENOSPC) {
874 ret = ext4_da_convert_inline_data_to_extent(mapping, 883 ret = ext4_da_convert_inline_data_to_extent(mapping,
875 inode, 884 inode,
@@ -882,11 +891,6 @@ retry_journal:
882 goto out; 891 goto out;
883 } 892 }
884 893
885 /*
886 * We cannot recurse into the filesystem as the transaction
887 * is already started.
888 */
889 flags |= AOP_FLAG_NOFS;
890 894
891 page = grab_cache_page_write_begin(mapping, 0, flags); 895 page = grab_cache_page_write_begin(mapping, 0, flags);
892 if (!page) { 896 if (!page) {
@@ -1807,11 +1811,12 @@ int ext4_destroy_inline_data(handle_t *handle, struct inode *inode)
1807 1811
1808int ext4_inline_data_fiemap(struct inode *inode, 1812int ext4_inline_data_fiemap(struct inode *inode,
1809 struct fiemap_extent_info *fieinfo, 1813 struct fiemap_extent_info *fieinfo,
1810 int *has_inline) 1814 int *has_inline, __u64 start, __u64 len)
1811{ 1815{
1812 __u64 physical = 0; 1816 __u64 physical = 0;
1813 __u64 length; 1817 __u64 inline_len;
1814 __u32 flags = FIEMAP_EXTENT_DATA_INLINE | FIEMAP_EXTENT_LAST; 1818 __u32 flags = FIEMAP_EXTENT_DATA_INLINE | FIEMAP_EXTENT_NOT_ALIGNED |
1819 FIEMAP_EXTENT_LAST;
1815 int error = 0; 1820 int error = 0;
1816 struct ext4_iloc iloc; 1821 struct ext4_iloc iloc;
1817 1822
@@ -1820,6 +1825,13 @@ int ext4_inline_data_fiemap(struct inode *inode,
1820 *has_inline = 0; 1825 *has_inline = 0;
1821 goto out; 1826 goto out;
1822 } 1827 }
1828 inline_len = min_t(size_t, ext4_get_inline_size(inode),
1829 i_size_read(inode));
1830 if (start >= inline_len)
1831 goto out;
1832 if (start + len < inline_len)
1833 inline_len = start + len;
1834 inline_len -= start;
1823 1835
1824 error = ext4_get_inode_loc(inode, &iloc); 1836 error = ext4_get_inode_loc(inode, &iloc);
1825 if (error) 1837 if (error)
@@ -1828,11 +1840,10 @@ int ext4_inline_data_fiemap(struct inode *inode,
1828 physical = (__u64)iloc.bh->b_blocknr << inode->i_sb->s_blocksize_bits; 1840 physical = (__u64)iloc.bh->b_blocknr << inode->i_sb->s_blocksize_bits;
1829 physical += (char *)ext4_raw_inode(&iloc) - iloc.bh->b_data; 1841 physical += (char *)ext4_raw_inode(&iloc) - iloc.bh->b_data;
1830 physical += offsetof(struct ext4_inode, i_block); 1842 physical += offsetof(struct ext4_inode, i_block);
1831 length = i_size_read(inode);
1832 1843
1833 if (physical) 1844 if (physical)
1834 error = fiemap_fill_next_extent(fieinfo, 0, physical, 1845 error = fiemap_fill_next_extent(fieinfo, start, physical,
1835 length, flags); 1846 inline_len, flags);
1836 brelse(iloc.bh); 1847 brelse(iloc.bh);
1837out: 1848out:
1838 up_read(&EXT4_I(inode)->xattr_sem); 1849 up_read(&EXT4_I(inode)->xattr_sem);