diff options
| author | Tao Ma <tao.ma@oracle.com> | 2009-08-17 23:43:24 -0400 |
|---|---|---|
| committer | Joel Becker <joel.becker@oracle.com> | 2009-09-22 23:09:42 -0400 |
| commit | 5aea1f0ef4024ba28213c10181e1b16ec678c82d (patch) | |
| tree | ca28a8214cf9a8761fbac6b5e8aef84aa22fff54 | |
| parent | fd68a894fc9641f816d9cffa58e853ba91cbc1a1 (diff) | |
ocfs2: Abstract the creation of xattr block.
In xattr reflink, we also need to create xattr block, so
abstract the process out.
Signed-off-by: Tao Ma <tao.ma@oracle.com>
| -rw-r--r-- | fs/ocfs2/xattr.c | 115 |
1 files changed, 70 insertions, 45 deletions
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c index eeb5b7caf195..a9339eb94a2e 100644 --- a/fs/ocfs2/xattr.c +++ b/fs/ocfs2/xattr.c | |||
| @@ -2105,6 +2105,72 @@ cleanup: | |||
| 2105 | return ret; | 2105 | return ret; |
| 2106 | } | 2106 | } |
| 2107 | 2107 | ||
| 2108 | static int ocfs2_create_xattr_block(handle_t *handle, | ||
| 2109 | struct inode *inode, | ||
| 2110 | struct buffer_head *inode_bh, | ||
| 2111 | struct ocfs2_alloc_context *meta_ac, | ||
| 2112 | struct buffer_head **ret_bh) | ||
| 2113 | { | ||
| 2114 | int ret; | ||
| 2115 | u16 suballoc_bit_start; | ||
| 2116 | u32 num_got; | ||
| 2117 | u64 first_blkno; | ||
| 2118 | struct ocfs2_dinode *di = (struct ocfs2_dinode *)inode_bh->b_data; | ||
| 2119 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | ||
| 2120 | struct buffer_head *new_bh = NULL; | ||
| 2121 | struct ocfs2_xattr_block *xblk; | ||
| 2122 | |||
| 2123 | ret = ocfs2_journal_access_di(handle, INODE_CACHE(inode), inode_bh, | ||
| 2124 | OCFS2_JOURNAL_ACCESS_CREATE); | ||
| 2125 | if (ret < 0) { | ||
| 2126 | mlog_errno(ret); | ||
| 2127 | goto end; | ||
| 2128 | } | ||
| 2129 | |||
| 2130 | ret = ocfs2_claim_metadata(osb, handle, meta_ac, 1, | ||
| 2131 | &suballoc_bit_start, &num_got, | ||
| 2132 | &first_blkno); | ||
| 2133 | if (ret < 0) { | ||
| 2134 | mlog_errno(ret); | ||
| 2135 | goto end; | ||
| 2136 | } | ||
| 2137 | |||
| 2138 | new_bh = sb_getblk(inode->i_sb, first_blkno); | ||
| 2139 | ocfs2_set_new_buffer_uptodate(INODE_CACHE(inode), new_bh); | ||
| 2140 | |||
| 2141 | ret = ocfs2_journal_access_xb(handle, INODE_CACHE(inode), | ||
| 2142 | new_bh, | ||
| 2143 | OCFS2_JOURNAL_ACCESS_CREATE); | ||
| 2144 | if (ret < 0) { | ||
| 2145 | mlog_errno(ret); | ||
| 2146 | goto end; | ||
| 2147 | } | ||
| 2148 | |||
| 2149 | /* Initialize ocfs2_xattr_block */ | ||
| 2150 | xblk = (struct ocfs2_xattr_block *)new_bh->b_data; | ||
| 2151 | memset(xblk, 0, inode->i_sb->s_blocksize); | ||
| 2152 | strcpy((void *)xblk, OCFS2_XATTR_BLOCK_SIGNATURE); | ||
| 2153 | xblk->xb_suballoc_slot = cpu_to_le16(osb->slot_num); | ||
| 2154 | xblk->xb_suballoc_bit = cpu_to_le16(suballoc_bit_start); | ||
| 2155 | xblk->xb_fs_generation = cpu_to_le32(osb->fs_generation); | ||
| 2156 | xblk->xb_blkno = cpu_to_le64(first_blkno); | ||
| 2157 | |||
| 2158 | ret = ocfs2_journal_dirty(handle, new_bh); | ||
| 2159 | if (ret < 0) { | ||
| 2160 | mlog_errno(ret); | ||
| 2161 | goto end; | ||
| 2162 | } | ||
| 2163 | di->i_xattr_loc = cpu_to_le64(first_blkno); | ||
| 2164 | ocfs2_journal_dirty(handle, inode_bh); | ||
| 2165 | |||
| 2166 | *ret_bh = new_bh; | ||
| 2167 | new_bh = NULL; | ||
| 2168 | |||
| 2169 | end: | ||
| 2170 | brelse(new_bh); | ||
| 2171 | return ret; | ||
| 2172 | } | ||
| 2173 | |||
| 2108 | /* | 2174 | /* |
| 2109 | * ocfs2_xattr_block_set() | 2175 | * ocfs2_xattr_block_set() |
| 2110 | * | 2176 | * |
| @@ -2117,65 +2183,24 @@ static int ocfs2_xattr_block_set(struct inode *inode, | |||
| 2117 | struct ocfs2_xattr_set_ctxt *ctxt) | 2183 | struct ocfs2_xattr_set_ctxt *ctxt) |
| 2118 | { | 2184 | { |
| 2119 | struct buffer_head *new_bh = NULL; | 2185 | struct buffer_head *new_bh = NULL; |
| 2120 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | ||
| 2121 | struct ocfs2_dinode *di = (struct ocfs2_dinode *)xs->inode_bh->b_data; | ||
| 2122 | handle_t *handle = ctxt->handle; | 2186 | handle_t *handle = ctxt->handle; |
| 2123 | struct ocfs2_xattr_block *xblk = NULL; | 2187 | struct ocfs2_xattr_block *xblk = NULL; |
| 2124 | u16 suballoc_bit_start; | ||
| 2125 | u32 num_got; | ||
| 2126 | u64 first_blkno; | ||
| 2127 | int ret; | 2188 | int ret; |
| 2128 | 2189 | ||
| 2129 | if (!xs->xattr_bh) { | 2190 | if (!xs->xattr_bh) { |
| 2130 | ret = ocfs2_journal_access_di(handle, INODE_CACHE(inode), | 2191 | ret = ocfs2_create_xattr_block(handle, inode, xs->inode_bh, |
| 2131 | xs->inode_bh, | 2192 | ctxt->meta_ac, &new_bh); |
| 2132 | OCFS2_JOURNAL_ACCESS_CREATE); | 2193 | if (ret) { |
| 2133 | if (ret < 0) { | ||
| 2134 | mlog_errno(ret); | ||
| 2135 | goto end; | ||
| 2136 | } | ||
| 2137 | |||
| 2138 | ret = ocfs2_claim_metadata(osb, handle, ctxt->meta_ac, 1, | ||
| 2139 | &suballoc_bit_start, &num_got, | ||
| 2140 | &first_blkno); | ||
| 2141 | if (ret < 0) { | ||
| 2142 | mlog_errno(ret); | ||
| 2143 | goto end; | ||
| 2144 | } | ||
| 2145 | |||
| 2146 | new_bh = sb_getblk(inode->i_sb, first_blkno); | ||
| 2147 | ocfs2_set_new_buffer_uptodate(INODE_CACHE(inode), new_bh); | ||
| 2148 | |||
| 2149 | ret = ocfs2_journal_access_xb(handle, INODE_CACHE(inode), | ||
| 2150 | new_bh, | ||
| 2151 | OCFS2_JOURNAL_ACCESS_CREATE); | ||
| 2152 | if (ret < 0) { | ||
| 2153 | mlog_errno(ret); | 2194 | mlog_errno(ret); |
| 2154 | goto end; | 2195 | goto end; |
| 2155 | } | 2196 | } |
| 2156 | 2197 | ||
| 2157 | /* Initialize ocfs2_xattr_block */ | ||
| 2158 | xs->xattr_bh = new_bh; | 2198 | xs->xattr_bh = new_bh; |
| 2159 | xblk = (struct ocfs2_xattr_block *)new_bh->b_data; | 2199 | xblk = (struct ocfs2_xattr_block *)xs->xattr_bh->b_data; |
| 2160 | memset(xblk, 0, inode->i_sb->s_blocksize); | ||
| 2161 | strcpy((void *)xblk, OCFS2_XATTR_BLOCK_SIGNATURE); | ||
| 2162 | xblk->xb_suballoc_slot = cpu_to_le16(osb->slot_num); | ||
| 2163 | xblk->xb_suballoc_bit = cpu_to_le16(suballoc_bit_start); | ||
| 2164 | xblk->xb_fs_generation = cpu_to_le32(osb->fs_generation); | ||
| 2165 | xblk->xb_blkno = cpu_to_le64(first_blkno); | ||
| 2166 | |||
| 2167 | xs->header = &xblk->xb_attrs.xb_header; | 2200 | xs->header = &xblk->xb_attrs.xb_header; |
| 2168 | xs->base = (void *)xs->header; | 2201 | xs->base = (void *)xs->header; |
| 2169 | xs->end = (void *)xblk + inode->i_sb->s_blocksize; | 2202 | xs->end = (void *)xblk + inode->i_sb->s_blocksize; |
| 2170 | xs->here = xs->header->xh_entries; | 2203 | xs->here = xs->header->xh_entries; |
| 2171 | |||
| 2172 | ret = ocfs2_journal_dirty(handle, new_bh); | ||
| 2173 | if (ret < 0) { | ||
| 2174 | mlog_errno(ret); | ||
| 2175 | goto end; | ||
| 2176 | } | ||
| 2177 | di->i_xattr_loc = cpu_to_le64(first_blkno); | ||
| 2178 | ocfs2_journal_dirty(handle, xs->inode_bh); | ||
| 2179 | } else | 2204 | } else |
| 2180 | xblk = (struct ocfs2_xattr_block *)xs->xattr_bh->b_data; | 2205 | xblk = (struct ocfs2_xattr_block *)xs->xattr_bh->b_data; |
| 2181 | 2206 | ||
