bin/175943: [PATCH] Add trim capability to gpart
Dan Nelson
dnelson at allantgroup.com
Thu Feb 7 23:30:01 UTC 2013
>Number: 175943
>Category: bin
>Synopsis: [PATCH] Add trim capability to gpart
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: change-request
>Submitter-Id: current-users
>Arrival-Date: Thu Feb 07 23:30:00 UTC 2013
>Closed-Date:
>Last-Modified:
>Originator: Dan Nelson
>Release: FreeBSD 9.1-STABLE amd64
>Organization:
>Environment:
System: FreeBSD dan.emsphone.com 9.1-STABLE FreeBSD 9.1-STABLE #652 r246183M: Thu Jan 31 16:32:57 CST 2013 zsh at dan.emsphone.com:/usr/src/sys/amd64/compile/DANSMP amd64
>Description:
I have occasionally wanted to erase all or part of an SSD device to recover
performance after heavy random write activity. It can sort-of be done with
either newfs -E or creating+deleting a zfs pool on the area to erase, but
both write a varying amount of data after they send their BIO_DELETE calls,
and there should be a cleaner way to do it. Attached is a patch that adds a
"trim" verb to the gpart command, which opens the raw device and calls
g_delete on it.
Feel free to pick a new name if you can think of a better one. I know that
"trim" refers only to the SATA implementation, but "delete" is already
taken, "erase" implies unconditional erasure which is not true for devices
that ignore BIO_DELETE calls, and most people that want the functionality
refer to it as TRIM anyway.
>How-To-Repeat:
>Fix:
Index: geom_part.c
===================================================================
--- geom_part.c (revision 246183)
+++ geom_part.c (working copy)
@@ -90,6 +90,7 @@
static void gpart_print_error(const char *);
static void gpart_backup(struct gctl_req *, unsigned int);
static void gpart_restore(struct gctl_req *, unsigned int);
+static void gpart_trim(struct gctl_req *, unsigned int);
struct g_command PUBSYM(class_commands)[] = {
{ "add", 0, gpart_issue, {
@@ -159,6 +160,9 @@
G_OPT_SENTINEL },
"[-l | -r] [-p] [geom ...]"
},
+ { "trim", 0, gpart_trim, G_NULL_OPTS,
+ "provider"
+ },
{ "undo", 0, gpart_issue, G_NULL_OPTS,
"geom"
},
@@ -1279,3 +1283,22 @@
gctl_free(req);
exit(status);
}
+
+static void
+gpart_trim(struct gctl_req *req, unsigned int fl __unused)
+{
+ const char *s;
+ int fd;
+
+ if (gctl_get_int(req, "nargs") != 1)
+ errx(EXIT_FAILURE, "Invalid number of arguments.");
+ s = gctl_get_ascii(req, "arg0");
+ if (s == NULL)
+ abort();
+ fd = g_open(s, 1);
+ if (fd == -1)
+ err(EXIT_FAILURE, "Cannot open %s", s);
+ if (g_delete(fd, 0, g_mediasize(fd)) == -1)
+ err(EXIT_FAILURE, "g_delete call failed");
+ g_close(fd);
+}
Index: gpart.8
===================================================================
--- gpart.8 (revision 246183)
+++ gpart.8 (working copy)
@@ -144,6 +144,10 @@
.Op Fl l | r
.Op Fl p
.Op Ar geom ...
+.\" ==== TRIM ====
+.Nm
+.Cm trim
+.Ar provider
.\" ==== UNDO ====
.Nm
.Cm undo
@@ -471,6 +475,15 @@
.It Fl r
Show raw partition type instead of symbolic name.
.El
+.\" ==== TRIM ====
+.It Cm trim
+Sends a BIO_DELETE request for the contents of the provider
+.Ar provider .
+Depending on the underlying storage device, this may may fill its blocks
+with a constant value (0x00 or 0xFF), or may do nothing. Running this
+command on a partition on an SSD device before deleting it may improve
+performance, since the SSD can immediately reuse the blocks for subsequent
+write requests.
.\" ==== UNDO ====
.It Cm undo
Revert any pending changes for geom
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list