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 | |
| 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>
| -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) | ||
