fdisk: add device topology to the API

This patch adds device topology discovery to the internal API. This
functionality is static only to the API and therefore hidden from general fdisk
code. Functionality itself doesn't really change, min_io_size, io_size, logical
and physical sector sizes and alignment offset are added to the fdisk_context
structure and elements are accessed from there. The logical sector size
(sector_size) is now unsigned long instead of unsigned int, this as no effect
otherwise.

A few things to notice:
 - The patch is larger than I wanted but we need to modify function parameters
   across fdisk and its labels to use the topology data from cxt-> instances.
   Hopefully this will be pretty much it regarding this kind of modifications -
   perhaps geometry will need something of the like too.

 - The -b option must override internal discovery.

 - A new helper function has added to verify if the device provides topology
   information, this replaces the 'has_topology' global variable.

Signed-off-by: Davidlohr Bueso <dave@gnu.org>
This commit is contained in:
Davidlohr Bueso 2012-06-03 20:15:17 +02:00 committed by Karel Zak
parent 7db8141571
commit e53ced85bf
10 changed files with 329 additions and 306 deletions

View File

@ -47,9 +47,6 @@
#ifdef HAVE_LINUX_BLKPG_H
#include <linux/blkpg.h>
#endif
#ifdef HAVE_LIBBLKID
#include <blkid.h>
#endif
#include "gpt.h"
@ -144,19 +141,12 @@ sector_t sector_offset = 1, sectors;
unsigned int heads,
cylinders,
sector_size = DEFAULT_SECTOR_SIZE,
user_set_sector_size = 0,
units_per_sector = 1,
display_in_cyl_units = 0;
sector_t total_number_of_sectors; /* in logical sectors */
unsigned long grain = DEFAULT_SECTOR_SIZE,
io_size = DEFAULT_SECTOR_SIZE,
min_io_size = DEFAULT_SECTOR_SIZE,
phy_sector_size = DEFAULT_SECTOR_SIZE,
alignment_offset;
int has_topology;
unsigned long grain = DEFAULT_SECTOR_SIZE;
enum labeltype disklabel; /* Current disklabel */
static void __attribute__ ((__noreturn__)) usage(FILE *out)
@ -318,22 +308,22 @@ test_c(char **m, char *mesg) {
}
static int
lba_is_aligned(sector_t lba)
lba_is_aligned(struct fdisk_context *cxt, sector_t lba)
{
unsigned int granularity = max(phy_sector_size, min_io_size);
sector_t offset = (lba * sector_size) & (granularity - 1);
unsigned int granularity = max(cxt->phy_sector_size, cxt->min_io_size);
sector_t offset = (lba * cxt->sector_size) & (granularity - 1);
return !((granularity + alignment_offset - offset) & (granularity - 1));
return !((granularity + cxt->alignment_offset - offset) & (granularity - 1));
}
sector_t align_lba(sector_t lba, int direction)
sector_t align_lba(struct fdisk_context *cxt, sector_t lba, int direction)
{
sector_t res;
if (lba_is_aligned(lba))
if (lba_is_aligned(cxt, lba))
res = lba;
else {
sector_t sects_in_phy = grain / sector_size;
sector_t sects_in_phy = grain / cxt->sector_size;
if (lba < sector_offset)
res = sector_offset;
@ -347,8 +337,8 @@ sector_t align_lba(sector_t lba, int direction)
else /* ALIGN_NEAREST */
res = ((lba + sects_in_phy / 2) / sects_in_phy) * sects_in_phy;
if (alignment_offset && !lba_is_aligned(res) &&
res > alignment_offset / sector_size) {
if (cxt->alignment_offset && !lba_is_aligned(cxt, res) &&
res > cxt->alignment_offset / cxt->sector_size) {
/*
* apply alignment_offset
*
@ -357,8 +347,8 @@ sector_t align_lba(sector_t lba, int direction)
* according the offset to be on the physical boundary.
*/
/* fprintf(stderr, "LBA: %llu apply alignment_offset\n", res); */
res -= (max(phy_sector_size, min_io_size) -
alignment_offset) / sector_size;
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;
@ -408,31 +398,31 @@ void update_units(void)
units_per_sector = 1; /* in sectors */
}
void warn_limits(void)
void warn_limits(struct fdisk_context *cxt)
{
if (total_number_of_sectors > UINT_MAX && !nowarn) {
unsigned long long bytes = total_number_of_sectors * sector_size;
unsigned long long bytes = total_number_of_sectors * cxt->sector_size;
int giga = bytes / 1000000000;
int hectogiga = (giga + 50) / 100;
fprintf(stderr, _("\n"
"WARNING: The size of this disk is %d.%d TB (%llu bytes).\n"
"DOS partition table format can not be used on drives for volumes\n"
"larger than (%llu bytes) for %d-byte sectors. Use parted(1) and GUID \n"
"larger than (%llu bytes) for %ld-byte sectors. Use parted(1) and GUID \n"
"partition table format (GPT).\n\n"),
hectogiga / 10, hectogiga % 10,
bytes,
(sector_t ) UINT_MAX * sector_size,
sector_size);
(sector_t ) UINT_MAX * cxt->sector_size,
cxt->sector_size);
}
}
void warn_alignment(void)
void warn_alignment(struct fdisk_context *cxt)
{
if (nowarn)
return;
if (sector_size != phy_sector_size)
if (cxt->sector_size != cxt->phy_sector_size)
fprintf(stderr, _("\n"
"The device presents a logical sector size that is smaller than\n"
"the physical sector size. Aligning to a physical sector (or optimal\n"
@ -450,64 +440,6 @@ void warn_alignment(void)
}
static void
get_topology(struct fdisk_context *cxt) {
int arg;
#ifdef HAVE_LIBBLKID
blkid_probe pr;
pr = blkid_new_probe();
if (pr && blkid_probe_set_device(pr, cxt->dev_fd, 0, 0) == 0) {
blkid_topology tp = blkid_probe_get_topology(pr);
if (tp) {
min_io_size = blkid_topology_get_minimum_io_size(tp);
io_size = blkid_topology_get_optimal_io_size(tp);
phy_sector_size = blkid_topology_get_physical_sector_size(tp);
alignment_offset = blkid_topology_get_alignment_offset(tp);
/* We assume that the device provides topology info if
* optimal_io_size is set or alignment_offset is set or
* minimum_io_size is not power of 2.
*
* See also update_sector_offset().
*/
if (io_size || alignment_offset ||
(min_io_size & (min_io_size - 1)))
has_topology = 1;
if (!io_size)
/* optimal IO is optional, default to minimum IO */
io_size = min_io_size;
}
}
blkid_free_probe(pr);
#endif
if (user_set_sector_size)
/* fdisk since 2.17 differentiate between logical and physical
* sectors size. For backward compatibility the
* fdisk -b <sectorsize>
* changes both, logical and physical sector size.
*/
phy_sector_size = sector_size;
else if (blkdev_get_sector_size(cxt->dev_fd, &arg) == 0) {
sector_size = arg;
if (!phy_sector_size)
phy_sector_size = sector_size;
}
if (!min_io_size)
min_io_size = phy_sector_size;
if (!io_size)
io_size = min_io_size;
if (sector_size != DEFAULT_SECTOR_SIZE)
printf(_("Note: sector size is %d (not %d)\n"),
sector_size, DEFAULT_SECTOR_SIZE);
}
static void
get_partition_table_geometry(void) {
unsigned char *bufp = MBRbuffer;
@ -544,9 +476,9 @@ get_partition_table_geometry(void) {
* Sets LBA of the first partition
*/
void
update_sector_offset(void)
update_sector_offset(struct fdisk_context *cxt)
{
grain = io_size;
grain = cxt->io_size;
if (dos_compatible_flag)
sector_offset = sectors; /* usually 63 sectors */
@ -564,29 +496,29 @@ update_sector_offset(void)
*/
sector_t x = 0;
if (has_topology) {
if (alignment_offset)
x = alignment_offset;
else if (io_size > 2048 * 512)
x = io_size;
if (fdisk_dev_has_topology(cxt)) {
if (cxt->alignment_offset)
x = cxt->alignment_offset;
else if (cxt->io_size > 2048 * 512)
x = cxt->io_size;
}
/* default to 1MiB */
if (!x)
x = 2048 * 512;
sector_offset = x / sector_size;
sector_offset = x / cxt->sector_size;
/* don't use huge offset on small devices */
if (total_number_of_sectors <= sector_offset * 4)
sector_offset = phy_sector_size / sector_size;
sector_offset = cxt->phy_sector_size / cxt->sector_size;
/* use 1MiB grain always when possible */
if (grain < 2048 * 512)
grain = 2048 * 512;
/* don't use huge grain on small devices */
if (total_number_of_sectors <= (grain * 4 / sector_size))
grain = phy_sector_size;
if (total_number_of_sectors <= (grain * 4 / cxt->sector_size))
grain = cxt->phy_sector_size;
}
}
@ -595,7 +527,6 @@ get_geometry(struct fdisk_context *cxt, struct geom *g) {
sector_t llcyls, nsects = 0;
unsigned int kern_heads = 0, kern_sectors = 0;
get_topology(cxt);
heads = cylinders = sectors = 0;
pt_heads = pt_sectors = 0;
@ -611,9 +542,9 @@ get_geometry(struct fdisk_context *cxt, struct geom *g) {
/* get number of 512-byte sectors, and convert it the real sectors */
if (blkdev_get_sectors(cxt->dev_fd, &nsects) == 0)
total_number_of_sectors = (nsects / (sector_size >> 9));
total_number_of_sectors = (nsects / (cxt->sector_size >> 9));
update_sector_offset();
update_sector_offset(cxt);
llcyls = total_number_of_sectors / (heads * sectors);
cylinders = llcyls;
@ -676,7 +607,7 @@ static int get_boot(struct fdisk_context *cxt, int try_only) {
if (check_osf_label(cxt)) {
/* intialize partitions for BSD as well */
dos_init();
dos_init(cxt);
if (!valid_part_table_flag(MBRbuffer)) {
disklabel = OSF_LABEL;
return 0;
@ -695,7 +626,7 @@ static int get_boot(struct fdisk_context *cxt, int try_only) {
#ifdef __sparc__
create_sunlabel(cxt);
#else
create_doslabel();
create_doslabel(cxt);
#endif
}
return 0;
@ -796,7 +727,8 @@ read_hex(struct systypes *sys)
}
unsigned int
read_int_with_suffix(unsigned int low, unsigned int dflt, unsigned int high,
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)
{
unsigned int res;
@ -895,7 +827,7 @@ read_int_with_suffix(unsigned int low, unsigned int dflt, unsigned int high,
unsigned long unit;
bytes = (unsigned long long) res * absolute;
unit = sector_size * units_per_sector;
unit = cxt->sector_size * units_per_sector;
bytes += unit/2; /* round */
bytes /= unit;
res = bytes;
@ -932,18 +864,19 @@ read_int_with_suffix(unsigned int low, unsigned int dflt, unsigned int high,
* There is no default if DFLT is not between LOW and HIGH.
*/
unsigned int
read_int(unsigned int low, unsigned int dflt, unsigned int high,
read_int(struct fdisk_context *cxt,
unsigned int low, unsigned int dflt, unsigned int high,
unsigned int base, char *mesg)
{
return read_int_with_suffix(low, dflt, high, base, mesg, NULL);
return read_int_with_suffix(cxt, low, dflt, high, base, mesg, NULL);
}
int
get_partition_dflt(int warn, int max, int dflt) {
get_partition_dflt(struct fdisk_context *cxt, int warn, int max, int dflt) {
struct pte *pe;
int i;
i = read_int(1, dflt, max, 0, _("Partition number")) - 1;
i = read_int(cxt, 1, dflt, max, 0, _("Partition number")) - 1;
pe = &ptes[i];
if (warn) {
@ -961,14 +894,14 @@ get_partition_dflt(int warn, int max, int dflt) {
}
int
get_partition(int warn, int max) {
return get_partition_dflt(warn, max, 0);
get_partition(struct fdisk_context *cxt, int warn, int max) {
return get_partition_dflt(cxt, warn, max, 0);
}
/* User partition selection unless one partition only is available */
static int
get_existing_partition(int warn, int max) {
get_existing_partition(struct fdisk_context *cxt, int warn, int max) {
int pno = -1;
int i;
@ -995,7 +928,7 @@ get_existing_partition(int warn, int max) {
not_implemented:
not_unique:
return get_partition(warn, max);
return get_partition(cxt, warn, max);
}
const char *
@ -1031,18 +964,18 @@ toggle_active(int i) {
}
static void
toggle_dos_compatibility_flag(void) {
toggle_dos_compatibility_flag(struct fdisk_context *cxt) {
dos_compatible_flag = ~dos_compatible_flag;
if (dos_compatible_flag)
printf(_("DOS Compatibility flag is set (DEPRECATED!)\n"));
else
printf(_("DOS Compatibility flag is not set\n"));
update_sector_offset();
update_sector_offset(cxt);
}
static void
delete_partition(int i)
delete_partition(struct fdisk_context *cxt, int i)
{
if (i < 0)
return;
@ -1057,18 +990,18 @@ delete_partition(int i)
else if (disklabel == SUN_LABEL)
sun_delete_partition(i);
else if (disklabel == SGI_LABEL)
sgi_delete_partition(i);
sgi_delete_partition(cxt, i);
printf(_("Partition %d is deleted\n"), i + 1);
}
static void
change_sysid(void) {
static void change_sysid(struct fdisk_context *cxt)
{
char *temp;
int i, sys, origsys;
struct partition *p;
i = get_existing_partition(0, partitions);
i = get_existing_partition(cxt, 0, partitions);
if (i == -1)
return;
@ -1204,16 +1137,16 @@ static void check_consistency(struct partition *p, int partition) {
}
static void
check_alignment(sector_t lba, int partition)
check_alignment(struct fdisk_context *cxt, sector_t lba, int partition)
{
if (!lba_is_aligned(lba))
if (!lba_is_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 = total_number_of_sectors * sector_size;
unsigned long long bytes = total_number_of_sectors * cxt->sector_size;
long megabytes = bytes/1000000;
if (megabytes < 10000)
@ -1229,16 +1162,16 @@ list_disk_geometry(struct fdisk_context *cxt) {
if (units_per_sector == 1)
printf(_(", total %llu sectors"), total_number_of_sectors);
printf("\n");
printf(_("Units = %s of %d * %d = %d bytes\n"),
printf(_("Units = %s of %d * %ld = %ld bytes\n"),
str_units(PLURAL),
units_per_sector, sector_size, units_per_sector * sector_size);
units_per_sector, cxt->sector_size, units_per_sector * cxt->sector_size);
printf(_("Sector size (logical/physical): %u bytes / %lu bytes\n"),
sector_size, phy_sector_size);
printf(_("Sector size (logical/physical): %lu bytes / %lu bytes\n"),
cxt->sector_size, cxt->phy_sector_size);
printf(_("I/O size (minimum/optimal): %lu bytes / %lu bytes\n"),
min_io_size, io_size);
if (alignment_offset)
printf(_("Alignment offset: %lu bytes\n"), alignment_offset);
cxt->min_io_size, cxt->io_size);
if (cxt->alignment_offset)
printf(_("Alignment offset: %lu bytes\n"), cxt->alignment_offset);
if (disklabel == DOS_LABEL)
dos_print_mbr_id();
printf("\n");
@ -1428,12 +1361,12 @@ list_table(struct fdisk_context *cxt, int xtra) {
unsigned int pblocks = psects;
unsigned int podd = 0;
if (sector_size < 1024) {
pblocks /= (1024 / sector_size);
podd = psects % (1024 / sector_size);
if (cxt->sector_size < 1024) {
pblocks /= (1024 / cxt->sector_size);
podd = psects % (1024 / cxt->sector_size);
}
if (sector_size > 1024)
pblocks *= (sector_size / 1024);
if (cxt->sector_size > 1024)
pblocks *= (cxt->sector_size / 1024);
printf(
"%s %c %11lu %11lu %11lu%c %2x %s\n",
partname(cxt->dev_path, i+1, w+2),
@ -1447,7 +1380,7 @@ list_table(struct fdisk_context *cxt, int xtra) {
/* type name */ (type = partition_type(p->sys_ind)) ?
type : _("Unknown"));
check_consistency(p, i);
check_alignment(get_partition_start(pe), i);
check_alignment(cxt, get_partition_start(pe), i);
}
}
@ -1482,7 +1415,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(p, i);
check_alignment(get_partition_start(pe), i);
check_alignment(cxt, get_partition_start(pe), i);
}
}
}
@ -1533,7 +1466,7 @@ check(int n, unsigned int h, unsigned int s, unsigned int c,
}
static void
verify(void) {
verify(struct fdisk_context *cxt) {
int i, j;
sector_t total = 1, n_sectors = total_number_of_sectors;
unsigned long long first[partitions], last[partitions];
@ -1559,7 +1492,7 @@ verify(void) {
p = pe->part_table;
if (p->sys_ind && !IS_EXTENDED (p->sys_ind)) {
check_consistency(p, i);
check_alignment(get_partition_start(pe), 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);
@ -1603,30 +1536,31 @@ verify(void) {
printf(_("Total allocated sectors %llu greater than the maximum"
" %llu\n"), total, n_sectors);
else if (total < n_sectors)
printf(_("Remaining %lld unallocated %d-byte sectors\n"),
n_sectors - total, sector_size);
printf(_("Remaining %lld unallocated %ld-byte sectors\n"),
n_sectors - total, cxt->sector_size);
}
void print_partition_size(int num, sector_t start, sector_t stop, int sysid)
void print_partition_size(struct fdisk_context *cxt,
int num, sector_t start, sector_t stop, int sysid)
{
char *str = size_to_human_string(SIZE_SUFFIX_3LETTER | SIZE_SUFFIX_SPACE,
(stop - start + 1) * sector_size);
(stop - start + 1) * cxt->sector_size);
printf(_("Partition %d of type %s and of size %s is set\n"), num, partition_type(sysid), str);
free(str);
}
static void new_partition(void)
static void new_partition(struct fdisk_context *cxt)
{
if (warn_geometry())
return;
if (disklabel == SUN_LABEL) {
add_sun_partition(get_partition(0, partitions), LINUX_NATIVE);
add_sun_partition(cxt, get_partition(cxt, 0, partitions), LINUX_NATIVE);
return;
}
if (disklabel == SGI_LABEL) {
sgi_add_partition(get_partition(0, partitions), LINUX_NATIVE);
sgi_add_partition(cxt, get_partition(cxt, 0, partitions), LINUX_NATIVE);
return;
}
@ -1649,7 +1583,7 @@ static void new_partition(void)
}
/* default to DOS/BSD */
dos_new_partition();
dos_new_partition(cxt);
}
static void
@ -1719,10 +1653,10 @@ reread_partition_table(struct fdisk_context *cxt, int leave) {
#define MAX_PER_LINE 16
static void
print_buffer(unsigned char pbuffer[]) {
print_buffer(struct fdisk_context *cxt, unsigned char pbuffer[]) {
unsigned int i, l;
for (i = 0, l = 0; i < sector_size; i++, l++) {
for (i = 0, l = 0; i < cxt->sector_size; i++, l++) {
if (l == 0)
printf("0x%03X:", i);
printf(" %02X", pbuffer[i]);
@ -1736,19 +1670,19 @@ print_buffer(unsigned char pbuffer[]) {
printf("\n");
}
static void
print_raw(char *dev) {
static void print_raw(struct fdisk_context *cxt)
{
int i;
printf(_("Device: %s\n"), dev);
printf(_("Device: %s\n"), cxt->dev_path);
if (disklabel == SUN_LABEL || disklabel == SGI_LABEL)
print_buffer(MBRbuffer);
print_buffer(cxt, MBRbuffer);
else for (i = 3; i < partitions; i++)
print_buffer(ptes[i].sectorbuffer);
print_buffer(cxt, ptes[i].sectorbuffer);
}
static void
move_begin(int i) {
move_begin(struct fdisk_context *cxt, int i) {
struct pte *pe = &ptes[i];
struct partition *p = pe->part_table;
unsigned int new, free_start, curr_start, last;
@ -1785,7 +1719,7 @@ move_begin(int i) {
last = get_partition_start(pe) + get_nr_sects(p) - 1;
new = read_int(free_start, curr_start, last, free_start,
new = read_int(cxt, free_start, curr_start, last, free_start,
_("New beginning of data")) - pe->offset;
if (new != get_nr_sects(p)) {
@ -1814,27 +1748,27 @@ expert_command_prompt(struct fdisk_context *cxt)
switch (c) {
case 'a':
if (disklabel == SUN_LABEL)
sun_set_alt_cyl();
sun_set_alt_cyl(cxt);
break;
case 'b':
if (disklabel == DOS_LABEL)
move_begin(get_partition(0, partitions));
move_begin(cxt, get_partition(cxt, 0, partitions));
break;
case 'c':
user_cylinders = cylinders =
read_int(1, cylinders, 1048576, 0,
read_int(cxt, 1, cylinders, 1048576, 0,
_("Number of cylinders"));
if (disklabel == SUN_LABEL)
sun_set_ncyl(cylinders);
break;
case 'd':
print_raw(cxt->dev_path);
print_raw(cxt);
break;
case 'e':
if (disklabel == SGI_LABEL)
sgi_set_xcyl();
else if (disklabel == SUN_LABEL)
sun_set_xcyl();
sun_set_xcyl(cxt);
else
if (disklabel == DOS_LABEL)
x_list_table(cxt, 1);
@ -1847,19 +1781,19 @@ expert_command_prompt(struct fdisk_context *cxt)
create_sgilabel(cxt);
break;
case 'h':
user_heads = heads = read_int(1, heads, 256, 0,
user_heads = heads = read_int(cxt, 1, heads, 256, 0,
_("Number of heads"));
update_units();
break;
case 'i':
if (disklabel == SUN_LABEL)
sun_set_ilfact();
sun_set_ilfact(cxt);
else if (disklabel == DOS_LABEL)
dos_set_mbr_id();
break;
case 'o':
if (disklabel == SUN_LABEL)
sun_set_rspeed();
sun_set_rspeed(cxt);
break;
case 'p':
if (disklabel == SUN_LABEL)
@ -1872,24 +1806,24 @@ expert_command_prompt(struct fdisk_context *cxt)
case 'r':
return;
case 's':
user_sectors = sectors = read_int(1, sectors, 63, 0,
user_sectors = sectors = read_int(cxt, 1, sectors, 63, 0,
_("Number of sectors"));
if (dos_compatible_flag)
fprintf(stderr, _("Warning: setting "
"sector offset for DOS "
"compatiblity\n"));
update_sector_offset();
update_sector_offset(cxt);
update_units();
break;
case 'v':
verify();
verify(cxt);
break;
case 'w':
write_table(cxt);
break;
case 'y':
if (disklabel == SUN_LABEL)
sun_set_pcylcount();
sun_set_pcylcount(cxt);
break;
default:
print_menu(EXPERT_MENU);
@ -1918,15 +1852,15 @@ gpt_warning(char *dev)
}
/* Print disk geometry and partition table of a specified device (-l option) */
static void
print_partition_table_from_option(char *device)
static void print_partition_table_from_option(char *device, unsigned long sector_size)
{
int gb;
struct fdisk_context *cxt = fdisk_new_context_from_filename(device, 1); /* read-only */
if (!cxt)
err(EXIT_FAILURE, _("unable to open %s"), device);
if (sector_size) /* passed -b option, override autodiscovery */
cxt->phy_sector_size = cxt->sector_size = sector_size;
gpt_warning(device);
gb = get_boot(cxt, 1);
@ -1946,7 +1880,7 @@ print_partition_table_from_option(char *device)
* try all things in /proc/partitions that look like a full disk
*/
static void
print_all_partition_table_from_option(void)
print_all_partition_table_from_option(unsigned long sector_size)
{
FILE *procpt;
char line[128], ptname[128], devname[256];
@ -1968,7 +1902,7 @@ print_all_partition_table_from_option(void)
char *cn = canonicalize_path(devname);
if (cn) {
if (!is_ide_cdrom_or_tape(cn))
print_partition_table_from_option(cn);
print_partition_table_from_option(cn, sector_size);
free(cn);
}
}
@ -2011,13 +1945,13 @@ static void command_prompt(struct fdisk_context *cxt)
switch (c) {
case 'a':
if (disklabel == DOS_LABEL)
toggle_active(get_partition(1, partitions));
toggle_active(get_partition(cxt, 1, partitions));
else if (disklabel == SUN_LABEL)
toggle_sunflags(get_partition(1, partitions),
toggle_sunflags(get_partition(cxt, 1, partitions),
SUN_FLAG_UNMNT);
else if (disklabel == SGI_LABEL)
sgi_set_bootpartition(
get_partition(1, partitions));
get_partition(cxt, 1, partitions));
else
unknown_command(c);
break;
@ -2033,18 +1967,18 @@ static void command_prompt(struct fdisk_context *cxt)
break;
case 'c':
if (disklabel == DOS_LABEL)
toggle_dos_compatibility_flag();
toggle_dos_compatibility_flag(cxt);
else if (disklabel == SUN_LABEL)
toggle_sunflags(get_partition(1, partitions),
toggle_sunflags(get_partition(cxt, 1, partitions),
SUN_FLAG_RONLY);
else if (disklabel == SGI_LABEL)
sgi_set_swappartition(
get_partition(1, partitions));
get_partition(cxt, 1, partitions));
else
unknown_command(c);
break;
case 'd':
delete_partition(get_existing_partition(1, partitions));
delete_partition(cxt, get_existing_partition(cxt, 1, partitions));
break;
case 'i':
if (disklabel == SGI_LABEL)
@ -2059,10 +1993,10 @@ static void command_prompt(struct fdisk_context *cxt)
print_menu(MAIN_MENU);
break;
case 'n':
new_partition();
new_partition(cxt);
break;
case 'o':
create_doslabel();
create_doslabel(cxt);
break;
case 'p':
list_table(cxt, 0);
@ -2073,13 +2007,13 @@ static void command_prompt(struct fdisk_context *cxt)
create_sunlabel(cxt);
break;
case 't':
change_sysid();
change_sysid(cxt);
break;
case 'u':
change_units();
break;
case 'v':
verify();
verify(cxt);
break;
case 'w':
write_table(cxt);
@ -2112,6 +2046,7 @@ static sector_t get_dev_blocks(char *dev)
int main(int argc, char **argv)
{
int c, optl = 0, opts = 0;
unsigned long sector_size = 0;
struct fdisk_context *cxt = NULL;
setlocale(LC_ALL, "");
@ -2191,9 +2126,9 @@ int main(int argc, char **argv)
if (argc > optind) {
int k;
for (k = optind; k < argc; k++)
print_partition_table_from_option(argv[k]);
print_partition_table_from_option(argv[k], sector_size);
} else
print_all_partition_table_from_option();
print_all_partition_table_from_option(sector_size);
exit(0);
}
@ -2216,6 +2151,8 @@ int main(int argc, char **argv)
cxt = fdisk_new_context_from_filename(argv[optind], 0);
if (!cxt)
err(EXIT_FAILURE, _("unable to open %s"), argv[optind]);
if (user_set_sector_size) /* passed -b option, override autodiscovery */
cxt->phy_sector_size = cxt->sector_size = sector_size;
}
else
usage(stderr);

View File

@ -105,9 +105,17 @@ typedef unsigned long long sector_t;
struct fdisk_context {
int dev_fd; /* device descriptor */
char *dev_path; /* device path */
/* topology */
unsigned long io_size;
unsigned long min_io_size;
unsigned long phy_sector_size; /* physical size */
unsigned long sector_size; /* logical size */
unsigned long alignment_offset;
};
extern struct fdisk_context *fdisk_new_context_from_filename(const char *fname, int readonly);
extern int fdisk_dev_has_topology(struct fdisk_context *cxt);
extern void fdisk_free_context(struct fdisk_context *cxt);
/* prototypes for fdisk.c */
@ -117,7 +125,7 @@ extern unsigned int display_in_cyl_units, units_per_sector;
extern void change_units(void);
extern void fatal(struct fdisk_context *cxt, enum failure why);
extern void get_geometry(struct fdisk_context *, struct geom *);
extern int get_partition(int warn, int max);
extern int get_partition(struct fdisk_context *cxt, int warn, int max);
extern void list_types(struct systypes *sys);
extern int read_line (int *asked);
extern char read_char(char *mesg);
@ -125,14 +133,15 @@ extern int read_hex(struct systypes *sys);
extern void reread_partition_table(struct fdisk_context *cxt, int leave);
extern struct partition *get_part_table(int);
extern int valid_part_table_flag(unsigned char *b);
extern unsigned int read_int(unsigned int low, unsigned int dflt,
extern unsigned int read_int(struct fdisk_context *cxt,
unsigned int low, unsigned int dflt,
unsigned int high, unsigned int base, char *mesg);
extern void print_menu(enum menutype);
extern void print_partition_size(int num, sector_t start, sector_t stop, int sysid);
extern void print_partition_size(struct fdisk_context *cxt, int num, sector_t start, sector_t stop, int sysid);
extern void zeroize_mbr_buffer(void);
extern void fill_bounds(sector_t *first, sector_t *last);
extern unsigned int heads, cylinders, sector_size;
extern unsigned int heads, cylinders;
extern sector_t sectors;
extern char *partition_type(unsigned char type);
extern void update_units(void);
@ -140,12 +149,13 @@ extern char read_chars(char *mesg);
extern void set_changed(int);
extern void set_all_unchanged(void);
extern int warn_geometry(void);
extern void warn_limits(void);
extern void warn_alignment(void);
extern unsigned int read_int_with_suffix(unsigned int low, unsigned int dflt, unsigned int high,
extern void warn_limits(struct fdisk_context *cxt);
extern void warn_alignment(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(sector_t lba, int direction);
extern int get_partition_dflt(int warn, int max, int dflt);
extern sector_t align_lba(struct fdisk_context *cxt, sector_t lba, int direction);
extern int get_partition_dflt(struct fdisk_context *cxt, int warn, int max, int dflt);
#define PLURAL 0
#define SINGULAR 1
@ -202,7 +212,7 @@ static inline void set_start_sect(struct partition *p, unsigned int start_sect)
static inline void seek_sector(struct fdisk_context *cxt, sector_t secno)
{
off_t offset = (off_t) secno * sector_size;
off_t offset = (off_t) secno * cxt->sector_size;
if (lseek(cxt->dev_fd, offset, SEEK_SET) == (off_t) -1)
fatal(cxt, unable_to_seek);
}
@ -210,14 +220,14 @@ static inline void seek_sector(struct fdisk_context *cxt, sector_t secno)
static inline void read_sector(struct fdisk_context *cxt, sector_t secno, unsigned char *buf)
{
seek_sector(cxt, secno);
if (read(cxt->dev_fd, buf, sector_size) != sector_size)
if (read(cxt->dev_fd, buf, cxt->sector_size) != cxt->sector_size)
fatal(cxt, unable_to_read);
}
static inline void write_sector(struct fdisk_context *cxt, sector_t secno, unsigned char *buf)
{
seek_sector(cxt, secno);
if (write(cxt->dev_fd, buf, sector_size) != sector_size)
if (write(cxt->dev_fd, buf, cxt->sector_size) != cxt->sector_size)
fatal(cxt, unable_to_write);
}

View File

@ -62,7 +62,7 @@
#include "fdiskbsdlabel.h"
static void xbsd_delete_part (void);
static void xbsd_new_part (void);
static void xbsd_new_part (struct fdisk_context *cxt);
static void xbsd_write_disklabel (struct fdisk_context *cxt);
static int xbsd_create_disklabel (struct fdisk_context *cxt);
static void xbsd_edit_disklabel (void);
@ -86,7 +86,7 @@ void alpha_bootblock_checksum (char *boot);
#if !defined (__alpha__)
static int xbsd_translate_fstype (int linux_type);
static void xbsd_link_part (void);
static void xbsd_link_part (struct fdisk_context *cxt);
static struct partition *xbsd_part;
static int xbsd_part_index;
#endif
@ -196,7 +196,7 @@ bsd_command_prompt (struct fdisk_context *cxt)
xbsd_list_types ();
break;
case 'n':
xbsd_new_part ();
xbsd_new_part (cxt);
break;
case 'p':
xbsd_print_disklabel (cxt, 0);
@ -220,7 +220,7 @@ bsd_command_prompt (struct fdisk_context *cxt)
break;
#if !defined (__alpha__)
case 'x':
xbsd_link_part ();
xbsd_link_part (cxt);
break;
#endif
default:
@ -245,7 +245,7 @@ xbsd_delete_part (void)
}
static void
xbsd_new_part (void)
xbsd_new_part (struct fdisk_context *cxt)
{
unsigned int begin, end;
char mesg[256];
@ -263,7 +263,7 @@ xbsd_new_part (void)
#endif
snprintf (mesg, sizeof(mesg), _("First %s"), str_units(SINGULAR));
begin = read_int (bsd_cround (begin), bsd_cround (begin), bsd_cround (end),
begin = read_int (cxt, bsd_cround (begin), bsd_cround (begin), bsd_cround (end),
0, mesg);
if (display_in_cyl_units)
@ -271,7 +271,7 @@ xbsd_new_part (void)
snprintf (mesg, sizeof(mesg), _("Last %s or +size or +sizeM or +sizeK"),
str_units(SINGULAR));
end = read_int (bsd_cround (begin), bsd_cround (end), bsd_cround (end),
end = read_int (cxt, bsd_cround (begin), bsd_cround (end), bsd_cround (end),
bsd_cround (begin), mesg);
if (display_in_cyl_units)
@ -810,12 +810,12 @@ xbsd_translate_fstype (int linux_type)
}
static void
xbsd_link_part (void)
xbsd_link_part (struct fdisk_context *cxt)
{
int k, i;
struct partition *p;
k = get_partition (1, partitions);
k = get_partition (cxt, 1, partitions);
if (!xbsd_check_new_partition (&i))
return;

View File

@ -22,13 +22,13 @@
s |= (sector >> 2) & 0xc0; \
}
#define alignment_required (grain != sector_size)
#define alignment_required (grain != cxt->sector_size)
struct pte ptes[MAXIMUM_PARTS];
sector_t extended_offset;
int ext_index;
static int get_nonexisting_partition(int warn, int max)
static int get_nonexisting_partition(struct fdisk_context *cxt, int warn, int max)
{
int pno = -1;
int i;
@ -54,7 +54,7 @@ static int get_nonexisting_partition(int warn, int max)
return -1;
not_unique:
return get_partition_dflt(warn, max, dflt);
return get_partition_dflt(cxt, warn, max, dflt);
}
@ -64,7 +64,7 @@ static void read_pte(struct fdisk_context *cxt, int pno, sector_t offset)
struct pte *pe = &ptes[pno];
pe->offset = offset;
pe->sectorbuffer = xmalloc(sector_size);
pe->sectorbuffer = xmalloc(cxt->sector_size);
read_sector(cxt, offset, pe->sectorbuffer);
pe->changed = 0;
pe->part_table = pe->ext_pointer = NULL;
@ -96,7 +96,7 @@ static void clear_partition(struct partition *p)
set_nr_sects(p,0);
}
void dos_init(void)
void dos_init(struct fdisk_context *cxt)
{
int i;
@ -116,8 +116,8 @@ void dos_init(void)
}
warn_geometry();
warn_limits();
warn_alignment();
warn_limits(cxt);
warn_alignment(cxt);
}
static void read_extended(struct fdisk_context *cxt, int ext)
@ -219,7 +219,7 @@ void dos_print_mbr_id(void)
printf(_("Disk identifier: 0x%08x\n"), dos_read_mbr_id(MBRbuffer));
}
void create_doslabel(void)
void create_doslabel(struct fdisk_context *cxt)
{
unsigned int id;
@ -228,7 +228,7 @@ void create_doslabel(void)
fprintf(stderr, _("Building a new DOS disklabel with disk identifier 0x%08x.\n"), id);
dos_init();
dos_init(cxt);
zeroize_mbr_buffer();
set_all_unchanged();
@ -324,7 +324,7 @@ int check_dos_label(struct fdisk_context *cxt)
if (!valid_part_table_flag(MBRbuffer))
return 0;
dos_init();
dos_init(cxt);
for (i = 0; i < 4; i++) {
struct pte *pe = &ptes[i];
@ -368,7 +368,8 @@ int is_dos_partition(int t)
t == 0xc1 || t == 0xc4 || t == 0xc6);
}
static void set_partition(int i, int doext, sector_t start,
static void set_partition(struct fdisk_context *cxt,
int i, int doext, sector_t start,
sector_t stop, int sysid)
{
struct partition *p;
@ -387,7 +388,7 @@ static void set_partition(int i, int doext, sector_t start,
set_nr_sects(p, stop - start + 1);
if (!doext)
print_partition_size(i + 1, start, stop, sysid);
print_partition_size(cxt, i + 1, start, stop, sysid);
if (dos_compatible_flag && (start/(sectors*heads) > 1023))
start = heads*sectors*1024 - 1;
@ -416,12 +417,13 @@ static sector_t get_unused_start(int part_n, sector_t start,
return start;
}
static sector_t align_lba_in_range(sector_t lba, sector_t start, sector_t stop)
static sector_t align_lba_in_range(struct fdisk_context *cxt,
sector_t lba, sector_t start, sector_t stop)
{
start = align_lba(start, ALIGN_UP);
stop = align_lba(stop, ALIGN_DOWN);
start = align_lba(cxt, start, ALIGN_UP);
stop = align_lba(cxt, stop, ALIGN_DOWN);
lba = align_lba(lba, ALIGN_NEAREST);
lba = align_lba(cxt, lba, ALIGN_NEAREST);
if (lba < start)
return start;
@ -430,7 +432,7 @@ static sector_t align_lba_in_range(sector_t lba, sector_t start, sector_t stop)
return lba;
}
void dos_add_partition(int n, int sys)
void dos_add_partition(struct fdisk_context *cxt, int n, int sys)
{
char mesg[256]; /* 48 does not suffice in Japanese */
int i, read = 0;
@ -477,7 +479,7 @@ void dos_add_partition(int n, int sys)
/* the default sector should be aligned and unused */
do {
aligned = align_lba_in_range(dflt, dflt, limit);
aligned = align_lba_in_range(cxt, dflt, dflt, limit);
dflt = get_unused_start(n, aligned, first, last);
} while (dflt != aligned && dflt > aligned && dflt < limit);
@ -493,7 +495,7 @@ void dos_add_partition(int n, int sys)
if (!read && start == temp) {
sector_t i = start;
start = read_int(cround(i), cround(dflt), cround(limit),
start = read_int(cxt, cround(i), cround(dflt), cround(limit),
0, mesg);
if (display_in_cyl_units) {
start = (start - 1) * units_per_sector;
@ -536,8 +538,9 @@ void dos_add_partition(int n, int sys)
_("Last %1$s, +%2$s or +size{K,M,G}"),
str_units(SINGULAR), str_units(PLURAL));
stop = read_int_with_suffix(cround(start), cround(limit), cround(limit),
cround(start), mesg, &is_suffix_used);
stop = read_int_with_suffix(cxt,
cround(start), cround(limit), cround(limit),
cround(start), mesg, &is_suffix_used);
if (display_in_cyl_units) {
stop = stop * units_per_sector - 1;
if (stop >limit)
@ -550,15 +553,15 @@ void dos_add_partition(int n, int sys)
* and align the end of the partition. The next
* partition will start at phy.block boundary.
*/
stop = align_lba_in_range(stop, start, limit) - 1;
stop = align_lba_in_range(cxt, stop, start, limit) - 1;
if (stop > limit)
stop = limit;
}
}
set_partition(n, 0, start, stop, sys);
set_partition(cxt, n, 0, start, stop, sys);
if (n > 4)
set_partition(n - 1, 1, ptes[n].offset, stop, EXTENDED);
set_partition(cxt, n - 1, 1, ptes[n].offset, stop, EXTENDED);
if (IS_EXTENDED (sys)) {
struct pte *pe4 = &ptes[4];
@ -567,7 +570,7 @@ void dos_add_partition(int n, int sys)
ext_index = n;
pen->ext_pointer = p;
pe4->offset = extended_offset = start;
pe4->sectorbuffer = xcalloc(1, sector_size);
pe4->sectorbuffer = xcalloc(1, cxt->sector_size);
pe4->part_table = pt_offset(pe4->sectorbuffer, 0);
pe4->ext_pointer = pe4->part_table + 1;
pe4->changed = 1;
@ -575,12 +578,12 @@ void dos_add_partition(int n, int sys)
}
}
static void add_logical(void)
static void add_logical(struct fdisk_context *cxt)
{
if (partitions > 5 || ptes[4].part_table->sys_ind) {
struct pte *pe = &ptes[partitions];
pe->sectorbuffer = xcalloc(1, sector_size);
pe->sectorbuffer = xcalloc(1, cxt->sector_size);
pe->part_table = pt_offset(pe->sectorbuffer, 0);
pe->ext_pointer = pe->part_table + 1;
pe->offset = 0;
@ -588,14 +591,14 @@ static void add_logical(void)
partitions++;
}
printf(_("Adding logical partition %d\n"), partitions);
dos_add_partition(partitions - 1, LINUX_NATIVE);
dos_add_partition(cxt, partitions - 1, LINUX_NATIVE);
}
/*
* Ask the user for new partition type information (logical, extended).
* This function calls the actual partition adding logic - dos_add_partition.
*/
void dos_new_partition(void)
void dos_new_partition(struct fdisk_context *cxt)
{
int i, free_primary = 0;
@ -610,14 +613,14 @@ void dos_new_partition(void)
if (!free_primary) {
if (extended_offset) {
printf(_("All primary partitions are in use\n"));
add_logical();
add_logical(cxt);
} else
printf(_("If you want to create more than four partitions, you must replace a\n"
"primary partition with an extended partition first.\n"));
} else if (partitions >= MAXIMUM_PARTS) {
printf(_("All logical partitions are in use\n"));
printf(_("Adding a primary partition\n"));
dos_add_partition(get_partition(0, 4), LINUX_NATIVE);
dos_add_partition(cxt, get_partition(cxt, 0, 4), LINUX_NATIVE);
} else {
char c, dflt, line[LINE_LENGTH];
@ -637,17 +640,17 @@ void dos_new_partition(void)
printf(_("Using default response %c\n"), c);
}
if (c == 'p') {
int i = get_nonexisting_partition(0, 4);
int i = get_nonexisting_partition(cxt, 0, 4);
if (i >= 0)
dos_add_partition(i, LINUX_NATIVE);
dos_add_partition(cxt, i, LINUX_NATIVE);
return;
} else if (c == 'l' && extended_offset) {
add_logical();
add_logical(cxt);
return;
} else if (c == 'e' && !extended_offset) {
int i = get_nonexisting_partition(0, 4);
int i = get_nonexisting_partition(cxt, 0, 4);
if (i >= 0)
dos_add_partition(i, EXTENDED);
dos_add_partition(cxt, i, EXTENDED);
return;
} else
printf(_("Invalid partition type `%c'\n"), c);

View File

@ -43,15 +43,15 @@ static inline sector_t get_partition_start(struct pte *pe)
return pe->offset + get_start_sect(pe->part_table);
}
extern void create_doslabel(void);
extern void create_doslabel(struct fdisk_context *cxt);
extern void dos_print_mbr_id(void);
extern void dos_set_mbr_id(void);
extern void dos_delete_partition(int i);
extern int check_dos_label(struct fdisk_context *cxt);
extern int is_dos_partition(int t);
extern void dos_init(void);
extern void dos_add_partition(int n, int sys);
extern void dos_new_partition(void);
extern void dos_init(struct fdisk_context *cxt);
extern void dos_add_partition(struct fdisk_context *cxt, int n, int sys);
extern void dos_new_partition(struct fdisk_context *cxt);
extern void dos_write_table(struct fdisk_context *cxt);
#endif

View File

@ -190,20 +190,20 @@ sgi_list_table(struct fdisk_context *cxt, int xtra) {
"%d cylinders, %d physical cylinders\n"
"%d extra sects/cyl, interleave %d:1\n"
"%s\n"
"Units = %s of %d * %d bytes\n\n"),
"Units = %s of %d * %ld bytes\n\n"),
cxt->dev_path, heads, sectors, cylinders,
SSWAP16(sgiparam.pcylcount),
(int) sgiparam.sparecyl, SSWAP16(sgiparam.ilfact),
(char *)sgilabel,
str_units(PLURAL), units_per_sector,
sector_size);
cxt->sector_size);
} else {
printf(_("\nDisk %s (SGI disk label): "
"%d heads, %llu sectors, %d cylinders\n"
"Units = %s of %d * %d bytes\n\n"),
"Units = %s of %d * %ld bytes\n\n"),
cxt->dev_path, heads, sectors, cylinders,
str_units(PLURAL), units_per_sector,
sector_size);
cxt->sector_size);
}
printf(_("----- partitions -----\n"
"Pt# %*s Info Start End Sectors Id System\n"),
@ -563,7 +563,8 @@ sgi_entire(void) {
}
static void
sgi_set_partition(int i, unsigned int start, unsigned int length, int sys) {
sgi_set_partition(struct fdisk_context *cxt,
int i, unsigned int start, unsigned int length, int sys) {
sgilabel->partitions[i].id = SSWAP32(sys);
sgilabel->partitions[i].num_sectors = SSWAP32(length);
sgilabel->partitions[i].start_sector = SSWAP32(start);
@ -571,16 +572,16 @@ sgi_set_partition(int i, unsigned int start, unsigned int length, int sys) {
if (sgi_gaps() < 0) /* rebuild freelist */
printf(_("Partition overlap on the disk.\n"));
if (length)
print_partition_size(i + 1, start, start + length, sys);
print_partition_size(cxt, i + 1, start, start + length, sys);
}
static void
sgi_set_entire(void) {
sgi_set_entire(struct fdisk_context *cxt) {
int n;
for (n=10; n<partitions; n++) {
if (!sgi_get_num_sectors(n)) {
sgi_set_partition(n, 0, sgi_get_lastblock(), SGI_VOLUME);
sgi_set_partition(cxt, n, 0, sgi_get_lastblock(), SGI_VOLUME);
break;
}
}
@ -588,7 +589,7 @@ sgi_set_entire(void) {
static
void
sgi_set_volhdr(void)
sgi_set_volhdr(struct fdisk_context *cxt)
{
int n;
@ -599,20 +600,20 @@ sgi_set_volhdr(void)
* as IRIX fx uses.
*/
if (4096 < sgi_get_lastblock())
sgi_set_partition(n, 0, 4096, SGI_VOLHDR);
sgi_set_partition(cxt, n, 0, 4096, SGI_VOLHDR);
break;
}
}
}
void
sgi_delete_partition(int i)
sgi_delete_partition(struct fdisk_context *cxt, int i)
{
sgi_set_partition(i, 0, 0, 0);
sgi_set_partition(cxt, i, 0, 0, 0);
}
void
sgi_add_partition(int n, int sys)
sgi_add_partition(struct fdisk_context *cxt, int n, int sys)
{
char mesg[256];
unsigned int first=0, last=0;
@ -630,8 +631,8 @@ sgi_add_partition(int n, int sys)
if ((sgi_entire() == -1)
&& (sys != SGI_VOLUME)) {
printf(_("Attempting to generate entire disk entry automatically.\n"));
sgi_set_entire();
sgi_set_volhdr();
sgi_set_entire(cxt);
sgi_set_volhdr(cxt);
}
if ((sgi_gaps() == 0) && (sys != SGI_VOLUME)) {
printf(_("The entire disk is already covered with partitions.\n"));
@ -645,7 +646,7 @@ sgi_add_partition(int n, int sys)
for (;;) {
if (sys == SGI_VOLUME) {
last = sgi_get_lastblock();
first = read_int(0, 0, last-1, 0, mesg);
first = read_int(cxt, 0, 0, last-1, 0, mesg);
if (first != 0) {
printf(_("It is highly recommended that eleventh partition\n"
"covers the entire disk and is of type `SGI volume'\n"));
@ -653,7 +654,7 @@ sgi_add_partition(int n, int sys)
} else {
first = freelist[0].first;
last = freelist[0].last;
first = read_int(scround(first), scround(first), scround(last)-1,
first = read_int(cxt, scround(first), scround(first), scround(last)-1,
0, mesg);
}
if (display_in_cyl_units)
@ -669,7 +670,7 @@ sgi_add_partition(int n, int sys)
break;
}
snprintf(mesg, sizeof(mesg), _(" Last %s"), str_units(SINGULAR));
last = read_int(scround(first), scround(last)-1, scround(last)-1,
last = read_int(cxt, scround(first), scround(last)-1, scround(last)-1,
scround(first), mesg)+1;
if (display_in_cyl_units)
last *= units_per_sector;
@ -678,7 +679,7 @@ sgi_add_partition(int n, int sys)
if ((sys == SGI_VOLUME) && (first != 0 || last != sgi_get_lastblock()))
printf(_("It is highly recommended that eleventh partition\n"
"covers the entire disk and is of type `SGI volume'\n"));
sgi_set_partition(n, first, last-first, sys);
sgi_set_partition(cxt, n, first, last-first, sys);
}
void
@ -695,7 +696,7 @@ create_sgilabel(struct fdisk_context *cxt)
int res; /* the result from the ioctl */
int sec_fac; /* the sector factor */
sec_fac = sector_size / 512; /* determine the sector factor */
sec_fac = cxt->sector_size / 512; /* determine the sector factor */
fprintf(stderr,
_("Building a new SGI disklabel.\n"));
@ -769,7 +770,7 @@ create_sgilabel(struct fdisk_context *cxt)
sgilabel->devparam.unused1 = SSWAP16(0);
sgilabel->devparam.nsect = SSWAP16(geometry.sectors);
/* sectors/track */
sgilabel->devparam.bytes = SSWAP16(sector_size);
sgilabel->devparam.bytes = SSWAP16(cxt->sector_size);
sgilabel->devparam.ilfact = SSWAP16(1);
sgilabel->devparam.flags = SSWAP32(TRACK_FWD|\
IGNORE_ERRORS|RESEEK);
@ -787,11 +788,11 @@ create_sgilabel(struct fdisk_context *cxt)
disklabel = SGI_LABEL;
partitions = 16;
volumes = 15;
sgi_set_entire();
sgi_set_volhdr();
sgi_set_entire(cxt);
sgi_set_volhdr(cxt);
for (i = 0; i < 4; i++) {
if (old[i].sysid) {
sgi_set_partition(i, old[i].start, old[i].nsect, old[i].sysid);
sgi_set_partition(cxt, i, old[i].start, old[i].nsect, old[i].sysid);
}
}
}

View File

@ -118,8 +118,8 @@ extern int sgi_change_sysid( int i, int sys );
extern unsigned int sgi_get_start_sector( int i );
extern unsigned int sgi_get_num_sectors( int i );
extern int sgi_get_sysid( int i );
extern void sgi_delete_partition( int i );
extern void sgi_add_partition( int n, int sys );
extern void sgi_delete_partition( struct fdisk_context *cxt, int i );
extern void sgi_add_partition( struct fdisk_context *cxt, int n, int sys );
extern void create_sgilabel( struct fdisk_context *cxt );
extern void create_sgiinfo( void );
extern int verify_sgi( int verbose );

View File

@ -59,7 +59,8 @@ static inline uint32_t __swap32(uint32_t x) {
#define SSWAP32(x) (other_endian ? __swap32(x) \
: (uint32_t)(x))
static void set_sun_partition(int i, uint32_t start, uint32_t stop, uint16_t sysid)
static void set_sun_partition(struct fdisk_context *cxt,
int i, uint32_t start, uint32_t stop, uint16_t sysid)
{
sunlabel->part_tags[i].tag = SSWAP16(sysid);
sunlabel->part_tags[i].flag = SSWAP16(0);
@ -68,7 +69,7 @@ static void set_sun_partition(int i, uint32_t start, uint32_t stop, uint16_t sys
sunlabel->partitions[i].num_sectors =
SSWAP32(stop - start);
set_changed(i);
print_partition_size(i + 1, start, stop, sysid);
print_partition_size(cxt, i + 1, start, stop, sysid);
}
static void init(void)
@ -173,7 +174,7 @@ void create_sunlabel(struct fdisk_context *cxt)
sunlabel->num_partitions = SSWAP16(SUN_NUM_PARTITIONS);
res = blkdev_get_sectors(cxt->dev_fd, &llsectors);
sec_fac = sector_size / 512;
sec_fac = cxt->sector_size / 512;
#ifdef HDIO_GETGEO
if (!ioctl(cxt->dev_fd, HDIO_GETGEO, &geometry)) {
@ -195,9 +196,9 @@ void create_sunlabel(struct fdisk_context *cxt)
} else
#endif
{
heads = read_int(1,1,1024,0,_("Heads"));
sectors = read_int(1,1,1024,0,_("Sectors/track"));
cylinders = read_int(1,1,65535,0,_("Cylinders"));
heads = read_int(cxt, 1,1,1024,0,_("Heads"));
sectors = read_int(cxt, 1,1,1024,0,_("Sectors/track"));
cylinders = read_int(cxt, 1,1,65535,0,_("Cylinders"));
}
sunlabel->acyl = SSWAP16(2);
@ -220,14 +221,14 @@ void create_sunlabel(struct fdisk_context *cxt)
} else
ndiv = cylinders * 2 / 3;
set_sun_partition(0, 0, ndiv * heads * sectors,
set_sun_partition(cxt, 0, 0, ndiv * heads * sectors,
SUN_TAG_LINUX_NATIVE);
set_sun_partition(1, ndiv * heads * sectors,
set_sun_partition(cxt, 1, ndiv * heads * sectors,
cylinders * heads * sectors,
SUN_TAG_LINUX_SWAP);
sunlabel->part_tags[1].flag |= SSWAP16(SUN_FLAG_UNMNT);
set_sun_partition(2, 0, cylinders * heads * sectors, SUN_TAG_BACKUP);
set_sun_partition(cxt, 2, 0, cylinders * heads * sectors, SUN_TAG_BACKUP);
{
unsigned short *ush = (unsigned short *)sunlabel;
@ -363,7 +364,7 @@ void verify_sun(void)
printf(_("Unused gap - sectors %d-%d\n"), start, stop);
}
void add_sun_partition(int n, int sys)
void add_sun_partition(struct fdisk_context *cxt, int n, int sys)
{
uint32_t starts[SUN_NUM_PARTITIONS], lens[SUN_NUM_PARTITIONS];
struct sun_partition *part = &sunlabel->partitions[n];
@ -394,9 +395,9 @@ void add_sun_partition(int n, int sys)
snprintf(mesg, sizeof(mesg), _("First %s"), str_units(SINGULAR));
for (;;) {
if (whole_disk)
first = read_int(0, 0, 0, 0, mesg);
first = read_int(cxt, 0, 0, 0, 0, mesg);
else
first = read_int(scround(start), scround(stop)+1,
first = read_int(cxt, scround(start), scround(stop)+1,
scround(stop), 0, mesg);
if (display_in_cyl_units)
first *= units_per_sector;
@ -451,13 +452,13 @@ and is of type `Whole disk'\n"));
_("Last %s or +size or +sizeM or +sizeK"),
str_units(SINGULAR));
if (whole_disk)
last = read_int(scround(stop2), scround(stop2), scround(stop2),
last = read_int(cxt, scround(stop2), scround(stop2), scround(stop2),
0, mesg);
else if (n == 2 && !first)
last = read_int(scround(first), scround(stop2), scround(stop2),
last = read_int(cxt, scround(first), scround(stop2), scround(stop2),
scround(first), mesg);
else
last = read_int(scround(first), scround(stop), scround(stop),
last = read_int(cxt, scround(first), scround(stop), scround(stop),
scround(first), mesg);
if (display_in_cyl_units)
last *= units_per_sector;
@ -480,7 +481,7 @@ and is of type `Whole disk'\n"));
if (whole_disk)
sys = SUN_TAG_BACKUP;
set_sun_partition(n, first, last, sys);
set_sun_partition(cxt, n, first, last, sys);
}
void sun_delete_partition(int i)
@ -586,10 +587,10 @@ void sun_list_table(struct fdisk_context *cxt, int xtra)
}
}
void sun_set_alt_cyl(void)
void sun_set_alt_cyl(struct fdisk_context *cxt)
{
sunlabel->acyl =
SSWAP16(read_int(0,SSWAP16(sunlabel->acyl), 65535, 0,
SSWAP16(read_int(cxt, 0,SSWAP16(sunlabel->acyl), 65535, 0,
_("Number of alternate cylinders")));
}
@ -598,31 +599,31 @@ void sun_set_ncyl(int cyl)
sunlabel->ncyl = SSWAP16(cyl);
}
void sun_set_xcyl(void)
void sun_set_xcyl(struct fdisk_context *cxt)
{
sunlabel->apc =
SSWAP16(read_int(0, SSWAP16(sunlabel->apc), sectors, 0,
SSWAP16(read_int(cxt, 0, SSWAP16(sunlabel->apc), sectors, 0,
_("Extra sectors per cylinder")));
}
void sun_set_ilfact(void)
void sun_set_ilfact(struct fdisk_context *cxt)
{
sunlabel->intrlv =
SSWAP16(read_int(1, SSWAP16(sunlabel->intrlv), 32, 0,
SSWAP16(read_int(cxt, 1, SSWAP16(sunlabel->intrlv), 32, 0,
_("Interleave factor")));
}
void sun_set_rspeed(void)
void sun_set_rspeed(struct fdisk_context *cxt)
{
sunlabel->rpm =
SSWAP16(read_int(1, SSWAP16(sunlabel->rpm), 100000, 0,
SSWAP16(read_int(cxt, 1, SSWAP16(sunlabel->rpm), 100000, 0,
_("Rotation speed (rpm)")));
}
void sun_set_pcylcount(void)
void sun_set_pcylcount(struct fdisk_context *cxt)
{
sunlabel->pcyl =
SSWAP16(read_int(0, SSWAP16(sunlabel->pcyl), 65535, 0,
SSWAP16(read_int(cxt, 0, SSWAP16(sunlabel->pcyl), 65535, 0,
_("Number of physical cylinders")));
}

View File

@ -84,14 +84,14 @@ extern void sun_delete_partition(int i);
extern int sun_change_sysid(int i, uint16_t sys);
extern void sun_list_table(struct fdisk_context *cxt, int xtra);
extern void verify_sun(void);
extern void add_sun_partition(int n, int sys);
extern void add_sun_partition(struct fdisk_context *cxt, int n, int sys);
extern void sun_write_table(struct fdisk_context *cxt);
extern void sun_set_alt_cyl(void);
extern void sun_set_alt_cyl(struct fdisk_context *cxt);
extern void sun_set_ncyl(int cyl);
extern void sun_set_xcyl(void);
extern void sun_set_ilfact(void);
extern void sun_set_rspeed(void);
extern void sun_set_pcylcount(void);
extern void sun_set_xcyl(struct fdisk_context *cxt);
extern void sun_set_ilfact(struct fdisk_context *cxt);
extern void sun_set_rspeed(struct fdisk_context *cxt);
extern void sun_set_pcylcount(struct fdisk_context *cxt);
extern void toggle_sunflags(int i, uint16_t mask);
extern int sun_get_sysid(int i);

View File

@ -20,12 +20,82 @@
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#ifdef HAVE_LIBBLKID
#include <blkid.h>
#endif
#include "nls.h"
#include "blkdev.h"
#include "common.h"
#include "fdisk.h"
int fdisk_debug_mask;
static unsigned long __get_sector_size(int fd)
{
unsigned int sect_sz;
if (!blkdev_get_sector_size(fd, &sect_sz))
return (unsigned long) sect_sz;
return DEFAULT_SECTOR_SIZE;
}
static int __discover_topology(struct fdisk_context *cxt)
{
#ifdef HAVE_LIBBLKID
blkid_probe pr;
pr = blkid_new_probe();
if (pr && blkid_probe_set_device(pr, cxt->dev_fd, 0, 0) == 0) {
blkid_topology tp = blkid_probe_get_topology(pr);
if (tp) {
cxt->min_io_size = blkid_topology_get_minimum_io_size(tp);
cxt->io_size = blkid_topology_get_optimal_io_size(tp);
cxt->phy_sector_size = blkid_topology_get_physical_sector_size(tp);
cxt->alignment_offset = blkid_topology_get_alignment_offset(tp);
if (!cxt->io_size)
/* optimal IO is optional, default to minimum IO */
cxt->io_size = cxt->min_io_size;
}
}
blkid_free_probe(pr);
#endif
/* no blkid or error, use default values */
if (!cxt->min_io_size) cxt->min_io_size = DEFAULT_SECTOR_SIZE;
if (!cxt->io_size) cxt->io_size = DEFAULT_SECTOR_SIZE;
cxt->sector_size = __get_sector_size(cxt->dev_fd);
if (!cxt->phy_sector_size) /* could not discover physical size */
cxt->phy_sector_size = cxt->sector_size;
if (cxt->sector_size != DEFAULT_SECTOR_SIZE)
printf(_("Note: sector size is %ld (not %d)\n"),
cxt->sector_size, DEFAULT_SECTOR_SIZE);
return 0;
}
/**
* fdisk_dev_has_topology:
* @cxt: fdisk context
*
* Returns 1 if the device provides topology information, otherwise 0.
*/
int fdisk_dev_has_topology(struct fdisk_context *cxt)
{
/*
* Assume that the device provides topology info if
* optimal_io_size is set or alignment_offset is set or
* minimum_io_size is not power of 2.
*/
if (cxt->io_size || cxt->alignment_offset ||
(cxt->min_io_size & (cxt->min_io_size - 1)))
return 1;
return 0;
}
/**
* fdisk_init_debug:
* @mask: debug mask (0xffff to enable full debuging)
@ -81,9 +151,10 @@ struct fdisk_context *fdisk_new_context_from_filename(const char *fname, int rea
cxt->dev_path = strdup(fname);
if (!cxt->dev_path)
goto fail;
__discover_topology(cxt);
DBG(CONTEXT, dbgprint("context initialized for %s [%s]",
fname, readonly ? "READ-ONLY" : "READ-WRITE"));
fname, readonly ? "READ-ONLY" : "READ-WRITE"));
return cxt;
fail:
errsv = errno;