summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/TODO6
-rw-r--r--disk-utils/fdisk.817
-rw-r--r--disk-utils/fdisk.c2
-rw-r--r--libfdisk/src/ask.c25
-rw-r--r--libfdisk/src/bsd.c5
-rw-r--r--libfdisk/src/dos.c5
-rw-r--r--libfdisk/src/fdiskP.h4
-rw-r--r--libfdisk/src/gpt.c3
-rw-r--r--libfdisk/src/libfdisk.h.in1
-rw-r--r--libfdisk/src/libfdisk.sym4
-rw-r--r--libfdisk/src/sgi.c1
-rw-r--r--libfdisk/src/sun.c4
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 +<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
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
@@ -320,6 +320,24 @@ int fdisk_ask_number_is_relative(struct fdisk_ask *ask)
}
/**
+ * 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
* @relative: 0 or 1
@@ -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 *