diff options
Diffstat (limited to 'fs/ocfs2/alloc.c')
-rw-r--r-- | fs/ocfs2/alloc.c | 300 |
1 files changed, 90 insertions, 210 deletions
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c index ce54730e18ff..786a82982622 100644 --- a/fs/ocfs2/alloc.c +++ b/fs/ocfs2/alloc.c | |||
@@ -49,20 +49,6 @@ | |||
49 | 49 | ||
50 | #include "buffer_head_io.h" | 50 | #include "buffer_head_io.h" |
51 | 51 | ||
52 | /* | ||
53 | * ocfs2_extent_tree and ocfs2_extent_tree_operations are used to abstract | ||
54 | * the b-tree operations in ocfs2. Now all the b-tree operations are not | ||
55 | * limited to ocfs2_dinode only. Any data which need to allocate clusters | ||
56 | * to store can use b-tree. And it only needs to implement its ocfs2_extent_tree | ||
57 | * and operation. | ||
58 | * | ||
59 | * ocfs2_extent_tree contains info for the root of the b-tree, it must have a | ||
60 | * root ocfs2_extent_list and a root_bh so that they can be used in the b-tree | ||
61 | * functions. | ||
62 | * ocfs2_extent_tree_operations abstract the normal operations we do for | ||
63 | * the root of extent b-tree. | ||
64 | */ | ||
65 | struct ocfs2_extent_tree; | ||
66 | 52 | ||
67 | struct ocfs2_extent_tree_operations { | 53 | struct ocfs2_extent_tree_operations { |
68 | void (*eo_set_last_eb_blk)(struct ocfs2_extent_tree *et, | 54 | void (*eo_set_last_eb_blk)(struct ocfs2_extent_tree *et, |
@@ -83,28 +69,38 @@ struct ocfs2_extent_tree_operations { | |||
83 | struct ocfs2_extent_tree *et); | 69 | struct ocfs2_extent_tree *et); |
84 | }; | 70 | }; |
85 | 71 | ||
86 | struct ocfs2_extent_tree { | ||
87 | enum ocfs2_extent_tree_type et_type; | ||
88 | struct ocfs2_extent_tree_operations *et_ops; | ||
89 | struct buffer_head *et_root_bh; | ||
90 | struct ocfs2_extent_list *et_root_el; | ||
91 | void *et_object; | ||
92 | unsigned int et_max_leaf_clusters; | ||
93 | }; | ||
94 | 72 | ||
95 | static void ocfs2_dinode_fill_root_el(struct ocfs2_extent_tree *et) | 73 | /* |
96 | { | 74 | * Pre-declare ocfs2_dinode_et_ops so we can use it as a sanity check |
97 | struct ocfs2_dinode *di = et->et_object; | 75 | * in the methods. |
98 | 76 | */ | |
99 | et->et_root_el = &di->id2.i_list; | 77 | static u64 ocfs2_dinode_get_last_eb_blk(struct ocfs2_extent_tree *et); |
100 | } | 78 | static void ocfs2_dinode_set_last_eb_blk(struct ocfs2_extent_tree *et, |
79 | u64 blkno); | ||
80 | static void ocfs2_dinode_update_clusters(struct inode *inode, | ||
81 | struct ocfs2_extent_tree *et, | ||
82 | u32 clusters); | ||
83 | static int ocfs2_dinode_insert_check(struct inode *inode, | ||
84 | struct ocfs2_extent_tree *et, | ||
85 | struct ocfs2_extent_rec *rec); | ||
86 | static int ocfs2_dinode_sanity_check(struct inode *inode, | ||
87 | struct ocfs2_extent_tree *et); | ||
88 | static void ocfs2_dinode_fill_root_el(struct ocfs2_extent_tree *et); | ||
89 | static struct ocfs2_extent_tree_operations ocfs2_dinode_et_ops = { | ||
90 | .eo_set_last_eb_blk = ocfs2_dinode_set_last_eb_blk, | ||
91 | .eo_get_last_eb_blk = ocfs2_dinode_get_last_eb_blk, | ||
92 | .eo_update_clusters = ocfs2_dinode_update_clusters, | ||
93 | .eo_insert_check = ocfs2_dinode_insert_check, | ||
94 | .eo_sanity_check = ocfs2_dinode_sanity_check, | ||
95 | .eo_fill_root_el = ocfs2_dinode_fill_root_el, | ||
96 | }; | ||
101 | 97 | ||
102 | static void ocfs2_dinode_set_last_eb_blk(struct ocfs2_extent_tree *et, | 98 | static void ocfs2_dinode_set_last_eb_blk(struct ocfs2_extent_tree *et, |
103 | u64 blkno) | 99 | u64 blkno) |
104 | { | 100 | { |
105 | struct ocfs2_dinode *di = et->et_object; | 101 | struct ocfs2_dinode *di = et->et_object; |
106 | 102 | ||
107 | BUG_ON(et->et_type != OCFS2_DINODE_EXTENT); | 103 | BUG_ON(et->et_ops != &ocfs2_dinode_et_ops); |
108 | di->i_last_eb_blk = cpu_to_le64(blkno); | 104 | di->i_last_eb_blk = cpu_to_le64(blkno); |
109 | } | 105 | } |
110 | 106 | ||
@@ -112,7 +108,7 @@ static u64 ocfs2_dinode_get_last_eb_blk(struct ocfs2_extent_tree *et) | |||
112 | { | 108 | { |
113 | struct ocfs2_dinode *di = et->et_object; | 109 | struct ocfs2_dinode *di = et->et_object; |
114 | 110 | ||
115 | BUG_ON(et->et_type != OCFS2_DINODE_EXTENT); | 111 | BUG_ON(et->et_ops != &ocfs2_dinode_et_ops); |
116 | return le64_to_cpu(di->i_last_eb_blk); | 112 | return le64_to_cpu(di->i_last_eb_blk); |
117 | } | 113 | } |
118 | 114 | ||
@@ -153,7 +149,7 @@ static int ocfs2_dinode_sanity_check(struct inode *inode, | |||
153 | int ret = 0; | 149 | int ret = 0; |
154 | struct ocfs2_dinode *di; | 150 | struct ocfs2_dinode *di; |
155 | 151 | ||
156 | BUG_ON(et->et_type != OCFS2_DINODE_EXTENT); | 152 | BUG_ON(et->et_ops != &ocfs2_dinode_et_ops); |
157 | 153 | ||
158 | di = et->et_object; | 154 | di = et->et_object; |
159 | if (!OCFS2_IS_VALID_DINODE(di)) { | 155 | if (!OCFS2_IS_VALID_DINODE(di)) { |
@@ -166,14 +162,13 @@ static int ocfs2_dinode_sanity_check(struct inode *inode, | |||
166 | return ret; | 162 | return ret; |
167 | } | 163 | } |
168 | 164 | ||
169 | static struct ocfs2_extent_tree_operations ocfs2_dinode_et_ops = { | 165 | static void ocfs2_dinode_fill_root_el(struct ocfs2_extent_tree *et) |
170 | .eo_set_last_eb_blk = ocfs2_dinode_set_last_eb_blk, | 166 | { |
171 | .eo_get_last_eb_blk = ocfs2_dinode_get_last_eb_blk, | 167 | struct ocfs2_dinode *di = et->et_object; |
172 | .eo_update_clusters = ocfs2_dinode_update_clusters, | 168 | |
173 | .eo_insert_check = ocfs2_dinode_insert_check, | 169 | et->et_root_el = &di->id2.i_list; |
174 | .eo_sanity_check = ocfs2_dinode_sanity_check, | 170 | } |
175 | .eo_fill_root_el = ocfs2_dinode_fill_root_el, | 171 | |
176 | }; | ||
177 | 172 | ||
178 | static void ocfs2_xattr_value_fill_root_el(struct ocfs2_extent_tree *et) | 173 | static void ocfs2_xattr_value_fill_root_el(struct ocfs2_extent_tree *et) |
179 | { | 174 | { |
@@ -269,10 +264,8 @@ static void __ocfs2_get_extent_tree(struct ocfs2_extent_tree *et, | |||
269 | struct inode *inode, | 264 | struct inode *inode, |
270 | struct buffer_head *bh, | 265 | struct buffer_head *bh, |
271 | void *obj, | 266 | void *obj, |
272 | enum ocfs2_extent_tree_type et_type, | ||
273 | struct ocfs2_extent_tree_operations *ops) | 267 | struct ocfs2_extent_tree_operations *ops) |
274 | { | 268 | { |
275 | et->et_type = et_type; | ||
276 | et->et_ops = ops; | 269 | et->et_ops = ops; |
277 | get_bh(bh); | 270 | get_bh(bh); |
278 | et->et_root_bh = bh; | 271 | et->et_root_bh = bh; |
@@ -287,50 +280,31 @@ static void __ocfs2_get_extent_tree(struct ocfs2_extent_tree *et, | |||
287 | et->et_ops->eo_fill_max_leaf_clusters(inode, et); | 280 | et->et_ops->eo_fill_max_leaf_clusters(inode, et); |
288 | } | 281 | } |
289 | 282 | ||
290 | static void ocfs2_get_dinode_extent_tree(struct ocfs2_extent_tree *et, | 283 | void ocfs2_get_dinode_extent_tree(struct ocfs2_extent_tree *et, |
291 | struct inode *inode, | 284 | struct inode *inode, |
292 | struct buffer_head *bh) | 285 | struct buffer_head *bh) |
293 | { | 286 | { |
294 | __ocfs2_get_extent_tree(et, inode, bh, NULL, OCFS2_DINODE_EXTENT, | 287 | __ocfs2_get_extent_tree(et, inode, bh, NULL, &ocfs2_dinode_et_ops); |
295 | &ocfs2_dinode_et_ops); | ||
296 | } | 288 | } |
297 | 289 | ||
298 | static void ocfs2_get_xattr_tree_extent_tree(struct ocfs2_extent_tree *et, | 290 | void ocfs2_get_xattr_tree_extent_tree(struct ocfs2_extent_tree *et, |
299 | struct inode *inode, | 291 | struct inode *inode, |
300 | struct buffer_head *bh) | 292 | struct buffer_head *bh) |
301 | { | 293 | { |
302 | __ocfs2_get_extent_tree(et, inode, bh, NULL, | 294 | __ocfs2_get_extent_tree(et, inode, bh, NULL, |
303 | OCFS2_XATTR_TREE_EXTENT, | ||
304 | &ocfs2_xattr_tree_et_ops); | 295 | &ocfs2_xattr_tree_et_ops); |
305 | } | 296 | } |
306 | 297 | ||
307 | static void ocfs2_get_xattr_value_extent_tree(struct ocfs2_extent_tree *et, | 298 | void ocfs2_get_xattr_value_extent_tree(struct ocfs2_extent_tree *et, |
308 | struct inode *inode, | 299 | struct inode *inode, |
309 | struct buffer_head *bh, | 300 | struct buffer_head *bh, |
310 | struct ocfs2_xattr_value_root *xv) | 301 | struct ocfs2_xattr_value_root *xv) |
311 | { | 302 | { |
312 | __ocfs2_get_extent_tree(et, inode, bh, xv, | 303 | __ocfs2_get_extent_tree(et, inode, bh, xv, |
313 | OCFS2_XATTR_VALUE_EXTENT, | ||
314 | &ocfs2_xattr_value_et_ops); | 304 | &ocfs2_xattr_value_et_ops); |
315 | } | 305 | } |
316 | 306 | ||
317 | static void ocfs2_get_extent_tree(struct ocfs2_extent_tree *et, | 307 | void ocfs2_put_extent_tree(struct ocfs2_extent_tree *et) |
318 | struct inode *inode, | ||
319 | struct buffer_head *bh, | ||
320 | enum ocfs2_extent_tree_type et_type, | ||
321 | void *obj) | ||
322 | { | ||
323 | if (et_type == OCFS2_DINODE_EXTENT) | ||
324 | ocfs2_get_dinode_extent_tree(et, inode, bh); | ||
325 | else if (et_type == OCFS2_XATTR_VALUE_EXTENT) | ||
326 | ocfs2_get_xattr_tree_extent_tree(et, inode, bh); | ||
327 | else if (et_type == OCFS2_XATTR_TREE_EXTENT) | ||
328 | ocfs2_get_xattr_value_extent_tree(et, inode, bh, obj); | ||
329 | else | ||
330 | BUG(); | ||
331 | } | ||
332 | |||
333 | static void ocfs2_put_extent_tree(struct ocfs2_extent_tree *et) | ||
334 | { | 308 | { |
335 | brelse(et->et_root_bh); | 309 | brelse(et->et_root_bh); |
336 | } | 310 | } |
@@ -682,22 +656,18 @@ struct ocfs2_merge_ctxt { | |||
682 | */ | 656 | */ |
683 | int ocfs2_num_free_extents(struct ocfs2_super *osb, | 657 | int ocfs2_num_free_extents(struct ocfs2_super *osb, |
684 | struct inode *inode, | 658 | struct inode *inode, |
685 | struct buffer_head *root_bh, | 659 | struct ocfs2_extent_tree *et) |
686 | enum ocfs2_extent_tree_type type, | ||
687 | void *obj) | ||
688 | { | 660 | { |
689 | int retval; | 661 | int retval; |
690 | struct ocfs2_extent_list *el = NULL; | 662 | struct ocfs2_extent_list *el = NULL; |
691 | struct ocfs2_extent_block *eb; | 663 | struct ocfs2_extent_block *eb; |
692 | struct buffer_head *eb_bh = NULL; | 664 | struct buffer_head *eb_bh = NULL; |
693 | u64 last_eb_blk = 0; | 665 | u64 last_eb_blk = 0; |
694 | struct ocfs2_extent_tree et; | ||
695 | 666 | ||
696 | mlog_entry_void(); | 667 | mlog_entry_void(); |
697 | 668 | ||
698 | ocfs2_get_extent_tree(&et, inode, root_bh, type, obj); | 669 | el = et->et_root_el; |
699 | el = et.et_root_el; | 670 | last_eb_blk = ocfs2_et_get_last_eb_blk(et); |
700 | last_eb_blk = ocfs2_et_get_last_eb_blk(&et); | ||
701 | 671 | ||
702 | if (last_eb_blk) { | 672 | if (last_eb_blk) { |
703 | retval = ocfs2_read_block(osb, last_eb_blk, | 673 | retval = ocfs2_read_block(osb, last_eb_blk, |
@@ -717,7 +687,6 @@ bail: | |||
717 | if (eb_bh) | 687 | if (eb_bh) |
718 | brelse(eb_bh); | 688 | brelse(eb_bh); |
719 | 689 | ||
720 | ocfs2_put_extent_tree(&et); | ||
721 | mlog_exit(retval); | 690 | mlog_exit(retval); |
722 | return retval; | 691 | return retval; |
723 | } | 692 | } |
@@ -4406,16 +4375,15 @@ out: | |||
4406 | * | 4375 | * |
4407 | * The caller needs to update fe->i_clusters | 4376 | * The caller needs to update fe->i_clusters |
4408 | */ | 4377 | */ |
4409 | static int ocfs2_insert_extent(struct ocfs2_super *osb, | 4378 | int ocfs2_insert_extent(struct ocfs2_super *osb, |
4410 | handle_t *handle, | 4379 | handle_t *handle, |
4411 | struct inode *inode, | 4380 | struct inode *inode, |
4412 | struct buffer_head *root_bh, | 4381 | struct ocfs2_extent_tree *et, |
4413 | u32 cpos, | 4382 | u32 cpos, |
4414 | u64 start_blk, | 4383 | u64 start_blk, |
4415 | u32 new_clusters, | 4384 | u32 new_clusters, |
4416 | u8 flags, | 4385 | u8 flags, |
4417 | struct ocfs2_alloc_context *meta_ac, | 4386 | struct ocfs2_alloc_context *meta_ac) |
4418 | struct ocfs2_extent_tree *et) | ||
4419 | { | 4387 | { |
4420 | int status; | 4388 | int status; |
4421 | int uninitialized_var(free_records); | 4389 | int uninitialized_var(free_records); |
@@ -4464,7 +4432,7 @@ static int ocfs2_insert_extent(struct ocfs2_super *osb, | |||
4464 | status = ocfs2_do_insert_extent(inode, handle, et, &rec, &insert); | 4432 | status = ocfs2_do_insert_extent(inode, handle, et, &rec, &insert); |
4465 | if (status < 0) | 4433 | if (status < 0) |
4466 | mlog_errno(status); | 4434 | mlog_errno(status); |
4467 | else if (et->et_type == OCFS2_DINODE_EXTENT) | 4435 | else if (et->et_ops == &ocfs2_dinode_et_ops) |
4468 | ocfs2_extent_map_insert_rec(inode, &rec); | 4436 | ocfs2_extent_map_insert_rec(inode, &rec); |
4469 | 4437 | ||
4470 | bail: | 4438 | bail: |
@@ -4475,77 +4443,10 @@ bail: | |||
4475 | return status; | 4443 | return status; |
4476 | } | 4444 | } |
4477 | 4445 | ||
4478 | int ocfs2_dinode_insert_extent(struct ocfs2_super *osb, | ||
4479 | handle_t *handle, | ||
4480 | struct inode *inode, | ||
4481 | struct buffer_head *root_bh, | ||
4482 | u32 cpos, | ||
4483 | u64 start_blk, | ||
4484 | u32 new_clusters, | ||
4485 | u8 flags, | ||
4486 | struct ocfs2_alloc_context *meta_ac) | ||
4487 | { | ||
4488 | int status; | ||
4489 | struct ocfs2_extent_tree et; | ||
4490 | |||
4491 | ocfs2_get_dinode_extent_tree(&et, inode, root_bh); | ||
4492 | status = ocfs2_insert_extent(osb, handle, inode, root_bh, | ||
4493 | cpos, start_blk, new_clusters, | ||
4494 | flags, meta_ac, &et); | ||
4495 | ocfs2_put_extent_tree(&et); | ||
4496 | |||
4497 | return status; | ||
4498 | } | ||
4499 | |||
4500 | int ocfs2_xattr_value_insert_extent(struct ocfs2_super *osb, | ||
4501 | handle_t *handle, | ||
4502 | struct inode *inode, | ||
4503 | struct buffer_head *root_bh, | ||
4504 | u32 cpos, | ||
4505 | u64 start_blk, | ||
4506 | u32 new_clusters, | ||
4507 | u8 flags, | ||
4508 | struct ocfs2_alloc_context *meta_ac, | ||
4509 | struct ocfs2_xattr_value_root *xv) | ||
4510 | { | ||
4511 | int status; | ||
4512 | struct ocfs2_extent_tree et; | ||
4513 | |||
4514 | ocfs2_get_xattr_value_extent_tree(&et, inode, root_bh, xv); | ||
4515 | status = ocfs2_insert_extent(osb, handle, inode, root_bh, | ||
4516 | cpos, start_blk, new_clusters, | ||
4517 | flags, meta_ac, &et); | ||
4518 | ocfs2_put_extent_tree(&et); | ||
4519 | |||
4520 | return status; | ||
4521 | } | ||
4522 | |||
4523 | int ocfs2_xattr_tree_insert_extent(struct ocfs2_super *osb, | ||
4524 | handle_t *handle, | ||
4525 | struct inode *inode, | ||
4526 | struct buffer_head *root_bh, | ||
4527 | u32 cpos, | ||
4528 | u64 start_blk, | ||
4529 | u32 new_clusters, | ||
4530 | u8 flags, | ||
4531 | struct ocfs2_alloc_context *meta_ac) | ||
4532 | { | ||
4533 | int status; | ||
4534 | struct ocfs2_extent_tree et; | ||
4535 | |||
4536 | ocfs2_get_xattr_tree_extent_tree(&et, inode, root_bh); | ||
4537 | status = ocfs2_insert_extent(osb, handle, inode, root_bh, | ||
4538 | cpos, start_blk, new_clusters, | ||
4539 | flags, meta_ac, &et); | ||
4540 | ocfs2_put_extent_tree(&et); | ||
4541 | |||
4542 | return status; | ||
4543 | } | ||
4544 | |||
4545 | /* | 4446 | /* |
4546 | * Allcate and add clusters into the extent b-tree. | 4447 | * Allcate and add clusters into the extent b-tree. |
4547 | * The new clusters(clusters_to_add) will be inserted at logical_offset. | 4448 | * The new clusters(clusters_to_add) will be inserted at logical_offset. |
4548 | * The extent b-tree's root is root_el and it should be in root_bh, and | 4449 | * The extent b-tree's root is specified by et, and |
4549 | * it is not limited to the file storage. Any extent tree can use this | 4450 | * it is not limited to the file storage. Any extent tree can use this |
4550 | * function if it implements the proper ocfs2_extent_tree. | 4451 | * function if it implements the proper ocfs2_extent_tree. |
4551 | */ | 4452 | */ |
@@ -4554,14 +4455,11 @@ int ocfs2_add_clusters_in_btree(struct ocfs2_super *osb, | |||
4554 | u32 *logical_offset, | 4455 | u32 *logical_offset, |
4555 | u32 clusters_to_add, | 4456 | u32 clusters_to_add, |
4556 | int mark_unwritten, | 4457 | int mark_unwritten, |
4557 | struct buffer_head *root_bh, | 4458 | struct ocfs2_extent_tree *et, |
4558 | struct ocfs2_extent_list *root_el, | ||
4559 | handle_t *handle, | 4459 | handle_t *handle, |
4560 | struct ocfs2_alloc_context *data_ac, | 4460 | struct ocfs2_alloc_context *data_ac, |
4561 | struct ocfs2_alloc_context *meta_ac, | 4461 | struct ocfs2_alloc_context *meta_ac, |
4562 | enum ocfs2_alloc_restarted *reason_ret, | 4462 | enum ocfs2_alloc_restarted *reason_ret) |
4563 | enum ocfs2_extent_tree_type type, | ||
4564 | void *obj) | ||
4565 | { | 4463 | { |
4566 | int status = 0; | 4464 | int status = 0; |
4567 | int free_extents; | 4465 | int free_extents; |
@@ -4575,8 +4473,7 @@ int ocfs2_add_clusters_in_btree(struct ocfs2_super *osb, | |||
4575 | if (mark_unwritten) | 4473 | if (mark_unwritten) |
4576 | flags = OCFS2_EXT_UNWRITTEN; | 4474 | flags = OCFS2_EXT_UNWRITTEN; |
4577 | 4475 | ||
4578 | free_extents = ocfs2_num_free_extents(osb, inode, root_bh, type, | 4476 | free_extents = ocfs2_num_free_extents(osb, inode, et); |
4579 | obj); | ||
4580 | if (free_extents < 0) { | 4477 | if (free_extents < 0) { |
4581 | status = free_extents; | 4478 | status = free_extents; |
4582 | mlog_errno(status); | 4479 | mlog_errno(status); |
@@ -4595,7 +4492,7 @@ int ocfs2_add_clusters_in_btree(struct ocfs2_super *osb, | |||
4595 | goto leave; | 4492 | goto leave; |
4596 | } else if ((!free_extents) | 4493 | } else if ((!free_extents) |
4597 | && (ocfs2_alloc_context_bits_left(meta_ac) | 4494 | && (ocfs2_alloc_context_bits_left(meta_ac) |
4598 | < ocfs2_extend_meta_needed(root_el))) { | 4495 | < ocfs2_extend_meta_needed(et->et_root_el))) { |
4599 | mlog(0, "filesystem is really fragmented...\n"); | 4496 | mlog(0, "filesystem is really fragmented...\n"); |
4600 | status = -EAGAIN; | 4497 | status = -EAGAIN; |
4601 | reason = RESTART_META; | 4498 | reason = RESTART_META; |
@@ -4613,7 +4510,7 @@ int ocfs2_add_clusters_in_btree(struct ocfs2_super *osb, | |||
4613 | BUG_ON(num_bits > clusters_to_add); | 4510 | BUG_ON(num_bits > clusters_to_add); |
4614 | 4511 | ||
4615 | /* reserve our write early -- insert_extent may update the inode */ | 4512 | /* reserve our write early -- insert_extent may update the inode */ |
4616 | status = ocfs2_journal_access(handle, inode, root_bh, | 4513 | status = ocfs2_journal_access(handle, inode, et->et_root_bh, |
4617 | OCFS2_JOURNAL_ACCESS_WRITE); | 4514 | OCFS2_JOURNAL_ACCESS_WRITE); |
4618 | if (status < 0) { | 4515 | if (status < 0) { |
4619 | mlog_errno(status); | 4516 | mlog_errno(status); |
@@ -4623,28 +4520,15 @@ int ocfs2_add_clusters_in_btree(struct ocfs2_super *osb, | |||
4623 | block = ocfs2_clusters_to_blocks(osb->sb, bit_off); | 4520 | block = ocfs2_clusters_to_blocks(osb->sb, bit_off); |
4624 | mlog(0, "Allocating %u clusters at block %u for inode %llu\n", | 4521 | mlog(0, "Allocating %u clusters at block %u for inode %llu\n", |
4625 | num_bits, bit_off, (unsigned long long)OCFS2_I(inode)->ip_blkno); | 4522 | num_bits, bit_off, (unsigned long long)OCFS2_I(inode)->ip_blkno); |
4626 | if (type == OCFS2_DINODE_EXTENT) | 4523 | status = ocfs2_insert_extent(osb, handle, inode, et, |
4627 | status = ocfs2_dinode_insert_extent(osb, handle, inode, root_bh, | 4524 | *logical_offset, block, |
4628 | *logical_offset, block, | 4525 | num_bits, flags, meta_ac); |
4629 | num_bits, flags, meta_ac); | ||
4630 | else if (type == OCFS2_XATTR_TREE_EXTENT) | ||
4631 | status = ocfs2_xattr_tree_insert_extent(osb, handle, | ||
4632 | inode, root_bh, | ||
4633 | *logical_offset, | ||
4634 | block, num_bits, flags, | ||
4635 | meta_ac); | ||
4636 | else | ||
4637 | status = ocfs2_xattr_value_insert_extent(osb, handle, | ||
4638 | inode, root_bh, | ||
4639 | *logical_offset, | ||
4640 | block, num_bits, flags, | ||
4641 | meta_ac, obj); | ||
4642 | if (status < 0) { | 4526 | if (status < 0) { |
4643 | mlog_errno(status); | 4527 | mlog_errno(status); |
4644 | goto leave; | 4528 | goto leave; |
4645 | } | 4529 | } |
4646 | 4530 | ||
4647 | status = ocfs2_journal_dirty(handle, root_bh); | 4531 | status = ocfs2_journal_dirty(handle, et->et_root_bh); |
4648 | if (status < 0) { | 4532 | if (status < 0) { |
4649 | mlog_errno(status); | 4533 | mlog_errno(status); |
4650 | goto leave; | 4534 | goto leave; |
@@ -4915,25 +4799,21 @@ out: | |||
4915 | * | 4799 | * |
4916 | * The caller is responsible for passing down meta_ac if we'll need it. | 4800 | * The caller is responsible for passing down meta_ac if we'll need it. |
4917 | */ | 4801 | */ |
4918 | int ocfs2_mark_extent_written(struct inode *inode, struct buffer_head *root_bh, | 4802 | int ocfs2_mark_extent_written(struct inode *inode, |
4803 | struct ocfs2_extent_tree *et, | ||
4919 | handle_t *handle, u32 cpos, u32 len, u32 phys, | 4804 | handle_t *handle, u32 cpos, u32 len, u32 phys, |
4920 | struct ocfs2_alloc_context *meta_ac, | 4805 | struct ocfs2_alloc_context *meta_ac, |
4921 | struct ocfs2_cached_dealloc_ctxt *dealloc, | 4806 | struct ocfs2_cached_dealloc_ctxt *dealloc) |
4922 | enum ocfs2_extent_tree_type et_type, | ||
4923 | void *obj) | ||
4924 | { | 4807 | { |
4925 | int ret, index; | 4808 | int ret, index; |
4926 | u64 start_blkno = ocfs2_clusters_to_blocks(inode->i_sb, phys); | 4809 | u64 start_blkno = ocfs2_clusters_to_blocks(inode->i_sb, phys); |
4927 | struct ocfs2_extent_rec split_rec; | 4810 | struct ocfs2_extent_rec split_rec; |
4928 | struct ocfs2_path *left_path = NULL; | 4811 | struct ocfs2_path *left_path = NULL; |
4929 | struct ocfs2_extent_list *el; | 4812 | struct ocfs2_extent_list *el; |
4930 | struct ocfs2_extent_tree et; | ||
4931 | 4813 | ||
4932 | mlog(0, "Inode %lu cpos %u, len %u, phys %u (%llu)\n", | 4814 | mlog(0, "Inode %lu cpos %u, len %u, phys %u (%llu)\n", |
4933 | inode->i_ino, cpos, len, phys, (unsigned long long)start_blkno); | 4815 | inode->i_ino, cpos, len, phys, (unsigned long long)start_blkno); |
4934 | 4816 | ||
4935 | ocfs2_get_extent_tree(&et, inode, root_bh, et_type, obj); | ||
4936 | |||
4937 | if (!ocfs2_writes_unwritten_extents(OCFS2_SB(inode->i_sb))) { | 4817 | if (!ocfs2_writes_unwritten_extents(OCFS2_SB(inode->i_sb))) { |
4938 | ocfs2_error(inode->i_sb, "Inode %llu has unwritten extents " | 4818 | ocfs2_error(inode->i_sb, "Inode %llu has unwritten extents " |
4939 | "that are being written to, but the feature bit " | 4819 | "that are being written to, but the feature bit " |
@@ -4946,11 +4826,14 @@ int ocfs2_mark_extent_written(struct inode *inode, struct buffer_head *root_bh, | |||
4946 | /* | 4826 | /* |
4947 | * XXX: This should be fixed up so that we just re-insert the | 4827 | * XXX: This should be fixed up so that we just re-insert the |
4948 | * next extent records. | 4828 | * next extent records. |
4829 | * | ||
4830 | * XXX: This is a hack on the extent tree, maybe it should be | ||
4831 | * an op? | ||
4949 | */ | 4832 | */ |
4950 | if (et_type == OCFS2_DINODE_EXTENT) | 4833 | if (et->et_ops == &ocfs2_dinode_et_ops) |
4951 | ocfs2_extent_map_trunc(inode, 0); | 4834 | ocfs2_extent_map_trunc(inode, 0); |
4952 | 4835 | ||
4953 | left_path = ocfs2_new_path(et.et_root_bh, et.et_root_el); | 4836 | left_path = ocfs2_new_path(et->et_root_bh, et->et_root_el); |
4954 | if (!left_path) { | 4837 | if (!left_path) { |
4955 | ret = -ENOMEM; | 4838 | ret = -ENOMEM; |
4956 | mlog_errno(ret); | 4839 | mlog_errno(ret); |
@@ -4981,7 +4864,7 @@ int ocfs2_mark_extent_written(struct inode *inode, struct buffer_head *root_bh, | |||
4981 | split_rec.e_flags = path_leaf_el(left_path)->l_recs[index].e_flags; | 4864 | split_rec.e_flags = path_leaf_el(left_path)->l_recs[index].e_flags; |
4982 | split_rec.e_flags &= ~OCFS2_EXT_UNWRITTEN; | 4865 | split_rec.e_flags &= ~OCFS2_EXT_UNWRITTEN; |
4983 | 4866 | ||
4984 | ret = __ocfs2_mark_extent_written(inode, &et, handle, left_path, | 4867 | ret = __ocfs2_mark_extent_written(inode, et, handle, left_path, |
4985 | index, &split_rec, meta_ac, | 4868 | index, &split_rec, meta_ac, |
4986 | dealloc); | 4869 | dealloc); |
4987 | if (ret) | 4870 | if (ret) |
@@ -4989,7 +4872,6 @@ int ocfs2_mark_extent_written(struct inode *inode, struct buffer_head *root_bh, | |||
4989 | 4872 | ||
4990 | out: | 4873 | out: |
4991 | ocfs2_free_path(left_path); | 4874 | ocfs2_free_path(left_path); |
4992 | ocfs2_put_extent_tree(&et); | ||
4993 | return ret; | 4875 | return ret; |
4994 | } | 4876 | } |
4995 | 4877 | ||
@@ -5219,25 +5101,21 @@ out: | |||
5219 | return ret; | 5101 | return ret; |
5220 | } | 5102 | } |
5221 | 5103 | ||
5222 | int ocfs2_remove_extent(struct inode *inode, struct buffer_head *root_bh, | 5104 | int ocfs2_remove_extent(struct inode *inode, |
5105 | struct ocfs2_extent_tree *et, | ||
5223 | u32 cpos, u32 len, handle_t *handle, | 5106 | u32 cpos, u32 len, handle_t *handle, |
5224 | struct ocfs2_alloc_context *meta_ac, | 5107 | struct ocfs2_alloc_context *meta_ac, |
5225 | struct ocfs2_cached_dealloc_ctxt *dealloc, | 5108 | struct ocfs2_cached_dealloc_ctxt *dealloc) |
5226 | enum ocfs2_extent_tree_type et_type, | ||
5227 | void *obj) | ||
5228 | { | 5109 | { |
5229 | int ret, index; | 5110 | int ret, index; |
5230 | u32 rec_range, trunc_range; | 5111 | u32 rec_range, trunc_range; |
5231 | struct ocfs2_extent_rec *rec; | 5112 | struct ocfs2_extent_rec *rec; |
5232 | struct ocfs2_extent_list *el; | 5113 | struct ocfs2_extent_list *el; |
5233 | struct ocfs2_path *path = NULL; | 5114 | struct ocfs2_path *path = NULL; |
5234 | struct ocfs2_extent_tree et; | ||
5235 | |||
5236 | ocfs2_get_extent_tree(&et, inode, root_bh, et_type, obj); | ||
5237 | 5115 | ||
5238 | ocfs2_extent_map_trunc(inode, 0); | 5116 | ocfs2_extent_map_trunc(inode, 0); |
5239 | 5117 | ||
5240 | path = ocfs2_new_path(et.et_root_bh, et.et_root_el); | 5118 | path = ocfs2_new_path(et->et_root_bh, et->et_root_el); |
5241 | if (!path) { | 5119 | if (!path) { |
5242 | ret = -ENOMEM; | 5120 | ret = -ENOMEM; |
5243 | mlog_errno(ret); | 5121 | mlog_errno(ret); |
@@ -5290,13 +5168,13 @@ int ocfs2_remove_extent(struct inode *inode, struct buffer_head *root_bh, | |||
5290 | 5168 | ||
5291 | if (le32_to_cpu(rec->e_cpos) == cpos || rec_range == trunc_range) { | 5169 | if (le32_to_cpu(rec->e_cpos) == cpos || rec_range == trunc_range) { |
5292 | ret = ocfs2_truncate_rec(inode, handle, path, index, dealloc, | 5170 | ret = ocfs2_truncate_rec(inode, handle, path, index, dealloc, |
5293 | cpos, len, &et); | 5171 | cpos, len, et); |
5294 | if (ret) { | 5172 | if (ret) { |
5295 | mlog_errno(ret); | 5173 | mlog_errno(ret); |
5296 | goto out; | 5174 | goto out; |
5297 | } | 5175 | } |
5298 | } else { | 5176 | } else { |
5299 | ret = ocfs2_split_tree(inode, &et, handle, path, index, | 5177 | ret = ocfs2_split_tree(inode, et, handle, path, index, |
5300 | trunc_range, meta_ac); | 5178 | trunc_range, meta_ac); |
5301 | if (ret) { | 5179 | if (ret) { |
5302 | mlog_errno(ret); | 5180 | mlog_errno(ret); |
@@ -5345,7 +5223,7 @@ int ocfs2_remove_extent(struct inode *inode, struct buffer_head *root_bh, | |||
5345 | } | 5223 | } |
5346 | 5224 | ||
5347 | ret = ocfs2_truncate_rec(inode, handle, path, index, dealloc, | 5225 | ret = ocfs2_truncate_rec(inode, handle, path, index, dealloc, |
5348 | cpos, len, &et); | 5226 | cpos, len, et); |
5349 | if (ret) { | 5227 | if (ret) { |
5350 | mlog_errno(ret); | 5228 | mlog_errno(ret); |
5351 | goto out; | 5229 | goto out; |
@@ -5354,7 +5232,6 @@ int ocfs2_remove_extent(struct inode *inode, struct buffer_head *root_bh, | |||
5354 | 5232 | ||
5355 | out: | 5233 | out: |
5356 | ocfs2_free_path(path); | 5234 | ocfs2_free_path(path); |
5357 | ocfs2_put_extent_tree(&et); | ||
5358 | return ret; | 5235 | return ret; |
5359 | } | 5236 | } |
5360 | 5237 | ||
@@ -6773,6 +6650,7 @@ int ocfs2_convert_inline_data_to_extents(struct inode *inode, | |||
6773 | struct ocfs2_alloc_context *data_ac = NULL; | 6650 | struct ocfs2_alloc_context *data_ac = NULL; |
6774 | struct page **pages = NULL; | 6651 | struct page **pages = NULL; |
6775 | loff_t end = osb->s_clustersize; | 6652 | loff_t end = osb->s_clustersize; |
6653 | struct ocfs2_extent_tree et; | ||
6776 | 6654 | ||
6777 | has_data = i_size_read(inode) ? 1 : 0; | 6655 | has_data = i_size_read(inode) ? 1 : 0; |
6778 | 6656 | ||
@@ -6872,8 +6750,10 @@ int ocfs2_convert_inline_data_to_extents(struct inode *inode, | |||
6872 | * this proves to be false, we could always re-build | 6750 | * this proves to be false, we could always re-build |
6873 | * the in-inode data from our pages. | 6751 | * the in-inode data from our pages. |
6874 | */ | 6752 | */ |
6875 | ret = ocfs2_dinode_insert_extent(osb, handle, inode, di_bh, | 6753 | ocfs2_get_dinode_extent_tree(&et, inode, di_bh); |
6876 | 0, block, 1, 0, NULL); | 6754 | ret = ocfs2_insert_extent(osb, handle, inode, &et, |
6755 | 0, block, 1, 0, NULL); | ||
6756 | ocfs2_put_extent_tree(&et); | ||
6877 | if (ret) { | 6757 | if (ret) { |
6878 | mlog_errno(ret); | 6758 | mlog_errno(ret); |
6879 | goto out_commit; | 6759 | goto out_commit; |