diff options
author | Karel Zak | 2018-01-02 16:43:22 +0100 |
---|---|---|
committer | Karel Zak | 2018-01-02 16:43:22 +0100 |
commit | 2dd2880f12f402e137cbfab774fde8ceef1c71a0 (patch) | |
tree | b36ea02fbfc783f55f6f77e3eb201c0102b997a8 | |
parent | rtcwake: wait stdin to settle down before entering a system sleep (diff) | |
download | kernel-qcow2-util-linux-2dd2880f12f402e137cbfab774fde8ceef1c71a0.tar.gz kernel-qcow2-util-linux-2dd2880f12f402e137cbfab774fde8ceef1c71a0.tar.xz kernel-qcow2-util-linux-2dd2880f12f402e137cbfab774fde8ceef1c71a0.zip |
libfdisk: extend API to provide label specific geometry ranges
Now fdisk provides DOS specific geometry ranges in expert menu.
Addresses: https://github.com/karelzak/util-linux/issues/556
Signed-off-by: Karel Zak <kzak@redhat.com>
-rw-r--r-- | disk-utils/fdisk-menu.c | 34 | ||||
-rw-r--r-- | libfdisk/src/dos.c | 8 | ||||
-rw-r--r-- | libfdisk/src/fdiskP.h | 3 | ||||
-rw-r--r-- | libfdisk/src/label.c | 70 | ||||
-rw-r--r-- | libfdisk/src/libfdisk.h.in | 7 | ||||
-rw-r--r-- | libfdisk/src/libfdisk.sym | 6 | ||||
-rw-r--r-- | libfdisk/src/sun.c | 21 |
7 files changed, 138 insertions, 11 deletions
diff --git a/disk-utils/fdisk-menu.c b/disk-utils/fdisk-menu.c index 8220d6586..b8a2e6003 100644 --- a/disk-utils/fdisk-menu.c +++ b/disk-utils/fdisk-menu.c @@ -151,7 +151,7 @@ static const struct menu menu_geo = { .callback = geo_menu_cb, .exclude = FDISK_DISKLABEL_GPT | FDISK_DISKLABEL_BSD, .entries = { - MENU_XSEP(N_("Geometry")), + MENU_XSEP(N_("Geometry (for the current label)")), MENU_XENT('c', N_("change number of cylinders")), MENU_XENT('h', N_("change number of heads")), MENU_XENT('s', N_("change number of sectors/track")), @@ -1004,32 +1004,50 @@ static int bsd_menu_cb(struct fdisk_context **cxt0, return rc; } -/* C/H/S commands */ +/* C/H/S commands + * + * The geometry setting from this dialog is not persistent and maybe reseted by + * fdisk_reset_device_properties() (for example when you create a new disk + * label). Note that on command line specified -C/-H/-S setting is persistent + * as it's based on fdisk_save_user_geometry(). + */ static int geo_menu_cb(struct fdisk_context **cxt0, const struct menu *menu __attribute__((__unused__)), const struct menu_entry *ent) { struct fdisk_context *cxt = *cxt0; + struct fdisk_label *lb = fdisk_get_label(cxt, NULL); int rc = -EINVAL; uintmax_t c = 0, h = 0, s = 0; + fdisk_sector_t mi, ma; DBG(MENU, ul_debug("enter GEO menu")); assert(cxt); assert(ent); + /* default */ + if (!lb) + lb = fdisk_get_label(cxt, "dos"); + switch (ent->key) { case 'c': - rc = fdisk_ask_number(cxt, 1, fdisk_get_geom_cylinders(cxt), - 1048576, _("Number of cylinders"), &c); + fdisk_label_get_geomrange_cylinders(lb, &mi, &ma); + rc = fdisk_ask_number(cxt, mi, fdisk_get_geom_cylinders(cxt), + ma, _("Number of cylinders"), &c); break; case 'h': - rc = fdisk_ask_number(cxt, 1, fdisk_get_geom_heads(cxt), - 256, _("Number of heads"), &h); + { + unsigned int i, a; + fdisk_label_get_geomrange_heads(lb, &i, &a); + rc = fdisk_ask_number(cxt, i, fdisk_get_geom_heads(cxt), + a, _("Number of heads"), &h); break; + } case 's': - rc = fdisk_ask_number(cxt, 1, fdisk_get_geom_sectors(cxt), - 63, _("Number of sectors"), &s); + fdisk_label_get_geomrange_sectors(lb, &mi, &ma); + rc = fdisk_ask_number(cxt, mi, fdisk_get_geom_sectors(cxt), + ma, _("Number of sectors"), &s); break; } diff --git a/libfdisk/src/dos.c b/libfdisk/src/dos.c index 9759ce2e0..fd6e2cbb5 100644 --- a/libfdisk/src/dos.c +++ b/libfdisk/src/dos.c @@ -2485,6 +2485,14 @@ struct fdisk_label *fdisk_new_dos_label(struct fdisk_context *cxt) lb->fields = dos_fields; lb->nfields = ARRAY_SIZE(dos_fields); + lb->geom_min.sectors = 1; + lb->geom_min.heads = 1; + lb->geom_min.cylinders = 1; + + lb->geom_max.sectors = 63; + lb->geom_max.heads = 256; + lb->geom_max.cylinders = 1048576; + return lb; } diff --git a/libfdisk/src/fdiskP.h b/libfdisk/src/fdiskP.h index b81d6fc7a..0b9d43413 100644 --- a/libfdisk/src/fdiskP.h +++ b/libfdisk/src/fdiskP.h @@ -279,6 +279,9 @@ struct fdisk_label { int flags; /* FDISK_LABEL_FL_* flags */ + struct fdisk_geometry geom_min; /* minimal geometry */ + struct fdisk_geometry geom_max; /* maximal geometry */ + unsigned int changed:1, /* label has been modified */ disabled:1; /* this driver is disabled at all */ diff --git a/libfdisk/src/label.c b/libfdisk/src/label.c index c1afdf1b9..304ea34e4 100644 --- a/libfdisk/src/label.c +++ b/libfdisk/src/label.c @@ -628,3 +628,73 @@ int fdisk_label_is_disabled(const struct fdisk_label *lb) assert(lb); return lb ? lb->disabled : 0; } + +/** + * fdisk_label_get_geomrange_sectors: + * @lb: label + * @mi: minimal number + * @ma: maximal number + * + * The function provides minimal and maximal geometry supported for the label, + * if no range defined by library than returns -ENOSYS. + * + * Returns: 0 on success, otherwise, a corresponding error. + */ +int fdisk_label_get_geomrange_sectors(const struct fdisk_label *lb, + fdisk_sector_t *mi, fdisk_sector_t *ma) +{ + if (!lb || lb->geom_min.sectors == 0) + return -ENOSYS; + if (mi) + *mi = lb->geom_min.sectors; + if (ma) + *ma = lb->geom_max.sectors; + return 0; +} + +/** + * fdisk_label_get_geomrange_heads: + * @lb: label + * @mi: minimal number + * @ma: maximal number + * + * The function provides minimal and maximal geometry supported for the label, + * if no range defined by library than returns -ENOSYS. + * + * Returns: 0 on success, otherwise, a corresponding error. + */ +int fdisk_label_get_geomrange_heads(const struct fdisk_label *lb, + unsigned int *mi, unsigned int *ma) +{ + if (!lb || lb->geom_min.heads == 0) + return -ENOSYS; + if (mi) + *mi = lb->geom_min.heads; + if (ma) + *ma = lb->geom_max.heads; + return 0; +} + +/** + * fdisk_label_get_geomrange_cylinders: + * @lb: label + * @mi: minimal number + * @ma: maximal number + * + * The function provides minimal and maximal geometry supported for the label, + * if no range defined by library than returns -ENOSYS. + * + * Returns: 0 on success, otherwise, a corresponding error. + */ +int fdisk_label_get_geomrange_cylinders(const struct fdisk_label *lb, + fdisk_sector_t *mi, fdisk_sector_t *ma) +{ + if (!lb || lb->geom_min.cylinders == 0) + return -ENOSYS; + if (mi) + *mi = lb->geom_min.cylinders; + if (ma) + *ma = lb->geom_max.cylinders; + return 0; +} + diff --git a/libfdisk/src/libfdisk.h.in b/libfdisk/src/libfdisk.h.in index 3586d6626..ddf4a91e6 100644 --- a/libfdisk/src/libfdisk.h.in +++ b/libfdisk/src/libfdisk.h.in @@ -321,6 +321,13 @@ extern int fdisk_locate_disklabel(struct fdisk_context *cxt, int n, uint64_t *offset, size_t *size); +extern int fdisk_label_get_geomrange_cylinders(const struct fdisk_label *lb, + fdisk_sector_t *mi, fdisk_sector_t *ma); +extern int fdisk_label_get_geomrange_heads(const struct fdisk_label *lb, + unsigned int *mi, unsigned int *ma); +extern int fdisk_label_get_geomrange_sectors(const struct fdisk_label *lb, + fdisk_sector_t *mi, fdisk_sector_t *ma); + /** * fdisk_labelitem_gen: * diff --git a/libfdisk/src/libfdisk.sym b/libfdisk/src/libfdisk.sym index 2c892a0c3..8d38332b9 100644 --- a/libfdisk/src/libfdisk.sym +++ b/libfdisk/src/libfdisk.sym @@ -291,3 +291,9 @@ FDISK_2.31 { fdisk_has_dialogs; fdisk_save_user_grain; } FDISK_2.30; + +FDISK_2.32 { + fdisk_label_get_geomrange_sectors; + fdisk_label_get_geomrange_heads; + fdisk_label_get_geomrange_cylinders; +} FDISK_2.31; diff --git a/libfdisk/src/sun.c b/libfdisk/src/sun.c index 923b73e32..0be4d8df6 100644 --- a/libfdisk/src/sun.c +++ b/libfdisk/src/sun.c @@ -182,11 +182,19 @@ static void ask_geom(struct fdisk_context *cxt) assert(cxt); - if (fdisk_ask_number(cxt, 1, 1, 1024, _("Heads"), &res) == 0) + if (fdisk_ask_number(cxt, cxt->label->geom_min.heads, 1, + cxt->label->geom_max.heads, + _("Heads"), &res) == 0) cxt->geom.heads = res; - if (fdisk_ask_number(cxt, 1, 1, 1024, _("Sectors/track"), &res) == 0) + + if (fdisk_ask_number(cxt, cxt->label->geom_min.sectors, 1, + cxt->label->geom_max.sectors, + _("Sectors/track"), &res) == 0) cxt->geom.sectors = res; - if (fdisk_ask_number(cxt, 1, 1, USHRT_MAX, _("Cylinders"), &res) == 0) + + if (fdisk_ask_number(cxt, cxt->label->geom_min.cylinders, 1, + cxt->label->geom_max.cylinders, + _("Cylinders"), &res) == 0) cxt->geom.cylinders = res; } @@ -1154,5 +1162,12 @@ struct fdisk_label *fdisk_new_sun_label(struct fdisk_context *cxt) lb->nfields = ARRAY_SIZE(sun_fields); lb->flags |= FDISK_LABEL_FL_REQUIRE_GEOMETRY; + lb->geom_min.sectors = 1; + lb->geom_min.heads = 1; + lb->geom_min.cylinders = 1; + + lb->geom_max.sectors = 1024; + lb->geom_max.heads = 1024; + lb->geom_max.cylinders = USHRT_MAX; return lb; } |