Пример #1
0
/*
 * Delete a block. If the lock was cancelled or the grant callback
 * failed, unlock is set to 1.
 * It is the caller's responsibility to check whether the file
 * can be closed hereafter.
 */
static void
nlmsvc_delete_block(struct nlm_block *block, int unlock)
{
	struct file_lock	*fl = &block->b_call.a_args.lock.fl;
	struct nlm_file		*file = block->b_file;
	struct nlm_block	**bp;

	dprintk("lockd: deleting block %p...\n", block);

	/* Remove block from list */
	nlmsvc_remove_block(block);
	posix_unblock_lock(&file->f_file, fl);
	block->b_granted = 0;

	/* If the block is in the middle of a GRANT callback,
	 * don't kill it yet. */
	if (block->b_incall) {
		nlmsvc_insert_block(block, NLM_NEVER);
		block->b_done = 1;
		return;
	}

	/* Remove block from file's list of blocks */
	for (bp = &file->f_blocks; *bp; bp = &(*bp)->b_fnext) {
		if (*bp == block) {
			*bp = block->b_fnext;
			break;
		}
	}

	if (block->b_host)
		nlm_release_host(block->b_host);
	nlmclnt_freegrantargs(&block->b_call);
	kfree(block);
}
Пример #2
0
/*
 * 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)
{
	struct nlm_block	**bp, *block;

	dprintk("lockd: VFS unblock notification for block %p\n", fl);
	posix_unblock_lock(fl);
	for (bp = &nlm_blocked; (block = *bp); bp = &block->b_next) {
		if (&block->b_call.a_args.lock.fl == fl) {
			svc_wake_up(block->b_daemon);
			nlmsvc_insert_block(block, 0);
			return;
		}
	}

	printk(KERN_WARNING "lockd: notification for unknown block!\n");
}