diff options
author | Tao Ma <tao.ma@oracle.com> | 2008-08-18 05:38:44 -0400 |
---|---|---|
committer | Mark Fasheh <mfasheh@suse.com> | 2008-10-13 16:57:58 -0400 |
commit | e7d4cb6bc19658646357eeff134645cd9bc3479f (patch) | |
tree | 4e24321e5c28fb90dffa1f396972fddb3c458e58 /fs/ocfs2 | |
parent | 811f933df1e55615fd0bb4818f31e3868a8e6e23 (diff) |
ocfs2: Abstract ocfs2_extent_tree in b-tree operations.
In the old extent tree operation, we take the hypothesis that we
are using the ocfs2_extent_list in ocfs2_dinode as the tree root.
As xattr will also use ocfs2_extent_list to store large value
for a xattr entry, we refactor the tree operation so that xattr
can use it directly.
The refactoring includes 4 steps:
1. Abstract set/get of last_eb_blk and update_clusters since they may
be stored in different location for dinode and xattr.
2. Add a new structure named ocfs2_extent_tree to indicate the
extent tree the operation will work on.
3. Remove all the use of fe_bh and di, use root_bh and root_el in
extent tree instead. So now all the fe_bh is replaced with
et->root_bh, el with root_el accordingly.
4. Make ocfs2_lock_allocators generic. Now it is limited to be only used
in file extend allocation. But the whole function is useful when we want
to store large EAs.
Note: This patch doesn't touch ocfs2_commit_truncate() since it is not used
for anything other than truncate inode data btrees.
Signed-off-by: Tao Ma <tao.ma@oracle.com>
Signed-off-by: Mark Fasheh <mfasheh@suse.com>
Diffstat (limited to 'fs/ocfs2')
-rw-r--r-- | fs/ocfs2/alloc.c | 508 | ||||
-rw-r--r-- | fs/ocfs2/alloc.h | 23 | ||||
-rw-r--r-- | fs/ocfs2/aops.c | 11 | ||||
-rw-r--r-- | fs/ocfs2/dir.c | 7 | ||||
-rw-r--r-- | fs/ocfs2/file.c | 104 | ||||
-rw-r--r-- | fs/ocfs2/file.h | 4 | ||||
-rw-r--r-- | fs/ocfs2/suballoc.c | 82 | ||||
-rw-r--r-- | fs/ocfs2/suballoc.h | 5 |
8 files changed, 456 insertions, 288 deletions
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c index dc36cd140754..579659bae6c5 100644 --- a/fs/ocfs2/alloc.c +++ b/fs/ocfs2/alloc.c | |||
@@ -49,6 +49,143 @@ | |||
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 | |||
67 | struct ocfs2_extent_tree_operations { | ||
68 | void (*set_last_eb_blk) (struct ocfs2_extent_tree *et, u64 blkno); | ||
69 | u64 (*get_last_eb_blk) (struct ocfs2_extent_tree *et); | ||
70 | void (*update_clusters) (struct inode *inode, | ||
71 | struct ocfs2_extent_tree *et, | ||
72 | u32 new_clusters); | ||
73 | int (*sanity_check) (struct inode *inode, struct ocfs2_extent_tree *et); | ||
74 | }; | ||
75 | |||
76 | struct ocfs2_extent_tree { | ||
77 | enum ocfs2_extent_tree_type type; | ||
78 | struct ocfs2_extent_tree_operations *eops; | ||
79 | struct buffer_head *root_bh; | ||
80 | struct ocfs2_extent_list *root_el; | ||
81 | }; | ||
82 | |||
83 | static void ocfs2_dinode_set_last_eb_blk(struct ocfs2_extent_tree *et, | ||
84 | u64 blkno) | ||
85 | { | ||
86 | struct ocfs2_dinode *di = (struct ocfs2_dinode *)et->root_bh->b_data; | ||
87 | |||
88 | BUG_ON(et->type != OCFS2_DINODE_EXTENT); | ||
89 | di->i_last_eb_blk = cpu_to_le64(blkno); | ||
90 | } | ||
91 | |||
92 | static u64 ocfs2_dinode_get_last_eb_blk(struct ocfs2_extent_tree *et) | ||
93 | { | ||
94 | struct ocfs2_dinode *di = (struct ocfs2_dinode *)et->root_bh->b_data; | ||
95 | |||
96 | BUG_ON(et->type != OCFS2_DINODE_EXTENT); | ||
97 | return le64_to_cpu(di->i_last_eb_blk); | ||
98 | } | ||
99 | |||
100 | static void ocfs2_dinode_update_clusters(struct inode *inode, | ||
101 | struct ocfs2_extent_tree *et, | ||
102 | u32 clusters) | ||
103 | { | ||
104 | struct ocfs2_dinode *di = | ||
105 | (struct ocfs2_dinode *)et->root_bh->b_data; | ||
106 | |||
107 | le32_add_cpu(&di->i_clusters, clusters); | ||
108 | spin_lock(&OCFS2_I(inode)->ip_lock); | ||
109 | OCFS2_I(inode)->ip_clusters = le32_to_cpu(di->i_clusters); | ||
110 | spin_unlock(&OCFS2_I(inode)->ip_lock); | ||
111 | } | ||
112 | |||
113 | static int ocfs2_dinode_sanity_check(struct inode *inode, | ||
114 | struct ocfs2_extent_tree *et) | ||
115 | { | ||
116 | int ret = 0; | ||
117 | struct ocfs2_dinode *di; | ||
118 | |||
119 | BUG_ON(et->type != OCFS2_DINODE_EXTENT); | ||
120 | |||
121 | di = (struct ocfs2_dinode *)et->root_bh->b_data; | ||
122 | if (!OCFS2_IS_VALID_DINODE(di)) { | ||
123 | ret = -EIO; | ||
124 | ocfs2_error(inode->i_sb, | ||
125 | "Inode %llu has invalid path root", | ||
126 | (unsigned long long)OCFS2_I(inode)->ip_blkno); | ||
127 | } | ||
128 | |||
129 | return ret; | ||
130 | } | ||
131 | |||
132 | static struct ocfs2_extent_tree_operations ocfs2_dinode_et_ops = { | ||
133 | .set_last_eb_blk = ocfs2_dinode_set_last_eb_blk, | ||
134 | .get_last_eb_blk = ocfs2_dinode_get_last_eb_blk, | ||
135 | .update_clusters = ocfs2_dinode_update_clusters, | ||
136 | .sanity_check = ocfs2_dinode_sanity_check, | ||
137 | }; | ||
138 | |||
139 | static struct ocfs2_extent_tree* | ||
140 | ocfs2_new_extent_tree(struct buffer_head *bh, | ||
141 | enum ocfs2_extent_tree_type et_type) | ||
142 | { | ||
143 | struct ocfs2_extent_tree *et; | ||
144 | |||
145 | et = kzalloc(sizeof(*et), GFP_NOFS); | ||
146 | if (!et) | ||
147 | return NULL; | ||
148 | |||
149 | et->type = et_type; | ||
150 | get_bh(bh); | ||
151 | et->root_bh = bh; | ||
152 | |||
153 | /* current we only support dinode extent. */ | ||
154 | BUG_ON(et->type != OCFS2_DINODE_EXTENT); | ||
155 | if (et_type == OCFS2_DINODE_EXTENT) { | ||
156 | et->root_el = &((struct ocfs2_dinode *)bh->b_data)->id2.i_list; | ||
157 | et->eops = &ocfs2_dinode_et_ops; | ||
158 | } | ||
159 | |||
160 | return et; | ||
161 | } | ||
162 | |||
163 | static void ocfs2_free_extent_tree(struct ocfs2_extent_tree *et) | ||
164 | { | ||
165 | if (et) { | ||
166 | brelse(et->root_bh); | ||
167 | kfree(et); | ||
168 | } | ||
169 | } | ||
170 | |||
171 | static inline void ocfs2_set_last_eb_blk(struct ocfs2_extent_tree *et, | ||
172 | u64 new_last_eb_blk) | ||
173 | { | ||
174 | et->eops->set_last_eb_blk(et, new_last_eb_blk); | ||
175 | } | ||
176 | |||
177 | static inline u64 ocfs2_get_last_eb_blk(struct ocfs2_extent_tree *et) | ||
178 | { | ||
179 | return et->eops->get_last_eb_blk(et); | ||
180 | } | ||
181 | |||
182 | static inline void ocfs2_update_clusters(struct inode *inode, | ||
183 | struct ocfs2_extent_tree *et, | ||
184 | u32 clusters) | ||
185 | { | ||
186 | et->eops->update_clusters(inode, et, clusters); | ||
187 | } | ||
188 | |||
52 | static void ocfs2_free_truncate_context(struct ocfs2_truncate_context *tc); | 189 | static void ocfs2_free_truncate_context(struct ocfs2_truncate_context *tc); |
53 | static int ocfs2_cache_extent_block_free(struct ocfs2_cached_dealloc_ctxt *ctxt, | 190 | static int ocfs2_cache_extent_block_free(struct ocfs2_cached_dealloc_ctxt *ctxt, |
54 | struct ocfs2_extent_block *eb); | 191 | struct ocfs2_extent_block *eb); |
@@ -205,17 +342,6 @@ static struct ocfs2_path *ocfs2_new_path(struct buffer_head *root_bh, | |||
205 | } | 342 | } |
206 | 343 | ||
207 | /* | 344 | /* |
208 | * Allocate and initialize a new path based on a disk inode tree. | ||
209 | */ | ||
210 | static struct ocfs2_path *ocfs2_new_inode_path(struct buffer_head *di_bh) | ||
211 | { | ||
212 | struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data; | ||
213 | struct ocfs2_extent_list *el = &di->id2.i_list; | ||
214 | |||
215 | return ocfs2_new_path(di_bh, el); | ||
216 | } | ||
217 | |||
218 | /* | ||
219 | * Convenience function to journal all components in a path. | 345 | * Convenience function to journal all components in a path. |
220 | */ | 346 | */ |
221 | static int ocfs2_journal_access_path(struct inode *inode, handle_t *handle, | 347 | static int ocfs2_journal_access_path(struct inode *inode, handle_t *handle, |
@@ -368,24 +494,33 @@ struct ocfs2_merge_ctxt { | |||
368 | */ | 494 | */ |
369 | int ocfs2_num_free_extents(struct ocfs2_super *osb, | 495 | int ocfs2_num_free_extents(struct ocfs2_super *osb, |
370 | struct inode *inode, | 496 | struct inode *inode, |
371 | struct buffer_head *bh) | 497 | struct buffer_head *root_bh, |
498 | enum ocfs2_extent_tree_type type) | ||
372 | { | 499 | { |
373 | int retval; | 500 | int retval; |
374 | struct ocfs2_extent_list *el; | 501 | struct ocfs2_extent_list *el = NULL; |
375 | struct ocfs2_extent_block *eb; | 502 | struct ocfs2_extent_block *eb; |
376 | struct buffer_head *eb_bh = NULL; | 503 | struct buffer_head *eb_bh = NULL; |
377 | struct ocfs2_dinode *fe = (struct ocfs2_dinode *)bh->b_data; | 504 | u64 last_eb_blk = 0; |
378 | 505 | ||
379 | mlog_entry_void(); | 506 | mlog_entry_void(); |
380 | 507 | ||
381 | if (!OCFS2_IS_VALID_DINODE(fe)) { | 508 | if (type == OCFS2_DINODE_EXTENT) { |
382 | OCFS2_RO_ON_INVALID_DINODE(inode->i_sb, fe); | 509 | struct ocfs2_dinode *fe = |
383 | retval = -EIO; | 510 | (struct ocfs2_dinode *)root_bh->b_data; |
384 | goto bail; | 511 | if (!OCFS2_IS_VALID_DINODE(fe)) { |
512 | OCFS2_RO_ON_INVALID_DINODE(inode->i_sb, fe); | ||
513 | retval = -EIO; | ||
514 | goto bail; | ||
515 | } | ||
516 | |||
517 | if (fe->i_last_eb_blk) | ||
518 | last_eb_blk = le64_to_cpu(fe->i_last_eb_blk); | ||
519 | el = &fe->id2.i_list; | ||
385 | } | 520 | } |
386 | 521 | ||
387 | if (fe->i_last_eb_blk) { | 522 | if (last_eb_blk) { |
388 | retval = ocfs2_read_block(osb, le64_to_cpu(fe->i_last_eb_blk), | 523 | retval = ocfs2_read_block(osb, last_eb_blk, |
389 | &eb_bh, OCFS2_BH_CACHED, inode); | 524 | &eb_bh, OCFS2_BH_CACHED, inode); |
390 | if (retval < 0) { | 525 | if (retval < 0) { |
391 | mlog_errno(retval); | 526 | mlog_errno(retval); |
@@ -393,8 +528,7 @@ int ocfs2_num_free_extents(struct ocfs2_super *osb, | |||
393 | } | 528 | } |
394 | eb = (struct ocfs2_extent_block *) eb_bh->b_data; | 529 | eb = (struct ocfs2_extent_block *) eb_bh->b_data; |
395 | el = &eb->h_list; | 530 | el = &eb->h_list; |
396 | } else | 531 | } |
397 | el = &fe->id2.i_list; | ||
398 | 532 | ||
399 | BUG_ON(el->l_tree_depth != 0); | 533 | BUG_ON(el->l_tree_depth != 0); |
400 | 534 | ||
@@ -532,7 +666,7 @@ static inline u32 ocfs2_sum_rightmost_rec(struct ocfs2_extent_list *el) | |||
532 | static int ocfs2_add_branch(struct ocfs2_super *osb, | 666 | static int ocfs2_add_branch(struct ocfs2_super *osb, |
533 | handle_t *handle, | 667 | handle_t *handle, |
534 | struct inode *inode, | 668 | struct inode *inode, |
535 | struct buffer_head *fe_bh, | 669 | struct ocfs2_extent_tree *et, |
536 | struct buffer_head *eb_bh, | 670 | struct buffer_head *eb_bh, |
537 | struct buffer_head **last_eb_bh, | 671 | struct buffer_head **last_eb_bh, |
538 | struct ocfs2_alloc_context *meta_ac) | 672 | struct ocfs2_alloc_context *meta_ac) |
@@ -541,7 +675,6 @@ static int ocfs2_add_branch(struct ocfs2_super *osb, | |||
541 | u64 next_blkno, new_last_eb_blk; | 675 | u64 next_blkno, new_last_eb_blk; |
542 | struct buffer_head *bh; | 676 | struct buffer_head *bh; |
543 | struct buffer_head **new_eb_bhs = NULL; | 677 | struct buffer_head **new_eb_bhs = NULL; |
544 | struct ocfs2_dinode *fe; | ||
545 | struct ocfs2_extent_block *eb; | 678 | struct ocfs2_extent_block *eb; |
546 | struct ocfs2_extent_list *eb_el; | 679 | struct ocfs2_extent_list *eb_el; |
547 | struct ocfs2_extent_list *el; | 680 | struct ocfs2_extent_list *el; |
@@ -551,13 +684,11 @@ static int ocfs2_add_branch(struct ocfs2_super *osb, | |||
551 | 684 | ||
552 | BUG_ON(!last_eb_bh || !*last_eb_bh); | 685 | BUG_ON(!last_eb_bh || !*last_eb_bh); |
553 | 686 | ||
554 | fe = (struct ocfs2_dinode *) fe_bh->b_data; | ||
555 | |||
556 | if (eb_bh) { | 687 | if (eb_bh) { |
557 | eb = (struct ocfs2_extent_block *) eb_bh->b_data; | 688 | eb = (struct ocfs2_extent_block *) eb_bh->b_data; |
558 | el = &eb->h_list; | 689 | el = &eb->h_list; |
559 | } else | 690 | } else |
560 | el = &fe->id2.i_list; | 691 | el = et->root_el; |
561 | 692 | ||
562 | /* we never add a branch to a leaf. */ | 693 | /* we never add a branch to a leaf. */ |
563 | BUG_ON(!el->l_tree_depth); | 694 | BUG_ON(!el->l_tree_depth); |
@@ -647,7 +778,7 @@ static int ocfs2_add_branch(struct ocfs2_super *osb, | |||
647 | mlog_errno(status); | 778 | mlog_errno(status); |
648 | goto bail; | 779 | goto bail; |
649 | } | 780 | } |
650 | status = ocfs2_journal_access(handle, inode, fe_bh, | 781 | status = ocfs2_journal_access(handle, inode, et->root_bh, |
651 | OCFS2_JOURNAL_ACCESS_WRITE); | 782 | OCFS2_JOURNAL_ACCESS_WRITE); |
652 | if (status < 0) { | 783 | if (status < 0) { |
653 | mlog_errno(status); | 784 | mlog_errno(status); |
@@ -663,7 +794,7 @@ static int ocfs2_add_branch(struct ocfs2_super *osb, | |||
663 | } | 794 | } |
664 | 795 | ||
665 | /* Link the new branch into the rest of the tree (el will | 796 | /* Link the new branch into the rest of the tree (el will |
666 | * either be on the fe, or the extent block passed in. */ | 797 | * either be on the root_bh, or the extent block passed in. */ |
667 | i = le16_to_cpu(el->l_next_free_rec); | 798 | i = le16_to_cpu(el->l_next_free_rec); |
668 | el->l_recs[i].e_blkno = cpu_to_le64(next_blkno); | 799 | el->l_recs[i].e_blkno = cpu_to_le64(next_blkno); |
669 | el->l_recs[i].e_cpos = cpu_to_le32(new_cpos); | 800 | el->l_recs[i].e_cpos = cpu_to_le32(new_cpos); |
@@ -672,7 +803,7 @@ static int ocfs2_add_branch(struct ocfs2_super *osb, | |||
672 | 803 | ||
673 | /* fe needs a new last extent block pointer, as does the | 804 | /* fe needs a new last extent block pointer, as does the |
674 | * next_leaf on the previously last-extent-block. */ | 805 | * next_leaf on the previously last-extent-block. */ |
675 | fe->i_last_eb_blk = cpu_to_le64(new_last_eb_blk); | 806 | ocfs2_set_last_eb_blk(et, new_last_eb_blk); |
676 | 807 | ||
677 | eb = (struct ocfs2_extent_block *) (*last_eb_bh)->b_data; | 808 | eb = (struct ocfs2_extent_block *) (*last_eb_bh)->b_data; |
678 | eb->h_next_leaf_blk = cpu_to_le64(new_last_eb_blk); | 809 | eb->h_next_leaf_blk = cpu_to_le64(new_last_eb_blk); |
@@ -680,7 +811,7 @@ static int ocfs2_add_branch(struct ocfs2_super *osb, | |||
680 | status = ocfs2_journal_dirty(handle, *last_eb_bh); | 811 | status = ocfs2_journal_dirty(handle, *last_eb_bh); |
681 | if (status < 0) | 812 | if (status < 0) |
682 | mlog_errno(status); | 813 | mlog_errno(status); |
683 | status = ocfs2_journal_dirty(handle, fe_bh); | 814 | status = ocfs2_journal_dirty(handle, et->root_bh); |
684 | if (status < 0) | 815 | if (status < 0) |
685 | mlog_errno(status); | 816 | mlog_errno(status); |
686 | if (eb_bh) { | 817 | if (eb_bh) { |
@@ -718,16 +849,15 @@ bail: | |||
718 | static int ocfs2_shift_tree_depth(struct ocfs2_super *osb, | 849 | static int ocfs2_shift_tree_depth(struct ocfs2_super *osb, |
719 | handle_t *handle, | 850 | handle_t *handle, |
720 | struct inode *inode, | 851 | struct inode *inode, |
721 | struct buffer_head *fe_bh, | 852 | struct ocfs2_extent_tree *et, |
722 | struct ocfs2_alloc_context *meta_ac, | 853 | struct ocfs2_alloc_context *meta_ac, |
723 | struct buffer_head **ret_new_eb_bh) | 854 | struct buffer_head **ret_new_eb_bh) |
724 | { | 855 | { |
725 | int status, i; | 856 | int status, i; |
726 | u32 new_clusters; | 857 | u32 new_clusters; |
727 | struct buffer_head *new_eb_bh = NULL; | 858 | struct buffer_head *new_eb_bh = NULL; |
728 | struct ocfs2_dinode *fe; | ||
729 | struct ocfs2_extent_block *eb; | 859 | struct ocfs2_extent_block *eb; |
730 | struct ocfs2_extent_list *fe_el; | 860 | struct ocfs2_extent_list *root_el; |
731 | struct ocfs2_extent_list *eb_el; | 861 | struct ocfs2_extent_list *eb_el; |
732 | 862 | ||
733 | mlog_entry_void(); | 863 | mlog_entry_void(); |
@@ -747,8 +877,7 @@ static int ocfs2_shift_tree_depth(struct ocfs2_super *osb, | |||
747 | } | 877 | } |
748 | 878 | ||
749 | eb_el = &eb->h_list; | 879 | eb_el = &eb->h_list; |
750 | fe = (struct ocfs2_dinode *) fe_bh->b_data; | 880 | root_el = et->root_el; |
751 | fe_el = &fe->id2.i_list; | ||
752 | 881 | ||
753 | status = ocfs2_journal_access(handle, inode, new_eb_bh, | 882 | status = ocfs2_journal_access(handle, inode, new_eb_bh, |
754 | OCFS2_JOURNAL_ACCESS_CREATE); | 883 | OCFS2_JOURNAL_ACCESS_CREATE); |
@@ -757,11 +886,11 @@ static int ocfs2_shift_tree_depth(struct ocfs2_super *osb, | |||
757 | goto bail; | 886 | goto bail; |
758 | } | 887 | } |
759 | 888 | ||
760 | /* copy the fe data into the new extent block */ | 889 | /* copy the root extent list data into the new extent block */ |
761 | eb_el->l_tree_depth = fe_el->l_tree_depth; | 890 | eb_el->l_tree_depth = root_el->l_tree_depth; |
762 | eb_el->l_next_free_rec = fe_el->l_next_free_rec; | 891 | eb_el->l_next_free_rec = root_el->l_next_free_rec; |
763 | for(i = 0; i < le16_to_cpu(fe_el->l_next_free_rec); i++) | 892 | for (i = 0; i < le16_to_cpu(root_el->l_next_free_rec); i++) |
764 | eb_el->l_recs[i] = fe_el->l_recs[i]; | 893 | eb_el->l_recs[i] = root_el->l_recs[i]; |
765 | 894 | ||
766 | status = ocfs2_journal_dirty(handle, new_eb_bh); | 895 | status = ocfs2_journal_dirty(handle, new_eb_bh); |
767 | if (status < 0) { | 896 | if (status < 0) { |
@@ -769,7 +898,7 @@ static int ocfs2_shift_tree_depth(struct ocfs2_super *osb, | |||
769 | goto bail; | 898 | goto bail; |
770 | } | 899 | } |
771 | 900 | ||
772 | status = ocfs2_journal_access(handle, inode, fe_bh, | 901 | status = ocfs2_journal_access(handle, inode, et->root_bh, |
773 | OCFS2_JOURNAL_ACCESS_WRITE); | 902 | OCFS2_JOURNAL_ACCESS_WRITE); |
774 | if (status < 0) { | 903 | if (status < 0) { |
775 | mlog_errno(status); | 904 | mlog_errno(status); |
@@ -778,21 +907,21 @@ static int ocfs2_shift_tree_depth(struct ocfs2_super *osb, | |||
778 | 907 | ||
779 | new_clusters = ocfs2_sum_rightmost_rec(eb_el); | 908 | new_clusters = ocfs2_sum_rightmost_rec(eb_el); |
780 | 909 | ||
781 | /* update fe now */ | 910 | /* update root_bh now */ |
782 | le16_add_cpu(&fe_el->l_tree_depth, 1); | 911 | le16_add_cpu(&root_el->l_tree_depth, 1); |
783 | fe_el->l_recs[0].e_cpos = 0; | 912 | root_el->l_recs[0].e_cpos = 0; |
784 | fe_el->l_recs[0].e_blkno = eb->h_blkno; | 913 | root_el->l_recs[0].e_blkno = eb->h_blkno; |
785 | fe_el->l_recs[0].e_int_clusters = cpu_to_le32(new_clusters); | 914 | root_el->l_recs[0].e_int_clusters = cpu_to_le32(new_clusters); |
786 | for(i = 1; i < le16_to_cpu(fe_el->l_next_free_rec); i++) | 915 | for (i = 1; i < le16_to_cpu(root_el->l_next_free_rec); i++) |
787 | memset(&fe_el->l_recs[i], 0, sizeof(struct ocfs2_extent_rec)); | 916 | memset(&root_el->l_recs[i], 0, sizeof(struct ocfs2_extent_rec)); |
788 | fe_el->l_next_free_rec = cpu_to_le16(1); | 917 | root_el->l_next_free_rec = cpu_to_le16(1); |
789 | 918 | ||
790 | /* If this is our 1st tree depth shift, then last_eb_blk | 919 | /* If this is our 1st tree depth shift, then last_eb_blk |
791 | * becomes the allocated extent block */ | 920 | * becomes the allocated extent block */ |
792 | if (fe_el->l_tree_depth == cpu_to_le16(1)) | 921 | if (root_el->l_tree_depth == cpu_to_le16(1)) |
793 | fe->i_last_eb_blk = eb->h_blkno; | 922 | ocfs2_set_last_eb_blk(et, le64_to_cpu(eb->h_blkno)); |
794 | 923 | ||
795 | status = ocfs2_journal_dirty(handle, fe_bh); | 924 | status = ocfs2_journal_dirty(handle, et->root_bh); |
796 | if (status < 0) { | 925 | if (status < 0) { |
797 | mlog_errno(status); | 926 | mlog_errno(status); |
798 | goto bail; | 927 | goto bail; |
@@ -818,22 +947,21 @@ bail: | |||
818 | * 1) a lowest extent block is found, then we pass it back in | 947 | * 1) a lowest extent block is found, then we pass it back in |
819 | * *lowest_eb_bh and return '0' | 948 | * *lowest_eb_bh and return '0' |
820 | * | 949 | * |
821 | * 2) the search fails to find anything, but the dinode has room. We | 950 | * 2) the search fails to find anything, but the root_el has room. We |
822 | * pass NULL back in *lowest_eb_bh, but still return '0' | 951 | * pass NULL back in *lowest_eb_bh, but still return '0' |
823 | * | 952 | * |
824 | * 3) the search fails to find anything AND the dinode is full, in | 953 | * 3) the search fails to find anything AND the root_el is full, in |
825 | * which case we return > 0 | 954 | * which case we return > 0 |
826 | * | 955 | * |
827 | * return status < 0 indicates an error. | 956 | * return status < 0 indicates an error. |
828 | */ | 957 | */ |
829 | static int ocfs2_find_branch_target(struct ocfs2_super *osb, | 958 | static int ocfs2_find_branch_target(struct ocfs2_super *osb, |
830 | struct inode *inode, | 959 | struct inode *inode, |
831 | struct buffer_head *fe_bh, | 960 | struct ocfs2_extent_tree *et, |
832 | struct buffer_head **target_bh) | 961 | struct buffer_head **target_bh) |
833 | { | 962 | { |
834 | int status = 0, i; | 963 | int status = 0, i; |
835 | u64 blkno; | 964 | u64 blkno; |
836 | struct ocfs2_dinode *fe; | ||
837 | struct ocfs2_extent_block *eb; | 965 | struct ocfs2_extent_block *eb; |
838 | struct ocfs2_extent_list *el; | 966 | struct ocfs2_extent_list *el; |
839 | struct buffer_head *bh = NULL; | 967 | struct buffer_head *bh = NULL; |
@@ -843,8 +971,7 @@ static int ocfs2_find_branch_target(struct ocfs2_super *osb, | |||
843 | 971 | ||
844 | *target_bh = NULL; | 972 | *target_bh = NULL; |
845 | 973 | ||
846 | fe = (struct ocfs2_dinode *) fe_bh->b_data; | 974 | el = et->root_el; |
847 | el = &fe->id2.i_list; | ||
848 | 975 | ||
849 | while(le16_to_cpu(el->l_tree_depth) > 1) { | 976 | while(le16_to_cpu(el->l_tree_depth) > 1) { |
850 | if (le16_to_cpu(el->l_next_free_rec) == 0) { | 977 | if (le16_to_cpu(el->l_next_free_rec) == 0) { |
@@ -896,8 +1023,8 @@ static int ocfs2_find_branch_target(struct ocfs2_super *osb, | |||
896 | 1023 | ||
897 | /* If we didn't find one and the fe doesn't have any room, | 1024 | /* If we didn't find one and the fe doesn't have any room, |
898 | * then return '1' */ | 1025 | * then return '1' */ |
899 | if (!lowest_bh | 1026 | el = et->root_el; |
900 | && (fe->id2.i_list.l_next_free_rec == fe->id2.i_list.l_count)) | 1027 | if (!lowest_bh && (el->l_next_free_rec == el->l_count)) |
901 | status = 1; | 1028 | status = 1; |
902 | 1029 | ||
903 | *target_bh = lowest_bh; | 1030 | *target_bh = lowest_bh; |
@@ -920,19 +1047,19 @@ bail: | |||
920 | * *last_eb_bh will be updated by ocfs2_add_branch(). | 1047 | * *last_eb_bh will be updated by ocfs2_add_branch(). |
921 | */ | 1048 | */ |
922 | static int ocfs2_grow_tree(struct inode *inode, handle_t *handle, | 1049 | static int ocfs2_grow_tree(struct inode *inode, handle_t *handle, |
923 | struct buffer_head *di_bh, int *final_depth, | 1050 | struct ocfs2_extent_tree *et, int *final_depth, |
924 | struct buffer_head **last_eb_bh, | 1051 | struct buffer_head **last_eb_bh, |
925 | struct ocfs2_alloc_context *meta_ac) | 1052 | struct ocfs2_alloc_context *meta_ac) |
926 | { | 1053 | { |
927 | int ret, shift; | 1054 | int ret, shift; |
928 | struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data; | 1055 | struct ocfs2_extent_list *el = et->root_el; |
929 | int depth = le16_to_cpu(di->id2.i_list.l_tree_depth); | 1056 | int depth = le16_to_cpu(el->l_tree_depth); |
930 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | 1057 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); |
931 | struct buffer_head *bh = NULL; | 1058 | struct buffer_head *bh = NULL; |
932 | 1059 | ||
933 | BUG_ON(meta_ac == NULL); | 1060 | BUG_ON(meta_ac == NULL); |
934 | 1061 | ||
935 | shift = ocfs2_find_branch_target(osb, inode, di_bh, &bh); | 1062 | shift = ocfs2_find_branch_target(osb, inode, et, &bh); |
936 | if (shift < 0) { | 1063 | if (shift < 0) { |
937 | ret = shift; | 1064 | ret = shift; |
938 | mlog_errno(ret); | 1065 | mlog_errno(ret); |
@@ -949,7 +1076,7 @@ static int ocfs2_grow_tree(struct inode *inode, handle_t *handle, | |||
949 | /* ocfs2_shift_tree_depth will return us a buffer with | 1076 | /* ocfs2_shift_tree_depth will return us a buffer with |
950 | * the new extent block (so we can pass that to | 1077 | * the new extent block (so we can pass that to |
951 | * ocfs2_add_branch). */ | 1078 | * ocfs2_add_branch). */ |
952 | ret = ocfs2_shift_tree_depth(osb, handle, inode, di_bh, | 1079 | ret = ocfs2_shift_tree_depth(osb, handle, inode, et, |
953 | meta_ac, &bh); | 1080 | meta_ac, &bh); |
954 | if (ret < 0) { | 1081 | if (ret < 0) { |
955 | mlog_errno(ret); | 1082 | mlog_errno(ret); |
@@ -976,7 +1103,7 @@ static int ocfs2_grow_tree(struct inode *inode, handle_t *handle, | |||
976 | /* call ocfs2_add_branch to add the final part of the tree with | 1103 | /* call ocfs2_add_branch to add the final part of the tree with |
977 | * the new data. */ | 1104 | * the new data. */ |
978 | mlog(0, "add branch. bh = %p\n", bh); | 1105 | mlog(0, "add branch. bh = %p\n", bh); |
979 | ret = ocfs2_add_branch(osb, handle, inode, di_bh, bh, last_eb_bh, | 1106 | ret = ocfs2_add_branch(osb, handle, inode, et, bh, last_eb_bh, |
980 | meta_ac); | 1107 | meta_ac); |
981 | if (ret < 0) { | 1108 | if (ret < 0) { |
982 | mlog_errno(ret); | 1109 | mlog_errno(ret); |
@@ -2059,11 +2186,11 @@ static int ocfs2_rotate_subtree_left(struct inode *inode, handle_t *handle, | |||
2059 | struct ocfs2_path *right_path, | 2186 | struct ocfs2_path *right_path, |
2060 | int subtree_index, | 2187 | int subtree_index, |
2061 | struct ocfs2_cached_dealloc_ctxt *dealloc, | 2188 | struct ocfs2_cached_dealloc_ctxt *dealloc, |
2062 | int *deleted) | 2189 | int *deleted, |
2190 | struct ocfs2_extent_tree *et) | ||
2063 | { | 2191 | { |
2064 | int ret, i, del_right_subtree = 0, right_has_empty = 0; | 2192 | int ret, i, del_right_subtree = 0, right_has_empty = 0; |
2065 | struct buffer_head *root_bh, *di_bh = path_root_bh(right_path); | 2193 | struct buffer_head *root_bh, *et_root_bh = path_root_bh(right_path); |
2066 | struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data; | ||
2067 | struct ocfs2_extent_list *right_leaf_el, *left_leaf_el; | 2194 | struct ocfs2_extent_list *right_leaf_el, *left_leaf_el; |
2068 | struct ocfs2_extent_block *eb; | 2195 | struct ocfs2_extent_block *eb; |
2069 | 2196 | ||
@@ -2115,7 +2242,7 @@ static int ocfs2_rotate_subtree_left(struct inode *inode, handle_t *handle, | |||
2115 | * We have to update i_last_eb_blk during the meta | 2242 | * We have to update i_last_eb_blk during the meta |
2116 | * data delete. | 2243 | * data delete. |
2117 | */ | 2244 | */ |
2118 | ret = ocfs2_journal_access(handle, inode, di_bh, | 2245 | ret = ocfs2_journal_access(handle, inode, et_root_bh, |
2119 | OCFS2_JOURNAL_ACCESS_WRITE); | 2246 | OCFS2_JOURNAL_ACCESS_WRITE); |
2120 | if (ret) { | 2247 | if (ret) { |
2121 | mlog_errno(ret); | 2248 | mlog_errno(ret); |
@@ -2190,7 +2317,7 @@ static int ocfs2_rotate_subtree_left(struct inode *inode, handle_t *handle, | |||
2190 | ocfs2_update_edge_lengths(inode, handle, left_path); | 2317 | ocfs2_update_edge_lengths(inode, handle, left_path); |
2191 | 2318 | ||
2192 | eb = (struct ocfs2_extent_block *)path_leaf_bh(left_path)->b_data; | 2319 | eb = (struct ocfs2_extent_block *)path_leaf_bh(left_path)->b_data; |
2193 | di->i_last_eb_blk = eb->h_blkno; | 2320 | ocfs2_set_last_eb_blk(et, le64_to_cpu(eb->h_blkno)); |
2194 | 2321 | ||
2195 | /* | 2322 | /* |
2196 | * Removal of the extent in the left leaf was skipped | 2323 | * Removal of the extent in the left leaf was skipped |
@@ -2200,7 +2327,7 @@ static int ocfs2_rotate_subtree_left(struct inode *inode, handle_t *handle, | |||
2200 | if (right_has_empty) | 2327 | if (right_has_empty) |
2201 | ocfs2_remove_empty_extent(left_leaf_el); | 2328 | ocfs2_remove_empty_extent(left_leaf_el); |
2202 | 2329 | ||
2203 | ret = ocfs2_journal_dirty(handle, di_bh); | 2330 | ret = ocfs2_journal_dirty(handle, et_root_bh); |
2204 | if (ret) | 2331 | if (ret) |
2205 | mlog_errno(ret); | 2332 | mlog_errno(ret); |
2206 | 2333 | ||
@@ -2323,7 +2450,8 @@ static int __ocfs2_rotate_tree_left(struct inode *inode, | |||
2323 | handle_t *handle, int orig_credits, | 2450 | handle_t *handle, int orig_credits, |
2324 | struct ocfs2_path *path, | 2451 | struct ocfs2_path *path, |
2325 | struct ocfs2_cached_dealloc_ctxt *dealloc, | 2452 | struct ocfs2_cached_dealloc_ctxt *dealloc, |
2326 | struct ocfs2_path **empty_extent_path) | 2453 | struct ocfs2_path **empty_extent_path, |
2454 | struct ocfs2_extent_tree *et) | ||
2327 | { | 2455 | { |
2328 | int ret, subtree_root, deleted; | 2456 | int ret, subtree_root, deleted; |
2329 | u32 right_cpos; | 2457 | u32 right_cpos; |
@@ -2396,7 +2524,7 @@ static int __ocfs2_rotate_tree_left(struct inode *inode, | |||
2396 | 2524 | ||
2397 | ret = ocfs2_rotate_subtree_left(inode, handle, left_path, | 2525 | ret = ocfs2_rotate_subtree_left(inode, handle, left_path, |
2398 | right_path, subtree_root, | 2526 | right_path, subtree_root, |
2399 | dealloc, &deleted); | 2527 | dealloc, &deleted, et); |
2400 | if (ret == -EAGAIN) { | 2528 | if (ret == -EAGAIN) { |
2401 | /* | 2529 | /* |
2402 | * The rotation has to temporarily stop due to | 2530 | * The rotation has to temporarily stop due to |
@@ -2439,29 +2567,20 @@ out: | |||
2439 | } | 2567 | } |
2440 | 2568 | ||
2441 | static int ocfs2_remove_rightmost_path(struct inode *inode, handle_t *handle, | 2569 | static int ocfs2_remove_rightmost_path(struct inode *inode, handle_t *handle, |
2442 | struct ocfs2_path *path, | 2570 | struct ocfs2_path *path, |
2443 | struct ocfs2_cached_dealloc_ctxt *dealloc) | 2571 | struct ocfs2_cached_dealloc_ctxt *dealloc, |
2572 | struct ocfs2_extent_tree *et) | ||
2444 | { | 2573 | { |
2445 | int ret, subtree_index; | 2574 | int ret, subtree_index; |
2446 | u32 cpos; | 2575 | u32 cpos; |
2447 | struct ocfs2_path *left_path = NULL; | 2576 | struct ocfs2_path *left_path = NULL; |
2448 | struct ocfs2_dinode *di; | ||
2449 | struct ocfs2_extent_block *eb; | 2577 | struct ocfs2_extent_block *eb; |
2450 | struct ocfs2_extent_list *el; | 2578 | struct ocfs2_extent_list *el; |
2451 | 2579 | ||
2452 | /* | ||
2453 | * XXX: This code assumes that the root is an inode, which is | ||
2454 | * true for now but may change as tree code gets generic. | ||
2455 | */ | ||
2456 | di = (struct ocfs2_dinode *)path_root_bh(path)->b_data; | ||
2457 | if (!OCFS2_IS_VALID_DINODE(di)) { | ||
2458 | ret = -EIO; | ||
2459 | ocfs2_error(inode->i_sb, | ||
2460 | "Inode %llu has invalid path root", | ||
2461 | (unsigned long long)OCFS2_I(inode)->ip_blkno); | ||
2462 | goto out; | ||
2463 | } | ||
2464 | 2580 | ||
2581 | ret = et->eops->sanity_check(inode, et); | ||
2582 | if (ret) | ||
2583 | goto out; | ||
2465 | /* | 2584 | /* |
2466 | * There's two ways we handle this depending on | 2585 | * There's two ways we handle this depending on |
2467 | * whether path is the only existing one. | 2586 | * whether path is the only existing one. |
@@ -2518,7 +2637,7 @@ static int ocfs2_remove_rightmost_path(struct inode *inode, handle_t *handle, | |||
2518 | ocfs2_update_edge_lengths(inode, handle, left_path); | 2637 | ocfs2_update_edge_lengths(inode, handle, left_path); |
2519 | 2638 | ||
2520 | eb = (struct ocfs2_extent_block *)path_leaf_bh(left_path)->b_data; | 2639 | eb = (struct ocfs2_extent_block *)path_leaf_bh(left_path)->b_data; |
2521 | di->i_last_eb_blk = eb->h_blkno; | 2640 | ocfs2_set_last_eb_blk(et, le64_to_cpu(eb->h_blkno)); |
2522 | } else { | 2641 | } else { |
2523 | /* | 2642 | /* |
2524 | * 'path' is also the leftmost path which | 2643 | * 'path' is also the leftmost path which |
@@ -2529,12 +2648,12 @@ static int ocfs2_remove_rightmost_path(struct inode *inode, handle_t *handle, | |||
2529 | */ | 2648 | */ |
2530 | ocfs2_unlink_path(inode, handle, dealloc, path, 1); | 2649 | ocfs2_unlink_path(inode, handle, dealloc, path, 1); |
2531 | 2650 | ||
2532 | el = &di->id2.i_list; | 2651 | el = et->root_el; |
2533 | el->l_tree_depth = 0; | 2652 | el->l_tree_depth = 0; |
2534 | el->l_next_free_rec = 0; | 2653 | el->l_next_free_rec = 0; |
2535 | memset(&el->l_recs[0], 0, sizeof(struct ocfs2_extent_rec)); | 2654 | memset(&el->l_recs[0], 0, sizeof(struct ocfs2_extent_rec)); |
2536 | 2655 | ||
2537 | di->i_last_eb_blk = 0; | 2656 | ocfs2_set_last_eb_blk(et, 0); |
2538 | } | 2657 | } |
2539 | 2658 | ||
2540 | ocfs2_journal_dirty(handle, path_root_bh(path)); | 2659 | ocfs2_journal_dirty(handle, path_root_bh(path)); |
@@ -2562,7 +2681,8 @@ out: | |||
2562 | */ | 2681 | */ |
2563 | static int ocfs2_rotate_tree_left(struct inode *inode, handle_t *handle, | 2682 | static int ocfs2_rotate_tree_left(struct inode *inode, handle_t *handle, |
2564 | struct ocfs2_path *path, | 2683 | struct ocfs2_path *path, |
2565 | struct ocfs2_cached_dealloc_ctxt *dealloc) | 2684 | struct ocfs2_cached_dealloc_ctxt *dealloc, |
2685 | struct ocfs2_extent_tree *et) | ||
2566 | { | 2686 | { |
2567 | int ret, orig_credits = handle->h_buffer_credits; | 2687 | int ret, orig_credits = handle->h_buffer_credits; |
2568 | struct ocfs2_path *tmp_path = NULL, *restart_path = NULL; | 2688 | struct ocfs2_path *tmp_path = NULL, *restart_path = NULL; |
@@ -2576,7 +2696,7 @@ static int ocfs2_rotate_tree_left(struct inode *inode, handle_t *handle, | |||
2576 | if (path->p_tree_depth == 0) { | 2696 | if (path->p_tree_depth == 0) { |
2577 | rightmost_no_delete: | 2697 | rightmost_no_delete: |
2578 | /* | 2698 | /* |
2579 | * In-inode extents. This is trivially handled, so do | 2699 | * Inline extents. This is trivially handled, so do |
2580 | * it up front. | 2700 | * it up front. |
2581 | */ | 2701 | */ |
2582 | ret = ocfs2_rotate_rightmost_leaf_left(inode, handle, | 2702 | ret = ocfs2_rotate_rightmost_leaf_left(inode, handle, |
@@ -2630,7 +2750,7 @@ rightmost_no_delete: | |||
2630 | */ | 2750 | */ |
2631 | 2751 | ||
2632 | ret = ocfs2_remove_rightmost_path(inode, handle, path, | 2752 | ret = ocfs2_remove_rightmost_path(inode, handle, path, |
2633 | dealloc); | 2753 | dealloc, et); |
2634 | if (ret) | 2754 | if (ret) |
2635 | mlog_errno(ret); | 2755 | mlog_errno(ret); |
2636 | goto out; | 2756 | goto out; |
@@ -2642,7 +2762,7 @@ rightmost_no_delete: | |||
2642 | */ | 2762 | */ |
2643 | try_rotate: | 2763 | try_rotate: |
2644 | ret = __ocfs2_rotate_tree_left(inode, handle, orig_credits, path, | 2764 | ret = __ocfs2_rotate_tree_left(inode, handle, orig_credits, path, |
2645 | dealloc, &restart_path); | 2765 | dealloc, &restart_path, et); |
2646 | if (ret && ret != -EAGAIN) { | 2766 | if (ret && ret != -EAGAIN) { |
2647 | mlog_errno(ret); | 2767 | mlog_errno(ret); |
2648 | goto out; | 2768 | goto out; |
@@ -2654,7 +2774,7 @@ try_rotate: | |||
2654 | 2774 | ||
2655 | ret = __ocfs2_rotate_tree_left(inode, handle, orig_credits, | 2775 | ret = __ocfs2_rotate_tree_left(inode, handle, orig_credits, |
2656 | tmp_path, dealloc, | 2776 | tmp_path, dealloc, |
2657 | &restart_path); | 2777 | &restart_path, et); |
2658 | if (ret && ret != -EAGAIN) { | 2778 | if (ret && ret != -EAGAIN) { |
2659 | mlog_errno(ret); | 2779 | mlog_errno(ret); |
2660 | goto out; | 2780 | goto out; |
@@ -2940,6 +3060,7 @@ static int ocfs2_merge_rec_left(struct inode *inode, | |||
2940 | handle_t *handle, | 3060 | handle_t *handle, |
2941 | struct ocfs2_extent_rec *split_rec, | 3061 | struct ocfs2_extent_rec *split_rec, |
2942 | struct ocfs2_cached_dealloc_ctxt *dealloc, | 3062 | struct ocfs2_cached_dealloc_ctxt *dealloc, |
3063 | struct ocfs2_extent_tree *et, | ||
2943 | int index) | 3064 | int index) |
2944 | { | 3065 | { |
2945 | int ret, i, subtree_index = 0, has_empty_extent = 0; | 3066 | int ret, i, subtree_index = 0, has_empty_extent = 0; |
@@ -3060,7 +3181,8 @@ static int ocfs2_merge_rec_left(struct inode *inode, | |||
3060 | le16_to_cpu(el->l_next_free_rec) == 1) { | 3181 | le16_to_cpu(el->l_next_free_rec) == 1) { |
3061 | 3182 | ||
3062 | ret = ocfs2_remove_rightmost_path(inode, handle, | 3183 | ret = ocfs2_remove_rightmost_path(inode, handle, |
3063 | right_path, dealloc); | 3184 | right_path, |
3185 | dealloc, et); | ||
3064 | if (ret) { | 3186 | if (ret) { |
3065 | mlog_errno(ret); | 3187 | mlog_errno(ret); |
3066 | goto out; | 3188 | goto out; |
@@ -3087,7 +3209,8 @@ static int ocfs2_try_to_merge_extent(struct inode *inode, | |||
3087 | int split_index, | 3209 | int split_index, |
3088 | struct ocfs2_extent_rec *split_rec, | 3210 | struct ocfs2_extent_rec *split_rec, |
3089 | struct ocfs2_cached_dealloc_ctxt *dealloc, | 3211 | struct ocfs2_cached_dealloc_ctxt *dealloc, |
3090 | struct ocfs2_merge_ctxt *ctxt) | 3212 | struct ocfs2_merge_ctxt *ctxt, |
3213 | struct ocfs2_extent_tree *et) | ||
3091 | 3214 | ||
3092 | { | 3215 | { |
3093 | int ret = 0; | 3216 | int ret = 0; |
@@ -3105,7 +3228,7 @@ static int ocfs2_try_to_merge_extent(struct inode *inode, | |||
3105 | * illegal. | 3228 | * illegal. |
3106 | */ | 3229 | */ |
3107 | ret = ocfs2_rotate_tree_left(inode, handle, path, | 3230 | ret = ocfs2_rotate_tree_left(inode, handle, path, |
3108 | dealloc); | 3231 | dealloc, et); |
3109 | if (ret) { | 3232 | if (ret) { |
3110 | mlog_errno(ret); | 3233 | mlog_errno(ret); |
3111 | goto out; | 3234 | goto out; |
@@ -3148,7 +3271,8 @@ static int ocfs2_try_to_merge_extent(struct inode *inode, | |||
3148 | BUG_ON(!ocfs2_is_empty_extent(&el->l_recs[0])); | 3271 | BUG_ON(!ocfs2_is_empty_extent(&el->l_recs[0])); |
3149 | 3272 | ||
3150 | /* The merge left us with an empty extent, remove it. */ | 3273 | /* The merge left us with an empty extent, remove it. */ |
3151 | ret = ocfs2_rotate_tree_left(inode, handle, path, dealloc); | 3274 | ret = ocfs2_rotate_tree_left(inode, handle, path, |
3275 | dealloc, et); | ||
3152 | if (ret) { | 3276 | if (ret) { |
3153 | mlog_errno(ret); | 3277 | mlog_errno(ret); |
3154 | goto out; | 3278 | goto out; |
@@ -3162,7 +3286,7 @@ static int ocfs2_try_to_merge_extent(struct inode *inode, | |||
3162 | */ | 3286 | */ |
3163 | ret = ocfs2_merge_rec_left(inode, path, | 3287 | ret = ocfs2_merge_rec_left(inode, path, |
3164 | handle, rec, | 3288 | handle, rec, |
3165 | dealloc, | 3289 | dealloc, et, |
3166 | split_index); | 3290 | split_index); |
3167 | 3291 | ||
3168 | if (ret) { | 3292 | if (ret) { |
@@ -3171,7 +3295,7 @@ static int ocfs2_try_to_merge_extent(struct inode *inode, | |||
3171 | } | 3295 | } |
3172 | 3296 | ||
3173 | ret = ocfs2_rotate_tree_left(inode, handle, path, | 3297 | ret = ocfs2_rotate_tree_left(inode, handle, path, |
3174 | dealloc); | 3298 | dealloc, et); |
3175 | /* | 3299 | /* |
3176 | * Error from this last rotate is not critical, so | 3300 | * Error from this last rotate is not critical, so |
3177 | * print but don't bubble it up. | 3301 | * print but don't bubble it up. |
@@ -3191,7 +3315,7 @@ static int ocfs2_try_to_merge_extent(struct inode *inode, | |||
3191 | ret = ocfs2_merge_rec_left(inode, | 3315 | ret = ocfs2_merge_rec_left(inode, |
3192 | path, | 3316 | path, |
3193 | handle, split_rec, | 3317 | handle, split_rec, |
3194 | dealloc, | 3318 | dealloc, et, |
3195 | split_index); | 3319 | split_index); |
3196 | if (ret) { | 3320 | if (ret) { |
3197 | mlog_errno(ret); | 3321 | mlog_errno(ret); |
@@ -3214,7 +3338,7 @@ static int ocfs2_try_to_merge_extent(struct inode *inode, | |||
3214 | * our leaf. Try to rotate it away. | 3338 | * our leaf. Try to rotate it away. |
3215 | */ | 3339 | */ |
3216 | ret = ocfs2_rotate_tree_left(inode, handle, path, | 3340 | ret = ocfs2_rotate_tree_left(inode, handle, path, |
3217 | dealloc); | 3341 | dealloc, et); |
3218 | if (ret) | 3342 | if (ret) |
3219 | mlog_errno(ret); | 3343 | mlog_errno(ret); |
3220 | ret = 0; | 3344 | ret = 0; |
@@ -3348,16 +3472,6 @@ rotate: | |||
3348 | ocfs2_rotate_leaf(el, insert_rec); | 3472 | ocfs2_rotate_leaf(el, insert_rec); |
3349 | } | 3473 | } |
3350 | 3474 | ||
3351 | static inline void ocfs2_update_dinode_clusters(struct inode *inode, | ||
3352 | struct ocfs2_dinode *di, | ||
3353 | u32 clusters) | ||
3354 | { | ||
3355 | le32_add_cpu(&di->i_clusters, clusters); | ||
3356 | spin_lock(&OCFS2_I(inode)->ip_lock); | ||
3357 | OCFS2_I(inode)->ip_clusters = le32_to_cpu(di->i_clusters); | ||
3358 | spin_unlock(&OCFS2_I(inode)->ip_lock); | ||
3359 | } | ||
3360 | |||
3361 | static void ocfs2_adjust_rightmost_records(struct inode *inode, | 3475 | static void ocfs2_adjust_rightmost_records(struct inode *inode, |
3362 | handle_t *handle, | 3476 | handle_t *handle, |
3363 | struct ocfs2_path *path, | 3477 | struct ocfs2_path *path, |
@@ -3559,8 +3673,8 @@ static void ocfs2_split_record(struct inode *inode, | |||
3559 | } | 3673 | } |
3560 | 3674 | ||
3561 | /* | 3675 | /* |
3562 | * This function only does inserts on an allocation b-tree. For dinode | 3676 | * This function only does inserts on an allocation b-tree. For tree |
3563 | * lists, ocfs2_insert_at_leaf() is called directly. | 3677 | * depth = 0, ocfs2_insert_at_leaf() is called directly. |
3564 | * | 3678 | * |
3565 | * right_path is the path we want to do the actual insert | 3679 | * right_path is the path we want to do the actual insert |
3566 | * in. left_path should only be passed in if we need to update that | 3680 | * in. left_path should only be passed in if we need to update that |
@@ -3657,7 +3771,7 @@ out: | |||
3657 | 3771 | ||
3658 | static int ocfs2_do_insert_extent(struct inode *inode, | 3772 | static int ocfs2_do_insert_extent(struct inode *inode, |
3659 | handle_t *handle, | 3773 | handle_t *handle, |
3660 | struct buffer_head *di_bh, | 3774 | struct ocfs2_extent_tree *et, |
3661 | struct ocfs2_extent_rec *insert_rec, | 3775 | struct ocfs2_extent_rec *insert_rec, |
3662 | struct ocfs2_insert_type *type) | 3776 | struct ocfs2_insert_type *type) |
3663 | { | 3777 | { |
@@ -3665,13 +3779,11 @@ static int ocfs2_do_insert_extent(struct inode *inode, | |||
3665 | u32 cpos; | 3779 | u32 cpos; |
3666 | struct ocfs2_path *right_path = NULL; | 3780 | struct ocfs2_path *right_path = NULL; |
3667 | struct ocfs2_path *left_path = NULL; | 3781 | struct ocfs2_path *left_path = NULL; |
3668 | struct ocfs2_dinode *di; | ||
3669 | struct ocfs2_extent_list *el; | 3782 | struct ocfs2_extent_list *el; |
3670 | 3783 | ||
3671 | di = (struct ocfs2_dinode *) di_bh->b_data; | 3784 | el = et->root_el; |
3672 | el = &di->id2.i_list; | ||
3673 | 3785 | ||
3674 | ret = ocfs2_journal_access(handle, inode, di_bh, | 3786 | ret = ocfs2_journal_access(handle, inode, et->root_bh, |
3675 | OCFS2_JOURNAL_ACCESS_WRITE); | 3787 | OCFS2_JOURNAL_ACCESS_WRITE); |
3676 | if (ret) { | 3788 | if (ret) { |
3677 | mlog_errno(ret); | 3789 | mlog_errno(ret); |
@@ -3683,7 +3795,7 @@ static int ocfs2_do_insert_extent(struct inode *inode, | |||
3683 | goto out_update_clusters; | 3795 | goto out_update_clusters; |
3684 | } | 3796 | } |
3685 | 3797 | ||
3686 | right_path = ocfs2_new_inode_path(di_bh); | 3798 | right_path = ocfs2_new_path(et->root_bh, et->root_el); |
3687 | if (!right_path) { | 3799 | if (!right_path) { |
3688 | ret = -ENOMEM; | 3800 | ret = -ENOMEM; |
3689 | mlog_errno(ret); | 3801 | mlog_errno(ret); |
@@ -3733,7 +3845,7 @@ static int ocfs2_do_insert_extent(struct inode *inode, | |||
3733 | * ocfs2_rotate_tree_right() might have extended the | 3845 | * ocfs2_rotate_tree_right() might have extended the |
3734 | * transaction without re-journaling our tree root. | 3846 | * transaction without re-journaling our tree root. |
3735 | */ | 3847 | */ |
3736 | ret = ocfs2_journal_access(handle, inode, di_bh, | 3848 | ret = ocfs2_journal_access(handle, inode, et->root_bh, |
3737 | OCFS2_JOURNAL_ACCESS_WRITE); | 3849 | OCFS2_JOURNAL_ACCESS_WRITE); |
3738 | if (ret) { | 3850 | if (ret) { |
3739 | mlog_errno(ret); | 3851 | mlog_errno(ret); |
@@ -3758,10 +3870,10 @@ static int ocfs2_do_insert_extent(struct inode *inode, | |||
3758 | 3870 | ||
3759 | out_update_clusters: | 3871 | out_update_clusters: |
3760 | if (type->ins_split == SPLIT_NONE) | 3872 | if (type->ins_split == SPLIT_NONE) |
3761 | ocfs2_update_dinode_clusters(inode, di, | 3873 | ocfs2_update_clusters(inode, et, |
3762 | le16_to_cpu(insert_rec->e_leaf_clusters)); | 3874 | le16_to_cpu(insert_rec->e_leaf_clusters)); |
3763 | 3875 | ||
3764 | ret = ocfs2_journal_dirty(handle, di_bh); | 3876 | ret = ocfs2_journal_dirty(handle, et->root_bh); |
3765 | if (ret) | 3877 | if (ret) |
3766 | mlog_errno(ret); | 3878 | mlog_errno(ret); |
3767 | 3879 | ||
@@ -3915,8 +4027,8 @@ static void ocfs2_figure_contig_type(struct inode *inode, | |||
3915 | * ocfs2_figure_appending_type() will figure out whether we'll have to | 4027 | * ocfs2_figure_appending_type() will figure out whether we'll have to |
3916 | * insert at the tail of the rightmost leaf. | 4028 | * insert at the tail of the rightmost leaf. |
3917 | * | 4029 | * |
3918 | * This should also work against the dinode list for tree's with 0 | 4030 | * This should also work against the root extent list for tree's with 0 |
3919 | * depth. If we consider the dinode list to be the rightmost leaf node | 4031 | * depth. If we consider the root extent list to be the rightmost leaf node |
3920 | * then the logic here makes sense. | 4032 | * then the logic here makes sense. |
3921 | */ | 4033 | */ |
3922 | static void ocfs2_figure_appending_type(struct ocfs2_insert_type *insert, | 4034 | static void ocfs2_figure_appending_type(struct ocfs2_insert_type *insert, |
@@ -3967,14 +4079,13 @@ set_tail_append: | |||
3967 | * structure. | 4079 | * structure. |
3968 | */ | 4080 | */ |
3969 | static int ocfs2_figure_insert_type(struct inode *inode, | 4081 | static int ocfs2_figure_insert_type(struct inode *inode, |
3970 | struct buffer_head *di_bh, | 4082 | struct ocfs2_extent_tree *et, |
3971 | struct buffer_head **last_eb_bh, | 4083 | struct buffer_head **last_eb_bh, |
3972 | struct ocfs2_extent_rec *insert_rec, | 4084 | struct ocfs2_extent_rec *insert_rec, |
3973 | int *free_records, | 4085 | int *free_records, |
3974 | struct ocfs2_insert_type *insert) | 4086 | struct ocfs2_insert_type *insert) |
3975 | { | 4087 | { |
3976 | int ret; | 4088 | int ret; |
3977 | struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data; | ||
3978 | struct ocfs2_extent_block *eb; | 4089 | struct ocfs2_extent_block *eb; |
3979 | struct ocfs2_extent_list *el; | 4090 | struct ocfs2_extent_list *el; |
3980 | struct ocfs2_path *path = NULL; | 4091 | struct ocfs2_path *path = NULL; |
@@ -3982,7 +4093,7 @@ static int ocfs2_figure_insert_type(struct inode *inode, | |||
3982 | 4093 | ||
3983 | insert->ins_split = SPLIT_NONE; | 4094 | insert->ins_split = SPLIT_NONE; |
3984 | 4095 | ||
3985 | el = &di->id2.i_list; | 4096 | el = et->root_el; |
3986 | insert->ins_tree_depth = le16_to_cpu(el->l_tree_depth); | 4097 | insert->ins_tree_depth = le16_to_cpu(el->l_tree_depth); |
3987 | 4098 | ||
3988 | if (el->l_tree_depth) { | 4099 | if (el->l_tree_depth) { |
@@ -3993,7 +4104,7 @@ static int ocfs2_figure_insert_type(struct inode *inode, | |||
3993 | * may want it later. | 4104 | * may want it later. |
3994 | */ | 4105 | */ |
3995 | ret = ocfs2_read_block(OCFS2_SB(inode->i_sb), | 4106 | ret = ocfs2_read_block(OCFS2_SB(inode->i_sb), |
3996 | le64_to_cpu(di->i_last_eb_blk), &bh, | 4107 | ocfs2_get_last_eb_blk(et), &bh, |
3997 | OCFS2_BH_CACHED, inode); | 4108 | OCFS2_BH_CACHED, inode); |
3998 | if (ret) { | 4109 | if (ret) { |
3999 | mlog_exit(ret); | 4110 | mlog_exit(ret); |
@@ -4020,7 +4131,7 @@ static int ocfs2_figure_insert_type(struct inode *inode, | |||
4020 | return 0; | 4131 | return 0; |
4021 | } | 4132 | } |
4022 | 4133 | ||
4023 | path = ocfs2_new_inode_path(di_bh); | 4134 | path = ocfs2_new_path(et->root_bh, et->root_el); |
4024 | if (!path) { | 4135 | if (!path) { |
4025 | ret = -ENOMEM; | 4136 | ret = -ENOMEM; |
4026 | mlog_errno(ret); | 4137 | mlog_errno(ret); |
@@ -4070,7 +4181,8 @@ static int ocfs2_figure_insert_type(struct inode *inode, | |||
4070 | * the case that we're doing a tail append, so maybe we can | 4181 | * the case that we're doing a tail append, so maybe we can |
4071 | * take advantage of that information somehow. | 4182 | * take advantage of that information somehow. |
4072 | */ | 4183 | */ |
4073 | if (le64_to_cpu(di->i_last_eb_blk) == path_leaf_bh(path)->b_blocknr) { | 4184 | if (ocfs2_get_last_eb_blk(et) == |
4185 | path_leaf_bh(path)->b_blocknr) { | ||
4074 | /* | 4186 | /* |
4075 | * Ok, ocfs2_find_path() returned us the rightmost | 4187 | * Ok, ocfs2_find_path() returned us the rightmost |
4076 | * tree path. This might be an appending insert. There are | 4188 | * tree path. This might be an appending insert. There are |
@@ -4100,21 +4212,30 @@ out: | |||
4100 | int ocfs2_insert_extent(struct ocfs2_super *osb, | 4212 | int ocfs2_insert_extent(struct ocfs2_super *osb, |
4101 | handle_t *handle, | 4213 | handle_t *handle, |
4102 | struct inode *inode, | 4214 | struct inode *inode, |
4103 | struct buffer_head *fe_bh, | 4215 | struct buffer_head *root_bh, |
4104 | u32 cpos, | 4216 | u32 cpos, |
4105 | u64 start_blk, | 4217 | u64 start_blk, |
4106 | u32 new_clusters, | 4218 | u32 new_clusters, |
4107 | u8 flags, | 4219 | u8 flags, |
4108 | struct ocfs2_alloc_context *meta_ac) | 4220 | struct ocfs2_alloc_context *meta_ac, |
4221 | enum ocfs2_extent_tree_type et_type) | ||
4109 | { | 4222 | { |
4110 | int status; | 4223 | int status; |
4111 | int uninitialized_var(free_records); | 4224 | int uninitialized_var(free_records); |
4112 | struct buffer_head *last_eb_bh = NULL; | 4225 | struct buffer_head *last_eb_bh = NULL; |
4113 | struct ocfs2_insert_type insert = {0, }; | 4226 | struct ocfs2_insert_type insert = {0, }; |
4114 | struct ocfs2_extent_rec rec; | 4227 | struct ocfs2_extent_rec rec; |
4228 | struct ocfs2_extent_tree *et = NULL; | ||
4115 | 4229 | ||
4116 | BUG_ON(OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL); | 4230 | BUG_ON(OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL); |
4117 | 4231 | ||
4232 | et = ocfs2_new_extent_tree(root_bh, et_type); | ||
4233 | if (!et) { | ||
4234 | status = -ENOMEM; | ||
4235 | mlog_errno(status); | ||
4236 | goto bail; | ||
4237 | } | ||
4238 | |||
4118 | mlog(0, "add %u clusters at position %u to inode %llu\n", | 4239 | mlog(0, "add %u clusters at position %u to inode %llu\n", |
4119 | new_clusters, cpos, (unsigned long long)OCFS2_I(inode)->ip_blkno); | 4240 | new_clusters, cpos, (unsigned long long)OCFS2_I(inode)->ip_blkno); |
4120 | 4241 | ||
@@ -4132,7 +4253,7 @@ int ocfs2_insert_extent(struct ocfs2_super *osb, | |||
4132 | rec.e_leaf_clusters = cpu_to_le16(new_clusters); | 4253 | rec.e_leaf_clusters = cpu_to_le16(new_clusters); |
4133 | rec.e_flags = flags; | 4254 | rec.e_flags = flags; |
4134 | 4255 | ||
4135 | status = ocfs2_figure_insert_type(inode, fe_bh, &last_eb_bh, &rec, | 4256 | status = ocfs2_figure_insert_type(inode, et, &last_eb_bh, &rec, |
4136 | &free_records, &insert); | 4257 | &free_records, &insert); |
4137 | if (status < 0) { | 4258 | if (status < 0) { |
4138 | mlog_errno(status); | 4259 | mlog_errno(status); |
@@ -4146,7 +4267,7 @@ int ocfs2_insert_extent(struct ocfs2_super *osb, | |||
4146 | free_records, insert.ins_tree_depth); | 4267 | free_records, insert.ins_tree_depth); |
4147 | 4268 | ||
4148 | if (insert.ins_contig == CONTIG_NONE && free_records == 0) { | 4269 | if (insert.ins_contig == CONTIG_NONE && free_records == 0) { |
4149 | status = ocfs2_grow_tree(inode, handle, fe_bh, | 4270 | status = ocfs2_grow_tree(inode, handle, et, |
4150 | &insert.ins_tree_depth, &last_eb_bh, | 4271 | &insert.ins_tree_depth, &last_eb_bh, |
4151 | meta_ac); | 4272 | meta_ac); |
4152 | if (status) { | 4273 | if (status) { |
@@ -4156,16 +4277,18 @@ int ocfs2_insert_extent(struct ocfs2_super *osb, | |||
4156 | } | 4277 | } |
4157 | 4278 | ||
4158 | /* Finally, we can add clusters. This might rotate the tree for us. */ | 4279 | /* Finally, we can add clusters. This might rotate the tree for us. */ |
4159 | status = ocfs2_do_insert_extent(inode, handle, fe_bh, &rec, &insert); | 4280 | status = ocfs2_do_insert_extent(inode, handle, et, &rec, &insert); |
4160 | if (status < 0) | 4281 | if (status < 0) |
4161 | mlog_errno(status); | 4282 | mlog_errno(status); |
4162 | else | 4283 | else if (et->type == OCFS2_DINODE_EXTENT) |
4163 | ocfs2_extent_map_insert_rec(inode, &rec); | 4284 | ocfs2_extent_map_insert_rec(inode, &rec); |
4164 | 4285 | ||
4165 | bail: | 4286 | bail: |
4166 | if (last_eb_bh) | 4287 | if (last_eb_bh) |
4167 | brelse(last_eb_bh); | 4288 | brelse(last_eb_bh); |
4168 | 4289 | ||
4290 | if (et) | ||
4291 | ocfs2_free_extent_tree(et); | ||
4169 | mlog_exit(status); | 4292 | mlog_exit(status); |
4170 | return status; | 4293 | return status; |
4171 | } | 4294 | } |
@@ -4193,7 +4316,7 @@ static void ocfs2_make_right_split_rec(struct super_block *sb, | |||
4193 | static int ocfs2_split_and_insert(struct inode *inode, | 4316 | static int ocfs2_split_and_insert(struct inode *inode, |
4194 | handle_t *handle, | 4317 | handle_t *handle, |
4195 | struct ocfs2_path *path, | 4318 | struct ocfs2_path *path, |
4196 | struct buffer_head *di_bh, | 4319 | struct ocfs2_extent_tree *et, |
4197 | struct buffer_head **last_eb_bh, | 4320 | struct buffer_head **last_eb_bh, |
4198 | int split_index, | 4321 | int split_index, |
4199 | struct ocfs2_extent_rec *orig_split_rec, | 4322 | struct ocfs2_extent_rec *orig_split_rec, |
@@ -4207,7 +4330,6 @@ static int ocfs2_split_and_insert(struct inode *inode, | |||
4207 | struct ocfs2_extent_rec split_rec = *orig_split_rec; | 4330 | struct ocfs2_extent_rec split_rec = *orig_split_rec; |
4208 | struct ocfs2_insert_type insert; | 4331 | struct ocfs2_insert_type insert; |
4209 | struct ocfs2_extent_block *eb; | 4332 | struct ocfs2_extent_block *eb; |
4210 | struct ocfs2_dinode *di; | ||
4211 | 4333 | ||
4212 | leftright: | 4334 | leftright: |
4213 | /* | 4335 | /* |
@@ -4216,8 +4338,7 @@ leftright: | |||
4216 | */ | 4338 | */ |
4217 | rec = path_leaf_el(path)->l_recs[split_index]; | 4339 | rec = path_leaf_el(path)->l_recs[split_index]; |
4218 | 4340 | ||
4219 | di = (struct ocfs2_dinode *)di_bh->b_data; | 4341 | rightmost_el = et->root_el; |
4220 | rightmost_el = &di->id2.i_list; | ||
4221 | 4342 | ||
4222 | depth = le16_to_cpu(rightmost_el->l_tree_depth); | 4343 | depth = le16_to_cpu(rightmost_el->l_tree_depth); |
4223 | if (depth) { | 4344 | if (depth) { |
@@ -4228,8 +4349,8 @@ leftright: | |||
4228 | 4349 | ||
4229 | if (le16_to_cpu(rightmost_el->l_next_free_rec) == | 4350 | if (le16_to_cpu(rightmost_el->l_next_free_rec) == |
4230 | le16_to_cpu(rightmost_el->l_count)) { | 4351 | le16_to_cpu(rightmost_el->l_count)) { |
4231 | ret = ocfs2_grow_tree(inode, handle, di_bh, &depth, last_eb_bh, | 4352 | ret = ocfs2_grow_tree(inode, handle, et, |
4232 | meta_ac); | 4353 | &depth, last_eb_bh, meta_ac); |
4233 | if (ret) { | 4354 | if (ret) { |
4234 | mlog_errno(ret); | 4355 | mlog_errno(ret); |
4235 | goto out; | 4356 | goto out; |
@@ -4266,8 +4387,7 @@ leftright: | |||
4266 | do_leftright = 1; | 4387 | do_leftright = 1; |
4267 | } | 4388 | } |
4268 | 4389 | ||
4269 | ret = ocfs2_do_insert_extent(inode, handle, di_bh, &split_rec, | 4390 | ret = ocfs2_do_insert_extent(inode, handle, et, &split_rec, &insert); |
4270 | &insert); | ||
4271 | if (ret) { | 4391 | if (ret) { |
4272 | mlog_errno(ret); | 4392 | mlog_errno(ret); |
4273 | goto out; | 4393 | goto out; |
@@ -4309,8 +4429,9 @@ out: | |||
4309 | * of the tree is required. All other cases will degrade into a less | 4429 | * of the tree is required. All other cases will degrade into a less |
4310 | * optimal tree layout. | 4430 | * optimal tree layout. |
4311 | * | 4431 | * |
4312 | * last_eb_bh should be the rightmost leaf block for any inode with a | 4432 | * last_eb_bh should be the rightmost leaf block for any extent |
4313 | * btree. Since a split may grow the tree or a merge might shrink it, the caller cannot trust the contents of that buffer after this call. | 4433 | * btree. Since a split may grow the tree or a merge might shrink it, |
4434 | * the caller cannot trust the contents of that buffer after this call. | ||
4314 | * | 4435 | * |
4315 | * This code is optimized for readability - several passes might be | 4436 | * This code is optimized for readability - several passes might be |
4316 | * made over certain portions of the tree. All of those blocks will | 4437 | * made over certain portions of the tree. All of those blocks will |
@@ -4318,7 +4439,7 @@ out: | |||
4318 | * extra overhead is not expressed in terms of disk reads. | 4439 | * extra overhead is not expressed in terms of disk reads. |
4319 | */ | 4440 | */ |
4320 | static int __ocfs2_mark_extent_written(struct inode *inode, | 4441 | static int __ocfs2_mark_extent_written(struct inode *inode, |
4321 | struct buffer_head *di_bh, | 4442 | struct ocfs2_extent_tree *et, |
4322 | handle_t *handle, | 4443 | handle_t *handle, |
4323 | struct ocfs2_path *path, | 4444 | struct ocfs2_path *path, |
4324 | int split_index, | 4445 | int split_index, |
@@ -4358,10 +4479,9 @@ static int __ocfs2_mark_extent_written(struct inode *inode, | |||
4358 | */ | 4479 | */ |
4359 | if (path->p_tree_depth) { | 4480 | if (path->p_tree_depth) { |
4360 | struct ocfs2_extent_block *eb; | 4481 | struct ocfs2_extent_block *eb; |
4361 | struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data; | ||
4362 | 4482 | ||
4363 | ret = ocfs2_read_block(OCFS2_SB(inode->i_sb), | 4483 | ret = ocfs2_read_block(OCFS2_SB(inode->i_sb), |
4364 | le64_to_cpu(di->i_last_eb_blk), | 4484 | ocfs2_get_last_eb_blk(et), |
4365 | &last_eb_bh, OCFS2_BH_CACHED, inode); | 4485 | &last_eb_bh, OCFS2_BH_CACHED, inode); |
4366 | if (ret) { | 4486 | if (ret) { |
4367 | mlog_exit(ret); | 4487 | mlog_exit(ret); |
@@ -4395,7 +4515,7 @@ static int __ocfs2_mark_extent_written(struct inode *inode, | |||
4395 | if (ctxt.c_split_covers_rec) | 4515 | if (ctxt.c_split_covers_rec) |
4396 | el->l_recs[split_index] = *split_rec; | 4516 | el->l_recs[split_index] = *split_rec; |
4397 | else | 4517 | else |
4398 | ret = ocfs2_split_and_insert(inode, handle, path, di_bh, | 4518 | ret = ocfs2_split_and_insert(inode, handle, path, et, |
4399 | &last_eb_bh, split_index, | 4519 | &last_eb_bh, split_index, |
4400 | split_rec, meta_ac); | 4520 | split_rec, meta_ac); |
4401 | if (ret) | 4521 | if (ret) |
@@ -4403,7 +4523,7 @@ static int __ocfs2_mark_extent_written(struct inode *inode, | |||
4403 | } else { | 4523 | } else { |
4404 | ret = ocfs2_try_to_merge_extent(inode, handle, path, | 4524 | ret = ocfs2_try_to_merge_extent(inode, handle, path, |
4405 | split_index, split_rec, | 4525 | split_index, split_rec, |
4406 | dealloc, &ctxt); | 4526 | dealloc, &ctxt, et); |
4407 | if (ret) | 4527 | if (ret) |
4408 | mlog_errno(ret); | 4528 | mlog_errno(ret); |
4409 | } | 4529 | } |
@@ -4421,16 +4541,18 @@ out: | |||
4421 | * | 4541 | * |
4422 | * The caller is responsible for passing down meta_ac if we'll need it. | 4542 | * The caller is responsible for passing down meta_ac if we'll need it. |
4423 | */ | 4543 | */ |
4424 | int ocfs2_mark_extent_written(struct inode *inode, struct buffer_head *di_bh, | 4544 | int ocfs2_mark_extent_written(struct inode *inode, struct buffer_head *root_bh, |
4425 | handle_t *handle, u32 cpos, u32 len, u32 phys, | 4545 | handle_t *handle, u32 cpos, u32 len, u32 phys, |
4426 | struct ocfs2_alloc_context *meta_ac, | 4546 | struct ocfs2_alloc_context *meta_ac, |
4427 | struct ocfs2_cached_dealloc_ctxt *dealloc) | 4547 | struct ocfs2_cached_dealloc_ctxt *dealloc, |
4548 | enum ocfs2_extent_tree_type et_type) | ||
4428 | { | 4549 | { |
4429 | int ret, index; | 4550 | int ret, index; |
4430 | u64 start_blkno = ocfs2_clusters_to_blocks(inode->i_sb, phys); | 4551 | u64 start_blkno = ocfs2_clusters_to_blocks(inode->i_sb, phys); |
4431 | struct ocfs2_extent_rec split_rec; | 4552 | struct ocfs2_extent_rec split_rec; |
4432 | struct ocfs2_path *left_path = NULL; | 4553 | struct ocfs2_path *left_path = NULL; |
4433 | struct ocfs2_extent_list *el; | 4554 | struct ocfs2_extent_list *el; |
4555 | struct ocfs2_extent_tree *et = NULL; | ||
4434 | 4556 | ||
4435 | mlog(0, "Inode %lu cpos %u, len %u, phys %u (%llu)\n", | 4557 | mlog(0, "Inode %lu cpos %u, len %u, phys %u (%llu)\n", |
4436 | inode->i_ino, cpos, len, phys, (unsigned long long)start_blkno); | 4558 | inode->i_ino, cpos, len, phys, (unsigned long long)start_blkno); |
@@ -4444,13 +4566,21 @@ int ocfs2_mark_extent_written(struct inode *inode, struct buffer_head *di_bh, | |||
4444 | goto out; | 4566 | goto out; |
4445 | } | 4567 | } |
4446 | 4568 | ||
4569 | et = ocfs2_new_extent_tree(root_bh, et_type); | ||
4570 | if (!et) { | ||
4571 | ret = -ENOMEM; | ||
4572 | mlog_errno(ret); | ||
4573 | goto out; | ||
4574 | } | ||
4575 | |||
4447 | /* | 4576 | /* |
4448 | * XXX: This should be fixed up so that we just re-insert the | 4577 | * XXX: This should be fixed up so that we just re-insert the |
4449 | * next extent records. | 4578 | * next extent records. |
4450 | */ | 4579 | */ |
4451 | ocfs2_extent_map_trunc(inode, 0); | 4580 | if (et_type == OCFS2_DINODE_EXTENT) |
4581 | ocfs2_extent_map_trunc(inode, 0); | ||
4452 | 4582 | ||
4453 | left_path = ocfs2_new_inode_path(di_bh); | 4583 | left_path = ocfs2_new_path(et->root_bh, et->root_el); |
4454 | if (!left_path) { | 4584 | if (!left_path) { |
4455 | ret = -ENOMEM; | 4585 | ret = -ENOMEM; |
4456 | mlog_errno(ret); | 4586 | mlog_errno(ret); |
@@ -4481,23 +4611,25 @@ int ocfs2_mark_extent_written(struct inode *inode, struct buffer_head *di_bh, | |||
4481 | split_rec.e_flags = path_leaf_el(left_path)->l_recs[index].e_flags; | 4611 | split_rec.e_flags = path_leaf_el(left_path)->l_recs[index].e_flags; |
4482 | split_rec.e_flags &= ~OCFS2_EXT_UNWRITTEN; | 4612 | split_rec.e_flags &= ~OCFS2_EXT_UNWRITTEN; |
4483 | 4613 | ||
4484 | ret = __ocfs2_mark_extent_written(inode, di_bh, handle, left_path, | 4614 | ret = __ocfs2_mark_extent_written(inode, et, handle, left_path, |
4485 | index, &split_rec, meta_ac, dealloc); | 4615 | index, &split_rec, meta_ac, |
4616 | dealloc); | ||
4486 | if (ret) | 4617 | if (ret) |
4487 | mlog_errno(ret); | 4618 | mlog_errno(ret); |
4488 | 4619 | ||
4489 | out: | 4620 | out: |
4490 | ocfs2_free_path(left_path); | 4621 | ocfs2_free_path(left_path); |
4622 | if (et) | ||
4623 | ocfs2_free_extent_tree(et); | ||
4491 | return ret; | 4624 | return ret; |
4492 | } | 4625 | } |
4493 | 4626 | ||
4494 | static int ocfs2_split_tree(struct inode *inode, struct buffer_head *di_bh, | 4627 | static int ocfs2_split_tree(struct inode *inode, struct ocfs2_extent_tree *et, |
4495 | handle_t *handle, struct ocfs2_path *path, | 4628 | handle_t *handle, struct ocfs2_path *path, |
4496 | int index, u32 new_range, | 4629 | int index, u32 new_range, |
4497 | struct ocfs2_alloc_context *meta_ac) | 4630 | struct ocfs2_alloc_context *meta_ac) |
4498 | { | 4631 | { |
4499 | int ret, depth, credits = handle->h_buffer_credits; | 4632 | int ret, depth, credits = handle->h_buffer_credits; |
4500 | struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data; | ||
4501 | struct buffer_head *last_eb_bh = NULL; | 4633 | struct buffer_head *last_eb_bh = NULL; |
4502 | struct ocfs2_extent_block *eb; | 4634 | struct ocfs2_extent_block *eb; |
4503 | struct ocfs2_extent_list *rightmost_el, *el; | 4635 | struct ocfs2_extent_list *rightmost_el, *el; |
@@ -4515,7 +4647,7 @@ static int ocfs2_split_tree(struct inode *inode, struct buffer_head *di_bh, | |||
4515 | depth = path->p_tree_depth; | 4647 | depth = path->p_tree_depth; |
4516 | if (depth > 0) { | 4648 | if (depth > 0) { |
4517 | ret = ocfs2_read_block(OCFS2_SB(inode->i_sb), | 4649 | ret = ocfs2_read_block(OCFS2_SB(inode->i_sb), |
4518 | le64_to_cpu(di->i_last_eb_blk), | 4650 | ocfs2_get_last_eb_blk(et), |
4519 | &last_eb_bh, OCFS2_BH_CACHED, inode); | 4651 | &last_eb_bh, OCFS2_BH_CACHED, inode); |
4520 | if (ret < 0) { | 4652 | if (ret < 0) { |
4521 | mlog_errno(ret); | 4653 | mlog_errno(ret); |
@@ -4528,7 +4660,7 @@ static int ocfs2_split_tree(struct inode *inode, struct buffer_head *di_bh, | |||
4528 | rightmost_el = path_leaf_el(path); | 4660 | rightmost_el = path_leaf_el(path); |
4529 | 4661 | ||
4530 | credits += path->p_tree_depth + | 4662 | credits += path->p_tree_depth + |
4531 | ocfs2_extend_meta_needed(&di->id2.i_list); | 4663 | ocfs2_extend_meta_needed(et->root_el); |
4532 | ret = ocfs2_extend_trans(handle, credits); | 4664 | ret = ocfs2_extend_trans(handle, credits); |
4533 | if (ret) { | 4665 | if (ret) { |
4534 | mlog_errno(ret); | 4666 | mlog_errno(ret); |
@@ -4537,7 +4669,7 @@ static int ocfs2_split_tree(struct inode *inode, struct buffer_head *di_bh, | |||
4537 | 4669 | ||
4538 | if (le16_to_cpu(rightmost_el->l_next_free_rec) == | 4670 | if (le16_to_cpu(rightmost_el->l_next_free_rec) == |
4539 | le16_to_cpu(rightmost_el->l_count)) { | 4671 | le16_to_cpu(rightmost_el->l_count)) { |
4540 | ret = ocfs2_grow_tree(inode, handle, di_bh, &depth, &last_eb_bh, | 4672 | ret = ocfs2_grow_tree(inode, handle, et, &depth, &last_eb_bh, |
4541 | meta_ac); | 4673 | meta_ac); |
4542 | if (ret) { | 4674 | if (ret) { |
4543 | mlog_errno(ret); | 4675 | mlog_errno(ret); |
@@ -4551,7 +4683,7 @@ static int ocfs2_split_tree(struct inode *inode, struct buffer_head *di_bh, | |||
4551 | insert.ins_split = SPLIT_RIGHT; | 4683 | insert.ins_split = SPLIT_RIGHT; |
4552 | insert.ins_tree_depth = depth; | 4684 | insert.ins_tree_depth = depth; |
4553 | 4685 | ||
4554 | ret = ocfs2_do_insert_extent(inode, handle, di_bh, &split_rec, &insert); | 4686 | ret = ocfs2_do_insert_extent(inode, handle, et, &split_rec, &insert); |
4555 | if (ret) | 4687 | if (ret) |
4556 | mlog_errno(ret); | 4688 | mlog_errno(ret); |
4557 | 4689 | ||
@@ -4563,7 +4695,8 @@ out: | |||
4563 | static int ocfs2_truncate_rec(struct inode *inode, handle_t *handle, | 4695 | static int ocfs2_truncate_rec(struct inode *inode, handle_t *handle, |
4564 | struct ocfs2_path *path, int index, | 4696 | struct ocfs2_path *path, int index, |
4565 | struct ocfs2_cached_dealloc_ctxt *dealloc, | 4697 | struct ocfs2_cached_dealloc_ctxt *dealloc, |
4566 | u32 cpos, u32 len) | 4698 | u32 cpos, u32 len, |
4699 | struct ocfs2_extent_tree *et) | ||
4567 | { | 4700 | { |
4568 | int ret; | 4701 | int ret; |
4569 | u32 left_cpos, rec_range, trunc_range; | 4702 | u32 left_cpos, rec_range, trunc_range; |
@@ -4575,7 +4708,7 @@ static int ocfs2_truncate_rec(struct inode *inode, handle_t *handle, | |||
4575 | struct ocfs2_extent_block *eb; | 4708 | struct ocfs2_extent_block *eb; |
4576 | 4709 | ||
4577 | if (ocfs2_is_empty_extent(&el->l_recs[0]) && index > 0) { | 4710 | if (ocfs2_is_empty_extent(&el->l_recs[0]) && index > 0) { |
4578 | ret = ocfs2_rotate_tree_left(inode, handle, path, dealloc); | 4711 | ret = ocfs2_rotate_tree_left(inode, handle, path, dealloc, et); |
4579 | if (ret) { | 4712 | if (ret) { |
4580 | mlog_errno(ret); | 4713 | mlog_errno(ret); |
4581 | goto out; | 4714 | goto out; |
@@ -4706,7 +4839,7 @@ static int ocfs2_truncate_rec(struct inode *inode, handle_t *handle, | |||
4706 | 4839 | ||
4707 | ocfs2_journal_dirty(handle, path_leaf_bh(path)); | 4840 | ocfs2_journal_dirty(handle, path_leaf_bh(path)); |
4708 | 4841 | ||
4709 | ret = ocfs2_rotate_tree_left(inode, handle, path, dealloc); | 4842 | ret = ocfs2_rotate_tree_left(inode, handle, path, dealloc, et); |
4710 | if (ret) { | 4843 | if (ret) { |
4711 | mlog_errno(ret); | 4844 | mlog_errno(ret); |
4712 | goto out; | 4845 | goto out; |
@@ -4717,20 +4850,29 @@ out: | |||
4717 | return ret; | 4850 | return ret; |
4718 | } | 4851 | } |
4719 | 4852 | ||
4720 | int ocfs2_remove_extent(struct inode *inode, struct buffer_head *di_bh, | 4853 | int ocfs2_remove_extent(struct inode *inode, struct buffer_head *root_bh, |
4721 | u32 cpos, u32 len, handle_t *handle, | 4854 | u32 cpos, u32 len, handle_t *handle, |
4722 | struct ocfs2_alloc_context *meta_ac, | 4855 | struct ocfs2_alloc_context *meta_ac, |
4723 | struct ocfs2_cached_dealloc_ctxt *dealloc) | 4856 | struct ocfs2_cached_dealloc_ctxt *dealloc, |
4857 | enum ocfs2_extent_tree_type et_type) | ||
4724 | { | 4858 | { |
4725 | int ret, index; | 4859 | int ret, index; |
4726 | u32 rec_range, trunc_range; | 4860 | u32 rec_range, trunc_range; |
4727 | struct ocfs2_extent_rec *rec; | 4861 | struct ocfs2_extent_rec *rec; |
4728 | struct ocfs2_extent_list *el; | 4862 | struct ocfs2_extent_list *el; |
4729 | struct ocfs2_path *path; | 4863 | struct ocfs2_path *path = NULL; |
4864 | struct ocfs2_extent_tree *et = NULL; | ||
4865 | |||
4866 | et = ocfs2_new_extent_tree(root_bh, et_type); | ||
4867 | if (!et) { | ||
4868 | ret = -ENOMEM; | ||
4869 | mlog_errno(ret); | ||
4870 | goto out; | ||
4871 | } | ||
4730 | 4872 | ||
4731 | ocfs2_extent_map_trunc(inode, 0); | 4873 | ocfs2_extent_map_trunc(inode, 0); |
4732 | 4874 | ||
4733 | path = ocfs2_new_inode_path(di_bh); | 4875 | path = ocfs2_new_path(et->root_bh, et->root_el); |
4734 | if (!path) { | 4876 | if (!path) { |
4735 | ret = -ENOMEM; | 4877 | ret = -ENOMEM; |
4736 | mlog_errno(ret); | 4878 | mlog_errno(ret); |
@@ -4783,13 +4925,13 @@ int ocfs2_remove_extent(struct inode *inode, struct buffer_head *di_bh, | |||
4783 | 4925 | ||
4784 | if (le32_to_cpu(rec->e_cpos) == cpos || rec_range == trunc_range) { | 4926 | if (le32_to_cpu(rec->e_cpos) == cpos || rec_range == trunc_range) { |
4785 | ret = ocfs2_truncate_rec(inode, handle, path, index, dealloc, | 4927 | ret = ocfs2_truncate_rec(inode, handle, path, index, dealloc, |
4786 | cpos, len); | 4928 | cpos, len, et); |
4787 | if (ret) { | 4929 | if (ret) { |
4788 | mlog_errno(ret); | 4930 | mlog_errno(ret); |
4789 | goto out; | 4931 | goto out; |
4790 | } | 4932 | } |
4791 | } else { | 4933 | } else { |
4792 | ret = ocfs2_split_tree(inode, di_bh, handle, path, index, | 4934 | ret = ocfs2_split_tree(inode, et, handle, path, index, |
4793 | trunc_range, meta_ac); | 4935 | trunc_range, meta_ac); |
4794 | if (ret) { | 4936 | if (ret) { |
4795 | mlog_errno(ret); | 4937 | mlog_errno(ret); |
@@ -4838,7 +4980,7 @@ int ocfs2_remove_extent(struct inode *inode, struct buffer_head *di_bh, | |||
4838 | } | 4980 | } |
4839 | 4981 | ||
4840 | ret = ocfs2_truncate_rec(inode, handle, path, index, dealloc, | 4982 | ret = ocfs2_truncate_rec(inode, handle, path, index, dealloc, |
4841 | cpos, len); | 4983 | cpos, len, et); |
4842 | if (ret) { | 4984 | if (ret) { |
4843 | mlog_errno(ret); | 4985 | mlog_errno(ret); |
4844 | goto out; | 4986 | goto out; |
@@ -4847,6 +4989,8 @@ int ocfs2_remove_extent(struct inode *inode, struct buffer_head *di_bh, | |||
4847 | 4989 | ||
4848 | out: | 4990 | out: |
4849 | ocfs2_free_path(path); | 4991 | ocfs2_free_path(path); |
4992 | if (et) | ||
4993 | ocfs2_free_extent_tree(et); | ||
4850 | return ret; | 4994 | return ret; |
4851 | } | 4995 | } |
4852 | 4996 | ||
@@ -6355,7 +6499,8 @@ int ocfs2_convert_inline_data_to_extents(struct inode *inode, | |||
6355 | * the in-inode data from our pages. | 6499 | * the in-inode data from our pages. |
6356 | */ | 6500 | */ |
6357 | ret = ocfs2_insert_extent(osb, handle, inode, di_bh, | 6501 | ret = ocfs2_insert_extent(osb, handle, inode, di_bh, |
6358 | 0, block, 1, 0, NULL); | 6502 | 0, block, 1, 0, |
6503 | NULL, OCFS2_DINODE_EXTENT); | ||
6359 | if (ret) { | 6504 | if (ret) { |
6360 | mlog_errno(ret); | 6505 | mlog_errno(ret); |
6361 | goto out_commit; | 6506 | goto out_commit; |
@@ -6397,13 +6542,14 @@ int ocfs2_commit_truncate(struct ocfs2_super *osb, | |||
6397 | handle_t *handle = NULL; | 6542 | handle_t *handle = NULL; |
6398 | struct inode *tl_inode = osb->osb_tl_inode; | 6543 | struct inode *tl_inode = osb->osb_tl_inode; |
6399 | struct ocfs2_path *path = NULL; | 6544 | struct ocfs2_path *path = NULL; |
6545 | struct ocfs2_dinode *di = (struct ocfs2_dinode *)fe_bh->b_data; | ||
6400 | 6546 | ||
6401 | mlog_entry_void(); | 6547 | mlog_entry_void(); |
6402 | 6548 | ||
6403 | new_highest_cpos = ocfs2_clusters_for_bytes(osb->sb, | 6549 | new_highest_cpos = ocfs2_clusters_for_bytes(osb->sb, |
6404 | i_size_read(inode)); | 6550 | i_size_read(inode)); |
6405 | 6551 | ||
6406 | path = ocfs2_new_inode_path(fe_bh); | 6552 | path = ocfs2_new_path(fe_bh, &di->id2.i_list); |
6407 | if (!path) { | 6553 | if (!path) { |
6408 | status = -ENOMEM; | 6554 | status = -ENOMEM; |
6409 | mlog_errno(status); | 6555 | mlog_errno(status); |
diff --git a/fs/ocfs2/alloc.h b/fs/ocfs2/alloc.h index a0e334f10cd1..473c8bcc62fb 100644 --- a/fs/ocfs2/alloc.h +++ b/fs/ocfs2/alloc.h | |||
@@ -26,28 +26,37 @@ | |||
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 | }; | ||
32 | |||
29 | struct ocfs2_alloc_context; | 33 | struct ocfs2_alloc_context; |
30 | int ocfs2_insert_extent(struct ocfs2_super *osb, | 34 | int ocfs2_insert_extent(struct ocfs2_super *osb, |
31 | handle_t *handle, | 35 | handle_t *handle, |
32 | struct inode *inode, | 36 | struct inode *inode, |
33 | struct buffer_head *fe_bh, | 37 | struct buffer_head *root_bh, |
34 | u32 cpos, | 38 | u32 cpos, |
35 | u64 start_blk, | 39 | u64 start_blk, |
36 | u32 new_clusters, | 40 | u32 new_clusters, |
37 | u8 flags, | 41 | u8 flags, |
38 | struct ocfs2_alloc_context *meta_ac); | 42 | struct ocfs2_alloc_context *meta_ac, |
43 | enum ocfs2_extent_tree_type et_type); | ||
39 | struct ocfs2_cached_dealloc_ctxt; | 44 | struct ocfs2_cached_dealloc_ctxt; |
40 | int ocfs2_mark_extent_written(struct inode *inode, struct buffer_head *di_bh, | 45 | int ocfs2_mark_extent_written(struct inode *inode, struct buffer_head *root_bh, |
41 | handle_t *handle, u32 cpos, u32 len, u32 phys, | 46 | handle_t *handle, u32 cpos, u32 len, u32 phys, |
42 | struct ocfs2_alloc_context *meta_ac, | 47 | struct ocfs2_alloc_context *meta_ac, |
43 | struct ocfs2_cached_dealloc_ctxt *dealloc); | 48 | struct ocfs2_cached_dealloc_ctxt *dealloc, |
44 | int ocfs2_remove_extent(struct inode *inode, struct buffer_head *di_bh, | 49 | enum ocfs2_extent_tree_type et_type); |
50 | int ocfs2_remove_extent(struct inode *inode, struct buffer_head *root_bh, | ||
45 | u32 cpos, u32 len, handle_t *handle, | 51 | u32 cpos, u32 len, handle_t *handle, |
46 | struct ocfs2_alloc_context *meta_ac, | 52 | struct ocfs2_alloc_context *meta_ac, |
47 | struct ocfs2_cached_dealloc_ctxt *dealloc); | 53 | struct ocfs2_cached_dealloc_ctxt *dealloc, |
54 | enum ocfs2_extent_tree_type et_type); | ||
48 | int ocfs2_num_free_extents(struct ocfs2_super *osb, | 55 | int ocfs2_num_free_extents(struct ocfs2_super *osb, |
49 | struct inode *inode, | 56 | struct inode *inode, |
50 | struct buffer_head *bh); | 57 | struct buffer_head *root_bh, |
58 | enum ocfs2_extent_tree_type et_type); | ||
59 | |||
51 | /* | 60 | /* |
52 | * how many new metadata chunks would an allocation need at maximum? | 61 | * how many new metadata chunks would an allocation need at maximum? |
53 | * | 62 | * |
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c index bbe3f8b2d0e2..44ea5eb3fdc4 100644 --- a/fs/ocfs2/aops.c +++ b/fs/ocfs2/aops.c | |||
@@ -1278,7 +1278,8 @@ static int ocfs2_write_cluster(struct address_space *mapping, | |||
1278 | } else if (unwritten) { | 1278 | } else if (unwritten) { |
1279 | ret = ocfs2_mark_extent_written(inode, wc->w_di_bh, | 1279 | ret = ocfs2_mark_extent_written(inode, wc->w_di_bh, |
1280 | wc->w_handle, cpos, 1, phys, | 1280 | wc->w_handle, cpos, 1, phys, |
1281 | meta_ac, &wc->w_dealloc); | 1281 | meta_ac, &wc->w_dealloc, |
1282 | OCFS2_DINODE_EXTENT); | ||
1282 | if (ret < 0) { | 1283 | if (ret < 0) { |
1283 | mlog_errno(ret); | 1284 | mlog_errno(ret); |
1284 | goto out; | 1285 | goto out; |
@@ -1712,7 +1713,13 @@ int ocfs2_write_begin_nolock(struct address_space *mapping, | |||
1712 | * ocfs2_lock_allocators(). It greatly over-estimates | 1713 | * ocfs2_lock_allocators(). It greatly over-estimates |
1713 | * the work to be done. | 1714 | * the work to be done. |
1714 | */ | 1715 | */ |
1715 | ret = ocfs2_lock_allocators(inode, wc->w_di_bh, | 1716 | mlog(0, "extend inode %llu, i_size = %lld, di->i_clusters = %u," |
1717 | " clusters_to_add = %u, extents_to_split = %u\n", | ||
1718 | (unsigned long long)OCFS2_I(inode)->ip_blkno, | ||
1719 | (long long)i_size_read(inode), le32_to_cpu(di->i_clusters), | ||
1720 | clusters_to_alloc, extents_to_split); | ||
1721 | |||
1722 | ret = ocfs2_lock_allocators(inode, wc->w_di_bh, &di->id2.i_list, | ||
1716 | clusters_to_alloc, extents_to_split, | 1723 | clusters_to_alloc, extents_to_split, |
1717 | &data_ac, &meta_ac); | 1724 | &data_ac, &meta_ac); |
1718 | if (ret) { | 1725 | if (ret) { |
diff --git a/fs/ocfs2/dir.c b/fs/ocfs2/dir.c index 126aa219c0c1..ba0fb9e16264 100644 --- a/fs/ocfs2/dir.c +++ b/fs/ocfs2/dir.c | |||
@@ -1306,7 +1306,7 @@ static int ocfs2_expand_inline_dir(struct inode *dir, struct buffer_head *di_bh, | |||
1306 | * related blocks have been journaled already. | 1306 | * related blocks have been journaled already. |
1307 | */ | 1307 | */ |
1308 | ret = ocfs2_insert_extent(osb, handle, dir, di_bh, 0, blkno, len, 0, | 1308 | ret = ocfs2_insert_extent(osb, handle, dir, di_bh, 0, blkno, len, 0, |
1309 | NULL); | 1309 | NULL, OCFS2_DINODE_EXTENT); |
1310 | if (ret) { | 1310 | if (ret) { |
1311 | mlog_errno(ret); | 1311 | mlog_errno(ret); |
1312 | goto out_commit; | 1312 | goto out_commit; |
@@ -1338,7 +1338,7 @@ static int ocfs2_expand_inline_dir(struct inode *dir, struct buffer_head *di_bh, | |||
1338 | blkno = ocfs2_clusters_to_blocks(dir->i_sb, bit_off); | 1338 | blkno = ocfs2_clusters_to_blocks(dir->i_sb, bit_off); |
1339 | 1339 | ||
1340 | ret = ocfs2_insert_extent(osb, handle, dir, di_bh, 1, blkno, | 1340 | ret = ocfs2_insert_extent(osb, handle, dir, di_bh, 1, blkno, |
1341 | len, 0, NULL); | 1341 | len, 0, NULL, OCFS2_DINODE_EXTENT); |
1342 | if (ret) { | 1342 | if (ret) { |
1343 | mlog_errno(ret); | 1343 | mlog_errno(ret); |
1344 | goto out_commit; | 1344 | goto out_commit; |
@@ -1481,7 +1481,8 @@ static int ocfs2_extend_dir(struct ocfs2_super *osb, | |||
1481 | if (dir_i_size == ocfs2_clusters_to_bytes(sb, OCFS2_I(dir)->ip_clusters)) { | 1481 | if (dir_i_size == ocfs2_clusters_to_bytes(sb, OCFS2_I(dir)->ip_clusters)) { |
1482 | spin_unlock(&OCFS2_I(dir)->ip_lock); | 1482 | spin_unlock(&OCFS2_I(dir)->ip_lock); |
1483 | num_free_extents = ocfs2_num_free_extents(osb, dir, | 1483 | num_free_extents = ocfs2_num_free_extents(osb, dir, |
1484 | parent_fe_bh); | 1484 | parent_fe_bh, |
1485 | OCFS2_DINODE_EXTENT); | ||
1485 | if (num_free_extents < 0) { | 1486 | if (num_free_extents < 0) { |
1486 | status = num_free_extents; | 1487 | status = num_free_extents; |
1487 | mlog_errno(status); | 1488 | mlog_errno(status); |
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index a31bba6c5575..f567cc53d9bc 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c | |||
@@ -521,7 +521,8 @@ int ocfs2_do_extend_allocation(struct ocfs2_super *osb, | |||
521 | if (mark_unwritten) | 521 | if (mark_unwritten) |
522 | flags = OCFS2_EXT_UNWRITTEN; | 522 | flags = OCFS2_EXT_UNWRITTEN; |
523 | 523 | ||
524 | free_extents = ocfs2_num_free_extents(osb, inode, fe_bh); | 524 | free_extents = ocfs2_num_free_extents(osb, inode, fe_bh, |
525 | OCFS2_DINODE_EXTENT); | ||
525 | if (free_extents < 0) { | 526 | if (free_extents < 0) { |
526 | status = free_extents; | 527 | status = free_extents; |
527 | mlog_errno(status); | 528 | mlog_errno(status); |
@@ -570,7 +571,7 @@ int ocfs2_do_extend_allocation(struct ocfs2_super *osb, | |||
570 | num_bits, bit_off, (unsigned long long)OCFS2_I(inode)->ip_blkno); | 571 | num_bits, bit_off, (unsigned long long)OCFS2_I(inode)->ip_blkno); |
571 | status = ocfs2_insert_extent(osb, handle, inode, fe_bh, | 572 | status = ocfs2_insert_extent(osb, handle, inode, fe_bh, |
572 | *logical_offset, block, num_bits, | 573 | *logical_offset, block, num_bits, |
573 | flags, meta_ac); | 574 | flags, meta_ac, OCFS2_DINODE_EXTENT); |
574 | if (status < 0) { | 575 | if (status < 0) { |
575 | mlog_errno(status); | 576 | mlog_errno(status); |
576 | goto leave; | 577 | goto leave; |
@@ -599,92 +600,6 @@ leave: | |||
599 | return status; | 600 | return status; |
600 | } | 601 | } |
601 | 602 | ||
602 | /* | ||
603 | * For a given allocation, determine which allocators will need to be | ||
604 | * accessed, and lock them, reserving the appropriate number of bits. | ||
605 | * | ||
606 | * Sparse file systems call this from ocfs2_write_begin_nolock() | ||
607 | * and ocfs2_allocate_unwritten_extents(). | ||
608 | * | ||
609 | * File systems which don't support holes call this from | ||
610 | * ocfs2_extend_allocation(). | ||
611 | */ | ||
612 | int ocfs2_lock_allocators(struct inode *inode, struct buffer_head *di_bh, | ||
613 | u32 clusters_to_add, u32 extents_to_split, | ||
614 | struct ocfs2_alloc_context **data_ac, | ||
615 | struct ocfs2_alloc_context **meta_ac) | ||
616 | { | ||
617 | int ret = 0, num_free_extents; | ||
618 | unsigned int max_recs_needed = clusters_to_add + 2 * extents_to_split; | ||
619 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | ||
620 | struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data; | ||
621 | |||
622 | *meta_ac = NULL; | ||
623 | if (data_ac) | ||
624 | *data_ac = NULL; | ||
625 | |||
626 | BUG_ON(clusters_to_add != 0 && data_ac == NULL); | ||
627 | |||
628 | mlog(0, "extend inode %llu, i_size = %lld, di->i_clusters = %u, " | ||
629 | "clusters_to_add = %u, extents_to_split = %u\n", | ||
630 | (unsigned long long)OCFS2_I(inode)->ip_blkno, (long long)i_size_read(inode), | ||
631 | le32_to_cpu(di->i_clusters), clusters_to_add, extents_to_split); | ||
632 | |||
633 | num_free_extents = ocfs2_num_free_extents(osb, inode, di_bh); | ||
634 | if (num_free_extents < 0) { | ||
635 | ret = num_free_extents; | ||
636 | mlog_errno(ret); | ||
637 | goto out; | ||
638 | } | ||
639 | |||
640 | /* | ||
641 | * Sparse allocation file systems need to be more conservative | ||
642 | * with reserving room for expansion - the actual allocation | ||
643 | * happens while we've got a journal handle open so re-taking | ||
644 | * a cluster lock (because we ran out of room for another | ||
645 | * extent) will violate ordering rules. | ||
646 | * | ||
647 | * Most of the time we'll only be seeing this 1 cluster at a time | ||
648 | * anyway. | ||
649 | * | ||
650 | * Always lock for any unwritten extents - we might want to | ||
651 | * add blocks during a split. | ||
652 | */ | ||
653 | if (!num_free_extents || | ||
654 | (ocfs2_sparse_alloc(osb) && num_free_extents < max_recs_needed)) { | ||
655 | ret = ocfs2_reserve_new_metadata(osb, &di->id2.i_list, meta_ac); | ||
656 | if (ret < 0) { | ||
657 | if (ret != -ENOSPC) | ||
658 | mlog_errno(ret); | ||
659 | goto out; | ||
660 | } | ||
661 | } | ||
662 | |||
663 | if (clusters_to_add == 0) | ||
664 | goto out; | ||
665 | |||
666 | ret = ocfs2_reserve_clusters(osb, clusters_to_add, data_ac); | ||
667 | if (ret < 0) { | ||
668 | if (ret != -ENOSPC) | ||
669 | mlog_errno(ret); | ||
670 | goto out; | ||
671 | } | ||
672 | |||
673 | out: | ||
674 | if (ret) { | ||
675 | if (*meta_ac) { | ||
676 | ocfs2_free_alloc_context(*meta_ac); | ||
677 | *meta_ac = NULL; | ||
678 | } | ||
679 | |||
680 | /* | ||
681 | * We cannot have an error and a non null *data_ac. | ||
682 | */ | ||
683 | } | ||
684 | |||
685 | return ret; | ||
686 | } | ||
687 | |||
688 | static int __ocfs2_extend_allocation(struct inode *inode, u32 logical_start, | 603 | static int __ocfs2_extend_allocation(struct inode *inode, u32 logical_start, |
689 | u32 clusters_to_add, int mark_unwritten) | 604 | u32 clusters_to_add, int mark_unwritten) |
690 | { | 605 | { |
@@ -725,7 +640,13 @@ static int __ocfs2_extend_allocation(struct inode *inode, u32 logical_start, | |||
725 | restart_all: | 640 | restart_all: |
726 | BUG_ON(le32_to_cpu(fe->i_clusters) != OCFS2_I(inode)->ip_clusters); | 641 | BUG_ON(le32_to_cpu(fe->i_clusters) != OCFS2_I(inode)->ip_clusters); |
727 | 642 | ||
728 | status = ocfs2_lock_allocators(inode, bh, clusters_to_add, 0, &data_ac, | 643 | mlog(0, "extend inode %llu, i_size = %lld, di->i_clusters = %u, " |
644 | "clusters_to_add = %u\n", | ||
645 | (unsigned long long)OCFS2_I(inode)->ip_blkno, | ||
646 | (long long)i_size_read(inode), le32_to_cpu(fe->i_clusters), | ||
647 | clusters_to_add); | ||
648 | status = ocfs2_lock_allocators(inode, bh, &fe->id2.i_list, | ||
649 | clusters_to_add, 0, &data_ac, | ||
729 | &meta_ac); | 650 | &meta_ac); |
730 | if (status) { | 651 | if (status) { |
731 | mlog_errno(status); | 652 | mlog_errno(status); |
@@ -1397,7 +1318,8 @@ static int __ocfs2_remove_inode_range(struct inode *inode, | |||
1397 | struct ocfs2_alloc_context *meta_ac = NULL; | 1318 | struct ocfs2_alloc_context *meta_ac = NULL; |
1398 | struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data; | 1319 | struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data; |
1399 | 1320 | ||
1400 | ret = ocfs2_lock_allocators(inode, di_bh, 0, 1, NULL, &meta_ac); | 1321 | ret = ocfs2_lock_allocators(inode, di_bh, &di->id2.i_list, |
1322 | 0, 1, NULL, &meta_ac); | ||
1401 | if (ret) { | 1323 | if (ret) { |
1402 | mlog_errno(ret); | 1324 | mlog_errno(ret); |
1403 | return ret; | 1325 | return ret; |
@@ -1428,7 +1350,7 @@ static int __ocfs2_remove_inode_range(struct inode *inode, | |||
1428 | } | 1350 | } |
1429 | 1351 | ||
1430 | ret = ocfs2_remove_extent(inode, di_bh, cpos, len, handle, meta_ac, | 1352 | ret = ocfs2_remove_extent(inode, di_bh, cpos, len, handle, meta_ac, |
1431 | dealloc); | 1353 | dealloc, OCFS2_DINODE_EXTENT); |
1432 | if (ret) { | 1354 | if (ret) { |
1433 | mlog_errno(ret); | 1355 | mlog_errno(ret); |
1434 | goto out_commit; | 1356 | goto out_commit; |
diff --git a/fs/ocfs2/file.h b/fs/ocfs2/file.h index c96b8054fbe7..18e5c80cc737 100644 --- a/fs/ocfs2/file.h +++ b/fs/ocfs2/file.h | |||
@@ -57,10 +57,6 @@ int ocfs2_do_extend_allocation(struct ocfs2_super *osb, | |||
57 | enum ocfs2_alloc_restarted *reason_ret); | 57 | enum ocfs2_alloc_restarted *reason_ret); |
58 | int ocfs2_extend_no_holes(struct inode *inode, u64 new_i_size, | 58 | int ocfs2_extend_no_holes(struct inode *inode, u64 new_i_size, |
59 | u64 zero_to); | 59 | u64 zero_to); |
60 | int ocfs2_lock_allocators(struct inode *inode, struct buffer_head *fe, | ||
61 | u32 clusters_to_add, u32 extents_to_split, | ||
62 | struct ocfs2_alloc_context **data_ac, | ||
63 | struct ocfs2_alloc_context **meta_ac); | ||
64 | int ocfs2_setattr(struct dentry *dentry, struct iattr *attr); | 60 | int ocfs2_setattr(struct dentry *dentry, struct iattr *attr); |
65 | int ocfs2_getattr(struct vfsmount *mnt, struct dentry *dentry, | 61 | int ocfs2_getattr(struct vfsmount *mnt, struct dentry *dentry, |
66 | struct kstat *stat); | 62 | struct kstat *stat); |
diff --git a/fs/ocfs2/suballoc.c b/fs/ocfs2/suballoc.c index 2a817bca1ddb..b642c825fb7c 100644 --- a/fs/ocfs2/suballoc.c +++ b/fs/ocfs2/suballoc.c | |||
@@ -1894,3 +1894,85 @@ static inline void ocfs2_debug_suballoc_inode(struct ocfs2_dinode *fe) | |||
1894 | (unsigned long long)fe->id2.i_chain.cl_recs[i].c_blkno); | 1894 | (unsigned long long)fe->id2.i_chain.cl_recs[i].c_blkno); |
1895 | } | 1895 | } |
1896 | } | 1896 | } |
1897 | |||
1898 | /* | ||
1899 | * For a given allocation, determine which allocators will need to be | ||
1900 | * accessed, and lock them, reserving the appropriate number of bits. | ||
1901 | * | ||
1902 | * Sparse file systems call this from ocfs2_write_begin_nolock() | ||
1903 | * and ocfs2_allocate_unwritten_extents(). | ||
1904 | * | ||
1905 | * File systems which don't support holes call this from | ||
1906 | * ocfs2_extend_allocation(). | ||
1907 | */ | ||
1908 | int ocfs2_lock_allocators(struct inode *inode, struct buffer_head *root_bh, | ||
1909 | struct ocfs2_extent_list *root_el, | ||
1910 | u32 clusters_to_add, u32 extents_to_split, | ||
1911 | struct ocfs2_alloc_context **data_ac, | ||
1912 | struct ocfs2_alloc_context **meta_ac) | ||
1913 | { | ||
1914 | int ret = 0, num_free_extents; | ||
1915 | unsigned int max_recs_needed = clusters_to_add + 2 * extents_to_split; | ||
1916 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | ||
1917 | |||
1918 | *meta_ac = NULL; | ||
1919 | if (data_ac) | ||
1920 | *data_ac = NULL; | ||
1921 | |||
1922 | BUG_ON(clusters_to_add != 0 && data_ac == NULL); | ||
1923 | |||
1924 | num_free_extents = ocfs2_num_free_extents(osb, inode, root_bh, | ||
1925 | OCFS2_DINODE_EXTENT); | ||
1926 | if (num_free_extents < 0) { | ||
1927 | ret = num_free_extents; | ||
1928 | mlog_errno(ret); | ||
1929 | goto out; | ||
1930 | } | ||
1931 | |||
1932 | /* | ||
1933 | * Sparse allocation file systems need to be more conservative | ||
1934 | * with reserving room for expansion - the actual allocation | ||
1935 | * happens while we've got a journal handle open so re-taking | ||
1936 | * a cluster lock (because we ran out of room for another | ||
1937 | * extent) will violate ordering rules. | ||
1938 | * | ||
1939 | * Most of the time we'll only be seeing this 1 cluster at a time | ||
1940 | * anyway. | ||
1941 | * | ||
1942 | * Always lock for any unwritten extents - we might want to | ||
1943 | * add blocks during a split. | ||
1944 | */ | ||
1945 | if (!num_free_extents || | ||
1946 | (ocfs2_sparse_alloc(osb) && num_free_extents < max_recs_needed)) { | ||
1947 | ret = ocfs2_reserve_new_metadata(osb, root_el, meta_ac); | ||
1948 | if (ret < 0) { | ||
1949 | if (ret != -ENOSPC) | ||
1950 | mlog_errno(ret); | ||
1951 | goto out; | ||
1952 | } | ||
1953 | } | ||
1954 | |||
1955 | if (clusters_to_add == 0) | ||
1956 | goto out; | ||
1957 | |||
1958 | ret = ocfs2_reserve_clusters(osb, clusters_to_add, data_ac); | ||
1959 | if (ret < 0) { | ||
1960 | if (ret != -ENOSPC) | ||
1961 | mlog_errno(ret); | ||
1962 | goto out; | ||
1963 | } | ||
1964 | |||
1965 | out: | ||
1966 | if (ret) { | ||
1967 | if (*meta_ac) { | ||
1968 | ocfs2_free_alloc_context(*meta_ac); | ||
1969 | *meta_ac = NULL; | ||
1970 | } | ||
1971 | |||
1972 | /* | ||
1973 | * We cannot have an error and a non null *data_ac. | ||
1974 | */ | ||
1975 | } | ||
1976 | |||
1977 | return ret; | ||
1978 | } | ||
diff --git a/fs/ocfs2/suballoc.h b/fs/ocfs2/suballoc.h index 3f96c875bcf7..a3e531e62df2 100644 --- a/fs/ocfs2/suballoc.h +++ b/fs/ocfs2/suballoc.h | |||
@@ -162,4 +162,9 @@ u64 ocfs2_which_cluster_group(struct inode *inode, u32 cluster); | |||
162 | int ocfs2_check_group_descriptor(struct super_block *sb, | 162 | int ocfs2_check_group_descriptor(struct super_block *sb, |
163 | struct ocfs2_dinode *di, | 163 | struct ocfs2_dinode *di, |
164 | struct ocfs2_group_desc *gd); | 164 | struct ocfs2_group_desc *gd); |
165 | int ocfs2_lock_allocators(struct inode *inode, struct buffer_head *root_bh, | ||
166 | struct ocfs2_extent_list *root_el, | ||
167 | u32 clusters_to_add, u32 extents_to_split, | ||
168 | struct ocfs2_alloc_context **data_ac, | ||
169 | struct ocfs2_alloc_context **meta_ac); | ||
165 | #endif /* _CHAINALLOC_H_ */ | 170 | #endif /* _CHAINALLOC_H_ */ |