2 #include <parted/vtoc.h>
5 #define PDEBUG fprintf(stderr, "%s:%d:%s\n", \
13 #include <parted/parted.h>
17 # define _(String) dgettext (PACKAGE, String)
19 # define _(String) (String)
20 #endif /* ENABLE_NLS */
22 static const unsigned char EBCtoASC[256] =
24 /* 0x00 NUL SOH STX ETX *SEL HT *RNL DEL */
25 0x00, 0x01, 0x02, 0x03, 0x07, 0x09, 0x07, 0x7F,
26 /* 0x08 -GE -SPS -RPT VT FF CR SO SI */
27 0x07, 0x07, 0x07, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
28 /* 0x10 DLE DC1 DC2 DC3 -RES -NL BS -POC
30 0x10, 0x11, 0x12, 0x13, 0x07, 0x0A, 0x08, 0x07,
31 /* 0x18 CAN EM -UBS -CU1 -IFS -IGS -IRS -ITB
33 0x18, 0x19, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
34 /* 0x20 -DS -SOS FS -WUS -BYP LF ETB ESC
36 0x07, 0x07, 0x1C, 0x07, 0x07, 0x0A, 0x17, 0x1B,
37 /* 0x28 -SA -SFE -SM -CSP -MFA ENQ ACK BEL
39 0x07, 0x07, 0x07, 0x07, 0x07, 0x05, 0x06, 0x07,
40 /* 0x30 ---- ---- SYN -IR -PP -TRN -NBS EOT */
41 0x07, 0x07, 0x16, 0x07, 0x07, 0x07, 0x07, 0x04,
42 /* 0x38 -SBS -IT -RFF -CU3 DC4 NAK ---- SUB */
43 0x07, 0x07, 0x07, 0x07, 0x14, 0x15, 0x07, 0x1A,
44 /* 0x40 SP RSP ä ---- */
45 0x20, 0xFF, 0x83, 0x84, 0x85, 0xA0, 0x07, 0x86,
47 0x87, 0xA4, 0x9B, 0x2E, 0x3C, 0x28, 0x2B, 0x7C,
49 0x26, 0x82, 0x88, 0x89, 0x8A, 0xA1, 0x8C, 0x07,
50 /* 0x58 ß ! $ * ) ; */
51 0x8D, 0xE1, 0x21, 0x24, 0x2A, 0x29, 0x3B, 0xAA,
52 /* 0x60 - / ---- Ä ---- ---- ---- */
53 0x2D, 0x2F, 0x07, 0x8E, 0x07, 0x07, 0x07, 0x8F,
54 /* 0x68 ---- , % _ > ? */
55 0x80, 0xA5, 0x07, 0x2C, 0x25, 0x5F, 0x3E, 0x3F,
56 /* 0x70 --- ---- ---- ---- ---- ---- ---- */
57 0x07, 0x90, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
58 /* 0x78 * ` : # @ ' = " */
59 0x70, 0x60, 0x3A, 0x23, 0x40, 0x27, 0x3D, 0x22,
60 /* 0x80 * a b c d e f g */
61 0x07, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
62 /* 0x88 h i ---- ---- ---- */
63 0x68, 0x69, 0xAE, 0xAF, 0x07, 0x07, 0x07, 0xF1,
64 /* 0x90 ° j k l m n o p */
65 0xF8, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70,
66 /* 0x98 q r ---- ---- */
67 0x71, 0x72, 0xA6, 0xA7, 0x91, 0x07, 0x92, 0x07,
68 /* 0xA0 ~ s t u v w x */
69 0xE6, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
70 /* 0xA8 y z ---- ---- ---- ---- */
71 0x79, 0x7A, 0xAD, 0xAB, 0x07, 0x07, 0x07, 0x07,
72 /* 0xB0 ^ ---- § ---- */
73 0x5E, 0x9C, 0x9D, 0xFA, 0x07, 0x07, 0x07, 0xAC,
74 /* 0xB8 ---- [ ] ---- ---- ---- ---- */
75 0xAB, 0x07, 0x5B, 0x5D, 0x07, 0x07, 0x07, 0x07,
76 /* 0xC0 { A B C D E F G */
77 0x7B, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
78 /* 0xC8 H I ---- ö ---- */
79 0x48, 0x49, 0x07, 0x93, 0x94, 0x95, 0xA2, 0x07,
80 /* 0xD0 } J K L M N O P */
81 0x7D, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50,
83 0x51, 0x52, 0x07, 0x96, 0x81, 0x97, 0xA3, 0x98,
84 /* 0xE0 \ S T U V W X */
85 0x5C, 0xF6, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
86 /* 0xE8 Y Z ---- Ö ---- ---- ---- */
87 0x59, 0x5A, 0xFD, 0x07, 0x99, 0x07, 0x07, 0x07,
88 /* 0xF0 0 1 2 3 4 5 6 7 */
89 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
90 /* 0xF8 8 9 ---- ---- Ü ---- ---- ---- */
91 0x38, 0x39, 0x07, 0x07, 0x9A, 0x07, 0x07, 0x07
94 static const unsigned char ASCtoEBC[256] =
96 /*00 NL SH SX EX ET NQ AK BL */
97 0x00, 0x01, 0x02, 0x03, 0x37, 0x2D, 0x2E, 0x2F,
98 /*08 BS HT LF VT FF CR SO SI */
99 0x16, 0x05, 0x15, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
100 /*10 DL D1 D2 D3 D4 NK SN EB */
101 0x10, 0x11, 0x12, 0x13, 0x3C, 0x15, 0x32, 0x26,
102 /*18 CN EM SB EC FS GS RS US */
103 0x18, 0x19, 0x3F, 0x27, 0x1C, 0x1D, 0x1E, 0x1F,
104 /*20 SP ! " # $ % & ' */
105 0x40, 0x5A, 0x7F, 0x7B, 0x5B, 0x6C, 0x50, 0x7D,
106 /*28 ( ) * + , - . / */
107 0x4D, 0x5D, 0x5C, 0x4E, 0x6B, 0x60, 0x4B, 0x61,
108 /*30 0 1 2 3 4 5 6 7 */
109 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
110 /*38 8 9 : ; < = > ? */
111 0xF8, 0xF9, 0x7A, 0x5E, 0x4C, 0x7E, 0x6E, 0x6F,
112 /*40 @ A B C D E F G */
113 0x7C, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
114 /*48 H I J K L M N O */
115 0xC8, 0xC9, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6,
116 /*50 P Q R S T U V W */
117 0xD7, 0xD8, 0xD9, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6,
118 /*58 X Y Z [ \ ] ^ _ */
119 0xE7, 0xE8, 0xE9, 0xAD, 0xE0, 0xBD, 0x5F, 0x6D,
120 /*60 ` a b c d e f g */
121 0x79, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
122 /*68 h i j k l m n o */
123 0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96,
124 /*70 p q r s t u v w */
125 0x97, 0x98, 0x99, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6,
126 /*78 x y z { | } ~ DL */
127 0xA7, 0xA8, 0xA9, 0xC0, 0x4F, 0xD0, 0xA1, 0x07,
128 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
129 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
130 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
131 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
132 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
133 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
134 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
135 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
136 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
137 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
138 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
139 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
140 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
141 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
142 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
143 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xFF
153 static char buffer[85];
156 vtoc_error (enum failure why, char *s1, char *s2)
163 sprintf(error, "VTOC: %s -- %s\n%s\n",
164 _("opening of device failed"), s1, s2);
167 sprintf(error, "VTOC: %s -- %s\n%s\n",
168 _("seeking on device failed"), s1, s2);
170 case unable_to_write:
171 sprintf(error, "VTOC: %s -- %s\n%s\n",
172 _("writing to device failed"), s1, s2);
175 sprintf(error, "VTOC: %s -- %s\n%s\n",
176 _("reading from device failed"), s1, s2);
179 sprintf(error, "VTOC: %s\n", _("Fatal error"));
182 ped_exception_throw(PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL, error);
186 vtoc_ebcdic_enc (char source[LINE_LENGTH],
187 char target[LINE_LENGTH],
193 for (i = 0; i < l; i++)
194 target[i]=ASCtoEBC[(unsigned char)(source[i])];
200 vtoc_ebcdic_dec (char source[LINE_LENGTH],
201 char target[LINE_LENGTH],
207 for (i = 0; i < l; i++)
208 target[i]=EBCtoASC[(unsigned char)(source[i])];
214 vtoc_set_extent (extent_t *ext, u_int8_t typeind, u_int8_t seqno,
215 cchh_t *lower, cchh_t *upper)
218 ext->typeind = typeind;
220 memcpy(&ext->llimit,lower,sizeof(cchh_t));
221 memcpy(&ext->ulimit,upper,sizeof(cchh_t));
225 vtoc_set_cchh (cchh_t *addr, u_int16_t cc, u_int16_t hh)
233 vtoc_set_ttr (ttr_t *addr, u_int16_t tt, u_int8_t r)
241 vtoc_set_cchhb (cchhb_t *addr, u_int16_t cc, u_int16_t hh, u_int8_t b)
250 vtoc_set_date (labeldate_t * d, u_int8_t year, u_int16_t day)
258 * initializes the volume label with EBCDIC spaces
261 vtoc_volume_label_init (volume_label_t *vlabel)
264 sprintf(buffer, "%84s", " ");
265 vtoc_ebcdic_enc(buffer, buffer, 84);
266 strncpy(vlabel->volkey, buffer, 84);
270 * reads the volume label from dasd
273 vtoc_read_volume_label (int f, unsigned long vlabel_start,
274 volume_label_t *vlabel)
279 if (lseek(f, vlabel_start, SEEK_SET) == -1) {
280 vtoc_error(unable_to_seek, "vtoc_read_volume_label",
281 _("Could not read volume label."));
285 rc = read(f, vlabel, sizeof(volume_label_t));
286 if (rc != sizeof(volume_label_t)) {
287 vtoc_error(unable_to_read, "vtoc_read_volume_label",
288 _("Could not read volume label."));
296 * writes the volume label to dasd
299 vtoc_write_volume_label (int f, unsigned long vlabel_start,
300 volume_label_t *vlabel)
305 if (lseek(f, vlabel_start, SEEK_SET) == -1)
306 vtoc_error(unable_to_seek, "vtoc_write_volume_label",
307 _("Could not write volume label."));
309 rc = write(f, vlabel, sizeof(volume_label_t));
310 if (rc != sizeof(volume_label_t))
311 vtoc_error(unable_to_write, "vtoc_write_volume_label",
312 _("Could not write volume label."));
318 * takes a string as input, converts it to uppercase, translates
319 * it to EBCDIC and fills it up with spaces before it copies it
320 * as volume serial to the volume label
323 vtoc_volume_label_set_volser (volume_label_t *vlabel, char *volser)
326 int j, i = strlen(volser);
327 char s[VOLSER_LENGTH + 1];
330 vtoc_ebcdic_enc(s, s, VOLSER_LENGTH);
331 strncpy(vlabel->volid, s, VOLSER_LENGTH);
333 if (i > VOLSER_LENGTH)
336 strncpy(s, volser, i);
338 s[j] = toupper(s[j]);
340 s[VOLSER_LENGTH] = 0x00;
341 vtoc_ebcdic_enc(s, s, i);
342 strncpy(vlabel->volid, s, i);
348 * returns the volume serial number right after it is translated
352 vtoc_volume_label_get_volser (volume_label_t *vlabel, char *volser)
355 vtoc_ebcdic_dec(vlabel->volid, volser, VOLSER_LENGTH);
361 * sets the volume label key right after
362 * it has been translated to EBCDIC
365 vtoc_volume_label_set_key (volume_label_t *vlabel, char *key)
370 vtoc_ebcdic_enc(key, s, 4);
371 strncpy(vlabel->volkey, s, 4);
377 * sets the volume label identifier right
378 * after it has been translated to EBCDIC
381 vtoc_volume_label_set_label (volume_label_t *vlabel, char *lbl)
386 vtoc_ebcdic_enc(lbl, s, 4);
387 strncpy(vlabel->vollbl, s, 4);
393 * returns the volume label key = the label identifier
394 * right after it has been translated to ASCII
397 vtoc_volume_label_get_label (volume_label_t *vlabel, char *lbl)
400 vtoc_ebcdic_dec(vlabel->vollbl, lbl, 4);
406 * reads either a format4 label or a format1 label
407 * from the specified position
410 vtoc_read_label (int f, unsigned long position, format1_label_t *f1,
411 format4_label_t *f4, format5_label_t *f5, format7_label_t *f7)
416 if (lseek(f, position, SEEK_SET) == -1)
417 vtoc_error(unable_to_seek, "vtoc_read_label",
418 _("Could not read VTOC labels."));
421 t = sizeof(format1_label_t);
422 if (read(f, f1, t) != t)
423 vtoc_error(unable_to_read, "vtoc_read_label",
424 _("Could not read VTOC FMT1 DSCB."));
428 t = sizeof(format4_label_t);
429 if (read(f, f4, t) != t)
430 vtoc_error(unable_to_read, "vtoc_read_label",
431 _("Could not read VTOC FMT4 DSCB."));
435 t = sizeof(format5_label_t);
436 if (read(f, f5, t) != t)
437 vtoc_error(unable_to_read, "vtoc_read_label",
438 _("Could not read VTOC FMT5 DSCB."));
442 t = sizeof(format7_label_t);
443 if (read(f, f7, t) != t)
444 vtoc_error(unable_to_read, "vtoc_read_label",
445 _("Could not read VTOC FMT7 DSCB."));
450 * writes either a FMT1, FMT4 or FMT5 label
451 * to the specified position
454 vtoc_write_label (int f, unsigned long position, format1_label_t *f1,
455 format4_label_t *f4, format5_label_t *f5, format7_label_t *f7)
460 if (lseek(f, position, SEEK_SET) == -1)
461 vtoc_error(unable_to_seek, "vtoc_write_label",
462 _("Could not write VTOC labels."));
465 t = sizeof(format1_label_t);
466 if (write(f, f1, t) != t)
467 vtoc_error(unable_to_write, "vtoc_write_label",
468 _("Could not write VTOC FMT1 DSCB."));
472 t = sizeof(format4_label_t);
473 if (write(f, f4, t) != t)
474 vtoc_error(unable_to_write, "vtoc_write_label",
475 _("Could not write VTOC FMT4 DSCB."));
479 t = sizeof(format5_label_t);
480 if (write(f, f5, t) != t)
481 vtoc_error(unable_to_write, "vtoc_write_label",
482 _("Could not write VTOC FMT5 DSCB."));
486 t = sizeof(format7_label_t);
487 if (write(f, f7, t) != t)
488 vtoc_error(unable_to_write, "vtoc_write_label",
489 _("Could not write VTOC FMT7 DSCB."));
494 * initializes a format4 label
497 vtoc_init_format4_label (format4_label_t *f4, unsigned int usable_partitions,
498 unsigned int cylinders, unsigned int tracks,
499 unsigned int blocks, unsigned int blksize,
505 cchh_t lower = {VTOC_START_CC, VTOC_START_HH};
506 cchh_t upper = {VTOC_START_CC, VTOC_START_HH};
508 for (i=0; i<44; i++) f4->DS4KEYCD[i] = 0x04;
511 vtoc_set_cchhb(&f4->DS4HPCHR, 0x0000, 0x0000, 0x00);
512 f4->DS4DSREC = blocks - 2;
513 /* free space starts right behind VTOC
514 vtoc_set_cchh(&f4->DS4HCCHH, VTOC_START_CC, VTOC_START_HH + 1);*/
515 vtoc_set_cchh(&f4->DS4HCCHH, 0x0000, 0x0000);
516 f4->DS4NOATK = 0x0000;
522 /* -- begin f4->DS4DEVCT -- */
523 f4->DS4DEVCT.DS4DSCYL = cylinders;
524 f4->DS4DEVCT.DS4DSTRK = tracks;
528 f4->DS4DEVCT.DS4DEVTK = DASD_3380_VALUE;
531 f4->DS4DEVCT.DS4DEVTK = DASD_3390_VALUE;
534 f4->DS4DEVCT.DS4DEVTK = DASD_9345_VALUE;
537 f4->DS4DEVCT.DS4DEVTK = blocks * blksize;;
540 f4->DS4DEVCT.DS4DEVI = 0x00;
541 f4->DS4DEVCT.DS4DEVL = 0x00;
542 f4->DS4DEVCT.DS4DEVK = 0x00;
543 f4->DS4DEVCT.DS4DEVFG = 0x30;
544 f4->DS4DEVCT.DS4DEVTL = 0x0000;
545 f4->DS4DEVCT.DS4DEVDT = blocks;
546 f4->DS4DEVCT.DS4DEVDB = 0x00;
547 /* -- end f4->DS4DEVCT -- */
549 bzero(f4->DS4AMTIM, sizeof(f4->DS4AMTIM));
550 bzero(f4->DS4AMCAT, sizeof(f4->DS4AMCAT));
551 bzero(f4->DS4R2TIM, sizeof(f4->DS4R2TIM));
552 bzero(f4->res1, sizeof(f4->res1));
553 bzero(f4->DS4F6PTR, sizeof(f4->DS4F6PTR));
555 /* -- begin f4lbl->DS4VTOCE -- */
556 vtoc_set_extent(&f4->DS4VTOCE, 0x01, 0x00, &lower, &upper);
557 /* -- end f4lbl->DS4VTOCE -- */
559 bzero(f4->res2, sizeof(f4->res2));
561 bzero(&f4->DS4EFPTR, sizeof(f4->DS4EFPTR));
562 bzero(f4->res3, sizeof(f4->res3));
566 * initializes a format5 label
569 vtoc_init_format5_label (format5_label_t *f5)
574 bzero(f5, sizeof(format5_label_t));
576 f5->DS5KEYID[i] = 0x05;
581 * initializes a format7 label
584 vtoc_init_format7_label (format7_label_t *f7)
589 bzero(f7, sizeof(format7_label_t));
591 f7->DS7KEYID[i] = 0x07;
596 * initializes a format1 label
599 vtoc_init_format1_label (char *volid, unsigned int blksize,
600 extent_t *part_extent, format1_label_t *f1)
603 struct tm * creatime;
607 /* get actual date */
609 creatime = gmtime(&t);
611 bzero(f1->DS1DSNAM, sizeof(f1->DS1DSNAM));
612 sprintf(str, "PART .NEW ");
613 vtoc_ebcdic_enc(str, str, 44);
614 strncpy(f1->DS1DSNAM, str, 44);
616 strncpy(f1->DS1DSSN, " ", 6);
617 f1->DS1VOLSQ = 0x0001;
619 vtoc_set_date(&f1->DS1CREDT, (u_int8_t) creatime->tm_year,
620 (u_int16_t) creatime->tm_yday);
621 /* expires never - 99 365 */
622 vtoc_set_date(&f1->DS1EXPDT, 0x63, 0x016D);
626 vtoc_ebcdic_enc("IBM LINUX ", str, 13);
627 strncpy(f1->DS1SYSCD, str, 13);
628 vtoc_set_date(&f1->DS1REFD, (u_int8_t) creatime->tm_year,
629 (u_int16_t) creatime->tm_yday);
632 f1->DS1SCXTV = 0x0000;
637 f1->DS1BLKL = blksize;
638 f1->DS1LRECL = blksize;
641 f1->DS1DSIND = 0x80; /* last volume for this dataset */
643 bzero(&f1->DS1SCAL3, sizeof(f1->DS1SCAL3));
644 vtoc_set_ttr(&f1->DS1LSTAR, 0x0000, 0x00);
646 bzero(&f1->res1, sizeof(f1->res1));
647 memcpy(&f1->DS1EXT1, part_extent, sizeof(extent_t));
648 bzero(&f1->DS1EXT2, sizeof(extent_t));
649 bzero(&f1->DS1EXT3, sizeof(extent_t));
650 vtoc_set_cchhb(&f1->DS1PTRDS, 0x0000, 0x0000, 0x00);
654 * do some updates to the VTOC format4 label
657 vtoc_update_format4_label (format4_label_t *f4, cchhb_t *highest_f1,
658 u_int16_t unused_update)
661 /* update highest address of a format 1 label */
662 memcpy(&f4->DS4HPCHR, highest_f1, sizeof(cchhb_t));
664 /* update unused DSCB count */
665 f4->DS4DSREC = unused_update;
669 * reorganizes all extents within a FMT5 label
672 vtoc_reorganize_FMT5_extents (format5_label_t *f5)
675 ds5ext_t *ext, *last, tmp;
678 for (i=0; i<26; i++) {
680 last = &f5->DS5AVEXT;
681 else if ((i > 0) && (i < 8))
682 last = &f5->DS5EXTAV[i-1];
684 last = &f5->DS5MAVET[i-8];
686 for (j=i; j<26; j++) {
689 else if ((j > 0) && (j < 8))
690 ext = &f5->DS5EXTAV[j-1];
692 ext = &f5->DS5MAVET[j-8];
694 if (((ext->t > 0) && (last->t == 0)) ||
695 ((ext->t > 0) && (ext->t < last->t)))
712 * add a free space extent description to the VTOC FMT5 DSCB
715 vtoc_update_format5_label_add (format5_label_t *f5, int verbose, int cyl,
716 int trk, u_int16_t a, u_int16_t b, u_int8_t c)
719 ds5ext_t *ext = NULL, *tmp = NULL;
722 for (i=0; i<26; i++) {
725 else if ((i > 0) && (i < 8))
726 ext = &f5->DS5EXTAV[i-1];
728 ext = &f5->DS5MAVET[i-8];
730 if (((a < ext->t) && (a + b*trk + c > ext->t)) ||
731 ((a > ext->t) && (ext->t + ext->fc*trk + ext->ft > a)))
733 puts ("BUG: overlapping free space extents "
734 "in FMT5 DSCB!\nexiting...");
738 if ((ext->t + ext->fc + ext->ft) == 0x0000) {
744 puts ("FMT5 add extent: add new extent");
750 /* BUG: no free extent found */
751 puts ("BUG: no free FMT5 DSCB extent found!\nexiting...");
755 for (i=0; i<26; i++) {
758 else if ((i > 0) && (i < 8))
759 ext = &f5->DS5EXTAV[i-1];
761 ext = &f5->DS5MAVET[i-8];
763 if ((ext->t + ext->fc + ext->ft) == 0x0000)
766 if ((ext->t + ext->fc*trk + ext->ft) == tmp->t) {
767 /* this extent precedes the new one */
768 ext->fc += (tmp->fc + (tmp->ft + ext->ft)/trk);
769 ext->ft = (tmp->ft + ext->ft) % trk;
770 bzero(tmp, sizeof(ds5ext_t));
774 puts ("FMT5 add extent: "
775 "merge with predecessor");
781 if ((tmp->t + tmp->fc*trk + tmp->ft) == ext->t) {
782 /* this extent succeeds the new one */
784 ext->fc += (tmp->fc + (tmp->ft + ext->ft)/trk);
785 ext->ft = (tmp->ft + ext->ft) % trk;
786 bzero(tmp, sizeof(ds5ext_t));
790 puts ("FMT5 add extent: "
791 "merge with successor");
800 * remove a free space extent description from the VTOC FMT5 DSCB
803 vtoc_update_format5_label_del (format5_label_t *f5, int verbose, int cyl,
804 int trk, u_int16_t a, u_int16_t b, u_int8_t c)
810 for (i=0; i<26; i++) {
813 else if ((i > 0) && (i < 8))
814 ext = &f5->DS5EXTAV[i-1];
816 ext = &f5->DS5MAVET[i-8];
818 if ((a == ext->t) && (b == ext->fc) && (c == ext->ft)) {
819 /* fills up whole free space gap */
820 bzero(ext, sizeof(ds5ext_t));
823 puts ("FMT5 del extent: fills whole gap");
829 if ((a == ext->t) && ((b < ext->fc) || (c < ext->ft))) {
830 /* left-bounded in free space gap */
831 ext->t = ext->t + b*trk + c;
835 ext->ft -= (c - trk);
842 puts ("FMT5 del extent: left bounded");
849 && ((ext->t + ext->fc*trk + ext->ft) == (a + b*trk + c)))
851 /* right-bounded in free space gap */
854 ext->ft -= (c - trk);
861 puts ("FMT5 del extent: right bounded");
868 && ((ext->t + ext->fc*trk + ext->ft) > (a + b*trk + c)))
870 /* partition devides free space into 2 pieces */
871 u_int16_t x = a + b*trk + c;
875 w = (ext->t + ext->fc*trk + ext->ft) - (a + b*trk + c);
879 ext->fc = (a - ext->t) / trk;
880 ext->ft = (a - ext->t) % trk;
882 vtoc_update_format5_label_add(f5, verbose,
886 puts ("FMT5 del extent: 2 pieces");
892 if ((a < ext->t) && (a + b*trk + c > ext->t)
893 && (a + b*trk + c < ext->t + ext->fc*trk + ext->ft))
895 puts ("BUG: corresponding free space extent "
896 "doesn't match free space currently shown "
897 "in FMT5 DSCB!\nexiting...");
901 if ((a > ext->t) && (a < ext->t + ext->fc*trk + ext->ft)
902 && (a + b*trk + c > ext->t + ext->fc*trk + ext->ft))
904 puts ("BUG: specified free space extent for "
905 "deleting doesn't match free space "
906 "currently shown in FMT5 DSCB!\n"
915 puts ("BUG: specified free space extent for "
916 "deleting not found in FMT5 DSCB!\n"
922 * reorganizes all extents within a FMT7 label
925 vtoc_reorganize_FMT7_extents (format7_label_t *f7)
928 ds7ext_t *ext, *last, tmp;
931 for (i=0; i<16; i++) {
933 last = &f7->DS7EXTNT[i];
935 last = &f7->DS7ADEXT[i-5];
937 for (j=i; j<16; j++) {
939 ext = &f7->DS7EXTNT[j];
941 ext = &f7->DS7ADEXT[j-5];
943 if (((ext->a > 0) && (last->a == 0))
944 || ((ext->a > 0) && (ext->a < last->a)))
958 * add a free space extent description to the VTOC FMT7 DSCB
961 vtoc_update_format7_label_add (format7_label_t *f7, int verbose,
962 u_int32_t a, u_int32_t b)
965 ds7ext_t *ext = NULL, *tmp = NULL;
968 for (i=0; i<16; i++) {
970 ext = &f7->DS7EXTNT[i];
972 ext = &f7->DS7ADEXT[i-5];
974 if (((a < ext->a) && (b > ext->a) && (b < ext->b))
975 || ((a > ext->a) && (a < ext->b) && (b > ext->b)))
977 puts ("BUG: overlapping free space extents "
978 "in FMT7 DSCB!\nexiting...");
982 if ((ext->a + ext->b) == 0x00000000) {
988 puts ("FMT7 add extent: add new extent");
995 /* BUG: no free extent found */
996 puts ("BUG: no free FMT7 DSCB extent found!\nexiting...");
1000 for (i=0; i<16; i++) {
1002 ext = &f7->DS7EXTNT[i];
1004 ext = &f7->DS7ADEXT[i-5];
1006 if ((ext->a + ext->b) == 0x00000000)
1009 if ((ext->b + 1) == tmp->a) {
1010 /* this extent precedes the new one */
1012 bzero(tmp, sizeof(ds7ext_t));
1016 puts ("FMT7 add extent: "
1017 "merge with predecessor");
1023 if (ext->a == (tmp->b + 1)) {
1024 /* this extent succeeds the new one */
1026 bzero(tmp, sizeof(ds7ext_t));
1030 puts ("FMT7 add extent: merge with successor");
1039 * remove a free space extent description from the VTOC FMT7 DSCB
1042 vtoc_update_format7_label_del (format7_label_t *f7, int verbose,
1043 u_int32_t a, u_int32_t b)
1049 for (i=0; i<16; i++) {
1051 ext = &f7->DS7EXTNT[i];
1053 ext = &f7->DS7ADEXT[i-5];
1055 if ((a == ext->a) && (b == ext->b)) {
1056 /* fills up whole free space gap */
1057 bzero(ext, sizeof(ds7ext_t));
1060 puts ("FMT7 del extent: fills whole gap");
1066 if ((a == ext->a) && (b < ext->b)) {
1067 /* left-bounded in free space gap */
1071 puts ("FMT7 add extent: left-bounded");
1077 if ((a > ext->a) && (b == ext->b)) {
1078 /* right-bounded in free space gap */
1082 puts ("FMT7 add extent: right-bounded");
1088 if ((a > ext->a) && (b < ext->b)) {
1089 /* partition devides free space into 2 pieces */
1090 vtoc_update_format7_label_add(f7, verbose, b+1, ext->b);
1094 puts ("FMT7 add extent: 2 pieces");
1100 if (((a < ext->a) && (b > ext->a)) || ((a < ext->b) && (b > ext->b))) {
1101 puts ("BUG: specified free space extent for deleting "
1102 "doesn't match free space currently shown in "
1103 "FMT7 DSCB!\nexiting...");
1104 printf ("%d %d %d %d\n", a, b, ext->a, ext->b);
1112 puts ("BUG: specified free space extent for "
1113 "deleting not found in FMT7 DSCB!\n"
1119 vtoc_set_freespace(format4_label_t *f4, format5_label_t *f5,
1120 format7_label_t *f7, char ch, int verbose,
1121 u_int32_t start, u_int32_t stop, int cyl, int trk)
1124 if ((cyl * trk) > BIG_DISK_SIZE) {
1126 vtoc_update_format7_label_add(f7, verbose, start, stop);
1128 vtoc_update_format7_label_del(f7, verbose, start, stop);
1130 puts ("BUG: syntax error in vtoc_set_freespace call");
1132 vtoc_reorganize_FMT7_extents (f7);
1134 f4->DS4VTOCI = 0xa0;
1135 f4->DS4EFLVL = 0x07;
1136 vtoc_set_cchhb(&f4->DS4EFPTR, 0x0000, 0x0001, 0x03);
1141 x = (u_int16_t) start;
1142 y = (u_int16_t) ((stop - start + 1) / trk);
1143 z = (u_int8_t) ((stop - start + 1) % trk);
1146 vtoc_update_format5_label_add(f5, verbose, cyl, trk, x, y, z);
1148 vtoc_update_format5_label_del(f5, verbose, cyl, trk, x, y, z);
1150 puts ("BUG: syntax error in vtoc_set_freespace call");
1152 vtoc_reorganize_FMT5_extents (f5);