* balloc.c contains the blocks allocation and deallocation routines
*/
+/*
+ * Calculate the block group number and offset, given a block number
+ */
+void ext4_get_group_no_and_offset(struct super_block *sb, ext4_fsblk_t blocknr,
+ unsigned long *blockgrpp, ext4_grpblk_t *offsetp)
+{
+ struct ext4_super_block *es = EXT4_SB(sb)->s_es;
+ ext4_grpblk_t offset;
+
+ blocknr = blocknr - le32_to_cpu(es->s_first_data_block);
+ offset = do_div(blocknr, EXT4_BLOCKS_PER_GROUP(sb));
+ if (offsetp)
+ *offsetp = offset;
+ if (blockgrpp)
+ *blockgrpp = blocknr;
+
+}
+
/*
* The free blocks are managed by bitmaps. A file system contains several
* blocks groups. Each group contains 1 bitmap block for blocks, 1 bitmap
desc = ext4_get_group_desc (sb, block_group, NULL);
if (!desc)
goto error_out;
- bh = sb_bread(sb, ext4_block_bitmap(desc));
+ bh = sb_bread(sb, ext4_block_bitmap(sb, desc));
if (!bh)
ext4_error (sb, "read_block_bitmap",
"Cannot read block bitmap - "
"block_group = %d, block_bitmap = %llu",
block_group,
- ext4_block_bitmap(desc));
+ ext4_block_bitmap(sb, desc));
error_out:
return bh;
}
if (!desc)
goto error_return;
- if (in_range(ext4_block_bitmap(desc), block, count) ||
- in_range(ext4_inode_bitmap(desc), block, count) ||
- in_range(block, ext4_inode_table(desc), sbi->s_itb_per_group) ||
- in_range(block + count - 1, ext4_inode_table(desc),
+ if (in_range(ext4_block_bitmap(sb, desc), block, count) ||
+ in_range(ext4_inode_bitmap(sb, desc), block, count) ||
+ in_range(block, ext4_inode_table(sb, desc), sbi->s_itb_per_group) ||
+ in_range(block + count - 1, ext4_inode_table(sb, desc),
sbi->s_itb_per_group))
ext4_error (sb, "ext4_free_blocks",
"Freeing blocks in system zones - "
if (!goal_in_my_reservation(&my_rsv->rsv_window,
grp_goal, group, sb))
grp_goal = -1;
- } else if (grp_goal > 0 &&
- (my_rsv->rsv_end-grp_goal+1) < *count)
- try_to_extend_reservation(my_rsv, sb,
- *count-my_rsv->rsv_end + grp_goal - 1);
+ } else if (grp_goal > 0) {
+ int curr = my_rsv->rsv_end -
+ (grp_goal + group_first_block) + 1;
+
+ if (curr < *count)
+ try_to_extend_reservation(my_rsv, sb,
+ *count - curr);
+ }
if ((my_rsv->rsv_start > group_last_block) ||
(my_rsv->rsv_end < group_first_block)) {
ret_block = grp_alloc_blk + ext4_group_first_block_no(sb, group_no);
- if (in_range(ext4_block_bitmap(gdp), ret_block, num) ||
- in_range(ext4_block_bitmap(gdp), ret_block, num) ||
- in_range(ret_block, ext4_inode_table(gdp),
+ if (in_range(ext4_block_bitmap(sb, gdp), ret_block, num) ||
+ in_range(ext4_block_bitmap(sb, gdp), ret_block, num) ||
+ in_range(ret_block, ext4_inode_table(sb, gdp),
EXT4_SB(sb)->s_itb_per_group) ||
- in_range(ret_block + num - 1, ext4_inode_table(gdp),
+ in_range(ret_block + num - 1, ext4_inode_table(sb, gdp),
EXT4_SB(sb)->s_itb_per_group))
ext4_error(sb, "ext4_new_block",
"Allocating block in system zone - "