[Parted-commits] GNU Parted Official Repository: Changes to 'master'

Jim Meyering meyering at alioth.debian.org
Thu Mar 5 15:04:29 UTC 2009


 include/parted/disk.h   |    5 +++
 libparted/arch/linux.c  |   79 ++++++++++++++++++++++++++++++++++++++++--------
 libparted/disk.c        |   17 +++++++++-
 libparted/labels/aix.c  |   13 +++++++
 libparted/labels/bsd.c  |   14 +++++++-
 libparted/labels/dasd.c |    9 +++++
 libparted/labels/dos.c  |   14 +++++++-
 libparted/labels/dvh.c  |   14 ++++++--
 libparted/labels/gpt.c  |   49 +++++++++++++++++++++++++++++
 libparted/labels/loop.c |   14 +++++++-
 libparted/labels/mac.c  |   14 +++++++-
 libparted/labels/pc98.c |   13 ++++++-
 libparted/labels/rdb.c  |   13 ++++++-
 libparted/labels/sun.c  |   11 ++++++
 14 files changed, 247 insertions(+), 32 deletions(-)

New commits:
commit 87ed16c5469a8a1af88414609215cbbf1a107965
Author: Jim Meyering <meyering at redhat.com>
Date:   Thu Mar 5 15:33:55 2009 +0100

    reword a comment; more formatting changes.
    
    * libparted/arch/linux.c (_disk_sync_part_table): Reword comment
    to use the "active" voice, not "we ...".
    Adjust formatting in new/moved code.

diff --git a/libparted/arch/linux.c b/libparted/arch/linux.c
index 6a90ee2..724df46 100644
--- a/libparted/arch/linux.c
+++ b/libparted/arch/linux.c
@@ -2294,10 +2294,10 @@ _device_get_partition_range(PedDevice* dev)
 }
 
 /*
- * 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.
+ * Sync the partition table in two step process:
+ * 1. Remove all of the partitions from the kernel's tables, but do not attempt
+ *    removal of any partition for which the corresponding ioctl call fails.
+ * 2. 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
@@ -2324,10 +2324,10 @@ _disk_sync_part_table (PedDisk* disk)
         if(lpn < 0)
                 return 0;
 
-        int*        rets = ped_malloc(sizeof(int) * lpn);
-        int*        errnums = ped_malloc(sizeof(int) * lpn);
-        int                 ret = 1;
-        int                 i;
+        int *rets = ped_malloc(sizeof(int) * lpn);
+        int *errnums = ped_malloc(sizeof(int) * lpn);
+        int ret = 1;
+        int i;
 
         for (i = 1; i <= lpn; i++) {
                 rets[i - 1] = _blkpg_remove_partition (disk, i);
@@ -2335,9 +2335,7 @@ _disk_sync_part_table (PedDisk* disk)
         }
 
         for (i = 1; i <= lpn; i++) {
-                const PedPartition *part;
-
-                part = ped_disk_get_partition (disk, i);
+                const PedPartition *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

commit a702d42f173c401510b7c1a65e8e2889c7e4894e
Author: Jim Meyering <meyering at redhat.com>
Date:   Thu Mar 5 11:42:45 2009 +0100

    rename all "support" parameters; avoid new compiler warnings
    
    Change each occurrence like this (which evokes a warning from gcc):
    -	return *supported = MAX_TOTAL_PART;
    to this:
    +	*max_n = MAX_TOTAL_PART;
    +	return true;
    
    I did it mostly mechanically:
    
      cd libparted/labels &&
        grep -l 'return .supported = ' *.c|xargs perl -ni \
          -e '$m=/^\treturn \*supported( = .*;)/;' \
          -e 'print $m ? "\t*max_n$1\n\treturn true;\n" : $_'
      git grep -l 'int\* supported'|xargs perl -pi -e 's/int\* supported/int *max_n/'
    
    That got all but aix.c, which used different spacing: "int *supported",
    which I changed manually.  Then I updated all copyright dates.

diff --git a/libparted/labels/aix.c b/libparted/labels/aix.c
index 2d8a40c..465cb6c 100644
--- a/libparted/labels/aix.c
+++ b/libparted/labels/aix.c
@@ -1,7 +1,7 @@
 /* -*- Mode: c; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
 
     libparted - a library for manipulating disk partitions
-    Copyright (C) 2000, 2001, 2007 Free Software Foundation, Inc.
+    Copyright (C) 2000, 2001, 2007, 2009 Free Software Foundation, Inc.
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -224,9 +224,10 @@ aix_get_max_primary_partition_count (const PedDisk* disk)
 }
 
 static bool
-aix_get_max_supported_partition_count (const PedDisk* disk, int *supported)
+aix_get_max_supported_partition_count (const PedDisk* disk, int *max_n)
 {
-	return *supported = MAX_TOTAL_PART;
+	*max_n = MAX_TOTAL_PART;
+	return true;
 }
 
 static int
diff --git a/libparted/labels/bsd.c b/libparted/labels/bsd.c
index 55af468..83e1709 100644
--- a/libparted/labels/bsd.c
+++ b/libparted/labels/bsd.c
@@ -1,7 +1,7 @@
 /* -*- Mode: c; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
 
     libparted - a library for manipulating disk partitions
-    Copyright (C) 2000, 2001, 2007 Free Software Foundation, Inc.
+    Copyright (C) 2000, 2001, 2007, 2009 Free Software Foundation, Inc.
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -549,9 +549,10 @@ bsd_get_max_primary_partition_count (const PedDisk* disk)
 }
 
 static bool
-bsd_get_max_supported_partition_count(const PedDisk* disk, int* supported)
+bsd_get_max_supported_partition_count(const PedDisk* disk, int *max_n)
 {
-	return *supported = BSD_MAXPARTITIONS;
+	*max_n = BSD_MAXPARTITIONS;
+	return true;
 }
 
 static PedConstraint*
diff --git a/libparted/labels/dasd.c b/libparted/labels/dasd.c
index 35cfbb3..3a0bb32 100644
--- a/libparted/labels/dasd.c
+++ b/libparted/labels/dasd.c
@@ -716,9 +716,10 @@ dasd_get_max_primary_partition_count (const PedDisk* disk)
 }
 
 static bool
-dasd_get_max_supported_partition_count (const PedDisk* disk, int* supported)
+dasd_get_max_supported_partition_count (const PedDisk* disk, int *max_n)
 {
-	return *supported = dasd_get_max_primary_partition_count(disk);
+	*max_n = dasd_get_max_primary_partition_count(disk);
+	return true;
 }
 
 static PedConstraint*
diff --git a/libparted/labels/dos.c b/libparted/labels/dos.c
index 92b728d..a0044b7 100644
--- a/libparted/labels/dos.c
+++ b/libparted/labels/dos.c
@@ -1,6 +1,6 @@
 /*
     libparted - a library for manipulating disk partitions
-    Copyright (C) 1999, 2000, 2001, 2004, 2005, 2007
+    Copyright (C) 1999, 2000, 2001, 2004, 2005, 2007, 2009
     Free Software Foundation, Inc.
 
     This program is free software; you can redistribute it and/or modify
@@ -2215,9 +2215,10 @@ msdos_get_max_primary_partition_count (const PedDisk* disk)
 }
 
 static bool
-msdos_get_max_supported_partition_count(const PedDisk* disk, int* supported)
+msdos_get_max_supported_partition_count(const PedDisk* disk, int *max_n)
 {
-	return *supported = MAX_TOTAL_PART;
+	*max_n = MAX_TOTAL_PART;
+	return true;
 }
 
 static PedDiskOps msdos_disk_ops = {
diff --git a/libparted/labels/dvh.c b/libparted/labels/dvh.c
index 3814824..38b7569 100644
--- a/libparted/labels/dvh.c
+++ b/libparted/labels/dvh.c
@@ -1,6 +1,6 @@
 /*
     libparted - a library for manipulating disk partitions
-    Copyright (C) 2001, 2002, 2005, 2007-2008 Free Software Foundation, Inc.
+    Copyright (C) 2001, 2002, 2005, 2007-2009 Free Software Foundation, Inc.
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -823,9 +823,10 @@ dvh_get_max_primary_partition_count (const PedDisk* disk)
 }
 
 static bool
-dvh_get_max_supported_partition_count (const PedDisk* disk, int* supported)
+dvh_get_max_supported_partition_count (const PedDisk* disk, int *max_n)
 {
-	return *supported = NPARTAB;
+	*max_n = NPARTAB;
+	return true;
 }
 
 
diff --git a/libparted/labels/loop.c b/libparted/labels/loop.c
index 23e0d3c..c89a9ce 100644
--- a/libparted/labels/loop.c
+++ b/libparted/labels/loop.c
@@ -1,6 +1,6 @@
 /*
     libparted - a library for manipulating disk partitions
-    Copyright (C) 1999, 2000, 2007 Free Software Foundation, Inc.
+    Copyright (C) 1999, 2000, 2007, 2009 Free Software Foundation, Inc.
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -282,9 +282,10 @@ loop_get_max_primary_partition_count (const PedDisk* disk)
 }
 
 static bool
-loop_get_max_supported_partition_count (const PedDisk* disk, int* supported)
+loop_get_max_supported_partition_count (const PedDisk* disk, int *max_n)
 {
-	return *supported = 1;
+	*max_n = 1;
+	return true;
 }
 
 static PedDiskOps loop_disk_ops = {
diff --git a/libparted/labels/mac.c b/libparted/labels/mac.c
index db22aa8..e89dc20 100644
--- a/libparted/labels/mac.c
+++ b/libparted/labels/mac.c
@@ -1,6 +1,6 @@
 /*
     libparted - a library for manipulating disk partitions
-    Copyright (C) 2000, 2002, 2004, 2007-2008 Free Software Foundation, Inc.
+    Copyright (C) 2000, 2002, 2004, 2007-2009 Free Software Foundation, Inc.
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -1565,9 +1565,10 @@ mac_get_max_primary_partition_count (const PedDisk* disk)
 }
 
 static bool
-mac_get_max_supported_partition_count (const PedDisk* disk, int* supported)
+mac_get_max_supported_partition_count (const PedDisk* disk, int *max_n)
 {
-	return *supported = 65536;
+	*max_n = 65536;
+	return true;
 }
 
 static PedDiskOps mac_disk_ops = {
diff --git a/libparted/labels/pc98.c b/libparted/labels/pc98.c
index ff21750..3ab7b03 100644
--- a/libparted/labels/pc98.c
+++ b/libparted/labels/pc98.c
@@ -1,6 +1,6 @@
 /*
     libparted - a library for manipulating disk partitions
-    Copyright (C) 2000, 2001, 2007-2008 Free Software Foundation, Inc.
+    Copyright (C) 2000, 2001, 2007-2009 Free Software Foundation, Inc.
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -833,9 +833,10 @@ pc98_get_max_primary_partition_count (const PedDisk* disk)
 }
 
 static bool
-pc98_get_max_supported_partition_count (const PedDisk* disk, int* supported)
+pc98_get_max_supported_partition_count (const PedDisk* disk, int *max_n)
 {
-	return *supported = MAX_PART_COUNT;
+	*max_n = MAX_PART_COUNT;
+	return true;
 }
 
 static PedDiskOps pc98_disk_ops = {
diff --git a/libparted/labels/rdb.c b/libparted/labels/rdb.c
index 43496dc..90acc2b 100644
--- a/libparted/labels/rdb.c
+++ b/libparted/labels/rdb.c
@@ -2,7 +2,7 @@
 
     libparted - a library for manipulating disk partitions
     disk_amiga.c - libparted module to manipulate amiga RDB partition tables.
-    Copyright (C) 2000, 2001, 2004, 2007-2008 Free Software Foundation, Inc.
+    Copyright (C) 2000, 2001, 2004, 2007-2009 Free Software Foundation, Inc.
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -1125,9 +1125,10 @@ amiga_get_max_primary_partition_count (const PedDisk* disk)
 }
 
 static bool
-amiga_get_max_supported_partition_count (const PedDisk* disk, int* supported)
+amiga_get_max_supported_partition_count (const PedDisk* disk, int *max_n)
 {
-	return *supported = AMIGA_MAX_PARTITIONS;
+	*max_n = AMIGA_MAX_PARTITIONS;
+	return true;
 }
 
 static PedDiskOps amiga_disk_ops = {
diff --git a/libparted/labels/sun.c b/libparted/labels/sun.c
index 7c43240..389db47 100644
--- a/libparted/labels/sun.c
+++ b/libparted/labels/sun.c
@@ -1,7 +1,7 @@
 /* -*- Mode: c; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
 
     libparted - a library for manipulating disk partitions
-    Copyright (C) 2000, 2001, 2005, 2007-2008 Free Software Foundation, Inc.
+    Copyright (C) 2000, 2001, 2005, 2007-2009 Free Software Foundation, Inc.
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -665,9 +665,10 @@ sun_partition_is_flag_available (const PedPartition* part,
 }
 
 static bool
-sun_get_max_supported_partition_count (const PedDisk* disk, int* supported)
+sun_get_max_supported_partition_count (const PedDisk* disk, int *max_n)
 {
-	return *supported = SUN_DISK_MAXPARTITIONS;
+	*max_n = SUN_DISK_MAXPARTITIONS;
+	return true;
 }
 
 static int

commit 45668ed23c6712533e2f96603db49eb1280a2f1a
Author: Jim Meyering <meyering at redhat.com>
Date:   Thu Mar 5 11:03:45 2009 +0100

    gpt: adjust formatting and rename a parameter: s/supported/max_n/.
    
    * libparted/labels/gpt.c (gpt_get_max_supported_partition_count): Rename
    parameter: s/supported/max_n/.  The latter sounds more like a number,
    while "supported" sounds boolean at first.

diff --git a/libparted/labels/gpt.c b/libparted/labels/gpt.c
index aeaee8a..be8f264 100644
--- a/libparted/labels/gpt.c
+++ b/libparted/labels/gpt.c
@@ -1501,24 +1501,24 @@ gpt_get_max_primary_partition_count (const PedDisk *disk)
  * SP = Blocksize(FirstusableLBA - 2) / SizeOfPartitoinEntry
  */
 static bool
-gpt_get_max_supported_partition_count (const PedDisk *disk, int *supported)
+gpt_get_max_supported_partition_count (const PedDisk *disk, int *max_n)
 {
 	GuidPartitionTableHeader_t *pth = NULL;
-	uint8_t *pth_raw = ped_malloc (pth_get_size(disk->dev));
-
-	if(ped_device_read(disk->dev, pth_raw, 1, GPT_HEADER_SECTORS) ||
-			ped_device_read(disk->dev, pth_raw, disk->dev->length, GPT_HEADER_SECTORS))
-		pth = pth_new_from_raw(disk->dev, pth_raw);
-	free(pth_raw);
-
-	if(pth){
-		*supported = (disk->dev->sector_size*(pth->FirstUsableLBA - 2) /
-				pth->SizeOfPartitionEntry);
-		pth_free(pth);
-		return true;
-	}
+	uint8_t *pth_raw = ped_malloc (pth_get_size (disk->dev));
+
+	if (ped_device_read (disk->dev, pth_raw, 1, GPT_HEADER_SECTORS)
+	    || ped_device_read (disk->dev, pth_raw,
+				disk->dev->length, GPT_HEADER_SECTORS))
+		pth = pth_new_from_raw (disk->dev, pth_raw);
+	free (pth_raw);
+
+	if (pth == NULL)
+		return false;
 
-	return false;
+	*max_n = (disk->dev->sector_size * (pth->FirstUsableLBA - 2)
+		  / pth->SizeOfPartitionEntry);
+	pth_free (pth);
+	return true;
 }
 
 static PedConstraint*

commit 18710c49b6b375f77f263ad3afcb1bcef2d1f3e4
Author: Joel Granados Moreno <jgranado at redhat.com>
Date:   Thu Mar 5 10:44:48 2009 +0100

    Properly sync partitions with operating system
    
    * include/parted/disk.h: Add prototypes for new function.
    * libparted/disk.c (ped_disk_get_max_supported_partition_count): New
    function that calls the partition-table-specific function.
    * libparted/arch/linux.c (_disk_sync_part_table): To sync the table in
    disk with the kernel, we remove all partitions from the kernel table
    and then add the ones that are in disk.  For this to happen we need to
    calculate the partition-table-type-specific maximum number of
    supported partitions.
    * libparted/labels/gpt.c (gpt_get_max_supported_partition_count):
    Read the gpt header from disk and calculate the maximum number of
    partitions it can accommodate.
    * libparted/labels/aix.c (get_max_supported_partition_count):
    New function.
    * libparted/labels/bsd.c: Likewise.
    * libparted/labels/dasd.c: Likewise.
    * libparted/labels/dos.c: Likewise.
    * libparted/labels/dvh.c: Likewise.
    * libparted/labels/gpt.c: Likewise.
    * libparted/labels/loop.c: Likewise.
    * libparted/labels/mac.c: Likewise.
    * libparted/labels/pc98.c: Likewise.
    * libparted/labels/rdb.c: Likewise.
    * libparted/labels/sun.c: Likewise.

diff --git a/include/parted/disk.h b/include/parted/disk.h
index dfcf39e..ec6044d 100644
--- a/include/parted/disk.h
+++ b/include/parted/disk.h
@@ -84,6 +84,7 @@ typedef const struct _PedDiskArchOps    PedDiskArchOps;
 #include <parted/filesys.h>
 #include <parted/natmath.h>
 #include <parted/geom.h>
+#include <stdbool.h>
 
 /** @} */
 
@@ -210,6 +211,8 @@ struct _PedDiskOps {
         /* other */
         int (*alloc_metadata) (PedDisk* disk);
         int (*get_max_primary_partition_count) (const PedDisk* disk);
+        bool (*get_max_supported_partition_count) (const PedDisk* disk,
+                                                   int* supported);
 };
 
 struct _PedDiskType {
@@ -257,6 +260,8 @@ extern void ped_disk_print (const PedDisk* disk);
 extern int ped_disk_get_primary_partition_count (const PedDisk* disk);
 extern int ped_disk_get_last_partition_num (const PedDisk* disk);
 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);
 
 /** @} */
 
diff --git a/libparted/arch/linux.c b/libparted/arch/linux.c
index 4a8c9e7..6a90ee2 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		64
+
 static char* _device_get_part_path (PedDevice* dev, int num);
 static int _partition_is_mounted_by_path (const char* path);
 
@@ -2261,25 +2264,77 @@ _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 unsigned int
+_device_get_partition_range(PedDevice* dev)
+{
+        int         range, r;
+        char        path[128];
+        FILE*       fp;
+        bool        ok;
+
+        r = snprintf(path, sizeof(path), "/sys/block/%s/range",
+                        basename(dev->path));
+        if(r < 0 || r > sizeof(path))
+                return MAX_NUM_PARTS;
+
+        fp = fopen(path, "r");
+        if(!fp)
+                return MAX_NUM_PARTS;
+
+        ok = fscanf(fp, "%d", &range) == 1;
+        fclose(fp);
+
+        /* (range <= 0) is none sense.*/
+        return ok && range > 0 ? range : MAX_NUM_PARTS;
+}
+
+/*
+ * 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)
+ */
 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 lpn;
 
-        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. */
+        if(ped_disk_get_max_supported_partition_count(disk, &lpn))
+                lpn = PED_MIN(lpn, _device_get_partition_range(disk->dev));
+        else
+                lpn = _device_get_partition_range(disk->dev);
 
-        for (i = 1; i <= last; i++) {
+        /* Its not possible to support largest_partnum < 0.
+         * largest_partnum == 0 would mean does not support partitions.
+         * */
+        if(lpn < 0)
+                return 0;
+
+        int*        rets = ped_malloc(sizeof(int) * lpn);
+        int*        errnums = ped_malloc(sizeof(int) * lpn);
+        int                 ret = 1;
+        int                 i;
+
+        for (i = 1; i <= lpn; i++) {
                 rets[i - 1] = _blkpg_remove_partition (disk, i);
                 errnums[i - 1] = errno;
         }
 
-        for (i = 1; i <= last; i++) {
+        for (i = 1; i <= lpn; i++) {
                 const PedPartition *part;
 
                 part = ped_disk_get_partition (disk, i);
diff --git a/libparted/disk.c b/libparted/disk.c
index 93929b2..4003618 100644
--- a/libparted/disk.c
+++ b/libparted/disk.c
@@ -36,6 +36,7 @@
 
 #include <parted/parted.h>
 #include <parted/debug.h>
+#include <stdbool.h>
 
 #include "architecture.h"
 #include "intprops.h"
@@ -628,7 +629,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 +649,20 @@ ped_disk_get_last_partition_num (const PedDisk* disk)
 }
 
 /**
+ * Get the highest supported partition number on \p disk.
+ *
+ * \return 0 if call fails. 1 otherwise.
+ */
+bool
+ped_disk_get_max_supported_partition_count(const PedDisk* disk, int* supported)
+{
+	PED_ASSERT(disk != NULL, return -1);
+	PED_ASSERT(disk->type->ops->get_max_supported_partition_count != NULL, return -1);
+
+	return disk->type->ops->get_max_supported_partition_count(disk, supported);
+}
+
+/**
  * 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..2d8a40c 100644
--- a/libparted/labels/aix.c
+++ b/libparted/labels/aix.c
@@ -24,6 +24,7 @@
 #include <parted/parted.h>
 #include <parted/debug.h>
 #include <parted/endian.h>
+#include <stdbool.h>
 
 #if ENABLE_NLS
 #  include <libintl.h>
@@ -33,6 +34,7 @@
 #endif /* ENABLE_NLS */
 
 #define	AIX_LABEL_MAGIC		0xc9c2d4c1
+#define	MAX_TOTAL_PART		16
 
 static PedDiskType aix_disk_type;
 
@@ -221,6 +223,12 @@ aix_get_max_primary_partition_count (const PedDisk* disk)
 	return 4;
 }
 
+static bool
+aix_get_max_supported_partition_count (const PedDisk* disk, int *supported)
+{
+	return *supported = MAX_TOTAL_PART;
+}
+
 static int
 aix_partition_align (PedPartition* part, const PedConstraint* constraint)
 {
@@ -270,6 +278,8 @@ static PedDiskOps aix_disk_ops = {
 	alloc_metadata:		aix_alloc_metadata,
 	get_max_primary_partition_count:
 				aix_get_max_primary_partition_count,
+	get_max_supported_partition_count:
+				aix_get_max_supported_partition_count,
 
 	partition_set_name:		NULL,
 	partition_get_name:		NULL,
diff --git a/libparted/labels/bsd.c b/libparted/labels/bsd.c
index 3eb5363..55af468 100644
--- a/libparted/labels/bsd.c
+++ b/libparted/labels/bsd.c
@@ -24,6 +24,7 @@
 #include <parted/parted.h>
 #include <parted/debug.h>
 #include <parted/endian.h>
+#include <stdbool.h>
 
 #if ENABLE_NLS
 #  include <libintl.h>
@@ -547,6 +548,12 @@ bsd_get_max_primary_partition_count (const PedDisk* disk)
 	return BSD_MAXPARTITIONS;
 }
 
+static bool
+bsd_get_max_supported_partition_count(const PedDisk* disk, int* supported)
+{
+	return *supported = BSD_MAXPARTITIONS;
+}
+
 static PedConstraint*
 _get_constraint (const PedDevice* dev)
 {
@@ -656,7 +663,9 @@ static PedDiskOps bsd_disk_ops = {
 
 	alloc_metadata:		bsd_alloc_metadata,
 	get_max_primary_partition_count:
-				bsd_get_max_primary_partition_count
+				bsd_get_max_primary_partition_count,
+	get_max_supported_partition_count:
+				bsd_get_max_supported_partition_count
 };
 
 static PedDiskType bsd_disk_type = {
diff --git a/libparted/labels/dasd.c b/libparted/labels/dasd.c
index b1cd937..35cfbb3 100644
--- a/libparted/labels/dasd.c
+++ b/libparted/labels/dasd.c
@@ -28,6 +28,7 @@
 #include <time.h>
 #include <fcntl.h>
 #include <unistd.h>
+#include <stdbool.h>
 
 #include <sys/stat.h>
 #include <sys/ioctl.h>
@@ -128,6 +129,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,
 
 	partition_duplicate: NULL
 };
@@ -713,6 +715,12 @@ dasd_get_max_primary_partition_count (const PedDisk* disk)
 	return USABLE_PARTITIONS;
 }
 
+static bool
+dasd_get_max_supported_partition_count (const PedDisk* disk, int* supported)
+{
+	return *supported = dasd_get_max_primary_partition_count(disk);
+}
+
 static PedConstraint*
 _primary_constraint (PedDisk* disk)
 {
diff --git a/libparted/labels/dos.c b/libparted/labels/dos.c
index cb7e45e..92b728d 100644
--- a/libparted/labels/dos.c
+++ b/libparted/labels/dos.c
@@ -97,6 +97,7 @@ static const char MBR_BOOT_CODE[] = {
  * (i.e. 1022 is sometimes used to indicate "use LBA").
  */
 #define MAX_CHS_CYLINDER	1021
+#define MAX_TOTAL_PART		16
 
 typedef struct _DosRawPartition		DosRawPartition;
 typedef struct _DosRawTable		DosRawTable;
@@ -2213,6 +2214,12 @@ msdos_get_max_primary_partition_count (const PedDisk* disk)
 	return 4;
 }
 
+static bool
+msdos_get_max_supported_partition_count(const PedDisk* disk, int* supported)
+{
+	return *supported = MAX_TOTAL_PART;
+}
+
 static PedDiskOps msdos_disk_ops = {
 	probe:			msdos_probe,
 #ifndef DISCOVER_ONLY
@@ -2244,7 +2251,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_supported_partition_count:
+				msdos_get_max_supported_partition_count
 };
 
 static PedDiskType msdos_disk_type = {
diff --git a/libparted/labels/dvh.c b/libparted/labels/dvh.c
index 8d8ba76..3814824 100644
--- a/libparted/labels/dvh.c
+++ b/libparted/labels/dvh.c
@@ -822,6 +822,13 @@ dvh_get_max_primary_partition_count (const PedDisk* disk)
 	return NPARTAB;
 }
 
+static bool
+dvh_get_max_supported_partition_count (const PedDisk* disk, int* supported)
+{
+	return *supported = NPARTAB;
+}
+
+
 static int
 dvh_alloc_metadata (PedDisk* disk)
 {
@@ -887,8 +894,8 @@ static PedDiskOps dvh_disk_ops = {
 	partition_enumerate:	dvh_partition_enumerate,
 
 	alloc_metadata:		dvh_alloc_metadata,
-	get_max_primary_partition_count:
-				dvh_get_max_primary_partition_count
+	get_max_primary_partition_count: dvh_get_max_primary_partition_count,
+	get_max_supported_partition_count: dvh_get_max_supported_partition_count
 };
 
 static PedDiskType dvh_disk_type = {
diff --git a/libparted/labels/gpt.c b/libparted/labels/gpt.c
index 90e5068..aeaee8a 100644
--- a/libparted/labels/gpt.c
+++ b/libparted/labels/gpt.c
@@ -1475,6 +1475,52 @@ gpt_get_max_primary_partition_count (const PedDisk *disk)
 	return gpt_disk_data->entry_count;
 }
 
+/*
+ * From (http://developer.apple.com/technotes/tn2006/tn2166.html Chapter 5).
+ * According to the specs the first LBA (LBA0) is not relevant (it exists
+ * to maintain compatibility).  on the second LBA(LBA1) gpt places the
+ * header.  The header is as big as the block size.  After the header we
+ * find the Entry array.  Each element of said array, describes each
+ * partition.  One can have as much elements as can fit between the end of
+ * the second LBA (where the header ends) and the FirstUsableLBA.
+ * FirstUsableLBA is the first logical block that is used for contents
+ * and is defined in header.
+ *
+ * /---------------------------------------------------\
+ * | BLOCK0 | HEADER | Entry Array | First Usable LBA  |
+ * |        | BLOCK1 |             |                   |
+ * \---------------------------------------------------/
+ *                  /              \
+ *     /----------/                  \----------\
+ *     /-----------------------------------------\
+ *     |  E1  |  E2  |  E3  |...............| EN |
+ *     \-----------------------------------------/
+ *
+ * The number of possible partitions or supported partitions is:
+ * SP = FirstUsableLBA*Blocksize - 2*Blocksize / SizeOfPartitionEntry
+ * SP = Blocksize(FirstusableLBA - 2) / SizeOfPartitoinEntry
+ */
+static bool
+gpt_get_max_supported_partition_count (const PedDisk *disk, int *supported)
+{
+	GuidPartitionTableHeader_t *pth = NULL;
+	uint8_t *pth_raw = ped_malloc (pth_get_size(disk->dev));
+
+	if(ped_device_read(disk->dev, pth_raw, 1, GPT_HEADER_SECTORS) ||
+			ped_device_read(disk->dev, pth_raw, disk->dev->length, GPT_HEADER_SECTORS))
+		pth = pth_new_from_raw(disk->dev, pth_raw);
+	free(pth_raw);
+
+	if(pth){
+		*supported = (disk->dev->sector_size*(pth->FirstUsableLBA - 2) /
+				pth->SizeOfPartitionEntry);
+		pth_free(pth);
+		return true;
+	}
+
+	return false;
+}
+
 static PedConstraint*
 _non_metadata_constraint (const PedDisk* disk)
 {
@@ -1529,7 +1575,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_supported_partition_count: gpt_get_max_supported_partition_count
 };
 
 static PedDiskType gpt_disk_type = {
diff --git a/libparted/labels/loop.c b/libparted/labels/loop.c
index a6a2057..23e0d3c 100644
--- a/libparted/labels/loop.c
+++ b/libparted/labels/loop.c
@@ -21,6 +21,7 @@
 #include <parted/parted.h>
 #include <parted/debug.h>
 #include <parted/endian.h>
+#include <stdbool.h>
 
 #if ENABLE_NLS
 #  include <libintl.h>
@@ -280,6 +281,12 @@ loop_get_max_primary_partition_count (const PedDisk* disk)
 	return 1;
 }
 
+static bool
+loop_get_max_supported_partition_count (const PedDisk* disk, int* supported)
+{
+	return *supported = 1;
+}
+
 static PedDiskOps loop_disk_ops = {
 	probe:			loop_probe,
 #ifndef DISCOVER_ONLY
@@ -311,7 +318,9 @@ static PedDiskOps loop_disk_ops = {
 
 	alloc_metadata:		loop_alloc_metadata,
 	get_max_primary_partition_count:
-				loop_get_max_primary_partition_count
+				loop_get_max_primary_partition_count,
+	get_max_supported_partition_count:
+				loop_get_max_supported_partition_count
 };
 
 static PedDiskType loop_disk_type = {
diff --git a/libparted/labels/mac.c b/libparted/labels/mac.c
index 3ec8390..db22aa8 100644
--- a/libparted/labels/mac.c
+++ b/libparted/labels/mac.c
@@ -21,6 +21,7 @@
 #include <parted/parted.h>
 #include <parted/debug.h>
 #include <parted/endian.h>
+#include <stdbool.h>
 
 #if ENABLE_NLS
 #  include <libintl.h>
@@ -1563,6 +1564,12 @@ mac_get_max_primary_partition_count (const PedDisk* disk)
 		- mac_disk_data->free_part_entry_count + 1;
 }
 
+static bool
+mac_get_max_supported_partition_count (const PedDisk* disk, int* supported)
+{
+	return *supported = 65536;
+}
+
 static PedDiskOps mac_disk_ops = {
 	probe:			mac_probe,
 #ifndef DISCOVER_ONLY
@@ -1596,7 +1603,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_supported_partition_count:
+				mac_get_max_supported_partition_count
 };
 
 static PedDiskType mac_disk_type = {
diff --git a/libparted/labels/pc98.c b/libparted/labels/pc98.c
index a7b7e57..ff21750 100644
--- a/libparted/labels/pc98.c
+++ b/libparted/labels/pc98.c
@@ -832,6 +832,12 @@ pc98_get_max_primary_partition_count (const PedDisk* disk)
 	return MAX_PART_COUNT;
 }
 
+static bool
+pc98_get_max_supported_partition_count (const PedDisk* disk, int* supported)
+{
+	return *supported = MAX_PART_COUNT;
+}
+
 static PedDiskOps pc98_disk_ops = {
 	probe:			pc98_probe,
 #ifndef DISCOVER_ONLY
@@ -863,7 +869,9 @@ static PedDiskOps pc98_disk_ops = {
 
 	alloc_metadata:		pc98_alloc_metadata,
 	get_max_primary_partition_count:
-				pc98_get_max_primary_partition_count
+				pc98_get_max_primary_partition_count,
+	get_max_supported_partition_count:
+				pc98_get_max_supported_partition_count
 };
 
 static PedDiskType pc98_disk_type = {
diff --git a/libparted/labels/rdb.c b/libparted/labels/rdb.c
index 386b2bd..43496dc 100644
--- a/libparted/labels/rdb.c
+++ b/libparted/labels/rdb.c
@@ -1124,6 +1124,12 @@ amiga_get_max_primary_partition_count (const PedDisk* disk)
 	return AMIGA_MAX_PARTITIONS;
 }
 
+static bool
+amiga_get_max_supported_partition_count (const PedDisk* disk, int* supported)
+{
+	return *supported = AMIGA_MAX_PARTITIONS;
+}
+
 static PedDiskOps amiga_disk_ops = {
 	probe:			amiga_probe,
 #ifndef DISCOVER_ONLY
@@ -1157,7 +1163,9 @@ static PedDiskOps amiga_disk_ops = {
 
 	alloc_metadata:		amiga_alloc_metadata,
 	get_max_primary_partition_count:
-				amiga_get_max_primary_partition_count
+				amiga_get_max_primary_partition_count,
+	get_max_supported_partition_count:
+				amiga_get_max_supported_partition_count
 };
 
 static PedDiskType amiga_disk_type = {
diff --git a/libparted/labels/sun.c b/libparted/labels/sun.c
index 76f2b78..7c43240 100644
--- a/libparted/labels/sun.c
+++ b/libparted/labels/sun.c
@@ -24,6 +24,7 @@
 #include <parted/parted.h>
 #include <parted/debug.h>
 #include <parted/endian.h>
+#include <stdbool.h>
 
 #if ENABLE_NLS
 #  include <libintl.h>
@@ -663,6 +664,11 @@ sun_partition_is_flag_available (const PedPartition* part,
 	}
 }
 
+static bool
+sun_get_max_supported_partition_count (const PedDisk* disk, int* supported)
+{
+	return *supported = SUN_DISK_MAXPARTITIONS;
+}
 
 static int
 sun_get_max_primary_partition_count (const PedDisk* disk)
@@ -858,6 +864,8 @@ static PedDiskOps sun_disk_ops = {
 	alloc_metadata:		sun_alloc_metadata,
 	get_max_primary_partition_count:
 				sun_get_max_primary_partition_count,
+	get_max_supported_partition_count:
+				sun_get_max_supported_partition_count,
 
 	partition_set_name:		NULL,
 	partition_get_name:		NULL,



More information about the Parted-commits mailing list