[parted-devel] [PATCH] Properly sync partitions with operating system
Petr Uzel
petr.uzel at suse.cz
Thu Feb 19 11:28:14 UTC 2009
Hi,
please see the inlined comments.
On Wed, Feb 18, 2009 at 10:01:11PM +0100, Joel Granados Moreno wrote:
> ---
> include/parted/disk.h | 3 +-
> libparted/arch/linux.c | 113 +++++++++++++++++++++++++++++++++-------------
> libparted/disk.c | 14 +++++-
> libparted/labels/aix.c | 8 +++
> libparted/labels/bsd.c | 2 +
> libparted/labels/dasd.c | 1 +
> libparted/labels/dos.c | 10 ++++-
> libparted/labels/dvh.c | 3 +-
> libparted/labels/gpt.c | 9 +++-
> libparted/labels/loop.c | 2 +
> libparted/labels/mac.c | 10 ++++-
> libparted/labels/pc98.c | 2 +
> libparted/labels/rdb.c | 2 +
> libparted/labels/sun.c | 2 +
> 14 files changed, 143 insertions(+), 38 deletions(-)
>
> diff --git a/include/parted/disk.h b/include/parted/disk.h
> index dfcf39e..9e50716 100644
> --- a/include/parted/disk.h
> +++ b/include/parted/disk.h
> @@ -210,6 +210,7 @@ struct _PedDiskOps {
> /* other */
> int (*alloc_metadata) (PedDisk* disk);
> int (*get_max_primary_partition_count) (const PedDisk* disk);
> + int (*get_max_partition_count) (const PedDisk* disk);
> };
>
> struct _PedDiskType {
> @@ -322,7 +323,7 @@ extern PedPartition* ped_disk_extended_partition (const PedDisk* disk);
> /* internal functions */
> extern PedDisk* _ped_disk_alloc (const PedDevice* dev, const PedDiskType* type);
> extern void _ped_disk_free (PedDisk* disk);
> -
> +extern int ped_disk_get_max_partition_num(const PedDisk* disk);
>
> /** @} */
>
> diff --git a/libparted/arch/linux.c b/libparted/arch/linux.c
> index 4a8c9e7..35ef1a5 100644
> --- a/libparted/arch/linux.c
> +++ b/libparted/arch/linux.c
> @@ -279,6 +279,9 @@ struct blkdev_ioctl_param {
> || (M) == SCSI_CDROM_MAJOR \
> || ((M) >= SCSI_DISK1_MAJOR && (M) <= SCSI_DISK7_MAJOR))
>
> +/* Maximum number of partitions supported by linux. */
> +#define MAX_NUM_PARTS 16
I'd suggest to increase this to 64
> +
> static char* _device_get_part_path (PedDevice* dev, int num);
> static int _partition_is_mounted_by_path (const char* path);
>
> @@ -2261,45 +2264,91 @@ _blkpg_remove_partition (PedDisk* disk, int n)
> BLKPG_DEL_PARTITION);
> }
>
> +/*
> + * The number of partitions that a device can have depends on the kernel.
> + * If we don't find this value in /sys/block/DEV/range, we will use our own
> + * value.
> + */
> +static int
> +_device_get_partition_range(PedDevice* dev)
> +{
> + int range;
> + char path[512];
> + FILE* fd;
> +
> + if(snprintf(path, sizeof(path), "/sys/block/%s/range", dev->path) < 0)
> + return MAX_NUM_PARTS;
> +
> + fd = fopen(path, "r");
> + if(!fd)
> + return MAX_NUM_PARTS;
> +
> + if(fscanf(fd, "%d", range) == EOF)
> + return MAX_NUM_PARTS;
> +
> + return range;
> +}
> +
> +/*
> + * We sync the partition table in two step process:
> + * 1. We remove all the partitions from the kernel's tables. The partitions
> + * will not be removed if the ioctl call fails.
> + * 2. We add all the partitions that we hold in disk.
> + *
> + * To achieve this two step process we must calculate the minimum number of
> + * maximum possible partitions between what linux supports and what the label
> + * type supports. EX:
> + *
> + * number=MIN(max_parts_supported_in_linux,max_parts_supported_in_msdos_tables)
> + *
> + * For now we will hard code the maximum number of partitions for linux to 16.
s/16/MAX_NUM_PARTS
> + * Might want to search for a way to include this from somewhere.
> + */
> static int
> _disk_sync_part_table (PedDisk* disk)
> {
> - int largest_partnum = ped_disk_get_last_partition_num (disk);
> - if (largest_partnum <= 0)
> - return 1;
> + PED_ASSERT(disk != NULL, return 0);
> + PED_ASSERT(disk->dev != NULL, return 0);
>
> - int last = 16;
> - int* rets = ped_malloc(sizeof(int) * last);
> - int* errnums = ped_malloc(sizeof(int) * last);
> - int ret = 1;
> - int i;
> + /* lpn = largest partition number. */
> + int lpn = PED_MIN(_device_get_partition_range(disk->dev),
> + ped_disk_get_max_partition_num(disk));
>
> - for (i = 1; i <= last; i++) {
> - rets[i - 1] = _blkpg_remove_partition (disk, i);
> - errnums[i - 1] = errno;
> - }
> + /* Its not possible to support largets_partnum <= 0. */
s/largets/largest
> + if(lpn <= 0)
> + return 0;
>
> - for (i = 1; i <= last; i++) {
> - const PedPartition *part;
> + int* rets = ped_malloc(sizeof(int) * lpn);
> + int* errnums = ped_malloc(sizeof(int) * lpn);
> + int ret = 1;
> + int i;
>
> - part = ped_disk_get_partition (disk, i);
> - if (part) {
> - /* busy... so we won't (can't!) disturb ;) Prolly
> - * doesn't matter anyway, because users shouldn't be
> - * changing mounted partitions anyway...
> - */
> - if (!rets[i - 1] && errnums[i - 1] == EBUSY)
> - continue;
> -
> - /* add the (possibly modified or new) partition */
> - if (!_blkpg_add_partition (disk, part))
> - ret = 0;
> - }
> - }
> + for(i = 1; i <= lpn; i++) {
> + rets[i - 1] = _blkpg_remove_partition (disk, i);
> + errnums[i - 1] = errno;
> + }
> +
> + for(i = 1; i <= lpn; i++) {
> + const PedPartition *part;
> +
> + part = ped_disk_get_partition (disk, i);
> + if (part) {
> + /* busy... so we won't (can't!) disturb ;) Prolly
> + * doesn't matter anyway, because users shouldn't be
> + * changing mounted partitions anyway...
> + */
> + if (!rets[i - 1] && errnums[i - 1] == EBUSY)
> + continue;
> +
> + /* add the (possibly modified or new) partition */
> + if (!_blkpg_add_partition (disk, part))
> + ret = 0;
> + }
> + }
>
> - free (rets);
> - free (errnums);
> - return ret;
> + free (rets);
> + free (errnums);
> + return ret;
> }
>
> #ifdef ENABLE_DEVICE_MAPPER
> diff --git a/libparted/disk.c b/libparted/disk.c
> index 93929b2..f259a9a 100644
> --- a/libparted/disk.c
> +++ b/libparted/disk.c
> @@ -628,7 +628,7 @@ ped_disk_get_primary_partition_count (const PedDisk* disk)
> }
>
> /**
> - * Get the highest partition number on \p disk.
> + * Get the highest available partition number on \p disk.
> */
> int
> ped_disk_get_last_partition_num (const PedDisk* disk)
> @@ -648,6 +648,18 @@ ped_disk_get_last_partition_num (const PedDisk* disk)
> }
>
> /**
> + * Get the highest suppoerted partition number on \p disk.
s/suppoerted/supported
> + */
> +int
> +ped_disk_get_max_partition_num(const PedDisk* disk)
> +{
> + PED_ASSERT(disk != NULL, return 0);
> + PED_ASSERT(disk->type->ops->get_max_partition_count != NULL, return 0);
> +
> + return disk->type->ops->get_max_partition_count(disk);
> +}
> +
> +/**
> * Get the maximum number of (primary) partitions the disk label supports.
> *
> * For example, MacIntosh partition maps can have different sizes,
> diff --git a/libparted/labels/aix.c b/libparted/labels/aix.c
> index b3dd176..c5da1fd 100644
> --- a/libparted/labels/aix.c
> +++ b/libparted/labels/aix.c
> @@ -222,6 +222,12 @@ aix_get_max_primary_partition_count (const PedDisk* disk)
> }
>
> static int
> +aix_get_max_partitoin_count (const PedDisk* disk)
> +{
> + return 16;
> +}
> +
> +static int
> aix_partition_align (PedPartition* part, const PedConstraint* constraint)
> {
> PED_ASSERT (part != NULL, return 0);
> @@ -270,6 +276,8 @@ static PedDiskOps aix_disk_ops = {
> alloc_metadata: aix_alloc_metadata,
> get_max_primary_partition_count:
> aix_get_max_primary_partition_count,
> + get_max_partition_count:
> + aix_get_max_partitoin_count,
>
> partition_set_name: NULL,
> partition_get_name: NULL,
> diff --git a/libparted/labels/bsd.c b/libparted/labels/bsd.c
> index 3eb5363..a1c75b8 100644
> --- a/libparted/labels/bsd.c
> +++ b/libparted/labels/bsd.c
> @@ -656,6 +656,8 @@ static PedDiskOps bsd_disk_ops = {
>
> alloc_metadata: bsd_alloc_metadata,
> get_max_primary_partition_count:
> + bsd_get_max_primary_partition_count,
> + get_max_partition_count:
> bsd_get_max_primary_partition_count
> };
>
> diff --git a/libparted/labels/dasd.c b/libparted/labels/dasd.c
> index 9edab40..af35707 100644
> --- a/libparted/labels/dasd.c
> +++ b/libparted/labels/dasd.c
> @@ -128,6 +128,7 @@ static PedDiskOps dasd_disk_ops = {
>
> alloc_metadata: dasd_alloc_metadata,
> get_max_primary_partition_count: dasd_get_max_primary_partition_count,
> + get_max_partition_count: dasd_get_max_primary_partition_count,
>
> partition_duplicate: NULL
> };
> diff --git a/libparted/labels/dos.c b/libparted/labels/dos.c
> index cb7e45e..3193069 100644
> --- a/libparted/labels/dos.c
> +++ b/libparted/labels/dos.c
> @@ -2213,6 +2213,12 @@ msdos_get_max_primary_partition_count (const PedDisk* disk)
> return 4;
> }
>
> +static int
> +msdos_get_max_partition_count(const PedDisk* disk)
> +{
> + return 16;
> +}
> +
> static PedDiskOps msdos_disk_ops = {
> probe: msdos_probe,
> #ifndef DISCOVER_ONLY
> @@ -2244,7 +2250,9 @@ static PedDiskOps msdos_disk_ops = {
>
> alloc_metadata: msdos_alloc_metadata,
> get_max_primary_partition_count:
> - msdos_get_max_primary_partition_count
> + msdos_get_max_primary_partition_count,
> + get_max_partition_count:
> + msdos_get_max_partition_count
> };
>
> static PedDiskType msdos_disk_type = {
> diff --git a/libparted/labels/dvh.c b/libparted/labels/dvh.c
> index 8d8ba76..bdea1c7 100644
> --- a/libparted/labels/dvh.c
> +++ b/libparted/labels/dvh.c
> @@ -888,7 +888,8 @@ static PedDiskOps dvh_disk_ops = {
>
> alloc_metadata: dvh_alloc_metadata,
> get_max_primary_partition_count:
> - dvh_get_max_primary_partition_count
> + dvh_get_max_primary_partition_count,
> + get_max_partition_count: dvh_get_max_primary_partition_count
> };
>
> static PedDiskType dvh_disk_type = {
> diff --git a/libparted/labels/gpt.c b/libparted/labels/gpt.c
> index eea562d..6c9929b 100644
> --- a/libparted/labels/gpt.c
> +++ b/libparted/labels/gpt.c
> @@ -1470,6 +1470,12 @@ gpt_get_max_primary_partition_count (const PedDisk *disk)
> return gpt_disk_data->entry_count;
> }
>
> +static int
> +gpt_get_max_partitoin_count(const PedDisk *disk)
> +{
> + return 16;
> +}
> +
Are you sure about this? I think GPT has no such on the number of
partitions.
> static PedConstraint*
> _non_metadata_constraint (const PedDisk* disk)
> {
> @@ -1524,7 +1530,8 @@ static PedDiskOps gpt_disk_ops = {
> partition_align: gpt_partition_align,
> partition_enumerate: gpt_partition_enumerate,
> alloc_metadata: gpt_alloc_metadata,
> - get_max_primary_partition_count: gpt_get_max_primary_partition_count
> + get_max_primary_partition_count: gpt_get_max_primary_partition_count,
> + get_max_partition_count: gpt_get_max_partitoin_count
> };
>
> static PedDiskType gpt_disk_type = {
> diff --git a/libparted/labels/loop.c b/libparted/labels/loop.c
> index a6a2057..19181ee 100644
> --- a/libparted/labels/loop.c
> +++ b/libparted/labels/loop.c
> @@ -311,6 +311,8 @@ static PedDiskOps loop_disk_ops = {
>
> alloc_metadata: loop_alloc_metadata,
> get_max_primary_partition_count:
> + loop_get_max_primary_partition_count,
> + get_max_partition_count:
> loop_get_max_primary_partition_count
> };
>
> diff --git a/libparted/labels/mac.c b/libparted/labels/mac.c
> index 3ec8390..8f17e8a 100644
> --- a/libparted/labels/mac.c
> +++ b/libparted/labels/mac.c
> @@ -1563,6 +1563,12 @@ mac_get_max_primary_partition_count (const PedDisk* disk)
> - mac_disk_data->free_part_entry_count + 1;
> }
>
> +static int
> +mac_get_max_partitoin_count (const PedDisk* disk)
> +{
> + return 65536;
> +}
> +
> static PedDiskOps mac_disk_ops = {
> probe: mac_probe,
> #ifndef DISCOVER_ONLY
> @@ -1596,7 +1602,9 @@ static PedDiskOps mac_disk_ops = {
>
> alloc_metadata: mac_alloc_metadata,
> get_max_primary_partition_count:
> - mac_get_max_primary_partition_count
> + mac_get_max_primary_partition_count,
> + get_max_partition_count:
> + mac_get_max_partitoin_count
> };
>
> static PedDiskType mac_disk_type = {
> diff --git a/libparted/labels/pc98.c b/libparted/labels/pc98.c
> index a7b7e57..05e1e45 100644
> --- a/libparted/labels/pc98.c
> +++ b/libparted/labels/pc98.c
> @@ -863,6 +863,8 @@ static PedDiskOps pc98_disk_ops = {
>
> alloc_metadata: pc98_alloc_metadata,
> get_max_primary_partition_count:
> + pc98_get_max_primary_partition_count,
> + get_max_partition_count:
> pc98_get_max_primary_partition_count
> };
>
> diff --git a/libparted/labels/rdb.c b/libparted/labels/rdb.c
> index 386b2bd..093d48f 100644
> --- a/libparted/labels/rdb.c
> +++ b/libparted/labels/rdb.c
> @@ -1157,6 +1157,8 @@ static PedDiskOps amiga_disk_ops = {
>
> alloc_metadata: amiga_alloc_metadata,
> get_max_primary_partition_count:
> + amiga_get_max_primary_partition_count,
> + get_max_partition_count:
> amiga_get_max_primary_partition_count
> };
>
> diff --git a/libparted/labels/sun.c b/libparted/labels/sun.c
> index 76f2b78..befc2fc 100644
> --- a/libparted/labels/sun.c
> +++ b/libparted/labels/sun.c
> @@ -858,6 +858,8 @@ static PedDiskOps sun_disk_ops = {
> alloc_metadata: sun_alloc_metadata,
> get_max_primary_partition_count:
> sun_get_max_primary_partition_count,
> + get_max_partition_count:
> + sun_get_max_primary_partition_count,
>
> partition_set_name: NULL,
> partition_get_name: NULL,
> --
> 1.6.0.6
>
>
> _______________________________________________
> parted-devel mailing list
> parted-devel at lists.alioth.debian.org
> http://lists.alioth.debian.org/mailman/listinfo/parted-devel
--
Best regards / s pozdravem
Petr Uzel, Packages maintainer
---------------------------------------------------------------------
SUSE LINUX, s.r.o. e-mail: puzel at suse.cz
Lihovarská 1060/12 tel: +420 284 028 964
190 00 Prague 9 fax: +420 284 028 951
Czech Republic http://www.suse.cz
More information about the parted-devel
mailing list