Compare commits
1 Commits
upstream/1
...
debian/11.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2e8fba7836 |
10
HISTORY
10
HISTORY
@@ -1,16 +1,6 @@
|
||||
SnapRAID HISTORY
|
||||
================
|
||||
|
||||
11.3 2018/11
|
||||
============
|
||||
* Fixed handing of Linux devices that have multiple slaves. This affects
|
||||
the smart/list/devices/down commands [Valentin Hilbig].
|
||||
* The 'list' command in verbose mode prints the full nanosecond
|
||||
timestamp precision.
|
||||
* After writing content files also sync their directory.
|
||||
* Fix a invalid time computation that could result in future scrub dates.
|
||||
Such dates are fixed automatically at the next scrub or sync.
|
||||
|
||||
11.2 2017/12
|
||||
============
|
||||
* Fixed recognition of NTFS hardlinks. They behave differently than
|
||||
|
||||
16
TODO
16
TODO
@@ -17,18 +17,6 @@ Not checked disks should be allowed to be missing.
|
||||
* Add an option to ignore subsecond timestamp.
|
||||
Like when you copy data to a filesystem with less timestamp precision.
|
||||
|
||||
* Use threads to scan all the disks at the same time.
|
||||
- After 7.0 Windows changes it seems fast enough even
|
||||
with a mono thread implementation with 100.0000 files.
|
||||
+ But if you have millions of files, it could take minutes.
|
||||
|
||||
* Support more parity levels
|
||||
It can be done with a generic computation function, using
|
||||
intrinsic for SSSE3 and AVX instructions.
|
||||
It would be intersting to compare performance with the hand-written
|
||||
assembler functions. Eventially we can convert them to use intrinsic also.
|
||||
https://sourceforge.net/p/snapraid/discussion/1677233/thread/9dbd7581/
|
||||
|
||||
* Extend haspdeep to support the SnapRAID hash :
|
||||
https://github.com/jessek/hashdeep/
|
||||
https://sourceforge.net/p/snapraid/discussion/1677233/thread/90b0e9b2/?limit=25
|
||||
@@ -234,6 +222,10 @@ and if we manage to keep it in the cache, we should save time.
|
||||
- We now hash first the faster disks, and this could
|
||||
reduce performance as we'll have to wait for all disks.
|
||||
|
||||
* Use threads to scan all the disks at the same time.
|
||||
- After 7.0 Windows changes it seems fast enough even
|
||||
with a mono thread implementation.
|
||||
|
||||
* Enable storing of creation time NTFS, crtime/birth time EXT4.
|
||||
But see: http://unix.stackexchange.com/questions/50177/birth-is-empty-on-ext4
|
||||
coreutils stat has an example, but it doesn't work in Linux (see lib/stat-time.h)
|
||||
|
||||
@@ -889,7 +889,7 @@ void io_init(struct snapraid_io* io, struct snapraid_state* state,
|
||||
allocated += state->block_size * buffer_max;
|
||||
}
|
||||
|
||||
msg_progress("Using %u MiB of memory for %u cached blocks.\n", (unsigned)(allocated / MEBI), io->io_max);
|
||||
msg_progress("Using %u MiB of memory for %u blocks of IO cache.\n", (unsigned)(allocated / MEBI), io->io_max);
|
||||
|
||||
if (parity_writer) {
|
||||
io->reader_max = handle_max;
|
||||
|
||||
@@ -74,7 +74,7 @@ void state_list(struct snapraid_state* state)
|
||||
if (tm) {
|
||||
printf("%04u/%02u/%02u %02u:%02u", tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min);
|
||||
if (msg_level >= MSG_VERBOSE)
|
||||
printf(":%02u.%09u", tm->tm_sec, file->mtime_nsec);
|
||||
printf(":%02u.%03u", tm->tm_sec, file->mtime_nsec / 1000000);
|
||||
printf(" ");
|
||||
}
|
||||
printf("%s\n", fmt_term(disk, file->sub, esc_buffer));
|
||||
@@ -105,7 +105,7 @@ void state_list(struct snapraid_state* state)
|
||||
printf("%12s ", type);
|
||||
printf(" ");
|
||||
if (msg_level >= MSG_VERBOSE)
|
||||
printf(" ");
|
||||
printf(" ");
|
||||
printf("%s -> %s\n", fmt_term(disk, slink->sub, esc_buffer), fmt_term(disk, slink->linkto, esc_buffer_alt));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -694,7 +694,6 @@ static void windows_errno(DWORD error)
|
||||
errno = EPERM;
|
||||
break;
|
||||
case ERROR_IO_DEVICE : /* in ReadFile() and WriteFile() */
|
||||
case ERROR_CRC : /* in ReadFile() */
|
||||
errno = EIO;
|
||||
break;
|
||||
default :
|
||||
|
||||
@@ -41,7 +41,6 @@ void test(void)
|
||||
s = sopen_multi_write(STREAM_MAX);
|
||||
for (i = 0; i < STREAM_MAX; ++i) {
|
||||
snprintf(file, sizeof(file), "stream%u.bin", i);
|
||||
remove(file);
|
||||
if (sopen_multi_file(s, i, file) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
exit(EXIT_FAILURE);
|
||||
|
||||
@@ -136,29 +136,25 @@ void MurmurHash3_x86_128(const void* data, size_t size, const uint8_t* seed, voi
|
||||
uint32_t k4 = 0;
|
||||
|
||||
switch (size_remainder) {
|
||||
case 15 : k4 ^= (uint32_t)tail[14] << 16; /* fallthrough */
|
||||
case 14 : k4 ^= (uint32_t)tail[13] << 8; /* fallthrough */
|
||||
case 13 : k4 ^= (uint32_t)tail[12] << 0; /* fallthrough */
|
||||
case 15 : k4 ^= (uint32_t)tail[14] << 16;
|
||||
case 14 : k4 ^= (uint32_t)tail[13] << 8;
|
||||
case 13 : k4 ^= (uint32_t)tail[12] << 0;
|
||||
k4 *= c4; k4 = util_rotl32(k4, 18); k4 *= c1; h4 ^= k4;
|
||||
/* fallthrough */
|
||||
case 12 : k3 ^= (uint32_t)tail[11] << 24; /* fallthrough */
|
||||
case 11 : k3 ^= (uint32_t)tail[10] << 16; /* fallthrough */
|
||||
case 10 : k3 ^= (uint32_t)tail[ 9] << 8; /* fallthrough */
|
||||
case 9 : k3 ^= (uint32_t)tail[ 8] << 0; /* fallthrough */
|
||||
case 12 : k3 ^= (uint32_t)tail[11] << 24;
|
||||
case 11 : k3 ^= (uint32_t)tail[10] << 16;
|
||||
case 10 : k3 ^= (uint32_t)tail[ 9] << 8;
|
||||
case 9 : k3 ^= (uint32_t)tail[ 8] << 0;
|
||||
k3 *= c3; k3 = util_rotl32(k3, 17); k3 *= c4; h3 ^= k3;
|
||||
/* fallthrough */
|
||||
case 8 : k2 ^= (uint32_t)tail[ 7] << 24; /* fallthrough */
|
||||
case 7 : k2 ^= (uint32_t)tail[ 6] << 16; /* fallthrough */
|
||||
case 6 : k2 ^= (uint32_t)tail[ 5] << 8; /* fallthrough */
|
||||
case 5 : k2 ^= (uint32_t)tail[ 4] << 0; /* fallthrough */
|
||||
case 8 : k2 ^= (uint32_t)tail[ 7] << 24;
|
||||
case 7 : k2 ^= (uint32_t)tail[ 6] << 16;
|
||||
case 6 : k2 ^= (uint32_t)tail[ 5] << 8;
|
||||
case 5 : k2 ^= (uint32_t)tail[ 4] << 0;
|
||||
k2 *= c2; k2 = util_rotl32(k2, 16); k2 *= c3; h2 ^= k2;
|
||||
/* fallthrough */
|
||||
case 4 : k1 ^= (uint32_t)tail[ 3] << 24; /* fallthrough */
|
||||
case 3 : k1 ^= (uint32_t)tail[ 2] << 16; /* fallthrough */
|
||||
case 2 : k1 ^= (uint32_t)tail[ 1] << 8; /* fallthrough */
|
||||
case 1 : k1 ^= (uint32_t)tail[ 0] << 0; /* fallthrough */
|
||||
case 4 : k1 ^= (uint32_t)tail[ 3] << 24;
|
||||
case 3 : k1 ^= (uint32_t)tail[ 2] << 16;
|
||||
case 2 : k1 ^= (uint32_t)tail[ 1] << 8;
|
||||
case 1 : k1 ^= (uint32_t)tail[ 0] << 0;
|
||||
k1 *= c1; k1 = util_rotl32(k1, 15); k1 *= c2; h1 ^= k1;
|
||||
/* fallthrough */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ void memory(void)
|
||||
log_tag("memory:link:%" PRIu64 "\n", (uint64_t)(sizeof(struct snapraid_link)));
|
||||
log_tag("memory:dir:%" PRIu64 "\n", (uint64_t)(sizeof(struct snapraid_dir)));
|
||||
|
||||
msg_progress("Using %u MiB of memory for the file-system.\n", (unsigned)(malloc_counter_get() / MEBI));
|
||||
msg_progress("Using %u MiB of memory for the FileSystem.\n", (unsigned)(malloc_counter_get() / MEBI));
|
||||
}
|
||||
|
||||
void test(int argc, char* argv[])
|
||||
@@ -1091,7 +1091,7 @@ int main(int argc, char* argv[])
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
/* fallthrough */
|
||||
/* follow */
|
||||
case OPERATION_SPINUP :
|
||||
case OPERATION_SPINDOWN :
|
||||
if (!tommy_list_empty(&filterlist_file)) {
|
||||
|
||||
103
cmdline/state.c
103
cmdline/state.c
@@ -2872,7 +2872,6 @@ struct state_write_thread_context {
|
||||
/* input */
|
||||
block_off_t blockmax;
|
||||
time_t info_oldest;
|
||||
time_t info_now;
|
||||
int info_has_rehash;
|
||||
STREAM* f;
|
||||
/* output */
|
||||
@@ -2889,7 +2888,6 @@ static void* state_write_thread(void* arg)
|
||||
struct snapraid_state* state = context->state;
|
||||
block_off_t blockmax = context->blockmax;
|
||||
time_t info_oldest = context->info_oldest;
|
||||
time_t info_now = context->info_now;
|
||||
int info_has_rehash = context->info_has_rehash;
|
||||
STREAM* f = context->f;
|
||||
uint32_t crc;
|
||||
@@ -3280,18 +3278,7 @@ static void* state_write_thread(void* arg)
|
||||
flag |= 8;
|
||||
sputb32(flag, f);
|
||||
|
||||
t = info_get_time(info);
|
||||
|
||||
/* truncate any time that is in the future */
|
||||
if (t > info_now)
|
||||
t = info_now;
|
||||
|
||||
/* the oldest info is computed only on required blocks, so it may not be the absolute oldest */
|
||||
if (t < info_oldest)
|
||||
t = 0;
|
||||
else
|
||||
t -= info_oldest;
|
||||
|
||||
t = info_get_time(info) - info_oldest;
|
||||
sputb32(t, f);
|
||||
} else {
|
||||
/* write a special 0 flag to mark missing info */
|
||||
@@ -3366,7 +3353,6 @@ static void state_write_content(struct snapraid_state* state, uint32_t* out_crc)
|
||||
tommy_node* i;
|
||||
block_off_t blockmax;
|
||||
time_t info_oldest;
|
||||
time_t info_now;
|
||||
int info_has_rehash;
|
||||
int mapping_idx;
|
||||
block_off_t idx;
|
||||
@@ -3385,7 +3371,6 @@ static void state_write_content(struct snapraid_state* state, uint32_t* out_crc)
|
||||
/* clear the info for unused blocks */
|
||||
/* and get some other info */
|
||||
info_oldest = 0; /* oldest time in info */
|
||||
info_now = time(0); /* get the present time */
|
||||
info_has_rehash = 0; /* if there is a rehash info */
|
||||
for (idx = 0; idx < blockmax; ++idx) {
|
||||
/* if the position is used */
|
||||
@@ -3449,21 +3434,10 @@ static void state_write_content(struct snapraid_state* state, uint32_t* out_crc)
|
||||
msg_progress("Saving state to %s...\n", content->content);
|
||||
|
||||
pathprint(tmp, sizeof(tmp), "%s.tmp", content->content);
|
||||
|
||||
/* ensure to delete a previous stale file */
|
||||
if (remove(tmp) != 0) {
|
||||
if (errno != ENOENT) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error removing the stale content file '%s'. %s.\n", tmp, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
|
||||
f = sopen_write(tmp);
|
||||
if (f == 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error opening the temporary content file '%s'. %s.\n", tmp, strerror(errno));
|
||||
log_fatal("Error opening the content file '%s'. %s.\n", tmp, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
@@ -3476,7 +3450,6 @@ static void state_write_content(struct snapraid_state* state, uint32_t* out_crc)
|
||||
context->state = state;
|
||||
context->blockmax = blockmax;
|
||||
context->info_oldest = info_oldest;
|
||||
context->info_now = info_now;
|
||||
context->info_has_rehash = info_has_rehash;
|
||||
context->f = f;
|
||||
|
||||
@@ -3589,24 +3562,12 @@ static void state_write_content(struct snapraid_state* state, uint32_t* out_crc)
|
||||
struct snapraid_content* content = i->data;
|
||||
char tmp[PATH_MAX];
|
||||
pathprint(tmp, sizeof(tmp), "%s.tmp", content->content);
|
||||
|
||||
/* ensure to delete a previous stale file */
|
||||
if (remove(tmp) != 0) {
|
||||
if (errno != ENOENT) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error removing the stale content file '%s'. %s.\n", tmp, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
|
||||
if (sopen_multi_file(f, k, tmp) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error opening the temporary content file '%s'. %s.\n", tmp, strerror(errno));
|
||||
log_fatal("Error opening the content file '%s'. %s.\n", tmp, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
++k;
|
||||
i = i->next;
|
||||
}
|
||||
@@ -3618,7 +3579,6 @@ static void state_write_content(struct snapraid_state* state, uint32_t* out_crc)
|
||||
context->state = state;
|
||||
context->blockmax = blockmax;
|
||||
context->info_oldest = info_oldest;
|
||||
context->info_now = info_now;
|
||||
context->info_has_rehash = info_has_rehash;
|
||||
context->f = f;
|
||||
|
||||
@@ -3891,10 +3851,11 @@ static void state_verify_content(struct snapraid_state* state, uint32_t crc)
|
||||
msg_progress("Verifying %s...\n", content->content);
|
||||
|
||||
pathprint(tmp, sizeof(tmp), "%s.tmp", content->content);
|
||||
|
||||
f = sopen_read(tmp);
|
||||
if (f == 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error reopening the temporary content file '%s'. %s.\n", tmp, strerror(errno));
|
||||
log_fatal("Error reopening the content file '%s'. %s.\n", tmp, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
@@ -3963,59 +3924,6 @@ static void state_rename_content(struct snapraid_state* state)
|
||||
{
|
||||
tommy_node* i;
|
||||
|
||||
#if defined(_linux) /* this sequence is linux specific */
|
||||
i = tommy_list_head(&state->contentlist);
|
||||
while (i) {
|
||||
struct snapraid_content* content = i->data;
|
||||
char tmp[PATH_MAX];
|
||||
char dir[PATH_MAX];
|
||||
char* slash;
|
||||
int handle;
|
||||
|
||||
pathcpy(dir, sizeof(dir), content->content);
|
||||
|
||||
slash = strrchr(tmp, '/');
|
||||
if (slash)
|
||||
*slash = 0;
|
||||
else
|
||||
pathcpy(dir, sizeof(dir), ".");
|
||||
|
||||
/* open the directory to get the handle */
|
||||
handle = open(dir, O_RDONLY | O_DIRECTORY);
|
||||
if (handle < 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error opening the directory '%s'. %s.\n", dir, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
/* now rename the just written copy with the correct name */
|
||||
pathprint(tmp, sizeof(tmp), "%s.tmp", content->content);
|
||||
if (rename(tmp, content->content) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error renaming the content file '%s' to '%s'. %s.\n", tmp, content->content, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
/* sync the directory */
|
||||
if (fsync(handle) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error syncing the directory '%s'. %s.\n", dir, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
if (close(handle) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error closing the directory '%s'. %s.\n", dir, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
i = i->next;
|
||||
}
|
||||
#else
|
||||
i = tommy_list_head(&state->contentlist);
|
||||
while (i) {
|
||||
struct snapraid_content* content = i->data;
|
||||
@@ -4032,7 +3940,6 @@ static void state_rename_content(struct snapraid_state* state)
|
||||
|
||||
i = i->next;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void state_write(struct snapraid_state* state)
|
||||
|
||||
@@ -29,10 +29,6 @@
|
||||
|
||||
unsigned day_ago(time_t ref, time_t now)
|
||||
{
|
||||
/* in case some dates is in the future */
|
||||
if (now < ref)
|
||||
return 0;
|
||||
|
||||
return (now - ref) / (24 * 3600);
|
||||
}
|
||||
|
||||
@@ -462,10 +458,6 @@ int state_status(struct snapraid_state* state)
|
||||
|
||||
printf("\n");
|
||||
|
||||
if (newest > now) {
|
||||
printf("WARNING! You have scrub dates in the future! The next sync/scrub will truncate them!\n");
|
||||
}
|
||||
|
||||
if (unsynced_blocks) {
|
||||
printf("WARNING! The array is NOT fully synced.\n");
|
||||
printf("You have a sync in progress at %u%%.\n", (blockmax - unsynced_blocks) * 100 / blockmax);
|
||||
|
||||
@@ -112,8 +112,7 @@ int sopen_multi_file(STREAM* s, unsigned i, const char* file)
|
||||
|
||||
pathcpy(s->handle[i].path, sizeof(s->handle[i].path), file);
|
||||
|
||||
/* O_EXCL to be resilent ensure to always create a new file and not use a stale link to the original file */
|
||||
f = open(file, O_WRONLY | O_CREAT | O_EXCL | O_BINARY | O_SEQUENTIAL, 0600);
|
||||
f = open(file, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_SEQUENTIAL, 0600);
|
||||
if (f == -1) {
|
||||
/* LCOV_EXCL_START */
|
||||
return -1;
|
||||
|
||||
@@ -299,8 +299,6 @@ void pathslash(char* dst, size_t size);
|
||||
|
||||
/**
|
||||
* Cut everything after the latest slash.
|
||||
*
|
||||
* If the string doesn't contain any slash, it returns the empty string.
|
||||
*/
|
||||
void pathcut(char* dst);
|
||||
|
||||
|
||||
@@ -1536,7 +1536,7 @@ int state_sync(struct snapraid_state* state, block_off_t blockstart, block_off_t
|
||||
data_off_t out_size;
|
||||
parity_size(&parity_handle[l], &out_size);
|
||||
parity_overflow(state, out_size);
|
||||
log_fatal("WARNING! Without an usable %s file, it isn't possible to sync.\n", lev_name(l));
|
||||
log_fatal("WARNING! Without an unsable %s file, it isn't possible to sync.\n", lev_name(l));
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
@@ -917,20 +917,18 @@ static int devtree(const char* name, const char* custom, dev_t device, devinfo_t
|
||||
|
||||
while ((dd = readdir(d)) != 0) {
|
||||
if (dd->d_name[0] != '.') {
|
||||
dev_t subdev;
|
||||
|
||||
/* for each slave, expand the full potential tree */
|
||||
pathprint(path, sizeof(path), "/sys/dev/block/%u:%u/slaves/%s/dev", major(device), minor(device), dd->d_name);
|
||||
|
||||
subdev = devread(path);
|
||||
if (!subdev) {
|
||||
device = devread(path);
|
||||
if (!device) {
|
||||
/* LCOV_EXCL_START */
|
||||
closedir(d);
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
if (devtree(name, custom, subdev, parent, list) != 0) {
|
||||
if (devtree(name, custom, device, parent, list) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
closedir(d);
|
||||
return -1;
|
||||
@@ -1074,8 +1072,8 @@ static int devscan(tommy_list* list)
|
||||
#if HAVE_LINUX_DEVICE
|
||||
static int devsmart(dev_t device, const char* name, const char* custom, uint64_t* smart, char* serial, char* vendor, char* model)
|
||||
{
|
||||
char cmd[PATH_MAX + 64];
|
||||
char file[PATH_MAX];
|
||||
char cmd[128];
|
||||
char file[128];
|
||||
FILE* f;
|
||||
int ret;
|
||||
|
||||
@@ -1088,7 +1086,7 @@ static int devsmart(dev_t device, const char* name, const char* custom, uint64_t
|
||||
|
||||
/* if there is a custom command */
|
||||
if (custom[0]) {
|
||||
char option[PATH_MAX];
|
||||
char option[128];
|
||||
snprintf(option, sizeof(option), custom, file);
|
||||
snprintf(cmd, sizeof(cmd), "smartctl -a %s", option);
|
||||
} else {
|
||||
@@ -1142,8 +1140,8 @@ static int devsmart(dev_t device, const char* name, const char* custom, uint64_t
|
||||
#if HAVE_LINUX_DEVICE
|
||||
static int devdown(dev_t device, const char* name, const char* custom)
|
||||
{
|
||||
char cmd[PATH_MAX + 64];
|
||||
char file[PATH_MAX];
|
||||
char cmd[128];
|
||||
char file[128];
|
||||
FILE* f;
|
||||
int ret;
|
||||
|
||||
@@ -1156,7 +1154,7 @@ static int devdown(dev_t device, const char* name, const char* custom)
|
||||
|
||||
/* if there is a custom command */
|
||||
if (custom[0]) {
|
||||
char option[PATH_MAX];
|
||||
char option[128];
|
||||
snprintf(option, sizeof(option), custom, file);
|
||||
snprintf(cmd, sizeof(cmd), "smartctl -s standby,now %s", option);
|
||||
} else {
|
||||
|
||||
20
configure
vendored
20
configure
vendored
@@ -1,6 +1,6 @@
|
||||
#! /bin/sh
|
||||
# Guess values for system-dependent variables and create Makefiles.
|
||||
# Generated by GNU Autoconf 2.69 for snapraid 11.3.
|
||||
# Generated by GNU Autoconf 2.69 for snapraid 11.2.
|
||||
#
|
||||
#
|
||||
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
|
||||
@@ -577,8 +577,8 @@ MAKEFLAGS=
|
||||
# Identity of this package.
|
||||
PACKAGE_NAME='snapraid'
|
||||
PACKAGE_TARNAME='snapraid'
|
||||
PACKAGE_VERSION='11.3'
|
||||
PACKAGE_STRING='snapraid 11.3'
|
||||
PACKAGE_VERSION='11.2'
|
||||
PACKAGE_STRING='snapraid 11.2'
|
||||
PACKAGE_BUGREPORT=''
|
||||
PACKAGE_URL='http://www.snapraid.it'
|
||||
|
||||
@@ -1304,7 +1304,7 @@ if test "$ac_init_help" = "long"; then
|
||||
# Omit some internal or obsolete options to make the list less imposing.
|
||||
# This message is too long to be a string in the A/UX 3.1 sh.
|
||||
cat <<_ACEOF
|
||||
\`configure' configures snapraid 11.3 to adapt to many kinds of systems.
|
||||
\`configure' configures snapraid 11.2 to adapt to many kinds of systems.
|
||||
|
||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||
|
||||
@@ -1374,7 +1374,7 @@ fi
|
||||
|
||||
if test -n "$ac_init_help"; then
|
||||
case $ac_init_help in
|
||||
short | recursive ) echo "Configuration of snapraid 11.3:";;
|
||||
short | recursive ) echo "Configuration of snapraid 11.2:";;
|
||||
esac
|
||||
cat <<\_ACEOF
|
||||
|
||||
@@ -1496,7 +1496,7 @@ fi
|
||||
test -n "$ac_init_help" && exit $ac_status
|
||||
if $ac_init_version; then
|
||||
cat <<\_ACEOF
|
||||
snapraid configure 11.3
|
||||
snapraid configure 11.2
|
||||
generated by GNU Autoconf 2.69
|
||||
|
||||
Copyright (C) 2012 Free Software Foundation, Inc.
|
||||
@@ -2102,7 +2102,7 @@ cat >config.log <<_ACEOF
|
||||
This file contains any messages produced by compilers while
|
||||
running configure, to aid debugging if configure makes a mistake.
|
||||
|
||||
It was created by snapraid $as_me 11.3, which was
|
||||
It was created by snapraid $as_me 11.2, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
$ $0 $@
|
||||
@@ -2965,7 +2965,7 @@ fi
|
||||
|
||||
# Define the identity of the package.
|
||||
PACKAGE='snapraid'
|
||||
VERSION='11.3'
|
||||
VERSION='11.2'
|
||||
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
@@ -7373,7 +7373,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
|
||||
# report actual input values of CONFIG_FILES etc. instead of their
|
||||
# values after options handling.
|
||||
ac_log="
|
||||
This file was extended by snapraid $as_me 11.3, which was
|
||||
This file was extended by snapraid $as_me 11.2, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
CONFIG_FILES = $CONFIG_FILES
|
||||
@@ -7436,7 +7436,7 @@ _ACEOF
|
||||
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
||||
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
|
||||
ac_cs_version="\\
|
||||
snapraid config.status 11.3
|
||||
snapraid config.status 11.2
|
||||
configured by $0, generated by GNU Autoconf 2.69,
|
||||
with options \\"\$ac_cs_config\\"
|
||||
|
||||
|
||||
686
debian/changelog
vendored
Normal file
686
debian/changelog
vendored
Normal file
@@ -0,0 +1,686 @@
|
||||
snapraid (11.2-0tikhonov1~xenial) xenial; urgency=medium
|
||||
|
||||
[11.2 2017/12]
|
||||
* Fixed recognition of NTFS hardlinks. They behave differently than
|
||||
standard Unix hardlinks and this could result in SnapRAID reporting
|
||||
internal inconsistency errors for detecting links to the same file
|
||||
with different metadata attributes.
|
||||
* More efficient 'pool' command that updates only the links
|
||||
that need to be updated. This ensures that no change is
|
||||
done, avoiding to trigger a directory rescan of other programs.
|
||||
* In Linux use by default the advise "discard" mode instead of "flush".
|
||||
This avoids to swap-out the other process memory, leaving the system
|
||||
more responsive.
|
||||
* Changed the fallocate() use to work better with Btrfs with parity disks.
|
||||
* Changed the --test-io-stats screen to print the file name in process
|
||||
for each disk.
|
||||
|
||||
-- Maxim Tikhonov <flaterichd@gmail.com> Wed, 18 Jul 2018 19:44:46 +0400
|
||||
|
||||
snapraid (11.1-0tikhonov1~trusty) trusty; urgency=medium
|
||||
|
||||
[11.1 2017/05]
|
||||
* Fixed the check command to correctly ignore errors on unused parity.
|
||||
This was broken in version 9.0.
|
||||
* Allow increasing the number of parity splits of existing parity.
|
||||
* Fixed quoting when printing in Linux. This fixes the UTF-8 screen
|
||||
output. Windows version was not affected.
|
||||
* Fixed recognition of 'hashsize' in the configuration file.
|
||||
The previous incorrect 'hash_size' is still supported for backward
|
||||
compatibility.
|
||||
* Fixed building in platforms that don't provide major/minor definitions
|
||||
in sys/types.h.
|
||||
* When creating 'pool' symbolic links, set their time as the linked files.
|
||||
* Added support for the Windows 10 symbolic link unprivileged creation,
|
||||
using SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE.
|
||||
* Windows binaries built with gcc 4.9.4 using the MXE cross compiler at
|
||||
commit ae56efa2b23a793b0146508bfef33027cdb09fd2 with targets
|
||||
i686-w64-mingw32 and x86_64-w64-mingw32 and optimization -O2.
|
||||
|
||||
-- Maxim Tikhonov <flaterichd@gmail.com> Mon, 28 Aug 2017 12:41:29 +0400
|
||||
|
||||
snapraid (11.0-0tikhonov1~trusty) trusty; urgency=medium
|
||||
|
||||
[11.0 2016/11]
|
||||
* Added support for splitting the parity in multiple partitions. You
|
||||
can now specify multiple files for a single parity. As soon a file
|
||||
cannot grow anymore, the next one starts growing.
|
||||
In the configuration file, just put more files in the same 'parity'
|
||||
line, separated by , (comma).
|
||||
Note that if this feature is used, the saved content file won't be
|
||||
read by older SnapRAID versions.
|
||||
In Windows, 256 MB are left free in each disk to avoid the warning
|
||||
about full disks.
|
||||
* Added a new 'hashsize' configuration option. It could be useful in
|
||||
systems with low memory, to reduce the memory usage.
|
||||
Note that if this feature is used, the saved content file won't be
|
||||
read by older SnapRAID versions.
|
||||
* In Linux added the missing support for Btrfs file-systems. Note that
|
||||
to have full support you need also the 'libblkid' library, otherwise
|
||||
you won't get the UUIDs.
|
||||
* In screen messages don't print the disk directory in file path. You
|
||||
can control the format with the test option:
|
||||
--test-fmt file|disk|path.
|
||||
* In Windows allows to use the escape char '^' to handle file patterns
|
||||
containing real characters matching the globbing '*?[]' ones. In Unix
|
||||
it was already possible to do the same escaping with '\'.
|
||||
* Added a new -R, --force-realloc option to reallocate all the
|
||||
parity information keeping the precomputed hash.
|
||||
This is the previous -F, --force-full that instead now maintains the
|
||||
same parity organization and just recomputes it.
|
||||
* Added test options for selecting the file advise mode to use:
|
||||
--test-io-advise-none for standard mode
|
||||
--test-io-advise-sequential advise sequential access (Linux/Windows)
|
||||
--test-io-advise-flush flush cache after every operation (Linux)
|
||||
--test-io-advise-flush-window flush cache every 8 MB (Linux)
|
||||
--test-io-advise-discard discard cache after every operation (Linux)
|
||||
--test-io-advise-discard-window discard cache every 8 MB (Linux)
|
||||
--test-io-advise-direct use direct/unbuffered mode (Linux/Windows)
|
||||
The new default mode is 'flush' in Linux (before it was 'sequential'),
|
||||
and 'sequential' in Windows (like before).
|
||||
* For Seagate SMR (Shingled Magnetic Recording) ignore the SMART
|
||||
attribute Command_Timeout 188 as not reliable.
|
||||
* Fixed running in Windows platforms that miss the RtlGenRandom()
|
||||
function.
|
||||
* Added the --test-io-cache=1 option to disable the multi-thread IO
|
||||
mode.
|
||||
|
||||
-- Maxim Tikhonov <flaterichd@gmail.com> Thu, 01 Dec 2016 16:25:21 +0400
|
||||
|
||||
snapraid (10.0-0tikhonov1~trusty) trusty; urgency=medium
|
||||
|
||||
[ 10.0 2016/02 ]
|
||||
* Boosts the speed of the 'sync' and 'scrub' commands with a new
|
||||
multi-thread implementation. It uses one thread for each disk,
|
||||
dedicated exclusively to read-ahead data and parity and to
|
||||
write-behind parity. This maximizes the data throughput keeping
|
||||
disks always busy.
|
||||
You can control the number of blocks to cache with the option
|
||||
--test-io-cache=NUMBER, where the number is between 3 and 128.
|
||||
The default is 8 MiB of blocks.
|
||||
You can show run-time stats during the process with the
|
||||
--test-io-stats option. You will see a graph with the number of
|
||||
cached blocks, and a graph with the wait time percentage for all the
|
||||
disks and computations.
|
||||
* The -h, --pre-hash command, saves the content file only after having
|
||||
verified all the hashes. This allows recovering of moved files in
|
||||
case a silent error is found during the hash verification check.
|
||||
* Allows to use the -d, --filter-disk option in the 'up' and 'down'
|
||||
commands.
|
||||
* Allows to run the 'smart' command without a configuration file.
|
||||
In such case it operates on all the disks of the machine.
|
||||
* In the configuration file 'data' is now a synonymous of 'disk'.
|
||||
* Adds the 'touch' command intended to arbitrarily set all the zero
|
||||
sub-second timestamps. This improves the SnapRAID capabilities to
|
||||
identify files. The 'status' command recommends to run 'touch' if
|
||||
required.
|
||||
* Restores the functionality of the -D, --force-device option when used
|
||||
to workaround the use of the same disk for two logical data drives
|
||||
when running the 'fix' command.
|
||||
* Uses a correct shell quoting in the example commands that involve
|
||||
files.
|
||||
* The minimum Windows version supported is now Windows Vista. This is
|
||||
required to use the native Windows thread support for the new
|
||||
multi-thread implementation. If you need to run on Windows XP, you
|
||||
have to stick on SnapRAID 9.x.
|
||||
|
||||
-- Maxim Tikhonov <flaterichd@gmail.com> Sat, 05 Mar 2016 17:44:53 +0400
|
||||
|
||||
snapraid (9.3-0tikhonov1~trusty) trusty; urgency=medium
|
||||
|
||||
[ 9.3 2016/01 ]
|
||||
* Fixes an invalid assumption in the copy detection mechanism that
|
||||
could result in an internal inconsistency, and with the impossibility
|
||||
to run the 'sync' and 'diff' commands.
|
||||
This was triggered by a very specific pattern of identical files.
|
||||
At least three of them, with one already in the parity, and at a
|
||||
higher disk number than the others that should be instead new ones.
|
||||
This had no bad effect, if not preventing the 'sync' command to run.
|
||||
A workaround was to just run 'sync' one time with the -N,
|
||||
--force-nocopy option to disable the copy detection.
|
||||
* Restored the -O2 optimization option for Windows binaries, as -Og has
|
||||
a too big performance penality.
|
||||
|
||||
[ 9.2 2016/01 ]
|
||||
* Fixes support for symlinks pointing to an empty target. Before they
|
||||
were only partially supported, and their presence could result in a
|
||||
content file not readable.
|
||||
This also disables multi-thread content write, as this was the issue
|
||||
we tried to detect with this feature, and it doesn't provide a
|
||||
performance advantage. Content verification is instead still multi
|
||||
thread.
|
||||
* Autorename disks using the matching UUID. To rename a disk you can
|
||||
now change directly the name in the configuration file, and run a
|
||||
'sync' command.
|
||||
* Improves the physical offset ordering for the Btrfs file-system,
|
||||
correctly detecting files that have not a physical offset, for
|
||||
whatever reason.
|
||||
* Adds UUID support to Btrfs file-systems. It's present only if the
|
||||
'libblkid' development library is available on the system.
|
||||
Usually this requires to install the libblkid-dev or libblkid-devel
|
||||
package.
|
||||
* Added a new --no-warnings option to disable some repetitive warnings
|
||||
that could be annoying to power users.
|
||||
* Improves the error reporting, printing a complete stack trace, that
|
||||
can be used to track down bugs more easily.
|
||||
For this reason the Windows binaries are now built with optimization
|
||||
option -Og, instead than -O2.
|
||||
|
||||
-- Maxim Tikhonov <flaterichd@gmail.com> Tue, 02 Feb 2016 12:59:13 +0400
|
||||
|
||||
snapraid (9.1-0tikhonov1~trusty) trusty; urgency=medium
|
||||
|
||||
[ 9.1 2015/11 ]
|
||||
* Fixes a bug when reading a content file with a deleted entry bigger
|
||||
than 4 GB. This was a regression introduced in version 9.0 that
|
||||
could result in the impossibility to read a valid content file,
|
||||
after a deletion of a file bigger than 4 GB in the array.
|
||||
If this happened to you, just upgrading to 9.1 fixes the issue, and
|
||||
it allows you to continue to work.
|
||||
Note that this bug only prevented to run 9.0, but your data was still
|
||||
protected and could have been recovered using the versions 8.1 or 9.1.
|
||||
* In Windows disables the file zero check requiring the --force-zero
|
||||
option. This check is intended for possible case using ext3/4 in Linux,
|
||||
and there is no evidence that in Windows it's possible at all.
|
||||
* Windows binaries built with gcc 4.9.3 using the MXE cross compiler at
|
||||
commit 62bcdbee56e87c81f1faa105b8777a5879d4e2e with targets
|
||||
i686-w64-mingw32 and x86_64-w64-mingw32 and optimization -O2.
|
||||
|
||||
[ 9.0 2015/11 ]
|
||||
* Fixes an invalid assumption that could happen when using the
|
||||
-e, --filter-error option with "fix" or "check".
|
||||
This was triggered by a very specific pattern of fragmented files
|
||||
and bad blocks combination, not so easy to reproduce.
|
||||
This had no bad effect, if not preventing the command to run.
|
||||
* Drastically reduces the memory usage. For each block, it now
|
||||
uses 17 bytes of memory, instead of the previous 28 bytes
|
||||
(for 32 bit) or 36 bytes (for 64 bit).
|
||||
This could result is a memory saving of up the 50%.
|
||||
* The -p, --plan option (old --percentage) can be used to
|
||||
define a scrub plan: "new", "bad" and "full".
|
||||
The "new" plan scrubs all the new synced blocks not yet scrubbed.
|
||||
This allows to verify as early as possible that the written
|
||||
parity during sync is really correct. You can use the "status"
|
||||
command to show the amount blocks not yet scrubbed.
|
||||
The "bad" plan scrubs only bad blocks.
|
||||
The "full" plan scrubs all blocks.
|
||||
* The graph in the "status" command now show scrubbed blocks
|
||||
with '*', and synced, but not yet scrubbed, blocks with 'o'.
|
||||
Note that when upgrading from a previous version, all blocks
|
||||
are assumed scrubbed the first time.
|
||||
* Content files are now written asyncronously from different
|
||||
threads to avoid the unfortunate condition that a memory
|
||||
error affects all of them in the same way.
|
||||
After writing, they are read again to verify their CRC.
|
||||
This is done to ensure thay they are really OK, even in the
|
||||
case of the worst possible silent errors.
|
||||
* Extends the -D, --force-device option to ignore more
|
||||
erroneous conditions in the 'fix' command, like unaccessible
|
||||
disks, or disks sharing the same physical device.
|
||||
* Extends the -d, --filter-disk option to allow to filter also
|
||||
by parity disk.
|
||||
* Extends the -h, --pre-hash option to also verify moved and
|
||||
copied files into the array before running a 'sync'.
|
||||
* Updates 'best' RAID functions for recent Atom CPUs.
|
||||
* Validates filters specifications rejecting relative paths.
|
||||
|
||||
-- Maxim Tikhonov <flaterichd@gmail.com> Tue, 01 Dec 2015 23:50:52 +0400
|
||||
|
||||
snapraid (8.1-0tikhonov1~trusty) trusty; urgency=medium
|
||||
|
||||
[ 8.1 2015/05 ]
|
||||
* Fix build issues in generic Unix platforms, including Mac OS X.
|
||||
* The "diff" command returns with error code 2 if a "sync" is
|
||||
required, to differentiate with the generic error code 1.
|
||||
* Reduced the effect of SMART attribute 193 on the failure
|
||||
probability to avoid some false positive reports.
|
||||
|
||||
-- Maxim Tikhonov <flaterichd@gmail.com> Sun, 17 May 2015 23:29:11 +0400
|
||||
|
||||
snapraid (8.0-0tikhonov1~trusty) trusty; urgency=medium
|
||||
|
||||
[ 8.0 2015/04 ]
|
||||
* Allows "sync" and "scrub" to continue after the first bunch of disk
|
||||
errors. Blocks with errors are marked as bad, and you can fix them
|
||||
with the "fix -e" command.
|
||||
The fix is expected to force the disk firmware to reallocate the
|
||||
bad sector, likely fixing the problem.
|
||||
You can control the number of allowed errors with the new
|
||||
-L, --error-limit option. The default is 100.
|
||||
* The -e, --filter-error option doesn't write anymore fixes to
|
||||
unsynced files. This helps in case you are running it on a not
|
||||
synced array, removing the risk to revert some files to an old state.
|
||||
* The -e, --filter-error option is now optimal and reads only the
|
||||
minimal amount of data necessary to fix the errors.
|
||||
* The "diff" command returns with an error code if a "sync" is
|
||||
required.
|
||||
* Adds new "smart" command to print a SMART report of the array.
|
||||
* Adds new "up" and "down" commands to spin up and down the disks of
|
||||
the array.
|
||||
* Adds new "devices" command to print the devices associations in
|
||||
the array.
|
||||
* Changes the log handling. If no log file is specified, all the
|
||||
warnings and not fatal errors messages goes to stderr. If a log file
|
||||
is specified, only fatal error messages are printed on the screen.
|
||||
You can control the amount of informative messages on stdout with
|
||||
the -q, --quiet and -v, --verbose options, that can be specified
|
||||
multiple times to be more quiet or verbose.
|
||||
* In the "status" command the "Wasted" column now shows a negative
|
||||
number for the amount of space that you can still waste without
|
||||
filling up the parity.
|
||||
* In the "status" and others commands we now use GB instead of GiB,
|
||||
when referring to disk space.
|
||||
* Renames the -s and -t options to -S and -B as they are intended to
|
||||
be manual only operations.
|
||||
* Windows binary built with gcc 4.8.1 using the MXE cross compiler 2.23,
|
||||
with targets i686-w64-mingw32 and x86_64-w64-mingw32. Before the x86
|
||||
target was i686-pc-mingw32.
|
||||
|
||||
-- Maxim Tikhonov <flaterichd@gmail.com> Thu, 30 Apr 2015 23:01:55 +0400
|
||||
|
||||
snapraid (7.1-0tikhonov1~precise) precise; urgency=medium
|
||||
|
||||
[ 7.1 2015/01 ]
|
||||
* In 'scrub' and 'sync' detects and reports Input/Output errors
|
||||
separately from generic file system errors.
|
||||
* In 'diff' doesn't print the "add" entry if a "copy" one is already
|
||||
printed.
|
||||
* Fixes build with old compilers in the x64 platforms [Leigh Phillips].
|
||||
* Fixes out-of-dir builds [Christoph Junghans].
|
||||
|
||||
-- Maxim Tikhonov <flaterichd@gmail.com> Wed, 11 Mar 2015 20:36:58 +0400
|
||||
|
||||
snapraid (7.0-0tikhonov2~precise) precise; urgency=medium
|
||||
|
||||
[ 7.0 2014/11 ]
|
||||
* In 'check' and 'fix' the array is scanned to find any moved files
|
||||
that could be used to recover missing data. Files are identified by
|
||||
timestamp, and then they are recognized also if moved to a different
|
||||
disk. Note that even if there are false positive they are identified
|
||||
checking the hash, so they have not effect, besides making the
|
||||
process a little slower. To disable this new behaviour you can use
|
||||
the -N, --force-nocopy option.
|
||||
* The -i, --import command now identifies files by timestamp making it
|
||||
very fast in importing directories.
|
||||
* More detailed 'status' report with single disk stats and free space
|
||||
available.
|
||||
* A lot faster directory listing for Windows.
|
||||
* Adds AVX2 support to improve parity generation speed.
|
||||
* Prints the time spent waiting for each disk also in 'scrub'.
|
||||
* The CPU usage, speed and ETA estimations are now based on the last 100
|
||||
seconds rather than from the start.
|
||||
* Keeps track of the UUID of the parity disks to check them before
|
||||
operating.
|
||||
* Windows binary built with gcc 4.8.1 using the MXE cross compiler 2.23.
|
||||
|
||||
-- Maxim Tikhonov <flaterichd@gmail.com> Thu, 27 Nov 2014 00:36:59 +0400
|
||||
|
||||
snapraid (6.2-0tikhonov1~precise) precise; urgency=low
|
||||
|
||||
[ 6.2 2014/5 ]
|
||||
* Fixed the regression test when run as root.
|
||||
* Added a new heuristic to detect file copies. Now a file is assumed
|
||||
to be a copy if name, size and nanosecond timestamp are matching,
|
||||
but if the nanosecond part of the timestamp is 0, it requires
|
||||
the full path matching and not only the name.
|
||||
* Added the -N, --force-nocopy option to disable completely
|
||||
the copy detection. SnapRAID also suggests to use this option
|
||||
in the error message of a data mismatch if likely caused by the
|
||||
copy detection.
|
||||
|
||||
-- Maxim Tikhonov <flaterichd@gmail.com> Wed, 16 Jul 2014 01:01:09 +0400
|
||||
|
||||
snapraid (6.1-0tikhonov1~precise) precise; urgency=high
|
||||
|
||||
[ 6.1 2014/4 ]
|
||||
* Fix build and regression test in Mac OS X.
|
||||
|
||||
-- Maxim Tikhonov <flaterichd@gmail.com> Tue, 22 Apr 2014 00:22:07 +0400
|
||||
|
||||
snapraid (6.0-0tikhonov1~precise) precise; urgency=low
|
||||
|
||||
[ 6.0 2014/3 ]
|
||||
* In "sync", even if a silent error is found, continue to update
|
||||
the parity if it's possible to correct the error.
|
||||
Note that the block will be marked bad, and the data
|
||||
will be fixed only at the next "fix -e" call.
|
||||
But any new data added will be protected if you are using
|
||||
enough parity to fix both the silent error and at least
|
||||
another potential error.
|
||||
* Detect copied files from one disk to another and reuse the already
|
||||
computed hash information to validate them in "sync".
|
||||
Files are assumed copied if they matches the name, size and timestamp.
|
||||
* For "sync", added a new -h, --pre-hash option to run a preliminary
|
||||
hashing step for all the new files to ensure to detect silent errors
|
||||
caused by the heavy machine usage of the parity computation.
|
||||
* In "fix", if a previous fixing attempt was made resulting in a
|
||||
.unrecoverable file, uses this file as starting point for the
|
||||
new attempt.
|
||||
* In the log file name allows the use of the '>>', %D, %T modifiers
|
||||
to select append mode, and to insert the date and time in the name.
|
||||
* The options -p, --percentage and -o, --older-than now keep their
|
||||
default value even if the other one is specified.
|
||||
* Moved the .lock file in the same dir of the first specified content
|
||||
file. This avoid to spin-up the parity disks in all commands.
|
||||
* The "diff", "list", "dup", "status" and "pool" commands don't access
|
||||
anymore the parity disks that can now stay powered down.
|
||||
* The default configuration file in Windows is now searched in the same
|
||||
directory where the snapraid.exe file resides.
|
||||
* New source code organization. The RAID engine is now
|
||||
an external component usable also in other projects.
|
||||
|
||||
-- Maxim Tikhonov <flaterichd@gmail.com> Fri, 11 Apr 2014 02:43:52 +0400
|
||||
|
||||
snapraid (5.3-0tikhonov1~precise) precise; urgency=low
|
||||
|
||||
[ 5.3 2014/3 ]
|
||||
* Don't warn about UUID changed if it's for an empty disk.
|
||||
* Fixed the number of blocks that scrub has to process when
|
||||
selecting a high percentage of the array.
|
||||
* Removed duplicate recovery attempts in synced state.
|
||||
|
||||
[ 5.2 2013/12 ]
|
||||
* If a disk changes UUID, automatically disable the inode
|
||||
recognition, because this is likely a new filesystem with
|
||||
all the inodes reassigned, and we don't want to risk a false
|
||||
positive when searching for inode/timestamp/size.
|
||||
* Allow to run a fix command with disks that doesn't need to be
|
||||
fixed mounted as read-only.
|
||||
* After a failed sync, always reallocates new files with a not
|
||||
yet computed parity to ensure to minimize the parity usage,
|
||||
if some other file is deleted in the meantime.
|
||||
* Doesn't count empty dirs as files in the diff counters.
|
||||
* Added a new "share" configuration option to allow to share
|
||||
in the network the pool directory also in Windows.
|
||||
* Fixed build problems in OpenBSD due the old assembler.
|
||||
* Fixed build problems in platforms different than x86.
|
||||
|
||||
[ 5.1 2013/12 ]
|
||||
* Fixed a potential crash if a file is deleted during a "sync/scrub".
|
||||
This is a problem introduced in version 5.0 due new logging.
|
||||
If happened to you to have a crash in sync, you don't need to
|
||||
take any special action, just run "sync" again.
|
||||
* Restored the functionality of -C, --gen-conf command.
|
||||
* Prints the files with duplicate physical offset if the
|
||||
-v, --verbose option is specified.
|
||||
|
||||
-- Maxim Tikhonov <flaterichd@gmail.com> Tue, 11 Mar 2014 18:56:46 +0400
|
||||
|
||||
snapraid (5.0-0tikhonov1~precise) precise; urgency=low
|
||||
|
||||
* New upstream release.
|
||||
|
||||
[ Upstream changelog 4.4 ]
|
||||
* Added support for up to six levels of parity.
|
||||
* Added a specific and faster triple parity format for CPUs that
|
||||
don't support SSSE3 instructions like ARM and AMD Phenom, Athlon
|
||||
and Opteron.
|
||||
* Faster RAID5 and RAID6 implementation for ARM 64 bit CPUs.
|
||||
* If a silent error is found during a "sync" command, directly marks
|
||||
the block as bad like in "scrub", without stopping the the "sync"
|
||||
process.
|
||||
* Sort files by inode when listing the directory. This improves
|
||||
the scanning performance.
|
||||
* For files with changes only in some blocks, updates the parity
|
||||
only for blocks that really are changed.
|
||||
This improves the performance in sync for modified files.
|
||||
* Added a new "list" command to see the stored list of files.
|
||||
* Removed the detailed list of errors from the screen output.
|
||||
To get it you must explicitely use the -l, --log option.
|
||||
It's now too detailed for the screen, because it contains a lot
|
||||
of info.
|
||||
* Changed the output format of some commands to make it similar
|
||||
at the new "list" one.
|
||||
* Reduced memory usage removing some unnecessary allocations.
|
||||
* Added a memory test on the memory buffers used in sync/scrub/check/fix
|
||||
before using them.
|
||||
|
||||
-- Maxim Tikhonov <flaterichd@gmail.com> Mon, 25 Nov 2013 15:58:37 +0400
|
||||
|
||||
snapraid (4.4-0tikhonov1~precise) precise; urgency=low
|
||||
|
||||
* New upstream release.
|
||||
|
||||
[ Upstream changelog 4.4 ]
|
||||
* Relaxed the check about small parity files, to allow to recover after a
|
||||
failed sync before resizing the parity files.
|
||||
|
||||
[ Upstream changelog 4.3 ]
|
||||
* Fixed the scrub command with the -p0 option. Now it really scrubs only the
|
||||
blocks marked as bad and not the full array.
|
||||
|
||||
[ Upstream changelog 4.2 ]
|
||||
* Fixed the wrong warning about physical offsets not supported caused by files
|
||||
not having a real offset because too small. For example, in NTFS it's possible
|
||||
to store such files in the MFT. It's just a cosmetic change, and not a
|
||||
functional one.
|
||||
* Remove unexpected 'Restore' entries in the diff output when dealing with
|
||||
filesystem without persistent inodes like NTFS in Linux.
|
||||
* Added support for filenames containing newlines. This happens in Mac OS X.
|
||||
|
||||
[ Upstream changelog 4.1 ]
|
||||
* If the underline filesystem doesn't support the FIEMAP command, automatically
|
||||
fallback to use FIBMAP for sorting files.
|
||||
* Fixed 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.
|
||||
* At the end of sync/scrub/check/fix prints "Everything OK" if no error was found.
|
||||
This should make clear that everything is really OK.
|
||||
|
||||
[ Upstream changelog 4.0 ]
|
||||
* New 'scrub' command to periodically check the oldest blocks for silent
|
||||
errors without the need to scan the whole array.
|
||||
* New 'status' command to check the fragmentation, the last check time
|
||||
distribution, and the silent error status of the array.
|
||||
* Added the new Spooky hash. It's faster in 64 bit architectures. To
|
||||
convert you can use the new 'rehash' command.
|
||||
* Changed to a binary content file to improve speed and reduce size.
|
||||
* Removed the --find-by-name, -N option. Now it always searches
|
||||
by name if a file is not found searching by inode, automatically
|
||||
reassigning inodes in restored files without needing to sync
|
||||
again the file. 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 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.
|
||||
* Better selection of the RAID6 implementation for different CPUs.
|
||||
* Added RAID5/RAID6 mmx and sse2 implementations with unrolling by 4.
|
||||
They are a little faster than the previous unroll by 2.
|
||||
* Added a lock file to avoid multiple running instances on the same array.
|
||||
The file is named as parity file adding the .lock extension.
|
||||
There is also the undocumented --test-skip-lock to avoid to check it.
|
||||
* Automatically ignores, with warning, mount points inside the array
|
||||
directory tree.
|
||||
* Changes the 'dup' output format to include the size of each duplicate file.
|
||||
|
||||
-- Maxim Tikhonov <flaterichd@gmail.com> Fri, 01 Nov 2013 00:04:46 +0400
|
||||
|
||||
snapraid (3.2-0tikhonov1~precise) precise; urgency=low
|
||||
|
||||
* New upstream release.
|
||||
|
||||
[ Upstream changelog 3.2 ]
|
||||
* Fix a directory creation problem in Windows when the "disk" option points to
|
||||
the root directory of a drive. Now SnapRAID won't complain about the
|
||||
inability to create such directory.
|
||||
If you encouter this problem when trying to recover your data, just upgrade
|
||||
to this version, and you'll be able to complete the recovering process.
|
||||
No need to upgrade for platforms different than Windows.
|
||||
|
||||
[ Upstream changelog 3.1 ]
|
||||
* Direct use of Windows API for disk access to improve error reporting.
|
||||
* If the 'fix' process is aborted, it removes all the new files partially
|
||||
recovered, to allow to reuse again the '-m, --filter-missing' flag.
|
||||
* In Windows don't exclude anymore system files. Only system directories are
|
||||
excluded.
|
||||
* In Windows applies filters in case insensitive way.
|
||||
* The Windows binaries are now built with gcc 4.7.2.
|
||||
* Reduced memory occupation for hardlinks and directories.
|
||||
* In 'dup' don't list file with 0 size.
|
||||
|
||||
-- Maxim Tikhonov <flaterichd@gmail.com> Fri, 09 Aug 2013 17:43:06 +0400
|
||||
|
||||
snapraid (3.0-0tikhonov1~precise) precise; urgency=low
|
||||
|
||||
* New upstream release.
|
||||
|
||||
[ Upstream changelog ]
|
||||
* Added pooling support with the new 'pool' command. It creates a virtual
|
||||
view of the array using symbolic links pointing to the original files.
|
||||
* Added a new -m, --filter-missing option that allow to undelete files,
|
||||
without checking/fixing the others.
|
||||
* Added a new -i, --import option to automatically import deleted files
|
||||
when fixing.
|
||||
* Added a new -l, --log option to save to disk the detailed log.
|
||||
* Added support also for hardlinks and empty directories.
|
||||
* Added support to save symlinks to files in Windows. Note that only the
|
||||
symlink is saved and not the linked file.
|
||||
Symlinks to dirs and junctions are still not supported in Windows.
|
||||
* Files without read permission generate an error instead of a warning.
|
||||
You now must explicitely exclude them in the configuration file with
|
||||
exclusion rules.
|
||||
* In 'check' and 'fix', if verbose is enabled, prints the result for each
|
||||
processed file.
|
||||
* Added an UUID check to detect when a disk is replaced, and to prevent
|
||||
unwanted disk swaps.
|
||||
|
||||
-- Maxim Tikhonov <flaterichd@gmail.com> Wed, 03 Apr 2013 13:01:53 +0400
|
||||
|
||||
snapraid (2.1-0tikhonov1~precise) precise; urgency=low
|
||||
|
||||
* New upstream release.
|
||||
|
||||
[ Upstream changelog ]
|
||||
* Checks for wrong empty fields in the configuration file.
|
||||
* Filter rules for files are not anymore applied to directories.
|
||||
|
||||
-- Maxim Tikhonov <flaterichd@gmail.com> Mon, 28 Jan 2013 02:10:28 +0400
|
||||
|
||||
snapraid (2.0-0tikhonov1~precise) precise; urgency=low
|
||||
|
||||
* New upstream release.
|
||||
|
||||
[ Upstream changelog ]
|
||||
* Added a new -a option to make the 'check' command to only check file hashes
|
||||
without checking the parity data.
|
||||
* Added a new -d option to filter by disk name.
|
||||
* The file modification time is now saved using nanosecond precision.
|
||||
This allows to restore the exact modification time in 'fix'.
|
||||
The new 'content' files written with this version are not backward
|
||||
compatible, but it's still possible to read the old 'content' format.
|
||||
* Fixed hard-links automatic exclusion. All the hardlinks after the first one
|
||||
are now correctly ignored.
|
||||
* If it isn't possible to grow a parity file, prints the list of files
|
||||
outside the maximum size allocated.
|
||||
* Autosave isn't triggered if we are near the end of the 'sync' process.
|
||||
* Before starting a 'sync', we wait for two seconds, to workaround the FAT
|
||||
limitation of having two seconds modification time precision.
|
||||
This a safe measure to be 100% sure to always detect file changes.
|
||||
* Always fill the memory after allocating it to avoid the OOM (Out Of Memory)
|
||||
killer in Linux.
|
||||
* Fixed compilation in Solaris/OpenIndiana for lacking both futimes()
|
||||
and futimens().
|
||||
* Now 'sync' ensures that the parity files are not too small to contain the
|
||||
just loaded data.
|
||||
* Removed the '-H,--filter-nohidden' option. It doesn't make sense to
|
||||
have it as command line option.
|
||||
You must use the 'nohidden' option in the configuration file.
|
||||
* When opening files in read-only mode, also specify the noatime flag,
|
||||
to avoid to update the file access time.
|
||||
* Exclude rules for files are now also applied to directories.
|
||||
This allows to excludes some file/directory without the need to call
|
||||
the stat() function on them.
|
||||
* The -N, --find-by-name option also ignores the nanosecond part of
|
||||
timestamps to work with copy programs not supporting nanoseconds.
|
||||
* Fixed deduplicated files handling in Windows Server 2012.
|
||||
* Removed MD5 support.
|
||||
|
||||
-- Maxim Tikhonov <flaterichd@gmail.com> Thu, 06 Dec 2012 00:38:20 +0400
|
||||
|
||||
snapraid (1.13-0tikhonov1~precise) precise; urgency=low
|
||||
|
||||
* New upstream release.
|
||||
|
||||
[ Upstream changelog ]
|
||||
* Fixed a Segmentation Fault when checking/fixing if there are three or
|
||||
more errors in a specific block.
|
||||
|
||||
-- Maxim Tikhonov <flaterichd@gmail.com> Mon, 05 Nov 2012 16:31:22 +0400
|
||||
|
||||
snapraid (1.12-0tikhonov1~precise) precise; urgency=low
|
||||
|
||||
* New upstream release 1.12.
|
||||
|
||||
[ Upstream changelog ]
|
||||
* Fixed file renaming in Windows during a 'fix' command. This is only a
|
||||
Windows issue, no reason to upgrade for other platforms.
|
||||
|
||||
-- Maxim Tikhonov <flaterichd@gmail.com> Thu, 20 Sep 2012 13:13:40 +0400
|
||||
|
||||
snapraid (1.11-0tikhonov1~precise) precise; urgency=high
|
||||
|
||||
* New upstream release 1.11.
|
||||
|
||||
[ Upstream changelog ]
|
||||
* Fixed again directories inclusion. Exclusion rules for directories were ignored.
|
||||
|
||||
-- Maxim Tikhonov <flaterichd@gmail.com> Mon, 09 Jul 2012 19:06:01 +0400
|
||||
|
||||
snapraid (1.10-0tikhonov1~precise) precise; urgency=low
|
||||
|
||||
* New upstream release 1.10.
|
||||
|
||||
[ Upstream changelog ]
|
||||
* Fixed directory inclusion, in case the last rule is an "include" one.
|
||||
* Fixed very long paths in Windows. We now always use the special '\\?' prefix to remove the 260 chars limitation.
|
||||
* If a file is excluded, it prints explicitely which attribute caused the exclusion.
|
||||
* Automatically excludes also the temporary copy of content file, the one with the ".tmp" extension.
|
||||
* Avoid the Windows system to go in automatic sleep mode when running.
|
||||
|
||||
-- Maxim Tikhonov <flaterichd@gmail.com> Sun, 01 Jul 2012 21:43:16 +0400
|
||||
|
||||
snapraid (1.9-0tikhonov1~precise) precise; urgency=low
|
||||
|
||||
* New upstream release 1.9.
|
||||
|
||||
[ Upstream changelog ]
|
||||
* Implemented a more sophisticated recovering in case a harddisk failure happens during a 'sync'
|
||||
command. When using RAID6 it improves the chances of recovering data after an aborted 'sync'.
|
||||
* Fixed the count of new files.
|
||||
* Added a new 'autosave' configuration option to save the intermediate 'sync' state.
|
||||
* Supported filesystems with read requests returning less data than requested.
|
||||
* In Windows ensures that the disk serial number is not zero.
|
||||
|
||||
-- Maxim Tikhonov <flaterichd@gmail.com> Tue, 10 Apr 2012 17:31:51 +0400
|
||||
|
||||
snapraid (1.8-0tikhonov1~oneiric) oneiric; urgency=low
|
||||
|
||||
* New upstream release 1.8.
|
||||
|
||||
Upstream changelog:
|
||||
* Added a new "dup" command to find all the duplicate files.
|
||||
* Added a new option "--filter-nohidden" to exclude hidden files.
|
||||
* Faster and parallel writing of content files.
|
||||
* The example configuration files now put the content files in the data
|
||||
disks instead than in the parity disks.
|
||||
* Added a checksum at the content file to ensure its integrity.
|
||||
* Using fallocate() instead posix_fallocate() to avoid the very slow
|
||||
posix_fallocate() fallback of writing the whole file.
|
||||
|
||||
-- Maxim Tikhonov <flaterichd@gmail.com> Sat, 17 Mar 2012 19:15:07 +0400
|
||||
|
||||
snapraid (1.7-0tikhonov2~oneiric) oneiric; urgency=low
|
||||
|
||||
* Fixed example snapraid.conf.
|
||||
|
||||
-- Maxim Tikhonov <flaterichd@gmail.com> Sat, 24 Dec 2011 01:28:39 +0400
|
||||
|
||||
snapraid (1.7-0tikhonov1~oneiric) oneiric; urgency=low
|
||||
|
||||
* Initial release.
|
||||
|
||||
-- Maxim Tikhonov <flaterichd@gmail.com> Thu, 22 Dec 2011 19:46:17 +0400
|
||||
1
debian/compat
vendored
Normal file
1
debian/compat
vendored
Normal file
@@ -0,0 +1 @@
|
||||
7
|
||||
28
debian/control
vendored
Normal file
28
debian/control
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
Source: snapraid
|
||||
Section: utils
|
||||
Priority: extra
|
||||
Maintainer: Maxim Tikhonov <flaterichd@gmail.com>
|
||||
Build-Depends: debhelper (>= 7.0.0), autotools-dev
|
||||
Standards-Version: 3.9.2
|
||||
Homepage: http://snapraid.sourceforge.net/
|
||||
|
||||
Package: snapraid
|
||||
Architecture: any
|
||||
Depends:
|
||||
${shlibs:Depends},
|
||||
${misc:Depends}
|
||||
Description: SnapRAID is a backup program for disk arrays.
|
||||
SnapRAID is a backup program for disk arrays.
|
||||
.
|
||||
SnapRAID stores redundancy information in the disk array, and it allows recovering from up to two disk failures.
|
||||
.
|
||||
SnapRAID is mainly targeted for a home media center, where you have a lot of big files that rarely change.
|
||||
.
|
||||
Beside the ability to recover from disk failures, the other features of SnapRAID are:
|
||||
- You can start using SnapRAID with already filled disks.
|
||||
- The disks of the array can have different sizes.
|
||||
- You can add more disks at any time.
|
||||
- If you accidentally delete some files in a disk, you can recover them.
|
||||
- If more than two disks fail, you lose the data only on the failed disks. All the data in the other disks is safe.
|
||||
- It doesn't lock-in your data. You can stop using SnapRAID at any time without the need to reformat or move data.
|
||||
- All your data is hashed to ensure data integrity and avoid silent corruption.
|
||||
40
debian/copyright
vendored
Normal file
40
debian/copyright
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
Format: http://dep.debian.net/deps/dep5
|
||||
Name: snapraid
|
||||
Upstream-Name: snapraid
|
||||
Maintainer: Maxim Tikhonov <flaterichd@gmail.com>
|
||||
Source: http://sourceforge.net/projects/snapraid/files/
|
||||
|
||||
Files: *
|
||||
Copyright: 2011 Andrea Mazzoleni <amadvance@users.sourceforge.net>
|
||||
License: GPL-3
|
||||
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 3 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.
|
||||
.
|
||||
On Debian systems, the complete text of the GNU General
|
||||
Public License can be found in `/usr/share/common-licenses/GPL-3'.
|
||||
|
||||
Files: debian/*
|
||||
Copyright: 2011 Maxim Tikhonov <flaterichd@gmail.com>
|
||||
License: GPL-2+
|
||||
This package 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 package 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, see <http://www.gnu.org/licenses/>
|
||||
.
|
||||
On Debian systems, the complete text of the GNU General
|
||||
Public License version 2 can be found in "/usr/share/common-licenses/GPL-2".
|
||||
9
debian/docs
vendored
Normal file
9
debian/docs
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
AUTHORS
|
||||
CHECK
|
||||
COPYING
|
||||
HISTORY
|
||||
INSTALL
|
||||
README
|
||||
TODO
|
||||
snapraid.conf.example
|
||||
snapraid.txt
|
||||
2
debian/install
vendored
Normal file
2
debian/install
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
debian/snapraid.conf etc
|
||||
snapraid usr/bin
|
||||
1
debian/manpage.1
vendored
Symbolic link
1
debian/manpage.1
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../snapraid.1
|
||||
21
debian/rules
vendored
Executable file
21
debian/rules
vendored
Executable file
@@ -0,0 +1,21 @@
|
||||
#!/usr/bin/make -f
|
||||
# -*- makefile -*-
|
||||
# Sample debian/rules that uses debhelper.
|
||||
#
|
||||
# This file was originally written by Joey Hess and Craig Small.
|
||||
# As a special exception, when this file is copied by dh-make into a
|
||||
# dh-make output file, you may use that output file without restriction.
|
||||
# This special exception was added by Craig Small in version 0.37 of dh-make.
|
||||
#
|
||||
# Modified to make a template file for a multi-binary package with separated
|
||||
# build-arch and build-indep targets by Bill Allombert 2001
|
||||
|
||||
# Uncomment this to turn on verbose mode.
|
||||
#export DH_VERBOSE=1
|
||||
|
||||
# This has to be exported to make some magic below work.
|
||||
export DH_OPTIONS
|
||||
|
||||
|
||||
%:
|
||||
dh $@
|
||||
86
debian/snapraid.conf
vendored
Normal file
86
debian/snapraid.conf
vendored
Normal file
@@ -0,0 +1,86 @@
|
||||
# Example configuration for snapraid
|
||||
|
||||
# Defines the file to use as parity storage
|
||||
# It must NOT be in a data disk
|
||||
# Format: "parity FILE_PATH"
|
||||
parity /mnt/diskp/snapraid.parity
|
||||
|
||||
# Defines the files to use as additional parity storage.
|
||||
# If specified, they enable the multiple failures protection
|
||||
# from two to six level of parity.
|
||||
# To enable, uncomment one parity file for each level of extra
|
||||
# protection required. Start from 2-parity, and follow in order.
|
||||
# It must NOT be in a data disk
|
||||
# Format: "X-parity FILE_PATH"
|
||||
#2-parity /mnt/diskq/snapraid.2-parity
|
||||
#3-parity /mnt/diskr/snapraid.3-parity
|
||||
#4-parity /mnt/disks/snapraid.4-parity
|
||||
#5-parity /mnt/diskt/snapraid.5-parity
|
||||
#6-parity /mnt/disku/snapraid.6-parity
|
||||
|
||||
# Defines the files to use as content list
|
||||
# You can use multiple specification to store more copies
|
||||
# You must have least one copy for each parity file plus one. Some more don't hurt
|
||||
# They can be in the disks used for data, parity or boot,
|
||||
# but each file must be in a different disk
|
||||
# Format: "content FILE_PATH"
|
||||
content /var/snapraid.content
|
||||
content /mnt/disk1/snapraid.content
|
||||
content /mnt/disk2/snapraid.content
|
||||
|
||||
# Defines the data disks to use
|
||||
# The name and mount point association is relevant for parity, do not change it
|
||||
# WARNING: Adding here your /home, /var or /tmp disks is NOT a good idea!
|
||||
# SnapRAID is better suited for files that rarely changes!
|
||||
# Format: "disk DISK_NAME DISK_MOUNT_POINT"
|
||||
data d1 /mnt/disk1/
|
||||
data d2 /mnt/disk2/
|
||||
data d3 /mnt/disk3/
|
||||
|
||||
# Excludes hidden files and directories (uncomment to enable).
|
||||
#nohidden
|
||||
|
||||
# Defines files and directories to exclude
|
||||
# Remember that all the paths are relative at the mount points
|
||||
# Format: "exclude FILE"
|
||||
# Format: "exclude DIR/"
|
||||
# Format: "exclude /PATH/FILE"
|
||||
# Format: "exclude /PATH/DIR/"
|
||||
exclude *.unrecoverable
|
||||
exclude /tmp/
|
||||
exclude /lost+found/
|
||||
|
||||
# Defines the block size in kibi bytes (1024 bytes) (uncomment to enable).
|
||||
# Default value is 256 -> 256 kibi bytes -> 262144 bytes
|
||||
# Format: "blocksize SIZE_IN_KiB"
|
||||
#blocksize 256
|
||||
|
||||
# Automatically save the state when syncing after the specified amount
|
||||
# of GB processed (uncomment to enable).
|
||||
# This option is useful to avoid to restart from scratch long 'sync'
|
||||
# commands interrupted by a machine crash.
|
||||
# It also improves the recovering if a disk break during a 'sync'.
|
||||
# Default value is 0, meaning disabled.
|
||||
# Format: "autosave SIZE_IN_GB"
|
||||
#autosave 500
|
||||
|
||||
# Defines the pooling directory where the virtual view of the disk
|
||||
# array is created using the "pool" command (uncomment to enable).
|
||||
# The files are not really copied here, but just linked using
|
||||
# symbolic links.
|
||||
# This directory must be outside the array.
|
||||
# Format: "pool DIR"
|
||||
#pool /pool
|
||||
|
||||
# Defines a custom smartctl command to obtain the SMART attributes
|
||||
# for each disk. This may be required for RAID controllers and for
|
||||
# some USB disk that cannot be autodetected.
|
||||
# In the specified options, the "%s" string is replaced by the device name.
|
||||
# Refers at the smartmontools documentation about the possible options:
|
||||
# RAID -> https://www.smartmontools.org/wiki/Supported_RAID-Controllers
|
||||
# USB -> https://www.smartmontools.org/wiki/Supported_USB-Devices
|
||||
#smartctl d1 -d sat %s
|
||||
#smartctl d2 -d usbjmicron %s
|
||||
#smartctl parity -d areca,1/1 /dev/sg0
|
||||
#smartctl 2-parity -d areca,2/1 /dev/sg0
|
||||
|
||||
1
debian/source/format
vendored
Normal file
1
debian/source/format
vendored
Normal file
@@ -0,0 +1 @@
|
||||
3.0 (quilt)
|
||||
2
debian/watch
vendored
Normal file
2
debian/watch
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
version=3
|
||||
https://github.com/amadvance/snapraid/releases .*snapraid-([0-9.]*\.[0-9.]*).tar.gz
|
||||
28
snapraid.1
28
snapraid.1
@@ -647,7 +647,7 @@ and ignore all the parity data.
|
||||
This command will take a long time, but if you are not paranoid,
|
||||
you can skip it.
|
||||
.SS STEP 4 \-> Sync
|
||||
Run the \[dq]sync\[dq] command to re\-synchronize the array with the new disk.
|
||||
Run the \[dq]sync\[dq] command to resynchronize the array with the new disk.
|
||||
.PP
|
||||
.RS 4
|
||||
snapraid sync
|
||||
@@ -745,7 +745,7 @@ Spins up all the disks of the array.
|
||||
.PP
|
||||
You can spin\-up only some specific disks using the \-d, \-\-filter\-disk option.
|
||||
.PP
|
||||
Take care that spinning\-up all the disks at the same time needs a lot of power.
|
||||
Take care that spinniup\-up all the disks at the same time needs a lot of power.
|
||||
Ensure that your power\-supply can sustain that.
|
||||
.PP
|
||||
Nothing is modified.
|
||||
@@ -912,7 +912,7 @@ Verify all the files and the parity data.
|
||||
It works like \[dq]fix\[dq], but it only simulates a recovery and no change
|
||||
is written in the array.
|
||||
.PP
|
||||
This command is mostly intended for manual verification,
|
||||
This command is mostly intended for manual verifications,
|
||||
like after a recovery process or in other special conditions.
|
||||
For periodic and scheduled checks uses \[dq]scrub\[dq].
|
||||
.PP
|
||||
@@ -931,7 +931,7 @@ Nothing is modified.
|
||||
.SS dup
|
||||
Lists all the duplicate files. Two files are assumed equal if their
|
||||
hashes are matching. The file data is not read, but only the
|
||||
pre\-computed hashes are used.
|
||||
precomputed hashes are used.
|
||||
.PP
|
||||
Nothing is modified.
|
||||
.SS pool
|
||||
@@ -942,7 +942,7 @@ The files are not really copied here, but just linked using
|
||||
symbolic links.
|
||||
.PP
|
||||
When updating, all the present symbolic links and empty
|
||||
sub\-directories are deleted and replaced with the new
|
||||
subdirectories are deleted and replaced with the new
|
||||
view of the array. Any other regular file is left in place.
|
||||
.PP
|
||||
Nothing is modified outside the pool directory.
|
||||
@@ -962,20 +962,20 @@ low level devices used by a single disk in the array.
|
||||
.PP
|
||||
Nothing is modified.
|
||||
.SS touch
|
||||
Sets arbitrarily the sub\-second time\-stamp of all the files
|
||||
Sets arbitrarely the sub\-second timestamp of all the files
|
||||
that have it at zero.
|
||||
.PP
|
||||
This improves the SnapRAID capability to recognize moved
|
||||
and copied files as it makes the time\-stamp almost unique,
|
||||
and copied files as it makes the timestamp almost unique,
|
||||
removing possible duplicates.
|
||||
.PP
|
||||
More specifically, if the sub\-second time\-stamp is not zero,
|
||||
More specifically, if the sub\-second timestamp is not zero,
|
||||
a moved or copied file is identified as such if it matches
|
||||
the name, size and time\-stamp. If instead the sub\-second time\-stamp
|
||||
the name, size and timestamp. If instead the sub\-second timestamp
|
||||
is zero, it\'s considered a copy only if it matches the full path,
|
||||
size and time\-stamp.
|
||||
size and timestamp.
|
||||
.PP
|
||||
Note that the second precision time\-stamp is not modified,
|
||||
Note that the second precision timestamp is not modified,
|
||||
and all the dates and times of your files will be maintained.
|
||||
.SS rehash
|
||||
Schedules a rehash of the whole array.
|
||||
@@ -1090,7 +1090,7 @@ Imports from the specified directory any file that you deleted
|
||||
from the array after the last \[dq]sync\[dq].
|
||||
If you still have such files, they could be used by \[dq]check\[dq]
|
||||
and \[dq]fix\[dq] to improve the recover process.
|
||||
The files are read also in sub\-directories and they are
|
||||
The files are read also in subdirectories and they are
|
||||
identified regardless of their name.
|
||||
This option can be used only with \[dq]check\[dq] and \[dq]fix\[dq].
|
||||
.TP
|
||||
@@ -1146,7 +1146,7 @@ This allows to identify copied or moved files from one disk
|
||||
to another, and to reuse the already computed hash information
|
||||
to detect silent errors or to recover missing files.
|
||||
This behavior, in some rare cases, may result in false positives,
|
||||
or in a slow process due the many hash verification, and this
|
||||
or in a slow process due the many hash verifications, and this
|
||||
option allows to resolve them.
|
||||
This option can be used only with \[dq]sync\[dq], \[dq]check\[dq] and \[dq]fix\[dq].
|
||||
.TP
|
||||
@@ -1280,7 +1280,7 @@ is enabled:
|
||||
6\-parity enables hexa (six) parity
|
||||
.PD
|
||||
.PP
|
||||
Each parity level requires the presence of all the previous parity
|
||||
Each parity level requires the precence of all the previous parity
|
||||
levels.
|
||||
.PP
|
||||
The same considerations of the \'parity\' option apply.
|
||||
|
||||
28
snapraid.txt
28
snapraid.txt
@@ -391,7 +391,7 @@ This command will take a long time, but if you are not paranoid,
|
||||
you can skip it.
|
||||
|
||||
---- 4.4.4 STEP 4 -> Sync ----
|
||||
Run the "sync" command to re-synchronize the array with the new disk.
|
||||
Run the "sync" command to resynchronize the array with the new disk.
|
||||
|
||||
snapraid sync
|
||||
|
||||
@@ -476,7 +476,7 @@ Spins up all the disks of the array.
|
||||
|
||||
You can spin-up only some specific disks using the -d, --filter-disk option.
|
||||
|
||||
Take care that spinning-up all the disks at the same time needs a lot of power.
|
||||
Take care that spinniup-up all the disks at the same time needs a lot of power.
|
||||
Ensure that your power-supply can sustain that.
|
||||
|
||||
Nothing is modified.
|
||||
@@ -643,7 +643,7 @@ Verify all the files and the parity data.
|
||||
It works like "fix", but it only simulates a recovery and no change
|
||||
is written in the array.
|
||||
|
||||
This command is mostly intended for manual verification,
|
||||
This command is mostly intended for manual verifications,
|
||||
like after a recovery process or in other special conditions.
|
||||
For periodic and scheduled checks uses "scrub".
|
||||
|
||||
@@ -668,7 +668,7 @@ Nothing is modified.
|
||||
|
||||
Lists all the duplicate files. Two files are assumed equal if their
|
||||
hashes are matching. The file data is not read, but only the
|
||||
pre-computed hashes are used.
|
||||
precomputed hashes are used.
|
||||
|
||||
Nothing is modified.
|
||||
|
||||
@@ -682,7 +682,7 @@ The files are not really copied here, but just linked using
|
||||
symbolic links.
|
||||
|
||||
When updating, all the present symbolic links and empty
|
||||
sub-directories are deleted and replaced with the new
|
||||
subdirectories are deleted and replaced with the new
|
||||
view of the array. Any other regular file is left in place.
|
||||
|
||||
Nothing is modified outside the pool directory.
|
||||
@@ -708,20 +708,20 @@ Nothing is modified.
|
||||
5.14 touch
|
||||
----------
|
||||
|
||||
Sets arbitrarily the sub-second time-stamp of all the files
|
||||
Sets arbitrarely the sub-second timestamp of all the files
|
||||
that have it at zero.
|
||||
|
||||
This improves the SnapRAID capability to recognize moved
|
||||
and copied files as it makes the time-stamp almost unique,
|
||||
and copied files as it makes the timestamp almost unique,
|
||||
removing possible duplicates.
|
||||
|
||||
More specifically, if the sub-second time-stamp is not zero,
|
||||
More specifically, if the sub-second timestamp is not zero,
|
||||
a moved or copied file is identified as such if it matches
|
||||
the name, size and time-stamp. If instead the sub-second time-stamp
|
||||
the name, size and timestamp. If instead the sub-second timestamp
|
||||
is zero, it's considered a copy only if it matches the full path,
|
||||
size and time-stamp.
|
||||
size and timestamp.
|
||||
|
||||
Note that the second precision time-stamp is not modified,
|
||||
Note that the second precision timestamp is not modified,
|
||||
and all the dates and times of your files will be maintained.
|
||||
|
||||
5.15 rehash
|
||||
@@ -843,7 +843,7 @@ SnapRAID provides the following options:
|
||||
from the array after the last "sync".
|
||||
If you still have such files, they could be used by "check"
|
||||
and "fix" to improve the recover process.
|
||||
The files are read also in sub-directories and they are
|
||||
The files are read also in subdirectories and they are
|
||||
identified regardless of their name.
|
||||
This option can be used only with "check" and "fix".
|
||||
|
||||
@@ -899,7 +899,7 @@ SnapRAID provides the following options:
|
||||
to another, and to reuse the already computed hash information
|
||||
to detect silent errors or to recover missing files.
|
||||
This behavior, in some rare cases, may result in false positives,
|
||||
or in a slow process due the many hash verification, and this
|
||||
or in a slow process due the many hash verifications, and this
|
||||
option allows to resolve them.
|
||||
This option can be used only with "sync", "check" and "fix".
|
||||
|
||||
@@ -1037,7 +1037,7 @@ is enabled:
|
||||
* 5-parity enables penta (five) parity
|
||||
* 6-parity enables hexa (six) parity
|
||||
|
||||
Each parity level requires the presence of all the previous parity
|
||||
Each parity level requires the precence of all the previous parity
|
||||
levels.
|
||||
|
||||
The same considerations of the 'parity' option apply.
|
||||
|
||||
@@ -36,7 +36,7 @@ void tommy_array_init(tommy_array* array)
|
||||
|
||||
/* fixed initial size */
|
||||
array->bucket_bit = TOMMY_ARRAY_BIT;
|
||||
array->bucket_max = (tommy_size_t)1 << array->bucket_bit;
|
||||
array->bucket_max = 1 << array->bucket_bit;
|
||||
array->bucket[0] = tommy_cast(void**, tommy_calloc(array->bucket_max, sizeof(void*)));
|
||||
for (i = 1; i < TOMMY_ARRAY_BIT; ++i)
|
||||
array->bucket[i] = array->bucket[0];
|
||||
@@ -51,11 +51,11 @@ void tommy_array_done(tommy_array* array)
|
||||
tommy_free(array->bucket[0]);
|
||||
for (i = TOMMY_ARRAY_BIT; i < array->bucket_bit; ++i) {
|
||||
void** segment = array->bucket[i];
|
||||
tommy_free(&segment[(tommy_ptrdiff_t)1 << i]);
|
||||
tommy_free(&segment[((tommy_ptrdiff_t)1) << i]);
|
||||
}
|
||||
}
|
||||
|
||||
void tommy_array_grow(tommy_array* array, tommy_size_t count)
|
||||
void tommy_array_grow(tommy_array* array, tommy_count_t count)
|
||||
{
|
||||
if (array->count >= count)
|
||||
return;
|
||||
@@ -72,7 +72,7 @@ void tommy_array_grow(tommy_array* array, tommy_size_t count)
|
||||
array->bucket[array->bucket_bit] = &segment[-(tommy_ptrdiff_t)array->bucket_max];
|
||||
|
||||
++array->bucket_bit;
|
||||
array->bucket_max = (tommy_size_t)1 << array->bucket_bit;
|
||||
array->bucket_max = 1 << array->bucket_bit;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -53,15 +53,20 @@
|
||||
*/
|
||||
#define TOMMY_ARRAY_BIT 6
|
||||
|
||||
/** \internal
|
||||
* Max number of elements as a power of 2.
|
||||
*/
|
||||
#define TOMMY_ARRAY_BIT_MAX 32
|
||||
|
||||
/**
|
||||
* Array container type.
|
||||
* \note Don't use internal fields directly, but access the container only using functions.
|
||||
*/
|
||||
typedef struct tommy_array_struct {
|
||||
void** bucket[TOMMY_SIZE_BIT]; /**< Dynamic array of buckets. */
|
||||
tommy_size_t bucket_max; /**< Number of buckets. */
|
||||
tommy_size_t count; /**< Number of initialized elements in the array. */
|
||||
void** bucket[TOMMY_ARRAY_BIT_MAX]; /**< Dynamic array of buckets. */
|
||||
tommy_uint_t bucket_bit; /**< Bits used in the bit mask. */
|
||||
tommy_count_t bucket_max; /**< Number of buckets. */
|
||||
tommy_count_t count; /**< Number of initialized elements in the array. */
|
||||
} tommy_array;
|
||||
|
||||
/**
|
||||
@@ -78,21 +83,21 @@ void tommy_array_done(tommy_array* array);
|
||||
* Grows the size up to the specified value.
|
||||
* All the new elements in the array are initialized with the 0 value.
|
||||
*/
|
||||
void tommy_array_grow(tommy_array* array, tommy_size_t size);
|
||||
void tommy_array_grow(tommy_array* array, tommy_count_t size);
|
||||
|
||||
/**
|
||||
* Gets a reference of the element at the specified position.
|
||||
* You must be sure that space for this position is already
|
||||
* allocated calling tommy_array_grow().
|
||||
*/
|
||||
tommy_inline void** tommy_array_ref(tommy_array* array, tommy_size_t pos)
|
||||
tommy_inline void** tommy_array_ref(tommy_array* array, tommy_count_t pos)
|
||||
{
|
||||
tommy_uint_t bsr;
|
||||
|
||||
assert(pos < array->count);
|
||||
|
||||
/* get the highest bit set, in case of all 0, return 0 */
|
||||
bsr = tommy_ilog2(pos | 1);
|
||||
bsr = tommy_ilog2_u32(pos | 1);
|
||||
|
||||
return &array->bucket[bsr][pos];
|
||||
}
|
||||
@@ -102,7 +107,7 @@ tommy_inline void** tommy_array_ref(tommy_array* array, tommy_size_t pos)
|
||||
* You must be sure that space for this position is already
|
||||
* allocated calling tommy_array_grow().
|
||||
*/
|
||||
tommy_inline void tommy_array_set(tommy_array* array, tommy_size_t pos, void* element)
|
||||
tommy_inline void tommy_array_set(tommy_array* array, tommy_count_t pos, void* element)
|
||||
{
|
||||
*tommy_array_ref(array, pos) = element;
|
||||
}
|
||||
@@ -112,7 +117,7 @@ tommy_inline void tommy_array_set(tommy_array* array, tommy_size_t pos, void* el
|
||||
* You must be sure that space for this position is already
|
||||
* allocated calling tommy_array_grow().
|
||||
*/
|
||||
tommy_inline void* tommy_array_get(tommy_array* array, tommy_size_t pos)
|
||||
tommy_inline void* tommy_array_get(tommy_array* array, tommy_count_t pos)
|
||||
{
|
||||
return *tommy_array_ref(array, pos);
|
||||
}
|
||||
@@ -122,7 +127,7 @@ tommy_inline void* tommy_array_get(tommy_array* array, tommy_size_t pos)
|
||||
*/
|
||||
tommy_inline void tommy_array_insert(tommy_array* array, void* element)
|
||||
{
|
||||
tommy_size_t pos = array->count;
|
||||
tommy_count_t pos = array->count;
|
||||
|
||||
tommy_array_grow(array, pos + 1);
|
||||
|
||||
@@ -132,7 +137,7 @@ tommy_inline void tommy_array_insert(tommy_array* array, void* element)
|
||||
/**
|
||||
* Gets the initialized size of the array.
|
||||
*/
|
||||
tommy_inline tommy_size_t tommy_array_size(tommy_array* array)
|
||||
tommy_inline tommy_count_t tommy_array_size(tommy_array* array)
|
||||
{
|
||||
return array->count;
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ void tommy_arrayblkof_init(tommy_arrayblkof* array, tommy_size_t element_size)
|
||||
|
||||
void tommy_arrayblkof_done(tommy_arrayblkof* array)
|
||||
{
|
||||
tommy_size_t i;
|
||||
tommy_count_t i;
|
||||
|
||||
for (i = 0; i < tommy_array_size(&array->block); ++i)
|
||||
tommy_free(tommy_array_get(&array->block, i));
|
||||
@@ -48,10 +48,10 @@ void tommy_arrayblkof_done(tommy_arrayblkof* array)
|
||||
tommy_array_done(&array->block);
|
||||
}
|
||||
|
||||
void tommy_arrayblkof_grow(tommy_arrayblkof* array, tommy_size_t count)
|
||||
void tommy_arrayblkof_grow(tommy_arrayblkof* array, tommy_count_t count)
|
||||
{
|
||||
tommy_size_t block_max;
|
||||
tommy_size_t block_mac;
|
||||
tommy_count_t block_max;
|
||||
tommy_count_t block_mac;
|
||||
|
||||
if (array->count >= count)
|
||||
return;
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
typedef struct tommy_arrayblkof_struct {
|
||||
tommy_array block; /**< Array of blocks. */
|
||||
tommy_size_t element_size; /**< Size of the stored element in bytes. */
|
||||
tommy_size_t count; /**< Number of initialized elements in the array. */
|
||||
tommy_count_t count; /**< Number of initialized elements in the array. */
|
||||
} tommy_arrayblkof;
|
||||
|
||||
/**
|
||||
@@ -79,14 +79,14 @@ void tommy_arrayblkof_done(tommy_arrayblkof* array);
|
||||
* Grows the size up to the specified value.
|
||||
* All the new elements in the array are initialized with the 0 value.
|
||||
*/
|
||||
void tommy_arrayblkof_grow(tommy_arrayblkof* array, tommy_size_t size);
|
||||
void tommy_arrayblkof_grow(tommy_arrayblkof* array, tommy_count_t size);
|
||||
|
||||
/**
|
||||
* Gets a reference of the element at the specified position.
|
||||
* You must be sure that space for this position is already
|
||||
* allocated calling tommy_arrayblkof_grow().
|
||||
*/
|
||||
tommy_inline void* tommy_arrayblkof_ref(tommy_arrayblkof* array, tommy_size_t pos)
|
||||
tommy_inline void* tommy_arrayblkof_ref(tommy_arrayblkof* array, tommy_count_t pos)
|
||||
{
|
||||
unsigned char* base;
|
||||
|
||||
@@ -100,7 +100,7 @@ tommy_inline void* tommy_arrayblkof_ref(tommy_arrayblkof* array, tommy_size_t po
|
||||
/**
|
||||
* Gets the initialized size of the array.
|
||||
*/
|
||||
tommy_inline tommy_size_t tommy_arrayblkof_size(tommy_arrayblkof* array)
|
||||
tommy_inline tommy_count_t tommy_arrayblkof_size(tommy_arrayblkof* array)
|
||||
{
|
||||
return array->count;
|
||||
}
|
||||
|
||||
@@ -136,6 +136,11 @@ tommy_inline void tommy_chain_merge_degenerated(tommy_chain* first, tommy_chain*
|
||||
tommy_chain_merge(first, second, cmp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Max number of elements as a power of 2.
|
||||
*/
|
||||
#define TOMMY_CHAIN_BIT_MAX 32
|
||||
|
||||
/**
|
||||
* Sorts a chain.
|
||||
* It's a stable merge sort using power of 2 buckets, with O(N*log(N)) complexity,
|
||||
@@ -153,20 +158,20 @@ tommy_inline void tommy_chain_mergesort(tommy_chain* chain, tommy_compare_func*
|
||||
/*
|
||||
* Bit buckets of chains.
|
||||
* Each bucket contains 2^i nodes or it's empty.
|
||||
* The chain at address TOMMY_BIT_MAX is an independet variable operating as "carry".
|
||||
* The chain at address TOMMY_CHAIN_BIT_MAX is an independet variable operating as "carry".
|
||||
* We keep it in the same "bit" vector to avoid reports from the valgrind tool sgcheck.
|
||||
*/
|
||||
tommy_chain bit[TOMMY_SIZE_BIT + 1];
|
||||
tommy_chain bit[TOMMY_CHAIN_BIT_MAX + 1];
|
||||
|
||||
/**
|
||||
* Value stored inside the bit bucket.
|
||||
* It's used to know which bucket is empty of full.
|
||||
*/
|
||||
tommy_size_t counter;
|
||||
tommy_count_t counter;
|
||||
tommy_node* node = chain->head;
|
||||
tommy_node* tail = chain->tail;
|
||||
tommy_size_t mask;
|
||||
tommy_size_t i;
|
||||
tommy_count_t mask;
|
||||
tommy_count_t i;
|
||||
|
||||
counter = 0;
|
||||
while (1) {
|
||||
@@ -174,9 +179,9 @@ tommy_inline void tommy_chain_mergesort(tommy_chain* chain, tommy_compare_func*
|
||||
tommy_chain* last;
|
||||
|
||||
/* carry bit to add */
|
||||
last = &bit[TOMMY_SIZE_BIT];
|
||||
bit[TOMMY_SIZE_BIT].head = node;
|
||||
bit[TOMMY_SIZE_BIT].tail = node;
|
||||
last = &bit[TOMMY_CHAIN_BIT_MAX];
|
||||
bit[TOMMY_CHAIN_BIT_MAX].head = node;
|
||||
bit[TOMMY_CHAIN_BIT_MAX].tail = node;
|
||||
next = node->next;
|
||||
|
||||
/* add the bit, propagating the carry */
|
||||
@@ -201,7 +206,7 @@ tommy_inline void tommy_chain_mergesort(tommy_chain* chain, tommy_compare_func*
|
||||
}
|
||||
|
||||
/* merge the buckets */
|
||||
i = tommy_ctz(counter);
|
||||
i = tommy_ctz_u32(counter);
|
||||
mask = counter >> i;
|
||||
while (mask != 1) {
|
||||
mask >>= 1;
|
||||
|
||||
@@ -92,22 +92,22 @@ tommy_uint32_t tommy_hash_u32(tommy_uint32_t init_val, const void* void_key, tom
|
||||
b += tommy_le_uint32_read(key + 4);
|
||||
a += tommy_le_uint32_read(key + 0);
|
||||
break;
|
||||
case 11 : c += ((tommy_uint32_t)key[10]) << 16; /* fallthrough */
|
||||
case 10 : c += ((tommy_uint32_t)key[9]) << 8; /* fallthrough */
|
||||
case 9 : c += key[8]; /* fallthrough */
|
||||
case 11 : c += ((tommy_uint32_t)key[10]) << 16;
|
||||
case 10 : c += ((tommy_uint32_t)key[9]) << 8;
|
||||
case 9 : c += key[8];
|
||||
case 8 :
|
||||
b += tommy_le_uint32_read(key + 4);
|
||||
a += tommy_le_uint32_read(key + 0);
|
||||
break;
|
||||
case 7 : b += ((tommy_uint32_t)key[6]) << 16; /* fallthrough */
|
||||
case 6 : b += ((tommy_uint32_t)key[5]) << 8; /* fallthrough */
|
||||
case 5 : b += key[4]; /* fallthrough */
|
||||
case 7 : b += ((tommy_uint32_t)key[6]) << 16;
|
||||
case 6 : b += ((tommy_uint32_t)key[5]) << 8;
|
||||
case 5 : b += key[4];
|
||||
case 4 :
|
||||
a += tommy_le_uint32_read(key + 0);
|
||||
break;
|
||||
case 3 : a += ((tommy_uint32_t)key[2]) << 16; /* fallthrough */
|
||||
case 2 : a += ((tommy_uint32_t)key[1]) << 8; /* fallthrough */
|
||||
case 1 : a += key[0]; /* fallthrough */
|
||||
case 3 : a += ((tommy_uint32_t)key[2]) << 16;
|
||||
case 2 : a += ((tommy_uint32_t)key[1]) << 8;
|
||||
case 1 : a += key[0];
|
||||
}
|
||||
|
||||
tommy_final(a, b, c);
|
||||
@@ -142,22 +142,22 @@ tommy_uint64_t tommy_hash_u64(tommy_uint64_t init_val, const void* void_key, tom
|
||||
b += tommy_le_uint32_read(key + 4);
|
||||
a += tommy_le_uint32_read(key + 0);
|
||||
break;
|
||||
case 11 : c += ((tommy_uint32_t)key[10]) << 16; /* fallthrough */
|
||||
case 10 : c += ((tommy_uint32_t)key[9]) << 8; /* fallthrough */
|
||||
case 9 : c += key[8]; /* fallthrough */
|
||||
case 11 : c += ((tommy_uint32_t)key[10]) << 16;
|
||||
case 10 : c += ((tommy_uint32_t)key[9]) << 8;
|
||||
case 9 : c += key[8];
|
||||
case 8 :
|
||||
b += tommy_le_uint32_read(key + 4);
|
||||
a += tommy_le_uint32_read(key + 0);
|
||||
break;
|
||||
case 7 : b += ((tommy_uint32_t)key[6]) << 16; /* fallthrough */
|
||||
case 6 : b += ((tommy_uint32_t)key[5]) << 8; /* fallthrough */
|
||||
case 5 : b += key[4]; /* fallthrough */
|
||||
case 7 : b += ((tommy_uint32_t)key[6]) << 16;
|
||||
case 6 : b += ((tommy_uint32_t)key[5]) << 8;
|
||||
case 5 : b += key[4];
|
||||
case 4 :
|
||||
a += tommy_le_uint32_read(key + 0);
|
||||
break;
|
||||
case 3 : a += ((tommy_uint32_t)key[2]) << 16; /* fallthrough */
|
||||
case 2 : a += ((tommy_uint32_t)key[1]) << 8; /* fallthrough */
|
||||
case 1 : a += key[0]; /* fallthrough */
|
||||
case 3 : a += ((tommy_uint32_t)key[2]) << 16;
|
||||
case 2 : a += ((tommy_uint32_t)key[1]) << 8;
|
||||
case 1 : a += key[0];
|
||||
}
|
||||
|
||||
tommy_final(a, b, c);
|
||||
|
||||
@@ -37,6 +37,11 @@
|
||||
/******************************************************************************/
|
||||
/* hash */
|
||||
|
||||
/**
|
||||
* Hash type used in hashtables.
|
||||
*/
|
||||
typedef tommy_key_t tommy_hash_t;
|
||||
|
||||
/**
|
||||
* Hash function with a 32 bits result.
|
||||
* Implementation of the Robert Jenkins "lookup3" hash 32 bits version,
|
||||
|
||||
@@ -35,7 +35,7 @@ void tommy_hashdyn_init(tommy_hashdyn* hashdyn)
|
||||
{
|
||||
/* fixed initial size */
|
||||
hashdyn->bucket_bit = TOMMY_HASHDYN_BIT;
|
||||
hashdyn->bucket_max = (tommy_size_t)1 << hashdyn->bucket_bit;
|
||||
hashdyn->bucket_max = 1 << hashdyn->bucket_bit;
|
||||
hashdyn->bucket_mask = hashdyn->bucket_max - 1;
|
||||
hashdyn->bucket = tommy_cast(tommy_hashdyn_node**, tommy_calloc(hashdyn->bucket_max, sizeof(tommy_hashdyn_node*)));
|
||||
|
||||
@@ -50,18 +50,18 @@ void tommy_hashdyn_done(tommy_hashdyn* hashdyn)
|
||||
/**
|
||||
* Resize the bucket vector.
|
||||
*/
|
||||
static void tommy_hashdyn_resize(tommy_hashdyn* hashdyn, tommy_size_t new_bucket_bit)
|
||||
static void tommy_hashdyn_resize(tommy_hashdyn* hashdyn, tommy_count_t new_bucket_bit)
|
||||
{
|
||||
tommy_size_t bucket_bit;
|
||||
tommy_size_t bucket_max;
|
||||
tommy_size_t new_bucket_max;
|
||||
tommy_size_t new_bucket_mask;
|
||||
tommy_count_t bucket_bit;
|
||||
tommy_count_t bucket_max;
|
||||
tommy_count_t new_bucket_max;
|
||||
tommy_count_t new_bucket_mask;
|
||||
tommy_hashdyn_node** new_bucket;
|
||||
|
||||
bucket_bit = hashdyn->bucket_bit;
|
||||
bucket_max = hashdyn->bucket_max;
|
||||
|
||||
new_bucket_max = (tommy_size_t)1 << new_bucket_bit;
|
||||
new_bucket_max = 1 << new_bucket_bit;
|
||||
new_bucket_mask = new_bucket_max - 1;
|
||||
|
||||
/* allocate the new vector using malloc() and not calloc() */
|
||||
@@ -70,7 +70,7 @@ static void tommy_hashdyn_resize(tommy_hashdyn* hashdyn, tommy_size_t new_bucket
|
||||
|
||||
/* reinsert all the elements */
|
||||
if (new_bucket_bit > bucket_bit) {
|
||||
tommy_size_t i;
|
||||
tommy_count_t i;
|
||||
|
||||
/* grow */
|
||||
for (i = 0; i < bucket_max; ++i) {
|
||||
@@ -84,7 +84,7 @@ static void tommy_hashdyn_resize(tommy_hashdyn* hashdyn, tommy_size_t new_bucket
|
||||
j = hashdyn->bucket[i];
|
||||
while (j) {
|
||||
tommy_hashdyn_node* j_next = j->next;
|
||||
tommy_size_t pos = j->index & new_bucket_mask;
|
||||
tommy_count_t pos = j->key & new_bucket_mask;
|
||||
if (new_bucket[pos])
|
||||
tommy_list_insert_tail_not_empty(new_bucket[pos], j);
|
||||
else
|
||||
@@ -93,7 +93,7 @@ static void tommy_hashdyn_resize(tommy_hashdyn* hashdyn, tommy_size_t new_bucket
|
||||
}
|
||||
}
|
||||
} else {
|
||||
tommy_size_t i;
|
||||
tommy_count_t i;
|
||||
|
||||
/* shrink */
|
||||
for (i = 0; i < new_bucket_max; ++i) {
|
||||
@@ -136,11 +136,11 @@ tommy_inline void hashdyn_shrink_step(tommy_hashdyn* hashdyn)
|
||||
|
||||
void tommy_hashdyn_insert(tommy_hashdyn* hashdyn, tommy_hashdyn_node* node, void* data, tommy_hash_t hash)
|
||||
{
|
||||
tommy_size_t pos = hash & hashdyn->bucket_mask;
|
||||
tommy_count_t pos = hash & hashdyn->bucket_mask;
|
||||
|
||||
tommy_list_insert_tail(&hashdyn->bucket[pos], node, data);
|
||||
|
||||
node->index = hash;
|
||||
node->key = hash;
|
||||
|
||||
++hashdyn->count;
|
||||
|
||||
@@ -149,7 +149,7 @@ void tommy_hashdyn_insert(tommy_hashdyn* hashdyn, tommy_hashdyn_node* node, void
|
||||
|
||||
void* tommy_hashdyn_remove_existing(tommy_hashdyn* hashdyn, tommy_hashdyn_node* node)
|
||||
{
|
||||
tommy_size_t pos = node->index & hashdyn->bucket_mask;
|
||||
tommy_count_t pos = node->key & hashdyn->bucket_mask;
|
||||
|
||||
tommy_list_remove_existing(&hashdyn->bucket[pos], node);
|
||||
|
||||
@@ -162,12 +162,12 @@ void* tommy_hashdyn_remove_existing(tommy_hashdyn* hashdyn, tommy_hashdyn_node*
|
||||
|
||||
void* tommy_hashdyn_remove(tommy_hashdyn* hashdyn, tommy_search_func* cmp, const void* cmp_arg, tommy_hash_t hash)
|
||||
{
|
||||
tommy_size_t pos = hash & hashdyn->bucket_mask;
|
||||
tommy_count_t pos = hash & hashdyn->bucket_mask;
|
||||
tommy_hashdyn_node* node = hashdyn->bucket[pos];
|
||||
|
||||
while (node) {
|
||||
/* we first check if the hash matches, as in the same bucket we may have multiples hash values */
|
||||
if (node->index == hash && cmp(cmp_arg, node->data) == 0) {
|
||||
if (node->key == hash && cmp(cmp_arg, node->data) == 0) {
|
||||
tommy_list_remove_existing(&hashdyn->bucket[pos], node);
|
||||
|
||||
--hashdyn->count;
|
||||
@@ -184,9 +184,9 @@ void* tommy_hashdyn_remove(tommy_hashdyn* hashdyn, tommy_search_func* cmp, const
|
||||
|
||||
void tommy_hashdyn_foreach(tommy_hashdyn* hashdyn, tommy_foreach_func* func)
|
||||
{
|
||||
tommy_size_t bucket_max = hashdyn->bucket_max;
|
||||
tommy_count_t bucket_max = hashdyn->bucket_max;
|
||||
tommy_hashdyn_node** bucket = hashdyn->bucket;
|
||||
tommy_size_t pos;
|
||||
tommy_count_t pos;
|
||||
|
||||
for (pos = 0; pos < bucket_max; ++pos) {
|
||||
tommy_hashdyn_node* node = bucket[pos];
|
||||
@@ -201,9 +201,9 @@ void tommy_hashdyn_foreach(tommy_hashdyn* hashdyn, tommy_foreach_func* func)
|
||||
|
||||
void tommy_hashdyn_foreach_arg(tommy_hashdyn* hashdyn, tommy_foreach_arg_func* func, void* arg)
|
||||
{
|
||||
tommy_size_t bucket_max = hashdyn->bucket_max;
|
||||
tommy_count_t bucket_max = hashdyn->bucket_max;
|
||||
tommy_hashdyn_node** bucket = hashdyn->bucket;
|
||||
tommy_size_t pos;
|
||||
tommy_count_t pos;
|
||||
|
||||
for (pos = 0; pos < bucket_max; ++pos) {
|
||||
tommy_hashdyn_node* node = bucket[pos];
|
||||
|
||||
@@ -160,10 +160,10 @@ typedef tommy_node tommy_hashdyn_node;
|
||||
*/
|
||||
typedef struct tommy_hashdyn_struct {
|
||||
tommy_hashdyn_node** bucket; /**< Hash buckets. One list for each hash modulus. */
|
||||
tommy_size_t bucket_max; /**< Number of buckets. */
|
||||
tommy_size_t bucket_mask; /**< Bit mask to access the buckets. */
|
||||
tommy_size_t count; /**< Number of elements. */
|
||||
tommy_uint_t bucket_bit; /**< Bits used in the bit mask. */
|
||||
tommy_count_t bucket_max; /**< Number of buckets. */
|
||||
tommy_count_t bucket_mask; /**< Bit mask to access the buckets. */
|
||||
tommy_count_t count; /**< Number of elements. */
|
||||
} tommy_hashdyn;
|
||||
|
||||
/**
|
||||
@@ -226,7 +226,7 @@ tommy_inline void* tommy_hashdyn_search(tommy_hashdyn* hashdyn, tommy_search_fun
|
||||
|
||||
while (i) {
|
||||
/* we first check if the hash matches, as in the same bucket we may have multiples hash values */
|
||||
if (i->index == hash && cmp(cmp_arg, i->data) == 0)
|
||||
if (i->key == hash && cmp(cmp_arg, i->data) == 0)
|
||||
return i->data;
|
||||
i = i->next;
|
||||
}
|
||||
@@ -281,7 +281,7 @@ void tommy_hashdyn_foreach_arg(tommy_hashdyn* hashdyn, tommy_foreach_arg_func* f
|
||||
/**
|
||||
* Gets the number of elements.
|
||||
*/
|
||||
tommy_inline tommy_size_t tommy_hashdyn_count(tommy_hashdyn* hashdyn)
|
||||
tommy_inline tommy_count_t tommy_hashdyn_count(tommy_hashdyn* hashdyn)
|
||||
{
|
||||
return hashdyn->count;
|
||||
}
|
||||
|
||||
@@ -226,6 +226,24 @@ tommy_inline void tommy_list_insert_tail(tommy_list* list, tommy_node* node, voi
|
||||
node->data = data;
|
||||
}
|
||||
|
||||
/** \internal
|
||||
* Removes an element from the head of a not empty list.
|
||||
* \param list The list. The list cannot be empty.
|
||||
* \return The node removed.
|
||||
*/
|
||||
tommy_inline tommy_node* tommy_list_remove_head_not_empty(tommy_list* list)
|
||||
{
|
||||
tommy_node* head = tommy_list_head(list);
|
||||
|
||||
/* remove from the "circular" prev list */
|
||||
head->next->prev = head->prev;
|
||||
|
||||
/* remove from the "0 terminated" next list */
|
||||
*list = head->next; /* the new head, in case 0 */
|
||||
|
||||
return head;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes an element from the list.
|
||||
* You must already have the address of the element to remove.
|
||||
@@ -311,9 +329,9 @@ tommy_inline tommy_bool_t tommy_list_empty(tommy_list* list)
|
||||
* Gets the number of elements.
|
||||
* \note This operation is O(n).
|
||||
*/
|
||||
tommy_inline tommy_size_t tommy_list_count(tommy_list* list)
|
||||
tommy_inline tommy_count_t tommy_list_count(tommy_list* list)
|
||||
{
|
||||
tommy_size_t count = 0;
|
||||
tommy_count_t count = 0;
|
||||
tommy_node* i = tommy_list_head(list);
|
||||
|
||||
while (i) {
|
||||
|
||||
@@ -39,10 +39,10 @@ void tommy_tree_init(tommy_tree* tree, tommy_compare_func* cmp)
|
||||
tree->cmp = cmp;
|
||||
}
|
||||
|
||||
static tommy_ssize_t tommy_tree_delta(tommy_tree_node* root)
|
||||
static int tommy_tree_delta(tommy_tree_node* root)
|
||||
{
|
||||
tommy_ssize_t left_height = root->prev ? root->prev->index : 0;
|
||||
tommy_ssize_t right_height = root->next ? root->next->index : 0;
|
||||
int left_height = root->prev ? root->prev->key : 0;
|
||||
int right_height = root->next ? root->next->key : 0;
|
||||
|
||||
return left_height - right_height;
|
||||
}
|
||||
@@ -84,7 +84,7 @@ static tommy_tree_node* tommy_tree_move_right(tommy_tree_node* root, tommy_tree_
|
||||
|
||||
static tommy_tree_node* tommy_tree_balance(tommy_tree_node* root)
|
||||
{
|
||||
tommy_ssize_t delta = tommy_tree_delta(root);
|
||||
int delta = tommy_tree_delta(root);
|
||||
|
||||
if (delta < -1) {
|
||||
if (tommy_tree_delta(root->next) > 0)
|
||||
@@ -99,16 +99,16 @@ static tommy_tree_node* tommy_tree_balance(tommy_tree_node* root)
|
||||
}
|
||||
|
||||
/* recompute key */
|
||||
root->index = 0;
|
||||
root->key = 0;
|
||||
|
||||
if (root->prev && root->prev->index > root->index)
|
||||
root->index = root->prev->index;
|
||||
if (root->prev && root->prev->key > root->key)
|
||||
root->key = root->prev->key;
|
||||
|
||||
if (root->next && root->next->index > root->index)
|
||||
root->index = root->next->index;
|
||||
if (root->next && root->next->key > root->key)
|
||||
root->key = root->next->key;
|
||||
|
||||
/* count itself */
|
||||
root->index += 1;
|
||||
root->key += 1;
|
||||
|
||||
return root;
|
||||
}
|
||||
@@ -145,7 +145,7 @@ void* tommy_tree_insert(tommy_tree* tree, tommy_tree_node* node, void* data)
|
||||
insert->data = data;
|
||||
insert->prev = 0;
|
||||
insert->next = 0;
|
||||
insert->index = 0;
|
||||
insert->key = 0;
|
||||
|
||||
tree->root = tommy_tree_insert_node(tree->cmp, tree->root, &insert);
|
||||
|
||||
|
||||
@@ -117,8 +117,8 @@ typedef tommy_node tommy_tree_node;
|
||||
*/
|
||||
typedef struct tommy_tree_struct {
|
||||
tommy_tree_node* root; /**< Root node. */
|
||||
tommy_count_t count; /**< Number of elements. */
|
||||
tommy_compare_func* cmp; /**< Comparison function. */
|
||||
tommy_size_t count; /**< Number of elements. */
|
||||
} tommy_tree;
|
||||
|
||||
/**
|
||||
@@ -213,7 +213,7 @@ void tommy_tree_foreach_arg(tommy_tree* tree, tommy_foreach_arg_func* func, void
|
||||
/**
|
||||
* Gets the number of elements.
|
||||
*/
|
||||
tommy_inline tommy_size_t tommy_tree_count(tommy_tree* tree)
|
||||
tommy_inline tommy_count_t tommy_tree_count(tommy_tree* tree)
|
||||
{
|
||||
return tree->count;
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* Generic types.
|
||||
*/
|
||||
@@ -36,37 +37,17 @@
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#if defined(_MSC_VER)
|
||||
typedef unsigned tommy_uint32_t; /**< Generic uint32_t type. */
|
||||
typedef unsigned _int64 tommy_uint64_t; /**< Generic uint64_t type. */
|
||||
typedef size_t tommy_uintptr_t; /**< Generic uintptr_t type. */
|
||||
#ifdef _WIN64
|
||||
#define TOMMY_SIZE_BIT 64
|
||||
typedef unsigned _int64_t tommy_size_t; /**< Generic size_t type. */
|
||||
typedef _int64_t tommy_ssize_t; /**< Generic ssize_t type. */
|
||||
#else
|
||||
#define TOMMY_SIZE_BIT 32
|
||||
typedef unsigned tommy_size_t; /**< Generic size_t type. */
|
||||
typedef int tommy_ssize_t; /**< Generic ssize_t type. */
|
||||
#endif
|
||||
#else
|
||||
#include <stdint.h>
|
||||
typedef uint32_t tommy_uint32_t; /**< Generic uint32_t type. */
|
||||
typedef uint64_t tommy_uint64_t; /**< Generic uint64_t type. */
|
||||
typedef uintptr_t tommy_uintptr_t; /**< Generic uintptr_t type. */
|
||||
#if SIZE_MAX == UINT64_MAX
|
||||
#define TOMMY_SIZE_BIT 64
|
||||
typedef uint64_t tommy_size_t; /**< Generic size_t type. */
|
||||
typedef int64_t tommy_ssize_t; /**< Generic ssize_t type. */
|
||||
#elif SIZE_MAX == UINT32_MAX
|
||||
#define TOMMY_SIZE_BIT 32
|
||||
typedef uint32_t tommy_size_t; /**< Generic size_t type. */
|
||||
typedef int32_t tommy_ssize_t; /**< Generic ssize_t type. */
|
||||
#else
|
||||
#error Unsupported SIZE_MAX
|
||||
#endif
|
||||
#endif
|
||||
|
||||
typedef size_t tommy_size_t; /**< Generic size_t type. */
|
||||
typedef ptrdiff_t tommy_ptrdiff_t; /**< Generic ptrdiff_t type. */
|
||||
typedef int tommy_bool_t; /**< Generic boolean type. */
|
||||
|
||||
@@ -78,6 +59,13 @@ typedef int tommy_bool_t; /**< Generic boolean type. */
|
||||
*/
|
||||
typedef tommy_uint32_t tommy_uint_t;
|
||||
|
||||
/**
|
||||
* Generic unsigned integer for counting objects.
|
||||
*
|
||||
* TommyDS doesn't support more than 2^32-1 objects.
|
||||
*/
|
||||
typedef tommy_uint32_t tommy_count_t;
|
||||
|
||||
/** \internal
|
||||
* Type cast required for the C++ compilation.
|
||||
* When compiling in C++ we cannot convert a void* pointer to another pointer.
|
||||
@@ -164,17 +152,17 @@ typedef tommy_uint32_t tommy_uint_t;
|
||||
#endif
|
||||
|
||||
/******************************************************************************/
|
||||
/* key/hash */
|
||||
/* key */
|
||||
|
||||
/**
|
||||
* Type used in indexed data structures to store the key of a object.
|
||||
* Key type used in indexed data structures to store the key or the hash value.
|
||||
*/
|
||||
typedef tommy_size_t tommy_key_t;
|
||||
typedef tommy_uint32_t tommy_key_t;
|
||||
|
||||
/**
|
||||
* Type used in hashtables to store the hash of a object.
|
||||
* Bits into the ::tommy_key_t type.
|
||||
*/
|
||||
typedef tommy_size_t tommy_hash_t;
|
||||
#define TOMMY_KEY_BIT (sizeof(tommy_key_t) * 8)
|
||||
|
||||
/******************************************************************************/
|
||||
/* node */
|
||||
@@ -212,12 +200,11 @@ typedef struct tommy_node_struct {
|
||||
void* data;
|
||||
|
||||
/**
|
||||
* Index of the node.
|
||||
* With tries this field is used to store the key.
|
||||
* Key used to store the node.
|
||||
* With hashtables this field is used to store the hash value.
|
||||
* With lists this field is not used.
|
||||
*/
|
||||
tommy_size_t index;
|
||||
tommy_key_t key;
|
||||
} tommy_node;
|
||||
|
||||
/******************************************************************************/
|
||||
@@ -315,10 +302,6 @@ typedef void tommy_foreach_arg_func(void* arg, void* obj);
|
||||
#include <intrin.h>
|
||||
#pragma intrinsic(_BitScanReverse)
|
||||
#pragma intrinsic(_BitScanForward)
|
||||
#if TOMMY_SIZE_BIT == 64
|
||||
#pragma intrinsic(_BitScanReverse64)
|
||||
#pragma intrinsic(_BitScanForward64)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/** \internal
|
||||
@@ -380,29 +363,6 @@ tommy_inline tommy_uint_t tommy_ilog2_u32(tommy_uint32_t value)
|
||||
#endif
|
||||
}
|
||||
|
||||
#if TOMMY_SIZE_BIT == 64
|
||||
/**
|
||||
* Bit scan reverse or integer log2 for 64 bits.
|
||||
*/
|
||||
tommy_inline tommy_uint_t tommy_ilog2_u64(tommy_uint64_t value)
|
||||
{
|
||||
#if defined(_MSC_VER)
|
||||
unsigned long count;
|
||||
_BitScanReverse64(&count, value);
|
||||
return count;
|
||||
#elif defined(__GNUC__)
|
||||
return __builtin_clzll(value) ^ 63;
|
||||
#else
|
||||
uint32_t l = value & 0xFFFFFFFFU;
|
||||
uint32_t h = value >> 32;
|
||||
if (h)
|
||||
return tommy_ilog2_u32(h) + 32;
|
||||
else
|
||||
return tommy_ilog2_u32(l);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Bit scan forward or trailing zero count.
|
||||
* Return the bit index of the least significant 1 bit.
|
||||
@@ -431,29 +391,6 @@ tommy_inline tommy_uint_t tommy_ctz_u32(tommy_uint32_t value)
|
||||
#endif
|
||||
}
|
||||
|
||||
#if TOMMY_SIZE_BIT == 64
|
||||
/**
|
||||
* Bit scan forward or trailing zero count for 64 bits.
|
||||
*/
|
||||
tommy_inline tommy_uint_t tommy_ctz_u64(tommy_uint64_t value)
|
||||
{
|
||||
#if defined(_MSC_VER)
|
||||
unsigned long count;
|
||||
_BitScanForward64(&count, value);
|
||||
return count;
|
||||
#elif defined(__GNUC__)
|
||||
return __builtin_ctzll(value);
|
||||
#else
|
||||
uint32_t l = value & 0xFFFFFFFFU;
|
||||
uint32_t h = value >> 32;
|
||||
if (l)
|
||||
return tommy_ctz_u32(l);
|
||||
else
|
||||
return tommy_ctz_u32(h) + 32;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Rounds up to the next power of 2.
|
||||
* For the value 0, the result is undefined.
|
||||
@@ -475,23 +412,6 @@ tommy_inline tommy_uint32_t tommy_roundup_pow2_u32(tommy_uint32_t value)
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rounds up to the next power of 2 for 64 bits.
|
||||
*/
|
||||
tommy_inline tommy_uint64_t tommy_roundup_pow2_u64(tommy_uint64_t value)
|
||||
{
|
||||
--value;
|
||||
value |= value >> 1;
|
||||
value |= value >> 2;
|
||||
value |= value >> 4;
|
||||
value |= value >> 8;
|
||||
value |= value >> 16;
|
||||
value |= value >> 32;
|
||||
++value;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the specified word has a byte at 0.
|
||||
* \return 0 or 1.
|
||||
@@ -500,19 +420,5 @@ tommy_inline int tommy_haszero_u32(tommy_uint32_t value)
|
||||
{
|
||||
return ((value - 0x01010101) & ~value & 0x80808080) != 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Bit depth mapping.
|
||||
*/
|
||||
#if TOMMY_SIZE_BIT == 64
|
||||
#define tommy_ilog2 tommy_ilog2_u64
|
||||
#define tommy_ctz tommy_ctz_u64
|
||||
#define tommy_roundup_pow2 tommy_roundup_pow2_u64
|
||||
#else
|
||||
#define tommy_ilog2 tommy_ilog2_u32
|
||||
#define tommy_ctz tommy_ctz_u32
|
||||
#define tommy_roundup_pow2 tommy_roundup_pow2_u32
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
Reference in New Issue
Block a user