static void ext4_write_super_lockfs(struct super_block *sb);
-ext4_fsblk_t ext4_block_bitmap(struct ext4_group_desc *bg)
+ext4_fsblk_t ext4_block_bitmap(struct super_block *sb,
+ struct ext4_group_desc *bg)
{
return le32_to_cpu(bg->bg_block_bitmap) |
- ((ext4_fsblk_t)le16_to_cpu(bg->bg_block_bitmap_hi) << 32);
+ (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT ?
+ (ext4_fsblk_t)le32_to_cpu(bg->bg_block_bitmap_hi) << 32 : 0);
}
-ext4_fsblk_t ext4_inode_bitmap(struct ext4_group_desc *bg)
+ext4_fsblk_t ext4_inode_bitmap(struct super_block *sb,
+ struct ext4_group_desc *bg)
{
return le32_to_cpu(bg->bg_inode_bitmap) |
- ((ext4_fsblk_t)le16_to_cpu(bg->bg_inode_bitmap_hi) << 32);
+ (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT ?
+ (ext4_fsblk_t)le32_to_cpu(bg->bg_inode_bitmap_hi) << 32 : 0);
}
-ext4_fsblk_t ext4_inode_table(struct ext4_group_desc *bg)
+ext4_fsblk_t ext4_inode_table(struct super_block *sb,
+ struct ext4_group_desc *bg)
{
return le32_to_cpu(bg->bg_inode_table) |
- ((ext4_fsblk_t)le16_to_cpu(bg->bg_inode_table_hi) << 32);
+ (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT ?
+ (ext4_fsblk_t)le32_to_cpu(bg->bg_inode_table_hi) << 32 : 0);
}
-void ext4_block_bitmap_set(struct ext4_group_desc *bg, ext4_fsblk_t blk)
+void ext4_block_bitmap_set(struct super_block *sb,
+ struct ext4_group_desc *bg, ext4_fsblk_t blk)
{
bg->bg_block_bitmap = cpu_to_le32((u32)blk);
- bg->bg_block_bitmap_hi = cpu_to_le16(blk >> 32);
+ if (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT)
+ bg->bg_block_bitmap_hi = cpu_to_le32(blk >> 32);
}
-void ext4_inode_bitmap_set(struct ext4_group_desc *bg, ext4_fsblk_t blk)
+void ext4_inode_bitmap_set(struct super_block *sb,
+ struct ext4_group_desc *bg, ext4_fsblk_t blk)
{
bg->bg_inode_bitmap = cpu_to_le32((u32)blk);
- bg->bg_inode_bitmap_hi = cpu_to_le16(blk >> 32);
+ if (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT)
+ bg->bg_inode_bitmap_hi = cpu_to_le32(blk >> 32);
}
-void ext4_inode_table_set(struct ext4_group_desc *bg, ext4_fsblk_t blk)
+void ext4_inode_table_set(struct super_block *sb,
+ struct ext4_group_desc *bg, ext4_fsblk_t blk)
{
bg->bg_inode_table = cpu_to_le32((u32)blk);
- bg->bg_inode_table_hi = cpu_to_le16(blk >> 32);
+ if (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT)
+ bg->bg_inode_table_hi = cpu_to_le32(blk >> 32);
}
/*
"running e2fsck is recommended\n");
#if 0
/* @@@ We _will_ want to clear the valid bit if we find
- inconsistencies, to force a fsck at reboot. But for
- a plain journaled filesystem we can keep it set as
- valid forever! :) */
+ * inconsistencies, to force a fsck at reboot. But for
+ * a plain journaled filesystem we can keep it set as
+ * valid forever! :)
+ */
es->s_state = cpu_to_le16(le16_to_cpu(es->s_state) & ~EXT4_VALID_FS);
#endif
if (!(__s16) le16_to_cpu(es->s_max_mnt_count))
if ((i % EXT4_DESC_PER_BLOCK(sb)) == 0)
gdp = (struct ext4_group_desc *)
sbi->s_group_desc[desc_block++]->b_data;
- block_bitmap = ext4_block_bitmap(gdp);
+ block_bitmap = ext4_block_bitmap(sb, gdp);
if (block_bitmap < first_block || block_bitmap > last_block)
{
ext4_error (sb, "ext4_check_descriptors",
i, block_bitmap);
return 0;
}
- inode_bitmap = ext4_inode_bitmap(gdp);
+ inode_bitmap = ext4_inode_bitmap(sb, gdp);
if (inode_bitmap < first_block || inode_bitmap > last_block)
{
ext4_error (sb, "ext4_check_descriptors",
i, inode_bitmap);
return 0;
}
- inode_table = ext4_inode_table(gdp);
+ inode_table = ext4_inode_table(sb, gdp);
if (inode_table < first_block ||
inode_table + sbi->s_itb_per_group > last_block)
{
return 0;
}
first_block += EXT4_BLOCKS_PER_GROUP(sb);
- gdp++;
+ gdp = (struct ext4_group_desc *)
+ ((__u8 *)gdp + EXT4_DESC_SIZE(sb));
}
ext4_free_blocks_count_set(sbi->s_es, ext4_count_free_blocks(sb));
}
static ext4_fsblk_t descriptor_loc(struct super_block *sb,
- ext4_fsblk_t logic_sb_block,
- int nr)
+ ext4_fsblk_t logical_sb_block, int nr)
{
struct ext4_sb_info *sbi = EXT4_SB(sb);
unsigned long bg, first_meta_bg;
if (!EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_META_BG) ||
nr < first_meta_bg)
- return (logic_sb_block + nr + 1);
+ return logical_sb_block + nr + 1;
bg = sbi->s_desc_per_block * nr;
if (ext4_bg_has_super(sb, bg))
has_super = 1;
struct ext4_sb_info *sbi;
ext4_fsblk_t block;
ext4_fsblk_t sb_block = get_sb_block(&data);
- ext4_fsblk_t logic_sb_block;
+ ext4_fsblk_t logical_sb_block;
unsigned long offset = 0;
unsigned int journal_inum = 0;
unsigned long journal_devnum = 0;
* block sizes. We need to calculate the offset from buffer start.
*/
if (blocksize != EXT4_MIN_BLOCK_SIZE) {
- logic_sb_block = sb_block * EXT4_MIN_BLOCK_SIZE;
- offset = sector_div(logic_sb_block, blocksize);
+ logical_sb_block = sb_block * EXT4_MIN_BLOCK_SIZE;
+ offset = do_div(logical_sb_block, blocksize);
} else {
- logic_sb_block = sb_block;
+ logical_sb_block = sb_block;
}
- if (!(bh = sb_bread(sb, logic_sb_block))) {
+ if (!(bh = sb_bread(sb, logical_sb_block))) {
printk (KERN_ERR "EXT4-fs: unable to read superblock\n");
goto out_fail;
}
set_opt(sbi->s_mount_opt, ERRORS_PANIC);
else if (le16_to_cpu(sbi->s_es->s_errors) == EXT4_ERRORS_RO)
set_opt(sbi->s_mount_opt, ERRORS_RO);
+ else
+ set_opt(sbi->s_mount_opt, ERRORS_CONT);
sbi->s_resuid = le16_to_cpu(es->s_def_resuid);
sbi->s_resgid = le16_to_cpu(es->s_def_resgid);
brelse (bh);
sb_set_blocksize(sb, blocksize);
- logic_sb_block = sb_block * EXT4_MIN_BLOCK_SIZE;
- offset = sector_div(logic_sb_block, blocksize);
- bh = sb_bread(sb, logic_sb_block);
+ logical_sb_block = sb_block * EXT4_MIN_BLOCK_SIZE;
+ offset = do_div(logical_sb_block, blocksize);
+ bh = sb_bread(sb, logical_sb_block);
if (!bh) {
printk(KERN_ERR
"EXT4-fs: Can't read superblock on 2nd try.\n");
sbi->s_frag_size, blocksize);
goto failed_mount;
}
- sbi->s_frags_per_block = 1;
+ sbi->s_desc_size = le16_to_cpu(es->s_desc_size);
+ if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_64BIT)) {
+ if (sbi->s_desc_size < EXT4_MIN_DESC_SIZE_64BIT ||
+ sbi->s_desc_size > EXT4_MAX_DESC_SIZE ||
+ sbi->s_desc_size & (sbi->s_desc_size - 1)) {
+ printk(KERN_ERR
+ "EXT4-fs: unsupported descriptor size %lu\n",
+ sbi->s_desc_size);
+ goto failed_mount;
+ }
+ } else
+ sbi->s_desc_size = EXT4_MIN_DESC_SIZE;
sbi->s_blocks_per_group = le32_to_cpu(es->s_blocks_per_group);
sbi->s_frags_per_group = le32_to_cpu(es->s_frags_per_group);
sbi->s_inodes_per_group = le32_to_cpu(es->s_inodes_per_group);
goto cantfind_ext4;
sbi->s_itb_per_group = sbi->s_inodes_per_group /
sbi->s_inodes_per_block;
- sbi->s_desc_per_block = blocksize / sizeof(struct ext4_group_desc);
+ sbi->s_desc_per_block = blocksize / EXT4_DESC_SIZE(sb);
sbi->s_sbh = bh;
sbi->s_mount_state = le16_to_cpu(es->s_state);
sbi->s_addr_per_block_bits = log2(EXT4_ADDR_PER_BLOCK(sb));
bgl_lock_init(&sbi->s_blockgroup_lock);
for (i = 0; i < db_count; i++) {
- block = descriptor_loc(sb, logic_sb_block, i);
+ block = descriptor_loc(sb, logical_sb_block, i);
sbi->s_group_desc[i] = sb_bread(sb, block);
if (!sbi->s_group_desc[i]) {
printk (KERN_ERR "EXT4-fs: "
switch (test_opt(sb, DATA_FLAGS)) {
case 0:
/* No mode set, assume a default based on the journal
- capabilities: ORDERED_DATA if the journal can
- cope, else JOURNAL_DATA */
+ * capabilities: ORDERED_DATA if the journal can
+ * cope, else JOURNAL_DATA
+ */
if (jbd2_journal_check_available_features
(sbi->s_journal, 0, 0, JBD2_FEATURE_INCOMPAT_REVOKE))
set_opt(sbi->s_mount_opt, ORDERED_DATA);
err = init_inodecache();
if (err)
goto out1;
- err = register_filesystem(&ext4dev_fs_type);
+ err = register_filesystem(&ext4dev_fs_type);
if (err)
goto out;
return 0;