Skip to content

Commit 415403b

Browse files
sergey-senozhatskytorvalds
authored andcommitted
zram: use crypto api to check alg availability
There is no way to get a string with all the crypto comp algorithms supported by the crypto comp engine, so we need to maintain our own backends list. At the same time we additionally need to use crypto_has_comp() to make sure that the user has requested a compression algorithm that is recognized by the crypto comp engine. Relying on /proc/crypto is not an options here, because it does not show not-yet-inserted compression modules. Example: modprobe zram cat /proc/crypto | grep -i lz4 modprobe lz4 cat /proc/crypto | grep -i lz4 name : lz4 driver : lz4-generic module : lz4 So the user can't tell exactly if the lz4 is really supported from /proc/crypto output, unless someone or something has loaded it. This patch also adds crypto_has_comp() to zcomp_available_show(). We store all the compression algorithms names in zcomp's `backends' array, regardless the CONFIG_CRYPTO_FOO configuration, but show only those that are also supported by crypto engine. This helps user to know the exact list of compression algorithms that can be used. Example: module lz4 is not loaded yet, but is supported by the crypto engine. /proc/crypto has no information on this module, while zram's `comp_algorithm' lists it: cat /proc/crypto | grep -i lz4 cat /sys/block/zram0/comp_algorithm [lzo] lz4 deflate lz4hc 842 We still use the `backends' array to determine if the requested compression backend is known to crypto api. This array, however, may not contain some entries, therefore as the last step we call crypto_has_comp() function which attempts to insmod the requested compression algorithm to determine if crypto api supports it. The advantage of this method is that now we permit the usage of out-of-tree crypto compression modules (implementing S/W or H/W compression). [[email protected]: zram-use-crypto-api-to-check-alg-availability-v3] Link: http://lkml.kernel.org/r/[email protected] Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: Sergey Senozhatsky <[email protected]> Acked-by: Minchan Kim <[email protected]> Cc: Joonsoo Kim <[email protected]> Signed-off-by: Sergey Senozhatsky <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent ebaf9ab commit 415403b

File tree

4 files changed

+60
-33
lines changed

4 files changed

+60
-33
lines changed

Documentation/blockdev/zram.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,17 @@ pre-created. Default: 1.
8383
#select lzo compression algorithm
8484
echo lzo > /sys/block/zram0/comp_algorithm
8585

86+
For the time being, the `comp_algorithm' content does not necessarily
87+
show every compression algorithm supported by the kernel. We keep this
88+
list primarily to simplify device configuration and one can configure
89+
a new device with a compression algorithm that is not listed in
90+
`comp_algorithm'. The thing is that, internally, ZRAM uses Crypto API
91+
and, if some of the algorithms were built as modules, it's impossible
92+
to list all of them using, for instance, /proc/crypto or any other
93+
method. This, however, has an advantage of permitting the usage of
94+
custom crypto compression modules (implementing S/W or H/W
95+
compression).
96+
8697
4) Set Disksize
8798
Set disk size by writing the value to sysfs node 'disksize'.
8899
The value can be either in bytes or you can use mem suffixes.

drivers/block/zram/zcomp.c

Lines changed: 37 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -26,17 +26,6 @@ static const char * const backends[] = {
2626
NULL
2727
};
2828

29-
static const char *find_backend(const char *compress)
30-
{
31-
int i = 0;
32-
while (backends[i]) {
33-
if (sysfs_streq(compress, backends[i]))
34-
break;
35-
i++;
36-
}
37-
return backends[i];
38-
}
39-
4029
static void zcomp_strm_free(struct zcomp_strm *zstrm)
4130
{
4231
if (!IS_ERR_OR_NULL(zstrm->tfm))
@@ -68,30 +57,56 @@ static struct zcomp_strm *zcomp_strm_alloc(struct zcomp *comp, gfp_t flags)
6857
return zstrm;
6958
}
7059

60+
bool zcomp_available_algorithm(const char *comp)
61+
{
62+
int i = 0;
63+
64+
while (backends[i]) {
65+
if (sysfs_streq(comp, backends[i]))
66+
return true;
67+
i++;
68+
}
69+
70+
/*
71+
* Crypto does not ignore a trailing new line symbol,
72+
* so make sure you don't supply a string containing
73+
* one.
74+
* This also means that we permit zcomp initialisation
75+
* with any compressing algorithm known to crypto api.
76+
*/
77+
return crypto_has_comp(comp, 0, 0) == 1;
78+
}
79+
7180
/* show available compressors */
7281
ssize_t zcomp_available_show(const char *comp, char *buf)
7382
{
83+
bool known_algorithm = false;
7484
ssize_t sz = 0;
7585
int i = 0;
7686

77-
while (backends[i]) {
78-
if (!strcmp(comp, backends[i]))
87+
for (; backends[i]; i++) {
88+
if (!strcmp(comp, backends[i])) {
89+
known_algorithm = true;
7990
sz += scnprintf(buf + sz, PAGE_SIZE - sz - 2,
8091
"[%s] ", backends[i]);
81-
else
92+
} else {
8293
sz += scnprintf(buf + sz, PAGE_SIZE - sz - 2,
8394
"%s ", backends[i]);
84-
i++;
95+
}
8596
}
97+
98+
/*
99+
* Out-of-tree module known to crypto api or a missing
100+
* entry in `backends'.
101+
*/
102+
if (!known_algorithm && crypto_has_comp(comp, 0, 0) == 1)
103+
sz += scnprintf(buf + sz, PAGE_SIZE - sz - 2,
104+
"[%s] ", comp);
105+
86106
sz += scnprintf(buf + sz, PAGE_SIZE - sz, "\n");
87107
return sz;
88108
}
89109

90-
bool zcomp_available_algorithm(const char *comp)
91-
{
92-
return find_backend(comp) != NULL;
93-
}
94-
95110
struct zcomp_strm *zcomp_stream_get(struct zcomp *comp)
96111
{
97112
return *get_cpu_ptr(comp->stream);
@@ -227,18 +242,16 @@ void zcomp_destroy(struct zcomp *comp)
227242
struct zcomp *zcomp_create(const char *compress)
228243
{
229244
struct zcomp *comp;
230-
const char *backend;
231245
int error;
232246

233-
backend = find_backend(compress);
234-
if (!backend)
247+
if (!zcomp_available_algorithm(compress))
235248
return ERR_PTR(-EINVAL);
236249

237250
comp = kzalloc(sizeof(struct zcomp), GFP_KERNEL);
238251
if (!comp)
239252
return ERR_PTR(-ENOMEM);
240253

241-
comp->name = backend;
254+
comp->name = compress;
242255
error = zcomp_init(comp);
243256
if (error) {
244257
kfree(comp);

drivers/block/zram/zram_drv.c

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -342,9 +342,16 @@ static ssize_t comp_algorithm_store(struct device *dev,
342342
struct device_attribute *attr, const char *buf, size_t len)
343343
{
344344
struct zram *zram = dev_to_zram(dev);
345+
char compressor[CRYPTO_MAX_ALG_NAME];
345346
size_t sz;
346347

347-
if (!zcomp_available_algorithm(buf))
348+
strlcpy(compressor, buf, sizeof(compressor));
349+
/* ignore trailing newline */
350+
sz = strlen(compressor);
351+
if (sz > 0 && compressor[sz - 1] == '\n')
352+
compressor[sz - 1] = 0x00;
353+
354+
if (!zcomp_available_algorithm(compressor))
348355
return -EINVAL;
349356

350357
down_write(&zram->init_lock);
@@ -353,13 +360,8 @@ static ssize_t comp_algorithm_store(struct device *dev,
353360
pr_info("Can't change algorithm for initialized device\n");
354361
return -EBUSY;
355362
}
356-
strlcpy(zram->compressor, buf, sizeof(zram->compressor));
357-
358-
/* ignore trailing newline */
359-
sz = strlen(zram->compressor);
360-
if (sz > 0 && zram->compressor[sz - 1] == '\n')
361-
zram->compressor[sz - 1] = 0x00;
362363

364+
strlcpy(zram->compressor, compressor, sizeof(compressor));
363365
up_write(&zram->init_lock);
364366
return len;
365367
}

drivers/block/zram/zram_drv.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,9 @@
1515
#ifndef _ZRAM_DRV_H_
1616
#define _ZRAM_DRV_H_
1717

18-
#include <linux/spinlock.h>
18+
#include <linux/rwsem.h>
1919
#include <linux/zsmalloc.h>
20+
#include <linux/crypto.h>
2021

2122
#include "zcomp.h"
2223

@@ -113,7 +114,7 @@ struct zram {
113114
* we can store in a disk.
114115
*/
115116
u64 disksize; /* bytes */
116-
char compressor[10];
117+
char compressor[CRYPTO_MAX_ALG_NAME];
117118
/*
118119
* zram is claimed so open request will be failed
119120
*/

0 commit comments

Comments
 (0)