Module Name:    src
Committed By:   bouyer
Date:           Sun Jan 16 12:38:28 UTC 2011

Modified Files:
        src/sbin/fsck_ext2fs [netbsd-5]: inode.c setup.c
        src/sbin/newfs_ext2fs [netbsd-5]: mke2fs.c newfs_ext2fs.8
            newfs_ext2fs.c
        src/sys/lib/libsa [netbsd-5]: ext2fs.c
        src/sys/ufs/ext2fs [netbsd-5]: ext2fs_dinode.h ext2fs_inode.c
            ext2fs_vfsops.c

Log Message:
Pull up following revision(s) (requested by tsutsui in ticket #1486):
        sbin/fsck_ext2fs/setup.c: revision 1.26
        sbin/newfs_ext2fs/mke2fs.c: revision 1.10
        sbin/newfs_ext2fs/mke2fs.c: revision 1.11
        sbin/newfs_ext2fs/mke2fs.c: revision 1.12
        sbin/fsck_ext2fs/inode.c: revision 1.24
        sys/lib/libsa/ext2fs.c: revision 1.6
        sbin/newfs_ext2fs/extern.h: revision 1.3
        sbin/fsck_ext2fs/inode.c: revision 1.25
        sys/lib/libsa/ext2fs.c: revision 1.7
        sbin/fsck_ext2fs/inode.c: revision 1.26
        sys/ufs/ext2fs/ext2fs_inode.c: revision 1.68
        sbin/fsck_ext2fs/inode.c: revision 1.27
        sbin/fsck_ext2fs/inode.c: revision 1.28
        sys/ufs/ext2fs/ext2fs_dinode.h: revision 1.18
        sys/ufs/ext2fs/ext2fs_dinode.h: revision 1.19
        sbin/newfs_ext2fs/newfs_ext2fs.c: revision 1.5
        sbin/newfs_ext2fs/newfs_ext2fs.8: revision 1.2
        sbin/newfs_ext2fs/newfs_ext2fs.c: revision 1.6
        sbin/newfs_ext2fs/newfs_ext2fs.8: revision 1.3
        sys/ufs/ext2fs/ext2fs_vfsops.c: revision 1.142
        sbin/newfs_ext2fs/newfs_ext2fs.c: revision 1.7
        sbin/newfs_ext2fs/newfs_ext2fs.8: revision 1.4
        sbin/newfs_ext2fs/newfs_ext2fs.c: revision 1.8
PR/40936: Frederik Sausmikat: ext2fs: add support for inodes > 128 bytes
Support variable inode sizes.
catch up with variable inode size.
Don't use e2fs_inode_size in superblock on E2FS_REV0 file system.
- accept only EXT2_REV0_DINODE_SIZE inodesize on -O 0
- use inodesize to get offset of inode, not struct ext2fs_dinode array
Replace a magic number with a new EXT2_REV0_DINODE_SIZE macro.
Use EXT2_DINODE_SIZE() to get offset of inode, not struct ext2fs_dinode array.
Fix botched logic in inodesize check.
Use inodesize to get offset of inode in one more place.
- add a sanity check for e2fs_inode_size in readsb()
- use EXT2_DINODE_SIZE() rather than sizeof(struct ext2fs_dinode) or
  struct ext2fs_dinode array/pointer to see e2fs_ipb and inode offsets
Sort options.
New sentence, new line.
Sort options in usage.
- unsigned -> unsigned int
- remove unnecessary casts from malloc(3) and free(3)
- fix a bogus indent
Use "size > INT32_MAX" rather than "size >= 0x80000000U" to check 2GB limit.
Add missed byteswap ops against ext2fs_dinode members.
Handle 32 bit uid field on E2FS_REV1.


To generate a diff of this commit:
cvs rdiff -u -r1.23 -r1.23.2.1 src/sbin/fsck_ext2fs/inode.c
cvs rdiff -u -r1.25 -r1.25.6.1 src/sbin/fsck_ext2fs/setup.c
cvs rdiff -u -r1.9 -r1.9.2.1 src/sbin/newfs_ext2fs/mke2fs.c
cvs rdiff -u -r1.1 -r1.1.16.1 src/sbin/newfs_ext2fs/newfs_ext2fs.8
cvs rdiff -u -r1.4 -r1.4.2.1 src/sbin/newfs_ext2fs/newfs_ext2fs.c
cvs rdiff -u -r1.4 -r1.4.36.1 src/sys/lib/libsa/ext2fs.c
cvs rdiff -u -r1.16.28.1 -r1.16.28.2 src/sys/ufs/ext2fs/ext2fs_dinode.h
cvs rdiff -u -r1.66.8.1 -r1.66.8.2 src/sys/ufs/ext2fs/ext2fs_inode.c
cvs rdiff -u -r1.137.6.5 -r1.137.6.6 src/sys/ufs/ext2fs/ext2fs_vfsops.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sbin/fsck_ext2fs/inode.c
diff -u src/sbin/fsck_ext2fs/inode.c:1.23 src/sbin/fsck_ext2fs/inode.c:1.23.2.1
--- src/sbin/fsck_ext2fs/inode.c:1.23	Thu Oct  9 16:56:23 2008
+++ src/sbin/fsck_ext2fs/inode.c	Sun Jan 16 12:38:27 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: inode.c,v 1.23 2008/10/09 16:56:23 christos Exp $	*/
+/*	$NetBSD: inode.c,v 1.23.2.1 2011/01/16 12:38:27 bouyer Exp $	*/
 
 /*
  * Copyright (c) 1980, 1986, 1993
@@ -63,7 +63,7 @@
 #if 0
 static char sccsid[] = "@(#)inode.c	8.5 (Berkeley) 2/8/95";
 #else
-__RCSID("$NetBSD: inode.c,v 1.23 2008/10/09 16:56:23 christos Exp $");
+__RCSID("$NetBSD: inode.c,v 1.23.2.1 2011/01/16 12:38:27 bouyer Exp $");
 #endif
 #endif /* not lint */
 
@@ -127,7 +127,7 @@
 
 	if ((fs2h16(dp->e2di_mode) & IFMT) == IFREG)
 		size |= (u_int64_t)fs2h32(dp->e2di_dacl) << 32;
-	if (size >= 0x80000000U)
+	if (size > INT32_MAX)
 		(void)setlarge();
 	return size;
 }
@@ -137,10 +137,10 @@
 {
 	if ((fs2h16(dp->e2di_mode) & IFMT) == IFREG) {
 		dp->e2di_dacl = h2fs32(size >> 32);
-		if (size >= 0x80000000U)
+		if (size > INT32_MAX)
 			if (!setlarge())
 				return;
-	} else if (size >= 0x80000000U) {
+	} else if (size > INT32_MAX) {
 		pfatal("TRYING TO SET FILESIZE TO %llu ON MODE %x FILE\n",
 		    (unsigned long long)size, fs2h16(dp->e2di_mode) & IFMT);
 		return;
@@ -169,7 +169,7 @@
 	dino = *dp;
 	ndb = howmany(inosize(&dino), sblock.e2fs_bsize);
 	for (ap = &dino.e2di_blocks[0]; ap < &dino.e2di_blocks[NDADDR];
-																ap++,ndb--) {
+	    ap++,ndb--) {
 		idesc->id_numfrags = 1;
 		if (*ap == 0) {
 			if (idesc->id_type == DATA && ndb > 0) {
@@ -325,7 +325,7 @@
 {
 	int c, overh;
 
-	if ((unsigned)(blk + cnt) > maxfsblock)
+	if ((unsigned int)(blk + cnt) > maxfsblock)
 		return (1);
 	c = dtog(&sblock, blk);
 	overh = cgoverhead(c);
@@ -371,6 +371,7 @@
 ginode(ino_t inumber)
 {
 	daddr_t iblk;
+	struct ext2fs_dinode *dp;
 
 	if ((inumber < EXT2_FIRSTINO &&
 	     inumber != EXT2_ROOTINO &&
@@ -385,9 +386,13 @@
 		if (pbp != 0)
 			pbp->b_flags &= ~B_INUSE;
 		pbp = getdatablk(iblk, sblock.e2fs_bsize);
-		startinum = ((inumber -1) / sblock.e2fs_ipb) * sblock.e2fs_ipb + 1;
+		startinum =
+		    ((inumber - 1) / sblock.e2fs_ipb) * sblock.e2fs_ipb + 1;
 	}
-	return (&pbp->b_un.b_dinode[(inumber-1) % sblock.e2fs_ipb]);
+	dp = (struct ext2fs_dinode *)(pbp->b_un.b_buf +
+	    EXT2_DINODE_SIZE(&sblock) * ino_to_fsbo(&sblock, inumber));
+
+	return dp;
 }
 
 /*
@@ -396,14 +401,15 @@
  */
 ino_t nextino, lastinum;
 long readcnt, readpercg, fullcnt, inobufsize, partialcnt, partialsize;
-struct ext2fs_dinode *inodebuf;
+char *inodebuf;
 
 struct ext2fs_dinode *
 getnextinode(ino_t inumber)
 {
 	long size;
 	daddr_t dblk;
-	static struct ext2fs_dinode *dp;
+	struct ext2fs_dinode *dp;
+	static char *bp;
 
 	if (inumber != nextino++ || inumber > maxino)
 		errexit("bad inode number %llu to nextinode",
@@ -418,10 +424,13 @@
 			size = inobufsize;
 			lastinum += fullcnt;
 		}
-		(void)bread(fsreadfd, (char *)inodebuf, dblk, size);
-		dp = inodebuf;
+		(void)bread(fsreadfd, inodebuf, dblk, size);
+		bp = inodebuf;
 	}
-	return (dp++);
+	dp = (struct ext2fs_dinode *)bp;
+	bp += EXT2_DINODE_SIZE(&sblock);
+
+	return dp;
 }
 
 void
@@ -433,10 +442,10 @@
 	lastinum = 1;
 	readcnt = 0;
 	inobufsize = blkroundup(&sblock, INOBUFSIZE);
-	fullcnt = inobufsize / sizeof(struct ext2fs_dinode);
+	fullcnt = inobufsize / EXT2_DINODE_SIZE(&sblock);
 	readpercg = sblock.e2fs.e2fs_ipg / fullcnt;
 	partialcnt = sblock.e2fs.e2fs_ipg % fullcnt;
-	partialsize = partialcnt * sizeof(struct ext2fs_dinode);
+	partialsize = partialcnt * EXT2_DINODE_SIZE(&sblock);
 	if (partialcnt != 0) {
 		readpercg++;
 	} else {
@@ -444,8 +453,7 @@
 		partialsize = inobufsize;
 	}
 	if (inodebuf == NULL &&
-	    (inodebuf = (struct ext2fs_dinode *)malloc((unsigned)inobufsize)) ==
-		NULL)
+	    (inodebuf = malloc((unsigned int)inobufsize)) == NULL)
 		errexit("Cannot allocate space for inode buffer");
 	while (nextino < EXT2_ROOTINO)
 		(void)getnextinode(nextino);
@@ -456,7 +464,7 @@
 {
 
 	if (inodebuf != NULL)
-		free((char *)inodebuf);
+		free(inodebuf);
 	inodebuf = NULL;
 }
 
@@ -478,8 +486,7 @@
 	if (blks > NDADDR)
 		blks = NDADDR + NIADDR;
 	/* XXX ondisk32 */
-	inp = (struct inoinfo *)
-		malloc(sizeof(*inp) + (blks - 1) * sizeof(int32_t));
+	inp = malloc(sizeof(*inp) + (blks - 1) * sizeof(int32_t));
 	if (inp == NULL)
 		return;
 	inpp = &inphead[inumber % numdirs];
@@ -499,7 +506,7 @@
 	if (inplast == listmax) {
 		listmax += 100;
 		inpsort = (struct inoinfo **)realloc((char *)inpsort,
-		    (unsigned)listmax * sizeof(struct inoinfo *));
+		    (unsigned int)listmax * sizeof(struct inoinfo *));
 		if (inpsort == NULL)
 			errexit("cannot increase directory list");
 	}
@@ -534,9 +541,9 @@
 	if (inphead == NULL)
 		return;
 	for (inpp = &inpsort[inplast - 1]; inpp >= inpsort; inpp--)
-		free((char *)(*inpp));
-	free((char *)inphead);
-	free((char *)inpsort);
+		free(*inpp);
+	free(inphead);
+	free(inpsort);
 	inphead = inpsort = NULL;
 }
 	
@@ -555,7 +562,7 @@
 	dp = ginode(idesc->id_number);
 	if (flag == 1) {
 		pwarn("%s %s", type,
-		    (dp->e2di_mode & IFMT) == IFDIR ? "DIR" : "FILE");
+		    (fs2h16(dp->e2di_mode) & IFMT) == IFDIR ? "DIR" : "FILE");
 		pinode(idesc->id_number);
 	}
 	if (preen || reply("CLEAR") == 1) {
@@ -612,18 +619,22 @@
 	char *p;
 	struct passwd *pw;
 	time_t t;
+	uid_t uid;
 
 	printf(" I=%llu ", (unsigned long long)ino);
 	if ((ino < EXT2_FIRSTINO && ino != EXT2_ROOTINO) || ino > maxino)
 		return;
 	dp = ginode(ino);
+	uid = fs2h16(dp->e2di_uid);
+	if (sblock.e2fs.e2fs_rev > E2FS_REV0)
+		uid |= fs2h16(dp->e2di_uid_high) << 16;
 	printf(" OWNER=");
 #ifndef SMALL
-	if (Uflag && (pw = getpwuid((int)dp->e2di_uid)) != 0)
+	if (Uflag && (pw = getpwuid(uid)) != 0)
 		printf("%s ", pw->pw_name);
 	else
 #endif
-		printf("%u ", (unsigned)fs2h16(dp->e2di_uid));
+		printf("%u ", (unsigned int)uid);
 	printf("MODE=%o\n", fs2h16(dp->e2di_mode));
 	if (preen)
 		printf("%s: ", cdevname());

Index: src/sbin/fsck_ext2fs/setup.c
diff -u src/sbin/fsck_ext2fs/setup.c:1.25 src/sbin/fsck_ext2fs/setup.c:1.25.6.1
--- src/sbin/fsck_ext2fs/setup.c:1.25	Sun Mar 16 23:17:55 2008
+++ src/sbin/fsck_ext2fs/setup.c	Sun Jan 16 12:38:27 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: setup.c,v 1.25 2008/03/16 23:17:55 lukem Exp $	*/
+/*	$NetBSD: setup.c,v 1.25.6.1 2011/01/16 12:38:27 bouyer Exp $	*/
 
 /*
  * Copyright (c) 1980, 1986, 1993
@@ -63,7 +63,7 @@
 #if 0
 static char sccsid[] = "@(#)setup.c	8.5 (Berkeley) 11/23/94";
 #else
-__RCSID("$NetBSD: setup.c,v 1.25 2008/03/16 23:17:55 lukem Exp $");
+__RCSID("$NetBSD: setup.c,v 1.25.6.1 2011/01/16 12:38:27 bouyer Exp $");
 #endif
 #endif /* not lint */
 
@@ -309,6 +309,14 @@
 		badsb(listerr, "BAD LOG_BSIZE");
 		return 0;
 	}
+	if (sblock.e2fs.e2fs_rev > E2FS_REV0 &&
+	    (!powerof2(sblock.e2fs.e2fs_inode_size) ||
+	     sblock.e2fs.e2fs_inode_size < sizeof(struct ext2fs_dinode) ||
+	     sblock.e2fs.e2fs_inode_size >
+	      (1024 << sblock.e2fs.e2fs_log_bsize))) {
+		badsb(listerr, "BAD INODE_SIZE");
+		return 0;
+	}
 
 	/* compute the dynamic fields of the in-memory sb */
 	/* compute dynamic sb infos */
@@ -323,7 +331,7 @@
 	sblock.e2fs_bmask = ~sblock.e2fs_qbmask;
 	sblock.e2fs_ngdb = howmany(sblock.e2fs_ncg,
 	    sblock.e2fs_bsize / sizeof(struct ext2_gd));
-	sblock.e2fs_ipb = sblock.e2fs_bsize / sizeof(struct ext2fs_dinode);
+	sblock.e2fs_ipb = sblock.e2fs_bsize / EXT2_DINODE_SIZE(&sblock);
 	sblock.e2fs_itpg = howmany(sblock.e2fs.e2fs_ipg, sblock.e2fs_ipb);
 
 	/*

Index: src/sbin/newfs_ext2fs/mke2fs.c
diff -u src/sbin/newfs_ext2fs/mke2fs.c:1.9 src/sbin/newfs_ext2fs/mke2fs.c:1.9.2.1
--- src/sbin/newfs_ext2fs/mke2fs.c:1.9	Thu Aug 28 16:29:24 2008
+++ src/sbin/newfs_ext2fs/mke2fs.c	Sun Jan 16 12:38:27 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: mke2fs.c,v 1.9 2008/08/28 16:29:24 tsutsui Exp $	*/
+/*	$NetBSD: mke2fs.c,v 1.9.2.1 2011/01/16 12:38:27 bouyer Exp $	*/
 
 /*-
  * Copyright (c) 2007 Izumi Tsutsui.  All rights reserved.
@@ -106,7 +106,7 @@
 #if 0
 static char sccsid[] = "@(#)mkfs.c	8.11 (Berkeley) 5/3/95";
 #else
-__RCSID("$NetBSD: mke2fs.c,v 1.9 2008/08/28 16:29:24 tsutsui Exp $");
+__RCSID("$NetBSD: mke2fs.c,v 1.9.2.1 2011/01/16 12:38:27 bouyer Exp $");
 #endif
 #endif /* not lint */
 
@@ -243,6 +243,12 @@
 		    bsize, fsize);
 	}
 
+	/* variable inodesize is REV1 feature */
+	if (Oflag == 0 && inodesize != EXT2_REV0_DINODE_SIZE) {
+		errx(EXIT_FAILURE, "GOOD_OLD_REV file system format"
+		    " doesn't support %d byte inode\n", inodesize);
+	}
+
 	sblock.e2fs.e2fs_log_bsize = ilog2(bsize) - LOG_MINBSIZE;
 	/* Umm, why not e2fs_log_fsize? */
 	sblock.e2fs.e2fs_fsize = ilog2(fsize) - LOG_MINBSIZE;
@@ -252,7 +258,7 @@
 	sblock.e2fs_qbmask = sblock.e2fs_bsize - 1;
 	sblock.e2fs_bmask = ~sblock.e2fs_qbmask;
 	sblock.e2fs_fsbtodb = ilog2(sblock.e2fs_bsize) - ilog2(sectorsize);
-	sblock.e2fs_ipb = sblock.e2fs_bsize / EXT2_DINODE_SIZE;
+	sblock.e2fs_ipb = sblock.e2fs_bsize / inodesize;
 
 	/*
 	 * Ext2fs preserves BBSIZE (1024 bytes) space at the top for
@@ -301,7 +307,7 @@
 		num_inodes = UINT16_MAX * ncg;	/* ext2bgd_nifree is uint16_t */
 
 	inodes_per_cg = num_inodes / ncg;
-	iblocks_per_cg = howmany(EXT2_DINODE_SIZE * inodes_per_cg, bsize);
+	iblocks_per_cg = howmany(inodesize * inodes_per_cg, bsize);
 
 	/* Check that the last cylinder group has enough space for inodes */
 	minblocks_per_cg =
@@ -404,7 +410,7 @@
 	sblock.e2fs.e2fs_rgid = getegid();
 
 	sblock.e2fs.e2fs_first_ino = EXT2_FIRSTINO;
-	sblock.e2fs.e2fs_inode_size = EXT2_DINODE_SIZE;
+	sblock.e2fs.e2fs_inode_size = inodesize;
 
 	/* e2fs_block_group_nr is set on writing superblock to each group */
 
@@ -754,11 +760,11 @@
 	 *       to override these generated numbers.
 	 */
 	memset(buf, 0, sblock.e2fs_bsize);
-	dp = (struct ext2fs_dinode *)buf;
 	for (i = 0; i < sblock.e2fs_itpg; i++) {
 		for (j = 0; j < sblock.e2fs_ipb; j++) {
+			dp = (struct ext2fs_dinode *)(buf + inodesize * j);
 			/* h2fs32() just for consistency */
-			dp[j].e2di_gen = h2fs32(arc4random());
+			dp->e2di_gen = h2fs32(arc4random());
 		}
 		wtfs(fsbtodb(&sblock, gd[cylno].ext2bgd_i_tables + i),
 		    sblock.e2fs_bsize, buf);
@@ -1352,8 +1358,8 @@
 	d = fsbtodb(&sblock, ino_to_fsba(&sblock, ino));
 	rdfs(d, sblock.e2fs_bsize, bp);
 
-	dp = (struct ext2fs_dinode *)bp;
-	dp += ino_to_fsbo(&sblock, ino);
+	dp = (struct ext2fs_dinode *)(bp +
+	    inodesize * ino_to_fsbo(&sblock, ino));
 	e2fs_isave(ip, dp);
 	/* e2fs_i_bswap() doesn't swap e2di_blocks addrs */
 	if ((ip->e2di_mode & EXT2_IFMT) != EXT2_IFLNK) {

Index: src/sbin/newfs_ext2fs/newfs_ext2fs.8
diff -u src/sbin/newfs_ext2fs/newfs_ext2fs.8:1.1 src/sbin/newfs_ext2fs/newfs_ext2fs.8:1.1.16.1
--- src/sbin/newfs_ext2fs/newfs_ext2fs.8:1.1	Sat Nov 17 16:50:26 2007
+++ src/sbin/newfs_ext2fs/newfs_ext2fs.8	Sun Jan 16 12:38:27 2011
@@ -1,4 +1,4 @@
-.\"	$NetBSD: newfs_ext2fs.8,v 1.1 2007/11/17 16:50:26 tsutsui Exp $
+.\"	$NetBSD: newfs_ext2fs.8,v 1.1.16.1 2011/01/16 12:38:27 bouyer Exp $
 .\"
 .\" Copyright (c) 1983, 1987, 1991, 1993, 1994
 .\"	The Regents of the University of California.  All rights reserved.
@@ -29,7 +29,7 @@
 .\"
 .\"     @(#)newfs.8	8.6 (Berkeley) 5/3/95
 .\"
-.Dd November 17, 2007
+.Dd March 1, 2009
 .Dt NEWFS_EXT2FS 8
 .Os
 .Sh NAME
@@ -39,6 +39,7 @@
 .Nm
 .Op Fl FINZ
 .Op Fl b Ar block-size
+.Op Fl D Ar inodesize
 .Op Fl f Ar frag-size
 .Op Fl i Ar bytes-per-inode
 .Op Fl m Ar free-space
@@ -93,6 +94,10 @@
 .It \*[Gt] 512 MB
 4 KB
 .El
+.It Fl D
+Set the inode size.
+Defaults to 128, and can also be set to 256 for
+compatibility with ext4.
 .It Fl F
 Create a file system image in
 .Ar special .
@@ -134,7 +139,8 @@
 .It 0
 .Ql GOOD_OLD_REV ;
 This option is primarily used to build root file systems that can be
-understood by old or dumb firmwares for bootstrap. (default)
+understood by old or dumb firmwares for bootstrap.
+(default)
 .It 1
 .Ql DYNAMIC_REV ;
 Various extended (and sometimes incompatible) features are enabled

Index: src/sbin/newfs_ext2fs/newfs_ext2fs.c
diff -u src/sbin/newfs_ext2fs/newfs_ext2fs.c:1.4 src/sbin/newfs_ext2fs/newfs_ext2fs.c:1.4.2.1
--- src/sbin/newfs_ext2fs/newfs_ext2fs.c:1.4	Sun Jul 20 01:20:23 2008
+++ src/sbin/newfs_ext2fs/newfs_ext2fs.c	Sun Jan 16 12:38:27 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: newfs_ext2fs.c,v 1.4 2008/07/20 01:20:23 lukem Exp $	*/
+/*	$NetBSD: newfs_ext2fs.c,v 1.4.2.1 2011/01/16 12:38:27 bouyer Exp $	*/
 
 /*
  * Copyright (c) 1983, 1989, 1993, 1994
@@ -39,7 +39,7 @@
 #if 0
 static char sccsid[] = "@(#)newfs.c	8.13 (Berkeley) 5/1/95";
 #else
-__RCSID("$NetBSD: newfs_ext2fs.c,v 1.4 2008/07/20 01:20:23 lukem Exp $");
+__RCSID("$NetBSD: newfs_ext2fs.c,v 1.4.2.1 2011/01/16 12:38:27 bouyer Exp $");
 #endif
 #endif /* not lint */
 
@@ -54,6 +54,7 @@
 #include <sys/mount.h>
 
 #include <ufs/ext2fs/ext2fs.h>
+#include <ufs/ext2fs/ext2fs_dinode.h>
 
 #include <disktab.h>
 #include <err.h>
@@ -104,6 +105,7 @@
 #define DEFAULT_VERBOSITY 3	/* 4 is traditional behavior of newfs(8) */
 int64_t fssize;			/* file system size */
 uint	sectorsize;		/* bytes/sector */
+uint16_t inodesize = EXT2_REV0_DINODE_SIZE;	/* inode size */
 uint	fsize = 0;		/* fragment size */
 uint	bsize = 0;		/* block size */
 uint	minfree = MINFREE;	/* free space threshold */
@@ -133,10 +135,16 @@
 	fsi = fso = -1;
 	Fflag = Iflag = Zflag = 0;
 	verbosity = -1;
-	opstring = "FINO:S:V:Zb:f:i:l:m:n:s:v:";
+	opstring = "D:FINO:S:V:Zb:f:i:l:m:n:s:v:";
 	byte_sized = 0;
 	while ((ch = getopt(argc, argv, opstring)) != -1)
 		switch (ch) {
+		case 'D':
+			inodesize = (uint16_t)strtol(optarg, &s1, 0);
+			if (*s1 || (inodesize != 128 && inodesize != 256))
+				errx(1, "Bad inode size %d "
+				    "(only 128 and 256 supported)", inodesize);
+			break;
 		case 'F':
 			Fflag = 1;
 			break;
@@ -449,20 +457,21 @@
 }
 
 static const char help_strings[] =
-	"\t-F \t\tcreate file system image in regular file\n"
-	"\t-I \t\tdo not check that the file system type is `Linux Ext2'\n"
-	"\t-N \t\tdo not create file system, just print out parameters\n"
-	"\t-O N\t\tfilesystem revision: 0 ==> REV0, 1 ==> REV1 (default 0)\n"
-	"\t-S secsize\tsector size\n"
-	"\t-V verbose\toutput verbosity: 0 ==> none, 4 ==> max\n"
-	"\t-Z \t\tpre-zero the image file\n"
 	"\t-b bsize\tblock size\n"
+	"\t-D inodesize\tsize of an inode in bytes (128 or 256)\n"
+	"\t-F \t\tcreate file system image in regular file\n"
 	"\t-f fsize\tfragment size\n"
+	"\t-I \t\tdo not check that the file system type is `Linux Ext2'\n"
 	"\t-i density\tnumber of bytes per inode\n"
 	"\t-m minfree\tminimum free space %\n"
+	"\t-N \t\tdo not create file system, just print out parameters\n"
 	"\t-n inodes\tnumber of inodes (overrides -i density)\n"
+	"\t-O N\t\tfilesystem revision: 0 ==> REV0, 1 ==> REV1 (default 0)\n"
+	"\t-S secsize\tsector size\n"
 	"\t-s fssize\tfile system size (sectors)\n"
-	"\t-v volname\text2fs volume name\n";
+	"\t-V verbose\toutput verbosity: 0 ==> none, 4 ==> max\n"
+	"\t-v volname\text2fs volume name\n"
+	"\t-Z \t\tpre-zero the image file\n";
 
 static void
 usage(void)

Index: src/sys/lib/libsa/ext2fs.c
diff -u src/sys/lib/libsa/ext2fs.c:1.4 src/sys/lib/libsa/ext2fs.c:1.4.36.1
--- src/sys/lib/libsa/ext2fs.c:1.4	Sun Dec  2 06:47:43 2007
+++ src/sys/lib/libsa/ext2fs.c	Sun Jan 16 12:38:27 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: ext2fs.c,v 1.4 2007/12/02 06:47:43 tsutsui Exp $	*/
+/*	$NetBSD: ext2fs.c,v 1.4.36.1 2011/01/16 12:38:27 bouyer Exp $	*/
 
 /*
  * Copyright (c) 1997 Manuel Bouyer.
@@ -189,8 +189,9 @@
 	if (rsize != fs->e2fs_bsize)
 		return EIO;
 
-	dip = (struct ext2fs_dinode *)buf;
-	e2fs_iload(&dip[ino_to_fsbo(fs, inumber)], &fp->f_di);
+	dip = (struct ext2fs_dinode *)(buf +
+	    EXT2_DINODE_SIZE(fs) * ino_to_fsbo(fs, inumber));
+	e2fs_iload(dip, &fp->f_di);
 
 	/*
 	 * Clear out the old buffers
@@ -431,7 +432,7 @@
 	if (ext2fs.e2fs_rev > E2FS_REV1 ||
 	    (ext2fs.e2fs_rev == E2FS_REV1 &&
 	     (ext2fs.e2fs_first_ino != EXT2_FIRSTINO ||
-	      ext2fs.e2fs_inode_size != EXT2_DINODE_SIZE ||
+	     (ext2fs.e2fs_inode_size != 128 && ext2fs.e2fs_inode_size != 256) ||
 	      ext2fs.e2fs_features_incompat & ~EXT2F_INCOMPAT_SUPP))) {
 		return ENODEV;
 	}
@@ -449,7 +450,7 @@
 	fs->e2fs_bmask = ~fs->e2fs_qbmask;
 	fs->e2fs_ngdb =
 	    howmany(fs->e2fs_ncg, fs->e2fs_bsize / sizeof(struct ext2_gd));
-	fs->e2fs_ipb = fs->e2fs_bsize / EXT2_DINODE_SIZE;
+	fs->e2fs_ipb = fs->e2fs_bsize / ext2fs.e2fs_inode_size;
 	fs->e2fs_itpg = fs->e2fs.e2fs_ipg / fs->e2fs_ipb;
 
 	return 0;

Index: src/sys/ufs/ext2fs/ext2fs_dinode.h
diff -u src/sys/ufs/ext2fs/ext2fs_dinode.h:1.16.28.1 src/sys/ufs/ext2fs/ext2fs_dinode.h:1.16.28.2
--- src/sys/ufs/ext2fs/ext2fs_dinode.h:1.16.28.1	Sat Nov 29 23:10:18 2008
+++ src/sys/ufs/ext2fs/ext2fs_dinode.h	Sun Jan 16 12:38:28 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: ext2fs_dinode.h,v 1.16.28.1 2008/11/29 23:10:18 snj Exp $	*/
+/*	$NetBSD: ext2fs_dinode.h,v 1.16.28.2 2011/01/16 12:38:28 bouyer Exp $	*/
 
 /*
  * Copyright (c) 1982, 1989, 1993
@@ -154,7 +154,10 @@
 #define EXT2_NODUMP		0x00000040	/* do not dump file */
 
 /* Size of on-disk inode. */
-#define	EXT2_DINODE_SIZE	(sizeof(struct ext2fs_dinode))	/* 128 */
+#define EXT2_REV0_DINODE_SIZE	sizeof(struct ext2fs_dinode)
+#define EXT2_DINODE_SIZE(fs)	((fs)->e2fs.e2fs_rev > E2FS_REV0 ?	\
+				    (fs)->e2fs.e2fs_inode_size :	\
+				    EXT2_REV0_DINODE_SIZE)
 
 /*
  * The e2di_blocks fields may be overlaid with other information for

Index: src/sys/ufs/ext2fs/ext2fs_inode.c
diff -u src/sys/ufs/ext2fs/ext2fs_inode.c:1.66.8.1 src/sys/ufs/ext2fs/ext2fs_inode.c:1.66.8.2
--- src/sys/ufs/ext2fs/ext2fs_inode.c:1.66.8.1	Mon Feb 22 04:43:46 2010
+++ src/sys/ufs/ext2fs/ext2fs_inode.c	Sun Jan 16 12:38:27 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: ext2fs_inode.c,v 1.66.8.1 2010/02/22 04:43:46 snj Exp $	*/
+/*	$NetBSD: ext2fs_inode.c,v 1.66.8.2 2011/01/16 12:38:27 bouyer Exp $	*/
 
 /*
  * Copyright (c) 1982, 1986, 1989, 1993
@@ -65,7 +65,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ext2fs_inode.c,v 1.66.8.1 2010/02/22 04:43:46 snj Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ext2fs_inode.c,v 1.66.8.2 2011/01/16 12:38:27 bouyer Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -221,7 +221,7 @@
 	}
 	ip->i_flag &= ~(IN_MODIFIED | IN_ACCESSED);
 	cp = (char *)bp->b_data +
-	    (ino_to_fsbo(fs, ip->i_number) * EXT2_DINODE_SIZE);
+	    (ino_to_fsbo(fs, ip->i_number) * EXT2_DINODE_SIZE(fs));
 	e2fs_isave(ip->i_din.e2fs_din, (struct ext2fs_dinode *)cp);
 	if ((updflags & (UPDATE_WAIT|UPDATE_DIROP)) != 0 &&
 	    (flags & IN_MODIFIED) != 0 &&

Index: src/sys/ufs/ext2fs/ext2fs_vfsops.c
diff -u src/sys/ufs/ext2fs/ext2fs_vfsops.c:1.137.6.5 src/sys/ufs/ext2fs/ext2fs_vfsops.c:1.137.6.6
--- src/sys/ufs/ext2fs/ext2fs_vfsops.c:1.137.6.5	Tue Oct 27 21:41:07 2009
+++ src/sys/ufs/ext2fs/ext2fs_vfsops.c	Sun Jan 16 12:38:28 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: ext2fs_vfsops.c,v 1.137.6.5 2009/10/27 21:41:07 bouyer Exp $	*/
+/*	$NetBSD: ext2fs_vfsops.c,v 1.137.6.6 2011/01/16 12:38:28 bouyer Exp $	*/
 
 /*
  * Copyright (c) 1989, 1991, 1993, 1994
@@ -65,7 +65,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ext2fs_vfsops.c,v 1.137.6.5 2009/10/27 21:41:07 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ext2fs_vfsops.c,v 1.137.6.6 2011/01/16 12:38:28 bouyer Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_compat_netbsd.h"
@@ -577,7 +577,7 @@
 	fs->e2fs_bmask = ~fs->e2fs_qbmask;
 	fs->e2fs_ngdb =
 	    howmany(fs->e2fs_ncg, fs->e2fs_bsize / sizeof(struct ext2_gd));
-	fs->e2fs_ipb = fs->e2fs_bsize / EXT2_DINODE_SIZE;
+	fs->e2fs_ipb = fs->e2fs_bsize / EXT2_DINODE_SIZE(fs);
 	fs->e2fs_itpg = fs->e2fs.e2fs_ipg / fs->e2fs_ipb;
 	brelse(bp, 0);
 
@@ -646,7 +646,7 @@
 			break;
 		}
 		cp = (char *)bp->b_data +
-		    (ino_to_fsbo(fs, ip->i_number) * EXT2_DINODE_SIZE);
+		    (ino_to_fsbo(fs, ip->i_number) * EXT2_DINODE_SIZE(fs));
 		e2fs_iload((struct ext2fs_dinode *)cp, ip->i_din.e2fs_din);
 		ext2fs_set_inode_guid(ip);
 		brelse(bp, 0);
@@ -696,8 +696,7 @@
 	ump = NULL;
 
 #ifdef DEBUG_EXT2
-	printf("sb size: %d ino size %d\n", sizeof(struct ext2fs),
-	    EXT2_DINODE_SIZE);
+	printf("ext2 sb size: %d\n", sizeof(struct ext2fs));
 #endif
 	error = bread(devvp, (SBOFF / size), SBSIZE, cred, 0, &bp);
 	if (error)
@@ -717,6 +716,10 @@
 	bp = NULL;
 	m_fs = ump->um_e2fs;
 	m_fs->e2fs_ronly = ronly;
+
+#ifdef DEBUG_EXT2
+	printf("ext2 ino size %d\n", EXT2_DINODE_SIZE(m_fs));
+#endif
 	if (ronly == 0) {
 		if (m_fs->e2fs.e2fs_state == E2FS_ISCLEAN)
 			m_fs->e2fs.e2fs_state = 0;
@@ -737,7 +740,7 @@
 	m_fs->e2fs_bmask = ~m_fs->e2fs_qbmask;
 	m_fs->e2fs_ngdb =
 	    howmany(m_fs->e2fs_ncg, m_fs->e2fs_bsize / sizeof(struct ext2_gd));
-	m_fs->e2fs_ipb = m_fs->e2fs_bsize / EXT2_DINODE_SIZE;
+	m_fs->e2fs_ipb = m_fs->e2fs_bsize / EXT2_DINODE_SIZE(m_fs);
 	m_fs->e2fs_itpg = m_fs->e2fs.e2fs_ipg / m_fs->e2fs_ipb;
 
 	m_fs->e2fs_gd = malloc(m_fs->e2fs_ngdb * m_fs->e2fs_bsize,
@@ -1078,7 +1081,7 @@
 		*vpp = NULL;
 		return (error);
 	}
-	cp = (char *)bp->b_data + (ino_to_fsbo(fs, ino) * EXT2_DINODE_SIZE);
+	cp = (char *)bp->b_data + (ino_to_fsbo(fs, ino) * EXT2_DINODE_SIZE(fs));
 	ip->i_din.e2fs_din = pool_get(&ext2fs_dinode_pool, PR_WAITOK);
 	e2fs_iload((struct ext2fs_dinode *)cp, ip->i_din.e2fs_din);
 	ext2fs_set_inode_guid(ip);
@@ -1260,9 +1263,8 @@
 		return (EINVAL);	   /* XXX needs translation */
 	}
 	if (fs2h32(fs->e2fs_rev) > E2FS_REV0) {
-		if (fs2h32(fs->e2fs_first_ino) != EXT2_FIRSTINO ||
-		    fs2h16(fs->e2fs_inode_size) != EXT2_DINODE_SIZE) {
-			printf("Ext2 fs: unsupported inode size\n");
+		if (fs2h32(fs->e2fs_first_ino) != EXT2_FIRSTINO) {
+			printf("Ext2 fs: unsupported first inode position\n");
 			return (EINVAL);      /* XXX needs translation */
 		}
 		if (fs2h32(fs->e2fs_features_incompat) &

Reply via email to