Propagate final writeback errors from advise_close

This commit is contained in:
Andrea Mazzoleni 2026-09-09 16:00:33 +02:00
parent 4a616558ec
commit 2b784748e3
5 changed files with 74 additions and 16 deletions

View file

@ -329,21 +329,29 @@ int handle_open(struct snapraid_handle* handle, struct snapraid_file* file, int
int handle_close(struct snapraid_handle* handle)
{
int ret;
int f_ret = 0;
int f_errno = 0;
/* close if open */
if (handle->f != -1) {
advise_close(&handle->advise, handle->f);
int ret = advise_close(&handle->advise, handle->f);
if (ret != 0) {
/* LCOV_EXCL_START */
f_ret = -1;
f_errno = errno;
log_fatal(errno, "Error advising file '%s'. %s.\n", handle->path, strerror(errno));
/* LCOV_EXCL_STOP */
}
ret = close(handle->f);
if (ret != 0) {
/* LCOV_EXCL_START */
if (f_ret == 0) {
f_ret = -1;
f_errno = errno;
}
log_fatal(errno, "Error closing file '%s'. %s.\n", handle->path, strerror(errno));
/* invalidate for error */
handle->file = 0;
handle->f = -1;
return -1;
/* LCOV_EXCL_STOP */
}
}
@ -353,7 +361,10 @@ int handle_close(struct snapraid_handle* handle)
handle->f = -1;
handle->readonly_errno = 0;
return 0;
if (f_ret != 0)
errno = f_errno;
return f_ret;
}
ssize_t handle_read(struct snapraid_handle* handle, block_off_t file_pos, unsigned char* block_buffer, unsigned block_size, log_ptr* out_missing)
@ -572,3 +583,4 @@ struct snapraid_handle* handle_mapping(struct snapraid_state* state, unsigned* h
*handlemax = size;
return handle;
}

View file

@ -47,6 +47,7 @@ static void import_file(struct snapraid_state* state, const char* path, uint64_t
ssize_t ret;
int f;
int flags;
int advise_errno;
unsigned block_size = state->block_size;
struct advise_struct advise;
block_off_t blockmax;
@ -149,9 +150,19 @@ static void import_file(struct snapraid_state* state, const char* path, uint64_t
size -= read_size;
}
advise_close(&advise, f);
ret = advise_close(&advise, f);
advise_errno = ret != 0 ? errno : 0;
ret = close(f);
if (advise_errno != 0) {
/* LCOV_EXCL_START */
errno = advise_errno;
log_fatal(errno, "Error advising file '%s'. %s.\n", path, strerror(errno));
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
if (ret != 0) {
/* LCOV_EXCL_START */
log_fatal(errno, "Error closing file '%s'. %s.\n", path, strerror(errno));

View file

@ -1001,23 +1001,35 @@ int parity_close(struct snapraid_parity_handle* handle)
{
unsigned s;
int f_ret = 0;
int f_errno = 0;
for (s = 0; s < handle->split_mac; ++s) {
struct snapraid_split_handle* split = &handle->split_map[s];
int ret;
advise_close(&split->advise, split->f);
int ret = advise_close(&split->advise, split->f);
if (ret != 0) {
/* LCOV_EXCL_START */
if (f_ret == 0) {
f_ret = -1;
f_errno = errno;
}
log_fatal(errno, "Error advising parity file '%s'. %s.\n", split->path, strerror(errno));
/* LCOV_EXCL_STOP */
}
ret = close(split->f);
if (ret != 0) {
/* LCOV_EXCL_START */
if (f_ret == 0) {
f_ret = -1;
f_errno = errno;
}
/*
* This is a serious error, as it may be the result of a failed write
* identified at later time.
* In a normal file-system (not NFS) it should never happen
*/
log_fatal(errno, "Error closing parity file '%s'. %s.\n", split->path, strerror(errno));
f_ret = -1;
/* LCOV_EXCL_STOP */
/* continue to close the others */
@ -1027,6 +1039,9 @@ int parity_close(struct snapraid_parity_handle* handle)
split->f = -1;
}
if (f_ret != 0)
errno = f_errno;
return f_ret;
}
@ -1217,3 +1232,4 @@ int parity_read(struct snapraid_parity_handle* handle, block_off_t pos, unsigned
return block_size;
}

View file

@ -1802,7 +1802,7 @@ int advise_read(struct advise_struct* advise, int f, data_off_t offset, data_off
return 0;
}
void advise_close(struct advise_struct* advise, int f)
int advise_close(struct advise_struct* advise, int f)
{
data_off_t flush_offset;
data_off_t flush_size;
@ -1835,8 +1835,15 @@ void advise_close(struct advise_struct* advise, int f)
#if HAVE_SYNC_FILE_RANGE
if (flush_size != 0) {
int ret;
/* start writing immediately */
sync_file_range(f, flush_offset, flush_size, SYNC_FILE_RANGE_WRITE);
ret = sync_file_range(f, flush_offset, flush_size, SYNC_FILE_RANGE_WRITE);
if (ret != 0) {
/* LCOV_EXCL_START */
return -1;
/* LCOV_EXCL_STOP */
}
}
#endif
@ -1848,17 +1855,29 @@ void advise_close(struct advise_struct* advise, int f)
ret = sync_file_range(f, discard_offset, discard_size, SYNC_FILE_RANGE_WAIT_BEFORE | SYNC_FILE_RANGE_WRITE | SYNC_FILE_RANGE_WAIT_AFTER);
if (ret != 0) {
/* LCOV_EXCL_START */
return;
return -1;
/* LCOV_EXCL_STOP */
}
/* flush the data from the cache */
posix_fadvise_wrapper(f, discard_offset, discard_size, POSIX_FADV_DONTNEED);
ret = posix_fadvise_wrapper(f, discard_offset, discard_size, POSIX_FADV_DONTNEED);
if (ret == ENOSYS) {
/* call is not supported */
ret = 0;
}
if (ret != 0) {
/* LCOV_EXCL_START */
errno = ret; /* posix_fadvise return the error code */
return -1;
/* LCOV_EXCL_STOP */
}
}
#endif
advise->dirty_begin = 0;
advise->dirty_end = 0;
return 0;
}
/****************************************************************************/

View file

@ -429,7 +429,7 @@ int advise_flags(struct advise_struct* advise);
int advise_open(struct advise_struct* advise, int f);
int advise_write(struct advise_struct* advise, int f, data_off_t offset, data_off_t size);
int advise_read(struct advise_struct* advise, int f, data_off_t offset, data_off_t size);
void advise_close(struct advise_struct* advise, int f);
int advise_close(struct advise_struct* advise, int f);
/****************************************************************************/
/* smartctl */