Lines Matching full:block
42 static void nlmsvc_release_block(struct nlm_block *block);
43 static void nlmsvc_insert_block(struct nlm_block *block, unsigned long);
44 static void nlmsvc_remove_block(struct nlm_block *block);
61 nlmsvc_insert_block_locked(struct nlm_block *block, unsigned long when) in nlmsvc_insert_block_locked() argument
66 dprintk("lockd: nlmsvc_insert_block(%p, %ld)\n", block, when); in nlmsvc_insert_block_locked()
67 if (list_empty(&block->b_list)) { in nlmsvc_insert_block_locked()
68 kref_get(&block->b_count); in nlmsvc_insert_block_locked()
70 list_del_init(&block->b_list); in nlmsvc_insert_block_locked()
87 list_add_tail(&block->b_list, pos); in nlmsvc_insert_block_locked()
88 block->b_when = when; in nlmsvc_insert_block_locked()
91 static void nlmsvc_insert_block(struct nlm_block *block, unsigned long when) in nlmsvc_insert_block() argument
94 nlmsvc_insert_block_locked(block, when); in nlmsvc_insert_block()
99 * Remove a block from the global list
102 nlmsvc_remove_block(struct nlm_block *block) in nlmsvc_remove_block() argument
104 if (!list_empty(&block->b_list)) { in nlmsvc_remove_block()
106 list_del_init(&block->b_list); in nlmsvc_remove_block()
108 nlmsvc_release_block(block); in nlmsvc_remove_block()
113 * Find a block for a given lock
118 struct nlm_block *block; in nlmsvc_lookup_block() local
125 list_for_each_entry(block, &nlm_blocked, b_list) { in nlmsvc_lookup_block()
126 fl = &block->b_call->a_args.lock.fl; in nlmsvc_lookup_block()
128 block->b_file, fl->fl_pid, in nlmsvc_lookup_block()
131 nlmdbg_cookie2a(&block->b_call->a_args.cookie)); in nlmsvc_lookup_block()
132 if (block->b_file == file && nlm_compare_locks(fl, &lock->fl)) { in nlmsvc_lookup_block()
133 kref_get(&block->b_count); in nlmsvc_lookup_block()
134 return block; in nlmsvc_lookup_block()
151 * Find a block with a given NLM cookie.
156 struct nlm_block *block; in nlmsvc_find_block() local
158 list_for_each_entry(block, &nlm_blocked, b_list) { in nlmsvc_find_block()
159 if (nlm_cookie_match(&block->b_call->a_args.cookie,cookie)) in nlmsvc_find_block()
166 dprintk("nlmsvc_find_block(%s): block=%p\n", nlmdbg_cookie2a(cookie), block); in nlmsvc_find_block()
167 kref_get(&block->b_count); in nlmsvc_find_block()
168 return block; in nlmsvc_find_block()
172 * Create a block and initialize it.
191 struct nlm_block *block; in nlmsvc_create_block() local
199 /* Allocate memory for block, and initialize arguments */ in nlmsvc_create_block()
200 block = kzalloc(sizeof(*block), GFP_KERNEL); in nlmsvc_create_block()
201 if (block == NULL) in nlmsvc_create_block()
203 kref_init(&block->b_count); in nlmsvc_create_block()
204 INIT_LIST_HEAD(&block->b_list); in nlmsvc_create_block()
205 INIT_LIST_HEAD(&block->b_flist); in nlmsvc_create_block()
215 dprintk("lockd: created block %p...\n", block); in nlmsvc_create_block()
217 /* Create and initialize the block */ in nlmsvc_create_block()
218 block->b_daemon = rqstp->rq_server; in nlmsvc_create_block()
219 block->b_host = host; in nlmsvc_create_block()
220 block->b_file = file; in nlmsvc_create_block()
221 block->b_fl = NULL; in nlmsvc_create_block()
225 list_add(&block->b_flist, &file->f_blocks); in nlmsvc_create_block()
228 block->b_call = call; in nlmsvc_create_block()
230 call->a_block = block; in nlmsvc_create_block()
232 return block; in nlmsvc_create_block()
235 kfree(block); in nlmsvc_create_block()
242 * Delete a block.
246 static int nlmsvc_unlink_block(struct nlm_block *block) in nlmsvc_unlink_block() argument
249 dprintk("lockd: unlinking block %p...\n", block); in nlmsvc_unlink_block()
251 /* Remove block from list */ in nlmsvc_unlink_block()
252 status = posix_unblock_lock(block->b_file->f_file, &block->b_call->a_args.lock.fl); in nlmsvc_unlink_block()
253 nlmsvc_remove_block(block); in nlmsvc_unlink_block()
259 struct nlm_block *block = container_of(kref, struct nlm_block, b_count); in nlmsvc_free_block() local
260 struct nlm_file *file = block->b_file; in nlmsvc_free_block()
262 dprintk("lockd: freeing block %p...\n", block); in nlmsvc_free_block()
264 /* Remove block from file's list of blocks */ in nlmsvc_free_block()
266 list_del_init(&block->b_flist); in nlmsvc_free_block()
269 nlmsvc_freegrantargs(block->b_call); in nlmsvc_free_block()
270 nlmsvc_release_call(block->b_call); in nlmsvc_free_block()
271 nlm_release_file(block->b_file); in nlmsvc_free_block()
272 kfree(block->b_fl); in nlmsvc_free_block()
273 kfree(block); in nlmsvc_free_block()
276 static void nlmsvc_release_block(struct nlm_block *block) in nlmsvc_release_block() argument
278 if (block != NULL) in nlmsvc_release_block()
279 kref_put(&block->b_count, nlmsvc_free_block); in nlmsvc_release_block()
290 struct nlm_block *block, *next; in nlmsvc_traverse_blocks() local
294 list_for_each_entry_safe(block, next, &file->f_blocks, b_flist) { in nlmsvc_traverse_blocks()
295 if (!match(block->b_host, host)) in nlmsvc_traverse_blocks()
299 if (list_empty(&block->b_list)) in nlmsvc_traverse_blocks()
301 kref_get(&block->b_count); in nlmsvc_traverse_blocks()
303 nlmsvc_unlink_block(block); in nlmsvc_traverse_blocks()
304 nlmsvc_release_block(block); in nlmsvc_traverse_blocks()
348 nlmsvc_defer_lock_rqst(struct svc_rqst *rqstp, struct nlm_block *block) in nlmsvc_defer_lock_rqst() argument
352 block->b_flags |= B_QUEUED; in nlmsvc_defer_lock_rqst()
354 nlmsvc_insert_block(block, NLM_TIMEOUT); in nlmsvc_defer_lock_rqst()
356 block->b_cache_req = &rqstp->rq_chandle; in nlmsvc_defer_lock_rqst()
358 block->b_deferred_req = in nlmsvc_defer_lock_rqst()
359 rqstp->rq_chandle.defer(block->b_cache_req); in nlmsvc_defer_lock_rqst()
360 if (block->b_deferred_req != NULL) in nlmsvc_defer_lock_rqst()
363 dprintk("lockd: nlmsvc_defer_lock_rqst block %p flags %d status %d\n", in nlmsvc_defer_lock_rqst()
364 block, block->b_flags, ntohl(status)); in nlmsvc_defer_lock_rqst()
370 * Attempt to establish a lock, and if it can't be granted, block it
378 struct nlm_block *block = NULL; in nlmsvc_lock() local
392 /* Get existing block (in case client is busy-waiting) in nlmsvc_lock()
393 * or create new block in nlmsvc_lock()
395 block = nlmsvc_lookup_block(file, lock); in nlmsvc_lock()
396 if (block == NULL) { in nlmsvc_lock()
397 block = nlmsvc_create_block(rqstp, host, file, lock, cookie); in nlmsvc_lock()
399 if (block == NULL) in nlmsvc_lock()
401 lock = &block->b_call->a_args.lock; in nlmsvc_lock()
405 if (block->b_flags & B_QUEUED) { in nlmsvc_lock()
406 dprintk("lockd: nlmsvc_lock deferred block %p flags %d\n", in nlmsvc_lock()
407 block, block->b_flags); in nlmsvc_lock()
408 if (block->b_granted) { in nlmsvc_lock()
409 nlmsvc_unlink_block(block); in nlmsvc_lock()
413 if (block->b_flags & B_TIMED_OUT) { in nlmsvc_lock()
414 nlmsvc_unlink_block(block); in nlmsvc_lock()
445 * to put it back on lockd's block list in nlmsvc_lock()
456 ret = nlmsvc_defer_lock_rqst(rqstp, block); in nlmsvc_lock()
469 nlmsvc_insert_block(block, NLM_NEVER); in nlmsvc_lock()
472 nlmsvc_release_block(block); in nlmsvc_lock()
485 struct nlm_block *block = NULL; in nlmsvc_testlock() local
496 /* Get existing block (in case client is busy-waiting) */ in nlmsvc_testlock()
497 block = nlmsvc_lookup_block(file, lock); in nlmsvc_testlock()
499 if (block == NULL) { in nlmsvc_testlock()
504 block = nlmsvc_create_block(rqstp, host, file, lock, cookie); in nlmsvc_testlock()
505 if (block == NULL) { in nlmsvc_testlock()
509 block->b_fl = conf; in nlmsvc_testlock()
511 if (block->b_flags & B_QUEUED) { in nlmsvc_testlock()
512 dprintk("lockd: nlmsvc_testlock deferred block %p flags %d fl %p\n", in nlmsvc_testlock()
513 block, block->b_flags, block->b_fl); in nlmsvc_testlock()
514 if (block->b_flags & B_TIMED_OUT) { in nlmsvc_testlock()
515 nlmsvc_unlink_block(block); in nlmsvc_testlock()
519 if (block->b_flags & B_GOT_CALLBACK) { in nlmsvc_testlock()
520 nlmsvc_unlink_block(block); in nlmsvc_testlock()
521 if (block->b_fl != NULL in nlmsvc_testlock()
522 && block->b_fl->fl_type != F_UNLCK) { in nlmsvc_testlock()
523 lock->fl = *block->b_fl; in nlmsvc_testlock()
540 ret = nlmsvc_defer_lock_rqst(rqstp, block); in nlmsvc_testlock()
565 if (block) in nlmsvc_testlock()
566 nlmsvc_release_block(block); in nlmsvc_testlock()
574 * afterwards. In this case the block will still be there, and hence
608 struct nlm_block *block; in nlmsvc_cancel_blocked() local
622 block = nlmsvc_lookup_block(file, lock); in nlmsvc_cancel_blocked()
624 if (block != NULL) { in nlmsvc_cancel_blocked()
625 vfs_cancel_lock(block->b_file->f_file, in nlmsvc_cancel_blocked()
626 &block->b_call->a_args.lock.fl); in nlmsvc_cancel_blocked()
627 status = nlmsvc_unlink_block(block); in nlmsvc_cancel_blocked()
628 nlmsvc_release_block(block); in nlmsvc_cancel_blocked()
639 * In all cases it will move the block to the head of nlm_blocked q where
644 nlmsvc_update_deferred_block(struct nlm_block *block, struct file_lock *conf, in nlmsvc_update_deferred_block() argument
647 block->b_flags |= B_GOT_CALLBACK; in nlmsvc_update_deferred_block()
649 block->b_granted = 1; in nlmsvc_update_deferred_block()
651 block->b_flags |= B_TIMED_OUT; in nlmsvc_update_deferred_block()
653 if (block->b_fl) in nlmsvc_update_deferred_block()
654 __locks_copy_lock(block->b_fl, conf); in nlmsvc_update_deferred_block()
661 struct nlm_block *block; in nlmsvc_grant_deferred() local
665 list_for_each_entry(block, &nlm_blocked, b_list) { in nlmsvc_grant_deferred()
666 if (nlm_compare_locks(&block->b_call->a_args.lock.fl, fl)) { in nlmsvc_grant_deferred()
667 dprintk("lockd: nlmsvc_notify_blocked block %p flags %d\n", in nlmsvc_grant_deferred()
668 block, block->b_flags); in nlmsvc_grant_deferred()
669 if (block->b_flags & B_QUEUED) { in nlmsvc_grant_deferred()
670 if (block->b_flags & B_TIMED_OUT) { in nlmsvc_grant_deferred()
674 nlmsvc_update_deferred_block(block, conf, result); in nlmsvc_grant_deferred()
676 block->b_granted = 1; in nlmsvc_grant_deferred()
678 nlmsvc_insert_block_locked(block, 0); in nlmsvc_grant_deferred()
679 svc_wake_up(block->b_daemon); in nlmsvc_grant_deferred()
686 printk(KERN_WARNING "lockd: grant for unknown block\n"); in nlmsvc_grant_deferred()
695 * the block to the head of nlm_blocked where it can be picked up by lockd.
700 struct nlm_block *block; in nlmsvc_notify_blocked() local
702 dprintk("lockd: VFS unblock notification for block %p\n", fl); in nlmsvc_notify_blocked()
704 list_for_each_entry(block, &nlm_blocked, b_list) { in nlmsvc_notify_blocked()
705 if (nlm_compare_locks(&block->b_call->a_args.lock.fl, fl)) { in nlmsvc_notify_blocked()
706 nlmsvc_insert_block_locked(block, 0); in nlmsvc_notify_blocked()
708 svc_wake_up(block->b_daemon); in nlmsvc_notify_blocked()
713 printk(KERN_WARNING "lockd: notification for unknown block!\n"); in nlmsvc_notify_blocked()
739 nlmsvc_grant_blocked(struct nlm_block *block) in nlmsvc_grant_blocked() argument
741 struct nlm_file *file = block->b_file; in nlmsvc_grant_blocked()
742 struct nlm_lock *lock = &block->b_call->a_args.lock; in nlmsvc_grant_blocked()
745 dprintk("lockd: grant blocked lock %p\n", block); in nlmsvc_grant_blocked()
747 kref_get(&block->b_count); in nlmsvc_grant_blocked()
749 /* Unlink block request from list */ in nlmsvc_grant_blocked()
750 nlmsvc_unlink_block(block); in nlmsvc_grant_blocked()
755 if (block->b_granted) { in nlmsvc_grant_blocked()
756 nlm_rebind_host(block->b_host); in nlmsvc_grant_blocked()
770 nlmsvc_insert_block(block, NLM_NEVER); in nlmsvc_grant_blocked()
771 nlmsvc_release_block(block); in nlmsvc_grant_blocked()
776 nlmsvc_insert_block(block, 10 * HZ); in nlmsvc_grant_blocked()
777 nlmsvc_release_block(block); in nlmsvc_grant_blocked()
784 block->b_granted = 1; in nlmsvc_grant_blocked()
786 /* keep block on the list, but don't reattempt until the RPC in nlmsvc_grant_blocked()
789 nlmsvc_insert_block(block, NLM_NEVER); in nlmsvc_grant_blocked()
794 error = nlm_async_call(block->b_call, NLMPROC_GRANTED_MSG, in nlmsvc_grant_blocked()
799 nlmsvc_insert_block(block, 10 * HZ); in nlmsvc_grant_blocked()
813 struct nlm_block *block = call->a_block; in nlmsvc_grant_callback() local
819 /* if the block is not on a list at this point then it has in nlmsvc_grant_callback()
822 * FIXME: it's possible that the block is removed from the list in nlmsvc_grant_callback()
827 if (list_empty(&block->b_list)) in nlmsvc_grant_callback()
831 * move the block towards the head of the queue only, no harm in nlmsvc_grant_callback()
840 nlmsvc_insert_block_locked(block, timeout); in nlmsvc_grant_callback()
841 svc_wake_up(block->b_daemon); in nlmsvc_grant_callback()
863 * block.
868 struct nlm_block *block; in nlmsvc_grant_reply() local
872 if (!(block = nlmsvc_find_block(cookie))) in nlmsvc_grant_reply()
875 if (block) { in nlmsvc_grant_reply()
878 nlmsvc_insert_block(block, 10 * HZ); in nlmsvc_grant_reply()
881 * In both cases, the block should be removed. */ in nlmsvc_grant_reply()
882 nlmsvc_unlink_block(block); in nlmsvc_grant_reply()
885 nlmsvc_release_block(block); in nlmsvc_grant_reply()
888 /* Helper function to handle retry of a deferred block.
893 retry_deferred_block(struct nlm_block *block) in retry_deferred_block() argument
895 if (!(block->b_flags & B_GOT_CALLBACK)) in retry_deferred_block()
896 block->b_flags |= B_TIMED_OUT; in retry_deferred_block()
897 nlmsvc_insert_block(block, NLM_TIMEOUT); in retry_deferred_block()
898 dprintk("revisit block %p flags %d\n", block, block->b_flags); in retry_deferred_block()
899 if (block->b_deferred_req) { in retry_deferred_block()
900 block->b_deferred_req->revisit(block->b_deferred_req, 0); in retry_deferred_block()
901 block->b_deferred_req = NULL; in retry_deferred_block()
914 struct nlm_block *block; in nlmsvc_retry_blocked() local
917 block = list_entry(nlm_blocked.next, struct nlm_block, b_list); in nlmsvc_retry_blocked()
919 if (block->b_when == NLM_NEVER) in nlmsvc_retry_blocked()
921 if (time_after(block->b_when, jiffies)) { in nlmsvc_retry_blocked()
922 timeout = block->b_when - jiffies; in nlmsvc_retry_blocked()
927 block, block->b_when); in nlmsvc_retry_blocked()
928 if (block->b_flags & B_QUEUED) { in nlmsvc_retry_blocked()
929 dprintk("nlmsvc_retry_blocked delete block (%p, granted=%d, flags=%d)\n", in nlmsvc_retry_blocked()
930 block, block->b_granted, block->b_flags); in nlmsvc_retry_blocked()
931 retry_deferred_block(block); in nlmsvc_retry_blocked()
933 nlmsvc_grant_blocked(block); in nlmsvc_retry_blocked()