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