fs/squashfs/decompressor_multi.c

Source file repositories/reference/linux-study-clean/fs/squashfs/decompressor_multi.c

File Facts

System
Linux kernel
Corpus path
fs/squashfs/decompressor_multi.c
Extension
.c
Size
4818 bytes
Lines
204
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 squashfs_stream {
	void			*comp_opts;
	struct list_head	strm_list;
	struct mutex		mutex;
	int			avail_decomp;
	wait_queue_head_t	wait;
};


struct decomp_stream {
	void *stream;
	struct list_head list;
};


static void put_decomp_stream(struct decomp_stream *decomp_strm,
				struct squashfs_stream *stream)
{
	mutex_lock(&stream->mutex);
	list_add(&decomp_strm->list, &stream->strm_list);
	mutex_unlock(&stream->mutex);
	wake_up(&stream->wait);
}

static void *squashfs_decompressor_create(struct squashfs_sb_info *msblk,
				void *comp_opts)
{
	struct squashfs_stream *stream;
	struct decomp_stream *decomp_strm = NULL;
	int err = -ENOMEM;

	stream = kzalloc_obj(*stream);
	if (!stream)
		goto out;

	stream->comp_opts = comp_opts;
	mutex_init(&stream->mutex);
	INIT_LIST_HEAD(&stream->strm_list);
	init_waitqueue_head(&stream->wait);

	/*
	 * We should have a decompressor at least as default
	 * so if we fail to allocate new decompressor dynamically,
	 * we could always fall back to default decompressor and
	 * file system works.
	 */
	decomp_strm = kmalloc_obj(*decomp_strm);
	if (!decomp_strm)
		goto out;

	decomp_strm->stream = msblk->decompressor->init(msblk,
						stream->comp_opts);
	if (IS_ERR(decomp_strm->stream)) {
		err = PTR_ERR(decomp_strm->stream);
		goto out;
	}

	list_add(&decomp_strm->list, &stream->strm_list);
	stream->avail_decomp = 1;
	return stream;

out:
	kfree(decomp_strm);
	kfree(stream);
	return ERR_PTR(err);
}


static void squashfs_decompressor_destroy(struct squashfs_sb_info *msblk)
{
	struct squashfs_stream *stream = msblk->stream;
	if (stream) {
		struct decomp_stream *decomp_strm;

		while (!list_empty(&stream->strm_list)) {
			decomp_strm = list_entry(stream->strm_list.prev,
						struct decomp_stream, list);
			list_del(&decomp_strm->list);
			msblk->decompressor->free(decomp_strm->stream);
			kfree(decomp_strm);
			stream->avail_decomp--;
		}
		WARN_ON(stream->avail_decomp);
		kfree(stream->comp_opts);
		kfree(stream);
	}
}


static struct decomp_stream *get_decomp_stream(struct squashfs_sb_info *msblk,

Annotation

Implementation Notes