]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blame - io/cowextsize.c
xfs: convert to new timestamp accessors
[thirdparty/xfsprogs-dev.git] / io / cowextsize.c
CommitLineData
959ef981 1// SPDX-License-Identifier: GPL-2.0+
1e51132f
DW
2/*
3 * Copyright (C) 2016 Oracle. All Rights Reserved.
1e51132f 4 * Author: Darrick J. Wong <darrick.wong@oracle.com>
1e51132f
DW
5 */
6/*
7 * If configure didn't find a struct fsxattr with fsx_cowextsize,
8 * disable the only other source (so far) of struct fsxattr. Thus,
9 * build with the internal definition of struct fsxattr, which has
10 * fsx_cowextsize.
11 */
12#include "platform_defs.h"
13#include "command.h"
14#include "init.h"
15#include "io.h"
16#include "input.h"
42b4c8e8 17#include "libfrog/paths.h"
1e51132f
DW
18
19static cmdinfo_t cowextsize_cmd;
20static long cowextsize;
21
22static void
23cowextsize_help(void)
24{
25 printf(_(
26"\n"
27" report or modify preferred CoW extent size (in bytes) for the current path\n"
28"\n"
29" -R -- recursively descend (useful when current path is a directory)\n"
30" -D -- recursively descend, only modifying cowextsize on directories\n"
31"\n"));
32}
33
34static int
35get_cowextsize(const char *path, int fd)
36{
37 struct fsxattr fsx;
38
ce24180d 39 if ((xfsctl(path, fd, FS_IOC_FSGETXATTR, &fsx)) < 0) {
1e51132f
DW
40 printf("%s: XFS_IOC_FSGETXATTR %s: %s\n",
41 progname, path, strerror(errno));
9e1595e6 42 exitcode = 1;
1e51132f
DW
43 return 0;
44 }
45 printf("[%u] %s\n", fsx.fsx_cowextsize, path);
46 return 0;
47}
48
49static int
50set_cowextsize(const char *path, int fd, long extsz)
51{
52 struct fsxattr fsx;
53 struct stat64 stat;
54
55 if (fstat64(fd, &stat) < 0) {
56 perror("fstat64");
9e1595e6 57 exitcode = 1;
1e51132f
DW
58 return 0;
59 }
ce24180d 60 if ((xfsctl(path, fd, FS_IOC_FSGETXATTR, &fsx)) < 0) {
1e51132f
DW
61 printf("%s: XFS_IOC_FSGETXATTR %s: %s\n",
62 progname, path, strerror(errno));
9e1595e6 63 exitcode = 1;
1e51132f
DW
64 return 0;
65 }
66
67 if (S_ISREG(stat.st_mode) || S_ISDIR(stat.st_mode)) {
68 fsx.fsx_xflags |= FS_XFLAG_COWEXTSIZE;
69 } else {
70 printf(_("invalid target file type - file %s\n"), path);
71 return 0;
72 }
73 fsx.fsx_cowextsize = extsz;
74
ce24180d 75 if ((xfsctl(path, fd, FS_IOC_FSSETXATTR, &fsx)) < 0) {
1e51132f
DW
76 printf("%s: XFS_IOC_FSSETXATTR %s: %s\n",
77 progname, path, strerror(errno));
9e1595e6 78 exitcode = 1;
1e51132f
DW
79 return 0;
80 }
81
82 return 0;
83}
84
85static int
86get_cowextsize_callback(
87 const char *path,
88 const struct stat *stat,
89 int status,
90 struct FTW *data)
91{
92 int fd;
93
94 if (recurse_dir && !S_ISDIR(stat->st_mode))
95 return 0;
96
97 fd = open(path, O_RDONLY);
98 if (fd < 0) {
99 fprintf(stderr, _("%s: cannot open %s: %s\n"),
100 progname, path, strerror(errno));
101 } else {
102 get_cowextsize(path, fd);
103 close(fd);
104 }
105 return 0;
106}
107
108static int
109set_cowextsize_callback(
110 const char *path,
111 const struct stat *stat,
112 int status,
113 struct FTW *data)
114{
115 int fd;
116
117 if (recurse_dir && !S_ISDIR(stat->st_mode))
118 return 0;
119
120 fd = open(path, O_RDONLY);
121 if (fd < 0) {
122 fprintf(stderr, _("%s: cannot open %s: %s\n"),
123 progname, path, strerror(errno));
124 } else {
125 set_cowextsize(path, fd, cowextsize);
126 close(fd);
127 }
128 return 0;
129}
130
131static int
132cowextsize_f(
133 int argc,
134 char **argv)
135{
136 size_t blocksize, sectsize;
137 int c;
138
139 recurse_all = recurse_dir = 0;
140 init_cvtnum(&blocksize, &sectsize);
141 while ((c = getopt(argc, argv, "DR")) != EOF) {
142 switch (c) {
143 case 'D':
1e51132f
DW
144 recurse_dir = 1;
145 break;
146 case 'R':
147 recurse_all = 1;
1e51132f
DW
148 break;
149 default:
150 return command_usage(&cowextsize_cmd);
151 }
152 }
153
154 if (optind < argc) {
155 cowextsize = (long)cvtnum(blocksize, sectsize, argv[optind]);
156 if (cowextsize < 0) {
157 printf(_("non-numeric cowextsize argument -- %s\n"),
158 argv[optind]);
9e1595e6 159 exitcode = 1;
1e51132f
DW
160 return 0;
161 }
162 } else {
163 cowextsize = -1;
164 }
165
5fd7257c
XY
166 if (recurse_all && recurse_dir) {
167 fprintf(stderr, _("%s: -R and -D options are mutually exclusive\n"),
168 progname);
169 exitcode = 1;
170 return 0;
171 }
172
1e51132f
DW
173 if (recurse_all || recurse_dir)
174 nftw(file->name, (cowextsize >= 0) ?
175 set_cowextsize_callback : get_cowextsize_callback,
176 100, FTW_PHYS | FTW_MOUNT | FTW_DEPTH);
177 else if (cowextsize >= 0)
178 set_cowextsize(file->name, file->fd, cowextsize);
179 else
180 get_cowextsize(file->name, file->fd);
181 return 0;
182}
183
184void
185cowextsize_init(void)
186{
187 cowextsize_cmd.name = "cowextsize";
188 cowextsize_cmd.cfunc = cowextsize_f;
189 cowextsize_cmd.args = _("[-D | -R] [cowextsize]");
190 cowextsize_cmd.argmin = 0;
191 cowextsize_cmd.argmax = -1;
192 cowextsize_cmd.flags = CMD_NOMAP_OK;
193 cowextsize_cmd.oneline =
194 _("get/set preferred CoW extent size (in bytes) for the open file");
195 cowextsize_cmd.help = cowextsize_help;
196
197 add_command(&cowextsize_cmd);
198}