Linux那些事儿之我是Sysfs(6)文件系统
接下来,我们进入sysfs部分。看看
kobject_add()->kobject_add_varg->kobject_add_internal->create_dir()->sysfs_create_dir_ns()
bus_create_file()->sysfs_create_file()
. . .
这些sysfs函数的内幕。
说白了,sysfs就是利用VFS的接口去读写kobject的层次结构,建立起来的文件系统。关于sysfs的内容就在fs/sysfs/下。 kobject的层次结构的更新与删除就是那些乱七八糟的XX_register()们干的事情。
在kobject_add()里面,调用了sysfs_create_dir_ns()。让我们看看它究竟是如何create的。
int sysfs_create_dir_ns(struct kobject *kobj, const void *ns)
{
struct kernfs_node *parent, *kn;
BUG_ON(!kobj);
if (kobj->parent)
parent = kobj->parent->sd;
else
parent = sysfs_root_kn;
if (!parent)
return -ENOENT;
kn = kernfs_create_dir_ns(parent, kobject_name(kobj),
S_IRWXU | S_IRUGO | S_IXUGO, kobj, ns);
if (IS_ERR(kn)) {
if (PTR_ERR(kn) == -EEXIST)
sysfs_warn_dup(parent, kobject_name(kobj));
return PTR_ERR(kn);
}
kobj->sd = kn;
return 0;
}
当你看见这么些新东西,如kernfs_node出现的时候,你一定感到很困惑。诚然,我一度为代码中突然出现的事物感到恐慌,人类对未知的恐惧是与生俱来的,面对死亡,面对怪力乱神,我们抱着一颗敬畏的心灵就可以了。而面对linux,我们始终坚信,未知肯定是可以被探索出来的。妖是妖他妈生的,代码是人他妈写出来的,既然写得出来,那就肯定看得懂。对不起,扯远了....我还是介绍介绍文件系统的基本知识先。
文件系统
文件系统是个很模糊广泛的概念,"文件"狭义地说,是指磁盘文件,广义理解,可以是有组织有次序地存储与任何介质(包括内存)的一组信息。linux把所有的资源都看成是文件,让用户通过一个统一的文件系统操作界面,也就是同一组系统调用,对属于不同文件系统的文件进行操作。这样,就可以对用户程序隐藏各种不同文件系统的实现细节,为用户程序提供了一个统一的,抽象的,虚拟的文件系统界面,这就是所谓"VFS(Virtual Filesystem Switch)"。这个抽象出来的接口就是一组函数操作。
我们要实现一种文件系统就是要实现VFS所定义的一系列接口,file_operations, dentry_operations, inode_operations等,供上层调用。file_operations是对每个具体文件的读写操作,dentry_operations, inode_operations则是对文件的属性,如改名字,建立或删除的操作。
include/linux/fs.h
struct file_operations {
struct module *owner;
loff_t (*llseek) (struct file *, loff_t, int);
ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
ssize_t (*aio_read) (struct kiocb *, const struct iovec *, unsigned long, loff_t);
ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t);
ssize_t (*read_iter) (struct kiocb *, struct iov_iter *);
ssize_t (*write_iter) (struct kiocb *, struct iov_iter *);
int (*iterate) (struct file *, struct dir_context *);
unsigned int (*poll) (struct file *, struct poll_table_struct *);
long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
int (*mmap) (struct file *, struct vm_area_struct *);
int (*open) (struct inode *, struct file *);
int (*flush) (struct file *, fl_owner_t id);
int (*release) (struct inode *, struct file *);
int (*fsync) (struct file *, loff_t, loff_t, int datasync);
int (*aio_fsync) (struct kiocb *, int datasync);
int (*fasync) (int, struct file *, int);
int (*lock) (struct file *, int, struct file_lock *);
ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);
unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
int (*check_flags)(int);
int (*flock) (struct file *, int, struct file_lock *);
ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int);
ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int);
int (*setlease)(struct file *, long, struct file_lock **, void **);
long (*fallocate)(struct file *file, int mode, loff_t offset,
loff_t len);
int (*show_fdinfo)(struct seq_file *m, struct file *f);
};
include/linux/dcache.h
struct dentry_operations {
int (*d_revalidate)(struct dentry *, unsigned int);
int (*d_weak_revalidate)(struct dentry *, unsigned int);
int (*d_hash)(const struct dentry *, struct qstr *);
int (*d_compare)(const struct dentry *, const struct dentry *,
unsigned int, const char *, const struct qstr *);
int (*d_delete)(const struct dentry *);
void (*d_release)(struct dentry *);
void (*d_prune)(struct dentry *);
void (*d_iput)(struct dentry *, struct inode *);
char *(*d_dname)(struct dentry *, char *, int);
struct vfsmount *(*d_automount)(struct path *);
int (*d_manage)(struct dentry *, bool);
}
include/linux/fs.h
struct inode_operations {
struct dentry * (*lookup) (struct inode *,struct dentry *, unsigned int);
void * (*follow_link) (struct dentry *, struct nameidata *);
int (*permission) (struct inode *, int);
struct posix_acl * (*get_acl)(struct inode *, int);
int (*readlink) (struct dentry *, char __user *,int);
void (*put_link) (struct dentry *, struct nameidata *, void *);
int (*create) (struct inode *,struct dentry *, umode_t, bool);
int (*link) (struct dentry *,struct inode *,struct dentry *);
int (*unlink) (struct inode *,struct dentry *);
int (*symlink) (struct inode *,struct dentry *,const char *);
int (*mkdir) (struct inode *,struct dentry *,umode_t);
int (*rmdir) (struct inode *,struct dentry *);
int (*mknod) (struct inode *,struct dentry *,umode_t,dev_t);
int (*rename) (struct inode *, struct dentry *,
struct inode *, struct dentry *);
int (*rename2) (struct inode *, struct dentry *,
struct inode *, struct dentry *, unsigned int);
int (*setattr) (struct dentry *, struct iattr *);
int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *);
int (*setxattr) (struct dentry *, const char *,const void *,size_t,int);
ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);
ssize_t (*listxattr) (struct dentry *, char *, size_t);
int (*removexattr) (struct dentry *, const char *);
int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start,
u64 len);
int (*update_time)(struct inode *, struct timespec *, int);
int (*atomic_open)(struct inode *, struct dentry *,
struct file *, unsigned open_flag,
umode_t create_mode, int *opened);
int (*tmpfile) (struct inode *, struct dentry *, umode_t);
int (*set_acl)(struct inode *, struct posix_acl *, int);
/* WARNING: probably going away soon, do not use! */
int (*dentry_open)(struct dentry *, struct file *, const struct cred *);
}
举个例子,我们写C程序,open(“hello.c”, O_RDONLY),它通过系统调用的流程是这样的
open() -> /*用户空间*/
-> 系统调用->
sys_open() -> file_operations->open() /*内核空间*/
不同的文件系统,调用不同的file_operations->open(),在sysfs下就是sysfs_open_file()。
Linux那些事儿之我是Sysfs(6)文件系统相关推荐
- Linux那些事儿之我是Sysfs(9)sysfs文件系统模型
最近Linus炮轰C++,"C++是一种糟糕的(horrible)语言.而且因为有大量不够标准的程序员在使用而使许多真正懂得底层问题,而不会折腾那些白痴'对象模型'".牛人就是牛气 ...
- Linux那些事儿之我是Sysfs(11)sysfs 创建普通文件
sysfs文件系统中,普通文件对应于kobject中的属性.用sysfs_create_file(),参数如下: sysfs_create_file(struct kobject * kobj, co ...
- Linux那些事儿之我是Sysfs(8)一起散散步-pathwalk
前面说过,只要知道文件的索引节点号,就可以得到那个文件.但是我们在操作文件时,从没听说谁会拿着索引节点号来操作文件,我们只知道文件名而已.它们是如何"和谐"起来的呢?linux把目 ...
- Linux那些事儿之我是Sysfs(7)dentry与inode
我们在进程中要怎样去描述一个文件呢?我们用目录项(dentry)和索引节点(inode).它们的定义如下: include/linux/dcache.h struct dentry { /* RCU ...
- Linux那些事儿之我是Sysfs(3)设备模型上层容器
§1 bus 系统中总线由struct bus_type描述,定义为: include/linux/device.h struct bus_type { const char *name;总线类型的名 ...
- Linux那些事儿之我是Sysfs(2)linux设备底层模型
关于linux设备模型网上有一些论述,有些东西我就用了拿来主义,进行了修改和整理. §1 Kobject Kobject 是Linux 2.6引入的新的设备管理机制,在内核中由struct kobje ...
- Linux那些事儿之我是Sysfs(1)sysfs初探
"sysfs is a ram-based filesystem initially based on ramfs. It provides a means to export kernel ...
- linux lddbus设备,Linux那些事儿之我是Sysfs(4)举例一lddbus | 技术部落
接下来我们从例子着手 localhost:/home/XX/examples/lddbus#insmod lddbus.ko 此时再看/sys/bus/ 这时就多了一个文件夹ldd.里面的文件构成是这 ...
- linux getdents 例子,Linux那些事儿之我是Sysfs(12)举例三:sysfs读入文件夹内容
上回我们说到,如何创建文件夹和文件.我们发现,在sysfs中,inode并不那么重要.这是因为我们所要读写的信息已经就在内存中,并且已经形成了层次结构.我们只需有dentry,就可以dentry-&g ...
最新文章
- 【5】青龙面板系列教程之Nolanjdc的安装【1月17作者删库,不用尝试了】
- Protobuf之proto文件编写规则
- 查询sql一个字段重复的数据mysql_sql查询按两个字段查询重复记录
- 如何评价一个开源项目——协作影响力
- 这几天微软发布的一些好玩的东西(顺祝女性程序员朋友们节日快乐!)
- 公开课精华 | 无人驾驶中感知的挑战与尝试
- 学python要有多少英语词汇量测试_非常适合新手的一个Python爬虫项目: 打造一个英文词汇量测试脚本!...
- python编程(数据库操作)
- Testbench编写方法
- 智慧园区大数据平台建设方案(ppt)
- 【柒】企业分析利器——强大企业模型
- matlab中men,matlab blackman函数
- 【言简意赅】聊聊DAS、NAS、SAN三种存储方式
- SQL Server 2014下载及安装教程
- 如何在 Excel 表格中查找数据
- 电脑系统知识:Windows原版系统与Ghost系统的区别,你知道吗?
- 前端技术:Vue+elementUI 饿了吗UI+CRUD,创建图书管理系统
- 最常用算法汇总(一)
- normal + lognormal
- git总结的笔记分享给大家,git常用命令。