diff options
-rw-r--r-- | libfdisk/src/context.c | 22 | ||||
-rw-r--r-- | libfdisk/src/fdiskP.h | 5 | ||||
-rw-r--r-- | libfdisk/src/label.c | 105 | ||||
-rw-r--r-- | libfdisk/src/libfdisk.h | 5 | ||||
-rw-r--r-- | libfdisk/src/partition.c | 9 |
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); |