最近客户反馈,编译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
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分区的大小,那么也就会出错了。
那么此时能够表示的最大的长度为2^32-1=4294967295=4095.99M=4G
也就是说,当时32位的系统时,ssize_t能够保存的最大值为4G,当data分区的大小超过4G的时候,
ssize_t就无法正常保存的获取的data分区的大小,那么也就会出错了。
而实际项目上面给data分区的大小为11G+, 那么自然就会出错了,我们把使用ssize_t的地方换成uint64_t即可
patch如下:
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) {到此,问题解决。