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) &