]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
zram: pass buffer offset to zcomp_available_show()
authorSergey Senozhatsky <senozhatsky@chromium.org>
Fri, 27 Jun 2025 07:18:21 +0000 (16:18 +0900)
committerJens Axboe <axboe@kernel.dk>
Fri, 4 Jul 2025 01:56:51 +0000 (19:56 -0600)
In most cases zcomp_available_show() is the only emitting
function that is called from sysfs read() handler, so it
assumes that there is a whole PAGE_SIZE buffer to work with.
There is an exception, however: recomp_algorithm_show().

In recomp_algorithm_show() we prepend the buffer with
priority number before we pass it to zcomp_available_show(),
so it cannot assume PAGE_SIZE anymore and must take
recomp_algorithm_show() modifications into consideration.
Therefore we need to pass buffer offset to zcomp_available_show().

Also convert it to use sysfs_emit_at(), to stay aligned
with the rest of zram's sysfs read() handlers.

On practice we are never even close to using the whole PAGE_SIZE
buffer, so that's not a critical bug, but still.

Signed-off-by: Sergey Senozhatsky <senozhatsky@chromium.org>
Link: https://lore.kernel.org/r/20250627071840.1394242-1-senozhatsky@chromium.org
Signed-off-by: Jens Axboe <axboe@kernel.dk>
drivers/block/zram/zcomp.c
drivers/block/zram/zcomp.h
drivers/block/zram/zram_drv.c

index d26a58c67e95f1e3d4716040f53c5d85160c6477..b1bd1daa0060a5b437d947d504d9ee6b4a9ac152 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/sched.h>
 #include <linux/cpuhotplug.h>
 #include <linux/vmalloc.h>
+#include <linux/sysfs.h>
 
 #include "zcomp.h"
 
@@ -89,23 +90,21 @@ bool zcomp_available_algorithm(const char *comp)
 }
 
 /* show available compressors */
-ssize_t zcomp_available_show(const char *comp, char *buf)
+ssize_t zcomp_available_show(const char *comp, char *buf, ssize_t at)
 {
-       ssize_t sz = 0;
        int i;
 
        for (i = 0; i < ARRAY_SIZE(backends) - 1; i++) {
                if (!strcmp(comp, backends[i]->name)) {
-                       sz += scnprintf(buf + sz, PAGE_SIZE - sz - 2,
-                                       "[%s] ", backends[i]->name);
+                       at += sysfs_emit_at(buf, at, "[%s] ",
+                                           backends[i]->name);
                } else {
-                       sz += scnprintf(buf + sz, PAGE_SIZE - sz - 2,
-                                       "%s ", backends[i]->name);
+                       at += sysfs_emit_at(buf, at, "%s ", backends[i]->name);
                }
        }
 
-       sz += scnprintf(buf + sz, PAGE_SIZE - sz, "\n");
-       return sz;
+       at += sysfs_emit_at(buf, at, "\n");
+       return at;
 }
 
 struct zcomp_strm *zcomp_stream_get(struct zcomp *comp)
index 4acffe671a5eafd352d60dbfa62769e3c797f6c5..eacfd3f7d61d9395694292713fb5da4f0023d6d7 100644 (file)
@@ -79,7 +79,7 @@ struct zcomp {
 
 int zcomp_cpu_up_prepare(unsigned int cpu, struct hlist_node *node);
 int zcomp_cpu_dead(unsigned int cpu, struct hlist_node *node);
-ssize_t zcomp_available_show(const char *comp, char *buf);
+ssize_t zcomp_available_show(const char *comp, char *buf, ssize_t at);
 bool zcomp_available_algorithm(const char *comp);
 
 struct zcomp *zcomp_create(const char *alg, struct zcomp_params *params);
index 385aaaa2531b8f025a9dd6e7ff949cba46ca9508..8acad3cc6e6ea16ccef7e898fd840e5994e2264b 100644 (file)
@@ -1225,12 +1225,13 @@ static void comp_algorithm_set(struct zram *zram, u32 prio, const char *alg)
        zram->comp_algs[prio] = alg;
 }
 
-static ssize_t __comp_algorithm_show(struct zram *zram, u32 prio, char *buf)
+static ssize_t __comp_algorithm_show(struct zram *zram, u32 prio,
+                                    char *buf, ssize_t at)
 {
        ssize_t sz;
 
        down_read(&zram->init_lock);
-       sz = zcomp_available_show(zram->comp_algs[prio], buf);
+       sz = zcomp_available_show(zram->comp_algs[prio], buf, at);
        up_read(&zram->init_lock);
 
        return sz;
@@ -1387,7 +1388,7 @@ static ssize_t comp_algorithm_show(struct device *dev,
 {
        struct zram *zram = dev_to_zram(dev);
 
-       return __comp_algorithm_show(zram, ZRAM_PRIMARY_COMP, buf);
+       return __comp_algorithm_show(zram, ZRAM_PRIMARY_COMP, buf, 0);
 }
 
 static ssize_t comp_algorithm_store(struct device *dev,
@@ -1416,7 +1417,7 @@ static ssize_t recomp_algorithm_show(struct device *dev,
                        continue;
 
                sz += sysfs_emit_at(buf, sz, "#%d: ", prio);
-               sz += __comp_algorithm_show(zram, prio, buf + sz);
+               sz += __comp_algorithm_show(zram, prio, buf, sz);
        }
 
        return sz;