diff options
-rw-r--r-- | fs/ocfs2/xattr.c | 52 |
1 files changed, 25 insertions, 27 deletions
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c index 5a5a1bd7eede..dfc51c305bb9 100644 --- a/fs/ocfs2/xattr.c +++ b/fs/ocfs2/xattr.c | |||
@@ -4314,43 +4314,42 @@ out: | |||
4314 | } | 4314 | } |
4315 | 4315 | ||
4316 | /* | 4316 | /* |
4317 | * Add new xattr bucket in an extent record and adjust the buckets accordingly. | 4317 | * Add new xattr bucket in an extent record and adjust the buckets |
4318 | * xb_bh is the ocfs2_xattr_block. | 4318 | * accordingly. xb_bh is the ocfs2_xattr_block, and target is the |
4319 | * We will move all the buckets starting from header_bh to the next place. As | 4319 | * bucket we want to insert into. |
4320 | * for this one, half num of its xattrs will be moved to the next one. | ||
4321 | * | 4320 | * |
4322 | * We will allocate a new cluster if current cluster is full. The | 4321 | * In the easy case, we will move all the buckets after target down by |
4323 | * underlying calls will make sure that there is space at the target | 4322 | * one. Half of target's xattrs will be moved to the next bucket. |
4324 | * bucket, shifting buckets around if necessary. 'target' may be updated | 4323 | * |
4325 | * by those calls. | 4324 | * If current cluster is full, we'll allocate a new one. This may not |
4325 | * be contiguous. The underlying calls will make sure that there is | ||
4326 | * space for the insert, shifting buckets around if necessary. | ||
4327 | * 'target' may be moved by those calls. | ||
4326 | */ | 4328 | */ |
4327 | static int ocfs2_add_new_xattr_bucket(struct inode *inode, | 4329 | static int ocfs2_add_new_xattr_bucket(struct inode *inode, |
4328 | struct buffer_head *xb_bh, | 4330 | struct buffer_head *xb_bh, |
4329 | struct buffer_head *header_bh, | 4331 | struct ocfs2_xattr_bucket *target, |
4330 | struct ocfs2_xattr_set_ctxt *ctxt) | 4332 | struct ocfs2_xattr_set_ctxt *ctxt) |
4331 | { | 4333 | { |
4332 | struct ocfs2_xattr_block *xb = | 4334 | struct ocfs2_xattr_block *xb = |
4333 | (struct ocfs2_xattr_block *)xb_bh->b_data; | 4335 | (struct ocfs2_xattr_block *)xb_bh->b_data; |
4334 | struct ocfs2_xattr_tree_root *xb_root = &xb->xb_attrs.xb_root; | 4336 | struct ocfs2_xattr_tree_root *xb_root = &xb->xb_attrs.xb_root; |
4335 | struct ocfs2_extent_list *el = &xb_root->xt_list; | 4337 | struct ocfs2_extent_list *el = &xb_root->xt_list; |
4336 | struct ocfs2_xattr_header *xh = | 4338 | u32 name_hash = |
4337 | (struct ocfs2_xattr_header *)header_bh->b_data; | 4339 | le32_to_cpu(bucket_xh(target)->xh_entries[0].xe_name_hash); |
4338 | u32 name_hash = le32_to_cpu(xh->xh_entries[0].xe_name_hash); | ||
4339 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | 4340 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); |
4340 | int ret, num_buckets, extend = 1; | 4341 | int ret, num_buckets, extend = 1; |
4341 | u64 p_blkno; | 4342 | u64 p_blkno; |
4342 | u32 e_cpos, num_clusters; | 4343 | u32 e_cpos, num_clusters; |
4343 | /* The bucket at the front of the extent */ | 4344 | /* The bucket at the front of the extent */ |
4344 | struct ocfs2_xattr_bucket *first, *target; | 4345 | struct ocfs2_xattr_bucket *first; |
4345 | 4346 | ||
4346 | mlog(0, "Add new xattr bucket starting form %llu\n", | 4347 | mlog(0, "Add new xattr bucket starting from %llu\n", |
4347 | (unsigned long long)header_bh->b_blocknr); | 4348 | (unsigned long long)bucket_blkno(target)); |
4348 | 4349 | ||
4349 | /* The first bucket of the original extent */ | 4350 | /* The first bucket of the original extent */ |
4350 | first = ocfs2_xattr_bucket_new(inode); | 4351 | first = ocfs2_xattr_bucket_new(inode); |
4351 | /* The target bucket for insert */ | 4352 | if (!first) { |
4352 | target = ocfs2_xattr_bucket_new(inode); | ||
4353 | if (!first || !target) { | ||
4354 | ret = -ENOMEM; | 4353 | ret = -ENOMEM; |
4355 | mlog_errno(ret); | 4354 | mlog_errno(ret); |
4356 | goto out; | 4355 | goto out; |
@@ -4369,12 +4368,6 @@ static int ocfs2_add_new_xattr_bucket(struct inode *inode, | |||
4369 | goto out; | 4368 | goto out; |
4370 | } | 4369 | } |
4371 | 4370 | ||
4372 | ret = ocfs2_read_xattr_bucket(target, header_bh->b_blocknr); | ||
4373 | if (ret) { | ||
4374 | mlog_errno(ret); | ||
4375 | goto out; | ||
4376 | } | ||
4377 | |||
4378 | num_buckets = ocfs2_xattr_buckets_per_cluster(osb) * num_clusters; | 4371 | num_buckets = ocfs2_xattr_buckets_per_cluster(osb) * num_clusters; |
4379 | if (num_buckets == le16_to_cpu(bucket_xh(first)->xh_num_buckets)) { | 4372 | if (num_buckets == le16_to_cpu(bucket_xh(first)->xh_num_buckets)) { |
4380 | /* | 4373 | /* |
@@ -4407,7 +4400,6 @@ static int ocfs2_add_new_xattr_bucket(struct inode *inode, | |||
4407 | 4400 | ||
4408 | out: | 4401 | out: |
4409 | ocfs2_xattr_bucket_free(first); | 4402 | ocfs2_xattr_bucket_free(first); |
4410 | ocfs2_xattr_bucket_free(target); | ||
4411 | 4403 | ||
4412 | return ret; | 4404 | return ret; |
4413 | } | 4405 | } |
@@ -5083,15 +5075,21 @@ try_again: | |||
5083 | 5075 | ||
5084 | ret = ocfs2_add_new_xattr_bucket(inode, | 5076 | ret = ocfs2_add_new_xattr_bucket(inode, |
5085 | xs->xattr_bh, | 5077 | xs->xattr_bh, |
5086 | xs->bucket->bu_bhs[0], | 5078 | xs->bucket, |
5087 | ctxt); | 5079 | ctxt); |
5088 | if (ret) { | 5080 | if (ret) { |
5089 | mlog_errno(ret); | 5081 | mlog_errno(ret); |
5090 | goto out; | 5082 | goto out; |
5091 | } | 5083 | } |
5092 | 5084 | ||
5085 | /* | ||
5086 | * ocfs2_add_new_xattr_bucket() will have updated | ||
5087 | * xs->bucket if it moved, but it will not have updated | ||
5088 | * any of the other search fields. Thus, we drop it and | ||
5089 | * re-search. Everything should be cached, so it'll be | ||
5090 | * quick. | ||
5091 | */ | ||
5093 | ocfs2_xattr_bucket_relse(xs->bucket); | 5092 | ocfs2_xattr_bucket_relse(xs->bucket); |
5094 | |||
5095 | ret = ocfs2_xattr_index_block_find(inode, xs->xattr_bh, | 5093 | ret = ocfs2_xattr_index_block_find(inode, xs->xattr_bh, |
5096 | xi->name_index, | 5094 | xi->name_index, |
5097 | xi->name, xs); | 5095 | xi->name, xs); |