Merge branch 'b4'

This commit is contained in:
Andrea Mazzoleni 2013-09-24 21:45:57 +02:00
commit f3eb9d9d22
6 changed files with 49 additions and 35 deletions

View file

@ -14,8 +14,10 @@ SnapRAID HISTORY
4.1 2013/9 (BETA)
=================
* If the underline filesystem doesn't support the FIEMAP command,
fallback to use the inode number for sorting files.
This happens with reiserfs in Linux.
automatically fallback to use FIBMAP and then the inode number for sorting
files.
* Fixes the import of content files from previous version of SnapRAID that
are the result of an incomplete sync.
* Added a new -C, --gen-conf option to generate a dummy configuration
file from the info in the content file.
Just in case that you lose everything, except the content file.
@ -38,7 +40,7 @@ SnapRAID HISTORY
This happens only if the file has the same path, size and timestamp
at nanosecond precision.
* Added a hash seed to make harder intentional collision attacks.
* When insering files for the first time, sort them by their physical
* When inserting files for the first time, sort them by their physical
address to improve read performance.
* Optimized the cache use for the all the RAID computations.
This improves a lot the RAID performance.

2
elem.c
View file

@ -583,7 +583,7 @@ int disk_is_empty(struct snapraid_disk* disk, block_off_t blockmax)
/* if there is a deleted block, the disk is not empty */
return 0;
default:
fprintf(stderr, "Internal incosistency for used block in disk '%s' without files\n", disk->name);
fprintf(stderr, "Internal inconsistency for used block in disk '%s' without files\n", disk->name);
exit(EXIT_FAILURE);
}
}

View file

@ -66,7 +66,7 @@ void state_rehash(struct snapraid_state* state)
}
if (info_get_rehash(info)) {
fprintf(stderr, "Internal incosistency for a rehash already in progress\n");
fprintf(stderr, "Internal inconsistency for a rehash already in progress\n");
exit(EXIT_FAILURE);
}

2
scan.c
View file

@ -919,6 +919,8 @@ void state_scan(struct snapraid_state* state, int output)
}
/* sort the files before inserting them */
/* we use a stable sort to ensure that if the reported physical offset/inode */
/* are always 0, we keep at least the directory order */
switch (state->opt.force_order) {
case SORT_PHYSICAL :
tommy_list_sort(&scan->file_insert_list, file_physical_compare);

22
state.c
View file

@ -770,7 +770,7 @@ static void state_map(struct snapraid_state* state)
}
if (j==0) {
fprintf(stderr, "Internal incosistency for mapping '%s'\n", map->name);
fprintf(stderr, "Internal inconsistency for mapping '%s'\n", map->name);
exit(EXIT_FAILURE);
}
@ -1075,7 +1075,7 @@ static void state_read_text(struct snapraid_state* state, const char* path, STRE
rehash = 1;
if (state->prevhash == HASH_UNDEFINED) {
fprintf(stderr, "Internal incosistency for missing previous checksum in '%s' at line %u\n", path, line);
fprintf(stderr, "Internal inconsistency for missing previous checksum in '%s' at line %u\n", path, line);
exit(EXIT_FAILURE);
}
} else {
@ -1115,10 +1115,6 @@ static void state_read_text(struct snapraid_state* state, const char* path, STRE
deleted->block.parity_pos = v_pos;
/* keep track of the max block number used in parity */
if (v_pos + 1 > blockmax)
blockmax = v_pos + 1;
/* read the hash */
c = sgetc(f);
if (c != ' ') {
@ -1638,7 +1634,7 @@ static void state_read_text(struct snapraid_state* state, const char* path, STRE
/* check that the stored parity size matches the loaded state */
if (blockmax != parity_size(state)) {
fprintf(stderr, "Internal incosistency in parity size in '%s' at line %u\n", path, line);
fprintf(stderr, "Internal inconsistency in parity size in '%s' at line %u\n", path, line);
exit(EXIT_FAILURE);
}
state->loaded_blockmax = blockmax;
@ -1746,7 +1742,7 @@ static void state_write_text(struct snapraid_state* state, STREAM* f)
/* find the disk for this mapping */
disk = find_disk(state, map->name);
if (!disk) {
fprintf(stderr, "Internal incosistency for unmapped disk '%s'\n", map->name);
fprintf(stderr, "Internal inconsistency for unmapped disk '%s'\n", map->name);
exit(EXIT_FAILURE);
}
@ -2305,7 +2301,7 @@ static void state_read_binary(struct snapraid_state* state, const char* path, ST
if (rehash && state->prevhash == HASH_UNDEFINED) {
decoding_error(path, f);
fprintf(stderr, "Internal incosistency for missing previous checksum!\n");
fprintf(stderr, "Internal inconsistency for missing previous checksum!\n");
exit(EXIT_FAILURE);
}
@ -2322,13 +2318,13 @@ static void state_read_binary(struct snapraid_state* state, const char* path, ST
if (position_has_any_hash(state, v_pos)) {
if (!info) {
decoding_error(path, f);
fprintf(stderr, "Internal incosistency for missing info!\n");
fprintf(stderr, "Internal inconsistency for missing info!\n");
exit(EXIT_FAILURE);
}
} else {
if (info) {
decoding_error(path, f);
fprintf(stderr, "Internal incosistency for unexpected info!\n");
fprintf(stderr, "Internal inconsistency for unexpected info!\n");
exit(EXIT_FAILURE);
}
}
@ -2689,7 +2685,7 @@ static void state_read_binary(struct snapraid_state* state, const char* path, ST
/* check that the stored parity size matches the loaded state */
if (blockmax != parity_size(state)) {
fprintf(stderr, "Internal incosistency in parity size in '%s' at offset %"PRIi64"\n", path, stell(f));
fprintf(stderr, "Internal inconsistency in parity size in '%s' at offset %"PRIi64"\n", path, stell(f));
exit(EXIT_FAILURE);
}
state->loaded_blockmax = blockmax;
@ -2810,7 +2806,7 @@ static void state_write_binary(struct snapraid_state* state, STREAM* f)
/* find the disk for this mapping */
disk = find_disk(state, map->name);
if (!disk) {
fprintf(stderr, "Internal incosistency for unmapped disk '%s'\n", map->name);
fprintf(stderr, "Internal inconsistency for unmapped disk '%s'\n", map->name);
exit(EXIT_FAILURE);
}

48
unix.c
View file

@ -129,43 +129,57 @@ int filephy(const char* path, struct stat* st, uint64_t* physical)
/* In Linux gets the real physical address of the file */
/* Note that FIEMAP doesn't require root permission */
int f;
struct {
struct fiemap fiemap;
struct fiemap_extent extent;
} fm;
unsigned int blknum;
f = open(path, O_RDONLY);
if (f == -1) {
return -1;
}
/* first try with FIEMAP */
/* if works for ext2, ext3, ext4, xfs */
memset(&fm, 0, sizeof(fm));
fm.fiemap.fm_start = 0;
fm.fiemap.fm_length = ~0ULL;
fm.fiemap.fm_flags = FIEMAP_FLAG_SYNC; /* required to ensure that just created files report a valid address and not 0 */
fm.fiemap.fm_extent_count = 1; /* we are interested only at the first block */
if (ioctl(f, FS_IOC_FIEMAP, &fm) == -1) {
/* if the underline filesystem doesn't support FS_IOC_FIEMAP */
/* fallback to use the inode */
if (errno == ENOTSUP) {
close(f);
*physical = st->st_ino;
return 0;
}
close(f);
return -1;
if (ioctl(f, FS_IOC_FIEMAP, &fm) == 0) {
*physical = fm.fiemap.fm_extents[0].fe_physical;
if (close(f) == -1)
return -1;
return 0;
}
*physical = fm.fiemap.fm_extents[0].fe_physical;
if (close(f) == -1) {
return -1;
/* if empty, FIBMAP doesn't work */
if (st->st_size == 0) {
*physical = 0;
if (close(f) == -1)
return -1;
return 0;
}
(void)st; /* not used here */
/* then try with FIBMAP */
/* it works for jfs, reiserfs, ntfs-3g */
/* in exfat it always returns 0, that it's anyway better than the fake inodes */
blknum = 0; /* first block */
if (ioctl(f, FIBMAP, &blknum) == 0) {
*physical = blknum;
if (close(f) == -1)
return -1;
return 0;
}
/* otherwise don't use anything, and keep the existing order */
/* at now this should happen only for vfat */
/* and it's surely better than using fake inodes */
*physical = 0;
if (close(f) == -1)
return -1;
#else
/* In a generic Unix uses the inode as fake physical address */
*physical = st->st_ino;