diff options
| -rw-r--r-- | fs/ocfs2/alloc.c | 685 | ||||
| -rw-r--r-- | fs/ocfs2/alloc.h | 8 | ||||
| -rw-r--r-- | fs/ocfs2/dir.c | 4 | ||||
| -rw-r--r-- | fs/ocfs2/file.c | 11 | ||||
| -rw-r--r-- | fs/ocfs2/inode.c | 9 | ||||
| -rw-r--r-- | fs/ocfs2/refcounttree.c | 29 | ||||
| -rw-r--r-- | fs/ocfs2/refcounttree.h | 4 |
7 files changed, 178 insertions, 572 deletions
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c index 0cb2945eb817..0cb4248e03cd 100644 --- a/fs/ocfs2/alloc.c +++ b/fs/ocfs2/alloc.c | |||
| @@ -5587,19 +5587,97 @@ out: | |||
| 5587 | return ret; | 5587 | return ret; |
| 5588 | } | 5588 | } |
| 5589 | 5589 | ||
| 5590 | /* | ||
| 5591 | * ocfs2_reserve_blocks_for_rec_trunc() would look basically the | ||
| 5592 | * same as ocfs2_lock_alloctors(), except for it accepts a blocks | ||
| 5593 | * number to reserve some extra blocks, and it only handles meta | ||
| 5594 | * data allocations. | ||
| 5595 | * | ||
| 5596 | * Currently, only ocfs2_remove_btree_range() uses it for truncating | ||
| 5597 | * and punching holes. | ||
| 5598 | */ | ||
| 5599 | static int ocfs2_reserve_blocks_for_rec_trunc(struct inode *inode, | ||
| 5600 | struct ocfs2_extent_tree *et, | ||
| 5601 | u32 extents_to_split, | ||
| 5602 | struct ocfs2_alloc_context **ac, | ||
| 5603 | int extra_blocks) | ||
| 5604 | { | ||
| 5605 | int ret = 0, num_free_extents; | ||
| 5606 | unsigned int max_recs_needed = 2 * extents_to_split; | ||
| 5607 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | ||
| 5608 | |||
| 5609 | *ac = NULL; | ||
| 5610 | |||
| 5611 | num_free_extents = ocfs2_num_free_extents(osb, et); | ||
| 5612 | if (num_free_extents < 0) { | ||
| 5613 | ret = num_free_extents; | ||
| 5614 | mlog_errno(ret); | ||
| 5615 | goto out; | ||
| 5616 | } | ||
| 5617 | |||
| 5618 | if (!num_free_extents || | ||
| 5619 | (ocfs2_sparse_alloc(osb) && num_free_extents < max_recs_needed)) | ||
| 5620 | extra_blocks += ocfs2_extend_meta_needed(et->et_root_el); | ||
| 5621 | |||
| 5622 | if (extra_blocks) { | ||
| 5623 | ret = ocfs2_reserve_new_metadata_blocks(osb, extra_blocks, ac); | ||
| 5624 | if (ret < 0) { | ||
| 5625 | if (ret != -ENOSPC) | ||
| 5626 | mlog_errno(ret); | ||
| 5627 | goto out; | ||
| 5628 | } | ||
| 5629 | } | ||
| 5630 | |||
| 5631 | out: | ||
| 5632 | if (ret) { | ||
| 5633 | if (*ac) { | ||
| 5634 | ocfs2_free_alloc_context(*ac); | ||
| 5635 | *ac = NULL; | ||
| 5636 | } | ||
| 5637 | } | ||
| 5638 | |||
| 5639 | return ret; | ||
| 5640 | } | ||
| 5641 | |||
| 5590 | int ocfs2_remove_btree_range(struct inode *inode, | 5642 | int ocfs2_remove_btree_range(struct inode *inode, |
| 5591 | struct ocfs2_extent_tree *et, | 5643 | struct ocfs2_extent_tree *et, |
| 5592 | u32 cpos, u32 phys_cpos, u32 len, | 5644 | u32 cpos, u32 phys_cpos, u32 len, int flags, |
| 5593 | struct ocfs2_cached_dealloc_ctxt *dealloc) | 5645 | struct ocfs2_cached_dealloc_ctxt *dealloc, |
| 5646 | u64 refcount_loc) | ||
| 5594 | { | 5647 | { |
| 5595 | int ret; | 5648 | int ret, credits = 0, extra_blocks = 0; |
| 5596 | u64 phys_blkno = ocfs2_clusters_to_blocks(inode->i_sb, phys_cpos); | 5649 | u64 phys_blkno = ocfs2_clusters_to_blocks(inode->i_sb, phys_cpos); |
| 5597 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | 5650 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); |
| 5598 | struct inode *tl_inode = osb->osb_tl_inode; | 5651 | struct inode *tl_inode = osb->osb_tl_inode; |
| 5599 | handle_t *handle; | 5652 | handle_t *handle; |
| 5600 | struct ocfs2_alloc_context *meta_ac = NULL; | 5653 | struct ocfs2_alloc_context *meta_ac = NULL; |
| 5654 | struct ocfs2_refcount_tree *ref_tree = NULL; | ||
| 5655 | |||
| 5656 | if ((flags & OCFS2_EXT_REFCOUNTED) && len) { | ||
| 5657 | BUG_ON(!(OCFS2_I(inode)->ip_dyn_features & | ||
| 5658 | OCFS2_HAS_REFCOUNT_FL)); | ||
| 5659 | |||
| 5660 | ret = ocfs2_lock_refcount_tree(osb, refcount_loc, 1, | ||
| 5661 | &ref_tree, NULL); | ||
| 5662 | if (ret) { | ||
| 5663 | mlog_errno(ret); | ||
| 5664 | goto out; | ||
| 5665 | } | ||
| 5666 | |||
| 5667 | ret = ocfs2_prepare_refcount_change_for_del(inode, | ||
| 5668 | refcount_loc, | ||
| 5669 | phys_blkno, | ||
| 5670 | len, | ||
| 5671 | &credits, | ||
| 5672 | &extra_blocks); | ||
| 5673 | if (ret < 0) { | ||
| 5674 | mlog_errno(ret); | ||
| 5675 | goto out; | ||
| 5676 | } | ||
| 5677 | } | ||
| 5601 | 5678 | ||
| 5602 | ret = ocfs2_lock_allocators(inode, et, 0, 1, NULL, &meta_ac); | 5679 | ret = ocfs2_reserve_blocks_for_rec_trunc(inode, et, 1, &meta_ac, |
| 5680 | extra_blocks); | ||
| 5603 | if (ret) { | 5681 | if (ret) { |
| 5604 | mlog_errno(ret); | 5682 | mlog_errno(ret); |
| 5605 | return ret; | 5683 | return ret; |
| @@ -5615,7 +5693,8 @@ int ocfs2_remove_btree_range(struct inode *inode, | |||
| 5615 | } | 5693 | } |
| 5616 | } | 5694 | } |
| 5617 | 5695 | ||
| 5618 | handle = ocfs2_start_trans(osb, ocfs2_remove_extent_credits(osb->sb)); | 5696 | handle = ocfs2_start_trans(osb, |
| 5697 | ocfs2_remove_extent_credits(osb->sb) + credits); | ||
| 5619 | if (IS_ERR(handle)) { | 5698 | if (IS_ERR(handle)) { |
| 5620 | ret = PTR_ERR(handle); | 5699 | ret = PTR_ERR(handle); |
| 5621 | mlog_errno(ret); | 5700 | mlog_errno(ret); |
| @@ -5642,9 +5721,20 @@ int ocfs2_remove_btree_range(struct inode *inode, | |||
| 5642 | 5721 | ||
| 5643 | ocfs2_journal_dirty(handle, et->et_root_bh); | 5722 | ocfs2_journal_dirty(handle, et->et_root_bh); |
| 5644 | 5723 | ||
| 5645 | ret = ocfs2_truncate_log_append(osb, handle, phys_blkno, len); | 5724 | if (phys_blkno) { |
| 5646 | if (ret) | 5725 | if (flags & OCFS2_EXT_REFCOUNTED) |
| 5647 | mlog_errno(ret); | 5726 | ret = ocfs2_decrease_refcount(inode, handle, |
| 5727 | ocfs2_blocks_to_clusters(osb->sb, | ||
| 5728 | phys_blkno), | ||
| 5729 | len, meta_ac, | ||
| 5730 | dealloc, 1); | ||
| 5731 | else | ||
| 5732 | ret = ocfs2_truncate_log_append(osb, handle, | ||
| 5733 | phys_blkno, len); | ||
| 5734 | if (ret) | ||
| 5735 | mlog_errno(ret); | ||
| 5736 | |||
| 5737 | } | ||
| 5648 | 5738 | ||
| 5649 | out_commit: | 5739 | out_commit: |
| 5650 | ocfs2_commit_trans(osb, handle); | 5740 | ocfs2_commit_trans(osb, handle); |
| @@ -5654,6 +5744,9 @@ out: | |||
| 5654 | if (meta_ac) | 5744 | if (meta_ac) |
| 5655 | ocfs2_free_alloc_context(meta_ac); | 5745 | ocfs2_free_alloc_context(meta_ac); |
| 5656 | 5746 | ||
| 5747 | if (ref_tree) | ||
| 5748 | ocfs2_unlock_refcount_tree(osb, ref_tree, 1); | ||
| 5749 | |||
| 5657 | return ret; | 5750 | return ret; |
| 5658 | } | 5751 | } |
| 5659 | 5752 | ||
| @@ -6481,417 +6574,6 @@ static int ocfs2_cache_extent_block_free(struct ocfs2_cached_dealloc_ctxt *ctxt, | |||
| 6481 | le16_to_cpu(eb->h_suballoc_bit)); | 6574 | le16_to_cpu(eb->h_suballoc_bit)); |
| 6482 | } | 6575 | } |
| 6483 | 6576 | ||
| 6484 | /* This function will figure out whether the currently last extent | ||
| 6485 | * block will be deleted, and if it will, what the new last extent | ||
| 6486 | * block will be so we can update his h_next_leaf_blk field, as well | ||
| 6487 | * as the dinodes i_last_eb_blk */ | ||
| 6488 | static int ocfs2_find_new_last_ext_blk(struct inode *inode, | ||
| 6489 | unsigned int clusters_to_del, | ||
| 6490 | struct ocfs2_path *path, | ||
| 6491 | struct buffer_head **new_last_eb) | ||
| 6492 | { | ||
| 6493 | int next_free, ret = 0; | ||
| 6494 | u32 cpos; | ||
| 6495 | struct ocfs2_extent_rec *rec; | ||
| 6496 | struct ocfs2_extent_block *eb; | ||
| 6497 | struct ocfs2_extent_list *el; | ||
| 6498 | struct buffer_head *bh = NULL; | ||
| 6499 | |||
| 6500 | *new_last_eb = NULL; | ||
| 6501 | |||
| 6502 | /* we have no tree, so of course, no last_eb. */ | ||
| 6503 | if (!path->p_tree_depth) | ||
| 6504 | goto out; | ||
| 6505 | |||
| 6506 | /* trunc to zero special case - this makes tree_depth = 0 | ||
| 6507 | * regardless of what it is. */ | ||
| 6508 | if (OCFS2_I(inode)->ip_clusters == clusters_to_del) | ||
| 6509 | goto out; | ||
| 6510 | |||
| 6511 | el = path_leaf_el(path); | ||
| 6512 | BUG_ON(!el->l_next_free_rec); | ||
| 6513 | |||
| 6514 | /* | ||
| 6515 | * Make sure that this extent list will actually be empty | ||
| 6516 | * after we clear away the data. We can shortcut out if | ||
| 6517 | * there's more than one non-empty extent in the | ||
| 6518 | * list. Otherwise, a check of the remaining extent is | ||
| 6519 | * necessary. | ||
| 6520 | */ | ||
| 6521 | next_free = le16_to_cpu(el->l_next_free_rec); | ||
| 6522 | rec = NULL; | ||
| 6523 | if (ocfs2_is_empty_extent(&el->l_recs[0])) { | ||
| 6524 | if (next_free > 2) | ||
| 6525 | goto out; | ||
| 6526 | |||
| 6527 | /* We may have a valid extent in index 1, check it. */ | ||
| 6528 | if (next_free == 2) | ||
| 6529 | rec = &el->l_recs[1]; | ||
| 6530 | |||
| 6531 | /* | ||
| 6532 | * Fall through - no more nonempty extents, so we want | ||
| 6533 | * to delete this leaf. | ||
| 6534 | */ | ||
| 6535 | } else { | ||
| 6536 | if (next_free > 1) | ||
| 6537 | goto out; | ||
| 6538 | |||
| 6539 | rec = &el->l_recs[0]; | ||
| 6540 | } | ||
| 6541 | |||
| 6542 | if (rec) { | ||
| 6543 | /* | ||
| 6544 | * Check it we'll only be trimming off the end of this | ||
| 6545 | * cluster. | ||
| 6546 | */ | ||
| 6547 | if (le16_to_cpu(rec->e_leaf_clusters) > clusters_to_del) | ||
| 6548 | goto out; | ||
| 6549 | } | ||
| 6550 | |||
| 6551 | ret = ocfs2_find_cpos_for_left_leaf(inode->i_sb, path, &cpos); | ||
| 6552 | if (ret) { | ||
| 6553 | mlog_errno(ret); | ||
| 6554 | goto out; | ||
| 6555 | } | ||
| 6556 | |||
| 6557 | ret = ocfs2_find_leaf(INODE_CACHE(inode), path_root_el(path), cpos, &bh); | ||
| 6558 | if (ret) { | ||
| 6559 | mlog_errno(ret); | ||
| 6560 | goto out; | ||
| 6561 | } | ||
| 6562 | |||
| 6563 | eb = (struct ocfs2_extent_block *) bh->b_data; | ||
| 6564 | el = &eb->h_list; | ||
| 6565 | |||
| 6566 | /* ocfs2_find_leaf() gets the eb from ocfs2_read_extent_block(). | ||
| 6567 | * Any corruption is a code bug. */ | ||
| 6568 | BUG_ON(!OCFS2_IS_VALID_EXTENT_BLOCK(eb)); | ||
| 6569 | |||
| 6570 | *new_last_eb = bh; | ||
| 6571 | get_bh(*new_last_eb); | ||
| 6572 | mlog(0, "returning block %llu, (cpos: %u)\n", | ||
| 6573 | (unsigned long long)le64_to_cpu(eb->h_blkno), cpos); | ||
| 6574 | out: | ||
| 6575 | brelse(bh); | ||
| 6576 | |||
| 6577 | return ret; | ||
| 6578 | } | ||
| 6579 | |||
| 6580 | /* | ||
| 6581 | * Trim some clusters off the rightmost edge of a tree. Only called | ||
| 6582 | * during truncate. | ||
| 6583 | * | ||
| 6584 | * The caller needs to: | ||
| 6585 | * - start journaling of each path component. | ||
| 6586 | * - compute and fully set up any new last ext block | ||
| 6587 | */ | ||
| 6588 | static int ocfs2_trim_tree(struct inode *inode, struct ocfs2_path *path, | ||
| 6589 | handle_t *handle, struct ocfs2_truncate_context *tc, | ||
| 6590 | u32 clusters_to_del, u64 *delete_start, u8 *flags) | ||
| 6591 | { | ||
| 6592 | int ret, i, index = path->p_tree_depth; | ||
| 6593 | u32 new_edge = 0; | ||
| 6594 | u64 deleted_eb = 0; | ||
| 6595 | struct buffer_head *bh; | ||
| 6596 | struct ocfs2_extent_list *el; | ||
| 6597 | struct ocfs2_extent_rec *rec; | ||
| 6598 | |||
| 6599 | *delete_start = 0; | ||
| 6600 | *flags = 0; | ||
| 6601 | |||
| 6602 | while (index >= 0) { | ||
| 6603 | bh = path->p_node[index].bh; | ||
| 6604 | el = path->p_node[index].el; | ||
| 6605 | |||
| 6606 | mlog(0, "traveling tree (index = %d, block = %llu)\n", | ||
| 6607 | index, (unsigned long long)bh->b_blocknr); | ||
| 6608 | |||
| 6609 | BUG_ON(le16_to_cpu(el->l_next_free_rec) == 0); | ||
| 6610 | |||
| 6611 | if (index != | ||
| 6612 | (path->p_tree_depth - le16_to_cpu(el->l_tree_depth))) { | ||
| 6613 | ocfs2_error(inode->i_sb, | ||
| 6614 | "Inode %lu has invalid ext. block %llu", | ||
| 6615 | inode->i_ino, | ||
| 6616 | (unsigned long long)bh->b_blocknr); | ||
| 6617 | ret = -EROFS; | ||
| 6618 | goto out; | ||
| 6619 | } | ||
| 6620 | |||
| 6621 | find_tail_record: | ||
| 6622 | i = le16_to_cpu(el->l_next_free_rec) - 1; | ||
| 6623 | rec = &el->l_recs[i]; | ||
| 6624 | |||
| 6625 | mlog(0, "Extent list before: record %d: (%u, %u, %llu), " | ||
| 6626 | "next = %u\n", i, le32_to_cpu(rec->e_cpos), | ||
| 6627 | ocfs2_rec_clusters(el, rec), | ||
| 6628 | (unsigned long long)le64_to_cpu(rec->e_blkno), | ||
| 6629 | le16_to_cpu(el->l_next_free_rec)); | ||
| 6630 | |||
| 6631 | BUG_ON(ocfs2_rec_clusters(el, rec) < clusters_to_del); | ||
| 6632 | |||
| 6633 | if (le16_to_cpu(el->l_tree_depth) == 0) { | ||
| 6634 | /* | ||
| 6635 | * If the leaf block contains a single empty | ||
| 6636 | * extent and no records, we can just remove | ||
| 6637 | * the block. | ||
| 6638 | */ | ||
| 6639 | if (i == 0 && ocfs2_is_empty_extent(rec)) { | ||
| 6640 | memset(rec, 0, | ||
| 6641 | sizeof(struct ocfs2_extent_rec)); | ||
| 6642 | el->l_next_free_rec = cpu_to_le16(0); | ||
| 6643 | |||
| 6644 | goto delete; | ||
| 6645 | } | ||
| 6646 | |||
| 6647 | /* | ||
| 6648 | * Remove any empty extents by shifting things | ||
| 6649 | * left. That should make life much easier on | ||
| 6650 | * the code below. This condition is rare | ||
| 6651 | * enough that we shouldn't see a performance | ||
| 6652 | * hit. | ||
| 6653 | */ | ||
| 6654 | if (ocfs2_is_empty_extent(&el->l_recs[0])) { | ||
| 6655 | le16_add_cpu(&el->l_next_free_rec, -1); | ||
| 6656 | |||
| 6657 | for(i = 0; | ||
| 6658 | i < le16_to_cpu(el->l_next_free_rec); i++) | ||
| 6659 | el->l_recs[i] = el->l_recs[i + 1]; | ||
| 6660 | |||
| 6661 | memset(&el->l_recs[i], 0, | ||
| 6662 | sizeof(struct ocfs2_extent_rec)); | ||
| 6663 | |||
| 6664 | /* | ||
| 6665 | * We've modified our extent list. The | ||
| 6666 | * simplest way to handle this change | ||
| 6667 | * is to being the search from the | ||
| 6668 | * start again. | ||
| 6669 | */ | ||
| 6670 | goto find_tail_record; | ||
| 6671 | } | ||
| 6672 | |||
| 6673 | le16_add_cpu(&rec->e_leaf_clusters, -clusters_to_del); | ||
| 6674 | |||
| 6675 | /* | ||
| 6676 | * We'll use "new_edge" on our way back up the | ||
| 6677 | * tree to know what our rightmost cpos is. | ||
| 6678 | */ | ||
| 6679 | new_edge = le16_to_cpu(rec->e_leaf_clusters); | ||
| 6680 | new_edge += le32_to_cpu(rec->e_cpos); | ||
| 6681 | |||
| 6682 | /* | ||
| 6683 | * The caller will use this to delete data blocks. | ||
| 6684 | */ | ||
| 6685 | *delete_start = le64_to_cpu(rec->e_blkno) | ||
| 6686 | + ocfs2_clusters_to_blocks(inode->i_sb, | ||
| 6687 | le16_to_cpu(rec->e_leaf_clusters)); | ||
| 6688 | *flags = rec->e_flags; | ||
| 6689 | |||
| 6690 | /* | ||
| 6691 | * If it's now empty, remove this record. | ||
| 6692 | */ | ||
| 6693 | if (le16_to_cpu(rec->e_leaf_clusters) == 0) { | ||
| 6694 | memset(rec, 0, | ||
| 6695 | sizeof(struct ocfs2_extent_rec)); | ||
| 6696 | le16_add_cpu(&el->l_next_free_rec, -1); | ||
| 6697 | } | ||
| 6698 | } else { | ||
| 6699 | if (le64_to_cpu(rec->e_blkno) == deleted_eb) { | ||
| 6700 | memset(rec, 0, | ||
| 6701 | sizeof(struct ocfs2_extent_rec)); | ||
| 6702 | le16_add_cpu(&el->l_next_free_rec, -1); | ||
| 6703 | |||
| 6704 | goto delete; | ||
| 6705 | } | ||
| 6706 | |||
| 6707 | /* Can this actually happen? */ | ||
| 6708 | if (le16_to_cpu(el->l_next_free_rec) == 0) | ||
| 6709 | goto delete; | ||
| 6710 | |||
| 6711 | /* | ||
| 6712 | * We never actually deleted any clusters | ||
| 6713 | * because our leaf was empty. There's no | ||
| 6714 | * reason to adjust the rightmost edge then. | ||
| 6715 | */ | ||
| 6716 | if (new_edge == 0) | ||
| 6717 | goto delete; | ||
| 6718 | |||
| 6719 | rec->e_int_clusters = cpu_to_le32(new_edge); | ||
| 6720 | le32_add_cpu(&rec->e_int_clusters, | ||
| 6721 | -le32_to_cpu(rec->e_cpos)); | ||
| 6722 | |||
| 6723 | /* | ||
| 6724 | * A deleted child record should have been | ||
| 6725 | * caught above. | ||
| 6726 | */ | ||
| 6727 | BUG_ON(le32_to_cpu(rec->e_int_clusters) == 0); | ||
| 6728 | } | ||
| 6729 | |||
| 6730 | delete: | ||
| 6731 | ocfs2_journal_dirty(handle, bh); | ||
| 6732 | |||
| 6733 | mlog(0, "extent list container %llu, after: record %d: " | ||
| 6734 | "(%u, %u, %llu), next = %u.\n", | ||
| 6735 | (unsigned long long)bh->b_blocknr, i, | ||
| 6736 | le32_to_cpu(rec->e_cpos), ocfs2_rec_clusters(el, rec), | ||
| 6737 | (unsigned long long)le64_to_cpu(rec->e_blkno), | ||
| 6738 | le16_to_cpu(el->l_next_free_rec)); | ||
| 6739 | |||
| 6740 | /* | ||
| 6741 | * We must be careful to only attempt delete of an | ||
| 6742 | * extent block (and not the root inode block). | ||
| 6743 | */ | ||
| 6744 | if (index > 0 && le16_to_cpu(el->l_next_free_rec) == 0) { | ||
| 6745 | struct ocfs2_extent_block *eb = | ||
| 6746 | (struct ocfs2_extent_block *)bh->b_data; | ||
| 6747 | |||
| 6748 | /* | ||
| 6749 | * Save this for use when processing the | ||
| 6750 | * parent block. | ||
| 6751 | */ | ||
| 6752 | deleted_eb = le64_to_cpu(eb->h_blkno); | ||
| 6753 | |||
| 6754 | mlog(0, "deleting this extent block.\n"); | ||
| 6755 | |||
| 6756 | ocfs2_remove_from_cache(INODE_CACHE(inode), bh); | ||
| 6757 | |||
| 6758 | BUG_ON(ocfs2_rec_clusters(el, &el->l_recs[0])); | ||
| 6759 | BUG_ON(le32_to_cpu(el->l_recs[0].e_cpos)); | ||
| 6760 | BUG_ON(le64_to_cpu(el->l_recs[0].e_blkno)); | ||
| 6761 | |||
| 6762 | ret = ocfs2_cache_extent_block_free(&tc->tc_dealloc, eb); | ||
| 6763 | /* An error here is not fatal. */ | ||
| 6764 | if (ret < 0) | ||
| 6765 | mlog_errno(ret); | ||
| 6766 | } else { | ||
| 6767 | deleted_eb = 0; | ||
| 6768 | } | ||
| 6769 | |||
| 6770 | index--; | ||
| 6771 | } | ||
| 6772 | |||
| 6773 | ret = 0; | ||
| 6774 | out: | ||
| 6775 | return ret; | ||
| 6776 | } | ||
| 6777 | |||
| 6778 | static int ocfs2_do_truncate(struct ocfs2_super *osb, | ||
| 6779 | unsigned int clusters_to_del, | ||
| 6780 | struct inode *inode, | ||
| 6781 | struct buffer_head *fe_bh, | ||
| 6782 | handle_t *handle, | ||
| 6783 | struct ocfs2_truncate_context *tc, | ||
| 6784 | struct ocfs2_path *path, | ||
| 6785 | struct ocfs2_alloc_context *meta_ac) | ||
| 6786 | { | ||
| 6787 | int status; | ||
| 6788 | struct ocfs2_dinode *fe; | ||
| 6789 | struct ocfs2_extent_block *last_eb = NULL; | ||
| 6790 | struct ocfs2_extent_list *el; | ||
| 6791 | struct buffer_head *last_eb_bh = NULL; | ||
| 6792 | u64 delete_blk = 0; | ||
| 6793 | u8 rec_flags; | ||
| 6794 | |||
| 6795 | fe = (struct ocfs2_dinode *) fe_bh->b_data; | ||
| 6796 | |||
| 6797 | status = ocfs2_find_new_last_ext_blk(inode, clusters_to_del, | ||
| 6798 | path, &last_eb_bh); | ||
| 6799 | if (status < 0) { | ||
| 6800 | mlog_errno(status); | ||
| 6801 | goto bail; | ||
| 6802 | } | ||
| 6803 | |||
| 6804 | /* | ||
| 6805 | * Each component will be touched, so we might as well journal | ||
| 6806 | * here to avoid having to handle errors later. | ||
| 6807 | */ | ||
| 6808 | status = ocfs2_journal_access_path(INODE_CACHE(inode), handle, path); | ||
| 6809 | if (status < 0) { | ||
| 6810 | mlog_errno(status); | ||
| 6811 | goto bail; | ||
| 6812 | } | ||
| 6813 | |||
| 6814 | if (last_eb_bh) { | ||
| 6815 | status = ocfs2_journal_access_eb(handle, INODE_CACHE(inode), last_eb_bh, | ||
| 6816 | OCFS2_JOURNAL_ACCESS_WRITE); | ||
| 6817 | if (status < 0) { | ||
| 6818 | mlog_errno(status); | ||
| 6819 | goto bail; | ||
| 6820 | } | ||
| 6821 | |||
| 6822 | last_eb = (struct ocfs2_extent_block *) last_eb_bh->b_data; | ||
| 6823 | } | ||
| 6824 | |||
| 6825 | el = &(fe->id2.i_list); | ||
| 6826 | |||
| 6827 | /* | ||
| 6828 | * Lower levels depend on this never happening, but it's best | ||
| 6829 | * to check it up here before changing the tree. | ||
| 6830 | */ | ||
| 6831 | if (el->l_tree_depth && el->l_recs[0].e_int_clusters == 0) { | ||
| 6832 | ocfs2_error(inode->i_sb, | ||
| 6833 | "Inode %lu has an empty extent record, depth %u\n", | ||
| 6834 | inode->i_ino, le16_to_cpu(el->l_tree_depth)); | ||
| 6835 | status = -EROFS; | ||
| 6836 | goto bail; | ||
| 6837 | } | ||
| 6838 | |||
| 6839 | dquot_free_space_nodirty(inode, | ||
| 6840 | ocfs2_clusters_to_bytes(osb->sb, clusters_to_del)); | ||
| 6841 | spin_lock(&OCFS2_I(inode)->ip_lock); | ||
| 6842 | OCFS2_I(inode)->ip_clusters = le32_to_cpu(fe->i_clusters) - | ||
| 6843 | clusters_to_del; | ||
| 6844 | spin_unlock(&OCFS2_I(inode)->ip_lock); | ||
| 6845 | le32_add_cpu(&fe->i_clusters, -clusters_to_del); | ||
| 6846 | inode->i_blocks = ocfs2_inode_sector_count(inode); | ||
| 6847 | |||
| 6848 | status = ocfs2_trim_tree(inode, path, handle, tc, | ||
| 6849 | clusters_to_del, &delete_blk, &rec_flags); | ||
| 6850 | if (status) { | ||
| 6851 | mlog_errno(status); | ||
| 6852 | goto bail; | ||
| 6853 | } | ||
| 6854 | |||
| 6855 | if (le32_to_cpu(fe->i_clusters) == 0) { | ||
| 6856 | /* trunc to zero is a special case. */ | ||
| 6857 | el->l_tree_depth = 0; | ||
| 6858 | fe->i_last_eb_blk = 0; | ||
| 6859 | } else if (last_eb) | ||
| 6860 | fe->i_last_eb_blk = last_eb->h_blkno; | ||
| 6861 | |||
| 6862 | ocfs2_journal_dirty(handle, fe_bh); | ||
| 6863 | |||
| 6864 | if (last_eb) { | ||
| 6865 | /* If there will be a new last extent block, then by | ||
| 6866 | * definition, there cannot be any leaves to the right of | ||
| 6867 | * him. */ | ||
| 6868 | last_eb->h_next_leaf_blk = 0; | ||
| 6869 | ocfs2_journal_dirty(handle, last_eb_bh); | ||
| 6870 | } | ||
| 6871 | |||
| 6872 | if (delete_blk) { | ||
| 6873 | if (rec_flags & OCFS2_EXT_REFCOUNTED) | ||
| 6874 | status = ocfs2_decrease_refcount(inode, handle, | ||
| 6875 | ocfs2_blocks_to_clusters(osb->sb, | ||
| 6876 | delete_blk), | ||
| 6877 | clusters_to_del, meta_ac, | ||
| 6878 | &tc->tc_dealloc, 1); | ||
| 6879 | else | ||
| 6880 | status = ocfs2_truncate_log_append(osb, handle, | ||
| 6881 | delete_blk, | ||
| 6882 | clusters_to_del); | ||
| 6883 | if (status < 0) { | ||
| 6884 | mlog_errno(status); | ||
| 6885 | goto bail; | ||
| 6886 | } | ||
| 6887 | } | ||
| 6888 | status = 0; | ||
| 6889 | bail: | ||
| 6890 | brelse(last_eb_bh); | ||
| 6891 | mlog_exit(status); | ||
| 6892 | return status; | ||
| 6893 | } | ||
| 6894 | |||
| 6895 | static int ocfs2_zero_func(handle_t *handle, struct buffer_head *bh) | 6577 | static int ocfs2_zero_func(handle_t *handle, struct buffer_head *bh) |
| 6896 | { | 6578 | { |
| 6897 | set_buffer_uptodate(bh); | 6579 | set_buffer_uptodate(bh); |
| @@ -7300,26 +6982,29 @@ out: | |||
| 7300 | */ | 6982 | */ |
| 7301 | int ocfs2_commit_truncate(struct ocfs2_super *osb, | 6983 | int ocfs2_commit_truncate(struct ocfs2_super *osb, |
| 7302 | struct inode *inode, | 6984 | struct inode *inode, |
| 7303 | struct buffer_head *fe_bh, | 6985 | struct buffer_head *di_bh) |
| 7304 | struct ocfs2_truncate_context *tc) | ||
| 7305 | { | 6986 | { |
| 7306 | int status, i, credits, tl_sem = 0; | 6987 | int status = 0, i, flags = 0; |
| 7307 | u32 clusters_to_del, new_highest_cpos, range; | 6988 | u32 new_highest_cpos, range, trunc_cpos, trunc_len, phys_cpos, coff; |
| 7308 | u64 blkno = 0; | 6989 | u64 blkno = 0; |
| 7309 | struct ocfs2_extent_list *el; | 6990 | struct ocfs2_extent_list *el; |
| 7310 | handle_t *handle = NULL; | 6991 | struct ocfs2_extent_rec *rec; |
| 7311 | struct inode *tl_inode = osb->osb_tl_inode; | ||
| 7312 | struct ocfs2_path *path = NULL; | 6992 | struct ocfs2_path *path = NULL; |
| 7313 | struct ocfs2_dinode *di = (struct ocfs2_dinode *)fe_bh->b_data; | 6993 | struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data; |
| 7314 | struct ocfs2_alloc_context *meta_ac = NULL; | 6994 | struct ocfs2_extent_list *root_el = &(di->id2.i_list); |
| 7315 | struct ocfs2_refcount_tree *ref_tree = NULL; | 6995 | u64 refcount_loc = le64_to_cpu(di->i_refcount_loc); |
| 6996 | struct ocfs2_extent_tree et; | ||
| 6997 | struct ocfs2_cached_dealloc_ctxt dealloc; | ||
| 7316 | 6998 | ||
| 7317 | mlog_entry_void(); | 6999 | mlog_entry_void(); |
| 7318 | 7000 | ||
| 7001 | ocfs2_init_dinode_extent_tree(&et, INODE_CACHE(inode), di_bh); | ||
| 7002 | ocfs2_init_dealloc_ctxt(&dealloc); | ||
| 7003 | |||
| 7319 | new_highest_cpos = ocfs2_clusters_for_bytes(osb->sb, | 7004 | new_highest_cpos = ocfs2_clusters_for_bytes(osb->sb, |
| 7320 | i_size_read(inode)); | 7005 | i_size_read(inode)); |
| 7321 | 7006 | ||
| 7322 | path = ocfs2_new_path(fe_bh, &di->id2.i_list, | 7007 | path = ocfs2_new_path(di_bh, &di->id2.i_list, |
| 7323 | ocfs2_journal_access_di); | 7008 | ocfs2_journal_access_di); |
| 7324 | if (!path) { | 7009 | if (!path) { |
| 7325 | status = -ENOMEM; | 7010 | status = -ENOMEM; |
| @@ -7338,8 +7023,6 @@ start: | |||
| 7338 | goto bail; | 7023 | goto bail; |
| 7339 | } | 7024 | } |
| 7340 | 7025 | ||
| 7341 | credits = 0; | ||
| 7342 | |||
| 7343 | /* | 7026 | /* |
| 7344 | * Truncate always works against the rightmost tree branch. | 7027 | * Truncate always works against the rightmost tree branch. |
| 7345 | */ | 7028 | */ |
| @@ -7374,101 +7057,62 @@ start: | |||
| 7374 | } | 7057 | } |
| 7375 | 7058 | ||
| 7376 | i = le16_to_cpu(el->l_next_free_rec) - 1; | 7059 | i = le16_to_cpu(el->l_next_free_rec) - 1; |
| 7377 | range = le32_to_cpu(el->l_recs[i].e_cpos) + | 7060 | rec = &el->l_recs[i]; |
| 7378 | ocfs2_rec_clusters(el, &el->l_recs[i]); | 7061 | flags = rec->e_flags; |
| 7379 | if (i == 0 && ocfs2_is_empty_extent(&el->l_recs[i])) { | 7062 | range = le32_to_cpu(rec->e_cpos) + ocfs2_rec_clusters(el, rec); |
| 7380 | clusters_to_del = 0; | 7063 | |
| 7381 | } else if (le32_to_cpu(el->l_recs[i].e_cpos) >= new_highest_cpos) { | 7064 | if (i == 0 && ocfs2_is_empty_extent(rec)) { |
| 7382 | clusters_to_del = ocfs2_rec_clusters(el, &el->l_recs[i]); | 7065 | /* |
| 7383 | blkno = le64_to_cpu(el->l_recs[i].e_blkno); | 7066 | * Lower levels depend on this never happening, but it's best |
| 7067 | * to check it up here before changing the tree. | ||
| 7068 | */ | ||
| 7069 | if (root_el->l_tree_depth && rec->e_int_clusters == 0) { | ||
| 7070 | ocfs2_error(inode->i_sb, "Inode %lu has an empty " | ||
| 7071 | "extent record, depth %u\n", inode->i_ino, | ||
| 7072 | le16_to_cpu(root_el->l_tree_depth)); | ||
| 7073 | status = -EROFS; | ||
| 7074 | goto bail; | ||
| 7075 | } | ||
| 7076 | trunc_cpos = le32_to_cpu(rec->e_cpos); | ||
| 7077 | trunc_len = 0; | ||
| 7078 | blkno = 0; | ||
| 7079 | } else if (le32_to_cpu(rec->e_cpos) >= new_highest_cpos) { | ||
| 7080 | /* | ||
| 7081 | * Truncate entire record. | ||
| 7082 | */ | ||
| 7083 | trunc_cpos = le32_to_cpu(rec->e_cpos); | ||
| 7084 | trunc_len = ocfs2_rec_clusters(el, rec); | ||
| 7085 | blkno = le64_to_cpu(rec->e_blkno); | ||
| 7384 | } else if (range > new_highest_cpos) { | 7086 | } else if (range > new_highest_cpos) { |
| 7385 | clusters_to_del = (ocfs2_rec_clusters(el, &el->l_recs[i]) + | 7087 | /* |
| 7386 | le32_to_cpu(el->l_recs[i].e_cpos)) - | 7088 | * Partial truncate. it also should be |
| 7387 | new_highest_cpos; | 7089 | * the last truncate we're doing. |
| 7388 | blkno = le64_to_cpu(el->l_recs[i].e_blkno) + | 7090 | */ |
| 7389 | ocfs2_clusters_to_blocks(inode->i_sb, | 7091 | trunc_cpos = new_highest_cpos; |
| 7390 | ocfs2_rec_clusters(el, &el->l_recs[i]) - | 7092 | trunc_len = range - new_highest_cpos; |
| 7391 | clusters_to_del); | 7093 | coff = new_highest_cpos - le32_to_cpu(rec->e_cpos); |
| 7094 | blkno = le64_to_cpu(rec->e_blkno) + | ||
| 7095 | ocfs2_clusters_to_blocks(inode->i_sb, coff); | ||
| 7392 | } else { | 7096 | } else { |
| 7097 | /* | ||
| 7098 | * Truncate completed, leave happily. | ||
| 7099 | */ | ||
| 7393 | status = 0; | 7100 | status = 0; |
| 7394 | goto bail; | 7101 | goto bail; |
| 7395 | } | 7102 | } |
| 7396 | 7103 | ||
| 7397 | mlog(0, "clusters_to_del = %u in this pass, tail blk=%llu\n", | 7104 | phys_cpos = ocfs2_blocks_to_clusters(inode->i_sb, blkno); |
| 7398 | clusters_to_del, (unsigned long long)path_leaf_bh(path)->b_blocknr); | ||
| 7399 | |||
| 7400 | if (el->l_recs[i].e_flags & OCFS2_EXT_REFCOUNTED && clusters_to_del) { | ||
| 7401 | BUG_ON(!(OCFS2_I(inode)->ip_dyn_features & | ||
| 7402 | OCFS2_HAS_REFCOUNT_FL)); | ||
| 7403 | |||
| 7404 | status = ocfs2_lock_refcount_tree(osb, | ||
| 7405 | le64_to_cpu(di->i_refcount_loc), | ||
| 7406 | 1, &ref_tree, NULL); | ||
| 7407 | if (status) { | ||
| 7408 | mlog_errno(status); | ||
| 7409 | goto bail; | ||
| 7410 | } | ||
| 7411 | |||
| 7412 | status = ocfs2_prepare_refcount_change_for_del(inode, fe_bh, | ||
| 7413 | blkno, | ||
| 7414 | clusters_to_del, | ||
| 7415 | &credits, | ||
| 7416 | &meta_ac); | ||
| 7417 | if (status < 0) { | ||
| 7418 | mlog_errno(status); | ||
| 7419 | goto bail; | ||
| 7420 | } | ||
| 7421 | } | ||
| 7422 | |||
| 7423 | mutex_lock(&tl_inode->i_mutex); | ||
| 7424 | tl_sem = 1; | ||
| 7425 | /* ocfs2_truncate_log_needs_flush guarantees us at least one | ||
| 7426 | * record is free for use. If there isn't any, we flush to get | ||
| 7427 | * an empty truncate log. */ | ||
| 7428 | if (ocfs2_truncate_log_needs_flush(osb)) { | ||
| 7429 | status = __ocfs2_flush_truncate_log(osb); | ||
| 7430 | if (status < 0) { | ||
| 7431 | mlog_errno(status); | ||
| 7432 | goto bail; | ||
| 7433 | } | ||
| 7434 | } | ||
| 7435 | |||
| 7436 | credits += ocfs2_calc_tree_trunc_credits(osb->sb, clusters_to_del, | ||
| 7437 | (struct ocfs2_dinode *)fe_bh->b_data, | ||
| 7438 | el); | ||
| 7439 | handle = ocfs2_start_trans(osb, credits); | ||
| 7440 | if (IS_ERR(handle)) { | ||
| 7441 | status = PTR_ERR(handle); | ||
| 7442 | handle = NULL; | ||
| 7443 | mlog_errno(status); | ||
| 7444 | goto bail; | ||
| 7445 | } | ||
| 7446 | 7105 | ||
| 7447 | status = ocfs2_do_truncate(osb, clusters_to_del, inode, fe_bh, handle, | 7106 | status = ocfs2_remove_btree_range(inode, &et, trunc_cpos, |
| 7448 | tc, path, meta_ac); | 7107 | phys_cpos, trunc_len, flags, &dealloc, |
| 7108 | refcount_loc); | ||
| 7449 | if (status < 0) { | 7109 | if (status < 0) { |
| 7450 | mlog_errno(status); | 7110 | mlog_errno(status); |
| 7451 | goto bail; | 7111 | goto bail; |
| 7452 | } | 7112 | } |
| 7453 | 7113 | ||
| 7454 | mutex_unlock(&tl_inode->i_mutex); | ||
| 7455 | tl_sem = 0; | ||
| 7456 | |||
| 7457 | ocfs2_commit_trans(osb, handle); | ||
| 7458 | handle = NULL; | ||
| 7459 | |||
| 7460 | ocfs2_reinit_path(path, 1); | 7114 | ocfs2_reinit_path(path, 1); |
| 7461 | 7115 | ||
| 7462 | if (meta_ac) { | ||
| 7463 | ocfs2_free_alloc_context(meta_ac); | ||
| 7464 | meta_ac = NULL; | ||
| 7465 | } | ||
| 7466 | |||
| 7467 | if (ref_tree) { | ||
| 7468 | ocfs2_unlock_refcount_tree(osb, ref_tree, 1); | ||
| 7469 | ref_tree = NULL; | ||
| 7470 | } | ||
| 7471 | |||
| 7472 | /* | 7116 | /* |
| 7473 | * The check above will catch the case where we've truncated | 7117 | * The check above will catch the case where we've truncated |
| 7474 | * away all allocation. | 7118 | * away all allocation. |
| @@ -7479,25 +7123,10 @@ bail: | |||
| 7479 | 7123 | ||
| 7480 | ocfs2_schedule_truncate_log_flush(osb, 1); | 7124 | ocfs2_schedule_truncate_log_flush(osb, 1); |
| 7481 | 7125 | ||
| 7482 | if (tl_sem) | 7126 | ocfs2_run_deallocs(osb, &dealloc); |
| 7483 | mutex_unlock(&tl_inode->i_mutex); | ||
| 7484 | |||
| 7485 | if (handle) | ||
| 7486 | ocfs2_commit_trans(osb, handle); | ||
| 7487 | |||
| 7488 | if (meta_ac) | ||
| 7489 | ocfs2_free_alloc_context(meta_ac); | ||
| 7490 | |||
| 7491 | if (ref_tree) | ||
| 7492 | ocfs2_unlock_refcount_tree(osb, ref_tree, 1); | ||
| 7493 | |||
| 7494 | ocfs2_run_deallocs(osb, &tc->tc_dealloc); | ||
| 7495 | 7127 | ||
| 7496 | ocfs2_free_path(path); | 7128 | ocfs2_free_path(path); |
| 7497 | 7129 | ||
| 7498 | /* This will drop the ext_alloc cluster lock for us */ | ||
| 7499 | ocfs2_free_truncate_context(tc); | ||
| 7500 | |||
| 7501 | mlog_exit(status); | 7130 | mlog_exit(status); |
| 7502 | return status; | 7131 | return status; |
| 7503 | } | 7132 | } |
diff --git a/fs/ocfs2/alloc.h b/fs/ocfs2/alloc.h index 1db4359ccb90..4fb9882ed2d6 100644 --- a/fs/ocfs2/alloc.h +++ b/fs/ocfs2/alloc.h | |||
| @@ -140,8 +140,9 @@ int ocfs2_remove_extent(handle_t *handle, struct ocfs2_extent_tree *et, | |||
| 140 | struct ocfs2_cached_dealloc_ctxt *dealloc); | 140 | struct ocfs2_cached_dealloc_ctxt *dealloc); |
| 141 | int ocfs2_remove_btree_range(struct inode *inode, | 141 | int ocfs2_remove_btree_range(struct inode *inode, |
| 142 | struct ocfs2_extent_tree *et, | 142 | struct ocfs2_extent_tree *et, |
| 143 | u32 cpos, u32 phys_cpos, u32 len, | 143 | u32 cpos, u32 phys_cpos, u32 len, int flags, |
| 144 | struct ocfs2_cached_dealloc_ctxt *dealloc); | 144 | struct ocfs2_cached_dealloc_ctxt *dealloc, |
| 145 | u64 refcount_loc); | ||
| 145 | 146 | ||
| 146 | int ocfs2_num_free_extents(struct ocfs2_super *osb, | 147 | int ocfs2_num_free_extents(struct ocfs2_super *osb, |
| 147 | struct ocfs2_extent_tree *et); | 148 | struct ocfs2_extent_tree *et); |
| @@ -233,8 +234,7 @@ int ocfs2_prepare_truncate(struct ocfs2_super *osb, | |||
| 233 | struct ocfs2_truncate_context **tc); | 234 | struct ocfs2_truncate_context **tc); |
| 234 | int ocfs2_commit_truncate(struct ocfs2_super *osb, | 235 | int ocfs2_commit_truncate(struct ocfs2_super *osb, |
| 235 | struct inode *inode, | 236 | struct inode *inode, |
| 236 | struct buffer_head *fe_bh, | 237 | struct buffer_head *di_bh); |
| 237 | struct ocfs2_truncate_context *tc); | ||
| 238 | int ocfs2_truncate_inline(struct inode *inode, struct buffer_head *di_bh, | 238 | int ocfs2_truncate_inline(struct inode *inode, struct buffer_head *di_bh, |
| 239 | unsigned int start, unsigned int end, int trunc); | 239 | unsigned int start, unsigned int end, int trunc); |
| 240 | 240 | ||
diff --git a/fs/ocfs2/dir.c b/fs/ocfs2/dir.c index 6c9a28a2d3ae..4a75c2e2f855 100644 --- a/fs/ocfs2/dir.c +++ b/fs/ocfs2/dir.c | |||
| @@ -4526,8 +4526,8 @@ int ocfs2_dx_dir_truncate(struct inode *dir, struct buffer_head *di_bh) | |||
| 4526 | 4526 | ||
| 4527 | p_cpos = ocfs2_blocks_to_clusters(dir->i_sb, blkno); | 4527 | p_cpos = ocfs2_blocks_to_clusters(dir->i_sb, blkno); |
| 4528 | 4528 | ||
| 4529 | ret = ocfs2_remove_btree_range(dir, &et, cpos, p_cpos, clen, | 4529 | ret = ocfs2_remove_btree_range(dir, &et, cpos, p_cpos, clen, 0, |
| 4530 | &dealloc); | 4530 | &dealloc, 0); |
| 4531 | if (ret) { | 4531 | if (ret) { |
| 4532 | mlog_errno(ret); | 4532 | mlog_errno(ret); |
| 4533 | goto out; | 4533 | goto out; |
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 19d16f2ef81e..4c7a4d8ed32c 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c | |||
| @@ -444,7 +444,6 @@ static int ocfs2_truncate_file(struct inode *inode, | |||
| 444 | int status = 0; | 444 | int status = 0; |
| 445 | struct ocfs2_dinode *fe = NULL; | 445 | struct ocfs2_dinode *fe = NULL; |
| 446 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | 446 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); |
| 447 | struct ocfs2_truncate_context *tc = NULL; | ||
| 448 | 447 | ||
| 449 | mlog_entry("(inode = %llu, new_i_size = %llu\n", | 448 | mlog_entry("(inode = %llu, new_i_size = %llu\n", |
| 450 | (unsigned long long)OCFS2_I(inode)->ip_blkno, | 449 | (unsigned long long)OCFS2_I(inode)->ip_blkno, |
| @@ -515,13 +514,7 @@ static int ocfs2_truncate_file(struct inode *inode, | |||
| 515 | goto bail_unlock_sem; | 514 | goto bail_unlock_sem; |
| 516 | } | 515 | } |
| 517 | 516 | ||
| 518 | status = ocfs2_prepare_truncate(osb, inode, di_bh, &tc); | 517 | status = ocfs2_commit_truncate(osb, inode, di_bh); |
| 519 | if (status < 0) { | ||
| 520 | mlog_errno(status); | ||
| 521 | goto bail_unlock_sem; | ||
| 522 | } | ||
| 523 | |||
| 524 | status = ocfs2_commit_truncate(osb, inode, di_bh, tc); | ||
| 525 | if (status < 0) { | 518 | if (status < 0) { |
| 526 | mlog_errno(status); | 519 | mlog_errno(status); |
| 527 | goto bail_unlock_sem; | 520 | goto bail_unlock_sem; |
| @@ -1494,7 +1487,7 @@ static int ocfs2_remove_inode_range(struct inode *inode, | |||
| 1494 | if (phys_cpos != 0) { | 1487 | if (phys_cpos != 0) { |
| 1495 | ret = ocfs2_remove_btree_range(inode, &et, cpos, | 1488 | ret = ocfs2_remove_btree_range(inode, &et, cpos, |
| 1496 | phys_cpos, alloc_size, | 1489 | phys_cpos, alloc_size, |
| 1497 | &dealloc); | 1490 | 0, &dealloc, 0); |
| 1498 | if (ret) { | 1491 | if (ret) { |
| 1499 | mlog_errno(ret); | 1492 | mlog_errno(ret); |
| 1500 | goto out; | 1493 | goto out; |
diff --git a/fs/ocfs2/inode.c b/fs/ocfs2/inode.c index b7650ccd76d0..9a17251f3d9e 100644 --- a/fs/ocfs2/inode.c +++ b/fs/ocfs2/inode.c | |||
| @@ -544,7 +544,6 @@ static int ocfs2_truncate_for_delete(struct ocfs2_super *osb, | |||
| 544 | struct buffer_head *fe_bh) | 544 | struct buffer_head *fe_bh) |
| 545 | { | 545 | { |
| 546 | int status = 0; | 546 | int status = 0; |
| 547 | struct ocfs2_truncate_context *tc = NULL; | ||
| 548 | struct ocfs2_dinode *fe; | 547 | struct ocfs2_dinode *fe; |
| 549 | handle_t *handle = NULL; | 548 | handle_t *handle = NULL; |
| 550 | 549 | ||
| @@ -586,13 +585,7 @@ static int ocfs2_truncate_for_delete(struct ocfs2_super *osb, | |||
| 586 | ocfs2_commit_trans(osb, handle); | 585 | ocfs2_commit_trans(osb, handle); |
| 587 | handle = NULL; | 586 | handle = NULL; |
| 588 | 587 | ||
| 589 | status = ocfs2_prepare_truncate(osb, inode, fe_bh, &tc); | 588 | status = ocfs2_commit_truncate(osb, inode, fe_bh); |
| 590 | if (status < 0) { | ||
| 591 | mlog_errno(status); | ||
| 592 | goto out; | ||
| 593 | } | ||
| 594 | |||
| 595 | status = ocfs2_commit_truncate(osb, inode, fe_bh, tc); | ||
| 596 | if (status < 0) { | 589 | if (status < 0) { |
| 597 | mlog_errno(status); | 590 | mlog_errno(status); |
| 598 | goto out; | 591 | goto out; |
diff --git a/fs/ocfs2/refcounttree.c b/fs/ocfs2/refcounttree.c index 33dd2a18cb74..6fab28921f3d 100644 --- a/fs/ocfs2/refcounttree.c +++ b/fs/ocfs2/refcounttree.c | |||
| @@ -2509,20 +2509,19 @@ out: | |||
| 2509 | * | 2509 | * |
| 2510 | * Normally the refcount blocks store these refcount should be | 2510 | * Normally the refcount blocks store these refcount should be |
| 2511 | * contiguous also, so that we can get the number easily. | 2511 | * contiguous also, so that we can get the number easily. |
| 2512 | * As for meta_ac, we will at most add split 2 refcount record and | 2512 | * We will at most add split 2 refcount records and 2 more |
| 2513 | * 2 more refcount block, so just check it in a rough way. | 2513 | * refcount blocks, so just check it in a rough way. |
| 2514 | * | 2514 | * |
| 2515 | * Caller must hold refcount tree lock. | 2515 | * Caller must hold refcount tree lock. |
| 2516 | */ | 2516 | */ |
| 2517 | int ocfs2_prepare_refcount_change_for_del(struct inode *inode, | 2517 | int ocfs2_prepare_refcount_change_for_del(struct inode *inode, |
| 2518 | struct buffer_head *di_bh, | 2518 | u64 refcount_loc, |
| 2519 | u64 phys_blkno, | 2519 | u64 phys_blkno, |
| 2520 | u32 clusters, | 2520 | u32 clusters, |
| 2521 | int *credits, | 2521 | int *credits, |
| 2522 | struct ocfs2_alloc_context **meta_ac) | 2522 | int *ref_blocks) |
| 2523 | { | 2523 | { |
| 2524 | int ret, ref_blocks = 0; | 2524 | int ret; |
| 2525 | struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data; | ||
| 2526 | struct ocfs2_inode_info *oi = OCFS2_I(inode); | 2525 | struct ocfs2_inode_info *oi = OCFS2_I(inode); |
| 2527 | struct buffer_head *ref_root_bh = NULL; | 2526 | struct buffer_head *ref_root_bh = NULL; |
| 2528 | struct ocfs2_refcount_tree *tree; | 2527 | struct ocfs2_refcount_tree *tree; |
| @@ -2539,14 +2538,13 @@ int ocfs2_prepare_refcount_change_for_del(struct inode *inode, | |||
| 2539 | BUG_ON(!(oi->ip_dyn_features & OCFS2_HAS_REFCOUNT_FL)); | 2538 | BUG_ON(!(oi->ip_dyn_features & OCFS2_HAS_REFCOUNT_FL)); |
| 2540 | 2539 | ||
| 2541 | ret = ocfs2_get_refcount_tree(OCFS2_SB(inode->i_sb), | 2540 | ret = ocfs2_get_refcount_tree(OCFS2_SB(inode->i_sb), |
| 2542 | le64_to_cpu(di->i_refcount_loc), &tree); | 2541 | refcount_loc, &tree); |
| 2543 | if (ret) { | 2542 | if (ret) { |
| 2544 | mlog_errno(ret); | 2543 | mlog_errno(ret); |
| 2545 | goto out; | 2544 | goto out; |
| 2546 | } | 2545 | } |
| 2547 | 2546 | ||
| 2548 | ret = ocfs2_read_refcount_block(&tree->rf_ci, | 2547 | ret = ocfs2_read_refcount_block(&tree->rf_ci, refcount_loc, |
| 2549 | le64_to_cpu(di->i_refcount_loc), | ||
| 2550 | &ref_root_bh); | 2548 | &ref_root_bh); |
| 2551 | if (ret) { | 2549 | if (ret) { |
| 2552 | mlog_errno(ret); | 2550 | mlog_errno(ret); |
| @@ -2557,21 +2555,14 @@ int ocfs2_prepare_refcount_change_for_del(struct inode *inode, | |||
| 2557 | &tree->rf_ci, | 2555 | &tree->rf_ci, |
| 2558 | ref_root_bh, | 2556 | ref_root_bh, |
| 2559 | start_cpos, clusters, | 2557 | start_cpos, clusters, |
| 2560 | &ref_blocks, credits); | 2558 | ref_blocks, credits); |
| 2561 | if (ret) { | 2559 | if (ret) { |
| 2562 | mlog_errno(ret); | 2560 | mlog_errno(ret); |
| 2563 | goto out; | 2561 | goto out; |
| 2564 | } | 2562 | } |
| 2565 | 2563 | ||
| 2566 | mlog(0, "reserve new metadata %d, credits = %d\n", | 2564 | mlog(0, "reserve new metadata %d blocks, credits = %d\n", |
| 2567 | ref_blocks, *credits); | 2565 | *ref_blocks, *credits); |
| 2568 | |||
| 2569 | if (ref_blocks) { | ||
| 2570 | ret = ocfs2_reserve_new_metadata_blocks(OCFS2_SB(inode->i_sb), | ||
| 2571 | ref_blocks, meta_ac); | ||
| 2572 | if (ret) | ||
| 2573 | mlog_errno(ret); | ||
| 2574 | } | ||
| 2575 | 2566 | ||
| 2576 | out: | 2567 | out: |
| 2577 | brelse(ref_root_bh); | 2568 | brelse(ref_root_bh); |
diff --git a/fs/ocfs2/refcounttree.h b/fs/ocfs2/refcounttree.h index c1d19b1d3ecc..9983ba1570e2 100644 --- a/fs/ocfs2/refcounttree.h +++ b/fs/ocfs2/refcounttree.h | |||
| @@ -47,11 +47,11 @@ int ocfs2_decrease_refcount(struct inode *inode, | |||
| 47 | struct ocfs2_cached_dealloc_ctxt *dealloc, | 47 | struct ocfs2_cached_dealloc_ctxt *dealloc, |
| 48 | int delete); | 48 | int delete); |
| 49 | int ocfs2_prepare_refcount_change_for_del(struct inode *inode, | 49 | int ocfs2_prepare_refcount_change_for_del(struct inode *inode, |
| 50 | struct buffer_head *di_bh, | 50 | u64 refcount_loc, |
| 51 | u64 phys_blkno, | 51 | u64 phys_blkno, |
| 52 | u32 clusters, | 52 | u32 clusters, |
| 53 | int *credits, | 53 | int *credits, |
| 54 | struct ocfs2_alloc_context **meta_ac); | 54 | int *ref_blocks); |
| 55 | int ocfs2_refcount_cow(struct inode *inode, struct buffer_head *di_bh, | 55 | int ocfs2_refcount_cow(struct inode *inode, struct buffer_head *di_bh, |
| 56 | u32 cpos, u32 write_len, u32 max_cpos); | 56 | u32 cpos, u32 write_len, u32 max_cpos); |
| 57 | 57 | ||
