]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libfdisk: Accept negative numbers for last sector input
authorAwal Garg <awalgarg@gmail.com>
Sat, 28 Jul 2018 13:20:35 +0000 (18:50 +0530)
committerKarel Zak <kzak@redhat.com>
Tue, 31 Jul 2018 12:54:12 +0000 (14:54 +0200)
[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 <kzak@redhat.com>
12 files changed:
Documentation/TODO
disk-utils/fdisk.8
disk-utils/fdisk.c
libfdisk/src/ask.c
libfdisk/src/bsd.c
libfdisk/src/dos.c
libfdisk/src/fdiskP.h
libfdisk/src/gpt.c
libfdisk/src/libfdisk.h.in
libfdisk/src/libfdisk.sym
libfdisk/src/sgi.c
libfdisk/src/sun.c

index 44c9805813e468f689947cc7099dd0205d60198e..22b28b00542451ddf96bbe1ad3c2d167c7027af6 100644 (file)
@@ -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
 ----
index 91c6b6f84da844618cbbc3f2a7197e3af9035570..430c96c3d587d75fbf4b7974d85ccf10eb0e28d4 100644 (file)
@@ -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 +<size>{M,G,...} notation are always aligned according
+sizes specified by the +/-<size>{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 +<size>{K,B,M,G,...} notation. 
+or by +/-<size>{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
-+<size>{K,B,M,G,...} notation is recommended.
++/-<size>{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
index 73525fa5141b872e417befb54d858403b5e5f364..ed4db8bd06b9a7d407ac2fb597df68b10716d467 100644 (file)
@@ -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;
 
index babe040ad0c78366a0270745abfcb5283da80a66..9fabc99c8db94af20d5a0e3229dcecd1a9bc5c86 100644 (file)
@@ -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'
  */
index 9ba3140f147ae4254971a066f2f51a787749befc..90b44b9639f2c170a847739f84f35ae4f0467c0e 100644 (file)
@@ -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);
index f7351646061c94c0953b10cce2399bbe0a85b6a5..2e46aca70be272f98365e40598cbaa4d9d71fe97 100644 (file)
@@ -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)
index e7c264edc46e2a8c99b700ed4b06f3a3907b21f6..bf2f60e083f101245c7f8dfd5a704ae1defb7c45 100644 (file)
@@ -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);
index 1ceb4f571070712ff73bee5bcfd1c45a27d8fd8d..d1d0c434dfe1a8e617e73c837cd703b49fd579de 100644 (file)
@@ -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)
index 0c312c3e183e97462c9ccd512387b6ea6e2bf6f6..0f8ecd96f0ad87257e1b91ea20341355789cbafe 100644 (file)
@@ -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);
 
index 8d38332b9aa51827ed3fce811a256fea03ee69d0..c9f35bebb8b4d98b945d923e738240ed2c1dba64 100644 (file)
@@ -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;
index 19d799205c3ebfe5b84df4ac7325d00ace0b2136..f38e9a09ccb130038e2709c19b69d9f6e42ae7ab 100644 (file)
@@ -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,
index 30e6b7f1e7cfc93909784b0f4cab484494879fd5..df91f543deda8ef3703d6344eedf32e65ede4ede 100644 (file)
@@ -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 *