inetd,mount: add comment with example of flags to build with libtirpc
[oweals/busybox.git] / util-linux / fstrim.c
1 /* vi: set sw=4 ts=4: */
2 /*
3  * fstrim.c - discard the part (or whole) of mounted filesystem.
4  *
5  * 03 March 2012 - Malek Degachi <malek-degachi@laposte.net>
6  * Adapted for busybox from util-linux-2.12a.
7  *
8  * Licensed under GPLv2 or later, see file LICENSE in this source tree.
9  */
10 //config:config FSTRIM
11 //config:       bool "fstrim (5.5 kb)"
12 //config:       default y
13 //config:       select PLATFORM_LINUX
14 //config:       help
15 //config:       Discard unused blocks on a mounted filesystem.
16
17 //applet:IF_FSTRIM(APPLET_NOEXEC(fstrim, fstrim, BB_DIR_SBIN, BB_SUID_DROP, fstrim))
18
19 //kbuild:lib-$(CONFIG_FSTRIM) += fstrim.o
20
21 //usage:#define fstrim_trivial_usage
22 //usage:       "[OPTIONS] MOUNTPOINT"
23 //usage:#define fstrim_full_usage "\n\n"
24 //usage:        IF_LONG_OPTS(
25 //usage:       "        -o,--offset OFFSET      Offset in bytes to discard from"
26 //usage:     "\n        -l,--length LEN         Bytes to discard"
27 //usage:     "\n        -m,--minimum MIN        Minimum extent length"
28 //usage:     "\n        -v,--verbose            Print number of discarded bytes"
29 //usage:        )
30 //usage:        IF_NOT_LONG_OPTS(
31 //usage:       "        -o OFFSET       Offset in bytes to discard from"
32 //usage:     "\n        -l LEN          Bytes to discard"
33 //usage:     "\n        -m MIN          Minimum extent length"
34 //usage:     "\n        -v              Print number of discarded bytes"
35 //usage:        )
36
37 #include "libbb.h"
38 #include <linux/fs.h>
39
40 #ifndef FITRIM
41 struct fstrim_range {
42         uint64_t start;
43         uint64_t len;
44         uint64_t minlen;
45 };
46 #define FITRIM          _IOWR('X', 121, struct fstrim_range)
47 #endif
48
49 int fstrim_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
50 int fstrim_main(int argc UNUSED_PARAM, char **argv)
51 {
52         struct fstrim_range range;
53         char *arg_o, *arg_l, *arg_m, *mp;
54         unsigned opts;
55         int fd;
56
57         enum {
58                 OPT_o = (1 << 0),
59                 OPT_l = (1 << 1),
60                 OPT_m = (1 << 2),
61                 OPT_v = (1 << 3),
62         };
63
64 #if ENABLE_LONG_OPTS
65         static const char fstrim_longopts[] ALIGN1 =
66                 "offset\0"    Required_argument    "o"
67                 "length\0"    Required_argument    "l"
68                 "minimum\0"   Required_argument    "m"
69                 "verbose\0"   No_argument          "v"
70                 ;
71 #endif
72
73         opts = getopt32long(argv, "^" "o:l:m:v" "\0" "=1", fstrim_longopts,
74                         &arg_o, &arg_l, &arg_m
75         );
76
77         memset(&range, 0, sizeof(range));
78         range.len = ULLONG_MAX;
79
80         if (opts & OPT_o)
81                 range.start = xatoull_sfx(arg_o, kmg_i_suffixes);
82         if (opts & OPT_l)
83                 range.len = xatoull_sfx(arg_l, kmg_i_suffixes);
84         if (opts & OPT_m)
85                 range.minlen = xatoull_sfx(arg_m, kmg_i_suffixes);
86
87         mp = argv[optind];
88         if (find_block_device(mp)) {
89                 fd = xopen_nonblocking(mp);
90                 xioctl(fd, FITRIM, &range);
91                 if (ENABLE_FEATURE_CLEAN_UP)
92                         close(fd);
93
94                 if (opts & OPT_v)
95                         printf("%s: %llu bytes trimmed\n", mp, (unsigned long long)range.len);
96                 return EXIT_SUCCESS;
97         }
98         return EXIT_FAILURE;
99 }