18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * This file contains all the stubs needed when communicating with lockd.
48c2ecf20Sopenharmony_ci * This level of indirection is necessary so we can run nfsd+lockd without
58c2ecf20Sopenharmony_ci * requiring the nfs client to be compiled in/loaded, and vice versa.
68c2ecf20Sopenharmony_ci *
78c2ecf20Sopenharmony_ci * Copyright (C) 1996, Olaf Kirch <okir@monad.swb.de>
88c2ecf20Sopenharmony_ci */
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ci#include <linux/file.h>
118c2ecf20Sopenharmony_ci#include <linux/lockd/bind.h>
128c2ecf20Sopenharmony_ci#include "nfsd.h"
138c2ecf20Sopenharmony_ci#include "vfs.h"
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_ci#define NFSDDBG_FACILITY		NFSDDBG_LOCKD
168c2ecf20Sopenharmony_ci
178c2ecf20Sopenharmony_ci#ifdef CONFIG_LOCKD_V4
188c2ecf20Sopenharmony_ci#define nlm_stale_fh	nlm4_stale_fh
198c2ecf20Sopenharmony_ci#define nlm_failed	nlm4_failed
208c2ecf20Sopenharmony_ci#else
218c2ecf20Sopenharmony_ci#define nlm_stale_fh	nlm_lck_denied_nolocks
228c2ecf20Sopenharmony_ci#define nlm_failed	nlm_lck_denied_nolocks
238c2ecf20Sopenharmony_ci#endif
248c2ecf20Sopenharmony_ci/*
258c2ecf20Sopenharmony_ci * Note: we hold the dentry use count while the file is open.
268c2ecf20Sopenharmony_ci */
278c2ecf20Sopenharmony_cistatic __be32
288c2ecf20Sopenharmony_cinlm_fopen(struct svc_rqst *rqstp, struct nfs_fh *f, struct file **filp)
298c2ecf20Sopenharmony_ci{
308c2ecf20Sopenharmony_ci	__be32		nfserr;
318c2ecf20Sopenharmony_ci	struct svc_fh	fh;
328c2ecf20Sopenharmony_ci
338c2ecf20Sopenharmony_ci	/* must initialize before using! but maxsize doesn't matter */
348c2ecf20Sopenharmony_ci	fh_init(&fh,0);
358c2ecf20Sopenharmony_ci	fh.fh_handle.fh_size = f->size;
368c2ecf20Sopenharmony_ci	memcpy((char*)&fh.fh_handle.fh_base, f->data, f->size);
378c2ecf20Sopenharmony_ci	fh.fh_export = NULL;
388c2ecf20Sopenharmony_ci
398c2ecf20Sopenharmony_ci	nfserr = nfsd_open(rqstp, &fh, S_IFREG, NFSD_MAY_LOCK, filp);
408c2ecf20Sopenharmony_ci	fh_put(&fh);
418c2ecf20Sopenharmony_ci 	/* We return nlm error codes as nlm doesn't know
428c2ecf20Sopenharmony_ci	 * about nfsd, but nfsd does know about nlm..
438c2ecf20Sopenharmony_ci	 */
448c2ecf20Sopenharmony_ci	switch (nfserr) {
458c2ecf20Sopenharmony_ci	case nfs_ok:
468c2ecf20Sopenharmony_ci		return 0;
478c2ecf20Sopenharmony_ci	case nfserr_dropit:
488c2ecf20Sopenharmony_ci		return nlm_drop_reply;
498c2ecf20Sopenharmony_ci	case nfserr_stale:
508c2ecf20Sopenharmony_ci		return nlm_stale_fh;
518c2ecf20Sopenharmony_ci	default:
528c2ecf20Sopenharmony_ci		return nlm_failed;
538c2ecf20Sopenharmony_ci	}
548c2ecf20Sopenharmony_ci}
558c2ecf20Sopenharmony_ci
568c2ecf20Sopenharmony_cistatic void
578c2ecf20Sopenharmony_cinlm_fclose(struct file *filp)
588c2ecf20Sopenharmony_ci{
598c2ecf20Sopenharmony_ci	fput(filp);
608c2ecf20Sopenharmony_ci}
618c2ecf20Sopenharmony_ci
628c2ecf20Sopenharmony_cistatic const struct nlmsvc_binding nfsd_nlm_ops = {
638c2ecf20Sopenharmony_ci	.fopen		= nlm_fopen,		/* open file for locking */
648c2ecf20Sopenharmony_ci	.fclose		= nlm_fclose,		/* close file */
658c2ecf20Sopenharmony_ci};
668c2ecf20Sopenharmony_ci
678c2ecf20Sopenharmony_civoid
688c2ecf20Sopenharmony_cinfsd_lockd_init(void)
698c2ecf20Sopenharmony_ci{
708c2ecf20Sopenharmony_ci	dprintk("nfsd: initializing lockd\n");
718c2ecf20Sopenharmony_ci	nlmsvc_ops = &nfsd_nlm_ops;
728c2ecf20Sopenharmony_ci}
738c2ecf20Sopenharmony_ci
748c2ecf20Sopenharmony_civoid
758c2ecf20Sopenharmony_cinfsd_lockd_shutdown(void)
768c2ecf20Sopenharmony_ci{
778c2ecf20Sopenharmony_ci	nlmsvc_ops = NULL;
788c2ecf20Sopenharmony_ci}
79