SDcardFS文件系统浅析(五)- sdcardfs在文件系统调用中

本文深入探讨了SDcardFS在文件系统调用中的角色,通过ftrace日志揭示了open()、read()和close()操作的流程。文章适合有一定文件系统基础的读者,与之前的Linux内核open()实现分析相辅相成。
摘要由CSDN通过智能技术生成

SDcardFS文件系统浅析(五)- sdcardfs在文件系统调用中

上一节从ftrace中可以看到在cat过程中sdcardfs调用顺序,我们知道了sdcardfs的调用流程,但是这些函数在整个文件系统的调用中是怎么配合的,怎么被串起来的?下面补齐缺失的trace,来看下其在整个文件系统调用中的位置。食用下面ftrace log需要有一定的文件系统基础,可以配合这个博客:open()在Linux内核的实现-准备工作这各博客里对linux中的open()中实现的流程以及其中各函数作用都做了注解。

  1. open()
 SyS_openat() {
  //系统调用
 4)               |    do_sys_open() {
 4)               |      getname() {
  //1. 将文件名由用户态拷贝到内核态
 4)               |        getname_flags() {
 4)               |          kmem_cache_alloc() {
 4)   2.604 us    |          }
 4)               |          __check_object_size() {
 4)   0.052 us    |            is_vmalloc_addr();
 4)               |            pfn_valid() {
 4)               |              memblock_is_map_memory() {
 4)   0.105 us    |                memblock_search();
 4)   0.677 us    |              }
 4)   1.250 us    |            }
 4)   0.104 us    |            __check_heap_object();
 4)   0.104 us    |            check_stack_object();
 4)   3.594 us    |          }
 4)   7.760 us    |        }
 4)   8.333 us    |      }
 4)               |      get_unused_fd_flags() {
  //2. 为即将打开的文件分配文件描述符
 4)               |        __alloc_fd() {
 4)               |          _etext() {
 4)   0.156 us    |            preempt_count_add();
 4)   1.458 us    |          }
 4)   0.104 us    |          expand_files();
 4)               |          _etext() {
 4)   0.157 us    |            preempt_count_sub();
 4)   0.729 us    |          }
 4)   4.218 us    |        }
 4)   4.740 us    |      }
 4)               |      do_filp_open() {
  /*3. 根据用户传入的路径去执行open,如果找到则为文件创建
                                       file结构体.open的核心操作函数,其解析文件路径创建
                                       file结构体*/
 4)               |        path_openat() {
  //3.1 路径查找
 4)               |          get_empty_filp() {
  //3.1.1 创建新的file结构体
 4)               |            kmem_cache_alloc() {
 4)   2.865 us    |            }
 4)               |            security_file_alloc() {
 4)               |              selinux_file_alloc_security() {
 4)               |                kmem_cache_alloc() {
 4)   2.760 us    |                }
 4)   3.334 us    |              }
 4)   3.906 us    |            }
 4)   0.052 us    |            __mutex_init();
 4) + 10.885 us   |          }
 4)               |          path_init() {
  /*3.1.2 路径查找前准备工作,主要判断遍历路径的起始位置
                                       根目录‘/’ or 当前路径 or 指定路径
                                       根据起始位置配置nameidata *nd中的一些参数*/
 4)   0.052 us    |            __rcu_read_lock();
 4)   1.719 us    |          }
 4)               |          link_path_walk() {
  /*3.1.3 逐一解析文件路径,将解析结果存入
                                            struct nameidata *nd */
 4)               |            inode_permission2() { //这个函数是被may_lookup()调用,作用权限检查
 4)               |              __inode_permission2() {
 4)               |                sdcardfs_permission() { //可以看到最终调用到sdcardfs的权限检查
 4)   0.105 us    |                  generic_permission();
 4)   2.188 us    |                }
 4)               |                security_inode_permission() {
  /*安全操作,最后决定是否有权限,
                                       调用内核自己注册的security_ops结构体的函数,新的内核特性属于                                        linux 安全模块(LSM)*/  
 4)               |                  selinux_inode_permission() {
 4)   0.052 us    |                    __rcu_read_lock();
 4)               |                    avc_lookup() {
 4)   1.823 us    |                    }
 4)   0.104 us    |                    __rcu_read_unlock();
 4)   3.750 us    |                  }
 4)   4.375 us    |                }
 4)   8.281 us    |              }
 4)   8.959 us    |            }
 4)   0.678 us    |            sdcardfs_hash_ci(); //根据dentry拿到 hash_len name

     ------------------------------------------------------------------------------------
      /* parent->d_op->d_hash(parent, &this);通过这种方式被调用,把hash_len 和 name写入this中*/
                struct qstr this = { { .hash_len = hash_len }, .name = name };
                err = parent->d_op->d_hash(parent, &this);
                if (err < 0)
                    return err;
                hash_len = this.hash_len;
                name = this.name;
     ------------------------------------------------------------------------------------

 4) + 11.510 us   |          }
 4)               |          lookup_fast() {
  /*这个是被walk_component()调用,作用处理当前目录项
                                           更新nd next(path类型,指向下一个目录项)*/
 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值