Chinaunix首页 | 论坛 | 博客
  • 博客访问: 371899
  • 博文数量: 47
  • 博客积分: 967
  • 博客等级: 准尉
  • 技术积分: 1290
  • 用 户 组: 普通用户
  • 注册时间: 2012-05-25 16:14
文章分类

全部博文(47)

文章存档

2019年(1)

2014年(1)

2013年(9)

2012年(36)

分类: LINUX

2012-08-31 08:26:48

目录项对象:
    每个文件除了有一个索引节点inode数据结构外,还有一个目录项dentry数据结构。dentry结构中有个d_inode指针指向相应的inode结构。大家有没有想过。既然inode结构和dentry结构都是对文件各方面属性的描述,为什么不直接把两个结构合二为一呢?这是因为目录项结构描述的是文件逻辑上的属性,在磁盘上并没有对应的映像,因此在dentry结构中不包含指出该对象已被修改的字段。目录项对象存放在名为dentry_cache的slab分配器高速缓存中;而indode结构代表的是物理意义上的文件,记录的是物理上的属性,对于一个具体的文件系统,如Ext2,Ext2_inode结构在磁盘上就有对应的映像。所以说,一个索引节点对象可能对应多个目录项对象。而一个目录项对象只能对应一个索引节点。也就是说,一个文件可以有不止一个文件名或路径名。这是因为一个应经建立的文件可以被Link到其他文件名。所以在inode结构中有一个队列i_dentry,凡是代表着同一个文件的所有目录项都通过其dentry结构中的d_alias域挂入相应inode结构中的i_dentry队列。
   一旦目录项被读入内存,VFS就把他转换成基于dentry结构的一个目录项对象,对于进程查找路径名中的每个分量,内核都为其创建一个目录项对象;目录项对象将每个分量与其对应的索引结点相联系。例如:在查找路径名/proc/syskall时,内核为根目录“/”创建一个目录项对象,为根目录下的proc项创建一个第二级目录对象,为/proc目录下的test项创建一个第三级目录项对象。

include/linux/dcac

  1. struct dentry {
  2.     unsigned int d_flags;        目录项高速缓存标志
  3.     struct dentry *d_parent;    父目录的目录项对象
  4.     struct qstr d_name; 文件名
  5.     struct inode *d_inode;        与文件名关联的索引结点
  6.     unsigned char d_iname[DNAME_INLINE_LEN];    短文件名
  7.     spinlock_t d_lock;        保护目录项的自旋锁
  8.     const struct dentry_operations *d_op; 操作目录项的函数
  9.     struct super_block *d_sb;    目录项树的根(即文件的超级块)
  10.     struct list_head d_lru;        未使用的LRU链表
  11.     struct list_head d_subdirs;    该目录项的子目录所形成的链表
  12.     struct list_head d_alias;    索引结点别名的链表。
  13. .....
  14. };
一个文件系统中所有目录项结构一般会组织为一个哈希表,或者组织为一棵树,或者按照某种需要组织为一个链表,这是为文件访问和文件路径搜索奠定下良好的基础。对目录项操作的一组函数叫目录项操作表。
d_revalidata:判断目录项是否生效。
d_hash():生成一个哈希值。
d_compare():比较两个文件名。
d_delete():删除d_count域为0的目录项对象。
d_release():释放一个目录项对象。
d_input():调用该方法丢弃目录项对应的索引结点。

文件对象
   
    文件对象是已打开文件在内存中的表示,因此,它在磁盘上并没有与之对应的数据。也就是说,文件对象只存在于内存中,所以这个结构也就不涉及脏数据字段和是否需要写回磁盘。
   文件最终是要被进程访问的,一个进程可以打开多个文件,而一个文件可以被多个进程同时访问。每个打开的文件都用一个32位的数字来表示下一个读写的字节位置,这个数字叫做文间位置或偏移量。可以通过执行系统调用lseek对文件位置进行修改。Linux在file文件对象中保存了打来文件的文件位置,这个对象称为打开的文件描述符。
   大家可能会产生疑惑,为什么不把文件位置存放在inode中呢?原因是Linux文件是共享的,加入把文件位置放在索引结点中,则如果有两个或更多的进程同时打开同一个文件,他们将去访问同一个索引结点,于是一个进程的lseek操作将影响到另一个进程的读操作,这显然是不可想象的。

inlcude/linux/fs.h

  1. struct file {
  2.         struct list_head f_list; 所有打开的文件形成的链表
  3.         struct dentry *f_dentry; 与文件相关的目录项对象
  4.         struct vfsmount *f_vfsmnt; 该文件所在的已安装的文件系统
  5.         struct file_operations *f_op; 指向文件操作表的指针
  6.         unsigned int         f_flags; 打开文件时所指定的标志
  7.         fmode_t            f_mode; 文件的打开模式
  8.         loff_t            f_pos; 文件的当前位置
  9.         ......
  10. };
对文件操作的一组函数叫文件操作表。由file_operations结构描述:
llseek();修改文件指针
read():从文件中读出若干字节。
write():给文件中写若干字节。
mmap():文件到内存的映射。
open():打开文件。
flush():关闭文件时减少f_count的计数。
fsync():文件在缓冲区的数据写回磁盘。
fs_struct结构描述进程与文件系统的关系,该函数在include/linux/fs_struct.h中定义。


  1. struct fs_struct {
  2.   int users;    
  3.   spinlock_t lock;    
  4.   seqcount_t seq;
  5.   int umask;
  6.   int in_exec;
  7.   struct path root, pwd;    root为根目录,pwd指向进程当前所在的目录。
  8.  };

阅读(1823) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~