From 75249edab0b22ea9aae9c7278b9f2c196c7d25d4 Mon Sep 17 00:00:00 2001 From: Ken Sumrall Date: Fri, 13 Aug 2010 16:04:49 -0700 Subject: [PATCH] Add support for sparse ext4 image creation. This adds the -s option to the make_ext4fs tool, which now creates "sparse" filesystem images, which is very useful for the large 32 Gbyte filesystems we are now building. This check-in also fixes make_ext4fs to properly create filesystems larger thatn 4 Gbytes on 64-bit Linux, 32-bit android and Macs. Change-Id: Ie5838492fcf944f5c875481693c0dbd7013deae4 --- ext4_utils/Android.mk | 7 ++ ext4_utils/backed_block.c | 4 +- ext4_utils/ext4_utils.c | 45 +++++--- ext4_utils/ext4_utils.h | 2 +- ext4_utils/make_ext4fs.c | 6 +- ext4_utils/make_ext4fs.h | 2 +- ext4_utils/make_ext4fs_main.c | 15 ++- ext4_utils/output_file.c | 248 ++++++++++++++++++++++++++++++++++++++---- ext4_utils/output_file.h | 3 +- ext4_utils/simg2img.c | 198 +++++++++++++++++++++++++++++++++ ext4_utils/sparse_format.h | 47 ++++++++ 11 files changed, 530 insertions(+), 47 deletions(-) create mode 100644 ext4_utils/simg2img.c create mode 100644 ext4_utils/sparse_format.h diff --git a/ext4_utils/Android.mk b/ext4_utils/Android.mk index 3f8b10ea..14702540 100644 --- a/ext4_utils/Android.mk +++ b/ext4_utils/Android.mk @@ -63,6 +63,13 @@ include $(BUILD_HOST_EXECUTABLE) include $(CLEAR_VARS) +LOCAL_SRC_FILES := simg2img.c +LOCAL_MODULE := simg2img + +include $(BUILD_HOST_EXECUTABLE) + +include $(CLEAR_VARS) + LOCAL_MODULE := mkuserimg.sh LOCAL_SRC_FILES := mkuserimg.sh LOCAL_MODULE_CLASS := EXECUTABLES diff --git a/ext4_utils/backed_block.c b/ext4_utils/backed_block.c index 5fa69435..c1a2f202 100644 --- a/ext4_utils/backed_block.c +++ b/ext4_utils/backed_block.c @@ -113,9 +113,9 @@ void for_each_data_block(data_block_callback_t data_func, last_block = db->block + DIV_ROUND_UP(db->len, info.block_size) - 1; if (db->filename) - file_func(out, db->block * info.block_size, db->filename, db->offset, db->len); + file_func(out, (u64)db->block * info.block_size, db->filename, db->offset, db->len); else - data_func(out, db->block * info.block_size, db->data, db->len); + data_func(out, (u64)db->block * info.block_size, db->data, db->len); } } diff --git a/ext4_utils/ext4_utils.c b/ext4_utils/ext4_utils.c index cd82827a..f34985f5 100644 --- a/ext4_utils/ext4_utils.c +++ b/ext4_utils/ext4_utils.c @@ -14,22 +14,12 @@ * limitations under the License. */ -#include "ext4_utils.h" -#include "output_file.h" -#include "backed_block.h" -#include "uuid.h" -#include "allocate.h" -#include "indirect.h" -#include "extent.h" - -#include "ext4.h" -#include "jbd2.h" - #include #include #include #include #include +#include #if defined(__linux__) #include @@ -37,6 +27,17 @@ #include #endif +#include "ext4_utils.h" +#include "output_file.h" +#include "backed_block.h" +#include "uuid.h" +#include "allocate.h" +#include "indirect.h" +#include "extent.h" + +#include "ext4.h" +#include "jbd2.h" + int force = 0; struct fs_info info; struct fs_aux_info aux_info; @@ -73,24 +74,36 @@ int ext4_bg_has_super_block(int bg) } /* Write the filesystem image to a file */ -void write_ext4_image(const char *filename, int gz) +void write_ext4_image(const char *filename, int gz, int sparse) { int ret = 0; - struct output_file *out = open_output_file(filename, gz); + struct output_file *out = open_output_file(filename, gz, sparse); off_t off; if (!out) return; - write_data_block(out, 1024, (u8*)aux_info.sb, 1024); + /* The write_data* functions expect only block aligned calls. + * This is not an issue, except when we write out the super + * block on a system with a block size > 1K. So, we need to + * deal with that here. + */ + if (info.block_size > 1024) { + u8 buf[4096] = { 0 }; /* The larget supported ext4 block size */ + memcpy(buf + 1024, (u8*)aux_info.sb, 1024); + write_data_block(out, 0, buf, info.block_size); + + } else { + write_data_block(out, 1024, (u8*)aux_info.sb, 1024); + } - write_data_block(out, (aux_info.first_data_block + 1) * info.block_size, + write_data_block(out, (u64)(aux_info.first_data_block + 1) * info.block_size, (u8*)aux_info.bg_desc, aux_info.bg_desc_blocks * info.block_size); for_each_data_block(write_data_block, write_data_file, out); - write_data_block(out, info.len - 1, (u8*)"", 1); + pad_output_file(out, info.len); close_output_file(out); } diff --git a/ext4_utils/ext4_utils.h b/ext4_utils/ext4_utils.h index 0a2b542a..697c8d90 100644 --- a/ext4_utils/ext4_utils.h +++ b/ext4_utils/ext4_utils.h @@ -116,7 +116,7 @@ static inline int log_2(int j) } int ext4_bg_has_super_block(int bg); -void write_ext4_image(const char *filename, int gz); +void write_ext4_image(const char *filename, int gz, int sparse); void ext4_create_fs_aux_info(void); void ext4_free_fs_aux_info(void); void ext4_fill_in_sb(void); diff --git a/ext4_utils/make_ext4fs.c b/ext4_utils/make_ext4fs.c index f77af0c9..87588ab6 100644 --- a/ext4_utils/make_ext4fs.c +++ b/ext4_utils/make_ext4fs.c @@ -62,6 +62,8 @@ static u32 build_default_directory_structure() root_inode = make_directory(0, 1, &dentries, 1); inode = make_directory(root_inode, 0, NULL, 0); *dentries.inode = inode; + inode_set_permissions(inode, dentries.mode, + dentries.uid, dentries.gid, dentries.mtime); return root_inode; } @@ -225,7 +227,7 @@ void reset_ext4fs_info() { } int make_ext4fs(const char *filename, const char *directory, - char *mountpoint, int android, int gzip) + char *mountpoint, int android, int gzip, int sparse) { u32 root_inode_num; u16 root_mode; @@ -319,7 +321,7 @@ int make_ext4fs(const char *filename, const char *directory, aux_info.sb->s_blocks_count_lo - aux_info.sb->s_free_blocks_count_lo, aux_info.sb->s_blocks_count_lo); - write_ext4_image(filename, gzip); + write_ext4_image(filename, gzip, sparse); return 0; } diff --git a/ext4_utils/make_ext4fs.h b/ext4_utils/make_ext4fs.h index 4045e6a0..8c6b2592 100644 --- a/ext4_utils/make_ext4fs.h +++ b/ext4_utils/make_ext4fs.h @@ -22,6 +22,6 @@ void reset_ext4fs_info(); int make_ext4fs(const char *filename, const char *directory, - char *mountpoint, int android, int gzip); + char *mountpoint, int android, int gzip, int sparse); #endif diff --git a/ext4_utils/make_ext4fs_main.c b/ext4_utils/make_ext4fs_main.c index afea6622..66d7aac6 100644 --- a/ext4_utils/make_ext4fs_main.c +++ b/ext4_utils/make_ext4fs_main.c @@ -33,6 +33,7 @@ static void usage(char *path) fprintf(stderr, "%s [ -l ] [ -j ] [ -b ]\n", basename(path)); fprintf(stderr, " [ -g ] [ -i ] [ -I ]\n"); fprintf(stderr, " [ -L