diff options
-rw-r--r-- | fs/ocfs2/refcounttree.c | 58 | ||||
-rw-r--r-- | fs/ocfs2/refcounttree.h | 11 |
2 files changed, 40 insertions, 29 deletions
diff --git a/fs/ocfs2/refcounttree.c b/fs/ocfs2/refcounttree.c index 3c7606cff1ab..ebfd3825f12a 100644 --- a/fs/ocfs2/refcounttree.c +++ b/fs/ocfs2/refcounttree.c | |||
@@ -66,7 +66,7 @@ struct ocfs2_cow_context { | |||
66 | u32 *num_clusters, | 66 | u32 *num_clusters, |
67 | unsigned int *extent_flags); | 67 | unsigned int *extent_flags); |
68 | int (*cow_duplicate_clusters)(handle_t *handle, | 68 | int (*cow_duplicate_clusters)(handle_t *handle, |
69 | struct ocfs2_cow_context *context, | 69 | struct file *file, |
70 | u32 cpos, u32 old_cluster, | 70 | u32 cpos, u32 old_cluster, |
71 | u32 new_cluster, u32 new_len); | 71 | u32 new_cluster, u32 new_len); |
72 | }; | 72 | }; |
@@ -2921,20 +2921,21 @@ static int ocfs2_clear_cow_buffer(handle_t *handle, struct buffer_head *bh) | |||
2921 | return 0; | 2921 | return 0; |
2922 | } | 2922 | } |
2923 | 2923 | ||
2924 | static int ocfs2_duplicate_clusters_by_page(handle_t *handle, | 2924 | int ocfs2_duplicate_clusters_by_page(handle_t *handle, |
2925 | struct ocfs2_cow_context *context, | 2925 | struct file *file, |
2926 | u32 cpos, u32 old_cluster, | 2926 | u32 cpos, u32 old_cluster, |
2927 | u32 new_cluster, u32 new_len) | 2927 | u32 new_cluster, u32 new_len) |
2928 | { | 2928 | { |
2929 | int ret = 0, partial; | 2929 | int ret = 0, partial; |
2930 | struct ocfs2_caching_info *ci = context->data_et.et_ci; | 2930 | struct inode *inode = file->f_path.dentry->d_inode; |
2931 | struct ocfs2_caching_info *ci = INODE_CACHE(inode); | ||
2931 | struct super_block *sb = ocfs2_metadata_cache_get_super(ci); | 2932 | struct super_block *sb = ocfs2_metadata_cache_get_super(ci); |
2932 | u64 new_block = ocfs2_clusters_to_blocks(sb, new_cluster); | 2933 | u64 new_block = ocfs2_clusters_to_blocks(sb, new_cluster); |
2933 | struct page *page; | 2934 | struct page *page; |
2934 | pgoff_t page_index; | 2935 | pgoff_t page_index; |
2935 | unsigned int from, to, readahead_pages; | 2936 | unsigned int from, to, readahead_pages; |
2936 | loff_t offset, end, map_end; | 2937 | loff_t offset, end, map_end; |
2937 | struct address_space *mapping = context->inode->i_mapping; | 2938 | struct address_space *mapping = inode->i_mapping; |
2938 | 2939 | ||
2939 | trace_ocfs2_duplicate_clusters_by_page(cpos, old_cluster, | 2940 | trace_ocfs2_duplicate_clusters_by_page(cpos, old_cluster, |
2940 | new_cluster, new_len); | 2941 | new_cluster, new_len); |
@@ -2948,8 +2949,8 @@ static int ocfs2_duplicate_clusters_by_page(handle_t *handle, | |||
2948 | * We only duplicate pages until we reach the page contains i_size - 1. | 2949 | * We only duplicate pages until we reach the page contains i_size - 1. |
2949 | * So trim 'end' to i_size. | 2950 | * So trim 'end' to i_size. |
2950 | */ | 2951 | */ |
2951 | if (end > i_size_read(context->inode)) | 2952 | if (end > i_size_read(inode)) |
2952 | end = i_size_read(context->inode); | 2953 | end = i_size_read(inode); |
2953 | 2954 | ||
2954 | while (offset < end) { | 2955 | while (offset < end) { |
2955 | page_index = offset >> PAGE_CACHE_SHIFT; | 2956 | page_index = offset >> PAGE_CACHE_SHIFT; |
@@ -2972,10 +2973,9 @@ static int ocfs2_duplicate_clusters_by_page(handle_t *handle, | |||
2972 | if (PAGE_CACHE_SIZE <= OCFS2_SB(sb)->s_clustersize) | 2973 | if (PAGE_CACHE_SIZE <= OCFS2_SB(sb)->s_clustersize) |
2973 | BUG_ON(PageDirty(page)); | 2974 | BUG_ON(PageDirty(page)); |
2974 | 2975 | ||
2975 | if (PageReadahead(page) && context->file) { | 2976 | if (PageReadahead(page)) { |
2976 | page_cache_async_readahead(mapping, | 2977 | page_cache_async_readahead(mapping, |
2977 | &context->file->f_ra, | 2978 | &file->f_ra, file, |
2978 | context->file, | ||
2979 | page, page_index, | 2979 | page, page_index, |
2980 | readahead_pages); | 2980 | readahead_pages); |
2981 | } | 2981 | } |
@@ -2999,8 +2999,7 @@ static int ocfs2_duplicate_clusters_by_page(handle_t *handle, | |||
2999 | } | 2999 | } |
3000 | } | 3000 | } |
3001 | 3001 | ||
3002 | ocfs2_map_and_dirty_page(context->inode, | 3002 | ocfs2_map_and_dirty_page(inode, handle, from, to, |
3003 | handle, from, to, | ||
3004 | page, 0, &new_block); | 3003 | page, 0, &new_block); |
3005 | mark_page_accessed(page); | 3004 | mark_page_accessed(page); |
3006 | unlock: | 3005 | unlock: |
@@ -3015,14 +3014,15 @@ unlock: | |||
3015 | return ret; | 3014 | return ret; |
3016 | } | 3015 | } |
3017 | 3016 | ||
3018 | static int ocfs2_duplicate_clusters_by_jbd(handle_t *handle, | 3017 | int ocfs2_duplicate_clusters_by_jbd(handle_t *handle, |
3019 | struct ocfs2_cow_context *context, | 3018 | struct file *file, |
3020 | u32 cpos, u32 old_cluster, | 3019 | u32 cpos, u32 old_cluster, |
3021 | u32 new_cluster, u32 new_len) | 3020 | u32 new_cluster, u32 new_len) |
3022 | { | 3021 | { |
3023 | int ret = 0; | 3022 | int ret = 0; |
3024 | struct super_block *sb = context->inode->i_sb; | 3023 | struct inode *inode = file->f_path.dentry->d_inode; |
3025 | struct ocfs2_caching_info *ci = context->data_et.et_ci; | 3024 | struct super_block *sb = inode->i_sb; |
3025 | struct ocfs2_caching_info *ci = INODE_CACHE(inode); | ||
3026 | int i, blocks = ocfs2_clusters_to_blocks(sb, new_len); | 3026 | int i, blocks = ocfs2_clusters_to_blocks(sb, new_len); |
3027 | u64 old_block = ocfs2_clusters_to_blocks(sb, old_cluster); | 3027 | u64 old_block = ocfs2_clusters_to_blocks(sb, old_cluster); |
3028 | u64 new_block = ocfs2_clusters_to_blocks(sb, new_cluster); | 3028 | u64 new_block = ocfs2_clusters_to_blocks(sb, new_cluster); |
@@ -3145,8 +3145,8 @@ static int ocfs2_replace_clusters(handle_t *handle, | |||
3145 | 3145 | ||
3146 | /*If the old clusters is unwritten, no need to duplicate. */ | 3146 | /*If the old clusters is unwritten, no need to duplicate. */ |
3147 | if (!(ext_flags & OCFS2_EXT_UNWRITTEN)) { | 3147 | if (!(ext_flags & OCFS2_EXT_UNWRITTEN)) { |
3148 | ret = context->cow_duplicate_clusters(handle, context, cpos, | 3148 | ret = context->cow_duplicate_clusters(handle, context->file, |
3149 | old, new, len); | 3149 | cpos, old, new, len); |
3150 | if (ret) { | 3150 | if (ret) { |
3151 | mlog_errno(ret); | 3151 | mlog_errno(ret); |
3152 | goto out; | 3152 | goto out; |
@@ -3162,22 +3162,22 @@ out: | |||
3162 | return ret; | 3162 | return ret; |
3163 | } | 3163 | } |
3164 | 3164 | ||
3165 | static int ocfs2_cow_sync_writeback(struct super_block *sb, | 3165 | int ocfs2_cow_sync_writeback(struct super_block *sb, |
3166 | struct ocfs2_cow_context *context, | 3166 | struct inode *inode, |
3167 | u32 cpos, u32 num_clusters) | 3167 | u32 cpos, u32 num_clusters) |
3168 | { | 3168 | { |
3169 | int ret = 0; | 3169 | int ret = 0; |
3170 | loff_t offset, end, map_end; | 3170 | loff_t offset, end, map_end; |
3171 | pgoff_t page_index; | 3171 | pgoff_t page_index; |
3172 | struct page *page; | 3172 | struct page *page; |
3173 | 3173 | ||
3174 | if (ocfs2_should_order_data(context->inode)) | 3174 | if (ocfs2_should_order_data(inode)) |
3175 | return 0; | 3175 | return 0; |
3176 | 3176 | ||
3177 | offset = ((loff_t)cpos) << OCFS2_SB(sb)->s_clustersize_bits; | 3177 | offset = ((loff_t)cpos) << OCFS2_SB(sb)->s_clustersize_bits; |
3178 | end = offset + (num_clusters << OCFS2_SB(sb)->s_clustersize_bits); | 3178 | end = offset + (num_clusters << OCFS2_SB(sb)->s_clustersize_bits); |
3179 | 3179 | ||
3180 | ret = filemap_fdatawrite_range(context->inode->i_mapping, | 3180 | ret = filemap_fdatawrite_range(inode->i_mapping, |
3181 | offset, end - 1); | 3181 | offset, end - 1); |
3182 | if (ret < 0) { | 3182 | if (ret < 0) { |
3183 | mlog_errno(ret); | 3183 | mlog_errno(ret); |
@@ -3190,7 +3190,7 @@ static int ocfs2_cow_sync_writeback(struct super_block *sb, | |||
3190 | if (map_end > end) | 3190 | if (map_end > end) |
3191 | map_end = end; | 3191 | map_end = end; |
3192 | 3192 | ||
3193 | page = find_or_create_page(context->inode->i_mapping, | 3193 | page = find_or_create_page(inode->i_mapping, |
3194 | page_index, GFP_NOFS); | 3194 | page_index, GFP_NOFS); |
3195 | BUG_ON(!page); | 3195 | BUG_ON(!page); |
3196 | 3196 | ||
@@ -3349,7 +3349,7 @@ static int ocfs2_make_clusters_writable(struct super_block *sb, | |||
3349 | * in write-back mode. | 3349 | * in write-back mode. |
3350 | */ | 3350 | */ |
3351 | if (context->get_clusters == ocfs2_di_get_clusters) { | 3351 | if (context->get_clusters == ocfs2_di_get_clusters) { |
3352 | ret = ocfs2_cow_sync_writeback(sb, context, cpos, | 3352 | ret = ocfs2_cow_sync_writeback(sb, context->inode, cpos, |
3353 | orig_num_clusters); | 3353 | orig_num_clusters); |
3354 | if (ret) | 3354 | if (ret) |
3355 | mlog_errno(ret); | 3355 | mlog_errno(ret); |
diff --git a/fs/ocfs2/refcounttree.h b/fs/ocfs2/refcounttree.h index c8ce46f7d8e3..7754608c83a4 100644 --- a/fs/ocfs2/refcounttree.h +++ b/fs/ocfs2/refcounttree.h | |||
@@ -84,6 +84,17 @@ int ocfs2_refcount_cow_xattr(struct inode *inode, | |||
84 | struct buffer_head *ref_root_bh, | 84 | struct buffer_head *ref_root_bh, |
85 | u32 cpos, u32 write_len, | 85 | u32 cpos, u32 write_len, |
86 | struct ocfs2_post_refcount *post); | 86 | struct ocfs2_post_refcount *post); |
87 | int ocfs2_duplicate_clusters_by_page(handle_t *handle, | ||
88 | struct file *file, | ||
89 | u32 cpos, u32 old_cluster, | ||
90 | u32 new_cluster, u32 new_len); | ||
91 | int ocfs2_duplicate_clusters_by_jbd(handle_t *handle, | ||
92 | struct file *file, | ||
93 | u32 cpos, u32 old_cluster, | ||
94 | u32 new_cluster, u32 new_len); | ||
95 | int ocfs2_cow_sync_writeback(struct super_block *sb, | ||
96 | struct inode *inode, | ||
97 | u32 cpos, u32 num_clusters); | ||
87 | int ocfs2_add_refcount_flag(struct inode *inode, | 98 | int ocfs2_add_refcount_flag(struct inode *inode, |
88 | struct ocfs2_extent_tree *data_et, | 99 | struct ocfs2_extent_tree *data_et, |
89 | struct ocfs2_caching_info *ref_ci, | 100 | struct ocfs2_caching_info *ref_ci, |