fs/erofs/decompressor_crypto.c

Source file repositories/reference/linux-study-clean/fs/erofs/decompressor_crypto.c

File Facts

System
Linux kernel
Corpus path
fs/erofs/decompressor_crypto.c
Extension
.c
Size
4351 bytes
Lines
183
Domain
Core OS
Bucket
VFS And Filesystem Core
Inferred role
Core OS: implementation source
Status
source implementation candidate

Why This File Exists

Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.

Dependency Surface

Detected Declarations

Annotated Snippet

struct z_erofs_crypto_engine {
	char *crypto_name;
	struct crypto_acomp *tfm;
};

static struct z_erofs_crypto_engine *z_erofs_crypto[Z_EROFS_COMPRESSION_MAX] = {
	[Z_EROFS_COMPRESSION_LZ4] = (struct z_erofs_crypto_engine[]) {
		{},
	},
	[Z_EROFS_COMPRESSION_LZMA] = (struct z_erofs_crypto_engine[]) {
		{},
	},
	[Z_EROFS_COMPRESSION_DEFLATE] = (struct z_erofs_crypto_engine[]) {
		{ .crypto_name = "qat_deflate", },
		{},
	},
	[Z_EROFS_COMPRESSION_ZSTD] = (struct z_erofs_crypto_engine[]) {
		{},
	},
};
static DECLARE_RWSEM(z_erofs_crypto_rwsem);

static struct crypto_acomp *z_erofs_crypto_get_engine(int alg)
{
	struct z_erofs_crypto_engine *e;

	for (e = z_erofs_crypto[alg]; e->crypto_name; ++e)
		if (e->tfm)
			return e->tfm;
	return NULL;
}

int z_erofs_crypto_decompress(struct z_erofs_decompress_req *rq,
			      struct page **pgpl)
{
	struct crypto_acomp *tfm;
	int i, err;

	down_read(&z_erofs_crypto_rwsem);
	tfm = z_erofs_crypto_get_engine(rq->alg);
	if (!tfm) {
		err = -EOPNOTSUPP;
		goto out;
	}

	for (i = 0; i < rq->outpages; i++) {
		struct page *const page = rq->out[i];
		struct page *victim;

		if (!page) {
			victim = __erofs_allocpage(pgpl, rq->gfp, true);
			if (!victim) {
				err = -ENOMEM;
				goto out;
			}
			set_page_private(victim, Z_EROFS_SHORTLIVED_PAGE);
			rq->out[i] = victim;
		}
	}
	err = __z_erofs_crypto_decompress(rq, tfm);
out:
	up_read(&z_erofs_crypto_rwsem);
	return err;
}

int z_erofs_crypto_enable_engine(const char *name, int len)
{
	struct z_erofs_crypto_engine *e;
	struct crypto_acomp *tfm;
	int alg;

	down_write(&z_erofs_crypto_rwsem);
	for (alg = 0; alg < Z_EROFS_COMPRESSION_MAX; ++alg) {
		for (e = z_erofs_crypto[alg]; e->crypto_name; ++e) {
			if (!strncmp(name, e->crypto_name, len)) {
				if (e->tfm)
					break;
				tfm = crypto_alloc_acomp(e->crypto_name, 0, 0);
				if (IS_ERR(tfm)) {
					up_write(&z_erofs_crypto_rwsem);
					return -EOPNOTSUPP;
				}
				e->tfm = tfm;
				break;
			}
		}
	}
	up_write(&z_erofs_crypto_rwsem);
	return 0;
}

Annotation

Implementation Notes