diff options
| author | Tristan Ye <tristan.ye@oracle.com> | 2011-05-24 04:21:20 -0400 |
|---|---|---|
| committer | Tristan Ye <tristan.ye@oracle.com> | 2011-05-25 03:17:08 -0400 |
| commit | 3e19a25e0591a6248f3ddd2c08566666607d827d (patch) | |
| tree | cd01e54a18f4f91e1ae14fccdbc564ee7ce1b09b | |
| parent | d24a10b9f8ed548981696cd36e2b4f16e6f360b1 (diff) | |
Ocfs2/refcounttree: Publicize couple of funcs from refcounttree.c
The original goal of commonizing these funcs is to benefit defraging/extent_moving
codes in the future, based on the fact that reflink and defragmentation having
the same Copy-On-Wrtie mechanism.
Signed-off-by: Tristan Ye <tristan.ye@oracle.com>
| -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 3c7606cff1a..ebfd3825f12 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 c8ce46f7d8e..7754608c83a 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, |
