mirror of
https://github.com/amadvance/snapraid.git
synced 2026-10-26 02:49:02 -04:00
Improve parity fixing speed
This commit is contained in:
parent
19c75877f1
commit
a873eee208
4 changed files with 49 additions and 2 deletions
4
HISTORY
4
HISTORY
|
|
@ -1,8 +1,10 @@
|
|||
SnapRAID HISTORY
|
||||
================
|
||||
|
||||
11.4 2018/12
|
||||
11.4 2019/05
|
||||
============
|
||||
* Avoid unnecessary parity read when fixing the parity itself.
|
||||
This improves the 'fix' speed when a parity file is completely missing.
|
||||
* Removed a build warning about major/minor defined now in sys/sysmacros.h.
|
||||
|
||||
11.3 2018/11
|
||||
|
|
|
|||
|
|
@ -184,6 +184,7 @@ int parity_create(struct snapraid_parity_handle* handle, const struct snapraid_p
|
|||
|
||||
handle->level = level;
|
||||
handle->split_mac = 0;
|
||||
handle->has_write_access = 0;
|
||||
|
||||
for (s = 0; s < parity->split_mac; ++s) {
|
||||
struct snapraid_split_handle* split = &handle->split_map[s];
|
||||
|
|
@ -217,6 +218,9 @@ int parity_create(struct snapraid_parity_handle* handle, const struct snapraid_p
|
|||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
/* the initial valid size is the size on disk */
|
||||
split->valid_size = split->st.st_size;
|
||||
|
||||
/**
|
||||
* If the parity size is not yet set, set it now.
|
||||
* This happens when expanding the number of parities,
|
||||
|
|
@ -528,6 +532,10 @@ static int parity_handle_chsize(struct snapraid_split_handle* split, data_off_t
|
|||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
/* if we shrink, update the valid size, but don't update when growing */
|
||||
if (split->valid_size > split->st.st_size)
|
||||
split->valid_size = split->st.st_size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -659,6 +667,7 @@ int parity_open(struct snapraid_parity_handle* handle, const struct snapraid_par
|
|||
|
||||
handle->level = level;
|
||||
handle->split_mac = 0;
|
||||
handle->has_write_access = 0;
|
||||
|
||||
/* mask of bits used by the block size */
|
||||
block_mask = ((data_off_t)block_size) - 1;
|
||||
|
|
@ -697,6 +706,9 @@ int parity_open(struct snapraid_parity_handle* handle, const struct snapraid_par
|
|||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
/* the initial valid size is the size on disk */
|
||||
split->valid_size = split->st.st_size;
|
||||
|
||||
/**
|
||||
* If the parity size is not yet set, set it now.
|
||||
* This happens when expanding the number of parities,
|
||||
|
|
@ -770,6 +782,19 @@ int parity_close(struct snapraid_parity_handle* handle)
|
|||
struct snapraid_split_handle* split = &handle->split_map[s];
|
||||
int ret;
|
||||
|
||||
if (handle->has_write_access) {
|
||||
/* truncate any data that we know it's not valid */
|
||||
ret = ftruncate(split->f, split->valid_size);
|
||||
if (ret != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error truncating the parity file '%s' to size %" PRIu64 ". %s.\n", split->path, split->valid_size, strerror(errno));
|
||||
f_ret = -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
|
||||
/* continue to close the others */
|
||||
}
|
||||
}
|
||||
|
||||
ret = close(split->f);
|
||||
if (ret != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
|
|
@ -826,6 +851,10 @@ int parity_write(struct snapraid_parity_handle* handle, block_off_t pos, unsigne
|
|||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
/* update the valid range */
|
||||
if (split->valid_size < offset + block_size)
|
||||
split->valid_size = offset + block_size;
|
||||
|
||||
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 */
|
||||
|
|
@ -867,6 +896,14 @@ int parity_read(struct snapraid_parity_handle* handle, block_off_t pos, unsigned
|
|||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
/* if read is completely out of the valid range */
|
||||
if (offset >= split->valid_size) {
|
||||
/* LCOV_EXCL_START */
|
||||
out("Missing data reading file '%s' at offset %" PRIu64 " for size %u.\n", split->path, offset, block_size);
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
count = 0;
|
||||
do {
|
||||
read_ret = pread(split->f, block_buffer + count, block_size - count, offset + count);
|
||||
|
|
|
|||
|
|
@ -36,6 +36,13 @@ struct snapraid_split_handle {
|
|||
*/
|
||||
data_off_t size;
|
||||
|
||||
/**
|
||||
* Valid size of the parity split.
|
||||
* This is the size effectively written, and not the reult of a chsize operation.
|
||||
* It's used to make read operations failing if read over that size.
|
||||
*/
|
||||
data_off_t valid_size;
|
||||
|
||||
/**
|
||||
* Artificial size limit for testing.
|
||||
* 0 means unlimited.
|
||||
|
|
@ -47,6 +54,7 @@ struct snapraid_parity_handle {
|
|||
struct snapraid_split_handle split_map[SPLIT_MAX];
|
||||
unsigned split_mac; /**< Number of parity splits. */
|
||||
unsigned level; /**< Level of the parity. */
|
||||
int has_write_access; /**< If the parity is open for writing. */
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ void log_flush(void);
|
|||
/**
|
||||
* Pointer to log function.
|
||||
*/
|
||||
typedef void fptr(const char* format, ...);
|
||||
typedef void fptr(const char* format, ...) __attribute__((format(attribute_printf, 1, 2)));
|
||||
|
||||
/****************************************************************************/
|
||||
/* message */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue