Fastboot: use flash erase & logical block size for building userdata

If the bootloader provides erase-block-size and logical-block-size
getvar variables, then pass these to libext4_utils when building a new
userdata image. This info is used to tune stride and stripe-width.

Bug: 33243520
Test: Modify fb_getvar to return values for "erase-block-size" and
"logical-block-size" and check that fastboot -w sets userdata
parameters correctly.
Signed-off-by: Connor O'Brien <connoro@google.com>

Change-Id: Id48b7a3ebb9074983a4422a79a64dcb437c0f888
This commit is contained in:
Connor O'Brien 2017-02-06 14:39:31 -08:00
parent 279cb8b39a
commit ce16a8a940
3 changed files with 49 additions and 14 deletions

View File

@ -1303,6 +1303,36 @@ static int64_t parse_num(const char *arg)
return num;
}
static std::string fb_fix_numeric_var(std::string var) {
// Some bootloaders (angler, for example), send spurious leading whitespace.
var = android::base::Trim(var);
// Some bootloaders (hammerhead, for example) use implicit hex.
// This code used to use strtol with base 16.
if (!android::base::StartsWith(var, "0x")) var = "0x" + var;
return var;
}
static unsigned fb_get_flash_block_size(Transport* transport, std::string name) {
std::string sizeString;
if (!fb_getvar(transport, name.c_str(), &sizeString)) {
/* This device does not report flash block sizes, so return 0 */
return 0;
}
sizeString = fb_fix_numeric_var(sizeString);
unsigned size;
if (!android::base::ParseUint(sizeString, &size)) {
fprintf(stderr, "Couldn't parse %s '%s'.\n", name.c_str(), sizeString.c_str());
return 0;
}
if (size < 4096 || (size & (size - 1)) != 0) {
fprintf(stderr, "Invalid %s %u: must be a power of 2 and at least 4096.\n",
name.c_str(), size);
return 0;
}
return size;
}
static void fb_perform_format(Transport* transport,
const char* partition, int skip_if_not_supported,
const char* type_override, const char* size_override,
@ -1345,11 +1375,7 @@ static void fb_perform_format(Transport* transport,
}
partition_size = size_override;
}
// Some bootloaders (angler, for example), send spurious leading whitespace.
partition_size = android::base::Trim(partition_size);
// Some bootloaders (hammerhead, for example) use implicit hex.
// This code used to use strtol with base 16.
if (!android::base::StartsWith(partition_size, "0x")) partition_size = "0x" + partition_size;
partition_size = fb_fix_numeric_var(partition_size);
gen = fs_get_generator(partition_type);
if (!gen) {
@ -1370,7 +1396,12 @@ static void fb_perform_format(Transport* transport,
}
fd = fileno(tmpfile());
if (fs_generator_generate(gen, fd, size, initial_dir)) {
unsigned eraseBlkSize, logicalBlkSize;
eraseBlkSize = fb_get_flash_block_size(transport, "erase-block-size");
logicalBlkSize = fb_get_flash_block_size(transport, "logical-block-size");
if (fs_generator_generate(gen, fd, size, initial_dir, eraseBlkSize, logicalBlkSize)) {
fprintf(stderr, "Cannot generate image: %s\n", strerror(errno));
close(fd);
return;

View File

@ -14,18 +14,21 @@
#include <ext4_utils/make_ext4fs.h>
#include <sparse/sparse.h>
static int generate_ext4_image(int fd, long long partSize, const std::string& initial_dir)
static int generate_ext4_image(int fd, long long partSize, const std::string& initial_dir,
unsigned eraseBlkSize, unsigned logicalBlkSize)
{
if (initial_dir.empty()) {
make_ext4fs_sparse_fd(fd, partSize, NULL, NULL);
make_ext4fs_sparse_fd_align(fd, partSize, NULL, NULL, eraseBlkSize, logicalBlkSize);
} else {
make_ext4fs_sparse_fd_directory(fd, partSize, NULL, NULL, initial_dir.c_str());
make_ext4fs_sparse_fd_directory_align(fd, partSize, NULL, NULL, initial_dir.c_str(),
eraseBlkSize, logicalBlkSize);
}
return 0;
}
#ifdef USE_F2FS
static int generate_f2fs_image(int fd, long long partSize, const std::string& initial_dir)
static int generate_f2fs_image(int fd, long long partSize, const std::string& initial_dir,
unsigned /* unused */, unsigned /* unused */)
{
if (!initial_dir.empty()) {
fprintf(stderr, "Unable to set initial directory on F2FS filesystem\n");
@ -39,7 +42,8 @@ static const struct fs_generator {
const char* fs_type; //must match what fastboot reports for partition type
//returns 0 or error value
int (*generate)(int fd, long long partSize, const std::string& initial_dir);
int (*generate)(int fd, long long partSize, const std::string& initial_dir,
unsigned eraseBlkSize, unsigned logicalBlkSize);
} generators[] = {
{ "ext4", generate_ext4_image},
@ -58,7 +62,7 @@ const struct fs_generator* fs_get_generator(const std::string& fs_type) {
}
int fs_generator_generate(const struct fs_generator* gen, int tmpFileNo, long long partSize,
const std::string& initial_dir)
const std::string& initial_dir, unsigned eraseBlkSize, unsigned logicalBlkSize)
{
return gen->generate(tmpFileNo, partSize, initial_dir);
return gen->generate(tmpFileNo, partSize, initial_dir, eraseBlkSize, logicalBlkSize);
}

View File

@ -8,6 +8,6 @@ struct fs_generator;
const struct fs_generator* fs_get_generator(const std::string& fs_type);
int fs_generator_generate(const struct fs_generator* gen, int tmpFileNo, long long partSize,
const std::string& initial_dir);
const std::string& initial_dir, unsigned eraseBlkSize = 0, unsigned logicalBlkSize = 0);
#endif