Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ce16a8a9 authored by Connor O'Brien's avatar Connor O'Brien
Browse files

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: default avatarConnor O'Brien <connoro@google.com>

Change-Id: Id48b7a3ebb9074983a4422a79a64dcb437c0f888
parent 279cb8b3
Loading
Loading
Loading
Loading
+37 −6
Original line number Diff line number Diff line
@@ -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;
+11 −7
Original line number Diff line number Diff line
@@ -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);
}
+1 −1
Original line number Diff line number Diff line
@@ -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