1 /* 2 * Copyright (c) 2013 The DragonFly Project. All rights reserved. 3 * 4 * This code is derived from software contributed to The DragonFly Project 5 * by Matthew Dillon <dillon@dragonflybsd.org> 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 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. 20 * 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. 33 */ 34 35 #include "hammer2.h" 36 37 static int cmd_setcheck_core(uint8_t check_algo, const char *path_str, 38 struct stat *st); 39 40 int 41 cmd_setcheck(const char *check_str, char **paths) 42 { 43 static const char *checks[] = HAMMER2_CHECK_STRINGS; 44 struct stat st; 45 int check_algo; 46 int ecode; 47 int res; 48 49 ecode = 0; 50 51 if (isdigit(check_str[0])) { 52 check_algo = strtol(check_str, NULL, 0); 53 } else { 54 check_algo = HAMMER2_CHECK_STRINGS_COUNT; 55 while (--check_algo >= 0) { 56 if (strcasecmp(check_str, checks[check_algo]) == 0) 57 break; 58 } 59 if (check_algo < 0 && strcasecmp(check_str, "default") == 0) { 60 check_algo = HAMMER2_CHECK_ISCSI32; 61 check_str = "crc32"; 62 } 63 if (check_algo < 0 && strcasecmp(check_str, "disabled") == 0) { 64 check_algo = HAMMER2_CHECK_DISABLED; 65 check_str = "disabled"; 66 } 67 if (check_algo < 0) { 68 fprintf(stderr, 69 "Unknown check code type: %s\n", 70 check_str); 71 ecode = 3; 72 } 73 } 74 75 if (ecode == 0) { 76 while (*paths) { 77 if (lstat(*paths, &st) == 0) { 78 res = cmd_setcheck_core( 79 HAMMER2_ENC_ALGO(check_algo), 80 *paths, 81 &st); 82 if (res) 83 ecode = res; 84 } else { 85 printf("%s: %s\n", *paths, strerror(errno)); 86 ecode = 3; 87 } 88 ++paths; 89 } 90 } 91 92 return ecode; 93 } 94 95 static int 96 cmd_setcheck_core(uint8_t check_algo, const char *path_str, struct stat *st) 97 { 98 hammer2_ioc_inode_t inode; 99 int fd; 100 int res; 101 102 fd = hammer2_ioctl_handle(path_str); 103 if (fd < 0) { 104 res = 3; 105 goto failed; 106 } 107 res = ioctl(fd, HAMMER2IOC_INODE_GET, &inode); 108 if (res < 0) { 109 fprintf(stderr, 110 "%s: HAMMER2IOC_INODE_GET: error %s\n", 111 path_str, strerror(errno)); 112 res = 3; 113 goto failed; 114 } 115 printf("%s\tcheck_algo=0x%02x\n", path_str, check_algo); 116 inode.ip_data.check_algo = check_algo; 117 res = ioctl(fd, HAMMER2IOC_INODE_SET, &inode); 118 if (res < 0) { 119 fprintf(stderr, 120 "%s: HAMMER2IOC_INODE_SET: error %s\n", 121 path_str, strerror(errno)); 122 res = 3; 123 goto failed; 124 } 125 res = 0; 126 127 if (RecurseOpt && S_ISDIR(st->st_mode)) { 128 DIR *dir; 129 char *path; 130 struct dirent *den; 131 132 if ((dir = fdopendir(fd)) != NULL) { 133 while ((den = readdir(dir)) != NULL) { 134 if (strcmp(den->d_name, ".") == 0 || 135 strcmp(den->d_name, "..") == 0) { 136 continue; 137 } 138 asprintf(&path, "%s/%s", path_str, den->d_name); 139 if (lstat(path, st) == 0) 140 cmd_setcheck_core(check_algo, path, st); 141 free(path); 142 } 143 closedir(dir); 144 } 145 } 146 failed: 147 close(fd); 148 return res; 149 } 150