// 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"

static const struct nfsd_localio_operations nfsd_localio_ops = {
	.nfsd_serv_try_get  = nfsd_serv_try_get,
	.nfsd_serv_put  = nfsd_serv_put,
	.nfsd_open_local_fh = nfsd_open_local_fh,
	.nfsd_file_put_local = nfsd_file_put_local,
	.nfsd_file_file = nfsd_file_file,
};

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

/**
 * 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
 * @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_serv_put and
 * nfsd_file_put (via nfs_to->nfsd_file_put_local).
 */
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, 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);

	/* 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);

	return localio;
}
EXPORT_SYMBOL_GPL(nfsd_open_local_fh);

/*
 * 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,
			  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,
};
