mirror of
https://github.com/amadvance/snapraid.git
synced 2026-10-26 02:49:02 -04:00
Address some portability issues
This commit is contained in:
parent
d25b55d393
commit
496971e9c9
18 changed files with 248 additions and 247 deletions
|
|
@ -3,7 +3,6 @@ check_PROGRAMS = testgen
|
|||
|
||||
snapraid_SOURCES = \
|
||||
snapraid.c \
|
||||
getopt.c \
|
||||
md5.c \
|
||||
tommy.c \
|
||||
util.c \
|
||||
|
|
@ -131,8 +130,7 @@ cachegrind:
|
|||
DISTWIN = \
|
||||
snapraid.txt \
|
||||
snapraid.html \
|
||||
snapraid.exe \
|
||||
snapraid.rc
|
||||
snapraid.exe
|
||||
|
||||
distwindows: $(DISTWIN)
|
||||
rm -f $(PACKAGE)-$(VERSION)-windows-x86.zip
|
||||
|
|
|
|||
17
check.c
17
check.c
|
|
@ -26,17 +26,17 @@
|
|||
/****************************************************************************/
|
||||
/* check */
|
||||
|
||||
static int state_check_process(int ret_on_error, struct snapraid_state* state, int fix, int parity_f, pos_t blockstart, pos_t blockmax)
|
||||
static int state_check_process(int ret_on_error, struct snapraid_state* state, int fix, int parity_f, block_off_t blockstart, block_off_t blockmax)
|
||||
{
|
||||
struct snapraid_handle* handle;
|
||||
unsigned diskmax = tommy_array_size(&state->diskarr);
|
||||
pos_t i;
|
||||
block_off_t i;
|
||||
unsigned j;
|
||||
unsigned char* block_buffer;
|
||||
unsigned char* xor_buffer;
|
||||
int ret;
|
||||
uint64_t count_size;
|
||||
uint64_t count_block;
|
||||
data_off_t count_size;
|
||||
data_off_t count_block;
|
||||
time_t start;
|
||||
time_t last;
|
||||
unsigned error;
|
||||
|
|
@ -271,11 +271,11 @@ static int state_check_process(int ret_on_error, struct snapraid_state* state, i
|
|||
return unrecoverable_error != 0 ? ret_on_error : 0;
|
||||
}
|
||||
|
||||
void state_check(struct snapraid_state* state, int fix, pos_t blockstart)
|
||||
void state_check(struct snapraid_state* state, int fix, block_off_t blockstart)
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
pos_t blockmax;
|
||||
off_t size;
|
||||
block_off_t blockmax;
|
||||
data_off_t size;
|
||||
int ret;
|
||||
int f;
|
||||
|
||||
|
|
@ -285,7 +285,7 @@ void state_check(struct snapraid_state* state, int fix, pos_t blockstart)
|
|||
printf("Checking...\n");
|
||||
|
||||
blockmax = parity_resize(state);
|
||||
size = blockmax * (off_t)state->block_size;
|
||||
size = blockmax * (data_off_t)state->block_size;
|
||||
|
||||
if (blockstart >= blockmax) {
|
||||
fprintf(stderr, "The specified starting block %u is bigger than the parity size %u.\n", blockstart, blockmax);
|
||||
|
|
@ -313,4 +313,3 @@ void state_check(struct snapraid_state* state, int fix, pos_t blockstart)
|
|||
parity_close(path, f);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
51
config.h
51
config.h
|
|
@ -11,6 +11,12 @@
|
|||
/* Define to 1 if you have the <fcntl.h> header file. */
|
||||
#define HAVE_FCNTL_H 1
|
||||
|
||||
/* Define to 1 if you have the `ferror_unlocked' function. */
|
||||
#define HAVE_FERROR_UNLOCKED 1
|
||||
|
||||
/* Define to 1 if you have the `fgetc_unlocked' function. */
|
||||
#define HAVE_FGETC_UNLOCKED 1
|
||||
|
||||
/* Define to 1 if you have the `fsync' function. */
|
||||
#define HAVE_FSYNC 1
|
||||
|
||||
|
|
@ -29,10 +35,6 @@
|
|||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#define HAVE_INTTYPES_H 1
|
||||
|
||||
/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
|
||||
to 0 otherwise. */
|
||||
#define HAVE_MALLOC 1
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#define HAVE_MEMORY_H 1
|
||||
|
||||
|
|
@ -104,6 +106,9 @@
|
|||
/* Define to 1 if you have the `vsnprintf' function. */
|
||||
#define HAVE_VSNPRINTF 1
|
||||
|
||||
/* Define to 1 if assertions should be disabled. */
|
||||
/* #undef NDEBUG */
|
||||
|
||||
/* Name of package */
|
||||
#define PACKAGE "snapraid"
|
||||
|
||||
|
|
@ -131,6 +136,28 @@
|
|||
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
|
||||
#define TIME_WITH_SYS_TIME 1
|
||||
|
||||
/* Enable extensions on AIX 3, Interix. */
|
||||
#ifndef _ALL_SOURCE
|
||||
# define _ALL_SOURCE 1
|
||||
#endif
|
||||
/* Enable GNU extensions on systems that have them. */
|
||||
#ifndef _GNU_SOURCE
|
||||
# define _GNU_SOURCE 1
|
||||
#endif
|
||||
/* Enable threading extensions on Solaris. */
|
||||
#ifndef _POSIX_PTHREAD_SEMANTICS
|
||||
# define _POSIX_PTHREAD_SEMANTICS 1
|
||||
#endif
|
||||
/* Enable extensions on HP NonStop. */
|
||||
#ifndef _TANDEM_SOURCE
|
||||
# define _TANDEM_SOURCE 1
|
||||
#endif
|
||||
/* Enable general extensions on Solaris. */
|
||||
#ifndef __EXTENSIONS__
|
||||
# define __EXTENSIONS__ 1
|
||||
#endif
|
||||
|
||||
|
||||
/* Version number of package */
|
||||
#define VERSION "0.1"
|
||||
|
||||
|
|
@ -149,12 +176,19 @@
|
|||
/* Number of bits in a file offset, on hosts where this is settable. */
|
||||
#define _FILE_OFFSET_BITS 64
|
||||
|
||||
/* Enable GLIBC symbols */
|
||||
#define _GNU_SOURCE 1
|
||||
|
||||
/* Define for large files, on AIX-style hosts. */
|
||||
/* #undef _LARGE_FILES */
|
||||
|
||||
/* Define to 1 if on MINIX. */
|
||||
/* #undef _MINIX */
|
||||
|
||||
/* Define to 2 if the system does not provide POSIX.1 features except with
|
||||
this defined. */
|
||||
/* #undef _POSIX_1_SOURCE */
|
||||
|
||||
/* Define to 1 if you need to in order for `stat' and other things to work. */
|
||||
/* #undef _POSIX_SOURCE */
|
||||
|
||||
/* Define for Solaris 2.5.1 so the uint32_t typedef from <sys/synch.h>,
|
||||
<pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
|
||||
#define below would cause a syntax error. */
|
||||
|
|
@ -179,9 +213,6 @@
|
|||
/* #undef inline */
|
||||
#endif
|
||||
|
||||
/* Define to rpl_malloc if the replacement function should be used. */
|
||||
/* #undef malloc */
|
||||
|
||||
/* Define to `long int' if <sys/types.h> does not define. */
|
||||
/* #undef off_t */
|
||||
|
||||
|
|
|
|||
12
configure.ac
12
configure.ac
|
|
@ -8,11 +8,13 @@ AC_CANONICAL_HOST
|
|||
|
||||
dnl Checks for programs.
|
||||
AC_PROG_CC
|
||||
AC_USE_SYSTEM_EXTENSIONS
|
||||
|
||||
dnl Checks for libraries.
|
||||
AC_SYS_LARGEFILE
|
||||
|
||||
dnl Checks for header files.
|
||||
AC_HEADER_ASSERT
|
||||
AC_HEADER_STDC
|
||||
AC_HEADER_DIRENT
|
||||
AC_HEADER_TIME
|
||||
|
|
@ -32,16 +34,10 @@ AC_TYPE_UINT64_T
|
|||
AC_TYPE_UINT8_T
|
||||
|
||||
dnl Checks for library functions.
|
||||
AC_FUNC_MALLOC
|
||||
AC_SYS_LARGEFILE
|
||||
AC_CHECK_FUNCS([memset strchr strerror strrchr])
|
||||
AC_CHECK_FUNCS([getopt getopt_long snprintf vsnprintf])
|
||||
AC_CHECK_FUNCS([ftruncate fsync posix_fallocate posix_fadvise pread pwrite])
|
||||
|
||||
dnl Configure for 64 bit files
|
||||
CFLAGS="$CFLAGS -D_FILE_OFFSET_BITS=64"
|
||||
|
||||
dnl Enable GLIBC symbols
|
||||
AC_DEFINE(_GNU_SOURCE,1,[Enable GLIBC symbols])
|
||||
AC_CHECK_FUNCS([ftruncate fsync posix_fallocate posix_fadvise pread pwrite fgetc_unlocked ferror_unlocked])
|
||||
|
||||
dnl Checks for architecture
|
||||
AC_C_BIGENDIAN
|
||||
|
|
|
|||
8
elem.c
8
elem.c
|
|
@ -23,7 +23,7 @@
|
|||
/****************************************************************************/
|
||||
/* snapraid */
|
||||
|
||||
pos_t block_file_pos(struct snapraid_block* block)
|
||||
block_off_t block_file_pos(struct snapraid_block* block)
|
||||
{
|
||||
struct snapraid_file* file = block->file;
|
||||
|
||||
|
|
@ -37,7 +37,7 @@ pos_t block_file_pos(struct snapraid_block* block)
|
|||
|
||||
unsigned block_file_size(struct snapraid_block* block, unsigned block_size)
|
||||
{
|
||||
pos_t pos = block_file_pos(block);
|
||||
block_off_t pos = block_file_pos(block);
|
||||
|
||||
/* if it's the last block */
|
||||
if (pos + 1 == block->file->blockmax) {
|
||||
|
|
@ -53,10 +53,10 @@ unsigned block_file_size(struct snapraid_block* block, unsigned block_size)
|
|||
return block_size;
|
||||
}
|
||||
|
||||
struct snapraid_file* file_alloc(unsigned block_size, const char* sub, uint64_t size, time_t mtime)
|
||||
struct snapraid_file* file_alloc(unsigned block_size, const char* sub, data_off_t size, time_t mtime)
|
||||
{
|
||||
struct snapraid_file* file;
|
||||
pos_t i;
|
||||
block_off_t i;
|
||||
|
||||
file = malloc_nofail(sizeof(struct snapraid_file));
|
||||
snprintf(file->sub, sizeof(file->sub), "%s", sub);
|
||||
|
|
|
|||
23
elem.h
23
elem.h
|
|
@ -38,10 +38,15 @@
|
|||
#define POS_INVALID -1
|
||||
|
||||
/**
|
||||
* Basic position type.
|
||||
* Basic block position type.
|
||||
* With 32 bits and 128k blocks you can address 256 TB.
|
||||
*/
|
||||
typedef uint32_t pos_t;
|
||||
typedef uint32_t block_off_t;
|
||||
|
||||
/**
|
||||
* Basic data position type.
|
||||
*/
|
||||
typedef uint64_t data_off_t;
|
||||
|
||||
struct snapraid_file;
|
||||
|
||||
|
|
@ -49,7 +54,7 @@ struct snapraid_file;
|
|||
* Block of a file.
|
||||
*/
|
||||
struct snapraid_block {
|
||||
pos_t parity_pos; /**< Position of the block in the parity. */
|
||||
block_off_t parity_pos; /**< Position of the block in the parity. */
|
||||
int is_hashed; /**< If the hash of the block is valid. */
|
||||
struct snapraid_file* file; /**< Back pointer to the file owning this block. */
|
||||
unsigned char hash[HASH_MAX]; /**< Hash of the block. */
|
||||
|
|
@ -60,9 +65,9 @@ struct snapraid_block {
|
|||
*/
|
||||
struct snapraid_file {
|
||||
char sub[PATH_MAX]; /**< Sub path of the file. Without the disk dir. The disk is implicit. */
|
||||
uint64_t size; /**< Size of the file. */
|
||||
data_off_t size; /**< Size of the file. */
|
||||
struct snapraid_block* blockvec; /**< All the blocks of the file. */
|
||||
pos_t blockmax; /**< Number of blocks. */
|
||||
block_off_t blockmax; /**< Number of blocks. */
|
||||
time_t mtime; /**< Modification time. */
|
||||
int is_present; /**< If it's seen as present. */
|
||||
|
||||
|
|
@ -77,7 +82,7 @@ struct snapraid_file {
|
|||
struct snapraid_disk {
|
||||
char name[PATH_MAX]; /**< Name of the disk. */
|
||||
char dir[PATH_MAX]; /**< Mount point of the disk. */
|
||||
pos_t first_free_block; /**< First free searching block. */
|
||||
block_off_t first_free_block; /**< First free searching block. */
|
||||
tommy_list filelist; /**< List of all the files. */
|
||||
tommy_hashdyn fileset; /**< Hashtable by sub of all the files. */
|
||||
tommy_array blockarr; /**< Block array of the disk. */
|
||||
|
|
@ -86,7 +91,7 @@ struct snapraid_disk {
|
|||
/**
|
||||
* Get the relative position of a block inside the file.
|
||||
*/
|
||||
pos_t block_file_pos(struct snapraid_block* block);
|
||||
block_off_t block_file_pos(struct snapraid_block* block);
|
||||
|
||||
/**
|
||||
* Get the size in bytes of the block.
|
||||
|
|
@ -94,7 +99,7 @@ pos_t block_file_pos(struct snapraid_block* block);
|
|||
*/
|
||||
unsigned block_file_size(struct snapraid_block* block, unsigned block_size);
|
||||
|
||||
struct snapraid_file* file_alloc(unsigned block_size, const char* sub, uint64_t size, time_t mtime);
|
||||
struct snapraid_file* file_alloc(unsigned block_size, const char* sub, data_off_t size, time_t mtime);
|
||||
|
||||
void file_free(struct snapraid_file* file);
|
||||
|
||||
|
|
@ -109,7 +114,7 @@ struct snapraid_disk* disk_alloc(const char* name, const char* dir);
|
|||
|
||||
void disk_free(struct snapraid_disk* disk);
|
||||
|
||||
static inline struct snapraid_block* disk_block_get(struct snapraid_disk* disk, pos_t pos)
|
||||
static inline struct snapraid_block* disk_block_get(struct snapraid_disk* disk, block_off_t pos)
|
||||
{
|
||||
if (pos < tommy_array_size(&disk->blockarr))
|
||||
return tommy_array_get(&disk->blockarr, pos);
|
||||
|
|
|
|||
113
getopt.c
113
getopt.c
|
|
@ -1,113 +0,0 @@
|
|||
/*
|
||||
* This file is part of the Advance project.
|
||||
*
|
||||
* Copyright (C) 2001, 2002 Andrea Mazzoleni
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#if !HAVE_GETOPT
|
||||
|
||||
/* This source is extracted from the DJGPP LIBC library */
|
||||
|
||||
#define unconst(var, type) ((type)(var))
|
||||
|
||||
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int opterr = 1, optind = 1, optopt = 0;
|
||||
char *optarg = 0;
|
||||
|
||||
#define BADCH (int)'?'
|
||||
#define EMSG ""
|
||||
|
||||
int getopt(int nargc, char *const nargv[], const char *ostr)
|
||||
{
|
||||
static const char *place = EMSG; /* option letter processing */
|
||||
char *oli; /* option letter list index */
|
||||
char *p;
|
||||
|
||||
if (!*place)
|
||||
{
|
||||
if (optind >= nargc || *(place = nargv[optind]) != '-')
|
||||
{
|
||||
place = EMSG;
|
||||
return(EOF);
|
||||
}
|
||||
if (place[1] && *++place == '-')
|
||||
{
|
||||
++optind;
|
||||
place = EMSG;
|
||||
return(EOF);
|
||||
}
|
||||
}
|
||||
|
||||
if ((optopt = (int)*place++) == (int)':'
|
||||
|| !(oli = strchr(ostr, optopt)))
|
||||
{
|
||||
/*
|
||||
* if the user didn't specify '-' as an option,
|
||||
* assume it means EOF.
|
||||
*/
|
||||
if (optopt == (int)'-')
|
||||
return EOF;
|
||||
if (!*place)
|
||||
++optind;
|
||||
if (opterr)
|
||||
{
|
||||
if (!(p = strrchr(*nargv, '/')))
|
||||
p = *nargv;
|
||||
else
|
||||
++p;
|
||||
fprintf(stderr, "%s: illegal option -- %c\n", p, optopt);
|
||||
}
|
||||
return BADCH;
|
||||
}
|
||||
if (*++oli != ':')
|
||||
{ /* don't need argument */
|
||||
optarg = NULL;
|
||||
if (!*place)
|
||||
++optind;
|
||||
}
|
||||
else
|
||||
{ /* need an argument */
|
||||
if (*place) /* no white space */
|
||||
optarg = unconst(place, char *);
|
||||
else if (nargc <= ++optind)
|
||||
{ /* no arg */
|
||||
place = EMSG;
|
||||
if (!(p = strrchr(*nargv, '/')))
|
||||
p = *nargv;
|
||||
else
|
||||
++p;
|
||||
if (opterr)
|
||||
fprintf(stderr, "%s: option requires an argument -- %c\n", p, optopt);
|
||||
return BADCH;
|
||||
}
|
||||
else /* white space */
|
||||
optarg = nargv[optind];
|
||||
place = EMSG;
|
||||
++optind;
|
||||
}
|
||||
return optopt; /* dump back option letter */
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
29
handle.c
29
handle.c
|
|
@ -165,14 +165,26 @@ void handle_close(struct snapraid_handle* handle)
|
|||
int handle_read(int ret_on_error, struct snapraid_handle* handle, struct snapraid_block* block, unsigned char* block_buffer, unsigned block_size)
|
||||
{
|
||||
ssize_t read_ret;
|
||||
off_t offset;
|
||||
data_off_t offset;
|
||||
unsigned read_size;
|
||||
|
||||
offset = block_file_pos(block) * (off_t)block_size;
|
||||
offset = block_file_pos(block) * (data_off_t)block_size;
|
||||
|
||||
read_size = block_file_size(block, block_size);
|
||||
|
||||
#if HAVE_PREAD
|
||||
read_ret = pread(handle->f, block_buffer, read_size, offset);
|
||||
#else
|
||||
if (lseek(handle->f, offset, SEEK_SET) != offset) {
|
||||
if (ret_on_error)
|
||||
return ret_on_error;
|
||||
|
||||
fprintf(stderr, "Error seeking file '%s'. %s.\n", handle->path, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
read_ret = read(handle->f, block_buffer, read_size);
|
||||
#endif
|
||||
if (read_ret != read_size) {
|
||||
if (ret_on_error)
|
||||
return ret_on_error;
|
||||
|
|
@ -187,14 +199,23 @@ int handle_read(int ret_on_error, struct snapraid_handle* handle, struct snaprai
|
|||
void handle_write(struct snapraid_handle* handle, struct snapraid_block* block, unsigned char* block_buffer, unsigned block_size)
|
||||
{
|
||||
ssize_t write_ret;
|
||||
off_t offset;
|
||||
data_off_t offset;
|
||||
unsigned write_size;
|
||||
|
||||
offset = block_file_pos(block) * (off_t)block_size;
|
||||
offset = block_file_pos(block) * (data_off_t)block_size;
|
||||
|
||||
write_size = block_file_size(block, block_size);
|
||||
|
||||
#if HAVE_PWRITE
|
||||
write_ret = pwrite(handle->f, block_buffer, write_size, offset);
|
||||
#else
|
||||
if (lseek(handle->f, offset, SEEK_SET) != offset) {
|
||||
fprintf(stderr, "Error seeking file '%s'. %s.\n", handle->path, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
write_ret = write(handle->f, block_buffer, write_size);
|
||||
#endif
|
||||
if (write_ret != write_size) {
|
||||
fprintf(stderr, "Error writing file '%s'. %s.\n", handle->path, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
|
|
|
|||
12
md5.h
12
md5.h
|
|
@ -20,12 +20,8 @@
|
|||
* Still in the public domain.
|
||||
*/
|
||||
|
||||
#ifndef MD5_H
|
||||
#define MD5_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#ifndef __MD5_H
|
||||
#define __MD5_H
|
||||
|
||||
#define MD5_SIZE 16
|
||||
|
||||
|
|
@ -39,8 +35,4 @@ void md5_init(struct md5_t* context);
|
|||
void md5_update(struct md5_t* context, const unsigned char* buf, unsigned len);
|
||||
void md5_final(struct md5_t* context, unsigned char* digest);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* !MD5_H */
|
||||
|
|
|
|||
57
parity.c
57
parity.c
|
|
@ -24,10 +24,10 @@
|
|||
/****************************************************************************/
|
||||
/* parity */
|
||||
|
||||
pos_t parity_resize(struct snapraid_state* state)
|
||||
block_off_t parity_resize(struct snapraid_state* state)
|
||||
{
|
||||
unsigned disk_count = tommy_array_size(&state->diskarr);
|
||||
pos_t parity_block;
|
||||
block_off_t parity_block;
|
||||
unsigned i;
|
||||
|
||||
/* compute the size of the parity file */
|
||||
|
|
@ -36,7 +36,7 @@ pos_t parity_resize(struct snapraid_state* state)
|
|||
struct snapraid_disk* disk = tommy_array_get(&state->diskarr, i);
|
||||
|
||||
/* start from the declared size */
|
||||
pos_t block = tommy_array_size(&disk->blockarr);
|
||||
block_off_t block = tommy_array_size(&disk->blockarr);
|
||||
|
||||
/* decrease the block until an allocated block */
|
||||
while (block > 0 && tommy_array_get(&disk->blockarr, block - 1) == 0)
|
||||
|
|
@ -49,7 +49,7 @@ pos_t parity_resize(struct snapraid_state* state)
|
|||
return parity_block;
|
||||
}
|
||||
|
||||
int parity_create(const char* path, off_t size)
|
||||
int parity_create(const char* path, data_off_t size)
|
||||
{
|
||||
struct stat st;
|
||||
int ret;
|
||||
|
|
@ -105,7 +105,9 @@ int parity_create(const char* path, off_t size)
|
|||
|
||||
int parity_open(int ret_on_error, const char* path)
|
||||
{
|
||||
#if HAVE_POSIX_FADVISE
|
||||
int ret;
|
||||
#endif
|
||||
int f;
|
||||
|
||||
f = open(path, O_RDONLY | O_BINARY);
|
||||
|
|
@ -129,8 +131,9 @@ int parity_open(int ret_on_error, const char* path)
|
|||
return f;
|
||||
}
|
||||
|
||||
void parity_close(const char* path, int f)
|
||||
void parity_sync(const char* path, int f)
|
||||
{
|
||||
#if HAVE_FSYNC
|
||||
int ret;
|
||||
|
||||
/* ensure that data changes are written to disk */
|
||||
|
|
@ -141,6 +144,12 @@ void parity_close(const char* path, int f)
|
|||
fprintf(stderr, "Error synching parity file '%s'. %s.\n", path, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void parity_close(const char* path, int f)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = close(f);
|
||||
if (ret != 0) {
|
||||
|
|
@ -149,14 +158,27 @@ void parity_close(const char* path, int f)
|
|||
}
|
||||
}
|
||||
|
||||
void parity_write(const char* path, int f, pos_t pos, unsigned char* block_buffer, unsigned block_size)
|
||||
void parity_write(const char* path, int f, block_off_t pos, unsigned char* block_buffer, unsigned block_size)
|
||||
{
|
||||
ssize_t write_ret;
|
||||
off_t offset;
|
||||
data_off_t offset;
|
||||
|
||||
offset = pos * (off_t)block_size;
|
||||
offset = pos * (data_off_t)block_size;
|
||||
|
||||
#if HAVE_PWRITE
|
||||
write_ret = pwrite(f, block_buffer, block_size, offset);
|
||||
#else
|
||||
if (lseek(f, offset, SEEK_SET) != offset) {
|
||||
if (errno == ENOSPC) {
|
||||
fprintf(stderr, "Failed to grow parity file '%s' due lack of space.\n", path);
|
||||
} else {
|
||||
fprintf(stderr, "Error seeking file '%s'. %s.\n", path, strerror(errno));
|
||||
}
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
write_ret = write(f, block_buffer, block_size);
|
||||
#endif
|
||||
if (write_ret != block_size) {
|
||||
if (errno == ENOSPC) {
|
||||
fprintf(stderr, "Failed to grow parity file '%s' due lack of space.\n", path);
|
||||
|
|
@ -167,21 +189,34 @@ void parity_write(const char* path, int f, pos_t pos, unsigned char* block_buffe
|
|||
}
|
||||
}
|
||||
|
||||
int parity_read(int ret_on_error, const char* path, int f, pos_t pos, unsigned char* block_buffer, unsigned block_size)
|
||||
int parity_read(int ret_on_error, const char* path, int f, block_off_t pos, unsigned char* block_buffer, unsigned block_size)
|
||||
{
|
||||
ssize_t read_ret;
|
||||
off_t offset;
|
||||
data_off_t offset;
|
||||
|
||||
/* if the file is not opened, return an error without trying */
|
||||
if (f == -1 && ret_on_error)
|
||||
return -1;
|
||||
|
||||
offset = pos * (off_t)block_size;
|
||||
offset = pos * (data_off_t)block_size;
|
||||
|
||||
#if HAVE_PREAD
|
||||
read_ret = pread(f, block_buffer, block_size, offset);
|
||||
#else
|
||||
if (lseek(f, offset, SEEK_SET) != offset) {
|
||||
if (ret_on_error)
|
||||
return ret_on_error;
|
||||
|
||||
fprintf(stderr, "Error seeking file '%s'. %s.\n", path, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
read_ret = read(f, block_buffer, block_size);
|
||||
#endif
|
||||
if (read_ret != block_size) {
|
||||
if (ret_on_error)
|
||||
return ret_on_error;
|
||||
|
||||
fprintf(stderr, "Error reading file '%s'. %s.\n", path, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
|
|
|||
10
parity.h
10
parity.h
|
|
@ -24,17 +24,19 @@
|
|||
/**
|
||||
* Computes the size of the parity data in number of blocks.
|
||||
*/
|
||||
pos_t parity_resize(struct snapraid_state* state);
|
||||
block_off_t parity_resize(struct snapraid_state* state);
|
||||
|
||||
int parity_create(const char* path, off_t size);
|
||||
int parity_create(const char* path, data_off_t size);
|
||||
|
||||
int parity_open(int ret_on_error, const char* path);
|
||||
|
||||
void parity_sync(const char* path, int f);
|
||||
|
||||
void parity_close(const char* path, int f);
|
||||
|
||||
void parity_write(const char* parity_path, int parity_f, pos_t pos, unsigned char* block_buffer, unsigned block_size);
|
||||
void parity_write(const char* parity_path, int parity_f, block_off_t pos, unsigned char* block_buffer, unsigned block_size);
|
||||
|
||||
int parity_read(int ret_on_error, const char* parity_path, int parity_f, pos_t pos, unsigned char* block_buffer, unsigned block_size);
|
||||
int parity_read(int ret_on_error, const char* parity_path, int parity_f, block_off_t pos, unsigned char* block_buffer, unsigned block_size);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
52
portable.h
52
portable.h
|
|
@ -25,14 +25,9 @@
|
|||
/***************************************************************************/
|
||||
/* Config */
|
||||
|
||||
#ifdef __WIN32__
|
||||
/* Customize for Windows Mingw/Cygwin */
|
||||
#define HAVE_SYS_TYPES_H 1
|
||||
#define HAVE_SYS_STAT_H 1
|
||||
#define HAVE_DIRENT_H 1
|
||||
#define TIME_WITH_SYS_TIME 1
|
||||
#define HAVE_SYS_TIME_H 1
|
||||
#define HAVE_UNISTD_H 1
|
||||
#ifdef __MINGW32__ /* Specific for MINGW */
|
||||
#define __MSVCRT_VERSION__ 0x0601 /* Define the MSVCRT version required */
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
/* Include some standard headers */
|
||||
|
|
@ -45,6 +40,7 @@
|
|||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <limits.h>
|
||||
|
||||
#if HAVE_STDINT_H
|
||||
#include <stdint.h>
|
||||
|
|
@ -94,12 +90,6 @@
|
|||
#include <getopt.h>
|
||||
#endif
|
||||
|
||||
#if !HAVE_GETOPT
|
||||
int getopt(int argc, char * const *argv, const char *options);
|
||||
extern char *optarg;
|
||||
extern int optind, opterr, optopt;
|
||||
#endif
|
||||
|
||||
#if HAVE_GETOPT_LONG
|
||||
#define SWITCH_GETOPT_LONG(a,b) a
|
||||
#else
|
||||
|
|
@ -110,5 +100,39 @@ extern int optind, opterr, optopt;
|
|||
#define O_BINARY 0
|
||||
#endif
|
||||
|
||||
#ifdef __MINGW32__ /* Specific for MINGW */
|
||||
|
||||
/* Remap functions and types for 64 bit support */
|
||||
#define stat _stati64
|
||||
#define off_t off64_t
|
||||
#define lseek lseek64
|
||||
#define fstat _fstati64
|
||||
#define HAVE_FTRUNCATE 1
|
||||
#define ftruncate _chsize_s
|
||||
#define HAVE_FSYNC 1
|
||||
#define fsync _commit
|
||||
|
||||
#define rename windows_atomic_rename
|
||||
static inline int windows_atomic_rename(const char* a, const char* b)
|
||||
{
|
||||
if (!MoveFileEx(a, b, MOVEFILE_REPLACE_EXISTING)) {
|
||||
switch (GetLastError()) {
|
||||
case ERROR_ACCESS_DENIED :
|
||||
errno = EACCES;
|
||||
break;
|
||||
case ERROR_FILE_NOT_FOUND :
|
||||
errno = ENOENT;
|
||||
break;
|
||||
default :
|
||||
errno = EIO;
|
||||
break;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
40
scan.c
40
scan.c
|
|
@ -33,11 +33,11 @@ struct snapraid_scan {
|
|||
*/
|
||||
static void scan_file_remove(struct snapraid_state* state, struct snapraid_disk* disk, struct snapraid_file* file)
|
||||
{
|
||||
pos_t i;
|
||||
block_off_t i;
|
||||
|
||||
/* free all the blocks of the file */
|
||||
for(i=0;i<file->blockmax;++i) {
|
||||
pos_t block_pos = file->blockvec[i].parity_pos;
|
||||
block_off_t block_pos = file->blockvec[i].parity_pos;
|
||||
|
||||
/* adjust the first free position */
|
||||
if (disk->first_free_block > block_pos)
|
||||
|
|
@ -59,9 +59,9 @@ static void scan_file_remove(struct snapraid_state* state, struct snapraid_disk*
|
|||
*/
|
||||
static void scan_file_insert(struct snapraid_state* state, struct snapraid_disk* disk, struct snapraid_file* file)
|
||||
{
|
||||
pos_t i;
|
||||
pos_t block_max;
|
||||
pos_t block_pos;
|
||||
block_off_t i;
|
||||
block_off_t block_max;
|
||||
block_off_t block_pos;
|
||||
|
||||
/* allocate the blocks of the file */
|
||||
block_pos = disk->first_free_block;
|
||||
|
|
@ -91,21 +91,15 @@ static void scan_file_insert(struct snapraid_state* state, struct snapraid_disk*
|
|||
tommy_list_insert_tail(&disk->filelist, &file->nodelist, file);
|
||||
}
|
||||
|
||||
static void scan_file(struct snapraid_scan* scan, struct snapraid_state* state, struct snapraid_disk* disk, const char* path, const char* sub)
|
||||
static void scan_file(struct snapraid_scan* scan, struct snapraid_state* state, struct snapraid_disk* disk, const char* path, const char* sub, const struct stat* st)
|
||||
{
|
||||
struct stat st;
|
||||
struct snapraid_file* file;
|
||||
|
||||
if (stat(path, &st) != 0) {
|
||||
fprintf(stderr, "Error in stat file '%s'\n", path);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* check if the file already exists */
|
||||
file = tommy_hashdyn_search(&disk->fileset, file_compare, sub, file_hash(sub));
|
||||
if (file) {
|
||||
/* check if the file is the same */
|
||||
if (file->size == st.st_size && file->mtime == st.st_mtime) {
|
||||
if (file->size == st->st_size && file->mtime == st->st_mtime) {
|
||||
/* mark as present */
|
||||
++scan->count_equal;
|
||||
file->is_present = 1;
|
||||
|
|
@ -121,7 +115,7 @@ static void scan_file(struct snapraid_scan* scan, struct snapraid_state* state,
|
|||
|
||||
/* create the new file */
|
||||
++scan->count_insert;
|
||||
file = file_alloc(state->block_size, sub, st.st_size, st.st_mtime);
|
||||
file = file_alloc(state->block_size, sub, st->st_size, st->st_mtime);
|
||||
file->is_present = 1;
|
||||
|
||||
/* insert it */
|
||||
|
|
@ -140,13 +134,21 @@ static void scan_dir(struct snapraid_scan* scan, struct snapraid_state* state, s
|
|||
}
|
||||
|
||||
while ((dd = readdir(d)) != 0) {
|
||||
if (dd->d_type == DT_REG) {
|
||||
char path_next[PATH_MAX];
|
||||
char path[PATH_MAX];
|
||||
struct stat st;
|
||||
|
||||
snprintf(path, sizeof(path), "%s%s", dir, dd->d_name);
|
||||
|
||||
if (stat(path, &st) != 0) {
|
||||
fprintf(stderr, "Error in stat file '%s'\n", path);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (S_ISREG(st.st_mode)) {
|
||||
char sub_next[PATH_MAX];
|
||||
snprintf(path_next, sizeof(path_next), "%s%s", dir, dd->d_name);
|
||||
snprintf(sub_next, sizeof(sub_next), "%s%s", sub, dd->d_name);
|
||||
scan_file(scan, state, disk, path_next, sub_next);
|
||||
} else if (dd->d_type == DT_DIR) {
|
||||
scan_file(scan, state, disk, path, sub_next, &st);
|
||||
} else if (S_ISDIR(st.st_mode)) {
|
||||
if (strcmp(dd->d_name, ".") != 0 && strcmp(dd->d_name, "..") != 0 && strcmp(dd->d_name, "lost+found") != 0
|
||||
) {
|
||||
char dir_next[PATH_MAX];
|
||||
|
|
|
|||
11
snapraid.c
11
snapraid.c
|
|
@ -79,8 +79,11 @@ int main(int argc, char* argv[])
|
|||
const char* conf;
|
||||
struct snapraid_state state;
|
||||
int operation;
|
||||
pos_t blockstart;
|
||||
block_off_t blockstart;
|
||||
|
||||
/* intercept Ctrl+C */
|
||||
signal(SIGINT, &signal_handler);
|
||||
|
||||
/* defaults */
|
||||
conf = "/etc/" PACKAGE ".conf";
|
||||
verbose = 0;
|
||||
|
|
@ -139,12 +142,6 @@ int main(int argc, char* argv[])
|
|||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
struct sigaction sig;
|
||||
sig.sa_handler = signal_handler;
|
||||
sigemptyset(&sig.sa_mask);
|
||||
sig.sa_flags = 0;
|
||||
sigaction(SIGINT, &sig, 0);
|
||||
|
||||
state_init(&state);
|
||||
|
||||
state_config(&state, conf, verbose, force);
|
||||
|
|
|
|||
24
state.c
24
state.c
|
|
@ -24,7 +24,7 @@
|
|||
/**
|
||||
* Max length of a line in the configuration and state files.
|
||||
*/
|
||||
#define LINE_MAX 1024
|
||||
#define TEXT_LINE_MAX 1024
|
||||
|
||||
void state_init(struct snapraid_state* state)
|
||||
{
|
||||
|
|
@ -35,7 +35,7 @@ void state_init(struct snapraid_state* state)
|
|||
tommy_array_init(&state->diskarr);
|
||||
|
||||
if (sizeof(off_t) < sizeof(uint64_t)) {
|
||||
fprintf(stderr, "Internal inconsistency in off_t type size\n");
|
||||
fprintf(stderr, "Missing support for large files\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
|
@ -70,14 +70,14 @@ void state_config(struct snapraid_state* state, const char* path, int verbose, i
|
|||
|
||||
line = 0;
|
||||
while (1) {
|
||||
char buffer[LINE_MAX];
|
||||
char buffer[TEXT_LINE_MAX];
|
||||
char* tag;
|
||||
char* s;
|
||||
int ret;
|
||||
|
||||
++line;
|
||||
|
||||
ret = strgets(buffer, LINE_MAX, f);
|
||||
ret = strgets(buffer, TEXT_LINE_MAX, f);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error reading the configuration file '%s' at line %u\n", path, line);
|
||||
exit(EXIT_FAILURE);
|
||||
|
|
@ -182,14 +182,14 @@ void state_read(struct snapraid_state* state)
|
|||
line = 0;
|
||||
block_index = 0;
|
||||
while (1) {
|
||||
char buffer[LINE_MAX];
|
||||
char buffer[TEXT_LINE_MAX];
|
||||
char* tag;
|
||||
char* s;
|
||||
int ret;
|
||||
|
||||
++line;
|
||||
|
||||
ret = strgets(buffer, LINE_MAX, f);
|
||||
ret = strgets(buffer, TEXT_LINE_MAX, f);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error reading the state file '%s' at line %u\n", path, line);
|
||||
exit(EXIT_FAILURE);
|
||||
|
|
@ -213,7 +213,7 @@ void state_read(struct snapraid_state* state)
|
|||
char* size;
|
||||
char* mtime;
|
||||
char* sub;
|
||||
uint64_t v_size;
|
||||
data_off_t v_size;
|
||||
uint64_t v_mtime;
|
||||
unsigned i;
|
||||
|
||||
|
|
@ -279,7 +279,7 @@ void state_read(struct snapraid_state* state)
|
|||
} else if (strcmp(tag, "blk") == 0) {
|
||||
char* pos;
|
||||
char* hash;
|
||||
pos_t v_pos;
|
||||
block_off_t v_pos;
|
||||
struct snapraid_block* block;
|
||||
char* e;
|
||||
|
||||
|
|
@ -381,7 +381,7 @@ void state_write(struct snapraid_state* state)
|
|||
|
||||
/* for each file */
|
||||
for(j=disk->filelist;j!=0;j=j->next) {
|
||||
pos_t k;
|
||||
block_off_t k;
|
||||
struct snapraid_file* file = j->data;
|
||||
int ret;
|
||||
|
||||
|
|
@ -423,10 +423,12 @@ void state_write(struct snapraid_state* state)
|
|||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
#if HAVE_FSYNC
|
||||
if (fsync(fileno(f)) != 0) {
|
||||
fprintf(stderr, "Error writing the state file '%s' in fsync(). %s.\n", path, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (fclose(f) != 0) {
|
||||
fprintf(stderr, "Error writing the state file '%s' in close(). %s.\n", path, strerror(errno));
|
||||
|
|
@ -446,7 +448,7 @@ void state_write(struct snapraid_state* state)
|
|||
|
||||
#define PROGRESS_CLEAR " "
|
||||
|
||||
int state_progress(time_t* start, time_t* last, pos_t blockpos, pos_t blockmax, uint64_t count_block, uint64_t count_size)
|
||||
int state_progress(time_t* start, time_t* last, block_off_t blockpos, block_off_t blockmax, data_off_t count_block, data_off_t count_size)
|
||||
{
|
||||
time_t now;
|
||||
|
||||
|
|
@ -463,7 +465,7 @@ int state_progress(time_t* start, time_t* last, pos_t blockpos, pos_t blockmax,
|
|||
|
||||
if (delta > 5 && count_block > 0) {
|
||||
unsigned m, h;
|
||||
uint64_t todo = blockmax - blockpos;
|
||||
data_off_t todo = blockmax - blockpos;
|
||||
|
||||
m = todo * delta / (60 * count_block);
|
||||
|
||||
|
|
|
|||
6
state.h
6
state.h
|
|
@ -59,14 +59,14 @@ void state_scan(struct snapraid_state* state);
|
|||
/**
|
||||
* Sync.
|
||||
*/
|
||||
void state_sync(struct snapraid_state* state, pos_t blockstart);
|
||||
void state_sync(struct snapraid_state* state, block_off_t blockstart);
|
||||
|
||||
/**
|
||||
* Check.
|
||||
*/
|
||||
void state_check(struct snapraid_state* state, int fix, pos_t blockstart);
|
||||
void state_check(struct snapraid_state* state, int fix, block_off_t blockstart);
|
||||
|
||||
int state_progress(time_t* start, time_t* last, pos_t blockpos, pos_t blockmax, uint64_t count_block, uint64_t count_size);
|
||||
int state_progress(time_t* start, time_t* last, block_off_t blockpos, block_off_t blockmax, data_off_t count_block, data_off_t count_size);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
18
sync.c
18
sync.c
|
|
@ -26,16 +26,16 @@
|
|||
/****************************************************************************/
|
||||
/* sync */
|
||||
|
||||
static void state_sync_process(struct snapraid_state* state, int parity_f, pos_t blockstart, pos_t blockmax)
|
||||
static void state_sync_process(struct snapraid_state* state, int parity_f, block_off_t blockstart, block_off_t blockmax)
|
||||
{
|
||||
struct snapraid_handle* handle;
|
||||
unsigned diskmax = tommy_array_size(&state->diskarr);
|
||||
pos_t i;
|
||||
block_off_t i;
|
||||
unsigned j;
|
||||
unsigned char* block_buffer;
|
||||
unsigned char* xor_buffer;
|
||||
uint64_t count_size;
|
||||
uint64_t count_block;
|
||||
data_off_t count_size;
|
||||
data_off_t count_block;
|
||||
time_t start;
|
||||
time_t last;
|
||||
|
||||
|
|
@ -138,17 +138,17 @@ static void state_sync_process(struct snapraid_state* state, int parity_f, pos_t
|
|||
free(xor_buffer);
|
||||
}
|
||||
|
||||
void state_sync(struct snapraid_state* state, pos_t blockstart)
|
||||
void state_sync(struct snapraid_state* state, block_off_t blockstart)
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
pos_t blockmax;
|
||||
off_t size;
|
||||
block_off_t blockmax;
|
||||
data_off_t size;
|
||||
int f;
|
||||
|
||||
printf("Syncing...\n");
|
||||
|
||||
blockmax = parity_resize(state);
|
||||
size = blockmax * (off_t)state->block_size;
|
||||
size = blockmax * (data_off_t)state->block_size;
|
||||
|
||||
if (blockstart >= blockmax) {
|
||||
fprintf(stderr, "The specified starting block %u is bigger than the parity size %u.\n", blockstart, blockmax);
|
||||
|
|
@ -160,6 +160,8 @@ void state_sync(struct snapraid_state* state, pos_t blockstart)
|
|||
|
||||
state_sync_process(state, f, blockstart, blockmax);
|
||||
|
||||
parity_sync(path, f);
|
||||
|
||||
parity_close(path, f);
|
||||
}
|
||||
|
||||
|
|
|
|||
8
util.h
8
util.h
|
|
@ -46,7 +46,11 @@ static inline int strgets(char* s, unsigned size, FILE* f)
|
|||
int c;
|
||||
|
||||
while (1) {
|
||||
#if HAVE_FGETC_UNLOCKED
|
||||
c = fgetc_unlocked(f);
|
||||
#else
|
||||
c = fgetc(f);
|
||||
#endif
|
||||
|
||||
if (c == EOF || c == '\n')
|
||||
break;
|
||||
|
|
@ -59,7 +63,11 @@ static inline int strgets(char* s, unsigned size, FILE* f)
|
|||
}
|
||||
|
||||
if (c == EOF) {
|
||||
#if HAVE_FERROR_UNLOCKED
|
||||
if (ferror_unlocked(f)) {
|
||||
#else
|
||||
if (ferror(f)) {
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
if (i == s)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue