aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext2/balloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ext2/balloc.c')
-rw-r--r--fs/ext2/balloc.c98
1 files changed, 81 insertions, 17 deletions
diff --git a/fs/ext2/balloc.c b/fs/ext2/balloc.c
index 377ad172d74b..e7b2bafa1dd9 100644
--- a/fs/ext2/balloc.c
+++ b/fs/ext2/balloc.c
@@ -69,9 +69,53 @@ struct ext2_group_desc * ext2_get_group_desc(struct super_block * sb,
69 return desc + offset; 69 return desc + offset;
70} 70}
71 71
72static int ext2_valid_block_bitmap(struct super_block *sb,
73 struct ext2_group_desc *desc,
74 unsigned int block_group,
75 struct buffer_head *bh)
76{
77 ext2_grpblk_t offset;
78 ext2_grpblk_t next_zero_bit;
79 ext2_fsblk_t bitmap_blk;
80 ext2_fsblk_t group_first_block;
81
82 group_first_block = ext2_group_first_block_no(sb, block_group);
83
84 /* check whether block bitmap block number is set */
85 bitmap_blk = le32_to_cpu(desc->bg_block_bitmap);
86 offset = bitmap_blk - group_first_block;
87 if (!ext2_test_bit(offset, bh->b_data))
88 /* bad block bitmap */
89 goto err_out;
90
91 /* check whether the inode bitmap block number is set */
92 bitmap_blk = le32_to_cpu(desc->bg_inode_bitmap);
93 offset = bitmap_blk - group_first_block;
94 if (!ext2_test_bit(offset, bh->b_data))
95 /* bad block bitmap */
96 goto err_out;
97
98 /* check whether the inode table block number is set */
99 bitmap_blk = le32_to_cpu(desc->bg_inode_table);
100 offset = bitmap_blk - group_first_block;
101 next_zero_bit = ext2_find_next_zero_bit(bh->b_data,
102 offset + EXT2_SB(sb)->s_itb_per_group,
103 offset);
104 if (next_zero_bit >= offset + EXT2_SB(sb)->s_itb_per_group)
105 /* good bitmap for inode tables */
106 return 1;
107
108err_out:
109 ext2_error(sb, __FUNCTION__,
110 "Invalid block bitmap - "
111 "block_group = %d, block = %lu",
112 block_group, bitmap_blk);
113 return 0;
114}
115
72/* 116/*
73 * Read the bitmap for a given block_group, reading into the specified 117 * Read the bitmap for a given block_group,and validate the
74 * slot in the superblock's bitmap cache. 118 * bits for block/inode/inode tables are set in the bitmaps
75 * 119 *
76 * Return buffer_head on success or NULL in case of failure. 120 * Return buffer_head on success or NULL in case of failure.
77 */ 121 */
@@ -80,17 +124,36 @@ read_block_bitmap(struct super_block *sb, unsigned int block_group)
80{ 124{
81 struct ext2_group_desc * desc; 125 struct ext2_group_desc * desc;
82 struct buffer_head * bh = NULL; 126 struct buffer_head * bh = NULL;
83 127 ext2_fsblk_t bitmap_blk;
84 desc = ext2_get_group_desc (sb, block_group, NULL); 128
129 desc = ext2_get_group_desc(sb, block_group, NULL);
85 if (!desc) 130 if (!desc)
86 goto error_out; 131 return NULL;
87 bh = sb_bread(sb, le32_to_cpu(desc->bg_block_bitmap)); 132 bitmap_blk = le32_to_cpu(desc->bg_block_bitmap);
88 if (!bh) 133 bh = sb_getblk(sb, bitmap_blk);
89 ext2_error (sb, "read_block_bitmap", 134 if (unlikely(!bh)) {
135 ext2_error(sb, __FUNCTION__,
136 "Cannot read block bitmap - "
137 "block_group = %d, block_bitmap = %u",
138 block_group, le32_to_cpu(desc->bg_block_bitmap));
139 return NULL;
140 }
141 if (likely(bh_uptodate_or_lock(bh)))
142 return bh;
143
144 if (bh_submit_read(bh) < 0) {
145 brelse(bh);
146 ext2_error(sb, __FUNCTION__,
90 "Cannot read block bitmap - " 147 "Cannot read block bitmap - "
91 "block_group = %d, block_bitmap = %u", 148 "block_group = %d, block_bitmap = %u",
92 block_group, le32_to_cpu(desc->bg_block_bitmap)); 149 block_group, le32_to_cpu(desc->bg_block_bitmap));
93error_out: 150 return NULL;
151 }
152 if (!ext2_valid_block_bitmap(sb, desc, block_group, bh)) {
153 brelse(bh);
154 return NULL;
155 }
156
94 return bh; 157 return bh;
95} 158}
96 159
@@ -474,11 +537,13 @@ do_more:
474 in_range (block, le32_to_cpu(desc->bg_inode_table), 537 in_range (block, le32_to_cpu(desc->bg_inode_table),
475 sbi->s_itb_per_group) || 538 sbi->s_itb_per_group) ||
476 in_range (block + count - 1, le32_to_cpu(desc->bg_inode_table), 539 in_range (block + count - 1, le32_to_cpu(desc->bg_inode_table),
477 sbi->s_itb_per_group)) 540 sbi->s_itb_per_group)) {
478 ext2_error (sb, "ext2_free_blocks", 541 ext2_error (sb, "ext2_free_blocks",
479 "Freeing blocks in system zones - " 542 "Freeing blocks in system zones - "
480 "Block = %lu, count = %lu", 543 "Block = %lu, count = %lu",
481 block, count); 544 block, count);
545 goto error_return;
546 }
482 547
483 for (i = 0, group_freed = 0; i < count; i++) { 548 for (i = 0, group_freed = 0; i < count; i++) {
484 if (!ext2_clear_bit_atomic(sb_bgl_lock(sbi, block_group), 549 if (!ext2_clear_bit_atomic(sb_bgl_lock(sbi, block_group),
@@ -1250,8 +1315,8 @@ retry_alloc:
1250 smp_rmb(); 1315 smp_rmb();
1251 1316
1252 /* 1317 /*
1253 * Now search the rest of the groups. We assume that 1318 * Now search the rest of the groups. We assume that
1254 * i and gdp correctly point to the last group visited. 1319 * group_no and gdp correctly point to the last group visited.
1255 */ 1320 */
1256 for (bgi = 0; bgi < ngroups; bgi++) { 1321 for (bgi = 0; bgi < ngroups; bgi++) {
1257 group_no++; 1322 group_no++;
@@ -1311,11 +1376,13 @@ allocated:
1311 in_range(ret_block, le32_to_cpu(gdp->bg_inode_table), 1376 in_range(ret_block, le32_to_cpu(gdp->bg_inode_table),
1312 EXT2_SB(sb)->s_itb_per_group) || 1377 EXT2_SB(sb)->s_itb_per_group) ||
1313 in_range(ret_block + num - 1, le32_to_cpu(gdp->bg_inode_table), 1378 in_range(ret_block + num - 1, le32_to_cpu(gdp->bg_inode_table),
1314 EXT2_SB(sb)->s_itb_per_group)) 1379 EXT2_SB(sb)->s_itb_per_group)) {
1315 ext2_error(sb, "ext2_new_blocks", 1380 ext2_error(sb, "ext2_new_blocks",
1316 "Allocating block in system zone - " 1381 "Allocating block in system zone - "
1317 "blocks from "E2FSBLK", length %lu", 1382 "blocks from "E2FSBLK", length %lu",
1318 ret_block, num); 1383 ret_block, num);
1384 goto out;
1385 }
1319 1386
1320 performed_allocation = 1; 1387 performed_allocation = 1;
1321 1388
@@ -1466,9 +1533,6 @@ int ext2_bg_has_super(struct super_block *sb, int group)
1466 */ 1533 */
1467unsigned long ext2_bg_num_gdb(struct super_block *sb, int group) 1534unsigned long ext2_bg_num_gdb(struct super_block *sb, int group)
1468{ 1535{
1469 if (EXT2_HAS_RO_COMPAT_FEATURE(sb,EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER)&& 1536 return ext2_bg_has_super(sb, group) ? EXT2_SB(sb)->s_gdb_count : 0;
1470 !ext2_group_sparse(group))
1471 return 0;
1472 return EXT2_SB(sb)->s_gdb_count;
1473} 1537}
1474 1538