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

Commit bf11ce74 authored by David Anderson's avatar David Anderson Committed by Gerrit Code Review
Browse files

Merge "libfiemap: Handle EAGAIN in fallocate()."

parents 2fb1c671 0fa37107
Loading
Loading
Loading
Loading
+28 −3
Original line number Diff line number Diff line
@@ -458,10 +458,35 @@ static FiemapStatus AllocateFile(int file_fd, const std::string& file_path, uint
            return FiemapStatus::Error();
    }

    if (fallocate(file_fd, 0, 0, file_size)) {
        PLOG(ERROR) << "Failed to allocate space for file: " << file_path << " size: " << file_size;
    // F2FS can return EAGAIN and partially fallocate. Keep trying to fallocate,
    // and if we don't make forward progress, return ENOSPC.
    std::optional<off_t> prev_size;
    while (true) {
        if (fallocate(file_fd, 0, 0, file_size) == 0) {
            break;
        }
        if (errno != EAGAIN) {
            PLOG(ERROR) << "Failed to allocate space for file: " << file_path
                        << " size: " << file_size;
            return FiemapStatus::FromErrno(errno);
        }

        struct stat s;
        if (fstat(file_fd, &s) < 0) {
            PLOG(ERROR) << "Failed to fstat after fallocate failure: " << file_path;
            return FiemapStatus::FromErrno(errno);
        }
        if (!prev_size) {
            prev_size = {s.st_size};
            continue;
        }
        if (*prev_size >= s.st_size) {
            LOG(ERROR) << "Fallocate retry failed, got " << s.st_size << ", asked for "
                       << file_size;
            return FiemapStatus(FiemapStatus::ErrorCode::NO_SPACE);
        }
        LOG(INFO) << "Retrying fallocate, got " << s.st_size << ", asked for " << file_size;
    }

    if (need_explicit_writes) {
        auto status = WriteZeroes(file_fd, file_path, blocksz, file_size, on_progress);
+1 −2
Original line number Diff line number Diff line
@@ -56,8 +56,7 @@ class FiemapStatus {
    // For logging and debugging only.
    std::string string() const;

  protected:
    FiemapStatus(ErrorCode code) : error_code_(code) {}
    explicit FiemapStatus(ErrorCode code) : error_code_(code) {}

  private:
    ErrorCode error_code_;