⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 userdlm.c

📁 ocfs1.4.1 oracle分布式文件系统
💻 C
📖 第 1 页 / 共 2 页
字号:
		spin_unlock(&lockres->l_lock);		mlog(0, "can't downconvert for ex: ro = %u, ex = %u\n",			lockres->l_ro_holders, lockres->l_ex_holders);		goto drop_ref;	}	if ((lockres->l_blocking == LKM_PRMODE)	    && lockres->l_ex_holders) {		spin_unlock(&lockres->l_lock);		mlog(0, "can't downconvert for pr: ex = %u\n",			lockres->l_ex_holders);		goto drop_ref;	}	/* yay, we can downconvert now. */	new_level = user_highest_compat_lock_level(lockres->l_blocking);	lockres->l_requested = new_level;	lockres->l_flags |= USER_LOCK_BUSY;	mlog(0, "Downconvert lock from %d to %d\n",		lockres->l_level, new_level);	spin_unlock(&lockres->l_lock);	/* need lock downconvert request now... */	status = dlmlock(dlm,			 new_level,			 &lockres->l_lksb,			 LKM_CONVERT|LKM_VALBLK,			 lockres->l_name,			 lockres->l_namelen,			 user_ast,			 lockres,			 user_bast);	if (status != DLM_NORMAL) {		user_log_dlm_error("dlmlock", status, lockres);		user_recover_from_dlm_error(lockres);	}drop_ref:	user_dlm_drop_inode_ref(lockres);}static inline void user_dlm_inc_holders(struct user_lock_res *lockres,					int level){	switch(level) {	case LKM_EXMODE:		lockres->l_ex_holders++;		break;	case LKM_PRMODE:		lockres->l_ro_holders++;		break;	default:		BUG();	}}/* predict what lock level we'll be dropping down to on behalf * of another node, and return true if the currently wanted * level will be compatible with it. */static inline intuser_may_continue_on_blocked_lock(struct user_lock_res *lockres,				  int wanted){	BUG_ON(!(lockres->l_flags & USER_LOCK_BLOCKED));	return wanted <= user_highest_compat_lock_level(lockres->l_blocking);}int user_dlm_cluster_lock(struct user_lock_res *lockres,			  int level,			  int lkm_flags){	int status, local_flags;	struct dlm_ctxt *dlm = dlm_ctxt_from_user_lockres(lockres);	if (level != LKM_EXMODE &&	    level != LKM_PRMODE) {		mlog(ML_ERROR, "lockres %.*s: invalid request!\n",		     lockres->l_namelen, lockres->l_name);		status = -EINVAL;		goto bail;	}	mlog(0, "lockres %.*s: asking for %s lock, passed flags = 0x%x\n",	     lockres->l_namelen, lockres->l_name,	     (level == LKM_EXMODE) ? "LKM_EXMODE" : "LKM_PRMODE",	     lkm_flags);again:	if (signal_pending(current)) {		status = -ERESTARTSYS;		goto bail;	}	spin_lock(&lockres->l_lock);	/* We only compare against the currently granted level	 * here. If the lock is blocked waiting on a downconvert,	 * we'll get caught below. */	if ((lockres->l_flags & USER_LOCK_BUSY) &&	    (level > lockres->l_level)) {		/* is someone sitting in dlm_lock? If so, wait on		 * them. */		spin_unlock(&lockres->l_lock);		user_wait_on_busy_lock(lockres);		goto again;	}	if ((lockres->l_flags & USER_LOCK_BLOCKED) &&	    (!user_may_continue_on_blocked_lock(lockres, level))) {		/* is the lock is currently blocked on behalf of		 * another node */		spin_unlock(&lockres->l_lock);		user_wait_on_blocked_lock(lockres);		goto again;	}	if (level > lockres->l_level) {		local_flags = lkm_flags | LKM_VALBLK;		if (lockres->l_level != LKM_IVMODE)			local_flags |= LKM_CONVERT;		lockres->l_requested = level;		lockres->l_flags |= USER_LOCK_BUSY;		spin_unlock(&lockres->l_lock);		BUG_ON(level == LKM_IVMODE);		BUG_ON(level == LKM_NLMODE);		/* call dlm_lock to upgrade lock now */		status = dlmlock(dlm,				 level,				 &lockres->l_lksb,				 local_flags,				 lockres->l_name,				 lockres->l_namelen,				 user_ast,				 lockres,				 user_bast);		if (status != DLM_NORMAL) {			if ((lkm_flags & LKM_NOQUEUE) &&			    (status == DLM_NOTQUEUED))				status = -EAGAIN;			else {				user_log_dlm_error("dlmlock", status, lockres);				status = -EINVAL;			}			user_recover_from_dlm_error(lockres);			goto bail;		}		user_wait_on_busy_lock(lockres);		goto again;	}	user_dlm_inc_holders(lockres, level);	spin_unlock(&lockres->l_lock);	status = 0;bail:	return status;}static inline void user_dlm_dec_holders(struct user_lock_res *lockres,					int level){	switch(level) {	case LKM_EXMODE:		BUG_ON(!lockres->l_ex_holders);		lockres->l_ex_holders--;		break;	case LKM_PRMODE:		BUG_ON(!lockres->l_ro_holders);		lockres->l_ro_holders--;		break;	default:		BUG();	}}void user_dlm_cluster_unlock(struct user_lock_res *lockres,			     int level){	if (level != LKM_EXMODE &&	    level != LKM_PRMODE) {		mlog(ML_ERROR, "lockres %.*s: invalid request!\n",		     lockres->l_namelen, lockres->l_name);		return;	}	spin_lock(&lockres->l_lock);	user_dlm_dec_holders(lockres, level);	__user_dlm_cond_queue_lockres(lockres);	spin_unlock(&lockres->l_lock);}void user_dlm_write_lvb(struct inode *inode,			const char *val,			unsigned int len){	struct user_lock_res *lockres = &DLMFS_I(inode)->ip_lockres;	char *lvb = lockres->l_lksb.lvb;	BUG_ON(len > DLM_LVB_LEN);	spin_lock(&lockres->l_lock);	BUG_ON(lockres->l_level < LKM_EXMODE);	memcpy(lvb, val, len);	spin_unlock(&lockres->l_lock);}void user_dlm_read_lvb(struct inode *inode,		       char *val,		       unsigned int len){	struct user_lock_res *lockres = &DLMFS_I(inode)->ip_lockres;	char *lvb = lockres->l_lksb.lvb;	BUG_ON(len > DLM_LVB_LEN);	spin_lock(&lockres->l_lock);	BUG_ON(lockres->l_level < LKM_PRMODE);	memcpy(val, lvb, len);	spin_unlock(&lockres->l_lock);}void user_dlm_lock_res_init(struct user_lock_res *lockres,			    struct dentry *dentry){	memset(lockres, 0, sizeof(*lockres));	spin_lock_init(&lockres->l_lock);	init_waitqueue_head(&lockres->l_event);	lockres->l_level = LKM_IVMODE;	lockres->l_requested = LKM_IVMODE;	lockres->l_blocking = LKM_IVMODE;	/* should have been checked before getting here. */	BUG_ON(dentry->d_name.len >= USER_DLM_LOCK_ID_MAX_LEN);	memcpy(lockres->l_name,	       dentry->d_name.name,	       dentry->d_name.len);	lockres->l_namelen = dentry->d_name.len;}int user_dlm_destroy_lock(struct user_lock_res *lockres){	int status = -EBUSY;	struct dlm_ctxt *dlm = dlm_ctxt_from_user_lockres(lockres);	mlog(0, "asked to destroy %.*s\n", lockres->l_namelen, lockres->l_name);	spin_lock(&lockres->l_lock);	if (lockres->l_flags & USER_LOCK_IN_TEARDOWN) {		spin_unlock(&lockres->l_lock);		return 0;	}	lockres->l_flags |= USER_LOCK_IN_TEARDOWN;	while (lockres->l_flags & USER_LOCK_BUSY) {		spin_unlock(&lockres->l_lock);		user_wait_on_busy_lock(lockres);		spin_lock(&lockres->l_lock);	}	if (lockres->l_ro_holders || lockres->l_ex_holders) {		spin_unlock(&lockres->l_lock);		goto bail;	}	status = 0;	if (!(lockres->l_flags & USER_LOCK_ATTACHED)) {		spin_unlock(&lockres->l_lock);		goto bail;	}	lockres->l_flags &= ~USER_LOCK_ATTACHED;	lockres->l_flags |= USER_LOCK_BUSY;	spin_unlock(&lockres->l_lock);	status = dlmunlock(dlm,			   &lockres->l_lksb,			   LKM_VALBLK,			   user_unlock_ast,			   lockres);	if (status != DLM_NORMAL) {		user_log_dlm_error("dlmunlock", status, lockres);		status = -EINVAL;		goto bail;	}	user_wait_on_busy_lock(lockres);	status = 0;bail:	return status;}struct dlm_ctxt *user_dlm_register_context(struct qstr *name,					   struct dlm_protocol_version *proto){	struct dlm_ctxt *dlm;	u32 dlm_key;	char *domain;	domain = kmalloc(name->len + 1, GFP_NOFS);	if (!domain) {		mlog_errno(-ENOMEM);		return ERR_PTR(-ENOMEM);	}	dlm_key = crc32_le(0, name->name, name->len);	snprintf(domain, name->len + 1, "%.*s", name->len, name->name);	dlm = dlm_register_domain(domain, dlm_key, proto);	if (IS_ERR(dlm))		mlog_errno(PTR_ERR(dlm));	kfree(domain);	return dlm;}void user_dlm_unregister_context(struct dlm_ctxt *dlm){	dlm_unregister_domain(dlm);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -