加入收藏 | 设为首页 | 会员中心 | 我要投稿 晋中站长网 (https://www.0354zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 资源网站 > 空间 > 正文

Linux 的虚拟文件系统(真正理解“一切皆文件”)

发布时间:2019-06-15 01:55:37 所属栏目:空间 来源:cpp软件架构狮
导读:1,引言 Linux 中允许众多不同的文件系统共存,如 ext2, ext3, vfat 等。通过使用同一套文件 I/O 系统 调用即可对 Linux 中的任意文件进行操作而无需考虑其所在的具体文件系统格式;更进一步,对文件的 操作可以跨文件系统而执行。如图 1 所示,我们可以使

不管是path_lookup_open()还是path_lookup_create()最终都是调用 __path_lookup_intent_open()来实现查找文件的功能。 查找时,在遍历路径的过程中,会逐层地将各个路径组成部分解析成目录项对象,如果此目录项对象在目录项缓存中,则直接从缓存中获得;如果该目录项在缓存中 不存在,则进行一次实际的读盘操作,从磁盘中读取该目录项所对应的索引节点。得到索引节点后,则建立索引节点与该目录项的联系。如此循环,直到最终找到目 标文件对应的目录项,也就找到了索引节点,而由索引节点找到对应的超级块对象就可知道该文件所在的文件系统的类型。 从磁盘中读取该目录项所对应的索引节点;这将引发VFS和实际的文件系统的一次交互。从前面的VFS理论介绍可知,读索引节点方法是由超级块来提供的。而 当安装一个实际的文件系统时,在内存中创建的超级块的信息是由一个实际文件系统的相关信息来填充的,这里的相关信息就包括了实际文件系统所定义的超级块的 操作函数列表,当然也就包括了读索引节点的具体执行方式。 当继续追踪一个实际文件系统ext3的ext3_read_inode()时,可发现这个函数很重要的一个工作就是为不同的文件类型设置不同的索引节点操 作函数表和文件操作函数表。

清单8. ext3_read_inode

  1. void ext3_read_inode(struct inode * inode) 
  2.  { 
  3.  …… 
  4.  //是普通文件  
  5.  if (S_ISREG(inode->i_mode)) { 
  6.  inode->i_op = &ext3_file_inode_operations; 
  7.  inode->i_fop = &ext3_file_operations; 
  8.  ext3_set_aops(inode); 
  9.  } else if (S_ISDIR(inode->i_mode)) { 
  10.  //是目录文件 
  11.  inode->i_op = &ext3_dir_inode_operations; 
  12.  inode->i_fop = &ext3_dir_operations; 
  13.  } else if (S_ISLNK(inode->i_mode)) { 
  14.  // 是连接文件  
  15.  …… 
  16.  } else {  
  17.  // 如果以上三种情况都排除了,则是设备驱动 
  18.  //这里的设备还包括套结字、FIFO等伪设备  
  19.  ……  

3.1.2 nameidata_to_filp子函数:__dentry_open

这是VFS与实际的文件系统联系的一个关键点。从3.1.1小节分析中可知,调用实际文件系统读取索引节点的方法读取索引节点时,实际文件系统会根据文件 的不同类型赋予索引节点不同的文件操作函数集,如普通文件有普通文件对应的一套操作函数,设备文件有设备文件对应的一套操作函数。这样当把对应的索引节点 的文件操作函数集赋予文件对象,以后对该文件进行操作时,比如读操作,VFS虽然对各种不同文件都是执行同一个read()操作界面,但是真正读时,内核 却知道怎么区分对待不同的文件类型。

清单9. __dentry_open

  1. static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt, 
  2.  int flags, struct file *f, 
  3.  int (*open)(struct inode *, struct file *)) 
  4.  { 
  5.  struct inode *inode; 
  6.  …… 
  7.  //整个函数的工作在于填充一个file对象 
  8.  …… 
  9.  f->f_mapping = inode->i_mapping;  
  10.  f->f_dentry = dentry; 
  11.  f->f_vfsmnt = mnt; 
  12.  f->f_pos = 0;  
  13.  //将对应的索引节点的文件操作函数集赋予文件对象的操作列表 
  14.  <span class="boldcode">f->f_op = fops_get(inode->i_fop); </span> 
  15.  ……  
  16.  //若文件自己定义了open操作,则执行这个特定的open操作。 
  17.  if (!open && f->f_op) 
  18.  open = f->f_op->open;  
  19.  if (open) { 
  20.  error = open(inode, f); 
  21.  if (error) 
  22.  goto cleanup_all; 
  23.  …… 
  24.  return f; 

3.2 sys_read()

sys_read()系统调用用于从已打开的文件读取数据。如read成功,则返回读到的字节数。如已到达文件的尾端,则返回0。图9是sys_read()实现代码中的函数调用关系图。

(编辑:晋中站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

推荐文章
    热点阅读