* Function sets desired raidz implementation. * * If we are called before init(), user preference will be saved in * user_sel_impl, and applied in later init() call. This occurs when module * parameter is specified on module load. Otherwise, directly update * zfs_vdev_raidz_impl. * * @val Name of raidz implementation to use * @param Unused. */
| 580 | * @param Unused. |
| 581 | */ |
| 582 | int |
| 583 | vdev_raidz_impl_set(const char *val) |
| 584 | { |
| 585 | int err = -EINVAL; |
| 586 | char req_name[RAIDZ_IMPL_NAME_MAX]; |
| 587 | uint32_t impl = RAIDZ_IMPL_READ(user_sel_impl); |
| 588 | size_t i; |
| 589 | |
| 590 | /* sanitize input */ |
| 591 | i = strnlen(val, RAIDZ_IMPL_NAME_MAX); |
| 592 | if (i == 0 || i == RAIDZ_IMPL_NAME_MAX) |
| 593 | return (err); |
| 594 | |
| 595 | strlcpy(req_name, val, RAIDZ_IMPL_NAME_MAX); |
| 596 | while (i > 0 && !!isspace(req_name[i-1])) |
| 597 | i--; |
| 598 | req_name[i] = '\0'; |
| 599 | |
| 600 | /* Check mandatory options */ |
| 601 | for (i = 0; i < ARRAY_SIZE(math_impl_opts); i++) { |
| 602 | if (strcmp(req_name, math_impl_opts[i].name) == 0) { |
| 603 | impl = math_impl_opts[i].sel; |
| 604 | err = 0; |
| 605 | break; |
| 606 | } |
| 607 | } |
| 608 | |
| 609 | /* check all supported impl if init() was already called */ |
| 610 | if (err != 0 && raidz_math_initialized) { |
| 611 | /* check all supported implementations */ |
| 612 | for (i = 0; i < raidz_supp_impl_cnt; i++) { |
| 613 | if (strcmp(req_name, raidz_supp_impl[i]->name) == 0) { |
| 614 | impl = i; |
| 615 | err = 0; |
| 616 | break; |
| 617 | } |
| 618 | } |
| 619 | } |
| 620 | |
| 621 | if (err == 0) { |
| 622 | if (raidz_math_initialized) |
| 623 | atomic_swap_32(&zfs_vdev_raidz_impl, impl); |
| 624 | else |
| 625 | atomic_swap_32(&user_sel_impl, impl); |
| 626 | } |
| 627 | |
| 628 | return (err); |
| 629 | } |
| 630 | |
| 631 | #if defined(_KERNEL) && defined(__linux__) |
| 632 |