mirror of
https://github.com/amadvance/snapraid.git
synced 2026-10-26 19:01:57 -04:00
Handle short writes and EINTR in sflush, handle_write, and parity_write
This commit is contained in:
parent
712b54ec98
commit
091e44afed
3 changed files with 50 additions and 24 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue