[git commit] fstrim: New applet

Bernhard Reutner-Fischer rep.dot.nop at gmail.com
Sat Nov 9 21:14:33 UTC 2013


commit: http://git.busybox.net/busybox/commit/?id=1d39e33d46f32862da2ec1c394401239515206b8
branch: http://git.busybox.net/busybox/commit/?id=refs/heads/master

fstrim applet is a port from util-linux.

"Trimming" your NAND/eMMC storage will restore the write performance
back to normal after having slow down issues on sequential write and
random write due to usage over time.

Good reading on subject:
http://forum.xda-developers.com/showthread.php?t=1971852

(with long options and CLEAN_UP turned on)
function                                             old     new   delta
.rodata                                           148494  148791    +297
fstrim_main                                            -     283    +283
fstrim_sfx                                             -     128    +128
packed_usage                                       28826   28903     +77
applet_main                                         2760    2768      +8
applet_names                                        2343    2350      +7
applet_nameofs                                       690     692      +2
------------------------------------------------------------------------------
(add/remove: 3/0 grow/shrink: 5/0 up/down: 802/0)             Total: 802 bytes

Signed-off-by: Malek Degachi <malek-degachi at laposte.net>
Cc: Eugene San (eugenesan) <eugenesan at gmail.com>
Signed-off-by: Bernhard Reutner-Fischer <rep.dot.nop at gmail.com>
---
 include/applets.src.h |    1 +
 util-linux/Config.src |    7 +++
 util-linux/Kbuild.src |    1 +
 util-linux/fstrim.c   |  111 +++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 120 insertions(+), 0 deletions(-)

diff --git a/include/applets.src.h b/include/applets.src.h
index 3a47e15..5268200 100644
--- a/include/applets.src.h
+++ b/include/applets.src.h
@@ -167,6 +167,7 @@ IF_FSCK(APPLET(fsck, BB_DIR_SBIN, BB_SUID_DROP))
 //IF_E2FSCK(APPLET_ODDNAME(fsck.ext2, e2fsck, BB_DIR_SBIN, BB_SUID_DROP, fsck_ext2))
 //IF_E2FSCK(APPLET_ODDNAME(fsck.ext3, e2fsck, BB_DIR_SBIN, BB_SUID_DROP, fsck_ext3))
 IF_FSCK_MINIX(APPLET_ODDNAME(fsck.minix, fsck_minix, BB_DIR_SBIN, BB_SUID_DROP, fsck_minix))
+IF_FSTRIM(APPLET(fstrim, BB_DIR_SBIN, BB_SUID_DROP))
 IF_FSYNC(APPLET_NOFORK(fsync, fsync, BB_DIR_BIN, BB_SUID_DROP, fsync))
 IF_FTPD(APPLET(ftpd, BB_DIR_USR_SBIN, BB_SUID_DROP))
 IF_FTPGET(APPLET_ODDNAME(ftpget, ftpgetput, BB_DIR_USR_BIN, BB_SUID_DROP, ftpget))
diff --git a/util-linux/Config.src b/util-linux/Config.src
index 5a8b006..ef70397 100644
--- a/util-linux/Config.src
+++ b/util-linux/Config.src
@@ -246,6 +246,13 @@ config FSCK_MINIX
 	  check for and attempt to repair any corruption that occurs to a minix
 	  filesystem.
 
+config FSTRIM
+	bool "fstrim"
+	default y
+	select PLATFORM_LINUX
+	help
+	  Discard unused blocks on a mounted filesystem.
+
 config MKFS_EXT2
 	bool "mkfs_ext2"
 	default y
diff --git a/util-linux/Kbuild.src b/util-linux/Kbuild.src
index 468fc6b..429cf11 100644
--- a/util-linux/Kbuild.src
+++ b/util-linux/Kbuild.src
@@ -18,6 +18,7 @@ lib-$(CONFIG_FINDFS)            += findfs.o
 lib-$(CONFIG_FLOCK)             += flock.o
 lib-$(CONFIG_FREERAMDISK)       += freeramdisk.o
 lib-$(CONFIG_FSCK_MINIX)        += fsck_minix.o
+lib-$(CONFIG_FSTRIM)            += fstrim.o
 lib-$(CONFIG_GETOPT)            += getopt.o
 lib-$(CONFIG_HEXDUMP)           += hexdump.o
 lib-$(CONFIG_HWCLOCK)           += hwclock.o
diff --git a/util-linux/fstrim.c b/util-linux/fstrim.c
new file mode 100644
index 0000000..2fa457b
--- /dev/null
+++ b/util-linux/fstrim.c
@@ -0,0 +1,111 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * fstrim.c - discard the part (or whole) of mounted filesystem.
+ *
+ * 03 March 2012 - Malek Degachi <malek-degachi at laposte.net>
+ * Adapted for busybox from util-linux-2.12a.
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this source tree.
+ */
+
+//usage:#define fstrim_trivial_usage
+//usage:       "[Options] <mountpoint>"
+//usage:#define fstrim_full_usage "\n\n"
+//usage:       "Options:"
+//usage:	IF_LONG_OPTS(
+//usage:     "\n	-o,--offset=offset	offset in bytes to discard from"
+//usage:     "\n	-l,--length=length	length of bytes to discard from the offset"
+//usage:     "\n	-m,--minimum=minimum	minimum extent length to discard"
+//usage:     "\n	-v,--verbose		print number of discarded bytes"
+//usage:	)
+//usage:	IF_NOT_LONG_OPTS(
+//usage:     "\n	-o offset	offset in bytes to discard from"
+//usage:     "\n	-l length	length of bytes to discard from the offset"
+//usage:     "\n	-m minimum	minimum extent length to discard"
+//usage:     "\n	-v,		print number of discarded bytes"
+//usage:	)
+
+#include "libbb.h"
+#include <linux/fs.h>
+
+#ifndef FITRIM
+struct fstrim_range {
+	uint64_t start;
+	uint64_t len;
+	uint64_t minlen;
+};
+#define FITRIM		_IOWR('X', 121, struct fstrim_range)
+#endif
+
+static const struct suffix_mult fstrim_sfx[] = {
+	{ "KiB", 1024 },
+	{ "kiB", 1024 },
+	{ "K", 1024 },
+	{ "k", 1024 },
+	{ "MiB", 1048576 },
+	{ "miB", 1048576 },
+	{ "M", 1048576 },
+	{ "m", 1048576 },
+	{ "GiB", 1073741824 },
+	{ "giB", 1073741824 },
+	{ "G", 1073741824 },
+	{ "g", 1073741824 },
+	{ "KB", 1000 },
+	{ "MB", 1000000 },
+	{ "GB", 1000000000 },
+	{ "", 0 }
+};
+
+int fstrim_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
+int fstrim_main(int argc UNUSED_PARAM, char **argv)
+{
+	struct fstrim_range range;
+	char *arg_o;
+	char *arg_l;
+	char *arg_m;
+	unsigned opts;
+	int fd;
+
+	enum {
+		OPT_o = (1 << 0),
+		OPT_l = (1 << 1),
+		OPT_m = (1 << 2),
+		OPT_v = (1 << 3),
+	};
+
+#if ENABLE_LONG_OPTS
+	static const char getopt_longopts[] ALIGN1 =
+		"offset\0"    Required_argument    "o"
+		"length\0"    Required_argument    "l"
+		"minimum\0"   Required_argument    "m"
+		"verbose\0"   No_argument          "v"
+		;
+	applet_long_options = getopt_longopts;
+#endif
+
+	opt_complementary = "=1"; /* exactly one non-option arg: the mountpoint */
+	opts = getopt32(argv, "o:l:m:v", &arg_o, &arg_l, &arg_m);
+
+	memset(&range, 0, sizeof(range));
+	range.len = ULLONG_MAX;
+
+	if (opts & OPT_o)
+		range.start = xatoull_sfx(arg_o, fstrim_sfx);
+	if (opts & OPT_l)
+		range.len = xatoull_sfx(arg_l, fstrim_sfx);
+	if (opts & OPT_m)
+		range.minlen = xatoull_sfx(arg_m, fstrim_sfx);
+
+	if (find_block_device(argv[optind])) {
+		fd = xopen_nonblocking(argv[optind]);
+		xioctl(fd, FITRIM, &range);
+		if (ENABLE_FEATURE_CLEAN_UP)
+			close(fd);
+
+		if (opts & OPT_v)
+			printf("%s: %llu bytes were trimmed\n", argv[optind], range.len);
+	}
+
+	return EXIT_SUCCESS;
+}
+


More information about the busybox-cvs mailing list