aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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);