forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-09 958e46acc8e900e8569dd467c1af9b8d2d019394
kernel/fs/ext4/inline.c
....@@ -35,6 +35,9 @@
3535 struct ext4_inode *raw_inode;
3636 int free, min_offs;
3737
38
+ if (!EXT4_INODE_HAS_XATTR_SPACE(inode))
39
+ return 0;
40
+
3841 min_offs = EXT4_SB(inode->i_sb)->s_inode_size -
3942 EXT4_GOOD_OLD_INODE_SIZE -
4043 EXT4_I(inode)->i_extra_isize -
....@@ -99,9 +102,9 @@
99102
100103 error = ext4_get_inode_loc(inode, &iloc);
101104 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);
105108 return 0;
106109 }
107110
....@@ -277,7 +280,7 @@
277280 len = 0;
278281 }
279282
280
- /* Insert the the xttr entry. */
283
+ /* Insert the xttr entry. */
281284 i.value = value;
282285 i.value_len = len;
283286
....@@ -355,7 +358,7 @@
355358 if (error)
356359 goto out;
357360
358
- /* Update the xttr entry. */
361
+ /* Update the xattr entry. */
359362 i.value = value;
360363 i.value_len = len;
361364
....@@ -747,18 +750,13 @@
747750 void *kaddr;
748751 struct ext4_iloc iloc;
749752
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;
756755
757756 ret = ext4_get_inode_loc(inode, &iloc);
758757 if (ret) {
759758 ext4_std_error(inode->i_sb, ret);
760
- copied = 0;
761
- goto out;
759
+ return ret;
762760 }
763761
764762 ext4_write_lock_xattr(inode, &no_expand);
....@@ -771,7 +769,7 @@
771769 (void) ext4_find_inline_data_nolock(inode);
772770
773771 kaddr = kmap_atomic(page);
774
- ext4_write_inline_data(inode, &iloc, kaddr, pos, len);
772
+ ext4_write_inline_data(inode, &iloc, kaddr, pos, copied);
775773 kunmap_atomic(kaddr);
776774 SetPageUptodate(page);
777775 /* clear page dirty so that writepages wouldn't work for us. */
....@@ -780,7 +778,7 @@
780778 ext4_write_unlock_xattr(inode, &no_expand);
781779 brelse(iloc.bh);
782780 mark_inode_dirty(inode);
783
-out:
781
+
784782 return copied;
785783 }
786784
....@@ -869,7 +867,7 @@
869867
870868 /*
871869 * 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
873871 * the page and make it uptodate, and start the journal.
874872 * Otherwise read the page, makes it dirty so that it can be
875873 * handle in writepages(the i_disksize update is left to the
....@@ -1160,7 +1158,6 @@
11601158 {
11611159 int err, csum_size = 0, header_size = 0;
11621160 struct ext4_dir_entry_2 *de;
1163
- struct ext4_dir_entry_tail *t;
11641161 void *target = dir_block->b_data;
11651162
11661163 /*
....@@ -1186,13 +1183,11 @@
11861183 inline_size - EXT4_INLINE_DOTDOT_SIZE + header_size,
11871184 inode->i_sb->s_blocksize - csum_size);
11881185
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);
11941189 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);
11961191 if (err)
11971192 return err;
11981193 set_buffer_verified(dir_block);
....@@ -1291,7 +1286,7 @@
12911286 int ext4_try_add_inline_entry(handle_t *handle, struct ext4_filename *fname,
12921287 struct inode *dir, struct inode *inode)
12931288 {
1294
- int ret, inline_size, no_expand;
1289
+ int ret, ret2, inline_size, no_expand;
12951290 void *inline_start;
12961291 struct ext4_iloc iloc;
12971292
....@@ -1345,7 +1340,9 @@
13451340
13461341 out:
13471342 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;
13491346 brelse(iloc.bh);
13501347 return ret;
13511348 }
....@@ -1355,11 +1352,11 @@
13551352 * inlined dir. It returns the number directory entries loaded
13561353 * into the tree. If there is an error it is returned in err.
13571354 */
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)
13631360 {
13641361 int err = 0, count = 0;
13651362 unsigned int parent_ino;
....@@ -1740,7 +1737,7 @@
17401737 if (err)
17411738 goto out;
17421739
1743
- err = ext4_generic_delete_entry(handle, dir, de_del, 0, bh,
1740
+ err = ext4_generic_delete_entry(dir, de_del, 0, bh,
17441741 inline_start, inline_size, 0);
17451742 if (err)
17461743 goto out;
....@@ -1793,18 +1790,20 @@
17931790 void *inline_pos;
17941791 unsigned int offset;
17951792 struct ext4_dir_entry_2 *de;
1796
- bool ret = true;
1793
+ bool ret = false;
17971794
17981795 err = ext4_get_inode_loc(dir, &iloc);
17991796 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;
18031801 }
18041802
18051803 down_read(&EXT4_I(dir)->xattr_sem);
18061804 if (!ext4_has_inline_data(dir)) {
18071805 *has_inline_data = 0;
1806
+ ret = true;
18081807 goto out;
18091808 }
18101809
....@@ -1813,7 +1812,6 @@
18131812 ext4_warning(dir->i_sb,
18141813 "bad inline directory (dir #%lu) - no `..'",
18151814 dir->i_ino);
1816
- ret = true;
18171815 goto out;
18181816 }
18191817
....@@ -1832,16 +1830,15 @@
18321830 dir->i_ino, le32_to_cpu(de->inode),
18331831 le16_to_cpu(de->rec_len), de->name_len,
18341832 inline_size);
1835
- ret = true;
18361833 goto out;
18371834 }
18381835 if (le32_to_cpu(de->inode)) {
1839
- ret = false;
18401836 goto out;
18411837 }
18421838 offset += ext4_rec_len_from_disk(de->rec_len, inline_size);
18431839 }
18441840
1841
+ ret = true;
18451842 out:
18461843 up_read(&EXT4_I(dir)->xattr_sem);
18471844 brelse(iloc.bh);
....@@ -1889,47 +1886,6 @@
18891886 out:
18901887 up_read(&EXT4_I(inode)->xattr_sem);
18911888 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);
19331889 }
19341890
19351891 int ext4_inline_data_truncate(struct inode *inode, int *has_inline)
....@@ -2040,6 +1996,18 @@
20401996 if (!ext4_has_inline_data(inode)) {
20411997 ext4_clear_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA);
20421998 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;
20432011 }
20442012
20452013 needed_blocks = ext4_writepage_trans_blocks(inode);