data分区变为只读
解决EXT4文件系统丢失文件(0长度文件)问题 -- (网上文章)
原文地址 http://hi.baidu.com/aokikyon/blog/item/4d9d8fa1ad06ec91471064ab.html
解决EXT4文件系统丢失文件(0长度文件)问题2011-07-25 17:35手机的Data分区被挂载为EXT4文件格式,由于开发阶段常会拔电源重启,经常遇到刚安装的程序重启后丢失以及设置壁纸重启后恢复等问题。
在网上搜了半天,ext4丢文件现象有很多人反映,不过多数是PC系统的问题。
看我自己手机的配置,发现有些参数不同。。于是研究了半天ext4挂载的参数,推荐看linux内核中的ext4文档,写的比网上文章详细多。
首先怀疑是data类型,有三种,分别为writeback、ordered和jounal
Data Mode
=
There are 3 different data modes:
- writeback mode
In data=writeback mode, ext4 does not journal data at all. This mode provides
a similar level of journaling as that of XFS, JFS, and ReiserFS in its default
mode - metadata journaling. A crash+recovery can cause incorrect data to
appear in files which were written shortly before the crash. This mode will
typically provide the best ext4 performance.
- ordered mode
In data=ordered mode, ext4 only officially journals metadata, but it logically
groups metadata information related to data changes with the data blocks into a
single unit called a transaction. When it's time to write the new metadata
out to disk, the associated data blocks are written first. In general,
this mode performs slightly slower than writeback but significantly faster than journal mode.
- journal mode
data=journal mode provides full data and metadata journaling. All new data is
written to the journal first, and then to its final location.
In the event of a crash, the journal can be replayed, bringing both data and
metadata into a consistent state. This mode is the slowest except when data
needs to be read from and written to disk at the same time where it
outperforms all others modes. Currently ext4 does not have delayed
allocation support if this data journalling mode is selected.
将默认的ordered改为writeback,还是会丢,和此次参数无关。
接着怀疑没有commit参数
commit=nrsec(*)Ext4 can be told to sync all its data and metadata
every 'nrsec' seconds. The default value is 5 seconds.
This means that if you lose your power, you will lose
as much as the latest 5 seconds of work (your
filesystem will not be damaged though, thanks to the
journaling). This default value (or any low value)
will hurt performance, but it's good for data-safety.
Setting it to 0 will have the same effect as leaving
it at the default (5 seconds).
Setting it to very large values will improve
performance.
看过文档后发现commit默认为5,改大改小还是会丢文件。不过为了提升性能,CM系统的设置一般为15。
网上还有人提出noauto_da_alloc要打开,结果发现默认是打开的orz
auto_da_alloc(*)Many broken applications don't use fsync() when
noauto_da_allocreplacing existing files via patterns such as
fd = open("foo.new")/write(fd,..)/close(fd)/
rename("foo.new", "foo"), or worse yet,
fd = open("foo", O_TRUNC)/write(fd,..)/close(fd).
If auto_da_alloc is enabled, ext4 will detect
the replace-via-rename and replace-via-truncate
patterns and force that any delayed allocation
blocks are allocated such that at the next
journal commit, in the default data=ordered
mode, the data blocks of the new file are forced
to disk before the rename() operation is
committed. This provides roughly the same level
of guarantees as ext3, and avoids the
"zero-length" problem that can happen when a
system crashes before the delayed allocation
blocks are forced to disk.
最后终于用zero size搜索到一篇有用的文章
How to Solve Zero Length File Problem in Linux’s Ext4 File System
文中指出
Cause:
The most possible cause for such behavior is the delayed allocation feature.What happens is when a file is closed after creation, the data blocks are allocated for the file after a minute or so. Because of this, the metadata of the modified file will show zero bytes as its size. The data allocation is done after the delayed allocation is over. Hence, in the case of a power surge the new file is considered as an empty file.
ext4的数据allocation竟然要等1分钟以上,这显然无法满足嵌入式的要求
解决方案是打开nodelalloc选项,尝试之,确有效!
nodelallocDisable delayed allocation. Blocks are allocated
when the data is copied from userspace to the
page cache, either via the write(2) system call
or when an mmap'ed page which was previously
unallocated is written for the first time.
但是不知道对性能有没有影响。
BTW
android的init.rc非常坑爹,mount命令和标准linux指令不同,
我一直怀疑只能解析一个参数,后来发现最后的参数不能用空格,需要用逗号隔开!
mount ext4 /dev/block/mmcblk0p13 /data nosuid nodev barrier=1 noauto_da_alloc,commit=15,nodelalloc