Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 273110
b: refs/heads/master
c: fd034a8
h: refs/heads/master
v: v3
  • Loading branch information
Theodore Ts'o committed Sep 9, 2011
1 parent 58f8328 commit bfc03e2
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 73 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 49f7f9af4bb4d7972f3a35a74877937fec9f622d
refs/heads/master: fd034a84e1ea5c8c8d159cd2089c32e792c269b0
105 changes: 52 additions & 53 deletions trunk/fs/ext4/balloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,74 +102,73 @@ static unsigned int num_blocks_in_group(struct super_block *sb,
return EXT4_BLOCKS_PER_GROUP(sb);
}

/* Initializes an uninitialized block bitmap if given, and returns the
* number of blocks free in the group. */
unsigned ext4_init_block_bitmap(struct super_block *sb, struct buffer_head *bh,
ext4_group_t block_group, struct ext4_group_desc *gdp)
/* Initializes an uninitialized block bitmap */
void ext4_init_block_bitmap(struct super_block *sb, struct buffer_head *bh,
ext4_group_t block_group,
struct ext4_group_desc *gdp)
{
unsigned int bit, bit_max = num_base_meta_blocks(sb, block_group);
ext4_group_t ngroups = ext4_get_groups_count(sb);
unsigned group_blocks = num_blocks_in_group(sb, block_group);
struct ext4_sb_info *sbi = EXT4_SB(sb);

if (bh) {
J_ASSERT_BH(bh, buffer_locked(bh));

/* If checksum is bad mark all blocks used to prevent allocation
* essentially implementing a per-group read-only flag. */
if (!ext4_group_desc_csum_verify(sbi, block_group, gdp)) {
ext4_error(sb, "Checksum bad for group %u",
block_group);
ext4_free_blks_set(sb, gdp, 0);
ext4_free_inodes_set(sb, gdp, 0);
ext4_itable_unused_set(sb, gdp, 0);
memset(bh->b_data, 0xff, sb->s_blocksize);
return 0;
}
memset(bh->b_data, 0, sb->s_blocksize);
ext4_fsblk_t start, tmp;
int flex_bg = 0;

J_ASSERT_BH(bh, buffer_locked(bh));

/* If checksum is bad mark all blocks used to prevent allocation
* essentially implementing a per-group read-only flag. */
if (!ext4_group_desc_csum_verify(sbi, block_group, gdp)) {
ext4_error(sb, "Checksum bad for group %u", block_group);
ext4_free_blks_set(sb, gdp, 0);
ext4_free_inodes_set(sb, gdp, 0);
ext4_itable_unused_set(sb, gdp, 0);
memset(bh->b_data, 0xff, sb->s_blocksize);
return;
}
memset(bh->b_data, 0, sb->s_blocksize);

if (bh) {
ext4_fsblk_t start, tmp;
int flex_bg = 0;
for (bit = 0; bit < bit_max; bit++)
ext4_set_bit(bit, bh->b_data);

for (bit = 0; bit < bit_max; bit++)
ext4_set_bit(bit, bh->b_data);
start = ext4_group_first_block_no(sb, block_group);

start = ext4_group_first_block_no(sb, block_group);
if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FLEX_BG))
flex_bg = 1;

if (EXT4_HAS_INCOMPAT_FEATURE(sb,
EXT4_FEATURE_INCOMPAT_FLEX_BG))
flex_bg = 1;
/* Set bits for block and inode bitmaps, and inode table */
tmp = ext4_block_bitmap(sb, gdp);
if (!flex_bg || ext4_block_in_group(sb, tmp, block_group))
ext4_set_bit(tmp - start, bh->b_data);

/* Set bits for block and inode bitmaps, and inode table */
tmp = ext4_block_bitmap(sb, gdp);
if (!flex_bg || ext4_block_in_group(sb, tmp, block_group))
ext4_set_bit(tmp - start, bh->b_data);
tmp = ext4_inode_bitmap(sb, gdp);
if (!flex_bg || ext4_block_in_group(sb, tmp, block_group))
ext4_set_bit(tmp - start, bh->b_data);

tmp = ext4_inode_bitmap(sb, gdp);
tmp = ext4_inode_table(sb, gdp);
for (; tmp < ext4_inode_table(sb, gdp) +
sbi->s_itb_per_group; tmp++) {
if (!flex_bg || ext4_block_in_group(sb, tmp, block_group))
ext4_set_bit(tmp - start, bh->b_data);

tmp = ext4_inode_table(sb, gdp);
for (; tmp < ext4_inode_table(sb, gdp) +
sbi->s_itb_per_group; tmp++) {
if (!flex_bg ||
ext4_block_in_group(sb, tmp, block_group))
ext4_set_bit(tmp - start, bh->b_data);
}
/*
* Also if the number of blocks within the group is
* less than the blocksize * 8 ( which is the size
* of bitmap ), set rest of the block bitmap to 1
*/
ext4_mark_bitmap_end(group_blocks, sb->s_blocksize * 8,
bh->b_data);
}
return group_blocks - bit_max -
ext4_group_used_meta_blocks(sb, block_group, gdp);
/*
* Also if the number of blocks within the group is less than
* the blocksize * 8 ( which is the size of bitmap ), set rest
* of the block bitmap to 1
*/
ext4_mark_bitmap_end(num_blocks_in_group(sb, block_group),
sb->s_blocksize * 8, bh->b_data);
}

/* Return the number of free blocks in a block group. It is used when
* the block bitmap is uninitialized, so we can't just count the bits
* in the bitmap. */
unsigned ext4_free_blocks_after_init(struct super_block *sb,
ext4_group_t block_group,
struct ext4_group_desc *gdp)
{
return num_blocks_in_group(sb, block_group) -
num_base_meta_blocks(sb, block_group) -
ext4_group_used_meta_blocks(sb, block_group, gdp);
}

/*
* The free blocks are managed by bitmaps. A file system contains several
Expand Down
13 changes: 7 additions & 6 deletions trunk/fs/ext4/ext4.h
Original file line number Diff line number Diff line change
Expand Up @@ -1763,12 +1763,13 @@ extern struct ext4_group_desc * ext4_get_group_desc(struct super_block * sb,
extern int ext4_should_retry_alloc(struct super_block *sb, int *retries);
struct buffer_head *ext4_read_block_bitmap(struct super_block *sb,
ext4_group_t block_group);
extern unsigned ext4_init_block_bitmap(struct super_block *sb,
struct buffer_head *bh,
ext4_group_t group,
struct ext4_group_desc *desc);
#define ext4_free_blocks_after_init(sb, group, desc) \
ext4_init_block_bitmap(sb, NULL, group, desc)
extern void ext4_init_block_bitmap(struct super_block *sb,
struct buffer_head *bh,
ext4_group_t group,
struct ext4_group_desc *desc);
extern unsigned ext4_free_blocks_after_init(struct super_block *sb,
ext4_group_t block_group,
struct ext4_group_desc *gdp);
ext4_fsblk_t ext4_inode_to_goal_block(struct inode *);

/* dir.c */
Expand Down
20 changes: 7 additions & 13 deletions trunk/fs/ext4/ialloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -816,7 +816,6 @@ struct inode *ext4_new_inode(handle_t *handle, struct inode *dir, int mode,
int ret2, err = 0;
struct inode *ret;
ext4_group_t i;
int free = 0;
static int once = 1;
ext4_group_t flex_group;

Expand Down Expand Up @@ -950,26 +949,21 @@ struct inode *ext4_new_inode(handle_t *handle, struct inode *dir, int mode,
goto fail;
}

free = 0;
ext4_lock_group(sb, group);
BUFFER_TRACE(block_bitmap_bh, "dirty block bitmap");
err = ext4_handle_dirty_metadata(handle, NULL, block_bitmap_bh);
brelse(block_bitmap_bh);

/* recheck and clear flag under lock if we still need to */
ext4_lock_group(sb, group);
if (gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) {
free = ext4_free_blocks_after_init(sb, group, gdp);
gdp->bg_flags &= cpu_to_le16(~EXT4_BG_BLOCK_UNINIT);
ext4_free_blks_set(sb, gdp, free);
ext4_free_blks_set(sb, gdp,
ext4_free_blocks_after_init(sb, group, gdp));
gdp->bg_checksum = ext4_group_desc_csum(sbi, group,
gdp);
}
ext4_unlock_group(sb, group);

/* Don't need to dirty bitmap block if we didn't change it */
if (free) {
BUFFER_TRACE(block_bitmap_bh, "dirty block bitmap");
err = ext4_handle_dirty_metadata(handle,
NULL, block_bitmap_bh);
}

brelse(block_bitmap_bh);
if (err)
goto fail;
}
Expand Down

0 comments on commit bfc03e2

Please sign in to comment.