diff options
Diffstat (limited to 'fs/ocfs2/alloc.c')
| -rw-r--r-- | fs/ocfs2/alloc.c | 482 |
1 files changed, 346 insertions, 136 deletions
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c index 778a850b4634..4ba7f0bdc248 100644 --- a/fs/ocfs2/alloc.c +++ b/fs/ocfs2/alloc.c | |||
| @@ -354,7 +354,6 @@ struct ocfs2_insert_type { | |||
| 354 | enum ocfs2_append_type ins_appending; | 354 | enum ocfs2_append_type ins_appending; |
| 355 | enum ocfs2_contig_type ins_contig; | 355 | enum ocfs2_contig_type ins_contig; |
| 356 | int ins_contig_index; | 356 | int ins_contig_index; |
| 357 | int ins_free_records; | ||
| 358 | int ins_tree_depth; | 357 | int ins_tree_depth; |
| 359 | }; | 358 | }; |
| 360 | 359 | ||
| @@ -362,7 +361,6 @@ struct ocfs2_merge_ctxt { | |||
| 362 | enum ocfs2_contig_type c_contig_type; | 361 | enum ocfs2_contig_type c_contig_type; |
| 363 | int c_has_empty_extent; | 362 | int c_has_empty_extent; |
| 364 | int c_split_covers_rec; | 363 | int c_split_covers_rec; |
| 365 | int c_used_tail_recs; | ||
| 366 | }; | 364 | }; |
| 367 | 365 | ||
| 368 | /* | 366 | /* |
| @@ -2808,36 +2806,28 @@ static int ocfs2_try_to_merge_extent(struct inode *inode, | |||
| 2808 | struct ocfs2_merge_ctxt *ctxt) | 2806 | struct ocfs2_merge_ctxt *ctxt) |
| 2809 | 2807 | ||
| 2810 | { | 2808 | { |
| 2811 | int ret = 0, delete_tail_recs = 0; | 2809 | int ret = 0; |
| 2812 | struct ocfs2_extent_list *el = path_leaf_el(left_path); | 2810 | struct ocfs2_extent_list *el = path_leaf_el(left_path); |
| 2813 | struct ocfs2_extent_rec *rec = &el->l_recs[split_index]; | 2811 | struct ocfs2_extent_rec *rec = &el->l_recs[split_index]; |
| 2814 | 2812 | ||
| 2815 | BUG_ON(ctxt->c_contig_type == CONTIG_NONE); | 2813 | BUG_ON(ctxt->c_contig_type == CONTIG_NONE); |
| 2816 | 2814 | ||
| 2817 | if (ctxt->c_split_covers_rec) { | 2815 | if (ctxt->c_split_covers_rec && ctxt->c_has_empty_extent) { |
| 2818 | delete_tail_recs++; | 2816 | /* |
| 2819 | 2817 | * The merge code will need to create an empty | |
| 2820 | if (ctxt->c_contig_type == CONTIG_LEFTRIGHT || | 2818 | * extent to take the place of the newly |
| 2821 | ctxt->c_has_empty_extent) | 2819 | * emptied slot. Remove any pre-existing empty |
| 2822 | delete_tail_recs++; | 2820 | * extents - having more than one in a leaf is |
| 2823 | 2821 | * illegal. | |
| 2824 | if (ctxt->c_has_empty_extent) { | 2822 | */ |
| 2825 | /* | 2823 | ret = ocfs2_rotate_tree_left(inode, handle, left_path, |
| 2826 | * The merge code will need to create an empty | 2824 | dealloc); |
| 2827 | * extent to take the place of the newly | 2825 | if (ret) { |
| 2828 | * emptied slot. Remove any pre-existing empty | 2826 | mlog_errno(ret); |
| 2829 | * extents - having more than one in a leaf is | 2827 | goto out; |
| 2830 | * illegal. | ||
| 2831 | */ | ||
| 2832 | ret = ocfs2_rotate_tree_left(inode, handle, left_path, | ||
| 2833 | dealloc); | ||
| 2834 | if (ret) { | ||
| 2835 | mlog_errno(ret); | ||
| 2836 | goto out; | ||
| 2837 | } | ||
| 2838 | split_index--; | ||
| 2839 | rec = &el->l_recs[split_index]; | ||
| 2840 | } | 2828 | } |
| 2829 | split_index--; | ||
| 2830 | rec = &el->l_recs[split_index]; | ||
| 2841 | } | 2831 | } |
| 2842 | 2832 | ||
| 2843 | if (ctxt->c_contig_type == CONTIG_LEFTRIGHT) { | 2833 | if (ctxt->c_contig_type == CONTIG_LEFTRIGHT) { |
| @@ -3593,6 +3583,7 @@ static int ocfs2_figure_insert_type(struct inode *inode, | |||
| 3593 | struct buffer_head *di_bh, | 3583 | struct buffer_head *di_bh, |
| 3594 | struct buffer_head **last_eb_bh, | 3584 | struct buffer_head **last_eb_bh, |
| 3595 | struct ocfs2_extent_rec *insert_rec, | 3585 | struct ocfs2_extent_rec *insert_rec, |
| 3586 | int *free_records, | ||
| 3596 | struct ocfs2_insert_type *insert) | 3587 | struct ocfs2_insert_type *insert) |
| 3597 | { | 3588 | { |
| 3598 | int ret; | 3589 | int ret; |
| @@ -3633,7 +3624,7 @@ static int ocfs2_figure_insert_type(struct inode *inode, | |||
| 3633 | * XXX: This test is simplistic, we can search for empty | 3624 | * XXX: This test is simplistic, we can search for empty |
| 3634 | * extent records too. | 3625 | * extent records too. |
| 3635 | */ | 3626 | */ |
| 3636 | insert->ins_free_records = le16_to_cpu(el->l_count) - | 3627 | *free_records = le16_to_cpu(el->l_count) - |
| 3637 | le16_to_cpu(el->l_next_free_rec); | 3628 | le16_to_cpu(el->l_next_free_rec); |
| 3638 | 3629 | ||
| 3639 | if (!insert->ins_tree_depth) { | 3630 | if (!insert->ins_tree_depth) { |
| @@ -3730,10 +3721,13 @@ int ocfs2_insert_extent(struct ocfs2_super *osb, | |||
| 3730 | struct ocfs2_alloc_context *meta_ac) | 3721 | struct ocfs2_alloc_context *meta_ac) |
| 3731 | { | 3722 | { |
| 3732 | int status; | 3723 | int status; |
| 3724 | int uninitialized_var(free_records); | ||
| 3733 | struct buffer_head *last_eb_bh = NULL; | 3725 | struct buffer_head *last_eb_bh = NULL; |
| 3734 | struct ocfs2_insert_type insert = {0, }; | 3726 | struct ocfs2_insert_type insert = {0, }; |
| 3735 | struct ocfs2_extent_rec rec; | 3727 | struct ocfs2_extent_rec rec; |
| 3736 | 3728 | ||
| 3729 | BUG_ON(OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL); | ||
| 3730 | |||
| 3737 | mlog(0, "add %u clusters at position %u to inode %llu\n", | 3731 | mlog(0, "add %u clusters at position %u to inode %llu\n", |
| 3738 | new_clusters, cpos, (unsigned long long)OCFS2_I(inode)->ip_blkno); | 3732 | new_clusters, cpos, (unsigned long long)OCFS2_I(inode)->ip_blkno); |
| 3739 | 3733 | ||
| @@ -3752,7 +3746,7 @@ int ocfs2_insert_extent(struct ocfs2_super *osb, | |||
| 3752 | rec.e_flags = flags; | 3746 | rec.e_flags = flags; |
| 3753 | 3747 | ||
| 3754 | status = ocfs2_figure_insert_type(inode, fe_bh, &last_eb_bh, &rec, | 3748 | status = ocfs2_figure_insert_type(inode, fe_bh, &last_eb_bh, &rec, |
| 3755 | &insert); | 3749 | &free_records, &insert); |
| 3756 | if (status < 0) { | 3750 | if (status < 0) { |
| 3757 | mlog_errno(status); | 3751 | mlog_errno(status); |
| 3758 | goto bail; | 3752 | goto bail; |
| @@ -3762,9 +3756,9 @@ int ocfs2_insert_extent(struct ocfs2_super *osb, | |||
| 3762 | "Insert.contig_index: %d, Insert.free_records: %d, " | 3756 | "Insert.contig_index: %d, Insert.free_records: %d, " |
| 3763 | "Insert.tree_depth: %d\n", | 3757 | "Insert.tree_depth: %d\n", |
| 3764 | insert.ins_appending, insert.ins_contig, insert.ins_contig_index, | 3758 | insert.ins_appending, insert.ins_contig, insert.ins_contig_index, |
| 3765 | insert.ins_free_records, insert.ins_tree_depth); | 3759 | free_records, insert.ins_tree_depth); |
| 3766 | 3760 | ||
| 3767 | if (insert.ins_contig == CONTIG_NONE && insert.ins_free_records == 0) { | 3761 | if (insert.ins_contig == CONTIG_NONE && free_records == 0) { |
| 3768 | status = ocfs2_grow_tree(inode, handle, fe_bh, | 3762 | status = ocfs2_grow_tree(inode, handle, fe_bh, |
| 3769 | &insert.ins_tree_depth, &last_eb_bh, | 3763 | &insert.ins_tree_depth, &last_eb_bh, |
| 3770 | meta_ac); | 3764 | meta_ac); |
| @@ -3847,26 +3841,17 @@ leftright: | |||
| 3847 | 3841 | ||
| 3848 | if (le16_to_cpu(rightmost_el->l_next_free_rec) == | 3842 | if (le16_to_cpu(rightmost_el->l_next_free_rec) == |
| 3849 | le16_to_cpu(rightmost_el->l_count)) { | 3843 | le16_to_cpu(rightmost_el->l_count)) { |
| 3850 | int old_depth = depth; | ||
| 3851 | |||
| 3852 | ret = ocfs2_grow_tree(inode, handle, di_bh, &depth, last_eb_bh, | 3844 | ret = ocfs2_grow_tree(inode, handle, di_bh, &depth, last_eb_bh, |
| 3853 | meta_ac); | 3845 | meta_ac); |
| 3854 | if (ret) { | 3846 | if (ret) { |
| 3855 | mlog_errno(ret); | 3847 | mlog_errno(ret); |
| 3856 | goto out; | 3848 | goto out; |
| 3857 | } | 3849 | } |
| 3858 | |||
| 3859 | if (old_depth != depth) { | ||
| 3860 | eb = (struct ocfs2_extent_block *)(*last_eb_bh)->b_data; | ||
| 3861 | rightmost_el = &eb->h_list; | ||
| 3862 | } | ||
| 3863 | } | 3850 | } |
| 3864 | 3851 | ||
| 3865 | memset(&insert, 0, sizeof(struct ocfs2_insert_type)); | 3852 | memset(&insert, 0, sizeof(struct ocfs2_insert_type)); |
| 3866 | insert.ins_appending = APPEND_NONE; | 3853 | insert.ins_appending = APPEND_NONE; |
| 3867 | insert.ins_contig = CONTIG_NONE; | 3854 | insert.ins_contig = CONTIG_NONE; |
| 3868 | insert.ins_free_records = le16_to_cpu(rightmost_el->l_count) | ||
| 3869 | - le16_to_cpu(rightmost_el->l_next_free_rec); | ||
| 3870 | insert.ins_tree_depth = depth; | 3855 | insert.ins_tree_depth = depth; |
| 3871 | 3856 | ||
| 3872 | insert_range = le32_to_cpu(split_rec.e_cpos) + | 3857 | insert_range = le32_to_cpu(split_rec.e_cpos) + |
| @@ -4015,11 +4000,6 @@ static int __ocfs2_mark_extent_written(struct inode *inode, | |||
| 4015 | } else | 4000 | } else |
| 4016 | rightmost_el = path_root_el(path); | 4001 | rightmost_el = path_root_el(path); |
| 4017 | 4002 | ||
| 4018 | ctxt.c_used_tail_recs = le16_to_cpu(rightmost_el->l_next_free_rec); | ||
| 4019 | if (ctxt.c_used_tail_recs > 0 && | ||
| 4020 | ocfs2_is_empty_extent(&rightmost_el->l_recs[0])) | ||
| 4021 | ctxt.c_used_tail_recs--; | ||
| 4022 | |||
| 4023 | if (rec->e_cpos == split_rec->e_cpos && | 4003 | if (rec->e_cpos == split_rec->e_cpos && |
| 4024 | rec->e_leaf_clusters == split_rec->e_leaf_clusters) | 4004 | rec->e_leaf_clusters == split_rec->e_leaf_clusters) |
| 4025 | ctxt.c_split_covers_rec = 1; | 4005 | ctxt.c_split_covers_rec = 1; |
| @@ -4028,10 +4008,9 @@ static int __ocfs2_mark_extent_written(struct inode *inode, | |||
| 4028 | 4008 | ||
| 4029 | ctxt.c_has_empty_extent = ocfs2_is_empty_extent(&el->l_recs[0]); | 4009 | ctxt.c_has_empty_extent = ocfs2_is_empty_extent(&el->l_recs[0]); |
| 4030 | 4010 | ||
| 4031 | mlog(0, "index: %d, contig: %u, used_tail_recs: %u, " | 4011 | mlog(0, "index: %d, contig: %u, has_empty: %u, split_covers: %u\n", |
| 4032 | "has_empty: %u, split_covers: %u\n", split_index, | 4012 | split_index, ctxt.c_contig_type, ctxt.c_has_empty_extent, |
| 4033 | ctxt.c_contig_type, ctxt.c_used_tail_recs, | 4013 | ctxt.c_split_covers_rec); |
| 4034 | ctxt.c_has_empty_extent, ctxt.c_split_covers_rec); | ||
| 4035 | 4014 | ||
| 4036 | if (ctxt.c_contig_type == CONTIG_NONE) { | 4015 | if (ctxt.c_contig_type == CONTIG_NONE) { |
| 4037 | if (ctxt.c_split_covers_rec) | 4016 | if (ctxt.c_split_covers_rec) |
| @@ -4180,27 +4159,18 @@ static int ocfs2_split_tree(struct inode *inode, struct buffer_head *di_bh, | |||
| 4180 | 4159 | ||
| 4181 | if (le16_to_cpu(rightmost_el->l_next_free_rec) == | 4160 | if (le16_to_cpu(rightmost_el->l_next_free_rec) == |
| 4182 | le16_to_cpu(rightmost_el->l_count)) { | 4161 | le16_to_cpu(rightmost_el->l_count)) { |
| 4183 | int old_depth = depth; | ||
| 4184 | |||
| 4185 | ret = ocfs2_grow_tree(inode, handle, di_bh, &depth, &last_eb_bh, | 4162 | ret = ocfs2_grow_tree(inode, handle, di_bh, &depth, &last_eb_bh, |
| 4186 | meta_ac); | 4163 | meta_ac); |
| 4187 | if (ret) { | 4164 | if (ret) { |
| 4188 | mlog_errno(ret); | 4165 | mlog_errno(ret); |
| 4189 | goto out; | 4166 | goto out; |
| 4190 | } | 4167 | } |
| 4191 | |||
| 4192 | if (old_depth != depth) { | ||
| 4193 | eb = (struct ocfs2_extent_block *)last_eb_bh->b_data; | ||
| 4194 | rightmost_el = &eb->h_list; | ||
| 4195 | } | ||
| 4196 | } | 4168 | } |
| 4197 | 4169 | ||
| 4198 | memset(&insert, 0, sizeof(struct ocfs2_insert_type)); | 4170 | memset(&insert, 0, sizeof(struct ocfs2_insert_type)); |
| 4199 | insert.ins_appending = APPEND_NONE; | 4171 | insert.ins_appending = APPEND_NONE; |
| 4200 | insert.ins_contig = CONTIG_NONE; | 4172 | insert.ins_contig = CONTIG_NONE; |
| 4201 | insert.ins_split = SPLIT_RIGHT; | 4173 | insert.ins_split = SPLIT_RIGHT; |
| 4202 | insert.ins_free_records = le16_to_cpu(rightmost_el->l_count) | ||
| 4203 | - le16_to_cpu(rightmost_el->l_next_free_rec); | ||
| 4204 | insert.ins_tree_depth = depth; | 4174 | insert.ins_tree_depth = depth; |
| 4205 | 4175 | ||
| 4206 | ret = ocfs2_do_insert_extent(inode, handle, di_bh, &split_rec, &insert); | 4176 | ret = ocfs2_do_insert_extent(inode, handle, di_bh, &split_rec, &insert); |
| @@ -5665,12 +5635,50 @@ static int ocfs2_ordered_zero_func(handle_t *handle, struct buffer_head *bh) | |||
| 5665 | return ocfs2_journal_dirty_data(handle, bh); | 5635 | return ocfs2_journal_dirty_data(handle, bh); |
| 5666 | } | 5636 | } |
| 5667 | 5637 | ||
| 5638 | static void ocfs2_map_and_dirty_page(struct inode *inode, handle_t *handle, | ||
| 5639 | unsigned int from, unsigned int to, | ||
| 5640 | struct page *page, int zero, u64 *phys) | ||
| 5641 | { | ||
| 5642 | int ret, partial = 0; | ||
| 5643 | |||
| 5644 | ret = ocfs2_map_page_blocks(page, phys, inode, from, to, 0); | ||
| 5645 | if (ret) | ||
| 5646 | mlog_errno(ret); | ||
| 5647 | |||
| 5648 | if (zero) | ||
| 5649 | zero_user_page(page, from, to - from, KM_USER0); | ||
| 5650 | |||
| 5651 | /* | ||
| 5652 | * Need to set the buffers we zero'd into uptodate | ||
| 5653 | * here if they aren't - ocfs2_map_page_blocks() | ||
| 5654 | * might've skipped some | ||
| 5655 | */ | ||
| 5656 | if (ocfs2_should_order_data(inode)) { | ||
| 5657 | ret = walk_page_buffers(handle, | ||
| 5658 | page_buffers(page), | ||
| 5659 | from, to, &partial, | ||
| 5660 | ocfs2_ordered_zero_func); | ||
| 5661 | if (ret < 0) | ||
| 5662 | mlog_errno(ret); | ||
| 5663 | } else { | ||
| 5664 | ret = walk_page_buffers(handle, page_buffers(page), | ||
| 5665 | from, to, &partial, | ||
| 5666 | ocfs2_writeback_zero_func); | ||
| 5667 | if (ret < 0) | ||
| 5668 | mlog_errno(ret); | ||
| 5669 | } | ||
| 5670 | |||
| 5671 | if (!partial) | ||
| 5672 | SetPageUptodate(page); | ||
| 5673 | |||
| 5674 | flush_dcache_page(page); | ||
| 5675 | } | ||
| 5676 | |||
| 5668 | static void ocfs2_zero_cluster_pages(struct inode *inode, loff_t start, | 5677 | static void ocfs2_zero_cluster_pages(struct inode *inode, loff_t start, |
| 5669 | loff_t end, struct page **pages, | 5678 | loff_t end, struct page **pages, |
| 5670 | int numpages, u64 phys, handle_t *handle) | 5679 | int numpages, u64 phys, handle_t *handle) |
| 5671 | { | 5680 | { |
| 5672 | int i, ret, partial = 0; | 5681 | int i; |
| 5673 | void *kaddr; | ||
| 5674 | struct page *page; | 5682 | struct page *page; |
| 5675 | unsigned int from, to = PAGE_CACHE_SIZE; | 5683 | unsigned int from, to = PAGE_CACHE_SIZE; |
| 5676 | struct super_block *sb = inode->i_sb; | 5684 | struct super_block *sb = inode->i_sb; |
| @@ -5691,87 +5699,31 @@ static void ocfs2_zero_cluster_pages(struct inode *inode, loff_t start, | |||
| 5691 | BUG_ON(from > PAGE_CACHE_SIZE); | 5699 | BUG_ON(from > PAGE_CACHE_SIZE); |
| 5692 | BUG_ON(to > PAGE_CACHE_SIZE); | 5700 | BUG_ON(to > PAGE_CACHE_SIZE); |
| 5693 | 5701 | ||
| 5694 | ret = ocfs2_map_page_blocks(page, &phys, inode, from, to, 0); | 5702 | ocfs2_map_and_dirty_page(inode, handle, from, to, page, 1, |
| 5695 | if (ret) | 5703 | &phys); |
| 5696 | mlog_errno(ret); | ||
| 5697 | |||
| 5698 | kaddr = kmap_atomic(page, KM_USER0); | ||
| 5699 | memset(kaddr + from, 0, to - from); | ||
| 5700 | kunmap_atomic(kaddr, KM_USER0); | ||
| 5701 | |||
| 5702 | /* | ||
| 5703 | * Need to set the buffers we zero'd into uptodate | ||
| 5704 | * here if they aren't - ocfs2_map_page_blocks() | ||
| 5705 | * might've skipped some | ||
| 5706 | */ | ||
| 5707 | if (ocfs2_should_order_data(inode)) { | ||
| 5708 | ret = walk_page_buffers(handle, | ||
| 5709 | page_buffers(page), | ||
| 5710 | from, to, &partial, | ||
| 5711 | ocfs2_ordered_zero_func); | ||
| 5712 | if (ret < 0) | ||
| 5713 | mlog_errno(ret); | ||
| 5714 | } else { | ||
| 5715 | ret = walk_page_buffers(handle, page_buffers(page), | ||
| 5716 | from, to, &partial, | ||
| 5717 | ocfs2_writeback_zero_func); | ||
| 5718 | if (ret < 0) | ||
| 5719 | mlog_errno(ret); | ||
| 5720 | } | ||
| 5721 | |||
| 5722 | if (!partial) | ||
| 5723 | SetPageUptodate(page); | ||
| 5724 | |||
| 5725 | flush_dcache_page(page); | ||
| 5726 | 5704 | ||
| 5727 | start = (page->index + 1) << PAGE_CACHE_SHIFT; | 5705 | start = (page->index + 1) << PAGE_CACHE_SHIFT; |
| 5728 | } | 5706 | } |
| 5729 | out: | 5707 | out: |
| 5730 | if (pages) { | 5708 | if (pages) |
| 5731 | for (i = 0; i < numpages; i++) { | 5709 | ocfs2_unlock_and_free_pages(pages, numpages); |
| 5732 | page = pages[i]; | ||
| 5733 | unlock_page(page); | ||
| 5734 | mark_page_accessed(page); | ||
| 5735 | page_cache_release(page); | ||
| 5736 | } | ||
| 5737 | } | ||
| 5738 | } | 5710 | } |
| 5739 | 5711 | ||
| 5740 | static int ocfs2_grab_eof_pages(struct inode *inode, loff_t start, loff_t end, | 5712 | static int ocfs2_grab_eof_pages(struct inode *inode, loff_t start, loff_t end, |
| 5741 | struct page **pages, int *num, u64 *phys) | 5713 | struct page **pages, int *num) |
| 5742 | { | 5714 | { |
| 5743 | int i, numpages = 0, ret = 0; | 5715 | int numpages, ret = 0; |
| 5744 | unsigned int ext_flags; | ||
| 5745 | struct super_block *sb = inode->i_sb; | 5716 | struct super_block *sb = inode->i_sb; |
| 5746 | struct address_space *mapping = inode->i_mapping; | 5717 | struct address_space *mapping = inode->i_mapping; |
| 5747 | unsigned long index; | 5718 | unsigned long index; |
| 5748 | loff_t last_page_bytes; | 5719 | loff_t last_page_bytes; |
| 5749 | 5720 | ||
| 5750 | BUG_ON(!ocfs2_sparse_alloc(OCFS2_SB(sb))); | ||
| 5751 | BUG_ON(start > end); | 5721 | BUG_ON(start > end); |
| 5752 | 5722 | ||
| 5753 | if (start == end) | ||
| 5754 | goto out; | ||
| 5755 | |||
| 5756 | BUG_ON(start >> OCFS2_SB(sb)->s_clustersize_bits != | 5723 | BUG_ON(start >> OCFS2_SB(sb)->s_clustersize_bits != |
| 5757 | (end - 1) >> OCFS2_SB(sb)->s_clustersize_bits); | 5724 | (end - 1) >> OCFS2_SB(sb)->s_clustersize_bits); |
| 5758 | 5725 | ||
| 5759 | ret = ocfs2_extent_map_get_blocks(inode, start >> sb->s_blocksize_bits, | 5726 | numpages = 0; |
| 5760 | phys, NULL, &ext_flags); | ||
| 5761 | if (ret) { | ||
| 5762 | mlog_errno(ret); | ||
| 5763 | goto out; | ||
| 5764 | } | ||
| 5765 | |||
| 5766 | /* Tail is a hole. */ | ||
| 5767 | if (*phys == 0) | ||
| 5768 | goto out; | ||
| 5769 | |||
| 5770 | /* Tail is marked as unwritten, we can count on write to zero | ||
| 5771 | * in that case. */ | ||
| 5772 | if (ext_flags & OCFS2_EXT_UNWRITTEN) | ||
| 5773 | goto out; | ||
| 5774 | |||
| 5775 | last_page_bytes = PAGE_ALIGN(end); | 5727 | last_page_bytes = PAGE_ALIGN(end); |
| 5776 | index = start >> PAGE_CACHE_SHIFT; | 5728 | index = start >> PAGE_CACHE_SHIFT; |
| 5777 | do { | 5729 | do { |
| @@ -5788,14 +5740,8 @@ static int ocfs2_grab_eof_pages(struct inode *inode, loff_t start, loff_t end, | |||
| 5788 | 5740 | ||
| 5789 | out: | 5741 | out: |
| 5790 | if (ret != 0) { | 5742 | if (ret != 0) { |
| 5791 | if (pages) { | 5743 | if (pages) |
| 5792 | for (i = 0; i < numpages; i++) { | 5744 | ocfs2_unlock_and_free_pages(pages, numpages); |
| 5793 | if (pages[i]) { | ||
| 5794 | unlock_page(pages[i]); | ||
| 5795 | page_cache_release(pages[i]); | ||
| 5796 | } | ||
| 5797 | } | ||
| 5798 | } | ||
| 5799 | numpages = 0; | 5745 | numpages = 0; |
| 5800 | } | 5746 | } |
| 5801 | 5747 | ||
| @@ -5816,18 +5762,20 @@ out: | |||
| 5816 | int ocfs2_zero_range_for_truncate(struct inode *inode, handle_t *handle, | 5762 | int ocfs2_zero_range_for_truncate(struct inode *inode, handle_t *handle, |
| 5817 | u64 range_start, u64 range_end) | 5763 | u64 range_start, u64 range_end) |
| 5818 | { | 5764 | { |
| 5819 | int ret, numpages; | 5765 | int ret = 0, numpages; |
| 5820 | struct page **pages = NULL; | 5766 | struct page **pages = NULL; |
| 5821 | u64 phys; | 5767 | u64 phys; |
| 5768 | unsigned int ext_flags; | ||
| 5769 | struct super_block *sb = inode->i_sb; | ||
| 5822 | 5770 | ||
| 5823 | /* | 5771 | /* |
| 5824 | * File systems which don't support sparse files zero on every | 5772 | * File systems which don't support sparse files zero on every |
| 5825 | * extend. | 5773 | * extend. |
| 5826 | */ | 5774 | */ |
| 5827 | if (!ocfs2_sparse_alloc(OCFS2_SB(inode->i_sb))) | 5775 | if (!ocfs2_sparse_alloc(OCFS2_SB(sb))) |
| 5828 | return 0; | 5776 | return 0; |
| 5829 | 5777 | ||
| 5830 | pages = kcalloc(ocfs2_pages_per_cluster(inode->i_sb), | 5778 | pages = kcalloc(ocfs2_pages_per_cluster(sb), |
| 5831 | sizeof(struct page *), GFP_NOFS); | 5779 | sizeof(struct page *), GFP_NOFS); |
| 5832 | if (pages == NULL) { | 5780 | if (pages == NULL) { |
| 5833 | ret = -ENOMEM; | 5781 | ret = -ENOMEM; |
| @@ -5835,16 +5783,31 @@ int ocfs2_zero_range_for_truncate(struct inode *inode, handle_t *handle, | |||
| 5835 | goto out; | 5783 | goto out; |
| 5836 | } | 5784 | } |
| 5837 | 5785 | ||
| 5838 | ret = ocfs2_grab_eof_pages(inode, range_start, range_end, pages, | 5786 | if (range_start == range_end) |
| 5839 | &numpages, &phys); | 5787 | goto out; |
| 5788 | |||
| 5789 | ret = ocfs2_extent_map_get_blocks(inode, | ||
| 5790 | range_start >> sb->s_blocksize_bits, | ||
| 5791 | &phys, NULL, &ext_flags); | ||
| 5840 | if (ret) { | 5792 | if (ret) { |
| 5841 | mlog_errno(ret); | 5793 | mlog_errno(ret); |
| 5842 | goto out; | 5794 | goto out; |
| 5843 | } | 5795 | } |
| 5844 | 5796 | ||
| 5845 | if (numpages == 0) | 5797 | /* |
| 5798 | * Tail is a hole, or is marked unwritten. In either case, we | ||
| 5799 | * can count on read and write to return/push zero's. | ||
| 5800 | */ | ||
| 5801 | if (phys == 0 || ext_flags & OCFS2_EXT_UNWRITTEN) | ||
| 5846 | goto out; | 5802 | goto out; |
| 5847 | 5803 | ||
| 5804 | ret = ocfs2_grab_eof_pages(inode, range_start, range_end, pages, | ||
| 5805 | &numpages); | ||
| 5806 | if (ret) { | ||
| 5807 | mlog_errno(ret); | ||
| 5808 | goto out; | ||
| 5809 | } | ||
| 5810 | |||
| 5848 | ocfs2_zero_cluster_pages(inode, range_start, range_end, pages, | 5811 | ocfs2_zero_cluster_pages(inode, range_start, range_end, pages, |
| 5849 | numpages, phys, handle); | 5812 | numpages, phys, handle); |
| 5850 | 5813 | ||
| @@ -5865,6 +5828,178 @@ out: | |||
| 5865 | return ret; | 5828 | return ret; |
| 5866 | } | 5829 | } |
| 5867 | 5830 | ||
| 5831 | static void ocfs2_zero_dinode_id2(struct inode *inode, struct ocfs2_dinode *di) | ||
| 5832 | { | ||
| 5833 | unsigned int blocksize = 1 << inode->i_sb->s_blocksize_bits; | ||
| 5834 | |||
| 5835 | memset(&di->id2, 0, blocksize - offsetof(struct ocfs2_dinode, id2)); | ||
| 5836 | } | ||
| 5837 | |||
| 5838 | void ocfs2_dinode_new_extent_list(struct inode *inode, | ||
| 5839 | struct ocfs2_dinode *di) | ||
| 5840 | { | ||
| 5841 | ocfs2_zero_dinode_id2(inode, di); | ||
| 5842 | di->id2.i_list.l_tree_depth = 0; | ||
| 5843 | di->id2.i_list.l_next_free_rec = 0; | ||
| 5844 | di->id2.i_list.l_count = cpu_to_le16(ocfs2_extent_recs_per_inode(inode->i_sb)); | ||
| 5845 | } | ||
| 5846 | |||
| 5847 | void ocfs2_set_inode_data_inline(struct inode *inode, struct ocfs2_dinode *di) | ||
| 5848 | { | ||
| 5849 | struct ocfs2_inode_info *oi = OCFS2_I(inode); | ||
| 5850 | struct ocfs2_inline_data *idata = &di->id2.i_data; | ||
| 5851 | |||
| 5852 | spin_lock(&oi->ip_lock); | ||
| 5853 | oi->ip_dyn_features |= OCFS2_INLINE_DATA_FL; | ||
| 5854 | di->i_dyn_features = cpu_to_le16(oi->ip_dyn_features); | ||
| 5855 | spin_unlock(&oi->ip_lock); | ||
| 5856 | |||
| 5857 | /* | ||
| 5858 | * We clear the entire i_data structure here so that all | ||
| 5859 | * fields can be properly initialized. | ||
| 5860 | */ | ||
| 5861 | ocfs2_zero_dinode_id2(inode, di); | ||
| 5862 | |||
| 5863 | idata->id_count = cpu_to_le16(ocfs2_max_inline_data(inode->i_sb)); | ||
| 5864 | } | ||
| 5865 | |||
| 5866 | int ocfs2_convert_inline_data_to_extents(struct inode *inode, | ||
| 5867 | struct buffer_head *di_bh) | ||
| 5868 | { | ||
| 5869 | int ret, i, has_data, num_pages = 0; | ||
| 5870 | handle_t *handle; | ||
| 5871 | u64 uninitialized_var(block); | ||
| 5872 | struct ocfs2_inode_info *oi = OCFS2_I(inode); | ||
| 5873 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | ||
| 5874 | struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data; | ||
| 5875 | struct ocfs2_alloc_context *data_ac = NULL; | ||
| 5876 | struct page **pages = NULL; | ||
| 5877 | loff_t end = osb->s_clustersize; | ||
| 5878 | |||
| 5879 | has_data = i_size_read(inode) ? 1 : 0; | ||
| 5880 | |||
| 5881 | if (has_data) { | ||
| 5882 | pages = kcalloc(ocfs2_pages_per_cluster(osb->sb), | ||
| 5883 | sizeof(struct page *), GFP_NOFS); | ||
| 5884 | if (pages == NULL) { | ||
| 5885 | ret = -ENOMEM; | ||
| 5886 | mlog_errno(ret); | ||
| 5887 | goto out; | ||
| 5888 | } | ||
| 5889 | |||
| 5890 | ret = ocfs2_reserve_clusters(osb, 1, &data_ac); | ||
| 5891 | if (ret) { | ||
| 5892 | mlog_errno(ret); | ||
| 5893 | goto out; | ||
| 5894 | } | ||
| 5895 | } | ||
| 5896 | |||
| 5897 | handle = ocfs2_start_trans(osb, OCFS2_INLINE_TO_EXTENTS_CREDITS); | ||
| 5898 | if (IS_ERR(handle)) { | ||
| 5899 | ret = PTR_ERR(handle); | ||
| 5900 | mlog_errno(ret); | ||
| 5901 | goto out_unlock; | ||
| 5902 | } | ||
| 5903 | |||
| 5904 | ret = ocfs2_journal_access(handle, inode, di_bh, | ||
| 5905 | OCFS2_JOURNAL_ACCESS_WRITE); | ||
| 5906 | if (ret) { | ||
| 5907 | mlog_errno(ret); | ||
| 5908 | goto out_commit; | ||
| 5909 | } | ||
| 5910 | |||
| 5911 | if (has_data) { | ||
| 5912 | u32 bit_off, num; | ||
| 5913 | unsigned int page_end; | ||
| 5914 | u64 phys; | ||
| 5915 | |||
| 5916 | ret = ocfs2_claim_clusters(osb, handle, data_ac, 1, &bit_off, | ||
| 5917 | &num); | ||
| 5918 | if (ret) { | ||
| 5919 | mlog_errno(ret); | ||
| 5920 | goto out_commit; | ||
| 5921 | } | ||
| 5922 | |||
| 5923 | /* | ||
| 5924 | * Save two copies, one for insert, and one that can | ||
| 5925 | * be changed by ocfs2_map_and_dirty_page() below. | ||
| 5926 | */ | ||
| 5927 | block = phys = ocfs2_clusters_to_blocks(inode->i_sb, bit_off); | ||
| 5928 | |||
| 5929 | /* | ||
| 5930 | * Non sparse file systems zero on extend, so no need | ||
| 5931 | * to do that now. | ||
| 5932 | */ | ||
| 5933 | if (!ocfs2_sparse_alloc(osb) && | ||
| 5934 | PAGE_CACHE_SIZE < osb->s_clustersize) | ||
| 5935 | end = PAGE_CACHE_SIZE; | ||
| 5936 | |||
| 5937 | ret = ocfs2_grab_eof_pages(inode, 0, end, pages, &num_pages); | ||
| 5938 | if (ret) { | ||
| 5939 | mlog_errno(ret); | ||
| 5940 | goto out_commit; | ||
| 5941 | } | ||
| 5942 | |||
| 5943 | /* | ||
| 5944 | * This should populate the 1st page for us and mark | ||
| 5945 | * it up to date. | ||
| 5946 | */ | ||
| 5947 | ret = ocfs2_read_inline_data(inode, pages[0], di_bh); | ||
| 5948 | if (ret) { | ||
| 5949 | mlog_errno(ret); | ||
| 5950 | goto out_commit; | ||
| 5951 | } | ||
| 5952 | |||
| 5953 | page_end = PAGE_CACHE_SIZE; | ||
| 5954 | if (PAGE_CACHE_SIZE > osb->s_clustersize) | ||
| 5955 | page_end = osb->s_clustersize; | ||
| 5956 | |||
| 5957 | for (i = 0; i < num_pages; i++) | ||
| 5958 | ocfs2_map_and_dirty_page(inode, handle, 0, page_end, | ||
| 5959 | pages[i], i > 0, &phys); | ||
| 5960 | } | ||
| 5961 | |||
| 5962 | spin_lock(&oi->ip_lock); | ||
| 5963 | oi->ip_dyn_features &= ~OCFS2_INLINE_DATA_FL; | ||
| 5964 | di->i_dyn_features = cpu_to_le16(oi->ip_dyn_features); | ||
| 5965 | spin_unlock(&oi->ip_lock); | ||
| 5966 | |||
| 5967 | ocfs2_dinode_new_extent_list(inode, di); | ||
| 5968 | |||
| 5969 | ocfs2_journal_dirty(handle, di_bh); | ||
| 5970 | |||
| 5971 | if (has_data) { | ||
| 5972 | /* | ||
| 5973 | * An error at this point should be extremely rare. If | ||
| 5974 | * this proves to be false, we could always re-build | ||
| 5975 | * the in-inode data from our pages. | ||
| 5976 | */ | ||
| 5977 | ret = ocfs2_insert_extent(osb, handle, inode, di_bh, | ||
| 5978 | 0, block, 1, 0, NULL); | ||
| 5979 | if (ret) { | ||
| 5980 | mlog_errno(ret); | ||
| 5981 | goto out_commit; | ||
| 5982 | } | ||
| 5983 | |||
| 5984 | inode->i_blocks = ocfs2_inode_sector_count(inode); | ||
| 5985 | } | ||
| 5986 | |||
| 5987 | out_commit: | ||
| 5988 | ocfs2_commit_trans(osb, handle); | ||
| 5989 | |||
| 5990 | out_unlock: | ||
| 5991 | if (data_ac) | ||
| 5992 | ocfs2_free_alloc_context(data_ac); | ||
| 5993 | |||
| 5994 | out: | ||
| 5995 | if (pages) { | ||
| 5996 | ocfs2_unlock_and_free_pages(pages, num_pages); | ||
| 5997 | kfree(pages); | ||
| 5998 | } | ||
| 5999 | |||
| 6000 | return ret; | ||
| 6001 | } | ||
| 6002 | |||
| 5868 | /* | 6003 | /* |
| 5869 | * It is expected, that by the time you call this function, | 6004 | * It is expected, that by the time you call this function, |
| 5870 | * inode->i_size and fe->i_size have been adjusted. | 6005 | * inode->i_size and fe->i_size have been adjusted. |
| @@ -6090,6 +6225,81 @@ bail: | |||
| 6090 | return status; | 6225 | return status; |
| 6091 | } | 6226 | } |
| 6092 | 6227 | ||
| 6228 | /* | ||
| 6229 | * 'start' is inclusive, 'end' is not. | ||
| 6230 | */ | ||
| 6231 | int ocfs2_truncate_inline(struct inode *inode, struct buffer_head *di_bh, | ||
| 6232 | unsigned int start, unsigned int end, int trunc) | ||
| 6233 | { | ||
| 6234 | int ret; | ||
| 6235 | unsigned int numbytes; | ||
| 6236 | handle_t *handle; | ||
| 6237 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | ||
| 6238 | struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data; | ||
| 6239 | struct ocfs2_inline_data *idata = &di->id2.i_data; | ||
| 6240 | |||
| 6241 | if (end > i_size_read(inode)) | ||
| 6242 | end = i_size_read(inode); | ||
| 6243 | |||
| 6244 | BUG_ON(start >= end); | ||
| 6245 | |||
| 6246 | if (!(OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL) || | ||
| 6247 | !(le16_to_cpu(di->i_dyn_features) & OCFS2_INLINE_DATA_FL) || | ||
| 6248 | !ocfs2_supports_inline_data(osb)) { | ||
| 6249 | ocfs2_error(inode->i_sb, | ||
| 6250 | "Inline data flags for inode %llu don't agree! " | ||
| 6251 | "Disk: 0x%x, Memory: 0x%x, Superblock: 0x%x\n", | ||
| 6252 | (unsigned long long)OCFS2_I(inode)->ip_blkno, | ||
| 6253 | le16_to_cpu(di->i_dyn_features), | ||
| 6254 | OCFS2_I(inode)->ip_dyn_features, | ||
| 6255 | osb->s_feature_incompat); | ||
| 6256 | ret = -EROFS; | ||
| 6257 | goto out; | ||
| 6258 | } | ||
| 6259 | |||
| 6260 | handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS); | ||
| 6261 | if (IS_ERR(handle)) { | ||
| 6262 | ret = PTR_ERR(handle); | ||
| 6263 | mlog_errno(ret); | ||
| 6264 | goto out; | ||
| 6265 | } | ||
| 6266 | |||
| 6267 | ret = ocfs2_journal_access(handle, inode, di_bh, | ||
| 6268 | OCFS2_JOURNAL_ACCESS_WRITE); | ||
| 6269 | if (ret) { | ||
| 6270 | mlog_errno(ret); | ||
| 6271 | goto out_commit; | ||
| 6272 | } | ||
| 6273 | |||
| 6274 | numbytes = end - start; | ||
| 6275 | memset(idata->id_data + start, 0, numbytes); | ||
| 6276 | |||
| 6277 | /* | ||
| 6278 | * No need to worry about the data page here - it's been | ||
| 6279 | * truncated already and inline data doesn't need it for | ||
| 6280 | * pushing zero's to disk, so we'll let readpage pick it up | ||
| 6281 | * later. | ||
| 6282 | */ | ||
| 6283 | if (trunc) { | ||
| 6284 | i_size_write(inode, start); | ||
| 6285 | di->i_size = cpu_to_le64(start); | ||
| 6286 | } | ||
| 6287 | |||
| 6288 | inode->i_blocks = ocfs2_inode_sector_count(inode); | ||
| 6289 | inode->i_ctime = inode->i_mtime = CURRENT_TIME; | ||
| 6290 | |||
| 6291 | di->i_ctime = di->i_mtime = cpu_to_le64(inode->i_ctime.tv_sec); | ||
| 6292 | di->i_ctime_nsec = di->i_mtime_nsec = cpu_to_le32(inode->i_ctime.tv_nsec); | ||
| 6293 | |||
| 6294 | ocfs2_journal_dirty(handle, di_bh); | ||
| 6295 | |||
| 6296 | out_commit: | ||
| 6297 | ocfs2_commit_trans(osb, handle); | ||
| 6298 | |||
| 6299 | out: | ||
| 6300 | return ret; | ||
| 6301 | } | ||
| 6302 | |||
| 6093 | static void ocfs2_free_truncate_context(struct ocfs2_truncate_context *tc) | 6303 | static void ocfs2_free_truncate_context(struct ocfs2_truncate_context *tc) |
| 6094 | { | 6304 | { |
| 6095 | /* | 6305 | /* |
