cputimer: Add more IDs for VMM cputimers.
[dragonfly.git] / sbin / hammer2 / cmd_setcomp.c
blob0f20754aee862959e1a057fb2bf41063ae26ac3e
1 /*
2 * Copyright (c) 2013 The DragonFly Project. All rights reserved.
4 * This code is derived from software contributed to The DragonFly Project
5 * by Matthew Dillon <dillon@dragonflybsd.org>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
16 * distribution.
17 * 3. Neither the name of The DragonFly Project nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific, prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
35 #include "hammer2.h"
37 static int cmd_setcomp_core(uint8_t comp_algo, const char *path_str,
38 struct stat *st);
40 int
41 cmd_setcomp(const char *comp_str, char **paths)
43 static const char *comps[] = HAMMER2_COMP_STRINGS;
44 struct stat st;
45 int comp_algo;
46 int comp_level;
47 int ecode;
48 int res;
49 char *str;
50 const char *s1;
51 const char *s2;
53 str = strdup(comp_str);
54 s1 = strtok(str, ":");
55 s2 = s1 ? strtok(NULL, ":") : NULL;
56 ecode = 0;
58 if (isdigit(s1[0])) {
59 comp_algo = strtol(s1, NULL, 0);
60 } else {
61 comp_algo = HAMMER2_COMP_STRINGS_COUNT;
62 while (--comp_algo >= 0) {
63 if (strcasecmp(s1, comps[comp_algo]) == 0)
64 break;
66 if (comp_algo < 0 && strcasecmp(s1, "default") == 0) {
67 comp_algo = HAMMER2_COMP_LZ4;
68 s1 = "lz4";
70 if (comp_algo < 0 && strcasecmp(s1, "disabled") == 0) {
71 comp_algo = HAMMER2_COMP_AUTOZERO;
72 s1 = "autozero";
74 if (comp_algo < 0) {
75 fprintf(stderr, "Unknown compression type: %s\n", s1);
76 ecode = 3;
79 if (s2 == NULL) {
80 comp_level = 0;
81 } else if (isdigit(s2[0])) {
82 comp_level = strtol(s2, NULL, 0);
83 } else if (strcasecmp(s2, "default") == 0) {
84 comp_level = 0;
85 } else {
86 comp_level = 0;
87 fprintf(stderr, "Unknown compression level: %s\n", s2);
88 ecode = 3;
91 if (comp_level) {
92 switch(comp_algo) {
93 case HAMMER2_COMP_ZLIB:
94 if (comp_level < 6 || comp_level > 9) {
95 fprintf(stderr,
96 "Unsupported comp_level %d for %s\n",
97 comp_level, s1);
98 ecode = 3;
100 break;
101 default:
102 fprintf(stderr,
103 "Unsupported comp_level %d for %s\n",
104 comp_level, s1);
105 ecode = 3;
109 if (ecode == 0) {
110 while (*paths) {
111 if (lstat(*paths, &st) == 0) {
112 res = cmd_setcomp_core(
113 HAMMER2_ENC_ALGO(comp_algo) |
114 HAMMER2_ENC_LEVEL(comp_level),
115 *paths,
116 &st);
117 if (res)
118 ecode = res;
119 } else {
120 printf("%s: %s\n", *paths, strerror(errno));
121 ecode = 3;
123 ++paths;
126 free (str);
128 return ecode;
131 static int
132 cmd_setcomp_core(uint8_t comp_algo, const char *path_str, struct stat *st)
134 hammer2_ioc_inode_t inode;
135 int fd;
136 int res;
138 fd = hammer2_ioctl_handle(path_str);
139 if (fd < 0) {
140 res = 3;
141 goto failed;
143 res = ioctl(fd, HAMMER2IOC_INODE_GET, &inode);
144 if (res < 0) {
145 fprintf(stderr,
146 "%s: HAMMER2IOC_INODE_GET: error %s\n",
147 path_str, strerror(errno));
148 res = 3;
149 goto failed;
151 printf("%s\tcomp_algo=0x%02x\n", path_str, comp_algo);
152 inode.flags |= HAMMER2IOC_INODE_FLAG_COMP;
153 inode.ip_data.meta.comp_algo = comp_algo;
154 res = ioctl(fd, HAMMER2IOC_INODE_SET, &inode);
155 if (res < 0) {
156 fprintf(stderr,
157 "%s: HAMMER2IOC_INODE_SET: error %s\n",
158 path_str, strerror(errno));
159 res = 3;
160 goto failed;
162 res = 0;
164 if (RecurseOpt && S_ISDIR(st->st_mode)) {
165 DIR *dir;
166 char *path;
167 struct dirent *den;
169 if ((dir = fdopendir(fd)) != NULL) {
170 while ((den = readdir(dir)) != NULL) {
171 if (strcmp(den->d_name, ".") == 0 ||
172 strcmp(den->d_name, "..") == 0) {
173 continue;
175 asprintf(&path, "%s/%s", path_str, den->d_name);
176 if (lstat(path, st) == 0)
177 cmd_setcomp_core(comp_algo, path, st);
178 free(path);
180 closedir(dir);
183 failed:
184 close(fd);
185 return res;
188 #if 0
191 cmd_setcomp_recursive(char* option_string, char* comp_string, char* file_string)
193 int ecode = 0;
194 int set_files;
195 int comp_method;
197 if (strcmp(option_string, "-r") == 0) {
198 set_files = 0;
199 } else if (strcmp(option_string, "-rf") == 0) {
200 set_files = 1;
201 } else {
202 printf("setcomp: Unrecognized option.\n");
203 exit(1);
205 if (strcmp(comp_string, "0") == 0) {
206 printf("Will turn off compression on directory/file %s\n", file_string);
207 comp_method = HAMMER2_COMP_NONE;
208 } else if (strcmp(comp_string, "1") == 0) {
209 printf("Will set zero-checking compression on directory/file %s.\n", file_string);
210 comp_method = HAMMER2_COMP_AUTOZERO;
211 } else if (strcmp(comp_string, "2") == 0) {
212 printf("Will set LZ4 compression on directory/file %s.\n", file_string);
213 comp_method = HAMMER2_COMP_LZ4;
214 } else if (strcmp(comp_string, "3") == 0) {
215 printf("Will set ZLIB (slowest) compression on directory/file %s.\n", file_string);
216 comp_method = HAMMER2_COMP_ZLIB;
218 else {
219 printf("Unknown compression method.\n");
220 return 1;
222 int fd = hammer2_ioctl_handle(file_string);
223 hammer2_ioc_inode_t inode;
224 int res = ioctl(fd, HAMMER2IOC_INODE_GET, &inode);
225 if (res < 0) {
226 fprintf(stderr, "ERROR before setting the mode: %s\n", strerror(errno));
227 return 3;
229 if (inode.ip_data.type != HAMMER2_OBJTYPE_DIRECTORY) {
230 printf("setcomp: the specified object is not a directory, nothing changed.\n");
231 return 1;
233 printf("Attention: recursive compression mode setting demanded, this may take a while...\n");
234 ecode = setcomp_recursive_call(file_string, comp_method, set_files);
235 inode.ip_data.comp_algo = comp_method;
236 res = ioctl(fd, HAMMER2IOC_INODE_SET, &inode);
237 if (res < 0) {
238 if (errno != EINVAL) {
239 fprintf(stderr, "ERROR after trying to set the mode: %s\n", strerror(errno));
240 return 3;
243 close(fd);
244 return ecode;
248 setcomp_recursive_call(char *directory, int comp_method, int set_files)
250 int ecode = 0;
251 DIR *dir;
252 if ((dir = opendir (directory)) == NULL) {
253 fprintf(stderr, "ERROR while trying to set the mode recursively: %s\n",
254 strerror(errno));
255 return 3;
257 struct dirent *dent;
258 int length;
259 length = strlen(directory);
260 char name[HAMMER2_INODE_MAXNAME];
261 strcpy(name, directory);
262 name[length] = '/';
263 ++length;
264 errno = 0;
265 dent = readdir(dir);
266 while (dent != NULL && ecode == 0) {
267 if ((strcmp(dent->d_name, ".") != 0) &&
268 (strcmp(dent->d_name, "..") != 0)) {
269 strncpy(name + length, dent->d_name, HAMMER2_INODE_MAXNAME -
270 length);
271 int fd = hammer2_ioctl_handle(name);
272 hammer2_ioc_inode_t inode;
273 int res = ioctl(fd, HAMMER2IOC_INODE_GET, &inode);
274 if (res < 0) {
275 fprintf(stderr, "ERROR during recursion: %s\n",
276 strerror(errno));
277 return 3;
279 if (inode.ip_data.type == HAMMER2_OBJTYPE_DIRECTORY) {
280 ecode = setcomp_recursive_call(name, comp_method, set_files);
281 inode.ip_data.comp_algo = comp_method;
282 res = ioctl(fd, HAMMER2IOC_INODE_SET, &inode);
284 else {
285 if (set_files == 1 && inode.ip_data.type ==
286 HAMMER2_OBJTYPE_REGFILE) {
287 inode.ip_data.comp_algo = comp_method;
288 res = ioctl(fd, HAMMER2IOC_INODE_SET, &inode);
291 if (res < 0) {
292 if (errno != EINVAL) {
293 fprintf(stderr, "ERROR during recursion after trying"
294 "to set the mode: %s\n",
295 strerror(errno));
296 return 3;
299 close(fd);
301 errno = 0; //we must set errno to 0 before readdir()
302 dent = readdir(dir);
304 closedir(dir);
305 if (errno != 0) {
306 fprintf(stderr, "ERROR during iteration: %s\n", strerror(errno));
307 return 3;
309 return ecode;
312 #endif