xref: /openbmc/linux/fs/lockd/svc4proc.c (revision 49d99608213b60dec319400edf997e0fe0567cdf)
1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
21da177e4SLinus Torvalds /*
31da177e4SLinus Torvalds  * linux/fs/lockd/svc4proc.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 /*
201da177e4SLinus Torvalds  * Obtain client and file from arguments
211da177e4SLinus Torvalds  */
2252921e02SAl Viro static __be32
231da177e4SLinus Torvalds nlm4svc_retrieve_args(struct svc_rqst *rqstp, struct nlm_args *argp,
241da177e4SLinus Torvalds 			struct nlm_host **hostp, struct nlm_file **filp)
251da177e4SLinus Torvalds {
261da177e4SLinus Torvalds 	struct nlm_host		*host = NULL;
271da177e4SLinus Torvalds 	struct nlm_file		*file = NULL;
281da177e4SLinus Torvalds 	struct nlm_lock		*lock = &argp->lock;
2952921e02SAl Viro 	__be32			error = 0;
301da177e4SLinus Torvalds 
311da177e4SLinus Torvalds 	/* nfsd callbacks must have been installed for this procedure */
321da177e4SLinus Torvalds 	if (!nlmsvc_ops)
331da177e4SLinus Torvalds 		return nlm_lck_denied_nolocks;
341da177e4SLinus Torvalds 
351da177e4SLinus Torvalds 	/* Obtain host handle */
36db4e4c9aSOlaf Kirch 	if (!(host = nlmsvc_lookup_host(rqstp, lock->caller, lock->len))
37977faf39SOlaf Kirch 	 || (argp->monitor && nsm_monitor(host) < 0))
381da177e4SLinus Torvalds 		goto no_locks;
391da177e4SLinus Torvalds 	*hostp = host;
401da177e4SLinus Torvalds 
411da177e4SLinus Torvalds 	/* Obtain file pointer. Not used by FREE_ALL call. */
421da177e4SLinus Torvalds 	if (filp != NULL) {
431da177e4SLinus Torvalds 		if ((error = nlm_lookup_file(rqstp, &file, &lock->fh)) != 0)
441da177e4SLinus Torvalds 			goto no_locks;
451da177e4SLinus Torvalds 		*filp = file;
461da177e4SLinus Torvalds 
471da177e4SLinus Torvalds 		/* Set up the missing parts of the file_lock structure */
481da177e4SLinus Torvalds 		lock->fl.fl_file  = file->f_file;
49646d73e9SBenjamin Coddington 		lock->fl.fl_pid = current->tgid;
501da177e4SLinus Torvalds 		lock->fl.fl_lmops = &nlmsvc_lock_operations;
5189e0edfbSBenjamin Coddington 		nlmsvc_locks_init_private(&lock->fl, host, (pid_t)lock->svid);
5289e0edfbSBenjamin Coddington 		if (!lock->fl.fl_owner) {
5389e0edfbSBenjamin Coddington 			/* lockowner allocation has failed */
5489e0edfbSBenjamin Coddington 			nlmsvc_release_host(host);
5589e0edfbSBenjamin Coddington 			return nlm_lck_denied_nolocks;
5689e0edfbSBenjamin Coddington 		}
571da177e4SLinus Torvalds 	}
581da177e4SLinus Torvalds 
591da177e4SLinus Torvalds 	return 0;
601da177e4SLinus Torvalds 
611da177e4SLinus Torvalds no_locks:
6267216b94SChuck Lever 	nlmsvc_release_host(host);
631da177e4SLinus Torvalds  	if (error)
641da177e4SLinus Torvalds 		return error;
651da177e4SLinus Torvalds 	return nlm_lck_denied_nolocks;
661da177e4SLinus Torvalds }
671da177e4SLinus Torvalds 
681da177e4SLinus Torvalds /*
691da177e4SLinus Torvalds  * NULL: Test for presence of service
701da177e4SLinus Torvalds  */
717111c66eSAl Viro static __be32
72a6beb732SChristoph Hellwig nlm4svc_proc_null(struct svc_rqst *rqstp)
731da177e4SLinus Torvalds {
741da177e4SLinus Torvalds 	dprintk("lockd: NULL          called\n");
751da177e4SLinus Torvalds 	return rpc_success;
761da177e4SLinus Torvalds }
771da177e4SLinus Torvalds 
781da177e4SLinus Torvalds /*
791da177e4SLinus Torvalds  * TEST: Check for conflicting lock
801da177e4SLinus Torvalds  */
817111c66eSAl Viro static __be32
82a6beb732SChristoph Hellwig __nlm4svc_proc_test(struct svc_rqst *rqstp, struct nlm_res *resp)
831da177e4SLinus Torvalds {
84a6beb732SChristoph Hellwig 	struct nlm_args *argp = rqstp->rq_argp;
851da177e4SLinus Torvalds 	struct nlm_host	*host;
861da177e4SLinus Torvalds 	struct nlm_file	*file;
87317602f3SHarvey Harrison 	__be32 rc = rpc_success;
881da177e4SLinus Torvalds 
891da177e4SLinus Torvalds 	dprintk("lockd: TEST4        called\n");
901da177e4SLinus Torvalds 	resp->cookie = argp->cookie;
911da177e4SLinus Torvalds 
921da177e4SLinus Torvalds 	/* Obtain client and file */
931da177e4SLinus Torvalds 	if ((resp->status = nlm4svc_retrieve_args(rqstp, argp, &host, &file)))
94d343fce1SNeilBrown 		return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success;
951da177e4SLinus Torvalds 
961da177e4SLinus Torvalds 	/* Now check for conflicting locks */
978f920d5eSJeff Layton 	resp->status = nlmsvc_testlock(rqstp, file, host, &argp->lock, &resp->lock, &resp->cookie);
985ea0d750SMarc Eshel 	if (resp->status == nlm_drop_reply)
99b7e6b869SOleg Drokin 		rc = rpc_drop_reply;
100b7e6b869SOleg Drokin 	else
1011da177e4SLinus Torvalds 		dprintk("lockd: TEST4        status %d\n", ntohl(resp->status));
102b7e6b869SOleg Drokin 
10389e0edfbSBenjamin Coddington 	nlmsvc_release_lockowner(&argp->lock);
10467216b94SChuck Lever 	nlmsvc_release_host(host);
1051da177e4SLinus Torvalds 	nlm_release_file(file);
106b7e6b869SOleg Drokin 	return rc;
1071da177e4SLinus Torvalds }
1081da177e4SLinus Torvalds 
1097111c66eSAl Viro static __be32
110a6beb732SChristoph Hellwig nlm4svc_proc_test(struct svc_rqst *rqstp)
1111da177e4SLinus Torvalds {
112a6beb732SChristoph Hellwig 	return __nlm4svc_proc_test(rqstp, rqstp->rq_resp);
113a6beb732SChristoph Hellwig }
114a6beb732SChristoph Hellwig 
115a6beb732SChristoph Hellwig static __be32
116a6beb732SChristoph Hellwig __nlm4svc_proc_lock(struct svc_rqst *rqstp, struct nlm_res *resp)
117a6beb732SChristoph Hellwig {
118a6beb732SChristoph Hellwig 	struct nlm_args *argp = rqstp->rq_argp;
1191da177e4SLinus Torvalds 	struct nlm_host	*host;
1201da177e4SLinus Torvalds 	struct nlm_file	*file;
121317602f3SHarvey Harrison 	__be32 rc = rpc_success;
1221da177e4SLinus Torvalds 
1231da177e4SLinus Torvalds 	dprintk("lockd: LOCK          called\n");
1241da177e4SLinus Torvalds 
1251da177e4SLinus Torvalds 	resp->cookie = argp->cookie;
1261da177e4SLinus Torvalds 
1271da177e4SLinus Torvalds 	/* Obtain client and file */
1281da177e4SLinus Torvalds 	if ((resp->status = nlm4svc_retrieve_args(rqstp, argp, &host, &file)))
129d343fce1SNeilBrown 		return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success;
1301da177e4SLinus Torvalds 
1311da177e4SLinus Torvalds #if 0
1321da177e4SLinus Torvalds 	/* If supplied state doesn't match current state, we assume it's
1331da177e4SLinus Torvalds 	 * an old request that time-warped somehow. Any error return would
1341da177e4SLinus Torvalds 	 * do in this case because it's irrelevant anyway.
1351da177e4SLinus Torvalds 	 *
1361da177e4SLinus Torvalds 	 * NB: We don't retrieve the remote host's state yet.
1371da177e4SLinus Torvalds 	 */
1381da177e4SLinus Torvalds 	if (host->h_nsmstate && host->h_nsmstate != argp->state) {
1391da177e4SLinus Torvalds 		resp->status = nlm_lck_denied_nolocks;
1401da177e4SLinus Torvalds 	} else
1411da177e4SLinus Torvalds #endif
1421da177e4SLinus Torvalds 
1431da177e4SLinus Torvalds 	/* Now try to lock the file */
1446cde4de8SJeff Layton 	resp->status = nlmsvc_lock(rqstp, file, host, &argp->lock,
145b2b50289SJ. Bruce Fields 					argp->block, &argp->cookie,
146b2b50289SJ. Bruce Fields 					argp->reclaim);
1471a8322b2SMarc Eshel 	if (resp->status == nlm_drop_reply)
148b7e6b869SOleg Drokin 		rc = rpc_drop_reply;
149b7e6b869SOleg Drokin 	else
1501da177e4SLinus Torvalds 		dprintk("lockd: LOCK         status %d\n", ntohl(resp->status));
151b7e6b869SOleg Drokin 
15289e0edfbSBenjamin Coddington 	nlmsvc_release_lockowner(&argp->lock);
15367216b94SChuck Lever 	nlmsvc_release_host(host);
1541da177e4SLinus Torvalds 	nlm_release_file(file);
155b7e6b869SOleg Drokin 	return rc;
1561da177e4SLinus Torvalds }
1571da177e4SLinus Torvalds 
1587111c66eSAl Viro static __be32
159a6beb732SChristoph Hellwig nlm4svc_proc_lock(struct svc_rqst *rqstp)
1601da177e4SLinus Torvalds {
161a6beb732SChristoph Hellwig 	return __nlm4svc_proc_lock(rqstp, rqstp->rq_resp);
162a6beb732SChristoph Hellwig }
163a6beb732SChristoph Hellwig 
164a6beb732SChristoph Hellwig static __be32
165a6beb732SChristoph Hellwig __nlm4svc_proc_cancel(struct svc_rqst *rqstp, struct nlm_res *resp)
166a6beb732SChristoph Hellwig {
167a6beb732SChristoph Hellwig 	struct nlm_args *argp = rqstp->rq_argp;
1681da177e4SLinus Torvalds 	struct nlm_host	*host;
1691da177e4SLinus Torvalds 	struct nlm_file	*file;
1701da177e4SLinus Torvalds 
1711da177e4SLinus Torvalds 	dprintk("lockd: CANCEL        called\n");
1721da177e4SLinus Torvalds 
1731da177e4SLinus Torvalds 	resp->cookie = argp->cookie;
1741da177e4SLinus Torvalds 
1751da177e4SLinus Torvalds 	/* Don't accept requests during grace period */
1765ccb0066SStanislav Kinsbursky 	if (locks_in_grace(SVC_NET(rqstp))) {
1771da177e4SLinus Torvalds 		resp->status = nlm_lck_denied_grace_period;
1781da177e4SLinus Torvalds 		return rpc_success;
1791da177e4SLinus Torvalds 	}
1801da177e4SLinus Torvalds 
1811da177e4SLinus Torvalds 	/* Obtain client and file */
1821da177e4SLinus Torvalds 	if ((resp->status = nlm4svc_retrieve_args(rqstp, argp, &host, &file)))
183d343fce1SNeilBrown 		return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success;
1841da177e4SLinus Torvalds 
1851da177e4SLinus Torvalds 	/* Try to cancel request. */
1865ccb0066SStanislav Kinsbursky 	resp->status = nlmsvc_cancel_blocked(SVC_NET(rqstp), file, &argp->lock);
1871da177e4SLinus Torvalds 
1881da177e4SLinus Torvalds 	dprintk("lockd: CANCEL        status %d\n", ntohl(resp->status));
18989e0edfbSBenjamin Coddington 	nlmsvc_release_lockowner(&argp->lock);
19067216b94SChuck Lever 	nlmsvc_release_host(host);
1911da177e4SLinus Torvalds 	nlm_release_file(file);
1921da177e4SLinus Torvalds 	return rpc_success;
1931da177e4SLinus Torvalds }
1941da177e4SLinus Torvalds 
195a6beb732SChristoph Hellwig static __be32
196a6beb732SChristoph Hellwig nlm4svc_proc_cancel(struct svc_rqst *rqstp)
197a6beb732SChristoph Hellwig {
198a6beb732SChristoph Hellwig 	return __nlm4svc_proc_cancel(rqstp, rqstp->rq_resp);
199a6beb732SChristoph Hellwig }
200a6beb732SChristoph Hellwig 
2011da177e4SLinus Torvalds /*
2021da177e4SLinus Torvalds  * UNLOCK: release a lock
2031da177e4SLinus Torvalds  */
2047111c66eSAl Viro static __be32
205a6beb732SChristoph Hellwig __nlm4svc_proc_unlock(struct svc_rqst *rqstp, struct nlm_res *resp)
2061da177e4SLinus Torvalds {
207a6beb732SChristoph Hellwig 	struct nlm_args *argp = rqstp->rq_argp;
2081da177e4SLinus Torvalds 	struct nlm_host	*host;
2091da177e4SLinus Torvalds 	struct nlm_file	*file;
2101da177e4SLinus Torvalds 
2111da177e4SLinus Torvalds 	dprintk("lockd: UNLOCK        called\n");
2121da177e4SLinus Torvalds 
2131da177e4SLinus Torvalds 	resp->cookie = argp->cookie;
2141da177e4SLinus Torvalds 
2151da177e4SLinus Torvalds 	/* Don't accept new lock requests during grace period */
2165ccb0066SStanislav Kinsbursky 	if (locks_in_grace(SVC_NET(rqstp))) {
2171da177e4SLinus Torvalds 		resp->status = nlm_lck_denied_grace_period;
2181da177e4SLinus Torvalds 		return rpc_success;
2191da177e4SLinus Torvalds 	}
2201da177e4SLinus Torvalds 
2211da177e4SLinus Torvalds 	/* Obtain client and file */
2221da177e4SLinus Torvalds 	if ((resp->status = nlm4svc_retrieve_args(rqstp, argp, &host, &file)))
223d343fce1SNeilBrown 		return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success;
2241da177e4SLinus Torvalds 
2251da177e4SLinus Torvalds 	/* Now try to remove the lock */
2265ccb0066SStanislav Kinsbursky 	resp->status = nlmsvc_unlock(SVC_NET(rqstp), file, &argp->lock);
2271da177e4SLinus Torvalds 
2281da177e4SLinus Torvalds 	dprintk("lockd: UNLOCK        status %d\n", ntohl(resp->status));
22989e0edfbSBenjamin Coddington 	nlmsvc_release_lockowner(&argp->lock);
23067216b94SChuck Lever 	nlmsvc_release_host(host);
2311da177e4SLinus Torvalds 	nlm_release_file(file);
2321da177e4SLinus Torvalds 	return rpc_success;
2331da177e4SLinus Torvalds }
2341da177e4SLinus Torvalds 
235a6beb732SChristoph Hellwig static __be32
236a6beb732SChristoph Hellwig nlm4svc_proc_unlock(struct svc_rqst *rqstp)
237a6beb732SChristoph Hellwig {
238a6beb732SChristoph Hellwig 	return __nlm4svc_proc_unlock(rqstp, rqstp->rq_resp);
239a6beb732SChristoph Hellwig }
240a6beb732SChristoph Hellwig 
2411da177e4SLinus Torvalds /*
2421da177e4SLinus Torvalds  * GRANTED: A server calls us to tell that a process' lock request
2431da177e4SLinus Torvalds  * was granted
2441da177e4SLinus Torvalds  */
2457111c66eSAl Viro static __be32
246a6beb732SChristoph Hellwig __nlm4svc_proc_granted(struct svc_rqst *rqstp, struct nlm_res *resp)
2471da177e4SLinus Torvalds {
248a6beb732SChristoph Hellwig 	struct nlm_args *argp = rqstp->rq_argp;
249a6beb732SChristoph Hellwig 
2501da177e4SLinus Torvalds 	resp->cookie = argp->cookie;
2511da177e4SLinus Torvalds 
2521da177e4SLinus Torvalds 	dprintk("lockd: GRANTED       called\n");
253dcff09f1SChuck Lever 	resp->status = nlmclnt_grant(svc_addr(rqstp), &argp->lock);
2541da177e4SLinus Torvalds 	dprintk("lockd: GRANTED       status %d\n", ntohl(resp->status));
2551da177e4SLinus Torvalds 	return rpc_success;
2561da177e4SLinus Torvalds }
2571da177e4SLinus Torvalds 
258a6beb732SChristoph Hellwig static __be32
259a6beb732SChristoph Hellwig nlm4svc_proc_granted(struct svc_rqst *rqstp)
260a6beb732SChristoph Hellwig {
261a6beb732SChristoph Hellwig 	return __nlm4svc_proc_granted(rqstp, rqstp->rq_resp);
262a6beb732SChristoph Hellwig }
263a6beb732SChristoph Hellwig 
2641da177e4SLinus Torvalds /*
265d4716624STrond Myklebust  * This is the generic lockd callback for async RPC calls
266d4716624STrond Myklebust  */
267d4716624STrond Myklebust static void nlm4svc_callback_exit(struct rpc_task *task, void *data)
268d4716624STrond Myklebust {
269c041b5ffSChuck Lever 	dprintk("lockd: %5u callback returned %d\n", task->tk_pid,
270d4716624STrond Myklebust 			-task->tk_status);
271d4716624STrond Myklebust }
272d4716624STrond Myklebust 
273d4716624STrond Myklebust static void nlm4svc_callback_release(void *data)
274d4716624STrond Myklebust {
2757db836d4SChuck Lever 	nlmsvc_release_call(data);
276d4716624STrond Myklebust }
277d4716624STrond Myklebust 
278d4716624STrond Myklebust static const struct rpc_call_ops nlm4svc_callback_ops = {
279d4716624STrond Myklebust 	.rpc_call_done = nlm4svc_callback_exit,
280d4716624STrond Myklebust 	.rpc_release = nlm4svc_callback_release,
281d4716624STrond Myklebust };
282d4716624STrond Myklebust 
283d4716624STrond Myklebust /*
2841da177e4SLinus Torvalds  * `Async' versions of the above service routines. They aren't really,
2851da177e4SLinus Torvalds  * because we send the callback before the reply proper. I hope this
2861da177e4SLinus Torvalds  * doesn't break any clients.
2871da177e4SLinus Torvalds  */
288a6beb732SChristoph Hellwig static __be32 nlm4svc_callback(struct svc_rqst *rqstp, u32 proc,
289a6beb732SChristoph Hellwig 		__be32 (*func)(struct svc_rqst *,  struct nlm_res *))
290d4716624STrond Myklebust {
291a6beb732SChristoph Hellwig 	struct nlm_args *argp = rqstp->rq_argp;
292d4716624STrond Myklebust 	struct nlm_host	*host;
293d4716624STrond Myklebust 	struct nlm_rqst	*call;
2947111c66eSAl Viro 	__be32 stat;
295d4716624STrond Myklebust 
296db4e4c9aSOlaf Kirch 	host = nlmsvc_lookup_host(rqstp,
297db4e4c9aSOlaf Kirch 				  argp->lock.caller,
298db4e4c9aSOlaf Kirch 				  argp->lock.len);
299d4716624STrond Myklebust 	if (host == NULL)
300d4716624STrond Myklebust 		return rpc_system_err;
301d4716624STrond Myklebust 
302d4716624STrond Myklebust 	call = nlm_alloc_call(host);
303446945abSAl Viro 	nlmsvc_release_host(host);
304d4716624STrond Myklebust 	if (call == NULL)
305d4716624STrond Myklebust 		return rpc_system_err;
306d4716624STrond Myklebust 
307a6beb732SChristoph Hellwig 	stat = func(rqstp, &call->a_res);
308d4716624STrond Myklebust 	if (stat != 0) {
3097db836d4SChuck Lever 		nlmsvc_release_call(call);
310d4716624STrond Myklebust 		return stat;
311d4716624STrond Myklebust 	}
312d4716624STrond Myklebust 
313d4716624STrond Myklebust 	call->a_flags = RPC_TASK_ASYNC;
314d4716624STrond Myklebust 	if (nlm_async_reply(call, proc, &nlm4svc_callback_ops) < 0)
315d4716624STrond Myklebust 		return rpc_system_err;
316d4716624STrond Myklebust 	return rpc_success;
317d4716624STrond Myklebust }
318d4716624STrond Myklebust 
319a6beb732SChristoph Hellwig static __be32 nlm4svc_proc_test_msg(struct svc_rqst *rqstp)
3201da177e4SLinus Torvalds {
3211da177e4SLinus Torvalds 	dprintk("lockd: TEST_MSG      called\n");
322a6beb732SChristoph Hellwig 	return nlm4svc_callback(rqstp, NLMPROC_TEST_RES, __nlm4svc_proc_test);
3231da177e4SLinus Torvalds }
3241da177e4SLinus Torvalds 
325a6beb732SChristoph Hellwig static __be32 nlm4svc_proc_lock_msg(struct svc_rqst *rqstp)
3261da177e4SLinus Torvalds {
3271da177e4SLinus Torvalds 	dprintk("lockd: LOCK_MSG      called\n");
328a6beb732SChristoph Hellwig 	return nlm4svc_callback(rqstp, NLMPROC_LOCK_RES, __nlm4svc_proc_lock);
3291da177e4SLinus Torvalds }
3301da177e4SLinus Torvalds 
331a6beb732SChristoph Hellwig static __be32 nlm4svc_proc_cancel_msg(struct svc_rqst *rqstp)
3321da177e4SLinus Torvalds {
3331da177e4SLinus Torvalds 	dprintk("lockd: CANCEL_MSG    called\n");
334a6beb732SChristoph Hellwig 	return nlm4svc_callback(rqstp, NLMPROC_CANCEL_RES, __nlm4svc_proc_cancel);
3351da177e4SLinus Torvalds }
3361da177e4SLinus Torvalds 
337a6beb732SChristoph Hellwig static __be32 nlm4svc_proc_unlock_msg(struct svc_rqst *rqstp)
3381da177e4SLinus Torvalds {
3391da177e4SLinus Torvalds 	dprintk("lockd: UNLOCK_MSG    called\n");
340a6beb732SChristoph Hellwig 	return nlm4svc_callback(rqstp, NLMPROC_UNLOCK_RES, __nlm4svc_proc_unlock);
3411da177e4SLinus Torvalds }
3421da177e4SLinus Torvalds 
343a6beb732SChristoph Hellwig static __be32 nlm4svc_proc_granted_msg(struct svc_rqst *rqstp)
3441da177e4SLinus Torvalds {
3451da177e4SLinus Torvalds 	dprintk("lockd: GRANTED_MSG   called\n");
346a6beb732SChristoph Hellwig 	return nlm4svc_callback(rqstp, NLMPROC_GRANTED_RES, __nlm4svc_proc_granted);
3471da177e4SLinus Torvalds }
3481da177e4SLinus Torvalds 
3491da177e4SLinus Torvalds /*
3501da177e4SLinus Torvalds  * SHARE: create a DOS share or alter existing share.
3511da177e4SLinus Torvalds  */
3527111c66eSAl Viro static __be32
353a6beb732SChristoph Hellwig nlm4svc_proc_share(struct svc_rqst *rqstp)
3541da177e4SLinus Torvalds {
355a6beb732SChristoph Hellwig 	struct nlm_args *argp = rqstp->rq_argp;
356a6beb732SChristoph Hellwig 	struct nlm_res *resp = rqstp->rq_resp;
3571da177e4SLinus Torvalds 	struct nlm_host	*host;
3581da177e4SLinus Torvalds 	struct nlm_file	*file;
3591da177e4SLinus Torvalds 
3601da177e4SLinus Torvalds 	dprintk("lockd: SHARE         called\n");
3611da177e4SLinus Torvalds 
3621da177e4SLinus Torvalds 	resp->cookie = argp->cookie;
3631da177e4SLinus Torvalds 
3641da177e4SLinus Torvalds 	/* Don't accept new lock requests during grace period */
3655ccb0066SStanislav Kinsbursky 	if (locks_in_grace(SVC_NET(rqstp)) && !argp->reclaim) {
3661da177e4SLinus Torvalds 		resp->status = nlm_lck_denied_grace_period;
3671da177e4SLinus Torvalds 		return rpc_success;
3681da177e4SLinus Torvalds 	}
3691da177e4SLinus Torvalds 
3701da177e4SLinus Torvalds 	/* Obtain client and file */
3711da177e4SLinus Torvalds 	if ((resp->status = nlm4svc_retrieve_args(rqstp, argp, &host, &file)))
372d343fce1SNeilBrown 		return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success;
3731da177e4SLinus Torvalds 
3741da177e4SLinus Torvalds 	/* Now try to create the share */
3751da177e4SLinus Torvalds 	resp->status = nlmsvc_share_file(host, file, argp);
3761da177e4SLinus Torvalds 
3771da177e4SLinus Torvalds 	dprintk("lockd: SHARE         status %d\n", ntohl(resp->status));
37889e0edfbSBenjamin Coddington 	nlmsvc_release_lockowner(&argp->lock);
37967216b94SChuck Lever 	nlmsvc_release_host(host);
3801da177e4SLinus Torvalds 	nlm_release_file(file);
3811da177e4SLinus Torvalds 	return rpc_success;
3821da177e4SLinus Torvalds }
3831da177e4SLinus Torvalds 
3841da177e4SLinus Torvalds /*
3851da177e4SLinus Torvalds  * UNSHARE: Release a DOS share.
3861da177e4SLinus Torvalds  */
3877111c66eSAl Viro static __be32
388a6beb732SChristoph Hellwig nlm4svc_proc_unshare(struct svc_rqst *rqstp)
3891da177e4SLinus Torvalds {
390a6beb732SChristoph Hellwig 	struct nlm_args *argp = rqstp->rq_argp;
391a6beb732SChristoph Hellwig 	struct nlm_res *resp = rqstp->rq_resp;
3921da177e4SLinus Torvalds 	struct nlm_host	*host;
3931da177e4SLinus Torvalds 	struct nlm_file	*file;
3941da177e4SLinus Torvalds 
3951da177e4SLinus Torvalds 	dprintk("lockd: UNSHARE       called\n");
3961da177e4SLinus Torvalds 
3971da177e4SLinus Torvalds 	resp->cookie = argp->cookie;
3981da177e4SLinus Torvalds 
3991da177e4SLinus Torvalds 	/* Don't accept requests during grace period */
4005ccb0066SStanislav Kinsbursky 	if (locks_in_grace(SVC_NET(rqstp))) {
4011da177e4SLinus Torvalds 		resp->status = nlm_lck_denied_grace_period;
4021da177e4SLinus Torvalds 		return rpc_success;
4031da177e4SLinus Torvalds 	}
4041da177e4SLinus Torvalds 
4051da177e4SLinus Torvalds 	/* Obtain client and file */
4061da177e4SLinus Torvalds 	if ((resp->status = nlm4svc_retrieve_args(rqstp, argp, &host, &file)))
407d343fce1SNeilBrown 		return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success;
4081da177e4SLinus Torvalds 
4091da177e4SLinus Torvalds 	/* Now try to lock the file */
4101da177e4SLinus Torvalds 	resp->status = nlmsvc_unshare_file(host, file, argp);
4111da177e4SLinus Torvalds 
4121da177e4SLinus Torvalds 	dprintk("lockd: UNSHARE       status %d\n", ntohl(resp->status));
41389e0edfbSBenjamin Coddington 	nlmsvc_release_lockowner(&argp->lock);
41467216b94SChuck Lever 	nlmsvc_release_host(host);
4151da177e4SLinus Torvalds 	nlm_release_file(file);
4161da177e4SLinus Torvalds 	return rpc_success;
4171da177e4SLinus Torvalds }
4181da177e4SLinus Torvalds 
4191da177e4SLinus Torvalds /*
4201da177e4SLinus Torvalds  * NM_LOCK: Create an unmonitored lock
4211da177e4SLinus Torvalds  */
4227111c66eSAl Viro static __be32
423a6beb732SChristoph Hellwig nlm4svc_proc_nm_lock(struct svc_rqst *rqstp)
4241da177e4SLinus Torvalds {
425a6beb732SChristoph Hellwig 	struct nlm_args *argp = rqstp->rq_argp;
426a6beb732SChristoph Hellwig 
4271da177e4SLinus Torvalds 	dprintk("lockd: NM_LOCK       called\n");
4281da177e4SLinus Torvalds 
4291da177e4SLinus Torvalds 	argp->monitor = 0;		/* just clean the monitor flag */
430a6beb732SChristoph Hellwig 	return nlm4svc_proc_lock(rqstp);
4311da177e4SLinus Torvalds }
4321da177e4SLinus Torvalds 
4331da177e4SLinus Torvalds /*
4341da177e4SLinus Torvalds  * FREE_ALL: Release all locks and shares held by client
4351da177e4SLinus Torvalds  */
4367111c66eSAl Viro static __be32
437a6beb732SChristoph Hellwig nlm4svc_proc_free_all(struct svc_rqst *rqstp)
4381da177e4SLinus Torvalds {
439a6beb732SChristoph Hellwig 	struct nlm_args *argp = rqstp->rq_argp;
4401da177e4SLinus Torvalds 	struct nlm_host	*host;
4411da177e4SLinus Torvalds 
4421da177e4SLinus Torvalds 	/* Obtain client */
4431da177e4SLinus Torvalds 	if (nlm4svc_retrieve_args(rqstp, argp, &host, NULL))
4441da177e4SLinus Torvalds 		return rpc_success;
4451da177e4SLinus Torvalds 
4461da177e4SLinus Torvalds 	nlmsvc_free_host_resources(host);
44767216b94SChuck Lever 	nlmsvc_release_host(host);
4481da177e4SLinus Torvalds 	return rpc_success;
4491da177e4SLinus Torvalds }
4501da177e4SLinus Torvalds 
4511da177e4SLinus Torvalds /*
4521da177e4SLinus Torvalds  * SM_NOTIFY: private callback from statd (not part of official NLM proto)
4531da177e4SLinus Torvalds  */
4547111c66eSAl Viro static __be32
455a6beb732SChristoph Hellwig nlm4svc_proc_sm_notify(struct svc_rqst *rqstp)
4561da177e4SLinus Torvalds {
457a6beb732SChristoph Hellwig 	struct nlm_reboot *argp = rqstp->rq_argp;
458a6beb732SChristoph Hellwig 
4591da177e4SLinus Torvalds 	dprintk("lockd: SM_NOTIFY     called\n");
460b85e4676SChuck Lever 
461b85e4676SChuck Lever 	if (!nlm_privileged_requester(rqstp)) {
462ad06e4bdSChuck Lever 		char buf[RPC_MAX_ADDRBUFLEN];
463ad06e4bdSChuck Lever 		printk(KERN_WARNING "lockd: rejected NSM callback from %s\n",
464ad06e4bdSChuck Lever 				svc_print_addr(rqstp, buf, sizeof(buf)));
4651da177e4SLinus Torvalds 		return rpc_system_err;
4661da177e4SLinus Torvalds 	}
4671da177e4SLinus Torvalds 
4680ad95472SAndrey Ryabinin 	nlm_host_rebooted(SVC_NET(rqstp), argp);
4691da177e4SLinus Torvalds 	return rpc_success;
4701da177e4SLinus Torvalds }
4711da177e4SLinus Torvalds 
4721da177e4SLinus Torvalds /*
4731da177e4SLinus Torvalds  * client sent a GRANTED_RES, let's remove the associated block
4741da177e4SLinus Torvalds  */
4757111c66eSAl Viro static __be32
476a6beb732SChristoph Hellwig nlm4svc_proc_granted_res(struct svc_rqst *rqstp)
4771da177e4SLinus Torvalds {
478a6beb732SChristoph Hellwig 	struct nlm_res *argp = rqstp->rq_argp;
479a6beb732SChristoph Hellwig 
4801da177e4SLinus Torvalds         if (!nlmsvc_ops)
4811da177e4SLinus Torvalds                 return rpc_success;
4821da177e4SLinus Torvalds 
4831da177e4SLinus Torvalds         dprintk("lockd: GRANTED_RES   called\n");
4841da177e4SLinus Torvalds 
48539be4502SOlaf Kirch         nlmsvc_grant_reply(&argp->cookie, argp->status);
4861da177e4SLinus Torvalds         return rpc_success;
4871da177e4SLinus Torvalds }
4881da177e4SLinus Torvalds 
489*49d99608SChuck Lever static __be32
490*49d99608SChuck Lever nlm4svc_proc_unused(struct svc_rqst *rqstp)
491*49d99608SChuck Lever {
492*49d99608SChuck Lever 	return rpc_proc_unavail;
493*49d99608SChuck Lever }
494*49d99608SChuck Lever 
4951da177e4SLinus Torvalds 
4961da177e4SLinus Torvalds /*
4971da177e4SLinus Torvalds  * NLM Server procedures.
4981da177e4SLinus Torvalds  */
4991da177e4SLinus Torvalds 
5001da177e4SLinus Torvalds struct nlm_void			{ int dummy; };
5011da177e4SLinus Torvalds 
5021da177e4SLinus Torvalds #define	Ck	(1+XDR_QUADLEN(NLM_MAXCOOKIELEN))	/* cookie */
5031da177e4SLinus Torvalds #define	No	(1+1024/4)				/* netobj */
5041da177e4SLinus Torvalds #define	St	1					/* status */
5051da177e4SLinus Torvalds #define	Rg	4					/* range (offset + length) */
5061da177e4SLinus Torvalds 
507*49d99608SChuck Lever const struct svc_procedure nlmsvc_procedures4[24] = {
508*49d99608SChuck Lever 	[NLMPROC_NULL] = {
509*49d99608SChuck Lever 		.pc_func = nlm4svc_proc_null,
510*49d99608SChuck Lever 		.pc_decode = nlm4svc_decode_void,
511*49d99608SChuck Lever 		.pc_encode = nlm4svc_encode_void,
512*49d99608SChuck Lever 		.pc_argsize = sizeof(struct nlm_void),
513*49d99608SChuck Lever 		.pc_ressize = sizeof(struct nlm_void),
514*49d99608SChuck Lever 		.pc_xdrressize = St,
515*49d99608SChuck Lever 	},
516*49d99608SChuck Lever 	[NLMPROC_TEST] = {
517*49d99608SChuck Lever 		.pc_func = nlm4svc_proc_test,
518*49d99608SChuck Lever 		.pc_decode = nlm4svc_decode_testargs,
519*49d99608SChuck Lever 		.pc_encode = nlm4svc_encode_testres,
520*49d99608SChuck Lever 		.pc_argsize = sizeof(struct nlm_args),
521*49d99608SChuck Lever 		.pc_ressize = sizeof(struct nlm_res),
522*49d99608SChuck Lever 		.pc_xdrressize = Ck+St+2+No+Rg,
523*49d99608SChuck Lever 	},
524*49d99608SChuck Lever 	[NLMPROC_LOCK] = {
525*49d99608SChuck Lever 		.pc_func = nlm4svc_proc_lock,
526*49d99608SChuck Lever 		.pc_decode = nlm4svc_decode_lockargs,
527*49d99608SChuck Lever 		.pc_encode = nlm4svc_encode_res,
528*49d99608SChuck Lever 		.pc_argsize = sizeof(struct nlm_args),
529*49d99608SChuck Lever 		.pc_ressize = sizeof(struct nlm_res),
530*49d99608SChuck Lever 		.pc_xdrressize = Ck+St,
531*49d99608SChuck Lever 	},
532*49d99608SChuck Lever 	[NLMPROC_CANCEL] = {
533*49d99608SChuck Lever 		.pc_func = nlm4svc_proc_cancel,
534*49d99608SChuck Lever 		.pc_decode = nlm4svc_decode_cancargs,
535*49d99608SChuck Lever 		.pc_encode = nlm4svc_encode_res,
536*49d99608SChuck Lever 		.pc_argsize = sizeof(struct nlm_args),
537*49d99608SChuck Lever 		.pc_ressize = sizeof(struct nlm_res),
538*49d99608SChuck Lever 		.pc_xdrressize = Ck+St,
539*49d99608SChuck Lever 	},
540*49d99608SChuck Lever 	[NLMPROC_UNLOCK] = {
541*49d99608SChuck Lever 		.pc_func = nlm4svc_proc_unlock,
542*49d99608SChuck Lever 		.pc_decode = nlm4svc_decode_unlockargs,
543*49d99608SChuck Lever 		.pc_encode = nlm4svc_encode_res,
544*49d99608SChuck Lever 		.pc_argsize = sizeof(struct nlm_args),
545*49d99608SChuck Lever 		.pc_ressize = sizeof(struct nlm_res),
546*49d99608SChuck Lever 		.pc_xdrressize = Ck+St,
547*49d99608SChuck Lever 	},
548*49d99608SChuck Lever 	[NLMPROC_GRANTED] = {
549*49d99608SChuck Lever 		.pc_func = nlm4svc_proc_granted,
550*49d99608SChuck Lever 		.pc_decode = nlm4svc_decode_testargs,
551*49d99608SChuck Lever 		.pc_encode = nlm4svc_encode_res,
552*49d99608SChuck Lever 		.pc_argsize = sizeof(struct nlm_args),
553*49d99608SChuck Lever 		.pc_ressize = sizeof(struct nlm_res),
554*49d99608SChuck Lever 		.pc_xdrressize = Ck+St,
555*49d99608SChuck Lever 	},
556*49d99608SChuck Lever 	[NLMPROC_TEST_MSG] = {
557*49d99608SChuck Lever 		.pc_func = nlm4svc_proc_test_msg,
558*49d99608SChuck Lever 		.pc_decode = nlm4svc_decode_testargs,
559*49d99608SChuck Lever 		.pc_encode = nlm4svc_encode_void,
560*49d99608SChuck Lever 		.pc_argsize = sizeof(struct nlm_args),
561*49d99608SChuck Lever 		.pc_ressize = sizeof(struct nlm_void),
562*49d99608SChuck Lever 		.pc_xdrressize = St,
563*49d99608SChuck Lever 	},
564*49d99608SChuck Lever 	[NLMPROC_LOCK_MSG] = {
565*49d99608SChuck Lever 		.pc_func = nlm4svc_proc_lock_msg,
566*49d99608SChuck Lever 		.pc_decode = nlm4svc_decode_lockargs,
567*49d99608SChuck Lever 		.pc_encode = nlm4svc_encode_void,
568*49d99608SChuck Lever 		.pc_argsize = sizeof(struct nlm_args),
569*49d99608SChuck Lever 		.pc_ressize = sizeof(struct nlm_void),
570*49d99608SChuck Lever 		.pc_xdrressize = St,
571*49d99608SChuck Lever 	},
572*49d99608SChuck Lever 	[NLMPROC_CANCEL_MSG] = {
573*49d99608SChuck Lever 		.pc_func = nlm4svc_proc_cancel_msg,
574*49d99608SChuck Lever 		.pc_decode = nlm4svc_decode_cancargs,
575*49d99608SChuck Lever 		.pc_encode = nlm4svc_encode_void,
576*49d99608SChuck Lever 		.pc_argsize = sizeof(struct nlm_args),
577*49d99608SChuck Lever 		.pc_ressize = sizeof(struct nlm_void),
578*49d99608SChuck Lever 		.pc_xdrressize = St,
579*49d99608SChuck Lever 	},
580*49d99608SChuck Lever 	[NLMPROC_UNLOCK_MSG] = {
581*49d99608SChuck Lever 		.pc_func = nlm4svc_proc_unlock_msg,
582*49d99608SChuck Lever 		.pc_decode = nlm4svc_decode_unlockargs,
583*49d99608SChuck Lever 		.pc_encode = nlm4svc_encode_void,
584*49d99608SChuck Lever 		.pc_argsize = sizeof(struct nlm_args),
585*49d99608SChuck Lever 		.pc_ressize = sizeof(struct nlm_void),
586*49d99608SChuck Lever 		.pc_xdrressize = St,
587*49d99608SChuck Lever 	},
588*49d99608SChuck Lever 	[NLMPROC_GRANTED_MSG] = {
589*49d99608SChuck Lever 		.pc_func = nlm4svc_proc_granted_msg,
590*49d99608SChuck Lever 		.pc_decode = nlm4svc_decode_testargs,
591*49d99608SChuck Lever 		.pc_encode = nlm4svc_encode_void,
592*49d99608SChuck Lever 		.pc_argsize = sizeof(struct nlm_args),
593*49d99608SChuck Lever 		.pc_ressize = sizeof(struct nlm_void),
594*49d99608SChuck Lever 		.pc_xdrressize = St,
595*49d99608SChuck Lever 	},
596*49d99608SChuck Lever 	[NLMPROC_TEST_RES] = {
597*49d99608SChuck Lever 		.pc_func = nlm4svc_proc_null,
598*49d99608SChuck Lever 		.pc_decode = nlm4svc_decode_void,
599*49d99608SChuck Lever 		.pc_encode = nlm4svc_encode_void,
600*49d99608SChuck Lever 		.pc_argsize = sizeof(struct nlm_res),
601*49d99608SChuck Lever 		.pc_ressize = sizeof(struct nlm_void),
602*49d99608SChuck Lever 		.pc_xdrressize = St,
603*49d99608SChuck Lever 	},
604*49d99608SChuck Lever 	[NLMPROC_LOCK_RES] = {
605*49d99608SChuck Lever 		.pc_func = nlm4svc_proc_null,
606*49d99608SChuck Lever 		.pc_decode = nlm4svc_decode_void,
607*49d99608SChuck Lever 		.pc_encode = nlm4svc_encode_void,
608*49d99608SChuck Lever 		.pc_argsize = sizeof(struct nlm_res),
609*49d99608SChuck Lever 		.pc_ressize = sizeof(struct nlm_void),
610*49d99608SChuck Lever 		.pc_xdrressize = St,
611*49d99608SChuck Lever 	},
612*49d99608SChuck Lever 	[NLMPROC_CANCEL_RES] = {
613*49d99608SChuck Lever 		.pc_func = nlm4svc_proc_null,
614*49d99608SChuck Lever 		.pc_decode = nlm4svc_decode_void,
615*49d99608SChuck Lever 		.pc_encode = nlm4svc_encode_void,
616*49d99608SChuck Lever 		.pc_argsize = sizeof(struct nlm_res),
617*49d99608SChuck Lever 		.pc_ressize = sizeof(struct nlm_void),
618*49d99608SChuck Lever 		.pc_xdrressize = St,
619*49d99608SChuck Lever 	},
620*49d99608SChuck Lever 	[NLMPROC_UNLOCK_RES] = {
621*49d99608SChuck Lever 		.pc_func = nlm4svc_proc_null,
622*49d99608SChuck Lever 		.pc_decode = nlm4svc_decode_void,
623*49d99608SChuck Lever 		.pc_encode = nlm4svc_encode_void,
624*49d99608SChuck Lever 		.pc_argsize = sizeof(struct nlm_res),
625*49d99608SChuck Lever 		.pc_ressize = sizeof(struct nlm_void),
626*49d99608SChuck Lever 		.pc_xdrressize = St,
627*49d99608SChuck Lever 	},
628*49d99608SChuck Lever 	[NLMPROC_GRANTED_RES] = {
629*49d99608SChuck Lever 		.pc_func = nlm4svc_proc_granted_res,
630*49d99608SChuck Lever 		.pc_decode = nlm4svc_decode_res,
631*49d99608SChuck Lever 		.pc_encode = nlm4svc_encode_void,
632*49d99608SChuck Lever 		.pc_argsize = sizeof(struct nlm_res),
633*49d99608SChuck Lever 		.pc_ressize = sizeof(struct nlm_void),
634*49d99608SChuck Lever 		.pc_xdrressize = St,
635*49d99608SChuck Lever 	},
636*49d99608SChuck Lever 	[NLMPROC_NSM_NOTIFY] = {
637*49d99608SChuck Lever 		.pc_func = nlm4svc_proc_sm_notify,
638*49d99608SChuck Lever 		.pc_decode = nlm4svc_decode_reboot,
639*49d99608SChuck Lever 		.pc_encode = nlm4svc_encode_void,
640*49d99608SChuck Lever 		.pc_argsize = sizeof(struct nlm_reboot),
641*49d99608SChuck Lever 		.pc_ressize = sizeof(struct nlm_void),
642*49d99608SChuck Lever 		.pc_xdrressize = St,
643*49d99608SChuck Lever 	},
644*49d99608SChuck Lever 	[17] = {
645*49d99608SChuck Lever 		.pc_func = nlm4svc_proc_unused,
646*49d99608SChuck Lever 		.pc_decode = nlm4svc_decode_void,
647*49d99608SChuck Lever 		.pc_encode = nlm4svc_encode_void,
648*49d99608SChuck Lever 		.pc_argsize = sizeof(struct nlm_void),
649*49d99608SChuck Lever 		.pc_ressize = sizeof(struct nlm_void),
650*49d99608SChuck Lever 		.pc_xdrressize = 0,
651*49d99608SChuck Lever 	},
652*49d99608SChuck Lever 	[18] = {
653*49d99608SChuck Lever 		.pc_func = nlm4svc_proc_unused,
654*49d99608SChuck Lever 		.pc_decode = nlm4svc_decode_void,
655*49d99608SChuck Lever 		.pc_encode = nlm4svc_encode_void,
656*49d99608SChuck Lever 		.pc_argsize = sizeof(struct nlm_void),
657*49d99608SChuck Lever 		.pc_ressize = sizeof(struct nlm_void),
658*49d99608SChuck Lever 		.pc_xdrressize = 0,
659*49d99608SChuck Lever 	},
660*49d99608SChuck Lever 	[19] = {
661*49d99608SChuck Lever 		.pc_func = nlm4svc_proc_unused,
662*49d99608SChuck Lever 		.pc_decode = nlm4svc_decode_void,
663*49d99608SChuck Lever 		.pc_encode = nlm4svc_encode_void,
664*49d99608SChuck Lever 		.pc_argsize = sizeof(struct nlm_void),
665*49d99608SChuck Lever 		.pc_ressize = sizeof(struct nlm_void),
666*49d99608SChuck Lever 		.pc_xdrressize = 0,
667*49d99608SChuck Lever 	},
668*49d99608SChuck Lever 	[NLMPROC_SHARE] = {
669*49d99608SChuck Lever 		.pc_func = nlm4svc_proc_share,
670*49d99608SChuck Lever 		.pc_decode = nlm4svc_decode_shareargs,
671*49d99608SChuck Lever 		.pc_encode = nlm4svc_encode_shareres,
672*49d99608SChuck Lever 		.pc_argsize = sizeof(struct nlm_args),
673*49d99608SChuck Lever 		.pc_ressize = sizeof(struct nlm_res),
674*49d99608SChuck Lever 		.pc_xdrressize = Ck+St+1,
675*49d99608SChuck Lever 	},
676*49d99608SChuck Lever 	[NLMPROC_UNSHARE] = {
677*49d99608SChuck Lever 		.pc_func = nlm4svc_proc_unshare,
678*49d99608SChuck Lever 		.pc_decode = nlm4svc_decode_shareargs,
679*49d99608SChuck Lever 		.pc_encode = nlm4svc_encode_shareres,
680*49d99608SChuck Lever 		.pc_argsize = sizeof(struct nlm_args),
681*49d99608SChuck Lever 		.pc_ressize = sizeof(struct nlm_res),
682*49d99608SChuck Lever 		.pc_xdrressize = Ck+St+1,
683*49d99608SChuck Lever 	},
684*49d99608SChuck Lever 	[NLMPROC_NM_LOCK] = {
685*49d99608SChuck Lever 		.pc_func = nlm4svc_proc_nm_lock,
686*49d99608SChuck Lever 		.pc_decode = nlm4svc_decode_lockargs,
687*49d99608SChuck Lever 		.pc_encode = nlm4svc_encode_res,
688*49d99608SChuck Lever 		.pc_argsize = sizeof(struct nlm_args),
689*49d99608SChuck Lever 		.pc_ressize = sizeof(struct nlm_res),
690*49d99608SChuck Lever 		.pc_xdrressize = Ck+St,
691*49d99608SChuck Lever 	},
692*49d99608SChuck Lever 	[NLMPROC_FREE_ALL] = {
693*49d99608SChuck Lever 		.pc_func = nlm4svc_proc_free_all,
694*49d99608SChuck Lever 		.pc_decode = nlm4svc_decode_notify,
695*49d99608SChuck Lever 		.pc_encode = nlm4svc_encode_void,
696*49d99608SChuck Lever 		.pc_argsize = sizeof(struct nlm_args),
697*49d99608SChuck Lever 		.pc_ressize = sizeof(struct nlm_void),
698*49d99608SChuck Lever 		.pc_xdrressize = St,
699*49d99608SChuck Lever 	},
7001da177e4SLinus Torvalds };
701