1 /* 2 * Copyright (c) 2011-2015 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 <sys/types.h> 36 37 #include <stdio.h> 38 #include <stdlib.h> 39 #include <stddef.h> 40 #include <unistd.h> 41 #include <string.h> 42 #include <assert.h> 43 #include <err.h> 44 45 #include "mkfs_hammer2.h" 46 47 static void parse_fs_size(hammer2_mkfs_options_t *, const char *); 48 static void usage(void); 49 50 int 51 main(int ac, char **av) 52 { 53 hammer2_mkfs_options_t opt; 54 int ch; 55 int label_specified = 0; 56 57 /* 58 * Initialize option structure. 59 */ 60 hammer2_mkfs_init(&opt); 61 62 /* 63 * Parse arguments. 64 */ 65 while ((ch = getopt(ac, av, "L:b:r:V:s:d")) != -1) { 66 switch(ch) { 67 case 'b': 68 opt.BootAreaSize = getsize(optarg, 69 HAMMER2_NEWFS_ALIGN, 70 HAMMER2_BOOT_MAX_BYTES, 2); 71 break; 72 case 'r': 73 opt.AuxAreaSize = getsize(optarg, 74 HAMMER2_NEWFS_ALIGN, 75 HAMMER2_AUX_MAX_BYTES, 2); 76 break; 77 case 'V': 78 opt.Hammer2Version = strtol(optarg, NULL, 0); 79 if (opt.Hammer2Version < HAMMER2_VOL_VERSION_MIN || 80 opt.Hammer2Version >= HAMMER2_VOL_VERSION_WIP) { 81 errx(1, "I don't understand how to format " 82 "HAMMER2 version %d", 83 opt.Hammer2Version); 84 } 85 break; 86 case 'L': 87 label_specified = 1; 88 if (strcasecmp(optarg, "none") == 0) { 89 break; 90 } 91 if (opt.NLabels >= MAXLABELS) { 92 errx(1, "Limit of %d local labels", 93 MAXLABELS - 1); 94 } 95 if (strlen(optarg) == 0) { 96 errx(1, "Volume label '%s' cannot be 0-length", 97 optarg); 98 } 99 if (strlen(optarg) >= HAMMER2_INODE_MAXNAME) { 100 errx(1, "Volume label '%s' is too long " 101 "(%d chars max)", 102 optarg, 103 HAMMER2_INODE_MAXNAME - 1); 104 } 105 opt.Label[opt.NLabels++] = strdup(optarg); 106 break; 107 case 's': 108 parse_fs_size(&opt, optarg); 109 break; 110 case 'd': 111 opt.DebugOpt = 1; 112 break; 113 default: 114 usage(); 115 break; 116 } 117 } 118 119 ac -= optind; 120 av += optind; 121 122 if (ac == 0) 123 errx(1, "You must specify at least one disk device"); 124 if (ac > HAMMER2_MAX_VOLUMES) 125 errx(1, "The maximum number of volumes is %d", 126 HAMMER2_MAX_VOLUMES); 127 128 /* 129 * Check default label type. 130 */ 131 if (!label_specified) { 132 char c = av[0][strlen(av[0]) - 1]; 133 if (c == 'a') 134 opt.DefaultLabelType = HAMMER2_LABEL_BOOT; 135 else if (c == 'd') 136 opt.DefaultLabelType = HAMMER2_LABEL_ROOT; 137 else 138 opt.DefaultLabelType = HAMMER2_LABEL_DATA; 139 } 140 141 /* 142 * Create Hammer2 filesystem. 143 */ 144 assert(opt.CompType == HAMMER2_COMP_NEWFS_DEFAULT); 145 assert(opt.CheckType == HAMMER2_CHECK_XXHASH64); 146 hammer2_mkfs(ac, av, &opt); 147 148 /* 149 * Cleanup option structure. 150 */ 151 hammer2_mkfs_cleanup(&opt); 152 153 return(0); 154 } 155 156 static 157 void 158 parse_fs_size(hammer2_mkfs_options_t *opt, const char *arg) 159 { 160 char *o, *p, *s; 161 162 opt->NFileSystemSizes = 0; 163 o = p = strdup(arg); 164 165 while ((s = p) != NULL) { 166 if ((p = strchr(p, ':')) != NULL) 167 *p++ = 0; 168 /* XXX 0x7fffffffffffffff isn't limitation of HAMMER2 */ 169 opt->FileSystemSize[opt->NFileSystemSizes++] = getsize(s, 170 HAMMER2_FREEMAP_LEVEL1_SIZE, 171 0x7fffffffffffffff, 2); 172 if (opt->NFileSystemSizes >= HAMMER2_MAX_VOLUMES) 173 break; 174 } 175 free(o); 176 } 177 178 static 179 void 180 usage(void) 181 { 182 fprintf(stderr, 183 "usage: newfs_hammer2 [-b bootsize] [-r auxsize] " 184 "[-V version] [-L label ...] [-s size] special ...\n" 185 ); 186 exit(1); 187 } 188