* 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jlbec/ocfs2: ocfs2: Silence gcc warning in ocfs2_write_zero_page(). jbd2/ocfs2: Fix block checksumming when a buffer is used in several transactions ocfs2/dlm: Remove BUG_ON from migration in the rare case of a down node ocfs2: Don't duplicate pages past i_size during CoW. ocfs2: tighten up strlen() checking ocfs2: Make xattr reflink work with new local alloc reservation. ocfs2: make xattr extension work with new local alloc reservation. ocfs2: Remove the redundant cpu_to_le64. ocfs2/dlm: don't access beyond bitmap size ocfs2: No need to zero pages past i_size. ocfs2: Zero the tail cluster when extending past i_size. ocfs2: When zero extending, do it by page. ocfs2: Limit default local alloc size within bitmap range. ocfs2: Move orphan scan work to ocfs2_wq. fs/ocfs2/dlm: Add missing spin_unlock
Unified · Split
| @@ -297,7 +297,6 @@ int jbd2_journal_write_metadata_buffer(transaction_t *transaction, · 296 unmodified lines | ||
| 297 | 297 | struct page *new_page; |
| 298 | 298 | unsigned int new_offset; |
| 299 | 299 | struct buffer_head *bh_in = jh2bh(jh_in); |
| 300 | − struct jbd2_buffer_trigger_type *triggers; | |
| 301 | 300 | journal_t *journal = transaction->t_journal; |
| 302 | 301 | |
| 303 | 302 | /* |
| @@ -328,21 +327,21 @@ repeat: · 24 unmodified lines | ||
| 328 | 327 | done_copy_out = 1; |
| 329 | 328 | new_page = virt_to_page(jh_in->b_frozen_data); |
| 330 | 329 | new_offset = offset_in_page(jh_in->b_frozen_data); |
| 331 | − triggers = jh_in->b_frozen_triggers; | |
| 332 | 330 | } else { |
| 333 | 331 | new_page = jh2bh(jh_in)->b_page; |
| 334 | 332 | new_offset = offset_in_page(jh2bh(jh_in)->b_data); |
| 335 | − triggers = jh_in->b_triggers; | |
| 336 | 333 | } |
| 337 | 334 | |
| 338 | 335 | mapped_data = kmap_atomic(new_page, KM_USER0); |
| 339 | 336 | /* |
| 340 | − * Fire any commit trigger. Do this before checking for escaping, | |
| 341 | − * as the trigger may modify the magic offset. If a copy-out | |
| 342 | − * happens afterwards, it will have the correct data in the buffer. | |
| 337 | + * Fire data frozen trigger if data already wasn't frozen. Do this | |
| 338 | + * before checking for escaping, as the trigger may modify the magic | |
| 339 | + * offset. If a copy-out happens afterwards, it will have the correct | |
| 340 | + * data in the buffer. | |
| 343 | 341 | */ |
| 344 | − jbd2_buffer_commit_trigger(jh_in, mapped_data + new_offset, | |
| 345 | − triggers); | |
| 342 | + if (!done_copy_out) | |
| 343 | + jbd2_buffer_frozen_trigger(jh_in, mapped_data + new_offset, | |
| 344 | + jh_in->b_triggers); | |
| 346 | 345 | |
| 347 | 346 | /* |
| 348 | 347 | * Check for escaping |
| @@ -725,6 +725,9 @@ done: · 724 unmodified lines | ||
| 725 | 725 | page = jh2bh(jh)->b_page; |
| 726 | 726 | offset = ((unsigned long) jh2bh(jh)->b_data) & ~PAGE_MASK; |
| 727 | 727 | source = kmap_atomic(page, KM_USER0); |
| 728 | + /* Fire data frozen trigger just before we copy the data */ | |
| 729 | + jbd2_buffer_frozen_trigger(jh, source + offset, | |
| 730 | + jh->b_triggers); | |
| 728 | 731 | memcpy(jh->b_frozen_data, source+offset, jh2bh(jh)->b_size); |
| 729 | 732 | kunmap_atomic(source, KM_USER0); |
| 730 | 733 | |
| @@ -963,15 +966,15 @@ void jbd2_journal_set_triggers(struct buffer_head *bh, · 232 unmodified lines | ||
| 963 | 966 | jh->b_triggers = type; |
| 964 | 967 | } |
| 965 | 968 | |
| 966 | −void jbd2_buffer_commit_trigger(struct journal_head *jh, void *mapped_data, | |
| 969 | +void jbd2_buffer_frozen_trigger(struct journal_head *jh, void *mapped_data, | |
| 967 | 970 | struct jbd2_buffer_trigger_type *triggers) |
| 968 | 971 | { |
| 969 | 972 | struct buffer_head *bh = jh2bh(jh); |
| 970 | 973 | |
| 971 | − if (!triggers || !triggers->t_commit) | |
| 974 | + if (!triggers || !triggers->t_frozen) | |
| 972 | 975 | return; |
| 973 | 976 | |
| 974 | − triggers->t_commit(triggers, bh, mapped_data, bh->b_size); | |
| 977 | + triggers->t_frozen(triggers, bh, mapped_data, bh->b_size); | |
| 975 | 978 | } |
| 976 | 979 | |
| 977 | 980 | void jbd2_buffer_abort_trigger(struct journal_head *jh, |
| @@ -196,15 +196,14 @@ int ocfs2_get_block(struct inode *inode, sector_t iblock, · 195 unmodified lines | ||
| 196 | 196 | dump_stack(); |
| 197 | 197 | goto bail; |
| 198 | 198 | } |
| 199 | − | |
| 200 | − past_eof = ocfs2_blocks_for_bytes(inode->i_sb, i_size_read(inode)); | |
| 201 | − mlog(0, "Inode %lu, past_eof = %llu\n", inode->i_ino, | |
| 202 | − (unsigned long long)past_eof); | |
| 203 | − | |
| 204 | − if (create && (iblock >= past_eof)) | |
| 205 | − set_buffer_new(bh_result); | |
| 206 | 199 | } |
| 207 | 200 | |
| 201 | + past_eof = ocfs2_blocks_for_bytes(inode->i_sb, i_size_read(inode)); | |
| 202 | + mlog(0, "Inode %lu, past_eof = %llu\n", inode->i_ino, | |
| 203 | + (unsigned long long)past_eof); | |
| 204 | + if (create && (iblock >= past_eof)) | |
| 205 | + set_buffer_new(bh_result); | |
| 206 | + | |
| 208 | 207 | bail: |
| 209 | 208 | if (err < 0) |
| 210 | 209 | err = -EIO; |
| @@ -459,36 +458,6 @@ int walk_page_buffers( handle_t *handle, · 248 unmodified lines | ||
| 459 | 458 | return ret; |
| 460 | 459 | } |
| 461 | 460 | |
| 462 | −handle_t *ocfs2_start_walk_page_trans(struct inode *inode, | |
| 463 | − struct page *page, | |
| 464 | − unsigned from, | |
| 465 | − unsigned to) | |
| 466 | −{ | |
| 467 | − struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | |
| 468 | − handle_t *handle; | |
| 469 | − int ret = 0; | |
| 470 | − | |
| 471 | − handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS); | |
| 472 | − if (IS_ERR(handle)) { | |
| 473 | − ret = -ENOMEM; | |
| 474 | − mlog_errno(ret); | |
| 475 | − goto out; | |
| 476 | − } | |
| 477 | − | |
| 478 | − if (ocfs2_should_order_data(inode)) { | |
| 479 | − ret = ocfs2_jbd2_file_inode(handle, inode); | |
| 480 | − if (ret < 0) | |
| 481 | − mlog_errno(ret); | |
| 482 | − } | |
| 483 | −out: | |
| 484 | − if (ret) { | |
| 485 | − if (!IS_ERR(handle)) | |
| 486 | − ocfs2_commit_trans(osb, handle); | |
| 487 | − handle = ERR_PTR(ret); | |
| 488 | − } | |
| 489 | − return handle; | |
| 490 | −} | |
| 491 | − | |
| 492 | 461 | static sector_t ocfs2_bmap(struct address_space *mapping, sector_t block) |
| 493 | 462 | { |
| 494 | 463 | sector_t status; |
| @@ -1131,23 +1100,37 @@ out: · 636 unmodified lines | ||
| 1131 | 1100 | */ |
| 1132 | 1101 | static int ocfs2_grab_pages_for_write(struct address_space *mapping, |
| 1133 | 1102 | struct ocfs2_write_ctxt *wc, |
| 1134 | − u32 cpos, loff_t user_pos, int new, | |
| 1103 | + u32 cpos, loff_t user_pos, | |
| 1104 | + unsigned user_len, int new, | |
| 1135 | 1105 | struct page *mmap_page) |
| 1136 | 1106 | { |
| 1137 | 1107 | int ret = 0, i; |
| 1138 | − unsigned long start, target_index, index; | |
| 1108 | + unsigned long start, target_index, end_index, index; | |
| 1139 | 1109 | struct inode *inode = mapping->host; |
| 1110 | + loff_t last_byte; | |
| 1140 | 1111 | |
| 1141 | 1112 | target_index = user_pos >> PAGE_CACHE_SHIFT; |
| 1142 | 1113 | |
| 1143 | 1114 | /* |
| 1144 | 1115 | * Figure out how many pages we'll be manipulating here. For |
| 1145 | 1116 | * non allocating write, we just change the one |
| 1146 | − * page. Otherwise, we'll need a whole clusters worth. | |
| 1117 | + * page. Otherwise, we'll need a whole clusters worth. If we're | |
| 1118 | + * writing past i_size, we only need enough pages to cover the | |
| 1119 | + * last page of the write. | |
| 1147 | 1120 | */ |
| 1148 | 1121 | if (new) { |
| 1149 | 1122 | wc->w_num_pages = ocfs2_pages_per_cluster(inode->i_sb); |
| 1150 | 1123 | start = ocfs2_align_clusters_to_page_index(inode->i_sb, cpos); |
| 1124 | + /* | |
| 1125 | + * We need the index *past* the last page we could possibly | |
| 1126 | + * touch. This is the page past the end of the write or | |
| 1127 | + * i_size, whichever is greater. | |
| 1128 | + */ | |
| 1129 | + last_byte = max(user_pos + user_len, i_size_read(inode)); | |
| 1130 | + BUG_ON(last_byte < 1); | |
| 1131 | + end_index = ((last_byte - 1) >> PAGE_CACHE_SHIFT) + 1; | |
| 1132 | + if ((start + wc->w_num_pages) > end_index) | |
| 1133 | + wc->w_num_pages = end_index - start; | |
| 1151 | 1134 | } else { |
| 1152 | 1135 | wc->w_num_pages = 1; |
| 1153 | 1136 | start = target_index; |
| @@ -1620,21 +1603,20 @@ out: · 466 unmodified lines | ||
| 1620 | 1603 | * write path can treat it as an non-allocating write, which has no |
| 1621 | 1604 | * special case code for sparse/nonsparse files. |
| 1622 | 1605 | */ |
| 1623 | −static int ocfs2_expand_nonsparse_inode(struct inode *inode, loff_t pos, | |
| 1624 | − unsigned len, | |
| 1606 | +static int ocfs2_expand_nonsparse_inode(struct inode *inode, | |
| 1607 | + struct buffer_head *di_bh, | |
| 1608 | + loff_t pos, unsigned len, | |
| 1625 | 1609 | struct ocfs2_write_ctxt *wc) |
| 1626 | 1610 | { |
| 1627 | 1611 | int ret; |
| 1628 | − struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | |
| 1629 | 1612 | loff_t newsize = pos + len; |
| 1630 | 1613 | |
| 1631 | − if (ocfs2_sparse_alloc(osb)) | |
| 1632 | − return 0; | |
| 1614 | + BUG_ON(ocfs2_sparse_alloc(OCFS2_SB(inode->i_sb))); | |
| 1633 | 1615 | |
| 1634 | 1616 | if (newsize <= i_size_read(inode)) |
| 1635 | 1617 | return 0; |
| 1636 | 1618 | |
| 1637 | − ret = ocfs2_extend_no_holes(inode, newsize, pos); | |
| 1619 | + ret = ocfs2_extend_no_holes(inode, di_bh, newsize, pos); | |
| 1638 | 1620 | if (ret) |
| 1639 | 1621 | mlog_errno(ret); |
| 1640 | 1622 | |
| @@ -1644,6 +1626,18 @@ static int ocfs2_expand_nonsparse_inode(struct inode *inode, loff_t pos, · 3 unmodified lines | ||
| 1644 | 1626 | return ret; |
| 1645 | 1627 | } |
| 1646 | 1628 | |
| 1629 | +static int ocfs2_zero_tail(struct inode *inode, struct buffer_head *di_bh, | |
| 1630 | + loff_t pos) | |
| 1631 | +{ | |
| 1632 | + int ret = 0; | |
| 1633 | + | |
| 1634 | + BUG_ON(!ocfs2_sparse_alloc(OCFS2_SB(inode->i_sb))); | |
| 1635 | + if (pos > i_size_read(inode)) | |
| 1636 | + ret = ocfs2_zero_extend(inode, di_bh, pos); | |
| 1637 | + | |
| 1638 | + return ret; | |
| 1639 | +} | |
| 1640 | + | |
| 1647 | 1641 | int ocfs2_write_begin_nolock(struct address_space *mapping, |
| 1648 | 1642 | loff_t pos, unsigned len, unsigned flags, |
| 1649 | 1643 | struct page **pagep, void **fsdata, |
| @@ -1679,7 +1673,11 @@ int ocfs2_write_begin_nolock(struct address_space *mapping, · 29 unmodified lines | ||
| 1679 | 1673 | } |
| 1680 | 1674 | } |
| 1681 | 1675 | |
| 1682 | − ret = ocfs2_expand_nonsparse_inode(inode, pos, len, wc); | |
| 1676 | + if (ocfs2_sparse_alloc(osb)) | |
| 1677 | + ret = ocfs2_zero_tail(inode, di_bh, pos); | |
| 1678 | + else | |
| 1679 | + ret = ocfs2_expand_nonsparse_inode(inode, di_bh, pos, len, | |
| 1680 | + wc); | |
| 1683 | 1681 | if (ret) { |
| 1684 | 1682 | mlog_errno(ret); |
| 1685 | 1683 | goto out; |
| @@ -1789,7 +1787,7 @@ int ocfs2_write_begin_nolock(struct address_space *mapping, · 103 unmodified lines | ||
| 1789 | 1787 | * that we can zero and flush if we error after adding the |
| 1790 | 1788 | * extent. |
| 1791 | 1789 | */ |
| 1792 | − ret = ocfs2_grab_pages_for_write(mapping, wc, wc->w_cpos, pos, | |
| 1790 | + ret = ocfs2_grab_pages_for_write(mapping, wc, wc->w_cpos, pos, len, | |
| 1793 | 1791 | cluster_of_pages, mmap_page); |
| 1794 | 1792 | if (ret) { |
| 1795 | 1793 | mlog_errno(ret); |
| @@ -1671,7 +1671,7 @@ struct dlm_ctxt * dlm_register_domain(const char *domain, · 1670 unmodified lines | ||
| 1671 | 1671 | struct dlm_ctxt *dlm = NULL; |
| 1672 | 1672 | struct dlm_ctxt *new_ctxt = NULL; |
| 1673 | 1673 | |
| 1674 | − if (strlen(domain) > O2NM_MAX_NAME_LEN) { | |
| 1674 | + if (strlen(domain) >= O2NM_MAX_NAME_LEN) { | |
| 1675 | 1675 | ret = -ENAMETOOLONG; |
| 1676 | 1676 | mlog(ML_ERROR, "domain name length too long\n"); |
| 1677 | 1677 | goto leave; |
| @@ -1709,6 +1709,7 @@ retry: · 31 unmodified lines | ||
| 1709 | 1709 | } |
| 1710 | 1710 | |
| 1711 | 1711 | if (dlm_protocol_compare(&dlm->fs_locking_proto, fs_proto)) { |
| 1712 | + spin_unlock(&dlm_domain_lock); | |
| 1712 | 1713 | mlog(ML_ERROR, |
| 1713 | 1714 | "Requested locking protocol version is not " |
| 1714 | 1715 | "compatible with already registered domain " |
| @@ -2808,14 +2808,8 @@ again: · 2807 unmodified lines | ||
| 2808 | 2808 | mlog(0, "trying again...\n"); |
| 2809 | 2809 | goto again; |
| 2810 | 2810 | } |
| 2811 | − /* now that we are sure the MIGRATING state is there, drop | |
| 2812 | − * the unneded state which blocked threads trying to DIRTY */ | |
| 2813 | − spin_lock(&res->spinlock); | |
| 2814 | − BUG_ON(!(res->state & DLM_LOCK_RES_BLOCK_DIRTY)); | |
| 2815 | − BUG_ON(!(res->state & DLM_LOCK_RES_MIGRATING)); | |
| 2816 | − res->state &= ~DLM_LOCK_RES_BLOCK_DIRTY; | |
| 2817 | − spin_unlock(&res->spinlock); | |
| 2818 | 2811 | |
| 2812 | + ret = 0; | |
| 2819 | 2813 | /* did the target go down or die? */ |
| 2820 | 2814 | spin_lock(&dlm->spinlock); |
| 2821 | 2815 | if (!test_bit(target, dlm->domain_map)) { |
| @@ -2825,10 +2819,22 @@ again: · 3 unmodified lines | ||
| 2825 | 2819 | } |
| 2826 | 2820 | spin_unlock(&dlm->spinlock); |
| 2827 | 2821 | |
| 2822 | + /* | |
| 2823 | + * if target is down, we need to clear DLM_LOCK_RES_BLOCK_DIRTY for | |
| 2824 | + * another try; otherwise, we are sure the MIGRATING state is there, | |
| 2825 | + * drop the unneded state which blocked threads trying to DIRTY | |
| 2826 | + */ | |
| 2827 | + spin_lock(&res->spinlock); | |
| 2828 | + BUG_ON(!(res->state & DLM_LOCK_RES_BLOCK_DIRTY)); | |
| 2829 | + res->state &= ~DLM_LOCK_RES_BLOCK_DIRTY; | |
| 2830 | + if (!ret) | |
| 2831 | + BUG_ON(!(res->state & DLM_LOCK_RES_MIGRATING)); | |
| 2832 | + spin_unlock(&res->spinlock); | |
| 2833 | + | |
| 2828 | 2834 | /* |
| 2829 | 2835 | * at this point: |
| 2830 | 2836 | * |
| 2831 | − * o the DLM_LOCK_RES_MIGRATING flag is set | |
| 2837 | + * o the DLM_LOCK_RES_MIGRATING flag is set if target not down | |
| 2832 | 2838 | * o there are no pending asts on this lockres |
| 2833 | 2839 | * o all processes trying to reserve an ast on this |
| 2834 | 2840 | * lockres must wait for the MIGRATING flag to clear |
| @@ -463,7 +463,7 @@ static int dlm_do_recovery(struct dlm_ctxt *dlm) · 462 unmodified lines | ||
| 463 | 463 | if (dlm->reco.dead_node == O2NM_INVALID_NODE_NUM) { |
| 464 | 464 | int bit; |
| 465 | 465 | |
| 466 | − bit = find_next_bit (dlm->recovery_map, O2NM_MAX_NODES+1, 0); | |
| 466 | + bit = find_next_bit (dlm->recovery_map, O2NM_MAX_NODES, 0); | |
| 467 | 467 | if (bit >= O2NM_MAX_NODES || bit < 0) |
| 468 | 468 | dlm_set_reco_dead_node(dlm, O2NM_INVALID_NODE_NUM); |
| 469 | 469 | else |
| @@ -724,28 +724,55 @@ leave: · 723 unmodified lines | ||
| 724 | 724 | return status; |
| 725 | 725 | } |
| 726 | 726 | |
| 727 | +/* | |
| 728 | + * While a write will already be ordering the data, a truncate will not. | |
| 729 | + * Thus, we need to explicitly order the zeroed pages. | |
| 730 | + */ | |
| 731 | +static handle_t *ocfs2_zero_start_ordered_transaction(struct inode *inode) | |
| 732 | +{ | |
| 733 | + struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | |
| 734 | + handle_t *handle = NULL; | |
| 735 | + int ret = 0; | |
| 736 | + | |
| 737 | + if (!ocfs2_should_order_data(inode)) | |
| 738 | + goto out; | |
| 739 | + | |
| 740 | + handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS); | |
| 741 | + if (IS_ERR(handle)) { | |
| 742 | + ret = -ENOMEM; | |
| 743 | + mlog_errno(ret); | |
| 744 | + goto out; | |
| 745 | + } | |
| 746 | + | |
| 747 | + ret = ocfs2_jbd2_file_inode(handle, inode); | |
| 748 | + if (ret < 0) | |
| 749 | + mlog_errno(ret); | |
| 750 | + | |
| 751 | +out: | |
| 752 | + if (ret) { | |
| 753 | + if (!IS_ERR(handle)) | |
| 754 | + ocfs2_commit_trans(osb, handle); | |
| 755 | + handle = ERR_PTR(ret); | |
| 756 | + } | |
| 757 | + return handle; | |
| 758 | +} | |
| 759 | + | |
| 727 | 760 | /* Some parts of this taken from generic_cont_expand, which turned out |
| 728 | 761 | * to be too fragile to do exactly what we need without us having to |
| 729 | 762 | * worry about recursive locking in ->write_begin() and ->write_end(). */ |
| 730 | −static int ocfs2_write_zero_page(struct inode *inode, | |
| 731 | − u64 size) | |
| 763 | +static int ocfs2_write_zero_page(struct inode *inode, u64 abs_from, | |
| 764 | + u64 abs_to) | |
| 732 | 765 | { |
| 733 | 766 | struct address_space *mapping = inode->i_mapping; |
| 734 | 767 | struct page *page; |
| 735 | − unsigned long index; | |
| 736 | − unsigned int offset; | |
| 768 | + unsigned long index = abs_from >> PAGE_CACHE_SHIFT; | |
| 737 | 769 | handle_t *handle = NULL; |
| 738 | − int ret; | |
| 770 | + int ret = 0; | |
| 771 | + unsigned zero_from, zero_to, block_start, block_end; | |
| 739 | 772 | |
| 740 | − offset = (size & (PAGE_CACHE_SIZE-1)); /* Within page */ | |
| 741 | − /* ugh. in prepare/commit_write, if from==to==start of block, we | |
| 742 | − ** skip the prepare. make sure we never send an offset for the start | |
| 743 | − ** of a block | |
| 744 | − */ | |
| 745 | − if ((offset & (inode->i_sb->s_blocksize - 1)) == 0) { | |
| 746 | − offset++; | |
| 747 | − } | |
| 748 | − index = size >> PAGE_CACHE_SHIFT; | |
| 773 | + BUG_ON(abs_from >= abs_to); | |
| 774 | + BUG_ON(abs_to > (((u64)index + 1) << PAGE_CACHE_SHIFT)); | |
| 775 | + BUG_ON(abs_from & (inode->i_blkbits - 1)); | |
| 749 | 776 | |
| 750 | 777 | page = grab_cache_page(mapping, index); |
| 751 | 778 | if (!page) { |
| @@ -754,31 +781,56 @@ static int ocfs2_write_zero_page(struct inode *inode, · 2 unmodified lines | ||
| 754 | 781 | goto out; |
| 755 | 782 | } |
| 756 | 783 | |
| 757 | − ret = ocfs2_prepare_write_nolock(inode, page, offset, offset); | |
| 758 | − if (ret < 0) { | |
| 759 | − mlog_errno(ret); | |
| 760 | − goto out_unlock; | |
| 761 | − } | |
| 784 | + /* Get the offsets within the page that we want to zero */ | |
| 785 | + zero_from = abs_from & (PAGE_CACHE_SIZE - 1); | |
| 786 | + zero_to = abs_to & (PAGE_CACHE_SIZE - 1); | |
| 787 | + if (!zero_to) | |
| 788 | + zero_to = PAGE_CACHE_SIZE; | |
| 762 | 789 | |
| 763 | − if (ocfs2_should_order_data(inode)) { | |
| 764 | − handle = ocfs2_start_walk_page_trans(inode, page, offset, | |
| 765 | − offset); | |
| 766 | − if (IS_ERR(handle)) { | |
| 767 | − ret = PTR_ERR(handle); | |
| 768 | − handle = NULL; | |
| 790 | + mlog(0, | |
| 791 | + "abs_from = %llu, abs_to = %llu, index = %lu, zero_from = %u, zero_to = %u\n", | |
| 792 | + (unsigned long long)abs_from, (unsigned long long)abs_to, | |
| 793 | + index, zero_from, zero_to); | |
| 794 | + | |
| 795 | + /* We know that zero_from is block aligned */ | |
| 796 | + for (block_start = zero_from; block_start < zero_to; | |
| 797 | + block_start = block_end) { | |
| 798 | + block_end = block_start + (1 << inode->i_blkbits); | |
| 799 | + | |
| 800 | + /* | |
| 801 | + * block_start is block-aligned. Bump it by one to | |
| 802 | + * force ocfs2_{prepare,commit}_write() to zero the | |
| 803 | + * whole block. | |
| 804 | + */ | |
| 805 | + ret = ocfs2_prepare_write_nolock(inode, page, | |
| 806 | + block_start + 1, | |
| 807 | + block_start + 1); | |
| 808 | + if (ret < 0) { | |
| 809 | + mlog_errno(ret); | |
| 769 | 810 | goto out_unlock; |
| 770 | 811 | } |
| 771 | − } | |
| 772 | 812 | |
| 773 | − /* must not update i_size! */ | |
| 774 | − ret = block_commit_write(page, offset, offset); | |
| 775 | − if (ret < 0) | |
| 776 | − mlog_errno(ret); | |
| 777 | − else | |
| 778 | − ret = 0; | |
| 813 | + if (!handle) { | |
| 814 | + handle = ocfs2_zero_start_ordered_transaction(inode); | |
| 815 | + if (IS_ERR(handle)) { | |
| 816 | + ret = PTR_ERR(handle); | |
| 817 | + handle = NULL; | |
| 818 | + break; | |
| 819 | + } | |
| 820 | + } | |
| 821 | + | |
| 822 | + /* must not update i_size! */ | |
| 823 | + ret = block_commit_write(page, block_start + 1, | |
| 824 | + block_start + 1); | |
| 825 | + if (ret < 0) | |
| 826 | + mlog_errno(ret); | |
| 827 | + else | |
| 828 | + ret = 0; | |
| 829 | + } | |
| 779 | 830 | |
| 780 | 831 | if (handle) |
| 781 | 832 | ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle); |
| 833 | + | |
| 782 | 834 | out_unlock: |
| 783 | 835 | unlock_page(page); |
| 784 | 836 | page_cache_release(page); |
| @@ -786,22 +838,114 @@ out: · 1 unmodified line | ||
| 786 | 838 | return ret; |
| 787 | 839 | } |
| 788 | 840 | |
| 789 | −static int ocfs2_zero_extend(struct inode *inode, | |
| 790 | − u64 zero_to_size) | |
| 841 | +/* | |
| 842 | + * Find the next range to zero. We do this in terms of bytes because | |
| 843 | + * that's what ocfs2_zero_extend() wants, and it is dealing with the | |
| 844 | + * pagecache. We may return multiple extents. | |
| 845 | + * | |
| 846 | + * zero_start and zero_end are ocfs2_zero_extend()s current idea of what | |
| 847 | + * needs to be zeroed. range_start and range_end return the next zeroing | |
| 848 | + * range. A subsequent call should pass the previous range_end as its | |
| 849 | + * zero_start. If range_end is 0, there's nothing to do. | |
| 850 | + * | |
| 851 | + * Unwritten extents are skipped over. Refcounted extents are CoWd. | |
| 852 | + */ | |
| 853 | +static int ocfs2_zero_extend_get_range(struct inode *inode, | |
| 854 | + struct buffer_head *di_bh, | |
| 855 | + u64 zero_start, u64 zero_end, | |
| 856 | + u64 *range_start, u64 *range_end) | |
| 791 | 857 | { |
| 792 | − int ret = 0; | |
| 793 | − u64 start_off; | |
| 794 | − struct super_block *sb = inode->i_sb; | |
| 858 | + int rc = 0, needs_cow = 0; | |
| 859 | + u32 p_cpos, zero_clusters = 0; | |
| 860 | + u32 zero_cpos = | |
| 861 | + zero_start >> OCFS2_SB(inode->i_sb)->s_clustersize_bits; | |
| 862 | + u32 last_cpos = ocfs2_clusters_for_bytes(inode->i_sb, zero_end); | |
| 863 | + unsigned int num_clusters = 0; | |
| 864 | + unsigned int ext_flags = 0; | |
| 795 | 865 | |
| 796 | − start_off = ocfs2_align_bytes_to_blocks(sb, i_size_read(inode)); | |
| 797 | − while (start_off < zero_to_size) { | |
| 798 | − ret = ocfs2_write_zero_page(inode, start_off); | |
| 799 | − if (ret < 0) { | |
| 800 | − mlog_errno(ret); | |
| 866 | + while (zero_cpos < last_cpos) { | |
| 867 | + rc = ocfs2_get_clusters(inode, zero_cpos, &p_cpos, | |
| 868 | + &num_clusters, &ext_flags); | |
| 869 | + if (rc) { | |
| 870 | + mlog_errno(rc); | |
| 871 | + goto out; | |
| 872 | + } | |
| 873 | + | |
| 874 | + if (p_cpos && !(ext_flags & OCFS2_EXT_UNWRITTEN)) { | |
| 875 | + zero_clusters = num_clusters; | |
| 876 | + if (ext_flags & OCFS2_EXT_REFCOUNTED) | |
| 877 | + needs_cow = 1; | |
| 878 | + break; | |
| 879 | + } | |
| 880 | + | |
| 881 | + zero_cpos += num_clusters; | |
| 882 | + } | |
| 883 | + if (!zero_clusters) { | |
| 884 | + *range_end = 0; | |
| 885 | + goto out; | |
| 886 | + } | |
| 887 | + | |
| 888 | + while ((zero_cpos + zero_clusters) < last_cpos) { | |
| 889 | + rc = ocfs2_get_clusters(inode, zero_cpos + zero_clusters, | |
| 890 | + &p_cpos, &num_clusters, | |
| 891 | + &ext_flags); | |
| 892 | + if (rc) { | |
| 893 | + mlog_errno(rc); | |
| 801 | 894 | goto out; |
| 802 | 895 | } |
| 803 | 896 | |
| 804 | − start_off += sb->s_blocksize; | |
| 897 | + if (!p_cpos || (ext_flags & OCFS2_EXT_UNWRITTEN)) | |
| 898 | + break; | |
| 899 | + if (ext_flags & OCFS2_EXT_REFCOUNTED) | |
| 900 | + needs_cow = 1; | |
| 901 | + zero_clusters += num_clusters; | |
| 902 | + } | |
| 903 | + if ((zero_cpos + zero_clusters) > last_cpos) | |
| 904 | + zero_clusters = last_cpos - zero_cpos; | |
| 905 | + | |
| 906 | + if (needs_cow) { | |
| 907 | + rc = ocfs2_refcount_cow(inode, di_bh, zero_cpos, zero_clusters, | |
| 908 | + UINT_MAX); | |
| 909 | + if (rc) { | |
| 910 | + mlog_errno(rc); | |
| 911 | + goto out; | |
| 912 | + } | |
| 913 | + } | |
| 914 | + | |
| 915 | + *range_start = ocfs2_clusters_to_bytes(inode->i_sb, zero_cpos); | |
| 916 | + *range_end = ocfs2_clusters_to_bytes(inode->i_sb, | |
| 917 | + zero_cpos + zero_clusters); | |
| 918 | + | |
| 919 | +out: | |
| 920 | + return rc; | |
| 921 | +} | |
| 922 | + | |
| 923 | +/* | |
| 924 | + * Zero one range returned from ocfs2_zero_extend_get_range(). The caller | |
| 925 | + * has made sure that the entire range needs zeroing. | |
| 926 | + */ | |
| 927 | +static int ocfs2_zero_extend_range(struct inode *inode, u64 range_start, | |
| 928 | + u64 range_end) | |
| 929 | +{ | |
| 930 | + int rc = 0; | |
| 931 | + u64 next_pos; | |
| 932 | + u64 zero_pos = range_start; | |
| 933 | + | |
| 934 | + mlog(0, "range_start = %llu, range_end = %llu\n", | |
| 935 | + (unsigned long long)range_start, | |
| 936 | + (unsigned long long)range_end); | |
| 937 | + BUG_ON(range_start >= range_end); | |
| 938 | + | |
| 939 | + while (zero_pos < range_end) { | |
| 940 | + next_pos = (zero_pos & PAGE_CACHE_MASK) + PAGE_CACHE_SIZE; | |
| 941 | + if (next_pos > range_end) | |
| 942 | + next_pos = range_end; | |
| 943 | + rc = ocfs2_write_zero_page(inode, zero_pos, next_pos); | |
| 944 | + if (rc < 0) { | |
| 945 | + mlog_errno(rc); | |
| 946 | + break; | |
| 947 | + } | |
| 948 | + zero_pos = next_pos; | |
| 805 | 949 | |
| 806 | 950 | /* |
| 807 | 951 | * Very large extends have the potential to lock up |
| @@ -810,16 +954,63 @@ static int ocfs2_zero_extend(struct inode *inode, · 2 unmodified lines | ||
| 810 | 954 | cond_resched(); |
| 811 | 955 | } |
| 812 | 956 | |
| 813 | −out: | |
| 957 | + return rc; | |
| 958 | +} | |
| 959 | + | |
| 960 | +int ocfs2_zero_extend(struct inode *inode, struct buffer_head *di_bh, | |
| 961 | + loff_t zero_to_size) | |
| 962 | +{ | |
| 963 | + int ret = 0; | |
| 964 | + u64 zero_start, range_start = 0, range_end = 0; | |
| 965 | + struct super_block *sb = inode->i_sb; | |
| 966 | + | |
| 967 | + zero_start = ocfs2_align_bytes_to_blocks(sb, i_size_read(inode)); | |
| 968 | + mlog(0, "zero_start %llu for i_size %llu\n", | |
| 969 | + (unsigned long long)zero_start, | |
| 970 | + (unsigned long long)i_size_read(inode)); | |
| 971 | + while (zero_start < zero_to_size) { | |
| 972 | + ret = ocfs2_zero_extend_get_range(inode, di_bh, zero_start, | |
| 973 | + zero_to_size, | |
| 974 | + &range_start, | |
| 975 | + &range_end); | |
| 976 | + if (ret) { | |
| 977 | + mlog_errno(ret); | |
| 978 | + break; | |
| 979 | + } | |
| 980 | + if (!range_end) | |
| 981 | + break; | |
| 982 | + /* Trim the ends */ | |
| 983 | + if (range_start < zero_start) | |
| 984 | + range_start = zero_start; | |
| 985 | + if (range_end > zero_to_size) | |
| 986 | + range_end = zero_to_size; | |
| 987 | + | |
| 988 | + ret = ocfs2_zero_extend_range(inode, range_start, | |
| 989 | + range_end); | |
| 990 | + if (ret) { | |
| 991 | + mlog_errno(ret); | |
| 992 | + break; | |
| 993 | + } | |
| 994 | + zero_start = range_end; | |
| 995 | + } | |
| 996 | + | |
| 814 | 997 | return ret; |
| 815 | 998 | } |
| 816 | 999 | |
| 817 | −int ocfs2_extend_no_holes(struct inode *inode, u64 new_i_size, u64 zero_to) | |
| 1000 | +int ocfs2_extend_no_holes(struct inode *inode, struct buffer_head *di_bh, | |
| 1001 | + u64 new_i_size, u64 zero_to) | |
| 818 | 1002 | { |
| 819 | 1003 | int ret; |
| 820 | 1004 | u32 clusters_to_add; |
| 821 | 1005 | struct ocfs2_inode_info *oi = OCFS2_I(inode); |
| 822 | 1006 | |
| 1007 | + /* | |
| 1008 | + * Only quota files call this without a bh, and they can't be | |
| 1009 | + * refcounted. | |
| 1010 | + */ | |
| 1011 | + BUG_ON(!di_bh && (oi->ip_dyn_features & OCFS2_HAS_REFCOUNT_FL)); | |
| 1012 | + BUG_ON(!di_bh && !(oi->ip_flags & OCFS2_INODE_SYSTEM_FILE)); | |
| 1013 | + | |
| 823 | 1014 | clusters_to_add = ocfs2_clusters_for_bytes(inode->i_sb, new_i_size); |
| 824 | 1015 | if (clusters_to_add < oi->ip_clusters) |
| 825 | 1016 | clusters_to_add = 0; |
| @@ -840,7 +1031,7 @@ int ocfs2_extend_no_holes(struct inode *inode, u64 new_i_size, u64 zero_to) · 14 unmodified lines | ||
| 840 | 1031 | * still need to zero the area between the old i_size and the |
| 841 | 1032 | * new i_size. |
| 842 | 1033 | */ |
| 843 | − ret = ocfs2_zero_extend(inode, zero_to); | |
| 1034 | + ret = ocfs2_zero_extend(inode, di_bh, zero_to); | |
| 844 | 1035 | if (ret < 0) |
| 845 | 1036 | mlog_errno(ret); |
| 846 | 1037 | |
| @@ -862,27 +1053,15 @@ static int ocfs2_extend_file(struct inode *inode, · 15 unmodified lines | ||
| 862 | 1053 | goto out; |
| 863 | 1054 | |
| 864 | 1055 | if (i_size_read(inode) == new_i_size) |
| 865 | − goto out; | |
| 1056 | + goto out; | |
| 866 | 1057 | BUG_ON(new_i_size < i_size_read(inode)); |
| 867 | 1058 | |
| 868 | − /* | |
| 869 | − * Fall through for converting inline data, even if the fs | |
| 870 | − * supports sparse files. | |
| 871 | − * | |
| 872 | − * The check for inline data here is legal - nobody can add | |
| 873 | − * the feature since we have i_mutex. We must check it again | |
| 874 | − * after acquiring ip_alloc_sem though, as paths like mmap | |
| 875 | − * might have raced us to converting the inode to extents. | |
| 876 | − */ | |
| 877 | − if (!(oi->ip_dyn_features & OCFS2_INLINE_DATA_FL) | |
| 878 | − && ocfs2_sparse_alloc(OCFS2_SB(inode->i_sb))) | |
| 879 | − goto out_update_size; | |
| 880 | − | |
| 881 | 1059 | /* |
| 882 | 1060 | * The alloc sem blocks people in read/write from reading our |
| 883 | 1061 | * allocation until we're done changing it. We depend on |
| 884 | 1062 | * i_mutex to block other extend/truncate calls while we're |
| 885 | − * here. | |
| 1063 | + * here. We even have to hold it for sparse files because there | |
| 1064 | + * might be some tail zeroing. | |
| 886 | 1065 | */ |
| 887 | 1066 | down_write(&oi->ip_alloc_sem); |
| 888 | 1067 | |
| @@ -899,14 +1078,16 @@ static int ocfs2_extend_file(struct inode *inode, · 10 unmodified lines | ||
| 899 | 1078 | ret = ocfs2_convert_inline_data_to_extents(inode, di_bh); |
| 900 | 1079 | if (ret) { |
| 901 | 1080 | up_write(&oi->ip_alloc_sem); |
| 902 | − | |
| 903 | 1081 | mlog_errno(ret); |
| 904 | 1082 | goto out; |
| 905 | 1083 | } |
| 906 | 1084 | } |
| 907 | 1085 | |
| 908 | − if (!ocfs2_sparse_alloc(OCFS2_SB(inode->i_sb))) | |
| 909 | − ret = ocfs2_extend_no_holes(inode, new_i_size, new_i_size); | |
| 1086 | + if (ocfs2_sparse_alloc(OCFS2_SB(inode->i_sb))) | |
| 1087 | + ret = ocfs2_zero_extend(inode, di_bh, new_i_size); | |
| 1088 | + else | |
| 1089 | + ret = ocfs2_extend_no_holes(inode, di_bh, new_i_size, | |
| 1090 | + new_i_size); | |
| 910 | 1091 | |
| 911 | 1092 | up_write(&oi->ip_alloc_sem); |
| 912 | 1093 | |
| @@ -54,8 +54,10 @@ int ocfs2_add_inode_data(struct ocfs2_super *osb, · 53 unmodified lines | ||
| 54 | 54 | int ocfs2_simple_size_update(struct inode *inode, |
| 55 | 55 | struct buffer_head *di_bh, |
| 56 | 56 | u64 new_i_size); |
| 57 | −int ocfs2_extend_no_holes(struct inode *inode, u64 new_i_size, | |
| 58 | − u64 zero_to); | |
| 57 | +int ocfs2_extend_no_holes(struct inode *inode, struct buffer_head *di_bh, | |
| 58 | + u64 new_i_size, u64 zero_to); | |
| 59 | +int ocfs2_zero_extend(struct inode *inode, struct buffer_head *di_bh, | |
| 60 | + loff_t zero_to); | |
| 59 | 61 | int ocfs2_setattr(struct dentry *dentry, struct iattr *attr); |
| 60 | 62 | int ocfs2_getattr(struct vfsmount *mnt, struct dentry *dentry, |
| 61 | 63 | struct kstat *stat); |
| @@ -472,7 +472,7 @@ static inline struct ocfs2_triggers *to_ocfs2_trigger(struct jbd2_buffer_trigger · 471 unmodified lines | ||
| 472 | 472 | return container_of(triggers, struct ocfs2_triggers, ot_triggers); |
| 473 | 473 | } |
| 474 | 474 | |
| 475 | −static void ocfs2_commit_trigger(struct jbd2_buffer_trigger_type *triggers, | |
| 475 | +static void ocfs2_frozen_trigger(struct jbd2_buffer_trigger_type *triggers, | |
| 476 | 476 | struct buffer_head *bh, |
| 477 | 477 | void *data, size_t size) |
| 478 | 478 | { |
| @@ -491,7 +491,7 @@ static void ocfs2_commit_trigger(struct jbd2_buffer_trigger_type *triggers, · 12 unmodified lines | ||
| 491 | 491 | * Quota blocks have their own trigger because the struct ocfs2_block_check |
| 492 | 492 | * offset depends on the blocksize. |
| 493 | 493 | */ |
| 494 | −static void ocfs2_dq_commit_trigger(struct jbd2_buffer_trigger_type *triggers, | |
| 494 | +static void ocfs2_dq_frozen_trigger(struct jbd2_buffer_trigger_type *triggers, | |
| 495 | 495 | struct buffer_head *bh, |
| 496 | 496 | void *data, size_t size) |
| 497 | 497 | { |
| @@ -511,7 +511,7 @@ static void ocfs2_dq_commit_trigger(struct jbd2_buffer_trigger_type *triggers, · 13 unmodified lines | ||
| 511 | 511 | * Directory blocks also have their own trigger because the |
| 512 | 512 | * struct ocfs2_block_check offset depends on the blocksize. |
| 513 | 513 | */ |
| 514 | −static void ocfs2_db_commit_trigger(struct jbd2_buffer_trigger_type *triggers, | |
| 514 | +static void ocfs2_db_frozen_trigger(struct jbd2_buffer_trigger_type *triggers, | |
| 515 | 515 | struct buffer_head *bh, |
| 516 | 516 | void *data, size_t size) |
| 517 | 517 | { |
| @@ -544,7 +544,7 @@ static void ocfs2_abort_trigger(struct jbd2_buffer_trigger_type *triggers, · 26 unmodified lines | ||
| 544 | 544 | |
| 545 | 545 | static struct ocfs2_triggers di_triggers = { |
| 546 | 546 | .ot_triggers = { |
| 547 | − .t_commit = ocfs2_commit_trigger, | |
| 547 | + .t_frozen = ocfs2_frozen_trigger, | |
| 548 | 548 | .t_abort = ocfs2_abort_trigger, |
| 549 | 549 | }, |
| 550 | 550 | .ot_offset = offsetof(struct ocfs2_dinode, i_check), |
| @@ -552,7 +552,7 @@ static struct ocfs2_triggers di_triggers = { · 1 unmodified line | ||
| 552 | 552 | |
| 553 | 553 | static struct ocfs2_triggers eb_triggers = { |
| 554 | 554 | .ot_triggers = { |
| 555 | − .t_commit = ocfs2_commit_trigger, | |
| 555 | + .t_frozen = ocfs2_frozen_trigger, | |
| 556 | 556 | .t_abort = ocfs2_abort_trigger, |
| 557 | 557 | }, |
| 558 | 558 | .ot_offset = offsetof(struct ocfs2_extent_block, h_check), |
| @@ -560,7 +560,7 @@ static struct ocfs2_triggers eb_triggers = { · 1 unmodified line | ||
| 560 | 560 | |
| 561 | 561 | static struct ocfs2_triggers rb_triggers = { |
| 562 | 562 | .ot_triggers = { |
| 563 | − .t_commit = ocfs2_commit_trigger, | |
| 563 | + .t_frozen = ocfs2_frozen_trigger, | |
| 564 | 564 | .t_abort = ocfs2_abort_trigger, |
| 565 | 565 | }, |
| 566 | 566 | .ot_offset = offsetof(struct ocfs2_refcount_block, rf_check), |
| @@ -568,7 +568,7 @@ static struct ocfs2_triggers rb_triggers = { · 1 unmodified line | ||
| 568 | 568 | |
| 569 | 569 | static struct ocfs2_triggers gd_triggers = { |
| 570 | 570 | .ot_triggers = { |
| 571 | − .t_commit = ocfs2_commit_trigger, | |
| 571 | + .t_frozen = ocfs2_frozen_trigger, | |
| 572 | 572 | .t_abort = ocfs2_abort_trigger, |
| 573 | 573 | }, |
| 574 | 574 | .ot_offset = offsetof(struct ocfs2_group_desc, bg_check), |
| @@ -576,14 +576,14 @@ static struct ocfs2_triggers gd_triggers = { · 1 unmodified line | ||
| 576 | 576 | |
| 577 | 577 | static struct ocfs2_triggers db_triggers = { |
| 578 | 578 | .ot_triggers = { |
| 579 | − .t_commit = ocfs2_db_commit_trigger, | |
| 579 | + .t_frozen = ocfs2_db_frozen_trigger, | |
| 580 | 580 | .t_abort = ocfs2_abort_trigger, |
| 581 | 581 | }, |
| 582 | 582 | }; |
| 583 | 583 | |
| 584 | 584 | static struct ocfs2_triggers xb_triggers = { |
| 585 | 585 | .ot_triggers = { |
| 586 | − .t_commit = ocfs2_commit_trigger, | |
| 586 | + .t_frozen = ocfs2_frozen_trigger, | |
| 587 | 587 | .t_abort = ocfs2_abort_trigger, |
| 588 | 588 | }, |
| 589 | 589 | .ot_offset = offsetof(struct ocfs2_xattr_block, xb_check), |
| @@ -591,14 +591,14 @@ static struct ocfs2_triggers xb_triggers = { · 1 unmodified line | ||
| 591 | 591 | |
| 592 | 592 | static struct ocfs2_triggers dq_triggers = { |
| 593 | 593 | .ot_triggers = { |
| 594 | − .t_commit = ocfs2_dq_commit_trigger, | |
| 594 | + .t_frozen = ocfs2_dq_frozen_trigger, | |
| 595 | 595 | .t_abort = ocfs2_abort_trigger, |
| 596 | 596 | }, |
| 597 | 597 | }; |
| 598 | 598 | |
| 599 | 599 | static struct ocfs2_triggers dr_triggers = { |
| 600 | 600 | .ot_triggers = { |
| 601 | − .t_commit = ocfs2_commit_trigger, | |
| 601 | + .t_frozen = ocfs2_frozen_trigger, | |
| 602 | 602 | .t_abort = ocfs2_abort_trigger, |
| 603 | 603 | }, |
| 604 | 604 | .ot_offset = offsetof(struct ocfs2_dx_root_block, dr_check), |
| @@ -606,7 +606,7 @@ static struct ocfs2_triggers dr_triggers = { · 1 unmodified line | ||
| 606 | 606 | |
| 607 | 607 | static struct ocfs2_triggers dl_triggers = { |
| 608 | 608 | .ot_triggers = { |
| 609 | − .t_commit = ocfs2_commit_trigger, | |
| 609 | + .t_frozen = ocfs2_frozen_trigger, | |
| 610 | 610 | .t_abort = ocfs2_abort_trigger, |
| 611 | 611 | }, |
| 612 | 612 | .ot_offset = offsetof(struct ocfs2_dx_leaf, dl_check), |
| @@ -1936,7 +1936,7 @@ void ocfs2_orphan_scan_work(struct work_struct *work) · 1323 unmodified lines | ||
| 1936 | 1936 | mutex_lock(&os->os_lock); |
| 1937 | 1937 | ocfs2_queue_orphan_scan(osb); |
| 1938 | 1938 | if (atomic_read(&os->os_state) == ORPHAN_SCAN_ACTIVE) |
| 1939 | − schedule_delayed_work(&os->os_orphan_scan_work, | |
| 1939 | + queue_delayed_work(ocfs2_wq, &os->os_orphan_scan_work, | |
| 1940 | 1940 | ocfs2_orphan_scan_timeout()); |
| 1941 | 1941 | mutex_unlock(&os->os_lock); |
| 1942 | 1942 | } |
| @@ -1976,8 +1976,8 @@ void ocfs2_orphan_scan_start(struct ocfs2_super *osb) · 33 unmodified lines | ||
| 1976 | 1976 | atomic_set(&os->os_state, ORPHAN_SCAN_INACTIVE); |
| 1977 | 1977 | else { |
| 1978 | 1978 | atomic_set(&os->os_state, ORPHAN_SCAN_ACTIVE); |
| 1979 | − schedule_delayed_work(&os->os_orphan_scan_work, | |
| 1980 | − ocfs2_orphan_scan_timeout()); | |
| 1979 | + queue_delayed_work(ocfs2_wq, &os->os_orphan_scan_work, | |
| 1980 | + ocfs2_orphan_scan_timeout()); | |
| 1981 | 1981 | } |
| 1982 | 1982 | } |
| 1983 | 1983 | |
| @@ -118,6 +118,7 @@ unsigned int ocfs2_la_default_mb(struct ocfs2_super *osb) · 117 unmodified lines | ||
| 118 | 118 | { |
| 119 | 119 | unsigned int la_mb; |
| 120 | 120 | unsigned int gd_mb; |
| 121 | + unsigned int la_max_mb; | |
| 121 | 122 | unsigned int megs_per_slot; |
| 122 | 123 | struct super_block *sb = osb->sb; |
| 123 | 124 | |
| @@ -182,6 +183,12 @@ unsigned int ocfs2_la_default_mb(struct ocfs2_super *osb) · 58 unmodified lines | ||
| 182 | 183 | if (megs_per_slot < la_mb) |
| 183 | 184 | la_mb = megs_per_slot; |
| 184 | 185 | |
| 186 | + /* We can't store more bits than we can in a block. */ | |
| 187 | + la_max_mb = ocfs2_clusters_to_megabytes(osb->sb, | |
| 188 | + ocfs2_local_alloc_size(sb) * 8); | |
| 189 | + if (la_mb > la_max_mb) | |
| 190 | + la_mb = la_max_mb; | |
| 191 | + | |
| 185 | 192 | return la_mb; |
| 186 | 193 | } |
| 187 | 194 | |
| @@ -775,7 +775,7 @@ static int ocfs2_acquire_dquot(struct dquot *dquot) · 774 unmodified lines | ||
| 775 | 775 | * locking allocators ranks above a transaction start |
| 776 | 776 | */ |
| 777 | 777 | WARN_ON(journal_current_handle()); |
| 778 | − status = ocfs2_extend_no_holes(gqinode, | |
| 778 | + status = ocfs2_extend_no_holes(gqinode, NULL, | |
| 779 | 779 | gqinode->i_size + (need_alloc << sb->s_blocksize_bits), |
| 780 | 780 | gqinode->i_size); |
| 781 | 781 | if (status < 0) |
| @@ -971,7 +971,7 @@ static struct ocfs2_quota_chunk *ocfs2_local_quota_add_chunk( · 970 unmodified lines | ||
| 971 | 971 | u64 p_blkno; |
| 972 | 972 | |
| 973 | 973 | /* We are protected by dqio_sem so no locking needed */ |
| 974 | − status = ocfs2_extend_no_holes(lqinode, | |
| 974 | + status = ocfs2_extend_no_holes(lqinode, NULL, | |
| 975 | 975 | lqinode->i_size + 2 * sb->s_blocksize, |
| 976 | 976 | lqinode->i_size); |
| 977 | 977 | if (status < 0) { |
| @@ -1114,7 +1114,7 @@ static struct ocfs2_quota_chunk *ocfs2_extend_local_quota_file( · 136 unmodified lines | ||
| 1114 | 1114 | return ocfs2_local_quota_add_chunk(sb, type, offset); |
| 1115 | 1115 | |
| 1116 | 1116 | /* We are protected by dqio_sem so no locking needed */ |
| 1117 | − status = ocfs2_extend_no_holes(lqinode, | |
| 1117 | + status = ocfs2_extend_no_holes(lqinode, NULL, | |
| 1118 | 1118 | lqinode->i_size + sb->s_blocksize, |
| 1119 | 1119 | lqinode->i_size); |
| 1120 | 1120 | if (status < 0) { |
| @@ -2931,6 +2931,12 @@ static int ocfs2_duplicate_clusters_by_page(handle_t *handle, · 2930 unmodified lines | ||
| 2931 | 2931 | |
| 2932 | 2932 | offset = ((loff_t)cpos) << OCFS2_SB(sb)->s_clustersize_bits; |
| 2933 | 2933 | end = offset + (new_len << OCFS2_SB(sb)->s_clustersize_bits); |
| 2934 | + /* | |
| 2935 | + * We only duplicate pages until we reach the page contains i_size - 1. | |
| 2936 | + * So trim 'end' to i_size. | |
| 2937 | + */ | |
| 2938 | + if (end > i_size_read(context->inode)) | |
| 2939 | + end = i_size_read(context->inode); | |
| 2934 | 2940 | |
| 2935 | 2941 | while (offset < end) { |
| 2936 | 2942 | page_index = offset >> PAGE_CACHE_SHIFT; |
| @@ -4166,6 +4172,12 @@ static int __ocfs2_reflink(struct dentry *old_dentry, · 1229 unmodified lines | ||
| 4166 | 4172 | struct inode *inode = old_dentry->d_inode; |
| 4167 | 4173 | struct buffer_head *new_bh = NULL; |
| 4168 | 4174 | |
| 4175 | + if (OCFS2_I(inode)->ip_flags & OCFS2_INODE_SYSTEM_FILE) { | |
| 4176 | + ret = -EINVAL; | |
| 4177 | + mlog_errno(ret); | |
| 4178 | + goto out; | |
| 4179 | + } | |
| 4180 | + | |
| 4169 | 4181 | ret = filemap_fdatawrite(inode->i_mapping); |
| 4170 | 4182 | if (ret) { |
| 4171 | 4183 | mlog_errno(ret); |
| @@ -741,7 +741,7 @@ static int ocfs2_block_group_alloc(struct ocfs2_super *osb, · 740 unmodified lines | ||
| 741 | 741 | le16_to_cpu(bg->bg_free_bits_count)); |
| 742 | 742 | le32_add_cpu(&cl->cl_recs[alloc_rec].c_total, |
| 743 | 743 | le16_to_cpu(bg->bg_bits)); |
| 744 | − cl->cl_recs[alloc_rec].c_blkno = cpu_to_le64(bg->bg_blkno); | |
| 744 | + cl->cl_recs[alloc_rec].c_blkno = bg->bg_blkno; | |
| 745 | 745 | if (le16_to_cpu(cl->cl_next_free_rec) < le16_to_cpu(cl->cl_count)) |
| 746 | 746 | le16_add_cpu(&cl->cl_next_free_rec, 1); |
| 747 | 747 | |
| @@ -709,7 +709,7 @@ static int ocfs2_xattr_extend_allocation(struct inode *inode, · 708 unmodified lines | ||
| 709 | 709 | struct ocfs2_xattr_value_buf *vb, |
| 710 | 710 | struct ocfs2_xattr_set_ctxt *ctxt) |
| 711 | 711 | { |
| 712 | − int status = 0; | |
| 712 | + int status = 0, credits; | |
| 713 | 713 | handle_t *handle = ctxt->handle; |
| 714 | 714 | enum ocfs2_alloc_restarted why; |
| 715 | 715 | u32 prev_clusters, logical_start = le32_to_cpu(vb->vb_xv->xr_clusters); |
| @@ -719,38 +719,54 @@ static int ocfs2_xattr_extend_allocation(struct inode *inode, · 3 unmodified lines | ||
| 719 | 719 | |
| 720 | 720 | ocfs2_init_xattr_value_extent_tree(&et, INODE_CACHE(inode), vb); |
| 721 | 721 | |
| 722 | − status = vb->vb_access(handle, INODE_CACHE(inode), vb->vb_bh, | |
| 723 | − OCFS2_JOURNAL_ACCESS_WRITE); | |
| 724 | − if (status < 0) { | |
| 725 | − mlog_errno(status); | |
| 726 | − goto leave; | |
| 727 | − } | |
| 722 | + while (clusters_to_add) { | |
| 723 | + status = vb->vb_access(handle, INODE_CACHE(inode), vb->vb_bh, | |
| 724 | + OCFS2_JOURNAL_ACCESS_WRITE); | |
| 725 | + if (status < 0) { | |
| 726 | + mlog_errno(status); | |
| 727 | + break; | |
| 728 | + } | |
| 728 | 729 | |
| 729 | − prev_clusters = le32_to_cpu(vb->vb_xv->xr_clusters); | |
| 730 | − status = ocfs2_add_clusters_in_btree(handle, | |
| 731 | − &et, | |
| 732 | − &logical_start, | |
| 733 | − clusters_to_add, | |
| 734 | − 0, | |
| 735 | − ctxt->data_ac, | |
| 736 | − ctxt->meta_ac, | |
| 737 | − &why); | |
| 738 | − if (status < 0) { | |
| 739 | − mlog_errno(status); | |
| 740 | − goto leave; | |
| 741 | − } | |
| 730 | + prev_clusters = le32_to_cpu(vb->vb_xv->xr_clusters); | |
| 731 | + status = ocfs2_add_clusters_in_btree(handle, | |
| 732 | + &et, | |
| 733 | + &logical_start, | |
| 734 | + clusters_to_add, | |
| 735 | + 0, | |
| 736 | + ctxt->data_ac, | |
| 737 | + ctxt->meta_ac, | |
| 738 | + &why); | |
| 739 | + if ((status < 0) && (status != -EAGAIN)) { | |
| 740 | + if (status != -ENOSPC) | |
| 741 | + mlog_errno(status); | |
| 742 | + break; | |
| 743 | + } | |
| 742 | 744 | |
| 743 | − ocfs2_journal_dirty(handle, vb->vb_bh); | |
| 745 | + ocfs2_journal_dirty(handle, vb->vb_bh); | |
| 744 | 746 | |
| 745 | − clusters_to_add -= le32_to_cpu(vb->vb_xv->xr_clusters) - prev_clusters; | |
| 747 | + clusters_to_add -= le32_to_cpu(vb->vb_xv->xr_clusters) - | |
| 748 | + prev_clusters; | |
| 746 | 749 | |
| 747 | − /* | |
| 748 | − * We should have already allocated enough space before the transaction, | |
| 749 | − * so no need to restart. | |
| 750 | − */ | |
| 751 | − BUG_ON(why != RESTART_NONE || clusters_to_add); | |
| 752 | − | |
| 753 | −leave: | |
| 750 | + if (why != RESTART_NONE && clusters_to_add) { | |
| 751 | + /* | |
| 752 | + * We can only fail in case the alloc file doesn't give | |
| 753 | + * up enough clusters. | |
| 754 | + */ | |
| 755 | + BUG_ON(why == RESTART_META); | |
| 756 | + | |
| 757 | + mlog(0, "restarting xattr value extension for %u" | |
| 758 | + " clusters,.\n", clusters_to_add); | |
| 759 | + credits = ocfs2_calc_extend_credits(inode->i_sb, | |
| 760 | + &vb->vb_xv->xr_list, | |
| 761 | + clusters_to_add); | |
| 762 | + status = ocfs2_extend_trans(handle, credits); | |
| 763 | + if (status < 0) { | |
| 764 | + status = -ENOMEM; | |
| 765 | + mlog_errno(status); | |
| 766 | + break; | |
| 767 | + } | |
| 768 | + } | |
| 769 | + } | |
| 754 | 770 | |
| 755 | 771 | return status; |
| 756 | 772 | } |
| @@ -6788,16 +6804,15 @@ out: · 6031 unmodified lines | ||
| 6788 | 6804 | return ret; |
| 6789 | 6805 | } |
| 6790 | 6806 | |
| 6791 | −static int ocfs2_reflink_xattr_buckets(handle_t *handle, | |
| 6807 | +static int ocfs2_reflink_xattr_bucket(handle_t *handle, | |
| 6792 | 6808 | u64 blkno, u64 new_blkno, u32 clusters, |
| 6809 | + u32 *cpos, int num_buckets, | |
| 6793 | 6810 | struct ocfs2_alloc_context *meta_ac, |
| 6794 | 6811 | struct ocfs2_alloc_context *data_ac, |
| 6795 | 6812 | struct ocfs2_reflink_xattr_tree_args *args) |
| 6796 | 6813 | { |
| 6797 | 6814 | int i, j, ret = 0; |
| 6798 | 6815 | struct super_block *sb = args->reflink->old_inode->i_sb; |
| 6799 | − u32 bpc = ocfs2_xattr_buckets_per_cluster(OCFS2_SB(sb)); | |
| 6800 | − u32 num_buckets = clusters * bpc; | |
| 6801 | 6816 | int bpb = args->old_bucket->bu_blocks; |
| 6802 | 6817 | struct ocfs2_xattr_value_buf vb = { |
| 6803 | 6818 | .vb_access = ocfs2_journal_access, |
| @@ -6816,14 +6831,6 @@ static int ocfs2_reflink_xattr_buckets(handle_t *handle, · 12 unmodified lines | ||
| 6816 | 6831 | break; |
| 6817 | 6832 | } |
| 6818 | 6833 | |
| 6819 | − /* | |
| 6820 | − * The real bucket num in this series of blocks is stored | |
| 6821 | − * in the 1st bucket. | |
| 6822 | − */ | |
| 6823 | − if (i == 0) | |
| 6824 | − num_buckets = le16_to_cpu( | |
| 6825 | − bucket_xh(args->old_bucket)->xh_num_buckets); | |
| 6826 | − | |
| 6827 | 6834 | ret = ocfs2_xattr_bucket_journal_access(handle, |
| 6828 | 6835 | args->new_bucket, |
| 6829 | 6836 | OCFS2_JOURNAL_ACCESS_CREATE); |
| @@ -6837,6 +6844,18 @@ static int ocfs2_reflink_xattr_buckets(handle_t *handle, · 7 unmodified lines | ||
| 6837 | 6844 | bucket_block(args->old_bucket, j), |
| 6838 | 6845 | sb->s_blocksize); |
| 6839 | 6846 | |
| 6847 | + /* | |
| 6848 | + * Record the start cpos so that we can use it to initialize | |
| 6849 | + * our xattr tree we also set the xh_num_bucket for the new | |
| 6850 | + * bucket. | |
| 6851 | + */ | |
| 6852 | + if (i == 0) { | |
| 6853 | + *cpos = le32_to_cpu(bucket_xh(args->new_bucket)-> | |
| 6854 | + xh_entries[0].xe_name_hash); | |
| 6855 | + bucket_xh(args->new_bucket)->xh_num_buckets = | |
| 6856 | + cpu_to_le16(num_buckets); | |
| 6857 | + } | |
| 6858 | + | |
| 6840 | 6859 | ocfs2_xattr_bucket_journal_dirty(handle, args->new_bucket); |
| 6841 | 6860 | |
| 6842 | 6861 | ret = ocfs2_reflink_xattr_header(handle, args->reflink, |
| @@ -6866,6 +6885,7 @@ static int ocfs2_reflink_xattr_buckets(handle_t *handle, · 23 unmodified lines | ||
| 6866 | 6885 | } |
| 6867 | 6886 | |
| 6868 | 6887 | ocfs2_xattr_bucket_journal_dirty(handle, args->new_bucket); |
| 6888 | + | |
| 6869 | 6889 | ocfs2_xattr_bucket_relse(args->old_bucket); |
| 6870 | 6890 | ocfs2_xattr_bucket_relse(args->new_bucket); |
| 6871 | 6891 | } |
| @@ -6874,6 +6894,75 @@ static int ocfs2_reflink_xattr_buckets(handle_t *handle, · 2 unmodified lines | ||
| 6874 | 6894 | ocfs2_xattr_bucket_relse(args->new_bucket); |
| 6875 | 6895 | return ret; |
| 6876 | 6896 | } |
| 6897 | + | |
| 6898 | +static int ocfs2_reflink_xattr_buckets(handle_t *handle, | |
| 6899 | + struct inode *inode, | |
| 6900 | + struct ocfs2_reflink_xattr_tree_args *args, | |
| 6901 | + struct ocfs2_extent_tree *et, | |
| 6902 | + struct ocfs2_alloc_context *meta_ac, | |
| 6903 | + struct ocfs2_alloc_context *data_ac, | |
| 6904 | + u64 blkno, u32 cpos, u32 len) | |
| 6905 | +{ | |
| 6906 | + int ret, first_inserted = 0; | |
| 6907 | + u32 p_cluster, num_clusters, reflink_cpos = 0; | |
| 6908 | + u64 new_blkno; | |
| 6909 | + unsigned int num_buckets, reflink_buckets; | |
| 6910 | + unsigned int bpc = | |
| 6911 | + ocfs2_xattr_buckets_per_cluster(OCFS2_SB(inode->i_sb)); | |
| 6912 | + | |
| 6913 | + ret = ocfs2_read_xattr_bucket(args->old_bucket, blkno); | |
| 6914 | + if (ret) { | |
| 6915 | + mlog_errno(ret); | |
| 6916 | + goto out; | |
| 6917 | + } | |
| 6918 | + num_buckets = le16_to_cpu(bucket_xh(args->old_bucket)->xh_num_buckets); | |
| 6919 | + ocfs2_xattr_bucket_relse(args->old_bucket); | |
| 6920 | + | |
| 6921 | + while (len && num_buckets) { | |
| 6922 | + ret = ocfs2_claim_clusters(handle, data_ac, | |
| 6923 | + 1, &p_cluster, &num_clusters); | |
| 6924 | + if (ret) { | |
| 6925 | + mlog_errno(ret); | |
| 6926 | + goto out; | |
| 6927 | + } | |
| 6928 | + | |
| 6929 | + new_blkno = ocfs2_clusters_to_blocks(inode->i_sb, p_cluster); | |
| 6930 | + reflink_buckets = min(num_buckets, bpc * num_clusters); | |
| 6931 | + | |
| 6932 | + ret = ocfs2_reflink_xattr_bucket(handle, blkno, | |
| 6933 | + new_blkno, num_clusters, | |
| 6934 | + &reflink_cpos, reflink_buckets, | |
| 6935 | + meta_ac, data_ac, args); | |
| 6936 | + if (ret) { | |
| 6937 | + mlog_errno(ret); | |
| 6938 | + goto out; | |
| 6939 | + } | |
| 6940 | + | |
| 6941 | + /* | |
| 6942 | + * For the 1st allocated cluster, we make it use the same cpos | |
| 6943 | + * so that the xattr tree looks the same as the original one | |
| 6944 | + * in the most case. | |
| 6945 | + */ | |
| 6946 | + if (!first_inserted) { | |
| 6947 | + reflink_cpos = cpos; | |
| 6948 | + first_inserted = 1; | |
| 6949 | + } | |
| 6950 | + ret = ocfs2_insert_extent(handle, et, reflink_cpos, new_blkno, | |
| 6951 | + num_clusters, 0, meta_ac); | |
| 6952 | + if (ret) | |
| 6953 | + mlog_errno(ret); | |
| 6954 | + | |
| 6955 | + mlog(0, "insert new xattr extent rec start %llu len %u to %u\n", | |
| 6956 | + (unsigned long long)new_blkno, num_clusters, reflink_cpos); | |
| 6957 | + | |
| 6958 | + len -= num_clusters; | |
| 6959 | + blkno += ocfs2_clusters_to_blocks(inode->i_sb, num_clusters); | |
| 6960 | + num_buckets -= reflink_buckets; | |
| 6961 | + } | |
| 6962 | +out: | |
| 6963 | + return ret; | |
| 6964 | +} | |
| 6965 | + | |
| 6877 | 6966 | /* |
| 6878 | 6967 | * Create the same xattr extent record in the new inode's xattr tree. |
| 6879 | 6968 | */ |
| @@ -6885,8 +6974,6 @@ static int ocfs2_reflink_xattr_rec(struct inode *inode, · 5 unmodified lines | ||
| 6885 | 6974 | void *para) |
| 6886 | 6975 | { |
| 6887 | 6976 | int ret, credits = 0; |
| 6888 | − u32 p_cluster, num_clusters; | |
| 6889 | − u64 new_blkno; | |
| 6890 | 6977 | handle_t *handle; |
| 6891 | 6978 | struct ocfs2_reflink_xattr_tree_args *args = |
| 6892 | 6979 | (struct ocfs2_reflink_xattr_tree_args *)para; |
| @@ -6895,6 +6982,9 @@ static int ocfs2_reflink_xattr_rec(struct inode *inode, · 2 unmodified lines | ||
| 6895 | 6982 | struct ocfs2_alloc_context *data_ac = NULL; |
| 6896 | 6983 | struct ocfs2_extent_tree et; |
| 6897 | 6984 | |
| 6985 | + mlog(0, "reflink xattr buckets %llu len %u\n", | |
| 6986 | + (unsigned long long)blkno, len); | |
| 6987 | + | |
| 6898 | 6988 | ocfs2_init_xattr_tree_extent_tree(&et, |
| 6899 | 6989 | INODE_CACHE(args->reflink->new_inode), |
| 6900 | 6990 | args->new_blk_bh); |
| @@ -6914,32 +7004,12 @@ static int ocfs2_reflink_xattr_rec(struct inode *inode, · 13 unmodified lines | ||
| 6914 | 7004 | goto out; |
| 6915 | 7005 | } |
| 6916 | 7006 | |
| 6917 | − ret = ocfs2_claim_clusters(handle, data_ac, | |
| 6918 | − len, &p_cluster, &num_clusters); | |
| 6919 | − if (ret) { | |
| 6920 | − mlog_errno(ret); | |
| 6921 | − goto out_commit; | |
| 6922 | − } | |
| 6923 | − | |
| 6924 | − new_blkno = ocfs2_clusters_to_blocks(osb->sb, p_cluster); | |
| 6925 | − | |
| 6926 | − mlog(0, "reflink xattr buckets %llu to %llu, len %u\n", | |
| 6927 | − (unsigned long long)blkno, (unsigned long long)new_blkno, len); | |
| 6928 | − ret = ocfs2_reflink_xattr_buckets(handle, blkno, new_blkno, len, | |
| 6929 | − meta_ac, data_ac, args); | |
| 6930 | − if (ret) { | |
| 6931 | − mlog_errno(ret); | |
| 6932 | − goto out_commit; | |
| 6933 | − } | |
| 6934 | − | |
| 6935 | − mlog(0, "insert new xattr extent rec start %llu len %u to %u\n", | |
| 6936 | − (unsigned long long)new_blkno, len, cpos); | |
| 6937 | − ret = ocfs2_insert_extent(handle, &et, cpos, new_blkno, | |
| 6938 | − len, 0, meta_ac); | |
| 7007 | + ret = ocfs2_reflink_xattr_buckets(handle, inode, args, &et, | |
| 7008 | + meta_ac, data_ac, | |
| 7009 | + blkno, cpos, len); | |
| 6939 | 7010 | if (ret) |
| 6940 | 7011 | mlog_errno(ret); |
| 6941 | 7012 | |
| 6942 | −out_commit: | |
| 6943 | 7013 | ocfs2_commit_trans(osb, handle); |
| 6944 | 7014 | |
| 6945 | 7015 | out: |
| @@ -1026,11 +1026,12 @@ void __jbd2_journal_insert_checkpoint(struct journal_head *, transaction_t *); · 1025 unmodified lines | ||
| 1026 | 1026 | |
| 1027 | 1027 | struct jbd2_buffer_trigger_type { |
| 1028 | 1028 | /* |
| 1029 | − * Fired just before a buffer is written to the journal. | |
| 1030 | − * mapped_data is a mapped buffer that is the frozen data for | |
| 1031 | − * commit. | |
| 1029 | + * Fired a the moment data to write to the journal are known to be | |
| 1030 | + * stable - so either at the moment b_frozen_data is created or just | |
| 1031 | + * before a buffer is written to the journal. mapped_data is a mapped | |
| 1032 | + * buffer that is the frozen data for commit. | |
| 1032 | 1033 | */ |
| 1033 | − void (*t_commit)(struct jbd2_buffer_trigger_type *type, | |
| 1034 | + void (*t_frozen)(struct jbd2_buffer_trigger_type *type, | |
| 1034 | 1035 | struct buffer_head *bh, void *mapped_data, |
| 1035 | 1036 | size_t size); |
| 1036 | 1037 | |
| @@ -1042,7 +1043,7 @@ struct jbd2_buffer_trigger_type { · 5 unmodified lines | ||
| 1042 | 1043 | struct buffer_head *bh); |
| 1043 | 1044 | }; |
| 1044 | 1045 | |
| 1045 | −extern void jbd2_buffer_commit_trigger(struct journal_head *jh, | |
| 1046 | +extern void jbd2_buffer_frozen_trigger(struct journal_head *jh, | |
| 1046 | 1047 | void *mapped_data, |
| 1047 | 1048 | struct jbd2_buffer_trigger_type *triggers); |
| 1048 | 1049 | extern void jbd2_buffer_abort_trigger(struct journal_head *jh, |