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) {

到此,問題解決。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM