f2fs学习笔记 - 7. f2fs文件打开

1. 前言

本文主要总结f2fs文件的打开过程,以touch test为例

2.打开文件总体流程

在打开文件时,获取了file描述符,创建了file, 而file->op_s来源于file所对应的inode->i_fop
而inode是如何被创建的呢?

[<7f003770>] (f2fs_create+0x24/0x1fc [f2fs]) from [<800c1724>] (vfs_create+0x80/0xb4)
[<800c1724>] (vfs_create+0x80/0xb4) from [<800c462c>] (do_last.isra.45+0x794/0xb98)
[<800c462c>] (do_last.isra.45+0x794/0xb98) from [<800c4ad8>] (path_openat+0xa8/0x47c)
[<800c4ad8>] (path_openat+0xa8/0x47c) from [<800c5170>] (do_filp_open+0x2c/0x80)
[<800c5170>] (do_filp_open+0x2c/0x80) from [<800b6f40>] (do_sys_open+0xe4/0x170)
[<800b6f40>] (do_sys_open+0xe4/0x170) from [<8000e140>] (ret_fast_syscall+0x0/0x30)

打开文件的过程中,会调用vfs_create,vfs_create会调用具体文件系统的create回调,对于f2fs文件系统就是通过f2fs_create来创建了inode, 并对inode进行初始化,其中:
inode->i_fop = &f2fs_file_operations; f2fs_file_operations定义在f2fs/file.c中

之后将通过如下的调用来将inode->i_fop赋值给file->f_op,如果file->f_op->open不为空,则将得到执行

do_last
    finish_open
        do_dentry_open

3. f2fs_create

通过f2fs_create创建了inode,同时初始化如下的操作函数集:

138         inode->i_op = &f2fs_file_inode_operations;                                                                                                                               
139         inode->i_fop = &f2fs_file_operations;                                                                                                                                    
140         inode->i_mapping->a_ops = &f2fs_dblock_aops;

f2fs_file_operations将用来初始化file->f_op
f2fs_dblock_aops主要用于与page cache的交互相关

3. mknod

字符设备文件的创建

mknod系统调用->
    vfs_mknod->
        dir->i_op->mknod(dir, dentry, mode, dev)->
            f2fs_mknod (struct inode * dir, struct dentry *dentry,int mode, dev_t rdev)->
                 f2fs_new_inode
                 init_special_inode

字符设备文件与块设备文件创建的流程基本是一致的,都是通过mknod系统调用。以f2fs为例它通过调用f2fs_mknod。首先通过f2fs_new_inode来创建inode

  1. f2fs_new_inode:创建新的inode

  2. init_special_inode
    为新创建的inode进行初始化,其中针对字符设备会指定inode->i_fop为def_chr_fops,它会在文件打开的时候赋值给新创建的file->f_ops,并调用其中的chrdev_open

4. 字符设备文件的打开

参考打开文件的流程,对于字符设备file->fops为def_chr_fops,它的open函数为chrdev_open
因此将按如下路程执行:

do_last
    finish_open
       do_dentry_open
          chrdev_open

5. 块设备文件的创建

mknod系统调用->
    vfs_mknod->
        dir->i_op->mknod(dir, dentry, mode, dev)->
             f2fs_mknod (struct inode * dir, struct dentry *dentry,int mode, dev_t rdev)->
                 f2fs_new_inode
                 init_special_inode

块设备文件创建与字符设备文件创建的流程基本是一致的,都是通过mknod系统调用。以f2fs为例它通过调用f2fs_mknod。首先通过f2fs_new_inode来创建次inode,这其中也包含了f2fs自己的inode,之后对次inode执行初始化,其中初始化次inode->f_ops为def_blk_fops

  1. f2fs_new_inode:创建新的inode,这个就是次inode,次inode的内容就是设备号,并没有占用额外的磁盘空间,将来次inode就是通过设备号建立了与block_inode的关联;

  2. init_special_inode:为新创建的次inode进行初始化,其中针对块设备会指定inode->i_fop为def_blk_fops

5. 块设备文件的打开

参考打开文件的流程,对于块设备file->fops为def_blk_fops,它的open函数为blkdev_open,它的执行流程为:

do_last
    finish_open
       do_dentry_open
           blkdev_open->
             bd_acquire(inode)//次inode
                 bdget
             blkdev_get(bdev, filp->f_mode, filp)
  1. blkdev_open
    在文件打开的时候将次inode->i_fop赋值给新创建的file->f_ops,并调用其中的blkdev_open,blkdev_open来源于创建块设备文件时,它被初始化为次inode的i_fop即def_blk_fops,blkdev_open调用bd_acquire

  2. bd_acquire
    获取主inode的block_device, 会通过bdget首先来查找是否已经创建了与传入设备号相同的inode,如果已经创建则直接返回,否则调用blockdev_superblock的ops来创建bdev文件系统下的块设备文件的bdev_inode,它包含了主inode和block_device,并建立起了与次inode的关系,注意到address_space是内嵌在inode中,因此address_space也准备好了。
    bdget也会对新创建的主inode进行初始化,其中会初始化inode内嵌的address_space->a_ops为def_blk_aops,它会在读写块设备文件时被调用

  3. blkdev_get
    建立起block_device与底层块设备的关系,这样就可以通过通过读写块设备文件来达到操作块设备的目的。上一步bdget获取了block_device,通过block_device可以获取到gendisk,进一步获取各个分区hd_struct,从而可以实现对磁盘的操作

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值