aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2
diff options
context:
space:
mode:
authorJoel Becker <joel.becker@oracle.com>2009-08-14 22:04:15 -0400
committerJoel Becker <joel.becker@oracle.com>2010-02-26 18:41:10 -0500
commit199799a3609f6d5bb231a75c2e702afaac805431 (patch)
treee9addab09c0c86a06dd97251888035cc0ccab202 /fs/ocfs2
parent18853b95d1fb964b76c3393a12c4d861e7779460 (diff)
ocfs2: Wrap calculation of name+value pair size.
An ocfs2 xattr entry stores the text name and value as a pair in the storage area. Obviously names and values can be variable-sized. If a value is too large for the entry storage, a tree root is stored instead. The name+value pair is also padded. Because of this, there are a million places in the code that do: if (needs_external_tree(value_size) namevalue_size = pad(name_size) + tree_root_size; else namevalue_size = pad(name_size) + pad(value_size); Let's create some convenience functions to make the code more readable. There are three forms. The first takes the raw sizes. The second takes an ocfs2_xattr_info structure. The third takes an existing ocfs2_xattr_entry. Signed-off-by: Joel Becker <joel.becker@oracle.com>
Diffstat (limited to 'fs/ocfs2')
-rw-r--r--fs/ocfs2/xattr.c170
1 files changed, 65 insertions, 105 deletions
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c
index 68126adbf311..064ec6d6c23c 100644
--- a/fs/ocfs2/xattr.c
+++ b/fs/ocfs2/xattr.c
@@ -183,6 +183,33 @@ struct ocfs2_xa_loc {
183 const struct ocfs2_xa_loc_operations *xl_ops; 183 const struct ocfs2_xa_loc_operations *xl_ops;
184}; 184};
185 185
186/*
187 * Convenience functions to calculate how much space is needed for a
188 * given name+value pair
189 */
190static int namevalue_size(int name_len, uint64_t value_len)
191{
192 if (value_len > OCFS2_XATTR_INLINE_SIZE)
193 return OCFS2_XATTR_SIZE(name_len) + OCFS2_XATTR_ROOT_SIZE;
194 else
195 return OCFS2_XATTR_SIZE(name_len) + OCFS2_XATTR_SIZE(value_len);
196}
197
198static int namevalue_size_xi(struct ocfs2_xattr_info *xi)
199{
200 return namevalue_size(xi->xi_name_len, xi->xi_value_len);
201}
202
203static int namevalue_size_xe(struct ocfs2_xattr_entry *xe)
204{
205 u64 value_len = le64_to_cpu(xe->xe_value_size);
206
207 BUG_ON((value_len > OCFS2_XATTR_INLINE_SIZE) &&
208 ocfs2_xattr_is_local(xe));
209 return namevalue_size(xe->xe_name_len, value_len);
210}
211
212
186static int ocfs2_xattr_bucket_get_name_value(struct super_block *sb, 213static int ocfs2_xattr_bucket_get_name_value(struct super_block *sb,
187 struct ocfs2_xattr_header *xh, 214 struct ocfs2_xattr_header *xh,
188 int index, 215 int index,
@@ -529,15 +556,20 @@ static void ocfs2_xattr_hash_entry(struct inode *inode,
529 556
530static int ocfs2_xattr_entry_real_size(int name_len, size_t value_len) 557static int ocfs2_xattr_entry_real_size(int name_len, size_t value_len)
531{ 558{
532 int size = 0; 559 return namevalue_size(name_len, value_len) +
560 sizeof(struct ocfs2_xattr_entry);
561}
533 562
534 if (value_len <= OCFS2_XATTR_INLINE_SIZE) 563static int ocfs2_xi_entry_usage(struct ocfs2_xattr_info *xi)
535 size = OCFS2_XATTR_SIZE(name_len) + OCFS2_XATTR_SIZE(value_len); 564{
536 else 565 return namevalue_size_xi(xi) +
537 size = OCFS2_XATTR_SIZE(name_len) + OCFS2_XATTR_ROOT_SIZE; 566 sizeof(struct ocfs2_xattr_entry);
538 size += sizeof(struct ocfs2_xattr_entry); 567}
539 568
540 return size; 569static int ocfs2_xe_entry_usage(struct ocfs2_xattr_entry *xe)
570{
571 return namevalue_size_xe(xe) +
572 sizeof(struct ocfs2_xattr_entry);
541} 573}
542 574
543int ocfs2_calc_security_init(struct inode *dir, 575int ocfs2_calc_security_init(struct inode *dir,
@@ -1363,8 +1395,7 @@ static int ocfs2_xattr_cleanup(struct inode *inode,
1363{ 1395{
1364 int ret = 0; 1396 int ret = 0;
1365 void *val = xs->base + offs; 1397 void *val = xs->base + offs;
1366 size_t size = OCFS2_XATTR_SIZE(xi->xi_name_len) + 1398 size_t size = namevalue_size_xi(xi);
1367 OCFS2_XATTR_ROOT_SIZE;
1368 1399
1369 ret = vb->vb_access(handle, INODE_CACHE(inode), vb->vb_bh, 1400 ret = vb->vb_access(handle, INODE_CACHE(inode), vb->vb_bh,
1370 OCFS2_JOURNAL_ACCESS_WRITE); 1401 OCFS2_JOURNAL_ACCESS_WRITE);
@@ -1430,8 +1461,7 @@ static int ocfs2_xattr_set_value_outside(struct inode *inode,
1430{ 1461{
1431 void *val = xs->base + offs; 1462 void *val = xs->base + offs;
1432 struct ocfs2_xattr_value_root *xv = NULL; 1463 struct ocfs2_xattr_value_root *xv = NULL;
1433 size_t size = OCFS2_XATTR_SIZE(xi->xi_name_len) + 1464 size_t size = namevalue_size_xi(xi);
1434 OCFS2_XATTR_ROOT_SIZE;
1435 int ret = 0; 1465 int ret = 0;
1436 1466
1437 memset(val, 0, size); 1467 memset(val, 0, size);
@@ -1490,15 +1520,10 @@ static void ocfs2_xa_block_wipe_namevalue(struct ocfs2_xa_loc *loc)
1490 int namevalue_offset, first_namevalue_offset, namevalue_size; 1520 int namevalue_offset, first_namevalue_offset, namevalue_size;
1491 struct ocfs2_xattr_entry *entry = loc->xl_entry; 1521 struct ocfs2_xattr_entry *entry = loc->xl_entry;
1492 struct ocfs2_xattr_header *xh = loc->xl_header; 1522 struct ocfs2_xattr_header *xh = loc->xl_header;
1493 u64 value_size = le64_to_cpu(entry->xe_value_size);
1494 int count = le16_to_cpu(xh->xh_count); 1523 int count = le16_to_cpu(xh->xh_count);
1495 1524
1496 namevalue_offset = le16_to_cpu(entry->xe_name_offset); 1525 namevalue_offset = le16_to_cpu(entry->xe_name_offset);
1497 namevalue_size = OCFS2_XATTR_SIZE(entry->xe_name_len); 1526 namevalue_size = namevalue_size_xe(entry);
1498 if (value_size > OCFS2_XATTR_INLINE_SIZE)
1499 namevalue_size += OCFS2_XATTR_ROOT_SIZE;
1500 else
1501 namevalue_size += OCFS2_XATTR_SIZE(value_size);
1502 1527
1503 for (i = 0, first_namevalue_offset = loc->xl_size; 1528 for (i = 0, first_namevalue_offset = loc->xl_size;
1504 i < count; i++) { 1529 i < count; i++) {
@@ -1553,17 +1578,8 @@ static void *ocfs2_xa_bucket_offset_pointer(struct ocfs2_xa_loc *loc,
1553 1578
1554static void ocfs2_xa_bucket_wipe_namevalue(struct ocfs2_xa_loc *loc) 1579static void ocfs2_xa_bucket_wipe_namevalue(struct ocfs2_xa_loc *loc)
1555{ 1580{
1556 int namevalue_size; 1581 le16_add_cpu(&loc->xl_header->xh_name_value_len,
1557 struct ocfs2_xattr_entry *entry = loc->xl_entry; 1582 -namevalue_size_xe(loc->xl_entry));
1558 u64 value_size = le64_to_cpu(entry->xe_value_size);
1559
1560 namevalue_size = OCFS2_XATTR_SIZE(entry->xe_name_len);
1561 if (value_size > OCFS2_XATTR_INLINE_SIZE)
1562 namevalue_size += OCFS2_XATTR_ROOT_SIZE;
1563 else
1564 namevalue_size += OCFS2_XATTR_SIZE(value_size);
1565
1566 le16_add_cpu(&loc->xl_header->xh_name_value_len, -namevalue_size);
1567} 1583}
1568 1584
1569/* Operations for xattrs stored in buckets. */ 1585/* Operations for xattrs stored in buckets. */
@@ -1683,16 +1699,8 @@ static void ocfs2_xattr_set_entry_local(struct inode *inode,
1683 offs = le16_to_cpu(xs->here->xe_name_offset); 1699 offs = le16_to_cpu(xs->here->xe_name_offset);
1684 val = xs->base + offs; 1700 val = xs->base + offs;
1685 1701
1686 if (le64_to_cpu(xs->here->xe_value_size) > 1702 size = namevalue_size_xe(xs->here);
1687 OCFS2_XATTR_INLINE_SIZE) 1703 if (xi->xi_value && (size == namevalue_size_xi(xi))) {
1688 size = OCFS2_XATTR_SIZE(xi->xi_name_len) +
1689 OCFS2_XATTR_ROOT_SIZE;
1690 else
1691 size = OCFS2_XATTR_SIZE(xi->xi_name_len) +
1692 OCFS2_XATTR_SIZE(le64_to_cpu(xs->here->xe_value_size));
1693
1694 if (xi->xi_value && size == OCFS2_XATTR_SIZE(xi->xi_name_len) +
1695 OCFS2_XATTR_SIZE(xi->xi_value_len)) {
1696 /* The old and the new value have the 1704 /* The old and the new value have the
1697 same size. Just replace the value. */ 1705 same size. Just replace the value. */
1698 ocfs2_xattr_set_local(xs->here, 1); 1706 ocfs2_xattr_set_local(xs->here, 1);
@@ -1716,8 +1724,7 @@ static void ocfs2_xattr_set_entry_local(struct inode *inode,
1716 } 1724 }
1717 if (xi->xi_value) { 1725 if (xi->xi_value) {
1718 /* Insert the new name+value. */ 1726 /* Insert the new name+value. */
1719 size_t size = OCFS2_XATTR_SIZE(xi->xi_name_len) + 1727 size_t size = namevalue_size_xi(xi);
1720 OCFS2_XATTR_SIZE(xi->xi_value_len);
1721 void *val = xs->base + min_offs - size; 1728 void *val = xs->base + min_offs - size;
1722 1729
1723 xs->here->xe_name_offset = cpu_to_le16(min_offs - size); 1730 xs->here->xe_name_offset = cpu_to_le16(min_offs - size);
@@ -1788,41 +1795,25 @@ static int ocfs2_xattr_set_entry(struct inode *inode,
1788 if (free < 0) 1795 if (free < 0)
1789 return -EIO; 1796 return -EIO;
1790 1797
1791 if (!xs->not_found) { 1798 if (!xs->not_found)
1792 size_t size = 0; 1799 free += ocfs2_xe_entry_usage(xs->here);
1793 if (ocfs2_xattr_is_local(xs->here)) 1800
1794 size = OCFS2_XATTR_SIZE(xi->xi_name_len) +
1795 OCFS2_XATTR_SIZE(le64_to_cpu(xs->here->xe_value_size));
1796 else
1797 size = OCFS2_XATTR_SIZE(xi->xi_name_len) +
1798 OCFS2_XATTR_ROOT_SIZE;
1799 free += (size + sizeof(struct ocfs2_xattr_entry));
1800 }
1801 /* Check free space in inode or block */ 1801 /* Check free space in inode or block */
1802 if (xi->xi_value && xi->xi_value_len > OCFS2_XATTR_INLINE_SIZE) { 1802 if (xi->xi_value) {
1803 if (free < sizeof(struct ocfs2_xattr_entry) + 1803 if (free < ocfs2_xi_entry_usage(xi)) {
1804 OCFS2_XATTR_SIZE(xi->xi_name_len) +
1805 OCFS2_XATTR_ROOT_SIZE) {
1806 ret = -ENOSPC; 1804 ret = -ENOSPC;
1807 goto out; 1805 goto out;
1808 } 1806 }
1809 size_l = OCFS2_XATTR_SIZE(xi->xi_name_len) + 1807 if (xi->xi_value_len > OCFS2_XATTR_INLINE_SIZE) {
1810 OCFS2_XATTR_ROOT_SIZE; 1808 size_l = namevalue_size_xi(xi);
1811 xi_l.xi_value = (void *)&def_xv; 1809 xi_l.xi_value = (void *)&def_xv;
1812 xi_l.xi_value_len = OCFS2_XATTR_ROOT_SIZE; 1810 xi_l.xi_value_len = OCFS2_XATTR_ROOT_SIZE;
1813 } else if (xi->xi_value) {
1814 if (free < sizeof(struct ocfs2_xattr_entry) +
1815 OCFS2_XATTR_SIZE(xi->xi_name_len) +
1816 OCFS2_XATTR_SIZE(xi->xi_value_len)) {
1817 ret = -ENOSPC;
1818 goto out;
1819 } 1811 }
1820 } 1812 }
1821 1813
1822 if (!xs->not_found) { 1814 if (!xs->not_found) {
1823 /* For existing extended attribute */ 1815 /* For existing extended attribute */
1824 size_t size = OCFS2_XATTR_SIZE(xi->xi_name_len) + 1816 size_t size = namevalue_size_xe(xs->here);
1825 OCFS2_XATTR_SIZE(le64_to_cpu(xs->here->xe_value_size));
1826 size_t offs = le16_to_cpu(xs->here->xe_name_offset); 1817 size_t offs = le16_to_cpu(xs->here->xe_name_offset);
1827 void *val = xs->base + offs; 1818 void *val = xs->base + offs;
1828 1819
@@ -2589,7 +2580,6 @@ static int ocfs2_xattr_can_be_in_inode(struct inode *inode,
2589 struct ocfs2_xattr_info *xi, 2580 struct ocfs2_xattr_info *xi,
2590 struct ocfs2_xattr_search *xs) 2581 struct ocfs2_xattr_search *xs)
2591{ 2582{
2592 u64 value_size;
2593 struct ocfs2_xattr_entry *last; 2583 struct ocfs2_xattr_entry *last;
2594 int free, i; 2584 int free, i;
2595 size_t min_offs = xs->end - xs->base; 2585 size_t min_offs = xs->end - xs->base;
@@ -2612,13 +2602,7 @@ static int ocfs2_xattr_can_be_in_inode(struct inode *inode,
2612 2602
2613 BUG_ON(!xs->not_found); 2603 BUG_ON(!xs->not_found);
2614 2604
2615 if (xi->xi_value_len > OCFS2_XATTR_INLINE_SIZE) 2605 if (free >= (sizeof(struct ocfs2_xattr_entry) + namevalue_size_xi(xi)))
2616 value_size = OCFS2_XATTR_ROOT_SIZE;
2617 else
2618 value_size = OCFS2_XATTR_SIZE(xi->xi_value_len);
2619
2620 if (free >= sizeof(struct ocfs2_xattr_entry) +
2621 OCFS2_XATTR_SIZE(xi->xi_name_len) + value_size)
2622 return 1; 2606 return 1;
2623 2607
2624 return 0; 2608 return 0;
@@ -3980,7 +3964,7 @@ static int ocfs2_defrag_xattr_bucket(struct inode *inode,
3980 struct ocfs2_xattr_bucket *bucket) 3964 struct ocfs2_xattr_bucket *bucket)
3981{ 3965{
3982 int ret, i; 3966 int ret, i;
3983 size_t end, offset, len, value_len; 3967 size_t end, offset, len;
3984 struct ocfs2_xattr_header *xh; 3968 struct ocfs2_xattr_header *xh;
3985 char *entries, *buf, *bucket_buf = NULL; 3969 char *entries, *buf, *bucket_buf = NULL;
3986 u64 blkno = bucket_blkno(bucket); 3970 u64 blkno = bucket_blkno(bucket);
@@ -4034,12 +4018,7 @@ static int ocfs2_defrag_xattr_bucket(struct inode *inode,
4034 end = OCFS2_XATTR_BUCKET_SIZE; 4018 end = OCFS2_XATTR_BUCKET_SIZE;
4035 for (i = 0; i < le16_to_cpu(xh->xh_count); i++, xe++) { 4019 for (i = 0; i < le16_to_cpu(xh->xh_count); i++, xe++) {
4036 offset = le16_to_cpu(xe->xe_name_offset); 4020 offset = le16_to_cpu(xe->xe_name_offset);
4037 if (ocfs2_xattr_is_local(xe)) 4021 len = namevalue_size_xe(xe);
4038 value_len = OCFS2_XATTR_SIZE(
4039 le64_to_cpu(xe->xe_value_size));
4040 else
4041 value_len = OCFS2_XATTR_ROOT_SIZE;
4042 len = OCFS2_XATTR_SIZE(xe->xe_name_len) + value_len;
4043 4022
4044 /* 4023 /*
4045 * We must make sure that the name/value pair 4024 * We must make sure that the name/value pair
@@ -4228,7 +4207,7 @@ static int ocfs2_divide_xattr_bucket(struct inode *inode,
4228 int new_bucket_head) 4207 int new_bucket_head)
4229{ 4208{
4230 int ret, i; 4209 int ret, i;
4231 int count, start, len, name_value_len = 0, xe_len, name_offset = 0; 4210 int count, start, len, name_value_len = 0, name_offset = 0;
4232 struct ocfs2_xattr_bucket *s_bucket = NULL, *t_bucket = NULL; 4211 struct ocfs2_xattr_bucket *s_bucket = NULL, *t_bucket = NULL;
4233 struct ocfs2_xattr_header *xh; 4212 struct ocfs2_xattr_header *xh;
4234 struct ocfs2_xattr_entry *xe; 4213 struct ocfs2_xattr_entry *xe;
@@ -4319,13 +4298,7 @@ static int ocfs2_divide_xattr_bucket(struct inode *inode,
4319 name_value_len = 0; 4298 name_value_len = 0;
4320 for (i = 0; i < start; i++) { 4299 for (i = 0; i < start; i++) {
4321 xe = &xh->xh_entries[i]; 4300 xe = &xh->xh_entries[i];
4322 xe_len = OCFS2_XATTR_SIZE(xe->xe_name_len); 4301 name_value_len += namevalue_size_xe(xe);
4323 if (ocfs2_xattr_is_local(xe))
4324 xe_len +=
4325 OCFS2_XATTR_SIZE(le64_to_cpu(xe->xe_value_size));
4326 else
4327 xe_len += OCFS2_XATTR_ROOT_SIZE;
4328 name_value_len += xe_len;
4329 if (le16_to_cpu(xe->xe_name_offset) < name_offset) 4302 if (le16_to_cpu(xe->xe_name_offset) < name_offset)
4330 name_offset = le16_to_cpu(xe->xe_name_offset); 4303 name_offset = le16_to_cpu(xe->xe_name_offset);
4331 } 4304 }
@@ -4355,12 +4328,6 @@ static int ocfs2_divide_xattr_bucket(struct inode *inode,
4355 xh->xh_free_start = cpu_to_le16(OCFS2_XATTR_BUCKET_SIZE); 4328 xh->xh_free_start = cpu_to_le16(OCFS2_XATTR_BUCKET_SIZE);
4356 for (i = 0; i < le16_to_cpu(xh->xh_count); i++) { 4329 for (i = 0; i < le16_to_cpu(xh->xh_count); i++) {
4357 xe = &xh->xh_entries[i]; 4330 xe = &xh->xh_entries[i];
4358 xe_len = OCFS2_XATTR_SIZE(xe->xe_name_len);
4359 if (ocfs2_xattr_is_local(xe))
4360 xe_len +=
4361 OCFS2_XATTR_SIZE(le64_to_cpu(xe->xe_value_size));
4362 else
4363 xe_len += OCFS2_XATTR_ROOT_SIZE;
4364 if (le16_to_cpu(xe->xe_name_offset) < 4331 if (le16_to_cpu(xe->xe_name_offset) <
4365 le16_to_cpu(xh->xh_free_start)) 4332 le16_to_cpu(xh->xh_free_start))
4366 xh->xh_free_start = xe->xe_name_offset; 4333 xh->xh_free_start = xe->xe_name_offset;
@@ -4997,12 +4964,7 @@ static void ocfs2_xattr_set_entry_normal(struct inode *inode,
4997 if (!xs->not_found) { 4964 if (!xs->not_found) {
4998 xe = xs->here; 4965 xe = xs->here;
4999 offs = le16_to_cpu(xe->xe_name_offset); 4966 offs = le16_to_cpu(xe->xe_name_offset);
5000 if (ocfs2_xattr_is_local(xe)) 4967 size = namevalue_size_xe(xe);
5001 size = OCFS2_XATTR_SIZE(xi->xi_name_len) +
5002 OCFS2_XATTR_SIZE(le64_to_cpu(xe->xe_value_size));
5003 else
5004 size = OCFS2_XATTR_SIZE(xi->xi_name_len) +
5005 OCFS2_XATTR_SIZE(OCFS2_XATTR_ROOT_SIZE);
5006 4968
5007 /* 4969 /*
5008 * If the new value will be stored outside, xi->xi_value has 4970 * If the new value will be stored outside, xi->xi_value has
@@ -5011,8 +4973,7 @@ static void ocfs2_xattr_set_entry_normal(struct inode *inode,
5011 * new_size safely here. 4973 * new_size safely here.
5012 * See ocfs2_xattr_set_in_bucket. 4974 * See ocfs2_xattr_set_in_bucket.
5013 */ 4975 */
5014 new_size = OCFS2_XATTR_SIZE(xi->xi_name_len) + 4976 new_size = namevalue_size_xi(xi);
5015 OCFS2_XATTR_SIZE(xi->xi_value_len);
5016 4977
5017 if (xi->xi_value) { 4978 if (xi->xi_value) {
5018 ocfs2_xa_wipe_namevalue(&loc); 4979 ocfs2_xa_wipe_namevalue(&loc);
@@ -5078,8 +5039,7 @@ static void ocfs2_xattr_set_entry_normal(struct inode *inode,
5078 5039
5079set_new_name_value: 5040set_new_name_value:
5080 /* Insert the new name+value. */ 5041 /* Insert the new name+value. */
5081 size = OCFS2_XATTR_SIZE(xi->xi_name_len) + 5042 size = namevalue_size_xi(xi);
5082 OCFS2_XATTR_SIZE(xi->xi_value_len);
5083 5043
5084 /* 5044 /*
5085 * We must make sure that the name/value pair 5045 * We must make sure that the name/value pair