===============================================================================
				GNU libparted API
===============================================================================

      by Andrew Clausen <clausen@gnu.org>

      Copyright (C) 1999, 2000 Free Software Foundation, Inc.

      Permission is granted to copy, distribute and/or modify this document
      under the terms of the GNU Free Documentation License, Version 1.1
      or any later version published by the Free Software Foundation;
      with the no Invariant Sections, with the no Front-Cover Texts, and
      with no Back-Cover Texts.  A copy of the license is included in the
      file, COPYING.DOC.


CONTENTS
--------

1	Introduction
2	Initialising libparted
3	PedDevice
4	PedDisk, PedDiskType
5	PedGeometry
6	PedPartition, PedPartitionType
7	PedFileSystem, PedFileSystemType
8	PedConstraint, PedAlignment
9	Exceptions

-------------------------------------------------------------------------------
1	INTRODUCTION
-------------------------------------------------------------------------------

GNU Parted is built on top of libparted, which does all of the real work.
libparted provides an API capable of manipulating partition tables, and
filesystems on them.

The main motivation for separating the back-end into a separate library was
to encourage different GNU/Linux distributions to encorporate their own
customized front-end into the install process.

This documents the API - not the implementation details of libparted.
Documentation that is not relevant to programs using the API are marked with
INTERNAL.  Apart from this file, a good place to look would be the
parted/parted.c - the front-end's source, and the TUTORIAL file (not finished
yet!).

This documentation isn't as complete as it should be.  Feel free to ask
questions, either to me personally (clausen@gnu.org), or to the mailing list
(bug-parted@gnu.org).

1.1	TERMINOLOGY
-------------------
Some of the terminology is a bit weird, so you might want to read this.

CONSTRAINT		a set of conditions that must be satisfied, for
			the GEOMETRY of a PARTITION.

DEVICE			a storage device.

DISK			a storage device, with a valid partition table.

EXCEPTION		an event that needs attention.

EXTENDED PARTITION	a PRIMARY PARTITION, that may contain LOGICAL
			PARTITIONS instead of a file system.  There is at most
			one extended partition.

FILE SYSTEM		any data that resides on a partition.  For the purposes
			for GNU Parted, this includes swap devices.

GEOMETRY		a description of a continuous region on a disk.  eg,
			partitions have a geometry.

HIDDEN PARTITION	a partition that is hidden from MS operating systems.
			Only FAT partitions may be hidden.

LOGICAL PARTITION	like normal partitions, but lie inside the extended
			partition.

PARTITION		a continous region on a disk, where a file system may
			reside.

PRIMARY PARTITION	a normal, vanilla, partition.

PARTITION TABLE		also, DISK LABEL.  A description of where the
			partitions lie, and information about those partitions.
			For example, what type of file system resides on them.
			The partition table is usually at the start of the
			disk.

1.2	DESIGN
--------------
libparted has a fairly object-oriented design.  The most important objects are:

PedDevice		a storage device
PedDisk			a device + partition table
PedFileSystem		a filesystem, associated with a PedGeometry, NOT a
			PedPartition.
PedGeometry		a continious region on a device
PedPartition		a partition (basically PedGeometry plus some attributes)
PedConstraint		a constraint on the geometry of a partition

All functions return 0 (or NULL) on failure and non-zero (or non-NULL) on
success.  If a function fails, an exception is thrown.  This may be handled be
either an exception handler, or the calling function (see section on
exceptions)

All objects are read-only.  They should only be modified by calls to API
functions.

-------------------------------------------------------------------------------
2	INITIALISING LIBPARTED
-------------------------------------------------------------------------------

Headers for libparted can be included with:

#include <parted/parted.h>

Before any API functions are called, ped_init() must called.  There is one
exception: you can set the exception handler with ped_exception_set_handler(),
beforehand, so if there's an error in ped_init(), it can be handled properly.
libparted does come with a default exception handler, if you're feeling lazy.

Before the program terminates, ped_done() must be called.  Otherwise, nasty
things can happen, like the partition table not being re-read by the kernel...

Here's a minimal example:

#include <parted/parted.h>

int
main()
{
	ped_exception_set_handler(exception_handler);	/* see section 7 */
	ped_init();
	ped_done();
	return 0;
}

-----------------------------------------------------------------------------
3	PEDDEVICE
-----------------------------------------------------------------------------

interface:		<parted/device.h>
implementation:		libparted/device.c, libparted/llseek.c.

When ped_device_probe_all() is called, libparted attempts to detect all
devices.  It constructs a list, which can be accessed with
ped_device_get_next().
	If you want to use a device that isn't on the list, use
ped_device_get().

3.1	FIELDS
--------------
#define PED_SECTOR_SIZE         512
typedef long long PedSector;

typedef enum {
	PED_DEVICE_UNKNOWN      = 0,
	PED_DEVICE_SCSI         = 1,
	PED_DEVICE_IDE          = 2,
	PED_DEVICE_DAC960       = 3
} PedDeviceType;

typedef struct _PedDevice PedDevice;

struct _PedDevice {
	PedDevice*      next;

	char*           model;
	char*           path;

	PedDeviceType   type;
	int             sector_size;
	PedSector       length;

	int             open_count;
	int             dirty;
	int		boot_dirty;
	int             fd;

/* x86-specific: TODO hide this in arch_specific */
	int             heads, sectors, cylinders;
	int		geom_known;
	short           host, did;
};

Useful fields are:

char*		model		A description of the hardware manufacturer and
				model

char*		path		Usually the block device.  Eg. /dev/sdb

PedSector	length		The size of the device, in sectors

3.2	FUNCTIONS
-----------------

void ped_device_probe_all ()
	Attempts to detect all devices.

void ped_device_free_all ()
	Closes/frees up all devices.  Called by ped_done(), so  you need not
	worry about it.

PedDevice* ped_device_get (char* name)
	Gets the device "name", where name is usually the block device (eg
	/dev/sdb).  If the device wasn't detected with ped_device_probe_all(),
	an attempt will be made to detect it again.  If it is found, it will
	be added to the list.

PedDevice* ped_device_get_next (PedDevice* dev)
	Returns the next device that was detected by ped_device_probe_all(), or
	calls to ped_device_get_next().  If dev is NULL, returns the first
	device.  Returns NULL if dev is the last device.

int ped_device_open (PedDevice* dev)
	INTERNAL:  Attempts to open dev, to allow use uf ped_device_read(),
	ped_device_write() and ped_device_sync().  Returns zero on failure.

int ped_device_close (PedDevice* dev)
	INTERNAL: Closes dev.  Returns zero on failure.

int ped_device_read (PedDevice* dev, void* buffer, PedSector start,
                     PedSector count)
	INTERNAL: Reads count sectors, beginning with sector start, from dev.
	Returns zero on failure.

int ped_device_write (PedDevice* dev, void* buffer, PedSector start,
                      PedSector count)
	INTERNAL: Writes count sectors, beginning with sector start, from dev.
	Returns zero on failure.

int ped_device_sync (PedDevice* dev)
	INTERNAL: Flushes the write cache.
	Returns zero on failure.

int ped_device_begin_external_access (PedDevice* dev)
	Begins external access mode.  External access mode allows you to
	safely do IO on the device.  If a PedDevice is open, then you should
	not do any IO on that device (eg: by calling an external program,
	like e2fsck), unless you put it in external access mode.  You should
	not use any libparted commands that do IO to a device (eg:
	ped_file_system_{open|resize|copy}, ped_disk_{read|write}), while
	a device is in external access mode.
		Also, you should not ped_device_close() a device, while it is
	in external access mode.
		Note: ped_device_begin_external_access_mode() does things like
	tell the kernel to flush it's caches, and re-read the partition table.
		Returns zero on failure.

int ped_device_end_external_access (PedDevice* dev)
	Ends external access mode.
		Note: ped_device_end_external_access_mode() does things like
	tell the kernel to flush it's caches, and re-read the partition table.
		Returns zero on failure.

-----------------------------------------------------------------------------
4	PEDDISK, PEDDISKTYPE
-----------------------------------------------------------------------------

interface:		<parted/disk.h>
implementation:		libparted/disk.c

Most programs will need to use ped_disk_open() or ped_disk_create() 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 PedDiskType's.

4.1	FIELDS
--------------

struct _PedDiskType {
	PedDiskType*            next;
	char*                   name;
	PedDiskOps*             ops;

	void*			disk_specific;

/* office use only ;-) */
	int			update_mode;
};

Useful fields are:
char*		name		the name of the partition table type.

struct _PedDisk {
	PedDevice*              dev;
	PedDiskType*            type;
	PedPartition*           part_list;
};

Useful fields are:
PedDiskType*    type		the type of disk label
PedPartition*   part_list	this is the list of partitions on the disk.
				It should be accessed with
				ped_disk_next_partition()

4.2	FUNCTIONS
-----------------

PedDiskType* ped_disk_type_get_next (PedDiskType* type)
	Returns the next disk type registers, after "type".  If "type" is
	NULL, returns the first disk type.  If "type" is the last registered
	disk type, returns NULL.

PedDiskType* ped_disk_type_get (char* name)
	Returns the disk type with a name of "name".  If there are none,
	returns NULL.

PedDisk* ped_disk_open (PedDevice* dev)
	Constructs a PedDisk object from dev, and reads the partition table.
	Returns zero on failure.
	WARNING: this can modify dev->cylinders, dev->heads and dev->sectors,
	because the partition table might indicate that the existing values
	were incorrect.

PedDisk* ped_disk_create (PedDevice* dev, PedDiskType* type)
	Creates a partition table on dev, and constructs a PedDisk object for
	it.  Returns NULL on failure.

int ped_disk_close (PedDisk* disk)
	Closes "disk".  Returns 0 on failure.

int ped_disk_read (PedDisk* disk)
	Reads the partition table "disk".  Returns 0 on failure.

int ped_disk_write (PedDisk* disk)
	Writes the partition table to "disk".  Returns 0 on failure.

int ped_disk_add_partition (PedDisk* disk, PedPartition* part,
			    PedConstraint* constraint)
	Adds "part" to "disk".
		"part"'s geometry may be changed, subject to "constraint".
	You could set "constraint" to ped_constraint_exact(&part->geom), but
	many partition table schemes have special requirements on the start
	and end of partitions.  Therefore, having an overly strict constraint
	will probably mean ped_disk_add_partition() will fail (in which case,
	"part" will be left unmodified)
		"part" is assigned a number (part->num) in this process.
	Returns 0 on failure.

int ped_disk_delete_partition (PedDisk* disk, PedPartition* part)
	Removes "part" from "disk", and destroys "part".  Returns 0 on failure.

int ped_disk_delete_all (PedDisk* disk)
	Removes and destroys all partitions on "disk".  Returns 0 on failure.

int ped_disk_set_partition_geom (PedDisk* disk, PedPartition* part,
                                 PedConstraint* constraint, PedSector start,
				 PedSector end)
	Sets the geometry of "part".  This can fail for many reasons (eg:
	can't overlap with other partitions).  If it does fail, "part" will
	remain unchanged.  Returns 0 on failure.
		"part"'s geometry may be set to something different to
	"start" and "end", subject to "constraint".

int ped_disk_maximize_partition (PedDisk* disk, PedPartition* part,
				 PedConstraint* constraint)
	Grows "part"'s geometry to the maximum possible, subject to
	"constraint".  The new geometry will be a superset of the old geometry.
	Returns 0 on failure.

PedGeometry* ped_disk_get_max_partition_geometry (PedDisk* disk,
				PedPartition* part, PedConstraint* constraint)
	Returns the maximum geometry "part" can be grown to, subject to
	"constraint".  Returns NULL on failure.

int ped_disk_minimize_extended_partition (PedDisk* disk)
	Reduces the extended partition on "disk" to the minimum possible.
	Returns 0 on failure.

PedPartition* ped_disk_next_partition (PedDisk* disk, PedPartition* part)
	Returns the next partition after "part" on "disk".  If "part" is NULL,
	returns the first partition.  If "part" is the last partition, returns
	NULL.  If "part" is an extended partition, returns the first logical
	partition.
		If this is called repeatededly, passing the return value as
	"part", a depth-first traversal is executed.

PedPartition* ped_disk_get_partition (PedDisk* disk, int num)
	Returns the partition numbered "num".  If no such partition exists,
	returns NULL.

int ped_disk_get_primary_partition_count (PedDisk* disk)
	Returns the number of primary partitions.

int ped_disk_get_last_partition_num (PedDisk* disk)
	Returns the highest part->num of all partitions.

PedPartition* ped_disk_get_partition_by_sector (PedDisk* disk, PedSector sect)
	Returns the partition that 'owns' "sect".  If sect lies inside a
	logical partition

PedPartition* ped_disk_extended_partition (PedDisk* disk)
	Returns the extended partition, or NULL if there isn't one.

-----------------------------------------------------------------------------
5	PEDGEOMETRY
-----------------------------------------------------------------------------

interface:		<parted/disk.h>
implementation:		libparted/geom.c

PedGeometry is created by ped_geometry_new(), from a PedDisk.  It represents
a continuous region on a device (i.e. disk->dev).  All addressing through
a PedGeometry object is in terms of the start of the continuous region.

The following conditions are always true on a PedGeometry object:
	* start + length - 1 == end
	* length > 0	[STRICTLY > 0]
	* end < disk->dev->length

5.1	FIELDS
--------------
struct _PedGeometry {
	PedDisk*                disk;
	PedSector               start;
	PedSector               length;
	PedSector               end;
};

Useful fields:
PedDisk*        disk		the disk
PedSector       start		the start of the region, in sectors.  (one
				sector = 512 bytes)
PedSector       length		the length of the region, in sectors
PedSector       end		the end of the region, in sectors

5.2	FUNCTIONS
-----------------
int ped_geometry_init (PedGeometry* geom, const PedDisk* disk, PedSector start,
		       PedSector length)
	Initialises a PedGeometry object.

PedGeometry* ped_geometry_new (PedDisk* disk, PedSector start, PedSector length)
	Creates a new PedGeometry object on "disk", starting at "start", of
	"length" sectors (units of 512 byte).  Returns NULL on failure.

PedGeometry* ped_geometry_duplicate (PedGeometry* geom)
	Duplicates a PedGeometry object.  Returns NULL on failure.

PedGeometry* ped_geometry_intersect (const PedGeometry* a, const PedGeometry* b)
	If a and b overlap, returns a PedGeometry object that refers to the
	overlapping region.  If not, returns NULL.

void ped_geometry_destroy (PedGeometry* geom)
	Destroys a PedGeometry object.

void ped_geometry_set (PedGeometry* geom, PedSector start, PedSector length)
	Assigns a new geom->start, geom->end and geom->length to "geom".
	geom->end is calculated from "start" and "length".

void ped_geometry_set_start (PedGeometry* geom, PedSector start)
	Assigns as new geom->start to "geom", without changing geom->end.
	geom->length is updated accordingly.

void ped_geometry_set_end (PedGeometry* geom, PedSector end);
	Assigns as new geom->end to "geom", without changing geom->start.
	geom->length is updated accordingly.

int ped_geometry_test_overlap (PedGeometry* a, PedGeometry* b)
	Tests if "a" overlaps with "b".  That is, they lie on the same
	physical device, and they share (some of) the same physical region.

int ped_geometry_test_inside (PedGeometry* a, PedGeometry* b);
	Tests if "b" lies completely within "b".  That is, they lie on the same
	physical device, and all of the "b"'s region is contained inside
	"a"'s.

int ped_geometry_test_equal (PedGeometry* a, PedGeometry* b);
	Tests if "a" and "b" refer to the same physical region.

int ped_geometry_read (PedGeometry* geom, void* buffer, PedSector offset,
		       PedSector count)
	Reads data from the region represented by "geom".  "offset" is the
	location from within the region, not from the start of the disk.
	"count" sectors are read into "buffer".
		This is essentially equivalent to:

	ped_device_read (geom->disk->dev, buffer, geom->start + offset, count)

	Returns 0 on failure.

int ped_geometry_write (PedGeometry* geom, void* buffer, PedSector offset,
			PedSector count)
	Writes data from the region represented by "geom".  "offset" is the
	location from within the region, not from the start of the disk.
	"count" sectors are written.  Returns 0 on failure.

PedSector ped_geometry_check (PedGeometry* geom, void* buffer,
			      PedSector buffer_size, PedSector offset,
			      PedSector granularity, PedSector count)
	Checks a region for physical defects on "geom".  "buffer" is used
	for temporary storage for ped_geometry_check(), and has an undefined
	value.  "buffer" is "buffer_size" sectors long.
		The region checked starts at "offset" sectors inside the
	region represented by "geom", and is "count" sectors long.
	The first bad sector is returned, or 0 if there were no physical
	errors.
		"granularity" specificies how sectors should be grouped
	together.  The first bad sector to be returned will always be in
	the form:
		offset + n * granularity

int ped_geometry_sync (PedGeometry* geom)
	Flushes the cache on "geom".  Returns 0 on failure.

PedSector ped_geometry_map (PedGeometry* dst, PedGeometry* src,
			    PedSector sector)
	If "src" and "dst" overlap, and "sector" on "src" is exists also on
	"dst", then the equivalent sector is retruned.
		-1 is returned if "sector" is not within "dst"'s space.

-----------------------------------------------------------------------------
6	PEDPARTITION, PEDPARTITIONTYPE
-----------------------------------------------------------------------------

interface:		<parted/disk.h>
implementation:		libparted/disk.c

A PedPartition represents a partition (surprise!).  PedPartitions have weird
relationships with PedDisks.  Hence, many functions for manipulating partitions
will be called ped_disk_* - so have a look at the PedDisk documentation as well.

Parted creates "imaginary" free space and metadata partitions.  You can't
do any operations on these partitions (like set_geometry, {set,get}_flag, etc.)
Partitions that are not free space or metadata partitions are said to
be "active" partitions.  You can use ped_partition_is_active() to check.

6.1	FIELDS
--------------
typedef enum {
	PED_PARTITION_PRIMARY		= 0x00,
	PED_PARTITION_LOGICAL		= 0x01,
	PED_PARTITION_EXTENDED		= 0x02,
	PED_PARTITION_FREESPACE		= 0x04,
	PED_PARTITION_METADATA		= 0x08
} PedPartitionType;

typedef enum {
	PED_PARTITION_BOOT=1,
	PED_PARTITION_ROOT=2,
	PED_PARTITION_SWAP=3,
	PED_PARTITION_HIDDEN=4,
	PED_PARTITION_RAID=5,
	PED_PARTITION_LVM=6,
	PED_PARTITION_LBA=7
} PedPartitionFlag;
#define PED_PARTITION_FIRST_FLAG        PED_PARTITION_BOOT
#define PED_PARTITION_LAST_FLAG         PED_PARTITION_LBA

struct _PedPartition {
	PedPartition*           prev;
	PedPartition*           next;

	PedGeometry             geom;
	int                     num;

	PedPartitionType        type;
	const PedFileSystemType* fs_type;
	PedPartition*           part_list;

	void*			disk_specific;
};

Useful fields:
PedGeometry     geom		geometry of the partition
int		num		the partition number.  In Linux, this is the
				same as the minor number.  No assumption should
				be made about "num" and "type" - different
				disk labels have different rules.
PedPartitionType  type		the type of partition: always one of
				PED_PARTITION_PRIMARY, PED_PARTITION_LOGICAL or
				PED_PARTITION_EXTENDED.
					A primary partition is a "normal"
				partition.  An extended partition is a
				primary partition that may contain logical
				partitions.  There is at most one extended
				partition on a disk.
					A logical partition is like a primary
				partition, except it's inside an extended
				partition.
					Internally, pseudo partitions are
				allocated to represent free space, or disk
				label meta-data.  These have the
				PED_PARTITION_FREESPACE or
				PED_PARTITION_METADATA bit set.
PedPartition*	part_list	Only used for an extended partition.  The list
				of logical partitions (and free space and
				metadata within the extended partition)
PedFileSystemType*  fs_type	The type of file system on the partition.
				NULL if not known.

6.2	FUNCTIONS
-----------------
PedPartition* ped_partition_new (PedDisk* disk,
				 PedPartitionType type,
				 const PedFileSystemType* fs_type
				 PedSector start, PedSector end)
	Creates a new PedPartition on "disk", starting at sector "start",
	and ending at "end".  "type" is one of PED_PARTITION_PRIMARY,
	PED_PARTITION_LOGICAL or PED_PARTITION_EXTENDED.  (PED_PARTITION_FREE
	and PED_PARTITION_METADATA are used internally).
		The new partition is NOT added to the disk's internal
	representation of the partition table.  Use ped_disk_add_partition()
	to do this.  
void ped_partition_destroy (PedPartition* part)
	Destroys a partition.  Should not be called on a partition that is
	in a partition table.  Use ped_disk_delete_partition() instead.

int ped_partition_is_active (PedPartition* part)
	Returns if the partition is "active".  If part->type is
	PED_PARTITION_METADATA or PED_PARTITION_FREE, then it's inactive.
	Otherwise, it's active.

int ped_partition_set_flag (PedPartition* part, PedPartitionFlag flag,
			    int state)
	Sets the state (1 or 0) of a flag on a partition.
		Flags are disk label specific, although they have a global
	"namespace".  e.g. the flag, PED_PARTITION_BOOT 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 msdos 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.
		It is an error to call this on an unavailable flag - see
	ped_partition_is_flag_available().

int ped_partition_get_flag (const PedPartition* part, PedPartitionFlag flag)
	Returns the state (1 or 0) of a flag on a partition.
		It is an error to call this on an unavailable flag - see
	ped_partition_is_flag_available().

int ped_partition_is_flag_available (const PedPartition* part,
				     PedPartitionFlag flag)
	Returns if 1 if a flag is available on a partition, and 0 otherwise.

int ped_partition_set_system (PedPartition* part, PedFileSystemType* fs_type)
	Sets the system type on the partition to be fs_type.  Note: the
	file system may be opened, to get more information about the
	file system.  Eg: to determine if it's FAT16 or FAT32.

int ped_partition_set_name (PedPartition* part, const char* name);
	Sets the name of a partition.  This will only work if the disk label
	supports it.  You can use this to check:
		ped_disk_type_check_feature (part->disk->type,
					     PED_DISK_TYPE_PARTITION_NAME);
	Note: the "name" will not be modified by libparted.  It can be free()'d
	by the caller immediately after ped_partition_set_name() is called.

const char* ped_partition_get_name (const PedPartition* part);
	Returns the name of a partition.  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.

int ped_partition_is_busy (PedPartition* part)
	Returns 1 if a partition is busy (i.e. mounted), 0 otherwise.  If part
	is an extended partition, then it is busy if any logical partitions are
	mounted.

const char* ped_partition_type_get_name (PedPartitionType part_type)
	Returns a name that seems mildly appropriate for a partition 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_flag_get_name (PedPartitionFlag flag)
	Returns a name for a flag.  Eg: 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.

PedPartitionFlag ped_partition_flag_get_by_name (const char* name)
	Returns the flag associated with "name".  "name" can be the English
	string, or the translation for the native language.

PedPartitionFlag ped_partition_flag_next (PedPartitionFlag flag)
	Function for iterating through all flags.  Returns the next flag.
	ped_partition_flag_next(0) returns the first flag.  Returns 0 if there
	are no more flags.

-----------------------------------------------------------------------------
7	PEDFILESYSTEM, PEDFILESYSTEMTYPE
-----------------------------------------------------------------------------

interface:		<parted/filesys.h>
implementation:		libparted/filesys.c,
			each file system type in fs_<file system name>

File systems exist on a PedGeometry - NOT a PedPartition.


7.1	FIELDS
--------------
struct _PedFileSystemType {
	PedFileSystemType*	next;
	char*			name;
	PedFileSystemOps*	ops;
};

Useful fields:
char*		name		name of the file system type

struct _PedFileSystem {
	PedFileSystemType*	type;
	PedGeometry*		geom;
	void*			type_specific;
};

Useful fields:
PedGeometry*	geom		where the file system actually is.

7.2	FUNCTIONS
-----------------
PedFileSystemType* ped_file_system_type_get (char* name)
	Returns the PedFileSystemType with name "name".  If none is found,
	returns NULL.

PedFileSystemType* ped_file_system_type_get_next (PedFileSystemType* fs_type)
	Returns the next PedFileSystemType, after "fs_type".  If "fs_type"
	is the last one registered, returns NULL.

PedFileSystemType* ped_file_system_probe (PedGeometry* geom)
	Attempts to detect a file system on "geom".  If successful, returns
	the PedFileSystemType.  Otherwise, returns NULL.

PedFileSystem* ped_file_system_open (PedGeometry* geom)
	Opens a filesystem on "geom".  Returns a PedFileSystem object if
	successful.  Returns NULL on failure.  
	This is often called like this:
		fs = ped_file_system_open (&part.geom)

PedFileSystem* ped_file_system_create (PedGeometry* geom,
				       PedFileSystemType* type)
	Creates a new file system, and returns a PedFileSystem representing it.
	Returns NULL on failure.

int ped_file_system_clobber (PedGeometry* geom)
	Destroys a file system, so that it won't be probed with
	ped_file_system_probe().  Note: ped_file_system_create() calls this
	before creating a new file system.

int ped_file_system_close (PedFileSystem* fs)
	Closes "fs".  Returns 0 on failure.

int ped_file_system_check (PedFileSystem* fs)
	Checks "fs" for errors.  Returns 0 on failure.

int ped_file_system_copy (PedFileSystem* fs, PedGeometry* geom)
	Creates a new file system (of the same type) on "geom", and
	copies the contents of "fs" into the new filesystem. 
	Returns 0 on failure.

int ped_file_system_resize (PedFileSystem* fs, PedGeometry* geom)
	Resizes "fs" to new geometry "geom".  Returns 0 on failure.  Note:
	"geom" should satisfy the ped_file_system_get_resize_constraint().

PedConstraint* ped_file_system_get_resize_constraint (const PedFileSystem* fs)
	Returns a constraint, that represents all of the possible ways the
	file system can be resized.  Hints:
	* if constraint->start_align->grain_size == 0, or
	constraint->max_geom->length == 1, then the start can not be moved
	* constraint->min_size is the minimum size you can resize the partition
	to.  You might want to tell the user this ;-)

-----------------------------------------------------------------------------
8	PEDCONSTRAINT, PEDALIGNMENT
-----------------------------------------------------------------------------

interface:		<parted/constraint.h>, <parted/natmath.h>
implementation:		libparted/constraint.c, libparted/natmath.c

Constraints are used to communicate restrictions on operations (only
ped_file_system_resize() at the moment).  Constraints are restrictions
on the location and alignment of the start and end of a partition, and the
minimum size.

"Alignments" are restrictions on the location of a sector, in the form of:

	sector = offset + X * grain_size

For example, logical partitions on msdos disk labels usually have a constraint
with offset = 63 and grain_size = 16065.  (Long story!)  An important
(and non-obvious!) property of alignment restrictions is they are closed
under intersection.  i.e. if you take two constraints, like (offset, grain_size)
= (63, 16065) and (0, 4), then either:
  * there are no valid solutions
  * all solutions can be expressed in the form of (offset + X * grain_size)
In the example, the intersection of the constraint is (16128, 64260).

For more information on the maths, see the source - there's a large comment
containing proofs above ped_alignment_intersect() in libparted/natmath.c

The restrictions on the location of the start and end are in the form of 
PedGeometry objects - continous regions in which the start and end must lie.
Obviously, these restrictions are also closed under intersection.

The other restriction - the minimum size - is also closed under intersection.
(The intersection of 2 minimum size restrictions is the maximum of the
2 values)

Therefore, constraints are closed under intersection.  libparted can compute
the intersection of constraints very efficiently.  Therefore, you can satisfy
an arbitary number of constraints, by finding the intersection of all the
constraints.

The interface consists of construction constraints, finding the intersection
of constraints, and finding solutions to constraints.

8.1	FIELDS
--------------
struct _PedConstraint {
        PedAlignment*   start_align;
        PedAlignment*   end_align;
        PedGeometry*    start_range;
        PedGeometry*    end_range;
        PedSector       min_size;
};

struct _PedAlignment {
        PedSector       offset;
        PedSector       grain_size;
};

8.2	FUNCTIONS
-----------------

int ped_constraint_init (
		PedConstraint* constraint,
		const PedAlignment* start_align,
		const PedAlignment* end_align,
		const PedGeometry* start_range,
		const PedGeometry* end_range,
		PedSector min_size)
	Initialises a pre-allocate piece of memory, to contain a constraint.
	Returns 0 on failure.

PedConstraint* ped_constraint_new (
		const PedAlignment* start_align,
		const PedAlignment* end_align,
		const PedGeometry* start_range,
		const PedGeometry* end_range,
		PedSector min_size)
	Creates a new constraint.  Returns NULL on failure.

PedConstraint* ped_constraint_duplicate (const PedConstraint* constraint)
	Duplicates "constraint".

void ped_constraint_done (PedConstraint* constraint)
	Frees up memory allocated for "constraint", initialized with
	ped_constraint_init().

void ped_constraint_destroy (PedConstraint* constraint)
	Frees up memory allocated for "constraint", allocated with
	ped_constraint_new().

PedConstraint* ped_constraint_intersect (
		const PedConstraint* a, const PedConstraint* b)
	Creates a new constraint, such that a PedGeometry is a solution to the
	new constraint if and only if it is a solution to both "a" and "b".
	If there are no PedGeometry objects that can satisfy both "a" and
	"b", then NULL is returned.  NULL is a valid PedConstraint object,
	that can be used for all ped_constraint_* functions.

PedGeometry* ped_constraint_solve_max (const PedConstraint* constraint)
	Finds the largest solution (i.e. geometry with maximum length) for
	"constraint".  Returns NULL if there is no solution.

PedGeometry* ped_constraint_solve_nearest (
        	const PedConstraint* constraint, const PedGeometry* geom)
	Solves "constraint", returning the nearest to "geom".  If there is no
	solution, NULL is returned.

int ped_constraint_is_solution (const PedConstraint* constraint,
		const PedGeometry* geom)
	Returns 1 if "geom" is a solution to "constraint", and 0 if it is not a
	solution.

PedConstraint* ped_constraint_any (const PedDisk* disk)
	Returns a constraint, such that any (valid) PedGeometry on "disk" is
	a solution.

PedConstraint* ped_constraint_exact (const PedGeometry* geom)
	Returns a constraint that only has one solution: "geom".

int ped_alignment_init (PedAlignment* align, PedSector offset,
                        PedSector grain_size)
	Initializes a preallocated piece of memory for an alignment object
	(used by PedConstraint), representing all PedSector's that are of the
	form "offset + X * grain_size".

PedAlignment* ped_alignment_new (PedSector offset, PedSector grain_size)
	Returns an alignment object (used by PedConstraint), representing all
	PedSector's that are of the form "offset + X * grain_size".

void ped_alignment_destroy (PedAlignment* align)
	Frees up memory associated "align".

PedAlignment* ped_alignment_duplicate (const PedAlignment* align)
	Returns a duplicate of "align".

PedAlignment* ped_alignment_intersect (const PedAlignment* a,
		const PedAlignment* b)
	Returns a PedAlignment object, such that a PedSector is a solution,
	if and only if it is a solutin to "a" and "b".  Note: if there are no
	solutions (i.e. no PedSector satisfies both "a" and "b"), then NULL
	is returned.  NULL is a valid PedAlignment object, and can be used
	for ped_alignment_*() function.

PedSector ped_alignment_align_up (const PedAlignment* align,
		const PedGeometry* geom, PedSector sector)
	Returns the closest PedSector to "sector", that lies within "geom" and
	satisfies the "align" restriction, or -1 if there is no such PedSector.
	PedSector's that are not smaller than "sector" are always considered
	closer.

PedSector ped_alignment_align_down (const PedAlignment* align,
		const PedGeometry* geom, PedSector sector)
	Returns the closest PedSector to "sector", that lies within "geom" and
	satisfies the "align" restriction, or -1 if there is no such PedSector.
	PedSector's that are not larger than "sector" are always considered
	closer.

PedSector ped_alignment_align_nearest (const PedAlignment* align,
		const PedGeometry* geom, PedSector sector)
	Returns the closest PedSector to "sector", that lies within "geom" and
	satisfies the "align" restriction, or -1 if there is no such PedSector.

int ped_alignment_is_aligned (const PedAlignment* align,
		const PedGeometry* geom, PedSector sector)
	Returns 1 if "sector" lies within "geom" and satisfies the "align"
	restriction, and 0 otherwise.

-----------------------------------------------------------------------------
9	EXCEPTIONS
-----------------------------------------------------------------------------

interface:		<parted/exception.h>
implementation:		libparted/exception.c

There are a few types of exceptions: PED_EXCEPTION_INFORMATION,
PED_EXCEPTION_WARNING, PED_EXCEPTION_ERROR, PED_EXCEPTION_FATAL,
PED_EXCEPTION_BUG.

They are "thrown" when one of the above events occur while executing
a libparted function.  For example, if ped_device_open() fails, because the
device doesn't exist, an exception will be thrown.  Exceptions contain
text describeing what the event was.  In this case: the device
doesn't exist.
	It will give at least one option for resolving the exception:
PED_EXCEPTION_FIX, PED_EXCEPTION_YES, PED_EXCEPTION_NO, PED_EXCEPTION_OK,
PED_EXCEPTION_RETRY, PED_EXCEPTION_IGNORE, PED_EXCEPTION_CANCEL.
	After an exception is thrown, there are a two things that
can happen:
(1) an exception handler is called, which selects how the exception
should be resolved (usually by asking the user).  Also note: an exception
handler may choose to return PED_EXCEPTION_UNHANDLED.  In this case, a default
action will be taken by libparted.  In general, a default action will take a
"safe" option.
(2) the exception is not handled, because the caller of the function wants
to handle everything itself.

9.1	FIELDS
--------------
enum _PedExceptionType {
	PED_EXCEPTION_INFORMATION=1,
	PED_EXCEPTION_WARNING=2,
	PED_EXCEPTION_ERROR=3,
	PED_EXCEPTION_FATAL=4,
	PED_EXCEPTION_BUG=5,
	PED_EXCEPTION_NO_FEATURE=6
};
typedef enum _PedExceptionType PedExceptionType;

enum _PedExceptionOption {
	PED_EXCEPTION_UNHANDLED=0,
	PED_EXCEPTION_FIX=1,
	PED_EXCEPTION_YES=2,
	PED_EXCEPTION_NO=4,
	PED_EXCEPTION_OK=8,
	PED_EXCEPTION_RETRY=16,
	PED_EXCEPTION_IGNORE=32,
	PED_EXCEPTION_CANCEL=64,
};
typedef enum _PedExceptionOption PedExceptionOption;

struct _PedException {
	char*			message;
	PedExceptionType	type;
	PedExceptionOption	options;
};

PedExceptionType	type		the type of exception
PedExceptionOption	options		the ways an exception can be resolved

9.2	FUNCTIONS
-----------------
char* ped_exception_get_type_string (PedExceptionType ex_type)
	Returns a string describing an exception type.

char* ped_exception_get_option_string (PedExceptionOption ex_opt)
	Returns a string describing an exception option.

typedef PedExceptionOption (PedExceptionHandler) (PedException* ex);
void ped_exception_set_handler (PedExceptionHandler* handler)
	Sets the exception handler.  The exception handler should return
	ONE of the options set in ex->options, indicating the way the
	event should be resolved.

PedExceptionOption ped_exception_throw (PedExceptionType ex_type,
		PedExceptionOption ex_opt, const char* message, ...)
	INTERNAL: throws an exception.  You can also use this in a front-end
	to libparted.
		message is a printf like format string.  So you can do:
	ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_RETRY_CANCEL,
			     "Can't open %s", file_name);
	Returns the option selected to resolve the exception.  If the exception
	was unhandled, PED_EXCEPTION_UNHANDLED is returned.

PedExceptionOption ped_exception_rethrow()
	Rethrows an unhandled exception.

void ped_exception_catch()
	Asserts that the exception has been resolved.

void ped_exception_fetch_all()
	Indicates that exceptions should not go to the exception handler, but
	passed up to the calling function(s).  All calls to
	ped_exception_throw() will return PED_EXCEPTION_UNHANDLED.

void ped_exception_leave_all()
	Indicate that the calling function does not want to accept any
	responsibilty for exceptions any more.  Note: a caller of that
	function may still want responsibility, so ped_exception_throw()
	may not invoke the exception handler.

