>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 z...@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: _______________________________________________ freebsd-bugs@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-bugs To unsubscribe, send any mail to "freebsd-bugs-unsubscr...@freebsd.org"