aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKarel Zak <kzak@redhat.com>2024-09-16 14:50:43 +0200
committerKarel Zak <kzak@redhat.com>2024-09-17 13:19:09 +0200
commit8f6f35aeb63341ce90122259196501467e44734b (patch)
treebacc3c493b551bd62e7326c1ecba335a03cb21ff
parent123d4de40dd96c1e720b1e87a6b17d362cc244ce (diff)
downloadutil-linux-8f6f35aeb63341ce90122259196501467e44734b.tar.gz
sfdisk: add --discard-free
Why do we need this? It can be difficult for end-users to discard unpartitioned areas using blkdiscard, as it requires using fdisk to obtain a list of free areas and then using blkdiscard with the correct --offset and --length options. It is less risky for end-users to use (s)fdisk, as they have a better understanding of the disk layout. Addresses: https://github.com/util-linux/util-linux/issues/2804 Signed-off-by: Karel Zak <kzak@redhat.com>
-rw-r--r--bash-completion/sfdisk1
-rw-r--r--disk-utils/sfdisk.8.adoc7
-rw-r--r--disk-utils/sfdisk.c75
-rw-r--r--sys-utils/blkdiscard.8.adoc2
4 files changed, 84 insertions, 1 deletions
diff --git a/bash-completion/sfdisk b/bash-completion/sfdisk
index b075ccc911..4dc57c4eaf 100644
--- a/bash-completion/sfdisk
+++ b/bash-completion/sfdisk
@@ -58,6 +58,7 @@ _sfdisk_module()
--show-geometry
--list
--list-free
+ --discard-free
--disk-id
--reorder
--show-size
diff --git a/disk-utils/sfdisk.8.adoc b/disk-utils/sfdisk.8.adoc
index b2e5279d26..26ccad5a3b 100644
--- a/disk-utils/sfdisk.8.adoc
+++ b/disk-utils/sfdisk.8.adoc
@@ -116,6 +116,13 @@ Change the GPT partition UUID. If _uuid_ is not specified, then print the curren
*--disk-id* _device_ [__id__]::
Change the disk identifier. If _id_ is not specified, then print the current identifier. The identifier is UUID for GPT or unsigned integer for MBR.
+*--discard-free* _device_ ::
+Discard any unused (unpartitioned) sectors on the device. Use the *--list-free* option to get a list of the free regions. See also *blkdiscard*(8).
++
+WARNING: All data in the discarded regions on the device will be lost! Do not use this option if you are unsure.
++
+Note that the 'T' command in *fdisk* provides a dialog to specify which unused area should be discarded. However, *sfdisk* always discards all unpartitioned regions (except for the areas where it is not possible to create partitions, such as the beginning of the device).
+
*-r*, *--reorder* _device_::
Renumber the partitions, ordering them by their start offset.
diff --git a/disk-utils/sfdisk.c b/disk-utils/sfdisk.c
index 71b0191d21..cf402007b5 100644
--- a/disk-utils/sfdisk.c
+++ b/disk-utils/sfdisk.c
@@ -87,6 +87,7 @@ enum {
ACT_PARTUUID,
ACT_PARTLABEL,
ACT_PARTATTRS,
+ ACT_DISCARD_FREE,
ACT_DISKID,
ACT_DELETE,
ACT_BACKUP_SECTORS,
@@ -1370,6 +1371,69 @@ static int command_partattrs(struct sfdisk *sf, int argc, char **argv)
}
/*
+ * sfdisk --discard-free <device>
+ */
+static int command_discard_free(struct sfdisk *sf, int argc, char **argv)
+{
+ struct fdisk_table *tb = NULL;
+ struct fdisk_iter *itr = NULL;
+ struct fdisk_partition *pa = NULL;
+ const char *devname = NULL;
+ uint64_t ss;
+ int rc;
+
+ if (!argc)
+ errx(EXIT_FAILURE, _("no disk device specified"));
+ devname = argv[0];
+ if (argc > 1)
+ errx(EXIT_FAILURE, _("unexpected arguments"));
+
+ itr = fdisk_new_iter(FDISK_ITER_FORWARD);
+ if (!itr)
+ err(EXIT_FAILURE, _("failed to allocate iterator"));
+
+ assign_device(sf, devname, 0);
+
+ ss = fdisk_get_sector_size(sf->cxt);
+
+ rc = fdisk_get_freespaces(sf->cxt, &tb);
+ if (rc) {
+ fdisk_warn(sf->cxt, _("failed to gather unpartitioned space"));
+ goto done;
+ }
+
+ while (fdisk_table_next_partition(tb, itr, &pa) == 0) {
+ uint64_t range[2];
+
+ if (!fdisk_partition_has_size(pa) ||
+ !fdisk_partition_has_start(pa))
+ continue;
+
+ range[0] = (uint64_t) fdisk_partition_get_start(pa);
+ range[1] = (uint64_t) fdisk_partition_get_size(pa);
+
+ fdisk_info(sf->cxt, _("Discarding region %"PRIu64
+ "-%"PRIu64""),
+ range[0], range[0] + range[1] - 1);
+
+ range[0] *= ss;
+ range[1] *= ss;
+
+ errno = 0;
+ if (ioctl(fdisk_get_devfd(sf->cxt), BLKDISCARD, &range)) {
+ rc = -errno;
+ fdisk_warn(sf->cxt, _("BLKDISCARD ioctl failed"));
+ break;
+ }
+ }
+
+done:
+ fdisk_free_iter(itr);
+ fdisk_unref_table(tb);
+ return rc;
+}
+
+/*
* sfdisk --disk-id <device> [<str>]
*/
static int command_diskid(struct sfdisk *sf, int argc, char **argv)
@@ -2070,6 +2134,7 @@ static void __attribute__((__noreturn__)) usage(void)
fputs(_(" --part-attrs <dev> <part> [<str>] print or change partition attributes\n"), out);
fputs(USAGE_SEPARATOR, out);
+ fputs(_(" --discard-free <dev> discard (trim) unpartitioned areas\n"), out);
fputs(_(" --disk-id <dev> [<str>] print or change disk label ID (UUID)\n"), out);
fputs(_(" --relocate <oper> <dev> move partition header\n"), out);
@@ -2142,6 +2207,7 @@ int main(int argc, char *argv[])
OPT_PARTLABEL,
OPT_PARTTYPE,
OPT_PARTATTRS,
+ OPT_DISCARDFREE,
OPT_DISKID,
OPT_BYTES,
OPT_COLOR,
@@ -2194,6 +2260,8 @@ int main(int argc, char *argv[])
{ "part-type", no_argument, NULL, OPT_PARTTYPE },
{ "part-attrs", no_argument, NULL, OPT_PARTATTRS },
+ { "discard-free", no_argument, NULL, OPT_DISCARDFREE },
+
{ "disk-id", no_argument, NULL, OPT_DISKID },
{ "show-pt-geometry", no_argument, NULL, 'G' }, /* deprecated */
@@ -2340,6 +2408,9 @@ int main(int argc, char *argv[])
case OPT_PARTATTRS:
sf->act = ACT_PARTATTRS;
break;
+ case OPT_DISCARDFREE:
+ sf->act = ACT_DISCARD_FREE;
+ break;
case OPT_DISKID:
sf->act = ACT_DISKID;
break;
@@ -2462,6 +2533,10 @@ int main(int argc, char *argv[])
rc = command_partattrs(sf, argc - optind, argv + optind);
break;
+ case ACT_DISCARD_FREE:
+ rc = command_discard_free(sf, argc - optind, argv + optind);
+ break;
+
case ACT_DISKID:
rc = command_diskid(sf, argc - optind, argv + optind);
break;
diff --git a/sys-utils/blkdiscard.8.adoc b/sys-utils/blkdiscard.8.adoc
index cf661acd9c..3be78b49dc 100644
--- a/sys-utils/blkdiscard.8.adoc
+++ b/sys-utils/blkdiscard.8.adoc
@@ -24,7 +24,7 @@ The _device_ argument is the pathname of the block device.
*WARNING: All data in the discarded region on the device will be lost!*
-Since util-linux v2.41, fdisk has the ability to discard sectors on both partitions and unpartitioned areas using the 'T' command.
+Since util-linux v2.41, *fdisk* has the ability to discard sectors on both partitions and unpartitioned areas using the 'T' command. Additionally, *sfdisk* has the option --discard-free to discard unpartitioned areas.
== OPTIONS