hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/fs/ext2/balloc.c
....@@ -187,7 +187,7 @@
187187
188188 /**
189189 * __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
191191 * @verbose: verbose mode
192192 * @fn: function which wishes to dump the reservation map
193193 *
....@@ -267,7 +267,7 @@
267267 ext2_fsblk_t group_first_block, group_last_block;
268268
269269 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);
271271
272272 if ((rsv->_rsv_start > group_last_block) ||
273273 (rsv->_rsv_end < group_first_block))
....@@ -280,7 +280,7 @@
280280
281281 /**
282282 * search_reserve_window()
283
- * @rb_root: root of reservation tree
283
+ * @root: root of reservation tree
284284 * @goal: target allocation block
285285 *
286286 * Find the reserved window which includes the goal, or the previous one
....@@ -488,9 +488,7 @@
488488 struct ext2_super_block * es = sbi->s_es;
489489 unsigned freed = 0, group_freed;
490490
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)) {
494492 ext2_error (sb, "ext2_free_blocks",
495493 "Freeing blocks not in datazone - "
496494 "block = %lu, count = %lu", block, count);
....@@ -666,37 +664,24 @@
666664 unsigned long *count,
667665 struct ext2_reserve_window *my_rsv)
668666 {
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);
670669 ext2_grpblk_t start, end;
671670 unsigned long num = 0;
672671
672
+ start = 0;
673
+ end = group_last_block - group_first_block + 1;
673674 /* we do allocation within the reservation window if we have a window */
674675 if (my_rsv) {
675
- group_first_block = ext2_group_first_block_no(sb, group);
676676 if (my_rsv->_rsv_start >= group_first_block)
677677 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)
688681 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);
695682 }
696
-
697683 BUG_ON(start > EXT2_BLOCKS_PER_GROUP(sb));
698684
699
-repeat:
700685 if (grp_goal < 0) {
701686 grp_goal = find_next_usable_block(start, bitmap_bh, end);
702687 if (grp_goal < 0)
....@@ -711,32 +696,23 @@
711696 ;
712697 }
713698 }
714
- start = grp_goal;
715699
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),
732702 grp_goal, bitmap_bh->b_data)) {
703
+ if (num == 0)
704
+ continue;
705
+ break;
706
+ }
733707 num++;
734
- grp_goal++;
735708 }
709
+
710
+ if (num == 0)
711
+ goto fail_access;
712
+
736713 *count = num;
737714 return grp_goal - num;
738715 fail_access:
739
- *count = num;
740716 return -1;
741717 }
742718
....@@ -754,10 +730,9 @@
754730 * but we will shift to the place where start_block is,
755731 * then start from there, when looking for a reservable space.
756732 *
757
- * @size: the target new reservation window size
733
+ * @sb: the super block.
758734 *
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
761736 *
762737 * @last_block:
763738 * the maximum block number that our goal reservable space
....@@ -882,7 +857,7 @@
882857 *
883858 * failed: we failed to find a reservation window in this group
884859 *
885
- * @rsv: the reservation
860
+ * @my_rsv: the reservation
886861 *
887862 * @grp_goal: The goal (group-relative). It is where the search for a
888863 * free reservable space should start from.
....@@ -908,7 +883,7 @@
908883 spinlock_t *rsv_lock = &EXT2_SB(sb)->s_rsv_window_lock;
909884
910885 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);
912887
913888 if (grp_goal < 0)
914889 start_block = group_first_block;
....@@ -1115,7 +1090,7 @@
11151090 * first block is the block number of the first block in this group
11161091 */
11171092 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);
11191094
11201095 /*
11211096 * Basically we will allocate a new block from inode's reservation
....@@ -1195,21 +1170,20 @@
11951170
11961171 /*
11971172 * 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.
11991174 */
12001175 int ext2_data_block_valid(struct ext2_sb_info *sbi, ext2_fsblk_t start_blk,
12011176 unsigned int count)
12021177 {
12031178 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)))
12061181 return 0;
12071182
12081183 /* Ensure we do not step over superblock */
12091184 if ((start_blk <= sbi->s_sb_block) &&
1210
- (start_blk + count >= sbi->s_sb_block))
1185
+ (start_blk + count - 1 >= sbi->s_sb_block))
12111186 return 0;
1212
-
12131187
12141188 return 1;
12151189 }
....@@ -1314,6 +1288,13 @@
13141288 if (free_blocks > 0) {
13151289 grp_target_blk = ((goal - le32_to_cpu(es->s_first_data_block)) %
13161290 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);
13171298 bitmap_bh = read_block_bitmap(sb, group_no);
13181299 if (!bitmap_bh)
13191300 goto io_error;
....@@ -1405,6 +1386,7 @@
14051386 * use. So we may want to selectively mark some of the blocks
14061387 * as free
14071388 */
1389
+ num = *count;
14081390 goto retry_alloc;
14091391 }
14101392