hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/fs/ext4/inline.c
....@@ -33,7 +33,11 @@
3333 struct ext4_xattr_ibody_header *header;
3434 struct ext4_xattr_entry *entry;
3535 struct ext4_inode *raw_inode;
36
+ void *end;
3637 int free, min_offs;
38
+
39
+ if (!EXT4_INODE_HAS_XATTR_SPACE(inode))
40
+ return 0;
3741
3842 min_offs = EXT4_SB(inode->i_sb)->s_inode_size -
3943 EXT4_GOOD_OLD_INODE_SIZE -
....@@ -53,14 +57,23 @@
5357 raw_inode = ext4_raw_inode(iloc);
5458 header = IHDR(inode, raw_inode);
5559 entry = IFIRST(header);
60
+ end = (void *)raw_inode + EXT4_SB(inode->i_sb)->s_inode_size;
5661
5762 /* Compute min_offs. */
58
- for (; !IS_LAST_ENTRY(entry); entry = EXT4_XATTR_NEXT(entry)) {
63
+ while (!IS_LAST_ENTRY(entry)) {
64
+ void *next = EXT4_XATTR_NEXT(entry);
65
+
66
+ if (next >= end) {
67
+ EXT4_ERROR_INODE(inode,
68
+ "corrupt xattr in inline inode");
69
+ return 0;
70
+ }
5971 if (!entry->e_value_inum && entry->e_value_size) {
6072 size_t offs = le16_to_cpu(entry->e_value_offs);
6173 if (offs < min_offs)
6274 min_offs = offs;
6375 }
76
+ entry = next;
6477 }
6578 free = min_offs -
6679 ((void *)entry - (void *)IFIRST(header)) - sizeof(__u32);
....@@ -99,9 +112,9 @@
99112
100113 error = ext4_get_inode_loc(inode, &iloc);
101114 if (error) {
102
- ext4_error_inode(inode, __func__, __LINE__, 0,
103
- "can't get inode location %lu",
104
- inode->i_ino);
115
+ ext4_error_inode_err(inode, __func__, __LINE__, 0, -error,
116
+ "can't get inode location %lu",
117
+ inode->i_ino);
105118 return 0;
106119 }
107120
....@@ -155,7 +168,6 @@
155168 (void *)ext4_raw_inode(&is.iloc));
156169 EXT4_I(inode)->i_inline_size = EXT4_MIN_INLINE_DATA_SIZE +
157170 le32_to_cpu(is.s.here->e_value_size);
158
- ext4_set_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA);
159171 }
160172 out:
161173 brelse(is.iloc.bh);
....@@ -205,7 +217,7 @@
205217 /*
206218 * write the buffer to the inline inode.
207219 * If 'create' is set, we don't need to do the extra copy in the xattr
208
- * value since it is already handled by ext4_xattr_ibody_inline_set.
220
+ * value since it is already handled by ext4_xattr_ibody_set.
209221 * That saves us one memcpy.
210222 */
211223 static void ext4_write_inline_data(struct inode *inode, struct ext4_iloc *iloc,
....@@ -277,7 +289,7 @@
277289 len = 0;
278290 }
279291
280
- /* Insert the the xttr entry. */
292
+ /* Insert the xttr entry. */
281293 i.value = value;
282294 i.value_len = len;
283295
....@@ -287,7 +299,7 @@
287299
288300 BUG_ON(!is.s.not_found);
289301
290
- error = ext4_xattr_ibody_inline_set(handle, inode, &i, &is);
302
+ error = ext4_xattr_ibody_set(handle, inode, &i, &is);
291303 if (error) {
292304 if (error == -ENOSPC)
293305 ext4_clear_inode_state(inode,
....@@ -347,7 +359,7 @@
347359
348360 error = ext4_xattr_ibody_get(inode, i.name_index, i.name,
349361 value, len);
350
- if (error == -ENODATA)
362
+ if (error < 0)
351363 goto out;
352364
353365 BUFFER_TRACE(is.iloc.bh, "get_write_access");
....@@ -355,11 +367,11 @@
355367 if (error)
356368 goto out;
357369
358
- /* Update the xttr entry. */
370
+ /* Update the xattr entry. */
359371 i.value = value;
360372 i.value_len = len;
361373
362
- error = ext4_xattr_ibody_inline_set(handle, inode, &i, &is);
374
+ error = ext4_xattr_ibody_set(handle, inode, &i, &is);
363375 if (error)
364376 goto out;
365377
....@@ -432,7 +444,7 @@
432444 if (error)
433445 goto out;
434446
435
- error = ext4_xattr_ibody_inline_set(handle, inode, &i, &is);
447
+ error = ext4_xattr_ibody_set(handle, inode, &i, &is);
436448 if (error)
437449 goto out;
438450
....@@ -747,18 +759,13 @@
747759 void *kaddr;
748760 struct ext4_iloc iloc;
749761
750
- if (unlikely(copied < len)) {
751
- if (!PageUptodate(page)) {
752
- copied = 0;
753
- goto out;
754
- }
755
- }
762
+ if (unlikely(copied < len) && !PageUptodate(page))
763
+ return 0;
756764
757765 ret = ext4_get_inode_loc(inode, &iloc);
758766 if (ret) {
759767 ext4_std_error(inode->i_sb, ret);
760
- copied = 0;
761
- goto out;
768
+ return ret;
762769 }
763770
764771 ext4_write_lock_xattr(inode, &no_expand);
....@@ -771,7 +778,7 @@
771778 (void) ext4_find_inline_data_nolock(inode);
772779
773780 kaddr = kmap_atomic(page);
774
- ext4_write_inline_data(inode, &iloc, kaddr, pos, len);
781
+ ext4_write_inline_data(inode, &iloc, kaddr, pos, copied);
775782 kunmap_atomic(kaddr);
776783 SetPageUptodate(page);
777784 /* clear page dirty so that writepages wouldn't work for us. */
....@@ -780,7 +787,7 @@
780787 ext4_write_unlock_xattr(inode, &no_expand);
781788 brelse(iloc.bh);
782789 mark_inode_dirty(inode);
783
-out:
790
+
784791 return copied;
785792 }
786793
....@@ -815,7 +822,7 @@
815822 * clear the inode state safely.
816823 * 2. The inode has inline data, then we need to read the data, make it
817824 * update and dirty so that ext4_da_writepages can handle it. We don't
818
- * need to start the journal since the file's metatdata isn't changed now.
825
+ * need to start the journal since the file's metadata isn't changed now.
819826 */
820827 static int ext4_da_convert_inline_data_to_extent(struct address_space *mapping,
821828 struct inode *inode,
....@@ -869,7 +876,7 @@
869876
870877 /*
871878 * Prepare the write for the inline data.
872
- * If the the data can be written into the inode, we just read
879
+ * If the data can be written into the inode, we just read
873880 * the page and make it uptodate, and start the journal.
874881 * Otherwise read the page, makes it dirty so that it can be
875882 * handle in writepages(the i_disksize update is left to the
....@@ -1160,7 +1167,6 @@
11601167 {
11611168 int err, csum_size = 0, header_size = 0;
11621169 struct ext4_dir_entry_2 *de;
1163
- struct ext4_dir_entry_tail *t;
11641170 void *target = dir_block->b_data;
11651171
11661172 /*
....@@ -1186,13 +1192,12 @@
11861192 inline_size - EXT4_INLINE_DOTDOT_SIZE + header_size,
11871193 inode->i_sb->s_blocksize - csum_size);
11881194
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
- }
1195
+ if (csum_size)
1196
+ ext4_initialize_dirent_tail(dir_block,
1197
+ inode->i_sb->s_blocksize);
11941198 set_buffer_uptodate(dir_block);
1195
- err = ext4_handle_dirty_dirent_node(handle, inode, dir_block);
1199
+ unlock_buffer(dir_block);
1200
+ err = ext4_handle_dirty_dirblock(handle, inode, dir_block);
11961201 if (err)
11971202 return err;
11981203 set_buffer_verified(dir_block);
....@@ -1265,6 +1270,7 @@
12651270 if (!S_ISDIR(inode->i_mode)) {
12661271 memcpy(data_bh->b_data, buf, inline_size);
12671272 set_buffer_uptodate(data_bh);
1273
+ unlock_buffer(data_bh);
12681274 error = ext4_handle_dirty_metadata(handle,
12691275 inode, data_bh);
12701276 } else {
....@@ -1272,7 +1278,6 @@
12721278 buf, inline_size);
12731279 }
12741280
1275
- unlock_buffer(data_bh);
12761281 out_restore:
12771282 if (error)
12781283 ext4_restore_inline_data(handle, inode, iloc, buf, inline_size);
....@@ -1291,7 +1296,7 @@
12911296 int ext4_try_add_inline_entry(handle_t *handle, struct ext4_filename *fname,
12921297 struct inode *dir, struct inode *inode)
12931298 {
1294
- int ret, inline_size, no_expand;
1299
+ int ret, ret2, inline_size, no_expand;
12951300 void *inline_start;
12961301 struct ext4_iloc iloc;
12971302
....@@ -1345,7 +1350,9 @@
13451350
13461351 out:
13471352 ext4_write_unlock_xattr(dir, &no_expand);
1348
- ext4_mark_inode_dirty(handle, dir);
1353
+ ret2 = ext4_mark_inode_dirty(handle, dir);
1354
+ if (unlikely(ret2 && !ret))
1355
+ ret = ret2;
13491356 brelse(iloc.bh);
13501357 return ret;
13511358 }
....@@ -1355,11 +1362,11 @@
13551362 * inlined dir. It returns the number directory entries loaded
13561363 * into the tree. If there is an error it is returned in err.
13571364 */
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)
1365
+int ext4_inlinedir_to_tree(struct file *dir_file,
1366
+ struct inode *dir, ext4_lblk_t block,
1367
+ struct dx_hash_info *hinfo,
1368
+ __u32 start_hash, __u32 start_minor_hash,
1369
+ int *has_inline_data)
13631370 {
13641371 int err = 0, count = 0;
13651372 unsigned int parent_ino;
....@@ -1740,7 +1747,7 @@
17401747 if (err)
17411748 goto out;
17421749
1743
- err = ext4_generic_delete_entry(handle, dir, de_del, 0, bh,
1750
+ err = ext4_generic_delete_entry(dir, de_del, 0, bh,
17441751 inline_start, inline_size, 0);
17451752 if (err)
17461753 goto out;
....@@ -1793,18 +1800,20 @@
17931800 void *inline_pos;
17941801 unsigned int offset;
17951802 struct ext4_dir_entry_2 *de;
1796
- bool ret = true;
1803
+ bool ret = false;
17971804
17981805 err = ext4_get_inode_loc(dir, &iloc);
17991806 if (err) {
1800
- EXT4_ERROR_INODE(dir, "error %d getting inode %lu block",
1801
- err, dir->i_ino);
1802
- return true;
1807
+ EXT4_ERROR_INODE_ERR(dir, -err,
1808
+ "error %d getting inode %lu block",
1809
+ err, dir->i_ino);
1810
+ return false;
18031811 }
18041812
18051813 down_read(&EXT4_I(dir)->xattr_sem);
18061814 if (!ext4_has_inline_data(dir)) {
18071815 *has_inline_data = 0;
1816
+ ret = true;
18081817 goto out;
18091818 }
18101819
....@@ -1813,7 +1822,6 @@
18131822 ext4_warning(dir->i_sb,
18141823 "bad inline directory (dir #%lu) - no `..'",
18151824 dir->i_ino);
1816
- ret = true;
18171825 goto out;
18181826 }
18191827
....@@ -1832,16 +1840,15 @@
18321840 dir->i_ino, le32_to_cpu(de->inode),
18331841 le16_to_cpu(de->rec_len), de->name_len,
18341842 inline_size);
1835
- ret = true;
18361843 goto out;
18371844 }
18381845 if (le32_to_cpu(de->inode)) {
1839
- ret = false;
18401846 goto out;
18411847 }
18421848 offset += ext4_rec_len_from_disk(de->rec_len, inline_size);
18431849 }
18441850
1851
+ ret = true;
18451852 out:
18461853 up_read(&EXT4_I(dir)->xattr_sem);
18471854 brelse(iloc.bh);
....@@ -1889,47 +1896,6 @@
18891896 out:
18901897 up_read(&EXT4_I(inode)->xattr_sem);
18911898 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);
19331899 }
19341900
19351901 int ext4_inline_data_truncate(struct inode *inode, int *has_inline)
....@@ -1994,8 +1960,7 @@
19941960 i.value = value;
19951961 i.value_len = i_size > EXT4_MIN_INLINE_DATA_SIZE ?
19961962 i_size - EXT4_MIN_INLINE_DATA_SIZE : 0;
1997
- err = ext4_xattr_ibody_inline_set(handle, inode,
1998
- &i, &is);
1963
+ err = ext4_xattr_ibody_set(handle, inode, &i, &is);
19991964 if (err)
20001965 goto out_error;
20011966 }
....@@ -2040,6 +2005,18 @@
20402005 if (!ext4_has_inline_data(inode)) {
20412006 ext4_clear_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA);
20422007 return 0;
2008
+ } else if (!ext4_test_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA)) {
2009
+ /*
2010
+ * Inode has inline data but EXT4_STATE_MAY_INLINE_DATA is
2011
+ * cleared. This means we are in the middle of moving of
2012
+ * inline data to delay allocated block. Just force writeout
2013
+ * here to finish conversion.
2014
+ */
2015
+ error = filemap_flush(inode->i_mapping);
2016
+ if (error)
2017
+ return error;
2018
+ if (!ext4_has_inline_data(inode))
2019
+ return 0;
20432020 }
20442021
20452022 needed_blocks = ext4_writepage_trans_blocks(inode);