mirror of
https://github.com/amadvance/snapraid.git
synced 2026-10-26 02:49:02 -04:00
Add support for short writes to files. It should not happen, but just to be sure.
This commit is contained in:
parent
caf9cd3961
commit
e743e23555
2 changed files with 48 additions and 23 deletions
|
|
@ -269,19 +269,20 @@ int handle_read(struct snapraid_handle* handle, block_off_t file_pos, unsigned c
|
|||
do {
|
||||
bw_limit(handle->bw, block_size - count);
|
||||
|
||||
/* read the full block to support O_DIRECT */
|
||||
read_ret = pread(handle->f, block_buffer + count, block_size - count, offset + count);
|
||||
if (read_ret < 0) {
|
||||
if (read_ret == -1) {
|
||||
/* LCOV_EXCL_START */
|
||||
out("Error reading file '%s' at offset %" PRIu64 " for size %u. %s.\n", handle->path, offset + count, block_size - count, strerror(errno));
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
if (read_ret == 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
out("Unexpected end of file '%s' at offset %" PRIu64 ". %s.\n", handle->path, offset, strerror(errno));
|
||||
if (errno == 0)
|
||||
errno = ENXIO;
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
count += read_ret;
|
||||
|
|
@ -308,21 +309,34 @@ int handle_write(struct snapraid_handle* handle, block_off_t file_pos, unsigned
|
|||
ssize_t write_ret;
|
||||
data_off_t offset;
|
||||
unsigned write_size;
|
||||
unsigned count;
|
||||
int ret;
|
||||
|
||||
offset = file_pos * (data_off_t)block_size;
|
||||
|
||||
write_size = file_block_size(handle->file, file_pos, block_size);
|
||||
|
||||
write_ret = pwrite(handle->f, block_buffer, write_size, offset);
|
||||
if (write_ret != (ssize_t)write_size) { /* conversion is safe because block_size is always small */
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error writing file '%s'. %s.\n", handle->path, strerror(errno));
|
||||
if (errno == 0)
|
||||
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) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error writing file '%s'. %s.\n", handle->path, strerror(errno));
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
if (write_ret == 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Unexpected 0 write to file '%s'. %s.\n", handle->path, strerror(errno));
|
||||
errno = ENXIO;
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
count += write_ret;
|
||||
} while (count < write_size);
|
||||
|
||||
/* adjust the size of the valid data */
|
||||
if (handle->valid_size < offset + write_size) {
|
||||
|
|
|
|||
|
|
@ -855,6 +855,7 @@ int parity_write(struct snapraid_parity_handle* handle, block_off_t pos, unsigne
|
|||
ssize_t write_ret;
|
||||
data_off_t offset;
|
||||
struct snapraid_split_handle* split;
|
||||
unsigned count;
|
||||
int ret;
|
||||
|
||||
offset = pos * (data_off_t)block_size;
|
||||
|
|
@ -871,21 +872,31 @@ 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, block_size, offset);
|
||||
if (write_ret != (ssize_t)block_size) { /* conversion is safe because block_size is always small */
|
||||
/* LCOV_EXCL_START */
|
||||
if (errno == ENOSPC) {
|
||||
log_fatal("Failed to grow parity file '%s' using write due lack of space.\n", split->path);
|
||||
} else {
|
||||
log_fatal("Error writing parity file '%s'. %s.\n", split->path, strerror(errno));
|
||||
write_ret = pwrite(split->f, block_buffer + count, block_size - count, offset + count);
|
||||
if (write_ret == -1) {
|
||||
/* LCOV_EXCL_START */
|
||||
if (errno == ENOSPC) {
|
||||
log_fatal("Failed to grow parity file '%s' using write due lack of space.\n", split->path);
|
||||
} else {
|
||||
log_fatal("Error writing parity file '%s'. %s.\n", split->path, strerror(errno));
|
||||
}
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
if (errno == 0)
|
||||
if (write_ret == 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Unexpected 0 write to file '%s'. %s.\n", split->path, strerror(errno));
|
||||
errno = ENXIO;
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
count += write_ret;
|
||||
} while (count < block_size);
|
||||
|
||||
ret = advise_write(&split->advise, split->f, offset, block_size);
|
||||
if (ret != 0) {
|
||||
|
|
@ -930,7 +941,7 @@ int parity_read(struct snapraid_parity_handle* handle, block_off_t pos, unsigned
|
|||
bw_limit(handle->bw, block_size - count);
|
||||
|
||||
read_ret = pread(split->f, block_buffer + count, block_size - count, offset + count);
|
||||
if (read_ret < 0) {
|
||||
if (read_ret == -1) {
|
||||
/* LCOV_EXCL_START */
|
||||
out("Error reading parity file '%s' at offset %" PRIu64 " for size %u. %s.\n", split->path, offset + count, block_size - count, strerror(errno));
|
||||
return -1;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue