Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

zram: unify and harden algo/priority params handling

We have two functions that accept algo= and priority= params -
algorithm_params_store() and recompress_store(). This patch unifies and
hardens handling of those parameters.

There are 4 possible cases:

- only priority= provided [recommended]
We need to verify that provided priority value is
within permitted range for each particular function.

- both algo= and priority= provided
We cannot prioritize one over another. All we should
do is to verify that zram is configured in the way
that user-space expects it to be. Namely that zram
indeed has compressor algo= setup at given priority=.

- only algo= provided [not recommended]
We should lookup priority in compressors list.

- none provided [not recommended]
Just use function's defaults.

Link: https://lkml.kernel.org/r/20260311084312.1766036-7-senozhatsky@chromium.org
Signed-off-by: Sergey Senozhatsky <senozhatsky@chromium.org>
Suggested-by: Minchan Kim <minchan@kernel.org>
Cc: Brian Geffon <bgeffon@google.com>
Cc: gao xu <gaoxu2@honor.com>
Cc: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Sergey Senozhatsky and committed by
Andrew Morton
301f3922 cedfa028

+68 -42
+68 -42
drivers/block/zram/zram_drv.c
··· 1619 1619 static void zram_debugfs_unregister(struct zram *zram) {}; 1620 1620 #endif 1621 1621 1622 + /* Only algo parameter given, lookup by algo name */ 1623 + static int lookup_algo_priority(struct zram *zram, const char *algo, 1624 + u32 min_prio) 1625 + { 1626 + s32 prio; 1627 + 1628 + for (prio = min_prio; prio < ZRAM_MAX_COMPS; prio++) { 1629 + if (!zram->comp_algs[prio]) 1630 + continue; 1631 + 1632 + if (!strcmp(zram->comp_algs[prio], algo)) 1633 + return prio; 1634 + } 1635 + 1636 + return -EINVAL; 1637 + } 1638 + 1639 + /* Both algo and priority parameters given, validate them */ 1640 + static int validate_algo_priority(struct zram *zram, const char *algo, u32 prio) 1641 + { 1642 + if (prio >= ZRAM_MAX_COMPS) 1643 + return -EINVAL; 1644 + /* No algo at given priority */ 1645 + if (!zram->comp_algs[prio]) 1646 + return -EINVAL; 1647 + /* A different algo at given priority */ 1648 + if (strcmp(zram->comp_algs[prio], algo)) 1649 + return -EINVAL; 1650 + return 0; 1651 + } 1652 + 1622 1653 static void comp_algorithm_set(struct zram *zram, u32 prio, const char *alg) 1623 1654 { 1624 1655 zram->comp_algs[prio] = alg; ··· 1722 1691 char *args, *param, *val, *algo = NULL, *dict_path = NULL; 1723 1692 struct deflate_params deflate_params; 1724 1693 struct zram *zram = dev_to_zram(dev); 1694 + bool prio_param = false; 1725 1695 int ret; 1726 1696 1727 1697 deflate_params.winbits = ZCOMP_PARAM_NOT_SET; ··· 1735 1703 return -EINVAL; 1736 1704 1737 1705 if (!strcmp(param, "priority")) { 1706 + prio_param = true; 1738 1707 ret = kstrtoint(val, 10, &prio); 1739 1708 if (ret) 1740 1709 return ret; ··· 1771 1738 if (init_done(zram)) 1772 1739 return -EBUSY; 1773 1740 1774 - /* Lookup priority by algorithm name */ 1775 - if (algo) { 1776 - s32 p; 1777 - 1778 - prio = -EINVAL; 1779 - for (p = ZRAM_PRIMARY_COMP; p < ZRAM_MAX_COMPS; p++) { 1780 - if (!zram->comp_algs[p]) 1781 - continue; 1782 - 1783 - if (!strcmp(zram->comp_algs[p], algo)) { 1784 - prio = p; 1785 - break; 1786 - } 1787 - } 1741 + if (prio_param) { 1742 + if (prio < ZRAM_PRIMARY_COMP || prio >= ZRAM_MAX_COMPS) 1743 + return -EINVAL; 1788 1744 } 1789 1745 1790 - if (prio < ZRAM_PRIMARY_COMP || prio >= ZRAM_MAX_COMPS) 1791 - return -EINVAL; 1746 + if (algo && prio_param) { 1747 + ret = validate_algo_priority(zram, algo, prio); 1748 + if (ret) 1749 + return ret; 1750 + } 1751 + 1752 + if (algo && !prio_param) { 1753 + prio = lookup_algo_priority(zram, algo, ZRAM_PRIMARY_COMP); 1754 + if (prio < 0) 1755 + return -EINVAL; 1756 + } 1792 1757 1793 1758 ret = comp_params_store(zram, prio, level, dict_path, &deflate_params); 1794 1759 return ret ? ret : len; ··· 2427 2396 void *src; 2428 2397 int ret = 0; 2429 2398 2430 - if (!zram->comps[prio]) 2431 - return -EINVAL; 2432 - 2433 2399 handle_old = get_slot_handle(zram, index); 2434 2400 if (!handle_old) 2435 2401 return -EINVAL; ··· 2528 2500 char *args, *param, *val, *algo = NULL; 2529 2501 u64 num_recomp_pages = ULLONG_MAX; 2530 2502 struct zram_pp_ctl *ctl = NULL; 2531 - u32 prio = ZRAM_SECONDARY_COMP; 2532 - struct zram_pp_slot *pps; 2503 + s32 prio = ZRAM_SECONDARY_COMP; 2533 2504 u32 mode = 0, threshold = 0; 2505 + struct zram_pp_slot *pps; 2534 2506 struct page *page = NULL; 2507 + bool prio_param = false; 2535 2508 ssize_t ret; 2536 2509 2537 2510 args = skip_spaces(buf); ··· 2580 2551 } 2581 2552 2582 2553 if (!strcmp(param, "priority")) { 2583 - ret = kstrtouint(val, 10, &prio); 2554 + prio_param = true; 2555 + ret = kstrtoint(val, 10, &prio); 2584 2556 if (ret) 2585 2557 return ret; 2586 2558 continue; ··· 2595 2565 if (!init_done(zram)) 2596 2566 return -EINVAL; 2597 2567 2598 - if (algo) { 2599 - bool found = false; 2600 - 2601 - for (; prio < ZRAM_MAX_COMPS; prio++) { 2602 - if (!zram->comp_algs[prio]) 2603 - continue; 2604 - 2605 - if (!strcmp(zram->comp_algs[prio], algo)) { 2606 - found = true; 2607 - break; 2608 - } 2609 - } 2610 - 2611 - if (!found) { 2612 - ret = -EINVAL; 2613 - goto out; 2614 - } 2568 + if (prio_param) { 2569 + if (prio < ZRAM_SECONDARY_COMP || prio >= ZRAM_MAX_COMPS) 2570 + return -EINVAL; 2615 2571 } 2616 2572 2617 - if (prio < ZRAM_SECONDARY_COMP || prio >= ZRAM_MAX_COMPS) { 2618 - ret = -EINVAL; 2619 - goto out; 2573 + if (algo && prio_param) { 2574 + ret = validate_algo_priority(zram, algo, prio); 2575 + if (ret) 2576 + return ret; 2620 2577 } 2578 + 2579 + if (algo && !prio_param) { 2580 + prio = lookup_algo_priority(zram, algo, ZRAM_SECONDARY_COMP); 2581 + if (prio < 0) 2582 + return -EINVAL; 2583 + } 2584 + 2585 + if (!zram->comps[prio]) 2586 + return -EINVAL; 2621 2587 2622 2588 page = alloc_page(GFP_KERNEL); 2623 2589 if (!page) {