]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blame - io/sync_file_range.c
xfs: support removing extents from CoW fork
[thirdparty/xfsprogs-dev.git] / io / sync_file_range.c
CommitLineData
a278c389
DC
1/*
2 * Copyright (c) 2012 Red Hat, Inc.
3 * All Rights Reserved.
4 *
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
7 * published by the Free Software Foundation.
8 *
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.
13 *
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
17 */
18
6b803e5a
CH
19#include "command.h"
20#include "input.h"
a278c389
DC
21#include "init.h"
22#include "io.h"
23
24static cmdinfo_t sync_range_cmd;
25
26static void
27sync_range_help(void)
28{
29 printf(_(
30"\n"
31" Trigger specific writeback commands on a range of the current file\n"
32"\n"
33" With no options, the SYNC_FILE_RANGE_WRITE is implied.\n"
34" -a -- wait for IO to finish after writing (SYNC_FILE_RANGE_WAIT_AFTER).\n"
35" -b -- wait for IO to finish before writing (SYNC_FILE_RANGE_WAIT_BEFORE).\n"
36" -w -- write dirty data in range (SYNC_FILE_RANGE_WRITE).\n"
37"\n"));
38}
39
40static int
41sync_range_f(
42 int argc,
43 char **argv)
44{
45 off64_t offset = 0, length = 0;
46 int c, sync_mode = 0;
47 size_t blocksize, sectsize;
48
49 while ((c = getopt(argc, argv, "abw")) != EOF) {
50 switch (c) {
51 case 'a':
52 sync_mode = SYNC_FILE_RANGE_WAIT_AFTER;
53 break;
54 case 'b':
55 sync_mode = SYNC_FILE_RANGE_WAIT_BEFORE;
56 break;
57 case 'w':
58 sync_mode = SYNC_FILE_RANGE_WRITE;
59 break;
60 default:
61 return command_usage(&sync_range_cmd);
62 }
63 }
64
65 /* default to just starting writeback on the range */
66 if (!sync_mode)
67 sync_mode = SYNC_FILE_RANGE_WRITE;
68
69 if (optind != argc - 2)
70 return command_usage(&sync_range_cmd);
71 init_cvtnum(&blocksize, &sectsize);
72 offset = cvtnum(blocksize, sectsize, argv[optind]);
73 if (offset < 0) {
74 printf(_("non-numeric offset argument -- %s\n"),
75 argv[optind]);
76 return 0;
77 }
78 optind++;
79 length = cvtnum(blocksize, sectsize, argv[optind]);
80 if (length < 0) {
81 printf(_("non-numeric length argument -- %s\n"),
82 argv[optind]);
83 return 0;
84 }
85
86 if (sync_file_range(file->fd, offset, length, sync_mode) < 0) {
87 perror("sync_file_range");
88 return 0;
89 }
90 return 0;
91}
92
93void
94sync_range_init(void)
95{
96 sync_range_cmd.name = "sync_range";
97 sync_range_cmd.cfunc = sync_range_f;
98 sync_range_cmd.argmin = 2;
99 sync_range_cmd.argmax = -1;
100 sync_range_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK;
101 sync_range_cmd.args = _("[-abw] off len");
102 sync_range_cmd.oneline = _("Control writeback on a range of a file");
103 sync_range_cmd.help = sync_range_help;
104
105 add_command(&sync_range_cmd);
106}