diff options
author | Tao Ma <tao.ma@oracle.com> | 2008-08-18 05:38:49 -0400 |
---|---|---|
committer | Mark Fasheh <mfasheh@suse.com> | 2008-10-13 19:57:02 -0400 |
commit | ba492615f0d32d0210b02c14b24512b4372b13d6 (patch) | |
tree | 65275171ba8543a497037c5a159701a06277af4b /fs/ocfs2 | |
parent | cf1d6c763fbcb115263114302485ad17e7933d87 (diff) |
ocfs2: Add xattr index tree operations
When necessary, an ocfs2_xattr_block will embed an ocfs2_extent_list to
store large numbers of EAs. This patch adds a new type in
ocfs2_extent_tree_type and adds the implementation so that we can re-use the
b-tree code to handle the storage of many EAs.
Signed-off-by: Tao Ma <tao.ma@oracle.com>
Signed-off-by: Mark Fasheh <mfasheh@suse.com>
Diffstat (limited to 'fs/ocfs2')
-rw-r--r-- | fs/ocfs2/alloc.c | 89 | ||||
-rw-r--r-- | fs/ocfs2/alloc.h | 10 |
2 files changed, 99 insertions, 0 deletions
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c index ace27d1ca574..06ea7913c134 100644 --- a/fs/ocfs2/alloc.c +++ b/fs/ocfs2/alloc.c | |||
@@ -177,6 +177,48 @@ static struct ocfs2_extent_tree_operations ocfs2_xattr_et_ops = { | |||
177 | .sanity_check = ocfs2_xattr_value_sanity_check, | 177 | .sanity_check = ocfs2_xattr_value_sanity_check, |
178 | }; | 178 | }; |
179 | 179 | ||
180 | static void ocfs2_xattr_tree_set_last_eb_blk(struct ocfs2_extent_tree *et, | ||
181 | u64 blkno) | ||
182 | { | ||
183 | struct ocfs2_xattr_block *xb = | ||
184 | (struct ocfs2_xattr_block *) et->root_bh->b_data; | ||
185 | struct ocfs2_xattr_tree_root *xt = &xb->xb_attrs.xb_root; | ||
186 | |||
187 | xt->xt_last_eb_blk = cpu_to_le64(blkno); | ||
188 | } | ||
189 | |||
190 | static u64 ocfs2_xattr_tree_get_last_eb_blk(struct ocfs2_extent_tree *et) | ||
191 | { | ||
192 | struct ocfs2_xattr_block *xb = | ||
193 | (struct ocfs2_xattr_block *) et->root_bh->b_data; | ||
194 | struct ocfs2_xattr_tree_root *xt = &xb->xb_attrs.xb_root; | ||
195 | |||
196 | return le64_to_cpu(xt->xt_last_eb_blk); | ||
197 | } | ||
198 | |||
199 | static void ocfs2_xattr_tree_update_clusters(struct inode *inode, | ||
200 | struct ocfs2_extent_tree *et, | ||
201 | u32 clusters) | ||
202 | { | ||
203 | struct ocfs2_xattr_block *xb = | ||
204 | (struct ocfs2_xattr_block *)et->root_bh->b_data; | ||
205 | |||
206 | le32_add_cpu(&xb->xb_attrs.xb_root.xt_clusters, clusters); | ||
207 | } | ||
208 | |||
209 | static int ocfs2_xattr_tree_sanity_check(struct inode *inode, | ||
210 | struct ocfs2_extent_tree *et) | ||
211 | { | ||
212 | return 0; | ||
213 | } | ||
214 | |||
215 | static struct ocfs2_extent_tree_operations ocfs2_xattr_tree_et_ops = { | ||
216 | .set_last_eb_blk = ocfs2_xattr_tree_set_last_eb_blk, | ||
217 | .get_last_eb_blk = ocfs2_xattr_tree_get_last_eb_blk, | ||
218 | .update_clusters = ocfs2_xattr_tree_update_clusters, | ||
219 | .sanity_check = ocfs2_xattr_tree_sanity_check, | ||
220 | }; | ||
221 | |||
180 | static struct ocfs2_extent_tree* | 222 | static struct ocfs2_extent_tree* |
181 | ocfs2_new_extent_tree(struct buffer_head *bh, | 223 | ocfs2_new_extent_tree(struct buffer_head *bh, |
182 | enum ocfs2_extent_tree_type et_type, | 224 | enum ocfs2_extent_tree_type et_type, |
@@ -201,6 +243,11 @@ static struct ocfs2_extent_tree* | |||
201 | (struct ocfs2_xattr_value_root *) private; | 243 | (struct ocfs2_xattr_value_root *) private; |
202 | et->root_el = &xv->xr_list; | 244 | et->root_el = &xv->xr_list; |
203 | et->eops = &ocfs2_xattr_et_ops; | 245 | et->eops = &ocfs2_xattr_et_ops; |
246 | } else if (et_type == OCFS2_XATTR_TREE_EXTENT) { | ||
247 | struct ocfs2_xattr_block *xb = | ||
248 | (struct ocfs2_xattr_block *)bh->b_data; | ||
249 | et->root_el = &xb->xb_attrs.xb_root.xt_list; | ||
250 | et->eops = &ocfs2_xattr_tree_et_ops; | ||
204 | } | 251 | } |
205 | 252 | ||
206 | return et; | 253 | return et; |
@@ -570,6 +617,12 @@ int ocfs2_num_free_extents(struct ocfs2_super *osb, | |||
570 | 617 | ||
571 | last_eb_blk = le64_to_cpu(xv->xr_last_eb_blk); | 618 | last_eb_blk = le64_to_cpu(xv->xr_last_eb_blk); |
572 | el = &xv->xr_list; | 619 | el = &xv->xr_list; |
620 | } else if (type == OCFS2_XATTR_TREE_EXTENT) { | ||
621 | struct ocfs2_xattr_block *xb = | ||
622 | (struct ocfs2_xattr_block *)root_bh->b_data; | ||
623 | |||
624 | last_eb_blk = le64_to_cpu(xb->xb_attrs.xb_root.xt_last_eb_blk); | ||
625 | el = &xb->xb_attrs.xb_root.xt_list; | ||
573 | } | 626 | } |
574 | 627 | ||
575 | if (last_eb_blk) { | 628 | if (last_eb_blk) { |
@@ -4397,6 +4450,36 @@ bail: | |||
4397 | return status; | 4450 | return status; |
4398 | } | 4451 | } |
4399 | 4452 | ||
4453 | int ocfs2_xattr_tree_insert_extent(struct ocfs2_super *osb, | ||
4454 | handle_t *handle, | ||
4455 | struct inode *inode, | ||
4456 | struct buffer_head *root_bh, | ||
4457 | u32 cpos, | ||
4458 | u64 start_blk, | ||
4459 | u32 new_clusters, | ||
4460 | u8 flags, | ||
4461 | struct ocfs2_alloc_context *meta_ac) | ||
4462 | { | ||
4463 | int status; | ||
4464 | struct ocfs2_extent_tree *et = NULL; | ||
4465 | |||
4466 | et = ocfs2_new_extent_tree(root_bh, OCFS2_XATTR_TREE_EXTENT, NULL); | ||
4467 | if (!et) { | ||
4468 | status = -ENOMEM; | ||
4469 | mlog_errno(status); | ||
4470 | goto bail; | ||
4471 | } | ||
4472 | |||
4473 | status = ocfs2_insert_extent(osb, handle, inode, root_bh, | ||
4474 | cpos, start_blk, new_clusters, | ||
4475 | flags, meta_ac, et); | ||
4476 | |||
4477 | if (et) | ||
4478 | ocfs2_free_extent_tree(et); | ||
4479 | bail: | ||
4480 | return status; | ||
4481 | } | ||
4482 | |||
4400 | /* | 4483 | /* |
4401 | * Allcate and add clusters into the extent b-tree. | 4484 | * Allcate and add clusters into the extent b-tree. |
4402 | * The new clusters(clusters_to_add) will be inserted at logical_offset. | 4485 | * The new clusters(clusters_to_add) will be inserted at logical_offset. |
@@ -4482,6 +4565,12 @@ int ocfs2_add_clusters_in_btree(struct ocfs2_super *osb, | |||
4482 | status = ocfs2_dinode_insert_extent(osb, handle, inode, root_bh, | 4565 | status = ocfs2_dinode_insert_extent(osb, handle, inode, root_bh, |
4483 | *logical_offset, block, | 4566 | *logical_offset, block, |
4484 | num_bits, flags, meta_ac); | 4567 | num_bits, flags, meta_ac); |
4568 | else if (type == OCFS2_XATTR_TREE_EXTENT) | ||
4569 | status = ocfs2_xattr_tree_insert_extent(osb, handle, | ||
4570 | inode, root_bh, | ||
4571 | *logical_offset, | ||
4572 | block, num_bits, flags, | ||
4573 | meta_ac); | ||
4485 | else | 4574 | else |
4486 | status = ocfs2_xattr_value_insert_extent(osb, handle, | 4575 | status = ocfs2_xattr_value_insert_extent(osb, handle, |
4487 | inode, root_bh, | 4576 | inode, root_bh, |
diff --git a/fs/ocfs2/alloc.h b/fs/ocfs2/alloc.h index ec7baeb2ea7d..cd4e12d2b6b9 100644 --- a/fs/ocfs2/alloc.h +++ b/fs/ocfs2/alloc.h | |||
@@ -29,6 +29,7 @@ | |||
29 | enum ocfs2_extent_tree_type { | 29 | enum ocfs2_extent_tree_type { |
30 | OCFS2_DINODE_EXTENT = 0, | 30 | OCFS2_DINODE_EXTENT = 0, |
31 | OCFS2_XATTR_VALUE_EXTENT, | 31 | OCFS2_XATTR_VALUE_EXTENT, |
32 | OCFS2_XATTR_TREE_EXTENT, | ||
32 | }; | 33 | }; |
33 | 34 | ||
34 | struct ocfs2_alloc_context; | 35 | struct ocfs2_alloc_context; |
@@ -51,6 +52,15 @@ int ocfs2_xattr_value_insert_extent(struct ocfs2_super *osb, | |||
51 | u8 flags, | 52 | u8 flags, |
52 | struct ocfs2_alloc_context *meta_ac, | 53 | struct ocfs2_alloc_context *meta_ac, |
53 | void *private); | 54 | void *private); |
55 | int ocfs2_xattr_tree_insert_extent(struct ocfs2_super *osb, | ||
56 | handle_t *handle, | ||
57 | struct inode *inode, | ||
58 | struct buffer_head *root_bh, | ||
59 | u32 cpos, | ||
60 | u64 start_blk, | ||
61 | u32 new_clusters, | ||
62 | u8 flags, | ||
63 | struct ocfs2_alloc_context *meta_ac); | ||
54 | enum ocfs2_alloc_restarted { | 64 | enum ocfs2_alloc_restarted { |
55 | RESTART_NONE = 0, | 65 | RESTART_NONE = 0, |
56 | RESTART_TRANS, | 66 | RESTART_TRANS, |