aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/xattr.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ocfs2/xattr.c')
-rw-r--r--fs/ocfs2/xattr.c74
1 files changed, 49 insertions, 25 deletions
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c
index e1d638af6ac3..2563df89fc2a 100644
--- a/fs/ocfs2/xattr.c
+++ b/fs/ocfs2/xattr.c
@@ -82,13 +82,14 @@ struct ocfs2_xattr_set_ctxt {
82 82
83#define OCFS2_XATTR_ROOT_SIZE (sizeof(struct ocfs2_xattr_def_value_root)) 83#define OCFS2_XATTR_ROOT_SIZE (sizeof(struct ocfs2_xattr_def_value_root))
84#define OCFS2_XATTR_INLINE_SIZE 80 84#define OCFS2_XATTR_INLINE_SIZE 80
85#define OCFS2_XATTR_HEADER_GAP 4
85#define OCFS2_XATTR_FREE_IN_IBODY (OCFS2_MIN_XATTR_INLINE_SIZE \ 86#define OCFS2_XATTR_FREE_IN_IBODY (OCFS2_MIN_XATTR_INLINE_SIZE \
86 - sizeof(struct ocfs2_xattr_header) \ 87 - sizeof(struct ocfs2_xattr_header) \
87 - sizeof(__u32)) 88 - OCFS2_XATTR_HEADER_GAP)
88#define OCFS2_XATTR_FREE_IN_BLOCK(ptr) ((ptr)->i_sb->s_blocksize \ 89#define OCFS2_XATTR_FREE_IN_BLOCK(ptr) ((ptr)->i_sb->s_blocksize \
89 - sizeof(struct ocfs2_xattr_block) \ 90 - sizeof(struct ocfs2_xattr_block) \
90 - sizeof(struct ocfs2_xattr_header) \ 91 - sizeof(struct ocfs2_xattr_header) \
91 - sizeof(__u32)) 92 - OCFS2_XATTR_HEADER_GAP)
92 93
93static struct ocfs2_xattr_def_value_root def_xv = { 94static struct ocfs2_xattr_def_value_root def_xv = {
94 .xv.xr_list.l_count = cpu_to_le16(1), 95 .xv.xr_list.l_count = cpu_to_le16(1),
@@ -274,10 +275,12 @@ static int ocfs2_read_xattr_bucket(struct ocfs2_xattr_bucket *bucket,
274 bucket->bu_blocks, bucket->bu_bhs, 0, 275 bucket->bu_blocks, bucket->bu_bhs, 0,
275 NULL); 276 NULL);
276 if (!rc) { 277 if (!rc) {
278 spin_lock(&OCFS2_SB(bucket->bu_inode->i_sb)->osb_xattr_lock);
277 rc = ocfs2_validate_meta_ecc_bhs(bucket->bu_inode->i_sb, 279 rc = ocfs2_validate_meta_ecc_bhs(bucket->bu_inode->i_sb,
278 bucket->bu_bhs, 280 bucket->bu_bhs,
279 bucket->bu_blocks, 281 bucket->bu_blocks,
280 &bucket_xh(bucket)->xh_check); 282 &bucket_xh(bucket)->xh_check);
283 spin_unlock(&OCFS2_SB(bucket->bu_inode->i_sb)->osb_xattr_lock);
281 if (rc) 284 if (rc)
282 mlog_errno(rc); 285 mlog_errno(rc);
283 } 286 }
@@ -310,9 +313,11 @@ static void ocfs2_xattr_bucket_journal_dirty(handle_t *handle,
310{ 313{
311 int i; 314 int i;
312 315
316 spin_lock(&OCFS2_SB(bucket->bu_inode->i_sb)->osb_xattr_lock);
313 ocfs2_compute_meta_ecc_bhs(bucket->bu_inode->i_sb, 317 ocfs2_compute_meta_ecc_bhs(bucket->bu_inode->i_sb,
314 bucket->bu_bhs, bucket->bu_blocks, 318 bucket->bu_bhs, bucket->bu_blocks,
315 &bucket_xh(bucket)->xh_check); 319 &bucket_xh(bucket)->xh_check);
320 spin_unlock(&OCFS2_SB(bucket->bu_inode->i_sb)->osb_xattr_lock);
316 321
317 for (i = 0; i < bucket->bu_blocks; i++) 322 for (i = 0; i < bucket->bu_blocks; i++)
318 ocfs2_journal_dirty(handle, bucket->bu_bhs[i]); 323 ocfs2_journal_dirty(handle, bucket->bu_bhs[i]);
@@ -542,8 +547,12 @@ int ocfs2_calc_xattr_init(struct inode *dir,
542 * when blocksize = 512, may reserve one more cluser for 547 * when blocksize = 512, may reserve one more cluser for
543 * xattr bucket, otherwise reserve one metadata block 548 * xattr bucket, otherwise reserve one metadata block
544 * for them is ok. 549 * for them is ok.
550 * If this is a new directory with inline data,
551 * we choose to reserve the entire inline area for
552 * directory contents and force an external xattr block.
545 */ 553 */
546 if (dir->i_sb->s_blocksize == OCFS2_MIN_BLOCKSIZE || 554 if (dir->i_sb->s_blocksize == OCFS2_MIN_BLOCKSIZE ||
555 (S_ISDIR(mode) && ocfs2_supports_inline_data(osb)) ||
547 (s_size + a_size) > OCFS2_XATTR_FREE_IN_IBODY) { 556 (s_size + a_size) > OCFS2_XATTR_FREE_IN_IBODY) {
548 ret = ocfs2_reserve_new_metadata_blocks(osb, 1, xattr_ac); 557 ret = ocfs2_reserve_new_metadata_blocks(osb, 1, xattr_ac);
549 if (ret) { 558 if (ret) {
@@ -1507,7 +1516,7 @@ static int ocfs2_xattr_set_entry(struct inode *inode,
1507 last += 1; 1516 last += 1;
1508 } 1517 }
1509 1518
1510 free = min_offs - ((void *)last - xs->base) - sizeof(__u32); 1519 free = min_offs - ((void *)last - xs->base) - OCFS2_XATTR_HEADER_GAP;
1511 if (free < 0) 1520 if (free < 0)
1512 return -EIO; 1521 return -EIO;
1513 1522
@@ -2190,7 +2199,7 @@ static int ocfs2_xattr_can_be_in_inode(struct inode *inode,
2190 last += 1; 2199 last += 1;
2191 } 2200 }
2192 2201
2193 free = min_offs - ((void *)last - xs->base) - sizeof(__u32); 2202 free = min_offs - ((void *)last - xs->base) - OCFS2_XATTR_HEADER_GAP;
2194 if (free < 0) 2203 if (free < 0)
2195 return 0; 2204 return 0;
2196 2205
@@ -2592,8 +2601,9 @@ static int __ocfs2_xattr_set_handle(struct inode *inode,
2592 2601
2593 if (!ret) { 2602 if (!ret) {
2594 /* Update inode ctime. */ 2603 /* Update inode ctime. */
2595 ret = ocfs2_journal_access(ctxt->handle, inode, xis->inode_bh, 2604 ret = ocfs2_journal_access_di(ctxt->handle, inode,
2596 OCFS2_JOURNAL_ACCESS_WRITE); 2605 xis->inode_bh,
2606 OCFS2_JOURNAL_ACCESS_WRITE);
2597 if (ret) { 2607 if (ret) {
2598 mlog_errno(ret); 2608 mlog_errno(ret);
2599 goto out; 2609 goto out;
@@ -4729,13 +4739,6 @@ static int ocfs2_xattr_bucket_value_truncate(struct inode *inode,
4729 vb.vb_xv = (struct ocfs2_xattr_value_root *) 4739 vb.vb_xv = (struct ocfs2_xattr_value_root *)
4730 (vb.vb_bh->b_data + offset % blocksize); 4740 (vb.vb_bh->b_data + offset % blocksize);
4731 4741
4732 ret = ocfs2_xattr_bucket_journal_access(ctxt->handle, bucket,
4733 OCFS2_JOURNAL_ACCESS_WRITE);
4734 if (ret) {
4735 mlog_errno(ret);
4736 goto out;
4737 }
4738
4739 /* 4742 /*
4740 * From here on out we have to dirty the bucket. The generic 4743 * From here on out we have to dirty the bucket. The generic
4741 * value calls only modify one of the bucket's bhs, but we need 4744 * value calls only modify one of the bucket's bhs, but we need
@@ -4748,12 +4751,18 @@ static int ocfs2_xattr_bucket_value_truncate(struct inode *inode,
4748 ret = ocfs2_xattr_value_truncate(inode, &vb, len, ctxt); 4751 ret = ocfs2_xattr_value_truncate(inode, &vb, len, ctxt);
4749 if (ret) { 4752 if (ret) {
4750 mlog_errno(ret); 4753 mlog_errno(ret);
4751 goto out_dirty; 4754 goto out;
4755 }
4756
4757 ret = ocfs2_xattr_bucket_journal_access(ctxt->handle, bucket,
4758 OCFS2_JOURNAL_ACCESS_WRITE);
4759 if (ret) {
4760 mlog_errno(ret);
4761 goto out;
4752 } 4762 }
4753 4763
4754 xe->xe_value_size = cpu_to_le64(len); 4764 xe->xe_value_size = cpu_to_le64(len);
4755 4765
4756out_dirty:
4757 ocfs2_xattr_bucket_journal_dirty(ctxt->handle, bucket); 4766 ocfs2_xattr_bucket_journal_dirty(ctxt->handle, bucket);
4758 4767
4759out: 4768out:
@@ -4786,19 +4795,33 @@ static int ocfs2_xattr_bucket_set_value_outside(struct inode *inode,
4786 char *val, 4795 char *val,
4787 int value_len) 4796 int value_len)
4788{ 4797{
4789 int offset; 4798 int ret, offset, block_off;
4790 struct ocfs2_xattr_value_root *xv; 4799 struct ocfs2_xattr_value_root *xv;
4791 struct ocfs2_xattr_entry *xe = xs->here; 4800 struct ocfs2_xattr_entry *xe = xs->here;
4801 struct ocfs2_xattr_header *xh = bucket_xh(xs->bucket);
4802 void *base;
4792 4803
4793 BUG_ON(!xs->base || !xe || ocfs2_xattr_is_local(xe)); 4804 BUG_ON(!xs->base || !xe || ocfs2_xattr_is_local(xe));
4794 4805
4795 offset = le16_to_cpu(xe->xe_name_offset) + 4806 ret = ocfs2_xattr_bucket_get_name_value(inode, xh,
4796 OCFS2_XATTR_SIZE(xe->xe_name_len); 4807 xe - xh->xh_entries,
4808 &block_off,
4809 &offset);
4810 if (ret) {
4811 mlog_errno(ret);
4812 goto out;
4813 }
4797 4814
4798 xv = (struct ocfs2_xattr_value_root *)(xs->base + offset); 4815 base = bucket_block(xs->bucket, block_off);
4816 xv = (struct ocfs2_xattr_value_root *)(base + offset +
4817 OCFS2_XATTR_SIZE(xe->xe_name_len));
4799 4818
4800 return __ocfs2_xattr_set_value_outside(inode, handle, 4819 ret = __ocfs2_xattr_set_value_outside(inode, handle,
4801 xv, val, value_len); 4820 xv, val, value_len);
4821 if (ret)
4822 mlog_errno(ret);
4823out:
4824 return ret;
4802} 4825}
4803 4826
4804static int ocfs2_rm_xattr_cluster(struct inode *inode, 4827static int ocfs2_rm_xattr_cluster(struct inode *inode,
@@ -5061,8 +5084,8 @@ try_again:
5061 xh_free_start = le16_to_cpu(xh->xh_free_start); 5084 xh_free_start = le16_to_cpu(xh->xh_free_start);
5062 header_size = sizeof(struct ocfs2_xattr_header) + 5085 header_size = sizeof(struct ocfs2_xattr_header) +
5063 count * sizeof(struct ocfs2_xattr_entry); 5086 count * sizeof(struct ocfs2_xattr_entry);
5064 max_free = OCFS2_XATTR_BUCKET_SIZE - 5087 max_free = OCFS2_XATTR_BUCKET_SIZE - header_size -
5065 le16_to_cpu(xh->xh_name_value_len) - header_size; 5088 le16_to_cpu(xh->xh_name_value_len) - OCFS2_XATTR_HEADER_GAP;
5066 5089
5067 mlog_bug_on_msg(header_size > blocksize, "bucket %llu has header size " 5090 mlog_bug_on_msg(header_size > blocksize, "bucket %llu has header size "
5068 "of %u which exceed block size\n", 5091 "of %u which exceed block size\n",
@@ -5095,7 +5118,7 @@ try_again:
5095 need = 0; 5118 need = 0;
5096 } 5119 }
5097 5120
5098 free = xh_free_start - header_size; 5121 free = xh_free_start - header_size - OCFS2_XATTR_HEADER_GAP;
5099 /* 5122 /*
5100 * We need to make sure the new name/value pair 5123 * We need to make sure the new name/value pair
5101 * can exist in the same block. 5124 * can exist in the same block.
@@ -5128,7 +5151,8 @@ try_again:
5128 } 5151 }
5129 5152
5130 xh_free_start = le16_to_cpu(xh->xh_free_start); 5153 xh_free_start = le16_to_cpu(xh->xh_free_start);
5131 free = xh_free_start - header_size; 5154 free = xh_free_start - header_size
5155 - OCFS2_XATTR_HEADER_GAP;
5132 if (xh_free_start % blocksize < need) 5156 if (xh_free_start % blocksize < need)
5133 free -= xh_free_start % blocksize; 5157 free -= xh_free_start % blocksize;
5134 5158