aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/xattr.c
diff options
context:
space:
mode:
authorJoel Becker <joel.becker@oracle.com>2008-11-24 22:32:13 -0500
committerMark Fasheh <mfasheh@suse.com>2009-01-05 11:40:26 -0500
commit548b0f22bb7497ba76f91627b99f9fed53a91704 (patch)
treec5242ab4cb1780fa6aa55624e92adb7a4fb5e1ef /fs/ocfs2/xattr.c
parentdf32b3343aa11e0c7f54783594b24321d17d376f (diff)
ocfs2: Dirty the entire bucket in ocfs2_bucket_value_truncate()
ocfs2_bucket_value_truncate() currently takes the first bh of the bucket, and magically plays around with the value bh - even though the bucket structure in the calling function already has it. In addition, 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. ocfs2_xattr_update_value_size() is no longer necessary, as it only did one thing other than journal access/dirty. 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.c74
1 files changed, 28 insertions, 46 deletions
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c
index 3b9634c7d296..6db68a23a296 100644
--- a/fs/ocfs2/xattr.c
+++ b/fs/ocfs2/xattr.c
@@ -4580,31 +4580,6 @@ out:
4580 return ret; 4580 return ret;
4581} 4581}
4582 4582
4583static int ocfs2_xattr_value_update_size(struct inode *inode,
4584 handle_t *handle,
4585 struct buffer_head *xe_bh,
4586 struct ocfs2_xattr_entry *xe,
4587 u64 new_size)
4588{
4589 int ret;
4590
4591 ret = ocfs2_journal_access(handle, inode, xe_bh,
4592 OCFS2_JOURNAL_ACCESS_WRITE);
4593 if (ret < 0) {
4594 mlog_errno(ret);
4595 goto out;
4596 }
4597
4598 xe->xe_value_size = cpu_to_le64(new_size);
4599
4600 ret = ocfs2_journal_dirty(handle, xe_bh);
4601 if (ret < 0)
4602 mlog_errno(ret);
4603
4604out:
4605 return ret;
4606}
4607
4608/* 4583/*
4609 * Truncate the specified xe_off entry in xattr bucket. 4584 * Truncate the specified xe_off entry in xattr bucket.
4610 * bucket is indicated by header_bh and len is the new length. 4585 * bucket is indicated by header_bh and len is the new length.
@@ -4613,7 +4588,7 @@ out:
4613 * Copy the new updated xe and xe_value_root to new_xe and new_xv if needed. 4588 * Copy the new updated xe and xe_value_root to new_xe and new_xv if needed.
4614 */ 4589 */
4615static int ocfs2_xattr_bucket_value_truncate(struct inode *inode, 4590static int ocfs2_xattr_bucket_value_truncate(struct inode *inode,
4616 struct buffer_head *header_bh, 4591 struct ocfs2_xattr_bucket *bucket,
4617 int xe_off, 4592 int xe_off,
4618 int len, 4593 int len,
4619 struct ocfs2_xattr_set_ctxt *ctxt) 4594 struct ocfs2_xattr_set_ctxt *ctxt)
@@ -4623,8 +4598,7 @@ static int ocfs2_xattr_bucket_value_truncate(struct inode *inode,
4623 struct buffer_head *value_bh = NULL; 4598 struct buffer_head *value_bh = NULL;
4624 struct ocfs2_xattr_value_root *xv; 4599 struct ocfs2_xattr_value_root *xv;
4625 struct ocfs2_xattr_entry *xe; 4600 struct ocfs2_xattr_entry *xe;
4626 struct ocfs2_xattr_header *xh = 4601 struct ocfs2_xattr_header *xh = bucket_xh(bucket);
4627 (struct ocfs2_xattr_header *)header_bh->b_data;
4628 size_t blocksize = inode->i_sb->s_blocksize; 4602 size_t blocksize = inode->i_sb->s_blocksize;
4629 4603
4630 xe = &xh->xh_entries[xe_off]; 4604 xe = &xh->xh_entries[xe_off];
@@ -4638,34 +4612,41 @@ static int ocfs2_xattr_bucket_value_truncate(struct inode *inode,
4638 4612
4639 /* We don't allow ocfs2_xattr_value to be stored in different block. */ 4613 /* We don't allow ocfs2_xattr_value to be stored in different block. */
4640 BUG_ON(value_blk != (offset + OCFS2_XATTR_ROOT_SIZE - 1) / blocksize); 4614 BUG_ON(value_blk != (offset + OCFS2_XATTR_ROOT_SIZE - 1) / blocksize);
4641 value_blk += header_bh->b_blocknr;
4642 4615
4643 ret = ocfs2_read_block(inode, value_blk, &value_bh, NULL); 4616 value_bh = bucket->bu_bhs[value_blk];
4644 if (ret) { 4617 BUG_ON(!value_bh);
4645 mlog_errno(ret);
4646 goto out;
4647 }
4648 4618
4649 xv = (struct ocfs2_xattr_value_root *) 4619 xv = (struct ocfs2_xattr_value_root *)
4650 (value_bh->b_data + offset % blocksize); 4620 (value_bh->b_data + offset % blocksize);
4651 4621
4652 mlog(0, "truncate %u in xattr bucket %llu to %d bytes.\n", 4622 ret = ocfs2_xattr_bucket_journal_access(ctxt->handle, bucket,
4653 xe_off, (unsigned long long)header_bh->b_blocknr, len); 4623 OCFS2_JOURNAL_ACCESS_WRITE);
4654 ret = ocfs2_xattr_value_truncate(inode, value_bh, xv, len, ctxt);
4655 if (ret) { 4624 if (ret) {
4656 mlog_errno(ret); 4625 mlog_errno(ret);
4657 goto out; 4626 goto out;
4658 } 4627 }
4659 4628
4660 ret = ocfs2_xattr_value_update_size(inode, ctxt->handle, 4629 /*
4661 header_bh, xe, len); 4630 * From here on out we have to dirty the bucket. The generic
4631 * value calls only modify one of the bucket's bhs, but we need
4632 * to send the bucket at once. So if they error, they *could* have
4633 * modified something. We have to assume they did, and dirty
4634 * the whole bucket. This leaves us in a consistent state.
4635 */
4636 mlog(0, "truncate %u in xattr bucket %llu to %d bytes.\n",
4637 xe_off, (unsigned long long)bucket_blkno(bucket), len);
4638 ret = ocfs2_xattr_value_truncate(inode, value_bh, xv, len, ctxt);
4662 if (ret) { 4639 if (ret) {
4663 mlog_errno(ret); 4640 mlog_errno(ret);
4664 goto out; 4641 goto out_dirty;
4665 } 4642 }
4666 4643
4644 xe->xe_value_size = cpu_to_le64(len);
4645
4646out_dirty:
4647 ocfs2_xattr_bucket_journal_dirty(ctxt->handle, bucket);
4648
4667out: 4649out:
4668 brelse(value_bh);
4669 return ret; 4650 return ret;
4670} 4651}
4671 4652
@@ -4681,7 +4662,7 @@ static int ocfs2_xattr_bucket_value_truncate_xs(struct inode *inode,
4681 BUG_ON(!xs->bucket->bu_bhs[0] || !xe || ocfs2_xattr_is_local(xe)); 4662 BUG_ON(!xs->bucket->bu_bhs[0] || !xe || ocfs2_xattr_is_local(xe));
4682 4663
4683 offset = xe - xh->xh_entries; 4664 offset = xe - xh->xh_entries;
4684 ret = ocfs2_xattr_bucket_value_truncate(inode, xs->bucket->bu_bhs[0], 4665 ret = ocfs2_xattr_bucket_value_truncate(inode, xs->bucket,
4685 offset, len, ctxt); 4666 offset, len, ctxt);
4686 if (ret) 4667 if (ret)
4687 mlog_errno(ret); 4668 mlog_errno(ret);
@@ -5107,11 +5088,13 @@ static int ocfs2_delete_xattr_in_bucket(struct inode *inode,
5107 struct ocfs2_xattr_entry *xe; 5088 struct ocfs2_xattr_entry *xe;
5108 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); 5089 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
5109 struct ocfs2_xattr_set_ctxt ctxt = {NULL, NULL,}; 5090 struct ocfs2_xattr_set_ctxt ctxt = {NULL, NULL,};
5091 int credits = ocfs2_remove_extent_credits(osb->sb) +
5092 ocfs2_blocks_per_xattr_bucket(inode->i_sb);
5093
5110 5094
5111 ocfs2_init_dealloc_ctxt(&ctxt.dealloc); 5095 ocfs2_init_dealloc_ctxt(&ctxt.dealloc);
5112 5096
5113 ctxt.handle = ocfs2_start_trans(osb, 5097 ctxt.handle = ocfs2_start_trans(osb, credits);
5114 ocfs2_remove_extent_credits(osb->sb));
5115 if (IS_ERR(ctxt.handle)) { 5098 if (IS_ERR(ctxt.handle)) {
5116 ret = PTR_ERR(ctxt.handle); 5099 ret = PTR_ERR(ctxt.handle);
5117 mlog_errno(ret); 5100 mlog_errno(ret);
@@ -5123,8 +5106,7 @@ static int ocfs2_delete_xattr_in_bucket(struct inode *inode,
5123 if (ocfs2_xattr_is_local(xe)) 5106 if (ocfs2_xattr_is_local(xe))
5124 continue; 5107 continue;
5125 5108
5126 ret = ocfs2_xattr_bucket_value_truncate(inode, 5109 ret = ocfs2_xattr_bucket_value_truncate(inode, bucket,
5127 bucket->bu_bhs[0],
5128 i, 0, &ctxt); 5110 i, 0, &ctxt);
5129 if (ret) { 5111 if (ret) {
5130 mlog_errno(ret); 5112 mlog_errno(ret);