From 757cefbb61dd22254ae8441f7caed39be7c59483 Mon Sep 17 00:00:00 2001 From: Awal Garg Date: Sat, 28 Jul 2018 18:50:35 +0530 Subject: libfdisk: Accept negative numbers for last sector input [kzak@redhat.com: - add note to the man page - add '-' to the dialog query - cleanup functions names and libfdisk.sym] Signed-off-by: Karel Zak --- Documentation/TODO | 6 ------ disk-utils/fdisk.8 | 17 ++++++++++------- disk-utils/fdisk.c | 2 ++ libfdisk/src/ask.c | 25 +++++++++++++++++++++++++ libfdisk/src/bsd.c | 5 +++-- libfdisk/src/dos.c | 5 +++-- libfdisk/src/fdiskP.h | 4 +++- libfdisk/src/gpt.c | 3 ++- libfdisk/src/libfdisk.h.in | 1 + libfdisk/src/libfdisk.sym | 4 ++++ libfdisk/src/sgi.c | 1 + libfdisk/src/sun.c | 4 +++- 12 files changed, 57 insertions(+), 20 deletions(-) diff --git a/Documentation/TODO b/Documentation/TODO index 44c980581..22b28b005 100644 --- a/Documentation/TODO +++ b/Documentation/TODO @@ -147,12 +147,6 @@ libfdisk - add support for Apple Partition Map (see libblkid/src/partitions/mac.c) http://en.wikipedia.org/wiki/Apple_Partition_Map -fdisk ------ - - - When creating a new partition, it would be helpful if the "Last sector" - dialog accepted negative numbers, to be able to specify how far from the - end of the drive you would like the partition to end. misc ---- diff --git a/disk-utils/fdisk.8 b/disk-utils/fdisk.8 index 91c6b6f84..430c96c3d 100644 --- a/disk-utils/fdisk.8 +++ b/disk-utils/fdisk.8 @@ -33,7 +33,7 @@ All partitioning is driven by device I/O limits (the topology) by default. is able to optimize the disk layout for a 4K-sector size and use an alignment offset on modern devices for MBR and GPT. It is always a good idea to follow \fBfdisk\fR's defaults as the default values (e.g. first and last partition sectors) and partition -sizes specified by the +{M,G,...} notation are always aligned according +sizes specified by the +/-{M,G,...} notation are always aligned according to the device properties. Note that @@ -161,16 +161,19 @@ documentation (the Documentation/devices.txt file). .SH SIZES The "last sector" dialog accepts partition size specified by number of sectors -or by +{K,B,M,G,...} notation. +or by +/-{K,B,M,G,...} notation. If the size is prefixed by '+' then it is interpreted as relative to the -partition first sector. In this case the size is expected in bytes and the -number may be followed by the multiplicative suffixes KiB=1024, MiB=1024*1024, -and so on for GiB, TiB, PiB, EiB, ZiB and YiB. The "iB" is optional, e.g. "K" -has the same meaning as "KiB". +partition first sector. If the size is prefixed by '-' then it is interpreted +as relative to the high limit (last available sector for the partition). + +In the case the size is specified in bytes than the number may be followed by +the multiplicative suffixes KiB=1024, MiB=1024*1024, and so on for GiB, TiB, +PiB, EiB, ZiB and YiB. The "iB" is optional, e.g. "K" has the same meaning as +"KiB". The relative sizes are always aligned according to device I/O limits. The -+{K,B,M,G,...} notation is recommended. ++/-{K,B,M,G,...} notation is recommended. For backward compatibility fdisk also accepts the suffixes KB=1000, MB=1000*1000, and so on for GB, TB, PB, EB, ZB and YB. These 10^N suffixes diff --git a/disk-utils/fdisk.c b/disk-utils/fdisk.c index 73525fa51..ed4db8bd0 100644 --- a/disk-utils/fdisk.c +++ b/disk-utils/fdisk.c @@ -357,6 +357,8 @@ static int ask_offset(struct fdisk_context *cxt, } if (sig == '+') num += base; + else if (sig == '-' && fdisk_ask_number_is_wrap_negative(ask)) + num = high - num; else if (sig == '-') num = base - num; diff --git a/libfdisk/src/ask.c b/libfdisk/src/ask.c index babe040ad..9fabc99c8 100644 --- a/libfdisk/src/ask.c +++ b/libfdisk/src/ask.c @@ -319,6 +319,24 @@ int fdisk_ask_number_is_relative(struct fdisk_ask *ask) return ask->data.num.relative; } +/** + * fdisk_ask_number_is_wrap_negative: + * @ask: ask instance + * + * The wrap-negative flag allows to accept negative number from user. In this + * case the dialog result is calculated as "high - num" (-N from high limit). + * + * Returns: 1 or 0. + * + * Since: 2.33 + */ +int fdisk_ask_number_is_wrap_negative(struct fdisk_ask *ask) +{ + assert(ask); + assert(is_number_ask(ask)); + return ask->data.num.wrap_negative; +} + /** * fdisk_ask_number_set_relative * @ask: ask instance @@ -354,6 +372,13 @@ int fdisk_ask_number_inchars(struct fdisk_ask *ask) return ask->data.num.inchars; } +int fdisk_ask_number_set_wrap_negative(struct fdisk_ask *ask, int wrap_negative) +{ + assert(ask); + ask->data.num.wrap_negative = wrap_negative ? 1 : 0; + return 0; +} + /* * Generates string with list ranges (e.g. 1,2,5-8) for the 'cur' */ diff --git a/libfdisk/src/bsd.c b/libfdisk/src/bsd.c index 9ba3140f1..90b44b963 100644 --- a/libfdisk/src/bsd.c +++ b/libfdisk/src/bsd.c @@ -288,12 +288,12 @@ static int bsd_add_partition(struct fdisk_context *cxt, fdisk_ask_set_type(ask, FDISK_ASKTYPE_OFFSET); if (fdisk_use_cylinders(cxt)) { - fdisk_ask_set_query(ask, _("Last cylinder, +cylinders or +size{K,M,G,T,P}")); + fdisk_ask_set_query(ask, _("Last cylinder, +/-cylinders or +/-size{K,M,G,T,P}")); fdisk_ask_number_set_unit(ask, cxt->sector_size * fdisk_get_units_per_sector(cxt)); } else { - fdisk_ask_set_query(ask, _("Last sector, +sectors or +size{K,M,G,T,P}")); + fdisk_ask_set_query(ask, _("Last sector, +/-sectors or +/-size{K,M,G,T,P}")); fdisk_ask_number_set_unit(ask,cxt->sector_size); } @@ -301,6 +301,7 @@ static int bsd_add_partition(struct fdisk_context *cxt, fdisk_ask_number_set_default(ask, fdisk_cround(cxt, end)); fdisk_ask_number_set_high(ask, fdisk_cround(cxt, end)); fdisk_ask_number_set_base(ask, fdisk_cround(cxt, begin)); + fdisk_ask_number_set_wrap_negative(ask, 1); /* wrap negative around high */ rc = fdisk_do_ask(cxt, ask); end = fdisk_ask_number_get_result(ask); diff --git a/libfdisk/src/dos.c b/libfdisk/src/dos.c index f73516460..2e46aca70 100644 --- a/libfdisk/src/dos.c +++ b/libfdisk/src/dos.c @@ -1210,12 +1210,12 @@ static int add_partition(struct fdisk_context *cxt, size_t n, fdisk_ask_set_type(ask, FDISK_ASKTYPE_OFFSET); if (fdisk_use_cylinders(cxt)) { - fdisk_ask_set_query(ask, _("Last cylinder, +cylinders or +size{K,M,G,T,P}")); + fdisk_ask_set_query(ask, _("Last cylinder, +/-cylinders or +/-size{K,M,G,T,P}")); fdisk_ask_number_set_unit(ask, cxt->sector_size * fdisk_get_units_per_sector(cxt)); } else { - fdisk_ask_set_query(ask, _("Last sector, +sectors or +size{K,M,G,T,P}")); + fdisk_ask_set_query(ask, _("Last sector, +/-sectors or +/-size{K,M,G,T,P}")); fdisk_ask_number_set_unit(ask,cxt->sector_size); } @@ -1223,6 +1223,7 @@ static int add_partition(struct fdisk_context *cxt, size_t n, fdisk_ask_number_set_default(ask, fdisk_cround(cxt, limit)); fdisk_ask_number_set_high(ask, fdisk_cround(cxt, limit)); fdisk_ask_number_set_base(ask, fdisk_cround(cxt, start)); /* base for relative input */ + fdisk_ask_number_set_wrap_negative(ask, 1); /* wrap negative around high */ rc = fdisk_do_ask(cxt, ask); if (rc) diff --git a/libfdisk/src/fdiskP.h b/libfdisk/src/fdiskP.h index e7c264edc..bf2f60e08 100644 --- a/libfdisk/src/fdiskP.h +++ b/libfdisk/src/fdiskP.h @@ -337,7 +337,8 @@ struct fdisk_ask { uint64_t unit; /* unit for offsets */ const char *range; /* by library generated list */ unsigned int relative :1, - inchars :1; + inchars :1, + wrap_negative :1; } num; /* FDISK_ASKTYPE_{WARN,WARNX,..} */ struct ask_print { @@ -491,6 +492,7 @@ int fdisk_ask_number_set_high(struct fdisk_ask *ask, uint64_t high); int fdisk_ask_number_set_base(struct fdisk_ask *ask, uint64_t base); int fdisk_ask_number_set_unit(struct fdisk_ask *ask, uint64_t unit); int fdisk_ask_number_is_relative(struct fdisk_ask *ask); +int fdisk_ask_number_set_wrap_negative(struct fdisk_ask *ask, int wrap_negative); int fdisk_ask_menu_set_default(struct fdisk_ask *ask, int dfl); int fdisk_ask_menu_add_item(struct fdisk_ask *ask, int key, const char *name, const char *desc); diff --git a/libfdisk/src/gpt.c b/libfdisk/src/gpt.c index 1ceb4f571..d1d0c434d 100644 --- a/libfdisk/src/gpt.c +++ b/libfdisk/src/gpt.c @@ -2444,13 +2444,14 @@ static int gpt_add_partition( if (!ask) return -ENOMEM; - fdisk_ask_set_query(ask, _("Last sector, +sectors or +size{K,M,G,T,P}")); + fdisk_ask_set_query(ask, _("Last sector, +/-sectors or +/-size{K,M,G,T,P}")); fdisk_ask_set_type(ask, FDISK_ASKTYPE_OFFSET); fdisk_ask_number_set_low(ask, user_f); /* minimal */ fdisk_ask_number_set_default(ask, dflt_l); /* default */ fdisk_ask_number_set_high(ask, dflt_l); /* maximal */ fdisk_ask_number_set_base(ask, user_f); /* base for relative input */ fdisk_ask_number_set_unit(ask, cxt->sector_size); + fdisk_ask_number_set_wrap_negative(ask, 1); /* wrap negative around high */ rc = fdisk_do_ask(cxt, ask); if (rc) diff --git a/libfdisk/src/libfdisk.h.in b/libfdisk/src/libfdisk.h.in index 0c312c3e1..0f8ecd96f 100644 --- a/libfdisk/src/libfdisk.h.in +++ b/libfdisk/src/libfdisk.h.in @@ -794,6 +794,7 @@ int fdisk_ask_number_set_result(struct fdisk_ask *ask, uint64_t result); uint64_t fdisk_ask_number_get_base(struct fdisk_ask *ask); uint64_t fdisk_ask_number_get_unit(struct fdisk_ask *ask); int fdisk_ask_number_set_relative(struct fdisk_ask *ask, int relative); +int fdisk_ask_number_is_wrap_negative(struct fdisk_ask *ask); int fdisk_ask_number_inchars(struct fdisk_ask *ask); int fdisk_ask_partnum(struct fdisk_context *cxt, size_t *partnum, int wantnew); diff --git a/libfdisk/src/libfdisk.sym b/libfdisk/src/libfdisk.sym index 8d38332b9..c9f35bebb 100644 --- a/libfdisk/src/libfdisk.sym +++ b/libfdisk/src/libfdisk.sym @@ -297,3 +297,7 @@ FDISK_2.32 { fdisk_label_get_geomrange_heads; fdisk_label_get_geomrange_cylinders; } FDISK_2.31; + +FDISK_2.33 { + fdisk_ask_number_is_wrap_negative; +} FDISK_2.32; diff --git a/libfdisk/src/sgi.c b/libfdisk/src/sgi.c index 19d799205..f38e9a09c 100644 --- a/libfdisk/src/sgi.c +++ b/libfdisk/src/sgi.c @@ -925,6 +925,7 @@ static int sgi_add_partition(struct fdisk_context *cxt, fdisk_ask_number_set_default(ask, fdisk_scround(cxt, last) - 1);/* default */ fdisk_ask_number_set_high(ask, fdisk_scround(cxt, last) - 1);/* maximal */ fdisk_ask_number_set_base(ask, fdisk_scround(cxt, first)); + fdisk_ask_number_set_wrap_negative(ask, 1); /* wrap negative around high */ if (fdisk_use_cylinders(cxt)) fdisk_ask_number_set_unit(ask, diff --git a/libfdisk/src/sun.c b/libfdisk/src/sun.c index 30e6b7f1e..df91f543d 100644 --- a/libfdisk/src/sun.c +++ b/libfdisk/src/sun.c @@ -647,7 +647,7 @@ static int sun_add_partition( return -ENOMEM; snprintf(mesg, sizeof(mesg), - _("Last %s or +%s or +size{K,M,G,T,P}"), + _("Last %s or +/-%s or +/-size{K,M,G,T,P}"), fdisk_get_unit(cxt, FDISK_SINGULAR), fdisk_get_unit(cxt, FDISK_PLURAL)); fdisk_ask_set_query(ask, mesg); @@ -670,6 +670,8 @@ static int sun_add_partition( fdisk_ask_number_set_base(ask, fdisk_scround(cxt, first)); } + fdisk_ask_number_set_wrap_negative(ask, 1); /* wrap negative around high */ + if (fdisk_use_cylinders(cxt)) fdisk_ask_number_set_unit(ask, cxt->sector_size * -- cgit v1.2.3-55-g7522