diff options
author | Karel Zak | 2012-12-05 14:32:20 +0100 |
---|---|---|
committer | Karel Zak | 2013-03-11 11:20:40 +0100 |
commit | 9475cc78ff5318fb659a7b90bb181f9c9522de02 (patch) | |
tree | 5a084b4eb71dfd2fad97d51b879fde061d9e0209 /fdisks | |
parent | libfdisk: add parttype code (diff) | |
download | kernel-qcow2-util-linux-9475cc78ff5318fb659a7b90bb181f9c9522de02.tar.gz kernel-qcow2-util-linux-9475cc78ff5318fb659a7b90bb181f9c9522de02.tar.xz kernel-qcow2-util-linux-9475cc78ff5318fb659a7b90bb181f9c9522de02.zip |
libfdisk: add alignment code
Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'fdisks')
-rw-r--r-- | fdisks/fdisk.c | 91 | ||||
-rw-r--r-- | fdisks/fdisk.h | 9 | ||||
-rw-r--r-- | fdisks/fdiskdoslabel.c | 6 | ||||
-rw-r--r-- | fdisks/gpt.c | 6 |
4 files changed, 8 insertions, 104 deletions
diff --git a/fdisks/fdisk.c b/fdisks/fdisk.c index dd06b9b22..f34617f08 100644 --- a/fdisks/fdisk.c +++ b/fdisks/fdisk.c @@ -288,86 +288,6 @@ test_c(char **m, char *mesg) { return val; } -static int -lba_is_aligned(struct fdisk_context *cxt, sector_t lba) -{ - unsigned int granularity = max(cxt->phy_sector_size, cxt->min_io_size); - unsigned long long offset; - - if (cxt->grain > granularity) - granularity = cxt->grain; - offset = (lba * cxt->sector_size) & (granularity - 1); - - return !((granularity + cxt->alignment_offset - offset) & (granularity - 1)); -} - -static int -lba_is_phy_aligned(struct fdisk_context *cxt, unsigned long long lba) -{ - unsigned int granularity = max(cxt->phy_sector_size, cxt->min_io_size); - unsigned long long offset = (lba * cxt->sector_size) & (granularity - 1); - - return !((granularity + cxt->alignment_offset - offset) & (granularity - 1)); -} - -sector_t align_lba(struct fdisk_context *cxt, sector_t lba, int direction) -{ - sector_t res; - - if (lba_is_aligned(cxt, lba)) - res = lba; - else { - sector_t sects_in_phy = cxt->grain / cxt->sector_size; - - if (lba < cxt->first_lba) - res = cxt->first_lba; - - else if (direction == ALIGN_UP) - res = ((lba + sects_in_phy) / sects_in_phy) * sects_in_phy; - - else if (direction == ALIGN_DOWN) - res = (lba / sects_in_phy) * sects_in_phy; - - else /* ALIGN_NEAREST */ - res = ((lba + sects_in_phy / 2) / sects_in_phy) * sects_in_phy; - - if (cxt->alignment_offset && !lba_is_aligned(cxt, res) && - res > cxt->alignment_offset / cxt->sector_size) { - /* - * apply alignment_offset - * - * On disk with alignment compensation physical blocks starts - * at LBA < 0 (usually LBA -1). It means we have to move LBA - * according the offset to be on the physical boundary. - */ - /* fprintf(stderr, "LBA: %llu apply alignment_offset\n", res); */ - res -= (max(cxt->phy_sector_size, cxt->min_io_size) - - cxt->alignment_offset) / cxt->sector_size; - - if (direction == ALIGN_UP && res < lba) - res += sects_in_phy; - } - } - - return res; -} - - -sector_t align_lba_in_range(struct fdisk_context *cxt, - sector_t lba, sector_t start, sector_t stop) -{ - start = align_lba(cxt, start, ALIGN_UP); - stop = align_lba(cxt, stop, ALIGN_DOWN); - - lba = align_lba(cxt, lba, ALIGN_NEAREST); - - if (lba < start) - return start; - else if (lba > stop) - return stop; - return lba; -} - int warn_geometry(struct fdisk_context *cxt) { char *m = NULL; @@ -862,13 +782,6 @@ void check_consistency(struct fdisk_context *cxt, struct partition *p, int parti } } -void check_alignment(struct fdisk_context *cxt, sector_t lba, int partition) -{ - if (!lba_is_phy_aligned(cxt, lba)) - printf(_("Partition %i does not start on physical sector boundary.\n"), - partition + 1); -} - static void list_disk_geometry(struct fdisk_context *cxt) { unsigned long long bytes = cxt->total_sectors * cxt->sector_size; @@ -1111,7 +1024,7 @@ static void list_table(struct fdisk_context *cxt, int xtra) /* type id */ p->sys_ind, /* type name */ type ? type->name : _("Unknown")); check_consistency(cxt, p, i); - check_alignment(cxt, get_partition_start(pe), i); + fdisk_warn_alignment(cxt, get_partition_start(pe), i); } } @@ -1146,7 +1059,7 @@ x_list_table(struct fdisk_context *cxt, int extend) { (unsigned long) get_nr_sects(p), p->sys_ind); if (p->sys_ind) { check_consistency(cxt, p, i); - check_alignment(cxt, get_partition_start(pe), i); + fdisk_warn_alignment(cxt, get_partition_start(pe), i); } } } diff --git a/fdisks/fdisk.h b/fdisks/fdisk.h index 82313c91e..4ea9b3b9c 100644 --- a/fdisks/fdisk.h +++ b/fdisks/fdisk.h @@ -26,9 +26,6 @@ #define LINUX_LVM 0x8e #define LINUX_RAID 0xfd -#define ALIGN_UP 1 -#define ALIGN_DOWN 2 -#define ALIGN_NEAREST 3 #define LINE_LENGTH 800 @@ -95,16 +92,12 @@ extern struct fdisk_parttype *fdisk_get_partition_type(struct fdisk_context *cxt extern int fdisk_set_partition_type(struct fdisk_context *cxt, int partnum, struct fdisk_parttype *t); -extern sector_t fdisk_topology_get_first_lba(struct fdisk_context *cxt); -extern unsigned long fdisk_topology_get_grain(struct fdisk_context *cxt); - /* prototypes for fdisk.c */ extern char *line_ptr; extern int 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 fatal(struct fdisk_context *cxt, enum failure why); @@ -132,8 +125,6 @@ extern void warn_limits(struct fdisk_context *cxt); extern unsigned int read_int_with_suffix(struct fdisk_context *cxt, unsigned int low, unsigned int dflt, unsigned int high, unsigned int base, char *mesg, int *is_suffix_used); -extern sector_t align_lba(struct fdisk_context *cxt, sector_t lba, int direction); -extern sector_t align_lba_in_range(struct fdisk_context *cxt, sector_t lba, sector_t start, sector_t stop); extern int get_partition_dflt(struct fdisk_context *cxt, int warn, int max, int dflt); #define PLURAL 0 diff --git a/fdisks/fdiskdoslabel.c b/fdisks/fdiskdoslabel.c index ab940a010..45343c838 100644 --- a/fdisks/fdiskdoslabel.c +++ b/fdisks/fdiskdoslabel.c @@ -590,7 +590,7 @@ static int add_partition(struct fdisk_context *cxt, int n, struct fdisk_parttype /* the default sector should be aligned and unused */ do { - aligned = align_lba_in_range(cxt, dflt, dflt, limit); + aligned = fdisk_align_lba_in_range(cxt, dflt, dflt, limit); dflt = get_unused_start(cxt, n, aligned, first, last); } while (dflt != aligned && dflt > aligned && dflt < limit); @@ -664,7 +664,7 @@ static int add_partition(struct fdisk_context *cxt, int n, struct fdisk_parttype * and align the end of the partition. The next * partition will start at phy.block boundary. */ - stop = align_lba_in_range(cxt, stop, start, limit) - 1; + stop = fdisk_align_lba_in_range(cxt, stop, start, limit) - 1; if (stop > limit) stop = limit; } @@ -721,7 +721,7 @@ static int dos_verify_disklabel(struct fdisk_context *cxt) 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); + fdisk_warn_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); diff --git a/fdisks/gpt.c b/fdisks/gpt.c index 87efd2550..0784d639a 100644 --- a/fdisks/gpt.c +++ b/fdisks/gpt.c @@ -1144,7 +1144,7 @@ void gpt_list_table(struct fdisk_context *cxt, t->name, name); - check_alignment(cxt, start, i); + fdisk_warn_alignment(cxt, start, i); free(name); free(sizestr); @@ -1516,7 +1516,7 @@ static int gpt_add_partition(struct fdisk_context *cxt, int partnum, dflt_l = find_last_free(pheader, ents, dflt_f); /* align the default in range <dflt_f,dflt_l>*/ - dflt_f = align_lba_in_range(cxt, dflt_f, dflt_f, dflt_l); + dflt_f = fdisk_align_lba_in_range(cxt, dflt_f, dflt_f, dflt_l); if (t && t->typestr) string_to_uuid(t->typestr, &uuid); @@ -1550,7 +1550,7 @@ static int gpt_add_partition(struct fdisk_context *cxt, int partnum, &is_suffix_used); if (is_suffix_used) - user_l = align_lba_in_range(cxt, user_l, user_f, dflt_l) - 1; + user_l = fdisk_align_lba_in_range(cxt, user_l, user_f, dflt_l) - 1; if (user_l > user_f && user_l <= disk_l) break; |