`
dato0123
  • 浏览: 913554 次
文章分类
社区版块
存档分类
最新评论

Linux那些事儿之我是Sysfs(12)举例三:sysfs读入文件夹内容

 
阅读更多

上回我们说到,如何创建文件夹和文件。我们发现,在sysfs中,inode并不那么重要。这是因为我们所要读写的信息已经就在内存中,并且已经形成了层次结构。我们只需有dentry,就可以dentry->fsdata,就能找到我们读些信息的来源 --- sysfs_dirent结构。这也是我觉得有必要研究 sysfs的原因之一,因为它简单,而且不涉及具体的硬件驱动,但是从这个过程中,我们可以把文件系统中的一些基本数据结构搞清楚。接下来,我以读取sysfs文件和文件夹的内容为例子,讲讲文件读的流程。那么关于写,还有关于symblink的东西完全可以以此类推了。

我们新建文件夹时,设置了
inode->i_op = &sysfs_dir_inode_operations;
inode->i_fop = &sysfs_dir_operations;

struct file_operations sysfs_dir_operations = {
.open = sysfs_dir_open,
.release = sysfs_dir_close,
.llseek = sysfs_dir_lseek,
.read = generic_read_dir,
.readdir = sysfs_readdir,
};

用一个简短的程序来做实验。

#include<sys/types.h>
#include
<dirent.h>
#include
<unistd.h>
intmain()...{
DIR
*dir;
structdirent*ptr;
dir
=opendir("/sys/bus/");
while((ptr=readdir(dir))!=NULL)...{
printf(
"d_name:%s ",ptr->d_name);
}

closedir(dir);
return-1;
}

在用户空间,用gcc编译执行即可。我们来看看它究竟做了什么。

(1)sysfs_dir_open()

这是个用户空间的程序。opendir()是glibc的函数,glibc也就是著名的标准c库。至于opendir ()是如何与sysfs dir open ()接上头的,那还得去看glibc的代码。我就不想分析了...glibc可以从gnu的网站上自己下载源代码,编译。再用gdb调试,就可以看得跟清楚。
函数流程如下:
opendir("/sys/bus/") -> /*用户空间*/
-> 系统调用->
sys_open() -> filp_open()-> dentry_open() -> sysfs_dir_open()/*内核空间*/

staticintsysfs_dir_open(structinode*inode,structfile*file)
...{
structdentry*dentry=file->f_dentry;
structsysfs_dirent*parent_sd=dentry->d_fsdata;
down(
&dentry->d_inode->i_sem);
file
->private_data=sysfs_new_dirent(parent_sd,NULL);
up(
&dentry->d_inode->i_sem);
returnfile->private_data?0:-ENOMEM;
}

内核空间:新建一个dirent结构,连入父辈的dentry中,并将它地址保存在file->private_data中。这个dirent的具体作用待会会讲。
用户空间:新建了一个DIR结构,DIR结构如下。

#define __dirstream DIR
struct __dirstream
{
int fd; /* File descriptor. */
char *data; /* Directory block. */
size_t allocation; /* Space allocated for the block. */
size_t size; /* Total valid data in the block. */
size_t offset; /* Current offset into the block. */
off_t filepos; /* Position of next entry to read. */
__libc_lock_define (, lock) /* Mutex lock for this structure. */
};

(2)sysfs_readdir()

流程如下:


readdir(dir) -> getdents() ->/*用户空间*/
-> 系统调用->
sys32 readdir() -> vfs readdir() -> sysfs readdir()/*内核空间*/

readdir(dir)这个函数有点复杂,虽然在main函数里的while循环中,readdir被执行了多次,我们看看glibc里面的代码

readdir(dir)...{
......
if(dirp->offset>=dirp->size)...{
......
getdents()
......
}

......
}

实际上,getdents() -> ... -> sysfs_readdir()只被调用了两次,getdents()一次就把所有的内容都读完,存在DIR结构当中,readdir()只是从DIR结构当中每次取出一个。DIR(dirstream)结构就是一个流。而回调函数filldir的作用就是往这个流中填充数据。第二次调用getdents()是用户把DIR里面的内容读完了,所以它又调用getdents()但是这次getdents()回返回NULL。

staticintsysfs_readdir(structfile*filp,void*dirent,filldir_tfilldir)
...{
structdentry*dentry=filp->f_dentry;
structsysfs_dirent*parent_sd=dentry->d_fsdata;
structsysfs_dirent*cursor=filp->private_data;
structlist_head*p,*q=&cursor->s_sibling;
ino_tino;
inti=filp->f_pos;
switch(i)...{
case0:
ino
=dentry->d_inode->i_ino;
if(filldir(dirent,".",1,i,ino,DT_DIR)<0)
break;
filp
->f_pos++;
i
++;
/**//*fallthrough*/
case1:
ino
=parent_ino(dentry);
if(filldir(dirent,"..",2,i,ino,DT_DIR)<0)
break;
filp
->f_pos++;
i
++;
/**//*fallthrough*/
default:
if(filp->f_pos==2)...{
list_del(q);
list_add(q,
&parent_sd->s_children);
}

for(p=q->next;p!=&parent_sd->s_children;p=p->next)...{
structsysfs_dirent*next;
constchar*name;
intlen;
next
=list_entry(p,structsysfs_dirent,s_sibling);
if(!next->s_element)
continue;
name
=sysfs_get_name(next);
len
=strlen(name);
if(next->s_dentry)
ino
=next->s_dentry->d_inode->i_ino;
else
ino
=iunique(sysfs_sb,2);
if(filldir(dirent,name,len,filp->f_pos,ino,dt_type(next))<0)
return0;
list_del(q);
list_add(q,p);
p
=q;
filp
->f_pos++;
}

}

return0;
}

看sysfs_readdir()其实很简单,它就是从我们调用sysfs_dir_open()时新建的一个sysfs_dirent结构开始,便利当前dentry->dirent下的所有子sysfs_dirent结构。读出名字,再回调函数filldir()将文件名,文件类型等信息,按照一定的格式写入某个缓冲区。

一个典型的filldir()就是filldir64(),它的作用的按一定格式向缓冲区写数据,再把数据复制到用户空间去。

分享到:
评论

相关推荐

    Linux那些事儿之我是sysfs

    Linux那些事儿之我是sysfs

    Linux那些事儿 之 我是Sysfs下.pdf

    "sysfs is a ram-based filesystem initially based on ramfs. It provides a means to export kernel data structures, their attributes, and the linkages between them to userspace.” --- documentation/file...

    Linux那些事儿之我是Sysfs

    Linux那些事儿之我是Sysfs简单,诙谐的介绍sysfs

    Linux那些事儿

    《Linux那些事儿》分为9个部分。 Linux那些事儿之我是U盘 Linux那些事儿之我是Hub ...Linux那些事儿之我是Sysfs 今天本人将9个单独的文档整理出来,做成了一个单独的文档,配有书签,更加方便读者阅读。

    Linux那些事儿 之 我是Sysfs上.pdf

    "sysfs is a ram-based filesystem initially based on ramfs. It provides a means to export kernel data structures, their attributes, and the linkages between them to userspace.” --- documentation/file...

    Linux那些事儿1-9合集

    由复旦fudan_abc写的,风趣的文笔,深入浅出地讲解了Linux内核相关模块,主要涉及了USB相关的模块,但是同样也解析了Linux驱动模型相关的知识,很值得一读。读过《linux那些事儿之我是U盘》...linux那些事儿之我是Sysfs

    linux那些事儿(EHCI Block SCSI Sysfs PCI USB U 盘 UHCI Hub)

    Linux那些事儿之我是EHCI主机...Linux那些事儿之我是Sysfs.pdf Linux那些事儿之我是PCI.pdf Linux那些事儿之我是USB core.pdf Linux 那些事儿之我是U 盘.pdf Linux那些事儿之我是Hub.pdf Linux那些事儿之我是UHCI.pdf

    Linux那些事儿(linux内核写的很详细)

    Linux那些事儿 Linux那些事儿之我是Block层 Linux那些事儿之我是Sysfs Linux那些事儿之我是U盘

    Linux那些事儿系列.rar

    》包括《Linux那些事儿之我是Hub》、《Linux那些事儿之我是Sysfs》《Linux那些事儿之我是UHCI》、《Linux那些事儿之我是USB core》、《Linux那些事儿之我是U盘》,令人叹为观止的一个linux系列书籍。只能说,江山代...

    linux的那些事儿全集

    Linux那些事儿之我是Block层 Linux那些事儿之我是EHCI主机控制器 Linux那些事儿之我是Hub ...Linux那些事儿之我是Sysfs Linux那些事儿之我是UHCI Linux那些事儿之我是USB core Linux那些事儿之我是U盘

    linux那些事全集

    Linux那些事儿之我是U盘 ...Linux那些事儿之我是Sysfs Linux那些事儿之我是SCSI硬盘 Linux那些事儿之我是PCI Linux那些事儿之我是Hub Linux那些事儿之我是EHCI主机控制器 Linux那些事儿之我是Block层

    Linux那些事儿 系列之2 Block+EHCI+PCI+SCSI

    Linux那些事儿之我是Block层.pdf Linux那些事儿之我是EHCI主机控制器.pdf Linux那些事儿之我是PCI.pdf Linux那些事儿之我是SCSI硬盘.pdf 注: 之前有人已经上传了《Linux那些事儿 系列》,其已经包含了:hub,sysfs...

    Linux那些事儿系列

    本人整理的fudan_abc的专栏中以完结的文章,在此向原作者表示感谢,给...内容包括:linux那些事儿之我是U盘,linux那些事儿之我是USB,linux那些事儿之我是HUB,linux那些事儿之我是UHCI,linux那些事儿之我是Sysfs。

    linux哪些事儿之我是usbcore echi pci u盘 sysfs

    linux哪些事儿之我是usbcore echi pci u盘 sysfs linux哪些事儿之我是usbcore echi pci u盘 sysfs

    Linux那些事儿.rar

    包括:Linux那些Linux那些事儿之我是SCSI硬盘,Linux那些事儿之我是Block层,Linux那些事儿之我是EHCI主机控制器,Linux那些事儿之我是HUB,Linux那些事儿之我是PCI,Linux那些事儿之我是Sysfs,Linux那些事儿之我是...

    Linux那些事系列

    Linux那些事儿之我是Hub Linux那些事儿之我是Sysfs Linux那些事儿之我是UHCI Linux那些事儿之我是USB core Linux那些事儿之我是U盘 Linux那些事之我是HUB1

    linux那些事儿之我是USB.zip

    里面包含Linux那些事的九个文档,Block层,ECHI主机控制,HUB,PCI,SCSI硬盘,Sysfs,UHCI,USB+core,U盘等九个文档,内容详细,而且全面都有书签,适合系统学习!

Global site tag (gtag.js) - Google Analytics