当前位置: 首页 > 科技观察

FUSE文件系统挂载在Android内卡上

时间:2023-03-13 22:00:50 科技观察

作者|陈浩评论|孙淑娟1.简介FUSE(FilesysteminUserspace)是一个用户空间的文件系统。用户可以通过FUSE文件系统对内部卡进行操作。FUSE主要实现代码位于用户空间,无需重新编译到内核。用户空间开发者可以通过FUSE的接口直接访问内核空间,而无需了解文件系统的内幕和内核模块编程知识。带来了很多方便。二、FUSE文件系统架构1、FUSE内核模块(kernelmode)实现VFS接口(FUSE文件驱动注册、supperblock、dentry、inode维护),接收请求传递给LibFUSE,LibFUSE再传递给用户程序操作界面。2、LibFUSE模块(用户态)实现了文件系统的主要框架,如封装实现的文件系统操作,挂载管理,通过设备/dev/fuse与内核模块通信。3.内卡挂载成功后,用户程序模块(用户态)对内卡进行读写操作。这种架构的设计允许用户通过FUSE在用户空间定制自己的文件系统,将文件系统与内核分离,大大降低了开发难度。本文将重点介绍libfuse是如何挂载内部卡的。3.内卡挂载3.1内卡挂载与分区挂载不同。分区挂载是挂载到内核的真实文件系统,比如userdata分区挂载f2fs到/data目录。内卡挂载是挂载用户空间文件系统,比如dev/fusemountfuse到mnt/user/0/emulated目录下。mnt/user/0/emulated和上图中的/data/media/0下的内容是一样的。原因是这两个目录是绑定关系,说明内卡是userdata的一部分。这部分空间可以由用户直接操作。在手机文件管理器中也可以看到同目录:3.2内卡挂载绑定VoldNativeService::mount收到framwork层发送的挂载请求后调用vol->mount,从而执行父级VolumeBase::mount种类。真正的实现是子类中的card会调用EmulatedVolume::doMount进行挂载。1、VoldNativeService::mountmountFlags决定是挂载内卡还是SD卡,为3时挂载内卡,为2时挂载SD卡。内卡的mountUserId为0,SD卡的mountUserId为卡本身的guid。最终vol->mount()将被执行。binder::StatusVoldNativeService::mount(conststd::string&volId,int32_tmountFlags,int32_tmountUserId,constandroid::sp&callback){ENFORCE_SYSTEM_OR_ROOT;CHECK_ARGUMENT_ID(volId);CKACQUIRE_vol=VolumeManager::Instance()->findVolume(volId);if(vol==nullptr){returnerror("找不到卷"+volId);}vol->setMountFlags(mountFlags);vol->setMountUserId(mountUserId);vol->setMountCallback(回调);intres=vol->mount();vol->setMountCallback(nullptr);如果(res!=OK){返回翻译(res);}返回翻译(确定);}2.vol->mountvol是VolumeBase的一个实例,VolumeBase的mount方法是由具体的子类EmulatedVolume、PublicVolume、PrivateVolume等实现的,执行后会向MountService发送响应消息。将挂载结果上报给framwork层。status_tVolumeBase::mount(){if((mState!=State::kUnmounted)&&(mState!=State::kUnmountable)){LOG(WARNING)<