& inode-> i_data和inode-> i_mapping之间的区别是什么?

时间:2015-08-17 09:39:54

标签: linux-kernel

我发现在大多数情况下,i_data只是i_mapping的解引用数据,如下所示,为什么在一个inode结构中设置两个相同的值?

crash> struct inode ffffffc073c1f360 -o
struct inode {
 ...
  [ffffffc073c1f4a8] struct file_lock *i_flock;
  **[ffffffc073c1f4b0] struct address_space i_data;**
  [ffffffc073c1f558] struct list_head i_devices;
 ...   

crash> struct inode ffffffc073c1f360
struct inode {
...
  i_op = 0xffffffc0007ad1c0 <ext4_file_inode_operations>, 
  i_sb = 0xffffffc002010000, 
  **i_mapping = 0xffffffc073c1f4b0,** 
  i_security = 0xffffffc07230d050, 
...

2 个答案:

答案 0 :(得分:4)

地址空间始终处理页面缓存。如果页面所有者是文件,则在页面缓存中访问页面时,address_space对象嵌入在VFS inode对象的i_data字段中。 inode的i_mapping字段始终指向包含inode数据的页面所有者的address_space对象。 address_space对象的host字段指向嵌入描述符的inode对象。

E.g。如果页面属于存储在ext4文件系统中的常规文件,则VFS inode的i_data指向该文件的inode,inode的i_mapping字段指向同一inode的i_data,address_space对象的host字段指向相同的inode。

然而事情总是那么简单。假设一个页面包含从块设备文件中读取的数据,该文件包含&#34; raw&#34;在块设备的数据中,address_space嵌入在&#34; master&#34; bdev中文件的inode,与块设备关联的特殊文件系统(由bd_inode引用)。因此,块设备文件的inode的i_mapping字段指向 嵌入在主索引节点中的address_space对象;相应地,address_space对象的主机字段指向主索引节点。以这种方式,包含从块设备读取的数据的所有页面具有相同的address_space对象,即使它们已经通过引用不同的块设备文件来访问。 因此,当它们来到页面属于常规文件或阻止设备专用文件时,它们之间存在细微的区别。

答案 1 :(得分:0)

来自http://lkml.iu.edu/hypermail/linux/kernel/0105.2/1363.html

  

i_data是“此​​inode读取/写入的页面”

     

i_mapping是“我应该问谁?”

     

IOW,单个文件系统之外的所有文件都应使用后者。   当(且仅当)inode拥有数据时,它们相同。 CODA(或其他任何   在本地fs上缓存数据)将使i_mapping指向   它缓存到的inode。如果/当设备进入页面缓存时也是如此-   我们应该将pagecache与struct block_device关联,因为我们可以   具有相同的major:minor的许多inode。 IOW,-> i_mapping应该指向   所有人都放在同一个地方。

来自https://marc.info/?l=linux-fsdevel&m=99470104708354&w=2

  

它由环绕现有文件系统的文件系统使用。 AFAIK Coda现为   树中唯一实际使用此功能的人。

     

所有VFS函数始终使用inode-> i_mapping-> a_ops。 Coda复制了   将基础索引节点的i_mapping映射到它自己的索引节点。这样我们使用   与容器文件具有相同的地址空间,并避免映射相同的文件   内存中不同位置的页面。

i_mapping是真实的页面缓存。 i_data是address_space所在的位置,并由inode分配和释放,通常是i_mapping指向的位置。但是文件系统可以将一个i节点的i_data保留为空,并将i_mapping指向另一个i节点的i_data,以避免多个页面缓存。