&inode->i_data 和 inode->i_mapping 有什么区别

问题描述 投票:0回答:2

我发现在大多数情况下,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, 
...
linux-kernel
2个回答
6
投票

地址空间总是处理页面缓存。当访问页面缓存中的页面时,如果该页面的所有者是文件,则

address_space
对象将嵌入到 VFS inode 对象的
i_data
字段中。 inode 的 i_mapping 字段始终指向包含 inode 数据的页面所有者的
address_space
对象。
address_space
对象的host字段指向嵌入描述符的inode对象。

例如如果页面属于存储在 ext4 文件系统中的常规文件,则 VFS inode 的

i_data
指向该文件的 inode,inode 的 i_mapping 字段指向同一 inode 的
i_data
,以及
address_space
对象的 host 字段指向同一个 inode。

然而事情并不总是那么简单。假设一个页面包含从块设备文件读取的数据,该文件包含块设备的“原始”数据,

address_space
嵌入在bdev中文件的“主”inode中,bdev是与块设备关联的特殊文件系统(参考通过 bd_inode)。因此块设备文件的inode的i_mapping字段指向
address_space
对象嵌入在主inode中;相应地,
address_space
对象的host字段指向主inode。这样,包含从块设备读取的数据的所有页面都具有相同的
address_space
对象,即使它们是通过引用不同的块设备文件来访问的。 因此,当页面属于常规文件或属于块设备特殊文件时,两者之间存在细微差别。


0
投票

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

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

i_mapping 是“我应该向谁索要页面?”

IOW,单个文件系统之外的所有内容都应该使用后者。 当(且仅当)inode 拥有数据时它们是相同的。 CODA(或任何 将数据缓存在本地文件系统上)将使 i_mapping 指向以下的 i_data 它缓存到的索引节点。对于块设备,如果/当它们进入页面缓存时也是如此 - 我们应该将 pagecache 与 struct block_device 关联起来,因为我们可以有 许多 inode 具有相同的主要:次要。 IOW,->i_mapping 应该指向 所有人都去同一个地方。

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

它由环绕现有文件系统的文件系统使用。据我所知尾声是 树中唯一真正使用它的。

所有 VFS 函数始终使用 inode->i_mapping->a_ops。科达复制了 底层 inode 到它自己的 inode 的 i_mapping。这样我们就可以使用 与容器文件相同的地址空间并避免映射相同的文件 内存中不同位置的页面。

i_mapping 是真正的页面缓存。 i_data 是address_space 所在的位置,并与inode 一起分配和释放,并且通常是i_mapping 指向的位置。但是文件系统可以将一个 inode 的 i_data 留空,并将 i_mapping 指向另一个 inode 的 i_data,以避免多个页面缓存。

© www.soinside.com 2019 - 2024. All rights reserved.