// SPDX-License-Identifier: GPL-2.0-or-later
/*
 *   Copyright (C) 2019 Samsung Electronics Co., Ltd.
 */

#include <linux/list.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/workqueue.h>

#include "server.h"
#include "connection.h"
#include "ksmbd_work.h"
#include "mgmt/ksmbd_ida.h"

static struct kmem_cache *work_cache;
static struct workqueue_struct *ksmbd_wq;

struct ksmbd_work *ksmbd_alloc_work_struct(void)
{
	struct ksmbd_work *work = kmem_cache_zalloc(work_cache, GFP_KERNEL);

	if (work) {
		work->compound_fid = KSMBD_NO_FID;
		work->compound_pfid = KSMBD_NO_FID;
		INIT_LIST_HEAD(&work->request_entry);
		INIT_LIST_HEAD(&work->async_request_entry);
		INIT_LIST_HEAD(&work->fp_entry);
		INIT_LIST_HEAD(&work->interim_entry);
		INIT_LIST_HEAD(&work->aux_read_list);
		work->iov_alloc_cnt = 4;
		work->iov = kcalloc(work->iov_alloc_cnt, sizeof(struct kvec),
				    GFP_KERNEL);
		if (!work->iov) {
			kmem_cache_free(work_cache, work);
			work = NULL;
		}
	}
	return work;
}

void ksmbd_free_work_struct(struct ksmbd_work *work)
{
	struct aux_read *ar, *tmp;

	WARN_ON(work->saved_cred != NULL);

	kvfree(work->response_buf);

	list_for_each_entry_safe(ar, tmp, &work->aux_read_list, entry) {
		kvfree(ar->buf);
		list_del(&ar->entry);
		kfree(ar);
	}

	kfree(work->tr_buf);
	kvfree(work->request_buf);
	kfree(work->iov);
	if (work->async_id)
		ksmbd_release_id(&work->conn->async_ida, work->async_id);
	kmem_cache_free(work_cache, work);
}

void ksmbd_work_pool_destroy(void)
{
	kmem_cache_destroy(work_cache);
}

int ksmbd_work_pool_init(void)
{
	work_cache = kmem_cache_create("ksmbd_work_cache",
				       sizeof(struct ksmbd_work), 0,
				       SLAB_HWCACHE_ALIGN, NULL);
	if (!work_cache)
		return -ENOMEM;
	return 0;
}

int ksmbd_workqueue_init(void)
{
	ksmbd_wq = alloc_workqueue("ksmbd-io", 0, 0);
	if (!ksmbd_wq)
		return -ENOMEM;
	return 0;
}

void ksmbd_workqueue_destroy(void)
{
	destroy_workqueue(ksmbd_wq);
	ksmbd_wq = NULL;
}

bool ksmbd_queue_work(struct ksmbd_work *work)
{
	return queue_work(ksmbd_wq, &work->work);
}

static int ksmbd_realloc_iov_pin(struct ksmbd_work *work, void *ib,
				 unsigned int ib_len)
{

	if (work->iov_alloc_cnt <= work->iov_cnt) {
		struct kvec *new;

		work->iov_alloc_cnt += 4;
		new = krealloc(work->iov,
			       sizeof(struct kvec) * work->iov_alloc_cnt,
			       GFP_KERNEL | __GFP_ZERO);
		if (!new)
			return -ENOMEM;
		work->iov = new;
	}

	work->iov[++work->iov_idx].iov_base = ib;
	work->iov[work->iov_idx].iov_len = ib_len;
	work->iov_cnt++;

	return 0;
}

static int __ksmbd_iov_pin_rsp(struct ksmbd_work *work, void *ib, int len,
			       void *aux_buf, unsigned int aux_size)
{
	/* Plus rfc_length size on first iov */
	if (!work->iov_idx) {
		work->iov[work->iov_idx].iov_base = work->response_buf;
		*(__be32 *)work->iov[0].iov_base = 0;
		work->iov[work->iov_idx].iov_len = 4;
		work->iov_cnt++;
	}

	ksmbd_realloc_iov_pin(work, ib, len);
	inc_rfc1001_len(work->iov[0].iov_base, len);

	if (aux_size) {
		struct aux_read *ar;

		ksmbd_realloc_iov_pin(work, aux_buf, aux_size);
		inc_rfc1001_len(work->iov[0].iov_base, aux_size);

		ar = kmalloc(sizeof(struct aux_read), GFP_KERNEL);
		if (!ar)
			return -ENOMEM;

		ar->buf = aux_buf;
		list_add(&ar->entry, &work->aux_read_list);
	}

	return 0;
}

int ksmbd_iov_pin_rsp(struct ksmbd_work *work, void *ib, int len)
{
	return __ksmbd_iov_pin_rsp(work, ib, len, NULL, 0);
}

int ksmbd_iov_pin_rsp_read(struct ksmbd_work *work, void *ib, int len,
			   void *aux_buf, unsigned int aux_size)
{
	return __ksmbd_iov_pin_rsp(work, ib, len, aux_buf, aux_size);
}

int allocate_interim_rsp_buf(struct ksmbd_work *work)
{
	work->response_buf = kzalloc(MAX_CIFS_SMALL_BUFFER_SIZE, GFP_KERNEL);
	if (!work->response_buf)
		return -ENOMEM;
	work->response_sz = MAX_CIFS_SMALL_BUFFER_SIZE;
	return 0;
}
