.. | .. |
---|
35 | 35 | struct ext4_inode *raw_inode; |
---|
36 | 36 | int free, min_offs; |
---|
37 | 37 | |
---|
| 38 | + if (!EXT4_INODE_HAS_XATTR_SPACE(inode)) |
---|
| 39 | + return 0; |
---|
| 40 | + |
---|
38 | 41 | min_offs = EXT4_SB(inode->i_sb)->s_inode_size - |
---|
39 | 42 | EXT4_GOOD_OLD_INODE_SIZE - |
---|
40 | 43 | EXT4_I(inode)->i_extra_isize - |
---|
.. | .. |
---|
99 | 102 | |
---|
100 | 103 | error = ext4_get_inode_loc(inode, &iloc); |
---|
101 | 104 | if (error) { |
---|
102 | | - ext4_error_inode(inode, __func__, __LINE__, 0, |
---|
103 | | - "can't get inode location %lu", |
---|
104 | | - inode->i_ino); |
---|
| 105 | + ext4_error_inode_err(inode, __func__, __LINE__, 0, -error, |
---|
| 106 | + "can't get inode location %lu", |
---|
| 107 | + inode->i_ino); |
---|
105 | 108 | return 0; |
---|
106 | 109 | } |
---|
107 | 110 | |
---|
.. | .. |
---|
277 | 280 | len = 0; |
---|
278 | 281 | } |
---|
279 | 282 | |
---|
280 | | - /* Insert the the xttr entry. */ |
---|
| 283 | + /* Insert the xttr entry. */ |
---|
281 | 284 | i.value = value; |
---|
282 | 285 | i.value_len = len; |
---|
283 | 286 | |
---|
.. | .. |
---|
355 | 358 | if (error) |
---|
356 | 359 | goto out; |
---|
357 | 360 | |
---|
358 | | - /* Update the xttr entry. */ |
---|
| 361 | + /* Update the xattr entry. */ |
---|
359 | 362 | i.value = value; |
---|
360 | 363 | i.value_len = len; |
---|
361 | 364 | |
---|
.. | .. |
---|
747 | 750 | void *kaddr; |
---|
748 | 751 | struct ext4_iloc iloc; |
---|
749 | 752 | |
---|
750 | | - if (unlikely(copied < len)) { |
---|
751 | | - if (!PageUptodate(page)) { |
---|
752 | | - copied = 0; |
---|
753 | | - goto out; |
---|
754 | | - } |
---|
755 | | - } |
---|
| 753 | + if (unlikely(copied < len) && !PageUptodate(page)) |
---|
| 754 | + return 0; |
---|
756 | 755 | |
---|
757 | 756 | ret = ext4_get_inode_loc(inode, &iloc); |
---|
758 | 757 | if (ret) { |
---|
759 | 758 | ext4_std_error(inode->i_sb, ret); |
---|
760 | | - copied = 0; |
---|
761 | | - goto out; |
---|
| 759 | + return ret; |
---|
762 | 760 | } |
---|
763 | 761 | |
---|
764 | 762 | ext4_write_lock_xattr(inode, &no_expand); |
---|
.. | .. |
---|
771 | 769 | (void) ext4_find_inline_data_nolock(inode); |
---|
772 | 770 | |
---|
773 | 771 | kaddr = kmap_atomic(page); |
---|
774 | | - ext4_write_inline_data(inode, &iloc, kaddr, pos, len); |
---|
| 772 | + ext4_write_inline_data(inode, &iloc, kaddr, pos, copied); |
---|
775 | 773 | kunmap_atomic(kaddr); |
---|
776 | 774 | SetPageUptodate(page); |
---|
777 | 775 | /* clear page dirty so that writepages wouldn't work for us. */ |
---|
.. | .. |
---|
780 | 778 | ext4_write_unlock_xattr(inode, &no_expand); |
---|
781 | 779 | brelse(iloc.bh); |
---|
782 | 780 | mark_inode_dirty(inode); |
---|
783 | | -out: |
---|
| 781 | + |
---|
784 | 782 | return copied; |
---|
785 | 783 | } |
---|
786 | 784 | |
---|
.. | .. |
---|
869 | 867 | |
---|
870 | 868 | /* |
---|
871 | 869 | * Prepare the write for the inline data. |
---|
872 | | - * If the the data can be written into the inode, we just read |
---|
| 870 | + * If the data can be written into the inode, we just read |
---|
873 | 871 | * the page and make it uptodate, and start the journal. |
---|
874 | 872 | * Otherwise read the page, makes it dirty so that it can be |
---|
875 | 873 | * handle in writepages(the i_disksize update is left to the |
---|
.. | .. |
---|
1160 | 1158 | { |
---|
1161 | 1159 | int err, csum_size = 0, header_size = 0; |
---|
1162 | 1160 | struct ext4_dir_entry_2 *de; |
---|
1163 | | - struct ext4_dir_entry_tail *t; |
---|
1164 | 1161 | void *target = dir_block->b_data; |
---|
1165 | 1162 | |
---|
1166 | 1163 | /* |
---|
.. | .. |
---|
1186 | 1183 | inline_size - EXT4_INLINE_DOTDOT_SIZE + header_size, |
---|
1187 | 1184 | inode->i_sb->s_blocksize - csum_size); |
---|
1188 | 1185 | |
---|
1189 | | - if (csum_size) { |
---|
1190 | | - t = EXT4_DIRENT_TAIL(dir_block->b_data, |
---|
1191 | | - inode->i_sb->s_blocksize); |
---|
1192 | | - initialize_dirent_tail(t, inode->i_sb->s_blocksize); |
---|
1193 | | - } |
---|
| 1186 | + if (csum_size) |
---|
| 1187 | + ext4_initialize_dirent_tail(dir_block, |
---|
| 1188 | + inode->i_sb->s_blocksize); |
---|
1194 | 1189 | set_buffer_uptodate(dir_block); |
---|
1195 | | - err = ext4_handle_dirty_dirent_node(handle, inode, dir_block); |
---|
| 1190 | + err = ext4_handle_dirty_dirblock(handle, inode, dir_block); |
---|
1196 | 1191 | if (err) |
---|
1197 | 1192 | return err; |
---|
1198 | 1193 | set_buffer_verified(dir_block); |
---|
.. | .. |
---|
1291 | 1286 | int ext4_try_add_inline_entry(handle_t *handle, struct ext4_filename *fname, |
---|
1292 | 1287 | struct inode *dir, struct inode *inode) |
---|
1293 | 1288 | { |
---|
1294 | | - int ret, inline_size, no_expand; |
---|
| 1289 | + int ret, ret2, inline_size, no_expand; |
---|
1295 | 1290 | void *inline_start; |
---|
1296 | 1291 | struct ext4_iloc iloc; |
---|
1297 | 1292 | |
---|
.. | .. |
---|
1345 | 1340 | |
---|
1346 | 1341 | out: |
---|
1347 | 1342 | ext4_write_unlock_xattr(dir, &no_expand); |
---|
1348 | | - ext4_mark_inode_dirty(handle, dir); |
---|
| 1343 | + ret2 = ext4_mark_inode_dirty(handle, dir); |
---|
| 1344 | + if (unlikely(ret2 && !ret)) |
---|
| 1345 | + ret = ret2; |
---|
1349 | 1346 | brelse(iloc.bh); |
---|
1350 | 1347 | return ret; |
---|
1351 | 1348 | } |
---|
.. | .. |
---|
1355 | 1352 | * inlined dir. It returns the number directory entries loaded |
---|
1356 | 1353 | * into the tree. If there is an error it is returned in err. |
---|
1357 | 1354 | */ |
---|
1358 | | -int htree_inlinedir_to_tree(struct file *dir_file, |
---|
1359 | | - struct inode *dir, ext4_lblk_t block, |
---|
1360 | | - struct dx_hash_info *hinfo, |
---|
1361 | | - __u32 start_hash, __u32 start_minor_hash, |
---|
1362 | | - int *has_inline_data) |
---|
| 1355 | +int ext4_inlinedir_to_tree(struct file *dir_file, |
---|
| 1356 | + struct inode *dir, ext4_lblk_t block, |
---|
| 1357 | + struct dx_hash_info *hinfo, |
---|
| 1358 | + __u32 start_hash, __u32 start_minor_hash, |
---|
| 1359 | + int *has_inline_data) |
---|
1363 | 1360 | { |
---|
1364 | 1361 | int err = 0, count = 0; |
---|
1365 | 1362 | unsigned int parent_ino; |
---|
.. | .. |
---|
1740 | 1737 | if (err) |
---|
1741 | 1738 | goto out; |
---|
1742 | 1739 | |
---|
1743 | | - err = ext4_generic_delete_entry(handle, dir, de_del, 0, bh, |
---|
| 1740 | + err = ext4_generic_delete_entry(dir, de_del, 0, bh, |
---|
1744 | 1741 | inline_start, inline_size, 0); |
---|
1745 | 1742 | if (err) |
---|
1746 | 1743 | goto out; |
---|
.. | .. |
---|
1793 | 1790 | void *inline_pos; |
---|
1794 | 1791 | unsigned int offset; |
---|
1795 | 1792 | struct ext4_dir_entry_2 *de; |
---|
1796 | | - bool ret = true; |
---|
| 1793 | + bool ret = false; |
---|
1797 | 1794 | |
---|
1798 | 1795 | err = ext4_get_inode_loc(dir, &iloc); |
---|
1799 | 1796 | if (err) { |
---|
1800 | | - EXT4_ERROR_INODE(dir, "error %d getting inode %lu block", |
---|
1801 | | - err, dir->i_ino); |
---|
1802 | | - return true; |
---|
| 1797 | + EXT4_ERROR_INODE_ERR(dir, -err, |
---|
| 1798 | + "error %d getting inode %lu block", |
---|
| 1799 | + err, dir->i_ino); |
---|
| 1800 | + return false; |
---|
1803 | 1801 | } |
---|
1804 | 1802 | |
---|
1805 | 1803 | down_read(&EXT4_I(dir)->xattr_sem); |
---|
1806 | 1804 | if (!ext4_has_inline_data(dir)) { |
---|
1807 | 1805 | *has_inline_data = 0; |
---|
| 1806 | + ret = true; |
---|
1808 | 1807 | goto out; |
---|
1809 | 1808 | } |
---|
1810 | 1809 | |
---|
.. | .. |
---|
1813 | 1812 | ext4_warning(dir->i_sb, |
---|
1814 | 1813 | "bad inline directory (dir #%lu) - no `..'", |
---|
1815 | 1814 | dir->i_ino); |
---|
1816 | | - ret = true; |
---|
1817 | 1815 | goto out; |
---|
1818 | 1816 | } |
---|
1819 | 1817 | |
---|
.. | .. |
---|
1832 | 1830 | dir->i_ino, le32_to_cpu(de->inode), |
---|
1833 | 1831 | le16_to_cpu(de->rec_len), de->name_len, |
---|
1834 | 1832 | inline_size); |
---|
1835 | | - ret = true; |
---|
1836 | 1833 | goto out; |
---|
1837 | 1834 | } |
---|
1838 | 1835 | if (le32_to_cpu(de->inode)) { |
---|
1839 | | - ret = false; |
---|
1840 | 1836 | goto out; |
---|
1841 | 1837 | } |
---|
1842 | 1838 | offset += ext4_rec_len_from_disk(de->rec_len, inline_size); |
---|
1843 | 1839 | } |
---|
1844 | 1840 | |
---|
| 1841 | + ret = true; |
---|
1845 | 1842 | out: |
---|
1846 | 1843 | up_read(&EXT4_I(dir)->xattr_sem); |
---|
1847 | 1844 | brelse(iloc.bh); |
---|
.. | .. |
---|
1889 | 1886 | out: |
---|
1890 | 1887 | up_read(&EXT4_I(inode)->xattr_sem); |
---|
1891 | 1888 | return error; |
---|
1892 | | -} |
---|
1893 | | - |
---|
1894 | | -int ext4_inline_data_fiemap(struct inode *inode, |
---|
1895 | | - struct fiemap_extent_info *fieinfo, |
---|
1896 | | - int *has_inline, __u64 start, __u64 len) |
---|
1897 | | -{ |
---|
1898 | | - __u64 physical = 0; |
---|
1899 | | - __u64 inline_len; |
---|
1900 | | - __u32 flags = FIEMAP_EXTENT_DATA_INLINE | FIEMAP_EXTENT_NOT_ALIGNED | |
---|
1901 | | - FIEMAP_EXTENT_LAST; |
---|
1902 | | - int error = 0; |
---|
1903 | | - struct ext4_iloc iloc; |
---|
1904 | | - |
---|
1905 | | - down_read(&EXT4_I(inode)->xattr_sem); |
---|
1906 | | - if (!ext4_has_inline_data(inode)) { |
---|
1907 | | - *has_inline = 0; |
---|
1908 | | - goto out; |
---|
1909 | | - } |
---|
1910 | | - inline_len = min_t(size_t, ext4_get_inline_size(inode), |
---|
1911 | | - i_size_read(inode)); |
---|
1912 | | - if (start >= inline_len) |
---|
1913 | | - goto out; |
---|
1914 | | - if (start + len < inline_len) |
---|
1915 | | - inline_len = start + len; |
---|
1916 | | - inline_len -= start; |
---|
1917 | | - |
---|
1918 | | - error = ext4_get_inode_loc(inode, &iloc); |
---|
1919 | | - if (error) |
---|
1920 | | - goto out; |
---|
1921 | | - |
---|
1922 | | - physical = (__u64)iloc.bh->b_blocknr << inode->i_sb->s_blocksize_bits; |
---|
1923 | | - physical += (char *)ext4_raw_inode(&iloc) - iloc.bh->b_data; |
---|
1924 | | - physical += offsetof(struct ext4_inode, i_block); |
---|
1925 | | - |
---|
1926 | | - brelse(iloc.bh); |
---|
1927 | | -out: |
---|
1928 | | - up_read(&EXT4_I(inode)->xattr_sem); |
---|
1929 | | - if (physical) |
---|
1930 | | - error = fiemap_fill_next_extent(fieinfo, start, physical, |
---|
1931 | | - inline_len, flags); |
---|
1932 | | - return (error < 0 ? error : 0); |
---|
1933 | 1889 | } |
---|
1934 | 1890 | |
---|
1935 | 1891 | int ext4_inline_data_truncate(struct inode *inode, int *has_inline) |
---|
.. | .. |
---|
2040 | 1996 | if (!ext4_has_inline_data(inode)) { |
---|
2041 | 1997 | ext4_clear_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA); |
---|
2042 | 1998 | return 0; |
---|
| 1999 | + } else if (!ext4_test_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA)) { |
---|
| 2000 | + /* |
---|
| 2001 | + * Inode has inline data but EXT4_STATE_MAY_INLINE_DATA is |
---|
| 2002 | + * cleared. This means we are in the middle of moving of |
---|
| 2003 | + * inline data to delay allocated block. Just force writeout |
---|
| 2004 | + * here to finish conversion. |
---|
| 2005 | + */ |
---|
| 2006 | + error = filemap_flush(inode->i_mapping); |
---|
| 2007 | + if (error) |
---|
| 2008 | + return error; |
---|
| 2009 | + if (!ext4_has_inline_data(inode)) |
---|
| 2010 | + return 0; |
---|
2043 | 2011 | } |
---|
2044 | 2012 | |
---|
2045 | 2013 | needed_blocks = ext4_writepage_trans_blocks(inode); |
---|