xref: /openbmc/linux/fs/lockd/svcproc.c (revision 49d99608213b60dec319400edf997e0fe0567cdf)
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;
5852921e02SAl Viro 	__be32			error = 0;
591da177e4SLinus Torvalds 
601da177e4SLinus Torvalds 	/* nfsd callbacks must have been installed for this procedure */
611da177e4SLinus Torvalds 	if (!nlmsvc_ops)
621da177e4SLinus Torvalds 		return nlm_lck_denied_nolocks;
631da177e4SLinus Torvalds 
641da177e4SLinus Torvalds 	/* Obtain host handle */
65db4e4c9aSOlaf Kirch 	if (!(host = nlmsvc_lookup_host(rqstp, lock->caller, lock->len))
66977faf39SOlaf Kirch 	 || (argp->monitor && nsm_monitor(host) < 0))
671da177e4SLinus Torvalds 		goto no_locks;
681da177e4SLinus Torvalds 	*hostp = host;
691da177e4SLinus Torvalds 
701da177e4SLinus Torvalds 	/* Obtain file pointer. Not used by FREE_ALL call. */
711da177e4SLinus Torvalds 	if (filp != NULL) {
72cd0b16c1STrond Myklebust 		error = cast_status(nlm_lookup_file(rqstp, &file, &lock->fh));
73cd0b16c1STrond Myklebust 		if (error != 0)
741da177e4SLinus Torvalds 			goto no_locks;
751da177e4SLinus Torvalds 		*filp = file;
761da177e4SLinus Torvalds 
771da177e4SLinus Torvalds 		/* Set up the missing parts of the file_lock structure */
781da177e4SLinus Torvalds 		lock->fl.fl_file  = file->f_file;
79646d73e9SBenjamin Coddington 		lock->fl.fl_pid = current->tgid;
801da177e4SLinus Torvalds 		lock->fl.fl_lmops = &nlmsvc_lock_operations;
8189e0edfbSBenjamin Coddington 		nlmsvc_locks_init_private(&lock->fl, host, (pid_t)lock->svid);
8289e0edfbSBenjamin Coddington 		if (!lock->fl.fl_owner) {
8389e0edfbSBenjamin Coddington 			/* lockowner allocation has failed */
8489e0edfbSBenjamin Coddington 			nlmsvc_release_host(host);
8589e0edfbSBenjamin Coddington 			return nlm_lck_denied_nolocks;
8689e0edfbSBenjamin Coddington 		}
871da177e4SLinus Torvalds 	}
881da177e4SLinus Torvalds 
891da177e4SLinus Torvalds 	return 0;
901da177e4SLinus Torvalds 
911da177e4SLinus Torvalds no_locks:
9267216b94SChuck Lever 	nlmsvc_release_host(host);
93d343fce1SNeilBrown 	if (error)
94d343fce1SNeilBrown 		return error;
951da177e4SLinus Torvalds 	return nlm_lck_denied_nolocks;
961da177e4SLinus Torvalds }
971da177e4SLinus Torvalds 
981da177e4SLinus Torvalds /*
991da177e4SLinus Torvalds  * NULL: Test for presence of service
1001da177e4SLinus Torvalds  */
1017111c66eSAl Viro static __be32
102a6beb732SChristoph Hellwig nlmsvc_proc_null(struct svc_rqst *rqstp)
1031da177e4SLinus Torvalds {
1041da177e4SLinus Torvalds 	dprintk("lockd: NULL          called\n");
1051da177e4SLinus Torvalds 	return rpc_success;
1061da177e4SLinus Torvalds }
1071da177e4SLinus Torvalds 
1081da177e4SLinus Torvalds /*
1091da177e4SLinus Torvalds  * TEST: Check for conflicting lock
1101da177e4SLinus Torvalds  */
1117111c66eSAl Viro static __be32
112a6beb732SChristoph Hellwig __nlmsvc_proc_test(struct svc_rqst *rqstp, struct nlm_res *resp)
1131da177e4SLinus Torvalds {
114a6beb732SChristoph Hellwig 	struct nlm_args *argp = rqstp->rq_argp;
1151da177e4SLinus Torvalds 	struct nlm_host	*host;
1161da177e4SLinus Torvalds 	struct nlm_file	*file;
117317602f3SHarvey Harrison 	__be32 rc = rpc_success;
1181da177e4SLinus Torvalds 
1191da177e4SLinus Torvalds 	dprintk("lockd: TEST          called\n");
1201da177e4SLinus Torvalds 	resp->cookie = argp->cookie;
1211da177e4SLinus Torvalds 
1221da177e4SLinus Torvalds 	/* Obtain client and file */
1231da177e4SLinus Torvalds 	if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, &host, &file)))
124d343fce1SNeilBrown 		return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success;
1251da177e4SLinus Torvalds 
1261da177e4SLinus Torvalds 	/* Now check for conflicting locks */
1278f920d5eSJeff Layton 	resp->status = cast_status(nlmsvc_testlock(rqstp, file, host, &argp->lock, &resp->lock, &resp->cookie));
1285ea0d750SMarc Eshel 	if (resp->status == nlm_drop_reply)
129b7e6b869SOleg Drokin 		rc = rpc_drop_reply;
130b7e6b869SOleg Drokin 	else
1311da177e4SLinus Torvalds 		dprintk("lockd: TEST          status %d vers %d\n",
1321da177e4SLinus Torvalds 			ntohl(resp->status), rqstp->rq_vers);
133b7e6b869SOleg Drokin 
13489e0edfbSBenjamin Coddington 	nlmsvc_release_lockowner(&argp->lock);
13567216b94SChuck Lever 	nlmsvc_release_host(host);
1361da177e4SLinus Torvalds 	nlm_release_file(file);
137b7e6b869SOleg Drokin 	return rc;
1381da177e4SLinus Torvalds }
1391da177e4SLinus Torvalds 
1407111c66eSAl Viro static __be32
141a6beb732SChristoph Hellwig nlmsvc_proc_test(struct svc_rqst *rqstp)
1421da177e4SLinus Torvalds {
143a6beb732SChristoph Hellwig 	return __nlmsvc_proc_test(rqstp, rqstp->rq_resp);
144a6beb732SChristoph Hellwig }
145a6beb732SChristoph Hellwig 
146a6beb732SChristoph Hellwig static __be32
147a6beb732SChristoph Hellwig __nlmsvc_proc_lock(struct svc_rqst *rqstp, struct nlm_res *resp)
148a6beb732SChristoph Hellwig {
149a6beb732SChristoph Hellwig 	struct nlm_args *argp = rqstp->rq_argp;
1501da177e4SLinus Torvalds 	struct nlm_host	*host;
1511da177e4SLinus Torvalds 	struct nlm_file	*file;
152317602f3SHarvey Harrison 	__be32 rc = rpc_success;
1531da177e4SLinus Torvalds 
1541da177e4SLinus Torvalds 	dprintk("lockd: LOCK          called\n");
1551da177e4SLinus Torvalds 
1561da177e4SLinus Torvalds 	resp->cookie = argp->cookie;
1571da177e4SLinus Torvalds 
1581da177e4SLinus Torvalds 	/* Obtain client and file */
1591da177e4SLinus Torvalds 	if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, &host, &file)))
160d343fce1SNeilBrown 		return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success;
1611da177e4SLinus Torvalds 
1621da177e4SLinus Torvalds #if 0
1631da177e4SLinus Torvalds 	/* If supplied state doesn't match current state, we assume it's
1641da177e4SLinus Torvalds 	 * an old request that time-warped somehow. Any error return would
1651da177e4SLinus Torvalds 	 * do in this case because it's irrelevant anyway.
1661da177e4SLinus Torvalds 	 *
1671da177e4SLinus Torvalds 	 * NB: We don't retrieve the remote host's state yet.
1681da177e4SLinus Torvalds 	 */
1691da177e4SLinus Torvalds 	if (host->h_nsmstate && host->h_nsmstate != argp->state) {
1701da177e4SLinus Torvalds 		resp->status = nlm_lck_denied_nolocks;
1711da177e4SLinus Torvalds 	} else
1721da177e4SLinus Torvalds #endif
1731da177e4SLinus Torvalds 
1741da177e4SLinus Torvalds 	/* Now try to lock the file */
1756cde4de8SJeff Layton 	resp->status = cast_status(nlmsvc_lock(rqstp, file, host, &argp->lock,
176b2b50289SJ. Bruce Fields 					       argp->block, &argp->cookie,
177b2b50289SJ. Bruce Fields 					       argp->reclaim));
1781a8322b2SMarc Eshel 	if (resp->status == nlm_drop_reply)
179b7e6b869SOleg Drokin 		rc = rpc_drop_reply;
180b7e6b869SOleg Drokin 	else
1811da177e4SLinus Torvalds 		dprintk("lockd: LOCK         status %d\n", ntohl(resp->status));
182b7e6b869SOleg Drokin 
18389e0edfbSBenjamin Coddington 	nlmsvc_release_lockowner(&argp->lock);
18467216b94SChuck Lever 	nlmsvc_release_host(host);
1851da177e4SLinus Torvalds 	nlm_release_file(file);
186b7e6b869SOleg Drokin 	return rc;
1871da177e4SLinus Torvalds }
1881da177e4SLinus Torvalds 
1897111c66eSAl Viro static __be32
190a6beb732SChristoph Hellwig nlmsvc_proc_lock(struct svc_rqst *rqstp)
1911da177e4SLinus Torvalds {
192a6beb732SChristoph Hellwig 	return __nlmsvc_proc_lock(rqstp, rqstp->rq_resp);
193a6beb732SChristoph Hellwig }
194a6beb732SChristoph Hellwig 
195a6beb732SChristoph Hellwig static __be32
196a6beb732SChristoph Hellwig __nlmsvc_proc_cancel(struct svc_rqst *rqstp, struct nlm_res *resp)
197a6beb732SChristoph Hellwig {
198a6beb732SChristoph Hellwig 	struct nlm_args *argp = rqstp->rq_argp;
1991da177e4SLinus Torvalds 	struct nlm_host	*host;
2001da177e4SLinus Torvalds 	struct nlm_file	*file;
2015ccb0066SStanislav Kinsbursky 	struct net *net = SVC_NET(rqstp);
2021da177e4SLinus Torvalds 
2031da177e4SLinus Torvalds 	dprintk("lockd: CANCEL        called\n");
2041da177e4SLinus Torvalds 
2051da177e4SLinus Torvalds 	resp->cookie = argp->cookie;
2061da177e4SLinus Torvalds 
2071da177e4SLinus Torvalds 	/* Don't accept requests during grace period */
2085ccb0066SStanislav Kinsbursky 	if (locks_in_grace(net)) {
2091da177e4SLinus Torvalds 		resp->status = nlm_lck_denied_grace_period;
2101da177e4SLinus Torvalds 		return rpc_success;
2111da177e4SLinus Torvalds 	}
2121da177e4SLinus Torvalds 
2131da177e4SLinus Torvalds 	/* Obtain client and file */
2141da177e4SLinus Torvalds 	if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, &host, &file)))
215d343fce1SNeilBrown 		return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success;
2161da177e4SLinus Torvalds 
2171da177e4SLinus Torvalds 	/* Try to cancel request. */
2185ccb0066SStanislav Kinsbursky 	resp->status = cast_status(nlmsvc_cancel_blocked(net, file, &argp->lock));
2191da177e4SLinus Torvalds 
2201da177e4SLinus Torvalds 	dprintk("lockd: CANCEL        status %d\n", ntohl(resp->status));
22189e0edfbSBenjamin Coddington 	nlmsvc_release_lockowner(&argp->lock);
22267216b94SChuck Lever 	nlmsvc_release_host(host);
2231da177e4SLinus Torvalds 	nlm_release_file(file);
2241da177e4SLinus Torvalds 	return rpc_success;
2251da177e4SLinus Torvalds }
2261da177e4SLinus Torvalds 
227a6beb732SChristoph Hellwig static __be32
228a6beb732SChristoph Hellwig nlmsvc_proc_cancel(struct svc_rqst *rqstp)
229a6beb732SChristoph Hellwig {
230a6beb732SChristoph Hellwig 	return __nlmsvc_proc_cancel(rqstp, rqstp->rq_resp);
231a6beb732SChristoph Hellwig }
232a6beb732SChristoph Hellwig 
2331da177e4SLinus Torvalds /*
2341da177e4SLinus Torvalds  * UNLOCK: release a lock
2351da177e4SLinus Torvalds  */
2367111c66eSAl Viro static __be32
237a6beb732SChristoph Hellwig __nlmsvc_proc_unlock(struct svc_rqst *rqstp, struct nlm_res *resp)
2381da177e4SLinus Torvalds {
239a6beb732SChristoph Hellwig 	struct nlm_args *argp = rqstp->rq_argp;
2401da177e4SLinus Torvalds 	struct nlm_host	*host;
2411da177e4SLinus Torvalds 	struct nlm_file	*file;
2425ccb0066SStanislav Kinsbursky 	struct net *net = SVC_NET(rqstp);
2431da177e4SLinus Torvalds 
2441da177e4SLinus Torvalds 	dprintk("lockd: UNLOCK        called\n");
2451da177e4SLinus Torvalds 
2461da177e4SLinus Torvalds 	resp->cookie = argp->cookie;
2471da177e4SLinus Torvalds 
2481da177e4SLinus Torvalds 	/* Don't accept new lock requests during grace period */
2495ccb0066SStanislav Kinsbursky 	if (locks_in_grace(net)) {
2501da177e4SLinus Torvalds 		resp->status = nlm_lck_denied_grace_period;
2511da177e4SLinus Torvalds 		return rpc_success;
2521da177e4SLinus Torvalds 	}
2531da177e4SLinus Torvalds 
2541da177e4SLinus Torvalds 	/* Obtain client and file */
2551da177e4SLinus Torvalds 	if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, &host, &file)))
256d343fce1SNeilBrown 		return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success;
2571da177e4SLinus Torvalds 
2581da177e4SLinus Torvalds 	/* Now try to remove the lock */
2595ccb0066SStanislav Kinsbursky 	resp->status = cast_status(nlmsvc_unlock(net, file, &argp->lock));
2601da177e4SLinus Torvalds 
2611da177e4SLinus Torvalds 	dprintk("lockd: UNLOCK        status %d\n", ntohl(resp->status));
26289e0edfbSBenjamin Coddington 	nlmsvc_release_lockowner(&argp->lock);
26367216b94SChuck Lever 	nlmsvc_release_host(host);
2641da177e4SLinus Torvalds 	nlm_release_file(file);
2651da177e4SLinus Torvalds 	return rpc_success;
2661da177e4SLinus Torvalds }
2671da177e4SLinus Torvalds 
268a6beb732SChristoph Hellwig static __be32
269a6beb732SChristoph Hellwig nlmsvc_proc_unlock(struct svc_rqst *rqstp)
270a6beb732SChristoph Hellwig {
271a6beb732SChristoph Hellwig 	return __nlmsvc_proc_unlock(rqstp, rqstp->rq_resp);
272a6beb732SChristoph Hellwig }
273a6beb732SChristoph Hellwig 
2741da177e4SLinus Torvalds /*
2751da177e4SLinus Torvalds  * GRANTED: A server calls us to tell that a process' lock request
2761da177e4SLinus Torvalds  * was granted
2771da177e4SLinus Torvalds  */
2787111c66eSAl Viro static __be32
279a6beb732SChristoph Hellwig __nlmsvc_proc_granted(struct svc_rqst *rqstp, struct nlm_res *resp)
2801da177e4SLinus Torvalds {
281a6beb732SChristoph Hellwig 	struct nlm_args *argp = rqstp->rq_argp;
282a6beb732SChristoph Hellwig 
2831da177e4SLinus Torvalds 	resp->cookie = argp->cookie;
2841da177e4SLinus Torvalds 
2851da177e4SLinus Torvalds 	dprintk("lockd: GRANTED       called\n");
286dcff09f1SChuck Lever 	resp->status = nlmclnt_grant(svc_addr(rqstp), &argp->lock);
2871da177e4SLinus Torvalds 	dprintk("lockd: GRANTED       status %d\n", ntohl(resp->status));
2881da177e4SLinus Torvalds 	return rpc_success;
2891da177e4SLinus Torvalds }
2901da177e4SLinus Torvalds 
291a6beb732SChristoph Hellwig static __be32
292a6beb732SChristoph Hellwig nlmsvc_proc_granted(struct svc_rqst *rqstp)
293a6beb732SChristoph Hellwig {
294a6beb732SChristoph Hellwig 	return __nlmsvc_proc_granted(rqstp, rqstp->rq_resp);
295a6beb732SChristoph Hellwig }
296a6beb732SChristoph Hellwig 
2971da177e4SLinus Torvalds /*
298d4716624STrond Myklebust  * This is the generic lockd callback for async RPC calls
299d4716624STrond Myklebust  */
300d4716624STrond Myklebust static void nlmsvc_callback_exit(struct rpc_task *task, void *data)
301d4716624STrond Myklebust {
302c041b5ffSChuck Lever 	dprintk("lockd: %5u callback returned %d\n", task->tk_pid,
303d4716624STrond Myklebust 			-task->tk_status);
304d4716624STrond Myklebust }
305d4716624STrond Myklebust 
3067db836d4SChuck Lever void nlmsvc_release_call(struct nlm_rqst *call)
3077db836d4SChuck Lever {
308fbca30c5SElena Reshetova 	if (!refcount_dec_and_test(&call->a_count))
3097db836d4SChuck Lever 		return;
31067216b94SChuck Lever 	nlmsvc_release_host(call->a_host);
3117db836d4SChuck Lever 	kfree(call);
3127db836d4SChuck Lever }
3137db836d4SChuck Lever 
314d4716624STrond Myklebust static void nlmsvc_callback_release(void *data)
315d4716624STrond Myklebust {
3167db836d4SChuck Lever 	nlmsvc_release_call(data);
317d4716624STrond Myklebust }
318d4716624STrond Myklebust 
319d4716624STrond Myklebust static const struct rpc_call_ops nlmsvc_callback_ops = {
320d4716624STrond Myklebust 	.rpc_call_done = nlmsvc_callback_exit,
321d4716624STrond Myklebust 	.rpc_release = nlmsvc_callback_release,
322d4716624STrond Myklebust };
323d4716624STrond Myklebust 
324d4716624STrond Myklebust /*
3251da177e4SLinus Torvalds  * `Async' versions of the above service routines. They aren't really,
3261da177e4SLinus Torvalds  * because we send the callback before the reply proper. I hope this
3271da177e4SLinus Torvalds  * doesn't break any clients.
3281da177e4SLinus Torvalds  */
329a6beb732SChristoph Hellwig static __be32 nlmsvc_callback(struct svc_rqst *rqstp, u32 proc,
330a6beb732SChristoph Hellwig 		__be32 (*func)(struct svc_rqst *, struct nlm_res *))
331d4716624STrond Myklebust {
332a6beb732SChristoph Hellwig 	struct nlm_args *argp = rqstp->rq_argp;
333d4716624STrond Myklebust 	struct nlm_host	*host;
334d4716624STrond Myklebust 	struct nlm_rqst	*call;
3357111c66eSAl Viro 	__be32 stat;
336d4716624STrond Myklebust 
337db4e4c9aSOlaf Kirch 	host = nlmsvc_lookup_host(rqstp,
338db4e4c9aSOlaf Kirch 				  argp->lock.caller,
339db4e4c9aSOlaf Kirch 				  argp->lock.len);
340d4716624STrond Myklebust 	if (host == NULL)
341d4716624STrond Myklebust 		return rpc_system_err;
342d4716624STrond Myklebust 
343d4716624STrond Myklebust 	call = nlm_alloc_call(host);
344446945abSAl Viro 	nlmsvc_release_host(host);
345d4716624STrond Myklebust 	if (call == NULL)
346d4716624STrond Myklebust 		return rpc_system_err;
347d4716624STrond Myklebust 
348a6beb732SChristoph Hellwig 	stat = func(rqstp, &call->a_res);
349d4716624STrond Myklebust 	if (stat != 0) {
3507db836d4SChuck Lever 		nlmsvc_release_call(call);
351d4716624STrond Myklebust 		return stat;
352d4716624STrond Myklebust 	}
353d4716624STrond Myklebust 
354d4716624STrond Myklebust 	call->a_flags = RPC_TASK_ASYNC;
355d4716624STrond Myklebust 	if (nlm_async_reply(call, proc, &nlmsvc_callback_ops) < 0)
356d4716624STrond Myklebust 		return rpc_system_err;
357d4716624STrond Myklebust 	return rpc_success;
358d4716624STrond Myklebust }
359d4716624STrond Myklebust 
360a6beb732SChristoph Hellwig static __be32 nlmsvc_proc_test_msg(struct svc_rqst *rqstp)
3611da177e4SLinus Torvalds {
3621da177e4SLinus Torvalds 	dprintk("lockd: TEST_MSG      called\n");
363a6beb732SChristoph Hellwig 	return nlmsvc_callback(rqstp, NLMPROC_TEST_RES, __nlmsvc_proc_test);
3641da177e4SLinus Torvalds }
3651da177e4SLinus Torvalds 
366a6beb732SChristoph Hellwig static __be32 nlmsvc_proc_lock_msg(struct svc_rqst *rqstp)
3671da177e4SLinus Torvalds {
3681da177e4SLinus Torvalds 	dprintk("lockd: LOCK_MSG      called\n");
369a6beb732SChristoph Hellwig 	return nlmsvc_callback(rqstp, NLMPROC_LOCK_RES, __nlmsvc_proc_lock);
3701da177e4SLinus Torvalds }
3711da177e4SLinus Torvalds 
372a6beb732SChristoph Hellwig static __be32 nlmsvc_proc_cancel_msg(struct svc_rqst *rqstp)
3731da177e4SLinus Torvalds {
3741da177e4SLinus Torvalds 	dprintk("lockd: CANCEL_MSG    called\n");
375a6beb732SChristoph Hellwig 	return nlmsvc_callback(rqstp, NLMPROC_CANCEL_RES, __nlmsvc_proc_cancel);
3761da177e4SLinus Torvalds }
3771da177e4SLinus Torvalds 
3787111c66eSAl Viro static __be32
379a6beb732SChristoph Hellwig nlmsvc_proc_unlock_msg(struct svc_rqst *rqstp)
3801da177e4SLinus Torvalds {
3811da177e4SLinus Torvalds 	dprintk("lockd: UNLOCK_MSG    called\n");
382a6beb732SChristoph Hellwig 	return nlmsvc_callback(rqstp, NLMPROC_UNLOCK_RES, __nlmsvc_proc_unlock);
3831da177e4SLinus Torvalds }
3841da177e4SLinus Torvalds 
3857111c66eSAl Viro static __be32
386a6beb732SChristoph Hellwig nlmsvc_proc_granted_msg(struct svc_rqst *rqstp)
3871da177e4SLinus Torvalds {
3881da177e4SLinus Torvalds 	dprintk("lockd: GRANTED_MSG   called\n");
389a6beb732SChristoph Hellwig 	return nlmsvc_callback(rqstp, NLMPROC_GRANTED_RES, __nlmsvc_proc_granted);
3901da177e4SLinus Torvalds }
3911da177e4SLinus Torvalds 
3921da177e4SLinus Torvalds /*
3931da177e4SLinus Torvalds  * SHARE: create a DOS share or alter existing share.
3941da177e4SLinus Torvalds  */
3957111c66eSAl Viro static __be32
396a6beb732SChristoph Hellwig nlmsvc_proc_share(struct svc_rqst *rqstp)
3971da177e4SLinus Torvalds {
398a6beb732SChristoph Hellwig 	struct nlm_args *argp = rqstp->rq_argp;
399a6beb732SChristoph Hellwig 	struct nlm_res *resp = rqstp->rq_resp;
4001da177e4SLinus Torvalds 	struct nlm_host	*host;
4011da177e4SLinus Torvalds 	struct nlm_file	*file;
4021da177e4SLinus Torvalds 
4031da177e4SLinus Torvalds 	dprintk("lockd: SHARE         called\n");
4041da177e4SLinus Torvalds 
4051da177e4SLinus Torvalds 	resp->cookie = argp->cookie;
4061da177e4SLinus Torvalds 
4071da177e4SLinus Torvalds 	/* Don't accept new lock requests during grace period */
4085ccb0066SStanislav Kinsbursky 	if (locks_in_grace(SVC_NET(rqstp)) && !argp->reclaim) {
4091da177e4SLinus Torvalds 		resp->status = nlm_lck_denied_grace_period;
4101da177e4SLinus Torvalds 		return rpc_success;
4111da177e4SLinus Torvalds 	}
4121da177e4SLinus Torvalds 
4131da177e4SLinus Torvalds 	/* Obtain client and file */
4141da177e4SLinus Torvalds 	if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, &host, &file)))
415d343fce1SNeilBrown 		return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success;
4161da177e4SLinus Torvalds 
4171da177e4SLinus Torvalds 	/* Now try to create the share */
4181da177e4SLinus Torvalds 	resp->status = cast_status(nlmsvc_share_file(host, file, argp));
4191da177e4SLinus Torvalds 
4201da177e4SLinus Torvalds 	dprintk("lockd: SHARE         status %d\n", ntohl(resp->status));
42189e0edfbSBenjamin Coddington 	nlmsvc_release_lockowner(&argp->lock);
42267216b94SChuck Lever 	nlmsvc_release_host(host);
4231da177e4SLinus Torvalds 	nlm_release_file(file);
4241da177e4SLinus Torvalds 	return rpc_success;
4251da177e4SLinus Torvalds }
4261da177e4SLinus Torvalds 
4271da177e4SLinus Torvalds /*
4281da177e4SLinus Torvalds  * UNSHARE: Release a DOS share.
4291da177e4SLinus Torvalds  */
4307111c66eSAl Viro static __be32
431a6beb732SChristoph Hellwig nlmsvc_proc_unshare(struct svc_rqst *rqstp)
4321da177e4SLinus Torvalds {
433a6beb732SChristoph Hellwig 	struct nlm_args *argp = rqstp->rq_argp;
434a6beb732SChristoph Hellwig 	struct nlm_res *resp = rqstp->rq_resp;
4351da177e4SLinus Torvalds 	struct nlm_host	*host;
4361da177e4SLinus Torvalds 	struct nlm_file	*file;
4371da177e4SLinus Torvalds 
4381da177e4SLinus Torvalds 	dprintk("lockd: UNSHARE       called\n");
4391da177e4SLinus Torvalds 
4401da177e4SLinus Torvalds 	resp->cookie = argp->cookie;
4411da177e4SLinus Torvalds 
4421da177e4SLinus Torvalds 	/* Don't accept requests during grace period */
4435ccb0066SStanislav Kinsbursky 	if (locks_in_grace(SVC_NET(rqstp))) {
4441da177e4SLinus Torvalds 		resp->status = nlm_lck_denied_grace_period;
4451da177e4SLinus Torvalds 		return rpc_success;
4461da177e4SLinus Torvalds 	}
4471da177e4SLinus Torvalds 
4481da177e4SLinus Torvalds 	/* Obtain client and file */
4491da177e4SLinus Torvalds 	if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, &host, &file)))
450d343fce1SNeilBrown 		return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success;
4511da177e4SLinus Torvalds 
4521da177e4SLinus Torvalds 	/* Now try to unshare the file */
4531da177e4SLinus Torvalds 	resp->status = cast_status(nlmsvc_unshare_file(host, file, argp));
4541da177e4SLinus Torvalds 
4551da177e4SLinus Torvalds 	dprintk("lockd: UNSHARE       status %d\n", ntohl(resp->status));
45689e0edfbSBenjamin Coddington 	nlmsvc_release_lockowner(&argp->lock);
45767216b94SChuck Lever 	nlmsvc_release_host(host);
4581da177e4SLinus Torvalds 	nlm_release_file(file);
4591da177e4SLinus Torvalds 	return rpc_success;
4601da177e4SLinus Torvalds }
4611da177e4SLinus Torvalds 
4621da177e4SLinus Torvalds /*
4631da177e4SLinus Torvalds  * NM_LOCK: Create an unmonitored lock
4641da177e4SLinus Torvalds  */
4657111c66eSAl Viro static __be32
466a6beb732SChristoph Hellwig nlmsvc_proc_nm_lock(struct svc_rqst *rqstp)
4671da177e4SLinus Torvalds {
468a6beb732SChristoph Hellwig 	struct nlm_args *argp = rqstp->rq_argp;
469a6beb732SChristoph Hellwig 
4701da177e4SLinus Torvalds 	dprintk("lockd: NM_LOCK       called\n");
4711da177e4SLinus Torvalds 
4721da177e4SLinus Torvalds 	argp->monitor = 0;		/* just clean the monitor flag */
473a6beb732SChristoph Hellwig 	return nlmsvc_proc_lock(rqstp);
4741da177e4SLinus Torvalds }
4751da177e4SLinus Torvalds 
4761da177e4SLinus Torvalds /*
4771da177e4SLinus Torvalds  * FREE_ALL: Release all locks and shares held by client
4781da177e4SLinus Torvalds  */
4797111c66eSAl Viro static __be32
480a6beb732SChristoph Hellwig nlmsvc_proc_free_all(struct svc_rqst *rqstp)
4811da177e4SLinus Torvalds {
482a6beb732SChristoph Hellwig 	struct nlm_args *argp = rqstp->rq_argp;
4831da177e4SLinus Torvalds 	struct nlm_host	*host;
4841da177e4SLinus Torvalds 
4851da177e4SLinus Torvalds 	/* Obtain client */
4861da177e4SLinus Torvalds 	if (nlmsvc_retrieve_args(rqstp, argp, &host, NULL))
4871da177e4SLinus Torvalds 		return rpc_success;
4881da177e4SLinus Torvalds 
4891da177e4SLinus Torvalds 	nlmsvc_free_host_resources(host);
49067216b94SChuck Lever 	nlmsvc_release_host(host);
4911da177e4SLinus Torvalds 	return rpc_success;
4921da177e4SLinus Torvalds }
4931da177e4SLinus Torvalds 
4941da177e4SLinus Torvalds /*
4951da177e4SLinus Torvalds  * SM_NOTIFY: private callback from statd (not part of official NLM proto)
4961da177e4SLinus Torvalds  */
4977111c66eSAl Viro static __be32
498a6beb732SChristoph Hellwig nlmsvc_proc_sm_notify(struct svc_rqst *rqstp)
4991da177e4SLinus Torvalds {
500a6beb732SChristoph Hellwig 	struct nlm_reboot *argp = rqstp->rq_argp;
501a6beb732SChristoph Hellwig 
5021da177e4SLinus Torvalds 	dprintk("lockd: SM_NOTIFY     called\n");
503b85e4676SChuck Lever 
504b85e4676SChuck Lever 	if (!nlm_privileged_requester(rqstp)) {
505ad06e4bdSChuck Lever 		char buf[RPC_MAX_ADDRBUFLEN];
506ad06e4bdSChuck Lever 		printk(KERN_WARNING "lockd: rejected NSM callback from %s\n",
507ad06e4bdSChuck Lever 				svc_print_addr(rqstp, buf, sizeof(buf)));
5081da177e4SLinus Torvalds 		return rpc_system_err;
5091da177e4SLinus Torvalds 	}
5101da177e4SLinus Torvalds 
5110ad95472SAndrey Ryabinin 	nlm_host_rebooted(SVC_NET(rqstp), argp);
5121da177e4SLinus Torvalds 	return rpc_success;
5131da177e4SLinus Torvalds }
5141da177e4SLinus Torvalds 
5151da177e4SLinus Torvalds /*
5161da177e4SLinus Torvalds  * client sent a GRANTED_RES, let's remove the associated block
5171da177e4SLinus Torvalds  */
5187111c66eSAl Viro static __be32
519a6beb732SChristoph Hellwig nlmsvc_proc_granted_res(struct svc_rqst *rqstp)
5201da177e4SLinus Torvalds {
521a6beb732SChristoph Hellwig 	struct nlm_res *argp = rqstp->rq_argp;
522a6beb732SChristoph Hellwig 
5231da177e4SLinus Torvalds 	if (!nlmsvc_ops)
5241da177e4SLinus Torvalds 		return rpc_success;
5251da177e4SLinus Torvalds 
5261da177e4SLinus Torvalds 	dprintk("lockd: GRANTED_RES   called\n");
5271da177e4SLinus Torvalds 
52839be4502SOlaf Kirch 	nlmsvc_grant_reply(&argp->cookie, argp->status);
5291da177e4SLinus Torvalds 	return rpc_success;
5301da177e4SLinus Torvalds }
5311da177e4SLinus Torvalds 
532*49d99608SChuck Lever static __be32
533*49d99608SChuck Lever nlmsvc_proc_unused(struct svc_rqst *rqstp)
534*49d99608SChuck Lever {
535*49d99608SChuck Lever 	return rpc_proc_unavail;
536*49d99608SChuck Lever }
537*49d99608SChuck Lever 
5381da177e4SLinus Torvalds /*
5391da177e4SLinus Torvalds  * NLM Server procedures.
5401da177e4SLinus Torvalds  */
5411da177e4SLinus Torvalds 
5421da177e4SLinus Torvalds struct nlm_void			{ int dummy; };
5431da177e4SLinus Torvalds 
5441da177e4SLinus Torvalds #define	Ck	(1+XDR_QUADLEN(NLM_MAXCOOKIELEN))	/* cookie */
5451da177e4SLinus Torvalds #define	St	1				/* status */
5461da177e4SLinus Torvalds #define	No	(1+1024/4)			/* Net Obj */
5471da177e4SLinus Torvalds #define	Rg	2				/* range - offset + size */
5481da177e4SLinus Torvalds 
549*49d99608SChuck Lever const struct svc_procedure nlmsvc_procedures[24] = {
550*49d99608SChuck Lever 	[NLMPROC_NULL] = {
551*49d99608SChuck Lever 		.pc_func = nlmsvc_proc_null,
552*49d99608SChuck Lever 		.pc_decode = nlmsvc_decode_void,
553*49d99608SChuck Lever 		.pc_encode = nlmsvc_encode_void,
554*49d99608SChuck Lever 		.pc_argsize = sizeof(struct nlm_void),
555*49d99608SChuck Lever 		.pc_ressize = sizeof(struct nlm_void),
556*49d99608SChuck Lever 		.pc_xdrressize = St,
557*49d99608SChuck Lever 	},
558*49d99608SChuck Lever 	[NLMPROC_TEST] = {
559*49d99608SChuck Lever 		.pc_func = nlmsvc_proc_test,
560*49d99608SChuck Lever 		.pc_decode = nlmsvc_decode_testargs,
561*49d99608SChuck Lever 		.pc_encode = nlmsvc_encode_testres,
562*49d99608SChuck Lever 		.pc_argsize = sizeof(struct nlm_args),
563*49d99608SChuck Lever 		.pc_ressize = sizeof(struct nlm_res),
564*49d99608SChuck Lever 		.pc_xdrressize = Ck+St+2+No+Rg,
565*49d99608SChuck Lever 	},
566*49d99608SChuck Lever 	[NLMPROC_LOCK] = {
567*49d99608SChuck Lever 		.pc_func = nlmsvc_proc_lock,
568*49d99608SChuck Lever 		.pc_decode = nlmsvc_decode_lockargs,
569*49d99608SChuck Lever 		.pc_encode = nlmsvc_encode_res,
570*49d99608SChuck Lever 		.pc_argsize = sizeof(struct nlm_args),
571*49d99608SChuck Lever 		.pc_ressize = sizeof(struct nlm_res),
572*49d99608SChuck Lever 		.pc_xdrressize = Ck+St,
573*49d99608SChuck Lever 	},
574*49d99608SChuck Lever 	[NLMPROC_CANCEL] = {
575*49d99608SChuck Lever 		.pc_func = nlmsvc_proc_cancel,
576*49d99608SChuck Lever 		.pc_decode = nlmsvc_decode_cancargs,
577*49d99608SChuck Lever 		.pc_encode = nlmsvc_encode_res,
578*49d99608SChuck Lever 		.pc_argsize = sizeof(struct nlm_args),
579*49d99608SChuck Lever 		.pc_ressize = sizeof(struct nlm_res),
580*49d99608SChuck Lever 		.pc_xdrressize = Ck+St,
581*49d99608SChuck Lever 	},
582*49d99608SChuck Lever 	[NLMPROC_UNLOCK] = {
583*49d99608SChuck Lever 		.pc_func = nlmsvc_proc_unlock,
584*49d99608SChuck Lever 		.pc_decode = nlmsvc_decode_unlockargs,
585*49d99608SChuck Lever 		.pc_encode = nlmsvc_encode_res,
586*49d99608SChuck Lever 		.pc_argsize = sizeof(struct nlm_args),
587*49d99608SChuck Lever 		.pc_ressize = sizeof(struct nlm_res),
588*49d99608SChuck Lever 		.pc_xdrressize = Ck+St,
589*49d99608SChuck Lever 	},
590*49d99608SChuck Lever 	[NLMPROC_GRANTED] = {
591*49d99608SChuck Lever 		.pc_func = nlmsvc_proc_granted,
592*49d99608SChuck Lever 		.pc_decode = nlmsvc_decode_testargs,
593*49d99608SChuck Lever 		.pc_encode = nlmsvc_encode_res,
594*49d99608SChuck Lever 		.pc_argsize = sizeof(struct nlm_args),
595*49d99608SChuck Lever 		.pc_ressize = sizeof(struct nlm_res),
596*49d99608SChuck Lever 		.pc_xdrressize = Ck+St,
597*49d99608SChuck Lever 	},
598*49d99608SChuck Lever 	[NLMPROC_TEST_MSG] = {
599*49d99608SChuck Lever 		.pc_func = nlmsvc_proc_test_msg,
600*49d99608SChuck Lever 		.pc_decode = nlmsvc_decode_testargs,
601*49d99608SChuck Lever 		.pc_encode = nlmsvc_encode_void,
602*49d99608SChuck Lever 		.pc_argsize = sizeof(struct nlm_args),
603*49d99608SChuck Lever 		.pc_ressize = sizeof(struct nlm_void),
604*49d99608SChuck Lever 		.pc_xdrressize = St,
605*49d99608SChuck Lever 	},
606*49d99608SChuck Lever 	[NLMPROC_LOCK_MSG] = {
607*49d99608SChuck Lever 		.pc_func = nlmsvc_proc_lock_msg,
608*49d99608SChuck Lever 		.pc_decode = nlmsvc_decode_lockargs,
609*49d99608SChuck Lever 		.pc_encode = nlmsvc_encode_void,
610*49d99608SChuck Lever 		.pc_argsize = sizeof(struct nlm_args),
611*49d99608SChuck Lever 		.pc_ressize = sizeof(struct nlm_void),
612*49d99608SChuck Lever 		.pc_xdrressize = St,
613*49d99608SChuck Lever 	},
614*49d99608SChuck Lever 	[NLMPROC_CANCEL_MSG] = {
615*49d99608SChuck Lever 		.pc_func = nlmsvc_proc_cancel_msg,
616*49d99608SChuck Lever 		.pc_decode = nlmsvc_decode_cancargs,
617*49d99608SChuck Lever 		.pc_encode = nlmsvc_encode_void,
618*49d99608SChuck Lever 		.pc_argsize = sizeof(struct nlm_args),
619*49d99608SChuck Lever 		.pc_ressize = sizeof(struct nlm_void),
620*49d99608SChuck Lever 		.pc_xdrressize = St,
621*49d99608SChuck Lever 	},
622*49d99608SChuck Lever 	[NLMPROC_UNLOCK_MSG] = {
623*49d99608SChuck Lever 		.pc_func = nlmsvc_proc_unlock_msg,
624*49d99608SChuck Lever 		.pc_decode = nlmsvc_decode_unlockargs,
625*49d99608SChuck Lever 		.pc_encode = nlmsvc_encode_void,
626*49d99608SChuck Lever 		.pc_argsize = sizeof(struct nlm_args),
627*49d99608SChuck Lever 		.pc_ressize = sizeof(struct nlm_void),
628*49d99608SChuck Lever 		.pc_xdrressize = St,
629*49d99608SChuck Lever 	},
630*49d99608SChuck Lever 	[NLMPROC_GRANTED_MSG] = {
631*49d99608SChuck Lever 		.pc_func = nlmsvc_proc_granted_msg,
632*49d99608SChuck Lever 		.pc_decode = nlmsvc_decode_testargs,
633*49d99608SChuck Lever 		.pc_encode = nlmsvc_encode_void,
634*49d99608SChuck Lever 		.pc_argsize = sizeof(struct nlm_args),
635*49d99608SChuck Lever 		.pc_ressize = sizeof(struct nlm_void),
636*49d99608SChuck Lever 		.pc_xdrressize = St,
637*49d99608SChuck Lever 	},
638*49d99608SChuck Lever 	[NLMPROC_TEST_RES] = {
639*49d99608SChuck Lever 		.pc_func = nlmsvc_proc_null,
640*49d99608SChuck Lever 		.pc_decode = nlmsvc_decode_void,
641*49d99608SChuck Lever 		.pc_encode = nlmsvc_encode_void,
642*49d99608SChuck Lever 		.pc_argsize = sizeof(struct nlm_res),
643*49d99608SChuck Lever 		.pc_ressize = sizeof(struct nlm_void),
644*49d99608SChuck Lever 		.pc_xdrressize = St,
645*49d99608SChuck Lever 	},
646*49d99608SChuck Lever 	[NLMPROC_LOCK_RES] = {
647*49d99608SChuck Lever 		.pc_func = nlmsvc_proc_null,
648*49d99608SChuck Lever 		.pc_decode = nlmsvc_decode_void,
649*49d99608SChuck Lever 		.pc_encode = nlmsvc_encode_void,
650*49d99608SChuck Lever 		.pc_argsize = sizeof(struct nlm_res),
651*49d99608SChuck Lever 		.pc_ressize = sizeof(struct nlm_void),
652*49d99608SChuck Lever 		.pc_xdrressize = St,
653*49d99608SChuck Lever 	},
654*49d99608SChuck Lever 	[NLMPROC_CANCEL_RES] = {
655*49d99608SChuck Lever 		.pc_func = nlmsvc_proc_null,
656*49d99608SChuck Lever 		.pc_decode = nlmsvc_decode_void,
657*49d99608SChuck Lever 		.pc_encode = nlmsvc_encode_void,
658*49d99608SChuck Lever 		.pc_argsize = sizeof(struct nlm_res),
659*49d99608SChuck Lever 		.pc_ressize = sizeof(struct nlm_void),
660*49d99608SChuck Lever 		.pc_xdrressize = St,
661*49d99608SChuck Lever 	},
662*49d99608SChuck Lever 	[NLMPROC_UNLOCK_RES] = {
663*49d99608SChuck Lever 		.pc_func = nlmsvc_proc_null,
664*49d99608SChuck Lever 		.pc_decode = nlmsvc_decode_void,
665*49d99608SChuck Lever 		.pc_encode = nlmsvc_encode_void,
666*49d99608SChuck Lever 		.pc_argsize = sizeof(struct nlm_res),
667*49d99608SChuck Lever 		.pc_ressize = sizeof(struct nlm_void),
668*49d99608SChuck Lever 		.pc_xdrressize = St,
669*49d99608SChuck Lever 	},
670*49d99608SChuck Lever 	[NLMPROC_GRANTED_RES] = {
671*49d99608SChuck Lever 		.pc_func = nlmsvc_proc_granted_res,
672*49d99608SChuck Lever 		.pc_decode = nlmsvc_decode_res,
673*49d99608SChuck Lever 		.pc_encode = nlmsvc_encode_void,
674*49d99608SChuck Lever 		.pc_argsize = sizeof(struct nlm_res),
675*49d99608SChuck Lever 		.pc_ressize = sizeof(struct nlm_void),
676*49d99608SChuck Lever 		.pc_xdrressize = St,
677*49d99608SChuck Lever 	},
678*49d99608SChuck Lever 	[NLMPROC_NSM_NOTIFY] = {
679*49d99608SChuck Lever 		.pc_func = nlmsvc_proc_sm_notify,
680*49d99608SChuck Lever 		.pc_decode = nlmsvc_decode_reboot,
681*49d99608SChuck Lever 		.pc_encode = nlmsvc_encode_void,
682*49d99608SChuck Lever 		.pc_argsize = sizeof(struct nlm_reboot),
683*49d99608SChuck Lever 		.pc_ressize = sizeof(struct nlm_void),
684*49d99608SChuck Lever 		.pc_xdrressize = St,
685*49d99608SChuck Lever 	},
686*49d99608SChuck Lever 	[17] = {
687*49d99608SChuck Lever 		.pc_func = nlmsvc_proc_unused,
688*49d99608SChuck Lever 		.pc_decode = nlmsvc_decode_void,
689*49d99608SChuck Lever 		.pc_encode = nlmsvc_encode_void,
690*49d99608SChuck Lever 		.pc_argsize = sizeof(struct nlm_void),
691*49d99608SChuck Lever 		.pc_ressize = sizeof(struct nlm_void),
692*49d99608SChuck Lever 		.pc_xdrressize = St,
693*49d99608SChuck Lever 	},
694*49d99608SChuck Lever 	[18] = {
695*49d99608SChuck Lever 		.pc_func = nlmsvc_proc_unused,
696*49d99608SChuck Lever 		.pc_decode = nlmsvc_decode_void,
697*49d99608SChuck Lever 		.pc_encode = nlmsvc_encode_void,
698*49d99608SChuck Lever 		.pc_argsize = sizeof(struct nlm_void),
699*49d99608SChuck Lever 		.pc_ressize = sizeof(struct nlm_void),
700*49d99608SChuck Lever 		.pc_xdrressize = St,
701*49d99608SChuck Lever 	},
702*49d99608SChuck Lever 	[19] = {
703*49d99608SChuck Lever 		.pc_func = nlmsvc_proc_unused,
704*49d99608SChuck Lever 		.pc_decode = nlmsvc_decode_void,
705*49d99608SChuck Lever 		.pc_encode = nlmsvc_encode_void,
706*49d99608SChuck Lever 		.pc_argsize = sizeof(struct nlm_void),
707*49d99608SChuck Lever 		.pc_ressize = sizeof(struct nlm_void),
708*49d99608SChuck Lever 		.pc_xdrressize = St,
709*49d99608SChuck Lever 	},
710*49d99608SChuck Lever 	[NLMPROC_SHARE] = {
711*49d99608SChuck Lever 		.pc_func = nlmsvc_proc_share,
712*49d99608SChuck Lever 		.pc_decode = nlmsvc_decode_shareargs,
713*49d99608SChuck Lever 		.pc_encode = nlmsvc_encode_shareres,
714*49d99608SChuck Lever 		.pc_argsize = sizeof(struct nlm_args),
715*49d99608SChuck Lever 		.pc_ressize = sizeof(struct nlm_res),
716*49d99608SChuck Lever 		.pc_xdrressize = Ck+St+1,
717*49d99608SChuck Lever 	},
718*49d99608SChuck Lever 	[NLMPROC_UNSHARE] = {
719*49d99608SChuck Lever 		.pc_func = nlmsvc_proc_unshare,
720*49d99608SChuck Lever 		.pc_decode = nlmsvc_decode_shareargs,
721*49d99608SChuck Lever 		.pc_encode = nlmsvc_encode_shareres,
722*49d99608SChuck Lever 		.pc_argsize = sizeof(struct nlm_args),
723*49d99608SChuck Lever 		.pc_ressize = sizeof(struct nlm_res),
724*49d99608SChuck Lever 		.pc_xdrressize = Ck+St+1,
725*49d99608SChuck Lever 	},
726*49d99608SChuck Lever 	[NLMPROC_NM_LOCK] = {
727*49d99608SChuck Lever 		.pc_func = nlmsvc_proc_nm_lock,
728*49d99608SChuck Lever 		.pc_decode = nlmsvc_decode_lockargs,
729*49d99608SChuck Lever 		.pc_encode = nlmsvc_encode_res,
730*49d99608SChuck Lever 		.pc_argsize = sizeof(struct nlm_args),
731*49d99608SChuck Lever 		.pc_ressize = sizeof(struct nlm_res),
732*49d99608SChuck Lever 		.pc_xdrressize = Ck+St,
733*49d99608SChuck Lever 	},
734*49d99608SChuck Lever 	[NLMPROC_FREE_ALL] = {
735*49d99608SChuck Lever 		.pc_func = nlmsvc_proc_free_all,
736*49d99608SChuck Lever 		.pc_decode = nlmsvc_decode_notify,
737*49d99608SChuck Lever 		.pc_encode = nlmsvc_encode_void,
738*49d99608SChuck Lever 		.pc_argsize = sizeof(struct nlm_args),
739*49d99608SChuck Lever 		.pc_ressize = sizeof(struct nlm_void),
740*49d99608SChuck Lever 		.pc_xdrressize = 0,
741*49d99608SChuck Lever 	},
7421da177e4SLinus Torvalds };
743