*
* Licensed under GPLv2 or later, see file LICENSE in this source tree.
*/
+//config:config FSTRIM
+//config: bool "fstrim (5.5 kb)"
+//config: default y
+//config: select PLATFORM_LINUX
+//config: help
+//config: Discard unused blocks on a mounted filesystem.
+
+//applet:IF_FSTRIM(APPLET_NOEXEC(fstrim, fstrim, BB_DIR_SBIN, BB_SUID_DROP, fstrim))
+
+//kbuild:lib-$(CONFIG_FSTRIM) += fstrim.o
//usage:#define fstrim_trivial_usage
-//usage: "[Options] <mountpoint>"
+//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: " -o,--offset OFFSET Offset in bytes to discard from"
+//usage: "\n -l,--length LEN Bytes to discard"
+//usage: "\n -m,--minimum MIN Minimum extent length"
+//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: " -o OFFSET Offset in bytes to discard from"
+//usage: "\n -l LEN Bytes to discard"
+//usage: "\n -m MIN Minimum extent length"
+//usage: "\n -v Print number of discarded bytes"
//usage: )
#include "libbb.h"
#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;
+ char *arg_o, *arg_l, *arg_m, *mp;
unsigned opts;
int fd;
};
#if ENABLE_LONG_OPTS
- static const char getopt_longopts[] ALIGN1 =
+ static const char fstrim_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);
+ opts = getopt32long(argv, "^"
+ "o:l:m:v"
+ "\0" "=1", fstrim_longopts,
+ &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);
+ range.start = xatoull_sfx(arg_o, kmg_i_suffixes);
if (opts & OPT_l)
- range.len = xatoull_sfx(arg_l, fstrim_sfx);
+ range.len = xatoull_sfx(arg_l, kmg_i_suffixes);
if (opts & OPT_m)
- range.minlen = xatoull_sfx(arg_m, fstrim_sfx);
+ range.minlen = xatoull_sfx(arg_m, kmg_i_suffixes);
- if (find_block_device(argv[optind])) {
- fd = xopen_nonblocking(argv[optind]);
+ mp = argv[optind];
+//Wwhy bother checking that it's a blockdev?
+// if (find_block_device(mp)) {
+ fd = xopen_nonblocking(mp);
+
+ /* On ENOTTY error, util-linux 2.31 says:
+ * "fstrim: FILE: the discard operation is not supported"
+ */
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;
+ printf("%s: %llu bytes trimmed\n", mp, (unsigned long long)range.len);
+ return EXIT_SUCCESS;
+// }
+ return EXIT_FAILURE;
}
-