diff options
author | Joel Becker <joel.becker@oracle.com> | 2009-08-19 05:13:50 -0400 |
---|---|---|
committer | Joel Becker <joel.becker@oracle.com> | 2010-02-26 18:41:13 -0500 |
commit | d3981544d7a4ed276966cdd58fe2f5d6e8a585d9 (patch) | |
tree | a2a90d6a67c40fac4b56edd524b08a8c52179570 /fs/ocfs2/xattr.c | |
parent | c5d95df5f78312c879f3058059c98a08821897a5 (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.c | 99 |
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 | ||
2751 | static int ocfs2_create_xattr_block(handle_t *handle, | 2743 | static 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 | ||
2876 | end: | 2874 | end: |
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); |
6462 | out: | 6461 | out: |
6463 | ocfs2_free_alloc_context(meta_ac); | 6462 | ocfs2_free_alloc_context(meta_ac); |
6464 | return ret; | 6463 | return ret; |