// SPDX-License-Identifier: GPL-2.0-or-later
#include <linux/blk_types.h>

#include "cache.h"
#include "cache_dev.h"
#include "backing_dev.h"
#include "dm_pcache.h"

struct kmem_cache *key_cache;

static inline struct pcache_cache_info *get_cache_info_addr(struct pcache_cache *cache)
{
	return (struct pcache_cache_info *)((char *)cache->cache_info_addr +
						(size_t)cache->info_index * PCACHE_CACHE_INFO_SIZE);
}

static void cache_info_write(struct pcache_cache *cache)
{
	struct pcache_cache_info *cache_info = &cache->cache_info;

	cache_info->header.seq++;
	cache_info->header.crc = pcache_meta_crc(&cache_info->header,
						sizeof(struct pcache_cache_info));

	cache->info_index = (cache->info_index + 1) % PCACHE_META_INDEX_MAX;
	memcpy_flushcache(get_cache_info_addr(cache), cache_info,
			sizeof(struct pcache_cache_info));
	pmem_wmb();
}

static void cache_info_init_default(struct pcache_cache *cache);
static int cache_info_init(struct pcache_cache *cache, struct pcache_cache_options *opts)
{
	struct dm_pcache *pcache = CACHE_TO_PCACHE(cache);
	struct pcache_cache_info *cache_info_addr;

	cache_info_addr = pcache_meta_find_latest(&cache->cache_info_addr->header,
						sizeof(struct pcache_cache_info),
						PCACHE_CACHE_INFO_SIZE,
						&cache->cache_info);
	if (IS_ERR(cache_info_addr))
		return PTR_ERR(cache_info_addr);

	if (cache_info_addr) {
		if (opts->data_crc !=
				(cache->cache_info.flags & PCACHE_CACHE_FLAGS_DATA_CRC)) {
			pcache_dev_err(pcache, "invalid option for data_crc: %s, expected: %s",
					opts->data_crc ? "true" : "false",
					cache->cache_info.flags & PCACHE_CACHE_FLAGS_DATA_CRC ? "true" : "false");
			return -EINVAL;
		}

		cache->info_index = ((char *)cache_info_addr - (char *)cache->cache_info_addr) / PCACHE_CACHE_INFO_SIZE;

		return 0;
	}

	/* init cache_info for new cache */
	cache_info_init_default(cache);
	cache_mode_set(cache, opts->cache_mode);
	if (opts->data_crc)
		cache->cache_info.flags |= PCACHE_CACHE_FLAGS_DATA_CRC;

	return 0;
}

static void cache_info_set_gc_percent(struct pcache_cache_info *cache_info, u8 percent)
{
	cache_info->flags &= ~PCACHE_CACHE_FLAGS_GC_PERCENT_MASK;
	cache_info->flags |= FIELD_PREP(PCACHE_CACHE_FLAGS_GC_PERCENT_MASK, percent);
}

int pcache_cache_set_gc_percent(struct pcache_cache *cache, u8 percent)
{
	if (percent > PCACHE_CACHE_GC_PERCENT_MAX || percent < PCACHE_CACHE_GC_PERCENT_MIN)
		return -EINVAL;

	mutex_lock(&cache->cache_info_lock);
	cache_info_set_gc_percent(&cache->cache_info, percent);

	cache_info_write(cache);
	mutex_unlock(&cache->cache_info_lock);

	return 0;
}

void cache_pos_encode(struct pcache_cache *cache,
			     struct pcache_cache_pos_onmedia *pos_onmedia_base,
			     struct pcache_cache_pos *pos, u64 seq, u32 *index)
{
	struct pcache_cache_pos_onmedia pos_onmedia;
	struct pcache_cache_pos_onmedia *pos_onmedia_addr = pos_onmedia_base + *index;

	pos_onmedia.cache_seg_id = pos->cache_seg->cache_seg_id;
	pos_onmedia.seg_off = pos->seg_off;
	pos_onmedia.header.seq = seq;
	pos_onmedia.header.crc = cache_pos_onmedia_crc(&pos_onmedia);

	*index = (*index + 1) % PCACHE_META_INDEX_MAX;

	memcpy_flushcache(pos_onmedia_addr, &pos_onmedia, sizeof(struct pcache_cache_pos_onmedia));
	pmem_wmb();
}

int cache_pos_decode(struct pcache_cache *cache,
			    struct pcache_cache_pos_onmedia *pos_onmedia,
			    struct pcache_cache_pos *pos, u64 *seq, u32 *index)
{
	struct pcache_cache_pos_onmedia latest, *latest_addr;

	latest_addr = pcache_meta_find_latest(&pos_onmedia->header,
					sizeof(struct pcache_cache_pos_onmedia),
					sizeof(struct pcache_cache_pos_onmedia),
					&latest);
	if (IS_ERR(latest_addr))
		return PTR_ERR(latest_addr);

	if (!latest_addr)
		return -EIO;

	if (!cache_seg_id_valid(cache, latest.cache_seg_id))
		return -EIO;

	pos->cache_seg = &cache->segments[latest.cache_seg_id];

	if (latest.seg_off >= pos->cache_seg->segment.data_size)
		return -EIO;

	pos->seg_off = latest.seg_off;
	*seq = latest.header.seq;
	*index = (latest_addr - pos_onmedia);

	return 0;
}

static inline void cache_info_set_seg_id(struct pcache_cache *cache, u32 seg_id)
{
	cache->cache_info.seg_id = seg_id;
}

static int cache_init(struct dm_pcache *pcache)
{
	struct pcache_cache *cache = &pcache->cache;
	struct pcache_backing_dev *backing_dev = &pcache->backing_dev;
	struct pcache_cache_dev *cache_dev = &pcache->cache_dev;
	int ret;

	cache->segments = kvzalloc_objs(struct pcache_cache_segment,
					cache_dev->seg_num);
	if (!cache->segments) {
		ret = -ENOMEM;
		goto err;
	}

	cache->seg_map = kvcalloc(BITS_TO_LONGS(cache_dev->seg_num), sizeof(unsigned long), GFP_KERNEL);
	if (!cache->seg_map) {
		ret = -ENOMEM;
		goto free_segments;
	}

	cache->backing_dev = backing_dev;
	cache->cache_dev = &pcache->cache_dev;
	cache->n_segs = cache_dev->seg_num;
	atomic_set(&cache->gc_errors, 0);
	atomic_set(&cache->writeback_errors, 0);
	spin_lock_init(&cache->seg_map_lock);
	spin_lock_init(&cache->key_head_lock);

	mutex_init(&cache->cache_info_lock);
	mutex_init(&cache->key_tail_lock);
	mutex_init(&cache->dirty_tail_lock);
	mutex_init(&cache->writeback_lock);

	INIT_DELAYED_WORK(&cache->writeback_work, cache_writeback_fn);
	INIT_DELAYED_WORK(&cache->gc_work, pcache_cache_gc_fn);
	INIT_WORK(&cache->clean_work, clean_fn);

	return 0;

free_segments:
	kvfree(cache->segments);
err:
	return ret;
}

static void cache_exit(struct pcache_cache *cache)
{
	kvfree(cache->seg_map);
	kvfree(cache->segments);
}

static void cache_info_init_default(struct pcache_cache *cache)
{
	struct pcache_cache_info *cache_info = &cache->cache_info;

	memset(cache_info, 0, sizeof(*cache_info));
	cache_info->n_segs = cache->cache_dev->seg_num;
	cache_info_set_gc_percent(cache_info, PCACHE_CACHE_GC_PERCENT_DEFAULT);
}

static int cache_tail_init(struct pcache_cache *cache)
{
	struct dm_pcache *pcache = CACHE_TO_PCACHE(cache);
	bool new_cache = !(cache->cache_info.flags & PCACHE_CACHE_FLAGS_INIT_DONE);
	int ret;

	if (new_cache) {
		__set_bit(0, cache->seg_map);

		cache->key_head.cache_seg = &cache->segments[0];
		cache->key_head.seg_off = 0;
		cache_pos_copy(&cache->key_tail, &cache->key_head);
		cache_pos_copy(&cache->dirty_tail, &cache->key_head);

		cache_encode_dirty_tail(cache);
		cache_encode_key_tail(cache);
	} else {
		if (cache_decode_key_tail(cache) || cache_decode_dirty_tail(cache)) {
			pcache_dev_err(pcache, "Corrupted key tail or dirty tail.\n");
			return -EIO;
		}

		ret = cache_verify_dirty_tail(cache);
		if (ret) {
			pcache_dev_err(pcache, "dirty tail chain does not terminate (crafted cache image?)\n");
			return ret;
		}
	}

	return 0;
}

static int get_seg_id(struct pcache_cache *cache,
		      struct pcache_cache_segment *prev_cache_seg,
		      bool new_cache, u32 *seg_id)
{
	struct dm_pcache *pcache = CACHE_TO_PCACHE(cache);
	struct pcache_cache_dev *cache_dev = cache->cache_dev;
	int ret;

	if (new_cache) {
		ret = cache_dev_get_empty_segment_id(cache_dev, seg_id);
		if (ret) {
			pcache_dev_err(pcache, "no available segment\n");
			goto err;
		}

		if (prev_cache_seg)
			cache_seg_set_next_seg(prev_cache_seg, *seg_id);
		else
			cache_info_set_seg_id(cache, *seg_id);
	} else {
		if (prev_cache_seg) {
			struct pcache_segment_info *prev_seg_info;

			prev_seg_info = &prev_cache_seg->cache_seg_info;
			if (!segment_info_has_next(prev_seg_info)) {
				ret = -EFAULT;
				goto err;
			}
			*seg_id = prev_cache_seg->cache_seg_info.next_seg;
		} else {
			*seg_id = cache->cache_info.seg_id;
		}

		if (*seg_id >= cache_dev->seg_num) {
			pcache_dev_err(pcache, "invalid segment id %u from cache device (seg_num %u)\n",
				       *seg_id, cache_dev->seg_num);
			ret = -EIO;
			goto err;
		}
	}
	return 0;
err:
	return ret;
}

static int cache_segs_init(struct pcache_cache *cache)
{
	struct pcache_cache_segment *prev_cache_seg = NULL;
	struct pcache_cache_info *cache_info = &cache->cache_info;
	bool new_cache = !(cache->cache_info.flags & PCACHE_CACHE_FLAGS_INIT_DONE);
	u32 seg_id;
	int ret;
	u32 i;

	if (cache_info->n_segs > cache->cache_dev->seg_num) {
		pcache_dev_err(CACHE_TO_PCACHE(cache),
			       "cache_info n_segs %u exceeds cache device segments %u\n",
			       cache_info->n_segs, cache->cache_dev->seg_num);
		return -EIO;
	}

	for (i = 0; i < cache_info->n_segs; i++) {
		ret = get_seg_id(cache, prev_cache_seg, new_cache, &seg_id);
		if (ret)
			goto err;

		ret = cache_seg_init(cache, seg_id, i, new_cache);
		if (ret)
			goto err;

		prev_cache_seg = &cache->segments[i];
	}
	return 0;
err:
	return ret;
}

static int cache_init_req_keys(struct pcache_cache *cache, u32 n_paral)
{
	struct dm_pcache *pcache = CACHE_TO_PCACHE(cache);
	u32 n_subtrees;
	int ret;
	u32 i, cpu;

	/* Calculate number of cache trees based on the device size */
	n_subtrees = DIV_ROUND_UP(cache->dev_size << SECTOR_SHIFT, PCACHE_CACHE_SUBTREE_SIZE);
	ret = cache_tree_init(cache, &cache->req_key_tree, n_subtrees);
	if (ret)
		goto err;

	cache->n_ksets = n_paral;
	cache->ksets = kvcalloc(cache->n_ksets, PCACHE_KSET_SIZE, GFP_KERNEL);
	if (!cache->ksets) {
		ret = -ENOMEM;
		goto req_tree_exit;
	}

	/*
	 * Initialize each kset with a spinlock and delayed work for flushing.
	 * Each kset is associated with one queue to ensure independent handling
	 * of cache keys across multiple queues, maximizing multiqueue concurrency.
	 */
	for (i = 0; i < cache->n_ksets; i++) {
		struct pcache_cache_kset *kset = get_kset(cache, i);

		kset->cache = cache;
		spin_lock_init(&kset->kset_lock);
		INIT_DELAYED_WORK(&kset->flush_work, kset_flush_fn);
	}

	cache->data_heads = alloc_percpu(struct pcache_cache_data_head);
	if (!cache->data_heads) {
		ret = -ENOMEM;
		goto free_kset;
	}

	for_each_possible_cpu(cpu) {
		struct pcache_cache_data_head *h =
			per_cpu_ptr(cache->data_heads, cpu);
		h->head_pos.cache_seg = NULL;
	}

	/*
	 * Replay persisted cache keys using cache_replay.
	 * This function loads and replays cache keys from previously stored
	 * ksets, allowing the cache to restore its state after a restart.
	 */
	ret = cache_replay(cache);
	if (ret) {
		pcache_dev_err(pcache, "failed to replay keys\n");
		goto free_heads;
	}

	return 0;

free_heads:
	free_percpu(cache->data_heads);
free_kset:
	kvfree(cache->ksets);
req_tree_exit:
	cache_tree_exit(&cache->req_key_tree);
err:
	return ret;
}

static void cache_destroy_req_keys(struct pcache_cache *cache)
{
	u32 i;

	for (i = 0; i < cache->n_ksets; i++) {
		struct pcache_cache_kset *kset = get_kset(cache, i);

		cancel_delayed_work_sync(&kset->flush_work);
	}

	free_percpu(cache->data_heads);
	kvfree(cache->ksets);
	cache_tree_exit(&cache->req_key_tree);
}

int pcache_cache_start(struct dm_pcache *pcache)
{
	struct pcache_backing_dev *backing_dev = &pcache->backing_dev;
	struct pcache_cache *cache = &pcache->cache;
	struct pcache_cache_options *opts = &pcache->opts;
	int ret;

	ret = cache_init(pcache);
	if (ret)
		return ret;

	cache->cache_info_addr = CACHE_DEV_CACHE_INFO(cache->cache_dev);
	cache->cache_ctrl = CACHE_DEV_CACHE_CTRL(cache->cache_dev);
	backing_dev->cache = cache;
	cache->dev_size = backing_dev->dev_size;

	ret = cache_info_init(cache, opts);
	if (ret)
		goto cache_exit;

	ret = cache_segs_init(cache);
	if (ret)
		goto cache_exit;

	ret = cache_tail_init(cache);
	if (ret)
		goto cache_exit;

	ret = cache_init_req_keys(cache, num_online_cpus());
	if (ret)
		goto cache_exit;

	ret = cache_writeback_init(cache);
	if (ret)
		goto destroy_keys;

	cache->cache_info.flags |= PCACHE_CACHE_FLAGS_INIT_DONE;
	cache_info_write(cache);
	queue_delayed_work(cache_get_wq(cache), &cache->gc_work, 0);

	return 0;

destroy_keys:
	cache_destroy_req_keys(cache);
cache_exit:
	cache_exit(cache);

	return ret;
}

void pcache_cache_stop(struct dm_pcache *pcache)
{
	struct pcache_cache *cache = &pcache->cache;

	pcache_cache_flush(cache);

	cancel_delayed_work_sync(&cache->gc_work);
	flush_work(&cache->clean_work);
	cache_writeback_exit(cache);

	if (cache->req_key_tree.n_subtrees)
		cache_destroy_req_keys(cache);

	cache_exit(cache);
}

struct workqueue_struct *cache_get_wq(struct pcache_cache *cache)
{
	struct dm_pcache *pcache = CACHE_TO_PCACHE(cache);

	return pcache->task_wq;
}

int pcache_cache_init(void)
{
	key_cache = KMEM_CACHE(pcache_cache_key, 0);
	if (!key_cache)
		return -ENOMEM;

	return 0;
}

void pcache_cache_exit(void)
{
	kmem_cache_destroy(key_cache);
}
