// SPDX-License-Identifier: GPL-2.0-only
/*
 *  Copyright (c) 2013
 *  Minchan Kim <minchan@kernel.org>
 */
#include <linux/types.h>
#include <linux/mutex.h>
#include <linux/slab.h>
#include <linux/bio.h>
#include <linux/sched.h>
#include <linux/wait.h>
#include <linux/cpumask.h>

#include "squashfs_fs.h"
#include "squashfs_fs_sb.h"
#include "decompressor.h"
#include "squashfs.h"

/*
 * This file implements multi-threaded decompression in the
 * decompressor framework
 */


/*
 * The reason that multiply two is that a CPU can request new I/O
 * while it is waiting previous request.
 */
#define MAX_DECOMPRESSOR	(num_online_cpus() * 2)


static int squashfs_max_decompressors(void)
{
	return MAX_DECOMPRESSOR;
}

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,
					struct squashfs_stream *stream)
{
	struct decomp_stream *decomp_strm;

	while (1) {
		mutex_lock(&stream->mutex);

		/* There is available decomp_stream */
		if (!list_empty(&stream->strm_list)) {
			decomp_strm = list_entry(stream->strm_list.prev,
				struct decomp_stream, list);
			list_del(&decomp_strm->list);
			mutex_unlock(&stream->mutex);
			break;
		}

		/*
		 * If there is no available decomp and already full,
		 * let's wait for releasing decomp from other users.
		 */
		if (stream->avail_decomp >= msblk->max_thread_num)
			goto wait;

		/* Let's allocate new decomp */
		decomp_strm = kmalloc_obj(*decomp_strm);
		if (!decomp_strm)
			goto wait;

		decomp_strm->stream = msblk->decompressor->init(msblk,
						stream->comp_opts);
		if (IS_ERR(decomp_strm->stream)) {
			kfree(decomp_strm);
			goto wait;
		}

		stream->avail_decomp++;
		WARN_ON(stream->avail_decomp > msblk->max_thread_num);

		mutex_unlock(&stream->mutex);
		break;
wait:
		/*
		 * If system memory is tough, let's for other's
		 * releasing instead of hurting VM because it could
		 * make page cache thrashing.
		 */
		mutex_unlock(&stream->mutex);
		wait_event(stream->wait,
			!list_empty(&stream->strm_list));
	}

	return decomp_strm;
}


static int squashfs_decompress(struct squashfs_sb_info *msblk, struct bio *bio,
			int offset, int length,
			struct squashfs_page_actor *output)
{
	int res;
	struct squashfs_stream *stream = msblk->stream;
	struct decomp_stream *decomp_stream = get_decomp_stream(msblk, stream);
	res = msblk->decompressor->decompress(msblk, decomp_stream->stream,
		bio, offset, length, output);
	put_decomp_stream(decomp_stream, stream);
	if (res < 0)
		ERROR("%s decompression failed, data probably corrupt\n",
			msblk->decompressor->name);
	return res;
}

const struct squashfs_decompressor_thread_ops squashfs_decompressor_multi = {
	.create = squashfs_decompressor_create,
	.destroy = squashfs_decompressor_destroy,
	.decompress = squashfs_decompress,
	.max_decompressors = squashfs_max_decompressors,
};
