// SPDX-License-Identifier: LGPL-2.1
/*
 *   CIFS filesystem cache interface
 *
 *   Copyright (c) 2010 Novell, Inc.
 *   Author(s): Suresh Jayaraman <sjayaraman@suse.de>
 *
 */
#include "fscache.h"
#include "cifsglob.h"
#include "cifs_debug.h"
#include "cifs_fs_sb.h"
#include "cifsproto.h"

static void cifs_fscache_fill_volume_coherency(
	struct cifs_tcon *tcon,
	struct cifs_fscache_volume_coherency_data *cd)
{
	memset(cd, 0, sizeof(*cd));
	cd->resource_id		= cpu_to_le64(tcon->resource_id);
	cd->vol_create_time	= tcon->vol_create_time;
	cd->vol_serial_number	= cpu_to_le32(tcon->vol_serial_number);
}

int cifs_fscache_get_super_cookie(struct cifs_tcon *tcon)
{
	struct cifs_fscache_volume_coherency_data cd;
	struct TCP_Server_Info *server = tcon->ses->server;
	struct fscache_volume *vcookie;
	const struct sockaddr *sa = (struct sockaddr *)&server->dstaddr;
	size_t slen, i;
	char *sharename;
	char *key;
	int ret = -ENOMEM;

	tcon->fscache = NULL;
	switch (sa->sa_family) {
	case AF_INET:
	case AF_INET6:
		break;
	default:
		cifs_dbg(VFS, "Unknown network family '%d'\n", sa->sa_family);
		return -EINVAL;
	}

	memset(&key, 0, sizeof(key));

	sharename = extract_sharename(tcon->tree_name);
	if (IS_ERR(sharename)) {
		cifs_dbg(FYI, "%s: couldn't extract sharename\n", __func__);
		return PTR_ERR(sharename);
	}

	slen = strlen(sharename);
	for (i = 0; i < slen; i++)
		if (sharename[i] == '/')
			sharename[i] = ';';

	key = kasprintf(GFP_KERNEL, "cifs,%pISpc,%s", sa, sharename);
	if (!key)
		goto out;

	cifs_fscache_fill_volume_coherency(tcon, &cd);
	vcookie = fscache_acquire_volume(key,
					 NULL, /* preferred_cache */
					 &cd, sizeof(cd));
	cifs_dbg(FYI, "%s: (%s/0x%p)\n", __func__, key, vcookie);
	if (IS_ERR(vcookie)) {
		if (vcookie != ERR_PTR(-EBUSY)) {
			ret = PTR_ERR(vcookie);
			goto out_2;
		}
		pr_err("Cache volume key already in use (%s)\n", key);
		vcookie = NULL;
	}

	tcon->fscache = vcookie;
	ret = 0;
out_2:
	kfree(key);
out:
	kfree(sharename);
	return ret;
}

void cifs_fscache_release_super_cookie(struct cifs_tcon *tcon)
{
	struct cifs_fscache_volume_coherency_data cd;

	cifs_dbg(FYI, "%s: (0x%p)\n", __func__, tcon->fscache);

	cifs_fscache_fill_volume_coherency(tcon, &cd);
	fscache_relinquish_volume(tcon->fscache, &cd, false);
	tcon->fscache = NULL;
}

void cifs_fscache_get_inode_cookie(struct inode *inode)
{
	struct cifs_fscache_inode_coherency_data cd;
	struct cifsInodeInfo *cifsi = CIFS_I(inode);
	struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
	struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);

	cifs_fscache_fill_coherency(&cifsi->netfs.inode, &cd);

	cifsi->netfs.cache =
		fscache_acquire_cookie(tcon->fscache, 0,
				       &cifsi->uniqueid, sizeof(cifsi->uniqueid),
				       &cd, sizeof(cd),
				       i_size_read(&cifsi->netfs.inode));
	if (cifsi->netfs.cache)
		mapping_set_release_always(inode->i_mapping);
}

void cifs_fscache_unuse_inode_cookie(struct inode *inode, bool update)
{
	if (update) {
		struct cifs_fscache_inode_coherency_data cd;
		loff_t i_size = i_size_read(inode);

		cifs_fscache_fill_coherency(inode, &cd);
		fscache_unuse_cookie(cifs_inode_cookie(inode), &cd, &i_size);
	} else {
		fscache_unuse_cookie(cifs_inode_cookie(inode), NULL, NULL);
	}
}

void cifs_fscache_release_inode_cookie(struct inode *inode)
{
	struct cifsInodeInfo *cifsi = CIFS_I(inode);
	struct fscache_cookie *cookie = cifs_inode_cookie(inode);

	if (cookie) {
		cifs_dbg(FYI, "%s: (0x%p)\n", __func__, cookie);
		fscache_relinquish_cookie(cookie, false);
		cifsi->netfs.cache = NULL;
	}
}

/*
 * Fallback page reading interface.
 */
static int fscache_fallback_read_page(struct inode *inode, struct page *page)
{
	struct netfs_cache_resources cres;
	struct fscache_cookie *cookie = cifs_inode_cookie(inode);
	struct iov_iter iter;
	struct bio_vec bvec;
	int ret;

	memset(&cres, 0, sizeof(cres));
	bvec_set_page(&bvec, page, PAGE_SIZE, 0);
	iov_iter_bvec(&iter, ITER_DEST, &bvec, 1, PAGE_SIZE);

	ret = fscache_begin_read_operation(&cres, cookie);
	if (ret < 0)
		return ret;

	ret = fscache_read(&cres, page_offset(page), &iter, NETFS_READ_HOLE_FAIL,
			   NULL, NULL);
	fscache_end_operation(&cres);
	return ret;
}

/*
 * Fallback page writing interface.
 */
static int fscache_fallback_write_pages(struct inode *inode, loff_t start, size_t len,
					bool no_space_allocated_yet)
{
	struct netfs_cache_resources cres;
	struct fscache_cookie *cookie = cifs_inode_cookie(inode);
	struct iov_iter iter;
	int ret;

	memset(&cres, 0, sizeof(cres));
	iov_iter_xarray(&iter, ITER_SOURCE, &inode->i_mapping->i_pages, start, len);

	ret = fscache_begin_write_operation(&cres, cookie);
	if (ret < 0)
		return ret;

	ret = cres.ops->prepare_write(&cres, &start, &len, len, i_size_read(inode),
				      no_space_allocated_yet);
	if (ret == 0)
		ret = fscache_write(&cres, start, &iter, NULL, NULL);
	fscache_end_operation(&cres);
	return ret;
}

/*
 * Retrieve a page from FS-Cache
 */
int __cifs_readpage_from_fscache(struct inode *inode, struct page *page)
{
	int ret;

	cifs_dbg(FYI, "%s: (fsc:%p, p:%p, i:0x%p\n",
		 __func__, cifs_inode_cookie(inode), page, inode);

	ret = fscache_fallback_read_page(inode, page);
	if (ret < 0)
		return ret;

	/* Read completed synchronously */
	SetPageUptodate(page);
	return 0;
}

void __cifs_readahead_to_fscache(struct inode *inode, loff_t pos, size_t len)
{
	cifs_dbg(FYI, "%s: (fsc: %p, p: %llx, l: %zx, i: %p)\n",
		 __func__, cifs_inode_cookie(inode), pos, len, inode);

	fscache_fallback_write_pages(inode, pos, len, true);
}

/*
 * Query the cache occupancy.
 */
int __cifs_fscache_query_occupancy(struct inode *inode,
				   pgoff_t first, unsigned int nr_pages,
				   pgoff_t *_data_first,
				   unsigned int *_data_nr_pages)
{
	struct netfs_cache_resources cres;
	struct fscache_cookie *cookie = cifs_inode_cookie(inode);
	loff_t start, data_start;
	size_t len, data_len;
	int ret;

	ret = fscache_begin_read_operation(&cres, cookie);
	if (ret < 0)
		return ret;

	start = first * PAGE_SIZE;
	len = nr_pages * PAGE_SIZE;
	ret = cres.ops->query_occupancy(&cres, start, len, PAGE_SIZE,
					&data_start, &data_len);
	if (ret == 0) {
		*_data_first = data_start / PAGE_SIZE;
		*_data_nr_pages = len / PAGE_SIZE;
	}

	fscache_end_operation(&cres);
	return ret;
}
