diff options
author | Laurent Vivier <Laurent.Vivier@bull.net> | 2006-10-11 04:21:10 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-10-11 14:14:17 -0400 |
commit | bd81d8eec043094d3ff729a8ff6d5b3a06d3c4b1 (patch) | |
tree | 6813a81b8d8453536839d8bcdc8ed924fdab3f44 /fs/ext4/super.c | |
parent | a1ddeb7eaecea6a924e3a79aa386797020cb436f (diff) |
[PATCH] ext4: 64bit metadata
In-kernel super block changes to support >32 bit free blocks numbers.
Signed-off-by: Laurent Vivier <Laurent.Vivier@bull.net>
Signed-off-by: Dave Kleikamp <shaggy@austin.ibm.com>
Signed-off-by: Alexandre Ratchov <alexandre.ratchov@bull.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs/ext4/super.c')
-rw-r--r-- | fs/ext4/super.c | 96 |
1 files changed, 68 insertions, 28 deletions
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 1d12e4f7d69f..b91dffd7a031 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
@@ -62,6 +62,43 @@ static void ext4_unlockfs(struct super_block *sb); | |||
62 | static void ext4_write_super (struct super_block * sb); | 62 | static void ext4_write_super (struct super_block * sb); |
63 | static void ext4_write_super_lockfs(struct super_block *sb); | 63 | static void ext4_write_super_lockfs(struct super_block *sb); |
64 | 64 | ||
65 | |||
66 | ext4_fsblk_t ext4_block_bitmap(struct ext4_group_desc *bg) | ||
67 | { | ||
68 | return le32_to_cpu(bg->bg_block_bitmap) | | ||
69 | ((ext4_fsblk_t)le16_to_cpu(bg->bg_block_bitmap_hi) << 32); | ||
70 | } | ||
71 | |||
72 | ext4_fsblk_t ext4_inode_bitmap(struct ext4_group_desc *bg) | ||
73 | { | ||
74 | return le32_to_cpu(bg->bg_inode_bitmap) | | ||
75 | ((ext4_fsblk_t)le16_to_cpu(bg->bg_inode_bitmap_hi) << 32); | ||
76 | } | ||
77 | |||
78 | ext4_fsblk_t ext4_inode_table(struct ext4_group_desc *bg) | ||
79 | { | ||
80 | return le32_to_cpu(bg->bg_inode_table) | | ||
81 | ((ext4_fsblk_t)le16_to_cpu(bg->bg_inode_table_hi) << 32); | ||
82 | } | ||
83 | |||
84 | void ext4_block_bitmap_set(struct ext4_group_desc *bg, ext4_fsblk_t blk) | ||
85 | { | ||
86 | bg->bg_block_bitmap = cpu_to_le32((u32)blk); | ||
87 | bg->bg_block_bitmap_hi = cpu_to_le16(blk >> 32); | ||
88 | } | ||
89 | |||
90 | void ext4_inode_bitmap_set(struct ext4_group_desc *bg, ext4_fsblk_t blk) | ||
91 | { | ||
92 | bg->bg_inode_bitmap = cpu_to_le32((u32)blk); | ||
93 | bg->bg_inode_bitmap_hi = cpu_to_le16(blk >> 32); | ||
94 | } | ||
95 | |||
96 | void ext4_inode_table_set(struct ext4_group_desc *bg, ext4_fsblk_t blk) | ||
97 | { | ||
98 | bg->bg_inode_table = cpu_to_le32((u32)blk); | ||
99 | bg->bg_inode_table_hi = cpu_to_le16(blk >> 32); | ||
100 | } | ||
101 | |||
65 | /* | 102 | /* |
66 | * Wrappers for jbd2_journal_start/end. | 103 | * Wrappers for jbd2_journal_start/end. |
67 | * | 104 | * |
@@ -1182,6 +1219,9 @@ static int ext4_check_descriptors (struct super_block * sb) | |||
1182 | struct ext4_sb_info *sbi = EXT4_SB(sb); | 1219 | struct ext4_sb_info *sbi = EXT4_SB(sb); |
1183 | ext4_fsblk_t first_block = le32_to_cpu(sbi->s_es->s_first_data_block); | 1220 | ext4_fsblk_t first_block = le32_to_cpu(sbi->s_es->s_first_data_block); |
1184 | ext4_fsblk_t last_block; | 1221 | ext4_fsblk_t last_block; |
1222 | ext4_fsblk_t block_bitmap; | ||
1223 | ext4_fsblk_t inode_bitmap; | ||
1224 | ext4_fsblk_t inode_table; | ||
1185 | struct ext4_group_desc * gdp = NULL; | 1225 | struct ext4_group_desc * gdp = NULL; |
1186 | int desc_block = 0; | 1226 | int desc_block = 0; |
1187 | int i; | 1227 | int i; |
@@ -1191,7 +1231,7 @@ static int ext4_check_descriptors (struct super_block * sb) | |||
1191 | for (i = 0; i < sbi->s_groups_count; i++) | 1231 | for (i = 0; i < sbi->s_groups_count; i++) |
1192 | { | 1232 | { |
1193 | if (i == sbi->s_groups_count - 1) | 1233 | if (i == sbi->s_groups_count - 1) |
1194 | last_block = le32_to_cpu(sbi->s_es->s_blocks_count) - 1; | 1234 | last_block = ext4_blocks_count(sbi->s_es) - 1; |
1195 | else | 1235 | else |
1196 | last_block = first_block + | 1236 | last_block = first_block + |
1197 | (EXT4_BLOCKS_PER_GROUP(sb) - 1); | 1237 | (EXT4_BLOCKS_PER_GROUP(sb) - 1); |
@@ -1199,42 +1239,39 @@ static int ext4_check_descriptors (struct super_block * sb) | |||
1199 | if ((i % EXT4_DESC_PER_BLOCK(sb)) == 0) | 1239 | if ((i % EXT4_DESC_PER_BLOCK(sb)) == 0) |
1200 | gdp = (struct ext4_group_desc *) | 1240 | gdp = (struct ext4_group_desc *) |
1201 | sbi->s_group_desc[desc_block++]->b_data; | 1241 | sbi->s_group_desc[desc_block++]->b_data; |
1202 | if (le32_to_cpu(gdp->bg_block_bitmap) < first_block || | 1242 | block_bitmap = ext4_block_bitmap(gdp); |
1203 | le32_to_cpu(gdp->bg_block_bitmap) > last_block) | 1243 | if (block_bitmap < first_block || block_bitmap > last_block) |
1204 | { | 1244 | { |
1205 | ext4_error (sb, "ext4_check_descriptors", | 1245 | ext4_error (sb, "ext4_check_descriptors", |
1206 | "Block bitmap for group %d" | 1246 | "Block bitmap for group %d" |
1207 | " not in group (block %lu)!", | 1247 | " not in group (block "E3FSBLK")!", |
1208 | i, (unsigned long) | 1248 | i, block_bitmap); |
1209 | le32_to_cpu(gdp->bg_block_bitmap)); | ||
1210 | return 0; | 1249 | return 0; |
1211 | } | 1250 | } |
1212 | if (le32_to_cpu(gdp->bg_inode_bitmap) < first_block || | 1251 | inode_bitmap = ext4_inode_bitmap(gdp); |
1213 | le32_to_cpu(gdp->bg_inode_bitmap) > last_block) | 1252 | if (inode_bitmap < first_block || inode_bitmap > last_block) |
1214 | { | 1253 | { |
1215 | ext4_error (sb, "ext4_check_descriptors", | 1254 | ext4_error (sb, "ext4_check_descriptors", |
1216 | "Inode bitmap for group %d" | 1255 | "Inode bitmap for group %d" |
1217 | " not in group (block %lu)!", | 1256 | " not in group (block "E3FSBLK")!", |
1218 | i, (unsigned long) | 1257 | i, inode_bitmap); |
1219 | le32_to_cpu(gdp->bg_inode_bitmap)); | ||
1220 | return 0; | 1258 | return 0; |
1221 | } | 1259 | } |
1222 | if (le32_to_cpu(gdp->bg_inode_table) < first_block || | 1260 | inode_table = ext4_inode_table(gdp); |
1223 | le32_to_cpu(gdp->bg_inode_table) + sbi->s_itb_per_group > | 1261 | if (inode_table < first_block || |
1224 | last_block) | 1262 | inode_table + sbi->s_itb_per_group > last_block) |
1225 | { | 1263 | { |
1226 | ext4_error (sb, "ext4_check_descriptors", | 1264 | ext4_error (sb, "ext4_check_descriptors", |
1227 | "Inode table for group %d" | 1265 | "Inode table for group %d" |
1228 | " not in group (block %lu)!", | 1266 | " not in group (block "E3FSBLK")!", |
1229 | i, (unsigned long) | 1267 | i, inode_table); |
1230 | le32_to_cpu(gdp->bg_inode_table)); | ||
1231 | return 0; | 1268 | return 0; |
1232 | } | 1269 | } |
1233 | first_block += EXT4_BLOCKS_PER_GROUP(sb); | 1270 | first_block += EXT4_BLOCKS_PER_GROUP(sb); |
1234 | gdp++; | 1271 | gdp++; |
1235 | } | 1272 | } |
1236 | 1273 | ||
1237 | sbi->s_es->s_free_blocks_count=cpu_to_le32(ext4_count_free_blocks(sb)); | 1274 | ext4_free_blocks_count_set(sbi->s_es, ext4_count_free_blocks(sb)); |
1238 | sbi->s_es->s_free_inodes_count=cpu_to_le32(ext4_count_free_inodes(sb)); | 1275 | sbi->s_es->s_free_inodes_count=cpu_to_le32(ext4_count_free_inodes(sb)); |
1239 | return 1; | 1276 | return 1; |
1240 | } | 1277 | } |
@@ -1411,6 +1448,7 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent) | |||
1411 | int i; | 1448 | int i; |
1412 | int needs_recovery; | 1449 | int needs_recovery; |
1413 | __le32 features; | 1450 | __le32 features; |
1451 | __u64 blocks_count; | ||
1414 | 1452 | ||
1415 | sbi = kzalloc(sizeof(*sbi), GFP_KERNEL); | 1453 | sbi = kzalloc(sizeof(*sbi), GFP_KERNEL); |
1416 | if (!sbi) | 1454 | if (!sbi) |
@@ -1620,7 +1658,7 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent) | |||
1620 | goto failed_mount; | 1658 | goto failed_mount; |
1621 | } | 1659 | } |
1622 | 1660 | ||
1623 | if (le32_to_cpu(es->s_blocks_count) > | 1661 | if (ext4_blocks_count(es) > |
1624 | (sector_t)(~0ULL) >> (sb->s_blocksize_bits - 9)) { | 1662 | (sector_t)(~0ULL) >> (sb->s_blocksize_bits - 9)) { |
1625 | printk(KERN_ERR "EXT4-fs: filesystem on %s:" | 1663 | printk(KERN_ERR "EXT4-fs: filesystem on %s:" |
1626 | " too large to mount safely\n", sb->s_id); | 1664 | " too large to mount safely\n", sb->s_id); |
@@ -1632,9 +1670,11 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent) | |||
1632 | 1670 | ||
1633 | if (EXT4_BLOCKS_PER_GROUP(sb) == 0) | 1671 | if (EXT4_BLOCKS_PER_GROUP(sb) == 0) |
1634 | goto cantfind_ext4; | 1672 | goto cantfind_ext4; |
1635 | sbi->s_groups_count = ((le32_to_cpu(es->s_blocks_count) - | 1673 | blocks_count = (ext4_blocks_count(es) - |
1636 | le32_to_cpu(es->s_first_data_block) - 1) | 1674 | le32_to_cpu(es->s_first_data_block) + |
1637 | / EXT4_BLOCKS_PER_GROUP(sb)) + 1; | 1675 | EXT4_BLOCKS_PER_GROUP(sb) - 1); |
1676 | do_div(blocks_count, EXT4_BLOCKS_PER_GROUP(sb)); | ||
1677 | sbi->s_groups_count = blocks_count; | ||
1638 | db_count = (sbi->s_groups_count + EXT4_DESC_PER_BLOCK(sb) - 1) / | 1678 | db_count = (sbi->s_groups_count + EXT4_DESC_PER_BLOCK(sb) - 1) / |
1639 | EXT4_DESC_PER_BLOCK(sb); | 1679 | EXT4_DESC_PER_BLOCK(sb); |
1640 | sbi->s_group_desc = kmalloc(db_count * sizeof (struct buffer_head *), | 1680 | sbi->s_group_desc = kmalloc(db_count * sizeof (struct buffer_head *), |
@@ -1949,7 +1989,7 @@ static journal_t *ext4_get_dev_journal(struct super_block *sb, | |||
1949 | goto out_bdev; | 1989 | goto out_bdev; |
1950 | } | 1990 | } |
1951 | 1991 | ||
1952 | len = le32_to_cpu(es->s_blocks_count); | 1992 | len = ext4_blocks_count(es); |
1953 | start = sb_block + 1; | 1993 | start = sb_block + 1; |
1954 | brelse(bh); /* we're done with the superblock */ | 1994 | brelse(bh); /* we're done with the superblock */ |
1955 | 1995 | ||
@@ -2119,7 +2159,7 @@ static void ext4_commit_super (struct super_block * sb, | |||
2119 | if (!sbh) | 2159 | if (!sbh) |
2120 | return; | 2160 | return; |
2121 | es->s_wtime = cpu_to_le32(get_seconds()); | 2161 | es->s_wtime = cpu_to_le32(get_seconds()); |
2122 | es->s_free_blocks_count = cpu_to_le32(ext4_count_free_blocks(sb)); | 2162 | ext4_free_blocks_count_set(es, ext4_count_free_blocks(sb)); |
2123 | es->s_free_inodes_count = cpu_to_le32(ext4_count_free_inodes(sb)); | 2163 | es->s_free_inodes_count = cpu_to_le32(ext4_count_free_inodes(sb)); |
2124 | BUFFER_TRACE(sbh, "marking dirty"); | 2164 | BUFFER_TRACE(sbh, "marking dirty"); |
2125 | mark_buffer_dirty(sbh); | 2165 | mark_buffer_dirty(sbh); |
@@ -2312,7 +2352,7 @@ static int ext4_remount (struct super_block * sb, int * flags, char * data) | |||
2312 | ext4_init_journal_params(sb, sbi->s_journal); | 2352 | ext4_init_journal_params(sb, sbi->s_journal); |
2313 | 2353 | ||
2314 | if ((*flags & MS_RDONLY) != (sb->s_flags & MS_RDONLY) || | 2354 | if ((*flags & MS_RDONLY) != (sb->s_flags & MS_RDONLY) || |
2315 | n_blocks_count > le32_to_cpu(es->s_blocks_count)) { | 2355 | n_blocks_count > ext4_blocks_count(es)) { |
2316 | if (sbi->s_mount_opt & EXT4_MOUNT_ABORT) { | 2356 | if (sbi->s_mount_opt & EXT4_MOUNT_ABORT) { |
2317 | err = -EROFS; | 2357 | err = -EROFS; |
2318 | goto restore_opts; | 2358 | goto restore_opts; |
@@ -2431,10 +2471,10 @@ static int ext4_statfs (struct dentry * dentry, struct kstatfs * buf) | |||
2431 | 2471 | ||
2432 | buf->f_type = EXT4_SUPER_MAGIC; | 2472 | buf->f_type = EXT4_SUPER_MAGIC; |
2433 | buf->f_bsize = sb->s_blocksize; | 2473 | buf->f_bsize = sb->s_blocksize; |
2434 | buf->f_blocks = le32_to_cpu(es->s_blocks_count) - overhead; | 2474 | buf->f_blocks = ext4_blocks_count(es) - overhead; |
2435 | buf->f_bfree = percpu_counter_sum(&sbi->s_freeblocks_counter); | 2475 | buf->f_bfree = percpu_counter_sum(&sbi->s_freeblocks_counter); |
2436 | buf->f_bavail = buf->f_bfree - le32_to_cpu(es->s_r_blocks_count); | 2476 | buf->f_bavail = buf->f_bfree - ext4_r_blocks_count(es); |
2437 | if (buf->f_bfree < le32_to_cpu(es->s_r_blocks_count)) | 2477 | if (buf->f_bfree < ext4_r_blocks_count(es)) |
2438 | buf->f_bavail = 0; | 2478 | buf->f_bavail = 0; |
2439 | buf->f_files = le32_to_cpu(es->s_inodes_count); | 2479 | buf->f_files = le32_to_cpu(es->s_inodes_count); |
2440 | buf->f_ffree = percpu_counter_sum(&sbi->s_freeinodes_counter); | 2480 | buf->f_ffree = percpu_counter_sum(&sbi->s_freeinodes_counter); |