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

Commit b3e18294 authored by Konstantin Vyshetsky's avatar Konstantin Vyshetsky
Browse files

fastbootd: pass handle in place of fd



There are cases such as non 4KB aligned buffers which break writes on
file descriptors opened with O_DIRECT. Flashing functions need more
control over the file descriptor, which is not achievable easily by
having only a file descriptor passed. This CL modifies the logic to pass
the PartitionHandle in place of the file descriptor during flashing.

Bug: 225108941
Signed-off-by: default avatarKonstantin Vyshetsky <vkon@google.com>
Change-Id: I049d0ffb183c9de1267b7e442488c8ba5002186a
parent c9b78e95
Loading
Loading
Loading
Loading
+14 −14
Original line number Diff line number Diff line
@@ -76,7 +76,7 @@ void WipeOverlayfsForPartition(FastbootDevice* device, const std::string& partit

}  // namespace

int FlashRawDataChunk(int fd, const char* data, size_t len) {
int FlashRawDataChunk(PartitionHandle* handle, const char* data, size_t len) {
    size_t ret = 0;
    const size_t max_write_size = 1048576;
    void* aligned_buffer;
@@ -91,7 +91,7 @@ int FlashRawDataChunk(int fd, const char* data, size_t len) {
    while (ret < len) {
        int this_len = std::min(max_write_size, len - ret);
        memcpy(aligned_buffer_unique_ptr.get(), data, this_len);
        int this_ret = write(fd, aligned_buffer_unique_ptr.get(), this_len);
        int this_ret = write(handle->fd(), aligned_buffer_unique_ptr.get(), this_len);
        if (this_ret < 0) {
            PLOG(ERROR) << "Failed to flash data of len " << len;
            return -1;
@@ -102,8 +102,8 @@ int FlashRawDataChunk(int fd, const char* data, size_t len) {
    return 0;
}

int FlashRawData(int fd, const std::vector<char>& downloaded_data) {
    int ret = FlashRawDataChunk(fd, downloaded_data.data(), downloaded_data.size());
int FlashRawData(PartitionHandle* handle, const std::vector<char>& downloaded_data) {
    int ret = FlashRawDataChunk(handle, downloaded_data.data(), downloaded_data.size());
    if (ret < 0) {
        return -errno;
    }
@@ -111,30 +111,30 @@ int FlashRawData(int fd, const std::vector<char>& downloaded_data) {
}

int WriteCallback(void* priv, const void* data, size_t len) {
    int fd = reinterpret_cast<long long>(priv);
    PartitionHandle* handle = reinterpret_cast<PartitionHandle*>(priv);
    if (!data) {
        return lseek64(fd, len, SEEK_CUR) >= 0 ? 0 : -errno;
        return lseek64(handle->fd(), len, SEEK_CUR) >= 0 ? 0 : -errno;
    }
    return FlashRawDataChunk(fd, reinterpret_cast<const char*>(data), len);
    return FlashRawDataChunk(handle, reinterpret_cast<const char*>(data), len);
}

int FlashSparseData(int fd, std::vector<char>& downloaded_data) {
int FlashSparseData(PartitionHandle* handle, std::vector<char>& downloaded_data) {
    struct sparse_file* file = sparse_file_import_buf(downloaded_data.data(),
                                                      downloaded_data.size(), true, false);
    if (!file) {
        // Invalid sparse format
        return -EINVAL;
    }
    return sparse_file_callback(file, false, false, WriteCallback, reinterpret_cast<void*>(fd));
    return sparse_file_callback(file, false, false, WriteCallback, reinterpret_cast<void*>(handle));
}

int FlashBlockDevice(int fd, std::vector<char>& downloaded_data) {
    lseek64(fd, 0, SEEK_SET);
int FlashBlockDevice(PartitionHandle* handle, std::vector<char>& downloaded_data) {
    lseek64(handle->fd(), 0, SEEK_SET);
    if (downloaded_data.size() >= sizeof(SPARSE_HEADER_MAGIC) &&
        *reinterpret_cast<uint32_t*>(downloaded_data.data()) == SPARSE_HEADER_MAGIC) {
        return FlashSparseData(fd, downloaded_data);
        return FlashSparseData(handle, downloaded_data);
    } else {
        return FlashRawData(fd, downloaded_data);
        return FlashRawData(handle, downloaded_data);
    }
}

@@ -181,7 +181,7 @@ int Flash(FastbootDevice* device, const std::string& partition_name) {
    if (android::base::GetProperty("ro.system.build.type", "") != "user") {
        WipeOverlayfsForPartition(device, partition_name);
    }
    int result = FlashBlockDevice(handle.fd(), data);
    int result = FlashBlockDevice(&handle, data);
    sync();
    return result;
}