Re: [RFC 13/13] extents and 48bit ext3: super block (metadata) changes
Alexandre Ratchov <[email protected]>
| Newsgroups | gmane.comp.file-systems.ext2.devel |
|---|---|
| Message-ID | <[email protected]> |
On Thu, Jun 08, 2006 at 06:24:16PM -0700, Mingming Cao wrote:
> In-kernel and on-disk super block changes to support >32 bit blocks numbers.
>
hi,
there is a small fix for the 64bit meta-data patch that you posted.
reserved fields of the ext3_super_block that we use to expand 32bit fields
are already in use by e2fsprogs (fs creation time, and journal inodes
backup). This prevents ext3 filesystems to be mounted with the above patch
set).
in the attached patch the issue is fixed by making kernel side and e2fsprogs
side superblock structures compatibles. (I've also changed the
EXT3_FEATURE_RO_COMPAT_64 to EXT3_FEATURE_INCOMPAT_64)
cheers,
--
Alexandre
Index: linux-2.6.17-rc6/fs/ext3/balloc.c
===================================================================
--- linux-2.6.17-rc6.orig/fs/ext3/balloc.c 2006-06-13 21:21:30.000000000 +0200
+++ linux-2.6.17-rc6/fs/ext3/balloc.c 2006-06-13 21:21:33.000000000 +0200
@@ -88,12 +88,16 @@ read_block_bitmap(struct super_block *sb
desc = ext3_get_group_desc (sb, block_group, NULL);
if (!desc)
goto error_out;
- bh = sb_bread(sb, le32_to_cpu(desc->bg_block_bitmap));
+ bh = sb_bread(sb,
+ EXT3_BLOCK_BITMAP(desc,
+ ext3_group_first_block_no(sb, block_group)));
if (!bh)
ext3_error (sb, "read_block_bitmap",
"Cannot read block bitmap - "
- "block_group = %d, block_bitmap = %u",
- block_group, le32_to_cpu(desc->bg_block_bitmap));
+ "block_group = %d, block_bitmap = "E3FSBLK,
+ block_group,
+ EXT3_BLOCK_BITMAP(desc,
+ ext3_group_first_block_no(sb, block_group)));
error_out:
return bh;
}
@@ -328,7 +332,7 @@ void ext3_free_blocks_sb(handle_t *handl
es = sbi->s_es;
if (block < le32_to_cpu(es->s_first_data_block) ||
block + count < block ||
- block + count > le32_to_cpu(es->s_blocks_count)) {
+ block + count > EXT3_BLOCKS_COUNT(es)) {
ext3_error (sb, "ext3_free_blocks",
"Freeing blocks not in datazone - "
"block = "E3FSBLK", count = %lu", block, count);
@@ -356,11 +360,19 @@ do_more:
if (!desc)
goto error_return;
- if (in_range (le32_to_cpu(desc->bg_block_bitmap), block, count) ||
- in_range (le32_to_cpu(desc->bg_inode_bitmap), block, count) ||
- in_range (block, le32_to_cpu(desc->bg_inode_table),
+ if (in_range (EXT3_BLOCK_BITMAP(desc,
+ ext3_group_first_block_no(sb, block_group)),
+ block, count) ||
+ in_range (EXT3_INODE_BITMAP(desc,
+ ext3_group_first_block_no(sb, block_group)),
+ block, count) ||
+ in_range (block,
+ EXT3_INODE_TABLE(desc,
+ ext3_group_first_block_no(sb, block_group)),
sbi->s_itb_per_group) ||
- in_range (block + count - 1, le32_to_cpu(desc->bg_inode_table),
+ in_range (block + count - 1,
+ EXT3_INODE_TABLE(desc,
+ ext3_group_first_block_no(sb, block_group)),
sbi->s_itb_per_group))
ext3_error (sb, "ext3_free_blocks",
"Freeing blocks in system zones - "
@@ -1163,7 +1175,7 @@ static int ext3_has_free_blocks(struct e
ext3_fsblk_t free_blocks, root_blocks;
free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
- root_blocks = le32_to_cpu(sbi->s_es->s_r_blocks_count);
+ root_blocks = EXT3_R_BLOCKS_COUNT(sbi->s_es);
if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) &&
sbi->s_resuid != current->fsuid &&
(sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) {
@@ -1262,7 +1274,7 @@ ext3_fsblk_t ext3_new_blocks(handle_t *h
* First, test whether the goal block is free.
*/
if (goal < le32_to_cpu(es->s_first_data_block) ||
- goal >= le32_to_cpu(es->s_blocks_count))
+ goal >= EXT3_BLOCKS_COUNT(es))
goal = le32_to_cpu(es->s_first_data_block);
ext3_get_group_no_and_offset(sb, goal, &group_no, &grp_target_blk);
gdp = ext3_get_group_desc(sb, group_no, &gdp_bh);
@@ -1361,11 +1373,15 @@ allocated:
ret_block = grp_alloc_blk + ext3_group_first_block_no(sb, group_no);
- if (in_range(le32_to_cpu(gdp->bg_block_bitmap), ret_block, num) ||
- in_range(le32_to_cpu(gdp->bg_inode_bitmap), ret_block, num) ||
- in_range(ret_block, le32_to_cpu(gdp->bg_inode_table),
+ if (in_range(EXT3_BLOCK_BITMAP(gdp, ext3_group_first_block_no(sb, group_no)),
+ ret_block, num) ||
+ in_range(EXT3_BLOCK_BITMAP(gdp, ext3_group_first_block_no(sb, group_no)),
+ ret_block, num) ||
+ in_range(ret_block, EXT3_INODE_TABLE(gdp,
+ ext3_group_first_block_no(sb, group_no)),
EXT3_SB(sb)->s_itb_per_group) ||
- in_range(ret_block + num - 1, le32_to_cpu(gdp->bg_inode_table),
+ in_range(ret_block + num - 1, EXT3_INODE_TABLE(gdp,
+ ext3_group_first_block_no(sb, group_no)),
EXT3_SB(sb)->s_itb_per_group))
ext3_error(sb, "ext3_new_block",
"Allocating block in system zone - "
@@ -1404,11 +1420,11 @@ allocated:
jbd_unlock_bh_state(bitmap_bh);
#endif
- if (ret_block + num - 1 >= le32_to_cpu(es->s_blocks_count)) {
+ if (ret_block + num - 1 >= EXT3_BLOCKS_COUNT(es)) {
ext3_error(sb, "ext3_new_block",
- "block("E3FSBLK") >= blocks count(%d) - "
+ "block("E3FSBLK") >= blocks count("E3FSBLK") - "
"block_group = %lu, es == %p ", ret_block,
- le32_to_cpu(es->s_blocks_count), group_no, es);
+ EXT3_BLOCKS_COUNT(es), group_no, es);
goto out;
}
@@ -1501,7 +1517,7 @@ ext3_fsblk_t ext3_count_free_blocks(stru
brelse(bitmap_bh);
printk("ext3_count_free_blocks: stored = "E3FSBLK
", computed = "E3FSBLK", "E3FSBLK"\n",
- le32_to_cpu(es->s_free_blocks_count),
+ EXT3_FREE_BLOCKS_COUNT(es),
desc_count, bitmap_count);
return bitmap_count;
#else
Index: linux-2.6.17-rc6/fs/ext3/ialloc.c
===================================================================
--- linux-2.6.17-rc6.orig/fs/ext3/ialloc.c 2006-06-13 21:21:30.000000000 +0200
+++ linux-2.6.17-rc6/fs/ext3/ialloc.c 2006-06-13 21:21:33.000000000 +0200
@@ -60,12 +60,14 @@ read_inode_bitmap(struct super_block * s
if (!desc)
goto error_out;
- bh = sb_bread(sb, le32_to_cpu(desc->bg_inode_bitmap));
+ bh = sb_bread(sb, EXT3_INODE_BITMAP(desc,
+ ext3_group_first_block_no(sb, block_group)));
if (!bh)
ext3_error(sb, "read_inode_bitmap",
"Cannot read inode bitmap - "
- "block_group = %lu, inode_bitmap = %u",
- block_group, le32_to_cpu(desc->bg_inode_bitmap));
+ "block_group = %lu, inode_bitmap = %llu",
+ block_group, EXT3_INODE_BITMAP(desc,
+ ext3_group_first_block_no(sb, block_group)));
error_out:
return bh;
}
@@ -304,7 +306,7 @@ static int find_group_orlov(struct super
goto fallback;
}
- blocks_per_dir = le32_to_cpu(es->s_blocks_count) - freeb;
+ blocks_per_dir = EXT3_BLOCKS_COUNT(es) - freeb;
sector_div(blocks_per_dir, ndirs);
max_dirs = ndirs / ngroups + inodes_per_group / 16;
Index: linux-2.6.17-rc6/fs/ext3/inode.c
===================================================================
--- linux-2.6.17-rc6.orig/fs/ext3/inode.c 2006-06-13 21:21:30.000000000 +0200
+++ linux-2.6.17-rc6/fs/ext3/inode.c 2006-06-13 21:21:33.000000000 +0200
@@ -2433,8 +2433,9 @@ static ext3_fsblk_t ext3_get_inode_block
*/
offset = ((ino - 1) % EXT3_INODES_PER_GROUP(sb)) *
EXT3_INODE_SIZE(sb);
- block = le32_to_cpu(gdp[desc].bg_inode_table) +
- (offset >> EXT3_BLOCK_SIZE_BITS(sb));
+ block = EXT3_INODE_TABLE((gdp+desc),
+ ext3_group_first_block_no(sb, block_group)) +
+ (offset >> EXT3_BLOCK_SIZE_BITS(sb));
iloc->block_group = block_group;
iloc->offset = offset & (EXT3_BLOCK_SIZE(sb) - 1);
@@ -2501,7 +2502,9 @@ static int __ext3_get_inode_loc(struct i
goto make_io;
bitmap_bh = sb_getblk(inode->i_sb,
- le32_to_cpu(desc->bg_inode_bitmap));
+ EXT3_INODE_BITMAP(desc,
+ ext3_group_first_block_no(inode->i_sb,
+ block_group)));
if (!bitmap_bh)
goto make_io;
Index: linux-2.6.17-rc6/fs/ext3/resize.c
===================================================================
--- linux-2.6.17-rc6.orig/fs/ext3/resize.c 2006-06-13 21:21:30.000000000 +0200
+++ linux-2.6.17-rc6/fs/ext3/resize.c 2006-06-13 21:21:33.000000000 +0200
@@ -27,7 +27,7 @@ static int verify_group_input(struct sup
{
struct ext3_sb_info *sbi = EXT3_SB(sb);
struct ext3_super_block *es = sbi->s_es;
- ext3_fsblk_t start = le32_to_cpu(es->s_blocks_count);
+ ext3_fsblk_t start = EXT3_BLOCKS_COUNT(es);
ext3_fsblk_t end = start + input->blocks_count;
unsigned group = input->group;
ext3_fsblk_t itend = input->inode_table + sbi->s_itb_per_group;
@@ -817,9 +817,12 @@ int ext3_group_add(struct super_block *s
/* Update group descriptor block for new group */
gdp = (struct ext3_group_desc *)primary->b_data + gdb_off;
- gdp->bg_block_bitmap = cpu_to_le32(input->block_bitmap);
- gdp->bg_inode_bitmap = cpu_to_le32(input->inode_bitmap);
- gdp->bg_inode_table = cpu_to_le32(input->inode_table);
+ EXT3_BLOCK_BITMAP_SET(gdp, ext3_group_first_block_no(sb, gdb_num),
+ input->block_bitmap); /* LV FIXME */
+ EXT3_INODE_BITMAP_SET(gdp, ext3_group_first_block_no(sb, gdb_num),
+ input->inode_bitmap); /* LV FIXME */
+ EXT3_INODE_TABLE_SET(gdp, ext3_group_first_block_no(sb, gdb_num),
+ input->inode_table); /* LV FIXME */
gdp->bg_free_blocks_count = cpu_to_le16(input->free_blocks_count);
gdp->bg_free_inodes_count = cpu_to_le16(EXT3_INODES_PER_GROUP(sb));
@@ -833,7 +836,7 @@ int ext3_group_add(struct super_block *s
* blocks/inodes before the group is live won't actually let us
* allocate the new space yet.
*/
- es->s_blocks_count = cpu_to_le32(le32_to_cpu(es->s_blocks_count) +
+ EXT3_BLOCKS_COUNT_SET(es, EXT3_BLOCKS_COUNT(es) +
input->blocks_count);
es->s_inodes_count = cpu_to_le32(le32_to_cpu(es->s_inodes_count) +
EXT3_INODES_PER_GROUP(sb));
@@ -869,7 +872,7 @@ int ext3_group_add(struct super_block *s
/* Update the reserved block counts only once the new group is
* active. */
- es->s_r_blocks_count = cpu_to_le32(le32_to_cpu(es->s_r_blocks_count) +
+ EXT3_R_BLOCKS_COUNT_SET(es, EXT3_R_BLOCKS_COUNT(es) +
input->reserved_blocks);
/* Update the free space counts */
@@ -920,7 +923,7 @@ int ext3_group_extend(struct super_block
/* We don't need to worry about locking wrt other resizers just
* yet: we're going to revalidate es->s_blocks_count after
* taking lock_super() below. */
- o_blocks_count = le32_to_cpu(es->s_blocks_count);
+ o_blocks_count = EXT3_BLOCKS_COUNT(es);
o_groups_count = EXT3_SB(sb)->s_groups_count;
if (test_opt(sb, DEBUG))
@@ -986,7 +989,7 @@ int ext3_group_extend(struct super_block
}
lock_super(sb);
- if (o_blocks_count != le32_to_cpu(es->s_blocks_count)) {
+ if (o_blocks_count != EXT3_BLOCKS_COUNT(es)) {
ext3_warning(sb, __FUNCTION__,
"multiple resizers run on filesystem!");
unlock_super(sb);
@@ -1002,7 +1005,7 @@ int ext3_group_extend(struct super_block
ext3_journal_stop(handle);
goto exit_put;
}
- es->s_blocks_count = cpu_to_le32(o_blocks_count + add);
+ EXT3_BLOCKS_COUNT_SET(es, o_blocks_count + add);
ext3_journal_dirty_metadata(handle, EXT3_SB(sb)->s_sbh);
sb->s_dirt = 1;
unlock_super(sb);
@@ -1014,8 +1017,8 @@ int ext3_group_extend(struct super_block
if ((err = ext3_journal_stop(handle)))
goto exit_put;
if (test_opt(sb, DEBUG))
- printk(KERN_DEBUG "EXT3-fs: extended group to %u blocks\n",
- le32_to_cpu(es->s_blocks_count));
+ printk(KERN_DEBUG "EXT3-fs: extended group to %llu blocks\n",
+ EXT3_BLOCKS_COUNT(es));
update_backups(sb, EXT3_SB(sb)->s_sbh->b_blocknr, (char *)es,
sizeof(struct ext3_super_block));
exit_put:
Index: linux-2.6.17-rc6/fs/ext3/super.c
===================================================================
--- linux-2.6.17-rc6.orig/fs/ext3/super.c 2006-06-13 21:21:30.000000000 +0200
+++ linux-2.6.17-rc6/fs/ext3/super.c 2006-06-13 21:21:33.000000000 +0200
@@ -1146,44 +1146,48 @@ static int ext3_check_descriptors (struc
if ((i % EXT3_DESC_PER_BLOCK(sb)) == 0)
gdp = (struct ext3_group_desc *)
sbi->s_group_desc[desc_block++]->b_data;
- if (le32_to_cpu(gdp->bg_block_bitmap) < block ||
- le32_to_cpu(gdp->bg_block_bitmap) >=
+ if (EXT3_BLOCK_BITMAP(gdp, ext3_group_first_block_no(sb, i)) <
+ block ||
+ EXT3_BLOCK_BITMAP(gdp, ext3_group_first_block_no(sb, i)) >=
block + EXT3_BLOCKS_PER_GROUP(sb))
{
ext3_error (sb, "ext3_check_descriptors",
"Block bitmap for group %d"
" not in group (block %lu)!",
i, (unsigned long)
- le32_to_cpu(gdp->bg_block_bitmap));
+ EXT3_BLOCK_BITMAP(gdp, ext3_group_first_block_no(sb, i)));
return 0;
}
- if (le32_to_cpu(gdp->bg_inode_bitmap) < block ||
- le32_to_cpu(gdp->bg_inode_bitmap) >=
+ if (EXT3_INODE_BITMAP(gdp, ext3_group_first_block_no(sb, i)) <
+ block ||
+ EXT3_INODE_BITMAP(gdp, ext3_group_first_block_no(sb, i)) >=
block + EXT3_BLOCKS_PER_GROUP(sb))
{
ext3_error (sb, "ext3_check_descriptors",
"Inode bitmap for group %d"
" not in group (block %lu)!",
i, (unsigned long)
- le32_to_cpu(gdp->bg_inode_bitmap));
+ EXT3_INODE_BITMAP(gdp, ext3_group_first_block_no(sb, i)));
return 0;
}
- if (le32_to_cpu(gdp->bg_inode_table) < block ||
- le32_to_cpu(gdp->bg_inode_table) + sbi->s_itb_per_group >=
- block + EXT3_BLOCKS_PER_GROUP(sb))
+ if (EXT3_INODE_TABLE(gdp, ext3_group_first_block_no(sb, i)) <
+ block ||
+ EXT3_INODE_TABLE(gdp, ext3_group_first_block_no(sb, i)) +
+ sbi->s_itb_per_group >=
+ block + EXT3_BLOCKS_PER_GROUP(sb))
{
ext3_error (sb, "ext3_check_descriptors",
"Inode table for group %d"
" not in group (block %lu)!",
i, (unsigned long)
- le32_to_cpu(gdp->bg_inode_table));
+ EXT3_INODE_TABLE(gdp, ext3_group_first_block_no(sb, i)));
return 0;
}
block += EXT3_BLOCKS_PER_GROUP(sb);
gdp++;
}
- sbi->s_es->s_free_blocks_count=cpu_to_le32(ext3_count_free_blocks(sb));
+ EXT3_FREE_BLOCKS_COUNT_SET(sbi->s_es, ext3_count_free_blocks(sb));
sbi->s_es->s_free_inodes_count=cpu_to_le32(ext3_count_free_inodes(sb));
return 1;
}
@@ -1360,6 +1364,7 @@ static int ext3_fill_super (struct super
int i;
int needs_recovery;
__le32 features;
+ __u64 blocks_count;
sbi = kmalloc(sizeof(*sbi), GFP_KERNEL);
if (!sbi)
@@ -1572,10 +1577,11 @@ static int ext3_fill_super (struct super
if (EXT3_BLOCKS_PER_GROUP(sb) == 0)
goto cantfind_ext3;
- sbi->s_groups_count = (le32_to_cpu(es->s_blocks_count) -
- le32_to_cpu(es->s_first_data_block) +
- EXT3_BLOCKS_PER_GROUP(sb) - 1) /
- EXT3_BLOCKS_PER_GROUP(sb);
+ blocks_count = (EXT3_BLOCKS_COUNT(es) -
+ le32_to_cpu(es->s_first_data_block) +
+ EXT3_BLOCKS_PER_GROUP(sb) - 1);
+ do_div(blocks_count, EXT3_BLOCKS_PER_GROUP(sb));
+ sbi->s_groups_count = blocks_count;
db_count = (sbi->s_groups_count + EXT3_DESC_PER_BLOCK(sb) - 1) /
EXT3_DESC_PER_BLOCK(sb);
sbi->s_group_desc = kmalloc(db_count * sizeof (struct buffer_head *),
@@ -1585,7 +1591,7 @@ static int ext3_fill_super (struct super
goto failed_mount;
}
- if (le32_to_cpu(es->s_blocks_count) >
+ if (EXT3_BLOCKS_COUNT(es) >
(sector_t)(~0ULL) >> (sb->s_blocksize_bits - 9)) {
printk(KERN_ERR "EXT3-fs: filesystem on %s"
" too large to mount safely\n", sb->s_id);
@@ -1900,7 +1906,7 @@ static journal_t *ext3_get_dev_journal(s
goto out_bdev;
}
- len = le32_to_cpu(es->s_blocks_count);
+ len = EXT3_BLOCKS_COUNT(es);
start = sb_block + 1;
brelse(bh); /* we're done with the superblock */
@@ -2070,7 +2076,7 @@ static void ext3_commit_super (struct su
if (!sbh)
return;
es->s_wtime = cpu_to_le32(get_seconds());
- es->s_free_blocks_count = cpu_to_le32(ext3_count_free_blocks(sb));
+ EXT3_FREE_BLOCKS_COUNT_SET(es, ext3_count_free_blocks(sb));
es->s_free_inodes_count = cpu_to_le32(ext3_count_free_inodes(sb));
BUFFER_TRACE(sbh, "marking dirty");
mark_buffer_dirty(sbh);
@@ -2263,7 +2269,7 @@ static int ext3_remount (struct super_bl
ext3_init_journal_params(sb, sbi->s_journal);
if ((*flags & MS_RDONLY) != (sb->s_flags & MS_RDONLY) ||
- n_blocks_count > le32_to_cpu(es->s_blocks_count)) {
+ n_blocks_count > EXT3_BLOCKS_COUNT(es)) {
if (sbi->s_mount_opt & EXT3_MOUNT_ABORT) {
err = -EROFS;
goto restore_opts;
@@ -2383,10 +2389,10 @@ static int ext3_statfs (struct super_blo
buf->f_type = EXT3_SUPER_MAGIC;
buf->f_bsize = sb->s_blocksize;
- buf->f_blocks = le32_to_cpu(es->s_blocks_count) - overhead;
+ buf->f_blocks = EXT3_BLOCKS_COUNT(es) - overhead;
buf->f_bfree = percpu_counter_sum(&sbi->s_freeblocks_counter);
- buf->f_bavail = buf->f_bfree - le32_to_cpu(es->s_r_blocks_count);
- if (buf->f_bfree < le32_to_cpu(es->s_r_blocks_count))
+ buf->f_bavail = buf->f_bfree - EXT3_R_BLOCKS_COUNT(es);
+ if (buf->f_bfree < EXT3_R_BLOCKS_COUNT(es))
buf->f_bavail = 0;
buf->f_files = le32_to_cpu(es->s_inodes_count);
buf->f_ffree = percpu_counter_sum(&sbi->s_freeinodes_counter);
Index: linux-2.6.17-rc6/include/linux/ext3_fs.h
===================================================================
--- linux-2.6.17-rc6.orig/include/linux/ext3_fs.h 2006-06-13 21:21:30.000000000 +0200
+++ linux-2.6.17-rc6/include/linux/ext3_fs.h 2006-06-13 21:23:25.000000000 +0200
@@ -140,6 +140,54 @@ struct ext3_group_desc
__le32 bg_reserved[3];
};
+static inline u32 EXT3_RELATIVE_ENCODE(ext3_fsblk_t group_base,
+ ext3_fsblk_t fs_block)
+{
+ s32 gdp_block;
+
+ if (fs_block < (1ULL<<32) && group_base < (1ULL<<32))
+ return fs_block;
+
+ gdp_block = (fs_block - group_base);
+ BUG_ON ((group_base + gdp_block) != fs_block);
+
+ return gdp_block;
+}
+
+static inline ext3_fsblk_t EXT3_RELATIVE_DECODE(ext3_fsblk_t group_base,
+ u32 gdp_block)
+{
+ if (group_base >= (1ULL<<32))
+ return group_base + (s32) gdp_block;
+
+ if ((s32) gdp_block >= 0 && gdp_block < group_base &&
+ group_base + gdp_block >= (1ULL<<32))
+ return group_base + gdp_block;
+
+ return gdp_block;
+}
+
+#define EXT3_BLOCK_BITMAP(bg, group_base) \
+ EXT3_RELATIVE_DECODE(group_base, le32_to_cpu((bg)->bg_block_bitmap))
+#define EXT3_INODE_BITMAP(bg, group_base) \
+ EXT3_RELATIVE_DECODE(group_base, le32_to_cpu((bg)->bg_inode_bitmap))
+#define EXT3_INODE_TABLE(bg, group_base) \
+ EXT3_RELATIVE_DECODE(group_base, le32_to_cpu((bg)->bg_inode_table))
+
+#define EXT3_BLOCK_BITMAP_SET(bg, group_base, value) \
+ do {(bg)->bg_block_bitmap = EXT3_RELATIVE_ENCODE(group_base, value);} while(0)
+#define EXT3_INODE_BITMAP_SET(bg, group_base, value) \
+ do {(bg)->bg_inode_bitmap = EXT3_RELATIVE_ENCODE(group_base, value);} while(0)
+#define EXT3_INODE_TABLE_SET(bg, group_base, value) \
+ do {(bg)->bg_inode_table = EXT3_RELATIVE_ENCODE(group_base, value);} while(0)
+
+#define EXT3_IS_USED_BLOCK_BITMAP(bg) \
+ ((bg)->bg_block_bitmap != 0)
+#define EXT3_IS_USED_INODE_BITMAP(bg) \
+ ((bg)->bg_inode_bitmap != 0)
+#define EXT3_IS_USED_INODE_TABLE(bg) \
+ ((bg)->bg_inode_table != 0)
+
/*
* Macro-instructions used to manage group descriptors
*/
@@ -487,9 +535,40 @@ struct ext3_super_block {
__u16 s_reserved_word_pad;
__le32 s_default_mount_opts;
__le32 s_first_meta_bg; /* First metablock block group */
- __u32 s_reserved[190]; /* Padding to the end of the block */
+ __le32 s_mkfs_time; /* When the filesystem was created */
+ __le32 s_jnl_blocks[17]; /* Backup of the journal inode */
+ /* 64bit support valid if EXT3_FEATURE_INCOMPAT_64BIT */
+ __le32 s_blocks_count_hi; /* Blocks count */
+ __le32 s_r_blocks_count_hi; /* Reserved blocks count */
+ __le32 s_free_blocks_count_hi; /* Free blocks count */
+ __u32 s_reserved[169]; /* Padding to the end of the block */
};
+
+#define EXT3_BLOCKS_COUNT(s) \
+ (ext3_fsblk_t)(((__u64)le32_to_cpu((s)->s_blocks_count_hi) << 32) | \
+ (__u64)le32_to_cpu((s)->s_blocks_count))
+#define EXT3_BLOCKS_COUNT_SET(s,v) do { \
+ (s)->s_blocks_count = cpu_to_le32((v)); \
+ (s)->s_blocks_count_hi = cpu_to_le32(((__u64)(v)) >> 32); \
+} while (0)
+
+#define EXT3_R_BLOCKS_COUNT(s) \
+ (ext3_fsblk_t)(((__u64)le32_to_cpu((s)->s_r_blocks_count_hi) << 32) | \
+ (__u64)le32_to_cpu((s)->s_r_blocks_count))
+#define EXT3_R_BLOCKS_COUNT_SET(s,v) do { \
+ (s)->s_r_blocks_count = cpu_to_le32((v)); \
+ (s)->s_r_blocks_count_hi = cpu_to_le32(((__u64)(v)) >> 32); \
+} while (0)
+
+#define EXT3_FREE_BLOCKS_COUNT(s) \
+ (ext3_fsblk_t)(((__u64)le32_to_cpu((s)->s_free_blocks_count_hi) << 32) | \
+ (__u64)le32_to_cpu((s)->s_free_blocks_count))
+#define EXT3_FREE_BLOCKS_COUNT_SET(s,v) do { \
+ (s)->s_free_blocks_count = cpu_to_le32((v)); \
+ (s)->s_free_blocks_count_hi = cpu_to_le32(((__u64)(v)) >> 32); \
+} while (0)
+
#ifdef __KERNEL__
static inline struct ext3_sb_info * EXT3_SB(struct super_block *sb)
{
@@ -568,12 +647,14 @@ static inline struct ext3_inode_info *EX
#define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV 0x0008 /* Journal device */
#define EXT3_FEATURE_INCOMPAT_META_BG 0x0010
#define EXT3_FEATURE_INCOMPAT_EXTENTS 0x0040 /* extents support */
+#define EXT3_FEATURE_INCOMPAT_64BIT 0x0080
#define EXT3_FEATURE_COMPAT_SUPP EXT2_FEATURE_COMPAT_EXT_ATTR
#define EXT3_FEATURE_INCOMPAT_SUPP (EXT3_FEATURE_INCOMPAT_FILETYPE| \
EXT3_FEATURE_INCOMPAT_RECOVER| \
EXT3_FEATURE_INCOMPAT_META_BG| \
- EXT3_FEATURE_INCOMPAT_EXTENTS)
+ EXT3_FEATURE_INCOMPAT_EXTENTS| \
+ EXT3_FEATURE_INCOMPAT_64BIT)
#define EXT3_FEATURE_RO_COMPAT_SUPP (EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER| \
EXT3_FEATURE_RO_COMPAT_LARGE_FILE| \
EXT3_FEATURE_RO_COMPAT_BTREE_DIR)