aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext3/balloc.c
diff options
context:
space:
mode:
authorMingming Cao <cmm@us.ibm.com>2006-06-25 08:48:06 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-06-25 13:01:10 -0400
commit1c2bf374a4b8c2e1a3e6ff3a64fb67272a8cd2e2 (patch)
treeabb4e01a4bc146183d5cf1f0e18c1aa6e847aa5e /fs/ext3/balloc.c
parentcedfb178ada245b6c52a654936b34d7996e26a1d (diff)
[PATCH] ext3_fsblk_t: filesystem, group blocks and bug fixes
Some of the in-kernel ext3 block variable type are treated as signed 4 bytes int type, thus limited ext3 filesystem to 8TB (4kblock size based). While trying to fix them, it seems quite confusing in the ext3 code where some blocks are filesystem-wide blocks, some are group relative offsets that need to be signed value (as -1 has special meaning). So it seem saner to define two types of physical blocks: one is filesystem wide blocks, another is group-relative blocks. The following patches clarify these two types of blocks in the ext3 code, and fix the type bugs which limit current 32 bit ext3 filesystem limit to 8TB. With this series of patches and the percpu counter data type changes in the mm tree, we are able to extend exts filesystem limit to 16TB. This work is also a pre-request for the recent >32 bit ext3 work, and makes the kernel to able to address 48 bit ext3 block a lot easier: Simply redefine ext3_fsblk_t from unsigned long to sector_t and redefine the format string for ext3 filesystem block corresponding. Two RFC with a series patches have been posted to ext2-devel list and have been reviewed and discussed: http://marc.theaimsgroup.com/?l=ext2-devel&m=114722190816690&w=2 http://marc.theaimsgroup.com/?l=ext2-devel&m=114784919525942&w=2 Patches are tested on both 32 bit machine and 64 bit machine, <8TB ext3 and >8TB ext3 filesystem(with the latest to be released e2fsprogs-1.39). Tests includes overnight fsx, tiobench, dbench and fsstress. This patch: Defines ext3_fsblk_t and ext3_grpblk_t, and the printk format string for filesystem wide blocks. This patch classifies all block group relative blocks, and ext3_fsblk_t blocks occurs in the same function where used to be confusing before. Also include kernel bug fixes for filesystem wide in-kernel block variables. There are some fileystem wide blocks are treated as int/unsigned int type in the kernel currently, especially in ext3 block allocation and reservation code. This patch fixed those bugs by converting those variables to ext3_fsblk_t(unsigned long) type. Signed-off-by: Mingming Cao <cmm@us.ibm.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs/ext3/balloc.c')
-rw-r--r--fs/ext3/balloc.c215
1 files changed, 112 insertions, 103 deletions
diff --git a/fs/ext3/balloc.c b/fs/ext3/balloc.c
index 77927d6938f..b1633cd28ec 100644
--- a/fs/ext3/balloc.c
+++ b/fs/ext3/balloc.c
@@ -163,10 +163,10 @@ restart:
163#endif 163#endif
164 164
165static int 165static int
166goal_in_my_reservation(struct ext3_reserve_window *rsv, int goal, 166goal_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 */
189static struct ext3_reserve_window_node * 189static struct ext3_reserve_window_node *
190search_reserve_window(struct rb_root *root, unsigned long goal) 190search_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 */
312void ext3_free_blocks_sb(handle_t *handle, struct super_block *sb, 312void 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 */
495void ext3_free_blocks(handle_t *handle, struct inode *inode, 496void 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 */
528static int ext3_test_allocatable(int nr, struct buffer_head *bh) 529static 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
545static int 546static ext3_grpblk_t
546bitmap_search_next_usable_block(int start, struct buffer_head *bh, 547bitmap_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 */
579static int 580static ext3_grpblk_t
580find_next_usable_block(int start, struct buffer_head *bh, int maxblocks) 581find_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 */
630static inline int 632static inline int
631claim_block(spinlock_t *lock, int block, struct buffer_head *bh) 633claim_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 */
654static int 656static ext3_grpblk_t
655ext3_try_to_allocate(struct super_block *sb, handle_t *handle, int group, 657ext3_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
690repeat: 693repeat:
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;
728fail_access: 731fail_access:
729 *count = num; 732 *count = num;
730 return -1; 733 return -1;
@@ -766,12 +769,13 @@ fail_access:
766static int find_next_reservable_window( 769static 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 */
887static int alloc_new_reservation(struct ext3_reserve_window_node *my_rsv, 891static 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 */
1060static int 1064static ext3_grpblk_t
1061ext3_try_to_allocate_with_rsv(struct super_block *sb, handle_t *handle, 1065ext3_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
1165static int ext3_has_free_blocks(struct ext3_sb_info *sbi) 1170static 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 */
1203int ext3_new_blocks(handle_t *handle, struct inode *inode, 1208ext3_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
1464int ext3_new_block(handle_t *handle, struct inode *inode, 1473ext3_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
1522static inline int 1531static inline int
1523block_in_use(unsigned long block, struct super_block *sb, unsigned char *map) 1532block_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)) %