// SPDX-License-Identifier: GPL-2.0-only
/*
 * NFS server support for local clients to bypass network stack
 *
 * Copyright (C) 2014 Weston Andros Adamson <dros@primarydata.com>
 * Copyright (C) 2019 Trond Myklebust <trond.myklebust@hammerspace.com>
 * Copyright (C) 2024 Mike Snitzer <snitzer@hammerspace.com>
 * Copyright (C) 2024 NeilBrown <neilb@suse.de>
 */

#include <linux/exportfs.h>
#include <linux/sunrpc/svcauth.h>
#include <linux/sunrpc/clnt.h>
#include <linux/nfs.h>
#include <linux/nfs_common.h>
#include <linux/nfslocalio.h>
#include <linux/nfs_fs.h>
#include <linux/nfs_xdr.h>
#include <linux/string.h>

#include "nfsd.h"
#include "vfs.h"
#include "netns.h"
#include "filecache.h"
#include "cache.h"

/**
 * nfsd_open_local_fh - lookup a local filehandle @nfs_fh and map to nfsd_file
 *
 * @net: 'struct net' to get the proper nfsd_net required for LOCALIO access
 * @dom: 'struct auth_domain' required for LOCALIO access
 * @rpc_clnt: rpc_clnt that the client established
 * @cred: cred that the client established
 * @nfs_fh: filehandle to lookup
 * @pnf: place to find the nfsd_file, or store it if it was non-NULL
 * @fmode: fmode_t to use for open
 *
 * This function maps a local fh to a path on a local filesystem.
 * This is useful when the nfs client has the local server mounted - it can
 * avoid all the NFS overhead with reads, writes and commits.
 *
 * On successful return, returned nfsd_file will have its nf_net member
 * set. Caller (NFS client) is responsible for calling nfsd_net_put and
 * nfsd_file_put (via nfs_to_nfsd_file_put_local).
 */
static struct nfsd_file *
nfsd_open_local_fh(struct net *net, struct auth_domain *dom,
		   struct rpc_clnt *rpc_clnt, const struct cred *cred,
		   const struct nfs_fh *nfs_fh, struct nfsd_file __rcu **pnf,
		   const fmode_t fmode)
{
	int mayflags = NFSD_MAY_LOCALIO;
	struct svc_cred rq_cred;
	struct svc_fh fh;
	struct nfsd_file *localio;
	__be32 beres;

	if (nfs_fh->size > NFS4_FHSIZE)
		return ERR_PTR(-EINVAL);

	if (!nfsd_net_try_get(net))
		return ERR_PTR(-ENXIO);

	rcu_read_lock();
	localio = nfsd_file_get(rcu_dereference(*pnf));
	rcu_read_unlock();
	if (localio)
		return localio;

	/* nfs_fh -> svc_fh */
	fh_init(&fh, NFS4_FHSIZE);
	fh.fh_handle.fh_size = nfs_fh->size;
	memcpy(fh.fh_handle.fh_raw, nfs_fh->data, nfs_fh->size);

	if (fmode & FMODE_READ)
		mayflags |= NFSD_MAY_READ;
	if (fmode & FMODE_WRITE)
		mayflags |= NFSD_MAY_WRITE;

	svcauth_map_clnt_to_svc_cred_local(rpc_clnt, cred, &rq_cred);

	beres = nfsd_file_acquire_local(net, &rq_cred, dom,
					&fh, mayflags, &localio);
	if (beres)
		localio = ERR_PTR(nfs_stat_to_errno(be32_to_cpu(beres)));

	fh_put(&fh);
	if (rq_cred.cr_group_info)
		put_group_info(rq_cred.cr_group_info);

	if (!IS_ERR(localio)) {
		struct nfsd_file *new;
		if (!nfsd_net_try_get(net)) {
			nfsd_file_put(localio);
			nfsd_net_put(net);
			return ERR_PTR(-ENXIO);
		}
		nfsd_file_get(localio);
	again:
		new = unrcu_pointer(cmpxchg(pnf, NULL, RCU_INITIALIZER(localio)));
		if (new) {
			/* Some other thread installed an nfsd_file */
			if (nfsd_file_get(new) == NULL)
				goto again;
			/*
			 * Drop the ref we were going to install (both file and
			 * net) and the one we were going to return (only file).
			 */
			nfsd_file_put(localio);
			nfsd_net_put(net);
			nfsd_file_put(localio);
			localio = new;
		}
	} else
		nfsd_net_put(net);

	return localio;
}

static void nfsd_file_dio_alignment(struct nfsd_file *nf,
				    u32 *nf_dio_mem_align,
				    u32 *nf_dio_offset_align,
				    u32 *nf_dio_read_offset_align)
{
	*nf_dio_mem_align = nf->nf_dio_mem_align;
	*nf_dio_offset_align = nf->nf_dio_offset_align;
	*nf_dio_read_offset_align = nf->nf_dio_read_offset_align;
}

static const struct nfsd_localio_operations nfsd_localio_ops = {
	.nfsd_net_try_get  = nfsd_net_try_get,
	.nfsd_net_put  = nfsd_net_put,
	.nfsd_open_local_fh = nfsd_open_local_fh,
	.nfsd_file_put_local = nfsd_file_put_local,
	.nfsd_file_file = nfsd_file_file,
	.nfsd_file_dio_alignment = nfsd_file_dio_alignment,
};

void nfsd_localio_ops_init(void)
{
	nfs_to = &nfsd_localio_ops;
}

/*
 * UUID_IS_LOCAL XDR functions
 */

static __be32 localio_proc_null(struct svc_rqst *rqstp)
{
	return rpc_success;
}

struct localio_uuidarg {
	uuid_t			uuid;
};

static __be32 localio_proc_uuid_is_local(struct svc_rqst *rqstp)
{
	struct localio_uuidarg *argp = rqstp->rq_argp;
	struct net *net = SVC_NET(rqstp);
	struct nfsd_net *nn = net_generic(net, nfsd_net_id);

	nfs_uuid_is_local(&argp->uuid, &nn->local_clients,
			  &nn->local_clients_lock,
			  net, rqstp->rq_client, THIS_MODULE);

	return rpc_success;
}

static bool localio_decode_uuidarg(struct svc_rqst *rqstp,
				   struct xdr_stream *xdr)
{
	struct localio_uuidarg *argp = rqstp->rq_argp;
	u8 uuid[UUID_SIZE];

	if (decode_opaque_fixed(xdr, uuid, UUID_SIZE))
		return false;
	import_uuid(&argp->uuid, uuid);

	return true;
}

static const struct svc_procedure localio_procedures1[] = {
	[LOCALIOPROC_NULL] = {
		.pc_func = localio_proc_null,
		.pc_decode = nfssvc_decode_voidarg,
		.pc_encode = nfssvc_encode_voidres,
		.pc_argsize = sizeof(struct nfsd_voidargs),
		.pc_ressize = sizeof(struct nfsd_voidres),
		.pc_cachetype = RC_NOCACHE,
		.pc_xdrressize = 0,
		.pc_name = "NULL",
	},
	[LOCALIOPROC_UUID_IS_LOCAL] = {
		.pc_func = localio_proc_uuid_is_local,
		.pc_decode = localio_decode_uuidarg,
		.pc_encode = nfssvc_encode_voidres,
		.pc_argsize = sizeof(struct localio_uuidarg),
		.pc_argzero = sizeof(struct localio_uuidarg),
		.pc_ressize = sizeof(struct nfsd_voidres),
		.pc_cachetype = RC_NOCACHE,
		.pc_name = "UUID_IS_LOCAL",
	},
};

#define LOCALIO_NR_PROCEDURES ARRAY_SIZE(localio_procedures1)
static DEFINE_PER_CPU_ALIGNED(unsigned long,
			      localio_count[LOCALIO_NR_PROCEDURES]);
const struct svc_version localio_version1 = {
	.vs_vers	= 1,
	.vs_nproc	= LOCALIO_NR_PROCEDURES,
	.vs_proc	= localio_procedures1,
	.vs_dispatch	= nfsd_dispatch,
	.vs_count	= localio_count,
	.vs_xdrsize	= XDR_QUADLEN(UUID_SIZE),
	.vs_hidden	= true,
};
