xref: /illumos-gate/usr/src/cmd/fs.d/udfs/mkfs/mkfs.c (revision 7c478bd9)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  */
22*7c478bd9Sstevel@tonic-gate /*
23*7c478bd9Sstevel@tonic-gate  * Copyright 2000 Sun Microsystems, Inc.  All rights reserved.
24*7c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
25*7c478bd9Sstevel@tonic-gate  */
26*7c478bd9Sstevel@tonic-gate 
27*7c478bd9Sstevel@tonic-gate /*	Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T	*/
28*7c478bd9Sstevel@tonic-gate /*	  All Rights Reserved  	*/
29*7c478bd9Sstevel@tonic-gate 
30*7c478bd9Sstevel@tonic-gate /*
31*7c478bd9Sstevel@tonic-gate  * Portions of this source code were derived from Berkeley 4.3 BSD
32*7c478bd9Sstevel@tonic-gate  * under license from the Regents of the University of California.
33*7c478bd9Sstevel@tonic-gate  */
34*7c478bd9Sstevel@tonic-gate 
35*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
36*7c478bd9Sstevel@tonic-gate 
37*7c478bd9Sstevel@tonic-gate /*
38*7c478bd9Sstevel@tonic-gate  * make file system for udfs (UDF - ISO13346)
39*7c478bd9Sstevel@tonic-gate  *
40*7c478bd9Sstevel@tonic-gate  * usage:
41*7c478bd9Sstevel@tonic-gate  *
42*7c478bd9Sstevel@tonic-gate  *    mkfs [-F FSType] [-V] [-m] [options]
43*7c478bd9Sstevel@tonic-gate  *	[-o specific_options]  special size
44*7c478bd9Sstevel@tonic-gate  *
45*7c478bd9Sstevel@tonic-gate  *  where specific_options are:
46*7c478bd9Sstevel@tonic-gate  *	N - no create
47*7c478bd9Sstevel@tonic-gate  *	label - volume label
48*7c478bd9Sstevel@tonic-gate  *	psize - physical block size
49*7c478bd9Sstevel@tonic-gate  */
50*7c478bd9Sstevel@tonic-gate 
51*7c478bd9Sstevel@tonic-gate #include	<stdio.h>
52*7c478bd9Sstevel@tonic-gate #include	<strings.h>
53*7c478bd9Sstevel@tonic-gate #include	<string.h>
54*7c478bd9Sstevel@tonic-gate #include	<stdlib.h>
55*7c478bd9Sstevel@tonic-gate #include	<unistd.h>
56*7c478bd9Sstevel@tonic-gate #include	<time.h>
57*7c478bd9Sstevel@tonic-gate #include	<locale.h>
58*7c478bd9Sstevel@tonic-gate #include	<fcntl.h>
59*7c478bd9Sstevel@tonic-gate #include	<errno.h>
60*7c478bd9Sstevel@tonic-gate #include	<limits.h>
61*7c478bd9Sstevel@tonic-gate #include	<sys/mnttab.h>
62*7c478bd9Sstevel@tonic-gate #include	<sys/param.h>
63*7c478bd9Sstevel@tonic-gate #include	<sys/types.h>
64*7c478bd9Sstevel@tonic-gate #include	<sys/sysmacros.h>
65*7c478bd9Sstevel@tonic-gate #include	<sys/vnode.h>
66*7c478bd9Sstevel@tonic-gate #include	<sys/mntent.h>
67*7c478bd9Sstevel@tonic-gate #include	<sys/filio.h>
68*7c478bd9Sstevel@tonic-gate #include	<sys/stat.h>
69*7c478bd9Sstevel@tonic-gate #include	<ustat.h>
70*7c478bd9Sstevel@tonic-gate #include 	<sys/isa_defs.h>	/* for ENDIAN defines */
71*7c478bd9Sstevel@tonic-gate #include	<sys/dkio.h>
72*7c478bd9Sstevel@tonic-gate #include	<sys/fdio.h>
73*7c478bd9Sstevel@tonic-gate #include	<sys/vtoc.h>
74*7c478bd9Sstevel@tonic-gate #include	<sys/fs/udf_volume.h>
75*7c478bd9Sstevel@tonic-gate 
76*7c478bd9Sstevel@tonic-gate extern char	*getfullrawname(char *);
77*7c478bd9Sstevel@tonic-gate extern char	*getfullblkname(char *);
78*7c478bd9Sstevel@tonic-gate extern struct tm *localtime_r(const time_t *, struct tm *);
79*7c478bd9Sstevel@tonic-gate extern void	maketag(struct tag *, struct tag *);
80*7c478bd9Sstevel@tonic-gate extern int	verifytag(struct tag *, uint32_t, struct tag *, int);
81*7c478bd9Sstevel@tonic-gate extern void	setcharspec(struct charspec *, int32_t, uint8_t *);
82*7c478bd9Sstevel@tonic-gate 
83*7c478bd9Sstevel@tonic-gate 
84*7c478bd9Sstevel@tonic-gate #define	UMASK		0755
85*7c478bd9Sstevel@tonic-gate #define	POWEROF2(num)	(((num) & ((num) - 1)) == 0)
86*7c478bd9Sstevel@tonic-gate #define	MB		(1024*1024)
87*7c478bd9Sstevel@tonic-gate 
88*7c478bd9Sstevel@tonic-gate /*
89*7c478bd9Sstevel@tonic-gate  * Forward declarations
90*7c478bd9Sstevel@tonic-gate  */
91*7c478bd9Sstevel@tonic-gate static void rdfs(daddr_t bno, int size, char *bf);
92*7c478bd9Sstevel@tonic-gate static void wtfs(daddr_t bno, int size, char *bf);
93*7c478bd9Sstevel@tonic-gate static void dump_fscmd(char *fsys, int fsi);
94*7c478bd9Sstevel@tonic-gate static int32_t number(long big, char *param);
95*7c478bd9Sstevel@tonic-gate static void usage();
96*7c478bd9Sstevel@tonic-gate static int match(char *s);
97*7c478bd9Sstevel@tonic-gate static int readvolseq();
98*7c478bd9Sstevel@tonic-gate static uint32_t get_last_block();
99*7c478bd9Sstevel@tonic-gate 
100*7c478bd9Sstevel@tonic-gate /*
101*7c478bd9Sstevel@tonic-gate  * variables set up by front end.
102*7c478bd9Sstevel@tonic-gate  */
103*7c478bd9Sstevel@tonic-gate static int	Nflag = 0;		/* run mkfs without writing */
104*7c478bd9Sstevel@tonic-gate 					/* file system */
105*7c478bd9Sstevel@tonic-gate static int	mflag = 0;		/* return the command line used */
106*7c478bd9Sstevel@tonic-gate 					/* to create this FS */
107*7c478bd9Sstevel@tonic-gate static int	fssize;			/* file system size */
108*7c478bd9Sstevel@tonic-gate static uint32_t	disk_size;		/* partition size from VTOC */
109*7c478bd9Sstevel@tonic-gate static uint32_t unused;			/* unused sectors in partition */
110*7c478bd9Sstevel@tonic-gate static int	sectorsize = 2048;	/* bytes/sector default */
111*7c478bd9Sstevel@tonic-gate 					/* If nothing specified */
112*7c478bd9Sstevel@tonic-gate 
113*7c478bd9Sstevel@tonic-gate static char	*fsys;
114*7c478bd9Sstevel@tonic-gate static int	fsi;
115*7c478bd9Sstevel@tonic-gate static int	fso;
116*7c478bd9Sstevel@tonic-gate 
117*7c478bd9Sstevel@tonic-gate #define	BIG	LONG_MAX
118*7c478bd9Sstevel@tonic-gate static	uint32_t	number_flags = 0;
119*7c478bd9Sstevel@tonic-gate 
120*7c478bd9Sstevel@tonic-gate static char	*string;
121*7c478bd9Sstevel@tonic-gate 
122*7c478bd9Sstevel@tonic-gate static void	setstamp(tstamp_t *);
123*7c478bd9Sstevel@tonic-gate static void	setextad(extent_ad_t *, uint32_t, uint32_t);
124*7c478bd9Sstevel@tonic-gate static void	setdstring(dstring_t *, char *, int32_t);
125*7c478bd9Sstevel@tonic-gate static void	wtvolseq(tag_t *, daddr_t, daddr_t);
126*7c478bd9Sstevel@tonic-gate static void	volseqinit();
127*7c478bd9Sstevel@tonic-gate static void	setstamp(tstamp_t *);
128*7c478bd9Sstevel@tonic-gate static uint32_t	get_bsize();
129*7c478bd9Sstevel@tonic-gate 
130*7c478bd9Sstevel@tonic-gate 
131*7c478bd9Sstevel@tonic-gate #define	VOLRECSTART	(32 * 1024)
132*7c478bd9Sstevel@tonic-gate 
133*7c478bd9Sstevel@tonic-gate #define	VOLSEQSTART	128
134*7c478bd9Sstevel@tonic-gate #define	VOLSEQLEN	16
135*7c478bd9Sstevel@tonic-gate #define	INTSEQSTART	192
136*7c478bd9Sstevel@tonic-gate #define	INTSEQLEN	8192
137*7c478bd9Sstevel@tonic-gate #define	FIRSTAVDP	256
138*7c478bd9Sstevel@tonic-gate #define	AVDPLEN		1
139*7c478bd9Sstevel@tonic-gate 
140*7c478bd9Sstevel@tonic-gate 
141*7c478bd9Sstevel@tonic-gate #define	FILESETLEN	2
142*7c478bd9Sstevel@tonic-gate 
143*7c478bd9Sstevel@tonic-gate #define	SPACEMAP_OFF	24
144*7c478bd9Sstevel@tonic-gate #define	MAXID		16
145*7c478bd9Sstevel@tonic-gate 
146*7c478bd9Sstevel@tonic-gate static time_t mkfstime;
147*7c478bd9Sstevel@tonic-gate static struct tm res;
148*7c478bd9Sstevel@tonic-gate static long tzone;
149*7c478bd9Sstevel@tonic-gate static char vsibuf[128];
150*7c478bd9Sstevel@tonic-gate 
151*7c478bd9Sstevel@tonic-gate static regid_t sunmicro = { 0, "*SUN SOLARIS UDF", 4, 2 };
152*7c478bd9Sstevel@tonic-gate static regid_t lvinfo = { 0, "*UDF LV Info", 0x50, 0x1, 4, 2 };
153*7c478bd9Sstevel@tonic-gate static regid_t partid = { 0, "+NSR02", 0 };
154*7c478bd9Sstevel@tonic-gate static regid_t udf_compliant = { 0, "*OSTA UDF Compliant", 0x50, 0x1, 0 };
155*7c478bd9Sstevel@tonic-gate static uint8_t osta_unicode[] = "OSTA Compressed Unicode";
156*7c478bd9Sstevel@tonic-gate 
157*7c478bd9Sstevel@tonic-gate static int bdevismounted;
158*7c478bd9Sstevel@tonic-gate static int ismounted;
159*7c478bd9Sstevel@tonic-gate static int directory;
160*7c478bd9Sstevel@tonic-gate static char buf[MAXBSIZE];
161*7c478bd9Sstevel@tonic-gate static char buf2[MAXBSIZE];
162*7c478bd9Sstevel@tonic-gate static char lvid[MAXBSIZE];
163*7c478bd9Sstevel@tonic-gate 
164*7c478bd9Sstevel@tonic-gate uint32_t ecma_version = 2;
165*7c478bd9Sstevel@tonic-gate 
166*7c478bd9Sstevel@tonic-gate static int serialnum = 1;	/* Tag serial number */
167*7c478bd9Sstevel@tonic-gate static char udfs_label[128] = "*NoLabel*";
168*7c478bd9Sstevel@tonic-gate static int acctype = PART_ACC_OW;
169*7c478bd9Sstevel@tonic-gate static uint32_t part_start;
170*7c478bd9Sstevel@tonic-gate static uint32_t part_len;
171*7c478bd9Sstevel@tonic-gate static uint32_t part_bmp_bytes;
172*7c478bd9Sstevel@tonic-gate static uint32_t part_bmp_sectors;
173*7c478bd9Sstevel@tonic-gate static int32_t part_unalloc = -1;
174*7c478bd9Sstevel@tonic-gate static uint32_t filesetblock;
175*7c478bd9Sstevel@tonic-gate 
176*7c478bd9Sstevel@tonic-gate /* Set by readvolseq for -m option */
177*7c478bd9Sstevel@tonic-gate static uint32_t oldfssize;
178*7c478bd9Sstevel@tonic-gate static char *oldlabel;
179*7c478bd9Sstevel@tonic-gate 
180*7c478bd9Sstevel@tonic-gate main(int32_t argc, int8_t *argv[])
181*7c478bd9Sstevel@tonic-gate {
182*7c478bd9Sstevel@tonic-gate 	long i;
183*7c478bd9Sstevel@tonic-gate 	FILE *mnttab;
184*7c478bd9Sstevel@tonic-gate 	struct mnttab mntp;
185*7c478bd9Sstevel@tonic-gate 	char *special, *raw_special;
186*7c478bd9Sstevel@tonic-gate 	struct stat statarea;
187*7c478bd9Sstevel@tonic-gate 	struct ustat ustatarea;
188*7c478bd9Sstevel@tonic-gate 	int32_t	c;
189*7c478bd9Sstevel@tonic-gate 	uint32_t temp_secsz;
190*7c478bd9Sstevel@tonic-gate 	int isfs;
191*7c478bd9Sstevel@tonic-gate 
192*7c478bd9Sstevel@tonic-gate 	(void) setlocale(LC_ALL, "");
193*7c478bd9Sstevel@tonic-gate 
194*7c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN)
195*7c478bd9Sstevel@tonic-gate #define	TEXT_DOMAIN "SYS_TEST"
196*7c478bd9Sstevel@tonic-gate #endif
197*7c478bd9Sstevel@tonic-gate 	(void) textdomain(TEXT_DOMAIN);
198*7c478bd9Sstevel@tonic-gate 
199*7c478bd9Sstevel@tonic-gate 	while ((c = getopt(argc, argv, "F:Vmo:")) != EOF) {
200*7c478bd9Sstevel@tonic-gate 		switch (c) {
201*7c478bd9Sstevel@tonic-gate 
202*7c478bd9Sstevel@tonic-gate 			case 'F':
203*7c478bd9Sstevel@tonic-gate 				string = optarg;
204*7c478bd9Sstevel@tonic-gate 				if (strcmp(string, "udfs") != 0) {
205*7c478bd9Sstevel@tonic-gate 					usage();
206*7c478bd9Sstevel@tonic-gate 				}
207*7c478bd9Sstevel@tonic-gate 				break;
208*7c478bd9Sstevel@tonic-gate 
209*7c478bd9Sstevel@tonic-gate 			case 'V':
210*7c478bd9Sstevel@tonic-gate 				{
211*7c478bd9Sstevel@tonic-gate 					char	*opt_text;
212*7c478bd9Sstevel@tonic-gate 					int	opt_count;
213*7c478bd9Sstevel@tonic-gate 
214*7c478bd9Sstevel@tonic-gate 					(void) fprintf(stdout,
215*7c478bd9Sstevel@tonic-gate 					gettext("mkfs -F udfs "));
216*7c478bd9Sstevel@tonic-gate 					for (opt_count = 1; opt_count < argc;
217*7c478bd9Sstevel@tonic-gate 							opt_count++) {
218*7c478bd9Sstevel@tonic-gate 						opt_text = argv[opt_count];
219*7c478bd9Sstevel@tonic-gate 						if (opt_text) {
220*7c478bd9Sstevel@tonic-gate 							(void) fprintf(stdout,
221*7c478bd9Sstevel@tonic-gate 							" %s ", opt_text);
222*7c478bd9Sstevel@tonic-gate 						}
223*7c478bd9Sstevel@tonic-gate 					}
224*7c478bd9Sstevel@tonic-gate 					(void) fprintf(stdout, "\n");
225*7c478bd9Sstevel@tonic-gate 				}
226*7c478bd9Sstevel@tonic-gate 				break;
227*7c478bd9Sstevel@tonic-gate 
228*7c478bd9Sstevel@tonic-gate 			case 'm':
229*7c478bd9Sstevel@tonic-gate 				/*
230*7c478bd9Sstevel@tonic-gate 				 * return command line used
231*7c478bd9Sstevel@tonic-gate 				 * to create this FS
232*7c478bd9Sstevel@tonic-gate 				 */
233*7c478bd9Sstevel@tonic-gate 				mflag++;
234*7c478bd9Sstevel@tonic-gate 				break;
235*7c478bd9Sstevel@tonic-gate 
236*7c478bd9Sstevel@tonic-gate 			case 'o':
237*7c478bd9Sstevel@tonic-gate 				/*
238*7c478bd9Sstevel@tonic-gate 				 * udfs specific options.
239*7c478bd9Sstevel@tonic-gate 				 */
240*7c478bd9Sstevel@tonic-gate 				string = optarg;
241*7c478bd9Sstevel@tonic-gate 				while (*string != '\0') {
242*7c478bd9Sstevel@tonic-gate 					if (match("N")) {
243*7c478bd9Sstevel@tonic-gate 						Nflag++;
244*7c478bd9Sstevel@tonic-gate 					} else if (match("psize=")) {
245*7c478bd9Sstevel@tonic-gate 						number_flags = 0;
246*7c478bd9Sstevel@tonic-gate 						sectorsize = number(BIG,
247*7c478bd9Sstevel@tonic-gate 							"psize");
248*7c478bd9Sstevel@tonic-gate 					} else if (match("label=")) {
249*7c478bd9Sstevel@tonic-gate 						for (i = 0; i < 31; i++) {
250*7c478bd9Sstevel@tonic-gate 							if (*string == '\0') {
251*7c478bd9Sstevel@tonic-gate 								break;
252*7c478bd9Sstevel@tonic-gate 							}
253*7c478bd9Sstevel@tonic-gate 							udfs_label[i] =
254*7c478bd9Sstevel@tonic-gate 								*string++;
255*7c478bd9Sstevel@tonic-gate 						}
256*7c478bd9Sstevel@tonic-gate 						udfs_label[i] = '\0';
257*7c478bd9Sstevel@tonic-gate 					} else if (*string == '\0') {
258*7c478bd9Sstevel@tonic-gate 						break;
259*7c478bd9Sstevel@tonic-gate 					} else {
260*7c478bd9Sstevel@tonic-gate 						(void) fprintf(stdout,
261*7c478bd9Sstevel@tonic-gate 							gettext("illegal "
262*7c478bd9Sstevel@tonic-gate 							"option: %s\n"),
263*7c478bd9Sstevel@tonic-gate 							string);
264*7c478bd9Sstevel@tonic-gate 						usage();
265*7c478bd9Sstevel@tonic-gate 					}
266*7c478bd9Sstevel@tonic-gate 					if (*string == ',') {
267*7c478bd9Sstevel@tonic-gate 						string++;
268*7c478bd9Sstevel@tonic-gate 					}
269*7c478bd9Sstevel@tonic-gate 					if (*string == ' ') {
270*7c478bd9Sstevel@tonic-gate 						string++;
271*7c478bd9Sstevel@tonic-gate 					}
272*7c478bd9Sstevel@tonic-gate 				}
273*7c478bd9Sstevel@tonic-gate 				break;
274*7c478bd9Sstevel@tonic-gate 
275*7c478bd9Sstevel@tonic-gate 			case '?':
276*7c478bd9Sstevel@tonic-gate 				usage();
277*7c478bd9Sstevel@tonic-gate 				break;
278*7c478bd9Sstevel@tonic-gate 		}
279*7c478bd9Sstevel@tonic-gate 	}
280*7c478bd9Sstevel@tonic-gate 
281*7c478bd9Sstevel@tonic-gate 	(void) time(&mkfstime);
282*7c478bd9Sstevel@tonic-gate 	if (optind > (argc - 1)) {
283*7c478bd9Sstevel@tonic-gate 		usage();
284*7c478bd9Sstevel@tonic-gate 	}
285*7c478bd9Sstevel@tonic-gate 
286*7c478bd9Sstevel@tonic-gate 	argc -= optind;
287*7c478bd9Sstevel@tonic-gate 	argv = &argv[optind];
288*7c478bd9Sstevel@tonic-gate 	fsys = argv[0];
289*7c478bd9Sstevel@tonic-gate 	raw_special = getfullrawname(fsys);
290*7c478bd9Sstevel@tonic-gate 	fsi = open(raw_special, 0);
291*7c478bd9Sstevel@tonic-gate 	if (fsi < 0) {
292*7c478bd9Sstevel@tonic-gate 		(void) fprintf(stdout,
293*7c478bd9Sstevel@tonic-gate 			gettext("%s: cannot open\n"), fsys);
294*7c478bd9Sstevel@tonic-gate 		exit(32);
295*7c478bd9Sstevel@tonic-gate 	}
296*7c478bd9Sstevel@tonic-gate 	fso = fsi;
297*7c478bd9Sstevel@tonic-gate 
298*7c478bd9Sstevel@tonic-gate 	if ((temp_secsz = get_bsize()) != 0) {
299*7c478bd9Sstevel@tonic-gate 		sectorsize = temp_secsz;
300*7c478bd9Sstevel@tonic-gate 	}
301*7c478bd9Sstevel@tonic-gate 
302*7c478bd9Sstevel@tonic-gate 	/* Get old file system information */
303*7c478bd9Sstevel@tonic-gate 	isfs = readvolseq();
304*7c478bd9Sstevel@tonic-gate 
305*7c478bd9Sstevel@tonic-gate 	if (mflag) {
306*7c478bd9Sstevel@tonic-gate 		/*
307*7c478bd9Sstevel@tonic-gate 		 * Figure out the block size and
308*7c478bd9Sstevel@tonic-gate 		 * file system size and print the information
309*7c478bd9Sstevel@tonic-gate 		 */
310*7c478bd9Sstevel@tonic-gate 		if (isfs)
311*7c478bd9Sstevel@tonic-gate 			dump_fscmd(fsys, fsi);
312*7c478bd9Sstevel@tonic-gate 		else
313*7c478bd9Sstevel@tonic-gate 			(void) printf(gettext(
314*7c478bd9Sstevel@tonic-gate 				"[not currently a valid file system]\n"));
315*7c478bd9Sstevel@tonic-gate 		exit(0);
316*7c478bd9Sstevel@tonic-gate 	}
317*7c478bd9Sstevel@tonic-gate 
318*7c478bd9Sstevel@tonic-gate 	/*
319*7c478bd9Sstevel@tonic-gate 	 * Get the disk size from the drive or VTOC for the N and N-256
320*7c478bd9Sstevel@tonic-gate 	 * AVDPs and to make sure we don't want to create a file system
321*7c478bd9Sstevel@tonic-gate 	 * bigger than the partition.
322*7c478bd9Sstevel@tonic-gate 	 */
323*7c478bd9Sstevel@tonic-gate 	disk_size = get_last_block();
324*7c478bd9Sstevel@tonic-gate 
325*7c478bd9Sstevel@tonic-gate 	if (argc < 2 && disk_size == 0 || argc < 1) {
326*7c478bd9Sstevel@tonic-gate 		usage();
327*7c478bd9Sstevel@tonic-gate 	}
328*7c478bd9Sstevel@tonic-gate 
329*7c478bd9Sstevel@tonic-gate 	if (argc < 2) {
330*7c478bd9Sstevel@tonic-gate 		(void) printf(gettext("No size specified, entire partition "
331*7c478bd9Sstevel@tonic-gate 			"of %u sectors used\n"), disk_size);
332*7c478bd9Sstevel@tonic-gate 		fssize = disk_size;
333*7c478bd9Sstevel@tonic-gate 	} else {
334*7c478bd9Sstevel@tonic-gate 		string = argv[1];
335*7c478bd9Sstevel@tonic-gate 		number_flags = 0;
336*7c478bd9Sstevel@tonic-gate 		fssize = number(BIG, "size");
337*7c478bd9Sstevel@tonic-gate 	}
338*7c478bd9Sstevel@tonic-gate 
339*7c478bd9Sstevel@tonic-gate 	if (fssize < 0) {
340*7c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr,
341*7c478bd9Sstevel@tonic-gate 			gettext("Negative number of sectors(%d) not allowed\n"),
342*7c478bd9Sstevel@tonic-gate 			fssize);
343*7c478bd9Sstevel@tonic-gate 		exit(32);
344*7c478bd9Sstevel@tonic-gate 	}
345*7c478bd9Sstevel@tonic-gate 
346*7c478bd9Sstevel@tonic-gate 	if (fssize < (512 * sectorsize / DEV_BSIZE)) {
347*7c478bd9Sstevel@tonic-gate 		(void) fprintf(stdout,
348*7c478bd9Sstevel@tonic-gate 			gettext("size should be at least %d sectors\n"),
349*7c478bd9Sstevel@tonic-gate 			(512 * sectorsize / DEV_BSIZE));
350*7c478bd9Sstevel@tonic-gate 		exit(32);
351*7c478bd9Sstevel@tonic-gate 	}
352*7c478bd9Sstevel@tonic-gate 
353*7c478bd9Sstevel@tonic-gate 	if (disk_size != 0) {
354*7c478bd9Sstevel@tonic-gate 		if (fssize > disk_size) {
355*7c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, gettext("Invalid size: %d "
356*7c478bd9Sstevel@tonic-gate 				"larger than the partition size\n"), fssize);
357*7c478bd9Sstevel@tonic-gate 			exit(32);
358*7c478bd9Sstevel@tonic-gate 		} else if (fssize < disk_size) {
359*7c478bd9Sstevel@tonic-gate 			unused = disk_size - fssize;
360*7c478bd9Sstevel@tonic-gate 			(void) printf(
361*7c478bd9Sstevel@tonic-gate 			    gettext("File system size %d smaller than "
362*7c478bd9Sstevel@tonic-gate 				"partition, %u sectors unused\n"),
363*7c478bd9Sstevel@tonic-gate 				fssize, unused);
364*7c478bd9Sstevel@tonic-gate 		}
365*7c478bd9Sstevel@tonic-gate 	} else {
366*7c478bd9Sstevel@tonic-gate 		/* Use passed-in size */
367*7c478bd9Sstevel@tonic-gate 		disk_size = fssize;
368*7c478bd9Sstevel@tonic-gate 	}
369*7c478bd9Sstevel@tonic-gate 
370*7c478bd9Sstevel@tonic-gate 	if (!Nflag) {
371*7c478bd9Sstevel@tonic-gate 		special = getfullblkname(fsys);
372*7c478bd9Sstevel@tonic-gate 
373*7c478bd9Sstevel@tonic-gate 		/*
374*7c478bd9Sstevel@tonic-gate 		 * If we found the block device name,
375*7c478bd9Sstevel@tonic-gate 		 * then check the mount table.
376*7c478bd9Sstevel@tonic-gate 		 * if mounted, write lock the file system
377*7c478bd9Sstevel@tonic-gate 		 *
378*7c478bd9Sstevel@tonic-gate 		 */
379*7c478bd9Sstevel@tonic-gate 		if ((special != NULL) && (*special != '\0')) {
380*7c478bd9Sstevel@tonic-gate 			mnttab = fopen(MNTTAB, "r");
381*7c478bd9Sstevel@tonic-gate 			while ((getmntent(mnttab, &mntp)) == NULL) {
382*7c478bd9Sstevel@tonic-gate 				if (strcmp(special, mntp.mnt_special) == 0) {
383*7c478bd9Sstevel@tonic-gate 					(void) fprintf(stdout,
384*7c478bd9Sstevel@tonic-gate 						gettext("%s is mounted,"
385*7c478bd9Sstevel@tonic-gate 						" can't mkfs\n"), special);
386*7c478bd9Sstevel@tonic-gate 					exit(32);
387*7c478bd9Sstevel@tonic-gate 				}
388*7c478bd9Sstevel@tonic-gate 			}
389*7c478bd9Sstevel@tonic-gate 			(void) fclose(mnttab);
390*7c478bd9Sstevel@tonic-gate 		}
391*7c478bd9Sstevel@tonic-gate 		if ((bdevismounted) && (ismounted == 0)) {
392*7c478bd9Sstevel@tonic-gate 			(void) fprintf(stdout,
393*7c478bd9Sstevel@tonic-gate 				gettext("can't check mount point; "));
394*7c478bd9Sstevel@tonic-gate 			(void) fprintf(stdout,
395*7c478bd9Sstevel@tonic-gate 				gettext("%s is mounted but not in mnttab(4)\n"),
396*7c478bd9Sstevel@tonic-gate 				special);
397*7c478bd9Sstevel@tonic-gate 			exit(32);
398*7c478bd9Sstevel@tonic-gate 		}
399*7c478bd9Sstevel@tonic-gate 		if (directory) {
400*7c478bd9Sstevel@tonic-gate 			if (ismounted == 0) {
401*7c478bd9Sstevel@tonic-gate 				(void) fprintf(stdout,
402*7c478bd9Sstevel@tonic-gate 					gettext("%s is not mounted\n"),
403*7c478bd9Sstevel@tonic-gate 					special);
404*7c478bd9Sstevel@tonic-gate 				exit(32);
405*7c478bd9Sstevel@tonic-gate 			}
406*7c478bd9Sstevel@tonic-gate 		}
407*7c478bd9Sstevel@tonic-gate 		fso = creat(fsys, 0666);
408*7c478bd9Sstevel@tonic-gate 		if (fso < 0) {
409*7c478bd9Sstevel@tonic-gate 			(void) fprintf(stdout,
410*7c478bd9Sstevel@tonic-gate 				gettext("%s: cannot create\n"), fsys);
411*7c478bd9Sstevel@tonic-gate 			exit(32);
412*7c478bd9Sstevel@tonic-gate 		}
413*7c478bd9Sstevel@tonic-gate 		if (stat(fsys, &statarea) < 0) {
414*7c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr,
415*7c478bd9Sstevel@tonic-gate 				gettext("%s: %s: cannot stat\n"),
416*7c478bd9Sstevel@tonic-gate 				argv[0], fsys);
417*7c478bd9Sstevel@tonic-gate 			exit(32);
418*7c478bd9Sstevel@tonic-gate 		}
419*7c478bd9Sstevel@tonic-gate 		if (ustat(statarea.st_rdev, &ustatarea) >= 0) {
420*7c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr,
421*7c478bd9Sstevel@tonic-gate 				gettext("%s is mounted, can't mkfs\n"), fsys);
422*7c478bd9Sstevel@tonic-gate 			exit(32);
423*7c478bd9Sstevel@tonic-gate 		}
424*7c478bd9Sstevel@tonic-gate 	} else {
425*7c478bd9Sstevel@tonic-gate 		/*
426*7c478bd9Sstevel@tonic-gate 		 * For the -N case, a file descriptor is needed for the llseek()
427*7c478bd9Sstevel@tonic-gate 		 * in wtfs(). See the comment in wtfs() for more information.
428*7c478bd9Sstevel@tonic-gate 		 *
429*7c478bd9Sstevel@tonic-gate 		 * Get a file descriptor that's read-only so that this code
430*7c478bd9Sstevel@tonic-gate 		 * doesn't accidentally write to the file.
431*7c478bd9Sstevel@tonic-gate 		 */
432*7c478bd9Sstevel@tonic-gate 		fso = open(fsys, O_RDONLY);
433*7c478bd9Sstevel@tonic-gate 		if (fso < 0) {
434*7c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, gettext("%s: cannot open\n"),
435*7c478bd9Sstevel@tonic-gate 				fsys);
436*7c478bd9Sstevel@tonic-gate 			exit(32);
437*7c478bd9Sstevel@tonic-gate 		}
438*7c478bd9Sstevel@tonic-gate 	}
439*7c478bd9Sstevel@tonic-gate 
440*7c478bd9Sstevel@tonic-gate 
441*7c478bd9Sstevel@tonic-gate 	/*
442*7c478bd9Sstevel@tonic-gate 	 * Validate the given file system size.
443*7c478bd9Sstevel@tonic-gate 	 * Verify that its last block can actually be accessed.
444*7c478bd9Sstevel@tonic-gate 	 */
445*7c478bd9Sstevel@tonic-gate 	fssize = fssize / (sectorsize / DEV_BSIZE);
446*7c478bd9Sstevel@tonic-gate 	if (fssize <= 0) {
447*7c478bd9Sstevel@tonic-gate 		(void) fprintf(stdout,
448*7c478bd9Sstevel@tonic-gate 			gettext("preposterous size %d. sectors\n"), fssize);
449*7c478bd9Sstevel@tonic-gate 		exit(32);
450*7c478bd9Sstevel@tonic-gate 	}
451*7c478bd9Sstevel@tonic-gate 	fssize --;
452*7c478bd9Sstevel@tonic-gate 
453*7c478bd9Sstevel@tonic-gate 	/*
454*7c478bd9Sstevel@tonic-gate 	 * verify device size
455*7c478bd9Sstevel@tonic-gate 	 */
456*7c478bd9Sstevel@tonic-gate 	rdfs(fssize - 1, sectorsize, buf);
457*7c478bd9Sstevel@tonic-gate 
458*7c478bd9Sstevel@tonic-gate 	if ((sectorsize < DEV_BSIZE) ||
459*7c478bd9Sstevel@tonic-gate 		(sectorsize > MAXBSIZE)) {
460*7c478bd9Sstevel@tonic-gate 		(void) fprintf(stdout,
461*7c478bd9Sstevel@tonic-gate 			gettext("sector size must be"
462*7c478bd9Sstevel@tonic-gate 			" between 512, 8192 bytes\n"));
463*7c478bd9Sstevel@tonic-gate 	}
464*7c478bd9Sstevel@tonic-gate 	if (!POWEROF2(sectorsize)) {
465*7c478bd9Sstevel@tonic-gate 		(void) fprintf(stdout,
466*7c478bd9Sstevel@tonic-gate 			gettext("sector size must be a power of 2, not %d\n"),
467*7c478bd9Sstevel@tonic-gate 			sectorsize);
468*7c478bd9Sstevel@tonic-gate 		exit(32);
469*7c478bd9Sstevel@tonic-gate 	}
470*7c478bd9Sstevel@tonic-gate 	if (Nflag) {
471*7c478bd9Sstevel@tonic-gate 		exit(0);
472*7c478bd9Sstevel@tonic-gate 	}
473*7c478bd9Sstevel@tonic-gate 
474*7c478bd9Sstevel@tonic-gate 	(void) printf(gettext("Creating file system with sector size of "
475*7c478bd9Sstevel@tonic-gate 		"%d bytes\n"), sectorsize);
476*7c478bd9Sstevel@tonic-gate 
477*7c478bd9Sstevel@tonic-gate 	/*
478*7c478bd9Sstevel@tonic-gate 	 * Set up time stamp values
479*7c478bd9Sstevel@tonic-gate 	 */
480*7c478bd9Sstevel@tonic-gate 	mkfstime = time(0);
481*7c478bd9Sstevel@tonic-gate 	(void) localtime_r(&mkfstime, &res);
482*7c478bd9Sstevel@tonic-gate 	if (res.tm_isdst > 0) {
483*7c478bd9Sstevel@tonic-gate 		tzone = altzone / 60;
484*7c478bd9Sstevel@tonic-gate 	} else if (res.tm_isdst == 0) {
485*7c478bd9Sstevel@tonic-gate 		tzone = tzone / 60;
486*7c478bd9Sstevel@tonic-gate 	} else {
487*7c478bd9Sstevel@tonic-gate 		tzone = 2047;	/* Unknown */
488*7c478bd9Sstevel@tonic-gate 	}
489*7c478bd9Sstevel@tonic-gate 
490*7c478bd9Sstevel@tonic-gate 	/*
491*7c478bd9Sstevel@tonic-gate 	 * Initialize the volume recognition sequence, the volume descriptor
492*7c478bd9Sstevel@tonic-gate 	 * sequences and the anchor pointer.
493*7c478bd9Sstevel@tonic-gate 	 */
494*7c478bd9Sstevel@tonic-gate 	volseqinit();
495*7c478bd9Sstevel@tonic-gate 
496*7c478bd9Sstevel@tonic-gate 	(void) fsync(fso);
497*7c478bd9Sstevel@tonic-gate 	(void) close(fsi);
498*7c478bd9Sstevel@tonic-gate 	(void) close(fso);
499*7c478bd9Sstevel@tonic-gate 
500*7c478bd9Sstevel@tonic-gate 	return (0);
501*7c478bd9Sstevel@tonic-gate }
502*7c478bd9Sstevel@tonic-gate 
503*7c478bd9Sstevel@tonic-gate static void
504*7c478bd9Sstevel@tonic-gate setstamp(tstamp_t *tp)
505*7c478bd9Sstevel@tonic-gate {
506*7c478bd9Sstevel@tonic-gate 	tp->ts_usec = 0;
507*7c478bd9Sstevel@tonic-gate 	tp->ts_husec = 0;
508*7c478bd9Sstevel@tonic-gate 	tp->ts_csec = 0;
509*7c478bd9Sstevel@tonic-gate 
510*7c478bd9Sstevel@tonic-gate 	tp->ts_sec = res.tm_sec;
511*7c478bd9Sstevel@tonic-gate 	tp->ts_min = res.tm_min;
512*7c478bd9Sstevel@tonic-gate 	tp->ts_hour = res.tm_hour;
513*7c478bd9Sstevel@tonic-gate 	tp->ts_day = res.tm_mday;
514*7c478bd9Sstevel@tonic-gate 	tp->ts_month = res.tm_mon + 1;
515*7c478bd9Sstevel@tonic-gate 	tp->ts_year = 1900 + res.tm_year;
516*7c478bd9Sstevel@tonic-gate 
517*7c478bd9Sstevel@tonic-gate 	tp->ts_tzone = 0x1000 + (-tzone & 0xFFF);
518*7c478bd9Sstevel@tonic-gate }
519*7c478bd9Sstevel@tonic-gate 
520*7c478bd9Sstevel@tonic-gate static void
521*7c478bd9Sstevel@tonic-gate setextad(extent_ad_t *eap, uint32_t len, uint32_t loc)
522*7c478bd9Sstevel@tonic-gate {
523*7c478bd9Sstevel@tonic-gate 	eap->ext_len = len;
524*7c478bd9Sstevel@tonic-gate 	eap->ext_loc = loc;
525*7c478bd9Sstevel@tonic-gate }
526*7c478bd9Sstevel@tonic-gate 
527*7c478bd9Sstevel@tonic-gate static void
528*7c478bd9Sstevel@tonic-gate setdstring(dstring_t *dp, char *cp, int len)
529*7c478bd9Sstevel@tonic-gate {
530*7c478bd9Sstevel@tonic-gate 	int32_t length;
531*7c478bd9Sstevel@tonic-gate 
532*7c478bd9Sstevel@tonic-gate 	bzero(dp, len);
533*7c478bd9Sstevel@tonic-gate 	length = strlen(cp);
534*7c478bd9Sstevel@tonic-gate 	if (length > len - 3) {
535*7c478bd9Sstevel@tonic-gate 		length = len - 3;
536*7c478bd9Sstevel@tonic-gate 	}
537*7c478bd9Sstevel@tonic-gate 	dp[len - 1] = length + 1;
538*7c478bd9Sstevel@tonic-gate 	*dp++ = 8;
539*7c478bd9Sstevel@tonic-gate 	(void) strncpy(dp, cp, len-2);
540*7c478bd9Sstevel@tonic-gate }
541*7c478bd9Sstevel@tonic-gate 
542*7c478bd9Sstevel@tonic-gate static void
543*7c478bd9Sstevel@tonic-gate wtvolseq(tag_t *tp, daddr_t blk1, daddr_t blk2)
544*7c478bd9Sstevel@tonic-gate {
545*7c478bd9Sstevel@tonic-gate 	static uint32_t vdsn = 0;
546*7c478bd9Sstevel@tonic-gate 
547*7c478bd9Sstevel@tonic-gate 	tp->tag_loc = blk1;
548*7c478bd9Sstevel@tonic-gate 	switch (tp->tag_id) {
549*7c478bd9Sstevel@tonic-gate 	case UD_PRI_VOL_DESC :
550*7c478bd9Sstevel@tonic-gate 		((struct pri_vol_desc *)tp)->pvd_vdsn = vdsn++;
551*7c478bd9Sstevel@tonic-gate 		break;
552*7c478bd9Sstevel@tonic-gate 	case UD_VOL_DESC_PTR :
553*7c478bd9Sstevel@tonic-gate 		((struct vol_desc_ptr *)tp)->vdp_vdsn = vdsn++;
554*7c478bd9Sstevel@tonic-gate 		break;
555*7c478bd9Sstevel@tonic-gate 	case UD_IMPL_USE_DESC :
556*7c478bd9Sstevel@tonic-gate 		((struct iuvd_desc *)tp)->iuvd_vdsn = vdsn++;
557*7c478bd9Sstevel@tonic-gate 		break;
558*7c478bd9Sstevel@tonic-gate 	case UD_PART_DESC :
559*7c478bd9Sstevel@tonic-gate 		((struct part_desc *)tp)->pd_vdsn = vdsn++;
560*7c478bd9Sstevel@tonic-gate 		break;
561*7c478bd9Sstevel@tonic-gate 	case UD_LOG_VOL_DESC :
562*7c478bd9Sstevel@tonic-gate 		((struct log_vol_desc *)tp)->lvd_vdsn = vdsn++;
563*7c478bd9Sstevel@tonic-gate 		break;
564*7c478bd9Sstevel@tonic-gate 	case UD_UNALL_SPA_DESC :
565*7c478bd9Sstevel@tonic-gate 		((struct unall_spc_desc *)tp)->ua_vdsn = vdsn++;
566*7c478bd9Sstevel@tonic-gate 		break;
567*7c478bd9Sstevel@tonic-gate 	}
568*7c478bd9Sstevel@tonic-gate 
569*7c478bd9Sstevel@tonic-gate 	bzero(buf2, sectorsize);
570*7c478bd9Sstevel@tonic-gate 	/* LINTED */
571*7c478bd9Sstevel@tonic-gate 	maketag(tp, (struct tag *)buf2);
572*7c478bd9Sstevel@tonic-gate 
573*7c478bd9Sstevel@tonic-gate 	/*
574*7c478bd9Sstevel@tonic-gate 	 * Write at Main Volume Descriptor Sequence
575*7c478bd9Sstevel@tonic-gate 	 */
576*7c478bd9Sstevel@tonic-gate 	wtfs(blk1, sectorsize, buf2);
577*7c478bd9Sstevel@tonic-gate 
578*7c478bd9Sstevel@tonic-gate 	tp->tag_loc = blk2;
579*7c478bd9Sstevel@tonic-gate 	switch (tp->tag_id) {
580*7c478bd9Sstevel@tonic-gate 	case UD_PRI_VOL_DESC :
581*7c478bd9Sstevel@tonic-gate 		((struct pri_vol_desc *)tp)->pvd_vdsn = vdsn++;
582*7c478bd9Sstevel@tonic-gate 		break;
583*7c478bd9Sstevel@tonic-gate 	case UD_VOL_DESC_PTR :
584*7c478bd9Sstevel@tonic-gate 		((struct vol_desc_ptr *)tp)->vdp_vdsn = vdsn++;
585*7c478bd9Sstevel@tonic-gate 		break;
586*7c478bd9Sstevel@tonic-gate 	case UD_IMPL_USE_DESC :
587*7c478bd9Sstevel@tonic-gate 		((struct iuvd_desc *)tp)->iuvd_vdsn = vdsn++;
588*7c478bd9Sstevel@tonic-gate 		break;
589*7c478bd9Sstevel@tonic-gate 	case UD_PART_DESC :
590*7c478bd9Sstevel@tonic-gate 		((struct part_desc *)tp)->pd_vdsn = vdsn++;
591*7c478bd9Sstevel@tonic-gate 		break;
592*7c478bd9Sstevel@tonic-gate 	case UD_LOG_VOL_DESC :
593*7c478bd9Sstevel@tonic-gate 		((struct log_vol_desc *)tp)->lvd_vdsn = vdsn++;
594*7c478bd9Sstevel@tonic-gate 		break;
595*7c478bd9Sstevel@tonic-gate 	case UD_UNALL_SPA_DESC :
596*7c478bd9Sstevel@tonic-gate 		((struct unall_spc_desc *)tp)->ua_vdsn = vdsn++;
597*7c478bd9Sstevel@tonic-gate 		break;
598*7c478bd9Sstevel@tonic-gate 	}
599*7c478bd9Sstevel@tonic-gate 	maketag(tp, tp);
600*7c478bd9Sstevel@tonic-gate 	/*
601*7c478bd9Sstevel@tonic-gate 	 * Write at Reserve Volume Descriptor Sequence
602*7c478bd9Sstevel@tonic-gate 	 */
603*7c478bd9Sstevel@tonic-gate 	wtfs(blk2, sectorsize, buf);
604*7c478bd9Sstevel@tonic-gate }
605*7c478bd9Sstevel@tonic-gate 
606*7c478bd9Sstevel@tonic-gate static void
607*7c478bd9Sstevel@tonic-gate volseqinit()
608*7c478bd9Sstevel@tonic-gate {
609*7c478bd9Sstevel@tonic-gate 	struct tag *tp;
610*7c478bd9Sstevel@tonic-gate 	struct nsr_desc *nsp;
611*7c478bd9Sstevel@tonic-gate 	struct pri_vol_desc *pvdp;
612*7c478bd9Sstevel@tonic-gate 	struct iuvd_desc *iudp;
613*7c478bd9Sstevel@tonic-gate 	struct part_desc *pp;
614*7c478bd9Sstevel@tonic-gate 	struct phdr_desc *php;
615*7c478bd9Sstevel@tonic-gate 	struct log_vol_desc *lvp;
616*7c478bd9Sstevel@tonic-gate 	long_ad_t *lap;
617*7c478bd9Sstevel@tonic-gate 	struct pmap_typ1 *pmp;
618*7c478bd9Sstevel@tonic-gate 	struct unall_spc_desc *uap;
619*7c478bd9Sstevel@tonic-gate 	struct log_vol_int_desc *lvip;
620*7c478bd9Sstevel@tonic-gate 	struct term_desc *tdp;
621*7c478bd9Sstevel@tonic-gate 	struct anch_vol_desc_ptr *avp;
622*7c478bd9Sstevel@tonic-gate 	struct lvid_iu *lviup;
623*7c478bd9Sstevel@tonic-gate 	struct file_set_desc *fsp;
624*7c478bd9Sstevel@tonic-gate 	struct file_entry *fp;
625*7c478bd9Sstevel@tonic-gate 	struct icb_tag *icb;
626*7c478bd9Sstevel@tonic-gate 	struct short_ad *sap;
627*7c478bd9Sstevel@tonic-gate 	struct file_id *fip;
628*7c478bd9Sstevel@tonic-gate 	struct space_bmap_desc *sbp;
629*7c478bd9Sstevel@tonic-gate 	uint8_t *cp;
630*7c478bd9Sstevel@tonic-gate 	daddr_t nextblock, endblock;
631*7c478bd9Sstevel@tonic-gate 	int32_t volseq_sectors, nextlogblock, rootfelen, i;
632*7c478bd9Sstevel@tonic-gate 	uint32_t mvds_loc, rvds_loc;
633*7c478bd9Sstevel@tonic-gate 
634*7c478bd9Sstevel@tonic-gate 	bzero(buf, MAXBSIZE);
635*7c478bd9Sstevel@tonic-gate 
636*7c478bd9Sstevel@tonic-gate 	/*
637*7c478bd9Sstevel@tonic-gate 	 * Starting from MAXBSIZE, clear out till 256 sectors.
638*7c478bd9Sstevel@tonic-gate 	 */
639*7c478bd9Sstevel@tonic-gate 	for (i = MAXBSIZE / sectorsize; i < FIRSTAVDP; i++) {
640*7c478bd9Sstevel@tonic-gate 		wtfs(i, sectorsize, buf);
641*7c478bd9Sstevel@tonic-gate 	}
642*7c478bd9Sstevel@tonic-gate 
643*7c478bd9Sstevel@tonic-gate 	/* Zero out the avdp at N - 257 */
644*7c478bd9Sstevel@tonic-gate 	wtfs(fssize - 256, sectorsize, buf);
645*7c478bd9Sstevel@tonic-gate 
646*7c478bd9Sstevel@tonic-gate 	/*
647*7c478bd9Sstevel@tonic-gate 	 * Leave 1st 32K for O.S.
648*7c478bd9Sstevel@tonic-gate 	 */
649*7c478bd9Sstevel@tonic-gate 	nextblock = VOLRECSTART / sectorsize;
650*7c478bd9Sstevel@tonic-gate 
651*7c478bd9Sstevel@tonic-gate 	/*
652*7c478bd9Sstevel@tonic-gate 	 * Write BEA01/NSR02/TEA01 sequence.
653*7c478bd9Sstevel@tonic-gate 	 * Each one must be 2K bytes in length.
654*7c478bd9Sstevel@tonic-gate 	 */
655*7c478bd9Sstevel@tonic-gate 	nsp = (struct nsr_desc *)buf;
656*7c478bd9Sstevel@tonic-gate 	nsp->nsr_str_type = 0;
657*7c478bd9Sstevel@tonic-gate 	nsp->nsr_ver = 1;
658*7c478bd9Sstevel@tonic-gate 	(void) strncpy((int8_t *)nsp->nsr_id, "BEA01", 5);
659*7c478bd9Sstevel@tonic-gate 
660*7c478bd9Sstevel@tonic-gate 	nsp = (struct nsr_desc *)&buf[2048];
661*7c478bd9Sstevel@tonic-gate 	nsp->nsr_str_type = 0;
662*7c478bd9Sstevel@tonic-gate 	nsp->nsr_ver = 1;
663*7c478bd9Sstevel@tonic-gate 	(void) strncpy((int8_t *)nsp->nsr_id, "NSR02", 5);
664*7c478bd9Sstevel@tonic-gate 
665*7c478bd9Sstevel@tonic-gate 	nsp = (struct nsr_desc *)&buf[4096];
666*7c478bd9Sstevel@tonic-gate 	nsp->nsr_str_type = 0;
667*7c478bd9Sstevel@tonic-gate 	nsp->nsr_ver = 1;
668*7c478bd9Sstevel@tonic-gate 	(void) strncpy((int8_t *)nsp->nsr_id, "TEA01", 5);
669*7c478bd9Sstevel@tonic-gate 
670*7c478bd9Sstevel@tonic-gate 	wtfs(nextblock, 8192, buf);
671*7c478bd9Sstevel@tonic-gate 	bzero(buf, MAXBSIZE);
672*7c478bd9Sstevel@tonic-gate 
673*7c478bd9Sstevel@tonic-gate 	/*
674*7c478bd9Sstevel@tonic-gate 	 * Minimum length of volume sequences
675*7c478bd9Sstevel@tonic-gate 	 */
676*7c478bd9Sstevel@tonic-gate 	volseq_sectors = 16;
677*7c478bd9Sstevel@tonic-gate 
678*7c478bd9Sstevel@tonic-gate 	/*
679*7c478bd9Sstevel@tonic-gate 	 * Round up to next 32K boundary for
680*7c478bd9Sstevel@tonic-gate 	 * volume descriptor sequences
681*7c478bd9Sstevel@tonic-gate 	 */
682*7c478bd9Sstevel@tonic-gate 	nextblock = VOLSEQSTART;
683*7c478bd9Sstevel@tonic-gate 	bzero(buf, sectorsize);
684*7c478bd9Sstevel@tonic-gate 	mvds_loc = VOLSEQSTART;
685*7c478bd9Sstevel@tonic-gate 	rvds_loc = mvds_loc + volseq_sectors;
686*7c478bd9Sstevel@tonic-gate 
687*7c478bd9Sstevel@tonic-gate 	/*
688*7c478bd9Sstevel@tonic-gate 	 * Primary Volume Descriptor
689*7c478bd9Sstevel@tonic-gate 	 */
690*7c478bd9Sstevel@tonic-gate 	/* LINTED */
691*7c478bd9Sstevel@tonic-gate 	pvdp = (struct pri_vol_desc *)buf;
692*7c478bd9Sstevel@tonic-gate 	tp = &pvdp->pvd_tag;
693*7c478bd9Sstevel@tonic-gate 	tp->tag_id =  UD_PRI_VOL_DESC;
694*7c478bd9Sstevel@tonic-gate 	tp->tag_desc_ver = ecma_version;
695*7c478bd9Sstevel@tonic-gate 	tp->tag_sno = serialnum;
696*7c478bd9Sstevel@tonic-gate 	tp->tag_crc_len = sizeof (struct pri_vol_desc) -
697*7c478bd9Sstevel@tonic-gate 			sizeof (struct tag);
698*7c478bd9Sstevel@tonic-gate 	pvdp->pvd_vdsn = 0;
699*7c478bd9Sstevel@tonic-gate 	pvdp->pvd_pvdn = 0;
700*7c478bd9Sstevel@tonic-gate 	setdstring(pvdp->pvd_vol_id, udfs_label, 32);
701*7c478bd9Sstevel@tonic-gate 	pvdp->pvd_vsn = 1;
702*7c478bd9Sstevel@tonic-gate 	pvdp->pvd_mvsn = 1;
703*7c478bd9Sstevel@tonic-gate 	pvdp->pvd_il = 2;		/* Single-volume */
704*7c478bd9Sstevel@tonic-gate 	pvdp->pvd_mil = 3;		/* Multi-volume */
705*7c478bd9Sstevel@tonic-gate 	pvdp->pvd_csl = 1;		/* CS0 */
706*7c478bd9Sstevel@tonic-gate 	pvdp->pvd_mcsl = 1;		/* CS0 */
707*7c478bd9Sstevel@tonic-gate 	(void) sprintf(vsibuf, "%08X", SWAP_32((uint32_t)mkfstime));
708*7c478bd9Sstevel@tonic-gate 	setdstring(pvdp->pvd_vsi, vsibuf, 128);
709*7c478bd9Sstevel@tonic-gate 	(void) strncpy(pvdp->pvd_vsi + 17, udfs_label, 128 - 17);
710*7c478bd9Sstevel@tonic-gate 	setcharspec(&pvdp->pvd_desc_cs, 0, osta_unicode);
711*7c478bd9Sstevel@tonic-gate 	setcharspec(&pvdp->pvd_exp_cs, 0, osta_unicode);
712*7c478bd9Sstevel@tonic-gate 	setextad(&pvdp->pvd_vol_abs, 0, 0);
713*7c478bd9Sstevel@tonic-gate 	setextad(&pvdp->pvd_vcn, 0, 0);
714*7c478bd9Sstevel@tonic-gate 	bzero(&pvdp->pvd_appl_id, sizeof (regid_t));
715*7c478bd9Sstevel@tonic-gate 	setstamp(&pvdp->pvd_time);
716*7c478bd9Sstevel@tonic-gate 	bcopy(&sunmicro, &pvdp->pvd_ii, sizeof (regid_t));
717*7c478bd9Sstevel@tonic-gate 	pvdp->pvd_flags = 0;
718*7c478bd9Sstevel@tonic-gate 	wtvolseq(tp, nextblock, nextblock + volseq_sectors);
719*7c478bd9Sstevel@tonic-gate 	nextblock++;
720*7c478bd9Sstevel@tonic-gate 
721*7c478bd9Sstevel@tonic-gate 	/*
722*7c478bd9Sstevel@tonic-gate 	 * Implementation Use Descriptor
723*7c478bd9Sstevel@tonic-gate 	 */
724*7c478bd9Sstevel@tonic-gate 	bzero(buf, sectorsize);
725*7c478bd9Sstevel@tonic-gate 	/* LINTED */
726*7c478bd9Sstevel@tonic-gate 	iudp = (struct iuvd_desc *)buf;
727*7c478bd9Sstevel@tonic-gate 	tp = &iudp->iuvd_tag;
728*7c478bd9Sstevel@tonic-gate 	tp->tag_id =  UD_IMPL_USE_DESC;
729*7c478bd9Sstevel@tonic-gate 	tp->tag_desc_ver = ecma_version;
730*7c478bd9Sstevel@tonic-gate 	tp->tag_sno = serialnum;
731*7c478bd9Sstevel@tonic-gate 	tp->tag_crc_len = sizeof (struct iuvd_desc) -
732*7c478bd9Sstevel@tonic-gate 			sizeof (struct tag);
733*7c478bd9Sstevel@tonic-gate 	iudp->iuvd_vdsn = 0;
734*7c478bd9Sstevel@tonic-gate 	bcopy(&lvinfo, &iudp->iuvd_ii, sizeof (regid_t));
735*7c478bd9Sstevel@tonic-gate 	setcharspec(&iudp->iuvd_cset, 0, osta_unicode);
736*7c478bd9Sstevel@tonic-gate 	setdstring(iudp->iuvd_lvi, udfs_label, 128);
737*7c478bd9Sstevel@tonic-gate 
738*7c478bd9Sstevel@tonic-gate 	setdstring(iudp->iuvd_ifo1, "", 36);
739*7c478bd9Sstevel@tonic-gate 	setdstring(iudp->iuvd_ifo2, "", 36);
740*7c478bd9Sstevel@tonic-gate 	setdstring(iudp->iuvd_ifo3, "", 36);
741*7c478bd9Sstevel@tonic-gate 
742*7c478bd9Sstevel@tonic-gate 
743*7c478bd9Sstevel@tonic-gate 	/*
744*7c478bd9Sstevel@tonic-gate 	 * info1,2,3 = user specified
745*7c478bd9Sstevel@tonic-gate 	 */
746*7c478bd9Sstevel@tonic-gate 	bcopy(&sunmicro, &iudp->iuvd_iid, sizeof (regid_t));
747*7c478bd9Sstevel@tonic-gate 	wtvolseq(tp, nextblock, nextblock + volseq_sectors);
748*7c478bd9Sstevel@tonic-gate 	nextblock++;
749*7c478bd9Sstevel@tonic-gate 
750*7c478bd9Sstevel@tonic-gate 	/*
751*7c478bd9Sstevel@tonic-gate 	 * Partition Descriptor
752*7c478bd9Sstevel@tonic-gate 	 */
753*7c478bd9Sstevel@tonic-gate 	bzero(buf, sectorsize);
754*7c478bd9Sstevel@tonic-gate 	/* LINTED */
755*7c478bd9Sstevel@tonic-gate 	pp = (struct part_desc *)buf;
756*7c478bd9Sstevel@tonic-gate 	tp = &pp->pd_tag;
757*7c478bd9Sstevel@tonic-gate 	tp->tag_id =  UD_PART_DESC;
758*7c478bd9Sstevel@tonic-gate 	tp->tag_desc_ver = ecma_version;
759*7c478bd9Sstevel@tonic-gate 	tp->tag_sno = serialnum;
760*7c478bd9Sstevel@tonic-gate 	tp->tag_crc_len = sizeof (struct part_desc) -
761*7c478bd9Sstevel@tonic-gate 			sizeof (struct tag);
762*7c478bd9Sstevel@tonic-gate 	pp->pd_vdsn = 0;
763*7c478bd9Sstevel@tonic-gate 	pp->pd_pflags = 1;			/* Allocated */
764*7c478bd9Sstevel@tonic-gate 	pp->pd_pnum = 0;
765*7c478bd9Sstevel@tonic-gate 	bcopy(&partid, &pp->pd_pcontents, sizeof (regid_t));
766*7c478bd9Sstevel@tonic-gate 
767*7c478bd9Sstevel@tonic-gate 	part_start = FIRSTAVDP + AVDPLEN;
768*7c478bd9Sstevel@tonic-gate 	part_len = fssize - part_start;
769*7c478bd9Sstevel@tonic-gate 	part_bmp_bytes = (part_len + NBBY - 1) / NBBY;
770*7c478bd9Sstevel@tonic-gate 	part_bmp_sectors = (part_bmp_bytes + SPACEMAP_OFF + sectorsize - 1) /
771*7c478bd9Sstevel@tonic-gate 		sectorsize;
772*7c478bd9Sstevel@tonic-gate 
773*7c478bd9Sstevel@tonic-gate 	pp->pd_part_start = part_start;
774*7c478bd9Sstevel@tonic-gate 	pp->pd_part_length = part_len;
775*7c478bd9Sstevel@tonic-gate 
776*7c478bd9Sstevel@tonic-gate 	pp->pd_acc_type = acctype;
777*7c478bd9Sstevel@tonic-gate 	nextlogblock = 0;
778*7c478bd9Sstevel@tonic-gate 
779*7c478bd9Sstevel@tonic-gate 	/*
780*7c478bd9Sstevel@tonic-gate 	 * Do the partition header
781*7c478bd9Sstevel@tonic-gate 	 */
782*7c478bd9Sstevel@tonic-gate 	/* LINTED */
783*7c478bd9Sstevel@tonic-gate 	php = (struct phdr_desc *)&pp->pd_pc_use;
784*7c478bd9Sstevel@tonic-gate 
785*7c478bd9Sstevel@tonic-gate 	/*
786*7c478bd9Sstevel@tonic-gate 	 * Set up unallocated space bitmap
787*7c478bd9Sstevel@tonic-gate 	 */
788*7c478bd9Sstevel@tonic-gate 	if (acctype == PART_ACC_RW || acctype == PART_ACC_OW) {
789*7c478bd9Sstevel@tonic-gate 		php->phdr_usb.sad_ext_len =
790*7c478bd9Sstevel@tonic-gate 			(part_bmp_bytes + SPACEMAP_OFF + sectorsize - 1) &
791*7c478bd9Sstevel@tonic-gate 				(~(sectorsize - 1));
792*7c478bd9Sstevel@tonic-gate 		php->phdr_usb.sad_ext_loc = nextlogblock;
793*7c478bd9Sstevel@tonic-gate 		part_unalloc = nextlogblock;
794*7c478bd9Sstevel@tonic-gate 		nextlogblock += part_bmp_sectors;
795*7c478bd9Sstevel@tonic-gate 	}
796*7c478bd9Sstevel@tonic-gate 
797*7c478bd9Sstevel@tonic-gate 	bcopy(&sunmicro, &pp->pd_ii, sizeof (regid_t));
798*7c478bd9Sstevel@tonic-gate 	wtvolseq(tp, nextblock, nextblock + volseq_sectors);
799*7c478bd9Sstevel@tonic-gate 	nextblock++;
800*7c478bd9Sstevel@tonic-gate 
801*7c478bd9Sstevel@tonic-gate 	/*
802*7c478bd9Sstevel@tonic-gate 	 * Logical Volume Descriptor
803*7c478bd9Sstevel@tonic-gate 	 */
804*7c478bd9Sstevel@tonic-gate 	bzero(buf, sectorsize);
805*7c478bd9Sstevel@tonic-gate 	/* LINTED */
806*7c478bd9Sstevel@tonic-gate 	lvp = (struct log_vol_desc *)buf;
807*7c478bd9Sstevel@tonic-gate 	tp = &lvp->lvd_tag;
808*7c478bd9Sstevel@tonic-gate 	tp->tag_id =  UD_LOG_VOL_DESC;
809*7c478bd9Sstevel@tonic-gate 	tp->tag_desc_ver = ecma_version;
810*7c478bd9Sstevel@tonic-gate 	tp->tag_sno = serialnum;
811*7c478bd9Sstevel@tonic-gate 	tp->tag_crc_len = sizeof (struct log_vol_desc) -
812*7c478bd9Sstevel@tonic-gate 			sizeof (struct tag);
813*7c478bd9Sstevel@tonic-gate 	lvp->lvd_vdsn = 0;
814*7c478bd9Sstevel@tonic-gate 	setcharspec(&lvp->lvd_desc_cs, 0, osta_unicode);
815*7c478bd9Sstevel@tonic-gate 	setdstring(lvp->lvd_lvid, udfs_label, 128);
816*7c478bd9Sstevel@tonic-gate 	lvp->lvd_log_bsize = sectorsize;
817*7c478bd9Sstevel@tonic-gate 	bcopy(&udf_compliant, &lvp->lvd_dom_id, sizeof (regid_t));
818*7c478bd9Sstevel@tonic-gate 	lap = (long_ad_t *)&lvp->lvd_lvcu;
819*7c478bd9Sstevel@tonic-gate 	lap->lad_ext_len = FILESETLEN * sectorsize;
820*7c478bd9Sstevel@tonic-gate 	filesetblock = nextlogblock;
821*7c478bd9Sstevel@tonic-gate 	lap->lad_ext_loc = nextlogblock;
822*7c478bd9Sstevel@tonic-gate 	lap->lad_ext_prn = 0;
823*7c478bd9Sstevel@tonic-gate 	lvp->lvd_mtbl_len = 6;
824*7c478bd9Sstevel@tonic-gate 	lvp->lvd_num_pmaps = 1;
825*7c478bd9Sstevel@tonic-gate 	bcopy(&sunmicro, &lvp->lvd_ii, sizeof (regid_t));
826*7c478bd9Sstevel@tonic-gate 	/* LINTED */
827*7c478bd9Sstevel@tonic-gate 	pmp = (struct pmap_typ1 *)&lvp->lvd_pmaps;
828*7c478bd9Sstevel@tonic-gate 	pmp->map1_type = 1;
829*7c478bd9Sstevel@tonic-gate 	pmp->map1_length = 6;
830*7c478bd9Sstevel@tonic-gate 	pmp->map1_vsn = SWAP_16(1);
831*7c478bd9Sstevel@tonic-gate 	pmp->map1_pn  = 0;
832*7c478bd9Sstevel@tonic-gate 	tp->tag_crc_len = (char *)(pmp + 1) - buf - sizeof (struct tag);
833*7c478bd9Sstevel@tonic-gate 	setextad(&lvp->lvd_int_seq_ext, INTSEQLEN, INTSEQSTART);
834*7c478bd9Sstevel@tonic-gate 	wtvolseq(tp, nextblock, nextblock + volseq_sectors);
835*7c478bd9Sstevel@tonic-gate 	nextblock++;
836*7c478bd9Sstevel@tonic-gate 
837*7c478bd9Sstevel@tonic-gate 	/*
838*7c478bd9Sstevel@tonic-gate 	 * Unallocated Space Descriptor
839*7c478bd9Sstevel@tonic-gate 	 */
840*7c478bd9Sstevel@tonic-gate 	bzero(buf, sectorsize);
841*7c478bd9Sstevel@tonic-gate 	/* LINTED */
842*7c478bd9Sstevel@tonic-gate 	uap = (struct unall_spc_desc *)buf;
843*7c478bd9Sstevel@tonic-gate 	tp = &uap->ua_tag;
844*7c478bd9Sstevel@tonic-gate 	tp->tag_id =  UD_UNALL_SPA_DESC;
845*7c478bd9Sstevel@tonic-gate 	tp->tag_desc_ver = ecma_version;
846*7c478bd9Sstevel@tonic-gate 	tp->tag_sno = serialnum;
847*7c478bd9Sstevel@tonic-gate 	uap->ua_vdsn = 0;
848*7c478bd9Sstevel@tonic-gate 	uap->ua_nad = 0;
849*7c478bd9Sstevel@tonic-gate 	tp->tag_crc_len = (char *)uap->ua_al_dsc - buf - sizeof (struct tag);
850*7c478bd9Sstevel@tonic-gate 	wtvolseq(tp, nextblock, nextblock + volseq_sectors);
851*7c478bd9Sstevel@tonic-gate 	nextblock++;
852*7c478bd9Sstevel@tonic-gate 
853*7c478bd9Sstevel@tonic-gate 	/*
854*7c478bd9Sstevel@tonic-gate 	 * Terminating Descriptor
855*7c478bd9Sstevel@tonic-gate 	 */
856*7c478bd9Sstevel@tonic-gate 	bzero(buf, sectorsize);
857*7c478bd9Sstevel@tonic-gate 	/* LINTED */
858*7c478bd9Sstevel@tonic-gate 	tdp = (struct term_desc *)buf;
859*7c478bd9Sstevel@tonic-gate 	tp = &tdp->td_tag;
860*7c478bd9Sstevel@tonic-gate 	tp->tag_id =  UD_TERM_DESC;
861*7c478bd9Sstevel@tonic-gate 	tp->tag_desc_ver = ecma_version;
862*7c478bd9Sstevel@tonic-gate 	tp->tag_sno = serialnum;
863*7c478bd9Sstevel@tonic-gate 	tp->tag_crc_len = sizeof (struct term_desc) -
864*7c478bd9Sstevel@tonic-gate 			sizeof (struct tag);
865*7c478bd9Sstevel@tonic-gate 	tp->tag_loc = nextblock;
866*7c478bd9Sstevel@tonic-gate 	wtvolseq(tp, nextblock, nextblock + volseq_sectors);
867*7c478bd9Sstevel@tonic-gate 	nextblock++;
868*7c478bd9Sstevel@tonic-gate 
869*7c478bd9Sstevel@tonic-gate 	/*
870*7c478bd9Sstevel@tonic-gate 	 * Do the anchor volume descriptor
871*7c478bd9Sstevel@tonic-gate 	 */
872*7c478bd9Sstevel@tonic-gate 	if (nextblock > FIRSTAVDP) {
873*7c478bd9Sstevel@tonic-gate 		(void) fprintf(stdout,
874*7c478bd9Sstevel@tonic-gate 			gettext("Volume integrity sequence"
875*7c478bd9Sstevel@tonic-gate 			" descriptors too long\n"));
876*7c478bd9Sstevel@tonic-gate 		exit(32);
877*7c478bd9Sstevel@tonic-gate 	}
878*7c478bd9Sstevel@tonic-gate 
879*7c478bd9Sstevel@tonic-gate 	nextblock = FIRSTAVDP;
880*7c478bd9Sstevel@tonic-gate 	bzero(buf, sectorsize);
881*7c478bd9Sstevel@tonic-gate 	/* LINTED */
882*7c478bd9Sstevel@tonic-gate 	avp = (struct anch_vol_desc_ptr *)buf;
883*7c478bd9Sstevel@tonic-gate 	tp = &avp->avd_tag;
884*7c478bd9Sstevel@tonic-gate 	tp->tag_id =  UD_ANCH_VOL_DESC;
885*7c478bd9Sstevel@tonic-gate 	tp->tag_desc_ver = ecma_version;
886*7c478bd9Sstevel@tonic-gate 	tp->tag_sno = serialnum;
887*7c478bd9Sstevel@tonic-gate 	tp->tag_crc_len = sizeof (struct anch_vol_desc_ptr) -
888*7c478bd9Sstevel@tonic-gate 			sizeof (struct tag);
889*7c478bd9Sstevel@tonic-gate 	tp->tag_loc = nextblock;
890*7c478bd9Sstevel@tonic-gate 	setextad(&avp->avd_main_vdse,
891*7c478bd9Sstevel@tonic-gate 			volseq_sectors * sectorsize, mvds_loc);
892*7c478bd9Sstevel@tonic-gate 	setextad(&avp->avd_res_vdse,
893*7c478bd9Sstevel@tonic-gate 			volseq_sectors * sectorsize, rvds_loc);
894*7c478bd9Sstevel@tonic-gate 	bzero(buf2, sectorsize);
895*7c478bd9Sstevel@tonic-gate 	/* LINTED */
896*7c478bd9Sstevel@tonic-gate 	maketag(tp, (struct tag *)buf2);
897*7c478bd9Sstevel@tonic-gate 	wtfs(nextblock, sectorsize, buf2);
898*7c478bd9Sstevel@tonic-gate 	nextblock++;
899*7c478bd9Sstevel@tonic-gate 
900*7c478bd9Sstevel@tonic-gate 	tp->tag_loc = fssize;
901*7c478bd9Sstevel@tonic-gate 	/* LINTED */
902*7c478bd9Sstevel@tonic-gate 	maketag(tp, (struct tag *)buf2);
903*7c478bd9Sstevel@tonic-gate 	wtfs(fssize, sectorsize, buf2);
904*7c478bd9Sstevel@tonic-gate 
905*7c478bd9Sstevel@tonic-gate 	/*
906*7c478bd9Sstevel@tonic-gate 	 * File Set Descriptor
907*7c478bd9Sstevel@tonic-gate 	 */
908*7c478bd9Sstevel@tonic-gate 	bzero(buf, sectorsize);
909*7c478bd9Sstevel@tonic-gate 	/* LINTED */
910*7c478bd9Sstevel@tonic-gate 	fsp = (struct file_set_desc *)&buf;
911*7c478bd9Sstevel@tonic-gate 	tp = &fsp->fsd_tag;
912*7c478bd9Sstevel@tonic-gate 	tp->tag_id =  UD_FILE_SET_DESC;
913*7c478bd9Sstevel@tonic-gate 	tp->tag_desc_ver = ecma_version;
914*7c478bd9Sstevel@tonic-gate 	tp->tag_sno = serialnum;
915*7c478bd9Sstevel@tonic-gate 	tp->tag_crc_len = sizeof (struct file_set_desc) -
916*7c478bd9Sstevel@tonic-gate 			sizeof (struct tag);
917*7c478bd9Sstevel@tonic-gate 	tp->tag_loc = nextlogblock;
918*7c478bd9Sstevel@tonic-gate 	setstamp(&fsp->fsd_time);
919*7c478bd9Sstevel@tonic-gate 	fsp->fsd_ilevel = 3;
920*7c478bd9Sstevel@tonic-gate 	fsp->fsd_mi_level = 3;
921*7c478bd9Sstevel@tonic-gate 	fsp->fsd_cs_list = 1;
922*7c478bd9Sstevel@tonic-gate 	fsp->fsd_mcs_list = 1;
923*7c478bd9Sstevel@tonic-gate 	fsp->fsd_fs_no = 0;
924*7c478bd9Sstevel@tonic-gate 	fsp->fsd_fsd_no = 0;
925*7c478bd9Sstevel@tonic-gate 	setcharspec(&fsp->fsd_lvidcs, 0, osta_unicode);
926*7c478bd9Sstevel@tonic-gate 	setdstring(fsp->fsd_lvid, udfs_label, 128);
927*7c478bd9Sstevel@tonic-gate 	setcharspec(&fsp->fsd_fscs, 0, osta_unicode);
928*7c478bd9Sstevel@tonic-gate 	setdstring(fsp->fsd_fsi, udfs_label, 32);
929*7c478bd9Sstevel@tonic-gate 	setdstring(fsp->fsd_cfi, "", 32);
930*7c478bd9Sstevel@tonic-gate 	setdstring(fsp->fsd_afi, "", 32);
931*7c478bd9Sstevel@tonic-gate 	lap = (long_ad_t *)&fsp->fsd_root_icb;
932*7c478bd9Sstevel@tonic-gate 	lap->lad_ext_len = sectorsize;
933*7c478bd9Sstevel@tonic-gate 	lap->lad_ext_loc = filesetblock + FILESETLEN;
934*7c478bd9Sstevel@tonic-gate 	lap->lad_ext_prn = 0;
935*7c478bd9Sstevel@tonic-gate 	bcopy(&udf_compliant, &fsp->fsd_did, sizeof (regid_t));
936*7c478bd9Sstevel@tonic-gate 	maketag(tp, tp);
937*7c478bd9Sstevel@tonic-gate 	wtfs(nextlogblock + part_start, sectorsize, (char *)tp);
938*7c478bd9Sstevel@tonic-gate 	nextlogblock++;
939*7c478bd9Sstevel@tonic-gate 
940*7c478bd9Sstevel@tonic-gate 	/*
941*7c478bd9Sstevel@tonic-gate 	 * Terminating Descriptor
942*7c478bd9Sstevel@tonic-gate 	 */
943*7c478bd9Sstevel@tonic-gate 	bzero(buf, sectorsize);
944*7c478bd9Sstevel@tonic-gate 	/* LINTED */
945*7c478bd9Sstevel@tonic-gate 	tdp = (struct term_desc *)buf;
946*7c478bd9Sstevel@tonic-gate 	tp = &tdp->td_tag;
947*7c478bd9Sstevel@tonic-gate 	tp->tag_id =  UD_TERM_DESC;
948*7c478bd9Sstevel@tonic-gate 	tp->tag_desc_ver = ecma_version;
949*7c478bd9Sstevel@tonic-gate 	tp->tag_sno = serialnum;
950*7c478bd9Sstevel@tonic-gate 	tp->tag_crc_len = sizeof (struct term_desc) -
951*7c478bd9Sstevel@tonic-gate 			sizeof (struct tag);
952*7c478bd9Sstevel@tonic-gate 	tp->tag_loc = nextlogblock;
953*7c478bd9Sstevel@tonic-gate 	maketag(tp, tp);
954*7c478bd9Sstevel@tonic-gate 	wtfs(nextlogblock + part_start, sectorsize, (char *)tp);
955*7c478bd9Sstevel@tonic-gate 	nextlogblock++;
956*7c478bd9Sstevel@tonic-gate 
957*7c478bd9Sstevel@tonic-gate 	if (nextlogblock > filesetblock + FILESETLEN) {
958*7c478bd9Sstevel@tonic-gate 		(void) fprintf(stdout,
959*7c478bd9Sstevel@tonic-gate 			gettext("File set descriptor too long\n"));
960*7c478bd9Sstevel@tonic-gate 		exit(32);
961*7c478bd9Sstevel@tonic-gate 	}
962*7c478bd9Sstevel@tonic-gate 	nextlogblock = filesetblock + FILESETLEN;
963*7c478bd9Sstevel@tonic-gate 
964*7c478bd9Sstevel@tonic-gate 	/*
965*7c478bd9Sstevel@tonic-gate 	 * Root File Entry
966*7c478bd9Sstevel@tonic-gate 	 */
967*7c478bd9Sstevel@tonic-gate 	bzero(buf, sectorsize);
968*7c478bd9Sstevel@tonic-gate 	/* LINTED */
969*7c478bd9Sstevel@tonic-gate 	fp = (struct file_entry *)&buf;
970*7c478bd9Sstevel@tonic-gate 	tp = &fp->fe_tag;
971*7c478bd9Sstevel@tonic-gate 	tp->tag_id =  UD_FILE_ENTRY;
972*7c478bd9Sstevel@tonic-gate 	tp->tag_desc_ver = ecma_version;
973*7c478bd9Sstevel@tonic-gate 	tp->tag_sno = serialnum;
974*7c478bd9Sstevel@tonic-gate 	tp->tag_loc = nextlogblock;
975*7c478bd9Sstevel@tonic-gate 	icb = &fp->fe_icb_tag;
976*7c478bd9Sstevel@tonic-gate 	icb->itag_prnde = 0;
977*7c478bd9Sstevel@tonic-gate 	icb->itag_strategy = STRAT_TYPE4;
978*7c478bd9Sstevel@tonic-gate 	icb->itag_param = 0; /* what does this mean? */
979*7c478bd9Sstevel@tonic-gate 	icb->itag_max_ent = 1;
980*7c478bd9Sstevel@tonic-gate 	icb->itag_ftype = FTYPE_DIRECTORY;
981*7c478bd9Sstevel@tonic-gate 	icb->itag_lb_loc = 0;
982*7c478bd9Sstevel@tonic-gate 	icb->itag_lb_prn = 0;
983*7c478bd9Sstevel@tonic-gate 	icb->itag_flags = ICB_FLAG_ARCHIVE;
984*7c478bd9Sstevel@tonic-gate 	fp->fe_uid = getuid();
985*7c478bd9Sstevel@tonic-gate 	fp->fe_gid = getgid();
986*7c478bd9Sstevel@tonic-gate 	fp->fe_perms = (0x1f << 10) | (0x5 << 5) | 0x5;
987*7c478bd9Sstevel@tonic-gate 	fp->fe_lcount = 1;
988*7c478bd9Sstevel@tonic-gate 	fp->fe_rec_for = 0;
989*7c478bd9Sstevel@tonic-gate 	fp->fe_rec_dis = 0;
990*7c478bd9Sstevel@tonic-gate 	fp->fe_rec_len = 0;
991*7c478bd9Sstevel@tonic-gate 	fp->fe_info_len = sizeof (struct file_id);
992*7c478bd9Sstevel@tonic-gate 	fp->fe_lbr = 1;
993*7c478bd9Sstevel@tonic-gate 	setstamp(&fp->fe_acc_time);
994*7c478bd9Sstevel@tonic-gate 	setstamp(&fp->fe_mod_time);
995*7c478bd9Sstevel@tonic-gate 	setstamp(&fp->fe_attr_time);
996*7c478bd9Sstevel@tonic-gate 	fp->fe_ckpoint = 1;
997*7c478bd9Sstevel@tonic-gate 	bcopy(&sunmicro, &fp->fe_impl_id, sizeof (regid_t));
998*7c478bd9Sstevel@tonic-gate 	fp->fe_uniq_id = 0;
999*7c478bd9Sstevel@tonic-gate 	fp->fe_len_ear = 0;
1000*7c478bd9Sstevel@tonic-gate 	fp->fe_len_adesc = sizeof (short_ad_t);
1001*7c478bd9Sstevel@tonic-gate 
1002*7c478bd9Sstevel@tonic-gate 	/* LINTED */
1003*7c478bd9Sstevel@tonic-gate 	sap = (short_ad_t *)(fp->fe_spec + fp->fe_len_ear);
1004*7c478bd9Sstevel@tonic-gate 	sap->sad_ext_len = sizeof (struct file_id);
1005*7c478bd9Sstevel@tonic-gate 	sap->sad_ext_loc = nextlogblock + 1;
1006*7c478bd9Sstevel@tonic-gate 	rootfelen = (char *)(sap + 1) - buf;
1007*7c478bd9Sstevel@tonic-gate 	tp->tag_crc_len = rootfelen - sizeof (struct tag);
1008*7c478bd9Sstevel@tonic-gate 	maketag(tp, tp);
1009*7c478bd9Sstevel@tonic-gate 	wtfs(nextlogblock + part_start, sectorsize, (char *)tp);
1010*7c478bd9Sstevel@tonic-gate 	nextlogblock++;
1011*7c478bd9Sstevel@tonic-gate 
1012*7c478bd9Sstevel@tonic-gate 	/*
1013*7c478bd9Sstevel@tonic-gate 	 * Root Directory
1014*7c478bd9Sstevel@tonic-gate 	 */
1015*7c478bd9Sstevel@tonic-gate 	bzero(buf, sectorsize);
1016*7c478bd9Sstevel@tonic-gate 	/* LINTED */
1017*7c478bd9Sstevel@tonic-gate 	fip = (struct file_id *)&buf;
1018*7c478bd9Sstevel@tonic-gate 	tp = &fip->fid_tag;
1019*7c478bd9Sstevel@tonic-gate 	tp->tag_id =  UD_FILE_ID_DESC;
1020*7c478bd9Sstevel@tonic-gate 	tp->tag_desc_ver = ecma_version;
1021*7c478bd9Sstevel@tonic-gate 	tp->tag_sno = serialnum;
1022*7c478bd9Sstevel@tonic-gate 	tp->tag_crc_len = sizeof (struct file_id) -
1023*7c478bd9Sstevel@tonic-gate 			sizeof (struct tag);
1024*7c478bd9Sstevel@tonic-gate 	tp->tag_loc = nextlogblock;
1025*7c478bd9Sstevel@tonic-gate 	fip->fid_ver = 1;
1026*7c478bd9Sstevel@tonic-gate 	fip->fid_flags = FID_DIR | FID_PARENT;
1027*7c478bd9Sstevel@tonic-gate 	fip->fid_idlen = 0;
1028*7c478bd9Sstevel@tonic-gate 	fip->fid_iulen = 0;
1029*7c478bd9Sstevel@tonic-gate 	fip->fid_icb.lad_ext_len = sectorsize; /* rootfelen; */
1030*7c478bd9Sstevel@tonic-gate 	fip->fid_icb.lad_ext_loc = nextlogblock - 1;
1031*7c478bd9Sstevel@tonic-gate 	fip->fid_icb.lad_ext_prn = 0;
1032*7c478bd9Sstevel@tonic-gate 	maketag(tp, tp);
1033*7c478bd9Sstevel@tonic-gate 	wtfs(nextlogblock + part_start, sectorsize, (char *)tp);
1034*7c478bd9Sstevel@tonic-gate 	nextlogblock++;
1035*7c478bd9Sstevel@tonic-gate 
1036*7c478bd9Sstevel@tonic-gate 	/*
1037*7c478bd9Sstevel@tonic-gate 	 * Now do the space bitmaps
1038*7c478bd9Sstevel@tonic-gate 	 */
1039*7c478bd9Sstevel@tonic-gate 	if (part_unalloc >= 0) {
1040*7c478bd9Sstevel@tonic-gate 		int size = sectorsize * part_bmp_sectors;
1041*7c478bd9Sstevel@tonic-gate 
1042*7c478bd9Sstevel@tonic-gate 		sbp = (struct space_bmap_desc *)malloc(size);
1043*7c478bd9Sstevel@tonic-gate 		if (!sbp) {
1044*7c478bd9Sstevel@tonic-gate 			(void) fprintf(stdout,
1045*7c478bd9Sstevel@tonic-gate 				gettext("Can't allocate bitmap space\n"));
1046*7c478bd9Sstevel@tonic-gate 			exit(32);
1047*7c478bd9Sstevel@tonic-gate 		}
1048*7c478bd9Sstevel@tonic-gate 		bzero((char *)sbp, sectorsize * part_bmp_sectors);
1049*7c478bd9Sstevel@tonic-gate 		tp = &sbp->sbd_tag;
1050*7c478bd9Sstevel@tonic-gate 		tp->tag_id =  UD_SPA_BMAP_DESC;
1051*7c478bd9Sstevel@tonic-gate 		tp->tag_desc_ver = ecma_version;
1052*7c478bd9Sstevel@tonic-gate 		tp->tag_sno = serialnum;
1053*7c478bd9Sstevel@tonic-gate 		tp->tag_crc_len = 0;	/* Don't do CRCs on bitmaps */
1054*7c478bd9Sstevel@tonic-gate 		tp->tag_loc = part_unalloc;
1055*7c478bd9Sstevel@tonic-gate 		sbp->sbd_nbits = part_len;
1056*7c478bd9Sstevel@tonic-gate 		sbp->sbd_nbytes = part_bmp_bytes;
1057*7c478bd9Sstevel@tonic-gate 		maketag(tp, tp);
1058*7c478bd9Sstevel@tonic-gate 		if (part_unalloc >= 0) {
1059*7c478bd9Sstevel@tonic-gate 			int32_t i;
1060*7c478bd9Sstevel@tonic-gate 
1061*7c478bd9Sstevel@tonic-gate 			cp = (uint8_t *)sbp + SPACEMAP_OFF;
1062*7c478bd9Sstevel@tonic-gate 			i = nextlogblock / NBBY;
1063*7c478bd9Sstevel@tonic-gate 			cp[i++] = (0xff << (nextlogblock % NBBY)) & 0xff;
1064*7c478bd9Sstevel@tonic-gate 			while (i < part_bmp_bytes)
1065*7c478bd9Sstevel@tonic-gate 				cp[i++] = 0xff;
1066*7c478bd9Sstevel@tonic-gate 			if (part_len % NBBY)
1067*7c478bd9Sstevel@tonic-gate 				cp[--i] = (unsigned)0xff >>
1068*7c478bd9Sstevel@tonic-gate 					(NBBY - part_len % NBBY);
1069*7c478bd9Sstevel@tonic-gate 
1070*7c478bd9Sstevel@tonic-gate 			wtfs(part_unalloc + part_start, size, (char *)tp);
1071*7c478bd9Sstevel@tonic-gate 		}
1072*7c478bd9Sstevel@tonic-gate 		free((char *)sbp);
1073*7c478bd9Sstevel@tonic-gate 	}
1074*7c478bd9Sstevel@tonic-gate 
1075*7c478bd9Sstevel@tonic-gate 	/*
1076*7c478bd9Sstevel@tonic-gate 	 * Volume Integrity Descriptor
1077*7c478bd9Sstevel@tonic-gate 	 */
1078*7c478bd9Sstevel@tonic-gate 	nextblock = INTSEQSTART;
1079*7c478bd9Sstevel@tonic-gate 	endblock = nextblock + INTSEQLEN / sectorsize;
1080*7c478bd9Sstevel@tonic-gate 	/* LINTED */
1081*7c478bd9Sstevel@tonic-gate 	lvip = (struct log_vol_int_desc *)&lvid;
1082*7c478bd9Sstevel@tonic-gate 	tp = &lvip->lvid_tag;
1083*7c478bd9Sstevel@tonic-gate 	tp->tag_id =  UD_LOG_VOL_INT;
1084*7c478bd9Sstevel@tonic-gate 	tp->tag_desc_ver = ecma_version;
1085*7c478bd9Sstevel@tonic-gate 	tp->tag_sno = serialnum;
1086*7c478bd9Sstevel@tonic-gate 	tp->tag_loc = nextblock;
1087*7c478bd9Sstevel@tonic-gate 	setstamp(&lvip->lvid_tstamp);
1088*7c478bd9Sstevel@tonic-gate 	lvip->lvid_int_type = LOG_VOL_CLOSE_INT;
1089*7c478bd9Sstevel@tonic-gate 	setextad(&lvip->lvid_nie, 0, 0);
1090*7c478bd9Sstevel@tonic-gate 	lvip->lvid_npart = 1;
1091*7c478bd9Sstevel@tonic-gate 	lvip->lvid_liu = 0x2e;
1092*7c478bd9Sstevel@tonic-gate 	lvip->lvid_uniqid = MAXID + 1;
1093*7c478bd9Sstevel@tonic-gate 	lvip->lvid_fst[0] = part_len - nextlogblock;	/* Free space */
1094*7c478bd9Sstevel@tonic-gate 	lvip->lvid_fst[1] = part_len;			/* Size */
1095*7c478bd9Sstevel@tonic-gate 	lviup = (struct lvid_iu *)&lvip->lvid_fst[2];
1096*7c478bd9Sstevel@tonic-gate 	bcopy(&sunmicro, &lviup->lvidiu_regid, sizeof (regid_t));
1097*7c478bd9Sstevel@tonic-gate 	lviup->lvidiu_nfiles = 0;
1098*7c478bd9Sstevel@tonic-gate 	lviup->lvidiu_ndirs = 1;
1099*7c478bd9Sstevel@tonic-gate 	lviup->lvidiu_mread = 0x102;
1100*7c478bd9Sstevel@tonic-gate 	lviup->lvidiu_mwrite = 0x102;
1101*7c478bd9Sstevel@tonic-gate 	lviup->lvidiu_maxwr = 0x150;
1102*7c478bd9Sstevel@tonic-gate 	tp->tag_crc_len = sizeof (struct log_vol_int_desc) + lvip->lvid_liu -
1103*7c478bd9Sstevel@tonic-gate 		sizeof (struct tag);
1104*7c478bd9Sstevel@tonic-gate 	maketag(tp, tp);
1105*7c478bd9Sstevel@tonic-gate 	wtfs(nextblock, sectorsize, (char *)tp);
1106*7c478bd9Sstevel@tonic-gate 	nextblock++;
1107*7c478bd9Sstevel@tonic-gate 
1108*7c478bd9Sstevel@tonic-gate 	/*
1109*7c478bd9Sstevel@tonic-gate 	 * Terminating Descriptor
1110*7c478bd9Sstevel@tonic-gate 	 */
1111*7c478bd9Sstevel@tonic-gate 	bzero(buf, sectorsize);
1112*7c478bd9Sstevel@tonic-gate 	/* LINTED */
1113*7c478bd9Sstevel@tonic-gate 	tdp = (struct term_desc *)buf;
1114*7c478bd9Sstevel@tonic-gate 	tp = &tdp->td_tag;
1115*7c478bd9Sstevel@tonic-gate 	tp->tag_id =  UD_TERM_DESC;
1116*7c478bd9Sstevel@tonic-gate 	tp->tag_desc_ver = ecma_version;
1117*7c478bd9Sstevel@tonic-gate 	tp->tag_sno = serialnum;
1118*7c478bd9Sstevel@tonic-gate 	tp->tag_crc_len = sizeof (struct term_desc) - sizeof (struct tag);
1119*7c478bd9Sstevel@tonic-gate 	tp->tag_loc = nextblock;
1120*7c478bd9Sstevel@tonic-gate 	maketag(tp, tp);
1121*7c478bd9Sstevel@tonic-gate 	wtfs(nextblock, sectorsize, (char *)tp);
1122*7c478bd9Sstevel@tonic-gate 	nextblock++;
1123*7c478bd9Sstevel@tonic-gate 
1124*7c478bd9Sstevel@tonic-gate 	/* Zero out the rest of the LVI extent */
1125*7c478bd9Sstevel@tonic-gate 	bzero(buf, sectorsize);
1126*7c478bd9Sstevel@tonic-gate 	while (nextblock < endblock)
1127*7c478bd9Sstevel@tonic-gate 		wtfs(nextblock++, sectorsize, buf);
1128*7c478bd9Sstevel@tonic-gate }
1129*7c478bd9Sstevel@tonic-gate 
1130*7c478bd9Sstevel@tonic-gate /*
1131*7c478bd9Sstevel@tonic-gate  * read a block from the file system
1132*7c478bd9Sstevel@tonic-gate  */
1133*7c478bd9Sstevel@tonic-gate static void
1134*7c478bd9Sstevel@tonic-gate rdfs(daddr_t bno, int size, char *bf)
1135*7c478bd9Sstevel@tonic-gate {
1136*7c478bd9Sstevel@tonic-gate 	int n, saverr;
1137*7c478bd9Sstevel@tonic-gate 
1138*7c478bd9Sstevel@tonic-gate 	if (llseek(fsi, (offset_t)bno * sectorsize, 0) < 0) {
1139*7c478bd9Sstevel@tonic-gate 		saverr = errno;
1140*7c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr,
1141*7c478bd9Sstevel@tonic-gate 			gettext("seek error on sector %ld: %s\n"),
1142*7c478bd9Sstevel@tonic-gate 			bno, strerror(saverr));
1143*7c478bd9Sstevel@tonic-gate 		exit(32);
1144*7c478bd9Sstevel@tonic-gate 	}
1145*7c478bd9Sstevel@tonic-gate 	n = read(fsi, bf, size);
1146*7c478bd9Sstevel@tonic-gate 	if (n != size) {
1147*7c478bd9Sstevel@tonic-gate 		saverr = errno;
1148*7c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr,
1149*7c478bd9Sstevel@tonic-gate 			gettext("read error on sector %ld: %s\n"),
1150*7c478bd9Sstevel@tonic-gate 			bno, strerror(saverr));
1151*7c478bd9Sstevel@tonic-gate 		exit(32);
1152*7c478bd9Sstevel@tonic-gate 	}
1153*7c478bd9Sstevel@tonic-gate }
1154*7c478bd9Sstevel@tonic-gate 
1155*7c478bd9Sstevel@tonic-gate /*
1156*7c478bd9Sstevel@tonic-gate  * write a block to the file system
1157*7c478bd9Sstevel@tonic-gate  */
1158*7c478bd9Sstevel@tonic-gate static void
1159*7c478bd9Sstevel@tonic-gate wtfs(daddr_t bno, int size, char *bf)
1160*7c478bd9Sstevel@tonic-gate {
1161*7c478bd9Sstevel@tonic-gate 	int n, saverr;
1162*7c478bd9Sstevel@tonic-gate 
1163*7c478bd9Sstevel@tonic-gate 	if (fso == -1)
1164*7c478bd9Sstevel@tonic-gate 		return;
1165*7c478bd9Sstevel@tonic-gate 
1166*7c478bd9Sstevel@tonic-gate 	if (llseek(fso, (offset_t)bno * sectorsize, 0) < 0) {
1167*7c478bd9Sstevel@tonic-gate 		saverr = errno;
1168*7c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr,
1169*7c478bd9Sstevel@tonic-gate 			gettext("seek error on sector %ld: %s\n"),
1170*7c478bd9Sstevel@tonic-gate 			bno, strerror(saverr));
1171*7c478bd9Sstevel@tonic-gate 		exit(32);
1172*7c478bd9Sstevel@tonic-gate 	}
1173*7c478bd9Sstevel@tonic-gate 	if (Nflag)
1174*7c478bd9Sstevel@tonic-gate 		return;
1175*7c478bd9Sstevel@tonic-gate 	n = write(fso, bf, size);
1176*7c478bd9Sstevel@tonic-gate 	if (n != size) {
1177*7c478bd9Sstevel@tonic-gate 		saverr = errno;
1178*7c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr,
1179*7c478bd9Sstevel@tonic-gate 			gettext("write error on sector %ld: %s\n"),
1180*7c478bd9Sstevel@tonic-gate 			bno, strerror(saverr));
1181*7c478bd9Sstevel@tonic-gate 		exit(32);
1182*7c478bd9Sstevel@tonic-gate 	}
1183*7c478bd9Sstevel@tonic-gate }
1184*7c478bd9Sstevel@tonic-gate 
1185*7c478bd9Sstevel@tonic-gate static void
1186*7c478bd9Sstevel@tonic-gate usage()
1187*7c478bd9Sstevel@tonic-gate {
1188*7c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr,
1189*7c478bd9Sstevel@tonic-gate 		gettext("udfs usage: mkfs [-F FSType] [-V]"
1190*7c478bd9Sstevel@tonic-gate 		" [-m] [-o options] special size(sectors)\n"));
1191*7c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr,
1192*7c478bd9Sstevel@tonic-gate 		gettext(" -m : dump fs cmd line used to make"
1193*7c478bd9Sstevel@tonic-gate 		" this partition\n"));
1194*7c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr,
1195*7c478bd9Sstevel@tonic-gate 		gettext(" -V : print this command line and return\n"));
1196*7c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr,
1197*7c478bd9Sstevel@tonic-gate 		gettext(" -o : udfs options: :psize=%d:label=%s\n"),
1198*7c478bd9Sstevel@tonic-gate 		sectorsize, udfs_label);
1199*7c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr,
1200*7c478bd9Sstevel@tonic-gate 		gettext("NOTE that all -o suboptions: must"
1201*7c478bd9Sstevel@tonic-gate 		" be separated only by commas so as to\n"));
1202*7c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr,
1203*7c478bd9Sstevel@tonic-gate 		gettext("be parsed as a single argument\n"));
1204*7c478bd9Sstevel@tonic-gate 	exit(32);
1205*7c478bd9Sstevel@tonic-gate }
1206*7c478bd9Sstevel@tonic-gate 
1207*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
1208*7c478bd9Sstevel@tonic-gate static void
1209*7c478bd9Sstevel@tonic-gate dump_fscmd(char *fsys, int fsi)
1210*7c478bd9Sstevel@tonic-gate {
1211*7c478bd9Sstevel@tonic-gate 	(void) printf(gettext("mkfs -F udfs -o "));
1212*7c478bd9Sstevel@tonic-gate 	(void) printf("psize=%d,label=\"%s\" %s %d\n",
1213*7c478bd9Sstevel@tonic-gate 		sectorsize, oldlabel, fsys, oldfssize);
1214*7c478bd9Sstevel@tonic-gate }
1215*7c478bd9Sstevel@tonic-gate 
1216*7c478bd9Sstevel@tonic-gate /* number ************************************************************* */
1217*7c478bd9Sstevel@tonic-gate /*									*/
1218*7c478bd9Sstevel@tonic-gate /* Convert a numeric arg to binary					*/
1219*7c478bd9Sstevel@tonic-gate /*									*/
1220*7c478bd9Sstevel@tonic-gate /* Arg:	 big - maximum valid input number				*/
1221*7c478bd9Sstevel@tonic-gate /* Global arg:  string - pointer to command arg				*/
1222*7c478bd9Sstevel@tonic-gate /*									*/
1223*7c478bd9Sstevel@tonic-gate /* Valid forms: 123 | 123k | 123*123 | 123x123				*/
1224*7c478bd9Sstevel@tonic-gate /*									*/
1225*7c478bd9Sstevel@tonic-gate /* Return:	converted number					*/
1226*7c478bd9Sstevel@tonic-gate /*									*/
1227*7c478bd9Sstevel@tonic-gate /* ******************************************************************** */
1228*7c478bd9Sstevel@tonic-gate 
1229*7c478bd9Sstevel@tonic-gate static int32_t
1230*7c478bd9Sstevel@tonic-gate number(long big, char *param)
1231*7c478bd9Sstevel@tonic-gate {
1232*7c478bd9Sstevel@tonic-gate 	char		*cs;
1233*7c478bd9Sstevel@tonic-gate 	int64_t		n = 0;
1234*7c478bd9Sstevel@tonic-gate 	int64_t		cut = BIG;
1235*7c478bd9Sstevel@tonic-gate 	int32_t		minus = 0;
1236*7c478bd9Sstevel@tonic-gate 
1237*7c478bd9Sstevel@tonic-gate #define	FOUND_MULT	0x1
1238*7c478bd9Sstevel@tonic-gate #define	FOUND_K		0x2
1239*7c478bd9Sstevel@tonic-gate 
1240*7c478bd9Sstevel@tonic-gate 	cs = string;
1241*7c478bd9Sstevel@tonic-gate 	if (*cs == '-') {
1242*7c478bd9Sstevel@tonic-gate 		minus = 1;
1243*7c478bd9Sstevel@tonic-gate 		cs++;
1244*7c478bd9Sstevel@tonic-gate 	}
1245*7c478bd9Sstevel@tonic-gate 	n = 0;
1246*7c478bd9Sstevel@tonic-gate 	while ((*cs != ' ') && (*cs != '\0') && (*cs != ',')) {
1247*7c478bd9Sstevel@tonic-gate 		if ((*cs >= '0') && (*cs <= '9')) {
1248*7c478bd9Sstevel@tonic-gate 			n = n * 10 + *cs - '0';
1249*7c478bd9Sstevel@tonic-gate 			cs++;
1250*7c478bd9Sstevel@tonic-gate 		} else if ((*cs == '*') || (*cs == 'x')) {
1251*7c478bd9Sstevel@tonic-gate 			if (number_flags & FOUND_MULT) {
1252*7c478bd9Sstevel@tonic-gate 				(void) fprintf(stderr,
1253*7c478bd9Sstevel@tonic-gate 				gettext("mkfs: only one \"*\" "
1254*7c478bd9Sstevel@tonic-gate 				"or \"x\" allowed\n"));
1255*7c478bd9Sstevel@tonic-gate 				exit(2);
1256*7c478bd9Sstevel@tonic-gate 			}
1257*7c478bd9Sstevel@tonic-gate 			number_flags |= FOUND_MULT;
1258*7c478bd9Sstevel@tonic-gate 			cs++;
1259*7c478bd9Sstevel@tonic-gate 			string = cs;
1260*7c478bd9Sstevel@tonic-gate 			n = n * number(big, param);
1261*7c478bd9Sstevel@tonic-gate 			cs = string;
1262*7c478bd9Sstevel@tonic-gate 			continue;
1263*7c478bd9Sstevel@tonic-gate 		} else if (*cs == 'k') {
1264*7c478bd9Sstevel@tonic-gate 			if (number_flags & FOUND_K) {
1265*7c478bd9Sstevel@tonic-gate 				(void) fprintf(stderr,
1266*7c478bd9Sstevel@tonic-gate 				gettext("mkfs: only one \"k\" allowed\n"));
1267*7c478bd9Sstevel@tonic-gate 				exit(2);
1268*7c478bd9Sstevel@tonic-gate 			}
1269*7c478bd9Sstevel@tonic-gate 			number_flags |= FOUND_K;
1270*7c478bd9Sstevel@tonic-gate 			n = n * 1024;
1271*7c478bd9Sstevel@tonic-gate 			cs++;
1272*7c478bd9Sstevel@tonic-gate 			continue;
1273*7c478bd9Sstevel@tonic-gate 		} else {
1274*7c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr,
1275*7c478bd9Sstevel@tonic-gate 				gettext("mkfs: bad numeric arg: \"%s\"\n"),
1276*7c478bd9Sstevel@tonic-gate 				string);
1277*7c478bd9Sstevel@tonic-gate 			exit(2);
1278*7c478bd9Sstevel@tonic-gate 		}
1279*7c478bd9Sstevel@tonic-gate 	}
1280*7c478bd9Sstevel@tonic-gate 
1281*7c478bd9Sstevel@tonic-gate 	if (n > cut) {
1282*7c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr,
1283*7c478bd9Sstevel@tonic-gate 			gettext("mkfs: value for %s overflowed\n"), param);
1284*7c478bd9Sstevel@tonic-gate 		exit(2);
1285*7c478bd9Sstevel@tonic-gate 	}
1286*7c478bd9Sstevel@tonic-gate 
1287*7c478bd9Sstevel@tonic-gate 	if (minus) {
1288*7c478bd9Sstevel@tonic-gate 		n = -n;
1289*7c478bd9Sstevel@tonic-gate 	}
1290*7c478bd9Sstevel@tonic-gate 
1291*7c478bd9Sstevel@tonic-gate 	if ((n > big) || (n < 0)) {
1292*7c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr,
1293*7c478bd9Sstevel@tonic-gate 			gettext("mkfs: argument %s out of range\n"), param);
1294*7c478bd9Sstevel@tonic-gate 		exit(2);
1295*7c478bd9Sstevel@tonic-gate 	}
1296*7c478bd9Sstevel@tonic-gate 
1297*7c478bd9Sstevel@tonic-gate 	string = cs;
1298*7c478bd9Sstevel@tonic-gate 	return ((int32_t)n);
1299*7c478bd9Sstevel@tonic-gate }
1300*7c478bd9Sstevel@tonic-gate 
1301*7c478bd9Sstevel@tonic-gate /* match ************************************************************** */
1302*7c478bd9Sstevel@tonic-gate /*									*/
1303*7c478bd9Sstevel@tonic-gate /* Compare two text strings for equality				*/
1304*7c478bd9Sstevel@tonic-gate /*									*/
1305*7c478bd9Sstevel@tonic-gate /* Arg:	 s - pointer to string to match with a command arg		*/
1306*7c478bd9Sstevel@tonic-gate /* Global arg:  string - pointer to command arg				*/
1307*7c478bd9Sstevel@tonic-gate /*									*/
1308*7c478bd9Sstevel@tonic-gate /* Return:	1 if match, 0 if no match				*/
1309*7c478bd9Sstevel@tonic-gate /*		If match, also reset `string' to point to the text	*/
1310*7c478bd9Sstevel@tonic-gate /*		that follows the matching text.				*/
1311*7c478bd9Sstevel@tonic-gate /*									*/
1312*7c478bd9Sstevel@tonic-gate /* ******************************************************************** */
1313*7c478bd9Sstevel@tonic-gate 
1314*7c478bd9Sstevel@tonic-gate static int
1315*7c478bd9Sstevel@tonic-gate match(char *s)
1316*7c478bd9Sstevel@tonic-gate {
1317*7c478bd9Sstevel@tonic-gate 	char *cs;
1318*7c478bd9Sstevel@tonic-gate 
1319*7c478bd9Sstevel@tonic-gate 	cs = string;
1320*7c478bd9Sstevel@tonic-gate 	while (*cs++ == *s) {
1321*7c478bd9Sstevel@tonic-gate 		if (*s++ == '\0') {
1322*7c478bd9Sstevel@tonic-gate 			goto true;
1323*7c478bd9Sstevel@tonic-gate 		}
1324*7c478bd9Sstevel@tonic-gate 	}
1325*7c478bd9Sstevel@tonic-gate 	if (*s != '\0') {
1326*7c478bd9Sstevel@tonic-gate 		return (0);
1327*7c478bd9Sstevel@tonic-gate 	}
1328*7c478bd9Sstevel@tonic-gate 
1329*7c478bd9Sstevel@tonic-gate true:
1330*7c478bd9Sstevel@tonic-gate 	cs--;
1331*7c478bd9Sstevel@tonic-gate 	string = cs;
1332*7c478bd9Sstevel@tonic-gate 	return (1);
1333*7c478bd9Sstevel@tonic-gate }
1334*7c478bd9Sstevel@tonic-gate 
1335*7c478bd9Sstevel@tonic-gate static uint32_t
1336*7c478bd9Sstevel@tonic-gate get_bsize()
1337*7c478bd9Sstevel@tonic-gate {
1338*7c478bd9Sstevel@tonic-gate 	struct dk_cinfo info;
1339*7c478bd9Sstevel@tonic-gate 	struct fd_char fd_char;
1340*7c478bd9Sstevel@tonic-gate 
1341*7c478bd9Sstevel@tonic-gate 	if (ioctl(fso, DKIOCINFO, &info) < 0) {
1342*7c478bd9Sstevel@tonic-gate 		perror("mkfs DKIOCINFO ");
1343*7c478bd9Sstevel@tonic-gate 		(void) fprintf(stdout,
1344*7c478bd9Sstevel@tonic-gate 			gettext("DKIOCINFO failed using psize = 2048"
1345*7c478bd9Sstevel@tonic-gate 			" for creating file-system\n"));
1346*7c478bd9Sstevel@tonic-gate 		return (0);
1347*7c478bd9Sstevel@tonic-gate 	}
1348*7c478bd9Sstevel@tonic-gate 
1349*7c478bd9Sstevel@tonic-gate 	switch (info.dki_ctype) {
1350*7c478bd9Sstevel@tonic-gate 		case DKC_CDROM :
1351*7c478bd9Sstevel@tonic-gate 			return (2048);
1352*7c478bd9Sstevel@tonic-gate 		case DKC_SCSI_CCS :
1353*7c478bd9Sstevel@tonic-gate 			/* FALLTHROUGH */
1354*7c478bd9Sstevel@tonic-gate 		case DKC_INTEL82072 :
1355*7c478bd9Sstevel@tonic-gate 			/* FALLTHROUGH */
1356*7c478bd9Sstevel@tonic-gate 		case DKC_INTEL82077 :
1357*7c478bd9Sstevel@tonic-gate 			/* FALLTHROUGH */
1358*7c478bd9Sstevel@tonic-gate 		case DKC_DIRECT :
1359*7c478bd9Sstevel@tonic-gate 			if (ioctl(fso, FDIOGCHAR, &fd_char) >= 0) {
1360*7c478bd9Sstevel@tonic-gate 				return (fd_char.fdc_sec_size);
1361*7c478bd9Sstevel@tonic-gate 			}
1362*7c478bd9Sstevel@tonic-gate 			/* FALLTHROUGH */
1363*7c478bd9Sstevel@tonic-gate 		case DKC_PCMCIA_ATA :
1364*7c478bd9Sstevel@tonic-gate 			return (512);
1365*7c478bd9Sstevel@tonic-gate 		default :
1366*7c478bd9Sstevel@tonic-gate 			return (0);
1367*7c478bd9Sstevel@tonic-gate 	}
1368*7c478bd9Sstevel@tonic-gate }
1369*7c478bd9Sstevel@tonic-gate 
1370*7c478bd9Sstevel@tonic-gate /*
1371*7c478bd9Sstevel@tonic-gate  * Read in the volume sequences descriptors.
1372*7c478bd9Sstevel@tonic-gate  */
1373*7c478bd9Sstevel@tonic-gate static int
1374*7c478bd9Sstevel@tonic-gate readvolseq()
1375*7c478bd9Sstevel@tonic-gate {
1376*7c478bd9Sstevel@tonic-gate 	struct tag *tp;
1377*7c478bd9Sstevel@tonic-gate 	uint8_t *cp, *end;
1378*7c478bd9Sstevel@tonic-gate 	int err;
1379*7c478bd9Sstevel@tonic-gate 	struct pri_vol_desc *pvolp;
1380*7c478bd9Sstevel@tonic-gate 	struct part_desc *partp;
1381*7c478bd9Sstevel@tonic-gate 	struct log_vol_desc *logvp;
1382*7c478bd9Sstevel@tonic-gate 	struct anch_vol_desc_ptr *avp;
1383*7c478bd9Sstevel@tonic-gate 	char *main_vdbuf;
1384*7c478bd9Sstevel@tonic-gate 	uint32_t nextblock;
1385*7c478bd9Sstevel@tonic-gate 
1386*7c478bd9Sstevel@tonic-gate 	avp = (struct anch_vol_desc_ptr *)malloc(sectorsize);
1387*7c478bd9Sstevel@tonic-gate 	rdfs(FIRSTAVDP, sectorsize, (char *)avp);
1388*7c478bd9Sstevel@tonic-gate 	tp = (struct tag *)avp;
1389*7c478bd9Sstevel@tonic-gate 	err = verifytag(tp, FIRSTAVDP, tp, UD_ANCH_VOL_DESC);
1390*7c478bd9Sstevel@tonic-gate 	if (err)
1391*7c478bd9Sstevel@tonic-gate 		return (0);
1392*7c478bd9Sstevel@tonic-gate 	main_vdbuf = malloc(avp->avd_main_vdse.ext_len);
1393*7c478bd9Sstevel@tonic-gate 	if (main_vdbuf == NULL) {
1394*7c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, gettext("Cannot allocate space for "
1395*7c478bd9Sstevel@tonic-gate 			"volume sequences\n"));
1396*7c478bd9Sstevel@tonic-gate 		exit(32);
1397*7c478bd9Sstevel@tonic-gate 	}
1398*7c478bd9Sstevel@tonic-gate 	rdfs(avp->avd_main_vdse.ext_loc, avp->avd_main_vdse.ext_len,
1399*7c478bd9Sstevel@tonic-gate 		main_vdbuf);
1400*7c478bd9Sstevel@tonic-gate 	end = (uint8_t *)main_vdbuf + avp->avd_main_vdse.ext_len;
1401*7c478bd9Sstevel@tonic-gate 
1402*7c478bd9Sstevel@tonic-gate 	nextblock = avp->avd_main_vdse.ext_loc;
1403*7c478bd9Sstevel@tonic-gate 	for (cp = (uint8_t *)main_vdbuf; cp < end; cp += sectorsize,
1404*7c478bd9Sstevel@tonic-gate 		nextblock++) {
1405*7c478bd9Sstevel@tonic-gate 		/* LINTED */
1406*7c478bd9Sstevel@tonic-gate 		tp = (struct tag *)cp;
1407*7c478bd9Sstevel@tonic-gate 		err = verifytag(tp, nextblock, tp, 0);
1408*7c478bd9Sstevel@tonic-gate 		if (err)
1409*7c478bd9Sstevel@tonic-gate 			continue;
1410*7c478bd9Sstevel@tonic-gate 
1411*7c478bd9Sstevel@tonic-gate 		switch (tp->tag_id) {
1412*7c478bd9Sstevel@tonic-gate 		case UD_PRI_VOL_DESC:
1413*7c478bd9Sstevel@tonic-gate 			/* Bump serial number, according to spec. */
1414*7c478bd9Sstevel@tonic-gate 			serialnum = tp->tag_sno + 1;
1415*7c478bd9Sstevel@tonic-gate 			pvolp = (struct pri_vol_desc *)tp;
1416*7c478bd9Sstevel@tonic-gate 			oldlabel = pvolp->pvd_vol_id + 1;
1417*7c478bd9Sstevel@tonic-gate 			break;
1418*7c478bd9Sstevel@tonic-gate 		case UD_ANCH_VOL_DESC:
1419*7c478bd9Sstevel@tonic-gate 			avp = (struct anch_vol_desc_ptr *)tp;
1420*7c478bd9Sstevel@tonic-gate 			break;
1421*7c478bd9Sstevel@tonic-gate 		case UD_VOL_DESC_PTR:
1422*7c478bd9Sstevel@tonic-gate 			break;
1423*7c478bd9Sstevel@tonic-gate 		case UD_IMPL_USE_DESC:
1424*7c478bd9Sstevel@tonic-gate 			break;
1425*7c478bd9Sstevel@tonic-gate 		case UD_PART_DESC:
1426*7c478bd9Sstevel@tonic-gate 			partp = (struct part_desc *)tp;
1427*7c478bd9Sstevel@tonic-gate 			part_start = partp->pd_part_start;
1428*7c478bd9Sstevel@tonic-gate 			part_len = partp->pd_part_length;
1429*7c478bd9Sstevel@tonic-gate 			oldfssize = part_start + part_len;
1430*7c478bd9Sstevel@tonic-gate 			break;
1431*7c478bd9Sstevel@tonic-gate 		case UD_LOG_VOL_DESC:
1432*7c478bd9Sstevel@tonic-gate 			logvp = (struct log_vol_desc *)tp;
1433*7c478bd9Sstevel@tonic-gate 			break;
1434*7c478bd9Sstevel@tonic-gate 		case UD_UNALL_SPA_DESC:
1435*7c478bd9Sstevel@tonic-gate 			break;
1436*7c478bd9Sstevel@tonic-gate 		case UD_TERM_DESC:
1437*7c478bd9Sstevel@tonic-gate 			goto done;
1438*7c478bd9Sstevel@tonic-gate 			break;
1439*7c478bd9Sstevel@tonic-gate 		case UD_LOG_VOL_INT:
1440*7c478bd9Sstevel@tonic-gate 			break;
1441*7c478bd9Sstevel@tonic-gate 		default:
1442*7c478bd9Sstevel@tonic-gate 			break;
1443*7c478bd9Sstevel@tonic-gate 		}
1444*7c478bd9Sstevel@tonic-gate 	}
1445*7c478bd9Sstevel@tonic-gate done:
1446*7c478bd9Sstevel@tonic-gate 	if (!partp || !logvp) {
1447*7c478bd9Sstevel@tonic-gate 		return (0);
1448*7c478bd9Sstevel@tonic-gate 	}
1449*7c478bd9Sstevel@tonic-gate 	return (1);
1450*7c478bd9Sstevel@tonic-gate }
1451*7c478bd9Sstevel@tonic-gate 
1452*7c478bd9Sstevel@tonic-gate uint32_t
1453*7c478bd9Sstevel@tonic-gate get_last_block()
1454*7c478bd9Sstevel@tonic-gate {
1455*7c478bd9Sstevel@tonic-gate 	struct vtoc vtoc;
1456*7c478bd9Sstevel@tonic-gate 	struct dk_cinfo dki_info;
1457*7c478bd9Sstevel@tonic-gate 
1458*7c478bd9Sstevel@tonic-gate 	if (ioctl(fsi, DKIOCGVTOC, (intptr_t)&vtoc) != 0) {
1459*7c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, gettext("Unable to read VTOC\n"));
1460*7c478bd9Sstevel@tonic-gate 		return (0);
1461*7c478bd9Sstevel@tonic-gate 	}
1462*7c478bd9Sstevel@tonic-gate 
1463*7c478bd9Sstevel@tonic-gate 	if (vtoc.v_sanity != VTOC_SANE) {
1464*7c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, gettext("Vtoc.v_sanity != VTOC_SANE\n"));
1465*7c478bd9Sstevel@tonic-gate 		return (0);
1466*7c478bd9Sstevel@tonic-gate 	}
1467*7c478bd9Sstevel@tonic-gate 
1468*7c478bd9Sstevel@tonic-gate 	if (ioctl(fsi, DKIOCINFO, (intptr_t)&dki_info) != 0) {
1469*7c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr,
1470*7c478bd9Sstevel@tonic-gate 		    gettext("Could not get the slice information\n"));
1471*7c478bd9Sstevel@tonic-gate 		return (0);
1472*7c478bd9Sstevel@tonic-gate 	}
1473*7c478bd9Sstevel@tonic-gate 
1474*7c478bd9Sstevel@tonic-gate 	if (dki_info.dki_partition > V_NUMPAR) {
1475*7c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr,
1476*7c478bd9Sstevel@tonic-gate 		    gettext("dki_info.dki_partition > V_NUMPAR\n"));
1477*7c478bd9Sstevel@tonic-gate 		return (0);
1478*7c478bd9Sstevel@tonic-gate 	}
1479*7c478bd9Sstevel@tonic-gate 
1480*7c478bd9Sstevel@tonic-gate 	return ((uint32_t)vtoc.v_part[dki_info.dki_partition].p_size);
1481*7c478bd9Sstevel@tonic-gate }
1482