ce6563fae4
- 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)
407 lines
12 KiB
Diff
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,
|