aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/xattr.c
diff options
context:
space:
mode:
authorJoel Becker <joel.becker@oracle.com>2009-08-18 23:26:41 -0400
committerJoel Becker <joel.becker@oracle.com>2010-02-26 18:41:11 -0500
commit73857ee0b548017f9632a0d0e6fe2dabbdc11d31 (patch)
treef073a4e84c3df446f6ed2dd5c58ff27708b51dd0 /fs/ocfs2/xattr.c
parentcf2bc809403ae48a4a2bb5cc551d2ec35f2e4a47 (diff)
ocfs2: Allocation in ocfs2_xa_prepare_entry(), values in ocfs2_xa_store_value()
ocfs2_xa_prepare_entry() gets all the logic to add, remove, or modify external value trees. Now, when it exits, the entry is ready to receive a value of any size. ocfs2_xa_remove() is added to handle the complete removal of an entry. It truncates the external value tree before calling ocfs2_xa_remove_entry(). ocfs2_xa_store_inline_value() becomes ocfs2_xa_store_value(). It can store any value. ocfs2_xattr_set_entry() loses all the allocation logic and just uses these functions. ocfs2_xattr_set_value_outside() disappears. ocfs2_xattr_set_in_bucket() uses these functions and makes ocfs2_xattr_set_entry_in_bucket() obsolete. That goes away, as does ocfs2_xattr_bucket_set_value_outside() and ocfs2_xattr_bucket_value_truncate(). Signed-off-by: Joel Becker <joel.becker@oracle.com>
Diffstat (limited to 'fs/ocfs2/xattr.c')
-rw-r--r--fs/ocfs2/xattr.c661
1 files changed, 186 insertions, 475 deletions
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c
index fbec11610223..550a3e86c971 100644
--- a/fs/ocfs2/xattr.c
+++ b/fs/ocfs2/xattr.c
@@ -573,24 +573,6 @@ static u32 ocfs2_xattr_name_hash(struct inode *inode,
573 return hash; 573 return hash;
574} 574}
575 575
576/*
577 * ocfs2_xattr_hash_entry()
578 *
579 * Compute the hash of an extended attribute.
580 */
581static void ocfs2_xattr_hash_entry(struct inode *inode,
582 struct ocfs2_xattr_header *header,
583 struct ocfs2_xattr_entry *entry)
584{
585 u32 hash = 0;
586 char *name = (char *)header + le16_to_cpu(entry->xe_name_offset);
587
588 hash = ocfs2_xattr_name_hash(inode, name, entry->xe_name_len);
589 entry->xe_name_hash = cpu_to_le32(hash);
590
591 return;
592}
593
594static int ocfs2_xattr_entry_real_size(int name_len, size_t value_len) 576static int ocfs2_xattr_entry_real_size(int name_len, size_t value_len)
595{ 577{
596 return namevalue_size(name_len, value_len) + 578 return namevalue_size(name_len, value_len) +
@@ -1423,113 +1405,6 @@ out:
1423 return ret; 1405 return ret;
1424} 1406}
1425 1407
1426static int ocfs2_xattr_cleanup(struct inode *inode,
1427 handle_t *handle,
1428 struct ocfs2_xattr_info *xi,
1429 struct ocfs2_xattr_search *xs,
1430 struct ocfs2_xattr_value_buf *vb,
1431 size_t offs)
1432{
1433 int ret = 0;
1434 void *val = xs->base + offs;
1435 size_t size = namevalue_size_xi(xi);
1436
1437 ret = vb->vb_access(handle, INODE_CACHE(inode), vb->vb_bh,
1438 OCFS2_JOURNAL_ACCESS_WRITE);
1439 if (ret) {
1440 mlog_errno(ret);
1441 goto out;
1442 }
1443 /* Decrease xattr count */
1444 le16_add_cpu(&xs->header->xh_count, -1);
1445 /* Remove the xattr entry and tree root which has already be set*/
1446 memset((void *)xs->here, 0, sizeof(struct ocfs2_xattr_entry));
1447 memset(val, 0, size);
1448
1449 ret = ocfs2_journal_dirty(handle, vb->vb_bh);
1450 if (ret < 0)
1451 mlog_errno(ret);
1452out:
1453 return ret;
1454}
1455
1456static int ocfs2_xattr_update_entry(struct inode *inode,
1457 handle_t *handle,
1458 struct ocfs2_xattr_info *xi,
1459 struct ocfs2_xattr_search *xs,
1460 struct ocfs2_xattr_value_buf *vb,
1461 size_t offs)
1462{
1463 int ret;
1464
1465 ret = vb->vb_access(handle, INODE_CACHE(inode), vb->vb_bh,
1466 OCFS2_JOURNAL_ACCESS_WRITE);
1467 if (ret) {
1468 mlog_errno(ret);
1469 goto out;
1470 }
1471
1472 xs->here->xe_name_offset = cpu_to_le16(offs);
1473 xs->here->xe_value_size = cpu_to_le64(xi->xi_value_len);
1474 if (xi->xi_value_len <= OCFS2_XATTR_INLINE_SIZE)
1475 ocfs2_xattr_set_local(xs->here, 1);
1476 else
1477 ocfs2_xattr_set_local(xs->here, 0);
1478 ocfs2_xattr_hash_entry(inode, xs->header, xs->here);
1479
1480 ret = ocfs2_journal_dirty(handle, vb->vb_bh);
1481 if (ret < 0)
1482 mlog_errno(ret);
1483out:
1484 return ret;
1485}
1486
1487/*
1488 * ocfs2_xattr_set_value_outside()
1489 *
1490 * Set large size value in B tree.
1491 */
1492static int ocfs2_xattr_set_value_outside(struct inode *inode,
1493 struct ocfs2_xattr_info *xi,
1494 struct ocfs2_xattr_search *xs,
1495 struct ocfs2_xattr_set_ctxt *ctxt,
1496 struct ocfs2_xattr_value_buf *vb,
1497 size_t offs)
1498{
1499 void *val = xs->base + offs;
1500 struct ocfs2_xattr_value_root *xv = NULL;
1501 size_t size = namevalue_size_xi(xi);
1502 int ret = 0;
1503
1504 memset(val, 0, size);
1505 memcpy(val, xi->xi_name, xi->xi_name_len);
1506 xv = (struct ocfs2_xattr_value_root *)
1507 (val + OCFS2_XATTR_SIZE(xi->xi_name_len));
1508 xv->xr_clusters = 0;
1509 xv->xr_last_eb_blk = 0;
1510 xv->xr_list.l_tree_depth = 0;
1511 xv->xr_list.l_count = cpu_to_le16(1);
1512 xv->xr_list.l_next_free_rec = 0;
1513 vb->vb_xv = xv;
1514
1515 ret = ocfs2_xattr_value_truncate(inode, vb, xi->xi_value_len, ctxt);
1516 if (ret < 0) {
1517 mlog_errno(ret);
1518 return ret;
1519 }
1520 ret = ocfs2_xattr_update_entry(inode, ctxt->handle, xi, xs, vb, offs);
1521 if (ret < 0) {
1522 mlog_errno(ret);
1523 return ret;
1524 }
1525 ret = __ocfs2_xattr_set_value_outside(inode, ctxt->handle, vb,
1526 xi->xi_value, xi->xi_value_len);
1527 if (ret < 0)
1528 mlog_errno(ret);
1529
1530 return ret;
1531}
1532
1533static int ocfs2_xa_check_space_helper(int needed_space, int free_start, 1408static int ocfs2_xa_check_space_helper(int needed_space, int free_start,
1534 int num_entries) 1409 int num_entries)
1535{ 1410{
@@ -1640,6 +1515,7 @@ static void ocfs2_xa_fill_value_buf(struct ocfs2_xa_loc *loc,
1640 int name_size = OCFS2_XATTR_SIZE(loc->xl_entry->xe_name_len); 1515 int name_size = OCFS2_XATTR_SIZE(loc->xl_entry->xe_name_len);
1641 1516
1642 /* Value bufs are for value trees */ 1517 /* Value bufs are for value trees */
1518 BUG_ON(ocfs2_xattr_is_local(loc->xl_entry));
1643 BUG_ON(namevalue_size_xe(loc->xl_entry) != 1519 BUG_ON(namevalue_size_xe(loc->xl_entry) !=
1644 (name_size + OCFS2_XATTR_ROOT_SIZE)); 1520 (name_size + OCFS2_XATTR_ROOT_SIZE));
1645 1521
@@ -2001,6 +1877,33 @@ static const struct ocfs2_xa_loc_operations ocfs2_xa_bucket_loc_ops = {
2001 .xlo_fill_value_buf = ocfs2_xa_bucket_fill_value_buf, 1877 .xlo_fill_value_buf = ocfs2_xa_bucket_fill_value_buf,
2002}; 1878};
2003 1879
1880static int ocfs2_xa_value_truncate(struct ocfs2_xa_loc *loc, u64 bytes,
1881 struct ocfs2_xattr_set_ctxt *ctxt)
1882{
1883 int trunc_rc, access_rc;
1884 struct ocfs2_xattr_value_buf vb;
1885
1886 ocfs2_xa_fill_value_buf(loc, &vb);
1887 trunc_rc = ocfs2_xattr_value_truncate(loc->xl_inode, &vb, bytes,
1888 ctxt);
1889
1890 /*
1891 * The caller of ocfs2_xa_value_truncate() has already called
1892 * ocfs2_xa_journal_access on the loc. However, The truncate code
1893 * calls ocfs2_extend_trans(). This may commit the previous
1894 * transaction and open a new one. If this is a bucket, truncate
1895 * could leave only vb->vb_bh set up for journaling. Meanwhile,
1896 * the caller is expecting to dirty the entire bucket. So we must
1897 * reset the journal work. We do this even if truncate has failed,
1898 * as it could have failed after committing the extend.
1899 */
1900 access_rc = ocfs2_xa_journal_access(ctxt->handle, loc,
1901 OCFS2_JOURNAL_ACCESS_WRITE);
1902
1903 /* Errors in truncate take precedence */
1904 return trunc_rc ? trunc_rc : access_rc;
1905}
1906
2004static void ocfs2_xa_remove_entry(struct ocfs2_xa_loc *loc) 1907static void ocfs2_xa_remove_entry(struct ocfs2_xa_loc *loc)
2005{ 1908{
2006 int index, count; 1909 int index, count;
@@ -2028,6 +1931,88 @@ static void ocfs2_xa_remove_entry(struct ocfs2_xa_loc *loc)
2028 } 1931 }
2029} 1932}
2030 1933
1934static int ocfs2_xa_remove(struct ocfs2_xa_loc *loc,
1935 struct ocfs2_xattr_set_ctxt *ctxt)
1936{
1937 int rc = 0;
1938
1939 if (!ocfs2_xattr_is_local(loc->xl_entry)) {
1940 rc = ocfs2_xa_value_truncate(loc, 0, ctxt);
1941 if (rc) {
1942 mlog_errno(rc);
1943 goto out;
1944 }
1945 }
1946
1947 ocfs2_xa_remove_entry(loc);
1948
1949out:
1950 return rc;
1951}
1952
1953static void ocfs2_xa_install_value_root(struct ocfs2_xa_loc *loc)
1954{
1955 int name_size = OCFS2_XATTR_SIZE(loc->xl_entry->xe_name_len);
1956 char *nameval_buf;
1957
1958 nameval_buf = ocfs2_xa_offset_pointer(loc,
1959 le16_to_cpu(loc->xl_entry->xe_name_offset));
1960 memcpy(nameval_buf + name_size, &def_xv, OCFS2_XATTR_ROOT_SIZE);
1961}
1962
1963/*
1964 * Take an existing entry and make it ready for the new value. This
1965 * won't allocate space, but it may free space. It should be ready for
1966 * ocfs2_xa_prepare_entry() to finish the work.
1967 */
1968static int ocfs2_xa_reuse_entry(struct ocfs2_xa_loc *loc,
1969 struct ocfs2_xattr_info *xi,
1970 struct ocfs2_xattr_set_ctxt *ctxt)
1971{
1972 int rc = 0;
1973 int name_size = OCFS2_XATTR_SIZE(xi->xi_name_len);
1974 char *nameval_buf;
1975 int xe_local = ocfs2_xattr_is_local(loc->xl_entry);
1976 int xi_local = xi->xi_value_len <= OCFS2_XATTR_INLINE_SIZE;
1977
1978 BUG_ON(OCFS2_XATTR_SIZE(loc->xl_entry->xe_name_len) !=
1979 name_size);
1980
1981 nameval_buf = ocfs2_xa_offset_pointer(loc,
1982 le16_to_cpu(loc->xl_entry->xe_name_offset));
1983 if (xe_local) {
1984 memset(nameval_buf + name_size, 0,
1985 namevalue_size_xe(loc->xl_entry) - name_size);
1986 if (!xi_local)
1987 ocfs2_xa_install_value_root(loc);
1988 } else {
1989 if (xi_local) {
1990 rc = ocfs2_xa_value_truncate(loc, 0, ctxt);
1991 if (rc < 0) {
1992 mlog_errno(rc);
1993 goto out;
1994 }
1995 memset(nameval_buf + name_size, 0,
1996 namevalue_size_xe(loc->xl_entry) -
1997 name_size);
1998 } else if (le64_to_cpu(loc->xl_entry->xe_value_size) >
1999 xi->xi_value_len) {
2000 rc = ocfs2_xa_value_truncate(loc, xi->xi_value_len,
2001 ctxt);
2002 if (rc < 0) {
2003 mlog_errno(rc);
2004 goto out;
2005 }
2006 }
2007 }
2008
2009 loc->xl_entry->xe_value_size = cpu_to_le64(xi->xi_value_len);
2010 ocfs2_xattr_set_local(loc->xl_entry, xi_local);
2011
2012out:
2013 return rc;
2014}
2015
2031/* 2016/*
2032 * Prepares loc->xl_entry to receive the new xattr. This includes 2017 * Prepares loc->xl_entry to receive the new xattr. This includes
2033 * properly setting up the name+value pair region. If loc->xl_entry 2018 * properly setting up the name+value pair region. If loc->xl_entry
@@ -2040,14 +2025,13 @@ static void ocfs2_xa_remove_entry(struct ocfs2_xa_loc *loc)
2040 */ 2025 */
2041static int ocfs2_xa_prepare_entry(struct ocfs2_xa_loc *loc, 2026static int ocfs2_xa_prepare_entry(struct ocfs2_xa_loc *loc,
2042 struct ocfs2_xattr_info *xi, 2027 struct ocfs2_xattr_info *xi,
2043 u32 name_hash) 2028 u32 name_hash,
2029 struct ocfs2_xattr_set_ctxt *ctxt)
2044{ 2030{
2045 int rc = 0; 2031 int rc = 0;
2046 int name_size = OCFS2_XATTR_SIZE(xi->xi_name_len);
2047 char *nameval_buf;
2048 2032
2049 if (!xi->xi_value) { 2033 if (!xi->xi_value) {
2050 ocfs2_xa_remove_entry(loc); 2034 rc = ocfs2_xa_remove(loc, ctxt);
2051 goto out; 2035 goto out;
2052 } 2036 }
2053 2037
@@ -2057,15 +2041,19 @@ static int ocfs2_xa_prepare_entry(struct ocfs2_xa_loc *loc,
2057 2041
2058 if (loc->xl_entry) { 2042 if (loc->xl_entry) {
2059 if (ocfs2_xa_can_reuse_entry(loc, xi)) { 2043 if (ocfs2_xa_can_reuse_entry(loc, xi)) {
2060 nameval_buf = ocfs2_xa_offset_pointer(loc, 2044 rc = ocfs2_xa_reuse_entry(loc, xi, ctxt);
2061 le16_to_cpu(loc->xl_entry->xe_name_offset)); 2045 if (rc)
2062 memset(nameval_buf + name_size, 0, 2046 goto out;
2063 namevalue_size_xe(loc->xl_entry) - name_size); 2047 goto alloc_value;
2064 loc->xl_entry->xe_value_size =
2065 cpu_to_le64(xi->xi_value_len);
2066 goto out;
2067 } 2048 }
2068 2049
2050 if (!ocfs2_xattr_is_local(loc->xl_entry)) {
2051 rc = ocfs2_xa_value_truncate(loc, 0, ctxt);
2052 if (rc) {
2053 mlog_errno(rc);
2054 goto out;
2055 }
2056 }
2069 ocfs2_xa_wipe_namevalue(loc); 2057 ocfs2_xa_wipe_namevalue(loc);
2070 } else 2058 } else
2071 ocfs2_xa_add_entry(loc, name_hash); 2059 ocfs2_xa_add_entry(loc, name_hash);
@@ -2075,33 +2063,50 @@ static int ocfs2_xa_prepare_entry(struct ocfs2_xa_loc *loc,
2075 * name+value pair back from the end. 2063 * name+value pair back from the end.
2076 */ 2064 */
2077 ocfs2_xa_add_namevalue(loc, xi); 2065 ocfs2_xa_add_namevalue(loc, xi);
2066 if (xi->xi_value_len > OCFS2_XATTR_INLINE_SIZE)
2067 ocfs2_xa_install_value_root(loc);
2068
2069alloc_value:
2070 if (xi->xi_value_len > OCFS2_XATTR_INLINE_SIZE) {
2071 rc = ocfs2_xa_value_truncate(loc, xi->xi_value_len, ctxt);
2072 if (rc < 0)
2073 mlog_errno(rc);
2074 }
2078 2075
2079out: 2076out:
2080 return rc; 2077 return rc;
2081} 2078}
2082 2079
2083/* 2080/*
2084 * Store the value portion of the name+value pair. This is either an 2081 * Store the value portion of the name+value pair. This will skip
2085 * inline value or the tree root of an external value. 2082 * values that are stored externally. Their tree roots were set up
2083 * by ocfs2_xa_prepare_entry().
2086 */ 2084 */
2087static void ocfs2_xa_store_inline_value(struct ocfs2_xa_loc *loc, 2085static int ocfs2_xa_store_value(struct ocfs2_xa_loc *loc,
2088 struct ocfs2_xattr_info *xi) 2086 struct ocfs2_xattr_info *xi,
2087 struct ocfs2_xattr_set_ctxt *ctxt)
2089{ 2088{
2089 int rc = 0;
2090 int nameval_offset = le16_to_cpu(loc->xl_entry->xe_name_offset); 2090 int nameval_offset = le16_to_cpu(loc->xl_entry->xe_name_offset);
2091 int name_size = OCFS2_XATTR_SIZE(xi->xi_name_len); 2091 int name_size = OCFS2_XATTR_SIZE(xi->xi_name_len);
2092 int inline_value_size = namevalue_size_xi(xi) - name_size;
2093 const void *value = xi->xi_value;
2094 char *nameval_buf; 2092 char *nameval_buf;
2093 struct ocfs2_xattr_value_buf vb;
2095 2094
2096 if (!xi->xi_value) 2095 if (!xi->xi_value)
2097 return; 2096 goto out;
2098 2097
2099 if (xi->xi_value_len > OCFS2_XATTR_INLINE_SIZE) {
2100 value = &def_xv;
2101 inline_value_size = OCFS2_XATTR_ROOT_SIZE;
2102 }
2103 nameval_buf = ocfs2_xa_offset_pointer(loc, nameval_offset); 2098 nameval_buf = ocfs2_xa_offset_pointer(loc, nameval_offset);
2104 memcpy(nameval_buf + name_size, value, inline_value_size); 2099 if (xi->xi_value_len > OCFS2_XATTR_INLINE_SIZE) {
2100 ocfs2_xa_fill_value_buf(loc, &vb);
2101 rc = __ocfs2_xattr_set_value_outside(loc->xl_inode,
2102 ctxt->handle, &vb,
2103 xi->xi_value,
2104 xi->xi_value_len);
2105 } else
2106 memcpy(nameval_buf + name_size, xi->xi_value, xi->xi_value_len);
2107
2108out:
2109 return rc;
2105} 2110}
2106 2111
2107static void ocfs2_init_dinode_xa_loc(struct ocfs2_xa_loc *loc, 2112static void ocfs2_init_dinode_xa_loc(struct ocfs2_xa_loc *loc,
@@ -2174,117 +2179,19 @@ static int ocfs2_xattr_set_entry(struct inode *inode,
2174 struct ocfs2_xattr_set_ctxt *ctxt, 2179 struct ocfs2_xattr_set_ctxt *ctxt,
2175 int flag) 2180 int flag)
2176{ 2181{
2177 struct ocfs2_xattr_entry *last;
2178 struct ocfs2_inode_info *oi = OCFS2_I(inode); 2182 struct ocfs2_inode_info *oi = OCFS2_I(inode);
2179 struct ocfs2_dinode *di = (struct ocfs2_dinode *)xs->inode_bh->b_data; 2183 struct ocfs2_dinode *di = (struct ocfs2_dinode *)xs->inode_bh->b_data;
2180 size_t min_offs = xs->end - xs->base;
2181 size_t size_l = 0;
2182 handle_t *handle = ctxt->handle; 2184 handle_t *handle = ctxt->handle;
2183 int free, i, ret; 2185 int ret;
2184 u32 name_hash = ocfs2_xattr_name_hash(inode, xi->xi_name, 2186 u32 name_hash = ocfs2_xattr_name_hash(inode, xi->xi_name,
2185 xi->xi_name_len); 2187 xi->xi_name_len);
2186 struct ocfs2_xa_loc loc; 2188 struct ocfs2_xa_loc loc;
2187 struct ocfs2_xattr_value_buf vb = {
2188 .vb_bh = xs->xattr_bh,
2189 .vb_access = ocfs2_journal_access_di,
2190 };
2191 2189
2192 if (!(flag & OCFS2_INLINE_XATTR_FL)) { 2190 if (!(flag & OCFS2_INLINE_XATTR_FL))
2193 BUG_ON(xs->xattr_bh == xs->inode_bh); 2191 BUG_ON(xs->xattr_bh == xs->inode_bh);
2194 vb.vb_access = ocfs2_journal_access_xb; 2192 else
2195 } else
2196 BUG_ON(xs->xattr_bh != xs->inode_bh); 2193 BUG_ON(xs->xattr_bh != xs->inode_bh);
2197 2194
2198 /* Compute min_offs, last and free space. */
2199 last = xs->header->xh_entries;
2200
2201 for (i = 0 ; i < le16_to_cpu(xs->header->xh_count); i++) {
2202 size_t offs = le16_to_cpu(last->xe_name_offset);
2203 if (offs < min_offs)
2204 min_offs = offs;
2205 last += 1;
2206 }
2207
2208 free = min_offs - ((void *)last - xs->base) - OCFS2_XATTR_HEADER_GAP;
2209 if (free < 0)
2210 return -EIO;
2211
2212 if (!xs->not_found)
2213 free += ocfs2_xe_entry_usage(xs->here);
2214
2215 /* Check free space in inode or block */
2216 if (xi->xi_value && (free < ocfs2_xi_entry_usage(xi))) {
2217 ret = -ENOSPC;
2218 goto out;
2219 }
2220
2221 if (!xs->not_found) {
2222 /* For existing extended attribute */
2223 size_t size = namevalue_size_xe(xs->here);
2224 size_t offs = le16_to_cpu(xs->here->xe_name_offset);
2225 void *val = xs->base + offs;
2226
2227 if (ocfs2_xattr_is_local(xs->here) && size == size_l) {
2228 /* Replace existing local xattr with tree root */
2229 ret = ocfs2_xattr_set_value_outside(inode, xi, xs,
2230 ctxt, &vb, offs);
2231 if (ret < 0)
2232 mlog_errno(ret);
2233 goto out;
2234 } else if (!ocfs2_xattr_is_local(xs->here)) {
2235 /* For existing xattr which has value outside */
2236 vb.vb_xv = (struct ocfs2_xattr_value_root *)
2237 (val + OCFS2_XATTR_SIZE(xi->xi_name_len));
2238
2239 if (xi->xi_value_len > OCFS2_XATTR_INLINE_SIZE) {
2240 /*
2241 * If new value need set outside also,
2242 * first truncate old value to new value,
2243 * then set new value with set_value_outside().
2244 */
2245 ret = ocfs2_xattr_value_truncate(inode,
2246 &vb,
2247 xi->xi_value_len,
2248 ctxt);
2249 if (ret < 0) {
2250 mlog_errno(ret);
2251 goto out;
2252 }
2253
2254 ret = ocfs2_xattr_update_entry(inode,
2255 handle,
2256 xi,
2257 xs,
2258 &vb,
2259 offs);
2260 if (ret < 0) {
2261 mlog_errno(ret);
2262 goto out;
2263 }
2264
2265 ret = __ocfs2_xattr_set_value_outside(inode,
2266 handle,
2267 &vb,
2268 xi->xi_value,
2269 xi->xi_value_len);
2270 if (ret < 0)
2271 mlog_errno(ret);
2272 goto out;
2273 } else {
2274 /*
2275 * If new value need set in local,
2276 * just trucate old value to zero.
2277 */
2278 ret = ocfs2_xattr_value_truncate(inode,
2279 &vb,
2280 0,
2281 ctxt);
2282 if (ret < 0)
2283 mlog_errno(ret);
2284 }
2285 }
2286 }
2287
2288 ret = ocfs2_journal_access_di(handle, INODE_CACHE(inode), xs->inode_bh, 2195 ret = ocfs2_journal_access_di(handle, INODE_CACHE(inode), xs->inode_bh,
2289 OCFS2_JOURNAL_ACCESS_WRITE); 2196 OCFS2_JOURNAL_ACCESS_WRITE);
2290 if (ret) { 2197 if (ret) {
@@ -2305,22 +2212,20 @@ static int ocfs2_xattr_set_entry(struct inode *inode,
2305 goto out; 2212 goto out;
2306 } 2213 }
2307 2214
2308 /* 2215 ret = ocfs2_xa_prepare_entry(&loc, xi, name_hash, ctxt);
2309 * Prepare our entry and insert the inline value. This will
2310 * be a value tree root for values that are larger than
2311 * OCFS2_XATTR_INLINE_SIZE.
2312 */
2313 ret = ocfs2_xa_prepare_entry(&loc, xi, name_hash);
2314 if (ret) { 2216 if (ret) {
2315 if (ret != -ENOSPC) 2217 if (ret != -ENOSPC)
2316 mlog_errno(ret); 2218 mlog_errno(ret);
2317 goto out; 2219 goto out;
2318 } 2220 }
2319 /* XXX For now, until we make ocfs2_xa_prepare_entry() primary */
2320 BUG_ON(ret == -ENOSPC);
2321 ocfs2_xa_store_inline_value(&loc, xi);
2322 xs->here = loc.xl_entry; 2221 xs->here = loc.xl_entry;
2323 2222
2223 ret = ocfs2_xa_store_value(&loc, xi, ctxt);
2224 if (ret) {
2225 mlog_errno(ret);
2226 goto out;
2227 }
2228
2324 ocfs2_xa_journal_dirty(handle, &loc); 2229 ocfs2_xa_journal_dirty(handle, &loc);
2325 2230
2326 if (!(oi->ip_dyn_features & OCFS2_INLINE_XATTR_FL) && 2231 if (!(oi->ip_dyn_features & OCFS2_INLINE_XATTR_FL) &&
@@ -2352,28 +2257,6 @@ static int ocfs2_xattr_set_entry(struct inode *inode,
2352 if (ret < 0) 2257 if (ret < 0)
2353 mlog_errno(ret); 2258 mlog_errno(ret);
2354 2259
2355 if (!ret && xi->xi_value_len > OCFS2_XATTR_INLINE_SIZE) {
2356 /*
2357 * Set value outside in B tree.
2358 * This is the second step for value size > INLINE_SIZE.
2359 */
2360 size_t offs = le16_to_cpu(xs->here->xe_name_offset);
2361 ret = ocfs2_xattr_set_value_outside(inode, xi, xs, ctxt,
2362 &vb, offs);
2363 if (ret < 0) {
2364 int ret2;
2365
2366 mlog_errno(ret);
2367 /*
2368 * If set value outside failed, we have to clean
2369 * the junk tree root we have already set in local.
2370 */
2371 ret2 = ocfs2_xattr_cleanup(inode, ctxt->handle,
2372 xi, xs, &vb, offs);
2373 if (ret2 < 0)
2374 mlog_errno(ret2);
2375 }
2376 }
2377out: 2260out:
2378 return ret; 2261 return ret;
2379} 2262}
@@ -5354,61 +5237,6 @@ static inline char *ocfs2_xattr_bucket_get_val(struct inode *inode,
5354} 5237}
5355 5238
5356/* 5239/*
5357 * Set the xattr entry in the specified bucket.
5358 * The bucket is indicated by xs->bucket and it should have the enough
5359 * space for the xattr insertion.
5360 */
5361static int ocfs2_xattr_set_entry_in_bucket(struct inode *inode,
5362 handle_t *handle,
5363 struct ocfs2_xattr_info *xi,
5364 struct ocfs2_xattr_search *xs,
5365 u32 name_hash)
5366{
5367 int ret;
5368 u64 blkno;
5369 struct ocfs2_xa_loc loc;
5370
5371 mlog(0, "Set xattr entry len = %lu index = %d in bucket %llu\n",
5372 (unsigned long)xi->xi_value_len, xi->xi_name_index,
5373 (unsigned long long)bucket_blkno(xs->bucket));
5374
5375 if (!xs->bucket->bu_bhs[1]) {
5376 blkno = bucket_blkno(xs->bucket);
5377 ocfs2_xattr_bucket_relse(xs->bucket);
5378 ret = ocfs2_read_xattr_bucket(xs->bucket, blkno);
5379 if (ret) {
5380 mlog_errno(ret);
5381 goto out;
5382 }
5383 }
5384
5385 ocfs2_init_xattr_bucket_xa_loc(&loc, xs->bucket,
5386 xs->not_found ? NULL : xs->here);
5387 ret = ocfs2_xa_journal_access(handle, &loc,
5388 OCFS2_JOURNAL_ACCESS_WRITE);
5389 if (ret < 0) {
5390 mlog_errno(ret);
5391 goto out;
5392 }
5393
5394 ret = ocfs2_xa_prepare_entry(&loc, xi, name_hash);
5395 if (ret) {
5396 if (ret != -ENOSPC)
5397 mlog_errno(ret);
5398 goto out;
5399 }
5400 /* XXX For now, until we make ocfs2_xa_prepare_entry() primary */
5401 BUG_ON(ret == -ENOSPC);
5402 ocfs2_xa_store_inline_value(&loc, xi);
5403 xs->here = loc.xl_entry;
5404
5405 ocfs2_xa_journal_dirty(handle, &loc);
5406
5407out:
5408 return ret;
5409}
5410
5411/*
5412 * Truncate the specified xe_off entry in xattr bucket. 5240 * Truncate the specified xe_off entry in xattr bucket.
5413 * bucket is indicated by header_bh and len is the new length. 5241 * bucket is indicated by header_bh and len is the new length.
5414 * Both the ocfs2_xattr_value_root and the entry will be updated here. 5242 * Both the ocfs2_xattr_value_root and the entry will be updated here.
@@ -5478,66 +5306,6 @@ out:
5478 return ret; 5306 return ret;
5479} 5307}
5480 5308
5481static int ocfs2_xattr_bucket_value_truncate_xs(struct inode *inode,
5482 struct ocfs2_xattr_search *xs,
5483 int len,
5484 struct ocfs2_xattr_set_ctxt *ctxt)
5485{
5486 int ret, offset;
5487 struct ocfs2_xattr_entry *xe = xs->here;
5488 struct ocfs2_xattr_header *xh = (struct ocfs2_xattr_header *)xs->base;
5489
5490 BUG_ON(!xs->bucket->bu_bhs[0] || !xe || ocfs2_xattr_is_local(xe));
5491
5492 offset = xe - xh->xh_entries;
5493 ret = ocfs2_xattr_bucket_value_truncate(inode, xs->bucket,
5494 offset, len, ctxt);
5495 if (ret)
5496 mlog_errno(ret);
5497
5498 return ret;
5499}
5500
5501static int ocfs2_xattr_bucket_set_value_outside(struct inode *inode,
5502 handle_t *handle,
5503 struct ocfs2_xattr_search *xs,
5504 char *val,
5505 int value_len)
5506{
5507 int ret, offset, block_off;
5508 struct ocfs2_xattr_value_root *xv;
5509 struct ocfs2_xattr_entry *xe = xs->here;
5510 struct ocfs2_xattr_header *xh = bucket_xh(xs->bucket);
5511 void *base;
5512 struct ocfs2_xattr_value_buf vb = {
5513 .vb_access = ocfs2_journal_access,
5514 };
5515
5516 BUG_ON(!xs->base || !xe || ocfs2_xattr_is_local(xe));
5517
5518 ret = ocfs2_xattr_bucket_get_name_value(inode->i_sb, xh,
5519 xe - xh->xh_entries,
5520 &block_off,
5521 &offset);
5522 if (ret) {
5523 mlog_errno(ret);
5524 goto out;
5525 }
5526
5527 base = bucket_block(xs->bucket, block_off);
5528 xv = (struct ocfs2_xattr_value_root *)(base + offset +
5529 OCFS2_XATTR_SIZE(xe->xe_name_len));
5530
5531 vb.vb_xv = xv;
5532 vb.vb_bh = xs->bucket->bu_bhs[block_off];
5533 ret = __ocfs2_xattr_set_value_outside(inode, handle,
5534 &vb, val, value_len);
5535 if (ret)
5536 mlog_errno(ret);
5537out:
5538 return ret;
5539}
5540
5541static int ocfs2_rm_xattr_cluster(struct inode *inode, 5309static int ocfs2_rm_xattr_cluster(struct inode *inode,
5542 struct buffer_head *root_bh, 5310 struct buffer_head *root_bh,
5543 u64 blkno, 5311 u64 blkno,
@@ -5636,41 +5404,8 @@ out:
5636 return ret; 5404 return ret;
5637} 5405}
5638 5406
5639static void ocfs2_xattr_bucket_remove_xs(struct inode *inode,
5640 handle_t *handle,
5641 struct ocfs2_xattr_search *xs)
5642{
5643 struct ocfs2_xattr_header *xh = bucket_xh(xs->bucket);
5644 struct ocfs2_xattr_entry *last = &xh->xh_entries[
5645 le16_to_cpu(xh->xh_count) - 1];
5646 int ret = 0;
5647
5648 ret = ocfs2_xattr_bucket_journal_access(handle, xs->bucket,
5649 OCFS2_JOURNAL_ACCESS_WRITE);
5650 if (ret) {
5651 mlog_errno(ret);
5652 return;
5653 }
5654
5655 /* Remove the old entry. */
5656 memmove(xs->here, xs->here + 1,
5657 (void *)last - (void *)xs->here);
5658 memset(last, 0, sizeof(struct ocfs2_xattr_entry));
5659 le16_add_cpu(&xh->xh_count, -1);
5660
5661 ocfs2_xattr_bucket_journal_dirty(handle, xs->bucket);
5662}
5663
5664/* 5407/*
5665 * Set the xattr name/value in the bucket specified in xs. 5408 * Set the xattr name/value in the bucket specified in xs.
5666 *
5667 * As the new value in xi may be stored in the bucket or in an outside cluster,
5668 * we divide the whole process into 3 steps:
5669 * 1. insert name/value in the bucket(ocfs2_xattr_set_entry_in_bucket)
5670 * 2. truncate of the outside cluster(ocfs2_xattr_bucket_value_truncate_xs)
5671 * 3. Set the value to the outside cluster(ocfs2_xattr_bucket_set_value_outside)
5672 * 4. If the clusters for the new outside value can't be allocated, we need
5673 * to free the xattr we allocated in set.
5674 */ 5409 */
5675static int ocfs2_xattr_set_in_bucket(struct inode *inode, 5410static int ocfs2_xattr_set_in_bucket(struct inode *inode,
5676 struct ocfs2_xattr_info *xi, 5411 struct ocfs2_xattr_info *xi,
@@ -5678,70 +5413,46 @@ static int ocfs2_xattr_set_in_bucket(struct inode *inode,
5678 struct ocfs2_xattr_set_ctxt *ctxt) 5413 struct ocfs2_xattr_set_ctxt *ctxt)
5679{ 5414{
5680 int ret; 5415 int ret;
5681 size_t value_len; 5416 u64 blkno;
5682 char *val = (char *)xi->xi_value; 5417 struct ocfs2_xa_loc loc;
5683 struct ocfs2_xattr_entry *xe = xs->here;
5684 u32 name_hash = ocfs2_xattr_name_hash(inode, xi->xi_name, 5418 u32 name_hash = ocfs2_xattr_name_hash(inode, xi->xi_name,
5685 xi->xi_name_len); 5419 xi->xi_name_len);
5686 5420
5687 value_len = xi->xi_value_len; 5421 if (!xs->bucket->bu_bhs[1]) {
5688 if (!xs->not_found && !ocfs2_xattr_is_local(xe)) { 5422 blkno = bucket_blkno(xs->bucket);
5689 /* 5423 ocfs2_xattr_bucket_relse(xs->bucket);
5690 * We need to truncate the xattr storage first. 5424 ret = ocfs2_read_xattr_bucket(xs->bucket, blkno);
5691 * 5425 if (ret) {
5692 * If both the old and new value are stored to 5426 mlog_errno(ret);
5693 * outside block, we only need to truncate
5694 * the storage and then set the value outside.
5695 *
5696 * If the new value should be stored within block,
5697 * we should free all the outside block first and
5698 * the modification to the xattr block will be done
5699 * by following steps.
5700 */
5701 if (xi->xi_value_len <= OCFS2_XATTR_INLINE_SIZE)
5702 value_len = 0;
5703
5704 ret = ocfs2_xattr_bucket_value_truncate_xs(inode, xs,
5705 value_len,
5706 ctxt);
5707 if (ret)
5708 goto out; 5427 goto out;
5709 5428 }
5710 if (value_len)
5711 goto set_value_outside;
5712 } 5429 }
5713 5430
5714 /* So we have to handle the inside block change now. */ 5431 ocfs2_init_xattr_bucket_xa_loc(&loc, xs->bucket,
5715 ret = ocfs2_xattr_set_entry_in_bucket(inode, ctxt->handle, xi, xs, 5432 xs->not_found ? NULL : xs->here);
5716 name_hash); 5433 ret = ocfs2_xa_journal_access(ctxt->handle, &loc,
5717 if (ret) { 5434 OCFS2_JOURNAL_ACCESS_WRITE);
5435 if (ret < 0) {
5718 mlog_errno(ret); 5436 mlog_errno(ret);
5719 goto out; 5437 goto out;
5720 } 5438 }
5721 5439
5722 if (xi->xi_value_len <= OCFS2_XATTR_INLINE_SIZE) 5440 ret = ocfs2_xa_prepare_entry(&loc, xi, name_hash, ctxt);
5441 if (ret) {
5442 if (ret != -ENOSPC)
5443 mlog_errno(ret);
5723 goto out; 5444 goto out;
5445 }
5446 xs->here = loc.xl_entry;
5724 5447
5725 /* allocate the space now for the outside block storage. */ 5448 ret = ocfs2_xa_store_value(&loc, xi, ctxt);
5726 ret = ocfs2_xattr_bucket_value_truncate_xs(inode, xs,
5727 value_len, ctxt);
5728 if (ret) { 5449 if (ret) {
5729 mlog_errno(ret); 5450 mlog_errno(ret);
5730
5731 if (xs->not_found) {
5732 /*
5733 * We can't allocate enough clusters for outside
5734 * storage and we have allocated xattr already,
5735 * so need to remove it.
5736 */
5737 ocfs2_xattr_bucket_remove_xs(inode, ctxt->handle, xs);
5738 }
5739 goto out; 5451 goto out;
5740 } 5452 }
5741 5453
5742set_value_outside: 5454 ocfs2_xa_journal_dirty(ctxt->handle, &loc);
5743 ret = ocfs2_xattr_bucket_set_value_outside(inode, ctxt->handle, 5455
5744 xs, val, value_len);
5745out: 5456out:
5746 return ret; 5457 return ret;
5747} 5458}