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