aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/file.c
diff options
context:
space:
mode:
authorTao Ma <tao.ma@oracle.com>2008-08-18 05:38:45 -0400
committerMark Fasheh <mfasheh@suse.com>2008-10-13 16:57:59 -0400
commit0eb8d47e69a2211a36643b180f1843ef45f6017d (patch)
tree745a063238cbcf6af84644bd51d4bfcd592e06a1 /fs/ocfs2/file.c
parente7d4cb6bc19658646357eeff134645cd9bc3479f (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/file.c')
-rw-r--r--fs/ocfs2/file.c136
1 files changed, 27 insertions, 109 deletions
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c
index f567cc53d9bc..7bb4fde70054 100644
--- a/fs/ocfs2/file.c
+++ b/fs/ocfs2/file.c
@@ -488,7 +488,7 @@ bail:
488} 488}
489 489
490/* 490/*
491 * extend allocation only here. 491 * extend file allocation only here.
492 * we'll update all the disk stuff, and oip->alloc_size 492 * we'll update all the disk stuff, and oip->alloc_size
493 * 493 *
494 * expect stuff to be locked, a transaction started and enough data / 494 * expect stuff to be locked, a transaction started and enough data /
@@ -497,107 +497,25 @@ bail:
497 * Will return -EAGAIN, and a reason if a restart is needed. 497 * Will return -EAGAIN, and a reason if a restart is needed.
498 * If passed in, *reason will always be set, even in error. 498 * If passed in, *reason will always be set, even in error.
499 */ 499 */
500int ocfs2_do_extend_allocation(struct ocfs2_super *osb, 500int ocfs2_add_inode_data(struct ocfs2_super *osb,
501 struct inode *inode, 501 struct inode *inode,
502 u32 *logical_offset, 502 u32 *logical_offset,
503 u32 clusters_to_add, 503 u32 clusters_to_add,
504 int mark_unwritten, 504 int mark_unwritten,
505 struct buffer_head *fe_bh, 505 struct buffer_head *fe_bh,
506 handle_t *handle, 506 handle_t *handle,
507 struct ocfs2_alloc_context *data_ac, 507 struct ocfs2_alloc_context *data_ac,
508 struct ocfs2_alloc_context *meta_ac, 508 struct ocfs2_alloc_context *meta_ac,
509 enum ocfs2_alloc_restarted *reason_ret) 509 enum ocfs2_alloc_restarted *reason_ret)
510{ 510{
511 int status = 0;
512 int free_extents;
513 struct ocfs2_dinode *fe = (struct ocfs2_dinode *) fe_bh->b_data; 511 struct ocfs2_dinode *fe = (struct ocfs2_dinode *) fe_bh->b_data;
514 enum ocfs2_alloc_restarted reason = RESTART_NONE; 512 struct ocfs2_extent_list *el = &fe->id2.i_list;
515 u32 bit_off, num_bits;
516 u64 block;
517 u8 flags = 0;
518
519 BUG_ON(!clusters_to_add);
520
521 if (mark_unwritten)
522 flags = OCFS2_EXT_UNWRITTEN;
523
524 free_extents = ocfs2_num_free_extents(osb, inode, fe_bh,
525 OCFS2_DINODE_EXTENT);
526 if (free_extents < 0) {
527 status = free_extents;
528 mlog_errno(status);
529 goto leave;
530 }
531
532 /* there are two cases which could cause us to EAGAIN in the
533 * we-need-more-metadata case:
534 * 1) we haven't reserved *any*
535 * 2) we are so fragmented, we've needed to add metadata too
536 * many times. */
537 if (!free_extents && !meta_ac) {
538 mlog(0, "we haven't reserved any metadata!\n");
539 status = -EAGAIN;
540 reason = RESTART_META;
541 goto leave;
542 } else if ((!free_extents)
543 && (ocfs2_alloc_context_bits_left(meta_ac)
544 < ocfs2_extend_meta_needed(&fe->id2.i_list))) {
545 mlog(0, "filesystem is really fragmented...\n");
546 status = -EAGAIN;
547 reason = RESTART_META;
548 goto leave;
549 }
550 513
551 status = __ocfs2_claim_clusters(osb, handle, data_ac, 1, 514 return ocfs2_add_clusters_in_btree(osb, inode, logical_offset,
552 clusters_to_add, &bit_off, &num_bits); 515 clusters_to_add, mark_unwritten,
553 if (status < 0) { 516 fe_bh, el, handle,
554 if (status != -ENOSPC) 517 data_ac, meta_ac, reason_ret,
555 mlog_errno(status); 518 OCFS2_DINODE_EXTENT);
556 goto leave;
557 }
558
559 BUG_ON(num_bits > clusters_to_add);
560
561 /* reserve our write early -- insert_extent may update the inode */
562 status = ocfs2_journal_access(handle, inode, fe_bh,
563 OCFS2_JOURNAL_ACCESS_WRITE);
564 if (status < 0) {
565 mlog_errno(status);
566 goto leave;
567 }
568
569 block = ocfs2_clusters_to_blocks(osb->sb, bit_off);
570 mlog(0, "Allocating %u clusters at block %u for inode %llu\n",
571 num_bits, bit_off, (unsigned long long)OCFS2_I(inode)->ip_blkno);
572 status = ocfs2_insert_extent(osb, handle, inode, fe_bh,
573 *logical_offset, block, num_bits,
574 flags, meta_ac, OCFS2_DINODE_EXTENT);
575 if (status < 0) {
576 mlog_errno(status);
577 goto leave;
578 }
579
580 status = ocfs2_journal_dirty(handle, fe_bh);
581 if (status < 0) {
582 mlog_errno(status);
583 goto leave;
584 }
585
586 clusters_to_add -= num_bits;
587 *logical_offset += num_bits;
588
589 if (clusters_to_add) {
590 mlog(0, "need to alloc once more, clusters = %u, wanted = "
591 "%u\n", fe->i_clusters, clusters_to_add);
592 status = -EAGAIN;
593 reason = RESTART_TRANS;
594 }
595
596leave:
597 mlog_exit(status);
598 if (reason_ret)
599 *reason_ret = reason;
600 return status;
601} 519}
602 520
603static int __ocfs2_extend_allocation(struct inode *inode, u32 logical_start, 521static int __ocfs2_extend_allocation(struct inode *inode, u32 logical_start,
@@ -676,16 +594,16 @@ restarted_transaction:
676 594
677 prev_clusters = OCFS2_I(inode)->ip_clusters; 595 prev_clusters = OCFS2_I(inode)->ip_clusters;
678 596
679 status = ocfs2_do_extend_allocation(osb, 597 status = ocfs2_add_inode_data(osb,
680 inode, 598 inode,
681 &logical_start, 599 &logical_start,
682 clusters_to_add, 600 clusters_to_add,
683 mark_unwritten, 601 mark_unwritten,
684 bh, 602 bh,
685 handle, 603 handle,
686 data_ac, 604 data_ac,
687 meta_ac, 605 meta_ac,
688 &why); 606 &why);
689 if ((status < 0) && (status != -EAGAIN)) { 607 if ((status < 0) && (status != -EAGAIN)) {
690 if (status != -ENOSPC) 608 if (status != -ENOSPC)
691 mlog_errno(status); 609 mlog_errno(status);