fs/ocfs2/dlm/dlmlock.c

Source file repositories/reference/linux-study-clean/fs/ocfs2/dlm/dlmlock.c

File Facts

System
Linux kernel
Corpus path
fs/ocfs2/dlm/dlmlock.c
Extension
.c
Size
19085 bytes
Lines
744
Domain
Core OS
Bucket
VFS And Filesystem Core
Inferred role
Core OS: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.

Dependency Surface

Detected Declarations

Annotated Snippet

if (flags & LKM_NOQUEUE) {
			status = DLM_NOTQUEUED;
			if (dlm_is_recovery_lock(res->lockname.name,
						 res->lockname.len)) {
				mlog(0, "%s: returning NOTQUEUED to "
				     "node %u for reco lock\n", dlm->name,
				     lock->ml.node);
			}
		} else {
			status = DLM_NORMAL;
			dlm_lock_get(lock);
			list_add_tail(&lock->list, &res->blocked);
			kick_thread = 1;
		}
	}

	spin_unlock(&res->spinlock);
	wake_up(&res->wq);

	/* either queue the ast or release it */
	if (call_ast)
		dlm_queue_ast(dlm, lock);
	else
		dlm_lockres_release_ast(dlm, res);

	dlm_lockres_calc_usage(dlm, res);
	if (kick_thread)
		dlm_kick_thread(dlm, res);

	return status;
}

void dlm_revert_pending_lock(struct dlm_lock_resource *res,
			     struct dlm_lock *lock)
{
	/* remove from local queue if it failed */
	list_del_init(&lock->list);
	lock->lksb->flags &= ~DLM_LKSB_GET_LVB;
}


/*
 * locking:
 *   caller needs:  none
 *   taken:         takes and drops res->spinlock
 *   held on exit:  none
 * returns: DLM_DENIED, DLM_RECOVERING, or net status
 */
static enum dlm_status dlmlock_remote(struct dlm_ctxt *dlm,
				      struct dlm_lock_resource *res,
				      struct dlm_lock *lock, int flags)
{
	enum dlm_status status = DLM_DENIED;
	int lockres_changed = 1;

	mlog(0, "type=%d, lockres %.*s, flags = 0x%x\n",
	     lock->ml.type, res->lockname.len,
	     res->lockname.name, flags);

	/*
	 * Wait if resource is getting recovered, remastered, etc.
	 * If the resource was remastered and new owner is self, then exit.
	 */
	spin_lock(&res->spinlock);
	__dlm_wait_on_lockres(res);
	if (res->owner == dlm->node_num) {
		spin_unlock(&res->spinlock);
		return DLM_RECOVERING;
	}
	res->state |= DLM_LOCK_RES_IN_PROGRESS;

	/* add lock to local (secondary) queue */
	dlm_lock_get(lock);
	list_add_tail(&lock->list, &res->blocked);
	lock->lock_pending = 1;
	spin_unlock(&res->spinlock);

	/* spec seems to say that you will get DLM_NORMAL when the lock
	 * has been queued, meaning we need to wait for a reply here. */
	status = dlm_send_remote_lock_request(dlm, res, lock, flags);

	spin_lock(&res->spinlock);
	res->state &= ~DLM_LOCK_RES_IN_PROGRESS;
	lock->lock_pending = 0;
	if (status != DLM_NORMAL) {
		if (status == DLM_RECOVERING &&
		    dlm_is_recovery_lock(res->lockname.name,
					 res->lockname.len)) {
			/* recovery lock was mastered by dead node.
			 * we need to have calc_usage shoot down this

Annotation

Implementation Notes