xref: /openbmc/linux/fs/lockd/svcproc.c (revision 184cefbe62627730c30282df12bcff9aae4816ea)
1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
21da177e4SLinus Torvalds /*
31da177e4SLinus Torvalds  * linux/fs/lockd/svcproc.c
41da177e4SLinus Torvalds  *
51da177e4SLinus Torvalds  * Lockd server procedures. We don't implement the NLM_*_RES
61da177e4SLinus Torvalds  * procedures because we don't use the async procedures.
71da177e4SLinus Torvalds  *
81da177e4SLinus Torvalds  * Copyright (C) 1996, Olaf Kirch <okir@monad.swb.de>
91da177e4SLinus Torvalds  */
101da177e4SLinus Torvalds 
111da177e4SLinus Torvalds #include <linux/types.h>
121da177e4SLinus Torvalds #include <linux/time.h>
131da177e4SLinus Torvalds #include <linux/lockd/lockd.h>
141da177e4SLinus Torvalds #include <linux/lockd/share.h>
155ccb0066SStanislav Kinsbursky #include <linux/sunrpc/svc_xprt.h>
161da177e4SLinus Torvalds 
171da177e4SLinus Torvalds #define NLMDBG_FACILITY		NLMDBG_CLIENT
181da177e4SLinus Torvalds 
191da177e4SLinus Torvalds #ifdef CONFIG_LOCKD_V4
2052921e02SAl Viro static __be32
2152921e02SAl Viro cast_to_nlm(__be32 status, u32 vers)
221da177e4SLinus Torvalds {
231da177e4SLinus Torvalds 	/* Note: status is assumed to be in network byte order !!! */
241da177e4SLinus Torvalds 	if (vers != 4){
251da177e4SLinus Torvalds 		switch (status) {
261da177e4SLinus Torvalds 		case nlm_granted:
271da177e4SLinus Torvalds 		case nlm_lck_denied:
281da177e4SLinus Torvalds 		case nlm_lck_denied_nolocks:
291da177e4SLinus Torvalds 		case nlm_lck_blocked:
301da177e4SLinus Torvalds 		case nlm_lck_denied_grace_period:
315ea0d750SMarc Eshel 		case nlm_drop_reply:
321da177e4SLinus Torvalds 			break;
331da177e4SLinus Torvalds 		case nlm4_deadlock:
341da177e4SLinus Torvalds 			status = nlm_lck_denied;
351da177e4SLinus Torvalds 			break;
361da177e4SLinus Torvalds 		default:
371da177e4SLinus Torvalds 			status = nlm_lck_denied_nolocks;
381da177e4SLinus Torvalds 		}
391da177e4SLinus Torvalds 	}
401da177e4SLinus Torvalds 
411da177e4SLinus Torvalds 	return (status);
421da177e4SLinus Torvalds }
431da177e4SLinus Torvalds #define	cast_status(status) (cast_to_nlm(status, rqstp->rq_vers))
441da177e4SLinus Torvalds #else
451da177e4SLinus Torvalds #define cast_status(status) (status)
461da177e4SLinus Torvalds #endif
471da177e4SLinus Torvalds 
481da177e4SLinus Torvalds /*
491da177e4SLinus Torvalds  * Obtain client and file from arguments
501da177e4SLinus Torvalds  */
5152921e02SAl Viro static __be32
521da177e4SLinus Torvalds nlmsvc_retrieve_args(struct svc_rqst *rqstp, struct nlm_args *argp,
531da177e4SLinus Torvalds 			struct nlm_host **hostp, struct nlm_file **filp)
541da177e4SLinus Torvalds {
551da177e4SLinus Torvalds 	struct nlm_host		*host = NULL;
561da177e4SLinus Torvalds 	struct nlm_file		*file = NULL;
571da177e4SLinus Torvalds 	struct nlm_lock		*lock = &argp->lock;
587f024fcdSJ. Bruce Fields 	int			mode;
5952921e02SAl Viro 	__be32			error = 0;
601da177e4SLinus Torvalds 
611da177e4SLinus Torvalds 	/* nfsd callbacks must have been installed for this procedure */
621da177e4SLinus Torvalds 	if (!nlmsvc_ops)
631da177e4SLinus Torvalds 		return nlm_lck_denied_nolocks;
641da177e4SLinus Torvalds 
651da177e4SLinus Torvalds 	/* Obtain host handle */
66db4e4c9aSOlaf Kirch 	if (!(host = nlmsvc_lookup_host(rqstp, lock->caller, lock->len))
67977faf39SOlaf Kirch 	 || (argp->monitor && nsm_monitor(host) < 0))
681da177e4SLinus Torvalds 		goto no_locks;
691da177e4SLinus Torvalds 	*hostp = host;
701da177e4SLinus Torvalds 
711da177e4SLinus Torvalds 	/* Obtain file pointer. Not used by FREE_ALL call. */
721da177e4SLinus Torvalds 	if (filp != NULL) {
732dc6f19eSJ. Bruce Fields 		error = cast_status(nlm_lookup_file(rqstp, &file, lock));
74cd0b16c1STrond Myklebust 		if (error != 0)
751da177e4SLinus Torvalds 			goto no_locks;
761da177e4SLinus Torvalds 		*filp = file;
771da177e4SLinus Torvalds 
781da177e4SLinus Torvalds 		/* Set up the missing parts of the file_lock structure */
797f024fcdSJ. Bruce Fields 		mode = lock_to_openmode(&lock->fl);
807f024fcdSJ. Bruce Fields 		lock->fl.fl_file  = file->f_file[mode];
81646d73e9SBenjamin Coddington 		lock->fl.fl_pid = current->tgid;
821da177e4SLinus Torvalds 		lock->fl.fl_lmops = &nlmsvc_lock_operations;
8389e0edfbSBenjamin Coddington 		nlmsvc_locks_init_private(&lock->fl, host, (pid_t)lock->svid);
8489e0edfbSBenjamin Coddington 		if (!lock->fl.fl_owner) {
8589e0edfbSBenjamin Coddington 			/* lockowner allocation has failed */
8689e0edfbSBenjamin Coddington 			nlmsvc_release_host(host);
8789e0edfbSBenjamin Coddington 			return nlm_lck_denied_nolocks;
8889e0edfbSBenjamin Coddington 		}
891da177e4SLinus Torvalds 	}
901da177e4SLinus Torvalds 
911da177e4SLinus Torvalds 	return 0;
921da177e4SLinus Torvalds 
931da177e4SLinus Torvalds no_locks:
9467216b94SChuck Lever 	nlmsvc_release_host(host);
95d343fce1SNeilBrown 	if (error)
96d343fce1SNeilBrown 		return error;
971da177e4SLinus Torvalds 	return nlm_lck_denied_nolocks;
981da177e4SLinus Torvalds }
991da177e4SLinus Torvalds 
1001da177e4SLinus Torvalds /*
1011da177e4SLinus Torvalds  * NULL: Test for presence of service
1021da177e4SLinus Torvalds  */
1037111c66eSAl Viro static __be32
104a6beb732SChristoph Hellwig nlmsvc_proc_null(struct svc_rqst *rqstp)
1051da177e4SLinus Torvalds {
1061da177e4SLinus Torvalds 	dprintk("lockd: NULL          called\n");
1071da177e4SLinus Torvalds 	return rpc_success;
1081da177e4SLinus Torvalds }
1091da177e4SLinus Torvalds 
1101da177e4SLinus Torvalds /*
1111da177e4SLinus Torvalds  * TEST: Check for conflicting lock
1121da177e4SLinus Torvalds  */
1137111c66eSAl Viro static __be32
114a6beb732SChristoph Hellwig __nlmsvc_proc_test(struct svc_rqst *rqstp, struct nlm_res *resp)
1151da177e4SLinus Torvalds {
116a6beb732SChristoph Hellwig 	struct nlm_args *argp = rqstp->rq_argp;
1171da177e4SLinus Torvalds 	struct nlm_host	*host;
1181da177e4SLinus Torvalds 	struct nlm_file	*file;
119*184cefbeSBenjamin Coddington 	struct nlm_lockowner *test_owner;
120317602f3SHarvey Harrison 	__be32 rc = rpc_success;
1211da177e4SLinus Torvalds 
1221da177e4SLinus Torvalds 	dprintk("lockd: TEST          called\n");
1231da177e4SLinus Torvalds 	resp->cookie = argp->cookie;
1241da177e4SLinus Torvalds 
1251da177e4SLinus Torvalds 	/* Obtain client and file */
1261da177e4SLinus Torvalds 	if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, &host, &file)))
127d343fce1SNeilBrown 		return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success;
1281da177e4SLinus Torvalds 
129*184cefbeSBenjamin Coddington 	test_owner = argp->lock.fl.fl_owner;
130*184cefbeSBenjamin Coddington 
1311da177e4SLinus Torvalds 	/* Now check for conflicting locks */
1328f920d5eSJeff Layton 	resp->status = cast_status(nlmsvc_testlock(rqstp, file, host, &argp->lock, &resp->lock, &resp->cookie));
1335ea0d750SMarc Eshel 	if (resp->status == nlm_drop_reply)
134b7e6b869SOleg Drokin 		rc = rpc_drop_reply;
135b7e6b869SOleg Drokin 	else
1361da177e4SLinus Torvalds 		dprintk("lockd: TEST          status %d vers %d\n",
1371da177e4SLinus Torvalds 			ntohl(resp->status), rqstp->rq_vers);
138b7e6b869SOleg Drokin 
139*184cefbeSBenjamin Coddington 	nlmsvc_put_lockowner(test_owner);
14067216b94SChuck Lever 	nlmsvc_release_host(host);
1411da177e4SLinus Torvalds 	nlm_release_file(file);
142b7e6b869SOleg Drokin 	return rc;
1431da177e4SLinus Torvalds }
1441da177e4SLinus Torvalds 
1457111c66eSAl Viro static __be32
146a6beb732SChristoph Hellwig nlmsvc_proc_test(struct svc_rqst *rqstp)
1471da177e4SLinus Torvalds {
148a6beb732SChristoph Hellwig 	return __nlmsvc_proc_test(rqstp, rqstp->rq_resp);
149a6beb732SChristoph Hellwig }
150a6beb732SChristoph Hellwig 
151a6beb732SChristoph Hellwig static __be32
152a6beb732SChristoph Hellwig __nlmsvc_proc_lock(struct svc_rqst *rqstp, struct nlm_res *resp)
153a6beb732SChristoph Hellwig {
154a6beb732SChristoph Hellwig 	struct nlm_args *argp = rqstp->rq_argp;
1551da177e4SLinus Torvalds 	struct nlm_host	*host;
1561da177e4SLinus Torvalds 	struct nlm_file	*file;
157317602f3SHarvey Harrison 	__be32 rc = rpc_success;
1581da177e4SLinus Torvalds 
1591da177e4SLinus Torvalds 	dprintk("lockd: LOCK          called\n");
1601da177e4SLinus Torvalds 
1611da177e4SLinus Torvalds 	resp->cookie = argp->cookie;
1621da177e4SLinus Torvalds 
1631da177e4SLinus Torvalds 	/* Obtain client and file */
1641da177e4SLinus Torvalds 	if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, &host, &file)))
165d343fce1SNeilBrown 		return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success;
1661da177e4SLinus Torvalds 
1671da177e4SLinus Torvalds #if 0
1681da177e4SLinus Torvalds 	/* If supplied state doesn't match current state, we assume it's
1691da177e4SLinus Torvalds 	 * an old request that time-warped somehow. Any error return would
1701da177e4SLinus Torvalds 	 * do in this case because it's irrelevant anyway.
1711da177e4SLinus Torvalds 	 *
1721da177e4SLinus Torvalds 	 * NB: We don't retrieve the remote host's state yet.
1731da177e4SLinus Torvalds 	 */
1741da177e4SLinus Torvalds 	if (host->h_nsmstate && host->h_nsmstate != argp->state) {
1751da177e4SLinus Torvalds 		resp->status = nlm_lck_denied_nolocks;
1761da177e4SLinus Torvalds 	} else
1771da177e4SLinus Torvalds #endif
1781da177e4SLinus Torvalds 
1791da177e4SLinus Torvalds 	/* Now try to lock the file */
1806cde4de8SJeff Layton 	resp->status = cast_status(nlmsvc_lock(rqstp, file, host, &argp->lock,
181b2b50289SJ. Bruce Fields 					       argp->block, &argp->cookie,
182b2b50289SJ. Bruce Fields 					       argp->reclaim));
1831a8322b2SMarc Eshel 	if (resp->status == nlm_drop_reply)
184b7e6b869SOleg Drokin 		rc = rpc_drop_reply;
185b7e6b869SOleg Drokin 	else
1861da177e4SLinus Torvalds 		dprintk("lockd: LOCK         status %d\n", ntohl(resp->status));
187b7e6b869SOleg Drokin 
18889e0edfbSBenjamin Coddington 	nlmsvc_release_lockowner(&argp->lock);
18967216b94SChuck Lever 	nlmsvc_release_host(host);
1901da177e4SLinus Torvalds 	nlm_release_file(file);
191b7e6b869SOleg Drokin 	return rc;
1921da177e4SLinus Torvalds }
1931da177e4SLinus Torvalds 
1947111c66eSAl Viro static __be32
195a6beb732SChristoph Hellwig nlmsvc_proc_lock(struct svc_rqst *rqstp)
1961da177e4SLinus Torvalds {
197a6beb732SChristoph Hellwig 	return __nlmsvc_proc_lock(rqstp, rqstp->rq_resp);
198a6beb732SChristoph Hellwig }
199a6beb732SChristoph Hellwig 
200a6beb732SChristoph Hellwig static __be32
201a6beb732SChristoph Hellwig __nlmsvc_proc_cancel(struct svc_rqst *rqstp, struct nlm_res *resp)
202a6beb732SChristoph Hellwig {
203a6beb732SChristoph Hellwig 	struct nlm_args *argp = rqstp->rq_argp;
2041da177e4SLinus Torvalds 	struct nlm_host	*host;
2051da177e4SLinus Torvalds 	struct nlm_file	*file;
2065ccb0066SStanislav Kinsbursky 	struct net *net = SVC_NET(rqstp);
2071da177e4SLinus Torvalds 
2081da177e4SLinus Torvalds 	dprintk("lockd: CANCEL        called\n");
2091da177e4SLinus Torvalds 
2101da177e4SLinus Torvalds 	resp->cookie = argp->cookie;
2111da177e4SLinus Torvalds 
2121da177e4SLinus Torvalds 	/* Don't accept requests during grace period */
2135ccb0066SStanislav Kinsbursky 	if (locks_in_grace(net)) {
2141da177e4SLinus Torvalds 		resp->status = nlm_lck_denied_grace_period;
2151da177e4SLinus Torvalds 		return rpc_success;
2161da177e4SLinus Torvalds 	}
2171da177e4SLinus Torvalds 
2181da177e4SLinus Torvalds 	/* Obtain client and file */
2191da177e4SLinus Torvalds 	if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, &host, &file)))
220d343fce1SNeilBrown 		return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success;
2211da177e4SLinus Torvalds 
2221da177e4SLinus Torvalds 	/* Try to cancel request. */
2235ccb0066SStanislav Kinsbursky 	resp->status = cast_status(nlmsvc_cancel_blocked(net, file, &argp->lock));
2241da177e4SLinus Torvalds 
2251da177e4SLinus Torvalds 	dprintk("lockd: CANCEL        status %d\n", ntohl(resp->status));
22689e0edfbSBenjamin Coddington 	nlmsvc_release_lockowner(&argp->lock);
22767216b94SChuck Lever 	nlmsvc_release_host(host);
2281da177e4SLinus Torvalds 	nlm_release_file(file);
2291da177e4SLinus Torvalds 	return rpc_success;
2301da177e4SLinus Torvalds }
2311da177e4SLinus Torvalds 
232a6beb732SChristoph Hellwig static __be32
233a6beb732SChristoph Hellwig nlmsvc_proc_cancel(struct svc_rqst *rqstp)
234a6beb732SChristoph Hellwig {
235a6beb732SChristoph Hellwig 	return __nlmsvc_proc_cancel(rqstp, rqstp->rq_resp);
236a6beb732SChristoph Hellwig }
237a6beb732SChristoph Hellwig 
2381da177e4SLinus Torvalds /*
2391da177e4SLinus Torvalds  * UNLOCK: release a lock
2401da177e4SLinus Torvalds  */
2417111c66eSAl Viro static __be32
242a6beb732SChristoph Hellwig __nlmsvc_proc_unlock(struct svc_rqst *rqstp, struct nlm_res *resp)
2431da177e4SLinus Torvalds {
244a6beb732SChristoph Hellwig 	struct nlm_args *argp = rqstp->rq_argp;
2451da177e4SLinus Torvalds 	struct nlm_host	*host;
2461da177e4SLinus Torvalds 	struct nlm_file	*file;
2475ccb0066SStanislav Kinsbursky 	struct net *net = SVC_NET(rqstp);
2481da177e4SLinus Torvalds 
2491da177e4SLinus Torvalds 	dprintk("lockd: UNLOCK        called\n");
2501da177e4SLinus Torvalds 
2511da177e4SLinus Torvalds 	resp->cookie = argp->cookie;
2521da177e4SLinus Torvalds 
2531da177e4SLinus Torvalds 	/* Don't accept new lock requests during grace period */
2545ccb0066SStanislav Kinsbursky 	if (locks_in_grace(net)) {
2551da177e4SLinus Torvalds 		resp->status = nlm_lck_denied_grace_period;
2561da177e4SLinus Torvalds 		return rpc_success;
2571da177e4SLinus Torvalds 	}
2581da177e4SLinus Torvalds 
2591da177e4SLinus Torvalds 	/* Obtain client and file */
2601da177e4SLinus Torvalds 	if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, &host, &file)))
261d343fce1SNeilBrown 		return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success;
2621da177e4SLinus Torvalds 
2631da177e4SLinus Torvalds 	/* Now try to remove the lock */
2645ccb0066SStanislav Kinsbursky 	resp->status = cast_status(nlmsvc_unlock(net, file, &argp->lock));
2651da177e4SLinus Torvalds 
2661da177e4SLinus Torvalds 	dprintk("lockd: UNLOCK        status %d\n", ntohl(resp->status));
26789e0edfbSBenjamin Coddington 	nlmsvc_release_lockowner(&argp->lock);
26867216b94SChuck Lever 	nlmsvc_release_host(host);
2691da177e4SLinus Torvalds 	nlm_release_file(file);
2701da177e4SLinus Torvalds 	return rpc_success;
2711da177e4SLinus Torvalds }
2721da177e4SLinus Torvalds 
273a6beb732SChristoph Hellwig static __be32
274a6beb732SChristoph Hellwig nlmsvc_proc_unlock(struct svc_rqst *rqstp)
275a6beb732SChristoph Hellwig {
276a6beb732SChristoph Hellwig 	return __nlmsvc_proc_unlock(rqstp, rqstp->rq_resp);
277a6beb732SChristoph Hellwig }
278a6beb732SChristoph Hellwig 
2791da177e4SLinus Torvalds /*
2801da177e4SLinus Torvalds  * GRANTED: A server calls us to tell that a process' lock request
2811da177e4SLinus Torvalds  * was granted
2821da177e4SLinus Torvalds  */
2837111c66eSAl Viro static __be32
284a6beb732SChristoph Hellwig __nlmsvc_proc_granted(struct svc_rqst *rqstp, struct nlm_res *resp)
2851da177e4SLinus Torvalds {
286a6beb732SChristoph Hellwig 	struct nlm_args *argp = rqstp->rq_argp;
287a6beb732SChristoph Hellwig 
2881da177e4SLinus Torvalds 	resp->cookie = argp->cookie;
2891da177e4SLinus Torvalds 
2901da177e4SLinus Torvalds 	dprintk("lockd: GRANTED       called\n");
291dcff09f1SChuck Lever 	resp->status = nlmclnt_grant(svc_addr(rqstp), &argp->lock);
2921da177e4SLinus Torvalds 	dprintk("lockd: GRANTED       status %d\n", ntohl(resp->status));
2931da177e4SLinus Torvalds 	return rpc_success;
2941da177e4SLinus Torvalds }
2951da177e4SLinus Torvalds 
296a6beb732SChristoph Hellwig static __be32
297a6beb732SChristoph Hellwig nlmsvc_proc_granted(struct svc_rqst *rqstp)
298a6beb732SChristoph Hellwig {
299a6beb732SChristoph Hellwig 	return __nlmsvc_proc_granted(rqstp, rqstp->rq_resp);
300a6beb732SChristoph Hellwig }
301a6beb732SChristoph Hellwig 
3021da177e4SLinus Torvalds /*
303d4716624STrond Myklebust  * This is the generic lockd callback for async RPC calls
304d4716624STrond Myklebust  */
305d4716624STrond Myklebust static void nlmsvc_callback_exit(struct rpc_task *task, void *data)
306d4716624STrond Myklebust {
307d4716624STrond Myklebust }
308d4716624STrond Myklebust 
3097db836d4SChuck Lever void nlmsvc_release_call(struct nlm_rqst *call)
3107db836d4SChuck Lever {
311fbca30c5SElena Reshetova 	if (!refcount_dec_and_test(&call->a_count))
3127db836d4SChuck Lever 		return;
31367216b94SChuck Lever 	nlmsvc_release_host(call->a_host);
3147db836d4SChuck Lever 	kfree(call);
3157db836d4SChuck Lever }
3167db836d4SChuck Lever 
317d4716624STrond Myklebust static void nlmsvc_callback_release(void *data)
318d4716624STrond Myklebust {
3197db836d4SChuck Lever 	nlmsvc_release_call(data);
320d4716624STrond Myklebust }
321d4716624STrond Myklebust 
322d4716624STrond Myklebust static const struct rpc_call_ops nlmsvc_callback_ops = {
323d4716624STrond Myklebust 	.rpc_call_done = nlmsvc_callback_exit,
324d4716624STrond Myklebust 	.rpc_release = nlmsvc_callback_release,
325d4716624STrond Myklebust };
326d4716624STrond Myklebust 
327d4716624STrond Myklebust /*
3281da177e4SLinus Torvalds  * `Async' versions of the above service routines. They aren't really,
3291da177e4SLinus Torvalds  * because we send the callback before the reply proper. I hope this
3301da177e4SLinus Torvalds  * doesn't break any clients.
3311da177e4SLinus Torvalds  */
332a6beb732SChristoph Hellwig static __be32 nlmsvc_callback(struct svc_rqst *rqstp, u32 proc,
333a6beb732SChristoph Hellwig 		__be32 (*func)(struct svc_rqst *, struct nlm_res *))
334d4716624STrond Myklebust {
335a6beb732SChristoph Hellwig 	struct nlm_args *argp = rqstp->rq_argp;
336d4716624STrond Myklebust 	struct nlm_host	*host;
337d4716624STrond Myklebust 	struct nlm_rqst	*call;
3387111c66eSAl Viro 	__be32 stat;
339d4716624STrond Myklebust 
340db4e4c9aSOlaf Kirch 	host = nlmsvc_lookup_host(rqstp,
341db4e4c9aSOlaf Kirch 				  argp->lock.caller,
342db4e4c9aSOlaf Kirch 				  argp->lock.len);
343d4716624STrond Myklebust 	if (host == NULL)
344d4716624STrond Myklebust 		return rpc_system_err;
345d4716624STrond Myklebust 
346d4716624STrond Myklebust 	call = nlm_alloc_call(host);
347446945abSAl Viro 	nlmsvc_release_host(host);
348d4716624STrond Myklebust 	if (call == NULL)
349d4716624STrond Myklebust 		return rpc_system_err;
350d4716624STrond Myklebust 
351a6beb732SChristoph Hellwig 	stat = func(rqstp, &call->a_res);
352d4716624STrond Myklebust 	if (stat != 0) {
3537db836d4SChuck Lever 		nlmsvc_release_call(call);
354d4716624STrond Myklebust 		return stat;
355d4716624STrond Myklebust 	}
356d4716624STrond Myklebust 
357d4716624STrond Myklebust 	call->a_flags = RPC_TASK_ASYNC;
358d4716624STrond Myklebust 	if (nlm_async_reply(call, proc, &nlmsvc_callback_ops) < 0)
359d4716624STrond Myklebust 		return rpc_system_err;
360d4716624STrond Myklebust 	return rpc_success;
361d4716624STrond Myklebust }
362d4716624STrond Myklebust 
363a6beb732SChristoph Hellwig static __be32 nlmsvc_proc_test_msg(struct svc_rqst *rqstp)
3641da177e4SLinus Torvalds {
3651da177e4SLinus Torvalds 	dprintk("lockd: TEST_MSG      called\n");
366a6beb732SChristoph Hellwig 	return nlmsvc_callback(rqstp, NLMPROC_TEST_RES, __nlmsvc_proc_test);
3671da177e4SLinus Torvalds }
3681da177e4SLinus Torvalds 
369a6beb732SChristoph Hellwig static __be32 nlmsvc_proc_lock_msg(struct svc_rqst *rqstp)
3701da177e4SLinus Torvalds {
3711da177e4SLinus Torvalds 	dprintk("lockd: LOCK_MSG      called\n");
372a6beb732SChristoph Hellwig 	return nlmsvc_callback(rqstp, NLMPROC_LOCK_RES, __nlmsvc_proc_lock);
3731da177e4SLinus Torvalds }
3741da177e4SLinus Torvalds 
375a6beb732SChristoph Hellwig static __be32 nlmsvc_proc_cancel_msg(struct svc_rqst *rqstp)
3761da177e4SLinus Torvalds {
3771da177e4SLinus Torvalds 	dprintk("lockd: CANCEL_MSG    called\n");
378a6beb732SChristoph Hellwig 	return nlmsvc_callback(rqstp, NLMPROC_CANCEL_RES, __nlmsvc_proc_cancel);
3791da177e4SLinus Torvalds }
3801da177e4SLinus Torvalds 
3817111c66eSAl Viro static __be32
382a6beb732SChristoph Hellwig nlmsvc_proc_unlock_msg(struct svc_rqst *rqstp)
3831da177e4SLinus Torvalds {
3841da177e4SLinus Torvalds 	dprintk("lockd: UNLOCK_MSG    called\n");
385a6beb732SChristoph Hellwig 	return nlmsvc_callback(rqstp, NLMPROC_UNLOCK_RES, __nlmsvc_proc_unlock);
3861da177e4SLinus Torvalds }
3871da177e4SLinus Torvalds 
3887111c66eSAl Viro static __be32
389a6beb732SChristoph Hellwig nlmsvc_proc_granted_msg(struct svc_rqst *rqstp)
3901da177e4SLinus Torvalds {
3911da177e4SLinus Torvalds 	dprintk("lockd: GRANTED_MSG   called\n");
392a6beb732SChristoph Hellwig 	return nlmsvc_callback(rqstp, NLMPROC_GRANTED_RES, __nlmsvc_proc_granted);
3931da177e4SLinus Torvalds }
3941da177e4SLinus Torvalds 
3951da177e4SLinus Torvalds /*
3961da177e4SLinus Torvalds  * SHARE: create a DOS share or alter existing share.
3971da177e4SLinus Torvalds  */
3987111c66eSAl Viro static __be32
399a6beb732SChristoph Hellwig nlmsvc_proc_share(struct svc_rqst *rqstp)
4001da177e4SLinus Torvalds {
401a6beb732SChristoph Hellwig 	struct nlm_args *argp = rqstp->rq_argp;
402a6beb732SChristoph Hellwig 	struct nlm_res *resp = rqstp->rq_resp;
4031da177e4SLinus Torvalds 	struct nlm_host	*host;
4041da177e4SLinus Torvalds 	struct nlm_file	*file;
4051da177e4SLinus Torvalds 
4061da177e4SLinus Torvalds 	dprintk("lockd: SHARE         called\n");
4071da177e4SLinus Torvalds 
4081da177e4SLinus Torvalds 	resp->cookie = argp->cookie;
4091da177e4SLinus Torvalds 
4101da177e4SLinus Torvalds 	/* Don't accept new lock requests during grace period */
4115ccb0066SStanislav Kinsbursky 	if (locks_in_grace(SVC_NET(rqstp)) && !argp->reclaim) {
4121da177e4SLinus Torvalds 		resp->status = nlm_lck_denied_grace_period;
4131da177e4SLinus Torvalds 		return rpc_success;
4141da177e4SLinus Torvalds 	}
4151da177e4SLinus Torvalds 
4161da177e4SLinus Torvalds 	/* Obtain client and file */
4171da177e4SLinus Torvalds 	if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, &host, &file)))
418d343fce1SNeilBrown 		return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success;
4191da177e4SLinus Torvalds 
4201da177e4SLinus Torvalds 	/* Now try to create the share */
4211da177e4SLinus Torvalds 	resp->status = cast_status(nlmsvc_share_file(host, file, argp));
4221da177e4SLinus Torvalds 
4231da177e4SLinus Torvalds 	dprintk("lockd: SHARE         status %d\n", ntohl(resp->status));
42489e0edfbSBenjamin Coddington 	nlmsvc_release_lockowner(&argp->lock);
42567216b94SChuck Lever 	nlmsvc_release_host(host);
4261da177e4SLinus Torvalds 	nlm_release_file(file);
4271da177e4SLinus Torvalds 	return rpc_success;
4281da177e4SLinus Torvalds }
4291da177e4SLinus Torvalds 
4301da177e4SLinus Torvalds /*
4311da177e4SLinus Torvalds  * UNSHARE: Release a DOS share.
4321da177e4SLinus Torvalds  */
4337111c66eSAl Viro static __be32
434a6beb732SChristoph Hellwig nlmsvc_proc_unshare(struct svc_rqst *rqstp)
4351da177e4SLinus Torvalds {
436a6beb732SChristoph Hellwig 	struct nlm_args *argp = rqstp->rq_argp;
437a6beb732SChristoph Hellwig 	struct nlm_res *resp = rqstp->rq_resp;
4381da177e4SLinus Torvalds 	struct nlm_host	*host;
4391da177e4SLinus Torvalds 	struct nlm_file	*file;
4401da177e4SLinus Torvalds 
4411da177e4SLinus Torvalds 	dprintk("lockd: UNSHARE       called\n");
4421da177e4SLinus Torvalds 
4431da177e4SLinus Torvalds 	resp->cookie = argp->cookie;
4441da177e4SLinus Torvalds 
4451da177e4SLinus Torvalds 	/* Don't accept requests during grace period */
4465ccb0066SStanislav Kinsbursky 	if (locks_in_grace(SVC_NET(rqstp))) {
4471da177e4SLinus Torvalds 		resp->status = nlm_lck_denied_grace_period;
4481da177e4SLinus Torvalds 		return rpc_success;
4491da177e4SLinus Torvalds 	}
4501da177e4SLinus Torvalds 
4511da177e4SLinus Torvalds 	/* Obtain client and file */
4521da177e4SLinus Torvalds 	if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, &host, &file)))
453d343fce1SNeilBrown 		return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success;
4541da177e4SLinus Torvalds 
4551da177e4SLinus Torvalds 	/* Now try to unshare the file */
4561da177e4SLinus Torvalds 	resp->status = cast_status(nlmsvc_unshare_file(host, file, argp));
4571da177e4SLinus Torvalds 
4581da177e4SLinus Torvalds 	dprintk("lockd: UNSHARE       status %d\n", ntohl(resp->status));
45989e0edfbSBenjamin Coddington 	nlmsvc_release_lockowner(&argp->lock);
46067216b94SChuck Lever 	nlmsvc_release_host(host);
4611da177e4SLinus Torvalds 	nlm_release_file(file);
4621da177e4SLinus Torvalds 	return rpc_success;
4631da177e4SLinus Torvalds }
4641da177e4SLinus Torvalds 
4651da177e4SLinus Torvalds /*
4661da177e4SLinus Torvalds  * NM_LOCK: Create an unmonitored lock
4671da177e4SLinus Torvalds  */
4687111c66eSAl Viro static __be32
469a6beb732SChristoph Hellwig nlmsvc_proc_nm_lock(struct svc_rqst *rqstp)
4701da177e4SLinus Torvalds {
471a6beb732SChristoph Hellwig 	struct nlm_args *argp = rqstp->rq_argp;
472a6beb732SChristoph Hellwig 
4731da177e4SLinus Torvalds 	dprintk("lockd: NM_LOCK       called\n");
4741da177e4SLinus Torvalds 
4751da177e4SLinus Torvalds 	argp->monitor = 0;		/* just clean the monitor flag */
476a6beb732SChristoph Hellwig 	return nlmsvc_proc_lock(rqstp);
4771da177e4SLinus Torvalds }
4781da177e4SLinus Torvalds 
4791da177e4SLinus Torvalds /*
4801da177e4SLinus Torvalds  * FREE_ALL: Release all locks and shares held by client
4811da177e4SLinus Torvalds  */
4827111c66eSAl Viro static __be32
483a6beb732SChristoph Hellwig nlmsvc_proc_free_all(struct svc_rqst *rqstp)
4841da177e4SLinus Torvalds {
485a6beb732SChristoph Hellwig 	struct nlm_args *argp = rqstp->rq_argp;
4861da177e4SLinus Torvalds 	struct nlm_host	*host;
4871da177e4SLinus Torvalds 
4881da177e4SLinus Torvalds 	/* Obtain client */
4891da177e4SLinus Torvalds 	if (nlmsvc_retrieve_args(rqstp, argp, &host, NULL))
4901da177e4SLinus Torvalds 		return rpc_success;
4911da177e4SLinus Torvalds 
4921da177e4SLinus Torvalds 	nlmsvc_free_host_resources(host);
49367216b94SChuck Lever 	nlmsvc_release_host(host);
4941da177e4SLinus Torvalds 	return rpc_success;
4951da177e4SLinus Torvalds }
4961da177e4SLinus Torvalds 
4971da177e4SLinus Torvalds /*
4981da177e4SLinus Torvalds  * SM_NOTIFY: private callback from statd (not part of official NLM proto)
4991da177e4SLinus Torvalds  */
5007111c66eSAl Viro static __be32
501a6beb732SChristoph Hellwig nlmsvc_proc_sm_notify(struct svc_rqst *rqstp)
5021da177e4SLinus Torvalds {
503a6beb732SChristoph Hellwig 	struct nlm_reboot *argp = rqstp->rq_argp;
504a6beb732SChristoph Hellwig 
5051da177e4SLinus Torvalds 	dprintk("lockd: SM_NOTIFY     called\n");
506b85e4676SChuck Lever 
507b85e4676SChuck Lever 	if (!nlm_privileged_requester(rqstp)) {
508ad06e4bdSChuck Lever 		char buf[RPC_MAX_ADDRBUFLEN];
509ad06e4bdSChuck Lever 		printk(KERN_WARNING "lockd: rejected NSM callback from %s\n",
510ad06e4bdSChuck Lever 				svc_print_addr(rqstp, buf, sizeof(buf)));
5111da177e4SLinus Torvalds 		return rpc_system_err;
5121da177e4SLinus Torvalds 	}
5131da177e4SLinus Torvalds 
5140ad95472SAndrey Ryabinin 	nlm_host_rebooted(SVC_NET(rqstp), argp);
5151da177e4SLinus Torvalds 	return rpc_success;
5161da177e4SLinus Torvalds }
5171da177e4SLinus Torvalds 
5181da177e4SLinus Torvalds /*
5191da177e4SLinus Torvalds  * client sent a GRANTED_RES, let's remove the associated block
5201da177e4SLinus Torvalds  */
5217111c66eSAl Viro static __be32
522a6beb732SChristoph Hellwig nlmsvc_proc_granted_res(struct svc_rqst *rqstp)
5231da177e4SLinus Torvalds {
524a6beb732SChristoph Hellwig 	struct nlm_res *argp = rqstp->rq_argp;
525a6beb732SChristoph Hellwig 
5261da177e4SLinus Torvalds 	if (!nlmsvc_ops)
5271da177e4SLinus Torvalds 		return rpc_success;
5281da177e4SLinus Torvalds 
5291da177e4SLinus Torvalds 	dprintk("lockd: GRANTED_RES   called\n");
5301da177e4SLinus Torvalds 
53139be4502SOlaf Kirch 	nlmsvc_grant_reply(&argp->cookie, argp->status);
5321da177e4SLinus Torvalds 	return rpc_success;
5331da177e4SLinus Torvalds }
5341da177e4SLinus Torvalds 
53549d99608SChuck Lever static __be32
53649d99608SChuck Lever nlmsvc_proc_unused(struct svc_rqst *rqstp)
53749d99608SChuck Lever {
53849d99608SChuck Lever 	return rpc_proc_unavail;
53949d99608SChuck Lever }
54049d99608SChuck Lever 
5411da177e4SLinus Torvalds /*
5421da177e4SLinus Torvalds  * NLM Server procedures.
5431da177e4SLinus Torvalds  */
5441da177e4SLinus Torvalds 
5451da177e4SLinus Torvalds struct nlm_void			{ int dummy; };
5461da177e4SLinus Torvalds 
5471da177e4SLinus Torvalds #define	Ck	(1+XDR_QUADLEN(NLM_MAXCOOKIELEN))	/* cookie */
5481da177e4SLinus Torvalds #define	St	1				/* status */
5491da177e4SLinus Torvalds #define	No	(1+1024/4)			/* Net Obj */
5501da177e4SLinus Torvalds #define	Rg	2				/* range - offset + size */
5511da177e4SLinus Torvalds 
55249d99608SChuck Lever const struct svc_procedure nlmsvc_procedures[24] = {
55349d99608SChuck Lever 	[NLMPROC_NULL] = {
55449d99608SChuck Lever 		.pc_func = nlmsvc_proc_null,
55549d99608SChuck Lever 		.pc_decode = nlmsvc_decode_void,
55649d99608SChuck Lever 		.pc_encode = nlmsvc_encode_void,
55749d99608SChuck Lever 		.pc_argsize = sizeof(struct nlm_void),
55849d99608SChuck Lever 		.pc_ressize = sizeof(struct nlm_void),
55949d99608SChuck Lever 		.pc_xdrressize = St,
5602289e87bSChuck Lever 		.pc_name = "NULL",
56149d99608SChuck Lever 	},
56249d99608SChuck Lever 	[NLMPROC_TEST] = {
56349d99608SChuck Lever 		.pc_func = nlmsvc_proc_test,
56449d99608SChuck Lever 		.pc_decode = nlmsvc_decode_testargs,
56549d99608SChuck Lever 		.pc_encode = nlmsvc_encode_testres,
56649d99608SChuck Lever 		.pc_argsize = sizeof(struct nlm_args),
56749d99608SChuck Lever 		.pc_ressize = sizeof(struct nlm_res),
56849d99608SChuck Lever 		.pc_xdrressize = Ck+St+2+No+Rg,
5692289e87bSChuck Lever 		.pc_name = "TEST",
57049d99608SChuck Lever 	},
57149d99608SChuck Lever 	[NLMPROC_LOCK] = {
57249d99608SChuck Lever 		.pc_func = nlmsvc_proc_lock,
57349d99608SChuck Lever 		.pc_decode = nlmsvc_decode_lockargs,
57449d99608SChuck Lever 		.pc_encode = nlmsvc_encode_res,
57549d99608SChuck Lever 		.pc_argsize = sizeof(struct nlm_args),
57649d99608SChuck Lever 		.pc_ressize = sizeof(struct nlm_res),
57749d99608SChuck Lever 		.pc_xdrressize = Ck+St,
5782289e87bSChuck Lever 		.pc_name = "LOCK",
57949d99608SChuck Lever 	},
58049d99608SChuck Lever 	[NLMPROC_CANCEL] = {
58149d99608SChuck Lever 		.pc_func = nlmsvc_proc_cancel,
58249d99608SChuck Lever 		.pc_decode = nlmsvc_decode_cancargs,
58349d99608SChuck Lever 		.pc_encode = nlmsvc_encode_res,
58449d99608SChuck Lever 		.pc_argsize = sizeof(struct nlm_args),
58549d99608SChuck Lever 		.pc_ressize = sizeof(struct nlm_res),
58649d99608SChuck Lever 		.pc_xdrressize = Ck+St,
5872289e87bSChuck Lever 		.pc_name = "CANCEL",
58849d99608SChuck Lever 	},
58949d99608SChuck Lever 	[NLMPROC_UNLOCK] = {
59049d99608SChuck Lever 		.pc_func = nlmsvc_proc_unlock,
59149d99608SChuck Lever 		.pc_decode = nlmsvc_decode_unlockargs,
59249d99608SChuck Lever 		.pc_encode = nlmsvc_encode_res,
59349d99608SChuck Lever 		.pc_argsize = sizeof(struct nlm_args),
59449d99608SChuck Lever 		.pc_ressize = sizeof(struct nlm_res),
59549d99608SChuck Lever 		.pc_xdrressize = Ck+St,
5962289e87bSChuck Lever 		.pc_name = "UNLOCK",
59749d99608SChuck Lever 	},
59849d99608SChuck Lever 	[NLMPROC_GRANTED] = {
59949d99608SChuck Lever 		.pc_func = nlmsvc_proc_granted,
60049d99608SChuck Lever 		.pc_decode = nlmsvc_decode_testargs,
60149d99608SChuck Lever 		.pc_encode = nlmsvc_encode_res,
60249d99608SChuck Lever 		.pc_argsize = sizeof(struct nlm_args),
60349d99608SChuck Lever 		.pc_ressize = sizeof(struct nlm_res),
60449d99608SChuck Lever 		.pc_xdrressize = Ck+St,
6052289e87bSChuck Lever 		.pc_name = "GRANTED",
60649d99608SChuck Lever 	},
60749d99608SChuck Lever 	[NLMPROC_TEST_MSG] = {
60849d99608SChuck Lever 		.pc_func = nlmsvc_proc_test_msg,
60949d99608SChuck Lever 		.pc_decode = nlmsvc_decode_testargs,
61049d99608SChuck Lever 		.pc_encode = nlmsvc_encode_void,
61149d99608SChuck Lever 		.pc_argsize = sizeof(struct nlm_args),
61249d99608SChuck Lever 		.pc_ressize = sizeof(struct nlm_void),
61349d99608SChuck Lever 		.pc_xdrressize = St,
6142289e87bSChuck Lever 		.pc_name = "TEST_MSG",
61549d99608SChuck Lever 	},
61649d99608SChuck Lever 	[NLMPROC_LOCK_MSG] = {
61749d99608SChuck Lever 		.pc_func = nlmsvc_proc_lock_msg,
61849d99608SChuck Lever 		.pc_decode = nlmsvc_decode_lockargs,
61949d99608SChuck Lever 		.pc_encode = nlmsvc_encode_void,
62049d99608SChuck Lever 		.pc_argsize = sizeof(struct nlm_args),
62149d99608SChuck Lever 		.pc_ressize = sizeof(struct nlm_void),
62249d99608SChuck Lever 		.pc_xdrressize = St,
6232289e87bSChuck Lever 		.pc_name = "LOCK_MSG",
62449d99608SChuck Lever 	},
62549d99608SChuck Lever 	[NLMPROC_CANCEL_MSG] = {
62649d99608SChuck Lever 		.pc_func = nlmsvc_proc_cancel_msg,
62749d99608SChuck Lever 		.pc_decode = nlmsvc_decode_cancargs,
62849d99608SChuck Lever 		.pc_encode = nlmsvc_encode_void,
62949d99608SChuck Lever 		.pc_argsize = sizeof(struct nlm_args),
63049d99608SChuck Lever 		.pc_ressize = sizeof(struct nlm_void),
63149d99608SChuck Lever 		.pc_xdrressize = St,
6322289e87bSChuck Lever 		.pc_name = "CANCEL_MSG",
63349d99608SChuck Lever 	},
63449d99608SChuck Lever 	[NLMPROC_UNLOCK_MSG] = {
63549d99608SChuck Lever 		.pc_func = nlmsvc_proc_unlock_msg,
63649d99608SChuck Lever 		.pc_decode = nlmsvc_decode_unlockargs,
63749d99608SChuck Lever 		.pc_encode = nlmsvc_encode_void,
63849d99608SChuck Lever 		.pc_argsize = sizeof(struct nlm_args),
63949d99608SChuck Lever 		.pc_ressize = sizeof(struct nlm_void),
64049d99608SChuck Lever 		.pc_xdrressize = St,
6412289e87bSChuck Lever 		.pc_name = "UNLOCK_MSG",
64249d99608SChuck Lever 	},
64349d99608SChuck Lever 	[NLMPROC_GRANTED_MSG] = {
64449d99608SChuck Lever 		.pc_func = nlmsvc_proc_granted_msg,
64549d99608SChuck Lever 		.pc_decode = nlmsvc_decode_testargs,
64649d99608SChuck Lever 		.pc_encode = nlmsvc_encode_void,
64749d99608SChuck Lever 		.pc_argsize = sizeof(struct nlm_args),
64849d99608SChuck Lever 		.pc_ressize = sizeof(struct nlm_void),
64949d99608SChuck Lever 		.pc_xdrressize = St,
6502289e87bSChuck Lever 		.pc_name = "GRANTED_MSG",
65149d99608SChuck Lever 	},
65249d99608SChuck Lever 	[NLMPROC_TEST_RES] = {
65349d99608SChuck Lever 		.pc_func = nlmsvc_proc_null,
65449d99608SChuck Lever 		.pc_decode = nlmsvc_decode_void,
65549d99608SChuck Lever 		.pc_encode = nlmsvc_encode_void,
65649d99608SChuck Lever 		.pc_argsize = sizeof(struct nlm_res),
65749d99608SChuck Lever 		.pc_ressize = sizeof(struct nlm_void),
65849d99608SChuck Lever 		.pc_xdrressize = St,
6592289e87bSChuck Lever 		.pc_name = "TEST_RES",
66049d99608SChuck Lever 	},
66149d99608SChuck Lever 	[NLMPROC_LOCK_RES] = {
66249d99608SChuck Lever 		.pc_func = nlmsvc_proc_null,
66349d99608SChuck Lever 		.pc_decode = nlmsvc_decode_void,
66449d99608SChuck Lever 		.pc_encode = nlmsvc_encode_void,
66549d99608SChuck Lever 		.pc_argsize = sizeof(struct nlm_res),
66649d99608SChuck Lever 		.pc_ressize = sizeof(struct nlm_void),
66749d99608SChuck Lever 		.pc_xdrressize = St,
6682289e87bSChuck Lever 		.pc_name = "LOCK_RES",
66949d99608SChuck Lever 	},
67049d99608SChuck Lever 	[NLMPROC_CANCEL_RES] = {
67149d99608SChuck Lever 		.pc_func = nlmsvc_proc_null,
67249d99608SChuck Lever 		.pc_decode = nlmsvc_decode_void,
67349d99608SChuck Lever 		.pc_encode = nlmsvc_encode_void,
67449d99608SChuck Lever 		.pc_argsize = sizeof(struct nlm_res),
67549d99608SChuck Lever 		.pc_ressize = sizeof(struct nlm_void),
67649d99608SChuck Lever 		.pc_xdrressize = St,
6772289e87bSChuck Lever 		.pc_name = "CANCEL_RES",
67849d99608SChuck Lever 	},
67949d99608SChuck Lever 	[NLMPROC_UNLOCK_RES] = {
68049d99608SChuck Lever 		.pc_func = nlmsvc_proc_null,
68149d99608SChuck Lever 		.pc_decode = nlmsvc_decode_void,
68249d99608SChuck Lever 		.pc_encode = nlmsvc_encode_void,
68349d99608SChuck Lever 		.pc_argsize = sizeof(struct nlm_res),
68449d99608SChuck Lever 		.pc_ressize = sizeof(struct nlm_void),
68549d99608SChuck Lever 		.pc_xdrressize = St,
6862289e87bSChuck Lever 		.pc_name = "UNLOCK_RES",
68749d99608SChuck Lever 	},
68849d99608SChuck Lever 	[NLMPROC_GRANTED_RES] = {
68949d99608SChuck Lever 		.pc_func = nlmsvc_proc_granted_res,
69049d99608SChuck Lever 		.pc_decode = nlmsvc_decode_res,
69149d99608SChuck Lever 		.pc_encode = nlmsvc_encode_void,
69249d99608SChuck Lever 		.pc_argsize = sizeof(struct nlm_res),
69349d99608SChuck Lever 		.pc_ressize = sizeof(struct nlm_void),
69449d99608SChuck Lever 		.pc_xdrressize = St,
6952289e87bSChuck Lever 		.pc_name = "GRANTED_RES",
69649d99608SChuck Lever 	},
69749d99608SChuck Lever 	[NLMPROC_NSM_NOTIFY] = {
69849d99608SChuck Lever 		.pc_func = nlmsvc_proc_sm_notify,
69949d99608SChuck Lever 		.pc_decode = nlmsvc_decode_reboot,
70049d99608SChuck Lever 		.pc_encode = nlmsvc_encode_void,
70149d99608SChuck Lever 		.pc_argsize = sizeof(struct nlm_reboot),
70249d99608SChuck Lever 		.pc_ressize = sizeof(struct nlm_void),
70349d99608SChuck Lever 		.pc_xdrressize = St,
7042289e87bSChuck Lever 		.pc_name = "SM_NOTIFY",
70549d99608SChuck Lever 	},
70649d99608SChuck Lever 	[17] = {
70749d99608SChuck Lever 		.pc_func = nlmsvc_proc_unused,
70849d99608SChuck Lever 		.pc_decode = nlmsvc_decode_void,
70949d99608SChuck Lever 		.pc_encode = nlmsvc_encode_void,
71049d99608SChuck Lever 		.pc_argsize = sizeof(struct nlm_void),
71149d99608SChuck Lever 		.pc_ressize = sizeof(struct nlm_void),
71249d99608SChuck Lever 		.pc_xdrressize = St,
7132289e87bSChuck Lever 		.pc_name = "UNUSED",
71449d99608SChuck Lever 	},
71549d99608SChuck Lever 	[18] = {
71649d99608SChuck Lever 		.pc_func = nlmsvc_proc_unused,
71749d99608SChuck Lever 		.pc_decode = nlmsvc_decode_void,
71849d99608SChuck Lever 		.pc_encode = nlmsvc_encode_void,
71949d99608SChuck Lever 		.pc_argsize = sizeof(struct nlm_void),
72049d99608SChuck Lever 		.pc_ressize = sizeof(struct nlm_void),
72149d99608SChuck Lever 		.pc_xdrressize = St,
7222289e87bSChuck Lever 		.pc_name = "UNUSED",
72349d99608SChuck Lever 	},
72449d99608SChuck Lever 	[19] = {
72549d99608SChuck Lever 		.pc_func = nlmsvc_proc_unused,
72649d99608SChuck Lever 		.pc_decode = nlmsvc_decode_void,
72749d99608SChuck Lever 		.pc_encode = nlmsvc_encode_void,
72849d99608SChuck Lever 		.pc_argsize = sizeof(struct nlm_void),
72949d99608SChuck Lever 		.pc_ressize = sizeof(struct nlm_void),
73049d99608SChuck Lever 		.pc_xdrressize = St,
7312289e87bSChuck Lever 		.pc_name = "UNUSED",
73249d99608SChuck Lever 	},
73349d99608SChuck Lever 	[NLMPROC_SHARE] = {
73449d99608SChuck Lever 		.pc_func = nlmsvc_proc_share,
73549d99608SChuck Lever 		.pc_decode = nlmsvc_decode_shareargs,
73649d99608SChuck Lever 		.pc_encode = nlmsvc_encode_shareres,
73749d99608SChuck Lever 		.pc_argsize = sizeof(struct nlm_args),
73849d99608SChuck Lever 		.pc_ressize = sizeof(struct nlm_res),
73949d99608SChuck Lever 		.pc_xdrressize = Ck+St+1,
7402289e87bSChuck Lever 		.pc_name = "SHARE",
74149d99608SChuck Lever 	},
74249d99608SChuck Lever 	[NLMPROC_UNSHARE] = {
74349d99608SChuck Lever 		.pc_func = nlmsvc_proc_unshare,
74449d99608SChuck Lever 		.pc_decode = nlmsvc_decode_shareargs,
74549d99608SChuck Lever 		.pc_encode = nlmsvc_encode_shareres,
74649d99608SChuck Lever 		.pc_argsize = sizeof(struct nlm_args),
74749d99608SChuck Lever 		.pc_ressize = sizeof(struct nlm_res),
74849d99608SChuck Lever 		.pc_xdrressize = Ck+St+1,
7492289e87bSChuck Lever 		.pc_name = "UNSHARE",
75049d99608SChuck Lever 	},
75149d99608SChuck Lever 	[NLMPROC_NM_LOCK] = {
75249d99608SChuck Lever 		.pc_func = nlmsvc_proc_nm_lock,
75349d99608SChuck Lever 		.pc_decode = nlmsvc_decode_lockargs,
75449d99608SChuck Lever 		.pc_encode = nlmsvc_encode_res,
75549d99608SChuck Lever 		.pc_argsize = sizeof(struct nlm_args),
75649d99608SChuck Lever 		.pc_ressize = sizeof(struct nlm_res),
75749d99608SChuck Lever 		.pc_xdrressize = Ck+St,
7582289e87bSChuck Lever 		.pc_name = "NM_LOCK",
75949d99608SChuck Lever 	},
76049d99608SChuck Lever 	[NLMPROC_FREE_ALL] = {
76149d99608SChuck Lever 		.pc_func = nlmsvc_proc_free_all,
76249d99608SChuck Lever 		.pc_decode = nlmsvc_decode_notify,
76349d99608SChuck Lever 		.pc_encode = nlmsvc_encode_void,
76449d99608SChuck Lever 		.pc_argsize = sizeof(struct nlm_args),
76549d99608SChuck Lever 		.pc_ressize = sizeof(struct nlm_void),
76649d99608SChuck Lever 		.pc_xdrressize = 0,
7672289e87bSChuck Lever 		.pc_name = "FREE_ALL",
76849d99608SChuck Lever 	},
7691da177e4SLinus Torvalds };
770