aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/inline.c
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2015-02-10 14:35:36 -0500
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2015-02-10 14:35:36 -0500
commit4ba24fef3eb3b142197135223b90ced2f319cd53 (patch)
treea20c125b27740ec7b4c761b11d801108e1b316b2 /fs/ext4/inline.c
parent47c1ffb2b6b630894e9a16442611c056ab21c057 (diff)
parent98a4a59ee31a12105a2b84f5b8b515ac2cb208ef (diff)
Merge branch 'next' into for-linus
Prepare first round of input updates for 3.20.
Diffstat (limited to 'fs/ext4/inline.c')
-rw-r--r--fs/ext4/inline.c42
1 files changed, 27 insertions, 15 deletions
diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c
index bea662bd0ca6..4b143febf21f 100644
--- a/fs/ext4/inline.c
+++ b/fs/ext4/inline.c
@@ -594,6 +594,7 @@ retry:
594 if (ret) { 594 if (ret) {
595 unlock_page(page); 595 unlock_page(page);
596 page_cache_release(page); 596 page_cache_release(page);
597 page = NULL;
597 ext4_orphan_add(handle, inode); 598 ext4_orphan_add(handle, inode);
598 up_write(&EXT4_I(inode)->xattr_sem); 599 up_write(&EXT4_I(inode)->xattr_sem);
599 sem_held = 0; 600 sem_held = 0;
@@ -613,7 +614,8 @@ retry:
613 if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries)) 614 if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries))
614 goto retry; 615 goto retry;
615 616
616 block_commit_write(page, from, to); 617 if (page)
618 block_commit_write(page, from, to);
617out: 619out:
618 if (page) { 620 if (page) {
619 unlock_page(page); 621 unlock_page(page);
@@ -809,8 +811,11 @@ static int ext4_da_convert_inline_data_to_extent(struct address_space *mapping,
809 ret = __block_write_begin(page, 0, inline_size, 811 ret = __block_write_begin(page, 0, inline_size,
810 ext4_da_get_block_prep); 812 ext4_da_get_block_prep);
811 if (ret) { 813 if (ret) {
814 up_read(&EXT4_I(inode)->xattr_sem);
815 unlock_page(page);
816 page_cache_release(page);
812 ext4_truncate_failed_write(inode); 817 ext4_truncate_failed_write(inode);
813 goto out; 818 return ret;
814 } 819 }
815 820
816 SetPageDirty(page); 821 SetPageDirty(page);
@@ -868,6 +873,12 @@ retry_journal:
868 goto out_journal; 873 goto out_journal;
869 } 874 }
870 875
876 /*
877 * We cannot recurse into the filesystem as the transaction
878 * is already started.
879 */
880 flags |= AOP_FLAG_NOFS;
881
871 if (ret == -ENOSPC) { 882 if (ret == -ENOSPC) {
872 ret = ext4_da_convert_inline_data_to_extent(mapping, 883 ret = ext4_da_convert_inline_data_to_extent(mapping,
873 inode, 884 inode,
@@ -880,11 +891,6 @@ retry_journal:
880 goto out; 891 goto out;
881 } 892 }
882 893
883 /*
884 * We cannot recurse into the filesystem as the transaction
885 * is already started.
886 */
887 flags |= AOP_FLAG_NOFS;
888 894
889 page = grab_cache_page_write_begin(mapping, 0, flags); 895 page = grab_cache_page_write_begin(mapping, 0, flags);
890 if (!page) { 896 if (!page) {
@@ -1126,8 +1132,7 @@ static int ext4_finish_convert_inline_dir(handle_t *handle,
1126 memcpy((void *)de, buf + EXT4_INLINE_DOTDOT_SIZE, 1132 memcpy((void *)de, buf + EXT4_INLINE_DOTDOT_SIZE,
1127 inline_size - EXT4_INLINE_DOTDOT_SIZE); 1133 inline_size - EXT4_INLINE_DOTDOT_SIZE);
1128 1134
1129 if (EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb, 1135 if (ext4_has_metadata_csum(inode->i_sb))
1130 EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
1131 csum_size = sizeof(struct ext4_dir_entry_tail); 1136 csum_size = sizeof(struct ext4_dir_entry_tail);
1132 1137
1133 inode->i_size = inode->i_sb->s_blocksize; 1138 inode->i_size = inode->i_sb->s_blocksize;
@@ -1806,11 +1811,12 @@ int ext4_destroy_inline_data(handle_t *handle, struct inode *inode)
1806 1811
1807int ext4_inline_data_fiemap(struct inode *inode, 1812int ext4_inline_data_fiemap(struct inode *inode,
1808 struct fiemap_extent_info *fieinfo, 1813 struct fiemap_extent_info *fieinfo,
1809 int *has_inline) 1814 int *has_inline, __u64 start, __u64 len)
1810{ 1815{
1811 __u64 physical = 0; 1816 __u64 physical = 0;
1812 __u64 length; 1817 __u64 inline_len;
1813 __u32 flags = FIEMAP_EXTENT_DATA_INLINE | FIEMAP_EXTENT_LAST; 1818 __u32 flags = FIEMAP_EXTENT_DATA_INLINE | FIEMAP_EXTENT_NOT_ALIGNED |
1819 FIEMAP_EXTENT_LAST;
1814 int error = 0; 1820 int error = 0;
1815 struct ext4_iloc iloc; 1821 struct ext4_iloc iloc;
1816 1822
@@ -1819,6 +1825,13 @@ int ext4_inline_data_fiemap(struct inode *inode,
1819 *has_inline = 0; 1825 *has_inline = 0;
1820 goto out; 1826 goto out;
1821 } 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;
1822 1835
1823 error = ext4_get_inode_loc(inode, &iloc); 1836 error = ext4_get_inode_loc(inode, &iloc);
1824 if (error) 1837 if (error)
@@ -1827,11 +1840,10 @@ int ext4_inline_data_fiemap(struct inode *inode,
1827 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;
1828 physical += (char *)ext4_raw_inode(&iloc) - iloc.bh->b_data; 1841 physical += (char *)ext4_raw_inode(&iloc) - iloc.bh->b_data;
1829 physical += offsetof(struct ext4_inode, i_block); 1842 physical += offsetof(struct ext4_inode, i_block);
1830 length = i_size_read(inode);
1831 1843
1832 if (physical) 1844 if (physical)
1833 error = fiemap_fill_next_extent(fieinfo, 0, physical, 1845 error = fiemap_fill_next_extent(fieinfo, start, physical,
1834 length, flags); 1846 inline_len, flags);
1835 brelse(iloc.bh); 1847 brelse(iloc.bh);
1836out: 1848out:
1837 up_read(&EXT4_I(inode)->xattr_sem); 1849 up_read(&EXT4_I(inode)->xattr_sem);