]> git.pld-linux.org Git - packages/parted.git/blob - parted-dasd.patch
- updated for 1.6.25
[packages/parted.git] / parted-dasd.patch
1 --- parted-1.6.25/include/parted/device.h.orig  2005-10-19 22:13:26.000000000 +0200
2 +++ parted-1.6.25/include/parted/device.h       2005-11-04 10:03:56.934241352 +0100
3 @@ -33,7 +33,8 @@
4         PED_DEVICE_FILE         = 5,
5         PED_DEVICE_ATARAID      = 6,
6         PED_DEVICE_I2O          = 7,
7 -       PED_DEVICE_UBD          = 8
8 +       PED_DEVICE_UBD          = 8,
9 +       PED_DEVICE_DASD         = 9
10  } PedDeviceType;
11  
12  typedef struct _PedDevice PedDevice;
13 diff -ruN --minimal parted-1.6.21.orig/include/parted/disk.h parted-1.6.21/include/parted/disk.h
14 --- parted-1.6.21.orig/include/parted/disk.h    2005-01-04 11:09:50.000000000 -0500
15 +++ parted-1.6.21/include/parted/disk.h 2005-01-21 15:00:40.422628505 -0500
16 @@ -36,7 +36,8 @@
17         PED_PARTITION_LOGICAL           = 0x01,
18         PED_PARTITION_EXTENDED          = 0x02,
19         PED_PARTITION_FREESPACE         = 0x04,
20 -       PED_PARTITION_METADATA          = 0x08
21 +       PED_PARTITION_METADATA          = 0x08,
22 +       PED_PARTITION_PROTECTED         = 0x10
23  } PedPartitionType;
24  
25  typedef enum {
26 diff -ruN --minimal parted-1.6.21.orig/include/parted/linux.h parted-1.6.21/include/parted/linux.h
27 --- parted-1.6.21.orig/include/parted/linux.h   2001-12-26 19:26:08.000000000 -0500
28 +++ parted-1.6.21/include/parted/linux.h        2005-01-21 15:00:40.422628505 -0500
29 @@ -29,6 +29,11 @@
30  
31  struct _LinuxSpecific {
32         int     fd;
33 +#if defined(__s390__) || defined(__s390x__)
34 +       unsigned int    real_sector_size;
35 +        /* IBM internal dasd structure (i guess ;), required. */
36 +        struct fdasd_anchor  *anchor;
37 +#endif
38  };
39  
40  extern PedArchitecture ped_linux_arch;
41 diff -ruN --minimal parted-1.6.21.orig/libparted/Makefile.am parted-1.6.21/libparted/Makefile.am
42 --- parted-1.6.21.orig/libparted/Makefile.am    2005-01-05 18:16:52.000000000 -0500
43 +++ parted-1.6.21/libparted/Makefile.am 2005-01-21 15:00:40.423628479 -0500
44 @@ -35,6 +35,11 @@
45                         timer.c                 \
46                         disk.c                  \
47                         disk_bsd.c              \
48 +                       disk_dasd.c             \
49 +                       fdasd.c                 \
50 +                       fdasd.h                 \
51 +                       vtoc.c                  \
52 +                       vtoc.h                  \
53                         disk_dos.c              \
54                         disk_gpt.c              \
55                         disk_loop.c             \
56 diff -ruN --minimal parted-1.6.21.orig/libparted/disk_dasd.c parted-1.6.21/libparted/disk_dasd.c
57 --- parted-1.6.21.orig/libparted/disk_dasd.c    1969-12-31 19:00:00.000000000 -0500
58 +++ parted-1.6.21/libparted/disk_dasd.c 2005-01-21 15:00:40.425628426 -0500
59 @@ -0,0 +1,882 @@
60 +/* -*- Mode: c; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
61 +
62 +    libparted - a library for manipulating disk partitions
63 +    Copyright (C) 2000, 2001 Free Software Foundation, Inc.
64 +
65 +    This program is free software; you can redistribute it and/or modify
66 +    it under the terms of the GNU General Public License as published by
67 +    the Free Software Foundation; either version 2 of the License, or
68 +    (at your option) any later version.
69 +
70 +    This program is distributed in the hope that it will be useful,
71 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
72 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
73 +    GNU General Public License for more details.
74 +
75 +    You should have received a copy of the GNU General Public License
76 +    along with this program; if not, write to the Free Software
77 +    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
78 +
79 +    Contributor:  Phil Knirsch <phil@redhat.de>
80 +                  Harald Hoyer <harald@redhat.de>
81 +*/
82 +
83 +#include "config.h"
84 +
85 +#include <string.h>
86 +#include <stdio.h>
87 +#include <errno.h>
88 +#include <ctype.h>
89 +#include <time.h>
90 +#include <fcntl.h>
91 +#include <unistd.h>
92 +
93 +#include <sys/stat.h>
94 +#include <sys/ioctl.h>
95 +#include <parted/parted.h>
96 +#include <parted/endian.h>
97 +#include <parted/debug.h>
98 +
99 +#include "vtoc.h"
100 +#include "fdasd.h"
101 +#include <parted/linux.h>
102 +
103 +#include <libintl.h>
104 +#if ENABLE_NLS
105 +#  define _(String) dgettext (PACKAGE, String)
106 +#else
107 +#  define _(String) (String)
108 +#endif /* ENABLE_NLS */
109 +
110 +
111 +#define PARTITION_LINUX_SWAP   0x82
112 +#define PARTITION_LINUX                0x83
113 +#define PARTITION_LINUX_EXT    0x85
114 +#define PARTITION_LINUX_LVM    0x8e
115 +#define PARTITION_LINUX_RAID   0xfd
116 +#define PARTITION_LINUX_LVM_OLD 0xfe
117 +
118 +
119 +extern void ped_disk_dasd_init ();
120 +extern void ped_disk_dasd_done ();
121 +
122 +
123 +#define DASD_NAME "dasd"
124 +
125 +typedef struct {
126 +       int type;
127 +        int system;
128 +       int             raid;
129 +       int             lvm;
130 +  void            *part_info;
131 +} DasdPartitionData;
132 +
133 +typedef struct {
134 +        unsigned int   real_sector_size;
135 +        unsigned int   format_type;
136 +        /* IBM internal dasd structure (i guess ;), required. */
137 +        struct fdasd_anchor  *anchor;
138 +} DasdDiskSpecific;
139 +
140 +static int dasd_probe (PedDevice *dev);
141 +static int dasd_clobber (PedDevice* dev);
142 +static int dasd_read (PedDisk* disk);
143 +static int dasd_write (PedDisk* disk);
144 +
145 +static PedPartition* dasd_partition_new (
146 +       const PedDisk* disk, PedPartitionType part_type,
147 +               const PedFileSystemType* fs_type, PedSector start, PedSector end);
148 +static void dasd_partition_destroy (PedPartition* part);
149 +static int dasd_partition_set_flag (
150 +       PedPartition* part, PedPartitionFlag flag, int state);
151 +static int dasd_partition_get_flag (
152 +       const PedPartition* part, PedPartitionFlag flag);
153 +static int dasd_partition_is_flag_available (
154 +       const PedPartition* part,
155 +       PedPartitionFlag flag);
156 +static int dasd_partition_align (PedPartition* part,
157 +                                 const PedConstraint* constraint);
158 +static int dasd_partition_enumerate (PedPartition* part);
159 +static int dasd_get_max_primary_partition_count (const PedDisk* disk);
160 +
161 +static PedDisk* dasd_alloc (PedDevice* dev);
162 +static PedDisk* dasd_duplicate (const PedDisk* disk);
163 +static void dasd_free (PedDisk* disk);
164 +static int dasd_partition_set_system (PedPartition* part, const PedFileSystemType* fs_type);
165 +static int dasd_alloc_metadata (PedDisk* disk);
166 +
167 +static PedDiskOps dasd_disk_ops = {
168 +       probe:                  dasd_probe,
169 +       clobber:                dasd_clobber,
170 +       read:                   dasd_read,
171 +       write:                  dasd_write,
172 +
173 +       alloc: dasd_alloc,
174 +       duplicate: dasd_duplicate,
175 +       free: dasd_free,
176 +       partition_set_system:   dasd_partition_set_system,
177 +       
178 +       partition_new:          dasd_partition_new,
179 +       partition_destroy:      dasd_partition_destroy,
180 +       partition_set_flag:     dasd_partition_set_flag,
181 +       partition_get_flag:     dasd_partition_get_flag,
182 +       partition_is_flag_available:    dasd_partition_is_flag_available,
183 +       partition_set_name:     NULL,
184 +       partition_get_name:     NULL,
185 +       partition_align:        dasd_partition_align,
186 +       partition_enumerate:    dasd_partition_enumerate,
187 +
188 +       alloc_metadata:         dasd_alloc_metadata,
189 +       get_max_primary_partition_count:
190 +        dasd_get_max_primary_partition_count,
191 +
192 +        partition_duplicate: NULL
193 +};
194 +
195 +static PedDiskType dasd_disk_type = {
196 +       next:           NULL,
197 +       name:           "dasd",
198 +       ops:            &dasd_disk_ops,
199 +       features:       0
200 +};
201 +
202 +static PedDisk*
203 +dasd_alloc (PedDevice* dev)
204 +{
205 +       PedDisk* disk;
206 +       LinuxSpecific* arch_specific;
207 +        DasdDiskSpecific *disk_specific;
208 +
209 +       PED_ASSERT (dev != NULL, return NULL);
210 +
211 +        arch_specific = LINUX_SPECIFIC (dev);
212 +        disk = _ped_disk_alloc (dev, &dasd_disk_type);
213 +       if (!disk)
214 +                return NULL;
215 +        
216 +       disk->disk_specific = disk_specific = ped_malloc (sizeof (DasdDiskSpecific));
217 +       if (!disk->disk_specific) {
218 +                ped_free (disk);
219 +                return NULL;
220 +        }
221 +        
222 +        /* because we lie to parted we have to compensate with the
223 +           real sector size.  Record that now. */
224 +       if (ioctl (arch_specific->fd, BLKSSZGET,
225 +                   &disk_specific->real_sector_size) == -1) {
226 +                ped_exception_throw (PED_EXCEPTION_ERROR,
227 +                                     PED_EXCEPTION_CANCEL,
228 +                                     _("Unable to determine the block "
229 +                                       "size of this dasd"));
230 +                ped_free (disk_specific);
231 +                ped_free (disk);
232 +                return NULL;
233 +        }
234 +
235 +        return disk;
236 +}
237 +
238 +static PedDisk*
239 +dasd_duplicate (const PedDisk* disk)
240 +{
241 +       PedDisk*        new_disk;
242 +
243 +       new_disk = ped_disk_new_fresh (disk->dev, &dasd_disk_type);
244 +       if (!new_disk)
245 +               return NULL;
246 +       new_disk->disk_specific = NULL;
247 +       return new_disk;
248 +}
249 +
250 +static void
251 +dasd_free (PedDisk* disk)
252 +{
253 +       PED_ASSERT (disk != NULL, return);
254 +
255 +       _ped_disk_free (disk);
256 +}
257 +
258 +
259 +void
260 +ped_disk_dasd_init ()
261 +{
262 +       ped_register_disk_type (&dasd_disk_type);
263 +}
264 +
265 +void
266 +ped_disk_dasd_done ()
267 +{
268 +       ped_unregister_disk_type (&dasd_disk_type);
269 +}
270 +
271 +static int
272 +dasd_probe (PedDevice *dev)
273 +{
274 +        char *errstr = 0;
275 +       LinuxSpecific* arch_specific;
276 +        struct fdasd_anchor anchor;
277 +
278 +       PED_ASSERT (dev != NULL, return 0);
279 +       PED_ASSERT ((dev->type == PED_DEVICE_DASD || dev->type == PED_DEVICE_VIODASD), return 0);
280 +
281 +        arch_specific = LINUX_SPECIFIC (dev);
282 +
283 +        /* add partition test here */
284 +        fdasd_initialize_anchor(&anchor);
285 +
286 +        fdasd_get_geometry(&anchor, arch_specific->fd);
287 +
288 +        fdasd_check_api_version(&anchor, arch_specific->fd);
289 +
290 +        if (fdasd_check_volume(&anchor, arch_specific->fd))
291 +                goto error_cleanup;
292 +
293 +        fdasd_cleanup(&anchor);
294 +
295 +       return 1;
296 +error_cleanup:
297 +        fdasd_cleanup(&anchor);
298 +error:
299 +        ped_exception_throw ( PED_EXCEPTION_ERROR,
300 +                              PED_EXCEPTION_IGNORE_CANCEL,
301 +                              errstr );
302 +
303 +        return 0;
304 +}
305 +
306 +
307 +static int
308 +dasd_clobber (PedDevice* dev)
309 +{
310 +        int i;
311 +        LinuxSpecific* arch_specific;
312 +        struct fdasd_anchor anchor;
313 +
314 +       PED_ASSERT (dev != NULL, return 0);
315 +
316 +       arch_specific = LINUX_SPECIFIC (dev);
317 +
318 +        fdasd_initialize_anchor(&anchor);
319 +        fdasd_get_geometry(&anchor, arch_specific->fd);
320 +
321 +        fdasd_recreate_vtoc(&anchor);
322 +        fdasd_write_labels(&anchor, arch_specific->fd);
323 +
324 +       return 1;
325 + error:
326 +        return 0;
327 +}
328 +
329 +static int
330 +dasd_read (PedDisk* disk)
331 +{
332 +       int i, s;
333 +       char str[20];
334 +        PedDevice* dev;
335 +       PedPartition* part;
336 +       PedSector start, end;
337 +       PedConstraint* constraint_exact;
338 +       partition_info_t *p;
339 +       LinuxSpecific*  arch_specific;
340 +        DasdDiskSpecific* disk_specific;
341 +
342 +        PDEBUG;
343 +
344 +       PED_ASSERT (disk != NULL, return 0);
345 +        PDEBUG;
346 +       PED_ASSERT (disk->dev != NULL, return 0);
347 +        PDEBUG;
348 +
349 +        dev = disk->dev;
350 +
351 +        arch_specific = LINUX_SPECIFIC (dev);
352 +        disk_specific = disk->disk_specific;
353 +
354 +        /* XXX why are we re-creating the anchor? */
355 +        if (disk_specific->anchor) {
356 +                fdasd_cleanup(disk_specific->anchor);
357 +                free(disk_specific->anchor);
358 +        }
359 +
360 +        disk_specific->anchor = ped_malloc(sizeof(fdasd_anchor_t));
361 +
362 +        PDEBUG;
363 +
364 +        fdasd_initialize_anchor(disk_specific->anchor);
365 +
366 +        fdasd_get_geometry(disk_specific->anchor, arch_specific->fd);
367 +
368 +       /* check dasd for labels and vtoc */
369 +        if (fdasd_check_volume(disk_specific->anchor, arch_specific->fd))
370 +               goto error_close_dev;
371 +
372 +       if ((disk_specific->anchor->geo.cylinders * disk_specific->anchor->geo.heads) > BIG_DISK_SIZE)
373 +               disk_specific->anchor->big_disk++;
374 +
375 +       ped_disk_delete_all (disk);
376 +
377 +       if (strncmp(disk_specific->anchor->vlabel->volkey, vtoc_ebcdic_enc ("LNX1", str, 4), 4) == 0)
378 +       {
379 +                DasdPartitionData*             dasd_data;
380 +
381 +               /* LDL format, old one */
382 +               disk_specific->format_type = 1;
383 +               start = 24;
384 +               end = (long long)(long long) disk_specific->anchor->geo.cylinders
385 +                     * (long long)disk_specific->anchor->geo.heads
386 +                     * (long long)disk->dev->hw_geom.sectors
387 +                     * (long long)disk_specific->real_sector_size
388 +                     / (long long)disk->dev->sector_size - 1;
389 +               part = ped_partition_new (disk, PED_PARTITION_PROTECTED, NULL, start, end);
390 +               if (!part)
391 +                       goto error_close_dev;
392 +               part->num = 1;
393 +               part->fs_type = ped_file_system_probe (&part->geom);
394 +                dasd_data = part->disk_specific;
395 +               dasd_data->raid = 0;
396 +               dasd_data->lvm = 0;
397 +                dasd_data->type = 0;
398 +               if (!ped_disk_add_partition (disk, part, NULL))
399 +                       goto error_close_dev;
400 +               return 1;
401 +       }
402 +
403 +       /* CDL format, newer */
404 +       disk_specific->format_type = 2;
405 +
406 +        p = disk_specific->anchor->first;
407 +        PDEBUG;
408 +
409 +       for (i = 1 ; i <= USABLE_PARTITIONS; i++)
410 +       {
411 +                char *ch = p->f1->DS1DSNAM;
412 +                DasdPartitionData*             dasd_data;
413 +
414 +
415 +                if (p->used != 0x01)
416 +                        continue;
417 +
418 +        PDEBUG;
419 +
420 +               start = (long long)(long long) p->start_trk 
421 +                        * (long long) disk->dev->hw_geom.sectors 
422 +                        * (long long) disk_specific->real_sector_size
423 +                        / (long long) disk->dev->sector_size
424 +                        ;
425 +               end   = (long long)((long long) p->end_trk + 1) 
426 +                        * (long long) disk->dev->hw_geom.sectors
427 +                        * (long long) disk_specific->real_sector_size 
428 +                        / (long long) disk->dev->sector_size 
429 +                        - 1;
430 +               part = ped_partition_new (disk, 0, NULL, start, end);
431 +        PDEBUG;
432 +
433 +               if (!part)
434 +                       goto error_close_dev;
435 +
436 +        PDEBUG;
437 +
438 +               part->num = i;
439 +               part->fs_type = ped_file_system_probe (&part->geom);
440 +
441 +                vtoc_ebcdic_dec(p->f1->DS1DSNAM, p->f1->DS1DSNAM, 44);
442 +                ch = strstr(p->f1->DS1DSNAM, "PART");
443 +                if (ch != NULL) {
444 +                        strncpy(str, ch+9, 6);
445 +                        str[6] = '\0';
446 +                        /*fprintf(stderr, "f1 label contains: >%s<\n", p->f1->DS1DSNAM);
447 +                } else {
448 +                        strcpy(str, "error");
449 +                        fprintf(stderr, "Error, f1 label contains: >%s<\n", p->f1->DS1DSNAM);
450 +                       */
451 +                }
452 +
453 +                dasd_data = part->disk_specific;
454 +
455 +                if(strncmp(PART_TYPE_RAID, str, 6) == 0)
456 +                       ped_partition_set_flag(part, PED_PARTITION_RAID, 1);
457 +                else
458 +                       ped_partition_set_flag(part, PED_PARTITION_RAID, 0);
459 +
460 +                if(strncmp(PART_TYPE_LVM, str, 6) == 0)
461 +                       ped_partition_set_flag(part, PED_PARTITION_LVM, 1);
462 +                else
463 +                       ped_partition_set_flag(part, PED_PARTITION_LVM, 0);
464 +
465 +                if(strncmp(PART_TYPE_SWAP, str, 6) == 0) {
466 +                        dasd_data->system = PARTITION_LINUX_SWAP;
467 +                        PDEBUG;
468 +                }
469 +
470 +                vtoc_ebcdic_enc(p->f1->DS1DSNAM, p->f1->DS1DSNAM, 44);
471 +
472 +                dasd_data->part_info = (void *) p;
473 +                dasd_data->type = 0;
474 +
475 +               constraint_exact = ped_constraint_exact (&part->geom);
476 +                if(!constraint_exact) 
477 +                        goto error_close_dev;
478 +               if (!ped_disk_add_partition (disk, part, constraint_exact))
479 +                       goto error_close_dev;
480 +               ped_constraint_destroy (constraint_exact);
481 +
482 +                if (p->fspace_trk > 0) {
483 +                        start = (long long)((long long) p->end_trk + 1)
484 +                                * (long long) disk->dev->hw_geom.sectors 
485 +                                * (long long) disk_specific->real_sector_size
486 +                                / (long long) disk->dev->sector_size
487 +                                ;
488 +                        end   = (long long)((long long) p->end_trk + 1 + p->fspace_trk) 
489 +                                * (long long) disk->dev->hw_geom.sectors
490 +                                * (long long) disk_specific->real_sector_size 
491 +                                / (long long) disk->dev->sector_size 
492 +                                - 1;
493 +                        part = ped_partition_new (disk, 0, NULL, start, end);
494 +                        if (!part)
495 +                                goto error_close_dev;
496 +                        part->type = PED_PARTITION_FREESPACE;
497 +                        constraint_exact = ped_constraint_exact (&part->geom);
498 +                        if(!constraint_exact) 
499 +                                goto error_close_dev;
500 +                        if (!ped_disk_add_partition (disk, part, constraint_exact))
501 +                                goto error_close_dev;
502 +                        ped_constraint_destroy (constraint_exact);
503 +                }
504 +
505 +               p = p->next;
506 +       }
507 +
508 +        PDEBUG;
509 +       return 1;
510 +
511 +error_close_dev:
512 +        PDEBUG;
513 +       return 0;
514 +}
515 +
516 +static int
517 +dasd_update_type(PedDisk* disk)
518 +{
519 +       PedPartition*           part;
520 +        LinuxSpecific* arch_specific;
521 +        DasdDiskSpecific* disk_specific;
522 +        char *sys = NULL;
523 +
524 +       arch_specific = LINUX_SPECIFIC (disk->dev);
525 +        disk_specific = disk->disk_specific;
526 +
527 +        PDEBUG;
528 +
529 +       for (part = ped_disk_next_partition (disk, NULL); part;
530 +            part = ped_disk_next_partition (disk, part)) {
531 +                partition_info_t *p;
532 +                char *ch = NULL;
533 +                DasdPartitionData*             dasd_data;
534 +
535 +                PDEBUG;
536 +
537 +                if(part->type & PED_PARTITION_FREESPACE
538 +                   || part->type & PED_PARTITION_METADATA) {
539 +                        continue;
540 +                }
541 +
542 +                PDEBUG;
543 +
544 +                dasd_data = part->disk_specific;
545 +                p = dasd_data->part_info;
546 +                if (!p ) {
547 +                        PDEBUG;
548 +                        continue;
549 +                }
550 +                vtoc_ebcdic_dec(p->f1->DS1DSNAM, p->f1->DS1DSNAM, 44);
551 +                ch = strstr(p->f1->DS1DSNAM, "PART");
552 +                /*fprintf(stderr, "f1 label contains: >%s<\n", p->f1->DS1DSNAM);*/
553 +
554 +                PDEBUG;
555 +                if (ch == NULL) {
556 +                        vtoc_ebcdic_enc(p->f1->DS1DSNAM, p->f1->DS1DSNAM, 44);
557 +                        PDEBUG;
558 +                        continue;
559 +                }
560 +
561 +                ch += 9;
562 +                                
563 +                switch(dasd_data->system) {
564 +                case PARTITION_LINUX_LVM:
565 +                        PDEBUG;
566 +                        strncpy(ch, PART_TYPE_LVM, 6);
567 +                        break;
568 +                case PARTITION_LINUX_RAID:
569 +                        PDEBUG;
570 +                        strncpy(ch, PART_TYPE_RAID, 6);
571 +                        break;
572 +                case PARTITION_LINUX:
573 +                        PDEBUG;
574 +                        strncpy(ch, PART_TYPE_NATIVE, 6);
575 +                        break;
576 +                case PARTITION_LINUX_SWAP:
577 +                        PDEBUG;
578 +                        strncpy(ch, PART_TYPE_SWAP, 6);
579 +                        break;
580 +                default:
581 +                        PDEBUG;
582 +                        strncpy(ch, PART_TYPE_NATIVE, 6);
583 +                        break;
584 +                }
585 +                disk_specific->anchor->vtoc_changed++;
586 +
587 +                vtoc_ebcdic_enc(p->f1->DS1DSNAM, p->f1->DS1DSNAM, 44);
588 +        }
589 +        return 1;
590 +}
591 +        
592 +static int
593 +dasd_write (PedDisk* disk)
594 +{
595 +       DasdPartitionData*      dasd_data;
596 +       PedPartition*           part;
597 +       int                     i;
598 +        int ret;
599 +       partition_info_t *p;
600 +        LinuxSpecific* arch_specific;
601 +        DasdDiskSpecific* disk_specific;
602 +       PED_ASSERT (disk != NULL, return 0);
603 +       PED_ASSERT (disk->dev != NULL, return 0);
604 +
605 +       arch_specific = LINUX_SPECIFIC (disk->dev);
606 +        disk_specific = disk->disk_specific;
607 +
608 +        PDEBUG;
609 +
610 +       /* If formated in LDL, don't write anything. */
611 +       if (disk_specific->format_type == 1)
612 +               return 1;
613 +
614 +        /* XXX re-initialize anchor? */
615 +        fdasd_initialize_anchor(disk_specific->anchor);
616 +        fdasd_get_geometry(disk_specific->anchor, arch_specific->fd);
617 +
618 +       /* check dasd for labels and vtoc */
619 +        if (fdasd_check_volume(disk_specific->anchor, arch_specific->fd))
620 +               goto error;
621 +
622 +       if ((disk_specific->anchor->geo.cylinders * disk_specific->anchor->geo.heads) > BIG_DISK_SIZE)
623 +               disk_specific->anchor->big_disk++;
624 +
625 +        fdasd_recreate_vtoc(disk_specific->anchor);
626 +
627 +       for (i = 1; i <= USABLE_PARTITIONS; i++) {
628 +                unsigned int start, stop;
629 +                int type;
630 +
631 +                PDEBUG;
632 +               part = ped_disk_get_partition (disk, i);
633 +               if (!part)
634 +                       continue;
635 +
636 +                PDEBUG;
637 +
638 +                start = part->geom.start * disk->dev->sector_size 
639 +                        / disk_specific->real_sector_size / disk->dev->hw_geom.sectors;
640 +                stop = (part->geom.end + 1) 
641 +                        * disk->dev->sector_size / disk_specific->real_sector_size
642 +                        / disk->dev->hw_geom.sectors - 1;
643 +
644 +                PDEBUG;
645 +                dasd_data = part->disk_specific;
646 +                
647 +                type = dasd_data->type;
648 +                PDEBUG;
649 +                /*fprintf(stderr, "Partition %d  %ld - %ld \t", i, part->geom.start, part->geom.end);
650 +                fprintf(stderr, "Partition %d  %ld - %ld \n", i, start, stop);
651 +               */
652 +
653 +                p = fdasd_add_partition(disk_specific->anchor, start, stop);
654 +                if(!p) {
655 +                        PDEBUG;
656 +                        return 0;
657 +                }
658 +                dasd_data->part_info = (void *) p;
659 +               p->type = dasd_data->system;
660 +       }
661 +        PDEBUG;
662 +
663 +        if(!fdasd_prepare_labels(disk_specific->anchor, arch_specific->fd))
664 +                return 0;
665 +
666 +        dasd_update_type(disk);
667 +        PDEBUG;
668 +
669 +        if(!fdasd_write_labels(disk_specific->anchor, arch_specific->fd))
670 +                return 0;
671 +
672 +        return 1;
673 + error:
674 +        PDEBUG;
675 +       return 0;
676 +}
677 +
678 +static PedPartition*
679 +dasd_partition_new (const PedDisk* disk, PedPartitionType part_type,
680 +                  const PedFileSystemType* fs_type,
681 +                  PedSector start, PedSector end)
682 +{
683 +       PedPartition*           part;
684 +
685 +       part = _ped_partition_alloc (disk, part_type, fs_type, start, end);
686 +       if (!part)
687 +               goto error;
688 +
689 +        part->disk_specific = ped_malloc (sizeof (DasdPartitionData));
690 +       return part;
691 +
692 +error:
693 +       return 0;
694 +}
695 +
696 +
697 +static void
698 +dasd_partition_destroy (PedPartition* part)
699 +{
700 +       PED_ASSERT (part != NULL, return);
701 +
702 +       if (ped_partition_is_active (part))
703 +               ped_free (part->disk_specific);
704 +       ped_free (part);
705 +}
706 +
707 +
708 +static int
709 +dasd_partition_set_flag (PedPartition* part, PedPartitionFlag flag, int state)
710 +{
711 +       PedDisk*                        disk;
712 +       PedPartition*                   walk;
713 +       DasdPartitionData*              dasd_data;
714 +       const PedFileSystemType*        fs_type;
715 +
716 +       PED_ASSERT (part != NULL, return 0);
717 +       PED_ASSERT (part->disk_specific != NULL, return 0);
718 +       dasd_data = part->disk_specific;
719 +
720 +       switch (flag) {
721 +       case PED_PARTITION_RAID:
722 +               if (state) {
723 +                       dasd_data->lvm = 0;
724 +               }
725 +               dasd_data->raid = state;
726 +               return ped_partition_set_system (part, part->fs_type);
727 +       case PED_PARTITION_LVM:
728 +               if (state) {
729 +                       dasd_data->raid = 0;
730 +               }
731 +               dasd_data->lvm = state;
732 +               return ped_partition_set_system (part, part->fs_type);
733 +       default:
734 +               return 0;
735 +       }
736 +}
737 +
738 +
739 +static int
740 +dasd_partition_get_flag (const PedPartition* part, PedPartitionFlag flag)
741 +{
742 +       DasdPartitionData*      dasd_data;
743 +
744 +       PED_ASSERT (part != NULL, return 0);
745 +       PED_ASSERT (part->disk_specific != NULL, return 0);
746 +       dasd_data = part->disk_specific;
747 +
748 +       switch (flag) {
749 +       case PED_PARTITION_RAID:
750 +               return dasd_data->raid;
751 +
752 +       case PED_PARTITION_LVM:
753 +               return dasd_data->lvm;
754 +
755 +       default:
756 +               return 0;
757 +       }
758 +}
759 +
760 +static int
761 +dasd_partition_is_flag_available (const PedPartition* part,
762 +                                PedPartitionFlag flag)
763 +{
764 +       switch (flag) {
765 +       case PED_PARTITION_RAID:
766 +               return 1;
767 +
768 +       case PED_PARTITION_LVM:
769 +               return 1;
770 +
771 +       default:
772 +               return 0;
773 +       }
774 +}
775 +
776 +
777 +static int
778 +dasd_get_max_primary_partition_count (const PedDisk* disk)
779 +{
780 +        DasdDiskSpecific* disk_specific;
781 +
782 +       disk_specific = disk->disk_specific;
783 +       /* If formated in LDL, maximum partition number is 1 */
784 +       if (disk_specific->format_type == 1)
785 +               return 1;
786 +
787 +       return USABLE_PARTITIONS;
788 +}
789 +
790 +static PedConstraint*
791 +_primary_constraint (PedDisk* disk)
792 +{
793 +       PedAlignment    start_align;
794 +       PedAlignment    end_align;
795 +       PedGeometry     max_geom;
796 +       PedSector       sector_size;
797 +        LinuxSpecific*  arch_specific;
798 +        DasdDiskSpecific* disk_specific;
799 +
800 +        PDEBUG;
801 +
802 +        arch_specific = LINUX_SPECIFIC (disk->dev);
803 +        disk_specific = disk->disk_specific;
804 +       sector_size = disk_specific->real_sector_size / disk->dev->sector_size;
805 +
806 +       if (!ped_alignment_init (&start_align, 0, disk->dev->hw_geom.sectors * sector_size))
807 +               return NULL;
808 +       if (!ped_alignment_init (&end_align, -1, disk->dev->hw_geom.sectors * sector_size))
809 +               return NULL;
810 +       if (!ped_geometry_init (&max_geom, disk->dev, 0, disk->dev->length))
811 +               return NULL;
812 +
813 +       return ped_constraint_new (&start_align, &end_align, &max_geom,
814 +                                  &max_geom, 1, disk->dev->length);
815 +}
816 +
817 +static int
818 +dasd_partition_align (PedPartition* part, const PedConstraint* constraint)
819 +{
820 +        DasdDiskSpecific* disk_specific;
821 +
822 +       PED_ASSERT (part != NULL, return 0);
823 +
824 +       disk_specific = part->disk->disk_specific;
825 +       /* If formated in LDL, ignore metadata partition */
826 +       if (disk_specific->format_type == 1)
827 +               return 1;
828 +
829 +       if (_ped_partition_attempt_align (part, constraint,
830 +                                         _primary_constraint (part->disk)))
831 +               return 1;
832 +
833 +#ifndef DISCOVER_ONLY
834 +       ped_exception_throw (
835 +               PED_EXCEPTION_ERROR,
836 +               PED_EXCEPTION_CANCEL,
837 +               _("Unable to satisfy all constraints on the partition."));
838 +#endif
839 +       return 0;
840 +}
841 +
842 +
843 +static int
844 +dasd_partition_enumerate (PedPartition* part)
845 +{
846 +       int i;
847 +       PedPartition* p;
848 +       
849 +       /* never change the partition numbers */
850 +       if (part->num != -1)
851 +               return 1;
852 +       for (i = 1; i <= USABLE_PARTITIONS; i++) {
853 +               p = ped_disk_get_partition (part->disk, i);
854 +               if (!p) {
855 +                       part->num = i;
856 +                       return 1;
857 +               }
858 +       }
859 +
860 +       /* failed to allocate a number */
861 +       ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
862 +                            _("Unable to allocate a dasd disklabel slot"));
863 +       return 0;
864 +}
865 +
866 +static int
867 +dasd_partition_set_system (PedPartition* part,
868 +                           const PedFileSystemType* fs_type)
869 +{
870 +       DasdPartitionData* dasd_data = part->disk_specific;
871 +       PedSector cyl_size = part->disk->dev->hw_geom.sectors * part->disk->dev->hw_geom.heads;
872 +
873 +        PDEBUG;
874 +
875 +       part->fs_type = fs_type;
876 +
877 +       if (dasd_data->lvm) {
878 +               dasd_data->system = PARTITION_LINUX_LVM;
879 +        PDEBUG;
880 +               return 1;
881 +       }
882 +       if (dasd_data->raid) {
883 +               dasd_data->system = PARTITION_LINUX_RAID;
884 +        PDEBUG;
885 +               return 1;
886 +       }
887 +       if (!fs_type) {
888 +               dasd_data->system = PARTITION_LINUX;
889 +        PDEBUG;
890 +       } else if (!strcmp (fs_type->name, "linux-swap")) {
891 +               dasd_data->system = PARTITION_LINUX_SWAP;
892 +        PDEBUG;
893 +        } else {
894 +               dasd_data->system = PARTITION_LINUX;
895 +        PDEBUG;
896 +        }
897 +
898 +       return 1;
899 +}
900 +
901 +static int
902 +dasd_alloc_metadata (PedDisk* disk)
903 +{
904 +       PedPartition*           new_part;
905 +       PedConstraint*          constraint_any = NULL;
906 +        PedSector              vtoc_end;
907 +        LinuxSpecific*         arch_specific;
908 +        DasdDiskSpecific*      disk_specific;
909 +
910 +       PED_ASSERT (disk != NULL, goto error);
911 +       PED_ASSERT (disk->dev != NULL, goto error);
912 +
913 +       arch_specific = LINUX_SPECIFIC (disk->dev);
914 +        disk_specific = disk->disk_specific;
915 +
916 +       constraint_any = ped_constraint_any (disk->dev);
917 +
918 +       /* If formated in LDL, the real partition starts at sector 24. */
919 +       if (disk_specific->format_type == 1)
920 +               vtoc_end = 23;
921 +        else
922 +        /* Mark the start of the disk as metadata. */
923 +               vtoc_end = (FIRST_USABLE_TRK * (long long) disk->dev->hw_geom.sectors 
924 +                               * (long long) disk_specific->real_sector_size
925 +                               / (long long) disk->dev->sector_size) - 1;
926 +       new_part = ped_partition_new (disk, PED_PARTITION_METADATA, NULL,
927 +                                      0, vtoc_end);
928 +       if (!new_part)
929 +               goto error;
930 +
931 +       if (!ped_disk_add_partition (disk, new_part, constraint_any)) {
932 +               ped_partition_destroy (new_part);
933 +               goto error;
934 +       }
935 +
936 +       ped_constraint_destroy (constraint_any);
937 +       return 1;
938 +error:
939 +       ped_constraint_destroy (constraint_any);
940 +       return 0;
941 +}
942 diff -ruN --minimal parted-1.6.21.orig/libparted/fdasd.c parted-1.6.21/libparted/fdasd.c
943 --- parted-1.6.21.orig/libparted/fdasd.c        1969-12-31 19:00:00.000000000 -0500
944 +++ parted-1.6.21/libparted/fdasd.c     2005-01-21 15:00:40.428628348 -0500
945 @@ -0,0 +1,1302 @@
946 +/*
947 + * File...........: arch/s390/tools/fdasd.c
948 + * Author(s)......: Volker Sameske <sameske@de.ibm.com>
949 + * Bugreports.to..: <Linux390@de.ibm.com>
950 + * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 2001
951 + *
952 + * History of changes (starts March 2001)
953 + * 2001-04-11 possibility to change volume serial added
954 + *            possibility to change partition type added
955 + *            some changes to DS4HPCHR and DS4DSREC
956 + * 2001-05-03 check for invalid partition numbers added
957 + *            wrong free_space calculation bug fixed
958 + * 2001-06-26 '-a' option added, it is now possible to add a single
959 + *            partition in non-interactive mode
960 + * 2001-06-26 long parameter support added
961 + *           
962 + */
963 +#include "vtoc.h"
964 +#include "fdasd.h"
965 +
966 +#include <parted/parted.h>
967 +
968 +#include <libintl.h>
969 +#if ENABLE_NLS
970 +#  define _(String) dgettext (PACKAGE, String)
971 +#else
972 +#  define _(String) (String)
973 +#endif /* ENABLE_NLS */
974 +
975 +
976 +#define GETARG(x) {int k=strlen(optarg);x=malloc(k);strncpy(x,optarg,k);}
977 +
978 +static int
979 +getpos (fdasd_anchor_t *anc, int dsn)
980 +{
981 +PDEBUG
982 +       return anc->partno[dsn];
983 +}
984 +
985 +static int
986 +getdsn (fdasd_anchor_t *anc, int pos)
987 +{
988 +PDEBUG
989 +       int i;
990 +
991 +       for (i=0; i<USABLE_PARTITIONS; i++)
992 +       {
993 +               if (anc->partno[i] == pos)
994 +                       return i;
995 +       }
996 +
997 +       return -1;
998 +}
999 +
1000 +static void
1001 +setpos (fdasd_anchor_t *anc, int dsn, int pos)
1002 +{
1003 +PDEBUG
1004 +       anc->partno[dsn] = pos;
1005 +}
1006 +
1007 +
1008 +static void
1009 +fdasd_check_volser (char *s, int devno)
1010 +{
1011 +PDEBUG
1012 +  int i, j;
1013 +
1014 +  for (i = 0; i < 6; i++)
1015 +    {
1016 +      if ((s[i] < 0x20) || (s[i] > 0x7a) || ((s[i] >= 0x21) && (s[i] <= 0x22)) ||      /* !"         */
1017 +         ((s[i] >= 0x26) && (s[i] <= 0x2f)) || /* &'()*+,-./ */
1018 +         ((s[i] >= 0x3a) && (s[i] <= 0x3f)) || /* :;<=>?     */
1019 +         ((s[i] >= 0x5b) && (s[i] <= 0x60)))   /* \]^_´     */
1020 +       s[i] = ' ';
1021 +      s[i] = toupper (s[i]);
1022 +    }
1023 +  s[6] = 0x00;
1024 +
1025 +  for (i = 0; i < 6; i++)
1026 +    {
1027 +      if (s[i] == ' ')
1028 +       for (j = i; j < 6; j++)
1029 +         if (s[j] != ' ')
1030 +           {
1031 +             s[i] = s[j];
1032 +             s[j] = ' ';
1033 +             break;
1034 +           }
1035 +    }
1036 +
1037 +  if (s[0] == ' ')
1038 +    {
1039 +      printf ("Usage error, switching to default.\n");
1040 +      sprintf (s, "0X%04x", devno);
1041 +      for (i = 0; i < 6; i++)
1042 +       s[i] = toupper (s[i]);
1043 +    }
1044 +}
1045 +
1046 +/*
1047 + *
1048 + */
1049 +void
1050 +fdasd_cleanup (fdasd_anchor_t *anchor) 
1051 +{
1052 +PDEBUG
1053 +        int i;
1054 +        partition_info_t *p, *q;
1055 +
1056 +        if (anchor == NULL) return;
1057 +
1058 +       if (anchor->f4 != NULL) free(anchor->f4);
1059 +       if (anchor->f5 != NULL) free(anchor->f5);
1060 +       if (anchor->f7 != NULL) free(anchor->f7);
1061 +       if (anchor->vlabel != NULL) free(anchor->vlabel);
1062 +
1063 +       p = anchor->first;
1064 +       if (p == NULL)
1065 +               return;
1066 +
1067 +        for (i=1; i <= USABLE_PARTITIONS; i++) 
1068 +       {
1069 +               if (p == NULL)
1070 +                       return;
1071 +               q = p->next;
1072 +               free(p);
1073 +               p = q;
1074 +       }
1075 +}
1076 +
1077 +
1078 +/*
1079 + *
1080 + */
1081 +static void 
1082 +fdasd_error(fdasd_anchor_t *anc,
1083 +           enum fdasd_failure why,
1084 +           char * str) 
1085 +{
1086 +PDEBUG
1087 +        char    error[2*LINE_LENGTH], *message = error;
1088 +
1089 +       switch (why) 
1090 +       {
1091 +        case unable_to_open_disk:
1092 +               sprintf(error, _("%s open error\n%s\n"), 
1093 +                       FDASD_ERROR, str);
1094 +               break;
1095 +        case unable_to_seek_disk:
1096 +               sprintf(error, _("%s seek error\n%s\n"), 
1097 +                       FDASD_ERROR, str);
1098 +               break;
1099 +        case unable_to_read_disk:
1100 +               sprintf(error, _("%s read error\n%s\n"), 
1101 +                       FDASD_ERROR, str);
1102 +               break;
1103 +        case read_only_disk:
1104 +               sprintf(error, _("%s write error\n%s\n"), 
1105 +                       FDASD_ERROR, str);
1106 +               break;
1107 +        case unable_to_ioctl:
1108 +               sprintf(error, _("%s IOCTL error\n%s\n"), 
1109 +                       FDASD_ERROR, str);
1110 +               break;
1111 +        case api_version_mismatch:
1112 +                sprintf(error, _("%s API version mismatch\n%s\n"),
1113 +                        FDASD_ERROR, str);
1114 +                break;     
1115 +        case wrong_disk_type:
1116 +                sprintf(error, _("%s Unsupported disk type\n%s\n"),
1117 +                        FDASD_ERROR, str);
1118 +                break;           
1119 +        case wrong_disk_format:
1120 +                sprintf(error, _("%s Unsupported disk format\n%s\n"),
1121 +                        FDASD_ERROR, str);
1122 +                break;   
1123 +        case disk_in_use:
1124 +                sprintf(error, _("%s Disk in use\n%s\n"),
1125 +                        FDASD_ERROR, str);
1126 +                break;      
1127 +        case config_syntax_error:
1128 +                sprintf(error, _("%s Config file syntax error\n%s\n"),
1129 +                        FDASD_ERROR, str);
1130 +                break;       
1131 +        case vlabel_corrupted:
1132 +               sprintf(error, _("%s Volume label is corrupted.\n%s\n"), 
1133 +                       FDASD_ERROR, str);
1134 +               break;
1135 +        case dsname_corrupted:
1136 +               sprintf(error, _("%s a data set name is corrupted.\n%s\n"), 
1137 +                       FDASD_ERROR, str);
1138 +               break;
1139 +        case malloc_failed:
1140 +               sprintf(error, _("%s space allocation\n%s\n"),
1141 +                       FDASD_ERROR, str);
1142 +               break;
1143 +        case device_verification_failed:
1144 +               sprintf(error, _("%s device verification failed\n" \
1145 +                       "The specified device is not a valid DASD device\n"),
1146 +                       FDASD_ERROR);
1147 +               break;
1148 +       default: 
1149 +               sprintf(error, _("%s Fatal error\n%s\n"),
1150 +                       FDASD_ERROR, str);
1151 +       }
1152 +
1153 +        ped_exception_throw(PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL, message);
1154 +}
1155 +
1156 +
1157 +/*
1158 + * converts cyl-cyl-head-head-blk to blk
1159 + */
1160 +static unsigned long 
1161 +cchhb2blk (cchhb_t *p, struct fdasd_hd_geometry *geo) 
1162 +{
1163 +PDEBUG
1164 +        return (unsigned long) (p->cc * geo->heads * geo->sectors + 
1165 +                                p->hh * geo->sectors +
1166 +                                p->b);
1167 +}
1168 +
1169 +
1170 +/*
1171 + *
1172 + */
1173 +static char *fdasd_partition_type (char *str) 
1174 +{
1175 +PDEBUG
1176 +       if (strncmp("NATIVE", str, 6) == 0)
1177 +               strcpy(str, "Linux native");
1178 +       else if (strncmp("NEW   ", str, 6) == 0)
1179 +               strcpy(str, "Linux native");
1180 +       else if (strncmp("SWAP  ", str, 6) == 0)
1181 +               strcpy(str, "Linux swap");
1182 +       else if (strncmp("RAID  ", str, 6) == 0)
1183 +               strcpy(str, "Linux Raid");
1184 +       else
1185 +               strcpy(str, "unknown");
1186 +
1187 +       return str;
1188 +}
1189 +
1190 +
1191 +/*
1192 + * initializes the anchor structure and allocates some
1193 + * memory for the labels
1194 + */
1195 +void
1196 +fdasd_initialize_anchor (fdasd_anchor_t * anc) 
1197 +{
1198 +PDEBUG
1199 +        int i;
1200 +       volume_label_t  *v;
1201 +       partition_info_t *p = NULL;
1202 +       partition_info_t *q = NULL;
1203 +
1204 +       anc->devno             = 0;
1205 +       anc->dev_type          = 0;
1206 +       anc->used_partitions   = 0;
1207 +
1208 +       anc->silent            = 0;
1209 +       anc->verbose           = 0;
1210 +       anc->big_disk          = 0;
1211 +       anc->volid_specified   = 0;
1212 +       anc->config_specified  = 0;
1213 +       anc->auto_partition    = 0;
1214 +       anc->devname_specified = 0;
1215 +       anc->print_table       = 0;
1216 +
1217 +       anc->option_reuse      = 0;
1218 +       anc->option_recreate   = 0;
1219 +
1220 +        anc->vlabel_changed    = 0;
1221 +       anc->vtoc_changed      = 0;
1222 +       anc->blksize           = 0;
1223 +       anc->fspace_trk        = 0;
1224 +       anc->label_pos         = 0;
1225 +
1226 +       for (i=0; i<USABLE_PARTITIONS; i++)
1227 +               setpos(anc, i, -1);
1228 +
1229 +       bzero(anc->confdata, sizeof(config_data_t));
1230 +
1231 +       anc->f4 = malloc(sizeof(format4_label_t));
1232 +       if (anc->f4 == NULL) 
1233 +               fdasd_error(anc, malloc_failed, 
1234 +                           "FMT4 DSCB memory allocation failed.");
1235 +
1236 +       anc->f5 = malloc(sizeof(format5_label_t));
1237 +       if (anc->f5 == NULL) 
1238 +               fdasd_error(anc, malloc_failed,
1239 +                           "FMT5 DSCB memory allocation failed.");
1240 +
1241 +       anc->f7 = malloc(sizeof(format7_label_t));
1242 +       if (anc->f7 == NULL) 
1243 +               fdasd_error(anc, malloc_failed,
1244 +                           "FMT7 DSCB memory allocation failed.");
1245 +
1246 +       bzero(anc->f4, sizeof(format4_label_t));
1247 +       bzero(anc->f5, sizeof(format5_label_t));
1248 +       bzero(anc->f7, sizeof(format7_label_t));
1249 +
1250 +       v = malloc(sizeof(volume_label_t));
1251 +       if (v == NULL) 
1252 +               fdasd_error(anc, malloc_failed,
1253 +                           "Volume label memory allocation failed.");
1254 +       bzero(v, sizeof(volume_label_t));
1255 +       anc->vlabel = v;
1256 +
1257 +       for (i=1; i<=USABLE_PARTITIONS; i++) 
1258 +       {
1259 +               p = malloc(sizeof(partition_info_t));
1260 +               if (p == NULL) 
1261 +                       fdasd_error(anc, malloc_failed,
1262 +                                  "Partition info memory allocation failed.");
1263 +               p->used       = 0x00;
1264 +               p->len_trk    = 0;
1265 +               p->start_trk  = 0;
1266 +               p->fspace_trk = 0;
1267 +               p->type       = 0;
1268 +
1269 +               /* add p to double pointered list */
1270 +               if (i == 1) 
1271 +               {
1272 +                       anc->first = p;
1273 +                       p->prev = NULL;
1274 +               } 
1275 +               else if (i == USABLE_PARTITIONS) 
1276 +               {
1277 +                       anc->last = p;
1278 +                       p->next = NULL;
1279 +                       p->prev = q;
1280 +                       q->next = p;
1281 +               } 
1282 +               else 
1283 +               {
1284 +                       p->prev = q;
1285 +                       q->next = p;
1286 +               }
1287 +
1288 +               p->f1 = malloc(sizeof(format1_label_t));
1289 +               if (p->f1 == NULL) 
1290 +                       fdasd_error(anc, malloc_failed,
1291 +                           "FMT1 DSCB memory allocation failed.");
1292 +               bzero(p->f1, sizeof(format1_label_t));
1293 +               
1294 +               q = p;
1295 +       }
1296 +}
1297 +
1298 +
1299 +/*
1300 + * call IOCTL to re-read the partition table
1301 + */
1302 +static void
1303 +fdasd_reread_partition_table (fdasd_anchor_t * anc, int fd)
1304 +{
1305 +PDEBUG
1306 +       char str[LINE_LENGTH];
1307 +       int f;
1308 +
1309 +       if (ioctl (fd, BLKRRPART, NULL) != 0)
1310 +               fdasd_error (anc, unable_to_ioctl, "Error while rereading "
1311 +                               "partition table.\nPlease reboot!");
1312 +}
1313 +
1314 +
1315 +/*
1316 + * writes all changes to dasd
1317 + */
1318 +static void
1319 +fdasd_write_vtoc_labels (fdasd_anchor_t * anc, int fd)
1320 +{ 
1321 +PDEBUG
1322 +       partition_info_t *p;
1323 +       unsigned long b;
1324 +       char dsno[6], s1[7], s2[45], *c1, *c2, *ch;
1325 +       int i = 0, k = 0;
1326 +    
1327 +       b = (cchhb2blk (&anc->vlabel->vtoc, &anc->geo) - 1) * anc->blksize;
1328 +       if (b <= 0)
1329 +               fdasd_error (anc, vlabel_corrupted, "");
1330 +
1331 +       /* write FMT4 DSCB */
1332 +       vtoc_write_label (fd, b, NULL, anc->f4, NULL, NULL);
1333 +
1334 +       /* write FMT5 DSCB */
1335 +       b += anc->blksize;
1336 +       vtoc_write_label (fd, b, NULL, NULL, anc->f5, NULL);
1337 +
1338 +       /* write FMT7 DSCB */
1339 +       if (anc->big_disk)
1340 +       {
1341 +               b += anc->blksize;
1342 +               vtoc_write_label (fd, b, NULL, NULL, NULL, anc->f7);
1343 +       }
1344 +
1345 +       /* loop over all FMT1 DSCBs */
1346 +       p = anc->first;
1347 +       for (i = 0; i < USABLE_PARTITIONS; i++)
1348 +       {
1349 +               b += anc->blksize;
1350 +
1351 +               if (p->used != 0x01)
1352 +               {
1353 +                       vtoc_write_label (fd, b, p->f1, NULL, NULL, NULL);
1354 +                       continue;
1355 +               }
1356 +  
1357 +               strncpy (p->f1->DS1DSSN, anc->vlabel->volid, 6);
1358 +
1359 +               ch = p->f1->DS1DSNAM;
1360 +               vtoc_ebcdic_dec (ch, ch, 44);
1361 +               c1 = ch + 7;
1362 +  
1363 +               if (getdsn (anc, i) > -1)
1364 +               {
1365 +                       /* re-use the existing data set name */
1366 +                       c2 = strchr (c1, '.');
1367 +                       if (c2 != NULL)
1368 +                               strncpy (s2, c2, 31);
1369 +                       else
1370 +                               fdasd_error (anc, dsname_corrupted, "");
1371 +
1372 +                       strncpy (s1, anc->vlabel->volid, 6);
1373 +                       vtoc_ebcdic_dec (s1, s1, 6);
1374 +                       s1[6] = ' ';
1375 +                       strncpy (c1, s1, 7);
1376 +                       c1 = strchr (ch, ' ');
1377 +                       strncpy (c1, s2, 31);
1378 +               }
1379 +               else
1380 +               {
1381 +                       /* create a new data set name */
1382 +                       while (getpos (anc, k) > -1)
1383 +                               k++;
1384 +
1385 +                       setpos (anc, k, i);
1386 +
1387 +                       strncpy (s2, ch, 44);
1388 +                       s2[44] = 0;
1389 +                       vtoc_ebcdic_dec (s2, s2, 44);
1390 +
1391 +                       strncpy (ch, "LINUX.V               " "                      ", 44);
1392 +
1393 +                       strncpy (s1, anc->vlabel->volid, 6);
1394 +                       vtoc_ebcdic_dec (s1, s1, 6);
1395 +                       strncpy (c1, s1, 6);
1396 +
1397 +                       c1 = strchr (ch, ' ');
1398 +                       strncpy (c1, ".PART", 5);
1399 +                       c1 += 5;
1400 +
1401 +                       sprintf (dsno, "%04d.", k + 1);
1402 +                       strncpy (c1, dsno, 5);
1403 +
1404 +                       c1 += 5;
1405 +                       switch(p->type) {
1406 +                               case PARTITION_LINUX_LVM:
1407 +                                       strncpy(c1, PART_TYPE_LVM, 6);
1408 +                                       break;
1409 +                               case PARTITION_LINUX_RAID:
1410 +                                       strncpy(c1, PART_TYPE_RAID, 6);
1411 +                                       break;
1412 +                               case PARTITION_LINUX:
1413 +                                       strncpy(c1, PART_TYPE_NATIVE, 6);
1414 +                                       break;
1415 +                               case PARTITION_LINUX_SWAP:
1416 +                                       strncpy(c1, PART_TYPE_SWAP, 6);
1417 +                                       break;
1418 +                               default:
1419 +                                       strncpy(c1, PART_TYPE_NATIVE, 6);
1420 +                                       break;
1421 +                       }
1422 +               }
1423 +               vtoc_ebcdic_enc (ch, ch, 44);
1424 +
1425 +               vtoc_write_label (fd, b, p->f1, NULL, NULL, NULL);
1426 +               p = p->next;
1427 +       }
1428 +}
1429 +
1430 +
1431 +/*
1432 + * writes all changes to dasd
1433 + */
1434 +int
1435 +fdasd_write_labels (fdasd_anchor_t * anc, int fd)
1436 +{
1437 +PDEBUG
1438 +       if (anc->vlabel_changed)
1439 +       {
1440 +               vtoc_write_volume_label (fd, anc->label_pos, anc->vlabel);
1441 +       }
1442 +
1443 +       if (anc->vtoc_changed)
1444 +               fdasd_write_vtoc_labels (anc, fd);
1445 +
1446 +       /*
1447 +       if ((anc->vtoc_changed) || (anc->vlabel_changed))
1448 +               fdasd_reread_partition_table (anc, fd);
1449 +
1450 +       */
1451 +
1452 +       return 1;
1453 +}
1454 +
1455 +
1456 +/*
1457 + * writes all changes to dasd
1458 + */
1459 +int
1460 +fdasd_prepare_labels (fdasd_anchor_t *anc, int fd) 
1461 +{
1462 +PDEBUG
1463 +        partition_info_t *p = anc->first;
1464 +       char dsno[6], s1[7], s2[45], *c1, *c2, *ch;
1465 +       int i = 0, k = 0;
1466 +
1467 +       /* loop over all FMT1 DSCBs */
1468 +       p = anc->first;
1469 +       for (i = 0; i < USABLE_PARTITIONS; i++)
1470 +       {
1471 +               strncpy (p->f1->DS1DSSN, anc->vlabel->volid, 6);
1472 +
1473 +               ch = p->f1->DS1DSNAM;
1474 +               vtoc_ebcdic_dec (ch, ch, 44);
1475 +               c1 = ch + 7;
1476 +  
1477 +               if (getdsn (anc, i) > -1)
1478 +               {
1479 +                       /* re-use the existing data set name */
1480 +                       c2 = strchr (c1, '.');
1481 +                       if (c2 != NULL)
1482 +                               strncpy (s2, c2, 31);
1483 +                       else
1484 +                               fdasd_error (anc, dsname_corrupted, "");
1485 +
1486 +                       strncpy (s1, anc->vlabel->volid, 6);
1487 +                       vtoc_ebcdic_dec (s1, s1, 6);
1488 +                       s1[6] = ' ';
1489 +                       strncpy (c1, s1, 7);
1490 +                       c1 = strchr (ch, ' ');
1491 +                       strncpy (c1, s2, 31);
1492 +               }
1493 +               else
1494 +               {
1495 +                       /* create a new data set name */
1496 +                       while (getpos (anc, k) > -1)
1497 +                               k++;
1498 +
1499 +                       setpos (anc, k, i);
1500 +
1501 +                       strncpy (s2, ch, 44);
1502 +                       s2[44] = 0;
1503 +                       vtoc_ebcdic_dec (s2, s2, 44);
1504 +
1505 +                       strncpy (ch, "LINUX.V               " "                      ", 44);
1506 +
1507 +                       strncpy (s1, anc->vlabel->volid, 6);
1508 +                       vtoc_ebcdic_dec (s1, s1, 6);
1509 +                       strncpy (c1, s1, 6);
1510 +
1511 +                       c1 = strchr (ch, ' ');
1512 +                       strncpy (c1, ".PART", 5);
1513 +                       c1 += 5;
1514 +
1515 +                       sprintf (dsno, "%04d.", k + 1);
1516 +                       strncpy (c1, dsno, 5);
1517 +
1518 +                       c1 += 5;
1519 +                       switch(p->type) {
1520 +                               case PARTITION_LINUX_LVM:
1521 +                                       strncpy(c1, PART_TYPE_LVM, 6);
1522 +                                       break;
1523 +                               case PARTITION_LINUX_RAID:
1524 +                                       strncpy(c1, PART_TYPE_RAID, 6);
1525 +                                       break;
1526 +                               case PARTITION_LINUX:
1527 +                                       strncpy(c1, PART_TYPE_NATIVE, 6);
1528 +                                       break;
1529 +                               case PARTITION_LINUX_SWAP:
1530 +                                       strncpy(c1, PART_TYPE_SWAP, 6);
1531 +                                       break;
1532 +                               default:
1533 +                                       strncpy(c1, PART_TYPE_NATIVE, 6);
1534 +                                       break;
1535 +                       }
1536 +               }
1537 +               vtoc_ebcdic_enc (ch, ch, 44);
1538 +               p = p->next;
1539 +       }
1540 +       return 1;
1541 +}
1542 +
1543 +
1544 +/*
1545 + *
1546 + */
1547 +void
1548 +fdasd_recreate_vtoc(fdasd_anchor_t *anc)
1549 +{
1550 +PDEBUG
1551 +       partition_info_t *p = anc->first;
1552 +       int i;
1553 +
1554 +       vtoc_init_format4_label(anc->f4,
1555 +                               USABLE_PARTITIONS,
1556 +                               anc->geo.cylinders,
1557 +                               anc->geo.heads,
1558 +                               anc->geo.sectors,
1559 +                               anc->blksize,
1560 +                               anc->dev_type);
1561 +
1562 +       vtoc_init_format5_label(anc->f5);
1563 +       vtoc_init_format7_label(anc->f7);
1564 +       vtoc_set_freespace(anc->f4, anc->f5, anc->f7, 
1565 +                          '+', anc->verbose,
1566 +                          FIRST_USABLE_TRK,
1567 +                          anc->geo.cylinders * anc->geo.heads - 1,
1568 +                          anc->geo.cylinders, anc->geo.heads);
1569 +
1570 +       for (i = 0; i < USABLE_PARTITIONS; i++)
1571 +       {
1572 +               bzero(p->f1, sizeof(format1_label_t));
1573 +               p->used       = 0x00;
1574 +               p->start_trk  = 0;
1575 +               p->end_trk    = 0;
1576 +               p->len_trk    = 0;
1577 +               p->fspace_trk = 0;
1578 +               p->type       = 0;
1579 +               p = p->next;
1580 +       }
1581 +
1582 +       anc->used_partitions = 0;
1583 +       anc->fspace_trk = anc->geo.cylinders * anc->geo.heads - FIRST_USABLE_TRK;
1584 +
1585 +       for (i=0; i<USABLE_PARTITIONS; i++)
1586 +               setpos(anc, i, -1);
1587 +
1588 +       anc->vtoc_changed++;
1589 +}
1590 +
1591 +
1592 +/*
1593 + * changes the volume serial
1594 + */
1595 +static void
1596 +fdasd_change_volser (fdasd_anchor_t *anc, char *line_ptr) 
1597 +{
1598 +PDEBUG
1599 +       char str[10];
1600 +
1601 +        if (strcmp(line_ptr, "") != 0) 
1602 +       {
1603 +               int i;
1604 +
1605 +               /* fill with blanks if necessary and remove the linebreak */
1606 +               i = strlen(line_ptr);
1607 +               if (i <= 6)
1608 +               {
1609 +                       strncpy(line_ptr + i - 1, "      ", 6);
1610 +               }
1611 +
1612 +               strncpy(str, line_ptr, 6);
1613 +
1614 +               for (i=0; i<6; i++) str[i] = toupper(str[i]);
1615 +               str[6] = 0x00;
1616 +
1617 +               fdasd_check_volser (str, anc->devno);
1618 +               vtoc_volume_label_set_volser(anc->vlabel, str);
1619 +
1620 +               vtoc_set_cchhb(&anc->vlabel->vtoc, 0x0000, 0x0001, 0x01);
1621 +               anc->vlabel_changed++;
1622 +               anc->vtoc_changed++;
1623 +       }
1624 +}
1625 +
1626 +
1627 +/*
1628 + * sets some important partition data
1629 + * (like used, start_trk, end_trk, len_trk)
1630 + * by calculating these values with the
1631 + * information provided in the labels
1632 + */
1633 +static void
1634 +fdasd_update_partition_info (fdasd_anchor_t *anc) 
1635 +{
1636 +PDEBUG
1637 +       partition_info_t *q = NULL, *p = anc->first;
1638 +       unsigned int h = anc->geo.heads;
1639 +       unsigned long max = anc->geo.cylinders * h - 1;
1640 +       int i;
1641 +       char *ch;
1642 +
1643 +       anc->used_partitions = anc->geo.sectors - 2 - anc->f4->DS4DSREC;
1644 +
1645 +       for (i = 1; i <= USABLE_PARTITIONS; i++)
1646 +       {
1647 +               if (p->f1->DS1FMTID != 0xf1)
1648 +               {
1649 +                       if (i == 1)
1650 +                               /* there is no partition at all */
1651 +                               anc->fspace_trk = max - FIRST_USABLE_TRK + 1;
1652 +                       else
1653 +                               /* previous partition was the last one */
1654 +                               q->fspace_trk = max - q->end_trk;
1655 +                       break;
1656 +               }
1657 +
1658 +               /* this is a valid format 1 label */
1659 +               p->used = 0x01;
1660 +               p->start_trk = p->f1->DS1EXT1.llimit.cc * h +
1661 +                              p->f1->DS1EXT1.llimit.hh;
1662 +               p->end_trk   = p->f1->DS1EXT1.ulimit.cc * h +
1663 +                              p->f1->DS1EXT1.ulimit.hh;
1664 +               p->len_trk   = p->end_trk - p->start_trk + 1;
1665 +
1666 +               if (i == 1)
1667 +                       /* first partition, there is at least one */
1668 +                       anc->fspace_trk = p->start_trk - FIRST_USABLE_TRK;
1669 +               else
1670 +               {
1671 +                       if (i == USABLE_PARTITIONS)
1672 +                               /* last possible partition */
1673 +                               p->fspace_trk = max - p->end_trk;
1674 +
1675 +                       /* set free space values of previous partition */
1676 +                       q->fspace_trk = p->start_trk - q->end_trk - 1;
1677 +               }
1678 +
1679 +               ch = p->f1->DS1DSNAM;
1680 +               vtoc_ebcdic_dec (ch, ch, 44);
1681 +               if (strstr(ch, PART_TYPE_LVM))
1682 +                       p->type = PARTITION_LINUX_LVM;
1683 +               else if (strstr(ch, PART_TYPE_RAID))
1684 +                       p->type = PARTITION_LINUX_RAID;
1685 +               else if (strstr(ch, PART_TYPE_NATIVE))
1686 +                       p->type = PARTITION_LINUX;
1687 +               else if (strstr(ch, PART_TYPE_SWAP))
1688 +                       p->type = PARTITION_LINUX_SWAP;
1689 +               else
1690 +                       p->type = PARTITION_LINUX;
1691 +               vtoc_ebcdic_enc (ch, ch, 44);
1692 +
1693 +               q = p;
1694 +               p = p->next;
1695 +       }
1696 +}
1697 +
1698 +
1699 +/*
1700 + * reorganizes all FMT1s, after that all used FMT1s should be right in 
1701 + * front of all unused FMT1s
1702 + */
1703 +static void
1704 +fdasd_reorganize_FMT1s (fdasd_anchor_t *anc) 
1705 +{
1706 +PDEBUG
1707 +       int i, j;
1708 +       format1_label_t *ltmp;
1709 +       partition_info_t *ptmp;
1710 +
1711 +       for (i=1; i<=USABLE_PARTITIONS - 1; i++)
1712 +       {
1713 +               ptmp = anc->first;
1714 +               for (j=1; j<=USABLE_PARTITIONS - i; j++)
1715 +               {
1716 +                       if (ptmp->f1->DS1FMTID < ptmp->next->f1->DS1FMTID)
1717 +                       {
1718 +                               ltmp = ptmp->f1;
1719 +                               ptmp->f1 = ptmp->next->f1;
1720 +                               ptmp->next->f1 = ltmp;
1721 +                       }
1722 +                       ptmp=ptmp->next;
1723 +               }
1724 +       }
1725 +}
1726 +
1727 +
1728 +/*
1729 + *
1730 + */
1731 +static void
1732 +fdasd_process_valid_vtoc (fdasd_anchor_t * anc, unsigned long b, int fd)
1733 +{
1734 +PDEBUG
1735 +       int f5_counter = 0, f7_counter = 0, f1_counter = 0, oldfmt = 0;
1736 +       int i, n, f1size = sizeof (format1_label_t);
1737 +       partition_info_t *p = anc->first;
1738 +       format1_label_t q;
1739 +       char s[5], *ch;
1740 +
1741 +       b += anc->blksize;
1742 +
1743 +       for (i = 1; i <= anc->geo.sectors; i++)
1744 +       {
1745 +               bzero (&q, f1size);
1746 +               vtoc_read_label (fd, b, &q, NULL, NULL, NULL);
1747 +
1748 +               switch (q.DS1FMTID)
1749 +               {
1750 +                       case 0xf1:
1751 +                               if (p == NULL)
1752 +                                       break;
1753 +                               memcpy (p->f1, &q, f1size);
1754 +
1755 +                               n = -1;
1756 +                               vtoc_ebcdic_dec (p->f1->DS1DSNAM, p->f1->DS1DSNAM, 44);
1757 +                               ch = strstr (p->f1->DS1DSNAM, "PART");
1758 +                               if (ch != NULL)
1759 +                               {
1760 +                                       strncpy (s, ch + 4, 4);
1761 +                                       s[4] = '\0';
1762 +                                       n = atoi (s) - 1;
1763 +                               }
1764 +
1765 +                               vtoc_ebcdic_enc (p->f1->DS1DSNAM, p->f1->DS1DSNAM, 44);
1766 +
1767 +                               /* this dasd has data set names 0000-0002
1768 +                               but we use now 0001-0003 */
1769 +                               if (n == -1)
1770 +                                       oldfmt++;
1771 +
1772 +                               if (((oldfmt == 0) && (n < 0)) || (n >= USABLE_PARTITIONS))
1773 +                               {
1774 +                               }
1775 +                               else
1776 +                               {
1777 +                                       if (oldfmt)       /* correct +1 */
1778 +                                       {
1779 +                                               setpos (anc, n + 1, f1_counter);
1780 +                                       }
1781 +                                       else
1782 +                                               setpos (anc, n, f1_counter);
1783 +                               }
1784 +
1785 +                               p = p->next;
1786 +                               f1_counter++;
1787 +                               break;
1788 +                       case 0xf5:
1789 +                               memcpy (anc->f5, &q, f1size);
1790 +                               f5_counter++;
1791 +                               break;
1792 +                       case 0xf7:
1793 +                               if (f7_counter == 0)
1794 +                                       memcpy (anc->f7, &q, f1size);
1795 +                               f7_counter++;
1796 +                               break;
1797 +               }
1798 +               b += anc->blksize;
1799 +       }
1800 +
1801 +       if (oldfmt > 0)
1802 +       {
1803 +               /* this is the old format PART0000 - PART0002 */
1804 +               anc->vtoc_changed++;
1805 +       }
1806 +
1807 +       if ((f5_counter == 0) || (anc->big_disk))
1808 +               vtoc_init_format5_label (anc->f5);
1809 +
1810 +       if (f7_counter == 0)
1811 +               vtoc_init_format7_label (anc->f7);
1812 +
1813 +       fdasd_reorganize_FMT1s (anc);
1814 +       fdasd_update_partition_info (anc);
1815 +}
1816 +
1817 +
1818 +/*
1819 + *
1820 + */
1821 +static int
1822 +fdasd_valid_vtoc_pointer(fdasd_anchor_t *anc, unsigned long b, int fd)
1823 +{
1824 +PDEBUG
1825 +       char str[LINE_LENGTH];
1826 +
1827 +       /* VOL1 label contains valid VTOC pointer */ 
1828 +       vtoc_read_label (fd, b, NULL, anc->f4, NULL, NULL);
1829 +
1830 +       if (anc->f4->DS4IDFMT != 0xf4)
1831 +       {
1832 +               if (strncmp (anc->vlabel->volkey, vtoc_ebcdic_enc ("LNX1", str, 4), 4) == 0)
1833 +                       return 0;
1834 +               /* format4 DSCB is invalid
1835 +               printf(" invalid\ncreating new VTOC...\n"); */
1836 +               fdasd_error(anc, wrong_disk_format, "Invalid VTOC");
1837 +       }
1838 +       else
1839 +               fdasd_process_valid_vtoc (anc, b, fd);
1840 +
1841 +       return 0;
1842 +}
1843 +
1844 +
1845 +/*
1846 + * check the dasd for a volume label
1847 + */
1848 +int 
1849 +fdasd_check_volume (fdasd_anchor_t *anc, int fd) 
1850 +{
1851 +PDEBUG
1852 +       volume_label_t *v = anc->vlabel;
1853 +       unsigned long b = -1;
1854 +       char str[LINE_LENGTH];
1855 +
1856 +       vtoc_read_volume_label (fd, anc->label_pos, v);
1857 +
1858 +       if (strncmp (v->vollbl, vtoc_ebcdic_enc ("VOL1", str, 4), 4) == 0)
1859 +       {
1860 +               /* found VOL1 volume label */
1861 +               b = (cchhb2blk (&v->vtoc, &anc->geo) - 1) * anc->blksize;
1862 +               if (b > 0)
1863 +               {
1864 +                       int rc;
1865 +                       rc = fdasd_valid_vtoc_pointer (anc, b, fd);
1866 +
1867 +                       if (rc < 0)
1868 +                               return 1;
1869 +                       else
1870 +                               return 0;
1871 +               }
1872 +               else 
1873 +               {
1874 +                       return 1;
1875 +               }
1876 +        }
1877 +       else if (strncmp (v->volkey, vtoc_ebcdic_enc ("LNX1", str, 4), 4) == 0)
1878 +       {
1879 +               return 0;
1880 +       }
1881 +
1882 +        return 1;
1883 +}
1884 +
1885 +
1886 +/*
1887 + * checks the current API version with the API version of the dasd driver
1888 + */
1889 +void
1890 +fdasd_check_api_version (fdasd_anchor_t *anc, int f)
1891 +{
1892 +PDEBUG
1893 +        int api;
1894 +       char s[LINE_LENGTH];
1895
1896 +        if (ioctl(f, DASDAPIVER, &api) != 0)
1897 +        {
1898 +                fdasd_error(anc, unable_to_ioctl,
1899 +                            "Could not retrieve API version.");
1900 +        }
1901
1902 +       if (api != DASD_MIN_API_VERSION)
1903 +       {
1904 +               sprintf(s, "The current API version '%d' doesn't " \
1905 +                       "match dasd driver API version " \
1906 +                       "'%d'!", api, DASD_MIN_API_VERSION);
1907 +               fdasd_error(anc, api_version_mismatch, s);
1908 +       }
1909 +}                                      
1910 +
1911 +
1912 +/*
1913 + * reads dasd geometry data
1914 + */
1915 +void 
1916 +fdasd_get_geometry (fdasd_anchor_t *anc, int f) 
1917 +{
1918 +PDEBUG
1919 +        int blksize = 0;
1920 +       dasd_information_t dasd_info;
1921 +       char s[LINE_LENGTH];
1922 +
1923 +       if (ioctl(f, HDIO_GETGEO, &anc->geo) != 0) 
1924 +       {
1925 +               fdasd_error(anc, unable_to_ioctl, 
1926 +                           "Could not retrieve disk geometry information.");
1927 +       }
1928 +
1929 +       if (ioctl(f, BLKSSZGET, &blksize) != 0)
1930 +       {
1931 +               fdasd_error(anc, unable_to_ioctl,
1932 +                           "Could not retrieve blocksize information.");
1933 +       }
1934 +
1935 +       /* get disk type */
1936 +       if (ioctl(f, BIODASDINFO, &dasd_info) != 0) 
1937 +       {
1938 +               fdasd_error(anc, unable_to_ioctl, 
1939 +                           "Could not retrieve disk information.");
1940 +       }
1941 +
1942 +       if (strncmp(dasd_info.type, "ECKD", 4) != 0)
1943 +       {
1944 +               sprintf(s, "This is not an ECKD disk! This disk type " \
1945 +                       "is not supported!");
1946 +               fdasd_error(anc,wrong_disk_type, s);
1947 +       }
1948 +
1949 +       /* Disable FBA_layout check
1950 +        if (dasd_info.FBA_layout)
1951 +        {
1952 +          if(!anc->silent) {
1953 +                sprintf(s, "Device is not formatted with z/OS compatible " \
1954 +                       "disk layout!");
1955 +                fdasd_error(anc,wrong_disk_format, s);
1956 +          }
1957 +        }      
1958 +       */
1959 +
1960 +       /* We do not write yet, so let this check go 
1961 +       if (dasd_info.open_count > 1)
1962 +       {
1963 +               sprintf(s, "Device is in use by another program. Exit all " \
1964 +                       "applications using this disk and/or unmount it.");
1965 +               fdasd_error(anc,disk_in_use, s);
1966 +       }
1967 +       */
1968 +
1969 +       anc->dev_type   = dasd_info.dev_type;
1970 +       anc->blksize    = blksize;
1971 +       anc->label_pos  = dasd_info.label_block * blksize;
1972 +       anc->devno      = dasd_info.devno;
1973 +       anc->fspace_trk = anc->geo.cylinders * anc->geo.heads - FIRST_USABLE_TRK;
1974 +}
1975 +
1976 +/*
1977 + * returns unused partition info pointer if there
1978 + * is a free partition, otherwise NULL
1979 + */
1980 +static partition_info_t * 
1981 +fdasd_get_empty_f1_label (fdasd_anchor_t * anc) 
1982 +{
1983 +PDEBUG
1984 +       if (anc->used_partitions < USABLE_PARTITIONS)     
1985 +               return anc->last;             
1986 +       else
1987 +               return NULL;
1988 +}
1989 +
1990 +/*
1991 + * asks for and sets some important partition data
1992 + */
1993 +static int 
1994 +fdasd_get_partition_data (fdasd_anchor_t *anc,
1995 +                         extent_t *part_extent,
1996 +                         partition_info_t *p, unsigned int *start_ptr, unsigned int *stop_ptr) 
1997 +{
1998 +PDEBUG
1999 +       unsigned int limit, cc, hh;
2000 +       cchh_t llimit, ulimit;
2001 +       partition_info_t *q;
2002 +        char mesg[48];
2003 +       u_int8_t b1, b2;
2004 +       u_int16_t c, h;
2005 +       unsigned int start = *start_ptr, stop = *stop_ptr;
2006 +       int i;
2007 +       char *ch;
2008 +
2009 +       if (anc->f4->DS4DEVCT.DS4DEVFG & ALTERNATE_CYLINDERS_USED)
2010 +               c = anc->f4->DS4DEVCT.DS4DSCYL - (u_int16_t) anc->f4->DS4DEVAC;
2011 +       else
2012 +               c = anc->f4->DS4DEVCT.DS4DSCYL;
2013 +
2014 +       h = anc->f4->DS4DEVCT.DS4DSTRK;
2015 +       limit = (h * c - 1);
2016 +
2017 +       /* check start value from user */
2018 +       q = anc->first;
2019 +       for (i = 0; i < USABLE_PARTITIONS; i++)
2020 +       {
2021 +               if ( q->next == NULL )
2022 +                       break;
2023 +               if (start >= q->start_trk && start <= q->end_trk)
2024 +               {
2025 +                       /* start is within another partition */
2026 +                       start = q->end_trk + 1;
2027 +                       if (start > limit)
2028 +                       {
2029 +                               start = FIRST_USABLE_TRK;
2030 +                               q = anc->first;
2031 +                       }
2032 +
2033 +/*
2034 +                       printf("value within another partition, " \
2035 +                              "using %d instead\n", start);
2036 +*/
2037 +               }
2038 +
2039 +               if (start < q->start_trk)
2040 +               {
2041 +                       limit = q->start_trk - 1;
2042 +                       break;
2043 +               }
2044 +               q = q->next;
2045 +       }
2046 +
2047 +       if (start == limit)
2048 +               stop = start;
2049 +
2050 +       /* update partition info */
2051 +       p->len_trk    = stop - start + 1;
2052 +       p->start_trk  = start;
2053 +       p->end_trk    = stop;
2054 +
2055 +       cc = start / anc->geo.heads;
2056 +       hh = start - (cc * anc->geo.heads);
2057 +       vtoc_set_cchh(&llimit, cc, hh);
2058 +
2059 +       /* check for cylinder boundary */
2060 +       if (hh == 0)  
2061 +               b1 = 0x81;
2062 +       else
2063 +               b1 = 0x01;
2064 +
2065 +       cc = stop / anc->geo.heads;
2066 +       hh = stop - cc * anc->geo.heads;
2067 +       vtoc_set_cchh(&ulimit, cc, hh);
2068 +
2069 +        /* it is always the 1st extent */
2070 +       b2 = 0x00;
2071 +
2072 +       vtoc_set_extent(part_extent, b1, b2, &llimit, &ulimit);
2073 +
2074 +       *start_ptr = start;
2075 +       *stop_ptr = stop;
2076 +
2077 +       ch = p->f1->DS1DSNAM;
2078 +       vtoc_ebcdic_dec (ch, ch, 44);
2079 +       if (strstr(ch, PART_TYPE_LVM))
2080 +               p->type = PARTITION_LINUX_LVM;
2081 +       else if (strstr(ch, PART_TYPE_RAID))
2082 +               p->type = PARTITION_LINUX_RAID;
2083 +       else if (strstr(ch, PART_TYPE_NATIVE))
2084 +               p->type = PARTITION_LINUX;
2085 +       else if (strstr(ch, PART_TYPE_SWAP))
2086 +               p->type = PARTITION_LINUX_SWAP;
2087 +       else
2088 +               p->type = PARTITION_LINUX;
2089 +       vtoc_ebcdic_enc (ch, ch, 44);
2090 +
2091 +       return 0;
2092 +}
2093 +
2094 +
2095 +/*
2096 + *
2097 + */
2098 +static void
2099 +fdasd_enqueue_new_partition (fdasd_anchor_t *anc) 
2100 +{
2101 +PDEBUG
2102 +        partition_info_t *q = anc->first, *p = anc->last;
2103 +       int i,k=0;
2104 +
2105 +       for (i=1; i<USABLE_PARTITIONS; i++) 
2106 +       {
2107 +               if ((q->end_trk == 0) || 
2108 +                   (p->start_trk < q->start_trk))
2109 +                       break;
2110 +               else
2111 +               { 
2112 +                       q = q->next;
2113 +                       k++;
2114 +               }
2115 +       }
2116 +
2117 +       if (anc->first == q) anc->first = p;
2118 +       
2119 +       if (p != q) 
2120 +       {
2121 +               anc->last->prev->next = NULL;
2122 +               anc->last = anc->last->prev;
2123 +
2124 +               p->next = q;
2125 +               p->prev = q->prev;
2126 +               q->prev = p;
2127 +               
2128 +               if (p->prev != NULL)
2129 +                       p->prev->next = p;
2130 +       }
2131 +
2132 +       p->used       = 0x01;
2133 +       p->type       = PARTITION_LINUX;
2134 +
2135 +       for (i=0; i<USABLE_PARTITIONS; i++)
2136 +       {
2137 +               int j = getpos(anc, i);
2138 +               if (j >= k) setpos(anc, i, j + 1);
2139 +       }
2140 +
2141 +       /* update free-space counters */
2142 +       if (anc->first == p) 
2143 +       {
2144 +               /* partition is the first used partition */
2145 +               if (p->start_trk == FIRST_USABLE_TRK) 
2146 +               {
2147 +                      /* partition starts right behind VTOC */
2148 +                      p->fspace_trk = anc->fspace_trk - p->len_trk;
2149 +                      anc->fspace_trk = 0;
2150 +               }
2151 +               else 
2152 +               {
2153 +                      /* there is some space between VTOC and partition */
2154 +
2155 +                      p->fspace_trk   = anc->fspace_trk - 
2156 +                                        p->len_trk -
2157 +                                        p->start_trk +
2158 +                                        FIRST_USABLE_TRK;
2159 +                      anc->fspace_trk = p->start_trk - FIRST_USABLE_TRK;
2160 +               }
2161 +       }
2162 +       else
2163 +       {
2164 +               /* there are partitons in front of the new one */
2165 +               if (p->start_trk == p->prev->end_trk + 1) 
2166 +               {
2167 +                       /* new partition is right behind the previous one */
2168 +                       p->fspace_trk = p->prev->fspace_trk - p->len_trk;
2169 +                       p->prev->fspace_trk = 0;
2170 +               }
2171 +               else
2172 +               {
2173 +                       /* there is some space between new and prev. part. */
2174 +                       p->fspace_trk       = p->prev->fspace_trk - 
2175 +                                             p->len_trk - 
2176 +                                             p->start_trk +
2177 +                                             p->prev->end_trk + 1;
2178 +                       p->prev->fspace_trk = p->start_trk -
2179 +                                              p->prev->end_trk - 
2180 +                                             1;
2181 +               }
2182 +       }
2183 +}
2184 +
2185 +
2186 +/*
2187 + * adds a new partition to the 'partition table'
2188 + */
2189 +partition_info_t *
2190 +fdasd_add_partition (fdasd_anchor_t *anc, unsigned int start, unsigned int stop) 
2191 +{
2192 +PDEBUG
2193 +       cchhb_t hf1;
2194 +       partition_info_t *p;
2195 +       extent_t ext;
2196 +       int i;
2197 +
2198 +       PDEBUG;
2199 +
2200 +       if ((p = fdasd_get_empty_f1_label(anc)) == NULL) 
2201 +       {
2202 +       PDEBUG;
2203 +               return 0;
2204 +       }
2205 +
2206 +       PDEBUG;
2207 +       if (fdasd_get_partition_data(anc, &ext, p, &start, &stop) != 0)
2208 +               return 0;
2209 +
2210 +       PDEBUG;
2211 +       vtoc_init_format1_label(anc->vlabel->volid,
2212 +                               anc->blksize,
2213 +                               &ext,
2214 +                               p->f1);
2215 +
2216 +
2217 +       PDEBUG;
2218 +       fdasd_enqueue_new_partition(anc);
2219 +       
2220 +       PDEBUG;
2221 +       anc->used_partitions += 1;
2222 +
2223 +       i = anc->used_partitions + 2;
2224 +       if (anc->big_disk) i++;
2225 +       PDEBUG;
2226 +
2227 +        vtoc_set_cchhb(&hf1, VTOC_START_CC, VTOC_START_HH, i);
2228 +
2229 +       vtoc_update_format4_label(anc->f4, &hf1, 
2230 +               anc->f4->DS4DSREC - 1);
2231 +
2232 +       PDEBUG;
2233 +
2234 +       start = ext.llimit.cc * anc->geo.heads + ext.llimit.hh;
2235 +       stop  = ext.ulimit.cc * anc->geo.heads + ext.ulimit.hh;
2236 +
2237 +       PDEBUG;
2238 +       vtoc_set_freespace(anc->f4, anc->f5, anc->f7, 
2239 +                          '-', anc->verbose,
2240 +                          start, stop,
2241 +                          anc->geo.cylinders, anc->geo.heads);
2242 +
2243 +       anc->vtoc_changed++;
2244 +
2245 +       PDEBUG;
2246 +       return p;
2247 +}
2248 diff -ruN --minimal parted-1.6.21.orig/libparted/fdasd.h parted-1.6.21/libparted/fdasd.h
2249 --- parted-1.6.21.orig/libparted/fdasd.h        1969-12-31 19:00:00.000000000 -0500
2250 +++ parted-1.6.21/libparted/fdasd.h     2005-01-21 15:00:40.429628321 -0500
2251 @@ -0,0 +1,230 @@
2252 +/*
2253 + * File...........: s390-tools/fdasd/fdasd.h
2254 + * Author(s)......: Volker Sameske <sameske@de.ibm.com>
2255 + *                  Horst Hummel   <Horst.Hummel@de.ibm.com>
2256 + * Bugreports.to..: <Linux390@de.ibm.com>
2257 + * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 2001-2002
2258 + *
2259 + * History of changes (starts March 2001)
2260 + * version 1.01 - menu entry 's' to show mapping devnode - DS name
2261 + *         1.02 - DS names count now from 0001 instead from 0000
2262 + *         1.03 - volser checks: 'AA AAA' to 'AAAAA '
2263 + *              - removed dependency to kernel headers.
2264 + *         1.04 - added -p option
2265 + *         1.05 - new API policy, set it back to 0
2266 + */
2267 +#ifndef FDASD_H
2268 +#define FDASD_H
2269 +
2270 +/*****************************************************************************
2271 + * SECTION: Definitions needed for DASD-API (see dasd.h)                     *
2272 + *****************************************************************************/
2273 +
2274 +#define DASD_IOCTL_LETTER 'D'
2275 +
2276 +#define DASD_PARTN_BITS 2
2277 +
2278 +#define PARTITION_LINUX_SWAP    0x82
2279 +#define PARTITION_LINUX         0x83
2280 +#define PARTITION_LINUX_EXT     0x85
2281 +#define PARTITION_LINUX_LVM     0x8e
2282 +#define PARTITION_LINUX_RAID    0xfd
2283 +#define PARTITION_LINUX_LVM_OLD 0xfe
2284 +
2285 +#define PART_TYPE_NATIVE "NATIVE"
2286 +#define PART_TYPE_SWAP   "SWAP  "
2287 +#define PART_TYPE_RAID   "RAID  "
2288 +#define PART_TYPE_LVM   "LVM   "
2289 +
2290 +#ifdef DEBUG_DASD
2291 +#define PDEBUG           fprintf(stderr, "%s:%d:%s\n", \
2292 +                         __FILE__,                              \
2293 +                         __LINE__,                              \
2294 +                         __PRETTY_FUNCTION__);
2295 +#else
2296 +#define PDEBUG
2297 +#endif
2298 +
2299 +/* 
2300 + * struct dasd_information_t
2301 + * represents any data about the device, which is visible to userspace.
2302 + *  including foramt and featueres.
2303 + */
2304 +typedef struct dasd_information_t {
2305 +        unsigned int devno;           /* S/390 devno                         */
2306 +        unsigned int real_devno;      /* for aliases                         */
2307 +        unsigned int schid;           /* S/390 subchannel identifier         */
2308 +        unsigned int cu_type  : 16;   /* from SenseID                        */
2309 +        unsigned int cu_model :  8;   /* from SenseID                        */
2310 +        unsigned int dev_type : 16;   /* from SenseID                        */
2311 +        unsigned int dev_model : 8;   /* from SenseID                        */
2312 +        unsigned int open_count; 
2313 +        unsigned int req_queue_len; 
2314 +        unsigned int chanq_len;       /* length of chanq                     */
2315 +        char type[4];                 /* from discipline.name, 'none' for    */
2316 +                                     /* unknown                             */
2317 +        unsigned int status;          /* current device level                */
2318 +        unsigned int label_block;     /* where to find the VOLSER            */
2319 +        unsigned int FBA_layout;      /* fixed block size (like AIXVOL)      */
2320 +        unsigned int characteristics_size;
2321 +        unsigned int confdata_size;
2322 +        char characteristics[64];     /* from read_device_characteristics    */
2323 +        char configuration_data[256]; /* from read_configuration_data        */
2324 +} dasd_information_t;
2325 +
2326 +/* 
2327 + * struct format_data_t
2328 + * represents all data necessary to format a dasd
2329 + */
2330 +typedef struct format_data_t {
2331 +       int start_unit; /* from track */
2332 +       int stop_unit;  /* to track */
2333 +       int blksize;    /* sectorsize */
2334 +        int intensity;  
2335 +} format_data_t;
2336 +
2337 +/*
2338 + * values to be used for format_data_t.intensity
2339 + * 0/8: normal format
2340 + * 1/9: also write record zero
2341 + * 3/11: also write home address
2342 + * 4/12: invalidate track
2343 + */
2344 +#define DASD_FMT_INT_FMT_R0 1 /* write record zero */
2345 +#define DASD_FMT_INT_FMT_HA 2 /* write home address, also set FMT_R0 ! */
2346 +#define DASD_FMT_INT_INVAL  4 /* invalidate tracks */
2347 +#define DASD_FMT_INT_COMPAT 8 /* use OS/390 compatible disk layout */
2348 +
2349 +
2350 +/* Disable the volume (for Linux) */
2351 +#define BIODASDDISABLE _IO(DASD_IOCTL_LETTER,0) 
2352 +/* Enable the volume (for Linux) */
2353 +#define BIODASDENABLE  _IO(DASD_IOCTL_LETTER,1)  
2354 +
2355 +/* retrieve API version number */
2356 +#define DASDAPIVER     _IOR(DASD_IOCTL_LETTER,0,int)
2357 +/* Get information on a dasd device (enhanced) */
2358 +#define BIODASDINFO   _IOR(DASD_IOCTL_LETTER,1,dasd_information_t)
2359 +
2360 +
2361 +/*****************************************************************************
2362 + * SECTION: Further IOCTL Definitions  (see fs.h)                            *
2363 + *****************************************************************************/
2364 +/* re-read partition table */
2365 +#define BLKRRPART  _IO(0x12,95)        
2366 +/* get block device sector size */
2367 +#define BLKSSZGET  _IO(0x12,104)
2368 +
2369 +/*****************************************************************************
2370 + * SECTION: Definition from hdreq.h                                          *
2371 + *****************************************************************************/
2372 +
2373 +struct fdasd_hd_geometry {
2374 +      unsigned char heads;
2375 +      unsigned char sectors;
2376 +      unsigned short cylinders;
2377 +      unsigned long start;
2378 +};
2379 +
2380 +/* get device geometry */
2381 +#define HDIO_GETGEO            0x0301  
2382 +
2383 +/*****************************************************************************
2384 + * SECTION: FDASD internal types                                             *
2385 + *****************************************************************************/
2386 +
2387 +#define DASD_MIN_API_VERSION 0
2388 +
2389 +#define DEFAULT_FDASD_CONF "/etc/fdasd.conf" /* default config file */
2390 +
2391 +#define PARTN_MASK ((1 << DASD_PARTN_BITS) - 1)
2392 +#define USABLE_PARTITIONS ((1 << DASD_PARTN_BITS) - 1)
2393 +
2394 +#define FDASD_VERSION "1.05"
2395 +#define FDASD_ERROR "fdasd error: "
2396 +#define DEVICE "device"
2397 +#define DISC   "disc"
2398 +#define PART   "part"
2399 +
2400 +#define ALTERNATE_CYLINDERS_USED 0x10
2401 +
2402 +typedef struct partition_info {
2403 +        u_int8_t           used;
2404 +        unsigned long      start_trk;
2405 +        unsigned long      end_trk;
2406 +        unsigned long      len_trk;
2407 +        unsigned long      fspace_trk;
2408 +        format1_label_t  * f1; 
2409 +        struct partition_info *next;
2410 +        struct partition_info *prev;
2411 +        u_int8_t           type;
2412 +} partition_info_t;
2413 +
2414 +
2415 +typedef struct config_data {
2416 +       unsigned long start;
2417 +       unsigned long stop;
2418 +} config_data_t;
2419 +
2420 +
2421 +typedef struct fdasd_anchor {
2422 +        int vlabel_changed;
2423 +        int vtoc_changed;
2424 +       int devname_specified;
2425 +       int volid_specified;
2426 +       int config_specified;
2427 +       int auto_partition;
2428 +       int print_table;
2429 +       int big_disk;
2430 +       int silent;
2431 +       int verbose;
2432 +       int devno;
2433 +       int option_reuse;
2434 +       int option_recreate;
2435 +       int partno[USABLE_PARTITIONS];
2436 +       u_int16_t dev_type;
2437 +       unsigned int used_partitions;
2438 +       unsigned long label_pos;
2439 +        unsigned int  blksize;
2440 +        unsigned long fspace_trk;
2441 +        format4_label_t  *f4;
2442 +        format5_label_t  *f5;
2443 +       format7_label_t  *f7;
2444 +        partition_info_t *first;
2445 +        partition_info_t *last;
2446 +        volume_label_t   *vlabel;
2447 +       config_data_t confdata[USABLE_PARTITIONS];
2448 +       struct fdasd_hd_geometry geo;
2449 +} fdasd_anchor_t;
2450 +
2451 +enum offset {lower, upper};
2452 +
2453 +enum fdasd_failure {
2454 +       unable_to_open_disk,
2455 +       unable_to_seek_disk,
2456 +       unable_to_read_disk,
2457 +       read_only_disk,
2458 +        unable_to_ioctl,
2459 +       api_version_mismatch,
2460 +       wrong_disk_type,
2461 +       wrong_disk_format,
2462 +       disk_in_use,
2463 +       config_syntax_error,
2464 +       vlabel_corrupted,
2465 +       dsname_corrupted,
2466 +       malloc_failed,
2467 +       device_verification_failed
2468 +};
2469 +
2470 +void fdasd_cleanup (fdasd_anchor_t *anchor);
2471 +void fdasd_initialize_anchor (fdasd_anchor_t * anc);
2472 +void fdasd_get_geometry (fdasd_anchor_t *anc, int fd);
2473 +void fdasd_check_api_version (fdasd_anchor_t *anc, int fd);
2474 +int fdasd_check_volume (fdasd_anchor_t *anc, int fd);
2475 +int fdasd_write_labels (fdasd_anchor_t *anc, int fd);
2476 +int fdasd_invalid_vtoc_pointer(fdasd_anchor_t *anc);
2477 +void fdasd_recreate_vtoc(fdasd_anchor_t *anc);
2478 +partition_info_t * fdasd_add_partition (fdasd_anchor_t *anc, unsigned int start, unsigned int stop);
2479 +int fdasd_prepare_labels (fdasd_anchor_t *anc, int fd) ;
2480 +
2481 +#endif /* FDASD_H */
2482 --- parted-1.6.23/libparted/libparted.c.orig    2005-03-29 02:01:22.000000000 +0200
2483 +++ parted-1.6.23/libparted/libparted.c 2005-07-18 20:57:09.847100720 +0200
2484 @@ -87,12 +87,17 @@
2485  extern void ped_disk_pc98_init ();
2486  extern void ped_disk_sun_init ();
2487  extern void ped_disk_amiga_init ();
2488 +extern void ped_disk_dasd_init ();
2489  
2490  static void
2491  init_disk_types ()
2492  {
2493         ped_disk_loop_init ();  /* must be last in the probe list */
2494  
2495 +#if defined(__s390__) || defined(__s390x__)
2496 +       ped_disk_dasd_init();
2497 +#endif
2498 +
2499         ped_disk_sun_init ();
2500  #ifdef ENABLE_PC98
2501         ped_disk_pc98_init ();
2502 @@ -142,10 +147,14 @@
2503  extern void ped_disk_pc98_done ();
2504  extern void ped_disk_sun_done ();
2505  extern void ped_disk_amiga_done ();
2506 +extern void ped_disk_dasd_done ();
2507  
2508  static void
2509  done_disk_types ()
2510  {
2511 +#if defined(__s390__) || defined(__s390x__)
2512 +       ped_disk_dasd_done ();
2513 +#endif
2514         ped_disk_sun_done ();
2515  #ifdef ENABLE_PC98
2516         ped_disk_pc98_done ();
2517 @@ -282,8 +291,9 @@
2518                 return NULL;
2519         }
2520  
2521 +       memset (mem, 0, size);
2522  #ifdef DEBUG
2523 -       memset (mem, 0xff, size);
2524 +       /* memset (mem, 0xff, size); */
2525         _check_dodgy_pointer (mem, size, 1);
2526  #endif
2527  
2528 diff -ruN --minimal parted-1.6.21.orig/libparted/linux.c parted-1.6.21/libparted/linux.c
2529 --- parted-1.6.21.orig/libparted/linux.c        2005-01-15 20:01:57.000000000 -0500
2530 +++ parted-1.6.21/libparted/linux.c     2005-01-21 15:04:40.574398622 -0500
2531 @@ -60,6 +60,9 @@
2532  #define HDIO_GETGEO            0x0301  /* get device geometry */
2533  #define HDIO_GET_IDENTITY      0x030d  /* get IDE identification info */
2534  
2535 +#include "vtoc.h"
2536 +#include "fdasd.h"
2537 +
2538  struct hd_geometry {
2539         unsigned char heads;
2540         unsigned char sectors;
2541 @@ -215,6 +218,8 @@
2542  #define I2O_MAJOR7             86
2543  #define I2O_MAJOR8             87
2544  
2545 +#define DASD_MAJOR             94
2546 +
2547  #define SCSI_BLK_MAJOR(M) (                                            \
2548                 (M) == SCSI_DISK0_MAJOR                                 \
2549                 || (M) == SCSI_CDROM_MAJOR                              \
2550 @@ -302,6 +307,8 @@
2551                 dev->type = PED_DEVICE_DAC960;
2552         } else if (dev_major == ATARAID_MAJOR && (dev_minor % 0x10 == 0)) {
2553                 dev->type = PED_DEVICE_ATARAID;
2554 +       } else if (dev_major == DASD_MAJOR && (dev_minor % 0x4 == 0)) {
2555 +               dev->type = PED_DEVICE_DASD;
2556         } else if (_is_i2o_major (dev_major) && (dev_minor % 0x10 == 0)) {
2557                 dev->type = PED_DEVICE_I2O;
2558         } else if (_is_cpqarray_major (dev_major) && (dev_minor % 0x10 == 0)) {
2559 @@ -363,6 +370,14 @@
2560         if (ioctl (arch_specific->fd, BLKSSZGET, &sector_size))
2561                 return PED_SECTOR_SIZE;
2562  
2563 +       /*
2564 +        * We return PED_SECTOR_SIZE, cause, we do not want to fiddle around with b0rken
2565 +        * parted and kernel for DASDs!!
2566 +        */
2567 +       if(dev->type == PED_DEVICE_DASD) {
2568 +               return PED_SECTOR_SIZE;
2569 +       }
2570 +
2571         if (sector_size != PED_SECTOR_SIZE) {
2572                 if (ped_exception_throw (
2573                         PED_EXCEPTION_BUG,
2574 @@ -696,6 +711,44 @@
2575  }
2576  
2577  static int
2578 +init_dasd (PedDevice* dev, char* model_name)
2579 +{
2580 +       struct stat             dev_stat;
2581 +       PedExceptionOption      ex_status;
2582 +        int f, blksize = 0;
2583 +        dasd_information_t dasd_info;
2584 +        char *errstr = 0;
2585 +        struct hd_geometry geo;
2586 +
2587 +
2588 +       if (!_device_stat (dev, &dev_stat))
2589 +               goto error;
2590 +
2591 +       if (!ped_device_open (dev))
2592 +               goto error;
2593 +
2594 +       LinuxSpecific* arch_specific = LINUX_SPECIFIC (dev);
2595 +
2596 +       if (!_device_probe_geometry (dev)) 
2597 +         goto error_close_dev;
2598 +
2599 +       dev->model = strdup (model_name);
2600 +
2601 +       ped_device_close (dev);
2602 +       return 1;
2603 +
2604 +except:
2605 +        ped_exception_throw ( PED_EXCEPTION_ERROR,
2606 +                              PED_EXCEPTION_IGNORE_CANCEL,
2607 +                              errstr );
2608 +
2609 +error_close_dev:
2610 +       ped_device_close (dev);
2611 +error:
2612 +       return 0;
2613 +}
2614 +
2615 +static int
2616  init_generic (PedDevice* dev, char* model_name)
2617  {
2618         struct stat             dev_stat;
2619 @@ -719,8 +772,8 @@
2620                                 PED_EXCEPTION_WARNING,
2621                                 PED_EXCEPTION_IGNORE_CANCEL,
2622                                 _("Unable to determine geometry of "
2623 -                               "file/device.  You should not use Parted "
2624 -                               "unless you REALLY know what you're doing!"));
2625 +                               "file/device %s.  You should not use Parted "
2626 +                               "unless you REALLY know what you're doing!"), dev->path);
2627                 switch (ex_status) {
2628                         case PED_EXCEPTION_CANCEL:
2629                                 goto error_close_dev;
2630 @@ -795,6 +848,11 @@
2631                         goto error_free_arch_specific;
2632                 break;
2633  
2634 +       case PED_DEVICE_DASD:
2635 +               if (!init_dasd (dev, _("IBM S390 DASD drive")))
2636 +                       goto error_free_arch_specific;
2637 +               break;
2638 +
2639         case PED_DEVICE_CPQARRAY:
2640                 if (!init_generic (dev, _("Compaq Smart Array")))
2641                         goto error_free_arch_specific;
2642 @@ -1710,7 +1768,10 @@
2643                  * created.  Therefore, if using DevFS, we must get the kernel
2644                  * to re-read and grok the partition table.
2645                  */
2646 -               if (_have_blkpg () && !_have_devfs ()) {
2647 +               /* Work around kernel dasd problem so we really do a
2648 +                  BLKRRPART */
2649 +               if (disk->dev->type != PED_DEVICE_DASD &&
2650 +                   _have_blkpg () && !_have_devfs ()) {
2651                         if (_disk_sync_part_table (disk))
2652                                 return 1;
2653                 }
2654 diff -ruN --minimal parted-1.6.21.orig/libparted/vtoc.c parted-1.6.21/libparted/vtoc.c
2655 --- parted-1.6.21.orig/libparted/vtoc.c 1969-12-31 19:00:00.000000000 -0500
2656 +++ parted-1.6.21/libparted/vtoc.c      2005-01-21 15:00:40.454627663 -0500
2657 @@ -0,0 +1,1352 @@
2658 +#include "vtoc.h"
2659 +
2660 +#ifdef DEBUG_DASD
2661 +#define PDEBUG           fprintf(stderr, "%s:%d:%s\n", \
2662 +                        __FILE__,                              \
2663 +                        __LINE__,                              \
2664 +                        __PRETTY_FUNCTION__);
2665 +#else
2666 +#define PDEBUG
2667 +#endif
2668 +
2669 +#include <parted/parted.h>
2670 +
2671 +#include <libintl.h>
2672 +#if ENABLE_NLS
2673 +#  define _(String) dgettext (PACKAGE, String)
2674 +#else
2675 +#  define _(String) (String)
2676 +#endif /* ENABLE_NLS */
2677 +
2678 +static unsigned char EBCtoASC[256] =
2679 +{
2680 +/* 0x00  NUL   SOH   STX   ETX  *SEL    HT  *RNL   DEL */
2681 +       0x00, 0x01, 0x02, 0x03, 0x07, 0x09, 0x07, 0x7F,
2682 +/* 0x08  -GE  -SPS  -RPT    VT    FF    CR    SO    SI */
2683 +       0x07, 0x07, 0x07, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
2684 +/* 0x10  DLE   DC1   DC2   DC3  -RES   -NL    BS  -POC
2685 +                                -ENP  ->LF             */
2686 +       0x10, 0x11, 0x12, 0x13, 0x07, 0x0A, 0x08, 0x07,
2687 +/* 0x18  CAN    EM  -UBS  -CU1  -IFS  -IGS  -IRS  -ITB
2688 +                                                  -IUS */
2689 +       0x18, 0x19, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
2690 +/* 0x20  -DS  -SOS    FS  -WUS  -BYP    LF   ETB   ESC
2691 +                                -INP                   */
2692 +       0x07, 0x07, 0x1C, 0x07, 0x07, 0x0A, 0x17, 0x1B,
2693 +/* 0x28  -SA  -SFE   -SM  -CSP  -MFA   ENQ   ACK   BEL
2694 +                     -SW                               */ 
2695 +       0x07, 0x07, 0x07, 0x07, 0x07, 0x05, 0x06, 0x07,
2696 +/* 0x30 ----  ----   SYN   -IR   -PP  -TRN  -NBS   EOT */
2697 +       0x07, 0x07, 0x16, 0x07, 0x07, 0x07, 0x07, 0x04,
2698 +/* 0x38 -SBS   -IT  -RFF  -CU3   DC4   NAK  ----   SUB */
2699 +       0x07, 0x07, 0x07, 0x07, 0x14, 0x15, 0x07, 0x1A,
2700 +/* 0x40   SP   RSP           Ã¤              ----       */
2701 +       0x20, 0xFF, 0x83, 0x84, 0x85, 0xA0, 0x07, 0x86,
2702 +/* 0x48                      .     <     (     +     | */
2703 +       0x87, 0xA4, 0x9B, 0x2E, 0x3C, 0x28, 0x2B, 0x7C,
2704 +/* 0x50    &                                      ---- */
2705 +       0x26, 0x82, 0x88, 0x89, 0x8A, 0xA1, 0x8C, 0x07,
2706 +/* 0x58          ÃŸ     !     $     *     )     ;       */
2707 +       0x8D, 0xE1, 0x21, 0x24, 0x2A, 0x29, 0x3B, 0xAA,
2708 +/* 0x60    -     /  ----     Ã„  ----  ----  ----       */
2709 +       0x2D, 0x2F, 0x07, 0x8E, 0x07, 0x07, 0x07, 0x8F,
2710 +/* 0x68             ----     ,     %     _     >     ? */ 
2711 +       0x80, 0xA5, 0x07, 0x2C, 0x25, 0x5F, 0x3E, 0x3F,
2712 +/* 0x70  ---        ----  ----  ----  ----  ----  ---- */
2713 +       0x07, 0x90, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
2714 +/* 0x78    *     `     :     #     @     '     =     " */
2715 +       0x70, 0x60, 0x3A, 0x23, 0x40, 0x27, 0x3D, 0x22,
2716 +/* 0x80    *     a     b     c     d     e     f     g */
2717 +       0x07, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
2718 +/* 0x88    h     i              ----  ----  ----       */
2719 +       0x68, 0x69, 0xAE, 0xAF, 0x07, 0x07, 0x07, 0xF1,
2720 +/* 0x90    Â°     j     k     l     m     n     o     p */
2721 +       0xF8, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70,
2722 +/* 0x98    q     r                    ----        ---- */
2723 +       0x71, 0x72, 0xA6, 0xA7, 0x91, 0x07, 0x92, 0x07,
2724 +/* 0xA0          ~     s     t     u     v     w     x */
2725 +       0xE6, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
2726 +/* 0xA8    y     z              ----  ----  ----  ---- */
2727 +       0x79, 0x7A, 0xAD, 0xAB, 0x07, 0x07, 0x07, 0x07,
2728 +/* 0xB0    ^                    ----     Â§  ----       */
2729 +       0x5E, 0x9C, 0x9D, 0xFA, 0x07, 0x07, 0x07, 0xAC,
2730 +/* 0xB8       ----     [     ]  ----  ----  ----  ---- */
2731 +       0xAB, 0x07, 0x5B, 0x5D, 0x07, 0x07, 0x07, 0x07,
2732 +/* 0xC0    {     A     B     C     D     E     F     G */
2733 +       0x7B, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
2734 +/* 0xC8    H     I  ----           Ã¶              ---- */
2735 +       0x48, 0x49, 0x07, 0x93, 0x94, 0x95, 0xA2, 0x07,
2736 +/* 0xD0    }     J     K     L     M     N     O     P */
2737 +       0x7D, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50,
2738 +/* 0xD8    Q     R  ----           Ã¼                   */
2739 +       0x51, 0x52, 0x07, 0x96, 0x81, 0x97, 0xA3, 0x98,
2740 +/* 0xE0    \           S     T     U     V     W     X */
2741 +       0x5C, 0xF6, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
2742 +/* 0xE8    Y     Z        ----     Ã–  ----  ----  ---- */
2743 +       0x59, 0x5A, 0xFD, 0x07, 0x99, 0x07, 0x07, 0x07,
2744 +/* 0xF0    0     1     2     3     4     5     6     7 */
2745 +       0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
2746 +/* 0xF8    8     9  ----  ----     Ãœ  ----  ----  ---- */
2747 +       0x38, 0x39, 0x07, 0x07, 0x9A, 0x07, 0x07, 0x07
2748 +};
2749 +
2750 +static unsigned char ASCtoEBC[256] =
2751 +{
2752 +    /*00  NL    SH    SX    EX    ET    NQ    AK    BL */
2753 +       0x00, 0x01, 0x02, 0x03, 0x37, 0x2D, 0x2E, 0x2F,
2754 +    /*08  BS    HT    LF    VT    FF    CR    SO    SI */
2755 +       0x16, 0x05, 0x15, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
2756 +    /*10  DL    D1    D2    D3    D4    NK    SN    EB */
2757 +       0x10, 0x11, 0x12, 0x13, 0x3C, 0x15, 0x32, 0x26,
2758 +    /*18  CN    EM    SB    EC    FS    GS    RS    US */
2759 +       0x18, 0x19, 0x3F, 0x27, 0x1C, 0x1D, 0x1E, 0x1F,
2760 +    /*20  SP     !     "     #     $     %     &     ' */
2761 +       0x40, 0x5A, 0x7F, 0x7B, 0x5B, 0x6C, 0x50, 0x7D,
2762 +    /*28   (     )     *     +     ,     -    .      / */
2763 +       0x4D, 0x5D, 0x5C, 0x4E, 0x6B, 0x60, 0x4B, 0x61,
2764 +    /*30   0     1     2     3     4     5     6     7 */
2765 +       0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
2766 +    /*38   8     9     :     ;     <     =     >     ? */
2767 +       0xF8, 0xF9, 0x7A, 0x5E, 0x4C, 0x7E, 0x6E, 0x6F,
2768 +    /*40   @     A     B     C     D     E     F     G */
2769 +       0x7C, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
2770 +    /*48   H     I     J     K     L     M     N     O */
2771 +       0xC8, 0xC9, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6,
2772 +    /*50   P     Q     R     S     T     U     V     W */
2773 +       0xD7, 0xD8, 0xD9, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6,
2774 +    /*58   X     Y     Z     [     \     ]     ^     _ */
2775 +       0xE7, 0xE8, 0xE9, 0xAD, 0xE0, 0xBD, 0x5F, 0x6D,
2776 +    /*60   `     a     b     c     d     e     f     g */
2777 +       0x79, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
2778 +    /*68   h     i     j     k     l     m     n     o */
2779 +       0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96,
2780 +    /*70   p     q     r     s     t     u     v     w */
2781 +       0x97, 0x98, 0x99, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6,
2782 +    /*78   x     y     z     {     |     }     ~    DL */
2783 +       0xA7, 0xA8, 0xA9, 0xC0, 0x4F, 0xD0, 0xA1, 0x07,
2784 +       0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
2785 +       0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
2786 +       0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
2787 +       0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
2788 +       0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
2789 +       0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
2790 +       0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
2791 +       0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
2792 +       0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
2793 +       0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
2794 +       0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
2795 +       0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
2796 +       0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
2797 +       0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
2798 +       0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
2799 +       0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xFF
2800 +};
2801 +
2802 +enum failure {unable_to_open,
2803 +             unable_to_seek,
2804 +             unable_to_write,
2805 +             unable_to_read};
2806 +
2807 +static char buffer[85];
2808 +
2809 +/*
2810 + *
2811 + */
2812 +static void 
2813 +vtoc_error(enum failure why, char *s1, char *s2) 
2814 +{
2815 +       PDEBUG
2816 +        char    error[LINE_LENGTH];
2817 +
2818 +       switch (why) 
2819 +       {
2820 +       case unable_to_open:
2821 +               sprintf(error, _("%s opening device '%s' failed.\n%s\n"),
2822 +                       VTOC_ERROR, s1, s2);
2823 +               break;
2824 +       case unable_to_seek:
2825 +               sprintf(error, _("%s seeking device '%s' failed.\n%s\n"),
2826 +                       VTOC_ERROR, s1, s2);
2827 +               break;
2828 +       case unable_to_write:
2829 +               sprintf(error, _("%s writing to device '%s' failed,\n%s\n"),
2830 +                       VTOC_ERROR, s1, s2);
2831 +               break;
2832 +       case unable_to_read:
2833 +               sprintf(error, _("%s reading from device '%s' failed.\n%s\n"),
2834 +                       VTOC_ERROR, s1, s2);
2835 +               break;
2836 +       default: sprintf(error, _("Fatal error\n"));
2837 +       }
2838 +
2839 +        ped_exception_throw(PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL, error);
2840 +}
2841 +
2842 +
2843 +/*
2844 + *
2845 + */
2846 +char * 
2847 +vtoc_ebcdic_enc (char source[LINE_LENGTH],
2848 +                char target[LINE_LENGTH],
2849 +                int l) 
2850 +{
2851 +       PDEBUG
2852 +        int i;
2853 +
2854 +       for (i = 0; i < l; i++) 
2855 +               target[i]=ASCtoEBC[(unsigned char)(source[i])];
2856 +
2857 +       return target;
2858 +}
2859 +
2860 +
2861 +/*
2862 + *
2863 + */
2864 +char * 
2865 +vtoc_ebcdic_dec (char source[LINE_LENGTH],
2866 +                char target[LINE_LENGTH],
2867 +                int l) 
2868 +{
2869 +       PDEBUG
2870 +        int i;
2871 +
2872 +       for (i = 0; i < l; i++) 
2873 +               target[i]=EBCtoASC[(unsigned char)(source[i])];
2874 +
2875 +       return target;
2876 +}
2877 +
2878 +
2879 +/*
2880 + *
2881 + */
2882 +void 
2883 +vtoc_set_extent (extent_t *ext,
2884 +                u_int8_t typeind,
2885 +                u_int8_t seqno,
2886 +                cchh_t *lower,
2887 +                cchh_t *upper) 
2888 +{ 
2889 +       PDEBUG
2890 +        ext->typeind = typeind;
2891 +        ext->seqno   = seqno;
2892 +        memcpy(&ext->llimit,lower,sizeof(cchh_t));
2893 +        memcpy(&ext->ulimit,upper,sizeof(cchh_t));
2894 +}
2895 +
2896 +
2897 +/*
2898 + *
2899 + */
2900 +void 
2901 +vtoc_set_cchh (cchh_t *addr,
2902 +               u_int16_t cc,
2903 +               u_int16_t hh) 
2904 +{
2905 +       PDEBUG
2906 +        addr->cc = cc;
2907 +       addr->hh = hh;
2908 +}
2909 +
2910 +
2911 +/*
2912 + *
2913 + */
2914 +static void 
2915 +vtoc_set_ttr (ttr_t *addr,
2916 +              u_int16_t tt,
2917 +              u_int8_t r) 
2918 +{
2919 +       PDEBUG
2920 +        addr->tt = tt;
2921 +       addr->r = r;
2922 +}
2923 +
2924 +
2925 +/*
2926 + *
2927 + */
2928 +void 
2929 +vtoc_set_cchhb (cchhb_t *addr,
2930 +               u_int16_t cc,
2931 +               u_int16_t hh,
2932 +               u_int8_t b) 
2933 +{
2934 +       PDEBUG
2935 +        addr->cc = cc;
2936 +        addr->hh = hh;
2937 +        addr->b = b;
2938 +}
2939 +
2940 +
2941 +/*
2942 + *
2943 + */
2944 +void 
2945 +vtoc_set_date (
2946 +        labeldate_t * d,
2947 +       u_int8_t year,
2948 +       u_int16_t day) 
2949 +{
2950 +       PDEBUG
2951 +        d->year = year;
2952 +        d->day = day;
2953 +}
2954 +
2955 +
2956 +/*
2957 + * initializes the volume label with EBCDIC spaces
2958 + */
2959 +void
2960 +vtoc_volume_label_init (volume_label_t *vlabel)
2961 +{
2962 +       PDEBUG
2963 +       sprintf(buffer, "%84s", " ");
2964 +       vtoc_ebcdic_enc(buffer, buffer, 84);    
2965 +       strncpy(vlabel->volkey, buffer, 84);
2966 +}
2967 +
2968 +
2969 +/*
2970 + * reads the volume label from dasd
2971 + */
2972 +int 
2973 +vtoc_read_volume_label (
2974 +        int f,
2975 +        unsigned long vlabel_start,
2976 +        volume_label_t *vlabel) 
2977 +{
2978 +       PDEBUG
2979 +       int rc;
2980 +
2981 +       if (lseek(f, vlabel_start, SEEK_SET) == -1) 
2982 +       {
2983 +               vtoc_error(unable_to_seek, "vtoc_read_volume_label",
2984 +                          "Could not read volume label.");
2985 +               return 1;
2986 +       }
2987 +
2988 +       rc = read(f, vlabel, sizeof(volume_label_t));
2989 +       if (rc != sizeof(volume_label_t)) 
2990 +       {
2991 +               vtoc_error(unable_to_read, "vtoc_read_volume_label",
2992 +                          "Could not read volume label.");
2993 +               return 1;
2994 +       }
2995 +
2996 +       return 0;
2997 +}
2998 +
2999 +
3000 +/*
3001 + * writes the volume label to dasd
3002 + */
3003 +int 
3004 +vtoc_write_volume_label (
3005 +        int f,
3006 +       unsigned long vlabel_start,
3007 +       volume_label_t *vlabel) 
3008 +{
3009 +       PDEBUG
3010 +        int rc;
3011 +
3012 +       if (lseek(f, vlabel_start, SEEK_SET) == -1) 
3013 +       {
3014 +               vtoc_error(unable_to_seek, "vtoc_write_volume_label",
3015 +                          "Could not write volume label.");
3016 +       }
3017 +
3018 +       rc = write(f, vlabel, sizeof(volume_label_t)); 
3019 +       if (rc != sizeof(volume_label_t)) 
3020 +       {
3021 +               vtoc_error(unable_to_write, "vtoc_write_volume_label",
3022 +                          "Could not write volume label.");
3023 +       }
3024 +       return 0;
3025 +}
3026 +
3027 +
3028 +/*
3029 + * takes a string as input, converts it to uppercase, translates
3030 + * it to EBCDIC and fills it up with spaces before it copies it
3031 + * as volume serial to the volume label
3032 + */
3033 +void
3034 +vtoc_volume_label_set_volser (
3035 +       volume_label_t *vlabel, 
3036 +       char *volser)
3037 +{
3038 +       PDEBUG
3039 +       int j, i = strlen(volser);
3040 +       char s[VOLSER_LENGTH + 1];
3041 +
3042 +       strcpy(s, "      ");
3043 +       vtoc_ebcdic_enc(s, s, VOLSER_LENGTH);
3044 +       strncpy(vlabel->volid, s, VOLSER_LENGTH);
3045 +
3046 +       if (i > VOLSER_LENGTH) i = VOLSER_LENGTH;
3047 +
3048 +       strncpy(s, volser, i);
3049 +       for (j=0; j<i; j++) {
3050 +               s[j] = toupper(s[j]);
3051 +       }
3052 +
3053 +       s[VOLSER_LENGTH] = 0x00;
3054 +       vtoc_ebcdic_enc(s, s, i);
3055 +       strncpy(vlabel->volid, s, i);
3056 +
3057 +       return;
3058 +}
3059 +
3060 +
3061 +/*
3062 + * returns the volume serial number right after it is translated 
3063 + * to ASCII
3064 + */
3065 +char *
3066 +vtoc_volume_label_get_volser (
3067 +       volume_label_t *vlabel,
3068 +       char *volser)
3069 +{
3070 +       PDEBUG
3071 +       vtoc_ebcdic_dec(vlabel->volid, volser, VOLSER_LENGTH);
3072 +
3073 +       return volser;
3074 +}
3075 +
3076 +
3077 +/*
3078 + * sets the volume label key right after
3079 + * it has been translated to EBCDIC
3080 + */
3081 +void
3082 +vtoc_volume_label_set_key (
3083 +        volume_label_t *vlabel,
3084 +        char *key)
3085 +{
3086 +       PDEBUG
3087 +        char s[4];
3088
3089 +        vtoc_ebcdic_enc(key, s, 4);
3090 +        strncpy(vlabel->volkey, s, 4);
3091
3092 +        return;
3093 +}                
3094 +
3095 +
3096 +/*
3097 + * sets the volume label identifier right
3098 + * after it has been translated to EBCDIC
3099 + */
3100 +void
3101 +vtoc_volume_label_set_label (
3102 +       volume_label_t *vlabel,
3103 +       char *lbl)
3104 +{
3105 +       PDEBUG
3106 +       char s[4];
3107 +
3108 +       vtoc_ebcdic_enc(lbl, s, 4);
3109 +       strncpy(vlabel->vollbl, s, 4);
3110 +
3111 +       return;
3112 +}
3113 +
3114 +
3115 +/*
3116 + * returns the volume label key = the label identifier
3117 + * right after it has been translated to ASCII
3118 + */
3119 +char *
3120 +vtoc_volume_label_get_label (
3121 +       volume_label_t *vlabel,
3122 +       char *lbl)
3123 +{
3124 +       PDEBUG
3125 +       vtoc_ebcdic_dec(vlabel->vollbl, lbl, 4);
3126 +
3127 +       return lbl;
3128 +}
3129 +
3130 +
3131 +/*
3132 + * reads either a format4 label or a format1 label
3133 + * from the specified position
3134 + */
3135 +void 
3136 +vtoc_read_label (int f,
3137 +                unsigned long position,
3138 +                format1_label_t *f1,
3139 +                format4_label_t *f4,
3140 +                format5_label_t *f5,
3141 +                format7_label_t *f7) 
3142 +{        
3143 +       PDEBUG
3144 +       int t;
3145 +
3146 +        if (lseek(f, position, SEEK_SET) == -1) 
3147 +       {
3148 +               vtoc_error(unable_to_seek, "vtoc_read_label",
3149 +                          _("Could not read VTOC labels."));
3150 +        }
3151 +
3152 +       if (f1 != NULL)
3153 +       {
3154 +               t = sizeof(format1_label_t);
3155 +               if (read(f, f1, t) != t) 
3156 +               {
3157 +                       vtoc_error(unable_to_read, "vtoc_read_label",
3158 +                                  _("Could not read VTOC FMT1 DSCB."));
3159 +               }
3160 +       }
3161 +
3162 +       if (f4 != NULL)
3163 +       {
3164 +               t = sizeof(format4_label_t);
3165 +               if (read(f, f4, t) != t) 
3166 +               {
3167 +                       vtoc_error(unable_to_read, "vtoc_read_label",
3168 +                                  _("Could not read VTOC FMT4 DSCB."));
3169 +               }
3170 +       }
3171 +
3172 +        if (f5 != NULL)
3173 +       {
3174 +               t = sizeof(format5_label_t);
3175 +                if (read(f, f5, t) != t)
3176 +                {
3177 +                        vtoc_error(unable_to_read, "vtoc_read_label",
3178 +                                   _("Could not read VTOC FMT5 DSCB."));
3179 +                }
3180 +       }
3181 +
3182 +       if (f7 != NULL)
3183 +       {
3184 +               t = sizeof(format7_label_t);
3185 +               if (read(f, f7, t) != t) 
3186 +               {
3187 +                       vtoc_error(unable_to_read, "vtoc_read_label",
3188 +                                  _("Could not read VTOC FMT7 DSCB."));
3189 +               }
3190 +       }
3191 +}
3192 +
3193 +
3194 +/*
3195 + * writes either a FMT1, FMT4 or FMT5 label
3196 + * to the specified position
3197 + */
3198 +void
3199 +vtoc_write_label (int f,
3200 +                 unsigned long position,
3201 +                 format1_label_t *f1, 
3202 +                 format4_label_t *f4,
3203 +                 format5_label_t *f5,
3204 +                 format7_label_t *f7)
3205 +{
3206 +       PDEBUG
3207 +       int t;
3208 +
3209 +        if (lseek(f, position, SEEK_SET) == -1) 
3210 +       {
3211 +               vtoc_error(unable_to_seek, "vtoc_write_label",
3212 +                          _("Could not write VTOC labels."));
3213 +        }
3214 +
3215 +       if (f1 != NULL)
3216 +       {
3217 +               t = sizeof(format1_label_t);
3218 +               if (write(f, f1, t) != t) 
3219 +               {
3220 +                       vtoc_error(unable_to_write, "vtoc_write_label",
3221 +                                  _("Could not write VTOC FMT1 DSCB."));
3222 +               }
3223 +       }
3224 +
3225 +       if (f4 != NULL)
3226 +       {
3227 +               t = sizeof(format4_label_t);
3228 +               if (write(f, f4, t) != t) 
3229 +               {
3230 +                       vtoc_error(unable_to_write, "vtoc_write_label",
3231 +                                  _("Could not write VTOC FMT4 DSCB."));
3232 +               }
3233 +       }
3234 +
3235 +       if (f5 != NULL)
3236 +       {
3237 +               t = sizeof(format5_label_t);
3238 +               if (write(f, f5, t) != t) 
3239 +               {
3240 +                       vtoc_error(unable_to_write, "vtoc_write_label",
3241 +                                  _("Could not write VTOC FMT5 DSCB."));
3242 +               }
3243 +       }
3244 +
3245 +       if (f7 != NULL)
3246 +       {
3247 +               t = sizeof(format7_label_t);
3248 +               if (write(f, f7, t) != t) 
3249 +               {
3250 +                       vtoc_error(unable_to_write, "vtoc_write_label",
3251 +                                  _("Could not write VTOC FMT7 DSCB."));
3252 +               }
3253 +       }
3254 +
3255 +}
3256 +
3257 +
3258 +/*
3259 + * initializes a format4 label
3260 + */
3261 +void 
3262 +vtoc_init_format4_label (
3263 +       format4_label_t    *f4,
3264 +       unsigned int usable_partitions,
3265 +       unsigned int cylinders,
3266 +       unsigned int tracks,
3267 +       unsigned int blocks,
3268 +       unsigned int blksize,
3269 +       u_int16_t dev_type) 
3270 +{
3271 +       PDEBUG
3272 +       int i;
3273 +
3274 +       cchh_t lower = {VTOC_START_CC, VTOC_START_HH};
3275 +       cchh_t upper = {VTOC_START_CC, VTOC_START_HH};
3276 +
3277 +       for (i=0; i<44; i++) f4->DS4KEYCD[i] = 0x04;
3278 +        f4->DS4IDFMT = 0xf4;
3279 +       vtoc_set_cchhb(&f4->DS4HPCHR, 0x0000, 0x0000, 0x00);
3280 +        f4->DS4DSREC = blocks - 2;
3281 +       /* free space starts right behind VTOC
3282 +          vtoc_set_cchh(&f4->DS4HCCHH, VTOC_START_CC, VTOC_START_HH + 1);*/
3283 +        vtoc_set_cchh(&f4->DS4HCCHH, 0x0000, 0x0000);
3284 +        f4->DS4NOATK = 0x0000;
3285 +        f4->DS4VTOCI = 0x00;
3286 +        f4->DS4NOEXT = 0x01;
3287 +        f4->DS4SMSFG = 0x00;
3288 +        f4->DS4DEVAC = 0x00;
3289 +
3290 +        /* -- begin f4->DS4DEVCT -- */
3291 +        f4->DS4DEVCT.DS4DSCYL = cylinders;
3292 +        f4->DS4DEVCT.DS4DSTRK = tracks;
3293 +
3294 +       switch (dev_type)
3295 +       {
3296 +       case DASD_3380_TYPE:
3297 +               f4->DS4DEVCT.DS4DEVTK = DASD_3380_VALUE;
3298 +               break;
3299 +       case DASD_3390_TYPE:
3300 +               f4->DS4DEVCT.DS4DEVTK = DASD_3390_VALUE;
3301 +               break;
3302 +       case DASD_9345_TYPE:
3303 +               f4->DS4DEVCT.DS4DEVTK = DASD_9345_VALUE;
3304 +               break;
3305 +        default:
3306 +               f4->DS4DEVCT.DS4DEVTK = blocks * blksize;;
3307 +        }
3308 +
3309 +
3310 +        f4->DS4DEVCT.DS4DEVI  = 0x00;
3311 +        f4->DS4DEVCT.DS4DEVL  = 0x00;
3312 +        f4->DS4DEVCT.DS4DEVK  = 0x00;
3313 +        f4->DS4DEVCT.DS4DEVFG = 0x30;
3314 +        f4->DS4DEVCT.DS4DEVTL = 0x0000;
3315 +        f4->DS4DEVCT.DS4DEVDT = blocks;
3316 +        f4->DS4DEVCT.DS4DEVDB = 0x00;
3317 +        /* -- end f4->DS4DEVCT -- */
3318 +
3319 +       bzero(f4->DS4AMTIM, sizeof(f4->DS4AMTIM));
3320 +       bzero(f4->DS4AMCAT, sizeof(f4->DS4AMCAT));
3321 +       bzero(f4->DS4R2TIM, sizeof(f4->DS4R2TIM));
3322 +       bzero(f4->res1, sizeof(f4->res1));
3323 +       bzero(f4->DS4F6PTR, sizeof(f4->DS4F6PTR));
3324 +
3325 +        /* -- begin f4lbl->DS4VTOCE -- */
3326 +       vtoc_set_extent(&f4->DS4VTOCE, 0x01, 0x00, &lower, &upper);
3327 +        /* -- end f4lbl->DS4VTOCE -- */
3328 +
3329 +       bzero(f4->res2, sizeof(f4->res2));
3330 +       f4->DS4EFLVL = 0x00;
3331 +       bzero(&f4->DS4EFPTR, sizeof(f4->DS4EFPTR));
3332 +       bzero(f4->res3, sizeof(f4->res3));
3333 +}
3334 +
3335 +
3336 +/*
3337 + * initializes a format5 label
3338 + */
3339 +void
3340 +vtoc_init_format5_label (format5_label_t *f5) 
3341 +{
3342 +       PDEBUG
3343 +       int i;
3344 +
3345 +       bzero(f5, sizeof(format5_label_t));
3346 +       for (i=0; i<4; i++) f5->DS5KEYID[i] = 0x05;
3347 +       f5->DS5FMTID = 0xf5;
3348 +}
3349 +
3350 +
3351 +/*
3352 + * initializes a format7 label
3353 + */
3354 +void
3355 +vtoc_init_format7_label (format7_label_t *f7) 
3356 +{
3357 +       PDEBUG
3358 +       int i;
3359 +
3360 +       bzero(f7, sizeof(format7_label_t));
3361 +       for (i=0; i<4; i++) f7->DS7KEYID[i] = 0x07;
3362 +       f7->DS7FMTID = 0xf7;
3363 +}
3364 +
3365 +
3366 +/*
3367 + * initializes a format1 label
3368 + */
3369 +void 
3370 +vtoc_init_format1_label (
3371 +       char *volid,
3372 +        unsigned int blksize,
3373 +       extent_t *part_extent,
3374 +       format1_label_t *f1) 
3375 +{
3376 +       PDEBUG
3377 +        struct tm * creatime;
3378 +       time_t t;
3379 +       char str[80];
3380 +
3381 +       /* get actual date */
3382 +       t = time(NULL);
3383 +       creatime = gmtime(&t);
3384 +
3385 +       bzero(f1->DS1DSNAM, sizeof(f1->DS1DSNAM));
3386 +       sprintf(str, "PART    .NEW                                ");
3387 +       vtoc_ebcdic_enc(str, str, 44);
3388 +       strncpy(f1->DS1DSNAM, str, 44);
3389 +       f1->DS1FMTID = 0xf1;
3390 +       strncpy(f1->DS1DSSN, "      ", 6);
3391 +       f1->DS1VOLSQ = 0x0001;
3392 +
3393 +       vtoc_set_date(&f1->DS1CREDT,
3394 +                      (u_int8_t) creatime->tm_year,
3395 +                     (u_int16_t) creatime->tm_yday);
3396 +       /* expires never - 99 365 */
3397 +        vtoc_set_date(&f1->DS1EXPDT,
3398 +                     0x63,
3399 +                      0x016D);
3400 +       f1->DS1NOEPV = 0x01;
3401 +       f1->DS1NOBDB = 0x00;
3402 +        f1->DS1FLAG1 = 0x00;
3403 +       vtoc_ebcdic_enc("IBM LINUX    ", str, 13);
3404 +       strncpy(f1->DS1SYSCD, str, 13);
3405 +        vtoc_set_date(&f1->DS1REFD,
3406 +                     (u_int8_t) creatime->tm_year,
3407 +                      (u_int16_t) creatime->tm_yday);
3408 +        f1->DS1SMSFG = 0x00;
3409 +        f1->DS1SCXTF = 0x00;
3410 +        f1->DS1SCXTV = 0x0000;
3411 +        f1->DS1DSRG1 = 0x00;
3412 +        f1->DS1DSRG2 = 0x00;
3413 +        f1->DS1RECFM = 0x88;
3414 +        f1->DS1OPTCD = 0x00;
3415 +        f1->DS1BLKL  = blksize;
3416 +        f1->DS1LRECL = blksize;
3417 +        f1->DS1KEYL  = 0x00;
3418 +        f1->DS1RKP   = 0x0000;
3419 +        f1->DS1DSIND = 0x80; /* last volume for this dataset */
3420 +        f1->DS1SCAL1 = 0x80;
3421 +        bzero(&f1->DS1SCAL3, sizeof(f1->DS1SCAL3));
3422 +       vtoc_set_ttr(&f1->DS1LSTAR,
3423 +                    0x0000,
3424 +                    0x00);
3425 +       f1->DS1TRBAL = 0x00;
3426 +       bzero(&f1->res1, sizeof(f1->res1));
3427 +        memcpy(&f1->DS1EXT1,
3428 +               part_extent,
3429 +               sizeof(extent_t));
3430 +        bzero(&f1->DS1EXT2, sizeof(extent_t));
3431 +        bzero(&f1->DS1EXT3, sizeof(extent_t));
3432 +        vtoc_set_cchhb(&f1->DS1PTRDS,
3433 +                       0x0000, 0x0000, 0x00);
3434 +}
3435 +
3436 +
3437 +/*
3438 + * do some updates to the VTOC format4 label
3439 + */
3440 +void 
3441 +vtoc_update_format4_label (
3442 +       format4_label_t *f4,
3443 +       cchhb_t *highest_f1,
3444 +       u_int16_t unused_update) 
3445 +{
3446 +       PDEBUG
3447 +       /* update highest address of a format 1 label */
3448 +       memcpy(&f4->DS4HPCHR, highest_f1, sizeof(cchhb_t));
3449 +
3450 +       /* update unused DSCB count */
3451 +       f4->DS4DSREC = unused_update;
3452 +}
3453 +
3454 +
3455 +/*
3456 + * reorganizes all extents within a FMT5 label
3457 + */
3458 +static void
3459 +vtoc_reorganize_FMT5_extents (format5_label_t *f5) 
3460 +{
3461 +       PDEBUG
3462 +       ds5ext_t *ext, *last, tmp;
3463 +       int i, j;
3464 +
3465 +       for (i=0; i<26; i++)
3466 +       {
3467 +               if (i==0) 
3468 +                       last = &f5->DS5AVEXT; 
3469 +               else if ((i > 0) && (i < 8))
3470 +                       last = &f5->DS5EXTAV[i-1];
3471 +               else
3472 +                       last = &f5->DS5MAVET[i-8];
3473 +
3474 +               for (j=i; j<26; j++)
3475 +               {
3476 +                       if (j==0) 
3477 +                               ext = &f5->DS5AVEXT; 
3478 +                       else if ((j > 0) && (j < 8))
3479 +                               ext = &f5->DS5EXTAV[j-1];
3480 +                       else
3481 +                               ext = &f5->DS5MAVET[j-8];
3482 +
3483 +                       if (((ext->t > 0) && (last->t == 0)) || 
3484 +                           ((ext->t > 0) && (ext->t < last->t)))
3485 +                       {
3486 +                               tmp.t  = last->t;
3487 +                               tmp.fc = last->fc;
3488 +                               tmp.ft = last->ft;
3489 +                               last->t  = ext->t;
3490 +                               last->fc = ext->fc;
3491 +                               last->ft = ext->ft;
3492 +                               ext->t  = tmp.t;
3493 +                               ext->fc = tmp.fc;
3494 +                               ext->ft = tmp.ft;
3495 +                       }
3496 +               }
3497 +       }
3498 +}
3499 +
3500 +
3501 +/*
3502 + * add a free space extent description to the VTOC FMT5 DSCB
3503 + */
3504 +void 
3505 +vtoc_update_format5_label_add (format5_label_t *f5,
3506 +                              int verbose,
3507 +                              int cyl,
3508 +                              int trk,
3509 +                              u_int16_t a, 
3510 +                              u_int16_t b, 
3511 +                              u_int8_t c) 
3512 +{
3513 +       PDEBUG
3514 +       ds5ext_t *ext = NULL, *tmp = NULL;
3515 +       int i;  
3516 +
3517 +       for (i=0; i<26; i++)
3518 +       {
3519 +               if (i==0) 
3520 +                       ext = &f5->DS5AVEXT; 
3521 +               else if ((i > 0) && (i < 8))
3522 +                       ext = &f5->DS5EXTAV[i-1];
3523 +               else
3524 +                       ext = &f5->DS5MAVET[i-8];
3525 +
3526 +               if (((a < ext->t) && (a + b*trk + c > ext->t)) || 
3527 +                   ((a > ext->t) && (ext->t + ext->fc*trk + ext->ft > a)))
3528 +               {
3529 +                       printf("BUG: overlapping free space extents " \
3530 +                              "in FMT5 DSCB!\nexiting...\n");
3531 +                       exit(1);
3532 +               }
3533 +
3534 +               if ((ext->t + ext->fc + ext->ft) == 0x0000)
3535 +               {
3536 +                       ext->t  = a;
3537 +                       ext->fc = b;
3538 +                       ext->ft = c;
3539 +                       tmp = ext;
3540 +                       if (verbose) 
3541 +                               printf("FMT5 add extent: " \
3542 +                                      "add new extent\n");
3543 +                       break;
3544 +               }
3545 +       }
3546 +
3547 +       if (tmp == NULL)
3548 +       {
3549 +               /* BUG: no free extent found */
3550 +               printf("BUG: no free FMT5 DSCB extent found!\nexiting...\n");
3551 +               exit(1);
3552 +       }
3553 +
3554 +       for (i=0; i<26; i++)
3555 +       {
3556 +               if (i==0)
3557 +                       ext = &f5->DS5AVEXT;
3558 +               else if ((i > 0) && (i < 8))
3559 +                       ext = &f5->DS5EXTAV[i-1];
3560 +               else
3561 +                       ext = &f5->DS5MAVET[i-8];
3562 +
3563 +               if ((ext->t + ext->fc + ext->ft) == 0x0000)
3564 +                       continue;
3565 +
3566 +               if ((ext->t + ext->fc*trk + ext->ft) == tmp->t)
3567 +               {
3568 +                       /* this extent precedes the new one */
3569 +                       ext->fc += (tmp->fc + (tmp->ft + ext->ft)/trk);
3570 +                       ext->ft = (tmp->ft + ext->ft) % trk;
3571 +                       bzero(tmp, sizeof(ds5ext_t));
3572 +                       tmp = ext;
3573 +                       if (verbose) 
3574 +                               printf("FMT5 add extent: " \
3575 +                                      "merge with predecessor\n");
3576 +                       i = -1;
3577 +                       continue;
3578 +               } 
3579 +
3580 +               if ((tmp->t + tmp->fc*trk + tmp->ft) == ext->t)
3581 +               {
3582 +                       /* this extent succeeds the new one */
3583 +                       ext->t = tmp->t;
3584 +                       ext->fc += (tmp->fc + (tmp->ft + ext->ft)/trk);
3585 +                       ext->ft = (tmp->ft + ext->ft) % trk;
3586 +                       bzero(tmp, sizeof(ds5ext_t));
3587 +                       tmp = ext;
3588 +                       if (verbose) 
3589 +                               printf("FMT5 add extent: " \
3590 +                                      "merge with successor\n");
3591 +                       i = -1;
3592 +                       continue;
3593 +               } 
3594 +       }
3595 +}
3596 +
3597 +
3598 +/*
3599 + * remove a free space extent description from the VTOC FMT5 DSCB
3600 + */
3601 +void 
3602 +vtoc_update_format5_label_del (format5_label_t *f5,
3603 +                              int verbose,
3604 +                              int cyl,
3605 +                              int trk,
3606 +                              u_int16_t a,
3607 +                              u_int16_t b,
3608 +                              u_int8_t c) 
3609 +{
3610 +       PDEBUG
3611 +       ds5ext_t *ext;
3612 +       int i, counter=0;
3613 +       
3614 +       for (i=0; i<26; i++)
3615 +       {
3616 +               if (i==0) 
3617 +                       ext = &f5->DS5AVEXT; 
3618 +               else if ((i > 0) && (i < 8))
3619 +                       ext = &f5->DS5EXTAV[i-1];
3620 +               else
3621 +                       ext = &f5->DS5MAVET[i-8];
3622 +
3623 +               if ((a == ext->t) && (b == ext->fc) && (c == ext->ft))
3624 +               {
3625 +                       /* fills up whole free space gap */
3626 +                       bzero(ext, sizeof(ds5ext_t));
3627 +                       if (verbose) 
3628 +                               printf("FMT5 del extent: fills whole gap\n");
3629 +                       counter++;
3630 +                       break;
3631 +               }
3632 +
3633 +               if ((a == ext->t) && ((b < ext->fc) || (c < ext->ft)))
3634 +               {
3635 +                       /* left-bounded in free space gap */
3636 +                       ext->t = ext->t + b*trk + c;
3637 +                       if (c > ext->ft)
3638 +                       {
3639 +                               ext->fc -= (b + 1);
3640 +                               ext->ft -= (c - trk);
3641 +                       }
3642 +                       else
3643 +                       {
3644 +                               ext->fc -= b;
3645 +                               ext->ft -= c;
3646 +                       }
3647 +                       if (verbose) 
3648 +                               printf("FMT5 del extent: left bounded\n");
3649 +                       counter++;
3650 +                       break;
3651 +               }
3652 +
3653 +               if ((ext->t < a) && 
3654 +                   ((ext->t + ext->fc*trk + ext->ft) == (a + b*trk + c)))
3655 +               {
3656 +                       /* right-bounded in free space gap */
3657 +                       if (c > ext->ft)
3658 +                       {
3659 +                               ext->fc -= (b + 1);
3660 +                               ext->ft -= (c - trk);
3661 +                       }
3662 +                       else
3663 +                       {
3664 +                               ext->fc -= b;
3665 +                               ext->ft -= c;
3666 +                       }
3667 +                       if (verbose) 
3668 +                               printf("FMT5 del extent: right bounded\n");
3669 +                       counter++;
3670 +                       break;
3671 +               }
3672 +
3673 +               if ((a > ext->t) &&
3674 +                       ((ext->t + ext->fc*trk + ext->ft) > (a + b*trk + c)))
3675 +               {
3676 +                       /* partition devides free space into 2 pieces */
3677 +                       u_int16_t x = a + b*trk + c;
3678 +                       u_int16_t w,y;
3679 +                       u_int8_t z;
3680 +
3681 +                       w = (ext->t + ext->fc*trk + ext->ft) - (a + b*trk + c);
3682 +                       y = w / trk;
3683 +                       z = w % trk;
3684 +
3685 +                       ext->fc = (a - ext->t) / trk;
3686 +                       ext->ft = (a - ext->t) % trk;
3687 +
3688 +                       vtoc_update_format5_label_add(f5, verbose, 
3689 +                                                     cyl, trk, x, y, z);
3690 +
3691 +                       if (verbose) 
3692 +                               printf("FMT5 del extent: 2 pieces\n");
3693 +                       counter++;
3694 +                       break;
3695 +               }
3696 +
3697 +               if ((a < ext->t) && (a + b*trk + c > ext->t) &&
3698 +                   (a + b*trk + c < ext->t + ext->fc*trk + ext->ft))
3699 +               {
3700 +                       printf("BUG: corresponding free space extent " \
3701 +                              "doesn't match free space currently shown " \
3702 +                              "in FMT5 DSCB!\nexiting...\n");
3703 +                       exit(1);
3704 +               }
3705 +               
3706 +               if ((a > ext->t) && (a < ext->t + ext->fc*trk + ext->ft) && 
3707 +                   (a + b*trk + c > ext->t + ext->fc*trk + ext->ft))
3708 +               {
3709 +                       printf("BUG: specified free space extent for " \
3710 +                              "deleting doesn't match free space " \
3711 +                              "currently shown in FMT5 DSCB!\n" \
3712 +                              "exiting...\n");
3713 +                       exit(1);
3714 +               }
3715 +       }
3716 +
3717 +       if (counter > 0) return;
3718 +
3719 +       printf("BUG: specified free space extent for " \
3720 +              "deleting not found in FMT5 DSCB!\n" \
3721 +              "exiting...\n");
3722 +       exit(1);
3723 +}
3724 +
3725 +
3726 +/*
3727 + * reorganizes all extents within a FMT7 label
3728 + */
3729 +static void
3730 +vtoc_reorganize_FMT7_extents (format7_label_t *f7) 
3731 +{
3732 +       PDEBUG
3733 +       ds7ext_t *ext, *last, tmp;
3734 +       int i, j;
3735 +
3736 +       for (i=0; i<16; i++)
3737 +       {
3738 +               if (i<5) 
3739 +                       last = &f7->DS7EXTNT[i]; 
3740 +               else 
3741 +                       last = &f7->DS7ADEXT[i-5];
3742 +
3743 +               for (j=i; j<16; j++)
3744 +               {
3745 +                       if (j<5) 
3746 +                               ext = &f7->DS7EXTNT[j]; 
3747 +                       else 
3748 +                               ext = &f7->DS7ADEXT[j-5];
3749 +
3750 +                       if (((ext->a > 0) && (last->a == 0)) || 
3751 +                           ((ext->a > 0) && (ext->a < last->a)))
3752 +                       {
3753 +                               tmp.a = last->a;
3754 +                               tmp.b = last->b;
3755 +                               last->a = ext->a;
3756 +                               last->b = ext->b;
3757 +                               ext->a = tmp.a;
3758 +                               ext->b = tmp.b;
3759 +                       }
3760 +               }
3761 +       }
3762 +}
3763 +
3764 +
3765 +/*
3766 + * add a free space extent description to the VTOC FMT7 DSCB
3767 + */
3768 +void 
3769 +vtoc_update_format7_label_add (format7_label_t *f7, int verbose, 
3770 +                              u_int32_t a, u_int32_t b) 
3771 +{
3772 +       PDEBUG
3773 +       ds7ext_t *ext = NULL, *tmp = NULL;
3774 +       int i;  
3775 +
3776 +       for (i=0; i<16; i++)
3777 +       {
3778 +               if (i<5) 
3779 +                       ext = &f7->DS7EXTNT[i]; 
3780 +               else 
3781 +                       ext = &f7->DS7ADEXT[i-5];
3782 +
3783 +               if (((a < ext->a) && (b > ext->a) && (b < ext->b)) || 
3784 +                   ((a > ext->a) && (a < ext->b) && (b > ext->b)))
3785 +               {
3786 +                       printf("BUG: overlapping free space extents " \
3787 +                              "in FMT7 DSCB!\nexiting...\n");
3788 +                       exit(1);
3789 +               }
3790 +
3791 +               if ((ext->a + ext->b) == 0x00000000)
3792 +               {
3793 +                       ext->a = a;
3794 +                       ext->b = b;
3795 +                       tmp = ext;
3796 +                       if (verbose) 
3797 +                               printf("FMT7 add extent: " \
3798 +                                      "add new extent\n");
3799 +                       break;
3800 +               }
3801 +       }
3802 +
3803 +       if (tmp == NULL)
3804 +       {
3805 +               /* BUG: no free extent found */
3806 +               printf("BUG: no free FMT7 DSCB extent found!\nexiting...\n");
3807 +               exit(1);
3808 +       }
3809 +
3810 +       for (i=0; i<16; i++)
3811 +       {
3812 +               if (i<5) 
3813 +                       ext = &f7->DS7EXTNT[i]; 
3814 +               else 
3815 +                       ext = &f7->DS7ADEXT[i-5];
3816 +
3817 +               if ((ext->a + ext->b) == 0x00000000)
3818 +                       continue;
3819 +
3820 +               if ((ext->b + 1) == tmp->a)
3821 +               {
3822 +                       /* this extent precedes the new one */
3823 +                       ext->b = tmp->b;
3824 +                       bzero(tmp, sizeof(ds7ext_t));
3825 +                       tmp = ext;
3826 +                       if (verbose) 
3827 +                               printf("FMT7 add extent: " \
3828 +                                      "merge with predecessor\n");
3829 +                       i = -1;
3830 +                       continue;
3831 +               } 
3832 +
3833 +               if (ext->a == (tmp->b + 1))
3834 +               {
3835 +                       /* this extent succeeds the new one */
3836 +                       ext->a = tmp->a;
3837 +                       bzero(tmp, sizeof(ds7ext_t));
3838 +                       tmp = ext;
3839 +                       if (verbose) 
3840 +                               printf("FMT7 add extent: " \
3841 +                                      "merge with successor\n");
3842 +                       i = -1;
3843 +                       continue;
3844 +               } 
3845 +       }
3846 +}
3847 +
3848 +
3849 +/*
3850 + * remove a free space extent description from the VTOC FMT7 DSCB
3851 + */
3852 +void 
3853 +vtoc_update_format7_label_del (format7_label_t *f7, int verbose, 
3854 +                              u_int32_t a, u_int32_t b) 
3855 +{
3856 +       PDEBUG
3857 +       ds7ext_t *ext;
3858 +       int i, counter=0;
3859 +       
3860 +       for (i=0; i<16; i++)
3861 +       {
3862 +               if (i<5) 
3863 +                       ext = &f7->DS7EXTNT[i]; 
3864 +               else 
3865 +                       ext = &f7->DS7ADEXT[i-5];
3866 +
3867 +               if ((a == ext->a) && (b == ext->b))
3868 +               {
3869 +                       /* fills up whole free space gap */
3870 +                       bzero(ext, sizeof(ds7ext_t));
3871 +                       if (verbose) 
3872 +                               printf("FMT7 del extent: " \
3873 +                                      "fills whole gap\n");
3874 +                       counter++;
3875 +                       break;
3876 +               }
3877 +
3878 +               if ((a == ext->a) && (b < ext->b))
3879 +               {
3880 +                       /* left-bounded in free space gap */
3881 +                       ext->a = b + 1;
3882 +                       if (verbose) 
3883 +                               printf("FMT7 add extent: " \
3884 +                                      "left-bounded\n");
3885 +                       counter++;
3886 +                       break;
3887 +               }
3888 +
3889 +               if ((a > ext->a) && (b == ext->b))
3890 +               {
3891 +                       /* right-bounded in free space gap */
3892 +                       ext->b = a - 1;
3893 +                       if (verbose) 
3894 +                               printf("FMT7 add extent: " \
3895 +                                      "right-bounded\n");
3896 +                       counter++;
3897 +                       break;
3898 +               }
3899 +
3900 +               if ((a > ext->a) && (b < ext->b))
3901 +               {
3902 +                       /* partition devides free space into 2 pieces */
3903 +                       vtoc_update_format7_label_add(f7, verbose, 
3904 +                                                     b+1, ext->b);
3905 +                       ext->b = a - 1;
3906 +                       if (verbose) 
3907 +                               printf("FMT7 add extent: " \
3908 +                                      "2 pieces\n");
3909 +                       counter++;
3910 +                       break;
3911 +               }
3912 +
3913 +               if (((a < ext->a) && (b > ext->a)) || ((a < ext->b) && (b > ext->b)))
3914 +               {
3915 +                       printf ("BUG: specified free space extent for deleting "
3916 +                               "doesn't match free space currently shown in "
3917 +                               "FMT7 DSCB!\nexiting...\n");
3918 +                       printf ("%d %d %d %d\n", a, b, ext->a, ext->b);
3919 +                       exit(1);
3920 +               }
3921 +       }
3922 +
3923 +       if (counter > 0) return;
3924 +
3925 +       printf("BUG: specified free space extent for " \
3926 +              "deleting not found in FMT7 DSCB!\n" \
3927 +              "exiting...\n");
3928 +       exit(1);
3929 +}
3930 +
3931 +
3932 +/*
3933 + *
3934 + */
3935 +void
3936 +vtoc_set_freespace(format4_label_t *f4,
3937 +                  format5_label_t *f5,
3938 +                  format7_label_t *f7,
3939 +                  char ch,
3940 +                  int verbose,
3941 +                  u_int32_t start,
3942 +                  u_int32_t stop,
3943 +                  int cyl,
3944 +                  int trk)
3945 +{
3946 +       PDEBUG
3947 +       if ((cyl * trk) > BIG_DISK_SIZE)
3948 +       {
3949 +               if (ch == '+')
3950 +               {
3951 +                       vtoc_update_format7_label_add(f7, verbose, 
3952 +                                                     start, stop);
3953 +               }
3954 +               else if (ch == '-')
3955 +               {
3956 +                       vtoc_update_format7_label_del(f7, verbose, 
3957 +                                                     start, stop);
3958 +               }
3959 +               else
3960 +               {
3961 +                       printf("BUG: syntax error in " \
3962 +                              "vtoc_set_freespace call\n");
3963 +               }
3964 +
3965 +               vtoc_reorganize_FMT7_extents (f7);
3966 +
3967 +               f4->DS4VTOCI = 0xa0;
3968 +               f4->DS4EFLVL = 0x07;
3969 +               vtoc_set_cchhb(&f4->DS4EFPTR, 0x0000, 0x0001, 0x03);
3970 +       }
3971 +       else
3972 +       {
3973 +               u_int16_t x,y;
3974 +               u_int8_t z;
3975 +
3976 +               x = (u_int16_t) start;
3977 +               y = (u_int16_t) ((stop - start + 1) / trk);
3978 +               z =  (u_int8_t) ((stop - start + 1) % trk);
3979 +
3980 +               if (ch == '+')
3981 +               {
3982 +                       vtoc_update_format5_label_add(f5, verbose,
3983 +                                                     cyl, trk,
3984 +                                                     x, y, z);
3985 +               }
3986 +               else if (ch == '-')
3987 +               {
3988 +                       vtoc_update_format5_label_del(f5, verbose, 
3989 +                                                     cyl, trk,
3990 +                                                     x, y, z);
3991 +               }
3992 +               else
3993 +               {
3994 +                       printf("BUG: syntax error in " \
3995 +                              "vtoc_set_freespace call\n");
3996 +               }
3997 +               vtoc_reorganize_FMT5_extents (f5);
3998 +       }
3999 +               
4000 +}
4001 +
4002 +
4003 +
4004 +
4005 +
4006 +
4007 +
4008 +
4009 +
4010 diff -ruN --minimal parted-1.6.21.orig/libparted/vtoc.h parted-1.6.21/libparted/vtoc.h
4011 --- parted-1.6.21.orig/libparted/vtoc.h 1969-12-31 19:00:00.000000000 -0500
4012 +++ parted-1.6.21/libparted/vtoc.h      2005-01-21 15:00:40.455627637 -0500
4013 @@ -0,0 +1,371 @@
4014 +/*
4015 + * File...........: s390-tools/dasdview/vtoc.h
4016 + * Author(s)......: Horst Hummel <horst.hummel@de.ibm.com>
4017 + * Bugreports.to..: <Linux390@de.ibm.com>
4018 + *
4019 + * This is a user-space copy of the kernel vtoc,h. 
4020 + * 
4021 + * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 2002
4022 + *
4023 + * History of changes (starts March 2002)
4024 + * 2002-03-12 initial
4025 + */
4026 +
4027 +#ifndef VTOC_H
4028 +#define VTOC_H
4029 +
4030 +#include <string.h>
4031 +#include <stdlib.h>
4032 +#include <stdio.h>
4033 +#include <errno.h>
4034 +#include <ctype.h>
4035 +#include <time.h>
4036 +#include <fcntl.h>
4037 +#include <unistd.h>
4038 +
4039 +#include <sys/stat.h>
4040 +#include <sys/ioctl.h>
4041 +
4042 +#define LINE_LENGTH 80
4043 +#define VTOC_START_CC 0x0
4044 +#define VTOC_START_HH 0x1
4045 +#define FIRST_USABLE_CYL 1
4046 +#define FIRST_USABLE_TRK 2
4047 +
4048 +#define DASD_3380_TYPE 13148
4049 +#define DASD_3390_TYPE 13200
4050 +#define DASD_9345_TYPE 37701
4051 +
4052 +#define DASD_3380_VALUE 0xbb60
4053 +#define DASD_3390_VALUE 0xe5a2
4054 +#define DASD_9345_VALUE 0xbc98
4055 +
4056 +#define VOLSER_LENGTH 6
4057 +#define BIG_DISK_SIZE 0x10000
4058 +
4059 +#define VTOC_ERROR "VTOC error:"
4060 +
4061 +
4062 +typedef struct ttr 
4063 +{
4064 +        u_int16_t tt;
4065 +        u_int8_t  r;
4066 +} __attribute__ ((packed)) ttr_t;
4067 +
4068 +typedef struct cchhb 
4069 +{
4070 +        u_int16_t cc;
4071 +        u_int16_t hh;
4072 +        u_int8_t b;
4073 +} __attribute__ ((packed)) cchhb_t;
4074 +
4075 +typedef struct cchh 
4076 +{
4077 +        u_int16_t cc;
4078 +        u_int16_t hh;
4079 +} __attribute__ ((packed)) cchh_t;
4080 +
4081 +typedef struct labeldate 
4082 +{
4083 +        u_int8_t  year;
4084 +        u_int16_t day;
4085 +} __attribute__ ((packed)) labeldate_t;
4086 +
4087 +
4088 +typedef struct volume_label 
4089 +{
4090 +        char volkey[4];         /* volume key = volume label                 */
4091 +       char vollbl[4];         /* volume label                              */
4092 +       char volid[6];          /* volume identifier                         */
4093 +       u_int8_t security;              /* security byte                             */
4094 +       cchhb_t vtoc;           /* VTOC address                              */
4095 +       char res1[5];           /* reserved                                  */
4096 +        char cisize[4];                /* CI-size for FBA,...                       */
4097 +                                /* ...blanks for CKD                         */
4098 +       char blkperci[4];       /* no of blocks per CI (FBA), blanks for CKD */
4099 +       char labperci[4];       /* no of labels per CI (FBA), blanks for CKD */
4100 +       char res2[4];           /* reserved                                  */
4101 +       char lvtoc[14];         /* owner code for LVTOC                      */
4102 +       char res3[29];          /* reserved                                  */
4103 +} __attribute__ ((packed)) volume_label_t;
4104 +
4105 +
4106 +typedef struct extent 
4107 +{
4108 +        u_int8_t  typeind;          /* extent type indicator                     */
4109 +        u_int8_t  seqno;            /* extent sequence number                    */
4110 +        cchh_t llimit;          /* starting point of this extent             */
4111 +        cchh_t ulimit;          /* ending point of this extent               */
4112 +} __attribute__ ((packed)) extent_t;
4113 +
4114 +
4115 +typedef struct dev_const 
4116 +{
4117 +        u_int16_t DS4DSCYL;           /* number of logical cyls                  */
4118 +        u_int16_t DS4DSTRK;           /* number of tracks in a logical cylinder  */
4119 +        u_int16_t DS4DEVTK;           /* device track length                     */
4120 +        u_int8_t  DS4DEVI;            /* non-last keyed record overhead          */
4121 +        u_int8_t  DS4DEVL;            /* last keyed record overhead              */
4122 +        u_int8_t  DS4DEVK;            /* non-keyed record overhead differential  */
4123 +        u_int8_t  DS4DEVFG;           /* flag byte                               */
4124 +        u_int16_t DS4DEVTL;           /* device tolerance                        */
4125 +        u_int8_t  DS4DEVDT;           /* number of DSCB's per track              */
4126 +        u_int8_t  DS4DEVDB;           /* number of directory blocks per track    */
4127 +} __attribute__ ((packed)) dev_const_t;
4128 +
4129 +
4130 +typedef struct format1_label 
4131 +{
4132 +       char  DS1DSNAM[44];       /* data set name                           */
4133 +       u_int8_t  DS1FMTID;           /* format identifier                       */
4134 +       char  DS1DSSN[6];         /* data set serial number                  */
4135 +       u_int16_t DS1VOLSQ;           /* volume sequence number                  */
4136 +       labeldate_t DS1CREDT;     /* creation date: ydd                      */
4137 +       labeldate_t DS1EXPDT;     /* expiration date                         */
4138 +       u_int8_t  DS1NOEPV;           /* number of extents on volume             */
4139 +        u_int8_t  DS1NOBDB;           /* no. of bytes used in last direction blk */
4140 +       u_int8_t  DS1FLAG1;           /* flag 1                                  */
4141 +       char  DS1SYSCD[13];       /* system code                             */
4142 +       labeldate_t DS1REFD;      /* date last referenced                    */
4143 +        u_int8_t  DS1SMSFG;           /* system managed storage indicators       */
4144 +        u_int8_t  DS1SCXTF;           /* sec. space extension flag byte          */
4145 +        u_int16_t DS1SCXTV;           /* secondary space extension value         */
4146 +        u_int8_t  DS1DSRG1;           /* data set organisation byte 1            */
4147 +        u_int8_t  DS1DSRG2;           /* data set organisation byte 2            */
4148 +       u_int8_t  DS1RECFM;           /* record format                           */
4149 +       u_int8_t  DS1OPTCD;           /* option code                             */
4150 +       u_int16_t DS1BLKL;            /* block length                            */
4151 +       u_int16_t DS1LRECL;           /* record length                           */
4152 +       u_int8_t  DS1KEYL;            /* key length                              */
4153 +       u_int16_t DS1RKP;             /* relative key position                   */
4154 +       u_int8_t  DS1DSIND;           /* data set indicators                     */
4155 +        u_int8_t  DS1SCAL1;           /* secondary allocation flag byte          */
4156 +       char DS1SCAL3[3];         /* secondary allocation quantity           */
4157 +       ttr_t DS1LSTAR;           /* last used track and block on track      */
4158 +       u_int16_t DS1TRBAL;           /* space remaining on last used track      */
4159 +        u_int16_t res1;               /* reserved                                */
4160 +       extent_t DS1EXT1;         /* first extent description                */
4161 +       extent_t DS1EXT2;         /* second extent description               */
4162 +       extent_t DS1EXT3;         /* third extent description                */
4163 +       cchhb_t DS1PTRDS;         /* possible pointer to f2 or f3 DSCB       */
4164 +} __attribute__ ((packed)) format1_label_t;
4165 +
4166 +
4167 +typedef struct format4_label 
4168 +{
4169 +       char  DS4KEYCD[44];       /* key code for VTOC labels: 44 times 0x04 */
4170 +        u_int8_t  DS4IDFMT;           /* format identifier                       */
4171 +       cchhb_t DS4HPCHR;         /* highest address of a format 1 DSCB      */
4172 +        u_int16_t DS4DSREC;           /* number of available DSCB's              */
4173 +        cchh_t DS4HCCHH;          /* CCHH of next available alternate track  */
4174 +        u_int16_t DS4NOATK;           /* number of remaining alternate tracks    */
4175 +        u_int8_t  DS4VTOCI;           /* VTOC indicators                         */
4176 +        u_int8_t  DS4NOEXT;           /* number of extents in VTOC               */
4177 +        u_int8_t  DS4SMSFG;           /* system managed storage indicators       */
4178 +        u_int8_t  DS4DEVAC;           /* number of alternate cylinders. 
4179 +                                     Subtract from first two bytes of 
4180 +                                     DS4DEVSZ to get number of usable
4181 +                                    cylinders. can be zero. valid
4182 +                                    only if DS4DEVAV on.                    */
4183 +        dev_const_t DS4DEVCT;     /* device constants                        */
4184 +        char DS4AMTIM[8];         /* VSAM time stamp                         */
4185 +        char DS4AMCAT[3];         /* VSAM catalog indicator                  */
4186 +        char DS4R2TIM[8];         /* VSAM volume/catalog match time stamp    */
4187 +        char res1[5];             /* reserved                                */
4188 +        char DS4F6PTR[5];         /* pointer to first format 6 DSCB          */
4189 +        extent_t DS4VTOCE;        /* VTOC extent description                 */
4190 +        char res2[10];            /* reserved                                */
4191 +        u_int8_t DS4EFLVL;            /* extended free-space management level    */
4192 +        cchhb_t DS4EFPTR;         /* pointer to extended free-space info     */
4193 +        char res3[9];             /* reserved                                */
4194 +} __attribute__ ((packed)) format4_label_t;
4195 +
4196 +
4197 +typedef struct ds5ext 
4198 +{
4199 +       u_int16_t t;                  /* RTA of the first track of free extent   */
4200 +       u_int16_t fc;                 /* number of whole cylinders in free ext.  */
4201 +       u_int8_t  ft;                 /* number of remaining free tracks         */
4202 +} __attribute__ ((packed)) ds5ext_t;
4203 +
4204 +
4205 +typedef struct format5_label 
4206 +{
4207 +       char DS5KEYID[4];         /* key identifier                          */
4208 +       ds5ext_t DS5AVEXT;        /* first available (free-space) extent.    */
4209 +       ds5ext_t DS5EXTAV[7];     /* seven available extents                 */
4210 +       u_int8_t DS5FMTID;            /* format identifier                       */
4211 +       ds5ext_t DS5MAVET[18];    /* eighteen available extents              */
4212 +       cchhb_t DS5PTRDS;         /* pointer to next format5 DSCB            */
4213 +} __attribute__ ((packed)) format5_label_t;
4214 +
4215 +
4216 +typedef struct ds7ext 
4217 +{
4218 +       u_int32_t a;                  /* starting RTA value                      */
4219 +       u_int32_t b;                  /* ending RTA value + 1                    */
4220 +} __attribute__ ((packed)) ds7ext_t;
4221 +
4222 +
4223 +typedef struct format7_label 
4224 +{
4225 +       char DS7KEYID[4];         /* key identifier                          */
4226 +       ds7ext_t DS7EXTNT[5];     /* space for 5 extent descriptions         */
4227 +       u_int8_t DS7FMTID;            /* format identifier                       */
4228 +       ds7ext_t DS7ADEXT[11];    /* space for 11 extent descriptions        */
4229 +       char res1[2];             /* reserved                                */
4230 +       cchhb_t DS7PTRDS;         /* pointer to next FMT7 DSCB               */
4231 +} __attribute__ ((packed)) format7_label_t;
4232 +
4233 +
4234 +char * vtoc_ebcdic_enc (
4235 +        char source[LINE_LENGTH],
4236 +        char target[LINE_LENGTH],
4237 +       int l);
4238 +char * vtoc_ebcdic_dec (
4239 +        char source[LINE_LENGTH],
4240 +       char target[LINE_LENGTH],
4241 +       int l);
4242 +void vtoc_set_extent (
4243 +        extent_t * ext,
4244 +        u_int8_t typeind,
4245 +        u_int8_t seqno,
4246 +        cchh_t * lower,
4247 +        cchh_t * upper);
4248 +void vtoc_set_cchh (
4249 +        cchh_t * addr,
4250 +       u_int16_t cc,
4251 +       u_int16_t hh);
4252 +void vtoc_set_cchhb (
4253 +        cchhb_t * addr,
4254 +        u_int16_t cc,
4255 +        u_int16_t hh,
4256 +        u_int8_t b);
4257 +void vtoc_set_date (
4258 +        labeldate_t * d,
4259 +        u_int8_t year,
4260 +        u_int16_t day);
4261 +
4262 +void vtoc_volume_label_init (
4263 +       volume_label_t *vlabel);
4264 +
4265 +int vtoc_read_volume_label (
4266 +        int fd,
4267 +        unsigned long vlabel_start,
4268 +        volume_label_t * vlabel);
4269 +
4270 +int vtoc_write_volume_label (
4271 +        int fd,
4272 +        unsigned long vlabel_start,
4273 +        volume_label_t *vlabel);
4274 +
4275 +void vtoc_volume_label_set_volser (
4276 +       volume_label_t *vlabel,
4277 +       char *volser);
4278 +
4279 +char *vtoc_volume_label_get_volser (
4280 +       volume_label_t *vlabel,
4281 +       char *volser);
4282 +
4283 +void vtoc_volume_label_set_key (
4284 +        volume_label_t *vlabel,
4285 +        char *key);     
4286 +
4287 +void vtoc_volume_label_set_label (
4288 +       volume_label_t *vlabel,
4289 +       char *lbl);
4290 +
4291 +char *vtoc_volume_label_get_label (
4292 +       volume_label_t *vlabel,
4293 +       char *lbl);
4294 +
4295 +void vtoc_read_label (
4296 +        int fd,
4297 +        unsigned long position,
4298 +        format1_label_t *f1,
4299 +        format4_label_t *f4,
4300 +        format5_label_t *f5,
4301 +        format7_label_t *f7);
4302 +
4303 +void vtoc_write_label (
4304 +        int fd,
4305 +        unsigned long position,
4306 +        format1_label_t *f1,
4307 +       format4_label_t *f4,
4308 +       format5_label_t *f5,
4309 +       format7_label_t *f7);
4310 +
4311 +
4312 +void vtoc_init_format1_label (
4313 +        char *volid,
4314 +        unsigned int blksize,
4315 +        extent_t *part_extent,
4316 +        format1_label_t *f1);
4317 +
4318 +
4319 +void vtoc_init_format4_label (
4320 +        format4_label_t *f4lbl,
4321 +       unsigned int usable_partitions,
4322 +       unsigned int cylinders,
4323 +       unsigned int tracks,
4324 +       unsigned int blocks,
4325 +       unsigned int blksize,
4326 +       u_int16_t dev_type);
4327 +
4328 +void vtoc_update_format4_label (
4329 +       format4_label_t *f4,
4330 +       cchhb_t *highest_f1,
4331 +       u_int16_t unused_update);
4332 +
4333 +
4334 +void vtoc_init_format5_label (
4335 +       format5_label_t *f5);
4336 +
4337 +void vtoc_update_format5_label_add (
4338 +       format5_label_t *f5,
4339 +       int verbose,
4340 +       int cyl,
4341 +       int trk,
4342 +       u_int16_t a, 
4343 +       u_int16_t b, 
4344 +       u_int8_t c);
4345
4346 +void vtoc_update_format5_label_del (
4347 +       format5_label_t *f5,
4348 +       int verbose,
4349 +       int cyl,
4350 +       int trk,
4351 +       u_int16_t a, 
4352 +       u_int16_t b, 
4353 +       u_int8_t c);
4354 +
4355 +
4356 +void vtoc_init_format7_label (
4357 +       format7_label_t *f7);
4358 +
4359 +void vtoc_update_format7_label_add (
4360 +       format7_label_t *f7,
4361 +       int verbose,
4362 +       u_int32_t a, 
4363 +       u_int32_t b);
4364 +
4365 +void vtoc_update_format7_label_del (
4366 +       format7_label_t *f7, 
4367 +       int verbose,
4368 +       u_int32_t a, 
4369 +       u_int32_t b);
4370 +
4371 +
4372 +void vtoc_set_freespace(
4373 +       format4_label_t *f4,
4374 +       format5_label_t *f5,
4375 +       format7_label_t *f7,
4376 +       char ch,
4377 +       int verbose,
4378 +       u_int32_t start,
4379 +       u_int32_t stop,
4380 +       int cyl,
4381 +       int trk);
4382 +
4383 +
4384 +#endif /* VTOC_H */
This page took 0.351622 seconds and 3 git commands to generate.