recovery 恢复出厂设置失败Data wipe failed

最近客户反馈,编译32位的android系统,在recovery中执行恢复出厂设置的时候失败了,失败的打印提升信息如下。
Formatting /data...
[    2.191404] E:get_file_size: invalid size -1289764864 for /dev/block/data
[    2.207430] Data wipe failed.

根据打印提示,意识是说获取data分区的size是无效的。我们来看看这个函数get_file_size
bootable/recovery/roots.cpp

static ssize_t get_file_size(int fd, uint64_t reserve_len) {
  struct stat buf;
  int ret = fstat(fd, &buf);
  if (ret) return 0;

  ssize_t computed_size;
  if (S_ISREG(buf.st_mode)) {
    computed_size = buf.st_size - reserve_len;
  } else if (S_ISBLK(buf.st_mode)) {
    computed_size = get_block_device_size(fd) - reserve_len;
  } else {
    computed_size = 0;
  }

  return computed_size;
}

这个ssize_t是跟系统的位数相关的,当时32位的系统时,ssize_t的大小为U32,
那么此时能够表示的最大的长度为2^32-1=4294967295=4095.99M=4G
也就是说,当时32位的系统时,ssize_t能够保存的最大值为4G,当data分区的大小超过4G的时候,
ssize_t就无法正常保存的获取的data分区的大小,那么也就会出错了。

而实际项目上面给data分区的大小为11G+, 那么自然就会出错了,我们把使用ssize_t的地方换成uint64_t即可
patch如下:
diff --git a/roots.cpp b/roots.cpp
index 25d9d7e..5197ccb 100644
--- a/roots.cpp
+++ b/roots.cpp
@@ -182,12 +182,12 @@ static int exec_cmd(const char* path, char* const argv[]) {
     return WEXITSTATUS(status);
 }
 
-static ssize_t get_file_size(int fd, uint64_t reserve_len) {
+static uint64_t get_file_size(int fd, uint64_t reserve_len) {
   struct stat buf;
   int ret = fstat(fd, &buf);
   if (ret) return 0;
 
-  ssize_t computed_size;
+  uint64_t computed_size;
   if (S_ISREG(buf.st_mode)) {
     computed_size = buf.st_size - reserve_len;
   } else if (S_ISBLK(buf.st_mode)) {
@@ -234,7 +234,7 @@ int format_volume(const char* volume, const char* directory) {
             close(fd);
         }
 
-        ssize_t length = 0;
+        uint64_t length = 0;
         if (v->length != 0) {
             length = v->length;
         } else if (v->key_loc != NULL && strcmp(v->key_loc, "footer") == 0) {
到此,问题解决。

猜你喜欢

转载自blog.csdn.net/csdn66_2016/article/details/80272790