// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Copyright (C) 2022, Alibaba Cloud
 * Copyright (C) 2022, Bytedance Inc. All rights reserved.
 */
#include <linux/fscache.h>
#include "internal.h"

static DEFINE_MUTEX(erofs_domain_list_lock);
static DEFINE_MUTEX(erofs_domain_cookies_lock);
static LIST_HEAD(erofs_domain_list);
static LIST_HEAD(erofs_domain_cookies_list);
static struct vfsmount *erofs_pseudo_mnt;

struct erofs_fscache_request {
	struct erofs_fscache_request *primary;
	struct netfs_cache_resources cache_resources;
	struct address_space	*mapping;	/* The mapping being accessed */
	loff_t			start;		/* Start position */
	size_t			len;		/* Length of the request */
	size_t			submitted;	/* Length of submitted */
	short			error;		/* 0 or error that occurred */
	refcount_t		ref;
};

static struct erofs_fscache_request *erofs_fscache_req_alloc(struct address_space *mapping,
					     loff_t start, size_t len)
{
	struct erofs_fscache_request *req;

	req = kzalloc(sizeof(struct erofs_fscache_request), GFP_KERNEL);
	if (!req)
		return ERR_PTR(-ENOMEM);

	req->mapping = mapping;
	req->start   = start;
	req->len     = len;
	refcount_set(&req->ref, 1);

	return req;
}

static struct erofs_fscache_request *erofs_fscache_req_chain(struct erofs_fscache_request *primary,
					     size_t len)
{
	struct erofs_fscache_request *req;

	/* use primary request for the first submission */
	if (!primary->submitted) {
		refcount_inc(&primary->ref);
		return primary;
	}

	req = erofs_fscache_req_alloc(primary->mapping,
			primary->start + primary->submitted, len);
	if (!IS_ERR(req)) {
		req->primary = primary;
		refcount_inc(&primary->ref);
	}
	return req;
}

static void erofs_fscache_req_complete(struct erofs_fscache_request *req)
{
	struct folio *folio;
	bool failed = req->error;
	pgoff_t start_page = req->start / PAGE_SIZE;
	pgoff_t last_page = ((req->start + req->len) / PAGE_SIZE) - 1;

	XA_STATE(xas, &req->mapping->i_pages, start_page);

	rcu_read_lock();
	xas_for_each(&xas, folio, last_page) {
		if (xas_retry(&xas, folio))
			continue;
		if (!failed)
			folio_mark_uptodate(folio);
		folio_unlock(folio);
	}
	rcu_read_unlock();
}

static void erofs_fscache_req_put(struct erofs_fscache_request *req)
{
	if (refcount_dec_and_test(&req->ref)) {
		if (req->cache_resources.ops)
			req->cache_resources.ops->end_operation(&req->cache_resources);
		if (!req->primary)
			erofs_fscache_req_complete(req);
		else
			erofs_fscache_req_put(req->primary);
		kfree(req);
	}
}

static void erofs_fscache_subreq_complete(void *priv,
		ssize_t transferred_or_error, bool was_async)
{
	struct erofs_fscache_request *req = priv;

	if (IS_ERR_VALUE(transferred_or_error)) {
		if (req->primary)
			req->primary->error = transferred_or_error;
		else
			req->error = transferred_or_error;
	}
	erofs_fscache_req_put(req);
}

/*
 * Read data from fscache (cookie, pstart, len), and fill the read data into
 * page cache described by (req->mapping, lstart, len). @pstart describeis the
 * start physical address in the cache file.
 */
static int erofs_fscache_read_folios_async(struct fscache_cookie *cookie,
		struct erofs_fscache_request *req, loff_t pstart, size_t len)
{
	enum netfs_io_source source;
	struct super_block *sb = req->mapping->host->i_sb;
	struct netfs_cache_resources *cres = &req->cache_resources;
	struct iov_iter iter;
	loff_t lstart = req->start + req->submitted;
	size_t done = 0;
	int ret;

	DBG_BUGON(len > req->len - req->submitted);

	ret = fscache_begin_read_operation(cres, cookie);
	if (ret)
		return ret;

	while (done < len) {
		loff_t sstart = pstart + done;
		size_t slen = len - done;
		unsigned long flags = 1 << NETFS_SREQ_ONDEMAND;

		source = cres->ops->prepare_ondemand_read(cres,
				sstart, &slen, LLONG_MAX, &flags, 0);
		if (WARN_ON(slen == 0))
			source = NETFS_INVALID_READ;
		if (source != NETFS_READ_FROM_CACHE) {
			erofs_err(sb, "failed to fscache prepare_read (source %d)", source);
			return -EIO;
		}

		refcount_inc(&req->ref);
		iov_iter_xarray(&iter, ITER_DEST, &req->mapping->i_pages,
				lstart + done, slen);

		ret = fscache_read(cres, sstart, &iter, NETFS_READ_HOLE_FAIL,
				   erofs_fscache_subreq_complete, req);
		if (ret == -EIOCBQUEUED)
			ret = 0;
		if (ret) {
			erofs_err(sb, "failed to fscache_read (ret %d)", ret);
			return ret;
		}

		done += slen;
	}
	DBG_BUGON(done != len);
	return 0;
}

static int erofs_fscache_meta_read_folio(struct file *data, struct folio *folio)
{
	int ret;
	struct erofs_fscache *ctx = folio_mapping(folio)->host->i_private;
	struct erofs_fscache_request *req;

	req = erofs_fscache_req_alloc(folio_mapping(folio),
				folio_pos(folio), folio_size(folio));
	if (IS_ERR(req)) {
		folio_unlock(folio);
		return PTR_ERR(req);
	}

	ret = erofs_fscache_read_folios_async(ctx->cookie, req,
				folio_pos(folio), folio_size(folio));
	if (ret)
		req->error = ret;

	erofs_fscache_req_put(req);
	return ret;
}

static int erofs_fscache_data_read_slice(struct erofs_fscache_request *primary)
{
	struct address_space *mapping = primary->mapping;
	struct inode *inode = mapping->host;
	struct super_block *sb = inode->i_sb;
	struct erofs_fscache_request *req;
	struct erofs_map_blocks map;
	struct erofs_map_dev mdev;
	struct iov_iter iter;
	loff_t pos = primary->start + primary->submitted;
	size_t count;
	int ret;

	map.m_la = pos;
	ret = erofs_map_blocks(inode, &map);
	if (ret)
		return ret;

	if (map.m_flags & EROFS_MAP_META) {
		struct erofs_buf buf = __EROFS_BUF_INITIALIZER;
		erofs_blk_t blknr;
		size_t offset, size;
		void *src;

		/* For tail packing layout, the offset may be non-zero. */
		offset = erofs_blkoff(sb, map.m_pa);
		blknr = erofs_blknr(sb, map.m_pa);
		size = map.m_llen;

		src = erofs_read_metabuf(&buf, sb, blknr, EROFS_KMAP);
		if (IS_ERR(src))
			return PTR_ERR(src);

		iov_iter_xarray(&iter, ITER_DEST, &mapping->i_pages, pos, PAGE_SIZE);
		if (copy_to_iter(src + offset, size, &iter) != size) {
			erofs_put_metabuf(&buf);
			return -EFAULT;
		}
		iov_iter_zero(PAGE_SIZE - size, &iter);
		erofs_put_metabuf(&buf);
		primary->submitted += PAGE_SIZE;
		return 0;
	}

	count = primary->len - primary->submitted;
	if (!(map.m_flags & EROFS_MAP_MAPPED)) {
		iov_iter_xarray(&iter, ITER_DEST, &mapping->i_pages, pos, count);
		iov_iter_zero(count, &iter);
		primary->submitted += count;
		return 0;
	}

	count = min_t(size_t, map.m_llen - (pos - map.m_la), count);
	DBG_BUGON(!count || count % PAGE_SIZE);

	mdev = (struct erofs_map_dev) {
		.m_deviceid = map.m_deviceid,
		.m_pa = map.m_pa,
	};
	ret = erofs_map_dev(sb, &mdev);
	if (ret)
		return ret;

	req = erofs_fscache_req_chain(primary, count);
	if (IS_ERR(req))
		return PTR_ERR(req);

	ret = erofs_fscache_read_folios_async(mdev.m_fscache->cookie,
			req, mdev.m_pa + (pos - map.m_la), count);
	erofs_fscache_req_put(req);
	primary->submitted += count;
	return ret;
}

static int erofs_fscache_data_read(struct erofs_fscache_request *req)
{
	int ret;

	do {
		ret = erofs_fscache_data_read_slice(req);
		if (ret)
			req->error = ret;
	} while (!ret && req->submitted < req->len);

	return ret;
}

static int erofs_fscache_read_folio(struct file *file, struct folio *folio)
{
	struct erofs_fscache_request *req;
	int ret;

	req = erofs_fscache_req_alloc(folio_mapping(folio),
			folio_pos(folio), folio_size(folio));
	if (IS_ERR(req)) {
		folio_unlock(folio);
		return PTR_ERR(req);
	}

	ret = erofs_fscache_data_read(req);
	erofs_fscache_req_put(req);
	return ret;
}

static void erofs_fscache_readahead(struct readahead_control *rac)
{
	struct erofs_fscache_request *req;

	if (!readahead_count(rac))
		return;

	req = erofs_fscache_req_alloc(rac->mapping,
			readahead_pos(rac), readahead_length(rac));
	if (IS_ERR(req))
		return;

	/* The request completion will drop refs on the folios. */
	while (readahead_folio(rac))
		;

	erofs_fscache_data_read(req);
	erofs_fscache_req_put(req);
}

static const struct address_space_operations erofs_fscache_meta_aops = {
	.read_folio = erofs_fscache_meta_read_folio,
};

const struct address_space_operations erofs_fscache_access_aops = {
	.read_folio = erofs_fscache_read_folio,
	.readahead = erofs_fscache_readahead,
};

static void erofs_fscache_domain_put(struct erofs_domain *domain)
{
	mutex_lock(&erofs_domain_list_lock);
	if (refcount_dec_and_test(&domain->ref)) {
		list_del(&domain->list);
		if (list_empty(&erofs_domain_list)) {
			kern_unmount(erofs_pseudo_mnt);
			erofs_pseudo_mnt = NULL;
		}
		fscache_relinquish_volume(domain->volume, NULL, false);
		mutex_unlock(&erofs_domain_list_lock);
		kfree(domain->domain_id);
		kfree(domain);
		return;
	}
	mutex_unlock(&erofs_domain_list_lock);
}

static int erofs_fscache_register_volume(struct super_block *sb)
{
	struct erofs_sb_info *sbi = EROFS_SB(sb);
	char *domain_id = sbi->domain_id;
	struct fscache_volume *volume;
	char *name;
	int ret = 0;

	name = kasprintf(GFP_KERNEL, "erofs,%s",
			 domain_id ? domain_id : sbi->fsid);
	if (!name)
		return -ENOMEM;

	volume = fscache_acquire_volume(name, NULL, NULL, 0);
	if (IS_ERR_OR_NULL(volume)) {
		erofs_err(sb, "failed to register volume for %s", name);
		ret = volume ? PTR_ERR(volume) : -EOPNOTSUPP;
		volume = NULL;
	}

	sbi->volume = volume;
	kfree(name);
	return ret;
}

static int erofs_fscache_init_domain(struct super_block *sb)
{
	int err;
	struct erofs_domain *domain;
	struct erofs_sb_info *sbi = EROFS_SB(sb);

	domain = kzalloc(sizeof(struct erofs_domain), GFP_KERNEL);
	if (!domain)
		return -ENOMEM;

	domain->domain_id = kstrdup(sbi->domain_id, GFP_KERNEL);
	if (!domain->domain_id) {
		kfree(domain);
		return -ENOMEM;
	}

	err = erofs_fscache_register_volume(sb);
	if (err)
		goto out;

	if (!erofs_pseudo_mnt) {
		erofs_pseudo_mnt = kern_mount(&erofs_fs_type);
		if (IS_ERR(erofs_pseudo_mnt)) {
			err = PTR_ERR(erofs_pseudo_mnt);
			goto out;
		}
	}

	domain->volume = sbi->volume;
	refcount_set(&domain->ref, 1);
	list_add(&domain->list, &erofs_domain_list);
	sbi->domain = domain;
	return 0;
out:
	kfree(domain->domain_id);
	kfree(domain);
	return err;
}

static int erofs_fscache_register_domain(struct super_block *sb)
{
	int err;
	struct erofs_domain *domain;
	struct erofs_sb_info *sbi = EROFS_SB(sb);

	mutex_lock(&erofs_domain_list_lock);
	list_for_each_entry(domain, &erofs_domain_list, list) {
		if (!strcmp(domain->domain_id, sbi->domain_id)) {
			sbi->domain = domain;
			sbi->volume = domain->volume;
			refcount_inc(&domain->ref);
			mutex_unlock(&erofs_domain_list_lock);
			return 0;
		}
	}
	err = erofs_fscache_init_domain(sb);
	mutex_unlock(&erofs_domain_list_lock);
	return err;
}

static struct erofs_fscache *erofs_fscache_acquire_cookie(struct super_block *sb,
						char *name, unsigned int flags)
{
	struct fscache_volume *volume = EROFS_SB(sb)->volume;
	struct erofs_fscache *ctx;
	struct fscache_cookie *cookie;
	struct super_block *isb;
	struct inode *inode;
	int ret;

	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
	if (!ctx)
		return ERR_PTR(-ENOMEM);
	INIT_LIST_HEAD(&ctx->node);
	refcount_set(&ctx->ref, 1);

	cookie = fscache_acquire_cookie(volume, FSCACHE_ADV_WANT_CACHE_SIZE,
					name, strlen(name), NULL, 0, 0);
	if (!cookie) {
		erofs_err(sb, "failed to get cookie for %s", name);
		ret = -EINVAL;
		goto err;
	}
	fscache_use_cookie(cookie, false);

	/*
	 * Allocate anonymous inode in global pseudo mount for shareable blobs,
	 * so that they are accessible among erofs fs instances.
	 */
	isb = flags & EROFS_REG_COOKIE_SHARE ? erofs_pseudo_mnt->mnt_sb : sb;
	inode = new_inode(isb);
	if (!inode) {
		erofs_err(sb, "failed to get anon inode for %s", name);
		ret = -ENOMEM;
		goto err_cookie;
	}

	inode->i_size = OFFSET_MAX;
	inode->i_mapping->a_ops = &erofs_fscache_meta_aops;
	mapping_set_gfp_mask(inode->i_mapping, GFP_NOFS);
	inode->i_blkbits = EROFS_SB(sb)->blkszbits;
	inode->i_private = ctx;

	ctx->cookie = cookie;
	ctx->inode = inode;
	return ctx;

err_cookie:
	fscache_unuse_cookie(cookie, NULL, NULL);
	fscache_relinquish_cookie(cookie, false);
err:
	kfree(ctx);
	return ERR_PTR(ret);
}

static void erofs_fscache_relinquish_cookie(struct erofs_fscache *ctx)
{
	fscache_unuse_cookie(ctx->cookie, NULL, NULL);
	fscache_relinquish_cookie(ctx->cookie, false);
	iput(ctx->inode);
	kfree(ctx->name);
	kfree(ctx);
}

static struct erofs_fscache *erofs_domain_init_cookie(struct super_block *sb,
						char *name, unsigned int flags)
{
	struct erofs_fscache *ctx;
	struct erofs_domain *domain = EROFS_SB(sb)->domain;

	ctx = erofs_fscache_acquire_cookie(sb, name, flags);
	if (IS_ERR(ctx))
		return ctx;

	ctx->name = kstrdup(name, GFP_KERNEL);
	if (!ctx->name) {
		erofs_fscache_relinquish_cookie(ctx);
		return ERR_PTR(-ENOMEM);
	}

	refcount_inc(&domain->ref);
	ctx->domain = domain;
	list_add(&ctx->node, &erofs_domain_cookies_list);
	return ctx;
}

static struct erofs_fscache *erofs_domain_register_cookie(struct super_block *sb,
						char *name, unsigned int flags)
{
	struct erofs_fscache *ctx;
	struct erofs_domain *domain = EROFS_SB(sb)->domain;

	flags |= EROFS_REG_COOKIE_SHARE;
	mutex_lock(&erofs_domain_cookies_lock);
	list_for_each_entry(ctx, &erofs_domain_cookies_list, node) {
		if (ctx->domain != domain || strcmp(ctx->name, name))
			continue;
		if (!(flags & EROFS_REG_COOKIE_NEED_NOEXIST)) {
			refcount_inc(&ctx->ref);
		} else {
			erofs_err(sb, "%s already exists in domain %s", name,
				  domain->domain_id);
			ctx = ERR_PTR(-EEXIST);
		}
		mutex_unlock(&erofs_domain_cookies_lock);
		return ctx;
	}
	ctx = erofs_domain_init_cookie(sb, name, flags);
	mutex_unlock(&erofs_domain_cookies_lock);
	return ctx;
}

struct erofs_fscache *erofs_fscache_register_cookie(struct super_block *sb,
						    char *name,
						    unsigned int flags)
{
	if (EROFS_SB(sb)->domain_id)
		return erofs_domain_register_cookie(sb, name, flags);
	return erofs_fscache_acquire_cookie(sb, name, flags);
}

void erofs_fscache_unregister_cookie(struct erofs_fscache *ctx)
{
	struct erofs_domain *domain = NULL;

	if (!ctx)
		return;
	if (!ctx->domain)
		return erofs_fscache_relinquish_cookie(ctx);

	mutex_lock(&erofs_domain_cookies_lock);
	if (refcount_dec_and_test(&ctx->ref)) {
		domain = ctx->domain;
		list_del(&ctx->node);
		erofs_fscache_relinquish_cookie(ctx);
	}
	mutex_unlock(&erofs_domain_cookies_lock);
	if (domain)
		erofs_fscache_domain_put(domain);
}

int erofs_fscache_register_fs(struct super_block *sb)
{
	int ret;
	struct erofs_sb_info *sbi = EROFS_SB(sb);
	struct erofs_fscache *fscache;
	unsigned int flags = 0;

	if (sbi->domain_id)
		ret = erofs_fscache_register_domain(sb);
	else
		ret = erofs_fscache_register_volume(sb);
	if (ret)
		return ret;

	/*
	 * When shared domain is enabled, using NEED_NOEXIST to guarantee
	 * the primary data blob (aka fsid) is unique in the shared domain.
	 *
	 * For non-shared-domain case, fscache_acquire_volume() invoked by
	 * erofs_fscache_register_volume() has already guaranteed
	 * the uniqueness of primary data blob.
	 *
	 * Acquired domain/volume will be relinquished in kill_sb() on error.
	 */
	if (sbi->domain_id)
		flags |= EROFS_REG_COOKIE_NEED_NOEXIST;
	fscache = erofs_fscache_register_cookie(sb, sbi->fsid, flags);
	if (IS_ERR(fscache))
		return PTR_ERR(fscache);

	sbi->s_fscache = fscache;
	return 0;
}

void erofs_fscache_unregister_fs(struct super_block *sb)
{
	struct erofs_sb_info *sbi = EROFS_SB(sb);

	erofs_fscache_unregister_cookie(sbi->s_fscache);

	if (sbi->domain)
		erofs_fscache_domain_put(sbi->domain);
	else
		fscache_relinquish_volume(sbi->volume, NULL, false);

	sbi->s_fscache = NULL;
	sbi->volume = NULL;
	sbi->domain = NULL;
}
