From 726c8084cdf994793375d18fd3aee053dc798e51 Mon Sep 17 00:00:00 2001 From: Igor Canadi Date: Mon, 31 Mar 2014 14:45:26 -0700 Subject: [PATCH] Retry FS system calls on EINTR Summary: EINTR means 'please retry'. We don't do that currenty. We should. Test Plan: make check, although it doesn't really test the new code. we'll just have to believe in the code! Reviewers: haobo, ljin Reviewed By: haobo CC: leveldb Differential Revision: https://reviews.facebook.net/D17349 --- util/env_posix.cc | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/util/env_posix.cc b/util/env_posix.cc index da65d7374..4935e47f8 100644 --- a/util/env_posix.cc +++ b/util/env_posix.cc @@ -174,7 +174,10 @@ class PosixSequentialFile: public SequentialFile { virtual Status Read(size_t n, Slice* result, char* scratch) { Status s; - size_t r = fread_unlocked(scratch, 1, n, file_); + size_t r = -1; + do { + r = fread_unlocked(scratch, 1, n, file_); + } while (r < 0 && errno == EINTR); *result = Slice(scratch, r); if (r < n) { if (feof(file_)) { @@ -231,7 +234,10 @@ class PosixRandomAccessFile: public RandomAccessFile { virtual Status Read(uint64_t offset, size_t n, Slice* result, char* scratch) const { Status s; - ssize_t r = pread(fd_, scratch, n, static_cast(offset)); + ssize_t r = -1; + do { + r = pread(fd_, scratch, n, static_cast(offset)); + } while (r < 0 && errno == EINTR); *result = Slice(scratch, (r < 0) ? 0 : r); if (r < 0) { // An error: return a non-ok status @@ -680,6 +686,9 @@ class PosixWritableFile : public WritableFile { while (left != 0) { ssize_t done = write(fd_, src, left); if (done < 0) { + if (errno == EINTR) { + continue; + } return IOError(filename_, errno); } TEST_KILL_RANDOM(rocksdb_kill_odds); @@ -727,6 +736,9 @@ class PosixWritableFile : public WritableFile { while (left != 0) { ssize_t done = write(fd_, src, left); if (done < 0) { + if (errno == EINTR) { + continue; + } return IOError(filename_, errno); } TEST_KILL_RANDOM(rocksdb_kill_odds * REDUCE_ODDS2); @@ -849,6 +861,9 @@ class PosixRandomRWFile : public RandomRWFile { while (left != 0) { ssize_t done = pwrite(fd_, src, left, offset); if (done < 0) { + if (errno == EINTR) { + continue; + } return IOError(filename_, errno); } @@ -1003,7 +1018,10 @@ class PosixEnv : public Env { unique_ptr* result, const EnvOptions& options) { result->reset(); - FILE* f = fopen(fname.c_str(), "r"); + FILE* f = nullptr; + do { + f = fopen(fname.c_str(), "r"); + } while (f == nullptr && errno == EINTR); if (f == nullptr) { *result = nullptr; return IOError(fname, errno); @@ -1051,7 +1069,10 @@ class PosixEnv : public Env { const EnvOptions& options) { result->reset(); Status s; - const int fd = open(fname.c_str(), O_CREAT | O_RDWR | O_TRUNC, 0644); + int fd = -1; + do { + fd = open(fname.c_str(), O_CREAT | O_RDWR | O_TRUNC, 0644); + } while (fd < 0 && errno == EINTR); if (fd < 0) { s = IOError(fname, errno); } else {