From owner-svn-src-stable@FreeBSD.ORG Tue Jul 26 14:41:55 2011 Return-Path: Delivered-To: svn-src-stable@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 17C00106566B; Tue, 26 Jul 2011 14:41:55 +0000 (UTC) (envelope-from marius@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 04C1E8FC1C; Tue, 26 Jul 2011 14:41:55 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id p6QEftV9013593; Tue, 26 Jul 2011 14:41:55 GMT (envelope-from marius@svn.freebsd.org) Received: (from marius@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id p6QEfsuF013575; Tue, 26 Jul 2011 14:41:54 GMT (envelope-from marius@svn.freebsd.org) Message-Id: <201107261441.p6QEfsuF013575@svn.freebsd.org> From: Marius Strobl Date: Tue, 26 Jul 2011 14:41:54 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-7@freebsd.org X-SVN-Group: stable-7 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r224448 - in stable/7/usr.sbin/makefs: . cd9660 compat ffs X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 26 Jul 2011 14:41:55 -0000 Author: marius Date: Tue Jul 26 14:41:54 2011 New Revision: 224448 URL: http://svn.freebsd.org/changeset/base/224448 Log: MFC: r214921, r219954, r219956, r221387, r221470, r221536, r222191 - Sync with the latest version from NetBSD. It notably addds ISO9660 support. - Add support for synthesizing an APM partition map to map Mac PowerPC bootstrap partitions from the ISO9660 boot catalog. This preserves OS X's ability to mount the CD, while allowing us a way to provide HFS-ified bootstrap code for Open Firmware. - Add analogs to the -chrp-boot and -prep-boot options to mkisofs. Added: stable/7/usr.sbin/makefs/cd9660/ - copied from r214921, head/usr.sbin/makefs/cd9660/ stable/7/usr.sbin/makefs/cd9660.c - copied, changed from r214921, head/usr.sbin/makefs/cd9660.c stable/7/usr.sbin/makefs/cd9660.h - copied, changed from r214921, head/usr.sbin/makefs/cd9660.h stable/7/usr.sbin/makefs/compat/Makefile.inc - copied unchanged from r214921, head/usr.sbin/makefs/compat/Makefile.inc stable/7/usr.sbin/makefs/ffs.h - copied unchanged from r214921, head/usr.sbin/makefs/ffs.h stable/7/usr.sbin/makefs/ffs/Makefile.inc - copied unchanged from r214921, head/usr.sbin/makefs/ffs/Makefile.inc Modified: stable/7/usr.sbin/makefs/Makefile stable/7/usr.sbin/makefs/cd9660/cd9660_eltorito.c stable/7/usr.sbin/makefs/cd9660/cd9660_strings.c stable/7/usr.sbin/makefs/ffs.c stable/7/usr.sbin/makefs/ffs/buf.c stable/7/usr.sbin/makefs/ffs/ffs_alloc.c stable/7/usr.sbin/makefs/ffs/mkfs.c stable/7/usr.sbin/makefs/makefs.8 stable/7/usr.sbin/makefs/makefs.c stable/7/usr.sbin/makefs/makefs.h stable/7/usr.sbin/makefs/walk.c Directory Properties: stable/7/usr.sbin/makefs/ (props changed) stable/7/usr.sbin/makefs/ffs/ffs_bswap.c (props changed) stable/7/usr.sbin/makefs/ffs/ffs_subr.c (props changed) stable/7/usr.sbin/makefs/ffs/ufs_bswap.h (props changed) stable/7/usr.sbin/makefs/getid.c (props changed) Modified: stable/7/usr.sbin/makefs/Makefile ============================================================================== --- stable/7/usr.sbin/makefs/Makefile Tue Jul 26 14:41:54 2011 (r224447) +++ stable/7/usr.sbin/makefs/Makefile Tue Jul 26 14:41:54 2011 (r224448) @@ -1,22 +1,23 @@ # $FreeBSD$ PROG= makefs + +CFLAGS+=-I${.CURDIR} + +SRCS= cd9660.c ffs.c \ + getid.c \ + makefs.c \ + walk.c MAN= makefs.8 WARNS?= 2 -CFLAGS+=-I${.CURDIR} -SRCS= ffs.c getid.c makefs.c walk.c +.include "${.CURDIR}/cd9660/Makefile.inc" +.include "${.CURDIR}/ffs/Makefile.inc" +.include "${.CURDIR}/compat/Makefile.inc" -.PATH: ${.CURDIR}/ffs -CFLAGS+=-I${.CURDIR}/ffs CFLAGS+=-DHAVE_STRUCT_STAT_ST_FLAGS=1 CFLAGS+=-DHAVE_STRUCT_STAT_ST_GEN=1 -SRCS+= buf.c ffs_alloc.c ffs_balloc.c ffs_bswap.c ffs_subr.c mkfs.c ufs_bmap.c - -.PATH: ${.CURDIR}/compat -CFLAGS+=-I${.CURDIR}/compat -SRCS+= pwcache.c strsuftoll.c .PATH: ${.CURDIR}/../mtree CFLAGS+=-I${.CURDIR}/../mtree Copied and modified: stable/7/usr.sbin/makefs/cd9660.c (from r214921, head/usr.sbin/makefs/cd9660.c) ============================================================================== --- head/usr.sbin/makefs/cd9660.c Sun Nov 7 16:05:04 2010 (r214921, copy source) +++ stable/7/usr.sbin/makefs/cd9660.c Tue Jul 26 14:41:54 2011 (r224448) @@ -207,6 +207,7 @@ cd9660_set_defaults(void) diskStructure.rr_moved_dir = 0; diskStructure.archimedes_enabled = 0; + diskStructure.chrp_boot = 0; diskStructure.include_padding_areas = 1; @@ -391,6 +392,8 @@ cd9660_parse_opts(const char *option, fs diskStructure.rock_ridge_enabled = 1; else if (CD9660_IS_COMMAND_ARG_DUAL(var, "A", "archimedes")) diskStructure.archimedes_enabled = 1; + else if (CD9660_IS_COMMAND_ARG(var, "chrp-boot")) + diskStructure.chrp_boot = 1; else if (CD9660_IS_COMMAND_ARG_DUAL(var, "K", "keep-bad-images")) diskStructure.keep_bad_images = 1; else if (CD9660_IS_COMMAND_ARG(var, "allow-deep-trees")) Copied and modified: stable/7/usr.sbin/makefs/cd9660.h (from r214921, head/usr.sbin/makefs/cd9660.h) ============================================================================== --- head/usr.sbin/makefs/cd9660.h Sun Nov 7 16:05:04 2010 (r214921, copy source) +++ stable/7/usr.sbin/makefs/cd9660.h Tue Jul 26 14:41:54 2011 (r224448) @@ -285,6 +285,7 @@ typedef struct _iso9660_disk { cd9660node *rr_moved_dir; int archimedes_enabled; + int chrp_boot; /* Spec breaking options */ u_char allow_deep_trees; Modified: stable/7/usr.sbin/makefs/cd9660/cd9660_eltorito.c ============================================================================== --- head/usr.sbin/makefs/cd9660/cd9660_eltorito.c Sun Nov 7 16:05:04 2010 (r214921) +++ stable/7/usr.sbin/makefs/cd9660/cd9660_eltorito.c Tue Jul 26 14:41:54 2011 (r224448) @@ -31,6 +31,9 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. */ + +#include + #include "cd9660.h" #include "cd9660_eltorito.h" @@ -497,11 +500,79 @@ cd9660_setup_boot_volume_descriptor(volu return 1; } +static int +cd9660_write_mbr_partition_entry(FILE *fd, int index, off_t sector_start, + off_t nsectors, int type) +{ + uint8_t val; + uint32_t lba; + + fseeko(fd, (off_t)(index) * 16 + 0x1be, SEEK_SET); + + val = 0x80; /* Bootable */ + fwrite(&val, sizeof(val), 1, fd); + + val = 0xff; /* CHS begin */ + fwrite(&val, sizeof(val), 1, fd); + fwrite(&val, sizeof(val), 1, fd); + fwrite(&val, sizeof(val), 1, fd); + + val = type; /* Part type */ + fwrite(&val, sizeof(val), 1, fd); + + val = 0xff; /* CHS end */ + fwrite(&val, sizeof(val), 1, fd); + fwrite(&val, sizeof(val), 1, fd); + fwrite(&val, sizeof(val), 1, fd); + + /* LBA extent */ + lba = htole32(sector_start); + fwrite(&lba, sizeof(lba), 1, fd); + lba = htole32(nsectors); + fwrite(&lba, sizeof(lba), 1, fd); + + return (0); +} + +static int +cd9660_write_apm_partition_entry(FILE *fd, int index, int total_partitions, + off_t sector_start, off_t nsectors, off_t sector_size, + const char *part_name, const char *part_type) +{ + uint32_t apm32; + uint16_t apm16; + + fseeko(fd, (off_t)(index + 1) * sector_size, SEEK_SET); + + /* Signature */ + apm16 = htobe16(0x504d); + fwrite(&apm16, sizeof(apm16), 1, fd); + apm16 = 0; + fwrite(&apm16, sizeof(apm16), 1, fd); + + /* Total number of partitions */ + apm32 = htobe32(total_partitions); + fwrite(&apm32, sizeof(apm32), 1, fd); + /* Bounds */ + apm32 = htobe32(sector_start); + fwrite(&apm32, sizeof(apm32), 1, fd); + apm32 = htobe32(nsectors); + fwrite(&apm32, sizeof(apm32), 1, fd); + + fwrite(part_name, strlen(part_name) + 1, 1, fd); + fseek(fd, 32 - strlen(part_name) - 1, SEEK_CUR); + fwrite(part_type, strlen(part_type) + 1, 1, fd); + + return 0; +} + int cd9660_write_boot(FILE *fd) { struct boot_catalog_entry *e; struct cd9660_boot_image *t; + int apm_partitions = 0; + int mbr_partitions = 0; /* write boot catalog */ if (fseeko(fd, (off_t)diskStructure.boot_catalog_sector * @@ -533,7 +604,88 @@ cd9660_write_boot(FILE *fd) t->filename, t->sector); } cd9660_copy_file(fd, t->sector, t->filename); + + if (t->system == ET_SYS_MAC) + apm_partitions++; + if (t->system == ET_SYS_PPC) + mbr_partitions++; + } + + /* some systems need partition tables as well */ + if (mbr_partitions > 0 || diskStructure.chrp_boot) { + uint16_t sig; + + fseek(fd, 0x1fe, SEEK_SET); + sig = htole16(0xaa55); + fwrite(&sig, sizeof(sig), 1, fd); + + mbr_partitions = 0; + + /* Write ISO9660 descriptor, enclosing the whole disk */ + if (diskStructure.chrp_boot) + cd9660_write_mbr_partition_entry(fd, mbr_partitions++, + 0, diskStructure.totalSectors * + (diskStructure.sectorSize / 512), 0x96); + + /* Write all partition entries */ + TAILQ_FOREACH(t, &diskStructure.boot_images, image_list) { + if (t->system != ET_SYS_PPC) + continue; + cd9660_write_mbr_partition_entry(fd, mbr_partitions++, + t->sector * (diskStructure.sectorSize / 512), + t->num_sectors * (diskStructure.sectorSize / 512), + 0x41 /* PReP Boot */); + } + } + + if (apm_partitions > 0) { + /* Write DDR and global APM info */ + uint32_t apm32; + uint16_t apm16; + int total_parts; + + fseek(fd, 0, SEEK_SET); + apm16 = htobe16(0x4552); + fwrite(&apm16, sizeof(apm16), 1, fd); + /* Device block size */ + apm16 = htobe16(512); + fwrite(&apm16, sizeof(apm16), 1, fd); + /* Device block count */ + apm32 = htobe32(diskStructure.totalSectors * + (diskStructure.sectorSize / 512)); + fwrite(&apm32, sizeof(apm32), 1, fd); + /* Device type/id */ + apm16 = htobe16(1); + fwrite(&apm16, sizeof(apm16), 1, fd); + fwrite(&apm16, sizeof(apm16), 1, fd); + + /* Count total needed entries */ + total_parts = 2 + apm_partitions; /* Self + ISO9660 */ + + /* Write self-descriptor */ + cd9660_write_apm_partition_entry(fd, 0, total_parts, 1, + total_parts, 512, "Apple", "Apple_partition_map"); + + /* Write ISO9660 descriptor, enclosing the whole disk */ + cd9660_write_apm_partition_entry(fd, 1, total_parts, 0, + diskStructure.totalSectors * + (diskStructure.sectorSize / 512), 512, "ISO9660", + "CD_ROM_Mode_1"); + + /* Write all partition entries */ + apm_partitions = 0; + TAILQ_FOREACH(t, &diskStructure.boot_images, image_list) { + if (t->system != ET_SYS_MAC) + continue; + + cd9660_write_apm_partition_entry(fd, + 2 + apm_partitions++, total_parts, + t->sector * (diskStructure.sectorSize / 512), + t->num_sectors * (diskStructure.sectorSize / 512), + 512, "CD Boot", "Apple_Bootstrap"); + } } return 0; } + Modified: stable/7/usr.sbin/makefs/cd9660/cd9660_strings.c ============================================================================== --- head/usr.sbin/makefs/cd9660/cd9660_strings.c Sun Nov 7 16:05:04 2010 (r214921) +++ stable/7/usr.sbin/makefs/cd9660/cd9660_strings.c Tue Jul 26 14:41:54 2011 (r224448) @@ -55,19 +55,19 @@ cd9660_uppercase_characters(char *str, i } static inline int -cd9660_is_a_char(char c) +cd9660_is_d_char(char c) { return (isupper((unsigned char)c) || c == '_' - || (c >= '0' && c <= '?')); + || (c >= '0' && c <= '9')); } static inline int -cd9660_is_d_char(char c) +cd9660_is_a_char(char c) { return (isupper((unsigned char)c) || c == '_' - || (c >= '%' && c <= '9') + || (c >= '%' && c <= '?') || (c >= ' ' && c <= '\"')); } Copied: stable/7/usr.sbin/makefs/compat/Makefile.inc (from r214921, head/usr.sbin/makefs/compat/Makefile.inc) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ stable/7/usr.sbin/makefs/compat/Makefile.inc Tue Jul 26 14:41:54 2011 (r224448, copy of r214921, head/usr.sbin/makefs/compat/Makefile.inc) @@ -0,0 +1,8 @@ +# $FreeBSD$ +# + +.PATH: ${.CURDIR}/compat + +CFLAGS+= -I${.CURDIR}/compat + +SRCS+= pwcache.c strsuftoll.c Modified: stable/7/usr.sbin/makefs/ffs.c ============================================================================== --- stable/7/usr.sbin/makefs/ffs.c Tue Jul 26 14:41:54 2011 (r224447) +++ stable/7/usr.sbin/makefs/ffs.c Tue Jul 26 14:41:54 2011 (r224448) @@ -1,4 +1,4 @@ -/* $NetBSD: ffs.c,v 1.30 2004/06/24 22:30:13 lukem Exp $ */ +/* $NetBSD: ffs.c,v 1.44 2009/04/28 22:49:26 joerg Exp $ */ /* * Copyright (c) 2001 Wasabi Systems, Inc. @@ -76,17 +76,24 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include #include #include "makefs.h" +#include "ffs.h" + +#if HAVE_STRUCT_STATVFS_F_IOSIZE && HAVE_FSTATVFS +#include +#endif #include #include #include + #include "ffs/ufs_bswap.h" #include "ffs/ufs_inode.h" #include "ffs/newfs_extern.h" @@ -94,7 +101,7 @@ __FBSDID("$FreeBSD$"); #undef DIP #define DIP(dp, field) \ - ((fsopts->version == 1) ? \ + ((ffs_opts->version == 1) ? \ (dp)->ffs1_din.di_##field : (dp)->ffs2_din.di_##field) /* @@ -139,39 +146,71 @@ int sectorsize; /* XXX: for buf.c::getb /* publically visible functions */ +void +ffs_prep_opts(fsinfo_t *fsopts) +{ + ffs_opt_t *ffs_opts; + + if ((ffs_opts = calloc(1, sizeof(ffs_opt_t))) == NULL) + err(1, "Allocating memory for ffs_options"); + + fsopts->fs_specific = ffs_opts; + + ffs_opts->bsize= -1; + ffs_opts->fsize= -1; + ffs_opts->cpg= -1; + ffs_opts->density= -1; + ffs_opts->minfree= -1; + ffs_opts->optimization= -1; + ffs_opts->maxcontig= -1; + ffs_opts->maxbpg= -1; + ffs_opts->avgfilesize= -1; + ffs_opts->avgfpdir= -1; + ffs_opts->version = 1; +} + +void +ffs_cleanup_opts(fsinfo_t *fsopts) +{ + if (fsopts->fs_specific) + free(fsopts->fs_specific); +} + int ffs_parse_opts(const char *option, fsinfo_t *fsopts) { + ffs_opt_t *ffs_opts = fsopts->fs_specific; + option_t ffs_options[] = { - { "bsize", &fsopts->bsize, 1, INT_MAX, + { "bsize", &ffs_opts->bsize, 1, INT_MAX, "block size" }, - { "fsize", &fsopts->fsize, 1, INT_MAX, + { "fsize", &ffs_opts->fsize, 1, INT_MAX, "fragment size" }, - { "density", &fsopts->density, 1, INT_MAX, + { "density", &ffs_opts->density, 1, INT_MAX, "bytes per inode" }, - { "minfree", &fsopts->minfree, 0, 99, + { "minfree", &ffs_opts->minfree, 0, 99, "minfree" }, - { "maxbpf", &fsopts->maxbpg, 1, INT_MAX, + { "maxbpf", &ffs_opts->maxbpg, 1, INT_MAX, "max blocks per file in a cg" }, - { "avgfilesize", &fsopts->avgfilesize, 1, INT_MAX, + { "avgfilesize", &ffs_opts->avgfilesize,1, INT_MAX, "expected average file size" }, - { "avgfpdir", &fsopts->avgfpdir, 1, INT_MAX, + { "avgfpdir", &ffs_opts->avgfpdir, 1, INT_MAX, "expected # of files per directory" }, - { "extent", &fsopts->maxbsize, 1, INT_MAX, + { "extent", &ffs_opts->maxbsize, 1, INT_MAX, "maximum # extent size" }, - { "maxbpcg", &fsopts->maxblkspercg, 1, INT_MAX, + { "maxbpcg", &ffs_opts->maxblkspercg,1, INT_MAX, "max # of blocks per group" }, - { "version", &fsopts->version, 1, 2, + { "version", &ffs_opts->version, 1, 2, "UFS version" }, - { NULL } + { .name = NULL } }; char *var, *val; int rv; - (void)&ffs_options; assert(option != NULL); assert(fsopts != NULL); + assert(ffs_opts != NULL); if (debug & DEBUG_FS_PARSE_OPTS) printf("ffs_parse_opts: got `%s'\n", option); @@ -188,9 +227,9 @@ ffs_parse_opts(const char *option, fsinf if (strcmp(var, "optimization") == 0) { if (strcmp(val, "time") == 0) { - fsopts->optimization = FS_OPTTIME; + ffs_opts->optimization = FS_OPTTIME; } else if (strcmp(val, "space") == 0) { - fsopts->optimization = FS_OPTSPACE; + ffs_opts->optimization = FS_OPTSPACE; } else { warnx("Invalid optimization `%s'", val); goto leave_ffs_parse_opts; @@ -277,11 +316,12 @@ ffs_validate(const char *dir, fsnode *ro #if notyet int32_t spc, nspf, ncyl, fssize; #endif - off_t size; + ffs_opt_t *ffs_opts = fsopts->fs_specific; assert(dir != NULL); assert(root != NULL); assert(fsopts != NULL); + assert(ffs_opts != NULL); if (debug & DEBUG_FS_VALIDATE) { printf("ffs_validate: before defaults set:\n"); @@ -291,31 +331,31 @@ ffs_validate(const char *dir, fsnode *ro /* set FFS defaults */ if (fsopts->sectorsize == -1) fsopts->sectorsize = DFL_SECSIZE; - if (fsopts->fsize == -1) - fsopts->fsize = MAX(DFL_FRAGSIZE, fsopts->sectorsize); - if (fsopts->bsize == -1) - fsopts->bsize = MIN(DFL_BLKSIZE, 8 * fsopts->fsize); - if (fsopts->cpg == -1) - fsopts->cpg = DFL_CYLSPERGROUP; + if (ffs_opts->fsize == -1) + ffs_opts->fsize = MAX(DFL_FRAGSIZE, fsopts->sectorsize); + if (ffs_opts->bsize == -1) + ffs_opts->bsize = MIN(DFL_BLKSIZE, 8 * ffs_opts->fsize); + if (ffs_opts->cpg == -1) + ffs_opts->cpg = DFL_CYLSPERGROUP; else - fsopts->cpgflg = 1; + ffs_opts->cpgflg = 1; /* fsopts->density is set below */ - if (fsopts->nsectors == -1) - fsopts->nsectors = DFL_NSECTORS; - if (fsopts->minfree == -1) - fsopts->minfree = MINFREE; - if (fsopts->optimization == -1) - fsopts->optimization = DEFAULTOPT; - if (fsopts->maxcontig == -1) - fsopts->maxcontig = - MAX(1, MIN(MAXPHYS, FFS_MAXBSIZE) / fsopts->bsize); + if (ffs_opts->nsectors == -1) + ffs_opts->nsectors = DFL_NSECTORS; + if (ffs_opts->minfree == -1) + ffs_opts->minfree = MINFREE; + if (ffs_opts->optimization == -1) + ffs_opts->optimization = DEFAULTOPT; + if (ffs_opts->maxcontig == -1) + ffs_opts->maxcontig = + MAX(1, MIN(MAXPHYS, FFS_MAXBSIZE) / ffs_opts->bsize); /* XXX ondisk32 */ - if (fsopts->maxbpg == -1) - fsopts->maxbpg = fsopts->bsize / sizeof(int32_t); - if (fsopts->avgfilesize == -1) - fsopts->avgfilesize = AVFILESIZ; - if (fsopts->avgfpdir == -1) - fsopts->avgfpdir = AFPDIR; + if (ffs_opts->maxbpg == -1) + ffs_opts->maxbpg = ffs_opts->bsize / sizeof(int32_t); + if (ffs_opts->avgfilesize == -1) + ffs_opts->avgfilesize = AVFILESIZ; + if (ffs_opts->avgfpdir == -1) + ffs_opts->avgfpdir = AFPDIR; /* calculate size of tree */ ffs_size_dir(root, fsopts); @@ -343,17 +383,19 @@ ffs_validate(const char *dir, fsnode *ro */ fsopts->size += (SBLOCK_UFS1 + SBLOCKSIZE) * ncg; /* add space needed to store inodes, x3 for blockmaps, etc */ - if (fsopts->version == 1) + if (ffs_opts->version == 1) fsopts->size += ncg * DINODE1_SIZE * - roundup(fsopts->inodes / ncg, fsopts->bsize / DINODE1_SIZE); + roundup(fsopts->inodes / ncg, + ffs_opts->bsize / DINODE1_SIZE); else fsopts->size += ncg * DINODE2_SIZE * - roundup(fsopts->inodes / ncg, fsopts->bsize / DINODE2_SIZE); + roundup(fsopts->inodes / ncg, + ffs_opts->bsize / DINODE2_SIZE); /* add minfree */ - if (fsopts->minfree > 0) + if (ffs_opts->minfree > 0) fsopts->size = - fsopts->size * (100 + fsopts->minfree) / 100; + fsopts->size * (100 + ffs_opts->minfree) / 100; /* * XXX any other fs slop to add, such as csum's, bitmaps, etc ?? */ @@ -362,24 +404,11 @@ ffs_validate(const char *dir, fsnode *ro fsopts->size = fsopts->minsize; /* round up to the next block */ - size = roundup(fsopts->size, fsopts->bsize); - - /* now check calculated sizes vs requested sizes */ - if (fsopts->maxsize > 0 && size > fsopts->maxsize) { - if (debug & DEBUG_FS_VALIDATE) { - printf("%s: `%s' size of %lld is larger than the " - "maxsize of %lld; rounding down to %lld.", - __func__, dir, (long long)size, - (long long)fsopts->maxsize, - (long long) rounddown(fsopts->size, fsopts->bsize)); - } - size = rounddown(fsopts->size, fsopts->bsize); - } - fsopts->size = size; + fsopts->size = roundup(fsopts->size, ffs_opts->bsize); /* calculate density if necessary */ - if (fsopts->density == -1) - fsopts->density = fsopts->size / fsopts->inodes + 1; + if (ffs_opts->density == -1) + ffs_opts->density = fsopts->size / fsopts->inodes + 1; if (debug & DEBUG_FS_VALIDATE) { printf("ffs_validate: after defaults set:\n"); @@ -388,6 +417,12 @@ ffs_validate(const char *dir, fsnode *ro dir, (long long)fsopts->size, (long long)fsopts->inodes); } sectorsize = fsopts->sectorsize; /* XXX - see earlier */ + + /* now check calculated sizes vs requested sizes */ + if (fsopts->maxsize > 0 && fsopts->size > fsopts->maxsize) { + errx(1, "`%s' size of %lld is larger than the maxsize of %lld.", + dir, (long long)fsopts->size, (long long)fsopts->maxsize); + } } @@ -395,6 +430,8 @@ static void ffs_dump_fsinfo(fsinfo_t *f) { + ffs_opt_t *fs = f->fs_specific; + printf("fsopts at %p\n", f); printf("\tsize %lld, inodes %lld, curinode %u\n", @@ -409,20 +446,20 @@ ffs_dump_fsinfo(fsinfo_t *f) printf("\tneedswap %d, sectorsize %d\n", f->needswap, f->sectorsize); printf("\tbsize %d, fsize %d, cpg %d, density %d\n", - f->bsize, f->fsize, f->cpg, f->density); + fs->bsize, fs->fsize, fs->cpg, fs->density); printf("\tnsectors %d, rpm %d, minfree %d\n", - f->nsectors, f->rpm, f->minfree); + fs->nsectors, fs->rpm, fs->minfree); printf("\tmaxcontig %d, maxbpg %d\n", - f->maxcontig, f->maxbpg); + fs->maxcontig, fs->maxbpg); printf("\toptimization %s\n", - f->optimization == FS_OPTSPACE ? "space" : "time"); + fs->optimization == FS_OPTSPACE ? "space" : "time"); } static int ffs_create_image(const char *image, fsinfo_t *fsopts) { -#if HAVE_STRUCT_STATVFS_F_IOSIZE +#if HAVE_STRUCT_STATVFS_F_IOSIZE && HAVE_FSTATVFS struct statvfs sfs; #endif struct fs *fs; @@ -434,18 +471,18 @@ ffs_create_image(const char *image, fsin assert (fsopts != NULL); /* create image */ - if ((fsopts->fd = open(image, O_RDWR | O_CREAT | O_TRUNC, 0777)) + if ((fsopts->fd = open(image, O_RDWR | O_CREAT | O_TRUNC, 0666)) == -1) { warn("Can't open `%s' for writing", image); return (-1); } /* zero image */ -#if HAVE_STRUCT_STATVFS_F_IOSIZE +#if HAVE_STRUCT_STATVFS_F_IOSIZE && HAVE_FSTATVFS if (fstatvfs(fsopts->fd, &sfs) == -1) { #endif bufsize = 8192; -#if HAVE_STRUCT_STATVFS_F_IOSIZE +#if HAVE_STRUCT_STATVFS_F_IOSIZE && HAVE_FSTATVFS warn("can't fstatvfs `%s', using default %d byte chunk", image, bufsize); } else @@ -465,10 +502,12 @@ ffs_create_image(const char *image, fsin if (i == -1) { warn("zeroing image, %lld bytes to go", (long long)bufrem); + free(buf); return (-1); } bufrem -= i; } + free(buf); /* make the file system */ if (debug & DEBUG_FS_CREATE_IMAGE) @@ -492,7 +531,7 @@ ffs_create_image(const char *image, fsin warnx( "Image file `%s' has %lld free inodes; %lld are required.", image, - (long long)fs->fs_cstotal.cs_nifree + ROOTINO, + (long long)(fs->fs_cstotal.cs_nifree + ROOTINO), (long long)fsopts->inodes); return (-1); } @@ -506,9 +545,11 @@ ffs_size_dir(fsnode *root, fsinfo_t *fso struct direct tmpdir; fsnode * node; int curdirsize, this; + ffs_opt_t *ffs_opts = fsopts->fs_specific; /* node may be NULL (empty directory) */ assert(fsopts != NULL); + assert(ffs_opts != NULL); if (debug & DEBUG_FS_SIZE_DIR) printf("ffs_size_dir: entry: bytes %lld inodes %lld\n", @@ -516,7 +557,7 @@ ffs_size_dir(fsnode *root, fsinfo_t *fso #define ADDDIRENT(e) do { \ tmpdir.d_namlen = strlen((e)); \ - this = DIRSIZ_SWAP(0, &tmpdir, 0); \ + this = DIRSIZ_SWAP(0, &tmpdir, 0); \ if (debug & DEBUG_FS_SIZE_DIR_ADD_DIRENT) \ printf("ADDDIRENT: was: %s (%d) this %d cur %d\n", \ e, tmpdir.d_namlen, this, curdirsize); \ @@ -533,14 +574,12 @@ ffs_size_dir(fsnode *root, fsinfo_t *fso * by indirect blocks, etc. */ #define ADDSIZE(x) do { \ - fsopts->size += roundup((x), fsopts->fsize); \ + fsopts->size += roundup((x), ffs_opts->fsize); \ } while (0); curdirsize = 0; for (node = root; node != NULL; node = node->next) { ADDDIRENT(node->name); - if (FSNODE_EXCLUDE_P(fsopts, node)) - continue; if (node == root) { /* we're at "." */ assert(strcmp(node->name, ".") == 0); ADDDIRENT(".."); @@ -558,7 +597,7 @@ ffs_size_dir(fsnode *root, fsinfo_t *fso int slen; slen = strlen(node->symlink) + 1; - if (slen >= (fsopts->version == 1 ? + if (slen >= (ffs_opts->version == 1 ? MAXSYMLINKLEN_UFS1 : MAXSYMLINKLEN_UFS2)) ADDSIZE(slen); @@ -682,10 +721,12 @@ ffs_populate_dir(const char *dir, fsnode union dinode din; void *membuf; char path[MAXPATHLEN + 1]; + ffs_opt_t *ffs_opts = fsopts->fs_specific; assert(dir != NULL); assert(root != NULL); assert(fsopts != NULL); + assert(ffs_opts != NULL); (void)memset(&dirbuf, 0, sizeof(dirbuf)); @@ -696,8 +737,6 @@ ffs_populate_dir(const char *dir, fsnode * pass 1: allocate inode numbers, build directory `file' */ for (cur = root; cur != NULL; cur = cur->next) { - if (FSNODE_EXCLUDE_P(fsopts, cur)) - continue; if ((cur->inode->flags & FI_ALLOCATED) == 0) { cur->inode->flags |= FI_ALLOCATED; if (cur == root && cur->parent != NULL) @@ -732,8 +771,6 @@ ffs_populate_dir(const char *dir, fsnode if (debug & DEBUG_FS_POPULATE) printf("ffs_populate_dir: PASS 2 dir %s\n", dir); for (cur = root; cur != NULL; cur = cur->next) { - if (FSNODE_EXCLUDE_P(fsopts, cur)) - continue; if (cur->inode->flags & FI_WRITTEN) continue; /* skip hard-linked entries */ cur->inode->flags |= FI_WRITTEN; @@ -746,7 +783,7 @@ ffs_populate_dir(const char *dir, fsnode continue; /* child creates own inode */ /* build on-disk inode */ - if (fsopts->version == 1) + if (ffs_opts->version == 1) membuf = ffs_build_dinode1(&din.ffs1_din, &dirbuf, cur, root, fsopts); else @@ -777,8 +814,6 @@ ffs_populate_dir(const char *dir, fsnode if (debug & DEBUG_FS_POPULATE) printf("ffs_populate_dir: PASS 3 dir %s\n", dir); for (cur = root; cur != NULL; cur = cur->next) { - if (FSNODE_EXCLUDE_P(fsopts, cur)) - continue; if (cur->child == NULL) continue; if (snprintf(path, sizeof(path), "%s/%s", dir, cur->name) @@ -804,16 +839,20 @@ ffs_write_file(union dinode *din, uint32 int isfile, ffd; char *fbuf, *p; off_t bufleft, chunk, offset; + ssize_t nread; struct inode in; struct buf * bp; + ffs_opt_t *ffs_opts = fsopts->fs_specific; assert (din != NULL); assert (buf != NULL); assert (fsopts != NULL); + assert (ffs_opts != NULL); isfile = S_ISREG(DIP(din, mode)); fbuf = NULL; ffd = -1; + p = NULL; in.i_fs = (struct fs *)fsopts->superblock; @@ -830,7 +869,7 @@ ffs_write_file(union dinode *din, uint32 in.i_number = ino; in.i_size = DIP(din, size); - if (fsopts->version == 1) + if (ffs_opts->version == 1) memcpy(&in.i_din.ffs1_din, &din->ffs1_din, sizeof(in.i_din.ffs1_din)); else @@ -842,7 +881,7 @@ ffs_write_file(union dinode *din, uint32 goto write_inode_and_leave; /* mmm, cheating */ if (isfile) { - if ((fbuf = malloc(fsopts->bsize)) == NULL) + if ((fbuf = malloc(ffs_opts->bsize)) == NULL) err(1, "Allocating memory for write buffer"); if ((ffd = open((char *)buf, O_RDONLY, 0444)) == -1) { warn("Can't open `%s' for reading", (char *)buf); @@ -854,13 +893,20 @@ ffs_write_file(union dinode *din, uint32 chunk = 0; for (bufleft = DIP(din, size); bufleft > 0; bufleft -= chunk) { - chunk = MIN(bufleft, fsopts->bsize); - if (isfile) { - if (read(ffd, fbuf, chunk) != chunk) - err(1, "Reading `%s', %lld bytes to go", - (char *)buf, (long long)bufleft); + chunk = MIN(bufleft, ffs_opts->bsize); + if (!isfile) + ; + else if ((nread = read(ffd, fbuf, chunk)) == -1) + err(EXIT_FAILURE, "Reading `%s', %lld bytes to go", + (char *)buf, (long long)bufleft); + else if (nread != chunk) + errx(EXIT_FAILURE, "Reading `%s', %lld bytes to go, " + "read %zd bytes, expected %ju bytes, does " + "metalog size= attribute mismatch source size?", + (char *)buf, (long long)bufleft, nread, + (uintmax_t)chunk); + else p = fbuf; - } offset = DIP(din, size) - bufleft; if (debug & DEBUG_FS_WRITE_FILE_BLOCK) printf( @@ -932,7 +978,7 @@ ffs_make_dirbuf(dirbuf_t *dbuf, const ch { struct direct de, *dp; uint16_t llen, reclen; - char *newbuf; + u_char *newbuf; assert (dbuf != NULL); assert (name != NULL); @@ -969,7 +1015,7 @@ ffs_make_dirbuf(dirbuf_t *dbuf, const ch dbuf->size += DIRBLKSIZ; memset(dbuf->buf + dbuf->size - DIRBLKSIZ, 0, DIRBLKSIZ); dbuf->cur = dbuf->size - DIRBLKSIZ; - } else { /* shrink end of previous */ + } else if (dp) { /* shrink end of previous */ dp->d_reclen = ufs_rw16(llen,needswap); dbuf->cur += llen; } @@ -993,10 +1039,12 @@ ffs_write_inode(union dinode *dp, uint32 daddr_t d; char sbbuf[FFS_MAXBSIZE]; int32_t initediblk; + ffs_opt_t *ffs_opts = fsopts->fs_specific; assert (dp != NULL); assert (ino > 0); assert (fsopts != NULL); + assert (ffs_opts != NULL); fs = (struct fs *)fsopts->superblock; cg = ino_to_cg(fs, ino); @@ -1041,7 +1089,7 @@ ffs_write_inode(union dinode *dp, uint32 * Initialize inode blocks on the fly for UFS2. */ initediblk = ufs_rw32(cgp->cg_initediblk, fsopts->needswap); - if (fsopts->version == 2 && cgino + INOPB(fs) > initediblk && + if (ffs_opts->version == 2 && cgino + INOPB(fs) > initediblk && initediblk < ufs_rw32(cgp->cg_niblk, fsopts->needswap)) { memset(buf, 0, fs->fs_bsize); dip = (struct ufs2_dinode *)buf; @@ -1065,14 +1113,14 @@ ffs_write_inode(union dinode *dp, uint32 d = fsbtodb(fs, ino_to_fsba(fs, ino)); ffs_rdfs(d, fs->fs_bsize, buf, fsopts); if (fsopts->needswap) { - if (fsopts->version == 1) + if (ffs_opts->version == 1) ffs_dinode1_swap(&dp->ffs1_din, &dp1[ino_to_fsbo(fs, ino)]); else ffs_dinode2_swap(&dp->ffs2_din, &dp2[ino_to_fsbo(fs, ino)]); } else { - if (fsopts->version == 1) + if (ffs_opts->version == 1) dp1[ino_to_fsbo(fs, ino)] = dp->ffs1_din; else dp2[ino_to_fsbo(fs, ino)] = dp->ffs2_din; Copied: stable/7/usr.sbin/makefs/ffs.h (from r214921, head/usr.sbin/makefs/ffs.h) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ stable/7/usr.sbin/makefs/ffs.h Tue Jul 26 14:41:54 2011 (r224448, copy of r214921, head/usr.sbin/makefs/ffs.h) @@ -0,0 +1,66 @@ +/* $NetBSD: ffs.h,v 1.1 2004/12/20 20:51:42 jmc Exp $ */ + +/* + * Copyright (c) 2001-2003 Wasabi Systems, Inc. + * All rights reserved. + * + * Written by Luke Mewburn for Wasabi Systems, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed for the NetBSD Project by + * Wasabi Systems, Inc. + * 4. The name of Wasabi Systems, Inc. may not be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _FFS_H +#define _FFS_H + +typedef struct { + int bsize; /* block size */ + int fsize; /* fragment size */ + int cpg; /* cylinders per group */ + int cpgflg; /* cpg was specified by user */ + int density; /* bytes per inode */ + int ntracks; /* number of tracks */ + int nsectors; /* number of sectors */ + int rpm; /* rpm */ + int minfree; /* free space threshold */ + int optimization; /* optimization (space or time) */ + int maxcontig; /* max contiguous blocks to allocate */ + int rotdelay; /* rotational delay between blocks */ + int maxbpg; /* maximum blocks per file in a cyl group */ + int nrpos; /* # of distinguished rotational positions */ + int avgfilesize; /* expected average file size */ + int avgfpdir; /* expected # of files per directory */ + int version; /* filesystem version (1 = FFS, 2 = UFS2) */ + int maxbsize; /* maximum extent size */ + int maxblkspercg; /* max # of blocks per cylinder group */ + /* XXX: support `old' file systems ? */ +} ffs_opt_t; + +#endif /* _FFS_H */ Copied: stable/7/usr.sbin/makefs/ffs/Makefile.inc (from r214921, head/usr.sbin/makefs/ffs/Makefile.inc) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ stable/7/usr.sbin/makefs/ffs/Makefile.inc Tue Jul 26 14:41:54 2011 (r224448, copy of r214921, head/usr.sbin/makefs/ffs/Makefile.inc) @@ -0,0 +1,9 @@ +# $FreeBSD$ +# + +.PATH: ${.CURDIR}/ffs ${.CURDIR}/../../sys/ufs/ffs + +CFLAGS+= -I${.CURDIR}/../../sys/ufs/ffs + +SRCS+= ffs_alloc.c ffs_balloc.c ffs_bswap.c ffs_subr.c ufs_bmap.c +SRCS+= buf.c mkfs.c Modified: stable/7/usr.sbin/makefs/ffs/buf.c ============================================================================== --- stable/7/usr.sbin/makefs/ffs/buf.c Tue Jul 26 14:41:54 2011 (r224447) +++ stable/7/usr.sbin/makefs/ffs/buf.c Tue Jul 26 14:41:54 2011 (r224448) @@ -118,7 +118,7 @@ brelse(struct buf *bp) bp->b_bcount = 0; return; } - + TAILQ_REMOVE(&buftail, bp, b_tailq); free(bp->b_data); free(bp); @@ -160,7 +160,7 @@ bcleanup(void) * know why there's still some buffers lying around that * aren't brelse()d */ - + if (TAILQ_EMPTY(&buftail)) return; @@ -201,7 +201,7 @@ getblk(int fd, struct fs *fs, daddr_t bl if (bp == NULL) { if ((bp = calloc(1, sizeof(struct buf))) == NULL) err(1, "getblk: calloc"); - + bp->b_bufsize = 0; bp->b_blkno = bp->b_lblkno = blkno; bp->b_fd = fd; Modified: stable/7/usr.sbin/makefs/ffs/ffs_alloc.c ============================================================================== --- stable/7/usr.sbin/makefs/ffs/ffs_alloc.c Tue Jul 26 14:41:54 2011 (r224447) +++ stable/7/usr.sbin/makefs/ffs/ffs_alloc.c Tue Jul 26 14:41:54 2011 (r224448) @@ -87,7 +87,7 @@ static int32_t ffs_mapsearch(struct fs * * available block is located. */ int -ffs_alloc(struct inode *ip, daddr_t lbn, daddr_t bpref, int size, +ffs_alloc(struct inode *ip, daddr_t lbn __unused, daddr_t bpref, int size, daddr_t *bnp) { struct fs *fs = ip->i_fs; @@ -95,7 +95,7 @@ ffs_alloc(struct inode *ip, daddr_t lbn, int cg; *bnp = 0; - if ((u_int)size > fs->fs_bsize || fragoff(fs, size) != 0) { + if (size > fs->fs_bsize || fragoff(fs, size) != 0) { errx(1, "ffs_alloc: bad size: bsize %d size %d", fs->fs_bsize, size); } @@ -187,11 +187,7 @@ ffs_blkpref_ufs1(struct inode *ip, daddr } daddr_t -ffs_blkpref_ufs2(ip, lbn, indx, bap) - struct inode *ip; - daddr_t lbn; - int indx; - int64_t *bap; +ffs_blkpref_ufs2(struct inode *ip, daddr_t lbn, int indx, int64_t *bap) { struct fs *fs; int cg; @@ -385,11 +381,11 @@ ffs_alloccgblk(struct inode *ip, struct int32_t bno; struct fs *fs = ip->i_fs; const int needswap = UFS_FSNEEDSWAP(fs); - u_int8_t *blksfree; + u_int8_t *blksfree_swap; *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***