xref: /onnv-gate/usr/src/cmd/fs.d/udfs/mkfs/mkfs.c (revision 9889:68d0fe4c716e)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
51053Smaheshvs  * Common Development and Distribution License (the "License").
61053Smaheshvs  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
210Sstevel@tonic-gate /*
22*9889SLarry.Liu@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
230Sstevel@tonic-gate  * Use is subject to license terms.
240Sstevel@tonic-gate  */
250Sstevel@tonic-gate 
260Sstevel@tonic-gate /*	Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T	*/
270Sstevel@tonic-gate /*	  All Rights Reserved  	*/
280Sstevel@tonic-gate 
290Sstevel@tonic-gate /*
300Sstevel@tonic-gate  * Portions of this source code were derived from Berkeley 4.3 BSD
310Sstevel@tonic-gate  * under license from the Regents of the University of California.
320Sstevel@tonic-gate  */
330Sstevel@tonic-gate 
340Sstevel@tonic-gate /*
350Sstevel@tonic-gate  * make file system for udfs (UDF - ISO13346)
360Sstevel@tonic-gate  *
370Sstevel@tonic-gate  * usage:
380Sstevel@tonic-gate  *
390Sstevel@tonic-gate  *    mkfs [-F FSType] [-V] [-m] [options]
400Sstevel@tonic-gate  *	[-o specific_options]  special size
410Sstevel@tonic-gate  *
420Sstevel@tonic-gate  *  where specific_options are:
430Sstevel@tonic-gate  *	N - no create
440Sstevel@tonic-gate  *	label - volume label
450Sstevel@tonic-gate  *	psize - physical block size
460Sstevel@tonic-gate  */
470Sstevel@tonic-gate 
480Sstevel@tonic-gate #include	<stdio.h>
490Sstevel@tonic-gate #include	<strings.h>
500Sstevel@tonic-gate #include	<string.h>
510Sstevel@tonic-gate #include	<stdlib.h>
520Sstevel@tonic-gate #include	<unistd.h>
530Sstevel@tonic-gate #include	<time.h>
540Sstevel@tonic-gate #include	<locale.h>
550Sstevel@tonic-gate #include	<fcntl.h>
560Sstevel@tonic-gate #include	<errno.h>
570Sstevel@tonic-gate #include	<limits.h>
580Sstevel@tonic-gate #include	<sys/mnttab.h>
590Sstevel@tonic-gate #include	<sys/param.h>
600Sstevel@tonic-gate #include	<sys/types.h>
610Sstevel@tonic-gate #include	<sys/sysmacros.h>
620Sstevel@tonic-gate #include	<sys/vnode.h>
630Sstevel@tonic-gate #include	<sys/mntent.h>
640Sstevel@tonic-gate #include	<sys/filio.h>
650Sstevel@tonic-gate #include	<sys/stat.h>
660Sstevel@tonic-gate #include	<ustat.h>
670Sstevel@tonic-gate #include 	<sys/isa_defs.h>	/* for ENDIAN defines */
680Sstevel@tonic-gate #include	<sys/dkio.h>
690Sstevel@tonic-gate #include	<sys/fdio.h>
700Sstevel@tonic-gate #include	<sys/vtoc.h>
710Sstevel@tonic-gate #include	<sys/fs/udf_volume.h>
720Sstevel@tonic-gate 
730Sstevel@tonic-gate extern char	*getfullrawname(char *);
740Sstevel@tonic-gate extern char	*getfullblkname(char *);
750Sstevel@tonic-gate extern struct tm *localtime_r(const time_t *, struct tm *);
760Sstevel@tonic-gate extern void	maketag(struct tag *, struct tag *);
770Sstevel@tonic-gate extern int	verifytag(struct tag *, uint32_t, struct tag *, int);
780Sstevel@tonic-gate extern void	setcharspec(struct charspec *, int32_t, uint8_t *);
790Sstevel@tonic-gate 
800Sstevel@tonic-gate 
810Sstevel@tonic-gate #define	UMASK		0755
820Sstevel@tonic-gate #define	POWEROF2(num)	(((num) & ((num) - 1)) == 0)
830Sstevel@tonic-gate #define	MB		(1024*1024)
840Sstevel@tonic-gate 
850Sstevel@tonic-gate /*
860Sstevel@tonic-gate  * Forward declarations
870Sstevel@tonic-gate  */
880Sstevel@tonic-gate static void rdfs(daddr_t bno, int size, char *bf);
890Sstevel@tonic-gate static void wtfs(daddr_t bno, int size, char *bf);
900Sstevel@tonic-gate static void dump_fscmd(char *fsys, int fsi);
910Sstevel@tonic-gate static int32_t number(long big, char *param);
920Sstevel@tonic-gate static void usage();
930Sstevel@tonic-gate static int match(char *s);
940Sstevel@tonic-gate static int readvolseq();
950Sstevel@tonic-gate static uint32_t get_last_block();
960Sstevel@tonic-gate 
970Sstevel@tonic-gate /*
980Sstevel@tonic-gate  * variables set up by front end.
990Sstevel@tonic-gate  */
1000Sstevel@tonic-gate static int	Nflag = 0;		/* run mkfs without writing */
1010Sstevel@tonic-gate 					/* file system */
1020Sstevel@tonic-gate static int	mflag = 0;		/* return the command line used */
1030Sstevel@tonic-gate 					/* to create this FS */
1040Sstevel@tonic-gate static int	fssize;			/* file system size */
1050Sstevel@tonic-gate static uint32_t	disk_size;		/* partition size from VTOC */
1060Sstevel@tonic-gate static uint32_t unused;			/* unused sectors in partition */
1070Sstevel@tonic-gate static int	sectorsize = 2048;	/* bytes/sector default */
1080Sstevel@tonic-gate 					/* If nothing specified */
1090Sstevel@tonic-gate 
1100Sstevel@tonic-gate static char	*fsys;
1110Sstevel@tonic-gate static int	fsi;
1120Sstevel@tonic-gate static int	fso;
1130Sstevel@tonic-gate 
1140Sstevel@tonic-gate #define	BIG	LONG_MAX
1150Sstevel@tonic-gate static	uint32_t	number_flags = 0;
1160Sstevel@tonic-gate 
1170Sstevel@tonic-gate static char	*string;
1180Sstevel@tonic-gate 
1190Sstevel@tonic-gate static void	setstamp(tstamp_t *);
1200Sstevel@tonic-gate static void	setextad(extent_ad_t *, uint32_t, uint32_t);
1210Sstevel@tonic-gate static void	setdstring(dstring_t *, char *, int32_t);
1220Sstevel@tonic-gate static void	wtvolseq(tag_t *, daddr_t, daddr_t);
1230Sstevel@tonic-gate static void	volseqinit();
1240Sstevel@tonic-gate static void	setstamp(tstamp_t *);
1250Sstevel@tonic-gate static uint32_t	get_bsize();
1260Sstevel@tonic-gate 
1270Sstevel@tonic-gate 
1280Sstevel@tonic-gate #define	VOLRECSTART	(32 * 1024)
1290Sstevel@tonic-gate 
1300Sstevel@tonic-gate #define	VOLSEQSTART	128
1310Sstevel@tonic-gate #define	VOLSEQLEN	16
1320Sstevel@tonic-gate #define	INTSEQSTART	192
1330Sstevel@tonic-gate #define	INTSEQLEN	8192
1340Sstevel@tonic-gate #define	FIRSTAVDP	256
1350Sstevel@tonic-gate #define	AVDPLEN		1
1360Sstevel@tonic-gate 
1370Sstevel@tonic-gate 
1380Sstevel@tonic-gate #define	FILESETLEN	2
1390Sstevel@tonic-gate 
1400Sstevel@tonic-gate #define	SPACEMAP_OFF	24
1410Sstevel@tonic-gate #define	MAXID		16
1420Sstevel@tonic-gate 
1430Sstevel@tonic-gate static time_t mkfstime;
1440Sstevel@tonic-gate static struct tm res;
1450Sstevel@tonic-gate static long tzone;
1460Sstevel@tonic-gate static char vsibuf[128];
1470Sstevel@tonic-gate 
1480Sstevel@tonic-gate static regid_t sunmicro = { 0, "*SUN SOLARIS UDF", 4, 2 };
1490Sstevel@tonic-gate static regid_t lvinfo = { 0, "*UDF LV Info", 0x50, 0x1, 4, 2 };
1500Sstevel@tonic-gate static regid_t partid = { 0, "+NSR02", 0 };
1510Sstevel@tonic-gate static regid_t udf_compliant = { 0, "*OSTA UDF Compliant", 0x50, 0x1, 0 };
1520Sstevel@tonic-gate static uint8_t osta_unicode[] = "OSTA Compressed Unicode";
1530Sstevel@tonic-gate 
1540Sstevel@tonic-gate static int bdevismounted;
1550Sstevel@tonic-gate static int ismounted;
1560Sstevel@tonic-gate static int directory;
1570Sstevel@tonic-gate static char buf[MAXBSIZE];
1580Sstevel@tonic-gate static char buf2[MAXBSIZE];
1590Sstevel@tonic-gate static char lvid[MAXBSIZE];
1600Sstevel@tonic-gate 
1610Sstevel@tonic-gate uint32_t ecma_version = 2;
1620Sstevel@tonic-gate 
1630Sstevel@tonic-gate static int serialnum = 1;	/* Tag serial number */
1640Sstevel@tonic-gate static char udfs_label[128] = "*NoLabel*";
1650Sstevel@tonic-gate static int acctype = PART_ACC_OW;
1660Sstevel@tonic-gate static uint32_t part_start;
1670Sstevel@tonic-gate static uint32_t part_len;
1680Sstevel@tonic-gate static uint32_t part_bmp_bytes;
1690Sstevel@tonic-gate static uint32_t part_bmp_sectors;
1700Sstevel@tonic-gate static int32_t part_unalloc = -1;
1710Sstevel@tonic-gate static uint32_t filesetblock;
1720Sstevel@tonic-gate 
1730Sstevel@tonic-gate /* Set by readvolseq for -m option */
1740Sstevel@tonic-gate static uint32_t oldfssize;
1750Sstevel@tonic-gate static char *oldlabel;
1760Sstevel@tonic-gate 
1771053Smaheshvs int
main(int32_t argc,int8_t * argv[])1780Sstevel@tonic-gate main(int32_t argc, int8_t *argv[])
1790Sstevel@tonic-gate {
1800Sstevel@tonic-gate 	long i;
1810Sstevel@tonic-gate 	FILE *mnttab;
1820Sstevel@tonic-gate 	struct mnttab mntp;
1830Sstevel@tonic-gate 	char *special, *raw_special;
1840Sstevel@tonic-gate 	struct stat statarea;
1850Sstevel@tonic-gate 	struct ustat ustatarea;
1860Sstevel@tonic-gate 	int32_t	c;
1870Sstevel@tonic-gate 	uint32_t temp_secsz;
1880Sstevel@tonic-gate 	int isfs;
1890Sstevel@tonic-gate 
1900Sstevel@tonic-gate 	(void) setlocale(LC_ALL, "");
1910Sstevel@tonic-gate 
1920Sstevel@tonic-gate #if !defined(TEXT_DOMAIN)
1930Sstevel@tonic-gate #define	TEXT_DOMAIN "SYS_TEST"
1940Sstevel@tonic-gate #endif
1950Sstevel@tonic-gate 	(void) textdomain(TEXT_DOMAIN);
1960Sstevel@tonic-gate 
1970Sstevel@tonic-gate 	while ((c = getopt(argc, argv, "F:Vmo:")) != EOF) {
1980Sstevel@tonic-gate 		switch (c) {
1990Sstevel@tonic-gate 
2000Sstevel@tonic-gate 			case 'F':
2010Sstevel@tonic-gate 				string = optarg;
2020Sstevel@tonic-gate 				if (strcmp(string, "udfs") != 0) {
2030Sstevel@tonic-gate 					usage();
2040Sstevel@tonic-gate 				}
2050Sstevel@tonic-gate 				break;
2060Sstevel@tonic-gate 
2070Sstevel@tonic-gate 			case 'V':
2080Sstevel@tonic-gate 				{
2090Sstevel@tonic-gate 					char	*opt_text;
2100Sstevel@tonic-gate 					int	opt_count;
2110Sstevel@tonic-gate 
2120Sstevel@tonic-gate 					(void) fprintf(stdout,
2130Sstevel@tonic-gate 					gettext("mkfs -F udfs "));
2140Sstevel@tonic-gate 					for (opt_count = 1; opt_count < argc;
2150Sstevel@tonic-gate 							opt_count++) {
2160Sstevel@tonic-gate 						opt_text = argv[opt_count];
2170Sstevel@tonic-gate 						if (opt_text) {
2180Sstevel@tonic-gate 							(void) fprintf(stdout,
2190Sstevel@tonic-gate 							" %s ", opt_text);
2200Sstevel@tonic-gate 						}
2210Sstevel@tonic-gate 					}
2220Sstevel@tonic-gate 					(void) fprintf(stdout, "\n");
2230Sstevel@tonic-gate 				}
2240Sstevel@tonic-gate 				break;
2250Sstevel@tonic-gate 
2260Sstevel@tonic-gate 			case 'm':
2270Sstevel@tonic-gate 				/*
2280Sstevel@tonic-gate 				 * return command line used
2290Sstevel@tonic-gate 				 * to create this FS
2300Sstevel@tonic-gate 				 */
2310Sstevel@tonic-gate 				mflag++;
2320Sstevel@tonic-gate 				break;
2330Sstevel@tonic-gate 
2340Sstevel@tonic-gate 			case 'o':
2350Sstevel@tonic-gate 				/*
2360Sstevel@tonic-gate 				 * udfs specific options.
2370Sstevel@tonic-gate 				 */
2380Sstevel@tonic-gate 				string = optarg;
2390Sstevel@tonic-gate 				while (*string != '\0') {
2400Sstevel@tonic-gate 					if (match("N")) {
2410Sstevel@tonic-gate 						Nflag++;
2420Sstevel@tonic-gate 					} else if (match("psize=")) {
2430Sstevel@tonic-gate 						number_flags = 0;
2440Sstevel@tonic-gate 						sectorsize = number(BIG,
2450Sstevel@tonic-gate 							"psize");
2460Sstevel@tonic-gate 					} else if (match("label=")) {
2470Sstevel@tonic-gate 						for (i = 0; i < 31; i++) {
2480Sstevel@tonic-gate 							if (*string == '\0') {
2490Sstevel@tonic-gate 								break;
2500Sstevel@tonic-gate 							}
2510Sstevel@tonic-gate 							udfs_label[i] =
2520Sstevel@tonic-gate 								*string++;
2530Sstevel@tonic-gate 						}
2540Sstevel@tonic-gate 						udfs_label[i] = '\0';
2550Sstevel@tonic-gate 					} else if (*string == '\0') {
2560Sstevel@tonic-gate 						break;
2570Sstevel@tonic-gate 					} else {
2580Sstevel@tonic-gate 						(void) fprintf(stdout,
2590Sstevel@tonic-gate 							gettext("illegal "
2600Sstevel@tonic-gate 							"option: %s\n"),
2610Sstevel@tonic-gate 							string);
2620Sstevel@tonic-gate 						usage();
2630Sstevel@tonic-gate 					}
2640Sstevel@tonic-gate 					if (*string == ',') {
2650Sstevel@tonic-gate 						string++;
2660Sstevel@tonic-gate 					}
2670Sstevel@tonic-gate 					if (*string == ' ') {
2680Sstevel@tonic-gate 						string++;
2690Sstevel@tonic-gate 					}
2700Sstevel@tonic-gate 				}
2710Sstevel@tonic-gate 				break;
2720Sstevel@tonic-gate 
2730Sstevel@tonic-gate 			case '?':
2740Sstevel@tonic-gate 				usage();
2750Sstevel@tonic-gate 				break;
2760Sstevel@tonic-gate 		}
2770Sstevel@tonic-gate 	}
2780Sstevel@tonic-gate 
2790Sstevel@tonic-gate 	(void) time(&mkfstime);
2800Sstevel@tonic-gate 	if (optind > (argc - 1)) {
2810Sstevel@tonic-gate 		usage();
2820Sstevel@tonic-gate 	}
2830Sstevel@tonic-gate 
2840Sstevel@tonic-gate 	argc -= optind;
2850Sstevel@tonic-gate 	argv = &argv[optind];
2860Sstevel@tonic-gate 	fsys = argv[0];
2870Sstevel@tonic-gate 	raw_special = getfullrawname(fsys);
2880Sstevel@tonic-gate 	fsi = open(raw_special, 0);
2890Sstevel@tonic-gate 	if (fsi < 0) {
2900Sstevel@tonic-gate 		(void) fprintf(stdout,
2910Sstevel@tonic-gate 			gettext("%s: cannot open\n"), fsys);
2920Sstevel@tonic-gate 		exit(32);
2930Sstevel@tonic-gate 	}
2940Sstevel@tonic-gate 	fso = fsi;
2950Sstevel@tonic-gate 
2960Sstevel@tonic-gate 	if ((temp_secsz = get_bsize()) != 0) {
2970Sstevel@tonic-gate 		sectorsize = temp_secsz;
2980Sstevel@tonic-gate 	}
299*9889SLarry.Liu@Sun.COM 
3000Sstevel@tonic-gate 	/* Get old file system information */
3010Sstevel@tonic-gate 	isfs = readvolseq();
3020Sstevel@tonic-gate 
3030Sstevel@tonic-gate 	if (mflag) {
3040Sstevel@tonic-gate 		/*
3050Sstevel@tonic-gate 		 * Figure out the block size and
3060Sstevel@tonic-gate 		 * file system size and print the information
3070Sstevel@tonic-gate 		 */
3080Sstevel@tonic-gate 		if (isfs)
3090Sstevel@tonic-gate 			dump_fscmd(fsys, fsi);
3100Sstevel@tonic-gate 		else
3110Sstevel@tonic-gate 			(void) printf(gettext(
3120Sstevel@tonic-gate 				"[not currently a valid file system]\n"));
3130Sstevel@tonic-gate 		exit(0);
3140Sstevel@tonic-gate 	}
3150Sstevel@tonic-gate 
3160Sstevel@tonic-gate 	/*
3170Sstevel@tonic-gate 	 * Get the disk size from the drive or VTOC for the N and N-256
3180Sstevel@tonic-gate 	 * AVDPs and to make sure we don't want to create a file system
3190Sstevel@tonic-gate 	 * bigger than the partition.
3200Sstevel@tonic-gate 	 */
3210Sstevel@tonic-gate 	disk_size = get_last_block();
3220Sstevel@tonic-gate 
3230Sstevel@tonic-gate 	if (argc < 2 && disk_size == 0 || argc < 1) {
3240Sstevel@tonic-gate 		usage();
3250Sstevel@tonic-gate 	}
3260Sstevel@tonic-gate 
3270Sstevel@tonic-gate 	if (argc < 2) {
3280Sstevel@tonic-gate 		(void) printf(gettext("No size specified, entire partition "
3290Sstevel@tonic-gate 			"of %u sectors used\n"), disk_size);
3300Sstevel@tonic-gate 		fssize = disk_size;
3310Sstevel@tonic-gate 	} else {
3320Sstevel@tonic-gate 		string = argv[1];
3330Sstevel@tonic-gate 		number_flags = 0;
3340Sstevel@tonic-gate 		fssize = number(BIG, "size");
3350Sstevel@tonic-gate 	}
3360Sstevel@tonic-gate 
3370Sstevel@tonic-gate 	if (fssize < 0) {
3380Sstevel@tonic-gate 		(void) fprintf(stderr,
3390Sstevel@tonic-gate 			gettext("Negative number of sectors(%d) not allowed\n"),
3400Sstevel@tonic-gate 			fssize);
3410Sstevel@tonic-gate 		exit(32);
3420Sstevel@tonic-gate 	}
3430Sstevel@tonic-gate 
3440Sstevel@tonic-gate 	if (fssize < (512 * sectorsize / DEV_BSIZE)) {
3450Sstevel@tonic-gate 		(void) fprintf(stdout,
3460Sstevel@tonic-gate 			gettext("size should be at least %d sectors\n"),
3470Sstevel@tonic-gate 			(512 * sectorsize / DEV_BSIZE));
3480Sstevel@tonic-gate 		exit(32);
3490Sstevel@tonic-gate 	}
3500Sstevel@tonic-gate 
3510Sstevel@tonic-gate 	if (disk_size != 0) {
3520Sstevel@tonic-gate 		if (fssize > disk_size) {
3530Sstevel@tonic-gate 			(void) fprintf(stderr, gettext("Invalid size: %d "
3540Sstevel@tonic-gate 				"larger than the partition size\n"), fssize);
3550Sstevel@tonic-gate 			exit(32);
3560Sstevel@tonic-gate 		} else if (fssize < disk_size) {
3570Sstevel@tonic-gate 			unused = disk_size - fssize;
3580Sstevel@tonic-gate 			(void) printf(
3590Sstevel@tonic-gate 			    gettext("File system size %d smaller than "
3600Sstevel@tonic-gate 				"partition, %u sectors unused\n"),
3610Sstevel@tonic-gate 				fssize, unused);
3620Sstevel@tonic-gate 		}
3630Sstevel@tonic-gate 	} else {
3640Sstevel@tonic-gate 		/* Use passed-in size */
3650Sstevel@tonic-gate 		disk_size = fssize;
3660Sstevel@tonic-gate 	}
3670Sstevel@tonic-gate 
3680Sstevel@tonic-gate 	if (!Nflag) {
3690Sstevel@tonic-gate 		special = getfullblkname(fsys);
3700Sstevel@tonic-gate 
3710Sstevel@tonic-gate 		/*
3720Sstevel@tonic-gate 		 * If we found the block device name,
3730Sstevel@tonic-gate 		 * then check the mount table.
3740Sstevel@tonic-gate 		 * if mounted, write lock the file system
3750Sstevel@tonic-gate 		 *
3760Sstevel@tonic-gate 		 */
3770Sstevel@tonic-gate 		if ((special != NULL) && (*special != '\0')) {
3780Sstevel@tonic-gate 			mnttab = fopen(MNTTAB, "r");
3790Sstevel@tonic-gate 			while ((getmntent(mnttab, &mntp)) == NULL) {
3800Sstevel@tonic-gate 				if (strcmp(special, mntp.mnt_special) == 0) {
3810Sstevel@tonic-gate 					(void) fprintf(stdout,
3820Sstevel@tonic-gate 						gettext("%s is mounted,"
3830Sstevel@tonic-gate 						" can't mkfs\n"), special);
3840Sstevel@tonic-gate 					exit(32);
3850Sstevel@tonic-gate 				}
3860Sstevel@tonic-gate 			}
3870Sstevel@tonic-gate 			(void) fclose(mnttab);
3880Sstevel@tonic-gate 		}
3890Sstevel@tonic-gate 		if ((bdevismounted) && (ismounted == 0)) {
3900Sstevel@tonic-gate 			(void) fprintf(stdout,
3910Sstevel@tonic-gate 				gettext("can't check mount point; "));
3920Sstevel@tonic-gate 			(void) fprintf(stdout,
3930Sstevel@tonic-gate 				gettext("%s is mounted but not in mnttab(4)\n"),
3940Sstevel@tonic-gate 				special);
3950Sstevel@tonic-gate 			exit(32);
3960Sstevel@tonic-gate 		}
3970Sstevel@tonic-gate 		if (directory) {
3980Sstevel@tonic-gate 			if (ismounted == 0) {
3990Sstevel@tonic-gate 				(void) fprintf(stdout,
4000Sstevel@tonic-gate 					gettext("%s is not mounted\n"),
4010Sstevel@tonic-gate 					special);
4020Sstevel@tonic-gate 				exit(32);
4030Sstevel@tonic-gate 			}
4040Sstevel@tonic-gate 		}
4050Sstevel@tonic-gate 		fso = creat(fsys, 0666);
4060Sstevel@tonic-gate 		if (fso < 0) {
4070Sstevel@tonic-gate 			(void) fprintf(stdout,
4080Sstevel@tonic-gate 				gettext("%s: cannot create\n"), fsys);
4090Sstevel@tonic-gate 			exit(32);
4100Sstevel@tonic-gate 		}
4110Sstevel@tonic-gate 		if (stat(fsys, &statarea) < 0) {
4120Sstevel@tonic-gate 			(void) fprintf(stderr,
4130Sstevel@tonic-gate 				gettext("%s: %s: cannot stat\n"),
4140Sstevel@tonic-gate 				argv[0], fsys);
4150Sstevel@tonic-gate 			exit(32);
4160Sstevel@tonic-gate 		}
4170Sstevel@tonic-gate 		if (ustat(statarea.st_rdev, &ustatarea) >= 0) {
4180Sstevel@tonic-gate 			(void) fprintf(stderr,
4190Sstevel@tonic-gate 				gettext("%s is mounted, can't mkfs\n"), fsys);
4200Sstevel@tonic-gate 			exit(32);
4210Sstevel@tonic-gate 		}
4220Sstevel@tonic-gate 	} else {
4230Sstevel@tonic-gate 		/*
4240Sstevel@tonic-gate 		 * For the -N case, a file descriptor is needed for the llseek()
4250Sstevel@tonic-gate 		 * in wtfs(). See the comment in wtfs() for more information.
4260Sstevel@tonic-gate 		 *
4270Sstevel@tonic-gate 		 * Get a file descriptor that's read-only so that this code
4280Sstevel@tonic-gate 		 * doesn't accidentally write to the file.
4290Sstevel@tonic-gate 		 */
4300Sstevel@tonic-gate 		fso = open(fsys, O_RDONLY);
4310Sstevel@tonic-gate 		if (fso < 0) {
4320Sstevel@tonic-gate 			(void) fprintf(stderr, gettext("%s: cannot open\n"),
4330Sstevel@tonic-gate 				fsys);
4340Sstevel@tonic-gate 			exit(32);
4350Sstevel@tonic-gate 		}
4360Sstevel@tonic-gate 	}
4370Sstevel@tonic-gate 
4380Sstevel@tonic-gate 
4390Sstevel@tonic-gate 	/*
4400Sstevel@tonic-gate 	 * Validate the given file system size.
4410Sstevel@tonic-gate 	 * Verify that its last block can actually be accessed.
4420Sstevel@tonic-gate 	 */
4430Sstevel@tonic-gate 	fssize = fssize / (sectorsize / DEV_BSIZE);
4440Sstevel@tonic-gate 	if (fssize <= 0) {
4450Sstevel@tonic-gate 		(void) fprintf(stdout,
4460Sstevel@tonic-gate 			gettext("preposterous size %d. sectors\n"), fssize);
4470Sstevel@tonic-gate 		exit(32);
4480Sstevel@tonic-gate 	}
4490Sstevel@tonic-gate 	fssize --;
4500Sstevel@tonic-gate 
4510Sstevel@tonic-gate 	/*
4520Sstevel@tonic-gate 	 * verify device size
4530Sstevel@tonic-gate 	 */
4540Sstevel@tonic-gate 	rdfs(fssize - 1, sectorsize, buf);
4550Sstevel@tonic-gate 
4560Sstevel@tonic-gate 	if ((sectorsize < DEV_BSIZE) ||
4570Sstevel@tonic-gate 		(sectorsize > MAXBSIZE)) {
4580Sstevel@tonic-gate 		(void) fprintf(stdout,
4590Sstevel@tonic-gate 			gettext("sector size must be"
4600Sstevel@tonic-gate 			" between 512, 8192 bytes\n"));
4610Sstevel@tonic-gate 	}
4620Sstevel@tonic-gate 	if (!POWEROF2(sectorsize)) {
4630Sstevel@tonic-gate 		(void) fprintf(stdout,
4640Sstevel@tonic-gate 			gettext("sector size must be a power of 2, not %d\n"),
4650Sstevel@tonic-gate 			sectorsize);
4660Sstevel@tonic-gate 		exit(32);
4670Sstevel@tonic-gate 	}
4680Sstevel@tonic-gate 	if (Nflag) {
4690Sstevel@tonic-gate 		exit(0);
4700Sstevel@tonic-gate 	}
4710Sstevel@tonic-gate 
4720Sstevel@tonic-gate 	(void) printf(gettext("Creating file system with sector size of "
4730Sstevel@tonic-gate 		"%d bytes\n"), sectorsize);
4740Sstevel@tonic-gate 
4750Sstevel@tonic-gate 	/*
4760Sstevel@tonic-gate 	 * Set up time stamp values
4770Sstevel@tonic-gate 	 */
4780Sstevel@tonic-gate 	mkfstime = time(0);
4790Sstevel@tonic-gate 	(void) localtime_r(&mkfstime, &res);
4800Sstevel@tonic-gate 	if (res.tm_isdst > 0) {
4810Sstevel@tonic-gate 		tzone = altzone / 60;
4820Sstevel@tonic-gate 	} else if (res.tm_isdst == 0) {
4830Sstevel@tonic-gate 		tzone = tzone / 60;
4840Sstevel@tonic-gate 	} else {
4850Sstevel@tonic-gate 		tzone = 2047;	/* Unknown */
4860Sstevel@tonic-gate 	}
4870Sstevel@tonic-gate 
4880Sstevel@tonic-gate 	/*
4890Sstevel@tonic-gate 	 * Initialize the volume recognition sequence, the volume descriptor
4900Sstevel@tonic-gate 	 * sequences and the anchor pointer.
4910Sstevel@tonic-gate 	 */
4920Sstevel@tonic-gate 	volseqinit();
4930Sstevel@tonic-gate 
4940Sstevel@tonic-gate 	(void) fsync(fso);
4950Sstevel@tonic-gate 	(void) close(fsi);
4960Sstevel@tonic-gate 	(void) close(fso);
4970Sstevel@tonic-gate 
4980Sstevel@tonic-gate 	return (0);
4990Sstevel@tonic-gate }
5000Sstevel@tonic-gate 
5010Sstevel@tonic-gate static void
setstamp(tstamp_t * tp)5020Sstevel@tonic-gate setstamp(tstamp_t *tp)
5030Sstevel@tonic-gate {
5040Sstevel@tonic-gate 	tp->ts_usec = 0;
5050Sstevel@tonic-gate 	tp->ts_husec = 0;
5060Sstevel@tonic-gate 	tp->ts_csec = 0;
5070Sstevel@tonic-gate 
5080Sstevel@tonic-gate 	tp->ts_sec = res.tm_sec;
5090Sstevel@tonic-gate 	tp->ts_min = res.tm_min;
5100Sstevel@tonic-gate 	tp->ts_hour = res.tm_hour;
5110Sstevel@tonic-gate 	tp->ts_day = res.tm_mday;
5120Sstevel@tonic-gate 	tp->ts_month = res.tm_mon + 1;
5130Sstevel@tonic-gate 	tp->ts_year = 1900 + res.tm_year;
5140Sstevel@tonic-gate 
5150Sstevel@tonic-gate 	tp->ts_tzone = 0x1000 + (-tzone & 0xFFF);
5160Sstevel@tonic-gate }
5170Sstevel@tonic-gate 
5180Sstevel@tonic-gate static void
setextad(extent_ad_t * eap,uint32_t len,uint32_t loc)5190Sstevel@tonic-gate setextad(extent_ad_t *eap, uint32_t len, uint32_t loc)
5200Sstevel@tonic-gate {
5210Sstevel@tonic-gate 	eap->ext_len = len;
5220Sstevel@tonic-gate 	eap->ext_loc = loc;
5230Sstevel@tonic-gate }
5240Sstevel@tonic-gate 
5250Sstevel@tonic-gate static void
setdstring(dstring_t * dp,char * cp,int len)5260Sstevel@tonic-gate setdstring(dstring_t *dp, char *cp, int len)
5270Sstevel@tonic-gate {
5280Sstevel@tonic-gate 	int32_t length;
5290Sstevel@tonic-gate 
5300Sstevel@tonic-gate 	bzero(dp, len);
5310Sstevel@tonic-gate 	length = strlen(cp);
5320Sstevel@tonic-gate 	if (length > len - 3) {
5330Sstevel@tonic-gate 		length = len - 3;
5340Sstevel@tonic-gate 	}
5350Sstevel@tonic-gate 	dp[len - 1] = length + 1;
5360Sstevel@tonic-gate 	*dp++ = 8;
5370Sstevel@tonic-gate 	(void) strncpy(dp, cp, len-2);
5380Sstevel@tonic-gate }
5390Sstevel@tonic-gate 
5400Sstevel@tonic-gate static void
wtvolseq(tag_t * tp,daddr_t blk1,daddr_t blk2)5410Sstevel@tonic-gate wtvolseq(tag_t *tp, daddr_t blk1, daddr_t blk2)
5420Sstevel@tonic-gate {
5430Sstevel@tonic-gate 	static uint32_t vdsn = 0;
5440Sstevel@tonic-gate 
5450Sstevel@tonic-gate 	tp->tag_loc = blk1;
5460Sstevel@tonic-gate 	switch (tp->tag_id) {
5470Sstevel@tonic-gate 	case UD_PRI_VOL_DESC :
5480Sstevel@tonic-gate 		((struct pri_vol_desc *)tp)->pvd_vdsn = vdsn++;
5490Sstevel@tonic-gate 		break;
5500Sstevel@tonic-gate 	case UD_VOL_DESC_PTR :
5510Sstevel@tonic-gate 		((struct vol_desc_ptr *)tp)->vdp_vdsn = vdsn++;
5520Sstevel@tonic-gate 		break;
5530Sstevel@tonic-gate 	case UD_IMPL_USE_DESC :
5540Sstevel@tonic-gate 		((struct iuvd_desc *)tp)->iuvd_vdsn = vdsn++;
5550Sstevel@tonic-gate 		break;
5560Sstevel@tonic-gate 	case UD_PART_DESC :
5570Sstevel@tonic-gate 		((struct part_desc *)tp)->pd_vdsn = vdsn++;
5580Sstevel@tonic-gate 		break;
5590Sstevel@tonic-gate 	case UD_LOG_VOL_DESC :
5600Sstevel@tonic-gate 		((struct log_vol_desc *)tp)->lvd_vdsn = vdsn++;
5610Sstevel@tonic-gate 		break;
5620Sstevel@tonic-gate 	case UD_UNALL_SPA_DESC :
5630Sstevel@tonic-gate 		((struct unall_spc_desc *)tp)->ua_vdsn = vdsn++;
5640Sstevel@tonic-gate 		break;
5650Sstevel@tonic-gate 	}
5660Sstevel@tonic-gate 
5670Sstevel@tonic-gate 	bzero(buf2, sectorsize);
5680Sstevel@tonic-gate 	/* LINTED */
5690Sstevel@tonic-gate 	maketag(tp, (struct tag *)buf2);
5700Sstevel@tonic-gate 
5710Sstevel@tonic-gate 	/*
5720Sstevel@tonic-gate 	 * Write at Main Volume Descriptor Sequence
5730Sstevel@tonic-gate 	 */
5740Sstevel@tonic-gate 	wtfs(blk1, sectorsize, buf2);
5750Sstevel@tonic-gate 
5760Sstevel@tonic-gate 	tp->tag_loc = blk2;
5770Sstevel@tonic-gate 	switch (tp->tag_id) {
5780Sstevel@tonic-gate 	case UD_PRI_VOL_DESC :
5790Sstevel@tonic-gate 		((struct pri_vol_desc *)tp)->pvd_vdsn = vdsn++;
5800Sstevel@tonic-gate 		break;
5810Sstevel@tonic-gate 	case UD_VOL_DESC_PTR :
5820Sstevel@tonic-gate 		((struct vol_desc_ptr *)tp)->vdp_vdsn = vdsn++;
5830Sstevel@tonic-gate 		break;
5840Sstevel@tonic-gate 	case UD_IMPL_USE_DESC :
5850Sstevel@tonic-gate 		((struct iuvd_desc *)tp)->iuvd_vdsn = vdsn++;
5860Sstevel@tonic-gate 		break;
5870Sstevel@tonic-gate 	case UD_PART_DESC :
5880Sstevel@tonic-gate 		((struct part_desc *)tp)->pd_vdsn = vdsn++;
5890Sstevel@tonic-gate 		break;
5900Sstevel@tonic-gate 	case UD_LOG_VOL_DESC :
5910Sstevel@tonic-gate 		((struct log_vol_desc *)tp)->lvd_vdsn = vdsn++;
5920Sstevel@tonic-gate 		break;
5930Sstevel@tonic-gate 	case UD_UNALL_SPA_DESC :
5940Sstevel@tonic-gate 		((struct unall_spc_desc *)tp)->ua_vdsn = vdsn++;
5950Sstevel@tonic-gate 		break;
5960Sstevel@tonic-gate 	}
5970Sstevel@tonic-gate 	maketag(tp, tp);
5980Sstevel@tonic-gate 	/*
5990Sstevel@tonic-gate 	 * Write at Reserve Volume Descriptor Sequence
6000Sstevel@tonic-gate 	 */
6010Sstevel@tonic-gate 	wtfs(blk2, sectorsize, buf);
6020Sstevel@tonic-gate }
6030Sstevel@tonic-gate 
6040Sstevel@tonic-gate static void
volseqinit()6050Sstevel@tonic-gate volseqinit()
6060Sstevel@tonic-gate {
6070Sstevel@tonic-gate 	struct tag *tp;
6080Sstevel@tonic-gate 	struct nsr_desc *nsp;
6090Sstevel@tonic-gate 	struct pri_vol_desc *pvdp;
6100Sstevel@tonic-gate 	struct iuvd_desc *iudp;
6110Sstevel@tonic-gate 	struct part_desc *pp;
6120Sstevel@tonic-gate 	struct phdr_desc *php;
6130Sstevel@tonic-gate 	struct log_vol_desc *lvp;
6140Sstevel@tonic-gate 	long_ad_t *lap;
6150Sstevel@tonic-gate 	struct pmap_typ1 *pmp;
6160Sstevel@tonic-gate 	struct unall_spc_desc *uap;
6170Sstevel@tonic-gate 	struct log_vol_int_desc *lvip;
6180Sstevel@tonic-gate 	struct term_desc *tdp;
6190Sstevel@tonic-gate 	struct anch_vol_desc_ptr *avp;
6200Sstevel@tonic-gate 	struct lvid_iu *lviup;
6210Sstevel@tonic-gate 	struct file_set_desc *fsp;
6220Sstevel@tonic-gate 	struct file_entry *fp;
6230Sstevel@tonic-gate 	struct icb_tag *icb;
6240Sstevel@tonic-gate 	struct short_ad *sap;
6250Sstevel@tonic-gate 	struct file_id *fip;
6260Sstevel@tonic-gate 	struct space_bmap_desc *sbp;
6270Sstevel@tonic-gate 	uint8_t *cp;
6280Sstevel@tonic-gate 	daddr_t nextblock, endblock;
6290Sstevel@tonic-gate 	int32_t volseq_sectors, nextlogblock, rootfelen, i;
6300Sstevel@tonic-gate 	uint32_t mvds_loc, rvds_loc;
6310Sstevel@tonic-gate 
6320Sstevel@tonic-gate 	bzero(buf, MAXBSIZE);
6330Sstevel@tonic-gate 
6340Sstevel@tonic-gate 	/*
6350Sstevel@tonic-gate 	 * Starting from MAXBSIZE, clear out till 256 sectors.
6360Sstevel@tonic-gate 	 */
6370Sstevel@tonic-gate 	for (i = MAXBSIZE / sectorsize; i < FIRSTAVDP; i++) {
6380Sstevel@tonic-gate 		wtfs(i, sectorsize, buf);
6390Sstevel@tonic-gate 	}
6400Sstevel@tonic-gate 
6410Sstevel@tonic-gate 	/* Zero out the avdp at N - 257 */
6420Sstevel@tonic-gate 	wtfs(fssize - 256, sectorsize, buf);
6430Sstevel@tonic-gate 
6440Sstevel@tonic-gate 	/*
6450Sstevel@tonic-gate 	 * Leave 1st 32K for O.S.
6460Sstevel@tonic-gate 	 */
6470Sstevel@tonic-gate 	nextblock = VOLRECSTART / sectorsize;
6480Sstevel@tonic-gate 
6490Sstevel@tonic-gate 	/*
6500Sstevel@tonic-gate 	 * Write BEA01/NSR02/TEA01 sequence.
6510Sstevel@tonic-gate 	 * Each one must be 2K bytes in length.
6520Sstevel@tonic-gate 	 */
6530Sstevel@tonic-gate 	nsp = (struct nsr_desc *)buf;
6540Sstevel@tonic-gate 	nsp->nsr_str_type = 0;
6550Sstevel@tonic-gate 	nsp->nsr_ver = 1;
6560Sstevel@tonic-gate 	(void) strncpy((int8_t *)nsp->nsr_id, "BEA01", 5);
6570Sstevel@tonic-gate 
6580Sstevel@tonic-gate 	nsp = (struct nsr_desc *)&buf[2048];
6590Sstevel@tonic-gate 	nsp->nsr_str_type = 0;
6600Sstevel@tonic-gate 	nsp->nsr_ver = 1;
6610Sstevel@tonic-gate 	(void) strncpy((int8_t *)nsp->nsr_id, "NSR02", 5);
6620Sstevel@tonic-gate 
6630Sstevel@tonic-gate 	nsp = (struct nsr_desc *)&buf[4096];
6640Sstevel@tonic-gate 	nsp->nsr_str_type = 0;
6650Sstevel@tonic-gate 	nsp->nsr_ver = 1;
6660Sstevel@tonic-gate 	(void) strncpy((int8_t *)nsp->nsr_id, "TEA01", 5);
6670Sstevel@tonic-gate 
6680Sstevel@tonic-gate 	wtfs(nextblock, 8192, buf);
6690Sstevel@tonic-gate 	bzero(buf, MAXBSIZE);
6700Sstevel@tonic-gate 
6710Sstevel@tonic-gate 	/*
6720Sstevel@tonic-gate 	 * Minimum length of volume sequences
6730Sstevel@tonic-gate 	 */
6740Sstevel@tonic-gate 	volseq_sectors = 16;
6750Sstevel@tonic-gate 
6760Sstevel@tonic-gate 	/*
6770Sstevel@tonic-gate 	 * Round up to next 32K boundary for
6780Sstevel@tonic-gate 	 * volume descriptor sequences
6790Sstevel@tonic-gate 	 */
6800Sstevel@tonic-gate 	nextblock = VOLSEQSTART;
6810Sstevel@tonic-gate 	bzero(buf, sectorsize);
6820Sstevel@tonic-gate 	mvds_loc = VOLSEQSTART;
6830Sstevel@tonic-gate 	rvds_loc = mvds_loc + volseq_sectors;
6840Sstevel@tonic-gate 
6850Sstevel@tonic-gate 	/*
6860Sstevel@tonic-gate 	 * Primary Volume Descriptor
6870Sstevel@tonic-gate 	 */
6880Sstevel@tonic-gate 	/* LINTED */
6890Sstevel@tonic-gate 	pvdp = (struct pri_vol_desc *)buf;
6900Sstevel@tonic-gate 	tp = &pvdp->pvd_tag;
6910Sstevel@tonic-gate 	tp->tag_id =  UD_PRI_VOL_DESC;
6920Sstevel@tonic-gate 	tp->tag_desc_ver = ecma_version;
6930Sstevel@tonic-gate 	tp->tag_sno = serialnum;
6940Sstevel@tonic-gate 	tp->tag_crc_len = sizeof (struct pri_vol_desc) -
6950Sstevel@tonic-gate 			sizeof (struct tag);
6960Sstevel@tonic-gate 	pvdp->pvd_vdsn = 0;
6970Sstevel@tonic-gate 	pvdp->pvd_pvdn = 0;
6980Sstevel@tonic-gate 	setdstring(pvdp->pvd_vol_id, udfs_label, 32);
6990Sstevel@tonic-gate 	pvdp->pvd_vsn = 1;
7000Sstevel@tonic-gate 	pvdp->pvd_mvsn = 1;
7010Sstevel@tonic-gate 	pvdp->pvd_il = 2;		/* Single-volume */
7020Sstevel@tonic-gate 	pvdp->pvd_mil = 3;		/* Multi-volume */
7030Sstevel@tonic-gate 	pvdp->pvd_csl = 1;		/* CS0 */
7040Sstevel@tonic-gate 	pvdp->pvd_mcsl = 1;		/* CS0 */
7050Sstevel@tonic-gate 	(void) sprintf(vsibuf, "%08X", SWAP_32((uint32_t)mkfstime));
7060Sstevel@tonic-gate 	setdstring(pvdp->pvd_vsi, vsibuf, 128);
7070Sstevel@tonic-gate 	(void) strncpy(pvdp->pvd_vsi + 17, udfs_label, 128 - 17);
7080Sstevel@tonic-gate 	setcharspec(&pvdp->pvd_desc_cs, 0, osta_unicode);
7090Sstevel@tonic-gate 	setcharspec(&pvdp->pvd_exp_cs, 0, osta_unicode);
7100Sstevel@tonic-gate 	setextad(&pvdp->pvd_vol_abs, 0, 0);
7110Sstevel@tonic-gate 	setextad(&pvdp->pvd_vcn, 0, 0);
7120Sstevel@tonic-gate 	bzero(&pvdp->pvd_appl_id, sizeof (regid_t));
7130Sstevel@tonic-gate 	setstamp(&pvdp->pvd_time);
7140Sstevel@tonic-gate 	bcopy(&sunmicro, &pvdp->pvd_ii, sizeof (regid_t));
7150Sstevel@tonic-gate 	pvdp->pvd_flags = 0;
7160Sstevel@tonic-gate 	wtvolseq(tp, nextblock, nextblock + volseq_sectors);
7170Sstevel@tonic-gate 	nextblock++;
7180Sstevel@tonic-gate 
7190Sstevel@tonic-gate 	/*
7200Sstevel@tonic-gate 	 * Implementation Use Descriptor
7210Sstevel@tonic-gate 	 */
7220Sstevel@tonic-gate 	bzero(buf, sectorsize);
7230Sstevel@tonic-gate 	/* LINTED */
7240Sstevel@tonic-gate 	iudp = (struct iuvd_desc *)buf;
7250Sstevel@tonic-gate 	tp = &iudp->iuvd_tag;
7260Sstevel@tonic-gate 	tp->tag_id =  UD_IMPL_USE_DESC;
7270Sstevel@tonic-gate 	tp->tag_desc_ver = ecma_version;
7280Sstevel@tonic-gate 	tp->tag_sno = serialnum;
7290Sstevel@tonic-gate 	tp->tag_crc_len = sizeof (struct iuvd_desc) -
7300Sstevel@tonic-gate 			sizeof (struct tag);
7310Sstevel@tonic-gate 	iudp->iuvd_vdsn = 0;
7320Sstevel@tonic-gate 	bcopy(&lvinfo, &iudp->iuvd_ii, sizeof (regid_t));
7330Sstevel@tonic-gate 	setcharspec(&iudp->iuvd_cset, 0, osta_unicode);
7340Sstevel@tonic-gate 	setdstring(iudp->iuvd_lvi, udfs_label, 128);
7350Sstevel@tonic-gate 
7360Sstevel@tonic-gate 	setdstring(iudp->iuvd_ifo1, "", 36);
7370Sstevel@tonic-gate 	setdstring(iudp->iuvd_ifo2, "", 36);
7380Sstevel@tonic-gate 	setdstring(iudp->iuvd_ifo3, "", 36);
7390Sstevel@tonic-gate 
7400Sstevel@tonic-gate 
7410Sstevel@tonic-gate 	/*
7420Sstevel@tonic-gate 	 * info1,2,3 = user specified
7430Sstevel@tonic-gate 	 */
7440Sstevel@tonic-gate 	bcopy(&sunmicro, &iudp->iuvd_iid, sizeof (regid_t));
7450Sstevel@tonic-gate 	wtvolseq(tp, nextblock, nextblock + volseq_sectors);
7460Sstevel@tonic-gate 	nextblock++;
7470Sstevel@tonic-gate 
7480Sstevel@tonic-gate 	/*
7490Sstevel@tonic-gate 	 * Partition Descriptor
7500Sstevel@tonic-gate 	 */
7510Sstevel@tonic-gate 	bzero(buf, sectorsize);
7520Sstevel@tonic-gate 	/* LINTED */
7530Sstevel@tonic-gate 	pp = (struct part_desc *)buf;
7540Sstevel@tonic-gate 	tp = &pp->pd_tag;
7550Sstevel@tonic-gate 	tp->tag_id =  UD_PART_DESC;
7560Sstevel@tonic-gate 	tp->tag_desc_ver = ecma_version;
7570Sstevel@tonic-gate 	tp->tag_sno = serialnum;
7580Sstevel@tonic-gate 	tp->tag_crc_len = sizeof (struct part_desc) -
7590Sstevel@tonic-gate 			sizeof (struct tag);
7600Sstevel@tonic-gate 	pp->pd_vdsn = 0;
7610Sstevel@tonic-gate 	pp->pd_pflags = 1;			/* Allocated */
7620Sstevel@tonic-gate 	pp->pd_pnum = 0;
7630Sstevel@tonic-gate 	bcopy(&partid, &pp->pd_pcontents, sizeof (regid_t));
7640Sstevel@tonic-gate 
7650Sstevel@tonic-gate 	part_start = FIRSTAVDP + AVDPLEN;
7660Sstevel@tonic-gate 	part_len = fssize - part_start;
7670Sstevel@tonic-gate 	part_bmp_bytes = (part_len + NBBY - 1) / NBBY;
7680Sstevel@tonic-gate 	part_bmp_sectors = (part_bmp_bytes + SPACEMAP_OFF + sectorsize - 1) /
7690Sstevel@tonic-gate 		sectorsize;
7700Sstevel@tonic-gate 
7710Sstevel@tonic-gate 	pp->pd_part_start = part_start;
7720Sstevel@tonic-gate 	pp->pd_part_length = part_len;
7730Sstevel@tonic-gate 
7740Sstevel@tonic-gate 	pp->pd_acc_type = acctype;
7750Sstevel@tonic-gate 	nextlogblock = 0;
7760Sstevel@tonic-gate 
7770Sstevel@tonic-gate 	/*
7780Sstevel@tonic-gate 	 * Do the partition header
7790Sstevel@tonic-gate 	 */
7800Sstevel@tonic-gate 	/* LINTED */
7810Sstevel@tonic-gate 	php = (struct phdr_desc *)&pp->pd_pc_use;
7820Sstevel@tonic-gate 
7830Sstevel@tonic-gate 	/*
7840Sstevel@tonic-gate 	 * Set up unallocated space bitmap
7850Sstevel@tonic-gate 	 */
7860Sstevel@tonic-gate 	if (acctype == PART_ACC_RW || acctype == PART_ACC_OW) {
7870Sstevel@tonic-gate 		php->phdr_usb.sad_ext_len =
7880Sstevel@tonic-gate 			(part_bmp_bytes + SPACEMAP_OFF + sectorsize - 1) &
7890Sstevel@tonic-gate 				(~(sectorsize - 1));
7900Sstevel@tonic-gate 		php->phdr_usb.sad_ext_loc = nextlogblock;
7910Sstevel@tonic-gate 		part_unalloc = nextlogblock;
7920Sstevel@tonic-gate 		nextlogblock += part_bmp_sectors;
7930Sstevel@tonic-gate 	}
7940Sstevel@tonic-gate 
7950Sstevel@tonic-gate 	bcopy(&sunmicro, &pp->pd_ii, sizeof (regid_t));
7960Sstevel@tonic-gate 	wtvolseq(tp, nextblock, nextblock + volseq_sectors);
7970Sstevel@tonic-gate 	nextblock++;
7980Sstevel@tonic-gate 
7990Sstevel@tonic-gate 	/*
8000Sstevel@tonic-gate 	 * Logical Volume Descriptor
8010Sstevel@tonic-gate 	 */
8020Sstevel@tonic-gate 	bzero(buf, sectorsize);
8030Sstevel@tonic-gate 	/* LINTED */
8040Sstevel@tonic-gate 	lvp = (struct log_vol_desc *)buf;
8050Sstevel@tonic-gate 	tp = &lvp->lvd_tag;
8060Sstevel@tonic-gate 	tp->tag_id =  UD_LOG_VOL_DESC;
8070Sstevel@tonic-gate 	tp->tag_desc_ver = ecma_version;
8080Sstevel@tonic-gate 	tp->tag_sno = serialnum;
8090Sstevel@tonic-gate 	tp->tag_crc_len = sizeof (struct log_vol_desc) -
8100Sstevel@tonic-gate 			sizeof (struct tag);
8110Sstevel@tonic-gate 	lvp->lvd_vdsn = 0;
8120Sstevel@tonic-gate 	setcharspec(&lvp->lvd_desc_cs, 0, osta_unicode);
8130Sstevel@tonic-gate 	setdstring(lvp->lvd_lvid, udfs_label, 128);
8140Sstevel@tonic-gate 	lvp->lvd_log_bsize = sectorsize;
8150Sstevel@tonic-gate 	bcopy(&udf_compliant, &lvp->lvd_dom_id, sizeof (regid_t));
8160Sstevel@tonic-gate 	lap = (long_ad_t *)&lvp->lvd_lvcu;
8170Sstevel@tonic-gate 	lap->lad_ext_len = FILESETLEN * sectorsize;
8180Sstevel@tonic-gate 	filesetblock = nextlogblock;
8190Sstevel@tonic-gate 	lap->lad_ext_loc = nextlogblock;
8200Sstevel@tonic-gate 	lap->lad_ext_prn = 0;
8210Sstevel@tonic-gate 	lvp->lvd_mtbl_len = 6;
8220Sstevel@tonic-gate 	lvp->lvd_num_pmaps = 1;
8230Sstevel@tonic-gate 	bcopy(&sunmicro, &lvp->lvd_ii, sizeof (regid_t));
8240Sstevel@tonic-gate 	/* LINTED */
8250Sstevel@tonic-gate 	pmp = (struct pmap_typ1 *)&lvp->lvd_pmaps;
8260Sstevel@tonic-gate 	pmp->map1_type = 1;
8270Sstevel@tonic-gate 	pmp->map1_length = 6;
8280Sstevel@tonic-gate 	pmp->map1_vsn = SWAP_16(1);
8290Sstevel@tonic-gate 	pmp->map1_pn  = 0;
8300Sstevel@tonic-gate 	tp->tag_crc_len = (char *)(pmp + 1) - buf - sizeof (struct tag);
8310Sstevel@tonic-gate 	setextad(&lvp->lvd_int_seq_ext, INTSEQLEN, INTSEQSTART);
8320Sstevel@tonic-gate 	wtvolseq(tp, nextblock, nextblock + volseq_sectors);
8330Sstevel@tonic-gate 	nextblock++;
8340Sstevel@tonic-gate 
8350Sstevel@tonic-gate 	/*
8360Sstevel@tonic-gate 	 * Unallocated Space Descriptor
8370Sstevel@tonic-gate 	 */
8380Sstevel@tonic-gate 	bzero(buf, sectorsize);
8390Sstevel@tonic-gate 	/* LINTED */
8400Sstevel@tonic-gate 	uap = (struct unall_spc_desc *)buf;
8410Sstevel@tonic-gate 	tp = &uap->ua_tag;
8420Sstevel@tonic-gate 	tp->tag_id =  UD_UNALL_SPA_DESC;
8430Sstevel@tonic-gate 	tp->tag_desc_ver = ecma_version;
8440Sstevel@tonic-gate 	tp->tag_sno = serialnum;
8450Sstevel@tonic-gate 	uap->ua_vdsn = 0;
8460Sstevel@tonic-gate 	uap->ua_nad = 0;
8470Sstevel@tonic-gate 	tp->tag_crc_len = (char *)uap->ua_al_dsc - buf - sizeof (struct tag);
8480Sstevel@tonic-gate 	wtvolseq(tp, nextblock, nextblock + volseq_sectors);
8490Sstevel@tonic-gate 	nextblock++;
8500Sstevel@tonic-gate 
8510Sstevel@tonic-gate 	/*
8520Sstevel@tonic-gate 	 * Terminating Descriptor
8530Sstevel@tonic-gate 	 */
8540Sstevel@tonic-gate 	bzero(buf, sectorsize);
8550Sstevel@tonic-gate 	/* LINTED */
8560Sstevel@tonic-gate 	tdp = (struct term_desc *)buf;
8570Sstevel@tonic-gate 	tp = &tdp->td_tag;
8580Sstevel@tonic-gate 	tp->tag_id =  UD_TERM_DESC;
8590Sstevel@tonic-gate 	tp->tag_desc_ver = ecma_version;
8600Sstevel@tonic-gate 	tp->tag_sno = serialnum;
8610Sstevel@tonic-gate 	tp->tag_crc_len = sizeof (struct term_desc) -
8620Sstevel@tonic-gate 			sizeof (struct tag);
8630Sstevel@tonic-gate 	tp->tag_loc = nextblock;
8640Sstevel@tonic-gate 	wtvolseq(tp, nextblock, nextblock + volseq_sectors);
8650Sstevel@tonic-gate 	nextblock++;
8660Sstevel@tonic-gate 
8670Sstevel@tonic-gate 	/*
8680Sstevel@tonic-gate 	 * Do the anchor volume descriptor
8690Sstevel@tonic-gate 	 */
8700Sstevel@tonic-gate 	if (nextblock > FIRSTAVDP) {
8710Sstevel@tonic-gate 		(void) fprintf(stdout,
8720Sstevel@tonic-gate 			gettext("Volume integrity sequence"
8730Sstevel@tonic-gate 			" descriptors too long\n"));
8740Sstevel@tonic-gate 		exit(32);
8750Sstevel@tonic-gate 	}
8760Sstevel@tonic-gate 
8770Sstevel@tonic-gate 	nextblock = FIRSTAVDP;
8780Sstevel@tonic-gate 	bzero(buf, sectorsize);
8790Sstevel@tonic-gate 	/* LINTED */
8800Sstevel@tonic-gate 	avp = (struct anch_vol_desc_ptr *)buf;
8810Sstevel@tonic-gate 	tp = &avp->avd_tag;
8820Sstevel@tonic-gate 	tp->tag_id =  UD_ANCH_VOL_DESC;
8830Sstevel@tonic-gate 	tp->tag_desc_ver = ecma_version;
8840Sstevel@tonic-gate 	tp->tag_sno = serialnum;
8850Sstevel@tonic-gate 	tp->tag_crc_len = sizeof (struct anch_vol_desc_ptr) -
8860Sstevel@tonic-gate 			sizeof (struct tag);
8870Sstevel@tonic-gate 	tp->tag_loc = nextblock;
8880Sstevel@tonic-gate 	setextad(&avp->avd_main_vdse,
8890Sstevel@tonic-gate 			volseq_sectors * sectorsize, mvds_loc);
8900Sstevel@tonic-gate 	setextad(&avp->avd_res_vdse,
8910Sstevel@tonic-gate 			volseq_sectors * sectorsize, rvds_loc);
8920Sstevel@tonic-gate 	bzero(buf2, sectorsize);
8930Sstevel@tonic-gate 	/* LINTED */
8940Sstevel@tonic-gate 	maketag(tp, (struct tag *)buf2);
8950Sstevel@tonic-gate 	wtfs(nextblock, sectorsize, buf2);
8960Sstevel@tonic-gate 	nextblock++;
8970Sstevel@tonic-gate 
8980Sstevel@tonic-gate 	tp->tag_loc = fssize;
8990Sstevel@tonic-gate 	/* LINTED */
9000Sstevel@tonic-gate 	maketag(tp, (struct tag *)buf2);
9010Sstevel@tonic-gate 	wtfs(fssize, sectorsize, buf2);
9020Sstevel@tonic-gate 
9030Sstevel@tonic-gate 	/*
9040Sstevel@tonic-gate 	 * File Set Descriptor
9050Sstevel@tonic-gate 	 */
9060Sstevel@tonic-gate 	bzero(buf, sectorsize);
9070Sstevel@tonic-gate 	/* LINTED */
9080Sstevel@tonic-gate 	fsp = (struct file_set_desc *)&buf;
9090Sstevel@tonic-gate 	tp = &fsp->fsd_tag;
9100Sstevel@tonic-gate 	tp->tag_id =  UD_FILE_SET_DESC;
9110Sstevel@tonic-gate 	tp->tag_desc_ver = ecma_version;
9120Sstevel@tonic-gate 	tp->tag_sno = serialnum;
9130Sstevel@tonic-gate 	tp->tag_crc_len = sizeof (struct file_set_desc) -
9140Sstevel@tonic-gate 			sizeof (struct tag);
9150Sstevel@tonic-gate 	tp->tag_loc = nextlogblock;
9160Sstevel@tonic-gate 	setstamp(&fsp->fsd_time);
9170Sstevel@tonic-gate 	fsp->fsd_ilevel = 3;
9180Sstevel@tonic-gate 	fsp->fsd_mi_level = 3;
9190Sstevel@tonic-gate 	fsp->fsd_cs_list = 1;
9200Sstevel@tonic-gate 	fsp->fsd_mcs_list = 1;
9210Sstevel@tonic-gate 	fsp->fsd_fs_no = 0;
9220Sstevel@tonic-gate 	fsp->fsd_fsd_no = 0;
9230Sstevel@tonic-gate 	setcharspec(&fsp->fsd_lvidcs, 0, osta_unicode);
9240Sstevel@tonic-gate 	setdstring(fsp->fsd_lvid, udfs_label, 128);
9250Sstevel@tonic-gate 	setcharspec(&fsp->fsd_fscs, 0, osta_unicode);
9260Sstevel@tonic-gate 	setdstring(fsp->fsd_fsi, udfs_label, 32);
9270Sstevel@tonic-gate 	setdstring(fsp->fsd_cfi, "", 32);
9280Sstevel@tonic-gate 	setdstring(fsp->fsd_afi, "", 32);
9290Sstevel@tonic-gate 	lap = (long_ad_t *)&fsp->fsd_root_icb;
9300Sstevel@tonic-gate 	lap->lad_ext_len = sectorsize;
9310Sstevel@tonic-gate 	lap->lad_ext_loc = filesetblock + FILESETLEN;
9320Sstevel@tonic-gate 	lap->lad_ext_prn = 0;
9330Sstevel@tonic-gate 	bcopy(&udf_compliant, &fsp->fsd_did, sizeof (regid_t));
9340Sstevel@tonic-gate 	maketag(tp, tp);
9350Sstevel@tonic-gate 	wtfs(nextlogblock + part_start, sectorsize, (char *)tp);
9360Sstevel@tonic-gate 	nextlogblock++;
9370Sstevel@tonic-gate 
9380Sstevel@tonic-gate 	/*
9390Sstevel@tonic-gate 	 * Terminating Descriptor
9400Sstevel@tonic-gate 	 */
9410Sstevel@tonic-gate 	bzero(buf, sectorsize);
9420Sstevel@tonic-gate 	/* LINTED */
9430Sstevel@tonic-gate 	tdp = (struct term_desc *)buf;
9440Sstevel@tonic-gate 	tp = &tdp->td_tag;
9450Sstevel@tonic-gate 	tp->tag_id =  UD_TERM_DESC;
9460Sstevel@tonic-gate 	tp->tag_desc_ver = ecma_version;
9470Sstevel@tonic-gate 	tp->tag_sno = serialnum;
9480Sstevel@tonic-gate 	tp->tag_crc_len = sizeof (struct term_desc) -
9490Sstevel@tonic-gate 			sizeof (struct tag);
9500Sstevel@tonic-gate 	tp->tag_loc = nextlogblock;
9510Sstevel@tonic-gate 	maketag(tp, tp);
9520Sstevel@tonic-gate 	wtfs(nextlogblock + part_start, sectorsize, (char *)tp);
9530Sstevel@tonic-gate 	nextlogblock++;
9540Sstevel@tonic-gate 
9550Sstevel@tonic-gate 	if (nextlogblock > filesetblock + FILESETLEN) {
9560Sstevel@tonic-gate 		(void) fprintf(stdout,
9570Sstevel@tonic-gate 			gettext("File set descriptor too long\n"));
9580Sstevel@tonic-gate 		exit(32);
9590Sstevel@tonic-gate 	}
9600Sstevel@tonic-gate 	nextlogblock = filesetblock + FILESETLEN;
9610Sstevel@tonic-gate 
9620Sstevel@tonic-gate 	/*
9630Sstevel@tonic-gate 	 * Root File Entry
9640Sstevel@tonic-gate 	 */
9650Sstevel@tonic-gate 	bzero(buf, sectorsize);
9660Sstevel@tonic-gate 	/* LINTED */
9670Sstevel@tonic-gate 	fp = (struct file_entry *)&buf;
9680Sstevel@tonic-gate 	tp = &fp->fe_tag;
9690Sstevel@tonic-gate 	tp->tag_id =  UD_FILE_ENTRY;
9700Sstevel@tonic-gate 	tp->tag_desc_ver = ecma_version;
9710Sstevel@tonic-gate 	tp->tag_sno = serialnum;
9720Sstevel@tonic-gate 	tp->tag_loc = nextlogblock;
9730Sstevel@tonic-gate 	icb = &fp->fe_icb_tag;
9740Sstevel@tonic-gate 	icb->itag_prnde = 0;
9750Sstevel@tonic-gate 	icb->itag_strategy = STRAT_TYPE4;
9760Sstevel@tonic-gate 	icb->itag_param = 0; /* what does this mean? */
9770Sstevel@tonic-gate 	icb->itag_max_ent = 1;
9780Sstevel@tonic-gate 	icb->itag_ftype = FTYPE_DIRECTORY;
9790Sstevel@tonic-gate 	icb->itag_lb_loc = 0;
9800Sstevel@tonic-gate 	icb->itag_lb_prn = 0;
9810Sstevel@tonic-gate 	icb->itag_flags = ICB_FLAG_ARCHIVE;
9820Sstevel@tonic-gate 	fp->fe_uid = getuid();
9830Sstevel@tonic-gate 	fp->fe_gid = getgid();
9840Sstevel@tonic-gate 	fp->fe_perms = (0x1f << 10) | (0x5 << 5) | 0x5;
9850Sstevel@tonic-gate 	fp->fe_lcount = 1;
9860Sstevel@tonic-gate 	fp->fe_rec_for = 0;
9870Sstevel@tonic-gate 	fp->fe_rec_dis = 0;
9880Sstevel@tonic-gate 	fp->fe_rec_len = 0;
9890Sstevel@tonic-gate 	fp->fe_info_len = sizeof (struct file_id);
9900Sstevel@tonic-gate 	fp->fe_lbr = 1;
9910Sstevel@tonic-gate 	setstamp(&fp->fe_acc_time);
9920Sstevel@tonic-gate 	setstamp(&fp->fe_mod_time);
9930Sstevel@tonic-gate 	setstamp(&fp->fe_attr_time);
9940Sstevel@tonic-gate 	fp->fe_ckpoint = 1;
9950Sstevel@tonic-gate 	bcopy(&sunmicro, &fp->fe_impl_id, sizeof (regid_t));
9960Sstevel@tonic-gate 	fp->fe_uniq_id = 0;
9970Sstevel@tonic-gate 	fp->fe_len_ear = 0;
9980Sstevel@tonic-gate 	fp->fe_len_adesc = sizeof (short_ad_t);
9990Sstevel@tonic-gate 
10000Sstevel@tonic-gate 	/* LINTED */
10010Sstevel@tonic-gate 	sap = (short_ad_t *)(fp->fe_spec + fp->fe_len_ear);
10020Sstevel@tonic-gate 	sap->sad_ext_len = sizeof (struct file_id);
10030Sstevel@tonic-gate 	sap->sad_ext_loc = nextlogblock + 1;
10040Sstevel@tonic-gate 	rootfelen = (char *)(sap + 1) - buf;
10050Sstevel@tonic-gate 	tp->tag_crc_len = rootfelen - sizeof (struct tag);
10060Sstevel@tonic-gate 	maketag(tp, tp);
10070Sstevel@tonic-gate 	wtfs(nextlogblock + part_start, sectorsize, (char *)tp);
10080Sstevel@tonic-gate 	nextlogblock++;
10090Sstevel@tonic-gate 
10100Sstevel@tonic-gate 	/*
10110Sstevel@tonic-gate 	 * Root Directory
10120Sstevel@tonic-gate 	 */
10130Sstevel@tonic-gate 	bzero(buf, sectorsize);
10140Sstevel@tonic-gate 	/* LINTED */
10150Sstevel@tonic-gate 	fip = (struct file_id *)&buf;
10160Sstevel@tonic-gate 	tp = &fip->fid_tag;
10170Sstevel@tonic-gate 	tp->tag_id =  UD_FILE_ID_DESC;
10180Sstevel@tonic-gate 	tp->tag_desc_ver = ecma_version;
10190Sstevel@tonic-gate 	tp->tag_sno = serialnum;
10200Sstevel@tonic-gate 	tp->tag_crc_len = sizeof (struct file_id) -
10210Sstevel@tonic-gate 			sizeof (struct tag);
10220Sstevel@tonic-gate 	tp->tag_loc = nextlogblock;
10230Sstevel@tonic-gate 	fip->fid_ver = 1;
10240Sstevel@tonic-gate 	fip->fid_flags = FID_DIR | FID_PARENT;
10250Sstevel@tonic-gate 	fip->fid_idlen = 0;
10260Sstevel@tonic-gate 	fip->fid_iulen = 0;
10270Sstevel@tonic-gate 	fip->fid_icb.lad_ext_len = sectorsize; /* rootfelen; */
10280Sstevel@tonic-gate 	fip->fid_icb.lad_ext_loc = nextlogblock - 1;
10290Sstevel@tonic-gate 	fip->fid_icb.lad_ext_prn = 0;
10300Sstevel@tonic-gate 	maketag(tp, tp);
10310Sstevel@tonic-gate 	wtfs(nextlogblock + part_start, sectorsize, (char *)tp);
10320Sstevel@tonic-gate 	nextlogblock++;
10330Sstevel@tonic-gate 
10340Sstevel@tonic-gate 	/*
10350Sstevel@tonic-gate 	 * Now do the space bitmaps
10360Sstevel@tonic-gate 	 */
10370Sstevel@tonic-gate 	if (part_unalloc >= 0) {
10380Sstevel@tonic-gate 		int size = sectorsize * part_bmp_sectors;
10390Sstevel@tonic-gate 
10400Sstevel@tonic-gate 		sbp = (struct space_bmap_desc *)malloc(size);
10410Sstevel@tonic-gate 		if (!sbp) {
10420Sstevel@tonic-gate 			(void) fprintf(stdout,
10430Sstevel@tonic-gate 				gettext("Can't allocate bitmap space\n"));
10440Sstevel@tonic-gate 			exit(32);
10450Sstevel@tonic-gate 		}
10460Sstevel@tonic-gate 		bzero((char *)sbp, sectorsize * part_bmp_sectors);
10470Sstevel@tonic-gate 		tp = &sbp->sbd_tag;
10480Sstevel@tonic-gate 		tp->tag_id =  UD_SPA_BMAP_DESC;
10490Sstevel@tonic-gate 		tp->tag_desc_ver = ecma_version;
10500Sstevel@tonic-gate 		tp->tag_sno = serialnum;
10510Sstevel@tonic-gate 		tp->tag_crc_len = 0;	/* Don't do CRCs on bitmaps */
10520Sstevel@tonic-gate 		tp->tag_loc = part_unalloc;
10530Sstevel@tonic-gate 		sbp->sbd_nbits = part_len;
10540Sstevel@tonic-gate 		sbp->sbd_nbytes = part_bmp_bytes;
10550Sstevel@tonic-gate 		maketag(tp, tp);
10560Sstevel@tonic-gate 		if (part_unalloc >= 0) {
10570Sstevel@tonic-gate 			int32_t i;
10580Sstevel@tonic-gate 
10590Sstevel@tonic-gate 			cp = (uint8_t *)sbp + SPACEMAP_OFF;
10600Sstevel@tonic-gate 			i = nextlogblock / NBBY;
10610Sstevel@tonic-gate 			cp[i++] = (0xff << (nextlogblock % NBBY)) & 0xff;
10620Sstevel@tonic-gate 			while (i < part_bmp_bytes)
10630Sstevel@tonic-gate 				cp[i++] = 0xff;
10640Sstevel@tonic-gate 			if (part_len % NBBY)
10650Sstevel@tonic-gate 				cp[--i] = (unsigned)0xff >>
10660Sstevel@tonic-gate 					(NBBY - part_len % NBBY);
10670Sstevel@tonic-gate 
10680Sstevel@tonic-gate 			wtfs(part_unalloc + part_start, size, (char *)tp);
10690Sstevel@tonic-gate 		}
10700Sstevel@tonic-gate 		free((char *)sbp);
10710Sstevel@tonic-gate 	}
10720Sstevel@tonic-gate 
10730Sstevel@tonic-gate 	/*
10740Sstevel@tonic-gate 	 * Volume Integrity Descriptor
10750Sstevel@tonic-gate 	 */
10760Sstevel@tonic-gate 	nextblock = INTSEQSTART;
10770Sstevel@tonic-gate 	endblock = nextblock + INTSEQLEN / sectorsize;
10780Sstevel@tonic-gate 	/* LINTED */
10790Sstevel@tonic-gate 	lvip = (struct log_vol_int_desc *)&lvid;
10800Sstevel@tonic-gate 	tp = &lvip->lvid_tag;
10810Sstevel@tonic-gate 	tp->tag_id =  UD_LOG_VOL_INT;
10820Sstevel@tonic-gate 	tp->tag_desc_ver = ecma_version;
10830Sstevel@tonic-gate 	tp->tag_sno = serialnum;
10840Sstevel@tonic-gate 	tp->tag_loc = nextblock;
10850Sstevel@tonic-gate 	setstamp(&lvip->lvid_tstamp);
10860Sstevel@tonic-gate 	lvip->lvid_int_type = LOG_VOL_CLOSE_INT;
10870Sstevel@tonic-gate 	setextad(&lvip->lvid_nie, 0, 0);
10880Sstevel@tonic-gate 	lvip->lvid_npart = 1;
10890Sstevel@tonic-gate 	lvip->lvid_liu = 0x2e;
10900Sstevel@tonic-gate 	lvip->lvid_uniqid = MAXID + 1;
10910Sstevel@tonic-gate 	lvip->lvid_fst[0] = part_len - nextlogblock;	/* Free space */
10920Sstevel@tonic-gate 	lvip->lvid_fst[1] = part_len;			/* Size */
10930Sstevel@tonic-gate 	lviup = (struct lvid_iu *)&lvip->lvid_fst[2];
10940Sstevel@tonic-gate 	bcopy(&sunmicro, &lviup->lvidiu_regid, sizeof (regid_t));
10950Sstevel@tonic-gate 	lviup->lvidiu_nfiles = 0;
10960Sstevel@tonic-gate 	lviup->lvidiu_ndirs = 1;
10970Sstevel@tonic-gate 	lviup->lvidiu_mread = 0x102;
10980Sstevel@tonic-gate 	lviup->lvidiu_mwrite = 0x102;
10990Sstevel@tonic-gate 	lviup->lvidiu_maxwr = 0x150;
11000Sstevel@tonic-gate 	tp->tag_crc_len = sizeof (struct log_vol_int_desc) + lvip->lvid_liu -
11010Sstevel@tonic-gate 		sizeof (struct tag);
11020Sstevel@tonic-gate 	maketag(tp, tp);
11030Sstevel@tonic-gate 	wtfs(nextblock, sectorsize, (char *)tp);
11040Sstevel@tonic-gate 	nextblock++;
11050Sstevel@tonic-gate 
11060Sstevel@tonic-gate 	/*
11070Sstevel@tonic-gate 	 * Terminating Descriptor
11080Sstevel@tonic-gate 	 */
11090Sstevel@tonic-gate 	bzero(buf, sectorsize);
11100Sstevel@tonic-gate 	/* LINTED */
11110Sstevel@tonic-gate 	tdp = (struct term_desc *)buf;
11120Sstevel@tonic-gate 	tp = &tdp->td_tag;
11130Sstevel@tonic-gate 	tp->tag_id =  UD_TERM_DESC;
11140Sstevel@tonic-gate 	tp->tag_desc_ver = ecma_version;
11150Sstevel@tonic-gate 	tp->tag_sno = serialnum;
11160Sstevel@tonic-gate 	tp->tag_crc_len = sizeof (struct term_desc) - sizeof (struct tag);
11170Sstevel@tonic-gate 	tp->tag_loc = nextblock;
11180Sstevel@tonic-gate 	maketag(tp, tp);
11190Sstevel@tonic-gate 	wtfs(nextblock, sectorsize, (char *)tp);
11200Sstevel@tonic-gate 	nextblock++;
11210Sstevel@tonic-gate 
11220Sstevel@tonic-gate 	/* Zero out the rest of the LVI extent */
11230Sstevel@tonic-gate 	bzero(buf, sectorsize);
11240Sstevel@tonic-gate 	while (nextblock < endblock)
11250Sstevel@tonic-gate 		wtfs(nextblock++, sectorsize, buf);
11260Sstevel@tonic-gate }
11270Sstevel@tonic-gate 
11280Sstevel@tonic-gate /*
11290Sstevel@tonic-gate  * read a block from the file system
11300Sstevel@tonic-gate  */
11310Sstevel@tonic-gate static void
rdfs(daddr_t bno,int size,char * bf)11320Sstevel@tonic-gate rdfs(daddr_t bno, int size, char *bf)
11330Sstevel@tonic-gate {
11340Sstevel@tonic-gate 	int n, saverr;
11350Sstevel@tonic-gate 
11360Sstevel@tonic-gate 	if (llseek(fsi, (offset_t)bno * sectorsize, 0) < 0) {
11370Sstevel@tonic-gate 		saverr = errno;
11380Sstevel@tonic-gate 		(void) fprintf(stderr,
11390Sstevel@tonic-gate 			gettext("seek error on sector %ld: %s\n"),
11400Sstevel@tonic-gate 			bno, strerror(saverr));
11410Sstevel@tonic-gate 		exit(32);
11420Sstevel@tonic-gate 	}
11430Sstevel@tonic-gate 	n = read(fsi, bf, size);
11440Sstevel@tonic-gate 	if (n != size) {
11450Sstevel@tonic-gate 		saverr = errno;
11460Sstevel@tonic-gate 		(void) fprintf(stderr,
11470Sstevel@tonic-gate 			gettext("read error on sector %ld: %s\n"),
11480Sstevel@tonic-gate 			bno, strerror(saverr));
11490Sstevel@tonic-gate 		exit(32);
11500Sstevel@tonic-gate 	}
11510Sstevel@tonic-gate }
11520Sstevel@tonic-gate 
11530Sstevel@tonic-gate /*
11540Sstevel@tonic-gate  * write a block to the file system
11550Sstevel@tonic-gate  */
11560Sstevel@tonic-gate static void
wtfs(daddr_t bno,int size,char * bf)11570Sstevel@tonic-gate wtfs(daddr_t bno, int size, char *bf)
11580Sstevel@tonic-gate {
11590Sstevel@tonic-gate 	int n, saverr;
11600Sstevel@tonic-gate 
11610Sstevel@tonic-gate 	if (fso == -1)
11620Sstevel@tonic-gate 		return;
11630Sstevel@tonic-gate 
11640Sstevel@tonic-gate 	if (llseek(fso, (offset_t)bno * sectorsize, 0) < 0) {
11650Sstevel@tonic-gate 		saverr = errno;
11660Sstevel@tonic-gate 		(void) fprintf(stderr,
11670Sstevel@tonic-gate 			gettext("seek error on sector %ld: %s\n"),
11680Sstevel@tonic-gate 			bno, strerror(saverr));
11690Sstevel@tonic-gate 		exit(32);
11700Sstevel@tonic-gate 	}
11710Sstevel@tonic-gate 	if (Nflag)
11720Sstevel@tonic-gate 		return;
11730Sstevel@tonic-gate 	n = write(fso, bf, size);
11740Sstevel@tonic-gate 	if (n != size) {
11750Sstevel@tonic-gate 		saverr = errno;
11760Sstevel@tonic-gate 		(void) fprintf(stderr,
11770Sstevel@tonic-gate 			gettext("write error on sector %ld: %s\n"),
11780Sstevel@tonic-gate 			bno, strerror(saverr));
11790Sstevel@tonic-gate 		exit(32);
11800Sstevel@tonic-gate 	}
11810Sstevel@tonic-gate }
11820Sstevel@tonic-gate 
11830Sstevel@tonic-gate static void
usage()11840Sstevel@tonic-gate usage()
11850Sstevel@tonic-gate {
11860Sstevel@tonic-gate 	(void) fprintf(stderr,
11870Sstevel@tonic-gate 		gettext("udfs usage: mkfs [-F FSType] [-V]"
11880Sstevel@tonic-gate 		" [-m] [-o options] special size(sectors)\n"));
11890Sstevel@tonic-gate 	(void) fprintf(stderr,
11900Sstevel@tonic-gate 		gettext(" -m : dump fs cmd line used to make"
11910Sstevel@tonic-gate 		" this partition\n"));
11920Sstevel@tonic-gate 	(void) fprintf(stderr,
11930Sstevel@tonic-gate 		gettext(" -V : print this command line and return\n"));
11940Sstevel@tonic-gate 	(void) fprintf(stderr,
11950Sstevel@tonic-gate 		gettext(" -o : udfs options: :psize=%d:label=%s\n"),
11960Sstevel@tonic-gate 		sectorsize, udfs_label);
11970Sstevel@tonic-gate 	(void) fprintf(stderr,
11980Sstevel@tonic-gate 		gettext("NOTE that all -o suboptions: must"
11990Sstevel@tonic-gate 		" be separated only by commas so as to\n"));
12000Sstevel@tonic-gate 	(void) fprintf(stderr,
12010Sstevel@tonic-gate 		gettext("be parsed as a single argument\n"));
12020Sstevel@tonic-gate 	exit(32);
12030Sstevel@tonic-gate }
12040Sstevel@tonic-gate 
12050Sstevel@tonic-gate /*ARGSUSED*/
12060Sstevel@tonic-gate static void
dump_fscmd(char * fsys,int fsi)12070Sstevel@tonic-gate dump_fscmd(char *fsys, int fsi)
12080Sstevel@tonic-gate {
12090Sstevel@tonic-gate 	(void) printf(gettext("mkfs -F udfs -o "));
12100Sstevel@tonic-gate 	(void) printf("psize=%d,label=\"%s\" %s %d\n",
12110Sstevel@tonic-gate 		sectorsize, oldlabel, fsys, oldfssize);
12120Sstevel@tonic-gate }
12130Sstevel@tonic-gate 
12140Sstevel@tonic-gate /* number ************************************************************* */
12150Sstevel@tonic-gate /*									*/
12160Sstevel@tonic-gate /* Convert a numeric arg to binary					*/
12170Sstevel@tonic-gate /*									*/
12180Sstevel@tonic-gate /* Arg:	 big - maximum valid input number				*/
12190Sstevel@tonic-gate /* Global arg:  string - pointer to command arg				*/
12200Sstevel@tonic-gate /*									*/
12210Sstevel@tonic-gate /* Valid forms: 123 | 123k | 123*123 | 123x123				*/
12220Sstevel@tonic-gate /*									*/
12230Sstevel@tonic-gate /* Return:	converted number					*/
12240Sstevel@tonic-gate /*									*/
12250Sstevel@tonic-gate /* ******************************************************************** */
12260Sstevel@tonic-gate 
12270Sstevel@tonic-gate static int32_t
number(long big,char * param)12280Sstevel@tonic-gate number(long big, char *param)
12290Sstevel@tonic-gate {
12300Sstevel@tonic-gate 	char		*cs;
12310Sstevel@tonic-gate 	int64_t		n = 0;
12320Sstevel@tonic-gate 	int64_t		cut = BIG;
12330Sstevel@tonic-gate 	int32_t		minus = 0;
12340Sstevel@tonic-gate 
12350Sstevel@tonic-gate #define	FOUND_MULT	0x1
12360Sstevel@tonic-gate #define	FOUND_K		0x2
12370Sstevel@tonic-gate 
12380Sstevel@tonic-gate 	cs = string;
12390Sstevel@tonic-gate 	if (*cs == '-') {
12400Sstevel@tonic-gate 		minus = 1;
12410Sstevel@tonic-gate 		cs++;
12420Sstevel@tonic-gate 	}
12430Sstevel@tonic-gate 	n = 0;
12440Sstevel@tonic-gate 	while ((*cs != ' ') && (*cs != '\0') && (*cs != ',')) {
12450Sstevel@tonic-gate 		if ((*cs >= '0') && (*cs <= '9')) {
12460Sstevel@tonic-gate 			n = n * 10 + *cs - '0';
12470Sstevel@tonic-gate 			cs++;
12480Sstevel@tonic-gate 		} else if ((*cs == '*') || (*cs == 'x')) {
12490Sstevel@tonic-gate 			if (number_flags & FOUND_MULT) {
12500Sstevel@tonic-gate 				(void) fprintf(stderr,
12510Sstevel@tonic-gate 				gettext("mkfs: only one \"*\" "
12520Sstevel@tonic-gate 				"or \"x\" allowed\n"));
12530Sstevel@tonic-gate 				exit(2);
12540Sstevel@tonic-gate 			}
12550Sstevel@tonic-gate 			number_flags |= FOUND_MULT;
12560Sstevel@tonic-gate 			cs++;
12570Sstevel@tonic-gate 			string = cs;
12580Sstevel@tonic-gate 			n = n * number(big, param);
12590Sstevel@tonic-gate 			cs = string;
12600Sstevel@tonic-gate 			continue;
12610Sstevel@tonic-gate 		} else if (*cs == 'k') {
12620Sstevel@tonic-gate 			if (number_flags & FOUND_K) {
12630Sstevel@tonic-gate 				(void) fprintf(stderr,
12640Sstevel@tonic-gate 				gettext("mkfs: only one \"k\" allowed\n"));
12650Sstevel@tonic-gate 				exit(2);
12660Sstevel@tonic-gate 			}
12670Sstevel@tonic-gate 			number_flags |= FOUND_K;
12680Sstevel@tonic-gate 			n = n * 1024;
12690Sstevel@tonic-gate 			cs++;
12700Sstevel@tonic-gate 			continue;
12710Sstevel@tonic-gate 		} else {
12720Sstevel@tonic-gate 			(void) fprintf(stderr,
12730Sstevel@tonic-gate 				gettext("mkfs: bad numeric arg: \"%s\"\n"),
12740Sstevel@tonic-gate 				string);
12750Sstevel@tonic-gate 			exit(2);
12760Sstevel@tonic-gate 		}
12770Sstevel@tonic-gate 	}
12780Sstevel@tonic-gate 
12790Sstevel@tonic-gate 	if (n > cut) {
12800Sstevel@tonic-gate 		(void) fprintf(stderr,
12810Sstevel@tonic-gate 			gettext("mkfs: value for %s overflowed\n"), param);
12820Sstevel@tonic-gate 		exit(2);
12830Sstevel@tonic-gate 	}
12840Sstevel@tonic-gate 
12850Sstevel@tonic-gate 	if (minus) {
12860Sstevel@tonic-gate 		n = -n;
12870Sstevel@tonic-gate 	}
12880Sstevel@tonic-gate 
12890Sstevel@tonic-gate 	if ((n > big) || (n < 0)) {
12900Sstevel@tonic-gate 		(void) fprintf(stderr,
12910Sstevel@tonic-gate 			gettext("mkfs: argument %s out of range\n"), param);
12920Sstevel@tonic-gate 		exit(2);
12930Sstevel@tonic-gate 	}
12940Sstevel@tonic-gate 
12950Sstevel@tonic-gate 	string = cs;
12960Sstevel@tonic-gate 	return ((int32_t)n);
12970Sstevel@tonic-gate }
12980Sstevel@tonic-gate 
12990Sstevel@tonic-gate /* match ************************************************************** */
13000Sstevel@tonic-gate /*									*/
13010Sstevel@tonic-gate /* Compare two text strings for equality				*/
13020Sstevel@tonic-gate /*									*/
13030Sstevel@tonic-gate /* Arg:	 s - pointer to string to match with a command arg		*/
13040Sstevel@tonic-gate /* Global arg:  string - pointer to command arg				*/
13050Sstevel@tonic-gate /*									*/
13060Sstevel@tonic-gate /* Return:	1 if match, 0 if no match				*/
13070Sstevel@tonic-gate /*		If match, also reset `string' to point to the text	*/
13080Sstevel@tonic-gate /*		that follows the matching text.				*/
13090Sstevel@tonic-gate /*									*/
13100Sstevel@tonic-gate /* ******************************************************************** */
13110Sstevel@tonic-gate 
13120Sstevel@tonic-gate static int
match(char * s)13130Sstevel@tonic-gate match(char *s)
13140Sstevel@tonic-gate {
13150Sstevel@tonic-gate 	char *cs;
13160Sstevel@tonic-gate 
13170Sstevel@tonic-gate 	cs = string;
13180Sstevel@tonic-gate 	while (*cs++ == *s) {
13190Sstevel@tonic-gate 		if (*s++ == '\0') {
13200Sstevel@tonic-gate 			goto true;
13210Sstevel@tonic-gate 		}
13220Sstevel@tonic-gate 	}
13230Sstevel@tonic-gate 	if (*s != '\0') {
13240Sstevel@tonic-gate 		return (0);
13250Sstevel@tonic-gate 	}
13260Sstevel@tonic-gate 
13270Sstevel@tonic-gate true:
13280Sstevel@tonic-gate 	cs--;
13290Sstevel@tonic-gate 	string = cs;
13300Sstevel@tonic-gate 	return (1);
13310Sstevel@tonic-gate }
13320Sstevel@tonic-gate 
13330Sstevel@tonic-gate static uint32_t
get_bsize()13340Sstevel@tonic-gate get_bsize()
13350Sstevel@tonic-gate {
13360Sstevel@tonic-gate 	struct dk_cinfo info;
13370Sstevel@tonic-gate 	struct fd_char fd_char;
1338*9889SLarry.Liu@Sun.COM 	struct dk_minfo dkminfo;
13390Sstevel@tonic-gate 
13400Sstevel@tonic-gate 	if (ioctl(fso, DKIOCINFO, &info) < 0) {
13410Sstevel@tonic-gate 		perror("mkfs DKIOCINFO ");
13420Sstevel@tonic-gate 		(void) fprintf(stdout,
13430Sstevel@tonic-gate 			gettext("DKIOCINFO failed using psize = 2048"
13440Sstevel@tonic-gate 			" for creating file-system\n"));
13450Sstevel@tonic-gate 		return (0);
13460Sstevel@tonic-gate 	}
13470Sstevel@tonic-gate 
13480Sstevel@tonic-gate 	switch (info.dki_ctype) {
13490Sstevel@tonic-gate 		case DKC_CDROM :
13500Sstevel@tonic-gate 			return (2048);
13510Sstevel@tonic-gate 		case DKC_SCSI_CCS :
1352*9889SLarry.Liu@Sun.COM 			if (ioctl(fso, DKIOCGMEDIAINFO, &dkminfo) != -1) {
1353*9889SLarry.Liu@Sun.COM 				if (dkminfo.dki_lbsize != 0 &&
1354*9889SLarry.Liu@Sun.COM 				    POWEROF2(dkminfo.dki_lbsize / DEV_BSIZE) &&
1355*9889SLarry.Liu@Sun.COM 				    dkminfo.dki_lbsize != DEV_BSIZE) {
1356*9889SLarry.Liu@Sun.COM 					fprintf(stderr,
1357*9889SLarry.Liu@Sun.COM 					    gettext("The device sector size "
1358*9889SLarry.Liu@Sun.COM 					    "%u is not supported by udfs!\n"),
1359*9889SLarry.Liu@Sun.COM 					    dkminfo.dki_lbsize);
1360*9889SLarry.Liu@Sun.COM 					(void) close(fso);
1361*9889SLarry.Liu@Sun.COM 					exit(1);
1362*9889SLarry.Liu@Sun.COM 				}
1363*9889SLarry.Liu@Sun.COM 			}
13640Sstevel@tonic-gate 			/* FALLTHROUGH */
13650Sstevel@tonic-gate 		case DKC_INTEL82072 :
13660Sstevel@tonic-gate 			/* FALLTHROUGH */
13670Sstevel@tonic-gate 		case DKC_INTEL82077 :
13680Sstevel@tonic-gate 			/* FALLTHROUGH */
13690Sstevel@tonic-gate 		case DKC_DIRECT :
13700Sstevel@tonic-gate 			if (ioctl(fso, FDIOGCHAR, &fd_char) >= 0) {
13710Sstevel@tonic-gate 				return (fd_char.fdc_sec_size);
13720Sstevel@tonic-gate 			}
13730Sstevel@tonic-gate 			/* FALLTHROUGH */
13740Sstevel@tonic-gate 		case DKC_PCMCIA_ATA :
13750Sstevel@tonic-gate 			return (512);
13760Sstevel@tonic-gate 		default :
13770Sstevel@tonic-gate 			return (0);
13780Sstevel@tonic-gate 	}
13790Sstevel@tonic-gate }
13800Sstevel@tonic-gate 
13810Sstevel@tonic-gate /*
13820Sstevel@tonic-gate  * Read in the volume sequences descriptors.
13830Sstevel@tonic-gate  */
13840Sstevel@tonic-gate static int
readvolseq()13850Sstevel@tonic-gate readvolseq()
13860Sstevel@tonic-gate {
13870Sstevel@tonic-gate 	struct tag *tp;
13880Sstevel@tonic-gate 	uint8_t *cp, *end;
13890Sstevel@tonic-gate 	int err;
13900Sstevel@tonic-gate 	struct pri_vol_desc *pvolp;
13910Sstevel@tonic-gate 	struct part_desc *partp;
13920Sstevel@tonic-gate 	struct log_vol_desc *logvp;
13930Sstevel@tonic-gate 	struct anch_vol_desc_ptr *avp;
13940Sstevel@tonic-gate 	char *main_vdbuf;
13950Sstevel@tonic-gate 	uint32_t nextblock;
13960Sstevel@tonic-gate 
13970Sstevel@tonic-gate 	avp = (struct anch_vol_desc_ptr *)malloc(sectorsize);
13980Sstevel@tonic-gate 	rdfs(FIRSTAVDP, sectorsize, (char *)avp);
13990Sstevel@tonic-gate 	tp = (struct tag *)avp;
14000Sstevel@tonic-gate 	err = verifytag(tp, FIRSTAVDP, tp, UD_ANCH_VOL_DESC);
14010Sstevel@tonic-gate 	if (err)
14020Sstevel@tonic-gate 		return (0);
14030Sstevel@tonic-gate 	main_vdbuf = malloc(avp->avd_main_vdse.ext_len);
14040Sstevel@tonic-gate 	if (main_vdbuf == NULL) {
14050Sstevel@tonic-gate 		(void) fprintf(stderr, gettext("Cannot allocate space for "
14060Sstevel@tonic-gate 			"volume sequences\n"));
14070Sstevel@tonic-gate 		exit(32);
14080Sstevel@tonic-gate 	}
14090Sstevel@tonic-gate 	rdfs(avp->avd_main_vdse.ext_loc, avp->avd_main_vdse.ext_len,
14100Sstevel@tonic-gate 		main_vdbuf);
14110Sstevel@tonic-gate 	end = (uint8_t *)main_vdbuf + avp->avd_main_vdse.ext_len;
14120Sstevel@tonic-gate 
14130Sstevel@tonic-gate 	nextblock = avp->avd_main_vdse.ext_loc;
14140Sstevel@tonic-gate 	for (cp = (uint8_t *)main_vdbuf; cp < end; cp += sectorsize,
14150Sstevel@tonic-gate 		nextblock++) {
14160Sstevel@tonic-gate 		/* LINTED */
14170Sstevel@tonic-gate 		tp = (struct tag *)cp;
14180Sstevel@tonic-gate 		err = verifytag(tp, nextblock, tp, 0);
14190Sstevel@tonic-gate 		if (err)
14200Sstevel@tonic-gate 			continue;
14210Sstevel@tonic-gate 
14220Sstevel@tonic-gate 		switch (tp->tag_id) {
14230Sstevel@tonic-gate 		case UD_PRI_VOL_DESC:
14240Sstevel@tonic-gate 			/* Bump serial number, according to spec. */
14250Sstevel@tonic-gate 			serialnum = tp->tag_sno + 1;
14260Sstevel@tonic-gate 			pvolp = (struct pri_vol_desc *)tp;
14270Sstevel@tonic-gate 			oldlabel = pvolp->pvd_vol_id + 1;
14280Sstevel@tonic-gate 			break;
14290Sstevel@tonic-gate 		case UD_ANCH_VOL_DESC:
14300Sstevel@tonic-gate 			avp = (struct anch_vol_desc_ptr *)tp;
14310Sstevel@tonic-gate 			break;
14320Sstevel@tonic-gate 		case UD_VOL_DESC_PTR:
14330Sstevel@tonic-gate 			break;
14340Sstevel@tonic-gate 		case UD_IMPL_USE_DESC:
14350Sstevel@tonic-gate 			break;
14360Sstevel@tonic-gate 		case UD_PART_DESC:
14370Sstevel@tonic-gate 			partp = (struct part_desc *)tp;
14380Sstevel@tonic-gate 			part_start = partp->pd_part_start;
14390Sstevel@tonic-gate 			part_len = partp->pd_part_length;
14400Sstevel@tonic-gate 			oldfssize = part_start + part_len;
14410Sstevel@tonic-gate 			break;
14420Sstevel@tonic-gate 		case UD_LOG_VOL_DESC:
14430Sstevel@tonic-gate 			logvp = (struct log_vol_desc *)tp;
14440Sstevel@tonic-gate 			break;
14450Sstevel@tonic-gate 		case UD_UNALL_SPA_DESC:
14460Sstevel@tonic-gate 			break;
14470Sstevel@tonic-gate 		case UD_TERM_DESC:
14480Sstevel@tonic-gate 			goto done;
14490Sstevel@tonic-gate 			break;
14500Sstevel@tonic-gate 		case UD_LOG_VOL_INT:
14510Sstevel@tonic-gate 			break;
14520Sstevel@tonic-gate 		default:
14530Sstevel@tonic-gate 			break;
14540Sstevel@tonic-gate 		}
14550Sstevel@tonic-gate 	}
14560Sstevel@tonic-gate done:
14570Sstevel@tonic-gate 	if (!partp || !logvp) {
14580Sstevel@tonic-gate 		return (0);
14590Sstevel@tonic-gate 	}
14600Sstevel@tonic-gate 	return (1);
14610Sstevel@tonic-gate }
14620Sstevel@tonic-gate 
14630Sstevel@tonic-gate uint32_t
get_last_block()14640Sstevel@tonic-gate get_last_block()
14650Sstevel@tonic-gate {
14660Sstevel@tonic-gate 	struct vtoc vtoc;
14670Sstevel@tonic-gate 	struct dk_cinfo dki_info;
14680Sstevel@tonic-gate 
14690Sstevel@tonic-gate 	if (ioctl(fsi, DKIOCGVTOC, (intptr_t)&vtoc) != 0) {
14700Sstevel@tonic-gate 		(void) fprintf(stderr, gettext("Unable to read VTOC\n"));
14710Sstevel@tonic-gate 		return (0);
14720Sstevel@tonic-gate 	}
14730Sstevel@tonic-gate 
14740Sstevel@tonic-gate 	if (vtoc.v_sanity != VTOC_SANE) {
14750Sstevel@tonic-gate 		(void) fprintf(stderr, gettext("Vtoc.v_sanity != VTOC_SANE\n"));
14760Sstevel@tonic-gate 		return (0);
14770Sstevel@tonic-gate 	}
14780Sstevel@tonic-gate 
14790Sstevel@tonic-gate 	if (ioctl(fsi, DKIOCINFO, (intptr_t)&dki_info) != 0) {
14800Sstevel@tonic-gate 		(void) fprintf(stderr,
14810Sstevel@tonic-gate 		    gettext("Could not get the slice information\n"));
14820Sstevel@tonic-gate 		return (0);
14830Sstevel@tonic-gate 	}
14840Sstevel@tonic-gate 
14850Sstevel@tonic-gate 	if (dki_info.dki_partition > V_NUMPAR) {
14860Sstevel@tonic-gate 		(void) fprintf(stderr,
14870Sstevel@tonic-gate 		    gettext("dki_info.dki_partition > V_NUMPAR\n"));
14880Sstevel@tonic-gate 		return (0);
14890Sstevel@tonic-gate 	}
14900Sstevel@tonic-gate 
14910Sstevel@tonic-gate 	return ((uint32_t)vtoc.v_part[dki_info.dki_partition].p_size);
14920Sstevel@tonic-gate }
1493