fd补充:file和inode的实现

struct file

在这里插入图片描述

struct file {
    // ...
    struct path                     f_path;
    struct inode                    *f_inode;
    const struct file_operations    *f_op;

    atomic_long_t                    f_count;
    unsigned int                     f_flags;
    fmode_t                          f_mode;
    struct mutex                     f_pos_lock;
    loff_t                           f_pos;
    struct fown_struct               f_owner;
    // ...

}

它标识一个进程打开的文件,数组内指针所指向的,下面解释相关的几个最重要的字段:
f_path :标识文件名

f_inode :inode 这个是vfs的inode类型,是基于具体文件系统之上的抽象封装;
f_op:驱动结构体。

f_pos :就是当前文件偏移。f_pos 在 open 的时候会设置成默认值,seek 的时候可以更改,从而影响到 write/read 的位置。


ionde

struct file 结构体里面有一个指向 inode 的指针。这个指向inode指针并没有直接指向具体文件,而是操作系统抽象出来的一层虚拟文件系统,叫做 VFS ( Virtual File System ),然后在 VFS 之下才是真正的文件系统,比如 ext4 之类的。
在这里插入图片描述
为了避免struct file 处理逻辑的复杂,因为每对接一个具体的文件系统,就要考虑一种实现。所以操作系统必须把底下文件系统屏蔽掉,对外提供统一的 inode概念,对下定义好接口进行回调注册。这样让 inode 的概念得以统一,Unix 一切皆文件的基础就来源于此。

struct inode {
	umode_t			i_mode;
	unsigned short		i_opflags;
	kuid_t			i_uid;
	kgid_t			i_gid;
	unsigned int		i_flags;
	...
	dev_t			i_rdev;
	loff_t			i_size;
}

1、dev_t  i_rdev包含有主次设备号信息
2、它是当文件存在时就存在了对应的inode,inode里面会保存着设备号等信息;这是因为inode是文件的伴生
也就是有文件就有文件对应的inode;当然这个inode是封装好的对上接口。

==通用的open流程:files_struct(进程级) ---- file(系统级资源) ---- inode(文件系统提前存在) ----- xxx.inode ==
把驱动相关的加进来:files_struct ---- file ---- inode(VFS以上) ----- xxx.inode(VFS以下) ---- 驱动层chrdev[]数组 ----- 驱动文件

每一类文件都有自己的驱动,所以每一个inode都会有i_rdev;实际上是先创建的xxx.inode再做地址偏移得到inode。

3、由于是伴生,所以包含**dev_t  i_rdev,设备节点信息**


lsof + 文件名
文件被那些进程打开了

/proc/pid/fd/
进程打开了那些文件 

VFS的ionde和特异化“ionde”接口

**VFS层对上层提供统一的inode(vfs_inode)接口,与下层对接的是特异化inode接口,如何通过 vfs提供的inode得到具体文件的inode?

强制地址转换

struct ext4_inode_info {
    // ext4 inode 特色字段
    // ...
    
    // 重要!!!
    struct inode    vfs_inode;  
};

每一个特异的具体的inode结构体中,本身就包含有 vfs_inode,直接通过 vfs inode 结构体的地址强转类型就能得到 ext4_inode_info 结构体。需要考虑的仅是两个结构体之间的地址偏移

例如:
vfs_inode 的地址为 0xa89be0
ext4_inode_info 里有个内嵌字段 vfs_inode,类型为 struct inode ,该字段在结构体内偏移为 64 字节;
ext4_inode_info 的地址为 (struct ext4_inode_info *)(0xa89be0 - 64)

分配 inode 的时候,其实分配的是 ext4_inode_info 结构体,包含了 vfs inode,然后对外给出去 vfs_inode 字段的地址即可。VFS 层拿 inode 的地址使用,底下文件系统强转类型后,取外层的 inode 地址使用。

inode 的内存由后端文件系统分配,vfs_inode 结构体内嵌在不同的文件系统的 inode 之中。不同的层(vfs层和具体文件层)用不同的地址,ext4 文件系统用 ext4_inode_info 的结构体的地址,vfs 层用 ext4_inode_info.vfs_inode 字段的地址


每一个具体的xxxxx_inode都有处于vfs层的成员对象vfs_inode,这是将具体文件统一成vfs_inode放置于vfs层供上层使用的(这就是vfs层的由来)。具体的xxxxx_inode和它所提供的vfs_inode存在一个偏移,通过所提供的vfs_inode并补偿偏移来访问具体的xxxxx_inode。这里每个vfs_inode只能对应一个xxxxx_inode,但多个vfs_inode指向同一个xxxxx_inode。这是因为先创建的xxxxx_inode,再创建的vfs_inode。

思考问题:怎么理解 fs inode 和 ext2_inode_info,ext4_inode_info 等结构体的区别?
所有文件系统共性的东西抽象到 vfs inode ,不同文件系统差异的东西放在各自的 inode 结构体中。


总结一下驱动下的file和inode

1、inode是伴生的,当设备节点(文件)创建了就创建了inode,所以inode存储静态信息,主要是主设备号;
2、file是当你打开文件后创建的(所以是动态的),用于维护打开的文件,所以file自然会包含inode;驱动结构体,而驱动结构体的初始化还是依赖inode中的主设备号;
open相同主设备号却不同次设备号的节点(文件),会有不同的fd,所以有不同的inode;但由于相同的设备号会有相同的file_operation;
3、inode(xxx.ionde)是文件系统中的,不管你打不打开它始终都存在;而open只是将这些文件系统囊括进file中进行维护。

在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值