sysfsWord文档下载推荐.docx

上传人:b****5 文档编号:20776025 上传时间:2023-01-25 格式:DOCX 页数:26 大小:24.82KB
下载 相关 举报
sysfsWord文档下载推荐.docx_第1页
第1页 / 共26页
sysfsWord文档下载推荐.docx_第2页
第2页 / 共26页
sysfsWord文档下载推荐.docx_第3页
第3页 / 共26页
sysfsWord文档下载推荐.docx_第4页
第4页 / 共26页
sysfsWord文档下载推荐.docx_第5页
第5页 / 共26页
点击查看更多>>
下载资源
资源描述

sysfsWord文档下载推荐.docx

《sysfsWord文档下载推荐.docx》由会员分享,可在线阅读,更多相关《sysfsWord文档下载推荐.docx(26页珍藏版)》请在冰豆网上搜索。

sysfsWord文档下载推荐.docx

err=register_filesystem(&

sysfs_fs_type);

if(!

err){

//挂载sysfs文件系统

sysfs_mount=kern_mount(&

if(IS_ERR(sysfs_mount)){

printk(KERN_ERR"

sysfs:

couldnotmount!

\n"

);

err=PTR_ERR(sysfs_mount);

sysfs_mount=NULL;

unregister_filesystem(&

}

}else

out:

returnerr;

out_err:

kmem_cache_destroy(sysfs_dir_cachep);

sysfs_dir_cachep=NULL;

gotoout;

}

每个kobject对应sysfs中的一个目录,kobject的每个属性对应sysfs文件系统中的文件.

structsysfs_dirent就是用来做kobject与dentry的互相转换用的.它们的关系如下图所示:

上图表示的是一个kobject的层次结构.dentry的d_fsdata字段指定该结点所表示的

sysfs_dirent.sysfs_dirent.s_parent表示它的父kobject.sysfs_dirent.s_sibling表示它的兄弟结点.

sysfs_dirent.s_dir.children表示它所属的子节点.

从上图可知.如果要遍历一个结点下面的子结点,只需要找到sysfs_dirent.s_dir.children结点

然后按着子节点的s_sibling域遍历即可.

当然,有时候也需要从structsysfs_dirent导出它所属的dentry结点.我们在代码中遇到的时候再进行分

析.

Sysfs文件系统的file_system_type定义如下:

staticstructfile_system_typesysfs_fs_type={

.name 

="

sysfs"

.get_sb 

=sysfs_get_sb,

.kill_sb 

=kill_anon_super,

};

通过前面文件系统的相关分析,我们知道在sys_mount()中最终会调用structfile_system_type的get_sb

函数来实现文件系统的挂载.它的代码如下:

staticintsysfs_get_sb(structfile_system_type*fs_type,

intflags,constchar*dev_name,void*data,structvfsmount*mnt)

returnget_sb_single(fs_type,flags,data,sysfs_fill_super,mnt);

get_sb_single()的代码在前面已经涉及到,它对super_block.以及挂载的dentry和inode的赋值是在回调

函数sysfs_fill_super,mnt()中完成的.代码如下:

staticintsysfs_fill_super(structsuper_block*sb,void*data,intsilent)

structinode*inode;

structdentry*root;

sb->

s_blocksize=PAGE_CACHE_SIZE;

s_blocksize_bits=PAGE_CACHE_SHIFT;

s_magic=SYSFS_MAGIC;

s_op=&

sysfs_ops;

s_time_gran=1;

sysfs_sb=sb;

/*getrootinode,initializeandunlockit*/

inode=sysfs_get_inode(&

sysfs_root);

inode){

pr_debug("

couldnotgetrootinode\n"

return-ENOMEM;

/*instantiateandlinkrootdentry*/

root=d_alloc_root(inode);

root){

%s:

couldnotgetrootdentry!

__FUNCTION__);

iput(inode);

//将sysfs_root关联到root

root->

d_fsdata=&

sysfs_root;

s_root=root;

return0;

在这里要注意几个全局量.sysfs_sb表示sysfs文件系统的super_block.sysfs_root表示sysfs文件系统

根目录的structsysfs_dirent.

sysfs_get_inode(&

sysfs_root)用来将sysfs_root导出相应的inode.代码如下:

structinode*sysfs_get_inode(structsysfs_dirent*sd)

//以super_block和sd->

s_ino为哈希值,到哈希表中寻找相应的inode.如果不存在,则新建

inode=iget_locked(sysfs_sb,sd->

s_ino);

//对新生成的inode进行初始化

if(inode&

&

(inode->

i_state&

I_NEW))

sysfs_init_inode(sd,inode);

returninode;

首先,它以sysfs文件系统的super_block和structsysfs_dirent.的s_ino成员的值做为哈希值到哈希表中

寻找相应的inode.如果在哈希表中不存在这个inode,那就新建一个,并将它链入到哈希表.之后,调用

sysfs_init_inode()对生成的inode进行初始化.显然.在mount的时候是不会生成inode的.必定会进入

sysfs_init_inode()函数.代码如下:

staticvoidsysfs_init_inode(structsysfs_dirent*sd,structinode*inode)

structbin_attribute*bin_attr;

inode->

i_blocks=0;

i_mapping->

a_ops=&

sysfs_aops;

backing_dev_info=&

sysfs_backing_dev_info;

i_op=&

sysfs_inode_operations;

i_ino=sd->

s_ino;

lockdep_set_class(&

i_mutex,&

sysfs_inode_imutex_key);

if(sd->

s_iattr){

/*sysfs_direnthasnon-defaultattributes

*getthemforthenewinodefrompersistentcopy

*insysfs_dirent

*/

set_inode_attr(inode,sd->

s_iattr);

set_default_inode_attr(inode,sd->

s_mode);

/*initializeinodeaccordingtotype*/

switch(sysfs_type(sd)){

caseSYSFS_DIR:

 

i_op=&

sysfs_dir_inode_operations;

i_fop=&

sysfs_dir_operations;

i_nlink=sysfs_count_nlink(sd);

break;

caseSYSFS_KOBJ_ATTR:

i_size=PAGE_SIZE;

i_fop=&

sysfs_file_operations;

caseSYSFS_KOBJ_BIN_ATTR:

bin_attr=sd->

s_bin_attr.bin_attr;

i_size=bin_attr->

size;

bin_fops;

caseSYSFS_KOBJ_LINK:

sysfs_symlink_inode_operations;

default:

BUG();

unlock_new_inode(inode);

在这里,我们可以看到sysfs文件系统中的各种操作函数了..

在syfs文件系统中,怎么样判断一个目录下是否有这个文件呢?

在前面有关文件系统的分析中我们可以看.有关文件的查找实际上都会由inod->

i_op->

lookup()函数进行

判断.在sysfs中,这个函数对应为sysfs_lookup().代码如下:

staticstructdentry*sysfs_lookup(structinode*dir,structdentry*dentry,

structnameidata*nd)

structdentry*ret=NULL;

//取得父结点对应的sysfs_dirent

structsysfs_dirent*parent_sd=dentry->

d_parent->

d_fsdata;

structsysfs_dirent*sd;

mutex_lock(&

sysfs_mutex);

//父结点的sysfs_dirent中是否有相应的子结点

sd=sysfs_find_dirent(parent_sd,dentry->

d_name.name);

/*nosuchentry*/

//如果没有.这个结点是不存在的

sd){

ret=ERR_PTR(-ENOENT);

gotoout_unlock;

/*attachdentryandinode*/

//如果有这个结点,为之生成inod结构.

inode=sysfs_get_inode(sd);

ret=ERR_PTR(-ENOMEM);

/*instantiateandhashdentry*/

dentry->

d_op=&

sysfs_dentry_ops;

//关联dentry与sysfs_dirent

d_fsdata=sysfs_get(sd);

d_instantiate(dentry,inode);

d_rehash(dentry);

out_unlock:

mutex_unlock(&

returnret;

由此可见,它的判断会转入到相应的sysfs_dirent中进行判断.如果设备模型在创建目录/文件的时候并不

会创建dentry或者inode.只会操作sysfs_dirent结构.如果找到了这个结构,就为这个结构生成inode.并

将其关联到denry中.

sysfs_find_dirent()如下:

structsysfs_dirent*sysfs_find_dirent(structsysfs_dirent*parent_sd,

constunsignedchar*name)

for(sd=parent_sd->

s_dir.children;

sd;

sd=sd->

s_sibling)

strcmp(sd->

s_name,name))

returnsd;

returnNULL;

它用的搜索方法就是我们在之前分析sysfs_dirent结构所讲述的.分析到这里,sysfs的大概轮廓就出现在

我们的眼前了.^_^.接下来分析sysfs文件系统中目录的创建过程

三:

在sysfs文件系统中创建目录

在linux设备模型中,每注册一个kobject.就会为之创建一个目录.具体的流程在分析linux设备模型的时候

再给出详细的分析.创建目录的接口为:

sysfs_create_dir().代码如下:

intsysfs_create_dir(structkobject*kobj)

structsysfs_dirent*parent_sd,*sd;

interror=0;

BUG_ON(!

kobj);

//如果kobject没有指定父结点,则将其父结点指定为sysfs的根目录syfs_root

if(kobj->

parent)

parent_sd=kobj->

parent->

sd;

else

parent_sd=&

//创建目录

error=create_dir(kobj,parent_sd,kobject_name(kobj),&

sd);

//kobj->

sd指向对应的sysfs_dirent

error)

kobj->

sd=sd;

returnerror;

在这里,先为结点指定父目录,然后调用create_dir()在父目录下生成结点.代码如下:

staticintcreate_dir(structkobject*kobj,structsysfs_dirent*parent_sd,

constchar*name,structsysfs_dirent**p_sd)

//指定目录的模式

umode_tmode=S_IFDIR|S_IRWXU|S_IRUGO|S_IXUGO;

structsysfs_addrm_cxtacxt;

intrc;

/*allocate*/

//分配并初始化一个sysfs_dirent

sd=sysfs_new_dirent(name,mode,SYSFS_DIR);

sd)

//初始化sd->

s_dir.kobj字段

sd->

s_dir.kobj=kobj;

/*linkin*/

//acxt是一个临时变量.它用来存放父结点的相关信息

//设置acxt->

parent_sd 

为父结点的sysfs_dirent.acxt->

parent_inode为父结点的inode

sysfs_addrm_start(&

acxt,parent_sd);

//设置sd->

s_parent.并按inod值按顺序链入父结点的children链表

rc=sysfs_add_one(&

acxt,sd);

sysfs_addrm_finish(&

acxt);

if(rc==0)

*p_sd=sd;

sysfs_put(sd);

returnrc;

在这里,为子节点生成了对应的sysfs_dirent.设置了它的父结点域,并将其链入到父结点的children链表.

这样,在文件系统中查找父目录下面的子结点了.

四:

在sysfs中创建一般属性文件

Kobject的每一项属性都对应在sysfs文件系统中,kobject对应的目录下的一个文件.文件名称与属性名称

相同.创建一般属性的接口为sysfs_create_file().代码如下:

intsysfs_create_file(structkobject*kobj,conststructattribute*attr)

kobj||!

sd||!

attr);

//kobject->

sd:

为kobject表示目录的structsysfs_dirent结构

returnsysfs_add_file(kobj->

sd,attr,SYSFS_KOBJ_ATTR);

最终会调用sysfs_add_file().参数attr.是要生成文件的属性值.

intsysfs_add_file(structsysfs_dirent*dir_sd,conststructattribute*attr,

inttype)

//文件对应的属性

umode_tmode=(attr->

mode&

S_IALLUGO)|S_IFREG;

//创建一个新的sysfs_dirent.对应的名称为attr->

name.即属性的名称

sd=sysfs_new_dirent(attr->

name,mode,type);

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 工作范文 > 行政公文

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1