Blame view
fs/lockd/svclock.c
25.6 KB
1da177e4c Linux-2.6.12-rc2 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
/* * linux/fs/lockd/svclock.c * * Handling of server-side locks, mostly of the blocked variety. * This is the ugliest part of lockd because we tread on very thin ice. * GRANT and CANCEL calls may get stuck, meet in mid-flight, etc. * IMNSHO introducing the grant callback into the NLM protocol was one * of the worst ideas Sun ever had. Except maybe for the idea of doing * NFS file locking at all. * * I'm trying hard to avoid race conditions by protecting most accesses * to a file's list of blocked locks through a semaphore. The global * list of blocked locks is not protected in this fashion however. * Therefore, some functions (such as the RPC callback for the async grant * call) move blocked locks towards the head of the list *while some other * process might be traversing it*. This should not be a problem in * practice, because this will only cause functions traversing the list * to visit some blocks twice. * * Copyright (C) 1996, Olaf Kirch <okir@monad.swb.de> */ |
1da177e4c Linux-2.6.12-rc2 |
22 |
#include <linux/types.h> |
5a0e3ad6a include cleanup: ... |
23 |
#include <linux/slab.h> |
1da177e4c Linux-2.6.12-rc2 |
24 25 26 |
#include <linux/errno.h> #include <linux/kernel.h> #include <linux/sched.h> |
1da177e4c Linux-2.6.12-rc2 |
27 28 29 30 |
#include <linux/sunrpc/clnt.h> #include <linux/sunrpc/svc.h> #include <linux/lockd/nlm.h> #include <linux/lockd/lockd.h> |
d751a7cd0 NLM: Convert lock... |
31 |
#include <linux/kthread.h> |
1da177e4c Linux-2.6.12-rc2 |
32 33 34 35 36 37 38 39 |
#define NLMDBG_FACILITY NLMDBG_SVCLOCK #ifdef CONFIG_LOCKD_V4 #define nlm_deadlock nlm4_deadlock #else #define nlm_deadlock nlm_lck_denied #endif |
6849c0cab lockd: Add refcou... |
40 |
static void nlmsvc_release_block(struct nlm_block *block); |
1da177e4c Linux-2.6.12-rc2 |
41 |
static void nlmsvc_insert_block(struct nlm_block *block, unsigned long); |
68a2d76ce [PATCH] knfsd: lo... |
42 |
static void nlmsvc_remove_block(struct nlm_block *block); |
963d8fe53 RPC: Clean up RPC... |
43 |
|
5e1abf8cb lockd: Clean up o... |
44 45 |
static int nlmsvc_setgrantargs(struct nlm_rqst *call, struct nlm_lock *lock); static void nlmsvc_freegrantargs(struct nlm_rqst *call); |
963d8fe53 RPC: Clean up RPC... |
46 |
static const struct rpc_call_ops nlmsvc_grant_ops; |
d8367c504 lockd: Move nlmdb... |
47 |
static const char *nlmdbg_cookie2a(const struct nlm_cookie *cookie); |
1da177e4c Linux-2.6.12-rc2 |
48 49 50 51 |
/* * The list of blocked locks to retry */ |
68a2d76ce [PATCH] knfsd: lo... |
52 |
static LIST_HEAD(nlm_blocked); |
f904be9cc lockd: Mostly rem... |
53 |
static DEFINE_SPINLOCK(nlm_blocked_lock); |
1da177e4c Linux-2.6.12-rc2 |
54 55 56 57 58 |
/* * Insert a blocked lock into the global list */ static void |
f904be9cc lockd: Mostly rem... |
59 |
nlmsvc_insert_block_locked(struct nlm_block *block, unsigned long when) |
1da177e4c Linux-2.6.12-rc2 |
60 |
{ |
68a2d76ce [PATCH] knfsd: lo... |
61 62 |
struct nlm_block *b; struct list_head *pos; |
1da177e4c Linux-2.6.12-rc2 |
63 64 65 |
dprintk("lockd: nlmsvc_insert_block(%p, %ld) ", block, when); |
68a2d76ce [PATCH] knfsd: lo... |
66 67 68 69 70 71 72 |
if (list_empty(&block->b_list)) { kref_get(&block->b_count); } else { list_del_init(&block->b_list); } pos = &nlm_blocked; |
1da177e4c Linux-2.6.12-rc2 |
73 74 75 |
if (when != NLM_NEVER) { if ((when += jiffies) == NLM_NEVER) when ++; |
68a2d76ce [PATCH] knfsd: lo... |
76 77 78 79 80 81 82 83 84 |
list_for_each(pos, &nlm_blocked) { b = list_entry(pos, struct nlm_block, b_list); if (time_after(b->b_when,when) || b->b_when == NLM_NEVER) break; } /* On normal exit from the loop, pos == &nlm_blocked, * so we will be adding to the end of the list - good */ } |
1da177e4c Linux-2.6.12-rc2 |
85 |
|
68a2d76ce [PATCH] knfsd: lo... |
86 |
list_add_tail(&block->b_list, pos); |
1da177e4c Linux-2.6.12-rc2 |
87 |
block->b_when = when; |
1da177e4c Linux-2.6.12-rc2 |
88 |
} |
f904be9cc lockd: Mostly rem... |
89 90 91 92 93 94 |
static void nlmsvc_insert_block(struct nlm_block *block, unsigned long when) { spin_lock(&nlm_blocked_lock); nlmsvc_insert_block_locked(block, when); spin_unlock(&nlm_blocked_lock); } |
1da177e4c Linux-2.6.12-rc2 |
95 96 97 |
/* * Remove a block from the global list */ |
68a2d76ce [PATCH] knfsd: lo... |
98 |
static inline void |
1da177e4c Linux-2.6.12-rc2 |
99 100 |
nlmsvc_remove_block(struct nlm_block *block) { |
68a2d76ce [PATCH] knfsd: lo... |
101 |
if (!list_empty(&block->b_list)) { |
f904be9cc lockd: Mostly rem... |
102 |
spin_lock(&nlm_blocked_lock); |
68a2d76ce [PATCH] knfsd: lo... |
103 |
list_del_init(&block->b_list); |
f904be9cc lockd: Mostly rem... |
104 |
spin_unlock(&nlm_blocked_lock); |
68a2d76ce [PATCH] knfsd: lo... |
105 |
nlmsvc_release_block(block); |
1da177e4c Linux-2.6.12-rc2 |
106 |
} |
1da177e4c Linux-2.6.12-rc2 |
107 108 109 |
} /* |
d9f6eb75d lockd: blocks sho... |
110 |
* Find a block for a given lock |
1da177e4c Linux-2.6.12-rc2 |
111 112 |
*/ static struct nlm_block * |
d9f6eb75d lockd: blocks sho... |
113 |
nlmsvc_lookup_block(struct nlm_file *file, struct nlm_lock *lock) |
1da177e4c Linux-2.6.12-rc2 |
114 |
{ |
68a2d76ce [PATCH] knfsd: lo... |
115 |
struct nlm_block *block; |
1da177e4c Linux-2.6.12-rc2 |
116 117 118 119 120 121 122 |
struct file_lock *fl; dprintk("lockd: nlmsvc_lookup_block f=%p pd=%d %Ld-%Ld ty=%d ", file, lock->fl.fl_pid, (long long)lock->fl.fl_start, (long long)lock->fl.fl_end, lock->fl.fl_type); |
68a2d76ce [PATCH] knfsd: lo... |
123 |
list_for_each_entry(block, &nlm_blocked, b_list) { |
92737230d NLM: Add nlmclnt_... |
124 |
fl = &block->b_call->a_args.lock.fl; |
1da177e4c Linux-2.6.12-rc2 |
125 126 127 128 129 |
dprintk("lockd: check f=%p pd=%d %Ld-%Ld ty=%d cookie=%s ", block->b_file, fl->fl_pid, (long long)fl->fl_start, (long long)fl->fl_end, fl->fl_type, |
92737230d NLM: Add nlmclnt_... |
130 |
nlmdbg_cookie2a(&block->b_call->a_args.cookie)); |
1da177e4c Linux-2.6.12-rc2 |
131 |
if (block->b_file == file && nlm_compare_locks(fl, &lock->fl)) { |
6849c0cab lockd: Add refcou... |
132 |
kref_get(&block->b_count); |
1da177e4c Linux-2.6.12-rc2 |
133 134 135 136 137 138 139 140 141 |
return block; } } return NULL; } static inline int nlm_cookie_match(struct nlm_cookie *a, struct nlm_cookie *b) { |
6d7bbbbac lockd: minor svcl... |
142 |
if (a->len != b->len) |
1da177e4c Linux-2.6.12-rc2 |
143 |
return 0; |
6d7bbbbac lockd: minor svcl... |
144 |
if (memcmp(a->data, b->data, a->len)) |
1da177e4c Linux-2.6.12-rc2 |
145 146 147 148 149 150 151 152 |
return 0; return 1; } /* * Find a block with a given NLM cookie. */ static inline struct nlm_block * |
39be4502c [PATCH] knfsd: ma... |
153 |
nlmsvc_find_block(struct nlm_cookie *cookie) |
1da177e4c Linux-2.6.12-rc2 |
154 155 |
{ struct nlm_block *block; |
68a2d76ce [PATCH] knfsd: lo... |
156 |
list_for_each_entry(block, &nlm_blocked, b_list) { |
39be4502c [PATCH] knfsd: ma... |
157 |
if (nlm_cookie_match(&block->b_call->a_args.cookie,cookie)) |
68a2d76ce [PATCH] knfsd: lo... |
158 |
goto found; |
1da177e4c Linux-2.6.12-rc2 |
159 |
} |
68a2d76ce [PATCH] knfsd: lo... |
160 161 162 |
return NULL; found: |
39be4502c [PATCH] knfsd: ma... |
163 164 |
dprintk("nlmsvc_find_block(%s): block=%p ", nlmdbg_cookie2a(cookie), block); |
68a2d76ce [PATCH] knfsd: lo... |
165 |
kref_get(&block->b_count); |
1da177e4c Linux-2.6.12-rc2 |
166 167 168 169 170 171 172 173 174 175 176 177 |
return block; } /* * Create a block and initialize it. * * Note: we explicitly set the cookie of the grant reply to that of * the blocked lock request. The spec explicitly mentions that the client * should _not_ rely on the callback containing the same cookie as the * request, but (as I found out later) that's because some implementations * do just this. Never mind the standards comittees, they support our * logging industries. |
39be4502c [PATCH] knfsd: ma... |
178 179 180 181 182 |
* * 10 years later: I hope we can safely ignore these old and broken * clients by now. Let's fix this so we can uniquely identify an incoming * GRANTED_RES message by cookie, without having to rely on the client's IP * address. --okir |
1da177e4c Linux-2.6.12-rc2 |
183 |
*/ |
255129d1e NLM: Fix a circul... |
184 185 186 187 |
static struct nlm_block * nlmsvc_create_block(struct svc_rqst *rqstp, struct nlm_host *host, struct nlm_file *file, struct nlm_lock *lock, struct nlm_cookie *cookie) |
1da177e4c Linux-2.6.12-rc2 |
188 189 |
{ struct nlm_block *block; |
92737230d NLM: Add nlmclnt_... |
190 |
struct nlm_rqst *call = NULL; |
1da177e4c Linux-2.6.12-rc2 |
191 |
|
560de0e65 lockd: get host r... |
192 |
nlm_get_host(host); |
92737230d NLM: Add nlmclnt_... |
193 194 195 |
call = nlm_alloc_call(host); if (call == NULL) return NULL; |
1da177e4c Linux-2.6.12-rc2 |
196 |
/* Allocate memory for block, and initialize arguments */ |
92737230d NLM: Add nlmclnt_... |
197 198 |
block = kzalloc(sizeof(*block), GFP_KERNEL); if (block == NULL) |
1da177e4c Linux-2.6.12-rc2 |
199 |
goto failed; |
6849c0cab lockd: Add refcou... |
200 |
kref_init(&block->b_count); |
68a2d76ce [PATCH] knfsd: lo... |
201 202 |
INIT_LIST_HEAD(&block->b_list); INIT_LIST_HEAD(&block->b_flist); |
1da177e4c Linux-2.6.12-rc2 |
203 |
|
92737230d NLM: Add nlmclnt_... |
204 |
if (!nlmsvc_setgrantargs(call, lock)) |
1da177e4c Linux-2.6.12-rc2 |
205 206 207 |
goto failed_free; /* Set notifier function for VFS, and init args */ |
92737230d NLM: Add nlmclnt_... |
208 209 |
call->a_args.lock.fl.fl_flags |= FL_SLEEP; call->a_args.lock.fl.fl_lmops = &nlmsvc_lock_operations; |
39be4502c [PATCH] knfsd: ma... |
210 |
nlmclnt_next_cookie(&call->a_args.cookie); |
1da177e4c Linux-2.6.12-rc2 |
211 212 213 214 215 216 217 218 |
dprintk("lockd: created block %p... ", block); /* Create and initialize the block */ block->b_daemon = rqstp->rq_server; block->b_host = host; block->b_file = file; |
5ea0d7503 lockd: handle tes... |
219 |
block->b_fl = NULL; |
d9f6eb75d lockd: blocks sho... |
220 |
file->f_count++; |
1da177e4c Linux-2.6.12-rc2 |
221 222 |
/* Add to file's list of blocks */ |
68a2d76ce [PATCH] knfsd: lo... |
223 |
list_add(&block->b_flist, &file->f_blocks); |
1da177e4c Linux-2.6.12-rc2 |
224 225 |
/* Set up RPC arguments for callback */ |
92737230d NLM: Add nlmclnt_... |
226 |
block->b_call = call; |
1da177e4c Linux-2.6.12-rc2 |
227 |
call->a_flags = RPC_TASK_ASYNC; |
92737230d NLM: Add nlmclnt_... |
228 |
call->a_block = block; |
1da177e4c Linux-2.6.12-rc2 |
229 230 231 232 233 234 |
return block; failed_free: kfree(block); failed: |
7db836d4a lockd: Split nlm_... |
235 |
nlmsvc_release_call(call); |
1da177e4c Linux-2.6.12-rc2 |
236 237 238 239 |
return NULL; } /* |
3c61eecb6 lockd: Fix stale ... |
240 |
* Delete a block. |
1da177e4c Linux-2.6.12-rc2 |
241 242 243 |
* It is the caller's responsibility to check whether the file * can be closed hereafter. */ |
6849c0cab lockd: Add refcou... |
244 |
static int nlmsvc_unlink_block(struct nlm_block *block) |
1da177e4c Linux-2.6.12-rc2 |
245 |
{ |
09c7938c5 lockd: Fix server... |
246 |
int status; |
6849c0cab lockd: Add refcou... |
247 248 |
dprintk("lockd: unlinking block %p... ", block); |
1da177e4c Linux-2.6.12-rc2 |
249 250 |
/* Remove block from list */ |
92737230d NLM: Add nlmclnt_... |
251 |
status = posix_unblock_lock(block->b_file->f_file, &block->b_call->a_args.lock.fl); |
1da177e4c Linux-2.6.12-rc2 |
252 |
nlmsvc_remove_block(block); |
6849c0cab lockd: Add refcou... |
253 254 |
return status; } |
1da177e4c Linux-2.6.12-rc2 |
255 |
|
6849c0cab lockd: Add refcou... |
256 257 258 259 |
static void nlmsvc_free_block(struct kref *kref) { struct nlm_block *block = container_of(kref, struct nlm_block, b_count); struct nlm_file *file = block->b_file; |
6849c0cab lockd: Add refcou... |
260 261 262 |
dprintk("lockd: freeing block %p... ", block); |
1da177e4c Linux-2.6.12-rc2 |
263 264 |
/* Remove block from file's list of blocks */ |
89e63ef60 [PATCH] Convert l... |
265 |
mutex_lock(&file->f_mutex); |
68a2d76ce [PATCH] knfsd: lo... |
266 |
list_del_init(&block->b_flist); |
89e63ef60 [PATCH] Convert l... |
267 |
mutex_unlock(&file->f_mutex); |
1da177e4c Linux-2.6.12-rc2 |
268 |
|
92737230d NLM: Add nlmclnt_... |
269 |
nlmsvc_freegrantargs(block->b_call); |
7db836d4a lockd: Split nlm_... |
270 |
nlmsvc_release_call(block->b_call); |
d9f6eb75d lockd: blocks sho... |
271 |
nlm_release_file(block->b_file); |
0e4ac9d93 lockd: handle fl_... |
272 |
kfree(block->b_fl); |
1da177e4c Linux-2.6.12-rc2 |
273 |
kfree(block); |
6849c0cab lockd: Add refcou... |
274 275 276 277 278 279 |
} static void nlmsvc_release_block(struct nlm_block *block) { if (block != NULL) kref_put(&block->b_count, nlmsvc_free_block); |
1da177e4c Linux-2.6.12-rc2 |
280 |
} |
f2af793db [PATCH] knfsd: lo... |
281 282 283 284 285 286 287 |
/* * Loop over all blocks and delete blocks held by * a matching host. */ void nlmsvc_traverse_blocks(struct nlm_host *host, struct nlm_file *file, nlm_host_match_fn_t match) |
d9f6eb75d lockd: blocks sho... |
288 |
{ |
68a2d76ce [PATCH] knfsd: lo... |
289 |
struct nlm_block *block, *next; |
d9f6eb75d lockd: blocks sho... |
290 291 |
restart: |
89e63ef60 [PATCH] Convert l... |
292 |
mutex_lock(&file->f_mutex); |
68a2d76ce [PATCH] knfsd: lo... |
293 |
list_for_each_entry_safe(block, next, &file->f_blocks, b_flist) { |
f2af793db [PATCH] knfsd: lo... |
294 |
if (!match(block->b_host, host)) |
d9f6eb75d lockd: blocks sho... |
295 |
continue; |
68a2d76ce [PATCH] knfsd: lo... |
296 297 298 |
/* Do not destroy blocks that are not on * the global retry list - why? */ if (list_empty(&block->b_list)) |
d9f6eb75d lockd: blocks sho... |
299 300 |
continue; kref_get(&block->b_count); |
89e63ef60 [PATCH] Convert l... |
301 |
mutex_unlock(&file->f_mutex); |
d9f6eb75d lockd: blocks sho... |
302 303 304 305 |
nlmsvc_unlink_block(block); nlmsvc_release_block(block); goto restart; } |
89e63ef60 [PATCH] Convert l... |
306 |
mutex_unlock(&file->f_mutex); |
d9f6eb75d lockd: blocks sho... |
307 |
} |
1da177e4c Linux-2.6.12-rc2 |
308 |
/* |
5e1abf8cb lockd: Clean up o... |
309 310 311 312 313 314 315 |
* Initialize arguments for GRANTED call. The nlm_rqst structure * has been cleared already. */ static int nlmsvc_setgrantargs(struct nlm_rqst *call, struct nlm_lock *lock) { locks_copy_lock(&call->a_args.lock.fl, &lock->fl); memcpy(&call->a_args.lock.fh, &lock->fh, sizeof(call->a_args.lock.fh)); |
e9ff3990f [PATCH] namespace... |
316 |
call->a_args.lock.caller = utsname()->nodename; |
5e1abf8cb lockd: Clean up o... |
317 318 319 320 321 322 323 324 |
call->a_args.lock.oh.len = lock->oh.len; /* set default data area */ call->a_args.lock.oh.data = call->a_owner; call->a_args.lock.svid = lock->fl.fl_pid; if (lock->oh.len > NLMCLNT_OHSIZE) { void *data = kmalloc(lock->oh.len, GFP_KERNEL); |
92737230d NLM: Add nlmclnt_... |
325 |
if (!data) |
5e1abf8cb lockd: Clean up o... |
326 |
return 0; |
5e1abf8cb lockd: Clean up o... |
327 328 329 330 331 332 333 334 335 |
call->a_args.lock.oh.data = (u8 *) data; } memcpy(call->a_args.lock.oh.data, lock->oh.data, lock->oh.len); return 1; } static void nlmsvc_freegrantargs(struct nlm_rqst *call) { |
92737230d NLM: Add nlmclnt_... |
336 |
if (call->a_args.lock.oh.data != call->a_owner) |
5e1abf8cb lockd: Clean up o... |
337 |
kfree(call->a_args.lock.oh.data); |
a9e61e25f lockd: call locks... |
338 339 |
locks_release_private(&call->a_args.lock.fl); |
5e1abf8cb lockd: Clean up o... |
340 341 342 |
} /* |
2b36f412a lockd: save lock ... |
343 344 |
* Deferred lock request handling for non-blocking lock */ |
ca5c8cde9 lockd and nfsd en... |
345 |
static __be32 |
2b36f412a lockd: save lock ... |
346 347 |
nlmsvc_defer_lock_rqst(struct svc_rqst *rqstp, struct nlm_block *block) { |
ca5c8cde9 lockd and nfsd en... |
348 |
__be32 status = nlm_lck_denied_nolocks; |
2b36f412a lockd: save lock ... |
349 350 351 352 353 354 355 356 357 358 359 360 361 362 |
block->b_flags |= B_QUEUED; nlmsvc_insert_block(block, NLM_TIMEOUT); block->b_cache_req = &rqstp->rq_chandle; if (rqstp->rq_chandle.defer) { block->b_deferred_req = rqstp->rq_chandle.defer(block->b_cache_req); if (block->b_deferred_req != NULL) status = nlm_drop_reply; } dprintk("lockd: nlmsvc_defer_lock_rqst block %p flags %d status %d ", |
ca5c8cde9 lockd and nfsd en... |
363 |
block, block->b_flags, ntohl(status)); |
2b36f412a lockd: save lock ... |
364 365 366 367 368 |
return status; } /* |
1da177e4c Linux-2.6.12-rc2 |
369 370 371 |
* Attempt to establish a lock, and if it can't be granted, block it * if required. */ |
52921e02a [PATCH] lockd end... |
372 |
__be32 |
1da177e4c Linux-2.6.12-rc2 |
373 |
nlmsvc_lock(struct svc_rqst *rqstp, struct nlm_file *file, |
6cde4de80 lockd: eliminate ... |
374 |
struct nlm_host *host, struct nlm_lock *lock, int wait, |
b2b502890 lockd: move grace... |
375 |
struct nlm_cookie *cookie, int reclaim) |
1da177e4c Linux-2.6.12-rc2 |
376 |
{ |
f81204802 lockd: always pre... |
377 |
struct nlm_block *block = NULL; |
1da177e4c Linux-2.6.12-rc2 |
378 |
int error; |
52921e02a [PATCH] lockd end... |
379 |
__be32 ret; |
1da177e4c Linux-2.6.12-rc2 |
380 381 382 |
dprintk("lockd: nlmsvc_lock(%s/%ld, ty=%d, pi=%d, %Ld-%Ld, bl=%d) ", |
225a719f7 [PATCH] struct pa... |
383 384 |
file->f_file->f_path.dentry->d_inode->i_sb->s_id, file->f_file->f_path.dentry->d_inode->i_ino, |
1da177e4c Linux-2.6.12-rc2 |
385 386 387 388 |
lock->fl.fl_type, lock->fl.fl_pid, (long long)lock->fl.fl_start, (long long)lock->fl.fl_end, wait); |
1da177e4c Linux-2.6.12-rc2 |
389 |
/* Lock file against concurrent access */ |
89e63ef60 [PATCH] Convert l... |
390 |
mutex_lock(&file->f_mutex); |
f81204802 lockd: always pre... |
391 392 393 |
/* Get existing block (in case client is busy-waiting) * or create new block */ |
d9f6eb75d lockd: blocks sho... |
394 |
block = nlmsvc_lookup_block(file, lock); |
09c7938c5 lockd: Fix server... |
395 |
if (block == NULL) { |
560de0e65 lockd: get host r... |
396 |
block = nlmsvc_create_block(rqstp, host, file, lock, cookie); |
f81204802 lockd: always pre... |
397 398 399 |
ret = nlm_lck_denied_nolocks; if (block == NULL) goto out; |
92737230d NLM: Add nlmclnt_... |
400 |
lock = &block->b_call->a_args.lock; |
f81204802 lockd: always pre... |
401 402 |
} else lock->fl.fl_flags &= ~FL_SLEEP; |
1da177e4c Linux-2.6.12-rc2 |
403 |
|
1a8322b2b lockd: add code t... |
404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 |
if (block->b_flags & B_QUEUED) { dprintk("lockd: nlmsvc_lock deferred block %p flags %d ", block, block->b_flags); if (block->b_granted) { nlmsvc_unlink_block(block); ret = nlm_granted; goto out; } if (block->b_flags & B_TIMED_OUT) { nlmsvc_unlink_block(block); ret = nlm_lck_denied; goto out; } ret = nlm_drop_reply; goto out; } |
1da177e4c Linux-2.6.12-rc2 |
421 |
|
b2b502890 lockd: move grace... |
422 423 424 425 |
if (locks_in_grace() && !reclaim) { ret = nlm_lck_denied_grace_period; goto out; } |
d22b1cff0 lockd: reject rec... |
426 427 428 429 |
if (reclaim && !locks_in_grace()) { ret = nlm_lck_denied_grace_period; goto out; } |
b2b502890 lockd: move grace... |
430 |
|
1a8322b2b lockd: add code t... |
431 432 433 434 |
if (!wait) lock->fl.fl_flags &= ~FL_SLEEP; error = vfs_lock_file(file->f_file, F_SETLK, &lock->fl, NULL); lock->fl.fl_flags &= ~FL_SLEEP; |
a85f193e2 lockd: make nlmsv... |
435 |
|
1a8322b2b lockd: add code t... |
436 437 |
dprintk("lockd: vfs_lock_file returned %d ", error); |
6d7bbbbac lockd: minor svcl... |
438 |
switch (error) { |
1da177e4c Linux-2.6.12-rc2 |
439 |
case 0: |
15dadef94 lockd: clean up n... |
440 441 |
ret = nlm_granted; goto out; |
09c7938c5 lockd: Fix server... |
442 |
case -EAGAIN: |
e33d1ea60 lockd: clean up b... |
443 444 445 446 447 448 449 |
/* * If this is a blocking request for an * already pending lock request then we need * to put it back on lockd's block list */ if (wait) break; |
1a8322b2b lockd: add code t... |
450 |
ret = nlm_lck_denied; |
e33d1ea60 lockd: clean up b... |
451 |
goto out; |
bde74e4bc locks: add specia... |
452 |
case FILE_LOCK_DEFERRED: |
1a8322b2b lockd: add code t... |
453 454 455 456 457 458 |
if (wait) break; /* Filesystem lock operation is in progress Add it to the queue waiting for callback */ ret = nlmsvc_defer_lock_rqst(rqstp, block); goto out; |
09c7938c5 lockd: Fix server... |
459 |
case -EDEADLK: |
15dadef94 lockd: clean up n... |
460 461 |
ret = nlm_deadlock; goto out; |
1da177e4c Linux-2.6.12-rc2 |
462 |
default: /* includes ENOLCK */ |
15dadef94 lockd: clean up n... |
463 464 |
ret = nlm_lck_denied_nolocks; goto out; |
1da177e4c Linux-2.6.12-rc2 |
465 |
} |
09c7938c5 lockd: Fix server... |
466 |
ret = nlm_lck_blocked; |
1da177e4c Linux-2.6.12-rc2 |
467 468 |
/* Append to list of blocked */ |
f81204802 lockd: always pre... |
469 |
nlmsvc_insert_block(block, NLM_NEVER); |
15dadef94 lockd: clean up n... |
470 |
out: |
89e63ef60 [PATCH] Convert l... |
471 |
mutex_unlock(&file->f_mutex); |
6849c0cab lockd: Add refcou... |
472 |
nlmsvc_release_block(block); |
15dadef94 lockd: clean up n... |
473 474 475 |
dprintk("lockd: nlmsvc_lock returned %u ", ret); return ret; |
1da177e4c Linux-2.6.12-rc2 |
476 477 478 479 480 |
} /* * Test for presence of a conflicting lock. */ |
52921e02a [PATCH] lockd end... |
481 |
__be32 |
85f3f1b3f lockd: pass cooki... |
482 |
nlmsvc_testlock(struct svc_rqst *rqstp, struct nlm_file *file, |
8f920d5e2 lockd: eliminate ... |
483 484 |
struct nlm_host *host, struct nlm_lock *lock, struct nlm_lock *conflock, struct nlm_cookie *cookie) |
1da177e4c Linux-2.6.12-rc2 |
485 |
{ |
5ea0d7503 lockd: handle tes... |
486 487 488 |
struct nlm_block *block = NULL; int error; __be32 ret; |
1da177e4c Linux-2.6.12-rc2 |
489 490 |
dprintk("lockd: nlmsvc_testlock(%s/%ld, ty=%d, %Ld-%Ld) ", |
225a719f7 [PATCH] struct pa... |
491 492 |
file->f_file->f_path.dentry->d_inode->i_sb->s_id, file->f_file->f_path.dentry->d_inode->i_ino, |
1da177e4c Linux-2.6.12-rc2 |
493 494 495 |
lock->fl.fl_type, (long long)lock->fl.fl_start, (long long)lock->fl.fl_end); |
5ea0d7503 lockd: handle tes... |
496 497 498 499 500 501 502 503 |
/* Get existing block (in case client is busy-waiting) */ block = nlmsvc_lookup_block(file, lock); if (block == NULL) { struct file_lock *conf = kzalloc(sizeof(*conf), GFP_KERNEL); if (conf == NULL) return nlm_granted; |
255129d1e NLM: Fix a circul... |
504 |
block = nlmsvc_create_block(rqstp, host, file, lock, cookie); |
5ea0d7503 lockd: handle tes... |
505 506 507 508 509 510 511 512 513 514 515 516 |
if (block == NULL) { kfree(conf); return nlm_granted; } block->b_fl = conf; } if (block->b_flags & B_QUEUED) { dprintk("lockd: nlmsvc_testlock deferred block %p flags %d fl %p ", block, block->b_flags, block->b_fl); if (block->b_flags & B_TIMED_OUT) { nlmsvc_unlink_block(block); |
29dbf5461 lockd: fix a leak... |
517 518 |
ret = nlm_lck_denied; goto out; |
5ea0d7503 lockd: handle tes... |
519 520 |
} if (block->b_flags & B_GOT_CALLBACK) { |
54ca95eb3 Leak in nlmsvc_te... |
521 |
nlmsvc_unlink_block(block); |
5ea0d7503 lockd: handle tes... |
522 523 524 525 |
if (block->b_fl != NULL && block->b_fl->fl_type != F_UNLCK) { lock->fl = *block->b_fl; goto conf_lock; |
29dbf5461 lockd: fix a leak... |
526 |
} else { |
29dbf5461 lockd: fix a leak... |
527 528 |
ret = nlm_granted; goto out; |
5ea0d7503 lockd: handle tes... |
529 530 |
} } |
29dbf5461 lockd: fix a leak... |
531 532 |
ret = nlm_drop_reply; goto out; |
1da177e4c Linux-2.6.12-rc2 |
533 |
} |
b2b502890 lockd: move grace... |
534 535 536 537 |
if (locks_in_grace()) { ret = nlm_lck_denied_grace_period; goto out; } |
5ea0d7503 lockd: handle tes... |
538 |
error = vfs_test_lock(file->f_file, &lock->fl); |
bde74e4bc locks: add specia... |
539 |
if (error == FILE_LOCK_DEFERRED) { |
29dbf5461 lockd: fix a leak... |
540 541 542 |
ret = nlmsvc_defer_lock_rqst(rqstp, block); goto out; } |
5ea0d7503 lockd: handle tes... |
543 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 |
if (error) { ret = nlm_lck_denied_nolocks; goto out; } if (lock->fl.fl_type == F_UNLCK) { ret = nlm_granted; goto out; } conf_lock: dprintk("lockd: conflicting lock(ty=%d, %Ld-%Ld) ", lock->fl.fl_type, (long long)lock->fl.fl_start, (long long)lock->fl.fl_end); conflock->caller = "somehost"; /* FIXME */ conflock->len = strlen(conflock->caller); conflock->oh.len = 0; /* don't return OH info */ conflock->svid = lock->fl.fl_pid; conflock->fl.fl_type = lock->fl.fl_type; conflock->fl.fl_start = lock->fl.fl_start; conflock->fl.fl_end = lock->fl.fl_end; ret = nlm_lck_denied; out: if (block) nlmsvc_release_block(block); return ret; |
1da177e4c Linux-2.6.12-rc2 |
569 570 571 572 573 574 575 576 577 |
} /* * Remove a lock. * This implies a CANCEL call: We send a GRANT_MSG, the client replies * with a GRANT_RES call which gets lost, and calls UNLOCK immediately * afterwards. In this case the block will still be there, and hence * must be removed. */ |
52921e02a [PATCH] lockd end... |
578 |
__be32 |
1da177e4c Linux-2.6.12-rc2 |
579 580 581 582 583 584 |
nlmsvc_unlock(struct nlm_file *file, struct nlm_lock *lock) { int error; dprintk("lockd: nlmsvc_unlock(%s/%ld, pi=%d, %Ld-%Ld) ", |
225a719f7 [PATCH] struct pa... |
585 586 |
file->f_file->f_path.dentry->d_inode->i_sb->s_id, file->f_file->f_path.dentry->d_inode->i_ino, |
1da177e4c Linux-2.6.12-rc2 |
587 588 589 590 591 592 593 594 |
lock->fl.fl_pid, (long long)lock->fl.fl_start, (long long)lock->fl.fl_end); /* First, cancel any lock that might be there */ nlmsvc_cancel_blocked(file, lock); lock->fl.fl_type = F_UNLCK; |
1a8322b2b lockd: add code t... |
595 |
error = vfs_lock_file(file->f_file, F_SETLK, &lock->fl, NULL); |
1da177e4c Linux-2.6.12-rc2 |
596 597 598 599 600 601 602 603 604 605 606 |
return (error < 0)? nlm_lck_denied_nolocks : nlm_granted; } /* * Cancel a previously blocked request. * * A cancel request always overrides any grant that may currently * be in progress. * The calling procedure must check whether the file can be closed. */ |
52921e02a [PATCH] lockd end... |
607 |
__be32 |
1da177e4c Linux-2.6.12-rc2 |
608 609 610 |
nlmsvc_cancel_blocked(struct nlm_file *file, struct nlm_lock *lock) { struct nlm_block *block; |
64a318ee2 NLM: Further canc... |
611 |
int status = 0; |
1da177e4c Linux-2.6.12-rc2 |
612 613 614 |
dprintk("lockd: nlmsvc_cancel(%s/%ld, pi=%d, %Ld-%Ld) ", |
225a719f7 [PATCH] struct pa... |
615 616 |
file->f_file->f_path.dentry->d_inode->i_sb->s_id, file->f_file->f_path.dentry->d_inode->i_ino, |
1da177e4c Linux-2.6.12-rc2 |
617 618 619 |
lock->fl.fl_pid, (long long)lock->fl.fl_start, (long long)lock->fl.fl_end); |
b2b502890 lockd: move grace... |
620 621 |
if (locks_in_grace()) return nlm_lck_denied_grace_period; |
89e63ef60 [PATCH] Convert l... |
622 |
mutex_lock(&file->f_mutex); |
d9f6eb75d lockd: blocks sho... |
623 |
block = nlmsvc_lookup_block(file, lock); |
89e63ef60 [PATCH] Convert l... |
624 |
mutex_unlock(&file->f_mutex); |
d9f6eb75d lockd: blocks sho... |
625 |
if (block != NULL) { |
1a8322b2b lockd: add code t... |
626 627 |
vfs_cancel_lock(block->b_file->f_file, &block->b_call->a_args.lock.fl); |
6849c0cab lockd: Add refcou... |
628 629 630 |
status = nlmsvc_unlink_block(block); nlmsvc_release_block(block); } |
64a318ee2 NLM: Further canc... |
631 |
return status ? nlm_lck_denied : nlm_granted; |
1da177e4c Linux-2.6.12-rc2 |
632 633 634 |
} /* |
0e4ac9d93 lockd: handle fl_... |
635 |
* This is a callback from the filesystem for VFS file lock requests. |
8fb47a4fb locks: rename loc... |
636 |
* It will be used if lm_grant is defined and the filesystem can not |
0e4ac9d93 lockd: handle fl_... |
637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 |
* respond to the request immediately. * For GETLK request it will copy the reply to the nlm_block. * For SETLK or SETLKW request it will get the local posix lock. * In all cases it will move the block to the head of nlm_blocked q where * nlmsvc_retry_blocked() can send back a reply for SETLKW or revisit the * deferred rpc for GETLK and SETLK. */ static void nlmsvc_update_deferred_block(struct nlm_block *block, struct file_lock *conf, int result) { block->b_flags |= B_GOT_CALLBACK; if (result == 0) block->b_granted = 1; else block->b_flags |= B_TIMED_OUT; if (conf) { |
0e4ac9d93 lockd: handle fl_... |
654 |
if (block->b_fl) |
1a747ee0c locks: don't call... |
655 |
__locks_copy_lock(block->b_fl, conf); |
0e4ac9d93 lockd: handle fl_... |
656 657 658 659 660 661 662 663 |
} } static int nlmsvc_grant_deferred(struct file_lock *fl, struct file_lock *conf, int result) { struct nlm_block *block; int rc = -ENOENT; |
f904be9cc lockd: Mostly rem... |
664 |
spin_lock(&nlm_blocked_lock); |
0e4ac9d93 lockd: handle fl_... |
665 666 667 668 669 670 671 672 673 674 675 676 677 |
list_for_each_entry(block, &nlm_blocked, b_list) { if (nlm_compare_locks(&block->b_call->a_args.lock.fl, fl)) { dprintk("lockd: nlmsvc_notify_blocked block %p flags %d ", block, block->b_flags); if (block->b_flags & B_QUEUED) { if (block->b_flags & B_TIMED_OUT) { rc = -ENOLCK; break; } nlmsvc_update_deferred_block(block, conf, result); } else if (result == 0) block->b_granted = 1; |
f904be9cc lockd: Mostly rem... |
678 |
nlmsvc_insert_block_locked(block, 0); |
0e4ac9d93 lockd: handle fl_... |
679 680 681 682 683 |
svc_wake_up(block->b_daemon); rc = 0; break; } } |
f904be9cc lockd: Mostly rem... |
684 |
spin_unlock(&nlm_blocked_lock); |
0e4ac9d93 lockd: handle fl_... |
685 686 687 688 689 690 691 |
if (rc == -ENOENT) printk(KERN_WARNING "lockd: grant for unknown block "); return rc; } /* |
1da177e4c Linux-2.6.12-rc2 |
692 693 694 695 696 697 698 699 700 |
* Unblock a blocked lock request. This is a callback invoked from the * VFS layer when a lock on which we blocked is removed. * * This function doesn't grant the blocked lock instantly, but rather moves * the block to the head of nlm_blocked where it can be picked up by lockd. */ static void nlmsvc_notify_blocked(struct file_lock *fl) { |
68a2d76ce [PATCH] knfsd: lo... |
701 |
struct nlm_block *block; |
1da177e4c Linux-2.6.12-rc2 |
702 703 704 |
dprintk("lockd: VFS unblock notification for block %p ", fl); |
a282a1fa6 lockd: fix nlmsvc... |
705 |
spin_lock(&nlm_blocked_lock); |
68a2d76ce [PATCH] knfsd: lo... |
706 |
list_for_each_entry(block, &nlm_blocked, b_list) { |
92737230d NLM: Add nlmclnt_... |
707 |
if (nlm_compare_locks(&block->b_call->a_args.lock.fl, fl)) { |
a282a1fa6 lockd: fix nlmsvc... |
708 709 |
nlmsvc_insert_block_locked(block, 0); spin_unlock(&nlm_blocked_lock); |
1da177e4c Linux-2.6.12-rc2 |
710 711 712 713 |
svc_wake_up(block->b_daemon); return; } } |
a282a1fa6 lockd: fix nlmsvc... |
714 |
spin_unlock(&nlm_blocked_lock); |
1da177e4c Linux-2.6.12-rc2 |
715 716 717 718 719 720 721 722 |
printk(KERN_WARNING "lockd: notification for unknown block! "); } static int nlmsvc_same_owner(struct file_lock *fl1, struct file_lock *fl2) { return fl1->fl_owner == fl2->fl_owner && fl1->fl_pid == fl2->fl_pid; } |
7b021967c const: make lock_... |
723 |
const struct lock_manager_operations nlmsvc_lock_operations = { |
8fb47a4fb locks: rename loc... |
724 725 726 |
.lm_compare_owner = nlmsvc_same_owner, .lm_notify = nlmsvc_notify_blocked, .lm_grant = nlmsvc_grant_deferred, |
1da177e4c Linux-2.6.12-rc2 |
727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 |
}; /* * Try to claim a lock that was previously blocked. * * Note that we use both the RPC_GRANTED_MSG call _and_ an async * RPC thread when notifying the client. This seems like overkill... * Here's why: * - we don't want to use a synchronous RPC thread, otherwise * we might find ourselves hanging on a dead portmapper. * - Some lockd implementations (e.g. HP) don't react to * RPC_GRANTED calls; they seem to insist on RPC_GRANTED_MSG calls. */ static void nlmsvc_grant_blocked(struct nlm_block *block) { struct nlm_file *file = block->b_file; |
92737230d NLM: Add nlmclnt_... |
744 |
struct nlm_lock *lock = &block->b_call->a_args.lock; |
1da177e4c Linux-2.6.12-rc2 |
745 746 747 748 |
int error; dprintk("lockd: grant blocked lock %p ", block); |
0e4ac9d93 lockd: handle fl_... |
749 |
kref_get(&block->b_count); |
1da177e4c Linux-2.6.12-rc2 |
750 |
/* Unlink block request from list */ |
6849c0cab lockd: Add refcou... |
751 |
nlmsvc_unlink_block(block); |
1da177e4c Linux-2.6.12-rc2 |
752 753 754 755 756 757 758 759 760 761 |
/* If b_granted is true this means we've been here before. * Just retry the grant callback, possibly refreshing the RPC * binding */ if (block->b_granted) { nlm_rebind_host(block->b_host); goto callback; } /* Try the lock operation again */ |
09c7938c5 lockd: Fix server... |
762 |
lock->fl.fl_flags |= FL_SLEEP; |
1a8322b2b lockd: add code t... |
763 |
error = vfs_lock_file(file->f_file, F_SETLK, &lock->fl, NULL); |
09c7938c5 lockd: Fix server... |
764 |
lock->fl.fl_flags &= ~FL_SLEEP; |
5de0e5024 lockd: simplify n... |
765 766 767 |
switch (error) { case 0: break; |
bde74e4bc locks: add specia... |
768 |
case FILE_LOCK_DEFERRED: |
1a8322b2b lockd: add code t... |
769 770 |
dprintk("lockd: lock still blocked error %d ", error); |
1da177e4c Linux-2.6.12-rc2 |
771 |
nlmsvc_insert_block(block, NLM_NEVER); |
0e4ac9d93 lockd: handle fl_... |
772 |
nlmsvc_release_block(block); |
d9f6eb75d lockd: blocks sho... |
773 |
return; |
5de0e5024 lockd: simplify n... |
774 |
default: |
1da177e4c Linux-2.6.12-rc2 |
775 776 |
printk(KERN_WARNING "lockd: unexpected error %d in %s! ", |
8e24eea72 fs: replace remai... |
777 |
-error, __func__); |
1da177e4c Linux-2.6.12-rc2 |
778 |
nlmsvc_insert_block(block, 10 * HZ); |
0e4ac9d93 lockd: handle fl_... |
779 |
nlmsvc_release_block(block); |
d9f6eb75d lockd: blocks sho... |
780 |
return; |
1da177e4c Linux-2.6.12-rc2 |
781 782 783 784 785 786 787 |
} callback: /* Lock was granted by VFS. */ dprintk("lockd: GRANTing blocked lock. "); block->b_granted = 1; |
1da177e4c Linux-2.6.12-rc2 |
788 |
|
9706501e4 NLM: don't reatte... |
789 790 791 792 |
/* keep block on the list, but don't reattempt until the RPC * completes or the submission fails */ nlmsvc_insert_block(block, NLM_NEVER); |
1da177e4c Linux-2.6.12-rc2 |
793 |
|
9706501e4 NLM: don't reatte... |
794 795 796 797 798 799 800 801 802 |
/* Call the client -- use a soft RPC task since nlmsvc_retry_blocked * will queue up a new one if this one times out */ error = nlm_async_call(block->b_call, NLMPROC_GRANTED_MSG, &nlmsvc_grant_ops); /* RPC submission failed, wait a bit and retry */ if (error < 0) nlmsvc_insert_block(block, 10 * HZ); |
1da177e4c Linux-2.6.12-rc2 |
803 804 805 806 807 808 809 810 811 812 |
} /* * This is the callback from the RPC layer when the NLM_GRANTED_MSG * RPC call has succeeded or timed out. * Like all RPC callbacks, it is invoked by the rpciod process, so it * better not sleep. Therefore, we put the blocked lock on the nlm_blocked * chain once more in order to have it removed by lockd itself (which can * then sleep on the file semaphore without disrupting e.g. the nfs client). */ |
963d8fe53 RPC: Clean up RPC... |
813 |
static void nlmsvc_grant_callback(struct rpc_task *task, void *data) |
1da177e4c Linux-2.6.12-rc2 |
814 |
{ |
963d8fe53 RPC: Clean up RPC... |
815 |
struct nlm_rqst *call = data; |
92737230d NLM: Add nlmclnt_... |
816 |
struct nlm_block *block = call->a_block; |
1da177e4c Linux-2.6.12-rc2 |
817 |
unsigned long timeout; |
1da177e4c Linux-2.6.12-rc2 |
818 819 820 |
dprintk("lockd: GRANT_MSG RPC callback "); |
1da177e4c Linux-2.6.12-rc2 |
821 |
|
f904be9cc lockd: Mostly rem... |
822 |
spin_lock(&nlm_blocked_lock); |
c64e80d55 NLM: don't requeu... |
823 824 825 826 827 828 829 830 831 |
/* if the block is not on a list at this point then it has * been invalidated. Don't try to requeue it. * * FIXME: it's possible that the block is removed from the list * after this check but before the nlmsvc_insert_block. In that * case it will be added back. Perhaps we need better locking * for nlm_blocked? */ if (list_empty(&block->b_list)) |
a86dc496b SUNRPC: Remove th... |
832 |
goto out; |
c64e80d55 NLM: don't requeu... |
833 |
|
1da177e4c Linux-2.6.12-rc2 |
834 835 836 837 838 839 |
/* Technically, we should down the file semaphore here. Since we * move the block towards the head of the queue only, no harm * can be done, though. */ if (task->tk_status < 0) { /* RPC error: Re-insert for retransmission */ timeout = 10 * HZ; |
1da177e4c Linux-2.6.12-rc2 |
840 841 842 843 |
} else { /* Call was successful, now wait for client callback */ timeout = 60 * HZ; } |
f904be9cc lockd: Mostly rem... |
844 |
nlmsvc_insert_block_locked(block, timeout); |
1da177e4c Linux-2.6.12-rc2 |
845 |
svc_wake_up(block->b_daemon); |
a86dc496b SUNRPC: Remove th... |
846 |
out: |
f904be9cc lockd: Mostly rem... |
847 |
spin_unlock(&nlm_blocked_lock); |
5e1abf8cb lockd: Clean up o... |
848 |
} |
f904be9cc lockd: Mostly rem... |
849 850 851 852 |
/* * FIXME: nlmsvc_release_block() grabs a mutex. This is not allowed for an * .rpc_release rpc_call_op */ |
ec535ce15 NFS: make 2 funct... |
853 |
static void nlmsvc_grant_release(void *data) |
5e1abf8cb lockd: Clean up o... |
854 |
{ |
6041b7919 lockd: Fix a typo... |
855 |
struct nlm_rqst *call = data; |
6041b7919 lockd: Fix a typo... |
856 |
nlmsvc_release_block(call->a_block); |
1da177e4c Linux-2.6.12-rc2 |
857 |
} |
963d8fe53 RPC: Clean up RPC... |
858 859 |
static const struct rpc_call_ops nlmsvc_grant_ops = { .rpc_call_done = nlmsvc_grant_callback, |
5e1abf8cb lockd: Clean up o... |
860 |
.rpc_release = nlmsvc_grant_release, |
963d8fe53 RPC: Clean up RPC... |
861 |
}; |
1da177e4c Linux-2.6.12-rc2 |
862 863 864 865 866 |
/* * We received a GRANT_RES callback. Try to find the corresponding * block. */ void |
e8c5c045d [PATCH] lockd end... |
867 |
nlmsvc_grant_reply(struct nlm_cookie *cookie, __be32 status) |
1da177e4c Linux-2.6.12-rc2 |
868 869 |
{ struct nlm_block *block; |
1da177e4c Linux-2.6.12-rc2 |
870 |
|
39be4502c [PATCH] knfsd: ma... |
871 872 873 874 |
dprintk("grant_reply: looking for cookie %x, s=%d ", *(unsigned int *)(cookie->data), status); if (!(block = nlmsvc_find_block(cookie))) |
1da177e4c Linux-2.6.12-rc2 |
875 |
return; |
1da177e4c Linux-2.6.12-rc2 |
876 |
|
f232142cc NLM: Clean up nlm... |
877 |
if (block) { |
e8c5c045d [PATCH] lockd end... |
878 |
if (status == nlm_lck_denied_grace_period) { |
1da177e4c Linux-2.6.12-rc2 |
879 880 |
/* Try again in a couple of seconds */ nlmsvc_insert_block(block, 10 * HZ); |
1da177e4c Linux-2.6.12-rc2 |
881 882 883 |
} else { /* Lock is now held by client, or has been rejected. * In both cases, the block should be removed. */ |
6849c0cab lockd: Add refcou... |
884 |
nlmsvc_unlink_block(block); |
1da177e4c Linux-2.6.12-rc2 |
885 886 |
} } |
6849c0cab lockd: Add refcou... |
887 |
nlmsvc_release_block(block); |
1da177e4c Linux-2.6.12-rc2 |
888 |
} |
0e4ac9d93 lockd: handle fl_... |
889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 |
/* Helper function to handle retry of a deferred block. * If it is a blocking lock, call grant_blocked. * For a non-blocking lock or test lock, revisit the request. */ static void retry_deferred_block(struct nlm_block *block) { if (!(block->b_flags & B_GOT_CALLBACK)) block->b_flags |= B_TIMED_OUT; nlmsvc_insert_block(block, NLM_TIMEOUT); dprintk("revisit block %p flags %d ", block, block->b_flags); if (block->b_deferred_req) { block->b_deferred_req->revisit(block->b_deferred_req, 0); block->b_deferred_req = NULL; } } |
1da177e4c Linux-2.6.12-rc2 |
906 907 908 909 910 911 912 913 |
/* * Retry all blocked locks that have been notified. This is where lockd * picks up locks that can be granted, or grant notifications that must * be retransmitted. */ unsigned long nlmsvc_retry_blocked(void) { |
68a2d76ce [PATCH] knfsd: lo... |
914 915 |
unsigned long timeout = MAX_SCHEDULE_TIMEOUT; struct nlm_block *block; |
d751a7cd0 NLM: Convert lock... |
916 |
while (!list_empty(&nlm_blocked) && !kthread_should_stop()) { |
68a2d76ce [PATCH] knfsd: lo... |
917 |
block = list_entry(nlm_blocked.next, struct nlm_block, b_list); |
1da177e4c Linux-2.6.12-rc2 |
918 |
|
1da177e4c Linux-2.6.12-rc2 |
919 920 |
if (block->b_when == NLM_NEVER) break; |
6d7bbbbac lockd: minor svcl... |
921 |
if (time_after(block->b_when, jiffies)) { |
68a2d76ce [PATCH] knfsd: lo... |
922 |
timeout = block->b_when - jiffies; |
1da177e4c Linux-2.6.12-rc2 |
923 |
break; |
68a2d76ce [PATCH] knfsd: lo... |
924 |
} |
f3d43c769 NLM/lockd: remove... |
925 926 927 |
dprintk("nlmsvc_retry_blocked(%p, when=%ld) ", block, block->b_when); |
0e4ac9d93 lockd: handle fl_... |
928 929 930 931 932 933 934 |
if (block->b_flags & B_QUEUED) { dprintk("nlmsvc_retry_blocked delete block (%p, granted=%d, flags=%d) ", block, block->b_granted, block->b_flags); retry_deferred_block(block); } else nlmsvc_grant_blocked(block); |
1da177e4c Linux-2.6.12-rc2 |
935 |
} |
68a2d76ce [PATCH] knfsd: lo... |
936 |
return timeout; |
1da177e4c Linux-2.6.12-rc2 |
937 |
} |
d8367c504 lockd: Move nlmdb... |
938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 |
#ifdef RPC_DEBUG static const char *nlmdbg_cookie2a(const struct nlm_cookie *cookie) { /* * We can get away with a static buffer because we're only * called with BKL held. */ static char buf[2*NLM_MAXCOOKIELEN+1]; unsigned int i, len = sizeof(buf); char *p = buf; len--; /* allow for trailing \0 */ if (len < 3) return "???"; for (i = 0 ; i < cookie->len ; i++) { if (len < 2) { strcpy(p-3, "..."); break; } sprintf(p, "%02x", cookie->data[i]); p += 2; len -= 2; } *p = '\0'; return buf; } #endif |