[PATCH] ext4 64 bit divide fix
authorAndrew Morton <akpm@osdl.org>
Wed, 11 Oct 2006 08:21:19 +0000 (01:21 -0700)
committerLinus Torvalds <torvalds@g5.osdl.org>
Wed, 11 Oct 2006 18:14:18 +0000 (11:14 -0700)
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: <linux-ext4@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
fs/ext4/balloc.c
fs/ext4/ialloc.c
fs/ext4/super.c

index 402475a6f3df1e17727e019c9226cb5024d2438e..5d45582f9517e35bacb67405d737190aaef128be 100644 (file)
@@ -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)
index 75608e1e5555a1068b1eaf1b9cc4f64ee5c1a2df..c88b439ba5cd5838d264450746c450cc45245c16 100644 (file)
@@ -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)
index 811011fc5c94e0082f5a5620dc55683edddb3eab..f7ea0224f5350a6aaed7317cc8b2096d8cab0c48 100644 (file)
@@ -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