From: Karel Zak Date: Fri, 13 Dec 2013 18:56:21 +0000 (+0100) Subject: libfdisk: add table container X-Git-Tag: v2.25-rc1~517 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=b48cdebcb45f75ff20cdab68f706de803532ceaf;p=thirdparty%2Futil-linux.git libfdisk: add table container Signed-off-by: Karel Zak --- diff --git a/libfdisk/src/Makemodule.am b/libfdisk/src/Makemodule.am index f58d0c6650..a87b2efcc4 100644 --- a/libfdisk/src/Makemodule.am +++ b/libfdisk/src/Makemodule.am @@ -18,6 +18,7 @@ libfdisk_la_SOURCES = \ libfdisk/src/context.c \ libfdisk/src/parttype.c \ libfdisk/src/partition.c \ + libfdisk/src/table.c \ \ libfdisk/src/sun.c \ libfdisk/src/sgi.c \ diff --git a/libfdisk/src/fdiskP.h b/libfdisk/src/fdiskP.h index 2defe33675..6459b36352 100644 --- a/libfdisk/src/fdiskP.h +++ b/libfdisk/src/fdiskP.h @@ -22,6 +22,7 @@ #include "nls.h" /* temporary before dialog API will be implamented */ #include "tt.h" +#include "list.h" /* features */ #define CONFIG_LIBFDISK_ASSERT @@ -51,6 +52,7 @@ #define FDISK_DEBUG_ASK (1 << 6) #define FDISK_DEBUG_FRONTEND (1 << 7) #define FDISK_DEBUG_PART (1 << 8) +#define FDISK_DEBUG_TAB (1 << 9) #define FDISK_DEBUG_ALL 0xFFFF # define ON_DBG(m, x) do { \ @@ -127,45 +129,52 @@ enum { #define fdisk_parttype_is_allocated(_x) ((_x) && ((_x)->flags & FDISK_PARTTYPE_ALLOCATED)) struct fdisk_partition { - struct fdisk_context *cxt; + struct fdisk_context *cxt; /* the current context */ - int refcount; - size_t partno; + int refcount; /* reference counter */ + size_t partno; /* partition number */ - uint64_t start; - uint64_t end; - uint64_t size; + uint64_t start; /* first sectors */ + uint64_t end; /* last sector */ + uint64_t size; /* size in sectors */ - char *name; - char *uuid; - char *attrs; + char *name; /* partition name */ + char *uuid; /* partition UUID */ + char *attrs; /* partition flags/attributes converted to string */ + struct fdisk_parttype *type; /* partition type */ - struct fdisk_parttype *type; + struct list_head parts; /* list of partitions */ - /* private fields */ - char start_post; - char end_post; - char size_post; - uint64_t fsize; + /* extra fields for partition_to_string() */ + char start_post; /* start postfix (e.g. '+') */ + char end_post; /* end postfix */ + char size_post; /* size postfix */ + + uint64_t fsize; /* bsd junk */ uint64_t bsize; uint64_t cpg; - char boot; - char *start_addr; - char *end_addr; + char boot; /* is bootable (MBS only) */ + char *start_addr; /* start C/H/S in string */ + char *end_addr; /* end C/H/S in string */ - unsigned int partno_follow_default : 1, - start_follow_default : 1, - end_follow_default : 1, - freespace : 1, /* describes gap between partitions*/ + unsigned int partno_follow_default : 1, /* use default partno */ + start_follow_default : 1, /* use default start */ + end_follow_default : 1, /* use default end */ + freespace : 1, /* dthis is not partition, this is free space */ nested : 1, /* logical partition */ - used : 1, /* partition used */ - endrel : 1; /* end is specified as relative number */ + used : 1, /* partition already used */ + endrel : 1; /* end is specified as relative number */ }; #define FDISK_EMPTY_PARTNO ((size_t) -1) #define FDISK_EMPTY_PARTITION { .partno = FDISK_EMPTY_PARTNO } +struct fdisk_table { + struct list_head parts; /* partitions */ + int refcount; +}; + /* * Legacy CHS based geometry */ diff --git a/libfdisk/src/libfdisk.h b/libfdisk/src/libfdisk.h index ef9b1a1293..0d30df8d6c 100644 --- a/libfdisk/src/libfdisk.h +++ b/libfdisk/src/libfdisk.h @@ -207,6 +207,16 @@ extern int fdisk_partition_to_string(struct fdisk_partition *pa, int id, char ** extern int fdisk_partition_next_partno( struct fdisk_context *cxt, struct fdisk_partition *pa, size_t *n); +/* table.c */ +extern struct fdisk_table *fdisk_new_table(void); +extern int fdisk_reset_table(struct fdisk_table *tb); +extern void fdisk_ref_table(struct fdisk_table *tb); +extern void fdisk_unref_table(struct fdisk_table *tb); +extern int fdisk_table_is_empty(struct fdisk_table *tb); +extern int fdisk_table_add_partition(struct fdisk_table *tb, struct fdisk_partition *pa); +extern int fdisk_table_remove_partition(struct fdisk_table *tb, struct fdisk_partition *pa); + + /* alignment.c */ extern int fdisk_reset_alignment(struct fdisk_context *cxt); extern int fdisk_reset_device_properties(struct fdisk_context *cxt); diff --git a/libfdisk/src/table.c b/libfdisk/src/table.c new file mode 100644 index 0000000000..34d8fbb8c9 --- /dev/null +++ b/libfdisk/src/table.c @@ -0,0 +1,149 @@ + +#include "fdiskP.h" + +/** + * fdisk_new_table: + * + * The table is a container for struct fdisk_partition entries. The container + * does not have any real connection with label (partition table) and with + * real on-disk data. + * + * Returns: newly allocated table struct. + */ +struct fdisk_table *fdisk_new_table(void) +{ + struct fdisk_table *tb = NULL; + + tb = calloc(1, sizeof(*tb)); + if (!tb) + return NULL; + + DBG(TAB, dbgprint("alloc")); + tb->refcount = 1; + INIT_LIST_HEAD(&tb->parts); + return tb; +} + +/** + * fdisk_reset_table: + * @tb: tab pointer + * + * Removes all entries (filesystems) from the table. The filesystems with zero + * reference count will be deallocated. + * + * Returns: 0 on success or negative number in case of error. + */ +int fdisk_reset_table(struct fdisk_table *tb) +{ + if (!tb) + return -EINVAL; + + DBG(TAB, dbgprint("reset")); + + while (!list_empty(&tb->parts)) { + struct fdisk_partition *pa = list_entry(tb->parts.next, + struct fdisk_partition, parts); + fdisk_table_remove_partition(tb, pa); + } + + return 0; +} + +/** + * fdisk_ref_table: + * @tb: table pointer + * + * Incremparts reference counter. + */ +void fdisk_ref_table(struct fdisk_table *tb) +{ + if (tb) + tb->refcount++; +} + +/** + * fdisk_unref_table: + * @tb: table pointer + * + * De-incremparts reference counter, on zero the @tb is automatically + * deallocated by fdisk_free_table(). + */ +void fdisk_unref_table(struct fdisk_table *tb) +{ + if (!tb) + return; + + tb->refcount--; + if (tb->refcount <= 0) { + fdisk_reset_table(tb); + + DBG(TAB, dbgprint("free")); + free(tb); + } +} + +/** + * fdisk_table_is_empty: + * @tb: pointer to tab + * + * Returns: 1 if the table is without filesystems, or 0. + */ +int fdisk_table_is_empty(struct fdisk_table *tb) +{ + assert(tb); + return tb == NULL || list_empty(&tb->parts) ? 1 : 0; +} + +/** + * fdisk_table_add_partition + * @tb: tab pointer + * @pa: new entry + * + * Adds a new entry to table and increment @pa reference counter. Don't forget to + * use fdisk_unref_pa() after fdisk_table_add_partition() if you want to keep + * the @pa referenced by the table only. + * + * Returns: 0 on success or negative number in case of error. + */ +int fdisk_table_add_partition(struct fdisk_table *tb, struct fdisk_partition *pa) +{ + assert(tb); + assert(pa); + + if (!tb || !pa) + return -EINVAL; + + fdisk_ref_partition(pa); + list_add_tail(&pa->parts, &tb->parts); + + DBG(TAB, dbgprint("add entry %p", pa)); + return 0; +} + +/** + * fdisk_table_remove_partition + * @tb: tab pointer + * @pa: new entry + * + * Removes the @pa from the table and de-increment reference counter of the @pa. The + * partition with zero reference counter will be deallocated. Don't forget to use + * fdisk_ref_partition() before call fdisk_table_remove_partition() if you want + * to use @pa later. + * + * Returns: 0 on success or negative number in case of error. + */ +int fdisk_table_remove_partition(struct fdisk_table *tb, struct fdisk_partition *pa) +{ + assert(tb); + assert(pa); + + if (!tb || !pa) + return -EINVAL; + + DBG(TAB, dbgprint("remove entry %p", pa)); + list_del(&pa->parts); + INIT_LIST_HEAD(&pa->parts); + + fdisk_unref_partition(pa); + return 0; +}