aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/xattr.c
diff options
context:
space:
mode:
authorJoel Becker <joel.becker@oracle.com>2008-11-26 18:25:41 -0500
committerMark Fasheh <mfasheh@suse.com>2009-01-05 11:40:30 -0500
commit91f2033fa997aa92607470ed1ef90685b9d77a8c (patch)
tree7082fbdd368eff8e82e09f26b24a9f19d17a8278 /fs/ocfs2/xattr.c
parented29c0ca14871021fc8aced74650648dcb2c6e81 (diff)
ocfs2: Pass xs->bucket into ocfs2_add_new_xattr_bucket().
Pass the actual target bucket for insert through to ocfs2_add_new_xattr_bucket(). Now growing a bucket has no buffer_head knowledge. ocfs2_add_new_xattr_bucket() leavs xs->bucket in the proper state for insert. However, it doesn't update the rest of the search fields in xs, so we still have to relse() and re-find. That's OK, because everything is cached. Signed-off-by: Joel Becker <joel.becker@oracle.com> Signed-off-by: Mark Fasheh <mfasheh@suse.com>
Diffstat (limited to 'fs/ocfs2/xattr.c')
-rw-r--r--fs/ocfs2/xattr.c52
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 */
4327static int ocfs2_add_new_xattr_bucket(struct inode *inode, 4329static 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
4408out: 4401out:
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);