mirror of
https://github.com/amadvance/snapraid.git
synced 2026-10-26 02:49:02 -04:00
Adds a new file_mode setting to control the access flags.
This commit is contained in:
parent
6d4d75ad0b
commit
d1d4abaf31
10 changed files with 53 additions and 29 deletions
|
|
@ -773,7 +773,7 @@ static int state_check_process(struct snapraid_state* state, int fix, struct sna
|
|||
/* if fixing, and the file is not excluded, we must open for writing */
|
||||
if (fix && !file_flag_has(block_file_get(block), FILE_IS_EXCLUDED)) {
|
||||
/* if fixing, create the file, open for writing and resize if required */
|
||||
ret = handle_create(&handle[j], block_file_get(block), state->opt.skip_sequential);
|
||||
ret = handle_create(&handle[j], block_file_get(block), state->file_mode);
|
||||
if (ret == -1) {
|
||||
/* LCOV_EXCL_START */
|
||||
if (errno == EACCES) {
|
||||
|
|
@ -806,7 +806,7 @@ static int state_check_process(struct snapraid_state* state, int fix, struct sna
|
|||
}
|
||||
} else {
|
||||
/* if checking or hashing, open the file only for reading */
|
||||
ret = handle_open(&handle[j], block_file_get(block), state->opt.skip_sequential, stdlog);
|
||||
ret = handle_open(&handle[j], block_file_get(block), state->file_mode, stdlog);
|
||||
if (ret == -1) {
|
||||
/* save the failed block for the check/fix */
|
||||
failed[failed_count].is_bad = 1;
|
||||
|
|
@ -1802,7 +1802,7 @@ int state_check(struct snapraid_state* state, int fix, block_off_t blockstart, b
|
|||
/* if it fails, we cannot continue */
|
||||
for(l=0;l<state->level;++l) {
|
||||
parity_ptr[l] = &parity[l];
|
||||
ret = parity_create(parity_ptr[l], state->parity_path[l], &out_size, state->opt.skip_sequential);
|
||||
ret = parity_create(parity_ptr[l], state->parity_path[l], &out_size, state->file_mode);
|
||||
if (ret == -1) {
|
||||
/* LCOV_EXCL_START */
|
||||
fprintf(stderr, "WARNING! Without an accessible %s file, it isn't possible to fix any error.\n", lev_name(l));
|
||||
|
|
@ -1823,7 +1823,7 @@ int state_check(struct snapraid_state* state, int fix, block_off_t blockstart, b
|
|||
/* it may fail if the file doesn't exist, in this case we continue to check the files */
|
||||
for(l=0;l<state->level;++l) {
|
||||
parity_ptr[l] = &parity[l];
|
||||
ret = parity_open(parity_ptr[l], state->parity_path[l], state->opt.skip_sequential);
|
||||
ret = parity_open(parity_ptr[l], state->parity_path[l], state->file_mode);
|
||||
if (ret == -1) {
|
||||
printf("No accessible %s file, only files will be checked.\n", lev_name(l));
|
||||
/* continue anyway */
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ static int state_dry_process(struct snapraid_state* state, struct snapraid_parit
|
|||
}
|
||||
|
||||
/* open the file only for reading */
|
||||
ret = handle_open(&handle[j], block_file_get(block), state->opt.skip_sequential, stdlog);
|
||||
ret = handle_open(&handle[j], block_file_get(block), state->file_mode, stdlog);
|
||||
if (ret == -1) {
|
||||
/* LCOV_EXCL_START */
|
||||
fprintf(stderr, "DANGER! Unexpected open error in a data disk, it isn't possible to dry.\n");
|
||||
|
|
@ -182,7 +182,7 @@ void state_dry(struct snapraid_state* state, block_off_t blockstart, block_off_t
|
|||
/* it may fail if the file doesn't exist, in this case we continue to dry the files */
|
||||
for(l=0;l<state->level;++l) {
|
||||
parity_ptr[l] = &parity[l];
|
||||
ret = parity_open(parity_ptr[l], state->parity_path[l], state->opt.skip_sequential);
|
||||
ret = parity_open(parity_ptr[l], state->parity_path[l], state->file_mode);
|
||||
if (ret == -1) {
|
||||
printf("No accessible %s file.\n", lev_name(l));
|
||||
/* continue anyway */
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@
|
|||
/****************************************************************************/
|
||||
/* handle */
|
||||
|
||||
int handle_create(struct snapraid_handle* handle, struct snapraid_file* file, int skip_sequential)
|
||||
int handle_create(struct snapraid_handle* handle, struct snapraid_file* file, int mode)
|
||||
{
|
||||
int ret;
|
||||
int flags;
|
||||
|
|
@ -51,9 +51,12 @@ int handle_create(struct snapraid_handle* handle, struct snapraid_file* file, in
|
|||
/* O_BINARY: open as binary file (Windows only) */
|
||||
/* O_NOFOLLOW: do not follow links to ensure to open the real file */
|
||||
/* O_SEQUENTIAL: improve performance for sequential access (Windows only) */
|
||||
/* O_DIRECT: required by libaio */
|
||||
flags = O_BINARY | O_NOFOLLOW;
|
||||
if (!skip_sequential)
|
||||
if ((mode & MODE_SEQUENTIAL) != 0)
|
||||
flags |= O_SEQUENTIAL;
|
||||
if ((mode & MODE_DIRECT) != 0)
|
||||
flags |= O_DIRECT;
|
||||
|
||||
/* open for read write */
|
||||
handle->f = open(handle->path, flags | O_RDWR);
|
||||
|
|
@ -135,8 +138,8 @@ int handle_create(struct snapraid_handle* handle, struct snapraid_file* file, in
|
|||
}
|
||||
|
||||
#if HAVE_POSIX_FADVISE
|
||||
if (!skip_sequential) {
|
||||
/* advise sequential access */
|
||||
if ((mode & MODE_SEQUENTIAL) != 0) {
|
||||
/* advise sequential access */
|
||||
ret = posix_fadvise(handle->f, 0, 0, POSIX_FADV_SEQUENTIAL);
|
||||
if (ret != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
|
|
@ -150,7 +153,7 @@ int handle_create(struct snapraid_handle* handle, struct snapraid_file* file, in
|
|||
return 0;
|
||||
}
|
||||
|
||||
int handle_open(struct snapraid_handle* handle, struct snapraid_file* file, int skip_sequential, FILE* out)
|
||||
int handle_open(struct snapraid_handle* handle, struct snapraid_file* file, int mode, FILE* out)
|
||||
{
|
||||
int ret;
|
||||
int flags;
|
||||
|
|
@ -170,9 +173,12 @@ int handle_open(struct snapraid_handle* handle, struct snapraid_file* file, int
|
|||
/* O_BINARY: open as binary file (Windows only) */
|
||||
/* O_NOFOLLOW: do not follow links to ensure to open the real file */
|
||||
/* O_SEQUENTIAL: improve performance for sequential access (Windows only) */
|
||||
/* O_DIRECT: required by libaio */
|
||||
flags = O_BINARY | O_NOFOLLOW;
|
||||
if (!skip_sequential)
|
||||
if ((mode & MODE_SEQUENTIAL) != 0)
|
||||
flags |= O_SEQUENTIAL;
|
||||
if ((mode & MODE_DIRECT) != 0)
|
||||
flags |= O_DIRECT;
|
||||
|
||||
/* open for read */
|
||||
handle->f = open_noatime(handle->path, flags | O_RDONLY);
|
||||
|
|
@ -202,7 +208,7 @@ int handle_open(struct snapraid_handle* handle, struct snapraid_file* file, int
|
|||
handle->valid_size = handle->st.st_size;
|
||||
|
||||
#if HAVE_POSIX_FADVISE
|
||||
if (!skip_sequential) {
|
||||
if ((mode & MODE_SEQUENTIAL) != 0) {
|
||||
/* advise sequential access */
|
||||
ret = posix_fadvise(handle->f, 0, 0, POSIX_FADV_SEQUENTIAL);
|
||||
if (ret != 0) {
|
||||
|
|
|
|||
|
|
@ -44,13 +44,13 @@ struct snapraid_handle {
|
|||
* If the file cannot be opened for write access, it's opened with read-only access.
|
||||
* The read-only access works only if the file has already the correct size and doesn't need to be modified.
|
||||
*/
|
||||
int handle_create(struct snapraid_handle* handle, struct snapraid_file* file, int skip_sequential);
|
||||
int handle_create(struct snapraid_handle* handle, struct snapraid_file* file, int mode);
|
||||
|
||||
/**
|
||||
* Opens a file.
|
||||
* The file is opened for reading.
|
||||
*/
|
||||
int handle_open(struct snapraid_handle* handle, struct snapraid_file* file, int skip_sequential, FILE* out);
|
||||
int handle_open(struct snapraid_handle* handle, struct snapraid_file* file, int mode, FILE* out);
|
||||
|
||||
/**
|
||||
* Closes a file.
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ static void import_file(struct snapraid_state* state, const char* path, uint64_t
|
|||
/* open for read */
|
||||
/* O_SEQUENTIAL: opening in sequential mode in Windows */
|
||||
flags = O_RDONLY | O_BINARY;
|
||||
if (!state->opt.skip_sequential)
|
||||
if ((state->file_mode & MODE_SEQUENTIAL) != 0)
|
||||
flags |= O_SEQUENTIAL;
|
||||
f = open(path, flags);
|
||||
if (f == -1) {
|
||||
|
|
@ -81,7 +81,7 @@ static void import_file(struct snapraid_state* state, const char* path, uint64_t
|
|||
}
|
||||
|
||||
#if HAVE_POSIX_FADVISE
|
||||
if (!state->opt.skip_sequential) {
|
||||
if ((state->file_mode & MODE_SEQUENTIAL) != 0) {
|
||||
/* advise sequential access */
|
||||
ret = posix_fadvise(f, 0, 0, POSIX_FADV_SEQUENTIAL);
|
||||
if (ret != 0) {
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
#include "elem.h"
|
||||
#include "state.h"
|
||||
#include "parity.h"
|
||||
#include "handle.h"
|
||||
|
||||
/****************************************************************************/
|
||||
/* parity */
|
||||
|
|
@ -88,7 +89,7 @@ void parity_overflow(struct snapraid_state* state, data_off_t size)
|
|||
}
|
||||
}
|
||||
|
||||
int parity_create(struct snapraid_parity* parity, const char* path, data_off_t* out_size, int skip_sequential)
|
||||
int parity_create(struct snapraid_parity* parity, const char* path, data_off_t* out_size, int mode)
|
||||
{
|
||||
int ret;
|
||||
int flags;
|
||||
|
|
@ -98,8 +99,10 @@ int parity_create(struct snapraid_parity* parity, const char* path, data_off_t*
|
|||
/* opening in sequential mode in Windows */
|
||||
/* O_SEQUENTIAL: opening in sequential mode in Windows */
|
||||
flags = O_RDWR | O_CREAT | O_BINARY | O_SEQUENTIAL;
|
||||
if (!skip_sequential)
|
||||
if ((mode & MODE_SEQUENTIAL) != 0)
|
||||
flags |= O_SEQUENTIAL;
|
||||
if ((mode & MODE_DIRECT) != 0)
|
||||
flags |= O_DIRECT;
|
||||
parity->f = open(parity->path, flags, 0600);
|
||||
if (parity->f == -1) {
|
||||
/* LCOV_EXCL_START */
|
||||
|
|
@ -118,7 +121,7 @@ int parity_create(struct snapraid_parity* parity, const char* path, data_off_t*
|
|||
}
|
||||
|
||||
#if HAVE_POSIX_FADVISE
|
||||
if (!skip_sequential) {
|
||||
if ((mode & MODE_SEQUENTIAL) != 0) {
|
||||
/* advise sequential access */
|
||||
ret = posix_fadvise(parity->f, 0, 0, POSIX_FADV_SEQUENTIAL);
|
||||
if (ret != 0) {
|
||||
|
|
@ -262,7 +265,7 @@ bail:
|
|||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
int parity_open(struct snapraid_parity* parity, const char* path, int skip_sequential)
|
||||
int parity_open(struct snapraid_parity* parity, const char* path, int mode)
|
||||
{
|
||||
int ret;
|
||||
int flags;
|
||||
|
|
@ -273,8 +276,10 @@ int parity_open(struct snapraid_parity* parity, const char* path, int skip_seque
|
|||
/* O_SEQUENTIAL: opening in sequential mode in Windows */
|
||||
/* O_NOATIME: do not change access time */
|
||||
flags = O_RDONLY | O_BINARY;
|
||||
if (!skip_sequential)
|
||||
if ((mode & MODE_SEQUENTIAL) != 0)
|
||||
flags |= O_SEQUENTIAL;
|
||||
if ((mode & MODE_DIRECT) != 0)
|
||||
flags |= O_DIRECT;
|
||||
parity->f = open_noatime(parity->path, flags);
|
||||
if (parity->f == -1) {
|
||||
fprintf(stderr, "Error opening parity file '%s'. %s.\n", parity->path, strerror(errno));
|
||||
|
|
@ -294,7 +299,7 @@ int parity_open(struct snapraid_parity* parity, const char* path, int skip_seque
|
|||
parity->valid_size = parity->st.st_size;
|
||||
|
||||
#if HAVE_POSIX_FADVISE
|
||||
if (!skip_sequential) {
|
||||
if ((mode & MODE_SEQUENTIAL) != 0) {
|
||||
/* advise sequential access */
|
||||
ret = posix_fadvise(parity->f, 0, 0, POSIX_FADV_SEQUENTIAL);
|
||||
if (ret != 0) {
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ void parity_overflow(struct snapraid_state* state, data_off_t size);
|
|||
* Creates the parity file.
|
||||
* \param out_size Return the size of the parity file.
|
||||
*/
|
||||
int parity_create(struct snapraid_parity* parity, const char* path, data_off_t* out_size, int skip_sequential);
|
||||
int parity_create(struct snapraid_parity* parity, const char* path, data_off_t* out_size, int mode);
|
||||
|
||||
/**
|
||||
* Changes the parity size.
|
||||
|
|
@ -53,7 +53,7 @@ int parity_chsize(struct snapraid_parity* parity, data_off_t size, data_off_t* o
|
|||
/**
|
||||
* Opens an already existing parity file.
|
||||
*/
|
||||
int parity_open(struct snapraid_parity* parity, const char* path, int skip_sequential);
|
||||
int parity_open(struct snapraid_parity* parity, const char* path, int mode);
|
||||
|
||||
/**
|
||||
* Flushes the parity file in the disk.
|
||||
|
|
|
|||
|
|
@ -81,6 +81,7 @@ void state_init(struct snapraid_state* state)
|
|||
state->checked_read = 0;
|
||||
state->block_size = 256 * 1024; /* default 256 KiB */
|
||||
state->raid_mode = RAID_MODE_CAUCHY;
|
||||
state->file_mode = MODE_SEQUENTIAL;
|
||||
for(l=0;l<LEV_MAX;++l) {
|
||||
state->parity_path[l][0] = 0;
|
||||
state->parity_device[l] = 0;
|
||||
|
|
@ -368,7 +369,12 @@ void state_config(struct snapraid_state* state, const char* path, const char* co
|
|||
/* if unsed, sort by physical order */
|
||||
if (!state->opt.force_order)
|
||||
state->opt.force_order = SORT_PHYSICAL;
|
||||
|
||||
|
||||
/* adjust file mode */
|
||||
if (state->opt.skip_sequential)
|
||||
state->file_mode &= ~MODE_SEQUENTIAL;
|
||||
|
||||
/* store current command */
|
||||
state->command = command;
|
||||
|
||||
fprintf(stdlog, "conf:%s\n", path);
|
||||
|
|
|
|||
|
|
@ -41,6 +41,12 @@ const char* lev_config_name(unsigned level);
|
|||
/****************************************************************************/
|
||||
/* state */
|
||||
|
||||
/**
|
||||
* File modes.
|
||||
*/
|
||||
#define MODE_SEQUENTIAL 1
|
||||
#define MODE_DIRECT 2
|
||||
|
||||
/**
|
||||
* Global variable to identify if Ctrl+C is pressed.
|
||||
*/
|
||||
|
|
@ -95,6 +101,7 @@ struct snapraid_state {
|
|||
int checked_read; /**< If the state was read and checked. */
|
||||
uint32_t block_size; /**< Block size in bytes. */
|
||||
unsigned raid_mode; /**< Raid mode to use. RAID_MODE_DEFAULT or RAID_MODE_ALTERNATE. */
|
||||
int file_mode; /**< File access mode. Combination of MODE_* flags. */
|
||||
char parity_path[LEV_MAX][PATH_MAX]; /**< Path of the parity file. One for each parity. */
|
||||
uint64_t parity_device[LEV_MAX]; /**< Device identifier of the parity. One for each parity. */
|
||||
char share[PATH_MAX]; /**< Path of the share tree. If !=0 pool links are created in a different way. */
|
||||
|
|
|
|||
|
|
@ -138,7 +138,7 @@ static int state_hash_process(struct snapraid_state* state, block_off_t blocksta
|
|||
}
|
||||
}
|
||||
|
||||
ret = handle_open(&handle[j], block_file_get(block), state->opt.skip_sequential, stderr);
|
||||
ret = handle_open(&handle[j], block_file_get(block), state->file_mode, stderr);
|
||||
if (ret == -1) {
|
||||
/* file we are processing for error reporting */
|
||||
struct snapraid_file* file = block_file_get(block);
|
||||
|
|
@ -562,7 +562,7 @@ static int state_sync_process(struct snapraid_state* state, struct snapraid_pari
|
|||
}
|
||||
}
|
||||
|
||||
ret = handle_open(&handle[j], block_file_get(block), state->opt.skip_sequential, stderr);
|
||||
ret = handle_open(&handle[j], block_file_get(block), state->file_mode, stderr);
|
||||
if (ret == -1) {
|
||||
/* file we are processing for error reporting */
|
||||
struct snapraid_file* file = block_file_get(block);
|
||||
|
|
@ -1050,7 +1050,7 @@ int state_sync(struct snapraid_state* state, block_off_t blockstart, block_off_t
|
|||
for(l=0;l<level;++l) {
|
||||
/* create the file and open for writing */
|
||||
parity_ptr[l] = &parity[l];
|
||||
ret = parity_create(parity_ptr[l], state->parity_path[l], &out_size, state->opt.skip_sequential);
|
||||
ret = parity_create(parity_ptr[l], state->parity_path[l], &out_size, state->file_mode);
|
||||
if (ret == -1) {
|
||||
/* LCOV_EXCL_START */
|
||||
fprintf(stderr, "WARNING! Without an accessible %s file, it isn't possible to sync.\n", lev_name(l));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue