/* vi: set sw=4 ts=4: */ /* * fstrim.c - discard the part (or whole) of mounted filesystem. * * 03 March 2012 - Malek Degachi * Adapted for busybox from util-linux-2.12a. * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ //config:config FSTRIM //config: bool "fstrim (4.4 kb)" //config: default y //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:#define fstrim_full_usage "\n\n" //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" #include "libbb.h" #include #ifndef FITRIM struct fstrim_range { uint64_t start; uint64_t len; uint64_t minlen; }; #define FITRIM _IOWR('X', 121, struct fstrim_range) #endif 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, *arg_l, *arg_m, *mp; 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 fstrim_longopts[] ALIGN1 = "offset\0" Required_argument "o" "length\0" Required_argument "l" "minimum\0" Required_argument "m" "verbose\0" No_argument "v" ; #endif 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, kmg_i_suffixes); if (opts & OPT_l) range.len = xatoull_sfx(arg_l, kmg_i_suffixes); if (opts & OPT_m) range.minlen = xatoull_sfx(arg_m, kmg_i_suffixes); 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 trimmed\n", mp, (unsigned long long)range.len); return EXIT_SUCCESS; // } return EXIT_FAILURE; }