X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=fs%2Fext2%2Fballoc.c;h=79a7c63108132e31d82e43709d615a2e99999d9e;hb=97bf2856c6014879bd04983a3e9dfcdac1e7fe85;hp=7b776af84f62849380f162a10e52d619c8ffb701;hpb=9213980e6a70d8473e0ffd4b39ab5b6caaba9ff5;p=linux-2.6.git diff --git a/fs/ext2/balloc.c b/fs/ext2/balloc.c index 7b776af84..79a7c6310 100644 --- a/fs/ext2/balloc.c +++ b/fs/ext2/balloc.c @@ -6,18 +6,18 @@ * Laboratoire MASI - Institut Blaise Pascal * Universite Pierre et Marie Curie (Paris VI) * - * Enhanced block allocation by Stephen Tweedie (sct@dcs.ed.ac.uk), 1993 + * Enhanced block allocation by Stephen Tweedie (sct@redhat.com), 1993 * Big-endian to little-endian byte-swapping/bitmaps by * David S. Miller (davem@caip.rutgers.edu), 1995 */ -#include #include "ext2.h" #include #include #include -#include +#include #include +#include /* * balloc.c contains the blocks allocation and deallocation routines @@ -54,9 +54,9 @@ struct ext2_group_desc * ext2_get_group_desc(struct super_block * sb, return NULL; } - - group_desc = block_group / EXT2_DESC_PER_BLOCK(sb); - offset = block_group % EXT2_DESC_PER_BLOCK(sb); + + group_desc = block_group >> EXT2_DESC_PER_BLOCK_BITS(sb); + offset = block_group & (EXT2_DESC_PER_BLOCK(sb) - 1); if (!sbi->s_group_desc[group_desc]) { ext2_error (sb, "ext2_get_group_desc", "Group descriptor not loaded - " @@ -64,7 +64,7 @@ struct ext2_group_desc * ext2_get_group_desc(struct super_block * sb, block_group, group_desc, offset); return NULL; } - + desc = (struct ext2_group_desc *) sbi->s_group_desc[group_desc]->b_data; if (bh) *bh = sbi->s_group_desc[group_desc]; @@ -90,8 +90,8 @@ read_block_bitmap(struct super_block *sb, unsigned int block_group) if (!bh) ext2_error (sb, "read_block_bitmap", "Cannot read block bitmap - " - "block_group = %d, block_bitmap = %lu", - block_group, (unsigned long) desc->bg_block_bitmap); + "block_group = %d, block_bitmap = %u", + block_group, le32_to_cpu(desc->bg_block_bitmap)); error_out: return bh; } @@ -104,13 +104,12 @@ static int reserve_blocks(struct super_block *sb, int count) { struct ext2_sb_info *sbi = EXT2_SB(sb); struct ext2_super_block *es = sbi->s_es; - unsigned free_blocks; - unsigned root_blocks; + unsigned long long free_blocks, root_blocks; free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter); root_blocks = le32_to_cpu(es->s_r_blocks_count); - DLIMIT_ADJUST_BLOCK(sb, vx_current_xid(), &free_blocks, &root_blocks); + DLIMIT_ADJUST_BLOCK(sb, dx_current_tag(), &free_blocks, &root_blocks); if (free_blocks < count) count = free_blocks; @@ -240,12 +239,12 @@ do_more: for (i = 0, group_freed = 0; i < count; i++) { if (!ext2_clear_bit_atomic(sb_bgl_lock(sbi, block_group), - bit + i, (void *) bitmap_bh->b_data)) - ext2_error (sb, "ext2_free_blocks", - "bit already cleared for block %lu", - block + i); - else + bit + i, bitmap_bh->b_data)) { + ext2_error(sb, __FUNCTION__, + "bit already cleared for block %lu", block + i); + } else { group_freed++; + } } mark_buffer_dirty(bitmap_bh); @@ -262,7 +261,7 @@ do_more: } error_return: brelse(bitmap_bh); - DLIMIT_FREE_BLOCK(sb, inode->i_xid, freed); + DLIMIT_FREE_BLOCK(inode, freed); release_blocks(sb, freed); DQUOT_FREE_BLOCK(inode, freed); } @@ -366,7 +365,7 @@ int ext2_new_block(struct inode *inode, unsigned long goal, *err = -ENOSPC; goto out_dquot; } - if (DLIMIT_ALLOC_BLOCK(sb, inode->i_xid, es_alloc)) { + if (DLIMIT_ALLOC_BLOCK(inode, es_alloc)) { *err = -ENOSPC; goto out_dlimit; } @@ -517,7 +516,7 @@ got_block: *err = 0; out_release: group_release_blocks(sb, group_no, desc, gdp_bh, group_alloc); - DLIMIT_FREE_BLOCK(sb, inode->i_xid, es_alloc); + DLIMIT_FREE_BLOCK(inode, es_alloc); out_dlimit: release_blocks(sb, es_alloc); out_dquot: @@ -531,6 +530,25 @@ io_error: goto out_release; } +#ifdef EXT2FS_DEBUG + +static int nibblemap[] = {4, 3, 3, 2, 3, 2, 2, 1, 3, 2, 2, 1, 2, 1, 1, 0}; + +unsigned long ext2_count_free (struct buffer_head * map, unsigned int numchars) +{ + unsigned int i; + unsigned long sum = 0; + + if (!map) + return (0); + for (i = 0; i < numchars; i++) + sum += nibblemap[map->b_data[i] & 0xf] + + nibblemap[(map->b_data[i] >> 4) & 0xf]; + return (sum); +} + +#endif /* EXT2FS_DEBUG */ + unsigned long ext2_count_free_blocks (struct super_block * sb) { struct ext2_group_desc * desc; @@ -540,7 +558,6 @@ unsigned long ext2_count_free_blocks (struct super_block * sb) unsigned long bitmap_count, x; struct ext2_super_block *es; - lock_super (sb); es = EXT2_SB(sb)->s_es; desc_count = 0; bitmap_count = 0; @@ -564,7 +581,6 @@ unsigned long ext2_count_free_blocks (struct super_block * sb) printk("ext2_count_free_blocks: stored = %lu, computed = %lu, %lu\n", (long)le32_to_cpu(es->s_free_blocks_count), desc_count, bitmap_count); - unlock_super (sb); return bitmap_count; #else for (i = 0; i < EXT2_SB(sb)->s_groups_count; i++) { @@ -580,25 +596,24 @@ unsigned long ext2_count_free_blocks (struct super_block * sb) static inline int block_in_use(unsigned long block, struct super_block *sb, unsigned char *map) { - return ext2_test_bit ((block - le32_to_cpu(EXT2_SB(sb)->s_es->s_first_data_block)) % + return ext2_test_bit ((block - + le32_to_cpu(EXT2_SB(sb)->s_es->s_first_data_block)) % EXT2_BLOCKS_PER_GROUP(sb), map); } static inline int test_root(int a, int b) { - if (a == 0) - return 1; - while (1) { - if (a == 1) - return 1; - if (a % b) - return 0; - a = a / b; - } + int num = b; + + while (a > num) + num *= b; + return num == a; } static int ext2_group_sparse(int group) { + if (group <= 1) + return 1; return (test_root(group, 3) || test_root(group, 5) || test_root(group, 7)); } @@ -636,76 +651,3 @@ unsigned long ext2_bg_num_gdb(struct super_block *sb, int group) return EXT2_SB(sb)->s_gdb_count; } -#ifdef CONFIG_EXT2_CHECK -/* Called at mount-time, super-block is locked */ -void ext2_check_blocks_bitmap (struct super_block * sb) -{ - struct buffer_head *bitmap_bh = NULL; - struct ext2_super_block * es; - unsigned long desc_count, bitmap_count, x, j; - unsigned long desc_blocks; - struct ext2_group_desc * desc; - int i; - - es = EXT2_SB(sb)->s_es; - desc_count = 0; - bitmap_count = 0; - desc = NULL; - for (i = 0; i < EXT2_SB(sb)->s_groups_count; i++) { - desc = ext2_get_group_desc (sb, i, NULL); - if (!desc) - continue; - desc_count += le16_to_cpu(desc->bg_free_blocks_count); - brelse(bitmap_bh); - bitmap_bh = read_block_bitmap(sb, i); - if (!bitmap_bh) - continue; - - if (ext2_bg_has_super(sb, i) && - !ext2_test_bit(0, bitmap_bh->b_data)) - ext2_error(sb, __FUNCTION__, - "Superblock in group %d is marked free", i); - - desc_blocks = ext2_bg_num_gdb(sb, i); - for (j = 0; j < desc_blocks; j++) - if (!ext2_test_bit(j + 1, bitmap_bh->b_data)) - ext2_error(sb, __FUNCTION__, - "Descriptor block #%ld in group " - "%d is marked free", j, i); - - if (!block_in_use(le32_to_cpu(desc->bg_block_bitmap), - sb, bitmap_bh->b_data)) - ext2_error(sb, "ext2_check_blocks_bitmap", - "Block bitmap for group %d is marked free", - i); - - if (!block_in_use(le32_to_cpu(desc->bg_inode_bitmap), - sb, bitmap_bh->b_data)) - ext2_error(sb, "ext2_check_blocks_bitmap", - "Inode bitmap for group %d is marked free", - i); - - for (j = 0; j < EXT2_SB(sb)->s_itb_per_group; j++) - if (!block_in_use(le32_to_cpu(desc->bg_inode_table) + j, - sb, bitmap_bh->b_data)) - ext2_error (sb, "ext2_check_blocks_bitmap", - "Block #%ld of the inode table in " - "group %d is marked free", j, i); - - x = ext2_count_free(bitmap_bh, sb->s_blocksize); - if (le16_to_cpu(desc->bg_free_blocks_count) != x) - ext2_error (sb, "ext2_check_blocks_bitmap", - "Wrong free blocks count for group %d, " - "stored = %d, counted = %lu", i, - le16_to_cpu(desc->bg_free_blocks_count), x); - bitmap_count += x; - } - if (le32_to_cpu(es->s_free_blocks_count) != bitmap_count) - ext2_error (sb, "ext2_check_blocks_bitmap", - "Wrong free blocks count in super block, " - "stored = %lu, counted = %lu", - (unsigned long)le32_to_cpu(es->s_free_blocks_count), - bitmap_count); - brelse(bitmap_bh); -} -#endif