[rfc, patch 2/3] larger block group descriptors
Alexandre Ratchov <[email protected]>
| Newsgroups | gmane.comp.file-systems.ext2.devel |
|---|---|
| Message-ID | <[email protected]> |
make e2fsprogs-1.39 use variable length block group descriptors. mke2fs,
debugfs, dumpe2fs and fsck should work.
Index: e2fsprogs-1.39/lib/ext2fs/swapfs.c
===================================================================
--- e2fsprogs-1.39.orig/lib/ext2fs/swapfs.c 2006-06-07 13:49:36.000000000 +0200
+++ e2fsprogs-1.39/lib/ext2fs/swapfs.c 2006-06-07 13:50:04.000000000 +0200
@@ -60,6 +60,7 @@ void ext2fs_swap_super(struct ext2_super
sb->s_journal_inum = ext2fs_swab32(sb->s_journal_inum);
sb->s_journal_dev = ext2fs_swab32(sb->s_journal_dev);
sb->s_last_orphan = ext2fs_swab32(sb->s_last_orphan);
+ sb->s_desc_size = ext2fs_swab16(sb->s_desc_size);
sb->s_default_mount_opts = ext2fs_swab32(sb->s_default_mount_opts);
sb->s_first_meta_bg = ext2fs_swab32(sb->s_first_meta_bg);
sb->s_mkfs_time = ext2fs_swab32(sb->s_mkfs_time);
Index: e2fsprogs-1.39/lib/ext2fs/ext2fs.h
===================================================================
--- e2fsprogs-1.39.orig/lib/ext2fs/ext2fs.h 2006-06-07 13:49:36.000000000 +0200
+++ e2fsprogs-1.39/lib/ext2fs/ext2fs.h 2006-06-07 13:50:04.000000000 +0200
@@ -210,6 +210,7 @@ struct struct_ext2_filsys {
char * device_name;
struct ext2_super_block * super;
unsigned int blocksize;
+ unsigned int desc_size;
int fragsize;
dgrp_t group_desc_count;
unsigned long desc_blocks;
@@ -453,12 +454,14 @@ typedef struct ext2_icount *ext2_icount_
EXT2_FEATURE_INCOMPAT_COMPRESSION|\
EXT3_FEATURE_INCOMPAT_JOURNAL_DEV|\
EXT2_FEATURE_INCOMPAT_META_BG|\
- EXT3_FEATURE_INCOMPAT_RECOVER)
+ EXT3_FEATURE_INCOMPAT_RECOVER|\
+ EXT3_FEATURE_INCOMPAT_DESC_SIZE)
#else
#define EXT2_LIB_FEATURE_INCOMPAT_SUPP (EXT2_FEATURE_INCOMPAT_FILETYPE|\
EXT3_FEATURE_INCOMPAT_JOURNAL_DEV|\
EXT2_FEATURE_INCOMPAT_META_BG|\
- EXT3_FEATURE_INCOMPAT_RECOVER)
+ EXT3_FEATURE_INCOMPAT_RECOVER|\
+ EXT3_FEATURE_INCOMPAT_DESC_SIZE)
#endif
#define EXT2_LIB_FEATURE_RO_COMPAT_SUPP (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER|\
EXT2_FEATURE_RO_COMPAT_LARGE_FILE)
Index: e2fsprogs-1.39/lib/ext2fs/openfs.c
===================================================================
--- e2fsprogs-1.39.orig/lib/ext2fs/openfs.c 2006-06-07 13:49:36.000000000 +0200
+++ e2fsprogs-1.39/lib/ext2fs/openfs.c 2006-06-07 13:50:04.000000000 +0200
@@ -39,7 +39,7 @@ blk_t ext2fs_descriptor_block_loc(ext2_f
(i < fs->super->s_first_meta_bg))
return (group_block + i + 1);
- bg = (fs->blocksize / sizeof (struct ext2_group_desc)) * i;
+ bg = (fs->blocksize / fs->desc_size) * i;
if (ext2fs_bg_has_super(fs, bg))
has_super = 1;
ret_blk = (fs->super->s_first_data_block + has_super +
@@ -90,6 +90,7 @@ errcode_t ext2fs_open2(const char *name,
blk_t group_block, blk;
char *dest, *cp;
struct ext2_group_desc *gdp;
+ char shadow_block[EXT2_MAX_BLOCK_SIZE];
EXT2_CHECK_MAGIC(manager, EXT2_ET_MAGIC_IO_MANAGER);
@@ -232,6 +233,13 @@ errcode_t ext2fs_open2(const char *name,
goto cleanup;
}
}
+
+ if (fs->super->s_feature_incompat &
+ EXT3_FEATURE_INCOMPAT_DESC_SIZE) {
+ fs->desc_size = EXT2_DESC_SIZE(fs->super);
+ } else {
+ fs->desc_size = EXT2_MIN_DESC_SIZE;
+ }
/*
* Set the blocksize to the filesystem's blocksize.
*/
@@ -270,21 +278,22 @@ errcode_t ext2fs_open2(const char *name,
goto cleanup;
if (!group_block)
group_block = fs->super->s_first_data_block;
- dest = (char *) fs->group_desc;
- groups_per_block = fs->blocksize / sizeof(struct ext2_group_desc);
+ gdp = fs->group_desc;
+ groups_per_block = fs->blocksize / fs->desc_size;
for (i=0 ; i < fs->desc_blocks; i++) {
blk = ext2fs_descriptor_block_loc(fs, group_block, i);
- retval = io_channel_read_blk(fs->io, blk, 1, dest);
+ retval = io_channel_read_blk(fs->io, blk, 1, shadow_block);
if (retval)
goto cleanup;
+
+ for (j=0; j < groups_per_block; j++) {
+ *gdp = *(struct ext2_group_desc *)(shadow_block + j * fs->desc_size);
#ifdef EXT2FS_ENABLE_SWAPFS
- if (fs->flags & EXT2_FLAG_SWAP_BYTES) {
- gdp = (struct ext2_group_desc *) dest;
- for (j=0; j < groups_per_block; j++)
- ext2fs_swap_group_desc(gdp++);
- }
+ if (fs->flags & EXT2_FLAG_SWAP_BYTES)
+ ext2fs_swap_group_desc(gdp);
#endif
- dest += fs->blocksize;
+ gdp++;
+ }
}
*ret_fs = fs;
Index: e2fsprogs-1.39/lib/ext2fs/closefs.c
===================================================================
--- e2fsprogs-1.39.orig/lib/ext2fs/closefs.c 2006-06-07 13:49:36.000000000 +0200
+++ e2fsprogs-1.39/lib/ext2fs/closefs.c 2006-06-07 13:50:04.000000000 +0200
@@ -81,7 +81,7 @@ int ext2fs_super_and_bgd_loc(ext2_filsys
super_blk = group_block;
numblocks--;
}
- meta_bg_size = (fs->blocksize / sizeof (struct ext2_group_desc));
+ meta_bg_size = (fs->blocksize / fs->desc_size);
meta_bg = group / meta_bg_size;
if (!(fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG) ||
@@ -221,33 +221,34 @@ errcode_t ext2fs_flush(ext2_filsys fs)
fs->super->s_wtime = fs->now ? fs->now : time(NULL);
fs->super->s_block_group_nr = 0;
+
+ retval = ext2fs_get_mem((size_t)(fs->blocksize * fs->desc_blocks),
+ &group_shadow);
+ if (retval)
+ goto errout;
+ memset(group_shadow, 0, (size_t) fs->blocksize * fs->desc_blocks);
+
+ /* swap the group descriptors */
+ for (j=0, s=fs->group_desc, t=group_shadow;
+ j < fs->group_desc_count; j++, s++) {
+ *t = *s;
+#ifdef EXT2FS_ENABLE_SWAPFS
+ if (fs->flags & EXT2_FLAG_SWAP_BYTES)
+ ext2fs_swap_group_desc(t);
+#endif
+ t = (struct ext2_group_desc *)((__u8 *)t + fs->desc_size);
+ }
+
#ifdef EXT2FS_ENABLE_SWAPFS
if (fs->flags & EXT2_FLAG_SWAP_BYTES) {
- retval = EXT2_ET_NO_MEMORY;
retval = ext2fs_get_mem(SUPERBLOCK_SIZE, &super_shadow);
if (retval)
goto errout;
- retval = ext2fs_get_mem((size_t)(fs->blocksize *
- fs->desc_blocks),
- &group_shadow);
- if (retval)
- goto errout;
- memset(group_shadow, 0, (size_t) fs->blocksize *
- fs->desc_blocks);
-
- /* swap the group descriptors */
- for (j=0, s=fs->group_desc, t=group_shadow;
- j < fs->group_desc_count; j++, t++, s++) {
- *t = *s;
- ext2fs_swap_group_desc(t);
- }
} else {
super_shadow = fs->super;
- group_shadow = fs->group_desc;
}
#else
super_shadow = fs->super;
- group_shadow = fs->group_desc;
#endif
/*
Index: e2fsprogs-1.39/lib/ext2fs/ext2_fs.h
===================================================================
--- e2fsprogs-1.39.orig/lib/ext2fs/ext2_fs.h 2006-06-07 13:49:36.000000000 +0200
+++ e2fsprogs-1.39/lib/ext2fs/ext2_fs.h 2006-06-07 13:50:04.000000000 +0200
@@ -190,6 +190,9 @@ struct ext2_dx_countlimit {
/*
* Macro-instructions used to manage group descriptors
*/
+#define EXT2_MIN_DESC_SIZE 32
+#define EXT2_MAX_DESC_SIZE EXT2_MIN_BLOCK_SIZE
+#define EXT2_DESC_SIZE(s) (EXT2_SB(s)->s_desc_size)
#define EXT2_BLOCKS_PER_GROUP(s) (EXT2_SB(s)->s_blocks_per_group)
#define EXT2_INODES_PER_GROUP(s) (EXT2_SB(s)->s_inodes_per_group)
#define EXT2_INODES_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s)/EXT2_INODE_SIZE(s))
@@ -200,7 +203,7 @@ struct ext2_dx_countlimit {
#define EXT2_DESC_PER_BLOCK(s) (EXT2_SB(s)->s_desc_per_block)
#define EXT2_DESC_PER_BLOCK_BITS(s) (EXT2_SB(s)->s_desc_per_block_bits)
#else
-#define EXT2_DESC_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / sizeof (struct ext2_group_desc))
+#define EXT2_DESC_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / EXT2_DESC_SIZE(s))
#endif
/*
@@ -521,7 +524,7 @@ struct ext2_super_block {
__u32 s_hash_seed[4]; /* HTREE hash seed */
__u8 s_def_hash_version; /* Default hash version to use */
__u8 s_jnl_backup_type; /* Default type of journal backup */
- __u16 s_reserved_word_pad;
+ __u16 s_desc_size; /* size of group descriptor */
__u32 s_default_mount_opts;
__u32 s_first_meta_bg; /* First metablock group */
__u32 s_mkfs_time; /* When the filesystem was created */
@@ -582,9 +585,9 @@ struct ext2_super_block {
#define EXT3_FEATURE_INCOMPAT_RECOVER 0x0004 /* Needs recovery */
#define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV 0x0008 /* Journal device */
#define EXT2_FEATURE_INCOMPAT_META_BG 0x0010
+#define EXT3_FEATURE_INCOMPAT_DESC_SIZE 0x0020
#define EXT3_FEATURE_INCOMPAT_EXTENTS 0x0040
-
#define EXT2_FEATURE_COMPAT_SUPP 0
#define EXT2_FEATURE_INCOMPAT_SUPP (EXT2_FEATURE_INCOMPAT_FILETYPE)
#define EXT2_FEATURE_RO_COMPAT_SUPP (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER| \
Index: e2fsprogs-1.39/lib/ext2fs/initialize.c
===================================================================
--- e2fsprogs-1.39.orig/lib/ext2fs/initialize.c 2006-06-07 13:49:36.000000000 +0200
+++ e2fsprogs-1.39/lib/ext2fs/initialize.c 2006-06-07 13:50:04.000000000 +0200
@@ -67,7 +67,7 @@ static unsigned int calc_reserved_gdt_bl
{
struct ext2_super_block *sb = fs->super;
unsigned long bpg = sb->s_blocks_per_group;
- unsigned int gdpb = fs->blocksize / sizeof(struct ext2_group_desc);
+ unsigned int gdpb = fs->blocksize / fs->desc_size;
unsigned long max_blocks = 0xffffffff;
unsigned long rsv_groups;
unsigned int rsv_gdb;
@@ -149,6 +149,7 @@ errcode_t ext2fs_initialize(const char *
set_field(s_log_block_size, 0); /* default blocksize: 1024 bytes */
set_field(s_log_frag_size, 0); /* default fragsize: 1024 bytes */
+ set_field(s_desc_size, EXT2_MIN_DESC_SIZE);
set_field(s_first_data_block, super->s_log_block_size ? 0 : 1);
set_field(s_max_mnt_count, EXT2_DFL_MAX_MNT_COUNT);
set_field(s_errors, EXT2_ERRORS_DEFAULT);
@@ -178,6 +179,7 @@ errcode_t ext2fs_initialize(const char *
fs->blocksize = EXT2_BLOCK_SIZE(super);
fs->fragsize = EXT2_FRAG_SIZE(super);
+ fs->desc_size = EXT2_DESC_SIZE(super);
frags_per_block = fs->blocksize / fs->fragsize;
/* default: (fs->blocksize*8) blocks/group, up to 2^16 (GDT limit) */
Index: e2fsprogs-1.39/lib/e2p/ls.c
===================================================================
--- e2fsprogs-1.39.orig/lib/e2p/ls.c 2006-05-31 15:44:49.000000000 +0200
+++ e2fsprogs-1.39/lib/e2p/ls.c 2006-06-07 16:04:38.000000000 +0200
@@ -199,6 +199,7 @@ void list_super2(struct ext2_super_block
fprintf(f, "First block: %u\n", sb->s_first_data_block);
fprintf(f, "Block size: %u\n", EXT2_BLOCK_SIZE(sb));
fprintf(f, "Fragment size: %u\n", EXT2_FRAG_SIZE(sb));
+ fprintf(f, "Descriptor size: %u\n", EXT2_DESC_SIZE(sb));
if (sb->s_reserved_gdt_blocks)
fprintf(f, "Reserved GDT blocks: %u\n",
sb->s_reserved_gdt_blocks);