/*
    libparted - a library for manipulating disk partitions
    Copyright (C) 2001, 2002, 2005, 2007 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/

#include <config.h>
#include <parted/parted.h>
#include <parted/debug.h>
#include <parted/endian.h>

#include "dvh.h"

#if ENABLE_NLS
#  include <libintl.h>
#  define _(String) dgettext (PACKAGE, String)
#else
#  define _(String) (String)
#endif /* ENABLE_NLS */

/* Default size for volhdr part, same val as IRIX's fx uses */
#define PTYPE_VOLHDR_DFLTSZ 4096

/* Partition numbers that seem to be strongly held convention */
#define PNUM_VOLHDR 8
#define PNUM_VOLUME 10

/* Other notes of interest:
 *  PED_PARTITION_EXTENDED is used for volume headers
 *  PED_PARTITION_LOGICAL  is used for bootfiles
 *  PED_PARTITION_NORMAL   is used for all else
 */

typedef struct _DVHDiskData {
	struct device_parameters	dev_params;
	int				swap;	/* part num of swap, 0=none */
	int				root;	/* part num of root, 0=none */
	int				boot;	/* part num of boot, 0=none */
} DVHDiskData;

typedef struct _DVHPartData {
	int	type;
	char	name[VDNAMESIZE + 1];	/* boot volumes only */
	int	real_file_size;		/* boot volumes only */
} DVHPartData;

static PedDiskType dvh_disk_type;

static int
dvh_probe (const PedDevice *dev)
{
	struct volume_header	vh;

        if (dev->sector_size != 512)
                return 0;

	if (!ped_device_read (dev, &vh, 0, 1))
		return 0;

	return PED_BE32_TO_CPU (vh.vh_magic) == VHMAGIC;
}

#ifndef DISCOVER_ONLY
static int
dvh_clobber (PedDevice* dev)
{
	char	zeros[512];

	memset (zeros, 0, 512);
	return ped_device_write (dev, zeros, 0, 1);
}
#endif /* !DISCOVER_ONLY */

static PedDisk*
dvh_alloc (const PedDevice* dev)
{
	PedDisk*	disk;
	DVHDiskData*	dvh_disk_data;
	PedPartition*	volume_part;
	PedConstraint*	constraint_any;

	disk = _ped_disk_alloc (dev, &dvh_disk_type);
	if (!disk)
		goto error;

	disk->disk_specific = dvh_disk_data
		= ped_malloc (sizeof (DVHDiskData));
	if (!dvh_disk_data)
		goto error_free_disk;

	memset (&dvh_disk_data->dev_params, 0,
		sizeof (struct device_parameters));
	dvh_disk_data->swap = 0;
	dvh_disk_data->root = 0;
	dvh_disk_data->boot = 0;

	volume_part = ped_partition_new (disk, PED_PARTITION_EXTENDED, NULL,
					 0, PTYPE_VOLHDR_DFLTSZ - 1);
	if (!volume_part)
		goto error_free_disk_specific;
	volume_part->num = PNUM_VOLHDR + 1;
	constraint_any = ped_constraint_any (dev);
	if (!ped_disk_add_partition (disk, volume_part, constraint_any))
		goto error_destroy_constraint_any;
	ped_constraint_destroy (constraint_any);
	return disk;

error_destroy_constraint_any:
	ped_constraint_destroy (constraint_any);
	ped_partition_destroy (volume_part);
error_free_disk_specific:
	ped_free (disk->disk_specific);
error_free_disk:
	ped_free (disk);
error:
	return NULL;
}

static PedDisk*
dvh_duplicate (const PedDisk* disk)
{
	PedDisk*	new_disk;
	DVHDiskData*	new_dvh_disk_data;
	DVHDiskData*	old_dvh_disk_data = disk->disk_specific;

	PED_ASSERT (old_dvh_disk_data != NULL, goto error);

	new_disk = _ped_disk_alloc (disk->dev, &dvh_disk_type);
	if (!new_disk)
		goto error;

	new_disk->disk_specific = new_dvh_disk_data
		= ped_malloc (sizeof (DVHDiskData));
	if (!new_dvh_disk_data)
		goto error_free_new_disk;

	new_dvh_disk_data->dev_params = old_dvh_disk_data->dev_params;
	return new_disk;

error_free_new_disk:
	ped_free (new_disk);
error:
	return NULL;
}

static void
dvh_free (PedDisk* disk)
{
	ped_free (disk->disk_specific);
	_ped_disk_free (disk);
}

/* two's complement 32-bit checksum */
static uint32_t
_checksum (const uint32_t* base, size_t size)
{
	uint32_t	sum = 0;
	size_t		i;

	for (i = 0; i < size / sizeof (uint32_t); i++)
		sum = sum - PED_BE32_TO_CPU (base[i]);

	return sum;
}

/* try to make a reasonable volume header partition... */
static PedExceptionOption
_handle_no_volume_header (PedDisk* disk)
{
	PedExceptionOption	ret;
	PedPartition*		part;
	PedConstraint*		constraint;

	switch (ped_exception_throw (
		PED_EXCEPTION_WARNING,
		PED_EXCEPTION_FIX + PED_EXCEPTION_CANCEL,
		_("%s has no extended partition (volume header partition)."),
		disk->dev->path)) {
		case PED_EXCEPTION_UNHANDLED:
		case PED_EXCEPTION_FIX:
		default:
			part = ped_partition_new (
				disk, PED_PARTITION_EXTENDED, NULL,
				0, PTYPE_VOLHDR_DFLTSZ - 1);
			if (!part)
				goto error;
			part->num = PNUM_VOLHDR + 1;
			constraint = ped_constraint_any (part->disk->dev);
			if (!constraint)
				goto error_destroy_part;
			if (!ped_disk_add_partition (disk, part, constraint))
				goto error_destroy_constraint;
			ped_constraint_destroy (constraint);
			ret = PED_EXCEPTION_FIX;
			break;

		case PED_EXCEPTION_CANCEL:
			goto error;
	}
	return ret;

error_destroy_constraint:
	ped_constraint_destroy (constraint);
error_destroy_part:
	ped_partition_destroy (part);
error:
	return PED_EXCEPTION_CANCEL;
}

static PedPartition*
_parse_partition (PedDisk* disk, struct partition_table* pt)
{
	PedPartition*	part;
	DVHPartData*	dvh_part_data;
	PedSector	start = PED_BE32_TO_CPU (pt->pt_firstlbn);
	PedSector	length = PED_BE32_TO_CPU (pt->pt_nblks);

	part = ped_partition_new (disk,
			          pt->pt_type ? 0 : PED_PARTITION_EXTENDED,
				  NULL,
				  start, start + length - 1);
	if (!part)
		return NULL;

	dvh_part_data = part->disk_specific;
	dvh_part_data->type = PED_BE32_TO_CPU (pt->pt_type);
	strcpy (dvh_part_data->name, "");

	return part;
}

static PedPartition*
_parse_boot_file (PedDisk* disk, struct volume_directory* vd)
{
	PedPartition*	part;
	DVHPartData*	dvh_part_data;
	PedSector	start = PED_BE32_TO_CPU (vd->vd_lbn);
	int		length = PED_BE32_TO_CPU (vd->vd_nbytes);

	part = ped_partition_new (disk, PED_PARTITION_LOGICAL, NULL,
				  start, start + length/512 - 1);
	if (!part)
		return NULL;

	dvh_part_data = part->disk_specific;
	dvh_part_data->real_file_size = length;

	strncpy (dvh_part_data->name, vd->vd_name, VDNAMESIZE);
	dvh_part_data->name[VDNAMESIZE] = 0;
	return part;
}

static int dvh_write (const PedDisk* disk);

/* YUCK
 *
 *  If you remove a boot/root/swap partition, the disk->disk_specific
 * thing isn't updated.  (Probably reflects a design bug somewhere...)
 * Anyway, the workaround is: flush stale flags whenever we allocate
 * new partition numbers, and before we write to disk.
 */
static void
_flush_stale_flags (const PedDisk* disk)
{
	DVHDiskData*		dvh_disk_data = disk->disk_specific;

	if (dvh_disk_data->root
		       && !ped_disk_get_partition (disk, dvh_disk_data->root))
		dvh_disk_data->root = 0;
	if (dvh_disk_data->swap
		       && !ped_disk_get_partition (disk, dvh_disk_data->swap))
		dvh_disk_data->swap = 0;
	if (dvh_disk_data->boot
		       && !ped_disk_get_partition (disk, dvh_disk_data->boot))
		dvh_disk_data->boot = 0;
}

static int
dvh_read (PedDisk* disk)
{
	DVHDiskData*		dvh_disk_data = disk->disk_specific;
	int			i;
	struct volume_header	vh;
	char			boot_name [BFNAMESIZE + 1];
#ifndef DISCOVER_ONLY
	int			write_back = 0;
#endif

	PED_ASSERT (dvh_disk_data != NULL, return 0);

	ped_disk_delete_all (disk);

	if (!ped_device_read (disk->dev, &vh, 0, 1))
		return 0;

	if (_checksum ((uint32_t*) &vh, sizeof (struct volume_header))) {
		if (ped_exception_throw (
			PED_EXCEPTION_ERROR,
			PED_EXCEPTION_IGNORE_CANCEL,
			_("Checksum is wrong, indicating the partition "
			  "table is corrupt."))
				== PED_EXCEPTION_CANCEL)
			return 0;
	}

	PED_ASSERT (PED_BE32_TO_CPU (vh.vh_magic) == VHMAGIC, return 0);

	dvh_disk_data->dev_params = vh.vh_dp;
	strncpy (boot_name, vh.vh_bootfile, BFNAMESIZE);
	boot_name[BFNAMESIZE] = 0;

	/* normal partitions */
	for (i = 0; i < NPARTAB; i++) {
		PedPartition* part;
		PedConstraint* constraint_exact;

		if (!vh.vh_pt[i].pt_nblks)
			continue;
		/* Skip the whole-disk partition, parted disklikes overlap */
		if (PED_BE32_TO_CPU (vh.vh_pt[i].pt_type) == PTYPE_VOLUME)
			continue;

		part = _parse_partition (disk, &vh.vh_pt[i]);
		if (!part)
			goto error_delete_all;

		part->fs_type = ped_file_system_probe (&part->geom);
		part->num = i + 1;

		if (PED_BE16_TO_CPU (vh.vh_rootpt) == i)
			ped_partition_set_flag (part, PED_PARTITION_ROOT, 1);
		if (PED_BE16_TO_CPU (vh.vh_swappt) == i)
			ped_partition_set_flag (part, PED_PARTITION_SWAP, 1);

		constraint_exact = ped_constraint_exact (&part->geom);
		if (!ped_disk_add_partition(disk, part, constraint_exact)) {
			ped_partition_destroy (part);
			goto error_delete_all;
		}
		ped_constraint_destroy (constraint_exact);
	}

	if (!ped_disk_extended_partition (disk)) {
#ifdef DISCOVER_ONLY
		return 1;
#else
		switch (_handle_no_volume_header (disk)) {
			case PED_EXCEPTION_CANCEL:
				return 0;
			case PED_EXCEPTION_IGNORE:
				return 1;
			case PED_EXCEPTION_FIX:
				write_back = 1;
				break;
			default:
				break;
		}
#endif
	}

	/* boot partitions */
	for (i = 0; i < NVDIR; i++) {
		PedPartition* part;
		PedConstraint* constraint_exact;

		if (!vh.vh_vd[i].vd_nbytes)
			continue;

		part = _parse_boot_file (disk, &vh.vh_vd[i]);
		if (!part)
			goto error_delete_all;

		part->fs_type = ped_file_system_probe (&part->geom);
		part->num = NPARTAB + i + 1;

		if (!strcmp (boot_name, ped_partition_get_name (part)))
			ped_partition_set_flag (part, PED_PARTITION_BOOT, 1);

		constraint_exact = ped_constraint_exact (&part->geom);
		if (!ped_disk_add_partition(disk, part, constraint_exact)) {
			ped_partition_destroy (part);
			goto error_delete_all;
		}
		ped_constraint_destroy (constraint_exact);
	}
#ifndef DISCOVER_ONLY
	if (write_back)
		dvh_write (disk);
#endif
	return 1;

error_delete_all:
	ped_disk_delete_all (disk);
	return 0;
}

#ifndef DISCOVER_ONLY
static void
_generate_partition (PedPartition* part, struct partition_table* pt)
{
	DVHPartData*	dvh_part_data = part->disk_specific;

	/* Assert not a bootfile */
	PED_ASSERT ((part->type & PED_PARTITION_LOGICAL) == 0, return);

	pt->pt_nblks = PED_CPU_TO_BE32 (part->geom.length);
	pt->pt_firstlbn = PED_CPU_TO_BE32 (part->geom.start);
	pt->pt_type = PED_CPU_TO_BE32 (dvh_part_data->type);
}

static void
_generate_boot_file (PedPartition* part, struct volume_directory* vd)
{
	DVHPartData*	dvh_part_data = part->disk_specific;

	/* Assert it's a bootfile */
	PED_ASSERT ((part->type & PED_PARTITION_LOGICAL) != 0, return);

	vd->vd_nbytes = PED_CPU_TO_BE32 (dvh_part_data->real_file_size);
	vd->vd_lbn = PED_CPU_TO_BE32 (part->geom.start);

	memset (vd->vd_name, 0, VDNAMESIZE);
	strncpy (vd->vd_name, dvh_part_data->name, VDNAMESIZE);
}

static int
dvh_write (const PedDisk* disk)
{
	DVHDiskData*		dvh_disk_data = disk->disk_specific;
	struct volume_header	vh;
	int			i;

	PED_ASSERT (dvh_disk_data != NULL, return 0);

	_flush_stale_flags (disk);

	memset (&vh, 0, sizeof (struct volume_header));

	vh.vh_magic = PED_CPU_TO_BE32 (VHMAGIC);
	vh.vh_rootpt = PED_CPU_TO_BE16 (dvh_disk_data->root - 1);
	vh.vh_swappt = PED_CPU_TO_BE16 (dvh_disk_data->swap - 1);

	if (dvh_disk_data->boot) {
		PedPartition* boot_part;
		boot_part = ped_disk_get_partition (disk, dvh_disk_data->boot);
		strcpy (vh.vh_bootfile, ped_partition_get_name (boot_part));
	}

	vh.vh_dp = dvh_disk_data->dev_params;
	/* Set up rudimentary device geometry */
	vh.vh_dp.dp_cyls
		= PED_CPU_TO_BE16 ((short)disk->dev->bios_geom.cylinders);
	vh.vh_dp.dp_trks0 = PED_CPU_TO_BE16 ((short)disk->dev->bios_geom.heads);
	vh.vh_dp.dp_secs
		= PED_CPU_TO_BE16 ((short)disk->dev->bios_geom.sectors);
	vh.vh_dp.dp_secbytes = PED_CPU_TO_BE16 ((short)disk->dev->sector_size);

	for (i = 0; i < NPARTAB; i++) {
		PedPartition* part = ped_disk_get_partition (disk, i + 1);
		if (part)
			_generate_partition (part, &vh.vh_pt[i]);
	}

	/* whole disk partition
	 * This is only ever written here, and never modified 
	 * (or even shown) as it must contain the entire disk, 
	 * and parted does not like overlapping partitions
	 */
	vh.vh_pt[PNUM_VOLUME].pt_nblks = PED_CPU_TO_BE32 (disk->dev->length);
	vh.vh_pt[PNUM_VOLUME].pt_firstlbn = PED_CPU_TO_BE32 (0);
	vh.vh_pt[PNUM_VOLUME].pt_type = PED_CPU_TO_BE32 (PTYPE_VOLUME);

	for (i = 0; i < NVDIR; i++) {
		PedPartition* part = ped_disk_get_partition (disk,
							     i + 1 + NPARTAB);
		if (part)
			_generate_boot_file (part, &vh.vh_vd[i]);
	}

	vh.vh_csum = 0;
	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);
}
#endif /* !DISCOVER_ONLY */

static PedPartition*
dvh_partition_new (const PedDisk* disk, PedPartitionType part_type,
		    const PedFileSystemType* fs_type,
		    PedSector start, PedSector end)
{
	PedPartition* part;
	DVHPartData* dvh_part_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 = NULL;
		return part;
	}

	dvh_part_data = part->disk_specific =
		ped_malloc (sizeof (DVHPartData));
	if (!dvh_part_data)
		goto error_free_part;

	dvh_part_data->type = (part_type == PED_PARTITION_EXTENDED)
					? PTYPE_VOLHDR
					: PTYPE_RAW;
	strcpy (dvh_part_data->name, "");
	dvh_part_data->real_file_size = part->geom.length * 512;
	return part;

error_free_part:
	_ped_partition_free (part);
error:
	return NULL;
}

static PedPartition*
dvh_partition_duplicate (const PedPartition* part)
{
	PedPartition* result;
	DVHPartData* part_data = part->disk_specific;
	DVHPartData* result_data;

	result = _ped_partition_alloc (part->disk, part->type, part->fs_type,
				       part->geom.start, part->geom.end);
	if (!result)
		goto error;
	result->num = part->num;

	if (!ped_partition_is_active (part)) {
		result->disk_specific = NULL;
		return result;
	}

	result_data = result->disk_specific =
		ped_malloc (sizeof (DVHPartData));
	if (!result_data)
		goto error_free_part;

	result_data->type = part_data->type;
	strcpy (result_data->name, part_data->name);
	result_data->real_file_size = part_data->real_file_size;
	return result;

error_free_part:
	_ped_partition_free (result);
error:
	return NULL;
}

static void
dvh_partition_destroy (PedPartition* part)
{
	if (ped_partition_is_active (part)) {
		PED_ASSERT (part->disk_specific != NULL, return);
		ped_free (part->disk_specific);
	}
	_ped_partition_free (part);
}

static int
dvh_partition_set_system (PedPartition* part, const PedFileSystemType* fs_type)
{
	DVHPartData* dvh_part_data = part->disk_specific;

	part->fs_type = fs_type;

	if (part->type == PED_PARTITION_EXTENDED) {
		dvh_part_data->type = PTYPE_VOLHDR;
		return 1;
	}

	/* Is this a bootfile? */
	if (part->type == PED_PARTITION_LOGICAL)
		return 1;

	if (fs_type && !strcmp (fs_type->name, "xfs"))
		dvh_part_data->type = PTYPE_XFS;
	else
		dvh_part_data->type = PTYPE_RAW;
	return 1;
}

static int
dvh_partition_set_flag (PedPartition* part, PedPartitionFlag flag, int state)
{
	DVHDiskData* dvh_disk_data = part->disk->disk_specific;

	switch (flag) {
	case PED_PARTITION_ROOT:
		if (part->type != 0 && state) {
#ifndef DISCOVER_ONLY
			ped_exception_throw (
				PED_EXCEPTION_ERROR,
				PED_EXCEPTION_CANCEL,
				_("Only primary partitions can be root "
				  "partitions."));
#endif
			return 0;
		}
		dvh_disk_data->root = state ? part->num : 0;
		break;

	case PED_PARTITION_SWAP:
		if (part->type != 0 && state) {
#ifndef DISCOVER_ONLY
			ped_exception_throw (
				PED_EXCEPTION_ERROR,
				PED_EXCEPTION_CANCEL,
				_("Only primary partitions can be swap "
				  "partitions."));
			return 0;
#endif
		}
		dvh_disk_data->swap = state ? part->num : 0;
		break;

	case PED_PARTITION_BOOT:
		if (part->type != PED_PARTITION_LOGICAL && state) {
#ifndef DISCOVER_ONLY
			ped_exception_throw (
				PED_EXCEPTION_ERROR,
				PED_EXCEPTION_CANCEL,
				_("Only logical partitions can be a boot "
				  "file."));
#endif
			return 0;
		}
		dvh_disk_data->boot = state ? part->num : 0;
		break;

	case PED_PARTITION_LVM:
	case PED_PARTITION_LBA:
	case PED_PARTITION_HIDDEN:
	case PED_PARTITION_RAID:
	default:
		return 0;
	}
	return 1;
}

static int
dvh_partition_get_flag (const PedPartition* part, PedPartitionFlag flag)
{
	DVHDiskData* dvh_disk_data = part->disk->disk_specific;

	switch (flag) {
	case PED_PARTITION_ROOT:
		return dvh_disk_data->root == part->num;

	case PED_PARTITION_SWAP:
		return dvh_disk_data->swap == part->num;

	case PED_PARTITION_BOOT:
		return dvh_disk_data->boot == part->num;

	case PED_PARTITION_LVM:
	case PED_PARTITION_LBA:
	case PED_PARTITION_HIDDEN:
	case PED_PARTITION_RAID:
	default:
		return 0;
	}
	return 1;
}

static int
dvh_partition_is_flag_available (const PedPartition* part,
				  PedPartitionFlag flag)
{
	switch (flag) {
	case PED_PARTITION_ROOT:
	case PED_PARTITION_SWAP:
	case PED_PARTITION_BOOT:
		return 1;

	case PED_PARTITION_LVM:
	case PED_PARTITION_LBA:
	case PED_PARTITION_HIDDEN:
	case PED_PARTITION_RAID:
	default:
		return 0;
	}
	return 1;
}

static void
dvh_partition_set_name (PedPartition* part, const char* name)
{
	DVHPartData* dvh_part_data = part->disk_specific;

	if (part->type == PED_PARTITION_LOGICAL) {
		/* Bootfile */
		strncpy (dvh_part_data->name, name, VDNAMESIZE);
		dvh_part_data->name[VDNAMESIZE] = 0;
	} else {
#ifndef DISCOVER_ONLY
		ped_exception_throw (
			PED_EXCEPTION_ERROR,
			PED_EXCEPTION_CANCEL,
			_("Only logical partitions (boot files) have a name."));
#endif
	}
}

static const char*
dvh_partition_get_name (const PedPartition* part)
{
	DVHPartData* dvh_part_data = part->disk_specific;
	return dvh_part_data->name;
}

/* The constraint for the volume header partition is different, because it must
 * contain the first sector of the disk.
 */
static PedConstraint*
_get_extended_constraint (PedDisk* disk)
{
        PedGeometry     min_geom;
	if (!ped_geometry_init (&min_geom, disk->dev, 0, 1))
		return NULL;
        return ped_constraint_new_from_min (&min_geom);
}

static PedConstraint*
_get_primary_constraint (PedDisk* disk)
{
        PedGeometry     max_geom;
	if (!ped_geometry_init (&max_geom, disk->dev, 1, disk->dev->length - 1))
		return NULL;
        return ped_constraint_new_from_max (&max_geom);
}

static int
dvh_partition_align (PedPartition* part, const PedConstraint* constraint)
{
        PED_ASSERT (part != NULL, return 0);

	if (_ped_partition_attempt_align (
			part, constraint,
			(part->type == PED_PARTITION_EXTENDED)
				? _get_extended_constraint (part->disk)
				: _get_primary_constraint (part->disk)))
		return 1;

#ifndef DISCOVER_ONLY
	ped_exception_throw (
		PED_EXCEPTION_ERROR,
		PED_EXCEPTION_CANCEL,
		_("Unable to satisfy all constraints on the partition."));
#endif
	return 0;
}

static int
dvh_partition_enumerate (PedPartition* part)
{
	int i;

	/* never change the partition numbers */
	if (part->num != -1)
		return 1;

	_flush_stale_flags (part->disk);

	if (part->type & PED_PARTITION_LOGICAL) {
		/* Bootfile */
		for (i = 1 + NPARTAB; i <= NPARTAB + NVDIR; i++) {
			if (!ped_disk_get_partition (part->disk, i)) {
				part->num = i;
				return 1;
			}
		}
		PED_ASSERT (0, return 0);
	} else if (part->type & PED_PARTITION_EXTENDED) {
		/* Volheader */
		part->num = PNUM_VOLHDR + 1;
	} else {
		for (i = 1; i <= NPARTAB; i++) {
			/* reserved for full volume partition */
			if (i == PNUM_VOLUME + 1)
				continue;

			if (!ped_disk_get_partition (part->disk, i)) {
				part->num = i;
				return 1;
			}
		}
		ped_exception_throw (
			PED_EXCEPTION_ERROR,
			PED_EXCEPTION_CANCEL,
			_("Too many primary partitions"));
	}

	return 0;
}

static int
dvh_get_max_primary_partition_count (const PedDisk* disk)
{
	return NPARTAB;
}

static int
dvh_alloc_metadata (PedDisk* disk)
{
	PedPartition* part;
	PedPartition* extended_part;
	PedConstraint* constraint_exact;
	PedPartitionType metadata_type;
	PED_ASSERT(disk != NULL, return 0);

	/* We don't need to "protect" the start of the disk from the volume
	 * header.
	 */
	extended_part = ped_disk_extended_partition (disk);
	if (extended_part && extended_part->geom.start == 0)
		metadata_type = PED_PARTITION_METADATA | PED_PARTITION_LOGICAL;
	else
		metadata_type = PED_PARTITION_METADATA;

	part = ped_partition_new (disk, metadata_type, NULL, 0, 0);
	if (!part)
		goto error;

	constraint_exact = ped_constraint_exact (&part->geom);
	if (!ped_disk_add_partition (disk, part, constraint_exact))
		goto error_destroy_part;
	ped_constraint_destroy (constraint_exact);
	return 1;

	ped_constraint_destroy (constraint_exact);
error_destroy_part:
	ped_partition_destroy (part);
error:
	return 0;
}

static PedDiskOps dvh_disk_ops = {
	probe:			dvh_probe,
#ifndef DISCOVER_ONLY
	clobber:		dvh_clobber,
#else
	clobber:		NULL,
#endif
	alloc:			dvh_alloc,
	duplicate:		dvh_duplicate,
	free:			dvh_free,
	read:			dvh_read,
#ifndef DISCOVER_ONLY
	write:			dvh_write,
#else
	write:			NULL,
#endif

	partition_new:		dvh_partition_new,
	partition_duplicate:	dvh_partition_duplicate,
	partition_destroy:	dvh_partition_destroy,
	partition_set_system:	dvh_partition_set_system,
	partition_set_flag:	dvh_partition_set_flag,
	partition_get_flag:	dvh_partition_get_flag,
	partition_is_flag_available:	dvh_partition_is_flag_available,
	partition_set_name:	dvh_partition_set_name,
	partition_get_name:	dvh_partition_get_name,
	partition_align:	dvh_partition_align,
	partition_enumerate:	dvh_partition_enumerate,

	alloc_metadata:		dvh_alloc_metadata,
	get_max_primary_partition_count:
				dvh_get_max_primary_partition_count
};

static PedDiskType dvh_disk_type = {
	next:		NULL,
	name:		"dvh",
	ops:		&dvh_disk_ops,
	features:	PED_DISK_TYPE_PARTITION_NAME | PED_DISK_TYPE_EXTENDED
};

void
ped_disk_dvh_init ()
{
	PED_ASSERT (sizeof (struct volume_header) == 512, return);

	ped_disk_type_register (&dvh_disk_type);
}

void
ped_disk_dvh_done ()
{
	ped_disk_type_unregister (&dvh_disk_type);
}
