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

Commit 324c9b87 authored by Kelvin Zhang's avatar Kelvin Zhang Committed by Automerger Merge Worker
Browse files

Merge "Make partition metadata write atomic" into main am: 9c949326 am: d8fd576b am: b7dbcaa4

parents f0171e51 b7dbcaa4
Loading
Loading
Loading
Loading
+1 −7
Original line number Diff line number Diff line
@@ -111,13 +111,7 @@ bool SaveMetadata(MetadataBuilder* builder, const std::string& metadata_dir) {
        return true;
    }

    unique_fd fd(open(metadata_file.c_str(), O_CREAT | O_RDWR | O_TRUNC | O_CLOEXEC | O_BINARY | O_SYNC, 0644));
    if (fd < 0) {
        LOG(ERROR) << "open failed: " << metadata_file;
        return false;
    }

    if (!WriteToImageFile(fd, *exported.get())) {
    if (!WriteToImageFile(metadata_file, *exported.get())) {
        LOG(ERROR) << "Unable to save new metadata";
        return false;
    }
+39 −5
Original line number Diff line number Diff line
@@ -123,13 +123,46 @@ bool WriteToImageFile(borrowed_fd fd, const LpMetadata& input) {
    return true;
}

#if !defined(_WIN32)
bool FsyncDirectory(const char* dirname) {
    android::base::unique_fd fd(TEMP_FAILURE_RETRY(open(dirname, O_RDONLY | O_CLOEXEC)));
    if (fd == -1) {
        PLOG(ERROR) << "Failed to open " << dirname;
        return false;
    }
    if (fsync(fd) == -1) {
        if (errno == EROFS || errno == EINVAL) {
            PLOG(WARNING) << "Skip fsync " << dirname
                          << " on a file system does not support synchronization";
        } else {
            PLOG(ERROR) << "Failed to fsync " << dirname;
            return false;
        }
    }
    return true;
}
#endif

bool WriteToImageFile(const std::string& file, const LpMetadata& input) {
    unique_fd fd(open(file.c_str(), O_CREAT | O_RDWR | O_TRUNC | O_CLOEXEC | O_BINARY, 0644));
    if (fd < 0) {
        PERROR << __PRETTY_FUNCTION__ << " open failed: " << file;
    const auto parent_dir = base::Dirname(file);
    TemporaryFile tmpfile(parent_dir);
    if (!WriteToImageFile(tmpfile.fd, input)) {
        PLOG(ERROR) << "Failed to write geometry data to tmpfile " << tmpfile.path;
        return false;
    }
    return WriteToImageFile(fd, input);

#if !defined(_WIN32)
    fsync(tmpfile.fd);
#endif
    const auto err = rename(tmpfile.path, file.c_str());
    if (err != 0) {
        PLOG(ERROR) << "Failed to rename tmp geometry file " << tmpfile.path << " to " << file;
        return false;
    }
#if !defined(_WIN32)
    FsyncDirectory(parent_dir.c_str());
#endif
    return true;
}

ImageBuilder::ImageBuilder(const LpMetadata& metadata, uint32_t block_size,
@@ -208,7 +241,8 @@ bool ImageBuilder::ExportFiles(const std::string& output_dir) {
        std::string file_name = "super_" + name + ".img";
        std::string file_path = output_dir + "/" + file_name;

        static const int kOpenFlags = O_CREAT | O_RDWR | O_TRUNC | O_CLOEXEC | O_NOFOLLOW | O_BINARY;
        static const int kOpenFlags =
                O_CREAT | O_RDWR | O_TRUNC | O_CLOEXEC | O_NOFOLLOW | O_BINARY;
        unique_fd fd(open(file_path.c_str(), kOpenFlags, 0644));
        if (fd < 0) {
            PERROR << "open failed: " << file_path;