提交 3a5b2ecd 编写于 作者: M Mingming Cao 提交者: Linus Torvalds

[PATCH] ext4: switch fsblk to sector_t

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: NMingming Cao <cmm@us.ibm.com>
Signed-off-by: NDave Kleikamp <shaggy@austin.ibm.com>
Signed-off-by: NAndrew Morton <akpm@osdl.org>
Signed-off-by: NLinus Torvalds <torvalds@osdl.org>
上级 a86c6181
...@@ -147,7 +147,7 @@ static void __rsv_window_dump(struct rb_root *root, int verbose, ...@@ -147,7 +147,7 @@ static void __rsv_window_dump(struct rb_root *root, int verbose,
rsv = list_entry(n, struct ext4_reserve_window_node, rsv_node); rsv = list_entry(n, struct ext4_reserve_window_node, rsv_node);
if (verbose) if (verbose)
printk("reservation window 0x%p " printk("reservation window 0x%p "
"start: %lu, end: %lu\n", "start: "E3FSBLK", end: "E3FSBLK"\n",
rsv, rsv->rsv_start, rsv->rsv_end); rsv, rsv->rsv_start, rsv->rsv_end);
if (rsv->rsv_start && rsv->rsv_start >= rsv->rsv_end) { if (rsv->rsv_start && rsv->rsv_start >= rsv->rsv_end) {
printk("Bad reservation %p (start >= end)\n", printk("Bad reservation %p (start >= end)\n",
...@@ -443,10 +443,7 @@ void ext4_free_blocks_sb(handle_t *handle, struct super_block *sb, ...@@ -443,10 +443,7 @@ void ext4_free_blocks_sb(handle_t *handle, struct super_block *sb,
do_more: do_more:
overflow = 0; overflow = 0;
block_group = (block - le32_to_cpu(es->s_first_data_block)) / ext4_get_group_no_and_offset(sb, block, &block_group, &bit);
EXT4_BLOCKS_PER_GROUP(sb);
bit = (block - le32_to_cpu(es->s_first_data_block)) %
EXT4_BLOCKS_PER_GROUP(sb);
/* /*
* Check to see if we are freeing blocks across a group * Check to see if we are freeing blocks across a group
* boundary. * boundary.
...@@ -1404,7 +1401,7 @@ ext4_fsblk_t ext4_new_blocks(handle_t *handle, struct inode *inode, ...@@ -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 *bitmap_bh = NULL;
struct buffer_head *gdp_bh; struct buffer_head *gdp_bh;
int group_no; unsigned long group_no;
int goal_group; int goal_group;
ext4_grpblk_t grp_target_blk; /* blockgroup relative goal block */ ext4_grpblk_t grp_target_blk; /* blockgroup relative goal block */
ext4_grpblk_t grp_alloc_blk; /* blockgroup-relative allocated 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, ...@@ -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) || if (goal < le32_to_cpu(es->s_first_data_block) ||
goal >= le32_to_cpu(es->s_blocks_count)) goal >= le32_to_cpu(es->s_blocks_count))
goal = le32_to_cpu(es->s_first_data_block); goal = le32_to_cpu(es->s_first_data_block);
group_no = (goal - le32_to_cpu(es->s_first_data_block)) / ext4_get_group_no_and_offset(sb, goal, &group_no, &grp_target_blk);
EXT4_BLOCKS_PER_GROUP(sb);
goal_group = group_no; goal_group = group_no;
retry_alloc: retry_alloc:
gdp = ext4_get_group_desc(sb, group_no, &gdp_bh); gdp = ext4_get_group_desc(sb, group_no, &gdp_bh);
...@@ -1485,8 +1481,6 @@ ext4_fsblk_t ext4_new_blocks(handle_t *handle, struct inode *inode, ...@@ -1485,8 +1481,6 @@ ext4_fsblk_t ext4_new_blocks(handle_t *handle, struct inode *inode,
my_rsv = NULL; my_rsv = NULL;
if (free_blocks > 0) { 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); bitmap_bh = read_block_bitmap(sb, group_no);
if (!bitmap_bh) if (!bitmap_bh)
goto io_error; goto io_error;
...@@ -1613,7 +1607,7 @@ ext4_fsblk_t ext4_new_blocks(handle_t *handle, struct inode *inode, ...@@ -1613,7 +1607,7 @@ ext4_fsblk_t ext4_new_blocks(handle_t *handle, struct inode *inode,
if (ret_block + num - 1 >= le32_to_cpu(es->s_blocks_count)) { if (ret_block + num - 1 >= le32_to_cpu(es->s_blocks_count)) {
ext4_error(sb, "ext4_new_block", ext4_error(sb, "ext4_new_block",
"block("E3FSBLK") >= blocks count(%d) - " "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); le32_to_cpu(es->s_blocks_count), group_no, es);
goto out; goto out;
} }
...@@ -1733,9 +1727,10 @@ ext4_fsblk_t ext4_count_free_blocks(struct super_block *sb) ...@@ -1733,9 +1727,10 @@ ext4_fsblk_t ext4_count_free_blocks(struct super_block *sb)
static inline int static inline int
block_in_use(ext4_fsblk_t block, struct super_block *sb, unsigned char *map) block_in_use(ext4_fsblk_t block, struct super_block *sb, unsigned char *map)
{ {
return ext4_test_bit ((block - ext4_grpblk_t offset;
le32_to_cpu(EXT4_SB(sb)->s_es->s_first_data_block)) %
EXT4_BLOCKS_PER_GROUP(sb), map); 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) static inline int test_root(int a, int b)
......
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
#include <linux/buffer_head.h> #include <linux/buffer_head.h>
#include <linux/random.h> #include <linux/random.h>
#include <linux/bitops.h> #include <linux/bitops.h>
#include <linux/blkdev.h>
#include <asm/byteorder.h> #include <asm/byteorder.h>
#include "xattr.h" #include "xattr.h"
...@@ -274,7 +274,8 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent) ...@@ -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); freei = percpu_counter_read_positive(&sbi->s_freeinodes_counter);
avefreei = freei / ngroups; avefreei = freei / ngroups;
freeb = percpu_counter_read_positive(&sbi->s_freeblocks_counter); 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); ndirs = percpu_counter_read_positive(&sbi->s_dirs_counter);
if ((parent == sb->s_root->d_inode) || if ((parent == sb->s_root->d_inode) ||
...@@ -303,13 +304,15 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent) ...@@ -303,13 +304,15 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent)
goto fallback; 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; max_dirs = ndirs / ngroups + inodes_per_group / 16;
min_inodes = avefreei - inodes_per_group / 4; min_inodes = avefreei - inodes_per_group / 4;
min_blocks = avefreeb - EXT4_BLOCKS_PER_GROUP(sb) / 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) if (max_debt * INODE_COST > inodes_per_group)
max_debt = inodes_per_group / INODE_COST; max_debt = inodes_per_group / INODE_COST;
if (max_debt > 255) if (max_debt > 255)
......
...@@ -36,7 +36,7 @@ static int verify_group_input(struct super_block *sb, ...@@ -36,7 +36,7 @@ static int verify_group_input(struct super_block *sb,
le16_to_cpu(es->s_reserved_gdt_blocks)) : 0; le16_to_cpu(es->s_reserved_gdt_blocks)) : 0;
ext4_fsblk_t metaend = start + overhead; ext4_fsblk_t metaend = start + overhead;
struct buffer_head *bh = NULL; struct buffer_head *bh = NULL;
ext4_grpblk_t free_blocks_count; ext4_grpblk_t free_blocks_count, offset;
int err = -EINVAL; int err = -EINVAL;
input->free_blocks_count = free_blocks_count = input->free_blocks_count = free_blocks_count =
...@@ -49,13 +49,13 @@ static int verify_group_input(struct super_block *sb, ...@@ -49,13 +49,13 @@ static int verify_group_input(struct super_block *sb,
"no-super", input->group, input->blocks_count, "no-super", input->group, input->blocks_count,
free_blocks_count, input->reserved_blocks); free_blocks_count, input->reserved_blocks);
ext4_get_group_no_and_offset(sb, start, NULL, &offset);
if (group != sbi->s_groups_count) if (group != sbi->s_groups_count)
ext4_warning(sb, __FUNCTION__, ext4_warning(sb, __FUNCTION__,
"Cannot add at group %u (only %lu groups)", "Cannot add at group %u (only %lu groups)",
input->group, sbi->s_groups_count); input->group, sbi->s_groups_count);
else if ((start - le32_to_cpu(es->s_first_data_block)) % else if (offset != 0)
EXT4_BLOCKS_PER_GROUP(sb)) ext4_warning(sb, __FUNCTION__, "Last group not full");
ext4_warning(sb, __FUNCTION__, "Last group not full");
else if (input->reserved_blocks > input->blocks_count / 5) else if (input->reserved_blocks > input->blocks_count / 5)
ext4_warning(sb, __FUNCTION__, "Reserved blocks too high (%u)", ext4_warning(sb, __FUNCTION__, "Reserved blocks too high (%u)",
input->reserved_blocks); input->reserved_blocks);
...@@ -945,7 +945,7 @@ int ext4_group_extend(struct super_block *sb, struct ext4_super_block *es, ...@@ -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)) { if (n_blocks_count > (sector_t)(~0ULL) >> (sb->s_blocksize_bits - 9)) {
printk(KERN_ERR "EXT4-fs: filesystem on %s:" 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); sb->s_id, n_blocks_count);
if (sizeof(sector_t) < 8) if (sizeof(sector_t) < 8)
ext4_warning(sb, __FUNCTION__, ext4_warning(sb, __FUNCTION__,
...@@ -960,8 +960,7 @@ int ext4_group_extend(struct super_block *sb, struct ext4_super_block *es, ...@@ -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. */ /* Handle the remaining blocks in the last group only. */
last = (o_blocks_count - le32_to_cpu(es->s_first_data_block)) % ext4_get_group_no_and_offset(sb, o_blocks_count, NULL, &last);
EXT4_BLOCKS_PER_GROUP(sb);
if (last == 0) { if (last == 0) {
ext4_warning(sb, __FUNCTION__, ext4_warning(sb, __FUNCTION__,
......
...@@ -1433,8 +1433,8 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent) ...@@ -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. * block sizes. We need to calculate the offset from buffer start.
*/ */
if (blocksize != EXT4_MIN_BLOCK_SIZE) { if (blocksize != EXT4_MIN_BLOCK_SIZE) {
logic_sb_block = (sb_block * EXT4_MIN_BLOCK_SIZE) / blocksize; logic_sb_block = sb_block * EXT4_MIN_BLOCK_SIZE;
offset = (sb_block * EXT4_MIN_BLOCK_SIZE) % blocksize; offset = sector_div(logic_sb_block, blocksize);
} else { } else {
logic_sb_block = sb_block; logic_sb_block = sb_block;
} }
...@@ -1539,8 +1539,8 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent) ...@@ -1539,8 +1539,8 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent)
brelse (bh); brelse (bh);
sb_set_blocksize(sb, blocksize); sb_set_blocksize(sb, blocksize);
logic_sb_block = (sb_block * EXT4_MIN_BLOCK_SIZE) / blocksize; logic_sb_block = sb_block * EXT4_MIN_BLOCK_SIZE;
offset = (sb_block * EXT4_MIN_BLOCK_SIZE) % blocksize; offset = sector_div(logic_sb_block, blocksize);
bh = sb_bread(sb, logic_sb_block); bh = sb_bread(sb, logic_sb_block);
if (!bh) { if (!bh) {
printk(KERN_ERR printk(KERN_ERR
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#define _LINUX_EXT4_FS_H #define _LINUX_EXT4_FS_H
#include <linux/types.h> #include <linux/types.h>
#include <linux/blkdev.h>
#include <linux/magic.h> #include <linux/magic.h>
/* /*
...@@ -749,6 +750,27 @@ ext4_group_first_block_no(struct super_block *sb, unsigned long group_no) ...@@ -749,6 +750,27 @@ ext4_group_first_block_no(struct super_block *sb, unsigned long group_no)
*/ */
#define ERR_BAD_DX_DIR -75000 #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 * Function prototypes
*/ */
...@@ -762,6 +784,10 @@ ext4_group_first_block_no(struct super_block *sb, unsigned long group_no) ...@@ -762,6 +784,10 @@ ext4_group_first_block_no(struct super_block *sb, unsigned long group_no)
# define NORET_AND noreturn, # define NORET_AND noreturn,
/* balloc.c */ /* 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 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 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, extern ext4_fsblk_t ext4_new_block (handle_t *handle, struct inode *inode,
......
...@@ -25,9 +25,13 @@ ...@@ -25,9 +25,13 @@
typedef int ext4_grpblk_t; typedef int ext4_grpblk_t;
/* data type for filesystem-wide blocks number */ /* 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" #define E3FSBLK "%lu"
#else
#define E3FSBLK "%llu"
#endif
struct ext4_reserve_window { struct ext4_reserve_window {
ext4_fsblk_t _rsv_start; /* First byte reserved */ ext4_fsblk_t _rsv_start; /* First byte reserved */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册