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

📄 lockspace.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*****************************************************************************************************************************************************************  Copyright (C) Sistina Software, Inc.  1997-2003  All rights reserved.**  Copyright (C) 2004-2007 Red Hat, Inc.  All rights reserved.****  This copyrighted material is made available to anyone wishing to use,**  modify, copy, or redistribute it subject to the terms and conditions**  of the GNU General Public License v.2.***************************************************************************************************************************************************************/#include "dlm_internal.h"#include "lockspace.h"#include "member.h"#include "recoverd.h"#include "ast.h"#include "dir.h"#include "lowcomms.h"#include "config.h"#include "memory.h"#include "lock.h"#include "recover.h"#include "requestqueue.h"#ifdef CONFIG_DLM_DEBUGint dlm_create_debug_file(struct dlm_ls *ls);void dlm_delete_debug_file(struct dlm_ls *ls);#elsestatic inline int dlm_create_debug_file(struct dlm_ls *ls) { return 0; }static inline void dlm_delete_debug_file(struct dlm_ls *ls) { }#endifstatic int			ls_count;static struct mutex		ls_lock;static struct list_head		lslist;static spinlock_t		lslist_lock;static struct task_struct *	scand_task;static ssize_t dlm_control_store(struct dlm_ls *ls, const char *buf, size_t len){	ssize_t ret = len;	int n = simple_strtol(buf, NULL, 0);	ls = dlm_find_lockspace_local(ls->ls_local_handle);	if (!ls)		return -EINVAL;	switch (n) {	case 0:		dlm_ls_stop(ls);		break;	case 1:		dlm_ls_start(ls);		break;	default:		ret = -EINVAL;	}	dlm_put_lockspace(ls);	return ret;}static ssize_t dlm_event_store(struct dlm_ls *ls, const char *buf, size_t len){	ls->ls_uevent_result = simple_strtol(buf, NULL, 0);	set_bit(LSFL_UEVENT_WAIT, &ls->ls_flags);	wake_up(&ls->ls_uevent_wait);	return len;}static ssize_t dlm_id_show(struct dlm_ls *ls, char *buf){	return snprintf(buf, PAGE_SIZE, "%u\n", ls->ls_global_id);}static ssize_t dlm_id_store(struct dlm_ls *ls, const char *buf, size_t len){	ls->ls_global_id = simple_strtoul(buf, NULL, 0);	return len;}static ssize_t dlm_recover_status_show(struct dlm_ls *ls, char *buf){	uint32_t status = dlm_recover_status(ls);	return snprintf(buf, PAGE_SIZE, "%x\n", status);}static ssize_t dlm_recover_nodeid_show(struct dlm_ls *ls, char *buf){	return snprintf(buf, PAGE_SIZE, "%d\n", ls->ls_recover_nodeid);}struct dlm_attr {	struct attribute attr;	ssize_t (*show)(struct dlm_ls *, char *);	ssize_t (*store)(struct dlm_ls *, const char *, size_t);};static struct dlm_attr dlm_attr_control = {	.attr  = {.name = "control", .mode = S_IWUSR},	.store = dlm_control_store};static struct dlm_attr dlm_attr_event = {	.attr  = {.name = "event_done", .mode = S_IWUSR},	.store = dlm_event_store};static struct dlm_attr dlm_attr_id = {	.attr  = {.name = "id", .mode = S_IRUGO | S_IWUSR},	.show  = dlm_id_show,	.store = dlm_id_store};static struct dlm_attr dlm_attr_recover_status = {	.attr  = {.name = "recover_status", .mode = S_IRUGO},	.show  = dlm_recover_status_show};static struct dlm_attr dlm_attr_recover_nodeid = {	.attr  = {.name = "recover_nodeid", .mode = S_IRUGO},	.show  = dlm_recover_nodeid_show};static struct attribute *dlm_attrs[] = {	&dlm_attr_control.attr,	&dlm_attr_event.attr,	&dlm_attr_id.attr,	&dlm_attr_recover_status.attr,	&dlm_attr_recover_nodeid.attr,	NULL,};static ssize_t dlm_attr_show(struct kobject *kobj, struct attribute *attr,			     char *buf){	struct dlm_ls *ls  = container_of(kobj, struct dlm_ls, ls_kobj);	struct dlm_attr *a = container_of(attr, struct dlm_attr, attr);	return a->show ? a->show(ls, buf) : 0;}static ssize_t dlm_attr_store(struct kobject *kobj, struct attribute *attr,			      const char *buf, size_t len){	struct dlm_ls *ls  = container_of(kobj, struct dlm_ls, ls_kobj);	struct dlm_attr *a = container_of(attr, struct dlm_attr, attr);	return a->store ? a->store(ls, buf, len) : len;}static void lockspace_kobj_release(struct kobject *k){	struct dlm_ls *ls  = container_of(k, struct dlm_ls, ls_kobj);	kfree(ls);}static struct sysfs_ops dlm_attr_ops = {	.show  = dlm_attr_show,	.store = dlm_attr_store,};static struct kobj_type dlm_ktype = {	.default_attrs = dlm_attrs,	.sysfs_ops     = &dlm_attr_ops,	.release       = lockspace_kobj_release,};static struct kset dlm_kset = {	.ktype  = &dlm_ktype,};static int kobject_setup(struct dlm_ls *ls){	char lsname[DLM_LOCKSPACE_LEN];	int error;	memset(lsname, 0, DLM_LOCKSPACE_LEN);	snprintf(lsname, DLM_LOCKSPACE_LEN, "%s", ls->ls_name);	error = kobject_set_name(&ls->ls_kobj, "%s", lsname);	if (error)		return error;	ls->ls_kobj.kset = &dlm_kset;	ls->ls_kobj.ktype = &dlm_ktype;	return 0;}static int do_uevent(struct dlm_ls *ls, int in){	int error;	if (in)		kobject_uevent(&ls->ls_kobj, KOBJ_ONLINE);	else		kobject_uevent(&ls->ls_kobj, KOBJ_OFFLINE);	log_debug(ls, "%s the lockspace group...", in ? "joining" : "leaving");	/* dlm_controld will see the uevent, do the necessary group management	   and then write to sysfs to wake us */	error = wait_event_interruptible(ls->ls_uevent_wait,			test_and_clear_bit(LSFL_UEVENT_WAIT, &ls->ls_flags));	log_debug(ls, "group event done %d %d", error, ls->ls_uevent_result);	if (error)		goto out;	error = ls->ls_uevent_result; out:	if (error)		log_error(ls, "group %s failed %d %d", in ? "join" : "leave",			  error, ls->ls_uevent_result);	return error;}int dlm_lockspace_init(void){	int error;	ls_count = 0;	mutex_init(&ls_lock);	INIT_LIST_HEAD(&lslist);	spin_lock_init(&lslist_lock);	kobject_set_name(&dlm_kset.kobj, "dlm");	kobj_set_kset_s(&dlm_kset, kernel_subsys);	error = kset_register(&dlm_kset);	if (error)		printk("dlm_lockspace_init: cannot register kset %d\n", error);	return error;}void dlm_lockspace_exit(void){	kset_unregister(&dlm_kset);}static int dlm_scand(void *data){	struct dlm_ls *ls;	while (!kthread_should_stop()) {		list_for_each_entry(ls, &lslist, ls_list) {			if (dlm_lock_recovery_try(ls)) {				dlm_scan_rsbs(ls);				dlm_scan_timeout(ls);				dlm_unlock_recovery(ls);			}		}		schedule_timeout_interruptible(dlm_config.ci_scan_secs * HZ);	}	return 0;}static int dlm_scand_start(void){	struct task_struct *p;	int error = 0;	p = kthread_run(dlm_scand, NULL, "dlm_scand");	if (IS_ERR(p))		error = PTR_ERR(p);	else		scand_task = p;	return error;}static void dlm_scand_stop(void){	kthread_stop(scand_task);}static struct dlm_ls *dlm_find_lockspace_name(char *name, int namelen){	struct dlm_ls *ls;	spin_lock(&lslist_lock);	list_for_each_entry(ls, &lslist, ls_list) {		if (ls->ls_namelen == namelen &&		    memcmp(ls->ls_name, name, namelen) == 0)			goto out;	}	ls = NULL; out:	spin_unlock(&lslist_lock);	return ls;}struct dlm_ls *dlm_find_lockspace_global(uint32_t id){	struct dlm_ls *ls;	spin_lock(&lslist_lock);	list_for_each_entry(ls, &lslist, ls_list) {		if (ls->ls_global_id == id) {			ls->ls_count++;			goto out;		}	}	ls = NULL; out:	spin_unlock(&lslist_lock);	return ls;}struct dlm_ls *dlm_find_lockspace_local(dlm_lockspace_t *lockspace){	struct dlm_ls *ls;	spin_lock(&lslist_lock);	list_for_each_entry(ls, &lslist, ls_list) {		if (ls->ls_local_handle == lockspace) {			ls->ls_count++;			goto out;		}	}	ls = NULL; out:	spin_unlock(&lslist_lock);	return ls;}struct dlm_ls *dlm_find_lockspace_device(int minor){	struct dlm_ls *ls;	spin_lock(&lslist_lock);	list_for_each_entry(ls, &lslist, ls_list) {		if (ls->ls_device.minor == minor) {			ls->ls_count++;			goto out;		}	}	ls = NULL; out:	spin_unlock(&lslist_lock);	return ls;}void dlm_put_lockspace(struct dlm_ls *ls){	spin_lock(&lslist_lock);	ls->ls_count--;	spin_unlock(&lslist_lock);}static void remove_lockspace(struct dlm_ls *ls){	for (;;) {		spin_lock(&lslist_lock);		if (ls->ls_count == 0) {			list_del(&ls->ls_list);			spin_unlock(&lslist_lock);			return;		}		spin_unlock(&lslist_lock);		ssleep(1);	}}static int threads_start(void){	int error;	/* Thread which process lock requests for all lockspace's */	error = dlm_astd_start();	if (error) {		log_print("cannot start dlm_astd thread %d", error);		goto fail;	}	error = dlm_scand_start();	if (error) {		log_print("cannot start dlm_scand thread %d", error);		goto astd_fail;	}	/* Thread for sending/receiving messages for all lockspace's */	error = dlm_lowcomms_start();	if (error) {		log_print("cannot start dlm lowcomms %d", error);		goto scand_fail;	}	return 0; scand_fail:	dlm_scand_stop(); astd_fail:

⌨️ 快捷键说明

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