aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/xattr.c
diff options
context:
space:
mode:
authorJoel Becker <joel.becker@oracle.com>2008-10-24 21:47:33 -0400
committerMark Fasheh <mfasheh@suse.com>2009-01-05 11:34:17 -0500
commit1224be020f62ada3e19822feeac3840abf80de3e (patch)
tree914ea36d842ef33c444b4bd11dfd5e21dbef6af4 /fs/ocfs2/xattr.c
parent784b816a9198dc3782c97cde8ddcf52fecdf1797 (diff)
ocfs2: Wrap journal_access/journal_dirty for xattr buckets.
A common action is to call ocfs2_journal_access() and ocfs2_journal_dirty() on the buffer heads of an xattr bucket. Let's create nice wrappers. While we're there, let's drop the places that try to be smart by writing only the first and last blocks of a bucket. A bucket is contiguous, so writing the whole thing is actually more efficient. 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.c140
1 files changed, 64 insertions, 76 deletions
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c
index fa13fa488786..99aefe4ea750 100644
--- a/fs/ocfs2/xattr.c
+++ b/fs/ocfs2/xattr.c
@@ -210,6 +210,37 @@ static int ocfs2_read_xattr_bucket(struct inode *inode,
210 return rc; 210 return rc;
211} 211}
212 212
213static int ocfs2_xattr_bucket_journal_access(handle_t *handle,
214 struct inode *inode,
215 struct ocfs2_xattr_bucket *bucket,
216 int type)
217{
218 int i, rc = 0;
219 int blks = ocfs2_blocks_per_xattr_bucket(inode->i_sb);
220
221 for (i = 0; i < blks; i++) {
222 rc = ocfs2_journal_access(handle, inode,
223 bucket->bu_bhs[i], type);
224 if (rc) {
225 mlog_errno(rc);
226 break;
227 }
228 }
229
230 return rc;
231}
232
233static void ocfs2_xattr_bucket_journal_dirty(handle_t *handle,
234 struct inode *inode,
235 struct ocfs2_xattr_bucket *bucket)
236{
237 int i, blks = ocfs2_blocks_per_xattr_bucket(inode->i_sb);
238
239 for (i = 0; i < blks; i++)
240 ocfs2_journal_dirty(handle, bucket->bu_bhs[i]);
241}
242
243
213static inline const char *ocfs2_xattr_prefix(int name_index) 244static inline const char *ocfs2_xattr_prefix(int name_index)
214{ 245{
215 struct xattr_handler *handler = NULL; 246 struct xattr_handler *handler = NULL;
@@ -3218,8 +3249,8 @@ static int ocfs2_divide_xattr_bucket(struct inode *inode,
3218 goto out; 3249 goto out;
3219 } 3250 }
3220 3251
3221 ret = ocfs2_journal_access(handle, inode, s_bucket.bu_bhs[0], 3252 ret = ocfs2_xattr_bucket_journal_access(handle, inode, &s_bucket,
3222 OCFS2_JOURNAL_ACCESS_WRITE); 3253 OCFS2_JOURNAL_ACCESS_WRITE);
3223 if (ret) { 3254 if (ret) {
3224 mlog_errno(ret); 3255 mlog_errno(ret);
3225 goto out; 3256 goto out;
@@ -3235,15 +3266,13 @@ static int ocfs2_divide_xattr_bucket(struct inode *inode,
3235 goto out; 3266 goto out;
3236 } 3267 }
3237 3268
3238 for (i = 0; i < blk_per_bucket; i++) { 3269 ret = ocfs2_xattr_bucket_journal_access(handle, inode, &t_bucket,
3239 ret = ocfs2_journal_access(handle, inode, t_bucket.bu_bhs[i], 3270 new_bucket_head ?
3240 new_bucket_head ? 3271 OCFS2_JOURNAL_ACCESS_CREATE :
3241 OCFS2_JOURNAL_ACCESS_CREATE : 3272 OCFS2_JOURNAL_ACCESS_WRITE);
3242 OCFS2_JOURNAL_ACCESS_WRITE); 3273 if (ret) {
3243 if (ret) { 3274 mlog_errno(ret);
3244 mlog_errno(ret); 3275 goto out;
3245 goto out;
3246 }
3247 } 3276 }
3248 3277
3249 xh = bucket_xh(&s_bucket); 3278 xh = bucket_xh(&s_bucket);
@@ -3339,11 +3368,7 @@ set_num_buckets:
3339 else 3368 else
3340 xh->xh_num_buckets = 0; 3369 xh->xh_num_buckets = 0;
3341 3370
3342 for (i = 0; i < blk_per_bucket; i++) { 3371 ocfs2_xattr_bucket_journal_dirty(handle, inode, &t_bucket);
3343 ocfs2_journal_dirty(handle, t_bucket.bu_bhs[i]);
3344 if (ret)
3345 mlog_errno(ret);
3346 }
3347 3372
3348 /* store the first_hash of the new bucket. */ 3373 /* store the first_hash of the new bucket. */
3349 if (first_hash) 3374 if (first_hash)
@@ -3364,9 +3389,7 @@ set_num_buckets:
3364 xh->xh_free_start = cpu_to_le16(name_offset); 3389 xh->xh_free_start = cpu_to_le16(name_offset);
3365 xh->xh_name_value_len = cpu_to_le16(name_value_len); 3390 xh->xh_name_value_len = cpu_to_le16(name_value_len);
3366 3391
3367 ocfs2_journal_dirty(handle, s_bucket.bu_bhs[0]); 3392 ocfs2_xattr_bucket_journal_dirty(handle, inode, &s_bucket);
3368 if (ret)
3369 mlog_errno(ret);
3370 3393
3371out: 3394out:
3372 ocfs2_xattr_bucket_relse(inode, &s_bucket); 3395 ocfs2_xattr_bucket_relse(inode, &s_bucket);
@@ -3413,20 +3436,18 @@ static int ocfs2_cp_xattr_bucket(struct inode *inode,
3413 if (ret) 3436 if (ret)
3414 goto out; 3437 goto out;
3415 3438
3416 for (i = 0; i < blk_per_bucket; i++) { 3439 ret = ocfs2_xattr_bucket_journal_access(handle, inode, &t_bucket,
3417 ret = ocfs2_journal_access(handle, inode, t_bucket.bu_bhs[i], 3440 t_is_new ?
3418 t_is_new ? 3441 OCFS2_JOURNAL_ACCESS_CREATE :
3419 OCFS2_JOURNAL_ACCESS_CREATE : 3442 OCFS2_JOURNAL_ACCESS_WRITE);
3420 OCFS2_JOURNAL_ACCESS_WRITE); 3443 if (ret)
3421 if (ret) 3444 goto out;
3422 goto out;
3423 }
3424 3445
3425 for (i = 0; i < blk_per_bucket; i++) { 3446 for (i = 0; i < blk_per_bucket; i++) {
3426 memcpy(bucket_block(&t_bucket, i), bucket_block(&s_bucket, i), 3447 memcpy(bucket_block(&t_bucket, i), bucket_block(&s_bucket, i),
3427 blocksize); 3448 blocksize);
3428 ocfs2_journal_dirty(handle, t_bucket.bu_bhs[i]);
3429 } 3449 }
3450 ocfs2_xattr_bucket_journal_dirty(handle, inode, &t_bucket);
3430 3451
3431out: 3452out:
3432 ocfs2_xattr_bucket_relse(inode, &s_bucket); 3453 ocfs2_xattr_bucket_relse(inode, &s_bucket);
@@ -3799,9 +3820,9 @@ static int ocfs2_extend_xattr_bucket(struct inode *inode,
3799 3820
3800 /* 3821 /*
3801 * We will touch all the buckets after the start_bh(include it). 3822 * We will touch all the buckets after the start_bh(include it).
3802 * Add one more bucket and modify the first_bh. 3823 * Then we add one more bucket.
3803 */ 3824 */
3804 credits = end_blk - start_blk + 2 * blk_per_bucket + 1; 3825 credits = end_blk - start_blk + 3 * blk_per_bucket + 1;
3805 handle = ocfs2_start_trans(osb, credits); 3826 handle = ocfs2_start_trans(osb, credits);
3806 if (IS_ERR(handle)) { 3827 if (IS_ERR(handle)) {
3807 ret = PTR_ERR(handle); 3828 ret = PTR_ERR(handle);
@@ -4077,33 +4098,6 @@ set_new_name_value:
4077 return; 4098 return;
4078} 4099}
4079 4100
4080static int ocfs2_xattr_bucket_handle_journal(struct inode *inode,
4081 handle_t *handle,
4082 struct ocfs2_xattr_search *xs,
4083 struct buffer_head **bhs,
4084 u16 bh_num)
4085{
4086 int ret = 0, off, block_off;
4087 struct ocfs2_xattr_entry *xe = xs->here;
4088
4089 /*
4090 * First calculate all the blocks we should journal_access
4091 * and journal_dirty. The first block should always be touched.
4092 */
4093 ret = ocfs2_journal_dirty(handle, bhs[0]);
4094 if (ret)
4095 mlog_errno(ret);
4096
4097 /* calc the data. */
4098 off = le16_to_cpu(xe->xe_name_offset);
4099 block_off = off >> inode->i_sb->s_blocksize_bits;
4100 ret = ocfs2_journal_dirty(handle, bhs[block_off]);
4101 if (ret)
4102 mlog_errno(ret);
4103
4104 return ret;
4105}
4106
4107/* 4101/*
4108 * Set the xattr entry in the specified bucket. 4102 * Set the xattr entry in the specified bucket.
4109 * The bucket is indicated by xs->bucket and it should have the enough 4103 * The bucket is indicated by xs->bucket and it should have the enough
@@ -4115,7 +4109,7 @@ static int ocfs2_xattr_set_entry_in_bucket(struct inode *inode,
4115 u32 name_hash, 4109 u32 name_hash,
4116 int local) 4110 int local)
4117{ 4111{
4118 int i, ret; 4112 int ret;
4119 handle_t *handle = NULL; 4113 handle_t *handle = NULL;
4120 u16 blk_per_bucket = ocfs2_blocks_per_xattr_bucket(inode->i_sb); 4114 u16 blk_per_bucket = ocfs2_blocks_per_xattr_bucket(inode->i_sb);
4121 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); 4115 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
@@ -4143,22 +4137,16 @@ static int ocfs2_xattr_set_entry_in_bucket(struct inode *inode,
4143 goto out; 4137 goto out;
4144 } 4138 }
4145 4139
4146 for (i = 0; i < blk_per_bucket; i++) { 4140 ret = ocfs2_xattr_bucket_journal_access(handle, inode, &xs->bucket,
4147 ret = ocfs2_journal_access(handle, inode, xs->bucket.bu_bhs[i], 4141 OCFS2_JOURNAL_ACCESS_WRITE);
4148 OCFS2_JOURNAL_ACCESS_WRITE); 4142 if (ret < 0) {
4149 if (ret < 0) { 4143 mlog_errno(ret);
4150 mlog_errno(ret); 4144 goto out;
4151 goto out;
4152 }
4153 } 4145 }
4154 4146
4155 ocfs2_xattr_set_entry_normal(inode, xi, xs, name_hash, local); 4147 ocfs2_xattr_set_entry_normal(inode, xi, xs, name_hash, local);
4148 ocfs2_xattr_bucket_journal_dirty(handle, inode, &xs->bucket);
4156 4149
4157 /*Only dirty the blocks we have touched in set xattr. */
4158 ret = ocfs2_xattr_bucket_handle_journal(inode, handle, xs,
4159 xs->bucket.bu_bhs, blk_per_bucket);
4160 if (ret)
4161 mlog_errno(ret);
4162out: 4150out:
4163 ocfs2_commit_trans(osb, handle); 4151 ocfs2_commit_trans(osb, handle);
4164 4152
@@ -4398,15 +4386,16 @@ static void ocfs2_xattr_bucket_remove_xs(struct inode *inode,
4398 le16_to_cpu(xh->xh_count) - 1]; 4386 le16_to_cpu(xh->xh_count) - 1];
4399 int ret = 0; 4387 int ret = 0;
4400 4388
4401 handle = ocfs2_start_trans((OCFS2_SB(inode->i_sb)), 1); 4389 handle = ocfs2_start_trans((OCFS2_SB(inode->i_sb)),
4390 ocfs2_blocks_per_xattr_bucket(inode->i_sb));
4402 if (IS_ERR(handle)) { 4391 if (IS_ERR(handle)) {
4403 ret = PTR_ERR(handle); 4392 ret = PTR_ERR(handle);
4404 mlog_errno(ret); 4393 mlog_errno(ret);
4405 return; 4394 return;
4406 } 4395 }
4407 4396
4408 ret = ocfs2_journal_access(handle, inode, xs->bucket.bu_bhs[0], 4397 ret = ocfs2_xattr_bucket_journal_access(handle, inode, &xs->bucket,
4409 OCFS2_JOURNAL_ACCESS_WRITE); 4398 OCFS2_JOURNAL_ACCESS_WRITE);
4410 if (ret) { 4399 if (ret) {
4411 mlog_errno(ret); 4400 mlog_errno(ret);
4412 goto out_commit; 4401 goto out_commit;
@@ -4418,9 +4407,8 @@ static void ocfs2_xattr_bucket_remove_xs(struct inode *inode,
4418 memset(last, 0, sizeof(struct ocfs2_xattr_entry)); 4407 memset(last, 0, sizeof(struct ocfs2_xattr_entry));
4419 le16_add_cpu(&xh->xh_count, -1); 4408 le16_add_cpu(&xh->xh_count, -1);
4420 4409
4421 ret = ocfs2_journal_dirty(handle, xs->bucket.bu_bhs[0]); 4410 ocfs2_xattr_bucket_journal_dirty(handle, inode, &xs->bucket);
4422 if (ret < 0) 4411
4423 mlog_errno(ret);
4424out_commit: 4412out_commit:
4425 ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle); 4413 ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle);
4426} 4414}