From 2ca61a61e13cc61bc8782f8dde0f8fece6a4eca6 Mon Sep 17 00:00:00 2001 From: Davidlohr Bueso Date: Tue, 24 Jul 2012 09:54:52 +0200 Subject: [PATCH] fdisk: API: add verify to label operations [kzak@redhat.com: - rename some functions] Signed-off-by: Davidlohr Bueso Signed-off-by: Karel Zak --- fdisks/fdisk.c | 86 +++++------------------------------------- fdisks/fdisk.h | 8 ++++ fdisks/fdiskaixlabel.c | 1 + fdisks/fdiskbsdlabel.c | 3 +- fdisks/fdiskdoslabel.c | 65 +++++++++++++++++++++++++++++++ fdisks/fdiskmaclabel.c | 1 + fdisks/fdisksgilabel.c | 29 +++++++------- fdisks/fdisksgilabel.h | 1 - fdisks/fdisksunlabel.c | 7 +++- fdisks/fdisksunlabel.h | 1 - fdisks/utils.c | 16 ++++++++ 11 files changed, 122 insertions(+), 96 deletions(-) diff --git a/fdisks/fdisk.c b/fdisks/fdisk.c index 355e313cbf..2b0f91a822 100644 --- a/fdisks/fdisk.c +++ b/fdisks/fdisk.c @@ -919,7 +919,8 @@ long2chs(struct fdisk_context *cxt, unsigned long ls, *s = ls % cxt->geom.sectors + 1; /* sectors count from 1 */ } -static void check_consistency(struct fdisk_context *cxt, struct partition *p, int partition) { +void check_consistency(struct fdisk_context *cxt, struct partition *p, int partition) +{ unsigned int pbc, pbh, pbs; /* physical beginning c, h, s */ unsigned int pec, peh, pes; /* physical ending c, h, s */ unsigned int lbc, lbh, lbs; /* logical beginning c, h, s */ @@ -970,8 +971,7 @@ static void check_consistency(struct fdisk_context *cxt, struct partition *p, in } } -static void -check_alignment(struct fdisk_context *cxt, sector_t lba, int partition) +void check_alignment(struct fdisk_context *cxt, sector_t lba, int partition) { if (!lba_is_aligned(cxt, lba)) printf(_("Partition %i does not start on physical sector boundary.\n"), @@ -1273,9 +1273,10 @@ void fill_bounds(sector_t *first, sector_t *last) } } -static void -check(struct fdisk_context *cxt, int n, unsigned int h, unsigned int s, unsigned int c, - unsigned int start) { +void check(struct fdisk_context *cxt, int n, + unsigned int h, unsigned int s, unsigned int c, + unsigned int start) +{ unsigned int total, real_s, real_c; real_s = sector(s) - 1; @@ -1299,79 +1300,12 @@ check(struct fdisk_context *cxt, int n, unsigned int h, unsigned int s, unsigned "total %d\n"), n, start, total); } -static void -verify(struct fdisk_context *cxt) { - int i, j; - sector_t total = 1, n_sectors = cxt->total_sectors; - unsigned long long first[partitions], last[partitions]; - struct partition *p; - +static void verify(struct fdisk_context *cxt) +{ if (warn_geometry(cxt)) return; - if (disklabel == SUN_LABEL) { - verify_sun(cxt); - return; - } - - if (disklabel == SGI_LABEL) { - verify_sgi(cxt, 1); - return; - } - - fill_bounds(first, last); - for (i = 0; i < partitions; i++) { - struct pte *pe = &ptes[i]; - - p = pe->part_table; - if (p->sys_ind && !IS_EXTENDED (p->sys_ind)) { - check_consistency(cxt, p, i); - check_alignment(cxt, get_partition_start(pe), i); - if (get_partition_start(pe) < first[i]) - printf(_("Warning: bad start-of-data in " - "partition %d\n"), i + 1); - check(cxt, i + 1, p->end_head, p->end_sector, p->end_cyl, - last[i]); - total += last[i] + 1 - first[i]; - for (j = 0; j < i; j++) - if ((first[i] >= first[j] && first[i] <= last[j]) - || ((last[i] <= last[j] && last[i] >= first[j]))) { - printf(_("Warning: partition %d overlaps " - "partition %d.\n"), j + 1, i + 1); - total += first[i] >= first[j] ? - first[i] : first[j]; - total -= last[i] <= last[j] ? - last[i] : last[j]; - } - } - } - - if (extended_offset) { - struct pte *pex = &ptes[ext_index]; - sector_t e_last = get_start_sect(pex->part_table) + - get_nr_sects(pex->part_table) - 1; - - for (i = 4; i < partitions; i++) { - total++; - p = ptes[i].part_table; - if (!p->sys_ind) { - if (i != 4 || i + 1 < partitions) - printf(_("Warning: partition %d " - "is empty\n"), i + 1); - } - else if (first[i] < extended_offset || - last[i] > e_last) - printf(_("Logical partition %d not entirely in " - "partition %d\n"), i + 1, ext_index + 1); - } - } - - if (total > n_sectors) - printf(_("Total allocated sectors %llu greater than the maximum" - " %llu\n"), total, n_sectors); - else if (total < n_sectors) - printf(_("Remaining %lld unallocated %ld-byte sectors\n"), - n_sectors - total, cxt->sector_size); + fdisk_verify_disklabel(cxt); } void print_partition_size(struct fdisk_context *cxt, diff --git a/fdisks/fdisk.h b/fdisks/fdisk.h index 975ac4d9a3..7f85020f15 100644 --- a/fdisks/fdisk.h +++ b/fdisks/fdisk.h @@ -139,6 +139,8 @@ struct fdisk_label { int (*probe)(struct fdisk_context *cxt); /* write in-memory changes to disk */ int (*write)(struct fdisk_context *cxt); + /* verify the partition table */ + int (*verify)(struct fdisk_context *cxt); /* new partition */ void (*part_add)(struct fdisk_context *cxt, int partnum, int parttype); /* delete partition */ @@ -169,11 +171,17 @@ extern int fdisk_create_default_disklabel(struct fdisk_context *cxt); extern int fdisk_delete_partition(struct fdisk_context *cxt, int partnum); extern int fdisk_add_partition(struct fdisk_context *cxt, int partnum, int parttype); extern int fdisk_write_disklabel(struct fdisk_context *cxt); +extern int fdisk_verify_disklabel(struct fdisk_context *cxt); /* prototypes for fdisk.c */ extern char *disk_device, *line_ptr; extern int fd, partitions; extern unsigned int display_in_cyl_units, units_per_sector; + +extern void check_consistency(struct fdisk_context *cxt, struct partition *p, int partition); +extern void check_alignment(struct fdisk_context *cxt, sector_t lba, int partition); +extern void check(struct fdisk_context *cxt, int n, unsigned int h, unsigned int s, unsigned int c, unsigned int start); + extern void change_units(struct fdisk_context *cxt); extern void fatal(struct fdisk_context *cxt, enum failure why); extern int get_partition(struct fdisk_context *cxt, int warn, int max); diff --git a/fdisks/fdiskaixlabel.c b/fdisks/fdiskaixlabel.c index c01af3dbc0..c692b0848c 100644 --- a/fdisks/fdiskaixlabel.c +++ b/fdisks/fdiskaixlabel.c @@ -79,6 +79,7 @@ const struct fdisk_label aix_label = .name = "aix", .probe = aix_probe_label, .write = NULL, + .verify = NULL, .part_add = aix_add_partition, .part_delete = NULL, }; diff --git a/fdisks/fdiskbsdlabel.c b/fdisks/fdiskbsdlabel.c index 7e8f2ba120..3492aa83cf 100644 --- a/fdisks/fdiskbsdlabel.c +++ b/fdisks/fdiskbsdlabel.c @@ -846,6 +846,7 @@ const struct fdisk_label bsd_label = .name = "bsd", .probe = osf_probe_label, .write = xbsd_write_disklabel, - .part_add= xbsd_add_part, + .verify = NULL, + .part_add = xbsd_add_part, .part_delete = xbsd_delete_part, }; diff --git a/fdisks/fdiskdoslabel.c b/fdisks/fdiskdoslabel.c index fde31a7a81..f81ada53a5 100644 --- a/fdisks/fdiskdoslabel.c +++ b/fdisks/fdiskdoslabel.c @@ -643,6 +643,70 @@ static void add_logical(struct fdisk_context *cxt) add_partition(cxt, partitions - 1, LINUX_NATIVE); } +static int dos_verify_disklabel(struct fdisk_context *cxt) +{ + int i, j; + sector_t total = 1, n_sectors = cxt->total_sectors; + unsigned long long first[partitions], last[partitions]; + struct partition *p; + + fill_bounds(first, last); + for (i = 0; i < partitions; i++) { + struct pte *pe = &ptes[i]; + + p = pe->part_table; + if (p->sys_ind && !IS_EXTENDED (p->sys_ind)) { + check_consistency(cxt, p, i); + check_alignment(cxt, get_partition_start(pe), i); + if (get_partition_start(pe) < first[i]) + printf(_("Warning: bad start-of-data in " + "partition %d\n"), i + 1); + check(cxt, i + 1, p->end_head, p->end_sector, p->end_cyl, + last[i]); + total += last[i] + 1 - first[i]; + for (j = 0; j < i; j++) + if ((first[i] >= first[j] && first[i] <= last[j]) + || ((last[i] <= last[j] && last[i] >= first[j]))) { + printf(_("Warning: partition %d overlaps " + "partition %d.\n"), j + 1, i + 1); + total += first[i] >= first[j] ? + first[i] : first[j]; + total -= last[i] <= last[j] ? + last[i] : last[j]; + } + } + } + + if (extended_offset) { + struct pte *pex = &ptes[ext_index]; + sector_t e_last = get_start_sect(pex->part_table) + + get_nr_sects(pex->part_table) - 1; + + for (i = 4; i < partitions; i++) { + total++; + p = ptes[i].part_table; + if (!p->sys_ind) { + if (i != 4 || i + 1 < partitions) + printf(_("Warning: partition %d " + "is empty\n"), i + 1); + } + else if (first[i] < extended_offset || + last[i] > e_last) + printf(_("Logical partition %d not entirely in " + "partition %d\n"), i + 1, ext_index + 1); + } + } + + if (total > n_sectors) + printf(_("Total allocated sectors %llu greater than the maximum" + " %llu\n"), total, n_sectors); + else if (total < n_sectors) + printf(_("Remaining %lld unallocated %ld-byte sectors\n"), + n_sectors - total, cxt->sector_size); + + return 0; +} + /* * Ask the user for new partition type information (logical, extended). * This function calls the actual partition adding logic - add_partition. @@ -757,6 +821,7 @@ const struct fdisk_label dos_label = .name = "dos", .probe = dos_probe_label, .write = dos_write_disklabel, + .verify = dos_verify_disklabel, .part_add = dos_add_partition, .part_delete = dos_delete_partition, }; diff --git a/fdisks/fdiskmaclabel.c b/fdisks/fdiskmaclabel.c index d69a920984..28eaa93b22 100644 --- a/fdisks/fdiskmaclabel.c +++ b/fdisks/fdiskmaclabel.c @@ -94,6 +94,7 @@ const struct fdisk_label mac_label = .name = "mac", .probe = mac_probe_label, .write = NULL, + .verify = NULL, .part_add = mac_add_partition, .part_delete = NULL, }; diff --git a/fdisks/fdisksgilabel.c b/fdisks/fdisksgilabel.c index 62fae99dfe..65f6dde648 100644 --- a/fdisks/fdisksgilabel.c +++ b/fdisks/fdisksgilabel.c @@ -391,17 +391,6 @@ compare_start(struct fdisk_context *cxt, const void *x, const void *y) { return (a > b) ? 1 : -1; } -static int -sgi_gaps(struct fdisk_context *cxt) { - /* - * returned value is: - * = 0 : disk is properly filled to the rim - * < 0 : there is an overlap - * > 0 : there is still some vacant space - */ - return verify_sgi(cxt, 0); -} - static void generic_swap(void *a, void *b, int size) { char t; @@ -450,13 +439,11 @@ static void sort(void *base, size_t num, size_t size, struct fdisk_context *cxt, } } - -int -verify_sgi(struct fdisk_context *cxt, int verbose) +static int sgi_verify_disklabel(struct fdisk_context *cxt) { int Index[16]; /* list of valid partitions */ int sortcount = 0; /* number of used partitions, i.e. non-zero lengths */ - int entire = 0, i = 0; + int entire = 0, i = 0, verbose = 1; unsigned int start = 0; long long gap = 0; /* count unused blocks */ unsigned int lastblock = sgi_get_lastblock(cxt); @@ -575,6 +562,17 @@ verify_sgi(struct fdisk_context *cxt, int verbose) return (gap > 0) ? 1 : (gap == 0) ? 0 : -1; } +static int +sgi_gaps(struct fdisk_context *cxt) { + /* + * returned value is: + * = 0 : disk is properly filled to the rim + * < 0 : there is an overlap + * > 0 : there is still some vacant space + */ + return sgi_verify_disklabel(cxt); +} + int sgi_change_sysid(struct fdisk_context *cxt, int i, int sys) { @@ -902,6 +900,7 @@ const struct fdisk_label sgi_label = .name = "sgi", .probe = sgi_probe_label, .write = sgi_write_disklabel, + .verify = sgi_verify_disklabel, .part_add = sgi_add_partition, .part_delete = sgi_delete_partition, }; diff --git a/fdisks/fdisksgilabel.h b/fdisks/fdisksgilabel.h index 83cf55effd..cf52bdd036 100644 --- a/fdisks/fdisksgilabel.h +++ b/fdisks/fdisksgilabel.h @@ -118,7 +118,6 @@ extern unsigned int sgi_get_num_sectors(struct fdisk_context *cxt, int i ); extern int sgi_get_sysid(struct fdisk_context *cxt, int i ); extern void create_sgilabel( struct fdisk_context *cxt ); extern void create_sgiinfo(struct fdisk_context *cxt); -extern int verify_sgi(struct fdisk_context *cxt, int verbose ); extern void sgi_set_ilfact( void ); extern void sgi_set_rspeed( void ); extern void sgi_set_pcylcount( void ); diff --git a/fdisks/fdisksunlabel.c b/fdisks/fdisksunlabel.c index 9743725758..31c263ee43 100644 --- a/fdisks/fdisksunlabel.c +++ b/fdisks/fdisksunlabel.c @@ -295,7 +295,7 @@ static int verify_sun_cmp(int *a, int *b) return -1; } -void verify_sun(struct fdisk_context *cxt) +static int sun_verify_disklabel(struct fdisk_context *cxt) { uint32_t starts[SUN_NUM_PARTITIONS], lens[SUN_NUM_PARTITIONS], start, stop; uint32_t i,j,k,starto,endo; @@ -347,7 +347,7 @@ void verify_sun(struct fdisk_context *cxt) if (array[0] == -1) { printf(_("No partitions defined\n")); - return; + return 0; } stop = cxt->geom.cylinders * cxt->geom.heads * cxt->geom.sectors; if (starts[array[0]]) @@ -360,6 +360,8 @@ void verify_sun(struct fdisk_context *cxt) start = (starts[array[i]] + lens[array[i]]); if (start < stop) printf(_("Unused gap - sectors %d-%d\n"), start, stop); + + return 0; } static void sun_add_partition(struct fdisk_context *cxt, int n, int sys) @@ -652,6 +654,7 @@ const struct fdisk_label sun_label = .name = "sun", .probe = sun_probe_label, .write = sun_write_disklabel, + .verify = sun_verify_disklabel, .part_add = sun_add_partition, .part_delete = sun_delete_partition, }; diff --git a/fdisks/fdisksunlabel.h b/fdisks/fdisksunlabel.h index 47c7cf8698..86db5fbc9e 100644 --- a/fdisks/fdisksunlabel.h +++ b/fdisks/fdisksunlabel.h @@ -80,7 +80,6 @@ extern struct systypes sun_sys_types[]; extern int create_sunlabel(struct fdisk_context *cxt); extern int sun_change_sysid(struct fdisk_context *cxt, int i, uint16_t sys); extern void sun_list_table(struct fdisk_context *cxt, int xtra); -extern void verify_sun(struct fdisk_context *cxt); extern void sun_set_alt_cyl(struct fdisk_context *cxt); extern void sun_set_ncyl(struct fdisk_context *cxt, int cyl); extern void sun_set_xcyl(struct fdisk_context *cxt); diff --git a/fdisks/utils.c b/fdisks/utils.c index 4ab9f630ac..9ed2ca97f4 100644 --- a/fdisks/utils.c +++ b/fdisks/utils.c @@ -63,6 +63,22 @@ int fdisk_write_disklabel(struct fdisk_context *cxt) return cxt->label->write(cxt); } +/** + * fdisk_verify_disklabel: + * @cxt: fdisk context + * + * Verifies the partition tabe. + * + * Returns 0. + */ +int fdisk_verify_disklabel(struct fdisk_context *cxt) +{ + if (!cxt) + return -EINVAL; + + return cxt->label->verify(cxt); +} + /* * fdisk_add_partition: * @cxt: fdisk context -- 2.47.3