diff options
author | Joel Becker <joel.becker@oracle.com> | 2008-10-24 21:47:33 -0400 |
---|---|---|
committer | Mark Fasheh <mfasheh@suse.com> | 2009-01-05 11:34:17 -0500 |
commit | 1224be020f62ada3e19822feeac3840abf80de3e (patch) | |
tree | 914ea36d842ef33c444b4bd11dfd5e21dbef6af4 /fs/ocfs2/xattr.c | |
parent | 784b816a9198dc3782c97cde8ddcf52fecdf1797 (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.c | 140 |
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 | ||
213 | static 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 | |||
233 | static 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 | |||
213 | static inline const char *ocfs2_xattr_prefix(int name_index) | 244 | static 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 | ||
3371 | out: | 3394 | out: |
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 | ||
3431 | out: | 3452 | out: |
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 | ||
4080 | static 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); | ||
4162 | out: | 4150 | out: |
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); | ||
4424 | out_commit: | 4412 | out_commit: |
4425 | ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle); | 4413 | ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle); |
4426 | } | 4414 | } |