.. | .. |
---|
187 | 187 | |
---|
188 | 188 | /** |
---|
189 | 189 | * __rsv_window_dump() -- Dump the filesystem block allocation reservation map |
---|
190 | | - * @rb_root: root of per-filesystem reservation rb tree |
---|
| 190 | + * @root: root of per-filesystem reservation rb tree |
---|
191 | 191 | * @verbose: verbose mode |
---|
192 | 192 | * @fn: function which wishes to dump the reservation map |
---|
193 | 193 | * |
---|
.. | .. |
---|
267 | 267 | ext2_fsblk_t group_first_block, group_last_block; |
---|
268 | 268 | |
---|
269 | 269 | group_first_block = ext2_group_first_block_no(sb, group); |
---|
270 | | - group_last_block = group_first_block + EXT2_BLOCKS_PER_GROUP(sb) - 1; |
---|
| 270 | + group_last_block = ext2_group_last_block_no(sb, group); |
---|
271 | 271 | |
---|
272 | 272 | if ((rsv->_rsv_start > group_last_block) || |
---|
273 | 273 | (rsv->_rsv_end < group_first_block)) |
---|
.. | .. |
---|
280 | 280 | |
---|
281 | 281 | /** |
---|
282 | 282 | * search_reserve_window() |
---|
283 | | - * @rb_root: root of reservation tree |
---|
| 283 | + * @root: root of reservation tree |
---|
284 | 284 | * @goal: target allocation block |
---|
285 | 285 | * |
---|
286 | 286 | * Find the reserved window which includes the goal, or the previous one |
---|
.. | .. |
---|
488 | 488 | struct ext2_super_block * es = sbi->s_es; |
---|
489 | 489 | unsigned freed = 0, group_freed; |
---|
490 | 490 | |
---|
491 | | - if (block < le32_to_cpu(es->s_first_data_block) || |
---|
492 | | - block + count < block || |
---|
493 | | - block + count > le32_to_cpu(es->s_blocks_count)) { |
---|
| 491 | + if (!ext2_data_block_valid(sbi, block, count)) { |
---|
494 | 492 | ext2_error (sb, "ext2_free_blocks", |
---|
495 | 493 | "Freeing blocks not in datazone - " |
---|
496 | 494 | "block = %lu, count = %lu", block, count); |
---|
.. | .. |
---|
666 | 664 | unsigned long *count, |
---|
667 | 665 | struct ext2_reserve_window *my_rsv) |
---|
668 | 666 | { |
---|
669 | | - ext2_fsblk_t group_first_block; |
---|
| 667 | + ext2_fsblk_t group_first_block = ext2_group_first_block_no(sb, group); |
---|
| 668 | + ext2_fsblk_t group_last_block = ext2_group_last_block_no(sb, group); |
---|
670 | 669 | ext2_grpblk_t start, end; |
---|
671 | 670 | unsigned long num = 0; |
---|
672 | 671 | |
---|
| 672 | + start = 0; |
---|
| 673 | + end = group_last_block - group_first_block + 1; |
---|
673 | 674 | /* we do allocation within the reservation window if we have a window */ |
---|
674 | 675 | if (my_rsv) { |
---|
675 | | - group_first_block = ext2_group_first_block_no(sb, group); |
---|
676 | 676 | if (my_rsv->_rsv_start >= group_first_block) |
---|
677 | 677 | start = my_rsv->_rsv_start - group_first_block; |
---|
678 | | - else |
---|
679 | | - /* reservation window cross group boundary */ |
---|
680 | | - start = 0; |
---|
681 | | - end = my_rsv->_rsv_end - group_first_block + 1; |
---|
682 | | - if (end > EXT2_BLOCKS_PER_GROUP(sb)) |
---|
683 | | - /* reservation window crosses group boundary */ |
---|
684 | | - end = EXT2_BLOCKS_PER_GROUP(sb); |
---|
685 | | - if ((start <= grp_goal) && (grp_goal < end)) |
---|
686 | | - start = grp_goal; |
---|
687 | | - else |
---|
| 678 | + if (my_rsv->_rsv_end < group_last_block) |
---|
| 679 | + end = my_rsv->_rsv_end - group_first_block + 1; |
---|
| 680 | + if (grp_goal < start || grp_goal >= end) |
---|
688 | 681 | grp_goal = -1; |
---|
689 | | - } else { |
---|
690 | | - if (grp_goal > 0) |
---|
691 | | - start = grp_goal; |
---|
692 | | - else |
---|
693 | | - start = 0; |
---|
694 | | - end = EXT2_BLOCKS_PER_GROUP(sb); |
---|
695 | 682 | } |
---|
696 | | - |
---|
697 | 683 | BUG_ON(start > EXT2_BLOCKS_PER_GROUP(sb)); |
---|
698 | 684 | |
---|
699 | | -repeat: |
---|
700 | 685 | if (grp_goal < 0) { |
---|
701 | 686 | grp_goal = find_next_usable_block(start, bitmap_bh, end); |
---|
702 | 687 | if (grp_goal < 0) |
---|
.. | .. |
---|
711 | 696 | ; |
---|
712 | 697 | } |
---|
713 | 698 | } |
---|
714 | | - start = grp_goal; |
---|
715 | 699 | |
---|
716 | | - if (ext2_set_bit_atomic(sb_bgl_lock(EXT2_SB(sb), group), grp_goal, |
---|
717 | | - bitmap_bh->b_data)) { |
---|
718 | | - /* |
---|
719 | | - * The block was allocated by another thread, or it was |
---|
720 | | - * allocated and then freed by another thread |
---|
721 | | - */ |
---|
722 | | - start++; |
---|
723 | | - grp_goal++; |
---|
724 | | - if (start >= end) |
---|
725 | | - goto fail_access; |
---|
726 | | - goto repeat; |
---|
727 | | - } |
---|
728 | | - num++; |
---|
729 | | - grp_goal++; |
---|
730 | | - while (num < *count && grp_goal < end |
---|
731 | | - && !ext2_set_bit_atomic(sb_bgl_lock(EXT2_SB(sb), group), |
---|
| 700 | + for (; num < *count && grp_goal < end; grp_goal++) { |
---|
| 701 | + if (ext2_set_bit_atomic(sb_bgl_lock(EXT2_SB(sb), group), |
---|
732 | 702 | grp_goal, bitmap_bh->b_data)) { |
---|
| 703 | + if (num == 0) |
---|
| 704 | + continue; |
---|
| 705 | + break; |
---|
| 706 | + } |
---|
733 | 707 | num++; |
---|
734 | | - grp_goal++; |
---|
735 | 708 | } |
---|
| 709 | + |
---|
| 710 | + if (num == 0) |
---|
| 711 | + goto fail_access; |
---|
| 712 | + |
---|
736 | 713 | *count = num; |
---|
737 | 714 | return grp_goal - num; |
---|
738 | 715 | fail_access: |
---|
739 | | - *count = num; |
---|
740 | 716 | return -1; |
---|
741 | 717 | } |
---|
742 | 718 | |
---|
.. | .. |
---|
754 | 730 | * but we will shift to the place where start_block is, |
---|
755 | 731 | * then start from there, when looking for a reservable space. |
---|
756 | 732 | * |
---|
757 | | - * @size: the target new reservation window size |
---|
| 733 | + * @sb: the super block. |
---|
758 | 734 | * |
---|
759 | | - * @group_first_block: the first block we consider to start |
---|
760 | | - * the real search from |
---|
| 735 | + * @start_block: the first block we consider to start the real search from |
---|
761 | 736 | * |
---|
762 | 737 | * @last_block: |
---|
763 | 738 | * the maximum block number that our goal reservable space |
---|
.. | .. |
---|
882 | 857 | * |
---|
883 | 858 | * failed: we failed to find a reservation window in this group |
---|
884 | 859 | * |
---|
885 | | - * @rsv: the reservation |
---|
| 860 | + * @my_rsv: the reservation |
---|
886 | 861 | * |
---|
887 | 862 | * @grp_goal: The goal (group-relative). It is where the search for a |
---|
888 | 863 | * free reservable space should start from. |
---|
.. | .. |
---|
908 | 883 | spinlock_t *rsv_lock = &EXT2_SB(sb)->s_rsv_window_lock; |
---|
909 | 884 | |
---|
910 | 885 | group_first_block = ext2_group_first_block_no(sb, group); |
---|
911 | | - group_end_block = group_first_block + (EXT2_BLOCKS_PER_GROUP(sb) - 1); |
---|
| 886 | + group_end_block = ext2_group_last_block_no(sb, group); |
---|
912 | 887 | |
---|
913 | 888 | if (grp_goal < 0) |
---|
914 | 889 | start_block = group_first_block; |
---|
.. | .. |
---|
1115 | 1090 | * first block is the block number of the first block in this group |
---|
1116 | 1091 | */ |
---|
1117 | 1092 | group_first_block = ext2_group_first_block_no(sb, group); |
---|
1118 | | - group_last_block = group_first_block + (EXT2_BLOCKS_PER_GROUP(sb) - 1); |
---|
| 1093 | + group_last_block = ext2_group_last_block_no(sb, group); |
---|
1119 | 1094 | |
---|
1120 | 1095 | /* |
---|
1121 | 1096 | * Basically we will allocate a new block from inode's reservation |
---|
.. | .. |
---|
1195 | 1170 | |
---|
1196 | 1171 | /* |
---|
1197 | 1172 | * Returns 1 if the passed-in block region is valid; 0 if some part overlaps |
---|
1198 | | - * with filesystem metadata blocksi. |
---|
| 1173 | + * with filesystem metadata blocks. |
---|
1199 | 1174 | */ |
---|
1200 | 1175 | int ext2_data_block_valid(struct ext2_sb_info *sbi, ext2_fsblk_t start_blk, |
---|
1201 | 1176 | unsigned int count) |
---|
1202 | 1177 | { |
---|
1203 | 1178 | if ((start_blk <= le32_to_cpu(sbi->s_es->s_first_data_block)) || |
---|
1204 | | - (start_blk + count < start_blk) || |
---|
1205 | | - (start_blk > le32_to_cpu(sbi->s_es->s_blocks_count))) |
---|
| 1179 | + (start_blk + count - 1 < start_blk) || |
---|
| 1180 | + (start_blk + count - 1 >= le32_to_cpu(sbi->s_es->s_blocks_count))) |
---|
1206 | 1181 | return 0; |
---|
1207 | 1182 | |
---|
1208 | 1183 | /* Ensure we do not step over superblock */ |
---|
1209 | 1184 | if ((start_blk <= sbi->s_sb_block) && |
---|
1210 | | - (start_blk + count >= sbi->s_sb_block)) |
---|
| 1185 | + (start_blk + count - 1 >= sbi->s_sb_block)) |
---|
1211 | 1186 | return 0; |
---|
1212 | | - |
---|
1213 | 1187 | |
---|
1214 | 1188 | return 1; |
---|
1215 | 1189 | } |
---|
.. | .. |
---|
1314 | 1288 | if (free_blocks > 0) { |
---|
1315 | 1289 | grp_target_blk = ((goal - le32_to_cpu(es->s_first_data_block)) % |
---|
1316 | 1290 | EXT2_BLOCKS_PER_GROUP(sb)); |
---|
| 1291 | + /* |
---|
| 1292 | + * In case we retry allocation (due to fs reservation not |
---|
| 1293 | + * working out or fs corruption), the bitmap_bh is non-null |
---|
| 1294 | + * pointer and we have to release it before calling |
---|
| 1295 | + * read_block_bitmap(). |
---|
| 1296 | + */ |
---|
| 1297 | + brelse(bitmap_bh); |
---|
1317 | 1298 | bitmap_bh = read_block_bitmap(sb, group_no); |
---|
1318 | 1299 | if (!bitmap_bh) |
---|
1319 | 1300 | goto io_error; |
---|
.. | .. |
---|
1405 | 1386 | * use. So we may want to selectively mark some of the blocks |
---|
1406 | 1387 | * as free |
---|
1407 | 1388 | */ |
---|
| 1389 | + num = *count; |
---|
1408 | 1390 | goto retry_alloc; |
---|
1409 | 1391 | } |
---|
1410 | 1392 | |
---|