[PATCH] ext4: switch fsblk to sector_t
authorMingming Cao <cmm@us.ibm.com>
Wed, 11 Oct 2006 08:21:05 +0000 (01:21 -0700)
committerLinus Torvalds <torvalds@g5.osdl.org>
Wed, 11 Oct 2006 18:14:16 +0000 (11:14 -0700)
Redefine ext3 in-kernel filesystem block type (ext3_fsblk_t) from unsigned
long to sector_t, to allow kernel to handle  >32 bit ext3 blocks.

Signed-off-by: Mingming Cao <cmm@us.ibm.com>
Signed-off-by: Dave Kleikamp <shaggy@austin.ibm.com>
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/resize.c
fs/ext4/super.c
include/linux/ext4_fs.h
include/linux/ext4_fs_i.h

index e9e9844..aa33ff2 100644 (file)
@@ -147,7 +147,7 @@ restart:
                rsv = list_entry(n, struct ext4_reserve_window_node, rsv_node);
                if (verbose)
                        printk("reservation window 0x%p "
-                              "start:  %lu, end:  %lu\n",
+                              "start:  "E3FSBLK", end:  "E3FSBLK"\n",
                               rsv, rsv->rsv_start, rsv->rsv_end);
                if (rsv->rsv_start && rsv->rsv_start >= rsv->rsv_end) {
                        printk("Bad reservation %p (start >= end)\n",
@@ -443,10 +443,7 @@ void ext4_free_blocks_sb(handle_t *handle, struct super_block *sb,
 
 do_more:
        overflow = 0;
-       block_group = (block - le32_to_cpu(es->s_first_data_block)) /
-                     EXT4_BLOCKS_PER_GROUP(sb);
-       bit = (block - le32_to_cpu(es->s_first_data_block)) %
-                     EXT4_BLOCKS_PER_GROUP(sb);
+       ext4_get_group_no_and_offset(sb, block, &block_group, &bit);
        /*
         * Check to see if we are freeing blocks across a group
         * boundary.
@@ -1404,7 +1401,7 @@ ext4_fsblk_t ext4_new_blocks(handle_t *handle, struct inode *inode,
 {
        struct buffer_head *bitmap_bh = NULL;
        struct buffer_head *gdp_bh;
-       int group_no;
+       unsigned long group_no;
        int goal_group;
        ext4_grpblk_t grp_target_blk;   /* blockgroup relative goal block */
        ext4_grpblk_t grp_alloc_blk;    /* blockgroup-relative allocated block*/
@@ -1467,8 +1464,7 @@ ext4_fsblk_t ext4_new_blocks(handle_t *handle, struct inode *inode,
        if (goal < le32_to_cpu(es->s_first_data_block) ||
            goal >= le32_to_cpu(es->s_blocks_count))
                goal = le32_to_cpu(es->s_first_data_block);
-       group_no = (goal - le32_to_cpu(es->s_first_data_block)) /
-                       EXT4_BLOCKS_PER_GROUP(sb);
+       ext4_get_group_no_and_offset(sb, goal, &group_no, &grp_target_blk);
        goal_group = group_no;
 retry_alloc:
        gdp = ext4_get_group_desc(sb, group_no, &gdp_bh);
@@ -1485,8 +1481,6 @@ retry_alloc:
                my_rsv = NULL;
 
        if (free_blocks > 0) {
-               grp_target_blk = ((goal - le32_to_cpu(es->s_first_data_block)) %
-                               EXT4_BLOCKS_PER_GROUP(sb));
                bitmap_bh = read_block_bitmap(sb, group_no);
                if (!bitmap_bh)
                        goto io_error;
@@ -1613,7 +1607,7 @@ allocated:
        if (ret_block + num - 1 >= le32_to_cpu(es->s_blocks_count)) {
                ext4_error(sb, "ext4_new_block",
                            "block("E3FSBLK") >= blocks count(%d) - "
-                           "block_group = %d, es == %p ", ret_block,
+                           "block_group = %lu, es == %p ", ret_block,
                        le32_to_cpu(es->s_blocks_count), group_no, es);
                goto out;
        }
@@ -1733,9 +1727,10 @@ ext4_fsblk_t ext4_count_free_blocks(struct super_block *sb)
 static inline int
 block_in_use(ext4_fsblk_t block, struct super_block *sb, unsigned char *map)
 {
-       return ext4_test_bit ((block -
-               le32_to_cpu(EXT4_SB(sb)->s_es->s_first_data_block)) %
-                        EXT4_BLOCKS_PER_GROUP(sb), map);
+       ext4_grpblk_t offset;
+
+       ext4_get_group_no_and_offset(sb, block, NULL, &offset);
+       return ext4_test_bit (offset, map);
 }
 
 static inline int test_root(int a, int b)
index e17a6c9..94e1bb4 100644 (file)
@@ -23,7 +23,7 @@
 #include <linux/buffer_head.h>
 #include <linux/random.h>
 #include <linux/bitops.h>
-
+#include <linux/blkdev.h>
 #include <asm/byteorder.h>
 
 #include "xattr.h"
@@ -274,7 +274,8 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent)
        freei = percpu_counter_read_positive(&sbi->s_freeinodes_counter);
        avefreei = freei / ngroups;
        freeb = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
-       avefreeb = freeb / ngroups;
+       avefreeb = freeb;
+       sector_div(avefreeb, ngroups);
        ndirs = percpu_counter_read_positive(&sbi->s_dirs_counter);
 
        if ((parent == sb->s_root->d_inode) ||
@@ -303,13 +304,15 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent)
                goto fallback;
        }
 
-       blocks_per_dir = (le32_to_cpu(es->s_blocks_count) - freeb) / ndirs;
+       blocks_per_dir = le32_to_cpu(es->s_blocks_count) - freeb;
+       sector_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) / max(blocks_per_dir, (ext4_fsblk_t)BLOCK_COST);
+       max_debt = EXT4_BLOCKS_PER_GROUP(sb);
+       sector_div(max_debt, max(blocks_per_dir, (ext4_fsblk_t)BLOCK_COST));
        if (max_debt * INODE_COST > inodes_per_group)
                max_debt = inodes_per_group / INODE_COST;
        if (max_debt > 255)
index 5b2828d..c60bfed 100644 (file)
@@ -36,7 +36,7 @@ static int verify_group_input(struct super_block *sb,
                 le16_to_cpu(es->s_reserved_gdt_blocks)) : 0;
        ext4_fsblk_t metaend = start + overhead;
        struct buffer_head *bh = NULL;
-       ext4_grpblk_t free_blocks_count;
+       ext4_grpblk_t free_blocks_count, offset;
        int err = -EINVAL;
 
        input->free_blocks_count = free_blocks_count =
@@ -49,13 +49,13 @@ static int verify_group_input(struct super_block *sb,
                       "no-super", input->group, input->blocks_count,
                       free_blocks_count, input->reserved_blocks);
 
+       ext4_get_group_no_and_offset(sb, start, NULL, &offset);
        if (group != sbi->s_groups_count)
                ext4_warning(sb, __FUNCTION__,
                             "Cannot add at group %u (only %lu groups)",
                             input->group, sbi->s_groups_count);
-       else if ((start - le32_to_cpu(es->s_first_data_block)) %
-                EXT4_BLOCKS_PER_GROUP(sb))
-               ext4_warning(sb, __FUNCTION__, "Last group not full");
+       else if (offset != 0)
+                       ext4_warning(sb, __FUNCTION__, "Last group not full");
        else if (input->reserved_blocks > input->blocks_count / 5)
                ext4_warning(sb, __FUNCTION__, "Reserved blocks too high (%u)",
                             input->reserved_blocks);
@@ -945,7 +945,7 @@ int ext4_group_extend(struct super_block *sb, struct ext4_super_block *es,
 
        if (n_blocks_count > (sector_t)(~0ULL) >> (sb->s_blocksize_bits - 9)) {
                printk(KERN_ERR "EXT4-fs: filesystem on %s:"
-                       " too large to resize to %lu blocks safely\n",
+                       " too large to resize to "E3FSBLK" blocks safely\n",
                        sb->s_id, n_blocks_count);
                if (sizeof(sector_t) < 8)
                        ext4_warning(sb, __FUNCTION__,
@@ -960,8 +960,7 @@ int ext4_group_extend(struct super_block *sb, struct ext4_super_block *es,
        }
 
        /* Handle the remaining blocks in the last group only. */
-       last = (o_blocks_count - le32_to_cpu(es->s_first_data_block)) %
-               EXT4_BLOCKS_PER_GROUP(sb);
+       ext4_get_group_no_and_offset(sb, o_blocks_count, NULL, &last);
 
        if (last == 0) {
                ext4_warning(sb, __FUNCTION__,
index 69f8752..1d12e4f 100644 (file)
@@ -1433,8 +1433,8 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent)
         * block sizes.  We need to calculate the offset from buffer start.
         */
        if (blocksize != EXT4_MIN_BLOCK_SIZE) {
-               logic_sb_block = (sb_block * EXT4_MIN_BLOCK_SIZE) / blocksize;
-               offset = (sb_block * EXT4_MIN_BLOCK_SIZE) % blocksize;
+               logic_sb_block = sb_block * EXT4_MIN_BLOCK_SIZE;
+               offset = sector_div(logic_sb_block, blocksize);
        } else {
                logic_sb_block = sb_block;
        }
@@ -1539,8 +1539,8 @@ 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) / blocksize;
-               offset = (sb_block * EXT4_MIN_BLOCK_SIZE) % blocksize;
+               logic_sb_block = sb_block * EXT4_MIN_BLOCK_SIZE;
+               offset = sector_div(logic_sb_block, blocksize);
                bh = sb_bread(sb, logic_sb_block);
                if (!bh) {
                        printk(KERN_ERR
index b61181a..e952c6d 100644 (file)
@@ -17,6 +17,7 @@
 #define _LINUX_EXT4_FS_H
 
 #include <linux/types.h>
+#include <linux/blkdev.h>
 #include <linux/magic.h>
 
 /*
@@ -750,6 +751,27 @@ ext4_group_first_block_no(struct super_block *sb, unsigned long group_no)
 #define ERR_BAD_DX_DIR -75000
 
 /*
+ * This function calculate the block group number and offset,
+ * given a block number
+ */
+
+static inline 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 = sector_div(blocknr, EXT4_BLOCKS_PER_GROUP(sb));
+       if (offsetp)
+               *offsetp = offset;
+       if (blockgrpp)
+               *blockgrpp = blocknr;
+
+}
+
+/*
  * Function prototypes
  */
 
@@ -762,6 +784,10 @@ ext4_group_first_block_no(struct super_block *sb, unsigned long group_no)
 # define NORET_AND     noreturn,
 
 /* balloc.c */
+extern unsigned int ext4_block_group(struct super_block *sb,
+                       ext4_fsblk_t blocknr);
+extern ext4_grpblk_t ext4_block_group_offset(struct super_block *sb,
+                       ext4_fsblk_t blocknr);
 extern int ext4_bg_has_super(struct super_block *sb, int group);
 extern unsigned long ext4_bg_num_gdb(struct super_block *sb, int group);
 extern ext4_fsblk_t ext4_new_block (handle_t *handle, struct inode *inode,
index 40ce04a..b2ccd98 100644 (file)
 typedef int ext4_grpblk_t;
 
 /* data type for filesystem-wide blocks number */
-typedef unsigned long ext4_fsblk_t;
+typedef sector_t ext4_fsblk_t;
 
+#if BITS_PER_LONG == 64
 #define E3FSBLK "%lu"
+#else
+#define E3FSBLK "%llu"
+#endif
 
 struct ext4_reserve_window {
        ext4_fsblk_t    _rsv_start;     /* First byte reserved */