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