diff options
Diffstat (limited to 'fs/ext4/inline.c')
-rw-r--r-- | fs/ext4/inline.c | 35 |
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 | ||
1808 | int ext4_inline_data_fiemap(struct inode *inode, | 1812 | int 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); |
1837 | out: | 1848 | out: |
1838 | up_read(&EXT4_I(inode)->xattr_sem); | 1849 | up_read(&EXT4_I(inode)->xattr_sem); |