2 * fstrim.c -- discard the part (or whole) of mounted filesystem.
4 * Copyright (C) 2010 Red Hat, Inc. All rights reserved.
5 * Written by Lukas Czerner <lczerner@redhat.com>
6 * Karel Zak <kzak@redhat.com>
8 * This program is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
22 * This program uses FITRIM ioctl to discard parts or the whole filesystem
23 * online (mounted). You can specify range (start and length) to be
24 * discarded, or simply discard whole filesystem.
38 #include <sys/ioctl.h>
52 #define FITRIM _IOWR('X', 121, struct fstrim_range)
55 static void __attribute__((__noreturn__
)) usage(FILE *out
)
57 fprintf(out
, _("Usage: %s [options] <mount point>\n\nOptions:\n"),
58 program_invocation_short_name
);
61 " -h, --help this help\n"
62 " -o, --offset <num> offset in bytes to discard from\n"
63 " -l, --length <num> length of bytes to discard from the offset\n"
64 " -m, --minimum <num> minimum extent length to discard\n"
65 " -v, --verbose print number of discarded bytes\n"));
67 fprintf(out
, _("\nFor more information see fstrim(1).\n"));
69 exit(out
== stderr
? EXIT_FAILURE
: EXIT_SUCCESS
);
72 int main(int argc
, char **argv
)
75 int c
, fd
, verbose
= 0;
76 struct fstrim_range range
;
79 struct option longopts
[] = {
80 { "help", 0, 0, 'h' },
81 { "offset", 1, 0, 'o' },
82 { "length", 1, 0, 'l' },
83 { "minimum", 1, 0, 'm' },
84 { "verbose", 0, 0, 'v' },
88 setlocale(LC_ALL
, "");
89 bindtextdomain(PACKAGE
, LOCALEDIR
);
92 memset(&range
, 0, sizeof(range
));
93 range
.len
= ULLONG_MAX
;
95 while ((c
= getopt_long(argc
, argv
, "ho:l:m:v", longopts
, NULL
)) != -1) {
101 if (strtosize(optarg
, &range
.len
))
103 _("failed to parse length: %s"), optarg
);
106 if (strtosize(optarg
, &range
.start
))
108 _("failed to parse offset: %s"), optarg
);
111 if (strtosize(optarg
, &range
.minlen
))
113 _("failed to parse minimal extend length: %s"),
126 errx(EXIT_FAILURE
, _("no mountpoint specified."));
128 path
= argv
[optind
++];
130 if (optind
!= argc
) {
131 warnx(_("unexpected number of arguments"));
135 if (stat(path
, &sb
) == -1)
136 err(EXIT_FAILURE
, _("%s: stat failed"), path
);
137 if (!S_ISDIR(sb
.st_mode
))
138 errx(EXIT_FAILURE
, _("%s: not a directory"), path
);
140 fd
= open(path
, O_RDONLY
);
142 err(EXIT_FAILURE
, _("%s: open failed"), path
);
144 if (ioctl(fd
, FITRIM
, &range
)) {
147 error(EXIT_FAILURE
, errsv
, _("%s: FITRIM ioctl failed"), path
);
150 printf(_("%s: %" PRIu64
" bytes was trimmed\n"),