diff --git a/Makefile.am b/Makefile.am index c406f2b7..5b7b35d6 100644 --- a/Makefile.am +++ b/Makefile.am @@ -229,7 +229,8 @@ endif $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) -a check echo -- Filesystem allocation test head -c 8192 /dev/zero > bench/disk1/TEST - head -c 8192 /dev/zero > bench/disk2/TEST +# Copy the file to trigger the copy optimization check + cp -a bench/disk1/TEST bench/disk2/TEST $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) sync # Now delete the file, and do a partial sync to force a deallocation in the middle of a file rm bench/disk1/TEST @@ -251,7 +252,7 @@ endif rm bench/disk1/TEST3 rm bench/disk1/TEST5 head -c 65536 /dev/zero > bench/disk1/TESTX - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) sync + $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) sync -l ">&1" rm -r bench/disk1/TEST* $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) -E sync echo --- Create some files diff --git a/cmdline/scan.c b/cmdline/scan.c index 517a9971..186d909f 100644 --- a/cmdline/scan.c +++ b/cmdline/scan.c @@ -398,12 +398,26 @@ static int file_is_full_hashed_and_stable(struct snapraid_state* state, struct s for (i = 0; i < file->blockmax; ++i) { snapraid_info info; struct snapraid_block* block = fs_file2block_get(file, i); - block_off_t parity_pos = fs_file2par_get(disk, file, i); + block_off_t parity_pos; /* exclude blocks without hash */ if (!block_has_updated_hash(block)) return 0; + /* + * Get the parity position, but only AFTER checking + * that the file has an updated hash. + * This is required because not hashed files may be + * not yet mapped into parity. + * + * This happens when a new file is in the delayed insertion + * list, and scan finds a copy of it, and it tries to copy + * the hash info. + * As just allocated files have only CHG blocks, checking that + * the hash is updated is enough to exclude such cases. + */ + parity_pos = fs_file2par_get(disk, file, i); + /* get block specific info */ info = info_get(&state->infoarr, parity_pos);