diff --git a/cov/cmdline/check.c.func-sort-c.html b/cov/cmdline/check.c.func-sort-c.html
index 5cbc315a..9d707518 100644
--- a/cov/cmdline/check.c.func-sort-c.html
+++ b/cov/cmdline/check.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -69,19 +69,19 @@
| repair |
- 869090 |
+ 869089 |
| blockcmp |
- 468340 |
+ 468172 |
| repair_step |
- 260919 |
+ 260805 |
| is_hash_matching |
- 209415 |
+ 209449 |
| is_parity_matching |
diff --git a/cov/cmdline/check.c.func.html b/cov/cmdline/check.c.func.html
index d4f4a28c..9544066b 100644
--- a/cov/cmdline/check.c.func.html
+++ b/cov/cmdline/check.c.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -65,7 +65,7 @@
| blockcmp |
- 468340 |
+ 468172 |
| file_post |
@@ -73,7 +73,7 @@
| is_hash_matching |
- 209415 |
+ 209449 |
| is_parity_matching |
@@ -81,11 +81,11 @@
| repair |
- 869090 |
+ 869089 |
| repair_step |
- 260919 |
+ 260805 |
| state_check |
diff --git a/cov/cmdline/check.c.gcov.html b/cov/cmdline/check.c.gcov.html
index 74a027d8..d2e357c6 100644
--- a/cov/cmdline/check.c.gcov.html
+++ b/cov/cmdline/check.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -129,64 +129,64 @@
67 : * Check if a block hash matches the specified buffer.
68 : * Return ==0 if equal
69 : */
- 70 468340 : static int blockcmp(struct snapraid_state* state, int rehash, struct snapraid_block* block, unsigned pos_size, unsigned char* buffer, unsigned char* buffer_zero)
+ 70 468172 : static int blockcmp(struct snapraid_state* state, int rehash, struct snapraid_block* block, unsigned pos_size, unsigned char* buffer, unsigned char* buffer_zero)
71 : {
72 : unsigned char hash[HASH_SIZE];
73 :
74 : /* now compute the hash of the valid part */
- 75 468340 : if (rehash) {
- 76 22269 : memhash(state->prevhash, state->prevhashseed, hash, buffer, pos_size);
+ 75 468172 : if (rehash) {
+ 76 22270 : memhash(state->prevhash, state->prevhashseed, hash, buffer, pos_size);
77 : } else {
- 78 446071 : memhash(state->hash, state->hashseed, hash, buffer, pos_size);
+ 78 445902 : memhash(state->hash, state->hashseed, hash, buffer, pos_size);
79 : }
80 :
81 : /* compare the hash */
- 82 468340 : if (memcmp(hash, block->hash, HASH_SIZE) != 0) {
- 83 13881 : return -1;
+ 82 468172 : if (memcmp(hash, block->hash, HASH_SIZE) != 0) {
+ 83 13872 : return -1;
84 : }
85 :
86 : /* compare to the end of the block */
- 87 454459 : if (pos_size < state->block_size) {
- 88 187794 : if (memcmp(buffer + pos_size, buffer_zero + pos_size, state->block_size - pos_size) != 0) {
- 89 21 : return -1;
+ 87 454300 : if (pos_size < state->block_size) {
+ 88 187749 : if (memcmp(buffer + pos_size, buffer_zero + pos_size, state->block_size - pos_size) != 0) {
+ 89 24 : return -1;
90 : }
91 : }
92 :
- 93 454438 : return 0;
+ 93 454276 : return 0;
94 : }
95 :
96 : /**
97 : * Check if the hash of all the failed block we are expecting to recover are now matching.
98 : */
- 99 209415 : static int is_hash_matching(struct snapraid_state* state, int rehash, unsigned diskmax, struct failed_struct* failed, unsigned* failed_map, unsigned failed_count, void** buffer, void* buffer_zero)
+ 99 209449 : static int is_hash_matching(struct snapraid_state* state, int rehash, unsigned diskmax, struct failed_struct* failed, unsigned* failed_map, unsigned failed_count, void** buffer, void* buffer_zero)
100 : {
101 : unsigned j;
102 : int hash_checked;
103 :
- 104 209415 : hash_checked = 0; /* keep track if we check at least one block */
+ 104 209449 : hash_checked = 0; /* keep track if we check at least one block */
105 :
106 : /* check if the recovered blocks are OK */
- 107 668375 : for (j = 0; j < failed_count; ++j) {
+ 107 668247 : for (j = 0; j < failed_count; ++j) {
108 : /* if we are expected to recover this block */
- 109 472862 : if (!failed[failed_map[j]].is_outofdate
+ 109 472694 : if (!failed[failed_map[j]].is_outofdate
110 : /* if the block has a hash to check */
- 111 468340 : && block_has_updated_hash(failed[failed_map[j]].block)
+ 111 468172 : && block_has_updated_hash(failed[failed_map[j]].block)
112 : ) {
113 : /* if a hash doesn't match, fail the check */
- 114 468340 : unsigned pos_size = file_block_size(failed[failed_map[j]].file, failed[failed_map[j]].file_pos, state->block_size);
- 115 468340 : if (blockcmp(state, rehash, failed[failed_map[j]].block, pos_size, buffer[failed[failed_map[j]].index], buffer_zero) != 0) {
- 116 13902 : log_tag("hash_error: Hash mismatch on entry %u\n", failed_map[j]);
- 117 13902 : return 0;
+ 114 468172 : unsigned pos_size = file_block_size(failed[failed_map[j]].file, failed[failed_map[j]].file_pos, state->block_size);
+ 115 468172 : if (blockcmp(state, rehash, failed[failed_map[j]].block, pos_size, buffer[failed[failed_map[j]].index], buffer_zero) != 0) {
+ 116 13896 : log_tag("hash_error: Hash mismatch on entry %u\n", failed_map[j]);
+ 117 13896 : return 0;
118 : }
119 :
- 120 454438 : hash_checked = 1;
+ 120 454276 : hash_checked = 1;
121 : }
122 : }
123 :
124 : /* if nothing checked, we reject it */
125 : /* note that we are excluding this case at upper level */
126 : /* but checking again doesn't hurt */
- 127 195513 : if (!hash_checked) {
+ 127 195553 : if (!hash_checked) {
128 : /* LCOV_EXCL_START */
129 : return 0;
130 : /* LCOV_EXCL_STOP */
@@ -194,8 +194,8 @@
132 :
133 : /* if we checked something, and no block failed the check */
134 : /* recompute all the redundancy information */
- 135 195513 : raid_gen(diskmax, state->level, state->block_size, buffer);
- 136 195513 : return 1;
+ 135 195553 : raid_gen(diskmax, state->level, state->block_size, buffer);
+ 136 195553 : return 1;
137 : }
138 :
139 : /**
@@ -221,7 +221,7 @@
159 : * Return <0 if failure for missing strategy, >0 if data is wrong and we cannot rebuild correctly, 0 on success.
160 : * If success, the parity are computed in the buffer variable.
161 : */
- 162 260919 : static int repair_step(struct snapraid_state* state, int rehash, unsigned pos, unsigned diskmax, struct failed_struct* failed, unsigned* failed_map, unsigned failed_count, void** buffer, void** buffer_recov, void* buffer_zero)
+ 162 260805 : static int repair_step(struct snapraid_state* state, int rehash, unsigned pos, unsigned diskmax, struct failed_struct* failed, unsigned* failed_map, unsigned failed_count, void** buffer, void** buffer_recov, void* buffer_zero)
163 : {
164 : unsigned i, n;
165 : int error;
@@ -230,7 +230,7 @@
168 : int ip[LEV_MAX];
169 :
170 : /* no fix required, already checked at higher level, but just to be sure */
- 171 260919 : if (failed_count == 0) {
+ 171 260805 : if (failed_count == 0) {
172 : /* LCOV_EXCL_START */
173 : /* recompute only the parity */
174 : raid_gen(diskmax, state->level, state->block_size, buffer);
@@ -238,28 +238,28 @@
176 : /* LCOV_EXCL_STOP */
177 : }
178 :
- 179 260919 : n = state->level;
- 180 260919 : error = 0;
+ 179 260805 : n = state->level;
+ 180 260805 : error = 0;
181 :
182 : /* setup vector of failed disk indexes */
- 183 908931 : for (i = 0; i < failed_count; ++i)
- 184 648012 : id[i] = failed[failed_map[i]].index;
+ 183 908349 : for (i = 0; i < failed_count; ++i)
+ 184 647544 : id[i] = failed[failed_map[i]].index;
185 :
186 : /* check if there is at least a failed block that can be checked for correctness using the hash */
187 : /* if there isn't, we have to sacrifice a parity block to check that the result is correct */
- 188 260919 : has_hash = 0;
- 189 908931 : for (i = 0; i < failed_count; ++i) {
+ 188 260805 : has_hash = 0;
+ 189 908349 : for (i = 0; i < failed_count; ++i) {
190 : /* if we are expected to recover this block */
- 191 648012 : if (!failed[failed_map[i]].is_outofdate
+ 191 647544 : if (!failed[failed_map[i]].is_outofdate
192 : /* if the block has a hash to check */
- 193 638968 : && block_has_updated_hash(failed[failed_map[i]].block)
+ 193 638500 : && block_has_updated_hash(failed[failed_map[i]].block)
194 : )
- 195 630582 : has_hash = 1;
+ 195 630114 : has_hash = 1;
196 : }
197 :
198 : /* if we don't have a hash, but we have an extra parity */
199 : /* (strictly-less failures than number of parities) */
- 200 260919 : if (!has_hash && failed_count < n) {
+ 200 260805 : if (!has_hash && failed_count < n) {
201 : /* number of parity to use, one more to check the recovering */
202 8386 : unsigned r = failed_count + 1;
203 :
@@ -299,54 +299,54 @@
237 :
238 : /* if we have a hash, and enough parities */
239 : /* (less-or-equal failures than number of parities) */
- 240 252533 : if (has_hash && failed_count <= n) {
+ 240 252419 : if (has_hash && failed_count <= n) {
241 : /* number of parities to use equal at the number of failures */
- 242 204669 : unsigned r = failed_count;
+ 242 204707 : unsigned r = failed_count;
243 :
244 : /* all combinations (r of n) parities */
- 245 204669 : combination_first(r, n, ip);
+ 245 204707 : combination_first(r, n, ip);
246 : do {
247 : /* if a parity is missing, do nothing */
- 248 686926 : for (i = 0; i < r; ++i) {
- 249 477511 : if (buffer_recov[ip[i]] == 0)
+ 248 686792 : for (i = 0; i < r; ++i) {
+ 249 477343 : if (buffer_recov[ip[i]] == 0)
250 4649 : break;
251 : }
- 252 214064 : if (i != r)
+ 252 214098 : if (i != r)
253 4649 : continue;
254 :
255 : /* copy the parities to use */
- 256 682277 : for (i = 0; i < r; ++i)
- 257 472862 : memcpy(buffer[diskmax + ip[i]], buffer_recov[ip[i]], state->block_size);
+ 256 682143 : for (i = 0; i < r; ++i)
+ 257 472694 : memcpy(buffer[diskmax + ip[i]], buffer_recov[ip[i]], state->block_size);
258 :
259 : /* recover */
- 260 209415 : raid_data(r, id, ip, diskmax, state->block_size, buffer);
+ 260 209449 : raid_data(r, id, ip, diskmax, state->block_size, buffer);
261 :
262 : /* use the hash to check the result */
- 263 209415 : if (is_hash_matching(state, rehash, diskmax, failed, failed_map, failed_count, buffer, buffer_zero))
- 264 195513 : return 0;
+ 263 209449 : if (is_hash_matching(state, rehash, diskmax, failed, failed_map, failed_count, buffer, buffer_zero))
+ 264 195553 : return 0;
265 :
266 : /* log */
- 267 13902 : log_tag("parity_error:%u:", pos);
- 268 27804 : for (i = 0; i < r; ++i) {
- 269 13902 : if (i != 0)
+ 267 13896 : log_tag("parity_error:%u:", pos);
+ 268 27792 : for (i = 0; i < r; ++i) {
+ 269 13896 : if (i != 0)
270 0 : log_tag("/");
- 271 13902 : log_tag("%s", lev_config_name(ip[i]));
+ 271 13896 : log_tag("%s", lev_config_name(ip[i]));
272 : }
- 273 13902 : log_tag(":hash: Hash mismatch\n");
- 274 13902 : ++error;
- 275 37102 : } while (combination_next(r, n, ip));
+ 273 13896 : log_tag(":hash: Hash mismatch\n");
+ 274 13896 : ++error;
+ 275 37090 : } while (combination_next(r, n, ip));
276 : }
277 :
278 : /* return the number of failed attempts, or -1 if no strategy */
- 279 57020 : if (error)
- 280 9156 : return error;
+ 279 56866 : if (error)
+ 280 9154 : return error;
281 :
- 282 47864 : log_tag("strategy_error:%u: No strategy to recover from %u failures with %u parity %s hash\n",
+ 282 47712 : log_tag("strategy_error:%u: No strategy to recover from %u failures with %u parity %s hash\n",
283 : pos, failed_count, n, has_hash ? "with" : "without");
- 284 47864 : return -1;
+ 284 47712 : return -1;
285 : }
286 :
- 287 869090 : static int repair(struct snapraid_state* state, int rehash, unsigned pos, unsigned diskmax, struct failed_struct* failed, unsigned* failed_map, unsigned failed_count, void** buffer, void** buffer_recov, void* buffer_zero)
+ 287 869089 : static int repair(struct snapraid_state* state, int rehash, unsigned pos, unsigned diskmax, struct failed_struct* failed, unsigned* failed_map, unsigned failed_count, void** buffer, void** buffer_recov, void* buffer_zero)
288 : {
289 : int ret;
290 : int error;
@@ -355,51 +355,51 @@
293 : int something_to_recover;
294 : int something_unsynced;
295 :
- 296 869090 : error = 0;
+ 296 869089 : error = 0;
297 :
298 : /* if nothing failed, just recompute the parity */
- 299 869090 : if (failed_count == 0) {
- 300 581319 : raid_gen(diskmax, state->level, state->block_size, buffer);
- 301 581319 : return 0;
+ 299 869089 : if (failed_count == 0) {
+ 300 581432 : raid_gen(diskmax, state->level, state->block_size, buffer);
+ 301 581432 : return 0;
302 : }
303 :
304 : /* logs the status */
- 305 1017302 : for (j = 0; j < failed_count; ++j) {
+ 305 1016720 : for (j = 0; j < failed_count; ++j) {
306 : const char* desc;
307 : const char* hash;
308 : const char* data;
- 309 729531 : struct snapraid_block* block = failed[j].block;
- 310 729531 : unsigned block_state = block_state_get(block);
+ 309 729063 : struct snapraid_block* block = failed[j].block;
+ 310 729063 : unsigned block_state = block_state_get(block);
311 :
- 312 729531 : switch (block_state) {
+ 312 729063 : switch (block_state) {
313 18454 : case BLOCK_STATE_DELETED : desc = "delete"; break;
314 52081 : case BLOCK_STATE_CHG : desc = "change"; break;
315 24042 : case BLOCK_STATE_REP : desc = "replace"; break;
- 316 634954 : case BLOCK_STATE_BLK : desc = "block"; break;
+ 316 634486 : case BLOCK_STATE_BLK : desc = "block"; break;
317 : /* LCOV_EXCL_START */
318 : default : desc = "unknown"; break;
319 : /* LCOV_EXCL_STOP */
320 : }
321 :
- 322 729531 : if (hash_is_invalid(block->hash)) {
+ 322 729063 : if (hash_is_invalid(block->hash)) {
323 13841 : hash = "lost";
- 324 715690 : } else if (hash_is_zero(block->hash)) {
+ 324 715222 : } else if (hash_is_zero(block->hash)) {
325 29602 : hash = "zero";
326 : } else {
- 327 686088 : hash = "known";
+ 327 685620 : hash = "known";
328 : }
329 :
- 330 729531 : if (failed[j].is_bad)
- 331 643808 : data = "bad";
+ 330 729063 : if (failed[j].is_bad)
+ 331 643340 : data = "bad";
332 : else
333 85723 : data = "good";
334 :
- 335 729531 : if (failed[j].file) {
- 336 711077 : struct snapraid_disk* disk = failed[j].disk;
- 337 711077 : struct snapraid_file* file = failed[j].file;
- 338 711077 : block_off_t file_pos = failed[j].file_pos;
+ 335 729063 : if (failed[j].file) {
+ 336 710609 : struct snapraid_disk* disk = failed[j].disk;
+ 337 710609 : struct snapraid_file* file = failed[j].file;
+ 338 710609 : block_off_t file_pos = failed[j].file_pos;
339 :
- 340 711077 : log_tag("entry:%u:%s:%s:%s:%s:%s:%u:\n", j, desc, hash, data, disk->name, esc(file->sub), file_pos);
+ 340 710609 : log_tag("entry:%u:%s:%s:%s:%s:%s:%u:\n", j, desc, hash, data, disk->name, esc(file->sub), file_pos);
341 : } else {
342 18454 : log_tag("entry:%u:%s:%s:%s:\n", j, desc, hash, data);
343 : }
@@ -421,35 +421,35 @@
359 : /* We are interested to recover BLK, REP and CHG blocks if they are marked as bad, */
360 : /* but we are not interested in DELETED ones. */
361 :
- 362 287771 : n = 0;
- 363 287771 : something_to_recover = 0; /* keep track if there is at least one block to fix */
- 364 1017302 : for (j = 0; j < failed_count; ++j) {
- 365 729531 : if (failed[j].is_bad) {
- 366 643808 : unsigned block_state = block_state_get(failed[j].block);
+ 362 287657 : n = 0;
+ 363 287657 : something_to_recover = 0; /* keep track if there is at least one block to fix */
+ 364 1016720 : for (j = 0; j < failed_count; ++j) {
+ 365 729063 : if (failed[j].is_bad) {
+ 366 643340 : unsigned block_state = block_state_get(failed[j].block);
367 :
- 368 643808 : assert(block_state != BLOCK_STATE_DELETED); /* we cannot have bad DELETED blocks */
+ 368 643340 : assert(block_state != BLOCK_STATE_DELETED); /* we cannot have bad DELETED blocks */
369 :
370 : /* if we have the hash for it */
- 371 643808 : if ((block_state == BLOCK_STATE_BLK || block_state == BLOCK_STATE_REP)
+ 371 643340 : if ((block_state == BLOCK_STATE_BLK || block_state == BLOCK_STATE_REP)
372 : /* try to fetch the block using the known hash */
- 373 635422 : && (state_import_fetch(state, rehash, failed[j].block, buffer[failed[j].index]) == 0
- 374 630950 : || state_search_fetch(state, rehash, failed[j].file, failed[j].file_pos, failed[j].block, buffer[failed[j].index]) == 0)
+ 373 634954 : && (state_import_fetch(state, rehash, failed[j].block, buffer[failed[j].index]) == 0
+ 374 630482 : || state_search_fetch(state, rehash, failed[j].file, failed[j].file_pos, failed[j].block, buffer[failed[j].index]) == 0)
375 : ) {
376 : /* we already have corrected it! */
377 13884 : log_tag("hash_import: Fixed entry %u\n", j);
378 : } else {
379 : /* otherwise try to recover it */
- 380 629924 : failed_map[n] = j;
- 381 629924 : ++n;
+ 380 629456 : failed_map[n] = j;
+ 381 629456 : ++n;
382 :
383 : /* we have something to try to recover */
- 384 629924 : something_to_recover = 1;
+ 384 629456 : something_to_recover = 1;
385 : }
386 : }
387 : }
388 :
389 : /* if nothing to fix */
- 390 287771 : if (!something_to_recover) {
+ 390 287657 : if (!something_to_recover) {
391 35896 : log_tag("recover_sync:%u:%u: Skipped for already recovered\n", pos, n);
392 :
393 : /* recompute only the parity */
@@ -457,22 +457,22 @@
395 35896 : return 0;
396 : }
397 :
- 398 251875 : ret = repair_step(state, rehash, pos, diskmax, failed, failed_map, n, buffer, buffer_recov, buffer_zero);
- 399 251875 : if (ret == 0) {
+ 398 251761 : ret = repair_step(state, rehash, pos, diskmax, failed, failed_map, n, buffer, buffer_recov, buffer_zero);
+ 399 251761 : if (ret == 0) {
400 : /* reprocess the CHG blocks, for which we don't have a hash to check */
401 : /* if they were BAD we have to use some euristics to ensure that we have recovered */
402 : /* the state after the sync. If unsure, we assume the worst case */
403 :
- 404 683980 : for (j = 0; j < failed_count; ++j) {
+ 404 683858 : for (j = 0; j < failed_count; ++j) {
405 : /* we take care only of BAD blocks we have to write back */
- 406 484603 : if (failed[j].is_bad) {
- 407 471091 : unsigned block_state = block_state_get(failed[j].block);
+ 406 484441 : if (failed[j].is_bad) {
+ 407 470929 : unsigned block_state = block_state_get(failed[j].block);
408 :
409 : /* BLK and REP blocks are always OK, because at this point */
410 : /* we have already checked their hash */
- 411 471091 : if (block_state != BLOCK_STATE_CHG) {
- 412 462705 : assert(block_state == BLOCK_STATE_BLK || block_state == BLOCK_STATE_REP);
- 413 462705 : continue;
+ 411 470929 : if (block_state != BLOCK_STATE_CHG) {
+ 412 462543 : assert(block_state == BLOCK_STATE_BLK || block_state == BLOCK_STATE_REP);
+ 413 462543 : continue;
414 : }
415 :
416 : /* for CHG blocks we have to 'guess' if they are correct or not */
@@ -514,15 +514,15 @@
452 : }
453 : }
454 :
- 455 199377 : return 0;
+ 455 199417 : return 0;
456 : }
- 457 52498 : if (ret > 0)
- 458 9156 : error += ret;
+ 457 52344 : if (ret > 0)
+ 458 9154 : error += ret;
459 :
- 460 52498 : if (ret < 0)
- 461 43342 : log_tag("recover_sync:%u:%u: Failed with no attempts\n", pos, n);
+ 460 52344 : if (ret < 0)
+ 461 43190 : log_tag("recover_sync:%u:%u: Failed with no attempts\n", pos, n);
462 : else
- 463 9156 : log_tag("recover_sync:%u:%u: Failed with %d attempts\n", pos, n, ret);
+ 463 9154 : log_tag("recover_sync:%u:%u: Failed with %d attempts\n", pos, n, ret);
464 :
465 : /* Now assume that the parity IS NOT updated at the current state, */
466 : /* but still represent the state before the last 'sync' process. */
@@ -532,15 +532,15 @@
470 : /* but we are not interested to recover CHG (new version) and REP (new version) blocks, */
471 : /* even if marked as bad, because we don't have parity for them and it's just impossible, */
472 : /* and we are not interested to recover DELETED ones. */
- 473 52498 : n = 0;
- 474 52498 : something_to_recover = 0; /* keep track if there is at least one block to fix */
- 475 52498 : something_unsynced = 0; /* keep track if we have some unsynced info to process */
- 476 233164 : for (j = 0; j < failed_count; ++j) {
- 477 180666 : unsigned block_state = block_state_get(failed[j].block);
+ 473 52344 : n = 0;
+ 474 52344 : something_to_recover = 0; /* keep track if there is at least one block to fix */
+ 475 52344 : something_unsynced = 0; /* keep track if we have some unsynced info to process */
+ 476 232704 : for (j = 0; j < failed_count; ++j) {
+ 477 180360 : unsigned block_state = block_state_get(failed[j].block);
478 :
- 479 180666 : if (block_state == BLOCK_STATE_DELETED
- 480 171622 : || block_state == BLOCK_STATE_CHG
- 481 171622 : || block_state == BLOCK_STATE_REP
+ 479 180360 : if (block_state == BLOCK_STATE_DELETED
+ 480 171316 : || block_state == BLOCK_STATE_CHG
+ 481 171316 : || block_state == BLOCK_STATE_REP
482 : ) {
483 : /* If the block is CHG, REP or DELETED, we don't have the original content of block, */
484 : /* and we must try to recover it. */
@@ -582,24 +582,24 @@
520 : /* it also applies to CHG and DELETE blocks because we want to have */
521 : /* a succesful recovering only if a BLK one is matching */
522 9044 : failed[j].is_outofdate = 1;
- 523 171622 : } else if (failed[j].is_bad) {
+ 523 171316 : } else if (failed[j].is_bad) {
524 : /* If the block is bad we don't know its content, and we try to recover it */
525 : /* At this point, we can have only BLK ones */
526 :
- 527 171622 : assert(block_state == BLOCK_STATE_BLK);
+ 527 171316 : assert(block_state == BLOCK_STATE_BLK);
528 :
529 : /* we have something we are interested to recover */
- 530 171622 : something_to_recover = 1;
+ 530 171316 : something_to_recover = 1;
531 :
532 : /* we try to recover it */
- 533 171622 : failed_map[n] = j;
- 534 171622 : ++n;
+ 533 171316 : failed_map[n] = j;
+ 534 171316 : ++n;
535 : }
536 : }
537 :
538 : /* if nothing to fix, we just don't try */
539 : /* if nothing unsynced we also don't retry, because it's the same try as before */
- 540 52498 : if (something_to_recover && something_unsynced) {
+ 540 52344 : if (something_to_recover && something_unsynced) {
541 9044 : ret = repair_step(state, rehash, pos, diskmax, failed, failed_map, n, buffer, buffer_recov, buffer_zero);
542 9044 : if (ret == 0) {
543 : /* reprocess the REP and CHG blocks, for which we have recovered and old state */
@@ -633,17 +633,17 @@
571 : else
572 0 : log_tag("recover_unsync:%u:%u: Failed with %d attempts\n", pos, n, ret);
573 : } else {
- 574 43454 : log_tag("recover_unsync:%u:%u: Skipped for%s%s\n", pos, n,
+ 574 43300 : log_tag("recover_unsync:%u:%u: Skipped for%s%s\n", pos, n,
575 : !something_to_recover ? " nothing to recover" : "",
576 : !something_unsynced ? " nothing unsynched" : ""
577 : );
578 : }
579 :
580 : /* return the number of failed attempts, or -1 if no strategy */
- 581 47976 : if (error)
- 582 4634 : return error;
+ 581 47822 : if (error)
+ 582 4632 : return error;
583 : else
- 584 43342 : return -1;
+ 584 43190 : return -1;
585 : }
586 :
587 : /**
@@ -715,12 +715,12 @@
653 : /* rename it to .unrecoverable */
654 : char path_to[PATH_MAX];
655 :
- 656 65043 : pathprint(path_to, sizeof(path_to), "%s%s.unrecoverable", disk->dir, file->sub);
+ 656 64972 : pathprint(path_to, sizeof(path_to), "%s%s.unrecoverable", disk->dir, file->sub);
657 :
658 : /* ensure to close the file before renaming */
- 659 65043 : if (handle[j].file == file) {
- 660 65043 : ret = handle_close(&handle[j]);
- 661 65043 : if (ret != 0) {
+ 659 64972 : if (handle[j].file == file) {
+ 660 64972 : ret = handle_close(&handle[j]);
+ 661 64972 : if (ret != 0) {
662 : /* LCOV_EXCL_START */
663 : log_tag("error:%u:%s:%s: Close error. %s\n", i, disk->name, esc(file->sub), strerror(errno));
664 : log_fatal("DANGER! Unexpected close error in a data disk.\n");
@@ -729,8 +729,8 @@
667 : }
668 : }
669 :
- 670 65043 : ret = rename(path, path_to);
- 671 65043 : if (ret != 0) {
+ 670 64972 : ret = rename(path, path_to);
+ 671 64972 : if (ret != 0) {
672 : /* LCOV_EXCL_START */
673 : log_fatal("Error renaming '%s' to '%s'. %s.\n", path, path_to, strerror(errno));
674 : log_fatal("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n");
@@ -738,22 +738,22 @@
676 : /* LCOV_EXCL_STOP */
677 : }
678 :
- 679 65043 : log_tag("status:unrecoverable:%s:%s\n", disk->name, esc(file->sub));
- 680 65043 : msg_info("unrecoverable %s\n", path);
+ 679 64972 : log_tag("status:unrecoverable:%s:%s\n", disk->name, esc(file->sub));
+ 680 64972 : msg_info("unrecoverable %s\n", path);
681 :
682 : /* and do not set the time if damaged */
- 683 65043 : goto close_and_continue;
+ 683 64972 : goto close_and_continue;
684 : }
685 :
686 : /* if the file is not fixed, meaning that it is untouched */
- 687 691999 : if (!file_flag_has(file, FILE_IS_FIXED)) {
+ 687 692070 : if (!file_flag_has(file, FILE_IS_FIXED)) {
688 : /* nothing to do, but close the file */
- 689 574163 : goto close_and_continue;
+ 689 574306 : goto close_and_continue;
690 : }
691 :
692 : /* if the file is closed or different than the one expected, reopen it */
693 : /* a different open file could happen when filtering for bad blocks */
- 694 117836 : if (handle[j].file != file) {
+ 694 117764 : if (handle[j].file != file) {
695 : /* close a potential different file */
696 0 : ret = handle_close(&handle[j]);
697 0 : if (ret != 0) {
@@ -776,13 +776,13 @@
714 : }
715 : }
716 :
- 717 117836 : log_tag("status:recovered:%s:%s\n", disk->name, esc(file->sub));
- 718 117836 : msg_info("recovered %s\n", path);
+ 717 117764 : log_tag("status:recovered:%s:%s\n", disk->name, esc(file->sub));
+ 718 117764 : msg_info("recovered %s\n", path);
719 :
- 720 117836 : inode = handle[j].st.st_ino;
+ 720 117764 : inode = handle[j].st.st_ino;
721 :
722 : /* search for the corresponding inode */
- 723 117836 : collide_file = tommy_hashdyn_search(&disk->inodeset, file_inode_compare_to_arg, &inode, file_inode_hash(inode));
+ 723 117764 : collide_file = tommy_hashdyn_search(&disk->inodeset, file_inode_compare_to_arg, &inode, file_inode_hash(inode));
724 :
725 : /* if the inode is already in the database and it refers at a different file name, */
726 : /* we can fix the file time ONLY if the time and size allow to differentiate */
@@ -792,15 +792,15 @@
730 : /* when recreating them the inodes may be reused in a different order, */
731 : /* and at the next sync some files may have matching inode/size/time even if different name */
732 : /* not allowing sync to detect that the file is changed and not renamed */
- 733 117836 : if (!collide_file /* if not in the database, there is no collision */
- 734 31552 : || strcmp(collide_file->sub, file->sub) == 0 /* if the name is the same, it's the right collision */
- 735 30029 : || collide_file->size != file->size /* if the size is different, the collision is identified */
- 736 8 : || collide_file->mtime_sec != file->mtime_sec /* if the mtime is different, the collision is identified */
- 737 6 : || collide_file->mtime_nsec != file->mtime_nsec /* same for mtime_nsec */
+ 733 117764 : if (!collide_file /* if not in the database, there is no collision */
+ 734 29250 : || strcmp(collide_file->sub, file->sub) == 0 /* if the name is the same, it's the right collision */
+ 735 27741 : || collide_file->size != file->size /* if the size is different, the collision is identified */
+ 736 5 : || collide_file->mtime_sec != file->mtime_sec /* if the mtime is different, the collision is identified */
+ 737 3 : || collide_file->mtime_nsec != file->mtime_nsec /* same for mtime_nsec */
738 : ) {
739 : /* set the original modification time */
- 740 117835 : ret = handle_utime(&handle[j]);
- 741 235670 : if (ret == -1) {
+ 740 117763 : ret = handle_utime(&handle[j]);
+ 741 235526 : if (ret == -1) {
742 : /* LCOV_EXCL_START */
743 : /* mark the file as damaged */
744 : file_flag_set(file, FILE_IS_DAMAGED);
@@ -815,21 +815,21 @@
753 : /* we are not fixing, but only checking */
754 : /* print just the final status */
755 1307318 : if (file_flag_has(file, FILE_IS_DAMAGED)) {
- 756 9521 : if (state->opt.auditonly) {
- 757 2859 : log_tag("status:damaged:%s:%s\n", disk->name, esc(file->sub));
- 758 2859 : msg_info("damaged %s\n", path);
+ 756 9389 : if (state->opt.auditonly) {
+ 757 2806 : log_tag("status:damaged:%s:%s\n", disk->name, esc(file->sub));
+ 758 2806 : msg_info("damaged %s\n", path);
759 : } else {
- 760 6662 : log_tag("status:unrecoverable:%s:%s\n", disk->name, esc(file->sub));
- 761 6662 : msg_info("unrecoverable %s\n", path);
+ 760 6583 : log_tag("status:unrecoverable:%s:%s\n", disk->name, esc(file->sub));
+ 761 6583 : msg_info("unrecoverable %s\n", path);
762 : }
- 763 1297797 : } else if (file_flag_has(file, FILE_IS_FIXED)) {
- 764 76467 : log_tag("status:recoverable:%s:%s\n", disk->name, esc(file->sub));
- 765 76467 : msg_info("recoverable %s\n", path);
+ 763 1297929 : } else if (file_flag_has(file, FILE_IS_FIXED)) {
+ 764 76370 : log_tag("status:recoverable:%s:%s\n", disk->name, esc(file->sub));
+ 765 76370 : msg_info("recoverable %s\n", path);
766 : } else {
- 767 1221330 : log_tag("status:correct:%s:%s\n", disk->name, esc(file->sub));
+ 767 1221559 : log_tag("status:correct:%s:%s\n", disk->name, esc(file->sub));
768 : /* we don't use msg_verbose() because it also goes into the log */
- 769 1221330 : if (msg_level >= MSG_VERBOSE)
- 770 23175 : msg_info("correct %s\n", path);
+ 769 1221559 : if (msg_level >= MSG_VERBOSE)
+ 770 23233 : msg_info("correct %s\n", path);
771 : }
772 : }
773 :
@@ -840,8 +840,8 @@
778 2161101 : if (handle[j].file == file) {
779 : /* ensure to close the file just after finishing with it */
780 : /* to avoid to keep it open without any possible use */
- 781 1975549 : ret = handle_close(&handle[j]);
- 782 1975549 : if (ret != 0) {
+ 781 1975748 : ret = handle_close(&handle[j]);
+ 782 1975748 : if (ret != 0) {
783 : /* LCOV_EXCL_START */
784 : log_tag("error:%u:%s:%s: Close error. %s\n", i, disk->name, esc(file->sub), strerror(errno));
785 : log_fatal("DANGER! Unexpected close error in a data disk.\n");
@@ -870,13 +870,13 @@
808 1866664 : if (state->opt.badonly) {
809 : /* skip if this is not bad */
810 18684 : if (!info_get_bad(info))
- 811 15078 : return 0;
+ 811 15080 : return 0;
812 : }
813 :
814 : /* for each parity */
- 815 2120450 : for (l = 0; l < state->level; ++l) {
- 816 2037334 : if (!state->parity[l].is_excluded) {
- 817 1768470 : return 1;
+ 815 2120448 : for (l = 0; l < state->level; ++l) {
+ 816 2037332 : if (!state->parity[l].is_excluded) {
+ 817 1768468 : return 1;
818 : }
819 : }
820 :
@@ -947,8 +947,8 @@
885 118 : countmax = 0;
886 933450 : for (i = blockstart; i < blockmax; ++i) {
887 933332 : if (!block_is_enabled(state, i, handle, diskmax))
- 888 25065 : continue;
- 889 908267 : ++countmax;
+ 888 25066 : continue;
+ 889 908266 : ++countmax;
890 : }
891 :
892 : /* check all the blocks in files */
@@ -963,15 +963,15 @@
901 :
902 933332 : if (!block_is_enabled(state, i, handle, diskmax)) {
903 : /* post process the files */
- 904 25065 : ret = file_post(state, fix, i, handle, diskmax);
- 905 25065 : if (ret == -1) {
+ 904 25066 : ret = file_post(state, fix, i, handle, diskmax);
+ 905 25066 : if (ret == -1) {
906 0 : log_fatal("Stopping at block %u\n", i);
907 0 : ++unrecoverable_error;
908 0 : goto bail;
909 : }
910 :
911 : /* and now continue with the next block */
- 912 25065 : continue;
+ 912 25066 : continue;
913 : }
914 :
915 : /* If we have valid parity, and it makes sense to check its content. */
@@ -979,19 +979,19 @@
917 : /* but we don't report parity errors */
918 : /* Note that with auditonly, we anyway skip the full parity check, */
919 : /* because we also don't read it at all */
- 920 908267 : valid_parity = 1;
+ 920 908266 : valid_parity = 1;
921 :
922 : /* keep track of the number of failed blocks */
- 923 908267 : failed_count = 0;
+ 923 908266 : failed_count = 0;
924 :
925 : /* get block specific info */
- 926 908267 : info = info_get(&state->infoarr, i);
+ 926 908266 : info = info_get(&state->infoarr, i);
927 :
928 : /* if we have to use the old hash */
- 929 908267 : rehash = info_get_rehash(info);
+ 929 908266 : rehash = info_get_rehash(info);
930 :
931 : /* for each disk, process the block */
- 932 6357869 : for (j = 0; j < diskmax; ++j) {
+ 932 6357862 : for (j = 0; j < diskmax; ++j) {
933 : int read_size;
934 : unsigned char hash[HASH_SIZE];
935 : struct snapraid_disk* disk;
@@ -1001,26 +1001,26 @@
939 : unsigned block_state;
940 :
941 : /* if the disk position is not used */
- 942 5449602 : disk = handle[j].disk;
- 943 5449602 : if (!disk) {
+ 942 5449596 : disk = handle[j].disk;
+ 943 5449596 : if (!disk) {
944 : /* use an empty block */
945 14013 : memset(buffer[j], 0, state->block_size);
- 946 952540 : continue;
+ 946 951802 : continue;
947 : }
948 :
949 : /* if the disk block is not used */
- 950 5435589 : block = fs_par2block_get(disk, i);
- 951 5435589 : if (block == BLOCK_EMPTY) {
+ 950 5435583 : block = fs_par2block_get(disk, i);
+ 951 5435583 : if (block == BLOCK_EMPTY) {
952 : /* use an empty block */
953 188862 : memset(buffer[j], 0, state->block_size);
954 188862 : continue;
955 : }
956 :
957 : /* get the state of the block */
- 958 5246727 : block_state = block_state_get(block);
+ 958 5246721 : block_state = block_state_get(block);
959 :
960 : /* if the parity is not valid */
- 961 5246727 : if (block_has_invalid_parity(block)) {
+ 961 5246721 : if (block_has_invalid_parity(block)) {
962 : /* mark the parity as invalid, and don't try to check/fix it */
963 : /* because it will be recomputed at the next sync */
964 94577 : valid_parity = 0;
@@ -1028,7 +1028,7 @@
966 : }
967 :
968 : /* if the block is DELETED */
- 969 5246727 : if (block_state == BLOCK_STATE_DELETED) {
+ 969 5246721 : if (block_state == BLOCK_STATE_DELETED) {
970 : /* use an empty block */
971 18454 : memset(buffer[j], 0, state->block_size);
972 :
@@ -1047,10 +1047,10 @@
985 : }
986 :
987 : /* get the file of this block */
- 988 5228273 : file = fs_par2file_get(disk, i, &file_pos);
+ 988 5228267 : file = fs_par2file_get(disk, i, &file_pos);
989 :
990 : /* if we are only hashing, we can skip excluded files and don't even read them */
- 991 5228273 : if (state->opt.auditonly && file_flag_has(file, FILE_IS_EXCLUDED)) {
+ 991 5228267 : if (state->opt.auditonly && file_flag_has(file, FILE_IS_EXCLUDED)) {
992 : /* use an empty block */
993 : /* in true, this is unnecessary, becase we are not checking any parity */
994 : /* but we keep it for completeness */
@@ -1059,10 +1059,10 @@
997 : }
998 :
999 : /* if the file is closed or different than the current one */
- 1000 5228273 : if (handle[j].file == 0 || handle[j].file != file) {
+ 1000 5228267 : if (handle[j].file == 0 || handle[j].file != file) {
1001 : /* close the old one, if any */
- 1002 2259132 : ret = handle_close(&handle[j]);
- 1003 2259132 : if (ret == -1) {
+ 1002 2258931 : ret = handle_close(&handle[j]);
+ 1003 2258931 : if (ret == -1) {
1004 : /* LCOV_EXCL_START */
1005 : log_tag("error:%u:%s:%s: Close error. %s\n", i, disk->name, esc(handle[j].file->sub), strerror(errno));
1006 : log_fatal("DANGER! Unexpected close error in a data disk.\n");
@@ -1073,10 +1073,10 @@
1011 : }
1012 :
1013 : /* if fixing, and the file is not excluded, we must open for writing */
- 1014 2259132 : if (fix && !file_flag_has(file, FILE_IS_EXCLUDED)) {
+ 1014 2258931 : if (fix && !file_flag_has(file, FILE_IS_EXCLUDED)) {
1015 : /* if fixing, create the file, open for writing and resize if required */
- 1016 771245 : ret = handle_create(&handle[j], file, state->file_mode);
- 1017 771245 : if (ret == -1) {
+ 1016 771210 : ret = handle_create(&handle[j], file, state->file_mode);
+ 1017 771210 : if (ret == -1) {
1018 : /* LCOV_EXCL_START */
1019 : if (errno == EACCES) {
1020 : log_fatal("WARNING! Please give write permission to the file.\n");
@@ -1090,69 +1090,69 @@
1028 : }
1029 :
1030 : /* check if the file was just created */
- 1031 1542490 : if (handle[j].created != 0) {
+ 1031 1542420 : if (handle[j].created != 0) {
1032 : /* if fragmented, it may be reopened, so remember that the file */
1033 : /* was originally missing */
- 1034 113043 : file_flag_set(file, FILE_IS_CREATED);
+ 1034 113024 : file_flag_set(file, FILE_IS_CREATED);
1035 : }
1036 : } else {
1037 : /* open the file only for reading */
- 1038 1487887 : if (!file_flag_has(file, FILE_IS_MISSING))
- 1039 1372035 : ret = handle_open(&handle[j], file, state->file_mode,
- 1040 1372035 : log_error, state->opt.expected_missing ? log_expected : 0);
+ 1038 1487721 : if (!file_flag_has(file, FILE_IS_MISSING))
+ 1039 1372062 : ret = handle_open(&handle[j], file, state->file_mode,
+ 1040 1372062 : log_error, state->opt.expected_missing ? log_expected : 0);
1041 : else
- 1042 115852 : ret = -1; /* if the file is missing, we cannot open it */
- 1043 1487887 : if (ret == -1) {
+ 1042 115659 : ret = -1; /* if the file is missing, we cannot open it */
+ 1043 1487721 : if (ret == -1) {
1044 : /* save the failed block for the check/fix */
- 1045 194739 : failed[failed_count].is_bad = 1;
- 1046 194739 : failed[failed_count].is_outofdate = 0;
- 1047 194739 : failed[failed_count].index = j;
- 1048 194739 : failed[failed_count].block = block;
- 1049 194739 : failed[failed_count].disk = disk;
- 1050 194739 : failed[failed_count].file = file;
- 1051 194739 : failed[failed_count].file_pos = file_pos;
- 1052 194739 : failed[failed_count].handle = &handle[j];
- 1053 194739 : ++failed_count;
+ 1045 194418 : failed[failed_count].is_bad = 1;
+ 1046 194418 : failed[failed_count].is_outofdate = 0;
+ 1047 194418 : failed[failed_count].index = j;
+ 1048 194418 : failed[failed_count].block = block;
+ 1049 194418 : failed[failed_count].disk = disk;
+ 1050 194418 : failed[failed_count].file = file;
+ 1051 194418 : failed[failed_count].file_pos = file_pos;
+ 1052 194418 : failed[failed_count].handle = &handle[j];
+ 1053 194418 : ++failed_count;
1054 :
- 1055 194739 : log_tag("error:%u:%s:%s: Open error at position %u\n", i, disk->name, esc(file->sub), file_pos);
- 1056 194739 : ++error;
+ 1055 194418 : log_tag("error:%u:%s:%s: Open error at position %u\n", i, disk->name, esc(file->sub), file_pos);
+ 1056 194418 : ++error;
1057 :
1058 : /* mark the file as missing, to avoid to retry to open it again */
1059 : /* note that this can be done only if we are not fixing it */
1060 : /* otherwise, it could be recreated */
- 1061 194739 : file_flag_set(file, FILE_IS_MISSING);
- 1062 194739 : continue;
+ 1061 194418 : file_flag_set(file, FILE_IS_MISSING);
+ 1062 194418 : continue;
1063 : }
1064 : }
1065 :
1066 : /* if it's the first open, and not excluded */
- 1067 2064393 : if (!file_flag_has(file, FILE_IS_OPENED)
- 1068 2049054 : && !file_flag_has(file, FILE_IS_EXCLUDED)) {
+ 1067 2064513 : if (!file_flag_has(file, FILE_IS_OPENED)
+ 1068 2049148 : && !file_flag_has(file, FILE_IS_EXCLUDED)) {
1069 :
1070 : /* check if the file is changed */
- 1071 1997699 : if (handle[j].st.st_size != file->size
- 1072 1804789 : || handle[j].st.st_mtime != file->mtime_sec
- 1073 1780584 : || STAT_NSEC(&handle[j].st) != file->mtime_nsec
+ 1071 1997793 : if (handle[j].st.st_size != file->size
+ 1072 1804861 : || handle[j].st.st_mtime != file->mtime_sec
+ 1073 1780308 : || STAT_NSEC(&handle[j].st) != file->mtime_nsec
1074 : /* don't check the inode to support filesystem without persistent inodes */
1075 : ) {
1076 : /* report that the file is not synced */
- 1077 217115 : file_flag_set(file, FILE_IS_UNSYNCED);
+ 1077 217485 : file_flag_set(file, FILE_IS_UNSYNCED);
1078 : }
1079 : }
1080 :
1081 : /* if it's the first open, and not excluded and larger */
- 1082 2064393 : if (!file_flag_has(file, FILE_IS_OPENED)
- 1083 2049054 : && !file_flag_has(file, FILE_IS_EXCLUDED)
- 1084 1997699 : && !(state->opt.syncedonly && file_flag_has(file, FILE_IS_UNSYNCED))
- 1085 1997699 : && handle[j].st.st_size > file->size
+ 1082 2064513 : if (!file_flag_has(file, FILE_IS_OPENED)
+ 1083 2049148 : && !file_flag_has(file, FILE_IS_EXCLUDED)
+ 1084 1997793 : && !(state->opt.syncedonly && file_flag_has(file, FILE_IS_UNSYNCED))
+ 1085 1997793 : && handle[j].st.st_size > file->size
1086 : ) {
- 1087 8622 : log_error("File '%s' is larger than expected.\n", handle[j].path);
- 1088 8622 : log_tag("error:%u:%s:%s: Size error\n", i, disk->name, esc(file->sub));
- 1089 8622 : ++error;
+ 1087 8781 : log_error("File '%s' is larger than expected.\n", handle[j].path);
+ 1088 8781 : log_tag("error:%u:%s:%s: Size error\n", i, disk->name, esc(file->sub));
+ 1089 8781 : ++error;
1090 :
- 1091 8622 : if (fix) {
- 1092 3177 : ret = handle_truncate(&handle[j], file);
- 1093 3177 : if (ret == -1) {
+ 1091 8781 : if (fix) {
+ 1092 3249 : ret = handle_truncate(&handle[j], file);
+ 1093 3249 : if (ret == -1) {
1094 : /* LCOV_EXCL_START */
1095 : log_fatal("DANGER! Unexpected truncate error in a data disk, it isn't possible to fix.\n");
1096 : log_fatal("Stopping at block %u\n", i);
@@ -1161,43 +1161,43 @@
1099 : /* LCOV_EXCL_STOP */
1100 : }
1101 :
- 1102 3177 : log_tag("fixed:%u:%s:%s: Fixed size\n", i, disk->name, esc(file->sub));
- 1103 3177 : ++recovered_error;
+ 1102 3249 : log_tag("fixed:%u:%s:%s: Fixed size\n", i, disk->name, esc(file->sub));
+ 1103 3249 : ++recovered_error;
1104 : }
1105 : }
1106 :
1107 : /* mark the file as opened at least one time */
1108 : /* this is used to avoid to check the unsynced and size */
1109 : /* more than one time, in case the file is reopened later */
- 1110 2064393 : file_flag_set(file, FILE_IS_OPENED);
+ 1110 2064513 : file_flag_set(file, FILE_IS_OPENED);
1111 : }
1112 :
1113 : /* read from the file */
- 1114 5033534 : read_size = handle_read(&handle[j], file_pos, buffer[j], state->block_size,
- 1115 5033534 : log_error, state->opt.expected_missing ? log_expected : 0);
- 1116 5033534 : if (read_size == -1) {
+ 1114 5033849 : read_size = handle_read(&handle[j], file_pos, buffer[j], state->block_size,
+ 1115 5033849 : log_error, state->opt.expected_missing ? log_expected : 0);
+ 1116 5033849 : if (read_size == -1) {
1117 : /* save the failed block for the check/fix */
- 1118 442375 : failed[failed_count].is_bad = 1; /* it's bad because we cannot read it */
- 1119 442375 : failed[failed_count].is_outofdate = 0;
- 1120 442375 : failed[failed_count].index = j;
- 1121 442375 : failed[failed_count].block = block;
- 1122 442375 : failed[failed_count].disk = disk;
- 1123 442375 : failed[failed_count].file = file;
- 1124 442375 : failed[failed_count].file_pos = file_pos;
- 1125 442375 : failed[failed_count].handle = &handle[j];
- 1126 442375 : ++failed_count;
+ 1118 442025 : failed[failed_count].is_bad = 1; /* it's bad because we cannot read it */
+ 1119 442025 : failed[failed_count].is_outofdate = 0;
+ 1120 442025 : failed[failed_count].index = j;
+ 1121 442025 : failed[failed_count].block = block;
+ 1122 442025 : failed[failed_count].disk = disk;
+ 1123 442025 : failed[failed_count].file = file;
+ 1124 442025 : failed[failed_count].file_pos = file_pos;
+ 1125 442025 : failed[failed_count].handle = &handle[j];
+ 1126 442025 : ++failed_count;
1127 :
- 1128 442375 : log_tag("error:%u:%s:%s: Read error at position %u\n", i, disk->name, esc(file->sub), file_pos);
- 1129 442375 : ++error;
- 1130 442375 : continue;
+ 1128 442025 : log_tag("error:%u:%s:%s: Read error at position %u\n", i, disk->name, esc(file->sub), file_pos);
+ 1129 442025 : ++error;
+ 1130 442025 : continue;
1131 : }
1132 :
- 1133 4591159 : countsize += read_size;
+ 1133 4591824 : countsize += read_size;
1134 :
1135 : /* always insert CHG blocks, the repair functions needs all of them */
1136 : /* because the parity may be still referring at the old state */
1137 : /* and the repair must be aware of it */
- 1138 4591159 : if (block_state == BLOCK_STATE_CHG) {
+ 1138 4591824 : if (block_state == BLOCK_STATE_CHG) {
1139 : /* we DO NOT mark them as bad to avoid to overwrite them with wrong data. */
1140 : /* if we don't have a hash, we always assume the first read of the block correct. */
1141 43695 : failed[failed_count].is_bad = 0; /* we assume the CHG block correct */
@@ -1212,39 +1212,39 @@
1150 43695 : continue;
1151 : }
1152 :
- 1153 4547464 : assert(block_state == BLOCK_STATE_BLK || block_state == BLOCK_STATE_REP);
+ 1153 4548129 : assert(block_state == BLOCK_STATE_BLK || block_state == BLOCK_STATE_REP);
1154 :
1155 : /* compute the hash of the block just read */
- 1156 4547464 : if (rehash) {
- 1157 286659 : memhash(state->prevhash, state->prevhashseed, hash, buffer[j], read_size);
+ 1156 4548129 : if (rehash) {
+ 1157 286660 : memhash(state->prevhash, state->prevhashseed, hash, buffer[j], read_size);
1158 : } else {
- 1159 4260805 : memhash(state->hash, state->hashseed, hash, buffer[j], read_size);
+ 1159 4261469 : memhash(state->hash, state->hashseed, hash, buffer[j], read_size);
1160 : }
1161 :
1162 : /* compare the hash */
- 1163 4547464 : if (memcmp(hash, block->hash, HASH_SIZE) != 0) {
- 1164 12815 : unsigned diff = memdiff(hash, block->hash, HASH_SIZE);
+ 1163 4548129 : if (memcmp(hash, block->hash, HASH_SIZE) != 0) {
+ 1164 12748 : unsigned diff = memdiff(hash, block->hash, HASH_SIZE);
1165 :
1166 : /* save the failed block for the check/fix */
- 1167 12815 : failed[failed_count].is_bad = 1; /* it's bad because the hash doesn't match */
- 1168 12815 : failed[failed_count].is_outofdate = 0;
- 1169 12815 : failed[failed_count].index = j;
- 1170 12815 : failed[failed_count].block = block;
- 1171 12815 : failed[failed_count].disk = disk;
- 1172 12815 : failed[failed_count].file = file;
- 1173 12815 : failed[failed_count].file_pos = file_pos;
- 1174 12815 : failed[failed_count].handle = &handle[j];
- 1175 12815 : ++failed_count;
+ 1167 12748 : failed[failed_count].is_bad = 1; /* it's bad because the hash doesn't match */
+ 1168 12748 : failed[failed_count].is_outofdate = 0;
+ 1169 12748 : failed[failed_count].index = j;
+ 1170 12748 : failed[failed_count].block = block;
+ 1171 12748 : failed[failed_count].disk = disk;
+ 1172 12748 : failed[failed_count].file = file;
+ 1173 12748 : failed[failed_count].file_pos = file_pos;
+ 1174 12748 : failed[failed_count].handle = &handle[j];
+ 1175 12748 : ++failed_count;
1176 :
- 1177 12815 : log_tag("error:%u:%s:%s: Data error at position %u, diff bits %u\n", i, disk->name, esc(file->sub), file_pos, diff);
- 1178 12815 : ++error;
- 1179 12815 : continue;
+ 1177 12748 : log_tag("error:%u:%s:%s: Data error at position %u, diff bits %u\n", i, disk->name, esc(file->sub), file_pos, diff);
+ 1178 12748 : ++error;
+ 1179 12748 : continue;
1180 : }
1181 :
1182 : /* always insert REP blocks, the repair functions needs all of them */
1183 : /* because the parity may be still referring at the old state */
1184 : /* and the repair must be aware of it */
- 1185 4534649 : if (block_state == BLOCK_STATE_REP) {
+ 1185 4535381 : if (block_state == BLOCK_STATE_REP) {
1186 23574 : failed[failed_count].is_bad = 0; /* it's not bad */
1187 23574 : failed[failed_count].is_outofdate = 0;
1188 23574 : failed[failed_count].index = j;
@@ -1259,24 +1259,24 @@
1197 : }
1198 :
1199 : /* now read and check the parity if requested */
- 1200 908267 : if (!state->opt.auditonly) {
+ 1200 908266 : if (!state->opt.auditonly) {
1201 : void* buffer_recov[LEV_MAX];
1202 : void* buffer_zero;
1203 :
1204 : /* buffers for parity read and not computed */
- 1205 4161705 : for (l = 0; l < state->level; ++l)
- 1206 3292615 : buffer_recov[l] = buffer[diskmax + state->level + l];
- 1207 2791015 : for (; l < LEV_MAX; ++l)
+ 1205 4161698 : for (l = 0; l < state->level; ++l)
+ 1206 3292609 : buffer_recov[l] = buffer[diskmax + state->level + l];
+ 1207 2791014 : for (; l < LEV_MAX; ++l)
1208 1921925 : buffer_recov[l] = 0;
1209 :
1210 : /* the zero buffer is the last one */
- 1211 869090 : buffer_zero = buffer[buffermax - 1];
+ 1211 869089 : buffer_zero = buffer[buffermax - 1];
1212 :
1213 : /* read the parity */
- 1214 4161705 : for (l = 0; l < state->level; ++l) {
- 1215 3292615 : if (parity[l]) {
- 1216 3278745 : ret = parity_read(parity[l], i, buffer_recov[l], state->block_size, log_error);
- 1217 3278745 : if (ret == -1) {
+ 1214 4161698 : for (l = 0; l < state->level; ++l) {
+ 1215 3292609 : if (parity[l]) {
+ 1216 3278739 : ret = parity_read(parity[l], i, buffer_recov[l], state->block_size, log_error);
+ 1217 3278739 : if (ret == -1) {
1218 90275 : buffer_recov[l] = 0; /* no parity to use */
1219 :
1220 90275 : log_tag("parity_error:%u:%s: Read error\n", i, lev_config_name(l));
@@ -1288,38 +1288,38 @@
1226 : }
1227 :
1228 : /* try all the recovering strategies */
- 1229 869090 : ret = repair(state, rehash, i, diskmax, failed, failed_map, failed_count, buffer, buffer_recov, buffer_zero);
- 1230 869090 : if (ret != 0) {
+ 1229 869089 : ret = repair(state, rehash, i, diskmax, failed, failed_map, failed_count, buffer, buffer_recov, buffer_zero);
+ 1230 869089 : if (ret != 0) {
1231 : /* increment the number of errors */
- 1232 47976 : if (ret > 0)
- 1233 4634 : error += ret;
- 1234 47976 : ++unrecoverable_error;
+ 1232 47822 : if (ret > 0)
+ 1233 4632 : error += ret;
+ 1234 47822 : ++unrecoverable_error;
1235 :
1236 : /* print a list of all the errors in files */
- 1237 219598 : for (j = 0; j < failed_count; ++j) {
- 1238 171622 : if (failed[j].is_bad)
- 1239 167100 : log_tag("unrecoverable:%u:%s:%s: Unrecoverable error at position %u\n", i, failed[j].disk->name, esc(failed[j].file->sub), failed[j].file_pos);
+ 1237 219138 : for (j = 0; j < failed_count; ++j) {
+ 1238 171316 : if (failed[j].is_bad)
+ 1239 166794 : log_tag("unrecoverable:%u:%s:%s: Unrecoverable error at position %u\n", i, failed[j].disk->name, esc(failed[j].file->sub), failed[j].file_pos);
1240 : }
1241 :
1242 : /* keep track of damaged files */
- 1243 219598 : for (j = 0; j < failed_count; ++j) {
- 1244 171622 : if (failed[j].is_bad)
- 1245 167100 : file_flag_set(failed[j].file, FILE_IS_DAMAGED);
+ 1243 219138 : for (j = 0; j < failed_count; ++j) {
+ 1244 171316 : if (failed[j].is_bad)
+ 1245 166794 : file_flag_set(failed[j].file, FILE_IS_DAMAGED);
1246 : }
1247 : } else {
1248 : /* now counts partial recovers */
1249 : /* note that this could happen only when we have an incomplete 'sync' */
1250 : /* and that we have recovered is the state before the 'sync' */
- 1251 821114 : int partial_recover_error = 0;
+ 1251 821267 : int partial_recover_error = 0;
1252 :
1253 : /* print a list of all the errors in files */
- 1254 1379023 : for (j = 0; j < failed_count; ++j) {
- 1255 557909 : if (failed[j].is_bad && failed[j].is_outofdate) {
+ 1254 1379014 : for (j = 0; j < failed_count; ++j) {
+ 1255 557747 : if (failed[j].is_bad && failed[j].is_outofdate) {
1256 4192 : ++partial_recover_error;
1257 4192 : log_tag("unrecoverable:%u:%s:%s: Unrecoverable unsynced error at position %u\n", i, failed[j].disk->name, esc(failed[j].file->sub), failed[j].file_pos);
1258 : }
1259 : }
- 1260 821114 : if (partial_recover_error != 0) {
+ 1260 821267 : if (partial_recover_error != 0) {
1261 4192 : error += partial_recover_error;
1262 4192 : ++unrecoverable_error;
1263 : }
@@ -1327,36 +1327,36 @@
1265 : /* now check parities, but only if all the blocks have it computed */
1266 : /* if you check/fix after a partial sync, it's OK to have parity errors on the blocks with invalid parity */
1267 : /* and doesn't make sense to try to fix it */
- 1268 821114 : if (valid_parity) {
+ 1268 821267 : if (valid_parity) {
1269 : /* check the parity */
- 1270 3718850 : for (l = 0; l < state->level; ++l) {
- 1271 2959425 : if (buffer_recov[l] != 0 && memcmp(buffer_recov[l], buffer[diskmax + l], state->block_size) != 0) {
- 1272 10638 : unsigned diff = memdiff(buffer_recov[l], buffer[diskmax + l], state->block_size);
+ 1270 3719151 : for (l = 0; l < state->level; ++l) {
+ 1271 2959573 : if (buffer_recov[l] != 0 && memcmp(buffer_recov[l], buffer[diskmax + l], state->block_size) != 0) {
+ 1272 10640 : unsigned diff = memdiff(buffer_recov[l], buffer[diskmax + l], state->block_size);
1273 :
1274 : /* mark that the read parity is wrong, setting ptr to 0 */
- 1275 10638 : buffer_recov[l] = 0;
+ 1275 10640 : buffer_recov[l] = 0;
1276 :
- 1277 10638 : log_tag("parity_error:%u:%s: Data error, diff bits %u\n", i, lev_config_name(l), diff);
- 1278 10638 : ++error;
+ 1277 10640 : log_tag("parity_error:%u:%s: Data error, diff bits %u\n", i, lev_config_name(l), diff);
+ 1278 10640 : ++error;
1279 : }
1280 : }
1281 : }
1282 :
1283 : /* now write recovered files */
- 1284 821114 : if (fix) {
+ 1284 821267 : if (fix) {
1285 : /* update the fixed files */
- 1286 651778 : for (j = 0; j < failed_count; ++j) {
+ 1286 651810 : for (j = 0; j < failed_count; ++j) {
1287 : /* nothing to do if it doesn't need recovering */
- 1288 337832 : if (!failed[j].is_bad)
+ 1288 337787 : if (!failed[j].is_bad)
1289 40318 : continue;
1290 :
1291 : /* do not fix if the file is excluded */
- 1292 297514 : if (file_flag_has(failed[j].file, FILE_IS_EXCLUDED)
- 1293 288250 : || (state->opt.syncedonly && file_flag_has(failed[j].file, FILE_IS_UNSYNCED)))
+ 1292 297469 : if (file_flag_has(failed[j].file, FILE_IS_EXCLUDED)
+ 1293 288205 : || (state->opt.syncedonly && file_flag_has(failed[j].file, FILE_IS_UNSYNCED)))
1294 9264 : continue;
1295 :
- 1296 288250 : ret = handle_write(failed[j].handle, failed[j].file_pos, buffer[failed[j].index], state->block_size);
- 1297 288250 : if (ret == -1) {
+ 1296 288205 : ret = handle_write(failed[j].handle, failed[j].file_pos, buffer[failed[j].index], state->block_size);
+ 1297 288205 : if (ret == -1) {
1298 : /* LCOV_EXCL_START */
1299 : /* mark the file as damaged */
1300 : file_flag_set(failed[j].file, FILE_IS_DAMAGED);
@@ -1374,7 +1374,7 @@
1312 : }
1313 :
1314 : /* if we are not sure that the recovered content is uptodate */
- 1315 288250 : if (failed[j].is_outofdate) {
+ 1315 288205 : if (failed[j].is_outofdate) {
1316 : /* mark the file as damaged */
1317 4192 : file_flag_set(failed[j].file, FILE_IS_DAMAGED);
1318 4192 : continue;
@@ -1382,20 +1382,20 @@
1320 :
1321 : /* mark the file as containing some fixes */
1322 : /* note that it could be also marked as damaged in other iterations */
- 1323 284058 : file_flag_set(failed[j].file, FILE_IS_FIXED);
+ 1323 284013 : file_flag_set(failed[j].file, FILE_IS_FIXED);
1324 :
- 1325 284058 : log_tag("fixed:%u:%s:%s: Fixed data error at position %u\n", i, failed[j].disk->name, esc(failed[j].file->sub), failed[j].file_pos);
- 1326 284058 : ++recovered_error;
+ 1325 284013 : log_tag("fixed:%u:%s:%s: Fixed data error at position %u\n", i, failed[j].disk->name, esc(failed[j].file->sub), failed[j].file_pos);
+ 1326 284013 : ++recovered_error;
1327 : }
1328 :
1329 : /* update parity only if all the blocks have it computed */
1330 : /* if you check/fix after a partial sync, you do not want to fix parity */
1331 : /* for blocks that are going to have it computed in the sync completion */
- 1332 313946 : if (valid_parity) {
+ 1332 314023 : if (valid_parity) {
1333 : /* update the parity */
- 1334 961633 : for (l = 0; l < state->level; ++l) {
+ 1334 961782 : for (l = 0; l < state->level; ++l) {
1335 : /* if the parity on disk is wrong */
- 1336 696859 : if (buffer_recov[l] == 0
+ 1336 696931 : if (buffer_recov[l] == 0
1337 : /* and we have access at the parity */
1338 67199 : && parity[l] != 0
1339 : /* and the parity is not excluded */
@@ -1420,9 +1420,9 @@
1358 : } else {
1359 : /* if we are not fixing, we just set the FIXED flag */
1360 : /* meaning that we could fix this file if we try */
- 1361 727245 : for (j = 0; j < failed_count; ++j) {
- 1362 220077 : if (failed[j].is_bad) {
- 1363 179194 : file_flag_set(failed[j].file, FILE_IS_FIXED);
+ 1361 727204 : for (j = 0; j < failed_count; ++j) {
+ 1362 219960 : if (failed[j].is_bad) {
+ 1363 179077 : file_flag_set(failed[j].file, FILE_IS_FIXED);
1364 : }
1365 : }
1366 : }
@@ -1430,26 +1430,26 @@
1368 : } else {
1369 : /* if we are not checking, we just set the DAMAGED flag */
1370 : /* to report that the file is damaged, and we don't know if we can fix it */
- 1371 45298 : for (j = 0; j < failed_count; ++j) {
- 1372 6121 : if (failed[j].is_bad) {
- 1373 6121 : file_flag_set(failed[j].file, FILE_IS_DAMAGED);
+ 1371 45028 : for (j = 0; j < failed_count; ++j) {
+ 1372 5851 : if (failed[j].is_bad) {
+ 1373 5851 : file_flag_set(failed[j].file, FILE_IS_DAMAGED);
1374 : }
1375 : }
1376 : }
1377 :
1378 : /* post process the files */
- 1379 908267 : ret = file_post(state, fix, i, handle, diskmax);
- 1380 908267 : if (ret == -1) {
+ 1379 908266 : ret = file_post(state, fix, i, handle, diskmax);
+ 1380 908266 : if (ret == -1) {
1381 0 : log_fatal("Stopping at block %u\n", i);
1382 0 : ++unrecoverable_error;
1383 0 : goto bail;
1384 : }
1385 :
1386 : /* count the number of processed block */
- 1387 908267 : ++countpos;
+ 1387 908266 : ++countpos;
1388 :
1389 : /* progress */
- 1390 908267 : if (state_progress(state, i, countpos, countmax, countsize)) {
+ 1390 908266 : if (state_progress(state, i, countpos, countmax, countsize)) {
1391 : /* LCOV_EXCL_START */
1392 : break;
1393 : /* LCOV_EXCL_STOP */
@@ -1467,52 +1467,52 @@
1405 : /* for each empty file in the disk */
1406 705 : disk = handle[i].disk;
1407 705 : node = disk->filelist;
- 1408 2187839 : while (node) {
+ 1408 2187957 : while (node) {
1409 : char path[PATH_MAX];
1410 : struct stat st;
1411 : struct snapraid_file* file;
- 1412 2186429 : int unsuccesful = 0;
+ 1412 2186547 : int unsuccesful = 0;
1413 :
- 1414 2186429 : file = node->data;
- 1415 2186429 : node = node->next; /* next node */
+ 1414 2186547 : file = node->data;
+ 1415 2186547 : node = node->next; /* next node */
1416 :
1417 : /* if not empty, it's already checked and continue to the next one */
- 1418 2186429 : if (file->size != 0) {
- 1419 4367351 : continue;
+ 1418 2186547 : if (file->size != 0) {
+ 1419 4367359 : continue;
1420 : }
1421 :
1422 : /* if excluded continue to the next one */
- 1423 2834 : if (file_flag_has(file, FILE_IS_EXCLUDED)) {
- 1424 161 : continue;
+ 1423 2952 : if (file_flag_has(file, FILE_IS_EXCLUDED)) {
+ 1424 169 : continue;
1425 : }
1426 :
1427 : /* stat the file */
- 1428 2673 : pathprint(path, sizeof(path), "%s%s", disk->dir, file->sub);
- 1429 2673 : ret = stat(path, &st);
- 1430 2673 : if (ret == -1) {
- 1431 162 : unsuccesful = 1;
+ 1428 2783 : pathprint(path, sizeof(path), "%s%s", disk->dir, file->sub);
+ 1429 2783 : ret = stat(path, &st);
+ 1430 2783 : if (ret == -1) {
+ 1431 173 : unsuccesful = 1;
1432 :
- 1433 162 : log_error("Error stating empty file '%s'. %s.\n", path, strerror(errno));
- 1434 162 : log_tag("error:%s:%s: Empty file stat error\n", disk->name, esc(file->sub));
- 1435 162 : ++error;
- 1436 2511 : } else if (!S_ISREG(st.st_mode)) {
+ 1433 173 : log_error("Error stating empty file '%s'. %s.\n", path, strerror(errno));
+ 1434 173 : log_tag("error:%s:%s: Empty file stat error\n", disk->name, esc(file->sub));
+ 1435 173 : ++error;
+ 1436 2610 : } else if (!S_ISREG(st.st_mode)) {
1437 0 : unsuccesful = 1;
1438 :
1439 0 : log_tag("error:%s:%s: Empty file error for not regular file\n", disk->name, esc(file->sub));
1440 0 : ++error;
- 1441 2511 : } else if (st.st_size != 0) {
- 1442 6 : unsuccesful = 1;
+ 1441 2610 : } else if (st.st_size != 0) {
+ 1442 8 : unsuccesful = 1;
1443 :
- 1444 6 : log_tag("error:%s:%s: Empty file error for size '%" PRIu64 "'\n", disk->name, esc(file->sub), st.st_size);
- 1445 6 : ++error;
+ 1444 8 : log_tag("error:%s:%s: Empty file error for size '%" PRIu64 "'\n", disk->name, esc(file->sub), st.st_size);
+ 1445 8 : ++error;
1446 : }
1447 :
- 1448 2673 : if (fix && unsuccesful) {
+ 1448 2783 : if (fix && unsuccesful) {
1449 : int f;
1450 :
1451 : /* create the ancestor directories */
- 1452 151 : ret = mkancestor(path);
- 1453 151 : if (ret != 0) {
+ 1452 158 : ret = mkancestor(path);
+ 1453 158 : if (ret != 0) {
1454 : /* LCOV_EXCL_START */
1455 : log_fatal("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n");
1456 : log_fatal("Stopping\n");
@@ -1523,8 +1523,8 @@
1461 :
1462 : /* create it */
1463 : /* O_NOFOLLOW: do not follow links to ensure to open the real file */
- 1464 151 : f = open(path, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_NOFOLLOW, 0600);
- 1465 151 : if (f == -1) {
+ 1464 158 : f = open(path, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_NOFOLLOW, 0600);
+ 1465 158 : if (f == -1) {
1466 : /* LCOV_EXCL_START */
1467 : log_fatal("Error creating empty file '%s'. %s.\n", path, strerror(errno));
1468 : if (errno == EACCES) {
@@ -1540,8 +1540,8 @@
1478 : }
1479 :
1480 : /* set the original modification time */
- 1481 151 : ret = fmtime(f, file->mtime_sec, file->mtime_nsec);
- 1482 151 : if (ret != 0) {
+ 1481 158 : ret = fmtime(f, file->mtime_sec, file->mtime_nsec);
+ 1482 158 : if (ret != 0) {
1483 : /* LCOV_EXCL_START */
1484 : close(f);
1485 :
@@ -1554,8 +1554,8 @@
1492 : }
1493 :
1494 : /* close it */
- 1495 151 : ret = close(f);
- 1496 151 : if (ret != 0) {
+ 1495 158 : ret = close(f);
+ 1496 158 : if (ret != 0) {
1497 : /* LCOV_EXCL_START */
1498 : log_fatal("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n");
1499 : log_fatal("Stopping\n");
@@ -1564,11 +1564,11 @@
1502 : /* LCOV_EXCL_STOP */
1503 : }
1504 :
- 1505 151 : log_tag("fixed:%s:%s: Fixed empty file\n", disk->name, esc(file->sub));
- 1506 151 : ++recovered_error;
+ 1505 158 : log_tag("fixed:%s:%s: Fixed empty file\n", disk->name, esc(file->sub));
+ 1506 158 : ++recovered_error;
1507 :
- 1508 151 : log_tag("status:recovered:%s:%s\n", disk->name, esc(file->sub));
- 1509 151 : msg_info("recovered %s%s\n", disk->dir, file->sub);
+ 1508 158 : log_tag("status:recovered:%s:%s\n", disk->name, esc(file->sub));
+ 1509 158 : msg_info("recovered %s%s\n", disk->dir, file->sub);
1510 : }
1511 : }
1512 :
@@ -1650,25 +1650,25 @@
1588 66532 : pathprint(path, sizeof(path), "%s%s", disk->dir, slink->sub);
1589 66532 : ret = readlink(path, linkto, sizeof(linkto));
1590 66532 : if (ret < 0) {
- 1591 4257 : unsuccesful = 1;
+ 1591 4337 : unsuccesful = 1;
1592 :
- 1593 4257 : log_error("Error reading symlink '%s'. %s.\n", path, strerror(errno));
- 1594 4257 : log_tag("symlink_error:%s:%s: Symlink read error\n", disk->name, esc(slink->sub));
- 1595 4257 : ++error;
- 1596 62275 : } else if (ret >= PATH_MAX) {
+ 1593 4337 : log_error("Error reading symlink '%s'. %s.\n", path, strerror(errno));
+ 1594 4337 : log_tag("symlink_error:%s:%s: Symlink read error\n", disk->name, esc(slink->sub));
+ 1595 4337 : ++error;
+ 1596 62195 : } else if (ret >= PATH_MAX) {
1597 0 : unsuccesful = 1;
1598 :
1599 0 : log_error("Error reading symlink '%s'. Symlink too long.\n", path);
1600 0 : log_tag("symlink_error:%s:%s: Symlink read error\n", disk->name, esc(slink->sub));
1601 0 : ++error;
1602 : } else {
- 1603 62275 : linkto[ret] = 0;
+ 1603 62195 : linkto[ret] = 0;
1604 :
- 1605 62275 : if (strcmp(linkto, slink->linkto) != 0) {
- 1606 574 : unsuccesful = 1;
+ 1605 62195 : if (strcmp(linkto, slink->linkto) != 0) {
+ 1606 493 : unsuccesful = 1;
1607 :
- 1608 574 : log_tag("symlink_error:%s:%s: Symlink data error '%s' instead of '%s'\n", disk->name, esc(slink->sub), linkto, slink->linkto);
- 1609 574 : ++error;
+ 1608 493 : log_tag("symlink_error:%s:%s: Symlink data error '%s' instead of '%s'\n", disk->name, esc(slink->sub), linkto, slink->linkto);
+ 1609 493 : ++error;
1610 : }
1611 : }
1612 : }
@@ -1846,23 +1846,23 @@
1784 : /* for each file in the disk */
1785 269 : disk = handle[i].disk;
1786 269 : node = disk->filelist;
- 1787 870354 : while (node) {
+ 1787 870399 : while (node) {
1788 : char path[PATH_MAX];
1789 : struct snapraid_file* file;
1790 :
- 1791 869816 : file = node->data;
- 1792 869816 : node = node->next; /* next node */
+ 1791 869861 : file = node->data;
+ 1792 869861 : node = node->next; /* next node */
1793 :
1794 : /* if the file was not created, meaning that it was already existing */
- 1795 869816 : if (!file_flag_has(file, FILE_IS_CREATED)) {
+ 1795 869861 : if (!file_flag_has(file, FILE_IS_CREATED)) {
1796 : /* nothing to do */
- 1797 1626589 : continue;
+ 1797 1626698 : continue;
1798 : }
1799 :
1800 : /* if processing was finished */
- 1801 113043 : if (file_flag_has(file, FILE_IS_FINISHED)) {
+ 1801 113024 : if (file_flag_has(file, FILE_IS_FINISHED)) {
1802 : /* nothing to do */
- 1803 113043 : continue;
+ 1803 113024 : continue;
1804 : }
1805 :
1806 : /* if the file was originally missing, and processing not yet finished */
diff --git a/cov/cmdline/device.c.func-sort-c.html b/cov/cmdline/device.c.func-sort-c.html
index a95a8d8e..566e5929 100644
--- a/cov/cmdline/device.c.func-sort-c.html
+++ b/cov/cmdline/device.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/cmdline/device.c.func.html b/cov/cmdline/device.c.func.html
index a2e66645..b0da8a8b 100644
--- a/cov/cmdline/device.c.func.html
+++ b/cov/cmdline/device.c.func.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/cmdline/device.c.gcov.html b/cov/cmdline/device.c.gcov.html
index 9dd230f0..1014045d 100644
--- a/cov/cmdline/device.c.gcov.html
+++ b/cov/cmdline/device.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/cmdline/dry.c.func-sort-c.html b/cov/cmdline/dry.c.func-sort-c.html
index a6ab1ed9..ac636230 100644
--- a/cov/cmdline/dry.c.func-sort-c.html
+++ b/cov/cmdline/dry.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/cmdline/dry.c.func.html b/cov/cmdline/dry.c.func.html
index 70114cd4..05c93ac8 100644
--- a/cov/cmdline/dry.c.func.html
+++ b/cov/cmdline/dry.c.func.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/cmdline/dry.c.gcov.html b/cov/cmdline/dry.c.gcov.html
index c8155f8f..52891e1b 100644
--- a/cov/cmdline/dry.c.gcov.html
+++ b/cov/cmdline/dry.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/cmdline/dup.c.func-sort-c.html b/cov/cmdline/dup.c.func-sort-c.html
index 071408f7..0817fb38 100644
--- a/cov/cmdline/dup.c.func-sort-c.html
+++ b/cov/cmdline/dup.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/cmdline/dup.c.func.html b/cov/cmdline/dup.c.func.html
index 1a267a3f..90e3eb0b 100644
--- a/cov/cmdline/dup.c.func.html
+++ b/cov/cmdline/dup.c.func.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/cmdline/dup.c.gcov.html b/cov/cmdline/dup.c.gcov.html
index ce35360b..628d41b2 100644
--- a/cov/cmdline/dup.c.gcov.html
+++ b/cov/cmdline/dup.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -168,14 +168,14 @@
106 18 : struct snapraid_disk* disk = i->data;
107 :
108 : /* for each file */
- 109 16996 : for (j = disk->filelist; j != 0; j = j->next) {
- 110 16978 : struct snapraid_file* file = j->data;
+ 109 16998 : for (j = disk->filelist; j != 0; j = j->next) {
+ 110 16980 : struct snapraid_file* file = j->data;
111 : struct snapraid_hash* hash;
112 : tommy_hash_t hash32;
113 :
114 : /* if empty, skip it */
- 115 16978 : if (file->size == 0)
- 116 22 : continue;
+ 115 16980 : if (file->size == 0)
+ 116 24 : continue;
117 :
118 16956 : hash = hash_alloc(state, disk, file);
119 :
diff --git a/cov/cmdline/elem.c.func-sort-c.html b/cov/cmdline/elem.c.func-sort-c.html
index 6e20dd20..ad72c590 100644
--- a/cov/cmdline/elem.c.func-sort-c.html
+++ b/cov/cmdline/elem.c.func-sort-c.html
@@ -31,18 +31,18 @@
|
-
-
-
+
+
+
-
+
|
-
-
-
+
+
+
 |
@@ -60,64 +60,68 @@
Hit count  |
- | chunk_parity_inside_compare |
- 213182654 |
+ chunk_parity_inside_compare |
+ 211700412 |
- | chunk_file_inside_compare |
- 123631586 |
+ chunk_file_inside_compare |
+ 123424429 |
- | fs_par2file_get_ts |
- 62727960 |
+ fs_file2block_get |
+ 112904165 |
- | fs_par2chunk_get_ts |
- 62657428 |
+ fs_par2file_get_ts |
+ 62671366 |
- | fs_par2block_get_ts |
- 51081912 |
+ fs_par2chunk_get_ts |
+ 62562730 |
- | chunk_file_compare |
- 43527266 |
+ fs_par2block_get_ts |
+ 51148943 |
- | chunk_parity_compare |
- 43029334 |
+ chunk_file_compare |
+ 43527418 |
- | fs_file2chunk_get_ts |
- 34130326 |
+ chunk_parity_compare |
+ 43029600 |
- | fs_file2par_get_ts |
- 28966119 |
+ fs_file2chunk_get_ts |
+ 34157182 |
+
+
+ | fs_file2par_get_ts |
+ 28740730 |
| filter_apply |
- 12035121 |
+ 12035450 |
- | fs_allocate |
- 8850076 |
+ fs_allocate |
+ 8849850 |
| file_block_size |
- 6609423 |
+ 6610122 |
- | chunk_file_check_foreach |
- 6291272 |
+ chunk_file_check_foreach |
+ 6291380 |
- | chunk_parity_check_foreach |
- 6291272 |
+ chunk_parity_check_foreach |
+ 6291380 |
| filter_recurse |
- 6023322 |
+ 6023667 |
| file_block_is_last |
@@ -125,95 +129,95 @@
| chunk_alloc |
- 3607803 |
+ 3607761 |
| file_alloc |
- 3565018 |
+ 3565141 |
- | chunk_free |
- 3437425 |
+ chunk_free |
+ 3437520 |
| file_free |
- 3417005 |
+ 3417248 |
| filter_element |
- 3226046 |
+ 3226232 |
| filter_path |
- 3223074 |
+ 3223260 |
| filter_content |
- 3066757 |
+ 3066852 |
| file_inode_compare_to_arg |
- 869924 |
+ 866983 |
- | time_compare |
- 713560 |
+ time_compare |
+ 743492 |
| file_path_compare |
- 126320 |
+ 126356 |
| filter_type |
- 125579 |
+ 125437 |
- | link_alloc |
+ link_alloc |
115419 |
- | link_free |
+ link_free |
109621 |
| file_path_compare_to_arg |
- 105086 |
+ 105104 |
- | fs_deallocate |
- 104031 |
+ fs_deallocate |
+ 104155 |
| filter_existence |
- 80649 |
-
-
- | file_physical_compare |
- 54526 |
+ 80654 |
| file_name |
- 47858 |
+ 47908 |
- | chunk_disk_size_compare |
- 47777 |
+ chunk_disk_size_compare |
+ 47779 |
| filter_correctness |
- 38803 |
+ 38806 |
- | link_name_compare_to_arg |
+ file_physical_compare |
+ 34618 |
+
+
+ | link_name_compare_to_arg |
30380 |
| file_namestamp_compare |
- 23929 |
+ 23954 |
| file_name_compare |
- 23929 |
+ 23954 |
| file_stamp_compare |
@@ -221,14 +225,14 @@
| file_dup |
- 21784 |
+ 21785 |
| file_copy |
6209 |
- | disk_size |
+ disk_size |
3955 |
@@ -236,15 +240,15 @@
| 2972 |
- | fs_check |
+ fs_check |
2676 |
- | disk_alloc |
+ disk_alloc |
1477 |
- | map_alloc |
+ map_alloc |
1447 |
@@ -252,11 +256,11 @@
| 1434 |
- | disk_free |
+ disk_free |
1351 |
- | map_free |
+ map_free |
1327 |
@@ -264,19 +268,19 @@
| 1297 |
- | link_alpha_compare |
+ link_alpha_compare |
1249 |
- | disk_is_empty |
+ disk_is_empty |
804 |
- | dir_alloc |
+ dir_alloc |
760 |
- | dir_free |
+ dir_free |
712 |
@@ -288,7 +292,7 @@
| 461 |
- | dir_name_compare |
+ dir_name_compare |
217 |
@@ -296,7 +300,7 @@
| 155 |
- | chunk_disk_empty_compare |
+ chunk_disk_empty_compare |
10 |
diff --git a/cov/cmdline/elem.c.func.html b/cov/cmdline/elem.c.func.html
index 14103d4a..a43507ef 100644
--- a/cov/cmdline/elem.c.func.html
+++ b/cov/cmdline/elem.c.func.html
@@ -31,18 +31,18 @@
|
-
-
-
+
+
+
-
+
|
-
-
-
+
+
+
 |
@@ -61,43 +61,43 @@
| chunk_alloc |
- 3607803 |
+ 3607761 |
- | chunk_disk_empty_compare |
+ chunk_disk_empty_compare |
10 |
- | chunk_disk_size_compare |
- 47777 |
+ chunk_disk_size_compare |
+ 47779 |
- | chunk_file_check_foreach |
- 6291272 |
+ chunk_file_check_foreach |
+ 6291380 |
- | chunk_file_compare |
- 43527266 |
+ chunk_file_compare |
+ 43527418 |
- | chunk_file_inside_compare |
- 123631586 |
+ chunk_file_inside_compare |
+ 123424429 |
- | chunk_free |
- 3437425 |
+ chunk_free |
+ 3437520 |
- | chunk_parity_check_foreach |
- 6291272 |
+ chunk_parity_check_foreach |
+ 6291380 |
- | chunk_parity_compare |
- 43029334 |
+ chunk_parity_compare |
+ 43029600 |
- | chunk_parity_inside_compare |
- 213182654 |
+ chunk_parity_inside_compare |
+ 211700412 |
| content_alloc |
@@ -108,36 +108,36 @@
1297 |
- | dir_alloc |
+ dir_alloc |
760 |
- | dir_free |
+ dir_free |
712 |
- | dir_name_compare |
+ dir_name_compare |
217 |
- | disk_alloc |
+ disk_alloc |
1477 |
- | disk_free |
+ disk_free |
1351 |
- | disk_is_empty |
+ disk_is_empty |
804 |
- | disk_size |
+ disk_size |
3955 |
| file_alloc |
- 3565018 |
+ 3565141 |
| file_block_is_last |
@@ -145,7 +145,7 @@
| file_block_size |
- 6609423 |
+ 6610122 |
| file_copy |
@@ -153,11 +153,11 @@
| file_dup |
- 21784 |
+ 21785 |
| file_free |
- 3417005 |
+ 3417248 |
| file_inode_compare |
@@ -165,27 +165,27 @@
| file_inode_compare_to_arg |
- 869924 |
+ 866983 |
| file_name |
- 47858 |
+ 47908 |
| file_name_compare |
- 23929 |
+ 23954 |
| file_namestamp_compare |
- 23929 |
+ 23954 |
| file_path_compare |
- 126320 |
+ 126356 |
| file_path_compare_to_arg |
- 105086 |
+ 105104 |
| file_pathstamp_compare |
@@ -193,7 +193,7 @@
| file_physical_compare |
- 54526 |
+ 34618 |
| file_rename |
@@ -213,15 +213,15 @@
| filter_apply |
- 12035121 |
+ 12035450 |
| filter_content |
- 3066757 |
+ 3066852 |
| filter_correctness |
- 38803 |
+ 38806 |
| filter_dir |
@@ -229,11 +229,11 @@
| filter_element |
- 3226046 |
+ 3226232 |
| filter_existence |
- 80649 |
+ 80654 |
| filter_free |
@@ -241,75 +241,79 @@
| filter_path |
- 3223074 |
+ 3223260 |
| filter_recurse |
- 6023322 |
+ 6023667 |
| filter_type |
- 125579 |
+ 125437 |
- | fs_allocate |
- 8850076 |
+ fs_allocate |
+ 8849850 |
- | fs_check |
+ fs_check |
2676 |
- | fs_deallocate |
- 104031 |
+ fs_deallocate |
+ 104155 |
- | fs_file2chunk_get_ts |
- 34130326 |
+ fs_file2block_get |
+ 112904165 |
- | fs_file2par_get_ts |
- 28966119 |
+ fs_file2chunk_get_ts |
+ 34157182 |
- | fs_par2block_get_ts |
- 51081912 |
+ fs_file2par_get_ts |
+ 28740730 |
- | fs_par2chunk_get_ts |
- 62657428 |
+ fs_par2block_get_ts |
+ 51148943 |
- | fs_par2file_get_ts |
- 62727960 |
+ fs_par2chunk_get_ts |
+ 62562730 |
- | link_alloc |
+ fs_par2file_get_ts |
+ 62671366 |
+
+
+ | link_alloc |
115419 |
- | link_alpha_compare |
+ link_alpha_compare |
1249 |
- | link_free |
+ link_free |
109621 |
- | link_name_compare_to_arg |
+ link_name_compare_to_arg |
30380 |
- | map_alloc |
+ map_alloc |
1447 |
- | map_free |
+ map_free |
1327 |
- | time_compare |
- 713560 |
+ time_compare |
+ 743492 |
diff --git a/cov/cmdline/elem.c.gcov.html b/cov/cmdline/elem.c.gcov.html
index 75d2540a..0121811d 100644
--- a/cov/cmdline/elem.c.gcov.html
+++ b/cov/cmdline/elem.c.gcov.html
@@ -31,18 +31,18 @@
|
-
-
-
+
+
+
-
+
|
-
-
-
+
+
+
 |
@@ -210,135 +210,135 @@
148 461 : free(filter);
149 461 : }
150 :
- 151 125579 : const char* filter_type(struct snapraid_filter* filter, char* out, size_t out_size)
+ 151 125437 : const char* filter_type(struct snapraid_filter* filter, char* out, size_t out_size)
152 : {
153 : const char* direction;
- 154 125579 : if (filter->direction < 0)
- 155 125333 : direction = "exclude";
+ 154 125437 : if (filter->direction < 0)
+ 155 125191 : direction = "exclude";
156 : else
157 246 : direction = "include";
158 :
- 159 125579 : if (filter->is_disk)
+ 159 125437 : if (filter->is_disk)
160 0 : pathprint(out, out_size, "%s %s:", direction, filter->pattern);
- 161 125579 : else if (filter->is_dir)
+ 161 125437 : else if (filter->is_dir)
162 0 : pathprint(out, out_size, "%s %s/", direction, filter->pattern);
163 : else
- 164 125579 : pathprint(out, out_size, "%s %s", direction, filter->pattern);
+ 164 125437 : pathprint(out, out_size, "%s %s", direction, filter->pattern);
165 :
- 166 125579 : return out;
+ 166 125437 : return out;
167 : }
168 :
- 169 12035121 : static int filter_apply(struct snapraid_filter* filter, struct snapraid_filter** reason, const char* path, const char* name, int is_dir)
+ 169 12035450 : static int filter_apply(struct snapraid_filter* filter, struct snapraid_filter** reason, const char* path, const char* name, int is_dir)
170 : {
- 171 12035121 : int ret = 0;
+ 171 12035450 : int ret = 0;
172 :
173 : /* match dirs with dirs and files with files */
- 174 12035121 : if (filter->is_dir && !is_dir)
- 175 2938 : return 0;
- 176 12032183 : if (!filter->is_dir && is_dir)
- 177 6014696 : return 0;
+ 174 12035450 : if (filter->is_dir && !is_dir)
+ 175 2939 : return 0;
+ 176 12032511 : if (!filter->is_dir && is_dir)
+ 177 6014680 : return 0;
178 :
- 179 6017487 : if (filter->is_path) {
+ 179 6017831 : if (filter->is_path) {
180 : /* skip initial slash, as always missing from the path */
- 181 2938 : if (fnmatch(filter->pattern + 1, path, FNM_PATHNAME | FNM_CASEINSENSITIVE_FOR_WIN) == 0)
+ 181 2939 : if (fnmatch(filter->pattern + 1, path, FNM_PATHNAME | FNM_CASEINSENSITIVE_FOR_WIN) == 0)
182 0 : ret = filter->direction;
183 : } else {
- 184 6014549 : if (fnmatch(filter->pattern, name, FNM_CASEINSENSITIVE_FOR_WIN) == 0)
- 185 128077 : ret = filter->direction;
+ 184 6014892 : if (fnmatch(filter->pattern, name, FNM_CASEINSENSITIVE_FOR_WIN) == 0)
+ 185 127935 : ret = filter->direction;
186 : }
187 :
- 188 6017487 : if (reason != 0 && ret < 0)
- 189 125087 : *reason = filter;
+ 188 6017831 : if (reason != 0 && ret < 0)
+ 189 124945 : *reason = filter;
190 :
- 191 6017487 : return ret;
+ 191 6017831 : return ret;
192 : }
193 :
- 194 6023322 : static int filter_recurse(struct snapraid_filter* filter, struct snapraid_filter** reason, const char* const_path, int is_dir)
+ 194 6023667 : static int filter_recurse(struct snapraid_filter* filter, struct snapraid_filter** reason, const char* const_path, int is_dir)
195 : {
196 : char path[PATH_MAX];
197 : char* name;
198 : unsigned i;
199 :
- 200 6023322 : pathcpy(path, sizeof(path), const_path);
+ 200 6023667 : pathcpy(path, sizeof(path), const_path);
201 :
202 : /* filter for all the directories */
- 203 6023322 : name = path;
- 204 86943549 : for (i = 0; path[i] != 0; ++i) {
- 205 80923217 : if (path[i] == '/') {
+ 203 6023667 : name = path;
+ 204 86942366 : for (i = 0; path[i] != 0; ++i) {
+ 205 80921689 : if (path[i] == '/') {
206 : /* set a terminator */
- 207 6014789 : path[i] = 0;
+ 207 6014773 : path[i] = 0;
208 :
209 : /* filter the directory */
- 210 6014789 : if (filter_apply(filter, reason, path, name, 1) != 0)
+ 210 6014773 : if (filter_apply(filter, reason, path, name, 1) != 0)
211 2990 : return filter->direction;
212 :
213 : /* restore the slash */
- 214 6011799 : path[i] = '/';
+ 214 6011783 : path[i] = '/';
215 :
216 : /* next name */
- 217 6011799 : name = path + i + 1;
+ 217 6011783 : name = path + i + 1;
218 : }
219 : }
220 :
221 : /* filter the final file */
- 222 6020332 : if (filter_apply(filter, reason, path, name, is_dir) != 0)
- 223 125087 : return filter->direction;
+ 222 6020677 : if (filter_apply(filter, reason, path, name, is_dir) != 0)
+ 223 124945 : return filter->direction;
224 :
- 225 5895245 : return 0;
+ 225 5895732 : return 0;
226 : }
227 :
- 228 3226046 : static int filter_element(tommy_list* filterlist, struct snapraid_filter** reason, const char* disk, const char* sub, int is_dir)
+ 228 3226232 : static int filter_element(tommy_list* filterlist, struct snapraid_filter** reason, const char* disk, const char* sub, int is_dir)
229 : {
230 : tommy_node* i;
231 :
- 232 3226046 : int direction = 1; /* by default include all */
+ 232 3226232 : int direction = 1; /* by default include all */
233 :
234 : /* for each filter */
- 235 9222499 : for (i = tommy_list_head(filterlist); i != 0; i = i->next) {
+ 235 9223179 : for (i = tommy_list_head(filterlist); i != 0; i = i->next) {
236 : int ret;
- 237 6133199 : struct snapraid_filter* filter = i->data;
+ 237 6133552 : struct snapraid_filter* filter = i->data;
238 :
- 239 6133199 : if (filter->is_disk) {
- 240 109877 : if (fnmatch(filter->pattern, disk, FNM_CASEINSENSITIVE_FOR_WIN) == 0)
- 241 8669 : ret = filter->direction;
+ 239 6133552 : if (filter->is_disk) {
+ 240 109885 : if (fnmatch(filter->pattern, disk, FNM_CASEINSENSITIVE_FOR_WIN) == 0)
+ 241 8670 : ret = filter->direction;
242 : else
- 243 101208 : ret = 0;
- 244 109877 : if (reason != 0 && ret < 0)
+ 243 101215 : ret = 0;
+ 244 109885 : if (reason != 0 && ret < 0)
245 0 : *reason = filter;
246 : } else {
- 247 6023322 : ret = filter_recurse(filter, reason, sub, is_dir);
+ 247 6023667 : ret = filter_recurse(filter, reason, sub, is_dir);
248 : }
249 :
- 250 6133199 : if (ret > 0) {
+ 250 6133552 : if (ret > 0) {
251 : /* include the file */
- 252 11659 : return 0;
- 253 6121540 : } else if (ret < 0) {
+ 252 11660 : return 0;
+ 253 6121892 : } else if (ret < 0) {
254 : /* exclude the file */
- 255 125087 : return -1;
+ 255 124945 : return -1;
256 : } else {
257 : /* default is opposite of the last filter */
- 258 5996453 : direction = -filter->direction;
- 259 5996453 : if (reason != 0 && direction < 0)
- 260 3004264 : *reason = filter;
+ 258 5996947 : direction = -filter->direction;
+ 259 5996947 : if (reason != 0 && direction < 0)
+ 260 3004435 : *reason = filter;
261 : /* continue with the next one */
262 : }
263 : }
264 :
265 : /* directories are always included by default, otherwise we cannot apply rules */
266 : /* to the contained files */
- 267 3089300 : if (is_dir)
+ 267 3089627 : if (is_dir)
268 2971 : return 0;
269 :
270 : /* files are excluded/included depending of the last rule processed */
- 271 3086329 : if (direction < 0)
- 272 57541 : return -1;
+ 271 3086656 : if (direction < 0)
+ 272 57545 : return -1;
273 :
- 274 3028788 : return 0;
+ 274 3029111 : return 0;
275 : }
276 :
- 277 3223074 : int filter_path(tommy_list* filterlist, struct snapraid_filter** reason, const char* disk, const char* sub)
+ 277 3223260 : int filter_path(tommy_list* filterlist, struct snapraid_filter** reason, const char* disk, const char* sub)
278 : {
- 279 3223074 : return filter_element(filterlist, reason, disk, sub, 0);
+ 279 3223260 : return filter_element(filterlist, reason, disk, sub, 0);
280 : }
281 :
282 2972 : int filter_dir(tommy_list* filterlist, struct snapraid_filter** reason, const char* disk, const char* sub)
@@ -346,18 +346,18 @@
284 2972 : return filter_element(filterlist, reason, disk, sub, 1);
285 : }
286 :
- 287 80649 : int filter_existence(int filter_missing, const char* dir, const char* sub)
+ 287 80654 : int filter_existence(int filter_missing, const char* dir, const char* sub)
288 : {
289 : char path[PATH_MAX];
290 : struct stat st;
291 :
- 292 80649 : if (!filter_missing)
- 293 34955 : return 0;
+ 292 80654 : if (!filter_missing)
+ 293 34958 : return 0;
294 :
295 : /* we directly check if in the disk the file is present or not */
- 296 45694 : pathprint(path, sizeof(path), "%s%s", dir, sub);
+ 296 45696 : pathprint(path, sizeof(path), "%s%s", dir, sub);
297 :
- 298 45694 : if (lstat(path, &st) != 0) {
+ 298 45696 : if (lstat(path, &st) != 0) {
299 : /* if the file doesn't exist, we don't filter it out */
300 5007 : if (errno == ENOENT)
301 5007 : return 0;
@@ -368,111 +368,111 @@
306 : }
307 :
308 : /* the file is present, so we filter it out */
- 309 40687 : return 1;
+ 309 40689 : return 1;
310 : }
311 :
- 312 38803 : int filter_correctness(int filter_error, tommy_arrayblkof* infoarr, struct snapraid_disk* disk, struct snapraid_file* file)
+ 312 38806 : int filter_correctness(int filter_error, tommy_arrayblkof* infoarr, struct snapraid_disk* disk, struct snapraid_file* file)
313 : {
314 : unsigned i;
315 :
- 316 38803 : if (!filter_error)
- 317 16277 : return 0;
+ 316 38806 : if (!filter_error)
+ 317 16278 : return 0;
318 :
319 : /* check each block of the file */
- 320 60103 : for (i = 0; i < file->blockmax; ++i) {
- 321 46031 : block_off_t parity_pos = fs_file2par_get(disk, file, i);
- 322 46031 : snapraid_info info = info_get(infoarr, parity_pos);
+ 320 60231 : for (i = 0; i < file->blockmax; ++i) {
+ 321 46123 : block_off_t parity_pos = fs_file2par_get(disk, file, i);
+ 322 46123 : snapraid_info info = info_get(infoarr, parity_pos);
323 :
324 : /* if the file has a bad block, don't exclude it */
- 325 46031 : if (info_get_bad(info))
- 326 8454 : return 0;
+ 325 46123 : if (info_get_bad(info))
+ 326 8420 : return 0;
327 : }
328 :
329 : /* the file is correct, so we filter it out */
- 330 14072 : return 1;
+ 330 14108 : return 1;
331 : }
332 :
- 333 3066757 : int filter_content(tommy_list* contentlist, const char* path)
+ 333 3066852 : int filter_content(tommy_list* contentlist, const char* path)
334 : {
335 : tommy_node* i;
336 :
- 337 39679746 : for (i = tommy_list_head(contentlist); i != 0; i = i->next) {
- 338 16773116 : struct snapraid_content* content = i->data;
+ 337 39681406 : for (i = tommy_list_head(contentlist); i != 0; i = i->next) {
+ 338 16773851 : struct snapraid_content* content = i->data;
339 : char tmp[PATH_MAX];
340 :
- 341 16773116 : if (pathcmp(content->content, path) == 0)
+ 341 16773851 : if (pathcmp(content->content, path) == 0)
342 0 : return -1;
343 :
344 : /* exclude also the ".tmp" copy used to save it */
- 345 16773116 : pathprint(tmp, sizeof(tmp), "%s.tmp", content->content);
- 346 16773116 : if (pathcmp(tmp, path) == 0)
+ 345 16773851 : pathprint(tmp, sizeof(tmp), "%s.tmp", content->content);
+ 346 16773851 : if (pathcmp(tmp, path) == 0)
347 0 : return -1;
348 :
349 : /* exclude also the ".lock" file */
- 350 16773116 : pathprint(tmp, sizeof(tmp), "%s.lock", content->content);
- 351 16773116 : if (pathcmp(tmp, path) == 0)
+ 350 16773851 : pathprint(tmp, sizeof(tmp), "%s.lock", content->content);
+ 351 16773851 : if (pathcmp(tmp, path) == 0)
352 0 : return -1;
353 : }
354 :
- 355 3066757 : return 0;
+ 355 3066852 : return 0;
356 : }
357 :
- 358 3565018 : struct snapraid_file* file_alloc(unsigned block_size, const char* sub, data_off_t size, uint64_t mtime_sec, int mtime_nsec, uint64_t inode, uint64_t physical)
+ 358 3565141 : struct snapraid_file* file_alloc(unsigned block_size, const char* sub, data_off_t size, uint64_t mtime_sec, int mtime_nsec, uint64_t inode, uint64_t physical)
359 : {
360 : struct snapraid_file* file;
361 : block_off_t i;
362 :
- 363 3565018 : file = malloc_nofail(sizeof(struct snapraid_file));
- 364 3565018 : file->sub = strdup_nofail(sub);
- 365 3565018 : file->size = size;
- 366 3565018 : file->blockmax = (size + block_size - 1) / block_size;
- 367 3565018 : file->mtime_sec = mtime_sec;
- 368 3565018 : file->mtime_nsec = mtime_nsec;
- 369 3565018 : file->inode = inode;
- 370 3565018 : file->physical = physical;
- 371 3565018 : file->flag = 0;
- 372 3565018 : file->blockvec = malloc_nofail(file->blockmax * sizeof(struct snapraid_block));
+ 363 3565141 : file = malloc_nofail(sizeof(struct snapraid_file));
+ 364 3565141 : file->sub = strdup_nofail(sub);
+ 365 3565141 : file->size = size;
+ 366 3565141 : file->blockmax = (size + block_size - 1) / block_size;
+ 367 3565141 : file->mtime_sec = mtime_sec;
+ 368 3565141 : file->mtime_nsec = mtime_nsec;
+ 369 3565141 : file->inode = inode;
+ 370 3565141 : file->physical = physical;
+ 371 3565141 : file->flag = 0;
+ 372 3565141 : file->blockvec = malloc_nofail(file->blockmax * sizeof(struct snapraid_block));
373 :
- 374 12361466 : for (i = 0; i < file->blockmax; ++i) {
- 375 8796448 : block_state_set(&file->blockvec[i], BLOCK_STATE_CHG);
- 376 8796448 : hash_invalid_set(file->blockvec[i].hash);
+ 374 12361356 : for (i = 0; i < file->blockmax; ++i) {
+ 375 8796215 : block_state_set(&file->blockvec[i], BLOCK_STATE_CHG);
+ 376 8796215 : hash_invalid_set(file->blockvec[i].hash);
377 : }
378 :
- 379 3565018 : return file;
+ 379 3565141 : return file;
380 : }
381 :
- 382 21784 : struct snapraid_file* file_dup(struct snapraid_file* copy)
+ 382 21785 : struct snapraid_file* file_dup(struct snapraid_file* copy)
383 : {
384 : struct snapraid_file* file;
385 : block_off_t i;
386 :
- 387 21784 : file = malloc_nofail(sizeof(struct snapraid_file));
- 388 21784 : file->sub = strdup_nofail(copy->sub);
- 389 21784 : file->size = copy->size;
- 390 21784 : file->blockmax = copy->blockmax;
- 391 21784 : file->mtime_sec = copy->mtime_sec;
- 392 21784 : file->mtime_nsec = copy->mtime_nsec;
- 393 21784 : file->inode = copy->inode;
- 394 21784 : file->physical = copy->physical;
- 395 21784 : file->flag = copy->flag;
- 396 21784 : file->blockvec = malloc_nofail(file->blockmax * sizeof(struct snapraid_block));
+ 387 21785 : file = malloc_nofail(sizeof(struct snapraid_file));
+ 388 21785 : file->sub = strdup_nofail(copy->sub);
+ 389 21785 : file->size = copy->size;
+ 390 21785 : file->blockmax = copy->blockmax;
+ 391 21785 : file->mtime_sec = copy->mtime_sec;
+ 392 21785 : file->mtime_nsec = copy->mtime_nsec;
+ 393 21785 : file->inode = copy->inode;
+ 394 21785 : file->physical = copy->physical;
+ 395 21785 : file->flag = copy->flag;
+ 396 21785 : file->blockvec = malloc_nofail(file->blockmax * sizeof(struct snapraid_block));
397 :
- 398 75416 : for (i = 0; i < file->blockmax; ++i) {
- 399 53632 : file->blockvec[i].state = copy->blockvec[i].state;
- 400 53632 : memcpy(file->blockvec[i].hash, copy->blockvec[i].hash, HASH_SIZE);
+ 398 75420 : for (i = 0; i < file->blockmax; ++i) {
+ 399 53635 : file->blockvec[i].state = copy->blockvec[i].state;
+ 400 53635 : memcpy(file->blockvec[i].hash, copy->blockvec[i].hash, HASH_SIZE);
401 : }
402 :
- 403 21784 : return file;
+ 403 21785 : return file;
404 : }
405 :
- 406 3417005 : void file_free(struct snapraid_file* file)
+ 406 3417248 : void file_free(struct snapraid_file* file)
407 : {
- 408 3417005 : free(file->sub);
- 409 3417005 : file->sub = 0;
- 410 3417005 : free(file->blockvec);
- 411 3417005 : file->blockvec = 0;
- 412 3417005 : free(file);
- 413 3417005 : }
+ 408 3417248 : free(file->sub);
+ 409 3417248 : file->sub = 0;
+ 410 3417248 : free(file->blockvec);
+ 411 3417248 : file->blockvec = 0;
+ 412 3417248 : free(file);
+ 413 3417248 : }
414 :
415 155 : void file_rename(struct snapraid_file* file, const char* sub)
416 : {
@@ -516,31 +516,31 @@
454 6209 : file_flag_set(dst_file, FILE_IS_COPY);
455 6209 : }
456 :
- 457 47858 : const char* file_name(const struct snapraid_file* file)
+ 457 47908 : const char* file_name(const struct snapraid_file* file)
458 : {
- 459 47858 : const char* r = strrchr(file->sub, '/');
+ 459 47908 : const char* r = strrchr(file->sub, '/');
460 :
- 461 47858 : if (!r)
+ 461 47908 : if (!r)
462 8 : r = file->sub;
463 : else
- 464 47850 : ++r;
- 465 47858 : return r;
+ 464 47900 : ++r;
+ 465 47908 : return r;
466 : }
467 :
- 468 6609423 : unsigned file_block_size(struct snapraid_file* file, block_off_t file_pos, unsigned block_size)
+ 468 6610122 : unsigned file_block_size(struct snapraid_file* file, block_off_t file_pos, unsigned block_size)
469 : {
470 : /* if it's the last block */
- 471 6609423 : if (file_pos + 1 == file->blockmax) {
+ 471 6610122 : if (file_pos + 1 == file->blockmax) {
472 : unsigned block_remainder;
- 473 2692095 : if (file->size == 0)
+ 473 2692717 : if (file->size == 0)
474 0 : return 0;
- 475 2692095 : block_remainder = file->size % block_size;
- 476 2692095 : if (block_remainder == 0)
- 477 1567 : block_remainder = block_size;
- 478 2692095 : return block_remainder;
+ 475 2692717 : block_remainder = file->size % block_size;
+ 476 2692717 : if (block_remainder == 0)
+ 477 1544 : block_remainder = block_size;
+ 478 2692717 : return block_remainder;
479 : }
480 :
- 481 3917328 : return block_size;
+ 481 3917405 : return block_size;
482 : }
483 :
484 5319910 : int file_block_is_last(struct snapraid_file* file, block_off_t file_pos)
@@ -558,16 +558,16 @@
496 5319910 : return file_pos == file->blockmax - 1;
497 : }
498 :
- 499 869924 : int file_inode_compare_to_arg(const void* void_arg, const void* void_data)
+ 499 866983 : int file_inode_compare_to_arg(const void* void_arg, const void* void_data)
500 : {
- 501 869924 : const uint64_t* arg = void_arg;
- 502 869924 : const struct snapraid_file* file = void_data;
+ 501 866983 : const uint64_t* arg = void_arg;
+ 502 866983 : const struct snapraid_file* file = void_data;
503 :
- 504 869924 : if (*arg < file->inode)
+ 504 866983 : if (*arg < file->inode)
505 0 : return -1;
- 506 869924 : if (*arg > file->inode)
+ 506 866983 : if (*arg > file->inode)
507 0 : return 1;
- 508 869924 : return 0;
+ 508 866983 : return 0;
509 : }
510 :
511 0 : int file_inode_compare(const void* void_a, const void* void_b)
@@ -582,42 +582,42 @@
520 0 : return 0;
521 : }
522 :
- 523 126320 : int file_path_compare(const void* void_a, const void* void_b)
+ 523 126356 : int file_path_compare(const void* void_a, const void* void_b)
524 : {
- 525 126320 : const struct snapraid_file* file_a = void_a;
- 526 126320 : const struct snapraid_file* file_b = void_b;
+ 525 126356 : const struct snapraid_file* file_a = void_a;
+ 526 126356 : const struct snapraid_file* file_b = void_b;
527 :
- 528 126320 : return strcmp(file_a->sub, file_b->sub);
+ 528 126356 : return strcmp(file_a->sub, file_b->sub);
529 : }
530 :
- 531 54526 : int file_physical_compare(const void* void_a, const void* void_b)
+ 531 34618 : int file_physical_compare(const void* void_a, const void* void_b)
532 : {
- 533 54526 : const struct snapraid_file* file_a = void_a;
- 534 54526 : const struct snapraid_file* file_b = void_b;
+ 533 34618 : const struct snapraid_file* file_a = void_a;
+ 534 34618 : const struct snapraid_file* file_b = void_b;
535 :
- 536 54526 : if (file_a->physical < file_b->physical)
- 537 35814 : return -1;
- 538 18712 : if (file_a->physical > file_b->physical)
- 539 18712 : return 1;
- 540 0 : return 0;
+ 536 34618 : if (file_a->physical < file_b->physical)
+ 537 26412 : return -1;
+ 538 8206 : if (file_a->physical > file_b->physical)
+ 539 8204 : return 1;
+ 540 2 : return 0;
541 : }
542 :
- 543 105086 : int file_path_compare_to_arg(const void* void_arg, const void* void_data)
+ 543 105104 : int file_path_compare_to_arg(const void* void_arg, const void* void_data)
544 : {
- 545 105086 : const char* arg = void_arg;
- 546 105086 : const struct snapraid_file* file = void_data;
+ 545 105104 : const char* arg = void_arg;
+ 546 105104 : const struct snapraid_file* file = void_data;
547 :
- 548 105086 : return strcmp(arg, file->sub);
+ 548 105104 : return strcmp(arg, file->sub);
549 : }
550 :
- 551 23929 : int file_name_compare(const void* void_a, const void* void_b)
+ 551 23954 : int file_name_compare(const void* void_a, const void* void_b)
552 : {
- 553 23929 : const struct snapraid_file* file_a = void_a;
- 554 23929 : const struct snapraid_file* file_b = void_b;
- 555 23929 : const char* name_a = file_name(file_a);
- 556 23929 : const char* name_b = file_name(file_b);
+ 553 23954 : const struct snapraid_file* file_a = void_a;
+ 554 23954 : const struct snapraid_file* file_b = void_b;
+ 555 23954 : const char* name_a = file_name(file_a);
+ 556 23954 : const char* name_b = file_name(file_b);
557 :
- 558 23929 : return strcmp(name_a, name_b);
+ 558 23954 : return strcmp(name_a, name_b);
559 : }
560 :
561 23659 : int file_stamp_compare(const void* void_a, const void* void_b)
@@ -643,13 +643,13 @@
581 23659 : return 0;
582 : }
583 :
- 584 23929 : int file_namestamp_compare(const void* void_a, const void* void_b)
+ 584 23954 : int file_namestamp_compare(const void* void_a, const void* void_b)
585 : {
586 : int ret;
587 :
- 588 23929 : ret = file_name_compare(void_a, void_b);
- 589 23929 : if (ret != 0)
- 590 270 : return ret;
+ 588 23954 : ret = file_name_compare(void_a, void_b);
+ 589 23954 : if (ret != 0)
+ 590 295 : return ret;
591 :
592 23659 : return file_stamp_compare(void_a, void_b);
593 : }
@@ -665,697 +665,740 @@
603 0 : return file_stamp_compare(void_a, void_b);
604 : }
605 :
- 606 3607803 : struct snapraid_chunk* chunk_alloc(block_off_t parity_pos, struct snapraid_file* file, block_off_t file_pos, block_off_t count)
+ 606 3607761 : struct snapraid_chunk* chunk_alloc(block_off_t parity_pos, struct snapraid_file* file, block_off_t file_pos, block_off_t count)
607 : {
608 : struct snapraid_chunk* chunk;
609 :
- 610 3607803 : chunk = malloc_nofail(sizeof(struct snapraid_chunk));
- 611 3607803 : chunk->parity_pos = parity_pos;
- 612 3607803 : chunk->file = file;
- 613 3607803 : chunk->file_pos = file_pos;
- 614 3607803 : chunk->count = count;
- 615 :
- 616 3607803 : return chunk;
- 617 : }
- 618 :
- 619 3437425 : void chunk_free(struct snapraid_chunk* chunk)
- 620 : {
- 621 3437425 : free(chunk);
- 622 3437425 : }
- 623 :
- 624 43029334 : int chunk_parity_compare(const void* void_a, const void* void_b)
- 625 : {
- 626 43029334 : const struct snapraid_chunk* arg_a = void_a;
- 627 43029334 : const struct snapraid_chunk* arg_b = void_b;
+ 610 3607761 : if (count == 0) {
+ 611 : /* LCOV_EXCL_START */
+ 612 : log_fatal("Internal inconsistency when allocating empty chunk for file '%s' at position '%u/%u'\n", file->sub, file_pos, file->blockmax);
+ 613 : exit(EXIT_FAILURE);
+ 614 : /* LCOV_EXCL_STOP */
+ 615 : }
+ 616 3607761 : if (file_pos + count > file->blockmax) {
+ 617 : /* LCOV_EXCL_START */
+ 618 : log_fatal("Internal inconsistency when allocating overflowing chunk for file '%s' at position '%u:%u/%u'\n", file->sub, file_pos, count, file->blockmax);
+ 619 : exit(EXIT_FAILURE);
+ 620 : /* LCOV_EXCL_STOP */
+ 621 : }
+ 622 :
+ 623 3607761 : chunk = malloc_nofail(sizeof(struct snapraid_chunk));
+ 624 3607761 : chunk->parity_pos = parity_pos;
+ 625 3607761 : chunk->file = file;
+ 626 3607761 : chunk->file_pos = file_pos;
+ 627 3607761 : chunk->count = count;
628 :
- 629 43029334 : if (arg_a->parity_pos < arg_b->parity_pos)
- 630 931264 : return -1;
- 631 42098070 : if (arg_a->parity_pos > arg_b->parity_pos)
- 632 42059274 : return 1;
- 633 :
- 634 38796 : return 0;
- 635 : }
+ 629 3607761 : return chunk;
+ 630 : }
+ 631 :
+ 632 3437520 : void chunk_free(struct snapraid_chunk* chunk)
+ 633 : {
+ 634 3437520 : free(chunk);
+ 635 3437520 : }
636 :
- 637 43527266 : int chunk_file_compare(const void* void_a, const void* void_b)
+ 637 43029600 : int chunk_parity_compare(const void* void_a, const void* void_b)
638 : {
- 639 43527266 : const struct snapraid_chunk* arg_a = void_a;
- 640 43527266 : const struct snapraid_chunk* arg_b = void_b;
+ 639 43029600 : const struct snapraid_chunk* arg_a = void_a;
+ 640 43029600 : const struct snapraid_chunk* arg_b = void_b;
641 :
- 642 43527266 : if (arg_a->file < arg_b->file)
- 643 855502 : return -1;
- 644 42671764 : if (arg_a->file > arg_b->file)
- 645 42603010 : return 1;
+ 642 43029600 : if (arg_a->parity_pos < arg_b->parity_pos)
+ 643 932908 : return -1;
+ 644 42096692 : if (arg_a->parity_pos > arg_b->parity_pos)
+ 645 42057855 : return 1;
646 :
- 647 68754 : if (arg_a->file_pos < arg_b->file_pos)
- 648 192 : return -1;
- 649 68562 : if (arg_a->file_pos > arg_b->file_pos)
- 650 29766 : return 1;
- 651 :
- 652 38796 : return 0;
- 653 : }
+ 647 38837 : return 0;
+ 648 : }
+ 649 :
+ 650 43527418 : int chunk_file_compare(const void* void_a, const void* void_b)
+ 651 : {
+ 652 43527418 : const struct snapraid_chunk* arg_a = void_a;
+ 653 43527418 : const struct snapraid_chunk* arg_b = void_b;
654 :
- 655 115419 : struct snapraid_link* link_alloc(const char* sub, const char* linkto, unsigned link_flag)
- 656 : {
- 657 : struct snapraid_link* slink;
- 658 :
- 659 115419 : slink = malloc_nofail(sizeof(struct snapraid_link));
- 660 115419 : slink->sub = strdup_nofail(sub);
- 661 115419 : slink->linkto = strdup_nofail(linkto);
- 662 115419 : slink->flag = link_flag;
- 663 :
- 664 115419 : return slink;
- 665 : }
- 666 :
- 667 109621 : void link_free(struct snapraid_link* slink)
- 668 : {
- 669 109621 : free(slink->sub);
- 670 109621 : free(slink->linkto);
- 671 109621 : free(slink);
- 672 109621 : }
- 673 :
- 674 30380 : int link_name_compare_to_arg(const void* void_arg, const void* void_data)
- 675 : {
- 676 30380 : const char* arg = void_arg;
- 677 30380 : const struct snapraid_link* slink = void_data;
- 678 :
- 679 30380 : return strcmp(arg, slink->sub);
- 680 : }
- 681 :
- 682 1249 : int link_alpha_compare(const void* void_a, const void* void_b)
- 683 : {
- 684 1249 : const struct snapraid_link* slink_a = void_a;
- 685 1249 : const struct snapraid_link* slink_b = void_b;
+ 655 43527418 : if (arg_a->file < arg_b->file)
+ 656 856585 : return -1;
+ 657 42670833 : if (arg_a->file > arg_b->file)
+ 658 42601978 : return 1;
+ 659 :
+ 660 68855 : if (arg_a->file_pos < arg_b->file_pos)
+ 661 192 : return -1;
+ 662 68663 : if (arg_a->file_pos > arg_b->file_pos)
+ 663 29826 : return 1;
+ 664 :
+ 665 38837 : return 0;
+ 666 : }
+ 667 :
+ 668 115419 : struct snapraid_link* link_alloc(const char* sub, const char* linkto, unsigned link_flag)
+ 669 : {
+ 670 : struct snapraid_link* slink;
+ 671 :
+ 672 115419 : slink = malloc_nofail(sizeof(struct snapraid_link));
+ 673 115419 : slink->sub = strdup_nofail(sub);
+ 674 115419 : slink->linkto = strdup_nofail(linkto);
+ 675 115419 : slink->flag = link_flag;
+ 676 :
+ 677 115419 : return slink;
+ 678 : }
+ 679 :
+ 680 109621 : void link_free(struct snapraid_link* slink)
+ 681 : {
+ 682 109621 : free(slink->sub);
+ 683 109621 : free(slink->linkto);
+ 684 109621 : free(slink);
+ 685 109621 : }
686 :
- 687 1249 : return strcmp(slink_a->sub, slink_b->sub);
- 688 : }
- 689 :
- 690 760 : struct snapraid_dir* dir_alloc(const char* sub)
- 691 : {
- 692 : struct snapraid_dir* dir;
- 693 :
- 694 760 : dir = malloc_nofail(sizeof(struct snapraid_dir));
- 695 760 : dir->sub = strdup_nofail(sub);
- 696 760 : dir->flag = 0;
- 697 :
- 698 760 : return dir;
- 699 : }
- 700 :
- 701 712 : void dir_free(struct snapraid_dir* dir)
- 702 : {
- 703 712 : free(dir->sub);
- 704 712 : free(dir);
- 705 712 : }
+ 687 30380 : int link_name_compare_to_arg(const void* void_arg, const void* void_data)
+ 688 : {
+ 689 30380 : const char* arg = void_arg;
+ 690 30380 : const struct snapraid_link* slink = void_data;
+ 691 :
+ 692 30380 : return strcmp(arg, slink->sub);
+ 693 : }
+ 694 :
+ 695 1249 : int link_alpha_compare(const void* void_a, const void* void_b)
+ 696 : {
+ 697 1249 : const struct snapraid_link* slink_a = void_a;
+ 698 1249 : const struct snapraid_link* slink_b = void_b;
+ 699 :
+ 700 1249 : return strcmp(slink_a->sub, slink_b->sub);
+ 701 : }
+ 702 :
+ 703 760 : struct snapraid_dir* dir_alloc(const char* sub)
+ 704 : {
+ 705 : struct snapraid_dir* dir;
706 :
- 707 217 : int dir_name_compare(const void* void_arg, const void* void_data)
- 708 : {
- 709 217 : const char* arg = void_arg;
- 710 217 : const struct snapraid_dir* dir = void_data;
- 711 :
- 712 217 : return strcmp(arg, dir->sub);
- 713 : }
- 714 :
- 715 1477 : struct snapraid_disk* disk_alloc(const char* name, const char* dir, uint64_t dev, int skip)
- 716 : {
- 717 : struct snapraid_disk* disk;
- 718 :
- 719 1477 : disk = malloc_nofail(sizeof(struct snapraid_disk));
- 720 1477 : pathcpy(disk->name, sizeof(disk->name), name);
- 721 1477 : pathimport(disk->dir, sizeof(disk->dir), dir);
- 722 :
- 723 : /* ensure that the dir terminate with "/" if it isn't empty */
- 724 1477 : pathslash(disk->dir, sizeof(disk->dir));
- 725 :
- 726 1477 : disk->smartctl[0] = 0;
- 727 1477 : disk->device = dev;
- 728 1477 : disk->tick = 0;
- 729 1477 : disk->total_blocks = 0;
- 730 1477 : disk->free_blocks = 0;
- 731 1477 : disk->first_free_block = 0;
- 732 1477 : disk->has_volatile_inodes = 0;
- 733 1477 : disk->has_unreliable_physical = 0;
- 734 1477 : disk->has_different_uuid = 0;
- 735 1477 : disk->has_unsupported_uuid = 0;
- 736 1477 : disk->had_empty_uuid = 0;
- 737 1477 : disk->mapping_idx = -1;
- 738 1477 : disk->skip_access = skip;
- 739 1477 : tommy_list_init(&disk->filelist);
- 740 1477 : tommy_list_init(&disk->deletedlist);
- 741 1477 : tommy_hashdyn_init(&disk->inodeset);
- 742 1477 : tommy_hashdyn_init(&disk->pathset);
- 743 1477 : tommy_hashdyn_init(&disk->stampset);
- 744 1477 : tommy_list_init(&disk->linklist);
- 745 1477 : tommy_hashdyn_init(&disk->linkset);
- 746 1477 : tommy_list_init(&disk->dirlist);
- 747 1477 : tommy_hashdyn_init(&disk->dirset);
- 748 1477 : tommy_tree_init(&disk->fs_parity, chunk_parity_compare);
- 749 1477 : tommy_tree_init(&disk->fs_file, chunk_file_compare);
- 750 1477 : disk->fs_last = 0;
- 751 :
- 752 1477 : return disk;
- 753 : }
- 754 :
- 755 1351 : void disk_free(struct snapraid_disk* disk)
- 756 : {
- 757 1351 : tommy_list_foreach(&disk->filelist, (tommy_foreach_func*)file_free);
- 758 1351 : tommy_list_foreach(&disk->deletedlist, (tommy_foreach_func*)file_free);
- 759 1351 : tommy_tree_foreach(&disk->fs_file, (tommy_foreach_func*)chunk_free);
- 760 1351 : tommy_hashdyn_done(&disk->inodeset);
- 761 1351 : tommy_hashdyn_done(&disk->pathset);
- 762 1351 : tommy_hashdyn_done(&disk->stampset);
- 763 1351 : tommy_list_foreach(&disk->linklist, (tommy_foreach_func*)link_free);
- 764 1351 : tommy_hashdyn_done(&disk->linkset);
- 765 1351 : tommy_list_foreach(&disk->dirlist, (tommy_foreach_func*)dir_free);
- 766 1351 : tommy_hashdyn_done(&disk->dirset);
- 767 1351 : free(disk);
- 768 1351 : }
- 769 :
- 770 : struct chunk_disk_empty {
- 771 : block_off_t blockmax;
- 772 : };
- 773 :
- 774 : /**
- 775 : * Compare the chunk if inside the specified blockmax.
- 776 : */
- 777 10 : static int chunk_disk_empty_compare(const void* void_a, const void* void_b)
- 778 : {
- 779 10 : const struct chunk_disk_empty* arg_a = void_a;
- 780 10 : const struct snapraid_chunk* arg_b = void_b;
- 781 :
- 782 : /* if the block is inside the specified blockmax, it's found */
- 783 10 : if (arg_a->blockmax > arg_b->parity_pos)
- 784 5 : return 0;
- 785 :
- 786 : /* otherwise search for a smaller one */
- 787 5 : return -1;
- 788 : }
- 789 :
- 790 804 : int disk_is_empty(struct snapraid_disk* disk, block_off_t blockmax)
+ 707 760 : dir = malloc_nofail(sizeof(struct snapraid_dir));
+ 708 760 : dir->sub = strdup_nofail(sub);
+ 709 760 : dir->flag = 0;
+ 710 :
+ 711 760 : return dir;
+ 712 : }
+ 713 :
+ 714 712 : void dir_free(struct snapraid_dir* dir)
+ 715 : {
+ 716 712 : free(dir->sub);
+ 717 712 : free(dir);
+ 718 712 : }
+ 719 :
+ 720 217 : int dir_name_compare(const void* void_arg, const void* void_data)
+ 721 : {
+ 722 217 : const char* arg = void_arg;
+ 723 217 : const struct snapraid_dir* dir = void_data;
+ 724 :
+ 725 217 : return strcmp(arg, dir->sub);
+ 726 : }
+ 727 :
+ 728 1477 : struct snapraid_disk* disk_alloc(const char* name, const char* dir, uint64_t dev, int skip)
+ 729 : {
+ 730 : struct snapraid_disk* disk;
+ 731 :
+ 732 1477 : disk = malloc_nofail(sizeof(struct snapraid_disk));
+ 733 1477 : pathcpy(disk->name, sizeof(disk->name), name);
+ 734 1477 : pathimport(disk->dir, sizeof(disk->dir), dir);
+ 735 :
+ 736 : /* ensure that the dir terminate with "/" if it isn't empty */
+ 737 1477 : pathslash(disk->dir, sizeof(disk->dir));
+ 738 :
+ 739 1477 : disk->smartctl[0] = 0;
+ 740 1477 : disk->device = dev;
+ 741 1477 : disk->tick = 0;
+ 742 1477 : disk->total_blocks = 0;
+ 743 1477 : disk->free_blocks = 0;
+ 744 1477 : disk->first_free_block = 0;
+ 745 1477 : disk->has_volatile_inodes = 0;
+ 746 1477 : disk->has_unreliable_physical = 0;
+ 747 1477 : disk->has_different_uuid = 0;
+ 748 1477 : disk->has_unsupported_uuid = 0;
+ 749 1477 : disk->had_empty_uuid = 0;
+ 750 1477 : disk->mapping_idx = -1;
+ 751 1477 : disk->skip_access = skip;
+ 752 1477 : tommy_list_init(&disk->filelist);
+ 753 1477 : tommy_list_init(&disk->deletedlist);
+ 754 1477 : tommy_hashdyn_init(&disk->inodeset);
+ 755 1477 : tommy_hashdyn_init(&disk->pathset);
+ 756 1477 : tommy_hashdyn_init(&disk->stampset);
+ 757 1477 : tommy_list_init(&disk->linklist);
+ 758 1477 : tommy_hashdyn_init(&disk->linkset);
+ 759 1477 : tommy_list_init(&disk->dirlist);
+ 760 1477 : tommy_hashdyn_init(&disk->dirset);
+ 761 1477 : tommy_tree_init(&disk->fs_parity, chunk_parity_compare);
+ 762 1477 : tommy_tree_init(&disk->fs_file, chunk_file_compare);
+ 763 1477 : disk->fs_last = 0;
+ 764 :
+ 765 1477 : return disk;
+ 766 : }
+ 767 :
+ 768 1351 : void disk_free(struct snapraid_disk* disk)
+ 769 : {
+ 770 1351 : tommy_list_foreach(&disk->filelist, (tommy_foreach_func*)file_free);
+ 771 1351 : tommy_list_foreach(&disk->deletedlist, (tommy_foreach_func*)file_free);
+ 772 1351 : tommy_tree_foreach(&disk->fs_file, (tommy_foreach_func*)chunk_free);
+ 773 1351 : tommy_hashdyn_done(&disk->inodeset);
+ 774 1351 : tommy_hashdyn_done(&disk->pathset);
+ 775 1351 : tommy_hashdyn_done(&disk->stampset);
+ 776 1351 : tommy_list_foreach(&disk->linklist, (tommy_foreach_func*)link_free);
+ 777 1351 : tommy_hashdyn_done(&disk->linkset);
+ 778 1351 : tommy_list_foreach(&disk->dirlist, (tommy_foreach_func*)dir_free);
+ 779 1351 : tommy_hashdyn_done(&disk->dirset);
+ 780 1351 : free(disk);
+ 781 1351 : }
+ 782 :
+ 783 : struct chunk_disk_empty {
+ 784 : block_off_t blockmax;
+ 785 : };
+ 786 :
+ 787 : /**
+ 788 : * Compare the chunk if inside the specified blockmax.
+ 789 : */
+ 790 10 : static int chunk_disk_empty_compare(const void* void_a, const void* void_b)
791 : {
- 792 804 : struct chunk_disk_empty arg = { blockmax };
- 793 :
- 794 : /* if there is an element, it's not empty */
- 795 : /* even if links and dirs have no block allocation */
- 796 804 : if (!tommy_list_empty(&disk->filelist))
- 797 736 : return 0;
- 798 68 : if (!tommy_list_empty(&disk->linklist))
- 799 0 : return 0;
- 800 68 : if (!tommy_list_empty(&disk->dirlist))
- 801 0 : return 0;
+ 792 10 : const struct chunk_disk_empty* arg_a = void_a;
+ 793 10 : const struct snapraid_chunk* arg_b = void_b;
+ 794 :
+ 795 : /* if the block is inside the specified blockmax, it's found */
+ 796 10 : if (arg_a->blockmax > arg_b->parity_pos)
+ 797 5 : return 0;
+ 798 :
+ 799 : /* otherwise search for a smaller one */
+ 800 5 : return -1;
+ 801 : }
802 :
- 803 : /* search for any chunk inside blockmax */
- 804 68 : if (tommy_tree_search_compare(&disk->fs_parity, chunk_disk_empty_compare, &arg) != 0)
- 805 5 : return 0;
+ 803 804 : int disk_is_empty(struct snapraid_disk* disk, block_off_t blockmax)
+ 804 : {
+ 805 804 : struct chunk_disk_empty arg = { blockmax };
806 :
- 807 : /* finally, it's empty */
- 808 63 : return 1;
- 809 : }
- 810 :
- 811 : struct chunk_disk_size {
- 812 : block_off_t size;
- 813 : };
- 814 :
- 815 : /**
- 816 : * Compare the chunk by highest parity position.
- 817 : *
- 818 : * The maximum parity position is stored as size.
- 819 : */
- 820 47777 : static int chunk_disk_size_compare(const void* void_a, const void* void_b)
- 821 : {
- 822 47777 : struct chunk_disk_size* arg_a = (void*)void_a;
- 823 47777 : const struct snapraid_chunk* arg_b = void_b;
- 824 :
- 825 : /* get the maximum size */
- 826 47777 : if (arg_a->size < arg_b->parity_pos + arg_b->count)
- 827 47777 : arg_a->size = arg_b->parity_pos + arg_b->count;
- 828 :
- 829 : /* search always for a bigger one */
- 830 47777 : return 1;
- 831 : }
- 832 :
- 833 3955 : block_off_t disk_size(struct snapraid_disk* disk)
+ 807 : /* if there is an element, it's not empty */
+ 808 : /* even if links and dirs have no block allocation */
+ 809 804 : if (!tommy_list_empty(&disk->filelist))
+ 810 736 : return 0;
+ 811 68 : if (!tommy_list_empty(&disk->linklist))
+ 812 0 : return 0;
+ 813 68 : if (!tommy_list_empty(&disk->dirlist))
+ 814 0 : return 0;
+ 815 :
+ 816 : /* search for any chunk inside blockmax */
+ 817 68 : if (tommy_tree_search_compare(&disk->fs_parity, chunk_disk_empty_compare, &arg) != 0)
+ 818 5 : return 0;
+ 819 :
+ 820 : /* finally, it's empty */
+ 821 63 : return 1;
+ 822 : }
+ 823 :
+ 824 : struct chunk_disk_size {
+ 825 : block_off_t size;
+ 826 : };
+ 827 :
+ 828 : /**
+ 829 : * Compare the chunk by highest parity position.
+ 830 : *
+ 831 : * The maximum parity position is stored as size.
+ 832 : */
+ 833 47779 : static int chunk_disk_size_compare(const void* void_a, const void* void_b)
834 : {
- 835 3955 : struct chunk_disk_size arg = { 0 };
- 836 3955 : tommy_tree_search_compare(&disk->fs_parity, chunk_disk_size_compare, &arg);
- 837 3955 : return arg.size;
- 838 : }
- 839 :
- 840 : struct chunk_check {
- 841 : const struct snapraid_chunk* prev;
- 842 : int result;
- 843 : };
- 844 :
- 845 6291272 : void chunk_parity_check_foreach(void* void_arg, void* void_obj)
- 846 : {
- 847 6291272 : struct chunk_check* arg = void_arg;
- 848 6291272 : const struct snapraid_chunk* obj = void_obj;
- 849 6291272 : const struct snapraid_chunk* prev = arg->prev;
- 850 :
- 851 : /* set the next previous block */
- 852 6291272 : arg->prev = obj;
- 853 :
- 854 : /* stop reporting if too many errors */
- 855 6291272 : if (arg->result > 100) {
- 856 : /* LCOV_EXCL_START */
- 857 : return;
- 858 : /* LCOV_EXCL_STOP */
- 859 : }
- 860 :
- 861 : /* check only if there is a previous block */
- 862 6291272 : if (!prev)
- 863 2473 : return;
- 864 :
- 865 : /* check the order */
- 866 6288799 : if (prev->parity_pos >= obj->parity_pos) {
- 867 : /* LCOV_EXCL_START */
- 868 : log_fatal("Internal inconsistency in parity order for files '%s' at '%u:%u' and '%s' at '%u:%u'\n",
- 869 : prev->file->sub, prev->parity_pos, prev->count, obj->file->sub, obj->parity_pos, obj->count);
- 870 : ++arg->result;
- 871 : return;
- 872 : /* LCOV_EXCL_STOP */
- 873 : }
- 874 :
- 875 : /* check that the chunks don't overlap */
- 876 6288799 : if (prev->parity_pos + prev->count > obj->parity_pos) {
- 877 : /* LCOV_EXCL_START */
- 878 : log_fatal("Internal inconsistency for parity overlap for files '%s' at '%u:%u' and '%s' at '%u:%u'\n",
- 879 : prev->file->sub, prev->parity_pos, prev->count, obj->file->sub, obj->parity_pos, obj->count);
- 880 : ++arg->result;
- 881 : return;
- 882 : /* LCOV_EXCL_STOP */
- 883 : }
- 884 : }
- 885 :
- 886 6291272 : void chunk_file_check_foreach(void* void_arg, void* void_obj)
- 887 : {
- 888 6291272 : struct chunk_check* arg = void_arg;
- 889 6291272 : const struct snapraid_chunk* obj = void_obj;
- 890 6291272 : const struct snapraid_chunk* prev = arg->prev;
- 891 :
- 892 : /* set the next previous block */
- 893 6291272 : arg->prev = obj;
- 894 :
- 895 : /* stop reporting if too many errors */
- 896 6291272 : if (arg->result > 100) {
- 897 : /* LCOV_EXCL_START */
- 898 : return;
- 899 : /* LCOV_EXCL_STOP */
- 900 : }
- 901 :
- 902 : /* note that for deleted files, some chunks may be missing */
- 903 :
- 904 : /* if the files are different */
- 905 6291272 : if (!prev || prev->file != obj->file) {
- 906 6247390 : if (prev != 0) {
- 907 6244917 : if (file_flag_has(prev->file, FILE_IS_DELETED)) {
- 908 : /* check that the chunk doesn't overflow the file */
- 909 59701 : if (prev->file_pos + prev->count > prev->file->blockmax) {
- 910 : /* LCOV_EXCL_START */
- 911 : log_fatal("Internal inconsistency in delete end for file '%s' at '%u:%u' overflowing size '%u'\n",
- 912 : prev->file->sub, prev->file_pos, prev->count, prev->file->blockmax);
- 913 : ++arg->result;
- 914 : return;
- 915 : /* LCOV_EXCL_STOP */
- 916 : }
- 917 : } else {
- 918 : /* check that the chunk ends the file */
- 919 6185216 : if (prev->file_pos + prev->count != prev->file->blockmax) {
- 920 : /* LCOV_EXCL_START */
- 921 : log_fatal("Internal inconsistency in file end for file '%s' at '%u:%u' instead of size '%u'\n",
- 922 : prev->file->sub, prev->file_pos, prev->count, prev->file->blockmax);
- 923 : ++arg->result;
- 924 : return;
- 925 : /* LCOV_EXCL_STOP */
- 926 : }
- 927 : }
- 928 : }
- 929 :
- 930 12494780 : if (file_flag_has(obj->file, FILE_IS_DELETED)) {
- 931 : /* check that the chunk doesn't overflow the file */
- 932 59776 : if (obj->file_pos + obj->count > obj->file->blockmax) {
- 933 : /* LCOV_EXCL_START */
- 934 : log_fatal("Internal inconsistency in delete start for file '%s' at '%u:%u' overflowing size '%u'\n",
- 935 : obj->file->sub, obj->file_pos, obj->count, obj->file->blockmax);
- 936 : ++arg->result;
- 937 : return;
- 938 : /* LCOV_EXCL_STOP */
- 939 : }
- 940 : } else {
- 941 : /* check that the chunk starts the file */
- 942 6187614 : if (obj->file_pos != 0) {
- 943 : /* LCOV_EXCL_START */
- 944 : log_fatal("Internal inconsistency in file start for file '%s' at '%u:%u'\n",
- 945 : obj->file->sub, obj->file_pos, obj->count);
- 946 : ++arg->result;
- 947 : return;
- 948 : /* LCOV_EXCL_STOP */
- 949 : }
- 950 : }
- 951 : } else {
- 952 : /* check the order */
- 953 43882 : if (prev->file_pos >= obj->file_pos) {
- 954 : /* LCOV_EXCL_START */
- 955 : log_fatal("Internal inconsistency in file order for file '%s' at '%u:%u' and at '%u:%u'\n",
- 956 : prev->file->sub, prev->file_pos, prev->count, obj->file_pos, obj->count);
- 957 : ++arg->result;
- 958 : return;
- 959 : /* LCOV_EXCL_STOP */
- 960 : }
- 961 :
- 962 43882 : if (file_flag_has(obj->file, FILE_IS_DELETED)) {
- 963 : /* check that the chunks don't overlap */
- 964 27 : if (prev->file_pos + prev->count > obj->file_pos) {
- 965 : /* LCOV_EXCL_START */
- 966 : log_fatal("Internal inconsistency in delete sequence for file '%s' at '%u:%u' and at '%u:%u'\n",
- 967 : prev->file->sub, prev->file_pos, prev->count, obj->file_pos, obj->count);
- 968 : ++arg->result;
- 969 : return;
- 970 : /* LCOV_EXCL_STOP */
- 971 : }
- 972 : } else {
- 973 : /* check that the chunks are sequential */
- 974 43855 : if (prev->file_pos + prev->count != obj->file_pos) {
- 975 : /* LCOV_EXCL_START */
- 976 : log_fatal("Internal inconsistency in file sequence for file '%s' at '%u:%u' and at '%u:%u'\n",
- 977 : prev->file->sub, prev->file_pos, prev->count, obj->file_pos, obj->count);
- 978 : ++arg->result;
- 979 : return;
- 980 : /* LCOV_EXCL_STOP */
- 981 : }
- 982 : }
- 983 : }
- 984 : }
- 985 :
- 986 2676 : int fs_check(struct snapraid_disk* disk)
- 987 : {
- 988 : struct chunk_check arg;
- 989 :
- 990 : /* error count starts from 0 */
- 991 2676 : arg.result = 0;
+ 835 47779 : struct chunk_disk_size* arg_a = (void*)void_a;
+ 836 47779 : const struct snapraid_chunk* arg_b = void_b;
+ 837 :
+ 838 : /* get the maximum size */
+ 839 47779 : if (arg_a->size < arg_b->parity_pos + arg_b->count)
+ 840 47779 : arg_a->size = arg_b->parity_pos + arg_b->count;
+ 841 :
+ 842 : /* search always for a bigger one */
+ 843 47779 : return 1;
+ 844 : }
+ 845 :
+ 846 3955 : block_off_t disk_size(struct snapraid_disk* disk)
+ 847 : {
+ 848 3955 : struct chunk_disk_size arg = { 0 };
+ 849 3955 : tommy_tree_search_compare(&disk->fs_parity, chunk_disk_size_compare, &arg);
+ 850 3955 : return arg.size;
+ 851 : }
+ 852 :
+ 853 : struct chunk_check {
+ 854 : const struct snapraid_chunk* prev;
+ 855 : int result;
+ 856 : };
+ 857 :
+ 858 6291380 : void chunk_parity_check_foreach(void* void_arg, void* void_obj)
+ 859 : {
+ 860 6291380 : struct chunk_check* arg = void_arg;
+ 861 6291380 : const struct snapraid_chunk* obj = void_obj;
+ 862 6291380 : const struct snapraid_chunk* prev = arg->prev;
+ 863 :
+ 864 : /* set the next previous block */
+ 865 6291380 : arg->prev = obj;
+ 866 :
+ 867 : /* stop reporting if too many errors */
+ 868 6291380 : if (arg->result > 100) {
+ 869 : /* LCOV_EXCL_START */
+ 870 : return;
+ 871 : /* LCOV_EXCL_STOP */
+ 872 : }
+ 873 :
+ 874 6291380 : if (obj->count == 0) {
+ 875 : /* LCOV_EXCL_START */
+ 876 : log_fatal("Internal inconsistency in parity count zero for file '%s' at '%u'\n",
+ 877 : obj->file->sub, obj->parity_pos);
+ 878 : ++arg->result;
+ 879 : return;
+ 880 : /* LCOV_EXCL_STOP */
+ 881 : }
+ 882 :
+ 883 : /* check only if there is a previous block */
+ 884 6291380 : if (!prev)
+ 885 2473 : return;
+ 886 :
+ 887 : /* check the order */
+ 888 6288907 : if (prev->parity_pos >= obj->parity_pos) {
+ 889 : /* LCOV_EXCL_START */
+ 890 : log_fatal("Internal inconsistency in parity order for files '%s' at '%u:%u' and '%s' at '%u:%u'\n",
+ 891 : prev->file->sub, prev->parity_pos, prev->count, obj->file->sub, obj->parity_pos, obj->count);
+ 892 : ++arg->result;
+ 893 : return;
+ 894 : /* LCOV_EXCL_STOP */
+ 895 : }
+ 896 :
+ 897 : /* check that the chunks don't overlap */
+ 898 6288907 : if (prev->parity_pos + prev->count > obj->parity_pos) {
+ 899 : /* LCOV_EXCL_START */
+ 900 : log_fatal("Internal inconsistency for parity overlap for files '%s' at '%u:%u' and '%s' at '%u:%u'\n",
+ 901 : prev->file->sub, prev->parity_pos, prev->count, obj->file->sub, obj->parity_pos, obj->count);
+ 902 : ++arg->result;
+ 903 : return;
+ 904 : /* LCOV_EXCL_STOP */
+ 905 : }
+ 906 : }
+ 907 :
+ 908 6291380 : void chunk_file_check_foreach(void* void_arg, void* void_obj)
+ 909 : {
+ 910 6291380 : struct chunk_check* arg = void_arg;
+ 911 6291380 : const struct snapraid_chunk* obj = void_obj;
+ 912 6291380 : const struct snapraid_chunk* prev = arg->prev;
+ 913 :
+ 914 : /* set the next previous block */
+ 915 6291380 : arg->prev = obj;
+ 916 :
+ 917 : /* stop reporting if too many errors */
+ 918 6291380 : if (arg->result > 100) {
+ 919 : /* LCOV_EXCL_START */
+ 920 : return;
+ 921 : /* LCOV_EXCL_STOP */
+ 922 : }
+ 923 :
+ 924 6291380 : if (obj->count == 0) {
+ 925 : /* LCOV_EXCL_START */
+ 926 : log_fatal("Internal inconsistency in file count zero for file '%s' at '%u'\n",
+ 927 : obj->file->sub, obj->file_pos);
+ 928 : ++arg->result;
+ 929 : return;
+ 930 : /* LCOV_EXCL_STOP */
+ 931 : }
+ 932 :
+ 933 : /* note that for deleted files, some chunks may be missing */
+ 934 :
+ 935 : /* if the files are different */
+ 936 6291380 : if (!prev || prev->file != obj->file) {
+ 937 6247390 : if (prev != 0) {
+ 938 6244917 : if (file_flag_has(prev->file, FILE_IS_DELETED)) {
+ 939 : /* check that the chunk doesn't overflow the file */
+ 940 59701 : if (prev->file_pos + prev->count > prev->file->blockmax) {
+ 941 : /* LCOV_EXCL_START */
+ 942 : log_fatal("Internal inconsistency in delete end for file '%s' at '%u:%u' overflowing size '%u'\n",
+ 943 : prev->file->sub, prev->file_pos, prev->count, prev->file->blockmax);
+ 944 : ++arg->result;
+ 945 : return;
+ 946 : /* LCOV_EXCL_STOP */
+ 947 : }
+ 948 : } else {
+ 949 : /* check that the chunk ends the file */
+ 950 6185216 : if (prev->file_pos + prev->count != prev->file->blockmax) {
+ 951 : /* LCOV_EXCL_START */
+ 952 : log_fatal("Internal inconsistency in file end for file '%s' at '%u:%u' instead of size '%u'\n",
+ 953 : prev->file->sub, prev->file_pos, prev->count, prev->file->blockmax);
+ 954 : ++arg->result;
+ 955 : return;
+ 956 : /* LCOV_EXCL_STOP */
+ 957 : }
+ 958 : }
+ 959 : }
+ 960 :
+ 961 12494780 : if (file_flag_has(obj->file, FILE_IS_DELETED)) {
+ 962 : /* check that the chunk doesn't overflow the file */
+ 963 59776 : if (obj->file_pos + obj->count > obj->file->blockmax) {
+ 964 : /* LCOV_EXCL_START */
+ 965 : log_fatal("Internal inconsistency in delete start for file '%s' at '%u:%u' overflowing size '%u'\n",
+ 966 : obj->file->sub, obj->file_pos, obj->count, obj->file->blockmax);
+ 967 : ++arg->result;
+ 968 : return;
+ 969 : /* LCOV_EXCL_STOP */
+ 970 : }
+ 971 : } else {
+ 972 : /* check that the chunk starts the file */
+ 973 6187614 : if (obj->file_pos != 0) {
+ 974 : /* LCOV_EXCL_START */
+ 975 : log_fatal("Internal inconsistency in file start for file '%s' at '%u:%u'\n",
+ 976 : obj->file->sub, obj->file_pos, obj->count);
+ 977 : ++arg->result;
+ 978 : return;
+ 979 : /* LCOV_EXCL_STOP */
+ 980 : }
+ 981 : }
+ 982 : } else {
+ 983 : /* check the order */
+ 984 43990 : if (prev->file_pos >= obj->file_pos) {
+ 985 : /* LCOV_EXCL_START */
+ 986 : log_fatal("Internal inconsistency in file order for file '%s' at '%u:%u' and at '%u:%u'\n",
+ 987 : prev->file->sub, prev->file_pos, prev->count, obj->file_pos, obj->count);
+ 988 : ++arg->result;
+ 989 : return;
+ 990 : /* LCOV_EXCL_STOP */
+ 991 : }
992 :
- 993 : /* check parity sequence */
- 994 2676 : arg.prev = 0;
- 995 2676 : tommy_tree_foreach_arg(&disk->fs_parity, chunk_parity_check_foreach, &arg);
- 996 :
- 997 : /* check file sequence */
- 998 2676 : arg.prev = 0;
- 999 2676 : tommy_tree_foreach_arg(&disk->fs_file, chunk_file_check_foreach, &arg);
- 1000 :
- 1001 2676 : if (arg.result != 0)
- 1002 0 : return -1;
- 1003 :
- 1004 2676 : return 0;
- 1005 : }
- 1006 :
- 1007 : struct chunk_parity_inside {
- 1008 : block_off_t parity_pos;
- 1009 : };
- 1010 :
- 1011 : /**
- 1012 : * Compare the chunk if containing the specified parity position.
- 1013 : */
- 1014 213182654 : static int chunk_parity_inside_compare(const void* void_a, const void* void_b)
- 1015 : {
- 1016 213182654 : const struct chunk_parity_inside* arg_a = void_a;
- 1017 213182654 : const struct snapraid_chunk* arg_b = void_b;
- 1018 :
- 1019 213182654 : if (arg_a->parity_pos < arg_b->parity_pos)
- 1020 79586474 : return -1;
- 1021 133596180 : if (arg_a->parity_pos >= arg_b->parity_pos + arg_b->count)
- 1022 116201011 : return 1;
+ 993 43990 : if (file_flag_has(obj->file, FILE_IS_DELETED)) {
+ 994 : /* check that the chunks don't overlap */
+ 995 27 : if (prev->file_pos + prev->count > obj->file_pos) {
+ 996 : /* LCOV_EXCL_START */
+ 997 : log_fatal("Internal inconsistency in delete sequence for file '%s' at '%u:%u' and at '%u:%u'\n",
+ 998 : prev->file->sub, prev->file_pos, prev->count, obj->file_pos, obj->count);
+ 999 : ++arg->result;
+ 1000 : return;
+ 1001 : /* LCOV_EXCL_STOP */
+ 1002 : }
+ 1003 : } else {
+ 1004 : /* check that the chunks are sequential */
+ 1005 43963 : if (prev->file_pos + prev->count != obj->file_pos) {
+ 1006 : /* LCOV_EXCL_START */
+ 1007 : log_fatal("Internal inconsistency in file sequence for file '%s' at '%u:%u' and at '%u:%u'\n",
+ 1008 : prev->file->sub, prev->file_pos, prev->count, obj->file_pos, obj->count);
+ 1009 : ++arg->result;
+ 1010 : return;
+ 1011 : /* LCOV_EXCL_STOP */
+ 1012 : }
+ 1013 : }
+ 1014 : }
+ 1015 : }
+ 1016 :
+ 1017 2676 : int fs_check(struct snapraid_disk* disk)
+ 1018 : {
+ 1019 : struct chunk_check arg;
+ 1020 :
+ 1021 : /* error count starts from 0 */
+ 1022 2676 : arg.result = 0;
1023 :
- 1024 17395169 : return 0;
- 1025 : }
- 1026 :
- 1027 : /**
- 1028 : * Seach the chunk at the specified parity position.
- 1029 : * The search is optimized for sequential accesses.
- 1030 : * \return If not found return 0
- 1031 : */
- 1032 62657428 : static struct snapraid_chunk* fs_par2chunk_get_ts(struct snapraid_disk* disk, struct snapraid_chunk** fs_last, block_off_t parity_pos)
- 1033 : {
- 1034 : struct snapraid_chunk* chunk;
- 1035 :
- 1036 : /* check if the last accessed chunk matches */
- 1037 62657428 : if (*fs_last
- 1038 62843273 : && parity_pos >= (*fs_last)->parity_pos
- 1039 62738070 : && parity_pos < (*fs_last)->parity_pos + (*fs_last)->count
- 1040 : ) {
- 1041 43160159 : chunk = *fs_last;
- 1042 : } else {
- 1043 19497269 : struct chunk_parity_inside arg = { parity_pos };
- 1044 19497269 : chunk = tommy_tree_search_compare(&disk->fs_parity, chunk_parity_inside_compare, &arg);
- 1045 : }
- 1046 :
- 1047 62844816 : if (!chunk)
- 1048 2353186 : return 0;
+ 1024 : /* check parity sequence */
+ 1025 2676 : arg.prev = 0;
+ 1026 2676 : tommy_tree_foreach_arg(&disk->fs_parity, chunk_parity_check_foreach, &arg);
+ 1027 :
+ 1028 : /* check file sequence */
+ 1029 2676 : arg.prev = 0;
+ 1030 2676 : tommy_tree_foreach_arg(&disk->fs_file, chunk_file_check_foreach, &arg);
+ 1031 :
+ 1032 2676 : if (arg.result != 0)
+ 1033 0 : return -1;
+ 1034 :
+ 1035 2676 : return 0;
+ 1036 : }
+ 1037 :
+ 1038 : struct chunk_parity_inside {
+ 1039 : block_off_t parity_pos;
+ 1040 : };
+ 1041 :
+ 1042 : /**
+ 1043 : * Compare the chunk if containing the specified parity position.
+ 1044 : */
+ 1045 211700412 : static int chunk_parity_inside_compare(const void* void_a, const void* void_b)
+ 1046 : {
+ 1047 211700412 : const struct chunk_parity_inside* arg_a = void_a;
+ 1048 211700412 : const struct snapraid_chunk* arg_b = void_b;
1049 :
- 1050 : /* store the last accessed chunk */
- 1051 60491630 : *fs_last = chunk;
- 1052 :
- 1053 60491630 : return chunk;
- 1054 : }
- 1055 :
- 1056 : struct chunk_file_inside {
- 1057 : struct snapraid_file* file;
- 1058 : block_off_t file_pos;
- 1059 : };
- 1060 :
- 1061 : /**
- 1062 : * Compare the chunk if containing the specified file position.
- 1063 : */
- 1064 123631586 : static int chunk_file_inside_compare(const void* void_a, const void* void_b)
- 1065 : {
- 1066 123631586 : const struct chunk_file_inside* arg_a = void_a;
- 1067 123631586 : const struct snapraid_chunk* arg_b = void_b;
- 1068 :
- 1069 123631586 : if (arg_a->file < arg_b->file)
- 1070 52889679 : return -1;
- 1071 70741907 : if (arg_a->file > arg_b->file)
- 1072 58811856 : return 1;
- 1073 :
- 1074 11930051 : if (arg_a->file_pos < arg_b->file_pos)
- 1075 48627 : return -1;
- 1076 11881424 : if (arg_a->file_pos >= arg_b->file_pos + arg_b->count)
- 1077 44495 : return 1;
- 1078 :
- 1079 11836929 : return 0;
- 1080 : }
- 1081 :
- 1082 : /**
- 1083 : * Seach the chunk at the specified file position.
- 1084 : * The search is optimized for sequential accesses.
- 1085 : * \return If not found return 0
- 1086 : */
- 1087 34130326 : static struct snapraid_chunk* fs_file2chunk_get_ts(struct snapraid_disk* disk, struct snapraid_chunk** fs_last, struct snapraid_file* file, block_off_t file_pos)
- 1088 : {
- 1089 : struct snapraid_chunk* chunk;
- 1090 :
- 1091 : /* check if the last accessed chunk matches */
- 1092 34130326 : if (*fs_last
- 1093 34328656 : && file == (*fs_last)->file
- 1094 22569402 : && file_pos >= (*fs_last)->file_pos
- 1095 22577024 : && file_pos < (*fs_last)->file_pos + (*fs_last)->count
- 1096 : ) {
- 1097 22445049 : chunk = *fs_last;
- 1098 : } else {
- 1099 11685277 : struct chunk_file_inside arg = { file, file_pos };
- 1100 11685277 : chunk = tommy_tree_search_compare(&disk->fs_file, chunk_file_inside_compare, &arg);
- 1101 : }
- 1102 :
- 1103 34258963 : if (!chunk)
- 1104 0 : return 0;
- 1105 :
- 1106 : /* store the last accessed chunk */
- 1107 34258963 : *fs_last = chunk;
- 1108 :
- 1109 34258963 : return chunk;
- 1110 : }
- 1111 :
- 1112 62727960 : struct snapraid_file* fs_par2file_get_ts(struct snapraid_disk* disk, struct snapraid_chunk** fs_last, block_off_t parity_pos, block_off_t* file_pos)
- 1113 : {
- 1114 : struct snapraid_chunk* chunk;
- 1115 :
- 1116 62727960 : chunk = fs_par2chunk_get_ts(disk, fs_last, parity_pos);
- 1117 62761969 : if (!chunk)
- 1118 2353128 : return 0;
- 1119 :
- 1120 60408841 : if (file_pos)
- 1121 59975482 : *file_pos = chunk->file_pos + (parity_pos - chunk->parity_pos);
- 1122 :
- 1123 60408841 : return chunk->file;
- 1124 : }
- 1125 :
- 1126 28966119 : block_off_t fs_file2par_get_ts(struct snapraid_disk* disk, struct snapraid_chunk** fs_last, struct snapraid_file* file, block_off_t file_pos)
- 1127 : {
- 1128 : struct snapraid_chunk* chunk;
- 1129 :
- 1130 28966119 : chunk = fs_file2chunk_get_ts(disk, fs_last, file, file_pos);
- 1131 28884994 : if (!chunk) {
- 1132 : /* LCOV_EXCL_START */
- 1133 : log_fatal("Internal inconsistency when resolving file '%s' at position '%u' in disk '%s'\n", file->sub, file_pos, disk->name);
- 1134 : exit(EXIT_FAILURE);
- 1135 : /* LCOV_EXCL_STOP */
- 1136 : }
- 1137 :
- 1138 28884994 : return chunk->parity_pos + (file_pos - chunk->file_pos);
- 1139 : }
- 1140 :
- 1141 8850076 : void fs_allocate(struct snapraid_disk* disk, block_off_t parity_pos, struct snapraid_file* file, block_off_t file_pos)
- 1142 : {
- 1143 : struct snapraid_chunk* chunk;
- 1144 : struct snapraid_chunk* parity_chunk;
- 1145 : struct snapraid_chunk* file_chunk;
+ 1050 211700412 : if (arg_a->parity_pos < arg_b->parity_pos)
+ 1051 78963776 : return -1;
+ 1052 132736636 : if (arg_a->parity_pos >= arg_b->parity_pos + arg_b->count)
+ 1053 115362811 : return 1;
+ 1054 :
+ 1055 17373825 : return 0;
+ 1056 : }
+ 1057 :
+ 1058 : /**
+ 1059 : * Seach the chunk at the specified parity position.
+ 1060 : * The search is optimized for sequential accesses.
+ 1061 : * \return If not found return 0
+ 1062 : */
+ 1063 62562730 : static struct snapraid_chunk* fs_par2chunk_get_ts(struct snapraid_disk* disk, struct snapraid_chunk** fs_last, block_off_t parity_pos)
+ 1064 : {
+ 1065 : struct snapraid_chunk* chunk;
+ 1066 :
+ 1067 : /* check if the last accessed chunk matches */
+ 1068 62562730 : if (*fs_last
+ 1069 62828537 : && parity_pos >= (*fs_last)->parity_pos
+ 1070 62678201 : && parity_pos < (*fs_last)->parity_pos + (*fs_last)->count
+ 1071 : ) {
+ 1072 43113171 : chunk = *fs_last;
+ 1073 : } else {
+ 1074 19449559 : struct chunk_parity_inside arg = { parity_pos };
+ 1075 19449559 : chunk = tommy_tree_search_compare(&disk->fs_parity, chunk_parity_inside_compare, &arg);
+ 1076 : }
+ 1077 :
+ 1078 62800800 : if (!chunk)
+ 1079 2351363 : return 0;
+ 1080 :
+ 1081 : /* store the last accessed chunk */
+ 1082 60449437 : *fs_last = chunk;
+ 1083 :
+ 1084 60449437 : return chunk;
+ 1085 : }
+ 1086 :
+ 1087 : struct chunk_file_inside {
+ 1088 : struct snapraid_file* file;
+ 1089 : block_off_t file_pos;
+ 1090 : };
+ 1091 :
+ 1092 : /**
+ 1093 : * Compare the chunk if containing the specified file position.
+ 1094 : */
+ 1095 123424429 : static int chunk_file_inside_compare(const void* void_a, const void* void_b)
+ 1096 : {
+ 1097 123424429 : const struct chunk_file_inside* arg_a = void_a;
+ 1098 123424429 : const struct snapraid_chunk* arg_b = void_b;
+ 1099 :
+ 1100 123424429 : if (arg_a->file < arg_b->file)
+ 1101 52876931 : return -1;
+ 1102 70547498 : if (arg_a->file > arg_b->file)
+ 1103 58630297 : return 1;
+ 1104 :
+ 1105 11917201 : if (arg_a->file_pos < arg_b->file_pos)
+ 1106 49120 : return -1;
+ 1107 11868081 : if (arg_a->file_pos >= arg_b->file_pos + arg_b->count)
+ 1108 44006 : return 1;
+ 1109 :
+ 1110 11824075 : return 0;
+ 1111 : }
+ 1112 :
+ 1113 : /**
+ 1114 : * Seach the chunk at the specified file position.
+ 1115 : * The search is optimized for sequential accesses.
+ 1116 : * \return If not found return 0
+ 1117 : */
+ 1118 34157182 : static struct snapraid_chunk* fs_file2chunk_get_ts(struct snapraid_disk* disk, struct snapraid_chunk** fs_last, struct snapraid_file* file, block_off_t file_pos)
+ 1119 : {
+ 1120 : struct snapraid_chunk* chunk;
+ 1121 :
+ 1122 : /* check if the last accessed chunk matches */
+ 1123 34157182 : if (*fs_last
+ 1124 34107260 : && file == (*fs_last)->file
+ 1125 22496891 : && file_pos >= (*fs_last)->file_pos
+ 1126 22481340 : && file_pos < (*fs_last)->file_pos + (*fs_last)->count
+ 1127 : ) {
+ 1128 22376150 : chunk = *fs_last;
+ 1129 : } else {
+ 1130 11781032 : struct chunk_file_inside arg = { file, file_pos };
+ 1131 11781032 : chunk = tommy_tree_search_compare(&disk->fs_file, chunk_file_inside_compare, &arg);
+ 1132 : }
+ 1133 :
+ 1134 34132437 : if (!chunk)
+ 1135 0 : return 0;
+ 1136 :
+ 1137 : /* store the last accessed chunk */
+ 1138 34132437 : *fs_last = chunk;
+ 1139 :
+ 1140 34132437 : return chunk;
+ 1141 : }
+ 1142 :
+ 1143 62671366 : struct snapraid_file* fs_par2file_get_ts(struct snapraid_disk* disk, struct snapraid_chunk** fs_last, block_off_t parity_pos, block_off_t* file_pos)
+ 1144 : {
+ 1145 : struct snapraid_chunk* chunk;
1146 :
- 1147 8850076 : if (file_pos > 0) {
- 1148 : /* search an existing chunk for the previous file_pos */
- 1149 5267929 : chunk = fs_file2chunk_get_ts(disk, &disk->fs_last, file, file_pos - 1);
+ 1147 62671366 : chunk = fs_par2chunk_get_ts(disk, fs_last, parity_pos);
+ 1148 62750330 : if (!chunk)
+ 1149 2351221 : return 0;
1150 :
- 1151 5267929 : if (chunk != 0 && parity_pos == chunk->parity_pos + chunk->count) {
- 1152 : /* ensure that we are extending the chunk at the end */
- 1153 5242274 : if (file_pos != chunk->file_pos + chunk->count) {
- 1154 : /* LCOV_EXCL_START */
- 1155 : log_fatal("Internal inconsistency when allocating file '%s' at position '%u' in the middle of chunk '%u:%u' in disk '%s'\n", file->sub, file_pos, chunk->file_pos, chunk->count, disk->name);
- 1156 : exit(EXIT_FAILURE);
- 1157 : /* LCOV_EXCL_STOP */
- 1158 : }
- 1159 :
- 1160 : /* extend the existing chunk */
- 1161 5242274 : ++chunk->count;
- 1162 :
- 1163 14092350 : return;
- 1164 : }
- 1165 : }
- 1166 :
- 1167 : /* a chunk doesn't exist, and we have to create a new one */
- 1168 3607802 : chunk = chunk_alloc(parity_pos, file, file_pos, 1);
- 1169 :
- 1170 : /* insert the chunk in the trees */
- 1171 3607802 : parity_chunk = tommy_tree_insert(&disk->fs_parity, &chunk->parity_node, chunk);
- 1172 3607802 : file_chunk = tommy_tree_insert(&disk->fs_file, &chunk->file_node, chunk);
- 1173 :
- 1174 3607802 : if (parity_chunk != chunk || file_chunk != chunk) {
- 1175 : /* LCOV_EXCL_START */
- 1176 : log_fatal("Internal inconsistency when allocating file '%s' at position '%u' for existing chunk '%u:%u' in disk '%s'\n", file->sub, file_pos, chunk->file_pos, chunk->count, disk->name);
- 1177 : exit(EXIT_FAILURE);
- 1178 : /* LCOV_EXCL_STOP */
- 1179 : }
- 1180 :
- 1181 : /* store the last accessed chunk */
- 1182 3607802 : disk->fs_last = chunk;
- 1183 : }
- 1184 :
- 1185 104031 : void fs_deallocate(struct snapraid_disk* disk, block_off_t parity_pos)
- 1186 : {
- 1187 : struct snapraid_chunk* chunk;
- 1188 : struct snapraid_chunk* second_chunk;
- 1189 : struct snapraid_chunk* parity_chunk;
- 1190 : struct snapraid_chunk* file_chunk;
- 1191 : block_off_t first_count, second_count;
- 1192 :
- 1193 104031 : chunk = fs_par2chunk_get_ts(disk, &disk->fs_last, parity_pos);
- 1194 104031 : if (!chunk) {
- 1195 : /* LCOV_EXCL_START */
- 1196 : log_fatal("Internal inconsistency when deallocating parity position '%u' for not existing chunk in disk '%s'\n", parity_pos, disk->name);
- 1197 : exit(EXIT_FAILURE);
- 1198 : /* LCOV_EXCL_STOP */
- 1199 : }
+ 1151 60399109 : if (file_pos)
+ 1152 59839728 : *file_pos = chunk->file_pos + (parity_pos - chunk->parity_pos);
+ 1153 :
+ 1154 60399109 : return chunk->file;
+ 1155 : }
+ 1156 :
+ 1157 28740730 : block_off_t fs_file2par_get_ts(struct snapraid_disk* disk, struct snapraid_chunk** fs_last, struct snapraid_file* file, block_off_t file_pos)
+ 1158 : {
+ 1159 : struct snapraid_chunk* chunk;
+ 1160 :
+ 1161 28740730 : chunk = fs_file2chunk_get_ts(disk, fs_last, file, file_pos);
+ 1162 28850478 : if (!chunk) {
+ 1163 : /* LCOV_EXCL_START */
+ 1164 : log_fatal("Internal inconsistency when resolving file '%s' at position '%u/%u' in disk '%s'\n", file->sub, file_pos, file->blockmax, disk->name);
+ 1165 : exit(EXIT_FAILURE);
+ 1166 : /* LCOV_EXCL_STOP */
+ 1167 : }
+ 1168 :
+ 1169 28850478 : return chunk->parity_pos + (file_pos - chunk->file_pos);
+ 1170 : }
+ 1171 :
+ 1172 8849850 : void fs_allocate(struct snapraid_disk* disk, block_off_t parity_pos, struct snapraid_file* file, block_off_t file_pos)
+ 1173 : {
+ 1174 : struct snapraid_chunk* chunk;
+ 1175 : struct snapraid_chunk* parity_chunk;
+ 1176 : struct snapraid_chunk* file_chunk;
+ 1177 :
+ 1178 8849850 : if (file_pos > 0) {
+ 1179 : /* search an existing chunk for the previous file_pos */
+ 1180 5267799 : chunk = fs_file2chunk_get_ts(disk, &disk->fs_last, file, file_pos - 1);
+ 1181 :
+ 1182 5267799 : if (chunk != 0 && parity_pos == chunk->parity_pos + chunk->count) {
+ 1183 : /* ensure that we are extending the chunk at the end */
+ 1184 5242090 : if (file_pos != chunk->file_pos + chunk->count) {
+ 1185 : /* LCOV_EXCL_START */
+ 1186 : log_fatal("Internal inconsistency when allocating file '%s' at position '%u/%u' in the middle of chunk '%u:%u' in disk '%s'\n", file->sub, file_pos, file->blockmax, chunk->file_pos, chunk->count, disk->name);
+ 1187 : exit(EXIT_FAILURE);
+ 1188 : /* LCOV_EXCL_STOP */
+ 1189 : }
+ 1190 :
+ 1191 : /* extend the existing chunk */
+ 1192 5242090 : ++chunk->count;
+ 1193 :
+ 1194 14091940 : return;
+ 1195 : }
+ 1196 : }
+ 1197 :
+ 1198 : /* a chunk doesn't exist, and we have to create a new one */
+ 1199 3607760 : chunk = chunk_alloc(parity_pos, file, file_pos, 1);
1200 :
- 1201 : /* if it's the only block of the chunk, delete it */
- 1202 104031 : if (chunk->count == 1) {
- 1203 : /* remove from the trees */
- 1204 38796 : tommy_tree_remove(&disk->fs_parity, chunk);
- 1205 38796 : tommy_tree_remove(&disk->fs_file, chunk);
- 1206 :
- 1207 : /* deallocate */
- 1208 38796 : chunk_free(chunk);
- 1209 :
- 1210 : /* clear the last accessed chunk */
- 1211 38796 : disk->fs_last = 0;
- 1212 38796 : return;
- 1213 : }
- 1214 :
- 1215 : /* if it's at the start of the chunk, shrink the chunk */
- 1216 65235 : if (parity_pos == chunk->parity_pos) {
- 1217 65233 : ++chunk->parity_pos;
- 1218 65233 : ++chunk->file_pos;
- 1219 65233 : --chunk->count;
- 1220 65233 : return;
- 1221 : }
- 1222 :
- 1223 : /* if it's at the end of the chunk, shrink the chunk */
- 1224 2 : if (parity_pos == chunk->parity_pos + chunk->count - 1) {
- 1225 1 : --chunk->count;
- 1226 1 : return;
- 1227 : }
- 1228 :
- 1229 : /* otherwise it's in the middle */
- 1230 1 : first_count = parity_pos - chunk->parity_pos;
- 1231 1 : second_count = chunk->count - first_count - 1;
- 1232 :
- 1233 : /* adjust the first chunk */
- 1234 1 : chunk->count = first_count;
- 1235 :
- 1236 : /* allocate the second chunk */
- 1237 1 : second_chunk = chunk_alloc(chunk->parity_pos + first_count + 1, chunk->file, chunk->file_pos + first_count + 1, second_count);
- 1238 :
- 1239 : /* insert the chunk in the trees */
- 1240 1 : parity_chunk = tommy_tree_insert(&disk->fs_parity, &second_chunk->parity_node, second_chunk);
- 1241 1 : file_chunk = tommy_tree_insert(&disk->fs_file, &second_chunk->file_node, second_chunk);
- 1242 :
- 1243 1 : if (parity_chunk != second_chunk || file_chunk != second_chunk) {
- 1244 : /* LCOV_EXCL_START */
- 1245 : log_fatal("Internal inconsistency when deallocating parity position '%u' for splitting chunk '%u:%u' in disk '%s'\n", parity_pos, second_chunk->file_pos, second_chunk->count, disk->name);
- 1246 : exit(EXIT_FAILURE);
- 1247 : /* LCOV_EXCL_STOP */
- 1248 : }
- 1249 :
- 1250 : /* store the last accessed chunk */
- 1251 1 : disk->fs_last = second_chunk;
- 1252 : }
+ 1201 : /* insert the chunk in the trees */
+ 1202 3607760 : parity_chunk = tommy_tree_insert(&disk->fs_parity, &chunk->parity_node, chunk);
+ 1203 3607760 : file_chunk = tommy_tree_insert(&disk->fs_file, &chunk->file_node, chunk);
+ 1204 :
+ 1205 3607760 : if (parity_chunk != chunk || file_chunk != chunk) {
+ 1206 : /* LCOV_EXCL_START */
+ 1207 : log_fatal("Internal inconsistency when allocating file '%s' at position '%u/%u' for existing chunk '%u:%u' in disk '%s'\n", file->sub, file_pos, file->blockmax, chunk->file_pos, chunk->count, disk->name);
+ 1208 : exit(EXIT_FAILURE);
+ 1209 : /* LCOV_EXCL_STOP */
+ 1210 : }
+ 1211 :
+ 1212 : /* store the last accessed chunk */
+ 1213 3607760 : disk->fs_last = chunk;
+ 1214 : }
+ 1215 :
+ 1216 104155 : void fs_deallocate(struct snapraid_disk* disk, block_off_t parity_pos)
+ 1217 : {
+ 1218 : struct snapraid_chunk* chunk;
+ 1219 : struct snapraid_chunk* second_chunk;
+ 1220 : struct snapraid_chunk* parity_chunk;
+ 1221 : struct snapraid_chunk* file_chunk;
+ 1222 : block_off_t first_count, second_count;
+ 1223 :
+ 1224 104155 : chunk = fs_par2chunk_get_ts(disk, &disk->fs_last, parity_pos);
+ 1225 104155 : if (!chunk) {
+ 1226 : /* LCOV_EXCL_START */
+ 1227 : log_fatal("Internal inconsistency when deallocating parity position '%u' for not existing chunk in disk '%s'\n", parity_pos, disk->name);
+ 1228 : exit(EXIT_FAILURE);
+ 1229 : /* LCOV_EXCL_STOP */
+ 1230 : }
+ 1231 :
+ 1232 : /* if it's the only block of the chunk, delete it */
+ 1233 104155 : if (chunk->count == 1) {
+ 1234 : /* remove from the trees */
+ 1235 38837 : tommy_tree_remove(&disk->fs_parity, chunk);
+ 1236 38837 : tommy_tree_remove(&disk->fs_file, chunk);
+ 1237 :
+ 1238 : /* deallocate */
+ 1239 38837 : chunk_free(chunk);
+ 1240 :
+ 1241 : /* clear the last accessed chunk */
+ 1242 38837 : disk->fs_last = 0;
+ 1243 38837 : return;
+ 1244 : }
+ 1245 :
+ 1246 : /* if it's at the start of the chunk, shrink the chunk */
+ 1247 65318 : if (parity_pos == chunk->parity_pos) {
+ 1248 65316 : ++chunk->parity_pos;
+ 1249 65316 : ++chunk->file_pos;
+ 1250 65316 : --chunk->count;
+ 1251 65316 : return;
+ 1252 : }
1253 :
- 1254 51081912 : struct snapraid_block* fs_par2block_get_ts(struct snapraid_disk* disk, struct snapraid_chunk** fs_last, block_off_t parity_pos)
- 1255 : {
- 1256 : struct snapraid_file* file;
- 1257 : block_off_t file_pos;
- 1258 :
- 1259 51081912 : file = fs_par2file_get_ts(disk, fs_last, parity_pos, &file_pos);
- 1260 :
- 1261 51089852 : if (!file)
- 1262 2353186 : return BLOCK_EMPTY;
+ 1254 : /* if it's at the end of the chunk, shrink the chunk */
+ 1255 2 : if (parity_pos == chunk->parity_pos + chunk->count - 1) {
+ 1256 1 : --chunk->count;
+ 1257 1 : return;
+ 1258 : }
+ 1259 :
+ 1260 : /* otherwise it's in the middle */
+ 1261 1 : first_count = parity_pos - chunk->parity_pos;
+ 1262 1 : second_count = chunk->count - first_count - 1;
1263 :
- 1264 48736666 : return fs_file2block_get(file, file_pos);
- 1265 : }
+ 1264 : /* adjust the first chunk */
+ 1265 1 : chunk->count = first_count;
1266 :
- 1267 1447 : struct snapraid_map* map_alloc(const char* name, unsigned position, block_off_t total_blocks, block_off_t free_blocks, const char* uuid)
- 1268 : {
- 1269 : struct snapraid_map* map;
- 1270 :
- 1271 1447 : map = malloc_nofail(sizeof(struct snapraid_map));
- 1272 1447 : pathcpy(map->name, sizeof(map->name), name);
- 1273 1447 : map->position = position;
- 1274 1447 : map->total_blocks = total_blocks;
- 1275 1447 : map->free_blocks = free_blocks;
- 1276 1447 : pathcpy(map->uuid, sizeof(map->uuid), uuid);
- 1277 :
- 1278 1447 : return map;
- 1279 : }
+ 1267 : /* allocate the second chunk */
+ 1268 1 : second_chunk = chunk_alloc(chunk->parity_pos + first_count + 1, chunk->file, chunk->file_pos + first_count + 1, second_count);
+ 1269 :
+ 1270 : /* insert the chunk in the trees */
+ 1271 1 : parity_chunk = tommy_tree_insert(&disk->fs_parity, &second_chunk->parity_node, second_chunk);
+ 1272 1 : file_chunk = tommy_tree_insert(&disk->fs_file, &second_chunk->file_node, second_chunk);
+ 1273 :
+ 1274 1 : if (parity_chunk != second_chunk || file_chunk != second_chunk) {
+ 1275 : /* LCOV_EXCL_START */
+ 1276 : log_fatal("Internal inconsistency when deallocating parity position '%u' for splitting chunk '%u:%u' in disk '%s'\n", parity_pos, second_chunk->file_pos, second_chunk->count, disk->name);
+ 1277 : exit(EXIT_FAILURE);
+ 1278 : /* LCOV_EXCL_STOP */
+ 1279 : }
1280 :
- 1281 1327 : void map_free(struct snapraid_map* map)
- 1282 : {
- 1283 1327 : free(map);
- 1284 1327 : }
- 1285 :
- 1286 713560 : int time_compare(const void* void_a, const void* void_b)
- 1287 : {
- 1288 713560 : const time_t* time_a = void_a;
- 1289 713560 : const time_t* time_b = void_b;
- 1290 :
- 1291 713560 : if (*time_a < *time_b)
- 1292 26114 : return -1;
- 1293 687446 : if (*time_a > *time_b)
- 1294 154206 : return 1;
- 1295 533240 : return 0;
- 1296 : }
+ 1281 : /* store the last accessed chunk */
+ 1282 1 : disk->fs_last = second_chunk;
+ 1283 : }
+ 1284 :
+ 1285 112904165 : struct snapraid_block* fs_file2block_get(struct snapraid_file* file, block_off_t file_pos)
+ 1286 : {
+ 1287 112904165 : if (file_pos >= file->blockmax) {
+ 1288 : /* LCOV_EXCL_START */
+ 1289 : log_fatal("Internal inconsistency when dereferencing file '%s' at position '%u/%u'\n", file->sub, file_pos, file->blockmax);
+ 1290 : exit(EXIT_FAILURE);
+ 1291 : /* LCOV_EXCL_STOP */
+ 1292 : }
+ 1293 :
+ 1294 112904165 : return &file->blockvec[file_pos];
+ 1295 : }
+ 1296 :
+ 1297 51148943 : struct snapraid_block* fs_par2block_get_ts(struct snapraid_disk* disk, struct snapraid_chunk** fs_last, block_off_t parity_pos)
+ 1298 : {
+ 1299 : struct snapraid_file* file;
+ 1300 : block_off_t file_pos;
+ 1301 :
+ 1302 51148943 : file = fs_par2file_get_ts(disk, fs_last, parity_pos, &file_pos);
+ 1303 :
+ 1304 51044271 : if (!file)
+ 1305 2337947 : return BLOCK_EMPTY;
+ 1306 :
+ 1307 48706324 : return fs_file2block_get(file, file_pos);
+ 1308 : }
+ 1309 :
+ 1310 1447 : struct snapraid_map* map_alloc(const char* name, unsigned position, block_off_t total_blocks, block_off_t free_blocks, const char* uuid)
+ 1311 : {
+ 1312 : struct snapraid_map* map;
+ 1313 :
+ 1314 1447 : map = malloc_nofail(sizeof(struct snapraid_map));
+ 1315 1447 : pathcpy(map->name, sizeof(map->name), name);
+ 1316 1447 : map->position = position;
+ 1317 1447 : map->total_blocks = total_blocks;
+ 1318 1447 : map->free_blocks = free_blocks;
+ 1319 1447 : pathcpy(map->uuid, sizeof(map->uuid), uuid);
+ 1320 :
+ 1321 1447 : return map;
+ 1322 : }
+ 1323 :
+ 1324 1327 : void map_free(struct snapraid_map* map)
+ 1325 : {
+ 1326 1327 : free(map);
+ 1327 1327 : }
+ 1328 :
+ 1329 743492 : int time_compare(const void* void_a, const void* void_b)
+ 1330 : {
+ 1331 743492 : const time_t* time_a = void_a;
+ 1332 743492 : const time_t* time_b = void_b;
+ 1333 :
+ 1334 743492 : if (*time_a < *time_b)
+ 1335 28996 : return -1;
+ 1336 714496 : if (*time_a > *time_b)
+ 1337 185655 : return 1;
+ 1338 528841 : return 0;
+ 1339 : }
diff --git a/cov/cmdline/elem.h.func-sort-c.html b/cov/cmdline/elem.h.func-sort-c.html
index cf4a43a7..2a9ac818 100644
--- a/cov/cmdline/elem.h.func-sort-c.html
+++ b/cov/cmdline/elem.h.func-sort-c.html
@@ -31,17 +31,17 @@
|
-
-
-
+
+
+
-
+
|
-
-
+
+
 |
@@ -59,117 +59,113 @@
Function Name  |
Hit count  |
-
- | fs_file2block_get |
- 114670866 |
-
| block_state_get |
- 96508438 |
+ 96735410 |
| file_flag_has |
- 33299349 |
+ 33299459 |
- | fs_par2block_get |
- 21725563 |
+ fs_par2block_get |
+ 21727310 |
| block_state_set |
- 18241681 |
+ 18242161 |
| block_has_file |
- 12928240 |
+ 12929086 |
- | fs_par2file_get |
- 11513278 |
+ fs_par2file_get |
+ 11514087 |
| block_has_invalid_parity |
- 11488433 |
+ 11489174 |
- | info_get |
- 10527480 |
+ info_get |
+ 10573034 |
| hash_invalid_set |
- 8911064 |
+ 8910831 |
| file_stamp_hash |
- 6139195 |
+ 6139138 |
| file_flag_set |
- 5178039 |
+ 5176917 |
| file_inode_hash |
- 4822885 |
+ 4822298 |
| file_path_hash |
- 3766477 |
+ 3766623 |
- | info_get_rehash |
- 3293767 |
+ info_get_rehash |
+ 3312725 |
| filter_hidden |
- 3066757 |
+ 3066852 |
| block_has_past_hash |
- 2287716 |
+ 2287366 |
- | info_get_time |
- 2241006 |
+ info_get_time |
+ 2258078 |
| block_has_updated_hash |
- 2004868 |
+ 2005171 |
- | info_get_bad |
- 1705083 |
+ info_get_bad |
+ 1725704 |
- | info_set |
- 1609362 |
+ info_set |
+ 1609485 |
- | info_get_justsynced |
- 1455572 |
+ info_get_justsynced |
+ 1474627 |
| hash_is_zero |
- 790624 |
+ 790275 |
| hash_is_invalid |
- 776390 |
+ 776042 |
- | fs_file2par_get |
- 602426 |
+ fs_file2par_get |
+ 464306 |
| link_flag_get |
- 410823 |
+ 410820 |
- | info_make |
- 390916 |
+ info_make |
+ 394996 |
| block_has_file_and_valid_parity |
- 221103 |
+ 221100 |
| link_flag_has |
@@ -185,7 +181,7 @@
| hash_is_real |
- 65665 |
+ 65785 |
| link_flag_set |
@@ -193,15 +189,15 @@
| file_flag_clear |
- 14861 |
+ 14174 |
- | info_set_rehash |
+ info_set_rehash |
9199 |
- | info_set_bad |
- 1803 |
+ info_set_bad |
+ 1802 |
| dir_name_hash |
diff --git a/cov/cmdline/elem.h.func.html b/cov/cmdline/elem.h.func.html
index 43a320f0..8e76d216 100644
--- a/cov/cmdline/elem.h.func.html
+++ b/cov/cmdline/elem.h.func.html
@@ -31,17 +31,17 @@
|
-
-
-
+
+
+
-
+
|
-
-
+
+
 |
@@ -61,31 +61,31 @@
| block_has_file |
- 12928240 |
+ 12929086 |
| block_has_file_and_valid_parity |
- 221103 |
+ 221100 |
| block_has_invalid_parity |
- 11488433 |
+ 11489174 |
| block_has_past_hash |
- 2287716 |
+ 2287366 |
| block_has_updated_hash |
- 2004868 |
+ 2005171 |
| block_state_get |
- 96508438 |
+ 96735410 |
| block_state_set |
- 18241681 |
+ 18242161 |
| dir_flag_has |
@@ -101,107 +101,103 @@
| file_flag_clear |
- 14861 |
+ 14174 |
| file_flag_has |
- 33299349 |
+ 33299459 |
| file_flag_set |
- 5178039 |
+ 5176917 |
| file_inode_hash |
- 4822885 |
+ 4822298 |
| file_path_hash |
- 3766477 |
+ 3766623 |
| file_stamp_hash |
- 6139195 |
+ 6139138 |
| filter_hidden |
- 3066757 |
+ 3066852 |
- | fs_file2block_get |
- 114670866 |
+ fs_file2par_get |
+ 464306 |
- | fs_file2par_get |
- 602426 |
+ fs_par2block_get |
+ 21727310 |
- | fs_par2block_get |
- 21725563 |
-
-
- | fs_par2file_get |
- 11513278 |
+ fs_par2file_get |
+ 11514087 |
| hash_invalid_set |
- 8911064 |
+ 8910831 |
| hash_is_invalid |
- 776390 |
+ 776042 |
| hash_is_real |
- 65665 |
+ 65785 |
| hash_is_zero |
- 790624 |
+ 790275 |
| hash_zero_set |
153288 |
- | info_get |
- 10527480 |
+ info_get |
+ 10573034 |
- | info_get_bad |
- 1705083 |
+ info_get_bad |
+ 1725704 |
- | info_get_justsynced |
- 1455572 |
+ info_get_justsynced |
+ 1474627 |
- | info_get_rehash |
- 3293767 |
+ info_get_rehash |
+ 3312725 |
- | info_get_time |
- 2241006 |
+ info_get_time |
+ 2258078 |
- | info_make |
- 390916 |
+ info_make |
+ 394996 |
- | info_set |
- 1609362 |
+ info_set |
+ 1609485 |
- | info_set_bad |
- 1803 |
+ info_set_bad |
+ 1802 |
- | info_set_rehash |
+ info_set_rehash |
9199 |
| link_flag_get |
- 410823 |
+ 410820 |
| link_flag_has |
diff --git a/cov/cmdline/elem.h.gcov.html b/cov/cmdline/elem.h.gcov.html
index e75a6eee..c8f25c02 100644
--- a/cov/cmdline/elem.h.gcov.html
+++ b/cov/cmdline/elem.h.gcov.html
@@ -31,17 +31,17 @@
|
-
-
-
+
+
+
-
+
|
-
-
+
+
 |
@@ -517,13 +517,13 @@
455 : * Filter hidden files.
456 : * Return !=0 if it matches and it should be excluded.
457 : */
- 458 3066757 : static inline int filter_hidden(int enable, struct dirent* dd)
+ 458 3066852 : static inline int filter_hidden(int enable, struct dirent* dd)
459 : {
- 460 3066757 : if (enable && dirent_hidden(dd)) {
+ 460 3066852 : if (enable && dirent_hidden(dd)) {
461 0 : return 1; /* filter out */
462 : }
463 :
- 464 3066757 : return 0;
+ 464 3066852 : return 0;
465 : }
466 :
467 : /**
@@ -564,13 +564,13 @@
502 : *
503 : * An invalid hash is represented with all bytes at 0x00.
504 : */
- 505 776390 : static inline int hash_is_invalid(const unsigned char* hash)
+ 505 776042 : static inline int hash_is_invalid(const unsigned char* hash)
506 : {
507 : unsigned i;
508 :
- 509 1265344 : for (i = 0; i < HASH_SIZE; ++i)
- 510 1234968 : if (hash[i] != 0x00)
- 511 746014 : return 0;
+ 509 1264688 : for (i = 0; i < HASH_SIZE; ++i)
+ 510 1234312 : if (hash[i] != 0x00)
+ 511 745666 : return 0;
512 :
513 30376 : return 1;
514 : }
@@ -580,13 +580,13 @@
518 : *
519 : * A zero hash is represented with all bytes at 0xFF.
520 : */
- 521 790624 : static inline int hash_is_zero(const unsigned char* hash)
+ 521 790275 : static inline int hash_is_zero(const unsigned char* hash)
522 : {
523 : unsigned i;
524 :
- 525 1835995 : for (i = 0; i < HASH_SIZE; ++i)
- 526 1770815 : if (hash[i] != 0xFF)
- 527 725444 : return 0;
+ 525 1835799 : for (i = 0; i < HASH_SIZE; ++i)
+ 526 1770619 : if (hash[i] != 0xFF)
+ 527 725095 : return 0;
528 :
529 65180 : return 1;
530 : }
@@ -594,18 +594,18 @@
532 : /**
533 : * Check if the specified hash is a real hash.
534 : */
- 535 65665 : static inline int hash_is_real(const unsigned char* hash)
+ 535 65785 : static inline int hash_is_real(const unsigned char* hash)
536 : {
- 537 65665 : return !hash_is_zero(hash) && !hash_is_invalid(hash);
+ 537 65785 : return !hash_is_zero(hash) && !hash_is_invalid(hash);
538 : }
539 :
540 : /**
541 : * Set the hash to the special INVALID value.
542 : */
- 543 8911064 : static inline void hash_invalid_set(unsigned char* hash)
+ 543 8910831 : static inline void hash_invalid_set(unsigned char* hash)
544 : {
- 545 8911064 : memset(hash, 0x00, HASH_SIZE);
- 546 8911064 : }
+ 545 8910831 : memset(hash, 0x00, HASH_SIZE);
+ 546 8910831 : }
547 :
548 : /**
549 : * Set the hash to the special ZERO value.
@@ -621,32 +621,32 @@
559 : * For this function, it's allowed to pass a NULL block
560 : * pointer than results in the BLOCK_STATE_EMPTY state.
561 : */
- 562 96508438 : static inline unsigned block_state_get(const struct snapraid_block* block)
+ 562 96735410 : static inline unsigned block_state_get(const struct snapraid_block* block)
563 : {
- 564 96508438 : if (block == BLOCK_EMPTY)
- 565 2429041 : return BLOCK_STATE_EMPTY;
+ 564 96735410 : if (block == BLOCK_EMPTY)
+ 565 2427201 : return BLOCK_STATE_EMPTY;
566 :
- 567 94079397 : return block->state;
+ 567 94308209 : return block->state;
568 : }
569 :
570 : /**
571 : * Set the state of the block.
572 : */
- 573 18241681 : static inline void block_state_set(struct snapraid_block* block, unsigned state)
+ 573 18242161 : static inline void block_state_set(struct snapraid_block* block, unsigned state)
574 : {
- 575 18241681 : block->state = state;
- 576 18241681 : }
+ 575 18242161 : block->state = state;
+ 576 18242161 : }
577 :
578 : /**
579 : * Check if the specified block has an updated hash.
580 : *
581 : * Note that EMPTY / CHG / DELETED return 0.
582 : */
- 583 2004868 : static inline int block_has_updated_hash(const struct snapraid_block* block)
+ 583 2005171 : static inline int block_has_updated_hash(const struct snapraid_block* block)
584 : {
- 585 2004868 : unsigned state = block_state_get(block);
+ 585 2005171 : unsigned state = block_state_get(block);
586 :
- 587 2004868 : return state == BLOCK_STATE_BLK || state == BLOCK_STATE_REP;
+ 587 2005171 : return state == BLOCK_STATE_BLK || state == BLOCK_STATE_REP;
588 : }
589 :
590 : /**
@@ -655,11 +655,11 @@
593 : *
594 : * Note that EMPTY / BLK / REP return 0.
595 : */
- 596 2287716 : static inline int block_has_past_hash(const struct snapraid_block* block)
+ 596 2287366 : static inline int block_has_past_hash(const struct snapraid_block* block)
597 : {
- 598 2287716 : unsigned state = block_state_get(block);
+ 598 2287366 : unsigned state = block_state_get(block);
599 :
- 600 2287716 : return state == BLOCK_STATE_CHG || state == BLOCK_STATE_DELETED;
+ 600 2287366 : return state == BLOCK_STATE_CHG || state == BLOCK_STATE_DELETED;
601 : }
602 :
603 : /**
@@ -667,12 +667,12 @@
605 : *
606 : * Note that EMPTY / DELETED return 0.
607 : */
- 608 12928240 : static inline int block_has_file(const struct snapraid_block* block)
+ 608 12929086 : static inline int block_has_file(const struct snapraid_block* block)
609 : {
- 610 12928240 : unsigned state = block_state_get(block);
+ 610 12929086 : unsigned state = block_state_get(block);
611 :
- 612 12928240 : return state == BLOCK_STATE_BLK
- 613 12928240 : || state == BLOCK_STATE_CHG || state == BLOCK_STATE_REP;
+ 612 12929086 : return state == BLOCK_STATE_BLK
+ 613 12929086 : || state == BLOCK_STATE_CHG || state == BLOCK_STATE_REP;
614 : }
615 :
616 : /**
@@ -680,12 +680,12 @@
618 : *
619 : * Note that EMPTY / BLK return 0.
620 : */
- 621 11488433 : static inline int block_has_invalid_parity(const struct snapraid_block* block)
+ 621 11489174 : static inline int block_has_invalid_parity(const struct snapraid_block* block)
622 : {
- 623 11488433 : unsigned state = block_state_get(block);
+ 623 11489174 : unsigned state = block_state_get(block);
624 :
- 625 11488433 : return state == BLOCK_STATE_DELETED
- 626 11488433 : || state == BLOCK_STATE_CHG || state == BLOCK_STATE_REP;
+ 625 11489174 : return state == BLOCK_STATE_DELETED
+ 626 11489174 : || state == BLOCK_STATE_CHG || state == BLOCK_STATE_REP;
627 : }
628 :
629 : /**
@@ -693,27 +693,27 @@
631 : *
632 : * Note that anything different than BLK return 0.
633 : */
- 634 221103 : static inline int block_has_file_and_valid_parity(const struct snapraid_block* block)
+ 634 221100 : static inline int block_has_file_and_valid_parity(const struct snapraid_block* block)
635 : {
- 636 221103 : unsigned state = block_state_get(block);
+ 636 221100 : unsigned state = block_state_get(block);
637 :
- 638 221103 : return state == BLOCK_STATE_BLK;
+ 638 221100 : return state == BLOCK_STATE_BLK;
639 : }
640 :
- 641 33299349 : static inline int file_flag_has(const struct snapraid_file* file, unsigned mask)
+ 641 33299459 : static inline int file_flag_has(const struct snapraid_file* file, unsigned mask)
642 : {
- 643 33299349 : return (file->flag & mask) == mask;
+ 643 33299459 : return (file->flag & mask) == mask;
644 : }
645 :
- 646 5178039 : static inline void file_flag_set(struct snapraid_file* file, unsigned mask)
+ 646 5176917 : static inline void file_flag_set(struct snapraid_file* file, unsigned mask)
647 : {
- 648 5178039 : file->flag |= mask;
- 649 5178039 : }
+ 648 5176917 : file->flag |= mask;
+ 649 5176917 : }
650 :
- 651 14861 : static inline void file_flag_clear(struct snapraid_file* file, unsigned mask)
+ 651 14174 : static inline void file_flag_clear(struct snapraid_file* file, unsigned mask)
652 : {
- 653 14861 : file->flag &= ~mask;
- 654 14861 : }
+ 653 14174 : file->flag &= ~mask;
+ 654 14174 : }
655 :
656 : /**
657 : * Allocate a file.
@@ -779,9 +779,9 @@
717 : /**
718 : * Compute the hash of a file inode.
719 : */
- 720 4822885 : static inline tommy_uint32_t file_inode_hash(uint64_t inode)
+ 720 4822298 : static inline tommy_uint32_t file_inode_hash(uint64_t inode)
721 : {
- 722 4822885 : return (tommy_uint32_t)tommy_inthash_u64(inode);
+ 722 4822298 : return (tommy_uint32_t)tommy_inthash_u64(inode);
723 : }
724 :
725 : /**
@@ -800,17 +800,17 @@
738 : /**
739 : * Compute the hash of a file path.
740 : */
- 741 3766477 : static inline tommy_uint32_t file_path_hash(const char* sub)
+ 741 3766623 : static inline tommy_uint32_t file_path_hash(const char* sub)
742 : {
- 743 3766477 : return tommy_hash_u32(0, sub, strlen(sub));
+ 743 3766623 : return tommy_hash_u32(0, sub, strlen(sub));
744 : }
745 :
746 : /**
747 : * Compute the hash of a file stamp.
748 : */
- 749 6139195 : static inline tommy_uint32_t file_stamp_hash(data_off_t size, int64_t mtime_sec, int mtime_nsec)
+ 749 6139138 : static inline tommy_uint32_t file_stamp_hash(data_off_t size, int64_t mtime_sec, int mtime_nsec)
750 : {
- 751 6139195 : return tommy_inthash_u32((tommy_uint32_t)size ^ tommy_inthash_u32(mtime_sec ^ tommy_inthash_u32(mtime_nsec)));
+ 751 6139138 : return tommy_inthash_u32((tommy_uint32_t)size ^ tommy_inthash_u32(mtime_sec ^ tommy_inthash_u32(mtime_nsec)));
752 : }
753 :
754 : /**
@@ -854,9 +854,9 @@
792 6 : slink->flag |= flag & mask;
793 6 : }
794 :
- 795 410823 : static inline unsigned link_flag_get(struct snapraid_link* slink, unsigned mask)
+ 795 410820 : static inline unsigned link_flag_get(struct snapraid_link* slink, unsigned mask)
796 : {
- 797 410823 : return slink->flag & mask;
+ 797 410820 : return slink->flag & mask;
798 : }
799 :
800 : /**
@@ -975,181 +975,176 @@
913 : void fs_deallocate(struct snapraid_disk* disk, block_off_t pos);
914 :
915 : /**
- 916 : * Get the block from the file position.
+ 916 : * Get the block from the file position.
917 : */
- 918 114670866 : static inline struct snapraid_block* fs_file2block_get(struct snapraid_file* file, block_off_t file_pos)
- 919 : {
- 920 114670866 : assert(file_pos < file->blockmax);
- 921 :
- 922 114670866 : return &file->blockvec[file_pos];
- 923 : }
+ 918 : struct snapraid_block* fs_file2block_get(struct snapraid_file* file, block_off_t file_pos);
+ 919 :
+ 920 : /**
+ 921 : * Like fs_file2par_get() but thread-safe.
+ 922 : */
+ 923 : struct snapraid_file* fs_par2file_get_ts(struct snapraid_disk* disk, struct snapraid_chunk** fs_last, block_off_t parity_pos, block_off_t* file_pos);
924 :
925 : /**
- 926 : * Like fs_file2par_get() but thread-safe.
- 927 : */
- 928 : struct snapraid_file* fs_par2file_get_ts(struct snapraid_disk* disk, struct snapraid_chunk** fs_last, block_off_t parity_pos, block_off_t* file_pos);
- 929 :
- 930 : /**
- 931 : * Get the file position from the parity position.
- 932 : * Return 0 if no file is using it.
- 933 : * \note This function is NOT thread-safe as it uses the the disk cache.
- 934 : */
- 935 11513278 : static inline struct snapraid_file* fs_par2file_get(struct snapraid_disk* disk, block_off_t parity_pos, block_off_t* file_pos)
- 936 : {
- 937 11513278 : return fs_par2file_get_ts(disk, &disk->fs_last, parity_pos, file_pos);
- 938 : }
+ 926 : * Get the file position from the parity position.
+ 927 : * Return 0 if no file is using it.
+ 928 : * \note This function is NOT thread-safe as it uses the the disk cache.
+ 929 : */
+ 930 11514087 : static inline struct snapraid_file* fs_par2file_get(struct snapraid_disk* disk, block_off_t parity_pos, block_off_t* file_pos)
+ 931 : {
+ 932 11514087 : return fs_par2file_get_ts(disk, &disk->fs_last, parity_pos, file_pos);
+ 933 : }
+ 934 :
+ 935 : /**
+ 936 : * Like fs_file2par_get() but thread-safe.
+ 937 : */
+ 938 : block_off_t fs_file2par_get_ts(struct snapraid_disk* disk, struct snapraid_chunk** fs_last, struct snapraid_file* file, block_off_t file_pos);
939 :
940 : /**
- 941 : * Like fs_file2par_get() but thread-safe.
- 942 : */
- 943 : block_off_t fs_file2par_get_ts(struct snapraid_disk* disk, struct snapraid_chunk** fs_last, struct snapraid_file* file, block_off_t file_pos);
- 944 :
- 945 : /**
- 946 : * Get the parity position from the file position.
- 947 : * \note This function is NOT thread-safe as it uses the the disk cache.
- 948 : */
- 949 602426 : static inline block_off_t fs_file2par_get(struct snapraid_disk* disk, struct snapraid_file* file, block_off_t file_pos)
- 950 : {
- 951 602426 : return fs_file2par_get_ts(disk, &disk->fs_last, file, file_pos);
- 952 : }
+ 941 : * Get the parity position from the file position.
+ 942 : * \note This function is NOT thread-safe as it uses the the disk cache.
+ 943 : */
+ 944 464306 : static inline block_off_t fs_file2par_get(struct snapraid_disk* disk, struct snapraid_file* file, block_off_t file_pos)
+ 945 : {
+ 946 464306 : return fs_file2par_get_ts(disk, &disk->fs_last, file, file_pos);
+ 947 : }
+ 948 :
+ 949 : /**
+ 950 : * Like fs_par2block_get() but thread-safe.
+ 951 : */
+ 952 : struct snapraid_block* fs_par2block_get_ts(struct snapraid_disk* disk, struct snapraid_chunk** fs_last, block_off_t parity_pos);
953 :
954 : /**
- 955 : * Like fs_par2block_get() but thread-safe.
- 956 : */
- 957 : struct snapraid_block* fs_par2block_get_ts(struct snapraid_disk* disk, struct snapraid_chunk** fs_last, block_off_t parity_pos);
- 958 :
- 959 : /**
- 960 : * Get the block from the parity position.
- 961 : * Return BLOCK_EMPTY==0 if the block is over the end of the disk or not used.
- 962 : * \note This function is NOT thread-safe as it uses the the disk cache.
- 963 : */
- 964 21725563 : static inline struct snapraid_block* fs_par2block_get(struct snapraid_disk* disk, block_off_t parity_pos)
- 965 : {
- 966 21725563 : return fs_par2block_get_ts(disk, &disk->fs_last, parity_pos);
- 967 : }
- 968 :
- 969 : /**
- 970 : * Allocate a disk mapping.
- 971 : * Uses uuid="" if not available.
+ 955 : * Get the block from the parity position.
+ 956 : * Return BLOCK_EMPTY==0 if the block is over the end of the disk or not used.
+ 957 : * \note This function is NOT thread-safe as it uses the the disk cache.
+ 958 : */
+ 959 21727310 : static inline struct snapraid_block* fs_par2block_get(struct snapraid_disk* disk, block_off_t parity_pos)
+ 960 : {
+ 961 21727310 : return fs_par2block_get_ts(disk, &disk->fs_last, parity_pos);
+ 962 : }
+ 963 :
+ 964 : /**
+ 965 : * Allocate a disk mapping.
+ 966 : * Uses uuid="" if not available.
+ 967 : */
+ 968 : struct snapraid_map* map_alloc(const char* name, unsigned position, block_off_t total_blocks, block_off_t free_blocks, const char* uuid);
+ 969 :
+ 970 : /**
+ 971 : * Deallocate a disk mapping.
972 : */
- 973 : struct snapraid_map* map_alloc(const char* name, unsigned position, block_off_t total_blocks, block_off_t free_blocks, const char* uuid);
+ 973 : void map_free(struct snapraid_map* map);
974 :
975 : /**
- 976 : * Deallocate a disk mapping.
- 977 : */
- 978 : void map_free(struct snapraid_map* map);
- 979 :
- 980 : /**
- 981 : * Mask used to store additional information in the info bits.
- 982 : *
- 983 : * These bits reduce the granurality of the time in the memory representation.
+ 976 : * Mask used to store additional information in the info bits.
+ 977 : *
+ 978 : * These bits reduce the granurality of the time in the memory representation.
+ 979 : */
+ 980 : #define INFO_MASK 0x7
+ 981 :
+ 982 : /**
+ 983 : * Make an info.
984 : */
- 985 : #define INFO_MASK 0x7
- 986 :
- 987 : /**
- 988 : * Make an info.
- 989 : */
- 990 390916 : static inline snapraid_info info_make(time_t last_access, int error, int rehash, int justsynced)
- 991 : {
- 992 : /* clear the lowest bits as reserved for other information */
- 993 390916 : snapraid_info info = last_access & ~INFO_MASK;
- 994 :
- 995 390916 : if (error != 0)
- 996 5433 : info |= 0x1;
- 997 390916 : if (rehash != 0)
- 998 127410 : info |= 0x2;
- 999 390916 : if (justsynced != 0)
- 1000 226165 : info |= 0x4;
- 1001 390916 : return info;
- 1002 : }
- 1003 :
- 1004 : /**
- 1005 : * Extract the time information.
- 1006 : * This is the last time when the block was know to be correct.
- 1007 : * The "scrubbed" info tells if the time is referreing at the latest sync or scrub.
- 1008 : */
- 1009 2241006 : static inline time_t info_get_time(snapraid_info info)
- 1010 : {
- 1011 2241006 : return info & ~INFO_MASK;
- 1012 : }
- 1013 :
- 1014 : /**
- 1015 : * Extract the error information.
- 1016 : * Report if the block address had some problem.
- 1017 : */
- 1018 1705083 : static inline int info_get_bad(snapraid_info info)
- 1019 : {
- 1020 1705083 : return (info & 0x1) != 0;
- 1021 : }
- 1022 :
- 1023 : /**
- 1024 : * Extract the rehash information.
- 1025 : * Report if the block address is using the old hash and needs to be rehashed.
- 1026 : */
- 1027 3293767 : static inline int info_get_rehash(snapraid_info info)
- 1028 : {
- 1029 3293767 : return (info & 0x2) != 0;
- 1030 : }
- 1031 :
- 1032 : /**
- 1033 : * Extract the scrubbed information.
- 1034 : * Report if the block address was never scrubbed.
- 1035 : */
- 1036 1455572 : static inline int info_get_justsynced(snapraid_info info)
- 1037 : {
- 1038 1455572 : return (info & 0x4) != 0;
- 1039 : }
- 1040 :
- 1041 : /**
- 1042 : * Mark the block address as with error.
- 1043 : */
- 1044 1803 : static inline snapraid_info info_set_bad(snapraid_info info)
- 1045 : {
- 1046 1803 : return info | 0x1;
- 1047 : }
- 1048 :
- 1049 : /**
- 1050 : * Mark the block address as with rehash.
- 1051 : */
- 1052 9199 : static inline snapraid_info info_set_rehash(snapraid_info info)
- 1053 : {
- 1054 9199 : return info | 0x2;
- 1055 : }
- 1056 :
- 1057 : /**
- 1058 : * Set the info at the specified position.
- 1059 : * The position is allocated if not yet done.
- 1060 : */
- 1061 1609362 : static inline void info_set(tommy_arrayblkof* array, unsigned pos, snapraid_info info)
- 1062 : {
- 1063 1609362 : tommy_arrayblkof_grow(array, pos + 1);
- 1064 :
- 1065 1609362 : memcpy(tommy_arrayblkof_ref(array, pos), &info, sizeof(snapraid_info));
- 1066 1609362 : }
- 1067 :
- 1068 : /**
- 1069 : * Get the info at the specified position.
- 1070 : * For not allocated position, 0 is returned.
- 1071 : */
- 1072 10527480 : static inline snapraid_info info_get(tommy_arrayblkof* array, unsigned pos)
- 1073 : {
- 1074 : snapraid_info info;
+ 985 394996 : static inline snapraid_info info_make(time_t last_access, int error, int rehash, int justsynced)
+ 986 : {
+ 987 : /* clear the lowest bits as reserved for other information */
+ 988 394996 : snapraid_info info = last_access & ~INFO_MASK;
+ 989 :
+ 990 394996 : if (error != 0)
+ 991 5460 : info |= 0x1;
+ 992 394996 : if (rehash != 0)
+ 993 127410 : info |= 0x2;
+ 994 394996 : if (justsynced != 0)
+ 995 226412 : info |= 0x4;
+ 996 394996 : return info;
+ 997 : }
+ 998 :
+ 999 : /**
+ 1000 : * Extract the time information.
+ 1001 : * This is the last time when the block was know to be correct.
+ 1002 : * The "scrubbed" info tells if the time is referreing at the latest sync or scrub.
+ 1003 : */
+ 1004 2258078 : static inline time_t info_get_time(snapraid_info info)
+ 1005 : {
+ 1006 2258078 : return info & ~INFO_MASK;
+ 1007 : }
+ 1008 :
+ 1009 : /**
+ 1010 : * Extract the error information.
+ 1011 : * Report if the block address had some problem.
+ 1012 : */
+ 1013 1725704 : static inline int info_get_bad(snapraid_info info)
+ 1014 : {
+ 1015 1725704 : return (info & 0x1) != 0;
+ 1016 : }
+ 1017 :
+ 1018 : /**
+ 1019 : * Extract the rehash information.
+ 1020 : * Report if the block address is using the old hash and needs to be rehashed.
+ 1021 : */
+ 1022 3312725 : static inline int info_get_rehash(snapraid_info info)
+ 1023 : {
+ 1024 3312725 : return (info & 0x2) != 0;
+ 1025 : }
+ 1026 :
+ 1027 : /**
+ 1028 : * Extract the scrubbed information.
+ 1029 : * Report if the block address was never scrubbed.
+ 1030 : */
+ 1031 1474627 : static inline int info_get_justsynced(snapraid_info info)
+ 1032 : {
+ 1033 1474627 : return (info & 0x4) != 0;
+ 1034 : }
+ 1035 :
+ 1036 : /**
+ 1037 : * Mark the block address as with error.
+ 1038 : */
+ 1039 1802 : static inline snapraid_info info_set_bad(snapraid_info info)
+ 1040 : {
+ 1041 1802 : return info | 0x1;
+ 1042 : }
+ 1043 :
+ 1044 : /**
+ 1045 : * Mark the block address as with rehash.
+ 1046 : */
+ 1047 9199 : static inline snapraid_info info_set_rehash(snapraid_info info)
+ 1048 : {
+ 1049 9199 : return info | 0x2;
+ 1050 : }
+ 1051 :
+ 1052 : /**
+ 1053 : * Set the info at the specified position.
+ 1054 : * The position is allocated if not yet done.
+ 1055 : */
+ 1056 1609485 : static inline void info_set(tommy_arrayblkof* array, unsigned pos, snapraid_info info)
+ 1057 : {
+ 1058 1609485 : tommy_arrayblkof_grow(array, pos + 1);
+ 1059 :
+ 1060 1609485 : memcpy(tommy_arrayblkof_ref(array, pos), &info, sizeof(snapraid_info));
+ 1061 1609485 : }
+ 1062 :
+ 1063 : /**
+ 1064 : * Get the info at the specified position.
+ 1065 : * For not allocated position, 0 is returned.
+ 1066 : */
+ 1067 10573034 : static inline snapraid_info info_get(tommy_arrayblkof* array, unsigned pos)
+ 1068 : {
+ 1069 : snapraid_info info;
+ 1070 :
+ 1071 10573034 : if (pos >= tommy_arrayblkof_size(array))
+ 1072 474047 : return 0;
+ 1073 :
+ 1074 10073489 : memcpy(&info, tommy_arrayblkof_ref(array, pos), sizeof(snapraid_info));
1075 :
- 1076 10527480 : if (pos >= tommy_arrayblkof_size(array))
- 1077 477684 : return 0;
+ 1076 10085303 : return info;
+ 1077 : }
1078 :
- 1079 10051219 : memcpy(&info, tommy_arrayblkof_ref(array, pos), sizeof(snapraid_info));
- 1080 :
- 1081 10056067 : return info;
- 1082 : }
+ 1079 : /**
+ 1080 : * Compare times
+ 1081 : */
+ 1082 : int time_compare(const void* void_a, const void* void_b);
1083 :
- 1084 : /**
- 1085 : * Compare times
- 1086 : */
- 1087 : int time_compare(const void* void_a, const void* void_b);
- 1088 :
- 1089 : #endif
- 1090 :
+ 1084 : #endif
+ 1085 :
diff --git a/cov/cmdline/handle.c.func-sort-c.html b/cov/cmdline/handle.c.func-sort-c.html
index 786e0389..364aeee3 100644
--- a/cov/cmdline/handle.c.func-sort-c.html
+++ b/cov/cmdline/handle.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,31 +61,31 @@
| handle_read |
- 5655264 |
+ 5656394 |
| handle_close |
- 4567924 |
+ 4568631 |
| handle_open |
- 1971646 |
+ 1972488 |
| handle_create |
- 771245 |
+ 771210 |
| handle_write |
- 288250 |
+ 288205 |
| handle_utime |
- 117835 |
+ 117763 |
| handle_truncate |
- 3177 |
+ 3249 |
| handle_map |
diff --git a/cov/cmdline/handle.c.func.html b/cov/cmdline/handle.c.func.html
index 80c45654..f0a579bc 100644
--- a/cov/cmdline/handle.c.func.html
+++ b/cov/cmdline/handle.c.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,11 +61,11 @@
| handle_close |
- 4567924 |
+ 4568631 |
| handle_create |
- 771245 |
+ 771210 |
| handle_map |
@@ -73,23 +73,23 @@
| handle_open |
- 1971646 |
+ 1972488 |
| handle_read |
- 5655264 |
+ 5656394 |
| handle_truncate |
- 3177 |
+ 3249 |
| handle_utime |
- 117835 |
+ 117763 |
| handle_write |
- 288250 |
+ 288205 |
diff --git a/cov/cmdline/handle.c.gcov.html b/cov/cmdline/handle.c.gcov.html
index 33da53e7..72e13a47 100644
--- a/cov/cmdline/handle.c.gcov.html
+++ b/cov/cmdline/handle.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -86,66 +86,66 @@
24 : /****************************************************************************/
25 : /* handle */
26 :
- 27 771245 : int handle_create(struct snapraid_handle* handle, struct snapraid_file* file, int mode)
+ 27 771210 : int handle_create(struct snapraid_handle* handle, struct snapraid_file* file, int mode)
28 : {
29 : int ret;
30 : int flags;
31 :
32 : /* if it's the same file, and already opened, nothing to do */
- 33 771245 : if (handle->file == file && handle->f != -1) {
+ 33 771210 : if (handle->file == file && handle->f != -1) {
34 0 : return 0;
35 : }
36 :
- 37 771245 : pathprint(handle->path, sizeof(handle->path), "%s%s", handle->disk->dir, file->sub);
+ 37 771210 : pathprint(handle->path, sizeof(handle->path), "%s%s", handle->disk->dir, file->sub);
38 :
- 39 771245 : ret = mkancestor(handle->path);
- 40 771245 : if (ret != 0) {
+ 39 771210 : ret = mkancestor(handle->path);
+ 40 771210 : if (ret != 0) {
41 : /* LCOV_EXCL_START */
42 : return -1;
43 : /* LCOV_EXCL_STOP */
44 : }
45 :
46 : /* initial values, changed later if required */
- 47 771245 : handle->created = 0;
+ 47 771210 : handle->created = 0;
48 :
49 : /* flags for opening */
50 : /* O_BINARY: open as binary file (Windows only) */
51 : /* O_NOFOLLOW: do not follow links to ensure to open the real file */
52 : /* O_SEQUENTIAL: improve performance for sequential access (Windows only) */
- 53 771245 : flags = O_BINARY | O_NOFOLLOW;
- 54 771245 : if ((mode & MODE_SEQUENTIAL) != 0)
- 55 771245 : flags |= O_SEQUENTIAL;
+ 53 771210 : flags = O_BINARY | O_NOFOLLOW;
+ 54 771210 : if ((mode & MODE_SEQUENTIAL) != 0)
+ 55 771210 : flags |= O_SEQUENTIAL;
56 :
57 : /* open for read write */
- 58 771245 : handle->f = open(handle->path, flags | O_RDWR);
+ 58 771210 : handle->f = open(handle->path, flags | O_RDWR);
59 :
60 : /* if failed for missing write permission */
- 61 771245 : if (handle->f == -1 && (errno == EACCES || errno == EROFS)) {
+ 61 771210 : if (handle->f == -1 && (errno == EACCES || errno == EROFS)) {
62 : /* open for real-only */
63 0 : handle->f = open(handle->path, flags | O_RDONLY);
64 : }
65 :
66 : /* if failed for missing file */
- 67 771245 : if (handle->f == -1 && errno == ENOENT) {
+ 67 771210 : if (handle->f == -1 && errno == ENOENT) {
68 : char path_from[PATH_MAX];
69 :
70 : /* check if exists a .unrecoverable copy, and rename to the real one */
- 71 176510 : pathprint(path_from, sizeof(path_from), "%s.unrecoverable", handle->path);
+ 71 176420 : pathprint(path_from, sizeof(path_from), "%s.unrecoverable", handle->path);
72 :
- 73 176510 : if (rename(path_from, handle->path) == 0) {
+ 73 176420 : if (rename(path_from, handle->path) == 0) {
74 : /* open for read write */
- 75 63467 : handle->f = open(handle->path, flags | O_RDWR);
+ 75 63396 : handle->f = open(handle->path, flags | O_RDWR);
76 : } else {
77 : /* create it */
- 78 113043 : handle->f = open(handle->path, flags | O_RDWR | O_CREAT, 0600);
- 79 113043 : if (handle->f != -1) {
+ 78 113024 : handle->f = open(handle->path, flags | O_RDWR | O_CREAT, 0600);
+ 79 113024 : if (handle->f != -1) {
80 : /* mark it as created if really done */
- 81 113043 : handle->created = 1;
+ 81 113024 : handle->created = 1;
82 : }
83 : }
84 : }
85 :
- 86 771245 : if (handle->f == -1) {
+ 86 771210 : if (handle->f == -1) {
87 : /* LCOV_EXCL_START */
88 : /* invalidate for error */
89 : handle->file = 0;
@@ -158,11 +158,11 @@
96 : }
97 :
98 : /* just opened */
- 99 771245 : handle->file = file;
+ 99 771210 : handle->file = file;
100 :
101 : /* get the stat info */
- 102 771245 : ret = fstat(handle->f, &handle->st);
- 103 771245 : if (ret != 0) {
+ 102 771210 : ret = fstat(handle->f, &handle->st);
+ 103 771210 : if (ret != 0) {
104 : /* LCOV_EXCL_START */
105 : log_fatal("Error accessing file '%s'. %s.\n", handle->path, strerror(errno));
106 : return -1;
@@ -170,13 +170,13 @@
108 : }
109 :
110 : /* get the size of the existing data */
- 111 771245 : handle->valid_size = handle->st.st_size;
+ 111 771210 : handle->valid_size = handle->st.st_size;
112 :
113 : #if HAVE_POSIX_FADVISE
- 114 771245 : if ((mode & MODE_SEQUENTIAL) != 0) {
+ 114 771210 : if ((mode & MODE_SEQUENTIAL) != 0) {
115 : /* advise sequential access */
- 116 771245 : ret = posix_fadvise(handle->f, 0, 0, POSIX_FADV_SEQUENTIAL);
- 117 771245 : if (ret != 0) {
+ 116 771210 : ret = posix_fadvise(handle->f, 0, 0, POSIX_FADV_SEQUENTIAL);
+ 117 771210 : if (ret != 0) {
118 : /* LCOV_EXCL_START */
119 : log_fatal("Error advising file '%s'. %s.\n", handle->path, strerror(ret));
120 : return -1;
@@ -185,15 +185,15 @@
123 : }
124 : #endif
125 :
- 126 771245 : return 0;
+ 126 771210 : return 0;
127 : }
128 :
- 129 3177 : int handle_truncate(struct snapraid_handle* handle, struct snapraid_file* file)
+ 129 3249 : int handle_truncate(struct snapraid_handle* handle, struct snapraid_file* file)
130 : {
131 : int ret;
132 :
- 133 3177 : ret = ftruncate(handle->f, file->size);
- 134 3177 : if (ret != 0) {
+ 133 3249 : ret = ftruncate(handle->f, file->size);
+ 134 3249 : if (ret != 0) {
135 : /* LCOV_EXCL_START */
136 : if (errno == EACCES) {
137 : log_fatal("Failed to truncate file '%s' for missing write permission.\n", handle->path);
@@ -205,58 +205,58 @@
143 : }
144 :
145 : /* adjust the size to the truncated size */
- 146 3177 : handle->valid_size = file->size;
+ 146 3249 : handle->valid_size = file->size;
147 :
- 148 3177 : return 0;
+ 148 3249 : return 0;
149 : }
150 :
- 151 1971646 : int handle_open(struct snapraid_handle* handle, struct snapraid_file* file, int mode, fptr* out, fptr* out_missing)
+ 151 1972488 : int handle_open(struct snapraid_handle* handle, struct snapraid_file* file, int mode, fptr* out, fptr* out_missing)
152 : {
153 : int ret;
154 : int flags;
155 :
- 156 1971646 : if (!out_missing)
- 157 1971130 : out_missing = out;
+ 156 1972488 : if (!out_missing)
+ 157 1971972 : out_missing = out;
158 :
159 : /* if already opened, nothing to do */
- 160 1971646 : if (handle->file == file && handle->f != -1) {
- 161 332255 : return 0;
+ 160 1972488 : if (handle->file == file && handle->f != -1) {
+ 161 332290 : return 0;
162 : }
163 :
- 164 1639391 : pathprint(handle->path, sizeof(handle->path), "%s%s", handle->disk->dir, file->sub);
+ 164 1640198 : pathprint(handle->path, sizeof(handle->path), "%s%s", handle->disk->dir, file->sub);
165 :
166 : /* for sure not created */
- 167 1639391 : handle->created = 0;
+ 167 1640198 : handle->created = 0;
168 :
169 : /* flags for opening */
170 : /* O_BINARY: open as binary file (Windows only) */
171 : /* O_NOFOLLOW: do not follow links to ensure to open the real file */
172 : /* O_SEQUENTIAL: improve performance for sequential access (Windows only) */
- 173 1639391 : flags = O_BINARY | O_NOFOLLOW;
- 174 1639391 : if ((mode & MODE_SEQUENTIAL) != 0)
- 175 1628063 : flags |= O_SEQUENTIAL;
+ 173 1640198 : flags = O_BINARY | O_NOFOLLOW;
+ 174 1640198 : if ((mode & MODE_SEQUENTIAL) != 0)
+ 175 1628870 : flags |= O_SEQUENTIAL;
176 :
177 : /* open for read */
- 178 1639391 : handle->f = open_noatime(handle->path, flags | O_RDONLY);
- 179 1639391 : if (handle->f == -1) {
+ 178 1640198 : handle->f = open_noatime(handle->path, flags | O_RDONLY);
+ 179 1640198 : if (handle->f == -1) {
180 : /* invalidate for error */
- 181 78905 : handle->file = 0;
- 182 78905 : handle->f = -1;
- 183 78905 : handle->valid_size = 0;
+ 181 78777 : handle->file = 0;
+ 182 78777 : handle->f = -1;
+ 183 78777 : handle->valid_size = 0;
184 :
- 185 78905 : if (errno == ENOENT)
- 186 78893 : out_missing("Missing file '%s'.\n", handle->path);
+ 185 78777 : if (errno == ENOENT)
+ 186 78765 : out_missing("Missing file '%s'.\n", handle->path);
187 : else
188 12 : out("Error opening file '%s'. %s.\n", handle->path, strerror(errno));
- 189 78905 : return -1;
+ 189 78777 : return -1;
190 : }
191 :
192 : /* just opened */
- 193 1560486 : handle->file = file;
+ 193 1561421 : handle->file = file;
194 :
195 : /* get the stat info */
- 196 1560486 : ret = fstat(handle->f, &handle->st);
- 197 1560486 : if (ret != 0) {
+ 196 1561421 : ret = fstat(handle->f, &handle->st);
+ 197 1561421 : if (ret != 0) {
198 : /* LCOV_EXCL_START */
199 : out("Error accessing file '%s'. %s.\n", handle->path, strerror(errno));
200 : return -1;
@@ -264,13 +264,13 @@
202 : }
203 :
204 : /* get the size of the existing data */
- 205 1560486 : handle->valid_size = handle->st.st_size;
+ 205 1561421 : handle->valid_size = handle->st.st_size;
206 :
207 : #if HAVE_POSIX_FADVISE
- 208 1560486 : if ((mode & MODE_SEQUENTIAL) != 0) {
+ 208 1561421 : if ((mode & MODE_SEQUENTIAL) != 0) {
209 : /* advise sequential access */
- 210 1549158 : ret = posix_fadvise(handle->f, 0, 0, POSIX_FADV_SEQUENTIAL);
- 211 1549158 : if (ret != 0) {
+ 210 1550093 : ret = posix_fadvise(handle->f, 0, 0, POSIX_FADV_SEQUENTIAL);
+ 211 1550093 : if (ret != 0) {
212 : /* LCOV_EXCL_START */
213 : out("Error advising file '%s'. %s.\n", handle->path, strerror(ret));
214 : return -1;
@@ -279,17 +279,17 @@
217 : }
218 : #endif
219 :
- 220 1560486 : return 0;
+ 220 1561421 : return 0;
221 : }
222 :
- 223 4567924 : int handle_close(struct snapraid_handle* handle)
+ 223 4568631 : int handle_close(struct snapraid_handle* handle)
224 : {
225 : int ret;
226 :
227 : /* close if open */
- 228 4567924 : if (handle->f != -1) {
- 229 2331731 : ret = close(handle->f);
- 230 2331731 : if (ret != 0) {
+ 228 4568631 : if (handle->f != -1) {
+ 229 2332631 : ret = close(handle->f);
+ 230 2332631 : if (ret != 0) {
231 : /* LCOV_EXCL_START */
232 : log_fatal("Error closing file '%s'. %s.\n", handle->file->sub, strerror(errno));
233 :
@@ -303,36 +303,36 @@
241 : }
242 :
243 : /* reset the descriptor */
- 244 4567924 : handle->file = 0;
- 245 4567924 : handle->f = -1;
- 246 4567924 : handle->valid_size = 0;
+ 244 4568631 : handle->file = 0;
+ 245 4568631 : handle->f = -1;
+ 246 4568631 : handle->valid_size = 0;
247 :
- 248 4567924 : return 0;
+ 248 4568631 : return 0;
249 : }
250 :
- 251 5655264 : int handle_read(struct snapraid_handle* handle, block_off_t file_pos, unsigned char* block_buffer, unsigned block_size, fptr* out, fptr* out_missing)
+ 251 5656394 : int handle_read(struct snapraid_handle* handle, block_off_t file_pos, unsigned char* block_buffer, unsigned block_size, fptr* out, fptr* out_missing)
252 : {
253 : ssize_t read_ret;
254 : data_off_t offset;
255 : unsigned read_size;
256 : unsigned count;
257 :
- 258 5655264 : offset = file_pos * (data_off_t)block_size;
+ 258 5656394 : offset = file_pos * (data_off_t)block_size;
259 :
- 260 5655264 : if (!out_missing)
- 261 5641863 : out_missing = out;
+ 260 5656394 : if (!out_missing)
+ 261 5642993 : out_missing = out;
262 :
263 : /* check if we are going to read only not initialized data */
- 264 5655264 : if (offset >= handle->valid_size) {
+ 264 5656394 : if (offset >= handle->valid_size) {
265 : /* if the file is missing, it's at 0 size, or it's rebuilt while reading */
- 266 433381 : if (offset == handle->valid_size || handle->valid_size == 0)
- 267 431954 : out_missing("Reading data from missing file '%s' at offset %" PRIu64 ".\n", handle->path, offset);
+ 266 433131 : if (offset == handle->valid_size || handle->valid_size == 0)
+ 267 431906 : out_missing("Reading data from missing file '%s' at offset %" PRIu64 ".\n", handle->path, offset);
268 : else
- 269 1427 : out("Reading missing data from file '%s' at offset %" PRIu64 ".\n", handle->path, offset);
- 270 433381 : return -1;
+ 269 1225 : out("Reading missing data from file '%s' at offset %" PRIu64 ".\n", handle->path, offset);
+ 270 433131 : return -1;
271 : }
272 :
- 273 5221883 : read_size = file_block_size(handle->file, file_pos, block_size);
+ 273 5223263 : read_size = file_block_size(handle->file, file_pos, block_size);
274 :
275 : #if !HAVE_PREAD
276 : if (lseek(handle->f, offset, SEEK_SET) != offset) {
@@ -343,32 +343,32 @@
281 : }
282 : #endif
283 :
- 284 5221883 : count = 0;
+ 284 5223263 : count = 0;
285 : do {
286 :
287 : #if HAVE_PREAD
- 288 5230877 : read_ret = pread(handle->f, block_buffer + count, read_size - count, offset + count);
+ 288 5232157 : read_ret = pread(handle->f, block_buffer + count, read_size - count, offset + count);
289 : #else
290 : read_ret = read(handle->f, block_buffer + count, read_size - count);
291 : #endif
292 :
- 293 5230877 : if (read_ret < 0) {
+ 293 5232157 : if (read_ret < 0) {
294 : /* LCOV_EXCL_START */
295 : out("Error reading file '%s' at offset %" PRIu64 " for size %u. %s.\n", handle->path, offset + count, read_size - count, strerror(errno));
296 : return -1;
297 : /* LCOV_EXCL_STOP */
298 : }
- 299 5230877 : if (read_ret == 0) {
- 300 8994 : out("Unexpected end of file '%s' at offset %" PRIu64 ". %s.\n", handle->path, offset, strerror(errno));
- 301 8994 : return -1;
+ 299 5232157 : if (read_ret == 0) {
+ 300 8894 : out("Unexpected end of file '%s' at offset %" PRIu64 ". %s.\n", handle->path, offset, strerror(errno));
+ 301 8894 : return -1;
302 : }
303 :
- 304 5221883 : count += read_ret;
- 305 5221883 : } while (count < read_size);
+ 304 5223263 : count += read_ret;
+ 305 5223263 : } while (count < read_size);
306 :
307 : /* pad with 0 */
- 308 5212889 : if (read_size < block_size) {
- 309 2111431 : memset(block_buffer + read_size, 0, block_size - read_size);
+ 308 5214369 : if (read_size < block_size) {
+ 309 2112031 : memset(block_buffer + read_size, 0, block_size - read_size);
310 : }
311 :
312 : /* Here isn't needed to call posix_fadvise(..., POSIX_FADV_DONTNEED) */
@@ -382,21 +382,21 @@
320 : /* at: https://lkml.org/lkml/2010/12/6/122 */
321 : /* We relay only on the automatic readahead triggered by POSIX_FADV_SEQUENTIAL. */
322 :
- 323 5212889 : return read_size;
+ 323 5214369 : return read_size;
324 : }
325 :
- 326 288250 : int handle_write(struct snapraid_handle* handle, block_off_t file_pos, unsigned char* block_buffer, unsigned block_size)
+ 326 288205 : int handle_write(struct snapraid_handle* handle, block_off_t file_pos, unsigned char* block_buffer, unsigned block_size)
327 : {
328 : ssize_t write_ret;
329 : data_off_t offset;
330 : unsigned write_size;
331 :
- 332 288250 : offset = file_pos * (data_off_t)block_size;
+ 332 288205 : offset = file_pos * (data_off_t)block_size;
333 :
- 334 288250 : write_size = file_block_size(handle->file, file_pos, block_size);
+ 334 288205 : write_size = file_block_size(handle->file, file_pos, block_size);
335 :
336 : #if HAVE_PWRITE
- 337 288250 : write_ret = pwrite(handle->f, block_buffer, write_size, offset);
+ 337 288205 : write_ret = pwrite(handle->f, block_buffer, write_size, offset);
338 : #else
339 : if (lseek(handle->f, offset, SEEK_SET) != offset) {
340 : /* LCOV_EXCL_START */
@@ -407,7 +407,7 @@
345 :
346 : write_ret = write(handle->f, block_buffer, write_size);
347 : #endif
- 348 288250 : if (write_ret != (ssize_t)write_size) { /* conversion is safe because block_size is always small */
+ 348 288205 : if (write_ret != (ssize_t)write_size) { /* conversion is safe because block_size is always small */
349 : /* LCOV_EXCL_START */
350 : log_fatal("Error writing file '%s'. %s.\n", handle->path, strerror(errno));
351 : return -1;
@@ -415,34 +415,34 @@
353 : }
354 :
355 : /* adjust the size of the valid data */
- 356 288250 : if (handle->valid_size < offset + write_size) {
- 357 282146 : handle->valid_size = offset + write_size;
+ 356 288205 : if (handle->valid_size < offset + write_size) {
+ 357 282174 : handle->valid_size = offset + write_size;
358 : }
359 :
360 : /* Here doesn't make sense to call posix_fadvise(..., POSIX_FADV_DONTNEED) because */
361 : /* at this time the data is still not yet written and it cannot be discharged. */
362 :
- 363 288250 : return 0;
+ 363 288205 : return 0;
364 : }
365 :
- 366 117835 : int handle_utime(struct snapraid_handle* handle)
+ 366 117763 : int handle_utime(struct snapraid_handle* handle)
367 : {
368 : int ret;
369 :
370 : /* do nothing if not opened */
- 371 117835 : if (handle->f == -1)
+ 371 117763 : if (handle->f == -1)
372 0 : return 0;
373 :
- 374 117835 : ret = fmtime(handle->f, handle->file->mtime_sec, handle->file->mtime_nsec);
+ 374 117763 : ret = fmtime(handle->f, handle->file->mtime_sec, handle->file->mtime_nsec);
375 :
- 376 117835 : if (ret != 0) {
+ 376 117763 : if (ret != 0) {
377 : /* LCOV_EXCL_START */
378 : log_fatal("Error timing file '%s'. %s.\n", handle->file->sub, strerror(errno));
379 : return -1;
380 : /* LCOV_EXCL_STOP */
381 : }
382 :
- 383 117835 : return 0;
+ 383 117763 : return 0;
384 : }
385 :
386 206 : struct snapraid_handle* handle_map(struct snapraid_state* state, unsigned* handlemax)
diff --git a/cov/cmdline/import.c.func-sort-c.html b/cov/cmdline/import.c.func-sort-c.html
index 6875e443..4ed3e003 100644
--- a/cov/cmdline/import.c.func-sort-c.html
+++ b/cov/cmdline/import.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,11 +61,11 @@
| import_block_hash |
- 653410 |
+ 652942 |
| state_import_fetch |
- 644466 |
+ 643998 |
| import_block_prevhash_compare |
diff --git a/cov/cmdline/import.c.func.html b/cov/cmdline/import.c.func.html
index ab8a545a..00f16958 100644
--- a/cov/cmdline/import.c.func.html
+++ b/cov/cmdline/import.c.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,7 +61,7 @@
| import_block_hash |
- 653410 |
+ 652942 |
| import_block_hash_compare |
@@ -89,7 +89,7 @@
| state_import_fetch |
- 644466 |
+ 643998 |
diff --git a/cov/cmdline/import.c.gcov.html b/cov/cmdline/import.c.gcov.html
index 80f00c7d..0cec9c66 100644
--- a/cov/cmdline/import.c.gcov.html
+++ b/cov/cmdline/import.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -108,9 +108,9 @@
46 : * Compute the hash of the hash for an import block.
47 : * We just use the first 32 bit of the hash itself.
48 : */
- 49 653410 : static inline tommy_uint32_t import_block_hash(const unsigned char* hash)
+ 49 652942 : static inline tommy_uint32_t import_block_hash(const unsigned char* hash)
50 : {
- 51 653410 : return *(const tommy_uint32_t*)hash;
+ 51 652942 : return *(const tommy_uint32_t*)hash;
52 : }
53 :
54 1750 : static void import_file(struct snapraid_state* state, const char* path, uint64_t size)
@@ -211,24 +211,24 @@
149 1750 : free(file);
150 1750 : }
151 :
- 152 644466 : int state_import_fetch(struct snapraid_state* state, int rehash, struct snapraid_block* missing_block, unsigned char* buffer)
+ 152 643998 : int state_import_fetch(struct snapraid_state* state, int rehash, struct snapraid_block* missing_block, unsigned char* buffer)
153 : {
154 : struct snapraid_import_block* block;
155 : int ret;
156 : int f;
- 157 644466 : const unsigned char* hash = missing_block->hash;
- 158 644466 : unsigned block_size = state->block_size;
+ 157 643998 : const unsigned char* hash = missing_block->hash;
+ 158 643998 : unsigned block_size = state->block_size;
159 : unsigned read_size;
160 : unsigned char buffer_hash[HASH_SIZE];
161 : const char* path;
162 :
- 163 644466 : if (rehash) {
- 164 28985 : block = tommy_hashdyn_search(&state->previmportset, import_block_prevhash_compare, hash, import_block_hash(hash));
+ 163 643998 : if (rehash) {
+ 164 28986 : block = tommy_hashdyn_search(&state->previmportset, import_block_prevhash_compare, hash, import_block_hash(hash));
165 : } else {
- 166 615481 : block = tommy_hashdyn_search(&state->importset, import_block_hash_compare, hash, import_block_hash(hash));
+ 166 615012 : block = tommy_hashdyn_search(&state->importset, import_block_hash_compare, hash, import_block_hash(hash));
167 : }
- 168 644466 : if (!block)
- 169 639994 : return -1;
+ 168 643998 : if (!block)
+ 169 639526 : return -1;
170 :
171 4472 : path = block->file->path;
172 4472 : read_size = block->size;
diff --git a/cov/cmdline/index-sort-f.html b/cov/cmdline/index-sort-f.html
index 9552eb6b..7e050b55 100644
--- a/cov/cmdline/index-sort-f.html
+++ b/cov/cmdline/index-sort-f.html
@@ -31,13 +31,13 @@
|
-
-
+
+
-
+
|
@@ -112,20 +112,20 @@
| elem.c |
-
+
|
- 93.6 % |
- 537 / 574 |
- 96.8 % |
- 61 / 63 |
+ 93.8 % |
+ 545 / 581 |
+ 96.9 % |
+ 62 / 64 |
| state.c |
-
+
|
- 92.5 % |
- 1249 / 1351 |
+ 92.4 % |
+ 1248 / 1351 |
97.2 % |
35 / 36 |
@@ -382,10 +382,10 @@
| scan.c |
-
+
|
- 87.3 % |
- 543 / 622 |
+ 87.4 % |
+ 542 / 620 |
100.0 % |
23 / 23 |
@@ -402,12 +402,12 @@
| elem.h |
-
+
|
- 99.2 % |
- 118 / 119 |
+ 99.1 % |
+ 115 / 116 |
100.0 % |
- 40 / 40 |
+ 39 / 39 |
diff --git a/cov/cmdline/index-sort-l.html b/cov/cmdline/index-sort-l.html
index 65ec8595..8aa34497 100644
--- a/cov/cmdline/index-sort-l.html
+++ b/cov/cmdline/index-sort-l.html
@@ -31,13 +31,13 @@
|
-
-
+
+
-
+
|
@@ -132,10 +132,10 @@
| scan.c |
-
+
|
- 87.3 % |
- 543 / 622 |
+ 87.4 % |
+ 542 / 620 |
100.0 % |
23 / 23 |
@@ -172,10 +172,10 @@
| state.c |
-
+
|
- 92.5 % |
- 1249 / 1351 |
+ 92.4 % |
+ 1248 / 1351 |
97.2 % |
35 / 36 |
@@ -232,12 +232,12 @@
| elem.c |
-
+
|
- 93.6 % |
- 537 / 574 |
- 96.8 % |
- 61 / 63 |
+ 93.8 % |
+ 545 / 581 |
+ 96.9 % |
+ 62 / 64 |
| snapraid.c |
@@ -322,12 +322,12 @@
| elem.h |
-
+
|
- 99.2 % |
- 118 / 119 |
+ 99.1 % |
+ 115 / 116 |
100.0 % |
- 40 / 40 |
+ 39 / 39 |
| speed.c |
diff --git a/cov/cmdline/index.html b/cov/cmdline/index.html
index c926b667..8449d375 100644
--- a/cov/cmdline/index.html
+++ b/cov/cmdline/index.html
@@ -31,13 +31,13 @@
|
-
-
+
+
-
+
|
@@ -112,22 +112,22 @@
| elem.c |
-
+
|
- 93.6 % |
- 537 / 574 |
- 96.8 % |
- 61 / 63 |
+ 93.8 % |
+ 545 / 581 |
+ 96.9 % |
+ 62 / 64 |
| elem.h |
-
+
|
- 99.2 % |
- 118 / 119 |
+ 99.1 % |
+ 115 / 116 |
100.0 % |
- 40 / 40 |
+ 39 / 39 |
| handle.c |
@@ -242,10 +242,10 @@
| scan.c |
-
+
|
- 87.3 % |
- 543 / 622 |
+ 87.4 % |
+ 542 / 620 |
100.0 % |
23 / 23 |
@@ -312,10 +312,10 @@
| state.c |
-
+
|
- 92.5 % |
- 1249 / 1351 |
+ 92.4 % |
+ 1248 / 1351 |
97.2 % |
35 / 36 |
diff --git a/cov/cmdline/list.c.func-sort-c.html b/cov/cmdline/list.c.func-sort-c.html
index ce4c4732..8a842797 100644
--- a/cov/cmdline/list.c.func-sort-c.html
+++ b/cov/cmdline/list.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/cmdline/list.c.func.html b/cov/cmdline/list.c.func.html
index cfba2184..6de816a4 100644
--- a/cov/cmdline/list.c.func.html
+++ b/cov/cmdline/list.c.func.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/cmdline/list.c.gcov.html b/cov/cmdline/list.c.gcov.html
index 64f07edf..6d26e742 100644
--- a/cov/cmdline/list.c.gcov.html
+++ b/cov/cmdline/list.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -110,34 +110,34 @@
48 18 : tommy_list_sort(&disk->filelist, file_path_compare);
49 :
50 : /* for each file */
- 51 16996 : for (j = disk->filelist; j != 0; j = j->next) {
- 52 16978 : struct snapraid_file* file = j->data;
+ 51 16998 : for (j = disk->filelist; j != 0; j = j->next) {
+ 52 16980 : struct snapraid_file* file = j->data;
53 : #if HAVE_LOCALTIME_R
54 : struct tm tm_res;
55 : #endif
56 : struct tm* tm;
57 : time_t t;
58 :
- 59 16978 : ++file_count;
- 60 16978 : file_size += file->size;
+ 59 16980 : ++file_count;
+ 60 16980 : file_size += file->size;
61 :
- 62 16978 : log_tag("file:%s:%s:%" PRIu64 ":%" PRIi64 ":%u:%" PRIi64 "\n", disk->name, esc(file->sub), file->size, file->mtime_sec, file->mtime_nsec, file->inode);
+ 62 16980 : log_tag("file:%s:%s:%" PRIu64 ":%" PRIi64 ":%u:%" PRIi64 "\n", disk->name, esc(file->sub), file->size, file->mtime_sec, file->mtime_nsec, file->inode);
63 :
- 64 16978 : t = file->mtime_sec;
+ 64 16980 : t = file->mtime_sec;
65 : #if HAVE_LOCALTIME_R
- 66 16978 : tm = localtime_r(&t, &tm_res);
+ 66 16980 : tm = localtime_r(&t, &tm_res);
67 : #else
68 : tm = localtime(&t);
69 : #endif
70 :
- 71 16978 : printf("%12" PRIu64 " ", file->size);
- 72 16978 : if (tm) {
- 73 16978 : printf("%04u/%02u/%02u %02u:%02u", tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min);
- 74 16978 : if (msg_level >= MSG_VERBOSE)
- 75 16978 : printf(":%02u.%03u", tm->tm_sec, file->mtime_nsec / 1000000);
- 76 16978 : printf(" ");
+ 71 16980 : printf("%12" PRIu64 " ", file->size);
+ 72 16980 : if (tm) {
+ 73 16980 : printf("%04u/%02u/%02u %02u:%02u", tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min);
+ 74 16980 : if (msg_level >= MSG_VERBOSE)
+ 75 16980 : printf(":%02u.%03u", tm->tm_sec, file->mtime_nsec / 1000000);
+ 76 16980 : printf(" ");
77 : }
- 78 16978 : printf("%s%s\n", disk->dir, file->sub);
+ 78 16980 : printf("%s%s\n", disk->dir, file->sub);
79 : }
80 :
81 : /* sort by name */
diff --git a/cov/cmdline/mkstream.c.func-sort-c.html b/cov/cmdline/mkstream.c.func-sort-c.html
index bf8063bc..0ef05fdf 100644
--- a/cov/cmdline/mkstream.c.func-sort-c.html
+++ b/cov/cmdline/mkstream.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/cmdline/mkstream.c.func.html b/cov/cmdline/mkstream.c.func.html
index 1c97fe6c..bd99773d 100644
--- a/cov/cmdline/mkstream.c.func.html
+++ b/cov/cmdline/mkstream.c.func.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/cmdline/mkstream.c.gcov.html b/cov/cmdline/mkstream.c.gcov.html
index b24133fb..f02e9bf5 100644
--- a/cov/cmdline/mkstream.c.gcov.html
+++ b/cov/cmdline/mkstream.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/cmdline/mktest.c.func-sort-c.html b/cov/cmdline/mktest.c.func-sort-c.html
index e9df362b..60c06d2d 100644
--- a/cov/cmdline/mktest.c.func-sort-c.html
+++ b/cov/cmdline/mktest.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,23 +61,23 @@
| rnd |
- 50983914 |
+ 50988385 |
| rndnz |
- 50573376 |
+ 50578180 |
| file_cmp |
- 146649 |
+ 146608 |
| rndnz_range |
- 31157 |
+ 31195 |
| rnd_name |
- 26855 |
+ 26824 |
| cmd_generate |
@@ -93,19 +93,19 @@
| cmd_write |
- 4738 |
+ 4703 |
| cmd_append |
- 3179 |
-
-
- | cmd_truncate |
- 3173 |
+ 3252 |
| cmd_delete |
- 3172 |
+ 3155 |
+
+
+ | cmd_truncate |
+ 3151 |
| cmd_damage |
@@ -121,7 +121,7 @@
| cmd_generate_symlink |
- 946 |
+ 915 |
| main |
diff --git a/cov/cmdline/mktest.c.func.html b/cov/cmdline/mktest.c.func.html
index 8a4ba172..96c88f25 100644
--- a/cov/cmdline/mktest.c.func.html
+++ b/cov/cmdline/mktest.c.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,7 +61,7 @@
| cmd_append |
- 3179 |
+ 3252 |
| cmd_change |
@@ -73,7 +73,7 @@
| cmd_delete |
- 3172 |
+ 3155 |
| cmd_generate |
@@ -85,15 +85,15 @@
| cmd_generate_symlink |
- 946 |
+ 915 |
| cmd_truncate |
- 3173 |
+ 3151 |
| cmd_write |
- 4738 |
+ 4703 |
| fallback |
@@ -101,7 +101,7 @@
| file_cmp |
- 146649 |
+ 146608 |
| help |
@@ -113,15 +113,15 @@
| rnd |
- 50983914 |
+ 50988385 |
| rnd_name |
- 26855 |
+ 26824 |
| rndnz |
- 50573376 |
+ 50578180 |
| rndnz_damage |
@@ -129,7 +129,7 @@
| rndnz_range |
- 31157 |
+ 31195 |
diff --git a/cov/cmdline/mktest.c.gcov.html b/cov/cmdline/mktest.c.gcov.html
index 9ec3a9fa..501823e9 100644
--- a/cov/cmdline/mktest.c.gcov.html
+++ b/cov/cmdline/mktest.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -89,28 +89,28 @@
27 : */
28 : unsigned long long seed = 0;
29 :
- 30 50983914 : unsigned rnd(unsigned max)
+ 30 50988385 : unsigned rnd(unsigned max)
31 : {
- 32 50983914 : seed = seed * 6364136223846793005LL + 1442695040888963407LL;
+ 32 50988385 : seed = seed * 6364136223846793005LL + 1442695040888963407LL;
33 :
- 34 50983914 : return (seed >> 32) % max;
+ 34 50988385 : return (seed >> 32) % max;
35 : }
36 :
- 37 50573376 : unsigned rndnz(unsigned max)
+ 37 50578180 : unsigned rndnz(unsigned max)
38 : {
- 39 50573376 : if (max <= 1)
+ 39 50578180 : if (max <= 1)
40 2831 : return 1;
41 : else
- 42 50570545 : return rnd(max - 1) + 1;
+ 42 50575349 : return rnd(max - 1) + 1;
43 : }
44 :
- 45 31157 : void rndnz_range(unsigned char* data, int size)
+ 45 31195 : void rndnz_range(unsigned char* data, int size)
46 : {
47 : int i;
48 :
- 49 50599273 : for (i = 0; i < size; ++i)
- 50 50568116 : data[i] = rndnz(256);
- 51 31157 : }
+ 49 50604116 : for (i = 0; i < size; ++i)
+ 50 50572921 : data[i] = rndnz(256);
+ 51 31195 : }
52 :
53 1821 : void rndnz_damage(unsigned char* data, int size)
54 : {
@@ -121,8 +121,8 @@
59 : unsigned char c;
60 :
61 : do {
- 62 1829 : c = rndnz(256);
- 63 1829 : } while (c == data[i]);
+ 62 1828 : c = rndnz(256);
+ 63 1828 : } while (c == data[i]);
64 :
65 1821 : data[i] = c;
66 : }
@@ -131,23 +131,23 @@
69 : char CHARSET[] = "qwertyuiopasdfghjklzxcvbnm1234567890 .-+";
70 : #define CHARSET_LEN (sizeof(CHARSET) - 1)
71 :
- 72 26855 : void rnd_name(char* file)
+ 72 26824 : void rnd_name(char* file)
73 : {
- 74 26855 : int l = 1 + rnd(20);
+ 74 26824 : int l = 1 + rnd(20);
75 :
- 76 335689 : while (l) {
- 77 281979 : *file++ = CHARSET[rnd(CHARSET_LEN)];
- 78 281979 : --l;
+ 76 335360 : while (l) {
+ 77 281712 : *file++ = CHARSET[rnd(CHARSET_LEN)];
+ 78 281712 : --l;
79 : }
- 80 26855 : *file = 0;
- 81 26855 : }
+ 80 26824 : *file = 0;
+ 81 26824 : }
82 :
83 : /****************************************************************************/
84 : /* file */
85 :
- 86 146649 : int file_cmp(const void* a, const void* b)
+ 86 146608 : int file_cmp(const void* a, const void* b)
87 : {
- 88 146649 : return strcmp(a, b);
+ 88 146608 : return strcmp(a, b);
89 : }
90 :
91 1821 : int fallback(int f, struct stat* st)
@@ -259,11 +259,11 @@
197 : * Create a symlink.
198 : * - If the file already exists, it's removed.
199 : */
- 200 946 : void cmd_generate_symlink(const char* path, const char* linkto)
+ 200 915 : void cmd_generate_symlink(const char* path, const char* linkto)
201 : {
202 : /* remove the existing file/symlink if any */
- 203 946 : if (remove(path) != 0) {
- 204 925 : if (errno != ENOENT) {
+ 203 915 : if (remove(path) != 0) {
+ 204 894 : if (errno != ENOENT) {
205 : /* LCOV_EXCL_START */
206 : log_fatal("Error removing file %s\n", path);
207 : exit(EXIT_FAILURE);
@@ -271,13 +271,13 @@
209 : }
210 : }
211 :
- 212 946 : if (symlink(linkto, path) != 0) {
+ 212 915 : if (symlink(linkto, path) != 0) {
213 : /* LCOV_EXCL_START */
214 : log_fatal("Error writing symlink %s\n", path);
215 : exit(EXIT_FAILURE);
216 : /* LCOV_EXCL_STOP */
217 : }
- 218 946 : }
+ 218 915 : }
219 :
220 : /**
221 : * Create a file or a symlink with a random name.
@@ -350,68 +350,68 @@
288 : * - The written data may be equal or not at the already existing one.
289 : * - If it's a symlink nothing is done.
290 : */
- 291 4738 : void cmd_write(const char* path, int size)
+ 291 4703 : void cmd_write(const char* path, int size)
292 : {
293 : struct stat st;
294 :
- 295 4738 : if (lstat(path, &st) != 0) {
+ 295 4703 : if (lstat(path, &st) != 0) {
296 : /* LCOV_EXCL_START */
297 : log_fatal("Error accessing %s\n", path);
298 : exit(EXIT_FAILURE);
299 : /* LCOV_EXCL_STOP */
300 : }
301 :
- 302 4738 : if (S_ISREG(st.st_mode)) {
+ 302 4703 : if (S_ISREG(st.st_mode)) {
303 : unsigned char* data;
304 : off_t off;
305 : int f;
306 :
307 : /* not over the end */
- 308 4711 : if (size > st.st_size)
- 309 181 : size = st.st_size;
+ 308 4676 : if (size > st.st_size)
+ 309 179 : size = st.st_size;
310 :
311 : /* start at random position inside the file */
- 312 4711 : if (size < st.st_size)
- 313 4530 : off = rnd(st.st_size - size);
+ 312 4676 : if (size < st.st_size)
+ 313 4496 : off = rnd(st.st_size - size);
314 : else
- 315 181 : off = 0;
+ 315 180 : off = 0;
316 :
- 317 4711 : data = malloc(size);
+ 317 4676 : data = malloc(size);
318 :
- 319 4711 : rndnz_range(data, size);
+ 319 4676 : rndnz_range(data, size);
320 :
- 321 4711 : f = open(path, O_WRONLY | O_BINARY | O_NOFOLLOW);
- 322 4711 : if (f < 0) {
+ 321 4676 : f = open(path, O_WRONLY | O_BINARY | O_NOFOLLOW);
+ 322 4676 : if (f < 0) {
323 : /* LCOV_EXCL_START */
324 : log_fatal("Error creating file %s\n", path);
325 : exit(EXIT_FAILURE);
326 : /* LCOV_EXCL_STOP */
327 : }
328 :
- 329 4711 : if (lseek(f, off, SEEK_SET) != off) {
+ 329 4676 : if (lseek(f, off, SEEK_SET) != off) {
330 : /* LCOV_EXCL_START */
331 : log_fatal("Error seeking file %s\n", path);
332 : exit(EXIT_FAILURE);
333 : /* LCOV_EXCL_STOP */
334 : }
335 :
- 336 4711 : if (write(f, data, size) != size) {
+ 336 4676 : if (write(f, data, size) != size) {
337 : /* LCOV_EXCL_START */
338 : log_fatal("Error writing file %s\n", path);
339 : exit(EXIT_FAILURE);
340 : /* LCOV_EXCL_STOP */
341 : }
342 :
- 343 4711 : if (close(f) != 0) {
+ 343 4676 : if (close(f) != 0) {
344 : /* LCOV_EXCL_START */
345 : log_fatal("Error closing file %s\n", path);
346 : exit(EXIT_FAILURE);
347 : /* LCOV_EXCL_STOP */
348 : }
349 :
- 350 4711 : free(data);
+ 350 4676 : free(data);
351 : }
- 352 4738 : }
+ 352 4703 : }
353 :
354 : /**
355 : * Damage a file.
@@ -518,50 +518,50 @@
456 : * - The file must exist.
457 : * - If it's a symlink nothing is done.
458 : */
- 459 3179 : void cmd_append(const char* path, int size)
+ 459 3252 : void cmd_append(const char* path, int size)
460 : {
461 : struct stat st;
462 :
- 463 3179 : if (lstat(path, &st) != 0) {
+ 463 3252 : if (lstat(path, &st) != 0) {
464 : /* LCOV_EXCL_START */
465 : log_fatal("Error accessing %s\n", path);
466 : exit(EXIT_FAILURE);
467 : /* LCOV_EXCL_STOP */
468 : }
469 :
- 470 3179 : if (S_ISREG(st.st_mode)) {
+ 470 3252 : if (S_ISREG(st.st_mode)) {
471 : unsigned char* data;
472 : int f;
473 :
- 474 3179 : data = malloc(size);
+ 474 3252 : data = malloc(size);
475 :
- 476 3179 : rndnz_range(data, size);
+ 476 3252 : rndnz_range(data, size);
477 :
- 478 3179 : f = open(path, O_WRONLY | O_APPEND | O_BINARY | O_NOFOLLOW);
- 479 3179 : if (f < 0) {
+ 478 3252 : f = open(path, O_WRONLY | O_APPEND | O_BINARY | O_NOFOLLOW);
+ 479 3252 : if (f < 0) {
480 : /* LCOV_EXCL_START */
481 : log_fatal("Error opening file %s\n", path);
482 : exit(EXIT_FAILURE);
483 : /* LCOV_EXCL_STOP */
484 : }
485 :
- 486 3179 : if (write(f, data, size) != size) {
+ 486 3252 : if (write(f, data, size) != size) {
487 : /* LCOV_EXCL_START */
488 : log_fatal("Error writing file %s\n", path);
489 : exit(EXIT_FAILURE);
490 : /* LCOV_EXCL_STOP */
491 : }
492 :
- 493 3179 : if (close(f) != 0) {
+ 493 3252 : if (close(f) != 0) {
494 : /* LCOV_EXCL_START */
495 : log_fatal("Error closing file %s\n", path);
496 : exit(EXIT_FAILURE);
497 : /* LCOV_EXCL_STOP */
498 : }
499 :
- 500 3179 : free(data);
+ 500 3252 : free(data);
501 : }
- 502 3179 : }
+ 502 3252 : }
503 :
504 : /**
505 : * Truncate a file.
@@ -569,69 +569,69 @@
507 : * - The file is NEVER truncated to 0.
508 : * - If it's a symlink nothing is done.
509 : */
- 510 3173 : void cmd_truncate(const char* path, int size)
+ 510 3151 : void cmd_truncate(const char* path, int size)
511 : {
512 : struct stat st;
513 :
- 514 3173 : if (lstat(path, &st) != 0) {
+ 514 3151 : if (lstat(path, &st) != 0) {
515 : /* LCOV_EXCL_START */
516 : log_fatal("Error accessing %s\n", path);
517 : exit(EXIT_FAILURE);
518 : /* LCOV_EXCL_STOP */
519 : }
520 :
- 521 3173 : if (S_ISREG(st.st_mode)) {
+ 521 3151 : if (S_ISREG(st.st_mode)) {
522 : off_t off;
523 : int f;
524 :
525 : /* if file is empty, just rewrite it */
- 526 3173 : if (st.st_size == 0) {
- 527 2 : size = 0;
+ 526 3151 : if (st.st_size == 0) {
+ 527 3 : size = 0;
528 : } else {
529 : /* don't truncate files to 0 size to avoid ZERO file size protection */
- 530 3171 : if (size >= st.st_size)
- 531 171 : size = st.st_size - 1;
+ 530 3148 : if (size >= st.st_size)
+ 531 193 : size = st.st_size - 1;
532 : }
533 :
- 534 3173 : off = st.st_size - size;
+ 534 3151 : off = st.st_size - size;
535 :
- 536 3173 : f = open(path, O_WRONLY | O_BINARY | O_NOFOLLOW);
- 537 3173 : if (f < 0) {
+ 536 3151 : f = open(path, O_WRONLY | O_BINARY | O_NOFOLLOW);
+ 537 3151 : if (f < 0) {
538 : /* LCOV_EXCL_START */
539 : log_fatal("Error opening file %s\n", path);
540 : exit(EXIT_FAILURE);
541 : /* LCOV_EXCL_STOP */
542 : }
543 :
- 544 3173 : if (ftruncate(f, off) != 0) {
+ 544 3151 : if (ftruncate(f, off) != 0) {
545 : /* LCOV_EXCL_START */
546 : log_fatal("Error truncating file %s\n", path);
547 : exit(EXIT_FAILURE);
548 : /* LCOV_EXCL_STOP */
549 : }
550 :
- 551 3173 : if (close(f) != 0) {
+ 551 3151 : if (close(f) != 0) {
552 : /* LCOV_EXCL_START */
553 : log_fatal("Error closing file %s\n", path);
554 : exit(EXIT_FAILURE);
555 : /* LCOV_EXCL_STOP */
556 : }
557 : }
- 558 3173 : }
+ 558 3151 : }
559 :
560 : /**
561 : * Delete a file.
562 : * - The file must exist.
563 : */
- 564 3172 : void cmd_delete(const char* path)
+ 564 3155 : void cmd_delete(const char* path)
565 : {
- 566 3172 : if (remove(path) != 0) {
+ 566 3155 : if (remove(path) != 0) {
567 : /* LCOV_EXCL_START */
568 : log_fatal("Error removing %s\n", path);
569 : exit(EXIT_FAILURE);
570 : /* LCOV_EXCL_STOP */
571 : }
- 572 3172 : }
+ 572 3155 : }
573 :
574 : /**
575 : * Change a file. Or deleted/truncated/append/created.
@@ -642,20 +642,20 @@
580 : struct stat st;
581 :
582 13128 : if (!size)
- 583 13151 : return;
+ 583 13152 : return;
584 :
- 585 13105 : if (lstat(path, &st) != 0) {
+ 585 13104 : if (lstat(path, &st) != 0) {
586 : /* LCOV_EXCL_START */
587 : log_fatal("Error accessing %s\n", path);
588 : exit(EXIT_FAILURE);
589 : /* LCOV_EXCL_STOP */
590 : }
591 :
- 592 13105 : if (S_ISLNK(st.st_mode)) {
+ 592 13104 : if (S_ISLNK(st.st_mode)) {
593 : /* symlink */
594 392 : if (rnd(2) == 0) {
595 : /* delete */
- 596 179 : if (remove(path) != 0) {
+ 596 210 : if (remove(path) != 0) {
597 : /* LCOV_EXCL_START */
598 : log_fatal("Error removing %s\n", path);
599 : exit(EXIT_FAILURE);
@@ -665,30 +665,30 @@
603 : /* recreate */
604 : char linkto[PATH_MAX];
605 :
- 606 213 : if (remove(path) != 0) {
+ 606 182 : if (remove(path) != 0) {
607 : /* LCOV_EXCL_START */
608 : log_fatal("Error removing %s\n", path);
609 : exit(EXIT_FAILURE);
610 : /* LCOV_EXCL_STOP */
611 : }
612 :
- 613 213 : rnd_name(linkto);
+ 613 182 : rnd_name(linkto);
614 :
- 615 213 : cmd_generate_symlink(path, linkto);
+ 615 182 : cmd_generate_symlink(path, linkto);
616 : }
- 617 12713 : } else if (S_ISREG(st.st_mode)) {
+ 617 12712 : } else if (S_ISREG(st.st_mode)) {
618 : int r;
619 :
- 620 12713 : r = rnd(4);
+ 620 12712 : r = rnd(4);
621 :
- 622 12713 : if (r == 0) {
- 623 3189 : cmd_write(path, size);
- 624 9524 : } else if (r == 1) {
- 625 3179 : cmd_append(path, size);
- 626 6345 : } else if (r == 2) {
- 627 3173 : cmd_truncate(path, size);
+ 622 12712 : if (r == 0) {
+ 623 3154 : cmd_write(path, size);
+ 624 9558 : } else if (r == 1) {
+ 625 3252 : cmd_append(path, size);
+ 626 6306 : } else if (r == 2) {
+ 627 3151 : cmd_truncate(path, size);
628 : } else {
- 629 3172 : cmd_delete(path);
+ 629 3155 : cmd_delete(path);
630 : }
631 : }
632 : }
diff --git a/cov/cmdline/murmur3.c.func-sort-c.html b/cov/cmdline/murmur3.c.func-sort-c.html
index e894914b..890c3fb1 100644
--- a/cov/cmdline/murmur3.c.func-sort-c.html
+++ b/cov/cmdline/murmur3.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,11 +61,11 @@
| fmix32 |
- 9010320 |
+ 9010328 |
| MurmurHash3_x86_128 |
- 2252580 |
+ 2252582 |
diff --git a/cov/cmdline/murmur3.c.func.html b/cov/cmdline/murmur3.c.func.html
index 8635275f..749722b4 100644
--- a/cov/cmdline/murmur3.c.func.html
+++ b/cov/cmdline/murmur3.c.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,11 +61,11 @@
| MurmurHash3_x86_128 |
- 2252580 |
+ 2252582 |
| fmix32 |
- 9010320 |
+ 9010328 |
diff --git a/cov/cmdline/murmur3.c.gcov.html b/cov/cmdline/murmur3.c.gcov.html
index 08078433..b92c0ea0 100644
--- a/cov/cmdline/murmur3.c.gcov.html
+++ b/cov/cmdline/murmur3.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -91,14 +91,14 @@
29 : // domain. The author hereby disclaims copyright to this source code.
30 :
31 : /* Finalization mix - force all bits of a hash block to avalanche */
- 32 9010320 : static inline uint32_t fmix32(uint32_t h)
+ 32 9010328 : static inline uint32_t fmix32(uint32_t h)
33 : {
- 34 9010320 : h ^= h >> 16;
- 35 9010320 : h *= 0x85ebca6b;
- 36 9010320 : h ^= h >> 13;
- 37 9010320 : h *= 0xc2b2ae35;
- 38 9010320 : h ^= h >> 16;
- 39 9010320 : return h;
+ 34 9010328 : h ^= h >> 16;
+ 35 9010328 : h *= 0x85ebca6b;
+ 36 9010328 : h ^= h >> 13;
+ 37 9010328 : h *= 0xc2b2ae35;
+ 38 9010328 : h ^= h >> 16;
+ 39 9010328 : return h;
40 : }
41 :
42 : /*
@@ -137,17 +137,17 @@
75 : uint32_t c3 = 0x38b34ae5;
76 : uint32_t c4 = 0xa1e38b93;
77 :
- 78 2252580 : void MurmurHash3_x86_128(const void* data, size_t size, const uint8_t* seed, void* digest)
+ 78 2252582 : void MurmurHash3_x86_128(const void* data, size_t size, const uint8_t* seed, void* digest)
79 : {
80 : size_t nblocks;
81 : const uint32_t* blocks;
82 : const uint32_t* end;
83 : size_t size_remainder;
84 :
- 85 2252580 : uint32_t h1 = ((const uint32_t*)seed)[0];
- 86 2252580 : uint32_t h2 = ((const uint32_t*)seed)[1];
- 87 2252580 : uint32_t h3 = ((const uint32_t*)seed)[2];
- 88 2252580 : uint32_t h4 = ((const uint32_t*)seed)[3];
+ 85 2252582 : uint32_t h1 = ((const uint32_t*)seed)[0];
+ 86 2252582 : uint32_t h2 = ((const uint32_t*)seed)[1];
+ 87 2252582 : uint32_t h3 = ((const uint32_t*)seed)[2];
+ 88 2252582 : uint32_t h4 = ((const uint32_t*)seed)[3];
89 :
90 : #if WORDS_BIGENDIAN
91 : h1 = util_swap32(h1);
@@ -156,16 +156,16 @@
94 : h4 = util_swap32(h4);
95 : #endif
96 :
- 97 2252580 : nblocks = size / 16;
- 98 2252580 : blocks = data;
- 99 2252580 : end = blocks + nblocks * 4;
+ 97 2252582 : nblocks = size / 16;
+ 98 2252582 : blocks = data;
+ 99 2252582 : end = blocks + nblocks * 4;
100 :
101 : /* body */
- 102 119858362 : while (blocks < end) {
- 103 115353202 : uint32_t k1 = blocks[0];
- 104 115353202 : uint32_t k2 = blocks[1];
- 105 115353202 : uint32_t k3 = blocks[2];
- 106 115353202 : uint32_t k4 = blocks[3];
+ 102 119857435 : while (blocks < end) {
+ 103 115352271 : uint32_t k1 = blocks[0];
+ 104 115352271 : uint32_t k2 = blocks[1];
+ 105 115352271 : uint32_t k3 = blocks[2];
+ 106 115352271 : uint32_t k4 = blocks[3];
107 :
108 : #if WORDS_BIGENDIAN
109 : k1 = util_swap32(k1);
@@ -174,71 +174,71 @@
112 : k4 = util_swap32(k4);
113 : #endif
114 :
- 115 115353202 : k1 *= c1; k1 = util_rotl32(k1, 15); k1 *= c2; h1 ^= k1;
+ 115 115352271 : k1 *= c1; k1 = util_rotl32(k1, 15); k1 *= c2; h1 ^= k1;
116 :
- 117 115353202 : h1 = util_rotl32(h1, 19); h1 += h2; h1 = h1 * 5 + 0x561ccd1b;
+ 117 115352271 : h1 = util_rotl32(h1, 19); h1 += h2; h1 = h1 * 5 + 0x561ccd1b;
118 :
- 119 115353202 : k2 *= c2; k2 = util_rotl32(k2, 16); k2 *= c3; h2 ^= k2;
+ 119 115352271 : k2 *= c2; k2 = util_rotl32(k2, 16); k2 *= c3; h2 ^= k2;
120 :
- 121 115353202 : h2 = util_rotl32(h2, 17); h2 += h3; h2 = h2 * 5 + 0x0bcaa747;
+ 121 115352271 : h2 = util_rotl32(h2, 17); h2 += h3; h2 = h2 * 5 + 0x0bcaa747;
122 :
- 123 115353202 : k3 *= c3; k3 = util_rotl32(k3, 17); k3 *= c4; h3 ^= k3;
+ 123 115352271 : k3 *= c3; k3 = util_rotl32(k3, 17); k3 *= c4; h3 ^= k3;
124 :
- 125 115353202 : h3 = util_rotl32(h3, 15); h3 += h4; h3 = h3 * 5 + 0x96cd1c35;
+ 125 115352271 : h3 = util_rotl32(h3, 15); h3 += h4; h3 = h3 * 5 + 0x96cd1c35;
126 :
- 127 115353202 : k4 *= c4; k4 = util_rotl32(k4, 18); k4 *= c1; h4 ^= k4;
+ 127 115352271 : k4 *= c4; k4 = util_rotl32(k4, 18); k4 *= c1; h4 ^= k4;
128 :
- 129 115353202 : h4 = util_rotl32(h4, 13); h4 += h1; h4 = h4 * 5 + 0x32ac3b17;
+ 129 115352271 : h4 = util_rotl32(h4, 13); h4 += h1; h4 = h4 * 5 + 0x32ac3b17;
130 :
- 131 115353202 : blocks += 4;
+ 131 115352271 : blocks += 4;
132 : }
133 :
134 : /* tail */
- 135 2252580 : size_remainder = size & 15;
- 136 2252580 : if (size_remainder != 0) {
- 137 848217 : const uint8_t* tail = (const uint8_t*)blocks;
+ 135 2252582 : size_remainder = size & 15;
+ 136 2252582 : if (size_remainder != 0) {
+ 137 848153 : const uint8_t* tail = (const uint8_t*)blocks;
138 :
- 139 848217 : uint32_t k1 = 0;
- 140 848217 : uint32_t k2 = 0;
- 141 848217 : uint32_t k3 = 0;
- 142 848217 : uint32_t k4 = 0;
+ 139 848153 : uint32_t k1 = 0;
+ 140 848153 : uint32_t k2 = 0;
+ 141 848153 : uint32_t k3 = 0;
+ 142 848153 : uint32_t k4 = 0;
143 :
- 144 848217 : switch (size_remainder) {
- 145 55797 : case 15 : k4 ^= tail[14] << 16;
- 146 112943 : case 14 : k4 ^= tail[13] << 8;
- 147 170169 : case 13 : k4 ^= tail[12] << 0;
- 148 170169 : k4 *= c4; k4 = util_rotl32(k4, 18); k4 *= c1; h4 ^= k4;
- 149 227575 : case 12 : k3 ^= tail[11] << 24;
- 150 284886 : case 11 : k3 ^= tail[10] << 16;
- 151 341909 : case 10 : k3 ^= tail[ 9] << 8;
- 152 400365 : case 9 : k3 ^= tail[ 8] << 0;
- 153 400365 : k3 *= c3; k3 = util_rotl32(k3, 17); k3 *= c4; h3 ^= k3;
- 154 458648 : case 8 : k2 ^= tail[ 7] << 24;
- 155 512723 : case 7 : k2 ^= tail[ 6] << 16;
- 156 569585 : case 6 : k2 ^= tail[ 5] << 8;
- 157 624551 : case 5 : k2 ^= tail[ 4] << 0;
- 158 624551 : k2 *= c2; k2 = util_rotl32(k2, 16); k2 *= c3; h2 ^= k2;
- 159 680593 : case 4 : k1 ^= tail[ 3] << 24;
- 160 735635 : case 3 : k1 ^= tail[ 2] << 16;
- 161 791529 : case 2 : k1 ^= tail[ 1] << 8;
- 162 848217 : case 1 : k1 ^= tail[ 0] << 0;
- 163 848217 : k1 *= c1; k1 = util_rotl32(k1, 15); k1 *= c2; h1 ^= k1;
+ 144 848153 : switch (size_remainder) {
+ 145 55834 : case 15 : k4 ^= tail[14] << 16;
+ 146 112972 : case 14 : k4 ^= tail[13] << 8;
+ 147 170132 : case 13 : k4 ^= tail[12] << 0;
+ 148 170132 : k4 *= c4; k4 = util_rotl32(k4, 18); k4 *= c1; h4 ^= k4;
+ 149 227529 : case 12 : k3 ^= tail[11] << 24;
+ 150 284808 : case 11 : k3 ^= tail[10] << 16;
+ 151 341803 : case 10 : k3 ^= tail[ 9] << 8;
+ 152 400242 : case 9 : k3 ^= tail[ 8] << 0;
+ 153 400242 : k3 *= c3; k3 = util_rotl32(k3, 17); k3 *= c4; h3 ^= k3;
+ 154 458531 : case 8 : k2 ^= tail[ 7] << 24;
+ 155 512645 : case 7 : k2 ^= tail[ 6] << 16;
+ 156 569544 : case 6 : k2 ^= tail[ 5] << 8;
+ 157 624516 : case 5 : k2 ^= tail[ 4] << 0;
+ 158 624516 : k2 *= c2; k2 = util_rotl32(k2, 16); k2 *= c3; h2 ^= k2;
+ 159 680502 : case 4 : k1 ^= tail[ 3] << 24;
+ 160 735518 : case 3 : k1 ^= tail[ 2] << 16;
+ 161 791435 : case 2 : k1 ^= tail[ 1] << 8;
+ 162 848153 : case 1 : k1 ^= tail[ 0] << 0;
+ 163 848153 : k1 *= c1; k1 = util_rotl32(k1, 15); k1 *= c2; h1 ^= k1;
164 : }
165 : }
166 :
167 : /* finalization */
- 168 2252580 : h1 ^= size; h2 ^= size; h3 ^= size; h4 ^= size;
+ 168 2252582 : h1 ^= size; h2 ^= size; h3 ^= size; h4 ^= size;
169 :
- 170 2252580 : h1 += h2; h1 += h3; h1 += h4;
- 171 2252580 : h2 += h1; h3 += h1; h4 += h1;
+ 170 2252582 : h1 += h2; h1 += h3; h1 += h4;
+ 171 2252582 : h2 += h1; h3 += h1; h4 += h1;
172 :
- 173 2252580 : h1 = fmix32(h1);
- 174 2252580 : h2 = fmix32(h2);
- 175 2252580 : h3 = fmix32(h3);
- 176 2252580 : h4 = fmix32(h4);
+ 173 2252582 : h1 = fmix32(h1);
+ 174 2252582 : h2 = fmix32(h2);
+ 175 2252582 : h3 = fmix32(h3);
+ 176 2252582 : h4 = fmix32(h4);
177 :
- 178 2252580 : h1 += h2; h1 += h3; h1 += h4;
- 179 2252580 : h2 += h1; h3 += h1; h4 += h1;
+ 178 2252582 : h1 += h2; h1 += h3; h1 += h4;
+ 179 2252582 : h2 += h1; h3 += h1; h4 += h1;
180 :
181 : #if WORDS_BIGENDIAN
182 : h1 = util_swap32(h1);
@@ -247,11 +247,11 @@
185 : h4 = util_swap32(h4);
186 : #endif
187 :
- 188 2252580 : ((uint32_t*)digest)[0] = h1;
- 189 2252580 : ((uint32_t*)digest)[1] = h2;
- 190 2252580 : ((uint32_t*)digest)[2] = h3;
- 191 2252580 : ((uint32_t*)digest)[3] = h4;
- 192 2252580 : }
+ 188 2252582 : ((uint32_t*)digest)[0] = h1;
+ 189 2252582 : ((uint32_t*)digest)[1] = h2;
+ 190 2252582 : ((uint32_t*)digest)[2] = h3;
+ 191 2252582 : ((uint32_t*)digest)[3] = h4;
+ 192 2252582 : }
193 :
diff --git a/cov/cmdline/nano.c.func-sort-c.html b/cov/cmdline/nano.c.func-sort-c.html
index ddd04821..86954774 100644
--- a/cov/cmdline/nano.c.func-sort-c.html
+++ b/cov/cmdline/nano.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/cmdline/nano.c.func.html b/cov/cmdline/nano.c.func.html
index 30b1558c..0a3357e1 100644
--- a/cov/cmdline/nano.c.func.html
+++ b/cov/cmdline/nano.c.func.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/cmdline/nano.c.gcov.html b/cov/cmdline/nano.c.gcov.html
index 491f4805..931ad05d 100644
--- a/cov/cmdline/nano.c.gcov.html
+++ b/cov/cmdline/nano.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -96,13 +96,13 @@
34 : tommy_node* j;
35 :
36 : /* for all files */
- 37 5723 : for (j = disk->filelist; j != 0; j = j->next) {
- 38 5717 : struct snapraid_file* file = j->data;
+ 37 5724 : for (j = disk->filelist; j != 0; j = j->next) {
+ 38 5718 : struct snapraid_file* file = j->data;
39 :
40 : /* if the file has a zero nanosecond timestamp */
41 : /* note that symbolic links are not in the file list */
42 : /* and then are not processed */
- 43 5717 : if (file->mtime_nsec == 0) {
+ 43 5718 : if (file->mtime_nsec == 0) {
44 : char path[PATH_MAX];
45 : struct stat st;
46 : int f;
diff --git a/cov/cmdline/parity.c.func-sort-c.html b/cov/cmdline/parity.c.func-sort-c.html
index 61e63a23..862a0682 100644
--- a/cov/cmdline/parity.c.func-sort-c.html
+++ b/cov/cmdline/parity.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,11 +61,11 @@
| parity_read |
- 3488589 |
+ 3488577 |
| parity_write |
- 505320 |
+ 506040 |
| parity_close |
diff --git a/cov/cmdline/parity.c.func.html b/cov/cmdline/parity.c.func.html
index 210ad1cd..700c0fe6 100644
--- a/cov/cmdline/parity.c.func.html
+++ b/cov/cmdline/parity.c.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -89,7 +89,7 @@
| parity_read |
- 3488589 |
+ 3488577 |
| parity_sync |
@@ -101,7 +101,7 @@
| parity_write |
- 505320 |
+ 506040 |
diff --git a/cov/cmdline/parity.c.gcov.html b/cov/cmdline/parity.c.gcov.html
index 86619b84..6ebacc6b 100644
--- a/cov/cmdline/parity.c.gcov.html
+++ b/cov/cmdline/parity.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -129,8 +129,8 @@
67 431 : block_off_t block = disk_size(disk);
68 :
69 : /* decrease the block until an used one */
- 70 221703 : while (block > parity_block && !block_has_file_and_valid_parity(fs_par2block_get(disk, block - 1)))
- 71 220841 : --block;
+ 70 221700 : while (block > parity_block && !block_has_file_and_valid_parity(fs_par2block_get(disk, block - 1)))
+ 71 220838 : --block;
72 :
73 : /* get the highest value */
74 431 : if (block > parity_block)
@@ -486,15 +486,15 @@
424 952 : return 0;
425 : }
426 :
- 427 505320 : int parity_write(struct snapraid_parity_handle* parity, block_off_t pos, unsigned char* block_buffer, unsigned block_size)
+ 427 506040 : int parity_write(struct snapraid_parity_handle* parity, block_off_t pos, unsigned char* block_buffer, unsigned block_size)
428 : {
429 : ssize_t write_ret;
430 : data_off_t offset;
431 :
- 432 505320 : offset = pos * (data_off_t)block_size;
+ 432 506040 : offset = pos * (data_off_t)block_size;
433 :
434 : #if HAVE_PWRITE
- 435 505320 : write_ret = pwrite(parity->f, block_buffer, block_size, offset);
+ 435 506040 : write_ret = pwrite(parity->f, block_buffer, block_size, offset);
436 : #else
437 : if (lseek(parity->f, offset, SEEK_SET) != offset) {
438 : /* LCOV_EXCL_START */
@@ -509,7 +509,7 @@
447 :
448 : write_ret = write(parity->f, block_buffer, block_size);
449 : #endif
- 450 505320 : if (write_ret != (ssize_t)block_size) { /* conversion is safe because block_size is always small */
+ 450 506040 : if (write_ret != (ssize_t)block_size) { /* conversion is safe because block_size is always small */
451 : /* LCOV_EXCL_START */
452 : if (errno == ENOSPC) {
453 : log_fatal("Failed to grow parity file '%s' using write due lack of space.\n", parity->path);
@@ -521,26 +521,26 @@
459 : }
460 :
461 : /* adjust the size of the valid data */
- 462 505320 : if (parity->valid_size < offset + block_size) {
+ 462 506040 : if (parity->valid_size < offset + block_size) {
463 170559 : parity->valid_size = offset + block_size;
464 : }
465 :
466 : /* Here doesn't make sense to call posix_fadvise(..., POSIX_FADV_DONTNEED) because */
467 : /* at this time the data is still in not yet written and it cannot be discharged. */
468 :
- 469 505320 : return 0;
+ 469 506040 : return 0;
470 : }
471 :
- 472 3488589 : int parity_read(struct snapraid_parity_handle* parity, block_off_t pos, unsigned char* block_buffer, unsigned block_size, fptr* out)
+ 472 3488577 : int parity_read(struct snapraid_parity_handle* parity, block_off_t pos, unsigned char* block_buffer, unsigned block_size, fptr* out)
473 : {
474 : ssize_t read_ret;
475 : data_off_t offset;
476 : unsigned count;
477 :
- 478 3488589 : offset = pos * (data_off_t)block_size;
+ 478 3488577 : offset = pos * (data_off_t)block_size;
479 :
480 : /* check if we are going to read only not initialized data */
- 481 3488589 : if (offset >= parity->valid_size) {
+ 481 3488577 : if (offset >= parity->valid_size) {
482 90275 : out("Reading missing data from file '%s' at offset %" PRIu64 ".\n", parity->path, offset);
483 90275 : return -1;
484 : }
@@ -554,36 +554,36 @@
492 : }
493 : #endif
494 :
- 495 3398314 : count = 0;
+ 495 3398302 : count = 0;
496 : do {
497 :
498 : #if HAVE_PREAD
- 499 3398314 : read_ret = pread(parity->f, block_buffer + count, block_size - count, offset + count);
+ 499 3398302 : read_ret = pread(parity->f, block_buffer + count, block_size - count, offset + count);
500 : #else
501 : read_ret = read(parity->f, block_buffer + count, block_size - count);
502 : #endif
- 503 3398314 : if (read_ret < 0) {
+ 503 3398302 : if (read_ret < 0) {
504 : /* LCOV_EXCL_START */
505 : out("Error reading file '%s' at offset %" PRIu64 " for size %u. %s.\n", parity->path, offset + count, block_size - count, strerror(errno));
506 : return -1;
507 : /* LCOV_EXCL_STOP */
508 : }
- 509 3398314 : if (read_ret == 0) {
+ 509 3398302 : if (read_ret == 0) {
510 : /* LCOV_EXCL_START */
511 : out("Unexpected end of file '%s' at offset %" PRIu64 ". %s.\n", parity->path, offset, strerror(errno));
512 : return -1;
513 : /* LCOV_EXCL_STOP */
514 : }
515 :
- 516 3398314 : count += read_ret;
- 517 3398314 : } while (count < block_size);
+ 516 3398302 : count += read_ret;
+ 517 3398302 : } while (count < block_size);
518 :
519 : /* Here isn't needed to call posix_fadvise(..., POSIX_FADV_DONTNEED) */
520 : /* because we already advised sequential access with POSIX_FADV_SEQUENTIAL. */
521 : /* In Linux 2.6.33 it's enough to ensure that data is not kept in the cache. */
522 : /* Better to do nothing and save a syscall for each block. */
523 :
- 524 3398314 : return block_size;
+ 524 3398302 : return block_size;
525 : }
526 :
diff --git a/cov/cmdline/pool.c.func-sort-c.html b/cov/cmdline/pool.c.func-sort-c.html
index ae0e893b..745f72a1 100644
--- a/cov/cmdline/pool.c.func-sort-c.html
+++ b/cov/cmdline/pool.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,7 +61,7 @@
| make_link |
- 17567 |
+ 17569 |
| clean_dir |
diff --git a/cov/cmdline/pool.c.func.html b/cov/cmdline/pool.c.func.html
index 7b8e4a5b..6a1d2ec3 100644
--- a/cov/cmdline/pool.c.func.html
+++ b/cov/cmdline/pool.c.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -65,7 +65,7 @@
| make_link |
- 17567 |
+ 17569 |
| state_pool |
diff --git a/cov/cmdline/pool.c.gcov.html b/cov/cmdline/pool.c.gcov.html
index 2cc7b271..233bc037 100644
--- a/cov/cmdline/pool.c.gcov.html
+++ b/cov/cmdline/pool.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -107,24 +107,24 @@
45 : struct dirent* dd;
46 :
47 : /* clear errno to detect erroneous conditions */
- 48 5759 : errno = 0;
- 49 5759 : dd = readdir(d);
- 50 5759 : if (dd == 0 && errno != 0) {
+ 48 5760 : errno = 0;
+ 49 5760 : dd = readdir(d);
+ 50 5760 : if (dd == 0 && errno != 0) {
51 : /* LCOV_EXCL_START */
52 : log_fatal("Error reading pool directory '%s'. %s.\n", dir, strerror(errno));
53 : exit(EXIT_FAILURE);
54 : /* LCOV_EXCL_STOP */
55 : }
- 56 5759 : if (dd == 0 && errno == 0) {
+ 56 5760 : if (dd == 0 && errno == 0) {
57 5 : break; /* finished */
58 : }
59 :
60 : /* skip "." and ".." files */
- 61 5754 : name = dd->d_name;
- 62 5754 : if (name[0] == '.' && (name[1] == 0 || (name[1] == '.' && name[2] == 0)))
+ 61 5755 : name = dd->d_name;
+ 62 5755 : if (name[0] == '.' && (name[1] == 0 || (name[1] == '.' && name[2] == 0)))
63 10 : continue;
64 :
- 65 5744 : pathprint(path_next, sizeof(path_next), "%s%s", dir, name);
+ 65 5745 : pathprint(path_next, sizeof(path_next), "%s%s", dir, name);
66 :
67 : #if HAVE_STRUCT_DIRENT_D_STAT
68 : /* convert dirent to lstat result */
@@ -142,7 +142,7 @@
80 : }
81 : #else
82 : /* get lstat info about the file */
- 83 5744 : if (lstat(path_next, &st) != 0) {
+ 83 5745 : if (lstat(path_next, &st) != 0) {
84 : /* LCOV_EXCL_START */
85 : log_fatal("Error in stat file/directory '%s'. %s.\n", path_next, strerror(errno));
86 : exit(EXIT_FAILURE);
@@ -150,12 +150,12 @@
88 : }
89 : #endif
90 :
- 91 5744 : if (S_ISLNK(st.st_mode)) {
+ 91 5745 : if (S_ISLNK(st.st_mode)) {
92 : int ret;
93 :
94 : /* delete the link */
- 95 5742 : ret = remove(path_next);
- 96 5742 : if (ret < 0) {
+ 95 5743 : ret = remove(path_next);
+ 96 5743 : if (ret < 0) {
97 : /* LCOV_EXCL_START */
98 : log_fatal("Error removing symlink '%s'. %s.\n", path_next, strerror(errno));
99 : exit(EXIT_FAILURE);
@@ -194,7 +194,7 @@
132 0 : ignored = 1;
133 0 : msg_verbose("Ignoring pool file '%s'\n", path_next);
134 : }
- 135 5754 : }
+ 135 5755 : }
136 :
137 5 : if (closedir(d) != 0) {
138 : /* LCOV_EXCL_START */
@@ -209,7 +209,7 @@
147 : /**
148 : * Create a link to the specified disk entry.
149 : */
- 150 17567 : static void make_link(const char* pool_dir, const char* share_dir, struct snapraid_disk* disk, const char* sub)
+ 150 17569 : static void make_link(const char* pool_dir, const char* share_dir, struct snapraid_disk* disk, const char* sub)
151 : {
152 : char path[PATH_MAX];
153 : char linkto[PATH_MAX];
@@ -217,31 +217,31 @@
155 : int ret;
156 :
157 : /* make the source path */
- 158 17567 : pathprint(path, sizeof(path), "%s%s", pool_dir, sub);
+ 158 17569 : pathprint(path, sizeof(path), "%s%s", pool_dir, sub);
159 :
160 : /* make the linkto path */
- 161 17567 : if (share_dir[0] != 0) {
+ 161 17569 : if (share_dir[0] != 0) {
162 : /* with a shared directory, use it */
- 163 17567 : pathprint(linkto, sizeof(linkto), "%s%s/%s", share_dir, disk->name, sub);
+ 163 17569 : pathprint(linkto, sizeof(linkto), "%s%s/%s", share_dir, disk->name, sub);
164 : } else {
165 : /* without a share directory, use the local disk paths */
166 0 : pathprint(linkto, sizeof(linkto), "%s%s", disk->dir, sub);
167 : }
168 :
169 : /* create the ancestor directories */
- 170 17567 : ret = mkancestor(path);
- 171 17567 : if (ret != 0) {
+ 170 17569 : ret = mkancestor(path);
+ 171 17569 : if (ret != 0) {
172 : /* LCOV_EXCL_START */
173 : exit(EXIT_FAILURE);
174 : /* LCOV_EXCL_STOP */
175 : }
176 :
177 : /* convert back slashes */
- 178 17567 : pathexport(linkto_exported, sizeof(linkto_exported), linkto);
+ 178 17569 : pathexport(linkto_exported, sizeof(linkto_exported), linkto);
179 :
180 : /* create the symlink */
- 181 17567 : ret = symlink(linkto_exported, path);
- 182 17567 : if (ret != 0) {
+ 181 17569 : ret = symlink(linkto_exported, path);
+ 182 17569 : if (ret != 0) {
183 517 : if (errno == EEXIST) {
184 517 : log_fatal("WARNING! Duplicate pooling for '%s'\n", path);
185 : #ifdef _WIN32
@@ -258,7 +258,7 @@
196 : /* LCOV_EXCL_STOP */
197 : }
198 : }
- 199 17567 : }
+ 199 17569 : }
200 :
201 3 : void state_pool(struct snapraid_state* state)
202 : {
@@ -296,10 +296,10 @@
234 18 : struct snapraid_disk* disk = i->data;
235 :
236 : /* for each file */
- 237 16996 : for (j = disk->filelist; j != 0; j = j->next) {
- 238 16978 : struct snapraid_file* file = j->data;
- 239 16978 : make_link(pool_dir, share_dir, disk, file->sub);
- 240 16978 : ++count;
+ 237 16998 : for (j = disk->filelist; j != 0; j = j->next) {
+ 238 16980 : struct snapraid_file* file = j->data;
+ 239 16980 : make_link(pool_dir, share_dir, disk, file->sub);
+ 240 16980 : ++count;
241 : }
242 :
243 : /* for each link */
diff --git a/cov/cmdline/portable.h.func-sort-c.html b/cov/cmdline/portable.h.func-sort-c.html
index 465a1c04..4b66bf09 100644
--- a/cov/cmdline/portable.h.func-sort-c.html
+++ b/cov/cmdline/portable.h.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/cmdline/portable.h.func.html b/cov/cmdline/portable.h.func.html
index 6872e429..ee3455ec 100644
--- a/cov/cmdline/portable.h.func.html
+++ b/cov/cmdline/portable.h.func.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/cmdline/portable.h.gcov.html b/cov/cmdline/portable.h.gcov.html
index 32c8c93d..5cb42125 100644
--- a/cov/cmdline/portable.h.gcov.html
+++ b/cov/cmdline/portable.h.gcov.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/cmdline/rehash.c.func-sort-c.html b/cov/cmdline/rehash.c.func-sort-c.html
index 2866182b..7f91b7d7 100644
--- a/cov/cmdline/rehash.c.func-sort-c.html
+++ b/cov/cmdline/rehash.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/cmdline/rehash.c.func.html b/cov/cmdline/rehash.c.func.html
index 53664a3e..4f50c788 100644
--- a/cov/cmdline/rehash.c.func.html
+++ b/cov/cmdline/rehash.c.func.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/cmdline/rehash.c.gcov.html b/cov/cmdline/rehash.c.gcov.html
index cdc16ba4..66b8ba99 100644
--- a/cov/cmdline/rehash.c.gcov.html
+++ b/cov/cmdline/rehash.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/cmdline/scan.c.func-sort-c.html b/cov/cmdline/scan.c.func-sort-c.html
index 86358b8f..c14fca19 100644
--- a/cov/cmdline/scan.c.func-sort-c.html
+++ b/cov/cmdline/scan.c.func-sort-c.html
@@ -31,13 +31,13 @@
|
-
-
-
+
+
+
-
+
|
@@ -60,59 +60,59 @@
Hit count  |
- | dd_name_compare |
- 10485267 |
+ dd_name_compare |
+ 10485497 |
- | dstat |
- 1004147 |
+ dstat |
+ 1004217 |
- | scan_file |
- 1003012 |
+ scan_file |
+ 1003082 |
- | scan_file_keep |
- 923695 |
+ scan_file_keep |
+ 923721 |
- | file_is_full_invalid_parity_and_stable |
- 923695 |
+ file_is_full_invalid_parity_and_stable |
+ 923721 |
- | dd_ino_compare |
- 103300 |
+ dd_ino_compare |
+ 103314 |
- | scan_file_delayed_allocate |
- 100930 |
+ scan_file_delayed_allocate |
+ 100975 |
- | scan_file_insert |
- 100930 |
+ scan_file_insert |
+ 100975 |
| scan_file_allocate |
- 100930 |
+ 100975 |
- | scan_file_refresh |
- 79146 |
+ scan_file_refresh |
+ 79190 |
- | scan_file_remove |
- 56098 |
+ scan_file_remove |
+ 56139 |
- | scan_file_deallocate |
- 56098 |
+ scan_file_deallocate |
+ 56139 |
| scan_link |
32837 |
- | file_is_full_hashed_and_stable |
+ file_is_full_hashed_and_stable |
23659 |
@@ -120,7 +120,7 @@
| 2457 |
- | scan_dir |
+ scan_dir |
1614 |
@@ -128,27 +128,27 @@
| 956 |
- | scan_emptydir |
+ scan_emptydir |
227 |
- | state_diffscan |
+ state_diffscan |
80 |
- | state_scan |
+ state_scan |
73 |
- | scan_emptydir_insert |
+ scan_emptydir_insert |
10 |
- | state_diff |
+ state_diff |
7 |
- | scan_emptydir_remove |
+ scan_emptydir_remove |
2 |
diff --git a/cov/cmdline/scan.c.func.html b/cov/cmdline/scan.c.func.html
index 7cf7f8dd..abe27914 100644
--- a/cov/cmdline/scan.c.func.html
+++ b/cov/cmdline/scan.c.func.html
@@ -31,13 +31,13 @@
|
-
-
-
+
+
+
-
+
|
@@ -60,72 +60,72 @@
Hit count  |
- | dd_ino_compare |
- 103300 |
+ dd_ino_compare |
+ 103314 |
- | dd_name_compare |
- 10485267 |
+ dd_name_compare |
+ 10485497 |
- | dstat |
- 1004147 |
+ dstat |
+ 1004217 |
- | file_is_full_hashed_and_stable |
+ file_is_full_hashed_and_stable |
23659 |
- | file_is_full_invalid_parity_and_stable |
- 923695 |
+ file_is_full_invalid_parity_and_stable |
+ 923721 |
- | scan_dir |
+ scan_dir |
1614 |
- | scan_emptydir |
+ scan_emptydir |
227 |
- | scan_emptydir_insert |
+ scan_emptydir_insert |
10 |
- | scan_emptydir_remove |
+ scan_emptydir_remove |
2 |
- | scan_file |
- 1003012 |
+ scan_file |
+ 1003082 |
| scan_file_allocate |
- 100930 |
+ 100975 |
- | scan_file_deallocate |
- 56098 |
+ scan_file_deallocate |
+ 56139 |
- | scan_file_delayed_allocate |
- 100930 |
+ scan_file_delayed_allocate |
+ 100975 |
- | scan_file_insert |
- 100930 |
+ scan_file_insert |
+ 100975 |
- | scan_file_keep |
- 923695 |
+ scan_file_keep |
+ 923721 |
- | scan_file_refresh |
- 79146 |
+ scan_file_refresh |
+ 79190 |
- | scan_file_remove |
- 56098 |
+ scan_file_remove |
+ 56139 |
| scan_link |
@@ -140,15 +140,15 @@
956 |
- | state_diff |
+ state_diff |
7 |
- | state_diffscan |
+ state_diffscan |
80 |
- | state_scan |
+ state_scan |
73 |
diff --git a/cov/cmdline/scan.c.gcov.html b/cov/cmdline/scan.c.gcov.html
index a8ad50c7..28c662b0 100644
--- a/cov/cmdline/scan.c.gcov.html
+++ b/cov/cmdline/scan.c.gcov.html
@@ -31,13 +31,13 @@
|
-
-
-
+
+
+
-
+
|
@@ -219,72 +219,72 @@
157 : /**
158 : * Insert the specified file in the parity.
159 : */
- 160 100930 : static void scan_file_allocate(struct snapraid_scan* scan, struct snapraid_file* file)
+ 160 100975 : static void scan_file_allocate(struct snapraid_scan* scan, struct snapraid_file* file)
161 : {
- 162 100930 : struct snapraid_state* state = scan->state;
- 163 100930 : struct snapraid_disk* disk = scan->disk;
+ 162 100975 : struct snapraid_state* state = scan->state;
+ 163 100975 : struct snapraid_disk* disk = scan->disk;
164 : block_off_t i;
165 : block_off_t parity_pos;
166 :
167 : /* state changed */
- 168 100930 : state->need_write = 1;
+ 168 100975 : state->need_write = 1;
169 :
170 : /* allocate the blocks of the file */
- 171 100930 : parity_pos = disk->first_free_block;
- 172 349520 : for (i = 0; i < file->blockmax; ++i) {
+ 171 100975 : parity_pos = disk->first_free_block;
+ 172 349689 : for (i = 0; i < file->blockmax; ++i) {
173 : struct snapraid_block* block;
174 : struct snapraid_block* over_block;
175 : snapraid_info info;
176 :
177 : /* increment the position until the first really free block */
- 178 1013272 : while (block_has_file(fs_par2block_get(disk, parity_pos)))
- 179 516092 : ++parity_pos;
+ 178 1013456 : while (block_has_file(fs_par2block_get(disk, parity_pos)))
+ 179 516028 : ++parity_pos;
180 :
181 : /* get block we are going to overwrite, if any */
- 182 248590 : over_block = fs_par2block_get(disk, parity_pos);
+ 182 248714 : over_block = fs_par2block_get(disk, parity_pos);
183 :
184 : /* deallocate it */
- 185 248590 : if (over_block != BLOCK_EMPTY)
- 186 92965 : fs_deallocate(disk, parity_pos);
+ 185 248714 : if (over_block != BLOCK_EMPTY)
+ 186 93089 : fs_deallocate(disk, parity_pos);
187 :
188 : /* get block specific info */
- 189 248590 : info = info_get(&state->infoarr, parity_pos);
+ 189 248714 : info = info_get(&state->infoarr, parity_pos);
190 :
191 : /* get the new block we are going to write */
- 192 248590 : block = fs_file2block_get(file, i);
+ 192 248714 : block = fs_file2block_get(file, i);
193 :
194 : /* if the file block already has an updated hash without rehash */
- 195 248590 : if (block_has_updated_hash(block) && !info_get_rehash(info)) {
+ 195 248714 : if (block_has_updated_hash(block) && !info_get_rehash(info)) {
196 : /* the only possible case is for REP blocks */
- 197 37266 : assert(block_state_get(block) == BLOCK_STATE_REP);
+ 197 37269 : assert(block_state_get(block) == BLOCK_STATE_REP);
198 :
199 : /* convert to a REP block */
- 200 37266 : block_state_set(block, BLOCK_STATE_REP);
+ 200 37269 : block_state_set(block, BLOCK_STATE_REP);
201 :
202 : /* and keep the hash as it's */
203 : } else {
204 : unsigned over_state;
205 :
206 : /* convert to a CHG block */
- 207 211324 : block_state_set(block, BLOCK_STATE_CHG);
+ 207 211445 : block_state_set(block, BLOCK_STATE_CHG);
208 :
209 : /* state of the block we are going to overwrite */
- 210 211324 : over_state = block_state_get(over_block);
+ 210 211445 : over_state = block_state_get(over_block);
211 :
212 : /* if the block is an empty one */
- 213 211324 : if (over_state == BLOCK_STATE_EMPTY) {
+ 213 211445 : if (over_state == BLOCK_STATE_EMPTY) {
214 : /* the block was empty and filled with zeros */
215 : /* set the hash to the special ZERO value */
216 153288 : hash_zero_set(block->hash);
217 : } else {
218 : /* otherwise it's a DELETED one */
- 219 58036 : assert(over_state == BLOCK_STATE_DELETED);
+ 219 58157 : assert(over_state == BLOCK_STATE_DELETED);
220 :
221 : /* copy the past hash of the block */
- 222 58036 : memcpy(block->hash, over_block->hash, HASH_SIZE);
+ 222 58157 : memcpy(block->hash, over_block->hash, HASH_SIZE);
223 :
224 : /* if we have not already cleared the past hash */
- 225 58036 : if (!state->clear_past_hash) {
+ 225 58157 : if (!state->clear_past_hash) {
226 : /* in this case we don't know if the old state is still the one */
227 : /* stored inside the parity, because after an aborted sync, the parity */
228 : /* may be or may be not have been updated with the new data */
@@ -301,1590 +301,1602 @@
239 : }
240 :
241 : /* store in the disk map, after invalidating all the other blocks */
- 242 248590 : fs_allocate(disk, parity_pos, file, i);
+ 242 248714 : fs_allocate(disk, parity_pos, file, i);
243 :
244 : /* set the new free position */
- 245 248590 : disk->first_free_block = parity_pos + 1;
+ 245 248714 : disk->first_free_block = parity_pos + 1;
246 : }
247 :
248 : /* insert in the list of contained files */
- 249 100930 : tommy_list_insert_tail(&disk->filelist, &file->nodelist, file);
- 250 100930 : }
+ 249 100975 : tommy_list_insert_tail(&disk->filelist, &file->nodelist, file);
+ 250 100975 : }
251 :
252 : /**
- 253 : * Remove the specified file from the parity.
- 254 : * The file is then inserted in the deleted set, and it should no be deallocated.
- 255 : */
- 256 56098 : static void scan_file_deallocate(struct snapraid_scan* scan, struct snapraid_file* file)
- 257 : {
- 258 56098 : struct snapraid_state* state = scan->state;
- 259 56098 : struct snapraid_disk* disk = scan->disk;
- 260 : block_off_t i;
- 261 :
- 262 : /* remove from the list of contained files */
- 263 56098 : tommy_list_remove_existing(&disk->filelist, &file->nodelist);
+ 253 : * Delete the specified file from the parity.
+ 254 : *
+ 255 : * Note that the parity remains allocated, but the blocks and the file are marked as DELETED.
+ 256 : * The file is then inserted in the deleted set, and it should not be deallocated,
+ 257 : * as the parity still references it.
+ 258 : */
+ 259 56139 : static void scan_file_deallocate(struct snapraid_scan* scan, struct snapraid_file* file)
+ 260 : {
+ 261 56139 : struct snapraid_state* state = scan->state;
+ 262 56139 : struct snapraid_disk* disk = scan->disk;
+ 263 : block_off_t i;
264 :
- 265 : /* state changed */
- 266 56098 : state->need_write = 1;
+ 265 : /* remove from the list of contained files */
+ 266 56139 : tommy_list_remove_existing(&disk->filelist, &file->nodelist);
267 :
- 268 : /* free all the blocks of the file */
- 269 194313 : for (i = 0; i < file->blockmax; ++i) {
- 270 138215 : struct snapraid_block* block = fs_file2block_get(file, i);
- 271 138215 : block_off_t parity_pos = fs_file2par_get(disk, file, i);
- 272 : unsigned block_state;
- 273 :
- 274 : /* adjust the first free position */
- 275 : /* note that doing all the deletions before alllocations, */
- 276 : /* first_free_block is always 0 and the "if" is never triggered */
- 277 : /* but we keep this code anyway for completeness. */
- 278 138215 : if (disk->first_free_block > parity_pos)
- 279 0 : disk->first_free_block = parity_pos;
- 280 :
- 281 : /* in case we scan after an aborted sync, */
- 282 : /* we could get also intermediate states */
- 283 138215 : block_state = block_state_get(block);
- 284 138215 : switch (block_state) {
- 285 : case BLOCK_STATE_BLK :
- 286 : /* we keep the hash making it an "old" hash, because the parity is still containing data for it */
- 287 33420 : break;
- 288 : case BLOCK_STATE_CHG :
- 289 : /* if we have not already cleared the past hash */
- 290 57596 : if (!state->clear_past_hash) {
- 291 : /* in these cases we don't know if the old state is still the one */
- 292 : /* stored inside the parity, because after an aborted sync, the parity */
- 293 : /* may be or may be not have been updated with the data that it's now */
- 294 : /* deleted. Then we reset the hash to a bogus value. */
- 295 : /* For example: */
- 296 : /* - One file is added */
- 297 : /* - Sync aborted after updating the parity to the new state, */
- 298 : /* but without saving the content file representing this new state. */
- 299 : /* - File is now deleted after the aborted sync */
- 300 : /* - Sync again, deleting the blocks (exactly here) */
- 301 : /* with the hash of CHG block not represeting the real parity state */
- 302 0 : hash_invalid_set(block->hash);
- 303 : }
- 304 57596 : break;
- 305 : case BLOCK_STATE_REP :
- 306 : /* we just don't know the old hash, and then we set it to invalid */
- 307 47199 : hash_invalid_set(block->hash);
- 308 47199 : break;
- 309 : default :
- 310 : /* LCOV_EXCL_START */
- 311 : log_fatal("Internal inconsistency in deallocating for block %u state %u\n", parity_pos, block_state);
- 312 : exit(EXIT_FAILURE);
- 313 : /* LCOV_EXCL_STOP */
- 314 : }
- 315 :
- 316 : /* set the block as deleted */
- 317 138215 : block_state_set(block, BLOCK_STATE_DELETED);
- 318 : }
- 319 :
- 320 : /* mark the file as deleted */
- 321 56098 : file_flag_set(file, FILE_IS_DELETED);
- 322 :
- 323 : /* insert it in the list of deleted blocks */
- 324 56098 : tommy_list_insert_tail(&disk->deletedlist, &file->nodelist, file);
- 325 56098 : }
- 326 :
- 327 100930 : static void scan_file_delayed_allocate(struct snapraid_scan* scan, struct snapraid_file* file)
- 328 : {
- 329 100930 : struct snapraid_state* state = scan->state;
- 330 100930 : struct snapraid_disk* disk = scan->disk;
- 331 :
- 332 : /* if we sort for physical offsets we have to read them for new files */
- 333 100930 : if (state->opt.force_order == SORT_PHYSICAL
- 334 11430 : && file->physical == FILEPHY_UNREAD_OFFSET
- 335 : ) {
- 336 : char path_next[PATH_MAX];
+ 268 : /* state changed */
+ 269 56139 : state->need_write = 1;
+ 270 :
+ 271 : /* here we are supposed to adjust the ::first_free_block position */
+ 272 : /* with the parity position we are deleting */
+ 273 : /* but we also know that we do only delayed insert, after all the deletion, */
+ 274 : /* so at this point ::first_free_block is always at 0, and we don't need to update it */
+ 275 56139 : if (disk->first_free_block != 0) {
+ 276 : /* LCOV_EXCL_START */
+ 277 : log_fatal("Internal inconsistency for first free position at '%u' deallocating file '%s'\n", disk->first_free_block, file->sub);
+ 278 : exit(EXIT_FAILURE);
+ 279 : /* LCOV_EXCL_STOP */
+ 280 : }
+ 281 :
+ 282 : /* free all the blocks of the file */
+ 283 194478 : for (i = 0; i < file->blockmax; ++i) {
+ 284 138339 : struct snapraid_block* block = fs_file2block_get(file, i);
+ 285 : unsigned block_state;
+ 286 :
+ 287 : /* in case we scan after an aborted sync, */
+ 288 : /* we could get also intermediate states */
+ 289 138339 : block_state = block_state_get(block);
+ 290 138339 : switch (block_state) {
+ 291 : case BLOCK_STATE_BLK :
+ 292 : /* we keep the hash making it an "old" hash, because the parity is still containing data for it */
+ 293 33544 : break;
+ 294 : case BLOCK_STATE_CHG :
+ 295 : /* if we have not already cleared the past hash */
+ 296 57596 : if (!state->clear_past_hash) {
+ 297 : /* in these cases we don't know if the old state is still the one */
+ 298 : /* stored inside the parity, because after an aborted sync, the parity */
+ 299 : /* may be or may be not have been updated with the data that it's now */
+ 300 : /* deleted. Then we reset the hash to a bogus value. */
+ 301 : /* For example: */
+ 302 : /* - One file is added */
+ 303 : /* - Sync aborted after updating the parity to the new state, */
+ 304 : /* but without saving the content file representing this new state. */
+ 305 : /* - File is now deleted after the aborted sync */
+ 306 : /* - Sync again, deleting the blocks (exactly here) */
+ 307 : /* with the hash of CHG block not represeting the real parity state */
+ 308 0 : hash_invalid_set(block->hash);
+ 309 : }
+ 310 57596 : break;
+ 311 : case BLOCK_STATE_REP :
+ 312 : /* we just don't know the old hash, and then we set it to invalid */
+ 313 47199 : hash_invalid_set(block->hash);
+ 314 47199 : break;
+ 315 : default :
+ 316 : /* LCOV_EXCL_START */
+ 317 : log_fatal("Internal inconsistency in file '%s' deallocating block '%u:%u' state %u\n", file->sub, i, file->blockmax, block_state);
+ 318 : exit(EXIT_FAILURE);
+ 319 : /* LCOV_EXCL_STOP */
+ 320 : }
+ 321 :
+ 322 : /* set the block as deleted */
+ 323 138339 : block_state_set(block, BLOCK_STATE_DELETED);
+ 324 : }
+ 325 :
+ 326 : /* mark the file as deleted */
+ 327 56139 : file_flag_set(file, FILE_IS_DELETED);
+ 328 :
+ 329 : /* insert it in the list of deleted blocks */
+ 330 56139 : tommy_list_insert_tail(&disk->deletedlist, &file->nodelist, file);
+ 331 56139 : }
+ 332 :
+ 333 100975 : static void scan_file_delayed_allocate(struct snapraid_scan* scan, struct snapraid_file* file)
+ 334 : {
+ 335 100975 : struct snapraid_state* state = scan->state;
+ 336 100975 : struct snapraid_disk* disk = scan->disk;
337 :
- 338 11430 : pathprint(path_next, sizeof(path_next), "%s%s", disk->dir, file->sub);
- 339 :
- 340 11430 : if (filephy(path_next, file->size, &file->physical) != 0) {
- 341 : /* LCOV_EXCL_START */
- 342 : log_fatal("Error in getting the physical offset of file '%s'. %s.\n", path_next, strerror(errno));
- 343 : exit(EXIT_FAILURE);
- 344 : /* LCOV_EXCL_STOP */
- 345 : }
- 346 : }
- 347 :
- 348 : /* insert in the delayed list */
- 349 100930 : tommy_list_insert_tail(&scan->file_insert_list, &file->nodelist, file);
- 350 100930 : }
- 351 :
- 352 : /**
- 353 : * Check if a file is completely formed of blocks with invalid parity,
- 354 : * and no rehash is tagged, and if it has at least one block.
- 355 : */
- 356 923695 : static int file_is_full_invalid_parity_and_stable(struct snapraid_state* state, struct snapraid_disk* disk, struct snapraid_file* file)
- 357 : {
- 358 : block_off_t i;
- 359 :
- 360 : /* with no block, it never has an invalid parity */
- 361 923695 : if (file->blockmax == 0)
- 362 1224 : return 0;
- 363 :
- 364 : /* check all blocks */
- 365 976103 : for (i = 0; i < file->blockmax; ++i) {
- 366 : snapraid_info info;
- 367 954319 : struct snapraid_block* block = fs_file2block_get(file, i);
- 368 : block_off_t parity_pos;
+ 338 : /* if we sort for physical offsets we have to read them for new files */
+ 339 100975 : if (state->opt.force_order == SORT_PHYSICAL
+ 340 11432 : && file->physical == FILEPHY_UNREAD_OFFSET
+ 341 : ) {
+ 342 : char path_next[PATH_MAX];
+ 343 :
+ 344 11432 : pathprint(path_next, sizeof(path_next), "%s%s", disk->dir, file->sub);
+ 345 :
+ 346 11432 : if (filephy(path_next, file->size, &file->physical) != 0) {
+ 347 : /* LCOV_EXCL_START */
+ 348 : log_fatal("Error in getting the physical offset of file '%s'. %s.\n", path_next, strerror(errno));
+ 349 : exit(EXIT_FAILURE);
+ 350 : /* LCOV_EXCL_STOP */
+ 351 : }
+ 352 : }
+ 353 :
+ 354 : /* insert in the delayed list */
+ 355 100975 : tommy_list_insert_tail(&scan->file_insert_list, &file->nodelist, file);
+ 356 100975 : }
+ 357 :
+ 358 : /**
+ 359 : * Check if a file is completely formed of blocks with invalid parity,
+ 360 : * and no rehash is tagged, and if it has at least one block.
+ 361 : */
+ 362 923721 : static int file_is_full_invalid_parity_and_stable(struct snapraid_state* state, struct snapraid_disk* disk, struct snapraid_file* file)
+ 363 : {
+ 364 : block_off_t i;
+ 365 :
+ 366 : /* with no block, it never has an invalid parity */
+ 367 923721 : if (file->blockmax == 0)
+ 368 1290 : return 0;
369 :
- 370 : /* exclude blocks with parity */
- 371 954319 : if (!block_has_invalid_parity(block))
- 372 900687 : return 0;
- 373 :
- 374 : /*
- 375 : * Get the parity position, but only after checking
- 376 : * that the file has invalid parity.
- 377 : * This is not really required, as we are sure
- 378 : * that 'kept" files are mapped into parity.
- 379 : */
- 380 53632 : parity_pos = fs_file2par_get(disk, file, i);
- 381 :
- 382 : /* get block specific info */
- 383 53632 : info = info_get(&state->infoarr, parity_pos);
- 384 :
- 385 : /* if rehash fails */
- 386 53632 : if (info_get_rehash(info))
- 387 0 : return 0;
- 388 : }
- 389 :
- 390 21784 : return 1;
- 391 : }
- 392 :
- 393 : /**
- 394 : * Check if a file is completely formed of blocks with an updated hash,
- 395 : * and no rehash is tagged, and if it has at least one block.
- 396 : */
- 397 23659 : static int file_is_full_hashed_and_stable(struct snapraid_state* state, struct snapraid_disk* disk, struct snapraid_file* file)
- 398 : {
- 399 : block_off_t i;
- 400 :
- 401 : /* with no block, it never has a hash */
- 402 23659 : if (file->blockmax == 0)
- 403 27 : return 0;
- 404 :
- 405 : /* check all blocks */
- 406 42158 : for (i = 0; i < file->blockmax; ++i) {
- 407 : snapraid_info info;
- 408 35949 : struct snapraid_block* block = fs_file2block_get(file, i);
- 409 : block_off_t parity_pos;
+ 370 : /* check all blocks */
+ 371 976066 : for (i = 0; i < file->blockmax; ++i) {
+ 372 : snapraid_info info;
+ 373 954281 : struct snapraid_block* block = fs_file2block_get(file, i);
+ 374 : block_off_t parity_pos;
+ 375 :
+ 376 : /* exclude blocks with parity */
+ 377 954281 : if (!block_has_invalid_parity(block))
+ 378 900646 : return 0;
+ 379 :
+ 380 : /*
+ 381 : * Get the parity position, but only after checking
+ 382 : * that the file has invalid parity.
+ 383 : * This is not really required, as we are sure
+ 384 : * that 'kept" files are mapped into parity.
+ 385 : */
+ 386 53635 : parity_pos = fs_file2par_get(disk, file, i);
+ 387 :
+ 388 : /* get block specific info */
+ 389 53635 : info = info_get(&state->infoarr, parity_pos);
+ 390 :
+ 391 : /* if rehash fails */
+ 392 53635 : if (info_get_rehash(info))
+ 393 0 : return 0;
+ 394 : }
+ 395 :
+ 396 21785 : return 1;
+ 397 : }
+ 398 :
+ 399 : /**
+ 400 : * Check if a file is completely formed of blocks with an updated hash,
+ 401 : * and no rehash is tagged, and if it has at least one block.
+ 402 : */
+ 403 23659 : static int file_is_full_hashed_and_stable(struct snapraid_state* state, struct snapraid_disk* disk, struct snapraid_file* file)
+ 404 : {
+ 405 : block_off_t i;
+ 406 :
+ 407 : /* with no block, it never has a hash */
+ 408 23659 : if (file->blockmax == 0)
+ 409 27 : return 0;
410 :
- 411 : /* exclude blocks without hash */
- 412 35949 : if (!block_has_updated_hash(block))
- 413 1704 : return 0;
- 414 :
- 415 : /*
- 416 : * Get the parity position, but only AFTER checking
- 417 : * that the file has an updated hash.
- 418 : * This is required because not hashed files may be
- 419 : * not yet mapped into parity.
- 420 : *
- 421 : * This happens when a new file is in the delayed insertion
- 422 : * list, and scan finds a copy of it, and it tries to copy
- 423 : * the hash info.
- 424 : * As just allocated files have only CHG blocks, checking that
- 425 : * the hash is updated is enough to exclude such cases.
- 426 : */
- 427 34245 : parity_pos = fs_file2par_get(disk, file, i);
- 428 :
- 429 : /* get block specific info */
- 430 34245 : info = info_get(&state->infoarr, parity_pos);
- 431 :
- 432 : /* exclude blocks needing a rehash */
- 433 34245 : if (info_get_rehash(info))
- 434 15719 : return 0;
- 435 : }
- 436 :
- 437 6209 : return 1;
- 438 : }
- 439 :
- 440 : /**
- 441 : * Refresh the file info.
- 442 : *
- 443 : * This is needed by Windows as the normal way to list directories may report not
- 444 : * updated info. Only the GetFileInformationByHandle() func, called file-by-file,
- 445 : * really ensures to return synced info.
- 446 : *
- 447 : * If this happens, we read also the physical offset, to avoid to read it later.
- 448 : */
- 449 79146 : static void scan_file_refresh(struct snapraid_scan* scan, const char* sub, struct stat* st, uint64_t* physical)
- 450 : {
- 451 : #if HAVE_LSTAT_SYNC
- 452 : struct snapraid_state* state = scan->state;
- 453 : struct snapraid_disk* disk = scan->disk;
- 454 :
- 455 : /* if the st_sync is not set, ensure to get synced info */
- 456 : if (st->st_sync == 0) {
- 457 : char path_next[PATH_MAX];
- 458 : struct stat synced_st;
- 459 :
- 460 : pathprint(path_next, sizeof(path_next), "%s%s", disk->dir, sub);
- 461 :
- 462 : /* if we sort for physical offsets we have to read them for new files */
- 463 : if (state->opt.force_order == SORT_PHYSICAL
- 464 : && *physical == FILEPHY_UNREAD_OFFSET
- 465 : ) {
- 466 : /* do nothing, leave the pointer to read the physical offset */
- 467 : } else {
- 468 : physical = 0; /* set the pointer to 0 to read nothing */
- 469 : }
- 470 :
- 471 : if (lstat_sync(path_next, &synced_st, physical) != 0) {
- 472 : /* LCOV_EXCL_START */
- 473 : log_fatal("Error in stat file '%s'. %s.\n", path_next, strerror(errno));
- 474 : exit(EXIT_FAILURE);
- 475 : /* LCOV_EXCL_STOP */
- 476 : }
- 477 :
- 478 : if (st->st_mtime != synced_st.st_mtime
- 479 : || st->st_mtimensec != synced_st.st_mtimensec
- 480 : ) {
- 481 : #ifndef _WIN32
- 482 : /*
- 483 : * In Windows having different metadata is expected with open files
- 484 : * because the metadata in the directory is updated only when the file
- 485 : * is closed.
- 486 : *
- 487 : * See also:
- 488 : * Why is the file size reported incorrectly for files that are still being written to?
- 489 : * http://blogs.msdn.com/b/oldnewthing/archive/2011/12/26/10251026.aspx
- 490 : */
- 491 : log_fatal("WARNING! Detected uncached time change for file '%s'\n", sub);
- 492 : log_fatal("It's better if you run SnapRAID without other processes running.\n");
- 493 : #endif
- 494 : st->st_mtime = synced_st.st_mtime;
- 495 : st->st_mtimensec = synced_st.st_mtimensec;
- 496 : }
- 497 :
- 498 : if (st->st_size != synced_st.st_size) {
- 499 : #ifndef _WIN32
- 500 : log_fatal("WARNING! Detected uncached size change for file '%s'\n", sub);
- 501 : log_fatal("It's better if you run SnapRAID without other processes running.\n");
- 502 : #endif
- 503 : st->st_size = synced_st.st_size;
- 504 : }
- 505 :
- 506 : if (st->st_ino != synced_st.st_ino) {
- 507 : log_fatal("DANGER! Detected uncached inode change for file '%s'\n", sub);
- 508 : log_fatal("Please ensure to run SnapRAID without other processes running.\n");
- 509 : /* at this point, it's too late to change inode */
- 510 : /* and having inconsistent inodes may result to internal failures */
- 511 : /* so, it's better to abort */
- 512 : exit(EXIT_FAILURE);
- 513 : }
- 514 : }
- 515 : #else
- 516 : (void)scan;
- 517 : (void)sub;
- 518 : (void)st;
- 519 : (void)physical;
- 520 : #endif
- 521 79146 : }
- 522 :
- 523 : /**
- 524 : * Insert the file in the data set.
- 525 : */
- 526 100930 : static void scan_file_insert(struct snapraid_scan* scan, struct snapraid_file* file)
- 527 : {
- 528 100930 : struct snapraid_disk* disk = scan->disk;
- 529 :
- 530 : /* insert the file in the containers */
- 531 100930 : if (!file_flag_has(file, FILE_IS_WITHOUT_INODE))
- 532 100930 : tommy_hashdyn_insert(&disk->inodeset, &file->nodeset, file, file_inode_hash(file->inode));
- 533 100930 : tommy_hashdyn_insert(&disk->pathset, &file->pathset, file, file_path_hash(file->sub));
- 534 100930 : tommy_hashdyn_insert(&disk->stampset, &file->stampset, file, file_stamp_hash(file->size, file->mtime_sec, file->mtime_nsec));
+ 411 : /* check all blocks */
+ 412 42158 : for (i = 0; i < file->blockmax; ++i) {
+ 413 : snapraid_info info;
+ 414 35949 : struct snapraid_block* block = fs_file2block_get(file, i);
+ 415 : block_off_t parity_pos;
+ 416 :
+ 417 : /* exclude blocks without hash */
+ 418 35949 : if (!block_has_updated_hash(block))
+ 419 1704 : return 0;
+ 420 :
+ 421 : /*
+ 422 : * Get the parity position, but only AFTER checking
+ 423 : * that the file has an updated hash.
+ 424 : * This is required because not hashed files may be
+ 425 : * not yet mapped into parity.
+ 426 : *
+ 427 : * This happens when a new file is in the delayed insertion
+ 428 : * list, and scan finds a copy of it, and it tries to copy
+ 429 : * the hash info.
+ 430 : * As just allocated files have only CHG blocks, checking that
+ 431 : * the hash is updated is enough to exclude such cases.
+ 432 : */
+ 433 34245 : parity_pos = fs_file2par_get(disk, file, i);
+ 434 :
+ 435 : /* get block specific info */
+ 436 34245 : info = info_get(&state->infoarr, parity_pos);
+ 437 :
+ 438 : /* exclude blocks needing a rehash */
+ 439 34245 : if (info_get_rehash(info))
+ 440 15719 : return 0;
+ 441 : }
+ 442 :
+ 443 6209 : return 1;
+ 444 : }
+ 445 :
+ 446 : /**
+ 447 : * Refresh the file info.
+ 448 : *
+ 449 : * This is needed by Windows as the normal way to list directories may report not
+ 450 : * updated info. Only the GetFileInformationByHandle() func, called file-by-file,
+ 451 : * really ensures to return synced info.
+ 452 : *
+ 453 : * If this happens, we read also the physical offset, to avoid to read it later.
+ 454 : */
+ 455 79190 : static void scan_file_refresh(struct snapraid_scan* scan, const char* sub, struct stat* st, uint64_t* physical)
+ 456 : {
+ 457 : #if HAVE_LSTAT_SYNC
+ 458 : struct snapraid_state* state = scan->state;
+ 459 : struct snapraid_disk* disk = scan->disk;
+ 460 :
+ 461 : /* if the st_sync is not set, ensure to get synced info */
+ 462 : if (st->st_sync == 0) {
+ 463 : char path_next[PATH_MAX];
+ 464 : struct stat synced_st;
+ 465 :
+ 466 : pathprint(path_next, sizeof(path_next), "%s%s", disk->dir, sub);
+ 467 :
+ 468 : /* if we sort for physical offsets we have to read them for new files */
+ 469 : if (state->opt.force_order == SORT_PHYSICAL
+ 470 : && *physical == FILEPHY_UNREAD_OFFSET
+ 471 : ) {
+ 472 : /* do nothing, leave the pointer to read the physical offset */
+ 473 : } else {
+ 474 : physical = 0; /* set the pointer to 0 to read nothing */
+ 475 : }
+ 476 :
+ 477 : if (lstat_sync(path_next, &synced_st, physical) != 0) {
+ 478 : /* LCOV_EXCL_START */
+ 479 : log_fatal("Error in stat file '%s'. %s.\n", path_next, strerror(errno));
+ 480 : exit(EXIT_FAILURE);
+ 481 : /* LCOV_EXCL_STOP */
+ 482 : }
+ 483 :
+ 484 : if (st->st_mtime != synced_st.st_mtime
+ 485 : || st->st_mtimensec != synced_st.st_mtimensec
+ 486 : ) {
+ 487 : #ifndef _WIN32
+ 488 : /*
+ 489 : * In Windows having different metadata is expected with open files
+ 490 : * because the metadata in the directory is updated only when the file
+ 491 : * is closed.
+ 492 : *
+ 493 : * See also:
+ 494 : * Why is the file size reported incorrectly for files that are still being written to?
+ 495 : * http://blogs.msdn.com/b/oldnewthing/archive/2011/12/26/10251026.aspx
+ 496 : */
+ 497 : log_fatal("WARNING! Detected uncached time change for file '%s'\n", sub);
+ 498 : log_fatal("It's better if you run SnapRAID without other processes running.\n");
+ 499 : #endif
+ 500 : st->st_mtime = synced_st.st_mtime;
+ 501 : st->st_mtimensec = synced_st.st_mtimensec;
+ 502 : }
+ 503 :
+ 504 : if (st->st_size != synced_st.st_size) {
+ 505 : #ifndef _WIN32
+ 506 : log_fatal("WARNING! Detected uncached size change for file '%s'\n", sub);
+ 507 : log_fatal("It's better if you run SnapRAID without other processes running.\n");
+ 508 : #endif
+ 509 : st->st_size = synced_st.st_size;
+ 510 : }
+ 511 :
+ 512 : if (st->st_ino != synced_st.st_ino) {
+ 513 : log_fatal("DANGER! Detected uncached inode change for file '%s'\n", sub);
+ 514 : log_fatal("Please ensure to run SnapRAID without other processes running.\n");
+ 515 : /* at this point, it's too late to change inode */
+ 516 : /* and having inconsistent inodes may result to internal failures */
+ 517 : /* so, it's better to abort */
+ 518 : exit(EXIT_FAILURE);
+ 519 : }
+ 520 : }
+ 521 : #else
+ 522 : (void)scan;
+ 523 : (void)sub;
+ 524 : (void)st;
+ 525 : (void)physical;
+ 526 : #endif
+ 527 79190 : }
+ 528 :
+ 529 : /**
+ 530 : * Insert the file in the data set.
+ 531 : */
+ 532 100975 : static void scan_file_insert(struct snapraid_scan* scan, struct snapraid_file* file)
+ 533 : {
+ 534 100975 : struct snapraid_disk* disk = scan->disk;
535 :
- 536 : /* delayed allocation of the parity */
- 537 100930 : scan_file_delayed_allocate(scan, file);
- 538 100930 : }
- 539 :
- 540 : /**
- 541 : * Remove the file from the data set.
- 542 : *
- 543 : * File is then deleted.
- 544 : */
- 545 56098 : static void scan_file_remove(struct snapraid_scan* scan, struct snapraid_file* file)
- 546 : {
- 547 56098 : struct snapraid_disk* disk = scan->disk;
- 548 :
- 549 : /* remove the file from the containers */
- 550 56098 : if (!file_flag_has(file, FILE_IS_WITHOUT_INODE))
- 551 56043 : tommy_hashdyn_remove_existing(&disk->inodeset, &file->nodeset);
- 552 56098 : tommy_hashdyn_remove_existing(&disk->pathset, &file->pathset);
- 553 56098 : tommy_hashdyn_remove_existing(&disk->stampset, &file->stampset);
+ 536 : /* insert the file in the containers */
+ 537 100975 : if (!file_flag_has(file, FILE_IS_WITHOUT_INODE))
+ 538 100975 : tommy_hashdyn_insert(&disk->inodeset, &file->nodeset, file, file_inode_hash(file->inode));
+ 539 100975 : tommy_hashdyn_insert(&disk->pathset, &file->pathset, file, file_path_hash(file->sub));
+ 540 100975 : tommy_hashdyn_insert(&disk->stampset, &file->stampset, file, file_stamp_hash(file->size, file->mtime_sec, file->mtime_nsec));
+ 541 :
+ 542 : /* delayed allocation of the parity */
+ 543 100975 : scan_file_delayed_allocate(scan, file);
+ 544 100975 : }
+ 545 :
+ 546 : /**
+ 547 : * Remove the file from the data set.
+ 548 : *
+ 549 : * File is then deleted.
+ 550 : */
+ 551 56139 : static void scan_file_remove(struct snapraid_scan* scan, struct snapraid_file* file)
+ 552 : {
+ 553 56139 : struct snapraid_disk* disk = scan->disk;
554 :
- 555 : /* deallocate the file from the parity */
- 556 56098 : scan_file_deallocate(scan, file);
- 557 56098 : }
- 558 :
- 559 : /**
- 560 : * Keep the file as it's (or with only a name/inode modification).
- 561 : *
- 562 : * If the file is kept, nothing has to be done.
- 563 : *
- 564 : * But if a file contains only blocks with invalid parity, it's reallocated to ensure
- 565 : * to always minimize the space used in the parity.
- 566 : *
- 567 : * This could happen after a failed sync, when some other files are deleted,
- 568 : * and then new ones can be moved backward to fill the hole created.
- 569 : */
- 570 923695 : static void scan_file_keep(struct snapraid_scan* scan, struct snapraid_file* file)
- 571 : {
- 572 923695 : struct snapraid_disk* disk = scan->disk;
- 573 :
- 574 : /* if the file is full invalid, schedule a reinsert at later stage */
- 575 923695 : if (file_is_full_invalid_parity_and_stable(scan->state, disk, file)) {
- 576 21784 : struct snapraid_file* copy = file_dup(file);
- 577 :
- 578 : /* remove the file */
- 579 21784 : scan_file_remove(scan, file);
- 580 :
- 581 : /* reinsert the copy in the delayed list */
- 582 21784 : scan_file_insert(scan, copy);
- 583 : }
- 584 923695 : }
- 585 :
- 586 : /**
- 587 : * Process a file.
- 588 : */
- 589 1003012 : static void scan_file(struct snapraid_scan* scan, int is_diff, const char* sub, struct stat* st, uint64_t physical)
- 590 : {
- 591 1003012 : struct snapraid_state* state = scan->state;
- 592 1003012 : struct snapraid_disk* disk = scan->disk;
- 593 : struct snapraid_file* file;
- 594 : tommy_node* i;
- 595 : int is_original_file_size_different_than_zero;
- 596 : int is_file_already_present;
- 597 : int is_file_reported;
- 598 :
- 599 : /*
- 600 : * If the disk has persistent inodes and UUID, try a search on the past inodes,
- 601 : * to detect moved files.
- 602 : *
- 603 : * For persistent inodes we mean inodes that keep their values when the filesystem
- 604 : * is unmounted and remounted. This don't always happen.
- 605 : *
- 606 : * Cases found are:
- 607 : * - Linux FUSE with exFAT driver from https://code.google.com/p/exfat/.
- 608 : * Inodes are reassigned at every mount restarting from 1 and incrementing.
- 609 : * As worse, the exFAT support in FUSE doesn't use subsecond precision in timestamps
- 610 : * making inode collision more easy (exFAT by design supports 10ms precision).
- 611 : * - Linux VFAT kernel (3.2) driver. Inodes are fully reassigned at every mount.
- 612 : *
- 613 : * In such cases, to avoid possible random collisions, it's better to disable the moved
- 614 : * file recognition.
- 615 : *
- 616 : * For persistent UUID we mean that it has the same UUID as before.
- 617 : * Otherwise, if the UUID is changed, likely it's a new recreated filesystem,
- 618 : * and then the inode have no meaning.
- 619 : *
- 620 : * Note that to disable the search by past inode, we do this implicitely
- 621 : * removing all the past inode before searching for files.
- 622 : * This ensures that no file is found with a past inode, but at the same time,
- 623 : * it allows to find new files with the same inode, to identify them as hardlinks.
- 624 : */
- 625 1003012 : int has_past_inodes = !disk->has_volatile_inodes && !disk->has_different_uuid && !disk->has_unsupported_uuid;
- 626 :
- 627 : /* always search with the new inode, in the all new inodes found until now, */
- 628 : /* with the eventual presence of also the past inodes */
- 629 1003012 : uint64_t inode = st->st_ino;
- 630 :
- 631 1003012 : file = tommy_hashdyn_search(&disk->inodeset, file_inode_compare_to_arg, &inode, file_inode_hash(inode));
+ 555 : /* remove the file from the containers */
+ 556 56139 : if (!file_flag_has(file, FILE_IS_WITHOUT_INODE))
+ 557 56084 : tommy_hashdyn_remove_existing(&disk->inodeset, &file->nodeset);
+ 558 56139 : tommy_hashdyn_remove_existing(&disk->pathset, &file->pathset);
+ 559 56139 : tommy_hashdyn_remove_existing(&disk->stampset, &file->stampset);
+ 560 :
+ 561 : /* deallocate the file from the parity */
+ 562 56139 : scan_file_deallocate(scan, file);
+ 563 56139 : }
+ 564 :
+ 565 : /**
+ 566 : * Keep the file as it's (or with only a name/inode modification).
+ 567 : *
+ 568 : * If the file is kept, nothing has to be done.
+ 569 : *
+ 570 : * But if a file contains only blocks with invalid parity, it's reallocated to ensure
+ 571 : * to always minimize the space used in the parity.
+ 572 : *
+ 573 : * This could happen after a failed sync, when some other files are deleted,
+ 574 : * and then new ones can be moved backward to fill the hole created.
+ 575 : */
+ 576 923721 : static void scan_file_keep(struct snapraid_scan* scan, struct snapraid_file* file)
+ 577 : {
+ 578 923721 : struct snapraid_disk* disk = scan->disk;
+ 579 :
+ 580 : /* if the file is full invalid, schedule a reinsert at later stage */
+ 581 923721 : if (file_is_full_invalid_parity_and_stable(scan->state, disk, file)) {
+ 582 21785 : struct snapraid_file* copy = file_dup(file);
+ 583 :
+ 584 : /* remove the file */
+ 585 21785 : scan_file_remove(scan, file);
+ 586 :
+ 587 : /* reinsert the copy in the delayed list */
+ 588 21785 : scan_file_insert(scan, copy);
+ 589 : }
+ 590 923721 : }
+ 591 :
+ 592 : /**
+ 593 : * Process a file.
+ 594 : */
+ 595 1003082 : static void scan_file(struct snapraid_scan* scan, int is_diff, const char* sub, struct stat* st, uint64_t physical)
+ 596 : {
+ 597 1003082 : struct snapraid_state* state = scan->state;
+ 598 1003082 : struct snapraid_disk* disk = scan->disk;
+ 599 : struct snapraid_file* file;
+ 600 : tommy_node* i;
+ 601 : int is_original_file_size_different_than_zero;
+ 602 : int is_file_already_present;
+ 603 : int is_file_reported;
+ 604 :
+ 605 : /*
+ 606 : * If the disk has persistent inodes and UUID, try a search on the past inodes,
+ 607 : * to detect moved files.
+ 608 : *
+ 609 : * For persistent inodes we mean inodes that keep their values when the filesystem
+ 610 : * is unmounted and remounted. This don't always happen.
+ 611 : *
+ 612 : * Cases found are:
+ 613 : * - Linux FUSE with exFAT driver from https://code.google.com/p/exfat/.
+ 614 : * Inodes are reassigned at every mount restarting from 1 and incrementing.
+ 615 : * As worse, the exFAT support in FUSE doesn't use subsecond precision in timestamps
+ 616 : * making inode collision more easy (exFAT by design supports 10ms precision).
+ 617 : * - Linux VFAT kernel (3.2) driver. Inodes are fully reassigned at every mount.
+ 618 : *
+ 619 : * In such cases, to avoid possible random collisions, it's better to disable the moved
+ 620 : * file recognition.
+ 621 : *
+ 622 : * For persistent UUID we mean that it has the same UUID as before.
+ 623 : * Otherwise, if the UUID is changed, likely it's a new recreated filesystem,
+ 624 : * and then the inode have no meaning.
+ 625 : *
+ 626 : * Note that to disable the search by past inode, we do this implicitely
+ 627 : * removing all the past inode before searching for files.
+ 628 : * This ensures that no file is found with a past inode, but at the same time,
+ 629 : * it allows to find new files with the same inode, to identify them as hardlinks.
+ 630 : */
+ 631 1003082 : int has_past_inodes = !disk->has_volatile_inodes && !disk->has_different_uuid && !disk->has_unsupported_uuid;
632 :
- 633 : /* identify moved files with past inodes and hardlinks with the new inodes */
- 634 1003012 : if (file) {
- 635 : /* check if the file is not changed */
- 636 838372 : if (file->size == st->st_size
- 637 826527 : && file->mtime_sec == st->st_mtime
- 638 823459 : && (file->mtime_nsec == STAT_NSEC(st)
- 639 : /* always accept the stored value if it's STAT_NSEC_INVALID */
- 640 : /* it happens when upgrading from an old version of SnapRAID */
- 641 : /* not yet supporting the nanosecond field */
- 642 3 : || file->mtime_nsec == STAT_NSEC_INVALID
- 643 : )
- 644 : ) {
- 645 : /* check if multiple files have the same inode */
- 646 823456 : if (file_flag_has(file, FILE_IS_PRESENT)) {
- 647 : #if HAVE_STRUCT_STAT_ST_NLINK
- 648 171 : if (st->st_nlink <= 1) {
- 649 : /* LCOV_EXCL_START */
- 650 : log_fatal("Internal inode '%" PRIu64 "' inconsistency for file '%s%s' already present\n", (uint64_t)st->st_ino, disk->dir, sub);
- 651 : exit(EXIT_FAILURE);
- 652 : /* LCOV_EXCL_STOP */
- 653 : }
- 654 : #endif
- 655 : /* it's a hardlink */
- 656 171 : scan_link(scan, is_diff, sub, file->sub, FILE_IS_HARDLINK);
- 657 171 : return;
- 658 : }
- 659 :
- 660 : /* mark as present */
- 661 823285 : file_flag_set(file, FILE_IS_PRESENT);
- 662 :
- 663 : /* update the nanoseconds mtime only if different */
- 664 : /* to avoid unneeded updates */
- 665 823285 : if (file->mtime_nsec == STAT_NSEC_INVALID
- 666 0 : && STAT_NSEC(st) != file->mtime_nsec
- 667 : ) {
- 668 0 : file->mtime_nsec = STAT_NSEC(st);
- 669 :
- 670 : /* we have to save the new mtime */
- 671 0 : state->need_write = 1;
- 672 : }
- 673 :
- 674 823285 : if (strcmp(file->sub, sub) != 0) {
- 675 : /* if the path is different, it means a moved file with the same inode */
- 676 155 : ++scan->count_move;
- 677 :
- 678 155 : log_tag("scan:move:%s:%s:%s\n", disk->name, esc(file->sub), esc(sub));
- 679 155 : if (is_diff) {
- 680 0 : printf("move %s%s -> %s%s\n", disk->dir, file->sub, disk->dir, sub);
- 681 : }
- 682 :
- 683 : /* remove from the name set */
- 684 155 : tommy_hashdyn_remove_existing(&disk->pathset, &file->pathset);
- 685 :
- 686 : /* save the new name */
- 687 155 : file_rename(file, sub);
+ 633 : /* always search with the new inode, in the all new inodes found until now, */
+ 634 : /* with the eventual presence of also the past inodes */
+ 635 1003082 : uint64_t inode = st->st_ino;
+ 636 :
+ 637 1003082 : file = tommy_hashdyn_search(&disk->inodeset, file_inode_compare_to_arg, &inode, file_inode_hash(inode));
+ 638 :
+ 639 : /* identify moved files with past inodes and hardlinks with the new inodes */
+ 640 1003082 : if (file) {
+ 641 : /* check if the file is not changed */
+ 642 837733 : if (file->size == st->st_size
+ 643 826569 : && file->mtime_sec == st->st_mtime
+ 644 823506 : && (file->mtime_nsec == STAT_NSEC(st)
+ 645 : /* always accept the stored value if it's STAT_NSEC_INVALID */
+ 646 : /* it happens when upgrading from an old version of SnapRAID */
+ 647 : /* not yet supporting the nanosecond field */
+ 648 2 : || file->mtime_nsec == STAT_NSEC_INVALID
+ 649 : )
+ 650 : ) {
+ 651 : /* check if multiple files have the same inode */
+ 652 823504 : if (file_flag_has(file, FILE_IS_PRESENT)) {
+ 653 : #if HAVE_STRUCT_STAT_ST_NLINK
+ 654 171 : if (st->st_nlink <= 1) {
+ 655 : /* LCOV_EXCL_START */
+ 656 : log_fatal("Internal inode '%" PRIu64 "' inconsistency for file '%s%s' already present\n", (uint64_t)st->st_ino, disk->dir, sub);
+ 657 : exit(EXIT_FAILURE);
+ 658 : /* LCOV_EXCL_STOP */
+ 659 : }
+ 660 : #endif
+ 661 : /* it's a hardlink */
+ 662 171 : scan_link(scan, is_diff, sub, file->sub, FILE_IS_HARDLINK);
+ 663 171 : return;
+ 664 : }
+ 665 :
+ 666 : /* mark as present */
+ 667 823333 : file_flag_set(file, FILE_IS_PRESENT);
+ 668 :
+ 669 : /* update the nanoseconds mtime only if different */
+ 670 : /* to avoid unneeded updates */
+ 671 823333 : if (file->mtime_nsec == STAT_NSEC_INVALID
+ 672 0 : && STAT_NSEC(st) != file->mtime_nsec
+ 673 : ) {
+ 674 0 : file->mtime_nsec = STAT_NSEC(st);
+ 675 :
+ 676 : /* we have to save the new mtime */
+ 677 0 : state->need_write = 1;
+ 678 : }
+ 679 :
+ 680 823333 : if (strcmp(file->sub, sub) != 0) {
+ 681 : /* if the path is different, it means a moved file with the same inode */
+ 682 155 : ++scan->count_move;
+ 683 :
+ 684 155 : log_tag("scan:move:%s:%s:%s\n", disk->name, esc(file->sub), esc(sub));
+ 685 155 : if (is_diff) {
+ 686 0 : printf("move %s%s -> %s%s\n", disk->dir, file->sub, disk->dir, sub);
+ 687 : }
688 :
- 689 : /* reinsert in the name set */
- 690 155 : tommy_hashdyn_insert(&disk->pathset, &file->pathset, file, file_path_hash(file->sub));
+ 689 : /* remove from the name set */
+ 690 155 : tommy_hashdyn_remove_existing(&disk->pathset, &file->pathset);
691 :
- 692 : /* we have to save the new name */
- 693 155 : state->need_write = 1;
- 694 : } else {
- 695 : /* otherwise it's equal */
- 696 823130 : ++scan->count_equal;
+ 692 : /* save the new name */
+ 693 155 : file_rename(file, sub);
+ 694 :
+ 695 : /* reinsert in the name set */
+ 696 155 : tommy_hashdyn_insert(&disk->pathset, &file->pathset, file, file_path_hash(file->sub));
697 :
- 698 823130 : if (state->opt.gui) {
- 699 22555 : log_tag("scan:equal:%s:%s\n", disk->name, esc(file->sub));
- 700 : }
- 701 : }
- 702 :
- 703 : /* mark the file as kept */
- 704 823285 : scan_file_keep(scan, file);
- 705 :
- 706 : /* nothing more to do */
- 707 823285 : return;
- 708 : }
- 709 :
- 710 : /* here the file matches the inode, but not the other info */
- 711 : /* if could be a modified file with the same name, */
- 712 : /* or a restored/copied file that get assigned a previously used inode, */
- 713 : /* or a filesystem with not persistent inodes */
- 714 :
- 715 : /* for sure it cannot be already present */
- 716 14916 : if (file_flag_has(file, FILE_IS_PRESENT)) {
- 717 : /* LCOV_EXCL_START */
- 718 : log_fatal("Internal inode '%" PRIu64 "' inconsistency for files '%s%s' and '%s%s' matching and already present but different\n", file->inode, disk->dir, sub, disk->dir, file->sub);
- 719 : exit(EXIT_FAILURE);
- 720 : /* LCOV_EXCL_STOP */
- 721 : }
- 722 :
- 723 : /* assume a previously used inode, it's the worst case */
- 724 : /* and we handle it removing the duplicate stored inode. */
- 725 : /* If the file is found by name (not necessarely in this function call), */
- 726 : /* it will have the inode restored, otherwise, it will get removed */
- 727 :
- 728 : /* remove from the inode set */
- 729 14916 : tommy_hashdyn_remove_existing(&disk->inodeset, &file->nodeset);
- 730 :
- 731 : /* clear the inode */
- 732 : /* this is not really needed for correct functionality */
- 733 : /* because we are going to set FILE_IS_WITHOUT_INODE */
- 734 : /* but it's easier for debugging to have invalid inodes set to 0 */
- 735 14916 : file->inode = 0;
+ 698 : /* we have to save the new name */
+ 699 155 : state->need_write = 1;
+ 700 : } else {
+ 701 : /* otherwise it's equal */
+ 702 823178 : ++scan->count_equal;
+ 703 :
+ 704 823178 : if (state->opt.gui) {
+ 705 22559 : log_tag("scan:equal:%s:%s\n", disk->name, esc(file->sub));
+ 706 : }
+ 707 : }
+ 708 :
+ 709 : /* mark the file as kept */
+ 710 823333 : scan_file_keep(scan, file);
+ 711 :
+ 712 : /* nothing more to do */
+ 713 823333 : return;
+ 714 : }
+ 715 :
+ 716 : /* here the file matches the inode, but not the other info */
+ 717 : /* if could be a modified file with the same name, */
+ 718 : /* or a restored/copied file that get assigned a previously used inode, */
+ 719 : /* or a filesystem with not persistent inodes */
+ 720 :
+ 721 : /* for sure it cannot be already present */
+ 722 14229 : if (file_flag_has(file, FILE_IS_PRESENT)) {
+ 723 : /* LCOV_EXCL_START */
+ 724 : log_fatal("Internal inode '%" PRIu64 "' inconsistency for files '%s%s' and '%s%s' matching and already present but different\n", file->inode, disk->dir, sub, disk->dir, file->sub);
+ 725 : exit(EXIT_FAILURE);
+ 726 : /* LCOV_EXCL_STOP */
+ 727 : }
+ 728 :
+ 729 : /* assume a previously used inode, it's the worst case */
+ 730 : /* and we handle it removing the duplicate stored inode. */
+ 731 : /* If the file is found by name (not necessarely in this function call), */
+ 732 : /* it will have the inode restored, otherwise, it will get removed */
+ 733 :
+ 734 : /* remove from the inode set */
+ 735 14229 : tommy_hashdyn_remove_existing(&disk->inodeset, &file->nodeset);
736 :
- 737 : /* mark as missing inode */
- 738 14916 : file_flag_set(file, FILE_IS_WITHOUT_INODE);
- 739 :
- 740 : /* go further to find it by name */
- 741 : }
+ 737 : /* clear the inode */
+ 738 : /* this is not really needed for correct functionality */
+ 739 : /* because we are going to set FILE_IS_WITHOUT_INODE */
+ 740 : /* but it's easier for debugging to have invalid inodes set to 0 */
+ 741 14229 : file->inode = 0;
742 :
- 743 : /* initialize for later overwrite */
- 744 179556 : is_file_reported = 0;
- 745 179556 : is_original_file_size_different_than_zero = 0;
- 746 :
- 747 : /* then try finding it by name */
- 748 179556 : file = tommy_hashdyn_search(&disk->pathset, file_path_compare_to_arg, sub, file_path_hash(sub));
- 749 :
- 750 : /* keep track if the file already exists */
- 751 179556 : is_file_already_present = file != 0;
+ 743 : /* mark as missing inode */
+ 744 14229 : file_flag_set(file, FILE_IS_WITHOUT_INODE);
+ 745 :
+ 746 : /* go further to find it by name */
+ 747 : }
+ 748 :
+ 749 : /* initialize for later overwrite */
+ 750 179578 : is_file_reported = 0;
+ 751 179578 : is_original_file_size_different_than_zero = 0;
752 :
- 753 179556 : if (is_file_already_present) {
- 754 : /* if the file is without an inode */
- 755 105086 : if (file_flag_has(file, FILE_IS_WITHOUT_INODE)) {
- 756 : /* set it now */
- 757 14861 : file->inode = st->st_ino;
+ 753 : /* then try finding it by name */
+ 754 179578 : file = tommy_hashdyn_search(&disk->pathset, file_path_compare_to_arg, sub, file_path_hash(sub));
+ 755 :
+ 756 : /* keep track if the file already exists */
+ 757 179578 : is_file_already_present = file != 0;
758 :
- 759 : /* insert in the set */
- 760 14861 : tommy_hashdyn_insert(&disk->inodeset, &file->nodeset, file, file_inode_hash(file->inode));
- 761 :
- 762 : /* unmark as missing inode */
- 763 14861 : file_flag_clear(file, FILE_IS_WITHOUT_INODE);
- 764 : } else {
- 765 : /* here the inode has to be different, otherwise we would have found it before */
- 766 90225 : if (file->inode == st->st_ino) {
- 767 : /* LCOV_EXCL_START */
- 768 : log_fatal("Internal inconsistency in inode '%" PRIu64 "' for files '%s%s' as unexpected matching\n", file->inode, disk->dir, sub);
- 769 : exit(EXIT_FAILURE);
- 770 : /* LCOV_EXCL_STOP */
- 771 : }
- 772 : }
- 773 :
- 774 : /* for sure it cannot be already present */
- 775 105086 : if (file_flag_has(file, FILE_IS_PRESENT)) {
- 776 : /* LCOV_EXCL_START */
- 777 : log_fatal("Internal inconsistency in path for file '%s%s' matching and already present\n", disk->dir, sub);
- 778 : exit(EXIT_FAILURE);
- 779 : /* LCOV_EXCL_STOP */
- 780 : }
- 781 :
- 782 : /* check if the file is not changed */
- 783 105086 : if (file->size == st->st_size
- 784 104492 : && file->mtime_sec == st->st_mtime
- 785 100410 : && (file->mtime_nsec == STAT_NSEC(st)
- 786 : /* always accept the stored value if it's STAT_NSEC_INVALID */
- 787 : /* it happens when upgrading from an old version of SnapRAID */
- 788 : /* not yet supporting the nanosecond field */
- 789 0 : || file->mtime_nsec == STAT_NSEC_INVALID
- 790 : )
- 791 : ) {
- 792 : /* mark as present */
- 793 100410 : file_flag_set(file, FILE_IS_PRESENT);
- 794 :
- 795 : /* update the nano seconds mtime only if different */
- 796 : /* to avoid unneeded updates */
- 797 100410 : if (file->mtime_nsec == STAT_NSEC_INVALID
- 798 0 : && STAT_NSEC(st) != STAT_NSEC_INVALID
- 799 : ) {
- 800 0 : file->mtime_nsec = STAT_NSEC(st);
- 801 :
- 802 : /* we have to save the new mtime */
- 803 0 : state->need_write = 1;
- 804 : }
- 805 :
- 806 : /* if when processing the disk we used the past inodes values */
- 807 100410 : if (has_past_inodes) {
- 808 : /* if persistent inodes are supported, we are sure that the inode number */
- 809 : /* is now different, because otherwise the file would have been found */
- 810 : /* when searching by inode. */
- 811 : /* if the inode is different, it means a rewritten file with the same path */
- 812 : /* like when restoring a backup that restores also the timestamp */
- 813 100410 : ++scan->count_restore;
- 814 :
- 815 100410 : log_tag("scan:restore:%s:%s\n", disk->name, esc(sub));
- 816 100410 : if (is_diff) {
- 817 0 : printf("restore %s%s\n", disk->dir, sub);
- 818 : }
- 819 :
- 820 : /* remove from the inode set */
- 821 100410 : tommy_hashdyn_remove_existing(&disk->inodeset, &file->nodeset);
- 822 :
- 823 : /* save the new inode */
- 824 100410 : file->inode = st->st_ino;
+ 759 179578 : if (is_file_already_present) {
+ 760 : /* if the file is without an inode */
+ 761 105104 : if (file_flag_has(file, FILE_IS_WITHOUT_INODE)) {
+ 762 : /* set it now */
+ 763 14174 : file->inode = st->st_ino;
+ 764 :
+ 765 : /* insert in the set */
+ 766 14174 : tommy_hashdyn_insert(&disk->inodeset, &file->nodeset, file, file_inode_hash(file->inode));
+ 767 :
+ 768 : /* unmark as missing inode */
+ 769 14174 : file_flag_clear(file, FILE_IS_WITHOUT_INODE);
+ 770 : } else {
+ 771 : /* here the inode has to be different, otherwise we would have found it before */
+ 772 90930 : if (file->inode == st->st_ino) {
+ 773 : /* LCOV_EXCL_START */
+ 774 : log_fatal("Internal inconsistency in inode '%" PRIu64 "' for files '%s%s' as unexpected matching\n", file->inode, disk->dir, sub);
+ 775 : exit(EXIT_FAILURE);
+ 776 : /* LCOV_EXCL_STOP */
+ 777 : }
+ 778 : }
+ 779 :
+ 780 : /* for sure it cannot be already present */
+ 781 105104 : if (file_flag_has(file, FILE_IS_PRESENT)) {
+ 782 : /* LCOV_EXCL_START */
+ 783 : log_fatal("Internal inconsistency in path for file '%s%s' matching and already present\n", disk->dir, sub);
+ 784 : exit(EXIT_FAILURE);
+ 785 : /* LCOV_EXCL_STOP */
+ 786 : }
+ 787 :
+ 788 : /* check if the file is not changed */
+ 789 105104 : if (file->size == st->st_size
+ 790 104510 : && file->mtime_sec == st->st_mtime
+ 791 100388 : && (file->mtime_nsec == STAT_NSEC(st)
+ 792 : /* always accept the stored value if it's STAT_NSEC_INVALID */
+ 793 : /* it happens when upgrading from an old version of SnapRAID */
+ 794 : /* not yet supporting the nanosecond field */
+ 795 0 : || file->mtime_nsec == STAT_NSEC_INVALID
+ 796 : )
+ 797 : ) {
+ 798 : /* mark as present */
+ 799 100388 : file_flag_set(file, FILE_IS_PRESENT);
+ 800 :
+ 801 : /* update the nano seconds mtime only if different */
+ 802 : /* to avoid unneeded updates */
+ 803 100388 : if (file->mtime_nsec == STAT_NSEC_INVALID
+ 804 0 : && STAT_NSEC(st) != STAT_NSEC_INVALID
+ 805 : ) {
+ 806 0 : file->mtime_nsec = STAT_NSEC(st);
+ 807 :
+ 808 : /* we have to save the new mtime */
+ 809 0 : state->need_write = 1;
+ 810 : }
+ 811 :
+ 812 : /* if when processing the disk we used the past inodes values */
+ 813 100388 : if (has_past_inodes) {
+ 814 : /* if persistent inodes are supported, we are sure that the inode number */
+ 815 : /* is now different, because otherwise the file would have been found */
+ 816 : /* when searching by inode. */
+ 817 : /* if the inode is different, it means a rewritten file with the same path */
+ 818 : /* like when restoring a backup that restores also the timestamp */
+ 819 100388 : ++scan->count_restore;
+ 820 :
+ 821 100388 : log_tag("scan:restore:%s:%s\n", disk->name, esc(sub));
+ 822 100388 : if (is_diff) {
+ 823 0 : printf("restore %s%s\n", disk->dir, sub);
+ 824 : }
825 :
- 826 : /* reinsert in the inode set */
- 827 100410 : tommy_hashdyn_insert(&disk->inodeset, &file->nodeset, file, file_inode_hash(file->inode));
+ 826 : /* remove from the inode set */
+ 827 100388 : tommy_hashdyn_remove_existing(&disk->inodeset, &file->nodeset);
828 :
- 829 : /* we have to save the new inode */
- 830 100410 : state->need_write = 1;
- 831 : } else {
- 832 : /* otherwise it's the case of not persistent inode, where doesn't */
- 833 : /* matter if the inode is different or equal, because they have no */
- 834 : /* meaning, and then we don't even save them */
- 835 0 : ++scan->count_equal;
- 836 :
- 837 0 : if (state->opt.gui) {
- 838 0 : log_tag("scan:equal:%s:%s\n", disk->name, esc(file->sub));
- 839 : }
- 840 : }
- 841 :
- 842 : /* mark the file as kept */
- 843 100410 : scan_file_keep(scan, file);
- 844 :
- 845 : /* nothing more to do */
- 846 100410 : return;
- 847 : }
- 848 :
- 849 : /* here if the file is changed but with the correct name */
+ 829 : /* save the new inode */
+ 830 100388 : file->inode = st->st_ino;
+ 831 :
+ 832 : /* reinsert in the inode set */
+ 833 100388 : tommy_hashdyn_insert(&disk->inodeset, &file->nodeset, file, file_inode_hash(file->inode));
+ 834 :
+ 835 : /* we have to save the new inode */
+ 836 100388 : state->need_write = 1;
+ 837 : } else {
+ 838 : /* otherwise it's the case of not persistent inode, where doesn't */
+ 839 : /* matter if the inode is different or equal, because they have no */
+ 840 : /* meaning, and then we don't even save them */
+ 841 0 : ++scan->count_equal;
+ 842 :
+ 843 0 : if (state->opt.gui) {
+ 844 0 : log_tag("scan:equal:%s:%s\n", disk->name, esc(file->sub));
+ 845 : }
+ 846 : }
+ 847 :
+ 848 : /* mark the file as kept */
+ 849 100388 : scan_file_keep(scan, file);
850 :
- 851 : /* keep track if the original file was not of zero size */
- 852 4676 : is_original_file_size_different_than_zero = file->size != 0;
- 853 :
- 854 : /* remove it, and continue to insert it again */
- 855 4676 : scan_file_remove(scan, file);
+ 851 : /* nothing more to do */
+ 852 100388 : return;
+ 853 : }
+ 854 :
+ 855 : /* here if the file is changed but with the correct name */
856 :
- 857 : /* and continue to insert it again */
- 858 : }
+ 857 : /* keep track if the original file was not of zero size */
+ 858 4716 : is_original_file_size_different_than_zero = file->size != 0;
859 :
- 860 : /* refresh the info, to ensure that they are synced, */
- 861 : /* note that we refresh only the info of the new or modified files */
- 862 : /* because this is slow operation */
- 863 79146 : scan_file_refresh(scan, sub, st, &physical);
- 864 :
- 865 : /* do a safety check to ensure that the common ext4 case of zeroing */
- 866 : /* the size of a file after a crash doesn't propagate to the backup */
- 867 79146 : if (is_original_file_size_different_than_zero && st->st_size == 0) {
- 868 0 : if (!state->opt.force_zero) {
- 869 : /* LCOV_EXCL_START */
- 870 : log_fatal("The file '%s%s' has unexpected zero size!\n", disk->dir, sub);
- 871 : log_fatal("It's possible that after a kernel crash this file was lost,\n");
- 872 : log_fatal("and you can use 'snapraid --filter %s fix' to recover it.\n", sub);
- 873 : if (!is_diff) {
- 874 : log_fatal("If this an expected condition you can '%s' anyway using 'snapraid --force-zero %s'\n", state->command, state->command);
- 875 : exit(EXIT_FAILURE);
- 876 : }
- 877 : /* LCOV_EXCL_STOP */
- 878 : }
- 879 : }
- 880 :
- 881 : /* insert it */
- 882 79146 : file = file_alloc(state->block_size, sub, st->st_size, st->st_mtime, STAT_NSEC(st), st->st_ino, physical);
- 883 :
- 884 : /* mark it as present */
- 885 79146 : file_flag_set(file, FILE_IS_PRESENT);
- 886 :
- 887 : /* if copy detection is enabled */
- 888 : /* note that the copy detection is tried also for updated files */
- 889 : /* this makes sense because it may happen to have two different copies */
- 890 : /* of the same file, and we move the right one over the wrong one */
- 891 : /* in such case we have a "copy" over an "update" */
- 892 79146 : if (!state->opt.force_nocopy) {
- 893 79146 : tommy_uint32_t hash = file_stamp_hash(file->size, file->mtime_sec, file->mtime_nsec);
- 894 :
- 895 : /* search for a file with the same name and stamp in all the disks */
- 896 518303 : for (i = state->disklist; i != 0; i = i->next) {
- 897 445366 : struct snapraid_disk* other_disk = i->data;
- 898 : struct snapraid_file* other_file;
- 899 :
- 900 : /* if the nanosecond part of the time stamp is valid, search */
- 901 : /* for name and stamp, otherwise for path and stamp */
- 902 445366 : if (file->mtime_nsec != 0 && file->mtime_nsec != STAT_NSEC_INVALID)
- 903 445258 : other_file = tommy_hashdyn_search(&other_disk->stampset, file_namestamp_compare, file, hash);
- 904 : else
- 905 108 : other_file = tommy_hashdyn_search(&other_disk->stampset, file_pathstamp_compare, file, hash);
+ 860 : /* remove it, and continue to insert it again */
+ 861 4716 : scan_file_remove(scan, file);
+ 862 :
+ 863 : /* and continue to insert it again */
+ 864 : }
+ 865 :
+ 866 : /* refresh the info, to ensure that they are synced, */
+ 867 : /* note that we refresh only the info of the new or modified files */
+ 868 : /* because this is slow operation */
+ 869 79190 : scan_file_refresh(scan, sub, st, &physical);
+ 870 :
+ 871 : #ifndef _WIN32
+ 872 : /* do a safety check to ensure that the common ext4 case of zeroing */
+ 873 : /* the size of a file after a crash doesn't propagate to the backup */
+ 874 : /* this check is specific for Linux, so we disable it on Windows */
+ 875 79190 : if (is_original_file_size_different_than_zero && st->st_size == 0) {
+ 876 0 : if (!state->opt.force_zero) {
+ 877 : /* LCOV_EXCL_START */
+ 878 : log_fatal("The file '%s%s' has unexpected zero size!\n", disk->dir, sub);
+ 879 : log_fatal("It's possible that after a kernel crash this file was lost,\n");
+ 880 : log_fatal("and you can use 'snapraid --filter %s fix' to recover it.\n", sub);
+ 881 : if (!is_diff) {
+ 882 : log_fatal("If this an expected condition you can '%s' anyway using 'snapraid --force-zero %s'\n", state->command, state->command);
+ 883 : exit(EXIT_FAILURE);
+ 884 : }
+ 885 : /* LCOV_EXCL_STOP */
+ 886 : }
+ 887 : }
+ 888 : #else
+ 889 : /* avoid the unused warning in Windows */
+ 890 : (void)is_original_file_size_different_than_zero;
+ 891 : #endif
+ 892 :
+ 893 : /* insert it */
+ 894 79190 : file = file_alloc(state->block_size, sub, st->st_size, st->st_mtime, STAT_NSEC(st), st->st_ino, physical);
+ 895 :
+ 896 : /* mark it as present */
+ 897 79190 : file_flag_set(file, FILE_IS_PRESENT);
+ 898 :
+ 899 : /* if copy detection is enabled */
+ 900 : /* note that the copy detection is tried also for updated files */
+ 901 : /* this makes sense because it may happen to have two different copies */
+ 902 : /* of the same file, and we move the right one over the wrong one */
+ 903 : /* in such case we have a "copy" over an "update" */
+ 904 79190 : if (!state->opt.force_nocopy) {
+ 905 79190 : tommy_uint32_t hash = file_stamp_hash(file->size, file->mtime_sec, file->mtime_nsec);
906 :
- 907 : /* if found, and it's a fully hashed file */
- 908 445366 : if (other_file && file_is_full_hashed_and_stable(scan->state, other_disk, other_file)) {
- 909 : /* assume that the file is a copy, and reuse the hash */
- 910 6209 : file_copy(other_file, file);
+ 907 : /* search for a file with the same name and stamp in all the disks */
+ 908 518611 : for (i = state->disklist; i != 0; i = i->next) {
+ 909 445630 : struct snapraid_disk* other_disk = i->data;
+ 910 : struct snapraid_file* other_file;
911 :
- 912 : /* revert old counter and use the copy one */
- 913 6209 : ++scan->count_copy;
- 914 :
- 915 6209 : log_tag("scan:copy:%s:%s:%s:%s\n", other_disk->name, esc(other_file->sub), disk->name, esc(file->sub));
- 916 6209 : if (is_diff) {
- 917 31 : printf("copy %s%s -> %s%s\n", other_disk->dir, other_file->sub, disk->dir, file->sub);
- 918 : }
- 919 :
- 920 : /* mark it as reported */
- 921 6209 : is_file_reported = 1;
- 922 :
- 923 : /* no need to continue the search */
- 924 6209 : break;
- 925 : }
- 926 : }
- 927 : }
- 928 :
- 929 : /* if not yet reported, do it now */
- 930 79146 : if (!is_file_reported) {
- 931 72937 : if (is_file_already_present) {
- 932 4676 : ++scan->count_change;
- 933 :
- 934 4676 : log_tag("scan:update:%s:%s\n", disk->name, esc(sub));
- 935 4676 : if (is_diff) {
- 936 118 : printf("update %s%s\n", disk->dir, sub);
+ 912 : /* if the nanosecond part of the time stamp is valid, search */
+ 913 : /* for name and stamp, otherwise for path and stamp */
+ 914 445630 : if (file->mtime_nsec != 0 && file->mtime_nsec != STAT_NSEC_INVALID)
+ 915 445522 : other_file = tommy_hashdyn_search(&other_disk->stampset, file_namestamp_compare, file, hash);
+ 916 : else
+ 917 108 : other_file = tommy_hashdyn_search(&other_disk->stampset, file_pathstamp_compare, file, hash);
+ 918 :
+ 919 : /* if found, and it's a fully hashed file */
+ 920 445630 : if (other_file && file_is_full_hashed_and_stable(scan->state, other_disk, other_file)) {
+ 921 : /* assume that the file is a copy, and reuse the hash */
+ 922 6209 : file_copy(other_file, file);
+ 923 :
+ 924 : /* revert old counter and use the copy one */
+ 925 6209 : ++scan->count_copy;
+ 926 :
+ 927 6209 : log_tag("scan:copy:%s:%s:%s:%s\n", other_disk->name, esc(other_file->sub), disk->name, esc(file->sub));
+ 928 6209 : if (is_diff) {
+ 929 31 : printf("copy %s%s -> %s%s\n", other_disk->dir, other_file->sub, disk->dir, file->sub);
+ 930 : }
+ 931 :
+ 932 : /* mark it as reported */
+ 933 6209 : is_file_reported = 1;
+ 934 :
+ 935 : /* no need to continue the search */
+ 936 6209 : break;
937 : }
- 938 : } else {
- 939 68261 : ++scan->count_insert;
+ 938 : }
+ 939 : }
940 :
- 941 68261 : log_tag("scan:add:%s:%s\n", disk->name, esc(sub));
- 942 68261 : if (is_diff) {
- 943 17042 : printf("add %s%s\n", disk->dir, sub);
- 944 : }
- 945 : }
- 946 : }
- 947 :
- 948 : /* insert the file in the delayed list */
- 949 79146 : scan_file_insert(scan, file);
- 950 : }
- 951 :
- 952 : /**
- 953 : * Remove the specified dir from the data set.
- 954 : */
- 955 2 : static void scan_emptydir_remove(struct snapraid_scan* scan, struct snapraid_dir* dir)
- 956 : {
- 957 2 : struct snapraid_state* state = scan->state;
- 958 2 : struct snapraid_disk* disk = scan->disk;
+ 941 : /* if not yet reported, do it now */
+ 942 79190 : if (!is_file_reported) {
+ 943 72981 : if (is_file_already_present) {
+ 944 4716 : ++scan->count_change;
+ 945 :
+ 946 4716 : log_tag("scan:update:%s:%s\n", disk->name, esc(sub));
+ 947 4716 : if (is_diff) {
+ 948 118 : printf("update %s%s\n", disk->dir, sub);
+ 949 : }
+ 950 : } else {
+ 951 68265 : ++scan->count_insert;
+ 952 :
+ 953 68265 : log_tag("scan:add:%s:%s\n", disk->name, esc(sub));
+ 954 68265 : if (is_diff) {
+ 955 17044 : printf("add %s%s\n", disk->dir, sub);
+ 956 : }
+ 957 : }
+ 958 : }
959 :
- 960 : /* state changed */
- 961 2 : state->need_write = 1;
- 962 :
- 963 : /* remove the file from the dir containers */
- 964 2 : tommy_hashdyn_remove_existing(&disk->dirset, &dir->nodeset);
- 965 2 : tommy_list_remove_existing(&disk->dirlist, &dir->nodelist);
- 966 :
- 967 : /* deallocate */
- 968 2 : dir_free(dir);
- 969 2 : }
- 970 :
- 971 : /**
- 972 : * Insert the specified dir in the data set.
- 973 : */
- 974 10 : static void scan_emptydir_insert(struct snapraid_scan* scan, struct snapraid_dir* dir)
- 975 : {
- 976 10 : struct snapraid_state* state = scan->state;
- 977 10 : struct snapraid_disk* disk = scan->disk;
+ 960 : /* insert the file in the delayed list */
+ 961 79190 : scan_file_insert(scan, file);
+ 962 : }
+ 963 :
+ 964 : /**
+ 965 : * Remove the specified dir from the data set.
+ 966 : */
+ 967 2 : static void scan_emptydir_remove(struct snapraid_scan* scan, struct snapraid_dir* dir)
+ 968 : {
+ 969 2 : struct snapraid_state* state = scan->state;
+ 970 2 : struct snapraid_disk* disk = scan->disk;
+ 971 :
+ 972 : /* state changed */
+ 973 2 : state->need_write = 1;
+ 974 :
+ 975 : /* remove the file from the dir containers */
+ 976 2 : tommy_hashdyn_remove_existing(&disk->dirset, &dir->nodeset);
+ 977 2 : tommy_list_remove_existing(&disk->dirlist, &dir->nodelist);
978 :
- 979 : /* state changed */
- 980 10 : state->need_write = 1;
- 981 :
- 982 : /* insert the dir in the dir containers */
- 983 10 : tommy_hashdyn_insert(&disk->dirset, &dir->nodeset, dir, dir_name_hash(dir->sub));
- 984 10 : tommy_list_insert_tail(&disk->dirlist, &dir->nodelist, dir);
- 985 10 : }
- 986 :
- 987 : /**
- 988 : * Process a dir.
- 989 : */
- 990 227 : static void scan_emptydir(struct snapraid_scan* scan, const char* sub)
- 991 : {
- 992 227 : struct snapraid_disk* disk = scan->disk;
- 993 : struct snapraid_dir* dir;
- 994 :
- 995 : /* check if the dir already exists */
- 996 227 : dir = tommy_hashdyn_search(&disk->dirset, dir_name_compare, sub, dir_name_hash(sub));
- 997 227 : if (dir) {
- 998 : /* check if multiple files have the same name */
- 999 217 : if (dir_flag_has(dir, FILE_IS_PRESENT)) {
- 1000 : /* LCOV_EXCL_START */
- 1001 : log_fatal("Internal inconsistency for dir '%s%s'\n", disk->dir, sub);
- 1002 : exit(EXIT_FAILURE);
- 1003 : /* LCOV_EXCL_STOP */
- 1004 : }
- 1005 :
- 1006 : /* mark as present */
- 1007 217 : dir_flag_set(dir, FILE_IS_PRESENT);
- 1008 :
- 1009 : /* nothing more to do */
- 1010 444 : return;
- 1011 : } else {
- 1012 : /* and continue to insert it */
- 1013 : }
- 1014 :
- 1015 : /* insert it */
- 1016 10 : dir = dir_alloc(sub);
+ 979 : /* deallocate */
+ 980 2 : dir_free(dir);
+ 981 2 : }
+ 982 :
+ 983 : /**
+ 984 : * Insert the specified dir in the data set.
+ 985 : */
+ 986 10 : static void scan_emptydir_insert(struct snapraid_scan* scan, struct snapraid_dir* dir)
+ 987 : {
+ 988 10 : struct snapraid_state* state = scan->state;
+ 989 10 : struct snapraid_disk* disk = scan->disk;
+ 990 :
+ 991 : /* state changed */
+ 992 10 : state->need_write = 1;
+ 993 :
+ 994 : /* insert the dir in the dir containers */
+ 995 10 : tommy_hashdyn_insert(&disk->dirset, &dir->nodeset, dir, dir_name_hash(dir->sub));
+ 996 10 : tommy_list_insert_tail(&disk->dirlist, &dir->nodelist, dir);
+ 997 10 : }
+ 998 :
+ 999 : /**
+ 1000 : * Process a dir.
+ 1001 : */
+ 1002 227 : static void scan_emptydir(struct snapraid_scan* scan, const char* sub)
+ 1003 : {
+ 1004 227 : struct snapraid_disk* disk = scan->disk;
+ 1005 : struct snapraid_dir* dir;
+ 1006 :
+ 1007 : /* check if the dir already exists */
+ 1008 227 : dir = tommy_hashdyn_search(&disk->dirset, dir_name_compare, sub, dir_name_hash(sub));
+ 1009 227 : if (dir) {
+ 1010 : /* check if multiple files have the same name */
+ 1011 217 : if (dir_flag_has(dir, FILE_IS_PRESENT)) {
+ 1012 : /* LCOV_EXCL_START */
+ 1013 : log_fatal("Internal inconsistency for dir '%s%s'\n", disk->dir, sub);
+ 1014 : exit(EXIT_FAILURE);
+ 1015 : /* LCOV_EXCL_STOP */
+ 1016 : }
1017 :
- 1018 : /* mark it as present */
- 1019 10 : dir_flag_set(dir, FILE_IS_PRESENT);
+ 1018 : /* mark as present */
+ 1019 217 : dir_flag_set(dir, FILE_IS_PRESENT);
1020 :
- 1021 : /* insert it in the delayed insert list */
- 1022 10 : tommy_list_insert_tail(&scan->dir_insert_list, &dir->nodelist, dir);
- 1023 : }
- 1024 :
- 1025 : struct dirent_sorted {
- 1026 : /* node for data structures */
- 1027 : tommy_node node;
- 1028 :
- 1029 : #if HAVE_STRUCT_DIRENT_D_INO
- 1030 : uint64_t d_ino; /**< Inode number. */
- 1031 : #endif
- 1032 : #if HAVE_STRUCT_DIRENT_D_TYPE
- 1033 : uint32_t d_type; /**< File type. */
- 1034 : #endif
- 1035 : #if HAVE_STRUCT_DIRENT_D_STAT
- 1036 : struct stat d_stat; /**< Stat result. */
- 1037 : #endif
- 1038 : char d_name[]; /**< Variable length name. It must be the last field. */
- 1039 : };
- 1040 :
+ 1021 : /* nothing more to do */
+ 1022 444 : return;
+ 1023 : } else {
+ 1024 : /* and continue to insert it */
+ 1025 : }
+ 1026 :
+ 1027 : /* insert it */
+ 1028 10 : dir = dir_alloc(sub);
+ 1029 :
+ 1030 : /* mark it as present */
+ 1031 10 : dir_flag_set(dir, FILE_IS_PRESENT);
+ 1032 :
+ 1033 : /* insert it in the delayed insert list */
+ 1034 10 : tommy_list_insert_tail(&scan->dir_insert_list, &dir->nodelist, dir);
+ 1035 : }
+ 1036 :
+ 1037 : struct dirent_sorted {
+ 1038 : /* node for data structures */
+ 1039 : tommy_node node;
+ 1040 :
1041 : #if HAVE_STRUCT_DIRENT_D_INO
- 1042 103300 : static int dd_ino_compare(const void* void_a, const void* void_b)
- 1043 : {
- 1044 103300 : const struct dirent_sorted* a = void_a;
- 1045 103300 : const struct dirent_sorted* b = void_b;
- 1046 :
- 1047 103300 : if (a->d_ino < b->d_ino)
- 1048 49394 : return -1;
- 1049 53906 : if (a->d_ino > b->d_ino)
- 1050 53906 : return 1;
- 1051 :
- 1052 0 : return 0;
- 1053 : }
- 1054 : #endif
- 1055 :
- 1056 10485267 : static int dd_name_compare(const void* void_a, const void* void_b)
- 1057 : {
- 1058 10485267 : const struct dirent_sorted* a = void_a;
- 1059 10485267 : const struct dirent_sorted* b = void_b;
- 1060 :
- 1061 10485267 : return strcmp(a->d_name, b->d_name);
- 1062 : }
+ 1042 : uint64_t d_ino; /**< Inode number. */
+ 1043 : #endif
+ 1044 : #if HAVE_STRUCT_DIRENT_D_TYPE
+ 1045 : uint32_t d_type; /**< File type. */
+ 1046 : #endif
+ 1047 : #if HAVE_STRUCT_DIRENT_D_STAT
+ 1048 : struct stat d_stat; /**< Stat result. */
+ 1049 : #endif
+ 1050 : char d_name[]; /**< Variable length name. It must be the last field. */
+ 1051 : };
+ 1052 :
+ 1053 : #if HAVE_STRUCT_DIRENT_D_INO
+ 1054 103314 : static int dd_ino_compare(const void* void_a, const void* void_b)
+ 1055 : {
+ 1056 103314 : const struct dirent_sorted* a = void_a;
+ 1057 103314 : const struct dirent_sorted* b = void_b;
+ 1058 :
+ 1059 103314 : if (a->d_ino < b->d_ino)
+ 1060 49400 : return -1;
+ 1061 53914 : if (a->d_ino > b->d_ino)
+ 1062 53914 : return 1;
1063 :
- 1064 : /**
- 1065 : * Return the stat info of a dir entry.
- 1066 : */
- 1067 : #if HAVE_STRUCT_DIRENT_D_STAT
- 1068 : #define DSTAT(file, dd, buf) dstat(dd)
- 1069 : struct stat* dstat(struct dirent_sorted* dd)
- 1070 : {
- 1071 : return &dd->d_stat;
- 1072 : }
- 1073 : #else
- 1074 : #define DSTAT(file, dd, buf) dstat(file, buf)
- 1075 1004147 : struct stat* dstat(const char* file, struct stat* st)
- 1076 : {
- 1077 1004147 : if (lstat(file, st) != 0) {
- 1078 : /* LCOV_EXCL_START */
- 1079 : log_fatal("Error in stat file/directory '%s'. %s.\n", file, strerror(errno));
- 1080 : exit(EXIT_FAILURE);
- 1081 : /* LCOV_EXCL_STOP */
- 1082 : }
- 1083 1004147 : return st;
+ 1064 0 : return 0;
+ 1065 : }
+ 1066 : #endif
+ 1067 :
+ 1068 10485497 : static int dd_name_compare(const void* void_a, const void* void_b)
+ 1069 : {
+ 1070 10485497 : const struct dirent_sorted* a = void_a;
+ 1071 10485497 : const struct dirent_sorted* b = void_b;
+ 1072 :
+ 1073 10485497 : return strcmp(a->d_name, b->d_name);
+ 1074 : }
+ 1075 :
+ 1076 : /**
+ 1077 : * Return the stat info of a dir entry.
+ 1078 : */
+ 1079 : #if HAVE_STRUCT_DIRENT_D_STAT
+ 1080 : #define DSTAT(file, dd, buf) dstat(dd)
+ 1081 : struct stat* dstat(struct dirent_sorted* dd)
+ 1082 : {
+ 1083 : return &dd->d_stat;
1084 : }
- 1085 : #endif
- 1086 :
- 1087 : /**
- 1088 : * Process a directory.
- 1089 : * Return != 0 if at least one file or link is processed.
- 1090 : */
- 1091 1614 : static int scan_dir(struct snapraid_scan* scan, int level, int is_diff, const char* dir, const char* sub)
- 1092 : {
- 1093 1614 : struct snapraid_state* state = scan->state;
- 1094 1614 : struct snapraid_disk* disk = scan->disk;
- 1095 1614 : int processed = 0;
- 1096 : DIR* d;
- 1097 : tommy_list list;
- 1098 : tommy_node* node;
- 1099 :
- 1100 1614 : tommy_list_init(&list);
- 1101 :
- 1102 1614 : d = opendir(dir);
- 1103 1614 : if (!d) {
- 1104 : /* LCOV_EXCL_START */
- 1105 : log_fatal("Error opening directory '%s'. %s.\n", dir, strerror(errno));
- 1106 : if (level == 0)
- 1107 : log_fatal("If this is the disk mount point, remember to create it manually\n");
- 1108 : else
- 1109 : log_fatal("If it's a permission problem, you can exclude it in the config file with:\n\texclude /%s\n", sub);
- 1110 : exit(EXIT_FAILURE);
- 1111 : /* LCOV_EXCL_STOP */
- 1112 : }
+ 1085 : #else
+ 1086 : #define DSTAT(file, dd, buf) dstat(file, buf)
+ 1087 1004217 : struct stat* dstat(const char* file, struct stat* st)
+ 1088 : {
+ 1089 1004217 : if (lstat(file, st) != 0) {
+ 1090 : /* LCOV_EXCL_START */
+ 1091 : log_fatal("Error in stat file/directory '%s'. %s.\n", file, strerror(errno));
+ 1092 : exit(EXIT_FAILURE);
+ 1093 : /* LCOV_EXCL_STOP */
+ 1094 : }
+ 1095 1004217 : return st;
+ 1096 : }
+ 1097 : #endif
+ 1098 :
+ 1099 : /**
+ 1100 : * Process a directory.
+ 1101 : * Return != 0 if at least one file or link is processed.
+ 1102 : */
+ 1103 1614 : static int scan_dir(struct snapraid_scan* scan, int level, int is_diff, const char* dir, const char* sub)
+ 1104 : {
+ 1105 1614 : struct snapraid_state* state = scan->state;
+ 1106 1614 : struct snapraid_disk* disk = scan->disk;
+ 1107 1614 : int processed = 0;
+ 1108 : DIR* d;
+ 1109 : tommy_list list;
+ 1110 : tommy_node* node;
+ 1111 :
+ 1112 1614 : tommy_list_init(&list);
1113 :
- 1114 : /* read the full directory */
- 1115 : while (1) {
- 1116 : char path_next[PATH_MAX];
- 1117 : char sub_next[PATH_MAX];
- 1118 : struct dirent_sorted* entry;
- 1119 : const char* name;
- 1120 : struct dirent* dd;
- 1121 : size_t name_len;
- 1122 :
- 1123 : /* clear errno to detect erroneous conditions */
- 1124 1041655 : errno = 0;
- 1125 1041655 : dd = readdir(d);
- 1126 1041655 : if (dd == 0 && errno != 0) {
- 1127 : /* LCOV_EXCL_START */
- 1128 : log_fatal("Error reading directory '%s'. %s.\n", dir, strerror(errno));
- 1129 : log_fatal("You can exclude it in the config file with:\n\texclude /%s\n", sub);
- 1130 : exit(EXIT_FAILURE);
- 1131 : /* LCOV_EXCL_STOP */
- 1132 : }
- 1133 1041655 : if (dd == 0) {
- 1134 1614 : break; /* finished */
- 1135 : }
- 1136 :
- 1137 : /* skip "." and ".." files */
- 1138 1040041 : name = dd->d_name;
- 1139 1040041 : if (name[0] == '.' && (name[1] == 0 || (name[1] == '.' && name[2] == 0)))
- 1140 6456 : continue;
- 1141 :
- 1142 1036813 : pathprint(path_next, sizeof(path_next), "%s%s", dir, name);
- 1143 1036813 : pathprint(sub_next, sizeof(sub_next), "%s%s", sub, name);
- 1144 :
- 1145 : /* check for not supported file names */
- 1146 1036813 : if (name[0] == 0) {
- 1147 : /* LCOV_EXCL_START */
- 1148 : log_fatal("Unsupported name '%s' in file '%s'.\n", name, path_next);
- 1149 : exit(EXIT_FAILURE);
- 1150 : /* LCOV_EXCL_STOP */
- 1151 : }
- 1152 :
- 1153 : /* exclude hidden files even before calling lstat() */
- 1154 1036813 : if (filter_hidden(state->filter_hidden, dd) != 0) {
- 1155 0 : msg_verbose("Excluding hidden '%s'\n", path_next);
- 1156 0 : continue;
- 1157 : }
- 1158 :
- 1159 : /* exclude content files even before calling lstat() */
- 1160 1036813 : if (filter_content(&state->contentlist, path_next) != 0) {
- 1161 0 : msg_verbose("Excluding content '%s'\n", path_next);
- 1162 0 : continue;
+ 1114 1614 : d = opendir(dir);
+ 1115 1614 : if (!d) {
+ 1116 : /* LCOV_EXCL_START */
+ 1117 : log_fatal("Error opening directory '%s'. %s.\n", dir, strerror(errno));
+ 1118 : if (level == 0)
+ 1119 : log_fatal("If this is the disk mount point, remember to create it manually\n");
+ 1120 : else
+ 1121 : log_fatal("If it's a permission problem, you can exclude it in the config file with:\n\texclude /%s\n", sub);
+ 1122 : exit(EXIT_FAILURE);
+ 1123 : /* LCOV_EXCL_STOP */
+ 1124 : }
+ 1125 :
+ 1126 : /* read the full directory */
+ 1127 : while (1) {
+ 1128 : char path_next[PATH_MAX];
+ 1129 : char sub_next[PATH_MAX];
+ 1130 : struct dirent_sorted* entry;
+ 1131 : const char* name;
+ 1132 : struct dirent* dd;
+ 1133 : size_t name_len;
+ 1134 :
+ 1135 : /* clear errno to detect erroneous conditions */
+ 1136 1041725 : errno = 0;
+ 1137 1041725 : dd = readdir(d);
+ 1138 1041725 : if (dd == 0 && errno != 0) {
+ 1139 : /* LCOV_EXCL_START */
+ 1140 : log_fatal("Error reading directory '%s'. %s.\n", dir, strerror(errno));
+ 1141 : log_fatal("You can exclude it in the config file with:\n\texclude /%s\n", sub);
+ 1142 : exit(EXIT_FAILURE);
+ 1143 : /* LCOV_EXCL_STOP */
+ 1144 : }
+ 1145 1041725 : if (dd == 0) {
+ 1146 1614 : break; /* finished */
+ 1147 : }
+ 1148 :
+ 1149 : /* skip "." and ".." files */
+ 1150 1040111 : name = dd->d_name;
+ 1151 1040111 : if (name[0] == '.' && (name[1] == 0 || (name[1] == '.' && name[2] == 0)))
+ 1152 6456 : continue;
+ 1153 :
+ 1154 1036883 : pathprint(path_next, sizeof(path_next), "%s%s", dir, name);
+ 1155 1036883 : pathprint(sub_next, sizeof(sub_next), "%s%s", sub, name);
+ 1156 :
+ 1157 : /* check for not supported file names */
+ 1158 1036883 : if (name[0] == 0) {
+ 1159 : /* LCOV_EXCL_START */
+ 1160 : log_fatal("Unsupported name '%s' in file '%s'.\n", name, path_next);
+ 1161 : exit(EXIT_FAILURE);
+ 1162 : /* LCOV_EXCL_STOP */
1163 : }
1164 :
- 1165 1036813 : name_len = strlen(dd->d_name);
- 1166 1036813 : entry = malloc_nofail(sizeof(struct dirent_sorted) + name_len + 1);
- 1167 :
- 1168 : /* copy the dir entry */
- 1169 : #if HAVE_STRUCT_DIRENT_D_INO
- 1170 1036813 : entry->d_ino = dd->d_ino;
- 1171 : #endif
- 1172 : #if HAVE_STRUCT_DIRENT_D_TYPE
- 1173 1036813 : entry->d_type = dd->d_type;
- 1174 : #endif
- 1175 : #if HAVE_STRUCT_DIRENT_D_STAT
- 1176 : /* convert dirent to lstat result */
- 1177 : dirent_lstat(dd, &entry->d_stat);
- 1178 :
- 1179 : /* note that at this point the st_mode may be 0 */
- 1180 : #endif
- 1181 1036813 : memcpy(entry->d_name, dd->d_name, name_len + 1);
- 1182 :
- 1183 : /* insert in the list */
- 1184 1036813 : tommy_list_insert_tail(&list, &entry->node, entry);
- 1185 1040041 : }
- 1186 :
- 1187 1614 : if (closedir(d) != 0) {
- 1188 : /* LCOV_EXCL_START */
- 1189 : log_fatal("Error closing directory '%s'. %s.\n", dir, strerror(errno));
- 1190 : exit(EXIT_FAILURE);
- 1191 : /* LCOV_EXCL_STOP */
- 1192 : }
- 1193 :
- 1194 1614 : if (state->opt.force_order == SORT_ALPHA) {
- 1195 : /* if requested sort alphabetically */
- 1196 : /* this is mainly done for testing to ensure to always */
- 1197 : /* process in the same way in different platforms */
- 1198 1578 : tommy_list_sort(&list, dd_name_compare);
- 1199 : }
- 1200 : #if HAVE_STRUCT_DIRENT_D_INO
- 1201 36 : else if (!disk->has_volatile_inodes) {
- 1202 : /* if inodes are persistent */
- 1203 : /* sort the list of dir entries by inodes */
- 1204 36 : tommy_list_sort(&list, dd_ino_compare);
- 1205 : }
- 1206 : /* otherwise just keep the insertion order */
- 1207 : #endif
- 1208 :
- 1209 : /* process the sorted dir entries */
- 1210 1614 : node = list;
- 1211 1040041 : while (node != 0) {
- 1212 : char path_next[PATH_MAX];
- 1213 : char sub_next[PATH_MAX];
- 1214 : char out[PATH_MAX];
- 1215 1036813 : struct snapraid_filter* reason = 0;
- 1216 1036813 : struct dirent_sorted* dd = node->data;
- 1217 1036813 : const char* name = dd->d_name;
- 1218 : struct stat* st;
- 1219 : int type;
- 1220 : #if !HAVE_STRUCT_DIRENT_D_STAT
- 1221 : struct stat st_buf;
- 1222 : #endif
- 1223 :
- 1224 1036813 : pathprint(path_next, sizeof(path_next), "%s%s", dir, name);
- 1225 1036813 : pathprint(sub_next, sizeof(sub_next), "%s%s", sub, name);
- 1226 :
- 1227 : /* start with an unknown type */
- 1228 1036813 : type = -1;
- 1229 1036813 : st = 0;
- 1230 :
- 1231 : /* if dirent has the type, use it */
- 1232 : #if HAVE_STRUCT_DIRENT_D_TYPE
- 1233 1036813 : switch (dd->d_type) {
- 1234 0 : case DT_UNKNOWN : break;
- 1235 1003012 : case DT_REG : type = 0; break;
- 1236 32666 : case DT_LNK : type = 1; break;
- 1237 1135 : case DT_DIR : type = 2; break;
- 1238 0 : default : type = 3; break;
- 1239 : }
- 1240 : #endif
- 1241 :
- 1242 : /* if type is still unknown */
- 1243 1036813 : if (type < 0) {
- 1244 : /* get the type from stat */
- 1245 0 : st = DSTAT(path_next, dd, &st_buf);
- 1246 :
- 1247 : #if HAVE_STRUCT_DIRENT_D_STAT
- 1248 : /* if the st_mode field is missing, takes care to fill it using normal lstat() */
- 1249 : /* at now this can happen only in Windows (with HAVE_STRUCT_DIRENT_D_STAT defined), */
- 1250 : /* because we use a directory reading method that doesn't read info about ReparsePoint. */
- 1251 : /* Note that here we cannot call here lstat_sync(), because we don't know what kind */
- 1252 : /* of file is it, and lstat_sync() doesn't always work */
- 1253 : if (st->st_mode == 0) {
- 1254 : if (lstat(path_next, st) != 0) {
- 1255 : /* LCOV_EXCL_START */
- 1256 : log_fatal("Error in stat file/directory '%s'. %s.\n", path_next, strerror(errno));
- 1257 : exit(EXIT_FAILURE);
- 1258 : /* LCOV_EXCL_STOP */
- 1259 : }
- 1260 : }
- 1261 : #endif
- 1262 :
- 1263 0 : if (S_ISREG(st->st_mode))
- 1264 0 : type = 0;
- 1265 0 : else if (S_ISLNK(st->st_mode))
- 1266 0 : type = 1;
- 1267 0 : else if (S_ISDIR(st->st_mode))
- 1268 0 : type = 2;
- 1269 : else
- 1270 0 : type = 3;
- 1271 : }
- 1272 :
- 1273 1036813 : if (type == 0) { /* REG */
- 1274 1003012 : if (filter_path(&state->filterlist, &reason, disk->name, sub_next) == 0) {
- 1275 :
- 1276 : /* late stat, if not yet called */
- 1277 1003012 : if (!st)
- 1278 1003012 : st = DSTAT(path_next, dd, &st_buf);
- 1279 :
- 1280 : #if HAVE_LSTAT_SYNC
- 1281 : /* if the st_ino field is missing, takes care to fill it using the extended lstat() */
- 1282 : /* this can happen only in Windows */
- 1283 : if (st->st_ino == 0) {
- 1284 : if (lstat_sync(path_next, st, 0) != 0) {
- 1285 : /* LCOV_EXCL_START */
- 1286 : log_fatal("Error in stat file '%s'. %s.\n", path_next, strerror(errno));
- 1287 : exit(EXIT_FAILURE);
- 1288 : /* LCOV_EXCL_STOP */
- 1289 : }
- 1290 : }
- 1291 : #endif
- 1292 :
- 1293 1003012 : scan_file(scan, is_diff, sub_next, st, FILEPHY_UNREAD_OFFSET);
- 1294 1003012 : processed = 1;
- 1295 : } else {
- 1296 0 : msg_verbose("Excluding file '%s' for rule '%s'\n", path_next, filter_type(reason, out, sizeof(out)));
- 1297 : }
- 1298 33801 : } else if (type == 1) { /* LNK */
- 1299 32666 : if (filter_path(&state->filterlist, &reason, disk->name, sub_next) == 0) {
- 1300 : char subnew[PATH_MAX];
- 1301 : int ret;
- 1302 :
- 1303 32666 : ret = readlink(path_next, subnew, sizeof(subnew));
- 1304 32666 : if (ret >= PATH_MAX) {
- 1305 : /* LCOV_EXCL_START */
- 1306 : log_fatal("Error in readlink file '%s'. Symlink too long.\n", path_next);
- 1307 : exit(EXIT_FAILURE);
- 1308 : /* LCOV_EXCL_STOP */
- 1309 : }
- 1310 32666 : if (ret < 0) {
- 1311 : /* LCOV_EXCL_START */
- 1312 : log_fatal("Error in readlink file '%s'. %s.\n", path_next, strerror(errno));
- 1313 : exit(EXIT_FAILURE);
- 1314 : /* LCOV_EXCL_STOP */
- 1315 : }
- 1316 :
- 1317 : /* readlink doesn't put the final 0 */
- 1318 32666 : subnew[ret] = 0;
- 1319 :
- 1320 : /* process as a symbolic link */
- 1321 32666 : scan_link(scan, is_diff, sub_next, subnew, FILE_IS_SYMLINK);
- 1322 32666 : processed = 1;
- 1323 : } else {
- 1324 0 : msg_verbose("Excluding link '%s' for rule '%s'\n", path_next, filter_type(reason, out, sizeof(out)));
- 1325 : }
- 1326 1135 : } else if (type == 2) { /* DIR */
- 1327 1135 : if (filter_dir(&state->filterlist, &reason, disk->name, sub_next) == 0) {
- 1328 : #ifndef _WIN32
- 1329 : /* late stat, if not yet called */
- 1330 1135 : if (!st)
- 1331 1135 : st = DSTAT(path_next, dd, &st_buf);
- 1332 :
- 1333 : /* in Unix don't follow mount points in different devices */
- 1334 : /* in Windows we are already skipping them reporting them as special files */
- 1335 1135 : if ((uint64_t)st->st_dev != disk->device) {
- 1336 0 : log_fatal("WARNING! Ignoring mount point '%s' because it appears to be in a different device\n", path_next);
- 1337 : } else
- 1338 : #endif
- 1339 : {
- 1340 : char sub_dir[PATH_MAX];
- 1341 :
- 1342 : /* recurse */
- 1343 1135 : pathslash(path_next, sizeof(path_next));
- 1344 1135 : pathcpy(sub_dir, sizeof(sub_dir), sub_next);
- 1345 1135 : pathslash(sub_dir, sizeof(sub_dir));
- 1346 1135 : if (scan_dir(scan, level + 1, is_diff, path_next, sub_dir) == 0) {
- 1347 : /* scan the directory as empty dir */
- 1348 227 : scan_emptydir(scan, sub_next);
- 1349 : }
- 1350 : /* or we processed something internally, or we have added the empty dir */
- 1351 1135 : processed = 1;
- 1352 : }
- 1353 : } else {
- 1354 0 : msg_verbose("Excluding directory '%s' for rule '%s'\n", path_next, filter_type(reason, out, sizeof(out)));
- 1355 : }
- 1356 : } else {
- 1357 0 : if (filter_path(&state->filterlist, &reason, disk->name, sub_next) == 0) {
- 1358 : /* late stat, if not yet called */
- 1359 0 : if (!st)
- 1360 0 : st = DSTAT(path_next, dd, &st_buf);
- 1361 :
- 1362 0 : log_fatal("WARNING! Ignoring special '%s' file '%s'\n", stat_desc(st), path_next);
- 1363 : } else {
- 1364 0 : msg_verbose("Excluding special file '%s' for rule '%s'\n", path_next, filter_type(reason, out, sizeof(out)));
- 1365 : }
- 1366 : }
- 1367 :
- 1368 : /* next entry */
- 1369 1036813 : node = node->next;
- 1370 :
- 1371 : /* free the present one */
- 1372 1036813 : free(dd);
- 1373 : }
- 1374 :
- 1375 1614 : return processed;
- 1376 : }
- 1377 :
- 1378 80 : static int state_diffscan(struct snapraid_state* state, int is_diff)
- 1379 : {
- 1380 : tommy_node* i;
- 1381 : tommy_node* j;
- 1382 : tommy_list scanlist;
- 1383 : int done;
- 1384 : fptr* msg;
- 1385 : struct snapraid_scan total;
- 1386 : int no_difference;
- 1387 :
- 1388 80 : tommy_list_init(&scanlist);
+ 1165 : /* exclude hidden files even before calling lstat() */
+ 1166 1036883 : if (filter_hidden(state->filter_hidden, dd) != 0) {
+ 1167 0 : msg_verbose("Excluding hidden '%s'\n", path_next);
+ 1168 0 : continue;
+ 1169 : }
+ 1170 :
+ 1171 : /* exclude content files even before calling lstat() */
+ 1172 1036883 : if (filter_content(&state->contentlist, path_next) != 0) {
+ 1173 0 : msg_verbose("Excluding content '%s'\n", path_next);
+ 1174 0 : continue;
+ 1175 : }
+ 1176 :
+ 1177 1036883 : name_len = strlen(dd->d_name);
+ 1178 1036883 : entry = malloc_nofail(sizeof(struct dirent_sorted) + name_len + 1);
+ 1179 :
+ 1180 : /* copy the dir entry */
+ 1181 : #if HAVE_STRUCT_DIRENT_D_INO
+ 1182 1036883 : entry->d_ino = dd->d_ino;
+ 1183 : #endif
+ 1184 : #if HAVE_STRUCT_DIRENT_D_TYPE
+ 1185 1036883 : entry->d_type = dd->d_type;
+ 1186 : #endif
+ 1187 : #if HAVE_STRUCT_DIRENT_D_STAT
+ 1188 : /* convert dirent to lstat result */
+ 1189 : dirent_lstat(dd, &entry->d_stat);
+ 1190 :
+ 1191 : /* note that at this point the st_mode may be 0 */
+ 1192 : #endif
+ 1193 1036883 : memcpy(entry->d_name, dd->d_name, name_len + 1);
+ 1194 :
+ 1195 : /* insert in the list */
+ 1196 1036883 : tommy_list_insert_tail(&list, &entry->node, entry);
+ 1197 1040111 : }
+ 1198 :
+ 1199 1614 : if (closedir(d) != 0) {
+ 1200 : /* LCOV_EXCL_START */
+ 1201 : log_fatal("Error closing directory '%s'. %s.\n", dir, strerror(errno));
+ 1202 : exit(EXIT_FAILURE);
+ 1203 : /* LCOV_EXCL_STOP */
+ 1204 : }
+ 1205 :
+ 1206 1614 : if (state->opt.force_order == SORT_ALPHA) {
+ 1207 : /* if requested sort alphabetically */
+ 1208 : /* this is mainly done for testing to ensure to always */
+ 1209 : /* process in the same way in different platforms */
+ 1210 1578 : tommy_list_sort(&list, dd_name_compare);
+ 1211 : }
+ 1212 : #if HAVE_STRUCT_DIRENT_D_INO
+ 1213 36 : else if (!disk->has_volatile_inodes) {
+ 1214 : /* if inodes are persistent */
+ 1215 : /* sort the list of dir entries by inodes */
+ 1216 36 : tommy_list_sort(&list, dd_ino_compare);
+ 1217 : }
+ 1218 : /* otherwise just keep the insertion order */
+ 1219 : #endif
+ 1220 :
+ 1221 : /* process the sorted dir entries */
+ 1222 1614 : node = list;
+ 1223 1040111 : while (node != 0) {
+ 1224 : char path_next[PATH_MAX];
+ 1225 : char sub_next[PATH_MAX];
+ 1226 : char out[PATH_MAX];
+ 1227 1036883 : struct snapraid_filter* reason = 0;
+ 1228 1036883 : struct dirent_sorted* dd = node->data;
+ 1229 1036883 : const char* name = dd->d_name;
+ 1230 : struct stat* st;
+ 1231 : int type;
+ 1232 : #if !HAVE_STRUCT_DIRENT_D_STAT
+ 1233 : struct stat st_buf;
+ 1234 : #endif
+ 1235 :
+ 1236 1036883 : pathprint(path_next, sizeof(path_next), "%s%s", dir, name);
+ 1237 1036883 : pathprint(sub_next, sizeof(sub_next), "%s%s", sub, name);
+ 1238 :
+ 1239 : /* start with an unknown type */
+ 1240 1036883 : type = -1;
+ 1241 1036883 : st = 0;
+ 1242 :
+ 1243 : /* if dirent has the type, use it */
+ 1244 : #if HAVE_STRUCT_DIRENT_D_TYPE
+ 1245 1036883 : switch (dd->d_type) {
+ 1246 0 : case DT_UNKNOWN : break;
+ 1247 1003082 : case DT_REG : type = 0; break;
+ 1248 32666 : case DT_LNK : type = 1; break;
+ 1249 1135 : case DT_DIR : type = 2; break;
+ 1250 0 : default : type = 3; break;
+ 1251 : }
+ 1252 : #endif
+ 1253 :
+ 1254 : /* if type is still unknown */
+ 1255 1036883 : if (type < 0) {
+ 1256 : /* get the type from stat */
+ 1257 0 : st = DSTAT(path_next, dd, &st_buf);
+ 1258 :
+ 1259 : #if HAVE_STRUCT_DIRENT_D_STAT
+ 1260 : /* if the st_mode field is missing, takes care to fill it using normal lstat() */
+ 1261 : /* at now this can happen only in Windows (with HAVE_STRUCT_DIRENT_D_STAT defined), */
+ 1262 : /* because we use a directory reading method that doesn't read info about ReparsePoint. */
+ 1263 : /* Note that here we cannot call here lstat_sync(), because we don't know what kind */
+ 1264 : /* of file is it, and lstat_sync() doesn't always work */
+ 1265 : if (st->st_mode == 0) {
+ 1266 : if (lstat(path_next, st) != 0) {
+ 1267 : /* LCOV_EXCL_START */
+ 1268 : log_fatal("Error in stat file/directory '%s'. %s.\n", path_next, strerror(errno));
+ 1269 : exit(EXIT_FAILURE);
+ 1270 : /* LCOV_EXCL_STOP */
+ 1271 : }
+ 1272 : }
+ 1273 : #endif
+ 1274 :
+ 1275 0 : if (S_ISREG(st->st_mode))
+ 1276 0 : type = 0;
+ 1277 0 : else if (S_ISLNK(st->st_mode))
+ 1278 0 : type = 1;
+ 1279 0 : else if (S_ISDIR(st->st_mode))
+ 1280 0 : type = 2;
+ 1281 : else
+ 1282 0 : type = 3;
+ 1283 : }
+ 1284 :
+ 1285 1036883 : if (type == 0) { /* REG */
+ 1286 1003082 : if (filter_path(&state->filterlist, &reason, disk->name, sub_next) == 0) {
+ 1287 :
+ 1288 : /* late stat, if not yet called */
+ 1289 1003082 : if (!st)
+ 1290 1003082 : st = DSTAT(path_next, dd, &st_buf);
+ 1291 :
+ 1292 : #if HAVE_LSTAT_SYNC
+ 1293 : /* if the st_ino field is missing, takes care to fill it using the extended lstat() */
+ 1294 : /* this can happen only in Windows */
+ 1295 : if (st->st_ino == 0) {
+ 1296 : if (lstat_sync(path_next, st, 0) != 0) {
+ 1297 : /* LCOV_EXCL_START */
+ 1298 : log_fatal("Error in stat file '%s'. %s.\n", path_next, strerror(errno));
+ 1299 : exit(EXIT_FAILURE);
+ 1300 : /* LCOV_EXCL_STOP */
+ 1301 : }
+ 1302 : }
+ 1303 : #endif
+ 1304 :
+ 1305 1003082 : scan_file(scan, is_diff, sub_next, st, FILEPHY_UNREAD_OFFSET);
+ 1306 1003082 : processed = 1;
+ 1307 : } else {
+ 1308 0 : msg_verbose("Excluding file '%s' for rule '%s'\n", path_next, filter_type(reason, out, sizeof(out)));
+ 1309 : }
+ 1310 33801 : } else if (type == 1) { /* LNK */
+ 1311 32666 : if (filter_path(&state->filterlist, &reason, disk->name, sub_next) == 0) {
+ 1312 : char subnew[PATH_MAX];
+ 1313 : int ret;
+ 1314 :
+ 1315 32666 : ret = readlink(path_next, subnew, sizeof(subnew));
+ 1316 32666 : if (ret >= PATH_MAX) {
+ 1317 : /* LCOV_EXCL_START */
+ 1318 : log_fatal("Error in readlink file '%s'. Symlink too long.\n", path_next);
+ 1319 : exit(EXIT_FAILURE);
+ 1320 : /* LCOV_EXCL_STOP */
+ 1321 : }
+ 1322 32666 : if (ret < 0) {
+ 1323 : /* LCOV_EXCL_START */
+ 1324 : log_fatal("Error in readlink file '%s'. %s.\n", path_next, strerror(errno));
+ 1325 : exit(EXIT_FAILURE);
+ 1326 : /* LCOV_EXCL_STOP */
+ 1327 : }
+ 1328 :
+ 1329 : /* readlink doesn't put the final 0 */
+ 1330 32666 : subnew[ret] = 0;
+ 1331 :
+ 1332 : /* process as a symbolic link */
+ 1333 32666 : scan_link(scan, is_diff, sub_next, subnew, FILE_IS_SYMLINK);
+ 1334 32666 : processed = 1;
+ 1335 : } else {
+ 1336 0 : msg_verbose("Excluding link '%s' for rule '%s'\n", path_next, filter_type(reason, out, sizeof(out)));
+ 1337 : }
+ 1338 1135 : } else if (type == 2) { /* DIR */
+ 1339 1135 : if (filter_dir(&state->filterlist, &reason, disk->name, sub_next) == 0) {
+ 1340 : #ifndef _WIN32
+ 1341 : /* late stat, if not yet called */
+ 1342 1135 : if (!st)
+ 1343 1135 : st = DSTAT(path_next, dd, &st_buf);
+ 1344 :
+ 1345 : /* in Unix don't follow mount points in different devices */
+ 1346 : /* in Windows we are already skipping them reporting them as special files */
+ 1347 1135 : if ((uint64_t)st->st_dev != disk->device) {
+ 1348 0 : log_fatal("WARNING! Ignoring mount point '%s' because it appears to be in a different device\n", path_next);
+ 1349 : } else
+ 1350 : #endif
+ 1351 : {
+ 1352 : char sub_dir[PATH_MAX];
+ 1353 :
+ 1354 : /* recurse */
+ 1355 1135 : pathslash(path_next, sizeof(path_next));
+ 1356 1135 : pathcpy(sub_dir, sizeof(sub_dir), sub_next);
+ 1357 1135 : pathslash(sub_dir, sizeof(sub_dir));
+ 1358 1135 : if (scan_dir(scan, level + 1, is_diff, path_next, sub_dir) == 0) {
+ 1359 : /* scan the directory as empty dir */
+ 1360 227 : scan_emptydir(scan, sub_next);
+ 1361 : }
+ 1362 : /* or we processed something internally, or we have added the empty dir */
+ 1363 1135 : processed = 1;
+ 1364 : }
+ 1365 : } else {
+ 1366 0 : msg_verbose("Excluding directory '%s' for rule '%s'\n", path_next, filter_type(reason, out, sizeof(out)));
+ 1367 : }
+ 1368 : } else {
+ 1369 0 : if (filter_path(&state->filterlist, &reason, disk->name, sub_next) == 0) {
+ 1370 : /* late stat, if not yet called */
+ 1371 0 : if (!st)
+ 1372 0 : st = DSTAT(path_next, dd, &st_buf);
+ 1373 :
+ 1374 0 : log_fatal("WARNING! Ignoring special '%s' file '%s'\n", stat_desc(st), path_next);
+ 1375 : } else {
+ 1376 0 : msg_verbose("Excluding special file '%s' for rule '%s'\n", path_next, filter_type(reason, out, sizeof(out)));
+ 1377 : }
+ 1378 : }
+ 1379 :
+ 1380 : /* next entry */
+ 1381 1036883 : node = node->next;
+ 1382 :
+ 1383 : /* free the present one */
+ 1384 1036883 : free(dd);
+ 1385 : }
+ 1386 :
+ 1387 1614 : return processed;
+ 1388 : }
1389 :
- 1390 80 : if (is_diff)
- 1391 7 : msg_progress("Comparing...\n");
- 1392 :
- 1393 : /* first scan all the directory and find new and deleted files */
- 1394 559 : for (i = state->disklist; i != 0; i = i->next) {
- 1395 479 : struct snapraid_disk* disk = i->data;
- 1396 : struct snapraid_scan* scan;
- 1397 : tommy_node* node;
- 1398 : int ret;
- 1399 : int has_persistent_inode;
- 1400 :
- 1401 479 : scan = malloc_nofail(sizeof(struct snapraid_scan));
- 1402 479 : scan->state = state;
- 1403 479 : scan->disk = disk;
- 1404 479 : scan->count_equal = 0;
- 1405 479 : scan->count_move = 0;
- 1406 479 : scan->count_copy = 0;
- 1407 479 : scan->count_restore = 0;
- 1408 479 : scan->count_change = 0;
- 1409 479 : scan->count_remove = 0;
- 1410 479 : scan->count_insert = 0;
- 1411 479 : tommy_list_init(&scan->file_insert_list);
- 1412 479 : tommy_list_init(&scan->link_insert_list);
- 1413 479 : tommy_list_init(&scan->dir_insert_list);
- 1414 :
- 1415 479 : tommy_list_insert_tail(&scanlist, &scan->node, scan);
- 1416 :
- 1417 479 : if (!is_diff)
- 1418 437 : msg_progress("Scanning disk %s...\n", disk->name);
- 1419 :
- 1420 : /* check if the disk supports persistent inodes */
- 1421 479 : ret = fsinfo(disk->dir, &has_persistent_inode, 0, 0);
- 1422 479 : if (ret < 0) {
- 1423 : /* LCOV_EXCL_START */
- 1424 : log_fatal("Error accessing disk '%s' to get filesystem info. %s.\n", disk->dir, strerror(errno));
- 1425 : exit(EXIT_FAILURE);
- 1426 : /* LCOV_EXCL_STOP */
- 1427 : }
- 1428 479 : if (!has_persistent_inode) {
- 1429 0 : disk->has_volatile_inodes = 1;
- 1430 : }
+ 1390 80 : static int state_diffscan(struct snapraid_state* state, int is_diff)
+ 1391 : {
+ 1392 : tommy_node* i;
+ 1393 : tommy_node* j;
+ 1394 : tommy_list scanlist;
+ 1395 : int done;
+ 1396 : fptr* msg;
+ 1397 : struct snapraid_scan total;
+ 1398 : int no_difference;
+ 1399 :
+ 1400 80 : tommy_list_init(&scanlist);
+ 1401 :
+ 1402 80 : if (is_diff)
+ 1403 7 : msg_progress("Comparing...\n");
+ 1404 :
+ 1405 : /* first scan all the directory and find new and deleted files */
+ 1406 559 : for (i = state->disklist; i != 0; i = i->next) {
+ 1407 479 : struct snapraid_disk* disk = i->data;
+ 1408 : struct snapraid_scan* scan;
+ 1409 : tommy_node* node;
+ 1410 : int ret;
+ 1411 : int has_persistent_inode;
+ 1412 :
+ 1413 479 : scan = malloc_nofail(sizeof(struct snapraid_scan));
+ 1414 479 : scan->state = state;
+ 1415 479 : scan->disk = disk;
+ 1416 479 : scan->count_equal = 0;
+ 1417 479 : scan->count_move = 0;
+ 1418 479 : scan->count_copy = 0;
+ 1419 479 : scan->count_restore = 0;
+ 1420 479 : scan->count_change = 0;
+ 1421 479 : scan->count_remove = 0;
+ 1422 479 : scan->count_insert = 0;
+ 1423 479 : tommy_list_init(&scan->file_insert_list);
+ 1424 479 : tommy_list_init(&scan->link_insert_list);
+ 1425 479 : tommy_list_init(&scan->dir_insert_list);
+ 1426 :
+ 1427 479 : tommy_list_insert_tail(&scanlist, &scan->node, scan);
+ 1428 :
+ 1429 479 : if (!is_diff)
+ 1430 437 : msg_progress("Scanning disk %s...\n", disk->name);
1431 :
- 1432 : /* if inodes or UUID are not persistent/changed/unsupported */
- 1433 479 : if (disk->has_volatile_inodes || disk->has_different_uuid || disk->has_unsupported_uuid) {
- 1434 : /* remove all the inodes from the inode collection */
- 1435 : /* if they are not persistent, all of them could be changed now */
- 1436 : /* and we don't want to find false matching ones */
- 1437 : /* see scan_file() for more details */
- 1438 75 : node = disk->filelist;
- 1439 150 : while (node) {
- 1440 0 : struct snapraid_file* file = node->data;
- 1441 :
- 1442 0 : node = node->next;
+ 1432 : /* check if the disk supports persistent inodes */
+ 1433 479 : ret = fsinfo(disk->dir, &has_persistent_inode, 0, 0);
+ 1434 479 : if (ret < 0) {
+ 1435 : /* LCOV_EXCL_START */
+ 1436 : log_fatal("Error accessing disk '%s' to get filesystem info. %s.\n", disk->dir, strerror(errno));
+ 1437 : exit(EXIT_FAILURE);
+ 1438 : /* LCOV_EXCL_STOP */
+ 1439 : }
+ 1440 479 : if (!has_persistent_inode) {
+ 1441 0 : disk->has_volatile_inodes = 1;
+ 1442 : }
1443 :
- 1444 : /* remove from the inode set */
- 1445 0 : tommy_hashdyn_remove_existing(&disk->inodeset, &file->nodeset);
- 1446 :
- 1447 : /* clear the inode */
- 1448 0 : file->inode = 0;
- 1449 :
- 1450 : /* mark as missing inode */
- 1451 0 : file_flag_set(file, FILE_IS_WITHOUT_INODE);
- 1452 : }
- 1453 : }
- 1454 :
- 1455 479 : scan_dir(scan, 0, is_diff, disk->dir, "");
- 1456 : }
- 1457 :
- 1458 : /* we split the search in two phases because to detect files */
- 1459 : /* moved from one disk to another we have to start deletion */
- 1460 : /* only when all disks have all the new files found */
+ 1444 : /* if inodes or UUID are not persistent/changed/unsupported */
+ 1445 479 : if (disk->has_volatile_inodes || disk->has_different_uuid || disk->has_unsupported_uuid) {
+ 1446 : /* remove all the inodes from the inode collection */
+ 1447 : /* if they are not persistent, all of them could be changed now */
+ 1448 : /* and we don't want to find false matching ones */
+ 1449 : /* see scan_file() for more details */
+ 1450 75 : node = disk->filelist;
+ 1451 150 : while (node) {
+ 1452 0 : struct snapraid_file* file = node->data;
+ 1453 :
+ 1454 0 : node = node->next;
+ 1455 :
+ 1456 : /* remove from the inode set */
+ 1457 0 : tommy_hashdyn_remove_existing(&disk->inodeset, &file->nodeset);
+ 1458 :
+ 1459 : /* clear the inode */
+ 1460 0 : file->inode = 0;
1461 :
- 1462 : /* now process all the new and deleted files */
- 1463 559 : for (i = scanlist; i != 0; i = i->next) {
- 1464 479 : struct snapraid_scan* scan = i->data;
- 1465 479 : struct snapraid_disk* disk = scan->disk;
- 1466 : tommy_node* node;
- 1467 : unsigned phy_count;
- 1468 : unsigned phy_dup;
- 1469 : uint64_t phy_last;
- 1470 : struct snapraid_file* phy_file_last;
- 1471 :
- 1472 : /* check for removed files */
- 1473 479 : node = disk->filelist;
- 1474 932507 : while (node) {
- 1475 931549 : struct snapraid_file* file = node->data;
- 1476 :
- 1477 : /* next node */
- 1478 931549 : node = node->next;
- 1479 :
- 1480 : /* remove if not present */
- 1481 931549 : if (!file_flag_has(file, FILE_IS_PRESENT)) {
- 1482 29638 : ++scan->count_remove;
+ 1462 : /* mark as missing inode */
+ 1463 0 : file_flag_set(file, FILE_IS_WITHOUT_INODE);
+ 1464 : }
+ 1465 : }
+ 1466 :
+ 1467 479 : scan_dir(scan, 0, is_diff, disk->dir, "");
+ 1468 : }
+ 1469 :
+ 1470 : /* we split the search in two phases because to detect files */
+ 1471 : /* moved from one disk to another we have to start deletion */
+ 1472 : /* only when all disks have all the new files found */
+ 1473 :
+ 1474 : /* now process all the new and deleted files */
+ 1475 559 : for (i = scanlist; i != 0; i = i->next) {
+ 1476 479 : struct snapraid_scan* scan = i->data;
+ 1477 479 : struct snapraid_disk* disk = scan->disk;
+ 1478 : tommy_node* node;
+ 1479 : unsigned phy_count;
+ 1480 : unsigned phy_dup;
+ 1481 : uint64_t phy_last;
+ 1482 : struct snapraid_file* phy_file_last;
1483 :
- 1484 29638 : log_tag("scan:remove:%s:%s\n", disk->name, esc(file->sub));
- 1485 29638 : if (is_diff) {
- 1486 97 : printf("remove %s%s\n", disk->dir, file->sub);
- 1487 : }
+ 1484 : /* check for removed files */
+ 1485 479 : node = disk->filelist;
+ 1486 932532 : while (node) {
+ 1487 931574 : struct snapraid_file* file = node->data;
1488 :
- 1489 29638 : scan_file_remove(scan, file);
- 1490 : }
- 1491 : }
- 1492 :
- 1493 : /* check for removed links */
- 1494 479 : node = disk->linklist;
- 1495 32294 : while (node) {
- 1496 31336 : struct snapraid_link* slink = node->data;
- 1497 :
- 1498 : /* next node */
- 1499 31336 : node = node->next;
+ 1489 : /* next node */
+ 1490 931574 : node = node->next;
+ 1491 :
+ 1492 : /* remove if not present */
+ 1493 931574 : if (!file_flag_has(file, FILE_IS_PRESENT)) {
+ 1494 29638 : ++scan->count_remove;
+ 1495 :
+ 1496 29638 : log_tag("scan:remove:%s:%s\n", disk->name, esc(file->sub));
+ 1497 29638 : if (is_diff) {
+ 1498 97 : printf("remove %s%s\n", disk->dir, file->sub);
+ 1499 : }
1500 :
- 1501 : /* remove if not present */
- 1502 31336 : if (!link_flag_has(slink, FILE_IS_PRESENT)) {
- 1503 956 : ++scan->count_remove;
+ 1501 29638 : scan_file_remove(scan, file);
+ 1502 : }
+ 1503 : }
1504 :
- 1505 956 : log_tag("scan:remove:%s:%s\n", disk->name, esc(slink->sub));
- 1506 956 : if (is_diff) {
- 1507 10 : printf("remove %s%s\n", disk->dir, slink->sub);
- 1508 : }
+ 1505 : /* check for removed links */
+ 1506 479 : node = disk->linklist;
+ 1507 32294 : while (node) {
+ 1508 31336 : struct snapraid_link* slink = node->data;
1509 :
- 1510 956 : scan_link_remove(scan, slink);
- 1511 : }
- 1512 : }
- 1513 :
- 1514 : /* check for removed dirs */
- 1515 479 : node = disk->dirlist;
- 1516 1177 : while (node) {
- 1517 219 : struct snapraid_dir* dir = node->data;
- 1518 :
- 1519 : /* next node */
- 1520 219 : node = node->next;
+ 1510 : /* next node */
+ 1511 31336 : node = node->next;
+ 1512 :
+ 1513 : /* remove if not present */
+ 1514 31336 : if (!link_flag_has(slink, FILE_IS_PRESENT)) {
+ 1515 956 : ++scan->count_remove;
+ 1516 :
+ 1517 956 : log_tag("scan:remove:%s:%s\n", disk->name, esc(slink->sub));
+ 1518 956 : if (is_diff) {
+ 1519 10 : printf("remove %s%s\n", disk->dir, slink->sub);
+ 1520 : }
1521 :
- 1522 : /* remove if not present */
- 1523 219 : if (!dir_flag_has(dir, FILE_IS_PRESENT)) {
- 1524 2 : scan_emptydir_remove(scan, dir);
- 1525 : }
- 1526 : }
- 1527 :
- 1528 : /* sort the files before inserting them */
- 1529 : /* we use a stable sort to ensure that if the reported physical offset/inode */
- 1530 : /* are always 0, we keep at least the directory order */
- 1531 479 : switch (state->opt.force_order) {
- 1532 : case SORT_PHYSICAL :
- 1533 12 : tommy_list_sort(&scan->file_insert_list, file_physical_compare);
- 1534 12 : break;
- 1535 : case SORT_INODE :
- 1536 0 : tommy_list_sort(&scan->file_insert_list, file_inode_compare);
- 1537 0 : break;
- 1538 : case SORT_ALPHA :
- 1539 467 : tommy_list_sort(&scan->file_insert_list, file_path_compare);
- 1540 467 : break;
- 1541 : case SORT_DIR :
- 1542 : /* already in order */
- 1543 0 : break;
- 1544 : }
- 1545 :
- 1546 : /* insert all the new files, we insert them only after the deletion */
- 1547 : /* to reuse the just freed space */
- 1548 : /* also check if the physical offset reported are fakes or not */
- 1549 479 : node = scan->file_insert_list;
- 1550 479 : phy_count = 0;
- 1551 479 : phy_dup = 0;
- 1552 479 : phy_last = FILEPHY_UNREAD_OFFSET;
- 1553 479 : phy_file_last = 0;
- 1554 101888 : while (node) {
- 1555 100930 : struct snapraid_file* file = node->data;
- 1556 :
- 1557 : /* if the file is not empty, count duplicate physical offsets */
- 1558 100930 : if (state->opt.force_order == SORT_PHYSICAL && file->size != 0) {
- 1559 11418 : if (phy_file_last != 0 && file->physical == phy_last
- 1560 : /* files without offset are expected to have duplicates */
- 1561 0 : && phy_last != FILEPHY_WITHOUT_OFFSET
- 1562 : ) {
- 1563 : /* if verbose, print the list of duplicates real offsets */
- 1564 : /* other cases are for offsets not supported, so we don't need to report them file by file */
- 1565 0 : if (phy_last >= FILEPHY_REAL_OFFSET) {
- 1566 0 : log_fatal("WARNING! Files '%s%s' and '%s%s' have the same physical offset %" PRId64 ".\n", disk->dir, phy_file_last->sub, disk->dir, file->sub, phy_last);
- 1567 : }
- 1568 0 : ++phy_dup;
- 1569 : }
- 1570 11418 : phy_file_last = file;
- 1571 11418 : phy_last = file->physical;
- 1572 11418 : ++phy_count;
- 1573 : }
- 1574 :
- 1575 : /* next node */
- 1576 100930 : node = node->next;
- 1577 :
- 1578 : /* insert in the parity */
- 1579 100930 : scan_file_allocate(scan, file);
- 1580 : }
- 1581 :
- 1582 : /* mark the disk without reliable physical offset if it has duplicates */
- 1583 : /* here it should never happen because we already sorted out hardlinks */
- 1584 479 : if (state->opt.force_order == SORT_PHYSICAL && phy_dup > 0) {
- 1585 0 : disk->has_unreliable_physical = 1;
- 1586 : }
- 1587 :
- 1588 : /* insert all the new links */
- 1589 479 : node = scan->link_insert_list;
- 1590 3415 : while (node) {
- 1591 2457 : struct snapraid_link* slink = node->data;
- 1592 :
- 1593 : /* next node */
- 1594 2457 : node = node->next;
- 1595 :
- 1596 : /* insert it */
- 1597 2457 : scan_link_insert(scan, slink);
+ 1522 956 : scan_link_remove(scan, slink);
+ 1523 : }
+ 1524 : }
+ 1525 :
+ 1526 : /* check for removed dirs */
+ 1527 479 : node = disk->dirlist;
+ 1528 1177 : while (node) {
+ 1529 219 : struct snapraid_dir* dir = node->data;
+ 1530 :
+ 1531 : /* next node */
+ 1532 219 : node = node->next;
+ 1533 :
+ 1534 : /* remove if not present */
+ 1535 219 : if (!dir_flag_has(dir, FILE_IS_PRESENT)) {
+ 1536 2 : scan_emptydir_remove(scan, dir);
+ 1537 : }
+ 1538 : }
+ 1539 :
+ 1540 : /* sort the files before inserting them */
+ 1541 : /* we use a stable sort to ensure that if the reported physical offset/inode */
+ 1542 : /* are always 0, we keep at least the directory order */
+ 1543 479 : switch (state->opt.force_order) {
+ 1544 : case SORT_PHYSICAL :
+ 1545 12 : tommy_list_sort(&scan->file_insert_list, file_physical_compare);
+ 1546 12 : break;
+ 1547 : case SORT_INODE :
+ 1548 0 : tommy_list_sort(&scan->file_insert_list, file_inode_compare);
+ 1549 0 : break;
+ 1550 : case SORT_ALPHA :
+ 1551 467 : tommy_list_sort(&scan->file_insert_list, file_path_compare);
+ 1552 467 : break;
+ 1553 : case SORT_DIR :
+ 1554 : /* already in order */
+ 1555 0 : break;
+ 1556 : }
+ 1557 :
+ 1558 : /* insert all the new files, we insert them only after the deletion */
+ 1559 : /* to reuse the just freed space */
+ 1560 : /* also check if the physical offset reported are fakes or not */
+ 1561 479 : node = scan->file_insert_list;
+ 1562 479 : phy_count = 0;
+ 1563 479 : phy_dup = 0;
+ 1564 479 : phy_last = FILEPHY_UNREAD_OFFSET;
+ 1565 479 : phy_file_last = 0;
+ 1566 101933 : while (node) {
+ 1567 100975 : struct snapraid_file* file = node->data;
+ 1568 :
+ 1569 : /* if the file is not empty, count duplicate physical offsets */
+ 1570 100975 : if (state->opt.force_order == SORT_PHYSICAL && file->size != 0) {
+ 1571 11418 : if (phy_file_last != 0 && file->physical == phy_last
+ 1572 : /* files without offset are expected to have duplicates */
+ 1573 0 : && phy_last != FILEPHY_WITHOUT_OFFSET
+ 1574 : ) {
+ 1575 : /* if verbose, print the list of duplicates real offsets */
+ 1576 : /* other cases are for offsets not supported, so we don't need to report them file by file */
+ 1577 0 : if (phy_last >= FILEPHY_REAL_OFFSET) {
+ 1578 0 : log_fatal("WARNING! Files '%s%s' and '%s%s' have the same physical offset %" PRId64 ".\n", disk->dir, phy_file_last->sub, disk->dir, file->sub, phy_last);
+ 1579 : }
+ 1580 0 : ++phy_dup;
+ 1581 : }
+ 1582 11418 : phy_file_last = file;
+ 1583 11418 : phy_last = file->physical;
+ 1584 11418 : ++phy_count;
+ 1585 : }
+ 1586 :
+ 1587 : /* next node */
+ 1588 100975 : node = node->next;
+ 1589 :
+ 1590 : /* insert in the parity */
+ 1591 100975 : scan_file_allocate(scan, file);
+ 1592 : }
+ 1593 :
+ 1594 : /* mark the disk without reliable physical offset if it has duplicates */
+ 1595 : /* here it should never happen because we already sorted out hardlinks */
+ 1596 479 : if (state->opt.force_order == SORT_PHYSICAL && phy_dup > 0) {
+ 1597 0 : disk->has_unreliable_physical = 1;
1598 : }
1599 :
- 1600 : /* insert all the new dirs */
- 1601 479 : node = scan->dir_insert_list;
- 1602 968 : while (node) {
- 1603 10 : struct snapraid_dir* dir = node->data;
+ 1600 : /* insert all the new links */
+ 1601 479 : node = scan->link_insert_list;
+ 1602 3415 : while (node) {
+ 1603 2457 : struct snapraid_link* slink = node->data;
1604 :
1605 : /* next node */
- 1606 10 : node = node->next;
+ 1606 2457 : node = node->next;
1607 :
1608 : /* insert it */
- 1609 10 : scan_emptydir_insert(scan, dir);
+ 1609 2457 : scan_link_insert(scan, slink);
1610 : }
- 1611 : }
- 1612 :
- 1613 : /* check for disks where all the previously existing files where removed */
- 1614 80 : if (!state->opt.force_empty) {
- 1615 75 : int all_missing = 0;
- 1616 75 : int all_rewritten = 0;
- 1617 75 : done = 0;
- 1618 524 : for (i = state->disklist, j = scanlist; i != 0; i = i->next, j = j->next) {
- 1619 449 : struct snapraid_disk* disk = i->data;
- 1620 449 : struct snapraid_scan* scan = j->data;
- 1621 :
- 1622 449 : if (scan->count_equal == 0
- 1623 60 : && scan->count_move == 0
- 1624 60 : && scan->count_restore == 0
- 1625 60 : && (scan->count_remove != 0 || scan->count_change != 0)
- 1626 : ) {
- 1627 1 : if (!done) {
- 1628 1 : done = 1;
- 1629 1 : log_fatal("WARNING! All the files previously present in disk '%s' at dir '%s'", disk->name, disk->dir);
- 1630 : } else {
- 1631 0 : log_fatal(", disk '%s' at dir '%s'", disk->name, disk->dir);
- 1632 : }
+ 1611 :
+ 1612 : /* insert all the new dirs */
+ 1613 479 : node = scan->dir_insert_list;
+ 1614 968 : while (node) {
+ 1615 10 : struct snapraid_dir* dir = node->data;
+ 1616 :
+ 1617 : /* next node */
+ 1618 10 : node = node->next;
+ 1619 :
+ 1620 : /* insert it */
+ 1621 10 : scan_emptydir_insert(scan, dir);
+ 1622 : }
+ 1623 : }
+ 1624 :
+ 1625 : /* check for disks where all the previously existing files where removed */
+ 1626 80 : if (!state->opt.force_empty) {
+ 1627 75 : int all_missing = 0;
+ 1628 75 : int all_rewritten = 0;
+ 1629 75 : done = 0;
+ 1630 524 : for (i = state->disklist, j = scanlist; i != 0; i = i->next, j = j->next) {
+ 1631 449 : struct snapraid_disk* disk = i->data;
+ 1632 449 : struct snapraid_scan* scan = j->data;
1633 :
- 1634 : /* detect the special condition of all files missing */
- 1635 1 : if (scan->count_change == 0)
- 1636 1 : all_missing = 1;
- 1637 :
- 1638 : /* detect the special condition of all files rewritten */
- 1639 1 : if (scan->count_remove == 0)
- 1640 0 : all_rewritten = 1;
- 1641 : }
- 1642 : }
- 1643 75 : if (done) {
- 1644 1 : log_fatal("\nare now missing or rewritten!\n");
- 1645 1 : if (all_rewritten) {
- 1646 0 : log_fatal("This could happen when restoring a disk with a backup\n");
- 1647 0 : log_fatal("program that is not setting correctly the timestamps.\n");
- 1648 : }
- 1649 1 : if (all_missing) {
- 1650 1 : log_fatal("This could happen when some disks are not mounted\n");
- 1651 1 : log_fatal("in the expected directory.\n");
- 1652 : }
- 1653 1 : if (!is_diff) {
- 1654 1 : log_fatal("If you want to '%s' anyway, use 'snapraid --force-empty %s'.", state->command, state->command);
- 1655 1 : exit(EXIT_FAILURE);
- 1656 : }
- 1657 : }
- 1658 : }
- 1659 :
- 1660 : /* check for disks without the physical offset support */
- 1661 79 : if (state->opt.force_order == SORT_PHYSICAL) {
- 1662 2 : done = 0;
- 1663 14 : for (i = state->disklist; i != 0; i = i->next) {
- 1664 12 : struct snapraid_disk* disk = i->data;
- 1665 :
- 1666 12 : if (disk->has_unreliable_physical) {
- 1667 0 : if (!done) {
- 1668 0 : done = 1;
- 1669 0 : log_fatal("WARNING! Physical offsets not supported for disk '%s'", disk->name);
- 1670 : } else {
- 1671 0 : log_fatal(", '%s'", disk->name);
- 1672 : }
- 1673 : }
- 1674 : }
- 1675 2 : if (done) {
- 1676 0 : log_fatal(". Files order won't be optimal.\n");
- 1677 : }
- 1678 : }
- 1679 :
- 1680 : /* check for disks without persistent inodes */
- 1681 79 : done = 0;
- 1682 552 : for (i = state->disklist; i != 0; i = i->next) {
- 1683 473 : struct snapraid_disk* disk = i->data;
- 1684 :
- 1685 473 : if (disk->has_volatile_inodes) {
- 1686 0 : if (!done) {
- 1687 0 : done = 1;
- 1688 0 : log_fatal("WARNING! Inodes are not persistent for disks: '%s'", disk->name);
- 1689 : } else {
- 1690 0 : log_fatal(", '%s'", disk->name);
- 1691 : }
- 1692 : }
- 1693 : }
- 1694 79 : if (done) {
- 1695 0 : log_fatal(". Move operations won't be optimal.\n");
- 1696 : }
- 1697 :
- 1698 : /* check for disks with changed UUID */
- 1699 79 : done = 0;
- 1700 552 : for (i = state->disklist; i != 0; i = i->next) {
- 1701 473 : struct snapraid_disk* disk = i->data;
- 1702 :
- 1703 : /* don't print the message if the UUID changed because before */
- 1704 : /* it was no set. */
- 1705 : /* this is the normal condition for an empty disk because it */
- 1706 : /* isn't stored */
- 1707 473 : if (disk->has_different_uuid && !disk->had_empty_uuid) {
- 1708 0 : if (!done) {
- 1709 0 : done = 1;
- 1710 0 : log_fatal("WARNING! UUID is changed for disks: '%s'", disk->name);
- 1711 : } else {
- 1712 0 : log_fatal(", '%s'", disk->name);
- 1713 : }
- 1714 : }
- 1715 : }
- 1716 79 : if (done) {
- 1717 0 : log_fatal(". Move operations won't be optimal.\n");
- 1718 : }
- 1719 :
- 1720 : /* check for disks with unsupported UUID */
- 1721 79 : done = 0;
- 1722 552 : for (i = state->disklist; i != 0; i = i->next) {
- 1723 473 : struct snapraid_disk* disk = i->data;
- 1724 :
- 1725 473 : if (disk->has_unsupported_uuid) {
- 1726 0 : if (!done) {
- 1727 0 : done = 1;
- 1728 0 : log_fatal("WARNING! UUID is unsupported for disks: '%s'", disk->name);
- 1729 : } else {
- 1730 0 : log_fatal(", '%s'", disk->name);
- 1731 : }
- 1732 : }
- 1733 : }
- 1734 79 : if (done) {
- 1735 0 : log_fatal(". Move operations won't be optimal.\n");
- 1736 : }
- 1737 :
- 1738 79 : total.count_equal = 0;
- 1739 79 : total.count_move = 0;
- 1740 79 : total.count_copy = 0;
- 1741 79 : total.count_restore = 0;
- 1742 79 : total.count_change = 0;
- 1743 79 : total.count_remove = 0;
- 1744 79 : total.count_insert = 0;
- 1745 :
- 1746 552 : for (i = scanlist; i != 0; i = i->next) {
- 1747 473 : struct snapraid_scan* scan = i->data;
- 1748 473 : total.count_equal += scan->count_equal;
- 1749 473 : total.count_move += scan->count_move;
- 1750 473 : total.count_copy += scan->count_copy;
- 1751 473 : total.count_restore += scan->count_restore;
- 1752 473 : total.count_change += scan->count_change;
- 1753 473 : total.count_remove += scan->count_remove;
- 1754 473 : total.count_insert += scan->count_insert;
- 1755 : }
- 1756 :
- 1757 79 : if (is_diff) {
- 1758 7 : msg_status("\n");
- 1759 7 : msg = msg_status;
- 1760 : } else {
- 1761 72 : msg = msg_verbose;
- 1762 : }
- 1763 :
- 1764 79 : msg("%8u equal\n", total.count_equal);
- 1765 79 : msg("%8u moved\n", total.count_move);
- 1766 79 : msg("%8u copied\n", total.count_copy);
- 1767 79 : msg("%8u restored\n", total.count_restore);
- 1768 79 : msg("%8u updated\n", total.count_change);
- 1769 79 : msg("%8u removed\n", total.count_remove);
- 1770 79 : msg("%8u added\n", total.count_insert);
- 1771 :
- 1772 79 : log_tag("summary:equal:%u\n", total.count_equal);
- 1773 79 : log_tag("summary:moved:%u\n", total.count_move);
- 1774 79 : log_tag("summary:copied:%u\n", total.count_copy);
- 1775 79 : log_tag("summary:restored:%u\n", total.count_restore);
- 1776 79 : log_tag("summary:updated:%u\n", total.count_change);
- 1777 79 : log_tag("summary:removed:%u\n", total.count_remove);
- 1778 79 : log_tag("summary:added:%u\n", total.count_insert);
- 1779 :
- 1780 236 : no_difference = !total.count_move && !total.count_copy && !total.count_restore
- 1781 129 : && !total.count_change && !total.count_remove && !total.count_insert;
- 1782 :
- 1783 79 : if (is_diff) {
- 1784 7 : if (no_difference) {
- 1785 1 : msg_status("No differences\n");
- 1786 : } else {
- 1787 6 : msg_status("There are differences!\n");
- 1788 : }
- 1789 : }
- 1790 :
- 1791 79 : if (no_difference) {
- 1792 9 : log_tag("summary:exit:equal\n");
- 1793 : } else {
- 1794 70 : log_tag("summary:exit:diff\n");
- 1795 : }
- 1796 79 : log_flush();
- 1797 :
- 1798 79 : tommy_list_foreach(&scanlist, (tommy_foreach_func*)free);
- 1799 :
- 1800 : /* check the filesystem on all disks */
- 1801 79 : state_fscheck(state, "after scan");
+ 1634 449 : if (scan->count_equal == 0
+ 1635 60 : && scan->count_move == 0
+ 1636 60 : && scan->count_restore == 0
+ 1637 60 : && (scan->count_remove != 0 || scan->count_change != 0)
+ 1638 : ) {
+ 1639 1 : if (!done) {
+ 1640 1 : done = 1;
+ 1641 1 : log_fatal("WARNING! All the files previously present in disk '%s' at dir '%s'", disk->name, disk->dir);
+ 1642 : } else {
+ 1643 0 : log_fatal(", disk '%s' at dir '%s'", disk->name, disk->dir);
+ 1644 : }
+ 1645 :
+ 1646 : /* detect the special condition of all files missing */
+ 1647 1 : if (scan->count_change == 0)
+ 1648 1 : all_missing = 1;
+ 1649 :
+ 1650 : /* detect the special condition of all files rewritten */
+ 1651 1 : if (scan->count_remove == 0)
+ 1652 0 : all_rewritten = 1;
+ 1653 : }
+ 1654 : }
+ 1655 75 : if (done) {
+ 1656 1 : log_fatal("\nare now missing or rewritten!\n");
+ 1657 1 : if (all_rewritten) {
+ 1658 0 : log_fatal("This could happen when restoring a disk with a backup\n");
+ 1659 0 : log_fatal("program that is not setting correctly the timestamps.\n");
+ 1660 : }
+ 1661 1 : if (all_missing) {
+ 1662 1 : log_fatal("This could happen when some disks are not mounted\n");
+ 1663 1 : log_fatal("in the expected directory.\n");
+ 1664 : }
+ 1665 1 : if (!is_diff) {
+ 1666 1 : log_fatal("If you want to '%s' anyway, use 'snapraid --force-empty %s'.", state->command, state->command);
+ 1667 1 : exit(EXIT_FAILURE);
+ 1668 : }
+ 1669 : }
+ 1670 : }
+ 1671 :
+ 1672 : /* check for disks without the physical offset support */
+ 1673 79 : if (state->opt.force_order == SORT_PHYSICAL) {
+ 1674 2 : done = 0;
+ 1675 14 : for (i = state->disklist; i != 0; i = i->next) {
+ 1676 12 : struct snapraid_disk* disk = i->data;
+ 1677 :
+ 1678 12 : if (disk->has_unreliable_physical) {
+ 1679 0 : if (!done) {
+ 1680 0 : done = 1;
+ 1681 0 : log_fatal("WARNING! Physical offsets not supported for disk '%s'", disk->name);
+ 1682 : } else {
+ 1683 0 : log_fatal(", '%s'", disk->name);
+ 1684 : }
+ 1685 : }
+ 1686 : }
+ 1687 2 : if (done) {
+ 1688 0 : log_fatal(". Files order won't be optimal.\n");
+ 1689 : }
+ 1690 : }
+ 1691 :
+ 1692 : /* check for disks without persistent inodes */
+ 1693 79 : done = 0;
+ 1694 552 : for (i = state->disklist; i != 0; i = i->next) {
+ 1695 473 : struct snapraid_disk* disk = i->data;
+ 1696 :
+ 1697 473 : if (disk->has_volatile_inodes) {
+ 1698 0 : if (!done) {
+ 1699 0 : done = 1;
+ 1700 0 : log_fatal("WARNING! Inodes are not persistent for disks: '%s'", disk->name);
+ 1701 : } else {
+ 1702 0 : log_fatal(", '%s'", disk->name);
+ 1703 : }
+ 1704 : }
+ 1705 : }
+ 1706 79 : if (done) {
+ 1707 0 : log_fatal(". Move operations won't be optimal.\n");
+ 1708 : }
+ 1709 :
+ 1710 : /* check for disks with changed UUID */
+ 1711 79 : done = 0;
+ 1712 552 : for (i = state->disklist; i != 0; i = i->next) {
+ 1713 473 : struct snapraid_disk* disk = i->data;
+ 1714 :
+ 1715 : /* don't print the message if the UUID changed because before */
+ 1716 : /* it was no set. */
+ 1717 : /* this is the normal condition for an empty disk because it */
+ 1718 : /* isn't stored */
+ 1719 473 : if (disk->has_different_uuid && !disk->had_empty_uuid) {
+ 1720 0 : if (!done) {
+ 1721 0 : done = 1;
+ 1722 0 : log_fatal("WARNING! UUID is changed for disks: '%s'", disk->name);
+ 1723 : } else {
+ 1724 0 : log_fatal(", '%s'", disk->name);
+ 1725 : }
+ 1726 : }
+ 1727 : }
+ 1728 79 : if (done) {
+ 1729 0 : log_fatal(". Move operations won't be optimal.\n");
+ 1730 : }
+ 1731 :
+ 1732 : /* check for disks with unsupported UUID */
+ 1733 79 : done = 0;
+ 1734 552 : for (i = state->disklist; i != 0; i = i->next) {
+ 1735 473 : struct snapraid_disk* disk = i->data;
+ 1736 :
+ 1737 473 : if (disk->has_unsupported_uuid) {
+ 1738 0 : if (!done) {
+ 1739 0 : done = 1;
+ 1740 0 : log_fatal("WARNING! UUID is unsupported for disks: '%s'", disk->name);
+ 1741 : } else {
+ 1742 0 : log_fatal(", '%s'", disk->name);
+ 1743 : }
+ 1744 : }
+ 1745 : }
+ 1746 79 : if (done) {
+ 1747 0 : log_fatal(". Move operations won't be optimal.\n");
+ 1748 : }
+ 1749 :
+ 1750 79 : total.count_equal = 0;
+ 1751 79 : total.count_move = 0;
+ 1752 79 : total.count_copy = 0;
+ 1753 79 : total.count_restore = 0;
+ 1754 79 : total.count_change = 0;
+ 1755 79 : total.count_remove = 0;
+ 1756 79 : total.count_insert = 0;
+ 1757 :
+ 1758 552 : for (i = scanlist; i != 0; i = i->next) {
+ 1759 473 : struct snapraid_scan* scan = i->data;
+ 1760 473 : total.count_equal += scan->count_equal;
+ 1761 473 : total.count_move += scan->count_move;
+ 1762 473 : total.count_copy += scan->count_copy;
+ 1763 473 : total.count_restore += scan->count_restore;
+ 1764 473 : total.count_change += scan->count_change;
+ 1765 473 : total.count_remove += scan->count_remove;
+ 1766 473 : total.count_insert += scan->count_insert;
+ 1767 : }
+ 1768 :
+ 1769 79 : if (is_diff) {
+ 1770 7 : msg_status("\n");
+ 1771 7 : msg = msg_status;
+ 1772 : } else {
+ 1773 72 : msg = msg_verbose;
+ 1774 : }
+ 1775 :
+ 1776 79 : msg("%8u equal\n", total.count_equal);
+ 1777 79 : msg("%8u moved\n", total.count_move);
+ 1778 79 : msg("%8u copied\n", total.count_copy);
+ 1779 79 : msg("%8u restored\n", total.count_restore);
+ 1780 79 : msg("%8u updated\n", total.count_change);
+ 1781 79 : msg("%8u removed\n", total.count_remove);
+ 1782 79 : msg("%8u added\n", total.count_insert);
+ 1783 :
+ 1784 79 : log_tag("summary:equal:%u\n", total.count_equal);
+ 1785 79 : log_tag("summary:moved:%u\n", total.count_move);
+ 1786 79 : log_tag("summary:copied:%u\n", total.count_copy);
+ 1787 79 : log_tag("summary:restored:%u\n", total.count_restore);
+ 1788 79 : log_tag("summary:updated:%u\n", total.count_change);
+ 1789 79 : log_tag("summary:removed:%u\n", total.count_remove);
+ 1790 79 : log_tag("summary:added:%u\n", total.count_insert);
+ 1791 :
+ 1792 236 : no_difference = !total.count_move && !total.count_copy && !total.count_restore
+ 1793 129 : && !total.count_change && !total.count_remove && !total.count_insert;
+ 1794 :
+ 1795 79 : if (is_diff) {
+ 1796 7 : if (no_difference) {
+ 1797 1 : msg_status("No differences\n");
+ 1798 : } else {
+ 1799 6 : msg_status("There are differences!\n");
+ 1800 : }
+ 1801 : }
1802 :
- 1803 79 : if (is_diff) {
- 1804 : /* check for file difference */
- 1805 7 : if (!no_difference)
- 1806 6 : return 1;
- 1807 :
- 1808 : /* check also for incomplete "sync" */
- 1809 1 : if (parity_is_invalid(state))
- 1810 0 : return 1;
- 1811 : }
- 1812 :
- 1813 73 : return 0;
- 1814 : }
- 1815 :
- 1816 7 : int state_diff(struct snapraid_state* state)
- 1817 : {
- 1818 7 : return state_diffscan(state, 1);
- 1819 : }
- 1820 :
- 1821 73 : void state_scan(struct snapraid_state* state)
- 1822 : {
- 1823 73 : (void)state_diffscan(state, 0); /* ignore return value */
- 1824 72 : }
- 1825 :
+ 1803 79 : if (no_difference) {
+ 1804 9 : log_tag("summary:exit:equal\n");
+ 1805 : } else {
+ 1806 70 : log_tag("summary:exit:diff\n");
+ 1807 : }
+ 1808 79 : log_flush();
+ 1809 :
+ 1810 79 : tommy_list_foreach(&scanlist, (tommy_foreach_func*)free);
+ 1811 :
+ 1812 : /* check the filesystem on all disks */
+ 1813 79 : state_fscheck(state, "after scan");
+ 1814 :
+ 1815 79 : if (is_diff) {
+ 1816 : /* check for file difference */
+ 1817 7 : if (!no_difference)
+ 1818 6 : return 1;
+ 1819 :
+ 1820 : /* check also for incomplete "sync" */
+ 1821 1 : if (parity_is_invalid(state))
+ 1822 0 : return 1;
+ 1823 : }
+ 1824 :
+ 1825 73 : return 0;
+ 1826 : }
+ 1827 :
+ 1828 7 : int state_diff(struct snapraid_state* state)
+ 1829 : {
+ 1830 7 : return state_diffscan(state, 1);
+ 1831 : }
+ 1832 :
+ 1833 73 : void state_scan(struct snapraid_state* state)
+ 1834 : {
+ 1835 73 : (void)state_diffscan(state, 0); /* ignore return value */
+ 1836 72 : }
+ 1837 :
diff --git a/cov/cmdline/scrub.c.func-sort-c.html b/cov/cmdline/scrub.c.func-sort-c.html
index 9ecf00a2..a40ea5f0 100644
--- a/cov/cmdline/scrub.c.func-sort-c.html
+++ b/cov/cmdline/scrub.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/cmdline/scrub.c.func.html b/cov/cmdline/scrub.c.func.html
index 7a283e31..9815b4ce 100644
--- a/cov/cmdline/scrub.c.func.html
+++ b/cov/cmdline/scrub.c.func.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/cmdline/scrub.c.gcov.html b/cov/cmdline/scrub.c.gcov.html
index 6e6097d8..751e79a9 100644
--- a/cov/cmdline/scrub.c.gcov.html
+++ b/cov/cmdline/scrub.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -122,12 +122,12 @@
60 :
61 : /* bad blocks are always scrubbed in all plans */
62 111818 : if (info_get_bad(info))
- 63 3606 : return 1;
+ 63 3604 : return 1;
64 :
- 65 108212 : switch (plan->plan) {
+ 65 108214 : switch (plan->plan) {
66 : case SCRUB_FULL :
67 : /* in 'full' plan everything is scrubbed */
- 68 16918 : return 1;
+ 68 16920 : return 1;
69 : case SCRUB_EVEN :
70 : /* in 'even' plan, scrub only even blocks */
71 18398 : return i % 2 == 0;
@@ -143,19 +143,19 @@
81 56052 : blocktime = info_get_time(info);
82 56052 : if (blocktime > plan->timelimit) {
83 : /* skip it */
- 84 20666 : return 0;
+ 84 22506 : return 0;
85 : }
86 :
87 : /* if the time is less than the limit, always include */
88 : /* otherwise, check if we reached the last limit count */
- 89 35386 : if (blocktime == plan->timelimit) {
+ 89 33546 : if (blocktime == plan->timelimit) {
90 : /* if we reached the count limit */
- 91 18912 : if (plan->countlast >= plan->lastlimit) {
+ 91 16872 : if (plan->countlast >= plan->lastlimit) {
92 : /* skip it */
- 93 13722 : return 0;
+ 93 11882 : return 0;
94 : }
95 :
- 96 5190 : ++plan->countlast;
+ 96 4990 : ++plan->countlast;
97 : }
98 :
99 21664 : return 1;
@@ -304,9 +304,9 @@
242 : /* if the file is different than the current one, close it */
243 166241 : if (handle[j].file != 0 && handle[j].file != file) {
244 : /* keep a pointer at the file we are going to close for error reporting */
- 245 78213 : struct snapraid_file* report = handle[j].file;
- 246 78213 : ret = handle_close(&handle[j]);
- 247 78213 : if (ret == -1) {
+ 245 78552 : struct snapraid_file* report = handle[j].file;
+ 246 78552 : ret = handle_close(&handle[j]);
+ 247 78552 : if (ret == -1) {
248 : /* LCOV_EXCL_START */
249 : /* This one is really an unexpected error, because we are only reading */
250 : /* and closing a descriptor should never fail */
@@ -351,12 +351,12 @@
289 : /* check if the file is changed */
290 166241 : if (handle[j].st.st_size != file->size
291 166241 : || handle[j].st.st_mtime != file->mtime_sec
- 292 160519 : || STAT_NSEC(&handle[j].st) != file->mtime_nsec
+ 292 160522 : || STAT_NSEC(&handle[j].st) != file->mtime_nsec
293 : /* don't check the inode to support filesystem without persistent inodes */
294 : ) {
295 : /* report that the block and the file are not synced */
- 296 5722 : block_is_unsynced = 1;
- 297 5722 : file_is_unsynced = 1;
+ 296 5719 : block_is_unsynced = 1;
+ 297 5719 : file_is_unsynced = 1;
298 : /* follow */
299 : }
300 :
@@ -728,12 +728,12 @@
666 : /* output the info map */
667 11 : i = 0;
668 11 : log_tag("info_count:%u\n", count);
- 669 51 : while (i < count) {
- 670 29 : unsigned j = i + 1;
- 671 55938 : while (j < count && timemap[i] == timemap[j])
- 672 55880 : ++j;
- 673 29 : log_tag("info_time:%" PRIu64 ":%u\n", (uint64_t)timemap[i], j - i);
- 674 29 : i = j;
+ 669 54 : while (i < count) {
+ 670 32 : unsigned j = i + 1;
+ 671 55941 : while (j < count && timemap[i] == timemap[j])
+ 672 55877 : ++j;
+ 673 32 : log_tag("info_time:%" PRIu64 ":%u\n", (uint64_t)timemap[i], j - i);
+ 674 32 : i = j;
675 : }
676 :
677 : /* compute the limits from count/recentlimit */
@@ -754,8 +754,8 @@
692 : /* count how many entries for this exact time we have to scrub */
693 : /* if the blocks have all the same time, we end with countlimit == lastlimit */
694 5 : ps.lastlimit = 1;
- 695 2600 : while (countlimit > ps.lastlimit && timemap[countlimit - ps.lastlimit - 1] == ps.timelimit)
- 696 2590 : ++ps.lastlimit;
+ 695 2500 : while (countlimit > ps.lastlimit && timemap[countlimit - ps.lastlimit - 1] == ps.timelimit)
+ 696 2490 : ++ps.lastlimit;
697 : } else {
698 : /* if nothing to scrub, disable also other limits */
699 1 : ps.timelimit = 0;
@@ -763,53 +763,52 @@
701 : }
702 :
703 6 : log_tag("count_limit:%u\n", countlimit);
- 704 : }
- 705 :
- 706 11 : log_tag("time_limit:%" PRIu64 "\n", (uint64_t)ps.timelimit);
- 707 11 : log_tag("last_limit:%u\n", ps.lastlimit);
- 708 :
- 709 : /* free the temp vector */
- 710 11 : free(timemap);
- 711 :
- 712 : /* open the file for reading */
- 713 77 : for (l = 0; l < state->level; ++l) {
- 714 66 : parity_ptr[l] = &parity[l];
- 715 66 : ret = parity_open(parity_ptr[l], state->parity[l].path, state->file_mode);
- 716 66 : if (ret == -1) {
- 717 : /* LCOV_EXCL_START */
- 718 : log_fatal("WARNING! Without an accessible %s file, it isn't possible to scrub.\n", lev_name(l));
- 719 : exit(EXIT_FAILURE);
- 720 : /* LCOV_EXCL_STOP */
- 721 : }
- 722 : }
- 723 :
- 724 11 : msg_progress("Scrubbing...\n");
- 725 :
- 726 11 : error = 0;
- 727 :
- 728 11 : ret = state_scrub_process(state, parity_ptr, 0, blockmax, &ps, now);
- 729 11 : if (ret == -1) {
- 730 0 : ++error;
- 731 : /* continue, as we are already exiting */
- 732 : }
- 733 :
- 734 77 : for (l = 0; l < state->level; ++l) {
- 735 66 : ret = parity_close(parity_ptr[l]);
- 736 66 : if (ret == -1) {
- 737 : /* LCOV_EXCL_START */
- 738 : log_fatal("DANGER! Unexpected close error in %s disk.\n", lev_name(l));
- 739 : ++error;
- 740 : /* continue, as we are already exiting */
- 741 : /* LCOV_EXCL_STOP */
- 742 : }
- 743 : }
- 744 :
- 745 : /* abort if required */
- 746 11 : if (error != 0)
- 747 0 : return -1;
- 748 11 : return 0;
- 749 : }
- 750 :
+ 704 6 : log_tag("time_limit:%" PRIu64 "\n", (uint64_t)ps.timelimit);
+ 705 6 : log_tag("last_limit:%u\n", ps.lastlimit);
+ 706 : }
+ 707 :
+ 708 : /* free the temp vector */
+ 709 11 : free(timemap);
+ 710 :
+ 711 : /* open the file for reading */
+ 712 77 : for (l = 0; l < state->level; ++l) {
+ 713 66 : parity_ptr[l] = &parity[l];
+ 714 66 : ret = parity_open(parity_ptr[l], state->parity[l].path, state->file_mode);
+ 715 66 : if (ret == -1) {
+ 716 : /* LCOV_EXCL_START */
+ 717 : log_fatal("WARNING! Without an accessible %s file, it isn't possible to scrub.\n", lev_name(l));
+ 718 : exit(EXIT_FAILURE);
+ 719 : /* LCOV_EXCL_STOP */
+ 720 : }
+ 721 : }
+ 722 :
+ 723 11 : msg_progress("Scrubbing...\n");
+ 724 :
+ 725 11 : error = 0;
+ 726 :
+ 727 11 : ret = state_scrub_process(state, parity_ptr, 0, blockmax, &ps, now);
+ 728 11 : if (ret == -1) {
+ 729 0 : ++error;
+ 730 : /* continue, as we are already exiting */
+ 731 : }
+ 732 :
+ 733 77 : for (l = 0; l < state->level; ++l) {
+ 734 66 : ret = parity_close(parity_ptr[l]);
+ 735 66 : if (ret == -1) {
+ 736 : /* LCOV_EXCL_START */
+ 737 : log_fatal("DANGER! Unexpected close error in %s disk.\n", lev_name(l));
+ 738 : ++error;
+ 739 : /* continue, as we are already exiting */
+ 740 : /* LCOV_EXCL_STOP */
+ 741 : }
+ 742 : }
+ 743 :
+ 744 : /* abort if required */
+ 745 11 : if (error != 0)
+ 746 0 : return -1;
+ 747 11 : return 0;
+ 748 : }
+ 749 :
diff --git a/cov/cmdline/search.c.func-sort-c.html b/cov/cmdline/search.c.func-sort-c.html
index 1b6afc8f..29c53774 100644
--- a/cov/cmdline/search.c.func-sort-c.html
+++ b/cov/cmdline/search.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,15 +61,15 @@
| search_file |
- 1842333 |
+ 1842576 |
| search_file_free |
- 1842333 |
+ 1842576 |
| state_search_fetch |
- 630950 |
+ 630482 |
| search_file_compare |
diff --git a/cov/cmdline/search.c.func.html b/cov/cmdline/search.c.func.html
index 1ec32225..7773723e 100644
--- a/cov/cmdline/search.c.func.html
+++ b/cov/cmdline/search.c.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -65,7 +65,7 @@
| search_file |
- 1842333 |
+ 1842576 |
| search_file_compare |
@@ -73,7 +73,7 @@
| search_file_free |
- 1842333 |
+ 1842576 |
| state_search |
@@ -85,7 +85,7 @@
| state_search_fetch |
- 630950 |
+ 630482 |
diff --git a/cov/cmdline/search.c.gcov.html b/cov/cmdline/search.c.gcov.html
index 4ffd440f..ae597b03 100644
--- a/cov/cmdline/search.c.gcov.html
+++ b/cov/cmdline/search.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -85,27 +85,27 @@
23 : /****************************************************************************/
24 : /* search */
25 :
- 26 1842333 : static void search_file(struct snapraid_state* state, const char* path, data_off_t size, int64_t mtime_sec, int mtime_nsec)
+ 26 1842576 : static void search_file(struct snapraid_state* state, const char* path, data_off_t size, int64_t mtime_sec, int mtime_nsec)
27 : {
28 : struct snapraid_search_file* file;
29 : tommy_uint32_t file_hash;
30 :
- 31 1842333 : file = malloc_nofail(sizeof(struct snapraid_search_file));
- 32 1842333 : file->path = strdup_nofail(path);
- 33 1842333 : file->size = size;
- 34 1842333 : file->mtime_sec = mtime_sec;
- 35 1842333 : file->mtime_nsec = mtime_nsec;
+ 31 1842576 : file = malloc_nofail(sizeof(struct snapraid_search_file));
+ 32 1842576 : file->path = strdup_nofail(path);
+ 33 1842576 : file->size = size;
+ 34 1842576 : file->mtime_sec = mtime_sec;
+ 35 1842576 : file->mtime_nsec = mtime_nsec;
36 :
- 37 1842333 : file_hash = file_stamp_hash(file->size, file->mtime_sec, file->mtime_nsec);
+ 37 1842576 : file_hash = file_stamp_hash(file->size, file->mtime_sec, file->mtime_nsec);
38 :
- 39 1842333 : tommy_hashdyn_insert(&state->searchset, &file->node, file, file_hash);
- 40 1842333 : }
+ 39 1842576 : tommy_hashdyn_insert(&state->searchset, &file->node, file, file_hash);
+ 40 1842576 : }
41 :
- 42 1842333 : void search_file_free(struct snapraid_search_file* file)
+ 42 1842576 : void search_file_free(struct snapraid_search_file* file)
43 : {
- 44 1842333 : free(file->path);
- 45 1842333 : free(file);
- 46 1842333 : }
+ 44 1842576 : free(file->path);
+ 45 1842576 : free(file);
+ 46 1842576 : }
47 :
48 : struct search_file_compare_arg {
49 : const struct snapraid_state* state;
@@ -176,9 +176,9 @@
114 :
115 : /* compute the hash */
116 11531 : if (arg->prevhash)
- 117 4483 : memhash(state->prevhash, state->prevhashseed, buffer_hash, arg->buffer, arg->read_size);
+ 117 4492 : memhash(state->prevhash, state->prevhashseed, buffer_hash, arg->buffer, arg->read_size);
118 : else
- 119 7048 : memhash(state->hash, state->hashseed, buffer_hash, arg->buffer, arg->read_size);
+ 119 7039 : memhash(state->hash, state->hashseed, buffer_hash, arg->buffer, arg->read_size);
120 :
121 : /* check if the hash is matching */
122 11531 : if (memcmp(buffer_hash, arg->block->hash, HASH_SIZE) != 0)
@@ -192,26 +192,26 @@
130 9412 : return 0;
131 : }
132 :
- 133 630950 : int state_search_fetch(struct snapraid_state* state, int prevhash, struct snapraid_file* missing_file, block_off_t missing_file_pos, struct snapraid_block* missing_block, unsigned char* buffer)
+ 133 630482 : int state_search_fetch(struct snapraid_state* state, int prevhash, struct snapraid_file* missing_file, block_off_t missing_file_pos, struct snapraid_block* missing_block, unsigned char* buffer)
134 : {
135 : struct snapraid_search_file* file;
136 : tommy_uint32_t file_hash;
137 : struct search_file_compare_arg arg;
138 :
- 139 630950 : arg.state = state;
- 140 630950 : arg.block = missing_block;
- 141 630950 : arg.file = missing_file;
- 142 630950 : arg.buffer = buffer;
- 143 630950 : arg.offset = state->block_size * (data_off_t)missing_file_pos;
- 144 630950 : arg.read_size = file_block_size(missing_file, missing_file_pos, state->block_size);
- 145 630950 : arg.prevhash = prevhash;
+ 139 630482 : arg.state = state;
+ 140 630482 : arg.block = missing_block;
+ 141 630482 : arg.file = missing_file;
+ 142 630482 : arg.buffer = buffer;
+ 143 630482 : arg.offset = state->block_size * (data_off_t)missing_file_pos;
+ 144 630482 : arg.read_size = file_block_size(missing_file, missing_file_pos, state->block_size);
+ 145 630482 : arg.prevhash = prevhash;
146 :
- 147 630950 : file_hash = file_stamp_hash(arg.file->size, arg.file->mtime_sec, arg.file->mtime_nsec);
+ 147 630482 : file_hash = file_stamp_hash(arg.file->size, arg.file->mtime_sec, arg.file->mtime_nsec);
148 :
149 : /* search in the hashtable, and also check if the data matches the hash */
- 150 630950 : file = tommy_hashdyn_search(&state->searchset, search_file_compare, &arg, file_hash);
- 151 630950 : if (!file)
- 152 621538 : return -1;
+ 150 630482 : file = tommy_hashdyn_search(&state->searchset, search_file_compare, &arg, file_hash);
+ 151 630482 : if (!file)
+ 152 621070 : return -1;
153 :
154 : /* if found, buffer is already set with data */
155 9412 : return 0;
@@ -233,40 +233,40 @@
171 : char path_next[PATH_MAX];
172 : char sub_next[PATH_MAX];
173 : char out[PATH_MAX];
- 174 2039139 : struct snapraid_filter* reason = 0;
+ 174 2039164 : struct snapraid_filter* reason = 0;
175 : struct stat st;
176 : const char* name;
177 : struct dirent* dd;
178 :
179 : /* clear errno to detect erroneous conditions */
- 180 2039139 : errno = 0;
- 181 2039139 : dd = readdir(d);
- 182 2039139 : if (dd == 0 && errno != 0) {
+ 180 2039164 : errno = 0;
+ 181 2039164 : dd = readdir(d);
+ 182 2039164 : if (dd == 0 && errno != 0) {
183 : /* LCOV_EXCL_START */
184 : log_fatal("Error reading directory '%s'. %s.\n", dir, strerror(errno));
185 : exit(EXIT_FAILURE);
186 : /* LCOV_EXCL_STOP */
187 : }
- 188 2039139 : if (dd == 0) {
+ 188 2039164 : if (dd == 0) {
189 2462 : break; /* finished */
190 : }
191 :
192 : /* skip "." and ".." files */
- 193 2036677 : name = dd->d_name;
- 194 2036677 : if (name[0] == '.' && (name[1] == 0 || (name[1] == '.' && name[2] == 0)))
+ 193 2036702 : name = dd->d_name;
+ 194 2036702 : if (name[0] == '.' && (name[1] == 0 || (name[1] == '.' && name[2] == 0)))
195 9848 : continue;
196 :
- 197 2031753 : pathprint(path_next, sizeof(path_next), "%s%s", dir, name);
- 198 2031753 : pathprint(sub_next, sizeof(sub_next), "%s%s", sub, name);
+ 197 2031778 : pathprint(path_next, sizeof(path_next), "%s%s", dir, name);
+ 198 2031778 : pathprint(sub_next, sizeof(sub_next), "%s%s", sub, name);
199 :
200 : /* exclude hidden files even before calling lstat() */
- 201 2031753 : if (disk != 0 && filter_hidden(state->filter_hidden, dd) != 0) {
+ 201 2031778 : if (disk != 0 && filter_hidden(state->filter_hidden, dd) != 0) {
202 0 : msg_verbose("Excluding hidden '%s'\n", path_next);
203 0 : continue;
204 : }
205 :
206 : /* exclude content files even before calling lstat() */
- 207 2031753 : if (disk != 0 && filter_content(&state->contentlist, path_next) != 0) {
+ 207 2031778 : if (disk != 0 && filter_content(&state->contentlist, path_next) != 0) {
208 0 : msg_verbose("Excluding content '%s'\n", path_next);
209 0 : continue;
210 : }
@@ -290,7 +290,7 @@
228 : }
229 : #else
230 : /* get lstat info about the file */
- 231 2031753 : if (lstat(path_next, &st) != 0) {
+ 231 2031778 : if (lstat(path_next, &st) != 0) {
232 : /* LCOV_EXCL_START */
233 : log_fatal("Error in stat file/directory '%s'. %s.\n", path_next, strerror(errno));
234 : exit(EXIT_FAILURE);
@@ -298,13 +298,13 @@
236 : }
237 : #endif
238 :
- 239 2031753 : if (S_ISREG(st.st_mode)) {
- 240 1967420 : if (disk == 0 || filter_path(&state->filterlist, &reason, disk->name, sub_next) == 0) {
- 241 1842333 : search_file(state, path_next, st.st_size, st.st_mtime, STAT_NSEC(&st));
+ 239 2031778 : if (S_ISREG(st.st_mode)) {
+ 240 1967521 : if (disk == 0 || filter_path(&state->filterlist, &reason, disk->name, sub_next) == 0) {
+ 241 1842576 : search_file(state, path_next, st.st_size, st.st_mtime, STAT_NSEC(&st));
242 : } else {
- 243 125087 : msg_verbose("Excluding link '%s' for rule '%s'\n", path_next, filter_type(reason, out, sizeof(out)));
+ 243 124945 : msg_verbose("Excluding link '%s' for rule '%s'\n", path_next, filter_type(reason, out, sizeof(out)));
244 : }
- 245 64333 : } else if (S_ISDIR(st.st_mode)) {
+ 245 64257 : } else if (S_ISDIR(st.st_mode)) {
246 1781 : if (disk == 0 || filter_dir(&state->filterlist, &reason, disk->name, sub_next) == 0) {
247 1781 : pathslash(path_next, sizeof(path_next));
248 1781 : pathslash(sub_next, sizeof(sub_next));
@@ -313,7 +313,7 @@
251 0 : msg_verbose("Excluding directory '%s' for rule '%s'\n", path_next, filter_type(reason, out, sizeof(out)));
252 : }
253 : }
- 254 2036677 : }
+ 254 2036702 : }
255 :
256 2462 : if (closedir(d) != 0) {
257 : /* LCOV_EXCL_START */
diff --git a/cov/cmdline/selftest.c.func-sort-c.html b/cov/cmdline/selftest.c.func-sort-c.html
index d7482c19..cbbf9134 100644
--- a/cov/cmdline/selftest.c.func-sort-c.html
+++ b/cov/cmdline/selftest.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/cmdline/selftest.c.func.html b/cov/cmdline/selftest.c.func.html
index a8b2aced..7dd73f90 100644
--- a/cov/cmdline/selftest.c.func.html
+++ b/cov/cmdline/selftest.c.func.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/cmdline/selftest.c.gcov.html b/cov/cmdline/selftest.c.gcov.html
index ec21e5a0..c18817e6 100644
--- a/cov/cmdline/selftest.c.gcov.html
+++ b/cov/cmdline/selftest.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/cmdline/snapraid.c.func-sort-c.html b/cov/cmdline/snapraid.c.func-sort-c.html
index a2fbacb2..8601a790 100644
--- a/cov/cmdline/snapraid.c.func-sort-c.html
+++ b/cov/cmdline/snapraid.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/cmdline/snapraid.c.func.html b/cov/cmdline/snapraid.c.func.html
index da1dd303..5c3cd1ce 100644
--- a/cov/cmdline/snapraid.c.func.html
+++ b/cov/cmdline/snapraid.c.func.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/cmdline/snapraid.c.gcov.html b/cov/cmdline/snapraid.c.gcov.html
index 8d470dea..9efa5568 100644
--- a/cov/cmdline/snapraid.c.gcov.html
+++ b/cov/cmdline/snapraid.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/cmdline/speed.c.func-sort-c.html b/cov/cmdline/speed.c.func-sort-c.html
index 587fdc01..af5d7d8f 100644
--- a/cov/cmdline/speed.c.func-sort-c.html
+++ b/cov/cmdline/speed.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,7 +61,7 @@
| diffgettimeofday |
- 1861 |
+ 1866 |
| speed |
diff --git a/cov/cmdline/speed.c.func.html b/cov/cmdline/speed.c.func.html
index 674c7d66..eb03f6a4 100644
--- a/cov/cmdline/speed.c.func.html
+++ b/cov/cmdline/speed.c.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,7 +61,7 @@
| diffgettimeofday |
- 1861 |
+ 1866 |
| speed |
diff --git a/cov/cmdline/speed.c.gcov.html b/cov/cmdline/speed.c.gcov.html
index e10bd832..edf49280 100644
--- a/cov/cmdline/speed.c.gcov.html
+++ b/cov/cmdline/speed.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -100,14 +100,14 @@
38 : /**
39 : * Differential us of two timeval.
40 : */
- 41 1861 : static int64_t diffgettimeofday(struct timeval *start, struct timeval *stop)
+ 41 1866 : static int64_t diffgettimeofday(struct timeval *start, struct timeval *stop)
42 : {
43 : int64_t d;
44 :
- 45 1861 : d = 1000000LL * (stop->tv_sec - start->tv_sec);
- 46 1861 : d += stop->tv_usec - start->tv_usec;
+ 45 1866 : d = 1000000LL * (stop->tv_sec - start->tv_sec);
+ 46 1866 : d += stop->tv_usec - start->tv_usec;
47 :
- 48 1861 : return d;
+ 48 1866 : return d;
49 : }
50 :
51 : /**
@@ -232,10 +232,10 @@
170 4 : printf("%8s", "memset");
171 4 : fflush(stdout);
172 :
- 173 383 : SPEED_START {
- 174 3411 : for (j = 0; j < nd; ++j)
- 175 3032 : memset(v[j], j, size);
- 176 379 : } SPEED_STOP
+ 173 385 : SPEED_START {
+ 174 3429 : for (j = 0; j < nd; ++j)
+ 175 3048 : memset(v[j], j, size);
+ 176 381 : } SPEED_STOP
177 :
178 4 : printf("%8" PRIu64, ds / dt);
179 4 : printf("\n");
@@ -247,10 +247,10 @@
185 4 : printf("%8s", "table");
186 4 : fflush(stdout);
187 :
- 188 44 : SPEED_START {
- 189 360 : for (j = 0; j < nd; ++j)
- 190 320 : side_effect += crc32c_gen(0, v[j], size);
- 191 40 : } SPEED_STOP
+ 188 46 : SPEED_START {
+ 189 378 : for (j = 0; j < nd; ++j)
+ 190 336 : side_effect += crc32c_gen(0, v[j], size);
+ 191 42 : } SPEED_STOP
192 :
193 4 : printf("%8" PRIu64, ds / dt);
194 4 : printf("\n");
@@ -302,10 +302,10 @@
240 4 : printf("%8" PRIu64, ds / dt);
241 4 : fflush(stdout);
242 :
- 243 36 : SPEED_START {
- 244 288 : for (j = 0; j < nd; ++j)
- 245 256 : memhash(HASH_SPOOKY2, seed, digest, v[j], size);
- 246 32 : } SPEED_STOP
+ 243 35 : SPEED_START {
+ 244 279 : for (j = 0; j < nd; ++j)
+ 245 248 : memhash(HASH_SPOOKY2, seed, digest, v[j], size);
+ 246 31 : } SPEED_STOP
247 :
248 4 : printf("%8" PRIu64, ds / dt);
249 4 : printf("\n");
@@ -358,9 +358,9 @@
296 : #ifdef CONFIG_X86
297 : #ifdef CONFIG_SSE2
298 4 : if (raid_cpu_has_sse2()) {
- 299 312 : SPEED_START {
- 300 308 : raid_gen1_sse2(nd, size, v);
- 301 308 : } SPEED_STOP
+ 299 310 : SPEED_START {
+ 300 306 : raid_gen1_sse2(nd, size, v);
+ 301 306 : } SPEED_STOP
302 :
303 4 : printf("%8" PRIu64, ds / dt);
304 4 : fflush(stdout);
@@ -411,9 +411,9 @@
349 : #ifdef CONFIG_X86
350 : #ifdef CONFIG_SSE2
351 4 : if (raid_cpu_has_sse2()) {
- 352 148 : SPEED_START {
- 353 144 : raid_gen2_sse2(nd, size, v);
- 354 144 : } SPEED_STOP
+ 352 147 : SPEED_START {
+ 353 143 : raid_gen2_sse2(nd, size, v);
+ 354 143 : } SPEED_STOP
355 :
356 4 : printf("%8" PRIu64, ds / dt);
357 4 : fflush(stdout);
@@ -537,9 +537,9 @@
475 : #ifdef CONFIG_X86
476 : #ifdef CONFIG_SSSE3
477 4 : if (raid_cpu_has_ssse3()) {
- 478 53 : SPEED_START {
- 479 50 : raid_gen3_ssse3(nd, size, v);
- 480 50 : } SPEED_STOP
+ 478 54 : SPEED_START {
+ 479 51 : raid_gen3_ssse3(nd, size, v);
+ 480 51 : } SPEED_STOP
481 :
482 3 : printf("%8" PRIu64, ds / dt);
483 3 : fflush(stdout);
@@ -602,9 +602,9 @@
540 : #ifdef CONFIG_X86
541 : #ifdef CONFIG_SSSE3
542 4 : if (raid_cpu_has_ssse3()) {
- 543 34 : SPEED_START {
- 544 31 : raid_gen4_ssse3(nd, size, v);
- 545 31 : } SPEED_STOP
+ 543 36 : SPEED_START {
+ 544 33 : raid_gen4_ssse3(nd, size, v);
+ 545 33 : } SPEED_STOP
546 :
547 3 : printf("%8" PRIu64, ds / dt);
548 3 : fflush(stdout);
@@ -667,9 +667,9 @@
605 : #ifdef CONFIG_X86
606 : #ifdef CONFIG_SSSE3
607 4 : if (raid_cpu_has_ssse3()) {
- 608 26 : SPEED_START {
- 609 23 : raid_gen5_ssse3(nd, size, v);
- 610 23 : } SPEED_STOP
+ 608 27 : SPEED_START {
+ 609 24 : raid_gen5_ssse3(nd, size, v);
+ 610 24 : } SPEED_STOP
611 :
612 3 : printf("%8" PRIu64, ds / dt);
613 3 : fflush(stdout);
@@ -707,9 +707,9 @@
645 4 : printf("%8s", raid_gen6_tag());
646 4 : fflush(stdout);
647 :
- 648 9 : SPEED_START {
- 649 5 : raid_gen6_int8(nd, size, v);
- 650 5 : } SPEED_STOP
+ 648 10 : SPEED_START {
+ 649 6 : raid_gen6_int8(nd, size, v);
+ 650 6 : } SPEED_STOP
651 :
652 4 : printf("%8" PRIu64, ds / dt);
653 4 : fflush(stdout);
diff --git a/cov/cmdline/spooky2.c.func-sort-c.html b/cov/cmdline/spooky2.c.func-sort-c.html
index ccc7db47..d52512e6 100644
--- a/cov/cmdline/spooky2.c.func-sort-c.html
+++ b/cov/cmdline/spooky2.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,7 +61,7 @@
| SpookyHash128 |
- 3470873 |
+ 3472174 |
diff --git a/cov/cmdline/spooky2.c.func.html b/cov/cmdline/spooky2.c.func.html
index 8b3213dc..d22d4cbf 100644
--- a/cov/cmdline/spooky2.c.func.html
+++ b/cov/cmdline/spooky2.c.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,7 +61,7 @@
| SpookyHash128 |
- 3470873 |
+ 3472174 |
diff --git a/cov/cmdline/spooky2.c.gcov.html b/cov/cmdline/spooky2.c.gcov.html
index b8c57bca..06596abb 100644
--- a/cov/cmdline/spooky2.c.gcov.html
+++ b/cov/cmdline/spooky2.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -170,7 +170,7 @@
108 : //
109 : #define sc_const 0xdeadbeefdeadbeefLL
110 :
- 111 3470873 : void SpookyHash128(const void* data, size_t size, const uint8_t* seed, uint8_t* digest)
+ 111 3472174 : void SpookyHash128(const void* data, size_t size, const uint8_t* seed, uint8_t* digest)
112 : {
113 : uint64_t h0, h1, h2, h3, h4, h5, h6, h7, h8, h9, h10, h11;
114 : uint64_t buf[sc_numVars];
@@ -182,39 +182,39 @@
120 : unsigned i;
121 : #endif
122 :
- 123 3470873 : h9 = ((const uint64_t*)seed)[0];
- 124 3470873 : h10 = ((const uint64_t*)seed)[1];
+ 123 3472174 : h9 = ((const uint64_t*)seed)[0];
+ 124 3472174 : h10 = ((const uint64_t*)seed)[1];
125 :
126 : #if WORDS_BIGENDIAN
127 : h9 = util_swap64(h9);
128 : h10 = util_swap64(h10);
129 : #endif
130 :
- 131 3470873 : h0 = h3 = h6 = h9;
- 132 3470873 : h1 = h4 = h7 = h10;
- 133 3470873 : h2 = h5 = h8 = h11 = sc_const;
+ 131 3472174 : h0 = h3 = h6 = h9;
+ 132 3472174 : h1 = h4 = h7 = h10;
+ 133 3472174 : h2 = h5 = h8 = h11 = sc_const;
134 :
- 135 3470873 : nblocks = size / sc_blockSize;
- 136 3470873 : blocks = data;
- 137 3470873 : end = blocks + nblocks * sc_numVars;
+ 135 3472174 : nblocks = size / sc_blockSize;
+ 136 3472174 : blocks = data;
+ 137 3472174 : end = blocks + nblocks * sc_numVars;
138 :
139 : /* body */
- 140 34954199 : while (blocks < end) {
+ 140 34945798 : while (blocks < end) {
141 : #if WORDS_BIGENDIAN
142 : for (i = 0; i < sc_numVars; ++i)
143 : buf[i] = util_swap64(blocks[i]);
144 : Mix(buf, h0, h1, h2, h3, h4, h5, h6, h7, h8, h9, h10, h11);
145 : #else
- 146 28012453 : Mix(blocks, h0, h1, h2, h3, h4, h5, h6, h7, h8, h9, h10, h11);
+ 146 28001450 : Mix(blocks, h0, h1, h2, h3, h4, h5, h6, h7, h8, h9, h10, h11);
147 : #endif
- 148 28012453 : blocks += sc_numVars;
+ 148 28001450 : blocks += sc_numVars;
149 : }
150 :
151 : /* tail */
- 152 3470873 : size_remainder = (size - ((const uint8_t*)end - (const uint8_t*)data));
- 153 3470873 : memcpy(buf, end, size_remainder);
- 154 3470873 : memset(((uint8_t*)buf) + size_remainder, 0, sc_blockSize - size_remainder);
- 155 3470873 : ((uint8_t*)buf)[sc_blockSize - 1] = size_remainder;
+ 152 3472174 : size_remainder = (size - ((const uint8_t*)end - (const uint8_t*)data));
+ 153 3472174 : memcpy(buf, end, size_remainder);
+ 154 3472174 : memset(((uint8_t*)buf) + size_remainder, 0, sc_blockSize - size_remainder);
+ 155 3472174 : ((uint8_t*)buf)[sc_blockSize - 1] = size_remainder;
156 :
157 : /* finalization */
158 : #if WORDS_BIGENDIAN
@@ -222,16 +222,16 @@
160 : buf[i] = util_swap64(buf[i]);
161 : #endif
162 :
- 163 3470873 : End(buf, h0, h1, h2, h3, h4, h5, h6, h7, h8, h9, h10, h11);
+ 163 3472174 : End(buf, h0, h1, h2, h3, h4, h5, h6, h7, h8, h9, h10, h11);
164 :
165 : #if WORDS_BIGENDIAN
166 : h0 = util_swap64(h0);
167 : h1 = util_swap64(h1);
168 : #endif
169 :
- 170 3470873 : ((uint64_t*)digest)[0] = h0;
- 171 3470873 : ((uint64_t*)digest)[1] = h1;
- 172 3470873 : }
+ 170 3472174 : ((uint64_t*)digest)[0] = h0;
+ 171 3472174 : ((uint64_t*)digest)[1] = h1;
+ 172 3472174 : }
173 :
diff --git a/cov/cmdline/state.c.func-sort-c.html b/cov/cmdline/state.c.func-sort-c.html
index cd64a35b..7cf9b431 100644
--- a/cov/cmdline/state.c.func-sort-c.html
+++ b/cov/cmdline/state.c.func-sort-c.html
@@ -31,13 +31,13 @@
|
-
+
-
+
-
+
|
@@ -61,7 +61,7 @@
| fs_is_block_deleted_ts |
- 29383119 |
+ 29344162 |
| fs_info_is_required |
@@ -69,7 +69,7 @@
| state_progress |
- 1038828 |
+ 1038958 |
| fs_position_is_required |
@@ -77,7 +77,7 @@
| lev_config_name |
- 178770 |
+ 178766 |
| find_disk |
@@ -93,7 +93,7 @@
| state_verify_thread |
- 908 |
+ 912 |
| state_fscheck |
diff --git a/cov/cmdline/state.c.func.html b/cov/cmdline/state.c.func.html
index 38f32f80..c610d3af 100644
--- a/cov/cmdline/state.c.func.html
+++ b/cov/cmdline/state.c.func.html
@@ -31,13 +31,13 @@
|
-
+
-
+
-
+
|
@@ -73,7 +73,7 @@
| fs_is_block_deleted_ts |
- 29383119 |
+ 29344162 |
| fs_position_clear_deleted |
@@ -89,7 +89,7 @@
| lev_config_name |
- 178770 |
+ 178766 |
| lev_config_scan |
@@ -137,7 +137,7 @@
| state_progress |
- 1038828 |
+ 1038958 |
| state_progress_begin |
@@ -185,7 +185,7 @@
| state_verify_thread |
- 908 |
+ 912 |
| state_write |
diff --git a/cov/cmdline/state.c.gcov.html b/cov/cmdline/state.c.gcov.html
index c8394e94..17e83360 100644
--- a/cov/cmdline/state.c.gcov.html
+++ b/cov/cmdline/state.c.gcov.html
@@ -31,13 +31,13 @@
|
-
+
-
+
-
+
|
@@ -103,10 +103,10 @@
41 0 : return 0;
42 : }
43 :
- 44 178770 : const char* lev_config_name(unsigned l)
+ 44 178766 : const char* lev_config_name(unsigned l)
45 : {
- 46 178770 : switch (l) {
- 47 70480 : case 0 : return "parity";
+ 46 178766 : switch (l) {
+ 47 70476 : case 0 : return "parity";
48 57423 : case 1 : return "2-parity";
49 12723 : case 2 : return "3-parity";
50 12719 : case 3 : return "4-parity";
@@ -1592,11 +1592,11 @@
1530 : /**
1531 : * Check if a block position in a disk is deleted.
1532 : */
- 1533 29383119 : static int fs_is_block_deleted_ts(struct snapraid_disk* disk, struct snapraid_chunk** fs_last, block_off_t pos)
+ 1533 29344162 : static int fs_is_block_deleted_ts(struct snapraid_disk* disk, struct snapraid_chunk** fs_last, block_off_t pos)
1534 : {
- 1535 29383119 : struct snapraid_block* block = fs_par2block_get_ts(disk, fs_last, pos);
+ 1535 29344162 : struct snapraid_block* block = fs_par2block_get_ts(disk, fs_last, pos);
1536 :
- 1537 29381514 : return block_state_get(block) == BLOCK_STATE_DELETED;
+ 1537 29163541 : return block_state_get(block) == BLOCK_STATE_DELETED;
1538 : }
1539 :
1540 : /**
@@ -1706,12 +1706,12 @@
1644 : int c;
1645 :
1646 : /* read the command */
- 1647 3604981 : c = sgetc(f);
- 1648 3604981 : if (c == EOF) {
+ 1647 3605061 : c = sgetc(f);
+ 1648 3605061 : if (c == EOF) {
1649 234 : break;
1650 : }
1651 :
- 1652 3604747 : if (c == 'f') {
+ 1652 3604827 : if (c == 'f') {
1653 : /* file */
1654 : char sub[PATH_MAX];
1655 : uint64_t v_size;
@@ -1723,18 +1723,18 @@
1661 : struct snapraid_disk* disk;
1662 : uint32_t mapping;
1663 :
- 1664 3485836 : ret = sgetb32(f, &mapping);
- 1665 3485836 : if (ret < 0 || mapping >= mapping_max) {
+ 1664 3485915 : ret = sgetb32(f, &mapping);
+ 1665 3485915 : if (ret < 0 || mapping >= mapping_max) {
1666 : /* LCOV_EXCL_START */
1667 : decoding_error(path, f);
1668 : log_fatal("Internal inconsistency in mapping index!\n");
1669 : exit(EXIT_FAILURE);
1670 : /* LCOV_EXCL_STOP */
1671 : }
- 1672 3485836 : disk = tommy_array_get(&disk_mapping, mapping);
+ 1672 3485915 : disk = tommy_array_get(&disk_mapping, mapping);
1673 :
- 1674 3485836 : ret = sgetb64(f, &v_size);
- 1675 3485836 : if (ret < 0) {
+ 1674 3485915 : ret = sgetb64(f, &v_size);
+ 1675 3485915 : if (ret < 0) {
1676 : /* LCOV_EXCL_START */
1677 : decoding_error(path, f);
1678 : exit(EXIT_FAILURE);
@@ -1742,7 +1742,7 @@
1680 : }
1681 :
1682 : /* check for impossible file size to avoid to crash for a too big allocation */
- 1683 3485836 : if (v_size / state->block_size > blockmax) {
+ 1683 3485915 : if (v_size / state->block_size > blockmax) {
1684 : /* LCOV_EXCL_START */
1685 : decoding_error(path, f);
1686 : log_fatal("Internal inconsistency in file size too big!\n");
@@ -1750,16 +1750,16 @@
1688 : /* LCOV_EXCL_STOP */
1689 : }
1690 :
- 1691 3485836 : ret = sgetb64(f, &v_mtime_sec);
- 1692 3485836 : if (ret < 0) {
+ 1691 3485915 : ret = sgetb64(f, &v_mtime_sec);
+ 1692 3485915 : if (ret < 0) {
1693 : /* LCOV_EXCL_START */
1694 : decoding_error(path, f);
1695 : exit(EXIT_FAILURE);
1696 : /* LCOV_EXCL_STOP */
1697 : }
1698 :
- 1699 3485836 : ret = sgetb32(f, &v_mtime_nsec);
- 1700 3485836 : if (ret < 0) {
+ 1699 3485915 : ret = sgetb32(f, &v_mtime_nsec);
+ 1700 3485915 : if (ret < 0) {
1701 : /* LCOV_EXCL_START */
1702 : decoding_error(path, f);
1703 : exit(EXIT_FAILURE);
@@ -1767,27 +1767,27 @@
1705 : }
1706 :
1707 : /* STAT_NSEC_INVALID is encoded as 0 */
- 1708 3485836 : if (v_mtime_nsec == 0)
+ 1708 3485915 : if (v_mtime_nsec == 0)
1709 0 : v_mtime_nsec = STAT_NSEC_INVALID;
1710 : else
- 1711 3485836 : --v_mtime_nsec;
+ 1711 3485915 : --v_mtime_nsec;
1712 :
- 1713 3485836 : ret = sgetb64(f, &v_inode);
- 1714 3485836 : if (ret < 0) {
+ 1713 3485915 : ret = sgetb64(f, &v_inode);
+ 1714 3485915 : if (ret < 0) {
1715 : /* LCOV_EXCL_START */
1716 : decoding_error(path, f);
1717 : exit(EXIT_FAILURE);
1718 : /* LCOV_EXCL_STOP */
1719 : }
1720 :
- 1721 3485836 : ret = sgetbs(f, sub, sizeof(sub));
- 1722 3485836 : if (ret < 0) {
+ 1721 3485915 : ret = sgetbs(f, sub, sizeof(sub));
+ 1722 3485915 : if (ret < 0) {
1723 : /* LCOV_EXCL_START */
1724 : decoding_error(path, f);
1725 : exit(EXIT_FAILURE);
1726 : /* LCOV_EXCL_STOP */
1727 : }
- 1728 3485836 : if (!*sub) {
+ 1728 3485915 : if (!*sub) {
1729 : /* LCOV_EXCL_START */
1730 : decoding_error(path, f);
1731 : exit(EXIT_FAILURE);
@@ -1795,40 +1795,40 @@
1733 : }
1734 :
1735 : /* allocate the file */
- 1736 3485836 : file = file_alloc(state->block_size, sub, v_size, v_mtime_sec, v_mtime_nsec, v_inode, 0);
+ 1736 3485915 : file = file_alloc(state->block_size, sub, v_size, v_mtime_sec, v_mtime_nsec, v_inode, 0);
1737 :
1738 : /* insert the file in the file containers */
- 1739 3485836 : tommy_hashdyn_insert(&disk->inodeset, &file->nodeset, file, file_inode_hash(file->inode));
- 1740 3485836 : tommy_hashdyn_insert(&disk->pathset, &file->pathset, file, file_path_hash(file->sub));
- 1741 3485836 : tommy_hashdyn_insert(&disk->stampset, &file->stampset, file, file_stamp_hash(file->size, file->mtime_sec, file->mtime_nsec));
- 1742 3485836 : tommy_list_insert_tail(&disk->filelist, &file->nodelist, file);
+ 1739 3485915 : tommy_hashdyn_insert(&disk->inodeset, &file->nodeset, file, file_inode_hash(file->inode));
+ 1740 3485915 : tommy_hashdyn_insert(&disk->pathset, &file->pathset, file, file_path_hash(file->sub));
+ 1741 3485915 : tommy_hashdyn_insert(&disk->stampset, &file->stampset, file, file_stamp_hash(file->size, file->mtime_sec, file->mtime_nsec));
+ 1742 3485915 : tommy_list_insert_tail(&disk->filelist, &file->nodelist, file);
1743 :
1744 : /* read all the blocks */
- 1745 3485836 : v_idx = 0;
- 1746 10477605 : while (v_idx < file->blockmax) {
+ 1745 3485915 : v_idx = 0;
+ 1746 10477653 : while (v_idx < file->blockmax) {
1747 : block_off_t v_pos;
1748 : uint32_t v_count;
1749 :
1750 : /* get the "subcommand */
- 1751 3505934 : c = sgetc(f);
+ 1751 3505823 : c = sgetc(f);
1752 :
- 1753 3505934 : ret = sgetb32(f, &v_pos);
- 1754 3505934 : if (ret < 0) {
+ 1753 3505823 : ret = sgetb32(f, &v_pos);
+ 1754 3505823 : if (ret < 0) {
1755 : /* LCOV_EXCL_START */
1756 : decoding_error(path, f);
1757 : exit(EXIT_FAILURE);
1758 : /* LCOV_EXCL_STOP */
1759 : }
1760 :
- 1761 3505934 : ret = sgetb32(f, &v_count);
- 1762 3505934 : if (ret < 0) {
+ 1761 3505823 : ret = sgetb32(f, &v_count);
+ 1762 3505823 : if (ret < 0) {
1763 : /* LCOV_EXCL_START */
1764 : decoding_error(path, f);
1765 : exit(EXIT_FAILURE);
1766 : /* LCOV_EXCL_STOP */
1767 : }
1768 :
- 1769 3505934 : if (v_idx + v_count > file->blockmax) {
+ 1769 3505823 : if (v_idx + v_count > file->blockmax) {
1770 : /* LCOV_EXCL_START */
1771 : decoding_error(path, f);
1772 : log_fatal("Internal inconsistency in block number!\n");
@@ -1836,7 +1836,7 @@
1774 : /* LCOV_EXCL_STOP */
1775 : }
1776 :
- 1777 3505933 : if (v_pos + v_count > blockmax) {
+ 1777 3505823 : if (v_pos + v_count > blockmax) {
1778 : /* LCOV_EXCL_START */
1779 : log_fatal("Internal inconsistency in block size %u/%u!\n", blockmax, v_pos + v_count);
1780 : decoding_error(path, f);
@@ -1871,9 +1871,9 @@
1809 : }
1810 :
1811 : /* read the hash only for 'blk/chg/rep', and not for 'new' */
- 1812 8573599 : if (c != 'n') {
- 1813 8573599 : ret = sread(f, block->hash, HASH_SIZE);
- 1814 8573599 : if (ret < 0) {
+ 1812 8573249 : if (c != 'n') {
+ 1813 8573249 : ret = sread(f, block->hash, HASH_SIZE);
+ 1814 8573249 : if (ret < 0) {
1815 : /* LCOV_EXCL_START */
1816 : decoding_error(path, f);
1817 : exit(EXIT_FAILURE);
@@ -1886,8 +1886,8 @@
1824 :
1825 : /* if the block contains a hash of past data */
1826 : /* and we are clearing such undeterminated hashes */
- 1827 8573599 : if (state->clear_past_hash
- 1828 2287716 : && block_has_past_hash(block)
+ 1827 8573249 : if (state->clear_past_hash
+ 1828 2287366 : && block_has_past_hash(block)
1829 : ) {
1830 : /* set the hash value to INVALID */
1831 57602 : hash_invalid_set(block->hash);
@@ -1898,8 +1898,8 @@
1836 : /* in other sync commands */
1837 : /* note that this is required only in sync, and we detect */
1838 : /* this using the clear_past_hash flag */
- 1839 8573599 : if (state->clear_past_hash
- 1840 2287716 : && state->opt.force_nocopy
+ 1839 8573249 : if (state->clear_past_hash
+ 1840 2287366 : && state->opt.force_nocopy
1841 14115 : && block_state_get(block) == BLOCK_STATE_REP
1842 : ) {
1843 : /* set the hash value to INVALID */
@@ -1911,25 +1911,25 @@
1849 : /* if we want a full sync, marks block as invalid parity */
1850 : /* note that we do this after the force_nocopy option */
1851 : /* to avoid to mixup the two things */
- 1852 8573599 : if (state->opt.force_full
+ 1852 8573249 : if (state->opt.force_full
1853 27746 : && block_state_get(block) == BLOCK_STATE_BLK) {
1854 : /* convert from BLK to REP */
1855 27746 : block_state_set(block, BLOCK_STATE_REP);
1856 : }
1857 :
1858 : /* set the parity association */
- 1859 8573599 : fs_allocate(disk, v_pos, file, v_idx);
+ 1859 8573249 : fs_allocate(disk, v_pos, file, v_idx);
1860 :
1861 : /* go to the next block */
- 1862 8573599 : ++v_idx;
- 1863 8573599 : ++v_pos;
- 1864 8573599 : --v_count;
+ 1862 8573249 : ++v_idx;
+ 1863 8573249 : ++v_pos;
+ 1864 8573249 : --v_count;
1865 : }
1866 : }
1867 :
1868 : /* stat */
- 1869 3485835 : ++count_file;
- 1870 118911 : } else if (c == 'i') {
+ 1869 3485915 : ++count_file;
+ 1870 118912 : } else if (c == 'i') {
1871 : /* "inf" command */
1872 : snapraid_info info;
1873 : uint32_t v_pos;
@@ -1944,7 +1944,7 @@
1882 : }
1883 :
1884 234 : v_pos = 0;
- 1885 284859 : while (v_pos < blockmax) {
+ 1885 288815 : while (v_pos < blockmax) {
1886 : int bad;
1887 : int rehash;
1888 : int justsynced;
@@ -1952,15 +1952,15 @@
1890 : uint32_t flag;
1891 : uint32_t v_count;
1892 :
- 1893 284391 : ret = sgetb32(f, &v_count);
- 1894 284391 : if (ret < 0) {
+ 1893 288347 : ret = sgetb32(f, &v_count);
+ 1894 288347 : if (ret < 0) {
1895 : /* LCOV_EXCL_START */
1896 : decoding_error(path, f);
1897 : exit(EXIT_FAILURE);
1898 : /* LCOV_EXCL_STOP */
1899 : }
1900 :
- 1901 284391 : if (v_pos + v_count > blockmax) {
+ 1901 288347 : if (v_pos + v_count > blockmax) {
1902 : /* LCOV_EXCL_START */
1903 : log_fatal("Internal inconsistency in info size %u/%u!\n", blockmax, v_pos + v_count);
1904 : decoding_error(path, f);
@@ -1968,8 +1968,8 @@
1906 : /* LCOV_EXCL_STOP */
1907 : }
1908 :
- 1909 284391 : ret = sgetb32(f, &flag);
- 1910 284391 : if (ret < 0) {
+ 1909 288347 : ret = sgetb32(f, &flag);
+ 1910 288347 : if (ret < 0) {
1911 : /* LCOV_EXCL_START */
1912 : decoding_error(path, f);
1913 : exit(EXIT_FAILURE);
@@ -1977,10 +1977,10 @@
1915 : }
1916 :
1917 : /* if there is an info */
- 1918 284391 : if ((flag & 1) != 0) {
+ 1918 288347 : if ((flag & 1) != 0) {
1919 : /* read the time */
- 1920 284376 : ret = sgetb32(f, &t);
- 1921 284376 : if (ret < 0) {
+ 1920 288332 : ret = sgetb32(f, &t);
+ 1921 288332 : if (ret < 0) {
1922 : /* LCOV_EXCL_START */
1923 : decoding_error(path, f);
1924 : exit(EXIT_FAILURE);
@@ -1988,11 +1988,11 @@
1926 : }
1927 :
1928 : /* analyze the flags */
- 1929 284376 : bad = (flag & 2) != 0;
- 1930 284376 : rehash = (flag & 4) != 0;
- 1931 284376 : justsynced = (flag & 8) != 0;
+ 1929 288332 : bad = (flag & 2) != 0;
+ 1930 288332 : rehash = (flag & 4) != 0;
+ 1931 288332 : justsynced = (flag & 8) != 0;
1932 :
- 1933 284376 : if (rehash && state->prevhash == HASH_UNDEFINED) {
+ 1933 288332 : if (rehash && state->prevhash == HASH_UNDEFINED) {
1934 : /* LCOV_EXCL_START */
1935 : decoding_error(path, f);
1936 : log_fatal("Internal inconsistency for missing previous checksum!\n");
@@ -2000,12 +2000,12 @@
1938 : /* LCOV_EXCL_STOP */
1939 : }
1940 :
- 1941 284376 : info = info_make(t + v_oldest, bad, rehash, justsynced);
+ 1941 288332 : info = info_make(t + v_oldest, bad, rehash, justsynced);
1942 : } else {
1943 15 : info = 0;
1944 : }
1945 :
- 1946 2060602 : while (v_count) {
+ 1946 2068514 : while (v_count) {
1947 : /* insert the info in the array */
1948 1491820 : info_set(&state->infoarr, v_pos, info);
1949 :
@@ -2028,7 +2028,7 @@
1966 1491820 : --v_count;
1967 : }
1968 : }
- 1969 118677 : } else if (c == 'h') {
+ 1969 118678 : } else if (c == 'h') {
1970 : /* hole */
1971 : uint32_t v_pos;
1972 : struct snapraid_disk* disk;
@@ -2074,7 +2074,7 @@
2012 : /* if it's a run of deleted blocks */
2013 :
2014 : /* allocate a fake deleted file */
- 2015 36 : deleted = file_alloc(state->block_size, "<deleted>", v_count * state->block_size, 0, 0, 0, 0);
+ 2015 36 : deleted = file_alloc(state->block_size, "<deleted>", v_count * (data_off_t)state->block_size, 0, 0, 0, 0);
2016 :
2017 : /* mark the file as deleted */
2018 36 : file_flag_set(deleted, FILE_IS_DELETED);
@@ -2126,7 +2126,7 @@
2064 : /* LCOV_EXCL_STOP */
2065 : }
2066 : }
- 2067 117378 : } else if (c == 's') {
+ 2067 117379 : } else if (c == 's') {
2068 : /* symlink */
2069 : char sub[PATH_MAX];
2070 : char linkto[PATH_MAX];
@@ -2176,7 +2176,7 @@
2114 :
2115 : /* stat */
2116 112395 : ++count_symlink;
- 2117 4983 : } else if (c == 'a') {
+ 2117 4984 : } else if (c == 'a') {
2118 : /* hardlink */
2119 : char sub[PATH_MAX];
2120 : char linkto[PATH_MAX];
@@ -2226,7 +2226,7 @@
2164 :
2165 : /* stat */
2166 567 : ++count_hardlink;
- 2167 4416 : } else if (c == 'r') {
+ 2167 4417 : } else if (c == 'r') {
2168 : /* dir */
2169 : char sub[PATH_MAX];
2170 : struct snapraid_dir* dir;
@@ -2267,7 +2267,7 @@
2205 :
2206 : /* stat */
2207 750 : ++count_dir;
- 2208 3666 : } else if (c == 'c') {
+ 2208 3667 : } else if (c == 'c') {
2209 : /* get the subcommand */
2210 235 : c = sgetc(f);
2211 :
@@ -2294,7 +2294,7 @@
2232 : exit(EXIT_FAILURE);
2233 : /* LCOV_EXCL_STOP */
2234 : }
- 2235 3431 : } else if (c == 'C') {
+ 2235 3432 : } else if (c == 'C') {
2236 : /* get the subcommand */
2237 87 : c = sgetc(f);
2238 :
@@ -2321,7 +2321,7 @@
2259 : exit(EXIT_FAILURE);
2260 : /* LCOV_EXCL_STOP */
2261 : }
- 2262 3344 : } else if (c == 'z') {
+ 2262 3345 : } else if (c == 'z') {
2263 : block_off_t blksize;
2264 :
2265 235 : ret = sgetb32(f, &blksize);
@@ -2345,7 +2345,7 @@
2283 : exit(EXIT_FAILURE);
2284 : /* LCOV_EXCL_STOP */
2285 : }
- 2286 3109 : } else if (c == 'x') {
+ 2286 3110 : } else if (c == 'x') {
2287 235 : ret = sgetb32(f, &blockmax);
2288 235 : if (ret < 0) {
2289 : /* LCOV_EXCL_START */
@@ -2353,7 +2353,7 @@
2291 : exit(EXIT_FAILURE);
2292 : /* LCOV_EXCL_STOP */
2293 : }
- 2294 4179 : } else if (c == 'm' || c == 'M') {
+ 2294 4180 : } else if (c == 'm' || c == 'M') {
2295 : struct snapraid_map* map;
2296 : char uuid[UUID_MAX];
2297 : uint32_t v_pos;
@@ -2427,7 +2427,7 @@
2365 1305 : tommy_array_grow(&disk_mapping, mapping_max + 1);
2366 1305 : tommy_array_set(&disk_mapping, mapping_max, disk);
2367 1305 : ++mapping_max;
- 2368 1569 : } else if (c == 'P') {
+ 2368 1570 : } else if (c == 'P') {
2369 : /* from SnapRAID 7.0 the 'P' command includes the free space */
2370 : char uuid[UUID_MAX];
2371 : uint32_t v_level;
@@ -2477,7 +2477,7 @@
2415 1081 : state->parity[v_level].total_blocks = v_total_blocks;
2416 1081 : state->parity[v_level].free_blocks = v_free_blocks;
2417 : }
- 2418 234 : } else if (c == 'N') {
+ 2418 235 : } else if (c == 'N') {
2419 : uint32_t crc_stored;
2420 : uint32_t crc_computed;
2421 :
@@ -2511,7 +2511,7 @@
2449 : exit(EXIT_FAILURE);
2450 : /* LCOV_EXCL_STOP */
2451 : }
- 2452 3604746 : }
+ 2452 3604826 : }
2453 :
2454 234 : tommy_array_done(&disk_mapping);
2455 :
@@ -2702,7 +2702,7 @@
2640 5428 : sputb32(l, f);
2641 5428 : sputb32(state->parity[l].total_blocks, f);
2642 5428 : sputb32(state->parity[l].free_blocks, f);
- 2643 5428 : sputbs(state->parity[l].uuid, f);
+ 2643 5427 : sputbs(state->parity[l].uuid, f);
2644 5428 : if (serror(f)) {
2645 : /* LCOV_EXCL_START */
2646 : log_fatal("Error writing the content file '%s'. %s.\n", serrorfile(f), strerror(errno));
@@ -2729,30 +2729,30 @@
2667 441 : continue;
2668 :
2669 : /* for each file */
- 2670 11587893 : for (j = disk->filelist; j != 0; j = j->next) {
- 2671 11582856 : struct snapraid_file* file = j->data;
+ 2670 11578188 : for (j = disk->filelist; j != 0; j = j->next) {
+ 2671 11573152 : struct snapraid_file* file = j->data;
2672 : uint64_t size;
2673 : uint64_t mtime_sec;
2674 : int32_t mtime_nsec;
2675 : uint64_t inode;
2676 :
- 2677 11582856 : size = file->size;
- 2678 11582856 : mtime_sec = file->mtime_sec;
- 2679 11582856 : mtime_nsec = file->mtime_nsec;
- 2680 11582856 : inode = file->inode;
+ 2677 11573152 : size = file->size;
+ 2678 11573152 : mtime_sec = file->mtime_sec;
+ 2679 11573152 : mtime_nsec = file->mtime_nsec;
+ 2680 11573152 : inode = file->inode;
2681 :
- 2682 11582856 : sputc('f', f);
- 2683 11521097 : sputb32(disk->mapping_idx, f);
- 2684 11524134 : sputb64(size, f);
- 2685 11502453 : sputb64(mtime_sec, f);
+ 2682 11573152 : sputc('f', f);
+ 2683 11523322 : sputb32(disk->mapping_idx, f);
+ 2684 11531504 : sputb64(size, f);
+ 2685 11543059 : sputb64(mtime_sec, f);
2686 : /* encode STAT_NSEC_INVALID as 0 */
- 2687 11514392 : if (mtime_nsec == STAT_NSEC_INVALID)
+ 2687 11521684 : if (mtime_nsec == STAT_NSEC_INVALID)
2688 0 : sputb32(0, f);
2689 : else
- 2690 11514392 : sputb32(mtime_nsec + 1, f);
- 2691 11535535 : sputb64(inode, f);
- 2692 11530269 : sputbs(file->sub, f);
- 2693 11528881 : if (serror(f)) {
+ 2690 11521684 : sputb32(mtime_nsec + 1, f);
+ 2691 11530611 : sputb64(inode, f);
+ 2692 11526825 : sputbs(file->sub, f);
+ 2693 11546662 : if (serror(f)) {
2694 : /* LCOV_EXCL_START */
2695 : log_fatal("Error writing the content file '%s'. %s.\n", serrorfile(f), strerror(errno));
2696 : goto bail;
@@ -2760,34 +2760,34 @@
2698 : }
2699 :
2700 : /* for all the blocks of the file */
- 2701 11541902 : begin = 0;
- 2702 34727907 : while (begin < file->blockmax) {
- 2703 11603149 : unsigned v_state = block_state_get(fs_file2block_get(file, begin));
- 2704 11623161 : block_off_t v_pos = fs_file2par_get_ts(disk, &fs_last, file, begin);
+ 2701 11560751 : begin = 0;
+ 2702 34754559 : while (begin < file->blockmax) {
+ 2703 11620657 : unsigned v_state = block_state_get(fs_file2block_get(file, begin));
+ 2704 11635419 : block_off_t v_pos = fs_file2par_get_ts(disk, &fs_last, file, begin);
2705 : uint32_t v_count;
2706 :
2707 : block_off_t end;
2708 :
2709 : /* find the end of run of blocks */
- 2710 11615466 : end = begin + 1;
- 2711 39962808 : while (end < file->blockmax) {
- 2712 16803655 : if (v_state != block_state_get(fs_file2block_get(file, end)))
+ 2710 11602915 : end = begin + 1;
+ 2711 40021161 : while (end < file->blockmax) {
+ 2712 16868038 : if (v_state != block_state_get(fs_file2block_get(file, end)))
2713 63 : break;
- 2714 16856743 : if (v_pos + (end - begin) != fs_file2par_get_ts(disk, &fs_last, file, end))
- 2715 82936 : break;
- 2716 16731876 : ++end;
+ 2714 16887534 : if (v_pos + (end - begin) != fs_file2par_get_ts(disk, &fs_last, file, end))
+ 2715 83317 : break;
+ 2716 16815331 : ++end;
2717 : }
2718 :
- 2719 11626686 : switch (v_state) {
+ 2719 11633588 : switch (v_state) {
2720 : case BLOCK_STATE_BLK :
- 2721 10916510 : sputc('b', f);
- 2722 10892646 : break;
+ 2721 10922665 : sputc('b', f);
+ 2722 10930254 : break;
2723 : case BLOCK_STATE_CHG :
- 2724 558744 : sputc('g', f);
- 2725 558725 : break;
+ 2724 559524 : sputc('g', f);
+ 2725 559519 : break;
2726 : case BLOCK_STATE_REP :
- 2727 151432 : sputc('p', f);
- 2728 151433 : break;
+ 2727 151399 : sputc('p', f);
+ 2728 151402 : break;
2729 : default :
2730 : /* LCOV_EXCL_START */
2731 : log_fatal("Internal inconsistency in state for block %u state %u\n", v_pos, v_state);
@@ -2795,19 +2795,19 @@
2733 : /* LCOV_EXCL_STOP */
2734 : }
2735 :
- 2736 11602804 : sputb32(v_pos, f);
+ 2736 11641175 : sputb32(v_pos, f);
2737 :
- 2738 11631290 : v_count = end - begin;
- 2739 11631290 : sputb32(v_count, f);
+ 2738 11622679 : v_count = end - begin;
+ 2739 11622679 : sputb32(v_count, f);
2740 :
2741 : /* write hashes */
- 2742 39802834 : for (idx = begin; idx < end; ++idx) {
- 2743 28167488 : struct snapraid_block* block = fs_file2block_get(file, idx);
+ 2742 39768736 : for (idx = begin; idx < end; ++idx) {
+ 2743 28155837 : struct snapraid_block* block = fs_file2block_get(file, idx);
2744 :
- 2745 28196345 : swrite(block->hash, HASH_SIZE, f);
+ 2745 28133584 : swrite(block->hash, HASH_SIZE, f);
2746 : }
2747 :
- 2748 11635346 : if (serror(f)) {
+ 2748 11612899 : if (serror(f)) {
2749 : /* LCOV_EXCL_START */
2750 : log_fatal("Error writing the content file '%s'. %s.\n", serrorfile(f), strerror(errno));
2751 : goto bail;
@@ -2815,31 +2815,31 @@
2753 : }
2754 :
2755 : /* next begin position */
- 2756 11644103 : begin = end;
+ 2756 11633057 : begin = end;
2757 : }
2758 :
- 2759 11582856 : ++count_file;
+ 2759 11573151 : ++count_file;
2760 : }
2761 :
2762 : /* for each link */
- 2763 385486 : for (j = disk->linklist; j != 0; j = j->next) {
- 2764 380449 : struct snapraid_link* slink = j->data;
+ 2763 385485 : for (j = disk->linklist; j != 0; j = j->next) {
+ 2764 380448 : struct snapraid_link* slink = j->data;
2765 :
- 2766 380449 : switch (link_flag_get(slink, FILE_IS_LINK_MASK)) {
+ 2766 380448 : switch (link_flag_get(slink, FILE_IS_LINK_MASK)) {
2767 : case FILE_IS_HARDLINK :
2768 2046 : sputc('a', f);
2769 2046 : ++count_hardlink;
2770 2046 : break;
2771 : case FILE_IS_SYMLINK :
- 2772 378355 : sputc('s', f);
- 2773 378402 : ++count_symlink;
- 2774 378402 : break;
+ 2772 378402 : sputc('s', f);
+ 2773 378020 : ++count_symlink;
+ 2774 378020 : break;
2775 : }
2776 :
- 2777 380132 : sputb32(disk->mapping_idx, f);
- 2778 380405 : sputbs(slink->sub, f);
- 2779 380450 : sputbs(slink->linkto, f);
- 2780 380448 : if (serror(f)) {
+ 2777 380066 : sputb32(disk->mapping_idx, f);
+ 2778 380422 : sputbs(slink->sub, f);
+ 2779 380445 : sputbs(slink->linkto, f);
+ 2780 380449 : if (serror(f)) {
2781 : /* LCOV_EXCL_START */
2782 : log_fatal("Error writing the content file '%s'. %s.\n", serrorfile(f), strerror(errno));
2783 : goto bail;
@@ -2881,11 +2881,11 @@
2819 5569 : is_deleted = fs_is_block_deleted_ts(disk, &fs_last, begin);
2820 :
2821 : /* find the end of run of blocks */
- 2822 5568 : end = begin + 1;
- 2823 29329135 : while (end < blockmax
- 2824 29372732 : && is_deleted == fs_is_block_deleted_ts(disk, &fs_last, end)
+ 2822 5569 : end = begin + 1;
+ 2823 29396439 : while (end < blockmax
+ 2824 29341613 : && is_deleted == fs_is_block_deleted_ts(disk, &fs_last, end)
2825 : ) {
- 2826 29317999 : ++end;
+ 2826 29385301 : ++end;
2827 : }
2828 :
2829 0 : sputb32(end - begin, f);
@@ -2923,45 +2923,45 @@
2861 : /* write the info for each block */
2862 913 : sputc('i', f);
2863 913 : sputb32(info_oldest, f);
- 2864 8223 : begin = 0;
- 2865 1418395 : while (begin < blockmax) {
+ 2864 929 : begin = 0;
+ 2865 1427365 : while (begin < blockmax) {
2866 : snapraid_info info;
2867 : block_off_t end;
2868 : time_t t;
2869 : unsigned flag;
2870 :
- 2871 1409259 : info = info_get(&state->infoarr, begin);
+ 2871 1425523 : info = info_get(&state->infoarr, begin);
2872 :
2873 : /* find the end of run of blocks */
- 2874 1408072 : end = begin + 1;
- 2875 6328564 : while (end < blockmax
- 2876 4918189 : && info == info_get(&state->infoarr, end)
+ 2874 1426289 : end = begin + 1;
+ 2875 6350808 : while (end < blockmax
+ 2876 4922834 : && info == info_get(&state->infoarr, end)
2877 : ) {
- 2878 3512420 : ++end;
+ 2878 3498230 : ++end;
2879 : }
2880 :
- 2881 1407793 : sputb32(end - begin, f);
+ 2881 1427382 : sputb32(end - begin, f);
2882 :
2883 : /* if there is info */
- 2884 1408365 : if (info) {
+ 2884 1426642 : if (info) {
2885 : /* other flags */
- 2886 1408235 : flag = 1; /* info is present */
- 2887 1408235 : if (info_get_bad(info))
- 2888 9500 : flag |= 2;
- 2889 1407263 : if (info_get_rehash(info))
- 2890 673630 : flag |= 4;
- 2891 1406735 : if (info_get_justsynced(info))
- 2892 723766 : flag |= 8;
- 2893 1398202 : sputb32(flag, f);
+ 2886 1426512 : flag = 1; /* info is present */
+ 2887 1426512 : if (info_get_bad(info))
+ 2888 9590 : flag |= 2;
+ 2889 1425847 : if (info_get_rehash(info))
+ 2890 673003 : flag |= 4;
+ 2891 1425736 : if (info_get_justsynced(info))
+ 2892 724485 : flag |= 8;
+ 2893 1425766 : sputb32(flag, f);
2894 :
- 2895 1408672 : t = info_get_time(info) - info_oldest;
- 2896 1408134 : sputb32(t, f);
+ 2895 1425741 : t = info_get_time(info) - info_oldest;
+ 2896 1425676 : sputb32(t, f);
2897 : } else {
2898 : /* write a special 0 flag to mark missing info */
2899 130 : sputb32(0, f);
2900 : }
2901 :
- 2902 1409231 : if (serror(f)) {
+ 2902 1425342 : if (serror(f)) {
2903 : /* LCOV_EXCL_START */
2904 : log_fatal("Error writing the content file '%s'. %s.\n", serrorfile(f), strerror(errno));
2905 : goto bail;
@@ -2969,7 +2969,7 @@
2907 : }
2908 :
2909 : /* next begin position */
- 2910 1401949 : begin = end;
+ 2910 1425507 : begin = end;
2911 : }
2912 :
2913 913 : sputc('N', f);
@@ -3022,7 +3022,7 @@
2960 : }
2961 : #endif
2962 :
- 2963 912 : if (sclose(f) != 0) {
+ 2963 913 : if (sclose(f) != 0) {
2964 : /* LCOV_EXCL_START */
2965 : f = 0;
2966 : log_fatal("Error closing the content files. %s.\n", strerror(errno));
@@ -3084,7 +3084,7 @@
3022 680773 : time_t info_time = info_get_time(info);
3023 :
3024 680773 : if (!info_oldest || info_time < info_oldest)
- 3025 169 : info_oldest = info_time;
+ 3025 170 : info_oldest = info_time;
3026 :
3027 680773 : if (info_get_rehash(info))
3028 108421 : info_has_rehash = 1;
@@ -3151,7 +3151,7 @@
3089 : /* LCOV_EXCL_STOP */
3090 : }
3091 : #else
- 3092 : content->retval = state_write_thread(context);
+ 3092 : context->retval = state_write_thread(context);
3093 : #endif
3094 :
3095 913 : i = i->next;
@@ -3384,17 +3384,17 @@
3322 : uint32_t crc;
3323 : };
3324 :
- 3325 908 : static void* state_verify_thread(void* arg)
+ 3325 912 : static void* state_verify_thread(void* arg)
3326 : {
- 3327 908 : struct state_verify_thread_context* context = arg;
- 3328 908 : struct snapraid_content* content = context->content;
+ 3327 912 : struct state_verify_thread_context* context = arg;
+ 3328 912 : struct snapraid_content* content = context->content;
3329 : STREAM* f;
3330 : char tmp[PATH_MAX];
3331 : unsigned char buf[4];
3332 : uint32_t crc_stored;
3333 : uint32_t crc_computed;
3334 :
- 3335 908 : pathprint(tmp, sizeof(tmp), "%s.tmp", content->content);
+ 3335 912 : pathprint(tmp, sizeof(tmp), "%s.tmp", content->content);
3336 :
3337 913 : f = sopen_read(tmp);
3338 913 : if (f == 0) {
@@ -3631,15 +3631,15 @@
3569 12 : msg_progress("Scanning disk %s...\n", disk->name);
3570 :
3571 : /* for each file */
- 3572 133845 : for (j = tommy_list_head(&disk->filelist); j != 0; j = j->next) {
- 3573 133791 : struct snapraid_file* file = j->data;
+ 3572 133854 : for (j = tommy_list_head(&disk->filelist); j != 0; j = j->next) {
+ 3573 133800 : struct snapraid_file* file = j->data;
3574 :
- 3575 133791 : if (filter_path(filterlist_disk, 0, disk->name, file->sub) != 0
- 3576 80918 : || filter_path(filterlist_file, 0, disk->name, file->sub) != 0
- 3577 78085 : || filter_existence(filter_missing, disk->dir, file->sub) != 0
- 3578 38803 : || filter_correctness(filter_error, &state->infoarr, disk, file) != 0
+ 3575 133800 : if (filter_path(filterlist_disk, 0, disk->name, file->sub) != 0
+ 3576 80924 : || filter_path(filterlist_file, 0, disk->name, file->sub) != 0
+ 3577 78090 : || filter_existence(filter_missing, disk->dir, file->sub) != 0
+ 3578 38806 : || filter_correctness(filter_error, &state->infoarr, disk, file) != 0
3579 : ) {
- 3580 109060 : file_flag_set(file, FILE_IS_EXCLUDED);
+ 3580 109102 : file_flag_set(file, FILE_IS_EXCLUDED);
3581 : }
3582 : }
3583 :
@@ -3776,21 +3776,21 @@
3714 :
3715 : #define PROGRESS_CLEAR " "
3716 :
- 3717 1038828 : int state_progress(struct snapraid_state* state, block_off_t blockpos, block_off_t countpos, block_off_t countmax, data_off_t countsize)
+ 3717 1038958 : int state_progress(struct snapraid_state* state, block_off_t blockpos, block_off_t countpos, block_off_t countmax, data_off_t countsize)
3718 : {
3719 : time_t now;
3720 : int pred;
3721 :
- 3722 1038828 : now = time(0);
+ 3722 1038958 : now = time(0);
3723 :
3724 : /* previous position */
- 3725 1038828 : pred = state->progress_ptr + PROGRESS_MAX - 1;
- 3726 1038828 : if (pred >= PROGRESS_MAX)
- 3727 1038640 : pred -= PROGRESS_MAX;
+ 3725 1038958 : pred = state->progress_ptr + PROGRESS_MAX - 1;
+ 3726 1038958 : if (pred >= PROGRESS_MAX)
+ 3727 1038770 : pred -= PROGRESS_MAX;
3728 :
3729 : /* if the previous measure is different */
- 3730 1038828 : if (state->progress_tick == 0
- 3731 1038640 : || state->progress_time[pred] != now
+ 3730 1038958 : if (state->progress_tick == 0
+ 3731 1038770 : || state->progress_time[pred] != now
3732 : ) {
3733 : uint64_t tick_total;
3734 : uint64_t tick_cpu;
@@ -3852,7 +3852,7 @@
3790 :
3791 : /* estimate the cpu usage percentage */
3792 72 : if (delta_tick_total != 0)
- 3793 12 : out_cpu = (unsigned)(delta_tick_cpu * 100U / delta_tick_total);
+ 3793 10 : out_cpu = (unsigned)(delta_tick_cpu * 100U / delta_tick_total);
3794 :
3795 : /* estimate the remaining time in minutes */
3796 72 : if (delta_pos != 0)
@@ -3865,11 +3865,11 @@
3803 : } else {
3804 253 : msg_bar("%u%%, %u MiB", out_perc, (unsigned)(countsize / MEGA));
3805 253 : if (out_speed)
- 3806 61 : msg_bar(", %u MiB/s", out_speed);
+ 3806 63 : msg_bar(", %u MiB/s", out_speed);
3807 253 : if (out_cpu)
- 3808 12 : msg_bar(", CPU %u%%", out_cpu);
+ 3808 10 : msg_bar(", CPU %u%%", out_cpu);
3809 253 : if (out_eta)
- 3810 2 : msg_bar(", %u:%02u ETA", out_eta / 60, out_eta % 60);
+ 3810 0 : msg_bar(", %u:%02u ETA", out_eta / 60, out_eta % 60);
3811 253 : msg_bar("%s\r", PROGRESS_CLEAR);
3812 253 : msg_flush();
3813 : }
@@ -3891,7 +3891,7 @@
3829 : }
3830 :
3831 : /* stop if requested */
- 3832 1038828 : if (global_interrupt) {
+ 3832 1038958 : if (global_interrupt) {
3833 : /* LCOV_EXCL_START */
3834 : if (!state->opt.gui) {
3835 : log_fatal("\n");
@@ -3903,7 +3903,7 @@
3841 : /* LCOV_EXCL_STOP */
3842 : }
3843 :
- 3844 1038828 : return 0;
+ 3844 1038958 : return 0;
3845 : }
3846 :
3847 81 : void state_usage_print(struct snapraid_state* state)
@@ -3919,7 +3919,7 @@
3857 484 : struct snapraid_disk* disk = i->data;
3858 484 : tick_total += disk->tick;
3859 484 : if (disk->tick > tick_max)
- 3860 100 : tick_max = disk->tick;
+ 3860 99 : tick_max = disk->tick;
3861 : }
3862 552 : for (l = 0; l < state->level; ++l) {
3863 471 : tick_total += state->parity[l].tick;
diff --git a/cov/cmdline/state.h.func-sort-c.html b/cov/cmdline/state.h.func-sort-c.html
index b1b14f40..05fa4cc0 100644
--- a/cov/cmdline/state.h.func-sort-c.html
+++ b/cov/cmdline/state.h.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,15 +61,15 @@
| state_usage_cpu |
- 771844 |
+ 772778 |
| state_usage_parity |
- 652636 |
+ 653350 |
| state_usage_disk |
- 621730 |
+ 622545 |
| state_usage_waste |
diff --git a/cov/cmdline/state.h.func.html b/cov/cmdline/state.h.func.html
index 5ef1afff..37c5849d 100644
--- a/cov/cmdline/state.h.func.html
+++ b/cov/cmdline/state.h.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,15 +61,15 @@
| state_usage_cpu |
- 771844 |
+ 772778 |
| state_usage_disk |
- 621730 |
+ 622545 |
| state_usage_parity |
- 652636 |
+ 653350 |
| state_usage_waste |
diff --git a/cov/cmdline/state.h.gcov.html b/cov/cmdline/state.h.gcov.html
index b420bafb..0cdf4d7f 100644
--- a/cov/cmdline/state.h.gcov.html
+++ b/cov/cmdline/state.h.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -394,48 +394,48 @@
332 : /**
333 : * Set the usage time for CPU.
334 : */
- 335 771844 : static inline void state_usage_cpu(struct snapraid_state* state)
+ 335 772778 : static inline void state_usage_cpu(struct snapraid_state* state)
336 : {
- 337 771844 : uint64_t now = tick();
- 338 771844 : uint64_t delta = now - state->tick_last;
+ 337 772778 : uint64_t now = tick();
+ 338 772778 : uint64_t delta = now - state->tick_last;
339 :
340 : /* increment the time spent in computations */
- 341 771844 : state->tick_cpu += delta;
+ 341 772778 : state->tick_cpu += delta;
342 :
- 343 771844 : state->tick_last = now;
- 344 771844 : }
+ 343 772778 : state->tick_last = now;
+ 344 772778 : }
345 :
346 : /**
347 : * Set the usage time for data disk.
348 : */
- 349 621730 : static inline void state_usage_disk(struct snapraid_state* state, struct snapraid_disk* disk)
+ 349 622545 : static inline void state_usage_disk(struct snapraid_state* state, struct snapraid_disk* disk)
350 : {
- 351 621730 : uint64_t now = tick();
- 352 621730 : uint64_t delta = now - state->tick_last;
+ 351 622545 : uint64_t now = tick();
+ 352 622545 : uint64_t delta = now - state->tick_last;
353 :
354 : /* increment the time spent in the data disk */
- 355 621730 : disk->tick += delta;
- 356 621730 : state->tick_io += delta;
+ 355 622545 : disk->tick += delta;
+ 356 622545 : state->tick_io += delta;
357 :
- 358 621730 : state->tick_last = now;
- 359 621730 : }
+ 358 622545 : state->tick_last = now;
+ 359 622545 : }
360 :
361 : /**
362 : * Set the usage time for parity disk.
363 : */
- 364 652636 : static inline void state_usage_parity(struct snapraid_state* state, unsigned level)
+ 364 653350 : static inline void state_usage_parity(struct snapraid_state* state, unsigned level)
365 : {
- 366 652636 : uint64_t now = tick();
- 367 652636 : uint64_t delta = now - state->tick_last;
+ 366 653350 : uint64_t now = tick();
+ 367 653350 : uint64_t delta = now - state->tick_last;
368 :
- 369 652636 : assert(level < LEV_MAX);
+ 369 653350 : assert(level < LEV_MAX);
370 :
371 : /* increment the time spent in the parity disk */
- 372 652636 : state->parity[level].tick += delta;
- 373 652636 : state->tick_io += delta;
+ 372 653350 : state->parity[level].tick += delta;
+ 373 653350 : state->tick_io += delta;
374 :
- 375 652636 : state->tick_last = now;
- 376 652636 : }
+ 375 653350 : state->tick_last = now;
+ 376 653350 : }
377 :
378 : /**
379 : * Print the stats of the usage time.
diff --git a/cov/cmdline/status.c.func-sort-c.html b/cov/cmdline/status.c.func-sort-c.html
index f2906c5b..3a3013e8 100644
--- a/cov/cmdline/status.c.func-sort-c.html
+++ b/cov/cmdline/status.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/cmdline/status.c.func.html b/cov/cmdline/status.c.func.html
index 3dbe2d34..fd04e329 100644
--- a/cov/cmdline/status.c.func.html
+++ b/cov/cmdline/status.c.func.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/cmdline/status.c.gcov.html b/cov/cmdline/status.c.gcov.html
index d11e227a..59c5f405 100644
--- a/cov/cmdline/status.c.gcov.html
+++ b/cov/cmdline/status.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -195,14 +195,14 @@
133 :
134 : /* for each file in the disk */
135 84 : node = disk->filelist;
- 136 95602 : while (node) {
+ 136 95610 : while (node) {
137 : struct snapraid_file* file;
138 :
- 139 95434 : file = node->data;
- 140 95434 : node = node->next; /* next node */
+ 139 95442 : file = node->data;
+ 140 95442 : node = node->next; /* next node */
141 :
142 : /* check fragmentation */
- 143 95434 : if (file->blockmax != 0) {
+ 143 95442 : if (file->blockmax != 0) {
144 : block_off_t prev_pos;
145 : block_off_t last_pos;
146 : int fragmented;
@@ -234,11 +234,11 @@
172 : }
173 :
174 : /* count files */
- 175 95434 : ++file_count;
- 176 95434 : ++disk_file_count;
- 177 95434 : file_size += file->size;
- 178 95434 : file_block_count += file->blockmax;
- 179 95434 : disk_file_size += file->size;
+ 175 95442 : ++file_count;
+ 176 95442 : ++disk_file_count;
+ 177 95442 : file_size += file->size;
+ 178 95442 : file_block_count += file->blockmax;
+ 179 95442 : disk_file_size += file->size;
180 : }
181 :
182 84 : if (disk->free_blocks != 0)
@@ -367,10 +367,10 @@
305 : time_t scrub_time;
306 :
307 39606 : if (info_get_bad(info)) {
- 308 1803 : if (bad == 0)
+ 308 1802 : if (bad == 0)
309 2 : bad_first = i;
- 310 1803 : bad_last = i;
- 311 1803 : ++bad;
+ 310 1802 : bad_last = i;
+ 311 1802 : ++bad;
312 : }
313 :
314 39606 : if (info_get_rehash(info))
@@ -379,10 +379,10 @@
317 39606 : scrub_time = info_get_time(info);
318 :
319 39606 : if (info_get_justsynced(info)) {
- 320 20357 : ++unscrubbed_blocks;
+ 320 20364 : ++unscrubbed_blocks;
321 :
322 : /* mark the time as not scrubbed */
- 323 20357 : scrub_time |= TIME_NEW;
+ 323 20364 : scrub_time |= TIME_NEW;
324 : }
325 :
326 39606 : timemap[count++] = scrub_time;
@@ -414,16 +414,16 @@
352 : /* output the info map */
353 8 : i = 0;
354 8 : log_tag("info_count:%u\n", count);
- 355 39 : while (i < count) {
- 356 23 : unsigned j = i + 1;
- 357 39629 : while (j < count && timemap[i] == timemap[j])
- 358 39583 : ++j;
- 359 23 : if ((timemap[i] & TIME_NEW) == 0) {
- 360 8 : log_tag("info_time:%" PRIu64 ":%u:scrubbed\n", (uint64_t)timemap[i], j - i);
+ 355 41 : while (i < count) {
+ 356 25 : unsigned j = i + 1;
+ 357 39631 : while (j < count && timemap[i] == timemap[j])
+ 358 39581 : ++j;
+ 359 25 : if ((timemap[i] & TIME_NEW) == 0) {
+ 360 9 : log_tag("info_time:%" PRIu64 ":%u:scrubbed\n", (uint64_t)timemap[i], j - i);
361 : } else {
- 362 15 : log_tag("info_time:%" PRIu64 ":%u:new\n", (uint64_t)(timemap[i] & ~TIME_NEW), j - i);
+ 362 16 : log_tag("info_time:%" PRIu64 ":%u:new\n", (uint64_t)(timemap[i] & ~TIME_NEW), j - i);
363 : }
- 364 23 : i = j;
+ 364 25 : i = j;
365 : }
366 :
367 8 : oldest = timemap[0];
@@ -446,9 +446,9 @@
384 560 : step_new = 0;
385 40726 : while (barpos < count && timemap[barpos] <= limit) {
386 39606 : if ((timemap[barpos] & TIME_NEW) != 0)
- 387 20357 : ++step_new;
+ 387 20364 : ++step_new;
388 : else
- 389 19249 : ++step_scrubbed;
+ 389 19242 : ++step_scrubbed;
390 39606 : ++barpos;
391 : }
392 :
@@ -483,13 +483,13 @@
421 : else
422 94 : printf("o");
423 8232 : } else if (both > pivot_lower) {
- 424 23 : if (scrubbed == both)
- 425 8 : printf("*");
+ 424 25 : if (scrubbed == both)
+ 425 9 : printf("*");
426 : else
- 427 15 : printf("o");
+ 427 16 : printf("o");
428 : } else {
- 429 8209 : if (y == GRAPH_ROW - 1)
- 430 537 : printf("_");
+ 429 8207 : if (y == GRAPH_ROW - 1)
+ 430 535 : printf("_");
431 : else
432 7672 : printf(" ");
433 : }
@@ -536,19 +536,19 @@
474 :
475 : /* print some of the errors */
476 2 : bad_print = 0;
- 477 611 : for (i = 0; i < blockmax; ++i) {
- 478 611 : snapraid_info info = info_get(&state->infoarr, i);
+ 477 609 : for (i = 0; i < blockmax; ++i) {
+ 478 609 : snapraid_info info = info_get(&state->infoarr, i);
479 :
480 : /* skip unused blocks */
- 481 611 : if (info == 0)
+ 481 609 : if (info == 0)
482 0 : continue;
483 :
- 484 611 : if (info_get_bad(info)) {
+ 484 609 : if (info_get_bad(info)) {
485 202 : printf(" %u", i);
486 202 : ++bad_print;
487 : }
488 :
- 489 611 : if (bad_print > 100) {
+ 489 609 : if (bad_print > 100) {
490 2 : printf(" and %u more...", bad - bad_print);
491 2 : break;
492 : }
diff --git a/cov/cmdline/stream.c.func-sort-c.html b/cov/cmdline/stream.c.func-sort-c.html
index 1ad1bd38..929397e4 100644
--- a/cov/cmdline/stream.c.func-sort-c.html
+++ b/cov/cmdline/stream.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,47 +61,47 @@
| swrite |
- 130046569 |
+ 129597634 |
| sputb32 |
- 62124806 |
+ 62339359 |
| sputb64 |
- 34119322 |
+ 34173479 |
| sgetb32 |
- 18698507 |
+ 18710390 |
| sread |
- 12343180 |
+ 12342909 |
| sputbs |
- 12250827 |
+ 12306366 |
| sgetb64 |
- 10465700 |
+ 10465937 |
| sgetbs |
- 3732711 |
+ 3732790 |
| sfill |
- 606448 |
+ 606496 |
| sgetc_uncached |
- 298580 |
+ 298585 |
| sflush |
- 52551 |
+ 52590 |
| sgettok |
@@ -117,7 +117,7 @@
| sclose |
- 2576 |
+ 2575 |
| scrc |
@@ -125,7 +125,7 @@
| sopen_read |
- 1700 |
+ 1701 |
| sdeplete |
@@ -139,22 +139,22 @@
scrc_stream |
929 |
-
- | sopen_multi_write |
- 929 |
-
| sputble32 |
929 |
- | ssync |
- 913 |
+ sopen_multi_write |
+ 928 |
| sopen_write |
913 |
+
+ | ssync |
+ 912 |
+
| sgetble32 |
362 |
diff --git a/cov/cmdline/stream.c.func.html b/cov/cmdline/stream.c.func.html
index 090c471f..518a0543 100644
--- a/cov/cmdline/stream.c.func.html
+++ b/cov/cmdline/stream.c.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,7 +61,7 @@
| sclose |
- 2576 |
+ 2575 |
| scrc |
@@ -77,19 +77,19 @@
| sfill |
- 606448 |
+ 606496 |
| sflush |
- 52551 |
+ 52590 |
| sgetb32 |
- 18698507 |
+ 18710390 |
| sgetb64 |
- 10465700 |
+ 10465937 |
| sgetble32 |
@@ -97,11 +97,11 @@
| sgetbs |
- 3732711 |
+ 3732790 |
| sgetc_uncached |
- 298580 |
+ 298585 |
| sgetlasttok |
@@ -129,11 +129,11 @@
| sopen_multi_write |
- 929 |
+ 928 |
| sopen_read |
- 1700 |
+ 1701 |
| sopen_write |
@@ -141,11 +141,11 @@
| sputb32 |
- 62124806 |
+ 62339359 |
| sputb64 |
- 34119322 |
+ 34173479 |
| sputble32 |
@@ -153,15 +153,15 @@
| sputbs |
- 12250827 |
+ 12306366 |
| sread |
- 12343180 |
+ 12342909 |
| ssync |
- 913 |
+ 912 |
| stell |
@@ -169,7 +169,7 @@
| swrite |
- 130046569 |
+ 129597634 |
diff --git a/cov/cmdline/stream.c.gcov.html b/cov/cmdline/stream.c.gcov.html
index 4cf237fc..93ec3984 100644
--- a/cov/cmdline/stream.c.gcov.html
+++ b/cov/cmdline/stream.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -88,19 +88,19 @@
26 :
27 : unsigned STREAM_SIZE = 1024 * 64;
28 :
- 29 1700 : STREAM* sopen_read(const char* file)
+ 29 1701 : STREAM* sopen_read(const char* file)
30 : {
31 : #if HAVE_POSIX_FADVISE
32 : int ret;
33 : #endif
- 34 1700 : STREAM* s = malloc_nofail(sizeof(STREAM));
+ 34 1701 : STREAM* s = malloc_nofail(sizeof(STREAM));
35 :
36 1701 : s->handle_size = 1;
37 1701 : s->handle = malloc_nofail(sizeof(struct stream_handle));
38 :
39 1700 : pathcpy(s->handle[0].path, sizeof(s->handle[0].path), file);
40 1701 : s->handle[0].f = open(file, O_RDONLY | O_BINARY | O_SEQUENTIAL);
- 41 1701 : if (s->handle[0].f == -1) {
+ 41 1700 : if (s->handle[0].f == -1) {
42 50 : free(s->handle);
43 50 : free(s);
44 50 : return 0;
@@ -108,8 +108,8 @@
46 :
47 : #if HAVE_POSIX_FADVISE
48 : /* advise sequential access */
- 49 1651 : ret = posix_fadvise(s->handle[0].f, 0, 0, POSIX_FADV_SEQUENTIAL);
- 50 1651 : if (ret != 0) {
+ 49 1650 : ret = posix_fadvise(s->handle[0].f, 0, 0, POSIX_FADV_SEQUENTIAL);
+ 50 1644 : if (ret != 0) {
51 : /* LCOV_EXCL_START */
52 : close(s->handle[0].f);
53 : free(s->handle);
@@ -119,33 +119,33 @@
57 : }
58 : #endif
59 :
- 60 1651 : s->buffer = malloc_nofail_test(STREAM_SIZE);
- 61 1651 : s->pos = s->buffer;
- 62 1651 : s->end = s->buffer;
- 63 1651 : s->state = STREAM_STATE_READ;
- 64 1651 : s->state_index = 0;
- 65 1651 : s->offset = 0;
- 66 1651 : s->offset_uncached = 0;
- 67 1651 : s->crc = 0;
- 68 1651 : s->crc_uncached = 0;
- 69 1651 : s->crc_stream = CRC_IV;
+ 60 1644 : s->buffer = malloc_nofail_test(STREAM_SIZE);
+ 61 1650 : s->pos = s->buffer;
+ 62 1650 : s->end = s->buffer;
+ 63 1650 : s->state = STREAM_STATE_READ;
+ 64 1650 : s->state_index = 0;
+ 65 1650 : s->offset = 0;
+ 66 1650 : s->offset_uncached = 0;
+ 67 1650 : s->crc = 0;
+ 68 1650 : s->crc_uncached = 0;
+ 69 1650 : s->crc_stream = CRC_IV;
70 :
- 71 1651 : return s;
+ 71 1650 : return s;
72 : }
73 :
- 74 929 : STREAM* sopen_multi_write(unsigned count)
+ 74 928 : STREAM* sopen_multi_write(unsigned count)
75 : {
76 : unsigned i;
77 :
- 78 929 : STREAM* s = malloc_nofail(sizeof(STREAM));
+ 78 928 : STREAM* s = malloc_nofail(sizeof(STREAM));
79 :
80 929 : s->handle_size = count;
81 929 : s->handle = malloc_nofail(count * sizeof(struct stream_handle));
82 :
- 83 1970 : for (i = 0; i < count; ++i)
- 84 1041 : s->handle[i].f = -1;
+ 83 1968 : for (i = 0; i < count; ++i)
+ 84 1040 : s->handle[i].f = -1;
85 :
- 86 929 : s->buffer = malloc_nofail_test(STREAM_SIZE);
+ 86 928 : s->buffer = malloc_nofail_test(STREAM_SIZE);
87 929 : s->pos = s->buffer;
88 929 : s->end = s->buffer + STREAM_SIZE;
89 929 : s->state = STREAM_STATE_WRITE;
@@ -203,21 +203,21 @@
141 913 : return s;
142 : }
143 :
- 144 2576 : int sclose(STREAM* s)
+ 144 2575 : int sclose(STREAM* s)
145 : {
- 146 2576 : int fail = 0;
+ 146 2575 : int fail = 0;
147 : unsigned i;
148 :
- 149 2576 : if (s->state == STREAM_STATE_WRITE) {
- 150 928 : if (sflush(s) != 0) {
+ 149 2575 : if (s->state == STREAM_STATE_WRITE) {
+ 150 927 : if (sflush(s) != 0) {
151 : /* LCOV_EXCL_START */
152 : fail = 1;
153 : /* LCOV_EXCL_STOP */
154 : }
155 : }
156 :
- 157 5267 : for (i = 0; i < s->handle_size; ++i) {
- 158 2689 : if (close(s->handle[i].f) != 0) {
+ 157 5266 : for (i = 0; i < s->handle_size; ++i) {
+ 158 2688 : if (close(s->handle[i].f) != 0) {
159 : /* LCOV_EXCL_START */
160 : fail = 1;
161 : /* LCOV_EXCL_STOP */
@@ -252,41 +252,41 @@
190 : * Fill the read stream buffer.
191 : * \return 0 if at least on char is read, or EOF on error.
192 : */
- 193 606448 : static int sfill(STREAM* s)
+ 193 606496 : static int sfill(STREAM* s)
194 : {
195 : ssize_t ret;
196 :
- 197 606448 : if (s->state != STREAM_STATE_READ) {
+ 197 606496 : if (s->state != STREAM_STATE_READ) {
198 : /* LCOV_EXCL_START */
199 : return EOF;
200 : /* LCOV_EXCL_STOP */
201 : }
202 :
- 203 605464 : ret = read(s->handle[0].f, s->buffer, STREAM_SIZE);
+ 203 605512 : ret = read(s->handle[0].f, s->buffer, STREAM_SIZE);
204 :
- 205 605464 : if (ret < 0) {
+ 205 605512 : if (ret < 0) {
206 : /* LCOV_EXCL_START */
207 : s->state = STREAM_STATE_ERROR;
208 : return EOF;
209 : /* LCOV_EXCL_STOP */
210 : }
- 211 605464 : if (ret == 0) {
+ 211 605512 : if (ret == 0) {
212 1522 : s->state = STREAM_STATE_EOF;
213 1522 : return EOF;
214 : }
215 :
216 : /* update the crc */
- 217 603942 : s->crc_uncached = s->crc;
- 218 603942 : s->crc = crc32c(s->crc, s->buffer, ret);
+ 217 603990 : s->crc_uncached = s->crc;
+ 218 603990 : s->crc = crc32c(s->crc, s->buffer, ret);
219 :
220 : /* update the offset */
- 221 603942 : s->offset_uncached = s->offset;
- 222 603942 : s->offset += ret;
+ 221 603990 : s->offset_uncached = s->offset;
+ 222 603990 : s->offset += ret;
223 :
- 224 603942 : s->pos = s->buffer;
- 225 603942 : s->end = s->buffer + ret;
+ 224 603990 : s->pos = s->buffer;
+ 225 603990 : s->end = s->buffer + ret;
226 :
- 227 603942 : return 0;
+ 227 603990 : return 0;
228 : }
229 :
230 1042 : int sdeplete(STREAM* s, unsigned char* last)
@@ -299,19 +299,19 @@
237 :
238 : while (1) {
239 : /* increase the position up to 4 bytes before the end */
- 240 307868 : if (s->pos + 4 <= s->end)
- 241 148091 : s->pos = s->end - 4;
+ 240 307911 : if (s->pos + 4 <= s->end)
+ 241 148134 : s->pos = s->end - 4;
242 :
243 : /* insert the last 4 bytes */
- 244 1467868 : while (s->pos < s->end) {
- 245 852132 : last[0] = last[1];
- 246 852132 : last[1] = last[2];
- 247 852132 : last[2] = last[3];
- 248 852132 : last[3] = *s->pos++;
+ 244 1468126 : while (s->pos < s->end) {
+ 245 852304 : last[0] = last[1];
+ 246 852304 : last[1] = last[2];
+ 247 852304 : last[2] = last[3];
+ 248 852304 : last[3] = *s->pos++;
249 : }
250 :
251 : /* fill again the buffer until the end of the file */
- 252 307868 : if (sfill(s) != 0) {
+ 252 307911 : if (sfill(s) != 0) {
253 : /* on error fail */
254 1042 : if (serror(s)) {
255 : /* LCOV_EXCL_START */
@@ -322,31 +322,31 @@
260 : /* on EOF terminate */
261 1042 : break;
262 : }
- 263 306826 : }
+ 263 306869 : }
264 :
265 1042 : return 0;
266 : }
267 :
- 268 52551 : int sflush(STREAM* s)
+ 268 52590 : int sflush(STREAM* s)
269 : {
270 : ssize_t ret;
271 : ssize_t size;
272 : unsigned i;
273 :
- 274 52551 : if (s->state != STREAM_STATE_WRITE) {
+ 274 52590 : if (s->state != STREAM_STATE_WRITE) {
275 : /* LCOV_EXCL_START */
276 : return EOF;
277 : /* LCOV_EXCL_STOP */
278 : }
279 :
- 280 52551 : size = s->pos - s->buffer;
- 281 52551 : if (!size)
- 282 913 : return 0;
+ 280 52590 : size = s->pos - s->buffer;
+ 281 52590 : if (!size)
+ 282 909 : return 0;
283 :
- 284 359365 : for (i = 0; i < s->handle_size; ++i) {
- 285 307726 : ret = write(s->handle[i].f, s->buffer, size);
+ 284 359449 : for (i = 0; i < s->handle_size; ++i) {
+ 285 307768 : ret = write(s->handle[i].f, s->buffer, size);
286 :
- 287 307727 : if (ret != size) {
+ 287 307768 : if (ret != size) {
288 : /* LCOV_EXCL_START */
289 : s->state = STREAM_STATE_ERROR;
290 : s->state_index = i;
@@ -362,16 +362,16 @@
300 : * to be able to detect memory errors on the buffer,
301 : * happening during the write.
302 : */
- 303 51639 : s->crc = crc32c(s->crc, s->buffer, size);
- 304 51639 : s->crc_uncached = s->crc;
+ 303 51681 : s->crc = crc32c(s->crc, s->buffer, size);
+ 304 51680 : s->crc_uncached = s->crc;
305 :
306 : /* update the offset */
- 307 51639 : s->offset += size;
- 308 51639 : s->offset_uncached = s->offset;
+ 307 51680 : s->offset += size;
+ 308 51680 : s->offset_uncached = s->offset;
309 :
- 310 51639 : s->pos = s->buffer;
+ 310 51680 : s->pos = s->buffer;
311 :
- 312 51639 : return 0;
+ 312 51680 : return 0;
313 : }
314 :
315 1 : int64_t stell(STREAM* s)
@@ -389,12 +389,12 @@
327 929 : return s->crc_stream ^ CRC_IV;
328 : }
329 :
- 330 298580 : int sgetc_uncached(STREAM* s)
+ 330 298585 : int sgetc_uncached(STREAM* s)
331 : {
332 : /* if at the end of the buffer, fill it */
- 333 298580 : if (s->pos == s->end && sfill(s) != 0)
+ 333 298585 : if (s->pos == s->end && sfill(s) != 0)
334 1464 : return EOF;
- 335 297116 : return *s->pos++;
+ 335 297121 : return *s->pos++;
336 : }
337 :
338 7623 : int sgettok(STREAM* f, char* str, int size)
@@ -434,35 +434,35 @@
372 7623 : return i - str;
373 : }
374 :
- 375 12343180 : int sread(STREAM* f, void* void_data, unsigned size)
+ 375 12342909 : int sread(STREAM* f, void* void_data, unsigned size)
376 : {
- 377 12343180 : unsigned char* data = void_data;
+ 377 12342909 : unsigned char* data = void_data;
378 :
379 : /* if there is enough space in memory */
- 380 12343180 : if (sptrlookup(f, size)) {
+ 380 12342909 : if (sptrlookup(f, size)) {
381 : /* optimized version with all the data in memory */
- 382 12317138 : unsigned char* pos = sptrget(f);
+ 382 12316849 : unsigned char* pos = sptrget(f);
383 :
384 : /* copy it */
- 385 209705167 : while (size--)
- 386 185070891 : *data++ = *pos++;
+ 385 209697747 : while (size--)
+ 386 185064049 : *data++ = *pos++;
387 :
- 388 12317138 : sptrset(f, pos);
+ 388 12316849 : sptrset(f, pos);
389 : } else {
390 : /* standard version using sgetc() */
- 391 1373473 : while (size--) {
- 392 1321389 : int c = sgetc(f);
- 393 1321389 : if (c == EOF) {
+ 391 1373859 : while (size--) {
+ 392 1321739 : int c = sgetc(f);
+ 393 1321739 : if (c == EOF) {
394 : /* LCOV_EXCL_START */
395 : return -1;
396 : /* LCOV_EXCL_STOP */
397 : }
398 :
- 399 1321389 : *data++ = c;
+ 399 1321739 : *data++ = c;
400 : }
401 : }
402 :
- 403 12343180 : return 0;
+ 403 12342909 : return 0;
404 : }
405 :
406 5069 : int sgetline(STREAM* f, char* str, int size)
@@ -575,76 +575,76 @@
513 : }
514 : }
515 :
- 516 18698507 : int sgetb32(STREAM* f, uint32_t* value)
+ 516 18710390 : int sgetb32(STREAM* f, uint32_t* value)
517 : {
518 : uint32_t v;
519 : unsigned char b;
520 : unsigned char s;
521 : int c;
522 :
- 523 18698507 : v = 0;
- 524 18698507 : s = 0;
+ 523 18710390 : v = 0;
+ 524 18710390 : s = 0;
525 : loop:
- 526 35035464 : c = sgetc(f);
- 527 35035464 : if (c == EOF) {
+ 526 35314985 : c = sgetc(f);
+ 527 35314985 : if (c == EOF) {
528 : /* LCOV_EXCL_START */
529 : return -1;
530 : /* LCOV_EXCL_STOP */
531 : }
532 :
- 533 35035464 : b = (unsigned char)c;
- 534 35035464 : if ((b & 0x80) == 0) {
- 535 16336957 : v |= (uint32_t)b << s;
- 536 16336957 : s += 7;
- 537 16336957 : if (s >= 32) {
+ 533 35314985 : b = (unsigned char)c;
+ 534 35314985 : if ((b & 0x80) == 0) {
+ 535 16604595 : v |= (uint32_t)b << s;
+ 536 16604595 : s += 7;
+ 537 16604595 : if (s >= 32) {
538 : /* LCOV_EXCL_START */
539 : return -1;
540 : /* LCOV_EXCL_STOP */
541 : }
- 542 16336957 : goto loop;
+ 542 16604595 : goto loop;
543 : }
544 :
- 545 18698507 : v |= (uint32_t)(b & 0x7f) << s;
+ 545 18710390 : v |= (uint32_t)(b & 0x7f) << s;
546 :
- 547 18698507 : *value = v;
+ 547 18710390 : *value = v;
548 :
- 549 18698507 : return 0;
+ 549 18710390 : return 0;
550 : }
551 :
- 552 10465700 : int sgetb64(STREAM* f, uint64_t* value)
+ 552 10465937 : int sgetb64(STREAM* f, uint64_t* value)
553 : {
554 : uint64_t v;
555 : unsigned char b;
556 : unsigned char s;
557 : int c;
558 :
- 559 10465700 : v = 0;
- 560 10465700 : s = 0;
+ 559 10465937 : v = 0;
+ 560 10465937 : s = 0;
561 : loop:
- 562 38270922 : c = sgetc(f);
- 563 38270922 : if (c == EOF) {
+ 562 38271575 : c = sgetc(f);
+ 563 38271575 : if (c == EOF) {
564 : /* LCOV_EXCL_START */
565 : return -1;
566 : /* LCOV_EXCL_STOP */
567 : }
568 :
- 569 38270922 : b = (unsigned char)c;
- 570 38270922 : if ((b & 0x80) == 0) {
- 571 27805222 : v |= (uint64_t)b << s;
- 572 27805222 : s += 7;
- 573 27805222 : if (s >= 64) {
+ 569 38271575 : b = (unsigned char)c;
+ 570 38271575 : if ((b & 0x80) == 0) {
+ 571 27805638 : v |= (uint64_t)b << s;
+ 572 27805638 : s += 7;
+ 573 27805638 : if (s >= 64) {
574 : /* LCOV_EXCL_START */
575 : return -1;
576 : /* LCOV_EXCL_STOP */
577 : }
- 578 27805222 : goto loop;
+ 578 27805638 : goto loop;
579 : }
580 :
- 581 10465700 : v |= (uint64_t)(b & 0x7f) << s;
+ 581 10465937 : v |= (uint64_t)(b & 0x7f) << s;
582 :
- 583 10465700 : *value = v;
+ 583 10465937 : *value = v;
584 :
- 585 10465700 : return 0;
+ 585 10465937 : return 0;
586 : }
587 :
588 362 : int sgetble32(STREAM* f, uint32_t* value)
@@ -662,35 +662,35 @@
600 362 : return 0;
601 : }
602 :
- 603 3732711 : int sgetbs(STREAM* f, char* str, int size)
+ 603 3732790 : int sgetbs(STREAM* f, char* str, int size)
604 : {
605 : uint32_t len;
606 :
- 607 3732711 : if (sgetb32(f, &len) < 0) {
+ 607 3732790 : if (sgetb32(f, &len) < 0) {
608 : /* LCOV_EXCL_START */
609 : return -1;
610 : /* LCOV_EXCL_STOP */
611 : }
612 :
- 613 3732711 : if (len + 1 > (uint32_t)size) {
+ 613 3732790 : if (len + 1 > (uint32_t)size) {
614 : /* LCOV_EXCL_START */
615 : return -1;
616 : /* LCOV_EXCL_STOP */
617 : }
618 :
- 619 3732711 : str[len] = 0;
+ 619 3732790 : str[len] = 0;
620 :
- 621 3732711 : return sread(f, str, (int)len);
+ 621 3732790 : return sread(f, str, (int)len);
622 : }
623 :
- 624 130046569 : int swrite(const void* void_data, unsigned size, STREAM* f)
+ 624 129597634 : int swrite(const void* void_data, unsigned size, STREAM* f)
625 : {
- 626 130046569 : const unsigned char* data = void_data;
+ 626 129597634 : const unsigned char* data = void_data;
627 :
628 : /* if there is enough space in memory */
- 629 130046569 : if (sptrlookup(f, size)) {
+ 629 129597634 : if (sptrlookup(f, size)) {
630 : /* optimized version with all the data in memory */
- 631 127834006 : unsigned char* pos = sptrget(f);
+ 631 128366511 : unsigned char* pos = sptrget(f);
632 :
633 : /**
634 : * Update the crc *before* writing the data in the buffer
@@ -699,17 +699,17 @@
637 : * to be able to detect memory errors on the buffer,
638 : * happening before we write it on the file.
639 : */
- 640 129791160 : f->crc_stream = crc32c_plain(f->crc_stream, data, size);
+ 640 127220529 : f->crc_stream = crc32c_plain(f->crc_stream, data, size);
641 :
642 : /* copy it */
- 643 1011408978 : while (size--)
- 644 752691158 : *pos++ = *data++;
+ 643 984312399 : while (size--)
+ 644 729779043 : *pos++ = *data++;
645 :
- 646 129358910 : sptrset(f, pos);
+ 646 127266678 : sptrset(f, pos);
647 : } else {
648 : /* standard version using sputc() */
- 649 355086 : while (size--) {
- 650 321067 : if (sputc(*data++, f) != 0) {
+ 649 352837 : while (size--) {
+ 650 318158 : if (sputc(*data++, f) != 0) {
651 : /* LCOV_EXCL_START */
652 : return -1;
653 : /* LCOV_EXCL_STOP */
@@ -717,49 +717,49 @@
655 : }
656 : }
657 :
- 658 131892349 : return 0;
+ 658 129224881 : return 0;
659 : }
660 :
- 661 62124806 : int sputb32(uint32_t value, STREAM* s)
+ 661 62339359 : int sputb32(uint32_t value, STREAM* s)
662 : {
663 : unsigned char b;
664 : unsigned char buf[16];
665 : unsigned i;
666 :
- 667 62124806 : i = 0;
+ 667 62339359 : i = 0;
668 : loop:
- 669 115908253 : b = value & 0x7f;
- 670 115908253 : value >>= 7;
+ 669 117525500 : b = value & 0x7f;
+ 670 117525500 : value >>= 7;
671 :
- 672 115908253 : if (value) {
- 673 53783447 : buf[i++] = b;
- 674 53783447 : goto loop;
+ 672 117525500 : if (value) {
+ 673 55186141 : buf[i++] = b;
+ 674 55186141 : goto loop;
675 : }
676 :
- 677 62124806 : buf[i++] = b | 0x80;
+ 677 62339359 : buf[i++] = b | 0x80;
678 :
- 679 62124806 : return swrite(buf, i, s);
+ 679 62339359 : return swrite(buf, i, s);
680 : }
681 :
- 682 34119322 : int sputb64(uint64_t value, STREAM* s)
+ 682 34173479 : int sputb64(uint64_t value, STREAM* s)
683 : {
684 : unsigned char b;
685 : unsigned char buf[16];
686 : unsigned i;
687 :
- 688 34119322 : i = 0;
+ 688 34173479 : i = 0;
689 : loop:
- 690 124052999 : b = value & 0x7f;
- 691 124052999 : value >>= 7;
+ 690 124705929 : b = value & 0x7f;
+ 691 124705929 : value >>= 7;
692 :
- 693 124052999 : if (value) {
- 694 89933677 : buf[i++] = b;
- 695 89933677 : goto loop;
+ 693 124705929 : if (value) {
+ 694 90532450 : buf[i++] = b;
+ 695 90532450 : goto loop;
696 : }
697 :
- 698 34119322 : buf[i++] = b | 0x80;
+ 698 34173479 : buf[i++] = b | 0x80;
699 :
- 700 34119322 : return swrite(buf, i, s);
+ 700 34173479 : return swrite(buf, i, s);
701 : }
702 :
703 929 : int sputble32(uint32_t value, STREAM* s)
@@ -774,25 +774,25 @@
712 929 : return swrite(buf, 4, s);
713 : }
714 :
- 715 12250827 : int sputbs(const char* str, STREAM* f)
+ 715 12306366 : int sputbs(const char* str, STREAM* f)
716 : {
- 717 12250827 : size_t len = strlen(str);
+ 717 12306366 : size_t len = strlen(str);
718 :
- 719 12250827 : if (sputb32(len, f) != 0) {
+ 719 12306366 : if (sputb32(len, f) != 0) {
720 : /* LCOV_EXCL_START */
721 : return -1;
722 : /* LCOV_EXCL_STOP */
723 : }
724 :
- 725 12311369 : return swrite(str, len, f);
+ 725 12287997 : return swrite(str, len, f);
726 : }
727 :
728 : #if HAVE_FSYNC
- 729 913 : int ssync(STREAM* s)
+ 729 912 : int ssync(STREAM* s)
730 : {
731 : unsigned i;
732 :
- 733 1826 : for (i = 0; i < s->handle_size; ++i) {
+ 733 1824 : for (i = 0; i < s->handle_size; ++i) {
734 913 : if (fsync(s->handle[i].f) != 0) {
735 : /* LCOV_EXCL_START */
736 : s->state = STREAM_STATE_ERROR;
@@ -802,7 +802,7 @@
740 : }
741 : }
742 :
- 743 913 : return 0;
+ 743 911 : return 0;
744 : }
745 : #endif
746 :
diff --git a/cov/cmdline/stream.h.func-sort-c.html b/cov/cmdline/stream.h.func-sort-c.html
index 3ba676b2..6fd4d017 100644
--- a/cov/cmdline/stream.h.func-sort-c.html
+++ b/cov/cmdline/stream.h.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -60,28 +60,28 @@
Hit count  |
- | sptrget |
- 143442663 |
+ sptrlookup |
+ 140471390 |
- | sptrlookup |
- 140856705 |
+ sptrget |
+ 140020205 |
| sptrset |
- 139615572 |
+ 138951723 |
| sgetc |
- 81925866 |
+ 82206359 |
| serror |
- 24801447 |
+ 24784868 |
| sputc |
- 23657932 |
+ 23611223 |
| sungetc |
diff --git a/cov/cmdline/stream.h.func.html b/cov/cmdline/stream.h.func.html
index 09494c2a..50565355 100644
--- a/cov/cmdline/stream.h.func.html
+++ b/cov/cmdline/stream.h.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -65,7 +65,7 @@
| serror |
- 24801447 |
+ 24784868 |
| serrorfile |
@@ -73,7 +73,7 @@
| sgetc |
- 81925866 |
+ 82206359 |
| sgeteol |
@@ -85,19 +85,19 @@
| sptrget |
- 143442663 |
+ 140020205 |
| sptrlookup |
- 140856705 |
+ 140471390 |
| sptrset |
- 139615572 |
+ 138951723 |
| sputc |
- 23657932 |
+ 23611223 |
| sungetc |
diff --git a/cov/cmdline/stream.h.gcov.html b/cov/cmdline/stream.h.gcov.html
index 3809d597..04b9f268 100644
--- a/cov/cmdline/stream.h.gcov.html
+++ b/cov/cmdline/stream.h.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -221,33 +221,33 @@
159 : /**
160 : * Check if the buffer has enough data loaded.
161 : */
- 162 140856705 : static inline int sptrlookup(STREAM* s, int size)
+ 162 140471390 : static inline int sptrlookup(STREAM* s, int size)
163 : {
- 164 140856705 : return s->pos + size <= s->end;
+ 164 140471390 : return s->pos + size <= s->end;
165 : }
166 :
167 : /**
168 : * Get the current stream ptr.
169 : */
- 170 143442663 : static inline unsigned char* sptrget(STREAM* s)
+ 170 140020205 : static inline unsigned char* sptrget(STREAM* s)
171 : {
- 172 143442663 : return s->pos;
+ 172 140020205 : return s->pos;
173 : }
174 :
175 : /**
176 : * Set the current stream ptr.
177 : */
- 178 139615572 : static inline void sptrset(STREAM* s, unsigned char* ptr)
+ 178 138951723 : static inline void sptrset(STREAM* s, unsigned char* ptr)
179 : {
- 180 139615572 : s->pos = ptr;
- 181 139615572 : }
+ 180 138951723 : s->pos = ptr;
+ 181 138951723 : }
182 :
183 : /**
184 : * Check the error status. Like ferror().
185 : */
- 186 24801447 : static inline int serror(STREAM* s)
+ 186 24784868 : static inline int serror(STREAM* s)
187 : {
- 188 24801447 : return s->state == STREAM_STATE_ERROR;
+ 188 24784868 : return s->state == STREAM_STATE_ERROR;
189 : }
190 :
191 : /**
@@ -291,11 +291,11 @@
229 : /**
230 : * Read a char. Like fgetc().
231 : */
- 232 81925866 : static inline int sgetc(STREAM* s)
+ 232 82206359 : static inline int sgetc(STREAM* s)
233 : {
- 234 81925866 : if (tommy_unlikely(s->pos == s->end))
- 235 298580 : return sgetc_uncached(s);
- 236 81627286 : return *s->pos++;
+ 234 82206359 : if (tommy_unlikely(s->pos == s->end))
+ 235 298585 : return sgetc_uncached(s);
+ 236 81907774 : return *s->pos++;
237 : }
238 :
239 : /**
@@ -407,10 +407,10 @@
345 : * Write a char. Like fputc().
346 : * Return 0 on success or -1 on error.
347 : */
- 348 23657932 : static inline int sputc(int c, STREAM* s)
+ 348 23611223 : static inline int sputc(int c, STREAM* s)
349 : {
- 350 23657932 : if (s->pos == s->end) {
- 351 49796 : if (sflush(s) != 0)
+ 350 23611223 : if (s->pos == s->end) {
+ 351 49838 : if (sflush(s) != 0)
352 0 : return -1;
353 : }
354 :
@@ -421,11 +421,11 @@
359 : * to be able to detect memory errors on the buffer,
360 : * happening before we write it on the file.
361 : */
- 362 23657933 : s->crc_stream = crc32c_plain_char(s->crc_stream, c);
+ 362 23611224 : s->crc_stream = crc32c_plain_char(s->crc_stream, c);
363 :
- 364 23816691 : *s->pos++ = c;
+ 364 23809904 : *s->pos++ = c;
365 :
- 366 23816691 : return 0;
+ 366 23809904 : return 0;
367 : }
368 :
369 : /**
diff --git a/cov/cmdline/support.c.func-sort-c.html b/cov/cmdline/support.c.func-sort-c.html
index 5f799715..e77ef92a 100644
--- a/cov/cmdline/support.c.func-sort-c.html
+++ b/cov/cmdline/support.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,55 +61,55 @@
| pathcmp |
- 50334016 |
+ 50336221 |
| pathprint |
- 50027975 |
+ 50030363 |
| malloc_nofail |
- 13871380 |
+ 13871886 |
| pathcpy |
- 6858280 |
+ 6858601 |
| strdup_nofail |
- 5662644 |
+ 5663011 |
| log_tag |
- 4043608 |
+ 4041705 |
| esc |
- 3594259 |
+ 3592843 |
| mkancestor |
- 793004 |
+ 792978 |
| log_error |
- 614821 |
+ 614592 |
| msg_info |
- 296170 |
+ 295863 |
| msg_verbose |
- 127078 |
+ 126936 |
| fmtime |
- 118002 |
+ 117937 |
| pathexport |
- 17567 |
+ 17569 |
| log_expected |
@@ -137,7 +137,7 @@
| msg_bar |
- 954 |
+ 952 |
| log_fatal |
@@ -149,7 +149,7 @@
| msg_status |
- 568 |
+ 569 |
| malloc_counter |
diff --git a/cov/cmdline/support.c.func.html b/cov/cmdline/support.c.func.html
index efa7b572..65c60503 100644
--- a/cov/cmdline/support.c.func.html
+++ b/cov/cmdline/support.c.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -65,15 +65,15 @@
| esc |
- 3594259 |
+ 3592843 |
| fmtime |
- 118002 |
+ 117937 |
| log_error |
- 614821 |
+ 614592 |
| log_expected |
@@ -89,7 +89,7 @@
| log_tag |
- 4043608 |
+ 4041705 |
| malloc_counter |
@@ -97,15 +97,15 @@
| malloc_nofail |
- 13871380 |
+ 13871886 |
| mkancestor |
- 793004 |
+ 792978 |
| msg_bar |
- 954 |
+ 952 |
| msg_flush |
@@ -113,7 +113,7 @@
| msg_info |
- 296170 |
+ 295863 |
| msg_progress |
@@ -121,11 +121,11 @@
| msg_status |
- 568 |
+ 569 |
| msg_verbose |
- 127078 |
+ 126936 |
| pathcat |
@@ -137,11 +137,11 @@
| pathcmp |
- 50334016 |
+ 50336221 |
| pathcpy |
- 6858280 |
+ 6858601 |
| pathcut |
@@ -149,7 +149,7 @@
| pathexport |
- 17567 |
+ 17569 |
| pathimport |
@@ -157,7 +157,7 @@
| pathprint |
- 50027975 |
+ 50030363 |
| pathslash |
@@ -181,7 +181,7 @@
| strdup_nofail |
- 5662644 |
+ 5663011 |
diff --git a/cov/cmdline/support.c.gcov.html b/cov/cmdline/support.c.gcov.html
index c725286a..07fccc29 100644
--- a/cov/cmdline/support.c.gcov.html
+++ b/cov/cmdline/support.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -138,27 +138,27 @@
76 804 : pthread_mutex_unlock(&msg_lock);
77 804 : }
78 :
- 79 614821 : void log_error(const char* format, ...)
+ 79 614592 : void log_error(const char* format, ...)
80 : {
81 : va_list ap;
82 :
- 83 614821 : pthread_mutex_lock(&msg_lock);
+ 83 614592 : pthread_mutex_lock(&msg_lock);
84 :
- 85 614821 : if (stdlog) {
- 86 612910 : va_start(ap, format);
- 87 612910 : fprintf(stdlog, "msg:error: ");
- 88 612910 : vfprintf(stdlog, format, ap);
- 89 612910 : fflush(stdlog);
- 90 612910 : va_end(ap);
+ 85 614592 : if (stdlog) {
+ 86 612682 : va_start(ap, format);
+ 87 612682 : fprintf(stdlog, "msg:error: ");
+ 88 612682 : vfprintf(stdlog, format, ap);
+ 89 612682 : fflush(stdlog);
+ 90 612682 : va_end(ap);
91 : } else {
- 92 1911 : va_start(ap, format);
- 93 1911 : vfprintf(stderr, format, ap);
- 94 1911 : fflush(stderr);
- 95 1911 : va_end(ap);
+ 92 1910 : va_start(ap, format);
+ 93 1910 : vfprintf(stderr, format, ap);
+ 94 1910 : fflush(stderr);
+ 95 1910 : va_end(ap);
96 : }
97 :
- 98 614821 : pthread_mutex_unlock(&msg_lock);
- 99 614821 : }
+ 98 614592 : pthread_mutex_unlock(&msg_lock);
+ 99 614592 : }
100 :
101 11751 : void log_expected(const char* format, ...)
102 : {
@@ -177,22 +177,22 @@
115 11751 : pthread_mutex_unlock(&msg_lock);
116 11751 : }
117 :
- 118 4043608 : void log_tag(const char* format, ...)
+ 118 4041705 : void log_tag(const char* format, ...)
119 : {
120 : va_list ap;
121 :
- 122 4043608 : pthread_mutex_lock(&msg_lock);
+ 122 4041705 : pthread_mutex_lock(&msg_lock);
123 :
- 124 4043608 : if (stdlog) {
- 125 2964603 : va_start(ap, format);
- 126 2964603 : vfprintf(stdlog, format, ap);
+ 124 4041705 : if (stdlog) {
+ 125 2962677 : va_start(ap, format);
+ 126 2962677 : vfprintf(stdlog, format, ap);
127 : /* here we intentionally don't flush */
128 : /* to make the output faster */
- 129 2964603 : va_end(ap);
+ 129 2962677 : va_end(ap);
130 : }
131 :
- 132 4043608 : pthread_mutex_unlock(&msg_lock);
- 133 4043608 : }
+ 132 4041705 : pthread_mutex_unlock(&msg_lock);
+ 133 4041705 : }
134 :
135 1108 : void log_flush(void)
136 : {
@@ -206,11 +206,11 @@
144 1108 : pthread_mutex_unlock(&msg_lock);
145 1108 : }
146 :
- 147 568 : void msg_status(const char* format, ...)
+ 147 569 : void msg_status(const char* format, ...)
148 : {
149 : va_list ap;
150 :
- 151 568 : pthread_mutex_lock(&msg_lock);
+ 151 569 : pthread_mutex_lock(&msg_lock);
152 :
153 569 : if (stdlog) {
154 276 : va_start(ap, format);
@@ -230,24 +230,24 @@
168 569 : pthread_mutex_unlock(&msg_lock);
169 569 : }
170 :
- 171 296170 : void msg_info(const char* format, ...)
+ 171 295863 : void msg_info(const char* format, ...)
172 : {
173 : va_list ap;
174 :
- 175 296170 : pthread_mutex_lock(&msg_lock);
+ 175 295863 : pthread_mutex_lock(&msg_lock);
176 :
177 : /* don't output in stdlog as these messages */
178 : /* are always paired with a msg_tag() call */
179 :
- 180 296170 : if (msg_level >= MSG_INFO) {
- 181 28833 : va_start(ap, format);
- 182 28833 : vfprintf(stdout, format, ap);
- 183 28833 : fflush(stdout);
- 184 28833 : va_end(ap);
+ 180 295863 : if (msg_level >= MSG_INFO) {
+ 181 28776 : va_start(ap, format);
+ 182 28776 : vfprintf(stdout, format, ap);
+ 183 28776 : fflush(stdout);
+ 184 28776 : va_end(ap);
185 : }
186 :
- 187 296170 : pthread_mutex_unlock(&msg_lock);
- 188 296170 : }
+ 187 295863 : pthread_mutex_unlock(&msg_lock);
+ 188 295863 : }
189 :
190 3911 : void msg_progress(const char* format, ...)
191 : {
@@ -273,48 +273,48 @@
211 3911 : pthread_mutex_unlock(&msg_lock);
212 3911 : }
213 :
- 214 954 : void msg_bar(const char* format, ...)
+ 214 952 : void msg_bar(const char* format, ...)
215 : {
216 : va_list ap;
217 :
- 218 954 : pthread_mutex_lock(&msg_lock);
+ 218 952 : pthread_mutex_lock(&msg_lock);
219 :
220 : /* don't output in stdlog as these messages */
221 : /* are intended for screen only */
222 : /* also don't flush stdout as they are intended to be partial messages */
223 :
- 224 954 : if (msg_level >= MSG_BAR) {
+ 224 952 : if (msg_level >= MSG_BAR) {
225 0 : va_start(ap, format);
226 0 : vfprintf(stdout, format, ap);
227 0 : va_end(ap);
228 : }
229 :
- 230 954 : pthread_mutex_unlock(&msg_lock);
- 231 954 : }
+ 230 952 : pthread_mutex_unlock(&msg_lock);
+ 231 952 : }
232 :
- 233 127078 : void msg_verbose(const char* format, ...)
+ 233 126936 : void msg_verbose(const char* format, ...)
234 : {
235 : va_list ap;
236 :
- 237 127078 : pthread_mutex_lock(&msg_lock);
+ 237 126936 : pthread_mutex_lock(&msg_lock);
238 :
- 239 127078 : if (stdlog) {
- 240 125434 : va_start(ap, format);
- 241 125434 : fprintf(stdlog, "msg:verbose: ");
- 242 125434 : vfprintf(stdlog, format, ap);
- 243 125434 : fflush(stdlog);
- 244 125434 : va_end(ap);
+ 239 126936 : if (stdlog) {
+ 240 125292 : va_start(ap, format);
+ 241 125292 : fprintf(stdlog, "msg:verbose: ");
+ 242 125292 : vfprintf(stdlog, format, ap);
+ 243 125292 : fflush(stdlog);
+ 244 125292 : va_end(ap);
245 : }
246 :
- 247 127078 : if (msg_level >= MSG_VERBOSE) {
+ 247 126936 : if (msg_level >= MSG_VERBOSE) {
248 79 : va_start(ap, format);
249 79 : vfprintf(stdout, format, ap);
250 79 : fflush(stdout);
251 79 : va_end(ap);
252 : }
253 :
- 254 127078 : pthread_mutex_unlock(&msg_lock);
- 255 127078 : }
+ 254 126936 : pthread_mutex_unlock(&msg_lock);
+ 255 126936 : }
256 :
257 440 : void msg_flush(void)
258 : {
@@ -351,20 +351,20 @@
289 : *p++ = to; \
290 : break
291 :
- 292 3594259 : const char* esc(const char* str)
+ 292 3592843 : const char* esc(const char* str)
293 : {
- 294 3594259 : char* begin = esc_table[esc_index];
- 295 3594259 : char* end = begin + PATH_MAX;
- 296 3594259 : char* p = begin;
+ 294 3592843 : char* begin = esc_table[esc_index];
+ 295 3592843 : char* end = begin + PATH_MAX;
+ 296 3592843 : char* p = begin;
297 :
298 : /* next call uses the next buffer */
- 299 3594259 : esc_index = (esc_index + 1) % ESC_MAX;
+ 299 3592843 : esc_index = (esc_index + 1) % ESC_MAX;
300 :
301 : /* copy string with escaping */
- 302 53734097 : while (*str) {
- 303 46545579 : char c = *str;
+ 302 53695808 : while (*str) {
+ 303 46510122 : char c = *str;
304 :
- 305 46545579 : switch (c) {
+ 305 46510122 : switch (c) {
306 :
307 0 : ESCAPE('\n', 'n');
308 0 : ESCAPE('\r', 'r');
@@ -372,21 +372,21 @@
310 0 : ESCAPE('\\', '\\');
311 :
312 : default:
- 313 46545579 : if (p == end)
+ 313 46510122 : if (p == end)
314 0 : goto bail;
- 315 46545579 : *p++ = c;
- 316 46545579 : break;
+ 315 46510122 : *p++ = c;
+ 316 46510122 : break;
317 : }
318 :
- 319 46545579 : ++str;
+ 319 46510122 : ++str;
320 : }
321 :
322 : /* put final 0 */
- 323 3594259 : if (p == end)
+ 323 3592843 : if (p == end)
324 0 : goto bail;
- 325 3594259 : *p = 0;
+ 325 3592843 : *p = 0;
326 :
- 327 7188518 : return begin;
+ 327 7185686 : return begin;
328 :
329 : bail:
330 : /* LCOV_EXCL_START */
@@ -411,19 +411,19 @@
349 : /****************************************************************************/
350 : /* path */
351 :
- 352 6858280 : void pathcpy(char* dst, size_t size, const char* src)
+ 352 6858601 : void pathcpy(char* dst, size_t size, const char* src)
353 : {
- 354 6858280 : size_t len = strlen(src);
+ 354 6858601 : size_t len = strlen(src);
355 :
- 356 6858280 : if (len + 1 > size) {
+ 356 6858601 : if (len + 1 > size) {
357 : /* LCOV_EXCL_START */
358 : log_fatal("Path too long\n");
359 : exit(EXIT_FAILURE);
360 : /* LCOV_EXCL_STOP */
361 : }
362 :
- 363 6858280 : memcpy(dst, src, len + 1);
- 364 6858280 : }
+ 363 6858601 : memcpy(dst, src, len + 1);
+ 364 6858601 : }
365 :
366 248 : void pathcat(char* dst, size_t size, const char* src)
367 : {
@@ -469,9 +469,9 @@
407 : #endif
408 8852 : }
409 :
- 410 17567 : void pathexport(char* dst, size_t size, const char* src)
+ 410 17569 : void pathexport(char* dst, size_t size, const char* src)
411 : {
- 412 17567 : pathcpy(dst, size, src);
+ 412 17569 : pathcpy(dst, size, src);
413 :
414 : #ifdef _WIN32
415 : /* convert all C '/' to Windows '\' */
@@ -481,24 +481,24 @@
419 : ++dst;
420 : }
421 : #endif
- 422 17567 : }
+ 422 17569 : }
423 :
- 424 50027975 : void pathprint(char* dst, size_t size, const char* format, ...)
+ 424 50030363 : void pathprint(char* dst, size_t size, const char* format, ...)
425 : {
426 : size_t len;
427 : va_list ap;
428 :
- 429 50027975 : va_start(ap, format);
- 430 50027975 : len = vsnprintf(dst, size, format, ap);
- 431 50027975 : va_end(ap);
+ 429 50030363 : va_start(ap, format);
+ 430 50030363 : len = vsnprintf(dst, size, format, ap);
+ 431 50030363 : va_end(ap);
432 :
- 433 50027975 : if (len >= size) {
+ 433 50030363 : if (len >= size) {
434 : /* LCOV_EXCL_START */
435 : log_fatal("Path too long\n");
436 : exit(EXIT_FAILURE);
437 : /* LCOV_EXCL_STOP */
438 : }
- 439 50027975 : }
+ 439 50030363 : }
440 :
441 7319 : void pathslash(char* dst, size_t size)
442 : {
@@ -526,7 +526,7 @@
464 0 : dst[0] = 0;
465 30 : }
466 :
- 467 50334016 : int pathcmp(const char* a, const char* b)
+ 467 50336221 : int pathcmp(const char* a, const char* b)
468 : {
469 : #ifdef _WIN32
470 : char ai[PATH_MAX];
@@ -539,32 +539,32 @@
477 : /* case insensitive compare in Windows */
478 : return stricmp(ai, bi);
479 : #else
- 480 50334016 : return strcmp(a, b);
+ 480 50336221 : return strcmp(a, b);
481 : #endif
482 : }
483 :
484 : /****************************************************************************/
485 : /* filesystem */
486 :
- 487 793004 : int mkancestor(const char* file)
+ 487 792978 : int mkancestor(const char* file)
488 : {
489 : char dir[PATH_MAX];
490 : struct stat st;
491 : char* c;
492 :
- 493 793004 : pathcpy(dir, sizeof(dir), file);
+ 493 792978 : pathcpy(dir, sizeof(dir), file);
494 :
- 495 793004 : c = strrchr(dir, '/');
- 496 793004 : if (!c) {
+ 495 792978 : c = strrchr(dir, '/');
+ 496 792978 : if (!c) {
497 : /* no ancestor */
498 0 : return 0;
499 : }
500 :
501 : /* clear the file */
- 502 793004 : *c = 0;
+ 502 792978 : *c = 0;
503 :
504 : /* if it's the root dir */
- 505 793004 : if (*dir == 0) {
+ 505 792978 : if (*dir == 0) {
506 : /* nothing more to do */
507 0 : return 0;
508 : }
@@ -587,9 +587,9 @@
525 : * Also in Windows it's better to use lstat() than stat() because it
526 : * doen't need to open the dir with CreateFile().
527 : */
- 528 793004 : if (lstat(dir, &st) == 0) {
+ 528 792978 : if (lstat(dir, &st) == 0) {
529 : /* it already exists */
- 530 792924 : return 0;
+ 530 792898 : return 0;
531 : }
532 :
533 : /* recursively create them all */
@@ -610,7 +610,7 @@
548 80 : return 0;
549 : }
550 :
- 551 118002 : int fmtime(int f, int64_t mtime_sec, int mtime_nsec)
+ 551 117937 : int fmtime(int f, int64_t mtime_sec, int mtime_nsec)
552 : {
553 : #if HAVE_FUTIMENS
554 : struct timespec tv[2];
@@ -620,15 +620,15 @@
558 : int ret;
559 :
560 : #if HAVE_FUTIMENS /* futimens() is preferred because it gives nanosecond precision */
- 561 118002 : tv[0].tv_sec = mtime_sec;
- 562 118002 : if (mtime_nsec != STAT_NSEC_INVALID)
- 563 118002 : tv[0].tv_nsec = mtime_nsec;
+ 561 117937 : tv[0].tv_sec = mtime_sec;
+ 562 117937 : if (mtime_nsec != STAT_NSEC_INVALID)
+ 563 117937 : tv[0].tv_nsec = mtime_nsec;
564 : else
565 0 : tv[0].tv_nsec = 0;
- 566 118002 : tv[1].tv_sec = tv[0].tv_sec;
- 567 118002 : tv[1].tv_nsec = tv[0].tv_nsec;
+ 566 117937 : tv[1].tv_sec = tv[0].tv_sec;
+ 567 117937 : tv[1].tv_nsec = tv[0].tv_nsec;
568 :
- 569 118002 : ret = futimens(f, tv);
+ 569 117937 : ret = futimens(f, tv);
570 : #elif HAVE_FUTIMES /* fallback to futimes() if nanosecond precision is not available */
571 : tv[0].tv_sec = mtime_sec;
572 : if (mtime_nsec != STAT_NSEC_INVALID)
@@ -653,7 +653,7 @@
591 : #error No function available to set file timestamps with sub-second precision
592 : #endif
593 :
- 594 118002 : return ret;
+ 594 117937 : return ret;
595 : }
596 :
597 : /****************************************************************************/
@@ -718,11 +718,11 @@
656 : }
657 : /* LCOV_EXCL_STOP */
658 :
- 659 13871380 : void* malloc_nofail(size_t size)
+ 659 13871886 : void* malloc_nofail(size_t size)
660 : {
- 661 13871380 : void* ptr = malloc(size);
+ 661 13871886 : void* ptr = malloc(size);
662 :
- 663 13871380 : if (!ptr) {
+ 663 13871886 : if (!ptr) {
664 : /* LCOV_EXCL_START */
665 : malloc_fail(size);
666 : exit(EXIT_FAILURE);
@@ -736,12 +736,12 @@
674 : /* Filling the memory doesn't ensure to disable OOM, but it increase a lot the chances to */
675 : /* get a real error from malloc() instead than a process killed. */
676 : /* Note that calloc() doesn't have the same effect. */
- 677 13871380 : memset(ptr, 0xA5, size);
+ 677 13871886 : memset(ptr, 0xA5, size);
678 : #endif
679 :
- 680 13871380 : mcounter += size;
+ 680 13871886 : mcounter += size;
681 :
- 682 13871380 : return ptr;
+ 682 13871886 : return ptr;
683 : }
684 :
685 9283 : void* calloc_nofail(size_t count, size_t size)
@@ -767,27 +767,27 @@
705 9283 : return ptr;
706 : }
707 :
- 708 5662644 : char* strdup_nofail(const char* str)
+ 708 5663011 : char* strdup_nofail(const char* str)
709 : {
710 : size_t size;
711 : char* ptr;
712 :
- 713 5662644 : size = strlen(str) + 1;
+ 713 5663011 : size = strlen(str) + 1;
714 :
- 715 5662644 : ptr = malloc(size);
+ 715 5663011 : ptr = malloc(size);
716 :
- 717 5662644 : if (!ptr) {
+ 717 5663011 : if (!ptr) {
718 : /* LCOV_EXCL_START */
719 : malloc_fail(size);
720 : exit(EXIT_FAILURE);
721 : /* LCOV_EXCL_STOP */
722 : }
723 :
- 724 5662644 : memcpy(ptr, str, size);
+ 724 5663011 : memcpy(ptr, str, size);
725 :
- 726 5662644 : mcounter += size;
+ 726 5663011 : mcounter += size;
727 :
- 728 5662644 : return ptr;
+ 728 5663011 : return ptr;
729 : }
730 :
731 : /****************************************************************************/
@@ -822,8 +822,8 @@
760 :
761 : /* preclear attribute */
762 25 : *serial = 0;
- 763 6525 : for (i = 0; i < SMART_COUNT; ++i)
- 764 6500 : smart[i] = SMART_UNASSIGNED;
+ 763 6501 : for (i = 0; i < SMART_COUNT; ++i)
+ 764 6476 : smart[i] = SMART_UNASSIGNED;
765 :
766 : /* read the file */
767 25 : inside = 0;
diff --git a/cov/cmdline/sync.c.func-sort-c.html b/cov/cmdline/sync.c.func-sort-c.html
index cd8f26c6..f3bdcd37 100644
--- a/cov/cmdline/sync.c.func-sort-c.html
+++ b/cov/cmdline/sync.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/cmdline/sync.c.func.html b/cov/cmdline/sync.c.func.html
index 21f3a3b8..e5f48fb5 100644
--- a/cov/cmdline/sync.c.func.html
+++ b/cov/cmdline/sync.c.func.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/cmdline/sync.c.gcov.html b/cov/cmdline/sync.c.gcov.html
index 17d69be4..36ec1bda 100644
--- a/cov/cmdline/sync.c.gcov.html
+++ b/cov/cmdline/sync.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -488,14 +488,14 @@
426 4180078 : one_valid = 1;
427 :
428 4389366 : if (block_has_invalid_parity(block))
- 429 360958 : one_invalid = 1;
+ 429 361206 : one_invalid = 1;
430 : }
431 :
432 : /* if none valid or none invalid, we don't need to update */
433 733118 : if (!one_invalid || !one_valid)
- 434 568698 : return 0;
+ 434 568436 : return 0;
435 :
- 436 164420 : return 1;
+ 436 164682 : return 1;
437 : }
438 :
439 68 : static int state_sync_process(struct snapraid_state* state, struct snapraid_parity_handle** parity, block_off_t blockstart, block_off_t blockmax)
@@ -559,8 +559,8 @@
497 68 : countmax = 0;
498 366627 : for (i = blockstart; i < blockmax; ++i) {
499 366559 : if (!block_is_enabled(i, handle, diskmax))
- 500 284349 : continue;
- 501 82210 : ++countmax;
+ 500 284218 : continue;
+ 501 82341 : ++countmax;
502 : }
503 :
504 : /* compute the autosave size for all disk, even if not read */
@@ -589,26 +589,26 @@
527 : int rehash;
528 :
529 366559 : if (!block_is_enabled(i, handle, diskmax))
- 530 284349 : continue;
+ 530 284218 : continue;
531 :
532 : /* one more block processed for autosave */
- 533 82210 : ++autosavedone;
- 534 82210 : --autosavemissing;
+ 533 82341 : ++autosavedone;
+ 534 82341 : --autosavemissing;
535 :
536 : /* by default process the block, and skip it if something go wrong */
- 537 82210 : error_on_this_block = 0;
- 538 82210 : silent_error_on_this_block = 0;
- 539 82210 : io_error_on_this_block = 0;
- 540 82210 : fixed_error_on_this_block = 0;
+ 537 82341 : error_on_this_block = 0;
+ 538 82341 : silent_error_on_this_block = 0;
+ 539 82341 : io_error_on_this_block = 0;
+ 540 82341 : fixed_error_on_this_block = 0;
541 :
542 : /* keep track of the number of failed blocks */
- 543 82210 : failed_count = 0;
+ 543 82341 : failed_count = 0;
544 :
545 : /* get block specific info */
- 546 82210 : info = info_get(&state->infoarr, i);
+ 546 82341 : info = info_get(&state->infoarr, i);
547 :
548 : /* if we have to use the old hash */
- 549 82210 : rehash = info_get_rehash(info);
+ 549 82341 : rehash = info_get_rehash(info);
550 :
551 : /* it could happens that all the blocks are EMPTY/BLK and CHG but with the hash */
552 : /* still matching because the specific CHG block was not modified. */
@@ -616,55 +616,55 @@
554 : /* have the hash cleared (::clear_past_hash flag), and then they won't never match the hash. */
555 : /* We are treating only CHG blocks created at runtime. */
556 : /* In such case, we can avoid to update parity, because it would be the same as before */
- 557 82210 : parity_needs_to_be_updated = 0;
+ 557 82341 : parity_needs_to_be_updated = 0;
558 :
559 : /* if the block is marked as bad, we force the parity update */
560 : /* because the bad block may be the result of a wrong parity */
- 561 82210 : if (info_get_bad(info))
+ 561 82341 : if (info_get_bad(info))
562 0 : parity_needs_to_be_updated = 1;
563 :
564 : /* for each disk, process the block */
- 565 575470 : for (j = 0; j < diskmax; ++j) {
+ 565 576387 : for (j = 0; j < diskmax; ++j) {
566 : int read_size;
567 : unsigned char hash[HASH_SIZE];
568 : struct snapraid_block* block;
569 : unsigned block_state;
- 570 493260 : struct snapraid_disk* disk = handle[j].disk;
+ 570 494046 : struct snapraid_disk* disk = handle[j].disk;
571 : struct snapraid_file* file;
572 : block_off_t file_pos;
573 :
574 : /* by default no rehash in case of "continue" */
- 575 493260 : rehandle[j].block = 0;
+ 575 494046 : rehandle[j].block = 0;
576 :
577 : /* if the disk position is not used */
- 578 493260 : if (!disk) {
+ 578 494046 : if (!disk) {
579 : /* use an empty block */
580 0 : memset(buffer[j], 0, state->block_size);
- 581 89224 : continue;
+ 581 89194 : continue;
582 : }
583 :
584 : /* get the block */
- 585 493260 : block = fs_par2block_get(disk, i);
+ 585 494046 : block = fs_par2block_get(disk, i);
586 :
587 : /* get the state of the block */
- 588 493260 : block_state = block_state_get(block);
+ 588 494046 : block_state = block_state_get(block);
589 :
590 : /* if the block has invalid parity, */
591 : /* we have to take care of it in case of recover */
- 592 493260 : if (block_has_invalid_parity(block)) {
+ 592 494046 : if (block_has_invalid_parity(block)) {
593 : /* store it in the failed set, because */
594 : /* the parity may be still computed with the previous content */
- 595 180479 : failed[failed_count].index = j;
- 596 180479 : failed[failed_count].size = state->block_size;
- 597 180479 : failed[failed_count].block = block;
- 598 180479 : ++failed_count;
+ 595 180603 : failed[failed_count].index = j;
+ 596 180603 : failed[failed_count].size = state->block_size;
+ 597 180603 : failed[failed_count].block = block;
+ 598 180603 : ++failed_count;
599 :
600 : /* if the block has invalid parity, we have to update the parity */
601 : /* to include this block change */
602 : /* This also apply to CHG blocks, but we are going to handle */
603 : /* later this case to do the updates only if really needed */
- 604 180479 : if (block_state != BLOCK_STATE_CHG)
- 605 56263 : parity_needs_to_be_updated = 1;
+ 604 180603 : if (block_state != BLOCK_STATE_CHG)
+ 605 56266 : parity_needs_to_be_updated = 1;
606 :
607 : /* note that DELETE blocks are skipped in the next check */
608 : /* and we have to store them in the failed blocks */
@@ -675,24 +675,24 @@
613 :
614 : /* if the block has no file, meanining that it's EMPTY or DELETED, */
615 : /* it doesn't partecipate in the new parity computation */
- 616 493260 : if (!block_has_file(block)) {
+ 616 494046 : if (!block_has_file(block)) {
617 : /* use an empty block */
- 618 88322 : memset(buffer[j], 0, state->block_size);
- 619 88322 : continue;
+ 618 88293 : memset(buffer[j], 0, state->block_size);
+ 619 88293 : continue;
620 : }
621 :
622 : /* get the file of this block */
- 623 404938 : file = fs_par2file_get(disk, i, &file_pos);
+ 623 405753 : file = fs_par2file_get(disk, i, &file_pos);
624 :
625 : /* until now is CPU */
- 626 404938 : state_usage_cpu(state);
+ 626 405753 : state_usage_cpu(state);
627 :
628 : /* if the file is different than the current one, close it */
- 629 404938 : if (handle[j].file != 0 && handle[j].file != file) {
+ 629 405753 : if (handle[j].file != 0 && handle[j].file != file) {
630 : /* keep a pointer at the file we are going to close for error reporting */
- 631 168338 : struct snapraid_file* report = handle[j].file;
- 632 168338 : ret = handle_close(&handle[j]);
- 633 168338 : if (ret == -1) {
+ 631 168779 : struct snapraid_file* report = handle[j].file;
+ 632 168779 : ret = handle_close(&handle[j]);
+ 633 168779 : if (ret == -1) {
634 : /* LCOV_EXCL_START */
635 : /* This one is really an unexpected error, because we are only reading */
636 : /* and closing a descriptor should never fail */
@@ -715,8 +715,8 @@
653 : }
654 : }
655 :
- 656 404938 : ret = handle_open(&handle[j], file, state->file_mode, log_error, 0);
- 657 404938 : if (ret == -1) {
+ 656 405753 : ret = handle_open(&handle[j], file, state->file_mode, log_error, 0);
+ 657 405753 : if (ret == -1) {
658 12 : if (errno == EIO) {
659 : /* LCOV_EXCL_START */
660 : log_tag("error:%u:%s:%s: Open EIO error. %s\n", i, disk->name, esc(file->sub), strerror(errno));
@@ -762,10 +762,10 @@
700 : }
701 :
702 : /* check if the file is changed */
- 703 404926 : if (handle[j].st.st_size != file->size
- 704 404924 : || handle[j].st.st_mtime != file->mtime_sec
- 705 404922 : || STAT_NSEC(&handle[j].st) != file->mtime_nsec
- 706 404922 : || handle[j].st.st_ino != file->inode
+ 703 405741 : if (handle[j].st.st_size != file->size
+ 704 405739 : || handle[j].st.st_mtime != file->mtime_sec
+ 705 405737 : || STAT_NSEC(&handle[j].st) != file->mtime_nsec
+ 706 405737 : || handle[j].st.st_ino != file->inode
707 : ) {
708 6 : log_tag("error:%u:%s:%s: Unexpected attribute change\n", i, disk->name, esc(file->sub));
709 6 : if (handle[j].st.st_size != file->size) {
@@ -785,8 +785,8 @@
723 6 : continue;
724 : }
725 :
- 726 404920 : read_size = handle_read(&handle[j], file_pos, buffer[j], state->block_size, log_error, 0);
- 727 404920 : if (read_size == -1) {
+ 726 405735 : read_size = handle_read(&handle[j], file_pos, buffer[j], state->block_size, log_error, 0);
+ 727 405735 : if (read_size == -1) {
728 : /* LCOV_EXCL_START */
729 : if (errno == EIO) {
730 : log_tag("error:%u:%s:%s: Read EIO error at position %u. %s\n", i, disk->name, esc(file->sub), file_pos, strerror(errno));
@@ -814,26 +814,26 @@
752 : }
753 :
754 : /* until now is disk */
- 755 404920 : state_usage_disk(state, disk);
+ 755 405735 : state_usage_disk(state, disk);
756 :
- 757 404920 : countsize += read_size;
+ 757 405735 : countsize += read_size;
758 :
759 : /* now compute the hash */
- 760 404920 : if (rehash) {
+ 760 405735 : if (rehash) {
761 52244 : memhash(state->prevhash, state->prevhashseed, hash, buffer[j], read_size);
762 :
763 : /* compute the new hash, and store it */
764 52244 : rehandle[j].block = block;
765 52244 : memhash(state->hash, state->hashseed, rehandle[j].hash, buffer[j], read_size);
766 : } else {
- 767 352676 : memhash(state->hash, state->hashseed, hash, buffer[j], read_size);
+ 767 353491 : memhash(state->hash, state->hashseed, hash, buffer[j], read_size);
768 : }
769 :
- 770 404920 : if (block_has_updated_hash(block)) {
+ 770 405735 : if (block_has_updated_hash(block)) {
771 : /* compare the hash */
- 772 280722 : if (memcmp(hash, block->hash, HASH_SIZE) != 0) {
+ 772 281416 : if (memcmp(hash, block->hash, HASH_SIZE) != 0) {
773 : /* if the file has invalid parity, it's a REP changed during the sync */
- 774 884 : if (block_has_invalid_parity(block)) {
+ 774 883 : if (block_has_invalid_parity(block)) {
775 1 : log_tag("error:%u:%s:%s: Unexpected data change\n", i, disk->name, esc(file->sub));
776 1 : log_error("Data change at file '%s' at position '%u'\n", handle[j].path, file_pos);
777 1 : log_error("WARNING! Unexpected data modification of a file without parity!\n");
@@ -854,38 +854,38 @@
792 1 : error_on_this_block = 1;
793 1 : continue;
794 : } else { /* otherwise it's a BLK with silent error */
- 795 883 : unsigned diff = memdiff(hash, block->hash, HASH_SIZE);
- 796 883 : log_tag("error:%u:%s:%s: Data error at position %u, diff bits %u\n", i, disk->name, esc(file->sub), file_pos, diff);
- 797 883 : log_error("Data error in file '%s' at position '%u', diff bits %u\n", handle[j].path, file_pos, diff);
+ 795 882 : unsigned diff = memdiff(hash, block->hash, HASH_SIZE);
+ 796 882 : log_tag("error:%u:%s:%s: Data error at position %u, diff bits %u\n", i, disk->name, esc(file->sub), file_pos, diff);
+ 797 882 : log_error("Data error in file '%s' at position '%u', diff bits %u\n", handle[j].path, file_pos, diff);
798 :
799 : /* save the failed block for the fix */
- 800 883 : failed[failed_count].index = j;
- 801 883 : failed[failed_count].size = read_size;
- 802 883 : failed[failed_count].block = block;
- 803 883 : ++failed_count;
+ 800 882 : failed[failed_count].index = j;
+ 801 882 : failed[failed_count].size = read_size;
+ 802 882 : failed[failed_count].block = block;
+ 803 882 : ++failed_count;
804 :
805 : /* silent errors are very rare, and are not a signal that a disk */
806 : /* is going to fail. So, we just continue marking the block as bad */
807 : /* just like in scrub */
- 808 883 : ++silent_error;
- 809 883 : silent_error_on_this_block = 1;
- 810 883 : continue;
+ 808 882 : ++silent_error;
+ 809 882 : silent_error_on_this_block = 1;
+ 810 882 : continue;
811 : }
812 : }
813 : } else {
814 : /* if until now the parity doesn't need to be updated */
- 815 124198 : if (!parity_needs_to_be_updated) {
+ 815 124319 : if (!parity_needs_to_be_updated) {
816 : /* for sure it's a CHG block, because EMPTY are processed before with "continue" */
817 : /* and BLK and REP have "block_has_updated_hash()" as 1, and all the others */
818 : /* have "parity_needs_to_be_updated" already at 1 */
- 819 56621 : assert(block_state_get(block) == BLOCK_STATE_CHG);
+ 819 56741 : assert(block_state_get(block) == BLOCK_STATE_CHG);
820 :
821 : /* if there is an hash */
- 822 56621 : if (hash_is_real(block->hash)) {
+ 822 56741 : if (hash_is_real(block->hash)) {
823 : /* check if the hash is changed */
- 824 12894 : if (memcmp(hash, block->hash, HASH_SIZE) != 0) {
+ 824 13014 : if (memcmp(hash, block->hash, HASH_SIZE) != 0) {
825 : /* the block is different, and we must update parity */
- 826 10323 : parity_needs_to_be_updated = 1;
+ 826 10443 : parity_needs_to_be_updated = 1;
827 : }
828 : } else {
829 : /* if the hash is already invalid, we update parity */
@@ -895,7 +895,7 @@
833 :
834 : /* copy the hash in the block, but doesn't mark the block as hashed */
835 : /* this allow in case of skipped block to do not save the failed computation */
- 836 124198 : memcpy(block->hash, hash, HASH_SIZE);
+ 836 124319 : memcpy(block->hash, hash, HASH_SIZE);
837 :
838 : /* note that in case of rehash, this is the wrong hash, */
839 : /* but it will be overwritten later */
@@ -905,52 +905,52 @@
843 : /* if we have only silent errors we can try to fix them on-the-fly */
844 : /* note the the fix is not written to disk, but used only to */
845 : /* compute the new parity */
- 846 82210 : if (!error_on_this_block && !io_error_on_this_block && silent_error_on_this_block) {
+ 846 82341 : if (!error_on_this_block && !io_error_on_this_block && silent_error_on_this_block) {
847 : unsigned failed_mac;
- 848 883 : int something_to_recover = 0;
+ 848 882 : int something_to_recover = 0;
849 :
850 : /* setup the blocks to recover */
- 851 883 : failed_mac = 0;
- 852 2649 : for (j = 0; j < failed_count; ++j) {
- 853 1766 : unsigned char* block_buffer = buffer[failed[j].index];
- 854 1766 : unsigned char* block_copy = buffer[diskmax + state->level + failed[j].index];
- 855 1766 : unsigned block_state = block_state_get(failed[j].block);
+ 851 882 : failed_mac = 0;
+ 852 2646 : for (j = 0; j < failed_count; ++j) {
+ 853 1764 : unsigned char* block_buffer = buffer[failed[j].index];
+ 854 1764 : unsigned char* block_copy = buffer[diskmax + state->level + failed[j].index];
+ 855 1764 : unsigned block_state = block_state_get(failed[j].block);
856 :
857 : /* we try to recover only if at least one BLK is present */
- 858 1766 : if (block_state == BLOCK_STATE_BLK)
- 859 883 : something_to_recover = 1;
+ 858 1764 : if (block_state == BLOCK_STATE_BLK)
+ 859 882 : something_to_recover = 1;
860 :
861 : /* save a copy of the content just read */
862 : /* that it's going to be overwritten by the recovering function */
- 863 1766 : memcpy(block_copy, block_buffer, state->block_size);
+ 863 1764 : memcpy(block_copy, block_buffer, state->block_size);
864 :
- 865 1766 : if (block_state == BLOCK_STATE_CHG
- 866 883 : && hash_is_zero(failed[j].block->hash)
+ 865 1764 : if (block_state == BLOCK_STATE_CHG
+ 866 882 : && hash_is_zero(failed[j].block->hash)
867 : ) {
868 : /* if the block was filled with 0, restore this state */
869 : /* and avoid to recover it */
870 0 : memset(block_buffer, 0, state->block_size);
871 : } else {
872 : /* if we have too many failures, we cannot recover */
- 873 1766 : if (failed_mac >= state->level)
+ 873 1764 : if (failed_mac >= state->level)
874 0 : break;
875 :
876 : /* otherwise it has to be recovered */
- 877 1766 : failed_map[failed_mac++] = failed[j].index;
+ 877 1764 : failed_map[failed_mac++] = failed[j].index;
878 : }
879 : }
880 :
881 : /* if we have something to recover and enough parity */
- 882 883 : if (something_to_recover && j == failed_count) {
+ 882 882 : if (something_to_recover && j == failed_count) {
883 : /* until now is CPU */
- 884 883 : state_usage_cpu(state);
+ 884 882 : state_usage_cpu(state);
885 :
886 : /* read the parity */
887 : /* we are sure that parity exists because */
888 : /* we have at least one BLK block */
- 889 6181 : for (l = 0; l < state->level; ++l) {
- 890 5298 : ret = parity_read(parity[l], i, buffer[diskmax + l], state->block_size, log_error);
- 891 5298 : if (ret == -1) {
+ 889 6174 : for (l = 0; l < state->level; ++l) {
+ 890 5292 : ret = parity_read(parity[l], i, buffer[diskmax + l], state->block_size, log_error);
+ 891 5292 : if (ret == -1) {
892 : /* LCOV_EXCL_START */
893 : if (errno == EIO) {
894 : log_tag("parity_error:%u:%s: Read EIO error. %s\n", i, lev_config_name(l), strerror(errno));
@@ -978,74 +978,74 @@
916 : }
917 :
918 : /* until now is parity */
- 919 5298 : state_usage_parity(state, l);
+ 919 5292 : state_usage_parity(state, l);
920 : }
921 :
922 : /* if no error in parity read */
- 923 883 : if (!io_error_on_this_block) {
+ 923 882 : if (!io_error_on_this_block) {
924 : /* try to fix the data */
925 : /* note that this is a simple fix algorithm, that doesn't take into */
926 : /* account the case of a wrong parity */
927 : /* only 'fix' supports the most advanced fixing */
- 928 883 : raid_rec(failed_mac, failed_map, diskmax, state->level, state->block_size, buffer);
+ 928 882 : raid_rec(failed_mac, failed_map, diskmax, state->level, state->block_size, buffer);
929 :
930 : /* check the result and prepare the data */
- 931 5298 : for (j = 0; j < failed_count; ++j) {
+ 931 5292 : for (j = 0; j < failed_count; ++j) {
932 : unsigned char hash[HASH_SIZE];
- 933 1766 : unsigned char* block_buffer = buffer[failed[j].index];
- 934 1766 : unsigned char* block_copy = buffer[diskmax + state->level + failed[j].index];
- 935 1766 : unsigned block_state = block_state_get(failed[j].block);
+ 933 1764 : unsigned char* block_buffer = buffer[failed[j].index];
+ 934 1764 : unsigned char* block_copy = buffer[diskmax + state->level + failed[j].index];
+ 935 1764 : unsigned block_state = block_state_get(failed[j].block);
936 :
- 937 1766 : if (block_state == BLOCK_STATE_BLK) {
- 938 883 : unsigned size = failed[j].size;
+ 937 1764 : if (block_state == BLOCK_STATE_BLK) {
+ 938 882 : unsigned size = failed[j].size;
939 :
940 : /* compute the hash of the recovered block */
- 941 883 : if (rehash) {
+ 941 882 : if (rehash) {
942 0 : memhash(state->prevhash, state->prevhashseed, hash, block_buffer, size);
943 : } else {
- 944 883 : memhash(state->hash, state->hashseed, hash, block_buffer, size);
+ 944 882 : memhash(state->hash, state->hashseed, hash, block_buffer, size);
945 : }
946 :
947 : /* if the hash doesn't match */
- 948 883 : if (memcmp(hash, failed[j].block->hash, HASH_SIZE) != 0) {
+ 948 882 : if (memcmp(hash, failed[j].block->hash, HASH_SIZE) != 0) {
949 : /* we have not recovered */
950 0 : break;
951 : }
952 :
953 : /* pad with 0 if needed */
- 954 883 : if (size < state->block_size)
- 955 370 : memset(block_buffer + size, 0, state->block_size - size);
+ 954 882 : if (size < state->block_size)
+ 955 342 : memset(block_buffer + size, 0, state->block_size - size);
956 : } else {
957 : /* otherwise restore the content */
958 : /* because we are not interested in the old state */
959 : /* that it's recovered for CHG, REP and DELETED blocks */
- 960 883 : memcpy(block_buffer, block_copy, state->block_size);
+ 960 882 : memcpy(block_buffer, block_copy, state->block_size);
961 : }
962 : }
963 :
964 : /* if all is processed, we have fixed it */
- 965 883 : if (j == failed_count)
- 966 883 : fixed_error_on_this_block = 1;
+ 965 882 : if (j == failed_count)
+ 966 882 : fixed_error_on_this_block = 1;
967 : }
968 : }
969 : }
970 :
971 : /* if we have read all the data required and it's correct, proceed with the parity */
- 972 82210 : if (!error_on_this_block && !io_error_on_this_block
- 973 82191 : && (!silent_error_on_this_block || fixed_error_on_this_block)
+ 972 82341 : if (!error_on_this_block && !io_error_on_this_block
+ 973 82322 : && (!silent_error_on_this_block || fixed_error_on_this_block)
974 : ) {
975 : /* update the parity only if really needed */
- 976 82191 : if (parity_needs_to_be_updated) {
+ 976 82322 : if (parity_needs_to_be_updated) {
977 : /* compute the parity */
- 978 79852 : raid_gen(diskmax, state->level, state->block_size, buffer);
+ 978 79972 : raid_gen(diskmax, state->level, state->block_size, buffer);
979 :
980 : /* until now is CPU */
- 981 79852 : state_usage_cpu(state);
+ 981 79972 : state_usage_cpu(state);
982 :
983 : /* write the parity */
- 984 522644 : for (l = 0; l < state->level; ++l) {
- 985 442792 : ret = parity_write(parity[l], i, buffer[diskmax + l], state->block_size);
- 986 442792 : if (ret == -1) {
+ 984 523484 : for (l = 0; l < state->level; ++l) {
+ 985 443512 : ret = parity_write(parity[l], i, buffer[diskmax + l], state->block_size);
+ 986 443512 : if (ret == -1) {
987 : /* LCOV_EXCL_START */
988 : if (errno == EIO) {
989 : log_tag("parity_error:%u:%s: Write EIO error. %s\n", i, lev_config_name(l), strerror(errno));
@@ -1073,35 +1073,35 @@
1011 : }
1012 :
1013 : /* until now is parity */
- 1014 442792 : state_usage_parity(state, l);
+ 1014 443512 : state_usage_parity(state, l);
1015 : }
1016 : }
1017 :
1018 : /* if no error in parity write */
- 1019 82191 : if (!io_error_on_this_block) {
+ 1019 82322 : if (!io_error_on_this_block) {
1020 : /* for each disk, mark the blocks as processed */
- 1021 575337 : for (j = 0; j < diskmax; ++j) {
+ 1021 576254 : for (j = 0; j < diskmax; ++j) {
1022 : struct snapraid_block* block;
1023 :
- 1024 493146 : if (!handle[j].disk)
+ 1024 493932 : if (!handle[j].disk)
1025 0 : continue;
1026 :
- 1027 493146 : block = fs_par2block_get(handle[j].disk, i);
+ 1027 493932 : block = fs_par2block_get(handle[j].disk, i);
1028 :
- 1029 493146 : if (block == BLOCK_EMPTY) {
+ 1029 493932 : if (block == BLOCK_EMPTY) {
1030 : /* nothing to do */
- 1031 77254 : continue;
+ 1031 77225 : continue;
1032 : }
1033 :
1034 : /* if it's a deleted block */
- 1035 415892 : if (block_state_get(block) == BLOCK_STATE_DELETED) {
+ 1035 416707 : if (block_state_get(block) == BLOCK_STATE_DELETED) {
1036 : /* the parity is now updated without this block, so it's now empty */
1037 11066 : fs_deallocate(handle[j].disk, i);
1038 11066 : continue;
1039 : }
1040 :
1041 : /* now all the blocks have the hash and the parity computed */
- 1042 404826 : block_state_set(block, BLOCK_STATE_BLK);
+ 1042 405641 : block_state_set(block, BLOCK_STATE_BLK);
1043 : }
1044 : }
1045 :
@@ -1110,12 +1110,12 @@
1048 : /* wrote the parity at this time */
1049 : /* we also update the info block only if no silent error was found */
1050 : /* because has no sense to refresh the time for data that we know bad */
- 1051 82191 : if (parity_needs_to_be_updated
- 1052 79852 : && !silent_error_on_this_block
- 1053 79501 : && !io_error_on_this_block
+ 1051 82322 : if (parity_needs_to_be_updated
+ 1052 79972 : && !silent_error_on_this_block
+ 1053 79625 : && !io_error_on_this_block
1054 : ) {
1055 : /* if rehash is neeed */
- 1056 79501 : if (rehash) {
+ 1056 79625 : if (rehash) {
1057 : /* store all the new hash already computed */
1058 64358 : for (j = 0; j < diskmax; ++j) {
1059 55164 : if (rehandle[j].block)
@@ -1125,37 +1125,37 @@
1063 :
1064 : /* update the time info of the block */
1065 : /* we are also clearing any previous bad and rehash flag */
- 1066 79501 : info_set(&state->infoarr, i, info_make(now, 0, 0, 1));
+ 1066 79625 : info_set(&state->infoarr, i, info_make(now, 0, 0, 1));
1067 : }
1068 : }
1069 :
1070 : /* if a silent (even if corrected) or input/output error was found */
1071 : /* mark the block as bad to have check/fix to handle it */
1072 : /* because our correction is in memory only and not yet written */
- 1073 82210 : if (silent_error_on_this_block || io_error_on_this_block) {
+ 1073 82341 : if (silent_error_on_this_block || io_error_on_this_block) {
1074 : /* set the error status keeping the other info */
- 1075 883 : info_set(&state->infoarr, i, info_set_bad(info));
+ 1075 882 : info_set(&state->infoarr, i, info_set_bad(info));
1076 : }
1077 :
1078 : /* mark the state as needing write */
- 1079 82210 : state->need_write = 1;
+ 1079 82341 : state->need_write = 1;
1080 :
1081 : /* count the number of processed block */
- 1082 82210 : ++countpos;
+ 1082 82341 : ++countpos;
1083 :
1084 : /* progress */
- 1085 82210 : if (state_progress(state, i, countpos, countmax, countsize)) {
+ 1085 82341 : if (state_progress(state, i, countpos, countmax, countsize)) {
1086 : /* LCOV_EXCL_START */
1087 : break;
1088 : /* LCOV_EXCL_STOP */
1089 : }
1090 :
1091 : /* autosave */
- 1092 82210 : if ((state->autosave != 0
+ 1092 82341 : if ((state->autosave != 0
1093 7264 : && autosavedone >= autosavelimit /* if we have reached the limit */
1094 0 : && autosavemissing >= autosavelimit) /* if we have at least a full step to do */
1095 : /* or if we have a forced autosave at the specified block */
- 1096 82210 : || (state->opt.force_autosave_at != 0 && state->opt.force_autosave_at == i)
+ 1096 82341 : || (state->opt.force_autosave_at != 0 && state->opt.force_autosave_at == i)
1097 : ) {
1098 1 : autosavedone = 0; /* restart the counter */
1099 :
diff --git a/cov/cmdline/unix.c.func-sort-c.html b/cov/cmdline/unix.c.func-sort-c.html
index 530cc0fa..5b352a9b 100644
--- a/cov/cmdline/unix.c.func-sort-c.html
+++ b/cov/cmdline/unix.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,15 +61,15 @@
| tick |
- 2046547 |
+ 2049010 |
| open_noatime |
- 1639793 |
+ 1640600 |
| filephy |
- 11430 |
+ 11432 |
| devuuid |
diff --git a/cov/cmdline/unix.c.func.html b/cov/cmdline/unix.c.func.html
index 494539a3..bd939ad7 100644
--- a/cov/cmdline/unix.c.func.html
+++ b/cov/cmdline/unix.c.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -105,7 +105,7 @@
| filephy |
- 11430 |
+ 11432 |
| fsinfo |
@@ -113,7 +113,7 @@
| open_noatime |
- 1639793 |
+ 1640600 |
| os_done |
@@ -145,7 +145,7 @@
| tick |
- 2046547 |
+ 2049010 |
| tick_ms |
diff --git a/cov/cmdline/unix.c.gcov.html b/cov/cmdline/unix.c.gcov.html
index 18f63c6b..3a428fcf 100644
--- a/cov/cmdline/unix.c.gcov.html
+++ b/cov/cmdline/unix.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -90,15 +90,15 @@
28 : int exit_failure = 1;
29 : int exit_sync_needed = 2;
30 :
- 31 1639793 : int open_noatime(const char* file, int flags)
+ 31 1640600 : int open_noatime(const char* file, int flags)
32 : {
33 : #ifdef O_NOATIME
- 34 1639793 : int f = open(file, flags | O_NOATIME);
+ 34 1640600 : int f = open(file, flags | O_NOATIME);
35 :
36 : /* only root is allowed to use O_NOATIME, in case retry without it */
- 37 1639793 : if (f == -1 && errno == EPERM)
+ 37 1640600 : if (f == -1 && errno == EPERM)
38 0 : f = open(file, flags);
- 39 1639793 : return f;
+ 39 1640600 : return f;
40 : #else
41 : return open(file, flags);
42 : #endif
@@ -185,7 +185,7 @@
123 : }
124 : #endif
125 :
- 126 11430 : int filephy(const char* path, uint64_t size, uint64_t* physical)
+ 126 11432 : int filephy(const char* path, uint64_t size, uint64_t* physical)
127 : {
128 : #if HAVE_LINUX_FIEMAP_H
129 : /* In Linux get the real physical address of the file */
@@ -197,24 +197,24 @@
135 : } fm;
136 : unsigned int blknum;
137 :
- 138 11430 : f = open(path, O_RDONLY);
- 139 11430 : if (f == -1) {
+ 138 11432 : f = open(path, O_RDONLY);
+ 139 11432 : if (f == -1) {
140 0 : return -1;
141 : }
142 :
143 : /* first try with FIEMAP */
144 : /* if works for ext2, ext3, ext4, xfs, btrfs */
- 145 11430 : memset(&fm, 0, sizeof(fm));
- 146 11430 : fm.fiemap.fm_start = 0;
- 147 11430 : fm.fiemap.fm_length = ~0ULL;
- 148 11430 : fm.fiemap.fm_flags = FIEMAP_FLAG_SYNC; /* required to ensure that just created files report a valid address and not 0 */
- 149 11430 : fm.fiemap.fm_extent_count = 1; /* we are interested only at the first block */
+ 145 11432 : memset(&fm, 0, sizeof(fm));
+ 146 11432 : fm.fiemap.fm_start = 0;
+ 147 11432 : fm.fiemap.fm_length = ~0ULL;
+ 148 11432 : fm.fiemap.fm_flags = FIEMAP_FLAG_SYNC; /* required to ensure that just created files report a valid address and not 0 */
+ 149 11432 : fm.fiemap.fm_extent_count = 1; /* we are interested only at the first block */
150 :
- 151 11430 : if (ioctl(f, FS_IOC_FIEMAP, &fm) != -1) {
- 152 11430 : *physical = fm.fiemap.fm_extents[0].fe_physical + FILEPHY_REAL_OFFSET;
- 153 11430 : if (close(f) == -1)
+ 151 11432 : if (ioctl(f, FS_IOC_FIEMAP, &fm) != -1) {
+ 152 11432 : *physical = fm.fiemap.fm_extents[0].fe_physical + FILEPHY_REAL_OFFSET;
+ 153 11432 : if (close(f) == -1)
154 0 : return -1;
- 155 11430 : return 0;
+ 155 11432 : return 0;
156 : }
157 :
158 : /* if the file is empty, FIBMAP doesn't work, and we don't even try to use it */
@@ -324,7 +324,7 @@
262 2175 : return 0;
263 : }
264 :
- 265 2046547 : uint64_t tick(void)
+ 265 2049010 : uint64_t tick(void)
266 : {
267 : #if HAVE_MACH_ABSOLUTE_TIME
268 : /* for Mac OS X */
@@ -335,14 +335,14 @@
273 :
274 : /* nanosecond precision with clock_gettime() */
275 : #if defined(CLOCK_MONOTONIC_RAW)
- 276 2046547 : if (clock_gettime(CLOCK_MONOTONIC_RAW, &tv) != 0) {
+ 276 2049010 : if (clock_gettime(CLOCK_MONOTONIC_RAW, &tv) != 0) {
277 : #else
278 : if (clock_gettime(CLOCK_MONOTONIC, &tv) != 0) {
279 : #endif
280 0 : return 0;
281 : }
282 :
- 283 2046547 : return tv.tv_sec * 1000000000ULL + tv.tv_nsec;
+ 283 2049010 : return tv.tv_sec * 1000000000ULL + tv.tv_nsec;
284 : #else
285 : /* other platforms */
286 : struct timeval tv;
@@ -504,14 +504,14 @@
442 : return -1;
443 : /* LCOV_EXCL_STOP */
444 : }
- 445 96 : if (st.st_rdev != device) {
+ 445 97 : if (st.st_rdev != device) {
446 : /* LCOV_EXCL_START */
447 : log_fatal("Unexpected device '%u:%u' instead of '%u:%u' for '%s'.\n", major(st.st_rdev), minor(st.st_rdev), major(device), minor(device), path);
448 : return -1;
449 : /* LCOV_EXCL_STOP */
450 : }
451 :
- 452 96 : return 0;
+ 452 97 : return 0;
453 : }
454 : #endif
455 :
diff --git a/cov/cmdline/util.c.func-sort-c.html b/cov/cmdline/util.c.func-sort-c.html
index f58dadb1..8fc8b9ea 100644
--- a/cov/cmdline/util.c.func-sort-c.html
+++ b/cov/cmdline/util.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,35 +61,35 @@
| util_rotl32 |
- 924868918 |
+ 924861211 |
| util_rotl64 |
- 461100864 |
+ 461015664 |
| memhash |
- 5723453 |
+ 5724756 |
| crc32c_x86 |
- 659437 |
+ 659527 |
| memdiff |
- 25256 |
+ 25190 |
| malloc_nofail_test |
- 2579 |
+ 2580 |
| mtest_vector |
- 2579 |
+ 2580 |
| crc32c_gen |
- 337 |
+ 353 |
| crc32c_init |
diff --git a/cov/cmdline/util.c.func.html b/cov/cmdline/util.c.func.html
index 878fbb41..a05830bd 100644
--- a/cov/cmdline/util.c.func.html
+++ b/cov/cmdline/util.c.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,7 +61,7 @@
| crc32c_gen |
- 337 |
+ 353 |
| crc32c_init |
@@ -69,7 +69,7 @@
| crc32c_x86 |
- 659437 |
+ 659527 |
| hash_config_name |
@@ -89,7 +89,7 @@
| malloc_nofail_test |
- 2579 |
+ 2580 |
| malloc_nofail_vector_align |
@@ -97,23 +97,23 @@
| memdiff |
- 25256 |
+ 25190 |
| memhash |
- 5723453 |
+ 5724756 |
| mtest_vector |
- 2579 |
+ 2580 |
| util_rotl32 |
- 924868918 |
+ 924861211 |
| util_rotl64 |
- 461100864 |
+ 461015664 |
diff --git a/cov/cmdline/util.c.gcov.html b/cov/cmdline/util.c.gcov.html
index 466752f2..501f3b20 100644
--- a/cov/cmdline/util.c.gcov.html
+++ b/cov/cmdline/util.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -119,20 +119,20 @@
57 201 : return ptr;
58 : }
59 :
- 60 2579 : void* malloc_nofail_test(size_t size)
+ 60 2580 : void* malloc_nofail_test(size_t size)
61 : {
62 : void* ptr;
63 :
- 64 2579 : ptr = malloc_nofail(size);
+ 64 2580 : ptr = malloc_nofail(size);
65 :
- 66 2578 : mtest_vector(1, size, &ptr);
+ 66 2580 : mtest_vector(1, size, &ptr);
67 :
68 2580 : return ptr;
69 : }
70 :
- 71 2579 : void mtest_vector(int n, size_t size, void** vv)
+ 71 2580 : void mtest_vector(int n, size_t size, void** vv)
72 : {
- 73 2579 : if (raid_mtest_vector(n, size, vv) != 0) {
+ 73 2580 : if (raid_mtest_vector(n, size, vv) != 0) {
74 : /* LCOV_EXCL_START */
75 : log_fatal("DANGER! Your RAM memory is broken! DO NOT PROCEED UNTIL FIXED!\n");
76 : log_fatal("Try running a memory test like http://www.memtest86.com/\n");
@@ -416,27 +416,27 @@
354 : int crc_x86;
355 : #endif
356 :
- 357 337 : uint32_t crc32c_gen(uint32_t crc, const unsigned char* ptr, unsigned size)
+ 357 353 : uint32_t crc32c_gen(uint32_t crc, const unsigned char* ptr, unsigned size)
358 : {
- 359 337 : crc ^= CRC_IV;
+ 359 353 : crc ^= CRC_IV;
360 :
- 361 337 : crc = crc32c_gen_plain(crc, ptr, size);
+ 361 353 : crc = crc32c_gen_plain(crc, ptr, size);
362 :
- 363 337 : crc ^= CRC_IV;
+ 363 353 : crc ^= CRC_IV;
364 :
- 365 337 : return crc;
+ 365 353 : return crc;
366 : }
367 :
368 : #if HAVE_SSE42
- 369 659437 : uint32_t crc32c_x86(uint32_t crc, const unsigned char* ptr, unsigned size)
+ 369 659527 : uint32_t crc32c_x86(uint32_t crc, const unsigned char* ptr, unsigned size)
370 : {
- 371 659437 : crc ^= CRC_IV;
+ 371 659527 : crc ^= CRC_IV;
372 :
- 373 659437 : crc = crc32c_x86_plain(crc, ptr, size);
+ 373 659527 : crc = crc32c_x86_plain(crc, ptr, size);
374 :
- 375 659437 : crc ^= CRC_IV;
+ 375 659526 : crc ^= CRC_IV;
376 :
- 377 659437 : return crc;
+ 377 659526 : return crc;
378 : }
379 : #endif
380 :
@@ -460,14 +460,14 @@
398 : * Rotate left.
399 : * In x86/x64 they are optimized with a single assembler instruction.
400 : */
- 401 924868918 : static inline uint32_t util_rotl32(uint32_t x, int8_t r)
+ 401 924861211 : static inline uint32_t util_rotl32(uint32_t x, int8_t r)
402 : {
- 403 924868918 : return (x << r) | (x >> (32 - r));
+ 403 924861211 : return (x << r) | (x >> (32 - r));
404 : }
405 :
- 406 461100864 : static inline uint64_t util_rotl64(uint64_t x, int8_t r)
+ 406 461015664 : static inline uint64_t util_rotl64(uint64_t x, int8_t r)
407 : {
- 408 461100864 : return (x << r) | (x >> (64 - r));
+ 408 461015664 : return (x << r) | (x >> (64 - r));
409 : }
410 :
411 : /**
@@ -508,15 +508,15 @@
446 : #include "murmur3.c"
447 : #include "spooky2.c"
448 :
- 449 5723453 : void memhash(unsigned kind, const unsigned char* seed, void* digest, const void* src, size_t size)
+ 449 5724756 : void memhash(unsigned kind, const unsigned char* seed, void* digest, const void* src, size_t size)
450 : {
- 451 5723453 : switch (kind) {
+ 451 5724756 : switch (kind) {
452 : case HASH_MURMUR3 :
- 453 2252580 : MurmurHash3_x86_128(src, size, seed, digest);
- 454 2252580 : break;
+ 453 2252582 : MurmurHash3_x86_128(src, size, seed, digest);
+ 454 2252582 : break;
455 : case HASH_SPOOKY2 :
- 456 3470873 : SpookyHash128(src, size, seed, digest);
- 457 3470873 : break;
+ 456 3472174 : SpookyHash128(src, size, seed, digest);
+ 457 3472174 : break;
458 : default :
459 : /* LCOV_EXCL_START */
460 : log_fatal("Internal inconsistency in hash function %u\n", kind);
@@ -524,7 +524,7 @@
462 : break;
463 : /* LCOV_EXCL_STOP */
464 : }
- 465 5723453 : }
+ 465 5724756 : }
466 :
467 42 : const char* hash_config_name(unsigned kind)
468 : {
@@ -539,23 +539,23 @@
477 : }
478 : }
479 :
- 480 25256 : unsigned memdiff(const unsigned char* data1, const unsigned char* data2, size_t size)
+ 480 25190 : unsigned memdiff(const unsigned char* data1, const unsigned char* data2, size_t size)
481 : {
482 : size_t i;
483 : unsigned count;
484 :
- 485 25256 : count = 0;
- 486 11152456 : for (i = 0; i < size; ++i) {
+ 485 25190 : count = 0;
+ 486 11153350 : for (i = 0; i < size; ++i) {
487 : unsigned j;
- 488 11127200 : unsigned char diff = data1[i] ^ data2[i];
- 489 100144800 : for (j = 0; j < 8; ++j) {
- 490 89017600 : if ((diff & 1) != 0)
- 491 39280018 : ++count;
- 492 89017600 : diff >>= 1;
+ 488 11128160 : unsigned char diff = data1[i] ^ data2[i];
+ 489 100153440 : for (j = 0; j < 8; ++j) {
+ 490 89025280 : if ((diff & 1) != 0)
+ 491 39291929 : ++count;
+ 492 89025280 : diff >>= 1;
493 : }
494 : }
495 :
- 496 25256 : return 0;
+ 496 25190 : return 0;
497 : }
498 :
499 : /****************************************************************************/
diff --git a/cov/cmdline/util.h.func-sort-c.html b/cov/cmdline/util.h.func-sort-c.html
index f8ed6e45..aba2a712 100644
--- a/cov/cmdline/util.h.func-sort-c.html
+++ b/cov/cmdline/util.h.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,19 +61,19 @@
| crc32c_x86_plain |
- 131430214 |
+ 131602718 |
| crc32c_plain |
- 130044002 |
+ 128046334 |
| crc32c_plain_char |
- 23710549 |
+ 23675077 |
| crc32c_gen_plain |
- 337 |
+ 353 |
diff --git a/cov/cmdline/util.h.func.html b/cov/cmdline/util.h.func.html
index cd6b9d13..92bc1cda 100644
--- a/cov/cmdline/util.h.func.html
+++ b/cov/cmdline/util.h.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,19 +61,19 @@
| crc32c_gen_plain |
- 337 |
+ 353 |
| crc32c_plain |
- 130044002 |
+ 128046334 |
| crc32c_plain_char |
- 23710549 |
+ 23675077 |
| crc32c_x86_plain |
- 131430214 |
+ 131602718 |
diff --git a/cov/cmdline/util.h.gcov.html b/cov/cmdline/util.h.gcov.html
index a65119b9..a736fd08 100644
--- a/cov/cmdline/util.h.gcov.html
+++ b/cov/cmdline/util.h.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -133,12 +133,12 @@
71 : /**
72 : * Compute CRC-32 (Castagnoli) for a single byte without the IV.
73 : */
- 74 23710549 : static inline uint32_t crc32c_plain_char(uint32_t crc, unsigned char c)
+ 74 23675077 : static inline uint32_t crc32c_plain_char(uint32_t crc, unsigned char c)
75 : {
76 : #if HAVE_SSE42
- 77 23710549 : if (tommy_likely(crc_x86)) {
- 78 23710549 : asm("crc32b %1, %0\n" : "+r" (crc) : "m" (c));
- 79 23710549 : return crc;
+ 77 23675077 : if (tommy_likely(crc_x86)) {
+ 78 23675077 : asm("crc32b %1, %0\n" : "+r" (crc) : "m" (c));
+ 79 23675077 : return crc;
80 : }
81 : #endif
82 0 : return CRC32C_0[(crc ^ c) & 0xff] ^ (crc >> 8);
@@ -147,29 +147,29 @@
85 : /**
86 : * Compute the CRC-32 (Castagnoli) without the IV.
87 : */
- 88 337 : static inline uint32_t crc32c_gen_plain(uint32_t crc, const unsigned char* ptr, unsigned size)
+ 88 353 : static inline uint32_t crc32c_gen_plain(uint32_t crc, const unsigned char* ptr, unsigned size)
89 : {
- 90 20972361 : while (size >= 4) {
- 91 20971687 : crc ^= ptr[0] | (uint32_t)ptr[1] << 8 | (uint32_t)ptr[2] << 16 | (uint32_t)ptr[3] << 24;
- 92 20971687 : crc = CRC32C_3[crc & 0xff] ^ CRC32C_2[(crc >> 8) & 0xff] ^ CRC32C_1[(crc >> 16) & 0xff] ^ CRC32C_0[crc >> 24];
- 93 20971687 : ptr += 4;
- 94 20971687 : size -= 4;
+ 90 22020969 : while (size >= 4) {
+ 91 22020263 : crc ^= ptr[0] | (uint32_t)ptr[1] << 8 | (uint32_t)ptr[2] << 16 | (uint32_t)ptr[3] << 24;
+ 92 22020263 : crc = CRC32C_3[crc & 0xff] ^ CRC32C_2[(crc >> 8) & 0xff] ^ CRC32C_1[(crc >> 16) & 0xff] ^ CRC32C_0[crc >> 24];
+ 93 22020263 : ptr += 4;
+ 94 22020263 : size -= 4;
95 : }
96 :
- 97 683 : while (size) {
+ 97 715 : while (size) {
98 9 : crc = CRC32C_0[(crc ^ *ptr) & 0xff] ^ (crc >> 8);
99 9 : ++ptr;
100 9 : --size;
101 : }
102 :
- 103 337 : return crc;
+ 103 353 : return crc;
104 : }
105 :
106 : /**
107 : * Compute the CRC-32 (Castagnoli) without the IV.
108 : */
109 : #if HAVE_SSE42
- 110 131430214 : static inline uint32_t crc32c_x86_plain(uint32_t crc, const unsigned char* ptr, unsigned size)
+ 110 131602718 : static inline uint32_t crc32c_x86_plain(uint32_t crc, const unsigned char* ptr, unsigned size)
111 : {
112 : #ifdef CONFIG_X86_64
113 : uint64_t crc64 = crc;
@@ -180,30 +180,30 @@
118 : }
119 : crc = crc64;
120 : #else
- 121 972142050 : while (size >= 4) {
- 122 709281622 : asm("crc32l %1, %0\n" : "+r" (crc) : "m" (*(const uint32_t*)ptr));
- 123 709281622 : ptr += 4;
- 124 709281622 : size -= 4;
+ 121 969717854 : while (size >= 4) {
+ 122 706512418 : asm("crc32l %1, %0\n" : "+r" (crc) : "m" (*(const uint32_t*)ptr));
+ 123 706512418 : ptr += 4;
+ 124 706512418 : size -= 4;
125 : }
126 : #endif
- 127 382290808 : while (size) {
- 128 119430380 : asm("crc32b %1, %0\n" : "+r" (crc) : "m" (*ptr));
- 129 119430380 : ++ptr;
- 130 119430380 : --size;
+ 127 382941674 : while (size) {
+ 128 119736238 : asm("crc32b %1, %0\n" : "+r" (crc) : "m" (*ptr));
+ 129 119736238 : ++ptr;
+ 130 119736238 : --size;
131 : }
132 :
- 133 131430214 : return crc;
+ 133 131602718 : return crc;
134 : }
135 : #endif
136 :
137 : /**
138 : * Compute CRC-32 (Castagnoli) without the IV.
139 : */
- 140 130044002 : static inline uint32_t crc32c_plain(uint32_t crc, const unsigned char* ptr, unsigned size)
+ 140 128046334 : static inline uint32_t crc32c_plain(uint32_t crc, const unsigned char* ptr, unsigned size)
141 : {
142 : #if HAVE_SSE42
- 143 130044002 : if (tommy_likely(crc_x86)) {
- 144 130044002 : return crc32c_x86_plain(crc, ptr, size);
+ 143 128046334 : if (tommy_likely(crc_x86)) {
+ 144 128046334 : return crc32c_x86_plain(crc, ptr, size);
145 : }
146 : #endif
147 0 : return crc32c_gen_plain(crc, ptr, size);
diff --git a/cov/index-sort-f.html b/cov/index-sort-f.html
index b5b5ab5f..bc18c20f 100644
--- a/cov/index-sort-f.html
+++ b/cov/index-sort-f.html
@@ -31,13 +31,13 @@
|
-
-
+
+
-
+
|
@@ -75,7 +75,7 @@
91.4 % |
- 7341 / 8031 |
+ 7344 / 8033 |
97.7 % |
388 / 397 |
diff --git a/cov/index-sort-l.html b/cov/index-sort-l.html
index 82ba3791..5f59d954 100644
--- a/cov/index-sort-l.html
+++ b/cov/index-sort-l.html
@@ -31,13 +31,13 @@
|
-
-
+
+
-
+
|
@@ -75,7 +75,7 @@
91.4 % |
- 7341 / 8031 |
+ 7344 / 8033 |
97.7 % |
388 / 397 |
diff --git a/cov/index.html b/cov/index.html
index 53c8f1f6..abaf833c 100644
--- a/cov/index.html
+++ b/cov/index.html
@@ -31,13 +31,13 @@
|
-
-
+
+
-
+
|
@@ -75,7 +75,7 @@
91.4 % |
- 7341 / 8031 |
+ 7344 / 8033 |
97.7 % |
388 / 397 |
diff --git a/cov/raid/check.c.func-sort-c.html b/cov/raid/check.c.func-sort-c.html
index bb79ab19..0c9b19f8 100644
--- a/cov/raid/check.c.func-sort-c.html
+++ b/cov/raid/check.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/raid/check.c.func.html b/cov/raid/check.c.func.html
index dc423ebe..eaef437a 100644
--- a/cov/raid/check.c.func.html
+++ b/cov/raid/check.c.func.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/raid/check.c.gcov.html b/cov/raid/check.c.gcov.html
index 94c6c33d..7b809175 100644
--- a/cov/raid/check.c.gcov.html
+++ b/cov/raid/check.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/raid/combo.h.func-sort-c.html b/cov/raid/combo.h.func-sort-c.html
index a906c074..9dc0148a 100644
--- a/cov/raid/combo.h.func-sort-c.html
+++ b/cov/raid/combo.h.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/raid/combo.h.func.html b/cov/raid/combo.h.func.html
index c1c1d847..428b1c38 100644
--- a/cov/raid/combo.h.func.html
+++ b/cov/raid/combo.h.func.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/raid/combo.h.gcov.html b/cov/raid/combo.h.gcov.html
index 8212c725..b8f76138 100644
--- a/cov/raid/combo.h.gcov.html
+++ b/cov/raid/combo.h.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -170,10 +170,10 @@
108 : int i;
109 :
110 : (void)n; /* unused, but kept for clarity */
- 111 215892 : assert(0 < r && r <= n);
+ 111 215930 : assert(0 < r && r <= n);
112 :
- 113 713955 : for (i = 0; i < r; ++i)
- 114 498063 : c[i] = i;
+ 113 713829 : for (i = 0; i < r; ++i)
+ 114 497899 : c[i] = i;
115 : }
116 :
117 : /**
@@ -182,19 +182,19 @@
120 : */
121 : static __always_inline int combination_next(int r, int n, int *c)
122 : {
- 123 51682 : int i = r - 1; /* present position */
- 124 51682 : int h = n; /* high limit for this position */
+ 123 51676 : int i = r - 1; /* present position */
+ 124 51676 : int h = n; /* high limit for this position */
125 :
126 : recurse:
127 : /* next element at position i */
- 128 84555 : ++c[i];
+ 128 84549 : ++c[i];
129 :
130 : /* if the position has reached the max */
- 131 84555 : if (c[i] >= h) {
+ 131 84549 : if (c[i] >= h) {
132 :
133 : /* if we are at the first level, we have finished */
- 134 44861 : if (i == 0)
- 135 11988 : return 0;
+ 134 44859 : if (i == 0)
+ 135 11986 : return 0;
136 :
137 : /* increase the previous position */
138 32873 : --i;
@@ -202,16 +202,16 @@
140 : goto recurse;
141 : }
142 :
- 143 39694 : ++i;
+ 143 39690 : ++i;
144 :
145 : /* initialize all the next positions, if any */
- 146 62239 : while (i < r) {
+ 146 62235 : while (i < r) {
147 : /* each position start at the next value of the previous one */
148 22545 : c[i] = c[i - 1] + 1;
149 22545 : ++i;
150 : }
151 :
- 152 39694 : return 1;
+ 152 39690 : return 1;
153 : }
154 : #endif
155 :
diff --git a/cov/raid/cpu.h.func-sort-c.html b/cov/raid/cpu.h.func-sort-c.html
index 54a94735..8c4e735a 100644
--- a/cov/raid/cpu.h.func-sort-c.html
+++ b/cov/raid/cpu.h.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/raid/cpu.h.func.html b/cov/raid/cpu.h.func.html
index fa1818ef..d313f5e0 100644
--- a/cov/raid/cpu.h.func.html
+++ b/cov/raid/cpu.h.func.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/raid/cpu.h.gcov.html b/cov/raid/cpu.h.gcov.html
index 6fadda4b..af6259db 100644
--- a/cov/raid/cpu.h.gcov.html
+++ b/cov/raid/cpu.h.gcov.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/raid/gf.h.func-sort-c.html b/cov/raid/gf.h.func-sort-c.html
index b9170894..38e50d01 100644
--- a/cov/raid/gf.h.func-sort-c.html
+++ b/cov/raid/gf.h.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/raid/gf.h.func.html b/cov/raid/gf.h.func.html
index a4a7aedc..d99cf543 100644
--- a/cov/raid/gf.h.func.html
+++ b/cov/raid/gf.h.func.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/raid/gf.h.gcov.html b/cov/raid/gf.h.gcov.html
index c9464223..f7076a13 100644
--- a/cov/raid/gf.h.gcov.html
+++ b/cov/raid/gf.h.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -88,7 +88,7 @@
26 : */
27 : static __always_inline uint8_t mul(uint8_t a, uint8_t b)
28 : {
- 29 23816594 : return gfmul[a][b];
+ 29 23813346 : return gfmul[a][b];
30 : }
31 :
32 : /*
@@ -97,9 +97,9 @@
35 : */
36 : static __always_inline uint8_t inv(uint8_t v)
37 : {
- 38 635932 : BUG_ON(v == 0); /* division by zero */
+ 38 635522 : BUG_ON(v == 0); /* division by zero */
39 :
- 40 635932 : return gfinv[v];
+ 40 635522 : return gfinv[v];
41 : }
42 :
43 : /*
@@ -125,7 +125,7 @@
63 : */
64 : static __always_inline uint8_t A(int p, int d)
65 : {
- 66 2606682 : return gfgen[p][d];
+ 66 2605866 : return gfgen[p][d];
67 : }
68 :
69 : /*
diff --git a/cov/raid/helper.c.func-sort-c.html b/cov/raid/helper.c.func-sort-c.html
index 84cfdf7e..47ed9277 100644
--- a/cov/raid/helper.c.func-sort-c.html
+++ b/cov/raid/helper.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/raid/helper.c.func.html b/cov/raid/helper.c.func.html
index b927219b..d1b46f34 100644
--- a/cov/raid/helper.c.func.html
+++ b/cov/raid/helper.c.func.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/raid/helper.c.gcov.html b/cov/raid/helper.c.gcov.html
index 229f4149..16b6e3f4 100644
--- a/cov/raid/helper.c.gcov.html
+++ b/cov/raid/helper.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/raid/index-sort-f.html b/cov/raid/index-sort-f.html
index 72129cda..53f2d677 100644
--- a/cov/raid/index-sort-f.html
+++ b/cov/raid/index-sort-f.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/raid/index-sort-l.html b/cov/raid/index-sort-l.html
index c412a33b..194b0b2c 100644
--- a/cov/raid/index-sort-l.html
+++ b/cov/raid/index-sort-l.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/raid/index.html b/cov/raid/index.html
index 5fecc0b8..c0b34a7b 100644
--- a/cov/raid/index.html
+++ b/cov/raid/index.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/raid/int.c.func-sort-c.html b/cov/raid/int.c.func-sort-c.html
index dc8cdc86..1e9686f8 100644
--- a/cov/raid/int.c.func-sort-c.html
+++ b/cov/raid/int.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -101,7 +101,7 @@
| raid_gen6_int8 |
- 15 |
+ 16 |
diff --git a/cov/raid/int.c.func.html b/cov/raid/int.c.func.html
index e58f1a52..a9474d76 100644
--- a/cov/raid/int.c.func.html
+++ b/cov/raid/int.c.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -89,7 +89,7 @@
| raid_gen6_int8 |
- 15 |
+ 16 |
| raid_rec1_int8 |
diff --git a/cov/raid/int.c.gcov.html b/cov/raid/int.c.gcov.html
index 784c1745..c6a492cd 100644
--- a/cov/raid/int.c.gcov.html
+++ b/cov/raid/int.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -379,9 +379,9 @@
317 : * But this is only a kind of reference function, and we are not really
318 : * interested in speed.
319 : */
- 320 15 : void raid_gen6_int8(int nd, size_t size, void **vv)
+ 320 16 : void raid_gen6_int8(int nd, size_t size, void **vv)
321 : {
- 322 15 : uint8_t **v = (uint8_t **)vv;
+ 322 16 : uint8_t **v = (uint8_t **)vv;
323 : uint8_t *p;
324 : uint8_t *q;
325 : uint8_t *r;
@@ -393,45 +393,45 @@
331 :
332 : uint8_t d0, u0, t0, s0, r0, q0, p0;
333 :
- 334 15 : l = nd - 1;
- 335 15 : p = v[nd];
- 336 15 : q = v[nd + 1];
- 337 15 : r = v[nd + 2];
- 338 15 : s = v[nd + 3];
- 339 15 : t = v[nd + 4];
- 340 15 : u = v[nd + 5];
+ 334 16 : l = nd - 1;
+ 335 16 : p = v[nd];
+ 336 16 : q = v[nd + 1];
+ 337 16 : r = v[nd + 2];
+ 338 16 : s = v[nd + 3];
+ 339 16 : t = v[nd + 4];
+ 340 16 : u = v[nd + 5];
341 :
- 342 3408399 : for (i = 0; i < size; i += 1) {
- 343 3408384 : p0 = q0 = r0 = s0 = t0 = u0 = 0;
- 344 27271424 : for (d = l; d > 0; --d) {
- 345 23863040 : d0 = v_8(v[d][i]);
+ 342 3670544 : for (i = 0; i < size; i += 1) {
+ 343 3670528 : p0 = q0 = r0 = s0 = t0 = u0 = 0;
+ 344 29368576 : for (d = l; d > 0; --d) {
+ 345 25698048 : d0 = v_8(v[d][i]);
346 :
- 347 23863040 : p0 ^= d0;
- 348 23863040 : q0 ^= gfmul[d0][gfgen[1][d]];
- 349 23863040 : r0 ^= gfmul[d0][gfgen[2][d]];
- 350 23863040 : s0 ^= gfmul[d0][gfgen[3][d]];
- 351 23863040 : t0 ^= gfmul[d0][gfgen[4][d]];
- 352 23863040 : u0 ^= gfmul[d0][gfgen[5][d]];
+ 347 25698048 : p0 ^= d0;
+ 348 25698048 : q0 ^= gfmul[d0][gfgen[1][d]];
+ 349 25698048 : r0 ^= gfmul[d0][gfgen[2][d]];
+ 350 25698048 : s0 ^= gfmul[d0][gfgen[3][d]];
+ 351 25698048 : t0 ^= gfmul[d0][gfgen[4][d]];
+ 352 25698048 : u0 ^= gfmul[d0][gfgen[5][d]];
353 : }
354 :
355 : /* first disk with all coefficients at 1 */
- 356 3408384 : d0 = v_8(v[0][i]);
+ 356 3670528 : d0 = v_8(v[0][i]);
357 :
- 358 3408384 : p0 ^= d0;
- 359 3408384 : q0 ^= d0;
- 360 3408384 : r0 ^= d0;
- 361 3408384 : s0 ^= d0;
- 362 3408384 : t0 ^= d0;
- 363 3408384 : u0 ^= d0;
+ 358 3670528 : p0 ^= d0;
+ 359 3670528 : q0 ^= d0;
+ 360 3670528 : r0 ^= d0;
+ 361 3670528 : s0 ^= d0;
+ 362 3670528 : t0 ^= d0;
+ 363 3670528 : u0 ^= d0;
364 :
- 365 3408384 : v_8(p[i]) = p0;
- 366 3408384 : v_8(q[i]) = q0;
- 367 3408384 : v_8(r[i]) = r0;
- 368 3408384 : v_8(s[i]) = s0;
- 369 3408384 : v_8(t[i]) = t0;
- 370 3408384 : v_8(u[i]) = u0;
+ 365 3670528 : v_8(p[i]) = p0;
+ 366 3670528 : v_8(q[i]) = q0;
+ 367 3670528 : v_8(r[i]) = r0;
+ 368 3670528 : v_8(s[i]) = s0;
+ 369 3670528 : v_8(t[i]) = t0;
+ 370 3670528 : v_8(u[i]) = u0;
371 : }
- 372 15 : }
+ 372 16 : }
373 :
374 : /*
375 : * Recover failure of one data block at index id[0] using parity at index
diff --git a/cov/raid/internal.h.func-sort-c.html b/cov/raid/internal.h.func-sort-c.html
index 342c2783..3b75e83e 100644
--- a/cov/raid/internal.h.func-sort-c.html
+++ b/cov/raid/internal.h.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/raid/internal.h.func.html b/cov/raid/internal.h.func.html
index 51989154..ee4ceee8 100644
--- a/cov/raid/internal.h.func.html
+++ b/cov/raid/internal.h.func.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/raid/internal.h.gcov.html b/cov/raid/internal.h.gcov.html
index c3a2c986..3e410102 100644
--- a/cov/raid/internal.h.gcov.html
+++ b/cov/raid/internal.h.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -159,11 +159,11 @@
97 : */
98 : static __always_inline void *__align_ptr(void *ptr, uintptr_t size)
99 : {
- 100 696867 : uintptr_t offset = (uintptr_t)ptr;
+ 100 696987 : uintptr_t offset = (uintptr_t)ptr;
101 :
- 102 696867 : offset = (offset + size - 1U) & ~(size - 1U);
+ 102 696987 : offset = (offset + size - 1U) & ~(size - 1U);
103 :
- 104 696867 : return (void *)offset;
+ 104 696987 : return (void *)offset;
105 : }
106 :
107 : /*
@@ -284,7 +284,7 @@
222 : /* that use a weak memory model. To ensure that other processors */
223 : /* see correctly the data written, we use a store-store memory */
224 : /* barrier at the end of the asm code */
- 225 1365600 : asm volatile ("sfence" : : : "memory");
+ 225 1365700 : asm volatile ("sfence" : : : "memory");
226 :
227 : /* clobbers registers used in the asm code */
228 : /* this is required because in the Windows ABI, */
diff --git a/cov/raid/intz.c.func-sort-c.html b/cov/raid/intz.c.func-sort-c.html
index c6e0e60f..b79b344c 100644
--- a/cov/raid/intz.c.func-sort-c.html
+++ b/cov/raid/intz.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/raid/intz.c.func.html b/cov/raid/intz.c.func.html
index 09e4658c..081fcf8b 100644
--- a/cov/raid/intz.c.func.html
+++ b/cov/raid/intz.c.func.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/raid/intz.c.gcov.html b/cov/raid/intz.c.gcov.html
index 0d481bcf..68473b3c 100644
--- a/cov/raid/intz.c.gcov.html
+++ b/cov/raid/intz.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/raid/memory.c.func-sort-c.html b/cov/raid/memory.c.func-sort-c.html
index b48d9a29..fd1f5017 100644
--- a/cov/raid/memory.c.func-sort-c.html
+++ b/cov/raid/memory.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,7 +61,7 @@
| raid_mtest_vector |
- 2583 |
+ 2579 |
| raid_malloc_align |
diff --git a/cov/raid/memory.c.func.html b/cov/raid/memory.c.func.html
index 92b379d6..25536f02 100644
--- a/cov/raid/memory.c.func.html
+++ b/cov/raid/memory.c.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -73,7 +73,7 @@
| raid_mtest_vector |
- 2583 |
+ 2579 |
diff --git a/cov/raid/memory.c.gcov.html b/cov/raid/memory.c.gcov.html
index 784a9006..3830eccb 100644
--- a/cov/raid/memory.c.gcov.html
+++ b/cov/raid/memory.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -94,7 +94,7 @@
32 290 : offset = ((uintptr_t)ptr) % RAID_MALLOC_ALIGN;
33 :
34 290 : if (offset != 0)
- 35 284 : ptr += RAID_MALLOC_ALIGN - offset;
+ 35 287 : ptr += RAID_MALLOC_ALIGN - offset;
36 :
37 290 : return ptr;
38 : }
@@ -154,9 +154,9 @@
92 : }
93 5 : }
94 :
- 95 2583 : int raid_mtest_vector(int n, size_t size, void **vv)
+ 95 2579 : int raid_mtest_vector(int n, size_t size, void **vv)
96 : {
- 97 2583 : unsigned char **v = (unsigned char **)vv;
+ 97 2579 : unsigned char **v = (unsigned char **)vv;
98 : int i;
99 : size_t j;
100 : unsigned k;
@@ -164,39 +164,39 @@
102 : unsigned char p;
103 :
104 : /* fill with 0 */
- 105 2583 : d = 0;
- 106 5257 : for (i = 0; i < n; ++i)
- 107 136288434 : for (j = 0; j < size; ++j)
- 108 136285760 : v[i][j] = d;
+ 105 2579 : d = 0;
+ 106 5254 : for (i = 0; i < n; ++i)
+ 107 137567034 : for (j = 0; j < size; ++j)
+ 108 137564359 : v[i][j] = d;
109 :
110 : /* test with all the byte patterns */
- 111 661234 : for (k = 1; k < 256; ++k) {
- 112 658651 : p = d;
- 113 658651 : d = k;
+ 111 661244 : for (k = 1; k < 256; ++k) {
+ 112 658661 : p = d;
+ 113 658661 : d = k;
114 :
115 : /* forward fill */
- 116 1340760 : for (i = 0; i < n; ++i) {
- 117 24240075844 : for (j = 0; j < size; ++j) {
- 118 24239393735 : if (v[i][j] != p) {
+ 116 1340781 : for (i = 0; i < n; ++i) {
+ 117 24484944507 : for (j = 0; j < size; ++j) {
+ 118 24484262387 : if (v[i][j] != p) {
119 : /* LCOV_EXCL_START */
120 : return -1;
121 : /* LCOV_EXCL_STOP */
122 : }
- 123 24239393729 : v[i][j] = d;
+ 123 24484262387 : v[i][j] = d;
124 : }
125 : }
126 :
- 127 658645 : p = d;
- 128 658645 : d = ~p;
+ 127 658661 : p = d;
+ 128 658661 : d = ~p;
129 : /* backward fill with complement */
- 130 1340755 : for (i = 0; i < n; ++i) {
- 131 23878874802 : for (j = size; j > 0; --j) {
- 132 23878192692 : if (v[i][j - 1] != p) {
+ 130 1340786 : for (i = 0; i < n; ++i) {
+ 131 24126962138 : for (j = size; j > 0; --j) {
+ 132 24126280013 : if (v[i][j - 1] != p) {
133 : /* LCOV_EXCL_START */
134 : return -1;
135 : /* LCOV_EXCL_STOP */
136 : }
- 137 23878192698 : v[i][j - 1] = d;
+ 137 24126280017 : v[i][j - 1] = d;
138 : }
139 : }
140 : }
diff --git a/cov/raid/module.c.func-sort-c.html b/cov/raid/module.c.func-sort-c.html
index b469fbc8..3a1aa0e0 100644
--- a/cov/raid/module.c.func-sort-c.html
+++ b/cov/raid/module.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/raid/module.c.func.html b/cov/raid/module.c.func.html
index 253ad344..a93ef0a6 100644
--- a/cov/raid/module.c.func.html
+++ b/cov/raid/module.c.func.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/raid/module.c.gcov.html b/cov/raid/module.c.gcov.html
index e51fae4a..5769f207 100644
--- a/cov/raid/module.c.gcov.html
+++ b/cov/raid/module.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/raid/raid.c.func-sort-c.html b/cov/raid/raid.c.func-sort-c.html
index e11a2ac4..77b192da 100644
--- a/cov/raid/raid.c.func-sort-c.html
+++ b/cov/raid/raid.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,27 +61,27 @@
| raid_gen |
- 1212640 |
+ 1212946 |
| raid_data |
- 217819 |
+ 217853 |
| raid_invert |
- 172870 |
+ 172667 |
| raid_delta_gen |
- 171518 |
+ 171311 |
| raid_rec1of1 |
- 104713 |
+ 104953 |
| raid_rec |
- 901 |
+ 900 |
| raid_mode |
diff --git a/cov/raid/raid.c.func.html b/cov/raid/raid.c.func.html
index 8867f809..88ff8f70 100644
--- a/cov/raid/raid.c.func.html
+++ b/cov/raid/raid.c.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,19 +61,19 @@
| raid_data |
- 217819 |
+ 217853 |
| raid_delta_gen |
- 171518 |
+ 171311 |
| raid_gen |
- 1212640 |
+ 1212946 |
| raid_invert |
- 172870 |
+ 172667 |
| raid_mode |
@@ -81,11 +81,11 @@
| raid_rec |
- 901 |
+ 900 |
| raid_rec1of1 |
- 104713 |
+ 104953 |
| raid_rec2of2_int8 |
diff --git a/cov/raid/raid.c.gcov.html b/cov/raid/raid.c.gcov.html
index 2f1d943e..54d53596 100644
--- a/cov/raid/raid.c.gcov.html
+++ b/cov/raid/raid.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -282,17 +282,17 @@
220 : void (*raid_gen3_ptr)(int nd, size_t size, void **vv);
221 : void (*raid_genz_ptr)(int nd, size_t size, void **vv);
222 :
- 223 1212640 : void raid_gen(int nd, int np, size_t size, void **v)
+ 223 1212946 : void raid_gen(int nd, int np, size_t size, void **v)
224 : {
225 : /* enforce limit on size */
- 226 1212640 : BUG_ON(size % 64 != 0);
+ 226 1212946 : BUG_ON(size % 64 != 0);
227 :
228 : /* enforce limit on number of failures */
- 229 1212640 : BUG_ON(np < 1);
- 230 1212640 : BUG_ON(np > RAID_PARITY_MAX);
+ 229 1212946 : BUG_ON(np < 1);
+ 230 1212946 : BUG_ON(np > RAID_PARITY_MAX);
231 :
- 232 1212640 : raid_gen_ptr[np - 1](nd, size, v);
- 233 1212640 : }
+ 232 1212946 : raid_gen_ptr[np - 1](nd, size, v);
+ 233 1212946 : }
234 :
235 : /**
236 : * Inverts the square matrix M of size nxn into V.
@@ -305,44 +305,44 @@
243 : * @V Destination matrix where the result is put.
244 : * @n Number of rows and columns of the matrix.
245 : */
- 246 172870 : void raid_invert(uint8_t *M, uint8_t *V, int n)
+ 246 172667 : void raid_invert(uint8_t *M, uint8_t *V, int n)
247 : {
248 : int i, j, k;
249 :
250 : /* set the identity matrix in V */
- 251 798767 : for (i = 0; i < n; ++i)
- 252 3222808 : for (j = 0; j < n; ++j)
- 253 2596911 : V[i * n + j] = i == j;
+ 251 798158 : for (i = 0; i < n; ++i)
+ 252 3221590 : for (j = 0; j < n; ++j)
+ 253 2596099 : V[i * n + j] = i == j;
254 :
255 : /* for each element in the diagonal */
- 256 798767 : for (k = 0; k < n; ++k) {
+ 256 798158 : for (k = 0; k < n; ++k) {
257 : uint8_t f;
258 :
259 : /* the diagonal element cannot be 0 because */
260 : /* we are inverting matrices with all the square */
261 : /* submatrices not singular */
- 262 625897 : BUG_ON(M[k * n + k] == 0);
+ 262 625491 : BUG_ON(M[k * n + k] == 0);
263 :
264 : /* make the diagonal element to be 1 */
- 265 1251794 : f = inv(M[k * n + k]);
- 266 3222808 : for (j = 0; j < n; ++j) {
- 267 5193822 : M[k * n + j] = mul(f, M[k * n + j]);
- 268 5193822 : V[k * n + j] = mul(f, V[k * n + j]);
+ 265 1250982 : f = inv(M[k * n + k]);
+ 266 3221590 : for (j = 0; j < n; ++j) {
+ 267 5192198 : M[k * n + j] = mul(f, M[k * n + j]);
+ 268 5192198 : V[k * n + j] = mul(f, V[k * n + j]);
269 : }
270 :
271 : /* make all the elements over and under the diagonal */
272 : /* to be zero */
- 273 3222808 : for (i = 0; i < n; ++i) {
- 274 2596911 : if (i == k)
- 275 625897 : continue;
- 276 1971014 : f = M[i * n + k];
- 277 11282400 : for (j = 0; j < n; ++j) {
- 278 18622772 : M[i * n + j] ^= mul(f, M[k * n + j]);
- 279 18622772 : V[i * n + j] ^= mul(f, V[k * n + j]);
+ 273 3221590 : for (i = 0; i < n; ++i) {
+ 274 2596099 : if (i == k)
+ 275 625491 : continue;
+ 276 1970608 : f = M[i * n + k];
+ 277 11281182 : for (j = 0; j < n; ++j) {
+ 278 18621148 : M[i * n + j] ^= mul(f, M[k * n + j]);
+ 279 18621148 : V[i * n + j] ^= mul(f, V[k * n + j]);
280 : }
281 : }
282 : }
- 283 172870 : }
+ 283 172667 : }
284 :
285 : /**
286 : * Computes the parity without the missing data blocks
@@ -350,7 +350,7 @@
288 : *
289 : * This is the parity expressed as Pa,Qa,Ra,Sa,Ta,Ua in the equations.
290 : */
- 291 171518 : void raid_delta_gen(int nr, int *id, int *ip, int nd, size_t size, void **v)
+ 291 171311 : void raid_delta_gen(int nr, int *id, int *ip, int nd, size_t size, void **v)
292 : {
293 : void *p[RAID_PARITY_MAX];
294 : void *pa[RAID_PARITY_MAX];
@@ -360,17 +360,17 @@
298 :
299 : /* total number of parities we are going to process */
300 : /* they are both the used and the unused ones */
- 301 171518 : np = ip[nr - 1] + 1;
+ 301 171311 : np = ip[nr - 1] + 1;
302 :
303 : /* latest missing data block */
- 304 171518 : latest = v[id[nr - 1]];
+ 304 171311 : latest = v[id[nr - 1]];
305 :
306 : /* setup pointers for delta computation */
- 307 873198 : for (i = 0, j = 0; i < np; ++i) {
+ 307 872577 : for (i = 0, j = 0; i < np; ++i) {
308 : /* keep a copy of the original parity vector */
- 309 701680 : p[i] = v[nd + i];
+ 309 701266 : p[i] = v[nd + i];
310 :
- 311 701680 : if (ip[j] == i) {
+ 311 701266 : if (ip[j] == i) {
312 : /*
313 : * Set used parities to point to the missing
314 : * data blocks.
@@ -381,19 +381,19 @@
319 :
320 : /* the latest parity to use ends the for loop and */
321 : /* then it cannot happen to process more of them */
- 322 605871 : BUG_ON(j >= nr);
+ 322 605461 : BUG_ON(j >= nr);
323 :
324 : /* buffer for missing data blocks */
- 325 605871 : pa[j] = v[id[j]];
+ 325 605461 : pa[j] = v[id[j]];
326 :
327 : /* set at zero the missing data blocks */
- 328 605871 : v[id[j]] = raid_zero_block;
+ 328 605461 : v[id[j]] = raid_zero_block;
329 :
330 : /* compute the parity over the missing data blocks */
- 331 605871 : v[nd + i] = pa[j];
+ 331 605461 : v[nd + i] = pa[j];
332 :
333 : /* check for the next used entry */
- 334 605871 : ++j;
+ 334 605461 : ++j;
335 : } else {
336 : /*
337 : * Unused parities are going to be rewritten with
@@ -413,25 +413,25 @@
351 : * multiple times and only the latest write will
352 : * contain the correct data.
353 : */
- 354 95809 : v[nd + i] = latest;
+ 354 95805 : v[nd + i] = latest;
355 : }
356 : }
357 :
358 : /* all the parities have to be processed */
- 359 171518 : BUG_ON(j != nr);
+ 359 171311 : BUG_ON(j != nr);
360 :
361 : /* recompute the parity, note that np may be smaller than the */
362 : /* total number of parities available */
- 363 171518 : raid_gen(nd, np, size, v);
+ 363 171311 : raid_gen(nd, np, size, v);
364 :
365 : /* restore data buffers as before */
- 366 777389 : for (j = 0; j < nr; ++j)
- 367 605871 : v[id[j]] = pa[j];
+ 366 776772 : for (j = 0; j < nr; ++j)
+ 367 605461 : v[id[j]] = pa[j];
368 :
369 : /* restore parity buffers as before */
- 370 873198 : for (i = 0; i < np; ++i)
- 371 701680 : v[nd + i] = p[i];
- 372 171518 : }
+ 370 872577 : for (i = 0; i < np; ++i)
+ 371 701266 : v[nd + i] = p[i];
+ 372 171311 : }
373 :
374 : /**
375 : * Recover failure of one data block for PAR1.
@@ -444,29 +444,29 @@
382 : *
383 : * Dx = Pd
384 : */
- 385 104713 : void raid_rec1of1(int *id, int nd, size_t size, void **v)
+ 385 104953 : void raid_rec1of1(int *id, int nd, size_t size, void **v)
386 : {
387 : void *p;
388 : void *pa;
389 :
390 : /* for PAR1 we can directly compute the missing block */
391 : /* and we don't need to use the zero buffer */
- 392 104713 : p = v[nd];
- 393 104713 : pa = v[id[0]];
+ 392 104953 : p = v[nd];
+ 393 104953 : pa = v[id[0]];
394 :
395 : /* use the parity as missing data block */
- 396 104713 : v[id[0]] = p;
+ 396 104953 : v[id[0]] = p;
397 :
398 : /* compute the parity over the missing data block */
- 399 104713 : v[nd] = pa;
+ 399 104953 : v[nd] = pa;
400 :
401 : /* compute */
- 402 104713 : raid_gen(nd, 1, size, v);
+ 402 104953 : raid_gen(nd, 1, size, v);
403 :
404 : /* restore as before */
- 405 104713 : v[id[0]] = pa;
- 406 104713 : v[nd] = p;
- 407 104713 : }
+ 405 104953 : v[id[0]] = pa;
+ 406 104953 : v[nd] = p;
+ 407 104953 : }
408 :
409 : /**
410 : * Recover failure of two data blocks for PAR2.
@@ -554,97 +554,97 @@
492 : void (*raid_rec_ptr[RAID_PARITY_MAX])(
493 : int nr, int *id, int *ip, int nd, size_t size, void **vv);
494 :
- 495 901 : void raid_rec(int nr, int *ir, int nd, int np, size_t size, void **v)
+ 495 900 : void raid_rec(int nr, int *ir, int nd, int np, size_t size, void **v)
496 : {
497 : int nrd; /* number of data blocks to recover */
498 : int nrp; /* number of parity blocks to recover */
499 :
500 : /* enforce limit on size */
- 501 901 : BUG_ON(size % 64 != 0);
+ 501 900 : BUG_ON(size % 64 != 0);
502 :
503 : /* enforce limit on number of failures */
- 504 901 : BUG_ON(nr > np);
- 505 901 : BUG_ON(np > RAID_PARITY_MAX);
+ 504 900 : BUG_ON(nr > np);
+ 505 900 : BUG_ON(np > RAID_PARITY_MAX);
506 :
507 : /* enforce order in index vector */
- 508 901 : BUG_ON(nr >= 2 && ir[0] >= ir[1]);
- 509 901 : BUG_ON(nr >= 3 && ir[1] >= ir[2]);
- 510 901 : BUG_ON(nr >= 4 && ir[2] >= ir[3]);
- 511 901 : BUG_ON(nr >= 5 && ir[3] >= ir[4]);
- 512 901 : BUG_ON(nr >= 6 && ir[4] >= ir[5]);
+ 508 900 : BUG_ON(nr >= 2 && ir[0] >= ir[1]);
+ 509 900 : BUG_ON(nr >= 3 && ir[1] >= ir[2]);
+ 510 900 : BUG_ON(nr >= 4 && ir[2] >= ir[3]);
+ 511 900 : BUG_ON(nr >= 5 && ir[3] >= ir[4]);
+ 512 900 : BUG_ON(nr >= 6 && ir[4] >= ir[5]);
513 :
514 : /* enforce limit on index vector */
- 515 901 : BUG_ON(nr > 0 && ir[nr-1] >= nd + np);
+ 515 900 : BUG_ON(nr > 0 && ir[nr-1] >= nd + np);
516 :
517 : /* count the number of data blocks to recover */
- 518 901 : nrd = 0;
- 519 3607 : while (nrd < nr && ir[nrd] < nd)
- 520 1805 : ++nrd;
+ 518 900 : nrd = 0;
+ 519 3603 : while (nrd < nr && ir[nrd] < nd)
+ 520 1803 : ++nrd;
521 :
522 : /* all the remaining are parity */
- 523 901 : nrp = nr - nrd;
+ 523 900 : nrp = nr - nrd;
524 :
525 : /* enforce limit on number of failures */
- 526 901 : BUG_ON(nrd > nd);
- 527 901 : BUG_ON(nrp > np);
+ 526 900 : BUG_ON(nrd > nd);
+ 527 900 : BUG_ON(nrp > np);
528 :
529 : /* if failed data is present */
- 530 901 : if (nrd != 0) {
+ 530 900 : if (nrd != 0) {
531 : int ip[RAID_PARITY_MAX];
532 : int i, j, k;
533 :
534 : /* setup the vector of parities to use */
- 535 6258 : for (i = 0, j = 0, k = 0; i < np; ++i) {
- 536 5359 : if (j < nrp && ir[nrd + j] == nd + i) {
+ 535 6251 : for (i = 0, j = 0, k = 0; i < np; ++i) {
+ 536 5353 : if (j < nrp && ir[nrd + j] == nd + i) {
537 : /* this parity has to be recovered */
538 22 : ++j;
539 : } else {
540 : /* this parity is used for recovering */
- 541 5337 : ip[k] = i;
- 542 5337 : ++k;
+ 541 5331 : ip[k] = i;
+ 542 5331 : ++k;
543 : }
544 : }
545 :
546 : /* recover the nrd data blocks specified in ir[], */
547 : /* using the first nrd parity in ip[] for recovering */
- 548 899 : raid_rec_ptr[nrd - 1](nrd, ir, ip, nd, size, v);
+ 548 898 : raid_rec_ptr[nrd - 1](nrd, ir, ip, nd, size, v);
549 : }
550 :
551 : /* recompute all the parities up to the last bad one */
- 552 901 : if (nrp != 0)
+ 552 900 : if (nrp != 0)
553 12 : raid_gen(nd, ir[nr - 1] - nd + 1, size, v);
- 554 901 : }
+ 554 900 : }
555 :
- 556 217819 : void raid_data(int nr, int *id, int *ip, int nd, size_t size, void **v)
+ 556 217853 : void raid_data(int nr, int *id, int *ip, int nd, size_t size, void **v)
557 : {
558 : /* enforce limit on size */
- 559 217819 : BUG_ON(size % 64 != 0);
+ 559 217853 : BUG_ON(size % 64 != 0);
560 :
561 : /* enforce limit on number of failures */
- 562 217819 : BUG_ON(nr > nd);
- 563 217819 : BUG_ON(nr > RAID_PARITY_MAX);
+ 562 217853 : BUG_ON(nr > nd);
+ 563 217853 : BUG_ON(nr > RAID_PARITY_MAX);
564 :
565 : /* enforce order in index vector for data */
- 566 217819 : BUG_ON(nr >= 2 && id[0] >= id[1]);
- 567 217819 : BUG_ON(nr >= 3 && id[1] >= id[2]);
- 568 217819 : BUG_ON(nr >= 4 && id[2] >= id[3]);
- 569 217819 : BUG_ON(nr >= 5 && id[3] >= id[4]);
- 570 217819 : BUG_ON(nr >= 6 && id[4] >= id[5]);
+ 566 217853 : BUG_ON(nr >= 2 && id[0] >= id[1]);
+ 567 217853 : BUG_ON(nr >= 3 && id[1] >= id[2]);
+ 568 217853 : BUG_ON(nr >= 4 && id[2] >= id[3]);
+ 569 217853 : BUG_ON(nr >= 5 && id[3] >= id[4]);
+ 570 217853 : BUG_ON(nr >= 6 && id[4] >= id[5]);
571 :
572 : /* enforce limit on index vector for data */
- 573 217819 : BUG_ON(nr > 0 && id[nr-1] >= nd);
+ 573 217853 : BUG_ON(nr > 0 && id[nr-1] >= nd);
574 :
575 : /* enforce order in index vector for parity */
- 576 217819 : BUG_ON(nr >= 2 && ip[0] >= ip[1]);
- 577 217819 : BUG_ON(nr >= 3 && ip[1] >= ip[2]);
- 578 217819 : BUG_ON(nr >= 4 && ip[2] >= ip[3]);
- 579 217819 : BUG_ON(nr >= 5 && ip[3] >= ip[4]);
- 580 217819 : BUG_ON(nr >= 6 && ip[4] >= ip[5]);
+ 576 217853 : BUG_ON(nr >= 2 && ip[0] >= ip[1]);
+ 577 217853 : BUG_ON(nr >= 3 && ip[1] >= ip[2]);
+ 578 217853 : BUG_ON(nr >= 4 && ip[2] >= ip[3]);
+ 579 217853 : BUG_ON(nr >= 5 && ip[3] >= ip[4]);
+ 580 217853 : BUG_ON(nr >= 6 && ip[4] >= ip[5]);
581 :
582 : /* if failed data is present */
- 583 217819 : if (nr != 0)
- 584 217817 : raid_rec_ptr[nr - 1](nr, id, ip, nd, size, v);
- 585 217819 : }
+ 583 217853 : if (nr != 0)
+ 584 217851 : raid_rec_ptr[nr - 1](nr, id, ip, nd, size, v);
+ 585 217853 : }
586 :
diff --git a/cov/raid/tag.c.func-sort-c.html b/cov/raid/tag.c.func-sort-c.html
index b103e719..31c0d253 100644
--- a/cov/raid/tag.c.func-sort-c.html
+++ b/cov/raid/tag.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/raid/tag.c.func.html b/cov/raid/tag.c.func.html
index 93261ea2..14aa49dc 100644
--- a/cov/raid/tag.c.func.html
+++ b/cov/raid/tag.c.func.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/raid/tag.c.gcov.html b/cov/raid/tag.c.gcov.html
index bb65c21e..942fdb77 100644
--- a/cov/raid/tag.c.gcov.html
+++ b/cov/raid/tag.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/raid/test.c.func-sort-c.html b/cov/raid/test.c.func-sort-c.html
index 4bb39850..98effa0b 100644
--- a/cov/raid/test.c.func-sort-c.html
+++ b/cov/raid/test.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/raid/test.c.func.html b/cov/raid/test.c.func.html
index 89e4ad2c..7a09c565 100644
--- a/cov/raid/test.c.func.html
+++ b/cov/raid/test.c.func.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/raid/test.c.gcov.html b/cov/raid/test.c.gcov.html
index eda1d7c4..6104fd17 100644
--- a/cov/raid/test.c.gcov.html
+++ b/cov/raid/test.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/raid/x86.c.func-sort-c.html b/cov/raid/x86.c.func-sort-c.html
index f6f0d5a9..5c4222d3 100644
--- a/cov/raid/x86.c.func-sort-c.html
+++ b/cov/raid/x86.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,19 +61,19 @@
| raid_gen6_ssse3 |
- 549547 |
+ 549666 |
| raid_gen2_sse2 |
- 276700 |
+ 276492 |
| raid_gen1_sse2 |
- 272945 |
+ 273337 |
| raid_rec1_ssse3 |
- 114194 |
+ 114430 |
| raid_recX_ssse3 |
@@ -81,19 +81,19 @@
| raid_gen5_ssse3 |
- 50257 |
+ 50258 |
| raid_rec2_ssse3 |
- 44409 |
+ 44206 |
| raid_gen4_ssse3 |
- 32611 |
+ 32613 |
| raid_gen3_ssse3 |
- 29450 |
+ 29451 |
| raid_recX_avx2 |
diff --git a/cov/raid/x86.c.func.html b/cov/raid/x86.c.func.html
index 6a37a421..adc9e8a9 100644
--- a/cov/raid/x86.c.func.html
+++ b/cov/raid/x86.c.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -65,7 +65,7 @@
| raid_gen1_sse2 |
- 272945 |
+ 273337 |
| raid_gen2_avx2 |
@@ -73,23 +73,23 @@
| raid_gen2_sse2 |
- 276700 |
+ 276492 |
| raid_gen3_ssse3 |
- 29450 |
+ 29451 |
| raid_gen4_ssse3 |
- 32611 |
+ 32613 |
| raid_gen5_ssse3 |
- 50257 |
+ 50258 |
| raid_gen6_ssse3 |
- 549547 |
+ 549666 |
| raid_rec1_avx2 |
@@ -97,7 +97,7 @@
| raid_rec1_ssse3 |
- 114194 |
+ 114430 |
| raid_rec2_avx2 |
@@ -105,7 +105,7 @@
| raid_rec2_ssse3 |
- 44409 |
+ 44206 |
| raid_recX_avx2 |
diff --git a/cov/raid/x86.c.gcov.html b/cov/raid/x86.c.gcov.html
index 9f5fbebe..8835cf3b 100644
--- a/cov/raid/x86.c.gcov.html
+++ b/cov/raid/x86.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -95,37 +95,37 @@
33 : * cache block, and processing 128 bytes doesn't increase performance, and in
34 : * some cases it even decreases it.
35 : */
- 36 272945 : void raid_gen1_sse2(int nd, size_t size, void **vv)
+ 36 273337 : void raid_gen1_sse2(int nd, size_t size, void **vv)
37 : {
- 38 272945 : uint8_t **v = (uint8_t **)vv;
+ 38 273337 : uint8_t **v = (uint8_t **)vv;
39 : uint8_t *p;
40 : int d, l;
41 : size_t i;
42 :
- 43 272945 : l = nd - 1;
- 44 272945 : p = v[nd];
+ 43 273337 : l = nd - 1;
+ 44 273337 : p = v[nd];
45 :
46 : raid_sse_begin();
47 :
- 48 5896669 : for (i = 0; i < size; i += 64) {
- 49 5623724 : asm volatile ("movdqa %0,%%xmm0" : : "m" (v[l][i]));
- 50 5623724 : asm volatile ("movdqa %0,%%xmm1" : : "m" (v[l][i + 16]));
- 51 5623724 : asm volatile ("movdqa %0,%%xmm2" : : "m" (v[l][i + 32]));
- 52 5623724 : asm volatile ("movdqa %0,%%xmm3" : : "m" (v[l][i + 48]));
- 53 36265668 : for (d = l - 1; d >= 0; --d) {
- 54 30641944 : asm volatile ("pxor %0,%%xmm0" : : "m" (v[d][i]));
- 55 30641944 : asm volatile ("pxor %0,%%xmm1" : : "m" (v[d][i + 16]));
- 56 30641944 : asm volatile ("pxor %0,%%xmm2" : : "m" (v[d][i + 32]));
- 57 30641944 : asm volatile ("pxor %0,%%xmm3" : : "m" (v[d][i + 48]));
+ 48 5895173 : for (i = 0; i < size; i += 64) {
+ 49 5621836 : asm volatile ("movdqa %0,%%xmm0" : : "m" (v[l][i]));
+ 50 5621836 : asm volatile ("movdqa %0,%%xmm1" : : "m" (v[l][i + 16]));
+ 51 5621836 : asm volatile ("movdqa %0,%%xmm2" : : "m" (v[l][i + 32]));
+ 52 5621836 : asm volatile ("movdqa %0,%%xmm3" : : "m" (v[l][i + 48]));
+ 53 36237956 : for (d = l - 1; d >= 0; --d) {
+ 54 30616120 : asm volatile ("pxor %0,%%xmm0" : : "m" (v[d][i]));
+ 55 30616120 : asm volatile ("pxor %0,%%xmm1" : : "m" (v[d][i + 16]));
+ 56 30616120 : asm volatile ("pxor %0,%%xmm2" : : "m" (v[d][i + 32]));
+ 57 30616120 : asm volatile ("pxor %0,%%xmm3" : : "m" (v[d][i + 48]));
58 : }
- 59 5623724 : asm volatile ("movntdq %%xmm0,%0" : "=m" (p[i]));
- 60 5623724 : asm volatile ("movntdq %%xmm1,%0" : "=m" (p[i + 16]));
- 61 5623724 : asm volatile ("movntdq %%xmm2,%0" : "=m" (p[i + 32]));
- 62 5623724 : asm volatile ("movntdq %%xmm3,%0" : "=m" (p[i + 48]));
+ 59 5621836 : asm volatile ("movntdq %%xmm0,%0" : "=m" (p[i]));
+ 60 5621836 : asm volatile ("movntdq %%xmm1,%0" : "=m" (p[i + 16]));
+ 61 5621836 : asm volatile ("movntdq %%xmm2,%0" : "=m" (p[i + 32]));
+ 62 5621836 : asm volatile ("movntdq %%xmm3,%0" : "=m" (p[i + 48]));
63 : }
64 :
65 : raid_sse_end();
- 66 272945 : }
+ 66 273337 : }
67 : #endif
68 :
69 : #if defined(CONFIG_X86) && defined(CONFIG_AVX2)
@@ -183,54 +183,54 @@
121 : /*
122 : * GEN2 (RAID6 with powers of 2) SSE2 implementation
123 : */
- 124 276700 : void raid_gen2_sse2(int nd, size_t size, void **vv)
+ 124 276492 : void raid_gen2_sse2(int nd, size_t size, void **vv)
125 : {
- 126 276700 : uint8_t **v = (uint8_t **)vv;
+ 126 276492 : uint8_t **v = (uint8_t **)vv;
127 : uint8_t *p;
128 : uint8_t *q;
129 : int d, l;
130 : size_t i;
131 :
- 132 276700 : l = nd - 1;
- 133 276700 : p = v[nd];
- 134 276700 : q = v[nd + 1];
+ 132 276492 : l = nd - 1;
+ 133 276492 : p = v[nd];
+ 134 276492 : q = v[nd + 1];
135 :
136 : raid_sse_begin();
137 :
- 138 276700 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.poly[0]));
+ 138 276492 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.poly[0]));
139 :
- 140 11089428 : for (i = 0; i < size; i += 32) {
- 141 10812728 : asm volatile ("movdqa %0,%%xmm0" : : "m" (v[l][i]));
- 142 10812728 : asm volatile ("movdqa %0,%%xmm1" : : "m" (v[l][i + 16]));
- 143 10812728 : asm volatile ("movdqa %xmm0,%xmm2");
- 144 10812728 : asm volatile ("movdqa %xmm1,%xmm3");
- 145 68808904 : for (d = l - 1; d >= 0; --d) {
- 146 57996176 : asm volatile ("pxor %xmm4,%xmm4");
- 147 57996176 : asm volatile ("pxor %xmm5,%xmm5");
- 148 57996176 : asm volatile ("pcmpgtb %xmm2,%xmm4");
- 149 57996176 : asm volatile ("pcmpgtb %xmm3,%xmm5");
- 150 57996176 : asm volatile ("paddb %xmm2,%xmm2");
- 151 57996176 : asm volatile ("paddb %xmm3,%xmm3");
- 152 57996176 : asm volatile ("pand %xmm7,%xmm4");
- 153 57996176 : asm volatile ("pand %xmm7,%xmm5");
- 154 57996176 : asm volatile ("pxor %xmm4,%xmm2");
- 155 57996176 : asm volatile ("pxor %xmm5,%xmm3");
+ 140 11074404 : for (i = 0; i < size; i += 32) {
+ 141 10797912 : asm volatile ("movdqa %0,%%xmm0" : : "m" (v[l][i]));
+ 142 10797912 : asm volatile ("movdqa %0,%%xmm1" : : "m" (v[l][i + 16]));
+ 143 10797912 : asm volatile ("movdqa %xmm0,%xmm2");
+ 144 10797912 : asm volatile ("movdqa %xmm1,%xmm3");
+ 145 68703624 : for (d = l - 1; d >= 0; --d) {
+ 146 57905712 : asm volatile ("pxor %xmm4,%xmm4");
+ 147 57905712 : asm volatile ("pxor %xmm5,%xmm5");
+ 148 57905712 : asm volatile ("pcmpgtb %xmm2,%xmm4");
+ 149 57905712 : asm volatile ("pcmpgtb %xmm3,%xmm5");
+ 150 57905712 : asm volatile ("paddb %xmm2,%xmm2");
+ 151 57905712 : asm volatile ("paddb %xmm3,%xmm3");
+ 152 57905712 : asm volatile ("pand %xmm7,%xmm4");
+ 153 57905712 : asm volatile ("pand %xmm7,%xmm5");
+ 154 57905712 : asm volatile ("pxor %xmm4,%xmm2");
+ 155 57905712 : asm volatile ("pxor %xmm5,%xmm3");
156 :
- 157 57996176 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[d][i]));
- 158 57996176 : asm volatile ("movdqa %0,%%xmm5" : : "m" (v[d][i + 16]));
- 159 57996176 : asm volatile ("pxor %xmm4,%xmm0");
- 160 57996176 : asm volatile ("pxor %xmm5,%xmm1");
- 161 57996176 : asm volatile ("pxor %xmm4,%xmm2");
- 162 57996176 : asm volatile ("pxor %xmm5,%xmm3");
+ 157 57905712 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[d][i]));
+ 158 57905712 : asm volatile ("movdqa %0,%%xmm5" : : "m" (v[d][i + 16]));
+ 159 57905712 : asm volatile ("pxor %xmm4,%xmm0");
+ 160 57905712 : asm volatile ("pxor %xmm5,%xmm1");
+ 161 57905712 : asm volatile ("pxor %xmm4,%xmm2");
+ 162 57905712 : asm volatile ("pxor %xmm5,%xmm3");
163 : }
- 164 10812728 : asm volatile ("movntdq %%xmm0,%0" : "=m" (p[i]));
- 165 10812728 : asm volatile ("movntdq %%xmm1,%0" : "=m" (p[i + 16]));
- 166 10812728 : asm volatile ("movntdq %%xmm2,%0" : "=m" (q[i]));
- 167 10812728 : asm volatile ("movntdq %%xmm3,%0" : "=m" (q[i + 16]));
+ 164 10797912 : asm volatile ("movntdq %%xmm0,%0" : "=m" (p[i]));
+ 165 10797912 : asm volatile ("movntdq %%xmm1,%0" : "=m" (p[i + 16]));
+ 166 10797912 : asm volatile ("movntdq %%xmm2,%0" : "=m" (q[i]));
+ 167 10797912 : asm volatile ("movntdq %%xmm3,%0" : "=m" (q[i + 16]));
168 : }
169 :
170 : raid_sse_end();
- 171 276700 : }
+ 171 276492 : }
172 : #endif
173 :
174 : #if defined(CONFIG_X86) && defined(CONFIG_AVX2)
@@ -370,93 +370,93 @@
308 : /*
309 : * GEN3 (triple parity with Cauchy matrix) SSSE3 implementation
310 : */
- 311 29450 : void raid_gen3_ssse3(int nd, size_t size, void **vv)
+ 311 29451 : void raid_gen3_ssse3(int nd, size_t size, void **vv)
312 : {
- 313 29450 : uint8_t **v = (uint8_t **)vv;
+ 313 29451 : uint8_t **v = (uint8_t **)vv;
314 : uint8_t *p;
315 : uint8_t *q;
316 : uint8_t *r;
317 : int d, l;
318 : size_t i;
319 :
- 320 29450 : l = nd - 1;
- 321 29450 : p = v[nd];
- 322 29450 : q = v[nd + 1];
- 323 29450 : r = v[nd + 2];
+ 320 29451 : l = nd - 1;
+ 321 29451 : p = v[nd];
+ 322 29451 : q = v[nd + 1];
+ 323 29451 : r = v[nd + 2];
324 :
325 : /* special case with only one data disk */
- 326 29450 : if (l == 0) {
+ 326 29451 : if (l == 0) {
327 4 : for (i = 0; i < 3; ++i)
328 3 : memcpy(v[1 + i], v[0], size);
- 329 29451 : return;
+ 329 29452 : return;
330 : }
331 :
332 : raid_sse_begin();
333 :
334 : /* generic case with at least two data disks */
- 335 29449 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfconst16.poly[0]));
- 336 29449 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0]));
+ 335 29450 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfconst16.poly[0]));
+ 336 29450 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0]));
337 :
- 338 4899161 : for (i = 0; i < size; i += 16) {
+ 338 4915546 : for (i = 0; i < size; i += 16) {
339 : /* last disk without the by two multiplication */
- 340 4869712 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[l][i]));
+ 340 4886096 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[l][i]));
341 :
- 342 4869712 : asm volatile ("movdqa %xmm4,%xmm0");
- 343 4869712 : asm volatile ("movdqa %xmm4,%xmm1");
+ 342 4886096 : asm volatile ("movdqa %xmm4,%xmm0");
+ 343 4886096 : asm volatile ("movdqa %xmm4,%xmm1");
344 :
- 345 4869712 : asm volatile ("movdqa %xmm4,%xmm5");
- 346 4869712 : asm volatile ("psrlw $4,%xmm5");
- 347 4869712 : asm volatile ("pand %xmm7,%xmm4");
- 348 4869712 : asm volatile ("pand %xmm7,%xmm5");
+ 345 4886096 : asm volatile ("movdqa %xmm4,%xmm5");
+ 346 4886096 : asm volatile ("psrlw $4,%xmm5");
+ 347 4886096 : asm volatile ("pand %xmm7,%xmm4");
+ 348 4886096 : asm volatile ("pand %xmm7,%xmm5");
349 :
- 350 4869712 : asm volatile ("movdqa %0,%%xmm2" : : "m" (gfgenpshufb[l][0][0][0]));
- 351 4869712 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[l][0][1][0]));
- 352 4869712 : asm volatile ("pshufb %xmm4,%xmm2");
- 353 4869712 : asm volatile ("pshufb %xmm5,%xmm6");
- 354 4869712 : asm volatile ("pxor %xmm6,%xmm2");
+ 350 4886096 : asm volatile ("movdqa %0,%%xmm2" : : "m" (gfgenpshufb[l][0][0][0]));
+ 351 4886096 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[l][0][1][0]));
+ 352 4886096 : asm volatile ("pshufb %xmm4,%xmm2");
+ 353 4886096 : asm volatile ("pshufb %xmm5,%xmm6");
+ 354 4886096 : asm volatile ("pxor %xmm6,%xmm2");
355 :
356 : /* intermediate disks */
- 357 30574256 : for (d = l - 1; d > 0; --d) {
- 358 25704544 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[d][i]));
+ 357 30688944 : for (d = l - 1; d > 0; --d) {
+ 358 25802848 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[d][i]));
359 :
- 360 25704544 : asm volatile ("pxor %xmm5,%xmm5");
- 361 25704544 : asm volatile ("pcmpgtb %xmm1,%xmm5");
- 362 25704544 : asm volatile ("paddb %xmm1,%xmm1");
- 363 25704544 : asm volatile ("pand %xmm3,%xmm5");
- 364 25704544 : asm volatile ("pxor %xmm5,%xmm1");
+ 360 25802848 : asm volatile ("pxor %xmm5,%xmm5");
+ 361 25802848 : asm volatile ("pcmpgtb %xmm1,%xmm5");
+ 362 25802848 : asm volatile ("paddb %xmm1,%xmm1");
+ 363 25802848 : asm volatile ("pand %xmm3,%xmm5");
+ 364 25802848 : asm volatile ("pxor %xmm5,%xmm1");
365 :
- 366 25704544 : asm volatile ("pxor %xmm4,%xmm0");
- 367 25704544 : asm volatile ("pxor %xmm4,%xmm1");
+ 366 25802848 : asm volatile ("pxor %xmm4,%xmm0");
+ 367 25802848 : asm volatile ("pxor %xmm4,%xmm1");
368 :
- 369 25704544 : asm volatile ("movdqa %xmm4,%xmm5");
- 370 25704544 : asm volatile ("psrlw $4,%xmm5");
- 371 25704544 : asm volatile ("pand %xmm7,%xmm4");
- 372 25704544 : asm volatile ("pand %xmm7,%xmm5");
+ 369 25802848 : asm volatile ("movdqa %xmm4,%xmm5");
+ 370 25802848 : asm volatile ("psrlw $4,%xmm5");
+ 371 25802848 : asm volatile ("pand %xmm7,%xmm4");
+ 372 25802848 : asm volatile ("pand %xmm7,%xmm5");
373 :
- 374 25704544 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][0][0][0]));
- 375 25704544 : asm volatile ("pshufb %xmm4,%xmm6");
- 376 25704544 : asm volatile ("pxor %xmm6,%xmm2");
- 377 25704544 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][0][1][0]));
- 378 25704544 : asm volatile ("pshufb %xmm5,%xmm6");
- 379 25704544 : asm volatile ("pxor %xmm6,%xmm2");
+ 374 25802848 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][0][0][0]));
+ 375 25802848 : asm volatile ("pshufb %xmm4,%xmm6");
+ 376 25802848 : asm volatile ("pxor %xmm6,%xmm2");
+ 377 25802848 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][0][1][0]));
+ 378 25802848 : asm volatile ("pshufb %xmm5,%xmm6");
+ 379 25802848 : asm volatile ("pxor %xmm6,%xmm2");
380 : }
381 :
382 : /* first disk with all coefficients at 1 */
- 383 4869712 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[0][i]));
+ 383 4886096 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[0][i]));
384 :
- 385 4869712 : asm volatile ("pxor %xmm5,%xmm5");
- 386 4869712 : asm volatile ("pcmpgtb %xmm1,%xmm5");
- 387 4869712 : asm volatile ("paddb %xmm1,%xmm1");
- 388 4869712 : asm volatile ("pand %xmm3,%xmm5");
- 389 4869712 : asm volatile ("pxor %xmm5,%xmm1");
+ 385 4886096 : asm volatile ("pxor %xmm5,%xmm5");
+ 386 4886096 : asm volatile ("pcmpgtb %xmm1,%xmm5");
+ 387 4886096 : asm volatile ("paddb %xmm1,%xmm1");
+ 388 4886096 : asm volatile ("pand %xmm3,%xmm5");
+ 389 4886096 : asm volatile ("pxor %xmm5,%xmm1");
390 :
- 391 4869712 : asm volatile ("pxor %xmm4,%xmm0");
- 392 4869712 : asm volatile ("pxor %xmm4,%xmm1");
- 393 4869712 : asm volatile ("pxor %xmm4,%xmm2");
+ 391 4886096 : asm volatile ("pxor %xmm4,%xmm0");
+ 392 4886096 : asm volatile ("pxor %xmm4,%xmm1");
+ 393 4886096 : asm volatile ("pxor %xmm4,%xmm2");
394 :
- 395 4869712 : asm volatile ("movntdq %%xmm0,%0" : "=m" (p[i]));
- 396 4869712 : asm volatile ("movntdq %%xmm1,%0" : "=m" (q[i]));
- 397 4869712 : asm volatile ("movntdq %%xmm2,%0" : "=m" (r[i]));
+ 395 4886096 : asm volatile ("movntdq %%xmm0,%0" : "=m" (p[i]));
+ 396 4886096 : asm volatile ("movntdq %%xmm1,%0" : "=m" (q[i]));
+ 397 4886096 : asm volatile ("movntdq %%xmm2,%0" : "=m" (r[i]));
398 : }
399 :
400 : raid_sse_end();
@@ -741,9 +741,9 @@
679 : /*
680 : * GEN4 (quad parity with Cauchy matrix) SSSE3 implementation
681 : */
- 682 32611 : void raid_gen4_ssse3(int nd, size_t size, void **vv)
+ 682 32613 : void raid_gen4_ssse3(int nd, size_t size, void **vv)
683 : {
- 684 32611 : uint8_t **v = (uint8_t **)vv;
+ 684 32613 : uint8_t **v = (uint8_t **)vv;
685 : uint8_t *p;
686 : uint8_t *q;
687 : uint8_t *r;
@@ -751,102 +751,102 @@
689 : int d, l;
690 : size_t i;
691 :
- 692 32611 : l = nd - 1;
- 693 32611 : p = v[nd];
- 694 32611 : q = v[nd + 1];
- 695 32611 : r = v[nd + 2];
- 696 32611 : s = v[nd + 3];
+ 692 32613 : l = nd - 1;
+ 693 32613 : p = v[nd];
+ 694 32613 : q = v[nd + 1];
+ 695 32613 : r = v[nd + 2];
+ 696 32613 : s = v[nd + 3];
697 :
698 : /* special case with only one data disk */
- 699 32611 : if (l == 0) {
+ 699 32613 : if (l == 0) {
700 5 : for (i = 0; i < 4; ++i)
701 4 : memcpy(v[1 + i], v[0], size);
- 702 32612 : return;
+ 702 32614 : return;
703 : }
704 :
705 : raid_sse_begin();
706 :
707 : /* generic case with at least two data disks */
- 708 3344034 : for (i = 0; i < size; i += 16) {
+ 708 3376804 : for (i = 0; i < size; i += 16) {
709 : /* last disk without the by two multiplication */
- 710 3311424 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0]));
- 711 3311424 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[l][i]));
+ 710 3344192 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0]));
+ 711 3344192 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[l][i]));
712 :
- 713 3311424 : asm volatile ("movdqa %xmm4,%xmm0");
- 714 3311424 : asm volatile ("movdqa %xmm4,%xmm1");
+ 713 3344192 : asm volatile ("movdqa %xmm4,%xmm0");
+ 714 3344192 : asm volatile ("movdqa %xmm4,%xmm1");
715 :
- 716 3311424 : asm volatile ("movdqa %xmm4,%xmm5");
- 717 3311424 : asm volatile ("psrlw $4,%xmm5");
- 718 3311424 : asm volatile ("pand %xmm7,%xmm4");
- 719 3311424 : asm volatile ("pand %xmm7,%xmm5");
+ 716 3344192 : asm volatile ("movdqa %xmm4,%xmm5");
+ 717 3344192 : asm volatile ("psrlw $4,%xmm5");
+ 718 3344192 : asm volatile ("pand %xmm7,%xmm4");
+ 719 3344192 : asm volatile ("pand %xmm7,%xmm5");
720 :
- 721 3311424 : asm volatile ("movdqa %0,%%xmm2" : : "m" (gfgenpshufb[l][0][0][0]));
- 722 3311424 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][0][1][0]));
- 723 3311424 : asm volatile ("pshufb %xmm4,%xmm2");
- 724 3311424 : asm volatile ("pshufb %xmm5,%xmm7");
- 725 3311424 : asm volatile ("pxor %xmm7,%xmm2");
+ 721 3344192 : asm volatile ("movdqa %0,%%xmm2" : : "m" (gfgenpshufb[l][0][0][0]));
+ 722 3344192 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][0][1][0]));
+ 723 3344192 : asm volatile ("pshufb %xmm4,%xmm2");
+ 724 3344192 : asm volatile ("pshufb %xmm5,%xmm7");
+ 725 3344192 : asm volatile ("pxor %xmm7,%xmm2");
726 :
- 727 3311424 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfgenpshufb[l][1][0][0]));
- 728 3311424 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][1][1][0]));
- 729 3311424 : asm volatile ("pshufb %xmm4,%xmm3");
- 730 3311424 : asm volatile ("pshufb %xmm5,%xmm7");
- 731 3311424 : asm volatile ("pxor %xmm7,%xmm3");
+ 727 3344192 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfgenpshufb[l][1][0][0]));
+ 728 3344192 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][1][1][0]));
+ 729 3344192 : asm volatile ("pshufb %xmm4,%xmm3");
+ 730 3344192 : asm volatile ("pshufb %xmm5,%xmm7");
+ 731 3344192 : asm volatile ("pxor %xmm7,%xmm3");
732 :
733 : /* intermediate disks */
- 734 19816832 : for (d = l - 1; d > 0; --d) {
- 735 16505408 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.poly[0]));
- 736 16505408 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[d][i]));
+ 734 20046208 : for (d = l - 1; d > 0; --d) {
+ 735 16702016 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.poly[0]));
+ 736 16702016 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[d][i]));
737 :
- 738 16505408 : asm volatile ("pxor %xmm5,%xmm5");
- 739 16505408 : asm volatile ("pcmpgtb %xmm1,%xmm5");
- 740 16505408 : asm volatile ("paddb %xmm1,%xmm1");
- 741 16505408 : asm volatile ("pand %xmm7,%xmm5");
- 742 16505408 : asm volatile ("pxor %xmm5,%xmm1");
+ 738 16702016 : asm volatile ("pxor %xmm5,%xmm5");
+ 739 16702016 : asm volatile ("pcmpgtb %xmm1,%xmm5");
+ 740 16702016 : asm volatile ("paddb %xmm1,%xmm1");
+ 741 16702016 : asm volatile ("pand %xmm7,%xmm5");
+ 742 16702016 : asm volatile ("pxor %xmm5,%xmm1");
743 :
- 744 16505408 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0]));
+ 744 16702016 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0]));
745 :
- 746 16505408 : asm volatile ("pxor %xmm4,%xmm0");
- 747 16505408 : asm volatile ("pxor %xmm4,%xmm1");
+ 746 16702016 : asm volatile ("pxor %xmm4,%xmm0");
+ 747 16702016 : asm volatile ("pxor %xmm4,%xmm1");
748 :
- 749 16505408 : asm volatile ("movdqa %xmm4,%xmm5");
- 750 16505408 : asm volatile ("psrlw $4,%xmm5");
- 751 16505408 : asm volatile ("pand %xmm7,%xmm4");
- 752 16505408 : asm volatile ("pand %xmm7,%xmm5");
+ 749 16702016 : asm volatile ("movdqa %xmm4,%xmm5");
+ 750 16702016 : asm volatile ("psrlw $4,%xmm5");
+ 751 16702016 : asm volatile ("pand %xmm7,%xmm4");
+ 752 16702016 : asm volatile ("pand %xmm7,%xmm5");
753 :
- 754 16505408 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][0][0][0]));
- 755 16505408 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][0][1][0]));
- 756 16505408 : asm volatile ("pshufb %xmm4,%xmm6");
- 757 16505408 : asm volatile ("pshufb %xmm5,%xmm7");
- 758 16505408 : asm volatile ("pxor %xmm6,%xmm2");
- 759 16505408 : asm volatile ("pxor %xmm7,%xmm2");
+ 754 16702016 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][0][0][0]));
+ 755 16702016 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][0][1][0]));
+ 756 16702016 : asm volatile ("pshufb %xmm4,%xmm6");
+ 757 16702016 : asm volatile ("pshufb %xmm5,%xmm7");
+ 758 16702016 : asm volatile ("pxor %xmm6,%xmm2");
+ 759 16702016 : asm volatile ("pxor %xmm7,%xmm2");
760 :
- 761 16505408 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][1][0][0]));
- 762 16505408 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][1][1][0]));
- 763 16505408 : asm volatile ("pshufb %xmm4,%xmm6");
- 764 16505408 : asm volatile ("pshufb %xmm5,%xmm7");
- 765 16505408 : asm volatile ("pxor %xmm6,%xmm3");
- 766 16505408 : asm volatile ("pxor %xmm7,%xmm3");
+ 761 16702016 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][1][0][0]));
+ 762 16702016 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][1][1][0]));
+ 763 16702016 : asm volatile ("pshufb %xmm4,%xmm6");
+ 764 16702016 : asm volatile ("pshufb %xmm5,%xmm7");
+ 765 16702016 : asm volatile ("pxor %xmm6,%xmm3");
+ 766 16702016 : asm volatile ("pxor %xmm7,%xmm3");
767 : }
768 :
769 : /* first disk with all coefficients at 1 */
- 770 3311424 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.poly[0]));
- 771 3311424 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[0][i]));
+ 770 3344192 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.poly[0]));
+ 771 3344192 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[0][i]));
772 :
- 773 3311424 : asm volatile ("pxor %xmm5,%xmm5");
- 774 3311424 : asm volatile ("pcmpgtb %xmm1,%xmm5");
- 775 3311424 : asm volatile ("paddb %xmm1,%xmm1");
- 776 3311424 : asm volatile ("pand %xmm7,%xmm5");
- 777 3311424 : asm volatile ("pxor %xmm5,%xmm1");
+ 773 3344192 : asm volatile ("pxor %xmm5,%xmm5");
+ 774 3344192 : asm volatile ("pcmpgtb %xmm1,%xmm5");
+ 775 3344192 : asm volatile ("paddb %xmm1,%xmm1");
+ 776 3344192 : asm volatile ("pand %xmm7,%xmm5");
+ 777 3344192 : asm volatile ("pxor %xmm5,%xmm1");
778 :
- 779 3311424 : asm volatile ("pxor %xmm4,%xmm0");
- 780 3311424 : asm volatile ("pxor %xmm4,%xmm1");
- 781 3311424 : asm volatile ("pxor %xmm4,%xmm2");
- 782 3311424 : asm volatile ("pxor %xmm4,%xmm3");
+ 779 3344192 : asm volatile ("pxor %xmm4,%xmm0");
+ 780 3344192 : asm volatile ("pxor %xmm4,%xmm1");
+ 781 3344192 : asm volatile ("pxor %xmm4,%xmm2");
+ 782 3344192 : asm volatile ("pxor %xmm4,%xmm3");
783 :
- 784 3311424 : asm volatile ("movntdq %%xmm0,%0" : "=m" (p[i]));
- 785 3311424 : asm volatile ("movntdq %%xmm1,%0" : "=m" (q[i]));
- 786 3311424 : asm volatile ("movntdq %%xmm2,%0" : "=m" (r[i]));
- 787 3311424 : asm volatile ("movntdq %%xmm3,%0" : "=m" (s[i]));
+ 784 3344192 : asm volatile ("movntdq %%xmm0,%0" : "=m" (p[i]));
+ 785 3344192 : asm volatile ("movntdq %%xmm1,%0" : "=m" (q[i]));
+ 786 3344192 : asm volatile ("movntdq %%xmm2,%0" : "=m" (r[i]));
+ 787 3344192 : asm volatile ("movntdq %%xmm3,%0" : "=m" (s[i]));
788 : }
789 :
790 : raid_sse_end();
@@ -1191,9 +1191,9 @@
1129 : /*
1130 : * GEN5 (penta parity with Cauchy matrix) SSSE3 implementation
1131 : */
- 1132 50257 : void raid_gen5_ssse3(int nd, size_t size, void **vv)
+ 1132 50258 : void raid_gen5_ssse3(int nd, size_t size, void **vv)
1133 : {
- 1134 50257 : uint8_t **v = (uint8_t **)vv;
+ 1134 50258 : uint8_t **v = (uint8_t **)vv;
1135 : uint8_t *p;
1136 : uint8_t *q;
1137 : uint8_t *r;
@@ -1202,122 +1202,122 @@
1140 : int d, l;
1141 : size_t i;
1142 : uint8_t buffer[16+16];
- 1143 50257 : uint8_t *pd = __align_ptr(buffer, 16);
+ 1143 50258 : uint8_t *pd = __align_ptr(buffer, 16);
1144 :
- 1145 50257 : l = nd - 1;
- 1146 50257 : p = v[nd];
- 1147 50257 : q = v[nd + 1];
- 1148 50257 : r = v[nd + 2];
- 1149 50257 : s = v[nd + 3];
- 1150 50257 : t = v[nd + 4];
+ 1145 50258 : l = nd - 1;
+ 1146 50258 : p = v[nd];
+ 1147 50258 : q = v[nd + 1];
+ 1148 50258 : r = v[nd + 2];
+ 1149 50258 : s = v[nd + 3];
+ 1150 50258 : t = v[nd + 4];
1151 :
1152 : /* special case with only one data disk */
- 1153 50257 : if (l == 0) {
+ 1153 50258 : if (l == 0) {
1154 6 : for (i = 0; i < 5; ++i)
1155 5 : memcpy(v[1 + i], v[0], size);
- 1156 50258 : return;
+ 1156 50259 : return;
1157 : }
1158 :
1159 : raid_sse_begin();
1160 :
1161 : /* generic case with at least two data disks */
- 1162 3928032 : for (i = 0; i < size; i += 16) {
+ 1162 3944417 : for (i = 0; i < size; i += 16) {
1163 : /* last disk without the by two multiplication */
- 1164 3877776 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[l][i]));
+ 1164 3894160 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[l][i]));
1165 :
- 1166 3877776 : asm volatile ("movdqa %xmm4,%xmm0");
- 1167 3877776 : asm volatile ("movdqa %%xmm4,%0" : "=m" (pd[0]));
+ 1166 3894160 : asm volatile ("movdqa %xmm4,%xmm0");
+ 1167 3894160 : asm volatile ("movdqa %%xmm4,%0" : "=m" (pd[0]));
1168 :
- 1169 3877776 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0]));
- 1170 3877776 : asm volatile ("movdqa %xmm4,%xmm5");
- 1171 3877776 : asm volatile ("psrlw $4,%xmm5");
- 1172 3877776 : asm volatile ("pand %xmm7,%xmm4");
- 1173 3877776 : asm volatile ("pand %xmm7,%xmm5");
+ 1169 3894160 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0]));
+ 1170 3894160 : asm volatile ("movdqa %xmm4,%xmm5");
+ 1171 3894160 : asm volatile ("psrlw $4,%xmm5");
+ 1172 3894160 : asm volatile ("pand %xmm7,%xmm4");
+ 1173 3894160 : asm volatile ("pand %xmm7,%xmm5");
1174 :
- 1175 3877776 : asm volatile ("movdqa %0,%%xmm1" : : "m" (gfgenpshufb[l][0][0][0]));
- 1176 3877776 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][0][1][0]));
- 1177 3877776 : asm volatile ("pshufb %xmm4,%xmm1");
- 1178 3877776 : asm volatile ("pshufb %xmm5,%xmm7");
- 1179 3877776 : asm volatile ("pxor %xmm7,%xmm1");
+ 1175 3894160 : asm volatile ("movdqa %0,%%xmm1" : : "m" (gfgenpshufb[l][0][0][0]));
+ 1176 3894160 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][0][1][0]));
+ 1177 3894160 : asm volatile ("pshufb %xmm4,%xmm1");
+ 1178 3894160 : asm volatile ("pshufb %xmm5,%xmm7");
+ 1179 3894160 : asm volatile ("pxor %xmm7,%xmm1");
1180 :
- 1181 3877776 : asm volatile ("movdqa %0,%%xmm2" : : "m" (gfgenpshufb[l][1][0][0]));
- 1182 3877776 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][1][1][0]));
- 1183 3877776 : asm volatile ("pshufb %xmm4,%xmm2");
- 1184 3877776 : asm volatile ("pshufb %xmm5,%xmm7");
- 1185 3877776 : asm volatile ("pxor %xmm7,%xmm2");
+ 1181 3894160 : asm volatile ("movdqa %0,%%xmm2" : : "m" (gfgenpshufb[l][1][0][0]));
+ 1182 3894160 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][1][1][0]));
+ 1183 3894160 : asm volatile ("pshufb %xmm4,%xmm2");
+ 1184 3894160 : asm volatile ("pshufb %xmm5,%xmm7");
+ 1185 3894160 : asm volatile ("pxor %xmm7,%xmm2");
1186 :
- 1187 3877776 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfgenpshufb[l][2][0][0]));
- 1188 3877776 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][2][1][0]));
- 1189 3877776 : asm volatile ("pshufb %xmm4,%xmm3");
- 1190 3877776 : asm volatile ("pshufb %xmm5,%xmm7");
- 1191 3877776 : asm volatile ("pxor %xmm7,%xmm3");
+ 1187 3894160 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfgenpshufb[l][2][0][0]));
+ 1188 3894160 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][2][1][0]));
+ 1189 3894160 : asm volatile ("pshufb %xmm4,%xmm3");
+ 1190 3894160 : asm volatile ("pshufb %xmm5,%xmm7");
+ 1191 3894160 : asm volatile ("pxor %xmm7,%xmm3");
1192 :
1193 : /* intermediate disks */
- 1194 23251312 : for (d = l - 1; d > 0; --d) {
- 1195 19373536 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[d][i]));
- 1196 19373536 : asm volatile ("movdqa %0,%%xmm6" : : "m" (pd[0]));
- 1197 19373536 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.poly[0]));
+ 1194 23366000 : for (d = l - 1; d > 0; --d) {
+ 1195 19471840 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[d][i]));
+ 1196 19471840 : asm volatile ("movdqa %0,%%xmm6" : : "m" (pd[0]));
+ 1197 19471840 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.poly[0]));
1198 :
- 1199 19373536 : asm volatile ("pxor %xmm5,%xmm5");
- 1200 19373536 : asm volatile ("pcmpgtb %xmm0,%xmm5");
- 1201 19373536 : asm volatile ("paddb %xmm0,%xmm0");
- 1202 19373536 : asm volatile ("pand %xmm7,%xmm5");
- 1203 19373536 : asm volatile ("pxor %xmm5,%xmm0");
+ 1199 19471840 : asm volatile ("pxor %xmm5,%xmm5");
+ 1200 19471840 : asm volatile ("pcmpgtb %xmm0,%xmm5");
+ 1201 19471840 : asm volatile ("paddb %xmm0,%xmm0");
+ 1202 19471840 : asm volatile ("pand %xmm7,%xmm5");
+ 1203 19471840 : asm volatile ("pxor %xmm5,%xmm0");
1204 :
- 1205 19373536 : asm volatile ("pxor %xmm4,%xmm0");
- 1206 19373536 : asm volatile ("pxor %xmm4,%xmm6");
- 1207 19373536 : asm volatile ("movdqa %%xmm6,%0" : "=m" (pd[0]));
+ 1205 19471840 : asm volatile ("pxor %xmm4,%xmm0");
+ 1206 19471840 : asm volatile ("pxor %xmm4,%xmm6");
+ 1207 19471840 : asm volatile ("movdqa %%xmm6,%0" : "=m" (pd[0]));
1208 :
- 1209 19373536 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0]));
- 1210 19373536 : asm volatile ("movdqa %xmm4,%xmm5");
- 1211 19373536 : asm volatile ("psrlw $4,%xmm5");
- 1212 19373536 : asm volatile ("pand %xmm7,%xmm4");
- 1213 19373536 : asm volatile ("pand %xmm7,%xmm5");
+ 1209 19471840 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0]));
+ 1210 19471840 : asm volatile ("movdqa %xmm4,%xmm5");
+ 1211 19471840 : asm volatile ("psrlw $4,%xmm5");
+ 1212 19471840 : asm volatile ("pand %xmm7,%xmm4");
+ 1213 19471840 : asm volatile ("pand %xmm7,%xmm5");
1214 :
- 1215 19373536 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][0][0][0]));
- 1216 19373536 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][0][1][0]));
- 1217 19373536 : asm volatile ("pshufb %xmm4,%xmm6");
- 1218 19373536 : asm volatile ("pshufb %xmm5,%xmm7");
- 1219 19373536 : asm volatile ("pxor %xmm6,%xmm1");
- 1220 19373536 : asm volatile ("pxor %xmm7,%xmm1");
+ 1215 19471840 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][0][0][0]));
+ 1216 19471840 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][0][1][0]));
+ 1217 19471840 : asm volatile ("pshufb %xmm4,%xmm6");
+ 1218 19471840 : asm volatile ("pshufb %xmm5,%xmm7");
+ 1219 19471840 : asm volatile ("pxor %xmm6,%xmm1");
+ 1220 19471840 : asm volatile ("pxor %xmm7,%xmm1");
1221 :
- 1222 19373536 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][1][0][0]));
- 1223 19373536 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][1][1][0]));
- 1224 19373536 : asm volatile ("pshufb %xmm4,%xmm6");
- 1225 19373536 : asm volatile ("pshufb %xmm5,%xmm7");
- 1226 19373536 : asm volatile ("pxor %xmm6,%xmm2");
- 1227 19373536 : asm volatile ("pxor %xmm7,%xmm2");
+ 1222 19471840 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][1][0][0]));
+ 1223 19471840 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][1][1][0]));
+ 1224 19471840 : asm volatile ("pshufb %xmm4,%xmm6");
+ 1225 19471840 : asm volatile ("pshufb %xmm5,%xmm7");
+ 1226 19471840 : asm volatile ("pxor %xmm6,%xmm2");
+ 1227 19471840 : asm volatile ("pxor %xmm7,%xmm2");
1228 :
- 1229 19373536 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][2][0][0]));
- 1230 19373536 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][2][1][0]));
- 1231 19373536 : asm volatile ("pshufb %xmm4,%xmm6");
- 1232 19373536 : asm volatile ("pshufb %xmm5,%xmm7");
- 1233 19373536 : asm volatile ("pxor %xmm6,%xmm3");
- 1234 19373536 : asm volatile ("pxor %xmm7,%xmm3");
+ 1229 19471840 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][2][0][0]));
+ 1230 19471840 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][2][1][0]));
+ 1231 19471840 : asm volatile ("pshufb %xmm4,%xmm6");
+ 1232 19471840 : asm volatile ("pshufb %xmm5,%xmm7");
+ 1233 19471840 : asm volatile ("pxor %xmm6,%xmm3");
+ 1234 19471840 : asm volatile ("pxor %xmm7,%xmm3");
1235 : }
1236 :
1237 : /* first disk with all coefficients at 1 */
- 1238 3877776 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[0][i]));
- 1239 3877776 : asm volatile ("movdqa %0,%%xmm6" : : "m" (pd[0]));
- 1240 3877776 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.poly[0]));
+ 1238 3894160 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[0][i]));
+ 1239 3894160 : asm volatile ("movdqa %0,%%xmm6" : : "m" (pd[0]));
+ 1240 3894160 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.poly[0]));
1241 :
- 1242 3877776 : asm volatile ("pxor %xmm5,%xmm5");
- 1243 3877776 : asm volatile ("pcmpgtb %xmm0,%xmm5");
- 1244 3877776 : asm volatile ("paddb %xmm0,%xmm0");
- 1245 3877776 : asm volatile ("pand %xmm7,%xmm5");
- 1246 3877776 : asm volatile ("pxor %xmm5,%xmm0");
+ 1242 3894160 : asm volatile ("pxor %xmm5,%xmm5");
+ 1243 3894160 : asm volatile ("pcmpgtb %xmm0,%xmm5");
+ 1244 3894160 : asm volatile ("paddb %xmm0,%xmm0");
+ 1245 3894160 : asm volatile ("pand %xmm7,%xmm5");
+ 1246 3894160 : asm volatile ("pxor %xmm5,%xmm0");
1247 :
- 1248 3877776 : asm volatile ("pxor %xmm4,%xmm0");
- 1249 3877776 : asm volatile ("pxor %xmm4,%xmm1");
- 1250 3877776 : asm volatile ("pxor %xmm4,%xmm2");
- 1251 3877776 : asm volatile ("pxor %xmm4,%xmm3");
- 1252 3877776 : asm volatile ("pxor %xmm4,%xmm6");
+ 1248 3894160 : asm volatile ("pxor %xmm4,%xmm0");
+ 1249 3894160 : asm volatile ("pxor %xmm4,%xmm1");
+ 1250 3894160 : asm volatile ("pxor %xmm4,%xmm2");
+ 1251 3894160 : asm volatile ("pxor %xmm4,%xmm3");
+ 1252 3894160 : asm volatile ("pxor %xmm4,%xmm6");
1253 :
- 1254 3877776 : asm volatile ("movntdq %%xmm6,%0" : "=m" (p[i]));
- 1255 3877776 : asm volatile ("movntdq %%xmm0,%0" : "=m" (q[i]));
- 1256 3877776 : asm volatile ("movntdq %%xmm1,%0" : "=m" (r[i]));
- 1257 3877776 : asm volatile ("movntdq %%xmm2,%0" : "=m" (s[i]));
- 1258 3877776 : asm volatile ("movntdq %%xmm3,%0" : "=m" (t[i]));
+ 1254 3894160 : asm volatile ("movntdq %%xmm6,%0" : "=m" (p[i]));
+ 1255 3894160 : asm volatile ("movntdq %%xmm0,%0" : "=m" (q[i]));
+ 1256 3894160 : asm volatile ("movntdq %%xmm1,%0" : "=m" (r[i]));
+ 1257 3894160 : asm volatile ("movntdq %%xmm2,%0" : "=m" (s[i]));
+ 1258 3894160 : asm volatile ("movntdq %%xmm3,%0" : "=m" (t[i]));
1259 : }
1260 :
1261 : raid_sse_end();
@@ -1591,9 +1591,9 @@
1529 : /*
1530 : * GEN6 (hexa parity with Cauchy matrix) SSSE3 implementation
1531 : */
- 1532 549547 : void raid_gen6_ssse3(int nd, size_t size, void **vv)
+ 1532 549666 : void raid_gen6_ssse3(int nd, size_t size, void **vv)
1533 : {
- 1534 549547 : uint8_t **v = (uint8_t **)vv;
+ 1534 549666 : uint8_t **v = (uint8_t **)vv;
1535 : uint8_t *p;
1536 : uint8_t *q;
1537 : uint8_t *r;
@@ -1603,142 +1603,142 @@
1541 : int d, l;
1542 : size_t i;
1543 : uint8_t buffer[2*16+16];
- 1544 549547 : uint8_t *pd = __align_ptr(buffer, 16);
+ 1544 549666 : uint8_t *pd = __align_ptr(buffer, 16);
1545 :
- 1546 549547 : l = nd - 1;
- 1547 549547 : p = v[nd];
- 1548 549547 : q = v[nd + 1];
- 1549 549547 : r = v[nd + 2];
- 1550 549547 : s = v[nd + 3];
- 1551 549547 : t = v[nd + 4];
- 1552 549547 : u = v[nd + 5];
+ 1546 549666 : l = nd - 1;
+ 1547 549666 : p = v[nd];
+ 1548 549666 : q = v[nd + 1];
+ 1549 549666 : r = v[nd + 2];
+ 1550 549666 : s = v[nd + 3];
+ 1551 549666 : t = v[nd + 4];
+ 1552 549666 : u = v[nd + 5];
1553 :
1554 : /* special case with only one data disk */
- 1555 549547 : if (l == 0) {
+ 1555 549666 : if (l == 0) {
1556 7 : for (i = 0; i < 6; ++i)
1557 6 : memcpy(v[1 + i], v[0], size);
- 1558 549548 : return;
+ 1558 549667 : return;
1559 : }
1560 :
1561 : raid_sse_begin();
1562 :
1563 : /* generic case with at least two data disks */
- 1564 35147130 : for (i = 0; i < size; i += 16) {
+ 1564 35154865 : for (i = 0; i < size; i += 16) {
1565 : /* last disk without the by two multiplication */
- 1566 34597584 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[l][i]));
+ 1566 34605200 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[l][i]));
1567 :
- 1568 34597584 : asm volatile ("movdqa %%xmm4,%0" : "=m" (pd[0]));
- 1569 34597584 : asm volatile ("movdqa %%xmm4,%0" : "=m" (pd[16]));
+ 1568 34605200 : asm volatile ("movdqa %%xmm4,%0" : "=m" (pd[0]));
+ 1569 34605200 : asm volatile ("movdqa %%xmm4,%0" : "=m" (pd[16]));
1570 :
- 1571 34597584 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0]));
- 1572 34597584 : asm volatile ("movdqa %xmm4,%xmm5");
- 1573 34597584 : asm volatile ("psrlw $4,%xmm5");
- 1574 34597584 : asm volatile ("pand %xmm7,%xmm4");
- 1575 34597584 : asm volatile ("pand %xmm7,%xmm5");
+ 1571 34605200 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0]));
+ 1572 34605200 : asm volatile ("movdqa %xmm4,%xmm5");
+ 1573 34605200 : asm volatile ("psrlw $4,%xmm5");
+ 1574 34605200 : asm volatile ("pand %xmm7,%xmm4");
+ 1575 34605200 : asm volatile ("pand %xmm7,%xmm5");
1576 :
- 1577 34597584 : asm volatile ("movdqa %0,%%xmm0" : : "m" (gfgenpshufb[l][0][0][0]));
- 1578 34597584 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][0][1][0]));
- 1579 34597584 : asm volatile ("pshufb %xmm4,%xmm0");
- 1580 34597584 : asm volatile ("pshufb %xmm5,%xmm7");
- 1581 34597584 : asm volatile ("pxor %xmm7,%xmm0");
+ 1577 34605200 : asm volatile ("movdqa %0,%%xmm0" : : "m" (gfgenpshufb[l][0][0][0]));
+ 1578 34605200 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][0][1][0]));
+ 1579 34605200 : asm volatile ("pshufb %xmm4,%xmm0");
+ 1580 34605200 : asm volatile ("pshufb %xmm5,%xmm7");
+ 1581 34605200 : asm volatile ("pxor %xmm7,%xmm0");
1582 :
- 1583 34597584 : asm volatile ("movdqa %0,%%xmm1" : : "m" (gfgenpshufb[l][1][0][0]));
- 1584 34597584 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][1][1][0]));
- 1585 34597584 : asm volatile ("pshufb %xmm4,%xmm1");
- 1586 34597584 : asm volatile ("pshufb %xmm5,%xmm7");
- 1587 34597584 : asm volatile ("pxor %xmm7,%xmm1");
+ 1583 34605200 : asm volatile ("movdqa %0,%%xmm1" : : "m" (gfgenpshufb[l][1][0][0]));
+ 1584 34605200 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][1][1][0]));
+ 1585 34605200 : asm volatile ("pshufb %xmm4,%xmm1");
+ 1586 34605200 : asm volatile ("pshufb %xmm5,%xmm7");
+ 1587 34605200 : asm volatile ("pxor %xmm7,%xmm1");
1588 :
- 1589 34597584 : asm volatile ("movdqa %0,%%xmm2" : : "m" (gfgenpshufb[l][2][0][0]));
- 1590 34597584 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][2][1][0]));
- 1591 34597584 : asm volatile ("pshufb %xmm4,%xmm2");
- 1592 34597584 : asm volatile ("pshufb %xmm5,%xmm7");
- 1593 34597584 : asm volatile ("pxor %xmm7,%xmm2");
+ 1589 34605200 : asm volatile ("movdqa %0,%%xmm2" : : "m" (gfgenpshufb[l][2][0][0]));
+ 1590 34605200 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][2][1][0]));
+ 1591 34605200 : asm volatile ("pshufb %xmm4,%xmm2");
+ 1592 34605200 : asm volatile ("pshufb %xmm5,%xmm7");
+ 1593 34605200 : asm volatile ("pxor %xmm7,%xmm2");
1594 :
- 1595 34597584 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfgenpshufb[l][3][0][0]));
- 1596 34597584 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][3][1][0]));
- 1597 34597584 : asm volatile ("pshufb %xmm4,%xmm3");
- 1598 34597584 : asm volatile ("pshufb %xmm5,%xmm7");
- 1599 34597584 : asm volatile ("pxor %xmm7,%xmm3");
+ 1595 34605200 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfgenpshufb[l][3][0][0]));
+ 1596 34605200 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][3][1][0]));
+ 1597 34605200 : asm volatile ("pshufb %xmm4,%xmm3");
+ 1598 34605200 : asm volatile ("pshufb %xmm5,%xmm7");
+ 1599 34605200 : asm volatile ("pxor %xmm7,%xmm3");
1600 :
1601 : /* intermediate disks */
- 1602 178992816 : for (d = l - 1; d > 0; --d) {
- 1603 144395232 : asm volatile ("movdqa %0,%%xmm5" : : "m" (pd[0]));
- 1604 144395232 : asm volatile ("movdqa %0,%%xmm6" : : "m" (pd[16]));
- 1605 144395232 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.poly[0]));
+ 1602 179030896 : for (d = l - 1; d > 0; --d) {
+ 1603 144425696 : asm volatile ("movdqa %0,%%xmm5" : : "m" (pd[0]));
+ 1604 144425696 : asm volatile ("movdqa %0,%%xmm6" : : "m" (pd[16]));
+ 1605 144425696 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.poly[0]));
1606 :
- 1607 144395232 : asm volatile ("pxor %xmm4,%xmm4");
- 1608 144395232 : asm volatile ("pcmpgtb %xmm6,%xmm4");
- 1609 144395232 : asm volatile ("paddb %xmm6,%xmm6");
- 1610 144395232 : asm volatile ("pand %xmm7,%xmm4");
- 1611 144395232 : asm volatile ("pxor %xmm4,%xmm6");
+ 1607 144425696 : asm volatile ("pxor %xmm4,%xmm4");
+ 1608 144425696 : asm volatile ("pcmpgtb %xmm6,%xmm4");
+ 1609 144425696 : asm volatile ("paddb %xmm6,%xmm6");
+ 1610 144425696 : asm volatile ("pand %xmm7,%xmm4");
+ 1611 144425696 : asm volatile ("pxor %xmm4,%xmm6");
1612 :
- 1613 144395232 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[d][i]));
+ 1613 144425696 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[d][i]));
1614 :
- 1615 144395232 : asm volatile ("pxor %xmm4,%xmm5");
- 1616 144395232 : asm volatile ("pxor %xmm4,%xmm6");
- 1617 144395232 : asm volatile ("movdqa %%xmm5,%0" : "=m" (pd[0]));
- 1618 144395232 : asm volatile ("movdqa %%xmm6,%0" : "=m" (pd[16]));
+ 1615 144425696 : asm volatile ("pxor %xmm4,%xmm5");
+ 1616 144425696 : asm volatile ("pxor %xmm4,%xmm6");
+ 1617 144425696 : asm volatile ("movdqa %%xmm5,%0" : "=m" (pd[0]));
+ 1618 144425696 : asm volatile ("movdqa %%xmm6,%0" : "=m" (pd[16]));
1619 :
- 1620 144395232 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0]));
- 1621 144395232 : asm volatile ("movdqa %xmm4,%xmm5");
- 1622 144395232 : asm volatile ("psrlw $4,%xmm5");
- 1623 144395232 : asm volatile ("pand %xmm7,%xmm4");
- 1624 144395232 : asm volatile ("pand %xmm7,%xmm5");
+ 1620 144425696 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0]));
+ 1621 144425696 : asm volatile ("movdqa %xmm4,%xmm5");
+ 1622 144425696 : asm volatile ("psrlw $4,%xmm5");
+ 1623 144425696 : asm volatile ("pand %xmm7,%xmm4");
+ 1624 144425696 : asm volatile ("pand %xmm7,%xmm5");
1625 :
- 1626 144395232 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][0][0][0]));
- 1627 144395232 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][0][1][0]));
- 1628 144395232 : asm volatile ("pshufb %xmm4,%xmm6");
- 1629 144395232 : asm volatile ("pshufb %xmm5,%xmm7");
- 1630 144395232 : asm volatile ("pxor %xmm6,%xmm0");
- 1631 144395232 : asm volatile ("pxor %xmm7,%xmm0");
+ 1626 144425696 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][0][0][0]));
+ 1627 144425696 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][0][1][0]));
+ 1628 144425696 : asm volatile ("pshufb %xmm4,%xmm6");
+ 1629 144425696 : asm volatile ("pshufb %xmm5,%xmm7");
+ 1630 144425696 : asm volatile ("pxor %xmm6,%xmm0");
+ 1631 144425696 : asm volatile ("pxor %xmm7,%xmm0");
1632 :
- 1633 144395232 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][1][0][0]));
- 1634 144395232 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][1][1][0]));
- 1635 144395232 : asm volatile ("pshufb %xmm4,%xmm6");
- 1636 144395232 : asm volatile ("pshufb %xmm5,%xmm7");
- 1637 144395232 : asm volatile ("pxor %xmm6,%xmm1");
- 1638 144395232 : asm volatile ("pxor %xmm7,%xmm1");
+ 1633 144425696 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][1][0][0]));
+ 1634 144425696 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][1][1][0]));
+ 1635 144425696 : asm volatile ("pshufb %xmm4,%xmm6");
+ 1636 144425696 : asm volatile ("pshufb %xmm5,%xmm7");
+ 1637 144425696 : asm volatile ("pxor %xmm6,%xmm1");
+ 1638 144425696 : asm volatile ("pxor %xmm7,%xmm1");
1639 :
- 1640 144395232 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][2][0][0]));
- 1641 144395232 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][2][1][0]));
- 1642 144395232 : asm volatile ("pshufb %xmm4,%xmm6");
- 1643 144395232 : asm volatile ("pshufb %xmm5,%xmm7");
- 1644 144395232 : asm volatile ("pxor %xmm6,%xmm2");
- 1645 144395232 : asm volatile ("pxor %xmm7,%xmm2");
+ 1640 144425696 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][2][0][0]));
+ 1641 144425696 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][2][1][0]));
+ 1642 144425696 : asm volatile ("pshufb %xmm4,%xmm6");
+ 1643 144425696 : asm volatile ("pshufb %xmm5,%xmm7");
+ 1644 144425696 : asm volatile ("pxor %xmm6,%xmm2");
+ 1645 144425696 : asm volatile ("pxor %xmm7,%xmm2");
1646 :
- 1647 144395232 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][3][0][0]));
- 1648 144395232 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][3][1][0]));
- 1649 144395232 : asm volatile ("pshufb %xmm4,%xmm6");
- 1650 144395232 : asm volatile ("pshufb %xmm5,%xmm7");
- 1651 144395232 : asm volatile ("pxor %xmm6,%xmm3");
- 1652 144395232 : asm volatile ("pxor %xmm7,%xmm3");
+ 1647 144425696 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][3][0][0]));
+ 1648 144425696 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][3][1][0]));
+ 1649 144425696 : asm volatile ("pshufb %xmm4,%xmm6");
+ 1650 144425696 : asm volatile ("pshufb %xmm5,%xmm7");
+ 1651 144425696 : asm volatile ("pxor %xmm6,%xmm3");
+ 1652 144425696 : asm volatile ("pxor %xmm7,%xmm3");
1653 : }
1654 :
1655 : /* first disk with all coefficients at 1 */
- 1656 34597584 : asm volatile ("movdqa %0,%%xmm5" : : "m" (pd[0]));
- 1657 34597584 : asm volatile ("movdqa %0,%%xmm6" : : "m" (pd[16]));
- 1658 34597584 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.poly[0]));
+ 1656 34605200 : asm volatile ("movdqa %0,%%xmm5" : : "m" (pd[0]));
+ 1657 34605200 : asm volatile ("movdqa %0,%%xmm6" : : "m" (pd[16]));
+ 1658 34605200 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.poly[0]));
1659 :
- 1660 34597584 : asm volatile ("pxor %xmm4,%xmm4");
- 1661 34597584 : asm volatile ("pcmpgtb %xmm6,%xmm4");
- 1662 34597584 : asm volatile ("paddb %xmm6,%xmm6");
- 1663 34597584 : asm volatile ("pand %xmm7,%xmm4");
- 1664 34597584 : asm volatile ("pxor %xmm4,%xmm6");
+ 1660 34605200 : asm volatile ("pxor %xmm4,%xmm4");
+ 1661 34605200 : asm volatile ("pcmpgtb %xmm6,%xmm4");
+ 1662 34605200 : asm volatile ("paddb %xmm6,%xmm6");
+ 1663 34605200 : asm volatile ("pand %xmm7,%xmm4");
+ 1664 34605200 : asm volatile ("pxor %xmm4,%xmm6");
1665 :
- 1666 34597584 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[0][i]));
- 1667 34597584 : asm volatile ("pxor %xmm4,%xmm0");
- 1668 34597584 : asm volatile ("pxor %xmm4,%xmm1");
- 1669 34597584 : asm volatile ("pxor %xmm4,%xmm2");
- 1670 34597584 : asm volatile ("pxor %xmm4,%xmm3");
- 1671 34597584 : asm volatile ("pxor %xmm4,%xmm5");
- 1672 34597584 : asm volatile ("pxor %xmm4,%xmm6");
+ 1666 34605200 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[0][i]));
+ 1667 34605200 : asm volatile ("pxor %xmm4,%xmm0");
+ 1668 34605200 : asm volatile ("pxor %xmm4,%xmm1");
+ 1669 34605200 : asm volatile ("pxor %xmm4,%xmm2");
+ 1670 34605200 : asm volatile ("pxor %xmm4,%xmm3");
+ 1671 34605200 : asm volatile ("pxor %xmm4,%xmm5");
+ 1672 34605200 : asm volatile ("pxor %xmm4,%xmm6");
1673 :
- 1674 34597584 : asm volatile ("movntdq %%xmm5,%0" : "=m" (p[i]));
- 1675 34597584 : asm volatile ("movntdq %%xmm6,%0" : "=m" (q[i]));
- 1676 34597584 : asm volatile ("movntdq %%xmm0,%0" : "=m" (r[i]));
- 1677 34597584 : asm volatile ("movntdq %%xmm1,%0" : "=m" (s[i]));
- 1678 34597584 : asm volatile ("movntdq %%xmm2,%0" : "=m" (t[i]));
- 1679 34597584 : asm volatile ("movntdq %%xmm3,%0" : "=m" (u[i]));
+ 1674 34605200 : asm volatile ("movntdq %%xmm5,%0" : "=m" (p[i]));
+ 1675 34605200 : asm volatile ("movntdq %%xmm6,%0" : "=m" (q[i]));
+ 1676 34605200 : asm volatile ("movntdq %%xmm0,%0" : "=m" (r[i]));
+ 1677 34605200 : asm volatile ("movntdq %%xmm1,%0" : "=m" (s[i]));
+ 1678 34605200 : asm volatile ("movntdq %%xmm2,%0" : "=m" (t[i]));
+ 1679 34605200 : asm volatile ("movntdq %%xmm3,%0" : "=m" (u[i]));
1680 : }
1681 :
1682 : raid_sse_end();
@@ -2046,9 +2046,9 @@
1984 : /*
1985 : * RAID recovering for one disk SSSE3 implementation
1986 : */
- 1987 114194 : void raid_rec1_ssse3(int nr, int *id, int *ip, int nd, size_t size, void **vv)
+ 1987 114430 : void raid_rec1_ssse3(int nr, int *id, int *ip, int nd, size_t size, void **vv)
1988 : {
- 1989 114194 : uint8_t **v = (uint8_t **)vv;
+ 1989 114430 : uint8_t **v = (uint8_t **)vv;
1990 : uint8_t *p;
1991 : uint8_t *pa;
1992 : uint8_t G;
@@ -2058,43 +2058,43 @@
1996 : (void)nr; /* unused, it's always 1 */
1997 :
1998 : /* if it's RAID5 uses the faster function */
- 1999 114194 : if (ip[0] == 0) {
- 2000 104659 : raid_rec1of1(id, nd, size, vv);
- 2001 218853 : return;
+ 1999 114430 : if (ip[0] == 0) {
+ 2000 104899 : raid_rec1of1(id, nd, size, vv);
+ 2001 219329 : return;
2002 : }
2003 :
2004 : /* setup the coefficients matrix */
- 2005 19070 : G = A(ip[0], id[0]);
+ 2005 19062 : G = A(ip[0], id[0]);
2006 :
2007 : /* invert it to solve the system of linear equations */
- 2008 19070 : V = inv(G);
+ 2008 19062 : V = inv(G);
2009 :
2010 : /* compute delta parity */
- 2011 9535 : raid_delta_gen(1, id, ip, nd, size, vv);
+ 2011 9531 : raid_delta_gen(1, id, ip, nd, size, vv);
2012 :
- 2013 9535 : p = v[nd + ip[0]];
- 2014 9535 : pa = v[id[0]];
+ 2013 9531 : p = v[nd + ip[0]];
+ 2014 9531 : pa = v[id[0]];
2015 :
2016 : raid_sse_begin();
2017 :
- 2018 9535 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0]));
- 2019 9535 : asm volatile ("movdqa %0,%%xmm4" : : "m" (gfmulpshufb[V][0][0]));
- 2020 9535 : asm volatile ("movdqa %0,%%xmm5" : : "m" (gfmulpshufb[V][1][0]));
+ 2018 9531 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0]));
+ 2019 9531 : asm volatile ("movdqa %0,%%xmm4" : : "m" (gfmulpshufb[V][0][0]));
+ 2020 9531 : asm volatile ("movdqa %0,%%xmm5" : : "m" (gfmulpshufb[V][1][0]));
2021 :
- 2022 1529663 : for (i = 0; i < size; i += 16) {
- 2023 1520128 : asm volatile ("movdqa %0,%%xmm0" : : "m" (p[i]));
- 2024 1520128 : asm volatile ("movdqa %0,%%xmm1" : : "m" (pa[i]));
- 2025 1520128 : asm volatile ("movdqa %xmm4,%xmm2");
- 2026 1520128 : asm volatile ("movdqa %xmm5,%xmm3");
- 2027 1520128 : asm volatile ("pxor %xmm0,%xmm1");
- 2028 1520128 : asm volatile ("movdqa %xmm1,%xmm0");
- 2029 1520128 : asm volatile ("psrlw $4,%xmm1");
- 2030 1520128 : asm volatile ("pand %xmm7,%xmm0");
- 2031 1520128 : asm volatile ("pand %xmm7,%xmm1");
- 2032 1520128 : asm volatile ("pshufb %xmm0,%xmm2");
- 2033 1520128 : asm volatile ("pshufb %xmm1,%xmm3");
- 2034 1520128 : asm volatile ("pxor %xmm3,%xmm2");
- 2035 1520128 : asm volatile ("movdqa %%xmm2,%0" : "=m" (pa[i]));
+ 2022 1529403 : for (i = 0; i < size; i += 16) {
+ 2023 1519872 : asm volatile ("movdqa %0,%%xmm0" : : "m" (p[i]));
+ 2024 1519872 : asm volatile ("movdqa %0,%%xmm1" : : "m" (pa[i]));
+ 2025 1519872 : asm volatile ("movdqa %xmm4,%xmm2");
+ 2026 1519872 : asm volatile ("movdqa %xmm5,%xmm3");
+ 2027 1519872 : asm volatile ("pxor %xmm0,%xmm1");
+ 2028 1519872 : asm volatile ("movdqa %xmm1,%xmm0");
+ 2029 1519872 : asm volatile ("psrlw $4,%xmm1");
+ 2030 1519872 : asm volatile ("pand %xmm7,%xmm0");
+ 2031 1519872 : asm volatile ("pand %xmm7,%xmm1");
+ 2032 1519872 : asm volatile ("pshufb %xmm0,%xmm2");
+ 2033 1519872 : asm volatile ("pshufb %xmm1,%xmm3");
+ 2034 1519872 : asm volatile ("pxor %xmm3,%xmm2");
+ 2035 1519872 : asm volatile ("movdqa %%xmm2,%0" : "=m" (pa[i]));
2036 : }
2037 :
2038 : raid_sse_end();
@@ -2105,106 +2105,106 @@
2043 : /*
2044 : * RAID recovering for two disks SSSE3 implementation
2045 : */
- 2046 44409 : void raid_rec2_ssse3(int nr, int *id, int *ip, int nd, size_t size, void **vv)
+ 2046 44206 : void raid_rec2_ssse3(int nr, int *id, int *ip, int nd, size_t size, void **vv)
2047 : {
- 2048 44409 : uint8_t **v = (uint8_t **)vv;
- 2049 44409 : const int N = 2;
- 2050 44409 : uint8_t *p[N];
- 2051 44409 : uint8_t *pa[N];
- 2052 44409 : uint8_t G[N * N];
- 2053 44409 : uint8_t V[N * N];
+ 2048 44206 : uint8_t **v = (uint8_t **)vv;
+ 2049 44206 : const int N = 2;
+ 2050 44206 : uint8_t *p[N];
+ 2051 44206 : uint8_t *pa[N];
+ 2052 44206 : uint8_t G[N * N];
+ 2053 44206 : uint8_t V[N * N];
2054 : size_t i;
2055 : int j, k;
2056 :
2057 : (void)nr; /* unused, it's always 2 */
2058 :
2059 : /* setup the coefficients matrix */
- 2060 133227 : for (j = 0; j < N; ++j)
- 2061 266454 : for (k = 0; k < N; ++k)
- 2062 355272 : G[j * N + k] = A(ip[j], id[k]);
+ 2060 132618 : for (j = 0; j < N; ++j)
+ 2061 265236 : for (k = 0; k < N; ++k)
+ 2062 353648 : G[j * N + k] = A(ip[j], id[k]);
2063 :
2064 : /* invert it to solve the system of linear equations */
- 2065 44409 : raid_invert(G, V, N);
+ 2065 44206 : raid_invert(G, V, N);
2066 :
2067 : /* compute delta parity */
- 2068 44409 : raid_delta_gen(N, id, ip, nd, size, vv);
+ 2068 44206 : raid_delta_gen(N, id, ip, nd, size, vv);
2069 :
- 2070 133227 : for (j = 0; j < N; ++j) {
- 2071 88818 : p[j] = v[nd + ip[j]];
- 2072 88818 : pa[j] = v[id[j]];
+ 2070 132618 : for (j = 0; j < N; ++j) {
+ 2071 88412 : p[j] = v[nd + ip[j]];
+ 2072 88412 : pa[j] = v[id[j]];
2073 : }
2074 :
2075 : raid_sse_begin();
2076 :
- 2077 44409 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0]));
+ 2077 44206 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0]));
2078 :
- 2079 3612921 : for (i = 0; i < size; i += 16) {
- 2080 3568512 : asm volatile ("movdqa %0,%%xmm0" : : "m" (p[0][i]));
- 2081 3568512 : asm volatile ("movdqa %0,%%xmm2" : : "m" (pa[0][i]));
- 2082 3568512 : asm volatile ("movdqa %0,%%xmm1" : : "m" (p[1][i]));
- 2083 3568512 : asm volatile ("movdqa %0,%%xmm3" : : "m" (pa[1][i]));
- 2084 3568512 : asm volatile ("pxor %xmm2,%xmm0");
- 2085 3568512 : asm volatile ("pxor %xmm3,%xmm1");
+ 2079 3599726 : for (i = 0; i < size; i += 16) {
+ 2080 3555520 : asm volatile ("movdqa %0,%%xmm0" : : "m" (p[0][i]));
+ 2081 3555520 : asm volatile ("movdqa %0,%%xmm2" : : "m" (pa[0][i]));
+ 2082 3555520 : asm volatile ("movdqa %0,%%xmm1" : : "m" (p[1][i]));
+ 2083 3555520 : asm volatile ("movdqa %0,%%xmm3" : : "m" (pa[1][i]));
+ 2084 3555520 : asm volatile ("pxor %xmm2,%xmm0");
+ 2085 3555520 : asm volatile ("pxor %xmm3,%xmm1");
2086 :
- 2087 3568512 : asm volatile ("pxor %xmm6,%xmm6");
+ 2087 3555520 : asm volatile ("pxor %xmm6,%xmm6");
2088 :
- 2089 3568512 : asm volatile ("movdqa %0,%%xmm2" : : "m" (gfmulpshufb[V[0]][0][0]));
- 2090 3568512 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfmulpshufb[V[0]][1][0]));
- 2091 3568512 : asm volatile ("movdqa %xmm0,%xmm4");
- 2092 3568512 : asm volatile ("movdqa %xmm0,%xmm5");
- 2093 3568512 : asm volatile ("psrlw $4,%xmm5");
- 2094 3568512 : asm volatile ("pand %xmm7,%xmm4");
- 2095 3568512 : asm volatile ("pand %xmm7,%xmm5");
- 2096 3568512 : asm volatile ("pshufb %xmm4,%xmm2");
- 2097 3568512 : asm volatile ("pshufb %xmm5,%xmm3");
- 2098 3568512 : asm volatile ("pxor %xmm2,%xmm6");
- 2099 3568512 : asm volatile ("pxor %xmm3,%xmm6");
+ 2089 3555520 : asm volatile ("movdqa %0,%%xmm2" : : "m" (gfmulpshufb[V[0]][0][0]));
+ 2090 3555520 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfmulpshufb[V[0]][1][0]));
+ 2091 3555520 : asm volatile ("movdqa %xmm0,%xmm4");
+ 2092 3555520 : asm volatile ("movdqa %xmm0,%xmm5");
+ 2093 3555520 : asm volatile ("psrlw $4,%xmm5");
+ 2094 3555520 : asm volatile ("pand %xmm7,%xmm4");
+ 2095 3555520 : asm volatile ("pand %xmm7,%xmm5");
+ 2096 3555520 : asm volatile ("pshufb %xmm4,%xmm2");
+ 2097 3555520 : asm volatile ("pshufb %xmm5,%xmm3");
+ 2098 3555520 : asm volatile ("pxor %xmm2,%xmm6");
+ 2099 3555520 : asm volatile ("pxor %xmm3,%xmm6");
2100 :
- 2101 3568512 : asm volatile ("movdqa %0,%%xmm2" : : "m" (gfmulpshufb[V[1]][0][0]));
- 2102 3568512 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfmulpshufb[V[1]][1][0]));
- 2103 3568512 : asm volatile ("movdqa %xmm1,%xmm4");
- 2104 3568512 : asm volatile ("movdqa %xmm1,%xmm5");
- 2105 3568512 : asm volatile ("psrlw $4,%xmm5");
- 2106 3568512 : asm volatile ("pand %xmm7,%xmm4");
- 2107 3568512 : asm volatile ("pand %xmm7,%xmm5");
- 2108 3568512 : asm volatile ("pshufb %xmm4,%xmm2");
- 2109 3568512 : asm volatile ("pshufb %xmm5,%xmm3");
- 2110 3568512 : asm volatile ("pxor %xmm2,%xmm6");
- 2111 3568512 : asm volatile ("pxor %xmm3,%xmm6");
+ 2101 3555520 : asm volatile ("movdqa %0,%%xmm2" : : "m" (gfmulpshufb[V[1]][0][0]));
+ 2102 3555520 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfmulpshufb[V[1]][1][0]));
+ 2103 3555520 : asm volatile ("movdqa %xmm1,%xmm4");
+ 2104 3555520 : asm volatile ("movdqa %xmm1,%xmm5");
+ 2105 3555520 : asm volatile ("psrlw $4,%xmm5");
+ 2106 3555520 : asm volatile ("pand %xmm7,%xmm4");
+ 2107 3555520 : asm volatile ("pand %xmm7,%xmm5");
+ 2108 3555520 : asm volatile ("pshufb %xmm4,%xmm2");
+ 2109 3555520 : asm volatile ("pshufb %xmm5,%xmm3");
+ 2110 3555520 : asm volatile ("pxor %xmm2,%xmm6");
+ 2111 3555520 : asm volatile ("pxor %xmm3,%xmm6");
2112 :
- 2113 3568512 : asm volatile ("movdqa %%xmm6,%0" : "=m" (pa[0][i]));
+ 2113 3555520 : asm volatile ("movdqa %%xmm6,%0" : "=m" (pa[0][i]));
2114 :
- 2115 3568512 : asm volatile ("pxor %xmm6,%xmm6");
+ 2115 3555520 : asm volatile ("pxor %xmm6,%xmm6");
2116 :
- 2117 3568512 : asm volatile ("movdqa %0,%%xmm2" : : "m" (gfmulpshufb[V[2]][0][0]));
- 2118 3568512 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfmulpshufb[V[2]][1][0]));
- 2119 3568512 : asm volatile ("movdqa %xmm0,%xmm4");
- 2120 3568512 : asm volatile ("movdqa %xmm0,%xmm5");
- 2121 3568512 : asm volatile ("psrlw $4,%xmm5");
- 2122 3568512 : asm volatile ("pand %xmm7,%xmm4");
- 2123 3568512 : asm volatile ("pand %xmm7,%xmm5");
- 2124 3568512 : asm volatile ("pshufb %xmm4,%xmm2");
- 2125 3568512 : asm volatile ("pshufb %xmm5,%xmm3");
- 2126 3568512 : asm volatile ("pxor %xmm2,%xmm6");
- 2127 3568512 : asm volatile ("pxor %xmm3,%xmm6");
+ 2117 3555520 : asm volatile ("movdqa %0,%%xmm2" : : "m" (gfmulpshufb[V[2]][0][0]));
+ 2118 3555520 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfmulpshufb[V[2]][1][0]));
+ 2119 3555520 : asm volatile ("movdqa %xmm0,%xmm4");
+ 2120 3555520 : asm volatile ("movdqa %xmm0,%xmm5");
+ 2121 3555520 : asm volatile ("psrlw $4,%xmm5");
+ 2122 3555520 : asm volatile ("pand %xmm7,%xmm4");
+ 2123 3555520 : asm volatile ("pand %xmm7,%xmm5");
+ 2124 3555520 : asm volatile ("pshufb %xmm4,%xmm2");
+ 2125 3555520 : asm volatile ("pshufb %xmm5,%xmm3");
+ 2126 3555520 : asm volatile ("pxor %xmm2,%xmm6");
+ 2127 3555520 : asm volatile ("pxor %xmm3,%xmm6");
2128 :
- 2129 3568512 : asm volatile ("movdqa %0,%%xmm2" : : "m" (gfmulpshufb[V[3]][0][0]));
- 2130 3568512 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfmulpshufb[V[3]][1][0]));
- 2131 3568512 : asm volatile ("movdqa %xmm1,%xmm4");
- 2132 3568512 : asm volatile ("movdqa %xmm1,%xmm5");
- 2133 3568512 : asm volatile ("psrlw $4,%xmm5");
- 2134 3568512 : asm volatile ("pand %xmm7,%xmm4");
- 2135 3568512 : asm volatile ("pand %xmm7,%xmm5");
- 2136 3568512 : asm volatile ("pshufb %xmm4,%xmm2");
- 2137 3568512 : asm volatile ("pshufb %xmm5,%xmm3");
- 2138 3568512 : asm volatile ("pxor %xmm2,%xmm6");
- 2139 3568512 : asm volatile ("pxor %xmm3,%xmm6");
+ 2129 3555520 : asm volatile ("movdqa %0,%%xmm2" : : "m" (gfmulpshufb[V[3]][0][0]));
+ 2130 3555520 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfmulpshufb[V[3]][1][0]));
+ 2131 3555520 : asm volatile ("movdqa %xmm1,%xmm4");
+ 2132 3555520 : asm volatile ("movdqa %xmm1,%xmm5");
+ 2133 3555520 : asm volatile ("psrlw $4,%xmm5");
+ 2134 3555520 : asm volatile ("pand %xmm7,%xmm4");
+ 2135 3555520 : asm volatile ("pand %xmm7,%xmm5");
+ 2136 3555520 : asm volatile ("pshufb %xmm4,%xmm2");
+ 2137 3555520 : asm volatile ("pshufb %xmm5,%xmm3");
+ 2138 3555520 : asm volatile ("pxor %xmm2,%xmm6");
+ 2139 3555520 : asm volatile ("pxor %xmm3,%xmm6");
2140 :
- 2141 3568512 : asm volatile ("movdqa %%xmm6,%0" : "=m" (pa[1][i]));
+ 2141 3555520 : asm volatile ("movdqa %%xmm6,%0" : "=m" (pa[1][i]));
2142 : }
2143 :
2144 : raid_sse_end();
- 2145 44409 : }
+ 2145 44206 : }
2146 : #endif
2147 :
2148 : #if defined(CONFIG_X86) && defined(CONFIG_SSSE3)
diff --git a/cov/raid/x86z.c.func-sort-c.html b/cov/raid/x86z.c.func-sort-c.html
index ac5c96aa..cb2cfb47 100644
--- a/cov/raid/x86z.c.func-sort-c.html
+++ b/cov/raid/x86z.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/raid/x86z.c.func.html b/cov/raid/x86z.c.func.html
index 41e2c249..f498b4e6 100644
--- a/cov/raid/x86z.c.func.html
+++ b/cov/raid/x86z.c.func.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/raid/x86z.c.gcov.html b/cov/raid/x86z.c.gcov.html
index 658f2eda..9039ba20 100644
--- a/cov/raid/x86z.c.gcov.html
+++ b/cov/raid/x86z.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/tommyds/index-sort-f.html b/cov/tommyds/index-sort-f.html
index 0c2c28a7..10ac305b 100644
--- a/cov/tommyds/index-sort-f.html
+++ b/cov/tommyds/index-sort-f.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/tommyds/index-sort-l.html b/cov/tommyds/index-sort-l.html
index 42d4d7d5..ac04e945 100644
--- a/cov/tommyds/index-sort-l.html
+++ b/cov/tommyds/index-sort-l.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/tommyds/index.html b/cov/tommyds/index.html
index 757ddbd8..ecd00113 100644
--- a/cov/tommyds/index.html
+++ b/cov/tommyds/index.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/tommyds/tommyarray.c.func-sort-c.html b/cov/tommyds/tommyarray.c.func-sort-c.html
index b7c42076..eb0f50ec 100644
--- a/cov/tommyds/tommyarray.c.func-sort-c.html
+++ b/cov/tommyds/tommyarray.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/tommyds/tommyarray.c.func.html b/cov/tommyds/tommyarray.c.func.html
index 9ea01c20..ea4d5acb 100644
--- a/cov/tommyds/tommyarray.c.func.html
+++ b/cov/tommyds/tommyarray.c.func.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/tommyds/tommyarray.c.gcov.html b/cov/tommyds/tommyarray.c.gcov.html
index f9f40a61..1e28d9b1 100644
--- a/cov/tommyds/tommyarray.c.gcov.html
+++ b/cov/tommyds/tommyarray.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/tommyds/tommyarray.h.func-sort-c.html b/cov/tommyds/tommyarray.h.func-sort-c.html
index f5bb5e63..47f38cb2 100644
--- a/cov/tommyds/tommyarray.h.func-sort-c.html
+++ b/cov/tommyds/tommyarray.h.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -60,12 +60,12 @@
Hit count  |
- | tommy_array_ref |
- 15269081 |
+ tommy_array_get |
+ 15295882 |
- | tommy_array_get |
- 15267826 |
+ tommy_array_ref |
+ 15273609 |
| tommy_array_size |
diff --git a/cov/tommyds/tommyarray.h.func.html b/cov/tommyds/tommyarray.h.func.html
index 0c171236..094f71fc 100644
--- a/cov/tommyds/tommyarray.h.func.html
+++ b/cov/tommyds/tommyarray.h.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,7 +61,7 @@
| tommy_array_get |
- 15267826 |
+ 15295882 |
| tommy_array_insert |
@@ -69,7 +69,7 @@
| tommy_array_ref |
- 15269081 |
+ 15273609 |
| tommy_array_set |
diff --git a/cov/tommyds/tommyarray.h.gcov.html b/cov/tommyds/tommyarray.h.gcov.html
index 4f787277..306db8c1 100644
--- a/cov/tommyds/tommyarray.h.gcov.html
+++ b/cov/tommyds/tommyarray.h.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -152,16 +152,16 @@
90 : * You must be sure that space for this position is already
91 : * allocated calling tommy_array_grow().
92 : */
- 93 15269081 : tommy_inline void** tommy_array_ref(tommy_array* array, tommy_count_t pos)
+ 93 15273609 : tommy_inline void** tommy_array_ref(tommy_array* array, tommy_count_t pos)
94 : {
95 : tommy_uint_t bsr;
96 :
- 97 15269081 : assert(pos < array->count);
+ 97 15273609 : assert(pos < array->count);
98 :
99 : /* get the highest bit set, in case of all 0, return 0 */
- 100 15269081 : bsr = tommy_ilog2_u32(pos | 1);
+ 100 15273609 : bsr = tommy_ilog2_u32(pos | 1);
101 :
- 102 15272644 : return &array->bucket[bsr][pos];
+ 102 15288941 : return &array->bucket[bsr][pos];
103 : }
104 :
105 : /**
@@ -179,9 +179,9 @@
117 : * You must be sure that space for this position is already
118 : * allocated calling tommy_array_grow().
119 : */
- 120 15267826 : tommy_inline void* tommy_array_get(tommy_array* array, tommy_count_t pos)
+ 120 15295882 : tommy_inline void* tommy_array_get(tommy_array* array, tommy_count_t pos)
121 : {
- 122 15267826 : return *tommy_array_ref(array, pos);
+ 122 15295882 : return *tommy_array_ref(array, pos);
123 : }
124 :
125 : /**
diff --git a/cov/tommyds/tommyarrayblk.c.func-sort-c.html b/cov/tommyds/tommyarrayblk.c.func-sort-c.html
index 323d33c2..b81595fd 100644
--- a/cov/tommyds/tommyarrayblk.c.func-sort-c.html
+++ b/cov/tommyds/tommyarrayblk.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/tommyds/tommyarrayblk.c.func.html b/cov/tommyds/tommyarrayblk.c.func.html
index e52e0c62..06bbfd2d 100644
--- a/cov/tommyds/tommyarrayblk.c.func.html
+++ b/cov/tommyds/tommyarrayblk.c.func.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/tommyds/tommyarrayblk.c.gcov.html b/cov/tommyds/tommyarrayblk.c.gcov.html
index 1b7676f4..deef2d86 100644
--- a/cov/tommyds/tommyarrayblk.c.gcov.html
+++ b/cov/tommyds/tommyarrayblk.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/tommyds/tommyarrayblk.h.func-sort-c.html b/cov/tommyds/tommyarrayblk.h.func-sort-c.html
index 5ca27edb..774c7f4c 100644
--- a/cov/tommyds/tommyarrayblk.h.func-sort-c.html
+++ b/cov/tommyds/tommyarrayblk.h.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/tommyds/tommyarrayblk.h.func.html b/cov/tommyds/tommyarrayblk.h.func.html
index 7516b3fa..0c988a32 100644
--- a/cov/tommyds/tommyarrayblk.h.func.html
+++ b/cov/tommyds/tommyarrayblk.h.func.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/tommyds/tommyarrayblk.h.gcov.html b/cov/tommyds/tommyarrayblk.h.gcov.html
index edab3915..dd4893ab 100644
--- a/cov/tommyds/tommyarrayblk.h.gcov.html
+++ b/cov/tommyds/tommyarrayblk.h.gcov.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/tommyds/tommyarrayblkof.c.func-sort-c.html b/cov/tommyds/tommyarrayblkof.c.func-sort-c.html
index 805ac844..9b15c5a4 100644
--- a/cov/tommyds/tommyarrayblkof.c.func-sort-c.html
+++ b/cov/tommyds/tommyarrayblkof.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,7 +61,7 @@
| tommy_arrayblkof_grow |
- 1609618 |
+ 1609741 |
| tommy_arrayblkof_init |
diff --git a/cov/tommyds/tommyarrayblkof.c.func.html b/cov/tommyds/tommyarrayblkof.c.func.html
index 36a316ad..17140f12 100644
--- a/cov/tommyds/tommyarrayblkof.c.func.html
+++ b/cov/tommyds/tommyarrayblkof.c.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -65,7 +65,7 @@
| tommy_arrayblkof_grow |
- 1609618 |
+ 1609741 |
| tommy_arrayblkof_init |
diff --git a/cov/tommyds/tommyarrayblkof.c.gcov.html b/cov/tommyds/tommyarrayblkof.c.gcov.html
index ccce00da..4da680ca 100644
--- a/cov/tommyds/tommyarrayblkof.c.gcov.html
+++ b/cov/tommyds/tommyarrayblkof.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -110,13 +110,13 @@
48 227 : tommy_array_done(&array->block);
49 227 : }
50 :
- 51 1609618 : void tommy_arrayblkof_grow(tommy_arrayblkof* array, tommy_count_t count)
+ 51 1609741 : void tommy_arrayblkof_grow(tommy_arrayblkof* array, tommy_count_t count)
52 : {
53 : tommy_count_t block_max;
54 : tommy_count_t block_mac;
55 :
- 56 1609618 : if (array->count >= count)
- 57 1700455 : return;
+ 56 1609741 : if (array->count >= count)
+ 57 1700701 : return;
58 1518781 : array->count = count;
59 :
60 1518781 : block_max = (count + TOMMY_ARRAYBLKOF_SIZE - 1) / TOMMY_ARRAYBLKOF_SIZE;
diff --git a/cov/tommyds/tommyarrayblkof.h.func-sort-c.html b/cov/tommyds/tommyarrayblkof.h.func-sort-c.html
index 7c3ce483..5a904630 100644
--- a/cov/tommyds/tommyarrayblkof.h.func-sort-c.html
+++ b/cov/tommyds/tommyarrayblkof.h.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,11 +61,11 @@
| tommy_arrayblkof_ref |
- 11669209 |
+ 11688426 |
| tommy_arrayblkof_size |
- 10549174 |
+ 10571361 |
diff --git a/cov/tommyds/tommyarrayblkof.h.func.html b/cov/tommyds/tommyarrayblkof.h.func.html
index 296efe6a..aab7c7c9 100644
--- a/cov/tommyds/tommyarrayblkof.h.func.html
+++ b/cov/tommyds/tommyarrayblkof.h.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,11 +61,11 @@
| tommy_arrayblkof_ref |
- 11669209 |
+ 11688426 |
| tommy_arrayblkof_size |
- 10549174 |
+ 10571361 |
diff --git a/cov/tommyds/tommyarrayblkof.h.gcov.html b/cov/tommyds/tommyarrayblkof.h.gcov.html
index d35382c5..41d4c08a 100644
--- a/cov/tommyds/tommyarrayblkof.h.gcov.html
+++ b/cov/tommyds/tommyarrayblkof.h.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -148,23 +148,23 @@
86 : * You must be sure that space for this position is already
87 : * allocated calling tommy_arrayblkof_grow().
88 : */
- 89 11669209 : tommy_inline void* tommy_arrayblkof_ref(tommy_arrayblkof* array, tommy_count_t pos)
+ 89 11688426 : tommy_inline void* tommy_arrayblkof_ref(tommy_arrayblkof* array, tommy_count_t pos)
90 : {
91 : unsigned char* base;
92 :
- 93 11669209 : assert(pos < array->count);
+ 93 11688426 : assert(pos < array->count);
94 :
- 95 11669209 : base = tommy_cast(unsigned char*, tommy_array_get(&array->block, pos / TOMMY_ARRAYBLKOF_SIZE));
+ 95 11688426 : base = tommy_cast(unsigned char*, tommy_array_get(&array->block, pos / TOMMY_ARRAYBLKOF_SIZE));
96 :
- 97 11653374 : return base + (pos % TOMMY_ARRAYBLKOF_SIZE) * array->element_size;
+ 97 11693987 : return base + (pos % TOMMY_ARRAYBLKOF_SIZE) * array->element_size;
98 : }
99 :
100 : /**
101 : * Gets the initialized size of the array.
102 : */
- 103 10549174 : tommy_inline tommy_count_t tommy_arrayblkof_size(tommy_arrayblkof* array)
+ 103 10571361 : tommy_inline tommy_count_t tommy_arrayblkof_size(tommy_arrayblkof* array)
104 : {
- 105 10549174 : return array->count;
+ 105 10571361 : return array->count;
106 : }
107 :
108 : /**
diff --git a/cov/tommyds/tommychain.h.func-sort-c.html b/cov/tommyds/tommychain.h.func-sort-c.html
index dec46b5c..9f911f5f 100644
--- a/cov/tommyds/tommychain.h.func-sort-c.html
+++ b/cov/tommyds/tommychain.h.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,19 +61,19 @@
| tommy_chain_splice |
- 4083447 |
+ 4073661 |
| tommy_chain_merge_degenerated |
- 1153837 |
+ 1153954 |
| tommy_chain_concat |
- 1147561 |
+ 1147870 |
| tommy_chain_merge |
- 427404 |
+ 427121 |
| tommy_chain_mergesort |
diff --git a/cov/tommyds/tommychain.h.func.html b/cov/tommyds/tommychain.h.func.html
index 52908717..5ac1a9e6 100644
--- a/cov/tommyds/tommychain.h.func.html
+++ b/cov/tommyds/tommychain.h.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,15 +61,15 @@
| tommy_chain_concat |
- 1147561 |
+ 1147870 |
| tommy_chain_merge |
- 427404 |
+ 427121 |
| tommy_chain_merge_degenerated |
- 1153837 |
+ 1153954 |
| tommy_chain_mergesort |
@@ -77,7 +77,7 @@
| tommy_chain_splice |
- 4083447 |
+ 4073661 |
diff --git a/cov/tommyds/tommychain.h.gcov.html b/cov/tommyds/tommychain.h.gcov.html
index 604fb394..8ed60019 100644
--- a/cov/tommyds/tommychain.h.gcov.html
+++ b/cov/tommyds/tommychain.h.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -119,83 +119,83 @@
57 : /**
58 : * Splices a chain in the middle of another chain.
59 : */
- 60 4083447 : tommy_inline void tommy_chain_splice(tommy_node* first_before, tommy_node* first_after, tommy_node* second_head, tommy_node* second_tail)
+ 60 4073661 : tommy_inline void tommy_chain_splice(tommy_node* first_before, tommy_node* first_after, tommy_node* second_head, tommy_node* second_tail)
61 : {
62 : /* set the prev list */
- 63 4083447 : first_after->prev = second_tail;
- 64 4083447 : second_head->prev = first_before;
+ 63 4073661 : first_after->prev = second_tail;
+ 64 4073661 : second_head->prev = first_before;
65 :
66 : /* set the next list */
- 67 4083447 : first_before->next = second_head;
- 68 4083447 : second_tail->next = first_after;
- 69 4083447 : }
+ 67 4073661 : first_before->next = second_head;
+ 68 4073661 : second_tail->next = first_after;
+ 69 4073661 : }
70 :
71 : /**
72 : * Concats two chains.
73 : */
- 74 1147561 : tommy_inline void tommy_chain_concat(tommy_node* first_tail, tommy_node* second_head)
+ 74 1147870 : tommy_inline void tommy_chain_concat(tommy_node* first_tail, tommy_node* second_head)
75 : {
76 : /* set the prev list */
- 77 1147561 : second_head->prev = first_tail;
+ 77 1147870 : second_head->prev = first_tail;
78 :
79 : /* set the next list */
- 80 1147561 : first_tail->next = second_head;
- 81 1147561 : }
+ 80 1147870 : first_tail->next = second_head;
+ 81 1147870 : }
82 :
83 : /**
84 : * Merges two chains.
85 : */
- 86 427404 : tommy_inline void tommy_chain_merge(tommy_chain* first, tommy_chain* second, tommy_compare_func* cmp)
+ 86 427121 : tommy_inline void tommy_chain_merge(tommy_chain* first, tommy_chain* second, tommy_compare_func* cmp)
87 : {
- 88 427404 : tommy_node* first_i = first->head;
- 89 427404 : tommy_node* second_i = second->head;
+ 88 427121 : tommy_node* first_i = first->head;
+ 89 427121 : tommy_node* second_i = second->head;
90 :
91 : /* merge */
92 : while (1) {
- 93 8885557 : if (cmp(first_i->data, second_i->data) > 0) {
- 94 4294267 : tommy_node* next = second_i->next;
- 95 4294267 : if (first_i == first->head) {
- 96 210820 : tommy_chain_concat(second_i, first_i);
- 97 210820 : first->head = second_i;
+ 93 8866117 : if (cmp(first_i->data, second_i->data) > 0) {
+ 94 4284467 : tommy_node* next = second_i->next;
+ 95 4284467 : if (first_i == first->head) {
+ 96 210806 : tommy_chain_concat(second_i, first_i);
+ 97 210806 : first->head = second_i;
98 : } else {
- 99 4083447 : tommy_chain_splice(first_i->prev, first_i, second_i, second_i);
+ 99 4073661 : tommy_chain_splice(first_i->prev, first_i, second_i, second_i);
100 : }
- 101 4294267 : if (second_i == second->tail)
- 102 217096 : break;
- 103 4077171 : second_i = next;
+ 101 4284467 : if (second_i == second->tail)
+ 102 216890 : break;
+ 103 4067577 : second_i = next;
104 : } else {
- 105 4591290 : if (first_i == first->tail) {
- 106 210308 : tommy_chain_concat(first_i, second_i);
- 107 210308 : first->tail = second->tail;
- 108 210308 : break;
+ 105 4581650 : if (first_i == first->tail) {
+ 106 210231 : tommy_chain_concat(first_i, second_i);
+ 107 210231 : first->tail = second->tail;
+ 108 210231 : break;
109 : }
- 110 4380982 : first_i = first_i->next;
+ 110 4371419 : first_i = first_i->next;
111 : }
- 112 8458153 : }
- 113 427404 : }
+ 112 8438996 : }
+ 113 427121 : }
114 :
115 : /**
116 : * Merges two chains managing special degenerated cases.
117 : * It's funtionally equivalent at tommy_chain_merge() but faster with already ordered chains.
118 : */
- 119 1153837 : tommy_inline void tommy_chain_merge_degenerated(tommy_chain* first, tommy_chain* second, tommy_compare_func* cmp)
+ 119 1153954 : tommy_inline void tommy_chain_merge_degenerated(tommy_chain* first, tommy_chain* second, tommy_compare_func* cmp)
120 : {
121 : /* identify the condition first <= second */
- 122 1153837 : if (cmp(first->tail->data, second->head->data) <= 0) {
- 123 422569 : tommy_chain_concat(first->tail, second->head);
- 124 422569 : first->tail = second->tail;
- 125 422569 : return;
+ 122 1153954 : if (cmp(first->tail->data, second->head->data) <= 0) {
+ 123 422991 : tommy_chain_concat(first->tail, second->head);
+ 124 422991 : first->tail = second->tail;
+ 125 422991 : return;
126 : }
127 :
128 : /* identify the condition second < first */
129 : /* here we must be strict on comparison to keep the sort stable */
- 130 731268 : if (cmp(second->tail->data, first->head->data) < 0) {
- 131 303864 : tommy_chain_concat(second->tail, first->head);
- 132 303864 : first->head = second->head;
- 133 303864 : return;
+ 130 730963 : if (cmp(second->tail->data, first->head->data) < 0) {
+ 131 303842 : tommy_chain_concat(second->tail, first->head);
+ 132 303842 : first->head = second->head;
+ 133 303842 : return;
134 : }
135 :
- 136 427404 : tommy_chain_merge(first, second, cmp);
+ 136 427121 : tommy_chain_merge(first, second, cmp);
137 : }
138 :
139 : /**
@@ -241,42 +241,42 @@
179 : tommy_chain* last;
180 :
181 : /* carry bit to add */
- 182 1155310 : last = &bit[TOMMY_CHAIN_BIT_MAX];
- 183 1155310 : bit[TOMMY_CHAIN_BIT_MAX].head = node;
- 184 1155310 : bit[TOMMY_CHAIN_BIT_MAX].tail = node;
- 185 1155310 : next = node->next;
+ 182 1155427 : last = &bit[TOMMY_CHAIN_BIT_MAX];
+ 183 1155427 : bit[TOMMY_CHAIN_BIT_MAX].head = node;
+ 184 1155427 : bit[TOMMY_CHAIN_BIT_MAX].tail = node;
+ 185 1155427 : next = node->next;
186 :
187 : /* add the bit, propagating the carry */
- 188 1155310 : i = 0;
- 189 1155310 : mask = counter;
- 190 3459162 : while ((mask & 1) != 0) {
- 191 1148542 : tommy_chain_merge_degenerated(&bit[i], last, cmp);
- 192 1148542 : mask >>= 1;
- 193 1148542 : last = &bit[i];
- 194 1148542 : ++i;
+ 188 1155427 : i = 0;
+ 189 1155427 : mask = counter;
+ 190 3459506 : while ((mask & 1) != 0) {
+ 191 1148652 : tommy_chain_merge_degenerated(&bit[i], last, cmp);
+ 192 1148652 : mask >>= 1;
+ 193 1148652 : last = &bit[i];
+ 194 1148652 : ++i;
195 : }
196 :
197 : /* copy the carry in the first empty bit */
- 198 1155310 : bit[i] = *last;
+ 198 1155427 : bit[i] = *last;
199 :
200 : /* add the carry in the counter */
- 201 1155310 : ++counter;
+ 201 1155427 : ++counter;
202 :
- 203 1155310 : if (node == tail)
+ 203 1155427 : if (node == tail)
204 1473 : break;
- 205 1153837 : node = next;
- 206 1153837 : }
+ 205 1153954 : node = next;
+ 206 1153954 : }
207 :
208 : /* merge the buckets */
209 1473 : i = tommy_ctz_u32(counter);
210 1473 : mask = counter >> i;
- 211 10798 : while (mask != 1) {
- 212 7852 : mask >>= 1;
- 213 7852 : if (mask & 1)
- 214 5295 : tommy_chain_merge_degenerated(&bit[i + 1], &bit[i], cmp);
+ 211 10792 : while (mask != 1) {
+ 212 7846 : mask >>= 1;
+ 213 7846 : if (mask & 1)
+ 214 5302 : tommy_chain_merge_degenerated(&bit[i + 1], &bit[i], cmp);
215 : else
- 216 2557 : bit[i + 1] = bit[i];
- 217 7852 : ++i;
+ 216 2544 : bit[i + 1] = bit[i];
+ 217 7846 : ++i;
218 : }
219 :
220 1473 : *chain = bit[i];
diff --git a/cov/tommyds/tommyhash.c.func-sort-c.html b/cov/tommyds/tommyhash.c.func-sort-c.html
index d96977bb..9466aeab 100644
--- a/cov/tommyds/tommyhash.c.func-sort-c.html
+++ b/cov/tommyds/tommyhash.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,11 +61,11 @@
| tommy_le_uint32_read |
- 11236413 |
+ 11236438 |
| tommy_hash_u32 |
- 3932695 |
+ 3932841 |
| tommy_hash_u64 |
diff --git a/cov/tommyds/tommyhash.c.func.html b/cov/tommyds/tommyhash.c.func.html
index 87d1f19a..311a42c9 100644
--- a/cov/tommyds/tommyhash.c.func.html
+++ b/cov/tommyds/tommyhash.c.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,7 +61,7 @@
| tommy_hash_u32 |
- 3932695 |
+ 3932841 |
| tommy_hash_u64 |
@@ -69,7 +69,7 @@
| tommy_le_uint32_read |
- 11236413 |
+ 11236438 |
diff --git a/cov/tommyds/tommyhash.c.gcov.html b/cov/tommyds/tommyhash.c.gcov.html
index f2d62a19..30b59be8 100644
--- a/cov/tommyds/tommyhash.c.gcov.html
+++ b/cov/tommyds/tommyhash.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -92,12 +92,12 @@
30 : /******************************************************************************/
31 : /* hash */
32 :
- 33 11236413 : tommy_inline tommy_uint32_t tommy_le_uint32_read(const void* ptr)
+ 33 11236438 : tommy_inline tommy_uint32_t tommy_le_uint32_read(const void* ptr)
34 : {
35 : /* allow unaligned read on Intel x86 and x86_64 platforms */
36 : #if defined(__i386__) || defined(_M_IX86) || defined(_X86_) || defined(__x86_64__) || defined(_M_X64)
37 : /* defines from http://predef.sourceforge.net/ */
- 38 11236413 : return *(const tommy_uint32_t*)ptr;
+ 38 11236438 : return *(const tommy_uint32_t*)ptr;
39 : #else
40 : const unsigned char* ptr8 = tommy_cast(const unsigned char*, ptr);
41 : return ptr8[0] + ((tommy_uint32_t)ptr8[1] << 8) + ((tommy_uint32_t)ptr8[2] << 16) + ((tommy_uint32_t)ptr8[3] << 24);
@@ -128,53 +128,53 @@
66 : c ^= b; c -= tommy_rot(b, 24); \
67 : } while (0)
68 :
- 69 3932695 : tommy_uint32_t tommy_hash_u32(tommy_uint32_t init_val, const void* void_key, tommy_size_t key_len)
+ 69 3932841 : tommy_uint32_t tommy_hash_u32(tommy_uint32_t init_val, const void* void_key, tommy_size_t key_len)
70 : {
- 71 3932695 : const unsigned char* key = tommy_cast(const unsigned char*, void_key);
+ 71 3932841 : const unsigned char* key = tommy_cast(const unsigned char*, void_key);
72 : tommy_uint32_t a, b, c;
73 :
- 74 3932695 : a = b = c = 0xdeadbeef + ((tommy_uint32_t)key_len) + init_val;
+ 74 3932841 : a = b = c = 0xdeadbeef + ((tommy_uint32_t)key_len) + init_val;
75 :
- 76 9922363 : while (key_len > 12) {
- 77 2056973 : a += tommy_le_uint32_read(key + 0);
- 78 2056973 : b += tommy_le_uint32_read(key + 4);
- 79 2056973 : c += tommy_le_uint32_read(key + 8);
+ 76 9922648 : while (key_len > 12) {
+ 77 2056966 : a += tommy_le_uint32_read(key + 0);
+ 78 2056966 : b += tommy_le_uint32_read(key + 4);
+ 79 2056966 : c += tommy_le_uint32_read(key + 8);
80 :
- 81 2056973 : tommy_mix(a, b, c);
+ 81 2056966 : tommy_mix(a, b, c);
82 :
- 83 2056973 : key_len -= 12;
- 84 2056973 : key += 12;
+ 83 2056966 : key_len -= 12;
+ 84 2056966 : key += 12;
85 : }
86 :
- 87 3932695 : switch (key_len) {
+ 87 3932841 : switch (key_len) {
88 : case 0 :
89 1 : return c; /* used only when called with a zero length */
90 : case 12 :
- 91 201767 : c += tommy_le_uint32_read(key + 8);
- 92 201767 : b += tommy_le_uint32_read(key + 4);
- 93 201767 : a += tommy_le_uint32_read(key + 0);
- 94 201767 : break;
- 95 210935 : case 11 : c += ((tommy_uint32_t)key[10]) << 16;
- 96 620774 : case 10 : c += ((tommy_uint32_t)key[9]) << 8;
- 97 1027793 : case 9 : c += key[8];
+ 91 201770 : c += tommy_le_uint32_read(key + 8);
+ 92 201770 : b += tommy_le_uint32_read(key + 4);
+ 93 201770 : a += tommy_le_uint32_read(key + 0);
+ 94 201770 : break;
+ 95 210915 : case 11 : c += ((tommy_uint32_t)key[10]) << 16;
+ 96 620733 : case 10 : c += ((tommy_uint32_t)key[9]) << 8;
+ 97 1027724 : case 9 : c += key[8];
98 : case 8 :
- 99 1426056 : b += tommy_le_uint32_read(key + 4);
- 100 1426056 : a += tommy_le_uint32_read(key + 0);
- 101 1426056 : break;
- 102 399999 : case 7 : b += ((tommy_uint32_t)key[6]) << 16;
- 103 787115 : case 6 : b += ((tommy_uint32_t)key[5]) << 8;
- 104 1189275 : case 5 : b += key[4];
+ 99 1425951 : b += tommy_le_uint32_read(key + 4);
+ 100 1425951 : a += tommy_le_uint32_read(key + 0);
+ 101 1425951 : break;
+ 102 400019 : case 7 : b += ((tommy_uint32_t)key[6]) << 16;
+ 103 787136 : case 6 : b += ((tommy_uint32_t)key[5]) << 8;
+ 104 1189288 : case 5 : b += key[4];
105 : case 4 :
- 106 1608032 : a += tommy_le_uint32_read(key + 0);
- 107 1608032 : break;
- 108 291889 : case 3 : a += ((tommy_uint32_t)key[2]) << 16;
- 109 493294 : case 2 : a += ((tommy_uint32_t)key[1]) << 8;
- 110 696839 : case 1 : a += key[0];
+ 106 1608279 : a += tommy_le_uint32_read(key + 0);
+ 107 1608279 : break;
+ 108 291874 : case 3 : a += ((tommy_uint32_t)key[2]) << 16;
+ 109 493291 : case 2 : a += ((tommy_uint32_t)key[1]) << 8;
+ 110 696840 : case 1 : a += key[0];
111 : }
112 :
- 113 3932694 : tommy_final(a, b, c);
+ 113 3932840 : tommy_final(a, b, c);
114 :
- 115 3932694 : return c;
+ 115 3932840 : return c;
116 : }
117 :
118 19 : tommy_uint64_t tommy_hash_u64(tommy_uint64_t init_val, const void* void_key, tommy_size_t key_len)
diff --git a/cov/tommyds/tommyhash.h.func-sort-c.html b/cov/tommyds/tommyhash.h.func-sort-c.html
index 1106f6e3..bd9b8354 100644
--- a/cov/tommyds/tommyhash.h.func-sort-c.html
+++ b/cov/tommyds/tommyhash.h.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,11 +61,11 @@
| tommy_inthash_u32 |
- 18417585 |
+ 18417414 |
| tommy_inthash_u64 |
- 4822885 |
+ 4822298 |
diff --git a/cov/tommyds/tommyhash.h.func.html b/cov/tommyds/tommyhash.h.func.html
index 49cfcdb7..d1761086 100644
--- a/cov/tommyds/tommyhash.h.func.html
+++ b/cov/tommyds/tommyhash.h.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,11 +61,11 @@
| tommy_inthash_u32 |
- 18417585 |
+ 18417414 |
| tommy_inthash_u64 |
- 4822885 |
+ 4822298 |
diff --git a/cov/tommyds/tommyhash.h.gcov.html b/cov/tommyds/tommyhash.h.gcov.html
index 71771923..33130e85 100644
--- a/cov/tommyds/tommyhash.h.gcov.html
+++ b/cov/tommyds/tommyhash.h.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -139,17 +139,17 @@
77 : * Implementation of the Robert Jenkins "4-byte Integer Hashing",
78 : * from http://burtleburtle.net/bob/hash/integer.html
79 : */
- 80 18417585 : tommy_inline tommy_uint32_t tommy_inthash_u32(tommy_uint32_t key)
+ 80 18417414 : tommy_inline tommy_uint32_t tommy_inthash_u32(tommy_uint32_t key)
81 : {
- 82 18417585 : key -= key << 6;
- 83 18417585 : key ^= key >> 17;
- 84 18417585 : key -= key << 9;
- 85 18417585 : key ^= key << 4;
- 86 18417585 : key -= key << 3;
- 87 18417585 : key ^= key << 10;
- 88 18417585 : key ^= key >> 15;
+ 82 18417414 : key -= key << 6;
+ 83 18417414 : key ^= key >> 17;
+ 84 18417414 : key -= key << 9;
+ 85 18417414 : key ^= key << 4;
+ 86 18417414 : key -= key << 3;
+ 87 18417414 : key ^= key << 10;
+ 88 18417414 : key ^= key >> 15;
89 :
- 90 18417585 : return key;
+ 90 18417414 : return key;
91 : }
92 :
93 : /**
@@ -157,17 +157,17 @@
95 : * Implementation of the Thomas Wang "Integer Hash Function",
96 : * from http://www.cris.com/~Ttwang/tech/inthash.htm
97 : */
- 98 4822885 : tommy_inline tommy_uint64_t tommy_inthash_u64(tommy_uint64_t key)
+ 98 4822298 : tommy_inline tommy_uint64_t tommy_inthash_u64(tommy_uint64_t key)
99 : {
- 100 4822885 : key = ~key + (key << 21);
- 101 4822885 : key = key ^ (key >> 24);
- 102 4822885 : key = key + (key << 3) + (key << 8);
- 103 4822885 : key = key ^ (key >> 14);
- 104 4822885 : key = key + (key << 2) + (key << 4);
- 105 4822885 : key = key ^ (key >> 28);
- 106 4822885 : key = key + (key << 31);
+ 100 4822298 : key = ~key + (key << 21);
+ 101 4822298 : key = key ^ (key >> 24);
+ 102 4822298 : key = key + (key << 3) + (key << 8);
+ 103 4822298 : key = key ^ (key >> 14);
+ 104 4822298 : key = key + (key << 2) + (key << 4);
+ 105 4822298 : key = key ^ (key >> 28);
+ 106 4822298 : key = key + (key << 31);
107 :
- 108 4822885 : return key;
+ 108 4822298 : return key;
109 : }
110 :
111 : #endif
diff --git a/cov/tommyds/tommyhashdyn.c.func-sort-c.html b/cov/tommyds/tommyhashdyn.c.func-sort-c.html
index f543d5bf..13e53317 100644
--- a/cov/tommyds/tommyhashdyn.c.func-sort-c.html
+++ b/cov/tommyds/tommyhashdyn.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,23 +61,23 @@
| hashdyn_grow_step |
- 12860390 |
+ 12860296 |
| tommy_hashdyn_insert |
- 12860390 |
+ 12860296 |
| hashdyn_shrink_step |
- 284934 |
+ 284348 |
| tommy_hashdyn_remove_existing |
- 284806 |
+ 284220 |
| tommy_hashdyn_resize |
- 39872 |
+ 39860 |
| tommy_hashdyn_init |
diff --git a/cov/tommyds/tommyhashdyn.c.func.html b/cov/tommyds/tommyhashdyn.c.func.html
index 4c5af758..190f8d85 100644
--- a/cov/tommyds/tommyhashdyn.c.func.html
+++ b/cov/tommyds/tommyhashdyn.c.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,11 +61,11 @@
| hashdyn_grow_step |
- 12860390 |
+ 12860296 |
| hashdyn_shrink_step |
- 284934 |
+ 284348 |
| tommy_hashdyn_done |
@@ -85,7 +85,7 @@
| tommy_hashdyn_insert |
- 12860390 |
+ 12860296 |
| tommy_hashdyn_memory_usage |
@@ -97,11 +97,11 @@
| tommy_hashdyn_remove_existing |
- 284806 |
+ 284220 |
| tommy_hashdyn_resize |
- 39872 |
+ 39860 |
diff --git a/cov/tommyds/tommyhashdyn.c.gcov.html b/cov/tommyds/tommyhashdyn.c.gcov.html
index cd764bc7..b140fbee 100644
--- a/cov/tommyds/tommyhashdyn.c.gcov.html
+++ b/cov/tommyds/tommyhashdyn.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -112,7 +112,7 @@
50 : /**
51 : * Resize the bucket vector.
52 : */
- 53 39872 : static void tommy_hashdyn_resize(tommy_hashdyn* hashdyn, tommy_count_t new_bucket_bit)
+ 53 39860 : static void tommy_hashdyn_resize(tommy_hashdyn* hashdyn, tommy_count_t new_bucket_bit)
54 : {
55 : tommy_count_t bucket_bit;
56 : tommy_count_t bucket_max;
@@ -120,38 +120,38 @@
58 : tommy_count_t new_bucket_mask;
59 : tommy_hashdyn_node** new_bucket;
60 :
- 61 39872 : bucket_bit = hashdyn->bucket_bit;
- 62 39872 : bucket_max = hashdyn->bucket_max;
+ 61 39860 : bucket_bit = hashdyn->bucket_bit;
+ 62 39860 : bucket_max = hashdyn->bucket_max;
63 :
- 64 39872 : new_bucket_max = 1 << new_bucket_bit;
- 65 39872 : new_bucket_mask = new_bucket_max - 1;
+ 64 39860 : new_bucket_max = 1 << new_bucket_bit;
+ 65 39860 : new_bucket_mask = new_bucket_max - 1;
66 :
67 : /* allocate the new vector using malloc() and not calloc() */
68 : /* because data is fully initialized in the update process */
- 69 39872 : new_bucket = tommy_cast(tommy_hashdyn_node**, tommy_malloc(new_bucket_max * sizeof(tommy_hashdyn_node*)));
+ 69 39860 : new_bucket = tommy_cast(tommy_hashdyn_node**, tommy_malloc(new_bucket_max * sizeof(tommy_hashdyn_node*)));
70 :
71 : /* reinsert all the elements */
- 72 39872 : if (new_bucket_bit > bucket_bit) {
+ 72 39860 : if (new_bucket_bit > bucket_bit) {
73 : tommy_count_t i;
74 :
75 : /* grow */
- 76 31392079 : for (i = 0; i < bucket_max; ++i) {
+ 76 31390627 : for (i = 0; i < bucket_max; ++i) {
77 : tommy_hashdyn_node* j;
78 :
79 : /* setup the new two buckets */
- 80 31352256 : new_bucket[i] = 0;
- 81 31352256 : new_bucket[i + bucket_max] = 0;
+ 80 31350816 : new_bucket[i] = 0;
+ 81 31350816 : new_bucket[i + bucket_max] = 0;
82 :
83 : /* reinsert the bucket */
- 84 31352256 : j = hashdyn->bucket[i];
- 85 78380640 : while (j) {
- 86 15676128 : tommy_hashdyn_node* j_next = j->next;
- 87 15676128 : tommy_count_t pos = j->key & new_bucket_mask;
- 88 15676128 : if (new_bucket[pos])
- 89 1859714 : tommy_list_insert_tail_not_empty(new_bucket[pos], j);
+ 84 31350816 : j = hashdyn->bucket[i];
+ 85 78377040 : while (j) {
+ 86 15675408 : tommy_hashdyn_node* j_next = j->next;
+ 87 15675408 : tommy_count_t pos = j->key & new_bucket_mask;
+ 88 15675408 : if (new_bucket[pos])
+ 89 1860861 : tommy_list_insert_tail_not_empty(new_bucket[pos], j);
90 : else
- 91 13816414 : tommy_list_insert_first(&new_bucket[pos], j);
- 92 15676128 : j = j_next;
+ 91 13814547 : tommy_list_insert_first(&new_bucket[pos], j);
+ 92 15675408 : j = j_next;
93 : }
94 : }
95 : } else {
@@ -167,59 +167,59 @@
105 : }
106 : }
107 :
- 108 39872 : tommy_free(hashdyn->bucket);
+ 108 39860 : tommy_free(hashdyn->bucket);
109 :
110 : /* setup */
- 111 39872 : hashdyn->bucket_bit = new_bucket_bit;
- 112 39872 : hashdyn->bucket_max = new_bucket_max;
- 113 39872 : hashdyn->bucket_mask = new_bucket_mask;
- 114 39872 : hashdyn->bucket = new_bucket;
- 115 39872 : }
+ 111 39860 : hashdyn->bucket_bit = new_bucket_bit;
+ 112 39860 : hashdyn->bucket_max = new_bucket_max;
+ 113 39860 : hashdyn->bucket_mask = new_bucket_mask;
+ 114 39860 : hashdyn->bucket = new_bucket;
+ 115 39860 : }
116 :
117 : /**
118 : * Grow.
119 : */
- 120 12860390 : tommy_inline void hashdyn_grow_step(tommy_hashdyn* hashdyn)
+ 120 12860296 : tommy_inline void hashdyn_grow_step(tommy_hashdyn* hashdyn)
121 : {
122 : /* grow if more than 50% full */
- 123 12860390 : if (hashdyn->count >= hashdyn->bucket_max / 2)
- 124 39823 : tommy_hashdyn_resize(hashdyn, hashdyn->bucket_bit + 1);
- 125 12860390 : }
+ 123 12860296 : if (hashdyn->count >= hashdyn->bucket_max / 2)
+ 124 39811 : tommy_hashdyn_resize(hashdyn, hashdyn->bucket_bit + 1);
+ 125 12860296 : }
126 :
127 : /**
128 : * Shrink.
129 : */
- 130 284934 : tommy_inline void hashdyn_shrink_step(tommy_hashdyn* hashdyn)
+ 130 284348 : tommy_inline void hashdyn_shrink_step(tommy_hashdyn* hashdyn)
131 : {
132 : /* shrink if less than 12.5% full */
- 133 284934 : if (hashdyn->count <= hashdyn->bucket_max / 8 && hashdyn->bucket_bit > TOMMY_HASHDYN_BIT)
+ 133 284348 : if (hashdyn->count <= hashdyn->bucket_max / 8 && hashdyn->bucket_bit > TOMMY_HASHDYN_BIT)
134 49 : tommy_hashdyn_resize(hashdyn, hashdyn->bucket_bit - 1);
- 135 284934 : }
+ 135 284348 : }
136 :
- 137 12860390 : void tommy_hashdyn_insert(tommy_hashdyn* hashdyn, tommy_hashdyn_node* node, void* data, tommy_hash_t hash)
+ 137 12860296 : void tommy_hashdyn_insert(tommy_hashdyn* hashdyn, tommy_hashdyn_node* node, void* data, tommy_hash_t hash)
138 : {
- 139 12860390 : tommy_count_t pos = hash & hashdyn->bucket_mask;
+ 139 12860296 : tommy_count_t pos = hash & hashdyn->bucket_mask;
140 :
- 141 12860390 : tommy_list_insert_tail(&hashdyn->bucket[pos], node, data);
+ 141 12860296 : tommy_list_insert_tail(&hashdyn->bucket[pos], node, data);
142 :
- 143 12860390 : node->key = hash;
+ 143 12860296 : node->key = hash;
144 :
- 145 12860390 : ++hashdyn->count;
+ 145 12860296 : ++hashdyn->count;
146 :
- 147 12860390 : hashdyn_grow_step(hashdyn);
- 148 12860390 : }
+ 147 12860296 : hashdyn_grow_step(hashdyn);
+ 148 12860296 : }
149 :
- 150 284806 : void* tommy_hashdyn_remove_existing(tommy_hashdyn* hashdyn, tommy_hashdyn_node* node)
+ 150 284220 : void* tommy_hashdyn_remove_existing(tommy_hashdyn* hashdyn, tommy_hashdyn_node* node)
151 : {
- 152 284806 : tommy_count_t pos = node->key & hashdyn->bucket_mask;
+ 152 284220 : tommy_count_t pos = node->key & hashdyn->bucket_mask;
153 :
- 154 284806 : tommy_list_remove_existing(&hashdyn->bucket[pos], node);
+ 154 284220 : tommy_list_remove_existing(&hashdyn->bucket[pos], node);
155 :
- 156 284806 : --hashdyn->count;
+ 156 284220 : --hashdyn->count;
157 :
- 158 284806 : hashdyn_shrink_step(hashdyn);
+ 158 284220 : hashdyn_shrink_step(hashdyn);
159 :
- 160 284806 : return node->data;
+ 160 284220 : return node->data;
161 : }
162 :
163 256 : void* tommy_hashdyn_remove(tommy_hashdyn* hashdyn, tommy_search_func* cmp, const void* cmp_arg, tommy_hash_t hash)
@@ -253,10 +253,10 @@
191 5812246 : for (pos = 0; pos < bucket_max; ++pos) {
192 5812016 : tommy_hashdyn_node* node = bucket[pos];
193 :
- 194 13483575 : while (node) {
- 195 1859543 : void* data = node->data;
- 196 1859543 : node = node->next;
- 197 1859543 : func(data);
+ 194 13483818 : while (node) {
+ 195 1859786 : void* data = node->data;
+ 196 1859786 : node = node->next;
+ 197 1859786 : func(data);
198 : }
199 : }
200 230 : }
diff --git a/cov/tommyds/tommyhashdyn.h.func-sort-c.html b/cov/tommyds/tommyhashdyn.h.func-sort-c.html
index bffd008b..524259cb 100644
--- a/cov/tommyds/tommyhashdyn.h.func-sort-c.html
+++ b/cov/tommyds/tommyhashdyn.h.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,11 +61,11 @@
| tommy_hashdyn_bucket |
- 3071206 |
+ 3070554 |
| tommy_hashdyn_search |
- 3071206 |
+ 3070554 |
| tommy_hashdyn_count |
diff --git a/cov/tommyds/tommyhashdyn.h.func.html b/cov/tommyds/tommyhashdyn.h.func.html
index 61832970..204c62c7 100644
--- a/cov/tommyds/tommyhashdyn.h.func.html
+++ b/cov/tommyds/tommyhashdyn.h.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,7 +61,7 @@
| tommy_hashdyn_bucket |
- 3071206 |
+ 3070554 |
| tommy_hashdyn_count |
@@ -69,7 +69,7 @@
| tommy_hashdyn_search |
- 3071206 |
+ 3070554 |
diff --git a/cov/tommyds/tommyhashdyn.h.gcov.html b/cov/tommyds/tommyhashdyn.h.gcov.html
index dae096d7..448c8108 100644
--- a/cov/tommyds/tommyhashdyn.h.gcov.html
+++ b/cov/tommyds/tommyhashdyn.h.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -267,9 +267,9 @@
205 : * \param hash Hash of the element to find.
206 : * \return The head of the bucket, or 0 if empty.
207 : */
- 208 3071206 : tommy_inline tommy_hashdyn_node* tommy_hashdyn_bucket(tommy_hashdyn* hashdyn, tommy_hash_t hash)
+ 208 3070554 : tommy_inline tommy_hashdyn_node* tommy_hashdyn_bucket(tommy_hashdyn* hashdyn, tommy_hash_t hash)
209 : {
- 210 3071206 : return hashdyn->bucket[hash & hashdyn->bucket_mask];
+ 210 3070554 : return hashdyn->bucket[hash & hashdyn->bucket_mask];
211 : }
212 :
213 : /**
@@ -282,17 +282,17 @@
220 : * \param hash Hash of the element to find.
221 : * \return The first element found, or 0 if none.
222 : */
- 223 3071206 : tommy_inline void* tommy_hashdyn_search(tommy_hashdyn* hashdyn, tommy_search_func* cmp, const void* cmp_arg, tommy_hash_t hash)
+ 223 3070554 : tommy_inline void* tommy_hashdyn_search(tommy_hashdyn* hashdyn, tommy_search_func* cmp, const void* cmp_arg, tommy_hash_t hash)
224 : {
- 225 3071206 : tommy_hashdyn_node* i = tommy_hashdyn_bucket(hashdyn, hash);
+ 225 3070554 : tommy_hashdyn_node* i = tommy_hashdyn_bucket(hashdyn, hash);
226 :
- 227 6828628 : while (i) {
+ 227 6829396 : while (i) {
228 : /* we first check if the hash matches, as in the same bucket we may have multiples hash values */
- 229 1729368 : if (i->key == hash && cmp(cmp_arg, i->data) == 0)
- 230 1043152 : return i->data;
- 231 686216 : i = i->next;
+ 229 1728517 : if (i->key == hash && cmp(cmp_arg, i->data) == 0)
+ 230 1040229 : return i->data;
+ 231 688288 : i = i->next;
232 : }
- 233 2028054 : return 0;
+ 233 2030325 : return 0;
234 : }
235 :
236 : /**
diff --git a/cov/tommyds/tommylist.c.func-sort-c.html b/cov/tommyds/tommylist.c.func-sort-c.html
index 47df2c6b..50240eef 100644
--- a/cov/tommyds/tommylist.c.func-sort-c.html
+++ b/cov/tommyds/tommylist.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/tommyds/tommylist.c.func.html b/cov/tommyds/tommylist.c.func.html
index 5048c524..4a3655e5 100644
--- a/cov/tommyds/tommylist.c.func.html
+++ b/cov/tommyds/tommylist.c.func.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/tommyds/tommylist.c.gcov.html b/cov/tommyds/tommylist.c.gcov.html
index d3fa6ea4..a3fd03cb 100644
--- a/cov/tommyds/tommylist.c.gcov.html
+++ b/cov/tommyds/tommylist.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -97,23 +97,23 @@
35 : tommy_node* second_head;
36 :
37 63152 : if (tommy_list_empty(second))
- 38 55852 : return;
+ 38 55942 : return;
39 :
- 40 7300 : if (tommy_list_empty(first)) {
- 41 6458 : *first = *second;
- 42 6458 : return;
+ 40 7210 : if (tommy_list_empty(first)) {
+ 41 6347 : *first = *second;
+ 42 6347 : return;
43 : }
44 :
- 45 842 : first_head = tommy_list_head(first);
- 46 842 : second_head = tommy_list_head(second);
- 47 842 : first_tail = tommy_list_tail(first);
+ 45 863 : first_head = tommy_list_head(first);
+ 46 863 : second_head = tommy_list_head(second);
+ 47 863 : first_tail = tommy_list_tail(first);
48 :
49 : /* set the "circular" prev list */
- 50 842 : first_head->prev = second_head->prev;
- 51 842 : second_head->prev = first_tail;
+ 50 863 : first_head->prev = second_head->prev;
+ 51 863 : second_head->prev = first_tail;
52 :
53 : /* set the "0 terminated" next list */
- 54 842 : first_tail->next = second_head;
+ 54 863 : first_tail->next = second_head;
55 : }
56 :
57 : /** \internal
diff --git a/cov/tommyds/tommylist.h.func-sort-c.html b/cov/tommyds/tommylist.h.func-sort-c.html
index 14e25432..9c8d2d57 100644
--- a/cov/tommyds/tommylist.h.func-sort-c.html
+++ b/cov/tommyds/tommylist.h.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,27 +61,27 @@
| tommy_list_head |
- 24488891 |
+ 24488786 |
| tommy_list_insert_first |
- 22766373 |
+ 22741744 |
| tommy_list_insert_tail |
- 17766906 |
+ 17767092 |
| tommy_list_insert_tail_not_empty |
- 10676661 |
+ 10700756 |
| tommy_list_remove_existing |
- 341990 |
+ 341445 |
| tommy_list_empty |
- 74265 |
+ 74175 |
| tommy_list_init |
@@ -93,7 +93,7 @@
| tommy_list_tail |
- 843 |
+ 864 |
| tommy_list_count |
diff --git a/cov/tommyds/tommylist.h.func.html b/cov/tommyds/tommylist.h.func.html
index a2edcfa4..c10d1292 100644
--- a/cov/tommyds/tommylist.h.func.html
+++ b/cov/tommyds/tommylist.h.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -65,7 +65,7 @@
| tommy_list_empty |
- 74265 |
+ 74175 |
| tommy_list_foreach |
@@ -73,7 +73,7 @@
| tommy_list_head |
- 24488891 |
+ 24488786 |
| tommy_list_init |
@@ -81,23 +81,23 @@
| tommy_list_insert_first |
- 22766373 |
+ 22741744 |
| tommy_list_insert_tail |
- 17766906 |
+ 17767092 |
| tommy_list_insert_tail_not_empty |
- 10676661 |
+ 10700756 |
| tommy_list_remove_existing |
- 341990 |
+ 341445 |
| tommy_list_tail |
- 843 |
+ 864 |
diff --git a/cov/tommyds/tommylist.h.gcov.html b/cov/tommyds/tommylist.h.gcov.html
index 51fe1a93..34f2c18f 100644
--- a/cov/tommyds/tommylist.h.gcov.html
+++ b/cov/tommyds/tommylist.h.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -182,23 +182,23 @@
120 : * Gets the head of the list.
121 : * \return The head node. For empty lists 0 is returned.
122 : */
- 123 24488891 : tommy_inline tommy_node* tommy_list_head(tommy_list* list)
+ 123 24488786 : tommy_inline tommy_node* tommy_list_head(tommy_list* list)
124 : {
- 125 24488891 : return *list;
+ 125 24488786 : return *list;
126 : }
127 :
128 : /**
129 : * Gets the tail of the list.
130 : * \return The tail node. For empty lists 0 is returned.
131 : */
- 132 843 : tommy_inline tommy_node* tommy_list_tail(tommy_list* list)
+ 132 864 : tommy_inline tommy_node* tommy_list_tail(tommy_list* list)
133 : {
- 134 843 : tommy_node* head = tommy_list_head(list);
+ 134 864 : tommy_node* head = tommy_list_head(list);
135 :
- 136 843 : if (!head)
+ 136 864 : if (!head)
137 1 : return 0;
138 :
- 139 842 : return head->prev;
+ 139 863 : return head->prev;
140 : }
141 :
142 : /** \internal
@@ -206,16 +206,16 @@
144 : * \param list The list to initialize.
145 : * \param node The node to insert.
146 : */
- 147 22766373 : tommy_inline void tommy_list_insert_first(tommy_list* list, tommy_node* node)
+ 147 22741744 : tommy_inline void tommy_list_insert_first(tommy_list* list, tommy_node* node)
148 : {
149 : /* one element "circular" prev list */
- 150 22766373 : node->prev = node;
+ 150 22741744 : node->prev = node;
151 :
152 : /* one element "0 terminated" next list */
- 153 22766373 : node->next = 0;
+ 153 22741744 : node->next = 0;
154 :
- 155 22766373 : *list = node;
- 156 22766373 : }
+ 155 22741744 : *list = node;
+ 156 22741744 : }
157 :
158 : /** \internal
159 : * Inserts an element at the head of a not empty list.
@@ -243,16 +243,16 @@
181 : * \param head The node at the list head. It cannot be 0.
182 : * \param node The node to insert.
183 : */
- 184 10676661 : tommy_inline void tommy_list_insert_tail_not_empty(tommy_node* head, tommy_node* node)
+ 184 10700756 : tommy_inline void tommy_list_insert_tail_not_empty(tommy_node* head, tommy_node* node)
185 : {
186 : /* insert in the "circular" prev list */
- 187 10676661 : node->prev = head->prev;
- 188 10676661 : head->prev = node;
+ 187 10700756 : node->prev = head->prev;
+ 188 10700756 : head->prev = node;
189 :
190 : /* insert in the "0 terminated" next list */
- 191 10676661 : node->next = 0;
- 192 10676661 : node->prev->next = node;
- 193 10676661 : }
+ 191 10700756 : node->next = 0;
+ 192 10700756 : node->prev->next = node;
+ 193 10700756 : }
194 :
195 : /**
196 : * Inserts an element at the head of a list.
@@ -276,17 +276,17 @@
214 : * \param node The node to insert.
215 : * \param data The object containing the node. It's used to set the tommy_node::data field of the node.
216 : */
- 217 17766906 : tommy_inline void tommy_list_insert_tail(tommy_list* list, tommy_node* node, void* data)
+ 217 17767092 : tommy_inline void tommy_list_insert_tail(tommy_list* list, tommy_node* node, void* data)
218 : {
- 219 17766906 : tommy_node* head = tommy_list_head(list);
+ 219 17767092 : tommy_node* head = tommy_list_head(list);
220 :
- 221 17766906 : if (head)
- 222 8816947 : tommy_list_insert_tail_not_empty(head, node);
+ 221 17767092 : if (head)
+ 222 8839895 : tommy_list_insert_tail_not_empty(head, node);
223 : else
- 224 8949959 : tommy_list_insert_first(list, node);
+ 224 8927197 : tommy_list_insert_first(list, node);
225 :
- 226 17766906 : node->data = data;
- 227 17766906 : }
+ 226 17767092 : node->data = data;
+ 227 17767092 : }
228 :
229 : /** \internal
230 : * Removes an element from the head of a not empty list.
@@ -314,23 +314,23 @@
252 : * \param node The node to remove. The node must be in the list.
253 : * \return The tommy_node::data field of the node removed.
254 : */
- 255 341990 : tommy_inline void* tommy_list_remove_existing(tommy_list* list, tommy_node* node)
+ 255 341445 : tommy_inline void* tommy_list_remove_existing(tommy_list* list, tommy_node* node)
256 : {
- 257 341990 : tommy_node* head = tommy_list_head(list);
+ 257 341445 : tommy_node* head = tommy_list_head(list);
258 :
259 : /* remove from the "circular" prev list */
- 260 341990 : if (node->next)
- 261 118050 : node->next->prev = node->prev;
+ 260 341445 : if (node->next)
+ 261 118988 : node->next->prev = node->prev;
262 : else
- 263 223940 : head->prev = node->prev; /* the last */
+ 263 222457 : head->prev = node->prev; /* the last */
264 :
265 : /* remove from the "0 terminated" next list */
- 266 341990 : if (head == node)
- 267 241521 : *list = node->next; /* the new head, in case 0 */
+ 266 341445 : if (head == node)
+ 267 241019 : *list = node->next; /* the new head, in case 0 */
268 : else
- 269 100469 : node->prev->next = node->next;
+ 269 100426 : node->prev->next = node->next;
270 :
- 271 341990 : return node->data;
+ 271 341445 : return node->data;
272 : }
273 :
274 : /**
@@ -355,9 +355,9 @@
293 : * Checks if empty.
294 : * \return If the list is empty.
295 : */
- 296 74265 : tommy_inline tommy_bool_t tommy_list_empty(tommy_list* list)
+ 296 74175 : tommy_inline tommy_bool_t tommy_list_empty(tommy_list* list)
297 : {
- 298 74265 : return tommy_list_head(list) == 0;
+ 298 74175 : return tommy_list_head(list) == 0;
299 : }
300 :
301 : /**
@@ -409,10 +409,10 @@
347 : {
348 7071 : tommy_node* node = tommy_list_head(list);
349 :
- 350 3547290 : while (node) {
- 351 3533148 : void* data = node->data;
- 352 3533148 : node = node->next;
- 353 3533148 : func(data);
+ 350 3547533 : while (node) {
+ 351 3533391 : void* data = node->data;
+ 352 3533391 : node = node->next;
+ 353 3533391 : func(data);
354 : }
355 7071 : }
356 :
diff --git a/cov/tommyds/tommytree.c.func-sort-c.html b/cov/tommyds/tommytree.c.func-sort-c.html
index 495ac6d7..b79d2f99 100644
--- a/cov/tommyds/tommytree.c.func-sort-c.html
+++ b/cov/tommyds/tommytree.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,55 +61,55 @@
| tommy_tree_search_node |
- 325769250 |
+ 324348165 |
| tommy_tree_delta |
- 108654608 |
+ 108663041 |
| tommy_tree_balance |
- 101404691 |
+ 101410069 |
| tommy_tree_insert_node |
- 93001944 |
+ 93001793 |
| tommy_tree_search_compare |
- 31419339 |
+ 31336465 |
| tommy_tree_foreach_arg_node |
- 25170953 |
+ 25171385 |
| tommy_tree_rotate_left |
- 7239414 |
+ 7241652 |
| tommy_tree_insert |
- 7215863 |
+ 7215779 |
| tommy_tree_foreach_node |
- 6799122 |
+ 6799230 |
| tommy_tree_remove_node |
- 774936 |
+ 775421 |
| tommy_tree_move_right |
- 181790 |
+ 183618 |
| tommy_tree_rotate_right |
- 169440 |
+ 168850 |
| tommy_tree_remove |
- 77976 |
+ 78058 |
| tommy_tree_foreach_arg |
diff --git a/cov/tommyds/tommytree.c.func.html b/cov/tommyds/tommytree.c.func.html
index af462197..c84d6f4c 100644
--- a/cov/tommyds/tommytree.c.func.html
+++ b/cov/tommyds/tommytree.c.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,11 +61,11 @@
| tommy_tree_balance |
- 101404691 |
+ 101410069 |
| tommy_tree_delta |
- 108654608 |
+ 108663041 |
| tommy_tree_foreach |
@@ -77,11 +77,11 @@
| tommy_tree_foreach_arg_node |
- 25170953 |
+ 25171385 |
| tommy_tree_foreach_node |
- 6799122 |
+ 6799230 |
| tommy_tree_init |
@@ -89,11 +89,11 @@
| tommy_tree_insert |
- 7215863 |
+ 7215779 |
| tommy_tree_insert_node |
- 93001944 |
+ 93001793 |
| tommy_tree_memory_usage |
@@ -101,11 +101,11 @@
| tommy_tree_move_right |
- 181790 |
+ 183618 |
| tommy_tree_remove |
- 77976 |
+ 78058 |
| tommy_tree_remove_existing |
@@ -113,15 +113,15 @@
| tommy_tree_remove_node |
- 774936 |
+ 775421 |
| tommy_tree_rotate_left |
- 7239414 |
+ 7241652 |
| tommy_tree_rotate_right |
- 169440 |
+ 168850 |
| tommy_tree_search |
@@ -129,11 +129,11 @@
| tommy_tree_search_compare |
- 31419339 |
+ 31336465 |
| tommy_tree_search_node |
- 325769250 |
+ 324348165 |
diff --git a/cov/tommyds/tommytree.c.gcov.html b/cov/tommyds/tommytree.c.gcov.html
index 1b25a859..4658bf45 100644
--- a/cov/tommyds/tommytree.c.gcov.html
+++ b/cov/tommyds/tommytree.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -101,97 +101,97 @@
39 2955 : tree->cmp = cmp;
40 2955 : }
41 :
- 42 108654608 : static int tommy_tree_delta(tommy_tree_node* root)
+ 42 108663041 : static int tommy_tree_delta(tommy_tree_node* root)
43 : {
- 44 108654608 : int left_height = root->prev ? root->prev->key : 0;
- 45 108654608 : int right_height = root->next ? root->next->key : 0;
+ 44 108663041 : int left_height = root->prev ? root->prev->key : 0;
+ 45 108663041 : int right_height = root->next ? root->next->key : 0;
46 :
- 47 108654608 : return left_height - right_height;
+ 47 108663041 : return left_height - right_height;
48 : }
49 :
50 : /* AVL tree operations */
51 : static tommy_tree_node* tommy_tree_balance(tommy_tree_node*);
52 :
- 53 7239414 : static tommy_tree_node* tommy_tree_rotate_left(tommy_tree_node* root)
+ 53 7241652 : static tommy_tree_node* tommy_tree_rotate_left(tommy_tree_node* root)
54 : {
- 55 7239414 : tommy_tree_node* next = root->next;
+ 55 7241652 : tommy_tree_node* next = root->next;
56 :
- 57 7239414 : root->next = next->prev;
+ 57 7241652 : root->next = next->prev;
58 :
- 59 7239414 : next->prev = tommy_tree_balance(root);
+ 59 7241652 : next->prev = tommy_tree_balance(root);
60 :
- 61 7239414 : return tommy_tree_balance(next);
+ 61 7241652 : return tommy_tree_balance(next);
62 : }
63 :
- 64 169440 : static tommy_tree_node* tommy_tree_rotate_right(tommy_tree_node* root)
+ 64 168850 : static tommy_tree_node* tommy_tree_rotate_right(tommy_tree_node* root)
65 : {
- 66 169440 : tommy_tree_node* prev = root->prev;
+ 66 168850 : tommy_tree_node* prev = root->prev;
67 :
- 68 169440 : root->prev = prev->next;
+ 68 168850 : root->prev = prev->next;
69 :
- 70 169440 : prev->next = tommy_tree_balance(root);
+ 70 168850 : prev->next = tommy_tree_balance(root);
71 :
- 72 169440 : return tommy_tree_balance(prev);
+ 72 168850 : return tommy_tree_balance(prev);
73 : }
74 :
- 75 181790 : static tommy_tree_node* tommy_tree_move_right(tommy_tree_node* root, tommy_tree_node* node)
+ 75 183618 : static tommy_tree_node* tommy_tree_move_right(tommy_tree_node* root, tommy_tree_node* node)
76 : {
- 77 181790 : if (!root)
- 78 77848 : return node;
+ 77 183618 : if (!root)
+ 78 77930 : return node;
79 :
- 80 103942 : root->next = tommy_tree_move_right(root->next, node);
+ 80 105688 : root->next = tommy_tree_move_right(root->next, node);
81 :
- 82 103942 : return tommy_tree_balance(root);
+ 82 105688 : return tommy_tree_balance(root);
83 : }
84 :
- 85 101404691 : static tommy_tree_node* tommy_tree_balance(tommy_tree_node* root)
+ 85 101410069 : static tommy_tree_node* tommy_tree_balance(tommy_tree_node* root)
86 : {
- 87 101404691 : int delta = tommy_tree_delta(root);
+ 87 101410069 : int delta = tommy_tree_delta(root);
88 :
- 89 101404691 : if (delta < -1) {
- 90 7121472 : if (tommy_tree_delta(root->next) > 0)
- 91 40995 : root->next = tommy_tree_rotate_right(root->next);
- 92 7121472 : return tommy_tree_rotate_left(root);
+ 89 101410069 : if (delta < -1) {
+ 90 7125675 : if (tommy_tree_delta(root->next) > 0)
+ 91 41553 : root->next = tommy_tree_rotate_right(root->next);
+ 92 7125675 : return tommy_tree_rotate_left(root);
93 : }
94 :
- 95 94283219 : if (delta > 1) {
- 96 128445 : if (tommy_tree_delta(root->prev) < 0)
- 97 117942 : root->prev = tommy_tree_rotate_left(root->prev);
- 98 128445 : return tommy_tree_rotate_right(root);
+ 95 94284394 : if (delta > 1) {
+ 96 127297 : if (tommy_tree_delta(root->prev) < 0)
+ 97 115977 : root->prev = tommy_tree_rotate_left(root->prev);
+ 98 127297 : return tommy_tree_rotate_right(root);
99 : }
100 :
101 : /* recompute key */
- 102 94154774 : root->key = 0;
+ 102 94157097 : root->key = 0;
103 :
- 104 94154774 : if (root->prev && root->prev->key > root->key)
- 105 76186657 : root->key = root->prev->key;
+ 104 94157097 : if (root->prev && root->prev->key > root->key)
+ 105 76188949 : root->key = root->prev->key;
106 :
- 107 94154774 : if (root->next && root->next->key > root->key)
- 108 43398384 : root->key = root->next->key;
+ 107 94157097 : if (root->next && root->next->key > root->key)
+ 108 43401597 : root->key = root->next->key;
109 :
110 : /* count itself */
- 111 94154774 : root->key += 1;
+ 111 94157097 : root->key += 1;
112 :
- 113 94154774 : return root;
+ 113 94157097 : return root;
114 : }
115 :
- 116 93001944 : static tommy_tree_node* tommy_tree_insert_node(tommy_compare_func* cmp, tommy_tree_node* root, tommy_tree_node** let)
+ 116 93001793 : static tommy_tree_node* tommy_tree_insert_node(tommy_compare_func* cmp, tommy_tree_node* root, tommy_tree_node** let)
117 : {
118 : int c;
119 :
- 120 93001944 : if (!root)
- 121 7215862 : return *let;
+ 120 93001793 : if (!root)
+ 121 7215778 : return *let;
122 :
- 123 85786082 : c = cmp((*let)->data, root->data);
+ 123 85786015 : c = cmp((*let)->data, root->data);
124 :
- 125 85786082 : if (c < 0) {
- 126 1489892 : root->prev = tommy_tree_insert_node(cmp, root->prev, let);
- 127 1489892 : return tommy_tree_balance(root);
+ 125 85786015 : if (c < 0) {
+ 126 1492912 : root->prev = tommy_tree_insert_node(cmp, root->prev, let);
+ 127 1492912 : return tommy_tree_balance(root);
128 : }
129 :
- 130 84296190 : if (c > 0) {
- 131 84296189 : root->next = tommy_tree_insert_node(cmp, root->next, let);
- 132 84296189 : return tommy_tree_balance(root);
+ 130 84293103 : if (c > 0) {
+ 131 84293102 : root->next = tommy_tree_insert_node(cmp, root->next, let);
+ 132 84293102 : return tommy_tree_balance(root);
133 : }
134 :
135 : /* already present, set the return pointer */
@@ -200,78 +200,78 @@
138 1 : return root;
139 : }
140 :
- 141 7215863 : void* tommy_tree_insert(tommy_tree* tree, tommy_tree_node* node, void* data)
+ 141 7215779 : void* tommy_tree_insert(tommy_tree* tree, tommy_tree_node* node, void* data)
142 : {
- 143 7215863 : tommy_tree_node* insert = node;
+ 143 7215779 : tommy_tree_node* insert = node;
144 :
- 145 7215863 : insert->data = data;
- 146 7215863 : insert->prev = 0;
- 147 7215863 : insert->next = 0;
- 148 7215863 : insert->key = 0;
+ 145 7215779 : insert->data = data;
+ 146 7215779 : insert->prev = 0;
+ 147 7215779 : insert->next = 0;
+ 148 7215779 : insert->key = 0;
149 :
- 150 7215863 : tree->root = tommy_tree_insert_node(tree->cmp, tree->root, &insert);
+ 150 7215779 : tree->root = tommy_tree_insert_node(tree->cmp, tree->root, &insert);
151 :
- 152 7215863 : if (insert == node)
- 153 7215862 : ++tree->count;
+ 152 7215779 : if (insert == node)
+ 153 7215778 : ++tree->count;
154 :
- 155 7215863 : return node->data;
+ 155 7215779 : return node->data;
156 : }
157 :
- 158 774936 : static tommy_tree_node* tommy_tree_remove_node(tommy_compare_func* cmp, tommy_tree_node* root, void* data, tommy_tree_node** let)
+ 158 775421 : static tommy_tree_node* tommy_tree_remove_node(tommy_compare_func* cmp, tommy_tree_node* root, void* data, tommy_tree_node** let)
159 : {
160 : int c;
161 :
- 162 774936 : if (!root)
+ 162 775421 : if (!root)
163 128 : return 0;
164 :
- 165 774808 : c = cmp(data, root->data);
+ 165 775293 : c = cmp(data, root->data);
166 :
- 167 774808 : if (c < 0) {
- 168 299059 : root->prev = tommy_tree_remove_node(cmp, root->prev, data, let);
- 169 299059 : return tommy_tree_balance(root);
+ 167 775293 : if (c < 0) {
+ 168 298766 : root->prev = tommy_tree_remove_node(cmp, root->prev, data, let);
+ 169 298766 : return tommy_tree_balance(root);
170 : }
171 :
- 172 475749 : if (c > 0) {
- 173 397901 : root->next = tommy_tree_remove_node(cmp, root->next, data, let);
- 174 397901 : return tommy_tree_balance(root);
+ 172 476527 : if (c > 0) {
+ 173 398597 : root->next = tommy_tree_remove_node(cmp, root->next, data, let);
+ 174 398597 : return tommy_tree_balance(root);
175 : }
176 :
177 : /* found */
- 178 77848 : *let = root;
+ 178 77930 : *let = root;
179 :
- 180 77848 : return tommy_tree_move_right(root->prev, root->next);
+ 180 77930 : return tommy_tree_move_right(root->prev, root->next);
181 : }
182 :
- 183 77976 : void* tommy_tree_remove(tommy_tree* tree, void* data)
+ 183 78058 : void* tommy_tree_remove(tommy_tree* tree, void* data)
184 : {
- 185 77976 : tommy_tree_node* node = 0;
+ 185 78058 : tommy_tree_node* node = 0;
186 :
- 187 77976 : tree->root = tommy_tree_remove_node(tree->cmp, tree->root, data, &node);
+ 187 78058 : tree->root = tommy_tree_remove_node(tree->cmp, tree->root, data, &node);
188 :
- 189 77976 : if (!node)
+ 189 78058 : if (!node)
190 128 : return 0;
191 :
- 192 77848 : --tree->count;
+ 192 77930 : --tree->count;
193 :
- 194 77848 : return node->data;
+ 194 77930 : return node->data;
195 : }
196 :
- 197 325769250 : static tommy_tree_node* tommy_tree_search_node(tommy_compare_func* cmp, tommy_tree_node* root, void* data)
+ 197 324348165 : static tommy_tree_node* tommy_tree_search_node(tommy_compare_func* cmp, tommy_tree_node* root, void* data)
198 : {
199 : int c;
200 :
- 201 325769250 : if (!root)
- 202 2357034 : return 0;
+ 201 324348165 : if (!root)
+ 202 2354776 : return 0;
203 :
- 204 323412216 : c = cmp(data, root->data);
+ 204 321993389 : c = cmp(data, root->data);
205 :
- 206 331008984 : if (c < 0)
- 207 130163691 : return tommy_tree_search_node(cmp, root->prev, data);
+ 206 330820889 : if (c < 0)
+ 207 130151880 : return tommy_tree_search_node(cmp, root->prev, data);
208 :
- 209 200845293 : if (c > 0)
- 210 171813618 : return tommy_tree_search_node(cmp, root->next, data);
+ 209 200669009 : if (c > 0)
+ 210 171722863 : return tommy_tree_search_node(cmp, root->next, data);
211 :
- 212 29031675 : return root;
+ 212 28946146 : return root;
213 : }
214 :
215 2 : void* tommy_tree_search(tommy_tree* tree, void* data)
@@ -284,14 +284,14 @@
222 1 : return node->data;
223 : }
224 :
- 225 31419339 : void* tommy_tree_search_compare(tommy_tree* tree, tommy_compare_func* cmp, void* cmp_arg)
+ 225 31336465 : void* tommy_tree_search_compare(tommy_tree* tree, tommy_compare_func* cmp, void* cmp_arg)
226 : {
- 227 31419339 : tommy_tree_node* node = tommy_tree_search_node(cmp, tree->root, cmp_arg);
+ 227 31336465 : tommy_tree_node* node = tommy_tree_search_node(cmp, tree->root, cmp_arg);
228 :
- 229 31233438 : if (!node)
- 230 2356966 : return 0;
+ 229 31273364 : if (!node)
+ 230 2346177 : return 0;
231 :
- 232 28876472 : return node->data;
+ 232 28927187 : return node->data;
233 : }
234 :
235 128 : void* tommy_tree_remove_existing(tommy_tree* tree, tommy_tree_node* node)
@@ -303,21 +303,21 @@
241 128 : return data;
242 : }
243 :
- 244 6799122 : static void tommy_tree_foreach_node(tommy_tree_node* root, tommy_foreach_func* func)
+ 244 6799230 : static void tommy_tree_foreach_node(tommy_tree_node* root, tommy_foreach_func* func)
245 : {
246 : tommy_tree_node* next;
247 :
- 248 6799122 : if (!root)
- 249 10199359 : return;
+ 248 6799230 : if (!root)
+ 249 10199521 : return;
250 :
- 251 3398885 : tommy_tree_foreach_node(root->prev, func);
+ 251 3398939 : tommy_tree_foreach_node(root->prev, func);
252 :
253 : /* make a copy in case func is free() */
- 254 3398885 : next = root->next;
+ 254 3398939 : next = root->next;
255 :
- 256 3398885 : func(root->data);
+ 256 3398939 : func(root->data);
257 :
- 258 3398885 : tommy_tree_foreach_node(next, func);
+ 258 3398939 : tommy_tree_foreach_node(next, func);
259 : }
260 :
261 1352 : void tommy_tree_foreach(tommy_tree* tree, tommy_foreach_func* func)
@@ -325,21 +325,21 @@
263 1352 : tommy_tree_foreach_node(tree->root, func);
264 1352 : }
265 :
- 266 25170953 : static void tommy_tree_foreach_arg_node(tommy_tree_node* root, tommy_foreach_arg_func* func, void* arg)
+ 266 25171385 : static void tommy_tree_foreach_arg_node(tommy_tree_node* root, tommy_foreach_arg_func* func, void* arg)
267 : {
268 : tommy_tree_node* next;
269 :
- 270 25170953 : if (!root)
- 271 37759106 : return;
+ 270 25171385 : if (!root)
+ 271 37759754 : return;
272 :
- 273 12582800 : tommy_tree_foreach_arg_node(root->prev, func, arg);
+ 273 12583016 : tommy_tree_foreach_arg_node(root->prev, func, arg);
274 :
275 : /* make a copy in case func is free() */
- 276 12582800 : next = root->next;
+ 276 12583016 : next = root->next;
277 :
- 278 12582800 : func(arg, root->data);
+ 278 12583016 : func(arg, root->data);
279 :
- 280 12582800 : tommy_tree_foreach_arg_node(next, func, arg);
+ 280 12583016 : tommy_tree_foreach_arg_node(next, func, arg);
281 : }
282 :
283 5353 : void tommy_tree_foreach_arg(tommy_tree* tree, tommy_foreach_arg_func* func, void* arg)
diff --git a/cov/tommyds/tommytree.h.func-sort-c.html b/cov/tommyds/tommytree.h.func-sort-c.html
index 7d920651..402c3c72 100644
--- a/cov/tommyds/tommytree.h.func-sort-c.html
+++ b/cov/tommyds/tommytree.h.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/tommyds/tommytree.h.func.html b/cov/tommyds/tommytree.h.func.html
index e540b6ba..6566356b 100644
--- a/cov/tommyds/tommytree.h.func.html
+++ b/cov/tommyds/tommytree.h.func.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/tommyds/tommytree.h.gcov.html b/cov/tommyds/tommytree.h.gcov.html
index 46d24eeb..ec3ff04a 100644
--- a/cov/tommyds/tommytree.h.gcov.html
+++ b/cov/tommyds/tommytree.h.gcov.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/tommyds/tommytypes.h.func-sort-c.html b/cov/tommyds/tommytypes.h.func-sort-c.html
index 2dd7628d..5b79e95e 100644
--- a/cov/tommyds/tommytypes.h.func-sort-c.html
+++ b/cov/tommyds/tommytypes.h.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,7 +61,7 @@
| tommy_ilog2_u32 |
- 15274023 |
+ 15297694 |
| tommy_ctz_u32 |
diff --git a/cov/tommyds/tommytypes.h.func.html b/cov/tommyds/tommytypes.h.func.html
index 9eb1778e..e495be7b 100644
--- a/cov/tommyds/tommytypes.h.func.html
+++ b/cov/tommyds/tommytypes.h.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -65,7 +65,7 @@
| tommy_ilog2_u32 |
- 15274023 |
+ 15297694 |
diff --git a/cov/tommyds/tommytypes.h.gcov.html b/cov/tommyds/tommytypes.h.gcov.html
index 55888cfb..018a04b9 100644
--- a/cov/tommyds/tommytypes.h.gcov.html
+++ b/cov/tommyds/tommytypes.h.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -385,7 +385,7 @@
323 : * \param value Value to scan. 0 is not allowed.
324 : * \return The index of the most significant bit set.
325 : */
- 326 15274023 : tommy_inline tommy_uint_t tommy_ilog2_u32(tommy_uint32_t value)
+ 326 15297694 : tommy_inline tommy_uint_t tommy_ilog2_u32(tommy_uint32_t value)
327 : {
328 : #if defined(_MSC_VER)
329 : unsigned long count;
@@ -401,7 +401,7 @@
339 : * So we write "__builtin_clz(x) ^ 31" instead of "31 - __builtin_clz(x)",
340 : * to allow the double xor to be optimized out.
341 : */
- 342 15274023 : return __builtin_clz(value) ^ 31;
+ 342 15297694 : return __builtin_clz(value) ^ 31;
343 : #else
344 : /* Find the log base 2 of an N-bit integer in O(lg(N)) operations with multiply and lookup */
345 : /* from http://graphics.stanford.edu/~seander/bithacks.html */
diff --git a/download.html b/download.html
index 88338e53..6cc52373 100644
--- a/download.html
+++ b/download.html
@@ -50,17 +50,17 @@ If you like to use a GUI, you can try E