]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - spaceman/trim.c
xfs: pass transaction lock while setting up agresv on cyclic metadata
[thirdparty/xfsprogs-dev.git] / spaceman / trim.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright (c) 2012 Red Hat, Inc.
4 * All Rights Reserved.
5 */
6
7 #include "libxfs.h"
8 #include "command.h"
9 #include "init.h"
10 #include "path.h"
11 #include "space.h"
12 #include "input.h"
13
14 static cmdinfo_t trim_cmd;
15
16 /*
17 * Trim unused space in xfs filesystem.
18 */
19 static int
20 trim_f(
21 int argc,
22 char **argv)
23 {
24 struct fstrim_range trim = {0};
25 xfs_agnumber_t agno = 0;
26 off64_t offset = 0;
27 ssize_t length = 0;
28 ssize_t minlen = 0;
29 int aflag = 0;
30 int fflag = 0;
31 int ret;
32 int c;
33
34 while ((c = getopt(argc, argv, "a:fm:")) != EOF) {
35 switch (c) {
36 case 'a':
37 aflag = 1;
38 agno = cvt_u32(optarg, 10);
39 if (errno) {
40 printf(_("bad agno value %s\n"), optarg);
41 return command_usage(&trim_cmd);
42 }
43 break;
44 case 'f':
45 fflag = 1;
46 break;
47 case 'm':
48 minlen = cvtnum(file->geom.blocksize,
49 file->geom.sectsize, optarg);
50 break;
51 default:
52 return command_usage(&trim_cmd);
53 }
54 }
55
56 if (aflag && fflag)
57 return command_usage(&trim_cmd);
58
59 if (optind != argc - 2 && !(aflag || fflag))
60 return command_usage(&trim_cmd);
61 if (optind != argc) {
62 offset = cvtnum(file->geom.blocksize, file->geom.sectsize,
63 argv[optind]);
64 length = cvtnum(file->geom.blocksize, file->geom.sectsize,
65 argv[optind + 1]);
66 } else if (agno) {
67 offset = (off64_t)agno * file->geom.agblocks * file->geom.blocksize;
68 length = file->geom.agblocks * file->geom.blocksize;
69 } else {
70 offset = 0;
71 length = file->geom.datablocks * file->geom.blocksize;
72 }
73
74 trim.start = offset;
75 trim.len = length;
76 trim.minlen = minlen;
77
78 ret = ioctl(file->fd, FITRIM, (unsigned long)&trim);
79 if (ret < 0) {
80 fprintf(stderr, "%s: ioctl(FITRIM) [\"%s\"]: %s\n",
81 progname, file->name, strerror(errno));
82 exitcode = 1;
83 }
84 return 0;
85 }
86
87 static void
88 trim_help(void)
89 {
90 printf(_(
91 "\n"
92 "Discard filesystem free space\n"
93 "\n"
94 " -a agno -- trim all the freespace in the given AG agno\n"
95 " -f -- trim all the freespace in the entire filesystem\n"
96 " offset length -- trim the freespace in the range {offset, length}\n"
97 " -m minlen -- skip freespace extents smaller than minlen\n"
98 "\n"
99 "One of -a, -f, or the offset/length pair are required.\n"
100 "\n"));
101
102 }
103
104 void
105 trim_init(void)
106 {
107 trim_cmd.name = "trim";
108 trim_cmd.altname = "tr";
109 trim_cmd.cfunc = trim_f;
110 trim_cmd.argmin = 1;
111 trim_cmd.argmax = 4;
112 trim_cmd.args = "[-m minlen] ( -a agno | -f | offset length )";
113 trim_cmd.flags = CMD_FLAG_ONESHOT;
114 trim_cmd.oneline = _("Discard filesystem free space");
115 trim_cmd.help = trim_help;
116
117 add_command(&trim_cmd);
118 }
119