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 | |
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')
-rw-r--r-- | fs/ext4/balloc.c | 50 | ||||
-rw-r--r-- | fs/ext4/ialloc.c | 8 | ||||
-rw-r--r-- | fs/ext4/inode.c | 6 | ||||
-rw-r--r-- | fs/ext4/resize.c | 52 | ||||
-rw-r--r-- | fs/ext4/super.c | 96 |
5 files changed, 128 insertions, 84 deletions
diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c index aa33ff271fa9..6887151ccc47 100644 --- a/fs/ext4/balloc.c +++ b/fs/ext4/balloc.c | |||
@@ -99,12 +99,13 @@ read_block_bitmap(struct super_block *sb, unsigned int block_group) | |||
99 | desc = ext4_get_group_desc (sb, block_group, NULL); | 99 | desc = ext4_get_group_desc (sb, block_group, NULL); |
100 | if (!desc) | 100 | if (!desc) |
101 | goto error_out; | 101 | goto error_out; |
102 | bh = sb_bread(sb, le32_to_cpu(desc->bg_block_bitmap)); | 102 | bh = sb_bread(sb, ext4_block_bitmap(desc)); |
103 | if (!bh) | 103 | if (!bh) |
104 | ext4_error (sb, "read_block_bitmap", | 104 | ext4_error (sb, "read_block_bitmap", |
105 | "Cannot read block bitmap - " | 105 | "Cannot read block bitmap - " |
106 | "block_group = %d, block_bitmap = %u", | 106 | "block_group = %d, block_bitmap = "E3FSBLK, |
107 | block_group, le32_to_cpu(desc->bg_block_bitmap)); | 107 | block_group, |
108 | ext4_block_bitmap(desc)); | ||
108 | error_out: | 109 | error_out: |
109 | return bh; | 110 | return bh; |
110 | } | 111 | } |
@@ -432,14 +433,14 @@ void ext4_free_blocks_sb(handle_t *handle, struct super_block *sb, | |||
432 | es = sbi->s_es; | 433 | es = sbi->s_es; |
433 | if (block < le32_to_cpu(es->s_first_data_block) || | 434 | if (block < le32_to_cpu(es->s_first_data_block) || |
434 | block + count < block || | 435 | block + count < block || |
435 | block + count > le32_to_cpu(es->s_blocks_count)) { | 436 | block + count > ext4_blocks_count(es)) { |
436 | ext4_error (sb, "ext4_free_blocks", | 437 | ext4_error (sb, "ext4_free_blocks", |
437 | "Freeing blocks not in datazone - " | 438 | "Freeing blocks not in datazone - " |
438 | "block = "E3FSBLK", count = %lu", block, count); | 439 | "block = "E3FSBLK", count = %lu", block, count); |
439 | goto error_return; | 440 | goto error_return; |
440 | } | 441 | } |
441 | 442 | ||
442 | ext4_debug ("freeing block(s) %lu-%lu\n", block, block + count - 1); | 443 | ext4_debug ("freeing block(s) %llu-%llu\n", block, block + count - 1); |
443 | 444 | ||
444 | do_more: | 445 | do_more: |
445 | overflow = 0; | 446 | overflow = 0; |
@@ -460,12 +461,11 @@ do_more: | |||
460 | if (!desc) | 461 | if (!desc) |
461 | goto error_return; | 462 | goto error_return; |
462 | 463 | ||
463 | if (in_range (le32_to_cpu(desc->bg_block_bitmap), block, count) || | 464 | if (in_range(ext4_block_bitmap(desc), block, count) || |
464 | in_range (le32_to_cpu(desc->bg_inode_bitmap), block, count) || | 465 | in_range(ext4_inode_bitmap(desc), block, count) || |
465 | in_range (block, le32_to_cpu(desc->bg_inode_table), | 466 | in_range(block, ext4_inode_table(desc), sbi->s_itb_per_group) || |
466 | sbi->s_itb_per_group) || | 467 | in_range(block + count - 1, ext4_inode_table(desc), |
467 | in_range (block + count - 1, le32_to_cpu(desc->bg_inode_table), | 468 | sbi->s_itb_per_group)) |
468 | sbi->s_itb_per_group)) | ||
469 | ext4_error (sb, "ext4_free_blocks", | 469 | ext4_error (sb, "ext4_free_blocks", |
470 | "Freeing blocks in system zones - " | 470 | "Freeing blocks in system zones - " |
471 | "Block = "E3FSBLK", count = %lu", | 471 | "Block = "E3FSBLK", count = %lu", |
@@ -552,8 +552,8 @@ do_more: | |||
552 | bit + i, bitmap_bh->b_data)) { | 552 | bit + i, bitmap_bh->b_data)) { |
553 | jbd_unlock_bh_state(bitmap_bh); | 553 | jbd_unlock_bh_state(bitmap_bh); |
554 | ext4_error(sb, __FUNCTION__, | 554 | ext4_error(sb, __FUNCTION__, |
555 | "bit already cleared for block "E3FSBLK, | 555 | "bit already cleared for block "E3FSBLK, |
556 | block + i); | 556 | (ext4_fsblk_t)(block + i)); |
557 | jbd_lock_bh_state(bitmap_bh); | 557 | jbd_lock_bh_state(bitmap_bh); |
558 | BUFFER_TRACE(bitmap_bh, "bit already cleared"); | 558 | BUFFER_TRACE(bitmap_bh, "bit already cleared"); |
559 | } else { | 559 | } else { |
@@ -1351,7 +1351,7 @@ static int ext4_has_free_blocks(struct ext4_sb_info *sbi) | |||
1351 | ext4_fsblk_t free_blocks, root_blocks; | 1351 | ext4_fsblk_t free_blocks, root_blocks; |
1352 | 1352 | ||
1353 | free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter); | 1353 | free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter); |
1354 | root_blocks = le32_to_cpu(sbi->s_es->s_r_blocks_count); | 1354 | root_blocks = ext4_r_blocks_count(sbi->s_es); |
1355 | if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) && | 1355 | if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) && |
1356 | sbi->s_resuid != current->fsuid && | 1356 | sbi->s_resuid != current->fsuid && |
1357 | (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) { | 1357 | (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) { |
@@ -1462,7 +1462,7 @@ ext4_fsblk_t ext4_new_blocks(handle_t *handle, struct inode *inode, | |||
1462 | * First, test whether the goal block is free. | 1462 | * First, test whether the goal block is free. |
1463 | */ | 1463 | */ |
1464 | if (goal < le32_to_cpu(es->s_first_data_block) || | 1464 | if (goal < le32_to_cpu(es->s_first_data_block) || |
1465 | goal >= le32_to_cpu(es->s_blocks_count)) | 1465 | goal >= ext4_blocks_count(es)) |
1466 | goal = le32_to_cpu(es->s_first_data_block); | 1466 | goal = le32_to_cpu(es->s_first_data_block); |
1467 | ext4_get_group_no_and_offset(sb, goal, &group_no, &grp_target_blk); | 1467 | ext4_get_group_no_and_offset(sb, goal, &group_no, &grp_target_blk); |
1468 | goal_group = group_no; | 1468 | goal_group = group_no; |
@@ -1561,12 +1561,12 @@ allocated: | |||
1561 | 1561 | ||
1562 | ret_block = grp_alloc_blk + ext4_group_first_block_no(sb, group_no); | 1562 | ret_block = grp_alloc_blk + ext4_group_first_block_no(sb, group_no); |
1563 | 1563 | ||
1564 | if (in_range(le32_to_cpu(gdp->bg_block_bitmap), ret_block, num) || | 1564 | if (in_range(ext4_block_bitmap(gdp), ret_block, num) || |
1565 | in_range(le32_to_cpu(gdp->bg_inode_bitmap), ret_block, num) || | 1565 | in_range(ext4_block_bitmap(gdp), ret_block, num) || |
1566 | in_range(ret_block, le32_to_cpu(gdp->bg_inode_table), | 1566 | in_range(ret_block, ext4_inode_table(gdp), |
1567 | EXT4_SB(sb)->s_itb_per_group) || | 1567 | EXT4_SB(sb)->s_itb_per_group) || |
1568 | in_range(ret_block + num - 1, le32_to_cpu(gdp->bg_inode_table), | 1568 | in_range(ret_block + num - 1, ext4_inode_table(gdp), |
1569 | EXT4_SB(sb)->s_itb_per_group)) | 1569 | EXT4_SB(sb)->s_itb_per_group)) |
1570 | ext4_error(sb, "ext4_new_block", | 1570 | ext4_error(sb, "ext4_new_block", |
1571 | "Allocating block in system zone - " | 1571 | "Allocating block in system zone - " |
1572 | "blocks from "E3FSBLK", length %lu", | 1572 | "blocks from "E3FSBLK", length %lu", |
@@ -1604,11 +1604,11 @@ allocated: | |||
1604 | jbd_unlock_bh_state(bitmap_bh); | 1604 | jbd_unlock_bh_state(bitmap_bh); |
1605 | #endif | 1605 | #endif |
1606 | 1606 | ||
1607 | if (ret_block + num - 1 >= le32_to_cpu(es->s_blocks_count)) { | 1607 | if (ret_block + num - 1 >= ext4_blocks_count(es)) { |
1608 | ext4_error(sb, "ext4_new_block", | 1608 | ext4_error(sb, "ext4_new_block", |
1609 | "block("E3FSBLK") >= blocks count(%d) - " | 1609 | "block("E3FSBLK") >= blocks count("E3FSBLK") - " |
1610 | "block_group = %lu, es == %p ", ret_block, | 1610 | "block_group = %lu, es == %p ", ret_block, |
1611 | le32_to_cpu(es->s_blocks_count), group_no, es); | 1611 | ext4_blocks_count(es), group_no, es); |
1612 | goto out; | 1612 | goto out; |
1613 | } | 1613 | } |
1614 | 1614 | ||
@@ -1707,7 +1707,7 @@ ext4_fsblk_t ext4_count_free_blocks(struct super_block *sb) | |||
1707 | brelse(bitmap_bh); | 1707 | brelse(bitmap_bh); |
1708 | printk("ext4_count_free_blocks: stored = "E3FSBLK | 1708 | printk("ext4_count_free_blocks: stored = "E3FSBLK |
1709 | ", computed = "E3FSBLK", "E3FSBLK"\n", | 1709 | ", computed = "E3FSBLK", "E3FSBLK"\n", |
1710 | le32_to_cpu(es->s_free_blocks_count), | 1710 | EXT4_FREE_BLOCKS_COUNT(es), |
1711 | desc_count, bitmap_count); | 1711 | desc_count, bitmap_count); |
1712 | return bitmap_count; | 1712 | return bitmap_count; |
1713 | #else | 1713 | #else |
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c index 94e1bb4abe31..959b7fa8f5db 100644 --- a/fs/ext4/ialloc.c +++ b/fs/ext4/ialloc.c | |||
@@ -60,12 +60,12 @@ read_inode_bitmap(struct super_block * sb, unsigned long block_group) | |||
60 | if (!desc) | 60 | if (!desc) |
61 | goto error_out; | 61 | goto error_out; |
62 | 62 | ||
63 | bh = sb_bread(sb, le32_to_cpu(desc->bg_inode_bitmap)); | 63 | bh = sb_bread(sb, ext4_inode_bitmap(desc)); |
64 | if (!bh) | 64 | if (!bh) |
65 | ext4_error(sb, "read_inode_bitmap", | 65 | ext4_error(sb, "read_inode_bitmap", |
66 | "Cannot read inode bitmap - " | 66 | "Cannot read inode bitmap - " |
67 | "block_group = %lu, inode_bitmap = %u", | 67 | "block_group = %lu, inode_bitmap = %llu", |
68 | block_group, le32_to_cpu(desc->bg_inode_bitmap)); | 68 | block_group, ext4_inode_bitmap(desc)); |
69 | error_out: | 69 | error_out: |
70 | return bh; | 70 | return bh; |
71 | } | 71 | } |
@@ -304,7 +304,7 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent) | |||
304 | goto fallback; | 304 | goto fallback; |
305 | } | 305 | } |
306 | 306 | ||
307 | blocks_per_dir = le32_to_cpu(es->s_blocks_count) - freeb; | 307 | blocks_per_dir = ext4_blocks_count(es) - freeb; |
308 | sector_div(blocks_per_dir, ndirs); | 308 | sector_div(blocks_per_dir, ndirs); |
309 | 309 | ||
310 | max_dirs = ndirs / ngroups + inodes_per_group / 16; | 310 | max_dirs = ndirs / ngroups + inodes_per_group / 16; |
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 9db8cff3baa4..effc38afebe3 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
@@ -2438,8 +2438,8 @@ static ext4_fsblk_t ext4_get_inode_block(struct super_block *sb, | |||
2438 | */ | 2438 | */ |
2439 | offset = ((ino - 1) % EXT4_INODES_PER_GROUP(sb)) * | 2439 | offset = ((ino - 1) % EXT4_INODES_PER_GROUP(sb)) * |
2440 | EXT4_INODE_SIZE(sb); | 2440 | EXT4_INODE_SIZE(sb); |
2441 | block = le32_to_cpu(gdp[desc].bg_inode_table) + | 2441 | block = ext4_inode_table(gdp + desc) + |
2442 | (offset >> EXT4_BLOCK_SIZE_BITS(sb)); | 2442 | (offset >> EXT4_BLOCK_SIZE_BITS(sb)); |
2443 | 2443 | ||
2444 | iloc->block_group = block_group; | 2444 | iloc->block_group = block_group; |
2445 | iloc->offset = offset & (EXT4_BLOCK_SIZE(sb) - 1); | 2445 | iloc->offset = offset & (EXT4_BLOCK_SIZE(sb) - 1); |
@@ -2506,7 +2506,7 @@ static int __ext4_get_inode_loc(struct inode *inode, | |||
2506 | goto make_io; | 2506 | goto make_io; |
2507 | 2507 | ||
2508 | bitmap_bh = sb_getblk(inode->i_sb, | 2508 | bitmap_bh = sb_getblk(inode->i_sb, |
2509 | le32_to_cpu(desc->bg_inode_bitmap)); | 2509 | ext4_inode_bitmap(desc)); |
2510 | if (!bitmap_bh) | 2510 | if (!bitmap_bh) |
2511 | goto make_io; | 2511 | goto make_io; |
2512 | 2512 | ||
diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c index c60bfed5f5e7..3dbf91b82202 100644 --- a/fs/ext4/resize.c +++ b/fs/ext4/resize.c | |||
@@ -27,7 +27,7 @@ static int verify_group_input(struct super_block *sb, | |||
27 | { | 27 | { |
28 | struct ext4_sb_info *sbi = EXT4_SB(sb); | 28 | struct ext4_sb_info *sbi = EXT4_SB(sb); |
29 | struct ext4_super_block *es = sbi->s_es; | 29 | struct ext4_super_block *es = sbi->s_es; |
30 | ext4_fsblk_t start = le32_to_cpu(es->s_blocks_count); | 30 | ext4_fsblk_t start = ext4_blocks_count(es); |
31 | ext4_fsblk_t end = start + input->blocks_count; | 31 | ext4_fsblk_t end = start + input->blocks_count; |
32 | unsigned group = input->group; | 32 | unsigned group = input->group; |
33 | ext4_fsblk_t itend = input->inode_table + sbi->s_itb_per_group; | 33 | ext4_fsblk_t itend = input->inode_table + sbi->s_itb_per_group; |
@@ -68,43 +68,43 @@ static int verify_group_input(struct super_block *sb, | |||
68 | end - 1); | 68 | end - 1); |
69 | else if (outside(input->block_bitmap, start, end)) | 69 | else if (outside(input->block_bitmap, start, end)) |
70 | ext4_warning(sb, __FUNCTION__, | 70 | ext4_warning(sb, __FUNCTION__, |
71 | "Block bitmap not in group (block %u)", | 71 | "Block bitmap not in group (block %llu)", |
72 | input->block_bitmap); | 72 | input->block_bitmap); |
73 | else if (outside(input->inode_bitmap, start, end)) | 73 | else if (outside(input->inode_bitmap, start, end)) |
74 | ext4_warning(sb, __FUNCTION__, | 74 | ext4_warning(sb, __FUNCTION__, |
75 | "Inode bitmap not in group (block %u)", | 75 | "Inode bitmap not in group (block %llu)", |
76 | input->inode_bitmap); | 76 | input->inode_bitmap); |
77 | else if (outside(input->inode_table, start, end) || | 77 | else if (outside(input->inode_table, start, end) || |
78 | outside(itend - 1, start, end)) | 78 | outside(itend - 1, start, end)) |
79 | ext4_warning(sb, __FUNCTION__, | 79 | ext4_warning(sb, __FUNCTION__, |
80 | "Inode table not in group (blocks %u-"E3FSBLK")", | 80 | "Inode table not in group (blocks %llu-%llu)", |
81 | input->inode_table, itend - 1); | 81 | input->inode_table, itend - 1); |
82 | else if (input->inode_bitmap == input->block_bitmap) | 82 | else if (input->inode_bitmap == input->block_bitmap) |
83 | ext4_warning(sb, __FUNCTION__, | 83 | ext4_warning(sb, __FUNCTION__, |
84 | "Block bitmap same as inode bitmap (%u)", | 84 | "Block bitmap same as inode bitmap (%llu)", |
85 | input->block_bitmap); | 85 | input->block_bitmap); |
86 | else if (inside(input->block_bitmap, input->inode_table, itend)) | 86 | else if (inside(input->block_bitmap, input->inode_table, itend)) |
87 | ext4_warning(sb, __FUNCTION__, | 87 | ext4_warning(sb, __FUNCTION__, |
88 | "Block bitmap (%u) in inode table (%u-"E3FSBLK")", | 88 | "Block bitmap (%llu) in inode table (%llu-%llu)", |
89 | input->block_bitmap, input->inode_table, itend-1); | 89 | input->block_bitmap, input->inode_table, itend-1); |
90 | else if (inside(input->inode_bitmap, input->inode_table, itend)) | 90 | else if (inside(input->inode_bitmap, input->inode_table, itend)) |
91 | ext4_warning(sb, __FUNCTION__, | 91 | ext4_warning(sb, __FUNCTION__, |
92 | "Inode bitmap (%u) in inode table (%u-"E3FSBLK")", | 92 | "Inode bitmap (%llu) in inode table (%llu-%llu)", |
93 | input->inode_bitmap, input->inode_table, itend-1); | 93 | input->inode_bitmap, input->inode_table, itend-1); |
94 | else if (inside(input->block_bitmap, start, metaend)) | 94 | else if (inside(input->block_bitmap, start, metaend)) |
95 | ext4_warning(sb, __FUNCTION__, | 95 | ext4_warning(sb, __FUNCTION__, |
96 | "Block bitmap (%u) in GDT table" | 96 | "Block bitmap (%llu) in GDT table" |
97 | " ("E3FSBLK"-"E3FSBLK")", | 97 | " ("E3FSBLK"-"E3FSBLK")", |
98 | input->block_bitmap, start, metaend - 1); | 98 | input->block_bitmap, start, metaend - 1); |
99 | else if (inside(input->inode_bitmap, start, metaend)) | 99 | else if (inside(input->inode_bitmap, start, metaend)) |
100 | ext4_warning(sb, __FUNCTION__, | 100 | ext4_warning(sb, __FUNCTION__, |
101 | "Inode bitmap (%u) in GDT table" | 101 | "Inode bitmap (%llu) in GDT table" |
102 | " ("E3FSBLK"-"E3FSBLK")", | 102 | " ("E3FSBLK"-"E3FSBLK")", |
103 | input->inode_bitmap, start, metaend - 1); | 103 | input->inode_bitmap, start, metaend - 1); |
104 | else if (inside(input->inode_table, start, metaend) || | 104 | else if (inside(input->inode_table, start, metaend) || |
105 | inside(itend - 1, start, metaend)) | 105 | inside(itend - 1, start, metaend)) |
106 | ext4_warning(sb, __FUNCTION__, | 106 | ext4_warning(sb, __FUNCTION__, |
107 | "Inode table (%u-"E3FSBLK") overlaps" | 107 | "Inode table ("E3FSBLK"-"E3FSBLK") overlaps" |
108 | "GDT table ("E3FSBLK"-"E3FSBLK")", | 108 | "GDT table ("E3FSBLK"-"E3FSBLK")", |
109 | input->inode_table, itend - 1, start, metaend - 1); | 109 | input->inode_table, itend - 1, start, metaend - 1); |
110 | else | 110 | else |
@@ -286,6 +286,7 @@ exit_journal: | |||
286 | return err; | 286 | return err; |
287 | } | 287 | } |
288 | 288 | ||
289 | |||
289 | /* | 290 | /* |
290 | * Iterate through the groups which hold BACKUP superblock/GDT copies in an | 291 | * Iterate through the groups which hold BACKUP superblock/GDT copies in an |
291 | * ext4 filesystem. The counters should be initialized to 1, 5, and 7 before | 292 | * ext4 filesystem. The counters should be initialized to 1, 5, and 7 before |
@@ -340,12 +341,15 @@ static int verify_reserved_gdb(struct super_block *sb, | |||
340 | int gdbackups = 0; | 341 | int gdbackups = 0; |
341 | 342 | ||
342 | while ((grp = ext4_list_backups(sb, &three, &five, &seven)) < end) { | 343 | while ((grp = ext4_list_backups(sb, &three, &five, &seven)) < end) { |
343 | if (le32_to_cpu(*p++) != grp * EXT4_BLOCKS_PER_GROUP(sb) + blk){ | 344 | if (le32_to_cpu(*p++) != |
345 | grp * EXT4_BLOCKS_PER_GROUP(sb) + blk){ | ||
344 | ext4_warning(sb, __FUNCTION__, | 346 | ext4_warning(sb, __FUNCTION__, |
345 | "reserved GDT "E3FSBLK | 347 | "reserved GDT "E3FSBLK |
346 | " missing grp %d ("E3FSBLK")", | 348 | " missing grp %d ("E3FSBLK")", |
347 | blk, grp, | 349 | blk, grp, |
348 | grp * EXT4_BLOCKS_PER_GROUP(sb) + blk); | 350 | grp * |
351 | (ext4_fsblk_t)EXT4_BLOCKS_PER_GROUP(sb) + | ||
352 | blk); | ||
349 | return -EINVAL; | 353 | return -EINVAL; |
350 | } | 354 | } |
351 | if (++gdbackups > EXT4_ADDR_PER_BLOCK(sb)) | 355 | if (++gdbackups > EXT4_ADDR_PER_BLOCK(sb)) |
@@ -731,8 +735,8 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input) | |||
731 | return -EPERM; | 735 | return -EPERM; |
732 | } | 736 | } |
733 | 737 | ||
734 | if (le32_to_cpu(es->s_blocks_count) + input->blocks_count < | 738 | if (ext4_blocks_count(es) + input->blocks_count < |
735 | le32_to_cpu(es->s_blocks_count)) { | 739 | ext4_blocks_count(es)) { |
736 | ext4_warning(sb, __FUNCTION__, "blocks_count overflow\n"); | 740 | ext4_warning(sb, __FUNCTION__, "blocks_count overflow\n"); |
737 | return -EINVAL; | 741 | return -EINVAL; |
738 | } | 742 | } |
@@ -830,9 +834,9 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input) | |||
830 | /* Update group descriptor block for new group */ | 834 | /* Update group descriptor block for new group */ |
831 | gdp = (struct ext4_group_desc *)primary->b_data + gdb_off; | 835 | gdp = (struct ext4_group_desc *)primary->b_data + gdb_off; |
832 | 836 | ||
833 | gdp->bg_block_bitmap = cpu_to_le32(input->block_bitmap); | 837 | ext4_block_bitmap_set(gdp, input->block_bitmap); /* LV FIXME */ |
834 | gdp->bg_inode_bitmap = cpu_to_le32(input->inode_bitmap); | 838 | ext4_inode_bitmap_set(gdp, input->inode_bitmap); /* LV FIXME */ |
835 | gdp->bg_inode_table = cpu_to_le32(input->inode_table); | 839 | ext4_inode_table_set(gdp, input->inode_table); /* LV FIXME */ |
836 | gdp->bg_free_blocks_count = cpu_to_le16(input->free_blocks_count); | 840 | gdp->bg_free_blocks_count = cpu_to_le16(input->free_blocks_count); |
837 | gdp->bg_free_inodes_count = cpu_to_le16(EXT4_INODES_PER_GROUP(sb)); | 841 | gdp->bg_free_inodes_count = cpu_to_le16(EXT4_INODES_PER_GROUP(sb)); |
838 | 842 | ||
@@ -846,7 +850,7 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input) | |||
846 | * blocks/inodes before the group is live won't actually let us | 850 | * blocks/inodes before the group is live won't actually let us |
847 | * allocate the new space yet. | 851 | * allocate the new space yet. |
848 | */ | 852 | */ |
849 | es->s_blocks_count = cpu_to_le32(le32_to_cpu(es->s_blocks_count) + | 853 | ext4_blocks_count_set(es, ext4_blocks_count(es) + |
850 | input->blocks_count); | 854 | input->blocks_count); |
851 | es->s_inodes_count = cpu_to_le32(le32_to_cpu(es->s_inodes_count) + | 855 | es->s_inodes_count = cpu_to_le32(le32_to_cpu(es->s_inodes_count) + |
852 | EXT4_INODES_PER_GROUP(sb)); | 856 | EXT4_INODES_PER_GROUP(sb)); |
@@ -882,7 +886,7 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input) | |||
882 | 886 | ||
883 | /* Update the reserved block counts only once the new group is | 887 | /* Update the reserved block counts only once the new group is |
884 | * active. */ | 888 | * active. */ |
885 | es->s_r_blocks_count = cpu_to_le32(le32_to_cpu(es->s_r_blocks_count) + | 889 | ext4_r_blocks_count_set(es, ext4_r_blocks_count(es) + |
886 | input->reserved_blocks); | 890 | input->reserved_blocks); |
887 | 891 | ||
888 | /* Update the free space counts */ | 892 | /* Update the free space counts */ |
@@ -933,7 +937,7 @@ int ext4_group_extend(struct super_block *sb, struct ext4_super_block *es, | |||
933 | /* We don't need to worry about locking wrt other resizers just | 937 | /* We don't need to worry about locking wrt other resizers just |
934 | * yet: we're going to revalidate es->s_blocks_count after | 938 | * yet: we're going to revalidate es->s_blocks_count after |
935 | * taking lock_super() below. */ | 939 | * taking lock_super() below. */ |
936 | o_blocks_count = le32_to_cpu(es->s_blocks_count); | 940 | o_blocks_count = ext4_blocks_count(es); |
937 | o_groups_count = EXT4_SB(sb)->s_groups_count; | 941 | o_groups_count = EXT4_SB(sb)->s_groups_count; |
938 | 942 | ||
939 | if (test_opt(sb, DEBUG)) | 943 | if (test_opt(sb, DEBUG)) |
@@ -1004,7 +1008,7 @@ int ext4_group_extend(struct super_block *sb, struct ext4_super_block *es, | |||
1004 | } | 1008 | } |
1005 | 1009 | ||
1006 | lock_super(sb); | 1010 | lock_super(sb); |
1007 | if (o_blocks_count != le32_to_cpu(es->s_blocks_count)) { | 1011 | if (o_blocks_count != ext4_blocks_count(es)) { |
1008 | ext4_warning(sb, __FUNCTION__, | 1012 | ext4_warning(sb, __FUNCTION__, |
1009 | "multiple resizers run on filesystem!"); | 1013 | "multiple resizers run on filesystem!"); |
1010 | unlock_super(sb); | 1014 | unlock_super(sb); |
@@ -1020,7 +1024,7 @@ int ext4_group_extend(struct super_block *sb, struct ext4_super_block *es, | |||
1020 | ext4_journal_stop(handle); | 1024 | ext4_journal_stop(handle); |
1021 | goto exit_put; | 1025 | goto exit_put; |
1022 | } | 1026 | } |
1023 | es->s_blocks_count = cpu_to_le32(o_blocks_count + add); | 1027 | ext4_blocks_count_set(es, o_blocks_count + add); |
1024 | ext4_journal_dirty_metadata(handle, EXT4_SB(sb)->s_sbh); | 1028 | ext4_journal_dirty_metadata(handle, EXT4_SB(sb)->s_sbh); |
1025 | sb->s_dirt = 1; | 1029 | sb->s_dirt = 1; |
1026 | unlock_super(sb); | 1030 | unlock_super(sb); |
@@ -1032,8 +1036,8 @@ int ext4_group_extend(struct super_block *sb, struct ext4_super_block *es, | |||
1032 | if ((err = ext4_journal_stop(handle))) | 1036 | if ((err = ext4_journal_stop(handle))) |
1033 | goto exit_put; | 1037 | goto exit_put; |
1034 | if (test_opt(sb, DEBUG)) | 1038 | if (test_opt(sb, DEBUG)) |
1035 | printk(KERN_DEBUG "EXT4-fs: extended group to %u blocks\n", | 1039 | printk(KERN_DEBUG "EXT4-fs: extended group to %llu blocks\n", |
1036 | le32_to_cpu(es->s_blocks_count)); | 1040 | ext4_blocks_count(es)); |
1037 | update_backups(sb, EXT4_SB(sb)->s_sbh->b_blocknr, (char *)es, | 1041 | update_backups(sb, EXT4_SB(sb)->s_sbh->b_blocknr, (char *)es, |
1038 | sizeof(struct ext4_super_block)); | 1042 | sizeof(struct ext4_super_block)); |
1039 | exit_put: | 1043 | exit_put: |
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); |