summaryrefslogtreecommitdiffstats
path: root/libfdisk
diff options
context:
space:
mode:
authorKarel Zak2014-02-04 20:50:02 +0100
committerKarel Zak2014-03-11 11:35:14 +0100
commitbd5e829198a61b0c2a9ef990ea6d017a7e7c8aef (patch)
treef0b0a0712f5195f4fd6edf07e5ec168ee8060ecb /libfdisk
parentlibfdisk: (dos) fix log.partition delete (diff)
downloadkernel-qcow2-util-linux-bd5e829198a61b0c2a9ef990ea6d017a7e7c8aef.tar.gz
kernel-qcow2-util-linux-bd5e829198a61b0c2a9ef990ea6d017a7e7c8aef.tar.xz
kernel-qcow2-util-linux-bd5e829198a61b0c2a9ef990ea6d017a7e7c8aef.zip
libfdisk: remove label specific get_freespace
- it seems we can use improved nested<->container relationship rather than implement DOS specific function Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'libfdisk')
-rw-r--r--libfdisk/src/dos.c9
-rw-r--r--libfdisk/src/fdiskP.h6
-rw-r--r--libfdisk/src/libfdisk.h2
-rw-r--r--libfdisk/src/partition.c14
-rw-r--r--libfdisk/src/table.c106
5 files changed, 60 insertions, 77 deletions
diff --git a/libfdisk/src/dos.c b/libfdisk/src/dos.c
index 5d01b3fbe..7f8e40cc1 100644
--- a/libfdisk/src/dos.c
+++ b/libfdisk/src/dos.c
@@ -1630,12 +1630,14 @@ static int dos_get_partition(struct fdisk_context *cxt, size_t n,
struct dos_partition *p;
struct pte *pe;
unsigned int psects;
+ struct fdisk_dos_label *lb;
assert(cxt);
assert(pa);
assert(cxt->label);
assert(fdisk_is_disklabel(cxt, DOS));
+ lb = self_label(cxt);
pe = self_pte(cxt, n);
p = pe->pt_entry;
pa->used = !is_cleared_partition(p);
@@ -1649,11 +1651,10 @@ static int dos_get_partition(struct fdisk_context *cxt, size_t n,
pa->start = get_abs_partition_start(pe);
pa->end = get_abs_partition_start(pe) + psects - (psects ? 1 : 0);
pa->size = psects;
+ pa->container = n == lb->ext_index;
- if (n >= 4) {
- pa->parent_partno = self_label(cxt)->ext_index;
- pa->nested = 1;
- }
+ if (n >= 4)
+ pa->parent_partno = lb->ext_index;
if (asprintf(&pa->attrs, "%02x", p->boot_ind) < 0)
return -ENOMEM;
diff --git a/libfdisk/src/fdiskP.h b/libfdisk/src/fdiskP.h
index 899a043b0..6d067fbf5 100644
--- a/libfdisk/src/fdiskP.h
+++ b/libfdisk/src/fdiskP.h
@@ -187,8 +187,8 @@ struct fdisk_partition {
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 */
+ freespace : 1, /* this is free space */
+ container : 1, /* container partition (e.g. extended partition) */
used : 1; /* partition already used */
};
@@ -253,8 +253,6 @@ struct fdisk_label_operations {
int (*get_part)(struct fdisk_context *cxt,
size_t n,
struct fdisk_partition *pa);
- /* add all gaps to table */
- int (*get_freespace)(struct fdisk_context *cxt, struct fdisk_table *tb);
int (*part_toggle_flag)(struct fdisk_context *cxt, size_t i, unsigned long flag);
diff --git a/libfdisk/src/libfdisk.h b/libfdisk/src/libfdisk.h
index 726296c32..ec6b87a1c 100644
--- a/libfdisk/src/libfdisk.h
+++ b/libfdisk/src/libfdisk.h
@@ -205,8 +205,8 @@ extern const char *fdisk_partition_get_name(struct fdisk_partition *pa);
extern int fdisk_partition_set_uuid(struct fdisk_partition *pa, const char *uuid);
extern const char *fdisk_partition_get_uuid(struct fdisk_partition *pa);
extern const char *fdisk_partition_get_attrs(struct fdisk_partition *pa);
-extern int fdisk_partition_set_nested(struct fdisk_partition *pa, int nested);
extern int fdisk_partition_is_nested(struct fdisk_partition *pa);
+extern int fdisk_partition_is_container(struct fdisk_partition *pa);
extern int fdisk_partition_get_parent(struct fdisk_partition *pa, size_t *parent);
extern int fdisk_partition_is_used(struct fdisk_partition *pa);
extern int fdisk_partition_to_string(struct fdisk_partition *pa,
diff --git a/libfdisk/src/partition.c b/libfdisk/src/partition.c
index 20993ba3a..81594842c 100644
--- a/libfdisk/src/partition.c
+++ b/libfdisk/src/partition.c
@@ -11,6 +11,7 @@ struct fdisk_partition *fdisk_new_partition(void)
pa->refcount = 1;
INIT_LIST_HEAD(&pa->parts);
pa->partno = FDISK_EMPTY_PARTNO;
+ pa->parent_partno = FDISK_EMPTY_PARTNO;
DBG(PART, dbgprint("new %p", pa));
return pa;
}
@@ -29,6 +30,7 @@ void fdisk_reset_partition(struct fdisk_partition *pa)
free(pa->attrs);
memset(pa, 0, sizeof(*pa));
pa->partno = FDISK_EMPTY_PARTNO;
+ pa->parent_partno = FDISK_EMPTY_PARTNO;
pa->refcount = ref;
INIT_LIST_HEAD(&pa->parts);
}
@@ -205,18 +207,14 @@ const char *fdisk_partition_get_attrs(struct fdisk_partition *pa)
return pa ? pa->attrs : NULL;
}
-/* nested partition means logical (within extended partition) */
-int fdisk_partition_set_nested(struct fdisk_partition *pa, int nested)
+int fdisk_partition_is_nested(struct fdisk_partition *pa)
{
- if (!pa)
- return -EINVAL;
- pa->nested = nested ? 1 : 0;
- return 0;
+ return pa && pa->parent_partno != FDISK_EMPTY_PARTNO;
}
-int fdisk_partition_is_nested(struct fdisk_partition *pa)
+int fdisk_partition_is_container(struct fdisk_partition *pa)
{
- return pa && pa->nested;
+ return pa && pa->container;
}
int fdisk_partition_get_parent(struct fdisk_partition *pa, size_t *parent)
diff --git a/libfdisk/src/table.c b/libfdisk/src/table.c
index 6b8c6e3a3..88e199cbf 100644
--- a/libfdisk/src/table.c
+++ b/libfdisk/src/table.c
@@ -315,11 +315,11 @@ static int table_add_freespace(
struct fdisk_table *tb,
uint64_t start,
uint64_t end,
- int dosort,
- struct fdisk_partition **res)
+ struct fdisk_partition *parent)
{
- struct fdisk_partition *pa;
- int rc = 0;
+ struct fdisk_partition *pa, *x, *real_parent = NULL, *best = NULL;
+ struct fdisk_iter itr;
+ int rc;
assert(tb);
@@ -334,21 +334,33 @@ static int table_add_freespace(
pa->end = end;
pa->size = pa->end - pa->start + 1ULL;
- if (!dosort)
- rc = fdisk_table_add_partition(tb, pa);
- else {
- struct fdisk_partition *x, *best = NULL;
- struct fdisk_iter itr;
+ fdisk_reset_iter(&itr, FDISK_ITER_FORWARD);
+
+ if (parent) {
+ pa->parent_partno = parent->partno;
- fdisk_reset_iter(&itr, FDISK_ITER_FORWARD);
while (fdisk_table_next_partition(tb, &itr, &x) == 0) {
- if (x->end < pa->start && (!best || best->end < x->end))
- best = x;
+ if (x->partno == parent->partno) {
+ real_parent = x;
+ break;
+ }
+ }
+ if (!real_parent) {
+ DBG(LABEL, dbgprint("not found freespace parent (partno=%ju)",
+ parent->partno));
+ fdisk_reset_iter(&itr, FDISK_ITER_FORWARD);
}
- rc = table_insert_partition(tb, best, pa);
}
- if (res)
- *res = pa;
+
+ while (fdisk_table_next_partition(tb, &itr, &x) == 0) {
+ if (x->end < pa->start && (!best || best->end < x->end))
+ best = x;
+ }
+
+ if (!best && real_parent)
+ best = real_parent;
+ rc = table_insert_partition(tb, best, pa);
+
fdisk_unref_partition(pa);
return rc;
}
@@ -366,12 +378,11 @@ static int table_add_freespace(
*/
int fdisk_get_freespaces(struct fdisk_context *cxt, struct fdisk_table **tb)
{
- int dosort, rc = 0;
+ int rc = 0;
uint64_t last, grain;
struct fdisk_table *parts = NULL;
- struct fdisk_partition *pa;
+ struct fdisk_partition *pa, *cont = NULL;
struct fdisk_iter itr;
- size_t cont = FDISK_EMPTY_PARTNO;
DBG(LABEL, dbgprint("get freespace"));
@@ -379,11 +390,6 @@ int fdisk_get_freespaces(struct fdisk_context *cxt, struct fdisk_table **tb)
return -EINVAL;
if (!*tb && !(*tb = fdisk_new_table()))
return -ENOMEM;
-
- /* label specific way */
- if (cxt->label->op->get_freespace)
- return cxt->label->op->get_freespace(cxt, *tb);
-
/* generic way */
rc = fdisk_get_partitions(cxt, &parts);
if (rc)
@@ -391,24 +397,21 @@ int fdisk_get_freespaces(struct fdisk_context *cxt, struct fdisk_table **tb)
fdisk_table_sort_partitions(parts, fdisk_partition_cmp_start);
fdisk_reset_iter(&itr, FDISK_ITER_FORWARD);
-
- dosort = !fdisk_table_is_empty(*tb);
last = cxt->first_lba;
grain = cxt->grain > cxt->sector_size ? cxt->grain / cxt->sector_size : 1;
/* analyze gaps between partitions */
while (fdisk_table_next_partition(parts, &itr, &pa) == 0) {
- if (pa->nested)
- cont = (int) pa->parent_partno;
- if (!pa->used || pa->nested)
+ if (!pa->used || fdisk_partition_is_nested(pa))
continue;
+ if (fdisk_partition_is_container(pa))
+ cont = pa;
DBG(LABEL, dbgprint("freespace analyze: partno=%zu, start=%ju, end=%ju",
pa->partno, pa->start, pa->end));
if (last + grain < pa->start) {
rc = table_add_freespace(cxt, *tb,
last + (last > cxt->first_lba ? 1 : 0),
- pa->start - 1,
- dosort, NULL);
+ pa->start - 1, NULL);
}
last = pa->end;
}
@@ -417,56 +420,39 @@ int fdisk_get_freespaces(struct fdisk_context *cxt, struct fdisk_table **tb)
if (rc == 0 && last + grain < cxt->total_sectors - 1)
rc = table_add_freespace(cxt, *tb,
last + (last > cxt->first_lba ? 1 : 0),
- cxt->last_lba,
- dosort, NULL);
+ cxt->last_lba, NULL);
/* add gaps between logical partitions */
- if (cont != FDISK_EMPTY_PARTNO) {
+ if (cont) {
uint64_t x;
- struct fdisk_partition *fr;
- struct fdisk_partition *parent =
- fdisk_table_get_partition(parts, cont);
- if (!parent)
- goto done;
- last = fdisk_partition_get_start(parent) + cxt->first_lba;
+
+ last = fdisk_partition_get_start(cont) + cxt->first_lba;
DBG(LABEL, dbgprint("check container freespace last=%ju, "
"grain=%ju, partno=%zu, start=%ju, end=%ju",
- last, grain, parent->partno, parent->start,
- parent->end));
+ last, grain, cont->partno, cont->start,
+ cont->end));
fdisk_reset_iter(&itr, FDISK_ITER_FORWARD);
while (fdisk_table_next_partition(parts, &itr, &pa) == 0) {
uint64_t lastfree;
- if (!pa->used || !pa->nested)
+ if (!pa->used || !fdisk_partition_is_nested(pa))
continue;
lastfree = pa->start - 1 - cxt->first_lba;
- if (last + grain < lastfree) {
+ if (last + grain < lastfree)
rc = table_add_freespace(cxt, *tb,
- last + grain, lastfree,
- dosort, &fr);
- if (rc == 0 && fr) {
- fr->parent_partno = parent->partno;
- fr->nested = 1;
- }
- }
+ last + grain, lastfree, cont);
last = pa->end;
}
/* free-space remaining in extended partition */
- x = fdisk_partition_get_start(parent)
- + fdisk_partition_get_size(parent) - 1;
- if (last + grain < x) {
+ x = fdisk_partition_get_start(cont)
+ + fdisk_partition_get_size(cont) - 1;
+ if (last + grain < x)
rc = table_add_freespace(cxt, *tb,
- last + grain, x - 1,
- dosort, &fr);
- if (rc == 0 && fr) {
- fr->parent_partno = parent->partno;
- fr->nested = 1;
- }
- }
+ last + grain, x - 1, cont);
}
done: