parted/parted-1.9.0-diskflags.patch
Hans de Goede ce6563fae4 - Allow partitioning of loopback devices (#546622)
- Add libparted function to query maximum partition length and start
    addresses for a given disk (#533417)
- Add per disk flags functions from upstream, this is the way upstream has
    implemented the disable cylinder alignment functionality
- Add --align cmdline option to specify how to align new partitions see the
    parted man page for details (#361951)
- Make the default alignment for new partitions optimal (#361951)
- When cylinder alignment is disabled, allow use of the last (incomplete)
    cylinder of the disk (#533328)
- Don't crash when printing partition tables in Russian (#543029)
- Make parted work correctly with new lvm (#525095)
2009-12-18 09:42:14 +00:00

407 lines
12 KiB
Diff

diff -up parted-1.9.0/include/parted/disk.h.diskflags parted-1.9.0/include/parted/disk.h
--- parted-1.9.0/include/parted/disk.h.diskflags 2009-12-15 11:07:11.000000000 +0100
+++ parted-1.9.0/include/parted/disk.h 2009-12-15 11:08:29.000000000 +0100
@@ -27,6 +27,20 @@
#define PED_DISK_H_INCLUDED
/**
+ * Disk flags
+ */
+enum _PedDiskFlag {
+ /* This flag (which defaults to true) controls if disk types for
+ which cylinder alignment is optional do cylinder alignment when a
+ new partition gets added.
+ This flag is available for msdos and sun disklabels (for sun labels
+ it only controls the aligning of the end of the partition) */
+ PED_DISK_CYLINDER_ALIGNMENT=1,
+};
+#define PED_DISK_FIRST_FLAG PED_DISK_CYLINDER_ALIGNMENT
+#define PED_DISK_LAST_FLAG PED_DISK_CYLINDER_ALIGNMENT
+
+/**
* Partition types
*/
enum _PedPartitionType {
@@ -72,6 +86,7 @@ struct _PedDiskOps;
struct _PedDiskType;
struct _PedDiskArchOps;
+typedef enum _PedDiskFlag PedDiskFlag;
typedef enum _PedPartitionType PedPartitionType;
typedef enum _PedPartitionFlag PedPartitionFlag;
typedef enum _PedDiskTypeFeature PedDiskTypeFeature;
@@ -180,6 +195,16 @@ struct _PedDiskOps {
void (*free) (PedDisk* disk);
int (*read) (PedDisk* disk);
int (*write) (const PedDisk* disk);
+ int (*disk_set_flag) (
+ PedDisk *disk,
+ PedDiskFlag flag,
+ int state);
+ int (*disk_get_flag) (
+ const PedDisk *disk,
+ PedDiskFlag flag);
+ int (*disk_is_flag_available) (
+ const PedDisk *disk,
+ PedDiskFlag flag);
/** \todo add label guessing op here */
/* partition operations */
@@ -304,6 +329,14 @@ extern const char* ped_partition_flag_ge
extern PedPartitionFlag ped_partition_flag_get_by_name (const char* name);
extern PedPartitionFlag ped_partition_flag_next (PedPartitionFlag flag);
+extern int ped_disk_set_flag(PedDisk *disk, PedDiskFlag flag, int state);
+extern int ped_disk_get_flag(const PedDisk *disk, PedDiskFlag flag);
+extern int ped_disk_is_flag_available(const PedDisk *disk, PedDiskFlag flag);
+
+extern const char *ped_disk_flag_get_name(PedDiskFlag flag);
+extern PedDiskFlag ped_disk_flag_get_by_name(const char *name);
+extern PedDiskFlag ped_disk_flag_next(PedDiskFlag flag);
+
/** @} */
/**
diff -up parted-1.9.0/libparted/disk.c.diskflags parted-1.9.0/libparted/disk.c
--- parted-1.9.0/libparted/disk.c.diskflags 2009-12-15 11:07:11.000000000 +0100
+++ parted-1.9.0/libparted/disk.c 2009-12-15 11:08:29.000000000 +0100
@@ -773,6 +773,130 @@ ped_disk_max_partition_start_sector (con
}
/**
+ * Set the state (\c 1 or \c 0) of a flag on a disk.
+ *
+ * \note It is an error to call this on an unavailable flag -- use
+ * ped_disk_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_disk_set_flag(PedDisk *disk, PedDiskFlag flag, int state)
+{
+ PED_ASSERT (disk != NULL, return 0);
+
+ PedDiskOps *ops = disk->type->ops;
+
+ if (!ped_disk_is_flag_available(disk, flag)) {
+ ped_exception_throw (
+ PED_EXCEPTION_ERROR,
+ PED_EXCEPTION_CANCEL,
+ "The flag '%s' is not available for %s disk labels.",
+ ped_disk_flag_get_name(flag),
+ disk->type->name);
+ return 0;
+ }
+
+ return ops->disk_set_flag(disk, flag, state);
+}
+
+/**
+ * Get the state (\c 1 or \c 0) of a flag on a disk.
+ */
+int
+ped_disk_get_flag(const PedDisk *disk, PedDiskFlag flag)
+{
+ PED_ASSERT (disk != NULL, return 0);
+
+ PedDiskOps *ops = disk->type->ops;
+
+ if (!ped_disk_is_flag_available(disk, flag))
+ return 0;
+
+ return ops->disk_get_flag(disk, flag);
+}
+
+/**
+ * Check whether a given flag is available on a disk.
+ *
+ * \return \c 1 if the flag is available.
+ */
+int
+ped_disk_is_flag_available(const PedDisk *disk, PedDiskFlag flag)
+{
+ PED_ASSERT (disk != NULL, return 0);
+
+ PedDiskOps *ops = disk->type->ops;
+
+ if (!ops->disk_is_flag_available)
+ return 0;
+
+ return ops->disk_is_flag_available(disk, flag);
+}
+
+/**
+ * Returns a name for a \p flag, e.g. PED_DISK_CYLINDER_ALIGNMENT will return
+ * "cylinder_alignment".
+ *
+ * \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_disk_flag_get_name(PedDiskFlag flag)
+{
+ switch (flag) {
+ case PED_DISK_CYLINDER_ALIGNMENT:
+ return N_("cylinder_alignment");
+
+ default:
+ ped_exception_throw (
+ PED_EXCEPTION_BUG,
+ PED_EXCEPTION_CANCEL,
+ _("Unknown disk flag, %d."),
+ flag);
+ return NULL;
+ }
+}
+
+/**
+ * Returns the flag associated with \p name.
+ *
+ * \p name can be the English
+ * string, or the translation for the native language.
+ */
+PedDiskFlag
+ped_disk_flag_get_by_name(const char *name)
+{
+ PedDiskFlag flag;
+
+ for (flag = ped_disk_flag_next(0); flag;
+ flag = ped_disk_flag_next(flag)) {
+ const char *flag_name = ped_disk_flag_get_name(flag);
+ if (strcasecmp(name, flag_name) == 0
+ || strcasecmp(name, _(flag_name)) == 0)
+ return flag;
+ }
+
+ return 0;
+}
+
+/**
+ * Iterates through all disk flags.
+ *
+ * ped_disk_flag_next(0) returns the first flag
+ *
+ * \return the next flag, or 0 if there are no more flags
+ */
+PedDiskFlag
+ped_disk_flag_next(PedDiskFlag flag)
+{
+ return (flag + 1) % (PED_DISK_LAST_FLAG + 1);
+}
+
+/**
* \internal We turned a really nasty bureaucracy problem into an elegant maths
* problem :-) Basically, there are some constraints to a partition's
* geometry:
diff -up parted-1.9.0/libparted/labels/dos.c.diskflags parted-1.9.0/libparted/labels/dos.c
--- parted-1.9.0/libparted/labels/dos.c.diskflags 2009-12-15 11:07:11.000000000 +0100
+++ parted-1.9.0/libparted/labels/dos.c 2009-12-15 11:12:46.000000000 +0100
@@ -140,6 +140,10 @@ typedef struct {
} OrigState;
typedef struct {
+ int cylinder_alignment;
+} DosDiskData;
+
+typedef struct {
unsigned char system;
int boot;
int hidden;
@@ -243,8 +247,16 @@ msdos_alloc (const PedDevice* dev)
PED_ASSERT (dev != NULL, return NULL);
disk = _ped_disk_alloc ((PedDevice*)dev, &msdos_disk_type);
- if (disk)
- disk->disk_specific = NULL;
+ if (disk) {
+ DosDiskData *disk_specific = ped_malloc(sizeof *disk_specific);
+ if (!disk_specific) {
+ free (disk);
+ return NULL;
+ }
+ disk_specific->cylinder_alignment = 1;
+ disk->disk_specific = disk_specific;
+ }
+
return disk;
}
@@ -256,7 +268,10 @@ msdos_duplicate (const PedDisk* disk)
new_disk = ped_disk_new_fresh (disk->dev, &msdos_disk_type);
if (!new_disk)
return NULL;
- new_disk->disk_specific = NULL;
+
+ memcpy(new_disk->disk_specific, disk->disk_specific,
+ sizeof(DosDiskData));
+
return new_disk;
}
@@ -265,7 +280,45 @@ msdos_free (PedDisk* disk)
{
PED_ASSERT (disk != NULL, return);
+ DosDiskData *disk_specific = disk->disk_specific;
_ped_disk_free (disk);
+ free(disk_specific);
+}
+
+static int
+msdos_disk_set_flag (PedDisk *disk, PedDiskFlag flag, int state)
+{
+ DosDiskData *disk_specific = disk->disk_specific;
+ switch (flag) {
+ case PED_DISK_CYLINDER_ALIGNMENT:
+ disk_specific->cylinder_alignment = !!state;
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+static int
+msdos_disk_get_flag (const PedDisk *disk, PedDiskFlag flag)
+{
+ DosDiskData *disk_specific = disk->disk_specific;
+ switch (flag) {
+ case PED_DISK_CYLINDER_ALIGNMENT:
+ return disk_specific->cylinder_alignment;
+ default:
+ return 0;
+ }
+}
+
+static int
+msdos_disk_is_flag_available (const PedDisk *disk, PedDiskFlag flag)
+{
+ switch (flag) {
+ case PED_DISK_CYLINDER_ALIGNMENT:
+ return 1;
+ default:
+ return 0;
+ }
}
#ifndef DISCOVER_ONLY
@@ -2029,7 +2083,9 @@ msdos_partition_align (PedPartition* par
partition_probe_bios_geometry (part, &bios_geom);
- if (ped_disk_align_to_cylinders_on())
+ DosDiskData *disk_specific = part->disk->disk_specific;
+ if (ped_disk_align_to_cylinders_on() &&
+ disk_specific->cylinder_alignment)
if (_align (part, &bios_geom, constraint))
return 1;
if (_align_no_geom (part, constraint))
@@ -2324,6 +2380,10 @@ static PedDiskOps msdos_disk_ops = {
write: NULL,
#endif
+ disk_set_flag: msdos_disk_set_flag,
+ disk_get_flag: msdos_disk_get_flag,
+ disk_is_flag_available: msdos_disk_is_flag_available,
+
partition_new: msdos_partition_new,
partition_duplicate: msdos_partition_duplicate,
partition_destroy: msdos_partition_destroy,
diff -up parted-1.9.0/libparted/labels/sun.c.diskflags parted-1.9.0/libparted/labels/sun.c
--- parted-1.9.0/libparted/labels/sun.c.diskflags 2009-12-15 11:07:11.000000000 +0100
+++ parted-1.9.0/libparted/labels/sun.c 2009-12-15 11:13:44.000000000 +0100
@@ -94,6 +94,7 @@ struct _SunPartitionData {
struct _SunDiskData {
PedSector length; /* This is based on cyl - alt-cyl */
SunRawLabel raw_label;
+ int cylinder_alignment;
};
static PedDiskType sun_disk_type;
@@ -190,6 +191,7 @@ sun_alloc (const PedDevice* dev)
bios_geom->cylinders = dev->length / cyl_size;
sun_specific->length = bios_geom->cylinders * cyl_size;
+ sun_specific->cylinder_alignment = 1;
label = &sun_specific->raw_label;
memset(label, 0, sizeof(SunRawLabel));
@@ -252,6 +254,42 @@ sun_free (PedDisk *disk)
}
static int
+sun_disk_set_flag (PedDisk *disk, PedDiskFlag flag, int state)
+{
+ SunDiskData *disk_specific = disk->disk_specific;
+ switch (flag) {
+ case PED_DISK_CYLINDER_ALIGNMENT:
+ disk_specific->cylinder_alignment = !!state;
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+static int
+sun_disk_get_flag (const PedDisk *disk, PedDiskFlag flag)
+{
+ SunDiskData *disk_specific = disk->disk_specific;
+ switch (flag) {
+ case PED_DISK_CYLINDER_ALIGNMENT:
+ return disk_specific->cylinder_alignment;
+ default:
+ return 0;
+ }
+}
+
+static int
+sun_disk_is_flag_available (const PedDisk *disk, PedDiskFlag flag)
+{
+ switch (flag) {
+ case PED_DISK_CYLINDER_ALIGNMENT:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+static int
_check_geometry_sanity (PedDisk* disk, SunRawLabel* label)
{
PedDevice* dev = disk->dev;
@@ -738,12 +776,15 @@ sun_partition_align (PedPartition* part,
{
PED_ASSERT (part != NULL, return 0);
- if (_ped_partition_attempt_align (part, constraint,
- _get_strict_constraint (part->disk)))
- return 1;
- if (_ped_partition_attempt_align (part, constraint,
- _get_lax_constraint (part->disk)))
- return 1;
+ SunDiskData *disk_specific = part->disk->disk_specific;
+
+ if (disk_specific->cylinder_alignment &&
+ _ped_partition_attempt_align (part, constraint,
+ _get_strict_constraint (part->disk)))
+ return 1;
+ if (_ped_partition_attempt_align (part, constraint,
+ _get_lax_constraint (part->disk)))
+ return 1;
#ifndef DISCOVER_ONLY
ped_exception_throw (
@@ -862,6 +903,10 @@ static PedDiskOps sun_disk_ops = {
write: NULL,
#endif
+ disk_set_flag: sun_disk_set_flag,
+ disk_get_flag: sun_disk_get_flag,
+ disk_is_flag_available: sun_disk_is_flag_available,
+
partition_new: sun_partition_new,
partition_duplicate: sun_partition_duplicate,
partition_destroy: sun_partition_destroy,