diff options
author | Joel Becker <joel.becker@oracle.com> | 2008-08-20 22:36:33 -0400 |
---|---|---|
committer | Mark Fasheh <mfasheh@suse.com> | 2008-10-13 19:57:05 -0400 |
commit | f99b9b7ccf6a691f653cec45f36bfdd1e94769c7 (patch) | |
tree | 1c6ff6ea1fa1bb86b70f1fd78dd725b559c729e4 /fs | |
parent | 1e61ee79e2a96f62c007486677319814ce621c3c (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.c | 300 | ||||
-rw-r--r-- | fs/ocfs2/alloc.h | 111 | ||||
-rw-r--r-- | fs/ocfs2/aops.c | 16 | ||||
-rw-r--r-- | fs/ocfs2/dir.c | 20 | ||||
-rw-r--r-- | fs/ocfs2/file.c | 36 | ||||
-rw-r--r-- | fs/ocfs2/suballoc.c | 12 | ||||
-rw-r--r-- | fs/ocfs2/suballoc.h | 6 | ||||
-rw-r--r-- | fs/ocfs2/xattr.c | 71 |
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 | */ | ||
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; |
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 | ||
29 | enum 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 | */ | ||
52 | struct ocfs2_extent_tree_operations; | ||
53 | struct 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 | */ | ||
66 | void ocfs2_get_dinode_extent_tree(struct ocfs2_extent_tree *et, | ||
67 | struct inode *inode, | ||
68 | struct buffer_head *bh); | ||
69 | void ocfs2_get_xattr_tree_extent_tree(struct ocfs2_extent_tree *et, | ||
70 | struct inode *inode, | ||
71 | struct buffer_head *bh); | ||
72 | void 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); | ||
76 | void ocfs2_put_extent_tree(struct ocfs2_extent_tree *et); | ||
77 | |||
40 | struct ocfs2_alloc_context; | 78 | struct ocfs2_alloc_context; |
41 | int ocfs2_dinode_insert_extent(struct ocfs2_super *osb, | 79 | int 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); |
50 | int 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); | ||
60 | int 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); | ||
69 | enum ocfs2_alloc_restarted { | 89 | enum 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); | ||
87 | struct ocfs2_cached_dealloc_ctxt; | 104 | struct ocfs2_cached_dealloc_ctxt; |
88 | int ocfs2_mark_extent_written(struct inode *inode, struct buffer_head *root_bh, | 105 | int 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, | 110 | int ocfs2_remove_extent(struct inode *inode, |
93 | void *private); | 111 | struct ocfs2_extent_tree *et, |
94 | int 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); | ||
100 | int ocfs2_num_free_extents(struct ocfs2_super *osb, | 115 | int 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 | ||
522 | static int __ocfs2_extend_allocation(struct inode *inode, u32 logical_start, | 525 | static 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 | */ |
1917 | int ocfs2_lock_allocators(struct inode *inode, struct buffer_head *root_bh, | 1917 | int 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); | |||
165 | int ocfs2_check_group_descriptor(struct super_block *sb, | 165 | int 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); |
168 | int ocfs2_lock_allocators(struct inode *inode, struct buffer_head *root_bh, | 168 | int 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 | |||
214 | restart_all: | 216 | restart_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 | ||