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 | } | ||
