linux文件系统的系统分析--(九)sysfs下属性文件的读写
2012-04-07 17:54
417 查看
sysfs的属性文件的读写,我们先看下open,open系统调用最终会调用sysfs_open_file
struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata; //获取sysfs_dirent结构
struct kobject *kobj = attr_sd->s_parent->s_dir.kobj; //根据sysfs_dirent结构获取上一层结构的kobj对象
struct sysfs_buffer *buffer;
const struct sysfs_ops *ops;
下面是几步关键步骤:
1、 if (kobj->ktype && kobj->ktype->sysfs_ops)
ops = kobj->ktype->sysfs_ops; //操作方法用的是ktype的sysfs_ops
2、对文件的读写权限做一些检查
3、 buffer->needs_read_fill = 1;
buffer->ops = ops; //buffer的ops指向了前面的ops
file->private_data = buffer; //file的private_data指向了buffer
这一步的指针操作在后面的read和write中可以看清楚
read和write是类似的过程,我们仅仅看read
sysfs_read_file:
1、struct sysfs_buffer * buffer = file->private_data; //根据open中的指针操作获取buffer指针
2、调用fill_read_buffer函数
struct sysfs_dirent *attr_sd = dentry->d_fsdata;
struct kobject *kobj = attr_sd->s_parent->s_dir.kobj;
const struct sysfs_ops * ops = buffer->ops; //获取了ktype中的sysfs_ops
调用ops->show(kobj, attr_sd->s_attr.attr, buffer->page);
3、调用simple_read_from_buffer将读取到的内容拷贝到用户空间(copy_to_user)
这里还有一个最后的疑问,这里的ops到底是什么,show和store方法是怎么样的?
我们以kobject-example.c为例做说明:
找kobj->ktype->sysfs_ops
在kobject_create-->kobject_init(kobj, &dynamic_kobj_ktype);
static struct kobj_type dynamic_kobj_ktype = {
.release
= dynamic_kobj_release,
.sysfs_ops
= &kobj_sysfs_ops,
};
const struct sysfs_ops kobj_sysfs_ops = {
.show = kobj_attr_show,
.store
= kobj_attr_store,
};
而对与ldd3中lddbus的例子,其实也是类似:
在bus_register函数中:
priv->subsys.kobj.ktype = &bus_ktype;
最终是调用bus_attr的show方法,就是:
根据这个流程走下来,再根据kobject-example.c和lddbus的例子,我们可以很清晰的了解sysfs中属性文件的读写过程。
sysfs到分析到这里了,我们整体上把握了sysfs的安装挂载,目录文件的创建和读写操作。
因为sysfs是将设备模型导入到用户空间的内存文件系统,下面我们就要由sysfs来看kobject,也就是linux的设备模型了。
struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata; //获取sysfs_dirent结构
struct kobject *kobj = attr_sd->s_parent->s_dir.kobj; //根据sysfs_dirent结构获取上一层结构的kobj对象
struct sysfs_buffer *buffer;
const struct sysfs_ops *ops;
下面是几步关键步骤:
1、 if (kobj->ktype && kobj->ktype->sysfs_ops)
ops = kobj->ktype->sysfs_ops; //操作方法用的是ktype的sysfs_ops
2、对文件的读写权限做一些检查
3、 buffer->needs_read_fill = 1;
buffer->ops = ops; //buffer的ops指向了前面的ops
file->private_data = buffer; //file的private_data指向了buffer
这一步的指针操作在后面的read和write中可以看清楚
read和write是类似的过程,我们仅仅看read
sysfs_read_file:
1、struct sysfs_buffer * buffer = file->private_data; //根据open中的指针操作获取buffer指针
2、调用fill_read_buffer函数
struct sysfs_dirent *attr_sd = dentry->d_fsdata;
struct kobject *kobj = attr_sd->s_parent->s_dir.kobj;
const struct sysfs_ops * ops = buffer->ops; //获取了ktype中的sysfs_ops
调用ops->show(kobj, attr_sd->s_attr.attr, buffer->page);
3、调用simple_read_from_buffer将读取到的内容拷贝到用户空间(copy_to_user)
这里还有一个最后的疑问,这里的ops到底是什么,show和store方法是怎么样的?
我们以kobject-example.c为例做说明:
找kobj->ktype->sysfs_ops
在kobject_create-->kobject_init(kobj, &dynamic_kobj_ktype);
static struct kobj_type dynamic_kobj_ktype = {
.release
= dynamic_kobj_release,
.sysfs_ops
= &kobj_sysfs_ops,
};
const struct sysfs_ops kobj_sysfs_ops = {
.show = kobj_attr_show,
.store
= kobj_attr_store,
};
/* default kobject attribute operations */ static ssize_t kobj_attr_show(struct kobject *kobj, struct attribute *attr, char *buf) { struct kobj_attribute *kattr; ssize_t ret = -EIO; kattr = container_of(attr, struct kobj_attribute, attr); if (kattr->show) ret = kattr->show(kobj, kattr, buf); return ret; }最后就是调用kattr->show方法,也就是:
static ssize_t foo_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { return sprintf(buf, "%d\n", foo); }
而对与ldd3中lddbus的例子,其实也是类似:
在bus_register函数中:
priv->subsys.kobj.ktype = &bus_ktype;
static struct kobj_type bus_ktype = { .sysfs_ops = &bus_sysfs_ops, };
static const struct sysfs_ops bus_sysfs_ops = { .show = bus_attr_show, .store = bus_attr_store, };
static ssize_t bus_attr_show(struct kobject *kobj, struct attribute *attr, char *buf) { struct bus_attribute *bus_attr = to_bus_attr(attr); struct bus_type_private *bus_priv = to_bus(kobj); ssize_t ret = 0; if (bus_attr->show) ret = bus_attr->show(bus_priv->bus, buf); return ret; }
最终是调用bus_attr的show方法,就是:
static ssize_t show_bus_version(struct bus_type *bus, char *buf) { return snprintf(buf, PAGE_SIZE, "%s\n", Version); } static BUS_ATTR(version, S_IRUGO, show_bus_version, NULL);
根据这个流程走下来,再根据kobject-example.c和lddbus的例子,我们可以很清晰的了解sysfs中属性文件的读写过程。
sysfs到分析到这里了,我们整体上把握了sysfs的安装挂载,目录文件的创建和读写操作。
因为sysfs是将设备模型导入到用户空间的内存文件系统,下面我们就要由sysfs来看kobject,也就是linux的设备模型了。
相关文章推荐
- linux文件系统的系统分析--(九)sysfs下属性文件的读写
- linux文件系统的系统分析--(七)sysfs下属性文件的创建
- linux文件系统的系统分析--(九)sysfs下属性文件的读写
- linux文件系统的系统分析--(七)sysfs下属性文件的创建
- linux文件系统的系统分析--(七)sysfs下属性文件的创建
- linux文件系统的系统分析--(十三)sysfs和设备模型--Device
- 统一设备模型(四):sysfs文件系统的分析
- 改变文件系统的读写属性
- 文件系统读写--文件写过程代码分析
- linux文件系统的系统分析--(十一)sysfs和设备模型--Bus
- sysfs文件系统之读写文件
- 分布式文件系统读写性能分析
- linux文件系统的系统分析--(十六)sysfs和设备模型--从platform和rtc来感受设备模型
- UBIFS文件系统分析5 - 文件读写 .
- Linux 内核/sys 文件系统之sysfs 属性文件
- sysfs 文件系统 通过设备属性访问硬件(DEVICE_ATTR, LINUX)
- UBIFS文件系统分析三之通过VFS的读写流程
- linux文件系统的系统分析--(四)sysfs的安装和挂载
- linux文件系统的系统分析--(四)sysfs的安装和挂载
- Linux 内核/sys 文件系统之sysfs 属性文件