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


http://linux.bihlman.com/2010/05/09/how-to-solve-zero-length-file-problem-in-linuxs-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