aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/xattr.c
diff options
context:
space:
mode:
authorJoel Becker <joel.becker@oracle.com>2009-08-19 14:09:17 -0400
committerJoel Becker <joel.becker@oracle.com>2010-02-26 18:41:13 -0500
commit139ffacebf5fe2cd9e2ae40d325a9661a679ad4f (patch)
tree4643a671b7712cfe7210cc970252641be17518ce /fs/ocfs2/xattr.c
parentd3981544d7a4ed276966cdd58fe2f5d6e8a585d9 (diff)
ocfs2: Set inline xattr entries with ocfs2_xa_set()
ocfs2_xattr_ibody_set() is the only remaining user of ocfs2_xattr_set_entry(). ocfs2_xattr_set_entry() actually does two things: it calls ocfs2_xa_set(), and it initializes the inline xattrs. Initializing the inline space really belongs in its own call. We lift the initialization to ocfs2_xattr_ibody_init(), called from ocfs2_xattr_ibody_set() only when necessary. Now ocfs2_xattr_ibody_set() can call ocfs2_xa_set() directly. ocfs2_xattr_set_entry() goes away. Another nice fact is that ocfs2_init_dinode_xa_loc() can trust i_xattr_inline_size. Signed-off-by: Joel Becker <joel.becker@oracle.com>
Diffstat (limited to 'fs/ocfs2/xattr.c')
-rw-r--r--fs/ocfs2/xattr.c157
1 files changed, 73 insertions, 84 deletions
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c
index fb8568d1e8a1..a2d912a92dd7 100644
--- a/fs/ocfs2/xattr.c
+++ b/fs/ocfs2/xattr.c
@@ -2137,17 +2137,13 @@ static void ocfs2_init_dinode_xa_loc(struct ocfs2_xa_loc *loc,
2137{ 2137{
2138 struct ocfs2_dinode *di = (struct ocfs2_dinode *)bh->b_data; 2138 struct ocfs2_dinode *di = (struct ocfs2_dinode *)bh->b_data;
2139 2139
2140 BUG_ON(!(OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_XATTR_FL));
2141
2140 loc->xl_inode = inode; 2142 loc->xl_inode = inode;
2141 loc->xl_ops = &ocfs2_xa_block_loc_ops; 2143 loc->xl_ops = &ocfs2_xa_block_loc_ops;
2142 loc->xl_storage = bh; 2144 loc->xl_storage = bh;
2143 loc->xl_entry = entry; 2145 loc->xl_entry = entry;
2144 2146 loc->xl_size = le16_to_cpu(di->i_xattr_inline_size);
2145 if (OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_XATTR_FL)
2146 loc->xl_size = le16_to_cpu(di->i_xattr_inline_size);
2147 else {
2148 BUG_ON(entry);
2149 loc->xl_size = OCFS2_SB(inode->i_sb)->s_xattr_inline_size;
2150 }
2151 loc->xl_header = 2147 loc->xl_header =
2152 (struct ocfs2_xattr_header *)(bh->b_data + bh->b_size - 2148 (struct ocfs2_xattr_header *)(bh->b_data + bh->b_size -
2153 loc->xl_size); 2149 loc->xl_size);
@@ -2184,80 +2180,6 @@ static void ocfs2_init_xattr_bucket_xa_loc(struct ocfs2_xa_loc *loc,
2184 loc->xl_size = OCFS2_XATTR_BUCKET_SIZE; 2180 loc->xl_size = OCFS2_XATTR_BUCKET_SIZE;
2185} 2181}
2186 2182
2187
2188/*
2189 * ocfs2_xattr_set_entry()
2190 *
2191 * Set extended attribute entry into inode or block.
2192 *
2193 * If extended attribute value size > OCFS2_XATTR_INLINE_SIZE,
2194 * We first insert tree root(ocfs2_xattr_value_root) like a normal value,
2195 * then set value in B tree with set_value_outside().
2196 */
2197static int ocfs2_xattr_set_entry(struct inode *inode,
2198 struct ocfs2_xattr_info *xi,
2199 struct ocfs2_xattr_search *xs,
2200 struct ocfs2_xattr_set_ctxt *ctxt,
2201 int flag)
2202{
2203 struct ocfs2_inode_info *oi = OCFS2_I(inode);
2204 struct ocfs2_dinode *di = (struct ocfs2_dinode *)xs->inode_bh->b_data;
2205 handle_t *handle = ctxt->handle;
2206 int ret;
2207 struct ocfs2_xa_loc loc;
2208
2209 BUG_ON(!(flag & OCFS2_INLINE_XATTR_FL));
2210 BUG_ON(xs->xattr_bh != xs->inode_bh);
2211
2212 ret = ocfs2_journal_access_di(handle, INODE_CACHE(inode), xs->inode_bh,
2213 OCFS2_JOURNAL_ACCESS_WRITE);
2214 if (ret) {
2215 mlog_errno(ret);
2216 goto out;
2217 }
2218
2219 ocfs2_init_dinode_xa_loc(&loc, inode, xs->inode_bh,
2220 xs->not_found ? NULL : xs->here);
2221 ret = ocfs2_xa_set(&loc, xi, ctxt);
2222 if (ret) {
2223 if (ret != -ENOSPC)
2224 mlog_errno(ret);
2225 goto out;
2226 }
2227 xs->here = loc.xl_entry;
2228
2229 if (!(oi->ip_dyn_features & OCFS2_INLINE_XATTR_FL)) {
2230 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
2231 unsigned int xattrsize = osb->s_xattr_inline_size;
2232
2233 /*
2234 * Adjust extent record count or inline data size
2235 * to reserve space for extended attribute.
2236 */
2237 if (oi->ip_dyn_features & OCFS2_INLINE_DATA_FL) {
2238 struct ocfs2_inline_data *idata = &di->id2.i_data;
2239 le16_add_cpu(&idata->id_count, -xattrsize);
2240 } else if (!(ocfs2_inode_is_fast_symlink(inode))) {
2241 struct ocfs2_extent_list *el = &di->id2.i_list;
2242 le16_add_cpu(&el->l_count, -(xattrsize /
2243 sizeof(struct ocfs2_extent_rec)));
2244 }
2245 di->i_xattr_inline_size = cpu_to_le16(xattrsize);
2246 }
2247 /* Update xattr flag */
2248 spin_lock(&oi->ip_lock);
2249 oi->ip_dyn_features |= OCFS2_INLINE_XATTR_FL;
2250 di->i_dyn_features = cpu_to_le16(oi->ip_dyn_features);
2251 spin_unlock(&oi->ip_lock);
2252
2253 ret = ocfs2_journal_dirty(handle, xs->inode_bh);
2254 if (ret < 0)
2255 mlog_errno(ret);
2256
2257out:
2258 return ret;
2259}
2260
2261/* 2183/*
2262 * In xattr remove, if it is stored outside and refcounted, we may have 2184 * In xattr remove, if it is stored outside and refcounted, we may have
2263 * the chance to split the refcount tree. So need the allocators. 2185 * the chance to split the refcount tree. So need the allocators.
@@ -2653,6 +2575,55 @@ static int ocfs2_xattr_ibody_find(struct inode *inode,
2653 return 0; 2575 return 0;
2654} 2576}
2655 2577
2578static int ocfs2_xattr_ibody_init(struct inode *inode,
2579 struct buffer_head *di_bh,
2580 struct ocfs2_xattr_set_ctxt *ctxt)
2581{
2582 int ret;
2583 struct ocfs2_inode_info *oi = OCFS2_I(inode);
2584 struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data;
2585 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
2586 unsigned int xattrsize = osb->s_xattr_inline_size;
2587
2588 if (!ocfs2_xattr_has_space_inline(inode, di)) {
2589 ret = -ENOSPC;
2590 goto out;
2591 }
2592
2593 ret = ocfs2_journal_access_di(ctxt->handle, INODE_CACHE(inode), di_bh,
2594 OCFS2_JOURNAL_ACCESS_WRITE);
2595 if (ret) {
2596 mlog_errno(ret);
2597 goto out;
2598 }
2599
2600 /*
2601 * Adjust extent record count or inline data size
2602 * to reserve space for extended attribute.
2603 */
2604 if (oi->ip_dyn_features & OCFS2_INLINE_DATA_FL) {
2605 struct ocfs2_inline_data *idata = &di->id2.i_data;
2606 le16_add_cpu(&idata->id_count, -xattrsize);
2607 } else if (!(ocfs2_inode_is_fast_symlink(inode))) {
2608 struct ocfs2_extent_list *el = &di->id2.i_list;
2609 le16_add_cpu(&el->l_count, -(xattrsize /
2610 sizeof(struct ocfs2_extent_rec)));
2611 }
2612 di->i_xattr_inline_size = cpu_to_le16(xattrsize);
2613
2614 spin_lock(&oi->ip_lock);
2615 oi->ip_dyn_features |= OCFS2_INLINE_XATTR_FL|OCFS2_HAS_XATTR_FL;
2616 di->i_dyn_features = cpu_to_le16(oi->ip_dyn_features);
2617 spin_unlock(&oi->ip_lock);
2618
2619 ret = ocfs2_journal_dirty(ctxt->handle, di_bh);
2620 if (ret < 0)
2621 mlog_errno(ret);
2622
2623out:
2624 return ret;
2625}
2626
2656/* 2627/*
2657 * ocfs2_xattr_ibody_set() 2628 * ocfs2_xattr_ibody_set()
2658 * 2629 *
@@ -2664,9 +2635,10 @@ static int ocfs2_xattr_ibody_set(struct inode *inode,
2664 struct ocfs2_xattr_search *xs, 2635 struct ocfs2_xattr_search *xs,
2665 struct ocfs2_xattr_set_ctxt *ctxt) 2636 struct ocfs2_xattr_set_ctxt *ctxt)
2666{ 2637{
2638 int ret;
2667 struct ocfs2_inode_info *oi = OCFS2_I(inode); 2639 struct ocfs2_inode_info *oi = OCFS2_I(inode);
2668 struct ocfs2_dinode *di = (struct ocfs2_dinode *)xs->inode_bh->b_data; 2640 struct ocfs2_dinode *di = (struct ocfs2_dinode *)xs->inode_bh->b_data;
2669 int ret; 2641 struct ocfs2_xa_loc loc;
2670 2642
2671 if (inode->i_sb->s_blocksize == OCFS2_MIN_BLOCKSIZE) 2643 if (inode->i_sb->s_blocksize == OCFS2_MIN_BLOCKSIZE)
2672 return -ENOSPC; 2644 return -ENOSPC;
@@ -2679,8 +2651,25 @@ static int ocfs2_xattr_ibody_set(struct inode *inode,
2679 } 2651 }
2680 } 2652 }
2681 2653
2682 ret = ocfs2_xattr_set_entry(inode, xi, xs, ctxt, 2654 if (!(oi->ip_dyn_features & OCFS2_INLINE_XATTR_FL)) {
2683 (OCFS2_INLINE_XATTR_FL | OCFS2_HAS_XATTR_FL)); 2655 ret = ocfs2_xattr_ibody_init(inode, xs->inode_bh, ctxt);
2656 if (ret) {
2657 if (ret != -ENOSPC)
2658 mlog_errno(ret);
2659 goto out;
2660 }
2661 }
2662
2663 ocfs2_init_dinode_xa_loc(&loc, inode, xs->inode_bh,
2664 xs->not_found ? NULL : xs->here);
2665 ret = ocfs2_xa_set(&loc, xi, ctxt);
2666 if (ret) {
2667 if (ret != -ENOSPC)
2668 mlog_errno(ret);
2669 goto out;
2670 }
2671 xs->here = loc.xl_entry;
2672
2684out: 2673out:
2685 up_write(&oi->ip_alloc_sem); 2674 up_write(&oi->ip_alloc_sem);
2686 2675