diff options
author | Tao Ma <tao.ma@oracle.com> | 2008-08-18 05:38:45 -0400 |
---|---|---|
committer | Mark Fasheh <mfasheh@suse.com> | 2008-10-13 16:57:59 -0400 |
commit | 0eb8d47e69a2211a36643b180f1843ef45f6017d (patch) | |
tree | 745a063238cbcf6af84644bd51d4bfcd592e06a1 /fs/ocfs2/alloc.c | |
parent | e7d4cb6bc19658646357eeff134645cd9bc3479f (diff) |
ocfs2: Make high level btree extend code generic
Factor out the non-inode specifics of ocfs2_do_extend_allocation() into a more generic
function, ocfs2_do_cluster_allocation(). ocfs2_do_extend_allocation calls
ocfs2_do_cluster_allocation() now, but the latter can be used for other
btree types as well.
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.c | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c index 579659bae6c5..cacfc118b71c 100644 --- a/fs/ocfs2/alloc.c +++ b/fs/ocfs2/alloc.c | |||
@@ -4293,6 +4293,116 @@ bail: | |||
4293 | return status; | 4293 | return status; |
4294 | } | 4294 | } |
4295 | 4295 | ||
4296 | /* | ||
4297 | * Allcate and add clusters into the extent b-tree. | ||
4298 | * The new clusters(clusters_to_add) will be inserted at logical_offset. | ||
4299 | * The extent b-tree's root is root_el and it should be in root_bh, and | ||
4300 | * it is not limited to the file storage. Any extent tree can use this | ||
4301 | * function if it implements the proper ocfs2_extent_tree. | ||
4302 | */ | ||
4303 | int ocfs2_add_clusters_in_btree(struct ocfs2_super *osb, | ||
4304 | struct inode *inode, | ||
4305 | u32 *logical_offset, | ||
4306 | u32 clusters_to_add, | ||
4307 | int mark_unwritten, | ||
4308 | struct buffer_head *root_bh, | ||
4309 | struct ocfs2_extent_list *root_el, | ||
4310 | handle_t *handle, | ||
4311 | struct ocfs2_alloc_context *data_ac, | ||
4312 | struct ocfs2_alloc_context *meta_ac, | ||
4313 | enum ocfs2_alloc_restarted *reason_ret, | ||
4314 | enum ocfs2_extent_tree_type type) | ||
4315 | { | ||
4316 | int status = 0; | ||
4317 | int free_extents; | ||
4318 | enum ocfs2_alloc_restarted reason = RESTART_NONE; | ||
4319 | u32 bit_off, num_bits; | ||
4320 | u64 block; | ||
4321 | u8 flags = 0; | ||
4322 | |||
4323 | BUG_ON(!clusters_to_add); | ||
4324 | |||
4325 | if (mark_unwritten) | ||
4326 | flags = OCFS2_EXT_UNWRITTEN; | ||
4327 | |||
4328 | free_extents = ocfs2_num_free_extents(osb, inode, root_bh, type); | ||
4329 | if (free_extents < 0) { | ||
4330 | status = free_extents; | ||
4331 | mlog_errno(status); | ||
4332 | goto leave; | ||
4333 | } | ||
4334 | |||
4335 | /* there are two cases which could cause us to EAGAIN in the | ||
4336 | * we-need-more-metadata case: | ||
4337 | * 1) we haven't reserved *any* | ||
4338 | * 2) we are so fragmented, we've needed to add metadata too | ||
4339 | * many times. */ | ||
4340 | if (!free_extents && !meta_ac) { | ||
4341 | mlog(0, "we haven't reserved any metadata!\n"); | ||
4342 | status = -EAGAIN; | ||
4343 | reason = RESTART_META; | ||
4344 | goto leave; | ||
4345 | } else if ((!free_extents) | ||
4346 | && (ocfs2_alloc_context_bits_left(meta_ac) | ||
4347 | < ocfs2_extend_meta_needed(root_el))) { | ||
4348 | mlog(0, "filesystem is really fragmented...\n"); | ||
4349 | status = -EAGAIN; | ||
4350 | reason = RESTART_META; | ||
4351 | goto leave; | ||
4352 | } | ||
4353 | |||
4354 | status = __ocfs2_claim_clusters(osb, handle, data_ac, 1, | ||
4355 | clusters_to_add, &bit_off, &num_bits); | ||
4356 | if (status < 0) { | ||
4357 | if (status != -ENOSPC) | ||
4358 | mlog_errno(status); | ||
4359 | goto leave; | ||
4360 | } | ||
4361 | |||
4362 | BUG_ON(num_bits > clusters_to_add); | ||
4363 | |||
4364 | /* reserve our write early -- insert_extent may update the inode */ | ||
4365 | status = ocfs2_journal_access(handle, inode, root_bh, | ||
4366 | OCFS2_JOURNAL_ACCESS_WRITE); | ||
4367 | if (status < 0) { | ||
4368 | mlog_errno(status); | ||
4369 | goto leave; | ||
4370 | } | ||
4371 | |||
4372 | block = ocfs2_clusters_to_blocks(osb->sb, bit_off); | ||
4373 | 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); | ||
4375 | status = ocfs2_insert_extent(osb, handle, inode, root_bh, | ||
4376 | *logical_offset, block, num_bits, | ||
4377 | flags, meta_ac, type); | ||
4378 | if (status < 0) { | ||
4379 | mlog_errno(status); | ||
4380 | goto leave; | ||
4381 | } | ||
4382 | |||
4383 | status = ocfs2_journal_dirty(handle, root_bh); | ||
4384 | if (status < 0) { | ||
4385 | mlog_errno(status); | ||
4386 | goto leave; | ||
4387 | } | ||
4388 | |||
4389 | clusters_to_add -= num_bits; | ||
4390 | *logical_offset += num_bits; | ||
4391 | |||
4392 | if (clusters_to_add) { | ||
4393 | mlog(0, "need to alloc once more, wanted = %u\n", | ||
4394 | clusters_to_add); | ||
4395 | status = -EAGAIN; | ||
4396 | reason = RESTART_TRANS; | ||
4397 | } | ||
4398 | |||
4399 | leave: | ||
4400 | mlog_exit(status); | ||
4401 | if (reason_ret) | ||
4402 | *reason_ret = reason; | ||
4403 | return status; | ||
4404 | } | ||
4405 | |||
4296 | static void ocfs2_make_right_split_rec(struct super_block *sb, | 4406 | static void ocfs2_make_right_split_rec(struct super_block *sb, |
4297 | struct ocfs2_extent_rec *split_rec, | 4407 | struct ocfs2_extent_rec *split_rec, |
4298 | u32 cpos, | 4408 | u32 cpos, |