aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/refcounttree.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ocfs2/refcounttree.c')
-rw-r--r--fs/ocfs2/refcounttree.c127
1 files changed, 71 insertions, 56 deletions
diff --git a/fs/ocfs2/refcounttree.c b/fs/ocfs2/refcounttree.c
index 62d21c6ce1d9..40de7bb9e9a6 100644
--- a/fs/ocfs2/refcounttree.c
+++ b/fs/ocfs2/refcounttree.c
@@ -45,12 +45,20 @@ struct ocfs2_cow_context {
45 struct inode *inode; 45 struct inode *inode;
46 u32 cow_start; 46 u32 cow_start;
47 u32 cow_len; 47 u32 cow_len;
48 struct ocfs2_extent_tree di_et; 48 struct ocfs2_extent_tree data_et;
49 struct ocfs2_caching_info *ref_ci; 49 struct ocfs2_refcount_tree *ref_tree;
50 struct buffer_head *ref_root_bh; 50 struct buffer_head *ref_root_bh;
51 struct ocfs2_alloc_context *meta_ac; 51 struct ocfs2_alloc_context *meta_ac;
52 struct ocfs2_alloc_context *data_ac; 52 struct ocfs2_alloc_context *data_ac;
53 struct ocfs2_cached_dealloc_ctxt dealloc; 53 struct ocfs2_cached_dealloc_ctxt dealloc;
54 int (*get_clusters)(struct ocfs2_cow_context *context,
55 u32 v_cluster, u32 *p_cluster,
56 u32 *num_clusters,
57 unsigned int *extent_flags);
58 int (*cow_duplicate_clusters)(handle_t *handle,
59 struct ocfs2_cow_context *context,
60 u32 cpos, u32 old_cluster,
61 u32 new_cluster, u32 new_len);
54}; 62};
55 63
56static inline struct ocfs2_refcount_tree * 64static inline struct ocfs2_refcount_tree *
@@ -2489,7 +2497,7 @@ static inline unsigned int ocfs2_cow_align_length(struct super_block *sb,
2489 * get good I/O from the resulting extent tree. 2497 * get good I/O from the resulting extent tree.
2490 */ 2498 */
2491static int ocfs2_refcount_cal_cow_clusters(struct inode *inode, 2499static int ocfs2_refcount_cal_cow_clusters(struct inode *inode,
2492 struct buffer_head *di_bh, 2500 struct ocfs2_extent_list *el,
2493 u32 cpos, 2501 u32 cpos,
2494 u32 write_len, 2502 u32 write_len,
2495 u32 max_cpos, 2503 u32 max_cpos,
@@ -2497,8 +2505,6 @@ static int ocfs2_refcount_cal_cow_clusters(struct inode *inode,
2497 u32 *cow_len) 2505 u32 *cow_len)
2498{ 2506{
2499 int ret = 0; 2507 int ret = 0;
2500 struct ocfs2_dinode *di = (struct ocfs2_dinode *) di_bh->b_data;
2501 struct ocfs2_extent_list *el = &di->id2.i_list;
2502 int tree_height = le16_to_cpu(el->l_tree_depth), i; 2508 int tree_height = le16_to_cpu(el->l_tree_depth), i;
2503 struct buffer_head *eb_bh = NULL; 2509 struct buffer_head *eb_bh = NULL;
2504 struct ocfs2_extent_block *eb = NULL; 2510 struct ocfs2_extent_block *eb = NULL;
@@ -2769,13 +2775,13 @@ static int ocfs2_clear_cow_buffer(handle_t *handle, struct buffer_head *bh)
2769 return 0; 2775 return 0;
2770} 2776}
2771 2777
2772static int ocfs2_duplicate_clusters(handle_t *handle, 2778static int ocfs2_duplicate_clusters_by_page(handle_t *handle,
2773 struct ocfs2_cow_context *context, 2779 struct ocfs2_cow_context *context,
2774 u32 cpos, u32 old_cluster, 2780 u32 cpos, u32 old_cluster,
2775 u32 new_cluster, u32 new_len) 2781 u32 new_cluster, u32 new_len)
2776{ 2782{
2777 int ret = 0, partial; 2783 int ret = 0, partial;
2778 struct ocfs2_caching_info *ci = context->di_et.et_ci; 2784 struct ocfs2_caching_info *ci = context->data_et.et_ci;
2779 struct super_block *sb = ocfs2_metadata_cache_get_super(ci); 2785 struct super_block *sb = ocfs2_metadata_cache_get_super(ci);
2780 u64 new_block = ocfs2_clusters_to_blocks(sb, new_cluster); 2786 u64 new_block = ocfs2_clusters_to_blocks(sb, new_cluster);
2781 struct page *page; 2787 struct page *page;
@@ -2909,7 +2915,7 @@ static int ocfs2_replace_clusters(handle_t *handle,
2909 unsigned int ext_flags) 2915 unsigned int ext_flags)
2910{ 2916{
2911 int ret; 2917 int ret;
2912 struct ocfs2_caching_info *ci = context->di_et.et_ci; 2918 struct ocfs2_caching_info *ci = context->data_et.et_ci;
2913 u64 ino = ocfs2_metadata_cache_owner(ci); 2919 u64 ino = ocfs2_metadata_cache_owner(ci);
2914 2920
2915 mlog(0, "inode %llu, cpos %u, old %u, new %u, len %u, ext_flags %u\n", 2921 mlog(0, "inode %llu, cpos %u, old %u, new %u, len %u, ext_flags %u\n",
@@ -2917,15 +2923,15 @@ static int ocfs2_replace_clusters(handle_t *handle,
2917 2923
2918 /*If the old clusters is unwritten, no need to duplicate. */ 2924 /*If the old clusters is unwritten, no need to duplicate. */
2919 if (!(ext_flags & OCFS2_EXT_UNWRITTEN)) { 2925 if (!(ext_flags & OCFS2_EXT_UNWRITTEN)) {
2920 ret = ocfs2_duplicate_clusters(handle, context, cpos, 2926 ret = context->cow_duplicate_clusters(handle, context, cpos,
2921 old, new, len); 2927 old, new, len);
2922 if (ret) { 2928 if (ret) {
2923 mlog_errno(ret); 2929 mlog_errno(ret);
2924 goto out; 2930 goto out;
2925 } 2931 }
2926 } 2932 }
2927 2933
2928 ret = ocfs2_clear_ext_refcount(handle, &context->di_et, 2934 ret = ocfs2_clear_ext_refcount(handle, &context->data_et,
2929 cpos, new, len, ext_flags, 2935 cpos, new, len, ext_flags,
2930 context->meta_ac, &context->dealloc); 2936 context->meta_ac, &context->dealloc);
2931 if (ret) 2937 if (ret)
@@ -2983,6 +2989,15 @@ static int ocfs2_cow_sync_writeback(struct super_block *sb,
2983 return ret; 2989 return ret;
2984} 2990}
2985 2991
2992static int ocfs2_di_get_clusters(struct ocfs2_cow_context *context,
2993 u32 v_cluster, u32 *p_cluster,
2994 u32 *num_clusters,
2995 unsigned int *extent_flags)
2996{
2997 return ocfs2_get_clusters(context->inode, v_cluster, p_cluster,
2998 num_clusters, extent_flags);
2999}
3000
2986static int ocfs2_make_clusters_writable(struct super_block *sb, 3001static int ocfs2_make_clusters_writable(struct super_block *sb,
2987 struct ocfs2_cow_context *context, 3002 struct ocfs2_cow_context *context,
2988 u32 cpos, u32 p_cluster, 3003 u32 cpos, u32 p_cluster,
@@ -2994,14 +3009,15 @@ static int ocfs2_make_clusters_writable(struct super_block *sb,
2994 struct ocfs2_super *osb = OCFS2_SB(sb); 3009 struct ocfs2_super *osb = OCFS2_SB(sb);
2995 handle_t *handle; 3010 handle_t *handle;
2996 struct buffer_head *ref_leaf_bh = NULL; 3011 struct buffer_head *ref_leaf_bh = NULL;
3012 struct ocfs2_caching_info *ref_ci = &context->ref_tree->rf_ci;
2997 struct ocfs2_refcount_rec rec; 3013 struct ocfs2_refcount_rec rec;
2998 3014
2999 mlog(0, "cpos %u, p_cluster %u, num_clusters %u, e_flags %u\n", 3015 mlog(0, "cpos %u, p_cluster %u, num_clusters %u, e_flags %u\n",
3000 cpos, p_cluster, num_clusters, e_flags); 3016 cpos, p_cluster, num_clusters, e_flags);
3001 3017
3002 ret = ocfs2_lock_refcount_allocators(sb, p_cluster, num_clusters, 3018 ret = ocfs2_lock_refcount_allocators(sb, p_cluster, num_clusters,
3003 &context->di_et, 3019 &context->data_et,
3004 context->ref_ci, 3020 ref_ci,
3005 context->ref_root_bh, 3021 context->ref_root_bh,
3006 &context->meta_ac, 3022 &context->meta_ac,
3007 &context->data_ac, &credits); 3023 &context->data_ac, &credits);
@@ -3018,8 +3034,7 @@ static int ocfs2_make_clusters_writable(struct super_block *sb,
3018 } 3034 }
3019 3035
3020 while (num_clusters) { 3036 while (num_clusters) {
3021 ret = ocfs2_get_refcount_rec(context->ref_ci, 3037 ret = ocfs2_get_refcount_rec(ref_ci, context->ref_root_bh,
3022 context->ref_root_bh,
3023 p_cluster, num_clusters, 3038 p_cluster, num_clusters,
3024 &rec, &index, &ref_leaf_bh); 3039 &rec, &index, &ref_leaf_bh);
3025 if (ret) { 3040 if (ret) {
@@ -3041,7 +3056,8 @@ static int ocfs2_make_clusters_writable(struct super_block *sb,
3041 */ 3056 */
3042 if (le32_to_cpu(rec.r_refcount) == 1) { 3057 if (le32_to_cpu(rec.r_refcount) == 1) {
3043 delete = 0; 3058 delete = 0;
3044 ret = ocfs2_clear_ext_refcount(handle, &context->di_et, 3059 ret = ocfs2_clear_ext_refcount(handle,
3060 &context->data_et,
3045 cpos, p_cluster, 3061 cpos, p_cluster,
3046 set_len, e_flags, 3062 set_len, e_flags,
3047 context->meta_ac, 3063 context->meta_ac,
@@ -3072,7 +3088,7 @@ static int ocfs2_make_clusters_writable(struct super_block *sb,
3072 set_len = new_len; 3088 set_len = new_len;
3073 } 3089 }
3074 3090
3075 ret = __ocfs2_decrease_refcount(handle, context->ref_ci, 3091 ret = __ocfs2_decrease_refcount(handle, ref_ci,
3076 context->ref_root_bh, 3092 context->ref_root_bh,
3077 p_cluster, set_len, 3093 p_cluster, set_len,
3078 context->meta_ac, 3094 context->meta_ac,
@@ -3114,17 +3130,14 @@ out:
3114 return ret; 3130 return ret;
3115} 3131}
3116 3132
3117static int ocfs2_replace_cow(struct inode *inode, 3133static int ocfs2_replace_cow(struct ocfs2_cow_context *context)
3118 struct buffer_head *di_bh,
3119 struct buffer_head *ref_root_bh,
3120 struct ocfs2_caching_info *ref_ci,
3121 u32 cow_start, u32 cow_len)
3122{ 3134{
3123 int ret = 0; 3135 int ret = 0;
3124 u32 p_cluster, num_clusters, start = cow_start; 3136 struct inode *inode = context->inode;
3137 u32 cow_start = context->cow_start, cow_len = context->cow_len;
3138 u32 p_cluster, num_clusters;
3125 unsigned int ext_flags; 3139 unsigned int ext_flags;
3126 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); 3140 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
3127 struct ocfs2_cow_context *context;
3128 3141
3129 if (!ocfs2_refcount_tree(OCFS2_SB(inode->i_sb))) { 3142 if (!ocfs2_refcount_tree(OCFS2_SB(inode->i_sb))) {
3130 ocfs2_error(inode->i_sb, "Inode %lu want to use refcount " 3143 ocfs2_error(inode->i_sb, "Inode %lu want to use refcount "
@@ -3133,26 +3146,11 @@ static int ocfs2_replace_cow(struct inode *inode,
3133 return -EROFS; 3146 return -EROFS;
3134 } 3147 }
3135 3148
3136 context = kzalloc(sizeof(struct ocfs2_cow_context), GFP_NOFS);
3137 if (!context) {
3138 ret = -ENOMEM;
3139 mlog_errno(ret);
3140 return ret;
3141 }
3142
3143 context->inode = inode;
3144 context->cow_start = cow_start;
3145 context->cow_len = cow_len;
3146 context->ref_ci = ref_ci;
3147 context->ref_root_bh = ref_root_bh;
3148
3149 ocfs2_init_dealloc_ctxt(&context->dealloc); 3149 ocfs2_init_dealloc_ctxt(&context->dealloc);
3150 ocfs2_init_dinode_extent_tree(&context->di_et,
3151 INODE_CACHE(inode), di_bh);
3152 3150
3153 while (cow_len) { 3151 while (cow_len) {
3154 ret = ocfs2_get_clusters(inode, cow_start, &p_cluster, 3152 ret = context->get_clusters(context, cow_start, &p_cluster,
3155 &num_clusters, &ext_flags); 3153 &num_clusters, &ext_flags);
3156 if (ret) { 3154 if (ret) {
3157 mlog_errno(ret); 3155 mlog_errno(ret);
3158 break; 3156 break;
@@ -3175,20 +3173,11 @@ static int ocfs2_replace_cow(struct inode *inode,
3175 cow_start += num_clusters; 3173 cow_start += num_clusters;
3176 } 3174 }
3177 3175
3178
3179 /*
3180 * truncate the extent map here since no matter whether we meet with
3181 * any error during the action, we shouldn't trust cached extent map
3182 * any more.
3183 */
3184 ocfs2_extent_map_trunc(inode, start);
3185
3186 if (ocfs2_dealloc_has_cluster(&context->dealloc)) { 3176 if (ocfs2_dealloc_has_cluster(&context->dealloc)) {
3187 ocfs2_schedule_truncate_log_flush(osb, 1); 3177 ocfs2_schedule_truncate_log_flush(osb, 1);
3188 ocfs2_run_deallocs(osb, &context->dealloc); 3178 ocfs2_run_deallocs(osb, &context->dealloc);
3189 } 3179 }
3190 3180
3191 kfree(context);
3192 return ret; 3181 return ret;
3193} 3182}
3194 3183
@@ -3208,10 +3197,11 @@ static int ocfs2_refcount_cow_hunk(struct inode *inode,
3208 struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data; 3197 struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data;
3209 struct buffer_head *ref_root_bh = NULL; 3198 struct buffer_head *ref_root_bh = NULL;
3210 struct ocfs2_refcount_tree *ref_tree; 3199 struct ocfs2_refcount_tree *ref_tree;
3200 struct ocfs2_cow_context *context = NULL;
3211 3201
3212 BUG_ON(!(oi->ip_dyn_features & OCFS2_HAS_REFCOUNT_FL)); 3202 BUG_ON(!(oi->ip_dyn_features & OCFS2_HAS_REFCOUNT_FL));
3213 3203
3214 ret = ocfs2_refcount_cal_cow_clusters(inode, di_bh, 3204 ret = ocfs2_refcount_cal_cow_clusters(inode, &di->id2.i_list,
3215 cpos, write_len, max_cpos, 3205 cpos, write_len, max_cpos,
3216 &cow_start, &cow_len); 3206 &cow_start, &cow_len);
3217 if (ret) { 3207 if (ret) {
@@ -3225,6 +3215,13 @@ static int ocfs2_refcount_cow_hunk(struct inode *inode,
3225 3215
3226 BUG_ON(cow_len == 0); 3216 BUG_ON(cow_len == 0);
3227 3217
3218 context = kzalloc(sizeof(struct ocfs2_cow_context), GFP_NOFS);
3219 if (!context) {
3220 ret = -ENOMEM;
3221 mlog_errno(ret);
3222 goto out;
3223 }
3224
3228 ret = ocfs2_lock_refcount_tree(osb, le64_to_cpu(di->i_refcount_loc), 3225 ret = ocfs2_lock_refcount_tree(osb, le64_to_cpu(di->i_refcount_loc),
3229 1, &ref_tree, &ref_root_bh); 3226 1, &ref_tree, &ref_root_bh);
3230 if (ret) { 3227 if (ret) {
@@ -3232,14 +3229,32 @@ static int ocfs2_refcount_cow_hunk(struct inode *inode,
3232 goto out; 3229 goto out;
3233 } 3230 }
3234 3231
3235 ret = ocfs2_replace_cow(inode, di_bh, ref_root_bh, &ref_tree->rf_ci, 3232 context->inode = inode;
3236 cow_start, cow_len); 3233 context->cow_start = cow_start;
3234 context->cow_len = cow_len;
3235 context->ref_tree = ref_tree;
3236 context->ref_root_bh = ref_root_bh;
3237 context->cow_duplicate_clusters = ocfs2_duplicate_clusters_by_page;
3238 context->get_clusters = ocfs2_di_get_clusters;
3239
3240 ocfs2_init_dinode_extent_tree(&context->data_et,
3241 INODE_CACHE(inode), di_bh);
3242
3243 ret = ocfs2_replace_cow(context);
3237 if (ret) 3244 if (ret)
3238 mlog_errno(ret); 3245 mlog_errno(ret);
3239 3246
3247 /*
3248 * truncate the extent map here since no matter whether we meet with
3249 * any error during the action, we shouldn't trust cached extent map
3250 * any more.
3251 */
3252 ocfs2_extent_map_trunc(inode, cow_start);
3253
3240 ocfs2_unlock_refcount_tree(osb, ref_tree, 1); 3254 ocfs2_unlock_refcount_tree(osb, ref_tree, 1);
3241 brelse(ref_root_bh); 3255 brelse(ref_root_bh);
3242out: 3256out:
3257 kfree(context);
3243 return ret; 3258 return ret;
3244} 3259}
3245 3260