diff --git a/cmdline/handle.c b/cmdline/handle.c index 0fca91bb..1f1259ac 100644 --- a/cmdline/handle.c +++ b/cmdline/handle.c @@ -273,13 +273,15 @@ ssize_t handle_read(struct snapraid_handle* handle, block_off_t file_pos, unsign read_size = file_block_size(handle->file, file_pos, block_size); - count = 0; - errno = 0; - do { - bw_limit(handle->bw, block_size - count); + bw_limit(handle->bw, block_size); + count = 0; + do { read_ret = pread(handle->f, block_buffer + count, block_size - count, offset + count); if (read_ret == -1) { + if (errno == EINTR) + continue; + /* LCOV_EXCL_START */ log_error(errno, "Error reading file '%s' at offset %" PRIu64 " for size %u. %s.\n", handle->path, offset + count, block_size - count, strerror(errno)); return -1; @@ -287,8 +289,7 @@ ssize_t handle_read(struct snapraid_handle* handle, block_off_t file_pos, unsign } if (read_ret == 0) { /* LCOV_EXCL_START */ - if (errno == 0) - errno = ENXIO; + errno = ENXIO; log_error(errno, "Unexpected end of file '%s' at offset %" PRIu64 ". %s.\n", handle->path, offset, strerror(errno)); return -1; /* LCOV_EXCL_STOP */ @@ -333,12 +334,15 @@ int handle_write(struct snapraid_handle* handle, block_off_t file_pos, unsigned write_size = file_block_size(handle->file, file_pos, block_size); + bw_limit(handle->bw, write_size); + count = 0; do { - bw_limit(handle->bw, write_size - count); - write_ret = pwrite(handle->f, block_buffer + count, write_size - count, offset + count); if (write_ret == -1) { + if (errno == EINTR) + continue; + /* LCOV_EXCL_START */ log_fatal(errno, "Error writing file '%s'. %s.\n", handle->path, strerror(errno)); return -1; diff --git a/cmdline/parity.c b/cmdline/parity.c index 28df8dd9..6bb78f3d 100644 --- a/cmdline/parity.c +++ b/cmdline/parity.c @@ -839,12 +839,15 @@ int parity_write(struct snapraid_parity_handle* handle, block_off_t pos, unsigne if (split->valid_size < offset + block_size) split->valid_size = offset + block_size; + bw_limit(handle->bw, block_size); + count = 0; do { - bw_limit(handle->bw, block_size - count); - write_ret = pwrite(split->f, block_buffer + count, block_size - count, offset + count); if (write_ret == -1) { + if (errno == EINTR) + continue; + /* LCOV_EXCL_START */ if (errno == ENOSPC) { log_fatal(errno, "Failed to grow parity file '%s' using write due lack of space.\n", split->path); @@ -904,13 +907,15 @@ int parity_read(struct snapraid_parity_handle* handle, block_off_t pos, unsigned /* LCOV_EXCL_STOP */ } - count = 0; - errno = 0; - do { - bw_limit(handle->bw, block_size - count); + bw_limit(handle->bw, block_size); + count = 0; + do { read_ret = pread(split->f, block_buffer + count, block_size - count, offset + count); if (read_ret == -1) { + if (errno == EINTR) + continue; + /* LCOV_EXCL_START */ log_error(errno, "Error reading parity file '%s' at offset %" PRIu64 " for size %u. %s.\n", split->path, offset + count, block_size - count, strerror(errno)); return -1; @@ -918,8 +923,7 @@ int parity_read(struct snapraid_parity_handle* handle, block_off_t pos, unsigned } if (read_ret == 0) { /* LCOV_EXCL_START */ - if (errno == 0) - errno = ENXIO; + errno = ENXIO; log_error(errno, "Unexpected end of parity file '%s' at offset %" PRIu64 ". %s.\n", split->path, offset, strerror(errno)); return -1; /* LCOV_EXCL_STOP */ diff --git a/cmdline/stream.c b/cmdline/stream.c index eabdd15a..3d8e82fb 100644 --- a/cmdline/stream.c +++ b/cmdline/stream.c @@ -309,6 +309,7 @@ int sflush(STREAM* s) { ssize_t ret; ssize_t size; + ssize_t count; unsigned i; if (s->state != STREAM_STATE_WRITE) { @@ -322,15 +323,32 @@ int sflush(STREAM* s) return 0; for (i = 0; i < s->handle_size; ++i) { - ret = write(s->handle[i].f, s->buffer, size); + count = 0; + do { + ret = write(s->handle[i].f, s->buffer + count, size - count); - if (ret != size) { - /* LCOV_EXCL_START */ - s->state = STREAM_STATE_ERROR; - s->state_index = i; - return EOF; - /* LCOV_EXCL_STOP */ - } + if (ret < 0) { + if (errno == EINTR) + continue; + + /* LCOV_EXCL_START */ + s->state = STREAM_STATE_ERROR; + s->state_index = i; + return EOF; + /* LCOV_EXCL_STOP */ + } + + if (ret == 0) { + /* LCOV_EXCL_START */ + errno = EIO; + s->state = STREAM_STATE_ERROR; + s->state_index = i; + return EOF; + /* LCOV_EXCL_STOP */ + } + + count += ret; + } while (count < size); } /*