From 04c277f9252a8903fdc9a14abc3999345df38f94 Mon Sep 17 00:00:00 2001 From: Andrea Mazzoleni Date: Fri, 13 Jul 2012 20:53:57 +0200 Subject: [PATCH] Automatically convert old content files to the new nanosecond format. --- elem.h | 8 +++++++- scan.c | 15 ++++++++++++++- state.c | 6 +++++- 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/elem.h b/elem.h index 1805736c..baba9e06 100644 --- a/elem.h +++ b/elem.h @@ -136,6 +136,12 @@ struct snapraid_block { #define FILE_IS_DAMAGED 8 /**< If a fix was attempted but it failed. */ #define FILE_IS_FIXED 16 /**< If a fix was done. */ +/** + * Value used to mark files without the nanoseconds value. + * Note that this value is never reported by stat(). + */ +#define FILE_MTIME_NSEC_INVALID -1 + /** * File. */ @@ -144,7 +150,7 @@ struct snapraid_file { uint64_t inode; /**< Inode. */ data_off_t size; /**< Size of the file. */ struct snapraid_block* blockvec; /**< All the blocks of the file. */ - int mtime_nsec; /**< Modification time nanoseconds. Less than 1000000000. */ + int mtime_nsec; /**< Modification time nanoseconds. In the range 0 <= x < 1,000,000,000, or FILE_MTIME_NSEC_INVALID. */ block_off_t blockmax; /**< Number of blocks. */ unsigned flag; /**< FILE_IS_* flags. */ char sub[PATH_MAX]; /**< Sub path of the file. Without the disk dir. The disk is implicit. */ diff --git a/scan.c b/scan.c index c69b9fd5..7582dd37 100644 --- a/scan.c +++ b/scan.c @@ -172,10 +172,23 @@ static void scan_file(struct snapraid_scan* scan, struct snapraid_state* state, } /* check if the file is not changed */ - if (file->size == st->st_size && file->mtime_sec == st->st_mtime && file->mtime_nsec == st->st_mtim.tv_nsec) { + if (file->size == st->st_size + && 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) + ) { /* 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; + + /* we have to save the new mtime */ + state->need_write = 1; + } + if (strcmp(file->sub, sub) != 0) { /* if the path is different, it means a moved file with the same inode */ ++scan->count_moved; diff --git a/state.c b/state.c index 6433f059..d38975bd 100644 --- a/state.c +++ b/state.c @@ -887,7 +887,7 @@ void state_read(struct snapraid_state* state) hash = oathash64(hash, v_mtime_sec); c = sgetc(f); - if (c == '.') { /* the nanosecond field is present only from version 1.13 */ + if (c == '.') { /* the nanosecond field is present only from version 1.12 */ ret = sgetu32(f, &v_mtime_nsec); if (ret < 0) { fprintf(stderr, "Invalid 'file' specification in '%s' at line %u\n", path, line); @@ -896,7 +896,11 @@ void state_read(struct snapraid_state* state) hash = oathash32(hash, v_mtime_nsec); c = sgetc(f); + } else { + /* 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);