// SPDX-License-Identifier: GPL-2.0-or-later
/*
 *  linux/fs/fat/cache.c
 *
 *  Written 1992,1993 by Werner Almesberger
 *
 *  Mar 1999. AV. Changed cache, so that it uses the starting cluster instead
 *	of inode number.
 *  May 1999. AV. Fixed the bogosity with FAT32 (read "FAT28"). Fscking lusers.
 *  Copyright (C) 2012-2013 Samsung Electronics Co., Ltd.
 */

#include <linux/slab.h>
#include <linux/unaligned.h>
#include <linux/buffer_head.h>

#include "exfat_raw.h"
#include "exfat_fs.h"

#define EXFAT_MAX_CACHE		16

struct exfat_cache {
	struct list_head cache_list;
	unsigned int nr_contig;	/* number of contiguous clusters */
	unsigned int fcluster;	/* cluster number in the file. */
	unsigned int dcluster;	/* cluster number on disk. */
};

struct exfat_cache_id {
	unsigned int id;
	unsigned int nr_contig;
	unsigned int fcluster;
	unsigned int dcluster;
};

static struct kmem_cache *exfat_cachep;

static void exfat_cache_init_once(void *c)
{
	struct exfat_cache *cache = (struct exfat_cache *)c;

	INIT_LIST_HEAD(&cache->cache_list);
}

int exfat_cache_init(void)
{
	exfat_cachep = kmem_cache_create("exfat_cache",
				sizeof(struct exfat_cache),
				0, SLAB_RECLAIM_ACCOUNT,
				exfat_cache_init_once);
	if (!exfat_cachep)
		return -ENOMEM;
	return 0;
}

void exfat_cache_shutdown(void)
{
	if (!exfat_cachep)
		return;
	kmem_cache_destroy(exfat_cachep);
}

static inline struct exfat_cache *exfat_cache_alloc(void)
{
	return kmem_cache_alloc(exfat_cachep, GFP_NOFS);
}

static inline void exfat_cache_free(struct exfat_cache *cache)
{
	WARN_ON(!list_empty(&cache->cache_list));
	kmem_cache_free(exfat_cachep, cache);
}

static inline void exfat_cache_update_lru(struct inode *inode,
		struct exfat_cache *cache)
{
	struct exfat_inode_info *ei = EXFAT_I(inode);

	if (ei->cache_lru.next != &cache->cache_list)
		list_move(&cache->cache_list, &ei->cache_lru);
}

static unsigned int exfat_cache_lookup(struct inode *inode,
		unsigned int fclus, struct exfat_cache_id *cid,
		unsigned int *cached_fclus, unsigned int *cached_dclus)
{
	struct exfat_inode_info *ei = EXFAT_I(inode);
	static struct exfat_cache nohit = { .fcluster = 0, };
	struct exfat_cache *hit = &nohit, *p;
	unsigned int offset = EXFAT_EOF_CLUSTER;

	spin_lock(&ei->cache_lru_lock);
	list_for_each_entry(p, &ei->cache_lru, cache_list) {
		/* Find the cache of "fclus" or nearest cache. */
		if (p->fcluster <= fclus && hit->fcluster < p->fcluster) {
			hit = p;
			if (hit->fcluster + hit->nr_contig < fclus) {
				offset = hit->nr_contig;
			} else {
				offset = fclus - hit->fcluster;
				break;
			}
		}
	}
	if (hit != &nohit) {
		exfat_cache_update_lru(inode, hit);

		cid->id = ei->cache_valid_id;
		cid->nr_contig = hit->nr_contig;
		cid->fcluster = hit->fcluster;
		cid->dcluster = hit->dcluster;
		*cached_fclus = cid->fcluster + offset;
		*cached_dclus = cid->dcluster + offset;
	}
	spin_unlock(&ei->cache_lru_lock);

	return offset;
}

static struct exfat_cache *exfat_cache_merge(struct inode *inode,
		struct exfat_cache_id *new)
{
	struct exfat_inode_info *ei = EXFAT_I(inode);
	struct exfat_cache *p;

	list_for_each_entry(p, &ei->cache_lru, cache_list) {
		/* Find the same part as "new" in cluster-chain. */
		if (p->fcluster == new->fcluster) {
			if (new->nr_contig > p->nr_contig)
				p->nr_contig = new->nr_contig;
			return p;
		}
	}
	return NULL;
}

static void exfat_cache_add(struct inode *inode,
		struct exfat_cache_id *new)
{
	struct exfat_inode_info *ei = EXFAT_I(inode);
	struct exfat_cache *cache, *tmp;

	if (new->fcluster == EXFAT_EOF_CLUSTER) /* dummy cache */
		return;

	spin_lock(&ei->cache_lru_lock);
	if (new->id != EXFAT_CACHE_VALID &&
	    new->id != ei->cache_valid_id)
		goto unlock;	/* this cache was invalidated */

	cache = exfat_cache_merge(inode, new);
	if (cache == NULL) {
		if (ei->nr_caches < EXFAT_MAX_CACHE) {
			ei->nr_caches++;
			spin_unlock(&ei->cache_lru_lock);

			tmp = exfat_cache_alloc();
			if (!tmp) {
				spin_lock(&ei->cache_lru_lock);
				ei->nr_caches--;
				spin_unlock(&ei->cache_lru_lock);
				return;
			}

			spin_lock(&ei->cache_lru_lock);
			cache = exfat_cache_merge(inode, new);
			if (cache != NULL) {
				ei->nr_caches--;
				exfat_cache_free(tmp);
				goto out_update_lru;
			}
			cache = tmp;
		} else {
			struct list_head *p = ei->cache_lru.prev;

			cache = list_entry(p,
					struct exfat_cache, cache_list);
		}
		cache->fcluster = new->fcluster;
		cache->dcluster = new->dcluster;
		cache->nr_contig = new->nr_contig;
	}
out_update_lru:
	exfat_cache_update_lru(inode, cache);
unlock:
	spin_unlock(&ei->cache_lru_lock);
}

/*
 * Cache invalidation occurs rarely, thus the LRU chain is not updated. It
 * fixes itself after a while.
 */
static void __exfat_cache_inval_inode(struct inode *inode)
{
	struct exfat_inode_info *ei = EXFAT_I(inode);
	struct exfat_cache *cache;

	while (!list_empty(&ei->cache_lru)) {
		cache = list_entry(ei->cache_lru.next,
				   struct exfat_cache, cache_list);
		list_del_init(&cache->cache_list);
		ei->nr_caches--;
		exfat_cache_free(cache);
	}
	/* Update. The copy of caches before this id is discarded. */
	ei->cache_valid_id++;
	if (ei->cache_valid_id == EXFAT_CACHE_VALID)
		ei->cache_valid_id++;
}

void exfat_cache_inval_inode(struct inode *inode)
{
	struct exfat_inode_info *ei = EXFAT_I(inode);

	spin_lock(&ei->cache_lru_lock);
	__exfat_cache_inval_inode(inode);
	spin_unlock(&ei->cache_lru_lock);
}

static inline int cache_contiguous(struct exfat_cache_id *cid,
		unsigned int dclus)
{
	cid->nr_contig++;
	return cid->dcluster + cid->nr_contig == dclus;
}

static inline void cache_init(struct exfat_cache_id *cid,
		unsigned int fclus, unsigned int dclus)
{
	cid->id = EXFAT_CACHE_VALID;
	cid->fcluster = fclus;
	cid->dcluster = dclus;
	cid->nr_contig = 0;
}

int exfat_get_cluster(struct inode *inode, unsigned int cluster,
		unsigned int *fclus, unsigned int *dclus,
		unsigned int *last_dclus, int allow_eof)
{
	struct super_block *sb = inode->i_sb;
	struct exfat_sb_info *sbi = EXFAT_SB(sb);
	unsigned int limit = sbi->num_clusters;
	struct exfat_inode_info *ei = EXFAT_I(inode);
	struct exfat_cache_id cid;
	unsigned int content;

	if (ei->start_clu == EXFAT_FREE_CLUSTER) {
		exfat_fs_error(sb,
			"invalid access to exfat cache (entry 0x%08x)",
			ei->start_clu);
		return -EIO;
	}

	*fclus = 0;
	*dclus = ei->start_clu;
	*last_dclus = *dclus;

	/*
	 * Don`t use exfat_cache if zero offset or non-cluster allocation
	 */
	if (cluster == 0 || *dclus == EXFAT_EOF_CLUSTER)
		return 0;

	cache_init(&cid, EXFAT_EOF_CLUSTER, EXFAT_EOF_CLUSTER);

	if (exfat_cache_lookup(inode, cluster, &cid, fclus, dclus) ==
			EXFAT_EOF_CLUSTER) {
		/*
		 * dummy, always not contiguous
		 * This is reinitialized by cache_init(), later.
		 */
		WARN_ON(cid.id != EXFAT_CACHE_VALID ||
			cid.fcluster != EXFAT_EOF_CLUSTER ||
			cid.dcluster != EXFAT_EOF_CLUSTER ||
			cid.nr_contig != 0);
	}

	if (*fclus == cluster)
		return 0;

	while (*fclus < cluster) {
		/* prevent the infinite loop of cluster chain */
		if (*fclus > limit) {
			exfat_fs_error(sb,
				"detected the cluster chain loop (i_pos %u)",
				(*fclus));
			return -EIO;
		}

		if (exfat_ent_get(sb, *dclus, &content))
			return -EIO;

		*last_dclus = *dclus;
		*dclus = content;
		(*fclus)++;

		if (content == EXFAT_EOF_CLUSTER) {
			if (!allow_eof) {
				exfat_fs_error(sb,
				       "invalid cluster chain (i_pos %u, last_clus 0x%08x is EOF)",
				       *fclus, (*last_dclus));
				return -EIO;
			}

			break;
		}

		if (!cache_contiguous(&cid, *dclus))
			cache_init(&cid, *fclus, *dclus);
	}

	exfat_cache_add(inode, &cid);
	return 0;
}
