aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/xattr.c
diff options
context:
space:
mode:
authorJoel Becker <joel.becker@oracle.com>2008-11-25 20:06:40 -0500
committerMark Fasheh <mfasheh@suse.com>2009-01-05 11:40:26 -0500
commit92de109ade7999084fb0bfcc65d603252504e0d0 (patch)
tree6a834f52a9e36118045d31017f7265ef5c0bb060 /fs/ocfs2/xattr.c
parent88c3b0622acf82c7c86fbc066e81e15edc7c1685 (diff)
ocfs2: Dirty the entire first bucket in ocfs2_extend_xattr_bucket()
ocfs2_extend_xattr_bucket() takes an extent of buckets and shifts some of them down to make room for a new xattr. It is passed the first bh of the first bucket, because that is where we store the number of buckets in the extent. However, future code wants to always dirty the entire bucket when it is changed. So let's pass the entire bucket into this function, skip any block reads (we have them), and add the access/dirty logic. We also can skip passing in the target bucket bh - we only need its block number. 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.c85
1 files changed, 55 insertions, 30 deletions
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c
index df53a2ce2de5..ed1e95967565 100644
--- a/fs/ocfs2/xattr.c
+++ b/fs/ocfs2/xattr.c
@@ -3905,7 +3905,7 @@ static int ocfs2_cp_xattr_bucket(struct inode *inode,
3905 mlog_errno(ret); 3905 mlog_errno(ret);
3906 goto out; 3906 goto out;
3907 } 3907 }
3908 3908
3909 ret = ocfs2_read_xattr_bucket(s_bucket, s_blkno); 3909 ret = ocfs2_read_xattr_bucket(s_bucket, s_blkno);
3910 if (ret) 3910 if (ret)
3911 goto out; 3911 goto out;
@@ -4232,37 +4232,45 @@ leave:
4232} 4232}
4233 4233
4234/* 4234/*
4235 * Extend a new xattr bucket and move xattrs to the end one by one until 4235 * We are given an extent. 'first' is the bucket at the very front of
4236 * We meet with start_bh. Only move half of the xattrs to the bucket after it. 4236 * the extent. The extent has space for an additional bucket past
4237 * bucket_xh(first)->xh_num_buckets. 'target_blkno' is the block number
4238 * of the target bucket. We wish to shift every bucket past the target
4239 * down one, filling in that additional space. When we get back to the
4240 * target, we split the target between itself and the now-empty bucket
4241 * at target+1 (aka, target_blkno + blks_per_bucket).
4237 */ 4242 */
4238static int ocfs2_extend_xattr_bucket(struct inode *inode, 4243static int ocfs2_extend_xattr_bucket(struct inode *inode,
4239 handle_t *handle, 4244 handle_t *handle,
4240 struct buffer_head *first_bh, 4245 struct ocfs2_xattr_bucket *first,
4241 struct buffer_head *start_bh, 4246 u64 target_blk,
4242 u32 num_clusters) 4247 u32 num_clusters)
4243{ 4248{
4244 int ret, credits; 4249 int ret, credits;
4245 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); 4250 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
4246 u16 blk_per_bucket = ocfs2_blocks_per_xattr_bucket(inode->i_sb); 4251 u16 blk_per_bucket = ocfs2_blocks_per_xattr_bucket(inode->i_sb);
4247 u64 start_blk = start_bh->b_blocknr, end_blk; 4252 u64 end_blk;
4248 u32 num_buckets = num_clusters * ocfs2_xattr_buckets_per_cluster(osb); 4253 u16 new_bucket = le16_to_cpu(bucket_xh(first)->xh_num_buckets);
4249 struct ocfs2_xattr_header *first_xh =
4250 (struct ocfs2_xattr_header *)first_bh->b_data;
4251 u16 bucket = le16_to_cpu(first_xh->xh_num_buckets);
4252 4254
4253 mlog(0, "extend xattr bucket in %llu, xattr extend rec starting " 4255 mlog(0, "extend xattr bucket in %llu, xattr extend rec starting "
4254 "from %llu, len = %u\n", (unsigned long long)start_blk, 4256 "from %llu, len = %u\n", (unsigned long long)target_blk,
4255 (unsigned long long)first_bh->b_blocknr, num_clusters); 4257 (unsigned long long)bucket_blkno(first), num_clusters);
4256 4258
4257 BUG_ON(bucket >= num_buckets); 4259 /* The extent must have room for an additional bucket */
4260 BUG_ON(new_bucket >=
4261 (num_clusters * ocfs2_xattr_buckets_per_cluster(osb)));
4258 4262
4259 end_blk = first_bh->b_blocknr + (bucket - 1) * blk_per_bucket; 4263 /* end_blk points to the last existing bucket */
4264 end_blk = bucket_blkno(first) + ((new_bucket - 1) * blk_per_bucket);
4260 4265
4261 /* 4266 /*
4262 * We will touch all the buckets after the start_bh(include it). 4267 * end_blk is the start of the last existing bucket.
4263 * Then we add one more bucket. 4268 * Thus, (end_blk - target_blk) covers the target bucket and
4269 * every bucket after it up to, but not including, the last
4270 * existing bucket. Then we add the last existing bucket, the
4271 * new bucket, and the first bucket (3 * blk_per_bucket).
4264 */ 4272 */
4265 credits = end_blk - start_blk + 3 * blk_per_bucket + 1 + 4273 credits = (end_blk - target_blk) + (3 * blk_per_bucket) +
4266 handle->h_buffer_credits; 4274 handle->h_buffer_credits;
4267 ret = ocfs2_extend_trans(handle, credits); 4275 ret = ocfs2_extend_trans(handle, credits);
4268 if (ret) { 4276 if (ret) {
@@ -4270,14 +4278,14 @@ static int ocfs2_extend_xattr_bucket(struct inode *inode,
4270 goto out; 4278 goto out;
4271 } 4279 }
4272 4280
4273 ret = ocfs2_journal_access(handle, inode, first_bh, 4281 ret = ocfs2_xattr_bucket_journal_access(handle, first,
4274 OCFS2_JOURNAL_ACCESS_WRITE); 4282 OCFS2_JOURNAL_ACCESS_WRITE);
4275 if (ret) { 4283 if (ret) {
4276 mlog_errno(ret); 4284 mlog_errno(ret);
4277 goto out; 4285 goto out;
4278 } 4286 }
4279 4287
4280 while (end_blk != start_blk) { 4288 while (end_blk != target_blk) {
4281 ret = ocfs2_cp_xattr_bucket(inode, handle, end_blk, 4289 ret = ocfs2_cp_xattr_bucket(inode, handle, end_blk,
4282 end_blk + blk_per_bucket, 0); 4290 end_blk + blk_per_bucket, 0);
4283 if (ret) 4291 if (ret)
@@ -4285,12 +4293,12 @@ static int ocfs2_extend_xattr_bucket(struct inode *inode,
4285 end_blk -= blk_per_bucket; 4293 end_blk -= blk_per_bucket;
4286 } 4294 }
4287 4295
4288 /* Move half of the xattr in start_blk to the next bucket. */ 4296 /* Move half of the xattr in target_blkno to the next bucket. */
4289 ret = ocfs2_divide_xattr_bucket(inode, handle, start_blk, 4297 ret = ocfs2_divide_xattr_bucket(inode, handle, target_blk,
4290 start_blk + blk_per_bucket, NULL, 0); 4298 target_blk + blk_per_bucket, NULL, 0);
4291 4299
4292 le16_add_cpu(&first_xh->xh_num_buckets, 1); 4300 le16_add_cpu(&bucket_xh(first)->xh_num_buckets, 1);
4293 ocfs2_journal_dirty(handle, first_bh); 4301 ocfs2_xattr_bucket_journal_dirty(handle, first);
4294 4302
4295out: 4303out:
4296 return ret; 4304 return ret;
@@ -4324,10 +4332,19 @@ static int ocfs2_add_new_xattr_bucket(struct inode *inode,
4324 int ret, num_buckets, extend = 1; 4332 int ret, num_buckets, extend = 1;
4325 u64 p_blkno; 4333 u64 p_blkno;
4326 u32 e_cpos, num_clusters; 4334 u32 e_cpos, num_clusters;
4335 /* The bucket at the front of the extent */
4336 struct ocfs2_xattr_bucket *first;
4327 4337
4328 mlog(0, "Add new xattr bucket starting form %llu\n", 4338 mlog(0, "Add new xattr bucket starting form %llu\n",
4329 (unsigned long long)header_bh->b_blocknr); 4339 (unsigned long long)header_bh->b_blocknr);
4330 4340
4341 first = ocfs2_xattr_bucket_new(inode);
4342 if (!first) {
4343 ret = -ENOMEM;
4344 mlog_errno(ret);
4345 goto out;
4346 }
4347
4331 /* 4348 /*
4332 * Add refrence for header_bh here because it may be 4349 * Add refrence for header_bh here because it may be
4333 * changed in ocfs2_add_new_xattr_cluster and we need 4350 * changed in ocfs2_add_new_xattr_cluster and we need
@@ -4367,17 +4384,25 @@ static int ocfs2_add_new_xattr_bucket(struct inode *inode,
4367 } 4384 }
4368 } 4385 }
4369 4386
4370 if (extend) 4387 if (extend) {
4388 /* These bucket reads should be cached */
4389 ret = ocfs2_read_xattr_bucket(first, first_bh->b_blocknr);
4390 if (ret) {
4391 mlog_errno(ret);
4392 goto out;
4393 }
4371 ret = ocfs2_extend_xattr_bucket(inode, 4394 ret = ocfs2_extend_xattr_bucket(inode,
4372 ctxt->handle, 4395 ctxt->handle,
4373 first_bh, 4396 first, header_bh->b_blocknr,
4374 header_bh,
4375 num_clusters); 4397 num_clusters);
4376 if (ret) 4398 if (ret)
4377 mlog_errno(ret); 4399 mlog_errno(ret);
4400 }
4401
4378out: 4402out:
4379 brelse(first_bh); 4403 brelse(first_bh);
4380 brelse(header_bh); 4404 brelse(header_bh);
4405 ocfs2_xattr_bucket_free(first);
4381 return ret; 4406 return ret;
4382} 4407}
4383 4408