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