]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blame - io/prealloc.c
xfs_io: support the new getfsmap ioctl
[thirdparty/xfsprogs-dev.git] / io / prealloc.c
CommitLineData
e246ba5f 1/*
da23017d
NS
2 * Copyright (c) 2003-2005 Silicon Graphics, Inc.
3 * All Rights Reserved.
dfc130f3 4 *
da23017d
NS
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
e246ba5f 7 * published by the Free Software Foundation.
dfc130f3 8 *
da23017d
NS
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
dfc130f3 13 *
da23017d
NS
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
e246ba5f
NS
17 */
18
c0b5232a
ES
19#if defined(HAVE_FALLOCATE)
20#include <linux/falloc.h>
21#endif
6b803e5a
CH
22#include "command.h"
23#include "input.h"
e246ba5f 24#include "init.h"
48c46ee3 25#include "io.h"
e246ba5f 26
bda4979e
CH
27#ifndef FALLOC_FL_PUNCH_HOLE
28#define FALLOC_FL_PUNCH_HOLE 0x02
29#endif
30
ca692f16
NJ
31#ifndef FALLOC_FL_COLLAPSE_RANGE
32#define FALLOC_FL_COLLAPSE_RANGE 0x08
33#endif
34
938904c4
LC
35#ifndef FALLOC_FL_ZERO_RANGE
36#define FALLOC_FL_ZERO_RANGE 0x10
37#endif
38
555bc8cc
NJ
39#ifndef FALLOC_FL_INSERT_RANGE
40#define FALLOC_FL_INSERT_RANGE 0x20
41#endif
42
3825c565
DW
43#ifndef FALLOC_FL_UNSHARE_RANGE
44#define FALLOC_FL_UNSHARE_RANGE 0x40
45#endif
46
e246ba5f
NS
47static cmdinfo_t allocsp_cmd;
48static cmdinfo_t freesp_cmd;
49static cmdinfo_t resvsp_cmd;
50static cmdinfo_t unresvsp_cmd;
72ec2b76 51static cmdinfo_t zero_cmd;
c0b5232a
ES
52#if defined(HAVE_FALLOCATE)
53static cmdinfo_t falloc_cmd;
d675ae8e 54static cmdinfo_t fpunch_cmd;
ca692f16 55static cmdinfo_t fcollapse_cmd;
555bc8cc 56static cmdinfo_t finsert_cmd;
938904c4 57static cmdinfo_t fzero_cmd;
c0b5232a 58#endif
e246ba5f
NS
59
60static int
61offset_length(
62 char *offset,
63 char *length,
64 xfs_flock64_t *segment)
65{
2c2f6d79 66 size_t blocksize, sectsize;
48c46ee3
NS
67
68 init_cvtnum(&blocksize, &sectsize);
e246ba5f
NS
69 memset(segment, 0, sizeof(*segment));
70 segment->l_whence = SEEK_SET;
48c46ee3 71 segment->l_start = cvtnum(blocksize, sectsize, offset);
638473d8 72 if (segment->l_start < 0) {
e246ba5f
NS
73 printf(_("non-numeric offset argument -- %s\n"), offset);
74 return 0;
75 }
48c46ee3 76 segment->l_len = cvtnum(blocksize, sectsize, length);
638473d8 77 if (segment->l_len < 0) {
e246ba5f
NS
78 printf(_("non-numeric length argument -- %s\n"), length);
79 return 0;
80 }
81 return 1;
82}
83
84static int
85allocsp_f(
86 int argc,
87 char **argv)
88{
89 xfs_flock64_t segment;
90
91 if (!offset_length(argv[1], argv[2], &segment))
92 return 0;
93
48c46ee3
NS
94 if (xfsctl(file->name, file->fd, XFS_IOC_ALLOCSP64, &segment) < 0) {
95 perror("XFS_IOC_ALLOCSP64");
e246ba5f
NS
96 return 0;
97 }
98 return 0;
99}
100
101static int
102freesp_f(
103 int argc,
104 char **argv)
105{
106 xfs_flock64_t segment;
107
108 if (!offset_length(argv[1], argv[2], &segment))
109 return 0;
110
48c46ee3
NS
111 if (xfsctl(file->name, file->fd, XFS_IOC_FREESP64, &segment) < 0) {
112 perror("XFS_IOC_FREESP64");
e246ba5f
NS
113 return 0;
114 }
115 return 0;
116}
117
118static int
119resvsp_f(
120 int argc,
121 char **argv)
122{
123 xfs_flock64_t segment;
124
125 if (!offset_length(argv[1], argv[2], &segment))
126 return 0;
127
48c46ee3
NS
128 if (xfsctl(file->name, file->fd, XFS_IOC_RESVSP64, &segment) < 0) {
129 perror("XFS_IOC_RESVSP64");
e246ba5f
NS
130 return 0;
131 }
132 return 0;
133}
134
135static int
136unresvsp_f(
137 int argc,
138 char **argv)
139{
140 xfs_flock64_t segment;
141
142 if (!offset_length(argv[1], argv[2], &segment))
143 return 0;
144
48c46ee3
NS
145 if (xfsctl(file->name, file->fd, XFS_IOC_UNRESVSP64, &segment) < 0) {
146 perror("XFS_IOC_UNRESVSP64");
e246ba5f
NS
147 return 0;
148 }
149 return 0;
150}
151
72ec2b76
DC
152static int
153zero_f(
154 int argc,
155 char **argv)
156{
157 xfs_flock64_t segment;
158
159 if (!offset_length(argv[1], argv[2], &segment))
160 return 0;
161
162 if (xfsctl(file->name, file->fd, XFS_IOC_ZERO_RANGE, &segment) < 0) {
163 perror("XFS_IOC_ZERO_RANGE");
164 return 0;
165 }
166 return 0;
167}
168
169
c0b5232a 170#if defined (HAVE_FALLOCATE)
0c2ed80a
DW
171static void
172falloc_help(void)
173{
174 printf(_(
175"\n"
176" modifies space associated with part of a file via fallocate"
177"\n"
178" Example:\n"
179" 'falloc 0 1m' - fills all holes within the first megabyte\n"
180"\n"
181" falloc uses the fallocate system call to alter space allocations in the\n"
182" open file. The following operations are supported:\n"
183" All the file offsets are in units of bytes.\n"
184" -c -- collapses the given range.\n"
185" -i -- inserts a hole into the given range of the file.\n"
186" -k -- do not change file size.\n"
187" -p -- unmap the given range from the file.\n"
3825c565 188" -u -- unshare shared extents in the given range.\n"
0c2ed80a
DW
189"\n"));
190}
191
c0b5232a
ES
192static int
193fallocate_f(
194 int argc,
195 char **argv)
196{
197 xfs_flock64_t segment;
198 int mode = 0;
199 int c;
200
3825c565 201 while ((c = getopt(argc, argv, "cikpu")) != EOF) {
c0b5232a 202 switch (c) {
ca692f16
NJ
203 case 'c':
204 mode = FALLOC_FL_COLLAPSE_RANGE;
205 break;
555bc8cc
NJ
206 case 'i':
207 mode = FALLOC_FL_INSERT_RANGE;
208 break;
c0b5232a
ES
209 case 'k':
210 mode = FALLOC_FL_KEEP_SIZE;
211 break;
bda4979e 212 case 'p':
c229968d 213 mode = FALLOC_FL_PUNCH_HOLE|FALLOC_FL_KEEP_SIZE;
bda4979e 214 break;
3825c565
DW
215 case 'u':
216 mode = FALLOC_FL_UNSHARE_RANGE;
217 break;
c0b5232a
ES
218 default:
219 command_usage(&falloc_cmd);
220 }
221 }
222 if (optind != argc - 2)
223 return command_usage(&falloc_cmd);
224
225 if (!offset_length(argv[optind], argv[optind+1], &segment))
226 return 0;
227
228 if (fallocate(file->fd, mode,
229 segment.l_start, segment.l_len)) {
230 perror("fallocate");
231 return 0;
232 }
233 return 0;
234}
d675ae8e
CH
235
236static int
237fpunch_f(
238 int argc,
239 char **argv)
240{
241 xfs_flock64_t segment;
242 int mode = FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE;
243
244 if (!offset_length(argv[1], argv[2], &segment))
245 return 0;
246
247 if (fallocate(file->fd, mode,
248 segment.l_start, segment.l_len)) {
249 perror("fallocate");
250 return 0;
251 }
252 return 0;
253}
ca692f16
NJ
254
255static int
256fcollapse_f(
257 int argc,
258 char **argv)
259{
260 xfs_flock64_t segment;
261 int mode = FALLOC_FL_COLLAPSE_RANGE;
262
263 if (!offset_length(argv[1], argv[2], &segment))
264 return 0;
265
266 if (fallocate(file->fd, mode,
267 segment.l_start, segment.l_len)) {
268 perror("fallocate");
269 return 0;
270 }
271 return 0;
272}
938904c4 273
555bc8cc
NJ
274static int
275finsert_f(
276 int argc,
277 char **argv)
278{
279 xfs_flock64_t segment;
280 int mode = FALLOC_FL_INSERT_RANGE;
281
282 if (!offset_length(argv[1], argv[2], &segment))
283 return 0;
284
285 if (fallocate(file->fd, mode,
286 segment.l_start, segment.l_len)) {
287 perror("fallocate");
288 return 0;
289 }
290 return 0;
291}
292
938904c4
LC
293static int
294fzero_f(
295 int argc,
296 char **argv)
297{
298 xfs_flock64_t segment;
299 int mode = FALLOC_FL_ZERO_RANGE;
300 int index = 1;
301
302 if (strncmp(argv[index], "-k", 3) == 0) {
303 mode |= FALLOC_FL_KEEP_SIZE;
304 index++;
305 }
306
307 if (!offset_length(argv[index], argv[index + 1], &segment))
308 return 0;
309
310 if (fallocate(file->fd, mode,
311 segment.l_start, segment.l_len)) {
312 perror("fallocate");
313 return 0;
314 }
315 return 0;
316}
3825c565
DW
317
318static int
319funshare_f(
320 int argc,
321 char **argv)
322{
323 xfs_flock64_t segment;
324 int mode = FALLOC_FL_UNSHARE_RANGE;
325 int index = 1;
326
327 if (!offset_length(argv[index], argv[index + 1], &segment))
328 return 0;
329
330 if (fallocate(file->fd, mode,
331 segment.l_start, segment.l_len)) {
332 perror("fallocate");
333 return 0;
334 }
335 return 0;
336}
d675ae8e 337#endif /* HAVE_FALLOCATE */
c0b5232a 338
e246ba5f
NS
339void
340prealloc_init(void)
341{
ad765595 342 allocsp_cmd.name = "allocsp";
e246ba5f
NS
343 allocsp_cmd.cfunc = allocsp_f;
344 allocsp_cmd.argmin = 2;
345 allocsp_cmd.argmax = 2;
48c46ee3 346 allocsp_cmd.flags = CMD_NOMAP_OK;
e246ba5f
NS
347 allocsp_cmd.args = _("off len");
348 allocsp_cmd.oneline = _("allocates zeroed space for part of a file");
349
ad765595 350 freesp_cmd.name = "freesp";
e246ba5f
NS
351 freesp_cmd.cfunc = freesp_f;
352 freesp_cmd.argmin = 2;
353 freesp_cmd.argmax = 2;
48c46ee3 354 freesp_cmd.flags = CMD_NOMAP_OK;
e246ba5f
NS
355 freesp_cmd.args = _("off len");
356 freesp_cmd.oneline = _("frees space associated with part of a file");
357
ad765595 358 resvsp_cmd.name = "resvsp";
e246ba5f
NS
359 resvsp_cmd.cfunc = resvsp_f;
360 resvsp_cmd.argmin = 2;
361 resvsp_cmd.argmax = 2;
370f69dd 362 resvsp_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK;
e246ba5f
NS
363 resvsp_cmd.args = _("off len");
364 resvsp_cmd.oneline =
365 _("reserves space associated with part of a file");
366
ad765595 367 unresvsp_cmd.name = "unresvsp";
e246ba5f
NS
368 unresvsp_cmd.cfunc = unresvsp_f;
369 unresvsp_cmd.argmin = 2;
370 unresvsp_cmd.argmax = 2;
371 unresvsp_cmd.args = _("off len");
48c46ee3 372 unresvsp_cmd.flags = CMD_NOMAP_OK;
e246ba5f
NS
373 unresvsp_cmd.oneline =
374 _("frees reserved space associated with part of a file");
375
ad765595 376 zero_cmd.name = "zero";
72ec2b76
DC
377 zero_cmd.cfunc = zero_f;
378 zero_cmd.argmin = 2;
379 zero_cmd.argmax = 2;
380 zero_cmd.flags = CMD_NOMAP_OK;
381 zero_cmd.args = _("off len");
382 zero_cmd.oneline =
383 _("Converts the given range of a file to allocated zeros");
384
e246ba5f
NS
385 add_command(&allocsp_cmd);
386 add_command(&freesp_cmd);
387 add_command(&resvsp_cmd);
388 add_command(&unresvsp_cmd);
72ec2b76 389 add_command(&zero_cmd);
c0b5232a
ES
390
391#if defined (HAVE_FALLOCATE)
ad765595 392 falloc_cmd.name = "falloc";
c0b5232a
ES
393 falloc_cmd.cfunc = fallocate_f;
394 falloc_cmd.argmin = 2;
395 falloc_cmd.argmax = -1;
396 falloc_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK;
3825c565 397 falloc_cmd.args = _("[-c] [-k] [-p] [-u] off len");
c0b5232a 398 falloc_cmd.oneline =
938904c4 399 _("allocates space associated with part of a file via fallocate");
0c2ed80a 400 falloc_cmd.help = falloc_help;
c0b5232a 401 add_command(&falloc_cmd);
d675ae8e 402
ad765595 403 fpunch_cmd.name = "fpunch";
d675ae8e
CH
404 fpunch_cmd.cfunc = fpunch_f;
405 fpunch_cmd.argmin = 2;
406 fpunch_cmd.argmax = 2;
407 fpunch_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK;
408 fpunch_cmd.args = _("off len");
409 fpunch_cmd.oneline =
938904c4 410 _("de-allocates space assocated with part of a file via fallocate");
d675ae8e 411 add_command(&fpunch_cmd);
ca692f16
NJ
412
413 fcollapse_cmd.name = "fcollapse";
414 fcollapse_cmd.cfunc = fcollapse_f;
415 fcollapse_cmd.argmin = 2;
416 fcollapse_cmd.argmax = 2;
417 fcollapse_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK;
418 fcollapse_cmd.args = _("off len");
419 fcollapse_cmd.oneline =
420 _("de-allocates space and eliminates the hole by shifting extents");
421 add_command(&fcollapse_cmd);
938904c4 422
555bc8cc
NJ
423 finsert_cmd.name = "finsert";
424 finsert_cmd.cfunc = finsert_f;
425 finsert_cmd.argmin = 2;
426 finsert_cmd.argmax = 2;
427 finsert_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK;
428 finsert_cmd.args = _("off len");
429 finsert_cmd.oneline =
430 _("creates new space for writing within file by shifting extents");
431 add_command(&finsert_cmd);
432
938904c4
LC
433 fzero_cmd.name = "fzero";
434 fzero_cmd.cfunc = fzero_f;
435 fzero_cmd.argmin = 2;
436 fzero_cmd.argmax = 3;
437 fzero_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK;
438 fzero_cmd.args = _("[-k] off len");
439 fzero_cmd.oneline =
440 _("zeroes space and eliminates holes by preallocating");
441 add_command(&fzero_cmd);
3825c565
DW
442
443 fzero_cmd.name = "funshare";
444 fzero_cmd.cfunc = funshare_f;
445 fzero_cmd.argmin = 2;
446 fzero_cmd.argmax = 2;
447 fzero_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK;
448 fzero_cmd.args = _("off len");
449 fzero_cmd.oneline =
450 _("unshares shared blocks within the range");
451 add_command(&fzero_cmd);
d675ae8e 452#endif /* HAVE_FALLOCATE */
e246ba5f 453}