libfdisk: add support to list free space
Signed-off-by: Karel Zak <kzak@redhat.com>
This commit is contained in:
parent
77d6a70ac4
commit
1de9fddbe5
|
@ -381,6 +381,28 @@ int fdisk_context_display_details(struct fdisk_context *cxt)
|
|||
return cxt->display_details == 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue