.. | .. |
---|
148 | 148 | struct super_block *sb = inode->i_sb; |
---|
149 | 149 | Indirect *p = chain; |
---|
150 | 150 | struct buffer_head *bh; |
---|
| 151 | + unsigned int key; |
---|
151 | 152 | int ret = -EIO; |
---|
152 | 153 | |
---|
153 | 154 | *err = 0; |
---|
.. | .. |
---|
156 | 157 | if (!p->key) |
---|
157 | 158 | goto no_block; |
---|
158 | 159 | while (--depth) { |
---|
159 | | - bh = sb_getblk(sb, le32_to_cpu(p->key)); |
---|
| 160 | + key = le32_to_cpu(p->key); |
---|
| 161 | + if (key > ext4_blocks_count(EXT4_SB(sb)->s_es)) { |
---|
| 162 | + /* the block was out of range */ |
---|
| 163 | + ret = -EFSCORRUPTED; |
---|
| 164 | + goto failure; |
---|
| 165 | + } |
---|
| 166 | + bh = sb_getblk(sb, key); |
---|
160 | 167 | if (unlikely(!bh)) { |
---|
161 | 168 | ret = -ENOMEM; |
---|
162 | 169 | goto failure; |
---|
163 | 170 | } |
---|
164 | 171 | |
---|
165 | 172 | if (!bh_uptodate_or_lock(bh)) { |
---|
166 | | - if (bh_submit_read(bh) < 0) { |
---|
| 173 | + if (ext4_read_bh(bh, 0, NULL) < 0) { |
---|
167 | 174 | put_bh(bh); |
---|
168 | 175 | goto failure; |
---|
169 | 176 | } |
---|
.. | .. |
---|
294 | 301 | } |
---|
295 | 302 | |
---|
296 | 303 | /** |
---|
297 | | - * ext4_alloc_branch - allocate and set up a chain of blocks. |
---|
298 | | - * @handle: handle for this transaction |
---|
299 | | - * @inode: owner |
---|
300 | | - * @indirect_blks: number of allocated indirect blocks |
---|
301 | | - * @blks: number of allocated direct blocks |
---|
302 | | - * @goal: preferred place for allocation |
---|
303 | | - * @offsets: offsets (in the blocks) to store the pointers to next. |
---|
304 | | - * @branch: place to store the chain in. |
---|
| 304 | + * ext4_alloc_branch() - allocate and set up a chain of blocks |
---|
| 305 | + * @handle: handle for this transaction |
---|
| 306 | + * @ar: structure describing the allocation request |
---|
| 307 | + * @indirect_blks: number of allocated indirect blocks |
---|
| 308 | + * @offsets: offsets (in the blocks) to store the pointers to next. |
---|
| 309 | + * @branch: place to store the chain in. |
---|
305 | 310 | * |
---|
306 | 311 | * This function allocates blocks, zeroes out all but the last one, |
---|
307 | 312 | * links them into chain and (if we are synchronous) writes them to disk. |
---|
.. | .. |
---|
333 | 338 | for (i = 0; i <= indirect_blks; i++) { |
---|
334 | 339 | if (i == indirect_blks) { |
---|
335 | 340 | new_blocks[i] = ext4_mb_new_blocks(handle, ar, &err); |
---|
336 | | - } else |
---|
| 341 | + } else { |
---|
337 | 342 | ar->goal = new_blocks[i] = ext4_new_meta_blocks(handle, |
---|
338 | 343 | ar->inode, ar->goal, |
---|
339 | 344 | ar->flags & EXT4_MB_DELALLOC_RESERVED, |
---|
340 | 345 | NULL, &err); |
---|
| 346 | + /* Simplify error cleanup... */ |
---|
| 347 | + branch[i+1].bh = NULL; |
---|
| 348 | + } |
---|
341 | 349 | if (err) { |
---|
342 | 350 | i--; |
---|
343 | 351 | goto failed; |
---|
.. | .. |
---|
379 | 387 | } |
---|
380 | 388 | return 0; |
---|
381 | 389 | failed: |
---|
| 390 | + if (i == indirect_blks) { |
---|
| 391 | + /* Free data blocks */ |
---|
| 392 | + ext4_free_blocks(handle, ar->inode, NULL, new_blocks[i], |
---|
| 393 | + ar->len, 0); |
---|
| 394 | + i--; |
---|
| 395 | + } |
---|
382 | 396 | for (; i >= 0; i--) { |
---|
383 | 397 | /* |
---|
384 | 398 | * We want to ext4_forget() only freshly allocated indirect |
---|
385 | | - * blocks. Buffer for new_blocks[i-1] is at branch[i].bh and |
---|
386 | | - * buffer at branch[0].bh is indirect block / inode already |
---|
387 | | - * existing before ext4_alloc_branch() was called. |
---|
| 399 | + * blocks. Buffer for new_blocks[i] is at branch[i+1].bh |
---|
| 400 | + * (buffer at branch[0].bh is indirect block / inode already |
---|
| 401 | + * existing before ext4_alloc_branch() was called). Also |
---|
| 402 | + * because blocks are freshly allocated, we don't need to |
---|
| 403 | + * revoke them which is why we don't set |
---|
| 404 | + * EXT4_FREE_BLOCKS_METADATA. |
---|
388 | 405 | */ |
---|
389 | | - if (i > 0 && i != indirect_blks && branch[i].bh) |
---|
390 | | - ext4_forget(handle, 1, ar->inode, branch[i].bh, |
---|
391 | | - branch[i].bh->b_blocknr); |
---|
392 | | - ext4_free_blocks(handle, ar->inode, NULL, new_blocks[i], |
---|
393 | | - (i == indirect_blks) ? ar->len : 1, 0); |
---|
| 406 | + ext4_free_blocks(handle, ar->inode, branch[i+1].bh, |
---|
| 407 | + new_blocks[i], 1, |
---|
| 408 | + branch[i+1].bh ? EXT4_FREE_BLOCKS_FORGET : 0); |
---|
394 | 409 | } |
---|
395 | 410 | return err; |
---|
396 | 411 | } |
---|
397 | 412 | |
---|
398 | 413 | /** |
---|
399 | | - * ext4_splice_branch - splice the allocated branch onto inode. |
---|
| 414 | + * ext4_splice_branch() - splice the allocated branch onto inode. |
---|
400 | 415 | * @handle: handle for this transaction |
---|
401 | | - * @inode: owner |
---|
402 | | - * @block: (logical) number of block we are adding |
---|
403 | | - * @chain: chain of indirect blocks (with a missing link - see |
---|
404 | | - * ext4_alloc_branch) |
---|
| 416 | + * @ar: structure describing the allocation request |
---|
405 | 417 | * @where: location of missing link |
---|
406 | 418 | * @num: number of indirect blocks we are adding |
---|
407 | | - * @blks: number of direct blocks we are adding |
---|
408 | 419 | * |
---|
409 | 420 | * This function fills the missing link and does all housekeeping needed in |
---|
410 | 421 | * inode (->i_blocks, etc.). In case of success we end up with the full |
---|
.. | .. |
---|
463 | 474 | /* |
---|
464 | 475 | * OK, we spliced it into the inode itself on a direct block. |
---|
465 | 476 | */ |
---|
466 | | - ext4_mark_inode_dirty(handle, ar->inode); |
---|
| 477 | + err = ext4_mark_inode_dirty(handle, ar->inode); |
---|
| 478 | + if (unlikely(err)) |
---|
| 479 | + goto err_out; |
---|
467 | 480 | jbd_debug(5, "splicing direct\n"); |
---|
468 | 481 | } |
---|
469 | 482 | return err; |
---|
.. | .. |
---|
587 | 600 | if (ext4_has_feature_bigalloc(inode->i_sb)) { |
---|
588 | 601 | EXT4_ERROR_INODE(inode, "Can't allocate blocks for " |
---|
589 | 602 | "non-extent mapped inodes with bigalloc"); |
---|
590 | | - return -EFSCORRUPTED; |
---|
| 603 | + err = -EFSCORRUPTED; |
---|
| 604 | + goto out; |
---|
591 | 605 | } |
---|
592 | 606 | |
---|
593 | 607 | /* Set up for the direct block allocation */ |
---|
.. | .. |
---|
635 | 649 | |
---|
636 | 650 | ext4_update_inode_fsync_trans(handle, inode, 1); |
---|
637 | 651 | count = ar.len; |
---|
| 652 | + |
---|
| 653 | + /* |
---|
| 654 | + * Update reserved blocks/metadata blocks after successful block |
---|
| 655 | + * allocation which had been deferred till now. |
---|
| 656 | + */ |
---|
| 657 | + if (flags & EXT4_GET_BLOCKS_DELALLOC_RESERVE) |
---|
| 658 | + ext4_da_update_reserve_space(inode, count, 1); |
---|
| 659 | + |
---|
638 | 660 | got_it: |
---|
639 | 661 | map->m_flags |= EXT4_MAP_MAPPED; |
---|
640 | 662 | map->m_pblk = le32_to_cpu(chain[depth-1].key); |
---|
.. | .. |
---|
656 | 678 | } |
---|
657 | 679 | |
---|
658 | 680 | /* |
---|
659 | | - * Calculate the number of metadata blocks need to reserve |
---|
660 | | - * to allocate a new block at @lblocks for non extent file based file |
---|
661 | | - */ |
---|
662 | | -int ext4_ind_calc_metadata_amount(struct inode *inode, sector_t lblock) |
---|
663 | | -{ |
---|
664 | | - struct ext4_inode_info *ei = EXT4_I(inode); |
---|
665 | | - sector_t dind_mask = ~((sector_t)EXT4_ADDR_PER_BLOCK(inode->i_sb) - 1); |
---|
666 | | - int blk_bits; |
---|
667 | | - |
---|
668 | | - if (lblock < EXT4_NDIR_BLOCKS) |
---|
669 | | - return 0; |
---|
670 | | - |
---|
671 | | - lblock -= EXT4_NDIR_BLOCKS; |
---|
672 | | - |
---|
673 | | - if (ei->i_da_metadata_calc_len && |
---|
674 | | - (lblock & dind_mask) == ei->i_da_metadata_calc_last_lblock) { |
---|
675 | | - ei->i_da_metadata_calc_len++; |
---|
676 | | - return 0; |
---|
677 | | - } |
---|
678 | | - ei->i_da_metadata_calc_last_lblock = lblock & dind_mask; |
---|
679 | | - ei->i_da_metadata_calc_len = 1; |
---|
680 | | - blk_bits = order_base_2(lblock); |
---|
681 | | - return (blk_bits / EXT4_ADDR_PER_BLOCK_BITS(inode->i_sb)) + 1; |
---|
682 | | -} |
---|
683 | | - |
---|
684 | | -/* |
---|
685 | 681 | * Calculate number of indirect blocks touched by mapping @nrblocks logically |
---|
686 | 682 | * contiguous blocks |
---|
687 | 683 | */ |
---|
.. | .. |
---|
695 | 691 | return DIV_ROUND_UP(nrblocks, EXT4_ADDR_PER_BLOCK(inode->i_sb)) + 4; |
---|
696 | 692 | } |
---|
697 | 693 | |
---|
| 694 | +static int ext4_ind_trunc_restart_fn(handle_t *handle, struct inode *inode, |
---|
| 695 | + struct buffer_head *bh, int *dropped) |
---|
| 696 | +{ |
---|
| 697 | + int err; |
---|
| 698 | + |
---|
| 699 | + if (bh) { |
---|
| 700 | + BUFFER_TRACE(bh, "call ext4_handle_dirty_metadata"); |
---|
| 701 | + err = ext4_handle_dirty_metadata(handle, inode, bh); |
---|
| 702 | + if (unlikely(err)) |
---|
| 703 | + return err; |
---|
| 704 | + } |
---|
| 705 | + err = ext4_mark_inode_dirty(handle, inode); |
---|
| 706 | + if (unlikely(err)) |
---|
| 707 | + return err; |
---|
| 708 | + /* |
---|
| 709 | + * Drop i_data_sem to avoid deadlock with ext4_map_blocks. At this |
---|
| 710 | + * moment, get_block can be called only for blocks inside i_size since |
---|
| 711 | + * page cache has been already dropped and writes are blocked by |
---|
| 712 | + * i_mutex. So we can safely drop the i_data_sem here. |
---|
| 713 | + */ |
---|
| 714 | + BUG_ON(EXT4_JOURNAL(inode) == NULL); |
---|
| 715 | + ext4_discard_preallocations(inode, 0); |
---|
| 716 | + up_write(&EXT4_I(inode)->i_data_sem); |
---|
| 717 | + *dropped = 1; |
---|
| 718 | + return 0; |
---|
| 719 | +} |
---|
| 720 | + |
---|
698 | 721 | /* |
---|
699 | 722 | * Truncate transactions can be complex and absolutely huge. So we need to |
---|
700 | | - * be able to restart the transaction at a conventient checkpoint to make |
---|
| 723 | + * be able to restart the transaction at a convenient checkpoint to make |
---|
701 | 724 | * sure we don't overflow the journal. |
---|
702 | 725 | * |
---|
703 | 726 | * Try to extend this transaction for the purposes of truncation. If |
---|
704 | | - * extend fails, we need to propagate the failure up and restart the |
---|
705 | | - * transaction in the top-level truncate loop. --sct |
---|
706 | | - * |
---|
707 | | - * Returns 0 if we managed to create more room. If we can't create more |
---|
708 | | - * room, and the transaction must be restarted we return 1. |
---|
| 727 | + * extend fails, we restart transaction. |
---|
709 | 728 | */ |
---|
710 | | -static int try_to_extend_transaction(handle_t *handle, struct inode *inode) |
---|
| 729 | +static int ext4_ind_truncate_ensure_credits(handle_t *handle, |
---|
| 730 | + struct inode *inode, |
---|
| 731 | + struct buffer_head *bh, |
---|
| 732 | + int revoke_creds) |
---|
711 | 733 | { |
---|
712 | | - if (!ext4_handle_valid(handle)) |
---|
713 | | - return 0; |
---|
714 | | - if (ext4_handle_has_enough_credits(handle, EXT4_RESERVE_TRANS_BLOCKS+1)) |
---|
715 | | - return 0; |
---|
716 | | - if (!ext4_journal_extend(handle, ext4_blocks_for_truncate(inode))) |
---|
717 | | - return 0; |
---|
718 | | - return 1; |
---|
| 734 | + int ret; |
---|
| 735 | + int dropped = 0; |
---|
| 736 | + |
---|
| 737 | + ret = ext4_journal_ensure_credits_fn(handle, EXT4_RESERVE_TRANS_BLOCKS, |
---|
| 738 | + ext4_blocks_for_truncate(inode), revoke_creds, |
---|
| 739 | + ext4_ind_trunc_restart_fn(handle, inode, bh, &dropped)); |
---|
| 740 | + if (dropped) |
---|
| 741 | + down_write(&EXT4_I(inode)->i_data_sem); |
---|
| 742 | + if (ret <= 0) |
---|
| 743 | + return ret; |
---|
| 744 | + if (bh) { |
---|
| 745 | + BUFFER_TRACE(bh, "retaking write access"); |
---|
| 746 | + ret = ext4_journal_get_write_access(handle, bh); |
---|
| 747 | + if (unlikely(ret)) |
---|
| 748 | + return ret; |
---|
| 749 | + } |
---|
| 750 | + return 0; |
---|
719 | 751 | } |
---|
720 | 752 | |
---|
721 | 753 | /* |
---|
.. | .. |
---|
849 | 881 | return 1; |
---|
850 | 882 | } |
---|
851 | 883 | |
---|
852 | | - if (try_to_extend_transaction(handle, inode)) { |
---|
853 | | - if (bh) { |
---|
854 | | - BUFFER_TRACE(bh, "call ext4_handle_dirty_metadata"); |
---|
855 | | - err = ext4_handle_dirty_metadata(handle, inode, bh); |
---|
856 | | - if (unlikely(err)) |
---|
857 | | - goto out_err; |
---|
858 | | - } |
---|
859 | | - err = ext4_mark_inode_dirty(handle, inode); |
---|
860 | | - if (unlikely(err)) |
---|
861 | | - goto out_err; |
---|
862 | | - err = ext4_truncate_restart_trans(handle, inode, |
---|
863 | | - ext4_blocks_for_truncate(inode)); |
---|
864 | | - if (unlikely(err)) |
---|
865 | | - goto out_err; |
---|
866 | | - if (bh) { |
---|
867 | | - BUFFER_TRACE(bh, "retaking write access"); |
---|
868 | | - err = ext4_journal_get_write_access(handle, bh); |
---|
869 | | - if (unlikely(err)) |
---|
870 | | - goto out_err; |
---|
871 | | - } |
---|
872 | | - } |
---|
| 884 | + err = ext4_ind_truncate_ensure_credits(handle, inode, bh, |
---|
| 885 | + ext4_free_data_revoke_credits(inode, count)); |
---|
| 886 | + if (err < 0) |
---|
| 887 | + goto out_err; |
---|
873 | 888 | |
---|
874 | 889 | for (p = first; p < last; p++) |
---|
875 | 890 | *p = 0; |
---|
.. | .. |
---|
1013 | 1028 | } |
---|
1014 | 1029 | |
---|
1015 | 1030 | /* Go read the buffer for the next level down */ |
---|
1016 | | - bh = sb_bread(inode->i_sb, nr); |
---|
| 1031 | + bh = ext4_sb_bread(inode->i_sb, nr, 0); |
---|
1017 | 1032 | |
---|
1018 | 1033 | /* |
---|
1019 | 1034 | * A read failure? Report error and clear slot |
---|
1020 | 1035 | * (should be rare). |
---|
1021 | 1036 | */ |
---|
1022 | | - if (!bh) { |
---|
1023 | | - EXT4_ERROR_INODE_BLOCK(inode, nr, |
---|
| 1037 | + if (IS_ERR(bh)) { |
---|
| 1038 | + ext4_error_inode_block(inode, nr, -PTR_ERR(bh), |
---|
1024 | 1039 | "Read failure"); |
---|
1025 | 1040 | continue; |
---|
1026 | 1041 | } |
---|
.. | .. |
---|
1034 | 1049 | brelse(bh); |
---|
1035 | 1050 | |
---|
1036 | 1051 | /* |
---|
1037 | | - * Everything below this this pointer has been |
---|
| 1052 | + * Everything below this pointer has been |
---|
1038 | 1053 | * released. Now let this top-of-subtree go. |
---|
1039 | 1054 | * |
---|
1040 | 1055 | * We want the freeing of this indirect block to be |
---|
.. | .. |
---|
1051 | 1066 | */ |
---|
1052 | 1067 | if (ext4_handle_is_aborted(handle)) |
---|
1053 | 1068 | return; |
---|
1054 | | - if (try_to_extend_transaction(handle, inode)) { |
---|
1055 | | - ext4_mark_inode_dirty(handle, inode); |
---|
1056 | | - ext4_truncate_restart_trans(handle, inode, |
---|
1057 | | - ext4_blocks_for_truncate(inode)); |
---|
1058 | | - } |
---|
| 1069 | + if (ext4_ind_truncate_ensure_credits(handle, inode, |
---|
| 1070 | + NULL, |
---|
| 1071 | + ext4_free_metadata_revoke_credits( |
---|
| 1072 | + inode->i_sb, 1)) < 0) |
---|
| 1073 | + return; |
---|
1059 | 1074 | |
---|
1060 | 1075 | /* |
---|
1061 | 1076 | * The forget flag here is critical because if |
---|
.. | .. |
---|
1181 | 1196 | ext4_free_branches(handle, inode, NULL, &nr, &nr+1, 1); |
---|
1182 | 1197 | i_data[EXT4_IND_BLOCK] = 0; |
---|
1183 | 1198 | } |
---|
| 1199 | + fallthrough; |
---|
1184 | 1200 | case EXT4_IND_BLOCK: |
---|
1185 | 1201 | nr = i_data[EXT4_DIND_BLOCK]; |
---|
1186 | 1202 | if (nr) { |
---|
1187 | 1203 | ext4_free_branches(handle, inode, NULL, &nr, &nr+1, 2); |
---|
1188 | 1204 | i_data[EXT4_DIND_BLOCK] = 0; |
---|
1189 | 1205 | } |
---|
| 1206 | + fallthrough; |
---|
1190 | 1207 | case EXT4_DIND_BLOCK: |
---|
1191 | 1208 | nr = i_data[EXT4_TIND_BLOCK]; |
---|
1192 | 1209 | if (nr) { |
---|
1193 | 1210 | ext4_free_branches(handle, inode, NULL, &nr, &nr+1, 3); |
---|
1194 | 1211 | i_data[EXT4_TIND_BLOCK] = 0; |
---|
1195 | 1212 | } |
---|
| 1213 | + fallthrough; |
---|
1196 | 1214 | case EXT4_TIND_BLOCK: |
---|
1197 | 1215 | ; |
---|
1198 | 1216 | } |
---|
.. | .. |
---|
1432 | 1450 | ext4_free_branches(handle, inode, NULL, &nr, &nr+1, 1); |
---|
1433 | 1451 | i_data[EXT4_IND_BLOCK] = 0; |
---|
1434 | 1452 | } |
---|
| 1453 | + fallthrough; |
---|
1435 | 1454 | case EXT4_IND_BLOCK: |
---|
1436 | 1455 | if (++n >= n2) |
---|
1437 | 1456 | break; |
---|
.. | .. |
---|
1440 | 1459 | ext4_free_branches(handle, inode, NULL, &nr, &nr+1, 2); |
---|
1441 | 1460 | i_data[EXT4_DIND_BLOCK] = 0; |
---|
1442 | 1461 | } |
---|
| 1462 | + fallthrough; |
---|
1443 | 1463 | case EXT4_DIND_BLOCK: |
---|
1444 | 1464 | if (++n >= n2) |
---|
1445 | 1465 | break; |
---|
.. | .. |
---|
1448 | 1468 | ext4_free_branches(handle, inode, NULL, &nr, &nr+1, 3); |
---|
1449 | 1469 | i_data[EXT4_TIND_BLOCK] = 0; |
---|
1450 | 1470 | } |
---|
| 1471 | + fallthrough; |
---|
1451 | 1472 | case EXT4_TIND_BLOCK: |
---|
1452 | 1473 | ; |
---|
1453 | 1474 | } |
---|