传统的Unix既有v节点(vnode)也有i节点(inode),vnode的数据结构中包含了inode信息。但在Linux中没有使用vnode,而使用了通用inode。“实现虽不同,但在概念上是一样的。”

vnode (“virtual node”)仅在文件打开的时候,才出现的;而inode定位文件在磁盘的位置,它的信息本身是存储在磁盘等上的,当打开文件的时候从磁盘上读入内存。

fs

inode信息就存储在磁盘的某个分区上。下图是上图的一个扩展:inode指示了文件在数据块中的物理位置。所以仅仅存在inode无法描述一个完整的文件系统,比如:目录与目录的树状结构,这一点在inode上无法体现。

延伸:

  • 如果多个inode指向同一个数据块的时候,是不是就可以实现熟悉的链接了?!这就是软连接的原理,新建一个文件(一个符号链接文件,文件的属性中有明确说明它是一个符号链接文件),为需要链接的文件分配一个新的inode,然后指向同一个文件。
  • 多个文件共用一个inode,同样可以实现链接?!这就是硬链接的原理,inode中有链接计数器,当增加一个文件指向这个inode时,计数器增1。特别的,当计数器为0时候,文件才真正从磁盘删除。即ls -l 命令中的第二栏

较详细的柱面组的i节点和数据块

ext3_inode上的数据结构如下:它记录了很多关于文件的信息,比如文件长度,文件所在的设备,文件的物理位置,创建、修改和更新时间等等,特别的,它不包含文件名!目录下的所有文件名和目录名都存储在目录的数据块中,即如上的目录块。

01 struct ext3_inode {
02     __le16 i_mode; File mode
03     __le16 i_uid; Low 16 bits of Owner Uid
04     __le32 i_size; Size in bytes
05     __le32 i_atime; Access time
06     __le32 i_ctime; Creation time
07     __le32 i_mtime; Modification time
08  
09     __le32 i_dtime; Deletion Time
10     __le16 i_gid; Low 16 bits of Group Id
11     __le16 i_links_count; Links count
12     ......
13     __le32 i_block[EXT2_N_BLOCKS]; Pointers to blocks
14     ......
15 };

引入vnode:早期版本的Unix是这样做的,但是Linux并没有。vnode一般包含了文件类型和对此文件进行各种操作的函数的指针。打开文件的内核数据结构

 

Linux上有dentry,中文的意思就是目录项,它粘合了内存中文件和磁盘中文件,同时它保存是经常访问的目录信息。

http://unix.stackexchange.com/questions/4402/what-is-a-superblock-inode-dentry-and-a-file

A dentry is the glue that holds inodes and files together by relating inode numbers to file names. Dentries also play a role in directory caching which, ideally, keeps the most frequently used files on-hand for faster access. File system traversal is another aspect of the dentry as it maintains a relationship between directories and their files.下面是一副很有趣的图片:

Interaction between processes and VFS objects

The common file model consists of the following object types:

<1>The superblock object
Stores information concerning a mounted filesystem. For disk-based filesystems, this object usually corresponds to a filesystem control block stored on disk.
<2>The inode object
Stores general information about a specific file. For disk-based filesystems, this object usually corresponds to a file control block stored on disk. Each inode object is associated with an inode number, which uniquely identifies the file within the filesystem.
<3>The file object
Stores information about the interaction between an open file and a process. This information exists only in kernel memory during the period when a process has the file open.
<4>The dentry object
Stores information about the linking of a directory entry (that is, a particular name of the file) with the corresponding file. Each disk-based filesystem stores this information in its own particular way on disk.
Figure 12-2 illustrates with a simple example how processes interact with files. Three different processes have opened the same file, two of them using the same hard link. In this case, each of the three processes uses its own file object, while only two dentry objects are requiredone for each hard link. Both dentry objects refer to the same inode object, which identifies the superblock object and, together with the latter, the common disk file.

inode和dentry

 

需要注意的几点如下所示:

1)进程每打开一个文件,就会有一个file结构与之对应。同一个进程可以多次打开同一个文件而得到多个不同的file结构,file结构描述被打开文件的属性,如文件的当前偏移量等信息。

2)两个不同的file结构可以对应同一个dentry结构。进程多次打开同一个文件时,对应的只有一个dentry结构。Dentry结构存储目录项和对应文件(inode)的信息。

3)在存储介质中,每个文件对应唯一的inode结点,但是每个文件又可以有多个文件名。即可以通过不同的文件名访问同一个文件。这里多个文件名对应一个文件的关系在数据结构中表示就是dentry和inode的关系。

4)Inode中不存储文件的名字,它只存储节点号;而dentry则保存有名字和与其对应的节点号,所以就可以通过不同的dentry访问同一个inode。

5)不同的dentry则是同个文件链接(ln命令)来实现的。

01 struct dentry {
02     atomic_t d_count; 目录项对象使用计数器
03     unsigned int d_flags; 目录项标志
04     struct inode * d_inode; 与文件名关联的索引节点
05     struct dentry * d_parent; 父目录的目录项对象
06     struct list_head d_hash; 散列表表项的指针
07     struct list_head d_lru; 未使用链表的指针
08     struct list_head d_child; 父目录中目录项对象的链表的指针
09     struct list_head d_subdirs;对目录而言,表示子目录目录项对象的链表
10     struct list_head d_alias; 相关索引节点(别名)的链表
11     int d_mounted; 对于安装点而言,表示被安装文件系统根项
12     struct qstr d_name; 文件名
13     unsigned long d_time; // used by d_revalidate
14     struct dentry_operations *d_op; 目录项方法
15     struct super_block * d_sb; 文件的超级块对象
16     vunsigned long d_vfs_flags;
17     void * d_fsdata;与文件系统相关的数据
18     unsigned char d_iname [DNAME_INLINE_LEN]; 存放短文件名
19 };

诸如文件名,父目录等。dentry可以描述目录的树状结构。

http://daoluan.net/blog/inode、vnode和dentry/

Logo

更多推荐