mirror of
https://github.com/amadvance/snapraid.git
synced 2026-10-26 19:01:57 -04:00
Compiles with optional nanoseconds supports.
This commit is contained in:
parent
7d6251c698
commit
3c598b28cc
8 changed files with 63 additions and 61 deletions
|
|
@ -38,12 +38,13 @@ AC_TYPE_UINT32_T
|
|||
AC_TYPE_UINT64_T
|
||||
AC_TYPE_UINT8_T
|
||||
AC_TYPE_INT8_T
|
||||
AC_CHECK_MEMBERS([struct stat.st_mtim.tv_nsec, struct stat.st_mtimensec, struct stat.st_mtimespec.tv_nsec], [], [], [[#include <sys/stat.h>]])
|
||||
|
||||
dnl Checks for library functions.
|
||||
AC_SYS_LARGEFILE
|
||||
AC_CHECK_FUNCS([memset strchr strerror strrchr mkdir gettimeofday strtoul])
|
||||
AC_CHECK_FUNCS([getopt getopt_long snprintf vsnprintf])
|
||||
AC_CHECK_FUNCS([ftruncate fallocate fsync access posix_fallocate posix_fadvise pread pwrite getc_unlocked ferror_unlocked fnmatch])
|
||||
AC_CHECK_FUNCS([ftruncate fallocate fsync access posix_fallocate posix_fadvise pread pwrite getc_unlocked ferror_unlocked fnmatch futimes futimens])
|
||||
|
||||
dnl Checks for architecture
|
||||
AC_C_BIGENDIAN
|
||||
|
|
|
|||
23
handle.c
23
handle.c
|
|
@ -327,20 +327,39 @@ int handle_write(struct snapraid_handle* handle, struct snapraid_block* block, u
|
|||
|
||||
int handle_utime(struct snapraid_handle* handle)
|
||||
{
|
||||
#if HAVE_FUTIMENS
|
||||
struct timespec tv[2];
|
||||
#else
|
||||
struct timeval tv[2];
|
||||
#endif
|
||||
int ret;
|
||||
|
||||
/* do nothing if not opened */
|
||||
if (handle->f == -1)
|
||||
return 0;
|
||||
|
||||
#if HAVE_FUTIMENS /* futimens is preferred because it gives nanosecond precision */
|
||||
tv[0].tv_sec = handle->file->mtime_sec;
|
||||
tv[0].tv_nsec = handle->file->mtime_nsec;
|
||||
|
||||
if (handle->file->mtime_nsec != FILE_MTIME_NSEC_INVALID)
|
||||
tv[0].tv_nsec = handle->file->mtime_nsec;
|
||||
else
|
||||
tv[0].tv_nsec = 0;
|
||||
tv[1].tv_sec = tv[0].tv_sec;
|
||||
tv[1].tv_nsec = tv[0].tv_nsec;
|
||||
|
||||
ret = futimens(handle->f, tv);
|
||||
#else
|
||||
tv[0].tv_sec = handle->file->mtime_sec;
|
||||
if (handle->file->mtime_nsec != FILE_MTIME_NSEC_INVALID)
|
||||
tv[0].tv_usec = handle->file->mtime_nsec / 1000;
|
||||
else
|
||||
tv[0].tv_usec = 0;
|
||||
tv[1].tv_sec = tv[0].tv_sec;
|
||||
tv[1].tv_usec = tv[0].tv_usec;
|
||||
|
||||
ret = futimes(handle->f, tv);
|
||||
#endif
|
||||
|
||||
if (ret != 0) {
|
||||
fprintf(stderr, "Error timing file '%s'. %s.\n", handle->file->sub, strerror(errno));
|
||||
return -1;
|
||||
|
|
|
|||
43
mingw.c
43
mingw.c
|
|
@ -203,7 +203,7 @@ static void windows_info2stat(const BY_HANDLE_FILE_INFORMATION* info, struct win
|
|||
*/
|
||||
mtime -= 116444736000000000LL;
|
||||
st->st_mtime = mtime / 10000000;
|
||||
st->st_mtim.tv_nsec = (mtime % 10000000) * 100;
|
||||
st->st_mtimensec = (mtime % 10000000) * 100;
|
||||
|
||||
st->st_ino = info->nFileIndexHigh;
|
||||
st->st_ino <<= 32;
|
||||
|
|
@ -264,7 +264,7 @@ static void windows_finddata2stat(const WIN32_FIND_DATAW* info, struct windows_s
|
|||
*/
|
||||
mtime -= 116444736000000000LL;
|
||||
st->st_mtime = mtime / 10000000;
|
||||
st->st_mtim.tv_nsec = (mtime % 10000000) * 100;
|
||||
st->st_mtimensec = (mtime % 10000000) * 100;
|
||||
|
||||
/* No inode information available */
|
||||
st->st_ino = 0;
|
||||
|
|
@ -470,45 +470,6 @@ int windows_ftruncate(int fd, off64_t off)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int windows_futimes(int fd, struct timeval tv[2])
|
||||
{
|
||||
HANDLE h;
|
||||
FILETIME ft;
|
||||
uint64_t mtime;
|
||||
|
||||
if (fd == -1) {
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
h = (HANDLE)_get_osfhandle(fd);
|
||||
if (h == INVALID_HANDLE_VALUE) {
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert to windows time
|
||||
*
|
||||
* How To Convert a UNIX time_t to a Win32 FILETIME or SYSTEMTIME
|
||||
* http://support.microsoft.com/kb/167296
|
||||
*/
|
||||
mtime = tv[0].tv_sec;
|
||||
mtime *= 10000000;
|
||||
mtime += tv[0].tv_usec * 10;
|
||||
mtime += 116444736000000000;
|
||||
|
||||
ft.dwHighDateTime = mtime >> 32;
|
||||
ft.dwLowDateTime = mtime;
|
||||
|
||||
if (!SetFileTime(h, 0, 0, &ft)) {
|
||||
windows_errno(GetLastError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int windows_futimens(int fd, struct windows_timespec tv[2])
|
||||
{
|
||||
HANDLE h;
|
||||
|
|
|
|||
8
mingw.h
8
mingw.h
|
|
@ -49,7 +49,7 @@
|
|||
#define opendir windows_opendir
|
||||
#define readdir windows_readdir
|
||||
#define closedir windows_closedir
|
||||
#define futimes windows_futimes
|
||||
#define HAVE_FUTIMENS 1
|
||||
#define futimens windows_futimens
|
||||
#define O_NOFOLLOW 0
|
||||
#define stat_hidden windows_stat_hidden
|
||||
|
|
@ -60,10 +60,6 @@
|
|||
#define readlink(a,b,c) -1
|
||||
#define symlink(a,b) -1
|
||||
|
||||
struct windows_mtim {
|
||||
int tv_nsec;
|
||||
};
|
||||
|
||||
/**
|
||||
* Generic stat information.
|
||||
*/
|
||||
|
|
@ -71,7 +67,7 @@ struct windows_stat {
|
|||
uint64_t st_ino;
|
||||
int64_t st_size;
|
||||
int64_t st_mtime;
|
||||
struct windows_mtim st_mtim;
|
||||
int32_t st_mtimensec;
|
||||
uint32_t st_mode;
|
||||
uint32_t st_nlink;
|
||||
uint32_t st_dev;
|
||||
|
|
|
|||
21
portable.h
21
portable.h
|
|
@ -112,10 +112,31 @@
|
|||
|
||||
#ifdef __MINGW32__ /* Specific for MingW */
|
||||
#include "mingw.h"
|
||||
|
||||
/* We have nano second support */
|
||||
#define STAT_NSEC(st) (st)->st_mtimensec
|
||||
|
||||
#else /* Specific for Unix */
|
||||
|
||||
#define O_BINARY 0 /**< Not used in Unix. */
|
||||
#define O_SEQUENTIAL 0 /**< In Unix posix_fadvise() shall be used. */
|
||||
|
||||
/* Check if we have nanoseconds support */
|
||||
#if HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
|
||||
#define STAT_NSEC(st) (st)->st_mtim.tv_nsec /* Linux */
|
||||
#elif HAVE_STRUCT_STAT_ST_MTIMENSEC
|
||||
#define STAT_NSEC(st) (st)->st_mtimensec /* FreeBSD, Mac OS X if _POSIX_C_SOURCE defined */
|
||||
#elif HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC
|
||||
#define STAT_NSEC(st) (st)->st_mtimespec.tv_nsec /* Mac OS X if _POSIX_C_SOURCE not defined */
|
||||
#else
|
||||
/**
|
||||
* If nanoseconds are not supported, we report the special FILE_MTIME_NSEC_INVALID value,
|
||||
* to mark that it's undefined.
|
||||
* This result in not having it saved into the content file as a dummy 0.
|
||||
*/
|
||||
#define STAT_NSEC(st) -1
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Check if the specified file is hidden.
|
||||
*/
|
||||
|
|
|
|||
10
scan.c
10
scan.c
|
|
@ -174,14 +174,16 @@ static void scan_file(struct snapraid_scan* scan, struct snapraid_state* state,
|
|||
&& file->mtime_sec == st->st_mtime
|
||||
/* always accept the value if it's FILE_MTIME_NSEC_INVALID */
|
||||
/* it happens when upgrading from an old version of SnapRAID */
|
||||
&& (file->mtime_nsec == st->st_mtim.tv_nsec || file->mtime_nsec == FILE_MTIME_NSEC_INVALID)
|
||||
&& (file->mtime_nsec == STAT_NSEC(st) || file->mtime_nsec == FILE_MTIME_NSEC_INVALID)
|
||||
) {
|
||||
/* mark as present */
|
||||
file_flag_set(file, FILE_IS_PRESENT);
|
||||
|
||||
/* update the nano seconds mtime if required */
|
||||
if (file->mtime_nsec == FILE_MTIME_NSEC_INVALID) {
|
||||
file->mtime_nsec = st->st_mtim.tv_nsec;
|
||||
if (file->mtime_nsec == FILE_MTIME_NSEC_INVALID
|
||||
&& STAT_NSEC(st) != FILE_MTIME_NSEC_INVALID
|
||||
) {
|
||||
file->mtime_nsec = STAT_NSEC(st);
|
||||
|
||||
/* we have to save the new mtime */
|
||||
state->need_write = 1;
|
||||
|
|
@ -315,7 +317,7 @@ static void scan_file(struct snapraid_scan* scan, struct snapraid_state* state,
|
|||
}
|
||||
|
||||
/* insert it */
|
||||
file = file_alloc(state->block_size, sub, st->st_size, st->st_mtime, st->st_mtim.tv_nsec, st->st_ino);
|
||||
file = file_alloc(state->block_size, sub, st->st_size, st->st_mtime, STAT_NSEC(st), st->st_ino);
|
||||
|
||||
/* mark it as present */
|
||||
file_flag_set(file, FILE_IS_PRESENT);
|
||||
|
|
|
|||
12
state.c
12
state.c
|
|
@ -900,7 +900,7 @@ void state_read(struct snapraid_state* state)
|
|||
/* use a special value, meaning that we don't have this information */
|
||||
v_mtime_nsec = FILE_MTIME_NSEC_INVALID;
|
||||
}
|
||||
|
||||
|
||||
if (c != ' ') {
|
||||
fprintf(stderr, "Invalid 'file' specification in '%s' at line %u\n", path, line);
|
||||
exit(EXIT_FAILURE);
|
||||
|
|
@ -1303,7 +1303,7 @@ void state_write(struct snapraid_state* state)
|
|||
block_off_t k;
|
||||
uint64_t size;
|
||||
uint64_t mtime_sec;
|
||||
uint32_t mtime_nsec;
|
||||
int32_t mtime_nsec;
|
||||
uint64_t inode;
|
||||
|
||||
size = file->size;
|
||||
|
|
@ -1321,9 +1321,11 @@ void state_write(struct snapraid_state* state)
|
|||
sputc(' ', f);
|
||||
sputu64(mtime_sec, f);
|
||||
hash = oathash64(hash, mtime_sec);
|
||||
sputc('.', f);
|
||||
sputu32(mtime_nsec, f);
|
||||
hash = oathash32(hash, mtime_nsec);
|
||||
if (mtime_nsec != FILE_MTIME_NSEC_INVALID) {
|
||||
sputc('.', f);
|
||||
sputu32(mtime_nsec, f);
|
||||
hash = oathash32(hash, mtime_nsec);
|
||||
}
|
||||
sputc(' ', f);
|
||||
sputu64(inode, f);
|
||||
hash = oathash64(hash, inode);
|
||||
|
|
|
|||
4
sync.c
4
sync.c
|
|
@ -204,13 +204,13 @@ static int state_sync_process(struct snapraid_state* state, struct snapraid_pari
|
|||
/* check if the file is changed */
|
||||
if (handle[j].st.st_size != block_file_get(block)->size
|
||||
|| handle[j].st.st_mtime != block_file_get(block)->mtime_sec
|
||||
|| handle[j].st.st_mtim.tv_nsec != block_file_get(block)->mtime_nsec
|
||||
|| STAT_NSEC(&handle[j].st) != block_file_get(block)->mtime_nsec
|
||||
|| handle[j].st.st_ino != block_file_get(block)->inode
|
||||
) {
|
||||
if (handle[j].st.st_size != block_file_get(block)->size)
|
||||
fprintf(stderr, "Unexpected size change at file '%s'.\n", handle[j].path);
|
||||
else if (handle[j].st.st_mtime != block_file_get(block)->mtime_sec
|
||||
|| handle[j].st.st_mtim.tv_nsec != block_file_get(block)->mtime_nsec)
|
||||
|| STAT_NSEC(&handle[j].st) != block_file_get(block)->mtime_nsec)
|
||||
fprintf(stderr, "Unexpected time change at file '%s'.\n", handle[j].path);
|
||||
else
|
||||
fprintf(stderr, "Unexpected inode change from %"PRIu64" to %"PRIu64" at file '%s'.\n", block_file_get(block)->inode, handle[j].st.st_ino, handle[j].path);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue