// SPDX-License-Identifier: GPL-2.0-or-later
/* Miscellaneous bits for the netfs support library.
 *
 * Copyright (C) 2022 Red Hat, Inc. All Rights Reserved.
 * Written by David Howells (dhowells@redhat.com)
 */

#include <linux/module.h>
#include <linux/export.h>
#include <linux/mempool.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include "internal.h"
#define CREATE_TRACE_POINTS
#include <trace/events/netfs.h>

MODULE_DESCRIPTION("Network fs support");
MODULE_AUTHOR("Red Hat, Inc.");
MODULE_LICENSE("GPL");

EXPORT_TRACEPOINT_SYMBOL(netfs_sreq);

unsigned netfs_debug;
module_param_named(debug, netfs_debug, uint, S_IWUSR | S_IRUGO);
MODULE_PARM_DESC(netfs_debug, "Netfs support debugging mask");

static struct kmem_cache *netfs_request_slab;
static struct kmem_cache *netfs_subrequest_slab;
mempool_t netfs_request_pool;
mempool_t netfs_subrequest_pool;

#ifdef CONFIG_PROC_FS
LIST_HEAD(netfs_io_requests);
DEFINE_SPINLOCK(netfs_proc_lock);

static const char *netfs_origins[nr__netfs_io_origin] = {
	[NETFS_READAHEAD]		= "RA",
	[NETFS_READPAGE]		= "RP",
	[NETFS_READ_GAPS]		= "RG",
	[NETFS_READ_FOR_WRITE]		= "RW",
	[NETFS_DIO_READ]		= "DR",
	[NETFS_WRITEBACK]		= "WB",
	[NETFS_WRITETHROUGH]		= "WT",
	[NETFS_UNBUFFERED_WRITE]	= "UW",
	[NETFS_DIO_WRITE]		= "DW",
	[NETFS_PGPRIV2_COPY_TO_CACHE]	= "2C",
};

/*
 * Generate a list of I/O requests in /proc/fs/netfs/requests
 */
static int netfs_requests_seq_show(struct seq_file *m, void *v)
{
	struct netfs_io_request *rreq;

	if (v == &netfs_io_requests) {
		seq_puts(m,
			 "REQUEST  OR REF FL ERR  OPS COVERAGE\n"
			 "======== == === == ==== === =========\n"
			 );
		return 0;
	}

	rreq = list_entry(v, struct netfs_io_request, proc_link);
	seq_printf(m,
		   "%08x %s %3d %2lx %4ld %3d @%04llx %llx/%llx",
		   rreq->debug_id,
		   netfs_origins[rreq->origin],
		   refcount_read(&rreq->ref),
		   rreq->flags,
		   rreq->error,
		   atomic_read(&rreq->nr_outstanding),
		   rreq->start, rreq->submitted, rreq->len);
	seq_putc(m, '\n');
	return 0;
}

static void *netfs_requests_seq_start(struct seq_file *m, loff_t *_pos)
	__acquires(rcu)
{
	rcu_read_lock();
	return seq_list_start_head(&netfs_io_requests, *_pos);
}

static void *netfs_requests_seq_next(struct seq_file *m, void *v, loff_t *_pos)
{
	return seq_list_next(v, &netfs_io_requests, _pos);
}

static void netfs_requests_seq_stop(struct seq_file *m, void *v)
	__releases(rcu)
{
	rcu_read_unlock();
}

static const struct seq_operations netfs_requests_seq_ops = {
	.start  = netfs_requests_seq_start,
	.next   = netfs_requests_seq_next,
	.stop   = netfs_requests_seq_stop,
	.show   = netfs_requests_seq_show,
};
#endif /* CONFIG_PROC_FS */

static int __init netfs_init(void)
{
	int ret = -ENOMEM;

	netfs_request_slab = kmem_cache_create("netfs_request",
					       sizeof(struct netfs_io_request), 0,
					       SLAB_HWCACHE_ALIGN | SLAB_ACCOUNT,
					       NULL);
	if (!netfs_request_slab)
		goto error_req;

	if (mempool_init_slab_pool(&netfs_request_pool, 100, netfs_request_slab) < 0)
		goto error_reqpool;

	netfs_subrequest_slab = kmem_cache_create("netfs_subrequest",
						  sizeof(struct netfs_io_subrequest), 0,
						  SLAB_HWCACHE_ALIGN | SLAB_ACCOUNT,
						  NULL);
	if (!netfs_subrequest_slab)
		goto error_subreq;

	if (mempool_init_slab_pool(&netfs_subrequest_pool, 100, netfs_subrequest_slab) < 0)
		goto error_subreqpool;

	if (!proc_mkdir("fs/netfs", NULL))
		goto error_proc;
	if (!proc_create_seq("fs/netfs/requests", S_IFREG | 0444, NULL,
			     &netfs_requests_seq_ops))
		goto error_procfile;
#ifdef CONFIG_FSCACHE_STATS
	if (!proc_create_single("fs/netfs/stats", S_IFREG | 0444, NULL,
				netfs_stats_show))
		goto error_procfile;
#endif

	ret = fscache_init();
	if (ret < 0)
		goto error_fscache;
	return 0;

error_fscache:
error_procfile:
	remove_proc_subtree("fs/netfs", NULL);
error_proc:
	mempool_exit(&netfs_subrequest_pool);
error_subreqpool:
	kmem_cache_destroy(netfs_subrequest_slab);
error_subreq:
	mempool_exit(&netfs_request_pool);
error_reqpool:
	kmem_cache_destroy(netfs_request_slab);
error_req:
	return ret;
}
fs_initcall(netfs_init);

static void __exit netfs_exit(void)
{
	fscache_exit();
	remove_proc_subtree("fs/netfs", NULL);
	mempool_exit(&netfs_subrequest_pool);
	kmem_cache_destroy(netfs_subrequest_slab);
	mempool_exit(&netfs_request_pool);
	kmem_cache_destroy(netfs_request_slab);
}
module_exit(netfs_exit);
