Index: AUTHORS =================================================================== RCS file: /mnt/devel/CVS/parted/AUTHORS,v retrieving revision 1.1.1.1 retrieving revision 1.1.1.1.2.1 diff -u -u -r1.1.1.1 -r1.1.1.1.2.1 --- AUTHORS 2000/11/20 16:18:14 1.1.1.1 +++ AUTHORS 2000/12/11 19:04:51 1.1.1.1.2.1 @@ -34,6 +34,7 @@ * basis of partition table and device code (disk.c, disk_dos.c, and device.c) Has morphed into something that looks completely different now :-) + * BSD disklabel support (disk_bsd.c) Martin von Löwis * German translations Index: include/parted/disk_bsd.h =================================================================== RCS file: disk_bsd.h diff -N disk_bsd.h --- /dev/null Thu Aug 24 05:00:32 2000 +++ /tmp/cvsT8yJLm Mon Dec 11 14:12:52 2000 @@ -0,0 +1,37 @@ +/* -*- Mode: c; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + + libparted - a library for manipulating disk partitions + Copyright (C) 1998-2000 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Contributor: Matt Wilson +*/ + +#ifndef PED_DISK_BSD_H_INCLUDED +#define PED_DISK_BSD_H_INCLUDED + +typedef struct { + u_int8_t type; +} BSDPartitionData; + +#define BSD_NAME "bsd" + +extern void ped_disk_bsd_init (); +extern void ped_disk_bsd_done (); + + +#endif /* PED_DISK_BSD_H_INCLUDED */ + Index: libparted/Makefile.am =================================================================== RCS file: /mnt/devel/CVS/parted/libparted/Makefile.am,v retrieving revision 1.1.1.1 retrieving revision 1.1.1.1.2.1 diff -u -u -r1.1.1.1 -r1.1.1.1.2.1 --- libparted/Makefile.am 2000/11/20 16:18:15 1.1.1.1 +++ libparted/Makefile.am 2000/12/08 23:18:44 1.1.1.1.2.1 @@ -19,7 +19,8 @@ disk_dos.c \ disk_loop.c \ disk_mac.c \ - disk_pc98.c + disk_pc98.c \ + disk_bsd.c libparted_la_LIBADD = fs_ext2/libext2.la \ fs_fat/libfat.la \ Index: libparted/device.c =================================================================== RCS file: /mnt/devel/CVS/parted/libparted/device.c,v retrieving revision 1.1.1.2 retrieving revision 1.1.1.2.2.2 diff -u -u -r1.1.1.2 -r1.1.1.2.2.2 --- libparted/device.c 2000/11/30 17:51:11 1.1.1.2 +++ libparted/device.c 2000/12/11 19:04:32 1.1.1.2.2.2 @@ -803,12 +803,12 @@ #if SIZEOF_OFF_T < 8 && defined(linux) if (sizeof (off_t) < 8) { - loff_t pos = sector * 512; + loff_t pos = sector * PED_SECTOR_SIZE; return ped_llseek (dev->fd, pos, SEEK_SET) == pos; } else #endif { - off_t pos = sector * 512; + off_t pos = sector * PED_SECTOR_SIZE; return lseek (dev->fd, pos, SEEK_SET) == pos; } } Index: libparted/disk_bsd.c =================================================================== RCS file: disk_bsd.c diff -N disk_bsd.c --- /dev/null Thu Aug 24 05:00:32 2000 +++ /tmp/cvsI9q4MF Mon Dec 11 14:12:52 2000 @@ -0,0 +1,565 @@ +/* -*- Mode: c; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + + libparted - a library for manipulating disk partitions + Copyright (C) 1998-2000 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Contributor: Matt Wilson +*/ + +#include "config.h" + +#include + +#include +#include +#include + +#define BSD_DISKMAGIC (0x82564557UL) /* The disk magic number */ +#define BSD_MAXPARTITIONS 8 +#define BSD_FS_UNUSED 0 /* disklabel unused partition entry ID */ +#define BSD_LABEL_OFFSET 64 + +#define BSD_DTYPE_SMD 1 /* SMD, XSMD; VAX hp/up */ +#define BSD_DTYPE_MSCP 2 /* MSCP */ +#define BSD_DTYPE_DEC 3 /* other DEC (rk, rl) */ +#define BSD_DTYPE_SCSI 4 /* SCSI */ +#define BSD_DTYPE_ESDI 5 /* ESDI interface */ +#define BSD_DTYPE_ST506 6 /* ST506 etc. */ +#define BSD_DTYPE_HPIB 7 /* CS/80 on HP-IB */ +#define BSD_DTYPE_HPFL 8 /* HP Fiber-link */ +#define BSD_DTYPE_FLOPPY 10 /* floppy */ + +#define BSD_BBSIZE 8192 /* size of boot area, with label */ +#define BSD_SBSIZE 8192 /* max size of fs superblock */ + +typedef struct _BSDRawPartition BSDRawPartition; +typedef struct _BSDRawLabel BSDRawLabel; + +struct _BSDRawPartition { /* the partition table */ + u_int32_t p_size; /* number of sectors in partition */ + u_int32_t p_offset; /* starting sector */ + u_int32_t p_fsize; /* filesystem basic fragment size */ + u_int8_t p_fstype; /* filesystem type, see below */ + u_int8_t p_frag; /* filesystem fragments per block */ + u_int16_t p_cpg; /* filesystem cylinders per group */ +}; + +struct _BSDRawLabel { + u_int32_t d_magic; /* the magic number */ + int16_t d_type; /* drive type */ + int16_t d_subtype; /* controller/d_type specific */ + int8_t d_typename[16]; /* type name, e.g. "eagle" */ + int8_t d_packname[16]; /* pack identifier */ + u_int32_t d_secsize; /* # of bytes per sector */ + u_int32_t d_nsectors; /* # of data sectors per track */ + u_int32_t d_ntracks; /* # of tracks per cylinder */ + u_int32_t d_ncylinders; /* # of data cylinders per unit */ + u_int32_t d_secpercyl; /* # of data sectors per cylinder */ + u_int32_t d_secperunit; /* # of data sectors per unit */ + u_int16_t d_sparespertrack; /* # of spare sectors per track */ + u_int16_t d_sparespercyl; /* # of spare sectors per cylinder */ + u_int32_t d_acylinders; /* # of alt. cylinders per unit */ + u_int16_t d_rpm; /* rotational speed */ + u_int16_t d_interleave; /* hardware sector interleave */ + u_int16_t d_trackskew; /* sector 0 skew, per track */ + u_int16_t d_cylskew; /* sector 0 skew, per cylinder */ + u_int32_t d_headswitch; /* head switch time, usec */ + u_int32_t d_trkseek; /* track-to-track seek, usec */ + u_int32_t d_flags; /* generic flags */ +#define NDDATA 5 + u_int32_t d_drivedata[NDDATA]; /* drive-type specific information */ +#define NSPARE 5 + u_int32_t d_spare[NSPARE]; /* reserved for future use */ + u_int32_t d_magic2; /* the magic number (again) */ + u_int16_t d_checksum; /* xor of data incl. partitions */ + + /* filesystem and partition information: */ + u_int16_t d_npartitions; /* number of partitions in following */ + u_int32_t d_bbsize; /* size of boot area at sn0, bytes */ + u_int32_t d_sbsize; /* max size of fs superblock, bytes */ + BSDRawPartition d_partitions[BSD_MAXPARTITIONS]; /* actually may be more */ +}; + +static int bsd_probe (const PedDevice *dev); +static PedDisk* bsd_open (PedDevice* dev); +static PedDisk* bsd_create (PedDevice* dev); +static int bsd_clobber (PedDevice* dev); +static int bsd_close (PedDisk* disk); +static int bsd_read (PedDisk* disk); +static int bsd_write (PedDisk* disk); + +static PedPartition* bsd_partition_new ( + const PedDisk* disk, PedPartitionType part_type, + const PedFileSystemType* fs_type, PedSector start, PedSector end); +static void bsd_partition_destroy (PedPartition* part); +static int bsd_partition_set_flag ( + PedPartition* part, PedPartitionFlag flag, int state); +static int bsd_partition_get_flag ( + const PedPartition* part, PedPartitionFlag flag); +static int bsd_partition_is_flag_available ( + const PedPartition* part, + PedPartitionFlag flag); +static int bsd_partition_align (PedPartition* part, + const PedConstraint* constraint); +static int bsd_partition_enumerate (PedPartition* part); +static int bsd_partition_set_extended_system (PedPartition* part); +static int bsd_get_max_primary_partition_count (const PedDisk* disk); + +static int bsd_alloc_metadata (PedDisk* disk); + +static PedDiskOps bsd_disk_ops = { + probe: bsd_probe, + open: bsd_open, + create: bsd_create, + clobber: bsd_clobber, + close: bsd_close, + read: bsd_read, + write: bsd_write, + + partition_new: bsd_partition_new, + partition_destroy: bsd_partition_destroy, + partition_set_flag: bsd_partition_set_flag, + partition_get_flag: bsd_partition_get_flag, + partition_is_flag_available: bsd_partition_is_flag_available, + partition_set_name: NULL, + partition_get_name: NULL, + partition_align: bsd_partition_align, + partition_enumerate: bsd_partition_enumerate, + partition_set_extended_system: bsd_partition_set_extended_system, + + alloc_metadata: bsd_alloc_metadata, + get_max_primary_partition_count: + bsd_get_max_primary_partition_count +}; + +static PedDiskType bsd_disk_type = { + next: NULL, + name: "bsd", + ops: &bsd_disk_ops, + features: 0 +}; + +void +ped_disk_bsd_init () +{ + PED_ASSERT (sizeof (BSDRawPartition) == 16, return); + PED_ASSERT (sizeof (BSDRawLabel) == 276, return); + + ped_register_disk_type (&bsd_disk_type); +} + +void +ped_disk_bsd_done () +{ + ped_unregister_disk_type (&bsd_disk_type); +} + + +/* XXX fixme: endian? */ +static unsigned short +xbsd_dkcksum (BSDRawLabel *lp) { + unsigned short *start, *end; + unsigned short sum = 0; + + lp->d_checksum = 0; + start = (u_short *)lp; + end = (u_short *)&lp->d_partitions[lp->d_npartitions]; + while (start < end) + sum ^= *start++; + return (sum); +} + +/* XXX fixme: endian? */ +static void +alpha_bootblock_checksum (char *boot) { + u_int64_t *dp, sum; + int i; + + dp = (u_int64_t *)boot; + sum = 0; + for (i = 0; i < 63; i++) + sum += dp[i]; + dp[63] = sum; +} + + +static int +bsd_probe (const PedDevice *dev) +{ + PedDiskType* disk_type; + char boot[512]; + BSDRawLabel *label; + int i; + + PED_ASSERT (dev != NULL, return 0); + + if (!ped_device_open ((PedDevice*) dev)) + return 0; + if (!ped_device_read (dev, boot, 0, 1)) { + ped_device_close ((PedDevice*) dev); + return 0; + } + + ped_device_close ((PedDevice*) dev); + label = (BSDRawLabel *) (boot + BSD_LABEL_OFFSET); + + alpha_bootblock_checksum(boot); + + /* check magic */ + if (PED_LE32_TO_CPU (label->d_magic) != BSD_DISKMAGIC) + return 0; + + return 1; +} + +static PedDisk* +bsd_open (PedDevice* dev) +{ + PedDisk* disk; + + PED_ASSERT (dev != NULL, return 0); + + if (!bsd_probe (dev)) + goto error; + + if (!ped_device_open ((PedDevice*) dev)) + goto error; + disk = ped_disk_alloc (dev, &bsd_disk_type); + if (!disk) + goto error; + + if (!bsd_read (disk)) + goto error_free_disk; + + return disk; + +error_free_disk: + ped_disk_free (disk); +error: + return NULL; +} + +static int +bsd_close (PedDisk* disk) +{ + PED_ASSERT (disk != NULL, return 0); + + ped_device_close (disk->dev); + ped_disk_free (disk); + return 1; +} + + +static PedDisk* +bsd_create (PedDevice* dev) +{ + char boot[512]; + BSDRawLabel *label; + + PED_ASSERT (dev != NULL, return 0); + + if (!ped_device_open ((PedDevice*) dev)) + goto error; + if (!ped_device_read (dev, boot, 0, 1)) { + ped_device_close ((PedDevice*) dev); + return 0; + } + label = (BSDRawLabel *) (boot + BSD_LABEL_OFFSET); + + memset(label, 0, sizeof(label)); + + label->d_magic = PED_CPU_TO_LE32 (BSD_DISKMAGIC); + label->d_type = PED_CPU_TO_LE16 (BSD_DTYPE_SCSI); + label->d_flags = 0; + label->d_secsize = PED_CPU_TO_LE16 (PED_SECTOR_SIZE); + label->d_nsectors = PED_CPU_TO_LE32 (dev->sectors); + label->d_ntracks = PED_CPU_TO_LE32 (dev->heads); + label->d_ncylinders = PED_CPU_TO_LE32 (dev->cylinders); + label->d_secpercyl = PED_CPU_TO_LE32 (dev->sectors * dev->heads); + label->d_secperunit = PED_CPU_TO_LE32 (dev->sectors * dev->heads * dev->cylinders); + + label->d_rpm = PED_CPU_TO_LE16 (3600); + label->d_interleave = PED_CPU_TO_LE16 (1);; + label->d_trackskew = 0; + label->d_cylskew = 0; + label->d_headswitch = 0; + label->d_trkseek = 0; + + label->d_magic2 = PED_CPU_TO_LE32 (BSD_DISKMAGIC); + label->d_bbsize = PED_CPU_TO_LE32 (BSD_BBSIZE); + label->d_sbsize = PED_CPU_TO_LE32 (BSD_SBSIZE); + + label->d_npartitions = 0; + label->d_checksum = xbsd_dkcksum (label); + + alpha_bootblock_checksum(boot); + + if (!ped_device_write (dev, (void*) boot, 0, 1)) + goto error_close_dev; + if (!ped_device_sync (dev)) + goto error_close_dev; + ped_device_close (dev); + return bsd_open (dev); + +error_close_dev: + ped_device_close (dev); +error: + return 0; +} + +static int +bsd_clobber (PedDevice* dev) +{ + char boot[512]; + BSDRawLabel *label; + + PED_ASSERT (dev != NULL, return 0); + PED_ASSERT (bsd_probe (dev), return 0); + + if (!ped_device_open ((PedDevice*) dev)) + goto error; + if (!ped_device_read (dev, boot, 0, 1)) + goto error_close_dev; + label = (BSDRawLabel *) (boot + BSD_LABEL_OFFSET); + + label->d_magic = 0; + alpha_bootblock_checksum(boot); + + if (!ped_device_write (dev, (void*) boot, 0, 1)) + goto error_close_dev; + + ped_device_close (dev); + return 1; + +error_close_dev: + ped_device_close (dev); +error: + return 0; +} + +static int +bsd_read (PedDisk* disk) +{ + char boot[512]; + BSDRawLabel *label; + BSDPartitionData* bsd_data; + int i, s; + PedPartition* part; + PedSector start, end; + PedConstraint* constraint_exact; + + PED_ASSERT (disk != NULL, return 0); + PED_ASSERT (disk->dev != NULL, return 0); + + ped_disk_delete_all (disk); + + if (!ped_device_open ((PedDevice*) disk->dev)) + goto error; + if (!ped_device_read (disk->dev, boot, 0, 1)) + goto error_close_dev; + label = (BSDRawLabel *) (boot + BSD_LABEL_OFFSET); + + for (i = 1; i <= BSD_MAXPARTITIONS; i++) { + if (!label->d_partitions[i - 1].p_size + || !label->d_partitions[i - 1].p_fstype) + continue; + start = PED_LE32_TO_CPU(label->d_partitions[i - 1].p_offset); + end = PED_LE32_TO_CPU(label->d_partitions[i - 1].p_offset) + + PED_LE32_TO_CPU(label->d_partitions[i - 1].p_size - 1); + part = ped_partition_new (disk, PED_PARTITION_PRIMARY, NULL, + start, end); + bsd_data = part->disk_specific; + bsd_data->type = label->d_partitions[i - 1].p_fstype; + if (!part) + goto error_close_dev; + part->num = i; + part->fs_type = ped_file_system_probe (&part->geom); + + constraint_exact = ped_constraint_exact (part); + if (!ped_disk_add_partition (disk, part, constraint_exact)) + goto error_close_dev; + ped_constraint_destroy (constraint_exact); + } + + ped_device_close ((PedDevice*) disk->dev); + return 1; + + error_close_dev: + ped_device_close ((PedDevice*) disk->dev); + error: + return 0; +} + +static int +bsd_write (PedDisk* disk) +{ + BSDRawLabel *label; + BSDPartitionData* bsd_data; + PedPartition* part; + int i, max_part; + char boot[512]; + + PED_ASSERT (disk != NULL, return 0); + PED_ASSERT (disk->dev != NULL, return 0); + + if (!ped_device_read (disk->dev, boot, 0, 1)) + return 0; + label = (BSDRawLabel *) (boot + BSD_LABEL_OFFSET); + + memset (label->d_partitions, 0, + sizeof (BSDRawPartition) * BSD_MAXPARTITIONS); + + for (i = 1; i <= BSD_MAXPARTITIONS; i++) { + part = ped_disk_get_partition (disk, i); + if (!part) + continue; + bsd_data = part->disk_specific; + label->d_partitions[i - 1].p_fstype = bsd_data->type; + label->d_partitions[i - 1].p_offset = PED_CPU_TO_LE32 (part->geom.start); + label->d_partitions[i - 1].p_size = PED_CPU_TO_LE32 (part->geom.length); + max_part = i; + } + + label->d_npartitions = PED_CPU_TO_LE16 (max_part + 1); + label->d_checksum = xbsd_dkcksum (label); + + alpha_bootblock_checksum(boot); + + if (!ped_device_write (disk->dev, (void*) boot, 0, 1)) + return 0; + if (!ped_device_sync (disk->dev)) + return 0; + + return 1; +} + +static PedPartition* +bsd_partition_new (const PedDisk* disk, PedPartitionType part_type, + const PedFileSystemType* fs_type, + PedSector start, PedSector end) +{ + PedPartition* part; + BSDPartitionData* bsd_data; + + part = ped_partition_alloc (disk, part_type, fs_type, start, end); + if (!part) + goto error; + + if (ped_partition_is_active (part)) { + part->disk_specific + = bsd_data = ped_malloc (sizeof (BSDPartitionData)); + if (!bsd_data) + goto error_free_part; + bsd_data->type = 0; + + if (fs_type && !ped_partition_set_system (part, fs_type)) + goto error_free_bsd_data; + } else { + part->disk_specific = NULL; + } + return part; + +error_free_bsd_data: + ped_free (bsd_data); +error_free_part: + ped_free (part); +error: + return 0; +} + + +static void +bsd_partition_destroy (PedPartition* part) +{ + PED_ASSERT (part != NULL, return); + + if (ped_partition_is_active (part)) + ped_free (part->disk_specific); + ped_free (part); +} + + +static int +bsd_partition_set_flag (PedPartition* part, PedPartitionFlag flag, int state) +{ + /* no flags for bsd */ + return 0; +} + + +static int +bsd_partition_get_flag (const PedPartition* part, PedPartitionFlag flag) +{ + /* no flags for bsd */ + return 0; +} + +static int +bsd_partition_is_flag_available (const PedPartition* part, + PedPartitionFlag flag) +{ + /* no flags for bsd */ + return 0; +} + + +static int +bsd_get_max_primary_partition_count (const PedDisk* disk) +{ + return BSD_MAXPARTITIONS; +} + +static int +bsd_partition_set_extended_system (PedPartition* part) +{ + return 1; +} + +static int +bsd_partition_align (PedPartition* part, const PedConstraint* constraint) +{ + /* no alignment problems */ + return 1; +} + +static int +bsd_partition_enumerate (PedPartition* part) +{ + int i; + PedPartition* p; + + /* never change the partition numbers */ + if (part->num != -1) + return 1; + for (i = 1; i <= BSD_MAXPARTITIONS; i++) { + p = ped_disk_get_partition (part->geom.disk, i); + if (!p) { + part->num = i; + return 1; + } + } + + /* failed to allocate a number */ + return 0; +} + +static int +bsd_alloc_metadata (PedDisk* disk) +{ + /* no metadata per partition */ + return 1; +} Index: libparted/libparted.c =================================================================== RCS file: /mnt/devel/CVS/parted/libparted/libparted.c,v retrieving revision 1.1.1.2 retrieving revision 1.1.1.2.2.1 diff -u -u -r1.1.1.2 -r1.1.1.2.2.1 --- libparted/libparted.c 2000/11/30 17:51:11 1.1.1.2 +++ libparted/libparted.c 2000/12/08 23:18:44 1.1.1.2.2.1 @@ -63,6 +63,7 @@ ped_disk_msdos_init (); ped_disk_pc98_init (); ped_disk_mac_init (); + ped_disk_bsd_init (); } static void @@ -97,6 +98,7 @@ ped_disk_pc98_done (); ped_disk_loop_done (); ped_disk_mac_done (); + ped_disk_bsd_done (); } static void Index: libparted/fs_ext2/interface.c =================================================================== RCS file: /mnt/devel/CVS/parted/libparted/fs_ext2/interface.c,v retrieving revision 1.1.1.2 retrieving revision 1.1.1.2.2.1 diff -u -u -r1.1.1.2 -r1.1.1.2.2.1 --- libparted/fs_ext2/interface.c 2000/11/30 17:51:11 1.1.1.2 +++ libparted/fs_ext2/interface.c 2000/12/08 23:18:44 1.1.1.2.2.1 @@ -21,7 +21,7 @@ * merged 1.1.11 changes (by Andrew) */ -static const char _interface_c[] = "$Id: interface.c,v 1.1.1.2 2000/11/30 17:51:11 msw Exp $"; +static const char _interface_c[] = "$Id: interface.c,v 1.1.1.2.2.1 2000/12/08 23:18:44 msw Exp $"; #include "config.h" @@ -30,6 +30,7 @@ #include #include #include +#include #include "ext2.h" #include "parted_io.h" @@ -334,6 +335,12 @@ else strcpy (mac_data->system_name, "Apple_UNIX_SVR2"); mac_data->status = 0x33; + return 1; + } + + if (strcmp (disk_type->name, BSD_NAME) == 0) { + BSDPartitionData* bsd_data = part->disk_specific; + bsd_data->type = 0x8; return 1; } Index: libparted/fs_linux_swap/linux_swap.c =================================================================== RCS file: /mnt/devel/CVS/parted/libparted/fs_linux_swap/linux_swap.c,v retrieving revision 1.1.1.1 retrieving revision 1.1.1.1.2.1 diff -u -u -r1.1.1.1 -r1.1.1.1.2.1 --- libparted/fs_linux_swap/linux_swap.c 2000/11/20 16:18:15 1.1.1.1 +++ libparted/fs_linux_swap/linux_swap.c 2000/12/08 23:18:44 1.1.1.1.2.1 @@ -31,6 +31,7 @@ #include #include #include +#include #include #if ENABLE_NLS @@ -562,6 +563,12 @@ return 0; } mac_data->status = 0x33; + return 1; + } + + if (strcmp (disk_type->name, BSD_NAME) == 0) { + BSDPartitionData* bsd_data = part->disk_specific; + bsd_data->type = 0x1; return 1; }