OSDN Git Service

aef8e1a8952bf712446eff3d6c24c3b7fdd476fa
[android-x86/external-parted.git] / libparted / labels / bsd.c
1 /* -*- Mode: c; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
2
3     libparted - a library for manipulating disk partitions
4     Copyright (C) 2000-2001, 2007-2009 Free Software Foundation, Inc.
5
6     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 3 of the License, or
9     (at your option) any later version.
10
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with this program.  If not, see <http://www.gnu.org/licenses/>.
18
19     Contributor:  Matt Wilson <msw@redhat.com>
20 */
21
22 #include <config.h>
23
24 #include <stdbool.h>
25 #include <parted/parted.h>
26 #include <parted/debug.h>
27 #include <parted/endian.h>
28 #include <stdbool.h>
29
30 #if ENABLE_NLS
31 #  include <libintl.h>
32 #  define _(String) dgettext (PACKAGE, String)
33 #else
34 #  define _(String) (String)
35 #endif /* ENABLE_NLS */
36
37 #include "misc.h"
38 #include "pt-tools.h"
39
40 /* struct's & #define's stolen from libfdisk, which probably came from
41  * Linux...
42  */
43
44 #define BSD_DISKMAGIC   (0x82564557UL)  /* The disk magic number */
45 #define BSD_MAXPARTITIONS       8
46 #define BSD_FS_UNUSED           0       /* disklabel unused partition entry ID */
47 #define BSD_LABEL_OFFSET        64
48
49 #define BSD_DTYPE_SMD           1               /* SMD, XSMD; VAX hp/up */
50 #define BSD_DTYPE_MSCP          2               /* MSCP */
51 #define BSD_DTYPE_DEC           3               /* other DEC (rk, rl) */
52 #define BSD_DTYPE_SCSI          4               /* SCSI */
53 #define BSD_DTYPE_ESDI          5               /* ESDI interface */
54 #define BSD_DTYPE_ST506         6               /* ST506 etc. */
55 #define BSD_DTYPE_HPIB          7               /* CS/80 on HP-IB */
56 #define BSD_DTYPE_HPFL          8               /* HP Fiber-link */
57 #define BSD_DTYPE_FLOPPY        10              /* floppy */
58
59 #define BSD_BBSIZE      8192            /* size of boot area, with label */
60 #define BSD_SBSIZE      8192            /* max size of fs superblock */
61
62 typedef struct _BSDRawPartition         BSDRawPartition;
63 typedef struct _BSDRawLabel             BSDRawLabel;
64
65 struct _BSDRawPartition {               /* the partition table */
66         uint32_t        p_size;         /* number of sectors in partition */
67         uint32_t        p_offset;       /* starting sector */
68         uint32_t        p_fsize;        /* file system basic fragment size */
69         uint8_t         p_fstype;       /* file system type, see below */
70         uint8_t         p_frag;         /* file system fragments per block */
71         uint16_t        p_cpg;          /* file system cylinders per group */
72 } __attribute__((packed));
73
74 struct _BSDRawLabel {
75         uint32_t        d_magic;                /* the magic number */
76         int16_t         d_type;                 /* drive type */
77         int16_t         d_subtype;              /* controller/d_type specific */
78         int8_t          d_typename[16];         /* type name, e.g. "eagle" */
79         int8_t          d_packname[16];         /* pack identifier */
80         uint32_t        d_secsize;              /* # of bytes per sector */
81         uint32_t        d_nsectors;             /* # of data sectors per track */
82         uint32_t        d_ntracks;              /* # of tracks per cylinder */
83         uint32_t        d_ncylinders;           /* # of data cylinders per unit */
84         uint32_t        d_secpercyl;            /* # of data sectors per cylinder */
85         uint32_t        d_secperunit;           /* # of data sectors per unit */
86         uint16_t        d_sparespertrack;       /* # of spare sectors per track */
87         uint16_t        d_sparespercyl;         /* # of spare sectors per cylinder */
88         uint32_t        d_acylinders;           /* # of alt. cylinders per unit */
89         uint16_t        d_rpm;                  /* rotational speed */
90         uint16_t        d_interleave;           /* hardware sector interleave */
91         uint16_t        d_trackskew;            /* sector 0 skew, per track */
92         uint16_t        d_cylskew;              /* sector 0 skew, per cylinder */
93         uint32_t        d_headswitch;           /* head switch time, usec */
94         uint32_t        d_trkseek;              /* track-to-track seek, usec */
95         uint32_t        d_flags;                /* generic flags */
96 #define NDDATA 5
97         uint32_t        d_drivedata[NDDATA];    /* drive-type specific information */
98 #define NSPARE 5
99         uint32_t        d_spare[NSPARE];        /* reserved for future use */
100         uint32_t        d_magic2;               /* the magic number (again) */
101         uint16_t        d_checksum;             /* xor of data incl. partitions */
102
103         /* file system and partition information: */
104         uint16_t        d_npartitions;          /* number of partitions in following */
105         uint32_t        d_bbsize;               /* size of boot area at sn0, bytes */
106         uint32_t        d_sbsize;               /* max size of fs superblock, bytes */
107         BSDRawPartition d_partitions[BSD_MAXPARTITIONS];        /* actually may be more */
108 } __attribute__((packed));
109
110 typedef struct {
111         char            boot_code [512];
112 } BSDDiskData;
113
114 typedef struct {
115         uint8_t         type;
116         int                     boot;
117         int                     raid;
118         int                     lvm;
119 } BSDPartitionData;
120
121 static PedDiskType bsd_disk_type;
122
123 /* XXX fixme: endian? */
124 static unsigned short
125 xbsd_dkcksum (BSDRawLabel *lp) {
126         unsigned short *start, *end;
127         unsigned short sum = 0;
128
129         lp->d_checksum = 0;
130         start = (u_short*) lp;
131         end = (u_short*) &lp->d_partitions [
132                                 PED_LE16_TO_CPU (lp->d_npartitions)];
133         while (start < end)
134                 sum ^= *start++;
135         return sum;
136 }
137
138 /* XXX fixme: endian? */
139 static void
140 alpha_bootblock_checksum (char *boot) {
141         uint64_t *dp, sum;
142         int i;
143
144         dp = (uint64_t *)boot;
145         sum = 0;
146         for (i = 0; i < 63; i++)
147                 sum += dp[i];
148         dp[63] = sum;
149 }
150
151 static int
152 bsd_probe (const PedDevice *dev)
153 {
154         BSDRawLabel     *partition;
155
156         PED_ASSERT (dev != NULL, return 0);
157
158         if (dev->sector_size < 512)
159                 return 0;
160
161         void *label;
162         if (!ptt_read_sector (dev, 0, &label))
163                 return 0;
164
165         partition = (BSDRawLabel *) ((char *) label + BSD_LABEL_OFFSET);
166
167         alpha_bootblock_checksum(label);
168
169         /* check magic */
170         bool found = PED_LE32_TO_CPU (partition->d_magic) == BSD_DISKMAGIC;
171         free (label);
172         return found;
173 }
174
175 static PedDisk*
176 bsd_alloc (const PedDevice* dev)
177 {
178         PedDisk*        disk;
179         BSDDiskData*    bsd_specific;
180         BSDRawLabel*    label;
181
182         PED_ASSERT(dev->sector_size % PED_SECTOR_SIZE_DEFAULT == 0, return 0);
183
184         disk = _ped_disk_alloc ((PedDevice*)dev, &bsd_disk_type);
185         if (!disk)
186                 goto error;
187         disk->disk_specific = bsd_specific = ped_malloc (sizeof (BSDDiskData));
188         if (!bsd_specific)
189                 goto error_free_disk;
190         /* Initialize the first byte to zero, so that the code in bsd_write
191            knows to call _probe_and_add_boot_code.  Initializing all of the
192            remaining buffer is a little wasteful, but the alternative is to
193            figure out why a block at offset 340 would otherwise be used
194            uninitialized.  */
195         memset(bsd_specific->boot_code, 0, sizeof (bsd_specific->boot_code));
196
197         label = (BSDRawLabel*) (bsd_specific->boot_code + BSD_LABEL_OFFSET);
198
199         label->d_magic = PED_CPU_TO_LE32 (BSD_DISKMAGIC);
200         label->d_type = PED_CPU_TO_LE16 (BSD_DTYPE_SCSI);
201         label->d_flags = 0;
202         label->d_secsize = PED_CPU_TO_LE16 (dev->sector_size);
203         label->d_nsectors = PED_CPU_TO_LE32 (dev->bios_geom.sectors);
204         label->d_ntracks = PED_CPU_TO_LE32 (dev->bios_geom.heads);
205         label->d_ncylinders = PED_CPU_TO_LE32 (dev->bios_geom.cylinders);
206         label->d_secpercyl = PED_CPU_TO_LE32 (dev->bios_geom.sectors
207                                                 * dev->bios_geom.heads);
208         label->d_secperunit
209                 = PED_CPU_TO_LE32 (dev->bios_geom.sectors
210                                    * dev->bios_geom.heads
211                                    * dev->bios_geom.cylinders);
212
213         label->d_rpm = PED_CPU_TO_LE16 (3600);
214         label->d_interleave = PED_CPU_TO_LE16 (1);;
215         label->d_trackskew = 0;
216         label->d_cylskew = 0;
217         label->d_headswitch = 0;
218         label->d_trkseek = 0;
219
220         label->d_magic2 = PED_CPU_TO_LE32 (BSD_DISKMAGIC);
221         label->d_bbsize = PED_CPU_TO_LE32 (BSD_BBSIZE);
222         label->d_sbsize = PED_CPU_TO_LE32 (BSD_SBSIZE);
223
224         label->d_npartitions = 0;
225         label->d_checksum = xbsd_dkcksum (label);
226         return disk;
227
228 error_free_disk:
229         free (disk);
230 error:
231         return NULL;
232 }
233
234 static PedDisk*
235 bsd_duplicate (const PedDisk* disk)
236 {
237         PedDisk*        new_disk;
238         BSDDiskData*    new_bsd_data;
239         BSDDiskData*    old_bsd_data = (BSDDiskData*) disk->disk_specific;
240
241         new_disk = ped_disk_new_fresh (disk->dev, &bsd_disk_type);
242         if (!new_disk)
243                 return NULL;
244
245         new_bsd_data = (BSDDiskData*) new_disk->disk_specific;
246         memcpy (new_bsd_data->boot_code, old_bsd_data->boot_code, 512);
247         return new_disk;
248 }
249
250 static void
251 bsd_free (PedDisk* disk)
252 {
253         free (disk->disk_specific);
254         _ped_disk_free (disk);
255 }
256
257 #ifndef DISCOVER_ONLY
258 static int
259 bsd_clobber (PedDevice* dev)
260 {
261         void *label;
262         if (!ptt_read_sector (dev, 0, &label))
263                 return 0;
264         BSDRawLabel *rawlabel
265           = (BSDRawLabel *) ((char *) label + BSD_LABEL_OFFSET);
266         rawlabel->d_magic = 0;
267         return ped_device_write (dev, label, 0, 1);
268 }
269 #endif /* !DISCOVER_ONLY */
270
271 static int
272 bsd_read (PedDisk* disk)
273 {
274         BSDDiskData*    bsd_specific = (BSDDiskData*) disk->disk_specific;
275         BSDRawLabel*    label;
276         int             i;
277
278         ped_disk_delete_all (disk);
279
280         void *s0;
281         if (!ptt_read_sector (disk->dev, 0, &s0))
282                 return 0;
283
284         memcpy (bsd_specific->boot_code, s0, sizeof (bsd_specific->boot_code));
285         free (s0);
286
287         label = (BSDRawLabel *) (bsd_specific->boot_code + BSD_LABEL_OFFSET);
288
289         for (i = 1; i <= BSD_MAXPARTITIONS; i++) {
290                 PedPartition*           part;
291                 BSDPartitionData*       bsd_part_data;
292                 PedSector               start;
293                 PedSector               end;
294                 PedConstraint*          constraint_exact;
295
296                 if (!label->d_partitions[i - 1].p_size
297                     || !label->d_partitions[i - 1].p_fstype)
298                         continue;
299                 start = PED_LE32_TO_CPU(label->d_partitions[i - 1].p_offset);
300                 end = PED_LE32_TO_CPU(label->d_partitions[i - 1].p_offset)
301                       + PED_LE32_TO_CPU(label->d_partitions[i - 1].p_size) - 1;
302                 part = ped_partition_new (disk, PED_PARTITION_NORMAL,
303                                           NULL, start, end);
304                 if (!part)
305                         goto error;
306                 bsd_part_data = part->disk_specific;
307                 bsd_part_data->type = label->d_partitions[i - 1].p_fstype;
308                 part->num = i;
309                 part->fs_type = ped_file_system_probe (&part->geom);
310
311                 constraint_exact = ped_constraint_exact (&part->geom);
312                 if (!ped_disk_add_partition (disk, part, constraint_exact))
313                         goto error;
314                 ped_constraint_destroy (constraint_exact);
315         }
316
317         return 1;
318
319 error:
320         return 0;
321 }
322
323 static void
324 _probe_and_add_boot_code (const PedDisk* disk)
325 {
326         void *s0;
327         if (!ptt_read_sector (disk->dev, 0, &s0))
328                 return;
329         char *old_boot_code = s0;
330         BSDRawLabel *old_label
331                 = (BSDRawLabel*) (old_boot_code + BSD_LABEL_OFFSET);
332
333         if (old_boot_code [0]
334             && old_label->d_magic == PED_CPU_TO_LE32 (BSD_DISKMAGIC)) {
335                 BSDDiskData *bsd_specific = (BSDDiskData*) disk->disk_specific;
336                 memcpy (bsd_specific->boot_code, old_boot_code,
337                         sizeof (BSDDiskData));
338         }
339         free (s0);
340 }
341
342 #ifndef DISCOVER_ONLY
343 static int
344 bsd_write (const PedDisk* disk)
345 {
346         BSDDiskData*            bsd_specific;
347         BSDRawLabel*            label;
348         BSDPartitionData*       bsd_data;
349         PedPartition*           part;
350         int                     i;
351         int                     max_part = 0;
352
353         PED_ASSERT (disk != NULL, return 0);
354         PED_ASSERT (disk->dev != NULL, return 0);
355
356         bsd_specific = (BSDDiskData*) disk->disk_specific;
357         label = (BSDRawLabel *) (bsd_specific->boot_code + BSD_LABEL_OFFSET);
358
359         if (!bsd_specific->boot_code [0])
360                 _probe_and_add_boot_code (disk);
361
362         memset (label->d_partitions, 0,
363                 sizeof (BSDRawPartition) * BSD_MAXPARTITIONS);
364
365         for (i = 1; i <= BSD_MAXPARTITIONS; i++) {
366                 part = ped_disk_get_partition (disk, i);
367                 if (!part)
368                         continue;
369                 bsd_data = part->disk_specific;
370                 label->d_partitions[i - 1].p_fstype = bsd_data->type;
371                 label->d_partitions[i - 1].p_offset
372                         = PED_CPU_TO_LE32 (part->geom.start);
373                 label->d_partitions[i - 1].p_size
374                         = PED_CPU_TO_LE32 (part->geom.length);
375                 max_part = i;
376         }
377
378         label->d_npartitions = PED_CPU_TO_LE16 (max_part) + 1;
379         label->d_checksum = xbsd_dkcksum (label);
380
381         alpha_bootblock_checksum (bsd_specific->boot_code);
382
383         if (!ptt_write_sector (disk, bsd_specific->boot_code,
384                                sizeof (BSDDiskData)))
385                 goto error;
386         return ped_device_sync (disk->dev);
387
388 error:
389         return 0;
390 }
391 #endif /* !DISCOVER_ONLY */
392
393 static PedPartition*
394 bsd_partition_new (const PedDisk* disk, PedPartitionType part_type,
395                    const PedFileSystemType* fs_type,
396                    PedSector start, PedSector end)
397 {
398         PedPartition*           part;
399         BSDPartitionData*       bsd_data;
400
401         part = _ped_partition_alloc (disk, part_type, fs_type, start, end);
402         if (!part)
403                 goto error;
404
405         if (ped_partition_is_active (part)) {
406                 part->disk_specific
407                         = bsd_data = ped_malloc (sizeof (BSDPartitionData));
408                 if (!bsd_data)
409                         goto error_free_part;
410                 bsd_data->type = 0;
411                 bsd_data->boot = 0;
412                 bsd_data->raid = 0;
413                 bsd_data->lvm  = 0;
414         } else {
415                 part->disk_specific = NULL;
416         }
417         return part;
418
419         free (bsd_data);
420 error_free_part:
421         free (part);
422 error:
423         return 0;
424 }
425
426 static PedPartition*
427 bsd_partition_duplicate (const PedPartition* part)
428 {
429         PedPartition*           new_part;
430         BSDPartitionData*       new_bsd_data;
431         BSDPartitionData*       old_bsd_data;
432
433         new_part = ped_partition_new (part->disk, part->type,
434                                       part->fs_type, part->geom.start,
435                                       part->geom.end);
436         if (!new_part)
437                 return NULL;
438         new_part->num = part->num;
439
440         old_bsd_data = (BSDPartitionData*) part->disk_specific;
441         new_bsd_data = (BSDPartitionData*) new_part->disk_specific;
442         new_bsd_data->type = old_bsd_data->type;
443         new_bsd_data->boot = old_bsd_data->boot;
444         new_bsd_data->raid = old_bsd_data->raid;
445         new_bsd_data->lvm = old_bsd_data->lvm;
446         return new_part;
447 }
448
449 static void
450 bsd_partition_destroy (PedPartition* part)
451 {
452         PED_ASSERT (part != NULL, return);
453
454         if (ped_partition_is_active (part))
455                 free (part->disk_specific);
456         _ped_partition_free (part);
457 }
458
459 static int
460 bsd_partition_set_system (PedPartition* part, const PedFileSystemType* fs_type)
461 {
462         BSDPartitionData* bsd_data = part->disk_specific;
463
464         part->fs_type = fs_type;
465
466         if (!fs_type)
467                 bsd_data->type = 0x8;
468         else if (is_linux_swap (fs_type->name))
469                 bsd_data->type = 0x1;
470         else
471                 bsd_data->type = 0x8;
472
473         return 1;
474 }
475
476 static int
477 bsd_partition_set_flag (PedPartition* part, PedPartitionFlag flag, int state)
478 {
479         PedDisk*                        disk;
480 //      PedPartition*           walk; // since -Werror, this unused variable would break build
481         BSDPartitionData*       bsd_data;
482
483         PED_ASSERT (part != NULL, return 0);
484         PED_ASSERT (part->disk_specific != NULL, return 0);
485         PED_ASSERT (part->disk != NULL, return 0);
486
487         bsd_data = part->disk_specific;
488         disk = part->disk;
489
490         switch (flag) {
491                 case PED_PARTITION_BOOT:
492                         bsd_data->boot = state;
493                         return 1;
494                 case PED_PARTITION_RAID:
495                         if (state) {
496                                 bsd_data->lvm = 0;
497                         }
498                         bsd_data->raid = state;
499                         return 1;
500                 case PED_PARTITION_LVM:
501                         if (state) {
502                                 bsd_data->raid = 0;
503                         }
504                         bsd_data->lvm = state;
505                 default:
506                         ;
507         }
508         return 0;
509 }
510
511 static int
512 bsd_partition_get_flag (const PedPartition* part, PedPartitionFlag flag)
513 {
514         BSDPartitionData*               bsd_data;
515
516         PED_ASSERT (part != NULL, return 0);
517         PED_ASSERT (part->disk_specific != NULL, return 0);
518
519         bsd_data = part->disk_specific;
520         switch (flag) {
521                 case PED_PARTITION_BOOT:
522                         return bsd_data->boot;
523
524                 case PED_PARTITION_RAID:
525                         return bsd_data->raid;
526
527                 case PED_PARTITION_LVM:
528                         return bsd_data->lvm;
529
530                 default:
531                         ;
532         }
533         return 0;
534 }
535
536 static int
537 bsd_partition_is_flag_available (const PedPartition* part,
538                                  PedPartitionFlag flag)
539 {
540         switch (flag) {
541                 case PED_PARTITION_BOOT:
542                 case PED_PARTITION_RAID:
543                 case PED_PARTITION_LVM:
544                         return 1;
545                 default:
546                         ;
547         }
548         return 0;
549 }
550
551
552 static int
553 bsd_get_max_primary_partition_count (const PedDisk* disk)
554 {
555         return BSD_MAXPARTITIONS;
556 }
557
558 static bool
559 bsd_get_max_supported_partition_count(const PedDisk* disk, int *max_n)
560 {
561         *max_n = BSD_MAXPARTITIONS;
562         return true;
563 }
564
565 static PedConstraint*
566 _get_constraint (const PedDevice* dev)
567 {
568         PedGeometry     max;
569
570         ped_geometry_init (&max, dev, 1, dev->length - 1);
571         return ped_constraint_new_from_max (&max);
572 }
573
574 static int
575 bsd_partition_align (PedPartition* part, const PedConstraint* constraint)
576 {
577         if (_ped_partition_attempt_align (part, constraint,
578                                           _get_constraint (part->disk->dev)))
579                 return 1;
580
581 #ifndef DISCOVER_ONLY
582         ped_exception_throw (
583                 PED_EXCEPTION_ERROR,
584                 PED_EXCEPTION_CANCEL,
585                 _("Unable to satisfy all constraints on the partition."));
586 #endif
587         return 0;
588 }
589
590 static int
591 bsd_partition_enumerate (PedPartition* part)
592 {
593         int i;
594         PedPartition* p;
595
596         /* never change the partition numbers */
597         if (part->num != -1)
598                 return 1;
599         for (i = 1; i <= BSD_MAXPARTITIONS; i++) {
600                 p = ped_disk_get_partition (part->disk, i);
601                 if (!p) {
602                         part->num = i;
603                         return 1;
604                 }
605         }
606
607         /* failed to allocate a number */
608 #ifndef DISCOVER_ONLY
609         ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
610                              _("Unable to allocate a bsd disklabel slot."));
611 #endif
612         return 0;
613 }
614
615 static int
616 bsd_alloc_metadata (PedDisk* disk)
617 {
618         PedPartition*           new_part;
619         PedConstraint*          constraint_any = NULL;
620
621         PED_ASSERT (disk != NULL, goto error);
622         PED_ASSERT (disk->dev != NULL, goto error);
623
624         constraint_any = ped_constraint_any (disk->dev);
625
626         /* allocate 1 sector for the disk label at the start */
627         new_part = ped_partition_new (disk, PED_PARTITION_METADATA, NULL, 0, 0);
628         if (!new_part)
629                 goto error;
630
631         if (!ped_disk_add_partition (disk, new_part, constraint_any)) {
632                 ped_partition_destroy (new_part);
633                 goto error;
634         }
635
636         ped_constraint_destroy (constraint_any);
637         return 1;
638 error:
639         ped_constraint_destroy (constraint_any);
640         return 0;
641 }
642
643 static bool
644 bsd_partition_check (const PedPartition* part)
645 {
646         return true;
647 }
648
649 static PedDiskOps bsd_disk_ops = {
650         probe:                  bsd_probe,
651 #ifndef DISCOVER_ONLY
652         clobber:                bsd_clobber,
653 #else
654         clobber:                NULL,
655 #endif
656         alloc:                  bsd_alloc,
657         duplicate:              bsd_duplicate,
658         free:                   bsd_free,
659         read:                   bsd_read,
660 #ifndef DISCOVER_ONLY
661         write:                  bsd_write,
662 #else
663         write:                  NULL,
664 #endif
665
666         partition_new:          bsd_partition_new,
667         partition_duplicate:    bsd_partition_duplicate,
668         partition_destroy:      bsd_partition_destroy,
669         partition_set_system:   bsd_partition_set_system,
670         partition_set_flag:     bsd_partition_set_flag,
671         partition_get_flag:     bsd_partition_get_flag,
672         partition_is_flag_available:    bsd_partition_is_flag_available,
673         partition_set_name:     NULL,
674         partition_get_name:     NULL,
675         partition_align:        bsd_partition_align,
676         partition_enumerate:    bsd_partition_enumerate,
677         partition_check:        bsd_partition_check,
678
679         alloc_metadata:         bsd_alloc_metadata,
680         get_max_primary_partition_count:
681                                 bsd_get_max_primary_partition_count,
682         get_max_supported_partition_count:
683                                 bsd_get_max_supported_partition_count
684 };
685
686 static PedDiskType bsd_disk_type = {
687         next:           NULL,
688         name:           "bsd",
689         ops:            &bsd_disk_ops,
690         features:       0
691 };
692
693 void
694 ped_disk_bsd_init ()
695 {
696         PED_ASSERT (sizeof (BSDRawPartition) == 16, return);
697         PED_ASSERT (sizeof (BSDRawLabel) == 276, return);
698
699         ped_disk_type_register (&bsd_disk_type);
700 }
701
702 void
703 ped_disk_bsd_done ()
704 {
705         ped_disk_type_unregister (&bsd_disk_type);
706 }