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);
89 nlmsvc_insert_block_locked(struct nlm_block *block, unsigned long when) in nlmsvc_insert_block_locked() argument
94 dprintk("lockd: nlmsvc_insert_block(%p, %ld)\n", block, when); in nlmsvc_insert_block_locked()
95 if (list_empty(&block->b_list)) { in nlmsvc_insert_block_locked()
96 kref_get(&block->b_count); in nlmsvc_insert_block_locked()
98 list_del_init(&block->b_list); in nlmsvc_insert_block_locked()
115 list_add_tail(&block->b_list, pos); in nlmsvc_insert_block_locked()
116 block->b_when = when; in nlmsvc_insert_block_locked()
119 static void nlmsvc_insert_block(struct nlm_block *block, unsigned long when) in nlmsvc_insert_block() argument
122 nlmsvc_insert_block_locked(block, when); in nlmsvc_insert_block()
127 * Remove a block from the global list
130 nlmsvc_remove_block(struct nlm_block *block) in nlmsvc_remove_block() argument
133 if (!list_empty(&block->b_list)) { in nlmsvc_remove_block()
134 list_del_init(&block->b_list); in nlmsvc_remove_block()
136 nlmsvc_release_block(block); in nlmsvc_remove_block()
143 * Find a block for a given lock
148 struct nlm_block *block; in nlmsvc_lookup_block() local
157 list_for_each_entry(block, &nlm_blocked, b_list) { in nlmsvc_lookup_block()
158 fl = &block->b_call->a_args.lock.fl; in nlmsvc_lookup_block()
160 block->b_file, fl->c.flc_pid, in nlmsvc_lookup_block()
163 nlmdbg_cookie2a(&block->b_call->a_args.cookie)); in nlmsvc_lookup_block()
164 if (block->b_file == file && nlm_compare_locks(fl, &lock->fl)) { in nlmsvc_lookup_block()
165 kref_get(&block->b_count); in nlmsvc_lookup_block()
167 return block; in nlmsvc_lookup_block()
185 * Find a block with a given NLM cookie.
190 struct nlm_block *block; in nlmsvc_find_block() local
193 list_for_each_entry(block, &nlm_blocked, b_list) { in nlmsvc_find_block()
194 if (nlm_cookie_match(&block->b_call->a_args.cookie,cookie)) in nlmsvc_find_block()
202 dprintk("nlmsvc_find_block(%s): block=%p\n", nlmdbg_cookie2a(cookie), block); in nlmsvc_find_block()
203 kref_get(&block->b_count); in nlmsvc_find_block()
205 return block; in nlmsvc_find_block()
209 * Create a block and initialize it.
228 struct nlm_block *block; in nlmsvc_create_block() local
235 /* Allocate memory for block, and initialize arguments */ in nlmsvc_create_block()
236 block = kzalloc(sizeof(*block), GFP_KERNEL); in nlmsvc_create_block()
237 if (block == NULL) in nlmsvc_create_block()
239 kref_init(&block->b_count); in nlmsvc_create_block()
240 INIT_LIST_HEAD(&block->b_list); in nlmsvc_create_block()
241 INIT_LIST_HEAD(&block->b_flist); in nlmsvc_create_block()
251 dprintk("lockd: created block %p...\n", block); in nlmsvc_create_block()
253 /* Create and initialize the block */ in nlmsvc_create_block()
254 block->b_daemon = rqstp->rq_server; in nlmsvc_create_block()
255 block->b_host = host; in nlmsvc_create_block()
256 block->b_file = file; in nlmsvc_create_block()
260 list_add(&block->b_flist, &file->f_blocks); in nlmsvc_create_block()
263 block->b_call = call; in nlmsvc_create_block()
265 call->a_block = block; in nlmsvc_create_block()
267 return block; in nlmsvc_create_block()
270 kfree(block); in nlmsvc_create_block()
277 * Delete a block.
281 static int nlmsvc_unlink_block(struct nlm_block *block) in nlmsvc_unlink_block() argument
284 dprintk("lockd: unlinking block %p...\n", block); in nlmsvc_unlink_block()
286 /* Remove block from list */ in nlmsvc_unlink_block()
287 status = locks_delete_block(&block->b_call->a_args.lock.fl); in nlmsvc_unlink_block()
288 nlmsvc_remove_block(block); in nlmsvc_unlink_block()
294 struct nlm_block *block = container_of(kref, struct nlm_block, b_count); in nlmsvc_free_block() local
295 struct nlm_file *file = block->b_file; in nlmsvc_free_block()
297 dprintk("lockd: freeing block %p...\n", block); in nlmsvc_free_block()
299 /* Remove block from file's list of blocks */ in nlmsvc_free_block()
300 list_del_init(&block->b_flist); in nlmsvc_free_block()
303 nlmsvc_freegrantargs(block->b_call); in nlmsvc_free_block()
304 nlmsvc_release_call(block->b_call); in nlmsvc_free_block()
305 nlm_release_file(block->b_file); in nlmsvc_free_block()
306 kfree(block); in nlmsvc_free_block()
309 static void nlmsvc_release_block(struct nlm_block *block) in nlmsvc_release_block() argument
311 if (block != NULL) in nlmsvc_release_block()
312 kref_put_mutex(&block->b_count, nlmsvc_free_block, &block->b_file->f_mutex); in nlmsvc_release_block()
323 struct nlm_block *block, *next; in nlmsvc_traverse_blocks() local
328 list_for_each_entry_safe(block, next, &file->f_blocks, b_flist) { in nlmsvc_traverse_blocks()
329 if (!match(block->b_host, host)) in nlmsvc_traverse_blocks()
333 if (list_empty(&block->b_list)) in nlmsvc_traverse_blocks()
335 kref_get(&block->b_count); in nlmsvc_traverse_blocks()
338 nlmsvc_unlink_block(block); in nlmsvc_traverse_blocks()
339 nlmsvc_release_block(block); in nlmsvc_traverse_blocks()
453 nlmsvc_defer_lock_rqst(struct svc_rqst *rqstp, struct nlm_block *block) in nlmsvc_defer_lock_rqst() argument
457 block->b_flags |= B_QUEUED; in nlmsvc_defer_lock_rqst()
459 nlmsvc_insert_block(block, NLM_TIMEOUT); in nlmsvc_defer_lock_rqst()
461 block->b_cache_req = &rqstp->rq_chandle; in nlmsvc_defer_lock_rqst()
463 block->b_deferred_req = in nlmsvc_defer_lock_rqst()
464 rqstp->rq_chandle.defer(block->b_cache_req); in nlmsvc_defer_lock_rqst()
465 if (block->b_deferred_req != NULL) in nlmsvc_defer_lock_rqst()
468 dprintk("lockd: nlmsvc_defer_lock_rqst block %p flags %d status %d\n", in nlmsvc_defer_lock_rqst()
469 block, block->b_flags, ntohl(status)); in nlmsvc_defer_lock_rqst()
475 * Attempt to establish a lock, and if it can't be granted, block it
484 struct nlm_block *block = NULL; in nlmsvc_lock() local
505 /* Get existing block (in case client is busy-waiting) in nlmsvc_lock()
506 * or create new block in nlmsvc_lock()
508 block = nlmsvc_lookup_block(file, lock); in nlmsvc_lock()
509 if (block == NULL) { in nlmsvc_lock()
510 block = nlmsvc_create_block(rqstp, host, file, lock, cookie); in nlmsvc_lock()
512 if (block == NULL) in nlmsvc_lock()
514 lock = &block->b_call->a_args.lock; in nlmsvc_lock()
518 if (block->b_flags & B_QUEUED) { in nlmsvc_lock()
519 dprintk("lockd: nlmsvc_lock deferred block %p flags %d\n", in nlmsvc_lock()
520 block, block->b_flags); in nlmsvc_lock()
521 if (block->b_granted) { in nlmsvc_lock()
522 nlmsvc_unlink_block(block); in nlmsvc_lock()
526 if (block->b_flags & B_TIMED_OUT) { in nlmsvc_lock()
527 nlmsvc_unlink_block(block); in nlmsvc_lock()
553 !list_empty(&block->b_list)) { in nlmsvc_lock()
560 nlmsvc_insert_block_locked(block, NLM_NEVER); in nlmsvc_lock()
572 nlmsvc_remove_block(block); in nlmsvc_lock()
577 nlmsvc_remove_block(block); in nlmsvc_lock()
585 ret = nlmsvc_defer_lock_rqst(rqstp, block); in nlmsvc_lock()
588 nlmsvc_remove_block(block); in nlmsvc_lock()
592 nlmsvc_remove_block(block); in nlmsvc_lock()
600 nlmsvc_release_block(block); in nlmsvc_lock()
666 * afterwards. In this case the block will still be there, and hence
707 struct nlm_block *block; in nlmsvc_cancel_blocked() local
722 block = nlmsvc_lookup_block(file, lock); in nlmsvc_cancel_blocked()
724 if (block != NULL) { in nlmsvc_cancel_blocked()
725 struct file_lock *fl = &block->b_call->a_args.lock.fl; in nlmsvc_cancel_blocked()
728 vfs_cancel_lock(block->b_file->f_file[mode], fl); in nlmsvc_cancel_blocked()
729 status = nlmsvc_unlink_block(block); in nlmsvc_cancel_blocked()
730 nlmsvc_release_block(block); in nlmsvc_cancel_blocked()
740 * In all cases it will move the block to the head of nlm_blocked q where
745 nlmsvc_update_deferred_block(struct nlm_block *block, int result) in nlmsvc_update_deferred_block() argument
747 block->b_flags |= B_GOT_CALLBACK; in nlmsvc_update_deferred_block()
749 block->b_granted = 1; in nlmsvc_update_deferred_block()
751 block->b_flags |= B_TIMED_OUT; in nlmsvc_update_deferred_block()
756 struct nlm_block *block; in nlmsvc_grant_deferred() local
760 list_for_each_entry(block, &nlm_blocked, b_list) { in nlmsvc_grant_deferred()
761 if (nlm_compare_locks(&block->b_call->a_args.lock.fl, fl)) { in nlmsvc_grant_deferred()
762 dprintk("lockd: nlmsvc_notify_blocked block %p flags %d\n", in nlmsvc_grant_deferred()
763 block, block->b_flags); in nlmsvc_grant_deferred()
764 if (block->b_flags & B_QUEUED) { in nlmsvc_grant_deferred()
765 if (block->b_flags & B_TIMED_OUT) { in nlmsvc_grant_deferred()
769 nlmsvc_update_deferred_block(block, result); in nlmsvc_grant_deferred()
771 block->b_granted = 1; in nlmsvc_grant_deferred()
773 nlmsvc_insert_block_locked(block, 0); in nlmsvc_grant_deferred()
774 svc_wake_up(block->b_daemon); in nlmsvc_grant_deferred()
781 printk(KERN_WARNING "lockd: grant for unknown block\n"); in nlmsvc_grant_deferred()
790 * the block to the head of nlm_blocked where it can be picked up by lockd.
795 struct nlm_block *block; in nlmsvc_notify_blocked() local
797 dprintk("lockd: VFS unblock notification for block %p\n", fl); in nlmsvc_notify_blocked()
799 list_for_each_entry(block, &nlm_blocked, b_list) { in nlmsvc_notify_blocked()
800 if (nlm_compare_locks(&block->b_call->a_args.lock.fl, fl)) { in nlmsvc_notify_blocked()
801 nlmsvc_insert_block_locked(block, 0); in nlmsvc_notify_blocked()
803 svc_wake_up(block->b_daemon); in nlmsvc_notify_blocked()
808 printk(KERN_WARNING "lockd: notification for unknown block!\n"); in nlmsvc_notify_blocked()
840 nlmsvc_grant_blocked(struct nlm_block *block) in nlmsvc_grant_blocked() argument
842 struct nlm_file *file = block->b_file; in nlmsvc_grant_blocked()
843 struct nlm_lock *lock = &block->b_call->a_args.lock; in nlmsvc_grant_blocked()
848 dprintk("lockd: grant blocked lock %p\n", block); in nlmsvc_grant_blocked()
850 kref_get(&block->b_count); in nlmsvc_grant_blocked()
852 /* Unlink block request from list */ in nlmsvc_grant_blocked()
853 nlmsvc_unlink_block(block); in nlmsvc_grant_blocked()
858 if (block->b_granted) { in nlmsvc_grant_blocked()
859 nlm_rebind_host(block->b_host); in nlmsvc_grant_blocked()
881 nlmsvc_insert_block(block, NLM_NEVER); in nlmsvc_grant_blocked()
882 nlmsvc_release_block(block); in nlmsvc_grant_blocked()
887 nlmsvc_insert_block(block, 10 * HZ); in nlmsvc_grant_blocked()
888 nlmsvc_release_block(block); in nlmsvc_grant_blocked()
895 block->b_granted = 1; in nlmsvc_grant_blocked()
897 /* keep block on the list, but don't reattempt until the RPC in nlmsvc_grant_blocked()
900 nlmsvc_insert_block(block, NLM_NEVER); in nlmsvc_grant_blocked()
905 error = nlm_async_call(block->b_call, NLMPROC_GRANTED_MSG, in nlmsvc_grant_blocked()
910 nlmsvc_insert_block(block, 10 * HZ); in nlmsvc_grant_blocked()
924 struct nlm_block *block = call->a_block; in nlmsvc_grant_callback() local
930 /* if the block is not on a list at this point then it has in nlmsvc_grant_callback()
933 * FIXME: it's possible that the block is removed from the list in nlmsvc_grant_callback()
938 if (list_empty(&block->b_list)) in nlmsvc_grant_callback()
942 * move the block towards the head of the queue only, no harm in nlmsvc_grant_callback()
951 nlmsvc_insert_block_locked(block, timeout); in nlmsvc_grant_callback()
952 svc_wake_up(block->b_daemon); in nlmsvc_grant_callback()
974 * block.
979 struct nlm_block *block; in nlmsvc_grant_reply() local
985 if (!(block = nlmsvc_find_block(cookie))) in nlmsvc_grant_reply()
991 nlmsvc_insert_block(block, 10 * HZ); in nlmsvc_grant_reply()
995 nlmsvc_unlink_block(block); in nlmsvc_grant_reply()
996 fl = &block->b_call->a_args.lock.fl; in nlmsvc_grant_reply()
1007 nlmsvc_unlink_block(block); in nlmsvc_grant_reply()
1009 nlmsvc_release_block(block); in nlmsvc_grant_reply()
1012 /* Helper function to handle retry of a deferred block.
1017 retry_deferred_block(struct nlm_block *block) in retry_deferred_block() argument
1019 if (!(block->b_flags & B_GOT_CALLBACK)) in retry_deferred_block()
1020 block->b_flags |= B_TIMED_OUT; in retry_deferred_block()
1021 nlmsvc_insert_block(block, NLM_TIMEOUT); in retry_deferred_block()
1022 dprintk("revisit block %p flags %d\n", block, block->b_flags); in retry_deferred_block()
1023 if (block->b_deferred_req) { in retry_deferred_block()
1024 block->b_deferred_req->revisit(block->b_deferred_req, 0); in retry_deferred_block()
1025 block->b_deferred_req = NULL; in retry_deferred_block()
1038 struct nlm_block *block; in nlmsvc_retry_blocked() local
1042 block = list_entry(nlm_blocked.next, struct nlm_block, b_list); in nlmsvc_retry_blocked()
1044 if (block->b_when == NLM_NEVER) in nlmsvc_retry_blocked()
1046 if (time_after(block->b_when, jiffies)) { in nlmsvc_retry_blocked()
1047 timeout = block->b_when - jiffies; in nlmsvc_retry_blocked()
1053 block, block->b_when); in nlmsvc_retry_blocked()
1054 if (block->b_flags & B_QUEUED) { in nlmsvc_retry_blocked()
1055 dprintk("nlmsvc_retry_blocked delete block (%p, granted=%d, flags=%d)\n", in nlmsvc_retry_blocked()
1056 block, block->b_granted, block->b_flags); in nlmsvc_retry_blocked()
1057 retry_deferred_block(block); in nlmsvc_retry_blocked()
1059 nlmsvc_grant_blocked(block); in nlmsvc_retry_blocked()