.. | .. |
---|
93 | 93 | #ifdef CONFIG_EXT4_FS_SECURITY |
---|
94 | 94 | [EXT4_XATTR_INDEX_SECURITY] = &ext4_xattr_security_handler, |
---|
95 | 95 | #endif |
---|
| 96 | + [EXT4_XATTR_INDEX_HURD] = &ext4_xattr_hurd_handler, |
---|
96 | 97 | }; |
---|
97 | 98 | |
---|
98 | 99 | const struct xattr_handler *ext4_xattr_handlers[] = { |
---|
.. | .. |
---|
105 | 106 | #ifdef CONFIG_EXT4_FS_SECURITY |
---|
106 | 107 | &ext4_xattr_security_handler, |
---|
107 | 108 | #endif |
---|
| 109 | + &ext4_xattr_hurd_handler, |
---|
108 | 110 | NULL |
---|
109 | 111 | }; |
---|
110 | 112 | |
---|
.. | .. |
---|
121 | 123 | #ifdef CONFIG_LOCKDEP |
---|
122 | 124 | void ext4_xattr_inode_set_class(struct inode *ea_inode) |
---|
123 | 125 | { |
---|
| 126 | + struct ext4_inode_info *ei = EXT4_I(ea_inode); |
---|
| 127 | + |
---|
124 | 128 | lockdep_set_subclass(&ea_inode->i_rwsem, 1); |
---|
| 129 | + (void) ei; /* shut up clang warning if !CONFIG_LOCKDEP */ |
---|
| 130 | + lockdep_set_subclass(&ei->i_data_sem, I_DATA_SEM_EA); |
---|
125 | 131 | } |
---|
126 | 132 | #endif |
---|
127 | 133 | |
---|
.. | .. |
---|
245 | 251 | bh->b_data); |
---|
246 | 252 | errout: |
---|
247 | 253 | if (error) |
---|
248 | | - __ext4_error_inode(inode, function, line, 0, |
---|
| 254 | + __ext4_error_inode(inode, function, line, 0, -error, |
---|
249 | 255 | "corrupted xattr block %llu", |
---|
250 | 256 | (unsigned long long) bh->b_blocknr); |
---|
251 | 257 | else |
---|
.. | .. |
---|
269 | 275 | error = ext4_xattr_check_entries(IFIRST(header), end, IFIRST(header)); |
---|
270 | 276 | errout: |
---|
271 | 277 | if (error) |
---|
272 | | - __ext4_error_inode(inode, function, line, 0, |
---|
| 278 | + __ext4_error_inode(inode, function, line, 0, -error, |
---|
273 | 279 | "corrupted in-inode xattr"); |
---|
274 | 280 | return error; |
---|
275 | 281 | } |
---|
.. | .. |
---|
384 | 390 | struct inode *inode; |
---|
385 | 391 | int err; |
---|
386 | 392 | |
---|
387 | | - inode = ext4_iget(parent->i_sb, ea_ino, EXT4_IGET_NORMAL); |
---|
| 393 | + /* |
---|
| 394 | + * We have to check for this corruption early as otherwise |
---|
| 395 | + * iget_locked() could wait indefinitely for the state of our |
---|
| 396 | + * parent inode. |
---|
| 397 | + */ |
---|
| 398 | + if (parent->i_ino == ea_ino) { |
---|
| 399 | + ext4_error(parent->i_sb, |
---|
| 400 | + "Parent and EA inode have the same ino %lu", ea_ino); |
---|
| 401 | + return -EFSCORRUPTED; |
---|
| 402 | + } |
---|
| 403 | + |
---|
| 404 | + inode = ext4_iget(parent->i_sb, ea_ino, EXT4_IGET_EA_INODE); |
---|
388 | 405 | if (IS_ERR(inode)) { |
---|
389 | 406 | err = PTR_ERR(inode); |
---|
390 | 407 | ext4_error(parent->i_sb, |
---|
.. | .. |
---|
392 | 409 | err); |
---|
393 | 410 | return err; |
---|
394 | 411 | } |
---|
395 | | - |
---|
396 | | - if (is_bad_inode(inode)) { |
---|
397 | | - ext4_error(parent->i_sb, |
---|
398 | | - "error while reading EA inode %lu is_bad_inode", |
---|
399 | | - ea_ino); |
---|
400 | | - err = -EIO; |
---|
401 | | - goto error; |
---|
402 | | - } |
---|
403 | | - |
---|
404 | | - if (!(EXT4_I(inode)->i_flags & EXT4_EA_INODE_FL)) { |
---|
405 | | - ext4_error(parent->i_sb, |
---|
406 | | - "EA inode %lu does not have EXT4_EA_INODE_FL flag", |
---|
407 | | - ea_ino); |
---|
408 | | - err = -EINVAL; |
---|
409 | | - goto error; |
---|
410 | | - } |
---|
411 | | - |
---|
412 | 412 | ext4_xattr_inode_set_class(inode); |
---|
413 | 413 | |
---|
414 | 414 | /* |
---|
.. | .. |
---|
429 | 429 | |
---|
430 | 430 | *ea_inode = inode; |
---|
431 | 431 | return 0; |
---|
432 | | -error: |
---|
433 | | - iput(inode); |
---|
434 | | - return err; |
---|
| 432 | +} |
---|
| 433 | + |
---|
| 434 | +/* Remove entry from mbcache when EA inode is getting evicted */ |
---|
| 435 | +void ext4_evict_ea_inode(struct inode *inode) |
---|
| 436 | +{ |
---|
| 437 | + struct mb_cache_entry *oe; |
---|
| 438 | + |
---|
| 439 | + if (!EA_INODE_CACHE(inode)) |
---|
| 440 | + return; |
---|
| 441 | + /* Wait for entry to get unused so that we can remove it */ |
---|
| 442 | + while ((oe = mb_cache_entry_delete_or_get(EA_INODE_CACHE(inode), |
---|
| 443 | + ext4_xattr_inode_get_hash(inode), inode->i_ino))) { |
---|
| 444 | + mb_cache_entry_wait_unused(oe); |
---|
| 445 | + mb_cache_entry_put(EA_INODE_CACHE(inode), oe); |
---|
| 446 | + } |
---|
435 | 447 | } |
---|
436 | 448 | |
---|
437 | 449 | static int |
---|
.. | .. |
---|
967 | 979 | return credits; |
---|
968 | 980 | } |
---|
969 | 981 | |
---|
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 | | - |
---|
1019 | 982 | static int ext4_xattr_inode_update_ref(handle_t *handle, struct inode *ea_inode, |
---|
1020 | 983 | int ref_change) |
---|
1021 | 984 | { |
---|
1022 | | - struct mb_cache *ea_inode_cache = EA_INODE_CACHE(ea_inode); |
---|
1023 | 985 | struct ext4_iloc iloc; |
---|
1024 | 986 | s64 ref_count; |
---|
1025 | | - u32 hash; |
---|
1026 | 987 | int ret; |
---|
1027 | 988 | |
---|
1028 | 989 | inode_lock(ea_inode); |
---|
1029 | 990 | |
---|
1030 | 991 | ret = ext4_reserve_inode_write(handle, ea_inode, &iloc); |
---|
1031 | | - if (ret) { |
---|
1032 | | - iloc.bh = NULL; |
---|
| 992 | + if (ret) |
---|
1033 | 993 | goto out; |
---|
1034 | | - } |
---|
1035 | 994 | |
---|
1036 | 995 | ref_count = ext4_xattr_inode_get_ref(ea_inode); |
---|
1037 | 996 | ref_count += ref_change; |
---|
.. | .. |
---|
1047 | 1006 | |
---|
1048 | 1007 | set_nlink(ea_inode, 1); |
---|
1049 | 1008 | ext4_orphan_del(handle, ea_inode); |
---|
1050 | | - |
---|
1051 | | - if (ea_inode_cache) { |
---|
1052 | | - hash = ext4_xattr_inode_get_hash(ea_inode); |
---|
1053 | | - mb_cache_entry_create(ea_inode_cache, |
---|
1054 | | - GFP_NOFS, hash, |
---|
1055 | | - ea_inode->i_ino, |
---|
1056 | | - true /* reusable */); |
---|
1057 | | - } |
---|
1058 | 1009 | } |
---|
1059 | 1010 | } else { |
---|
1060 | 1011 | WARN_ONCE(ref_count < 0, "EA inode %lu ref_count=%lld", |
---|
.. | .. |
---|
1067 | 1018 | |
---|
1068 | 1019 | clear_nlink(ea_inode); |
---|
1069 | 1020 | ext4_orphan_add(handle, ea_inode); |
---|
1070 | | - |
---|
1071 | | - if (ea_inode_cache) { |
---|
1072 | | - hash = ext4_xattr_inode_get_hash(ea_inode); |
---|
1073 | | - mb_cache_entry_delete(ea_inode_cache, hash, |
---|
1074 | | - ea_inode->i_ino); |
---|
1075 | | - } |
---|
1076 | 1021 | } |
---|
1077 | 1022 | } |
---|
1078 | 1023 | |
---|
1079 | 1024 | ret = ext4_mark_iloc_dirty(handle, ea_inode, &iloc); |
---|
1080 | | - iloc.bh = NULL; |
---|
1081 | 1025 | if (ret) |
---|
1082 | 1026 | ext4_warning_inode(ea_inode, |
---|
1083 | 1027 | "ext4_mark_iloc_dirty() failed ret=%d", ret); |
---|
1084 | 1028 | out: |
---|
1085 | | - brelse(iloc.bh); |
---|
1086 | 1029 | inode_unlock(ea_inode); |
---|
1087 | 1030 | return ret; |
---|
1088 | 1031 | } |
---|
.. | .. |
---|
1153 | 1096 | return saved_err; |
---|
1154 | 1097 | } |
---|
1155 | 1098 | |
---|
| 1099 | +static int ext4_xattr_restart_fn(handle_t *handle, struct inode *inode, |
---|
| 1100 | + struct buffer_head *bh, bool block_csum, bool dirty) |
---|
| 1101 | +{ |
---|
| 1102 | + int error; |
---|
| 1103 | + |
---|
| 1104 | + if (bh && dirty) { |
---|
| 1105 | + if (block_csum) |
---|
| 1106 | + ext4_xattr_block_csum_set(inode, bh); |
---|
| 1107 | + error = ext4_handle_dirty_metadata(handle, NULL, bh); |
---|
| 1108 | + if (error) { |
---|
| 1109 | + ext4_warning(inode->i_sb, "Handle metadata (error %d)", |
---|
| 1110 | + error); |
---|
| 1111 | + return error; |
---|
| 1112 | + } |
---|
| 1113 | + } |
---|
| 1114 | + return 0; |
---|
| 1115 | +} |
---|
| 1116 | + |
---|
1156 | 1117 | static void |
---|
1157 | 1118 | ext4_xattr_inode_dec_ref_all(handle_t *handle, struct inode *parent, |
---|
1158 | 1119 | struct buffer_head *bh, |
---|
.. | .. |
---|
1189 | 1150 | continue; |
---|
1190 | 1151 | } |
---|
1191 | 1152 | |
---|
1192 | | - err = ext4_xattr_ensure_credits(handle, parent, credits, bh, |
---|
1193 | | - dirty, block_csum); |
---|
1194 | | - if (err) { |
---|
| 1153 | + err = ext4_journal_ensure_credits_fn(handle, credits, credits, |
---|
| 1154 | + ext4_free_metadata_revoke_credits(parent->i_sb, 1), |
---|
| 1155 | + ext4_xattr_restart_fn(handle, parent, bh, block_csum, |
---|
| 1156 | + dirty)); |
---|
| 1157 | + if (err < 0) { |
---|
1195 | 1158 | ext4_warning_inode(ea_inode, "Ensure credits err=%d", |
---|
1196 | 1159 | err); |
---|
1197 | 1160 | continue; |
---|
| 1161 | + } |
---|
| 1162 | + if (err > 0) { |
---|
| 1163 | + err = ext4_journal_get_write_access(handle, bh); |
---|
| 1164 | + if (err) { |
---|
| 1165 | + ext4_warning_inode(ea_inode, |
---|
| 1166 | + "Re-get write access err=%d", |
---|
| 1167 | + err); |
---|
| 1168 | + continue; |
---|
| 1169 | + } |
---|
1198 | 1170 | } |
---|
1199 | 1171 | |
---|
1200 | 1172 | err = ext4_xattr_inode_dec_ref(handle, ea_inode); |
---|
.. | .. |
---|
1253 | 1225 | if (error) |
---|
1254 | 1226 | goto out; |
---|
1255 | 1227 | |
---|
| 1228 | +retry_ref: |
---|
1256 | 1229 | lock_buffer(bh); |
---|
1257 | 1230 | hash = le32_to_cpu(BHDR(bh)->h_hash); |
---|
1258 | 1231 | ref = le32_to_cpu(BHDR(bh)->h_refcount); |
---|
.. | .. |
---|
1262 | 1235 | * This must happen under buffer lock for |
---|
1263 | 1236 | * ext4_xattr_block_set() to reliably detect freed block |
---|
1264 | 1237 | */ |
---|
1265 | | - if (ea_block_cache) |
---|
1266 | | - mb_cache_entry_delete(ea_block_cache, hash, |
---|
1267 | | - bh->b_blocknr); |
---|
| 1238 | + if (ea_block_cache) { |
---|
| 1239 | + struct mb_cache_entry *oe; |
---|
| 1240 | + |
---|
| 1241 | + oe = mb_cache_entry_delete_or_get(ea_block_cache, hash, |
---|
| 1242 | + bh->b_blocknr); |
---|
| 1243 | + if (oe) { |
---|
| 1244 | + unlock_buffer(bh); |
---|
| 1245 | + mb_cache_entry_wait_unused(oe); |
---|
| 1246 | + mb_cache_entry_put(ea_block_cache, oe); |
---|
| 1247 | + goto retry_ref; |
---|
| 1248 | + } |
---|
| 1249 | + } |
---|
1268 | 1250 | get_bh(bh); |
---|
1269 | 1251 | unlock_buffer(bh); |
---|
1270 | 1252 | |
---|
.. | .. |
---|
1288 | 1270 | ce = mb_cache_entry_get(ea_block_cache, hash, |
---|
1289 | 1271 | bh->b_blocknr); |
---|
1290 | 1272 | if (ce) { |
---|
1291 | | - ce->e_reusable = 1; |
---|
| 1273 | + set_bit(MBE_REUSABLE_B, &ce->e_flags); |
---|
1292 | 1274 | mb_cache_entry_put(ea_block_cache, ce); |
---|
1293 | 1275 | } |
---|
1294 | 1276 | } |
---|
.. | .. |
---|
1351 | 1333 | int blocksize = ea_inode->i_sb->s_blocksize; |
---|
1352 | 1334 | int max_blocks = (bufsize + blocksize - 1) >> ea_inode->i_blkbits; |
---|
1353 | 1335 | int csize, wsize = 0; |
---|
1354 | | - int ret = 0; |
---|
| 1336 | + int ret = 0, ret2 = 0; |
---|
1355 | 1337 | int retries = 0; |
---|
1356 | 1338 | |
---|
1357 | 1339 | retry: |
---|
.. | .. |
---|
1378 | 1360 | |
---|
1379 | 1361 | block = 0; |
---|
1380 | 1362 | while (wsize < bufsize) { |
---|
1381 | | - if (bh != NULL) |
---|
1382 | | - brelse(bh); |
---|
| 1363 | + brelse(bh); |
---|
1383 | 1364 | csize = (bufsize - wsize) > blocksize ? blocksize : |
---|
1384 | 1365 | bufsize - wsize; |
---|
1385 | 1366 | bh = ext4_getblk(handle, ea_inode, block, 0); |
---|
.. | .. |
---|
1409 | 1390 | ext4_update_i_disksize(ea_inode, wsize); |
---|
1410 | 1391 | inode_unlock(ea_inode); |
---|
1411 | 1392 | |
---|
1412 | | - ext4_mark_inode_dirty(handle, ea_inode); |
---|
| 1393 | + ret2 = ext4_mark_inode_dirty(handle, ea_inode); |
---|
| 1394 | + if (unlikely(ret2 && !ret)) |
---|
| 1395 | + ret = ret2; |
---|
1413 | 1396 | |
---|
1414 | 1397 | out: |
---|
1415 | 1398 | brelse(bh); |
---|
.. | .. |
---|
1426 | 1409 | struct inode *ea_inode = NULL; |
---|
1427 | 1410 | uid_t owner[2] = { i_uid_read(inode), i_gid_read(inode) }; |
---|
1428 | 1411 | int err; |
---|
| 1412 | + |
---|
| 1413 | + if (inode->i_sb->s_root == NULL) { |
---|
| 1414 | + ext4_warning(inode->i_sb, |
---|
| 1415 | + "refuse to create EA inode when umounting"); |
---|
| 1416 | + WARN_ON(1); |
---|
| 1417 | + return ERR_PTR(-EINVAL); |
---|
| 1418 | + } |
---|
1429 | 1419 | |
---|
1430 | 1420 | /* |
---|
1431 | 1421 | * Let the next inode be the goal, so we try and allocate the EA inode |
---|
.. | .. |
---|
1446 | 1436 | if (!err) |
---|
1447 | 1437 | err = ext4_inode_attach_jinode(ea_inode); |
---|
1448 | 1438 | if (err) { |
---|
| 1439 | + if (ext4_xattr_inode_dec_ref(handle, ea_inode)) |
---|
| 1440 | + ext4_warning_inode(ea_inode, |
---|
| 1441 | + "cleanup dec ref error %d", err); |
---|
1449 | 1442 | iput(ea_inode); |
---|
1450 | 1443 | return ERR_PTR(err); |
---|
1451 | 1444 | } |
---|
.. | .. |
---|
1483 | 1476 | WARN_ON_ONCE(ext4_handle_valid(journal_current_handle()) && |
---|
1484 | 1477 | !(current->flags & PF_MEMALLOC_NOFS)); |
---|
1485 | 1478 | |
---|
1486 | | - ea_data = ext4_kvmalloc(value_len, GFP_NOFS); |
---|
| 1479 | + ea_data = kvmalloc(value_len, GFP_KERNEL); |
---|
1487 | 1480 | if (!ea_data) { |
---|
1488 | 1481 | mb_cache_entry_put(ea_inode_cache, ce); |
---|
1489 | 1482 | return NULL; |
---|
.. | .. |
---|
1491 | 1484 | |
---|
1492 | 1485 | while (ce) { |
---|
1493 | 1486 | ea_inode = ext4_iget(inode->i_sb, ce->e_value, |
---|
1494 | | - EXT4_IGET_NORMAL); |
---|
1495 | | - if (!IS_ERR(ea_inode) && |
---|
1496 | | - !is_bad_inode(ea_inode) && |
---|
1497 | | - (EXT4_I(ea_inode)->i_flags & EXT4_EA_INODE_FL) && |
---|
1498 | | - i_size_read(ea_inode) == value_len && |
---|
| 1487 | + EXT4_IGET_EA_INODE); |
---|
| 1488 | + if (IS_ERR(ea_inode)) |
---|
| 1489 | + goto next_entry; |
---|
| 1490 | + ext4_xattr_inode_set_class(ea_inode); |
---|
| 1491 | + if (i_size_read(ea_inode) == value_len && |
---|
1499 | 1492 | !ext4_xattr_inode_read(ea_inode, ea_data, value_len) && |
---|
1500 | 1493 | !ext4_xattr_inode_verify_hashes(ea_inode, NULL, ea_data, |
---|
1501 | 1494 | value_len) && |
---|
.. | .. |
---|
1505 | 1498 | kvfree(ea_data); |
---|
1506 | 1499 | return ea_inode; |
---|
1507 | 1500 | } |
---|
1508 | | - |
---|
1509 | | - if (!IS_ERR(ea_inode)) |
---|
1510 | | - iput(ea_inode); |
---|
| 1501 | + iput(ea_inode); |
---|
| 1502 | + next_entry: |
---|
1511 | 1503 | ce = mb_cache_entry_find_next(ea_inode_cache, ce); |
---|
1512 | 1504 | } |
---|
1513 | 1505 | kvfree(ea_data); |
---|
.. | .. |
---|
1635 | 1627 | * If storing the value in an external inode is an option, |
---|
1636 | 1628 | * reserve space for xattr entries/names in the external |
---|
1637 | 1629 | * attribute block so that a long value does not occupy the |
---|
1638 | | - * whole space and prevent futher entries being added. |
---|
| 1630 | + * whole space and prevent further entries being added. |
---|
1639 | 1631 | */ |
---|
1640 | 1632 | if (ext4_has_feature_ea_inode(inode->i_sb) && |
---|
1641 | 1633 | new_size && is_block && |
---|
.. | .. |
---|
1733 | 1725 | memmove(here, (void *)here + size, |
---|
1734 | 1726 | (void *)last - (void *)here + sizeof(__u32)); |
---|
1735 | 1727 | memset(last, 0, size); |
---|
| 1728 | + |
---|
| 1729 | + /* |
---|
| 1730 | + * Update i_inline_off - moved ibody region might contain |
---|
| 1731 | + * system.data attribute. Handling a failure here won't |
---|
| 1732 | + * cause other complications for setting an xattr. |
---|
| 1733 | + */ |
---|
| 1734 | + if (!is_block && ext4_has_inline_data(inode)) { |
---|
| 1735 | + ret = ext4_find_inline_data_nolock(inode); |
---|
| 1736 | + if (ret) { |
---|
| 1737 | + ext4_warning_inode(inode, |
---|
| 1738 | + "unable to update i_inline_off"); |
---|
| 1739 | + goto out; |
---|
| 1740 | + } |
---|
| 1741 | + } |
---|
1736 | 1742 | } else if (s->not_found) { |
---|
1737 | 1743 | /* Insert new name. */ |
---|
1738 | 1744 | size_t size = EXT4_XATTR_LEN(name_len); |
---|
.. | .. |
---|
1872 | 1878 | #define header(x) ((struct ext4_xattr_header *)(x)) |
---|
1873 | 1879 | |
---|
1874 | 1880 | if (s->base) { |
---|
| 1881 | + int offset = (char *)s->here - bs->bh->b_data; |
---|
| 1882 | + |
---|
1875 | 1883 | BUFFER_TRACE(bs->bh, "get_write_access"); |
---|
1876 | 1884 | error = ext4_journal_get_write_access(handle, bs->bh); |
---|
1877 | 1885 | if (error) |
---|
.. | .. |
---|
1886 | 1894 | * ext4_xattr_block_set() to reliably detect modified |
---|
1887 | 1895 | * block |
---|
1888 | 1896 | */ |
---|
1889 | | - if (ea_block_cache) |
---|
1890 | | - mb_cache_entry_delete(ea_block_cache, hash, |
---|
1891 | | - bs->bh->b_blocknr); |
---|
| 1897 | + if (ea_block_cache) { |
---|
| 1898 | + struct mb_cache_entry *oe; |
---|
| 1899 | + |
---|
| 1900 | + oe = mb_cache_entry_delete_or_get(ea_block_cache, |
---|
| 1901 | + hash, bs->bh->b_blocknr); |
---|
| 1902 | + if (oe) { |
---|
| 1903 | + /* |
---|
| 1904 | + * Xattr block is getting reused. Leave |
---|
| 1905 | + * it alone. |
---|
| 1906 | + */ |
---|
| 1907 | + mb_cache_entry_put(ea_block_cache, oe); |
---|
| 1908 | + goto clone_block; |
---|
| 1909 | + } |
---|
| 1910 | + } |
---|
1892 | 1911 | ea_bdebug(bs->bh, "modifying in-place"); |
---|
1893 | 1912 | error = ext4_xattr_set_entry(i, s, handle, inode, |
---|
1894 | 1913 | true /* is_block */); |
---|
.. | .. |
---|
1903 | 1922 | if (error) |
---|
1904 | 1923 | goto cleanup; |
---|
1905 | 1924 | goto inserted; |
---|
1906 | | - } else { |
---|
1907 | | - int offset = (char *)s->here - bs->bh->b_data; |
---|
| 1925 | + } |
---|
| 1926 | +clone_block: |
---|
| 1927 | + unlock_buffer(bs->bh); |
---|
| 1928 | + ea_bdebug(bs->bh, "cloning"); |
---|
| 1929 | + s->base = kmemdup(BHDR(bs->bh), bs->bh->b_size, GFP_NOFS); |
---|
| 1930 | + error = -ENOMEM; |
---|
| 1931 | + if (s->base == NULL) |
---|
| 1932 | + goto cleanup; |
---|
| 1933 | + s->first = ENTRY(header(s->base)+1); |
---|
| 1934 | + header(s->base)->h_refcount = cpu_to_le32(1); |
---|
| 1935 | + s->here = ENTRY(s->base + offset); |
---|
| 1936 | + s->end = s->base + bs->bh->b_size; |
---|
1908 | 1937 | |
---|
1909 | | - unlock_buffer(bs->bh); |
---|
1910 | | - ea_bdebug(bs->bh, "cloning"); |
---|
1911 | | - s->base = kmalloc(bs->bh->b_size, GFP_NOFS); |
---|
1912 | | - error = -ENOMEM; |
---|
1913 | | - if (s->base == NULL) |
---|
| 1938 | + /* |
---|
| 1939 | + * If existing entry points to an xattr inode, we need |
---|
| 1940 | + * to prevent ext4_xattr_set_entry() from decrementing |
---|
| 1941 | + * ref count on it because the reference belongs to the |
---|
| 1942 | + * original block. In this case, make the entry look |
---|
| 1943 | + * like it has an empty value. |
---|
| 1944 | + */ |
---|
| 1945 | + if (!s->not_found && s->here->e_value_inum) { |
---|
| 1946 | + ea_ino = le32_to_cpu(s->here->e_value_inum); |
---|
| 1947 | + error = ext4_xattr_inode_iget(inode, ea_ino, |
---|
| 1948 | + le32_to_cpu(s->here->e_hash), |
---|
| 1949 | + &tmp_inode); |
---|
| 1950 | + if (error) |
---|
1914 | 1951 | goto cleanup; |
---|
1915 | | - memcpy(s->base, BHDR(bs->bh), bs->bh->b_size); |
---|
1916 | | - s->first = ENTRY(header(s->base)+1); |
---|
1917 | | - header(s->base)->h_refcount = cpu_to_le32(1); |
---|
1918 | | - s->here = ENTRY(s->base + offset); |
---|
1919 | | - s->end = s->base + bs->bh->b_size; |
---|
1920 | 1952 | |
---|
1921 | | - /* |
---|
1922 | | - * If existing entry points to an xattr inode, we need |
---|
1923 | | - * to prevent ext4_xattr_set_entry() from decrementing |
---|
1924 | | - * ref count on it because the reference belongs to the |
---|
1925 | | - * original block. In this case, make the entry look |
---|
1926 | | - * like it has an empty value. |
---|
1927 | | - */ |
---|
1928 | | - if (!s->not_found && s->here->e_value_inum) { |
---|
1929 | | - ea_ino = le32_to_cpu(s->here->e_value_inum); |
---|
1930 | | - error = ext4_xattr_inode_iget(inode, ea_ino, |
---|
1931 | | - le32_to_cpu(s->here->e_hash), |
---|
1932 | | - &tmp_inode); |
---|
1933 | | - if (error) |
---|
1934 | | - goto cleanup; |
---|
1935 | | - |
---|
1936 | | - if (!ext4_test_inode_state(tmp_inode, |
---|
1937 | | - EXT4_STATE_LUSTRE_EA_INODE)) { |
---|
1938 | | - /* |
---|
1939 | | - * Defer quota free call for previous |
---|
1940 | | - * inode until success is guaranteed. |
---|
1941 | | - */ |
---|
1942 | | - old_ea_inode_quota = le32_to_cpu( |
---|
1943 | | - s->here->e_value_size); |
---|
1944 | | - } |
---|
1945 | | - iput(tmp_inode); |
---|
1946 | | - |
---|
1947 | | - s->here->e_value_inum = 0; |
---|
1948 | | - s->here->e_value_size = 0; |
---|
| 1953 | + if (!ext4_test_inode_state(tmp_inode, |
---|
| 1954 | + EXT4_STATE_LUSTRE_EA_INODE)) { |
---|
| 1955 | + /* |
---|
| 1956 | + * Defer quota free call for previous |
---|
| 1957 | + * inode until success is guaranteed. |
---|
| 1958 | + */ |
---|
| 1959 | + old_ea_inode_quota = le32_to_cpu( |
---|
| 1960 | + s->here->e_value_size); |
---|
1949 | 1961 | } |
---|
| 1962 | + iput(tmp_inode); |
---|
| 1963 | + |
---|
| 1964 | + s->here->e_value_inum = 0; |
---|
| 1965 | + s->here->e_value_size = 0; |
---|
1950 | 1966 | } |
---|
1951 | 1967 | } else { |
---|
1952 | 1968 | /* Allocate a buffer where we construct the new block. */ |
---|
.. | .. |
---|
1997 | 2013 | else { |
---|
1998 | 2014 | u32 ref; |
---|
1999 | 2015 | |
---|
| 2016 | +#ifdef EXT4_XATTR_DEBUG |
---|
2000 | 2017 | WARN_ON_ONCE(dquot_initialize_needed(inode)); |
---|
2001 | | - |
---|
| 2018 | +#endif |
---|
2002 | 2019 | /* The old block is released after updating |
---|
2003 | 2020 | the inode. */ |
---|
2004 | 2021 | error = dquot_alloc_block(inode, |
---|
.. | .. |
---|
2013 | 2030 | lock_buffer(new_bh); |
---|
2014 | 2031 | /* |
---|
2015 | 2032 | * We have to be careful about races with |
---|
2016 | | - * freeing, rehashing or adding references to |
---|
2017 | | - * xattr block. Once we hold buffer lock xattr |
---|
2018 | | - * block's state is stable so we can check |
---|
2019 | | - * whether the block got freed / rehashed or |
---|
2020 | | - * not. Since we unhash mbcache entry under |
---|
2021 | | - * buffer lock when freeing / rehashing xattr |
---|
2022 | | - * block, checking whether entry is still |
---|
2023 | | - * hashed is reliable. Same rules hold for |
---|
2024 | | - * e_reusable handling. |
---|
| 2033 | + * adding references to xattr block. Once we |
---|
| 2034 | + * hold buffer lock xattr block's state is |
---|
| 2035 | + * stable so we can check the additional |
---|
| 2036 | + * reference fits. |
---|
2025 | 2037 | */ |
---|
2026 | | - if (hlist_bl_unhashed(&ce->e_hash_list) || |
---|
2027 | | - !ce->e_reusable) { |
---|
| 2038 | + ref = le32_to_cpu(BHDR(new_bh)->h_refcount) + 1; |
---|
| 2039 | + if (ref > EXT4_XATTR_REFCOUNT_MAX) { |
---|
2028 | 2040 | /* |
---|
2029 | 2041 | * Undo everything and check mbcache |
---|
2030 | 2042 | * again. |
---|
.. | .. |
---|
2039 | 2051 | new_bh = NULL; |
---|
2040 | 2052 | goto inserted; |
---|
2041 | 2053 | } |
---|
2042 | | - ref = le32_to_cpu(BHDR(new_bh)->h_refcount) + 1; |
---|
2043 | 2054 | BHDR(new_bh)->h_refcount = cpu_to_le32(ref); |
---|
2044 | | - if (ref >= EXT4_XATTR_REFCOUNT_MAX) |
---|
2045 | | - ce->e_reusable = 0; |
---|
| 2055 | + if (ref == EXT4_XATTR_REFCOUNT_MAX) |
---|
| 2056 | + clear_bit(MBE_REUSABLE_B, &ce->e_flags); |
---|
2046 | 2057 | ea_bdebug(new_bh, "reusing; refcount now=%d", |
---|
2047 | 2058 | ref); |
---|
2048 | 2059 | ext4_xattr_block_csum_set(inode, new_bh); |
---|
.. | .. |
---|
2066 | 2077 | /* We need to allocate a new block */ |
---|
2067 | 2078 | ext4_fsblk_t goal, block; |
---|
2068 | 2079 | |
---|
| 2080 | +#ifdef EXT4_XATTR_DEBUG |
---|
2069 | 2081 | WARN_ON_ONCE(dquot_initialize_needed(inode)); |
---|
2070 | | - |
---|
| 2082 | +#endif |
---|
2071 | 2083 | goal = ext4_group_first_block_no(sb, |
---|
2072 | 2084 | EXT4_I(inode)->i_block_group); |
---|
2073 | | - |
---|
2074 | | - /* non-extent files can't have physical blocks past 2^32 */ |
---|
2075 | | - if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))) |
---|
2076 | | - goal = goal & EXT4_MAX_BLOCK_FILE_PHYS; |
---|
2077 | | - |
---|
2078 | 2085 | block = ext4_new_meta_blocks(handle, inode, goal, 0, |
---|
2079 | 2086 | NULL, &error); |
---|
2080 | 2087 | if (error) |
---|
2081 | 2088 | goto cleanup; |
---|
2082 | | - |
---|
2083 | | - if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))) |
---|
2084 | | - BUG_ON(block > EXT4_MAX_BLOCK_FILE_PHYS); |
---|
2085 | 2089 | |
---|
2086 | 2090 | ea_idebug(inode, "creating block %llu", |
---|
2087 | 2091 | (unsigned long long)block); |
---|
.. | .. |
---|
2188 | 2192 | struct ext4_inode *raw_inode; |
---|
2189 | 2193 | int error; |
---|
2190 | 2194 | |
---|
2191 | | - if (EXT4_I(inode)->i_extra_isize == 0) |
---|
| 2195 | + if (!EXT4_INODE_HAS_XATTR_SPACE(inode)) |
---|
2192 | 2196 | return 0; |
---|
| 2197 | + |
---|
2193 | 2198 | raw_inode = ext4_raw_inode(&is->iloc); |
---|
2194 | 2199 | header = IHDR(inode, raw_inode); |
---|
2195 | 2200 | is->s.base = is->s.first = IFIRST(header); |
---|
.. | .. |
---|
2209 | 2214 | return 0; |
---|
2210 | 2215 | } |
---|
2211 | 2216 | |
---|
2212 | | -int ext4_xattr_ibody_inline_set(handle_t *handle, struct inode *inode, |
---|
| 2217 | +int ext4_xattr_ibody_set(handle_t *handle, struct inode *inode, |
---|
2213 | 2218 | struct ext4_xattr_info *i, |
---|
2214 | 2219 | struct ext4_xattr_ibody_find *is) |
---|
2215 | 2220 | { |
---|
.. | .. |
---|
2217 | 2222 | struct ext4_xattr_search *s = &is->s; |
---|
2218 | 2223 | int error; |
---|
2219 | 2224 | |
---|
2220 | | - if (EXT4_I(inode)->i_extra_isize == 0) |
---|
| 2225 | + if (!EXT4_INODE_HAS_XATTR_SPACE(inode)) |
---|
2221 | 2226 | return -ENOSPC; |
---|
2222 | | - error = ext4_xattr_set_entry(i, s, handle, inode, false /* is_block */); |
---|
2223 | | - if (error) |
---|
2224 | | - return error; |
---|
2225 | | - header = IHDR(inode, ext4_raw_inode(&is->iloc)); |
---|
2226 | | - if (!IS_LAST_ENTRY(s->first)) { |
---|
2227 | | - header->h_magic = cpu_to_le32(EXT4_XATTR_MAGIC); |
---|
2228 | | - ext4_set_inode_state(inode, EXT4_STATE_XATTR); |
---|
2229 | | - } else { |
---|
2230 | | - header->h_magic = cpu_to_le32(0); |
---|
2231 | | - ext4_clear_inode_state(inode, EXT4_STATE_XATTR); |
---|
2232 | | - } |
---|
2233 | | - return 0; |
---|
2234 | | -} |
---|
2235 | 2227 | |
---|
2236 | | -static int ext4_xattr_ibody_set(handle_t *handle, struct inode *inode, |
---|
2237 | | - struct ext4_xattr_info *i, |
---|
2238 | | - struct ext4_xattr_ibody_find *is) |
---|
2239 | | -{ |
---|
2240 | | - struct ext4_xattr_ibody_header *header; |
---|
2241 | | - struct ext4_xattr_search *s = &is->s; |
---|
2242 | | - int error; |
---|
2243 | | - |
---|
2244 | | - if (EXT4_I(inode)->i_extra_isize == 0) |
---|
2245 | | - return -ENOSPC; |
---|
2246 | 2228 | error = ext4_xattr_set_entry(i, s, handle, inode, false /* is_block */); |
---|
2247 | 2229 | if (error) |
---|
2248 | 2230 | return error; |
---|
.. | .. |
---|
2345 | 2327 | flags & XATTR_CREATE); |
---|
2346 | 2328 | brelse(bh); |
---|
2347 | 2329 | |
---|
2348 | | - if (!ext4_handle_has_enough_credits(handle, credits)) { |
---|
| 2330 | + if (jbd2_handle_buffer_credits(handle) < credits) { |
---|
2349 | 2331 | error = -ENOSPC; |
---|
2350 | 2332 | goto cleanup; |
---|
2351 | 2333 | } |
---|
.. | .. |
---|
2444 | 2426 | if (IS_SYNC(inode)) |
---|
2445 | 2427 | ext4_handle_sync(handle); |
---|
2446 | 2428 | } |
---|
| 2429 | + ext4_fc_mark_ineligible(inode->i_sb, EXT4_FC_REASON_XATTR); |
---|
2447 | 2430 | |
---|
2448 | 2431 | cleanup: |
---|
2449 | 2432 | brelse(is.iloc.bh); |
---|
.. | .. |
---|
2521 | 2504 | if (error == 0) |
---|
2522 | 2505 | error = error2; |
---|
2523 | 2506 | } |
---|
| 2507 | + ext4_fc_mark_ineligible(inode->i_sb, EXT4_FC_REASON_XATTR); |
---|
2524 | 2508 | |
---|
2525 | 2509 | return error; |
---|
2526 | 2510 | } |
---|
.. | .. |
---|
2569 | 2553 | .in_inode = !!entry->e_value_inum, |
---|
2570 | 2554 | }; |
---|
2571 | 2555 | struct ext4_xattr_ibody_header *header = IHDR(inode, raw_inode); |
---|
| 2556 | + int needs_kvfree = 0; |
---|
2572 | 2557 | int error; |
---|
2573 | 2558 | |
---|
2574 | 2559 | is = kzalloc(sizeof(struct ext4_xattr_ibody_find), GFP_NOFS); |
---|
2575 | 2560 | bs = kzalloc(sizeof(struct ext4_xattr_block_find), GFP_NOFS); |
---|
2576 | | - buffer = kmalloc(value_size, GFP_NOFS); |
---|
2577 | 2561 | b_entry_name = kmalloc(entry->e_name_len + 1, GFP_NOFS); |
---|
2578 | | - if (!is || !bs || !buffer || !b_entry_name) { |
---|
| 2562 | + if (!is || !bs || !b_entry_name) { |
---|
2579 | 2563 | error = -ENOMEM; |
---|
2580 | 2564 | goto out; |
---|
2581 | 2565 | } |
---|
.. | .. |
---|
2587 | 2571 | |
---|
2588 | 2572 | /* Save the entry name and the entry value */ |
---|
2589 | 2573 | if (entry->e_value_inum) { |
---|
| 2574 | + buffer = kvmalloc(value_size, GFP_NOFS); |
---|
| 2575 | + if (!buffer) { |
---|
| 2576 | + error = -ENOMEM; |
---|
| 2577 | + goto out; |
---|
| 2578 | + } |
---|
| 2579 | + needs_kvfree = 1; |
---|
2590 | 2580 | error = ext4_xattr_inode_get(inode, entry, buffer, value_size); |
---|
2591 | 2581 | if (error) |
---|
2592 | 2582 | goto out; |
---|
2593 | 2583 | } else { |
---|
2594 | 2584 | size_t value_offs = le16_to_cpu(entry->e_value_offs); |
---|
2595 | | - memcpy(buffer, (void *)IFIRST(header) + value_offs, value_size); |
---|
| 2585 | + buffer = (void *)IFIRST(header) + value_offs; |
---|
2596 | 2586 | } |
---|
2597 | 2587 | |
---|
2598 | 2588 | memcpy(b_entry_name, entry->e_name, entry->e_name_len); |
---|
.. | .. |
---|
2607 | 2597 | if (error) |
---|
2608 | 2598 | goto out; |
---|
2609 | 2599 | |
---|
2610 | | - /* Remove the chosen entry from the inode */ |
---|
2611 | | - error = ext4_xattr_ibody_set(handle, inode, &i, is); |
---|
2612 | | - if (error) |
---|
2613 | | - goto out; |
---|
2614 | | - |
---|
2615 | 2600 | i.value = buffer; |
---|
2616 | 2601 | i.value_len = value_size; |
---|
2617 | 2602 | error = ext4_xattr_block_find(inode, &i, bs); |
---|
2618 | 2603 | if (error) |
---|
2619 | 2604 | goto out; |
---|
2620 | 2605 | |
---|
2621 | | - /* Add entry which was removed from the inode into the block */ |
---|
| 2606 | + /* Move ea entry from the inode into the block */ |
---|
2622 | 2607 | error = ext4_xattr_block_set(handle, inode, &i, bs); |
---|
2623 | 2608 | if (error) |
---|
2624 | 2609 | goto out; |
---|
2625 | | - error = 0; |
---|
| 2610 | + |
---|
| 2611 | + /* Remove the chosen entry from the inode */ |
---|
| 2612 | + i.value = NULL; |
---|
| 2613 | + i.value_len = 0; |
---|
| 2614 | + error = ext4_xattr_ibody_set(handle, inode, &i, is); |
---|
| 2615 | + |
---|
2626 | 2616 | out: |
---|
2627 | 2617 | kfree(b_entry_name); |
---|
2628 | | - kfree(buffer); |
---|
| 2618 | + if (needs_kvfree && buffer) |
---|
| 2619 | + kvfree(buffer); |
---|
2629 | 2620 | if (is) |
---|
2630 | 2621 | brelse(is->iloc.bh); |
---|
2631 | 2622 | if (bs) |
---|
.. | .. |
---|
2800 | 2791 | (void *)header, total_ino); |
---|
2801 | 2792 | EXT4_I(inode)->i_extra_isize = new_extra_isize; |
---|
2802 | 2793 | |
---|
| 2794 | + if (ext4_has_inline_data(inode)) |
---|
| 2795 | + error = ext4_find_inline_data_nolock(inode); |
---|
| 2796 | + |
---|
2803 | 2797 | cleanup: |
---|
2804 | 2798 | if (error && (mnt_count != le16_to_cpu(sbi->s_es->s_mnt_count))) { |
---|
2805 | 2799 | ext4_warning(inode->i_sb, "Unable to expand inode %lu. Delete some EAs or run e2fsck.", |
---|
.. | .. |
---|
2873 | 2867 | struct inode *ea_inode; |
---|
2874 | 2868 | int error; |
---|
2875 | 2869 | |
---|
2876 | | - error = ext4_xattr_ensure_credits(handle, inode, extra_credits, |
---|
2877 | | - NULL /* bh */, |
---|
2878 | | - false /* dirty */, |
---|
2879 | | - false /* block_csum */); |
---|
2880 | | - if (error) { |
---|
| 2870 | + error = ext4_journal_ensure_credits(handle, extra_credits, |
---|
| 2871 | + ext4_free_metadata_revoke_credits(inode->i_sb, 1)); |
---|
| 2872 | + if (error < 0) { |
---|
2881 | 2873 | EXT4_ERROR_INODE(inode, "ensure credits (error %d)", error); |
---|
2882 | 2874 | goto cleanup; |
---|
2883 | 2875 | } |
---|
.. | .. |
---|
2912 | 2904 | bh = ext4_sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl, REQ_PRIO); |
---|
2913 | 2905 | if (IS_ERR(bh)) { |
---|
2914 | 2906 | error = PTR_ERR(bh); |
---|
2915 | | - if (error == -EIO) |
---|
2916 | | - EXT4_ERROR_INODE(inode, "block %llu read error", |
---|
2917 | | - EXT4_I(inode)->i_file_acl); |
---|
| 2907 | + if (error == -EIO) { |
---|
| 2908 | + EXT4_ERROR_INODE_ERR(inode, EIO, |
---|
| 2909 | + "block %llu read error", |
---|
| 2910 | + EXT4_I(inode)->i_file_acl); |
---|
| 2911 | + } |
---|
2918 | 2912 | bh = NULL; |
---|
2919 | 2913 | goto cleanup; |
---|
2920 | 2914 | } |
---|
.. | .. |
---|
2953 | 2947 | error); |
---|
2954 | 2948 | goto cleanup; |
---|
2955 | 2949 | } |
---|
| 2950 | + ext4_fc_mark_ineligible(inode->i_sb, EXT4_FC_REASON_XATTR); |
---|
2956 | 2951 | } |
---|
2957 | 2952 | error = 0; |
---|
2958 | 2953 | cleanup: |
---|