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