parted/parted-1.9.0-export-alignment-info.patch
Hans de Goede 7061b8af36 - Fix error when creating a fresh dasd disk (#532425)
- Rewrite dasd disk duplication patches, as the old old ones conflicted
    with fixing creating a fresh dasd disk
2009-11-03 12:07:15 +00:00

571 lines
21 KiB
Diff

diff -up parted-1.9.0/configure.ac.export-align parted-1.9.0/configure.ac
--- parted-1.9.0/configure.ac.export-align 2009-07-23 19:52:08.000000000 +0200
+++ parted-1.9.0/configure.ac 2009-11-03 11:30:46.000000000 +0100
@@ -519,6 +519,18 @@ HOST=$(hostname)
BUILDINFO="$USER@$HOST, $DATE"
AC_SUBST([BUILDINFO])
+LIB_BLKID=
+AC_SUBST([LIB_BLKID])
+pe_saved_libs=$LIBS
+ AC_SEARCH_LIBS([blkid_probe_get_topology], [blkid],
+ [test "$ac_cv_search_blkid_probe_get_topology" = "none required" \
+ || LIB_BLKID=$ac_cv_search_blkid_probe_get_topology])
+ AC_CHECK_FUNC([blkid_probe_get_topology], [use_blkid=1], [use_blkid=0])
+LIBS=$pe_saved_libs
+AC_DEFINE_UNQUOTED([USE_BLKID], [$use_blkid],
+ [Define if you have sufficient blkid support.])
+AC_CHECK_HEADERS_ONCE([blkid/blkid.h])
+
AC_OUTPUT([
Makefile
lib/Makefile
diff -up parted-1.9.0/include/parted/device.h.export-align parted-1.9.0/include/parted/device.h
--- parted-1.9.0/include/parted/device.h.export-align 2009-07-23 19:52:08.000000000 +0200
+++ parted-1.9.0/include/parted/device.h 2009-11-03 11:30:46.000000000 +0100
@@ -92,6 +92,8 @@ struct _PedDevice {
void* arch_specific;
};
+#include <parted/natmath.h>
+
/**
* List of functions implementing architecture-specific operations.
*/
@@ -112,6 +114,9 @@ struct _PedDeviceArchOps {
PedSector (*check) (PedDevice* dev, void* buffer,
PedSector start, PedSector count);
void (*probe_all) ();
+ /* These functions are optional */
+ PedAlignment *(*get_minimum_alignment)(const PedDevice *dev);
+ PedAlignment *(*get_optimum_alignment)(const PedDevice *dev);
};
#include <parted/constraint.h>
@@ -141,6 +146,14 @@ extern PedSector ped_device_check (PedDe
PedSector start, PedSector count);
extern PedConstraint* ped_device_get_constraint (PedDevice* dev);
+extern PedConstraint *ped_device_get_minimal_aligned_constraint(
+ const PedDevice *dev);
+extern PedConstraint *ped_device_get_optimal_aligned_constraint(
+ const PedDevice *dev);
+
+extern PedAlignment *ped_device_get_minimum_alignment(const PedDevice *dev);
+extern PedAlignment *ped_device_get_optimum_alignment(const PedDevice *dev);
+
/* private stuff ;-) */
extern void _ped_device_probe (const char* path);
diff -up parted-1.9.0/include/parted/disk.h.export-align parted-1.9.0/include/parted/disk.h
--- parted-1.9.0/include/parted/disk.h.export-align 2009-11-03 11:30:46.000000000 +0100
+++ parted-1.9.0/include/parted/disk.h 2009-11-03 11:30:46.000000000 +0100
@@ -214,6 +214,7 @@ struct _PedDiskOps {
int (*get_max_primary_partition_count) (const PedDisk* disk);
bool (*get_max_supported_partition_count) (const PedDisk* disk,
int* supported);
+ PedAlignment *(*get_partition_alignment)(const PedDisk *disk);
};
struct _PedDiskType {
@@ -263,6 +264,8 @@ extern int ped_disk_get_last_partition_n
extern int ped_disk_get_max_primary_partition_count (const PedDisk* disk);
extern bool ped_disk_get_max_supported_partition_count(const PedDisk* disk,
int* supported);
+extern PedAlignment *ped_disk_get_partition_alignment(const PedDisk *disk);
+
extern int ped_disk_align_to_cylinders_on();
extern int ped_disk_align_to_cylinders_toggle();
/** @} */
diff -up parted-1.9.0/include/parted/natmath.h.export-align parted-1.9.0/include/parted/natmath.h
--- parted-1.9.0/include/parted/natmath.h.export-align 2009-07-23 19:52:08.000000000 +0200
+++ parted-1.9.0/include/parted/natmath.h 2009-11-03 11:30:46.000000000 +0100
@@ -31,6 +31,7 @@ typedef struct _PedAlignment PedAlignmen
#include <parted/disk.h>
#include <parted/device.h>
+#include <parted/geom.h>
#define PED_MIN(a, b) ( ((a)<(b)) ? (a) : (b) )
#define PED_MAX(a, b) ( ((a)>(b)) ? (a) : (b) )
diff -up parted-1.9.0/libparted/Makefile.am.export-align parted-1.9.0/libparted/Makefile.am
--- parted-1.9.0/libparted/Makefile.am.export-align 2009-07-23 19:52:08.000000000 +0200
+++ parted-1.9.0/libparted/Makefile.am 2009-11-03 11:30:46.000000000 +0100
@@ -50,6 +50,7 @@ libparted_la_LIBADD = \
$(DL_LIBS) \
$(DM_LIBS) \
$(SELINUX_LIBS) \
+ $(LIB_BLKID) \
$(INTLLIBS)
EXTRA_DIST = mbr.s
diff -up parted-1.9.0/libparted/arch/linux.c.export-align parted-1.9.0/libparted/arch/linux.c
--- parted-1.9.0/libparted/arch/linux.c.export-align 2009-11-03 11:30:46.000000000 +0100
+++ parted-1.9.0/libparted/arch/linux.c 2009-11-03 11:30:46.000000000 +0100
@@ -598,7 +598,24 @@ _have_kern26 ()
kver = _get_linux_version();
return have_kern26 = kver >= KERNEL_VERSION (2,6,0) ? 1 : 0;
}
-
+
+#if USE_BLKID
+static void
+get_blkid_topology (LinuxSpecific *arch_specific)
+{
+ arch_specific->probe = blkid_new_probe ();
+ if (!arch_specific->probe)
+ return;
+
+ if (blkid_probe_set_device(arch_specific->probe,
+ arch_specific->fd, 0, 0))
+ return;
+
+ arch_specific->topology =
+ blkid_probe_get_topology(arch_specific->probe);
+}
+#endif
+
static void
_device_set_sector_size (PedDevice* dev)
{
@@ -626,6 +643,9 @@ _device_set_sector_size (PedDevice* dev)
dev->sector_size = (long long)sector_size;
}
+#if USE_BLKID
+ get_blkid_topology(arch_specific);
+#endif
/* Return PED_SECTOR_SIZE_DEFAULT for DASDs. */
if (dev->type == PED_DEVICE_DASD) {
dev->sector_size = PED_SECTOR_SIZE_DEFAULT;
@@ -1215,6 +1235,10 @@ linux_new (const char* path)
goto error_free_path;
arch_specific = LINUX_SPECIFIC (dev);
arch_specific->dmtype = NULL;
+#if USE_BLKID
+ arch_specific->probe = NULL;
+ arch_specific->topology = NULL;
+#endif
dev->open_count = 0;
dev->read_only = 0;
@@ -1335,7 +1359,12 @@ error:
static void
linux_destroy (PedDevice* dev)
{
- free (((LinuxSpecific*)dev->arch_specific)->dmtype);
+ LinuxSpecific *arch_specific = LINUX_SPECIFIC(dev);
+#if USE_BLKID
+ if (arch_specific->probe)
+ blkid_free_probe(arch_specific->probe);
+#endif
+ free (arch_specific->dmtype);
free (dev->arch_specific);
free (dev->path);
free (dev->model);
@@ -2446,6 +2475,34 @@ linux_disk_commit (PedDisk* disk)
return 1;
}
+#if HAVE_BLKID_BLKID_H
+PedAlignment*
+linux_get_minimum_alignment(const PedDevice *dev)
+{
+ blkid_topology tp = LINUX_SPECIFIC(dev)->topology;
+
+ if (!tp || blkid_topology_get_minimum_io_size(tp) == 0)
+ return NULL; /* ped_alignment_none */
+
+ return ped_alignment_new(
+ blkid_topology_get_alignment_offset(tp) / dev->sector_size,
+ blkid_topology_get_minimum_io_size(tp) / dev->sector_size);
+}
+
+PedAlignment*
+linux_get_optimum_alignment(const PedDevice *dev)
+{
+ blkid_topology tp = LINUX_SPECIFIC(dev)->topology;
+
+ if (!tp || blkid_topology_get_optimal_io_size(tp) == 0)
+ return NULL; /* ped_alignment_none */
+
+ return ped_alignment_new(
+ blkid_topology_get_alignment_offset(tp) / dev->sector_size,
+ blkid_topology_get_optimal_io_size(tp) / dev->sector_size);
+}
+#endif
+
static PedDeviceArchOps linux_dev_ops = {
_new: linux_new,
destroy: linux_destroy,
@@ -2459,7 +2516,11 @@ static PedDeviceArchOps linux_dev_ops =
check: linux_check,
sync: linux_sync,
sync_fast: linux_sync_fast,
- probe_all: linux_probe_all
+ probe_all: linux_probe_all,
+#if HAVE_BLKID_BLKID_H
+ get_minimum_alignment: linux_get_minimum_alignment,
+ get_optimum_alignment: linux_get_optimum_alignment,
+#endif
};
PedDiskArchOps linux_disk_ops = {
diff -up parted-1.9.0/libparted/arch/linux.h.export-align parted-1.9.0/libparted/arch/linux.h
--- parted-1.9.0/libparted/arch/linux.h.export-align 2009-07-23 19:52:08.000000000 +0200
+++ parted-1.9.0/libparted/arch/linux.h 2009-11-03 11:30:46.000000000 +0100
@@ -22,6 +22,10 @@
# include <parted/fdasd.h>
#endif
+#if HAVE_BLKID_BLKID_H
+# include <blkid/blkid.h>
+#endif
+
#define LINUX_SPECIFIC(dev) ((LinuxSpecific*) (dev)->arch_specific)
typedef struct _LinuxSpecific LinuxSpecific;
@@ -34,6 +38,10 @@ struct _LinuxSpecific {
/* IBM internal dasd structure (i guess ;), required. */
struct fdasd_anchor *anchor;
#endif
+#if HAVE_BLKID_BLKID_H
+ blkid_probe probe;
+ blkid_topology topology;
+#endif
};
#endif /* PED_ARCH_LINUX_H_INCLUDED */
diff -up parted-1.9.0/libparted/device.c.export-align parted-1.9.0/libparted/device.c
--- parted-1.9.0/libparted/device.c.export-align 2009-07-23 19:52:08.000000000 +0200
+++ parted-1.9.0/libparted/device.c 2009-11-03 11:30:46.000000000 +0100
@@ -416,33 +416,146 @@ ped_device_sync_fast (PedDevice* dev)
}
/**
- * Get a constraint that represents hardware requirements on alignment and
- * geometry.
- * This is, for example, important for media that have a physical sector
- * size that is a multiple of the logical sector size.
+ * Get a constraint that represents hardware requirements on geometry.
+ * This function will return a constraint representing the limits imposed
+ * by the size of the disk, it will *not* provide any alignment constraints.
*
- * \warning This function is experimental for physical sector sizes not equal to
- * 2^9.
+ * Alignment constraints may be desirable when using media that have a physical
+ * sector size that is a multiple of the logical sector size, as in this case
+ * proper partition alignment can benefit disk performance signigicantly.
+ * When you want a constraint with alignment info, use
+ * ped_device_get_minimal_aligned_constraint() or
+ * ped_device_get_optimal_aligned_constraint().
+ *
+ * \return NULL on error, otherwise a pointer to a dynamically allocated
+ * constraint.
*/
PedConstraint*
ped_device_get_constraint (PedDevice* dev)
{
- int multiplier = dev->phys_sector_size / dev->sector_size;
-
- PedAlignment* start_align = ped_alignment_new (multiplier, multiplier);
-
PedGeometry *s, *e;
PedConstraint* c = ped_constraint_new (
- start_align, ped_alignment_any,
+ ped_alignment_any, ped_alignment_any,
s = ped_geometry_new (dev, 0, dev->length),
e = ped_geometry_new (dev, 0, dev->length),
1, dev->length);
free (s);
free (e);
+ return c;
+}
+
+static PedConstraint*
+_ped_device_get_aligned_constraint(const PedDevice *dev,
+ PedAlignment* start_align)
+{
+ PedAlignment *end_align = NULL;
+ PedGeometry *whole_dev_geom = NULL;
+ PedConstraint *c = NULL;
+
+ if (start_align) {
+ end_align = ped_alignment_new(start_align->offset - 1,
+ start_align->grain_size);
+ if (!end_align)
+ goto free_start_align;
+ }
+
+ whole_dev_geom = ped_geometry_new (dev, 0, dev->length);
+
+ if (start_align)
+ c = ped_constraint_new (start_align, end_align,
+ whole_dev_geom, whole_dev_geom,
+ 1, dev->length);
+ else
+ c = ped_constraint_new (ped_alignment_any, ped_alignment_any,
+ whole_dev_geom, whole_dev_geom,
+ 1, dev->length);
+
+ free (whole_dev_geom);
+ free (end_align);
+free_start_align:
free (start_align);
return c;
}
+/**
+ * Get a constraint that represents hardware requirements on geometry and
+ * alignment.
+ *
+ * This function will return a constraint representing the limits imposed
+ * by the size of the disk and the minimal alignment requirements for proper
+ * performance of the disk.
+ *
+ * \return NULL on error, otherwise a pointer to a dynamically allocated
+ * constraint.
+ */
+PedConstraint*
+ped_device_get_minimal_aligned_constraint(const PedDevice *dev)
+{
+ return _ped_device_get_aligned_constraint(dev,
+ ped_device_get_minimum_alignment(dev));
+}
+
+/**
+ * Get a constraint that represents hardware requirements on geometry and
+ * alignment.
+ *
+ * This function will return a constraint representing the limits imposed
+ * by the size of the disk and the alignment requirements for optimal
+ * performance of the disk.
+ *
+ * \return NULL on error, otherwise a pointer to a dynamically allocated
+ * constraint.
+ */
+PedConstraint*
+ped_device_get_optimal_aligned_constraint(const PedDevice *dev)
+{
+ return _ped_device_get_aligned_constraint(dev,
+ ped_device_get_optimum_alignment(dev));
+}
+
+/**
+ * Get an alignment that represents minimum hardware requirements on alignment.
+ * When for example using media that has a physical sector size that is a
+ * multiple of the logical sector size, it is desirable to have disk accesses
+ * (and thus partitions) properly aligned. Having partitions not aligned to
+ * the minimum hardware requirements may lead to a performance penalty.
+ *
+ * The returned alignment describes the alignment for the start sector of the
+ * partition, the end sector should be aligned too, to get the end sector
+ * alignment decrease the returned alignment's offset by 1.
+ *
+ * \return the minimum alignment of partition start sectors, or NULL if this
+ * information is not available.
+ */
+PedAlignment*
+ped_device_get_minimum_alignment(const PedDevice *dev)
+{
+ if (ped_architecture->dev_ops->get_minimum_alignment)
+ return ped_architecture->dev_ops->get_minimum_alignment(dev);
+
+ return NULL; /* ped_alignment_none */
+}
+
+/**
+ * Get an alignment that represents the hardware requirements for optimal
+ * performance.
+ *
+ * The returned alignment describes the alignment for the start sector of the
+ * partition, the end sector should be aligned too, to get the end sector
+ * alignment decrease the returned alignment's offset by 1.
+ *
+ * \return the optimal alignment of partition start sectors, or NULL if this
+ * information is not available.
+ */
+PedAlignment*
+ped_device_get_optimum_alignment(const PedDevice *dev)
+{
+ if (ped_architecture->dev_ops->get_optimum_alignment)
+ return ped_architecture->dev_ops->get_optimum_alignment(dev);
+
+ return NULL; /* ped_alignment_none */
+}
+
/** @} */
diff -up parted-1.9.0/libparted/disk.c.export-align parted-1.9.0/libparted/disk.c
--- parted-1.9.0/libparted/disk.c.export-align 2009-11-03 11:30:46.000000000 +0100
+++ parted-1.9.0/libparted/disk.c 2009-11-03 11:30:46.000000000 +0100
@@ -703,6 +703,26 @@ ped_disk_get_max_supported_partition_cou
}
/**
+ * Get the alignment needed for partition boundaries on this disk.
+ * The returned alignment describes the alignment for the start sector of the
+ * partition, for all disklabel types which require alignment, except Sun
+ * disklabels, the end sector must be aligned too. To get the end sector
+ * alignment decrease the PedAlignment offset by 1.
+ *
+ * \return NULL on error, otherwise a pointer to a dynamically allocated
+ * alignment.
+ */
+PedAlignment*
+ped_disk_get_partition_alignment(const PedDisk *disk)
+{
+ /* disklabel handlers which don't need alignment don't define this */
+ if (!disk->type->ops->get_partition_alignment)
+ return ped_alignment_duplicate(ped_alignment_any);
+
+ return disk->type->ops->get_partition_alignment(disk);
+}
+
+/**
* Get the maximum number of (primary) partitions the disk label supports.
*
* For example, MacIntosh partition maps can have different sizes,
diff -up parted-1.9.0/libparted/labels/dasd.c.export-align parted-1.9.0/libparted/labels/dasd.c
--- parted-1.9.0/libparted/labels/dasd.c.export-align 2009-11-03 11:30:46.000000000 +0100
+++ parted-1.9.0/libparted/labels/dasd.c 2009-11-03 11:32:19.000000000 +0100
@@ -646,6 +646,16 @@ dasd_get_max_supported_partition_count (
return true;
}
+static PedAlignment*
+dasd_get_partition_alignment(const PedDisk *disk)
+{
+ DasdDiskSpecific* disk_specific = disk->disk_specific;
+ PedSector sector_size =
+ disk_specific->real_sector_size / disk->dev->sector_size;
+
+ return ped_alignment_new(0, disk->dev->hw_geom.sectors * sector_size);
+}
+
static PedConstraint*
_primary_constraint (PedDisk* disk)
{
@@ -830,6 +840,7 @@ static PedDiskOps dasd_disk_ops = {
alloc_metadata: dasd_alloc_metadata,
get_max_primary_partition_count: dasd_get_max_primary_partition_count,
get_max_supported_partition_count: dasd_get_max_supported_partition_count,
+ get_partition_alignment: dasd_get_partition_alignment,
partition_duplicate: NULL
};
diff -up parted-1.9.0/libparted/labels/mac.c.export-align parted-1.9.0/libparted/labels/mac.c
--- parted-1.9.0/libparted/labels/mac.c.export-align 2009-07-23 19:52:08.000000000 +0200
+++ parted-1.9.0/libparted/labels/mac.c 2009-11-03 11:30:46.000000000 +0100
@@ -1375,6 +1375,14 @@ mac_partition_get_name (const PedPartiti
return mac_data->volume_name;
}
+static PedAlignment*
+mac_get_partition_alignment(const PedDisk *disk)
+{
+ PedSector sector_size = disk->dev->sector_size / 512;
+
+ return ped_alignment_new(0, sector_size);
+}
+
static PedConstraint*
_primary_constraint (PedDisk* disk)
{
@@ -1606,7 +1614,8 @@ static PedDiskOps mac_disk_ops = {
get_max_primary_partition_count:
mac_get_max_primary_partition_count,
get_max_supported_partition_count:
- mac_get_max_supported_partition_count
+ mac_get_max_supported_partition_count,
+ get_partition_alignment: mac_get_partition_alignment,
};
static PedDiskType mac_disk_type = {
diff -up parted-1.9.0/libparted/labels/pc98.c.export-align parted-1.9.0/libparted/labels/pc98.c
--- parted-1.9.0/libparted/labels/pc98.c.export-align 2009-07-23 19:52:08.000000000 +0200
+++ parted-1.9.0/libparted/labels/pc98.c 2009-11-03 11:30:46.000000000 +0100
@@ -720,6 +720,15 @@ pc98_partition_get_name (const PedPartit
return pc98_data->name;
}
+static PedAlignment*
+pc98_get_partition_alignment(const PedDisk *disk)
+{
+ PedSector cylinder_size =
+ disk->dev->hw_geom.sectors * disk->dev->hw_geom.heads;
+
+ return ped_alignment_new(0, cylinder_size);
+}
+
static PedConstraint*
_primary_constraint (PedDisk* disk)
{
@@ -872,7 +881,8 @@ static PedDiskOps pc98_disk_ops = {
get_max_primary_partition_count:
pc98_get_max_primary_partition_count,
get_max_supported_partition_count:
- pc98_get_max_supported_partition_count
+ pc98_get_max_supported_partition_count,
+ get_partition_alignment: pc98_get_partition_alignment,
};
static PedDiskType pc98_disk_type = {
diff -up parted-1.9.0/libparted/labels/rdb.c.export-align parted-1.9.0/libparted/labels/rdb.c
--- parted-1.9.0/libparted/labels/rdb.c.export-align 2009-07-23 19:52:08.000000000 +0200
+++ parted-1.9.0/libparted/labels/rdb.c 2009-11-03 11:30:46.000000000 +0100
@@ -1024,6 +1024,15 @@ amiga_partition_get_name (const PedParti
return _amiga_get_bstr(partition->pb_DriveName);
}
+static PedAlignment*
+amiga_get_partition_alignment(const PedDisk *disk)
+{
+ PedSector cylinder_size =
+ disk->dev->hw_geom.sectors * disk->dev->hw_geom.heads;
+
+ return ped_alignment_new(0, cylinder_size);
+}
+
static PedConstraint*
_amiga_get_constraint (const PedDisk *disk)
{
@@ -1166,7 +1175,8 @@ static PedDiskOps amiga_disk_ops = {
get_max_primary_partition_count:
amiga_get_max_primary_partition_count,
get_max_supported_partition_count:
- amiga_get_max_supported_partition_count
+ amiga_get_max_supported_partition_count,
+ get_partition_alignment: amiga_get_partition_alignment,
};
static PedDiskType amiga_disk_type = {
diff -up parted-1.9.0/libparted/labels/sun.c.export-align parted-1.9.0/libparted/labels/sun.c
--- parted-1.9.0/libparted/labels/sun.c.export-align 2009-07-23 19:52:08.000000000 +0200
+++ parted-1.9.0/libparted/labels/sun.c 2009-11-03 11:30:46.000000000 +0100
@@ -677,6 +677,15 @@ sun_get_max_primary_partition_count (con
return SUN_DISK_MAXPARTITIONS;
}
+static PedAlignment*
+sun_get_partition_alignment(const PedDisk *disk)
+{
+ PedSector block =
+ disk->dev->hw_geom.sectors * disk->dev->hw_geom.heads;
+
+ return ped_alignment_new(0, block);
+}
+
static PedConstraint*
_get_strict_constraint (PedDisk* disk)
{
@@ -867,6 +876,7 @@ static PedDiskOps sun_disk_ops = {
sun_get_max_primary_partition_count,
get_max_supported_partition_count:
sun_get_max_supported_partition_count,
+ get_partition_alignment: sun_get_partition_alignment,
partition_set_name: NULL,
partition_get_name: NULL,