Add a test option to skip the space holder

This commit is contained in:
Andrea Mazzoleni 2016-10-04 23:56:13 +02:00
parent 00cd931fad
commit ba0184c37c
7 changed files with 47 additions and 34 deletions

View file

@ -1,7 +1,7 @@
SnapRAID HISTORY
================
11.0 2016/09
11.0 2016/10
============
* Added support for splitting the parity in multiple partitions. You
can now specify multiple files for a single parity. As soon a file

View file

@ -1955,7 +1955,7 @@ int state_check(struct snapraid_state* state, int fix, block_off_t blockstart, b
/* LCOV_EXCL_STOP */
}
ret = parity_chsize(parity_ptr[l], &state->parity[l], 0, size, state->block_size, state->opt.skip_fallocate);
ret = parity_chsize(parity_ptr[l], &state->parity[l], 0, size, state->block_size, state->opt.skip_fallocate, state->opt.skip_space_holder);
if (ret == -1) {
/* LCOV_EXCL_START */
log_fatal("WARNING! Without an accessible %s file, it isn't possible to sync.\n", lev_name(l));

View file

@ -346,7 +346,7 @@ uint64_t hbit_u64(uint64_t v)
return 1ULL << ilog;
}
static int parity_handle_fill(struct snapraid_split_handle* split, data_off_t size, uint32_t block_size, int skip_fallocate)
static int parity_handle_fill(struct snapraid_split_handle* split, data_off_t size, uint32_t block_size, int skip_fallocate, int skip_space_holder)
{
data_off_t base;
data_off_t delta;
@ -362,38 +362,43 @@ static int parity_handle_fill(struct snapraid_split_handle* split, data_off_t si
* the disk.
*/
char spaceholder_path[PATH_MAX];
data_off_t spaceholder_size = 256 * 1024 * 1024;
int spaceholder_f;
pathprint(spaceholder_path, sizeof(spaceholder_path), "%s%s", split->path, ".spaceholder");
spaceholder_f = open(spaceholder_path, O_RDWR | O_CREAT | O_TRUNC | O_BINARY, 0600);
if (spaceholder_f == -1) {
log_fatal("Failed to create space holder file '%s'.\n", spaceholder_path);
return -1;
}
if (!skip_space_holder) {
data_off_t spaceholder_size = 256 * 1024 * 1024;
int spaceholder_f;
/* note that in Windows ftruncate is really allocating space */
if (ftruncate(spaceholder_f, spaceholder_size) != 0) {
log_fatal("WARNING Failed to resize the space holder file '%s' to %llu bytes.\n", spaceholder_path, spaceholder_size);
log_fatal("Assuming that no more space is available.\n");
close(spaceholder_f);
remove(spaceholder_path);
return 0;
}
spaceholder_f = open(spaceholder_path, O_RDWR | O_CREAT | O_TRUNC | O_BINARY, 0600);
if (spaceholder_f == -1) {
log_fatal("Failed to create space holder file '%s'.\n", spaceholder_path);
return -1;
}
if (fsync(spaceholder_f) != 0) {
log_fatal("Failed to sync the space holder file '%s'.\n", spaceholder_path);
close(spaceholder_f);
remove(spaceholder_path);
return -1;
}
/* note that in Windows ftruncate is really allocating space */
if (ftruncate(spaceholder_f, spaceholder_size) != 0) {
log_fatal("WARNING Failed to resize the space holder file '%s' to %llu bytes.\n", spaceholder_path, spaceholder_size);
log_fatal("Assuming that no more space is available.\n");
close(spaceholder_f);
remove(spaceholder_path);
return 0;
}
if (close(spaceholder_f) != 0) {
log_fatal("Failed to close the space holder file '%s'.\n", spaceholder_path);
remove(spaceholder_path);
return -1;
if (fsync(spaceholder_f) != 0) {
log_fatal("Failed to sync the space holder file '%s'.\n", spaceholder_path);
close(spaceholder_f);
remove(spaceholder_path);
return -1;
}
if (close(spaceholder_f) != 0) {
log_fatal("Failed to close the space holder file '%s'.\n", spaceholder_path);
remove(spaceholder_path);
return -1;
}
}
#else
(void)skip_space_holder;
#endif
/* mask of bits used by the block size */
@ -451,7 +456,7 @@ static int parity_handle_fill(struct snapraid_split_handle* split, data_off_t si
return parity_handle_shrink(split, base);
}
static int parity_handle_chsize(struct snapraid_split_handle* split, data_off_t size, uint32_t block_size, int skip_fallocate)
static int parity_handle_chsize(struct snapraid_split_handle* split, data_off_t size, uint32_t block_size, int skip_fallocate, int skip_space_holder)
{
int ret;
int f_ret;
@ -459,7 +464,7 @@ static int parity_handle_chsize(struct snapraid_split_handle* split, data_off_t
int f_dir;
if (split->st.st_size < size) {
f_ret = parity_handle_fill(split, size, block_size, skip_fallocate);
f_ret = parity_handle_fill(split, size, block_size, skip_fallocate, skip_space_holder);
f_errno = errno;
f_dir = 1;
} else if (split->st.st_size > size) {
@ -516,7 +521,7 @@ static int parity_split_is_fixed(struct snapraid_parity_handle* handle, unsigned
return 1;
}
int parity_chsize(struct snapraid_parity_handle* handle, struct snapraid_parity* parity, int* is_modified, data_off_t size, uint32_t block_size, int skip_fallocate)
int parity_chsize(struct snapraid_parity_handle* handle, struct snapraid_parity* parity, int* is_modified, data_off_t size, uint32_t block_size, int skip_fallocate, int skip_space_holder)
{
int ret;
unsigned s;
@ -557,7 +562,7 @@ int parity_chsize(struct snapraid_parity_handle* handle, struct snapraid_parity*
run = size;
}
ret = parity_handle_chsize(split, run, block_size, skip_fallocate);
ret = parity_handle_chsize(split, run, block_size, skip_fallocate, skip_space_holder);
if (ret != 0)
return -1;

View file

@ -94,7 +94,7 @@ int parity_create(struct snapraid_parity_handle* handle, const struct snapraid_p
* Change the parity size.
* \param out_size Return the size of the parity file. The out_size is set also on error to reflect a partial resize.
*/
int parity_chsize(struct snapraid_parity_handle* handle, struct snapraid_parity* parity, int* is_modified, data_off_t size, uint32_t block_size, int skip_fallocate);
int parity_chsize(struct snapraid_parity_handle* handle, struct snapraid_parity* parity, int* is_modified, data_off_t size, uint32_t block_size, int skip_fallocate, int skip_space_holder);
/**
* Get the size of the parity.

View file

@ -292,6 +292,7 @@ void config(char* conf, size_t conf_size, const char* argv0)
#define OPT_TEST_IO_ADVISE_DIRECT 299
#define OPT_TEST_PARITY_LIMIT 301
#define OPT_TEST_SKIP_CONTENT_WRITE 302
#define OPT_TEST_SKIP_SPACE_HOLDER 303
#if HAVE_GETOPT_LONG
struct option long_options[] = {
@ -453,6 +454,9 @@ struct option long_options[] = {
/* Skip content write */
{ "test-skip-content-write", 0, 0, OPT_TEST_SKIP_CONTENT_WRITE },
/* Skip space holder file in parity disks */
{ "test-skip-space-holder", 0, 0, OPT_TEST_SKIP_SPACE_HOLDER },
{ 0, 0, 0, 0 }
};
#endif
@ -879,6 +883,9 @@ int main(int argc, char* argv[])
case OPT_TEST_SKIP_CONTENT_WRITE :
opt.skip_content_write = 1;
break;
case OPT_TEST_SKIP_SPACE_HOLDER :
opt.skip_space_holder = 1;
break;
default :
/* LCOV_EXCL_START */
log_fatal("Unknown option '%c'\n", (char)c);

View file

@ -89,6 +89,7 @@ struct snapraid_option {
int skip_device; /**< Skip devices matching checks. */
int skip_sign; /**< Skip the sign check for content files. */
int skip_fallocate; /**< Skip the use of fallocate(). */
int skip_space_holder; /**< Skip the use of spaceholder file. */
int file_mode; /**< File mode. Mask of ADVISE_* flags. */
int skip_lock; /**< Skip the lock file protection. */
int skip_self; /**< Skip the self-test. */

View file

@ -1514,7 +1514,7 @@ int state_sync(struct snapraid_state* state, block_off_t blockstart, block_off_t
/* change the size of the parity file, truncating or extending it */
/* from this point all the DELETED blocks after the end of the parity are invalid */
/* and they are automatically removed when we save the new content file */
ret = parity_chsize(&parity_handle[l], &state->parity[l], &is_modified, size, state->block_size, state->opt.skip_fallocate);
ret = parity_chsize(&parity_handle[l], &state->parity[l], &is_modified, size, state->block_size, state->opt.skip_fallocate, state->opt.skip_space_holder);
if (ret == -1) {
/* LCOV_EXCL_START */
data_off_t out_size;