diff options
| -rw-r--r-- | fs/jbd2/journal.c | 15 | ||||
| -rw-r--r-- | fs/jbd2/transaction.c | 9 | ||||
| -rw-r--r-- | fs/ocfs2/aops.c | 94 | ||||
| -rw-r--r-- | fs/ocfs2/dlm/dlmdomain.c | 3 | ||||
| -rw-r--r-- | fs/ocfs2/dlm/dlmmaster.c | 22 | ||||
| -rw-r--r-- | fs/ocfs2/dlm/dlmrecovery.c | 2 | ||||
| -rw-r--r-- | fs/ocfs2/file.c | 309 | ||||
| -rw-r--r-- | fs/ocfs2/file.h | 6 | ||||
| -rw-r--r-- | fs/ocfs2/journal.c | 30 | ||||
| -rw-r--r-- | fs/ocfs2/localalloc.c | 7 | ||||
| -rw-r--r-- | fs/ocfs2/quota_global.c | 2 | ||||
| -rw-r--r-- | fs/ocfs2/quota_local.c | 4 | ||||
| -rw-r--r-- | fs/ocfs2/refcounttree.c | 12 | ||||
| -rw-r--r-- | fs/ocfs2/suballoc.c | 2 | ||||
| -rw-r--r-- | fs/ocfs2/xattr.c | 200 | ||||
| -rw-r--r-- | include/linux/jbd2.h | 11 |
16 files changed, 504 insertions, 224 deletions
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c index bc2ff5932769..036880895bfc 100644 --- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c | |||
| @@ -297,7 +297,6 @@ int jbd2_journal_write_metadata_buffer(transaction_t *transaction, | |||
| 297 | struct page *new_page; | 297 | struct page *new_page; |
| 298 | unsigned int new_offset; | 298 | unsigned int new_offset; |
| 299 | struct buffer_head *bh_in = jh2bh(jh_in); | 299 | struct buffer_head *bh_in = jh2bh(jh_in); |
| 300 | struct jbd2_buffer_trigger_type *triggers; | ||
| 301 | journal_t *journal = transaction->t_journal; | 300 | journal_t *journal = transaction->t_journal; |
| 302 | 301 | ||
| 303 | /* | 302 | /* |
| @@ -328,21 +327,21 @@ repeat: | |||
| 328 | done_copy_out = 1; | 327 | done_copy_out = 1; |
| 329 | new_page = virt_to_page(jh_in->b_frozen_data); | 328 | new_page = virt_to_page(jh_in->b_frozen_data); |
| 330 | new_offset = offset_in_page(jh_in->b_frozen_data); | 329 | new_offset = offset_in_page(jh_in->b_frozen_data); |
| 331 | triggers = jh_in->b_frozen_triggers; | ||
| 332 | } else { | 330 | } else { |
| 333 | new_page = jh2bh(jh_in)->b_page; | 331 | new_page = jh2bh(jh_in)->b_page; |
| 334 | new_offset = offset_in_page(jh2bh(jh_in)->b_data); | 332 | new_offset = offset_in_page(jh2bh(jh_in)->b_data); |
| 335 | triggers = jh_in->b_triggers; | ||
| 336 | } | 333 | } |
| 337 | 334 | ||
| 338 | mapped_data = kmap_atomic(new_page, KM_USER0); | 335 | mapped_data = kmap_atomic(new_page, KM_USER0); |
| 339 | /* | 336 | /* |
| 340 | * Fire any commit trigger. Do this before checking for escaping, | 337 | * Fire data frozen trigger if data already wasn't frozen. Do this |
| 341 | * as the trigger may modify the magic offset. If a copy-out | 338 | * before checking for escaping, as the trigger may modify the magic |
| 342 | * happens afterwards, it will have the correct data in the buffer. | 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, | 342 | if (!done_copy_out) |
| 345 | triggers); | 343 | jbd2_buffer_frozen_trigger(jh_in, mapped_data + new_offset, |
| 344 | jh_in->b_triggers); | ||
| 346 | 345 | ||
| 347 | /* | 346 | /* |
| 348 | * Check for escaping | 347 | * Check for escaping |
diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c index e214d68620ac..b8e0806681bb 100644 --- a/fs/jbd2/transaction.c +++ b/fs/jbd2/transaction.c | |||
| @@ -725,6 +725,9 @@ done: | |||
| 725 | page = jh2bh(jh)->b_page; | 725 | page = jh2bh(jh)->b_page; |
| 726 | offset = ((unsigned long) jh2bh(jh)->b_data) & ~PAGE_MASK; | 726 | offset = ((unsigned long) jh2bh(jh)->b_data) & ~PAGE_MASK; |
| 727 | source = kmap_atomic(page, KM_USER0); | 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 | memcpy(jh->b_frozen_data, source+offset, jh2bh(jh)->b_size); | 731 | memcpy(jh->b_frozen_data, source+offset, jh2bh(jh)->b_size); |
| 729 | kunmap_atomic(source, KM_USER0); | 732 | kunmap_atomic(source, KM_USER0); |
| 730 | 733 | ||
| @@ -963,15 +966,15 @@ void jbd2_journal_set_triggers(struct buffer_head *bh, | |||
| 963 | jh->b_triggers = type; | 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 | struct jbd2_buffer_trigger_type *triggers) | 970 | struct jbd2_buffer_trigger_type *triggers) |
| 968 | { | 971 | { |
| 969 | struct buffer_head *bh = jh2bh(jh); | 972 | struct buffer_head *bh = jh2bh(jh); |
| 970 | 973 | ||
| 971 | if (!triggers || !triggers->t_commit) | 974 | if (!triggers || !triggers->t_frozen) |
| 972 | return; | 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 | void jbd2_buffer_abort_trigger(struct journal_head *jh, | 980 | void jbd2_buffer_abort_trigger(struct journal_head *jh, |
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c index 3623ca20cc18..356e976772bf 100644 --- a/fs/ocfs2/aops.c +++ b/fs/ocfs2/aops.c | |||
| @@ -196,15 +196,14 @@ int ocfs2_get_block(struct inode *inode, sector_t iblock, | |||
| 196 | dump_stack(); | 196 | dump_stack(); |
| 197 | goto bail; | 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 | bail: | 207 | bail: |
| 209 | if (err < 0) | 208 | if (err < 0) |
| 210 | err = -EIO; | 209 | err = -EIO; |
| @@ -459,36 +458,6 @@ int walk_page_buffers( handle_t *handle, | |||
| 459 | return ret; | 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 | static sector_t ocfs2_bmap(struct address_space *mapping, sector_t block) | 461 | static sector_t ocfs2_bmap(struct address_space *mapping, sector_t block) |
| 493 | { | 462 | { |
| 494 | sector_t status; | 463 | sector_t status; |
| @@ -1131,23 +1100,37 @@ out: | |||
| 1131 | */ | 1100 | */ |
| 1132 | static int ocfs2_grab_pages_for_write(struct address_space *mapping, | 1101 | static int ocfs2_grab_pages_for_write(struct address_space *mapping, |
| 1133 | struct ocfs2_write_ctxt *wc, | 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 | struct page *mmap_page) | 1105 | struct page *mmap_page) |
| 1136 | { | 1106 | { |
| 1137 | int ret = 0, i; | 1107 | int ret = 0, i; |
| 1138 | unsigned long start, target_index, index; | 1108 | unsigned long start, target_index, end_index, index; |
| 1139 | struct inode *inode = mapping->host; | 1109 | struct inode *inode = mapping->host; |
| 1110 | loff_t last_byte; | ||
| 1140 | 1111 | ||
| 1141 | target_index = user_pos >> PAGE_CACHE_SHIFT; | 1112 | target_index = user_pos >> PAGE_CACHE_SHIFT; |
| 1142 | 1113 | ||
| 1143 | /* | 1114 | /* |
| 1144 | * Figure out how many pages we'll be manipulating here. For | 1115 | * Figure out how many pages we'll be manipulating here. For |
| 1145 | * non allocating write, we just change the one | 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 | if (new) { | 1121 | if (new) { |
| 1149 | wc->w_num_pages = ocfs2_pages_per_cluster(inode->i_sb); | 1122 | wc->w_num_pages = ocfs2_pages_per_cluster(inode->i_sb); |
| 1150 | start = ocfs2_align_clusters_to_page_index(inode->i_sb, cpos); | 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 | } else { | 1134 | } else { |
| 1152 | wc->w_num_pages = 1; | 1135 | wc->w_num_pages = 1; |
| 1153 | start = target_index; | 1136 | start = target_index; |
| @@ -1620,21 +1603,20 @@ out: | |||
| 1620 | * write path can treat it as an non-allocating write, which has no | 1603 | * write path can treat it as an non-allocating write, which has no |
| 1621 | * special case code for sparse/nonsparse files. | 1604 | * special case code for sparse/nonsparse files. |
| 1622 | */ | 1605 | */ |
| 1623 | static int ocfs2_expand_nonsparse_inode(struct inode *inode, loff_t pos, | 1606 | static int ocfs2_expand_nonsparse_inode(struct inode *inode, |
| 1624 | unsigned len, | 1607 | struct buffer_head *di_bh, |
| 1608 | loff_t pos, unsigned len, | ||
| 1625 | struct ocfs2_write_ctxt *wc) | 1609 | struct ocfs2_write_ctxt *wc) |
| 1626 | { | 1610 | { |
| 1627 | int ret; | 1611 | int ret; |
| 1628 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | ||
| 1629 | loff_t newsize = pos + len; | 1612 | loff_t newsize = pos + len; |
| 1630 | 1613 | ||
| 1631 | if (ocfs2_sparse_alloc(osb)) | 1614 | BUG_ON(ocfs2_sparse_alloc(OCFS2_SB(inode->i_sb))); |
| 1632 | return 0; | ||
| 1633 | 1615 | ||
| 1634 | if (newsize <= i_size_read(inode)) | 1616 | if (newsize <= i_size_read(inode)) |
| 1635 | return 0; | 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 | if (ret) | 1620 | if (ret) |
| 1639 | mlog_errno(ret); | 1621 | mlog_errno(ret); |
| 1640 | 1622 | ||
| @@ -1644,6 +1626,18 @@ static int ocfs2_expand_nonsparse_inode(struct inode *inode, loff_t pos, | |||
| 1644 | return ret; | 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 | int ocfs2_write_begin_nolock(struct address_space *mapping, | 1641 | int ocfs2_write_begin_nolock(struct address_space *mapping, |
| 1648 | loff_t pos, unsigned len, unsigned flags, | 1642 | loff_t pos, unsigned len, unsigned flags, |
| 1649 | struct page **pagep, void **fsdata, | 1643 | struct page **pagep, void **fsdata, |
| @@ -1679,7 +1673,11 @@ int ocfs2_write_begin_nolock(struct address_space *mapping, | |||
| 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 | if (ret) { | 1681 | if (ret) { |
| 1684 | mlog_errno(ret); | 1682 | mlog_errno(ret); |
| 1685 | goto out; | 1683 | goto out; |
| @@ -1789,7 +1787,7 @@ int ocfs2_write_begin_nolock(struct address_space *mapping, | |||
| 1789 | * that we can zero and flush if we error after adding the | 1787 | * that we can zero and flush if we error after adding the |
| 1790 | * extent. | 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 | cluster_of_pages, mmap_page); | 1791 | cluster_of_pages, mmap_page); |
| 1794 | if (ret) { | 1792 | if (ret) { |
| 1795 | mlog_errno(ret); | 1793 | mlog_errno(ret); |
diff --git a/fs/ocfs2/dlm/dlmdomain.c b/fs/ocfs2/dlm/dlmdomain.c index 6b5a492e1749..153abb5abef0 100644 --- a/fs/ocfs2/dlm/dlmdomain.c +++ b/fs/ocfs2/dlm/dlmdomain.c | |||
| @@ -1671,7 +1671,7 @@ struct dlm_ctxt * dlm_register_domain(const char *domain, | |||
| 1671 | struct dlm_ctxt *dlm = NULL; | 1671 | struct dlm_ctxt *dlm = NULL; |
| 1672 | struct dlm_ctxt *new_ctxt = NULL; | 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 | ret = -ENAMETOOLONG; | 1675 | ret = -ENAMETOOLONG; |
| 1676 | mlog(ML_ERROR, "domain name length too long\n"); | 1676 | mlog(ML_ERROR, "domain name length too long\n"); |
| 1677 | goto leave; | 1677 | goto leave; |
| @@ -1709,6 +1709,7 @@ retry: | |||
| 1709 | } | 1709 | } |
| 1710 | 1710 | ||
| 1711 | if (dlm_protocol_compare(&dlm->fs_locking_proto, fs_proto)) { | 1711 | if (dlm_protocol_compare(&dlm->fs_locking_proto, fs_proto)) { |
| 1712 | spin_unlock(&dlm_domain_lock); | ||
| 1712 | mlog(ML_ERROR, | 1713 | mlog(ML_ERROR, |
| 1713 | "Requested locking protocol version is not " | 1714 | "Requested locking protocol version is not " |
| 1714 | "compatible with already registered domain " | 1715 | "compatible with already registered domain " |
diff --git a/fs/ocfs2/dlm/dlmmaster.c b/fs/ocfs2/dlm/dlmmaster.c index 4a7506a4e314..94b97fc6a88e 100644 --- a/fs/ocfs2/dlm/dlmmaster.c +++ b/fs/ocfs2/dlm/dlmmaster.c | |||
| @@ -2808,14 +2808,8 @@ again: | |||
| 2808 | mlog(0, "trying again...\n"); | 2808 | mlog(0, "trying again...\n"); |
| 2809 | goto again; | 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 | /* did the target go down or die? */ | 2813 | /* did the target go down or die? */ |
| 2820 | spin_lock(&dlm->spinlock); | 2814 | spin_lock(&dlm->spinlock); |
| 2821 | if (!test_bit(target, dlm->domain_map)) { | 2815 | if (!test_bit(target, dlm->domain_map)) { |
| @@ -2826,9 +2820,21 @@ again: | |||
| 2826 | spin_unlock(&dlm->spinlock); | 2820 | spin_unlock(&dlm->spinlock); |
| 2827 | 2821 | ||
| 2828 | /* | 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 | |||
| 2834 | /* | ||
| 2829 | * at this point: | 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 | * o there are no pending asts on this lockres | 2838 | * o there are no pending asts on this lockres |
| 2833 | * o all processes trying to reserve an ast on this | 2839 | * o all processes trying to reserve an ast on this |
| 2834 | * lockres must wait for the MIGRATING flag to clear | 2840 | * lockres must wait for the MIGRATING flag to clear |
diff --git a/fs/ocfs2/dlm/dlmrecovery.c b/fs/ocfs2/dlm/dlmrecovery.c index f8b75ce4be70..9dfaac73b36d 100644 --- a/fs/ocfs2/dlm/dlmrecovery.c +++ b/fs/ocfs2/dlm/dlmrecovery.c | |||
| @@ -463,7 +463,7 @@ static int dlm_do_recovery(struct dlm_ctxt *dlm) | |||
| 463 | if (dlm->reco.dead_node == O2NM_INVALID_NODE_NUM) { | 463 | if (dlm->reco.dead_node == O2NM_INVALID_NODE_NUM) { |
| 464 | int bit; | 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 | if (bit >= O2NM_MAX_NODES || bit < 0) | 467 | if (bit >= O2NM_MAX_NODES || bit < 0) |
| 468 | dlm_set_reco_dead_node(dlm, O2NM_INVALID_NODE_NUM); | 468 | dlm_set_reco_dead_node(dlm, O2NM_INVALID_NODE_NUM); |
| 469 | else | 469 | else |
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 6a13ea64c447..2b10b36d1577 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c | |||
| @@ -724,28 +724,55 @@ leave: | |||
| 724 | return status; | 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 | /* Some parts of this taken from generic_cont_expand, which turned out | 760 | /* Some parts of this taken from generic_cont_expand, which turned out |
| 728 | * to be too fragile to do exactly what we need without us having to | 761 | * to be too fragile to do exactly what we need without us having to |
| 729 | * worry about recursive locking in ->write_begin() and ->write_end(). */ | 762 | * worry about recursive locking in ->write_begin() and ->write_end(). */ |
| 730 | static int ocfs2_write_zero_page(struct inode *inode, | 763 | static int ocfs2_write_zero_page(struct inode *inode, u64 abs_from, |
| 731 | u64 size) | 764 | u64 abs_to) |
| 732 | { | 765 | { |
| 733 | struct address_space *mapping = inode->i_mapping; | 766 | struct address_space *mapping = inode->i_mapping; |
| 734 | struct page *page; | 767 | struct page *page; |
| 735 | unsigned long index; | 768 | unsigned long index = abs_from >> PAGE_CACHE_SHIFT; |
| 736 | unsigned int offset; | ||
| 737 | handle_t *handle = NULL; | 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 */ | 773 | BUG_ON(abs_from >= abs_to); |
| 741 | /* ugh. in prepare/commit_write, if from==to==start of block, we | 774 | BUG_ON(abs_to > (((u64)index + 1) << PAGE_CACHE_SHIFT)); |
| 742 | ** skip the prepare. make sure we never send an offset for the start | 775 | BUG_ON(abs_from & (inode->i_blkbits - 1)); |
| 743 | ** of a block | ||
| 744 | */ | ||
| 745 | if ((offset & (inode->i_sb->s_blocksize - 1)) == 0) { | ||
| 746 | offset++; | ||
| 747 | } | ||
| 748 | index = size >> PAGE_CACHE_SHIFT; | ||
| 749 | 776 | ||
| 750 | page = grab_cache_page(mapping, index); | 777 | page = grab_cache_page(mapping, index); |
| 751 | if (!page) { | 778 | if (!page) { |
| @@ -754,31 +781,56 @@ static int ocfs2_write_zero_page(struct inode *inode, | |||
| 754 | goto out; | 781 | goto out; |
| 755 | } | 782 | } |
| 756 | 783 | ||
| 757 | ret = ocfs2_prepare_write_nolock(inode, page, offset, offset); | 784 | /* Get the offsets within the page that we want to zero */ |
| 758 | if (ret < 0) { | 785 | zero_from = abs_from & (PAGE_CACHE_SIZE - 1); |
| 759 | mlog_errno(ret); | 786 | zero_to = abs_to & (PAGE_CACHE_SIZE - 1); |
| 760 | goto out_unlock; | 787 | if (!zero_to) |
| 761 | } | 788 | zero_to = PAGE_CACHE_SIZE; |
| 762 | 789 | ||
| 763 | if (ocfs2_should_order_data(inode)) { | 790 | mlog(0, |
| 764 | handle = ocfs2_start_walk_page_trans(inode, page, offset, | 791 | "abs_from = %llu, abs_to = %llu, index = %lu, zero_from = %u, zero_to = %u\n", |
| 765 | offset); | 792 | (unsigned long long)abs_from, (unsigned long long)abs_to, |
| 766 | if (IS_ERR(handle)) { | 793 | index, zero_from, zero_to); |
| 767 | ret = PTR_ERR(handle); | 794 | |
| 768 | handle = NULL; | 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 | goto out_unlock; | 810 | goto out_unlock; |
| 770 | } | 811 | } |
| 771 | } | ||
| 772 | 812 | ||
| 773 | /* must not update i_size! */ | 813 | if (!handle) { |
| 774 | ret = block_commit_write(page, offset, offset); | 814 | handle = ocfs2_zero_start_ordered_transaction(inode); |
| 775 | if (ret < 0) | 815 | if (IS_ERR(handle)) { |
| 776 | mlog_errno(ret); | 816 | ret = PTR_ERR(handle); |
| 777 | else | 817 | handle = NULL; |
| 778 | ret = 0; | 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 | if (handle) | 831 | if (handle) |
| 781 | ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle); | 832 | ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle); |
| 833 | |||
| 782 | out_unlock: | 834 | out_unlock: |
| 783 | unlock_page(page); | 835 | unlock_page(page); |
| 784 | page_cache_release(page); | 836 | page_cache_release(page); |
| @@ -786,22 +838,114 @@ out: | |||
| 786 | return ret; | 838 | return ret; |
| 787 | } | 839 | } |
| 788 | 840 | ||
| 789 | static int ocfs2_zero_extend(struct inode *inode, | 841 | /* |
| 790 | u64 zero_to_size) | 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; | 858 | int rc = 0, needs_cow = 0; |
| 793 | u64 start_off; | 859 | u32 p_cpos, zero_clusters = 0; |
| 794 | struct super_block *sb = inode->i_sb; | 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)); | 866 | while (zero_cpos < last_cpos) { |
| 797 | while (start_off < zero_to_size) { | 867 | rc = ocfs2_get_clusters(inode, zero_cpos, &p_cpos, |
| 798 | ret = ocfs2_write_zero_page(inode, start_off); | 868 | &num_clusters, &ext_flags); |
| 799 | if (ret < 0) { | 869 | if (rc) { |
| 800 | mlog_errno(ret); | 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 | goto out; | 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 | * Very large extends have the potential to lock up | 951 | * Very large extends have the potential to lock up |
| @@ -810,16 +954,63 @@ static int ocfs2_zero_extend(struct inode *inode, | |||
| 810 | cond_resched(); | 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 | return ret; | 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 | int ret; | 1003 | int ret; |
| 820 | u32 clusters_to_add; | 1004 | u32 clusters_to_add; |
| 821 | struct ocfs2_inode_info *oi = OCFS2_I(inode); | 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 | clusters_to_add = ocfs2_clusters_for_bytes(inode->i_sb, new_i_size); | 1014 | clusters_to_add = ocfs2_clusters_for_bytes(inode->i_sb, new_i_size); |
| 824 | if (clusters_to_add < oi->ip_clusters) | 1015 | if (clusters_to_add < oi->ip_clusters) |
| 825 | clusters_to_add = 0; | 1016 | clusters_to_add = 0; |
| @@ -840,7 +1031,7 @@ int ocfs2_extend_no_holes(struct inode *inode, u64 new_i_size, u64 zero_to) | |||
| 840 | * still need to zero the area between the old i_size and the | 1031 | * still need to zero the area between the old i_size and the |
| 841 | * new i_size. | 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 | if (ret < 0) | 1035 | if (ret < 0) |
| 845 | mlog_errno(ret); | 1036 | mlog_errno(ret); |
| 846 | 1037 | ||
| @@ -862,27 +1053,15 @@ static int ocfs2_extend_file(struct inode *inode, | |||
| 862 | goto out; | 1053 | goto out; |
| 863 | 1054 | ||
| 864 | if (i_size_read(inode) == new_i_size) | 1055 | if (i_size_read(inode) == new_i_size) |
| 865 | goto out; | 1056 | goto out; |
| 866 | BUG_ON(new_i_size < i_size_read(inode)); | 1057 | BUG_ON(new_i_size < i_size_read(inode)); |
| 867 | 1058 | ||
| 868 | /* | 1059 | /* |
| 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 | /* | ||
| 882 | * The alloc sem blocks people in read/write from reading our | 1060 | * The alloc sem blocks people in read/write from reading our |
| 883 | * allocation until we're done changing it. We depend on | 1061 | * allocation until we're done changing it. We depend on |
| 884 | * i_mutex to block other extend/truncate calls while we're | 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 | down_write(&oi->ip_alloc_sem); | 1066 | down_write(&oi->ip_alloc_sem); |
| 888 | 1067 | ||
| @@ -899,14 +1078,16 @@ static int ocfs2_extend_file(struct inode *inode, | |||
| 899 | ret = ocfs2_convert_inline_data_to_extents(inode, di_bh); | 1078 | ret = ocfs2_convert_inline_data_to_extents(inode, di_bh); |
| 900 | if (ret) { | 1079 | if (ret) { |
| 901 | up_write(&oi->ip_alloc_sem); | 1080 | up_write(&oi->ip_alloc_sem); |
| 902 | |||
| 903 | mlog_errno(ret); | 1081 | mlog_errno(ret); |
| 904 | goto out; | 1082 | goto out; |
| 905 | } | 1083 | } |
| 906 | } | 1084 | } |
| 907 | 1085 | ||
| 908 | if (!ocfs2_sparse_alloc(OCFS2_SB(inode->i_sb))) | 1086 | if (ocfs2_sparse_alloc(OCFS2_SB(inode->i_sb))) |
| 909 | ret = ocfs2_extend_no_holes(inode, new_i_size, new_i_size); | 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 | up_write(&oi->ip_alloc_sem); | 1092 | up_write(&oi->ip_alloc_sem); |
| 912 | 1093 | ||
diff --git a/fs/ocfs2/file.h b/fs/ocfs2/file.h index d66cf4f7c70e..97bf761c9e7c 100644 --- a/fs/ocfs2/file.h +++ b/fs/ocfs2/file.h | |||
| @@ -54,8 +54,10 @@ int ocfs2_add_inode_data(struct ocfs2_super *osb, | |||
| 54 | int ocfs2_simple_size_update(struct inode *inode, | 54 | int ocfs2_simple_size_update(struct inode *inode, |
| 55 | struct buffer_head *di_bh, | 55 | struct buffer_head *di_bh, |
| 56 | u64 new_i_size); | 56 | u64 new_i_size); |
| 57 | int ocfs2_extend_no_holes(struct inode *inode, u64 new_i_size, | 57 | int ocfs2_extend_no_holes(struct inode *inode, struct buffer_head *di_bh, |
| 58 | u64 zero_to); | 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 | int ocfs2_setattr(struct dentry *dentry, struct iattr *attr); | 61 | int ocfs2_setattr(struct dentry *dentry, struct iattr *attr); |
| 60 | int ocfs2_getattr(struct vfsmount *mnt, struct dentry *dentry, | 62 | int ocfs2_getattr(struct vfsmount *mnt, struct dentry *dentry, |
| 61 | struct kstat *stat); | 63 | struct kstat *stat); |
diff --git a/fs/ocfs2/journal.c b/fs/ocfs2/journal.c index 47878cf16418..625de9d7088c 100644 --- a/fs/ocfs2/journal.c +++ b/fs/ocfs2/journal.c | |||
| @@ -472,7 +472,7 @@ static inline struct ocfs2_triggers *to_ocfs2_trigger(struct jbd2_buffer_trigger | |||
| 472 | return container_of(triggers, struct ocfs2_triggers, ot_triggers); | 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 | struct buffer_head *bh, | 476 | struct buffer_head *bh, |
| 477 | void *data, size_t size) | 477 | void *data, size_t size) |
| 478 | { | 478 | { |
| @@ -491,7 +491,7 @@ static void ocfs2_commit_trigger(struct jbd2_buffer_trigger_type *triggers, | |||
| 491 | * Quota blocks have their own trigger because the struct ocfs2_block_check | 491 | * Quota blocks have their own trigger because the struct ocfs2_block_check |
| 492 | * offset depends on the blocksize. | 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 | struct buffer_head *bh, | 495 | struct buffer_head *bh, |
| 496 | void *data, size_t size) | 496 | void *data, size_t size) |
| 497 | { | 497 | { |
| @@ -511,7 +511,7 @@ static void ocfs2_dq_commit_trigger(struct jbd2_buffer_trigger_type *triggers, | |||
| 511 | * Directory blocks also have their own trigger because the | 511 | * Directory blocks also have their own trigger because the |
| 512 | * struct ocfs2_block_check offset depends on the blocksize. | 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 | struct buffer_head *bh, | 515 | struct buffer_head *bh, |
| 516 | void *data, size_t size) | 516 | void *data, size_t size) |
| 517 | { | 517 | { |
| @@ -544,7 +544,7 @@ static void ocfs2_abort_trigger(struct jbd2_buffer_trigger_type *triggers, | |||
| 544 | 544 | ||
| 545 | static struct ocfs2_triggers di_triggers = { | 545 | static struct ocfs2_triggers di_triggers = { |
| 546 | .ot_triggers = { | 546 | .ot_triggers = { |
| 547 | .t_commit = ocfs2_commit_trigger, | 547 | .t_frozen = ocfs2_frozen_trigger, |
| 548 | .t_abort = ocfs2_abort_trigger, | 548 | .t_abort = ocfs2_abort_trigger, |
| 549 | }, | 549 | }, |
| 550 | .ot_offset = offsetof(struct ocfs2_dinode, i_check), | 550 | .ot_offset = offsetof(struct ocfs2_dinode, i_check), |
| @@ -552,7 +552,7 @@ static struct ocfs2_triggers di_triggers = { | |||
| 552 | 552 | ||
| 553 | static struct ocfs2_triggers eb_triggers = { | 553 | static struct ocfs2_triggers eb_triggers = { |
| 554 | .ot_triggers = { | 554 | .ot_triggers = { |
| 555 | .t_commit = ocfs2_commit_trigger, | 555 | .t_frozen = ocfs2_frozen_trigger, |
| 556 | .t_abort = ocfs2_abort_trigger, | 556 | .t_abort = ocfs2_abort_trigger, |
| 557 | }, | 557 | }, |
| 558 | .ot_offset = offsetof(struct ocfs2_extent_block, h_check), | 558 | .ot_offset = offsetof(struct ocfs2_extent_block, h_check), |
| @@ -560,7 +560,7 @@ static struct ocfs2_triggers eb_triggers = { | |||
| 560 | 560 | ||
| 561 | static struct ocfs2_triggers rb_triggers = { | 561 | static struct ocfs2_triggers rb_triggers = { |
| 562 | .ot_triggers = { | 562 | .ot_triggers = { |
| 563 | .t_commit = ocfs2_commit_trigger, | 563 | .t_frozen = ocfs2_frozen_trigger, |
| 564 | .t_abort = ocfs2_abort_trigger, | 564 | .t_abort = ocfs2_abort_trigger, |
| 565 | }, | 565 | }, |
| 566 | .ot_offset = offsetof(struct ocfs2_refcount_block, rf_check), | 566 | .ot_offset = offsetof(struct ocfs2_refcount_block, rf_check), |
| @@ -568,7 +568,7 @@ static struct ocfs2_triggers rb_triggers = { | |||
| 568 | 568 | ||
| 569 | static struct ocfs2_triggers gd_triggers = { | 569 | static struct ocfs2_triggers gd_triggers = { |
| 570 | .ot_triggers = { | 570 | .ot_triggers = { |
| 571 | .t_commit = ocfs2_commit_trigger, | 571 | .t_frozen = ocfs2_frozen_trigger, |
| 572 | .t_abort = ocfs2_abort_trigger, | 572 | .t_abort = ocfs2_abort_trigger, |
| 573 | }, | 573 | }, |
| 574 | .ot_offset = offsetof(struct ocfs2_group_desc, bg_check), | 574 | .ot_offset = offsetof(struct ocfs2_group_desc, bg_check), |
| @@ -576,14 +576,14 @@ static struct ocfs2_triggers gd_triggers = { | |||
| 576 | 576 | ||
| 577 | static struct ocfs2_triggers db_triggers = { | 577 | static struct ocfs2_triggers db_triggers = { |
| 578 | .ot_triggers = { | 578 | .ot_triggers = { |
| 579 | .t_commit = ocfs2_db_commit_trigger, | 579 | .t_frozen = ocfs2_db_frozen_trigger, |
| 580 | .t_abort = ocfs2_abort_trigger, | 580 | .t_abort = ocfs2_abort_trigger, |
| 581 | }, | 581 | }, |
| 582 | }; | 582 | }; |
| 583 | 583 | ||
| 584 | static struct ocfs2_triggers xb_triggers = { | 584 | static struct ocfs2_triggers xb_triggers = { |
| 585 | .ot_triggers = { | 585 | .ot_triggers = { |
| 586 | .t_commit = ocfs2_commit_trigger, | 586 | .t_frozen = ocfs2_frozen_trigger, |
| 587 | .t_abort = ocfs2_abort_trigger, | 587 | .t_abort = ocfs2_abort_trigger, |
| 588 | }, | 588 | }, |
| 589 | .ot_offset = offsetof(struct ocfs2_xattr_block, xb_check), | 589 | .ot_offset = offsetof(struct ocfs2_xattr_block, xb_check), |
| @@ -591,14 +591,14 @@ static struct ocfs2_triggers xb_triggers = { | |||
| 591 | 591 | ||
| 592 | static struct ocfs2_triggers dq_triggers = { | 592 | static struct ocfs2_triggers dq_triggers = { |
| 593 | .ot_triggers = { | 593 | .ot_triggers = { |
| 594 | .t_commit = ocfs2_dq_commit_trigger, | 594 | .t_frozen = ocfs2_dq_frozen_trigger, |
| 595 | .t_abort = ocfs2_abort_trigger, | 595 | .t_abort = ocfs2_abort_trigger, |
| 596 | }, | 596 | }, |
| 597 | }; | 597 | }; |
| 598 | 598 | ||
| 599 | static struct ocfs2_triggers dr_triggers = { | 599 | static struct ocfs2_triggers dr_triggers = { |
| 600 | .ot_triggers = { | 600 | .ot_triggers = { |
| 601 | .t_commit = ocfs2_commit_trigger, | 601 | .t_frozen = ocfs2_frozen_trigger, |
| 602 | .t_abort = ocfs2_abort_trigger, | 602 | .t_abort = ocfs2_abort_trigger, |
| 603 | }, | 603 | }, |
| 604 | .ot_offset = offsetof(struct ocfs2_dx_root_block, dr_check), | 604 | .ot_offset = offsetof(struct ocfs2_dx_root_block, dr_check), |
| @@ -606,7 +606,7 @@ static struct ocfs2_triggers dr_triggers = { | |||
| 606 | 606 | ||
| 607 | static struct ocfs2_triggers dl_triggers = { | 607 | static struct ocfs2_triggers dl_triggers = { |
| 608 | .ot_triggers = { | 608 | .ot_triggers = { |
| 609 | .t_commit = ocfs2_commit_trigger, | 609 | .t_frozen = ocfs2_frozen_trigger, |
| 610 | .t_abort = ocfs2_abort_trigger, | 610 | .t_abort = ocfs2_abort_trigger, |
| 611 | }, | 611 | }, |
| 612 | .ot_offset = offsetof(struct ocfs2_dx_leaf, dl_check), | 612 | .ot_offset = offsetof(struct ocfs2_dx_leaf, dl_check), |
| @@ -1936,7 +1936,7 @@ void ocfs2_orphan_scan_work(struct work_struct *work) | |||
| 1936 | mutex_lock(&os->os_lock); | 1936 | mutex_lock(&os->os_lock); |
| 1937 | ocfs2_queue_orphan_scan(osb); | 1937 | ocfs2_queue_orphan_scan(osb); |
| 1938 | if (atomic_read(&os->os_state) == ORPHAN_SCAN_ACTIVE) | 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 | ocfs2_orphan_scan_timeout()); | 1940 | ocfs2_orphan_scan_timeout()); |
| 1941 | mutex_unlock(&os->os_lock); | 1941 | mutex_unlock(&os->os_lock); |
| 1942 | } | 1942 | } |
| @@ -1976,8 +1976,8 @@ void ocfs2_orphan_scan_start(struct ocfs2_super *osb) | |||
| 1976 | atomic_set(&os->os_state, ORPHAN_SCAN_INACTIVE); | 1976 | atomic_set(&os->os_state, ORPHAN_SCAN_INACTIVE); |
| 1977 | else { | 1977 | else { |
| 1978 | atomic_set(&os->os_state, ORPHAN_SCAN_ACTIVE); | 1978 | atomic_set(&os->os_state, ORPHAN_SCAN_ACTIVE); |
| 1979 | schedule_delayed_work(&os->os_orphan_scan_work, | 1979 | queue_delayed_work(ocfs2_wq, &os->os_orphan_scan_work, |
| 1980 | ocfs2_orphan_scan_timeout()); | 1980 | ocfs2_orphan_scan_timeout()); |
| 1981 | } | 1981 | } |
| 1982 | } | 1982 | } |
| 1983 | 1983 | ||
diff --git a/fs/ocfs2/localalloc.c b/fs/ocfs2/localalloc.c index 3d7419682dc0..ec6adbf8f551 100644 --- a/fs/ocfs2/localalloc.c +++ b/fs/ocfs2/localalloc.c | |||
| @@ -118,6 +118,7 @@ unsigned int ocfs2_la_default_mb(struct ocfs2_super *osb) | |||
| 118 | { | 118 | { |
| 119 | unsigned int la_mb; | 119 | unsigned int la_mb; |
| 120 | unsigned int gd_mb; | 120 | unsigned int gd_mb; |
| 121 | unsigned int la_max_mb; | ||
| 121 | unsigned int megs_per_slot; | 122 | unsigned int megs_per_slot; |
| 122 | struct super_block *sb = osb->sb; | 123 | struct super_block *sb = osb->sb; |
| 123 | 124 | ||
| @@ -182,6 +183,12 @@ unsigned int ocfs2_la_default_mb(struct ocfs2_super *osb) | |||
| 182 | if (megs_per_slot < la_mb) | 183 | if (megs_per_slot < la_mb) |
| 183 | la_mb = megs_per_slot; | 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 | return la_mb; | 192 | return la_mb; |
| 186 | } | 193 | } |
| 187 | 194 | ||
diff --git a/fs/ocfs2/quota_global.c b/fs/ocfs2/quota_global.c index 2bb35fe00511..4607923eb24c 100644 --- a/fs/ocfs2/quota_global.c +++ b/fs/ocfs2/quota_global.c | |||
| @@ -775,7 +775,7 @@ static int ocfs2_acquire_dquot(struct dquot *dquot) | |||
| 775 | * locking allocators ranks above a transaction start | 775 | * locking allocators ranks above a transaction start |
| 776 | */ | 776 | */ |
| 777 | WARN_ON(journal_current_handle()); | 777 | WARN_ON(journal_current_handle()); |
| 778 | status = ocfs2_extend_no_holes(gqinode, | 778 | status = ocfs2_extend_no_holes(gqinode, NULL, |
| 779 | gqinode->i_size + (need_alloc << sb->s_blocksize_bits), | 779 | gqinode->i_size + (need_alloc << sb->s_blocksize_bits), |
| 780 | gqinode->i_size); | 780 | gqinode->i_size); |
| 781 | if (status < 0) | 781 | if (status < 0) |
diff --git a/fs/ocfs2/quota_local.c b/fs/ocfs2/quota_local.c index 8bd70d4d184d..dc78764ccc4c 100644 --- a/fs/ocfs2/quota_local.c +++ b/fs/ocfs2/quota_local.c | |||
| @@ -971,7 +971,7 @@ static struct ocfs2_quota_chunk *ocfs2_local_quota_add_chunk( | |||
| 971 | u64 p_blkno; | 971 | u64 p_blkno; |
| 972 | 972 | ||
| 973 | /* We are protected by dqio_sem so no locking needed */ | 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 | lqinode->i_size + 2 * sb->s_blocksize, | 975 | lqinode->i_size + 2 * sb->s_blocksize, |
| 976 | lqinode->i_size); | 976 | lqinode->i_size); |
| 977 | if (status < 0) { | 977 | if (status < 0) { |
| @@ -1114,7 +1114,7 @@ static struct ocfs2_quota_chunk *ocfs2_extend_local_quota_file( | |||
| 1114 | return ocfs2_local_quota_add_chunk(sb, type, offset); | 1114 | return ocfs2_local_quota_add_chunk(sb, type, offset); |
| 1115 | 1115 | ||
| 1116 | /* We are protected by dqio_sem so no locking needed */ | 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 | lqinode->i_size + sb->s_blocksize, | 1118 | lqinode->i_size + sb->s_blocksize, |
| 1119 | lqinode->i_size); | 1119 | lqinode->i_size); |
| 1120 | if (status < 0) { | 1120 | if (status < 0) { |
diff --git a/fs/ocfs2/refcounttree.c b/fs/ocfs2/refcounttree.c index 4793f36f6518..3ac5aa733e9c 100644 --- a/fs/ocfs2/refcounttree.c +++ b/fs/ocfs2/refcounttree.c | |||
| @@ -2931,6 +2931,12 @@ static int ocfs2_duplicate_clusters_by_page(handle_t *handle, | |||
| 2931 | 2931 | ||
| 2932 | offset = ((loff_t)cpos) << OCFS2_SB(sb)->s_clustersize_bits; | 2932 | offset = ((loff_t)cpos) << OCFS2_SB(sb)->s_clustersize_bits; |
| 2933 | end = offset + (new_len << OCFS2_SB(sb)->s_clustersize_bits); | 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 | while (offset < end) { | 2941 | while (offset < end) { |
| 2936 | page_index = offset >> PAGE_CACHE_SHIFT; | 2942 | page_index = offset >> PAGE_CACHE_SHIFT; |
| @@ -4166,6 +4172,12 @@ static int __ocfs2_reflink(struct dentry *old_dentry, | |||
| 4166 | struct inode *inode = old_dentry->d_inode; | 4172 | struct inode *inode = old_dentry->d_inode; |
| 4167 | struct buffer_head *new_bh = NULL; | 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 | ret = filemap_fdatawrite(inode->i_mapping); | 4181 | ret = filemap_fdatawrite(inode->i_mapping); |
| 4170 | if (ret) { | 4182 | if (ret) { |
| 4171 | mlog_errno(ret); | 4183 | mlog_errno(ret); |
diff --git a/fs/ocfs2/suballoc.c b/fs/ocfs2/suballoc.c index f4c2a9eb8c4d..a8e6a95a353f 100644 --- a/fs/ocfs2/suballoc.c +++ b/fs/ocfs2/suballoc.c | |||
| @@ -741,7 +741,7 @@ static int ocfs2_block_group_alloc(struct ocfs2_super *osb, | |||
| 741 | le16_to_cpu(bg->bg_free_bits_count)); | 741 | le16_to_cpu(bg->bg_free_bits_count)); |
| 742 | le32_add_cpu(&cl->cl_recs[alloc_rec].c_total, | 742 | le32_add_cpu(&cl->cl_recs[alloc_rec].c_total, |
| 743 | le16_to_cpu(bg->bg_bits)); | 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 | if (le16_to_cpu(cl->cl_next_free_rec) < le16_to_cpu(cl->cl_count)) | 745 | if (le16_to_cpu(cl->cl_next_free_rec) < le16_to_cpu(cl->cl_count)) |
| 746 | le16_add_cpu(&cl->cl_next_free_rec, 1); | 746 | le16_add_cpu(&cl->cl_next_free_rec, 1); |
| 747 | 747 | ||
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c index e97b34842cfe..d03469f61801 100644 --- a/fs/ocfs2/xattr.c +++ b/fs/ocfs2/xattr.c | |||
| @@ -709,7 +709,7 @@ static int ocfs2_xattr_extend_allocation(struct inode *inode, | |||
| 709 | struct ocfs2_xattr_value_buf *vb, | 709 | struct ocfs2_xattr_value_buf *vb, |
| 710 | struct ocfs2_xattr_set_ctxt *ctxt) | 710 | struct ocfs2_xattr_set_ctxt *ctxt) |
| 711 | { | 711 | { |
| 712 | int status = 0; | 712 | int status = 0, credits; |
| 713 | handle_t *handle = ctxt->handle; | 713 | handle_t *handle = ctxt->handle; |
| 714 | enum ocfs2_alloc_restarted why; | 714 | enum ocfs2_alloc_restarted why; |
| 715 | u32 prev_clusters, logical_start = le32_to_cpu(vb->vb_xv->xr_clusters); | 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, | |||
| 719 | 719 | ||
| 720 | ocfs2_init_xattr_value_extent_tree(&et, INODE_CACHE(inode), vb); | 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, | 722 | while (clusters_to_add) { |
| 723 | OCFS2_JOURNAL_ACCESS_WRITE); | 723 | status = vb->vb_access(handle, INODE_CACHE(inode), vb->vb_bh, |
| 724 | if (status < 0) { | 724 | OCFS2_JOURNAL_ACCESS_WRITE); |
| 725 | mlog_errno(status); | 725 | if (status < 0) { |
| 726 | goto leave; | 726 | mlog_errno(status); |
| 727 | } | 727 | break; |
| 728 | } | ||
| 728 | 729 | ||
| 729 | prev_clusters = le32_to_cpu(vb->vb_xv->xr_clusters); | 730 | prev_clusters = le32_to_cpu(vb->vb_xv->xr_clusters); |
| 730 | status = ocfs2_add_clusters_in_btree(handle, | 731 | status = ocfs2_add_clusters_in_btree(handle, |
| 731 | &et, | 732 | &et, |
| 732 | &logical_start, | 733 | &logical_start, |
| 733 | clusters_to_add, | 734 | clusters_to_add, |
| 734 | 0, | 735 | 0, |
| 735 | ctxt->data_ac, | 736 | ctxt->data_ac, |
| 736 | ctxt->meta_ac, | 737 | ctxt->meta_ac, |
| 737 | &why); | 738 | &why); |
| 738 | if (status < 0) { | 739 | if ((status < 0) && (status != -EAGAIN)) { |
| 739 | mlog_errno(status); | 740 | if (status != -ENOSPC) |
| 740 | goto leave; | 741 | mlog_errno(status); |
| 741 | } | 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 | /* | 750 | if (why != RESTART_NONE && clusters_to_add) { |
| 748 | * We should have already allocated enough space before the transaction, | 751 | /* |
| 749 | * so no need to restart. | 752 | * We can only fail in case the alloc file doesn't give |
| 750 | */ | 753 | * up enough clusters. |
| 751 | BUG_ON(why != RESTART_NONE || clusters_to_add); | 754 | */ |
| 752 | 755 | BUG_ON(why == RESTART_META); | |
| 753 | leave: | 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 | return status; | 771 | return status; |
| 756 | } | 772 | } |
| @@ -6788,16 +6804,15 @@ out: | |||
| 6788 | return ret; | 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 | u64 blkno, u64 new_blkno, u32 clusters, | 6808 | u64 blkno, u64 new_blkno, u32 clusters, |
| 6809 | u32 *cpos, int num_buckets, | ||
| 6793 | struct ocfs2_alloc_context *meta_ac, | 6810 | struct ocfs2_alloc_context *meta_ac, |
| 6794 | struct ocfs2_alloc_context *data_ac, | 6811 | struct ocfs2_alloc_context *data_ac, |
| 6795 | struct ocfs2_reflink_xattr_tree_args *args) | 6812 | struct ocfs2_reflink_xattr_tree_args *args) |
| 6796 | { | 6813 | { |
| 6797 | int i, j, ret = 0; | 6814 | int i, j, ret = 0; |
| 6798 | struct super_block *sb = args->reflink->old_inode->i_sb; | 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 | int bpb = args->old_bucket->bu_blocks; | 6816 | int bpb = args->old_bucket->bu_blocks; |
| 6802 | struct ocfs2_xattr_value_buf vb = { | 6817 | struct ocfs2_xattr_value_buf vb = { |
| 6803 | .vb_access = ocfs2_journal_access, | 6818 | .vb_access = ocfs2_journal_access, |
| @@ -6816,14 +6831,6 @@ static int ocfs2_reflink_xattr_buckets(handle_t *handle, | |||
| 6816 | break; | 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 | ret = ocfs2_xattr_bucket_journal_access(handle, | 6834 | ret = ocfs2_xattr_bucket_journal_access(handle, |
| 6828 | args->new_bucket, | 6835 | args->new_bucket, |
| 6829 | OCFS2_JOURNAL_ACCESS_CREATE); | 6836 | OCFS2_JOURNAL_ACCESS_CREATE); |
| @@ -6837,6 +6844,18 @@ static int ocfs2_reflink_xattr_buckets(handle_t *handle, | |||
| 6837 | bucket_block(args->old_bucket, j), | 6844 | bucket_block(args->old_bucket, j), |
| 6838 | sb->s_blocksize); | 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 | ocfs2_xattr_bucket_journal_dirty(handle, args->new_bucket); | 6859 | ocfs2_xattr_bucket_journal_dirty(handle, args->new_bucket); |
| 6841 | 6860 | ||
| 6842 | ret = ocfs2_reflink_xattr_header(handle, args->reflink, | 6861 | ret = ocfs2_reflink_xattr_header(handle, args->reflink, |
| @@ -6866,6 +6885,7 @@ static int ocfs2_reflink_xattr_buckets(handle_t *handle, | |||
| 6866 | } | 6885 | } |
| 6867 | 6886 | ||
| 6868 | ocfs2_xattr_bucket_journal_dirty(handle, args->new_bucket); | 6887 | ocfs2_xattr_bucket_journal_dirty(handle, args->new_bucket); |
| 6888 | |||
| 6869 | ocfs2_xattr_bucket_relse(args->old_bucket); | 6889 | ocfs2_xattr_bucket_relse(args->old_bucket); |
| 6870 | ocfs2_xattr_bucket_relse(args->new_bucket); | 6890 | ocfs2_xattr_bucket_relse(args->new_bucket); |
| 6871 | } | 6891 | } |
| @@ -6874,6 +6894,75 @@ static int ocfs2_reflink_xattr_buckets(handle_t *handle, | |||
| 6874 | ocfs2_xattr_bucket_relse(args->new_bucket); | 6894 | ocfs2_xattr_bucket_relse(args->new_bucket); |
| 6875 | return ret; | 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 | * Create the same xattr extent record in the new inode's xattr tree. | 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, | |||
| 6885 | void *para) | 6974 | void *para) |
| 6886 | { | 6975 | { |
| 6887 | int ret, credits = 0; | 6976 | int ret, credits = 0; |
| 6888 | u32 p_cluster, num_clusters; | ||
| 6889 | u64 new_blkno; | ||
| 6890 | handle_t *handle; | 6977 | handle_t *handle; |
| 6891 | struct ocfs2_reflink_xattr_tree_args *args = | 6978 | struct ocfs2_reflink_xattr_tree_args *args = |
| 6892 | (struct ocfs2_reflink_xattr_tree_args *)para; | 6979 | (struct ocfs2_reflink_xattr_tree_args *)para; |
| @@ -6895,6 +6982,9 @@ static int ocfs2_reflink_xattr_rec(struct inode *inode, | |||
| 6895 | struct ocfs2_alloc_context *data_ac = NULL; | 6982 | struct ocfs2_alloc_context *data_ac = NULL; |
| 6896 | struct ocfs2_extent_tree et; | 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 | ocfs2_init_xattr_tree_extent_tree(&et, | 6988 | ocfs2_init_xattr_tree_extent_tree(&et, |
| 6899 | INODE_CACHE(args->reflink->new_inode), | 6989 | INODE_CACHE(args->reflink->new_inode), |
| 6900 | args->new_blk_bh); | 6990 | args->new_blk_bh); |
| @@ -6914,32 +7004,12 @@ static int ocfs2_reflink_xattr_rec(struct inode *inode, | |||
| 6914 | goto out; | 7004 | goto out; |
| 6915 | } | 7005 | } |
| 6916 | 7006 | ||
| 6917 | ret = ocfs2_claim_clusters(handle, data_ac, | 7007 | ret = ocfs2_reflink_xattr_buckets(handle, inode, args, &et, |
| 6918 | len, &p_cluster, &num_clusters); | 7008 | meta_ac, data_ac, |
| 6919 | if (ret) { | 7009 | blkno, cpos, len); |
| 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); | ||
| 6939 | if (ret) | 7010 | if (ret) |
| 6940 | mlog_errno(ret); | 7011 | mlog_errno(ret); |
| 6941 | 7012 | ||
| 6942 | out_commit: | ||
| 6943 | ocfs2_commit_trans(osb, handle); | 7013 | ocfs2_commit_trans(osb, handle); |
| 6944 | 7014 | ||
| 6945 | out: | 7015 | out: |
diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h index a4d2e9f7088a..adf832dec3f3 100644 --- a/include/linux/jbd2.h +++ b/include/linux/jbd2.h | |||
| @@ -1026,11 +1026,12 @@ void __jbd2_journal_insert_checkpoint(struct journal_head *, transaction_t *); | |||
| 1026 | 1026 | ||
| 1027 | struct jbd2_buffer_trigger_type { | 1027 | struct jbd2_buffer_trigger_type { |
| 1028 | /* | 1028 | /* |
| 1029 | * Fired just before a buffer is written to the journal. | 1029 | * Fired a the moment data to write to the journal are known to be |
| 1030 | * mapped_data is a mapped buffer that is the frozen data for | 1030 | * stable - so either at the moment b_frozen_data is created or just |
| 1031 | * commit. | 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 | struct buffer_head *bh, void *mapped_data, | 1035 | struct buffer_head *bh, void *mapped_data, |
| 1035 | size_t size); | 1036 | size_t size); |
| 1036 | 1037 | ||
| @@ -1042,7 +1043,7 @@ struct jbd2_buffer_trigger_type { | |||
| 1042 | struct buffer_head *bh); | 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 | void *mapped_data, | 1047 | void *mapped_data, |
| 1047 | struct jbd2_buffer_trigger_type *triggers); | 1048 | struct jbd2_buffer_trigger_type *triggers); |
| 1048 | extern void jbd2_buffer_abort_trigger(struct journal_head *jh, | 1049 | extern void jbd2_buffer_abort_trigger(struct journal_head *jh, |
