fs/ocfs2/dlmfs/userdlm.c

Source file repositories/reference/linux-study-clean/fs/ocfs2/dlmfs/userdlm.c

File Facts

System
Linux kernel
Corpus path
fs/ocfs2/dlmfs/userdlm.c
Extension
.c
Size
17627 bytes
Lines
683
Domain
Core OS
Bucket
VFS And Filesystem Core
Inferred role
Core OS: implementation source
Status
source 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

user_highest_compat_lock_level(lockres->l_blocking)) {
			lockres->l_blocking = DLM_LOCK_NL;
			lockres->l_flags &= ~USER_LOCK_BLOCKED;
		}
	}

	lockres->l_level = lockres->l_requested;
	lockres->l_requested = DLM_LOCK_IV;
	lockres->l_flags |= USER_LOCK_ATTACHED;
	lockres->l_flags &= ~USER_LOCK_BUSY;

	spin_unlock(&lockres->l_lock);

	wake_up(&lockres->l_event);
}

static inline void user_dlm_grab_inode_ref(struct user_lock_res *lockres)
{
	struct inode *inode;
	inode = user_dlm_inode_from_user_lockres(lockres);
	if (!igrab(inode))
		BUG();
}

static void user_dlm_unblock_lock(struct work_struct *work);

static void __user_dlm_queue_lockres(struct user_lock_res *lockres)
{
	if (!(lockres->l_flags & USER_LOCK_QUEUED)) {
		user_dlm_grab_inode_ref(lockres);

		INIT_WORK(&lockres->l_work, user_dlm_unblock_lock);

		queue_work(user_dlm_worker, &lockres->l_work);
		lockres->l_flags |= USER_LOCK_QUEUED;
	}
}

static void __user_dlm_cond_queue_lockres(struct user_lock_res *lockres)
{
	int queue = 0;

	if (!(lockres->l_flags & USER_LOCK_BLOCKED))
		return;

	switch (lockres->l_blocking) {
	case DLM_LOCK_EX:
		if (!lockres->l_ex_holders && !lockres->l_ro_holders)
			queue = 1;
		break;
	case DLM_LOCK_PR:
		if (!lockres->l_ex_holders)
			queue = 1;
		break;
	default:
		BUG();
	}

	if (queue)
		__user_dlm_queue_lockres(lockres);
}

static void user_bast(struct ocfs2_dlm_lksb *lksb, int level)
{
	struct user_lock_res *lockres = user_lksb_to_lock_res(lksb);

	mlog(ML_BASTS, "BAST fired for lockres %.*s, blocking %d, level %d\n",
	     lockres->l_namelen, lockres->l_name, level, lockres->l_level);

	spin_lock(&lockres->l_lock);
	lockres->l_flags |= USER_LOCK_BLOCKED;
	if (level > lockres->l_blocking)
		lockres->l_blocking = level;

	__user_dlm_queue_lockres(lockres);
	spin_unlock(&lockres->l_lock);

	wake_up(&lockres->l_event);
}

static void user_unlock_ast(struct ocfs2_dlm_lksb *lksb, int status)
{
	struct user_lock_res *lockres = user_lksb_to_lock_res(lksb);

	mlog(ML_BASTS, "UNLOCK AST fired for lockres %.*s, flags 0x%x\n",
	     lockres->l_namelen, lockres->l_name, lockres->l_flags);

	if (status)
		mlog(ML_ERROR, "dlm returns status %d\n", status);

Annotation

Implementation Notes