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