aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/xattr.c
diff options
context:
space:
mode:
authorJoel Becker <joel.becker@oracle.com>2009-08-17 22:56:01 -0400
committerJoel Becker <joel.becker@oracle.com>2010-02-26 18:41:10 -0500
commit9dc474005d0e34cf21d4b510f347e3942f24b021 (patch)
treef19e028c6f500802623a5c8256c64e434a79a2be /fs/ocfs2/xattr.c
parent69a3e539d083ac09aec92b8705b8ff2c2e5c810c (diff)
ocfs2: Handle value tree roots in ocfs2_xa_set_inline_value()
Previously the xattr code would send in a fake value, containing a tree root, to the function that installed name+value pairs. Instead, we pass the real value to ocfs2_xa_set_inline_value(), and it notices that the value cannot fit. Thus, it installs a tree root. Signed-off-by: Joel Becker <joel.becker@oracle.com>
Diffstat (limited to 'fs/ocfs2/xattr.c')
-rw-r--r--fs/ocfs2/xattr.c54
1 files changed, 16 insertions, 38 deletions
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c
index 4bf6ec849e1..6d362e2d396 100644
--- a/fs/ocfs2/xattr.c
+++ b/fs/ocfs2/xattr.c
@@ -1968,14 +1968,19 @@ static void ocfs2_xa_store_inline_value(struct ocfs2_xa_loc *loc,
1968{ 1968{
1969 int nameval_offset = le16_to_cpu(loc->xl_entry->xe_name_offset); 1969 int nameval_offset = le16_to_cpu(loc->xl_entry->xe_name_offset);
1970 int name_size = OCFS2_XATTR_SIZE(xi->xi_name_len); 1970 int name_size = OCFS2_XATTR_SIZE(xi->xi_name_len);
1971 int size = namevalue_size_xi(xi); 1971 int inline_value_size = namevalue_size_xi(xi) - name_size;
1972 const void *value = xi->xi_value;
1972 char *nameval_buf; 1973 char *nameval_buf;
1973 1974
1974 if (!xi->xi_value) 1975 if (!xi->xi_value)
1975 return; 1976 return;
1976 1977
1978 if (xi->xi_value_len > OCFS2_XATTR_INLINE_SIZE) {
1979 value = &def_xv;
1980 inline_value_size = OCFS2_XATTR_ROOT_SIZE;
1981 }
1977 nameval_buf = ocfs2_xa_offset_pointer(loc, nameval_offset); 1982 nameval_buf = ocfs2_xa_offset_pointer(loc, nameval_offset);
1978 memcpy(nameval_buf + name_size, xi->xi_value, size - name_size); 1983 memcpy(nameval_buf + name_size, value, inline_value_size);
1979} 1984}
1980 1985
1981static void ocfs2_init_dinode_xa_loc(struct ocfs2_xa_loc *loc, 1986static void ocfs2_init_dinode_xa_loc(struct ocfs2_xa_loc *loc,
@@ -2054,13 +2059,6 @@ static int ocfs2_xattr_set_entry(struct inode *inode,
2054 u32 name_hash = ocfs2_xattr_name_hash(inode, xi->xi_name, 2059 u32 name_hash = ocfs2_xattr_name_hash(inode, xi->xi_name,
2055 xi->xi_name_len); 2060 xi->xi_name_len);
2056 struct ocfs2_xa_loc loc; 2061 struct ocfs2_xa_loc loc;
2057 struct ocfs2_xattr_info xi_l = {
2058 .xi_name_index = xi->xi_name_index,
2059 .xi_name = xi->xi_name,
2060 .xi_name_len = xi->xi_name_len,
2061 .xi_value = xi->xi_value,
2062 .xi_value_len = xi->xi_value_len,
2063 };
2064 struct ocfs2_xattr_value_buf vb = { 2062 struct ocfs2_xattr_value_buf vb = {
2065 .vb_bh = xs->xattr_bh, 2063 .vb_bh = xs->xattr_bh,
2066 .vb_access = ocfs2_journal_access_di, 2064 .vb_access = ocfs2_journal_access_di,
@@ -2090,16 +2088,9 @@ static int ocfs2_xattr_set_entry(struct inode *inode,
2090 free += ocfs2_xe_entry_usage(xs->here); 2088 free += ocfs2_xe_entry_usage(xs->here);
2091 2089
2092 /* Check free space in inode or block */ 2090 /* Check free space in inode or block */
2093 if (xi->xi_value) { 2091 if (xi->xi_value && (free < ocfs2_xi_entry_usage(xi))) {
2094 if (free < ocfs2_xi_entry_usage(xi)) { 2092 ret = -ENOSPC;
2095 ret = -ENOSPC; 2093 goto out;
2096 goto out;
2097 }
2098 if (xi->xi_value_len > OCFS2_XATTR_INLINE_SIZE) {
2099 size_l = namevalue_size_xi(xi);
2100 xi_l.xi_value = (void *)&def_xv;
2101 xi_l.xi_value_len = OCFS2_XATTR_ROOT_SIZE;
2102 }
2103 } 2094 }
2104 2095
2105 if (!xs->not_found) { 2096 if (!xs->not_found) {
@@ -5255,8 +5246,7 @@ static int ocfs2_xattr_set_entry_in_bucket(struct inode *inode,
5255 handle_t *handle, 5246 handle_t *handle,
5256 struct ocfs2_xattr_info *xi, 5247 struct ocfs2_xattr_info *xi,
5257 struct ocfs2_xattr_search *xs, 5248 struct ocfs2_xattr_search *xs,
5258 u32 name_hash, 5249 u32 name_hash)
5259 int local)
5260{ 5250{
5261 int ret; 5251 int ret;
5262 u64 blkno; 5252 u64 blkno;
@@ -5571,13 +5561,14 @@ static int ocfs2_xattr_set_in_bucket(struct inode *inode,
5571 struct ocfs2_xattr_search *xs, 5561 struct ocfs2_xattr_search *xs,
5572 struct ocfs2_xattr_set_ctxt *ctxt) 5562 struct ocfs2_xattr_set_ctxt *ctxt)
5573{ 5563{
5574 int ret, local = 1; 5564 int ret;
5575 size_t value_len; 5565 size_t value_len;
5576 char *val = (char *)xi->xi_value; 5566 char *val = (char *)xi->xi_value;
5577 struct ocfs2_xattr_entry *xe = xs->here; 5567 struct ocfs2_xattr_entry *xe = xs->here;
5578 u32 name_hash = ocfs2_xattr_name_hash(inode, xi->xi_name, 5568 u32 name_hash = ocfs2_xattr_name_hash(inode, xi->xi_name,
5579 xi->xi_name_len); 5569 xi->xi_name_len);
5580 5570
5571 value_len = xi->xi_value_len;
5581 if (!xs->not_found && !ocfs2_xattr_is_local(xe)) { 5572 if (!xs->not_found && !ocfs2_xattr_is_local(xe)) {
5582 /* 5573 /*
5583 * We need to truncate the xattr storage first. 5574 * We need to truncate the xattr storage first.
@@ -5591,9 +5582,7 @@ static int ocfs2_xattr_set_in_bucket(struct inode *inode,
5591 * the modification to the xattr block will be done 5582 * the modification to the xattr block will be done
5592 * by following steps. 5583 * by following steps.
5593 */ 5584 */
5594 if (xi->xi_value_len > OCFS2_XATTR_INLINE_SIZE) 5585 if (xi->xi_value_len <= OCFS2_XATTR_INLINE_SIZE)
5595 value_len = xi->xi_value_len;
5596 else
5597 value_len = 0; 5586 value_len = 0;
5598 5587
5599 ret = ocfs2_xattr_bucket_value_truncate_xs(inode, xs, 5588 ret = ocfs2_xattr_bucket_value_truncate_xs(inode, xs,
@@ -5606,26 +5595,15 @@ static int ocfs2_xattr_set_in_bucket(struct inode *inode,
5606 goto set_value_outside; 5595 goto set_value_outside;
5607 } 5596 }
5608 5597
5609 value_len = xi->xi_value_len;
5610 /* So we have to handle the inside block change now. */ 5598 /* So we have to handle the inside block change now. */
5611 if (value_len > OCFS2_XATTR_INLINE_SIZE) {
5612 /*
5613 * If the new value will be stored outside of block,
5614 * initalize a new empty value root and insert it first.
5615 */
5616 local = 0;
5617 xi->xi_value = &def_xv;
5618 xi->xi_value_len = OCFS2_XATTR_ROOT_SIZE;
5619 }
5620
5621 ret = ocfs2_xattr_set_entry_in_bucket(inode, ctxt->handle, xi, xs, 5599 ret = ocfs2_xattr_set_entry_in_bucket(inode, ctxt->handle, xi, xs,
5622 name_hash, local); 5600 name_hash);
5623 if (ret) { 5601 if (ret) {
5624 mlog_errno(ret); 5602 mlog_errno(ret);
5625 goto out; 5603 goto out;
5626 } 5604 }
5627 5605
5628 if (value_len <= OCFS2_XATTR_INLINE_SIZE) 5606 if (xi->xi_value_len <= OCFS2_XATTR_INLINE_SIZE)
5629 goto out; 5607 goto out;
5630 5608
5631 /* allocate the space now for the outside block storage. */ 5609 /* allocate the space now for the outside block storage. */