aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/xattr.c
diff options
context:
space:
mode:
authorJoel Becker <joel.becker@oracle.com>2009-08-19 05:13:50 -0400
committerJoel Becker <joel.becker@oracle.com>2010-02-26 18:41:13 -0500
commitd3981544d7a4ed276966cdd58fe2f5d6e8a585d9 (patch)
treea2a90d6a67c40fac4b56edd524b08a8c52179570 /fs/ocfs2/xattr.c
parentc5d95df5f78312c879f3058059c98a08821897a5 (diff)
ocfs2: Set xattr block entries with ocfs2_xa_set()
ocfs2_xattr_block_set() calls into ocfs2_xattr_set_entry() with just the HAS_XATTR flag. Most of the machinery of ocfs2_xattr_set_entry() is skipped. All that really happens other than the call to ocfs2_xa_set() is making sure the HAS_XATTR flag is set on the inode. But HAS_XATTR should be set when we also set di->i_xattr_loc. And that's done in ocfs2_create_xattr_block(). So let's move it there, and then ocfs2_xattr_block_set() can just call ocfs2_xa_set(). While we're there, ocfs2_create_xattr_block() can take the set_ctxt for a smaller argument list. It also learns to set HAS_XATTR_FL, because it knows for sure. ocfs2_create_empty_xatttr_block() in the reflink path fakes a set_ctxt to call ocfs2_create_xattr_block(). Signed-off-by: Joel Becker <joel.becker@oracle.com>
Diffstat (limited to 'fs/ocfs2/xattr.c')
-rw-r--r--fs/ocfs2/xattr.c99
1 files changed, 49 insertions, 50 deletions
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c
index e7630a77a6c8..fb8568d1e8a1 100644
--- a/fs/ocfs2/xattr.c
+++ b/fs/ocfs2/xattr.c
@@ -2206,10 +2206,8 @@ static int ocfs2_xattr_set_entry(struct inode *inode,
2206 int ret; 2206 int ret;
2207 struct ocfs2_xa_loc loc; 2207 struct ocfs2_xa_loc loc;
2208 2208
2209 if (!(flag & OCFS2_INLINE_XATTR_FL)) 2209 BUG_ON(!(flag & OCFS2_INLINE_XATTR_FL));
2210 BUG_ON(xs->xattr_bh == xs->inode_bh); 2210 BUG_ON(xs->xattr_bh != xs->inode_bh);
2211 else
2212 BUG_ON(xs->xattr_bh != xs->inode_bh);
2213 2211
2214 ret = ocfs2_journal_access_di(handle, INODE_CACHE(inode), xs->inode_bh, 2212 ret = ocfs2_journal_access_di(handle, INODE_CACHE(inode), xs->inode_bh,
2215 OCFS2_JOURNAL_ACCESS_WRITE); 2213 OCFS2_JOURNAL_ACCESS_WRITE);
@@ -2218,13 +2216,8 @@ static int ocfs2_xattr_set_entry(struct inode *inode,
2218 goto out; 2216 goto out;
2219 } 2217 }
2220 2218
2221 if (xs->xattr_bh == xs->inode_bh) 2219 ocfs2_init_dinode_xa_loc(&loc, inode, xs->inode_bh,
2222 ocfs2_init_dinode_xa_loc(&loc, inode, xs->inode_bh, 2220 xs->not_found ? NULL : xs->here);
2223 xs->not_found ? NULL : xs->here);
2224 else
2225 ocfs2_init_xattr_block_xa_loc(&loc, inode, xs->xattr_bh,
2226 xs->not_found ? NULL : xs->here);
2227
2228 ret = ocfs2_xa_set(&loc, xi, ctxt); 2221 ret = ocfs2_xa_set(&loc, xi, ctxt);
2229 if (ret) { 2222 if (ret) {
2230 if (ret != -ENOSPC) 2223 if (ret != -ENOSPC)
@@ -2233,8 +2226,7 @@ static int ocfs2_xattr_set_entry(struct inode *inode,
2233 } 2226 }
2234 xs->here = loc.xl_entry; 2227 xs->here = loc.xl_entry;
2235 2228
2236 if (!(oi->ip_dyn_features & OCFS2_INLINE_XATTR_FL) && 2229 if (!(oi->ip_dyn_features & OCFS2_INLINE_XATTR_FL)) {
2237 (flag & OCFS2_INLINE_XATTR_FL)) {
2238 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); 2230 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
2239 unsigned int xattrsize = osb->s_xattr_inline_size; 2231 unsigned int xattrsize = osb->s_xattr_inline_size;
2240 2232
@@ -2254,7 +2246,7 @@ static int ocfs2_xattr_set_entry(struct inode *inode,
2254 } 2246 }
2255 /* Update xattr flag */ 2247 /* Update xattr flag */
2256 spin_lock(&oi->ip_lock); 2248 spin_lock(&oi->ip_lock);
2257 oi->ip_dyn_features |= flag; 2249 oi->ip_dyn_features |= OCFS2_INLINE_XATTR_FL;
2258 di->i_dyn_features = cpu_to_le16(oi->ip_dyn_features); 2250 di->i_dyn_features = cpu_to_le16(oi->ip_dyn_features);
2259 spin_unlock(&oi->ip_lock); 2251 spin_unlock(&oi->ip_lock);
2260 2252
@@ -2748,12 +2740,11 @@ cleanup:
2748 return ret; 2740 return ret;
2749} 2741}
2750 2742
2751static int ocfs2_create_xattr_block(handle_t *handle, 2743static int ocfs2_create_xattr_block(struct inode *inode,
2752 struct inode *inode,
2753 struct buffer_head *inode_bh, 2744 struct buffer_head *inode_bh,
2754 struct ocfs2_alloc_context *meta_ac, 2745 struct ocfs2_xattr_set_ctxt *ctxt,
2755 struct buffer_head **ret_bh, 2746 int indexed,
2756 int indexed) 2747 struct buffer_head **ret_bh)
2757{ 2748{
2758 int ret; 2749 int ret;
2759 u16 suballoc_bit_start; 2750 u16 suballoc_bit_start;
@@ -2764,14 +2755,14 @@ static int ocfs2_create_xattr_block(handle_t *handle,
2764 struct buffer_head *new_bh = NULL; 2755 struct buffer_head *new_bh = NULL;
2765 struct ocfs2_xattr_block *xblk; 2756 struct ocfs2_xattr_block *xblk;
2766 2757
2767 ret = ocfs2_journal_access_di(handle, INODE_CACHE(inode), inode_bh, 2758 ret = ocfs2_journal_access_di(ctxt->handle, INODE_CACHE(inode),
2768 OCFS2_JOURNAL_ACCESS_CREATE); 2759 inode_bh, OCFS2_JOURNAL_ACCESS_CREATE);
2769 if (ret < 0) { 2760 if (ret < 0) {
2770 mlog_errno(ret); 2761 mlog_errno(ret);
2771 goto end; 2762 goto end;
2772 } 2763 }
2773 2764
2774 ret = ocfs2_claim_metadata(osb, handle, meta_ac, 1, 2765 ret = ocfs2_claim_metadata(osb, ctxt->handle, ctxt->meta_ac, 1,
2775 &suballoc_bit_start, &num_got, 2766 &suballoc_bit_start, &num_got,
2776 &first_blkno); 2767 &first_blkno);
2777 if (ret < 0) { 2768 if (ret < 0) {
@@ -2782,7 +2773,7 @@ static int ocfs2_create_xattr_block(handle_t *handle,
2782 new_bh = sb_getblk(inode->i_sb, first_blkno); 2773 new_bh = sb_getblk(inode->i_sb, first_blkno);
2783 ocfs2_set_new_buffer_uptodate(INODE_CACHE(inode), new_bh); 2774 ocfs2_set_new_buffer_uptodate(INODE_CACHE(inode), new_bh);
2784 2775
2785 ret = ocfs2_journal_access_xb(handle, INODE_CACHE(inode), 2776 ret = ocfs2_journal_access_xb(ctxt->handle, INODE_CACHE(inode),
2786 new_bh, 2777 new_bh,
2787 OCFS2_JOURNAL_ACCESS_CREATE); 2778 OCFS2_JOURNAL_ACCESS_CREATE);
2788 if (ret < 0) { 2779 if (ret < 0) {
@@ -2794,11 +2785,10 @@ static int ocfs2_create_xattr_block(handle_t *handle,
2794 xblk = (struct ocfs2_xattr_block *)new_bh->b_data; 2785 xblk = (struct ocfs2_xattr_block *)new_bh->b_data;
2795 memset(xblk, 0, inode->i_sb->s_blocksize); 2786 memset(xblk, 0, inode->i_sb->s_blocksize);
2796 strcpy((void *)xblk, OCFS2_XATTR_BLOCK_SIGNATURE); 2787 strcpy((void *)xblk, OCFS2_XATTR_BLOCK_SIGNATURE);
2797 xblk->xb_suballoc_slot = cpu_to_le16(meta_ac->ac_alloc_slot); 2788 xblk->xb_suballoc_slot = cpu_to_le16(ctxt->meta_ac->ac_alloc_slot);
2798 xblk->xb_suballoc_bit = cpu_to_le16(suballoc_bit_start); 2789 xblk->xb_suballoc_bit = cpu_to_le16(suballoc_bit_start);
2799 xblk->xb_fs_generation = cpu_to_le32(osb->fs_generation); 2790 xblk->xb_fs_generation = cpu_to_le32(osb->fs_generation);
2800 xblk->xb_blkno = cpu_to_le64(first_blkno); 2791 xblk->xb_blkno = cpu_to_le64(first_blkno);
2801
2802 if (indexed) { 2792 if (indexed) {
2803 struct ocfs2_xattr_tree_root *xr = &xblk->xb_attrs.xb_root; 2793 struct ocfs2_xattr_tree_root *xr = &xblk->xb_attrs.xb_root;
2804 xr->xt_clusters = cpu_to_le32(1); 2794 xr->xt_clusters = cpu_to_le32(1);
@@ -2809,14 +2799,17 @@ static int ocfs2_create_xattr_block(handle_t *handle,
2809 xr->xt_list.l_next_free_rec = cpu_to_le16(1); 2799 xr->xt_list.l_next_free_rec = cpu_to_le16(1);
2810 xblk->xb_flags = cpu_to_le16(OCFS2_XATTR_INDEXED); 2800 xblk->xb_flags = cpu_to_le16(OCFS2_XATTR_INDEXED);
2811 } 2801 }
2802 ocfs2_journal_dirty(ctxt->handle, new_bh);
2812 2803
2813 ret = ocfs2_journal_dirty(handle, new_bh); 2804 /* Add it to the inode */
2814 if (ret < 0) {
2815 mlog_errno(ret);
2816 goto end;
2817 }
2818 di->i_xattr_loc = cpu_to_le64(first_blkno); 2805 di->i_xattr_loc = cpu_to_le64(first_blkno);
2819 ocfs2_journal_dirty(handle, inode_bh); 2806
2807 spin_lock(&OCFS2_I(inode)->ip_lock);
2808 OCFS2_I(inode)->ip_dyn_features |= OCFS2_HAS_XATTR_FL;
2809 di->i_dyn_features = cpu_to_le16(OCFS2_I(inode)->ip_dyn_features);
2810 spin_unlock(&OCFS2_I(inode)->ip_lock);
2811
2812 ocfs2_journal_dirty(ctxt->handle, inode_bh);
2820 2813
2821 *ret_bh = new_bh; 2814 *ret_bh = new_bh;
2822 new_bh = NULL; 2815 new_bh = NULL;
@@ -2838,13 +2831,13 @@ static int ocfs2_xattr_block_set(struct inode *inode,
2838 struct ocfs2_xattr_set_ctxt *ctxt) 2831 struct ocfs2_xattr_set_ctxt *ctxt)
2839{ 2832{
2840 struct buffer_head *new_bh = NULL; 2833 struct buffer_head *new_bh = NULL;
2841 handle_t *handle = ctxt->handle;
2842 struct ocfs2_xattr_block *xblk = NULL; 2834 struct ocfs2_xattr_block *xblk = NULL;
2843 int ret; 2835 int ret;
2836 struct ocfs2_xa_loc loc;
2844 2837
2845 if (!xs->xattr_bh) { 2838 if (!xs->xattr_bh) {
2846 ret = ocfs2_create_xattr_block(handle, inode, xs->inode_bh, 2839 ret = ocfs2_create_xattr_block(inode, xs->inode_bh, ctxt,
2847 ctxt->meta_ac, &new_bh, 0); 2840 0, &new_bh);
2848 if (ret) { 2841 if (ret) {
2849 mlog_errno(ret); 2842 mlog_errno(ret);
2850 goto end; 2843 goto end;
@@ -2860,21 +2853,25 @@ static int ocfs2_xattr_block_set(struct inode *inode,
2860 xblk = (struct ocfs2_xattr_block *)xs->xattr_bh->b_data; 2853 xblk = (struct ocfs2_xattr_block *)xs->xattr_bh->b_data;
2861 2854
2862 if (!(le16_to_cpu(xblk->xb_flags) & OCFS2_XATTR_INDEXED)) { 2855 if (!(le16_to_cpu(xblk->xb_flags) & OCFS2_XATTR_INDEXED)) {
2863 /* Set extended attribute into external block */ 2856 ocfs2_init_xattr_block_xa_loc(&loc, inode, xs->xattr_bh,
2864 ret = ocfs2_xattr_set_entry(inode, xi, xs, ctxt, 2857 xs->not_found ? NULL : xs->here);
2865 OCFS2_HAS_XATTR_FL);
2866 if (!ret || ret != -ENOSPC)
2867 goto end;
2868 2858
2869 ret = ocfs2_xattr_create_index_block(inode, xs, ctxt); 2859 ret = ocfs2_xa_set(&loc, xi, ctxt);
2870 if (ret) 2860 if (!ret)
2861 xs->here = loc.xl_entry;
2862 else if (ret != -ENOSPC)
2871 goto end; 2863 goto end;
2864 else {
2865 ret = ocfs2_xattr_create_index_block(inode, xs, ctxt);
2866 if (ret)
2867 goto end;
2868 }
2872 } 2869 }
2873 2870
2874 ret = ocfs2_xattr_set_entry_index_block(inode, xi, xs, ctxt); 2871 if (le16_to_cpu(xblk->xb_flags) & OCFS2_XATTR_INDEXED)
2872 ret = ocfs2_xattr_set_entry_index_block(inode, xi, xs, ctxt);
2875 2873
2876end: 2874end:
2877
2878 return ret; 2875 return ret;
2879} 2876}
2880 2877
@@ -6434,9 +6431,11 @@ static int ocfs2_create_empty_xattr_block(struct inode *inode,
6434 int indexed) 6431 int indexed)
6435{ 6432{
6436 int ret; 6433 int ret;
6437 handle_t *handle;
6438 struct ocfs2_alloc_context *meta_ac; 6434 struct ocfs2_alloc_context *meta_ac;
6439 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); 6435 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
6436 struct ocfs2_xattr_set_ctxt ctxt = {
6437 .meta_ac = meta_ac,
6438 };
6440 6439
6441 ret = ocfs2_reserve_new_metadata_blocks(osb, 1, &meta_ac); 6440 ret = ocfs2_reserve_new_metadata_blocks(osb, 1, &meta_ac);
6442 if (ret < 0) { 6441 if (ret < 0) {
@@ -6444,21 +6443,21 @@ static int ocfs2_create_empty_xattr_block(struct inode *inode,
6444 return ret; 6443 return ret;
6445 } 6444 }
6446 6445
6447 handle = ocfs2_start_trans(osb, OCFS2_XATTR_BLOCK_CREATE_CREDITS); 6446 ctxt.handle = ocfs2_start_trans(osb, OCFS2_XATTR_BLOCK_CREATE_CREDITS);
6448 if (IS_ERR(handle)) { 6447 if (IS_ERR(ctxt.handle)) {
6449 ret = PTR_ERR(handle); 6448 ret = PTR_ERR(ctxt.handle);
6450 mlog_errno(ret); 6449 mlog_errno(ret);
6451 goto out; 6450 goto out;
6452 } 6451 }
6453 6452
6454 mlog(0, "create new xattr block for inode %llu, index = %d\n", 6453 mlog(0, "create new xattr block for inode %llu, index = %d\n",
6455 (unsigned long long)fe_bh->b_blocknr, indexed); 6454 (unsigned long long)fe_bh->b_blocknr, indexed);
6456 ret = ocfs2_create_xattr_block(handle, inode, fe_bh, 6455 ret = ocfs2_create_xattr_block(inode, fe_bh, &ctxt, indexed,
6457 meta_ac, ret_bh, indexed); 6456 ret_bh);
6458 if (ret) 6457 if (ret)
6459 mlog_errno(ret); 6458 mlog_errno(ret);
6460 6459
6461 ocfs2_commit_trans(osb, handle); 6460 ocfs2_commit_trans(osb, ctxt.handle);
6462out: 6461out:
6463 ocfs2_free_alloc_context(meta_ac); 6462 ocfs2_free_alloc_context(meta_ac);
6464 return ret; 6463 return ret;