forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-11 6778948f9de86c3cfaf36725a7c87dcff9ba247f
kernel/fs/ext4/xattr.c
....@@ -93,6 +93,7 @@
9393 #ifdef CONFIG_EXT4_FS_SECURITY
9494 [EXT4_XATTR_INDEX_SECURITY] = &ext4_xattr_security_handler,
9595 #endif
96
+ [EXT4_XATTR_INDEX_HURD] = &ext4_xattr_hurd_handler,
9697 };
9798
9899 const struct xattr_handler *ext4_xattr_handlers[] = {
....@@ -105,6 +106,7 @@
105106 #ifdef CONFIG_EXT4_FS_SECURITY
106107 &ext4_xattr_security_handler,
107108 #endif
109
+ &ext4_xattr_hurd_handler,
108110 NULL
109111 };
110112
....@@ -245,7 +247,7 @@
245247 bh->b_data);
246248 errout:
247249 if (error)
248
- __ext4_error_inode(inode, function, line, 0,
250
+ __ext4_error_inode(inode, function, line, 0, -error,
249251 "corrupted xattr block %llu",
250252 (unsigned long long) bh->b_blocknr);
251253 else
....@@ -269,7 +271,7 @@
269271 error = ext4_xattr_check_entries(IFIRST(header), end, IFIRST(header));
270272 errout:
271273 if (error)
272
- __ext4_error_inode(inode, function, line, 0,
274
+ __ext4_error_inode(inode, function, line, 0, -error,
273275 "corrupted in-inode xattr");
274276 return error;
275277 }
....@@ -967,55 +969,6 @@
967969 return credits;
968970 }
969971
970
-static int ext4_xattr_ensure_credits(handle_t *handle, struct inode *inode,
971
- int credits, struct buffer_head *bh,
972
- bool dirty, bool block_csum)
973
-{
974
- int error;
975
-
976
- if (!ext4_handle_valid(handle))
977
- return 0;
978
-
979
- if (handle->h_buffer_credits >= credits)
980
- return 0;
981
-
982
- error = ext4_journal_extend(handle, credits - handle->h_buffer_credits);
983
- if (!error)
984
- return 0;
985
- if (error < 0) {
986
- ext4_warning(inode->i_sb, "Extend journal (error %d)", error);
987
- return error;
988
- }
989
-
990
- if (bh && dirty) {
991
- if (block_csum)
992
- ext4_xattr_block_csum_set(inode, bh);
993
- error = ext4_handle_dirty_metadata(handle, NULL, bh);
994
- if (error) {
995
- ext4_warning(inode->i_sb, "Handle metadata (error %d)",
996
- error);
997
- return error;
998
- }
999
- }
1000
-
1001
- error = ext4_journal_restart(handle, credits);
1002
- if (error) {
1003
- ext4_warning(inode->i_sb, "Restart journal (error %d)", error);
1004
- return error;
1005
- }
1006
-
1007
- if (bh) {
1008
- error = ext4_journal_get_write_access(handle, bh);
1009
- if (error) {
1010
- ext4_warning(inode->i_sb,
1011
- "Get write access failed (error %d)",
1012
- error);
1013
- return error;
1014
- }
1015
- }
1016
- return 0;
1017
-}
1018
-
1019972 static int ext4_xattr_inode_update_ref(handle_t *handle, struct inode *ea_inode,
1020973 int ref_change)
1021974 {
....@@ -1028,10 +981,8 @@
1028981 inode_lock(ea_inode);
1029982
1030983 ret = ext4_reserve_inode_write(handle, ea_inode, &iloc);
1031
- if (ret) {
1032
- iloc.bh = NULL;
984
+ if (ret)
1033985 goto out;
1034
- }
1035986
1036987 ref_count = ext4_xattr_inode_get_ref(ea_inode);
1037988 ref_count += ref_change;
....@@ -1077,12 +1028,10 @@
10771028 }
10781029
10791030 ret = ext4_mark_iloc_dirty(handle, ea_inode, &iloc);
1080
- iloc.bh = NULL;
10811031 if (ret)
10821032 ext4_warning_inode(ea_inode,
10831033 "ext4_mark_iloc_dirty() failed ret=%d", ret);
10841034 out:
1085
- brelse(iloc.bh);
10861035 inode_unlock(ea_inode);
10871036 return ret;
10881037 }
....@@ -1153,6 +1102,24 @@
11531102 return saved_err;
11541103 }
11551104
1105
+static int ext4_xattr_restart_fn(handle_t *handle, struct inode *inode,
1106
+ struct buffer_head *bh, bool block_csum, bool dirty)
1107
+{
1108
+ int error;
1109
+
1110
+ if (bh && dirty) {
1111
+ if (block_csum)
1112
+ ext4_xattr_block_csum_set(inode, bh);
1113
+ error = ext4_handle_dirty_metadata(handle, NULL, bh);
1114
+ if (error) {
1115
+ ext4_warning(inode->i_sb, "Handle metadata (error %d)",
1116
+ error);
1117
+ return error;
1118
+ }
1119
+ }
1120
+ return 0;
1121
+}
1122
+
11561123 static void
11571124 ext4_xattr_inode_dec_ref_all(handle_t *handle, struct inode *parent,
11581125 struct buffer_head *bh,
....@@ -1189,12 +1156,23 @@
11891156 continue;
11901157 }
11911158
1192
- err = ext4_xattr_ensure_credits(handle, parent, credits, bh,
1193
- dirty, block_csum);
1194
- if (err) {
1159
+ err = ext4_journal_ensure_credits_fn(handle, credits, credits,
1160
+ ext4_free_metadata_revoke_credits(parent->i_sb, 1),
1161
+ ext4_xattr_restart_fn(handle, parent, bh, block_csum,
1162
+ dirty));
1163
+ if (err < 0) {
11951164 ext4_warning_inode(ea_inode, "Ensure credits err=%d",
11961165 err);
11971166 continue;
1167
+ }
1168
+ if (err > 0) {
1169
+ err = ext4_journal_get_write_access(handle, bh);
1170
+ if (err) {
1171
+ ext4_warning_inode(ea_inode,
1172
+ "Re-get write access err=%d",
1173
+ err);
1174
+ continue;
1175
+ }
11981176 }
11991177
12001178 err = ext4_xattr_inode_dec_ref(handle, ea_inode);
....@@ -1351,7 +1329,7 @@
13511329 int blocksize = ea_inode->i_sb->s_blocksize;
13521330 int max_blocks = (bufsize + blocksize - 1) >> ea_inode->i_blkbits;
13531331 int csize, wsize = 0;
1354
- int ret = 0;
1332
+ int ret = 0, ret2 = 0;
13551333 int retries = 0;
13561334
13571335 retry:
....@@ -1378,8 +1356,7 @@
13781356
13791357 block = 0;
13801358 while (wsize < bufsize) {
1381
- if (bh != NULL)
1382
- brelse(bh);
1359
+ brelse(bh);
13831360 csize = (bufsize - wsize) > blocksize ? blocksize :
13841361 bufsize - wsize;
13851362 bh = ext4_getblk(handle, ea_inode, block, 0);
....@@ -1409,7 +1386,9 @@
14091386 ext4_update_i_disksize(ea_inode, wsize);
14101387 inode_unlock(ea_inode);
14111388
1412
- ext4_mark_inode_dirty(handle, ea_inode);
1389
+ ret2 = ext4_mark_inode_dirty(handle, ea_inode);
1390
+ if (unlikely(ret2 && !ret))
1391
+ ret = ret2;
14131392
14141393 out:
14151394 brelse(bh);
....@@ -1483,7 +1462,7 @@
14831462 WARN_ON_ONCE(ext4_handle_valid(journal_current_handle()) &&
14841463 !(current->flags & PF_MEMALLOC_NOFS));
14851464
1486
- ea_data = ext4_kvmalloc(value_len, GFP_NOFS);
1465
+ ea_data = kvmalloc(value_len, GFP_KERNEL);
14871466 if (!ea_data) {
14881467 mb_cache_entry_put(ea_inode_cache, ce);
14891468 return NULL;
....@@ -2188,8 +2167,9 @@
21882167 struct ext4_inode *raw_inode;
21892168 int error;
21902169
2191
- if (EXT4_I(inode)->i_extra_isize == 0)
2170
+ if (!EXT4_INODE_HAS_XATTR_SPACE(inode))
21922171 return 0;
2172
+
21932173 raw_inode = ext4_raw_inode(&is->iloc);
21942174 header = IHDR(inode, raw_inode);
21952175 is->s.base = is->s.first = IFIRST(header);
....@@ -2217,8 +2197,9 @@
22172197 struct ext4_xattr_search *s = &is->s;
22182198 int error;
22192199
2220
- if (EXT4_I(inode)->i_extra_isize == 0)
2200
+ if (!EXT4_INODE_HAS_XATTR_SPACE(inode))
22212201 return -ENOSPC;
2202
+
22222203 error = ext4_xattr_set_entry(i, s, handle, inode, false /* is_block */);
22232204 if (error)
22242205 return error;
....@@ -2345,7 +2326,7 @@
23452326 flags & XATTR_CREATE);
23462327 brelse(bh);
23472328
2348
- if (!ext4_handle_has_enough_credits(handle, credits)) {
2329
+ if (jbd2_handle_buffer_credits(handle) < credits) {
23492330 error = -ENOSPC;
23502331 goto cleanup;
23512332 }
....@@ -2444,6 +2425,7 @@
24442425 if (IS_SYNC(inode))
24452426 ext4_handle_sync(handle);
24462427 }
2428
+ ext4_fc_mark_ineligible(inode->i_sb, EXT4_FC_REASON_XATTR);
24472429
24482430 cleanup:
24492431 brelse(is.iloc.bh);
....@@ -2521,6 +2503,7 @@
25212503 if (error == 0)
25222504 error = error2;
25232505 }
2506
+ ext4_fc_mark_ineligible(inode->i_sb, EXT4_FC_REASON_XATTR);
25242507
25252508 return error;
25262509 }
....@@ -2873,11 +2856,9 @@
28732856 struct inode *ea_inode;
28742857 int error;
28752858
2876
- error = ext4_xattr_ensure_credits(handle, inode, extra_credits,
2877
- NULL /* bh */,
2878
- false /* dirty */,
2879
- false /* block_csum */);
2880
- if (error) {
2859
+ error = ext4_journal_ensure_credits(handle, extra_credits,
2860
+ ext4_free_metadata_revoke_credits(inode->i_sb, 1));
2861
+ if (error < 0) {
28812862 EXT4_ERROR_INODE(inode, "ensure credits (error %d)", error);
28822863 goto cleanup;
28832864 }
....@@ -2912,9 +2893,11 @@
29122893 bh = ext4_sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl, REQ_PRIO);
29132894 if (IS_ERR(bh)) {
29142895 error = PTR_ERR(bh);
2915
- if (error == -EIO)
2916
- EXT4_ERROR_INODE(inode, "block %llu read error",
2917
- EXT4_I(inode)->i_file_acl);
2896
+ if (error == -EIO) {
2897
+ EXT4_ERROR_INODE_ERR(inode, EIO,
2898
+ "block %llu read error",
2899
+ EXT4_I(inode)->i_file_acl);
2900
+ }
29182901 bh = NULL;
29192902 goto cleanup;
29202903 }
....@@ -2953,6 +2936,7 @@
29532936 error);
29542937 goto cleanup;
29552938 }
2939
+ ext4_fc_mark_ineligible(inode->i_sb, EXT4_FC_REASON_XATTR);
29562940 }
29572941 error = 0;
29582942 cleanup: