diff options
author | Glauber de Oliveira Costa <glommer@br.ibm.com> | 2006-03-24 06:18:37 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-03-24 10:33:30 -0500 |
commit | b5a7c4f5835ae2805d00ca39709002cb03364143 (patch) | |
tree | 667be9c3dc48afae4cb9ace7366019974f05a9f8 | |
parent | d3561f78fd379a7110e46c87964ba7aa4120235c (diff) |
[PATCH] ext3: Properly report backup block present in a group
In filesystems with the meta block group flag on, ext3_bg_num_gdb() fails
to report the correct number of blocks used to store the group descriptor
backups in a given group. It happens because meta_bg follows a different
logic from the original ext3 backup placement in groups multiples of 3, 5
and 7.
Signed-off-by: Glauber de Oliveira Costa <glommer@br.ibm.com>
Cc: Andreas Dilger <adilger@clusterfs.com>
Cc: "Stephen C. Tweedie" <sct@redhat.com>
Cc: Alex Tomas <alex@clusterfs.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r-- | fs/ext3/balloc.c | 40 |
1 files changed, 33 insertions, 7 deletions
diff --git a/fs/ext3/balloc.c b/fs/ext3/balloc.c index 6250fcdf14a1..46623f77666b 100644 --- a/fs/ext3/balloc.c +++ b/fs/ext3/balloc.c | |||
@@ -1493,12 +1493,33 @@ static int ext3_group_sparse(int group) | |||
1493 | */ | 1493 | */ |
1494 | int ext3_bg_has_super(struct super_block *sb, int group) | 1494 | int ext3_bg_has_super(struct super_block *sb, int group) |
1495 | { | 1495 | { |
1496 | if (EXT3_HAS_RO_COMPAT_FEATURE(sb,EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER)&& | 1496 | if (EXT3_HAS_RO_COMPAT_FEATURE(sb, |
1497 | !ext3_group_sparse(group)) | 1497 | EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER) && |
1498 | !ext3_group_sparse(group)) | ||
1498 | return 0; | 1499 | return 0; |
1499 | return 1; | 1500 | return 1; |
1500 | } | 1501 | } |
1501 | 1502 | ||
1503 | static unsigned long ext3_bg_num_gdb_meta(struct super_block *sb, int group) | ||
1504 | { | ||
1505 | unsigned long metagroup = group / EXT3_DESC_PER_BLOCK(sb); | ||
1506 | unsigned long first = metagroup * EXT3_DESC_PER_BLOCK(sb); | ||
1507 | unsigned long last = first + EXT3_DESC_PER_BLOCK(sb) - 1; | ||
1508 | |||
1509 | if (group == first || group == first + 1 || group == last) | ||
1510 | return 1; | ||
1511 | return 0; | ||
1512 | } | ||
1513 | |||
1514 | static unsigned long ext3_bg_num_gdb_nometa(struct super_block *sb, int group) | ||
1515 | { | ||
1516 | if (EXT3_HAS_RO_COMPAT_FEATURE(sb, | ||
1517 | EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER) && | ||
1518 | !ext3_group_sparse(group)) | ||
1519 | return 0; | ||
1520 | return EXT3_SB(sb)->s_gdb_count; | ||
1521 | } | ||
1522 | |||
1502 | /** | 1523 | /** |
1503 | * ext3_bg_num_gdb - number of blocks used by the group table in group | 1524 | * ext3_bg_num_gdb - number of blocks used by the group table in group |
1504 | * @sb: superblock for filesystem | 1525 | * @sb: superblock for filesystem |
@@ -1510,9 +1531,14 @@ int ext3_bg_has_super(struct super_block *sb, int group) | |||
1510 | */ | 1531 | */ |
1511 | unsigned long ext3_bg_num_gdb(struct super_block *sb, int group) | 1532 | unsigned long ext3_bg_num_gdb(struct super_block *sb, int group) |
1512 | { | 1533 | { |
1513 | if (EXT3_HAS_RO_COMPAT_FEATURE(sb,EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER)&& | 1534 | unsigned long first_meta_bg = |
1514 | !ext3_group_sparse(group)) | 1535 | le32_to_cpu(EXT3_SB(sb)->s_es->s_first_meta_bg); |
1515 | return 0; | 1536 | unsigned long metagroup = group / EXT3_DESC_PER_BLOCK(sb); |
1516 | return EXT3_SB(sb)->s_gdb_count; | 1537 | |
1517 | } | 1538 | if (!EXT3_HAS_INCOMPAT_FEATURE(sb,EXT3_FEATURE_INCOMPAT_META_BG) || |
1539 | metagroup < first_meta_bg) | ||
1540 | return ext3_bg_num_gdb_nometa(sb,group); | ||
1518 | 1541 | ||
1542 | return ext3_bg_num_gdb_meta(sb,group); | ||
1543 | |||
1544 | } | ||