aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGlauber de Oliveira Costa <glommer@br.ibm.com>2006-03-24 06:18:37 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-03-24 10:33:30 -0500
commitb5a7c4f5835ae2805d00ca39709002cb03364143 (patch)
tree667be9c3dc48afae4cb9ace7366019974f05a9f8
parentd3561f78fd379a7110e46c87964ba7aa4120235c (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.c40
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 */
1494int ext3_bg_has_super(struct super_block *sb, int group) 1494int 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
1503static 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
1514static 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 */
1511unsigned long ext3_bg_num_gdb(struct super_block *sb, int group) 1532unsigned 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}