![Greg Kroah-Hartman](/assets/img/avatar_default.png)
We don't need a "default" ktype for a kset. We should set this explicitly every time for each kset. This change is needed so that we can make ksets dynamic, and cleans up one of the odd, undocumented assumption that the kset/kobject/ktype model has. This patch is based on a lot of help from Kay Sievers. Nasty bug in the block code was found by Dave Young <hidave.darkstar@gmail.com> Cc: Kay Sievers <kay.sievers@vrfy.org> Cc: Dave Young <hidave.darkstar@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
124 lines
3 KiB
C
124 lines
3 KiB
C
/* -*- mode: c; c-basic-offset: 8; -*-
|
|
* vim: noexpandtab sw=8 ts=8 sts=0:
|
|
*
|
|
* sys.c
|
|
*
|
|
* OCFS2 cluster sysfs interface
|
|
*
|
|
* Copyright (C) 2005 Oracle. All rights reserved.
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public
|
|
* License as published by the Free Software Foundation,
|
|
* version 2 of the License.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public
|
|
* License along with this program; if not, write to the
|
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
* Boston, MA 021110-1307, USA.
|
|
*
|
|
*/
|
|
|
|
#include <linux/kernel.h>
|
|
#include <linux/module.h>
|
|
#include <linux/kobject.h>
|
|
#include <linux/sysfs.h>
|
|
|
|
#include "ocfs2_nodemanager.h"
|
|
#include "masklog.h"
|
|
#include "sys.h"
|
|
|
|
struct o2cb_attribute {
|
|
struct attribute attr;
|
|
ssize_t (*show)(char *buf);
|
|
ssize_t (*store)(const char *buf, size_t count);
|
|
};
|
|
|
|
#define O2CB_ATTR(_name, _mode, _show, _store) \
|
|
struct o2cb_attribute o2cb_attr_##_name = __ATTR(_name, _mode, _show, _store)
|
|
|
|
#define to_o2cb_attr(_attr) container_of(_attr, struct o2cb_attribute, attr)
|
|
|
|
static ssize_t o2cb_interface_revision_show(char *buf)
|
|
{
|
|
return snprintf(buf, PAGE_SIZE, "%u\n", O2NM_API_VERSION);
|
|
}
|
|
|
|
static O2CB_ATTR(interface_revision, S_IFREG | S_IRUGO, o2cb_interface_revision_show, NULL);
|
|
|
|
static struct attribute *o2cb_attrs[] = {
|
|
&o2cb_attr_interface_revision.attr,
|
|
NULL,
|
|
};
|
|
|
|
static ssize_t
|
|
o2cb_show(struct kobject * kobj, struct attribute * attr, char * buffer);
|
|
static ssize_t
|
|
o2cb_store(struct kobject * kobj, struct attribute * attr,
|
|
const char * buffer, size_t count);
|
|
static struct sysfs_ops o2cb_sysfs_ops = {
|
|
.show = o2cb_show,
|
|
.store = o2cb_store,
|
|
};
|
|
|
|
static struct kobj_type o2cb_subsys_type = {
|
|
.default_attrs = o2cb_attrs,
|
|
.sysfs_ops = &o2cb_sysfs_ops,
|
|
};
|
|
|
|
/* gives us o2cb_subsys */
|
|
static decl_subsys(o2cb, NULL);
|
|
|
|
static ssize_t
|
|
o2cb_show(struct kobject * kobj, struct attribute * attr, char * buffer)
|
|
{
|
|
struct o2cb_attribute *o2cb_attr = to_o2cb_attr(attr);
|
|
struct kset *sbs = to_kset(kobj);
|
|
|
|
BUG_ON(sbs != &o2cb_subsys);
|
|
|
|
if (o2cb_attr->show)
|
|
return o2cb_attr->show(buffer);
|
|
return -EIO;
|
|
}
|
|
|
|
static ssize_t
|
|
o2cb_store(struct kobject * kobj, struct attribute * attr,
|
|
const char * buffer, size_t count)
|
|
{
|
|
struct o2cb_attribute *o2cb_attr = to_o2cb_attr(attr);
|
|
struct kset *sbs = to_kset(kobj);
|
|
|
|
BUG_ON(sbs != &o2cb_subsys);
|
|
|
|
if (o2cb_attr->store)
|
|
return o2cb_attr->store(buffer, count);
|
|
return -EIO;
|
|
}
|
|
|
|
void o2cb_sys_shutdown(void)
|
|
{
|
|
mlog_sys_shutdown();
|
|
subsystem_unregister(&o2cb_subsys);
|
|
}
|
|
|
|
int o2cb_sys_init(void)
|
|
{
|
|
int ret;
|
|
|
|
o2cb_subsys.kobj.ktype = &o2cb_subsys_type;
|
|
ret = subsystem_register(&o2cb_subsys);
|
|
if (ret)
|
|
return ret;
|
|
|
|
ret = mlog_sys_init(&o2cb_subsys);
|
|
if (ret)
|
|
subsystem_unregister(&o2cb_subsys);
|
|
return ret;
|
|
}
|