Android Fuse文件系统开篇

1,138 阅读2分钟

注: 此系列文章基于Android11,写于2021年,原本发布于公司wiki. Android12之后多了passthrough

Fuse 系列内容简介:

  • 核心原理概述
  • mount篇
  • App进程创建篇 --- bindmount
  • FuseDeamon启动---loop
  • 以 open 为例子概述内核fuse流程
  • passthrough 方案

内容涉及知识点:

  • vold 服务进程 VoldNativeService.cpp

  • mount 服务进程 StorageManagerService.java

  • mount挂载

    • bind mount挂载
    • 命名空间mount挂载
  • Linux内核空间-用户空间

  • 系统调用与中断

  • Linux文件系统 以及 文件与进程之间的权限关系

  • Zygote进程---App进程创建流程 bind mount挂载

  • 繁琐,复杂,冗余,杂乱,恶心,非人类,反人性的 sdcard 目录

^

讲解目标

理解这些目录为什么都是相同内容:

底层目录:/data/media/0

上层目录:storage/emulated/0

挂载目录:/mnt/user/0/emulated/0

/mnt/pass_through/0/emulated/0

/mnt/installer/0/emulated/0

链接: /sdcard

Android Fuse 的难点就是 各个目录之间的挂载关系很复杂:

理解这些目录为什么都是相同内容:

底层目录:/data/media/ 真实文件所在目录

挂载目录:

/mnt/user/0/ vold服务代码中把目录 /mnt/user/0/emulated 挂载为 fuse 文件系统 /mnt/pass_through/0/ vold服务代码中通过bindmount 指向 /data/media/

上层目录:

/storage/ init.rc 文件中,通过bindmount 指向 /mnt/user/0

因此对于普通进程而言,访问 /storage 目录就是访问 /mnt/user/0/ 目录。

/mnt/user/0/ 目录为Fuse文件系统,因此其访问请求被Fuse系统内核转发到用户空间FuseDaemon所在的 MediaProvider 进程处理。

命名空间moun目录:

对于 MediaProvider 进程: 在进程创建过程中把 /storage 通过命名空间bindmount 指向 /mnt/pass_through/0 目录。

又因为/mnt/pass_through/0 指向 /data/media/ ,

因此,MediaProvider 接收到内核转发的文件请求,再去访问文件时,是访问的文件真实所在的目录 /data/media/

链接: /sdcard 链接到 /storage/self/primary,/storage/self/primary 又链接到 /storage/emulated/0