]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libfdisk: split label and label operations
authorKarel Zak <kzak@redhat.com>
Tue, 11 Dec 2012 11:56:27 +0000 (12:56 +0100)
committerKarel Zak <kzak@redhat.com>
Mon, 11 Mar 2013 11:47:29 +0000 (12:47 +0100)
 Changes:

 - fdisk_label is a private label driver struct
 - generic header of the fdisk_label points to fdisk_label_operations
 - the private fdisk_label stuff is always allocated for all drivers
   during fdisk_context initialization

 - context->labels[] contains pointers to all supported labels (drivers)
 - context->label is a pointer to the currently used label

 This change allows to:

 - store label specific global settings (e.g. dos compatible mode,
   display units, ...) independently on the current label

 - add label specific function to the API

Signed-off-by: Karel Zak <kzak@redhat.com>
12 files changed:
fdisks/fdiskaixlabel.c
fdisks/fdiskbsdlabel.c
fdisks/fdiskdoslabel.c
fdisks/fdiskmaclabel.c
fdisks/fdisksgilabel.c
fdisks/fdisksunlabel.c
fdisks/gpt.c
libfdisk/src/alignment.c
libfdisk/src/context.c
libfdisk/src/fdiskP.h
libfdisk/src/label.c
libfdisk/src/libfdisk.h

index d836363c9a348108683b43bfb2499b3f5285df58..d5872243be236b0975a8a3e277665b42f9030f5b 100644 (file)
 static int     other_endian = 0;
 static  short  volumes=1;
 
+/*
+ * in-memory fdisk AIX stuff
+ */
+struct fdisk_aix_label {
+       struct fdisk_label      head;           /* generic part */
+};
+
+
 /*
  * only dealing with free blocks here
  */
@@ -80,13 +88,31 @@ static int aix_add_partition(
        return -ENOSYS;
 }
 
-const struct fdisk_label aix_label =
+static const struct fdisk_label_operations aix_operations =
 {
-       .name = "aix",
-       .probe = aix_probe_label,
-       .write = NULL,
-       .verify = NULL,
-       .create = NULL,
-       .part_add = aix_add_partition,
-       .part_delete = NULL,
+       .probe          = aix_probe_label,
+       .part_add       = aix_add_partition
 };
+
+
+/*
+ * allocates AIX label driver
+ */
+struct fdisk_label *fdisk_new_aix_label(struct fdisk_context *cxt)
+{
+       struct fdisk_label *lb;
+       struct fdisk_aix_label *aix;
+
+       assert(cxt);
+
+       aix = calloc(1, sizeof(*aix));
+       if (!aix)
+               return NULL;
+
+       /* initialize generic part of the driver */
+       lb = (struct fdisk_label *) aix;
+       lb->name = "aix";
+       lb->op = &aix_operations;
+
+       return lb;
+}
index c3b76a3377741f96435ce445ee7bc9d8a98ad66b..ef2047a0a536cd5021a9c1f4fc87491783ebcc8f 100644 (file)
 #include "fdiskbsdlabel.h"
 #include "fdiskdoslabel.h"
 
+/*
+ * in-memory fdisk BSD stuff
+ */
+struct fdisk_bsd_label {
+       struct fdisk_label      head;           /* generic part */
+};
+
+
 static int xbsd_delete_part (struct fdisk_context *cxt, int partnum);
 static void xbsd_edit_disklabel (void);
 static void xbsd_write_bootstrap (struct fdisk_context *cxt);
@@ -879,18 +887,38 @@ static int xbsd_set_parttype(struct fdisk_context *cxt, int partnum,
        return 0;
 }
 
-const struct fdisk_label bsd_label =
+static const struct fdisk_label_operations bsd_operations =
 {
-       .name = "bsd",
-       .parttypes = xbsd_fstypes,
-       .nparttypes = ARRAY_SIZE(xbsd_fstypes),
-
-       .probe = osf_probe_label,
-       .write = xbsd_write_disklabel,
-       .verify = NULL,
-       .create = xbsd_create_disklabel,
-       .part_add = xbsd_add_part,
-       .part_delete = xbsd_delete_part,
-       .part_get_type = xbsd_get_parttype,
-       .part_set_type = xbsd_set_parttype,
+       .probe          = osf_probe_label,
+       .write          = xbsd_write_disklabel,
+       .create         = xbsd_create_disklabel,
+       .part_add       = xbsd_add_part,
+       .part_delete    = xbsd_delete_part,
+       .part_get_type  = xbsd_get_parttype,
+       .part_set_type  = xbsd_set_parttype
 };
+
+
+/*
+ * allocates BSD label driver
+ */
+struct fdisk_label *fdisk_new_bsd_label(struct fdisk_context *cxt)
+{
+       struct fdisk_label *lb;
+       struct fdisk_bsd_label *bsd;
+
+       assert(cxt);
+
+       bsd = calloc(1, sizeof(*bsd));
+       if (!bsd)
+               return NULL;
+
+       /* initialize generic part of the driver */
+       lb = (struct fdisk_label *) bsd;
+       lb->name = "bsd";
+       lb->op = &bsd_operations;
+       lb->parttypes = xbsd_fstypes;
+       lb->nparttypes = ARRAY_SIZE(xbsd_fstypes);
+
+       return lb;
+}
index 45343c8383fdc9dea70e5c2b4a7a5a0869257869..74d24cdea2d71ac7cb0a490f32383621ccc6a14f 100644 (file)
 #include "fdisk.h"
 #include "fdiskdoslabel.h"
 
+
+/*
+ * in-memory fdisk GPT stuff
+ */
+struct fdisk_dos_label {
+       struct fdisk_label      head;           /* generic part */
+};
+
+/*
+ * Partition types
+ */
 static struct fdisk_parttype dos_parttypes[] = {
        #include "dos_part_types.h"
 };
@@ -934,19 +945,39 @@ static int dos_set_parttype(struct fdisk_context *cxt, int partnum,
        return 0;
 }
 
-const struct fdisk_label dos_label =
+static const struct fdisk_label_operations dos_operations =
 {
-       .name = "dos",
-       .parttypes = dos_parttypes,
-       .nparttypes = ARRAY_SIZE(dos_parttypes),
-
-       .probe = dos_probe_label,
-       .write = dos_write_disklabel,
-       .verify = dos_verify_disklabel,
-       .create = dos_create_disklabel,
-       .part_add = dos_add_partition,
-       .part_delete = dos_delete_partition,
-       .part_get_type = dos_get_parttype,
-       .part_set_type = dos_set_parttype,
+       .probe          = dos_probe_label,
+       .write          = dos_write_disklabel,
+       .verify         = dos_verify_disklabel,
+       .create         = dos_create_disklabel,
+       .part_add       = dos_add_partition,
+       .part_delete    = dos_delete_partition,
+       .part_get_type  = dos_get_parttype,
+       .part_set_type  = dos_set_parttype,
        .reset_alignment = dos_reset_alignment,
 };
+
+/*
+ * allocates DOS in-memory stuff
+ */
+struct fdisk_label *fdisk_new_dos_label(struct fdisk_context *cxt)
+{
+       struct fdisk_label *lb;
+       struct fdisk_dos_label *dos;
+
+       assert(cxt);
+
+       dos = calloc(1, sizeof(*dos));
+       if (!dos)
+               return NULL;
+
+       /* initialize generic part of the driver */
+       lb = (struct fdisk_label *) dos;
+       lb->name = "dos";
+       lb->op = &dos_operations;
+       lb->parttypes = dos_parttypes;
+       lb->nparttypes = ARRAY_SIZE(dos_parttypes);
+
+       return lb;
+}
index de3a8ccbcbace12af8194839b1dc0e682004f69e..f15b802cce0eb8abc22370d45310b4dafc310d9f 100644 (file)
 
 #define MAC_BITMASK 0xffff0000
 
+/*
+ * in-memory fdisk mac stuff
+ */
+struct fdisk_mac_label {
+       struct fdisk_label      head;           /* generic part */
+};
+
 
 static int     other_endian = 0;
 static  short  volumes=1;
@@ -98,13 +105,31 @@ static int mac_add_partition(
        return -ENOSYS;
 }
 
-const struct fdisk_label mac_label =
+static const struct fdisk_label_operations mac_operations =
 {
-       .name = "mac",
-       .probe = mac_probe_label,
-       .write = NULL,
-       .verify = NULL,
-       .create = NULL,
-       .part_add = mac_add_partition,
-       .part_delete = NULL,
+       .probe          = mac_probe_label,
+       .part_add       = mac_add_partition
 };
+
+
+/*
+ * allocates MAC label driver
+ */
+struct fdisk_label *fdisk_new_mac_label(struct fdisk_context *cxt)
+{
+       struct fdisk_label *lb;
+       struct fdisk_mac_label *mac;
+
+       assert(cxt);
+
+       mac = calloc(1, sizeof(*mac));
+       if (!mac)
+               return NULL;
+
+       /* initialize generic part of the driver */
+       lb = (struct fdisk_label *) mac;
+       lb->name = "mac";
+       lb->op = &mac_operations;
+
+       return lb;
+}
index cf20445e41b73577896d321b25749bc1358f8f18..c58e7263be2490edba59dc06fe4d529a9d1c0f5a 100644 (file)
 #include "fdisksgilabel.h"
 #include "fdiskdoslabel.h"
 
+
+/*
+ * in-memory fdisk SGI stuff
+ */
+struct fdisk_sgi_label {
+       struct fdisk_label      head;           /* generic part */
+};
+
+
 static int     other_endian = 0;
 static int     debug = 0;
 static  short volumes=1;
@@ -929,18 +938,38 @@ static int sgi_set_parttype(struct fdisk_context *cxt, int i,
        return 0;
 }
 
-const struct fdisk_label sgi_label =
+static const struct fdisk_label_operations sgi_operations =
 {
-       .name = "sgi",
-       .parttypes = sgi_parttypes,
-       .nparttypes = ARRAY_SIZE(sgi_parttypes),
-
-       .probe = sgi_probe_label,
-       .write = sgi_write_disklabel,
-       .verify = sgi_verify_disklabel,
-       .create = sgi_create_disklabel,
-       .part_add = sgi_add_partition,
-       .part_delete = sgi_delete_partition,
-       .part_get_type = sgi_get_parttype,
-       .part_set_type = sgi_set_parttype,
+       .probe          = sgi_probe_label,
+       .write          = sgi_write_disklabel,
+       .verify         = sgi_verify_disklabel,
+       .create         = sgi_create_disklabel,
+       .part_add       = sgi_add_partition,
+       .part_delete    = sgi_delete_partition,
+       .part_get_type  = sgi_get_parttype,
+       .part_set_type  = sgi_set_parttype
 };
+
+/*
+ * allocates SGI label driver
+ */
+struct fdisk_label *fdisk_new_sgi_label(struct fdisk_context *cxt)
+{
+       struct fdisk_label *lb;
+       struct fdisk_sgi_label *sgi;
+
+       assert(cxt);
+
+       sgi = calloc(1, sizeof(*sgi));
+       if (!sgi)
+               return NULL;
+
+       /* initialize generic part of the driver */
+       lb = (struct fdisk_label *) sgi;
+       lb->name = "sgi";
+       lb->op = &sgi_operations;
+       lb->parttypes = sgi_parttypes;
+       lb->nparttypes = ARRAY_SIZE(sgi_parttypes);
+
+       return lb;
+}
index cb22ffcec153bad2974f379335042ea7650cab65..77d660168251abea7729042dc3480e2a77cef721 100644 (file)
 
 static int     other_endian = 0;
 
+/*
+ * in-memory fdisk SUN stuff
+ */
+struct fdisk_sun_label {
+       struct fdisk_label      head;           /* generic part */
+};
+
+
 static struct fdisk_parttype sun_parttypes[] = {
        {SUN_TAG_UNASSIGNED, N_("Unassigned")},
        {SUN_TAG_BOOT, N_("Boot")},
@@ -684,19 +692,39 @@ static int sun_reset_alignment(struct fdisk_context *cxt)
        return 0;
 }
 
-const struct fdisk_label sun_label =
+const struct fdisk_label_operations sun_operations =
 {
-       .name = "sun",
-       .parttypes = sun_parttypes,
-       .nparttypes = ARRAY_SIZE(sun_parttypes),
-
-       .probe = sun_probe_label,
-       .write = sun_write_disklabel,
-       .verify = sun_verify_disklabel,
-       .create = sun_create_disklabel,
-       .part_add = sun_add_partition,
-       .part_delete = sun_delete_partition,
-       .part_get_type = sun_get_parttype,
-       .part_set_type = sun_set_parttype,
-       .reset_alignment = sun_reset_alignment,
+       .probe          = sun_probe_label,
+       .write          = sun_write_disklabel,
+       .verify         = sun_verify_disklabel,
+       .create         = sun_create_disklabel,
+       .part_add       = sun_add_partition,
+       .part_delete    = sun_delete_partition,
+       .part_get_type  = sun_get_parttype,
+       .part_set_type  = sun_set_parttype,
+       .reset_alignment = sun_reset_alignment
 };
+
+/*
+ * allocates SUN label driver
+ */
+struct fdisk_label *fdisk_new_sun_label(struct fdisk_context *cxt)
+{
+       struct fdisk_label *lb;
+       struct fdisk_sun_label *sun;
+
+       assert(cxt);
+
+       sun = calloc(1, sizeof(*sun));
+       if (!sun)
+               return NULL;
+
+       /* initialize generic part of the driver */
+       lb = (struct fdisk_label *) sun;
+       lb->name = "sun";
+       lb->op = &sun_operations;
+       lb->parttypes = sun_parttypes;
+       lb->nparttypes = ARRAY_SIZE(sun_parttypes);
+
+       return lb;
+}
index 0784d639a54c234d456586b8a3028791d6f19752..4f70f962d019f7e87085b99224b59fccdf468f5c 100644 (file)
 #include "strutils.h"
 #include "all-io.h"
 
+/*
+ * in-memory fdisk GPT stuff
+ */
+struct fdisk_gpt_label {
+       struct fdisk_label      head;           /* generic part */
+};
+
+
 #define GPT_HEADER_SIGNATURE 0x5452415020494645LL /* EFI PART */
 #define GPT_HEADER_REVISION_V1_02 0x00010200
 #define GPT_HEADER_REVISION_V1_00 0x00010000
@@ -1655,18 +1663,38 @@ static int gpt_set_partition_type(struct fdisk_context *cxt, int i,
        return 0;
 }
 
-const struct fdisk_label gpt_label =
+static const struct fdisk_label_operations gpt_operations =
 {
-       .name = "gpt",
-       .parttypes = gpt_parttypes,
-       .nparttypes = ARRAY_SIZE(gpt_parttypes),
-
-       .probe = gpt_probe_label,
-       .write = gpt_write_disklabel,
-       .verify = gpt_verify_disklabel,
-       .create = gpt_create_disklabel,
-       .part_add = gpt_add_partition,
-       .part_delete = gpt_delete_partition,
-       .part_get_type = gpt_get_partition_type,
-       .part_set_type = gpt_set_partition_type
+       .probe          = gpt_probe_label,
+       .write          = gpt_write_disklabel,
+       .verify         = gpt_verify_disklabel,
+       .create         = gpt_create_disklabel,
+       .part_add       = gpt_add_partition,
+       .part_delete    = gpt_delete_partition,
+       .part_get_type  = gpt_get_partition_type,
+       .part_set_type  = gpt_set_partition_type
 };
+
+/*
+ * allocates GPT in-memory stuff
+ */
+struct fdisk_label *fdisk_new_gpt_label(struct fdisk_context *cxt)
+{
+       struct fdisk_label *lb;
+       struct fdisk_gpt_label *gpt;
+
+       assert(cxt);
+
+       gpt = calloc(1, sizeof(*gpt));
+       if (!gpt)
+               return NULL;
+
+       /* initialize generic part of the driver */
+       lb = (struct fdisk_label *) gpt;
+       lb->name = "gpt";
+       lb->op = &gpt_operations;
+       lb->parttypes = gpt_parttypes;
+       lb->nparttypes = ARRAY_SIZE(gpt_parttypes);
+
+       return lb;
+}
index 25c0c6467b6e22be8980f8632a51c609821e9c62..1ef5796a45a8e59bd36d1468444bdec54b2e4b32 100644 (file)
@@ -368,8 +368,8 @@ int fdisk_reset_alignment(struct fdisk_context *cxt)
        cxt->first_lba = fdisk_topology_get_first_lba(cxt);
 
        /* overwrite default by label stuff */
-       if (cxt->label && cxt->label->reset_alignment)
-               rc = cxt->label->reset_alignment(cxt);
+       if (cxt->label && cxt->label->op->reset_alignment)
+               rc = cxt->label->op->reset_alignment(cxt);
 
        DBG(LABEL, dbgprint("%s alignment reseted to: "
                            "first LBA=%ju, grain=%lu [rc=%d]",
index 302020590d9141ba3f3ab16e80dff7aa2fb9b445..83420a9779a625627488e02b8ccc531840e7004e 100644 (file)
@@ -1,8 +1,54 @@
 
 #include "fdiskP.h"
 
+static struct fdisk_context *fdisk_new_context(void)
+{
+       struct fdisk_context *cxt;
+       size_t i;
+
+       cxt = calloc(1, sizeof(*cxt));
+       if (!cxt)
+               return NULL;
+
+       /*
+        * Allocate label specific structs.
+        *
+        * This is necessary (for example) to store label specific
+        * context setting.
+        */
+       cxt->labels[ cxt->nlabels++ ] = fdisk_new_gpt_label(cxt);
+       cxt->labels[ cxt->nlabels++ ] = fdisk_new_dos_label(cxt);
+       cxt->labels[ cxt->nlabels++ ] = fdisk_new_aix_label(cxt);
+       cxt->labels[ cxt->nlabels++ ] = fdisk_new_bsd_label(cxt);
+       cxt->labels[ cxt->nlabels++ ] = fdisk_new_mac_label(cxt);
+       cxt->labels[ cxt->nlabels++ ] = fdisk_new_sgi_label(cxt);
+       cxt->labels[ cxt->nlabels++ ] = fdisk_new_sun_label(cxt);
+
+       DBG(CONTEXT, dbgprint("supported labels:"));
+       for (i = 0; i < cxt->nlabels; i++) {
+               DBG(CONTEXT, dbgprint(" %s", cxt->labels[i]->name));
+               cxt->labels[i]->cxt = cxt;
+       }
+
+       return cxt;
+}
+
+struct fdisk_label *fdisk_context_get_label(struct fdisk_context *cxt, const char *name)
+{
+       size_t i;
+
+       assert(cxt);
+
+       for (i = 0; i < cxt->nlabels; i++)
+               if (strcmp(cxt->labels[i]->name, name) == 0)
+                       return cxt->labels[i];
+
+       DBG(LABEL, dbgprint("failed to found %s label driver\n", name));
+       return NULL;
+}
+
 /**
- * fdisk_new_context:
+ * fdisk_new_context_from_filename:
  * @fname: path to the device to be handled
  * @readonly: how to open the device
  *
@@ -25,7 +71,7 @@ struct fdisk_context *fdisk_new_context_from_filename(const char *fname, int rea
                readonly = 1;
        }
 
-       cxt = calloc(1, sizeof(*cxt));
+       cxt = fdisk_new_context();
        if (!cxt)
                goto fail;
 
@@ -67,12 +113,26 @@ fail:
  */
 void fdisk_free_context(struct fdisk_context *cxt)
 {
+       int i;
+
        if (!cxt)
                return;
 
        DBG(CONTEXT, dbgprint("freeing context %p for %s", cxt, cxt->dev_path));
-       close(cxt->dev_fd);
+       if (cxt->dev_fd > -1)
+               close(cxt->dev_fd);
        free(cxt->dev_path);
        free(cxt->firstsector);
+
+       /* deallocate label's private stuff */
+       for (i = 0; i < cxt->nlabels; i++) {
+               if (!cxt->labels[i])
+                       continue;
+               if (cxt->labels[i]->op->free)
+                       cxt->labels[i]->op->free(cxt->labels[i]);
+               else
+                       free(cxt->labels[i]);
+       }
+
        free(cxt);
 }
index eac127ee6ce7693f2a5e1b28655488a538619cad..01dd71f514cf279c3d18db0d9a5ecda84f1ec230 100644 (file)
@@ -118,6 +118,56 @@ struct fdisk_geometry {
        sector_t cylinders;
 };
 
+/*
+ * Label specific operations
+ */
+struct fdisk_label_operations {
+       /* probe disk label */
+       int (*probe)(struct fdisk_context *cxt);
+       /* write in-memory changes to disk */
+       int (*write)(struct fdisk_context *cxt);
+       /* verify the partition table */
+       int (*verify)(struct fdisk_context *cxt);
+       /* create new disk label */
+       int (*create)(struct fdisk_context *cxt);
+       /* new partition */
+       int (*part_add)(struct fdisk_context *cxt, int partnum, struct fdisk_parttype *t);
+       /* delete partition */
+       int (*part_delete)(struct fdisk_context *cxt, int partnum);
+       /* get partition type */
+       struct fdisk_parttype *(*part_get_type)(struct fdisk_context *cxt, int partnum);
+       /* set partition type */
+       int (*part_set_type)(struct fdisk_context *cxt, int partnum, struct fdisk_parttype *t);
+       /* refresh alignment setting */
+       int (*reset_alignment)(struct fdisk_context *cxt);
+
+       /* free in-memory label stuff */
+       void (*free)(struct fdisk_label *lb);
+};
+
+/*
+ * Generic label
+ */
+struct fdisk_label {
+       const char *name;
+
+       struct fdisk_parttype   *parttypes;
+       size_t                  nparttypes;     /* number of items in parttypes[] */
+
+       const struct fdisk_label_operations *op;
+
+       struct fdisk_context    *cxt;
+};
+
+/* label allocators */
+extern struct fdisk_label *fdisk_new_gpt_label(struct fdisk_context *cxt);
+extern struct fdisk_label *fdisk_new_dos_label(struct fdisk_context *cxt);
+extern struct fdisk_label *fdisk_new_aix_label(struct fdisk_context *cxt);
+extern struct fdisk_label *fdisk_new_bsd_label(struct fdisk_context *cxt);
+extern struct fdisk_label *fdisk_new_mac_label(struct fdisk_context *cxt);
+extern struct fdisk_label *fdisk_new_sgi_label(struct fdisk_context *cxt);
+extern struct fdisk_label *fdisk_new_sun_label(struct fdisk_context *cxt);
+
 struct fdisk_context {
        int dev_fd;         /* device descriptor */
        char *dev_path;     /* device path */
@@ -141,39 +191,14 @@ struct fdisk_context {
        sector_t total_sectors; /* in logical sectors */
        struct fdisk_geometry geom;
 
-       /* label operations and description */
-       const struct fdisk_label *label;
-};
+       struct fdisk_label *label;      /* current label, pointer to labels[] */
 
-/*
- * Label specific operations
- */
-struct fdisk_label {
-       const char *name;
+       size_t nlabels;                 /* number of initialized label drivers */
+       struct fdisk_label *labels[8];  /* all supported labels,
+                                        * FIXME: use any enum rather than hardcoded number */
+};
 
-       /* array with partition types */
-       struct fdisk_parttype   *parttypes;
-       size_t                  nparttypes;     /* number of items in parttypes[] */
 
-       /* probe disk label */
-       int (*probe)(struct fdisk_context *cxt);
-       /* write in-memory changes to disk */
-       int (*write)(struct fdisk_context *cxt);
-       /* verify the partition table */
-       int (*verify)(struct fdisk_context *cxt);
-       /* create new disk label */
-       int (*create)(struct fdisk_context *cxt);
-       /* new partition */
-       int (*part_add)(struct fdisk_context *cxt, int partnum, struct fdisk_parttype *t);
-       /* delete partition */
-       int (*part_delete)(struct fdisk_context *cxt, int partnum);
-       /* get partition type */
-       struct fdisk_parttype *(*part_get_type)(struct fdisk_context *cxt, int partnum);
-       /* set partition type */
-       int (*part_set_type)(struct fdisk_context *cxt, int partnum, struct fdisk_parttype *t);
-       /* refresh alignment setting */
-       int (*reset_alignment)(struct fdisk_context *cxt);
-};
 
 /* alignment.c */
 extern sector_t fdisk_topology_get_first_lba(struct fdisk_context *cxt);
index 5d0eb3ef8a60f68142f5b9e1e259b1aabc8af07c..8f9934835573935c8b21cca7efa7435209bedd87 100644 (file)
@@ -1,28 +1,6 @@
 
 #include "fdiskP.h"
 
-/*
- * Label probing functions.
- */
-extern const struct fdisk_label aix_label;
-extern const struct fdisk_label dos_label;
-extern const struct fdisk_label bsd_label;
-extern const struct fdisk_label mac_label;
-extern const struct fdisk_label sun_label;
-extern const struct fdisk_label sgi_label;
-extern const struct fdisk_label gpt_label;
-
-static const struct fdisk_label *labels[] =
-{
-       &gpt_label,
-       &dos_label,
-       &sun_label,
-       &sgi_label,
-       &aix_label,
-       &bsd_label,
-       &mac_label,
-};
-
 /*
  * Don't use this function derectly, use fdisk_new_context_from_filename()
  */
@@ -32,11 +10,12 @@ int fdisk_probe_labels(struct fdisk_context *cxt)
 
        cxt->disklabel = FDISK_DISKLABEL_ANY;
 
-       for (i = 0; i < ARRAY_SIZE(labels); i++) {
-               if (!labels[i]->probe || labels[i]->probe(cxt) != 1)
+       for (i = 0; i < cxt->nlabels; i++) {
+               if (!cxt->labels[i]->op->probe ||
+                    cxt->labels[i]->op->probe(cxt) != 1)
                        continue;
 
-               cxt->label = labels[i];
+               cxt->label = cxt->labels[i];
 
                DBG(LABEL, dbgprint("detected a %s label", cxt->label->name));
                return 0;
@@ -81,10 +60,10 @@ int fdisk_write_disklabel(struct fdisk_context *cxt)
 {
        if (!cxt || !cxt->label)
                return -EINVAL;
-       if (!cxt->label->write)
+       if (!cxt->label->op->write)
                return -ENOSYS;
 
-       return cxt->label->write(cxt);
+       return cxt->label->op->write(cxt);
 }
 
 /**
@@ -99,10 +78,10 @@ int fdisk_verify_disklabel(struct fdisk_context *cxt)
 {
        if (!cxt || !cxt->label)
                return -EINVAL;
-       if (!cxt->label->verify)
+       if (!cxt->label->op->verify)
                return -ENOSYS;
 
-       return cxt->label->verify(cxt);
+       return cxt->label->op->verify(cxt);
 }
 
 /**
@@ -120,11 +99,11 @@ int fdisk_add_partition(struct fdisk_context *cxt, int partnum,
 {
        if (!cxt || !cxt->label)
                return -EINVAL;
-       if (!cxt->label->part_add)
+       if (!cxt->label->op->part_add)
                return -ENOSYS;
 
        DBG(LABEL, dbgprint("adding new partition number %d", partnum));
-       cxt->label->part_add(cxt, partnum, t);
+       cxt->label->op->part_add(cxt, partnum, t);
        return 0;
 }
 
@@ -141,12 +120,12 @@ int fdisk_delete_partition(struct fdisk_context *cxt, int partnum)
 {
        if (!cxt || !cxt->label)
                return -EINVAL;
-       if (!cxt->label->part_delete)
+       if (!cxt->label->op->part_delete)
                return -ENOSYS;
 
        DBG(LABEL, dbgprint("deleting %s partition number %d",
                                cxt->label->name, partnum));
-       return cxt->label->part_delete(cxt, partnum);
+       return cxt->label->op->part_delete(cxt, partnum);
 }
 
 /**
@@ -164,35 +143,24 @@ int fdisk_create_disklabel(struct fdisk_context *cxt, const char *name)
        if (!cxt)
                return -EINVAL;
 
-       cxt->label = NULL;
-
        if (!name) { /* use default label creation */
 #ifdef __sparc__
-               cxt->label = &sun_label;
+               name = "sun";
 #else
-               cxt->label = &dos_label;
+               name = "dos";
 #endif
-       } else {
-               size_t i;
-
-               for (i = 0; i < ARRAY_SIZE(labels); i++) {
-                       if (strcmp(name, labels[i]->name) != 0)
-                               continue;
-
-                       cxt->label = labels[i];
-                       DBG(LABEL, dbgprint("changing to %s label\n", cxt->label->name));
-                       break;
-               }
        }
 
+       cxt->label = fdisk_context_get_label(cxt, name);
        if (!cxt->label)
                return -EINVAL;
-       if (!cxt->label->create)
+
+       DBG(LABEL, dbgprint("changing to %s label\n", cxt->label->name));
+       if (!cxt->label->op->create)
                return -ENOSYS;
 
        fdisk_reset_alignment(cxt);
-
-       return cxt->label->create(cxt);
+       return cxt->label->op->create(cxt);
 }
 
 /**
@@ -204,11 +172,11 @@ int fdisk_create_disklabel(struct fdisk_context *cxt, const char *name)
  */
 struct fdisk_parttype *fdisk_get_partition_type(struct fdisk_context *cxt, int partnum)
 {
-       if (!cxt || !cxt->label || !cxt->label->part_get_type)
+       if (!cxt || !cxt->label || !cxt->label->op->part_get_type)
                return NULL;
 
        DBG(LABEL, dbgprint("partition: %d: get type", partnum));
-       return cxt->label->part_get_type(cxt, partnum);
+       return cxt->label->op->part_get_type(cxt, partnum);
 }
 
 /**
@@ -222,11 +190,11 @@ struct fdisk_parttype *fdisk_get_partition_type(struct fdisk_context *cxt, int p
 int fdisk_set_partition_type(struct fdisk_context *cxt, int partnum,
                             struct fdisk_parttype *t)
 {
-       if (!cxt || !cxt->label || !cxt->label->part_set_type)
+       if (!cxt || !cxt->label || !cxt->label->op->part_set_type)
                return -EINVAL;
 
        DBG(LABEL, dbgprint("partition: %d: set type", partnum));
-       return cxt->label->part_set_type(cxt, partnum, t);
+       return cxt->label->op->part_set_type(cxt, partnum, t);
 }
 
 /**
index d719a5c8d3917bf7576acf88528f94212f45785f..d72a608899e9ff74d65b37da34f6bd7cea10558d 100644 (file)
@@ -26,6 +26,7 @@ extern "C" {
 #endif
 
 struct fdisk_context;
+struct fdisk_label;
 struct fdisk_parttype;
 
 /*
@@ -50,6 +51,9 @@ extern struct fdisk_context *fdisk_new_context_from_filename(
                                const char *fname, int readonly);
 extern void fdisk_free_context(struct fdisk_context *cxt);
 
+extern struct fdisk_label *fdisk_context_get_label(struct fdisk_context *cxt,
+                               const char *name);
+
 /* parttype.c */
 extern struct fdisk_parttype *fdisk_get_parttype_from_code(struct fdisk_context *cxt,
                                 unsigned int code);