Skip to content

Commit

Permalink
ext4: fix block bitmap initialization under sparse_super2
Browse files Browse the repository at this point in the history
The ext4_bg_has_super() function doesn't know about the new rules for
where backup superblocks go on a sparse_super2 filesystem.  Therefore,
block bitmap initialization doesn't know that it shouldn't reserve
space for backups in groups that are never going to contain backups.
The result of this is e2fsck complaining about the block bitmap being
incorrect (fortunately not in a way that results in cross-linked
files), so fix the whole thing.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
  • Loading branch information
Darrick J. Wong authored and Theodore Ts'o committed May 12, 2014
1 parent bd63f6b commit 1beeef1
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 15 deletions.
33 changes: 19 additions & 14 deletions fs/ext4/balloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -708,16 +708,6 @@ static inline int test_root(ext4_group_t a, int b)
}
}

static int ext4_group_sparse(ext4_group_t group)
{
if (group <= 1)
return 1;
if (!(group & 1))
return 0;
return (test_root(group, 7) || test_root(group, 5) ||
test_root(group, 3));
}

/**
* ext4_bg_has_super - number of blocks used by the superblock in group
* @sb: superblock for filesystem
Expand All @@ -728,11 +718,26 @@ static int ext4_group_sparse(ext4_group_t group)
*/
int ext4_bg_has_super(struct super_block *sb, ext4_group_t group)
{
if (EXT4_HAS_RO_COMPAT_FEATURE(sb,
EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER) &&
!ext4_group_sparse(group))
struct ext4_super_block *es = EXT4_SB(sb)->s_es;

if (group == 0)
return 1;
if (EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_SPARSE_SUPER2)) {
if (group == le32_to_cpu(es->s_backup_bgs[0]) ||
group == le32_to_cpu(es->s_backup_bgs[1]))
return 1;
return 0;
}
if ((group <= 1) || !EXT4_HAS_RO_COMPAT_FEATURE(sb,
EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER))
return 1;
if (!(group & 1))
return 0;
return 1;
if (test_root(group, 3) || (test_root(group, 5)) ||
test_root(group, 7))
return 1;

return 0;
}

static unsigned long ext4_bg_num_gdb_meta(struct super_block *sb,
Expand Down
4 changes: 3 additions & 1 deletion fs/ext4/ext4.h
Original file line number Diff line number Diff line change
Expand Up @@ -1160,7 +1160,8 @@ struct ext4_super_block {
__le32 s_usr_quota_inum; /* inode for tracking user quota */
__le32 s_grp_quota_inum; /* inode for tracking group quota */
__le32 s_overhead_clusters; /* overhead blocks/clusters in fs */
__le32 s_reserved[108]; /* Padding to the end of the block */
__le32 s_backup_bgs[2]; /* groups with sparse_super2 SBs */
__le32 s_reserved[106]; /* Padding to the end of the block */
__le32 s_checksum; /* crc32c(superblock) */
};

Expand Down Expand Up @@ -1506,6 +1507,7 @@ static inline void ext4_clear_state_flags(struct ext4_inode_info *ei)
#define EXT4_FEATURE_COMPAT_EXT_ATTR 0x0008
#define EXT4_FEATURE_COMPAT_RESIZE_INODE 0x0010
#define EXT4_FEATURE_COMPAT_DIR_INDEX 0x0020
#define EXT4_FEATURE_COMPAT_SPARSE_SUPER2 0x0200

#define EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER 0x0001
#define EXT4_FEATURE_RO_COMPAT_LARGE_FILE 0x0002
Expand Down

0 comments on commit 1beeef1

Please sign in to comment.