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

This commit is contained in:
David Anderson 2023-05-22 17:39:07 +00:00 committed by Gerrit Code Review
commit bf11ce74ff
2 changed files with 29 additions and 5 deletions

View file

@ -458,9 +458,34 @@ 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;
return FiemapStatus::FromErrno(errno);
// 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) {

View file

@ -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_;