aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/xattr.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ocfs2/xattr.c')
-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