From: Karel Zak Date: Tue, 11 Dec 2012 11:56:27 +0000 (+0100) Subject: libfdisk: split label and label operations X-Git-Tag: v2.23-rc1~157 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=0c5d095e46306ed4d6009f56e0339857d733d72e;p=thirdparty%2Futil-linux.git libfdisk: split label and label operations 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 --- diff --git a/fdisks/fdiskaixlabel.c b/fdisks/fdiskaixlabel.c index d836363c9a..d5872243be 100644 --- a/fdisks/fdiskaixlabel.c +++ b/fdisks/fdiskaixlabel.c @@ -17,6 +17,14 @@ 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; +} diff --git a/fdisks/fdiskbsdlabel.c b/fdisks/fdiskbsdlabel.c index c3b76a3377..ef2047a0a5 100644 --- a/fdisks/fdiskbsdlabel.c +++ b/fdisks/fdiskbsdlabel.c @@ -62,6 +62,14 @@ #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; +} diff --git a/fdisks/fdiskdoslabel.c b/fdisks/fdiskdoslabel.c index 45343c8383..74d24cdea2 100644 --- a/fdisks/fdiskdoslabel.c +++ b/fdisks/fdiskdoslabel.c @@ -13,6 +13,17 @@ #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; +} diff --git a/fdisks/fdiskmaclabel.c b/fdisks/fdiskmaclabel.c index de3a8ccbcb..f15b802cce 100644 --- a/fdisks/fdiskmaclabel.c +++ b/fdisks/fdiskmaclabel.c @@ -16,6 +16,13 @@ #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; +} diff --git a/fdisks/fdisksgilabel.c b/fdisks/fdisksgilabel.c index cf20445e41..c58e7263be 100644 --- a/fdisks/fdisksgilabel.c +++ b/fdisks/fdisksgilabel.c @@ -35,6 +35,15 @@ #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; +} diff --git a/fdisks/fdisksunlabel.c b/fdisks/fdisksunlabel.c index cb22ffcec1..77d6601682 100644 --- a/fdisks/fdisksunlabel.c +++ b/fdisks/fdisksunlabel.c @@ -28,6 +28,14 @@ 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; +} diff --git a/fdisks/gpt.c b/fdisks/gpt.c index 0784d639a5..4f70f962d0 100644 --- a/fdisks/gpt.c +++ b/fdisks/gpt.c @@ -45,6 +45,14 @@ #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; +} diff --git a/libfdisk/src/alignment.c b/libfdisk/src/alignment.c index 25c0c6467b..1ef5796a45 100644 --- a/libfdisk/src/alignment.c +++ b/libfdisk/src/alignment.c @@ -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]", diff --git a/libfdisk/src/context.c b/libfdisk/src/context.c index 302020590d..83420a9779 100644 --- a/libfdisk/src/context.c +++ b/libfdisk/src/context.c @@ -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); } diff --git a/libfdisk/src/fdiskP.h b/libfdisk/src/fdiskP.h index eac127ee6c..01dd71f514 100644 --- a/libfdisk/src/fdiskP.h +++ b/libfdisk/src/fdiskP.h @@ -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); diff --git a/libfdisk/src/label.c b/libfdisk/src/label.c index 5d0eb3ef8a..8f99348355 100644 --- a/libfdisk/src/label.c +++ b/libfdisk/src/label.c @@ -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); } /** diff --git a/libfdisk/src/libfdisk.h b/libfdisk/src/libfdisk.h index d719a5c8d3..d72a608899 100644 --- a/libfdisk/src/libfdisk.h +++ b/libfdisk/src/libfdisk.h @@ -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);