// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2012 Bryan Schumaker <bjschuma@netapp.com>
 */
#include <linux/init.h>
#include <linux/module.h>
#include <linux/mount.h>
#include <linux/nfs4_mount.h>
#include <linux/nfs_fs.h>
#include <linux/nfs_ssc.h>
#include "delegation.h"
#include "internal.h"
#include "nfs4_fs.h"
#include "nfs4idmap.h"
#include "dns_resolve.h"
#include "pnfs.h"
#include "nfs.h"

#define NFSDBG_FACILITY		NFSDBG_VFS

static int nfs4_write_inode(struct inode *inode, struct writeback_control *wbc);
static void nfs4_evict_inode(struct inode *inode);

static const struct super_operations nfs4_sops = {
	.alloc_inode	= nfs_alloc_inode,
	.free_inode	= nfs_free_inode,
	.write_inode	= nfs4_write_inode,
	.drop_inode	= nfs_drop_inode,
	.statfs		= nfs_statfs,
	.evict_inode	= nfs4_evict_inode,
	.umount_begin	= nfs_umount_begin,
	.show_options	= nfs_show_options,
	.show_devname	= nfs_show_devname,
	.show_path	= nfs_show_path,
	.show_stats	= nfs_show_stats,
};

struct nfs_subversion nfs_v4 = {
	.owner		= THIS_MODULE,
	.nfs_fs		= &nfs4_fs_type,
	.rpc_vers	= &nfs_version4,
	.rpc_ops	= &nfs_v4_clientops,
	.sops		= &nfs4_sops,
	.xattr		= nfs4_xattr_handlers,
};

static int nfs4_write_inode(struct inode *inode, struct writeback_control *wbc)
{
	int ret = nfs_write_inode(inode, wbc);

	if (ret == 0)
		ret = pnfs_layoutcommit_inode(inode,
				wbc->sync_mode == WB_SYNC_ALL);
	return ret;
}

/*
 * Clean out any remaining NFSv4 state that might be left over due
 * to open() calls that passed nfs_atomic_lookup, but failed to call
 * nfs_open().
 */
static void nfs4_evict_inode(struct inode *inode)
{
	truncate_inode_pages_final(&inode->i_data);
	clear_inode(inode);
	/* If we are holding a delegation, return and free it */
	nfs_inode_evict_delegation(inode);
	/* Note that above delegreturn would trigger pnfs return-on-close */
	pnfs_return_layout(inode);
	pnfs_destroy_layout_final(NFS_I(inode));
	/* First call standard NFS clear_inode() code */
	nfs_clear_inode(inode);
	nfs4_xattr_cache_zap(inode);
}

struct nfs_referral_count {
	struct list_head list;
	const struct task_struct *task;
	unsigned int referral_count;
};

static LIST_HEAD(nfs_referral_count_list);
static DEFINE_SPINLOCK(nfs_referral_count_list_lock);

static struct nfs_referral_count *nfs_find_referral_count(void)
{
	struct nfs_referral_count *p;

	list_for_each_entry(p, &nfs_referral_count_list, list) {
		if (p->task == current)
			return p;
	}
	return NULL;
}

#define NFS_MAX_NESTED_REFERRALS 2

static int nfs_referral_loop_protect(void)
{
	struct nfs_referral_count *p, *new;
	int ret = -ENOMEM;

	new = kmalloc_obj(*new);
	if (!new)
		goto out;
	new->task = current;
	new->referral_count = 1;

	ret = 0;
	spin_lock(&nfs_referral_count_list_lock);
	p = nfs_find_referral_count();
	if (p != NULL) {
		if (p->referral_count >= NFS_MAX_NESTED_REFERRALS)
			ret = -ELOOP;
		else
			p->referral_count++;
	} else {
		list_add(&new->list, &nfs_referral_count_list);
		new = NULL;
	}
	spin_unlock(&nfs_referral_count_list_lock);
	kfree(new);
out:
	return ret;
}

static void nfs_referral_loop_unprotect(void)
{
	struct nfs_referral_count *p;

	spin_lock(&nfs_referral_count_list_lock);
	p = nfs_find_referral_count();
	p->referral_count--;
	if (p->referral_count == 0)
		list_del(&p->list);
	else
		p = NULL;
	spin_unlock(&nfs_referral_count_list_lock);
	kfree(p);
}

static int do_nfs4_mount(struct nfs_server *server,
			 struct fs_context *fc,
			 const char *hostname,
			 const char *export_path)
{
	struct nfs_fs_context *root_ctx;
	struct nfs_fs_context *ctx;
	struct fs_context *root_fc;
	struct vfsmount *root_mnt;
	struct dentry *dentry;
	char *source;
	int ret;

	if (IS_ERR(server))
		return PTR_ERR(server);

	root_fc = vfs_dup_fs_context(fc);
	if (IS_ERR(root_fc)) {
		nfs_free_server(server);
		return PTR_ERR(root_fc);
	}
	kfree(root_fc->source);
	root_fc->source = NULL;

	ctx = nfs_fc2context(fc);
	root_ctx = nfs_fc2context(root_fc);
	root_ctx->internal = true;
	root_ctx->server = server;

	if (ctx->fscache_uniq) {
		ret = vfs_parse_fs_string(root_fc, "fsc", ctx->fscache_uniq);
		if (ret < 0) {
			put_fs_context(root_fc);
			return ret;
		}
	}
	/* We leave export_path unset as it's not used to find the root. */

	/* Does hostname needs to be enclosed in brackets? */
	if (strchr(hostname, ':'))
		source = kasprintf(GFP_KERNEL, "[%s]:/", hostname);
	else
		source = kasprintf(GFP_KERNEL, "%s:/", hostname);

	if (!source) {
		put_fs_context(root_fc);
		return -ENOMEM;
	}
	ret = vfs_parse_fs_string(root_fc, "source", source);
	kfree(source);
	if (ret < 0) {
		put_fs_context(root_fc);
		return ret;
	}
	root_mnt = fc_mount(root_fc);
	put_fs_context(root_fc);

	if (IS_ERR(root_mnt))
		return PTR_ERR(root_mnt);

	ret = nfs_referral_loop_protect();
	if (ret) {
		mntput(root_mnt);
		return ret;
	}

	dentry = mount_subtree(root_mnt, export_path);
	nfs_referral_loop_unprotect();

	if (IS_ERR(dentry))
		return PTR_ERR(dentry);

	fc->root = dentry;
	return 0;
}

int nfs4_try_get_tree(struct fs_context *fc)
{
	struct nfs_fs_context *ctx = nfs_fc2context(fc);
	int err;

	dfprintk(MOUNT, "--> nfs4_try_get_tree()\n");

	/* We create a mount for the server's root, walk to the requested
	 * location and then create another mount for that.
	 */
	err= do_nfs4_mount(nfs4_create_server(fc),
			   fc, ctx->nfs_server.hostname,
			   ctx->nfs_server.export_path);
	if (err) {
		nfs_ferrorf(fc, MOUNT, "NFS4: Couldn't follow remote path");
		dfprintk(MOUNT, "<-- nfs4_try_get_tree() = %d [error]\n", err);
	} else {
		dfprintk(MOUNT, "<-- nfs4_try_get_tree() = 0\n");
	}
	return err;
}

/*
 * Create an NFS4 server record on referral traversal
 */
int nfs4_get_referral_tree(struct fs_context *fc)
{
	struct nfs_fs_context *ctx = nfs_fc2context(fc);
	int err;

	dprintk("--> nfs4_referral_mount()\n");

	/* create a new volume representation */
	err = do_nfs4_mount(nfs4_create_referral_server(fc),
			    fc, ctx->nfs_server.hostname,
			    ctx->nfs_server.export_path);
	if (err) {
		nfs_ferrorf(fc, MOUNT, "NFS4: Couldn't follow remote path");
		dfprintk(MOUNT, "<-- nfs4_get_referral_tree() = %d [error]\n", err);
	} else {
		dfprintk(MOUNT, "<-- nfs4_get_referral_tree() = 0\n");
	}
	return err;
}

static int __init init_nfs_v4(void)
{
	int err;

	err = nfs_dns_resolver_init();
	if (err)
		goto out;

	err = nfs_idmap_init();
	if (err)
		goto out1;

#ifdef CONFIG_NFS_V4_2
	err = nfs4_xattr_cache_init();
	if (err)
		goto out2;
#endif

	err = nfs4_register_sysctl();
	if (err)
		goto out2;

#ifdef CONFIG_NFS_V4_2
	nfs42_ssc_register_ops();
#endif
	register_nfs_version(&nfs_v4);
	return 0;
out2:
	nfs_idmap_quit();
out1:
	nfs_dns_resolver_destroy();
out:
	return err;
}

static void __exit exit_nfs_v4(void)
{
	/* Not called in the _init(), conditionally loaded */
	nfs4_pnfs_v3_ds_connect_unload();

	unregister_nfs_version(&nfs_v4);
#ifdef CONFIG_NFS_V4_2
	nfs4_xattr_cache_exit();
	nfs42_ssc_unregister_ops();
#endif
	nfs4_unregister_sysctl();
	nfs_idmap_quit();
	nfs_dns_resolver_destroy();
}

MODULE_DESCRIPTION("NFSv4 client support");
MODULE_LICENSE("GPL");

module_init(init_nfs_v4);
module_exit(exit_nfs_v4);
