libfdisk/src/context.c \
libfdisk/src/parttype.c \
libfdisk/src/partition.c \
+ libfdisk/src/table.c \
\
libfdisk/src/sun.c \
libfdisk/src/sgi.c \
#include "nls.h" /* temporary before dialog API will be implamented */
#include "tt.h"
+#include "list.h"
/* features */
#define CONFIG_LIBFDISK_ASSERT
#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 { \
#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
*/
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);
--- /dev/null
+
+#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;
+}