Blame view

fs/lockd/svcproc.c 18.9 KB
b24413180   Greg Kroah-Hartman   License cleanup: ...
1
  // SPDX-License-Identifier: GPL-2.0
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2
3
4
5
6
7
8
9
  /*
   * linux/fs/lockd/svcproc.c
   *
   * Lockd server procedures. We don't implement the NLM_*_RES 
   * procedures because we don't use the async procedures.
   *
   * Copyright (C) 1996, Olaf Kirch <okir@monad.swb.de>
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
10
11
  #include <linux/types.h>
  #include <linux/time.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
12
13
  #include <linux/lockd/lockd.h>
  #include <linux/lockd/share.h>
5ccb0066f   Stanislav Kinsbursky   LockD: pass actua...
14
  #include <linux/sunrpc/svc_xprt.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
15
16
  
  #define NLMDBG_FACILITY		NLMDBG_CLIENT
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
17
  #ifdef CONFIG_LOCKD_V4
52921e02a   Al Viro   [PATCH] lockd end...
18
19
  static __be32
  cast_to_nlm(__be32 status, u32 vers)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
20
21
22
23
24
25
26
27
28
  {
  	/* Note: status is assumed to be in network byte order !!! */
  	if (vers != 4){
  		switch (status) {
  		case nlm_granted:
  		case nlm_lck_denied:
  		case nlm_lck_denied_nolocks:
  		case nlm_lck_blocked:
  		case nlm_lck_denied_grace_period:
5ea0d7503   Marc Eshel   lockd: handle tes...
29
  		case nlm_drop_reply:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
  			break;
  		case nlm4_deadlock:
  			status = nlm_lck_denied;
  			break;
  		default:
  			status = nlm_lck_denied_nolocks;
  		}
  	}
  
  	return (status);
  }
  #define	cast_status(status) (cast_to_nlm(status, rqstp->rq_vers))
  #else
  #define cast_status(status) (status)
  #endif
  
  /*
   * Obtain client and file from arguments
   */
52921e02a   Al Viro   [PATCH] lockd end...
49
  static __be32
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
50
51
52
53
54
55
  nlmsvc_retrieve_args(struct svc_rqst *rqstp, struct nlm_args *argp,
  			struct nlm_host **hostp, struct nlm_file **filp)
  {
  	struct nlm_host		*host = NULL;
  	struct nlm_file		*file = NULL;
  	struct nlm_lock		*lock = &argp->lock;
52921e02a   Al Viro   [PATCH] lockd end...
56
  	__be32			error = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
57
58
59
60
61
62
  
  	/* nfsd callbacks must have been installed for this procedure */
  	if (!nlmsvc_ops)
  		return nlm_lck_denied_nolocks;
  
  	/* Obtain host handle */
db4e4c9a9   Olaf Kirch   [PATCH] knfsd: wh...
63
  	if (!(host = nlmsvc_lookup_host(rqstp, lock->caller, lock->len))
977faf392   Olaf Kirch   [PATCH] knfsd: hi...
64
  	 || (argp->monitor && nsm_monitor(host) < 0))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
65
66
67
68
69
  		goto no_locks;
  	*hostp = host;
  
  	/* Obtain file pointer. Not used by FREE_ALL call. */
  	if (filp != NULL) {
cd0b16c1c   Trond Myklebust   NLM: nlm_lookup_f...
70
71
  		error = cast_status(nlm_lookup_file(rqstp, &file, &lock->fh));
  		if (error != 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
72
73
74
75
76
  			goto no_locks;
  		*filp = file;
  
  		/* Set up the missing parts of the file_lock structure */
  		lock->fl.fl_file  = file->f_file;
646d73e91   Benjamin Coddington   lockd: Show pid o...
77
  		lock->fl.fl_pid = current->tgid;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
78
  		lock->fl.fl_lmops = &nlmsvc_lock_operations;
89e0edfbe   Benjamin Coddington   lockd: Convert NL...
79
80
81
82
83
84
  		nlmsvc_locks_init_private(&lock->fl, host, (pid_t)lock->svid);
  		if (!lock->fl.fl_owner) {
  			/* lockowner allocation has failed */
  			nlmsvc_release_host(host);
  			return nlm_lck_denied_nolocks;
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
85
86
87
88
89
  	}
  
  	return 0;
  
  no_locks:
67216b94d   Chuck Lever   lockd: Clean up n...
90
  	nlmsvc_release_host(host);
d343fce14   NeilBrown   [PATCH] knfsd: Al...
91
92
  	if (error)
  		return error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
93
94
95
96
97
98
  	return nlm_lck_denied_nolocks;
  }
  
  /*
   * NULL: Test for presence of service
   */
7111c66e4   Al Viro   [PATCH] fix svc_p...
99
  static __be32
a6beb7327   Christoph Hellwig   sunrpc: properly ...
100
  nlmsvc_proc_null(struct svc_rqst *rqstp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
101
102
103
104
105
106
107
108
109
  {
  	dprintk("lockd: NULL          called
  ");
  	return rpc_success;
  }
  
  /*
   * TEST: Check for conflicting lock
   */
7111c66e4   Al Viro   [PATCH] fix svc_p...
110
  static __be32
a6beb7327   Christoph Hellwig   sunrpc: properly ...
111
  __nlmsvc_proc_test(struct svc_rqst *rqstp, struct nlm_res *resp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
112
  {
a6beb7327   Christoph Hellwig   sunrpc: properly ...
113
  	struct nlm_args *argp = rqstp->rq_argp;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
114
115
  	struct nlm_host	*host;
  	struct nlm_file	*file;
317602f3e   Harvey Harrison   lockd: trivial sp...
116
  	__be32 rc = rpc_success;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
117
118
119
120
  
  	dprintk("lockd: TEST          called
  ");
  	resp->cookie = argp->cookie;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
121
122
  	/* Obtain client and file */
  	if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, &host, &file)))
d343fce14   NeilBrown   [PATCH] knfsd: Al...
123
  		return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
124
125
  
  	/* Now check for conflicting locks */
8f920d5e2   Jeff Layton   lockd: eliminate ...
126
  	resp->status = cast_status(nlmsvc_testlock(rqstp, file, host, &argp->lock, &resp->lock, &resp->cookie));
5ea0d7503   Marc Eshel   lockd: handle tes...
127
  	if (resp->status == nlm_drop_reply)
b7e6b8694   Oleg Drokin   lockd: fix refere...
128
129
130
131
132
  		rc = rpc_drop_reply;
  	else
  		dprintk("lockd: TEST          status %d vers %d
  ",
  			ntohl(resp->status), rqstp->rq_vers);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
133

89e0edfbe   Benjamin Coddington   lockd: Convert NL...
134
  	nlmsvc_release_lockowner(&argp->lock);
67216b94d   Chuck Lever   lockd: Clean up n...
135
  	nlmsvc_release_host(host);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
136
  	nlm_release_file(file);
b7e6b8694   Oleg Drokin   lockd: fix refere...
137
  	return rc;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
138
  }
7111c66e4   Al Viro   [PATCH] fix svc_p...
139
  static __be32
a6beb7327   Christoph Hellwig   sunrpc: properly ...
140
  nlmsvc_proc_test(struct svc_rqst *rqstp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
141
  {
a6beb7327   Christoph Hellwig   sunrpc: properly ...
142
143
144
145
146
147
148
  	return __nlmsvc_proc_test(rqstp, rqstp->rq_resp);
  }
  
  static __be32
  __nlmsvc_proc_lock(struct svc_rqst *rqstp, struct nlm_res *resp)
  {
  	struct nlm_args *argp = rqstp->rq_argp;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
149
150
  	struct nlm_host	*host;
  	struct nlm_file	*file;
317602f3e   Harvey Harrison   lockd: trivial sp...
151
  	__be32 rc = rpc_success;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
152
153
154
155
156
  
  	dprintk("lockd: LOCK          called
  ");
  
  	resp->cookie = argp->cookie;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
157
158
  	/* Obtain client and file */
  	if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, &host, &file)))
d343fce14   NeilBrown   [PATCH] knfsd: Al...
159
  		return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
160
161
162
163
164
165
166
167
168
169
170
171
172
173
  
  #if 0
  	/* If supplied state doesn't match current state, we assume it's
  	 * an old request that time-warped somehow. Any error return would
  	 * do in this case because it's irrelevant anyway.
  	 *
  	 * NB: We don't retrieve the remote host's state yet.
  	 */
  	if (host->h_nsmstate && host->h_nsmstate != argp->state) {
  		resp->status = nlm_lck_denied_nolocks;
  	} else
  #endif
  
  	/* Now try to lock the file */
6cde4de80   Jeff Layton   lockd: eliminate ...
174
  	resp->status = cast_status(nlmsvc_lock(rqstp, file, host, &argp->lock,
b2b502890   J. Bruce Fields   lockd: move grace...
175
176
  					       argp->block, &argp->cookie,
  					       argp->reclaim));
1a8322b2b   Marc Eshel   lockd: add code t...
177
  	if (resp->status == nlm_drop_reply)
b7e6b8694   Oleg Drokin   lockd: fix refere...
178
179
180
181
  		rc = rpc_drop_reply;
  	else
  		dprintk("lockd: LOCK         status %d
  ", ntohl(resp->status));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
182

89e0edfbe   Benjamin Coddington   lockd: Convert NL...
183
  	nlmsvc_release_lockowner(&argp->lock);
67216b94d   Chuck Lever   lockd: Clean up n...
184
  	nlmsvc_release_host(host);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
185
  	nlm_release_file(file);
b7e6b8694   Oleg Drokin   lockd: fix refere...
186
  	return rc;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
187
  }
7111c66e4   Al Viro   [PATCH] fix svc_p...
188
  static __be32
a6beb7327   Christoph Hellwig   sunrpc: properly ...
189
190
191
192
193
194
195
  nlmsvc_proc_lock(struct svc_rqst *rqstp)
  {
  	return __nlmsvc_proc_lock(rqstp, rqstp->rq_resp);
  }
  
  static __be32
  __nlmsvc_proc_cancel(struct svc_rqst *rqstp, struct nlm_res *resp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
196
  {
a6beb7327   Christoph Hellwig   sunrpc: properly ...
197
  	struct nlm_args *argp = rqstp->rq_argp;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
198
199
  	struct nlm_host	*host;
  	struct nlm_file	*file;
5ccb0066f   Stanislav Kinsbursky   LockD: pass actua...
200
  	struct net *net = SVC_NET(rqstp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
201
202
203
204
205
206
207
  
  	dprintk("lockd: CANCEL        called
  ");
  
  	resp->cookie = argp->cookie;
  
  	/* Don't accept requests during grace period */
5ccb0066f   Stanislav Kinsbursky   LockD: pass actua...
208
  	if (locks_in_grace(net)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
209
210
211
212
213
214
  		resp->status = nlm_lck_denied_grace_period;
  		return rpc_success;
  	}
  
  	/* Obtain client and file */
  	if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, &host, &file)))
d343fce14   NeilBrown   [PATCH] knfsd: Al...
215
  		return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
216
217
  
  	/* Try to cancel request. */
5ccb0066f   Stanislav Kinsbursky   LockD: pass actua...
218
  	resp->status = cast_status(nlmsvc_cancel_blocked(net, file, &argp->lock));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
219
220
221
  
  	dprintk("lockd: CANCEL        status %d
  ", ntohl(resp->status));
89e0edfbe   Benjamin Coddington   lockd: Convert NL...
222
  	nlmsvc_release_lockowner(&argp->lock);
67216b94d   Chuck Lever   lockd: Clean up n...
223
  	nlmsvc_release_host(host);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
224
225
226
  	nlm_release_file(file);
  	return rpc_success;
  }
a6beb7327   Christoph Hellwig   sunrpc: properly ...
227
228
229
230
231
  static __be32
  nlmsvc_proc_cancel(struct svc_rqst *rqstp)
  {
  	return __nlmsvc_proc_cancel(rqstp, rqstp->rq_resp);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
232
233
234
  /*
   * UNLOCK: release a lock
   */
7111c66e4   Al Viro   [PATCH] fix svc_p...
235
  static __be32
a6beb7327   Christoph Hellwig   sunrpc: properly ...
236
  __nlmsvc_proc_unlock(struct svc_rqst *rqstp, struct nlm_res *resp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
237
  {
a6beb7327   Christoph Hellwig   sunrpc: properly ...
238
  	struct nlm_args *argp = rqstp->rq_argp;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
239
240
  	struct nlm_host	*host;
  	struct nlm_file	*file;
5ccb0066f   Stanislav Kinsbursky   LockD: pass actua...
241
  	struct net *net = SVC_NET(rqstp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
242
243
244
245
246
247
248
  
  	dprintk("lockd: UNLOCK        called
  ");
  
  	resp->cookie = argp->cookie;
  
  	/* Don't accept new lock requests during grace period */
5ccb0066f   Stanislav Kinsbursky   LockD: pass actua...
249
  	if (locks_in_grace(net)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
250
251
252
253
254
255
  		resp->status = nlm_lck_denied_grace_period;
  		return rpc_success;
  	}
  
  	/* Obtain client and file */
  	if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, &host, &file)))
d343fce14   NeilBrown   [PATCH] knfsd: Al...
256
  		return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
257
258
  
  	/* Now try to remove the lock */
5ccb0066f   Stanislav Kinsbursky   LockD: pass actua...
259
  	resp->status = cast_status(nlmsvc_unlock(net, file, &argp->lock));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
260
261
262
  
  	dprintk("lockd: UNLOCK        status %d
  ", ntohl(resp->status));
89e0edfbe   Benjamin Coddington   lockd: Convert NL...
263
  	nlmsvc_release_lockowner(&argp->lock);
67216b94d   Chuck Lever   lockd: Clean up n...
264
  	nlmsvc_release_host(host);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
265
266
267
  	nlm_release_file(file);
  	return rpc_success;
  }
a6beb7327   Christoph Hellwig   sunrpc: properly ...
268
269
270
271
272
  static __be32
  nlmsvc_proc_unlock(struct svc_rqst *rqstp)
  {
  	return __nlmsvc_proc_unlock(rqstp, rqstp->rq_resp);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
273
274
275
276
  /*
   * GRANTED: A server calls us to tell that a process' lock request
   * was granted
   */
7111c66e4   Al Viro   [PATCH] fix svc_p...
277
  static __be32
a6beb7327   Christoph Hellwig   sunrpc: properly ...
278
  __nlmsvc_proc_granted(struct svc_rqst *rqstp, struct nlm_res *resp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
279
  {
a6beb7327   Christoph Hellwig   sunrpc: properly ...
280
  	struct nlm_args *argp = rqstp->rq_argp;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
281
282
283
284
  	resp->cookie = argp->cookie;
  
  	dprintk("lockd: GRANTED       called
  ");
dcff09f12   Chuck Lever   lockd: change nlm...
285
  	resp->status = nlmclnt_grant(svc_addr(rqstp), &argp->lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
286
287
288
289
  	dprintk("lockd: GRANTED       status %d
  ", ntohl(resp->status));
  	return rpc_success;
  }
a6beb7327   Christoph Hellwig   sunrpc: properly ...
290
291
292
293
294
  static __be32
  nlmsvc_proc_granted(struct svc_rqst *rqstp)
  {
  	return __nlmsvc_proc_granted(rqstp, rqstp->rq_resp);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
295
  /*
d47166244   Trond Myklebust   lockd: Add helper...
296
297
298
299
   * This is the generic lockd callback for async RPC calls
   */
  static void nlmsvc_callback_exit(struct rpc_task *task, void *data)
  {
c041b5ff8   Chuck Lever   NLM: fix print fo...
300
301
  	dprintk("lockd: %5u callback returned %d
  ", task->tk_pid,
d47166244   Trond Myklebust   lockd: Add helper...
302
303
  			-task->tk_status);
  }
7db836d4a   Chuck Lever   lockd: Split nlm_...
304
305
  void nlmsvc_release_call(struct nlm_rqst *call)
  {
fbca30c51   Elena Reshetova   lockd: convert nl...
306
  	if (!refcount_dec_and_test(&call->a_count))
7db836d4a   Chuck Lever   lockd: Split nlm_...
307
  		return;
67216b94d   Chuck Lever   lockd: Clean up n...
308
  	nlmsvc_release_host(call->a_host);
7db836d4a   Chuck Lever   lockd: Split nlm_...
309
310
  	kfree(call);
  }
d47166244   Trond Myklebust   lockd: Add helper...
311
312
  static void nlmsvc_callback_release(void *data)
  {
7db836d4a   Chuck Lever   lockd: Split nlm_...
313
  	nlmsvc_release_call(data);
d47166244   Trond Myklebust   lockd: Add helper...
314
315
316
317
318
319
320
321
  }
  
  static const struct rpc_call_ops nlmsvc_callback_ops = {
  	.rpc_call_done = nlmsvc_callback_exit,
  	.rpc_release = nlmsvc_callback_release,
  };
  
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
322
323
324
325
   * `Async' versions of the above service routines. They aren't really,
   * because we send the callback before the reply proper. I hope this
   * doesn't break any clients.
   */
a6beb7327   Christoph Hellwig   sunrpc: properly ...
326
327
  static __be32 nlmsvc_callback(struct svc_rqst *rqstp, u32 proc,
  		__be32 (*func)(struct svc_rqst *, struct nlm_res *))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
328
  {
a6beb7327   Christoph Hellwig   sunrpc: properly ...
329
  	struct nlm_args *argp = rqstp->rq_argp;
d47166244   Trond Myklebust   lockd: Add helper...
330
331
  	struct nlm_host	*host;
  	struct nlm_rqst	*call;
7111c66e4   Al Viro   [PATCH] fix svc_p...
332
  	__be32 stat;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
333

db4e4c9a9   Olaf Kirch   [PATCH] knfsd: wh...
334
335
336
  	host = nlmsvc_lookup_host(rqstp,
  				  argp->lock.caller,
  				  argp->lock.len);
d47166244   Trond Myklebust   lockd: Add helper...
337
338
339
340
  	if (host == NULL)
  		return rpc_system_err;
  
  	call = nlm_alloc_call(host);
446945ab9   Al Viro   lockd: shift grab...
341
  	nlmsvc_release_host(host);
d47166244   Trond Myklebust   lockd: Add helper...
342
343
  	if (call == NULL)
  		return rpc_system_err;
a6beb7327   Christoph Hellwig   sunrpc: properly ...
344
  	stat = func(rqstp, &call->a_res);
d47166244   Trond Myklebust   lockd: Add helper...
345
  	if (stat != 0) {
7db836d4a   Chuck Lever   lockd: Split nlm_...
346
  		nlmsvc_release_call(call);
d47166244   Trond Myklebust   lockd: Add helper...
347
348
  		return stat;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
349

d47166244   Trond Myklebust   lockd: Add helper...
350
351
352
353
  	call->a_flags = RPC_TASK_ASYNC;
  	if (nlm_async_reply(call, proc, &nlmsvc_callback_ops) < 0)
  		return rpc_system_err;
  	return rpc_success;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
354
  }
a6beb7327   Christoph Hellwig   sunrpc: properly ...
355
  static __be32 nlmsvc_proc_test_msg(struct svc_rqst *rqstp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
356
  {
d47166244   Trond Myklebust   lockd: Add helper...
357
358
  	dprintk("lockd: TEST_MSG      called
  ");
a6beb7327   Christoph Hellwig   sunrpc: properly ...
359
  	return nlmsvc_callback(rqstp, NLMPROC_TEST_RES, __nlmsvc_proc_test);
d47166244   Trond Myklebust   lockd: Add helper...
360
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
361

a6beb7327   Christoph Hellwig   sunrpc: properly ...
362
  static __be32 nlmsvc_proc_lock_msg(struct svc_rqst *rqstp)
d47166244   Trond Myklebust   lockd: Add helper...
363
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
364
365
  	dprintk("lockd: LOCK_MSG      called
  ");
a6beb7327   Christoph Hellwig   sunrpc: properly ...
366
  	return nlmsvc_callback(rqstp, NLMPROC_LOCK_RES, __nlmsvc_proc_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
367
  }
a6beb7327   Christoph Hellwig   sunrpc: properly ...
368
  static __be32 nlmsvc_proc_cancel_msg(struct svc_rqst *rqstp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
369
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
370
371
  	dprintk("lockd: CANCEL_MSG    called
  ");
a6beb7327   Christoph Hellwig   sunrpc: properly ...
372
  	return nlmsvc_callback(rqstp, NLMPROC_CANCEL_RES, __nlmsvc_proc_cancel);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
373
  }
7111c66e4   Al Viro   [PATCH] fix svc_p...
374
  static __be32
a6beb7327   Christoph Hellwig   sunrpc: properly ...
375
  nlmsvc_proc_unlock_msg(struct svc_rqst *rqstp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
376
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
377
378
  	dprintk("lockd: UNLOCK_MSG    called
  ");
a6beb7327   Christoph Hellwig   sunrpc: properly ...
379
  	return nlmsvc_callback(rqstp, NLMPROC_UNLOCK_RES, __nlmsvc_proc_unlock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
380
  }
7111c66e4   Al Viro   [PATCH] fix svc_p...
381
  static __be32
a6beb7327   Christoph Hellwig   sunrpc: properly ...
382
  nlmsvc_proc_granted_msg(struct svc_rqst *rqstp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
383
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
384
385
  	dprintk("lockd: GRANTED_MSG   called
  ");
a6beb7327   Christoph Hellwig   sunrpc: properly ...
386
  	return nlmsvc_callback(rqstp, NLMPROC_GRANTED_RES, __nlmsvc_proc_granted);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
387
388
389
390
391
  }
  
  /*
   * SHARE: create a DOS share or alter existing share.
   */
7111c66e4   Al Viro   [PATCH] fix svc_p...
392
  static __be32
a6beb7327   Christoph Hellwig   sunrpc: properly ...
393
  nlmsvc_proc_share(struct svc_rqst *rqstp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
394
  {
a6beb7327   Christoph Hellwig   sunrpc: properly ...
395
396
  	struct nlm_args *argp = rqstp->rq_argp;
  	struct nlm_res *resp = rqstp->rq_resp;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
397
398
399
400
401
402
403
404
405
  	struct nlm_host	*host;
  	struct nlm_file	*file;
  
  	dprintk("lockd: SHARE         called
  ");
  
  	resp->cookie = argp->cookie;
  
  	/* Don't accept new lock requests during grace period */
5ccb0066f   Stanislav Kinsbursky   LockD: pass actua...
406
  	if (locks_in_grace(SVC_NET(rqstp)) && !argp->reclaim) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
407
408
409
410
411
412
  		resp->status = nlm_lck_denied_grace_period;
  		return rpc_success;
  	}
  
  	/* Obtain client and file */
  	if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, &host, &file)))
d343fce14   NeilBrown   [PATCH] knfsd: Al...
413
  		return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
414
415
416
417
418
419
  
  	/* Now try to create the share */
  	resp->status = cast_status(nlmsvc_share_file(host, file, argp));
  
  	dprintk("lockd: SHARE         status %d
  ", ntohl(resp->status));
89e0edfbe   Benjamin Coddington   lockd: Convert NL...
420
  	nlmsvc_release_lockowner(&argp->lock);
67216b94d   Chuck Lever   lockd: Clean up n...
421
  	nlmsvc_release_host(host);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
422
423
424
425
426
427
428
  	nlm_release_file(file);
  	return rpc_success;
  }
  
  /*
   * UNSHARE: Release a DOS share.
   */
7111c66e4   Al Viro   [PATCH] fix svc_p...
429
  static __be32
a6beb7327   Christoph Hellwig   sunrpc: properly ...
430
  nlmsvc_proc_unshare(struct svc_rqst *rqstp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
431
  {
a6beb7327   Christoph Hellwig   sunrpc: properly ...
432
433
  	struct nlm_args *argp = rqstp->rq_argp;
  	struct nlm_res *resp = rqstp->rq_resp;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
434
435
436
437
438
439
440
441
442
  	struct nlm_host	*host;
  	struct nlm_file	*file;
  
  	dprintk("lockd: UNSHARE       called
  ");
  
  	resp->cookie = argp->cookie;
  
  	/* Don't accept requests during grace period */
5ccb0066f   Stanislav Kinsbursky   LockD: pass actua...
443
  	if (locks_in_grace(SVC_NET(rqstp))) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
444
445
446
447
448
449
  		resp->status = nlm_lck_denied_grace_period;
  		return rpc_success;
  	}
  
  	/* Obtain client and file */
  	if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, &host, &file)))
d343fce14   NeilBrown   [PATCH] knfsd: Al...
450
  		return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
451
452
453
454
455
456
  
  	/* Now try to unshare the file */
  	resp->status = cast_status(nlmsvc_unshare_file(host, file, argp));
  
  	dprintk("lockd: UNSHARE       status %d
  ", ntohl(resp->status));
89e0edfbe   Benjamin Coddington   lockd: Convert NL...
457
  	nlmsvc_release_lockowner(&argp->lock);
67216b94d   Chuck Lever   lockd: Clean up n...
458
  	nlmsvc_release_host(host);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
459
460
461
462
463
464
465
  	nlm_release_file(file);
  	return rpc_success;
  }
  
  /*
   * NM_LOCK: Create an unmonitored lock
   */
7111c66e4   Al Viro   [PATCH] fix svc_p...
466
  static __be32
a6beb7327   Christoph Hellwig   sunrpc: properly ...
467
  nlmsvc_proc_nm_lock(struct svc_rqst *rqstp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
468
  {
a6beb7327   Christoph Hellwig   sunrpc: properly ...
469
  	struct nlm_args *argp = rqstp->rq_argp;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
470
471
472
473
  	dprintk("lockd: NM_LOCK       called
  ");
  
  	argp->monitor = 0;		/* just clean the monitor flag */
a6beb7327   Christoph Hellwig   sunrpc: properly ...
474
  	return nlmsvc_proc_lock(rqstp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
475
476
477
478
479
  }
  
  /*
   * FREE_ALL: Release all locks and shares held by client
   */
7111c66e4   Al Viro   [PATCH] fix svc_p...
480
  static __be32
a6beb7327   Christoph Hellwig   sunrpc: properly ...
481
  nlmsvc_proc_free_all(struct svc_rqst *rqstp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
482
  {
a6beb7327   Christoph Hellwig   sunrpc: properly ...
483
  	struct nlm_args *argp = rqstp->rq_argp;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
484
485
486
487
488
489
490
  	struct nlm_host	*host;
  
  	/* Obtain client */
  	if (nlmsvc_retrieve_args(rqstp, argp, &host, NULL))
  		return rpc_success;
  
  	nlmsvc_free_host_resources(host);
67216b94d   Chuck Lever   lockd: Clean up n...
491
  	nlmsvc_release_host(host);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
492
493
494
495
496
497
  	return rpc_success;
  }
  
  /*
   * SM_NOTIFY: private callback from statd (not part of official NLM proto)
   */
7111c66e4   Al Viro   [PATCH] fix svc_p...
498
  static __be32
a6beb7327   Christoph Hellwig   sunrpc: properly ...
499
  nlmsvc_proc_sm_notify(struct svc_rqst *rqstp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
500
  {
a6beb7327   Christoph Hellwig   sunrpc: properly ...
501
  	struct nlm_reboot *argp = rqstp->rq_argp;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
502
503
  	dprintk("lockd: SM_NOTIFY     called
  ");
b85e46763   Chuck Lever   lockd: Add helper...
504
505
  
  	if (!nlm_privileged_requester(rqstp)) {
ad06e4bd6   Chuck Lever   [PATCH] knfsd: SU...
506
507
508
509
  		char buf[RPC_MAX_ADDRBUFLEN];
  		printk(KERN_WARNING "lockd: rejected NSM callback from %s
  ",
  				svc_print_addr(rqstp, buf, sizeof(buf)));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
510
511
  		return rpc_system_err;
  	}
0ad95472b   Andrey Ryabinin   lockd: create NSM...
512
  	nlm_host_rebooted(SVC_NET(rqstp), argp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
513
514
515
516
517
518
  	return rpc_success;
  }
  
  /*
   * client sent a GRANTED_RES, let's remove the associated block
   */
7111c66e4   Al Viro   [PATCH] fix svc_p...
519
  static __be32
a6beb7327   Christoph Hellwig   sunrpc: properly ...
520
  nlmsvc_proc_granted_res(struct svc_rqst *rqstp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
521
  {
a6beb7327   Christoph Hellwig   sunrpc: properly ...
522
  	struct nlm_res *argp = rqstp->rq_argp;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
523
524
525
526
527
  	if (!nlmsvc_ops)
  		return rpc_success;
  
  	dprintk("lockd: GRANTED_RES   called
  ");
39be4502c   Olaf Kirch   [PATCH] knfsd: ma...
528
  	nlmsvc_grant_reply(&argp->cookie, argp->status);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
529
530
  	return rpc_success;
  }
49d996082   Chuck Lever   lockd: Replace PR...
531
532
533
534
535
  static __be32
  nlmsvc_proc_unused(struct svc_rqst *rqstp)
  {
  	return rpc_proc_unavail;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
536
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
537
538
   * NLM Server procedures.
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
539
  struct nlm_void			{ int dummy; };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
540
541
542
543
  #define	Ck	(1+XDR_QUADLEN(NLM_MAXCOOKIELEN))	/* cookie */
  #define	St	1				/* status */
  #define	No	(1+1024/4)			/* Net Obj */
  #define	Rg	2				/* range - offset + size */
49d996082   Chuck Lever   lockd: Replace PR...
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
  const struct svc_procedure nlmsvc_procedures[24] = {
  	[NLMPROC_NULL] = {
  		.pc_func = nlmsvc_proc_null,
  		.pc_decode = nlmsvc_decode_void,
  		.pc_encode = nlmsvc_encode_void,
  		.pc_argsize = sizeof(struct nlm_void),
  		.pc_ressize = sizeof(struct nlm_void),
  		.pc_xdrressize = St,
  	},
  	[NLMPROC_TEST] = {
  		.pc_func = nlmsvc_proc_test,
  		.pc_decode = nlmsvc_decode_testargs,
  		.pc_encode = nlmsvc_encode_testres,
  		.pc_argsize = sizeof(struct nlm_args),
  		.pc_ressize = sizeof(struct nlm_res),
  		.pc_xdrressize = Ck+St+2+No+Rg,
  	},
  	[NLMPROC_LOCK] = {
  		.pc_func = nlmsvc_proc_lock,
  		.pc_decode = nlmsvc_decode_lockargs,
  		.pc_encode = nlmsvc_encode_res,
  		.pc_argsize = sizeof(struct nlm_args),
  		.pc_ressize = sizeof(struct nlm_res),
  		.pc_xdrressize = Ck+St,
  	},
  	[NLMPROC_CANCEL] = {
  		.pc_func = nlmsvc_proc_cancel,
  		.pc_decode = nlmsvc_decode_cancargs,
  		.pc_encode = nlmsvc_encode_res,
  		.pc_argsize = sizeof(struct nlm_args),
  		.pc_ressize = sizeof(struct nlm_res),
  		.pc_xdrressize = Ck+St,
  	},
  	[NLMPROC_UNLOCK] = {
  		.pc_func = nlmsvc_proc_unlock,
  		.pc_decode = nlmsvc_decode_unlockargs,
  		.pc_encode = nlmsvc_encode_res,
  		.pc_argsize = sizeof(struct nlm_args),
  		.pc_ressize = sizeof(struct nlm_res),
  		.pc_xdrressize = Ck+St,
  	},
  	[NLMPROC_GRANTED] = {
  		.pc_func = nlmsvc_proc_granted,
  		.pc_decode = nlmsvc_decode_testargs,
  		.pc_encode = nlmsvc_encode_res,
  		.pc_argsize = sizeof(struct nlm_args),
  		.pc_ressize = sizeof(struct nlm_res),
  		.pc_xdrressize = Ck+St,
  	},
  	[NLMPROC_TEST_MSG] = {
  		.pc_func = nlmsvc_proc_test_msg,
  		.pc_decode = nlmsvc_decode_testargs,
  		.pc_encode = nlmsvc_encode_void,
  		.pc_argsize = sizeof(struct nlm_args),
  		.pc_ressize = sizeof(struct nlm_void),
  		.pc_xdrressize = St,
  	},
  	[NLMPROC_LOCK_MSG] = {
  		.pc_func = nlmsvc_proc_lock_msg,
  		.pc_decode = nlmsvc_decode_lockargs,
  		.pc_encode = nlmsvc_encode_void,
  		.pc_argsize = sizeof(struct nlm_args),
  		.pc_ressize = sizeof(struct nlm_void),
  		.pc_xdrressize = St,
  	},
  	[NLMPROC_CANCEL_MSG] = {
  		.pc_func = nlmsvc_proc_cancel_msg,
  		.pc_decode = nlmsvc_decode_cancargs,
  		.pc_encode = nlmsvc_encode_void,
  		.pc_argsize = sizeof(struct nlm_args),
  		.pc_ressize = sizeof(struct nlm_void),
  		.pc_xdrressize = St,
  	},
  	[NLMPROC_UNLOCK_MSG] = {
  		.pc_func = nlmsvc_proc_unlock_msg,
  		.pc_decode = nlmsvc_decode_unlockargs,
  		.pc_encode = nlmsvc_encode_void,
  		.pc_argsize = sizeof(struct nlm_args),
  		.pc_ressize = sizeof(struct nlm_void),
  		.pc_xdrressize = St,
  	},
  	[NLMPROC_GRANTED_MSG] = {
  		.pc_func = nlmsvc_proc_granted_msg,
  		.pc_decode = nlmsvc_decode_testargs,
  		.pc_encode = nlmsvc_encode_void,
  		.pc_argsize = sizeof(struct nlm_args),
  		.pc_ressize = sizeof(struct nlm_void),
  		.pc_xdrressize = St,
  	},
  	[NLMPROC_TEST_RES] = {
  		.pc_func = nlmsvc_proc_null,
  		.pc_decode = nlmsvc_decode_void,
  		.pc_encode = nlmsvc_encode_void,
  		.pc_argsize = sizeof(struct nlm_res),
  		.pc_ressize = sizeof(struct nlm_void),
  		.pc_xdrressize = St,
  	},
  	[NLMPROC_LOCK_RES] = {
  		.pc_func = nlmsvc_proc_null,
  		.pc_decode = nlmsvc_decode_void,
  		.pc_encode = nlmsvc_encode_void,
  		.pc_argsize = sizeof(struct nlm_res),
  		.pc_ressize = sizeof(struct nlm_void),
  		.pc_xdrressize = St,
  	},
  	[NLMPROC_CANCEL_RES] = {
  		.pc_func = nlmsvc_proc_null,
  		.pc_decode = nlmsvc_decode_void,
  		.pc_encode = nlmsvc_encode_void,
  		.pc_argsize = sizeof(struct nlm_res),
  		.pc_ressize = sizeof(struct nlm_void),
  		.pc_xdrressize = St,
  	},
  	[NLMPROC_UNLOCK_RES] = {
  		.pc_func = nlmsvc_proc_null,
  		.pc_decode = nlmsvc_decode_void,
  		.pc_encode = nlmsvc_encode_void,
  		.pc_argsize = sizeof(struct nlm_res),
  		.pc_ressize = sizeof(struct nlm_void),
  		.pc_xdrressize = St,
  	},
  	[NLMPROC_GRANTED_RES] = {
  		.pc_func = nlmsvc_proc_granted_res,
  		.pc_decode = nlmsvc_decode_res,
  		.pc_encode = nlmsvc_encode_void,
  		.pc_argsize = sizeof(struct nlm_res),
  		.pc_ressize = sizeof(struct nlm_void),
  		.pc_xdrressize = St,
  	},
  	[NLMPROC_NSM_NOTIFY] = {
  		.pc_func = nlmsvc_proc_sm_notify,
  		.pc_decode = nlmsvc_decode_reboot,
  		.pc_encode = nlmsvc_encode_void,
  		.pc_argsize = sizeof(struct nlm_reboot),
  		.pc_ressize = sizeof(struct nlm_void),
  		.pc_xdrressize = St,
  	},
  	[17] = {
  		.pc_func = nlmsvc_proc_unused,
  		.pc_decode = nlmsvc_decode_void,
  		.pc_encode = nlmsvc_encode_void,
  		.pc_argsize = sizeof(struct nlm_void),
  		.pc_ressize = sizeof(struct nlm_void),
  		.pc_xdrressize = St,
  	},
  	[18] = {
  		.pc_func = nlmsvc_proc_unused,
  		.pc_decode = nlmsvc_decode_void,
  		.pc_encode = nlmsvc_encode_void,
  		.pc_argsize = sizeof(struct nlm_void),
  		.pc_ressize = sizeof(struct nlm_void),
  		.pc_xdrressize = St,
  	},
  	[19] = {
  		.pc_func = nlmsvc_proc_unused,
  		.pc_decode = nlmsvc_decode_void,
  		.pc_encode = nlmsvc_encode_void,
  		.pc_argsize = sizeof(struct nlm_void),
  		.pc_ressize = sizeof(struct nlm_void),
  		.pc_xdrressize = St,
  	},
  	[NLMPROC_SHARE] = {
  		.pc_func = nlmsvc_proc_share,
  		.pc_decode = nlmsvc_decode_shareargs,
  		.pc_encode = nlmsvc_encode_shareres,
  		.pc_argsize = sizeof(struct nlm_args),
  		.pc_ressize = sizeof(struct nlm_res),
  		.pc_xdrressize = Ck+St+1,
  	},
  	[NLMPROC_UNSHARE] = {
  		.pc_func = nlmsvc_proc_unshare,
  		.pc_decode = nlmsvc_decode_shareargs,
  		.pc_encode = nlmsvc_encode_shareres,
  		.pc_argsize = sizeof(struct nlm_args),
  		.pc_ressize = sizeof(struct nlm_res),
  		.pc_xdrressize = Ck+St+1,
  	},
  	[NLMPROC_NM_LOCK] = {
  		.pc_func = nlmsvc_proc_nm_lock,
  		.pc_decode = nlmsvc_decode_lockargs,
  		.pc_encode = nlmsvc_encode_res,
  		.pc_argsize = sizeof(struct nlm_args),
  		.pc_ressize = sizeof(struct nlm_res),
  		.pc_xdrressize = Ck+St,
  	},
  	[NLMPROC_FREE_ALL] = {
  		.pc_func = nlmsvc_proc_free_all,
  		.pc_decode = nlmsvc_decode_notify,
  		.pc_encode = nlmsvc_encode_void,
  		.pc_argsize = sizeof(struct nlm_args),
  		.pc_ressize = sizeof(struct nlm_void),
  		.pc_xdrressize = 0,
  	},
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
737
  };