aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTao Ma <tao.ma@oracle.com>2009-08-17 23:43:42 -0400
committerJoel Becker <joel.becker@oracle.com>2009-09-22 23:09:43 -0400
commit47bca4950bc40fb54e9d41cbbc8b06cd653d2ae2 (patch)
tree17d36e5b9f330cda55b6ee8ff9a0293bd080040e
parent5aea1f0ef4024ba28213c10181e1b16ec678c82d (diff)
ocfs2: Abstract ocfs2 xattr tree extend rec iteration process.
Currently we have ocfs2_iterate_xattr_buckets which can receive a para and a callback to iterate a series of bucket. It is good. But actually the 2 callers ocfs2_xattr_tree_list_index_block and ocfs2_delete_xattr_index_block are almost the same. The only difference is that the latter need to handle the extent record also. So add a new function named ocfs2_iterate_xattr_index_block. It can be given func callback which are used for exten record. So now we only have one iteration function for the xattr index block. Ane what's more, it is useful for our future reflink operations. Signed-off-by: Tao Ma <tao.ma@oracle.com>
-rw-r--r--fs/ocfs2/xattr.c147
1 files changed, 76 insertions, 71 deletions
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c
index a9339eb94a2e..bfa7ee208855 100644
--- a/fs/ocfs2/xattr.c
+++ b/fs/ocfs2/xattr.c
@@ -157,7 +157,7 @@ static int ocfs2_xattr_index_block_find(struct inode *inode,
157 struct ocfs2_xattr_search *xs); 157 struct ocfs2_xattr_search *xs);
158 158
159static int ocfs2_xattr_tree_list_index_block(struct inode *inode, 159static int ocfs2_xattr_tree_list_index_block(struct inode *inode,
160 struct ocfs2_xattr_tree_root *xt, 160 struct buffer_head *blk_bh,
161 char *buffer, 161 char *buffer,
162 size_t buffer_size); 162 size_t buffer_size);
163 163
@@ -170,8 +170,23 @@ static int ocfs2_xattr_set_entry_index_block(struct inode *inode,
170 struct ocfs2_xattr_search *xs, 170 struct ocfs2_xattr_search *xs,
171 struct ocfs2_xattr_set_ctxt *ctxt); 171 struct ocfs2_xattr_set_ctxt *ctxt);
172 172
173static int ocfs2_delete_xattr_index_block(struct inode *inode, 173typedef int (xattr_tree_rec_func)(struct inode *inode,
174 struct buffer_head *xb_bh); 174 struct buffer_head *root_bh,
175 u64 blkno, u32 cpos, u32 len, void *para);
176static int ocfs2_iterate_xattr_index_block(struct inode *inode,
177 struct buffer_head *root_bh,
178 xattr_tree_rec_func *rec_func,
179 void *para);
180static int ocfs2_delete_xattr_in_bucket(struct inode *inode,
181 struct ocfs2_xattr_bucket *bucket,
182 void *para);
183static int ocfs2_rm_xattr_cluster(struct inode *inode,
184 struct buffer_head *root_bh,
185 u64 blkno,
186 u32 cpos,
187 u32 len,
188 void *para);
189
175static int ocfs2_mv_xattr_buckets(struct inode *inode, handle_t *handle, 190static int ocfs2_mv_xattr_buckets(struct inode *inode, handle_t *handle,
176 u64 src_blk, u64 last_blk, u64 to_blk, 191 u64 src_blk, u64 last_blk, u64 to_blk,
177 unsigned int start_bucket, 192 unsigned int start_bucket,
@@ -870,11 +885,9 @@ static int ocfs2_xattr_block_list(struct inode *inode,
870 struct ocfs2_xattr_header *header = &xb->xb_attrs.xb_header; 885 struct ocfs2_xattr_header *header = &xb->xb_attrs.xb_header;
871 ret = ocfs2_xattr_list_entries(inode, header, 886 ret = ocfs2_xattr_list_entries(inode, header,
872 buffer, buffer_size); 887 buffer, buffer_size);
873 } else { 888 } else
874 struct ocfs2_xattr_tree_root *xt = &xb->xb_attrs.xb_root; 889 ret = ocfs2_xattr_tree_list_index_block(inode, blk_bh,
875 ret = ocfs2_xattr_tree_list_index_block(inode, xt,
876 buffer, buffer_size); 890 buffer, buffer_size);
877 }
878 891
879 brelse(blk_bh); 892 brelse(blk_bh);
880 893
@@ -1801,7 +1814,10 @@ static int ocfs2_xattr_block_remove(struct inode *inode,
1801 struct ocfs2_xattr_header *header = &(xb->xb_attrs.xb_header); 1814 struct ocfs2_xattr_header *header = &(xb->xb_attrs.xb_header);
1802 ret = ocfs2_remove_value_outside(inode, &vb, header); 1815 ret = ocfs2_remove_value_outside(inode, &vb, header);
1803 } else 1816 } else
1804 ret = ocfs2_delete_xattr_index_block(inode, blk_bh); 1817 ret = ocfs2_iterate_xattr_index_block(inode,
1818 blk_bh,
1819 ocfs2_rm_xattr_cluster,
1820 NULL);
1805 1821
1806 return ret; 1822 return ret;
1807} 1823}
@@ -3298,22 +3314,19 @@ static int ocfs2_list_xattr_bucket(struct inode *inode,
3298 return ret; 3314 return ret;
3299} 3315}
3300 3316
3301static int ocfs2_xattr_tree_list_index_block(struct inode *inode, 3317static int ocfs2_iterate_xattr_index_block(struct inode *inode,
3302 struct ocfs2_xattr_tree_root *xt, 3318 struct buffer_head *blk_bh,
3303 char *buffer, 3319 xattr_tree_rec_func *rec_func,
3304 size_t buffer_size) 3320 void *para)
3305{ 3321{
3306 struct ocfs2_extent_list *el = &xt->xt_list; 3322 struct ocfs2_xattr_block *xb =
3323 (struct ocfs2_xattr_block *)blk_bh->b_data;
3324 struct ocfs2_extent_list *el = &xb->xb_attrs.xb_root.xt_list;
3307 int ret = 0; 3325 int ret = 0;
3308 u32 name_hash = UINT_MAX, e_cpos = 0, num_clusters = 0; 3326 u32 name_hash = UINT_MAX, e_cpos = 0, num_clusters = 0;
3309 u64 p_blkno = 0; 3327 u64 p_blkno = 0;
3310 struct ocfs2_xattr_tree_list xl = {
3311 .buffer = buffer,
3312 .buffer_size = buffer_size,
3313 .result = 0,
3314 };
3315 3328
3316 if (le16_to_cpu(el->l_next_free_rec) == 0) 3329 if (!el->l_next_free_rec || !rec_func)
3317 return 0; 3330 return 0;
3318 3331
3319 while (name_hash > 0) { 3332 while (name_hash > 0) {
@@ -3321,16 +3334,15 @@ static int ocfs2_xattr_tree_list_index_block(struct inode *inode,
3321 &e_cpos, &num_clusters, el); 3334 &e_cpos, &num_clusters, el);
3322 if (ret) { 3335 if (ret) {
3323 mlog_errno(ret); 3336 mlog_errno(ret);
3324 goto out; 3337 break;
3325 } 3338 }
3326 3339
3327 ret = ocfs2_iterate_xattr_buckets(inode, p_blkno, num_clusters, 3340 ret = rec_func(inode, blk_bh, p_blkno, e_cpos,
3328 ocfs2_list_xattr_bucket, 3341 num_clusters, para);
3329 &xl);
3330 if (ret) { 3342 if (ret) {
3331 if (ret != -ERANGE) 3343 if (ret != -ERANGE)
3332 mlog_errno(ret); 3344 mlog_errno(ret);
3333 goto out; 3345 break;
3334 } 3346 }
3335 3347
3336 if (e_cpos == 0) 3348 if (e_cpos == 0)
@@ -3339,6 +3351,37 @@ static int ocfs2_xattr_tree_list_index_block(struct inode *inode,
3339 name_hash = e_cpos - 1; 3351 name_hash = e_cpos - 1;
3340 } 3352 }
3341 3353
3354 return ret;
3355
3356}
3357
3358static int ocfs2_list_xattr_tree_rec(struct inode *inode,
3359 struct buffer_head *root_bh,
3360 u64 blkno, u32 cpos, u32 len, void *para)
3361{
3362 return ocfs2_iterate_xattr_buckets(inode, blkno, len,
3363 ocfs2_list_xattr_bucket, para);
3364}
3365
3366static int ocfs2_xattr_tree_list_index_block(struct inode *inode,
3367 struct buffer_head *blk_bh,
3368 char *buffer,
3369 size_t buffer_size)
3370{
3371 int ret;
3372 struct ocfs2_xattr_tree_list xl = {
3373 .buffer = buffer,
3374 .buffer_size = buffer_size,
3375 .result = 0,
3376 };
3377
3378 ret = ocfs2_iterate_xattr_index_block(inode, blk_bh,
3379 ocfs2_list_xattr_tree_rec, &xl);
3380 if (ret) {
3381 mlog_errno(ret);
3382 goto out;
3383 }
3384
3342 ret = xl.result; 3385 ret = xl.result;
3343out: 3386out:
3344 return ret; 3387 return ret;
@@ -4897,7 +4940,8 @@ static int ocfs2_rm_xattr_cluster(struct inode *inode,
4897 struct buffer_head *root_bh, 4940 struct buffer_head *root_bh,
4898 u64 blkno, 4941 u64 blkno,
4899 u32 cpos, 4942 u32 cpos,
4900 u32 len) 4943 u32 len,
4944 void *para)
4901{ 4945{
4902 int ret; 4946 int ret;
4903 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); 4947 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
@@ -4909,6 +4953,13 @@ static int ocfs2_rm_xattr_cluster(struct inode *inode,
4909 struct ocfs2_cached_dealloc_ctxt dealloc; 4953 struct ocfs2_cached_dealloc_ctxt dealloc;
4910 struct ocfs2_extent_tree et; 4954 struct ocfs2_extent_tree et;
4911 4955
4956 ret = ocfs2_iterate_xattr_buckets(inode, blkno, len,
4957 ocfs2_delete_xattr_in_bucket, NULL);
4958 if (ret) {
4959 mlog_errno(ret);
4960 return ret;
4961 }
4962
4912 ocfs2_init_xattr_tree_extent_tree(&et, INODE_CACHE(inode), root_bh); 4963 ocfs2_init_xattr_tree_extent_tree(&et, INODE_CACHE(inode), root_bh);
4913 4964
4914 ocfs2_init_dealloc_ctxt(&dealloc); 4965 ocfs2_init_dealloc_ctxt(&dealloc);
@@ -5331,52 +5382,6 @@ static int ocfs2_delete_xattr_in_bucket(struct inode *inode,
5331 return ret; 5382 return ret;
5332} 5383}
5333 5384
5334static int ocfs2_delete_xattr_index_block(struct inode *inode,
5335 struct buffer_head *xb_bh)
5336{
5337 struct ocfs2_xattr_block *xb =
5338 (struct ocfs2_xattr_block *)xb_bh->b_data;
5339 struct ocfs2_extent_list *el = &xb->xb_attrs.xb_root.xt_list;
5340 int ret = 0;
5341 u32 name_hash = UINT_MAX, e_cpos, num_clusters;
5342 u64 p_blkno;
5343
5344 if (le16_to_cpu(el->l_next_free_rec) == 0)
5345 return 0;
5346
5347 while (name_hash > 0) {
5348 ret = ocfs2_xattr_get_rec(inode, name_hash, &p_blkno,
5349 &e_cpos, &num_clusters, el);
5350 if (ret) {
5351 mlog_errno(ret);
5352 goto out;
5353 }
5354
5355 ret = ocfs2_iterate_xattr_buckets(inode, p_blkno, num_clusters,
5356 ocfs2_delete_xattr_in_bucket,
5357 NULL);
5358 if (ret) {
5359 mlog_errno(ret);
5360 goto out;
5361 }
5362
5363 ret = ocfs2_rm_xattr_cluster(inode, xb_bh,
5364 p_blkno, e_cpos, num_clusters);
5365 if (ret) {
5366 mlog_errno(ret);
5367 break;
5368 }
5369
5370 if (e_cpos == 0)
5371 break;
5372
5373 name_hash = e_cpos - 1;
5374 }
5375
5376out:
5377 return ret;
5378}
5379
5380/* 5385/*
5381 * Whenever we modify a xattr value root in the bucket(e.g, CoW 5386 * Whenever we modify a xattr value root in the bucket(e.g, CoW
5382 * or change the extent record flag), we need to recalculate 5387 * or change the extent record flag), we need to recalculate