sysfs 文件系统简单分析
2011-10-22 19:26
295 查看
01int __init sysfs_init(void) 02{ 03 int err = -ENOMEM; 04 05 sysfs_dir_cachep = kmem_cache_create("sysfs_dir_cache", 06 sizeof(struct sysfs_dirent), 07 0, 0, NULL); 08 if (!sysfs_dir_cachep) 09 goto out; 10 11 err = sysfs_inode_init(); 12 if (err) 13 goto out_err; 14 15 err = register_filesystem(&sysfs_fs_type); 16 if (!err) { 17 sysfs_mount = kern_mount(&sysfs_fs_type); 18 if (IS_ERR(sysfs_mount)) { 19 printk(KERN_ERR "sysfs: could not mount!\n"); 20 err = PTR_ERR(sysfs_mount); 21 sysfs_mount = NULL; 22 unregister_filesystem(&sysfs_fs_type); 23 goto out_err; 24 } 25 } else 26 goto out_err; 27out: 28 return err; 29out_err: 30 kmem_cache_destroy(sysfs_dir_cachep); 31 sysfs_dir_cachep = NULL; 32 goto out; 33}第5行对sysfs_dir_cachep指针分配空间
第15行注册sysfs文件系统。
第17行挂载sysfs文件系统。
第18-23行挂载文件系统失败后,会卸载文件系统。
第29-32行注册文件系统失败后,所做的一些处理,销毁分配的内存,设置sysfs_dir_cachep的指针为空。
[/code]
1static struct file_system_type sysfs_fs_type = { 2 .name = "sysfs", 3 .get_sb = sysfs_get_sb, 4 .kill_sb = kill_anon_super, 5};
第2行文件系统的名字 第3行分配超级块 第4行卸载文件系统后,释放超级块所占有的资源
1static int sysfs_get_sb(struct file_system_type *fs_type, 2 int flags, const char *dev_name, void *data, struct vfsmount *mnt) 3{ 4 return get_sb_single(fs_type, flags, data, sysfs_fill_super, mnt); 5} 01int get_sb_single(struct file_system_type *fs_type, 02 int flags, void *data, 03 int (*fill_super)(struct super_block *, void *, int), 04 struct vfsmount *mnt) 05{ 06 struct super_block *s; 07 int error; 08 09 s = sget(fs_type, compare_single, set_anon_super, NULL); 10 if (IS_ERR(s)) 11 return PTR_ERR(s); 12 if (!s->s_root) { 13 s->s_flags = flags; 14 error = fill_super(s, data, flags & MS_SILENT ? 1 : 0); 15 if (error) { 16 deactivate_locked_super(s); 17 return error; 18 } 19 s->s_flags |= MS_ACTIVE; 20 } 21 do_remount_sb(s, flags, data, 0); 22 simple_set_mnt(mnt, s); 23 return 0; 24}
第9行调用sget()函数分配新的超级块,传递set_anon_super()函数的地址作为参数。用合适的方式设置超级块的s_dev字段。
第10行将flags参数的值拷到超级块的s_flags字段中。
第11行的函数指针指向sysfs_fill_super函数,来分配索引节点对象和对应的目录项对象,并填充超级块字段的值。
01static int sysfs_fill_super(struct super_block *sb, void *data, int silent) 02{ 03 struct inode *inode; 04 struct dentry *root; 05 06 sb->s_blocksize = PAGE_CACHE_SIZE; 07 sb->s_blocksize_bits = PAGE_CACHE_SHIFT; 08 sb->s_magic = SYSFS_MAGIC; 09 sb->s_op = &sysfs_ops; 10 sb->s_time_gran = 1; 11 sysfs_sb = sb; 12 13 /* get root inode, initialize and unlock it */ 14 mutex_lock(&sysfs_mutex); 15 inode = sysfs_get_inode(&sysfs_root); 16 mutex_unlock(&sysfs_mutex); 17 if (!inode) { 18 pr_debug("sysfs: could not get root inode\n"); 19 return -ENOMEM; 20 } 21 22 /* instantiate and link root dentry */ 23 root = d_alloc_root(inode); 24 if (!root) { 25 pr_debug("%s: could not get root dentry!\n",__func__); 26 iput(inode); 27 return -ENOMEM; 28 } 29 root->d_fsdata = &sysfs_root; 30 sb->s_root = root; 31 return 0; 32} 33
第6行给超级块的文件的最长长度赋值
第7行给超级块的字节为单位的块大小的字段赋值
第9行超级块的方法指向sysfs_ops结构体的地址
第10行超级块时间戳的粒度赋值
第11行把超级块的指针赋给全局的指针syssb
第14行对变量sysfs_mutex加锁
第15行得到sysfs_dirent的节点,如果没有这个节点,分配新的节点,如果有的话,利用哈希表的方式找出来。
第23行实例和链接根目录
第29行root的d_fsdata字段指向sysfs_root。
第30行超级块的根目录指向root目录
01struct inode * sysfs_get_inode(struct sysfs_dirent *sd) 02{ 03 struct inode *inode; 04 05 inode = iget_locked(sysfs_sb, sd->s_ino); 06 if (inode && (inode->i_state & I_NEW)) 07 sysfs_init_inode(sd, inode); 08 09 return inode; 10}
第5行从挂载的文件系统中获得节点,使用ifind_fast函数搜索结点按节点号在inode 缓存里面。如果出现,增加一个引用,如果节点不在缓存里面,调用get_new_inode_fast函数返回一个新节点。
第7行初始化一个新节点
01static void sysfs_init_inode(struct sysfs_dirent *sd, struct inode *inode) 02{ 03 struct bin_attribute *bin_attr; 04 05 inode->i_private = sysfs_get(sd); 06 inode->i_mapping->a_ops = &sysfs_aops; 07 inode->i_mapping->backing_dev_info = &sysfs_backing_dev_info; 08 inode->i_op = &sysfs_inode_operations; 09 inode->i_ino = sd->s_ino; 10 lockdep_set_class(&inode->i_mutex, &sysfs_inode_imutex_key); 11 12 if (sd->s_iattr) { 13 /* sysfs_dirent has non-default attributes 14 * get them for the new inode from persistent copy 15 * in sysfs_dirent 16 */ 17 set_inode_attr(inode, sd->s_iattr); 18 } else 19 set_default_inode_attr(inode, sd->s_mode); 20 21 22 /* initialize inode according to type */ 23 switch (sysfs_type(sd)) { 24 case SYSFS_DIR: 25 inode->i_op = &sysfs_dir_inode_operations; 26 inode->i_fop = &sysfs_dir_operations; 27 inode->i_nlink = sysfs_count_nlink(sd); 28 break; 29 case SYSFS_KOBJ_ATTR: 30 inode->i_size = PAGE_SIZE; 31 inode->i_fop = &sysfs_file_operations; 32 break; 33 case SYSFS_KOBJ_BIN_ATTR: 34 bin_attr = sd->s_bin_attr.bin_attr; 35 inode->i_size = bin_attr->size; 36 inode->i_fop = &bin_fops; 37 break; 38 case SYSFS_KOBJ_LINK: 39 inode->i_op = &sysfs_symlink_inode_operations; 40 break; 41 default: 42 BUG(); 43 } 44 45 unlock_new_inode(inode); 46}
第6行对索引节点的指向address_space对象的方法赋值(后面会分析)
第7行对索引节点的指向address_space对象的设备信息赋值
第8行索引节点的方法指向sysfs_inode_operations
下面是根据索引节点的类型,分别进行初始化。
第24行如果索引节点是目录,分别对索引节点的方法进行赋值。
第29行如果索引节点是属性文件,分别对其赋值
第33行如果索引节点是二进制文件,分别对其赋值。
第38行如果是链接文件,对它的方法进行初始化。
01struct dentry * d_alloc_root(struct inode * root_inode) 02{ 03 struct dentry *res = NULL; 04 05 if (root_inode) { 06 static const struct qstr name = { .name = "/", .len = 1 }; 07 08 res = d_alloc(NULL, &name); 09 if (res) { 10 res->d_sb = root_inode->i_sb; 11 res->d_parent = res; 12 d_instantiate(res, root_inode); 13 } 14 } 15 return res; 16}
第5行判断root_inode的节点是否为真。
第6行对name结构体初始化
第8行分配一个dcache 目录
第10行目录项的超级块指向指向索引节点的超级块指针
第11行目录项的父指针指向自己
第12填充索引节点信息为根目录。
相关文章推荐
- linux文件系统的系统分析--(十六)sysfs和设备模型--从platform和rtc来感受设备模型
- linux文件系统的系统分析--(六)sysfs下目录的创建
- Sysfs文件系统read流程安全性分析
- rootfs文件系统简单分析
- 统一设备模型(四):sysfs文件系统的分析
- rootfs文件系统的简单分析
- Glusterfs文件系统简介和源码简单分析
- linux文件系统的系统分析--(九)sysfs下属性文件的读写
- linux文件系统的系统分析--(四)sysfs的安装和挂载
- linux文件系统的系统分析--(六)sysfs下目录的创建
- linux文件系统的系统分析--(十六)sysfs和设备模型--从platform和rtc来感受设备模型
- linux文件系统的系统分析--(七)sysfs下属性文件的创建
- linux文件系统的系统分析--(七)sysfs下属性文件的创建
- linux文件系统的系统分析--(九)sysfs下属性文件的读写
- linux文件系统的系统分析--(八)sysfs中sysfs_dirent与inode dentry的关系
- linux文件系统的系统分析--(八)sysfs中sysfs_dirent与inode dentry的关系
- 20135337——Linux实践三:ELF文件格式(64位系统,简单分析)
- 根文件系统分析之旅——简单分析(一)
- linux文件系统的系统分析--(九)sysfs下属性文件的读写
- linux文件系统的系统分析--(十四)sysfs和设备模型--Driver