[source] tools: bring back genext2fs for apm821xx

LEDE Commits lede-commits at lists.infradead.org
Sat Jul 23 10:37:25 PDT 2016


nbd pushed a commit to source.git, branch master:
https://git.lede-project.org/?p=source.git;a=commitdiff;h=07577c5ebe1a49b5c05659559c2fd220647b33f6

commit 07577c5ebe1a49b5c05659559c2fd220647b33f6
Author: Felix Fietkau <nbd at nbd.name>
AuthorDate: Sat Jul 23 19:33:28 2016 +0200

    tools: bring back genext2fs for apm821xx
    
    This reverts commit 8c68c104eaba65273280c7a4727fbb10ab10f5af.
    It is used for apm821xx, which needs ext2 (not ext4) images for some
    devices.
    
    Signed-off-by: Felix Fietkau <nbd at nbd.name>
---
 target/linux/apm821xx/sata/target.mk               |   4 -
 tools/Makefile                                     |   1 +
 tools/genext2fs/Makefile                           |  51 ++
 tools/genext2fs/patches/100-c99_scanf.patch        |  21 +
 tools/genext2fs/patches/200-autoconf.patch         |  13 +
 .../genext2fs/patches/300-blocksize-creator.patch  | 558 +++++++++++++++++++++
 tools/genext2fs/patches/400-byteswap_fix.patch     |  44 ++
 7 files changed, 688 insertions(+), 4 deletions(-)

diff --git a/target/linux/apm821xx/sata/target.mk b/target/linux/apm821xx/sata/target.mk
index 60efb50..c652fe4 100644
--- a/target/linux/apm821xx/sata/target.mk
+++ b/target/linux/apm821xx/sata/target.mk
@@ -7,7 +7,3 @@ define Target/Description
 	Build firmware images for APM82181 boards that boot from SATA.
 	For NAS like the MyBook Live Series.
 endef
-
-$(eval $(call $(if $(CONFIG_TARGET_ROOTFS_EXT4FS),RequireCommand,Ignore),genext2fs, \
-        Please install genext2fs. \
-))
diff --git a/tools/Makefile b/tools/Makefile
index 4fb583e..b412d26 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -44,6 +44,7 @@ tools-$(BUILD_B43_TOOLS) += b43-tools
 tools-$(BUILD_PPL_CLOOG) += ppl cloog
 tools-$(BUILD_ISL) += isl
 tools-$(CONFIG_USE_SPARSE) += sparse
+tools-$(CONFIG_TARGET_apm821xx) += genext2fs
 
 # builddir dependencies
 $(curdir)/bison/compile := $(curdir)/flex/install
diff --git a/tools/genext2fs/Makefile b/tools/genext2fs/Makefile
new file mode 100644
index 0000000..ad941c7
--- /dev/null
+++ b/tools/genext2fs/Makefile
@@ -0,0 +1,51 @@
+# 
+# Copyright (C) 2006 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=genext2fs
+PKG_VERSION:=1.4.1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=@SF/genext2fs
+PKG_MD5SUM:=b7b6361bcce2cedff1ae437fadafe53b
+
+include $(INCLUDE_DIR)/host-build.mk
+
+HOST_CONFIGURE_ARGS = \
+	--target=$(GNU_HOST_NAME) \
+	--host=$(GNU_HOST_NAME) \
+	--build=$(GNU_HOST_NAME) \
+	--program-prefix="" \
+	--program-suffix="" \
+	--prefix=/usr \
+	--exec-prefix=/usr \
+	--bindir=/usr/bin \
+	--sbindir=/usr/sbin \
+	--libexecdir=/usr/lib \
+	--sysconfdir=/etc \
+	--datadir=/usr/share \
+	--localstatedir=/var \
+	--mandir=/usr/man \
+	--infodir=/usr/info \
+
+define Host/Compile
+	$(MAKE) -C $(HOST_BUILD_DIR) \
+		CFLAGS="$(HOST_CFLAGS)" \
+		LDFLAGS="$(HOST_LDFLAGS)" \
+		all
+endef
+
+define Host/Install
+	install -m0755 $(HOST_BUILD_DIR)/genext2fs $(STAGING_DIR_HOST)/bin/
+endef
+
+define Host/Clean
+	rm -f $(STAGING_DIR_HOST)/bin/genext2fs
+endef
+
+$(eval $(call HostBuild))
diff --git a/tools/genext2fs/patches/100-c99_scanf.patch b/tools/genext2fs/patches/100-c99_scanf.patch
new file mode 100644
index 0000000..e7aa17c
--- /dev/null
+++ b/tools/genext2fs/patches/100-c99_scanf.patch
@@ -0,0 +1,21 @@
+commit 3b8ca0ce9a0b58287a780747c90c449bdebfe464
+Author: Xavier Bestel <bestouff at users.sourceforge.net>
+Date:   Mon Jan 14 08:52:44 2008 +0000
+
+    removed use of %as is scanf (GNU conflicts with C99) by Giacomo Catenazzi <cate at debian.org>
+
+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 0000000..b3317bd
--- /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 0000000..97a4836
--- /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;grp<nbgroups && !bk;grp++)
+-			bk=allocate(get_blk(fs,fs->gd[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; grp<nbgroups; grp++) {
+-		if (fs->gd[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;i<GRP_NBGROUPS(fs);i++)
+-		swap_gd(&(fs->gd[i]));
++		swap_gd(get_gd(fs, i));
+ 	swap_sb(&fs->sb);
+ }
+ 
+@@ -1870,7 +1885,7 @@
+ 	uint32 i;
+ 	swap_sb(&fs->sb);
+ 	for(i=0;i<GRP_NBGROUPS(fs);i++)
+-		swap_gd(&(fs->gd[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<nbgroups;
+ 		i++, bbmpos+=nbblocks_per_group, ibmpos+=nbblocks_per_group, itblpos+=nbblocks_per_group)
+ 	{
++		groupdescriptor *gd = get_gd(fs, i);
++
+ 		if(free_blocks > 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; i<nbgroups;i++) {
+ 
+ 		/* Block bitmap */
+-		bbm = get_blk(fs,fs->gd[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 <image>\n"
+ 	"  -d, --root <directory>\n"
+ 	"  -D, --devtable <file>\n"
++	"  -B, --block-size <bytes>\n"
+ 	"  -b, --size-in-blocks <blocks>\n"
+ 	"  -i, --bytes-per-inode <bytes per inode>\n"
+ 	"  -N, --number-of-inodes <number of inodes>\n"
+ 	"  -m, --reserved-percentage <percentage of blocks to reserve>\n"
++	"  -o, --creator-os <os>      'linux', 'hurd', 'freebsd' or a numerical value.\n"
+ 	"  -g, --block-map <path>     Generate a block map file for this path.\n"
+ 	"  -e, --fill-value <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 <os>
++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 0000000..7b3c00b
--- /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;



More information about the lede-commits mailing list