diff options
author | Mingming Cao <cmm@us.ibm.com> | 2006-10-11 04:21:05 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-10-11 14:14:16 -0400 |
commit | 3a5b2ecdd1fa63a8f25bd769223bc1c2564ce45d (patch) | |
tree | dc80fdde9ed01e77ef0ed6fdef7573d303bd07db | |
parent | a86c61812637c7dd0c57e29880cffd477b62f2e7 (diff) |
[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: 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>
-rw-r--r-- | fs/ext4/balloc.c | 23 | ||||
-rw-r--r-- | fs/ext4/ialloc.c | 11 | ||||
-rw-r--r-- | fs/ext4/resize.c | 13 | ||||
-rw-r--r-- | fs/ext4/super.c | 8 | ||||
-rw-r--r-- | include/linux/ext4_fs.h | 26 | ||||
-rw-r--r-- | include/linux/ext4_fs_i.h | 6 |
6 files changed, 57 insertions, 30 deletions
diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c index e9e98449137b..aa33ff271fa9 100644 --- a/fs/ext4/balloc.c +++ b/fs/ext4/balloc.c | |||
@@ -147,7 +147,7 @@ restart: | |||
147 | rsv = list_entry(n, struct ext4_reserve_window_node, rsv_node); | 147 | rsv = list_entry(n, struct ext4_reserve_window_node, rsv_node); |
148 | if (verbose) | 148 | if (verbose) |
149 | printk("reservation window 0x%p " | 149 | printk("reservation window 0x%p " |
150 | "start: %lu, end: %lu\n", | 150 | "start: "E3FSBLK", end: "E3FSBLK"\n", |
151 | rsv, rsv->rsv_start, rsv->rsv_end); | 151 | rsv, rsv->rsv_start, rsv->rsv_end); |
152 | if (rsv->rsv_start && rsv->rsv_start >= rsv->rsv_end) { | 152 | if (rsv->rsv_start && rsv->rsv_start >= rsv->rsv_end) { |
153 | printk("Bad reservation %p (start >= end)\n", | 153 | printk("Bad reservation %p (start >= end)\n", |
@@ -443,10 +443,7 @@ void ext4_free_blocks_sb(handle_t *handle, struct super_block *sb, | |||
443 | 443 | ||
444 | do_more: | 444 | do_more: |
445 | overflow = 0; | 445 | overflow = 0; |
446 | block_group = (block - le32_to_cpu(es->s_first_data_block)) / | 446 | ext4_get_group_no_and_offset(sb, block, &block_group, &bit); |
447 | EXT4_BLOCKS_PER_GROUP(sb); | ||
448 | bit = (block - le32_to_cpu(es->s_first_data_block)) % | ||
449 | EXT4_BLOCKS_PER_GROUP(sb); | ||
450 | /* | 447 | /* |
451 | * Check to see if we are freeing blocks across a group | 448 | * Check to see if we are freeing blocks across a group |
452 | * boundary. | 449 | * boundary. |
@@ -1404,7 +1401,7 @@ ext4_fsblk_t ext4_new_blocks(handle_t *handle, struct inode *inode, | |||
1404 | { | 1401 | { |
1405 | struct buffer_head *bitmap_bh = NULL; | 1402 | struct buffer_head *bitmap_bh = NULL; |
1406 | struct buffer_head *gdp_bh; | 1403 | struct buffer_head *gdp_bh; |
1407 | int group_no; | 1404 | unsigned long group_no; |
1408 | int goal_group; | 1405 | int goal_group; |
1409 | ext4_grpblk_t grp_target_blk; /* blockgroup relative goal block */ | 1406 | ext4_grpblk_t grp_target_blk; /* blockgroup relative goal block */ |
1410 | ext4_grpblk_t grp_alloc_blk; /* blockgroup-relative allocated block*/ | 1407 | 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 | if (goal < le32_to_cpu(es->s_first_data_block) || | 1464 | if (goal < le32_to_cpu(es->s_first_data_block) || |
1468 | goal >= le32_to_cpu(es->s_blocks_count)) | 1465 | goal >= le32_to_cpu(es->s_blocks_count)) |
1469 | goal = le32_to_cpu(es->s_first_data_block); | 1466 | goal = le32_to_cpu(es->s_first_data_block); |
1470 | group_no = (goal - le32_to_cpu(es->s_first_data_block)) / | 1467 | ext4_get_group_no_and_offset(sb, goal, &group_no, &grp_target_blk); |
1471 | EXT4_BLOCKS_PER_GROUP(sb); | ||
1472 | goal_group = group_no; | 1468 | goal_group = group_no; |
1473 | retry_alloc: | 1469 | retry_alloc: |
1474 | gdp = ext4_get_group_desc(sb, group_no, &gdp_bh); | 1470 | gdp = ext4_get_group_desc(sb, group_no, &gdp_bh); |
@@ -1485,8 +1481,6 @@ retry_alloc: | |||
1485 | my_rsv = NULL; | 1481 | my_rsv = NULL; |
1486 | 1482 | ||
1487 | if (free_blocks > 0) { | 1483 | if (free_blocks > 0) { |
1488 | grp_target_blk = ((goal - le32_to_cpu(es->s_first_data_block)) % | ||
1489 | EXT4_BLOCKS_PER_GROUP(sb)); | ||
1490 | bitmap_bh = read_block_bitmap(sb, group_no); | 1484 | bitmap_bh = read_block_bitmap(sb, group_no); |
1491 | if (!bitmap_bh) | 1485 | if (!bitmap_bh) |
1492 | goto io_error; | 1486 | goto io_error; |
@@ -1613,7 +1607,7 @@ allocated: | |||
1613 | if (ret_block + num - 1 >= le32_to_cpu(es->s_blocks_count)) { | 1607 | if (ret_block + num - 1 >= le32_to_cpu(es->s_blocks_count)) { |
1614 | ext4_error(sb, "ext4_new_block", | 1608 | ext4_error(sb, "ext4_new_block", |
1615 | "block("E3FSBLK") >= blocks count(%d) - " | 1609 | "block("E3FSBLK") >= blocks count(%d) - " |
1616 | "block_group = %d, es == %p ", ret_block, | 1610 | "block_group = %lu, es == %p ", ret_block, |
1617 | le32_to_cpu(es->s_blocks_count), group_no, es); | 1611 | le32_to_cpu(es->s_blocks_count), group_no, es); |
1618 | goto out; | 1612 | goto out; |
1619 | } | 1613 | } |
@@ -1733,9 +1727,10 @@ ext4_fsblk_t ext4_count_free_blocks(struct super_block *sb) | |||
1733 | static inline int | 1727 | static inline int |
1734 | block_in_use(ext4_fsblk_t block, struct super_block *sb, unsigned char *map) | 1728 | block_in_use(ext4_fsblk_t block, struct super_block *sb, unsigned char *map) |
1735 | { | 1729 | { |
1736 | return ext4_test_bit ((block - | 1730 | ext4_grpblk_t offset; |
1737 | le32_to_cpu(EXT4_SB(sb)->s_es->s_first_data_block)) % | 1731 | |
1738 | EXT4_BLOCKS_PER_GROUP(sb), map); | 1732 | ext4_get_group_no_and_offset(sb, block, NULL, &offset); |
1733 | return ext4_test_bit (offset, map); | ||
1739 | } | 1734 | } |
1740 | 1735 | ||
1741 | static inline int test_root(int a, int b) | 1736 | static inline int test_root(int a, int b) |
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c index e17a6c918d72..94e1bb4abe31 100644 --- a/fs/ext4/ialloc.c +++ b/fs/ext4/ialloc.c | |||
@@ -23,7 +23,7 @@ | |||
23 | #include <linux/buffer_head.h> | 23 | #include <linux/buffer_head.h> |
24 | #include <linux/random.h> | 24 | #include <linux/random.h> |
25 | #include <linux/bitops.h> | 25 | #include <linux/bitops.h> |
26 | 26 | #include <linux/blkdev.h> | |
27 | #include <asm/byteorder.h> | 27 | #include <asm/byteorder.h> |
28 | 28 | ||
29 | #include "xattr.h" | 29 | #include "xattr.h" |
@@ -274,7 +274,8 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent) | |||
274 | freei = percpu_counter_read_positive(&sbi->s_freeinodes_counter); | 274 | freei = percpu_counter_read_positive(&sbi->s_freeinodes_counter); |
275 | avefreei = freei / ngroups; | 275 | avefreei = freei / ngroups; |
276 | freeb = percpu_counter_read_positive(&sbi->s_freeblocks_counter); | 276 | freeb = percpu_counter_read_positive(&sbi->s_freeblocks_counter); |
277 | avefreeb = freeb / ngroups; | 277 | avefreeb = freeb; |
278 | sector_div(avefreeb, ngroups); | ||
278 | ndirs = percpu_counter_read_positive(&sbi->s_dirs_counter); | 279 | ndirs = percpu_counter_read_positive(&sbi->s_dirs_counter); |
279 | 280 | ||
280 | if ((parent == sb->s_root->d_inode) || | 281 | if ((parent == sb->s_root->d_inode) || |
@@ -303,13 +304,15 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent) | |||
303 | goto fallback; | 304 | goto fallback; |
304 | } | 305 | } |
305 | 306 | ||
306 | blocks_per_dir = (le32_to_cpu(es->s_blocks_count) - freeb) / ndirs; | 307 | blocks_per_dir = le32_to_cpu(es->s_blocks_count) - freeb; |
308 | sector_div(blocks_per_dir, ndirs); | ||
307 | 309 | ||
308 | max_dirs = ndirs / ngroups + inodes_per_group / 16; | 310 | max_dirs = ndirs / ngroups + inodes_per_group / 16; |
309 | min_inodes = avefreei - inodes_per_group / 4; | 311 | min_inodes = avefreei - inodes_per_group / 4; |
310 | min_blocks = avefreeb - EXT4_BLOCKS_PER_GROUP(sb) / 4; | 312 | min_blocks = avefreeb - EXT4_BLOCKS_PER_GROUP(sb) / 4; |
311 | 313 | ||
312 | max_debt = EXT4_BLOCKS_PER_GROUP(sb) / max(blocks_per_dir, (ext4_fsblk_t)BLOCK_COST); | 314 | max_debt = EXT4_BLOCKS_PER_GROUP(sb); |
315 | sector_div(max_debt, max(blocks_per_dir, (ext4_fsblk_t)BLOCK_COST)); | ||
313 | if (max_debt * INODE_COST > inodes_per_group) | 316 | if (max_debt * INODE_COST > inodes_per_group) |
314 | max_debt = inodes_per_group / INODE_COST; | 317 | max_debt = inodes_per_group / INODE_COST; |
315 | if (max_debt > 255) | 318 | if (max_debt > 255) |
diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c index 5b2828d21180..c60bfed5f5e7 100644 --- a/fs/ext4/resize.c +++ b/fs/ext4/resize.c | |||
@@ -36,7 +36,7 @@ static int verify_group_input(struct super_block *sb, | |||
36 | le16_to_cpu(es->s_reserved_gdt_blocks)) : 0; | 36 | le16_to_cpu(es->s_reserved_gdt_blocks)) : 0; |
37 | ext4_fsblk_t metaend = start + overhead; | 37 | ext4_fsblk_t metaend = start + overhead; |
38 | struct buffer_head *bh = NULL; | 38 | struct buffer_head *bh = NULL; |
39 | ext4_grpblk_t free_blocks_count; | 39 | ext4_grpblk_t free_blocks_count, offset; |
40 | int err = -EINVAL; | 40 | int err = -EINVAL; |
41 | 41 | ||
42 | input->free_blocks_count = free_blocks_count = | 42 | input->free_blocks_count = free_blocks_count = |
@@ -49,13 +49,13 @@ static int verify_group_input(struct super_block *sb, | |||
49 | "no-super", input->group, input->blocks_count, | 49 | "no-super", input->group, input->blocks_count, |
50 | free_blocks_count, input->reserved_blocks); | 50 | free_blocks_count, input->reserved_blocks); |
51 | 51 | ||
52 | ext4_get_group_no_and_offset(sb, start, NULL, &offset); | ||
52 | if (group != sbi->s_groups_count) | 53 | if (group != sbi->s_groups_count) |
53 | ext4_warning(sb, __FUNCTION__, | 54 | ext4_warning(sb, __FUNCTION__, |
54 | "Cannot add at group %u (only %lu groups)", | 55 | "Cannot add at group %u (only %lu groups)", |
55 | input->group, sbi->s_groups_count); | 56 | input->group, sbi->s_groups_count); |
56 | else if ((start - le32_to_cpu(es->s_first_data_block)) % | 57 | else if (offset != 0) |
57 | EXT4_BLOCKS_PER_GROUP(sb)) | 58 | ext4_warning(sb, __FUNCTION__, "Last group not full"); |
58 | ext4_warning(sb, __FUNCTION__, "Last group not full"); | ||
59 | else if (input->reserved_blocks > input->blocks_count / 5) | 59 | else if (input->reserved_blocks > input->blocks_count / 5) |
60 | ext4_warning(sb, __FUNCTION__, "Reserved blocks too high (%u)", | 60 | ext4_warning(sb, __FUNCTION__, "Reserved blocks too high (%u)", |
61 | input->reserved_blocks); | 61 | input->reserved_blocks); |
@@ -945,7 +945,7 @@ int ext4_group_extend(struct super_block *sb, struct ext4_super_block *es, | |||
945 | 945 | ||
946 | if (n_blocks_count > (sector_t)(~0ULL) >> (sb->s_blocksize_bits - 9)) { | 946 | if (n_blocks_count > (sector_t)(~0ULL) >> (sb->s_blocksize_bits - 9)) { |
947 | printk(KERN_ERR "EXT4-fs: filesystem on %s:" | 947 | printk(KERN_ERR "EXT4-fs: filesystem on %s:" |
948 | " too large to resize to %lu blocks safely\n", | 948 | " too large to resize to "E3FSBLK" blocks safely\n", |
949 | sb->s_id, n_blocks_count); | 949 | sb->s_id, n_blocks_count); |
950 | if (sizeof(sector_t) < 8) | 950 | if (sizeof(sector_t) < 8) |
951 | ext4_warning(sb, __FUNCTION__, | 951 | ext4_warning(sb, __FUNCTION__, |
@@ -960,8 +960,7 @@ int ext4_group_extend(struct super_block *sb, struct ext4_super_block *es, | |||
960 | } | 960 | } |
961 | 961 | ||
962 | /* Handle the remaining blocks in the last group only. */ | 962 | /* Handle the remaining blocks in the last group only. */ |
963 | last = (o_blocks_count - le32_to_cpu(es->s_first_data_block)) % | 963 | ext4_get_group_no_and_offset(sb, o_blocks_count, NULL, &last); |
964 | EXT4_BLOCKS_PER_GROUP(sb); | ||
965 | 964 | ||
966 | if (last == 0) { | 965 | if (last == 0) { |
967 | ext4_warning(sb, __FUNCTION__, | 966 | ext4_warning(sb, __FUNCTION__, |
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 69f875250500..1d12e4f7d69f 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
@@ -1433,8 +1433,8 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent) | |||
1433 | * block sizes. We need to calculate the offset from buffer start. | 1433 | * block sizes. We need to calculate the offset from buffer start. |
1434 | */ | 1434 | */ |
1435 | if (blocksize != EXT4_MIN_BLOCK_SIZE) { | 1435 | if (blocksize != EXT4_MIN_BLOCK_SIZE) { |
1436 | logic_sb_block = (sb_block * EXT4_MIN_BLOCK_SIZE) / blocksize; | 1436 | logic_sb_block = sb_block * EXT4_MIN_BLOCK_SIZE; |
1437 | offset = (sb_block * EXT4_MIN_BLOCK_SIZE) % blocksize; | 1437 | offset = sector_div(logic_sb_block, blocksize); |
1438 | } else { | 1438 | } else { |
1439 | logic_sb_block = sb_block; | 1439 | logic_sb_block = sb_block; |
1440 | } | 1440 | } |
@@ -1539,8 +1539,8 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent) | |||
1539 | 1539 | ||
1540 | brelse (bh); | 1540 | brelse (bh); |
1541 | sb_set_blocksize(sb, blocksize); | 1541 | sb_set_blocksize(sb, blocksize); |
1542 | logic_sb_block = (sb_block * EXT4_MIN_BLOCK_SIZE) / blocksize; | 1542 | logic_sb_block = sb_block * EXT4_MIN_BLOCK_SIZE; |
1543 | offset = (sb_block * EXT4_MIN_BLOCK_SIZE) % blocksize; | 1543 | offset = sector_div(logic_sb_block, blocksize); |
1544 | bh = sb_bread(sb, logic_sb_block); | 1544 | bh = sb_bread(sb, logic_sb_block); |
1545 | if (!bh) { | 1545 | if (!bh) { |
1546 | printk(KERN_ERR | 1546 | printk(KERN_ERR |
diff --git a/include/linux/ext4_fs.h b/include/linux/ext4_fs.h index b61181aadcbb..e952c6db9690 100644 --- a/include/linux/ext4_fs.h +++ b/include/linux/ext4_fs.h | |||
@@ -17,6 +17,7 @@ | |||
17 | #define _LINUX_EXT4_FS_H | 17 | #define _LINUX_EXT4_FS_H |
18 | 18 | ||
19 | #include <linux/types.h> | 19 | #include <linux/types.h> |
20 | #include <linux/blkdev.h> | ||
20 | #include <linux/magic.h> | 21 | #include <linux/magic.h> |
21 | 22 | ||
22 | /* | 23 | /* |
@@ -750,6 +751,27 @@ ext4_group_first_block_no(struct super_block *sb, unsigned long group_no) | |||
750 | #define ERR_BAD_DX_DIR -75000 | 751 | #define ERR_BAD_DX_DIR -75000 |
751 | 752 | ||
752 | /* | 753 | /* |
754 | * This function calculate the block group number and offset, | ||
755 | * given a block number | ||
756 | */ | ||
757 | |||
758 | static inline void ext4_get_group_no_and_offset(struct super_block * sb, | ||
759 | ext4_fsblk_t blocknr, unsigned long* blockgrpp, | ||
760 | ext4_grpblk_t *offsetp) | ||
761 | { | ||
762 | struct ext4_super_block *es = EXT4_SB(sb)->s_es; | ||
763 | ext4_grpblk_t offset; | ||
764 | |||
765 | blocknr = blocknr - le32_to_cpu(es->s_first_data_block); | ||
766 | offset = sector_div(blocknr, EXT4_BLOCKS_PER_GROUP(sb)); | ||
767 | if (offsetp) | ||
768 | *offsetp = offset; | ||
769 | if (blockgrpp) | ||
770 | *blockgrpp = blocknr; | ||
771 | |||
772 | } | ||
773 | |||
774 | /* | ||
753 | * Function prototypes | 775 | * Function prototypes |
754 | */ | 776 | */ |
755 | 777 | ||
@@ -762,6 +784,10 @@ ext4_group_first_block_no(struct super_block *sb, unsigned long group_no) | |||
762 | # define NORET_AND noreturn, | 784 | # define NORET_AND noreturn, |
763 | 785 | ||
764 | /* balloc.c */ | 786 | /* balloc.c */ |
787 | extern unsigned int ext4_block_group(struct super_block *sb, | ||
788 | ext4_fsblk_t blocknr); | ||
789 | extern ext4_grpblk_t ext4_block_group_offset(struct super_block *sb, | ||
790 | ext4_fsblk_t blocknr); | ||
765 | extern int ext4_bg_has_super(struct super_block *sb, int group); | 791 | extern int ext4_bg_has_super(struct super_block *sb, int group); |
766 | extern unsigned long ext4_bg_num_gdb(struct super_block *sb, int group); | 792 | extern unsigned long ext4_bg_num_gdb(struct super_block *sb, int group); |
767 | extern ext4_fsblk_t ext4_new_block (handle_t *handle, struct inode *inode, | 793 | extern ext4_fsblk_t ext4_new_block (handle_t *handle, struct inode *inode, |
diff --git a/include/linux/ext4_fs_i.h b/include/linux/ext4_fs_i.h index 40ce04a52b04..b2ccd9876bd1 100644 --- a/include/linux/ext4_fs_i.h +++ b/include/linux/ext4_fs_i.h | |||
@@ -25,9 +25,13 @@ | |||
25 | typedef int ext4_grpblk_t; | 25 | typedef int ext4_grpblk_t; |
26 | 26 | ||
27 | /* data type for filesystem-wide blocks number */ | 27 | /* data type for filesystem-wide blocks number */ |
28 | typedef unsigned long ext4_fsblk_t; | 28 | typedef sector_t ext4_fsblk_t; |
29 | 29 | ||
30 | #if BITS_PER_LONG == 64 | ||
30 | #define E3FSBLK "%lu" | 31 | #define E3FSBLK "%lu" |
32 | #else | ||
33 | #define E3FSBLK "%llu" | ||
34 | #endif | ||
31 | 35 | ||
32 | struct ext4_reserve_window { | 36 | struct ext4_reserve_window { |
33 | ext4_fsblk_t _rsv_start; /* First byte reserved */ | 37 | ext4_fsblk_t _rsv_start; /* First byte reserved */ |