aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/alloc.c
diff options
context:
space:
mode:
authorTao Ma <tao.ma@oracle.com>2008-08-18 05:38:48 -0400
committerMark Fasheh <mfasheh@suse.com>2008-10-13 19:57:01 -0400
commitf56654c435c06f2b2bd5751889b1a08a3add7d6c (patch)
treeb186d68aedc5dda7afe435f5a68c03937ae382ff /fs/ocfs2/alloc.c
parentac11c827192272eabb68b8f4cf844066461d9690 (diff)
ocfs2: Add extent tree operation for xattr value btrees
Add some thin wrappers around ocfs2_insert_extent() for each of the 3 different btree types, ocfs2_inode_insert_extent(), ocfs2_xattr_value_insert_extent() and ocfs2_xattr_tree_insert_extent(). The last is for the xattr index btree, which will be used in a followup patch. All the old callers in file.c etc will call ocfs2_dinode_insert_extent(), while the other two handle the xattr issue. And the init of extent tree are handled by these functions. When storing xattr value which is too large, we will allocate some clusters for it and here ocfs2_extent_list and ocfs2_extent_rec will also be used. In order to re-use the b-tree operation code, a new parameter named "private" is added into ocfs2_extent_tree and it is used to indicate the root of ocfs2_exent_list. The reason is that we can't deduce the root from the buffer_head now. It may be in an inode, an ocfs2_xattr_block or even worse, in any place in an ocfs2_xattr_bucket. Signed-off-by: Tao Ma <tao.ma@oracle.com> Signed-off-by: Mark Fasheh <mfasheh@suse.com>
Diffstat (limited to 'fs/ocfs2/alloc.c')
-rw-r--r--fs/ocfs2/alloc.c184
1 files changed, 149 insertions, 35 deletions
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c
index cacfc118b71c..e45421fee204 100644
--- a/fs/ocfs2/alloc.c
+++ b/fs/ocfs2/alloc.c
@@ -78,6 +78,7 @@ struct ocfs2_extent_tree {
78 struct ocfs2_extent_tree_operations *eops; 78 struct ocfs2_extent_tree_operations *eops;
79 struct buffer_head *root_bh; 79 struct buffer_head *root_bh;
80 struct ocfs2_extent_list *root_el; 80 struct ocfs2_extent_list *root_el;
81 void *private;
81}; 82};
82 83
83static void ocfs2_dinode_set_last_eb_blk(struct ocfs2_extent_tree *et, 84static void ocfs2_dinode_set_last_eb_blk(struct ocfs2_extent_tree *et,
@@ -136,9 +137,50 @@ static struct ocfs2_extent_tree_operations ocfs2_dinode_et_ops = {
136 .sanity_check = ocfs2_dinode_sanity_check, 137 .sanity_check = ocfs2_dinode_sanity_check,
137}; 138};
138 139
140static void ocfs2_xattr_value_set_last_eb_blk(struct ocfs2_extent_tree *et,
141 u64 blkno)
142{
143 struct ocfs2_xattr_value_root *xv =
144 (struct ocfs2_xattr_value_root *)et->private;
145
146 xv->xr_last_eb_blk = cpu_to_le64(blkno);
147}
148
149static u64 ocfs2_xattr_value_get_last_eb_blk(struct ocfs2_extent_tree *et)
150{
151 struct ocfs2_xattr_value_root *xv =
152 (struct ocfs2_xattr_value_root *) et->private;
153
154 return le64_to_cpu(xv->xr_last_eb_blk);
155}
156
157static void ocfs2_xattr_value_update_clusters(struct inode *inode,
158 struct ocfs2_extent_tree *et,
159 u32 clusters)
160{
161 struct ocfs2_xattr_value_root *xv =
162 (struct ocfs2_xattr_value_root *)et->private;
163
164 le32_add_cpu(&xv->xr_clusters, clusters);
165}
166
167static int ocfs2_xattr_value_sanity_check(struct inode *inode,
168 struct ocfs2_extent_tree *et)
169{
170 return 0;
171}
172
173static struct ocfs2_extent_tree_operations ocfs2_xattr_et_ops = {
174 .set_last_eb_blk = ocfs2_xattr_value_set_last_eb_blk,
175 .get_last_eb_blk = ocfs2_xattr_value_get_last_eb_blk,
176 .update_clusters = ocfs2_xattr_value_update_clusters,
177 .sanity_check = ocfs2_xattr_value_sanity_check,
178};
179
139static struct ocfs2_extent_tree* 180static struct ocfs2_extent_tree*
140 ocfs2_new_extent_tree(struct buffer_head *bh, 181 ocfs2_new_extent_tree(struct buffer_head *bh,
141 enum ocfs2_extent_tree_type et_type) 182 enum ocfs2_extent_tree_type et_type,
183 void *private)
142{ 184{
143 struct ocfs2_extent_tree *et; 185 struct ocfs2_extent_tree *et;
144 186
@@ -149,12 +191,16 @@ static struct ocfs2_extent_tree*
149 et->type = et_type; 191 et->type = et_type;
150 get_bh(bh); 192 get_bh(bh);
151 et->root_bh = bh; 193 et->root_bh = bh;
194 et->private = private;
152 195
153 /* current we only support dinode extent. */
154 BUG_ON(et->type != OCFS2_DINODE_EXTENT);
155 if (et_type == OCFS2_DINODE_EXTENT) { 196 if (et_type == OCFS2_DINODE_EXTENT) {
156 et->root_el = &((struct ocfs2_dinode *)bh->b_data)->id2.i_list; 197 et->root_el = &((struct ocfs2_dinode *)bh->b_data)->id2.i_list;
157 et->eops = &ocfs2_dinode_et_ops; 198 et->eops = &ocfs2_dinode_et_ops;
199 } else if (et_type == OCFS2_XATTR_VALUE_EXTENT) {
200 struct ocfs2_xattr_value_root *xv =
201 (struct ocfs2_xattr_value_root *) private;
202 et->root_el = &xv->xr_list;
203 et->eops = &ocfs2_xattr_et_ops;
158 } 204 }
159 205
160 return et; 206 return et;
@@ -495,7 +541,8 @@ struct ocfs2_merge_ctxt {
495int ocfs2_num_free_extents(struct ocfs2_super *osb, 541int ocfs2_num_free_extents(struct ocfs2_super *osb,
496 struct inode *inode, 542 struct inode *inode,
497 struct buffer_head *root_bh, 543 struct buffer_head *root_bh,
498 enum ocfs2_extent_tree_type type) 544 enum ocfs2_extent_tree_type type,
545 void *private)
499{ 546{
500 int retval; 547 int retval;
501 struct ocfs2_extent_list *el = NULL; 548 struct ocfs2_extent_list *el = NULL;
@@ -517,6 +564,12 @@ int ocfs2_num_free_extents(struct ocfs2_super *osb,
517 if (fe->i_last_eb_blk) 564 if (fe->i_last_eb_blk)
518 last_eb_blk = le64_to_cpu(fe->i_last_eb_blk); 565 last_eb_blk = le64_to_cpu(fe->i_last_eb_blk);
519 el = &fe->id2.i_list; 566 el = &fe->id2.i_list;
567 } else if (type == OCFS2_XATTR_VALUE_EXTENT) {
568 struct ocfs2_xattr_value_root *xv =
569 (struct ocfs2_xattr_value_root *) private;
570
571 last_eb_blk = le64_to_cpu(xv->xr_last_eb_blk);
572 el = &xv->xr_list;
520 } 573 }
521 574
522 if (last_eb_blk) { 575 if (last_eb_blk) {
@@ -4209,33 +4262,25 @@ out:
4209 * 4262 *
4210 * The caller needs to update fe->i_clusters 4263 * The caller needs to update fe->i_clusters
4211 */ 4264 */
4212int ocfs2_insert_extent(struct ocfs2_super *osb, 4265static int ocfs2_insert_extent(struct ocfs2_super *osb,
4213 handle_t *handle, 4266 handle_t *handle,
4214 struct inode *inode, 4267 struct inode *inode,
4215 struct buffer_head *root_bh, 4268 struct buffer_head *root_bh,
4216 u32 cpos, 4269 u32 cpos,
4217 u64 start_blk, 4270 u64 start_blk,
4218 u32 new_clusters, 4271 u32 new_clusters,
4219 u8 flags, 4272 u8 flags,
4220 struct ocfs2_alloc_context *meta_ac, 4273 struct ocfs2_alloc_context *meta_ac,
4221 enum ocfs2_extent_tree_type et_type) 4274 struct ocfs2_extent_tree *et)
4222{ 4275{
4223 int status; 4276 int status;
4224 int uninitialized_var(free_records); 4277 int uninitialized_var(free_records);
4225 struct buffer_head *last_eb_bh = NULL; 4278 struct buffer_head *last_eb_bh = NULL;
4226 struct ocfs2_insert_type insert = {0, }; 4279 struct ocfs2_insert_type insert = {0, };
4227 struct ocfs2_extent_rec rec; 4280 struct ocfs2_extent_rec rec;
4228 struct ocfs2_extent_tree *et = NULL;
4229 4281
4230 BUG_ON(OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL); 4282 BUG_ON(OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL);
4231 4283
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
4239 mlog(0, "add %u clusters at position %u to inode %llu\n", 4284 mlog(0, "add %u clusters at position %u to inode %llu\n",
4240 new_clusters, cpos, (unsigned long long)OCFS2_I(inode)->ip_blkno); 4285 new_clusters, cpos, (unsigned long long)OCFS2_I(inode)->ip_blkno);
4241 4286
@@ -4287,9 +4332,68 @@ bail:
4287 if (last_eb_bh) 4332 if (last_eb_bh)
4288 brelse(last_eb_bh); 4333 brelse(last_eb_bh);
4289 4334
4335 mlog_exit(status);
4336 return status;
4337}
4338
4339int ocfs2_dinode_insert_extent(struct ocfs2_super *osb,
4340 handle_t *handle,
4341 struct inode *inode,
4342 struct buffer_head *root_bh,
4343 u32 cpos,
4344 u64 start_blk,
4345 u32 new_clusters,
4346 u8 flags,
4347 struct ocfs2_alloc_context *meta_ac)
4348{
4349 int status;
4350 struct ocfs2_extent_tree *et = NULL;
4351
4352 et = ocfs2_new_extent_tree(root_bh, OCFS2_DINODE_EXTENT, NULL);
4353 if (!et) {
4354 status = -ENOMEM;
4355 mlog_errno(status);
4356 goto bail;
4357 }
4358
4359 status = ocfs2_insert_extent(osb, handle, inode, root_bh,
4360 cpos, start_blk, new_clusters,
4361 flags, meta_ac, et);
4362
4290 if (et) 4363 if (et)
4291 ocfs2_free_extent_tree(et); 4364 ocfs2_free_extent_tree(et);
4292 mlog_exit(status); 4365bail:
4366 return status;
4367}
4368
4369int ocfs2_xattr_value_insert_extent(struct ocfs2_super *osb,
4370 handle_t *handle,
4371 struct inode *inode,
4372 struct buffer_head *root_bh,
4373 u32 cpos,
4374 u64 start_blk,
4375 u32 new_clusters,
4376 u8 flags,
4377 struct ocfs2_alloc_context *meta_ac,
4378 void *private)
4379{
4380 int status;
4381 struct ocfs2_extent_tree *et = NULL;
4382
4383 et = ocfs2_new_extent_tree(root_bh, OCFS2_XATTR_VALUE_EXTENT, private);
4384 if (!et) {
4385 status = -ENOMEM;
4386 mlog_errno(status);
4387 goto bail;
4388 }
4389
4390 status = ocfs2_insert_extent(osb, handle, inode, root_bh,
4391 cpos, start_blk, new_clusters,
4392 flags, meta_ac, et);
4393
4394 if (et)
4395 ocfs2_free_extent_tree(et);
4396bail:
4293 return status; 4397 return status;
4294} 4398}
4295 4399
@@ -4311,7 +4415,8 @@ int ocfs2_add_clusters_in_btree(struct ocfs2_super *osb,
4311 struct ocfs2_alloc_context *data_ac, 4415 struct ocfs2_alloc_context *data_ac,
4312 struct ocfs2_alloc_context *meta_ac, 4416 struct ocfs2_alloc_context *meta_ac,
4313 enum ocfs2_alloc_restarted *reason_ret, 4417 enum ocfs2_alloc_restarted *reason_ret,
4314 enum ocfs2_extent_tree_type type) 4418 enum ocfs2_extent_tree_type type,
4419 void *private)
4315{ 4420{
4316 int status = 0; 4421 int status = 0;
4317 int free_extents; 4422 int free_extents;
@@ -4325,7 +4430,8 @@ int ocfs2_add_clusters_in_btree(struct ocfs2_super *osb,
4325 if (mark_unwritten) 4430 if (mark_unwritten)
4326 flags = OCFS2_EXT_UNWRITTEN; 4431 flags = OCFS2_EXT_UNWRITTEN;
4327 4432
4328 free_extents = ocfs2_num_free_extents(osb, inode, root_bh, type); 4433 free_extents = ocfs2_num_free_extents(osb, inode, root_bh, type,
4434 private);
4329 if (free_extents < 0) { 4435 if (free_extents < 0) {
4330 status = free_extents; 4436 status = free_extents;
4331 mlog_errno(status); 4437 mlog_errno(status);
@@ -4372,9 +4478,16 @@ int ocfs2_add_clusters_in_btree(struct ocfs2_super *osb,
4372 block = ocfs2_clusters_to_blocks(osb->sb, bit_off); 4478 block = ocfs2_clusters_to_blocks(osb->sb, bit_off);
4373 mlog(0, "Allocating %u clusters at block %u for inode %llu\n", 4479 mlog(0, "Allocating %u clusters at block %u for inode %llu\n",
4374 num_bits, bit_off, (unsigned long long)OCFS2_I(inode)->ip_blkno); 4480 num_bits, bit_off, (unsigned long long)OCFS2_I(inode)->ip_blkno);
4375 status = ocfs2_insert_extent(osb, handle, inode, root_bh, 4481 if (type == OCFS2_DINODE_EXTENT)
4376 *logical_offset, block, num_bits, 4482 status = ocfs2_dinode_insert_extent(osb, handle, inode, root_bh,
4377 flags, meta_ac, type); 4483 *logical_offset, block,
4484 num_bits, flags, meta_ac);
4485 else
4486 status = ocfs2_xattr_value_insert_extent(osb, handle,
4487 inode, root_bh,
4488 *logical_offset,
4489 block, num_bits, flags,
4490 meta_ac, private);
4378 if (status < 0) { 4491 if (status < 0) {
4379 mlog_errno(status); 4492 mlog_errno(status);
4380 goto leave; 4493 goto leave;
@@ -4655,7 +4768,8 @@ int ocfs2_mark_extent_written(struct inode *inode, struct buffer_head *root_bh,
4655 handle_t *handle, u32 cpos, u32 len, u32 phys, 4768 handle_t *handle, u32 cpos, u32 len, u32 phys,
4656 struct ocfs2_alloc_context *meta_ac, 4769 struct ocfs2_alloc_context *meta_ac,
4657 struct ocfs2_cached_dealloc_ctxt *dealloc, 4770 struct ocfs2_cached_dealloc_ctxt *dealloc,
4658 enum ocfs2_extent_tree_type et_type) 4771 enum ocfs2_extent_tree_type et_type,
4772 void *private)
4659{ 4773{
4660 int ret, index; 4774 int ret, index;
4661 u64 start_blkno = ocfs2_clusters_to_blocks(inode->i_sb, phys); 4775 u64 start_blkno = ocfs2_clusters_to_blocks(inode->i_sb, phys);
@@ -4676,7 +4790,7 @@ int ocfs2_mark_extent_written(struct inode *inode, struct buffer_head *root_bh,
4676 goto out; 4790 goto out;
4677 } 4791 }
4678 4792
4679 et = ocfs2_new_extent_tree(root_bh, et_type); 4793 et = ocfs2_new_extent_tree(root_bh, et_type, private);
4680 if (!et) { 4794 if (!et) {
4681 ret = -ENOMEM; 4795 ret = -ENOMEM;
4682 mlog_errno(ret); 4796 mlog_errno(ret);
@@ -4964,7 +5078,8 @@ int ocfs2_remove_extent(struct inode *inode, struct buffer_head *root_bh,
4964 u32 cpos, u32 len, handle_t *handle, 5078 u32 cpos, u32 len, handle_t *handle,
4965 struct ocfs2_alloc_context *meta_ac, 5079 struct ocfs2_alloc_context *meta_ac,
4966 struct ocfs2_cached_dealloc_ctxt *dealloc, 5080 struct ocfs2_cached_dealloc_ctxt *dealloc,
4967 enum ocfs2_extent_tree_type et_type) 5081 enum ocfs2_extent_tree_type et_type,
5082 void *private)
4968{ 5083{
4969 int ret, index; 5084 int ret, index;
4970 u32 rec_range, trunc_range; 5085 u32 rec_range, trunc_range;
@@ -4973,7 +5088,7 @@ int ocfs2_remove_extent(struct inode *inode, struct buffer_head *root_bh,
4973 struct ocfs2_path *path = NULL; 5088 struct ocfs2_path *path = NULL;
4974 struct ocfs2_extent_tree *et = NULL; 5089 struct ocfs2_extent_tree *et = NULL;
4975 5090
4976 et = ocfs2_new_extent_tree(root_bh, et_type); 5091 et = ocfs2_new_extent_tree(root_bh, et_type, private);
4977 if (!et) { 5092 if (!et) {
4978 ret = -ENOMEM; 5093 ret = -ENOMEM;
4979 mlog_errno(ret); 5094 mlog_errno(ret);
@@ -6608,9 +6723,8 @@ int ocfs2_convert_inline_data_to_extents(struct inode *inode,
6608 * this proves to be false, we could always re-build 6723 * this proves to be false, we could always re-build
6609 * the in-inode data from our pages. 6724 * the in-inode data from our pages.
6610 */ 6725 */
6611 ret = ocfs2_insert_extent(osb, handle, inode, di_bh, 6726 ret = ocfs2_dinode_insert_extent(osb, handle, inode, di_bh,
6612 0, block, 1, 0, 6727 0, block, 1, 0, NULL);
6613 NULL, OCFS2_DINODE_EXTENT);
6614 if (ret) { 6728 if (ret) {
6615 mlog_errno(ret); 6729 mlog_errno(ret);
6616 goto out_commit; 6730 goto out_commit;