diff options
Diffstat (limited to 'fs/ext3/balloc.c')
-rw-r--r-- | fs/ext3/balloc.c | 215 |
1 files changed, 112 insertions, 103 deletions
diff --git a/fs/ext3/balloc.c b/fs/ext3/balloc.c index 77927d6938f6..b1633cd28eca 100644 --- a/fs/ext3/balloc.c +++ b/fs/ext3/balloc.c | |||
@@ -163,10 +163,10 @@ restart: | |||
163 | #endif | 163 | #endif |
164 | 164 | ||
165 | static int | 165 | static int |
166 | goal_in_my_reservation(struct ext3_reserve_window *rsv, int goal, | 166 | goal_in_my_reservation(struct ext3_reserve_window *rsv, ext3_grpblk_t grp_goal, |
167 | unsigned int group, struct super_block * sb) | 167 | unsigned int group, struct super_block * sb) |
168 | { | 168 | { |
169 | unsigned long group_first_block, group_last_block; | 169 | ext3_fsblk_t group_first_block, group_last_block; |
170 | 170 | ||
171 | group_first_block = le32_to_cpu(EXT3_SB(sb)->s_es->s_first_data_block) + | 171 | group_first_block = le32_to_cpu(EXT3_SB(sb)->s_es->s_first_data_block) + |
172 | group * EXT3_BLOCKS_PER_GROUP(sb); | 172 | group * EXT3_BLOCKS_PER_GROUP(sb); |
@@ -175,8 +175,8 @@ goal_in_my_reservation(struct ext3_reserve_window *rsv, int goal, | |||
175 | if ((rsv->_rsv_start > group_last_block) || | 175 | if ((rsv->_rsv_start > group_last_block) || |
176 | (rsv->_rsv_end < group_first_block)) | 176 | (rsv->_rsv_end < group_first_block)) |
177 | return 0; | 177 | return 0; |
178 | if ((goal >= 0) && ((goal + group_first_block < rsv->_rsv_start) | 178 | if ((grp_goal >= 0) && ((grp_goal + group_first_block < rsv->_rsv_start) |
179 | || (goal + group_first_block > rsv->_rsv_end))) | 179 | || (grp_goal + group_first_block > rsv->_rsv_end))) |
180 | return 0; | 180 | return 0; |
181 | return 1; | 181 | return 1; |
182 | } | 182 | } |
@@ -187,7 +187,7 @@ goal_in_my_reservation(struct ext3_reserve_window *rsv, int goal, | |||
187 | * Returns NULL if there are no windows or if all windows start after the goal. | 187 | * Returns NULL if there are no windows or if all windows start after the goal. |
188 | */ | 188 | */ |
189 | static struct ext3_reserve_window_node * | 189 | static struct ext3_reserve_window_node * |
190 | search_reserve_window(struct rb_root *root, unsigned long goal) | 190 | search_reserve_window(struct rb_root *root, ext3_fsblk_t goal) |
191 | { | 191 | { |
192 | struct rb_node *n = root->rb_node; | 192 | struct rb_node *n = root->rb_node; |
193 | struct ext3_reserve_window_node *rsv; | 193 | struct ext3_reserve_window_node *rsv; |
@@ -223,7 +223,7 @@ void ext3_rsv_window_add(struct super_block *sb, | |||
223 | { | 223 | { |
224 | struct rb_root *root = &EXT3_SB(sb)->s_rsv_window_root; | 224 | struct rb_root *root = &EXT3_SB(sb)->s_rsv_window_root; |
225 | struct rb_node *node = &rsv->rsv_node; | 225 | struct rb_node *node = &rsv->rsv_node; |
226 | unsigned int start = rsv->rsv_start; | 226 | ext3_fsblk_t start = rsv->rsv_start; |
227 | 227 | ||
228 | struct rb_node ** p = &root->rb_node; | 228 | struct rb_node ** p = &root->rb_node; |
229 | struct rb_node * parent = NULL; | 229 | struct rb_node * parent = NULL; |
@@ -310,20 +310,20 @@ void ext3_discard_reservation(struct inode *inode) | |||
310 | 310 | ||
311 | /* Free given blocks, update quota and i_blocks field */ | 311 | /* Free given blocks, update quota and i_blocks field */ |
312 | void ext3_free_blocks_sb(handle_t *handle, struct super_block *sb, | 312 | void ext3_free_blocks_sb(handle_t *handle, struct super_block *sb, |
313 | unsigned long block, unsigned long count, | 313 | ext3_fsblk_t block, unsigned long count, |
314 | int *pdquot_freed_blocks) | 314 | unsigned long *pdquot_freed_blocks) |
315 | { | 315 | { |
316 | struct buffer_head *bitmap_bh = NULL; | 316 | struct buffer_head *bitmap_bh = NULL; |
317 | struct buffer_head *gd_bh; | 317 | struct buffer_head *gd_bh; |
318 | unsigned long block_group; | 318 | unsigned long block_group; |
319 | unsigned long bit; | 319 | ext3_grpblk_t bit; |
320 | unsigned long i; | 320 | unsigned long i; |
321 | unsigned long overflow; | 321 | unsigned long overflow; |
322 | struct ext3_group_desc * desc; | 322 | struct ext3_group_desc * desc; |
323 | struct ext3_super_block * es; | 323 | struct ext3_super_block * es; |
324 | struct ext3_sb_info *sbi; | 324 | struct ext3_sb_info *sbi; |
325 | int err = 0, ret; | 325 | int err = 0, ret; |
326 | unsigned group_freed; | 326 | ext3_grpblk_t group_freed; |
327 | 327 | ||
328 | *pdquot_freed_blocks = 0; | 328 | *pdquot_freed_blocks = 0; |
329 | sbi = EXT3_SB(sb); | 329 | sbi = EXT3_SB(sb); |
@@ -333,7 +333,7 @@ void ext3_free_blocks_sb(handle_t *handle, struct super_block *sb, | |||
333 | block + count > le32_to_cpu(es->s_blocks_count)) { | 333 | block + count > le32_to_cpu(es->s_blocks_count)) { |
334 | ext3_error (sb, "ext3_free_blocks", | 334 | ext3_error (sb, "ext3_free_blocks", |
335 | "Freeing blocks not in datazone - " | 335 | "Freeing blocks not in datazone - " |
336 | "block = %lu, count = %lu", block, count); | 336 | "block = "E3FSBLK", count = %lu", block, count); |
337 | goto error_return; | 337 | goto error_return; |
338 | } | 338 | } |
339 | 339 | ||
@@ -369,7 +369,7 @@ do_more: | |||
369 | sbi->s_itb_per_group)) | 369 | sbi->s_itb_per_group)) |
370 | ext3_error (sb, "ext3_free_blocks", | 370 | ext3_error (sb, "ext3_free_blocks", |
371 | "Freeing blocks in system zones - " | 371 | "Freeing blocks in system zones - " |
372 | "Block = %lu, count = %lu", | 372 | "Block = "E3FSBLK", count = %lu", |
373 | block, count); | 373 | block, count); |
374 | 374 | ||
375 | /* | 375 | /* |
@@ -453,7 +453,8 @@ do_more: | |||
453 | bit + i, bitmap_bh->b_data)) { | 453 | bit + i, bitmap_bh->b_data)) { |
454 | jbd_unlock_bh_state(bitmap_bh); | 454 | jbd_unlock_bh_state(bitmap_bh); |
455 | ext3_error(sb, __FUNCTION__, | 455 | ext3_error(sb, __FUNCTION__, |
456 | "bit already cleared for block %lu", block + i); | 456 | "bit already cleared for block "E3FSBLK, |
457 | block + i); | ||
457 | jbd_lock_bh_state(bitmap_bh); | 458 | jbd_lock_bh_state(bitmap_bh); |
458 | BUFFER_TRACE(bitmap_bh, "bit already cleared"); | 459 | BUFFER_TRACE(bitmap_bh, "bit already cleared"); |
459 | } else { | 460 | } else { |
@@ -493,10 +494,10 @@ error_return: | |||
493 | 494 | ||
494 | /* Free given blocks, update quota and i_blocks field */ | 495 | /* Free given blocks, update quota and i_blocks field */ |
495 | void ext3_free_blocks(handle_t *handle, struct inode *inode, | 496 | void ext3_free_blocks(handle_t *handle, struct inode *inode, |
496 | unsigned long block, unsigned long count) | 497 | ext3_fsblk_t block, unsigned long count) |
497 | { | 498 | { |
498 | struct super_block * sb; | 499 | struct super_block * sb; |
499 | int dquot_freed_blocks; | 500 | unsigned long dquot_freed_blocks; |
500 | 501 | ||
501 | sb = inode->i_sb; | 502 | sb = inode->i_sb; |
502 | if (!sb) { | 503 | if (!sb) { |
@@ -525,7 +526,7 @@ void ext3_free_blocks(handle_t *handle, struct inode *inode, | |||
525 | * data-writes at some point, and disable it for metadata allocations or | 526 | * data-writes at some point, and disable it for metadata allocations or |
526 | * sync-data inodes. | 527 | * sync-data inodes. |
527 | */ | 528 | */ |
528 | static int ext3_test_allocatable(int nr, struct buffer_head *bh) | 529 | static int ext3_test_allocatable(ext3_grpblk_t nr, struct buffer_head *bh) |
529 | { | 530 | { |
530 | int ret; | 531 | int ret; |
531 | struct journal_head *jh = bh2jh(bh); | 532 | struct journal_head *jh = bh2jh(bh); |
@@ -542,11 +543,11 @@ static int ext3_test_allocatable(int nr, struct buffer_head *bh) | |||
542 | return ret; | 543 | return ret; |
543 | } | 544 | } |
544 | 545 | ||
545 | static int | 546 | static ext3_grpblk_t |
546 | bitmap_search_next_usable_block(int start, struct buffer_head *bh, | 547 | bitmap_search_next_usable_block(ext3_grpblk_t start, struct buffer_head *bh, |
547 | int maxblocks) | 548 | ext3_grpblk_t maxblocks) |
548 | { | 549 | { |
549 | int next; | 550 | ext3_grpblk_t next; |
550 | struct journal_head *jh = bh2jh(bh); | 551 | struct journal_head *jh = bh2jh(bh); |
551 | 552 | ||
552 | /* | 553 | /* |
@@ -576,10 +577,11 @@ bitmap_search_next_usable_block(int start, struct buffer_head *bh, | |||
576 | * the initial goal; then for a free byte somewhere in the bitmap; then | 577 | * the initial goal; then for a free byte somewhere in the bitmap; then |
577 | * for any free bit in the bitmap. | 578 | * for any free bit in the bitmap. |
578 | */ | 579 | */ |
579 | static int | 580 | static ext3_grpblk_t |
580 | find_next_usable_block(int start, struct buffer_head *bh, int maxblocks) | 581 | find_next_usable_block(ext3_grpblk_t start, struct buffer_head *bh, |
582 | ext3_grpblk_t maxblocks) | ||
581 | { | 583 | { |
582 | int here, next; | 584 | ext3_grpblk_t here, next; |
583 | char *p, *r; | 585 | char *p, *r; |
584 | 586 | ||
585 | if (start > 0) { | 587 | if (start > 0) { |
@@ -591,7 +593,7 @@ find_next_usable_block(int start, struct buffer_head *bh, int maxblocks) | |||
591 | * less than EXT3_BLOCKS_PER_GROUP. Aligning up to the | 593 | * less than EXT3_BLOCKS_PER_GROUP. Aligning up to the |
592 | * next 64-bit boundary is simple.. | 594 | * next 64-bit boundary is simple.. |
593 | */ | 595 | */ |
594 | int end_goal = (start + 63) & ~63; | 596 | ext3_grpblk_t end_goal = (start + 63) & ~63; |
595 | if (end_goal > maxblocks) | 597 | if (end_goal > maxblocks) |
596 | end_goal = maxblocks; | 598 | end_goal = maxblocks; |
597 | here = ext3_find_next_zero_bit(bh->b_data, end_goal, start); | 599 | here = ext3_find_next_zero_bit(bh->b_data, end_goal, start); |
@@ -628,7 +630,7 @@ find_next_usable_block(int start, struct buffer_head *bh, int maxblocks) | |||
628 | * zero (failure). | 630 | * zero (failure). |
629 | */ | 631 | */ |
630 | static inline int | 632 | static inline int |
631 | claim_block(spinlock_t *lock, int block, struct buffer_head *bh) | 633 | claim_block(spinlock_t *lock, ext3_grpblk_t block, struct buffer_head *bh) |
632 | { | 634 | { |
633 | struct journal_head *jh = bh2jh(bh); | 635 | struct journal_head *jh = bh2jh(bh); |
634 | int ret; | 636 | int ret; |
@@ -651,12 +653,13 @@ claim_block(spinlock_t *lock, int block, struct buffer_head *bh) | |||
651 | * new bitmap. In that case we must release write access to the old one via | 653 | * new bitmap. In that case we must release write access to the old one via |
652 | * ext3_journal_release_buffer(), else we'll run out of credits. | 654 | * ext3_journal_release_buffer(), else we'll run out of credits. |
653 | */ | 655 | */ |
654 | static int | 656 | static ext3_grpblk_t |
655 | ext3_try_to_allocate(struct super_block *sb, handle_t *handle, int group, | 657 | ext3_try_to_allocate(struct super_block *sb, handle_t *handle, int group, |
656 | struct buffer_head *bitmap_bh, int goal, | 658 | struct buffer_head *bitmap_bh, ext3_grpblk_t grp_goal, |
657 | unsigned long *count, struct ext3_reserve_window *my_rsv) | 659 | unsigned long *count, struct ext3_reserve_window *my_rsv) |
658 | { | 660 | { |
659 | int group_first_block, start, end; | 661 | ext3_fsblk_t group_first_block; |
662 | ext3_grpblk_t start, end; | ||
660 | unsigned long num = 0; | 663 | unsigned long num = 0; |
661 | 664 | ||
662 | /* we do allocation within the reservation window if we have a window */ | 665 | /* we do allocation within the reservation window if we have a window */ |
@@ -673,13 +676,13 @@ ext3_try_to_allocate(struct super_block *sb, handle_t *handle, int group, | |||
673 | if (end > EXT3_BLOCKS_PER_GROUP(sb)) | 676 | if (end > EXT3_BLOCKS_PER_GROUP(sb)) |
674 | /* reservation window crosses group boundary */ | 677 | /* reservation window crosses group boundary */ |
675 | end = EXT3_BLOCKS_PER_GROUP(sb); | 678 | end = EXT3_BLOCKS_PER_GROUP(sb); |
676 | if ((start <= goal) && (goal < end)) | 679 | if ((start <= grp_goal) && (grp_goal < end)) |
677 | start = goal; | 680 | start = grp_goal; |
678 | else | 681 | else |
679 | goal = -1; | 682 | grp_goal = -1; |
680 | } else { | 683 | } else { |
681 | if (goal > 0) | 684 | if (grp_goal > 0) |
682 | start = goal; | 685 | start = grp_goal; |
683 | else | 686 | else |
684 | start = 0; | 687 | start = 0; |
685 | end = EXT3_BLOCKS_PER_GROUP(sb); | 688 | end = EXT3_BLOCKS_PER_GROUP(sb); |
@@ -688,43 +691,43 @@ ext3_try_to_allocate(struct super_block *sb, handle_t *handle, int group, | |||
688 | BUG_ON(start > EXT3_BLOCKS_PER_GROUP(sb)); | 691 | BUG_ON(start > EXT3_BLOCKS_PER_GROUP(sb)); |
689 | 692 | ||
690 | repeat: | 693 | repeat: |
691 | if (goal < 0 || !ext3_test_allocatable(goal, bitmap_bh)) { | 694 | if (grp_goal < 0 || !ext3_test_allocatable(grp_goal, bitmap_bh)) { |
692 | goal = find_next_usable_block(start, bitmap_bh, end); | 695 | grp_goal = find_next_usable_block(start, bitmap_bh, end); |
693 | if (goal < 0) | 696 | if (grp_goal < 0) |
694 | goto fail_access; | 697 | goto fail_access; |
695 | if (!my_rsv) { | 698 | if (!my_rsv) { |
696 | int i; | 699 | int i; |
697 | 700 | ||
698 | for (i = 0; i < 7 && goal > start && | 701 | for (i = 0; i < 7 && grp_goal > start && |
699 | ext3_test_allocatable(goal - 1, | 702 | ext3_test_allocatable(grp_goal - 1, |
700 | bitmap_bh); | 703 | bitmap_bh); |
701 | i++, goal--) | 704 | i++, grp_goal--) |
702 | ; | 705 | ; |
703 | } | 706 | } |
704 | } | 707 | } |
705 | start = goal; | 708 | start = grp_goal; |
706 | 709 | ||
707 | if (!claim_block(sb_bgl_lock(EXT3_SB(sb), group), goal, bitmap_bh)) { | 710 | if (!claim_block(sb_bgl_lock(EXT3_SB(sb), group), grp_goal, bitmap_bh)) { |
708 | /* | 711 | /* |
709 | * The block was allocated by another thread, or it was | 712 | * The block was allocated by another thread, or it was |
710 | * allocated and then freed by another thread | 713 | * allocated and then freed by another thread |
711 | */ | 714 | */ |
712 | start++; | 715 | start++; |
713 | goal++; | 716 | grp_goal++; |
714 | if (start >= end) | 717 | if (start >= end) |
715 | goto fail_access; | 718 | goto fail_access; |
716 | goto repeat; | 719 | goto repeat; |
717 | } | 720 | } |
718 | num++; | 721 | num++; |
719 | goal++; | 722 | grp_goal++; |
720 | while (num < *count && goal < end | 723 | while (num < *count && grp_goal < end |
721 | && ext3_test_allocatable(goal, bitmap_bh) | 724 | && ext3_test_allocatable(grp_goal, bitmap_bh) |
722 | && claim_block(sb_bgl_lock(EXT3_SB(sb), group), goal, bitmap_bh)) { | 725 | && claim_block(sb_bgl_lock(EXT3_SB(sb), group), grp_goal, bitmap_bh)) { |
723 | num++; | 726 | num++; |
724 | goal++; | 727 | grp_goal++; |
725 | } | 728 | } |
726 | *count = num; | 729 | *count = num; |
727 | return goal - num; | 730 | return grp_goal - num; |
728 | fail_access: | 731 | fail_access: |
729 | *count = num; | 732 | *count = num; |
730 | return -1; | 733 | return -1; |
@@ -766,12 +769,13 @@ fail_access: | |||
766 | static int find_next_reservable_window( | 769 | static int find_next_reservable_window( |
767 | struct ext3_reserve_window_node *search_head, | 770 | struct ext3_reserve_window_node *search_head, |
768 | struct ext3_reserve_window_node *my_rsv, | 771 | struct ext3_reserve_window_node *my_rsv, |
769 | struct super_block * sb, int start_block, | 772 | struct super_block * sb, |
770 | int last_block) | 773 | ext3_fsblk_t start_block, |
774 | ext3_fsblk_t last_block) | ||
771 | { | 775 | { |
772 | struct rb_node *next; | 776 | struct rb_node *next; |
773 | struct ext3_reserve_window_node *rsv, *prev; | 777 | struct ext3_reserve_window_node *rsv, *prev; |
774 | int cur; | 778 | ext3_fsblk_t cur; |
775 | int size = my_rsv->rsv_goal_size; | 779 | int size = my_rsv->rsv_goal_size; |
776 | 780 | ||
777 | /* TODO: make the start of the reservation window byte-aligned */ | 781 | /* TODO: make the start of the reservation window byte-aligned */ |
@@ -873,10 +877,10 @@ static int find_next_reservable_window( | |||
873 | * | 877 | * |
874 | * @rsv: the reservation | 878 | * @rsv: the reservation |
875 | * | 879 | * |
876 | * @goal: The goal (group-relative). It is where the search for a | 880 | * @grp_goal: The goal (group-relative). It is where the search for a |
877 | * free reservable space should start from. | 881 | * free reservable space should start from. |
878 | * if we have a goal(goal >0 ), then start from there, | 882 | * if we have a grp_goal(grp_goal >0 ), then start from there, |
879 | * no goal(goal = -1), we start from the first block | 883 | * no grp_goal(grp_goal = -1), we start from the first block |
880 | * of the group. | 884 | * of the group. |
881 | * | 885 | * |
882 | * @sb: the super block | 886 | * @sb: the super block |
@@ -885,12 +889,12 @@ static int find_next_reservable_window( | |||
885 | * | 889 | * |
886 | */ | 890 | */ |
887 | static int alloc_new_reservation(struct ext3_reserve_window_node *my_rsv, | 891 | static int alloc_new_reservation(struct ext3_reserve_window_node *my_rsv, |
888 | int goal, struct super_block *sb, | 892 | ext3_grpblk_t grp_goal, struct super_block *sb, |
889 | unsigned int group, struct buffer_head *bitmap_bh) | 893 | unsigned int group, struct buffer_head *bitmap_bh) |
890 | { | 894 | { |
891 | struct ext3_reserve_window_node *search_head; | 895 | struct ext3_reserve_window_node *search_head; |
892 | int group_first_block, group_end_block, start_block; | 896 | ext3_fsblk_t group_first_block, group_end_block, start_block; |
893 | int first_free_block; | 897 | ext3_grpblk_t first_free_block; |
894 | struct rb_root *fs_rsv_root = &EXT3_SB(sb)->s_rsv_window_root; | 898 | struct rb_root *fs_rsv_root = &EXT3_SB(sb)->s_rsv_window_root; |
895 | unsigned long size; | 899 | unsigned long size; |
896 | int ret; | 900 | int ret; |
@@ -900,10 +904,10 @@ static int alloc_new_reservation(struct ext3_reserve_window_node *my_rsv, | |||
900 | group * EXT3_BLOCKS_PER_GROUP(sb); | 904 | group * EXT3_BLOCKS_PER_GROUP(sb); |
901 | group_end_block = group_first_block + EXT3_BLOCKS_PER_GROUP(sb) - 1; | 905 | group_end_block = group_first_block + EXT3_BLOCKS_PER_GROUP(sb) - 1; |
902 | 906 | ||
903 | if (goal < 0) | 907 | if (grp_goal < 0) |
904 | start_block = group_first_block; | 908 | start_block = group_first_block; |
905 | else | 909 | else |
906 | start_block = goal + group_first_block; | 910 | start_block = grp_goal + group_first_block; |
907 | 911 | ||
908 | size = my_rsv->rsv_goal_size; | 912 | size = my_rsv->rsv_goal_size; |
909 | 913 | ||
@@ -1057,14 +1061,15 @@ static void try_to_extend_reservation(struct ext3_reserve_window_node *my_rsv, | |||
1057 | * sorted double linked list should be fast. | 1061 | * sorted double linked list should be fast. |
1058 | * | 1062 | * |
1059 | */ | 1063 | */ |
1060 | static int | 1064 | static ext3_grpblk_t |
1061 | ext3_try_to_allocate_with_rsv(struct super_block *sb, handle_t *handle, | 1065 | ext3_try_to_allocate_with_rsv(struct super_block *sb, handle_t *handle, |
1062 | unsigned int group, struct buffer_head *bitmap_bh, | 1066 | unsigned int group, struct buffer_head *bitmap_bh, |
1063 | int goal, struct ext3_reserve_window_node * my_rsv, | 1067 | ext3_grpblk_t grp_goal, |
1068 | struct ext3_reserve_window_node * my_rsv, | ||
1064 | unsigned long *count, int *errp) | 1069 | unsigned long *count, int *errp) |
1065 | { | 1070 | { |
1066 | unsigned long group_first_block; | 1071 | ext3_fsblk_t group_first_block; |
1067 | int ret = 0; | 1072 | ext3_grpblk_t ret = 0; |
1068 | int fatal; | 1073 | int fatal; |
1069 | unsigned long num = *count; | 1074 | unsigned long num = *count; |
1070 | 1075 | ||
@@ -1090,12 +1095,12 @@ ext3_try_to_allocate_with_rsv(struct super_block *sb, handle_t *handle, | |||
1090 | */ | 1095 | */ |
1091 | if (my_rsv == NULL ) { | 1096 | if (my_rsv == NULL ) { |
1092 | ret = ext3_try_to_allocate(sb, handle, group, bitmap_bh, | 1097 | ret = ext3_try_to_allocate(sb, handle, group, bitmap_bh, |
1093 | goal, count, NULL); | 1098 | grp_goal, count, NULL); |
1094 | goto out; | 1099 | goto out; |
1095 | } | 1100 | } |
1096 | /* | 1101 | /* |
1097 | * goal is a group relative block number (if there is a goal) | 1102 | * grp_goal is a group relative block number (if there is a goal) |
1098 | * 0 < goal < EXT3_BLOCKS_PER_GROUP(sb) | 1103 | * 0 < grp_goal < EXT3_BLOCKS_PER_GROUP(sb) |
1099 | * first block is a filesystem wide block number | 1104 | * first block is a filesystem wide block number |
1100 | * first block is the block number of the first block in this group | 1105 | * first block is the block number of the first block in this group |
1101 | */ | 1106 | */ |
@@ -1119,24 +1124,24 @@ ext3_try_to_allocate_with_rsv(struct super_block *sb, handle_t *handle, | |||
1119 | */ | 1124 | */ |
1120 | while (1) { | 1125 | while (1) { |
1121 | if (rsv_is_empty(&my_rsv->rsv_window) || (ret < 0) || | 1126 | if (rsv_is_empty(&my_rsv->rsv_window) || (ret < 0) || |
1122 | !goal_in_my_reservation(&my_rsv->rsv_window, goal, group, sb)) { | 1127 | !goal_in_my_reservation(&my_rsv->rsv_window, grp_goal, group, sb)) { |
1123 | if (my_rsv->rsv_goal_size < *count) | 1128 | if (my_rsv->rsv_goal_size < *count) |
1124 | my_rsv->rsv_goal_size = *count; | 1129 | my_rsv->rsv_goal_size = *count; |
1125 | ret = alloc_new_reservation(my_rsv, goal, sb, | 1130 | ret = alloc_new_reservation(my_rsv, grp_goal, sb, |
1126 | group, bitmap_bh); | 1131 | group, bitmap_bh); |
1127 | if (ret < 0) | 1132 | if (ret < 0) |
1128 | break; /* failed */ | 1133 | break; /* failed */ |
1129 | 1134 | ||
1130 | if (!goal_in_my_reservation(&my_rsv->rsv_window, goal, group, sb)) | 1135 | if (!goal_in_my_reservation(&my_rsv->rsv_window, grp_goal, group, sb)) |
1131 | goal = -1; | 1136 | grp_goal = -1; |
1132 | } else if (goal > 0 && (my_rsv->rsv_end-goal+1) < *count) | 1137 | } else if (grp_goal > 0 && (my_rsv->rsv_end-grp_goal+1) < *count) |
1133 | try_to_extend_reservation(my_rsv, sb, | 1138 | try_to_extend_reservation(my_rsv, sb, |
1134 | *count-my_rsv->rsv_end + goal - 1); | 1139 | *count-my_rsv->rsv_end + grp_goal - 1); |
1135 | 1140 | ||
1136 | if ((my_rsv->rsv_start >= group_first_block + EXT3_BLOCKS_PER_GROUP(sb)) | 1141 | if ((my_rsv->rsv_start >= group_first_block + EXT3_BLOCKS_PER_GROUP(sb)) |
1137 | || (my_rsv->rsv_end < group_first_block)) | 1142 | || (my_rsv->rsv_end < group_first_block)) |
1138 | BUG(); | 1143 | BUG(); |
1139 | ret = ext3_try_to_allocate(sb, handle, group, bitmap_bh, goal, | 1144 | ret = ext3_try_to_allocate(sb, handle, group, bitmap_bh, grp_goal, |
1140 | &num, &my_rsv->rsv_window); | 1145 | &num, &my_rsv->rsv_window); |
1141 | if (ret >= 0) { | 1146 | if (ret >= 0) { |
1142 | my_rsv->rsv_alloc_hit += num; | 1147 | my_rsv->rsv_alloc_hit += num; |
@@ -1164,7 +1169,7 @@ out: | |||
1164 | 1169 | ||
1165 | static int ext3_has_free_blocks(struct ext3_sb_info *sbi) | 1170 | static int ext3_has_free_blocks(struct ext3_sb_info *sbi) |
1166 | { | 1171 | { |
1167 | int free_blocks, root_blocks; | 1172 | ext3_fsblk_t free_blocks, root_blocks; |
1168 | 1173 | ||
1169 | free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter); | 1174 | free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter); |
1170 | root_blocks = le32_to_cpu(sbi->s_es->s_r_blocks_count); | 1175 | root_blocks = le32_to_cpu(sbi->s_es->s_r_blocks_count); |
@@ -1200,19 +1205,20 @@ int ext3_should_retry_alloc(struct super_block *sb, int *retries) | |||
1200 | * bitmap, and then for any free bit if that fails. | 1205 | * bitmap, and then for any free bit if that fails. |
1201 | * This function also updates quota and i_blocks field. | 1206 | * This function also updates quota and i_blocks field. |
1202 | */ | 1207 | */ |
1203 | int ext3_new_blocks(handle_t *handle, struct inode *inode, | 1208 | ext3_fsblk_t ext3_new_blocks(handle_t *handle, struct inode *inode, |
1204 | unsigned long goal, unsigned long *count, int *errp) | 1209 | ext3_fsblk_t goal, unsigned long *count, int *errp) |
1205 | { | 1210 | { |
1206 | struct buffer_head *bitmap_bh = NULL; | 1211 | struct buffer_head *bitmap_bh = NULL; |
1207 | struct buffer_head *gdp_bh; | 1212 | struct buffer_head *gdp_bh; |
1208 | int group_no; | 1213 | int group_no; |
1209 | int goal_group; | 1214 | int goal_group; |
1210 | int ret_block; | 1215 | ext3_grpblk_t grp_target_blk; /* blockgroup relative goal block */ |
1216 | ext3_grpblk_t grp_alloc_blk; /* blockgroup-relative allocated block*/ | ||
1217 | ext3_fsblk_t ret_block; /* filesyetem-wide allocated block */ | ||
1211 | int bgi; /* blockgroup iteration index */ | 1218 | int bgi; /* blockgroup iteration index */ |
1212 | int target_block; | ||
1213 | int fatal = 0, err; | 1219 | int fatal = 0, err; |
1214 | int performed_allocation = 0; | 1220 | int performed_allocation = 0; |
1215 | int free_blocks; | 1221 | ext3_grpblk_t free_blocks; /* number of free blocks in a group */ |
1216 | struct super_block *sb; | 1222 | struct super_block *sb; |
1217 | struct ext3_group_desc *gdp; | 1223 | struct ext3_group_desc *gdp; |
1218 | struct ext3_super_block *es; | 1224 | struct ext3_super_block *es; |
@@ -1285,16 +1291,17 @@ retry: | |||
1285 | my_rsv = NULL; | 1291 | my_rsv = NULL; |
1286 | 1292 | ||
1287 | if (free_blocks > 0) { | 1293 | if (free_blocks > 0) { |
1288 | ret_block = ((goal - le32_to_cpu(es->s_first_data_block)) % | 1294 | grp_target_blk = ((goal - le32_to_cpu(es->s_first_data_block)) % |
1289 | EXT3_BLOCKS_PER_GROUP(sb)); | 1295 | EXT3_BLOCKS_PER_GROUP(sb)); |
1290 | bitmap_bh = read_block_bitmap(sb, group_no); | 1296 | bitmap_bh = read_block_bitmap(sb, group_no); |
1291 | if (!bitmap_bh) | 1297 | if (!bitmap_bh) |
1292 | goto io_error; | 1298 | goto io_error; |
1293 | ret_block = ext3_try_to_allocate_with_rsv(sb, handle, group_no, | 1299 | grp_alloc_blk = ext3_try_to_allocate_with_rsv(sb, handle, |
1294 | bitmap_bh, ret_block, my_rsv, &num, &fatal); | 1300 | group_no, bitmap_bh, grp_target_blk, |
1301 | my_rsv, &num, &fatal); | ||
1295 | if (fatal) | 1302 | if (fatal) |
1296 | goto out; | 1303 | goto out; |
1297 | if (ret_block >= 0) | 1304 | if (grp_alloc_blk >= 0) |
1298 | goto allocated; | 1305 | goto allocated; |
1299 | } | 1306 | } |
1300 | 1307 | ||
@@ -1327,11 +1334,15 @@ retry: | |||
1327 | bitmap_bh = read_block_bitmap(sb, group_no); | 1334 | bitmap_bh = read_block_bitmap(sb, group_no); |
1328 | if (!bitmap_bh) | 1335 | if (!bitmap_bh) |
1329 | goto io_error; | 1336 | goto io_error; |
1330 | ret_block = ext3_try_to_allocate_with_rsv(sb, handle, group_no, | 1337 | /* |
1331 | bitmap_bh, -1, my_rsv, &num, &fatal); | 1338 | * try to allocate block(s) from this group, without a goal(-1). |
1339 | */ | ||
1340 | grp_alloc_blk = ext3_try_to_allocate_with_rsv(sb, handle, | ||
1341 | group_no, bitmap_bh, -1, my_rsv, | ||
1342 | &num, &fatal); | ||
1332 | if (fatal) | 1343 | if (fatal) |
1333 | goto out; | 1344 | goto out; |
1334 | if (ret_block >= 0) | 1345 | if (grp_alloc_blk >= 0) |
1335 | goto allocated; | 1346 | goto allocated; |
1336 | } | 1347 | } |
1337 | /* | 1348 | /* |
@@ -1360,18 +1371,19 @@ allocated: | |||
1360 | if (fatal) | 1371 | if (fatal) |
1361 | goto out; | 1372 | goto out; |
1362 | 1373 | ||
1363 | target_block = ret_block + group_no * EXT3_BLOCKS_PER_GROUP(sb) | 1374 | ret_block = grp_alloc_blk + group_no * EXT3_BLOCKS_PER_GROUP(sb) |
1364 | + le32_to_cpu(es->s_first_data_block); | 1375 | + le32_to_cpu(es->s_first_data_block); |
1365 | 1376 | ||
1366 | if (in_range(le32_to_cpu(gdp->bg_block_bitmap), target_block, num) || | 1377 | if (in_range(le32_to_cpu(gdp->bg_block_bitmap), ret_block, num) || |
1367 | in_range(le32_to_cpu(gdp->bg_inode_bitmap), target_block, num) || | 1378 | in_range(le32_to_cpu(gdp->bg_inode_bitmap), ret_block, num) || |
1368 | in_range(target_block, le32_to_cpu(gdp->bg_inode_table), | 1379 | in_range(ret_block, le32_to_cpu(gdp->bg_inode_table), |
1369 | EXT3_SB(sb)->s_itb_per_group) || | 1380 | EXT3_SB(sb)->s_itb_per_group) || |
1370 | in_range(target_block + num - 1, le32_to_cpu(gdp->bg_inode_table), | 1381 | in_range(ret_block + num - 1, le32_to_cpu(gdp->bg_inode_table), |
1371 | EXT3_SB(sb)->s_itb_per_group)) | 1382 | EXT3_SB(sb)->s_itb_per_group)) |
1372 | ext3_error(sb, "ext3_new_block", | 1383 | ext3_error(sb, "ext3_new_block", |
1373 | "Allocating block in system zone - " | 1384 | "Allocating block in system zone - " |
1374 | "blocks from %u, length %lu", target_block, num); | 1385 | "blocks from "E3FSBLK", length %lu", |
1386 | ret_block, num); | ||
1375 | 1387 | ||
1376 | performed_allocation = 1; | 1388 | performed_allocation = 1; |
1377 | 1389 | ||
@@ -1380,7 +1392,7 @@ allocated: | |||
1380 | struct buffer_head *debug_bh; | 1392 | struct buffer_head *debug_bh; |
1381 | 1393 | ||
1382 | /* Record bitmap buffer state in the newly allocated block */ | 1394 | /* Record bitmap buffer state in the newly allocated block */ |
1383 | debug_bh = sb_find_get_block(sb, target_block); | 1395 | debug_bh = sb_find_get_block(sb, ret_block); |
1384 | if (debug_bh) { | 1396 | if (debug_bh) { |
1385 | BUFFER_TRACE(debug_bh, "state when allocated"); | 1397 | BUFFER_TRACE(debug_bh, "state when allocated"); |
1386 | BUFFER_TRACE2(debug_bh, bitmap_bh, "bitmap state"); | 1398 | BUFFER_TRACE2(debug_bh, bitmap_bh, "bitmap state"); |
@@ -1393,24 +1405,21 @@ allocated: | |||
1393 | int i; | 1405 | int i; |
1394 | 1406 | ||
1395 | for (i = 0; i < num; i++) { | 1407 | for (i = 0; i < num; i++) { |
1396 | if (ext3_test_bit(ret_block, | 1408 | if (ext3_test_bit(grp_alloc_blk+i, |
1397 | bh2jh(bitmap_bh)->b_committed_data)) { | 1409 | bh2jh(bitmap_bh)->b_committed_data)) { |
1398 | printk("%s: block was unexpectedly set in " | 1410 | printk("%s: block was unexpectedly set in " |
1399 | "b_committed_data\n", __FUNCTION__); | 1411 | "b_committed_data\n", __FUNCTION__); |
1400 | } | 1412 | } |
1401 | } | 1413 | } |
1402 | } | 1414 | } |
1403 | ext3_debug("found bit %d\n", ret_block); | 1415 | ext3_debug("found bit %d\n", grp_alloc_blk); |
1404 | spin_unlock(sb_bgl_lock(sbi, group_no)); | 1416 | spin_unlock(sb_bgl_lock(sbi, group_no)); |
1405 | jbd_unlock_bh_state(bitmap_bh); | 1417 | jbd_unlock_bh_state(bitmap_bh); |
1406 | #endif | 1418 | #endif |
1407 | 1419 | ||
1408 | /* ret_block was blockgroup-relative. Now it becomes fs-relative */ | ||
1409 | ret_block = target_block; | ||
1410 | |||
1411 | if (ret_block + num - 1 >= le32_to_cpu(es->s_blocks_count)) { | 1420 | if (ret_block + num - 1 >= le32_to_cpu(es->s_blocks_count)) { |
1412 | ext3_error(sb, "ext3_new_block", | 1421 | ext3_error(sb, "ext3_new_block", |
1413 | "block(%d) >= blocks count(%d) - " | 1422 | "block("E3FSBLK") >= blocks count(%d) - " |
1414 | "block_group = %d, es == %p ", ret_block, | 1423 | "block_group = %d, es == %p ", ret_block, |
1415 | le32_to_cpu(es->s_blocks_count), group_no, es); | 1424 | le32_to_cpu(es->s_blocks_count), group_no, es); |
1416 | goto out; | 1425 | goto out; |
@@ -1421,7 +1430,7 @@ allocated: | |||
1421 | * list of some description. We don't know in advance whether | 1430 | * list of some description. We don't know in advance whether |
1422 | * the caller wants to use it as metadata or data. | 1431 | * the caller wants to use it as metadata or data. |
1423 | */ | 1432 | */ |
1424 | ext3_debug("allocating block %d. Goal hits %d of %d.\n", | 1433 | ext3_debug("allocating block %lu. Goal hits %d of %d.\n", |
1425 | ret_block, goal_hits, goal_attempts); | 1434 | ret_block, goal_hits, goal_attempts); |
1426 | 1435 | ||
1427 | spin_lock(sb_bgl_lock(sbi, group_no)); | 1436 | spin_lock(sb_bgl_lock(sbi, group_no)); |
@@ -1461,8 +1470,8 @@ out: | |||
1461 | return 0; | 1470 | return 0; |
1462 | } | 1471 | } |
1463 | 1472 | ||
1464 | int ext3_new_block(handle_t *handle, struct inode *inode, | 1473 | ext3_fsblk_t ext3_new_block(handle_t *handle, struct inode *inode, |
1465 | unsigned long goal, int *errp) | 1474 | ext3_fsblk_t goal, int *errp) |
1466 | { | 1475 | { |
1467 | unsigned long count = 1; | 1476 | unsigned long count = 1; |
1468 | 1477 | ||
@@ -1520,7 +1529,7 @@ unsigned long ext3_count_free_blocks(struct super_block *sb) | |||
1520 | } | 1529 | } |
1521 | 1530 | ||
1522 | static inline int | 1531 | static inline int |
1523 | block_in_use(unsigned long block, struct super_block *sb, unsigned char *map) | 1532 | block_in_use(ext3_fsblk_t block, struct super_block *sb, unsigned char *map) |
1524 | { | 1533 | { |
1525 | return ext3_test_bit ((block - | 1534 | return ext3_test_bit ((block - |
1526 | le32_to_cpu(EXT3_SB(sb)->s_es->s_first_data_block)) % | 1535 | le32_to_cpu(EXT3_SB(sb)->s_es->s_first_data_block)) % |