1 // SPDX-License-Identifier: GPL-2.0 2 3 #include <linux/kernel.h> 4 5 #include "bcachefs.h" 6 #include "compress.h" 7 #include "disk_groups.h" 8 #include "error.h" 9 #include "opts.h" 10 #include "super-io.h" 11 #include "util.h" 12 13 #define x(t, n, ...) [n] = #t, 14 15 const char * const bch2_error_actions[] = { 16 BCH_ERROR_ACTIONS() 17 NULL 18 }; 19 20 const char * const bch2_fsck_fix_opts[] = { 21 BCH_FIX_ERRORS_OPTS() 22 NULL 23 }; 24 25 const char * const bch2_version_upgrade_opts[] = { 26 BCH_VERSION_UPGRADE_OPTS() 27 NULL 28 }; 29 30 const char * const bch2_sb_features[] = { 31 BCH_SB_FEATURES() 32 NULL 33 }; 34 35 const char * const bch2_sb_compat[] = { 36 BCH_SB_COMPAT() 37 NULL 38 }; 39 40 const char * const __bch2_btree_ids[] = { 41 BCH_BTREE_IDS() 42 NULL 43 }; 44 45 const char * const bch2_csum_types[] = { 46 BCH_CSUM_TYPES() 47 NULL 48 }; 49 50 const char * const bch2_csum_opts[] = { 51 BCH_CSUM_OPTS() 52 NULL 53 }; 54 55 const char * const __bch2_compression_types[] = { 56 BCH_COMPRESSION_TYPES() 57 NULL 58 }; 59 60 const char * const bch2_compression_opts[] = { 61 BCH_COMPRESSION_OPTS() 62 NULL 63 }; 64 65 const char * const bch2_str_hash_types[] = { 66 BCH_STR_HASH_TYPES() 67 NULL 68 }; 69 70 const char * const bch2_str_hash_opts[] = { 71 BCH_STR_HASH_OPTS() 72 NULL 73 }; 74 75 const char * const __bch2_data_types[] = { 76 BCH_DATA_TYPES() 77 NULL 78 }; 79 80 const char * const bch2_member_states[] = { 81 BCH_MEMBER_STATES() 82 NULL 83 }; 84 85 const char * const bch2_jset_entry_types[] = { 86 BCH_JSET_ENTRY_TYPES() 87 NULL 88 }; 89 90 const char * const bch2_fs_usage_types[] = { 91 BCH_FS_USAGE_TYPES() 92 NULL 93 }; 94 95 #undef x 96 97 static int bch2_opt_fix_errors_parse(struct bch_fs *c, const char *val, u64 *res, 98 struct printbuf *err) 99 { 100 if (!val) { 101 *res = FSCK_FIX_yes; 102 } else { 103 int ret = match_string(bch2_fsck_fix_opts, -1, val); 104 105 if (ret < 0 && err) 106 prt_str(err, "fix_errors: invalid selection"); 107 if (ret < 0) 108 return ret; 109 *res = ret; 110 } 111 112 return 0; 113 } 114 115 static void bch2_opt_fix_errors_to_text(struct printbuf *out, 116 struct bch_fs *c, 117 struct bch_sb *sb, 118 u64 v) 119 { 120 prt_str(out, bch2_fsck_fix_opts[v]); 121 } 122 123 #define bch2_opt_fix_errors (struct bch_opt_fn) { \ 124 .parse = bch2_opt_fix_errors_parse, \ 125 .to_text = bch2_opt_fix_errors_to_text, \ 126 } 127 128 const char * const bch2_d_types[BCH_DT_MAX] = { 129 [DT_UNKNOWN] = "unknown", 130 [DT_FIFO] = "fifo", 131 [DT_CHR] = "chr", 132 [DT_DIR] = "dir", 133 [DT_BLK] = "blk", 134 [DT_REG] = "reg", 135 [DT_LNK] = "lnk", 136 [DT_SOCK] = "sock", 137 [DT_WHT] = "whiteout", 138 [DT_SUBVOL] = "subvol", 139 }; 140 141 u64 BCH2_NO_SB_OPT(const struct bch_sb *sb) 142 { 143 BUG(); 144 } 145 146 void SET_BCH2_NO_SB_OPT(struct bch_sb *sb, u64 v) 147 { 148 BUG(); 149 } 150 151 void bch2_opts_apply(struct bch_opts *dst, struct bch_opts src) 152 { 153 #define x(_name, ...) \ 154 if (opt_defined(src, _name)) \ 155 opt_set(*dst, _name, src._name); 156 157 BCH_OPTS() 158 #undef x 159 } 160 161 bool bch2_opt_defined_by_id(const struct bch_opts *opts, enum bch_opt_id id) 162 { 163 switch (id) { 164 #define x(_name, ...) \ 165 case Opt_##_name: \ 166 return opt_defined(*opts, _name); 167 BCH_OPTS() 168 #undef x 169 default: 170 BUG(); 171 } 172 } 173 174 u64 bch2_opt_get_by_id(const struct bch_opts *opts, enum bch_opt_id id) 175 { 176 switch (id) { 177 #define x(_name, ...) \ 178 case Opt_##_name: \ 179 return opts->_name; 180 BCH_OPTS() 181 #undef x 182 default: 183 BUG(); 184 } 185 } 186 187 void bch2_opt_set_by_id(struct bch_opts *opts, enum bch_opt_id id, u64 v) 188 { 189 switch (id) { 190 #define x(_name, ...) \ 191 case Opt_##_name: \ 192 opt_set(*opts, _name, v); \ 193 break; 194 BCH_OPTS() 195 #undef x 196 default: 197 BUG(); 198 } 199 } 200 201 const struct bch_option bch2_opt_table[] = { 202 #define OPT_BOOL() .type = BCH_OPT_BOOL, .min = 0, .max = 2 203 #define OPT_UINT(_min, _max) .type = BCH_OPT_UINT, \ 204 .min = _min, .max = _max 205 #define OPT_STR(_choices) .type = BCH_OPT_STR, \ 206 .min = 0, .max = ARRAY_SIZE(_choices), \ 207 .choices = _choices 208 #define OPT_FN(_fn) .type = BCH_OPT_FN, .fn = _fn 209 210 #define x(_name, _bits, _flags, _type, _sb_opt, _default, _hint, _help) \ 211 [Opt_##_name] = { \ 212 .attr = { \ 213 .name = #_name, \ 214 .mode = (_flags) & OPT_RUNTIME ? 0644 : 0444, \ 215 }, \ 216 .flags = _flags, \ 217 .hint = _hint, \ 218 .help = _help, \ 219 .get_sb = _sb_opt, \ 220 .set_sb = SET_##_sb_opt, \ 221 _type \ 222 }, 223 224 BCH_OPTS() 225 #undef x 226 }; 227 228 int bch2_opt_lookup(const char *name) 229 { 230 const struct bch_option *i; 231 232 for (i = bch2_opt_table; 233 i < bch2_opt_table + ARRAY_SIZE(bch2_opt_table); 234 i++) 235 if (!strcmp(name, i->attr.name)) 236 return i - bch2_opt_table; 237 238 return -1; 239 } 240 241 struct synonym { 242 const char *s1, *s2; 243 }; 244 245 static const struct synonym bch_opt_synonyms[] = { 246 { "quota", "usrquota" }, 247 }; 248 249 static int bch2_mount_opt_lookup(const char *name) 250 { 251 const struct synonym *i; 252 253 for (i = bch_opt_synonyms; 254 i < bch_opt_synonyms + ARRAY_SIZE(bch_opt_synonyms); 255 i++) 256 if (!strcmp(name, i->s1)) 257 name = i->s2; 258 259 return bch2_opt_lookup(name); 260 } 261 262 int bch2_opt_validate(const struct bch_option *opt, u64 v, struct printbuf *err) 263 { 264 if (v < opt->min) { 265 if (err) 266 prt_printf(err, "%s: too small (min %llu)", 267 opt->attr.name, opt->min); 268 return -BCH_ERR_ERANGE_option_too_small; 269 } 270 271 if (opt->max && v >= opt->max) { 272 if (err) 273 prt_printf(err, "%s: too big (max %llu)", 274 opt->attr.name, opt->max); 275 return -BCH_ERR_ERANGE_option_too_big; 276 } 277 278 if ((opt->flags & OPT_SB_FIELD_SECTORS) && (v & 511)) { 279 if (err) 280 prt_printf(err, "%s: not a multiple of 512", 281 opt->attr.name); 282 return -BCH_ERR_opt_parse_error; 283 } 284 285 if ((opt->flags & OPT_MUST_BE_POW_2) && !is_power_of_2(v)) { 286 if (err) 287 prt_printf(err, "%s: must be a power of two", 288 opt->attr.name); 289 return -BCH_ERR_opt_parse_error; 290 } 291 292 if (opt->fn.validate) 293 return opt->fn.validate(v, err); 294 295 return 0; 296 } 297 298 int bch2_opt_parse(struct bch_fs *c, 299 const struct bch_option *opt, 300 const char *val, u64 *res, 301 struct printbuf *err) 302 { 303 ssize_t ret; 304 305 switch (opt->type) { 306 case BCH_OPT_BOOL: 307 if (val) { 308 ret = kstrtou64(val, 10, res); 309 } else { 310 ret = 0; 311 *res = 1; 312 } 313 314 if (ret < 0 || (*res != 0 && *res != 1)) { 315 if (err) 316 prt_printf(err, "%s: must be bool", opt->attr.name); 317 return ret; 318 } 319 break; 320 case BCH_OPT_UINT: 321 if (!val) { 322 prt_printf(err, "%s: required value", 323 opt->attr.name); 324 return -EINVAL; 325 } 326 327 ret = opt->flags & OPT_HUMAN_READABLE 328 ? bch2_strtou64_h(val, res) 329 : kstrtou64(val, 10, res); 330 if (ret < 0) { 331 if (err) 332 prt_printf(err, "%s: must be a number", 333 opt->attr.name); 334 return ret; 335 } 336 break; 337 case BCH_OPT_STR: 338 if (!val) { 339 prt_printf(err, "%s: required value", 340 opt->attr.name); 341 return -EINVAL; 342 } 343 344 ret = match_string(opt->choices, -1, val); 345 if (ret < 0) { 346 if (err) 347 prt_printf(err, "%s: invalid selection", 348 opt->attr.name); 349 return ret; 350 } 351 352 *res = ret; 353 break; 354 case BCH_OPT_FN: 355 ret = opt->fn.parse(c, val, res, err); 356 if (ret < 0) { 357 if (err) 358 prt_printf(err, "%s: parse error", 359 opt->attr.name); 360 return ret; 361 } 362 } 363 364 return bch2_opt_validate(opt, *res, err); 365 } 366 367 void bch2_opt_to_text(struct printbuf *out, 368 struct bch_fs *c, struct bch_sb *sb, 369 const struct bch_option *opt, u64 v, 370 unsigned flags) 371 { 372 if (flags & OPT_SHOW_MOUNT_STYLE) { 373 if (opt->type == BCH_OPT_BOOL) { 374 prt_printf(out, "%s%s", 375 v ? "" : "no", 376 opt->attr.name); 377 return; 378 } 379 380 prt_printf(out, "%s=", opt->attr.name); 381 } 382 383 switch (opt->type) { 384 case BCH_OPT_BOOL: 385 case BCH_OPT_UINT: 386 if (opt->flags & OPT_HUMAN_READABLE) 387 prt_human_readable_u64(out, v); 388 else 389 prt_printf(out, "%lli", v); 390 break; 391 case BCH_OPT_STR: 392 if (flags & OPT_SHOW_FULL_LIST) 393 prt_string_option(out, opt->choices, v); 394 else 395 prt_str(out, opt->choices[v]); 396 break; 397 case BCH_OPT_FN: 398 opt->fn.to_text(out, c, sb, v); 399 break; 400 default: 401 BUG(); 402 } 403 } 404 405 int bch2_opt_check_may_set(struct bch_fs *c, int id, u64 v) 406 { 407 int ret = 0; 408 409 switch (id) { 410 case Opt_compression: 411 case Opt_background_compression: 412 ret = bch2_check_set_has_compressed_data(c, v); 413 break; 414 case Opt_erasure_code: 415 if (v) 416 bch2_check_set_feature(c, BCH_FEATURE_ec); 417 break; 418 } 419 420 return ret; 421 } 422 423 int bch2_opts_check_may_set(struct bch_fs *c) 424 { 425 unsigned i; 426 int ret; 427 428 for (i = 0; i < bch2_opts_nr; i++) { 429 ret = bch2_opt_check_may_set(c, i, 430 bch2_opt_get_by_id(&c->opts, i)); 431 if (ret) 432 return ret; 433 } 434 435 return 0; 436 } 437 438 int bch2_parse_mount_opts(struct bch_fs *c, struct bch_opts *opts, 439 char *options) 440 { 441 char *copied_opts, *copied_opts_start; 442 char *opt, *name, *val; 443 int ret, id; 444 struct printbuf err = PRINTBUF; 445 u64 v; 446 447 if (!options) 448 return 0; 449 450 /* 451 * sys_fsconfig() is now occasionally providing us with option lists 452 * starting with a comma - weird. 453 */ 454 if (*options == ',') 455 options++; 456 457 copied_opts = kstrdup(options, GFP_KERNEL); 458 if (!copied_opts) 459 return -1; 460 copied_opts_start = copied_opts; 461 462 while ((opt = strsep(&copied_opts, ",")) != NULL) { 463 name = strsep(&opt, "="); 464 val = opt; 465 466 id = bch2_mount_opt_lookup(name); 467 468 /* Check for the form "noopt", negation of a boolean opt: */ 469 if (id < 0 && 470 !val && 471 !strncmp("no", name, 2)) { 472 id = bch2_mount_opt_lookup(name + 2); 473 val = "0"; 474 } 475 476 /* Unknown options are ignored: */ 477 if (id < 0) 478 continue; 479 480 if (!(bch2_opt_table[id].flags & OPT_MOUNT)) 481 goto bad_opt; 482 483 if (id == Opt_acl && 484 !IS_ENABLED(CONFIG_BCACHEFS_POSIX_ACL)) 485 goto bad_opt; 486 487 if ((id == Opt_usrquota || 488 id == Opt_grpquota) && 489 !IS_ENABLED(CONFIG_BCACHEFS_QUOTA)) 490 goto bad_opt; 491 492 ret = bch2_opt_parse(c, &bch2_opt_table[id], val, &v, &err); 493 if (ret < 0) 494 goto bad_val; 495 496 bch2_opt_set_by_id(opts, id, v); 497 } 498 499 ret = 0; 500 goto out; 501 502 bad_opt: 503 pr_err("Bad mount option %s", name); 504 ret = -1; 505 goto out; 506 bad_val: 507 pr_err("Invalid mount option %s", err.buf); 508 ret = -1; 509 goto out; 510 out: 511 kfree(copied_opts_start); 512 printbuf_exit(&err); 513 return ret; 514 } 515 516 u64 bch2_opt_from_sb(struct bch_sb *sb, enum bch_opt_id id) 517 { 518 const struct bch_option *opt = bch2_opt_table + id; 519 u64 v; 520 521 v = opt->get_sb(sb); 522 523 if (opt->flags & OPT_SB_FIELD_ILOG2) 524 v = 1ULL << v; 525 526 if (opt->flags & OPT_SB_FIELD_SECTORS) 527 v <<= 9; 528 529 return v; 530 } 531 532 /* 533 * Initial options from superblock - here we don't want any options undefined, 534 * any options the superblock doesn't specify are set to 0: 535 */ 536 int bch2_opts_from_sb(struct bch_opts *opts, struct bch_sb *sb) 537 { 538 unsigned id; 539 540 for (id = 0; id < bch2_opts_nr; id++) { 541 const struct bch_option *opt = bch2_opt_table + id; 542 543 if (opt->get_sb == BCH2_NO_SB_OPT) 544 continue; 545 546 bch2_opt_set_by_id(opts, id, bch2_opt_from_sb(sb, id)); 547 } 548 549 return 0; 550 } 551 552 void __bch2_opt_set_sb(struct bch_sb *sb, const struct bch_option *opt, u64 v) 553 { 554 if (opt->set_sb == SET_BCH2_NO_SB_OPT) 555 return; 556 557 if (opt->flags & OPT_SB_FIELD_SECTORS) 558 v >>= 9; 559 560 if (opt->flags & OPT_SB_FIELD_ILOG2) 561 v = ilog2(v); 562 563 opt->set_sb(sb, v); 564 } 565 566 void bch2_opt_set_sb(struct bch_fs *c, const struct bch_option *opt, u64 v) 567 { 568 if (opt->set_sb == SET_BCH2_NO_SB_OPT) 569 return; 570 571 mutex_lock(&c->sb_lock); 572 __bch2_opt_set_sb(c->disk_sb.sb, opt, v); 573 bch2_write_super(c); 574 mutex_unlock(&c->sb_lock); 575 } 576 577 /* io opts: */ 578 579 struct bch_io_opts bch2_opts_to_inode_opts(struct bch_opts src) 580 { 581 return (struct bch_io_opts) { 582 #define x(_name, _bits) ._name = src._name, 583 BCH_INODE_OPTS() 584 #undef x 585 }; 586 } 587 588 bool bch2_opt_is_inode_opt(enum bch_opt_id id) 589 { 590 static const enum bch_opt_id inode_opt_list[] = { 591 #define x(_name, _bits) Opt_##_name, 592 BCH_INODE_OPTS() 593 #undef x 594 }; 595 unsigned i; 596 597 for (i = 0; i < ARRAY_SIZE(inode_opt_list); i++) 598 if (inode_opt_list[i] == id) 599 return true; 600 601 return false; 602 } 603