#include <parted/parted.h>
#include <parted/debug.h>
#include <parted/endian.h>
+#include <stdbool.h>
#include "dvh.h"
+#include "pt-tools.h"
#if ENABLE_NLS
# include <libintl.h>
static PedDiskType dvh_disk_type;
+/* FIXME: factor out this function: copied from aix.c, with changes to
+ the description, and an added sector number argument.
+ Read sector, SECTOR_NUM (which has length DEV->sector_size) into malloc'd
+ storage. If the read fails, free the memory and return zero without
+ modifying *BUF. Otherwise, set *BUF to the new buffer and return 1. */
static int
-dvh_probe (const PedDevice *dev)
+read_sector (const PedDevice *dev, PedSector sector_num, char **buf)
{
- struct volume_header vh;
+ char *b = ped_malloc (dev->sector_size);
+ PED_ASSERT (b != NULL, return 0);
+ if (!ped_device_read (dev, b, sector_num, 1)) {
+ free (b);
+ return 0;
+ }
+ *buf = b;
+ return 1;
+}
- if (dev->sector_size != 512)
- return 0;
+static int
+dvh_probe (const PedDevice *dev)
+{
+ struct volume_header *vh;
- if (!ped_device_read (dev, &vh, 0, 1))
+ char *label;
+ if (!read_sector (dev, 0, &label))
return 0;
- return PED_BE32_TO_CPU (vh.vh_magic) == VHMAGIC;
+ vh = (struct volume_header *) label;
+
+ bool found = PED_BE32_TO_CPU (vh->vh_magic) == VHMAGIC;
+ free (label);
+ return found;
}
#ifndef DISCOVER_ONLY
static int
dvh_clobber (PedDevice* dev)
{
- char zeros[512];
-
- memset (zeros, 0, 512);
- return ped_device_write (dev, zeros, 0, 1);
+ char *zeros = ped_calloc (dev->sector_size);
+ if (zeros == NULL)
+ return 0;
+ int ok = ped_device_write (dev, zeros, 0, 1);
+ free (zeros);
+ return ok;
}
#endif /* !DISCOVER_ONLY */
ped_disk_delete_all (disk);
- if (!ped_device_read (disk->dev, &vh, 0, 1))
+ char *s0;
+ if (!read_sector (disk->dev, 0, &s0))
return 0;
+ memcpy (&vh, s0, sizeof vh);
+ free (s0);
if (_checksum ((uint32_t*) &vh, sizeof (struct volume_header))) {
if (ped_exception_throw (
vh.vh_csum = PED_CPU_TO_BE32 (_checksum ((uint32_t*) &vh,
sizeof (struct volume_header)));
- return ped_device_write (disk->dev, &vh, 0, 1)
- && ped_device_sync (disk->dev);
+ return (ptt_write_sector (disk, &vh, sizeof vh)
+ && ped_device_sync (disk->dev));
}
#endif /* !DISCOVER_ONLY */
return 0;
}
+/*
+ * Enforce some restrictions inherent in the dvh partition table format.
+ * 1. Partition size must be smaller than 2^32 (unsigned int) sectors.
+ * If sector size is 512 bytes, this results in 2T aprox.
+ * 2. Partition starting sector number must be smaller than 2^32.
+ */
+static bool
+dvh_partition_check (const PedPartition* part)
+{
+ if (!ptt_partition_max_start_len("dvh", part))
+ return false;
+
+ return true;
+}
+
static PedDiskOps dvh_disk_ops = {
probe: dvh_probe,
#ifndef DISCOVER_ONLY
partition_get_name: dvh_partition_get_name,
partition_align: dvh_partition_align,
partition_enumerate: dvh_partition_enumerate,
+ partition_check: dvh_partition_check,
alloc_metadata: dvh_alloc_metadata,
get_max_primary_partition_count: dvh_get_max_primary_partition_count,