Commit b5a7c4f5835ae2805d00ca39709002cb03364143
Committed by
Linus Torvalds
1 parent
d3561f78fd
Exists in
master
and in
7 other branches
[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>
Showing 1 changed file with 33 additions and 7 deletions Side-by-side Diff
fs/ext3/balloc.c
| ... | ... | @@ -1493,12 +1493,33 @@ |
| 1493 | 1493 | */ |
| 1494 | 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)&& | |
| 1497 | - !ext3_group_sparse(group)) | |
| 1496 | + if (EXT3_HAS_RO_COMPAT_FEATURE(sb, | |
| 1497 | + EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER) && | |
| 1498 | + !ext3_group_sparse(group)) | |
| 1498 | 1499 | return 0; |
| 1499 | 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 | 1524 | * ext3_bg_num_gdb - number of blocks used by the group table in group |
| 1504 | 1525 | * @sb: superblock for filesystem |
| ... | ... | @@ -1510,9 +1531,15 @@ |
| 1510 | 1531 | */ |
| 1511 | 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)&& | |
| 1514 | - !ext3_group_sparse(group)) | |
| 1515 | - return 0; | |
| 1516 | - return EXT3_SB(sb)->s_gdb_count; | |
| 1534 | + unsigned long first_meta_bg = | |
| 1535 | + le32_to_cpu(EXT3_SB(sb)->s_es->s_first_meta_bg); | |
| 1536 | + unsigned long metagroup = group / EXT3_DESC_PER_BLOCK(sb); | |
| 1537 | + | |
| 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); | |
| 1541 | + | |
| 1542 | + return ext3_bg_num_gdb_meta(sb,group); | |
| 1543 | + | |
| 1517 | 1544 | } |