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

Commit 6a999710 authored by Chris Fries's avatar Chris Fries
Browse files

fastboot: Cap max size sent to libsparse

This is required for large (>INT_MAX) sparse limit reported by
the target.

Also, patch up return chains of "int" that need to deal with sizes
bigger than 2GB as well as return negative error codes.

Test: -S works with large max-download-size
Test: Flash 3GB system.img with max-download-size 2.5GB

Bug: 36810152
Change-Id: I562a50eabd706bd5b97c71a1aef07c1ffd1a2e5c
parent 4bf1be7e
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -328,11 +328,11 @@ void fb_queue_wait_for_disconnect(void)
    queue_action(OP_WAIT_FOR_DISCONNECT, "");
}

int fb_execute_queue(Transport* transport)
int64_t fb_execute_queue(Transport* transport)
{
    Action *a;
    char resp[FB_RESPONSE_SZ+1];
    int status = 0;
    int64_t status = 0;

    a = action_list;
    if (!a)
+5 −1
Original line number Diff line number Diff line
@@ -78,6 +78,10 @@ static const char* product = nullptr;
static const char* cmdline = nullptr;
static unsigned short vendor_id = 0;
static int long_listing = 0;
// Don't resparse files in too-big chunks.
// libsparse will support INT_MAX, but this results in large allocations, so
// let's keep it at 1GB to avoid memory pressure on the host.
static constexpr int64_t RESPARSE_LIMIT = 1 * 1024 * 1024 * 1024;
static int64_t sparse_limit = -1;
static int64_t target_sparse_limit = -1;

@@ -789,7 +793,7 @@ static int64_t get_sparse_limit(Transport* transport, int64_t size) {
    }

    if (size > limit) {
        return limit;
        return std::min(limit, RESPARSE_LIMIT);
    }

    return 0;
+2 −2
Original line number Diff line number Diff line
@@ -41,7 +41,7 @@ struct sparse_file;
/* protocol.c - fastboot protocol */
int fb_command(Transport* transport, const char* cmd);
int fb_command_response(Transport* transport, const char* cmd, char* response);
int fb_download_data(Transport* transport, const void* data, uint32_t size);
int64_t fb_download_data(Transport* transport, const void* data, uint32_t size);
int fb_download_data_sparse(Transport* transport, struct sparse_file* s);
const std::string fb_get_error();

@@ -64,7 +64,7 @@ void fb_queue_command(const char *cmd, const char *msg);
void fb_queue_download(const char *name, void *data, uint32_t size);
void fb_queue_notice(const char *notice);
void fb_queue_wait_for_disconnect(void);
int fb_execute_queue(Transport* transport);
int64_t fb_execute_queue(Transport* transport);
void fb_set_active(const char *slot);

/* util stuff */
+11 −10
Original line number Diff line number Diff line
@@ -48,7 +48,7 @@ const std::string fb_get_error() {
    return g_error;
}

static int check_response(Transport* transport, uint32_t size, char* response) {
static int64_t check_response(Transport* transport, uint32_t size, char* response) {
    char status[65];

    while (true) {
@@ -105,7 +105,7 @@ static int check_response(Transport* transport, uint32_t size, char* response) {
    return -1;
}

static int _command_start(Transport* transport, const char* cmd, uint32_t size, char* response) {
static int64_t _command_start(Transport* transport, const char* cmd, uint32_t size, char* response) {
    size_t cmdsize = strlen(cmd);
    if (cmdsize > 64) {
        g_error = android::base::StringPrintf("command too large (%zu)", cmdsize);
@@ -125,14 +125,14 @@ static int _command_start(Transport* transport, const char* cmd, uint32_t size,
    return check_response(transport, size, response);
}

static int _command_data(Transport* transport, const void* data, uint32_t size) {
    int r = transport->Write(data, size);
static int64_t _command_data(Transport* transport, const void* data, uint32_t size) {
    int64_t r = transport->Write(data, size);
    if (r < 0) {
        g_error = android::base::StringPrintf("data transfer failure (%s)", strerror(errno));
        transport->Close();
        return -1;
    }
    if (r != ((int) size)) {
    if (r != static_cast<int64_t>(size)) {
        g_error = "data transfer failure (short transfer)";
        transport->Close();
        return -1;
@@ -140,17 +140,17 @@ static int _command_data(Transport* transport, const void* data, uint32_t size)
    return r;
}

static int _command_end(Transport* transport) {
static int64_t _command_end(Transport* transport) {
    return check_response(transport, 0, 0) < 0 ? -1 : 0;
}

static int _command_send(Transport* transport, const char* cmd, const void* data, uint32_t size,
static int64_t _command_send(Transport* transport, const char* cmd, const void* data, uint32_t size,
                         char* response) {
    if (size == 0) {
        return -1;
    }

    int r = _command_start(transport, cmd, size, response);
    int64_t r = _command_start(transport, cmd, size, response);
    if (r < 0) {
        return -1;
    }
@@ -180,7 +180,7 @@ int fb_command_response(Transport* transport, const char* cmd, char* response) {
    return _command_send_no_data(transport, cmd, response);
}

int fb_download_data(Transport* transport, const void* data, uint32_t size) {
int64_t fb_download_data(Transport* transport, const void* data, uint32_t size) {
    char cmd[64];
    snprintf(cmd, sizeof(cmd), "download:%08x", size);
    return _command_send(transport, cmd, data, size, 0) < 0 ? -1 : 0;
@@ -242,7 +242,8 @@ static int fb_download_data_sparse_write(void *priv, const void *data, int len)

static int fb_download_data_sparse_flush(Transport* transport) {
    if (transport_buf_len > 0) {
        if (_command_data(transport, transport_buf, transport_buf_len) != transport_buf_len) {
        int64_t r = _command_data(transport, transport_buf, transport_buf_len);
        if (r != static_cast<int64_t>(transport_buf_len)) {
            return -1;
        }
        transport_buf_len = 0;