aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorJoel Becker <joel.becker@oracle.com>2008-08-20 22:36:33 -0400
committerMark Fasheh <mfasheh@suse.com>2008-10-13 19:57:05 -0400
commitf99b9b7ccf6a691f653cec45f36bfdd1e94769c7 (patch)
tree1c6ff6ea1fa1bb86b70f1fd78dd725b559c729e4 /fs
parent1e61ee79e2a96f62c007486677319814ce621c3c (diff)
ocfs2: Make ocfs2_extent_tree the first-class representation of a tree.
We now have three different kinds of extent trees in ocfs2: inode data (dinode), extended attributes (xattr_tree), and extended attribute values (xattr_value). There is a nice abstraction for them, ocfs2_extent_tree, but it is hidden in alloc.c. All the calling functions have to pick amongst a varied API and pass in type bits and often extraneous pointers. A better way is to make ocfs2_extent_tree a first-class object. Everyone converts their object to an ocfs2_extent_tree() via the ocfs2_get_*_extent_tree() calls, then uses the ocfs2_extent_tree for all tree calls to alloc.c. This simplifies a lot of callers, making for readability. It also provides an easy way to add additional extent tree types, as they only need to be defined in alloc.c with a ocfs2_get_<new>_extent_tree() function. Signed-off-by: Joel Becker <joel.becker@oracle.com> Signed-off-by: Mark Fasheh <mfasheh@suse.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/ocfs2/alloc.c300
-rw-r--r--fs/ocfs2/alloc.h111
-rw-r--r--fs/ocfs2/aops.c16
-rw-r--r--fs/ocfs2/dir.c20
-rw-r--r--fs/ocfs2/file.c36
-rw-r--r--fs/ocfs2/suballoc.c12
-rw-r--r--fs/ocfs2/suballoc.h6
-rw-r--r--fs/ocfs2/xattr.c71
8 files changed, 240 insertions, 332 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 */
65struct ocfs2_extent_tree;
66 52
67struct ocfs2_extent_tree_operations { 53struct 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
86struct 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
95static 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; 77static u64 ocfs2_dinode_get_last_eb_blk(struct ocfs2_extent_tree *et);
100} 78static void ocfs2_dinode_set_last_eb_blk(struct ocfs2_extent_tree *et,
79 u64 blkno);
80static void ocfs2_dinode_update_clusters(struct inode *inode,
81 struct ocfs2_extent_tree *et,
82 u32 clusters);
83static int ocfs2_dinode_insert_check(struct inode *inode,
84 struct ocfs2_extent_tree *et,
85 struct ocfs2_extent_rec *rec);
86static int ocfs2_dinode_sanity_check(struct inode *inode,
87 struct ocfs2_extent_tree *et);
88static void ocfs2_dinode_fill_root_el(struct ocfs2_extent_tree *et);
89static 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
102static void ocfs2_dinode_set_last_eb_blk(struct ocfs2_extent_tree *et, 98static 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
169static struct ocfs2_extent_tree_operations ocfs2_dinode_et_ops = { 165static 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
178static void ocfs2_xattr_value_fill_root_el(struct ocfs2_extent_tree *et) 173static 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
290static void ocfs2_get_dinode_extent_tree(struct ocfs2_extent_tree *et, 283void 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
298static void ocfs2_get_xattr_tree_extent_tree(struct ocfs2_extent_tree *et, 290void 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
307static void ocfs2_get_xattr_value_extent_tree(struct ocfs2_extent_tree *et, 298void 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
317static void ocfs2_get_extent_tree(struct ocfs2_extent_tree *et, 307void 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
333static 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 */
683int ocfs2_num_free_extents(struct ocfs2_super *osb, 657int 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 */
4409static int ocfs2_insert_extent(struct ocfs2_super *osb, 4378int 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
4470bail: 4438bail:
@@ -4475,77 +4443,10 @@ bail:
4475 return status; 4443 return status;
4476} 4444}
4477 4445
4478int 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
4500int 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
4523int 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 */
4918int ocfs2_mark_extent_written(struct inode *inode, struct buffer_head *root_bh, 4802int 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
4990out: 4873out:
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
5222int ocfs2_remove_extent(struct inode *inode, struct buffer_head *root_bh, 5104int 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
5355out: 5233out:
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;
diff --git a/fs/ocfs2/alloc.h b/fs/ocfs2/alloc.h
index 5cc9a83cf1a1..35ad07f96104 100644
--- a/fs/ocfs2/alloc.h
+++ b/fs/ocfs2/alloc.h
@@ -26,46 +26,66 @@
26#ifndef OCFS2_ALLOC_H 26#ifndef OCFS2_ALLOC_H
27#define OCFS2_ALLOC_H 27#define OCFS2_ALLOC_H
28 28
29enum ocfs2_extent_tree_type {
30 OCFS2_DINODE_EXTENT = 0,
31 OCFS2_XATTR_VALUE_EXTENT,
32 OCFS2_XATTR_TREE_EXTENT,
33};
34 29
35/* 30/*
36 * For xattr tree leaf, we limit the leaf byte size to be 64K. 31 * For xattr tree leaf, we limit the leaf byte size to be 64K.
37 */ 32 */
38#define OCFS2_MAX_XATTR_TREE_LEAF_SIZE 65536 33#define OCFS2_MAX_XATTR_TREE_LEAF_SIZE 65536
39 34
35/*
36 * ocfs2_extent_tree and ocfs2_extent_tree_operations are used to abstract
37 * the b-tree operations in ocfs2. Now all the b-tree operations are not
38 * limited to ocfs2_dinode only. Any data which need to allocate clusters
39 * to store can use b-tree. And it only needs to implement its ocfs2_extent_tree
40 * and operation.
41 *
42 * ocfs2_extent_tree becomes the first-class object for extent tree
43 * manipulation. Callers of the alloc.c code need to fill it via one of
44 * the ocfs2_get_*_extent_tree() operations below.
45 *
46 * ocfs2_extent_tree contains info for the root of the b-tree, it must have a
47 * root ocfs2_extent_list and a root_bh so that they can be used in the b-tree
48 * functions.
49 * ocfs2_extent_tree_operations abstract the normal operations we do for
50 * the root of extent b-tree.
51 */
52struct ocfs2_extent_tree_operations;
53struct ocfs2_extent_tree {
54 struct ocfs2_extent_tree_operations *et_ops;
55 struct buffer_head *et_root_bh;
56 struct ocfs2_extent_list *et_root_el;
57 void *et_object;
58 unsigned int et_max_leaf_clusters;
59};
60
61/*
62 * ocfs2_*_get_extent_tree() will fill an ocfs2_extent_tree from the
63 * specified object buffer. The bh is referenced until
64 * ocfs2_put_extent_tree().
65 */
66void ocfs2_get_dinode_extent_tree(struct ocfs2_extent_tree *et,
67 struct inode *inode,
68 struct buffer_head *bh);
69void ocfs2_get_xattr_tree_extent_tree(struct ocfs2_extent_tree *et,
70 struct inode *inode,
71 struct buffer_head *bh);
72void ocfs2_get_xattr_value_extent_tree(struct ocfs2_extent_tree *et,
73 struct inode *inode,
74 struct buffer_head *bh,
75 struct ocfs2_xattr_value_root *xv);
76void ocfs2_put_extent_tree(struct ocfs2_extent_tree *et);
77
40struct ocfs2_alloc_context; 78struct ocfs2_alloc_context;
41int ocfs2_dinode_insert_extent(struct ocfs2_super *osb, 79int ocfs2_insert_extent(struct ocfs2_super *osb,
42 handle_t *handle, 80 handle_t *handle,
43 struct inode *inode, 81 struct inode *inode,
44 struct buffer_head *root_bh, 82 struct ocfs2_extent_tree *et,
45 u32 cpos, 83 u32 cpos,
46 u64 start_blk, 84 u64 start_blk,
47 u32 new_clusters, 85 u32 new_clusters,
48 u8 flags, 86 u8 flags,
49 struct ocfs2_alloc_context *meta_ac); 87 struct ocfs2_alloc_context *meta_ac);
50int ocfs2_xattr_value_insert_extent(struct ocfs2_super *osb, 88
51 handle_t *handle,
52 struct inode *inode,
53 struct buffer_head *root_bh,
54 u32 cpos,
55 u64 start_blk,
56 u32 new_clusters,
57 u8 flags,
58 struct ocfs2_alloc_context *meta_ac,
59 struct ocfs2_xattr_value_root *xv);
60int ocfs2_xattr_tree_insert_extent(struct ocfs2_super *osb,
61 handle_t *handle,
62 struct inode *inode,
63 struct buffer_head *root_bh,
64 u32 cpos,
65 u64 start_blk,
66 u32 new_clusters,
67 u8 flags,
68 struct ocfs2_alloc_context *meta_ac);
69enum ocfs2_alloc_restarted { 89enum ocfs2_alloc_restarted {
70 RESTART_NONE = 0, 90 RESTART_NONE = 0,
71 RESTART_TRANS, 91 RESTART_TRANS,
@@ -76,32 +96,25 @@ int ocfs2_add_clusters_in_btree(struct ocfs2_super *osb,
76 u32 *logical_offset, 96 u32 *logical_offset,
77 u32 clusters_to_add, 97 u32 clusters_to_add,
78 int mark_unwritten, 98 int mark_unwritten,
79 struct buffer_head *root_bh, 99 struct ocfs2_extent_tree *et,
80 struct ocfs2_extent_list *root_el,
81 handle_t *handle, 100 handle_t *handle,
82 struct ocfs2_alloc_context *data_ac, 101 struct ocfs2_alloc_context *data_ac,
83 struct ocfs2_alloc_context *meta_ac, 102 struct ocfs2_alloc_context *meta_ac,
84 enum ocfs2_alloc_restarted *reason_ret, 103 enum ocfs2_alloc_restarted *reason_ret);
85 enum ocfs2_extent_tree_type type,
86 void *private);
87struct ocfs2_cached_dealloc_ctxt; 104struct ocfs2_cached_dealloc_ctxt;
88int ocfs2_mark_extent_written(struct inode *inode, struct buffer_head *root_bh, 105int ocfs2_mark_extent_written(struct inode *inode,
106 struct ocfs2_extent_tree *et,
89 handle_t *handle, u32 cpos, u32 len, u32 phys, 107 handle_t *handle, u32 cpos, u32 len, u32 phys,
90 struct ocfs2_alloc_context *meta_ac, 108 struct ocfs2_alloc_context *meta_ac,
91 struct ocfs2_cached_dealloc_ctxt *dealloc, 109 struct ocfs2_cached_dealloc_ctxt *dealloc);
92 enum ocfs2_extent_tree_type et_type, 110int ocfs2_remove_extent(struct inode *inode,
93 void *private); 111 struct ocfs2_extent_tree *et,
94int ocfs2_remove_extent(struct inode *inode, struct buffer_head *root_bh,
95 u32 cpos, u32 len, handle_t *handle, 112 u32 cpos, u32 len, handle_t *handle,
96 struct ocfs2_alloc_context *meta_ac, 113 struct ocfs2_alloc_context *meta_ac,
97 struct ocfs2_cached_dealloc_ctxt *dealloc, 114 struct ocfs2_cached_dealloc_ctxt *dealloc);
98 enum ocfs2_extent_tree_type et_type,
99 void *private);
100int ocfs2_num_free_extents(struct ocfs2_super *osb, 115int ocfs2_num_free_extents(struct ocfs2_super *osb,
101 struct inode *inode, 116 struct inode *inode,
102 struct buffer_head *root_bh, 117 struct ocfs2_extent_tree *et);
103 enum ocfs2_extent_tree_type et_type,
104 void *private);
105 118
106/* 119/*
107 * how many new metadata chunks would an allocation need at maximum? 120 * how many new metadata chunks would an allocation need at maximum?
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index 530b1ff599c0..ed937fa9e4e3 100644
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -1242,6 +1242,7 @@ static int ocfs2_write_cluster(struct address_space *mapping,
1242 int ret, i, new, should_zero = 0; 1242 int ret, i, new, should_zero = 0;
1243 u64 v_blkno, p_blkno; 1243 u64 v_blkno, p_blkno;
1244 struct inode *inode = mapping->host; 1244 struct inode *inode = mapping->host;
1245 struct ocfs2_extent_tree et;
1245 1246
1246 new = phys == 0 ? 1 : 0; 1247 new = phys == 0 ? 1 : 0;
1247 if (new || unwritten) 1248 if (new || unwritten)
@@ -1276,10 +1277,11 @@ static int ocfs2_write_cluster(struct address_space *mapping,
1276 goto out; 1277 goto out;
1277 } 1278 }
1278 } else if (unwritten) { 1279 } else if (unwritten) {
1279 ret = ocfs2_mark_extent_written(inode, wc->w_di_bh, 1280 ocfs2_get_dinode_extent_tree(&et, inode, wc->w_di_bh);
1281 ret = ocfs2_mark_extent_written(inode, &et,
1280 wc->w_handle, cpos, 1, phys, 1282 wc->w_handle, cpos, 1, phys,
1281 meta_ac, &wc->w_dealloc, 1283 meta_ac, &wc->w_dealloc);
1282 OCFS2_DINODE_EXTENT, NULL); 1284 ocfs2_put_extent_tree(&et);
1283 if (ret < 0) { 1285 if (ret < 0) {
1284 mlog_errno(ret); 1286 mlog_errno(ret);
1285 goto out; 1287 goto out;
@@ -1666,6 +1668,7 @@ int ocfs2_write_begin_nolock(struct address_space *mapping,
1666 struct ocfs2_alloc_context *data_ac = NULL; 1668 struct ocfs2_alloc_context *data_ac = NULL;
1667 struct ocfs2_alloc_context *meta_ac = NULL; 1669 struct ocfs2_alloc_context *meta_ac = NULL;
1668 handle_t *handle; 1670 handle_t *handle;
1671 struct ocfs2_extent_tree et;
1669 1672
1670 ret = ocfs2_alloc_write_ctxt(&wc, osb, pos, len, di_bh); 1673 ret = ocfs2_alloc_write_ctxt(&wc, osb, pos, len, di_bh);
1671 if (ret) { 1674 if (ret) {
@@ -1719,10 +1722,11 @@ int ocfs2_write_begin_nolock(struct address_space *mapping,
1719 (long long)i_size_read(inode), le32_to_cpu(di->i_clusters), 1722 (long long)i_size_read(inode), le32_to_cpu(di->i_clusters),
1720 clusters_to_alloc, extents_to_split); 1723 clusters_to_alloc, extents_to_split);
1721 1724
1722 ret = ocfs2_lock_allocators(inode, wc->w_di_bh, &di->id2.i_list, 1725 ocfs2_get_dinode_extent_tree(&et, inode, wc->w_di_bh);
1726 ret = ocfs2_lock_allocators(inode, &et,
1723 clusters_to_alloc, extents_to_split, 1727 clusters_to_alloc, extents_to_split,
1724 &data_ac, &meta_ac, 1728 &data_ac, &meta_ac);
1725 OCFS2_DINODE_EXTENT, NULL); 1729 ocfs2_put_extent_tree(&et);
1726 if (ret) { 1730 if (ret) {
1727 mlog_errno(ret); 1731 mlog_errno(ret);
1728 goto out; 1732 goto out;
diff --git a/fs/ocfs2/dir.c b/fs/ocfs2/dir.c
index 5426a02c12bb..2cdc55390348 100644
--- a/fs/ocfs2/dir.c
+++ b/fs/ocfs2/dir.c
@@ -1192,6 +1192,9 @@ static int ocfs2_expand_inline_dir(struct inode *dir, struct buffer_head *di_bh,
1192 struct buffer_head *dirdata_bh = NULL; 1192 struct buffer_head *dirdata_bh = NULL;
1193 struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data; 1193 struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data;
1194 handle_t *handle; 1194 handle_t *handle;
1195 struct ocfs2_extent_tree et;
1196
1197 ocfs2_get_dinode_extent_tree(&et, dir, di_bh);
1195 1198
1196 alloc = ocfs2_clusters_for_bytes(sb, bytes); 1199 alloc = ocfs2_clusters_for_bytes(sb, bytes);
1197 1200
@@ -1305,8 +1308,8 @@ static int ocfs2_expand_inline_dir(struct inode *dir, struct buffer_head *di_bh,
1305 * This should never fail as our extent list is empty and all 1308 * This should never fail as our extent list is empty and all
1306 * related blocks have been journaled already. 1309 * related blocks have been journaled already.
1307 */ 1310 */
1308 ret = ocfs2_dinode_insert_extent(osb, handle, dir, di_bh, 0, blkno, 1311 ret = ocfs2_insert_extent(osb, handle, dir, &et, 0, blkno, len,
1309 len, 0, NULL); 1312 0, NULL);
1310 if (ret) { 1313 if (ret) {
1311 mlog_errno(ret); 1314 mlog_errno(ret);
1312 goto out_commit; 1315 goto out_commit;
@@ -1337,8 +1340,8 @@ static int ocfs2_expand_inline_dir(struct inode *dir, struct buffer_head *di_bh,
1337 } 1340 }
1338 blkno = ocfs2_clusters_to_blocks(dir->i_sb, bit_off); 1341 blkno = ocfs2_clusters_to_blocks(dir->i_sb, bit_off);
1339 1342
1340 ret = ocfs2_dinode_insert_extent(osb, handle, dir, di_bh, 1, 1343 ret = ocfs2_insert_extent(osb, handle, dir, &et, 1,
1341 blkno, len, 0, NULL); 1344 blkno, len, 0, NULL);
1342 if (ret) { 1345 if (ret) {
1343 mlog_errno(ret); 1346 mlog_errno(ret);
1344 goto out_commit; 1347 goto out_commit;
@@ -1360,6 +1363,7 @@ out:
1360 1363
1361 brelse(dirdata_bh); 1364 brelse(dirdata_bh);
1362 1365
1366 ocfs2_put_extent_tree(&et);
1363 return ret; 1367 return ret;
1364} 1368}
1365 1369
@@ -1437,6 +1441,7 @@ static int ocfs2_extend_dir(struct ocfs2_super *osb,
1437 struct buffer_head *new_bh = NULL; 1441 struct buffer_head *new_bh = NULL;
1438 struct ocfs2_dir_entry * de; 1442 struct ocfs2_dir_entry * de;
1439 struct super_block *sb = osb->sb; 1443 struct super_block *sb = osb->sb;
1444 struct ocfs2_extent_tree et;
1440 1445
1441 mlog_entry_void(); 1446 mlog_entry_void();
1442 1447
@@ -1480,10 +1485,9 @@ static int ocfs2_extend_dir(struct ocfs2_super *osb,
1480 spin_lock(&OCFS2_I(dir)->ip_lock); 1485 spin_lock(&OCFS2_I(dir)->ip_lock);
1481 if (dir_i_size == ocfs2_clusters_to_bytes(sb, OCFS2_I(dir)->ip_clusters)) { 1486 if (dir_i_size == ocfs2_clusters_to_bytes(sb, OCFS2_I(dir)->ip_clusters)) {
1482 spin_unlock(&OCFS2_I(dir)->ip_lock); 1487 spin_unlock(&OCFS2_I(dir)->ip_lock);
1483 num_free_extents = ocfs2_num_free_extents(osb, dir, 1488 ocfs2_get_dinode_extent_tree(&et, dir, parent_fe_bh);
1484 parent_fe_bh, 1489 num_free_extents = ocfs2_num_free_extents(osb, dir, &et);
1485 OCFS2_DINODE_EXTENT, 1490 ocfs2_put_extent_tree(&et);
1486 NULL);
1487 if (num_free_extents < 0) { 1491 if (num_free_extents < 0) {
1488 status = num_free_extents; 1492 status = num_free_extents;
1489 mlog_errno(status); 1493 mlog_errno(status);
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c
index f4273c2c2095..ca3d38addbb9 100644
--- a/fs/ocfs2/file.c
+++ b/fs/ocfs2/file.c
@@ -509,14 +509,17 @@ int ocfs2_add_inode_data(struct ocfs2_super *osb,
509 struct ocfs2_alloc_context *meta_ac, 509 struct ocfs2_alloc_context *meta_ac,
510 enum ocfs2_alloc_restarted *reason_ret) 510 enum ocfs2_alloc_restarted *reason_ret)
511{ 511{
512 struct ocfs2_dinode *fe = (struct ocfs2_dinode *) fe_bh->b_data; 512 int ret;
513 struct ocfs2_extent_list *el = &fe->id2.i_list; 513 struct ocfs2_extent_tree et;
514 514
515 return ocfs2_add_clusters_in_btree(osb, inode, logical_offset, 515 ocfs2_get_dinode_extent_tree(&et, inode, fe_bh);
516 ret = ocfs2_add_clusters_in_btree(osb, inode, logical_offset,
516 clusters_to_add, mark_unwritten, 517 clusters_to_add, mark_unwritten,
517 fe_bh, el, handle, 518 &et, handle,
518 data_ac, meta_ac, reason_ret, 519 data_ac, meta_ac, reason_ret);
519 OCFS2_DINODE_EXTENT, NULL); 520 ocfs2_put_extent_tree(&et);
521
522 return ret;
520} 523}
521 524
522static int __ocfs2_extend_allocation(struct inode *inode, u32 logical_start, 525static int __ocfs2_extend_allocation(struct inode *inode, u32 logical_start,
@@ -533,6 +536,7 @@ static int __ocfs2_extend_allocation(struct inode *inode, u32 logical_start,
533 struct ocfs2_alloc_context *meta_ac = NULL; 536 struct ocfs2_alloc_context *meta_ac = NULL;
534 enum ocfs2_alloc_restarted why; 537 enum ocfs2_alloc_restarted why;
535 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); 538 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
539 struct ocfs2_extent_tree et;
536 540
537 mlog_entry("(clusters_to_add = %u)\n", clusters_to_add); 541 mlog_entry("(clusters_to_add = %u)\n", clusters_to_add);
538 542
@@ -564,9 +568,10 @@ restart_all:
564 (unsigned long long)OCFS2_I(inode)->ip_blkno, 568 (unsigned long long)OCFS2_I(inode)->ip_blkno,
565 (long long)i_size_read(inode), le32_to_cpu(fe->i_clusters), 569 (long long)i_size_read(inode), le32_to_cpu(fe->i_clusters),
566 clusters_to_add); 570 clusters_to_add);
567 status = ocfs2_lock_allocators(inode, bh, &fe->id2.i_list, 571 ocfs2_get_dinode_extent_tree(&et, inode, bh);
568 clusters_to_add, 0, &data_ac, 572 status = ocfs2_lock_allocators(inode, &et, clusters_to_add, 0,
569 &meta_ac, OCFS2_DINODE_EXTENT, NULL); 573 &data_ac, &meta_ac);
574 ocfs2_put_extent_tree(&et);
570 if (status) { 575 if (status) {
571 mlog_errno(status); 576 mlog_errno(status);
572 goto leave; 577 goto leave;
@@ -1236,11 +1241,13 @@ static int __ocfs2_remove_inode_range(struct inode *inode,
1236 handle_t *handle; 1241 handle_t *handle;
1237 struct ocfs2_alloc_context *meta_ac = NULL; 1242 struct ocfs2_alloc_context *meta_ac = NULL;
1238 struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data; 1243 struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data;
1244 struct ocfs2_extent_tree et;
1245
1246 ocfs2_get_dinode_extent_tree(&et, inode, di_bh);
1239 1247
1240 ret = ocfs2_lock_allocators(inode, di_bh, &di->id2.i_list, 1248 ret = ocfs2_lock_allocators(inode, &et, 0, 1, NULL, &meta_ac);
1241 0, 1, NULL, &meta_ac,
1242 OCFS2_DINODE_EXTENT, NULL);
1243 if (ret) { 1249 if (ret) {
1250 ocfs2_put_extent_tree(&et);
1244 mlog_errno(ret); 1251 mlog_errno(ret);
1245 return ret; 1252 return ret;
1246 } 1253 }
@@ -1269,8 +1276,8 @@ static int __ocfs2_remove_inode_range(struct inode *inode,
1269 goto out; 1276 goto out;
1270 } 1277 }
1271 1278
1272 ret = ocfs2_remove_extent(inode, di_bh, cpos, len, handle, meta_ac, 1279 ret = ocfs2_remove_extent(inode, &et, cpos, len, handle, meta_ac,
1273 dealloc, OCFS2_DINODE_EXTENT, NULL); 1280 dealloc);
1274 if (ret) { 1281 if (ret) {
1275 mlog_errno(ret); 1282 mlog_errno(ret);
1276 goto out_commit; 1283 goto out_commit;
@@ -1297,6 +1304,7 @@ out:
1297 if (meta_ac) 1304 if (meta_ac)
1298 ocfs2_free_alloc_context(meta_ac); 1305 ocfs2_free_alloc_context(meta_ac);
1299 1306
1307 ocfs2_put_extent_tree(&et);
1300 return ret; 1308 return ret;
1301} 1309}
1302 1310
diff --git a/fs/ocfs2/suballoc.c b/fs/ocfs2/suballoc.c
index f1871ca83815..8d3947e94a2e 100644
--- a/fs/ocfs2/suballoc.c
+++ b/fs/ocfs2/suballoc.c
@@ -1914,12 +1914,11 @@ static inline void ocfs2_debug_suballoc_inode(struct ocfs2_dinode *fe)
1914 * File systems which don't support holes call this from 1914 * File systems which don't support holes call this from
1915 * ocfs2_extend_allocation(). 1915 * ocfs2_extend_allocation().
1916 */ 1916 */
1917int ocfs2_lock_allocators(struct inode *inode, struct buffer_head *root_bh, 1917int ocfs2_lock_allocators(struct inode *inode,
1918 struct ocfs2_extent_list *root_el, 1918 struct ocfs2_extent_tree *et,
1919 u32 clusters_to_add, u32 extents_to_split, 1919 u32 clusters_to_add, u32 extents_to_split,
1920 struct ocfs2_alloc_context **data_ac, 1920 struct ocfs2_alloc_context **data_ac,
1921 struct ocfs2_alloc_context **meta_ac, 1921 struct ocfs2_alloc_context **meta_ac)
1922 enum ocfs2_extent_tree_type type, void *private)
1923{ 1922{
1924 int ret = 0, num_free_extents; 1923 int ret = 0, num_free_extents;
1925 unsigned int max_recs_needed = clusters_to_add + 2 * extents_to_split; 1924 unsigned int max_recs_needed = clusters_to_add + 2 * extents_to_split;
@@ -1931,8 +1930,7 @@ int ocfs2_lock_allocators(struct inode *inode, struct buffer_head *root_bh,
1931 1930
1932 BUG_ON(clusters_to_add != 0 && data_ac == NULL); 1931 BUG_ON(clusters_to_add != 0 && data_ac == NULL);
1933 1932
1934 num_free_extents = ocfs2_num_free_extents(osb, inode, root_bh, 1933 num_free_extents = ocfs2_num_free_extents(osb, inode, et);
1935 type, private);
1936 if (num_free_extents < 0) { 1934 if (num_free_extents < 0) {
1937 ret = num_free_extents; 1935 ret = num_free_extents;
1938 mlog_errno(ret); 1936 mlog_errno(ret);
@@ -1954,7 +1952,7 @@ int ocfs2_lock_allocators(struct inode *inode, struct buffer_head *root_bh,
1954 */ 1952 */
1955 if (!num_free_extents || 1953 if (!num_free_extents ||
1956 (ocfs2_sparse_alloc(osb) && num_free_extents < max_recs_needed)) { 1954 (ocfs2_sparse_alloc(osb) && num_free_extents < max_recs_needed)) {
1957 ret = ocfs2_reserve_new_metadata(osb, root_el, meta_ac); 1955 ret = ocfs2_reserve_new_metadata(osb, et->et_root_el, meta_ac);
1958 if (ret < 0) { 1956 if (ret < 0) {
1959 if (ret != -ENOSPC) 1957 if (ret != -ENOSPC)
1960 mlog_errno(ret); 1958 mlog_errno(ret);
diff --git a/fs/ocfs2/suballoc.h b/fs/ocfs2/suballoc.h
index 028fd633b44e..dd0963695edc 100644
--- a/fs/ocfs2/suballoc.h
+++ b/fs/ocfs2/suballoc.h
@@ -165,10 +165,8 @@ u64 ocfs2_which_cluster_group(struct inode *inode, u32 cluster);
165int ocfs2_check_group_descriptor(struct super_block *sb, 165int ocfs2_check_group_descriptor(struct super_block *sb,
166 struct ocfs2_dinode *di, 166 struct ocfs2_dinode *di,
167 struct ocfs2_group_desc *gd); 167 struct ocfs2_group_desc *gd);
168int ocfs2_lock_allocators(struct inode *inode, struct buffer_head *root_bh, 168int ocfs2_lock_allocators(struct inode *inode, struct ocfs2_extent_tree *et,
169 struct ocfs2_extent_list *root_el,
170 u32 clusters_to_add, u32 extents_to_split, 169 u32 clusters_to_add, u32 extents_to_split,
171 struct ocfs2_alloc_context **data_ac, 170 struct ocfs2_alloc_context **data_ac,
172 struct ocfs2_alloc_context **meta_ac, 171 struct ocfs2_alloc_context **meta_ac);
173 enum ocfs2_extent_tree_type type, void *private);
174#endif /* _CHAINALLOC_H_ */ 172#endif /* _CHAINALLOC_H_ */
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c
index 1b349c7367a9..9c3d4dc3e2ea 100644
--- a/fs/ocfs2/xattr.c
+++ b/fs/ocfs2/xattr.c
@@ -206,22 +206,24 @@ static int ocfs2_xattr_extend_allocation(struct inode *inode,
206 struct ocfs2_alloc_context *meta_ac = NULL; 206 struct ocfs2_alloc_context *meta_ac = NULL;
207 enum ocfs2_alloc_restarted why; 207 enum ocfs2_alloc_restarted why;
208 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); 208 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
209 struct ocfs2_extent_list *root_el = &xv->xr_list;
210 u32 prev_clusters, logical_start = le32_to_cpu(xv->xr_clusters); 209 u32 prev_clusters, logical_start = le32_to_cpu(xv->xr_clusters);
210 struct ocfs2_extent_tree et;
211 211
212 mlog(0, "(clusters_to_add for xattr= %u)\n", clusters_to_add); 212 mlog(0, "(clusters_to_add for xattr= %u)\n", clusters_to_add);
213 213
214 ocfs2_get_xattr_value_extent_tree(&et, inode, xattr_bh, xv);
215
214restart_all: 216restart_all:
215 217
216 status = ocfs2_lock_allocators(inode, xattr_bh, root_el, 218 status = ocfs2_lock_allocators(inode, &et, clusters_to_add, 0,
217 clusters_to_add, 0, &data_ac, 219 &data_ac, &meta_ac);
218 &meta_ac, OCFS2_XATTR_VALUE_EXTENT, xv);
219 if (status) { 220 if (status) {
220 mlog_errno(status); 221 mlog_errno(status);
221 goto leave; 222 goto leave;
222 } 223 }
223 224
224 credits = ocfs2_calc_extend_credits(osb->sb, root_el, clusters_to_add); 225 credits = ocfs2_calc_extend_credits(osb->sb, et.et_root_el,
226 clusters_to_add);
225 handle = ocfs2_start_trans(osb, credits); 227 handle = ocfs2_start_trans(osb, credits);
226 if (IS_ERR(handle)) { 228 if (IS_ERR(handle)) {
227 status = PTR_ERR(handle); 229 status = PTR_ERR(handle);
@@ -244,14 +246,11 @@ restarted_transaction:
244 &logical_start, 246 &logical_start,
245 clusters_to_add, 247 clusters_to_add,
246 0, 248 0,
247 xattr_bh, 249 &et,
248 root_el,
249 handle, 250 handle,
250 data_ac, 251 data_ac,
251 meta_ac, 252 meta_ac,
252 &why, 253 &why);
253 OCFS2_XATTR_VALUE_EXTENT,
254 xv);
255 if ((status < 0) && (status != -EAGAIN)) { 254 if ((status < 0) && (status != -EAGAIN)) {
256 if (status != -ENOSPC) 255 if (status != -ENOSPC)
257 mlog_errno(status); 256 mlog_errno(status);
@@ -276,7 +275,7 @@ restarted_transaction:
276 mlog(0, "restarting transaction.\n"); 275 mlog(0, "restarting transaction.\n");
277 /* TODO: This can be more intelligent. */ 276 /* TODO: This can be more intelligent. */
278 credits = ocfs2_calc_extend_credits(osb->sb, 277 credits = ocfs2_calc_extend_credits(osb->sb,
279 root_el, 278 et.et_root_el,
280 clusters_to_add); 279 clusters_to_add);
281 status = ocfs2_extend_trans(handle, credits); 280 status = ocfs2_extend_trans(handle, credits);
282 if (status < 0) { 281 if (status < 0) {
@@ -308,6 +307,7 @@ leave:
308 goto restart_all; 307 goto restart_all;
309 } 308 }
310 309
310 ocfs2_put_extent_tree(&et);
311 return status; 311 return status;
312} 312}
313 313
@@ -323,11 +323,13 @@ static int __ocfs2_remove_xattr_range(struct inode *inode,
323 struct inode *tl_inode = osb->osb_tl_inode; 323 struct inode *tl_inode = osb->osb_tl_inode;
324 handle_t *handle; 324 handle_t *handle;
325 struct ocfs2_alloc_context *meta_ac = NULL; 325 struct ocfs2_alloc_context *meta_ac = NULL;
326 struct ocfs2_extent_tree et;
327
328 ocfs2_get_xattr_value_extent_tree(&et, inode, root_bh, xv);
326 329
327 ret = ocfs2_lock_allocators(inode, root_bh, &xv->xr_list, 330 ret = ocfs2_lock_allocators(inode, &et, 0, 1, NULL, &meta_ac);
328 0, 1, NULL, &meta_ac,
329 OCFS2_XATTR_VALUE_EXTENT, xv);
330 if (ret) { 331 if (ret) {
332 ocfs2_put_extent_tree(&et);
331 mlog_errno(ret); 333 mlog_errno(ret);
332 return ret; 334 return ret;
333 } 335 }
@@ -356,8 +358,8 @@ static int __ocfs2_remove_xattr_range(struct inode *inode,
356 goto out_commit; 358 goto out_commit;
357 } 359 }
358 360
359 ret = ocfs2_remove_extent(inode, root_bh, cpos, len, handle, meta_ac, 361 ret = ocfs2_remove_extent(inode, &et, cpos, len, handle, meta_ac,
360 dealloc, OCFS2_XATTR_VALUE_EXTENT, xv); 362 dealloc);
361 if (ret) { 363 if (ret) {
362 mlog_errno(ret); 364 mlog_errno(ret);
363 goto out_commit; 365 goto out_commit;
@@ -383,6 +385,7 @@ out:
383 if (meta_ac) 385 if (meta_ac)
384 ocfs2_free_alloc_context(meta_ac); 386 ocfs2_free_alloc_context(meta_ac);
385 387
388 ocfs2_put_extent_tree(&et);
386 return ret; 389 return ret;
387} 390}
388 391
@@ -3622,26 +3625,24 @@ static int ocfs2_add_new_xattr_cluster(struct inode *inode,
3622 struct ocfs2_alloc_context *data_ac = NULL; 3625 struct ocfs2_alloc_context *data_ac = NULL;
3623 struct ocfs2_alloc_context *meta_ac = NULL; 3626 struct ocfs2_alloc_context *meta_ac = NULL;
3624 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); 3627 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
3625 struct ocfs2_xattr_block *xb = 3628 struct ocfs2_extent_tree et;
3626 (struct ocfs2_xattr_block *)root_bh->b_data;
3627 struct ocfs2_xattr_tree_root *xb_root = &xb->xb_attrs.xb_root;
3628 struct ocfs2_extent_list *root_el = &xb_root->xt_list;
3629 enum ocfs2_extent_tree_type type = OCFS2_XATTR_TREE_EXTENT;
3630 3629
3631 mlog(0, "Add new xattr cluster for %llu, previous xattr hash = %u, " 3630 mlog(0, "Add new xattr cluster for %llu, previous xattr hash = %u, "
3632 "previous xattr blkno = %llu\n", 3631 "previous xattr blkno = %llu\n",
3633 (unsigned long long)OCFS2_I(inode)->ip_blkno, 3632 (unsigned long long)OCFS2_I(inode)->ip_blkno,
3634 prev_cpos, prev_blkno); 3633 prev_cpos, prev_blkno);
3635 3634
3636 ret = ocfs2_lock_allocators(inode, root_bh, root_el, 3635 ocfs2_get_xattr_tree_extent_tree(&et, inode, root_bh);
3637 clusters_to_add, 0, &data_ac, 3636
3638 &meta_ac, type, NULL); 3637 ret = ocfs2_lock_allocators(inode, &et, clusters_to_add, 0,
3638 &data_ac, &meta_ac);
3639 if (ret) { 3639 if (ret) {
3640 mlog_errno(ret); 3640 mlog_errno(ret);
3641 goto leave; 3641 goto leave;
3642 } 3642 }
3643 3643
3644 credits = ocfs2_calc_extend_credits(osb->sb, root_el, clusters_to_add); 3644 credits = ocfs2_calc_extend_credits(osb->sb, et.et_root_el,
3645 clusters_to_add);
3645 handle = ocfs2_start_trans(osb, credits); 3646 handle = ocfs2_start_trans(osb, credits);
3646 if (IS_ERR(handle)) { 3647 if (IS_ERR(handle)) {
3647 ret = PTR_ERR(handle); 3648 ret = PTR_ERR(handle);
@@ -3705,9 +3706,8 @@ static int ocfs2_add_new_xattr_cluster(struct inode *inode,
3705 3706
3706 mlog(0, "Insert %u clusters at block %llu for xattr at %u\n", 3707 mlog(0, "Insert %u clusters at block %llu for xattr at %u\n",
3707 num_bits, block, v_start); 3708 num_bits, block, v_start);
3708 ret = ocfs2_xattr_tree_insert_extent(osb, handle, inode, root_bh, 3709 ret = ocfs2_insert_extent(osb, handle, inode, &et, v_start, block,
3709 v_start, block, num_bits, 3710 num_bits, 0, meta_ac);
3710 0, meta_ac);
3711 if (ret < 0) { 3711 if (ret < 0) {
3712 mlog_errno(ret); 3712 mlog_errno(ret);
3713 goto leave; 3713 goto leave;
@@ -3727,6 +3727,7 @@ leave:
3727 if (meta_ac) 3727 if (meta_ac)
3728 ocfs2_free_alloc_context(meta_ac); 3728 ocfs2_free_alloc_context(meta_ac);
3729 3729
3730 ocfs2_put_extent_tree(&et);
3730 return ret; 3731 return ret;
3731} 3732}
3732 3733
@@ -4331,9 +4332,11 @@ static int ocfs2_rm_xattr_cluster(struct inode *inode,
4331 handle_t *handle; 4332 handle_t *handle;
4332 struct ocfs2_xattr_block *xb = 4333 struct ocfs2_xattr_block *xb =
4333 (struct ocfs2_xattr_block *)root_bh->b_data; 4334 (struct ocfs2_xattr_block *)root_bh->b_data;
4334 struct ocfs2_extent_list *root_el = &xb->xb_attrs.xb_root.xt_list;
4335 struct ocfs2_alloc_context *meta_ac = NULL; 4335 struct ocfs2_alloc_context *meta_ac = NULL;
4336 struct ocfs2_cached_dealloc_ctxt dealloc; 4336 struct ocfs2_cached_dealloc_ctxt dealloc;
4337 struct ocfs2_extent_tree et;
4338
4339 ocfs2_get_xattr_tree_extent_tree(&et, inode, root_bh);
4337 4340
4338 ocfs2_init_dealloc_ctxt(&dealloc); 4341 ocfs2_init_dealloc_ctxt(&dealloc);
4339 4342
@@ -4342,10 +4345,9 @@ static int ocfs2_rm_xattr_cluster(struct inode *inode,
4342 4345
4343 ocfs2_remove_xattr_clusters_from_cache(inode, blkno, len); 4346 ocfs2_remove_xattr_clusters_from_cache(inode, blkno, len);
4344 4347
4345 ret = ocfs2_lock_allocators(inode, root_bh, root_el, 4348 ret = ocfs2_lock_allocators(inode, &et, 0, 1, NULL, &meta_ac);
4346 0, 1, NULL, &meta_ac,
4347 OCFS2_XATTR_TREE_EXTENT, NULL);
4348 if (ret) { 4349 if (ret) {
4350 ocfs2_put_extent_tree(&et);
4349 mlog_errno(ret); 4351 mlog_errno(ret);
4350 return ret; 4352 return ret;
4351 } 4353 }
@@ -4374,8 +4376,8 @@ static int ocfs2_rm_xattr_cluster(struct inode *inode,
4374 goto out_commit; 4376 goto out_commit;
4375 } 4377 }
4376 4378
4377 ret = ocfs2_remove_extent(inode, root_bh, cpos, len, handle, meta_ac, 4379 ret = ocfs2_remove_extent(inode, &et, cpos, len, handle, meta_ac,
4378 &dealloc, OCFS2_XATTR_TREE_EXTENT, NULL); 4380 &dealloc);
4379 if (ret) { 4381 if (ret) {
4380 mlog_errno(ret); 4382 mlog_errno(ret);
4381 goto out_commit; 4383 goto out_commit;
@@ -4405,6 +4407,7 @@ out:
4405 4407
4406 ocfs2_run_deallocs(osb, &dealloc); 4408 ocfs2_run_deallocs(osb, &dealloc);
4407 4409
4410 ocfs2_put_extent_tree(&et);
4408 return ret; 4411 return ret;
4409} 4412}
4410 4413