--- old/usr/src/lib/libparted/common/libparted/disk.c	2014-07-17 16:13:47.906723145 +0200
+++ /dev/null	2014-07-17 16:13:47.000000000 +0200
@@ -1,2265 +0,0 @@
- /*
-    libparted - a library for manipulating disk partitions
-    Copyright (C) 1999, 2000, 2001, 2002, 2003, 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 3 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, see <http://www.gnu.org/licenses/>.
-*/
-
-/** \file disk.c */
-
-/**
- * \addtogroup PedDisk
- *
- * \brief Disk label access.
- * 
- * Most programs will need to use ped_disk_new() or ped_disk_new_fresh() to get
- * anything done.  A PedDisk is always associated with a device and has a
- * partition table.  There are different types of partition tables (or disk
- * labels).  These are represented by the PedDiskType enumeration.
- *
- * @{
- */
-
-#include <config.h>
-
-#include <parted/parted.h>
-#include <parted/debug.h>
-
-#if ENABLE_NLS
-#  include <libintl.h>
-#  define _(String) dgettext (PACKAGE, String)
-#  define N_(String) (String)
-#else
-#  define _(String) (String)
-#  define N_(String) (String)
-#endif /* ENABLE_NLS */
-
-/* UPDATE MODE functions */
-#ifdef DEBUG
-static int _disk_check_sanity (PedDisk* disk);
-#endif
-static void _disk_push_update_mode (PedDisk* disk);
-static void _disk_pop_update_mode (PedDisk* disk);
-static int _disk_raw_insert_before (PedDisk* disk, PedPartition* loc,
-				    PedPartition* part);
-static int _disk_raw_insert_after (PedDisk* disk, PedPartition* loc,
-				   PedPartition* part);
-static int _disk_raw_remove (PedDisk* disk, PedPartition* part);
-static int _disk_raw_add (PedDisk* disk, PedPartition* part);
-
-static PedDiskType*	disk_types = NULL;
-
-void
-ped_disk_type_register (PedDiskType* disk_type)
-{
-	PED_ASSERT (disk_type != NULL, return);
-	PED_ASSERT (disk_type->ops != NULL, return);
-	PED_ASSERT (disk_type->name != NULL, return);
-	
-	/* pretend that "next" isn't part of the struct :-) */
-	((struct _PedDiskType*) disk_type)->next = disk_types;
-	disk_types = (struct _PedDiskType*) disk_type;
-}
-
-void
-ped_disk_type_unregister (PedDiskType* disk_type)
-{
-	PedDiskType*	walk;
-	PedDiskType*	last = NULL;
-
-	PED_ASSERT (disk_types != NULL, return);
-	PED_ASSERT (disk_type != NULL, return);
-
-	for (walk = disk_types; walk && walk != disk_type;
-                last = walk, walk = walk->next);
-
-	PED_ASSERT (walk != NULL, return);
-	if (last)
-		((struct _PedDiskType*) last)->next = disk_type->next;
-	else
-		disk_types = disk_type->next;
-}
-
-/**
- * Deprecated: use ped_disk_type_regiser.
- */
-void
-ped_register_disk_type (PedDiskType* disk_type)
-{
-        ped_disk_type_register (disk_type);
-}
-
-/**
- * Deprecated: use ped_disk_type_unregiser.
- */
-void
-ped_unregister_disk_type (PedDiskType* disk_type)
-{
-        ped_disk_type_unregister (disk_type);
-}
-
-/**
- * Return the next disk type registers, after "type".  If "type" is
- * NULL, returns the first disk type.
- *
- * \return Next disk; NULL if "type" is the last registered disk type.
- */
-PedDiskType*
-ped_disk_type_get_next (PedDiskType* type)
-{
-	if (type)
-		return type->next;
-	else
-		return disk_types;
-}
-
-/**
- * Return the disk type with a name of "name".
- *
- * \return Disk type; NULL if no match.
- */
-PedDiskType*
-ped_disk_type_get (const char* name)
-{
-	PedDiskType*	walk = NULL;
-
-	PED_ASSERT (name != NULL, return NULL);
-
-	for (walk = ped_disk_type_get_next (NULL); walk;
-	     walk = ped_disk_type_get_next (walk))
-			if (strcasecmp (walk->name, name) == 0)
-					break;
-
-	return walk;
-}
-
-/**
- * Return the type of partition table detected on "dev".
- *
- * \return Type; NULL if none was detected.
- */
-PedDiskType*
-ped_disk_probe (PedDevice* dev)
-{
-        PedDiskType *walk = NULL;
-
-        PED_ASSERT (dev != NULL, return NULL);
-
-        if (!ped_device_open (dev))
-                return NULL;
-
-        ped_exception_fetch_all ();
-        for (walk = ped_disk_type_get_next (NULL); walk;
-             walk = ped_disk_type_get_next (walk)) {
-                if (walk->ops->probe (dev))
-                        break;
-        }
-
-        if (ped_exception)
-                ped_exception_catch ();
-        ped_exception_leave_all ();
-
-        ped_device_close (dev);
-        return walk;
-}
-
-/**
- * Read the partition table off a device (if one is found). 
- * 
- * \warning May modify \p dev->cylinders, \p dev->heads and \p dev->sectors
- *      if the partition table indicates that the existing values
- *      are incorrect.
- * 
- * \return A new \link _PedDisk PedDisk \endlink object;
- *         NULL on failure (e.g. partition table not detected).
- */
-PedDisk*
-ped_disk_new (PedDevice* dev)
-{
-	PedDiskType*	type;
-	PedDisk*	disk;
-
-	PED_ASSERT (dev != NULL, return NULL);
-
-	if (!ped_device_open (dev))
-		goto error;
-
-	type = ped_disk_probe (dev);
-	if (!type) {
-		ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
-			_("%s: unrecognised disk label"),
-			dev->path);
-		goto error_close_dev;
-	}
-	disk = ped_disk_new_fresh (dev, type);
-	if (!disk)
-		goto error_close_dev;
-	if (!type->ops->read (disk))
-		goto error_destroy_disk;
-	disk->needs_clobber = 0;
-	ped_device_close (dev);
-	return disk;
-
-error_destroy_disk:
-	ped_disk_destroy (disk);
-error_close_dev:
-	ped_device_close (dev);
-error:
-	return NULL;
-}
-
-static int
-_add_duplicate_part (PedDisk* disk, PedPartition* old_part)
-{
-	PedPartition*	new_part;
-	PedConstraint*	constraint_exact;
-
-	new_part = disk->type->ops->partition_duplicate (old_part);
-	if (!new_part)
-		goto error;
-	new_part->disk = disk;
-
-	constraint_exact = ped_constraint_exact (&new_part->geom);
-	if (!constraint_exact)
-		goto error_destroy_new_part;
-	if (!ped_disk_add_partition (disk, new_part, constraint_exact))
-       		goto error_destroy_constraint_exact;
-	ped_constraint_destroy (constraint_exact);
-	return 1;
-
-error_destroy_constraint_exact:
-	ped_constraint_destroy (constraint_exact);
-error_destroy_new_part:
-	ped_partition_destroy (new_part);
-error:
-	return 0;
-}
-
-/**
- * Clone a \link _PedDisk PedDisk \endlink object.
- *
- * \return Deep copy of \p old_disk, NULL on failure.
- */
-PedDisk*
-ped_disk_duplicate (const PedDisk* old_disk)
-{
-	PedDisk*	new_disk;
-	PedPartition*	old_part;
-
-	PED_ASSERT (old_disk != NULL, return NULL);
-	PED_ASSERT (!old_disk->update_mode, return NULL);
-	PED_ASSERT (old_disk->type->ops->duplicate != NULL, return NULL);
-	PED_ASSERT (old_disk->type->ops->partition_duplicate != NULL,
-		    return NULL);
-
-	new_disk = old_disk->type->ops->duplicate (old_disk);
-	if (!new_disk)
-		goto error;
-
-	_disk_push_update_mode (new_disk);
-	for (old_part = ped_disk_next_partition (old_disk, NULL); old_part;
-	     old_part = ped_disk_next_partition (old_disk, old_part)) {
-		if (ped_partition_is_active (old_part)) {
-			if (!_add_duplicate_part (new_disk, old_part))
-				goto error_destroy_new_disk;
-		}
-	}
-	_disk_pop_update_mode (new_disk);
-	return new_disk;
-
-error_destroy_new_disk:
-	ped_disk_destroy (new_disk);
-error:
-	return NULL;
-}
-
-/**
- * Remove all identifying signatures of a partition table,
- * except for partition tables of a given type.
- * 
- * \return 0 on error, 1 otherwise.
- * 
- * \sa ped_disk_clobber()
- */
-int
-ped_disk_clobber_exclude (PedDevice* dev, const PedDiskType* exclude)
-{
-	PedDiskType*	walk;
-
-	PED_ASSERT (dev != NULL, goto error);
-
-	if (!ped_device_open (dev))
-		goto error;
-
-	for (walk = ped_disk_type_get_next (NULL); walk;
-	     walk = ped_disk_type_get_next (walk)) {
-		int	probed;
-
-		if (walk == exclude)
-			continue;
-
-		ped_exception_fetch_all ();
-		probed = walk->ops->probe (dev);
-		if (!probed)
-			ped_exception_catch ();
-		ped_exception_leave_all ();
-
-		if (probed && walk->ops->clobber) {
-			if (!walk->ops->clobber (dev))
-				goto error_close_dev;
-		}
-	}
-	ped_device_close (dev);
-	return 1;
-
-error_close_dev:
-	ped_device_close (dev);
-error:
-	return 0;
-}
-
-/** 
- * Remove all identifying signatures of a partition table,
- * 
- * \return 0 on error, 1 otherwise.
- * 
- * \sa ped_disk_clobber_exclude()
- */
-int
-ped_disk_clobber (PedDevice* dev)
-{
-	return ped_disk_clobber_exclude (dev, NULL);
-}
-
-/**
- * Create a new partition table on \p dev.
- *
- * This new partition table is only created in-memory, and nothing is written
- * to disk until ped_disk_commit_to_dev() is called.
- * 
- * \return The newly constructed \link _PedDisk PedDisk \endlink,
- *      NULL on failure.
- */
-PedDisk*
-ped_disk_new_fresh (PedDevice* dev, const PedDiskType* type)
-{
-	PedDisk*	disk;
-
-	PED_ASSERT (dev != NULL, return NULL);
-	PED_ASSERT (type != NULL, return NULL);
-	PED_ASSERT (type->ops->alloc != NULL, return NULL);
-
-	disk = type->ops->alloc (dev);
-	if (!disk)
-       		goto error;
-	_disk_pop_update_mode (disk);
-	PED_ASSERT (disk->update_mode == 0, goto error_destroy_disk);
-
-	disk->needs_clobber = 1;
-	return disk;
-
-error_destroy_disk:
-	ped_disk_destroy (disk);
-error:
-	return NULL;
-}
-
-PedDisk*
-_ped_disk_alloc (const PedDevice* dev, const PedDiskType* disk_type)
-{
-	PedDisk*	disk;
-
-	disk = (PedDisk*) ped_malloc (sizeof (PedDisk));
-	if (!disk)
-		goto error;
-
-	disk->dev = (PedDevice*)dev;
-	disk->type = disk_type;
-	disk->update_mode = 1;
-	disk->part_list = NULL;
-	return disk;
-
-	ped_free (disk);
-error:
-	return NULL;
-}
-
-void
-_ped_disk_free (PedDisk* disk)
-{
-	_disk_push_update_mode (disk);
-	ped_disk_delete_all (disk);
-	ped_free (disk);
-}
-
-/**
- * Close \p disk.
- *
- * What this function does depends on the PedDiskType of \p disk,
- * but you can generally assume that outstanding writes are flushed
- * (this mainly means that _ped_disk_free is called).
- */
-void
-ped_disk_destroy (PedDisk* disk)
-{
-	PED_ASSERT (disk != NULL, return);
-	PED_ASSERT (!disk->update_mode, return);
-
-	disk->type->ops->free (disk);
-}
-
-/**
- * Tell the operating system kernel about the partition table layout
- * of \p disk.
- *
- * This is rather loosely defined: for example, on old versions of Linux,
- * it simply calls the BLKRRPART ioctl, which tells the kernel to
- * reread the partition table. On newer versions (2.4.x), it will
- * use the new blkpg interface to tell Linux where each partition
- * starts/ends, etc. In this case, Linux does not need to have support for
- * a specific type of partition table.
- * 
- * \return 0 on failure, 1 otherwise.
- */
-int
-ped_disk_commit_to_os (PedDisk* disk)
-{
-	PED_ASSERT (disk != NULL, return 0);
-
-	if (!ped_device_open (disk->dev))
-		goto error;
-	if (!ped_architecture->disk_ops->disk_commit (disk))
-		goto error_close_dev;
-	ped_device_close (disk->dev);
-	return 1;
-
-error_close_dev:
-	ped_device_close (disk->dev);
-error:
-	return 0;
-}
-
-/**
- * Write the changes made to the in-memory description
- * of a partition table to the device.
- *
- * \return 0 on failure, 1 otherwise.
- */
-int
-ped_disk_commit_to_dev (PedDisk* disk)
-{
-	PED_ASSERT (disk != NULL, goto error);
-	PED_ASSERT (!disk->update_mode, goto error);
-
-	if (!disk->type->ops->write) {
-		ped_exception_throw (
-			PED_EXCEPTION_ERROR,
-			PED_EXCEPTION_CANCEL,
-			_("This libparted doesn't have write support for "
-			  "%s.  Perhaps it was compiled read-only."),
-			disk->type->name);
-		goto error;
-	}
-
-	if (!ped_device_open (disk->dev))
-		goto error;
-
-	if (disk->needs_clobber) {
-		if (!ped_disk_clobber_exclude (disk->dev, disk->type))
-			goto error_close_dev;
-		disk->needs_clobber = 0;
-	}
-	if (!disk->type->ops->write (disk))
-		goto error_close_dev;
-	ped_device_close (disk->dev);
-	return 1;
-
-error_close_dev:
-	ped_device_close (disk->dev);
-error:
-	return 0;
-}
-
-/*
- * This function writes the in-memory changes to a partition table to
- * disk and informs the operating system of the changes.
- *
- * \note Equivalent to calling first ped_disk_commit_to_dev(), then
- *      ped_disk_commit_to_os().
- *
- * \return 0 on failure, 1 otherwise.
- */
-int
-ped_disk_commit (PedDisk* disk)
-{
-	if (!ped_disk_commit_to_dev (disk))
-		return 0;
-	return ped_disk_commit_to_os (disk);
-}
-
-/**
- * \addtogroup PedPartition
- *
- * @{
- */
-
-/**
- * Check whether a partition is mounted or busy in some
- * other way.
- *
- * \note An extended partition is busy if any logical partitions are mounted.
- *
- * \return \c 1 if busy.
- */
-int
-ped_partition_is_busy (const PedPartition* part)
-{
-	PED_ASSERT (part != NULL, return 1);
-
-	return ped_architecture->disk_ops->partition_is_busy (part);
-}
-
-/**
- * Return a path that can be used to address the partition in the
- * operating system.
- */
-char*
-ped_partition_get_path (const PedPartition* part)
-{
-	PED_ASSERT (part != NULL, return NULL);
-
-	return ped_architecture->disk_ops->partition_get_path (part);
-}
-
-/** @} */
-
-/**
- * \addtogroup PedDisk
- *
- * @{
- */
-
-/**
- * Perform a sanity check on a partition table.
- *
- * \note The check performed is generic (i.e. it does not depends on the label
- *      type of the disk.
- *
- * \throws PED_EXCEPTION_WARNING if a partition type ID does not match the file
- *      system on it.
- *
- * \return 0 if the check fails, 1 otherwise.
- */
-int
-ped_disk_check (const PedDisk* disk)
-{
-	PedPartition*	walk;
-
-	PED_ASSERT (disk != NULL, return 0);
-
-	for (walk = disk->part_list; walk;
-	     walk = ped_disk_next_partition (disk, walk)) {
-		const PedFileSystemType*	fs_type = walk->fs_type;
-		PedGeometry*			geom;
-		PedSector			length_error;
-		PedSector			max_length_error;
-
-		if (!ped_partition_is_active (walk) || !fs_type)
-			continue;
-
-		geom = ped_file_system_probe_specific (fs_type, &walk->geom);
-		if (!geom)
-			continue;
-
-		length_error = abs (walk->geom.length - geom->length);
-		max_length_error = PED_MAX (4096, walk->geom.length / 100);
-		if (!ped_geometry_test_inside (&walk->geom, geom)
-		    || length_error > max_length_error) {
-			char* part_size = ped_unit_format (disk->dev, walk->geom.length);
-			char* fs_size = ped_unit_format (disk->dev, geom->length);
-			PedExceptionOption choice;
-
-			choice = ped_exception_throw (
-				PED_EXCEPTION_WARNING,
-				PED_EXCEPTION_IGNORE_CANCEL,
-				_("Partition %d is %s, but the file system is "
-				  "%s."),
-				walk->num, part_size, fs_size);
-
-			ped_free (part_size);
-			ped_free (fs_size);
-
-			if (choice != PED_EXCEPTION_IGNORE)
-				return 0;
-		}
-	}
-
-	return 1;
-}
-
-/**
- * This function checks if a particular type of partition table supports
- * a feature.
- *
- * \return 1 if \p disk_type supports \p feature, 0 otherwise.
- */
-int
-ped_disk_type_check_feature (const PedDiskType* disk_type,
-			     PedDiskTypeFeature feature)
-{
-	return (disk_type->features & feature) != 0;
-}
-
-/**
- * Get the number of primary partitions.
- */
-int
-ped_disk_get_primary_partition_count (const PedDisk* disk)
-{
-	PedPartition*	walk;
-	int		count = 0;
-
-	PED_ASSERT (disk != NULL, return 0);
-
-	for (walk = disk->part_list; walk;
-	     walk = ped_disk_next_partition (disk, walk)) {
-		if (ped_partition_is_active (walk)
-				&& ! (walk->type & PED_PARTITION_LOGICAL))
-			count++;
-	}
-
-	return count;
-}
-
-/**
- * Get the highest partition number on \p disk.
- */
-int
-ped_disk_get_last_partition_num (const PedDisk* disk)
-{
-	PedPartition*	walk;
-	int		highest = -1;
-
-	PED_ASSERT (disk != NULL, return 0);
-
-	for (walk = disk->part_list; walk;
-	     walk = ped_disk_next_partition (disk, walk)) {
-		if (walk->num > highest)
-			highest = walk->num;
-	}
-
-	return highest;
-}
-
-/**
- * Get the maximum number of (primary) partitions the disk label supports.
- * 
- * For example, MacIntosh partition maps can have different sizes,
- * and accordingly support a different number of partitions.
- */
-int
-ped_disk_get_max_primary_partition_count (const PedDisk* disk)
-{
-	PED_ASSERT (disk->type != NULL, return 0);
-	PED_ASSERT (disk->type->ops->get_max_primary_partition_count != NULL,
-		    return 0);
-
-	return disk->type->ops->get_max_primary_partition_count (disk);
-}
-
-/**
- * \internal We turned a really nasty bureaucracy problem into an elegant maths
- * problem :-)  Basically, there are some constraints to a partition's
- * geometry:
- *
- * (1) it must start and end on a "disk" block, determined by the disk label
- * (not the hardware).  (constraint represented by a PedAlignment)
- *
- * (2) if we're resizing a partition, we MIGHT need to keep each block aligned.
- * Eg: if an ext2 file system has 4k blocks, then we can only move the start
- * by a multiple of 4k.  (constraint represented by a PedAlignment)
- *
- * (3) we need to keep the start and end within the device's physical
- * boundaries.  (constraint represented by a PedGeometry)
- *
- * Satisfying (1) and (2) simultaneously required a bit of fancy maths ;-)  See
- * ped_alignment_intersect()
- *
- * The application of these constraints is in disk_*.c's *_partition_align()
- * function.
- */
-static int
-_partition_align (PedPartition* part, const PedConstraint* constraint)
-{
-	const PedDiskType*	disk_type;
-
-	PED_ASSERT (part != NULL, return 0);
-	PED_ASSERT (part->num != -1, return 0);
-	PED_ASSERT (part->disk != NULL, return 0);
-	disk_type = part->disk->type;
-	PED_ASSERT (disk_type != NULL, return 0);
-	PED_ASSERT (disk_type->ops->partition_align != NULL, return 0);
-	PED_ASSERT (part->disk->update_mode, return 0);
-
-	return disk_type->ops->partition_align (part, constraint);
-}
-
-static int
-_partition_enumerate (PedPartition* part)
-{
-	const PedDiskType*	disk_type;
-
-	PED_ASSERT (part != NULL, return 0);
-	PED_ASSERT (part->disk != NULL, return 0);
-	disk_type = part->disk->type;
-	PED_ASSERT (disk_type != NULL, return 0);
-	PED_ASSERT (disk_type->ops->partition_enumerate != NULL, return 0);
-
-	return disk_type->ops->partition_enumerate (part);
-}
-
-/**
- * Gives all the (active) partitions a number.  It should preserve the numbers
- * and orders as much as possible.
- */
-static int
-ped_disk_enumerate_partitions (PedDisk* disk)
-{
-	PedPartition*	walk;
-	int		i;
-	int		end;
-
-	PED_ASSERT (disk != NULL, return 0);
-
-/* first "sort" already-numbered partitions.  (e.g. if a logical partition
- * is removed, then all logical partitions that were number higher MUST be
- * renumbered)
- */
-	end = ped_disk_get_last_partition_num (disk);
-	for (i=1; i<=end; i++) {
-		walk = ped_disk_get_partition (disk, i);
-		if (walk) {
-			if (!_partition_enumerate (walk))
-				return 0;
-		}
-	}
-
-/* now, number un-numbered partitions */
-	for (walk = disk->part_list; walk;
-	     walk = ped_disk_next_partition (disk, walk)) {
-		if (ped_partition_is_active (walk) && walk->num == -1) {
-			if (!_partition_enumerate (walk))
-				return 0;
-		}
-	}
-
-	return 1;
-}
-
-static int
-_disk_remove_metadata (PedDisk* disk)
-{
-	PedPartition*	walk = NULL;
-	PedPartition*	next;
-
-	PED_ASSERT (disk != NULL, return 0);
-
-	next = ped_disk_next_partition (disk, walk);
-
-	while (next) {
-		walk = next;
-		while (1) {
-			next = ped_disk_next_partition (disk, next);
-			if (!next || next->type & PED_PARTITION_METADATA)
-				break;
-		}
-		if (walk->type & PED_PARTITION_METADATA)
-			ped_disk_delete_partition (disk, walk);
-	}
-	return 1;
-}
-
-static int
-_disk_alloc_metadata (PedDisk* disk)
-{
-	PED_ASSERT (disk != NULL, return 0);
-
-	if (!disk->update_mode)
-		_disk_remove_metadata (disk);
-
-	return disk->type->ops->alloc_metadata (disk);
-}
-
-static int
-_disk_remove_freespace (PedDisk* disk)
-{
-	PedPartition*	walk;
-	PedPartition*	next;
-
-	walk = ped_disk_next_partition (disk, NULL);
-	for (; walk; walk = next) {
-		next = ped_disk_next_partition (disk, walk);
-
-		if (walk->type & PED_PARTITION_FREESPACE) {
-			_disk_raw_remove (disk, walk);
-			ped_partition_destroy (walk);
-		}
-	}
-
-	return 1;
-}
-
-static int
-_alloc_extended_freespace (PedDisk* disk)
-{
-	PedSector	last_end;
-	PedPartition*	walk;
-	PedPartition*	last;
-	PedPartition*	free_space;
-	PedPartition*	extended_part;
-
-	extended_part = ped_disk_extended_partition (disk);
-	if (!extended_part)
-		return 1;
-
-	last_end = extended_part->geom.start;
-	last = NULL;
-	
-	for (walk = extended_part->part_list; walk; walk = walk->next) {
-		if (walk->geom.start > last_end + 1) {
-			free_space = ped_partition_new (
-					disk,
-					PED_PARTITION_FREESPACE
-						| PED_PARTITION_LOGICAL,
-					NULL,
-					last_end + 1, walk->geom.start - 1);
-			_disk_raw_insert_before (disk, walk, free_space);
-		}
-
-		last = walk;
-		last_end = last->geom.end;
-	}
-
-	if (last_end < extended_part->geom.end) {
-		free_space = ped_partition_new (
-				disk,
-				PED_PARTITION_FREESPACE | PED_PARTITION_LOGICAL,
-				NULL,
-				last_end + 1, extended_part->geom.end);
-
-		if (last)
-			return _disk_raw_insert_after (disk, last, free_space);
-		else
-			extended_part->part_list = free_space;
-	}
-
-	return 1;
-}
-
-static int
-_disk_alloc_freespace (PedDisk* disk)
-{
-	PedSector	last_end;
-	PedPartition*	walk;
-	PedPartition*	last;
-	PedPartition*	free_space;
-
-	if (!_disk_remove_freespace (disk))
-		return 0;
-	if (!_alloc_extended_freespace (disk))
-		return 0;
-
-	last = NULL;
-	last_end = -1;
-
-	for (walk = disk->part_list; walk; walk = walk->next) {
-		if (walk->geom.start > last_end + 1) {
-			free_space = ped_partition_new (disk,
-					PED_PARTITION_FREESPACE, NULL,
-					last_end + 1, walk->geom.start - 1);
-			_disk_raw_insert_before (disk, walk, free_space);
-		}
-
-		last = walk;
-		last_end = last->geom.end;
-	}
-
-	if (last_end < disk->dev->length - 1) {
-		free_space = ped_partition_new (disk,
-					PED_PARTITION_FREESPACE, NULL,
-					last_end + 1, disk->dev->length - 1);
-		if (last)
-			return _disk_raw_insert_after (disk, last, free_space);
-		else
-			disk->part_list = free_space;
-	}
-
-	return 1;
-}
-
-/**
- * Update mode: used when updating the internal representation of the partition
- * table.  In update mode, the metadata and freespace placeholder/virtual
- * partitions are removed, making it much easier for various manipulation
- * routines...
- */
-static void
-_disk_push_update_mode (PedDisk* disk)
-{
-	if (!disk->update_mode) {
-#ifdef DEBUG
-		_disk_check_sanity (disk);
-#endif
-
-		_disk_remove_freespace (disk);
-		disk->update_mode++;
-		_disk_remove_metadata (disk);
-
-#ifdef DEBUG
-		_disk_check_sanity (disk);
-#endif
-	} else {
-		disk->update_mode++;
-	}
-}
-
-static void
-_disk_pop_update_mode (PedDisk* disk)
-{
-	PED_ASSERT (disk->update_mode, return);
-
-	if (disk->update_mode == 1) {
-	/* re-allocate metadata BEFORE leaving update mode, to prevent infinite
-	 * recursion (metadata allocation requires update mode)
-	 */
-#ifdef DEBUG
-		_disk_check_sanity (disk);
-#endif
-
-		_disk_alloc_metadata (disk);
-		disk->update_mode--;
-		_disk_alloc_freespace (disk);
-
-#ifdef DEBUG
-		_disk_check_sanity (disk);
-#endif
-	} else {
-		disk->update_mode--;
-	}
-}
-
-/** @} */
-
-/**
- * \addtogroup PedPartition
- *
- * \brief Partition access.
- * 
- * @{
- */
-
-PedPartition*
-_ped_partition_alloc (const PedDisk* disk, PedPartitionType type,
-		      const PedFileSystemType* fs_type,
-		      PedSector start, PedSector end)
-{
-	PedPartition*	part;
-
-	PED_ASSERT (disk != NULL, return 0);
-
-	part = (PedPartition*) ped_malloc (sizeof (PedPartition));
-	if (!part)
-		goto error;
-
-	part->prev = NULL;
-	part->next = NULL;
-
-	part->disk = (PedDisk*) disk;
-	if (!ped_geometry_init (&part->geom, disk->dev, start, end - start + 1))
-		goto error_free_part;
-
-	part->num = -1;
-	part->type = type;
-	part->part_list = NULL;
-	part->fs_type = fs_type;
-
-	return part;
-
-error_free_part:
-	ped_free (part);
-error:
-	return NULL;
-}
-
-void
-_ped_partition_free (PedPartition* part)
-{
-	ped_free (part);
-}
-
-int
-_ped_partition_attempt_align (PedPartition* part,
-			      const PedConstraint* external,
-			      PedConstraint* internal)
-{
-	PedConstraint*		intersection;
-	PedGeometry*		solution;
-
-	intersection = ped_constraint_intersect (external, internal);
-	ped_constraint_destroy (internal);
-	if (!intersection)
-		goto fail;
-
-	solution = ped_constraint_solve_nearest (intersection, &part->geom);
-	if (!solution)
-		goto fail_free_intersection;
-	ped_geometry_set (&part->geom, solution->start, solution->length);
-	ped_geometry_destroy (solution);
-	ped_constraint_destroy (intersection);
-	return 1;
-
-fail_free_intersection:
-	ped_constraint_destroy (intersection);
-fail:
-	return 0;
-}
-
-/**
- * Create a new \link _PedPartition PedPartition \endlink on \p disk.
- *
- * \param type One of \p PED_PARTITION_NORMAL, \p PED_PARTITION_EXTENDED,
- *      \p PED_PARTITION_LOGICAL.
- *
- * \note The constructed partition is not added to <tt>disk</tt>'s
- *      partition table. Use ped_disk_add_partition() to do this.
- * 
- * \return A new \link _PedPartition PedPartition \endlink object,
- *      NULL on failure.
- *
- * \throws PED_EXCEPTION_ERROR if \p type is \p EXTENDED or \p LOGICAL but the
- *      label does not support this concept.
- */ 
-PedPartition*
-ped_partition_new (const PedDisk* disk, PedPartitionType type,
-		   const PedFileSystemType* fs_type, PedSector start,
-		   PedSector end)
-{
-	int		supports_extended;
-	PedPartition*	part;
-
-	PED_ASSERT (disk != NULL, return NULL);
-	PED_ASSERT (disk->type->ops->partition_new != NULL, return NULL);
-
-	supports_extended = ped_disk_type_check_feature (disk->type,
-			    	PED_DISK_TYPE_EXTENDED);
-
-	if (!supports_extended
-	    && (type == PED_PARTITION_EXTENDED
-			|| type == PED_PARTITION_LOGICAL)) {
-		ped_exception_throw (
-			PED_EXCEPTION_ERROR,
-			PED_EXCEPTION_CANCEL,
-			_("%s disk labels do not support extended "
-			  "partitions."),
-			disk->type->name);
-		goto error;
-	}
-
-	part = disk->type->ops->partition_new (disk, type, fs_type, start, end);
-	if (!part)
-		goto error;
-
-	if (fs_type || part->type == PED_PARTITION_EXTENDED) {
-		if (!ped_partition_set_system (part, fs_type))
-			goto error_destroy_part;
-	}
-	return part;
-
-error_destroy_part:
-	ped_partition_destroy (part);
-error:
-	return NULL;
-}
-
-/**
- * Destroy a \link _PedPartition PedPartition \endlink object.
- *
- * \note Should not be called on a partition that is in a partition table.
- *      Use ped_disk_delete_partition() instead.
- */
-void
-ped_partition_destroy (PedPartition* part)
-{
-	PED_ASSERT (part != NULL, return);
-	PED_ASSERT (part->disk != NULL, return);
-	PED_ASSERT (part->disk->type->ops->partition_new != NULL, return);
-
-	part->disk->type->ops->partition_destroy (part);
-}
-
-
-/**
- * Return whether or not the partition is "active".
- *
- * A partition is active if \p part->type is neither \p PED_PARTITION_METADATA
- * nor \p PED_PARTITION_FREE.
- */
-int
-ped_partition_is_active (const PedPartition* part)
-{
-	PED_ASSERT (part != NULL, return 0);
-
-	return !(part->type & PED_PARTITION_FREESPACE
-		 || part->type & PED_PARTITION_METADATA);
-}
-
-/**
- * Set the state (\c 1 or \c 0) of a flag on a partition.
- * 
- * Flags are disk label specific, although they have a global
- * "namespace": the flag PED_PARTITION_BOOT, for example, roughly means
- * "this" partition is bootable". But this means different things on different
- * disk labels (and may not be defined on some disk labels). For example,
- * on MS-DOS disk labels, there can only be one boot partition, and this
- * refers to the partition that will be booted from on startup. On PC98
- * disk labels, the user can choose from any bootable partition on startup.
- * 
- * \note It is an error to call this on an unavailable flag -- use
- * ped_partition_is_flag_available() to determine which flags are available
- * for a given disk label.
- *
- * \throws PED_EXCEPTION_ERROR if the requested flag is not available for this
- *      label.
- */
-int
-ped_partition_set_flag (PedPartition* part, PedPartitionFlag flag, int state)
-{
-	PedDiskOps*	ops;
-
-	PED_ASSERT (part != NULL, return 0);
-	PED_ASSERT (part->disk != NULL, return 0);
-	PED_ASSERT (ped_partition_is_active (part), return 0);
-
-	ops = part->disk->type->ops;
-	PED_ASSERT (ops->partition_set_flag != NULL, return 0);
-	PED_ASSERT (ops->partition_is_flag_available != NULL, return 0);
-
-	if (!ops->partition_is_flag_available (part, flag)) {
-		ped_exception_throw (
-			PED_EXCEPTION_ERROR,
-			PED_EXCEPTION_CANCEL,
-			"The flag '%s' is not available for %s disk labels.",
-			ped_partition_flag_get_name (flag),
-			part->disk->type->name);
-		return 0;
-	}
-
-	return ops->partition_set_flag (part, flag, state);
-}
-
-/**
- * Get the state (\c 1 or \c 0) of a flag on a partition.
- *
- * See ped_partition_set_flag() for conditions that must hold.
- *
- * \todo Where's the check for flag availability?
- */
-int
-ped_partition_get_flag (const PedPartition* part, PedPartitionFlag flag)
-{
-	PED_ASSERT (part != NULL, return 0);
-	PED_ASSERT (part->disk != NULL, return 0);
-	PED_ASSERT (part->disk->type->ops->partition_get_flag != NULL,
-		    return 0);
-	PED_ASSERT (ped_partition_is_active (part), return 0);
-
-	return part->disk->type->ops->partition_get_flag (part, flag);
-}
-
-/**
- * Check whether a given flag is available on a partition.
- *
- * \return \c 1 if the flag is available.
- */
-int
-ped_partition_is_flag_available (const PedPartition* part,
-	       			 PedPartitionFlag flag)
-{
-	PED_ASSERT (part != NULL, return 0);
-	PED_ASSERT (part->disk != NULL, return 0);
-	PED_ASSERT (part->disk->type->ops->partition_is_flag_available != NULL,
-		    return 0);
-	PED_ASSERT (ped_partition_is_active (part), return 0);
-
-	return part->disk->type->ops->partition_is_flag_available (part, flag);
-}
-
-/**
- * Sets the system type on the partition to \p fs_type.
- *
- * \note The file system may be opened, to get more information about the
- * file system, e.g. to determine if it's FAT16 or FAT32.
- *
- * \return \c 0 on failure.
- */
-int
-ped_partition_set_system (PedPartition* part, const PedFileSystemType* fs_type)
-{
-	const PedDiskType*	disk_type;
-
-	PED_ASSERT (part != NULL, return 0);
-	PED_ASSERT (ped_partition_is_active (part), return 0);
-	PED_ASSERT (part->disk != NULL, return 0);
-	disk_type = part->disk->type;
-	PED_ASSERT (disk_type != NULL, return 0);
-	PED_ASSERT (disk_type->ops != NULL, return 0);
-	PED_ASSERT (disk_type->ops->partition_set_system != NULL, return 0);
-
-	return disk_type->ops->partition_set_system (part, fs_type);
-}
-
-static int
-_assert_partition_name_feature (const PedDiskType* disk_type)
-{
-	if (!ped_disk_type_check_feature (
-			disk_type, PED_DISK_TYPE_PARTITION_NAME)) {
-		ped_exception_throw (
-			PED_EXCEPTION_ERROR,
-			PED_EXCEPTION_CANCEL,
-			"%s disk labels do not support partition names.",
-			disk_type->name);
-		return 0;
-	}
-	return 1;
-}
-
-/**
- * Sets the name of a partition.
- *
- * \note This will only work if the disk label supports it.
- *      You can use
- *      \code
- * ped_disk_type_check_feature (part->disk->type, PED_DISK_TYPE_PARTITION_NAME);
- *      \endcode
- *      to check whether this feature is enabled for a label.
- *      
- * \note \p name will not be modified by libparted. It can be freed
- *      by the caller immediately after ped_partition_set_name() is called.
- *
- * \return \c 1 on success, \c 0 otherwise.
- */
-int
-ped_partition_set_name (PedPartition* part, const char* name)
-{
-	PED_ASSERT (part != NULL, return 0);
-	PED_ASSERT (part->disk != NULL, return 0);
-	PED_ASSERT (ped_partition_is_active (part), return 0);
-	PED_ASSERT (name != NULL, return 0);
-
-	if (!_assert_partition_name_feature (part->disk->type))
-		return 0;
-
-	PED_ASSERT (part->disk->type->ops->partition_set_name != NULL,
-		    return 0);
-	part->disk->type->ops->partition_set_name (part, name);
-	return 1;
-}
-
-/**
- * Returns the name of a partition \p part.  This will only work if the disk
- * label supports it.
- *
- * \note The returned string should not be modified.  It should
- *	not be referenced after the partition is destroyed.
- */
-const char*
-ped_partition_get_name (const PedPartition* part)
-{
-	PED_ASSERT (part != NULL, return NULL);
-	PED_ASSERT (part->disk != NULL, return 0);
-	PED_ASSERT (ped_partition_is_active (part), return 0);
-
-	if (!_assert_partition_name_feature (part->disk->type))
-		return NULL;
-
-	PED_ASSERT (part->disk->type->ops->partition_get_name != NULL,
-		    return NULL);
-	return part->disk->type->ops->partition_get_name (part);
-}
-
-/** @} */
-
-/**
- * \addtogroup PedDisk
- *
- * @{
- */
-
-PedPartition*
-ped_disk_extended_partition (const PedDisk* disk)
-{
-	PedPartition*		walk;
-
-	PED_ASSERT (disk != NULL, return 0);
-
-	for (walk = disk->part_list; walk; walk = walk->next) {
-		if (walk->type == PED_PARTITION_EXTENDED)
-			break;
-	}
-	return walk;
-}
-
-/** 
- * Return the next partition after \p part on \p disk. If \p part is \c NULL,
- * return the first partition. If \p part is the last partition, returns
- * \c NULL. If \p part is an extended partition, returns the first logical
- * partition. If this is called repeatedly passing the return value as \p part,
- * a depth-first traversal is executed.
- *
- * \return The next partition, \c NULL if no more partitions left.
- */
-PedPartition*
-ped_disk_next_partition (const PedDisk* disk, const PedPartition* part)
-{
-	PED_ASSERT (disk != NULL, return 0);
-
-	if (!part)
-		return disk->part_list;
-	if (part->type == PED_PARTITION_EXTENDED)
-		return part->part_list ? part->part_list : part->next;
-	if (part->next)
-		return part->next;
-	if (part->type & PED_PARTITION_LOGICAL)
-		return ped_disk_extended_partition (disk)->next;
-	return NULL;
-}
-
-/** @} */
-
-#ifdef DEBUG
-static int
-_disk_check_sanity (PedDisk* disk)
-{
-	PedPartition*	walk;
-
-	PED_ASSERT (disk != NULL, return 0);
-
-	for (walk = disk->part_list; walk; walk = walk->next) {
-		PED_ASSERT (!(walk->type & PED_PARTITION_LOGICAL), return 0);
-		PED_ASSERT (!walk->prev || walk->prev->next == walk, return 0);
-	}
-
-	if (!ped_disk_extended_partition (disk))
-		return 1;
-
-	for (walk = ped_disk_extended_partition (disk)->part_list; walk;
-	     walk = walk->next) {
-		PED_ASSERT (walk->type & PED_PARTITION_LOGICAL, return 0);
-		if (walk->prev)
-			PED_ASSERT (walk->prev->next == walk, return 0);
-	}
-	return 1;
-}
-#endif
-
-/**
- * Returns the partition numbered \p num. 
- *
- * \return \c NULL if the specified partition does not exist.
- */
-PedPartition*
-ped_disk_get_partition (const PedDisk* disk, int num)
-{
-	PedPartition*	walk;
-
-	PED_ASSERT (disk != NULL, return 0);
-
-	for (walk = disk->part_list; walk;
-	     walk = ped_disk_next_partition (disk, walk)) {
-		if (walk->num == num && !(walk->type & PED_PARTITION_FREESPACE))
-			return walk;
-	}
-
-	return NULL;
-}
-
-/**
- * Returns the partition that contains sect.  If sect lies within a logical
- * partition, then the logical partition is returned (not the extended
- * partition).
- */
-PedPartition*
-ped_disk_get_partition_by_sector (const PedDisk* disk, PedSector sect)
-{
-	PedPartition*	walk;
-
-	PED_ASSERT (disk != NULL, return 0);
-
-	for (walk = disk->part_list; walk;
-	     walk = ped_disk_next_partition (disk, walk)) {
-		if (ped_geometry_test_sector_inside (&walk->geom, sect)
-		    && walk->type != PED_PARTITION_EXTENDED)
-			return walk;
-	}
-
-	/* should never get here, unless sect is outside of disk's useable
-	 * part, or we're in "update mode", and the free space place-holders
-	 * have been removed with _disk_remove_freespace()
-	 */
-	return NULL;
-}
-
-/* I'm beginning to agree with Sedgewick :-/ */
-static int
-_disk_raw_insert_before (PedDisk* disk, PedPartition* loc, PedPartition* part)
-{
-	PED_ASSERT (disk != NULL, return 0);
-	PED_ASSERT (loc != NULL, return 0);
-	PED_ASSERT (part != NULL, return 0);
-
-	part->prev = loc->prev;
-	part->next = loc;
-	if (part->prev) {
-		part->prev->next = part;
-	} else {
-		if (loc->type & PED_PARTITION_LOGICAL)
-			ped_disk_extended_partition (disk)->part_list = part;
-		else
-			disk->part_list = part;
-	}
-	loc->prev = part;
-
-	return 1;
-}
-
-static int
-_disk_raw_insert_after (PedDisk* disk, PedPartition* loc, PedPartition* part)
-{
-	PED_ASSERT (disk != NULL, return 0);
-	PED_ASSERT (loc != NULL, return 0);
-	PED_ASSERT (part != NULL, return 0);
-
-	part->prev = loc;
-	part->next = loc->next;
-	if (loc->next)
-		loc->next->prev = part;
-	loc->next = part;
-
-	return 1;
-}
-
-static int
-_disk_raw_remove (PedDisk* disk, PedPartition* part)
-{
-	PED_ASSERT (disk != NULL, return 0);
-	PED_ASSERT (part != NULL, return 0);
-
-	if (part->prev) {
-		part->prev->next = part->next;
-		if (part->next)
-			part->next->prev = part->prev;
-	} else {
-		if (part->type & PED_PARTITION_LOGICAL) {
-			ped_disk_extended_partition (disk)->part_list
-				= part->next;
-		} else {
-			disk->part_list = part->next;
-		}
-		if (part->next)
-			part->next->prev = NULL;
-	}
-
-	return 1;
-}
-
-/*
- *UPDATE MODE ONLY
- */
-static int
-_disk_raw_add (PedDisk* disk, PedPartition* part)
-{
-	PedPartition*	walk;
-	PedPartition*	last;
-	PedPartition*	ext_part;
-
-	PED_ASSERT (disk->update_mode, return 0);
-
-	ext_part = ped_disk_extended_partition (disk);
-
-	last = NULL;
-	walk = (part->type & PED_PARTITION_LOGICAL) ?
-			ext_part->part_list : disk->part_list;
-
-	for (; walk; last = walk, walk = walk->next) {
-		if (walk->geom.start > part->geom.end)
-			break;
-	}
-
-	if (walk) {
-		return _disk_raw_insert_before (disk, walk, part);
-	} else {
-		if (last) {
-			return _disk_raw_insert_after (disk, last, part);
-		} else {
-			if (part->type & PED_PARTITION_LOGICAL)
-				ext_part->part_list = part;
-			else
-				disk->part_list = part;
-		} 
-	}
-
-	return 1;
-}
-
-static PedConstraint*
-_partition_get_overlap_constraint (PedPartition* part, PedGeometry* geom)
-{
-	PedSector	min_start;
-	PedSector	max_end;
-	PedPartition*	walk;
-	PedGeometry	free_space;
-
-	PED_ASSERT (part->disk->update_mode, return NULL);
-	PED_ASSERT (part->geom.dev == geom->dev, return NULL);
-
-	if (part->type & PED_PARTITION_LOGICAL) {
-		PedPartition* ext_part;
-		
-		ext_part = ped_disk_extended_partition (part->disk);
-		PED_ASSERT (ext_part != NULL, return NULL);
-
-		min_start = ext_part->geom.start;
-		max_end = ext_part->geom.end;
-		walk = ext_part->part_list;
-	} else {
-		min_start = 0;
-		max_end = part->disk->dev->length - 1;
-		walk = part->disk->part_list;
-	}
-
-	while (walk != NULL
-	       && (walk->geom.start < geom->start
-			    || min_start >= walk->geom.start)) {
-		if (walk != part)
-			min_start = walk->geom.end + 1;
-		walk = walk->next;
-	}
-
-	if (walk == part)
-		walk = walk->next;
-
-	if (walk)
-		max_end = walk->geom.start - 1;
-
-	if (min_start >= max_end)
-		return NULL;
-
-	ped_geometry_init (&free_space, part->disk->dev,
-			   min_start, max_end - min_start + 1);
-	return ped_constraint_new_from_max (&free_space);
-}
-
-/*
- * Returns \c 0 if the partition, \p part overlaps with any partitions on the
- * \p disk.  The geometry of \p part is taken to be \p geom, NOT \p part->geom
- * (the idea here is to check if \p geom is valid, before changing \p part).
- * 
- * This is useful for seeing if a resized partitions new geometry is going to
- * fit, without the existing geomtry getting in the way.
- *
- * Note: overlap with an extended partition is also allowed, provided that
- * \p geom lies completely inside the extended partition.
- */
-static int
-_disk_check_part_overlaps (PedDisk* disk, PedPartition* part)
-{
-	PedPartition*	walk;
-
-	PED_ASSERT (disk != NULL, return 0);
-	PED_ASSERT (part != NULL, return 0);
-
-	for (walk = ped_disk_next_partition (disk, NULL); walk;
-	     walk = ped_disk_next_partition (disk, walk)) {
-		if (walk->type & PED_PARTITION_FREESPACE)
-			continue;
-		if (walk == part)
-			continue;
-		if (part->type & PED_PARTITION_EXTENDED
-		    && walk->type & PED_PARTITION_LOGICAL)
-			continue;
-
-		if (ped_geometry_test_overlap (&walk->geom, &part->geom)) {
-			if (walk->type & PED_PARTITION_EXTENDED
-			    && part->type & PED_PARTITION_LOGICAL
-			    && ped_geometry_test_inside (&walk->geom,
-							 &part->geom))
-				continue;
-			return 0;
-		}
-	}
-
-	return 1;
-}
-
-static int
-_partition_check_basic_sanity (PedDisk* disk, PedPartition* part)
-{
-	PedPartition*	ext_part = ped_disk_extended_partition (disk);
-
-	PED_ASSERT (part->disk == disk, return 0);
-
-	PED_ASSERT (part->geom.start >= 0, return 0);
-	PED_ASSERT (part->geom.end < disk->dev->length, return 0);
-	PED_ASSERT (part->geom.start <= part->geom.end, return 0);
-
-	if (!ped_disk_type_check_feature (disk->type, PED_DISK_TYPE_EXTENDED)
-	    && (part->type == PED_PARTITION_EXTENDED
-		    || part->type == PED_PARTITION_LOGICAL)) {
-		ped_exception_throw (
-			PED_EXCEPTION_ERROR,
-			PED_EXCEPTION_CANCEL,
-			_("%s disk labels don't support logical or extended "
-			  "partitions."),
-			disk->type->name);
-		return 0;
-	}
-
-	if (ped_partition_is_active (part)
-			&& ! (part->type & PED_PARTITION_LOGICAL)) {
-		if (ped_disk_get_primary_partition_count (disk) + 1
-		    > ped_disk_get_max_primary_partition_count (disk)) {
-			ped_exception_throw (
-				PED_EXCEPTION_ERROR,
-				PED_EXCEPTION_CANCEL,
-				_("Too many primary partitions."));
-			return 0;
-		}
-	}
-
-	if ((part->type & PED_PARTITION_LOGICAL) && !ext_part) {
-		ped_exception_throw (
-			PED_EXCEPTION_ERROR,
-			PED_EXCEPTION_CANCEL,
-			_("Can't add a logical partition to %s, because "
-			"there is no extended partition."),
-			disk->dev->path);
-		return 0;
-	}
-
-	return 1;
-}
-
-static int
-_check_extended_partition (PedDisk* disk, PedPartition* part)
-{
-	PedPartition*		walk;
-	PedPartition*		ext_part;
-
-	PED_ASSERT (disk != NULL, return 0);
-	ext_part = ped_disk_extended_partition (disk);
-	if (!ext_part) ext_part = part;
-	PED_ASSERT (ext_part != NULL, return 0);
-
-	if (part != ext_part) {
-		ped_exception_throw (
-			PED_EXCEPTION_ERROR,
-			PED_EXCEPTION_CANCEL,
-			_("Can't have more than one extended partition on %s."),
-			disk->dev->path);
-		return 0;
-	}
-
-	for (walk = ext_part->part_list; walk; walk = walk->next) {
-		if (!ped_geometry_test_inside (&ext_part->geom, &walk->geom)) {
-			ped_exception_throw (
-				PED_EXCEPTION_ERROR,
-				PED_EXCEPTION_CANCEL,
-				_("Can't have logical partitions outside of "
-				  "the extended partition."));
-			return 0;
-		}
-	}
-	return 1;
-}
-
-static int
-_check_partition (PedDisk* disk, PedPartition* part)
-{
-	PedPartition*	ext_part = ped_disk_extended_partition (disk);
-
-	PED_ASSERT (part->geom.start <= part->geom.end, return 0);
-
-	if (part->type == PED_PARTITION_EXTENDED) {
-		if (!_check_extended_partition (disk, part))
-			return 0;
-	}
-
-	if (part->type & PED_PARTITION_LOGICAL
-	    && !ped_geometry_test_inside (&ext_part->geom, &part->geom)) {
-		ped_exception_throw (
-			PED_EXCEPTION_ERROR,
-			PED_EXCEPTION_CANCEL,
-			_("Can't have a logical partition outside of the "
-			  "extended partition on %s."),
-			disk->dev->path);
-		return 0;
-	}
-
-	if (!_disk_check_part_overlaps (disk, part)) {
-		ped_exception_throw (
-			PED_EXCEPTION_ERROR,
-			PED_EXCEPTION_CANCEL,
-			_("Can't have overlapping partitions."));
-		return 0;
-	}
-
-	if (! (part->type & PED_PARTITION_LOGICAL)
-	    && ext_part && ext_part != part
-	    && ped_geometry_test_inside (&ext_part->geom, &part->geom)) {
-		ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
-			_("Can't have a primary partition inside an extended "
-			 "partition."));
-		return 0;
-	}
-
-	return 1;
-}
-
-/**
- * Adds PedPartition \p part to PedPartition \p disk.
- * 
- * \warning The partition's geometry may be changed, subject to \p constraint.
- * You could set \p constraint to <tt>ped_constraint_exact(&part->geom)</tt>,
- * but many partition table schemes have special requirements on the start
- * and end of partitions.  Therefore, having an overly strict constraint
- * will probably mean that this function will fail (in which
- * case \p part will be left unmodified)
- * \p part is assigned a number (\p part->num) in this process.
- * 
- * \return \c 0 on failure.
- */
-int
-ped_disk_add_partition (PedDisk* disk, PedPartition* part,
-			const PedConstraint* constraint)
-{
-	PedConstraint*	overlap_constraint = NULL;
-	PedConstraint*	constraints = NULL;
-
-	PED_ASSERT (disk != NULL, return 0);
-	PED_ASSERT (part != NULL, return 0);
-
-	if (!_partition_check_basic_sanity (disk, part))
-		return 0;
-
-	_disk_push_update_mode (disk);
-
-	if (ped_partition_is_active (part)) {
-		overlap_constraint
-			= _partition_get_overlap_constraint (part, &part->geom);
-		constraints = ped_constraint_intersect (overlap_constraint,
-							constraint);
-
-		if (!constraints && constraint) {
-			ped_exception_throw (
-				PED_EXCEPTION_ERROR,
-				PED_EXCEPTION_CANCEL,
-				_("Can't have overlapping partitions."));
-			goto error;
-		}
-
-		if (!_partition_enumerate (part))
-			goto error;
-		if (!_partition_align (part, constraints))
-			goto error;
-	}
-	if (!_check_partition (disk, part))
-		goto error;
-	if (!_disk_raw_add (disk, part))
-		goto error;
-
-	ped_constraint_destroy (overlap_constraint);
-	ped_constraint_destroy (constraints);
-	_disk_pop_update_mode (disk);
-#ifdef DEBUG
-	if (!_disk_check_sanity (disk))
-		return 0;
-#endif
-	return 1;
-
-error:
-	ped_constraint_destroy (overlap_constraint);
-	ped_constraint_destroy (constraints);
-	_disk_pop_update_mode (disk);
-	return 0;
-}
-
-/**
- * Removes PedPartition \p part from PedDisk \p disk.
- *
- * If \p part is an extended partition, it must not contain any logical
- * partitions. \p part is *NOT* destroyed. The caller must call
- * ped_partition_destroy(), or use ped_disk_delete_partition() instead.
- *
- * \return \c 0 on error.
- */
-int
-ped_disk_remove_partition (PedDisk* disk, PedPartition* part)
-{
-	PED_ASSERT (disk != NULL, return 0);
-	PED_ASSERT (part != NULL, return 0);
-
-	_disk_push_update_mode (disk);
-	PED_ASSERT (part->part_list == NULL, goto error);
-	_disk_raw_remove (disk, part);
-	_disk_pop_update_mode (disk);
-	ped_disk_enumerate_partitions (disk);
-	return 1;
-
-error:
-	_disk_pop_update_mode (disk);
-	return 0;
-}
-
-static int
-ped_disk_delete_all_logical (PedDisk* disk);
-
-/**
- * Removes \p part from \p disk, and destroys \p part.
- *
- * \return \c 0 on failure.
- */
-int
-ped_disk_delete_partition (PedDisk* disk, PedPartition* part)
-{
-	PED_ASSERT (disk != NULL, return 0);
-	PED_ASSERT (part != NULL, return 0);
-
-	_disk_push_update_mode (disk);
-	if (part->type == PED_PARTITION_EXTENDED)
-		ped_disk_delete_all_logical (disk);
-	ped_disk_remove_partition (disk, part);
-	ped_partition_destroy (part);
-	_disk_pop_update_mode (disk);
-
-	return 1;
-}
-
-static int
-ped_disk_delete_all_logical (PedDisk* disk)
-{
-	PedPartition*		walk;
-	PedPartition*		next;
-	PedPartition*		ext_part;
-
-	PED_ASSERT (disk != NULL, return 0);
-	ext_part = ped_disk_extended_partition (disk);
-	PED_ASSERT (ext_part != NULL, return 0);
-
-	for (walk = ext_part->part_list; walk; walk = next) {
-		next = walk->next;
-
-		if (!ped_disk_delete_partition (disk, walk))
-			return 0;
-	}
-	return 1;
-}
-
-/**
- * Removes and destroys all partitions on \p disk.
- *
- * \return \c 0 on failure.
- */
-int
-ped_disk_delete_all (PedDisk* disk)
-{
-	PedPartition*		walk;
-	PedPartition*		next;
-
-	PED_ASSERT (disk != NULL, return 0);
-
-	_disk_push_update_mode (disk);
-
-	for (walk = disk->part_list; walk; walk = next) {
-		next = walk->next;
-
-		if (!ped_disk_delete_partition (disk, walk))
-			return 0;
-	}
-
-	_disk_pop_update_mode (disk);
-
-	return 1;
-}
-
-/**
- * Sets the geometry of \p part (i.e. change a partitions location). This can
- * fail for many reasons, e.g. can't overlap with other partitions. If it
- * does fail, \p part will remain unchanged. Returns \c 0 on failure. \p part's
- * geometry may be set to something different from \p start and \p end subject
- * to \p constraint.
- *
- * \warning The constraint warning from ped_disk_add_partition() applies.
- * 
- * \note this function does not modify the contents of the partition.  You need
- *       to call ped_file_system_resize() separately.
- */
-int
-ped_disk_set_partition_geom (PedDisk* disk, PedPartition* part,
-			     const PedConstraint* constraint,
-			     PedSector start, PedSector end)
-{
-	PedConstraint*	overlap_constraint = NULL;
-	PedConstraint*	constraints = NULL;
-	PedGeometry	old_geom;
-	PedGeometry	new_geom;
-
-	PED_ASSERT (disk != NULL, return 0);
-	PED_ASSERT (part != NULL, return 0);
-	PED_ASSERT (part->disk == disk, return 0);
-
-	old_geom = part->geom;
-	ped_geometry_init (&new_geom, part->geom.dev, start, end - start + 1);
-
-	_disk_push_update_mode (disk);
-
-	overlap_constraint
-		= _partition_get_overlap_constraint (part, &new_geom);
-	constraints = ped_constraint_intersect (overlap_constraint, constraint);
-	if (!constraints && constraint) {
-		ped_exception_throw (
-			PED_EXCEPTION_ERROR,
-			PED_EXCEPTION_CANCEL,
-			_("Can't have overlapping partitions."));
-		goto error_pop_update_mode;
-	}
-
-	part->geom = new_geom;
-	if (!_partition_align (part, constraints))
-		goto error_pop_update_mode;
-	if (!_check_partition (disk, part))
-		goto error_pop_update_mode;
-
-	/* remove and add, to ensure the ordering gets updated if necessary */
-	_disk_raw_remove (disk, part);
-	_disk_raw_add (disk, part);
-
-	_disk_pop_update_mode (disk);
-
-	ped_constraint_destroy (overlap_constraint);
-	ped_constraint_destroy (constraints);
-	return 1;
-
-error_pop_update_mode:
-	_disk_pop_update_mode (disk);
-	ped_constraint_destroy (overlap_constraint);
-	ped_constraint_destroy (constraints);
-	part->geom = old_geom;
-	return 0;
-}
-
-/**
- * Grow PedPartition \p part geometry to the maximum possible subject to
- * \p constraint.  The new geometry will be a superset of the old geometry.
- * 
- * \return 0 on failure
- */
-int
-ped_disk_maximize_partition (PedDisk* disk, PedPartition* part,
-			     const PedConstraint* constraint)
-{
-	PedGeometry	old_geom;
-	PedSector	global_min_start;
-	PedSector	global_max_end;
-	PedSector	new_start;
-	PedSector	new_end;
-	PedPartition*	ext_part = ped_disk_extended_partition (disk);
-	PedConstraint*	constraint_any;
-
-	PED_ASSERT (disk != NULL, return 0);
-	PED_ASSERT (part != NULL, return 0);
-
-	if (part->type & PED_PARTITION_LOGICAL) {
-		PED_ASSERT (ext_part != NULL, return 0);
-		global_min_start = ext_part->geom.start;
-		global_max_end = ext_part->geom.end;
-	} else {
-		global_min_start = 0;
-		global_max_end = disk->dev->length - 1;
-	}
-
-	old_geom = part->geom;
-
-	_disk_push_update_mode (disk);
-
-	if (part->prev)
-		new_start = part->prev->geom.end + 1;
-	else
-		new_start = global_min_start;
-
-	if (part->next)
-		new_end = part->next->geom.start - 1;
-	else
-		new_end = global_max_end;
-
-	if (!ped_disk_set_partition_geom (disk, part, constraint, new_start,
-					  new_end))
-		goto error;
-
-	_disk_pop_update_mode (disk);
-	return 1;
-
-error:
-	constraint_any = ped_constraint_any (disk->dev);
-	ped_disk_set_partition_geom (disk, part, constraint_any,
-				     old_geom.start, old_geom.end);
-	ped_constraint_destroy (constraint_any);
-	_disk_pop_update_mode (disk);
-	return 0;
-}
-
-/**
- * Get the maximum geometry \p part can be grown to, subject to
- * \p constraint.
- *
- * \return \c NULL on failure.
- */
-PedGeometry*
-ped_disk_get_max_partition_geometry (PedDisk* disk, PedPartition* part,
-				     const PedConstraint* constraint)
-{
-	PedGeometry	old_geom;
-	PedGeometry*	max_geom;
-	PedConstraint*	constraint_exact;
-
-	PED_ASSERT(disk != NULL, return NULL);
-	PED_ASSERT(part != NULL, return NULL);
-	PED_ASSERT(ped_partition_is_active (part), return NULL);
-
-	old_geom = part->geom;
-	if (!ped_disk_maximize_partition (disk, part, constraint))
-		return NULL;
-	max_geom = ped_geometry_duplicate (&part->geom);
-
-	constraint_exact = ped_constraint_exact (&old_geom);
-	ped_disk_set_partition_geom (disk, part, constraint_exact,
-				     old_geom.start, old_geom.end);
-	ped_constraint_destroy (constraint_exact);
-
-	/* this assertion should never fail, because the old
-	 * geometry was valid
-	 */
-	PED_ASSERT (ped_geometry_test_equal (&part->geom, &old_geom),
-		    return NULL);
-
-	return max_geom;
-}
-
-/** 
- * Reduce the size of the extended partition to a minimum while still wrapping
- * its logical partitions.  If there are no logical partitions, remove the
- * extended partition.
- *
- * \return 0 on failure.
- */
-int
-ped_disk_minimize_extended_partition (PedDisk* disk)
-{
-	PedPartition*		first_logical;
-	PedPartition*		last_logical;
-	PedPartition*		walk;
-	PedPartition*		ext_part;
-	PedConstraint*		constraint;
-	int			status;
-
-	PED_ASSERT (disk != NULL, return 0);
-
-	ext_part = ped_disk_extended_partition (disk);
-	if (!ext_part)
-		return 1;
-
-	_disk_push_update_mode (disk);
-
-	first_logical = ext_part->part_list;
-	if (!first_logical) {
-		_disk_pop_update_mode (disk);
-		return ped_disk_delete_partition (disk, ext_part);
-	}
-
-	for (walk = first_logical; walk->next; walk = walk->next);
-	last_logical = walk;
-
-	constraint = ped_constraint_any (disk->dev);
-	status = ped_disk_set_partition_geom (disk, ext_part, constraint,
-					      first_logical->geom.start,
-					      last_logical->geom.end);
-	ped_constraint_destroy (constraint);
-
-	_disk_pop_update_mode (disk);
-	return status;
-}
-
-/**
- * @}
- */
-
-/**
- * \addtogroup PedPartition
- *
- * @{
- */
-
-/**
- * Returns a name that seems mildly appropriate for a partition type \p type.
- * 
- * Eg, if you pass (PED_PARTITION_LOGICAL & PED_PARTITION_FREESPACE), it
- * will return "free".  This isn't to be taken too seriously - it's just
- * useful for user interfaces, so you can show the user something ;-)
- * 
- * \note The returned string will be in English.  However,
- * translations are provided, so the caller can call
- * dgettext("parted", RESULT) on the result.
- *
- */
-const char*
-ped_partition_type_get_name (PedPartitionType type)
-{
-	if (type & PED_PARTITION_METADATA)
-		return N_("metadata");
-	else if (type & PED_PARTITION_FREESPACE)
-		return N_("free");
-	else if (type & PED_PARTITION_EXTENDED)
-		return N_("extended");
-	else if (type & PED_PARTITION_LOGICAL)
-		return N_("logical");
-	else
-		return N_("primary");
-}
-
-
-/**
- * Returns a name for a \p flag, e.g. PED_PARTITION_BOOT will return "boot".
- * 
- * \note The returned string will be in English.  However,
- * translations are provided, so the caller can call
- * dgettext("parted", RESULT) on the result.
- */
-const char*
-ped_partition_flag_get_name (PedPartitionFlag flag)
-{
-	switch (flag) {
-	case PED_PARTITION_BOOT:
-		return N_("boot");
-	case PED_PARTITION_ROOT:
-		return N_("root");
-	case PED_PARTITION_SWAP:
-		return N_("swap");
-	case PED_PARTITION_HIDDEN:
-		return N_("hidden");
-	case PED_PARTITION_RAID:
-		return N_("raid");
-	case PED_PARTITION_LVM:
-		return N_("lvm");
-	case PED_PARTITION_LBA:
-		return N_("lba");
-	case PED_PARTITION_HPSERVICE:
-		return N_("hp-service");
-	case PED_PARTITION_PALO:
-		return N_("palo");
-	case PED_PARTITION_PREP:
-		return N_("prep");
-	case PED_PARTITION_MSFT_RESERVED:
-		return N_("msftres");
-
-	default:
-		ped_exception_throw (
-			PED_EXCEPTION_BUG,
-			PED_EXCEPTION_CANCEL,
-			_("Unknown partition flag, %d."),
-			flag);
-		return NULL;
-	}
-}
-
-/**
- * Iterates through all flags. 
- * 
- * ped_partition_flag_next(0) returns the first flag
- *
- * \return the next flag, or 0 if there are no more flags
- */
-PedPartitionFlag
-ped_partition_flag_next (PedPartitionFlag flag)
-{
-	return (flag + 1) % (PED_PARTITION_LAST_FLAG + 1);
-}
-
-/**
- * Returns the flag associated with \p name.  
- *
- * \p name can be the English
- * string, or the translation for the native language.
- */
-PedPartitionFlag
-ped_partition_flag_get_by_name (const char* name)
-{
-	PedPartitionFlag	flag;
-	const char*		flag_name;
-
-	for (flag = ped_partition_flag_next (0); flag;
-	     		flag = ped_partition_flag_next (flag)) {
-		flag_name = ped_partition_flag_get_name (flag);
-		if (strcasecmp (name, flag_name) == 0
-		    || strcasecmp (name, _(flag_name)) == 0)
-			return flag;
-	}
-
-	return 0;
-}
-
-static void
-ped_partition_print (const PedPartition* part)
-{
-	PED_ASSERT (part != NULL, return);
-
-	printf ("  %-10s %02d  (%d->%d)\n",
-		ped_partition_type_get_name (part->type),
-		part->num,
-		(int) part->geom.start, (int) part->geom.end);
-}
-
-/** @} */
-
-/**
- * \addtogroup PedDisk
- *
- * @{
- */
-
-/**
- * Prints a summary of disk's partitions.  Useful for debugging.
- */
-void
-ped_disk_print (const PedDisk* disk)
-{
-	PedPartition*	part;
-
-	PED_ASSERT (disk != NULL, return);
-
-	for (part = disk->part_list; part;
-	     part = ped_disk_next_partition (disk, part))
-		ped_partition_print (part);
-}
-
-/** @} */
