summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libfdisk/src/context.c22
-rw-r--r--libfdisk/src/fdiskP.h5
-rw-r--r--libfdisk/src/label.c105
-rw-r--r--libfdisk/src/libfdisk.h5
-rw-r--r--libfdisk/src/partition.c9
5 files changed, 120 insertions, 26 deletions
diff --git a/libfdisk/src/context.c b/libfdisk/src/context.c
index c4054034e..0db21c81e 100644
--- a/libfdisk/src/context.c
+++ b/libfdisk/src/context.c
@@ -382,6 +382,28 @@ int fdisk_context_display_details(struct fdisk_context *cxt)
}
/**
+ * fdisk_context_enable_freespace
+ * cxt: context
+ * enable: true/flase
+ *
+ * Enables or disables "free space" in list() output
+ *
+ * Returns: 0 on success, < 0 on error.
+ */
+int fdisk_context_enable_freespace(struct fdisk_context *cxt, int enable)
+{
+ assert(cxt);
+ cxt->display_freespace = enable ? 1 : 0;
+ return 0;
+}
+
+int fdisk_context_display_freespace(struct fdisk_context *cxt)
+{
+ assert(cxt);
+ return cxt->display_freespace == 1;
+}
+
+/**
* fdisk_context_enable_listonly:
* cxt: context
* enable: true/flase
diff --git a/libfdisk/src/fdiskP.h b/libfdisk/src/fdiskP.h
index fbeaf7ee2..881e1b2b6 100644
--- a/libfdisk/src/fdiskP.h
+++ b/libfdisk/src/fdiskP.h
@@ -156,12 +156,14 @@ struct fdisk_partition {
unsigned int partno_follow_default : 1,
start_follow_default : 1,
end_follow_default : 1,
+ freespace : 1, /* describes gap between partitions*/
nested : 1, /* logical partition */
used : 1, /* partition used */
endrel : 1; /* end is specified as relative number */
};
#define FDISK_EMPTY_PARTNO ((size_t) -1)
+#define FDISK_EMPTY_PARTITION { .partno = FDISK_EMPTY_PARTNO }
/*
* Legacy CHS based geometry
@@ -338,6 +340,7 @@ struct fdisk_context {
unsigned int display_in_cyl_units : 1, /* for obscure labels */
display_details : 1, /* expert display mode */
+ display_freespace : 1, /* freesapce in list() output */
listonly : 1; /* list partition, nothing else */
/* alignment */
@@ -369,8 +372,6 @@ struct fdisk_context {
extern int __fdisk_context_switch_label(struct fdisk_context *cxt,
struct fdisk_label *lb);
-extern int fdisk_context_use_cylinders(struct fdisk_context *cxt);
-extern int fdisk_context_display_details(struct fdisk_context *cxt);
extern int fdisk_context_enable_listonly(struct fdisk_context *cxt, int enable);
extern int fdisk_context_listonly(struct fdisk_context *cxt);
diff --git a/libfdisk/src/label.c b/libfdisk/src/label.c
index 358162c57..e243dc05f 100644
--- a/libfdisk/src/label.c
+++ b/libfdisk/src/label.c
@@ -258,6 +258,64 @@ int fdisk_list_disklabel(struct fdisk_context *cxt)
return cxt->label->op->list(cxt);
}
+static int add_partition_to_tt(struct fdisk_context *cxt,
+ struct tt *tb,
+ int *cols,
+ size_t ncols,
+ struct fdisk_partition *pa)
+{
+ size_t j;
+ struct tt_line *ln = tt_add_line(tb, NULL);
+ const struct fdisk_column *col;
+
+ if (!ln)
+ return -ENOMEM;
+
+ /* set data for the columns */
+ for (j = 0; j < ncols; j++) {
+ char *data = NULL;
+ int id;
+
+ col = fdisk_label_get_column(cxt->label, cols[j]);
+ if (!col)
+ continue;
+ id = (col->id == FDISK_COL_SECTORS &&
+ fdisk_context_use_cylinders(cxt)) ?
+ FDISK_COL_CYLINDERS :
+ col->id;
+
+ if (fdisk_partition_to_string(pa, id, &data))
+ continue;
+ tt_line_set_data(ln, j, data);
+ }
+
+ return 0;
+}
+
+static void gap_to_freespace(
+ struct fdisk_context *cxt,
+ struct tt *tb,
+ int *cols,
+ size_t ncols,
+ uint64_t start,
+ uint64_t end)
+{
+ struct fdisk_partition pa = FDISK_EMPTY_PARTITION;
+
+ pa.freespace = 1;
+ pa.cxt = cxt;
+
+ pa.start = start;
+ pa.end = end;
+ pa.size = pa.end - pa.start + 1ULL;
+
+ DBG(LABEL, dbgprint("gap->freespace [%ju, size=%ju]",
+ pa.start, pa.size));
+
+ add_partition_to_tt(cxt, tb, cols, ncols, &pa);
+}
+
+
/**
* fdisk_list_partitions
* @cxt: fdisk context
@@ -280,13 +338,15 @@ int fdisk_list_partitions(struct fdisk_context *cxt, int *cols, size_t ncols)
const struct fdisk_column *col;
struct fdisk_partition *pa = NULL;
size_t i, j;
+ uint64_t last, grain;
if (!cxt || !cxt->label)
return -EINVAL;
if (!cxt->label->op->get_part)
return -ENOSYS;
- DBG(LABEL, dbgprint("list partitions"));
+ DBG(LABEL, dbgprint("list partitions%s",
+ fdisk_context_display_freespace(cxt) ? " and free-space" : ""));
if (!cols || !ncols) {
rc = fdisk_get_columns(cxt, 0, &cols, &ncols);
@@ -300,6 +360,9 @@ int fdisk_list_partitions(struct fdisk_context *cxt, int *cols, size_t ncols)
goto done;
}
+ last = cxt->first_lba;
+ grain = cxt->grain / cxt->sector_size;
+
/* define table columns */
for (j = 0; j < ncols; j++) {
col = fdisk_label_get_column(cxt->label, cols[j]);
@@ -314,35 +377,31 @@ int fdisk_list_partitions(struct fdisk_context *cxt, int *cols, size_t ncols)
/* generate per-partition lines into table */
for (i = 0; i < cxt->label->nparts_max; i++) {
- struct tt_line *ln;
-
rc = fdisk_get_partition(cxt, i, &pa);
if (rc)
continue;
if (!fdisk_partition_is_used(pa))
continue;
- ln = tt_add_line(tb, NULL);
- if (!ln)
- continue;
- /* set data for the columns */
- for (j = 0; j < ncols; j++) {
- char *data = NULL;
- int id;
-
- col = fdisk_label_get_column(cxt->label, cols[j]);
- if (!col)
- continue;
- id = (col->id == FDISK_COL_SECTORS &&
- fdisk_context_use_cylinders(cxt)) ?
- FDISK_COL_CYLINDERS :
- col->id;
-
- rc = fdisk_partition_to_string(pa, id, &data);
- if (rc)
- continue;
- tt_line_set_data(ln, j, data);
+ /* add free-space (before partition) to the list */
+ if (fdisk_context_display_freespace(cxt) &&
+ last + grain < pa->start) {
+ gap_to_freespace(cxt, tb, cols, ncols,
+ last + (last > cxt->first_lba ? 1 : 0),
+ pa->start - 1);
}
+ last = pa->end;
+
+ /* add partition to the list */
+ add_partition_to_tt(cxt, tb, cols, ncols, pa);
+ }
+
+ /* add free-space (behind last partition) to the list */
+ if (fdisk_context_display_freespace(cxt) &&
+ last + grain < cxt->total_sectors - 1) {
+ gap_to_freespace(cxt, tb, cols, ncols,
+ last + (last > cxt->first_lba ? 1 : 0),
+ cxt->total_sectors - 1);
}
if (!tt_is_empty(tb))
diff --git a/libfdisk/src/libfdisk.h b/libfdisk/src/libfdisk.h
index f49377471..22741d80f 100644
--- a/libfdisk/src/libfdisk.h
+++ b/libfdisk/src/libfdisk.h
@@ -97,6 +97,10 @@ extern const char *fdisk_context_get_unit(struct fdisk_context *cxt, int n);
extern unsigned int fdisk_context_get_units_per_sector(struct fdisk_context *cxt);
extern int fdisk_context_enable_details(struct fdisk_context *cxt, int enable);
+extern int fdisk_context_enable_freespace(struct fdisk_context *cxt, int enable);
+extern int fdisk_context_use_cylinders(struct fdisk_context *cxt);
+extern int fdisk_context_display_details(struct fdisk_context *cxt);
+extern int fdisk_context_display_freespace(struct fdisk_context *cxt);
/* parttype.c */
extern struct fdisk_parttype *fdisk_get_parttype_from_code(struct fdisk_context *cxt,
@@ -178,6 +182,7 @@ extern int fdisk_partition_toggle_flag(struct fdisk_context *cxt, size_t partnum
extern struct fdisk_partition *fdisk_new_partition(void);
extern void fdisk_reset_partition(struct fdisk_partition *pa);
extern void fdisk_free_partition(struct fdisk_partition *pa);
+extern int fdisk_partition_is_freespace(struct fdisk_partition *pa);
extern int fdisk_partition_set_start(struct fdisk_partition *pa, uint64_t off);
extern uint64_t fdisk_partition_get_start(struct fdisk_partition *pa);
extern int fdisk_partition_set_end(struct fdisk_partition *pa, uint64_t off, int isrel);
diff --git a/libfdisk/src/partition.c b/libfdisk/src/partition.c
index 65cdc9f48..57c5eb976 100644
--- a/libfdisk/src/partition.c
+++ b/libfdisk/src/partition.c
@@ -170,6 +170,11 @@ int fdisk_partition_is_used(struct fdisk_partition *pa)
return pa && pa->used;
}
+int fdisk_partition_is_freespace(struct fdisk_partition *pa)
+{
+ return pa && pa->freespace;
+}
+
int fdisk_partition_next_partno(
struct fdisk_context *cxt,
struct fdisk_partition *pa,
@@ -233,7 +238,9 @@ int fdisk_partition_to_string(struct fdisk_partition *pa,
switch (id) {
case FDISK_COL_DEVICE:
- if (pa->cxt->label->flags & FDISK_LABEL_FL_INCHARS_PARTNO)
+ if (pa->freespace)
+ p = strdup(_("Free space"));
+ else if (pa->cxt->label->flags & FDISK_LABEL_FL_INCHARS_PARTNO)
rc = asprintf(&p, "%c", (int) pa->partno + 'a');
else
p = fdisk_partname(pa->cxt->dev_path, pa->partno + 1);