成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Android內(nèi)卡掛載之FUSE文件系統(tǒng)

原創(chuàng)
開發(fā) 前端
FUSE(Filesystem in Userspace),是一種用戶空間文件系統(tǒng)。用戶可以通過FUSE文件系統(tǒng)操作內(nèi)卡。FUSE主要實現(xiàn)代碼位于用戶空間中,而不需要重新編譯到內(nèi)核,用戶空間開發(fā)者可以通過FUSE的接口直接訪問內(nèi)核空間,不需要了解文件系統(tǒng)的內(nèi)幕和內(nèi)核模塊編程的知識,這給用戶空間開發(fā)者帶來了眾多便利。

作者 | 陳豪

審校 | 孫淑娟

一、簡介

FUSE(Filesystem in Userspace),是一種用戶空間文件系統(tǒng)。用戶可以通過FUSE文件系統(tǒng)操作內(nèi)卡。FUSE主要實現(xiàn)代碼位于用戶空間中,而不需要重新編譯到內(nèi)核,用戶空間開發(fā)者可以通過FUSE的接口直接訪問內(nèi)核空間,不需要了解文件系統(tǒng)的內(nèi)幕和內(nèi)核模塊編程的知識,這給用戶空間開發(fā)者帶來了眾多便利。

二、FUSE文件系統(tǒng)架構

1.FUSE內(nèi)核模塊(內(nèi)核態(tài))實現(xiàn)VFS 接口(FUSE文件驅動注冊、supper block、dentry、inode的維護),接收請求傳遞給LibFUSE,LibFUSE 再傳遞給用戶程序的接口進行操作。

2.LibFUSE模塊(用戶態(tài))實現(xiàn)文件系統(tǒng)主要框架,比如對實現(xiàn)的文件系統(tǒng)操作進行封裝、mount管理、通過設備/dev/fuse與內(nèi)核模塊通信。

3.用戶程序模塊(用戶態(tài))當內(nèi)卡掛載成功后,對內(nèi)卡進行讀寫操作。

這種架構的設計可以讓用戶通過FUSE在用戶空間來定制自己的文件系統(tǒng),將文件系統(tǒng)從內(nèi)核剝離出來,大大縮減了開發(fā)的難度。本文將著重介紹libfuse如何掛載內(nèi)卡。

三、內(nèi)卡的掛載

3.1 內(nèi)卡掛載與分區(qū)掛載的不同

分區(qū)掛載是掛載到內(nèi)核實地文件系統(tǒng),例如userdata分區(qū)掛載f2fs到 /data目錄下。內(nèi)卡掛載是掛載用戶空間文件系統(tǒng),如dev/fuse 掛載fuse到mnt/user/0/emulated目錄下。

上圖mnt/user/0/emulated和/data/media/0下的內(nèi)容是一樣的。原因是這兩個目錄是綁定的關系,說明內(nèi)卡是userdata的一部分。這部分空間是用戶可以直接操作的。

在手機的文件管理器中也可以看到同樣的目錄:

3.2 內(nèi)卡掛載和綁定

VoldNativeService::mount接收到framwork層發(fā)送的mount請求后調用vol->mount,從而執(zhí)行VolumeBase::mount這個父類。真正的實現(xiàn)是在子類內(nèi)卡會調用EmulatedVolume::doMount執(zhí)行掛載。

1.VoldNativeService::mount

mountFlags決定掛載的是內(nèi)卡還是SD卡,為3時掛載內(nèi)卡,為2時掛載SD卡。內(nèi)卡的mountUserId為0,SD卡的mountUserId是卡本身的guid。最終會執(zhí)行vol->mount()。

binder::Status VoldNativeService::mount(
  const std::string& volId, int32_t mountFlags, int32_t mountUserId,
  const android::sp<android::os::IVoldMountCallback>& callback) {
  ENFORCE_SYSTEM_OR_ROOT;
  CHECK_ARGUMENT_ID(volId);
  ACQUIRE_LOCK;
 
  auto vol = VolumeManager::Instance()->findVolume(volId);
  if (vol == nullptr) {
  return error("Failed to find volume " + volId);
  }
 
  vol->setMountFlags(mountFlags);
  vol->setMountUserId(mountUserId);
 
  vol->setMountCallback(callback);
  int res = vol->mount();
  vol->setMountCallback(nullptr);
 
  if (res != OK) {
  return translate(res);
  }
 
  return translate(OK);
 }

2.vol->mount

vol是VolumeBase的實例,VolumeBase的mount方法由具體的子類EmulatedVolume、PublicVolume、PrivateVolume等實現(xiàn)。執(zhí)行操作之后會發(fā)送應答消息給MountService。將掛載的結果上報給framwork層。

status_t VolumeBase::mount() {
  if ((mState != State::kUnmounted) && (mState != State::kUnmountable)) {
  LOG(WARNING) << getId() << " mount requires state unmounted or unmountable";
  return -EBUSY;
  }
  setState(State::kChecking);
  status_t res = doMount();
  setState(res == OK ? State::kMounted : State::kUnmountable);
 
  if (res == OK) {
  doPostMount();
  }
  return res;
 }

3.EmulatedVolume::doMount ()

內(nèi)卡會走到EmulatedVolume這個子類進行掛載,SD卡則會走PublicVolume掛載。在EmulatedVolume函數(shù)里建立了四個/mnt/runtime路徑并設置了不同的權限,原因是控制不同權限APP訪問。然后利用掛載命名空間實現(xiàn)了掛載點的隔離,用戶在不同掛載命名空間的進程,看到的目錄層次不同。MountUserFuse是掛載FUSE的實現(xiàn),內(nèi)卡和SD卡都會走這個流程。著重看一下MountUserFuse函數(shù)的實參,如果掛載的是內(nèi)卡,user_id則為0,getInternalPath()為/data/media,label為emulated。

status_t EmulatedVolume::doMount() {
  std::string label = getLabel();
  bool isVisible = getMountFlags() & MountFlags::kVisible;
  mSdcardFsDefault = StringPrintf("/mnt/runtime/default/%s", label.c_str());
  mSdcardFsRead = StringPrintf("/mnt/runtime/read/%s", label.c_str());
  mSdcardFsWrite = StringPrintf("/mnt/runtime/write/%s", label.c_str());
  mSdcardFsFull = StringPrintf("/mnt/runtime/full/%s", label.c_str());
 
  setInternalPath(mRawPath);
  setPath(StringPrintf("/storage/%s", label.c_str()));

………………………………
res = MountUserFuse(user_id, getInternalPath(), label, &fd);

…………………………..
}

4.MountUserFuse();

如下函數(shù)中只粘貼了重要的部分。fuse_path是掛載路徑mnt/user/0/emulated。隨后調用mount函數(shù)調用內(nèi)核接口進行掛載,將/dev/fuse 掛載到/mnt/user/0/emulated。

status_t MountUserFuse(userid_t user_id, const std::string& absolute_lower_path,
  const std::string& relative_upper_path, android::base::unique_fd* fuse_fd) {

std::string fuse_path(
  StringPrintf("%s/%s", pre_fuse_path.c_str(), relative_upper_path.c_str()));

result = TEMP_FAILURE_RETRY(mount("/dev/fuse", fuse_path.c_str(), "fuse",
  MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_NOATIME | MS_LAZYTIME,
  opts.c_str()));
}

掛載成功后可以用mount命令去查看,截圖如下:

四、總結

本文介紹了內(nèi)卡對FUSE的掛載,將創(chuàng)建好的FUSE設備掛載到內(nèi)置存儲空間關聯(lián)目錄。對于內(nèi)置存儲空間的訪問變成了先訪問FUSE文件系統(tǒng),再訪問f2fs文件系統(tǒng)。對于FUSE而言,在內(nèi)核空間和用戶空間來回切換會增加性能開銷,所以對FUSE的性能優(yōu)化至關重要。

作者介紹

陳豪,51CTO社區(qū)編輯,具有6年工作經(jīng)驗的高級系統(tǒng)工程師。擅長技能有Linux內(nèi)嵌匯編語言,Python,C,C++,Java,Linux內(nèi)核分析,智能機器人軟件設計等。

參考鏈接

??https://blog.csdn.net/kongxinsun/article/details/79587305??

??https://blog.csdn.net/bob_fly1984/article/details/80720807??


責任編輯:華軒 來源: 51CTO
相關推薦

2014-02-26 11:41:33

Fuse文件系統(tǒng)

2018-06-08 15:56:52

LinuxBittorrent文件系統(tǒng)

2014-01-24 09:58:45

fuse文件系統(tǒng)

2023-09-27 23:19:04

Linuxmount

2021-05-31 07:50:59

Linux文件系統(tǒng)

2018-05-29 09:00:00

LinuxBTFS文件系統(tǒng)

2010-01-08 18:01:03

Ubuntu硬盤操作

2021-08-25 10:10:52

findmnt命令Linux

2021-03-10 08:02:58

Findmnt命令系統(tǒng)

2010-03-02 15:09:26

Linux mount

2010-01-26 13:41:50

Android文件系統(tǒng)

2009-10-28 14:29:40

linux文件系統(tǒng)

2020-07-22 14:53:06

Linux系統(tǒng)虛擬文件

2017-04-25 15:50:02

sparse傳輸處理

2018-11-05 09:45:01

Linux文件系統(tǒng)命令

2011-01-13 14:10:30

Linux文件系統(tǒng)

2020-01-03 08:33:57

Ceph硬件系統(tǒng)

2010-01-26 15:08:11

Android根文件系

2023-04-12 15:09:25

Overlay fs鴻蒙

2019-09-20 10:04:45

Linux系統(tǒng)虛擬文件
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产在线一区二区三区 | 欧美亚洲国产日韩 | 国产精品xxxx| 国产精品久久久爽爽爽麻豆色哟哟 | 欧美一区二区三区在线免费观看 | 天天操夜夜操免费视频 | 特级丰满少妇一级aaaa爱毛片 | 黄色av一区 | 国产日韩一区二区三免费高清 | 美女天天干 | 久久久久99| 日韩电影免费观看中文字幕 | 99精品国自产在线 | 伊色综合久久之综合久久 | 国内精品视频在线观看 | 91精品成人久久 | 欧美久久一区二区 | 久久免费看 | 在线观看免费av网站 | 国产精品高清在线 | h视频网站在线观看 | 日韩一二区在线 | 一级a性色生活片久久毛片波多野 | 久久久久久久国产精品视频 | 在线视频99| 精品国产一区二区三区久久久蜜月 | 中文字幕 在线观看 | 瑟瑟视频在线看 | 少妇一级淫片免费放播放 | 呦呦在线视频 | 一区二区中文 | 欧美男人天堂 | 国产一级在线观看 | 二区av | www.99re | 国内成人免费视频 | 欧美精品一级 | 亚洲国产福利视频 | 亚洲一二三视频 | 国产精品自拍一区 | 欧美国产激情 |