From b6fbe7bd5da6548323030ced25582d90c7a99cc7 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Mon, 2 Jun 2014 12:43:46 +0000 Subject: [PATCH] tools: genext2fs: add support for blocksize != 1024 This patch series is extracted from http://ftp.de.debian.org/debian/pool/main/g/genext2fs/genext2fs_1.4.1-4.debian.tar.gz The patches are used in Debian for quite a long time, so I assume that this is solid material. At least, my Ubuntu host fsck.ext4 does not bark :-) The goal is to allow building filesystems with larger blocksizes instead of the current default of 1k. This should improve performance and lifetime when the filesystem is stored e.g. on a SD card (on Raspberry Pi/I2SE Duckbill for example) which uses internal flash memory. Writing to flash memory is slow because writing the data of one block results in erasing a whole erase block of the flash memory. Thus it is preferable to align the filesystem block size on a flash device with the erase blocksize, or at least bring it closer to the later one, to avoid unnecessary write amplification. Signed-off-by: Michael Heimpold SVN-Revision: 40921 --- tools/genext2fs/patches/100-c99_scanf.patch | 21 + tools/genext2fs/patches/200-autoconf.patch | 13 + .../patches/300-blocksize-creator.patch | 558 ++++++++++++++++++ .../genext2fs/patches/400-byteswap_fix.patch | 44 ++ 4 files changed, 636 insertions(+) create mode 100644 tools/genext2fs/patches/100-c99_scanf.patch create mode 100644 tools/genext2fs/patches/200-autoconf.patch create mode 100644 tools/genext2fs/patches/300-blocksize-creator.patch create mode 100644 tools/genext2fs/patches/400-byteswap_fix.patch diff --git a/tools/genext2fs/patches/100-c99_scanf.patch b/tools/genext2fs/patches/100-c99_scanf.patch new file mode 100644 index 0000000000..e7aa17cc6f --- /dev/null +++ b/tools/genext2fs/patches/100-c99_scanf.patch @@ -0,0 +1,21 @@ +commit 3b8ca0ce9a0b58287a780747c90c449bdebfe464 +Author: Xavier Bestel +Date: Mon Jan 14 08:52:44 2008 +0000 + + removed use of %as is scanf (GNU conflicts with C99) by Giacomo Catenazzi + +diff --git a/genext2fs.c b/genext2fs.c +index 070b270..f0d797d 100644 +--- a/genext2fs.c ++++ b/genext2fs.c +@@ -286,7 +286,9 @@ typedef unsigned int uint32; + // older solaris. Note that this is still not very portable, in that + // the return value cannot be trusted. + +-#if SCANF_CAN_MALLOC ++#if 0 // SCANF_CAN_MALLOC ++// C99 define "a" for floating point, so you can have runtime surprise ++// according the library versions + # define SCANF_PREFIX "a" + # define SCANF_STRING(s) (&s) + #else diff --git a/tools/genext2fs/patches/200-autoconf.patch b/tools/genext2fs/patches/200-autoconf.patch new file mode 100644 index 0000000000..b3317bdd10 --- /dev/null +++ b/tools/genext2fs/patches/200-autoconf.patch @@ -0,0 +1,13 @@ +Index: genext2fs/m4/ac_func_scanf_can_malloc.m4 +=================================================================== +--- genext2fs.orig/m4/ac_func_scanf_can_malloc.m4 2011-09-03 21:28:49.000000000 +0200 ++++ genext2fs/m4/ac_func_scanf_can_malloc.m4 2011-09-03 21:29:41.000000000 +0200 +@@ -9,7 +9,7 @@ + # -------------------------------------- + AC_DEFUN([AC_FUNC_SCANF_CAN_MALLOC], + [ AC_CHECK_HEADERS([stdlib.h]) +- AC_CACHE_CHECK([whether scanf can malloc], [ac_scanf_can_malloc], ++ AC_CACHE_CHECK([whether scanf can malloc], [ac_cv_func_scanf_can_malloc], + [ AC_RUN_IFELSE( + [ AC_LANG_PROGRAM( + [ diff --git a/tools/genext2fs/patches/300-blocksize-creator.patch b/tools/genext2fs/patches/300-blocksize-creator.patch new file mode 100644 index 0000000000..97a4836eeb --- /dev/null +++ b/tools/genext2fs/patches/300-blocksize-creator.patch @@ -0,0 +1,558 @@ +Index: genext2fs/genext2fs.c +=================================================================== +--- genext2fs.orig/genext2fs.c 2011-09-03 14:21:17.000000000 +0200 ++++ genext2fs/genext2fs.c 2011-09-03 14:21:17.000000000 +0200 +@@ -151,13 +151,24 @@ + + // block size + +-#define BLOCKSIZE 1024 ++static int blocksize = 1024; ++ ++#define BLOCKSIZE blocksize + #define BLOCKS_PER_GROUP 8192 + #define INODES_PER_GROUP 8192 + /* Percentage of blocks that are reserved.*/ + #define RESERVED_BLOCKS 5/100 + #define MAX_RESERVED_BLOCKS 25/100 + ++/* The default value for s_creator_os. */ ++#if defined(__GNU__) ++# define CREATOR_OS 1 /* Hurd */ ++#elif defined(__FreeBSD__) ++# define CREATOR_OS 3 /* FreeBSD */ ++#else ++# define CREATOR_OS 0 /* Linux */ ++#endif ++ + + // inode block size (why is it != BLOCKSIZE ?!?) + /* The field i_blocks in the ext2 inode stores the number of data blocks +@@ -239,10 +250,10 @@ + (fs)->sb.s_blocks_per_group - 1) / (fs)->sb.s_blocks_per_group) + + // Get group block bitmap (bbm) given the group number +-#define GRP_GET_GROUP_BBM(fs,grp) ( get_blk((fs),(fs)->gd[(grp)].bg_block_bitmap) ) ++#define GRP_GET_GROUP_BBM(fs,grp) ( get_blk((fs), get_gd((fs),(grp))->bg_block_bitmap) ) + + // Get group inode bitmap (ibm) given the group number +-#define GRP_GET_GROUP_IBM(fs,grp) ( get_blk((fs),(fs)->gd[(grp)].bg_inode_bitmap) ) ++#define GRP_GET_GROUP_IBM(fs,grp) ( get_blk((fs), get_gd((fs),(grp))->bg_inode_bitmap) ) + + // Given an inode number find the group it belongs to + #define GRP_GROUP_OF_INODE(fs,nod) ( ((nod)-1) / (fs)->sb.s_inodes_per_group) +@@ -532,7 +543,7 @@ + char d_name[0]; + } directory; + +-typedef uint8 block[BLOCKSIZE]; ++typedef uint8 *block; + + /* blockwalker fields: + The blockwalker is used to access all the blocks of a file (including +@@ -571,16 +582,12 @@ + + + /* Filesystem structure that support groups */ +-#if BLOCKSIZE == 1024 + typedef struct + { +- block zero; // The famous block 0 +- superblock sb; // The superblock +- groupdescriptor gd[0]; // The group descriptors ++ uint8 zero[1024]; // Room for bootloader stuff ++ superblock sb; // The superblock, always at 1024 ++ // group descriptors come next, see get_gd() below + } filesystem; +-#else +-#error UNHANDLED BLOCKSIZE +-#endif + + // now the endianness swap + +@@ -820,6 +827,14 @@ + return (uint8*)fs + blk*BLOCKSIZE; + } + ++// the group descriptors are aligned on the block size ++static inline groupdescriptor * ++get_gd(filesystem *fs, int no) ++{ ++ int gdblk = (sizeof (filesystem) + BLOCKSIZE - 1) / BLOCKSIZE; ++ return ((groupdescriptor *) get_blk(fs, gdblk)) + no; ++} ++ + // return a given inode from a filesystem + static inline inode * + get_nod(filesystem *fs, uint32 nod) +@@ -829,7 +844,7 @@ + + offset = GRP_IBM_OFFSET(fs,nod); + grp = GRP_GROUP_OF_INODE(fs,nod); +- itab = (inode *)get_blk(fs, fs->gd[grp].bg_inode_table); ++ itab = (inode *)get_blk(fs, get_gd(fs,grp)->bg_inode_table); + return itab+offset-1; + } + +@@ -875,18 +890,18 @@ + + grp = GRP_GROUP_OF_INODE(fs,nod); + nbgroups = GRP_NBGROUPS(fs); +- if(!(bk = allocate(get_blk(fs,fs->gd[grp].bg_block_bitmap), 0))) { ++ if(!(bk = allocate(GRP_GET_GROUP_BBM(fs, grp), 0))) { + for(grp=0;grpgd[grp].bg_block_bitmap),0); ++ bk = allocate(GRP_GET_GROUP_BBM(fs, grp), 0); + grp--; + } + if (!bk) + error_msg_and_die("couldn't allocate a block (no free space)"); +- if(!(fs->gd[grp].bg_free_blocks_count--)) ++ if(!(get_gd(fs, grp)->bg_free_blocks_count--)) + error_msg_and_die("group descr %d. free blocks count == 0 (corrupted fs?)",grp); + if(!(fs->sb.s_free_blocks_count--)) + error_msg_and_die("superblock free blocks count == 0 (corrupted fs?)"); +- return fs->sb.s_blocks_per_group*grp + bk; ++ return fs->sb.s_first_data_block + fs->sb.s_blocks_per_group*grp + (bk-1); + } + + // free a block +@@ -897,8 +912,8 @@ + + grp = bk / fs->sb.s_blocks_per_group; + bk %= fs->sb.s_blocks_per_group; +- deallocate(get_blk(fs,fs->gd[grp].bg_block_bitmap), bk); +- fs->gd[grp].bg_free_blocks_count++; ++ deallocate(GRP_GET_GROUP_BBM(fs, grp), bk); ++ get_gd(fs, grp)->bg_free_blocks_count++; + fs->sb.s_free_blocks_count++; + } + +@@ -918,16 +933,16 @@ + /* We do it for all inodes. */ + avefreei = fs->sb.s_free_inodes_count / nbgroups; + for(grp=0; grpgd[grp].bg_free_inodes_count < avefreei || +- fs->gd[grp].bg_free_inodes_count == 0) ++ if (get_gd(fs, grp)->bg_free_inodes_count < avefreei || ++ get_gd(fs, grp)->bg_free_inodes_count == 0) + continue; + if (!best_group || +- fs->gd[grp].bg_free_blocks_count > fs->gd[best_group].bg_free_blocks_count) ++ get_gd(fs, grp)->bg_free_blocks_count > get_gd(fs, best_group)->bg_free_blocks_count) + best_group = grp; + } +- if (!(nod = allocate(get_blk(fs,fs->gd[best_group].bg_inode_bitmap),0))) ++ if (!(nod = allocate(GRP_GET_GROUP_IBM(fs, best_group), 0))) + error_msg_and_die("couldn't allocate an inode (no free inode)"); +- if(!(fs->gd[best_group].bg_free_inodes_count--)) ++ if(!(get_gd(fs, best_group)->bg_free_inodes_count--)) + error_msg_and_die("group descr. free blocks count == 0 (corrupted fs?)"); + if(!(fs->sb.s_free_inodes_count--)) + error_msg_and_die("superblock free blocks count == 0 (corrupted fs?)"); +@@ -1390,7 +1405,7 @@ + case FM_IFDIR: + add2dir(fs, nod, nod, "."); + add2dir(fs, nod, parent_nod, ".."); +- fs->gd[GRP_GROUP_OF_INODE(fs,nod)].bg_used_dirs_count++; ++ get_gd(fs, GRP_GROUP_OF_INODE(fs,nod))->bg_used_dirs_count++; + break; + } + } +@@ -1860,7 +1875,7 @@ + swap_nod(nod); + } + for(i=0;igd[i])); ++ swap_gd(get_gd(fs, i)); + swap_sb(&fs->sb); + } + +@@ -1870,7 +1885,7 @@ + uint32 i; + swap_sb(&fs->sb); + for(i=0;igd[i])); ++ swap_gd(get_gd(fs, i)); + for(i = 1; i < fs->sb.s_inodes_count; i++) + { + inode *nod = get_nod(fs, i); +@@ -1895,7 +1910,8 @@ + + // initialize an empty filesystem + static filesystem * +-init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes, uint32 fs_timestamp) ++init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes, ++ uint32 fs_timestamp, uint32 creator_os) + { + uint32 i; + filesystem *fs; +@@ -1921,10 +1937,14 @@ + */ + min_nbgroups = (nbinodes + INODES_PER_GROUP - 1) / INODES_PER_GROUP; + ++ /* On filesystems with 1k block size, the bootloader area uses a full ++ * block. For 2048 and up, the superblock can be fitted into block 0. ++ */ ++ first_block = (BLOCKSIZE == 1024); ++ + /* nbblocks is the total number of blocks in the filesystem. + * a block group can have no more than 8192 blocks. + */ +- first_block = (BLOCKSIZE == 1024); + nbgroups = (nbblocks - first_block + BLOCKS_PER_GROUP - 1) / BLOCKS_PER_GROUP; + if(nbgroups < min_nbgroups) nbgroups = min_nbgroups; + nbblocks_per_group = rndup((nbblocks - first_block + nbgroups - 1)/nbgroups, 8); +@@ -1936,10 +1956,10 @@ + gdsz = rndup(nbgroups*sizeof(groupdescriptor),BLOCKSIZE)/BLOCKSIZE; + itblsz = nbinodes_per_group * sizeof(inode)/BLOCKSIZE; + overhead_per_group = 3 /*sb,bbm,ibm*/ + gdsz + itblsz; +- if((uint32)nbblocks - 1 < overhead_per_group * nbgroups) +- error_msg_and_die("too much overhead, try fewer inodes or more blocks. Note: options have changed, see --help or the man page."); +- free_blocks = nbblocks - overhead_per_group*nbgroups - 1 /*boot block*/; ++ free_blocks = nbblocks - overhead_per_group*nbgroups - first_block; + free_blocks_per_group = nbblocks_per_group - overhead_per_group; ++ if(free_blocks < 0) ++ error_msg_and_die("too much overhead, try fewer inodes or more blocks. Note: options have changed, see --help or the man page."); + + if(!(fs = (filesystem*)calloc(nbblocks, BLOCKSIZE))) + error_msg_and_die("not enough memory for filesystem"); +@@ -1959,28 +1979,31 @@ + fs->sb.s_wtime = fs_timestamp; + fs->sb.s_magic = EXT2_MAGIC_NUMBER; + fs->sb.s_lastcheck = fs_timestamp; ++ fs->sb.s_creator_os = creator_os; + + // set up groupdescriptors +- for(i=0, bbmpos=gdsz+2, ibmpos=bbmpos+1, itblpos=ibmpos+1; ++ for(i=0, bbmpos=first_block+1+gdsz, ibmpos=bbmpos+1, itblpos=ibmpos+1; + i free_blocks_per_group) { +- fs->gd[i].bg_free_blocks_count = free_blocks_per_group; ++ gd->bg_free_blocks_count = free_blocks_per_group; + free_blocks -= free_blocks_per_group; + } else { +- fs->gd[i].bg_free_blocks_count = free_blocks; ++ gd->bg_free_blocks_count = free_blocks; + free_blocks = 0; // this is the last block group + } + if(i) +- fs->gd[i].bg_free_inodes_count = nbinodes_per_group; ++ gd->bg_free_inodes_count = nbinodes_per_group; + else +- fs->gd[i].bg_free_inodes_count = nbinodes_per_group - ++ gd->bg_free_inodes_count = nbinodes_per_group - + EXT2_FIRST_INO + 2; +- fs->gd[i].bg_used_dirs_count = 0; +- fs->gd[i].bg_block_bitmap = bbmpos; +- fs->gd[i].bg_inode_bitmap = ibmpos; +- fs->gd[i].bg_inode_table = itblpos; ++ gd->bg_used_dirs_count = 0; ++ gd->bg_block_bitmap = bbmpos; ++ gd->bg_inode_bitmap = ibmpos; ++ gd->bg_inode_table = itblpos; + } + + /* Mark non-filesystem blocks and inodes as allocated */ +@@ -1988,9 +2011,9 @@ + for(i = 0; igd[i].bg_block_bitmap); ++ bbm = GRP_GET_GROUP_BBM(fs, i); + //non-filesystem blocks +- for(j = fs->gd[i].bg_free_blocks_count ++ for(j = get_gd(fs, i)->bg_free_blocks_count + + overhead_per_group + 1; j <= BLOCKSIZE * 8; j++) + allocate(bbm, j); + //system blocks +@@ -1998,7 +2021,7 @@ + allocate(bbm, j); + + /* Inode bitmap */ +- ibm = get_blk(fs,fs->gd[i].bg_inode_bitmap); ++ ibm = GRP_GET_GROUP_IBM(fs, i); + //non-filesystem inodes + for(j = fs->sb.s_inodes_per_group+1; j <= BLOCKSIZE * 8; j++) + allocate(ibm, j); +@@ -2012,9 +2035,9 @@ + // make root inode and directory + /* We have groups now. Add the root filesystem in group 0 */ + /* Also increment the directory count for group 0 */ +- fs->gd[0].bg_free_inodes_count--; +- fs->gd[0].bg_used_dirs_count = 1; +- itab0 = (inode *)get_blk(fs,fs->gd[0].bg_inode_table); ++ get_gd(fs, 0)->bg_free_inodes_count--; ++ get_gd(fs, 0)->bg_used_dirs_count = 1; ++ itab0 = (inode *)get_blk(fs, get_gd(fs,0)->bg_inode_table); + itab0[EXT2_ROOT_INO-1].i_mode = FM_IFDIR | FM_IRWXU | FM_IRGRP | FM_IROTH | FM_IXGRP | FM_IXOTH; + itab0[EXT2_ROOT_INO-1].i_ctime = fs_timestamp; + itab0[EXT2_ROOT_INO-1].i_mtime = fs_timestamp; +@@ -2338,8 +2361,9 @@ + for (i = 0; i < GRP_NBGROUPS(fs); i++) { + printf("Group No: %d\n", i+1); + printf("block bitmap: block %d,inode bitmap: block %d, inode table: block %d\n", +- fs->gd[i].bg_block_bitmap, fs->gd[i].bg_inode_bitmap, +- fs->gd[i].bg_inode_table); ++ get_gd(fs, i)->bg_block_bitmap, ++ get_gd(fs, i)->bg_inode_bitmap, ++ get_gd(fs, i)->bg_inode_table); + printf("block bitmap allocation:\n"); + print_bm(GRP_GET_GROUP_BBM(fs, i),fs->sb.s_blocks_per_group); + printf("inode bitmap allocation:\n"); +@@ -2421,10 +2445,12 @@ + " -x, --starting-image \n" + " -d, --root \n" + " -D, --devtable \n" ++ " -B, --block-size \n" + " -b, --size-in-blocks \n" + " -i, --bytes-per-inode \n" + " -N, --number-of-inodes \n" + " -m, --reserved-percentage \n" ++ " -o, --creator-os 'linux', 'hurd', 'freebsd' or a numerical value.\n" + " -g, --block-map Generate a block map file for this path.\n" + " -e, --fill-value Fill unallocated blocks with value.\n" + " -z, --allow-holes Allow files with holes.\n" +@@ -2446,6 +2472,29 @@ + extern char* optarg; + extern int optind, opterr, optopt; + ++// parse the value for -o ++int ++lookup_creator_os(const char *name) ++{ ++ static const char *const creators[] = ++ {"linux", "hurd", "2", "freebsd", NULL}; ++ char *endptr; ++ int i; ++ ++ // numerical value ? ++ i = strtol(name, &endptr, 0); ++ if(name[0] && *endptr == '\0') ++ return i; ++ ++ // symbolic name ? ++ for(i=0; creators[i]; i++) ++ if(strcasecmp(creators[i], name) == 0) ++ return i; ++ ++ // whatever ? ++ return -1; ++} ++ + int + main(int argc, char **argv) + { +@@ -2455,6 +2504,7 @@ + float bytes_per_inode = -1; + float reserved_frac = -1; + int fs_timestamp = -1; ++ int creator_os = CREATOR_OS; + char * fsout = "-"; + char * fsin = 0; + char * dopt[MAX_DOPT]; +@@ -2478,10 +2528,12 @@ + { "starting-image", required_argument, NULL, 'x' }, + { "root", required_argument, NULL, 'd' }, + { "devtable", required_argument, NULL, 'D' }, ++ { "block-size", required_argument, NULL, 'B' }, + { "size-in-blocks", required_argument, NULL, 'b' }, + { "bytes-per-inode", required_argument, NULL, 'i' }, + { "number-of-inodes", required_argument, NULL, 'N' }, + { "reserved-percentage", required_argument, NULL, 'm' }, ++ { "creator-os", required_argument, NULL, 'o' }, + { "block-map", required_argument, NULL, 'g' }, + { "fill-value", required_argument, NULL, 'e' }, + { "allow-holes", no_argument, NULL, 'z' }, +@@ -2497,11 +2549,11 @@ + + app_name = argv[0]; + +- while((c = getopt_long(argc, argv, "x:d:D:b:i:N:m:g:e:zfqUPhVv", longopts, NULL)) != EOF) { ++ while((c = getopt_long(argc, argv, "x:d:D:B:b:i:N:m:o:g:e:zfqUPhVv", longopts, NULL)) != EOF) { + #else + app_name = argv[0]; + +- while((c = getopt(argc, argv, "x:d:D:b:i:N:m:g:e:zfqUPhVv")) != EOF) { ++ while((c = getopt(argc, argv, "x:d:D:B:b:i:N:m:o:g:e:zfqUPhVv")) != EOF) { + #endif /* HAVE_GETOPT_LONG */ + switch(c) + { +@@ -2512,6 +2564,9 @@ + case 'D': + dopt[didx++] = optarg; + break; ++ case 'B': ++ blocksize = SI_atof(optarg); ++ break; + case 'b': + nbblocks = SI_atof(optarg); + break; +@@ -2524,6 +2579,9 @@ + case 'm': + reserved_frac = SI_atof(optarg) / 100; + break; ++ case 'o': ++ creator_os = lookup_creator_os(optarg); ++ break; + case 'g': + gopt[gidx++] = optarg; + break; +@@ -2567,6 +2625,11 @@ + error_msg_and_die("Not enough arguments. Try --help or else see the man page."); + fsout = argv[optind]; + ++ if(blocksize != 1024 && blocksize != 2048 && blocksize != 4096) ++ error_msg_and_die("Valid block sizes: 1024, 2048 or 4096."); ++ if(creator_os < 0) ++ error_msg_and_die("Creator OS unknown."); ++ + hdlinks.hdl = (struct hdlink_s *)malloc(hdlink_cnt * sizeof(struct hdlink_s)); + if (!hdlinks.hdl) + error_msg_and_die("Not enough memory"); +@@ -2611,7 +2674,8 @@ + } + if(fs_timestamp == -1) + fs_timestamp = time(NULL); +- fs = init_fs(nbblocks, nbinodes, nbresrvd, holes, fs_timestamp); ++ fs = init_fs(nbblocks, nbinodes, nbresrvd, holes, ++ fs_timestamp, creator_os); + } + + populate_fs(fs, dopt, didx, squash_uids, squash_perms, fs_timestamp, NULL); +Index: genext2fs/test-gen.lib +=================================================================== +--- genext2fs.orig/test-gen.lib 2011-09-03 13:40:35.000000000 +0200 ++++ genext2fs/test-gen.lib 2011-09-03 14:21:17.000000000 +0200 +@@ -8,7 +8,7 @@ + # Creates an image with a file of given size + # Usage: dgen file-size number-of-blocks + dgen () { +- size=$1; blocks=$2 ++ size=$1; blocks=$2; blocksz=$3; + rm -rf test + mkdir -p test + cd test +@@ -20,7 +20,7 @@ + chmod 777 file.$1 + TZ=UTC-11 touch -t 200502070321.43 file.$1 . + cd .. +- ./genext2fs -N 17 -b $blocks -d test -f -q ext2.img ++ ./genext2fs -B $blocksz -N 17 -b $blocks -d test -f -o Linux -q ext2.img + } + + # fgen - Exercises the -f spec-file option of genext2fs +@@ -31,7 +31,7 @@ + mkdir -p test + cp $fname test + TZ=UTC-11 touch -t 200502070321.43 test/$fname +- ./genext2fs -N 92 -b $blocks -D test/$fname -f ext2.img ++ ./genext2fs -N 92 -b $blocks -D test/$fname -f -o Linux ext2.img + } + + # gen_cleanup - Remove the files generated by the above functions +Index: genext2fs/test-mount.sh +=================================================================== +--- genext2fs.orig/test-mount.sh 2011-09-03 13:40:35.000000000 +0200 ++++ genext2fs/test-mount.sh 2011-09-03 14:21:17.000000000 +0200 +@@ -33,9 +33,9 @@ + # and returns the command line with which to invoke dtest() + # Usage: dtest-mount file-size number-of-blocks + dtest_mount () { +- size=$1; blocks=$2 +- echo Testing with file of size $size +- dgen $size $blocks ++ size=$1; blocks=$2; blocksz=$3; ++ echo Testing $blocks blocks of $blocksz bytes with file of size $size ++ dgen $size $blocks $blocksz + /sbin/e2fsck -fn ext2.img || fail + mkdir -p mnt + mount -t ext2 -o ro,loop ext2.img mnt || fail +@@ -44,7 +44,7 @@ + awk '{print $5}'`" ] ; then + fail + fi +- pass dtest $size $blocks ++ pass dtest $size $blocks $blocksz + } + + # ftest-mount - Exercise the -f spec-file option of genext2fs +@@ -75,13 +75,21 @@ + pass ftest $fname $blocks + } + +-dtest_mount 0 4096 +-dtest_mount 0 8193 +-dtest_mount 0 8194 +-dtest_mount 1 4096 +-dtest_mount 12288 4096 +-dtest_mount 274432 4096 +-dtest_mount 8388608 9000 +-dtest_mount 16777216 20000 ++dtest_mount 0 4096 1024 ++dtest_mount 0 2048 2048 ++dtest_mount 0 1024 4096 ++dtest_mount 0 8193 1024 ++dtest_mount 0 8194 1024 ++dtest_mount 0 8193 4096 ++dtest_mount 0 8194 2048 ++dtest_mount 1 4096 1024 ++dtest_mount 1 1024 4096 ++dtest_mount 12288 4096 1024 ++dtest_mount 274432 4096 1024 ++dtest_mount 8388608 9000 1024 ++dtest_mount 8388608 4500 2048 ++dtest_mount 8388608 2250 4096 ++dtest_mount 16777216 20000 1024 ++dtest_mount 16777216 10000 2048 + + ftest_mount device_table.txt 4096 +Index: genext2fs/test.sh +=================================================================== +--- genext2fs.orig/test.sh 2011-09-03 13:40:35.000000000 +0200 ++++ genext2fs/test.sh 2011-09-03 14:21:17.000000000 +0200 +@@ -30,9 +30,9 @@ + # Creates an image with a file of given size and verifies it + # Usage: dtest file-size number-of-blocks correct-checksum + dtest () { +- size=$1; blocks=$2; checksum=$3 ++ size=$1; blocks=$2; blocksz=$3; checksum=$4 + echo Testing with file of size $size +- dgen $size $blocks ++ dgen $size $blocks $blocksz + md5cmp $checksum + gen_cleanup + } +@@ -53,12 +53,20 @@ + # replace the following lines with the output of + # sudo sh test-mount.sh|grep test + +-dtest 0 4096 3bc6424b8fcd51a0de34ee59d91d5f16 +-dtest 0 8193 f174804f6b433b552706cbbfc60c416d +-dtest 0 8194 4855a55d0cbdc44584634df49ebd5711 +-dtest 1 4096 09c569b6bfb45222c729c42d04d5451f +-dtest 12288 4096 61febcbfbf32024ef99103fcdc282c39 +-dtest 274432 4096 0c517803552c55c1806e4220b0a0164f +-dtest 8388608 9000 e0e5ea15bced10ab486d8135584b5d8e +-dtest 16777216 20000 fdf636eb905ab4dc1bf76dce5ac5d209 ++dtest 0 4096 1024 3bc6424b8fcd51a0de34ee59d91d5f16 ++dtest 0 2048 2048 230afa16496df019878cc2370c661cdc ++dtest 0 1024 4096 ebff5eeb38b70f3f1cd081e60eb44561 ++dtest 0 8193 1024 f174804f6b433b552706cbbfc60c416d ++dtest 0 8194 1024 4855a55d0cbdc44584634df49ebd5711 ++dtest 0 8193 4096 c493679698418ec7e6552005e2d2a6d8 ++dtest 0 8194 2048 ec13f328fa7543563f35f494bddc059c ++dtest 1 4096 1024 09c569b6bfb45222c729c42d04d5451f ++dtest 1 1024 4096 d318a326fdc907810ae9e6b0a20e9b06 ++dtest 12288 4096 1024 61febcbfbf32024ef99103fcdc282c39 ++dtest 274432 4096 1024 0c517803552c55c1806e4220b0a0164f ++dtest 8388608 9000 1024 e0e5ea15bced10ab486d8135584b5d8e ++dtest 8388608 4500 2048 39f4d537a72f5053fd6891721c59680d ++dtest 8388608 2250 4096 1d697fa4bc2cfffe02ac91edfadc40bf ++dtest 16777216 20000 1024 fdf636eb905ab4dc1bf76dce5ac5d209 ++dtest 16777216 10000 2048 f9824a81ea5e74fdf469c097927c292b + ftest device_table.txt 4096 a0af06d944b11d2902dfd705484c64cc diff --git a/tools/genext2fs/patches/400-byteswap_fix.patch b/tools/genext2fs/patches/400-byteswap_fix.patch new file mode 100644 index 0000000000..7b3c00b5ee --- /dev/null +++ b/tools/genext2fs/patches/400-byteswap_fix.patch @@ -0,0 +1,44 @@ +Index: genext2fs/genext2fs.c +=================================================================== +--- genext2fs.orig/genext2fs.c 2011-11-29 17:36:06.000000000 +0100 ++++ genext2fs/genext2fs.c 2011-11-29 17:37:37.000000000 +0100 +@@ -1779,7 +1779,8 @@ + assert(nod->i_block[EXT2_DIND_BLOCK] != 0); + for(i = 0; i < BLOCKSIZE/4; i++) + if(nblk > EXT2_IND_BLOCK + BLOCKSIZE/4 + (BLOCKSIZE/4)*i ) +- swap_block(get_blk(fs, ((uint32*)get_blk(fs, nod->i_block[EXT2_DIND_BLOCK]))[i])); ++ if (((uint32*)get_blk(fs, nod->i_block[EXT2_DIND_BLOCK]))[i]) ++ swap_block(get_blk(fs, ((uint32*)get_blk(fs, nod->i_block[EXT2_DIND_BLOCK]))[i])); + swap_block(get_blk(fs, nod->i_block[EXT2_DIND_BLOCK])); + if(nblk <= EXT2_IND_BLOCK + BLOCKSIZE/4 + BLOCKSIZE/4 * BLOCKSIZE/4) + return; +@@ -1792,7 +1793,8 @@ + (BLOCKSIZE/4)*(BLOCKSIZE/4) + + i*(BLOCKSIZE/4)*(BLOCKSIZE/4) + + j*(BLOCKSIZE/4)) ) +- swap_block(get_blk(fs,b2[j])); ++ if (b2[j]) ++ swap_block(get_blk(fs,b2[j])); + else { + done = 1; + break; +@@ -1825,7 +1827,8 @@ + swap_block(get_blk(fs, nod->i_block[EXT2_DIND_BLOCK])); + for(i = 0; i < BLOCKSIZE/4; i++) + if(nblk > EXT2_IND_BLOCK + BLOCKSIZE/4 + (BLOCKSIZE/4)*i ) +- swap_block(get_blk(fs, ((uint32*)get_blk(fs, nod->i_block[EXT2_DIND_BLOCK]))[i])); ++ if (((uint32*)get_blk(fs, nod->i_block[EXT2_DIND_BLOCK]))[i]) ++ swap_block(get_blk(fs, ((uint32*)get_blk(fs, nod->i_block[EXT2_DIND_BLOCK]))[i])); + if(nblk <= EXT2_IND_BLOCK + BLOCKSIZE/4 + BLOCKSIZE/4 * BLOCKSIZE/4) + return; + /* Adding support for triple indirection */ +@@ -1839,7 +1842,8 @@ + (BLOCKSIZE/4)*(BLOCKSIZE/4) + + i*(BLOCKSIZE/4)*(BLOCKSIZE/4) + + j*(BLOCKSIZE/4)) ) +- swap_block(get_blk(fs,b2[j])); ++ if (b2[j]) ++ swap_block(get_blk(fs,b2[j])); + else { + done = 1; + break; -- 2.30.2