From: Andrew Morton Date: Wed, 11 Oct 2006 08:21:19 +0000 (-0700) Subject: [PATCH] ext4 64 bit divide fix X-Git-Tag: v2.6.19-rc2~107 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=f4e5bc244f23ee024a4dfa034b591b219b2bfb8f;p=profile%2Fivi%2Fkernel-x86-ivi.git [PATCH] ext4 64 bit divide fix With CONFIG_LBD=n, sector_div() expands to a plain old divide. But ext4 is _not_ passing in a sector_t as the first argument, so... fs/built-in.o: In function `ext4_get_group_no_and_offset': fs/ext4/balloc.c:39: undefined reference to `__umoddi3' fs/ext4/balloc.c:41: undefined reference to `__udivdi3' fs/built-in.o: In function `find_group_orlov': fs/ext4/ialloc.c:278: undefined reference to `__udivdi3' fs/built-in.o: In function `ext4_fill_super': fs/ext4/super.c:1488: undefined reference to `__udivdi3' fs/ext4/super.c:1488: undefined reference to `__umoddi3' fs/ext4/super.c:1594: undefined reference to `__udivdi3' fs/ext4/super.c:1601: undefined reference to `__umoddi3' Fix that up by calling do_div() directly. Also cast the arg to u64. do_div() is only defined on u64, and ext4_fsblk_t is supposed to be opaque. Note especially the changes to find_group_orlov(). It was attempting to do do_div(int, unsigned long long); which is royally screwed up. Switched it to plain old divide. Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c index 402475a..5d45582 100644 --- a/fs/ext4/balloc.c +++ b/fs/ext4/balloc.c @@ -34,7 +34,7 @@ void ext4_get_group_no_and_offset(struct super_block *sb, ext4_fsblk_t blocknr, ext4_grpblk_t offset; blocknr = blocknr - le32_to_cpu(es->s_first_data_block); - offset = sector_div(blocknr, EXT4_BLOCKS_PER_GROUP(sb)); + offset = do_div(blocknr, EXT4_BLOCKS_PER_GROUP(sb)); if (offsetp) *offsetp = offset; if (blockgrpp) diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c index 75608e1..c88b439 100644 --- a/fs/ext4/ialloc.c +++ b/fs/ext4/ialloc.c @@ -275,7 +275,7 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent) avefreei = freei / ngroups; freeb = percpu_counter_read_positive(&sbi->s_freeblocks_counter); avefreeb = freeb; - sector_div(avefreeb, ngroups); + do_div(avefreeb, ngroups); ndirs = percpu_counter_read_positive(&sbi->s_dirs_counter); if ((parent == sb->s_root->d_inode) || @@ -305,14 +305,14 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent) } blocks_per_dir = ext4_blocks_count(es) - freeb; - sector_div(blocks_per_dir, ndirs); + do_div(blocks_per_dir, ndirs); max_dirs = ndirs / ngroups + inodes_per_group / 16; min_inodes = avefreei - inodes_per_group / 4; min_blocks = avefreeb - EXT4_BLOCKS_PER_GROUP(sb) / 4; max_debt = EXT4_BLOCKS_PER_GROUP(sb); - sector_div(max_debt, max(blocks_per_dir, (ext4_fsblk_t)BLOCK_COST)); + max_debt /= max_t(int, blocks_per_dir, BLOCK_COST); if (max_debt * INODE_COST > inodes_per_group) max_debt = inodes_per_group / INODE_COST; if (max_debt > 255) diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 811011f..f7ea022 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -1485,7 +1485,7 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent) */ if (blocksize != EXT4_MIN_BLOCK_SIZE) { logic_sb_block = sb_block * EXT4_MIN_BLOCK_SIZE; - offset = sector_div(logic_sb_block, blocksize); + offset = do_div(logic_sb_block, blocksize); } else { logic_sb_block = sb_block; } @@ -1591,7 +1591,7 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent) brelse (bh); sb_set_blocksize(sb, blocksize); logic_sb_block = sb_block * EXT4_MIN_BLOCK_SIZE; - offset = sector_div(logic_sb_block, blocksize); + offset = do_div(logic_sb_block, blocksize); bh = sb_bread(sb, logic_sb_block); if (!bh) { printk(KERN_ERR