xref: /titanic_51/usr/src/cmd/fs.d/udfs/mkfs/mkfs.c (revision 65908c77dfc02644236ba18bffe67b5ed6f23135)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5fe0e7ec4Smaheshvs  * Common Development and Distribution License (the "License").
6fe0e7ec4Smaheshvs  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
22*65908c77Syu, larry liu - Sun Microsystems - Beijing China  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate /*	Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T	*/
277c478bd9Sstevel@tonic-gate /*	  All Rights Reserved  	*/
287c478bd9Sstevel@tonic-gate 
297c478bd9Sstevel@tonic-gate /*
307c478bd9Sstevel@tonic-gate  * Portions of this source code were derived from Berkeley 4.3 BSD
317c478bd9Sstevel@tonic-gate  * under license from the Regents of the University of California.
327c478bd9Sstevel@tonic-gate  */
337c478bd9Sstevel@tonic-gate 
347c478bd9Sstevel@tonic-gate /*
357c478bd9Sstevel@tonic-gate  * make file system for udfs (UDF - ISO13346)
367c478bd9Sstevel@tonic-gate  *
377c478bd9Sstevel@tonic-gate  * usage:
387c478bd9Sstevel@tonic-gate  *
397c478bd9Sstevel@tonic-gate  *    mkfs [-F FSType] [-V] [-m] [options]
407c478bd9Sstevel@tonic-gate  *	[-o specific_options]  special size
417c478bd9Sstevel@tonic-gate  *
427c478bd9Sstevel@tonic-gate  *  where specific_options are:
437c478bd9Sstevel@tonic-gate  *	N - no create
447c478bd9Sstevel@tonic-gate  *	label - volume label
457c478bd9Sstevel@tonic-gate  *	psize - physical block size
467c478bd9Sstevel@tonic-gate  */
477c478bd9Sstevel@tonic-gate 
487c478bd9Sstevel@tonic-gate #include	<stdio.h>
497c478bd9Sstevel@tonic-gate #include	<strings.h>
507c478bd9Sstevel@tonic-gate #include	<string.h>
517c478bd9Sstevel@tonic-gate #include	<stdlib.h>
527c478bd9Sstevel@tonic-gate #include	<unistd.h>
537c478bd9Sstevel@tonic-gate #include	<time.h>
547c478bd9Sstevel@tonic-gate #include	<locale.h>
557c478bd9Sstevel@tonic-gate #include	<fcntl.h>
567c478bd9Sstevel@tonic-gate #include	<errno.h>
577c478bd9Sstevel@tonic-gate #include	<limits.h>
587c478bd9Sstevel@tonic-gate #include	<sys/mnttab.h>
597c478bd9Sstevel@tonic-gate #include	<sys/param.h>
607c478bd9Sstevel@tonic-gate #include	<sys/types.h>
617c478bd9Sstevel@tonic-gate #include	<sys/sysmacros.h>
627c478bd9Sstevel@tonic-gate #include	<sys/vnode.h>
637c478bd9Sstevel@tonic-gate #include	<sys/mntent.h>
647c478bd9Sstevel@tonic-gate #include	<sys/filio.h>
657c478bd9Sstevel@tonic-gate #include	<sys/stat.h>
667c478bd9Sstevel@tonic-gate #include	<ustat.h>
677c478bd9Sstevel@tonic-gate #include 	<sys/isa_defs.h>	/* for ENDIAN defines */
687c478bd9Sstevel@tonic-gate #include	<sys/dkio.h>
697c478bd9Sstevel@tonic-gate #include	<sys/fdio.h>
707c478bd9Sstevel@tonic-gate #include	<sys/vtoc.h>
717c478bd9Sstevel@tonic-gate #include	<sys/fs/udf_volume.h>
727c478bd9Sstevel@tonic-gate 
737c478bd9Sstevel@tonic-gate extern char	*getfullrawname(char *);
747c478bd9Sstevel@tonic-gate extern char	*getfullblkname(char *);
757c478bd9Sstevel@tonic-gate extern struct tm *localtime_r(const time_t *, struct tm *);
767c478bd9Sstevel@tonic-gate extern void	maketag(struct tag *, struct tag *);
777c478bd9Sstevel@tonic-gate extern int	verifytag(struct tag *, uint32_t, struct tag *, int);
787c478bd9Sstevel@tonic-gate extern void	setcharspec(struct charspec *, int32_t, uint8_t *);
797c478bd9Sstevel@tonic-gate 
807c478bd9Sstevel@tonic-gate 
817c478bd9Sstevel@tonic-gate #define	UMASK		0755
827c478bd9Sstevel@tonic-gate #define	POWEROF2(num)	(((num) & ((num) - 1)) == 0)
837c478bd9Sstevel@tonic-gate #define	MB		(1024*1024)
847c478bd9Sstevel@tonic-gate 
857c478bd9Sstevel@tonic-gate /*
867c478bd9Sstevel@tonic-gate  * Forward declarations
877c478bd9Sstevel@tonic-gate  */
887c478bd9Sstevel@tonic-gate static void rdfs(daddr_t bno, int size, char *bf);
897c478bd9Sstevel@tonic-gate static void wtfs(daddr_t bno, int size, char *bf);
907c478bd9Sstevel@tonic-gate static void dump_fscmd(char *fsys, int fsi);
917c478bd9Sstevel@tonic-gate static int32_t number(long big, char *param);
927c478bd9Sstevel@tonic-gate static void usage();
937c478bd9Sstevel@tonic-gate static int match(char *s);
947c478bd9Sstevel@tonic-gate static int readvolseq();
957c478bd9Sstevel@tonic-gate static uint32_t get_last_block();
967c478bd9Sstevel@tonic-gate 
977c478bd9Sstevel@tonic-gate /*
987c478bd9Sstevel@tonic-gate  * variables set up by front end.
997c478bd9Sstevel@tonic-gate  */
1007c478bd9Sstevel@tonic-gate static int	Nflag = 0;		/* run mkfs without writing */
1017c478bd9Sstevel@tonic-gate 					/* file system */
1027c478bd9Sstevel@tonic-gate static int	mflag = 0;		/* return the command line used */
1037c478bd9Sstevel@tonic-gate 					/* to create this FS */
1047c478bd9Sstevel@tonic-gate static int	fssize;			/* file system size */
1057c478bd9Sstevel@tonic-gate static uint32_t	disk_size;		/* partition size from VTOC */
1067c478bd9Sstevel@tonic-gate static uint32_t unused;			/* unused sectors in partition */
1077c478bd9Sstevel@tonic-gate static int	sectorsize = 2048;	/* bytes/sector default */
1087c478bd9Sstevel@tonic-gate 					/* If nothing specified */
1097c478bd9Sstevel@tonic-gate 
1107c478bd9Sstevel@tonic-gate static char	*fsys;
1117c478bd9Sstevel@tonic-gate static int	fsi;
1127c478bd9Sstevel@tonic-gate static int	fso;
1137c478bd9Sstevel@tonic-gate 
1147c478bd9Sstevel@tonic-gate #define	BIG	LONG_MAX
1157c478bd9Sstevel@tonic-gate static	uint32_t	number_flags = 0;
1167c478bd9Sstevel@tonic-gate 
1177c478bd9Sstevel@tonic-gate static char	*string;
1187c478bd9Sstevel@tonic-gate 
1197c478bd9Sstevel@tonic-gate static void	setstamp(tstamp_t *);
1207c478bd9Sstevel@tonic-gate static void	setextad(extent_ad_t *, uint32_t, uint32_t);
1217c478bd9Sstevel@tonic-gate static void	setdstring(dstring_t *, char *, int32_t);
1227c478bd9Sstevel@tonic-gate static void	wtvolseq(tag_t *, daddr_t, daddr_t);
1237c478bd9Sstevel@tonic-gate static void	volseqinit();
1247c478bd9Sstevel@tonic-gate static void	setstamp(tstamp_t *);
1257c478bd9Sstevel@tonic-gate static uint32_t	get_bsize();
1267c478bd9Sstevel@tonic-gate 
1277c478bd9Sstevel@tonic-gate 
1287c478bd9Sstevel@tonic-gate #define	VOLRECSTART	(32 * 1024)
1297c478bd9Sstevel@tonic-gate 
1307c478bd9Sstevel@tonic-gate #define	VOLSEQSTART	128
1317c478bd9Sstevel@tonic-gate #define	VOLSEQLEN	16
1327c478bd9Sstevel@tonic-gate #define	INTSEQSTART	192
1337c478bd9Sstevel@tonic-gate #define	INTSEQLEN	8192
1347c478bd9Sstevel@tonic-gate #define	FIRSTAVDP	256
1357c478bd9Sstevel@tonic-gate #define	AVDPLEN		1
1367c478bd9Sstevel@tonic-gate 
1377c478bd9Sstevel@tonic-gate 
1387c478bd9Sstevel@tonic-gate #define	FILESETLEN	2
1397c478bd9Sstevel@tonic-gate 
1407c478bd9Sstevel@tonic-gate #define	SPACEMAP_OFF	24
1417c478bd9Sstevel@tonic-gate #define	MAXID		16
1427c478bd9Sstevel@tonic-gate 
1437c478bd9Sstevel@tonic-gate static time_t mkfstime;
1447c478bd9Sstevel@tonic-gate static struct tm res;
1457c478bd9Sstevel@tonic-gate static long tzone;
1467c478bd9Sstevel@tonic-gate static char vsibuf[128];
1477c478bd9Sstevel@tonic-gate 
1487c478bd9Sstevel@tonic-gate static regid_t sunmicro = { 0, "*SUN SOLARIS UDF", 4, 2 };
1497c478bd9Sstevel@tonic-gate static regid_t lvinfo = { 0, "*UDF LV Info", 0x50, 0x1, 4, 2 };
1507c478bd9Sstevel@tonic-gate static regid_t partid = { 0, "+NSR02", 0 };
1517c478bd9Sstevel@tonic-gate static regid_t udf_compliant = { 0, "*OSTA UDF Compliant", 0x50, 0x1, 0 };
1527c478bd9Sstevel@tonic-gate static uint8_t osta_unicode[] = "OSTA Compressed Unicode";
1537c478bd9Sstevel@tonic-gate 
1547c478bd9Sstevel@tonic-gate static int bdevismounted;
1557c478bd9Sstevel@tonic-gate static int ismounted;
1567c478bd9Sstevel@tonic-gate static int directory;
1577c478bd9Sstevel@tonic-gate static char buf[MAXBSIZE];
1587c478bd9Sstevel@tonic-gate static char buf2[MAXBSIZE];
1597c478bd9Sstevel@tonic-gate static char lvid[MAXBSIZE];
1607c478bd9Sstevel@tonic-gate 
1617c478bd9Sstevel@tonic-gate uint32_t ecma_version = 2;
1627c478bd9Sstevel@tonic-gate 
1637c478bd9Sstevel@tonic-gate static int serialnum = 1;	/* Tag serial number */
1647c478bd9Sstevel@tonic-gate static char udfs_label[128] = "*NoLabel*";
1657c478bd9Sstevel@tonic-gate static int acctype = PART_ACC_OW;
1667c478bd9Sstevel@tonic-gate static uint32_t part_start;
1677c478bd9Sstevel@tonic-gate static uint32_t part_len;
1687c478bd9Sstevel@tonic-gate static uint32_t part_bmp_bytes;
1697c478bd9Sstevel@tonic-gate static uint32_t part_bmp_sectors;
1707c478bd9Sstevel@tonic-gate static int32_t part_unalloc = -1;
1717c478bd9Sstevel@tonic-gate static uint32_t filesetblock;
1727c478bd9Sstevel@tonic-gate 
1737c478bd9Sstevel@tonic-gate /* Set by readvolseq for -m option */
1747c478bd9Sstevel@tonic-gate static uint32_t oldfssize;
1757c478bd9Sstevel@tonic-gate static char *oldlabel;
1767c478bd9Sstevel@tonic-gate 
177fe0e7ec4Smaheshvs int
1787c478bd9Sstevel@tonic-gate main(int32_t argc, int8_t *argv[])
1797c478bd9Sstevel@tonic-gate {
1807c478bd9Sstevel@tonic-gate 	long i;
1817c478bd9Sstevel@tonic-gate 	FILE *mnttab;
1827c478bd9Sstevel@tonic-gate 	struct mnttab mntp;
1837c478bd9Sstevel@tonic-gate 	char *special, *raw_special;
1847c478bd9Sstevel@tonic-gate 	struct stat statarea;
1857c478bd9Sstevel@tonic-gate 	struct ustat ustatarea;
1867c478bd9Sstevel@tonic-gate 	int32_t	c;
1877c478bd9Sstevel@tonic-gate 	uint32_t temp_secsz;
1887c478bd9Sstevel@tonic-gate 	int isfs;
1897c478bd9Sstevel@tonic-gate 
1907c478bd9Sstevel@tonic-gate 	(void) setlocale(LC_ALL, "");
1917c478bd9Sstevel@tonic-gate 
1927c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN)
1937c478bd9Sstevel@tonic-gate #define	TEXT_DOMAIN "SYS_TEST"
1947c478bd9Sstevel@tonic-gate #endif
1957c478bd9Sstevel@tonic-gate 	(void) textdomain(TEXT_DOMAIN);
1967c478bd9Sstevel@tonic-gate 
1977c478bd9Sstevel@tonic-gate 	while ((c = getopt(argc, argv, "F:Vmo:")) != EOF) {
1987c478bd9Sstevel@tonic-gate 		switch (c) {
1997c478bd9Sstevel@tonic-gate 
2007c478bd9Sstevel@tonic-gate 			case 'F':
2017c478bd9Sstevel@tonic-gate 				string = optarg;
2027c478bd9Sstevel@tonic-gate 				if (strcmp(string, "udfs") != 0) {
2037c478bd9Sstevel@tonic-gate 					usage();
2047c478bd9Sstevel@tonic-gate 				}
2057c478bd9Sstevel@tonic-gate 				break;
2067c478bd9Sstevel@tonic-gate 
2077c478bd9Sstevel@tonic-gate 			case 'V':
2087c478bd9Sstevel@tonic-gate 				{
2097c478bd9Sstevel@tonic-gate 					char	*opt_text;
2107c478bd9Sstevel@tonic-gate 					int	opt_count;
2117c478bd9Sstevel@tonic-gate 
2127c478bd9Sstevel@tonic-gate 					(void) fprintf(stdout,
2137c478bd9Sstevel@tonic-gate 					gettext("mkfs -F udfs "));
2147c478bd9Sstevel@tonic-gate 					for (opt_count = 1; opt_count < argc;
2157c478bd9Sstevel@tonic-gate 							opt_count++) {
2167c478bd9Sstevel@tonic-gate 						opt_text = argv[opt_count];
2177c478bd9Sstevel@tonic-gate 						if (opt_text) {
2187c478bd9Sstevel@tonic-gate 							(void) fprintf(stdout,
2197c478bd9Sstevel@tonic-gate 							" %s ", opt_text);
2207c478bd9Sstevel@tonic-gate 						}
2217c478bd9Sstevel@tonic-gate 					}
2227c478bd9Sstevel@tonic-gate 					(void) fprintf(stdout, "\n");
2237c478bd9Sstevel@tonic-gate 				}
2247c478bd9Sstevel@tonic-gate 				break;
2257c478bd9Sstevel@tonic-gate 
2267c478bd9Sstevel@tonic-gate 			case 'm':
2277c478bd9Sstevel@tonic-gate 				/*
2287c478bd9Sstevel@tonic-gate 				 * return command line used
2297c478bd9Sstevel@tonic-gate 				 * to create this FS
2307c478bd9Sstevel@tonic-gate 				 */
2317c478bd9Sstevel@tonic-gate 				mflag++;
2327c478bd9Sstevel@tonic-gate 				break;
2337c478bd9Sstevel@tonic-gate 
2347c478bd9Sstevel@tonic-gate 			case 'o':
2357c478bd9Sstevel@tonic-gate 				/*
2367c478bd9Sstevel@tonic-gate 				 * udfs specific options.
2377c478bd9Sstevel@tonic-gate 				 */
2387c478bd9Sstevel@tonic-gate 				string = optarg;
2397c478bd9Sstevel@tonic-gate 				while (*string != '\0') {
2407c478bd9Sstevel@tonic-gate 					if (match("N")) {
2417c478bd9Sstevel@tonic-gate 						Nflag++;
2427c478bd9Sstevel@tonic-gate 					} else if (match("psize=")) {
2437c478bd9Sstevel@tonic-gate 						number_flags = 0;
2447c478bd9Sstevel@tonic-gate 						sectorsize = number(BIG,
2457c478bd9Sstevel@tonic-gate 							"psize");
2467c478bd9Sstevel@tonic-gate 					} else if (match("label=")) {
2477c478bd9Sstevel@tonic-gate 						for (i = 0; i < 31; i++) {
2487c478bd9Sstevel@tonic-gate 							if (*string == '\0') {
2497c478bd9Sstevel@tonic-gate 								break;
2507c478bd9Sstevel@tonic-gate 							}
2517c478bd9Sstevel@tonic-gate 							udfs_label[i] =
2527c478bd9Sstevel@tonic-gate 								*string++;
2537c478bd9Sstevel@tonic-gate 						}
2547c478bd9Sstevel@tonic-gate 						udfs_label[i] = '\0';
2557c478bd9Sstevel@tonic-gate 					} else if (*string == '\0') {
2567c478bd9Sstevel@tonic-gate 						break;
2577c478bd9Sstevel@tonic-gate 					} else {
2587c478bd9Sstevel@tonic-gate 						(void) fprintf(stdout,
2597c478bd9Sstevel@tonic-gate 							gettext("illegal "
2607c478bd9Sstevel@tonic-gate 							"option: %s\n"),
2617c478bd9Sstevel@tonic-gate 							string);
2627c478bd9Sstevel@tonic-gate 						usage();
2637c478bd9Sstevel@tonic-gate 					}
2647c478bd9Sstevel@tonic-gate 					if (*string == ',') {
2657c478bd9Sstevel@tonic-gate 						string++;
2667c478bd9Sstevel@tonic-gate 					}
2677c478bd9Sstevel@tonic-gate 					if (*string == ' ') {
2687c478bd9Sstevel@tonic-gate 						string++;
2697c478bd9Sstevel@tonic-gate 					}
2707c478bd9Sstevel@tonic-gate 				}
2717c478bd9Sstevel@tonic-gate 				break;
2727c478bd9Sstevel@tonic-gate 
2737c478bd9Sstevel@tonic-gate 			case '?':
2747c478bd9Sstevel@tonic-gate 				usage();
2757c478bd9Sstevel@tonic-gate 				break;
2767c478bd9Sstevel@tonic-gate 		}
2777c478bd9Sstevel@tonic-gate 	}
2787c478bd9Sstevel@tonic-gate 
2797c478bd9Sstevel@tonic-gate 	(void) time(&mkfstime);
2807c478bd9Sstevel@tonic-gate 	if (optind > (argc - 1)) {
2817c478bd9Sstevel@tonic-gate 		usage();
2827c478bd9Sstevel@tonic-gate 	}
2837c478bd9Sstevel@tonic-gate 
2847c478bd9Sstevel@tonic-gate 	argc -= optind;
2857c478bd9Sstevel@tonic-gate 	argv = &argv[optind];
2867c478bd9Sstevel@tonic-gate 	fsys = argv[0];
2877c478bd9Sstevel@tonic-gate 	raw_special = getfullrawname(fsys);
2887c478bd9Sstevel@tonic-gate 	fsi = open(raw_special, 0);
2897c478bd9Sstevel@tonic-gate 	if (fsi < 0) {
2907c478bd9Sstevel@tonic-gate 		(void) fprintf(stdout,
2917c478bd9Sstevel@tonic-gate 			gettext("%s: cannot open\n"), fsys);
2927c478bd9Sstevel@tonic-gate 		exit(32);
2937c478bd9Sstevel@tonic-gate 	}
2947c478bd9Sstevel@tonic-gate 	fso = fsi;
2957c478bd9Sstevel@tonic-gate 
2967c478bd9Sstevel@tonic-gate 	if ((temp_secsz = get_bsize()) != 0) {
2977c478bd9Sstevel@tonic-gate 		sectorsize = temp_secsz;
2987c478bd9Sstevel@tonic-gate 	}
2997c478bd9Sstevel@tonic-gate 
3007c478bd9Sstevel@tonic-gate 	/* Get old file system information */
3017c478bd9Sstevel@tonic-gate 	isfs = readvolseq();
3027c478bd9Sstevel@tonic-gate 
3037c478bd9Sstevel@tonic-gate 	if (mflag) {
3047c478bd9Sstevel@tonic-gate 		/*
3057c478bd9Sstevel@tonic-gate 		 * Figure out the block size and
3067c478bd9Sstevel@tonic-gate 		 * file system size and print the information
3077c478bd9Sstevel@tonic-gate 		 */
3087c478bd9Sstevel@tonic-gate 		if (isfs)
3097c478bd9Sstevel@tonic-gate 			dump_fscmd(fsys, fsi);
3107c478bd9Sstevel@tonic-gate 		else
3117c478bd9Sstevel@tonic-gate 			(void) printf(gettext(
3127c478bd9Sstevel@tonic-gate 				"[not currently a valid file system]\n"));
3137c478bd9Sstevel@tonic-gate 		exit(0);
3147c478bd9Sstevel@tonic-gate 	}
3157c478bd9Sstevel@tonic-gate 
3167c478bd9Sstevel@tonic-gate 	/*
3177c478bd9Sstevel@tonic-gate 	 * Get the disk size from the drive or VTOC for the N and N-256
3187c478bd9Sstevel@tonic-gate 	 * AVDPs and to make sure we don't want to create a file system
3197c478bd9Sstevel@tonic-gate 	 * bigger than the partition.
3207c478bd9Sstevel@tonic-gate 	 */
3217c478bd9Sstevel@tonic-gate 	disk_size = get_last_block();
3227c478bd9Sstevel@tonic-gate 
3237c478bd9Sstevel@tonic-gate 	if (argc < 2 && disk_size == 0 || argc < 1) {
3247c478bd9Sstevel@tonic-gate 		usage();
3257c478bd9Sstevel@tonic-gate 	}
3267c478bd9Sstevel@tonic-gate 
3277c478bd9Sstevel@tonic-gate 	if (argc < 2) {
3287c478bd9Sstevel@tonic-gate 		(void) printf(gettext("No size specified, entire partition "
3297c478bd9Sstevel@tonic-gate 			"of %u sectors used\n"), disk_size);
3307c478bd9Sstevel@tonic-gate 		fssize = disk_size;
3317c478bd9Sstevel@tonic-gate 	} else {
3327c478bd9Sstevel@tonic-gate 		string = argv[1];
3337c478bd9Sstevel@tonic-gate 		number_flags = 0;
3347c478bd9Sstevel@tonic-gate 		fssize = number(BIG, "size");
3357c478bd9Sstevel@tonic-gate 	}
3367c478bd9Sstevel@tonic-gate 
3377c478bd9Sstevel@tonic-gate 	if (fssize < 0) {
3387c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr,
3397c478bd9Sstevel@tonic-gate 			gettext("Negative number of sectors(%d) not allowed\n"),
3407c478bd9Sstevel@tonic-gate 			fssize);
3417c478bd9Sstevel@tonic-gate 		exit(32);
3427c478bd9Sstevel@tonic-gate 	}
3437c478bd9Sstevel@tonic-gate 
3447c478bd9Sstevel@tonic-gate 	if (fssize < (512 * sectorsize / DEV_BSIZE)) {
3457c478bd9Sstevel@tonic-gate 		(void) fprintf(stdout,
3467c478bd9Sstevel@tonic-gate 			gettext("size should be at least %d sectors\n"),
3477c478bd9Sstevel@tonic-gate 			(512 * sectorsize / DEV_BSIZE));
3487c478bd9Sstevel@tonic-gate 		exit(32);
3497c478bd9Sstevel@tonic-gate 	}
3507c478bd9Sstevel@tonic-gate 
3517c478bd9Sstevel@tonic-gate 	if (disk_size != 0) {
3527c478bd9Sstevel@tonic-gate 		if (fssize > disk_size) {
3537c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, gettext("Invalid size: %d "
3547c478bd9Sstevel@tonic-gate 				"larger than the partition size\n"), fssize);
3557c478bd9Sstevel@tonic-gate 			exit(32);
3567c478bd9Sstevel@tonic-gate 		} else if (fssize < disk_size) {
3577c478bd9Sstevel@tonic-gate 			unused = disk_size - fssize;
3587c478bd9Sstevel@tonic-gate 			(void) printf(
3597c478bd9Sstevel@tonic-gate 			    gettext("File system size %d smaller than "
3607c478bd9Sstevel@tonic-gate 				"partition, %u sectors unused\n"),
3617c478bd9Sstevel@tonic-gate 				fssize, unused);
3627c478bd9Sstevel@tonic-gate 		}
3637c478bd9Sstevel@tonic-gate 	} else {
3647c478bd9Sstevel@tonic-gate 		/* Use passed-in size */
3657c478bd9Sstevel@tonic-gate 		disk_size = fssize;
3667c478bd9Sstevel@tonic-gate 	}
3677c478bd9Sstevel@tonic-gate 
3687c478bd9Sstevel@tonic-gate 	if (!Nflag) {
3697c478bd9Sstevel@tonic-gate 		special = getfullblkname(fsys);
3707c478bd9Sstevel@tonic-gate 
3717c478bd9Sstevel@tonic-gate 		/*
3727c478bd9Sstevel@tonic-gate 		 * If we found the block device name,
3737c478bd9Sstevel@tonic-gate 		 * then check the mount table.
3747c478bd9Sstevel@tonic-gate 		 * if mounted, write lock the file system
3757c478bd9Sstevel@tonic-gate 		 *
3767c478bd9Sstevel@tonic-gate 		 */
3777c478bd9Sstevel@tonic-gate 		if ((special != NULL) && (*special != '\0')) {
3787c478bd9Sstevel@tonic-gate 			mnttab = fopen(MNTTAB, "r");
3797c478bd9Sstevel@tonic-gate 			while ((getmntent(mnttab, &mntp)) == NULL) {
3807c478bd9Sstevel@tonic-gate 				if (strcmp(special, mntp.mnt_special) == 0) {
3817c478bd9Sstevel@tonic-gate 					(void) fprintf(stdout,
3827c478bd9Sstevel@tonic-gate 						gettext("%s is mounted,"
3837c478bd9Sstevel@tonic-gate 						" can't mkfs\n"), special);
3847c478bd9Sstevel@tonic-gate 					exit(32);
3857c478bd9Sstevel@tonic-gate 				}
3867c478bd9Sstevel@tonic-gate 			}
3877c478bd9Sstevel@tonic-gate 			(void) fclose(mnttab);
3887c478bd9Sstevel@tonic-gate 		}
3897c478bd9Sstevel@tonic-gate 		if ((bdevismounted) && (ismounted == 0)) {
3907c478bd9Sstevel@tonic-gate 			(void) fprintf(stdout,
3917c478bd9Sstevel@tonic-gate 				gettext("can't check mount point; "));
3927c478bd9Sstevel@tonic-gate 			(void) fprintf(stdout,
3937c478bd9Sstevel@tonic-gate 				gettext("%s is mounted but not in mnttab(4)\n"),
3947c478bd9Sstevel@tonic-gate 				special);
3957c478bd9Sstevel@tonic-gate 			exit(32);
3967c478bd9Sstevel@tonic-gate 		}
3977c478bd9Sstevel@tonic-gate 		if (directory) {
3987c478bd9Sstevel@tonic-gate 			if (ismounted == 0) {
3997c478bd9Sstevel@tonic-gate 				(void) fprintf(stdout,
4007c478bd9Sstevel@tonic-gate 					gettext("%s is not mounted\n"),
4017c478bd9Sstevel@tonic-gate 					special);
4027c478bd9Sstevel@tonic-gate 				exit(32);
4037c478bd9Sstevel@tonic-gate 			}
4047c478bd9Sstevel@tonic-gate 		}
4057c478bd9Sstevel@tonic-gate 		fso = creat(fsys, 0666);
4067c478bd9Sstevel@tonic-gate 		if (fso < 0) {
4077c478bd9Sstevel@tonic-gate 			(void) fprintf(stdout,
4087c478bd9Sstevel@tonic-gate 				gettext("%s: cannot create\n"), fsys);
4097c478bd9Sstevel@tonic-gate 			exit(32);
4107c478bd9Sstevel@tonic-gate 		}
4117c478bd9Sstevel@tonic-gate 		if (stat(fsys, &statarea) < 0) {
4127c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr,
4137c478bd9Sstevel@tonic-gate 				gettext("%s: %s: cannot stat\n"),
4147c478bd9Sstevel@tonic-gate 				argv[0], fsys);
4157c478bd9Sstevel@tonic-gate 			exit(32);
4167c478bd9Sstevel@tonic-gate 		}
4177c478bd9Sstevel@tonic-gate 		if (ustat(statarea.st_rdev, &ustatarea) >= 0) {
4187c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr,
4197c478bd9Sstevel@tonic-gate 				gettext("%s is mounted, can't mkfs\n"), fsys);
4207c478bd9Sstevel@tonic-gate 			exit(32);
4217c478bd9Sstevel@tonic-gate 		}
4227c478bd9Sstevel@tonic-gate 	} else {
4237c478bd9Sstevel@tonic-gate 		/*
4247c478bd9Sstevel@tonic-gate 		 * For the -N case, a file descriptor is needed for the llseek()
4257c478bd9Sstevel@tonic-gate 		 * in wtfs(). See the comment in wtfs() for more information.
4267c478bd9Sstevel@tonic-gate 		 *
4277c478bd9Sstevel@tonic-gate 		 * Get a file descriptor that's read-only so that this code
4287c478bd9Sstevel@tonic-gate 		 * doesn't accidentally write to the file.
4297c478bd9Sstevel@tonic-gate 		 */
4307c478bd9Sstevel@tonic-gate 		fso = open(fsys, O_RDONLY);
4317c478bd9Sstevel@tonic-gate 		if (fso < 0) {
4327c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, gettext("%s: cannot open\n"),
4337c478bd9Sstevel@tonic-gate 				fsys);
4347c478bd9Sstevel@tonic-gate 			exit(32);
4357c478bd9Sstevel@tonic-gate 		}
4367c478bd9Sstevel@tonic-gate 	}
4377c478bd9Sstevel@tonic-gate 
4387c478bd9Sstevel@tonic-gate 
4397c478bd9Sstevel@tonic-gate 	/*
4407c478bd9Sstevel@tonic-gate 	 * Validate the given file system size.
4417c478bd9Sstevel@tonic-gate 	 * Verify that its last block can actually be accessed.
4427c478bd9Sstevel@tonic-gate 	 */
4437c478bd9Sstevel@tonic-gate 	fssize = fssize / (sectorsize / DEV_BSIZE);
4447c478bd9Sstevel@tonic-gate 	if (fssize <= 0) {
4457c478bd9Sstevel@tonic-gate 		(void) fprintf(stdout,
4467c478bd9Sstevel@tonic-gate 			gettext("preposterous size %d. sectors\n"), fssize);
4477c478bd9Sstevel@tonic-gate 		exit(32);
4487c478bd9Sstevel@tonic-gate 	}
4497c478bd9Sstevel@tonic-gate 	fssize --;
4507c478bd9Sstevel@tonic-gate 
4517c478bd9Sstevel@tonic-gate 	/*
4527c478bd9Sstevel@tonic-gate 	 * verify device size
4537c478bd9Sstevel@tonic-gate 	 */
4547c478bd9Sstevel@tonic-gate 	rdfs(fssize - 1, sectorsize, buf);
4557c478bd9Sstevel@tonic-gate 
4567c478bd9Sstevel@tonic-gate 	if ((sectorsize < DEV_BSIZE) ||
4577c478bd9Sstevel@tonic-gate 		(sectorsize > MAXBSIZE)) {
4587c478bd9Sstevel@tonic-gate 		(void) fprintf(stdout,
4597c478bd9Sstevel@tonic-gate 			gettext("sector size must be"
4607c478bd9Sstevel@tonic-gate 			" between 512, 8192 bytes\n"));
4617c478bd9Sstevel@tonic-gate 	}
4627c478bd9Sstevel@tonic-gate 	if (!POWEROF2(sectorsize)) {
4637c478bd9Sstevel@tonic-gate 		(void) fprintf(stdout,
4647c478bd9Sstevel@tonic-gate 			gettext("sector size must be a power of 2, not %d\n"),
4657c478bd9Sstevel@tonic-gate 			sectorsize);
4667c478bd9Sstevel@tonic-gate 		exit(32);
4677c478bd9Sstevel@tonic-gate 	}
4687c478bd9Sstevel@tonic-gate 	if (Nflag) {
4697c478bd9Sstevel@tonic-gate 		exit(0);
4707c478bd9Sstevel@tonic-gate 	}
4717c478bd9Sstevel@tonic-gate 
4727c478bd9Sstevel@tonic-gate 	(void) printf(gettext("Creating file system with sector size of "
4737c478bd9Sstevel@tonic-gate 		"%d bytes\n"), sectorsize);
4747c478bd9Sstevel@tonic-gate 
4757c478bd9Sstevel@tonic-gate 	/*
4767c478bd9Sstevel@tonic-gate 	 * Set up time stamp values
4777c478bd9Sstevel@tonic-gate 	 */
4787c478bd9Sstevel@tonic-gate 	mkfstime = time(0);
4797c478bd9Sstevel@tonic-gate 	(void) localtime_r(&mkfstime, &res);
4807c478bd9Sstevel@tonic-gate 	if (res.tm_isdst > 0) {
4817c478bd9Sstevel@tonic-gate 		tzone = altzone / 60;
4827c478bd9Sstevel@tonic-gate 	} else if (res.tm_isdst == 0) {
4837c478bd9Sstevel@tonic-gate 		tzone = tzone / 60;
4847c478bd9Sstevel@tonic-gate 	} else {
4857c478bd9Sstevel@tonic-gate 		tzone = 2047;	/* Unknown */
4867c478bd9Sstevel@tonic-gate 	}
4877c478bd9Sstevel@tonic-gate 
4887c478bd9Sstevel@tonic-gate 	/*
4897c478bd9Sstevel@tonic-gate 	 * Initialize the volume recognition sequence, the volume descriptor
4907c478bd9Sstevel@tonic-gate 	 * sequences and the anchor pointer.
4917c478bd9Sstevel@tonic-gate 	 */
4927c478bd9Sstevel@tonic-gate 	volseqinit();
4937c478bd9Sstevel@tonic-gate 
4947c478bd9Sstevel@tonic-gate 	(void) fsync(fso);
4957c478bd9Sstevel@tonic-gate 	(void) close(fsi);
4967c478bd9Sstevel@tonic-gate 	(void) close(fso);
4977c478bd9Sstevel@tonic-gate 
4987c478bd9Sstevel@tonic-gate 	return (0);
4997c478bd9Sstevel@tonic-gate }
5007c478bd9Sstevel@tonic-gate 
5017c478bd9Sstevel@tonic-gate static void
5027c478bd9Sstevel@tonic-gate setstamp(tstamp_t *tp)
5037c478bd9Sstevel@tonic-gate {
5047c478bd9Sstevel@tonic-gate 	tp->ts_usec = 0;
5057c478bd9Sstevel@tonic-gate 	tp->ts_husec = 0;
5067c478bd9Sstevel@tonic-gate 	tp->ts_csec = 0;
5077c478bd9Sstevel@tonic-gate 
5087c478bd9Sstevel@tonic-gate 	tp->ts_sec = res.tm_sec;
5097c478bd9Sstevel@tonic-gate 	tp->ts_min = res.tm_min;
5107c478bd9Sstevel@tonic-gate 	tp->ts_hour = res.tm_hour;
5117c478bd9Sstevel@tonic-gate 	tp->ts_day = res.tm_mday;
5127c478bd9Sstevel@tonic-gate 	tp->ts_month = res.tm_mon + 1;
5137c478bd9Sstevel@tonic-gate 	tp->ts_year = 1900 + res.tm_year;
5147c478bd9Sstevel@tonic-gate 
5157c478bd9Sstevel@tonic-gate 	tp->ts_tzone = 0x1000 + (-tzone & 0xFFF);
5167c478bd9Sstevel@tonic-gate }
5177c478bd9Sstevel@tonic-gate 
5187c478bd9Sstevel@tonic-gate static void
5197c478bd9Sstevel@tonic-gate setextad(extent_ad_t *eap, uint32_t len, uint32_t loc)
5207c478bd9Sstevel@tonic-gate {
5217c478bd9Sstevel@tonic-gate 	eap->ext_len = len;
5227c478bd9Sstevel@tonic-gate 	eap->ext_loc = loc;
5237c478bd9Sstevel@tonic-gate }
5247c478bd9Sstevel@tonic-gate 
5257c478bd9Sstevel@tonic-gate static void
5267c478bd9Sstevel@tonic-gate setdstring(dstring_t *dp, char *cp, int len)
5277c478bd9Sstevel@tonic-gate {
5287c478bd9Sstevel@tonic-gate 	int32_t length;
5297c478bd9Sstevel@tonic-gate 
5307c478bd9Sstevel@tonic-gate 	bzero(dp, len);
5317c478bd9Sstevel@tonic-gate 	length = strlen(cp);
5327c478bd9Sstevel@tonic-gate 	if (length > len - 3) {
5337c478bd9Sstevel@tonic-gate 		length = len - 3;
5347c478bd9Sstevel@tonic-gate 	}
5357c478bd9Sstevel@tonic-gate 	dp[len - 1] = length + 1;
5367c478bd9Sstevel@tonic-gate 	*dp++ = 8;
5377c478bd9Sstevel@tonic-gate 	(void) strncpy(dp, cp, len-2);
5387c478bd9Sstevel@tonic-gate }
5397c478bd9Sstevel@tonic-gate 
5407c478bd9Sstevel@tonic-gate static void
5417c478bd9Sstevel@tonic-gate wtvolseq(tag_t *tp, daddr_t blk1, daddr_t blk2)
5427c478bd9Sstevel@tonic-gate {
5437c478bd9Sstevel@tonic-gate 	static uint32_t vdsn = 0;
5447c478bd9Sstevel@tonic-gate 
5457c478bd9Sstevel@tonic-gate 	tp->tag_loc = blk1;
5467c478bd9Sstevel@tonic-gate 	switch (tp->tag_id) {
5477c478bd9Sstevel@tonic-gate 	case UD_PRI_VOL_DESC :
5487c478bd9Sstevel@tonic-gate 		((struct pri_vol_desc *)tp)->pvd_vdsn = vdsn++;
5497c478bd9Sstevel@tonic-gate 		break;
5507c478bd9Sstevel@tonic-gate 	case UD_VOL_DESC_PTR :
5517c478bd9Sstevel@tonic-gate 		((struct vol_desc_ptr *)tp)->vdp_vdsn = vdsn++;
5527c478bd9Sstevel@tonic-gate 		break;
5537c478bd9Sstevel@tonic-gate 	case UD_IMPL_USE_DESC :
5547c478bd9Sstevel@tonic-gate 		((struct iuvd_desc *)tp)->iuvd_vdsn = vdsn++;
5557c478bd9Sstevel@tonic-gate 		break;
5567c478bd9Sstevel@tonic-gate 	case UD_PART_DESC :
5577c478bd9Sstevel@tonic-gate 		((struct part_desc *)tp)->pd_vdsn = vdsn++;
5587c478bd9Sstevel@tonic-gate 		break;
5597c478bd9Sstevel@tonic-gate 	case UD_LOG_VOL_DESC :
5607c478bd9Sstevel@tonic-gate 		((struct log_vol_desc *)tp)->lvd_vdsn = vdsn++;
5617c478bd9Sstevel@tonic-gate 		break;
5627c478bd9Sstevel@tonic-gate 	case UD_UNALL_SPA_DESC :
5637c478bd9Sstevel@tonic-gate 		((struct unall_spc_desc *)tp)->ua_vdsn = vdsn++;
5647c478bd9Sstevel@tonic-gate 		break;
5657c478bd9Sstevel@tonic-gate 	}
5667c478bd9Sstevel@tonic-gate 
5677c478bd9Sstevel@tonic-gate 	bzero(buf2, sectorsize);
5687c478bd9Sstevel@tonic-gate 	/* LINTED */
5697c478bd9Sstevel@tonic-gate 	maketag(tp, (struct tag *)buf2);
5707c478bd9Sstevel@tonic-gate 
5717c478bd9Sstevel@tonic-gate 	/*
5727c478bd9Sstevel@tonic-gate 	 * Write at Main Volume Descriptor Sequence
5737c478bd9Sstevel@tonic-gate 	 */
5747c478bd9Sstevel@tonic-gate 	wtfs(blk1, sectorsize, buf2);
5757c478bd9Sstevel@tonic-gate 
5767c478bd9Sstevel@tonic-gate 	tp->tag_loc = blk2;
5777c478bd9Sstevel@tonic-gate 	switch (tp->tag_id) {
5787c478bd9Sstevel@tonic-gate 	case UD_PRI_VOL_DESC :
5797c478bd9Sstevel@tonic-gate 		((struct pri_vol_desc *)tp)->pvd_vdsn = vdsn++;
5807c478bd9Sstevel@tonic-gate 		break;
5817c478bd9Sstevel@tonic-gate 	case UD_VOL_DESC_PTR :
5827c478bd9Sstevel@tonic-gate 		((struct vol_desc_ptr *)tp)->vdp_vdsn = vdsn++;
5837c478bd9Sstevel@tonic-gate 		break;
5847c478bd9Sstevel@tonic-gate 	case UD_IMPL_USE_DESC :
5857c478bd9Sstevel@tonic-gate 		((struct iuvd_desc *)tp)->iuvd_vdsn = vdsn++;
5867c478bd9Sstevel@tonic-gate 		break;
5877c478bd9Sstevel@tonic-gate 	case UD_PART_DESC :
5887c478bd9Sstevel@tonic-gate 		((struct part_desc *)tp)->pd_vdsn = vdsn++;
5897c478bd9Sstevel@tonic-gate 		break;
5907c478bd9Sstevel@tonic-gate 	case UD_LOG_VOL_DESC :
5917c478bd9Sstevel@tonic-gate 		((struct log_vol_desc *)tp)->lvd_vdsn = vdsn++;
5927c478bd9Sstevel@tonic-gate 		break;
5937c478bd9Sstevel@tonic-gate 	case UD_UNALL_SPA_DESC :
5947c478bd9Sstevel@tonic-gate 		((struct unall_spc_desc *)tp)->ua_vdsn = vdsn++;
5957c478bd9Sstevel@tonic-gate 		break;
5967c478bd9Sstevel@tonic-gate 	}
5977c478bd9Sstevel@tonic-gate 	maketag(tp, tp);
5987c478bd9Sstevel@tonic-gate 	/*
5997c478bd9Sstevel@tonic-gate 	 * Write at Reserve Volume Descriptor Sequence
6007c478bd9Sstevel@tonic-gate 	 */
6017c478bd9Sstevel@tonic-gate 	wtfs(blk2, sectorsize, buf);
6027c478bd9Sstevel@tonic-gate }
6037c478bd9Sstevel@tonic-gate 
6047c478bd9Sstevel@tonic-gate static void
6057c478bd9Sstevel@tonic-gate volseqinit()
6067c478bd9Sstevel@tonic-gate {
6077c478bd9Sstevel@tonic-gate 	struct tag *tp;
6087c478bd9Sstevel@tonic-gate 	struct nsr_desc *nsp;
6097c478bd9Sstevel@tonic-gate 	struct pri_vol_desc *pvdp;
6107c478bd9Sstevel@tonic-gate 	struct iuvd_desc *iudp;
6117c478bd9Sstevel@tonic-gate 	struct part_desc *pp;
6127c478bd9Sstevel@tonic-gate 	struct phdr_desc *php;
6137c478bd9Sstevel@tonic-gate 	struct log_vol_desc *lvp;
6147c478bd9Sstevel@tonic-gate 	long_ad_t *lap;
6157c478bd9Sstevel@tonic-gate 	struct pmap_typ1 *pmp;
6167c478bd9Sstevel@tonic-gate 	struct unall_spc_desc *uap;
6177c478bd9Sstevel@tonic-gate 	struct log_vol_int_desc *lvip;
6187c478bd9Sstevel@tonic-gate 	struct term_desc *tdp;
6197c478bd9Sstevel@tonic-gate 	struct anch_vol_desc_ptr *avp;
6207c478bd9Sstevel@tonic-gate 	struct lvid_iu *lviup;
6217c478bd9Sstevel@tonic-gate 	struct file_set_desc *fsp;
6227c478bd9Sstevel@tonic-gate 	struct file_entry *fp;
6237c478bd9Sstevel@tonic-gate 	struct icb_tag *icb;
6247c478bd9Sstevel@tonic-gate 	struct short_ad *sap;
6257c478bd9Sstevel@tonic-gate 	struct file_id *fip;
6267c478bd9Sstevel@tonic-gate 	struct space_bmap_desc *sbp;
6277c478bd9Sstevel@tonic-gate 	uint8_t *cp;
6287c478bd9Sstevel@tonic-gate 	daddr_t nextblock, endblock;
6297c478bd9Sstevel@tonic-gate 	int32_t volseq_sectors, nextlogblock, rootfelen, i;
6307c478bd9Sstevel@tonic-gate 	uint32_t mvds_loc, rvds_loc;
6317c478bd9Sstevel@tonic-gate 
6327c478bd9Sstevel@tonic-gate 	bzero(buf, MAXBSIZE);
6337c478bd9Sstevel@tonic-gate 
6347c478bd9Sstevel@tonic-gate 	/*
6357c478bd9Sstevel@tonic-gate 	 * Starting from MAXBSIZE, clear out till 256 sectors.
6367c478bd9Sstevel@tonic-gate 	 */
6377c478bd9Sstevel@tonic-gate 	for (i = MAXBSIZE / sectorsize; i < FIRSTAVDP; i++) {
6387c478bd9Sstevel@tonic-gate 		wtfs(i, sectorsize, buf);
6397c478bd9Sstevel@tonic-gate 	}
6407c478bd9Sstevel@tonic-gate 
6417c478bd9Sstevel@tonic-gate 	/* Zero out the avdp at N - 257 */
6427c478bd9Sstevel@tonic-gate 	wtfs(fssize - 256, sectorsize, buf);
6437c478bd9Sstevel@tonic-gate 
6447c478bd9Sstevel@tonic-gate 	/*
6457c478bd9Sstevel@tonic-gate 	 * Leave 1st 32K for O.S.
6467c478bd9Sstevel@tonic-gate 	 */
6477c478bd9Sstevel@tonic-gate 	nextblock = VOLRECSTART / sectorsize;
6487c478bd9Sstevel@tonic-gate 
6497c478bd9Sstevel@tonic-gate 	/*
6507c478bd9Sstevel@tonic-gate 	 * Write BEA01/NSR02/TEA01 sequence.
6517c478bd9Sstevel@tonic-gate 	 * Each one must be 2K bytes in length.
6527c478bd9Sstevel@tonic-gate 	 */
6537c478bd9Sstevel@tonic-gate 	nsp = (struct nsr_desc *)buf;
6547c478bd9Sstevel@tonic-gate 	nsp->nsr_str_type = 0;
6557c478bd9Sstevel@tonic-gate 	nsp->nsr_ver = 1;
6567c478bd9Sstevel@tonic-gate 	(void) strncpy((int8_t *)nsp->nsr_id, "BEA01", 5);
6577c478bd9Sstevel@tonic-gate 
6587c478bd9Sstevel@tonic-gate 	nsp = (struct nsr_desc *)&buf[2048];
6597c478bd9Sstevel@tonic-gate 	nsp->nsr_str_type = 0;
6607c478bd9Sstevel@tonic-gate 	nsp->nsr_ver = 1;
6617c478bd9Sstevel@tonic-gate 	(void) strncpy((int8_t *)nsp->nsr_id, "NSR02", 5);
6627c478bd9Sstevel@tonic-gate 
6637c478bd9Sstevel@tonic-gate 	nsp = (struct nsr_desc *)&buf[4096];
6647c478bd9Sstevel@tonic-gate 	nsp->nsr_str_type = 0;
6657c478bd9Sstevel@tonic-gate 	nsp->nsr_ver = 1;
6667c478bd9Sstevel@tonic-gate 	(void) strncpy((int8_t *)nsp->nsr_id, "TEA01", 5);
6677c478bd9Sstevel@tonic-gate 
6687c478bd9Sstevel@tonic-gate 	wtfs(nextblock, 8192, buf);
6697c478bd9Sstevel@tonic-gate 	bzero(buf, MAXBSIZE);
6707c478bd9Sstevel@tonic-gate 
6717c478bd9Sstevel@tonic-gate 	/*
6727c478bd9Sstevel@tonic-gate 	 * Minimum length of volume sequences
6737c478bd9Sstevel@tonic-gate 	 */
6747c478bd9Sstevel@tonic-gate 	volseq_sectors = 16;
6757c478bd9Sstevel@tonic-gate 
6767c478bd9Sstevel@tonic-gate 	/*
6777c478bd9Sstevel@tonic-gate 	 * Round up to next 32K boundary for
6787c478bd9Sstevel@tonic-gate 	 * volume descriptor sequences
6797c478bd9Sstevel@tonic-gate 	 */
6807c478bd9Sstevel@tonic-gate 	nextblock = VOLSEQSTART;
6817c478bd9Sstevel@tonic-gate 	bzero(buf, sectorsize);
6827c478bd9Sstevel@tonic-gate 	mvds_loc = VOLSEQSTART;
6837c478bd9Sstevel@tonic-gate 	rvds_loc = mvds_loc + volseq_sectors;
6847c478bd9Sstevel@tonic-gate 
6857c478bd9Sstevel@tonic-gate 	/*
6867c478bd9Sstevel@tonic-gate 	 * Primary Volume Descriptor
6877c478bd9Sstevel@tonic-gate 	 */
6887c478bd9Sstevel@tonic-gate 	/* LINTED */
6897c478bd9Sstevel@tonic-gate 	pvdp = (struct pri_vol_desc *)buf;
6907c478bd9Sstevel@tonic-gate 	tp = &pvdp->pvd_tag;
6917c478bd9Sstevel@tonic-gate 	tp->tag_id =  UD_PRI_VOL_DESC;
6927c478bd9Sstevel@tonic-gate 	tp->tag_desc_ver = ecma_version;
6937c478bd9Sstevel@tonic-gate 	tp->tag_sno = serialnum;
6947c478bd9Sstevel@tonic-gate 	tp->tag_crc_len = sizeof (struct pri_vol_desc) -
6957c478bd9Sstevel@tonic-gate 			sizeof (struct tag);
6967c478bd9Sstevel@tonic-gate 	pvdp->pvd_vdsn = 0;
6977c478bd9Sstevel@tonic-gate 	pvdp->pvd_pvdn = 0;
6987c478bd9Sstevel@tonic-gate 	setdstring(pvdp->pvd_vol_id, udfs_label, 32);
6997c478bd9Sstevel@tonic-gate 	pvdp->pvd_vsn = 1;
7007c478bd9Sstevel@tonic-gate 	pvdp->pvd_mvsn = 1;
7017c478bd9Sstevel@tonic-gate 	pvdp->pvd_il = 2;		/* Single-volume */
7027c478bd9Sstevel@tonic-gate 	pvdp->pvd_mil = 3;		/* Multi-volume */
7037c478bd9Sstevel@tonic-gate 	pvdp->pvd_csl = 1;		/* CS0 */
7047c478bd9Sstevel@tonic-gate 	pvdp->pvd_mcsl = 1;		/* CS0 */
7057c478bd9Sstevel@tonic-gate 	(void) sprintf(vsibuf, "%08X", SWAP_32((uint32_t)mkfstime));
7067c478bd9Sstevel@tonic-gate 	setdstring(pvdp->pvd_vsi, vsibuf, 128);
7077c478bd9Sstevel@tonic-gate 	(void) strncpy(pvdp->pvd_vsi + 17, udfs_label, 128 - 17);
7087c478bd9Sstevel@tonic-gate 	setcharspec(&pvdp->pvd_desc_cs, 0, osta_unicode);
7097c478bd9Sstevel@tonic-gate 	setcharspec(&pvdp->pvd_exp_cs, 0, osta_unicode);
7107c478bd9Sstevel@tonic-gate 	setextad(&pvdp->pvd_vol_abs, 0, 0);
7117c478bd9Sstevel@tonic-gate 	setextad(&pvdp->pvd_vcn, 0, 0);
7127c478bd9Sstevel@tonic-gate 	bzero(&pvdp->pvd_appl_id, sizeof (regid_t));
7137c478bd9Sstevel@tonic-gate 	setstamp(&pvdp->pvd_time);
7147c478bd9Sstevel@tonic-gate 	bcopy(&sunmicro, &pvdp->pvd_ii, sizeof (regid_t));
7157c478bd9Sstevel@tonic-gate 	pvdp->pvd_flags = 0;
7167c478bd9Sstevel@tonic-gate 	wtvolseq(tp, nextblock, nextblock + volseq_sectors);
7177c478bd9Sstevel@tonic-gate 	nextblock++;
7187c478bd9Sstevel@tonic-gate 
7197c478bd9Sstevel@tonic-gate 	/*
7207c478bd9Sstevel@tonic-gate 	 * Implementation Use Descriptor
7217c478bd9Sstevel@tonic-gate 	 */
7227c478bd9Sstevel@tonic-gate 	bzero(buf, sectorsize);
7237c478bd9Sstevel@tonic-gate 	/* LINTED */
7247c478bd9Sstevel@tonic-gate 	iudp = (struct iuvd_desc *)buf;
7257c478bd9Sstevel@tonic-gate 	tp = &iudp->iuvd_tag;
7267c478bd9Sstevel@tonic-gate 	tp->tag_id =  UD_IMPL_USE_DESC;
7277c478bd9Sstevel@tonic-gate 	tp->tag_desc_ver = ecma_version;
7287c478bd9Sstevel@tonic-gate 	tp->tag_sno = serialnum;
7297c478bd9Sstevel@tonic-gate 	tp->tag_crc_len = sizeof (struct iuvd_desc) -
7307c478bd9Sstevel@tonic-gate 			sizeof (struct tag);
7317c478bd9Sstevel@tonic-gate 	iudp->iuvd_vdsn = 0;
7327c478bd9Sstevel@tonic-gate 	bcopy(&lvinfo, &iudp->iuvd_ii, sizeof (regid_t));
7337c478bd9Sstevel@tonic-gate 	setcharspec(&iudp->iuvd_cset, 0, osta_unicode);
7347c478bd9Sstevel@tonic-gate 	setdstring(iudp->iuvd_lvi, udfs_label, 128);
7357c478bd9Sstevel@tonic-gate 
7367c478bd9Sstevel@tonic-gate 	setdstring(iudp->iuvd_ifo1, "", 36);
7377c478bd9Sstevel@tonic-gate 	setdstring(iudp->iuvd_ifo2, "", 36);
7387c478bd9Sstevel@tonic-gate 	setdstring(iudp->iuvd_ifo3, "", 36);
7397c478bd9Sstevel@tonic-gate 
7407c478bd9Sstevel@tonic-gate 
7417c478bd9Sstevel@tonic-gate 	/*
7427c478bd9Sstevel@tonic-gate 	 * info1,2,3 = user specified
7437c478bd9Sstevel@tonic-gate 	 */
7447c478bd9Sstevel@tonic-gate 	bcopy(&sunmicro, &iudp->iuvd_iid, sizeof (regid_t));
7457c478bd9Sstevel@tonic-gate 	wtvolseq(tp, nextblock, nextblock + volseq_sectors);
7467c478bd9Sstevel@tonic-gate 	nextblock++;
7477c478bd9Sstevel@tonic-gate 
7487c478bd9Sstevel@tonic-gate 	/*
7497c478bd9Sstevel@tonic-gate 	 * Partition Descriptor
7507c478bd9Sstevel@tonic-gate 	 */
7517c478bd9Sstevel@tonic-gate 	bzero(buf, sectorsize);
7527c478bd9Sstevel@tonic-gate 	/* LINTED */
7537c478bd9Sstevel@tonic-gate 	pp = (struct part_desc *)buf;
7547c478bd9Sstevel@tonic-gate 	tp = &pp->pd_tag;
7557c478bd9Sstevel@tonic-gate 	tp->tag_id =  UD_PART_DESC;
7567c478bd9Sstevel@tonic-gate 	tp->tag_desc_ver = ecma_version;
7577c478bd9Sstevel@tonic-gate 	tp->tag_sno = serialnum;
7587c478bd9Sstevel@tonic-gate 	tp->tag_crc_len = sizeof (struct part_desc) -
7597c478bd9Sstevel@tonic-gate 			sizeof (struct tag);
7607c478bd9Sstevel@tonic-gate 	pp->pd_vdsn = 0;
7617c478bd9Sstevel@tonic-gate 	pp->pd_pflags = 1;			/* Allocated */
7627c478bd9Sstevel@tonic-gate 	pp->pd_pnum = 0;
7637c478bd9Sstevel@tonic-gate 	bcopy(&partid, &pp->pd_pcontents, sizeof (regid_t));
7647c478bd9Sstevel@tonic-gate 
7657c478bd9Sstevel@tonic-gate 	part_start = FIRSTAVDP + AVDPLEN;
7667c478bd9Sstevel@tonic-gate 	part_len = fssize - part_start;
7677c478bd9Sstevel@tonic-gate 	part_bmp_bytes = (part_len + NBBY - 1) / NBBY;
7687c478bd9Sstevel@tonic-gate 	part_bmp_sectors = (part_bmp_bytes + SPACEMAP_OFF + sectorsize - 1) /
7697c478bd9Sstevel@tonic-gate 		sectorsize;
7707c478bd9Sstevel@tonic-gate 
7717c478bd9Sstevel@tonic-gate 	pp->pd_part_start = part_start;
7727c478bd9Sstevel@tonic-gate 	pp->pd_part_length = part_len;
7737c478bd9Sstevel@tonic-gate 
7747c478bd9Sstevel@tonic-gate 	pp->pd_acc_type = acctype;
7757c478bd9Sstevel@tonic-gate 	nextlogblock = 0;
7767c478bd9Sstevel@tonic-gate 
7777c478bd9Sstevel@tonic-gate 	/*
7787c478bd9Sstevel@tonic-gate 	 * Do the partition header
7797c478bd9Sstevel@tonic-gate 	 */
7807c478bd9Sstevel@tonic-gate 	/* LINTED */
7817c478bd9Sstevel@tonic-gate 	php = (struct phdr_desc *)&pp->pd_pc_use;
7827c478bd9Sstevel@tonic-gate 
7837c478bd9Sstevel@tonic-gate 	/*
7847c478bd9Sstevel@tonic-gate 	 * Set up unallocated space bitmap
7857c478bd9Sstevel@tonic-gate 	 */
7867c478bd9Sstevel@tonic-gate 	if (acctype == PART_ACC_RW || acctype == PART_ACC_OW) {
7877c478bd9Sstevel@tonic-gate 		php->phdr_usb.sad_ext_len =
7887c478bd9Sstevel@tonic-gate 			(part_bmp_bytes + SPACEMAP_OFF + sectorsize - 1) &
7897c478bd9Sstevel@tonic-gate 				(~(sectorsize - 1));
7907c478bd9Sstevel@tonic-gate 		php->phdr_usb.sad_ext_loc = nextlogblock;
7917c478bd9Sstevel@tonic-gate 		part_unalloc = nextlogblock;
7927c478bd9Sstevel@tonic-gate 		nextlogblock += part_bmp_sectors;
7937c478bd9Sstevel@tonic-gate 	}
7947c478bd9Sstevel@tonic-gate 
7957c478bd9Sstevel@tonic-gate 	bcopy(&sunmicro, &pp->pd_ii, sizeof (regid_t));
7967c478bd9Sstevel@tonic-gate 	wtvolseq(tp, nextblock, nextblock + volseq_sectors);
7977c478bd9Sstevel@tonic-gate 	nextblock++;
7987c478bd9Sstevel@tonic-gate 
7997c478bd9Sstevel@tonic-gate 	/*
8007c478bd9Sstevel@tonic-gate 	 * Logical Volume Descriptor
8017c478bd9Sstevel@tonic-gate 	 */
8027c478bd9Sstevel@tonic-gate 	bzero(buf, sectorsize);
8037c478bd9Sstevel@tonic-gate 	/* LINTED */
8047c478bd9Sstevel@tonic-gate 	lvp = (struct log_vol_desc *)buf;
8057c478bd9Sstevel@tonic-gate 	tp = &lvp->lvd_tag;
8067c478bd9Sstevel@tonic-gate 	tp->tag_id =  UD_LOG_VOL_DESC;
8077c478bd9Sstevel@tonic-gate 	tp->tag_desc_ver = ecma_version;
8087c478bd9Sstevel@tonic-gate 	tp->tag_sno = serialnum;
8097c478bd9Sstevel@tonic-gate 	tp->tag_crc_len = sizeof (struct log_vol_desc) -
8107c478bd9Sstevel@tonic-gate 			sizeof (struct tag);
8117c478bd9Sstevel@tonic-gate 	lvp->lvd_vdsn = 0;
8127c478bd9Sstevel@tonic-gate 	setcharspec(&lvp->lvd_desc_cs, 0, osta_unicode);
8137c478bd9Sstevel@tonic-gate 	setdstring(lvp->lvd_lvid, udfs_label, 128);
8147c478bd9Sstevel@tonic-gate 	lvp->lvd_log_bsize = sectorsize;
8157c478bd9Sstevel@tonic-gate 	bcopy(&udf_compliant, &lvp->lvd_dom_id, sizeof (regid_t));
8167c478bd9Sstevel@tonic-gate 	lap = (long_ad_t *)&lvp->lvd_lvcu;
8177c478bd9Sstevel@tonic-gate 	lap->lad_ext_len = FILESETLEN * sectorsize;
8187c478bd9Sstevel@tonic-gate 	filesetblock = nextlogblock;
8197c478bd9Sstevel@tonic-gate 	lap->lad_ext_loc = nextlogblock;
8207c478bd9Sstevel@tonic-gate 	lap->lad_ext_prn = 0;
8217c478bd9Sstevel@tonic-gate 	lvp->lvd_mtbl_len = 6;
8227c478bd9Sstevel@tonic-gate 	lvp->lvd_num_pmaps = 1;
8237c478bd9Sstevel@tonic-gate 	bcopy(&sunmicro, &lvp->lvd_ii, sizeof (regid_t));
8247c478bd9Sstevel@tonic-gate 	/* LINTED */
8257c478bd9Sstevel@tonic-gate 	pmp = (struct pmap_typ1 *)&lvp->lvd_pmaps;
8267c478bd9Sstevel@tonic-gate 	pmp->map1_type = 1;
8277c478bd9Sstevel@tonic-gate 	pmp->map1_length = 6;
8287c478bd9Sstevel@tonic-gate 	pmp->map1_vsn = SWAP_16(1);
8297c478bd9Sstevel@tonic-gate 	pmp->map1_pn  = 0;
8307c478bd9Sstevel@tonic-gate 	tp->tag_crc_len = (char *)(pmp + 1) - buf - sizeof (struct tag);
8317c478bd9Sstevel@tonic-gate 	setextad(&lvp->lvd_int_seq_ext, INTSEQLEN, INTSEQSTART);
8327c478bd9Sstevel@tonic-gate 	wtvolseq(tp, nextblock, nextblock + volseq_sectors);
8337c478bd9Sstevel@tonic-gate 	nextblock++;
8347c478bd9Sstevel@tonic-gate 
8357c478bd9Sstevel@tonic-gate 	/*
8367c478bd9Sstevel@tonic-gate 	 * Unallocated Space Descriptor
8377c478bd9Sstevel@tonic-gate 	 */
8387c478bd9Sstevel@tonic-gate 	bzero(buf, sectorsize);
8397c478bd9Sstevel@tonic-gate 	/* LINTED */
8407c478bd9Sstevel@tonic-gate 	uap = (struct unall_spc_desc *)buf;
8417c478bd9Sstevel@tonic-gate 	tp = &uap->ua_tag;
8427c478bd9Sstevel@tonic-gate 	tp->tag_id =  UD_UNALL_SPA_DESC;
8437c478bd9Sstevel@tonic-gate 	tp->tag_desc_ver = ecma_version;
8447c478bd9Sstevel@tonic-gate 	tp->tag_sno = serialnum;
8457c478bd9Sstevel@tonic-gate 	uap->ua_vdsn = 0;
8467c478bd9Sstevel@tonic-gate 	uap->ua_nad = 0;
8477c478bd9Sstevel@tonic-gate 	tp->tag_crc_len = (char *)uap->ua_al_dsc - buf - sizeof (struct tag);
8487c478bd9Sstevel@tonic-gate 	wtvolseq(tp, nextblock, nextblock + volseq_sectors);
8497c478bd9Sstevel@tonic-gate 	nextblock++;
8507c478bd9Sstevel@tonic-gate 
8517c478bd9Sstevel@tonic-gate 	/*
8527c478bd9Sstevel@tonic-gate 	 * Terminating Descriptor
8537c478bd9Sstevel@tonic-gate 	 */
8547c478bd9Sstevel@tonic-gate 	bzero(buf, sectorsize);
8557c478bd9Sstevel@tonic-gate 	/* LINTED */
8567c478bd9Sstevel@tonic-gate 	tdp = (struct term_desc *)buf;
8577c478bd9Sstevel@tonic-gate 	tp = &tdp->td_tag;
8587c478bd9Sstevel@tonic-gate 	tp->tag_id =  UD_TERM_DESC;
8597c478bd9Sstevel@tonic-gate 	tp->tag_desc_ver = ecma_version;
8607c478bd9Sstevel@tonic-gate 	tp->tag_sno = serialnum;
8617c478bd9Sstevel@tonic-gate 	tp->tag_crc_len = sizeof (struct term_desc) -
8627c478bd9Sstevel@tonic-gate 			sizeof (struct tag);
8637c478bd9Sstevel@tonic-gate 	tp->tag_loc = nextblock;
8647c478bd9Sstevel@tonic-gate 	wtvolseq(tp, nextblock, nextblock + volseq_sectors);
8657c478bd9Sstevel@tonic-gate 	nextblock++;
8667c478bd9Sstevel@tonic-gate 
8677c478bd9Sstevel@tonic-gate 	/*
8687c478bd9Sstevel@tonic-gate 	 * Do the anchor volume descriptor
8697c478bd9Sstevel@tonic-gate 	 */
8707c478bd9Sstevel@tonic-gate 	if (nextblock > FIRSTAVDP) {
8717c478bd9Sstevel@tonic-gate 		(void) fprintf(stdout,
8727c478bd9Sstevel@tonic-gate 			gettext("Volume integrity sequence"
8737c478bd9Sstevel@tonic-gate 			" descriptors too long\n"));
8747c478bd9Sstevel@tonic-gate 		exit(32);
8757c478bd9Sstevel@tonic-gate 	}
8767c478bd9Sstevel@tonic-gate 
8777c478bd9Sstevel@tonic-gate 	nextblock = FIRSTAVDP;
8787c478bd9Sstevel@tonic-gate 	bzero(buf, sectorsize);
8797c478bd9Sstevel@tonic-gate 	/* LINTED */
8807c478bd9Sstevel@tonic-gate 	avp = (struct anch_vol_desc_ptr *)buf;
8817c478bd9Sstevel@tonic-gate 	tp = &avp->avd_tag;
8827c478bd9Sstevel@tonic-gate 	tp->tag_id =  UD_ANCH_VOL_DESC;
8837c478bd9Sstevel@tonic-gate 	tp->tag_desc_ver = ecma_version;
8847c478bd9Sstevel@tonic-gate 	tp->tag_sno = serialnum;
8857c478bd9Sstevel@tonic-gate 	tp->tag_crc_len = sizeof (struct anch_vol_desc_ptr) -
8867c478bd9Sstevel@tonic-gate 			sizeof (struct tag);
8877c478bd9Sstevel@tonic-gate 	tp->tag_loc = nextblock;
8887c478bd9Sstevel@tonic-gate 	setextad(&avp->avd_main_vdse,
8897c478bd9Sstevel@tonic-gate 			volseq_sectors * sectorsize, mvds_loc);
8907c478bd9Sstevel@tonic-gate 	setextad(&avp->avd_res_vdse,
8917c478bd9Sstevel@tonic-gate 			volseq_sectors * sectorsize, rvds_loc);
8927c478bd9Sstevel@tonic-gate 	bzero(buf2, sectorsize);
8937c478bd9Sstevel@tonic-gate 	/* LINTED */
8947c478bd9Sstevel@tonic-gate 	maketag(tp, (struct tag *)buf2);
8957c478bd9Sstevel@tonic-gate 	wtfs(nextblock, sectorsize, buf2);
8967c478bd9Sstevel@tonic-gate 	nextblock++;
8977c478bd9Sstevel@tonic-gate 
8987c478bd9Sstevel@tonic-gate 	tp->tag_loc = fssize;
8997c478bd9Sstevel@tonic-gate 	/* LINTED */
9007c478bd9Sstevel@tonic-gate 	maketag(tp, (struct tag *)buf2);
9017c478bd9Sstevel@tonic-gate 	wtfs(fssize, sectorsize, buf2);
9027c478bd9Sstevel@tonic-gate 
9037c478bd9Sstevel@tonic-gate 	/*
9047c478bd9Sstevel@tonic-gate 	 * File Set Descriptor
9057c478bd9Sstevel@tonic-gate 	 */
9067c478bd9Sstevel@tonic-gate 	bzero(buf, sectorsize);
9077c478bd9Sstevel@tonic-gate 	/* LINTED */
9087c478bd9Sstevel@tonic-gate 	fsp = (struct file_set_desc *)&buf;
9097c478bd9Sstevel@tonic-gate 	tp = &fsp->fsd_tag;
9107c478bd9Sstevel@tonic-gate 	tp->tag_id =  UD_FILE_SET_DESC;
9117c478bd9Sstevel@tonic-gate 	tp->tag_desc_ver = ecma_version;
9127c478bd9Sstevel@tonic-gate 	tp->tag_sno = serialnum;
9137c478bd9Sstevel@tonic-gate 	tp->tag_crc_len = sizeof (struct file_set_desc) -
9147c478bd9Sstevel@tonic-gate 			sizeof (struct tag);
9157c478bd9Sstevel@tonic-gate 	tp->tag_loc = nextlogblock;
9167c478bd9Sstevel@tonic-gate 	setstamp(&fsp->fsd_time);
9177c478bd9Sstevel@tonic-gate 	fsp->fsd_ilevel = 3;
9187c478bd9Sstevel@tonic-gate 	fsp->fsd_mi_level = 3;
9197c478bd9Sstevel@tonic-gate 	fsp->fsd_cs_list = 1;
9207c478bd9Sstevel@tonic-gate 	fsp->fsd_mcs_list = 1;
9217c478bd9Sstevel@tonic-gate 	fsp->fsd_fs_no = 0;
9227c478bd9Sstevel@tonic-gate 	fsp->fsd_fsd_no = 0;
9237c478bd9Sstevel@tonic-gate 	setcharspec(&fsp->fsd_lvidcs, 0, osta_unicode);
9247c478bd9Sstevel@tonic-gate 	setdstring(fsp->fsd_lvid, udfs_label, 128);
9257c478bd9Sstevel@tonic-gate 	setcharspec(&fsp->fsd_fscs, 0, osta_unicode);
9267c478bd9Sstevel@tonic-gate 	setdstring(fsp->fsd_fsi, udfs_label, 32);
9277c478bd9Sstevel@tonic-gate 	setdstring(fsp->fsd_cfi, "", 32);
9287c478bd9Sstevel@tonic-gate 	setdstring(fsp->fsd_afi, "", 32);
9297c478bd9Sstevel@tonic-gate 	lap = (long_ad_t *)&fsp->fsd_root_icb;
9307c478bd9Sstevel@tonic-gate 	lap->lad_ext_len = sectorsize;
9317c478bd9Sstevel@tonic-gate 	lap->lad_ext_loc = filesetblock + FILESETLEN;
9327c478bd9Sstevel@tonic-gate 	lap->lad_ext_prn = 0;
9337c478bd9Sstevel@tonic-gate 	bcopy(&udf_compliant, &fsp->fsd_did, sizeof (regid_t));
9347c478bd9Sstevel@tonic-gate 	maketag(tp, tp);
9357c478bd9Sstevel@tonic-gate 	wtfs(nextlogblock + part_start, sectorsize, (char *)tp);
9367c478bd9Sstevel@tonic-gate 	nextlogblock++;
9377c478bd9Sstevel@tonic-gate 
9387c478bd9Sstevel@tonic-gate 	/*
9397c478bd9Sstevel@tonic-gate 	 * Terminating Descriptor
9407c478bd9Sstevel@tonic-gate 	 */
9417c478bd9Sstevel@tonic-gate 	bzero(buf, sectorsize);
9427c478bd9Sstevel@tonic-gate 	/* LINTED */
9437c478bd9Sstevel@tonic-gate 	tdp = (struct term_desc *)buf;
9447c478bd9Sstevel@tonic-gate 	tp = &tdp->td_tag;
9457c478bd9Sstevel@tonic-gate 	tp->tag_id =  UD_TERM_DESC;
9467c478bd9Sstevel@tonic-gate 	tp->tag_desc_ver = ecma_version;
9477c478bd9Sstevel@tonic-gate 	tp->tag_sno = serialnum;
9487c478bd9Sstevel@tonic-gate 	tp->tag_crc_len = sizeof (struct term_desc) -
9497c478bd9Sstevel@tonic-gate 			sizeof (struct tag);
9507c478bd9Sstevel@tonic-gate 	tp->tag_loc = nextlogblock;
9517c478bd9Sstevel@tonic-gate 	maketag(tp, tp);
9527c478bd9Sstevel@tonic-gate 	wtfs(nextlogblock + part_start, sectorsize, (char *)tp);
9537c478bd9Sstevel@tonic-gate 	nextlogblock++;
9547c478bd9Sstevel@tonic-gate 
9557c478bd9Sstevel@tonic-gate 	if (nextlogblock > filesetblock + FILESETLEN) {
9567c478bd9Sstevel@tonic-gate 		(void) fprintf(stdout,
9577c478bd9Sstevel@tonic-gate 			gettext("File set descriptor too long\n"));
9587c478bd9Sstevel@tonic-gate 		exit(32);
9597c478bd9Sstevel@tonic-gate 	}
9607c478bd9Sstevel@tonic-gate 	nextlogblock = filesetblock + FILESETLEN;
9617c478bd9Sstevel@tonic-gate 
9627c478bd9Sstevel@tonic-gate 	/*
9637c478bd9Sstevel@tonic-gate 	 * Root File Entry
9647c478bd9Sstevel@tonic-gate 	 */
9657c478bd9Sstevel@tonic-gate 	bzero(buf, sectorsize);
9667c478bd9Sstevel@tonic-gate 	/* LINTED */
9677c478bd9Sstevel@tonic-gate 	fp = (struct file_entry *)&buf;
9687c478bd9Sstevel@tonic-gate 	tp = &fp->fe_tag;
9697c478bd9Sstevel@tonic-gate 	tp->tag_id =  UD_FILE_ENTRY;
9707c478bd9Sstevel@tonic-gate 	tp->tag_desc_ver = ecma_version;
9717c478bd9Sstevel@tonic-gate 	tp->tag_sno = serialnum;
9727c478bd9Sstevel@tonic-gate 	tp->tag_loc = nextlogblock;
9737c478bd9Sstevel@tonic-gate 	icb = &fp->fe_icb_tag;
9747c478bd9Sstevel@tonic-gate 	icb->itag_prnde = 0;
9757c478bd9Sstevel@tonic-gate 	icb->itag_strategy = STRAT_TYPE4;
9767c478bd9Sstevel@tonic-gate 	icb->itag_param = 0; /* what does this mean? */
9777c478bd9Sstevel@tonic-gate 	icb->itag_max_ent = 1;
9787c478bd9Sstevel@tonic-gate 	icb->itag_ftype = FTYPE_DIRECTORY;
9797c478bd9Sstevel@tonic-gate 	icb->itag_lb_loc = 0;
9807c478bd9Sstevel@tonic-gate 	icb->itag_lb_prn = 0;
9817c478bd9Sstevel@tonic-gate 	icb->itag_flags = ICB_FLAG_ARCHIVE;
9827c478bd9Sstevel@tonic-gate 	fp->fe_uid = getuid();
9837c478bd9Sstevel@tonic-gate 	fp->fe_gid = getgid();
9847c478bd9Sstevel@tonic-gate 	fp->fe_perms = (0x1f << 10) | (0x5 << 5) | 0x5;
9857c478bd9Sstevel@tonic-gate 	fp->fe_lcount = 1;
9867c478bd9Sstevel@tonic-gate 	fp->fe_rec_for = 0;
9877c478bd9Sstevel@tonic-gate 	fp->fe_rec_dis = 0;
9887c478bd9Sstevel@tonic-gate 	fp->fe_rec_len = 0;
9897c478bd9Sstevel@tonic-gate 	fp->fe_info_len = sizeof (struct file_id);
9907c478bd9Sstevel@tonic-gate 	fp->fe_lbr = 1;
9917c478bd9Sstevel@tonic-gate 	setstamp(&fp->fe_acc_time);
9927c478bd9Sstevel@tonic-gate 	setstamp(&fp->fe_mod_time);
9937c478bd9Sstevel@tonic-gate 	setstamp(&fp->fe_attr_time);
9947c478bd9Sstevel@tonic-gate 	fp->fe_ckpoint = 1;
9957c478bd9Sstevel@tonic-gate 	bcopy(&sunmicro, &fp->fe_impl_id, sizeof (regid_t));
9967c478bd9Sstevel@tonic-gate 	fp->fe_uniq_id = 0;
9977c478bd9Sstevel@tonic-gate 	fp->fe_len_ear = 0;
9987c478bd9Sstevel@tonic-gate 	fp->fe_len_adesc = sizeof (short_ad_t);
9997c478bd9Sstevel@tonic-gate 
10007c478bd9Sstevel@tonic-gate 	/* LINTED */
10017c478bd9Sstevel@tonic-gate 	sap = (short_ad_t *)(fp->fe_spec + fp->fe_len_ear);
10027c478bd9Sstevel@tonic-gate 	sap->sad_ext_len = sizeof (struct file_id);
10037c478bd9Sstevel@tonic-gate 	sap->sad_ext_loc = nextlogblock + 1;
10047c478bd9Sstevel@tonic-gate 	rootfelen = (char *)(sap + 1) - buf;
10057c478bd9Sstevel@tonic-gate 	tp->tag_crc_len = rootfelen - sizeof (struct tag);
10067c478bd9Sstevel@tonic-gate 	maketag(tp, tp);
10077c478bd9Sstevel@tonic-gate 	wtfs(nextlogblock + part_start, sectorsize, (char *)tp);
10087c478bd9Sstevel@tonic-gate 	nextlogblock++;
10097c478bd9Sstevel@tonic-gate 
10107c478bd9Sstevel@tonic-gate 	/*
10117c478bd9Sstevel@tonic-gate 	 * Root Directory
10127c478bd9Sstevel@tonic-gate 	 */
10137c478bd9Sstevel@tonic-gate 	bzero(buf, sectorsize);
10147c478bd9Sstevel@tonic-gate 	/* LINTED */
10157c478bd9Sstevel@tonic-gate 	fip = (struct file_id *)&buf;
10167c478bd9Sstevel@tonic-gate 	tp = &fip->fid_tag;
10177c478bd9Sstevel@tonic-gate 	tp->tag_id =  UD_FILE_ID_DESC;
10187c478bd9Sstevel@tonic-gate 	tp->tag_desc_ver = ecma_version;
10197c478bd9Sstevel@tonic-gate 	tp->tag_sno = serialnum;
10207c478bd9Sstevel@tonic-gate 	tp->tag_crc_len = sizeof (struct file_id) -
10217c478bd9Sstevel@tonic-gate 			sizeof (struct tag);
10227c478bd9Sstevel@tonic-gate 	tp->tag_loc = nextlogblock;
10237c478bd9Sstevel@tonic-gate 	fip->fid_ver = 1;
10247c478bd9Sstevel@tonic-gate 	fip->fid_flags = FID_DIR | FID_PARENT;
10257c478bd9Sstevel@tonic-gate 	fip->fid_idlen = 0;
10267c478bd9Sstevel@tonic-gate 	fip->fid_iulen = 0;
10277c478bd9Sstevel@tonic-gate 	fip->fid_icb.lad_ext_len = sectorsize; /* rootfelen; */
10287c478bd9Sstevel@tonic-gate 	fip->fid_icb.lad_ext_loc = nextlogblock - 1;
10297c478bd9Sstevel@tonic-gate 	fip->fid_icb.lad_ext_prn = 0;
10307c478bd9Sstevel@tonic-gate 	maketag(tp, tp);
10317c478bd9Sstevel@tonic-gate 	wtfs(nextlogblock + part_start, sectorsize, (char *)tp);
10327c478bd9Sstevel@tonic-gate 	nextlogblock++;
10337c478bd9Sstevel@tonic-gate 
10347c478bd9Sstevel@tonic-gate 	/*
10357c478bd9Sstevel@tonic-gate 	 * Now do the space bitmaps
10367c478bd9Sstevel@tonic-gate 	 */
10377c478bd9Sstevel@tonic-gate 	if (part_unalloc >= 0) {
10387c478bd9Sstevel@tonic-gate 		int size = sectorsize * part_bmp_sectors;
10397c478bd9Sstevel@tonic-gate 
10407c478bd9Sstevel@tonic-gate 		sbp = (struct space_bmap_desc *)malloc(size);
10417c478bd9Sstevel@tonic-gate 		if (!sbp) {
10427c478bd9Sstevel@tonic-gate 			(void) fprintf(stdout,
10437c478bd9Sstevel@tonic-gate 				gettext("Can't allocate bitmap space\n"));
10447c478bd9Sstevel@tonic-gate 			exit(32);
10457c478bd9Sstevel@tonic-gate 		}
10467c478bd9Sstevel@tonic-gate 		bzero((char *)sbp, sectorsize * part_bmp_sectors);
10477c478bd9Sstevel@tonic-gate 		tp = &sbp->sbd_tag;
10487c478bd9Sstevel@tonic-gate 		tp->tag_id =  UD_SPA_BMAP_DESC;
10497c478bd9Sstevel@tonic-gate 		tp->tag_desc_ver = ecma_version;
10507c478bd9Sstevel@tonic-gate 		tp->tag_sno = serialnum;
10517c478bd9Sstevel@tonic-gate 		tp->tag_crc_len = 0;	/* Don't do CRCs on bitmaps */
10527c478bd9Sstevel@tonic-gate 		tp->tag_loc = part_unalloc;
10537c478bd9Sstevel@tonic-gate 		sbp->sbd_nbits = part_len;
10547c478bd9Sstevel@tonic-gate 		sbp->sbd_nbytes = part_bmp_bytes;
10557c478bd9Sstevel@tonic-gate 		maketag(tp, tp);
10567c478bd9Sstevel@tonic-gate 		if (part_unalloc >= 0) {
10577c478bd9Sstevel@tonic-gate 			int32_t i;
10587c478bd9Sstevel@tonic-gate 
10597c478bd9Sstevel@tonic-gate 			cp = (uint8_t *)sbp + SPACEMAP_OFF;
10607c478bd9Sstevel@tonic-gate 			i = nextlogblock / NBBY;
10617c478bd9Sstevel@tonic-gate 			cp[i++] = (0xff << (nextlogblock % NBBY)) & 0xff;
10627c478bd9Sstevel@tonic-gate 			while (i < part_bmp_bytes)
10637c478bd9Sstevel@tonic-gate 				cp[i++] = 0xff;
10647c478bd9Sstevel@tonic-gate 			if (part_len % NBBY)
10657c478bd9Sstevel@tonic-gate 				cp[--i] = (unsigned)0xff >>
10667c478bd9Sstevel@tonic-gate 					(NBBY - part_len % NBBY);
10677c478bd9Sstevel@tonic-gate 
10687c478bd9Sstevel@tonic-gate 			wtfs(part_unalloc + part_start, size, (char *)tp);
10697c478bd9Sstevel@tonic-gate 		}
10707c478bd9Sstevel@tonic-gate 		free((char *)sbp);
10717c478bd9Sstevel@tonic-gate 	}
10727c478bd9Sstevel@tonic-gate 
10737c478bd9Sstevel@tonic-gate 	/*
10747c478bd9Sstevel@tonic-gate 	 * Volume Integrity Descriptor
10757c478bd9Sstevel@tonic-gate 	 */
10767c478bd9Sstevel@tonic-gate 	nextblock = INTSEQSTART;
10777c478bd9Sstevel@tonic-gate 	endblock = nextblock + INTSEQLEN / sectorsize;
10787c478bd9Sstevel@tonic-gate 	/* LINTED */
10797c478bd9Sstevel@tonic-gate 	lvip = (struct log_vol_int_desc *)&lvid;
10807c478bd9Sstevel@tonic-gate 	tp = &lvip->lvid_tag;
10817c478bd9Sstevel@tonic-gate 	tp->tag_id =  UD_LOG_VOL_INT;
10827c478bd9Sstevel@tonic-gate 	tp->tag_desc_ver = ecma_version;
10837c478bd9Sstevel@tonic-gate 	tp->tag_sno = serialnum;
10847c478bd9Sstevel@tonic-gate 	tp->tag_loc = nextblock;
10857c478bd9Sstevel@tonic-gate 	setstamp(&lvip->lvid_tstamp);
10867c478bd9Sstevel@tonic-gate 	lvip->lvid_int_type = LOG_VOL_CLOSE_INT;
10877c478bd9Sstevel@tonic-gate 	setextad(&lvip->lvid_nie, 0, 0);
10887c478bd9Sstevel@tonic-gate 	lvip->lvid_npart = 1;
10897c478bd9Sstevel@tonic-gate 	lvip->lvid_liu = 0x2e;
10907c478bd9Sstevel@tonic-gate 	lvip->lvid_uniqid = MAXID + 1;
10917c478bd9Sstevel@tonic-gate 	lvip->lvid_fst[0] = part_len - nextlogblock;	/* Free space */
10927c478bd9Sstevel@tonic-gate 	lvip->lvid_fst[1] = part_len;			/* Size */
10937c478bd9Sstevel@tonic-gate 	lviup = (struct lvid_iu *)&lvip->lvid_fst[2];
10947c478bd9Sstevel@tonic-gate 	bcopy(&sunmicro, &lviup->lvidiu_regid, sizeof (regid_t));
10957c478bd9Sstevel@tonic-gate 	lviup->lvidiu_nfiles = 0;
10967c478bd9Sstevel@tonic-gate 	lviup->lvidiu_ndirs = 1;
10977c478bd9Sstevel@tonic-gate 	lviup->lvidiu_mread = 0x102;
10987c478bd9Sstevel@tonic-gate 	lviup->lvidiu_mwrite = 0x102;
10997c478bd9Sstevel@tonic-gate 	lviup->lvidiu_maxwr = 0x150;
11007c478bd9Sstevel@tonic-gate 	tp->tag_crc_len = sizeof (struct log_vol_int_desc) + lvip->lvid_liu -
11017c478bd9Sstevel@tonic-gate 		sizeof (struct tag);
11027c478bd9Sstevel@tonic-gate 	maketag(tp, tp);
11037c478bd9Sstevel@tonic-gate 	wtfs(nextblock, sectorsize, (char *)tp);
11047c478bd9Sstevel@tonic-gate 	nextblock++;
11057c478bd9Sstevel@tonic-gate 
11067c478bd9Sstevel@tonic-gate 	/*
11077c478bd9Sstevel@tonic-gate 	 * Terminating Descriptor
11087c478bd9Sstevel@tonic-gate 	 */
11097c478bd9Sstevel@tonic-gate 	bzero(buf, sectorsize);
11107c478bd9Sstevel@tonic-gate 	/* LINTED */
11117c478bd9Sstevel@tonic-gate 	tdp = (struct term_desc *)buf;
11127c478bd9Sstevel@tonic-gate 	tp = &tdp->td_tag;
11137c478bd9Sstevel@tonic-gate 	tp->tag_id =  UD_TERM_DESC;
11147c478bd9Sstevel@tonic-gate 	tp->tag_desc_ver = ecma_version;
11157c478bd9Sstevel@tonic-gate 	tp->tag_sno = serialnum;
11167c478bd9Sstevel@tonic-gate 	tp->tag_crc_len = sizeof (struct term_desc) - sizeof (struct tag);
11177c478bd9Sstevel@tonic-gate 	tp->tag_loc = nextblock;
11187c478bd9Sstevel@tonic-gate 	maketag(tp, tp);
11197c478bd9Sstevel@tonic-gate 	wtfs(nextblock, sectorsize, (char *)tp);
11207c478bd9Sstevel@tonic-gate 	nextblock++;
11217c478bd9Sstevel@tonic-gate 
11227c478bd9Sstevel@tonic-gate 	/* Zero out the rest of the LVI extent */
11237c478bd9Sstevel@tonic-gate 	bzero(buf, sectorsize);
11247c478bd9Sstevel@tonic-gate 	while (nextblock < endblock)
11257c478bd9Sstevel@tonic-gate 		wtfs(nextblock++, sectorsize, buf);
11267c478bd9Sstevel@tonic-gate }
11277c478bd9Sstevel@tonic-gate 
11287c478bd9Sstevel@tonic-gate /*
11297c478bd9Sstevel@tonic-gate  * read a block from the file system
11307c478bd9Sstevel@tonic-gate  */
11317c478bd9Sstevel@tonic-gate static void
11327c478bd9Sstevel@tonic-gate rdfs(daddr_t bno, int size, char *bf)
11337c478bd9Sstevel@tonic-gate {
11347c478bd9Sstevel@tonic-gate 	int n, saverr;
11357c478bd9Sstevel@tonic-gate 
11367c478bd9Sstevel@tonic-gate 	if (llseek(fsi, (offset_t)bno * sectorsize, 0) < 0) {
11377c478bd9Sstevel@tonic-gate 		saverr = errno;
11387c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr,
11397c478bd9Sstevel@tonic-gate 			gettext("seek error on sector %ld: %s\n"),
11407c478bd9Sstevel@tonic-gate 			bno, strerror(saverr));
11417c478bd9Sstevel@tonic-gate 		exit(32);
11427c478bd9Sstevel@tonic-gate 	}
11437c478bd9Sstevel@tonic-gate 	n = read(fsi, bf, size);
11447c478bd9Sstevel@tonic-gate 	if (n != size) {
11457c478bd9Sstevel@tonic-gate 		saverr = errno;
11467c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr,
11477c478bd9Sstevel@tonic-gate 			gettext("read error on sector %ld: %s\n"),
11487c478bd9Sstevel@tonic-gate 			bno, strerror(saverr));
11497c478bd9Sstevel@tonic-gate 		exit(32);
11507c478bd9Sstevel@tonic-gate 	}
11517c478bd9Sstevel@tonic-gate }
11527c478bd9Sstevel@tonic-gate 
11537c478bd9Sstevel@tonic-gate /*
11547c478bd9Sstevel@tonic-gate  * write a block to the file system
11557c478bd9Sstevel@tonic-gate  */
11567c478bd9Sstevel@tonic-gate static void
11577c478bd9Sstevel@tonic-gate wtfs(daddr_t bno, int size, char *bf)
11587c478bd9Sstevel@tonic-gate {
11597c478bd9Sstevel@tonic-gate 	int n, saverr;
11607c478bd9Sstevel@tonic-gate 
11617c478bd9Sstevel@tonic-gate 	if (fso == -1)
11627c478bd9Sstevel@tonic-gate 		return;
11637c478bd9Sstevel@tonic-gate 
11647c478bd9Sstevel@tonic-gate 	if (llseek(fso, (offset_t)bno * sectorsize, 0) < 0) {
11657c478bd9Sstevel@tonic-gate 		saverr = errno;
11667c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr,
11677c478bd9Sstevel@tonic-gate 			gettext("seek error on sector %ld: %s\n"),
11687c478bd9Sstevel@tonic-gate 			bno, strerror(saverr));
11697c478bd9Sstevel@tonic-gate 		exit(32);
11707c478bd9Sstevel@tonic-gate 	}
11717c478bd9Sstevel@tonic-gate 	if (Nflag)
11727c478bd9Sstevel@tonic-gate 		return;
11737c478bd9Sstevel@tonic-gate 	n = write(fso, bf, size);
11747c478bd9Sstevel@tonic-gate 	if (n != size) {
11757c478bd9Sstevel@tonic-gate 		saverr = errno;
11767c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr,
11777c478bd9Sstevel@tonic-gate 			gettext("write error on sector %ld: %s\n"),
11787c478bd9Sstevel@tonic-gate 			bno, strerror(saverr));
11797c478bd9Sstevel@tonic-gate 		exit(32);
11807c478bd9Sstevel@tonic-gate 	}
11817c478bd9Sstevel@tonic-gate }
11827c478bd9Sstevel@tonic-gate 
11837c478bd9Sstevel@tonic-gate static void
11847c478bd9Sstevel@tonic-gate usage()
11857c478bd9Sstevel@tonic-gate {
11867c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr,
11877c478bd9Sstevel@tonic-gate 		gettext("udfs usage: mkfs [-F FSType] [-V]"
11887c478bd9Sstevel@tonic-gate 		" [-m] [-o options] special size(sectors)\n"));
11897c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr,
11907c478bd9Sstevel@tonic-gate 		gettext(" -m : dump fs cmd line used to make"
11917c478bd9Sstevel@tonic-gate 		" this partition\n"));
11927c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr,
11937c478bd9Sstevel@tonic-gate 		gettext(" -V : print this command line and return\n"));
11947c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr,
11957c478bd9Sstevel@tonic-gate 		gettext(" -o : udfs options: :psize=%d:label=%s\n"),
11967c478bd9Sstevel@tonic-gate 		sectorsize, udfs_label);
11977c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr,
11987c478bd9Sstevel@tonic-gate 		gettext("NOTE that all -o suboptions: must"
11997c478bd9Sstevel@tonic-gate 		" be separated only by commas so as to\n"));
12007c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr,
12017c478bd9Sstevel@tonic-gate 		gettext("be parsed as a single argument\n"));
12027c478bd9Sstevel@tonic-gate 	exit(32);
12037c478bd9Sstevel@tonic-gate }
12047c478bd9Sstevel@tonic-gate 
12057c478bd9Sstevel@tonic-gate /*ARGSUSED*/
12067c478bd9Sstevel@tonic-gate static void
12077c478bd9Sstevel@tonic-gate dump_fscmd(char *fsys, int fsi)
12087c478bd9Sstevel@tonic-gate {
12097c478bd9Sstevel@tonic-gate 	(void) printf(gettext("mkfs -F udfs -o "));
12107c478bd9Sstevel@tonic-gate 	(void) printf("psize=%d,label=\"%s\" %s %d\n",
12117c478bd9Sstevel@tonic-gate 		sectorsize, oldlabel, fsys, oldfssize);
12127c478bd9Sstevel@tonic-gate }
12137c478bd9Sstevel@tonic-gate 
12147c478bd9Sstevel@tonic-gate /* number ************************************************************* */
12157c478bd9Sstevel@tonic-gate /*									*/
12167c478bd9Sstevel@tonic-gate /* Convert a numeric arg to binary					*/
12177c478bd9Sstevel@tonic-gate /*									*/
12187c478bd9Sstevel@tonic-gate /* Arg:	 big - maximum valid input number				*/
12197c478bd9Sstevel@tonic-gate /* Global arg:  string - pointer to command arg				*/
12207c478bd9Sstevel@tonic-gate /*									*/
12217c478bd9Sstevel@tonic-gate /* Valid forms: 123 | 123k | 123*123 | 123x123				*/
12227c478bd9Sstevel@tonic-gate /*									*/
12237c478bd9Sstevel@tonic-gate /* Return:	converted number					*/
12247c478bd9Sstevel@tonic-gate /*									*/
12257c478bd9Sstevel@tonic-gate /* ******************************************************************** */
12267c478bd9Sstevel@tonic-gate 
12277c478bd9Sstevel@tonic-gate static int32_t
12287c478bd9Sstevel@tonic-gate number(long big, char *param)
12297c478bd9Sstevel@tonic-gate {
12307c478bd9Sstevel@tonic-gate 	char		*cs;
12317c478bd9Sstevel@tonic-gate 	int64_t		n = 0;
12327c478bd9Sstevel@tonic-gate 	int64_t		cut = BIG;
12337c478bd9Sstevel@tonic-gate 	int32_t		minus = 0;
12347c478bd9Sstevel@tonic-gate 
12357c478bd9Sstevel@tonic-gate #define	FOUND_MULT	0x1
12367c478bd9Sstevel@tonic-gate #define	FOUND_K		0x2
12377c478bd9Sstevel@tonic-gate 
12387c478bd9Sstevel@tonic-gate 	cs = string;
12397c478bd9Sstevel@tonic-gate 	if (*cs == '-') {
12407c478bd9Sstevel@tonic-gate 		minus = 1;
12417c478bd9Sstevel@tonic-gate 		cs++;
12427c478bd9Sstevel@tonic-gate 	}
12437c478bd9Sstevel@tonic-gate 	n = 0;
12447c478bd9Sstevel@tonic-gate 	while ((*cs != ' ') && (*cs != '\0') && (*cs != ',')) {
12457c478bd9Sstevel@tonic-gate 		if ((*cs >= '0') && (*cs <= '9')) {
12467c478bd9Sstevel@tonic-gate 			n = n * 10 + *cs - '0';
12477c478bd9Sstevel@tonic-gate 			cs++;
12487c478bd9Sstevel@tonic-gate 		} else if ((*cs == '*') || (*cs == 'x')) {
12497c478bd9Sstevel@tonic-gate 			if (number_flags & FOUND_MULT) {
12507c478bd9Sstevel@tonic-gate 				(void) fprintf(stderr,
12517c478bd9Sstevel@tonic-gate 				gettext("mkfs: only one \"*\" "
12527c478bd9Sstevel@tonic-gate 				"or \"x\" allowed\n"));
12537c478bd9Sstevel@tonic-gate 				exit(2);
12547c478bd9Sstevel@tonic-gate 			}
12557c478bd9Sstevel@tonic-gate 			number_flags |= FOUND_MULT;
12567c478bd9Sstevel@tonic-gate 			cs++;
12577c478bd9Sstevel@tonic-gate 			string = cs;
12587c478bd9Sstevel@tonic-gate 			n = n * number(big, param);
12597c478bd9Sstevel@tonic-gate 			cs = string;
12607c478bd9Sstevel@tonic-gate 			continue;
12617c478bd9Sstevel@tonic-gate 		} else if (*cs == 'k') {
12627c478bd9Sstevel@tonic-gate 			if (number_flags & FOUND_K) {
12637c478bd9Sstevel@tonic-gate 				(void) fprintf(stderr,
12647c478bd9Sstevel@tonic-gate 				gettext("mkfs: only one \"k\" allowed\n"));
12657c478bd9Sstevel@tonic-gate 				exit(2);
12667c478bd9Sstevel@tonic-gate 			}
12677c478bd9Sstevel@tonic-gate 			number_flags |= FOUND_K;
12687c478bd9Sstevel@tonic-gate 			n = n * 1024;
12697c478bd9Sstevel@tonic-gate 			cs++;
12707c478bd9Sstevel@tonic-gate 			continue;
12717c478bd9Sstevel@tonic-gate 		} else {
12727c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr,
12737c478bd9Sstevel@tonic-gate 				gettext("mkfs: bad numeric arg: \"%s\"\n"),
12747c478bd9Sstevel@tonic-gate 				string);
12757c478bd9Sstevel@tonic-gate 			exit(2);
12767c478bd9Sstevel@tonic-gate 		}
12777c478bd9Sstevel@tonic-gate 	}
12787c478bd9Sstevel@tonic-gate 
12797c478bd9Sstevel@tonic-gate 	if (n > cut) {
12807c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr,
12817c478bd9Sstevel@tonic-gate 			gettext("mkfs: value for %s overflowed\n"), param);
12827c478bd9Sstevel@tonic-gate 		exit(2);
12837c478bd9Sstevel@tonic-gate 	}
12847c478bd9Sstevel@tonic-gate 
12857c478bd9Sstevel@tonic-gate 	if (minus) {
12867c478bd9Sstevel@tonic-gate 		n = -n;
12877c478bd9Sstevel@tonic-gate 	}
12887c478bd9Sstevel@tonic-gate 
12897c478bd9Sstevel@tonic-gate 	if ((n > big) || (n < 0)) {
12907c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr,
12917c478bd9Sstevel@tonic-gate 			gettext("mkfs: argument %s out of range\n"), param);
12927c478bd9Sstevel@tonic-gate 		exit(2);
12937c478bd9Sstevel@tonic-gate 	}
12947c478bd9Sstevel@tonic-gate 
12957c478bd9Sstevel@tonic-gate 	string = cs;
12967c478bd9Sstevel@tonic-gate 	return ((int32_t)n);
12977c478bd9Sstevel@tonic-gate }
12987c478bd9Sstevel@tonic-gate 
12997c478bd9Sstevel@tonic-gate /* match ************************************************************** */
13007c478bd9Sstevel@tonic-gate /*									*/
13017c478bd9Sstevel@tonic-gate /* Compare two text strings for equality				*/
13027c478bd9Sstevel@tonic-gate /*									*/
13037c478bd9Sstevel@tonic-gate /* Arg:	 s - pointer to string to match with a command arg		*/
13047c478bd9Sstevel@tonic-gate /* Global arg:  string - pointer to command arg				*/
13057c478bd9Sstevel@tonic-gate /*									*/
13067c478bd9Sstevel@tonic-gate /* Return:	1 if match, 0 if no match				*/
13077c478bd9Sstevel@tonic-gate /*		If match, also reset `string' to point to the text	*/
13087c478bd9Sstevel@tonic-gate /*		that follows the matching text.				*/
13097c478bd9Sstevel@tonic-gate /*									*/
13107c478bd9Sstevel@tonic-gate /* ******************************************************************** */
13117c478bd9Sstevel@tonic-gate 
13127c478bd9Sstevel@tonic-gate static int
13137c478bd9Sstevel@tonic-gate match(char *s)
13147c478bd9Sstevel@tonic-gate {
13157c478bd9Sstevel@tonic-gate 	char *cs;
13167c478bd9Sstevel@tonic-gate 
13177c478bd9Sstevel@tonic-gate 	cs = string;
13187c478bd9Sstevel@tonic-gate 	while (*cs++ == *s) {
13197c478bd9Sstevel@tonic-gate 		if (*s++ == '\0') {
13207c478bd9Sstevel@tonic-gate 			goto true;
13217c478bd9Sstevel@tonic-gate 		}
13227c478bd9Sstevel@tonic-gate 	}
13237c478bd9Sstevel@tonic-gate 	if (*s != '\0') {
13247c478bd9Sstevel@tonic-gate 		return (0);
13257c478bd9Sstevel@tonic-gate 	}
13267c478bd9Sstevel@tonic-gate 
13277c478bd9Sstevel@tonic-gate true:
13287c478bd9Sstevel@tonic-gate 	cs--;
13297c478bd9Sstevel@tonic-gate 	string = cs;
13307c478bd9Sstevel@tonic-gate 	return (1);
13317c478bd9Sstevel@tonic-gate }
13327c478bd9Sstevel@tonic-gate 
13337c478bd9Sstevel@tonic-gate static uint32_t
13347c478bd9Sstevel@tonic-gate get_bsize()
13357c478bd9Sstevel@tonic-gate {
13367c478bd9Sstevel@tonic-gate 	struct dk_cinfo info;
13377c478bd9Sstevel@tonic-gate 	struct fd_char fd_char;
1338*65908c77Syu, larry liu - Sun Microsystems - Beijing China 	struct dk_minfo dkminfo;
13397c478bd9Sstevel@tonic-gate 
13407c478bd9Sstevel@tonic-gate 	if (ioctl(fso, DKIOCINFO, &info) < 0) {
13417c478bd9Sstevel@tonic-gate 		perror("mkfs DKIOCINFO ");
13427c478bd9Sstevel@tonic-gate 		(void) fprintf(stdout,
13437c478bd9Sstevel@tonic-gate 			gettext("DKIOCINFO failed using psize = 2048"
13447c478bd9Sstevel@tonic-gate 			" for creating file-system\n"));
13457c478bd9Sstevel@tonic-gate 		return (0);
13467c478bd9Sstevel@tonic-gate 	}
13477c478bd9Sstevel@tonic-gate 
13487c478bd9Sstevel@tonic-gate 	switch (info.dki_ctype) {
13497c478bd9Sstevel@tonic-gate 		case DKC_CDROM :
13507c478bd9Sstevel@tonic-gate 			return (2048);
13517c478bd9Sstevel@tonic-gate 		case DKC_SCSI_CCS :
1352*65908c77Syu, larry liu - Sun Microsystems - Beijing China 			if (ioctl(fso, DKIOCGMEDIAINFO, &dkminfo) != -1) {
1353*65908c77Syu, larry liu - Sun Microsystems - Beijing China 				if (dkminfo.dki_lbsize != 0 &&
1354*65908c77Syu, larry liu - Sun Microsystems - Beijing China 				    POWEROF2(dkminfo.dki_lbsize / DEV_BSIZE) &&
1355*65908c77Syu, larry liu - Sun Microsystems - Beijing China 				    dkminfo.dki_lbsize != DEV_BSIZE) {
1356*65908c77Syu, larry liu - Sun Microsystems - Beijing China 					fprintf(stderr,
1357*65908c77Syu, larry liu - Sun Microsystems - Beijing China 					    gettext("The device sector size "
1358*65908c77Syu, larry liu - Sun Microsystems - Beijing China 					    "%u is not supported by udfs!\n"),
1359*65908c77Syu, larry liu - Sun Microsystems - Beijing China 					    dkminfo.dki_lbsize);
1360*65908c77Syu, larry liu - Sun Microsystems - Beijing China 					(void) close(fso);
1361*65908c77Syu, larry liu - Sun Microsystems - Beijing China 					exit(1);
1362*65908c77Syu, larry liu - Sun Microsystems - Beijing China 				}
1363*65908c77Syu, larry liu - Sun Microsystems - Beijing China 			}
13647c478bd9Sstevel@tonic-gate 			/* FALLTHROUGH */
13657c478bd9Sstevel@tonic-gate 		case DKC_INTEL82072 :
13667c478bd9Sstevel@tonic-gate 			/* FALLTHROUGH */
13677c478bd9Sstevel@tonic-gate 		case DKC_INTEL82077 :
13687c478bd9Sstevel@tonic-gate 			/* FALLTHROUGH */
13697c478bd9Sstevel@tonic-gate 		case DKC_DIRECT :
13707c478bd9Sstevel@tonic-gate 			if (ioctl(fso, FDIOGCHAR, &fd_char) >= 0) {
13717c478bd9Sstevel@tonic-gate 				return (fd_char.fdc_sec_size);
13727c478bd9Sstevel@tonic-gate 			}
13737c478bd9Sstevel@tonic-gate 			/* FALLTHROUGH */
13747c478bd9Sstevel@tonic-gate 		case DKC_PCMCIA_ATA :
13757c478bd9Sstevel@tonic-gate 			return (512);
13767c478bd9Sstevel@tonic-gate 		default :
13777c478bd9Sstevel@tonic-gate 			return (0);
13787c478bd9Sstevel@tonic-gate 	}
13797c478bd9Sstevel@tonic-gate }
13807c478bd9Sstevel@tonic-gate 
13817c478bd9Sstevel@tonic-gate /*
13827c478bd9Sstevel@tonic-gate  * Read in the volume sequences descriptors.
13837c478bd9Sstevel@tonic-gate  */
13847c478bd9Sstevel@tonic-gate static int
13857c478bd9Sstevel@tonic-gate readvolseq()
13867c478bd9Sstevel@tonic-gate {
13877c478bd9Sstevel@tonic-gate 	struct tag *tp;
13887c478bd9Sstevel@tonic-gate 	uint8_t *cp, *end;
13897c478bd9Sstevel@tonic-gate 	int err;
13907c478bd9Sstevel@tonic-gate 	struct pri_vol_desc *pvolp;
13917c478bd9Sstevel@tonic-gate 	struct part_desc *partp;
13927c478bd9Sstevel@tonic-gate 	struct log_vol_desc *logvp;
13937c478bd9Sstevel@tonic-gate 	struct anch_vol_desc_ptr *avp;
13947c478bd9Sstevel@tonic-gate 	char *main_vdbuf;
13957c478bd9Sstevel@tonic-gate 	uint32_t nextblock;
13967c478bd9Sstevel@tonic-gate 
13977c478bd9Sstevel@tonic-gate 	avp = (struct anch_vol_desc_ptr *)malloc(sectorsize);
13987c478bd9Sstevel@tonic-gate 	rdfs(FIRSTAVDP, sectorsize, (char *)avp);
13997c478bd9Sstevel@tonic-gate 	tp = (struct tag *)avp;
14007c478bd9Sstevel@tonic-gate 	err = verifytag(tp, FIRSTAVDP, tp, UD_ANCH_VOL_DESC);
14017c478bd9Sstevel@tonic-gate 	if (err)
14027c478bd9Sstevel@tonic-gate 		return (0);
14037c478bd9Sstevel@tonic-gate 	main_vdbuf = malloc(avp->avd_main_vdse.ext_len);
14047c478bd9Sstevel@tonic-gate 	if (main_vdbuf == NULL) {
14057c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, gettext("Cannot allocate space for "
14067c478bd9Sstevel@tonic-gate 			"volume sequences\n"));
14077c478bd9Sstevel@tonic-gate 		exit(32);
14087c478bd9Sstevel@tonic-gate 	}
14097c478bd9Sstevel@tonic-gate 	rdfs(avp->avd_main_vdse.ext_loc, avp->avd_main_vdse.ext_len,
14107c478bd9Sstevel@tonic-gate 		main_vdbuf);
14117c478bd9Sstevel@tonic-gate 	end = (uint8_t *)main_vdbuf + avp->avd_main_vdse.ext_len;
14127c478bd9Sstevel@tonic-gate 
14137c478bd9Sstevel@tonic-gate 	nextblock = avp->avd_main_vdse.ext_loc;
14147c478bd9Sstevel@tonic-gate 	for (cp = (uint8_t *)main_vdbuf; cp < end; cp += sectorsize,
14157c478bd9Sstevel@tonic-gate 		nextblock++) {
14167c478bd9Sstevel@tonic-gate 		/* LINTED */
14177c478bd9Sstevel@tonic-gate 		tp = (struct tag *)cp;
14187c478bd9Sstevel@tonic-gate 		err = verifytag(tp, nextblock, tp, 0);
14197c478bd9Sstevel@tonic-gate 		if (err)
14207c478bd9Sstevel@tonic-gate 			continue;
14217c478bd9Sstevel@tonic-gate 
14227c478bd9Sstevel@tonic-gate 		switch (tp->tag_id) {
14237c478bd9Sstevel@tonic-gate 		case UD_PRI_VOL_DESC:
14247c478bd9Sstevel@tonic-gate 			/* Bump serial number, according to spec. */
14257c478bd9Sstevel@tonic-gate 			serialnum = tp->tag_sno + 1;
14267c478bd9Sstevel@tonic-gate 			pvolp = (struct pri_vol_desc *)tp;
14277c478bd9Sstevel@tonic-gate 			oldlabel = pvolp->pvd_vol_id + 1;
14287c478bd9Sstevel@tonic-gate 			break;
14297c478bd9Sstevel@tonic-gate 		case UD_ANCH_VOL_DESC:
14307c478bd9Sstevel@tonic-gate 			avp = (struct anch_vol_desc_ptr *)tp;
14317c478bd9Sstevel@tonic-gate 			break;
14327c478bd9Sstevel@tonic-gate 		case UD_VOL_DESC_PTR:
14337c478bd9Sstevel@tonic-gate 			break;
14347c478bd9Sstevel@tonic-gate 		case UD_IMPL_USE_DESC:
14357c478bd9Sstevel@tonic-gate 			break;
14367c478bd9Sstevel@tonic-gate 		case UD_PART_DESC:
14377c478bd9Sstevel@tonic-gate 			partp = (struct part_desc *)tp;
14387c478bd9Sstevel@tonic-gate 			part_start = partp->pd_part_start;
14397c478bd9Sstevel@tonic-gate 			part_len = partp->pd_part_length;
14407c478bd9Sstevel@tonic-gate 			oldfssize = part_start + part_len;
14417c478bd9Sstevel@tonic-gate 			break;
14427c478bd9Sstevel@tonic-gate 		case UD_LOG_VOL_DESC:
14437c478bd9Sstevel@tonic-gate 			logvp = (struct log_vol_desc *)tp;
14447c478bd9Sstevel@tonic-gate 			break;
14457c478bd9Sstevel@tonic-gate 		case UD_UNALL_SPA_DESC:
14467c478bd9Sstevel@tonic-gate 			break;
14477c478bd9Sstevel@tonic-gate 		case UD_TERM_DESC:
14487c478bd9Sstevel@tonic-gate 			goto done;
14497c478bd9Sstevel@tonic-gate 			break;
14507c478bd9Sstevel@tonic-gate 		case UD_LOG_VOL_INT:
14517c478bd9Sstevel@tonic-gate 			break;
14527c478bd9Sstevel@tonic-gate 		default:
14537c478bd9Sstevel@tonic-gate 			break;
14547c478bd9Sstevel@tonic-gate 		}
14557c478bd9Sstevel@tonic-gate 	}
14567c478bd9Sstevel@tonic-gate done:
14577c478bd9Sstevel@tonic-gate 	if (!partp || !logvp) {
14587c478bd9Sstevel@tonic-gate 		return (0);
14597c478bd9Sstevel@tonic-gate 	}
14607c478bd9Sstevel@tonic-gate 	return (1);
14617c478bd9Sstevel@tonic-gate }
14627c478bd9Sstevel@tonic-gate 
14637c478bd9Sstevel@tonic-gate uint32_t
14647c478bd9Sstevel@tonic-gate get_last_block()
14657c478bd9Sstevel@tonic-gate {
14667c478bd9Sstevel@tonic-gate 	struct vtoc vtoc;
14677c478bd9Sstevel@tonic-gate 	struct dk_cinfo dki_info;
14687c478bd9Sstevel@tonic-gate 
14697c478bd9Sstevel@tonic-gate 	if (ioctl(fsi, DKIOCGVTOC, (intptr_t)&vtoc) != 0) {
14707c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, gettext("Unable to read VTOC\n"));
14717c478bd9Sstevel@tonic-gate 		return (0);
14727c478bd9Sstevel@tonic-gate 	}
14737c478bd9Sstevel@tonic-gate 
14747c478bd9Sstevel@tonic-gate 	if (vtoc.v_sanity != VTOC_SANE) {
14757c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, gettext("Vtoc.v_sanity != VTOC_SANE\n"));
14767c478bd9Sstevel@tonic-gate 		return (0);
14777c478bd9Sstevel@tonic-gate 	}
14787c478bd9Sstevel@tonic-gate 
14797c478bd9Sstevel@tonic-gate 	if (ioctl(fsi, DKIOCINFO, (intptr_t)&dki_info) != 0) {
14807c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr,
14817c478bd9Sstevel@tonic-gate 		    gettext("Could not get the slice information\n"));
14827c478bd9Sstevel@tonic-gate 		return (0);
14837c478bd9Sstevel@tonic-gate 	}
14847c478bd9Sstevel@tonic-gate 
14857c478bd9Sstevel@tonic-gate 	if (dki_info.dki_partition > V_NUMPAR) {
14867c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr,
14877c478bd9Sstevel@tonic-gate 		    gettext("dki_info.dki_partition > V_NUMPAR\n"));
14887c478bd9Sstevel@tonic-gate 		return (0);
14897c478bd9Sstevel@tonic-gate 	}
14907c478bd9Sstevel@tonic-gate 
14917c478bd9Sstevel@tonic-gate 	return ((uint32_t)vtoc.v_part[dki_info.dki_partition].p_size);
14927c478bd9Sstevel@tonic-gate }
1493