sysfs文件系统和procfs类似,也是一种内存文件系统, 它不仅能提供内核信息查看和配置功能,在Linux 中它还有一个重要的功能,就是为linux设备模型提供统一的管理. 如果要深入研究linux设备模型,那就要先从sysfs入手.
sysfs初始化
sysfs文件系统默认是被编译到内核中的,初始化函数流程为sysfs_init()->register_filesystem()->kern_mount();
在挂载sysfs中需要关注的一个函数sysfs_fill_super();
42 static int sysfs_fill_super(struct super_block *sb, void *data, int silent)
43 {
44 struct inode *inode;
45 struct dentry *root;
46
47 sb->s_blocksize = PAGE_CACHE_SIZE;
48 sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
49 sb->s_magic = SYSFS_MAGIC;
50 sb->s_op = &sysfs_ops;
51 sb->s_time_gran = 1;
52 sysfs_sb = sb;
53
54 /* get root inode, initialize and unlock it */
55 inode = sysfs_get_inode(&sysfs_root);
56 if (!inode) {
57 pr_debug("sysfs: could not get root inode\n");
58 return -ENOMEM;
59 }
60
61 /* instantiate and link root dentry */
62 root = d_alloc_root(inode);
63 if (!root) {
64 pr_debug("%s: could not get root dentry!\n",__func__);
65 iput(inode);
66 return -ENOMEM;
67 }
68 root->d_fsdata = &sysfs_root;
69 sb->s_root = root;
70 return 0;
71 }
第55行分配sysfs根目录Inode ,第62行建立根目录dentry .
第68行是把sysfs根目录的sysfs_dirent对象(sysfs_root) 初始化给根目录dentry->d_fsdata ,这是很中要的,在后面sysfs动态建立文件时可以看到它的用处.
sysfs分配inode函数流程为sysfs_get_inode()->iget_locked()->sysfs_init_inode() ,接下来需要看看sysfs是如何初始化inode的.
148 static void sysfs_init_inode(struct sysfs_dirent *sd, struct inode *inode)
149 {
150 struct bin_attribute *bin_attr;
151
152 inode->i_blocks = 0;
153 inode->i_mapping->a_ops = &sysfs_aops;
154 inode->i_mapping->backing_dev_info = &sysfs_backing_dev_info;
155 inode->i_op = &sysfs_inode_operations;
156 inode->i_ino = sd->s_ino;
157 lockdep_set_class(&inode->i_mutex, &sysfs_inode_imutex_key);
158
159 if (sd->s_iattr) {
160 /* sysfs_dirent has non-default attributes
161 * get them for the new inode from persistent copy
162 * in sysfs_dirent
163 */
164 set_inode_attr(inode, sd->s_iattr);
165 } else
166 set_default_inode_attr(inode, sd->s_mode);
167
168
169 /* initialize inode according to type */
170 switch (sysfs_type(sd)) {
171 case SYSFS_DIR:
172 inode->i_op = &sysfs_dir_inode_operations;
173 inode->i_fop = &sysfs_dir_operations;
174 inode->i_nlink = sysfs_count_nlink(sd);
175 break;
176 case SYSFS_KOBJ_ATTR:
177 inode->i_size = PAGE_SIZE;
178 inode->i_fop = &sysfs_file_operations;
179 break;
180 case SYSFS_KOBJ_BIN_ATTR:
181 bin_attr = sd->s_bin_attr.bin_attr;
182 inode->i_size = bin_attr->size;
183 inode->i_fop = &bin_fops;
184 break;
185 case SYSFS_KOBJ_LINK:
186 inode->i_op = &sysfs_symlink_inode_operations;
187 break;
188 default:
189 BUG();
190 }
191
192 unlock_new_inode(inode);
193 }
第171行 case SYSFS_DIR 说明这个文件是sysfs下的目录文件, 然后初始化inode操作方法为sysfs_dir_inode_operations ,目录文件操作方法为sysfs_dir_operations,
第176行case SYSFS_KOBJ_ATTR: 说明这个文件是sysfs下的属性文件, 初始化文件操作方法为sysfs_file_operations
第180行 case SYSFS_KOBJ_BIN_ATTR:该文件是一个二进制文件,初始化文件文件操作方法为bin_fops.
第185行 case SYSFS_KOBJ_LINK:,文件是一个符号链接文件,初始化索引节点操作方法为sysfs_symlink_inode_operations .