linux fuse文件系统在 android fuse sdcard的 运用
一、android GB 及JB、KK版本内置sdcard效果对比图
从上面效果对比图,我们可以发现android fuse sdcard 有如下两个优点:
1、使用fuse后 /data 和 /sdcard0 是共离一块分区,这块分区的空间/data和/sdcard0 动态享用, 用户使用灵活。
2、去掉了fat32文件系统,这样也免去了一个license的风险。
二、fuse的标准工作流程图
这里重点说明libfuse的作用:libfuse为开发者提供了接口fuse_operations开发者只需要实现这组接口,然后调用fuse初始化接口:fuse_mount()、fuse_new()、fuse_loop()即可实现一个用户空间文件系统。这样为开发多种fuse文件系统带来很多方便。
三、android fuse sdcard架构图及source code
android fuse sdcard 流程和标准fuse流程图最大不同点在于:
android没有直接移植标准的libfuse,而是重写了相关代码,将libfuse的功能集成到sdcard dameon。
这样做的我能想到的好处,可能就是函数调用的层次少了一些,可能效率会好点。
一直想不明白android为什么不移植libfuse。
3、fuse sdcard 的mount状态,如下图:
四、使用fuse sdcard 带来的一些问题及解决方法
1、/data和/sdcard 动态占用空间,如果用户通过/sdcard将整个分区填满,则会导致系统无法启动。
解决办法,就是设置一个/sdcard/可用的上限,不至于导致系统崩溃至无法启用。
具体可以参考mtk修改的代码:\kernel\fs\fuse\inode.c (LIMIT_SDCARD_SIZE包宏处)
static void convert_fuse_statfs(struct kstatfs *stbuf, struct fuse_kstatfs *attr)
{
stbuf->f_type = FUSE_SUPER_MAGIC;
stbuf->f_bsize = attr->bsize;
stbuf->f_frsize = attr->frsize;
stbuf->f_blocks = attr->blocks;
stbuf->f_bfree = attr->bfree;
stbuf->f_bavail = attr->bavail;
stbuf->f_files = attr->files;
stbuf->f_ffree = attr->ffree;
stbuf->f_namelen = attr->namelen;
#ifdef LIMIT_SDCARD_SIZE
stbuf->f_blocks -= (u32)data_free_size_th/attr->bsize;
if(stbuf->f_bfree < ((u32)data_free_size_th/attr->bsize)){
stbuf->f_bfree = 0;
}else{
stbuf->f_bfree-= (u32)data_free_size_th/attr->bsize;
}
if(stbuf->f_bavail < ((u32)data_free_size_th/attr->bsize)){
stbuf->f_bavail = 0;
}else{
stbuf->f_bavail-= (u32)data_free_size_th/attr->bsize;
}
#endif
/* fsid is left zero */
}
2、清除用户数据或者recovey、ota等涉及到要format /data 目录时,/storage/sdcard0 的数据也会被清空掉。
解决办法:
3、不同size emmc 的兼容:同一款手机,可能需要兼容多个size emmc,比如16G版本,32G版本。
4、厂家的预置资源文件,如何导入到内置sdcard?
手机出货前,厂家通常会预置一些资源文件,比如,导航地图,广告视频等。
解决方法:将预置资源编译到/data/media/目录下,系统第一次启动时installd进程会自动将/data/media/目录的东西移到/data/media/0 目录,即sdcard根目录可见该预置资源。
见如下代码:frameworks\base\cmds\installd\installd.c
int initialize_directories() {
int res = -1;
// Read current filesystem layout version to handle upgrade paths
char version_path[PATH_MAX];
snprintf(version_path, PATH_MAX, "%s.layout_version", android_data_dir.path);
int oldVersion;
if (fs_read_atomic_int(version_path, &oldVersion) == -1) {
oldVersion = 0;
}
int version = oldVersion;
// /data/media.tmp
char media_tmp_dir[PATH_MAX];
snprintf(media_tmp_dir, PATH_MAX, "%smedia.tmp", android_data_dir.path);
// Only copy when upgrade not already in progress
if (access(media_tmp_dir, F_OK) == -1) {
if (rename(android_media_dir.path, media_tmp_dir) == -1) {
ALOGE("Failed to move legacy media path: %s", strerror(errno));
goto fail;
}
}
// Create /data/media again
if (fs_prepare_dir(android_media_dir.path, 0770, AID_MEDIA_RW, AID_MEDIA_RW) == -1) {
goto fail;
}
// /data/media/0
char owner_media_dir[PATH_MAX];
snprintf(owner_media_dir, PATH_MAX, "%s0", android_media_dir.path);
// Move any owner data into place
if (access(media_tmp_dir, F_OK) == 0) {
if (rename(media_tmp_dir, owner_media_dir) == -1) {
ALOGE("Failed to move owner media path: %s", strerror(errno));
goto fail;
}
}
version = 2;
// Persist layout version if changed
if (version != oldVersion) {
if (fs_write_atomic_int(version_path, version) == -1) {
ALOGE("Failed to save version to %s: %s", version_path, strerror(errno));
goto fail;
}
}
// Success!
res = 0;
}
通过上面的方法,确实可以将预置资源导入到sdcard,但在实际大量生产中,发现一个新问题:
预置资源可能会被移到/sdcard/0/ 目录(即/data/media/0/0),多了一级0目录。
为什么会发生这种问题呢? 经过长时间分析,应该是因为上面的代码稳定性极度依赖于函数fs_write_atomic_int()的原子操作性。
但实际上,该函数根本达不到原子操作效果。
如果解决该问题呢? 1、取消多用户 2、fs_write_atomic_int()函数后面添加sync()。
5、fuse sdcard对开机速度的影响
6、fuse sdcard 相对fat32 sdcard性能更差
linux fuse文件系统在 android fuse sdcard的 运用相关推荐
- 基于fuse文件系统的android sdcard存储方案:之二
续<基于fuse文件系统的android sdcard存储方案:之一>,再聊聊基于fuse文件系统的android sdcard存储方案:之二, 以后有空再谈谈该方案的缺点,及优化方案. ...
- Android fuse文件系统
一.fuse文件系统挂载 从android4.4 以来,第三方应用程序是不能再随便的访问sdcard,sdcard的权限管理是fuse 即用户空间文件系统(Filesystem in Userspac ...
- linux fuse安装脚本,Linux FUSE(用户态文件系统)的使用:用libfuse创建FUSE文件系统...
说明 FUSE 是Linux Kernel的特性之一:一个用户态文件系统框架,a userspace filesystem framework. 形象的说就是可以在用户态运行一个程序,这个程序暴露出一 ...
- fuse文件系统调试环境
libfuse源码:GitHub - libfuse/libfuse: The reference implementation of the Linux FUSE (Filesystem in Us ...
- python画画bup_用Python编写一个简单的FUSE文件系统的教程
如果你是我的长期读者,那么你应该知道我在寻找一个完美备份程序,最后我写了一个基于bup的我自己的加密层. 在写encbup的时候,我对仅仅恢复一个文件就必须要下载整个巨大的档案文件的做法不甚满意,但仍 ...
- android fuse 检测原理,fuse 原理总结
Fuse是filesystem in user space,一个用户空间的文件系统框架,允许非特权用户建立功能完备的文件系统,而不需要重新编译内核.fuse模块仅仅提供内核模块的入口,而本身的主要实现 ...
- 嵌入式Linux根文件系统制作
嵌入式Linux根文件系统制作 一.根文件系统简介 根文件系统首先是一种文件系统,该文件系统不仅具有普通文件系统的存储数据文件的功能,但是相对于普通的文件系统而言它还是内核启动时所挂载(mount)的 ...
- Android研究-linux内核启动到android系统
很多人阅读代码,总喜欢从头开始,这样觉得很安全,有依靠,无论如何总是能知道"头",有头就能找到任何需要的部分. Android生在linux内核基础上,linux内核启动的最后一步 ...
- 构建基本的嵌入式Linux根文件系统
构建基本的嵌入式Linux根文件系统 其实在去年8月份我做系统移植时就构建好了一个可以用的根文件系统,但是那时是跟着别人的<Linux全线移植文档>做的.有些东西我也不清楚,只是跟着做,做 ...
最新文章
- 熵是什么?熵的公式是什么?决策树如何把熵的递减变换为信息增益进行树枝的分叉以及树的生长的?
- django(权限、认证)系统—— 基于Authentication backends定制
- oracle学习第一天
- 【重复制造精讲】定义重复制造参数文件
- 【ASP.NET Web API教程】2.3.5 用Knockout.js创建动态UI
- mysql 行转列分级输出_MySQL如何实现行转列分级输出?_MySQL
- Solr-5.3.1安装配置
- 关于搞技术的一点思考
- python 内置运算
- java生成excel到本地_java 将数据库中的数据导出成Excel文件 并保存到本地 将文件地址返回给前端...
- 机器学习之工程师入门路线
- 【手势识别】基于matlab k-means聚类手势识别【含Matlab源码 386期】
- 学计算机编程要考证吗,程序员可以考的证书有哪些_可以自学吗_上学吧
- 卡尔曼滤波与扩展卡尔曼滤波(EKF)
- 卡内基梅隆计算机硕士录取案例,大神offer | 恭喜再来人学员录取卡耐基梅隆大学-机器学习硕士!...
- 三星发布全球首款太阳能笔记本
- Mac电脑如何快速回到桌面?
- 中国中试工厂市场现状研究分析与发展前景预测报告
- 零基础语法入门第第二十三讲 动词的用法总结
- python爬虫--获取天猫店铺商品价格及销量
热门文章
- 转:移动网络下的性能优化之省电篇
- J2EE 架构师之路
- 车载娱乐系统 AppSupport
- Android开源库集合(控件)
- BestCoder Round #90 Kblack loves flag
- python函数参数定义顺序_18 Python - 函数定义与参数
- Javascript第七章cookie的读取和写入源码第一课
- 搭建SSM全流程框架过程
- 向指定的服务器端口发送信息,向指定服务器的指定端口发送UDP包
- linux多进程spawn,【Linux Shell脚本编程】expect解决脚本交互 + Shell的多进程处理