diff --git a/cov/cmdline/check.c.func-sort-c.html b/cov/cmdline/check.c.func-sort-c.html
index 42c16119..f692495f 100644
--- a/cov/cmdline/check.c.func-sort-c.html
+++ b/cov/cmdline/check.c.func-sort-c.html
@@ -32,8 +32,8 @@
|
-
-
+
+
@@ -73,18 +73,18 @@
| blockcmp |
- 473403 |
+ 473381 |
| repair_step |
- 252742 |
+ 252815 |
| is_hash_matching |
- 214689 |
+ 214888 |
- | state_check |
+ state_check |
120 |
diff --git a/cov/cmdline/check.c.func.html b/cov/cmdline/check.c.func.html
index cade11b5..a78876cd 100644
--- a/cov/cmdline/check.c.func.html
+++ b/cov/cmdline/check.c.func.html
@@ -32,8 +32,8 @@
|
-
-
+
+
@@ -65,7 +65,7 @@
| blockcmp |
- 473403 |
+ 473381 |
| file_post |
@@ -73,7 +73,7 @@
| is_hash_matching |
- 214689 |
+ 214888 |
| is_parity_matching |
@@ -85,10 +85,10 @@
| repair_step |
- 252742 |
+ 252815 |
- | state_check |
+ state_check |
120 |
diff --git a/cov/cmdline/check.c.gcov.html b/cov/cmdline/check.c.gcov.html
index ba89f607..35bb07f2 100644
--- a/cov/cmdline/check.c.gcov.html
+++ b/cov/cmdline/check.c.gcov.html
@@ -32,8 +32,8 @@
|
-
-
+
+
@@ -129,64 +129,64 @@
67 : * Check if a block hash matches the specified buffer.
68 : * Return ==0 if equal
69 : */
- 70 473403 : static int blockcmp(struct snapraid_state* state, int rehash, struct snapraid_block* block, unsigned pos_size, unsigned char* buffer, unsigned char* buffer_zero)
+ 70 473381 : 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_MAX];
73 :
74 : /* now compute the hash of the valid part */
- 75 473403 : if (rehash) {
+ 75 473381 : if (rehash) {
76 0 : memhash(state->prevhash, state->prevhashseed, hash, buffer, pos_size);
77 : } else {
- 78 473403 : memhash(state->hash, state->hashseed, hash, buffer, pos_size);
+ 78 473381 : memhash(state->hash, state->hashseed, hash, buffer, pos_size);
79 : }
80 :
81 : /* compare the hash */
- 82 473403 : if (memcmp(hash, block->hash, BLOCK_HASH_SIZE) != 0) {
- 83 19016 : return -1;
+ 82 473381 : if (memcmp(hash, block->hash, BLOCK_HASH_SIZE) != 0) {
+ 83 19034 : return -1;
84 : }
85 :
86 : /* compare to the end of the block */
- 87 454387 : if (pos_size < state->block_size) {
- 88 187463 : if (memcmp(buffer + pos_size, buffer_zero + pos_size, state->block_size - pos_size) != 0) {
- 89 36 : return -1;
+ 87 454347 : if (pos_size < state->block_size) {
+ 88 187568 : if (memcmp(buffer + pos_size, buffer_zero + pos_size, state->block_size - pos_size) != 0) {
+ 89 39 : return -1;
90 : }
91 : }
92 :
- 93 454351 : return 0;
+ 93 454308 : 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 214689 : 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 214888 : 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 214689 : hash_checked = 0; /* keep track if we check at least one block */
+ 104 214888 : hash_checked = 0; /* keep track if we check at least one block */
105 :
106 : /* check if the recovered blocks are OK */
- 107 673562 : for (j = 0; j < failed_count; ++j) {
+ 107 673718 : for (j = 0; j < failed_count; ++j) {
108 : /* if we are expected to recover this block */
- 109 477925 : if (!failed[failed_map[j]].is_outofdate
+ 109 477903 : if (!failed[failed_map[j]].is_outofdate
110 : /* if the block has a hash to check */
- 111 473403 : && block_has_updated_hash(failed[failed_map[j]].block)
+ 111 473381 : && block_has_updated_hash(failed[failed_map[j]].block)
112 : ) {
113 : /* if a hash doesn't match, fail the check */
- 114 473403 : unsigned pos_size = file_block_size(failed[failed_map[j]].file, failed[failed_map[j]].file_pos, state->block_size);
- 115 473403 : if (blockcmp(state, rehash, failed[failed_map[j]].block, pos_size, buffer[failed[failed_map[j]].index], buffer_zero) != 0) {
- 116 19052 : log_tag("hash_error: Hash mismatch on entry %u\n", failed_map[j]);
- 117 19052 : return 0;
+ 114 473381 : unsigned pos_size = file_block_size(failed[failed_map[j]].file, failed[failed_map[j]].file_pos, state->block_size);
+ 115 473381 : if (blockcmp(state, rehash, failed[failed_map[j]].block, pos_size, buffer[failed[failed_map[j]].index], buffer_zero) != 0) {
+ 116 19073 : log_tag("hash_error: Hash mismatch on entry %u\n", failed_map[j]);
+ 117 19073 : return 0;
118 : }
119 :
- 120 454351 : hash_checked = 1;
+ 120 454308 : 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 195637 : if (!hash_checked) {
+ 127 195815 : 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 195637 : raid_gen(diskmax, state->level, state->block_size, buffer);
- 136 195637 : return 1;
+ 135 195815 : raid_gen(diskmax, state->level, state->block_size, buffer);
+ 136 195815 : 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 252742 : 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 252815 : 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 252742 : if (failed_count == 0) {
+ 171 252815 : 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 252742 : n = state->level;
- 180 252742 : error = 0;
+ 179 252815 : n = state->level;
+ 180 252815 : error = 0;
181 :
182 : /* setup vector of failed disk indexes */
- 183 892104 : for (i = 0; i < failed_count; ++i)
- 184 639362 : id[i] = failed[failed_map[i]].index;
+ 183 891917 : for (i = 0; i < failed_count; ++i)
+ 184 639102 : 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 252742 : has_hash = 0;
- 189 892104 : for (i = 0; i < failed_count; ++i) {
+ 188 252815 : has_hash = 0;
+ 189 891917 : for (i = 0; i < failed_count; ++i) {
190 : /* if we are expected to recover this block */
- 191 639362 : if (!failed[failed_map[i]].is_outofdate
+ 191 639102 : if (!failed[failed_map[i]].is_outofdate
192 : /* if the block has a hash to check */
- 193 630318 : && block_has_updated_hash(failed[failed_map[i]].block)
+ 193 630058 : && block_has_updated_hash(failed[failed_map[i]].block)
194 : )
- 195 630310 : has_hash = 1;
+ 195 630050 : 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 252742 : if (!has_hash && failed_count < n) {
+ 200 252815 : if (!has_hash && failed_count < n) {
201 : /* number of parity to use, one more to check the recovering */
202 8 : unsigned r = failed_count + 1;
203 :
@@ -299,51 +299,51 @@
237 :
238 : /* if we have a hash, and enough parities */
239 : /* (less-or-equal failures than number of parities) */
- 240 252734 : if (has_hash && failed_count <= n) {
+ 240 252807 : if (has_hash && failed_count <= n) {
241 : /* number of parities to use equal at the number of failures */
- 242 204960 : unsigned r = failed_count;
+ 242 205145 : unsigned r = failed_count;
243 :
244 : /* all combinations (r of n) parities */
- 245 204960 : combination_first(r, n, ip);
+ 245 205145 : combination_first(r, n, ip);
246 : do {
247 : /* if a parity is missing, do nothing */
- 248 692614 : for (i = 0; i < r; ++i) {
- 249 477925 : if (buffer_recov[ip[i]] == 0)
+ 248 692791 : for (i = 0; i < r; ++i) {
+ 249 477903 : if (buffer_recov[ip[i]] == 0)
250 0 : break;
251 : }
- 252 214689 : if (i != r)
+ 252 214888 : if (i != r)
253 0 : continue;
254 :
255 : /* copy the parities to use */
- 256 692614 : for (i = 0; i < r; ++i)
- 257 477925 : memcpy(buffer[diskmax + ip[i]], buffer_recov[ip[i]], state->block_size);
+ 256 692791 : for (i = 0; i < r; ++i)
+ 257 477903 : memcpy(buffer[diskmax + ip[i]], buffer_recov[ip[i]], state->block_size);
258 :
259 : /* recover */
- 260 214689 : raid_data(r, id, ip, diskmax, state->block_size, buffer);
+ 260 214888 : raid_data(r, id, ip, diskmax, state->block_size, buffer);
261 :
262 : /* use the hash to check the result */
- 263 214689 : if (is_hash_matching(state, rehash, diskmax, failed, failed_map, failed_count, buffer, buffer_zero))
- 264 195637 : return 0;
+ 263 214888 : if (is_hash_matching(state, rehash, diskmax, failed, failed_map, failed_count, buffer, buffer_zero))
+ 264 195815 : return 0;
265 :
266 : /* log */
- 267 19052 : log_tag("parity_error:%u:", pos);
- 268 38104 : for (i = 0; i < r; ++i) {
- 269 19052 : if (i != 0)
+ 267 19073 : log_tag("parity_error:%u:", pos);
+ 268 38146 : for (i = 0; i < r; ++i) {
+ 269 19073 : if (i != 0)
270 0 : log_tag("/");
- 271 19052 : log_tag("%s", lev_config_name(ip[i]));
+ 271 19073 : log_tag("%s", lev_config_name(ip[i]));
272 : }
- 273 19052 : log_tag(":hash: Hash mismatch\n");
- 274 19052 : ++error;
- 275 38104 : } while (combination_next(r, n, ip));
+ 273 19073 : log_tag(":hash: Hash mismatch\n");
+ 274 19073 : ++error;
+ 275 38146 : } while (combination_next(r, n, ip));
276 : }
277 :
278 : /* return the number of failed attempts, or -1 if no strategy */
- 279 57097 : if (error)
- 280 9323 : return error;
+ 279 56992 : if (error)
+ 280 9330 : return error;
281 :
- 282 47774 : log_tag("strategy_error:%u: No strategy to recover from %u failures with %u parity %s hash\n",
+ 282 47662 : 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 47774 : return -1;
+ 284 47662 : return -1;
285 : }
286 :
287 870958 : 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)
@@ -360,47 +360,47 @@
298 :
299 : /* if nothing failed, just recompute the parity */
300 870958 : if (failed_count == 0) {
- 301 583304 : raid_gen(diskmax, state->level, state->block_size, buffer);
- 302 583304 : return 0;
+ 301 583231 : raid_gen(diskmax, state->level, state->block_size, buffer);
+ 302 583231 : return 0;
303 : }
304 :
305 : /* logs the status */
- 306 1017035 : for (j = 0; j < failed_count; ++j) {
+ 306 1016848 : for (j = 0; j < failed_count; ++j) {
307 : const char* desc;
308 : const char* hash;
309 : const char* data;
- 310 729381 : struct snapraid_block* block = failed[j].block;
- 311 729381 : unsigned block_state = block_state_get(block);
+ 310 729121 : struct snapraid_block* block = failed[j].block;
+ 311 729121 : unsigned block_state = block_state_get(block);
312 :
- 313 729381 : switch (block_state) {
+ 313 729121 : switch (block_state) {
314 18454 : case BLOCK_STATE_DELETED : desc = "delete"; break;
315 13851 : case BLOCK_STATE_CHG : desc = "change"; break;
316 62282 : case BLOCK_STATE_REP : desc = "replace"; break;
- 317 634794 : case BLOCK_STATE_BLK : desc = "block"; break;
+ 317 634534 : case BLOCK_STATE_BLK : desc = "block"; break;
318 : /* LCOV_EXCL_START */
319 : default : desc = "unknown"; break;
320 : /* LCOV_EXCL_STOP */
321 : }
322 :
- 323 729381 : if (hash_is_invalid(block->hash)) {
+ 323 729121 : if (hash_is_invalid(block->hash)) {
324 13843 : hash = "lost";
- 325 715538 : } else if (hash_is_zero(block->hash)) {
+ 325 715278 : } else if (hash_is_zero(block->hash)) {
326 8 : hash = "zero";
327 : } else {
- 328 715530 : hash = "known";
+ 328 715270 : hash = "known";
329 : }
330 :
- 331 729381 : if (failed[j].is_bad)
- 332 643656 : data = "bad";
+ 331 729121 : if (failed[j].is_bad)
+ 332 643396 : data = "bad";
333 : else
334 85725 : data = "good";
335 :
- 336 729381 : if (failed[j].file) {
- 337 710927 : struct snapraid_disk* disk = failed[j].disk;
- 338 710927 : struct snapraid_file* file = failed[j].file;
- 339 710927 : block_off_t file_pos = failed[j].file_pos;
+ 336 729121 : if (failed[j].file) {
+ 337 710667 : struct snapraid_disk* disk = failed[j].disk;
+ 338 710667 : struct snapraid_file* file = failed[j].file;
+ 339 710667 : block_off_t file_pos = failed[j].file_pos;
340 :
- 341 710927 : log_tag("entry:%u:%s:%s:%s:%s:%s:%u:\n", j, desc, hash, data, disk->name, esc_tag(file->sub, esc_buffer), file_pos);
+ 341 710667 : log_tag("entry:%u:%s:%s:%s:%s:%s:%u:\n", j, desc, hash, data, disk->name, esc_tag(file->sub, esc_buffer), file_pos);
342 : } else {
343 18454 : log_tag("entry:%u:%s:%s:%s:\n", j, desc, hash, data);
344 : }
@@ -422,35 +422,35 @@
360 : /* We are interested to recover BLK, REP and CHG blocks if they are marked as bad, */
361 : /* but we are not interested in DELETED ones. */
362 :
- 363 287654 : n = 0;
- 364 287654 : something_to_recover = 0; /* keep track if there is at least one block to fix */
- 365 1017035 : for (j = 0; j < failed_count; ++j) {
- 366 729381 : if (failed[j].is_bad) {
- 367 643656 : unsigned block_state = block_state_get(failed[j].block);
+ 363 287727 : n = 0;
+ 364 287727 : something_to_recover = 0; /* keep track if there is at least one block to fix */
+ 365 1016848 : for (j = 0; j < failed_count; ++j) {
+ 366 729121 : if (failed[j].is_bad) {
+ 367 643396 : unsigned block_state = block_state_get(failed[j].block);
368 :
- 369 643656 : assert(block_state != BLOCK_STATE_DELETED); /* we cannot have bad DELETED blocks */
+ 369 643396 : assert(block_state != BLOCK_STATE_DELETED); /* we cannot have bad DELETED blocks */
370 :
371 : /* if we have the hash for it */
- 372 643656 : if ((block_state == BLOCK_STATE_BLK || block_state == BLOCK_STATE_REP)
+ 372 643396 : if ((block_state == BLOCK_STATE_BLK || block_state == BLOCK_STATE_REP)
373 : /* try to fetch the block using the known hash */
- 374 643648 : && (state_import_fetch(state, rehash, failed[j].block, buffer[failed[j].index]) == 0
- 375 639176 : || state_search_fetch(state, rehash, failed[j].file, failed[j].file_pos, failed[j].block, buffer[failed[j].index]) == 0)
+ 374 643388 : && (state_import_fetch(state, rehash, failed[j].block, buffer[failed[j].index]) == 0
+ 375 638916 : || state_search_fetch(state, rehash, failed[j].file, failed[j].file_pos, failed[j].block, buffer[failed[j].index]) == 0)
376 : ) {
377 : /* we already have corrected it! */
378 22382 : log_tag("hash_import: Fixed entry %u\n", j);
379 : } else {
380 : /* otherwise try to recover it */
- 381 621274 : failed_map[n] = j;
- 382 621274 : ++n;
+ 381 621014 : failed_map[n] = j;
+ 382 621014 : ++n;
383 :
384 : /* we have something to try to recover */
- 385 621274 : something_to_recover = 1;
+ 385 621014 : something_to_recover = 1;
386 : }
387 : }
388 : }
389 :
390 : /* if nothing to fix */
- 391 287654 : if (!something_to_recover) {
+ 391 287727 : if (!something_to_recover) {
392 43956 : log_tag("recover_sync:%u:%u: Skipped for already recovered\n", pos, n);
393 :
394 : /* recompute only the parity */
@@ -458,22 +458,22 @@
396 43956 : return 0;
397 : }
398 :
- 399 243698 : ret = repair_step(state, rehash, pos, diskmax, failed, failed_map, n, buffer, buffer_recov, buffer_zero);
- 400 243698 : if (ret == 0) {
+ 399 243771 : ret = repair_step(state, rehash, pos, diskmax, failed, failed_map, n, buffer, buffer_recov, buffer_zero);
+ 400 243771 : if (ret == 0) {
401 : /* reprocess the CHG blocks, for which we don't have a hash to check */
402 : /* if they were BAD we have to use some heuristics to ensure that we have recovered */
403 : /* the state after the sync. If unsure, we assume the worst case */
404 :
- 405 667587 : for (j = 0; j < failed_count; ++j) {
+ 405 667722 : for (j = 0; j < failed_count; ++j) {
406 : /* we take care only of BAD blocks we have to write back */
- 407 476464 : if (failed[j].is_bad) {
- 408 462992 : unsigned block_state = block_state_get(failed[j].block);
+ 407 476421 : if (failed[j].is_bad) {
+ 408 462949 : unsigned block_state = block_state_get(failed[j].block);
409 :
410 : /* BLK and REP blocks are always OK, because at this point */
411 : /* we have already checked their hash */
- 412 462992 : if (block_state != BLOCK_STATE_CHG) {
- 413 462984 : assert(block_state == BLOCK_STATE_BLK || block_state == BLOCK_STATE_REP);
- 414 462984 : continue;
+ 412 462949 : if (block_state != BLOCK_STATE_CHG) {
+ 413 462941 : assert(block_state == BLOCK_STATE_BLK || block_state == BLOCK_STATE_REP);
+ 414 462941 : continue;
415 : }
416 :
417 : /* for CHG blocks we have to 'guess' if they are correct or not */
@@ -515,15 +515,15 @@
453 : }
454 : }
455 :
- 456 191123 : return 0;
+ 456 191301 : return 0;
457 : }
- 458 52575 : if (ret > 0)
- 459 9323 : error += ret;
+ 458 52470 : if (ret > 0)
+ 459 9330 : error += ret;
460 :
- 461 52575 : if (ret < 0)
- 462 43252 : log_tag("recover_sync:%u:%u: Failed with no attempts\n", pos, n);
+ 461 52470 : if (ret < 0)
+ 462 43140 : log_tag("recover_sync:%u:%u: Failed with no attempts\n", pos, n);
463 : else
- 464 9323 : log_tag("recover_sync:%u:%u: Failed with %d attempts\n", pos, n, ret);
+ 464 9330 : log_tag("recover_sync:%u:%u: Failed with %d attempts\n", pos, n, ret);
465 :
466 : /* Now assume that the parity IS NOT updated at the current state, */
467 : /* but still represent the state before the last 'sync' process. */
@@ -533,15 +533,15 @@
471 : /* but we are not interested to recover CHG (new version) and REP (new version) blocks, */
472 : /* even if marked as bad, because we don't have parity for them and it's just impossible, */
473 : /* and we are not interested to recover DELETED ones. */
- 474 52575 : n = 0;
- 475 52575 : something_to_recover = 0; /* keep track if there is at least one block to fix */
- 476 52575 : something_unsynced = 0; /* keep track if we have some unsynced info to process */
- 477 233056 : for (j = 0; j < failed_count; ++j) {
- 478 180481 : unsigned block_state = block_state_get(failed[j].block);
+ 474 52470 : n = 0;
+ 475 52470 : something_to_recover = 0; /* keep track if there is at least one block to fix */
+ 476 52470 : something_unsynced = 0; /* keep track if we have some unsynced info to process */
+ 477 232734 : for (j = 0; j < failed_count; ++j) {
+ 478 180264 : unsigned block_state = block_state_get(failed[j].block);
479 :
- 480 180481 : if (block_state == BLOCK_STATE_DELETED
- 481 171437 : || block_state == BLOCK_STATE_CHG
- 482 171437 : || block_state == BLOCK_STATE_REP
+ 480 180264 : if (block_state == BLOCK_STATE_DELETED
+ 481 171220 : || block_state == BLOCK_STATE_CHG
+ 482 171220 : || block_state == BLOCK_STATE_REP
483 : ) {
484 : /* If the block is CHG, REP or DELETED, we don't have the original content of block, */
485 : /* and we must try to recover it. */
@@ -583,24 +583,24 @@
521 : /* it also applies to CHG and DELETE blocks because we want to have */
522 : /* a successful recovering only if a BLK one is matching */
523 9044 : failed[j].is_outofdate = 1;
- 524 171437 : } else if (failed[j].is_bad) {
+ 524 171220 : } else if (failed[j].is_bad) {
525 : /* If the block is bad we don't know its content, and we try to recover it */
526 : /* At this point, we can have only BLK ones */
527 :
- 528 171437 : assert(block_state == BLOCK_STATE_BLK);
+ 528 171220 : assert(block_state == BLOCK_STATE_BLK);
529 :
530 : /* we have something we are interested to recover */
- 531 171437 : something_to_recover = 1;
+ 531 171220 : something_to_recover = 1;
532 :
533 : /* we try to recover it */
- 534 171437 : failed_map[n] = j;
- 535 171437 : ++n;
+ 534 171220 : failed_map[n] = j;
+ 535 171220 : ++n;
536 : }
537 : }
538 :
539 : /* if nothing to fix, we just don't try */
540 : /* if nothing unsynced we also don't retry, because it's the same try as before */
- 541 52575 : if (something_to_recover && something_unsynced) {
+ 541 52470 : if (something_to_recover && something_unsynced) {
542 9044 : ret = repair_step(state, rehash, pos, diskmax, failed, failed_map, n, buffer, buffer_recov, buffer_zero);
543 9044 : if (ret == 0) {
544 : /* reprocess the REP and CHG blocks, for which we have recovered and old state */
@@ -634,17 +634,17 @@
572 : else
573 0 : log_tag("recover_unsync:%u:%u: Failed with %d attempts\n", pos, n, ret);
574 : } else {
- 575 43531 : log_tag("recover_unsync:%u:%u: Skipped for%s%s\n", pos, n,
+ 575 43426 : log_tag("recover_unsync:%u:%u: Skipped for%s%s\n", pos, n,
576 : !something_to_recover ? " nothing to recover" : "",
577 : !something_unsynced ? " nothing unsynched" : ""
578 : );
579 : }
580 :
581 : /* return the number of failed attempts, or -1 if no strategy */
- 582 48053 : if (error)
- 583 4801 : return error;
+ 582 47948 : if (error)
+ 583 4808 : return error;
584 : else
- 585 43252 : return -1;
+ 585 43140 : return -1;
586 : }
587 :
588 : /**
@@ -718,12 +718,12 @@
656 : /* rename it to .unrecoverable */
657 : char path_to[PATH_MAX];
658 :
- 659 63283 : pathprint(path_to, sizeof(path_to), "%s%s.unrecoverable", disk->dir, file->sub);
+ 659 63287 : pathprint(path_to, sizeof(path_to), "%s%s.unrecoverable", disk->dir, file->sub);
660 :
661 : /* ensure to close the file before renaming */
- 662 63283 : if (handle[j].file == file) {
- 663 63283 : ret = handle_close(&handle[j]);
- 664 63283 : if (ret != 0) {
+ 662 63287 : if (handle[j].file == file) {
+ 663 63287 : ret = handle_close(&handle[j]);
+ 664 63287 : if (ret != 0) {
665 : /* LCOV_EXCL_START */
666 : log_tag("error:%u:%s:%s: Close error. %s\n", i, disk->name, esc_tag(file->sub, esc_buffer), strerror(errno));
667 : log_fatal("DANGER! Unexpected close error in a data disk.\n");
@@ -732,8 +732,8 @@
670 : }
671 : }
672 :
- 673 63283 : ret = rename(path, path_to);
- 674 63283 : if (ret != 0) {
+ 673 63287 : ret = rename(path, path_to);
+ 674 63287 : if (ret != 0) {
675 : /* LCOV_EXCL_START */
676 : log_fatal("Error renaming '%s' to '%s'. %s.\n", path, path_to, strerror(errno));
677 : log_fatal("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n");
@@ -741,22 +741,22 @@
679 : /* LCOV_EXCL_STOP */
680 : }
681 :
- 682 63283 : log_tag("status:unrecoverable:%s:%s\n", disk->name, esc_tag(file->sub, esc_buffer));
- 683 63283 : msg_info("unrecoverable %s\n", fmt_term(disk, file->sub, esc_buffer));
+ 682 63287 : log_tag("status:unrecoverable:%s:%s\n", disk->name, esc_tag(file->sub, esc_buffer));
+ 683 63287 : msg_info("unrecoverable %s\n", fmt_term(disk, file->sub, esc_buffer));
684 :
685 : /* and do not set the time if damaged */
- 686 63283 : goto close_and_continue;
+ 686 63287 : goto close_and_continue;
687 : }
688 :
689 : /* if the file is not fixed, meaning that it is untouched */
- 690 693951 : if (!file_flag_has(file, FILE_IS_FIXED)) {
+ 690 693947 : if (!file_flag_has(file, FILE_IS_FIXED)) {
691 : /* nothing to do, but close the file */
- 692 574520 : goto close_and_continue;
+ 692 574476 : goto close_and_continue;
693 : }
694 :
695 : /* if the file is closed or different than the one expected, reopen it */
696 : /* a different open file could happen when filtering for bad blocks */
- 697 119431 : if (handle[j].file != file) {
+ 697 119471 : if (handle[j].file != file) {
698 : /* close a potential different file */
699 0 : ret = handle_close(&handle[j]);
700 0 : if (ret != 0) {
@@ -779,13 +779,13 @@
717 : }
718 : }
719 :
- 720 119431 : log_tag("status:recovered:%s:%s\n", disk->name, esc_tag(file->sub, esc_buffer));
- 721 119431 : msg_info("recovered %s\n", fmt_term(disk, file->sub, esc_buffer));
+ 720 119471 : log_tag("status:recovered:%s:%s\n", disk->name, esc_tag(file->sub, esc_buffer));
+ 721 119471 : msg_info("recovered %s\n", fmt_term(disk, file->sub, esc_buffer));
722 :
- 723 119431 : inode = handle[j].st.st_ino;
+ 723 119471 : inode = handle[j].st.st_ino;
724 :
725 : /* search for the corresponding inode */
- 726 119431 : collide_file = tommy_hashdyn_search(&disk->inodeset, file_inode_compare_to_arg, &inode, file_inode_hash(inode));
+ 726 119471 : collide_file = tommy_hashdyn_search(&disk->inodeset, file_inode_compare_to_arg, &inode, file_inode_hash(inode));
727 :
728 : /* if the inode is already in the database and it refers at a different file name, */
729 : /* we can fix the file time ONLY if the time and size allow to differentiate */
@@ -795,15 +795,15 @@
733 : /* when recreating them the inodes may be reused in a different order, */
734 : /* and at the next sync some files may have matching inode/size/time even if different name */
735 : /* not allowing sync to detect that the file is changed and not renamed */
- 736 119431 : if (!collide_file /* if not in the database, there is no collision */
- 737 37411 : || strcmp(collide_file->sub, file->sub) == 0 /* if the name is the same, it's the right collision */
- 738 28341 : || collide_file->size != file->size /* if the size is different, the collision is identified */
+ 736 119471 : if (!collide_file /* if not in the database, there is no collision */
+ 737 37421 : || strcmp(collide_file->sub, file->sub) == 0 /* if the name is the same, it's the right collision */
+ 738 28313 : || collide_file->size != file->size /* if the size is different, the collision is identified */
739 9 : || collide_file->mtime_sec != file->mtime_sec /* if the mtime is different, the collision is identified */
740 7 : || collide_file->mtime_nsec != file->mtime_nsec /* same for mtime_nsec */
741 : ) {
742 : /* set the original modification time */
- 743 119431 : ret = handle_utime(&handle[j]);
- 744 238862 : if (ret == -1) {
+ 743 119471 : ret = handle_utime(&handle[j]);
+ 744 238942 : if (ret == -1) {
745 : /* LCOV_EXCL_START */
746 : /* mark the file as damaged */
747 : file_flag_set(file, FILE_IS_DAMAGED);
@@ -818,21 +818,21 @@
756 : /* we are not fixing, but only checking */
757 : /* print just the final status */
758 1308032 : if (file_flag_has(file, FILE_IS_DAMAGED)) {
- 759 9499 : if (state->opt.auditonly) {
- 760 2799 : log_tag("status:damaged:%s:%s\n", disk->name, esc_tag(file->sub, esc_buffer));
- 761 2799 : msg_info("damaged %s\n", fmt_term(disk, file->sub, esc_buffer));
+ 759 9468 : if (state->opt.auditonly) {
+ 760 2829 : log_tag("status:damaged:%s:%s\n", disk->name, esc_tag(file->sub, esc_buffer));
+ 761 2829 : msg_info("damaged %s\n", fmt_term(disk, file->sub, esc_buffer));
762 : } else {
- 763 6700 : log_tag("status:unrecoverable:%s:%s\n", disk->name, esc_tag(file->sub, esc_buffer));
- 764 6700 : msg_info("unrecoverable %s\n", fmt_term(disk, file->sub, esc_buffer));
+ 763 6639 : log_tag("status:unrecoverable:%s:%s\n", disk->name, esc_tag(file->sub, esc_buffer));
+ 764 6639 : msg_info("unrecoverable %s\n", fmt_term(disk, file->sub, esc_buffer));
765 : }
- 766 1298533 : } else if (file_flag_has(file, FILE_IS_FIXED)) {
- 767 76212 : log_tag("status:recoverable:%s:%s\n", disk->name, esc_tag(file->sub, esc_buffer));
- 768 76212 : msg_info("recoverable %s\n", fmt_term(disk, file->sub, esc_buffer));
+ 766 1298564 : } else if (file_flag_has(file, FILE_IS_FIXED)) {
+ 767 76301 : log_tag("status:recoverable:%s:%s\n", disk->name, esc_tag(file->sub, esc_buffer));
+ 768 76301 : msg_info("recoverable %s\n", fmt_term(disk, file->sub, esc_buffer));
769 : } else {
770 : /* we don't use msg_verbose() because it also goes into the log */
- 771 1222321 : if (msg_level >= MSG_VERBOSE) {
- 772 23229 : log_tag("status:correct:%s:%s\n", disk->name, esc_tag(file->sub, esc_buffer));
- 773 23229 : msg_info("correct %s\n", fmt_term(disk, file->sub, esc_buffer));
+ 771 1222263 : if (msg_level >= MSG_VERBOSE) {
+ 772 23199 : log_tag("status:correct:%s:%s\n", disk->name, esc_tag(file->sub, esc_buffer));
+ 773 23199 : msg_info("correct %s\n", fmt_term(disk, file->sub, esc_buffer));
774 : }
775 : }
776 : }
@@ -844,8 +844,8 @@
782 2162259 : if (handle[j].file == file) {
783 : /* ensure to close the file just after finishing with it */
784 : /* to avoid to keep it open without any possible use */
- 785 1978440 : ret = handle_close(&handle[j]);
- 786 1978440 : if (ret != 0) {
+ 785 1978527 : ret = handle_close(&handle[j]);
+ 786 1978527 : if (ret != 0) {
787 : /* LCOV_EXCL_START */
788 : log_tag("error:%u:%s:%s: Close error. %s\n", i, disk->name, esc_tag(file->sub, esc_buffer), strerror(errno));
789 : log_fatal("DANGER! Unexpected close error in a data disk.\n");
@@ -971,1118 +971,1122 @@
909 : /* post process the files */
910 25246 : ret = file_post(state, fix, i, handle, diskmax);
911 25246 : if (ret == -1) {
- 912 0 : log_fatal("Stopping at block %u\n", i);
- 913 0 : ++unrecoverable_error;
- 914 0 : goto bail;
- 915 : }
- 916 :
- 917 : /* and now continue with the next block */
- 918 25246 : continue;
- 919 : }
- 920 :
- 921 : /* If we have valid parity, and it makes sense to check its content. */
- 922 : /* If we already know that the parity is invalid, we just read the file */
- 923 : /* but we don't report parity errors */
- 924 : /* Note that with auditonly, we anyway skip the full parity check, */
- 925 : /* because we also don't read it at all */
- 926 910233 : valid_parity = 1;
- 927 :
- 928 : /* keep track of the number of failed blocks */
- 929 910233 : failed_count = 0;
- 930 :
- 931 : /* get block specific info */
- 932 910233 : info = info_get(&state->infoarr, i);
- 933 :
- 934 : /* if we have to use the old hash */
- 935 910233 : rehash = info_get_rehash(info);
- 936 :
- 937 : /* for each disk, process the block */
- 938 6371631 : for (j = 0; j < diskmax; ++j) {
- 939 : int read_size;
- 940 : unsigned char hash[HASH_MAX];
- 941 : struct snapraid_disk* disk;
- 942 : struct snapraid_block* block;
- 943 : struct snapraid_file* file;
- 944 : block_off_t file_pos;
- 945 : unsigned block_state;
- 946 :
- 947 : /* if the disk position is not used */
- 948 5461398 : disk = handle[j].disk;
- 949 5461398 : if (!disk) {
- 950 : /* use an empty block */
- 951 14061 : memset(buffer[j], 0, state->block_size);
- 952 955462 : continue;
- 953 : }
- 954 :
- 955 : /* if the disk block is not used */
- 956 5447337 : block = fs_par2block_find(disk, i);
- 957 5447337 : if (block == BLOCK_NULL) {
- 958 : /* use an empty block */
- 959 192063 : memset(buffer[j], 0, state->block_size);
- 960 192063 : continue;
- 961 : }
- 962 :
- 963 : /* get the state of the block */
- 964 5255274 : block_state = block_state_get(block);
- 965 :
- 966 : /* if the parity is not valid */
- 967 5255274 : if (block_has_invalid_parity(block)) {
- 968 : /* mark the parity as invalid, and don't try to check/fix it */
- 969 : /* because it will be recomputed at the next sync */
- 970 94587 : valid_parity = 0;
- 971 : /* follow */
- 972 : }
- 973 :
- 974 : /* if the block is DELETED */
- 975 5255274 : if (block_state == BLOCK_STATE_DELETED) {
- 976 : /* use an empty block */
- 977 18454 : memset(buffer[j], 0, state->block_size);
- 978 :
- 979 : /* store it in the failed set, because potentially */
- 980 : /* the parity may be still computed with the previous content */
- 981 18454 : failed[failed_count].is_bad = 0; /* note that is_bad==0 <=> file==0 */
- 982 18454 : failed[failed_count].is_outofdate = 0;
- 983 18454 : failed[failed_count].index = j;
- 984 18454 : failed[failed_count].block = block;
- 985 18454 : failed[failed_count].disk = disk;
- 986 18454 : failed[failed_count].file = 0;
- 987 18454 : failed[failed_count].file_pos = 0;
- 988 18454 : failed[failed_count].handle = 0;
- 989 18454 : ++failed_count;
- 990 18454 : continue;
- 991 : }
- 992 :
- 993 : /* get the file of this block */
- 994 5236820 : file = fs_par2file_get(disk, i, &file_pos);
- 995 :
- 996 : /* if we are only hashing, we can skip excluded files and don't even read them */
- 997 5236820 : if (state->opt.auditonly && file_flag_has(file, FILE_IS_EXCLUDED)) {
- 998 : /* use an empty block */
- 999 : /* in true, this is unnecessary, because we are not checking any parity */
- 1000 : /* but we keep it for completeness */
- 1001 0 : memset(buffer[j], 0, state->block_size);
- 1002 0 : continue;
- 1003 : }
- 1004 :
- 1005 : /* if the file is closed or different than the current one */
- 1006 5236820 : if (handle[j].file == 0 || handle[j].file != file) {
- 1007 : /* close the old one, if any */
- 1008 2260089 : ret = handle_close(&handle[j]);
- 1009 2260089 : if (ret == -1) {
- 1010 : /* LCOV_EXCL_START */
- 1011 : log_tag("error:%u:%s:%s: Close error. %s\n", i, disk->name, esc_tag(handle[j].file->sub, esc_buffer), strerror(errno));
- 1012 : log_fatal("DANGER! Unexpected close error in a data disk.\n");
- 1013 : log_fatal("Stopping at block %u\n", i);
- 1014 : ++unrecoverable_error;
- 1015 : goto bail;
- 1016 : /* LCOV_EXCL_STOP */
- 1017 : }
- 1018 :
- 1019 : /* if fixing, and the file is not excluded, we must open for writing */
- 1020 2260089 : if (fix && !file_flag_has(file, FILE_IS_EXCLUDED)) {
- 1021 : /* if fixing, create the file, open for writing and resize if required */
- 1022 771311 : ret = handle_create(&handle[j], file, state->file_mode);
- 1023 771311 : if (ret == -1) {
- 1024 : /* LCOV_EXCL_START */
- 1025 : if (errno == EACCES) {
- 1026 : log_fatal("WARNING! Please give write permission to the file.\n");
- 1027 : } else {
- 1028 : log_fatal("DANGER! Without a working data disk, it isn't possible to fix errors on it.\n");
- 1029 : }
- 1030 : log_fatal("Stopping at block %u\n", i);
- 1031 : ++unrecoverable_error;
- 1032 : goto bail;
- 1033 : /* LCOV_EXCL_STOP */
- 1034 : }
- 1035 :
- 1036 : /* check if the file was just created */
- 1037 1542622 : if (handle[j].created != 0) {
- 1038 : /* if fragmented, it may be reopened, so remember that the file */
- 1039 : /* was originally missing */
- 1040 113135 : file_flag_set(file, FILE_IS_CREATED);
- 1041 : }
- 1042 : } else {
- 1043 : /* open the file only for reading */
- 1044 1488778 : if (!file_flag_has(file, FILE_IS_MISSING))
- 1045 1372856 : ret = handle_open(&handle[j], file, state->file_mode,
- 1046 1372856 : log_error, state->opt.expected_missing ? log_expected : 0);
- 1047 : else
- 1048 115922 : ret = -1; /* if the file is missing, we cannot open it */
- 1049 1488778 : if (ret == -1) {
- 1050 : /* save the failed block for the check/fix */
- 1051 194661 : failed[failed_count].is_bad = 1;
- 1052 194661 : failed[failed_count].is_outofdate = 0;
- 1053 194661 : failed[failed_count].index = j;
- 1054 194661 : failed[failed_count].block = block;
- 1055 194661 : failed[failed_count].disk = disk;
- 1056 194661 : failed[failed_count].file = file;
- 1057 194661 : failed[failed_count].file_pos = file_pos;
- 1058 194661 : failed[failed_count].handle = &handle[j];
- 1059 194661 : ++failed_count;
- 1060 :
- 1061 194661 : log_tag("error:%u:%s:%s: Open error at position %u\n", i, disk->name, esc_tag(file->sub, esc_buffer), file_pos);
- 1062 194661 : ++error;
- 1063 :
- 1064 : /* mark the file as missing, to avoid to retry to open it again */
- 1065 : /* note that this can be done only if we are not fixing it */
- 1066 : /* otherwise, it could be recreated */
- 1067 194661 : file_flag_set(file, FILE_IS_MISSING);
- 1068 194661 : continue;
- 1069 : }
- 1070 : }
- 1071 :
- 1072 : /* if it's the first open, and not excluded */
- 1073 2065428 : if (!file_flag_has(file, FILE_IS_OPENED)
- 1074 2050067 : && !file_flag_has(file, FILE_IS_EXCLUDED)) {
- 1075 :
- 1076 : /* check if the file is changed */
- 1077 1998636 : if (handle[j].st.st_size != file->size
- 1078 1805944 : || handle[j].st.st_mtime != file->mtime_sec
- 1079 1781522 : || STAT_NSEC(&handle[j].st) != file->mtime_nsec
- 1080 : /* don't check the inode to support file-system without persistent inodes */
- 1081 : ) {
- 1082 : /* report that the file is not synced */
- 1083 217114 : file_flag_set(file, FILE_IS_UNSYNCED);
- 1084 : }
- 1085 : }
- 1086 :
- 1087 : /* if it's the first open, and not excluded and larger */
- 1088 2065428 : if (!file_flag_has(file, FILE_IS_OPENED)
- 1089 2050067 : && !file_flag_has(file, FILE_IS_EXCLUDED)
- 1090 1998636 : && !(state->opt.syncedonly && file_flag_has(file, FILE_IS_UNSYNCED))
- 1091 1998636 : && handle[j].st.st_size > file->size
- 1092 : ) {
- 1093 8724 : log_error("File '%s' is larger than expected.\n", handle[j].path);
- 1094 8724 : log_tag("error:%u:%s:%s: Size error\n", i, disk->name, esc_tag(file->sub, esc_buffer));
- 1095 8724 : ++error;
- 1096 :
- 1097 8724 : if (fix) {
- 1098 3222 : ret = handle_truncate(&handle[j], file);
- 1099 3222 : if (ret == -1) {
- 1100 : /* LCOV_EXCL_START */
- 1101 : log_fatal("DANGER! Unexpected truncate error in a data disk, it isn't possible to fix.\n");
- 1102 : log_fatal("Stopping at block %u\n", i);
- 1103 : ++unrecoverable_error;
- 1104 : goto bail;
- 1105 : /* LCOV_EXCL_STOP */
- 1106 : }
- 1107 :
- 1108 3222 : log_tag("fixed:%u:%s:%s: Fixed size\n", i, disk->name, esc_tag(file->sub, esc_buffer));
- 1109 3222 : ++recovered_error;
- 1110 : }
- 1111 : }
- 1112 :
- 1113 : /* mark the file as opened at least one time */
- 1114 : /* this is used to avoid to check the unsynced and size */
- 1115 : /* more than one time, in case the file is reopened later */
- 1116 2065428 : file_flag_set(file, FILE_IS_OPENED);
- 1117 : }
- 1118 :
- 1119 : /* read from the file */
- 1120 5042159 : read_size = handle_read(&handle[j], file_pos, buffer[j], state->block_size,
- 1121 5042159 : log_error, state->opt.expected_missing ? log_expected : 0);
- 1122 5042159 : if (read_size == -1) {
- 1123 : /* save the failed block for the check/fix */
- 1124 442169 : failed[failed_count].is_bad = 1; /* it's bad because we cannot read it */
- 1125 442169 : failed[failed_count].is_outofdate = 0;
- 1126 442169 : failed[failed_count].index = j;
- 1127 442169 : failed[failed_count].block = block;
- 1128 442169 : failed[failed_count].disk = disk;
- 1129 442169 : failed[failed_count].file = file;
- 1130 442169 : failed[failed_count].file_pos = file_pos;
- 1131 442169 : failed[failed_count].handle = &handle[j];
- 1132 442169 : ++failed_count;
- 1133 :
- 1134 442169 : log_tag("error:%u:%s:%s: Read error at position %u\n", i, disk->name, esc_tag(file->sub, esc_buffer), file_pos);
- 1135 442169 : ++error;
- 1136 442169 : continue;
- 1137 : }
- 1138 :
- 1139 4599990 : countsize += read_size;
+ 912 : /* LCOV_EXCL_START */
+ 913 : log_fatal("Stopping at block %u\n", i);
+ 914 : ++unrecoverable_error;
+ 915 : goto bail;
+ 916 : /* LCOV_EXCL_STOP */
+ 917 : }
+ 918 :
+ 919 : /* and now continue with the next block */
+ 920 25246 : continue;
+ 921 : }
+ 922 :
+ 923 : /* If we have valid parity, and it makes sense to check its content. */
+ 924 : /* If we already know that the parity is invalid, we just read the file */
+ 925 : /* but we don't report parity errors */
+ 926 : /* Note that with auditonly, we anyway skip the full parity check, */
+ 927 : /* because we also don't read it at all */
+ 928 910233 : valid_parity = 1;
+ 929 :
+ 930 : /* keep track of the number of failed blocks */
+ 931 910233 : failed_count = 0;
+ 932 :
+ 933 : /* get block specific info */
+ 934 910233 : info = info_get(&state->infoarr, i);
+ 935 :
+ 936 : /* if we have to use the old hash */
+ 937 910233 : rehash = info_get_rehash(info);
+ 938 :
+ 939 : /* for each disk, process the block */
+ 940 6371631 : for (j = 0; j < diskmax; ++j) {
+ 941 : int read_size;
+ 942 : unsigned char hash[HASH_MAX];
+ 943 : struct snapraid_disk* disk;
+ 944 : struct snapraid_block* block;
+ 945 : struct snapraid_file* file;
+ 946 : block_off_t file_pos;
+ 947 : unsigned block_state;
+ 948 :
+ 949 : /* if the disk position is not used */
+ 950 5461398 : disk = handle[j].disk;
+ 951 5461398 : if (!disk) {
+ 952 : /* use an empty block */
+ 953 14061 : memset(buffer[j], 0, state->block_size);
+ 954 955271 : continue;
+ 955 : }
+ 956 :
+ 957 : /* if the disk block is not used */
+ 958 5447337 : block = fs_par2block_find(disk, i);
+ 959 5447337 : if (block == BLOCK_NULL) {
+ 960 : /* use an empty block */
+ 961 192063 : memset(buffer[j], 0, state->block_size);
+ 962 192063 : continue;
+ 963 : }
+ 964 :
+ 965 : /* get the state of the block */
+ 966 5255274 : block_state = block_state_get(block);
+ 967 :
+ 968 : /* if the parity is not valid */
+ 969 5255274 : if (block_has_invalid_parity(block)) {
+ 970 : /* mark the parity as invalid, and don't try to check/fix it */
+ 971 : /* because it will be recomputed at the next sync */
+ 972 94587 : valid_parity = 0;
+ 973 : /* follow */
+ 974 : }
+ 975 :
+ 976 : /* if the block is DELETED */
+ 977 5255274 : if (block_state == BLOCK_STATE_DELETED) {
+ 978 : /* use an empty block */
+ 979 18454 : memset(buffer[j], 0, state->block_size);
+ 980 :
+ 981 : /* store it in the failed set, because potentially */
+ 982 : /* the parity may be still computed with the previous content */
+ 983 18454 : failed[failed_count].is_bad = 0; /* note that is_bad==0 <=> file==0 */
+ 984 18454 : failed[failed_count].is_outofdate = 0;
+ 985 18454 : failed[failed_count].index = j;
+ 986 18454 : failed[failed_count].block = block;
+ 987 18454 : failed[failed_count].disk = disk;
+ 988 18454 : failed[failed_count].file = 0;
+ 989 18454 : failed[failed_count].file_pos = 0;
+ 990 18454 : failed[failed_count].handle = 0;
+ 991 18454 : ++failed_count;
+ 992 18454 : continue;
+ 993 : }
+ 994 :
+ 995 : /* get the file of this block */
+ 996 5236820 : file = fs_par2file_get(disk, i, &file_pos);
+ 997 :
+ 998 : /* if we are only hashing, we can skip excluded files and don't even read them */
+ 999 5236820 : if (state->opt.auditonly && file_flag_has(file, FILE_IS_EXCLUDED)) {
+ 1000 : /* use an empty block */
+ 1001 : /* in true, this is unnecessary, because we are not checking any parity */
+ 1002 : /* but we keep it for completeness */
+ 1003 0 : memset(buffer[j], 0, state->block_size);
+ 1004 0 : continue;
+ 1005 : }
+ 1006 :
+ 1007 : /* if the file is closed or different than the current one */
+ 1008 5236820 : if (handle[j].file == 0 || handle[j].file != file) {
+ 1009 : /* close the old one, if any */
+ 1010 2259726 : ret = handle_close(&handle[j]);
+ 1011 2259726 : if (ret == -1) {
+ 1012 : /* LCOV_EXCL_START */
+ 1013 : log_tag("error:%u:%s:%s: Close error. %s\n", i, disk->name, esc_tag(handle[j].file->sub, esc_buffer), strerror(errno));
+ 1014 : log_fatal("DANGER! Unexpected close error in a data disk.\n");
+ 1015 : log_fatal("Stopping at block %u\n", i);
+ 1016 : ++unrecoverable_error;
+ 1017 : goto bail;
+ 1018 : /* LCOV_EXCL_STOP */
+ 1019 : }
+ 1020 :
+ 1021 : /* if fixing, and the file is not excluded, we must open for writing */
+ 1022 2259726 : if (fix && !file_flag_has(file, FILE_IS_EXCLUDED)) {
+ 1023 : /* if fixing, create the file, open for writing and resize if required */
+ 1024 771305 : ret = handle_create(&handle[j], file, state->file_mode);
+ 1025 771305 : if (ret == -1) {
+ 1026 : /* LCOV_EXCL_START */
+ 1027 : if (errno == EACCES) {
+ 1028 : log_fatal("WARNING! Please give write permission to the file.\n");
+ 1029 : } else {
+ 1030 : log_fatal("DANGER! Without a working data disk, it isn't possible to fix errors on it.\n");
+ 1031 : }
+ 1032 : log_fatal("Stopping at block %u\n", i);
+ 1033 : ++unrecoverable_error;
+ 1034 : goto bail;
+ 1035 : /* LCOV_EXCL_STOP */
+ 1036 : }
+ 1037 :
+ 1038 : /* check if the file was just created */
+ 1039 1542610 : if (handle[j].created != 0) {
+ 1040 : /* if fragmented, it may be reopened, so remember that the file */
+ 1041 : /* was originally missing */
+ 1042 113067 : file_flag_set(file, FILE_IS_CREATED);
+ 1043 : }
+ 1044 : } else {
+ 1045 : /* open the file only for reading */
+ 1046 1488421 : if (!file_flag_has(file, FILE_IS_MISSING))
+ 1047 1372845 : ret = handle_open(&handle[j], file, state->file_mode,
+ 1048 1372845 : log_error, state->opt.expected_missing ? log_expected : 0);
+ 1049 : else
+ 1050 115576 : ret = -1; /* if the file is missing, we cannot open it */
+ 1051 1488421 : if (ret == -1) {
+ 1052 : /* save the failed block for the check/fix */
+ 1053 194224 : failed[failed_count].is_bad = 1;
+ 1054 194224 : failed[failed_count].is_outofdate = 0;
+ 1055 194224 : failed[failed_count].index = j;
+ 1056 194224 : failed[failed_count].block = block;
+ 1057 194224 : failed[failed_count].disk = disk;
+ 1058 194224 : failed[failed_count].file = file;
+ 1059 194224 : failed[failed_count].file_pos = file_pos;
+ 1060 194224 : failed[failed_count].handle = &handle[j];
+ 1061 194224 : ++failed_count;
+ 1062 :
+ 1063 194224 : log_tag("error:%u:%s:%s: Open error at position %u\n", i, disk->name, esc_tag(file->sub, esc_buffer), file_pos);
+ 1064 194224 : ++error;
+ 1065 :
+ 1066 : /* mark the file as missing, to avoid to retry to open it again */
+ 1067 : /* note that this can be done only if we are not fixing it */
+ 1068 : /* otherwise, it could be recreated */
+ 1069 194224 : file_flag_set(file, FILE_IS_MISSING);
+ 1070 194224 : continue;
+ 1071 : }
+ 1072 : }
+ 1073 :
+ 1074 : /* if it's the first open, and not excluded */
+ 1075 2065502 : if (!file_flag_has(file, FILE_IS_OPENED)
+ 1076 2050149 : && !file_flag_has(file, FILE_IS_EXCLUDED)) {
+ 1077 :
+ 1078 : /* check if the file is changed */
+ 1079 1998718 : if (handle[j].st.st_size != file->size
+ 1080 1805971 : || handle[j].st.st_mtime != file->mtime_sec
+ 1081 1781347 : || STAT_NSEC(&handle[j].st) != file->mtime_nsec
+ 1082 : /* don't check the inode to support file-system without persistent inodes */
+ 1083 : ) {
+ 1084 : /* report that the file is not synced */
+ 1085 217371 : file_flag_set(file, FILE_IS_UNSYNCED);
+ 1086 : }
+ 1087 : }
+ 1088 :
+ 1089 : /* if it's the first open, and not excluded and larger */
+ 1090 2065502 : if (!file_flag_has(file, FILE_IS_OPENED)
+ 1091 2050149 : && !file_flag_has(file, FILE_IS_EXCLUDED)
+ 1092 1998718 : && !(state->opt.syncedonly && file_flag_has(file, FILE_IS_UNSYNCED))
+ 1093 1998718 : && handle[j].st.st_size > file->size
+ 1094 : ) {
+ 1095 8628 : log_error("File '%s' is larger than expected.\n", handle[j].path);
+ 1096 8628 : log_tag("error:%u:%s:%s: Size error\n", i, disk->name, esc_tag(file->sub, esc_buffer));
+ 1097 8628 : ++error;
+ 1098 :
+ 1099 8628 : if (fix) {
+ 1100 3180 : ret = handle_truncate(&handle[j], file);
+ 1101 3180 : if (ret == -1) {
+ 1102 : /* LCOV_EXCL_START */
+ 1103 : log_fatal("DANGER! Unexpected truncate error in a data disk, it isn't possible to fix.\n");
+ 1104 : log_fatal("Stopping at block %u\n", i);
+ 1105 : ++unrecoverable_error;
+ 1106 : goto bail;
+ 1107 : /* LCOV_EXCL_STOP */
+ 1108 : }
+ 1109 :
+ 1110 3180 : log_tag("fixed:%u:%s:%s: Fixed size\n", i, disk->name, esc_tag(file->sub, esc_buffer));
+ 1111 3180 : ++recovered_error;
+ 1112 : }
+ 1113 : }
+ 1114 :
+ 1115 : /* mark the file as opened at least one time */
+ 1116 : /* this is used to avoid to check the unsynced and size */
+ 1117 : /* more than one time, in case the file is reopened later */
+ 1118 2065502 : file_flag_set(file, FILE_IS_OPENED);
+ 1119 : }
+ 1120 :
+ 1121 : /* read from the file */
+ 1122 5042596 : read_size = handle_read(&handle[j], file_pos, buffer[j], state->block_size,
+ 1123 5042596 : log_error, state->opt.expected_missing ? log_expected : 0);
+ 1124 5042596 : if (read_size == -1) {
+ 1125 : /* save the failed block for the check/fix */
+ 1126 442271 : failed[failed_count].is_bad = 1; /* it's bad because we cannot read it */
+ 1127 442271 : failed[failed_count].is_outofdate = 0;
+ 1128 442271 : failed[failed_count].index = j;
+ 1129 442271 : failed[failed_count].block = block;
+ 1130 442271 : failed[failed_count].disk = disk;
+ 1131 442271 : failed[failed_count].file = file;
+ 1132 442271 : failed[failed_count].file_pos = file_pos;
+ 1133 442271 : failed[failed_count].handle = &handle[j];
+ 1134 442271 : ++failed_count;
+ 1135 :
+ 1136 442271 : log_tag("error:%u:%s:%s: Read error at position %u\n", i, disk->name, esc_tag(file->sub, esc_buffer), file_pos);
+ 1137 442271 : ++error;
+ 1138 442271 : continue;
+ 1139 : }
1140 :
- 1141 : /* always insert CHG blocks, the repair functions needs all of them */
- 1142 : /* because the parity may be still referring at the old state */
- 1143 : /* and the repair must be aware of it */
- 1144 4599990 : if (block_state == BLOCK_STATE_CHG) {
- 1145 : /* we DO NOT mark them as bad to avoid to overwrite them with wrong data. */
- 1146 : /* if we don't have a hash, we always assume the first read of the block correct. */
- 1147 13843 : failed[failed_count].is_bad = 0; /* we assume the CHG block correct */
- 1148 13843 : failed[failed_count].is_outofdate = 0;
- 1149 13843 : failed[failed_count].index = j;
- 1150 13843 : failed[failed_count].block = block;
- 1151 13843 : failed[failed_count].disk = disk;
- 1152 13843 : failed[failed_count].file = file;
- 1153 13843 : failed[failed_count].file_pos = file_pos;
- 1154 13843 : failed[failed_count].handle = &handle[j];
- 1155 13843 : ++failed_count;
- 1156 13843 : continue;
- 1157 : }
- 1158 :
- 1159 4586147 : assert(block_state == BLOCK_STATE_BLK || block_state == BLOCK_STATE_REP);
+ 1141 4600325 : countsize += read_size;
+ 1142 :
+ 1143 : /* always insert CHG blocks, the repair functions needs all of them */
+ 1144 : /* because the parity may be still referring at the old state */
+ 1145 : /* and the repair must be aware of it */
+ 1146 4600325 : if (block_state == BLOCK_STATE_CHG) {
+ 1147 : /* we DO NOT mark them as bad to avoid to overwrite them with wrong data. */
+ 1148 : /* if we don't have a hash, we always assume the first read of the block correct. */
+ 1149 13843 : failed[failed_count].is_bad = 0; /* we assume the CHG block correct */
+ 1150 13843 : failed[failed_count].is_outofdate = 0;
+ 1151 13843 : failed[failed_count].index = j;
+ 1152 13843 : failed[failed_count].block = block;
+ 1153 13843 : failed[failed_count].disk = disk;
+ 1154 13843 : failed[failed_count].file = file;
+ 1155 13843 : failed[failed_count].file_pos = file_pos;
+ 1156 13843 : failed[failed_count].handle = &handle[j];
+ 1157 13843 : ++failed_count;
+ 1158 13843 : continue;
+ 1159 : }
1160 :
- 1161 : /* compute the hash of the block just read */
- 1162 4586147 : if (rehash) {
- 1163 27243 : memhash(state->prevhash, state->prevhashseed, hash, buffer[j], read_size);
- 1164 : } else {
- 1165 4558904 : memhash(state->hash, state->hashseed, hash, buffer[j], read_size);
- 1166 : }
- 1167 :
- 1168 : /* compare the hash */
- 1169 4586147 : if (memcmp(hash, block->hash, BLOCK_HASH_SIZE) != 0) {
- 1170 12722 : unsigned diff = memdiff(hash, block->hash, BLOCK_HASH_SIZE);
- 1171 :
- 1172 : /* save the failed block for the check/fix */
- 1173 12722 : failed[failed_count].is_bad = 1; /* it's bad because the hash doesn't match */
- 1174 12722 : failed[failed_count].is_outofdate = 0;
- 1175 12722 : failed[failed_count].index = j;
- 1176 12722 : failed[failed_count].block = block;
- 1177 12722 : failed[failed_count].disk = disk;
- 1178 12722 : failed[failed_count].file = file;
- 1179 12722 : failed[failed_count].file_pos = file_pos;
- 1180 12722 : failed[failed_count].handle = &handle[j];
- 1181 12722 : ++failed_count;
- 1182 :
- 1183 12722 : log_tag("error:%u:%s:%s: Data error at position %u, diff bits %u\n", i, disk->name, esc_tag(file->sub, esc_buffer), file_pos, diff);
- 1184 12722 : ++error;
- 1185 12722 : continue;
- 1186 : }
- 1187 :
- 1188 : /* always insert REP blocks, the repair functions needs all of them */
- 1189 : /* because the parity may be still referring at the old state */
- 1190 : /* and the repair must be aware of it */
- 1191 4573425 : if (block_state == BLOCK_STATE_REP) {
- 1192 53428 : failed[failed_count].is_bad = 0; /* it's not bad */
- 1193 53428 : failed[failed_count].is_outofdate = 0;
- 1194 53428 : failed[failed_count].index = j;
- 1195 53428 : failed[failed_count].block = block;
- 1196 53428 : failed[failed_count].disk = disk;
- 1197 53428 : failed[failed_count].file = file;
- 1198 53428 : failed[failed_count].file_pos = file_pos;
- 1199 53428 : failed[failed_count].handle = &handle[j];
- 1200 53428 : ++failed_count;
- 1201 53428 : continue;
- 1202 : }
- 1203 : }
- 1204 :
- 1205 : /* now read and check the parity if requested */
- 1206 910233 : if (!state->opt.auditonly) {
- 1207 : void* buffer_recov[LEV_MAX];
- 1208 : void* buffer_zero;
- 1209 :
- 1210 : /* buffers for parity read and not computed */
- 1211 4170787 : for (l = 0; l < state->level; ++l)
- 1212 3299829 : buffer_recov[l] = buffer[diskmax + state->level + l];
- 1213 2796877 : for (; l < LEV_MAX; ++l)
- 1214 1925919 : buffer_recov[l] = 0;
- 1215 :
- 1216 : /* the zero buffer is the last one */
- 1217 870958 : buffer_zero = buffer[buffermax - 1];
- 1218 :
- 1219 : /* read the parity */
- 1220 4170787 : for (l = 0; l < state->level; ++l) {
- 1221 3299829 : if (parity[l]) {
- 1222 3285927 : ret = parity_read(parity[l], i, buffer_recov[l], state->block_size, log_error);
- 1223 3285927 : if (ret == -1) {
- 1224 11360 : buffer_recov[l] = 0; /* no parity to use */
- 1225 :
- 1226 11360 : log_tag("parity_error:%u:%s: Read error\n", i, lev_config_name(l));
- 1227 11360 : ++error;
- 1228 : }
- 1229 : } else {
- 1230 13902 : buffer_recov[l] = 0;
- 1231 : }
- 1232 : }
- 1233 :
- 1234 : /* try all the recovering strategies */
- 1235 870958 : ret = repair(state, rehash, i, diskmax, failed, failed_map, failed_count, buffer, buffer_recov, buffer_zero);
- 1236 870958 : if (ret != 0) {
- 1237 : /* increment the number of errors */
- 1238 48053 : if (ret > 0)
- 1239 4801 : error += ret;
- 1240 48053 : ++unrecoverable_error;
- 1241 :
- 1242 : /* print a list of all the errors in files */
- 1243 219490 : for (j = 0; j < failed_count; ++j) {
- 1244 171437 : if (failed[j].is_bad)
- 1245 166915 : log_tag("unrecoverable:%u:%s:%s: Unrecoverable error at position %u\n", i, failed[j].disk->name, esc_tag(failed[j].file->sub, esc_buffer), failed[j].file_pos);
- 1246 : }
- 1247 :
- 1248 : /* keep track of damaged files */
- 1249 219490 : for (j = 0; j < failed_count; ++j) {
- 1250 171437 : if (failed[j].is_bad)
- 1251 166915 : file_flag_set(failed[j].file, FILE_IS_DAMAGED);
- 1252 : }
- 1253 : } else {
- 1254 : /* now counts partial recovers */
- 1255 : /* note that this could happen only when we have an incomplete 'sync' */
- 1256 : /* and that we have recovered is the state before the 'sync' */
- 1257 822905 : int partial_recover_error = 0;
- 1258 :
- 1259 : /* print a list of all the errors in files */
- 1260 1380849 : for (j = 0; j < failed_count; ++j) {
- 1261 557944 : if (failed[j].is_bad && failed[j].is_outofdate) {
- 1262 8 : ++partial_recover_error;
- 1263 8 : log_tag("unrecoverable:%u:%s:%s: Unrecoverable unsynced error at position %u\n", i, failed[j].disk->name, esc_tag(failed[j].file->sub, esc_buffer), failed[j].file_pos);
- 1264 : }
- 1265 : }
- 1266 822905 : if (partial_recover_error != 0) {
- 1267 8 : error += partial_recover_error;
- 1268 8 : ++unrecoverable_error;
- 1269 : }
- 1270 :
- 1271 : /* now check parities, but only if all the blocks have it computed */
- 1272 : /* if you check/fix after a partial sync, it's OK to have parity errors on the blocks with invalid parity */
- 1273 : /* and doesn't make sense to try to fix it */
- 1274 822905 : if (valid_parity) {
- 1275 : /* check the parity */
- 1276 3728710 : for (l = 0; l < state->level; ++l) {
- 1277 2967390 : if (buffer_recov[l] != 0 && memcmp(buffer_recov[l], buffer[diskmax + l], state->block_size) != 0) {
- 1278 78690 : unsigned diff = memdiff(buffer_recov[l], buffer[diskmax + l], state->block_size);
- 1279 :
- 1280 : /* mark that the read parity is wrong, setting ptr to 0 */
- 1281 78690 : buffer_recov[l] = 0;
- 1282 :
- 1283 78690 : log_tag("parity_error:%u:%s: Data error, diff bits %u\n", i, lev_config_name(l), diff);
- 1284 78690 : ++error;
- 1285 : }
- 1286 : }
- 1287 : }
- 1288 :
- 1289 : /* now write recovered files */
- 1290 822905 : if (fix) {
- 1291 : /* update the fixed files */
- 1292 652804 : for (j = 0; j < failed_count; ++j) {
- 1293 : /* nothing to do if it doesn't need recovering */
- 1294 338160 : if (!failed[j].is_bad)
- 1295 40318 : continue;
- 1296 :
- 1297 : /* do not fix if the file is excluded */
- 1298 297842 : if (file_flag_has(failed[j].file, FILE_IS_EXCLUDED)
- 1299 288562 : || (state->opt.syncedonly && file_flag_has(failed[j].file, FILE_IS_UNSYNCED)))
- 1300 9280 : continue;
- 1301 :
- 1302 288562 : ret = handle_write(failed[j].handle, failed[j].file_pos, buffer[failed[j].index], state->block_size);
- 1303 288562 : if (ret == -1) {
- 1304 : /* LCOV_EXCL_START */
- 1305 : /* mark the file as damaged */
- 1306 : file_flag_set(failed[j].file, FILE_IS_DAMAGED);
- 1307 :
- 1308 : if (errno == EACCES) {
- 1309 : log_fatal("WARNING! Please give write permission to the file.\n");
- 1310 : } else {
- 1311 : /* we do not use DANGER because it could be ENOSPC which is not always correctly reported */
- 1312 : log_fatal("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n");
- 1313 : }
- 1314 : log_fatal("Stopping at block %u\n", i);
- 1315 : ++unrecoverable_error;
- 1316 : goto bail;
- 1317 : /* LCOV_EXCL_STOP */
- 1318 : }
- 1319 :
- 1320 : /* if we are not sure that the recovered content is uptodate */
- 1321 288562 : if (failed[j].is_outofdate) {
- 1322 : /* mark the file as damaged */
- 1323 8 : file_flag_set(failed[j].file, FILE_IS_DAMAGED);
- 1324 8 : continue;
- 1325 : }
- 1326 :
- 1327 : /* mark the file as containing some fixes */
- 1328 : /* note that it could be also marked as damaged in other iterations */
- 1329 288554 : file_flag_set(failed[j].file, FILE_IS_FIXED);
- 1330 :
- 1331 288554 : log_tag("fixed:%u:%s:%s: Fixed data error at position %u\n", i, failed[j].disk->name, esc_tag(failed[j].file->sub, esc_buffer), failed[j].file_pos);
- 1332 288554 : ++recovered_error;
- 1333 : }
- 1334 :
- 1335 : /* update parity only if all the blocks have it computed */
- 1336 : /* if you check/fix after a partial sync, you do not want to fix parity */
- 1337 : /* for blocks that are going to have it computed in the sync completion */
- 1338 314644 : if (valid_parity) {
- 1339 : /* update the parity */
- 1340 964013 : for (l = 0; l < state->level; ++l) {
- 1341 : /* if the parity on disk is wrong */
- 1342 698549 : if (buffer_recov[l] == 0
- 1343 : /* and we have access at the parity */
- 1344 72150 : && parity[l] != 0
- 1345 : /* and the parity is not excluded */
- 1346 67463 : && !state->parity[l].is_excluded
- 1347 : ) {
- 1348 67463 : ret = parity_write(parity[l], i, buffer[diskmax + l], state->block_size);
- 1349 67463 : if (ret == -1) {
- 1350 : /* LCOV_EXCL_START */
- 1351 : /* we do not use DANGER because it could be ENOSPC which is not always correctly reported */
- 1352 : log_fatal("WARNING! Without a working %s disk, it isn't possible to fix errors on it.\n", lev_name(l));
- 1353 : log_fatal("Stopping at block %u\n", i);
- 1354 : ++unrecoverable_error;
- 1355 : goto bail;
- 1356 : /* LCOV_EXCL_STOP */
- 1357 : }
- 1358 :
- 1359 67463 : log_tag("parity_fixed:%u:%s: Fixed data error\n", i, lev_config_name(l));
- 1360 67463 : ++recovered_error;
- 1361 : }
- 1362 : }
- 1363 : }
- 1364 : } else {
- 1365 : /* if we are not fixing, we just set the FIXED flag */
- 1366 : /* meaning that we could fix this file if we try */
- 1367 728045 : for (j = 0; j < failed_count; ++j) {
- 1368 219784 : if (failed[j].is_bad) {
- 1369 178899 : file_flag_set(failed[j].file, FILE_IS_FIXED);
- 1370 : }
- 1371 : }
- 1372 : }
- 1373 : }
- 1374 : } else {
- 1375 : /* if we are not checking, we just set the DAMAGED flag */
- 1376 : /* to report that the file is damaged, and we don't know if we can fix it */
- 1377 45171 : for (j = 0; j < failed_count; ++j) {
- 1378 5896 : if (failed[j].is_bad) {
- 1379 5896 : file_flag_set(failed[j].file, FILE_IS_DAMAGED);
- 1380 : }
- 1381 : }
- 1382 : }
- 1383 :
- 1384 : /* post process the files */
- 1385 910233 : ret = file_post(state, fix, i, handle, diskmax);
- 1386 910233 : if (ret == -1) {
- 1387 0 : log_fatal("Stopping at block %u\n", i);
- 1388 0 : ++unrecoverable_error;
- 1389 0 : goto bail;
- 1390 : }
- 1391 :
- 1392 : /* count the number of processed block */
- 1393 910233 : ++countpos;
- 1394 :
- 1395 : /* progress */
- 1396 910233 : if (state_progress(state, 0, i, countpos, countmax, countsize)) {
- 1397 : /* LCOV_EXCL_START */
- 1398 : break;
- 1399 : /* LCOV_EXCL_STOP */
- 1400 : }
- 1401 : }
- 1402 :
- 1403 : /* for each disk, recover empty files, symlinks and empty dirs */
- 1404 826 : for (i = 0; i < diskmax; ++i) {
- 1405 : tommy_node* node;
- 1406 : struct snapraid_disk* disk;
- 1407 :
- 1408 708 : if (!handle[i].disk)
- 1409 3 : continue;
- 1410 :
- 1411 : /* for each empty file in the disk */
- 1412 705 : disk = handle[i].disk;
- 1413 705 : node = disk->filelist;
- 1414 2189135 : while (node) {
- 1415 : char path[PATH_MAX];
- 1416 : struct stat st;
- 1417 : struct snapraid_file* file;
- 1418 2187725 : int unsuccesful = 0;
- 1419 :
- 1420 2187725 : file = node->data;
- 1421 2187725 : node = node->next; /* next node */
- 1422 :
- 1423 : /* if not empty, it's already checked and continue to the next one */
- 1424 2187725 : if (file->size != 0) {
- 1425 4369715 : continue;
- 1426 : }
- 1427 :
- 1428 : /* if excluded continue to the next one */
- 1429 2952 : if (file_flag_has(file, FILE_IS_EXCLUDED)) {
- 1430 169 : continue;
- 1431 : }
- 1432 :
- 1433 : /* stat the file */
- 1434 2783 : pathprint(path, sizeof(path), "%s%s", disk->dir, file->sub);
- 1435 2783 : ret = stat(path, &st);
- 1436 2783 : if (ret == -1) {
- 1437 165 : unsuccesful = 1;
- 1438 :
- 1439 165 : log_error("Error stating empty file '%s'. %s.\n", path, strerror(errno));
- 1440 165 : log_tag("error:%s:%s: Empty file stat error\n", disk->name, esc_tag(file->sub, esc_buffer));
- 1441 165 : ++error;
- 1442 2618 : } else if (!S_ISREG(st.st_mode)) {
- 1443 0 : unsuccesful = 1;
- 1444 :
- 1445 0 : log_tag("error:%s:%s: Empty file error for not regular file\n", disk->name, esc_tag(file->sub, esc_buffer));
- 1446 0 : ++error;
- 1447 2618 : } else if (st.st_size != 0) {
- 1448 5 : unsuccesful = 1;
- 1449 :
- 1450 5 : log_tag("error:%s:%s: Empty file error for size '%" PRIu64 "'\n", disk->name, esc_tag(file->sub, esc_buffer), st.st_size);
- 1451 5 : ++error;
- 1452 : }
+ 1161 4586482 : assert(block_state == BLOCK_STATE_BLK || block_state == BLOCK_STATE_REP);
+ 1162 :
+ 1163 : /* compute the hash of the block just read */
+ 1164 4586482 : if (rehash) {
+ 1165 27243 : memhash(state->prevhash, state->prevhashseed, hash, buffer[j], read_size);
+ 1166 : } else {
+ 1167 4559239 : memhash(state->hash, state->hashseed, hash, buffer[j], read_size);
+ 1168 : }
+ 1169 :
+ 1170 : /* compare the hash */
+ 1171 4586482 : if (memcmp(hash, block->hash, BLOCK_HASH_SIZE) != 0) {
+ 1172 12866 : unsigned diff = memdiff(hash, block->hash, BLOCK_HASH_SIZE);
+ 1173 :
+ 1174 : /* save the failed block for the check/fix */
+ 1175 12866 : failed[failed_count].is_bad = 1; /* it's bad because the hash doesn't match */
+ 1176 12866 : failed[failed_count].is_outofdate = 0;
+ 1177 12866 : failed[failed_count].index = j;
+ 1178 12866 : failed[failed_count].block = block;
+ 1179 12866 : failed[failed_count].disk = disk;
+ 1180 12866 : failed[failed_count].file = file;
+ 1181 12866 : failed[failed_count].file_pos = file_pos;
+ 1182 12866 : failed[failed_count].handle = &handle[j];
+ 1183 12866 : ++failed_count;
+ 1184 :
+ 1185 12866 : log_tag("error:%u:%s:%s: Data error at position %u, diff bits %u\n", i, disk->name, esc_tag(file->sub, esc_buffer), file_pos, diff);
+ 1186 12866 : ++error;
+ 1187 12866 : continue;
+ 1188 : }
+ 1189 :
+ 1190 : /* always insert REP blocks, the repair functions needs all of them */
+ 1191 : /* because the parity may be still referring at the old state */
+ 1192 : /* and the repair must be aware of it */
+ 1193 4573616 : if (block_state == BLOCK_STATE_REP) {
+ 1194 53428 : failed[failed_count].is_bad = 0; /* it's not bad */
+ 1195 53428 : failed[failed_count].is_outofdate = 0;
+ 1196 53428 : failed[failed_count].index = j;
+ 1197 53428 : failed[failed_count].block = block;
+ 1198 53428 : failed[failed_count].disk = disk;
+ 1199 53428 : failed[failed_count].file = file;
+ 1200 53428 : failed[failed_count].file_pos = file_pos;
+ 1201 53428 : failed[failed_count].handle = &handle[j];
+ 1202 53428 : ++failed_count;
+ 1203 53428 : continue;
+ 1204 : }
+ 1205 : }
+ 1206 :
+ 1207 : /* now read and check the parity if requested */
+ 1208 910233 : if (!state->opt.auditonly) {
+ 1209 : void* buffer_recov[LEV_MAX];
+ 1210 : void* buffer_zero;
+ 1211 :
+ 1212 : /* buffers for parity read and not computed */
+ 1213 4170787 : for (l = 0; l < state->level; ++l)
+ 1214 3299829 : buffer_recov[l] = buffer[diskmax + state->level + l];
+ 1215 2796877 : for (; l < LEV_MAX; ++l)
+ 1216 1925919 : buffer_recov[l] = 0;
+ 1217 :
+ 1218 : /* the zero buffer is the last one */
+ 1219 870958 : buffer_zero = buffer[buffermax - 1];
+ 1220 :
+ 1221 : /* read the parity */
+ 1222 4170787 : for (l = 0; l < state->level; ++l) {
+ 1223 3299829 : if (parity[l]) {
+ 1224 3285927 : ret = parity_read(parity[l], i, buffer_recov[l], state->block_size, log_error);
+ 1225 3285927 : if (ret == -1) {
+ 1226 11360 : buffer_recov[l] = 0; /* no parity to use */
+ 1227 :
+ 1228 11360 : log_tag("parity_error:%u:%s: Read error\n", i, lev_config_name(l));
+ 1229 11360 : ++error;
+ 1230 : }
+ 1231 : } else {
+ 1232 13902 : buffer_recov[l] = 0;
+ 1233 : }
+ 1234 : }
+ 1235 :
+ 1236 : /* try all the recovering strategies */
+ 1237 870958 : ret = repair(state, rehash, i, diskmax, failed, failed_map, failed_count, buffer, buffer_recov, buffer_zero);
+ 1238 870958 : if (ret != 0) {
+ 1239 : /* increment the number of errors */
+ 1240 47948 : if (ret > 0)
+ 1241 4808 : error += ret;
+ 1242 47948 : ++unrecoverable_error;
+ 1243 :
+ 1244 : /* print a list of all the errors in files */
+ 1245 219168 : for (j = 0; j < failed_count; ++j) {
+ 1246 171220 : if (failed[j].is_bad)
+ 1247 166698 : log_tag("unrecoverable:%u:%s:%s: Unrecoverable error at position %u\n", i, failed[j].disk->name, esc_tag(failed[j].file->sub, esc_buffer), failed[j].file_pos);
+ 1248 : }
+ 1249 :
+ 1250 : /* keep track of damaged files */
+ 1251 219168 : for (j = 0; j < failed_count; ++j) {
+ 1252 171220 : if (failed[j].is_bad)
+ 1253 166698 : file_flag_set(failed[j].file, FILE_IS_DAMAGED);
+ 1254 : }
+ 1255 : } else {
+ 1256 : /* now counts partial recovers */
+ 1257 : /* note that this could happen only when we have an incomplete 'sync' */
+ 1258 : /* and that we have recovered is the state before the 'sync' */
+ 1259 823010 : int partial_recover_error = 0;
+ 1260 :
+ 1261 : /* print a list of all the errors in files */
+ 1262 1380911 : for (j = 0; j < failed_count; ++j) {
+ 1263 557901 : if (failed[j].is_bad && failed[j].is_outofdate) {
+ 1264 8 : ++partial_recover_error;
+ 1265 8 : log_tag("unrecoverable:%u:%s:%s: Unrecoverable unsynced error at position %u\n", i, failed[j].disk->name, esc_tag(failed[j].file->sub, esc_buffer), failed[j].file_pos);
+ 1266 : }
+ 1267 : }
+ 1268 823010 : if (partial_recover_error != 0) {
+ 1269 8 : error += partial_recover_error;
+ 1270 8 : ++unrecoverable_error;
+ 1271 : }
+ 1272 :
+ 1273 : /* now check parities, but only if all the blocks have it computed */
+ 1274 : /* if you check/fix after a partial sync, it's OK to have parity errors on the blocks with invalid parity */
+ 1275 : /* and doesn't make sense to try to fix it */
+ 1276 823010 : if (valid_parity) {
+ 1277 : /* check the parity */
+ 1278 3728920 : for (l = 0; l < state->level; ++l) {
+ 1279 2967495 : if (buffer_recov[l] != 0 && memcmp(buffer_recov[l], buffer[diskmax + l], state->block_size) != 0) {
+ 1280 78683 : unsigned diff = memdiff(buffer_recov[l], buffer[diskmax + l], state->block_size);
+ 1281 :
+ 1282 : /* mark that the read parity is wrong, setting ptr to 0 */
+ 1283 78683 : buffer_recov[l] = 0;
+ 1284 :
+ 1285 78683 : log_tag("parity_error:%u:%s: Data error, diff bits %u\n", i, lev_config_name(l), diff);
+ 1286 78683 : ++error;
+ 1287 : }
+ 1288 : }
+ 1289 : }
+ 1290 :
+ 1291 : /* now write recovered files */
+ 1292 823010 : if (fix) {
+ 1293 : /* update the fixed files */
+ 1294 652734 : for (j = 0; j < failed_count; ++j) {
+ 1295 : /* nothing to do if it doesn't need recovering */
+ 1296 338081 : if (!failed[j].is_bad)
+ 1297 40318 : continue;
+ 1298 :
+ 1299 : /* do not fix if the file is excluded */
+ 1300 297763 : if (file_flag_has(failed[j].file, FILE_IS_EXCLUDED)
+ 1301 288483 : || (state->opt.syncedonly && file_flag_has(failed[j].file, FILE_IS_UNSYNCED)))
+ 1302 9280 : continue;
+ 1303 :
+ 1304 288483 : ret = handle_write(failed[j].handle, failed[j].file_pos, buffer[failed[j].index], state->block_size);
+ 1305 288483 : if (ret == -1) {
+ 1306 : /* LCOV_EXCL_START */
+ 1307 : /* mark the file as damaged */
+ 1308 : file_flag_set(failed[j].file, FILE_IS_DAMAGED);
+ 1309 :
+ 1310 : if (errno == EACCES) {
+ 1311 : log_fatal("WARNING! Please give write permission to the file.\n");
+ 1312 : } else {
+ 1313 : /* we do not use DANGER because it could be ENOSPC which is not always correctly reported */
+ 1314 : log_fatal("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n");
+ 1315 : }
+ 1316 : log_fatal("Stopping at block %u\n", i);
+ 1317 : ++unrecoverable_error;
+ 1318 : goto bail;
+ 1319 : /* LCOV_EXCL_STOP */
+ 1320 : }
+ 1321 :
+ 1322 : /* if we are not sure that the recovered content is uptodate */
+ 1323 288483 : if (failed[j].is_outofdate) {
+ 1324 : /* mark the file as damaged */
+ 1325 8 : file_flag_set(failed[j].file, FILE_IS_DAMAGED);
+ 1326 8 : continue;
+ 1327 : }
+ 1328 :
+ 1329 : /* mark the file as containing some fixes */
+ 1330 : /* note that it could be also marked as damaged in other iterations */
+ 1331 288475 : file_flag_set(failed[j].file, FILE_IS_FIXED);
+ 1332 :
+ 1333 288475 : log_tag("fixed:%u:%s:%s: Fixed data error at position %u\n", i, failed[j].disk->name, esc_tag(failed[j].file->sub, esc_buffer), failed[j].file_pos);
+ 1334 288475 : ++recovered_error;
+ 1335 : }
+ 1336 :
+ 1337 : /* update parity only if all the blocks have it computed */
+ 1338 : /* if you check/fix after a partial sync, you do not want to fix parity */
+ 1339 : /* for blocks that are going to have it computed in the sync completion */
+ 1340 314653 : if (valid_parity) {
+ 1341 : /* update the parity */
+ 1342 964031 : for (l = 0; l < state->level; ++l) {
+ 1343 : /* if the parity on disk is wrong */
+ 1344 698558 : if (buffer_recov[l] == 0
+ 1345 : /* and we have access at the parity */
+ 1346 72150 : && parity[l] != 0
+ 1347 : /* and the parity is not excluded */
+ 1348 67463 : && !state->parity[l].is_excluded
+ 1349 : ) {
+ 1350 67463 : ret = parity_write(parity[l], i, buffer[diskmax + l], state->block_size);
+ 1351 67463 : if (ret == -1) {
+ 1352 : /* LCOV_EXCL_START */
+ 1353 : /* we do not use DANGER because it could be ENOSPC which is not always correctly reported */
+ 1354 : log_fatal("WARNING! Without a working %s disk, it isn't possible to fix errors on it.\n", lev_name(l));
+ 1355 : log_fatal("Stopping at block %u\n", i);
+ 1356 : ++unrecoverable_error;
+ 1357 : goto bail;
+ 1358 : /* LCOV_EXCL_STOP */
+ 1359 : }
+ 1360 :
+ 1361 67463 : log_tag("parity_fixed:%u:%s: Fixed data error\n", i, lev_config_name(l));
+ 1362 67463 : ++recovered_error;
+ 1363 : }
+ 1364 : }
+ 1365 : }
+ 1366 : } else {
+ 1367 : /* if we are not fixing, we just set the FIXED flag */
+ 1368 : /* meaning that we could fix this file if we try */
+ 1369 728177 : for (j = 0; j < failed_count; ++j) {
+ 1370 219820 : if (failed[j].is_bad) {
+ 1371 178935 : file_flag_set(failed[j].file, FILE_IS_FIXED);
+ 1372 : }
+ 1373 : }
+ 1374 : }
+ 1375 : }
+ 1376 : } else {
+ 1377 : /* if we are not checking, we just set the DAMAGED flag */
+ 1378 : /* to report that the file is damaged, and we don't know if we can fix it */
+ 1379 45240 : for (j = 0; j < failed_count; ++j) {
+ 1380 5965 : if (failed[j].is_bad) {
+ 1381 5965 : file_flag_set(failed[j].file, FILE_IS_DAMAGED);
+ 1382 : }
+ 1383 : }
+ 1384 : }
+ 1385 :
+ 1386 : /* post process the files */
+ 1387 910233 : ret = file_post(state, fix, i, handle, diskmax);
+ 1388 910233 : if (ret == -1) {
+ 1389 : /* LCOV_EXCL_START */
+ 1390 : log_fatal("Stopping at block %u\n", i);
+ 1391 : ++unrecoverable_error;
+ 1392 : goto bail;
+ 1393 : /* LCOV_EXCL_STOP */
+ 1394 : }
+ 1395 :
+ 1396 : /* count the number of processed block */
+ 1397 910233 : ++countpos;
+ 1398 :
+ 1399 : /* progress */
+ 1400 910233 : if (state_progress(state, 0, i, countpos, countmax, countsize)) {
+ 1401 : /* LCOV_EXCL_START */
+ 1402 : break;
+ 1403 : /* LCOV_EXCL_STOP */
+ 1404 : }
+ 1405 : }
+ 1406 :
+ 1407 : /* for each disk, recover empty files, symlinks and empty dirs */
+ 1408 826 : for (i = 0; i < diskmax; ++i) {
+ 1409 : tommy_node* node;
+ 1410 : struct snapraid_disk* disk;
+ 1411 :
+ 1412 708 : if (!handle[i].disk)
+ 1413 3 : continue;
+ 1414 :
+ 1415 : /* for each empty file in the disk */
+ 1416 705 : disk = handle[i].disk;
+ 1417 705 : node = disk->filelist;
+ 1418 2189135 : while (node) {
+ 1419 : char path[PATH_MAX];
+ 1420 : struct stat st;
+ 1421 : struct snapraid_file* file;
+ 1422 2187725 : int unsuccesful = 0;
+ 1423 :
+ 1424 2187725 : file = node->data;
+ 1425 2187725 : node = node->next; /* next node */
+ 1426 :
+ 1427 : /* if not empty, it's already checked and continue to the next one */
+ 1428 2187725 : if (file->size != 0) {
+ 1429 4369715 : continue;
+ 1430 : }
+ 1431 :
+ 1432 : /* if excluded continue to the next one */
+ 1433 2952 : if (file_flag_has(file, FILE_IS_EXCLUDED)) {
+ 1434 169 : continue;
+ 1435 : }
+ 1436 :
+ 1437 : /* stat the file */
+ 1438 2783 : pathprint(path, sizeof(path), "%s%s", disk->dir, file->sub);
+ 1439 2783 : ret = stat(path, &st);
+ 1440 2783 : if (ret == -1) {
+ 1441 167 : unsuccesful = 1;
+ 1442 :
+ 1443 167 : log_error("Error stating empty file '%s'. %s.\n", path, strerror(errno));
+ 1444 167 : log_tag("error:%s:%s: Empty file stat error\n", disk->name, esc_tag(file->sub, esc_buffer));
+ 1445 167 : ++error;
+ 1446 2616 : } else if (!S_ISREG(st.st_mode)) {
+ 1447 0 : unsuccesful = 1;
+ 1448 :
+ 1449 0 : log_tag("error:%s:%s: Empty file error for not regular file\n", disk->name, esc_tag(file->sub, esc_buffer));
+ 1450 0 : ++error;
+ 1451 2616 : } else if (st.st_size != 0) {
+ 1452 3 : unsuccesful = 1;
1453 :
- 1454 2783 : if (fix && unsuccesful) {
- 1455 : int f;
- 1456 :
- 1457 : /* create the ancestor directories */
- 1458 154 : ret = mkancestor(path);
- 1459 154 : if (ret != 0) {
- 1460 : /* LCOV_EXCL_START */
- 1461 : log_fatal("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n");
- 1462 : log_fatal("Stopping\n");
- 1463 : ++unrecoverable_error;
- 1464 : goto bail;
- 1465 : /* LCOV_EXCL_STOP */
- 1466 : }
- 1467 :
- 1468 : /* create it */
- 1469 : /* O_NOFOLLOW: do not follow links to ensure to open the real file */
- 1470 154 : f = open(path, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_NOFOLLOW, 0600);
- 1471 154 : if (f == -1) {
- 1472 : /* LCOV_EXCL_START */
- 1473 : log_fatal("Error creating empty file '%s'. %s.\n", path, strerror(errno));
- 1474 : if (errno == EACCES) {
- 1475 : log_fatal("WARNING! Please give write permission to the file.\n");
- 1476 : } else {
- 1477 : /* we do not use DANGER because it could be ENOSPC which is not always correctly reported */
- 1478 : log_fatal("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n");
- 1479 : }
- 1480 : log_fatal("Stopping\n");
- 1481 : ++unrecoverable_error;
- 1482 : goto bail;
- 1483 : /* LCOV_EXCL_STOP */
- 1484 : }
- 1485 :
- 1486 : /* set the original modification time */
- 1487 154 : ret = fmtime(f, file->mtime_sec, file->mtime_nsec);
- 1488 154 : if (ret != 0) {
- 1489 : /* LCOV_EXCL_START */
- 1490 : close(f);
- 1491 :
- 1492 : log_fatal("Error timing file '%s'. %s.\n", file->sub, strerror(errno));
- 1493 : log_fatal("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n");
- 1494 : log_fatal("Stopping\n");
- 1495 : ++unrecoverable_error;
- 1496 : goto bail;
- 1497 : /* LCOV_EXCL_STOP */
- 1498 : }
- 1499 :
- 1500 : /* close it */
- 1501 154 : ret = close(f);
- 1502 154 : if (ret != 0) {
- 1503 : /* LCOV_EXCL_START */
- 1504 : log_fatal("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n");
- 1505 : log_fatal("Stopping\n");
- 1506 : ++unrecoverable_error;
- 1507 : goto bail;
- 1508 : /* LCOV_EXCL_STOP */
- 1509 : }
- 1510 :
- 1511 154 : log_tag("fixed:%s:%s: Fixed empty file\n", disk->name, esc_tag(file->sub, esc_buffer));
- 1512 154 : ++recovered_error;
- 1513 :
- 1514 154 : log_tag("status:recovered:%s:%s\n", disk->name, esc_tag(file->sub, esc_buffer));
- 1515 154 : msg_info("recovered %s\n", fmt_term(disk, file->sub, esc_buffer));
- 1516 : }
- 1517 : }
- 1518 :
- 1519 : /* for each link in the disk */
- 1520 705 : disk = handle[i].disk;
- 1521 705 : node = disk->linklist;
- 1522 71537 : while (node) {
- 1523 : char path[PATH_MAX];
- 1524 : char pathto[PATH_MAX];
- 1525 : char linkto[PATH_MAX];
- 1526 : struct stat st;
- 1527 : struct stat stto;
- 1528 : struct snapraid_link* slink;
- 1529 70127 : int unsuccesful = 0;
- 1530 70127 : int unrecoverable = 0;
- 1531 :
- 1532 70127 : slink = node->data;
- 1533 70127 : node = node->next; /* next node */
- 1534 :
- 1535 : /* if excluded continue to the next one */
- 1536 70127 : if (link_flag_has(slink, FILE_IS_EXCLUDED)) {
- 1537 3277 : continue;
- 1538 : }
- 1539 :
- 1540 66850 : if (link_flag_has(slink, FILE_IS_HARDLINK)) {
- 1541 : /* stat the link */
- 1542 318 : pathprint(path, sizeof(path), "%s%s", disk->dir, slink->sub);
- 1543 318 : ret = stat(path, &st);
- 1544 318 : if (ret == -1) {
- 1545 36 : unsuccesful = 1;
- 1546 :
- 1547 36 : log_error("Error stating hardlink '%s'. %s.\n", path, strerror(errno));
- 1548 36 : log_tag("hardlink_error:%s:%s:%s: Hardlink stat error\n", disk->name, esc_tag(slink->sub, esc_buffer), esc_tag(slink->linkto, esc_buffer_alt));
- 1549 36 : ++error;
- 1550 282 : } else if (!S_ISREG(st.st_mode)) {
- 1551 0 : unsuccesful = 1;
- 1552 :
- 1553 0 : log_tag("hardlink_error:%s:%s:%s: Hardlink error for not regular file\n", disk->name, esc_tag(slink->sub, esc_buffer), esc_tag(slink->linkto, esc_buffer_alt));
- 1554 0 : ++error;
- 1555 : }
+ 1454 3 : log_tag("error:%s:%s: Empty file error for size '%" PRIu64 "'\n", disk->name, esc_tag(file->sub, esc_buffer), st.st_size);
+ 1455 3 : ++error;
+ 1456 : }
+ 1457 :
+ 1458 2783 : if (fix && unsuccesful) {
+ 1459 : int f;
+ 1460 :
+ 1461 : /* create the ancestor directories */
+ 1462 154 : ret = mkancestor(path);
+ 1463 154 : if (ret != 0) {
+ 1464 : /* LCOV_EXCL_START */
+ 1465 : log_fatal("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n");
+ 1466 : log_fatal("Stopping\n");
+ 1467 : ++unrecoverable_error;
+ 1468 : goto bail;
+ 1469 : /* LCOV_EXCL_STOP */
+ 1470 : }
+ 1471 :
+ 1472 : /* create it */
+ 1473 : /* O_NOFOLLOW: do not follow links to ensure to open the real file */
+ 1474 154 : f = open(path, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_NOFOLLOW, 0600);
+ 1475 154 : if (f == -1) {
+ 1476 : /* LCOV_EXCL_START */
+ 1477 : log_fatal("Error creating empty file '%s'. %s.\n", path, strerror(errno));
+ 1478 : if (errno == EACCES) {
+ 1479 : log_fatal("WARNING! Please give write permission to the file.\n");
+ 1480 : } else {
+ 1481 : /* we do not use DANGER because it could be ENOSPC which is not always correctly reported */
+ 1482 : log_fatal("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n");
+ 1483 : }
+ 1484 : log_fatal("Stopping\n");
+ 1485 : ++unrecoverable_error;
+ 1486 : goto bail;
+ 1487 : /* LCOV_EXCL_STOP */
+ 1488 : }
+ 1489 :
+ 1490 : /* set the original modification time */
+ 1491 154 : ret = fmtime(f, file->mtime_sec, file->mtime_nsec);
+ 1492 154 : if (ret != 0) {
+ 1493 : /* LCOV_EXCL_START */
+ 1494 : close(f);
+ 1495 :
+ 1496 : log_fatal("Error timing file '%s'. %s.\n", file->sub, strerror(errno));
+ 1497 : log_fatal("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n");
+ 1498 : log_fatal("Stopping\n");
+ 1499 : ++unrecoverable_error;
+ 1500 : goto bail;
+ 1501 : /* LCOV_EXCL_STOP */
+ 1502 : }
+ 1503 :
+ 1504 : /* close it */
+ 1505 154 : ret = close(f);
+ 1506 154 : if (ret != 0) {
+ 1507 : /* LCOV_EXCL_START */
+ 1508 : log_fatal("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n");
+ 1509 : log_fatal("Stopping\n");
+ 1510 : ++unrecoverable_error;
+ 1511 : goto bail;
+ 1512 : /* LCOV_EXCL_STOP */
+ 1513 : }
+ 1514 :
+ 1515 154 : log_tag("fixed:%s:%s: Fixed empty file\n", disk->name, esc_tag(file->sub, esc_buffer));
+ 1516 154 : ++recovered_error;
+ 1517 :
+ 1518 154 : log_tag("status:recovered:%s:%s\n", disk->name, esc_tag(file->sub, esc_buffer));
+ 1519 154 : msg_info("recovered %s\n", fmt_term(disk, file->sub, esc_buffer));
+ 1520 : }
+ 1521 : }
+ 1522 :
+ 1523 : /* for each link in the disk */
+ 1524 705 : disk = handle[i].disk;
+ 1525 705 : node = disk->linklist;
+ 1526 71537 : while (node) {
+ 1527 : char path[PATH_MAX];
+ 1528 : char pathto[PATH_MAX];
+ 1529 : char linkto[PATH_MAX];
+ 1530 : struct stat st;
+ 1531 : struct stat stto;
+ 1532 : struct snapraid_link* slink;
+ 1533 70127 : int unsuccesful = 0;
+ 1534 70127 : int unrecoverable = 0;
+ 1535 :
+ 1536 70127 : slink = node->data;
+ 1537 70127 : node = node->next; /* next node */
+ 1538 :
+ 1539 : /* if excluded continue to the next one */
+ 1540 70127 : if (link_flag_has(slink, FILE_IS_EXCLUDED)) {
+ 1541 3277 : continue;
+ 1542 : }
+ 1543 :
+ 1544 66850 : if (link_flag_has(slink, FILE_IS_HARDLINK)) {
+ 1545 : /* stat the link */
+ 1546 318 : pathprint(path, sizeof(path), "%s%s", disk->dir, slink->sub);
+ 1547 318 : ret = stat(path, &st);
+ 1548 318 : if (ret == -1) {
+ 1549 36 : unsuccesful = 1;
+ 1550 :
+ 1551 36 : log_error("Error stating hardlink '%s'. %s.\n", path, strerror(errno));
+ 1552 36 : log_tag("hardlink_error:%s:%s:%s: Hardlink stat error\n", disk->name, esc_tag(slink->sub, esc_buffer), esc_tag(slink->linkto, esc_buffer_alt));
+ 1553 36 : ++error;
+ 1554 282 : } else if (!S_ISREG(st.st_mode)) {
+ 1555 0 : unsuccesful = 1;
1556 :
- 1557 : /* stat the "to" file */
- 1558 318 : pathprint(pathto, sizeof(pathto), "%s%s", disk->dir, slink->linkto);
- 1559 318 : ret = stat(pathto, &stto);
- 1560 318 : if (ret == -1) {
- 1561 24 : unsuccesful = 1;
- 1562 :
- 1563 24 : if (errno == ENOENT) {
- 1564 24 : unrecoverable = 1;
- 1565 24 : if (fix) {
- 1566 : /* if the target doesn't exist, it's unrecoverable */
- 1567 : /* because we cannot create an hardlink of a file that */
- 1568 : /* doesn't exists */
- 1569 12 : ++unrecoverable_error;
- 1570 : } else {
- 1571 : /* but in check, we can assume that fixing will recover */
- 1572 : /* such missing file, so we assume a less drastic error */
- 1573 12 : ++error;
- 1574 : }
- 1575 : }
- 1576 :
- 1577 24 : log_error("Error stating hardlink-to '%s'. %s.\n", pathto, strerror(errno));
- 1578 24 : log_tag("hardlink_error:%s:%s:%s: Hardlink to stat error\n", disk->name, esc_tag(slink->sub, esc_buffer), esc_tag(slink->linkto, esc_buffer_alt));
- 1579 24 : ++error;
- 1580 294 : } else if (!S_ISREG(stto.st_mode)) {
- 1581 0 : unsuccesful = 1;
- 1582 :
- 1583 0 : log_tag("hardlink_error:%s:%s:%s: Hardlink-to error for not regular file\n", disk->name, esc_tag(slink->sub, esc_buffer), esc_tag(slink->linkto, esc_buffer_alt));
- 1584 0 : ++error;
- 1585 294 : } else if (!unsuccesful && st.st_ino != stto.st_ino) {
- 1586 0 : unsuccesful = 1;
- 1587 :
- 1588 0 : log_error("Mismatch hardlink '%s' and '%s'. Different inode.\n", path, pathto);
- 1589 0 : log_tag("hardlink_error:%s:%s:%s: Hardlink mismatch for different inode\n", disk->name, esc_tag(slink->sub, esc_buffer), esc_tag(slink->linkto, esc_buffer_alt));
- 1590 0 : ++error;
- 1591 : }
- 1592 : } else {
- 1593 : /* read the symlink */
- 1594 66532 : pathprint(path, sizeof(path), "%s%s", disk->dir, slink->sub);
- 1595 66532 : ret = readlink(path, linkto, sizeof(linkto));
- 1596 66532 : if (ret < 0) {
- 1597 4292 : unsuccesful = 1;
- 1598 :
- 1599 4292 : log_error("Error reading symlink '%s'. %s.\n", path, strerror(errno));
- 1600 4292 : log_tag("symlink_error:%s:%s: Symlink read error\n", disk->name, esc_tag(slink->sub, esc_buffer));
- 1601 4292 : ++error;
- 1602 62240 : } else if (ret >= PATH_MAX) {
- 1603 0 : unsuccesful = 1;
- 1604 :
- 1605 0 : log_error("Error reading symlink '%s'. Symlink too long.\n", path);
- 1606 0 : log_tag("symlink_error:%s:%s: Symlink read error\n", disk->name, esc_tag(slink->sub, esc_buffer));
- 1607 0 : ++error;
- 1608 : } else {
- 1609 62240 : linkto[ret] = 0;
- 1610 :
- 1611 62240 : if (strcmp(linkto, slink->linkto) != 0) {
- 1612 544 : unsuccesful = 1;
- 1613 :
- 1614 544 : log_tag("symlink_error:%s:%s: Symlink data error '%s' instead of '%s'\n", disk->name, esc_tag(slink->sub, esc_buffer), linkto, slink->linkto);
- 1615 544 : ++error;
- 1616 : }
- 1617 : }
- 1618 : }
- 1619 :
- 1620 66850 : if (fix && unsuccesful && !unrecoverable) {
- 1621 : /* create the ancestor directories */
- 1622 3942 : ret = mkancestor(path);
- 1623 3942 : if (ret != 0) {
- 1624 : /* LCOV_EXCL_START */
- 1625 : log_fatal("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n");
- 1626 : log_fatal("Stopping\n");
- 1627 : ++unrecoverable_error;
- 1628 : goto bail;
- 1629 : /* LCOV_EXCL_STOP */
- 1630 : }
- 1631 :
- 1632 : /* if it exists, it must be deleted before recreating */
- 1633 3942 : ret = remove(path);
- 1634 3942 : if (ret != 0 && errno != ENOENT) {
- 1635 : /* LCOV_EXCL_START */
- 1636 : log_fatal("Error removing '%s'. %s.\n", path, strerror(errno));
- 1637 : log_fatal("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n");
- 1638 : log_fatal("Stopping\n");
- 1639 : ++unrecoverable_error;
- 1640 : goto bail;
- 1641 : /* LCOV_EXCL_STOP */
- 1642 : }
- 1643 :
- 1644 : /* create it */
- 1645 3942 : if (link_flag_has(slink, FILE_IS_HARDLINK)) {
- 1646 12 : ret = hardlink(pathto, path);
- 1647 12 : if (ret != 0) {
- 1648 : /* LCOV_EXCL_START */
- 1649 : log_fatal("Error writing hardlink '%s' to '%s'. %s.\n", path, pathto, strerror(errno));
- 1650 : if (errno == EACCES) {
- 1651 : log_fatal("WARNING! Please give write permission to the hardlink.\n");
- 1652 : } else {
- 1653 : /* we do not use DANGER because it could be ENOSPC which is not always correctly reported */
- 1654 : log_fatal("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n");
- 1655 : }
- 1656 : log_fatal("Stopping\n");
- 1657 : ++unrecoverable_error;
- 1658 : goto bail;
- 1659 : /* LCOV_EXCL_STOP */
- 1660 : }
- 1661 :
- 1662 12 : log_tag("hardlink_fixed:%s:%s: Fixed hardlink error\n", disk->name, esc_tag(slink->sub, esc_buffer));
- 1663 12 : ++recovered_error;
- 1664 : } else {
- 1665 3930 : ret = symlink(slink->linkto, path);
- 1666 3930 : if (ret != 0) {
- 1667 : /* LCOV_EXCL_START */
- 1668 : log_fatal("Error writing symlink '%s' to '%s'. %s.\n", path, slink->linkto, strerror(errno));
- 1669 : if (errno == EACCES) {
- 1670 : log_fatal("WARNING! Please give write permission to the symlink.\n");
- 1671 : } else {
- 1672 : /* we do not use DANGER because it could be ENOSPC which is not always correctly reported */
- 1673 : log_fatal("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n");
- 1674 : }
- 1675 : log_fatal("Stopping\n");
- 1676 : ++unrecoverable_error;
- 1677 : goto bail;
- 1678 : /* LCOV_EXCL_STOP */
- 1679 : }
- 1680 :
- 1681 3930 : log_tag("symlink_fixed:%s:%s: Fixed symlink error\n", disk->name, esc_tag(slink->sub, esc_buffer));
- 1682 3930 : ++recovered_error;
- 1683 : }
+ 1557 0 : log_tag("hardlink_error:%s:%s:%s: Hardlink error for not regular file\n", disk->name, esc_tag(slink->sub, esc_buffer), esc_tag(slink->linkto, esc_buffer_alt));
+ 1558 0 : ++error;
+ 1559 : }
+ 1560 :
+ 1561 : /* stat the "to" file */
+ 1562 318 : pathprint(pathto, sizeof(pathto), "%s%s", disk->dir, slink->linkto);
+ 1563 318 : ret = stat(pathto, &stto);
+ 1564 318 : if (ret == -1) {
+ 1565 24 : unsuccesful = 1;
+ 1566 :
+ 1567 24 : if (errno == ENOENT) {
+ 1568 24 : unrecoverable = 1;
+ 1569 24 : if (fix) {
+ 1570 : /* if the target doesn't exist, it's unrecoverable */
+ 1571 : /* because we cannot create an hardlink of a file that */
+ 1572 : /* doesn't exists */
+ 1573 12 : ++unrecoverable_error;
+ 1574 : } else {
+ 1575 : /* but in check, we can assume that fixing will recover */
+ 1576 : /* such missing file, so we assume a less drastic error */
+ 1577 12 : ++error;
+ 1578 : }
+ 1579 : }
+ 1580 :
+ 1581 24 : log_error("Error stating hardlink-to '%s'. %s.\n", pathto, strerror(errno));
+ 1582 24 : log_tag("hardlink_error:%s:%s:%s: Hardlink to stat error\n", disk->name, esc_tag(slink->sub, esc_buffer), esc_tag(slink->linkto, esc_buffer_alt));
+ 1583 24 : ++error;
+ 1584 294 : } else if (!S_ISREG(stto.st_mode)) {
+ 1585 0 : unsuccesful = 1;
+ 1586 :
+ 1587 0 : log_tag("hardlink_error:%s:%s:%s: Hardlink-to error for not regular file\n", disk->name, esc_tag(slink->sub, esc_buffer), esc_tag(slink->linkto, esc_buffer_alt));
+ 1588 0 : ++error;
+ 1589 294 : } else if (!unsuccesful && st.st_ino != stto.st_ino) {
+ 1590 0 : unsuccesful = 1;
+ 1591 :
+ 1592 0 : log_error("Mismatch hardlink '%s' and '%s'. Different inode.\n", path, pathto);
+ 1593 0 : log_tag("hardlink_error:%s:%s:%s: Hardlink mismatch for different inode\n", disk->name, esc_tag(slink->sub, esc_buffer), esc_tag(slink->linkto, esc_buffer_alt));
+ 1594 0 : ++error;
+ 1595 : }
+ 1596 : } else {
+ 1597 : /* read the symlink */
+ 1598 66532 : pathprint(path, sizeof(path), "%s%s", disk->dir, slink->sub);
+ 1599 66532 : ret = readlink(path, linkto, sizeof(linkto));
+ 1600 66532 : if (ret < 0) {
+ 1601 4267 : unsuccesful = 1;
+ 1602 :
+ 1603 4267 : log_error("Error reading symlink '%s'. %s.\n", path, strerror(errno));
+ 1604 4267 : log_tag("symlink_error:%s:%s: Symlink read error\n", disk->name, esc_tag(slink->sub, esc_buffer));
+ 1605 4267 : ++error;
+ 1606 62265 : } else if (ret >= PATH_MAX) {
+ 1607 0 : unsuccesful = 1;
+ 1608 :
+ 1609 0 : log_error("Error reading symlink '%s'. Symlink too long.\n", path);
+ 1610 0 : log_tag("symlink_error:%s:%s: Symlink read error\n", disk->name, esc_tag(slink->sub, esc_buffer));
+ 1611 0 : ++error;
+ 1612 : } else {
+ 1613 62265 : linkto[ret] = 0;
+ 1614 :
+ 1615 62265 : if (strcmp(linkto, slink->linkto) != 0) {
+ 1616 566 : unsuccesful = 1;
+ 1617 :
+ 1618 566 : log_tag("symlink_error:%s:%s: Symlink data error '%s' instead of '%s'\n", disk->name, esc_tag(slink->sub, esc_buffer), linkto, slink->linkto);
+ 1619 566 : ++error;
+ 1620 : }
+ 1621 : }
+ 1622 : }
+ 1623 :
+ 1624 66850 : if (fix && unsuccesful && !unrecoverable) {
+ 1625 : /* create the ancestor directories */
+ 1626 3941 : ret = mkancestor(path);
+ 1627 3941 : if (ret != 0) {
+ 1628 : /* LCOV_EXCL_START */
+ 1629 : log_fatal("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n");
+ 1630 : log_fatal("Stopping\n");
+ 1631 : ++unrecoverable_error;
+ 1632 : goto bail;
+ 1633 : /* LCOV_EXCL_STOP */
+ 1634 : }
+ 1635 :
+ 1636 : /* if it exists, it must be deleted before recreating */
+ 1637 3941 : ret = remove(path);
+ 1638 3941 : if (ret != 0 && errno != ENOENT) {
+ 1639 : /* LCOV_EXCL_START */
+ 1640 : log_fatal("Error removing '%s'. %s.\n", path, strerror(errno));
+ 1641 : log_fatal("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n");
+ 1642 : log_fatal("Stopping\n");
+ 1643 : ++unrecoverable_error;
+ 1644 : goto bail;
+ 1645 : /* LCOV_EXCL_STOP */
+ 1646 : }
+ 1647 :
+ 1648 : /* create it */
+ 1649 3941 : if (link_flag_has(slink, FILE_IS_HARDLINK)) {
+ 1650 12 : ret = hardlink(pathto, path);
+ 1651 12 : if (ret != 0) {
+ 1652 : /* LCOV_EXCL_START */
+ 1653 : log_fatal("Error writing hardlink '%s' to '%s'. %s.\n", path, pathto, strerror(errno));
+ 1654 : if (errno == EACCES) {
+ 1655 : log_fatal("WARNING! Please give write permission to the hardlink.\n");
+ 1656 : } else {
+ 1657 : /* we do not use DANGER because it could be ENOSPC which is not always correctly reported */
+ 1658 : log_fatal("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n");
+ 1659 : }
+ 1660 : log_fatal("Stopping\n");
+ 1661 : ++unrecoverable_error;
+ 1662 : goto bail;
+ 1663 : /* LCOV_EXCL_STOP */
+ 1664 : }
+ 1665 :
+ 1666 12 : log_tag("hardlink_fixed:%s:%s: Fixed hardlink error\n", disk->name, esc_tag(slink->sub, esc_buffer));
+ 1667 12 : ++recovered_error;
+ 1668 : } else {
+ 1669 3929 : ret = symlink(slink->linkto, path);
+ 1670 3929 : if (ret != 0) {
+ 1671 : /* LCOV_EXCL_START */
+ 1672 : log_fatal("Error writing symlink '%s' to '%s'. %s.\n", path, slink->linkto, strerror(errno));
+ 1673 : if (errno == EACCES) {
+ 1674 : log_fatal("WARNING! Please give write permission to the symlink.\n");
+ 1675 : } else {
+ 1676 : /* we do not use DANGER because it could be ENOSPC which is not always correctly reported */
+ 1677 : log_fatal("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n");
+ 1678 : }
+ 1679 : log_fatal("Stopping\n");
+ 1680 : ++unrecoverable_error;
+ 1681 : goto bail;
+ 1682 : /* LCOV_EXCL_STOP */
+ 1683 : }
1684 :
- 1685 3942 : log_tag("status:recovered:%s:%s\n", disk->name, esc_tag(slink->sub, esc_buffer));
- 1686 3942 : msg_info("recovered %s\n", fmt_term(disk, slink->sub, esc_buffer));
- 1687 : }
- 1688 : }
- 1689 :
- 1690 : /* for each dir in the disk */
- 1691 705 : disk = handle[i].disk;
- 1692 705 : node = disk->dirlist;
- 1693 1850 : while (node) {
- 1694 : char path[PATH_MAX];
- 1695 : struct stat st;
- 1696 : struct snapraid_dir* dir;
- 1697 440 : int unsuccesful = 0;
- 1698 :
- 1699 440 : dir = node->data;
- 1700 440 : node = node->next; /* next node */
- 1701 :
- 1702 : /* if excluded continue to the next one */
- 1703 440 : if (dir_flag_has(dir, FILE_IS_EXCLUDED)) {
- 1704 19 : continue;
- 1705 : }
- 1706 :
- 1707 : /* stat the dir */
- 1708 421 : pathprint(path, sizeof(path), "%s%s", disk->dir, dir->sub);
- 1709 421 : ret = stat(path, &st);
- 1710 421 : if (ret == -1) {
- 1711 23 : unsuccesful = 1;
- 1712 :
- 1713 23 : log_error("Error stating dir '%s'. %s.\n", path, strerror(errno));
- 1714 23 : log_tag("dir_error:%s:%s: Dir stat error\n", disk->name, esc_tag(dir->sub, esc_buffer));
- 1715 23 : ++error;
- 1716 398 : } else if (!S_ISDIR(st.st_mode)) {
- 1717 0 : unsuccesful = 1;
- 1718 :
- 1719 0 : log_tag("dir_error:%s:%s: Dir error for not directory\n", disk->name, esc_tag(dir->sub, esc_buffer));
- 1720 0 : ++error;
- 1721 : }
+ 1685 3929 : log_tag("symlink_fixed:%s:%s: Fixed symlink error\n", disk->name, esc_tag(slink->sub, esc_buffer));
+ 1686 3929 : ++recovered_error;
+ 1687 : }
+ 1688 :
+ 1689 3941 : log_tag("status:recovered:%s:%s\n", disk->name, esc_tag(slink->sub, esc_buffer));
+ 1690 3941 : msg_info("recovered %s\n", fmt_term(disk, slink->sub, esc_buffer));
+ 1691 : }
+ 1692 : }
+ 1693 :
+ 1694 : /* for each dir in the disk */
+ 1695 705 : disk = handle[i].disk;
+ 1696 705 : node = disk->dirlist;
+ 1697 1850 : while (node) {
+ 1698 : char path[PATH_MAX];
+ 1699 : struct stat st;
+ 1700 : struct snapraid_dir* dir;
+ 1701 440 : int unsuccesful = 0;
+ 1702 :
+ 1703 440 : dir = node->data;
+ 1704 440 : node = node->next; /* next node */
+ 1705 :
+ 1706 : /* if excluded continue to the next one */
+ 1707 440 : if (dir_flag_has(dir, FILE_IS_EXCLUDED)) {
+ 1708 19 : continue;
+ 1709 : }
+ 1710 :
+ 1711 : /* stat the dir */
+ 1712 421 : pathprint(path, sizeof(path), "%s%s", disk->dir, dir->sub);
+ 1713 421 : ret = stat(path, &st);
+ 1714 421 : if (ret == -1) {
+ 1715 23 : unsuccesful = 1;
+ 1716 :
+ 1717 23 : log_error("Error stating dir '%s'. %s.\n", path, strerror(errno));
+ 1718 23 : log_tag("dir_error:%s:%s: Dir stat error\n", disk->name, esc_tag(dir->sub, esc_buffer));
+ 1719 23 : ++error;
+ 1720 398 : } else if (!S_ISDIR(st.st_mode)) {
+ 1721 0 : unsuccesful = 1;
1722 :
- 1723 421 : if (fix && unsuccesful) {
- 1724 : /* create the ancestor directories */
- 1725 21 : ret = mkancestor(path);
- 1726 21 : if (ret != 0) {
- 1727 : /* LCOV_EXCL_START */
- 1728 : log_fatal("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n");
- 1729 : log_fatal("Stopping\n");
- 1730 : ++unrecoverable_error;
- 1731 : goto bail;
- 1732 : /* LCOV_EXCL_STOP */
- 1733 : }
- 1734 :
- 1735 : /* create it */
- 1736 21 : ret = mkdir(path, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
- 1737 21 : if (ret != 0) {
- 1738 : /* LCOV_EXCL_START */
- 1739 : log_fatal("Error creating dir '%s'. %s.\n", path, strerror(errno));
- 1740 : if (errno == EACCES) {
- 1741 : log_fatal("WARNING! Please give write permission to the dir.\n");
- 1742 : } else {
- 1743 : /* we do not use DANGER because it could be ENOSPC which is not always correctly reported */
- 1744 : log_fatal("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n");
- 1745 : }
- 1746 : log_fatal("Stopping\n");
- 1747 : ++unrecoverable_error;
- 1748 : goto bail;
- 1749 : /* LCOV_EXCL_STOP */
- 1750 : }
- 1751 :
- 1752 21 : log_tag("dir_fixed:%s:%s: Fixed dir error\n", disk->name, esc_tag(dir->sub, esc_buffer));
- 1753 21 : ++recovered_error;
- 1754 :
- 1755 21 : log_tag("status:recovered:%s:%s\n", disk->name, esc_tag(dir->sub, esc_buffer));
- 1756 21 : msg_info("recovered %s\n", fmt_term(disk, dir->sub, esc_buffer));
- 1757 : }
- 1758 : }
- 1759 : }
- 1760 :
- 1761 118 : state_progress_end(state, countpos, countmax, countsize);
- 1762 :
- 1763 : bail:
- 1764 : /* close all the files left open */
- 1765 826 : for (j = 0; j < diskmax; ++j) {
- 1766 708 : struct snapraid_file* file = handle[j].file;
- 1767 708 : struct snapraid_disk* disk = handle[j].disk;
- 1768 708 : ret = handle_close(&handle[j]);
- 1769 708 : if (ret == -1) {
- 1770 : /* LCOV_EXCL_START */
- 1771 : log_tag("error:%u:%s:%s: Close error. %s\n", blockmax, disk->name, esc_tag(file->sub, esc_buffer), strerror(errno));
- 1772 : log_fatal("DANGER! Unexpected close error in a data disk.\n");
- 1773 : ++unrecoverable_error;
- 1774 : /* continue, as we are already exiting */
- 1775 : /* LCOV_EXCL_STOP */
- 1776 : }
- 1777 : }
- 1778 :
- 1779 : /* remove all the files created from scratch that have not finished the processing */
- 1780 : /* it happens only when aborting pressing Ctrl+C or other reason. */
- 1781 118 : if (fix) {
- 1782 : /* for each disk */
- 1783 315 : for (i = 0; i < diskmax; ++i) {
- 1784 : tommy_node* node;
- 1785 : struct snapraid_disk* disk;
- 1786 :
- 1787 270 : if (!handle[i].disk)
- 1788 1 : continue;
- 1789 :
- 1790 : /* for each file in the disk */
- 1791 269 : disk = handle[i].disk;
- 1792 269 : node = disk->filelist;
- 1793 870849 : while (node) {
- 1794 : char path[PATH_MAX];
- 1795 : struct snapraid_file* file;
- 1796 :
- 1797 870311 : file = node->data;
- 1798 870311 : node = node->next; /* next node */
- 1799 :
- 1800 : /* if the file was not created, meaning that it was already existing */
- 1801 870311 : if (!file_flag_has(file, FILE_IS_CREATED)) {
- 1802 : /* nothing to do */
- 1803 1627487 : continue;
- 1804 : }
- 1805 :
- 1806 : /* if processing was finished */
- 1807 113135 : if (file_flag_has(file, FILE_IS_FINISHED)) {
- 1808 : /* nothing to do */
- 1809 113135 : continue;
- 1810 : }
- 1811 :
- 1812 : /* if the file was originally missing, and processing not yet finished */
- 1813 : /* we have to throw it away to ensure that at the next run we will retry */
- 1814 : /* to fix it, in case we select to undelete missing files */
- 1815 0 : pathprint(path, sizeof(path), "%s%s", disk->dir, file->sub);
- 1816 :
- 1817 0 : ret = remove(path);
- 1818 0 : if (ret != 0) {
- 1819 : /* LCOV_EXCL_START */
- 1820 : log_fatal("Error removing '%s'. %s.\n", path, strerror(errno));
- 1821 : log_fatal("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n");
- 1822 : ++unrecoverable_error;
- 1823 : /* continue, as we are already exiting */
- 1824 : /* LCOV_EXCL_STOP */
- 1825 : }
- 1826 : }
- 1827 : }
- 1828 : }
- 1829 :
- 1830 118 : if (error || recovered_error || unrecoverable_error) {
- 1831 67 : msg_status("\n");
- 1832 67 : msg_status("%8u errors\n", error);
- 1833 67 : if (fix) {
- 1834 43 : msg_status("%8u recovered errors\n", recovered_error);
- 1835 : }
- 1836 134 : if (unrecoverable_error) {
- 1837 13 : msg_status("%8u UNRECOVERABLE errors\n", unrecoverable_error);
- 1838 : } else {
- 1839 : /* without checking, we don't know if they are really recoverable or not */
- 1840 54 : if (!state->opt.auditonly)
- 1841 52 : msg_status("%8u unrecoverable errors\n", unrecoverable_error);
- 1842 54 : if (fix)
- 1843 34 : msg_status("Everything OK\n");
- 1844 : }
- 1845 : } else {
- 1846 51 : msg_status("Everything OK\n");
- 1847 : }
- 1848 :
- 1849 118 : if (error && !fix)
- 1850 24 : log_fatal("WARNING! There are errors!\n");
- 1851 118 : if (unrecoverable_error)
- 1852 13 : log_fatal("DANGER! There are unrecoverable errors!\n");
- 1853 :
- 1854 118 : log_tag("summary:error:%u\n", error);
- 1855 118 : if (fix)
- 1856 45 : log_tag("summary:error_recovered:%u\n", recovered_error);
- 1857 118 : if (!state->opt.auditonly)
- 1858 113 : log_tag("summary:error_unrecoverable:%u\n", unrecoverable_error);
- 1859 118 : if (fix) {
- 1860 45 : if (error + recovered_error + unrecoverable_error == 0)
- 1861 2 : log_tag("summary:exit:ok\n");
- 1862 43 : else if (unrecoverable_error == 0)
- 1863 34 : log_tag("summary:exit:recovered\n");
- 1864 : else
- 1865 9 : log_tag("summary:exit:unrecoverable\n");
- 1866 73 : } else if (!state->opt.auditonly) {
- 1867 68 : if (error + unrecoverable_error == 0)
- 1868 46 : log_tag("summary:exit:ok\n");
- 1869 22 : else if (unrecoverable_error == 0)
- 1870 18 : log_tag("summary:exit:recoverable\n");
- 1871 : else
- 1872 4 : log_tag("summary:exit:unrecoverable\n");
- 1873 : } else { /* audit only */
- 1874 5 : if (error == 0)
- 1875 3 : log_tag("summary:exit:ok\n");
- 1876 : else
- 1877 2 : log_tag("summary:exit:error\n");
- 1878 : }
- 1879 118 : log_flush();
- 1880 :
- 1881 118 : free(failed);
- 1882 118 : free(failed_map);
- 1883 118 : free(handle);
- 1884 118 : free(buffer_alloc);
- 1885 118 : free(buffer);
- 1886 :
- 1887 : /* fail if some error are present after the run */
- 1888 118 : if (fix) {
- 1889 45 : if (state->opt.expect_unrecoverable) {
- 1890 9 : if (unrecoverable_error == 0)
- 1891 0 : return -1;
- 1892 : } else {
- 1893 36 : if (unrecoverable_error != 0)
- 1894 0 : return -1;
- 1895 : }
- 1896 : } else {
- 1897 73 : if (state->opt.expect_unrecoverable) {
- 1898 4 : if (unrecoverable_error == 0)
- 1899 0 : return -1;
- 1900 69 : } else if (state->opt.expect_recoverable) {
- 1901 20 : if (unrecoverable_error != 0 || error == 0)
- 1902 0 : return -1;
- 1903 : } else {
- 1904 49 : if (error != 0 || unrecoverable_error != 0)
- 1905 0 : return -1;
- 1906 : }
- 1907 : }
- 1908 :
- 1909 118 : return 0;
- 1910 : }
- 1911 :
- 1912 120 : int state_check(struct snapraid_state* state, int fix, block_off_t blockstart, block_off_t blockcount)
- 1913 : {
- 1914 : block_off_t blockmax;
- 1915 : data_off_t size;
- 1916 : int ret;
- 1917 : struct snapraid_parity_handle parity[LEV_MAX];
- 1918 : struct snapraid_parity_handle* parity_ptr[LEV_MAX];
- 1919 : unsigned error;
- 1920 : unsigned l;
- 1921 :
- 1922 120 : msg_progress("Initializing...\n");
- 1923 :
- 1924 120 : blockmax = parity_allocated_size(state);
- 1925 120 : size = blockmax * (data_off_t)state->block_size;
- 1926 :
- 1927 120 : if (blockstart > blockmax) {
- 1928 : /* LCOV_EXCL_START */
- 1929 : log_fatal("Error in the specified starting block %u. It's bigger than the parity size %u.\n", blockstart, blockmax);
- 1930 : exit(EXIT_FAILURE);
- 1931 : /* LCOV_EXCL_STOP */
- 1932 : }
- 1933 :
- 1934 : /* adjust the number of block to process */
- 1935 120 : if (blockcount != 0 && blockstart + blockcount < blockmax) {
- 1936 0 : blockmax = blockstart + blockcount;
- 1937 : }
- 1938 :
- 1939 120 : if (fix) {
- 1940 : /* if fixing, create the file and open for writing */
- 1941 : /* if it fails, we cannot continue */
- 1942 180 : for (l = 0; l < state->level; ++l) {
- 1943 : /* skip parity disks that are not accessible */
- 1944 135 : if (state->parity[l].skip_access) {
- 1945 1 : parity_ptr[l] = 0;
- 1946 1 : continue;
- 1947 : }
- 1948 :
- 1949 134 : parity_ptr[l] = &parity[l];
- 1950 134 : ret = parity_create(parity_ptr[l], &state->parity[l], l, state->file_mode, state->block_size, state->opt.parity_limit_size);
- 1951 134 : if (ret == -1) {
- 1952 : /* LCOV_EXCL_START */
- 1953 : log_fatal("WARNING! Without an accessible %s file, it isn't possible to fix any error.\n", lev_name(l));
- 1954 : exit(EXIT_FAILURE);
- 1955 : /* LCOV_EXCL_STOP */
- 1956 : }
- 1957 :
- 1958 134 : ret = parity_chsize(parity_ptr[l], &state->parity[l], 0, size, state->block_size, state->opt.skip_fallocate, state->opt.skip_space_holder);
- 1959 134 : if (ret == -1) {
- 1960 : /* LCOV_EXCL_START */
- 1961 : log_fatal("WARNING! Without an accessible %s file, it isn't possible to sync.\n", lev_name(l));
- 1962 : exit(EXIT_FAILURE);
- 1963 : /* LCOV_EXCL_STOP */
- 1964 : }
- 1965 : }
- 1966 75 : } else if (!state->opt.auditonly) {
- 1967 : /* if checking, open the file for reading */
- 1968 : /* it may fail if the file doesn't exist, in this case we continue to check the files */
- 1969 393 : for (l = 0; l < state->level; ++l) {
- 1970 324 : parity_ptr[l] = &parity[l];
- 1971 324 : ret = parity_open(parity_ptr[l], &state->parity[l], l, state->file_mode, state->block_size, state->opt.parity_limit_size);
- 1972 324 : if (ret == -1) {
- 1973 1 : msg_status("No accessible %s file, only files will be checked.\n", lev_name(l));
- 1974 : /* continue anyway */
- 1975 1 : parity_ptr[l] = 0;
- 1976 : }
- 1977 : }
- 1978 : } else {
- 1979 : /* otherwise don't use any parity */
- 1980 28 : for (l = 0; l < state->level; ++l)
- 1981 22 : parity_ptr[l] = 0;
- 1982 : }
- 1983 :
- 1984 120 : if (fix)
- 1985 45 : msg_progress("Fixing...\n");
- 1986 75 : else if (!state->opt.auditonly)
- 1987 69 : msg_progress("Checking...\n");
- 1988 : else
- 1989 6 : msg_progress("Hashing...\n");
- 1990 :
- 1991 120 : error = 0;
- 1992 :
- 1993 : /* skip degenerated cases of empty parity, or skipping all */
- 1994 120 : if (blockstart < blockmax) {
- 1995 118 : ret = state_check_process(state, fix, parity_ptr, blockstart, blockmax);
- 1996 118 : if (ret == -1) {
- 1997 : /* LCOV_EXCL_START */
- 1998 : ++error;
- 1999 : /* continue, as we are already exiting */
- 2000 : /* LCOV_EXCL_STOP */
- 2001 : }
- 2002 : }
- 2003 :
- 2004 : /* try to close only if opened */
- 2005 601 : for (l = 0; l < state->level; ++l) {
- 2006 481 : if (parity_ptr[l]) {
- 2007 457 : ret = parity_close(parity_ptr[l]);
- 2008 : /* LCOV_EXCL_START */
- 2009 : if (ret == -1) {
- 2010 : log_fatal("DANGER! Unexpected close error in %s disk.\n", lev_name(l));
- 2011 : ++error;
- 2012 : /* continue, as we are already exiting */
- 2013 : }
- 2014 : /* LCOV_EXCL_STOP */
- 2015 : }
- 2016 : }
- 2017 :
- 2018 : /* abort if error are present */
- 2019 120 : if (error != 0)
- 2020 0 : return -1;
- 2021 120 : return 0;
- 2022 : }
- 2023 :
+ 1723 0 : log_tag("dir_error:%s:%s: Dir error for not directory\n", disk->name, esc_tag(dir->sub, esc_buffer));
+ 1724 0 : ++error;
+ 1725 : }
+ 1726 :
+ 1727 421 : if (fix && unsuccesful) {
+ 1728 : /* create the ancestor directories */
+ 1729 21 : ret = mkancestor(path);
+ 1730 21 : if (ret != 0) {
+ 1731 : /* LCOV_EXCL_START */
+ 1732 : log_fatal("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n");
+ 1733 : log_fatal("Stopping\n");
+ 1734 : ++unrecoverable_error;
+ 1735 : goto bail;
+ 1736 : /* LCOV_EXCL_STOP */
+ 1737 : }
+ 1738 :
+ 1739 : /* create it */
+ 1740 21 : ret = mkdir(path, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
+ 1741 21 : if (ret != 0) {
+ 1742 : /* LCOV_EXCL_START */
+ 1743 : log_fatal("Error creating dir '%s'. %s.\n", path, strerror(errno));
+ 1744 : if (errno == EACCES) {
+ 1745 : log_fatal("WARNING! Please give write permission to the dir.\n");
+ 1746 : } else {
+ 1747 : /* we do not use DANGER because it could be ENOSPC which is not always correctly reported */
+ 1748 : log_fatal("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n");
+ 1749 : }
+ 1750 : log_fatal("Stopping\n");
+ 1751 : ++unrecoverable_error;
+ 1752 : goto bail;
+ 1753 : /* LCOV_EXCL_STOP */
+ 1754 : }
+ 1755 :
+ 1756 21 : log_tag("dir_fixed:%s:%s: Fixed dir error\n", disk->name, esc_tag(dir->sub, esc_buffer));
+ 1757 21 : ++recovered_error;
+ 1758 :
+ 1759 21 : log_tag("status:recovered:%s:%s\n", disk->name, esc_tag(dir->sub, esc_buffer));
+ 1760 21 : msg_info("recovered %s\n", fmt_term(disk, dir->sub, esc_buffer));
+ 1761 : }
+ 1762 : }
+ 1763 : }
+ 1764 :
+ 1765 118 : state_progress_end(state, countpos, countmax, countsize);
+ 1766 :
+ 1767 : bail:
+ 1768 : /* close all the files left open */
+ 1769 826 : for (j = 0; j < diskmax; ++j) {
+ 1770 708 : struct snapraid_file* file = handle[j].file;
+ 1771 708 : struct snapraid_disk* disk = handle[j].disk;
+ 1772 708 : ret = handle_close(&handle[j]);
+ 1773 708 : if (ret == -1) {
+ 1774 : /* LCOV_EXCL_START */
+ 1775 : log_tag("error:%u:%s:%s: Close error. %s\n", blockmax, disk->name, esc_tag(file->sub, esc_buffer), strerror(errno));
+ 1776 : log_fatal("DANGER! Unexpected close error in a data disk.\n");
+ 1777 : ++unrecoverable_error;
+ 1778 : /* continue, as we are already exiting */
+ 1779 : /* LCOV_EXCL_STOP */
+ 1780 : }
+ 1781 : }
+ 1782 :
+ 1783 : /* remove all the files created from scratch that have not finished the processing */
+ 1784 : /* it happens only when aborting pressing Ctrl+C or other reason. */
+ 1785 118 : if (fix) {
+ 1786 : /* for each disk */
+ 1787 315 : for (i = 0; i < diskmax; ++i) {
+ 1788 : tommy_node* node;
+ 1789 : struct snapraid_disk* disk;
+ 1790 :
+ 1791 270 : if (!handle[i].disk)
+ 1792 1 : continue;
+ 1793 :
+ 1794 : /* for each file in the disk */
+ 1795 269 : disk = handle[i].disk;
+ 1796 269 : node = disk->filelist;
+ 1797 870849 : while (node) {
+ 1798 : char path[PATH_MAX];
+ 1799 : struct snapraid_file* file;
+ 1800 :
+ 1801 870311 : file = node->data;
+ 1802 870311 : node = node->next; /* next node */
+ 1803 :
+ 1804 : /* if the file was not created, meaning that it was already existing */
+ 1805 870311 : if (!file_flag_has(file, FILE_IS_CREATED)) {
+ 1806 : /* nothing to do */
+ 1807 1627555 : continue;
+ 1808 : }
+ 1809 :
+ 1810 : /* if processing was finished */
+ 1811 113067 : if (file_flag_has(file, FILE_IS_FINISHED)) {
+ 1812 : /* nothing to do */
+ 1813 113067 : continue;
+ 1814 : }
+ 1815 :
+ 1816 : /* if the file was originally missing, and processing not yet finished */
+ 1817 : /* we have to throw it away to ensure that at the next run we will retry */
+ 1818 : /* to fix it, in case we select to undelete missing files */
+ 1819 0 : pathprint(path, sizeof(path), "%s%s", disk->dir, file->sub);
+ 1820 :
+ 1821 0 : ret = remove(path);
+ 1822 0 : if (ret != 0) {
+ 1823 : /* LCOV_EXCL_START */
+ 1824 : log_fatal("Error removing '%s'. %s.\n", path, strerror(errno));
+ 1825 : log_fatal("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n");
+ 1826 : ++unrecoverable_error;
+ 1827 : /* continue, as we are already exiting */
+ 1828 : /* LCOV_EXCL_STOP */
+ 1829 : }
+ 1830 : }
+ 1831 : }
+ 1832 : }
+ 1833 :
+ 1834 118 : if (error || recovered_error || unrecoverable_error) {
+ 1835 67 : msg_status("\n");
+ 1836 67 : msg_status("%8u errors\n", error);
+ 1837 67 : if (fix) {
+ 1838 43 : msg_status("%8u recovered errors\n", recovered_error);
+ 1839 : }
+ 1840 134 : if (unrecoverable_error) {
+ 1841 13 : msg_status("%8u UNRECOVERABLE errors\n", unrecoverable_error);
+ 1842 : } else {
+ 1843 : /* without checking, we don't know if they are really recoverable or not */
+ 1844 54 : if (!state->opt.auditonly)
+ 1845 52 : msg_status("%8u unrecoverable errors\n", unrecoverable_error);
+ 1846 54 : if (fix)
+ 1847 34 : msg_status("Everything OK\n");
+ 1848 : }
+ 1849 : } else {
+ 1850 51 : msg_status("Everything OK\n");
+ 1851 : }
+ 1852 :
+ 1853 118 : if (error && !fix)
+ 1854 24 : log_fatal("WARNING! There are errors!\n");
+ 1855 118 : if (unrecoverable_error)
+ 1856 13 : log_fatal("DANGER! There are unrecoverable errors!\n");
+ 1857 :
+ 1858 118 : log_tag("summary:error:%u\n", error);
+ 1859 118 : if (fix)
+ 1860 45 : log_tag("summary:error_recovered:%u\n", recovered_error);
+ 1861 118 : if (!state->opt.auditonly)
+ 1862 113 : log_tag("summary:error_unrecoverable:%u\n", unrecoverable_error);
+ 1863 118 : if (fix) {
+ 1864 45 : if (error + recovered_error + unrecoverable_error == 0)
+ 1865 2 : log_tag("summary:exit:ok\n");
+ 1866 43 : else if (unrecoverable_error == 0)
+ 1867 34 : log_tag("summary:exit:recovered\n");
+ 1868 : else
+ 1869 9 : log_tag("summary:exit:unrecoverable\n");
+ 1870 73 : } else if (!state->opt.auditonly) {
+ 1871 68 : if (error + unrecoverable_error == 0)
+ 1872 46 : log_tag("summary:exit:ok\n");
+ 1873 22 : else if (unrecoverable_error == 0)
+ 1874 18 : log_tag("summary:exit:recoverable\n");
+ 1875 : else
+ 1876 4 : log_tag("summary:exit:unrecoverable\n");
+ 1877 : } else { /* audit only */
+ 1878 5 : if (error == 0)
+ 1879 3 : log_tag("summary:exit:ok\n");
+ 1880 : else
+ 1881 2 : log_tag("summary:exit:error\n");
+ 1882 : }
+ 1883 118 : log_flush();
+ 1884 :
+ 1885 118 : free(failed);
+ 1886 118 : free(failed_map);
+ 1887 118 : free(handle);
+ 1888 118 : free(buffer_alloc);
+ 1889 118 : free(buffer);
+ 1890 :
+ 1891 : /* fail if some error are present after the run */
+ 1892 118 : if (fix) {
+ 1893 45 : if (state->opt.expect_unrecoverable) {
+ 1894 9 : if (unrecoverable_error == 0)
+ 1895 0 : return -1;
+ 1896 : } else {
+ 1897 36 : if (unrecoverable_error != 0)
+ 1898 0 : return -1;
+ 1899 : }
+ 1900 : } else {
+ 1901 73 : if (state->opt.expect_unrecoverable) {
+ 1902 4 : if (unrecoverable_error == 0)
+ 1903 0 : return -1;
+ 1904 69 : } else if (state->opt.expect_recoverable) {
+ 1905 20 : if (unrecoverable_error != 0 || error == 0)
+ 1906 0 : return -1;
+ 1907 : } else {
+ 1908 49 : if (error != 0 || unrecoverable_error != 0)
+ 1909 0 : return -1;
+ 1910 : }
+ 1911 : }
+ 1912 :
+ 1913 118 : return 0;
+ 1914 : }
+ 1915 :
+ 1916 120 : int state_check(struct snapraid_state* state, int fix, block_off_t blockstart, block_off_t blockcount)
+ 1917 : {
+ 1918 : block_off_t blockmax;
+ 1919 : data_off_t size;
+ 1920 : int ret;
+ 1921 : struct snapraid_parity_handle parity[LEV_MAX];
+ 1922 : struct snapraid_parity_handle* parity_ptr[LEV_MAX];
+ 1923 : unsigned error;
+ 1924 : unsigned l;
+ 1925 :
+ 1926 120 : msg_progress("Initializing...\n");
+ 1927 :
+ 1928 120 : blockmax = parity_allocated_size(state);
+ 1929 120 : size = blockmax * (data_off_t)state->block_size;
+ 1930 :
+ 1931 120 : if (blockstart > blockmax) {
+ 1932 : /* LCOV_EXCL_START */
+ 1933 : log_fatal("Error in the specified starting block %u. It's bigger than the parity size %u.\n", blockstart, blockmax);
+ 1934 : exit(EXIT_FAILURE);
+ 1935 : /* LCOV_EXCL_STOP */
+ 1936 : }
+ 1937 :
+ 1938 : /* adjust the number of block to process */
+ 1939 120 : if (blockcount != 0 && blockstart + blockcount < blockmax) {
+ 1940 0 : blockmax = blockstart + blockcount;
+ 1941 : }
+ 1942 :
+ 1943 120 : if (fix) {
+ 1944 : /* if fixing, create the file and open for writing */
+ 1945 : /* if it fails, we cannot continue */
+ 1946 180 : for (l = 0; l < state->level; ++l) {
+ 1947 : /* skip parity disks that are not accessible */
+ 1948 135 : if (state->parity[l].skip_access) {
+ 1949 1 : parity_ptr[l] = 0;
+ 1950 1 : continue;
+ 1951 : }
+ 1952 :
+ 1953 134 : parity_ptr[l] = &parity[l];
+ 1954 134 : ret = parity_create(parity_ptr[l], &state->parity[l], l, state->file_mode, state->block_size, state->opt.parity_limit_size);
+ 1955 134 : if (ret == -1) {
+ 1956 : /* LCOV_EXCL_START */
+ 1957 : log_fatal("WARNING! Without an accessible %s file, it isn't possible to fix any error.\n", lev_name(l));
+ 1958 : exit(EXIT_FAILURE);
+ 1959 : /* LCOV_EXCL_STOP */
+ 1960 : }
+ 1961 :
+ 1962 134 : ret = parity_chsize(parity_ptr[l], &state->parity[l], 0, size, state->block_size, state->opt.skip_fallocate, state->opt.skip_space_holder);
+ 1963 134 : if (ret == -1) {
+ 1964 : /* LCOV_EXCL_START */
+ 1965 : log_fatal("WARNING! Without an accessible %s file, it isn't possible to sync.\n", lev_name(l));
+ 1966 : exit(EXIT_FAILURE);
+ 1967 : /* LCOV_EXCL_STOP */
+ 1968 : }
+ 1969 : }
+ 1970 75 : } else if (!state->opt.auditonly) {
+ 1971 : /* if checking, open the file for reading */
+ 1972 : /* it may fail if the file doesn't exist, in this case we continue to check the files */
+ 1973 393 : for (l = 0; l < state->level; ++l) {
+ 1974 324 : parity_ptr[l] = &parity[l];
+ 1975 324 : ret = parity_open(parity_ptr[l], &state->parity[l], l, state->file_mode, state->block_size, state->opt.parity_limit_size);
+ 1976 324 : if (ret == -1) {
+ 1977 1 : msg_status("No accessible %s file, only files will be checked.\n", lev_name(l));
+ 1978 : /* continue anyway */
+ 1979 1 : parity_ptr[l] = 0;
+ 1980 : }
+ 1981 : }
+ 1982 : } else {
+ 1983 : /* otherwise don't use any parity */
+ 1984 28 : for (l = 0; l < state->level; ++l)
+ 1985 22 : parity_ptr[l] = 0;
+ 1986 : }
+ 1987 :
+ 1988 120 : if (fix)
+ 1989 45 : msg_progress("Fixing...\n");
+ 1990 75 : else if (!state->opt.auditonly)
+ 1991 69 : msg_progress("Checking...\n");
+ 1992 : else
+ 1993 6 : msg_progress("Hashing...\n");
+ 1994 :
+ 1995 120 : error = 0;
+ 1996 :
+ 1997 : /* skip degenerated cases of empty parity, or skipping all */
+ 1998 120 : if (blockstart < blockmax) {
+ 1999 118 : ret = state_check_process(state, fix, parity_ptr, blockstart, blockmax);
+ 2000 118 : if (ret == -1) {
+ 2001 : /* LCOV_EXCL_START */
+ 2002 : ++error;
+ 2003 : /* continue, as we are already exiting */
+ 2004 : /* LCOV_EXCL_STOP */
+ 2005 : }
+ 2006 : }
+ 2007 :
+ 2008 : /* try to close only if opened */
+ 2009 601 : for (l = 0; l < state->level; ++l) {
+ 2010 481 : if (parity_ptr[l]) {
+ 2011 457 : ret = parity_close(parity_ptr[l]);
+ 2012 : /* LCOV_EXCL_START */
+ 2013 : if (ret == -1) {
+ 2014 : log_fatal("DANGER! Unexpected close error in %s disk.\n", lev_name(l));
+ 2015 : ++error;
+ 2016 : /* continue, as we are already exiting */
+ 2017 : }
+ 2018 : /* LCOV_EXCL_STOP */
+ 2019 : }
+ 2020 : }
+ 2021 :
+ 2022 : /* abort if error are present */
+ 2023 120 : if (error != 0)
+ 2024 0 : return -1;
+ 2025 120 : return 0;
+ 2026 : }
+ 2027 :
diff --git a/cov/cmdline/dry.c.func-sort-c.html b/cov/cmdline/dry.c.func-sort-c.html
index 57c0a78f..3dc0963d 100644
--- a/cov/cmdline/dry.c.func-sort-c.html
+++ b/cov/cmdline/dry.c.func-sort-c.html
@@ -32,8 +32,8 @@
|
-
-
+
+
@@ -61,18 +61,18 @@
| dry_parity_reader |
- 42604 |
+ 42601 |
| dry_data_reader |
- 42590 |
+ 42596 |
| block_is_enabled |
7102 |
- | state_dry |
+ state_dry |
2 |
diff --git a/cov/cmdline/dry.c.func.html b/cov/cmdline/dry.c.func.html
index 141183a7..6a9299f2 100644
--- a/cov/cmdline/dry.c.func.html
+++ b/cov/cmdline/dry.c.func.html
@@ -32,8 +32,8 @@
|
-
-
+
+
@@ -65,14 +65,14 @@
| dry_data_reader |
- 42590 |
+ 42596 |
| dry_parity_reader |
- 42604 |
+ 42601 |
- | state_dry |
+ state_dry |
2 |
diff --git a/cov/cmdline/dry.c.gcov.html b/cov/cmdline/dry.c.gcov.html
index 52744e1f..a360ddef 100644
--- a/cov/cmdline/dry.c.gcov.html
+++ b/cov/cmdline/dry.c.gcov.html
@@ -32,8 +32,8 @@
|
-
-
+
+
@@ -101,30 +101,30 @@
39 7102 : return 1;
40 : }
41 :
- 42 42590 : static void dry_data_reader(struct snapraid_worker* worker, struct snapraid_task* task)
+ 42 42596 : static void dry_data_reader(struct snapraid_worker* worker, struct snapraid_task* task)
43 : {
- 44 42590 : struct snapraid_io* io = worker->io;
- 45 42590 : struct snapraid_state* state = io->state;
- 46 42590 : struct snapraid_handle* handle = worker->handle;
- 47 42590 : struct snapraid_disk* disk = handle->disk;
- 48 42590 : block_off_t blockcur = task->position;
- 49 42590 : unsigned char* buffer = task->buffer;
+ 44 42596 : struct snapraid_io* io = worker->io;
+ 45 42596 : struct snapraid_state* state = io->state;
+ 46 42596 : struct snapraid_handle* handle = worker->handle;
+ 47 42596 : struct snapraid_disk* disk = handle->disk;
+ 48 42596 : block_off_t blockcur = task->position;
+ 49 42596 : unsigned char* buffer = task->buffer;
50 : int ret;
51 : char esc_buffer[ESC_MAX];
52 :
53 : /* if the disk position is not used */
- 54 42590 : if (!disk) {
+ 54 42596 : if (!disk) {
55 : /* use an empty block */
- 56 4686 : memset(buffer, 0, state->block_size);
- 57 4686 : task->state = TASK_STATE_DONE;
- 58 9916 : return;
+ 56 4687 : memset(buffer, 0, state->block_size);
+ 57 4687 : task->state = TASK_STATE_DONE;
+ 58 9918 : return;
59 : }
60 :
61 : /* get the block */
- 62 37904 : task->block = fs_par2block_find(disk, blockcur);
+ 62 37909 : task->block = fs_par2block_find(disk, blockcur);
63 :
64 : /* if the block is not used */
- 65 37878 : if (!block_has_file(task->block)) {
+ 65 37865 : if (!block_has_file(task->block)) {
66 : /* use an empty block */
67 544 : memset(buffer, 0, state->block_size);
68 544 : task->state = TASK_STATE_DONE;
@@ -132,14 +132,14 @@
70 : }
71 :
72 : /* get the file of this block */
- 73 37320 : task->file = fs_par2file_get(disk, blockcur, &task->file_pos);
+ 73 37325 : task->file = fs_par2file_get(disk, blockcur, &task->file_pos);
74 :
75 : /* if the file is different than the current one, close it */
- 76 37335 : if (handle->file != 0 && handle->file != task->file) {
+ 76 37355 : if (handle->file != 0 && handle->file != task->file) {
77 : /* keep a pointer at the file we are going to close for error reporting */
- 78 15082 : struct snapraid_file* report = handle->file;
- 79 15082 : ret = handle_close(handle);
- 80 15071 : if (ret == -1) {
+ 78 15077 : struct snapraid_file* report = handle->file;
+ 79 15077 : ret = handle_close(handle);
+ 80 15079 : if (ret == -1) {
81 : /* LCOV_EXCL_START */
82 : /* This one is really an unexpected error, because we are only reading */
83 : /* and closing a descriptor should never fail */
@@ -162,8 +162,8 @@
100 : }
101 : }
102 :
- 103 37324 : ret = handle_open(handle, task->file, state->file_mode, log_error, 0);
- 104 37350 : if (ret == -1) {
+ 103 37357 : ret = handle_open(handle, task->file, state->file_mode, log_error, 0);
+ 104 37369 : if (ret == -1) {
105 0 : if (errno == EIO) {
106 : /* LCOV_EXCL_START */
107 : log_tag("error:%u:%s:%s: Open EIO error. %s\n", blockcur, disk->name, esc_tag(task->file->sub, esc_buffer), strerror(errno));
@@ -180,8 +180,8 @@
118 0 : return;
119 : }
120 :
- 121 37350 : task->read_size = handle_read(handle, task->file_pos, buffer, state->block_size, log_error, 0);
- 122 37281 : if (task->read_size == -1) {
+ 121 37369 : task->read_size = handle_read(handle, task->file_pos, buffer, state->block_size, log_error, 0);
+ 122 37250 : if (task->read_size == -1) {
123 0 : if (errno == EIO) {
124 0 : log_tag("error:%u:%s:%s: Read EIO error at position %u. %s\n", blockcur, disk->name, esc_tag(task->file->sub, esc_buffer), task->file_pos, strerror(errno));
125 0 : log_error("Input/Output error in file '%s' at position '%u'\n", handle->path, task->file_pos);
@@ -195,24 +195,24 @@
133 : }
134 :
135 : /* store the path of the opened file */
- 136 37281 : pathcpy(task->path, sizeof(task->path), handle->path);
+ 136 37250 : pathcpy(task->path, sizeof(task->path), handle->path);
137 :
- 138 37299 : task->state = TASK_STATE_DONE;
+ 138 37319 : task->state = TASK_STATE_DONE;
139 : }
140 :
- 141 42604 : static void dry_parity_reader(struct snapraid_worker* worker, struct snapraid_task* task)
+ 141 42601 : static void dry_parity_reader(struct snapraid_worker* worker, struct snapraid_task* task)
142 : {
- 143 42604 : struct snapraid_io* io = worker->io;
- 144 42604 : struct snapraid_state* state = io->state;
- 145 42604 : struct snapraid_parity_handle* parity_handle = worker->parity_handle;
- 146 42604 : unsigned level = parity_handle->level;
- 147 42604 : block_off_t blockcur = task->position;
- 148 42604 : unsigned char* buffer = task->buffer;
+ 143 42601 : struct snapraid_io* io = worker->io;
+ 144 42601 : struct snapraid_state* state = io->state;
+ 145 42601 : struct snapraid_parity_handle* parity_handle = worker->parity_handle;
+ 146 42601 : unsigned level = parity_handle->level;
+ 147 42601 : block_off_t blockcur = task->position;
+ 148 42601 : unsigned char* buffer = task->buffer;
149 : int ret;
150 :
151 : /* read the parity */
- 152 42604 : ret = parity_read(parity_handle, blockcur, buffer, state->block_size, log_error);
- 153 42568 : if (ret == -1) {
+ 152 42601 : ret = parity_read(parity_handle, blockcur, buffer, state->block_size, log_error);
+ 153 42575 : if (ret == -1) {
154 0 : if (errno == EIO) {
155 0 : log_tag("parity_error:%u:%s: Read EIO error. %s\n", blockcur, lev_config_name(level), strerror(errno));
156 0 : log_error("Input/Output error in parity '%s' at position '%u'\n", lev_config_name(level), blockcur);
@@ -225,7 +225,7 @@
163 0 : return;
164 : }
165 :
- 166 42568 : task->state = TASK_STATE_DONE;
+ 166 42575 : task->state = TASK_STATE_DONE;
167 : }
168 :
169 2 : static int state_dry_process(struct snapraid_state* state, struct snapraid_parity_handle* parity_handle, block_off_t blockstart, block_off_t blockmax)
@@ -316,210 +316,218 @@
254 :
255 : /* handle error conditions */
256 37380 : if (task->state == TASK_STATE_IOERROR) {
- 257 0 : ++io_error;
- 258 0 : goto bail;
- 259 : }
- 260 37380 : if (task->state == TASK_STATE_ERROR) {
- 261 0 : ++error;
- 262 0 : goto bail;
- 263 : }
- 264 37380 : if (task->state == TASK_STATE_ERROR_CONTINUE) {
- 265 0 : ++error;
- 266 0 : continue;
+ 257 : /* LCOV_EXCL_START */
+ 258 : ++io_error;
+ 259 : goto bail;
+ 260 : /* LCOV_EXCL_STOP */
+ 261 : }
+ 262 37380 : if (task->state == TASK_STATE_ERROR) {
+ 263 : /* LCOV_EXCL_START */
+ 264 : ++error;
+ 265 : goto bail;
+ 266 : /* LCOV_EXCL_STOP */
267 : }
- 268 37380 : if (task->state == TASK_STATE_IOERROR_CONTINUE) {
- 269 0 : ++io_error;
- 270 0 : if (io_error >= state->opt.io_error_limit) {
- 271 : /* LCOV_EXCL_START */
- 272 : log_fatal("DANGER! Too many input/output read error in a data disk, it isn't possible to scrub.\n");
- 273 : log_fatal("Ensure that disk '%s' is sane and that file '%s' can be accessed.\n", disk->dir, task->path);
- 274 : log_fatal("Stopping at block %u\n", blockcur);
- 275 : goto bail;
- 276 : /* LCOV_EXCL_STOP */
- 277 : }
- 278 :
- 279 : /* otherwise continue */
- 280 0 : continue;
- 281 : }
- 282 37380 : if (task->state != TASK_STATE_DONE) {
- 283 : /* LCOV_EXCL_START */
- 284 : log_fatal("Internal inconsistency in task state\n");
- 285 : os_abort();
- 286 : /* LCOV_EXCL_STOP */
- 287 : }
- 288 :
- 289 37380 : countsize += read_size;
- 290 : }
- 291 :
- 292 : /* until now is misc */
- 293 7102 : state_usage_misc(state);
- 294 :
- 295 : /* read the parity */
- 296 49714 : for (l = 0; l < state->level; ++l) {
- 297 : struct snapraid_task* task;
- 298 : unsigned levcur;
- 299 :
- 300 42612 : task = io_parity_read(&io, &levcur, waiting_map, &waiting_mac);
- 301 :
- 302 : /* until now is parity */
- 303 42612 : state_usage_parity(state, waiting_map, waiting_mac);
- 304 :
- 305 : /* handle error conditions */
- 306 42612 : if (task->state == TASK_STATE_IOERROR) {
- 307 0 : ++io_error;
- 308 0 : goto bail;
- 309 : }
- 310 42612 : if (task->state == TASK_STATE_ERROR) {
- 311 0 : ++error;
- 312 0 : goto bail;
- 313 : }
- 314 42612 : if (task->state == TASK_STATE_ERROR_CONTINUE) {
- 315 0 : ++error;
- 316 0 : continue;
- 317 : }
- 318 42612 : if (task->state == TASK_STATE_IOERROR_CONTINUE) {
- 319 0 : ++io_error;
- 320 0 : if (io_error >= state->opt.io_error_limit) {
- 321 : /* LCOV_EXCL_START */
- 322 : log_fatal("DANGER! Too many input/output read error in the %s disk, it isn't possible to scrub.\n", lev_name(levcur));
- 323 : log_fatal("Ensure that disk '%s' is sane and can be read.\n", lev_config_name(levcur));
- 324 : log_fatal("Stopping at block %u\n", blockcur);
- 325 : goto bail;
- 326 : /* LCOV_EXCL_STOP */
- 327 : }
- 328 0 : continue;
- 329 : }
- 330 42612 : if (task->state != TASK_STATE_DONE) {
- 331 : /* LCOV_EXCL_START */
- 332 : log_fatal("Internal inconsistency in task state\n");
- 333 : os_abort();
- 334 : /* LCOV_EXCL_STOP */
- 335 : }
- 336 : }
- 337 :
- 338 : /* count the number of processed block */
- 339 7102 : ++countpos;
- 340 :
- 341 : /* progress */
- 342 7102 : if (state_progress(state, &io, blockcur, countpos, countmax, countsize)) {
- 343 : /* LCOV_EXCL_START */
- 344 : break;
- 345 : /* LCOV_EXCL_STOP */
- 346 : }
- 347 7102 : }
+ 268 37380 : if (task->state == TASK_STATE_ERROR_CONTINUE) {
+ 269 0 : ++error;
+ 270 0 : continue;
+ 271 : }
+ 272 37380 : if (task->state == TASK_STATE_IOERROR_CONTINUE) {
+ 273 0 : ++io_error;
+ 274 0 : if (io_error >= state->opt.io_error_limit) {
+ 275 : /* LCOV_EXCL_START */
+ 276 : log_fatal("DANGER! Too many input/output read error in a data disk, it isn't possible to scrub.\n");
+ 277 : log_fatal("Ensure that disk '%s' is sane and that file '%s' can be accessed.\n", disk->dir, task->path);
+ 278 : log_fatal("Stopping at block %u\n", blockcur);
+ 279 : goto bail;
+ 280 : /* LCOV_EXCL_STOP */
+ 281 : }
+ 282 :
+ 283 : /* otherwise continue */
+ 284 0 : continue;
+ 285 : }
+ 286 37380 : if (task->state != TASK_STATE_DONE) {
+ 287 : /* LCOV_EXCL_START */
+ 288 : log_fatal("Internal inconsistency in task state\n");
+ 289 : os_abort();
+ 290 : /* LCOV_EXCL_STOP */
+ 291 : }
+ 292 :
+ 293 37380 : countsize += read_size;
+ 294 : }
+ 295 :
+ 296 : /* until now is misc */
+ 297 7102 : state_usage_misc(state);
+ 298 :
+ 299 : /* read the parity */
+ 300 49714 : for (l = 0; l < state->level; ++l) {
+ 301 : struct snapraid_task* task;
+ 302 : unsigned levcur;
+ 303 :
+ 304 42612 : task = io_parity_read(&io, &levcur, waiting_map, &waiting_mac);
+ 305 :
+ 306 : /* until now is parity */
+ 307 42612 : state_usage_parity(state, waiting_map, waiting_mac);
+ 308 :
+ 309 : /* handle error conditions */
+ 310 42612 : if (task->state == TASK_STATE_IOERROR) {
+ 311 : /* LCOV_EXCL_START */
+ 312 : ++io_error;
+ 313 : goto bail;
+ 314 : /* LCOV_EXCL_STOP */
+ 315 : }
+ 316 42612 : if (task->state == TASK_STATE_ERROR) {
+ 317 : /* LCOV_EXCL_START */
+ 318 : ++error;
+ 319 : goto bail;
+ 320 : /* LCOV_EXCL_STOP */
+ 321 : }
+ 322 42612 : if (task->state == TASK_STATE_ERROR_CONTINUE) {
+ 323 0 : ++error;
+ 324 0 : continue;
+ 325 : }
+ 326 42612 : if (task->state == TASK_STATE_IOERROR_CONTINUE) {
+ 327 0 : ++io_error;
+ 328 0 : if (io_error >= state->opt.io_error_limit) {
+ 329 : /* LCOV_EXCL_START */
+ 330 : log_fatal("DANGER! Too many input/output read error in the %s disk, it isn't possible to scrub.\n", lev_name(levcur));
+ 331 : log_fatal("Ensure that disk '%s' is sane and can be read.\n", lev_config_name(levcur));
+ 332 : log_fatal("Stopping at block %u\n", blockcur);
+ 333 : goto bail;
+ 334 : /* LCOV_EXCL_STOP */
+ 335 : }
+ 336 0 : continue;
+ 337 : }
+ 338 42612 : if (task->state != TASK_STATE_DONE) {
+ 339 : /* LCOV_EXCL_START */
+ 340 : log_fatal("Internal inconsistency in task state\n");
+ 341 : os_abort();
+ 342 : /* LCOV_EXCL_STOP */
+ 343 : }
+ 344 : }
+ 345 :
+ 346 : /* count the number of processed block */
+ 347 7102 : ++countpos;
348 :
- 349 2 : state_progress_end(state, countpos, countmax, countsize);
- 350 :
- 351 2 : state_usage_print(state);
- 352 :
- 353 : bail:
- 354 : /* stop all the worker threads */
- 355 2 : io_stop(&io);
+ 349 : /* progress */
+ 350 7102 : if (state_progress(state, &io, blockcur, countpos, countmax, countsize)) {
+ 351 : /* LCOV_EXCL_START */
+ 352 : break;
+ 353 : /* LCOV_EXCL_STOP */
+ 354 : }
+ 355 7102 : }
356 :
- 357 14 : for (j = 0; j < diskmax; ++j) {
- 358 12 : struct snapraid_file* file = handle[j].file;
- 359 12 : struct snapraid_disk* disk = handle[j].disk;
- 360 12 : ret = handle_close(&handle[j]);
- 361 12 : if (ret == -1) {
- 362 : /* LCOV_EXCL_START */
- 363 : log_tag("error:%u:%s:%s: Close error. %s\n", blockmax, disk->name, esc_tag(file->sub, esc_buffer), strerror(errno));
- 364 : log_fatal("DANGER! Unexpected close error in a data disk.\n");
- 365 : ++error;
- 366 : /* continue, as we are already exiting */
- 367 : /* LCOV_EXCL_STOP */
- 368 : }
- 369 : }
- 370 :
- 371 2 : if (error || io_error) {
- 372 0 : msg_status("\n");
- 373 0 : msg_status("%8u file errors\n", error);
- 374 0 : msg_status("%8u io errors\n", io_error);
- 375 : } else {
- 376 2 : msg_status("Everything OK\n");
+ 357 2 : state_progress_end(state, countpos, countmax, countsize);
+ 358 :
+ 359 2 : state_usage_print(state);
+ 360 :
+ 361 : bail:
+ 362 : /* stop all the worker threads */
+ 363 2 : io_stop(&io);
+ 364 :
+ 365 14 : for (j = 0; j < diskmax; ++j) {
+ 366 12 : struct snapraid_file* file = handle[j].file;
+ 367 12 : struct snapraid_disk* disk = handle[j].disk;
+ 368 12 : ret = handle_close(&handle[j]);
+ 369 12 : if (ret == -1) {
+ 370 : /* LCOV_EXCL_START */
+ 371 : log_tag("error:%u:%s:%s: Close error. %s\n", blockmax, disk->name, esc_tag(file->sub, esc_buffer), strerror(errno));
+ 372 : log_fatal("DANGER! Unexpected close error in a data disk.\n");
+ 373 : ++error;
+ 374 : /* continue, as we are already exiting */
+ 375 : /* LCOV_EXCL_STOP */
+ 376 : }
377 : }
378 :
- 379 2 : if (error)
- 380 0 : log_fatal("DANGER! Unexpected errors!\n");
- 381 2 : if (io_error)
- 382 0 : log_fatal("DANGER! Unexpected input/output errors!\n");
- 383 :
- 384 2 : free(handle);
- 385 2 : free(waiting_map);
- 386 2 : io_done(&io);
- 387 :
- 388 2 : if (error + io_error != 0)
- 389 0 : return -1;
- 390 2 : return 0;
- 391 : }
- 392 :
- 393 2 : void state_dry(struct snapraid_state* state, block_off_t blockstart, block_off_t blockcount)
- 394 : {
- 395 : block_off_t blockmax;
- 396 : int ret;
- 397 : struct snapraid_parity_handle parity_handle[LEV_MAX];
- 398 : unsigned error;
- 399 : unsigned l;
+ 379 2 : if (error || io_error) {
+ 380 0 : msg_status("\n");
+ 381 0 : msg_status("%8u file errors\n", error);
+ 382 0 : msg_status("%8u io errors\n", io_error);
+ 383 : } else {
+ 384 2 : msg_status("Everything OK\n");
+ 385 : }
+ 386 :
+ 387 2 : if (error)
+ 388 0 : log_fatal("DANGER! Unexpected errors!\n");
+ 389 2 : if (io_error)
+ 390 0 : log_fatal("DANGER! Unexpected input/output errors!\n");
+ 391 :
+ 392 2 : free(handle);
+ 393 2 : free(waiting_map);
+ 394 2 : io_done(&io);
+ 395 :
+ 396 2 : if (error + io_error != 0)
+ 397 0 : return -1;
+ 398 2 : return 0;
+ 399 : }
400 :
- 401 2 : msg_progress("Drying...\n");
- 402 :
- 403 2 : blockmax = parity_allocated_size(state);
- 404 :
- 405 2 : if (blockstart > blockmax) {
- 406 : /* LCOV_EXCL_START */
- 407 : log_fatal("Error in the specified starting block %u. It's bigger than the parity size %u.\n", blockstart, blockmax);
- 408 : exit(EXIT_FAILURE);
- 409 : /* LCOV_EXCL_STOP */
- 410 : }
- 411 :
- 412 : /* adjust the number of block to process */
- 413 2 : if (blockcount != 0 && blockstart + blockcount < blockmax) {
- 414 0 : blockmax = blockstart + blockcount;
- 415 : }
- 416 :
- 417 : /* open the file for reading */
- 418 : /* it may fail if the file doesn't exist, in this case we continue to dry the files */
- 419 14 : for (l = 0; l < state->level; ++l) {
- 420 12 : ret = parity_open(&parity_handle[l], &state->parity[l], l, state->file_mode, state->block_size, state->opt.parity_limit_size);
- 421 12 : if (ret == -1) {
- 422 : /* LCOV_EXCL_START */
- 423 : log_fatal("WARNING! Without an accessible %s file, it isn't possible to dry.\n", lev_name(l));
- 424 : exit(EXIT_FAILURE);
- 425 : /* LCOV_EXCL_STOP */
- 426 : }
- 427 : }
- 428 :
- 429 2 : error = 0;
- 430 :
- 431 : /* skip degenerated cases of empty parity, or skipping all */
- 432 2 : if (blockstart < blockmax) {
- 433 2 : ret = state_dry_process(state, parity_handle, blockstart, blockmax);
- 434 2 : if (ret == -1) {
- 435 : /* LCOV_EXCL_START */
- 436 : ++error;
- 437 : /* continue, as we are already exiting */
- 438 : /* LCOV_EXCL_STOP */
- 439 : }
- 440 : }
- 441 :
- 442 : /* try to close only if opened */
- 443 14 : for (l = 0; l < state->level; ++l) {
- 444 12 : ret = parity_close(&parity_handle[l]);
- 445 12 : if (ret == -1) {
- 446 : /* LCOV_EXCL_START */
- 447 : ++error;
- 448 : /* continue, as we are already exiting */
- 449 : /* LCOV_EXCL_STOP */
- 450 : }
- 451 : }
- 452 :
- 453 : /* abort if required */
- 454 2 : if (error != 0) {
- 455 : /* LCOV_EXCL_START */
- 456 : exit(EXIT_FAILURE);
- 457 : /* LCOV_EXCL_STOP */
- 458 : }
- 459 2 : }
+ 401 2 : void state_dry(struct snapraid_state* state, block_off_t blockstart, block_off_t blockcount)
+ 402 : {
+ 403 : block_off_t blockmax;
+ 404 : int ret;
+ 405 : struct snapraid_parity_handle parity_handle[LEV_MAX];
+ 406 : unsigned error;
+ 407 : unsigned l;
+ 408 :
+ 409 2 : msg_progress("Drying...\n");
+ 410 :
+ 411 2 : blockmax = parity_allocated_size(state);
+ 412 :
+ 413 2 : if (blockstart > blockmax) {
+ 414 : /* LCOV_EXCL_START */
+ 415 : log_fatal("Error in the specified starting block %u. It's bigger than the parity size %u.\n", blockstart, blockmax);
+ 416 : exit(EXIT_FAILURE);
+ 417 : /* LCOV_EXCL_STOP */
+ 418 : }
+ 419 :
+ 420 : /* adjust the number of block to process */
+ 421 2 : if (blockcount != 0 && blockstart + blockcount < blockmax) {
+ 422 0 : blockmax = blockstart + blockcount;
+ 423 : }
+ 424 :
+ 425 : /* open the file for reading */
+ 426 : /* it may fail if the file doesn't exist, in this case we continue to dry the files */
+ 427 14 : for (l = 0; l < state->level; ++l) {
+ 428 12 : ret = parity_open(&parity_handle[l], &state->parity[l], l, state->file_mode, state->block_size, state->opt.parity_limit_size);
+ 429 12 : if (ret == -1) {
+ 430 : /* LCOV_EXCL_START */
+ 431 : log_fatal("WARNING! Without an accessible %s file, it isn't possible to dry.\n", lev_name(l));
+ 432 : exit(EXIT_FAILURE);
+ 433 : /* LCOV_EXCL_STOP */
+ 434 : }
+ 435 : }
+ 436 :
+ 437 2 : error = 0;
+ 438 :
+ 439 : /* skip degenerated cases of empty parity, or skipping all */
+ 440 2 : if (blockstart < blockmax) {
+ 441 2 : ret = state_dry_process(state, parity_handle, blockstart, blockmax);
+ 442 2 : if (ret == -1) {
+ 443 : /* LCOV_EXCL_START */
+ 444 : ++error;
+ 445 : /* continue, as we are already exiting */
+ 446 : /* LCOV_EXCL_STOP */
+ 447 : }
+ 448 : }
+ 449 :
+ 450 : /* try to close only if opened */
+ 451 14 : for (l = 0; l < state->level; ++l) {
+ 452 12 : ret = parity_close(&parity_handle[l]);
+ 453 12 : if (ret == -1) {
+ 454 : /* LCOV_EXCL_START */
+ 455 : ++error;
+ 456 : /* continue, as we are already exiting */
+ 457 : /* LCOV_EXCL_STOP */
+ 458 : }
+ 459 : }
460 :
+ 461 : /* abort if required */
+ 462 2 : if (error != 0) {
+ 463 : /* LCOV_EXCL_START */
+ 464 : exit(EXIT_FAILURE);
+ 465 : /* LCOV_EXCL_STOP */
+ 466 : }
+ 467 2 : }
+ 468 :
diff --git a/cov/cmdline/elem.c.func-sort-c.html b/cov/cmdline/elem.c.func-sort-c.html
index 37d36fef..adc5592a 100644
--- a/cov/cmdline/elem.c.func-sort-c.html
+++ b/cov/cmdline/elem.c.func-sort-c.html
@@ -61,71 +61,71 @@
| extent_parity_inside_compare_unlock |
- 113816358 |
+ 113835807 |
| fs_lock |
- 53194369 |
+ 53196480 |
| fs_unlock |
- 53193869 |
+ 53196096 |
| extent_file_compare |
- 45007856 |
+ 45007274 |
| fs_file2block_get |
- 44945080 |
+ 44946613 |
| extent_parity_compare |
- 44511012 |
+ 44510782 |
| fs_par2extent_get_unlock |
- 39142093 |
+ 39144459 |
| fs_par2file_find |
- 39035232 |
+ 39037806 |
| fs_par2block_find |
- 27312315 |
+ 27314040 |
| extent_file_inside_compare_unlock |
- 21314053 |
+ 21310663 |
| filter_apply |
- 12456124 |
+ 12456904 |
| fs_file2extent_get_unlock |
- 10336325 |
+ 10336351 |
| fs_allocate |
- 9175619 |
+ 9175524 |
| file_block_size |
- 6823060 |
+ 6823791 |
| extent_file_check_foreach_unlock |
- 6584437 |
+ 6584417 |
| extent_parity_check_foreach_unlock |
- 6584437 |
+ 6584417 |
| filter_recurse |
- 6236157 |
+ 6236559 |
| file_block_is_last |
@@ -133,55 +133,55 @@
| fs_file2par_find |
- 4869535 |
+ 4869582 |
| extent_alloc |
- 3735492 |
+ 3735396 |
| file_alloc |
- 3691209 |
+ 3691126 |
| extent_free |
- 3564805 |
+ 3564840 |
| file_free |
- 3543765 |
+ 3543814 |
| filter_element |
- 3332623 |
+ 3332824 |
| filter_path |
- 3329526 |
+ 3329727 |
| filter_content |
- 3173124 |
+ 3173351 |
| file_inode_compare_to_arg |
- 987050 |
+ 987099 |
| time_compare |
- 684987 |
+ 684203 |
| fmt_term |
- 356004 |
+ 356075 |
| file_path_compare |
- 189434 |
+ 189486 |
| filter_type |
- 125245 |
+ 125255 |
| link_alloc |
@@ -193,27 +193,27 @@
| fs_deallocate |
- 106126 |
+ 106308 |
| file_path_compare_to_arg |
- 97552 |
+ 97531 |
| filter_existence |
80691 |
-
- | file_physical_compare |
- 63430 |
-
| extent_disk_size_compare_unlock |
- 50483 |
+ 50510 |
| file_name |
- 47954 |
+ 47922 |
+
+
+ | file_physical_compare |
+ 44202 |
| filter_correctness |
@@ -225,11 +225,11 @@
| file_namestamp_compare |
- 23977 |
+ 23961 |
| file_name_compare |
- 23977 |
+ 23961 |
| file_stamp_compare |
@@ -241,11 +241,11 @@
| file_dup |
- 22680 |
+ 22687 |
| fs_size |
- 4339 |
+ 4351 |
| link_alpha_compare |
@@ -257,19 +257,19 @@
| fs_check |
- 2970 |
+ 2982 |
| disk_alloc |
- 1579 |
+ 1585 |
| map_alloc |
- 1549 |
+ 1555 |
| content_alloc |
- 1523 |
+ 1525 |
| disk_free |
@@ -297,7 +297,7 @@
| filter_alloc_file |
- 532 |
+ 534 |
| filter_free |
diff --git a/cov/cmdline/elem.c.func.html b/cov/cmdline/elem.c.func.html
index 4f769ce7..867b2c1f 100644
--- a/cov/cmdline/elem.c.func.html
+++ b/cov/cmdline/elem.c.func.html
@@ -61,7 +61,7 @@
| content_alloc |
- 1523 |
+ 1525 |
| content_free |
@@ -81,7 +81,7 @@
| disk_alloc |
- 1579 |
+ 1585 |
| disk_free |
@@ -89,7 +89,7 @@
| extent_alloc |
- 3735492 |
+ 3735396 |
| extent_disk_empty_compare_unlock |
@@ -97,39 +97,39 @@
| extent_disk_size_compare_unlock |
- 50483 |
+ 50510 |
| extent_file_check_foreach_unlock |
- 6584437 |
+ 6584417 |
| extent_file_compare |
- 45007856 |
+ 45007274 |
| extent_file_inside_compare_unlock |
- 21314053 |
+ 21310663 |
| extent_free |
- 3564805 |
+ 3564840 |
| extent_parity_check_foreach_unlock |
- 6584437 |
+ 6584417 |
| extent_parity_compare |
- 44511012 |
+ 44510782 |
| extent_parity_inside_compare_unlock |
- 113816358 |
+ 113835807 |
| file_alloc |
- 3691209 |
+ 3691126 |
| file_block_is_last |
@@ -137,7 +137,7 @@
| file_block_size |
- 6823060 |
+ 6823791 |
| file_copy |
@@ -145,11 +145,11 @@
| file_dup |
- 22680 |
+ 22687 |
| file_free |
- 3543765 |
+ 3543814 |
| file_inode_compare |
@@ -157,27 +157,27 @@
| file_inode_compare_to_arg |
- 987050 |
+ 987099 |
| file_name |
- 47954 |
+ 47922 |
| file_name_compare |
- 23977 |
+ 23961 |
| file_namestamp_compare |
- 23977 |
+ 23961 |
| file_path_compare |
- 189434 |
+ 189486 |
| file_path_compare_to_arg |
- 97552 |
+ 97531 |
| file_pathstamp_compare |
@@ -185,7 +185,7 @@
| file_physical_compare |
- 63430 |
+ 44202 |
| file_rename |
@@ -201,15 +201,15 @@
| filter_alloc_file |
- 532 |
+ 534 |
| filter_apply |
- 12456124 |
+ 12456904 |
| filter_content |
- 3173124 |
+ 3173351 |
| filter_correctness |
@@ -217,7 +217,7 @@
| filter_element |
- 3332623 |
+ 3332824 |
| filter_emptydir |
@@ -233,11 +233,11 @@
| filter_path |
- 3329526 |
+ 3329727 |
| filter_recurse |
- 6236157 |
+ 6236559 |
| filter_subdir |
@@ -245,7 +245,7 @@
| filter_type |
- 125245 |
+ 125255 |
| fmt_poll |
@@ -253,31 +253,31 @@
| fmt_term |
- 356004 |
+ 356075 |
| fs_allocate |
- 9175619 |
+ 9175524 |
| fs_check |
- 2970 |
+ 2982 |
| fs_deallocate |
- 106126 |
+ 106308 |
| fs_file2block_get |
- 44945080 |
+ 44946613 |
| fs_file2extent_get_unlock |
- 10336325 |
+ 10336351 |
| fs_file2par_find |
- 4869535 |
+ 4869582 |
| fs_is_empty |
@@ -285,27 +285,27 @@
| fs_lock |
- 53194369 |
+ 53196480 |
| fs_par2block_find |
- 27312315 |
+ 27314040 |
| fs_par2extent_get_unlock |
- 39142093 |
+ 39144459 |
| fs_par2file_find |
- 39035232 |
+ 39037806 |
| fs_size |
- 4339 |
+ 4351 |
| fs_unlock |
- 53193869 |
+ 53196096 |
| link_alloc |
@@ -325,7 +325,7 @@
| map_alloc |
- 1549 |
+ 1555 |
| map_free |
@@ -333,7 +333,7 @@
| time_compare |
- 684987 |
+ 684203 |
diff --git a/cov/cmdline/elem.c.gcov.html b/cov/cmdline/elem.c.gcov.html
index dec010b8..82da91c6 100644
--- a/cov/cmdline/elem.c.gcov.html
+++ b/cov/cmdline/elem.c.gcov.html
@@ -88,15 +88,15 @@
26 :
27 : int BLOCK_HASH_SIZE = HASH_MAX;
28 :
- 29 1523 : struct snapraid_content* content_alloc(const char* path, uint64_t dev)
+ 29 1525 : struct snapraid_content* content_alloc(const char* path, uint64_t dev)
30 : {
31 : struct snapraid_content* content;
32 :
- 33 1523 : content = malloc_nofail(sizeof(struct snapraid_content));
- 34 1523 : pathimport(content->content, sizeof(content->content), path);
- 35 1523 : content->device = dev;
+ 33 1525 : content = malloc_nofail(sizeof(struct snapraid_content));
+ 34 1525 : pathimport(content->content, sizeof(content->content), path);
+ 35 1525 : content->device = dev;
36 :
- 37 1523 : return content;
+ 37 1525 : return content;
38 : }
39 :
40 1386 : void content_free(struct snapraid_content* content)
@@ -104,7 +104,7 @@
42 1386 : free(content);
43 1386 : }
44 :
- 45 532 : struct snapraid_filter* filter_alloc_file(int direction, const char* pattern)
+ 45 534 : struct snapraid_filter* filter_alloc_file(int direction, const char* pattern)
46 : {
47 : struct snapraid_filter* filter;
48 : char* i;
@@ -113,18 +113,18 @@
51 : int token_is_valid;
52 : int token_is_filled;
53 :
- 54 532 : filter = malloc_nofail(sizeof(struct snapraid_filter));
- 55 532 : pathimport(filter->pattern, sizeof(filter->pattern), pattern);
- 56 532 : filter->direction = direction;
+ 54 534 : filter = malloc_nofail(sizeof(struct snapraid_filter));
+ 55 534 : pathimport(filter->pattern, sizeof(filter->pattern), pattern);
+ 56 534 : filter->direction = direction;
57 :
58 : /* find first and last slash */
- 59 532 : first = 0;
- 60 532 : last = 0;
+ 59 534 : first = 0;
+ 60 534 : last = 0;
61 : /* reject invalid tokens, like "<empty>", ".", ".." and more dots */
- 62 532 : token_is_valid = 0;
- 63 532 : token_is_filled = 0;
- 64 6597 : for (i = filter->pattern; *i; ++i) {
- 65 6066 : if (*i == '/') {
+ 62 534 : token_is_valid = 0;
+ 63 534 : token_is_filled = 0;
+ 64 6622 : for (i = filter->pattern; *i; ++i) {
+ 65 6089 : if (*i == '/') {
66 : /* reject invalid tokens, but accept an empty one as first */
67 5 : if (!token_is_valid && (first != 0 || token_is_filled)) {
68 1 : free(filter);
@@ -137,27 +137,27 @@
75 4 : if (!first)
76 3 : first = i;
77 4 : last = i;
- 78 6061 : } else if (*i != '.') {
- 79 5533 : token_is_valid = 1;
- 80 5533 : token_is_filled = 1;
+ 78 6084 : } else if (*i != '.') {
+ 79 5554 : token_is_valid = 1;
+ 80 5554 : token_is_filled = 1;
81 : } else {
- 82 528 : token_is_filled = 1;
+ 82 530 : token_is_filled = 1;
83 : }
84 : }
85 :
86 : /* reject invalid tokens, but accept an empty one as last, but not if it's the only one */
- 87 531 : if (!token_is_valid && (first == 0 || token_is_filled)) {
+ 87 533 : if (!token_is_valid && (first == 0 || token_is_filled)) {
88 1 : free(filter);
89 1 : return 0;
90 : }
91 :
92 : /* it's a file filter */
- 93 530 : filter->is_disk = 0;
+ 93 532 : filter->is_disk = 0;
94 :
- 95 530 : if (first == 0) {
+ 95 532 : if (first == 0) {
96 : /* no slash */
- 97 527 : filter->is_path = 0;
- 98 527 : filter->is_dir = 0;
+ 97 529 : filter->is_path = 0;
+ 98 529 : filter->is_dir = 0;
99 3 : } else if (first == last && last[1] == 0) {
100 : /* one slash at the end */
101 1 : filter->is_path = 0;
@@ -180,7 +180,7 @@
118 : }
119 : }
120 :
- 121 529 : return filter;
+ 121 531 : return filter;
122 : }
123 :
124 10 : struct snapraid_filter* filter_alloc_disk(int direction, const char* pattern)
@@ -212,96 +212,96 @@
150 497 : free(filter);
151 497 : }
152 :
- 153 125245 : const char* filter_type(struct snapraid_filter* filter, char* out, size_t out_size)
+ 153 125255 : const char* filter_type(struct snapraid_filter* filter, char* out, size_t out_size)
154 : {
155 : const char* direction;
156 :
- 157 125245 : if (filter->direction < 0)
- 158 124982 : direction = "exclude";
+ 157 125255 : if (filter->direction < 0)
+ 158 124991 : direction = "exclude";
159 : else
- 160 263 : direction = "include";
+ 160 264 : direction = "include";
161 :
- 162 125245 : if (filter->is_disk)
+ 162 125255 : if (filter->is_disk)
163 0 : pathprint(out, out_size, "%s %s:", direction, filter->pattern);
- 164 125245 : else if (filter->is_dir)
+ 164 125255 : else if (filter->is_dir)
165 0 : pathprint(out, out_size, "%s %s/", direction, filter->pattern);
166 : else
- 167 125245 : pathprint(out, out_size, "%s %s", direction, filter->pattern);
+ 167 125255 : pathprint(out, out_size, "%s %s", direction, filter->pattern);
168 :
- 169 125245 : return out;
+ 169 125255 : return out;
170 : }
171 :
- 172 12456124 : static int filter_apply(struct snapraid_filter* filter, struct snapraid_filter** reason, const char* path, const char* name, int is_dir)
+ 172 12456904 : static int filter_apply(struct snapraid_filter* filter, struct snapraid_filter** reason, const char* path, const char* name, int is_dir)
173 : {
- 174 12456124 : int ret = 0;
+ 174 12456904 : int ret = 0;
175 :
176 : /* match dirs with dirs and files with files */
- 177 12456124 : if (filter->is_dir && !is_dir)
+ 177 12456904 : if (filter->is_dir && !is_dir)
178 2949 : return 0;
- 179 12453175 : if (!filter->is_dir && is_dir)
- 180 6223136 : return 0;
+ 179 12453955 : if (!filter->is_dir && is_dir)
+ 180 6223514 : return 0;
181 :
- 182 6230039 : if (filter->is_path) {
+ 182 6230441 : if (filter->is_path) {
183 : /* skip initial slash, as always missing from the path */
184 2949 : if (fnmatch(filter->pattern + 1, path, FNM_PATHNAME | FNM_CASEINSENSITIVE_FOR_WIN) == 0)
185 0 : ret = filter->direction;
186 : } else {
- 187 6227090 : if (fnmatch(filter->pattern, name, FNM_CASEINSENSITIVE_FOR_WIN) == 0)
- 188 127709 : ret = filter->direction;
+ 187 6227492 : if (fnmatch(filter->pattern, name, FNM_CASEINSENSITIVE_FOR_WIN) == 0)
+ 188 127717 : ret = filter->direction;
189 : }
190 :
- 191 6230039 : if (reason != 0 && ret < 0)
- 192 124719 : *reason = filter;
+ 191 6230441 : if (reason != 0 && ret < 0)
+ 192 124727 : *reason = filter;
193 :
- 194 6230039 : return ret;
+ 194 6230441 : return ret;
195 : }
196 :
- 197 6236157 : static int filter_recurse(struct snapraid_filter* filter, struct snapraid_filter** reason, const char* const_path, int is_dir)
+ 197 6236559 : static int filter_recurse(struct snapraid_filter* filter, struct snapraid_filter** reason, const char* const_path, int is_dir)
198 : {
199 : char path[PATH_MAX];
200 : char* name;
201 : unsigned i;
202 :
- 203 6236157 : pathcpy(path, sizeof(path), const_path);
+ 203 6236559 : pathcpy(path, sizeof(path), const_path);
204 :
205 : /* filter for all the directories */
- 206 6236157 : name = path;
- 207 89818142 : for (i = 0; path[i] != 0; ++i) {
- 208 83584975 : if (path[i] == '/') {
+ 206 6236559 : name = path;
+ 207 89823626 : for (i = 0; path[i] != 0; ++i) {
+ 208 83590057 : if (path[i] == '/') {
209 : /* set a terminator */
- 210 6222957 : path[i] = 0;
+ 210 6223335 : path[i] = 0;
211 :
212 : /* filter the directory */
- 213 6222957 : if (filter_apply(filter, reason, path, name, 1) != 0)
+ 213 6223335 : if (filter_apply(filter, reason, path, name, 1) != 0)
214 2990 : return filter->direction;
215 :
216 : /* restore the slash */
- 217 6219967 : path[i] = '/';
+ 217 6220345 : path[i] = '/';
218 :
219 : /* next name */
- 220 6219967 : name = path + i + 1;
+ 220 6220345 : name = path + i + 1;
221 : }
222 : }
223 :
224 : /* filter the final file */
- 225 6233167 : if (filter_apply(filter, reason, path, name, is_dir) != 0)
- 226 124719 : return filter->direction;
+ 225 6233569 : if (filter_apply(filter, reason, path, name, is_dir) != 0)
+ 226 124727 : return filter->direction;
227 :
- 228 6108448 : return 0;
+ 228 6108842 : return 0;
229 : }
230 :
- 231 3332623 : static int filter_element(tommy_list* filterlist, struct snapraid_filter** reason, const char* disk, const char* sub, int is_dir, int is_def_include)
+ 231 3332824 : static int filter_element(tommy_list* filterlist, struct snapraid_filter** reason, const char* disk, const char* sub, int is_dir, int is_def_include)
232 : {
233 : tommy_node* i;
234 :
- 235 3332623 : int direction = 1; /* by default include all */
+ 235 3332824 : int direction = 1; /* by default include all */
236 :
237 : /* for each filter */
- 238 9542379 : for (i = tommy_list_head(filterlist); i != 0; i = i->next) {
+ 238 9542974 : for (i = tommy_list_head(filterlist); i != 0; i = i->next) {
239 : int ret;
- 240 6346145 : struct snapraid_filter* filter = i->data;
+ 240 6346547 : struct snapraid_filter* filter = i->data;
241 :
- 242 6346145 : if (filter->is_disk) {
+ 242 6346547 : if (filter->is_disk) {
243 109988 : if (fnmatch(filter->pattern, disk, FNM_CASEINSENSITIVE_FOR_WIN) == 0)
244 8680 : ret = filter->direction;
245 : else
@@ -309,39 +309,39 @@
247 109988 : if (reason != 0 && ret < 0)
248 0 : *reason = filter;
249 : } else {
- 250 6236157 : ret = filter_recurse(filter, reason, sub, is_dir);
+ 250 6236559 : ret = filter_recurse(filter, reason, sub, is_dir);
251 : }
252 :
- 253 6346145 : if (ret > 0) {
+ 253 6346547 : if (ret > 0) {
254 : /* include the file */
255 11670 : return 0;
- 256 6334475 : } else if (ret < 0) {
+ 256 6334877 : } else if (ret < 0) {
257 : /* exclude the file */
- 258 124719 : return -1;
+ 258 124727 : return -1;
259 : } else {
260 : /* default is opposite of the last filter */
- 261 6209756 : direction = -filter->direction;
- 262 6209756 : if (reason != 0 && direction < 0)
- 263 3110665 : *reason = filter;
+ 261 6210150 : direction = -filter->direction;
+ 262 6210150 : if (reason != 0 && direction < 0)
+ 263 3110866 : *reason = filter;
264 : /* continue with the next one */
265 : }
266 : }
267 :
268 : /* directories are always included by default, otherwise we cannot apply rules */
269 : /* to the contained files */
- 270 3196234 : if (is_def_include)
+ 270 3196427 : if (is_def_include)
271 3052 : return 0;
272 :
273 : /* files are excluded/included depending of the last rule processed */
- 274 3193182 : if (direction < 0)
+ 274 3193375 : if (direction < 0)
275 57608 : return -1;
276 :
- 277 3135574 : return 0;
+ 277 3135767 : return 0;
278 : }
279 :
- 280 3329526 : int filter_path(tommy_list* filterlist, struct snapraid_filter** reason, const char* disk, const char* sub)
+ 280 3329727 : int filter_path(tommy_list* filterlist, struct snapraid_filter** reason, const char* disk, const char* sub)
281 : {
- 282 3329526 : return filter_element(filterlist, reason, disk, sub, 0, 0);
+ 282 3329727 : return filter_element(filterlist, reason, disk, sub, 0, 0);
283 : }
284 :
285 3052 : int filter_subdir(tommy_list* filterlist, struct snapraid_filter** reason, const char* disk, const char* sub)
@@ -387,103 +387,103 @@
325 16098 : return 0;
326 :
327 : /* check each block of the file */
- 328 60655 : for (i = 0; i < file->blockmax; ++i) {
- 329 46442 : block_off_t parity_pos = fs_file2par_get(disk, file, i);
- 330 46442 : snapraid_info info = info_get(infoarr, parity_pos);
+ 328 60677 : for (i = 0; i < file->blockmax; ++i) {
+ 329 46455 : block_off_t parity_pos = fs_file2par_get(disk, file, i);
+ 330 46455 : snapraid_info info = info_get(infoarr, parity_pos);
331 :
332 : /* if the file has a bad block, don't exclude it */
- 333 46442 : if (info_get_bad(info))
- 334 8335 : return 0;
+ 333 46455 : if (info_get_bad(info))
+ 334 8326 : return 0;
335 : }
336 :
337 : /* the file is correct, so we filter it out */
- 338 14213 : return 1;
+ 338 14222 : return 1;
339 : }
340 :
- 341 3173124 : int filter_content(tommy_list* contentlist, const char* path)
+ 341 3173351 : int filter_content(tommy_list* contentlist, const char* path)
342 : {
343 : tommy_node* i;
344 :
- 345 40911380 : for (i = tommy_list_head(contentlist); i != 0; i = i->next) {
- 346 17282566 : struct snapraid_content* content = i->data;
+ 345 40912970 : for (i = tommy_list_head(contentlist); i != 0; i = i->next) {
+ 346 17283134 : struct snapraid_content* content = i->data;
347 : char tmp[PATH_MAX];
348 :
- 349 17282566 : if (pathcmp(content->content, path) == 0)
+ 349 17283134 : if (pathcmp(content->content, path) == 0)
350 0 : return -1;
351 :
352 : /* exclude also the ".tmp" copy used to save it */
- 353 17282566 : pathprint(tmp, sizeof(tmp), "%s.tmp", content->content);
- 354 17282566 : if (pathcmp(tmp, path) == 0)
+ 353 17283134 : pathprint(tmp, sizeof(tmp), "%s.tmp", content->content);
+ 354 17283134 : if (pathcmp(tmp, path) == 0)
355 0 : return -1;
356 :
357 : /* exclude also the ".lock" file */
- 358 17282566 : pathprint(tmp, sizeof(tmp), "%s.lock", content->content);
- 359 17282566 : if (pathcmp(tmp, path) == 0)
+ 358 17283134 : pathprint(tmp, sizeof(tmp), "%s.lock", content->content);
+ 359 17283134 : if (pathcmp(tmp, path) == 0)
360 0 : return -1;
361 : }
362 :
- 363 3173124 : return 0;
+ 363 3173351 : return 0;
364 : }
365 :
- 366 3691209 : 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)
+ 366 3691126 : 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)
367 : {
368 : struct snapraid_file* file;
369 : block_off_t i;
370 :
- 371 3691209 : file = malloc_nofail(sizeof(struct snapraid_file));
- 372 3691209 : file->sub = strdup_nofail(sub);
- 373 3691209 : file->size = size;
- 374 3691209 : file->blockmax = (size + block_size - 1) / block_size;
- 375 3691209 : file->mtime_sec = mtime_sec;
- 376 3691209 : file->mtime_nsec = mtime_nsec;
- 377 3691209 : file->inode = inode;
- 378 3691209 : file->physical = physical;
- 379 3691209 : file->flag = 0;
- 380 3691209 : file->blockvec = malloc_nofail(file->blockmax * block_sizeof());
+ 371 3691126 : file = malloc_nofail(sizeof(struct snapraid_file));
+ 372 3691126 : file->sub = strdup_nofail(sub);
+ 373 3691126 : file->size = size;
+ 374 3691126 : file->blockmax = (size + block_size - 1) / block_size;
+ 375 3691126 : file->mtime_sec = mtime_sec;
+ 376 3691126 : file->mtime_nsec = mtime_nsec;
+ 377 3691126 : file->inode = inode;
+ 378 3691126 : file->physical = physical;
+ 379 3691126 : file->flag = 0;
+ 380 3691126 : file->blockvec = malloc_nofail(file->blockmax * block_sizeof());
381 :
- 382 12810920 : for (i = 0; i < file->blockmax; ++i) {
- 383 9119711 : struct snapraid_block* block = file_block(file, i);
- 384 9119711 : block_state_set(block, BLOCK_STATE_CHG);
- 385 9119711 : hash_invalid_set(block->hash);
+ 382 12810682 : for (i = 0; i < file->blockmax; ++i) {
+ 383 9119556 : struct snapraid_block* block = file_block(file, i);
+ 384 9119556 : block_state_set(block, BLOCK_STATE_CHG);
+ 385 9119556 : hash_invalid_set(block->hash);
386 : }
387 :
- 388 3691209 : return file;
+ 388 3691126 : return file;
389 : }
390 :
- 391 22680 : struct snapraid_file* file_dup(struct snapraid_file* copy)
+ 391 22687 : struct snapraid_file* file_dup(struct snapraid_file* copy)
392 : {
393 : struct snapraid_file* file;
394 : block_off_t i;
395 :
- 396 22680 : file = malloc_nofail(sizeof(struct snapraid_file));
- 397 22680 : file->sub = strdup_nofail(copy->sub);
- 398 22680 : file->size = copy->size;
- 399 22680 : file->blockmax = copy->blockmax;
- 400 22680 : file->mtime_sec = copy->mtime_sec;
- 401 22680 : file->mtime_nsec = copy->mtime_nsec;
- 402 22680 : file->inode = copy->inode;
- 403 22680 : file->physical = copy->physical;
- 404 22680 : file->flag = copy->flag;
- 405 22680 : file->blockvec = malloc_nofail(file->blockmax * block_sizeof());
+ 396 22687 : file = malloc_nofail(sizeof(struct snapraid_file));
+ 397 22687 : file->sub = strdup_nofail(copy->sub);
+ 398 22687 : file->size = copy->size;
+ 399 22687 : file->blockmax = copy->blockmax;
+ 400 22687 : file->mtime_sec = copy->mtime_sec;
+ 401 22687 : file->mtime_nsec = copy->mtime_nsec;
+ 402 22687 : file->inode = copy->inode;
+ 403 22687 : file->physical = copy->physical;
+ 404 22687 : file->flag = copy->flag;
+ 405 22687 : file->blockvec = malloc_nofail(file->blockmax * block_sizeof());
406 :
- 407 78592 : for (i = 0; i < file->blockmax; ++i) {
- 408 55912 : struct snapraid_block* block = file_block(file, i);
- 409 55912 : struct snapraid_block* copy_block = file_block(copy, i);
- 410 55912 : block->state = copy_block->state;
- 411 55912 : memcpy(block->hash, copy_block->hash, BLOCK_HASH_SIZE);
+ 407 78655 : for (i = 0; i < file->blockmax; ++i) {
+ 408 55968 : struct snapraid_block* block = file_block(file, i);
+ 409 55968 : struct snapraid_block* copy_block = file_block(copy, i);
+ 410 55968 : block->state = copy_block->state;
+ 411 55968 : memcpy(block->hash, copy_block->hash, BLOCK_HASH_SIZE);
412 : }
413 :
- 414 22680 : return file;
+ 414 22687 : return file;
415 : }
416 :
- 417 3543765 : void file_free(struct snapraid_file* file)
+ 417 3543814 : void file_free(struct snapraid_file* file)
418 : {
- 419 3543765 : free(file->sub);
- 420 3543765 : file->sub = 0;
- 421 3543765 : free(file->blockvec);
- 422 3543765 : file->blockvec = 0;
- 423 3543765 : free(file);
- 424 3543765 : }
+ 419 3543814 : free(file->sub);
+ 420 3543814 : file->sub = 0;
+ 421 3543814 : free(file->blockvec);
+ 422 3543814 : file->blockvec = 0;
+ 423 3543814 : free(file);
+ 424 3543814 : }
425 :
426 155 : void file_rename(struct snapraid_file* file, const char* sub)
427 : {
@@ -527,31 +527,31 @@
465 23636 : file_flag_set(dst_file, FILE_IS_COPY);
466 23636 : }
467 :
- 468 47954 : const char* file_name(const struct snapraid_file* file)
+ 468 47922 : const char* file_name(const struct snapraid_file* file)
469 : {
- 470 47954 : const char* r = strrchr(file->sub, '/');
+ 470 47922 : const char* r = strrchr(file->sub, '/');
471 :
- 472 47954 : if (!r)
+ 472 47922 : if (!r)
473 78 : r = file->sub;
474 : else
- 475 47876 : ++r;
- 476 47954 : return r;
+ 475 47844 : ++r;
+ 476 47922 : return r;
477 : }
478 :
- 479 6823060 : unsigned file_block_size(struct snapraid_file* file, block_off_t file_pos, unsigned block_size)
+ 479 6823791 : unsigned file_block_size(struct snapraid_file* file, block_off_t file_pos, unsigned block_size)
480 : {
481 : /* if it's the last block */
- 482 6823060 : if (file_pos + 1 == file->blockmax) {
+ 482 6823791 : if (file_pos + 1 == file->blockmax) {
483 : unsigned block_remainder;
- 484 2775047 : if (file->size == 0)
+ 484 2775528 : if (file->size == 0)
485 0 : return 0;
- 486 2775047 : block_remainder = file->size % block_size;
- 487 2775047 : if (block_remainder == 0)
- 488 3052 : block_remainder = block_size;
- 489 2775047 : return block_remainder;
+ 486 2775528 : block_remainder = file->size % block_size;
+ 487 2775528 : if (block_remainder == 0)
+ 488 3039 : block_remainder = block_size;
+ 489 2775528 : return block_remainder;
490 : }
491 :
- 492 4048013 : return block_size;
+ 492 4048263 : return block_size;
493 : }
494 :
495 5329167 : int file_block_is_last(struct snapraid_file* file, block_off_t file_pos)
@@ -569,16 +569,16 @@
507 5329167 : return file_pos == file->blockmax - 1;
508 : }
509 :
- 510 987050 : int file_inode_compare_to_arg(const void* void_arg, const void* void_data)
+ 510 987099 : int file_inode_compare_to_arg(const void* void_arg, const void* void_data)
511 : {
- 512 987050 : const uint64_t* arg = void_arg;
- 513 987050 : const struct snapraid_file* file = void_data;
+ 512 987099 : const uint64_t* arg = void_arg;
+ 513 987099 : const struct snapraid_file* file = void_data;
514 :
- 515 987050 : if (*arg < file->inode)
+ 515 987099 : if (*arg < file->inode)
516 0 : return -1;
- 517 987050 : if (*arg > file->inode)
+ 517 987099 : if (*arg > file->inode)
518 0 : return 1;
- 519 987050 : return 0;
+ 519 987099 : return 0;
520 : }
521 :
522 0 : int file_inode_compare(const void* void_a, const void* void_b)
@@ -593,42 +593,42 @@
531 0 : return 0;
532 : }
533 :
- 534 189434 : int file_path_compare(const void* void_a, const void* void_b)
+ 534 189486 : int file_path_compare(const void* void_a, const void* void_b)
535 : {
- 536 189434 : const struct snapraid_file* file_a = void_a;
- 537 189434 : const struct snapraid_file* file_b = void_b;
+ 536 189486 : const struct snapraid_file* file_a = void_a;
+ 537 189486 : const struct snapraid_file* file_b = void_b;
538 :
- 539 189434 : return strcmp(file_a->sub, file_b->sub);
+ 539 189486 : return strcmp(file_a->sub, file_b->sub);
540 : }
541 :
- 542 63430 : int file_physical_compare(const void* void_a, const void* void_b)
+ 542 44202 : int file_physical_compare(const void* void_a, const void* void_b)
543 : {
- 544 63430 : const struct snapraid_file* file_a = void_a;
- 545 63430 : const struct snapraid_file* file_b = void_b;
+ 544 44202 : const struct snapraid_file* file_a = void_a;
+ 545 44202 : const struct snapraid_file* file_b = void_b;
546 :
- 547 63430 : if (file_a->physical < file_b->physical)
- 548 38882 : return -1;
- 549 24548 : if (file_a->physical > file_b->physical)
- 550 24546 : return 1;
+ 547 44202 : if (file_a->physical < file_b->physical)
+ 548 30758 : return -1;
+ 549 13444 : if (file_a->physical > file_b->physical)
+ 550 13442 : return 1;
551 2 : return 0;
552 : }
553 :
- 554 97552 : int file_path_compare_to_arg(const void* void_arg, const void* void_data)
+ 554 97531 : int file_path_compare_to_arg(const void* void_arg, const void* void_data)
555 : {
- 556 97552 : const char* arg = void_arg;
- 557 97552 : const struct snapraid_file* file = void_data;
+ 556 97531 : const char* arg = void_arg;
+ 557 97531 : const struct snapraid_file* file = void_data;
558 :
- 559 97552 : return strcmp(arg, file->sub);
+ 559 97531 : return strcmp(arg, file->sub);
560 : }
561 :
- 562 23977 : int file_name_compare(const void* void_a, const void* void_b)
+ 562 23961 : int file_name_compare(const void* void_a, const void* void_b)
563 : {
- 564 23977 : const struct snapraid_file* file_a = void_a;
- 565 23977 : const struct snapraid_file* file_b = void_b;
- 566 23977 : const char* name_a = file_name(file_a);
- 567 23977 : const char* name_b = file_name(file_b);
+ 564 23961 : const struct snapraid_file* file_a = void_a;
+ 565 23961 : const struct snapraid_file* file_b = void_b;
+ 566 23961 : const char* name_a = file_name(file_a);
+ 567 23961 : const char* name_b = file_name(file_b);
568 :
- 569 23977 : return strcmp(name_a, name_b);
+ 569 23961 : return strcmp(name_a, name_b);
570 : }
571 :
572 23670 : int file_stamp_compare(const void* void_a, const void* void_b)
@@ -654,13 +654,13 @@
592 23670 : return 0;
593 : }
594 :
- 595 23977 : int file_namestamp_compare(const void* void_a, const void* void_b)
+ 595 23961 : int file_namestamp_compare(const void* void_a, const void* void_b)
596 : {
597 : int ret;
598 :
- 599 23977 : ret = file_name_compare(void_a, void_b);
- 600 23977 : if (ret != 0)
- 601 307 : return ret;
+ 599 23961 : ret = file_name_compare(void_a, void_b);
+ 600 23961 : if (ret != 0)
+ 601 291 : return ret;
602 :
603 23670 : return file_stamp_compare(void_a, void_b);
604 : }
@@ -676,66 +676,66 @@
614 0 : return file_stamp_compare(void_a, void_b);
615 : }
616 :
- 617 3735492 : struct snapraid_extent* extent_alloc(block_off_t parity_pos, struct snapraid_file* file, block_off_t file_pos, block_off_t count)
+ 617 3735396 : struct snapraid_extent* extent_alloc(block_off_t parity_pos, struct snapraid_file* file, block_off_t file_pos, block_off_t count)
618 : {
619 : struct snapraid_extent* extent;
620 :
- 621 3735492 : if (count == 0) {
+ 621 3735396 : if (count == 0) {
622 : /* LCOV_EXCL_START */
623 : log_fatal("Internal inconsistency when allocating empty extent for file '%s' at position '%u/%u'\n", file->sub, file_pos, file->blockmax);
624 : os_abort();
625 : /* LCOV_EXCL_STOP */
626 : }
- 627 3735492 : if (file_pos + count > file->blockmax) {
+ 627 3735396 : if (file_pos + count > file->blockmax) {
628 : /* LCOV_EXCL_START */
629 : log_fatal("Internal inconsistency when allocating overflowing extent for file '%s' at position '%u:%u/%u'\n", file->sub, file_pos, count, file->blockmax);
630 : os_abort();
631 : /* LCOV_EXCL_STOP */
632 : }
633 :
- 634 3735492 : extent = malloc_nofail(sizeof(struct snapraid_extent));
- 635 3735492 : extent->parity_pos = parity_pos;
- 636 3735492 : extent->file = file;
- 637 3735492 : extent->file_pos = file_pos;
- 638 3735492 : extent->count = count;
+ 634 3735396 : extent = malloc_nofail(sizeof(struct snapraid_extent));
+ 635 3735396 : extent->parity_pos = parity_pos;
+ 636 3735396 : extent->file = file;
+ 637 3735396 : extent->file_pos = file_pos;
+ 638 3735396 : extent->count = count;
639 :
- 640 3735492 : return extent;
+ 640 3735396 : return extent;
641 : }
642 :
- 643 3564805 : void extent_free(struct snapraid_extent* extent)
+ 643 3564840 : void extent_free(struct snapraid_extent* extent)
644 : {
- 645 3564805 : free(extent);
- 646 3564805 : }
+ 645 3564840 : free(extent);
+ 646 3564840 : }
647 :
- 648 44511012 : int extent_parity_compare(const void* void_a, const void* void_b)
+ 648 44510782 : int extent_parity_compare(const void* void_a, const void* void_b)
649 : {
- 650 44511012 : const struct snapraid_extent* arg_a = void_a;
- 651 44511012 : const struct snapraid_extent* arg_b = void_b;
+ 650 44510782 : const struct snapraid_extent* arg_a = void_a;
+ 651 44510782 : const struct snapraid_extent* arg_b = void_b;
652 :
- 653 44511012 : if (arg_a->parity_pos < arg_b->parity_pos)
- 654 959727 : return -1;
- 655 43551285 : if (arg_a->parity_pos > arg_b->parity_pos)
- 656 43511675 : return 1;
+ 653 44510782 : if (arg_a->parity_pos < arg_b->parity_pos)
+ 654 960328 : return -1;
+ 655 43550454 : if (arg_a->parity_pos > arg_b->parity_pos)
+ 656 43510787 : return 1;
657 :
- 658 39610 : return 0;
+ 658 39667 : return 0;
659 : }
660 :
- 661 45007856 : int extent_file_compare(const void* void_a, const void* void_b)
+ 661 45007274 : int extent_file_compare(const void* void_a, const void* void_b)
662 : {
- 663 45007856 : const struct snapraid_extent* arg_a = void_a;
- 664 45007856 : const struct snapraid_extent* arg_b = void_b;
+ 663 45007274 : const struct snapraid_extent* arg_a = void_a;
+ 664 45007274 : const struct snapraid_extent* arg_b = void_b;
665 :
- 666 45007856 : if (arg_a->file < arg_b->file)
- 667 879576 : return -1;
- 668 44128280 : if (arg_a->file > arg_b->file)
- 669 44057503 : return 1;
+ 666 45007274 : if (arg_a->file < arg_b->file)
+ 667 874179 : return -1;
+ 668 44133095 : if (arg_a->file > arg_b->file)
+ 669 44062303 : return 1;
670 :
- 671 70777 : if (arg_a->file_pos < arg_b->file_pos)
+ 671 70792 : if (arg_a->file_pos < arg_b->file_pos)
672 208 : return -1;
- 673 70569 : if (arg_a->file_pos > arg_b->file_pos)
- 674 30959 : return 1;
+ 673 70584 : if (arg_a->file_pos > arg_b->file_pos)
+ 674 30917 : return 1;
675 :
- 676 39610 : return 0;
+ 676 39667 : return 0;
677 : }
678 :
679 119522 : struct snapraid_link* link_alloc(const char* sub, const char* linkto, unsigned link_flag)
@@ -798,50 +798,50 @@
736 249 : return strcmp(arg, dir->sub);
737 : }
738 :
- 739 1579 : struct snapraid_disk* disk_alloc(const char* name, const char* dir, uint64_t dev, const char* uuid, int skip)
+ 739 1585 : struct snapraid_disk* disk_alloc(const char* name, const char* dir, uint64_t dev, const char* uuid, int skip)
740 : {
741 : struct snapraid_disk* disk;
742 :
- 743 1579 : disk = malloc_nofail(sizeof(struct snapraid_disk));
- 744 1579 : pathcpy(disk->name, sizeof(disk->name), name);
- 745 1579 : pathimport(disk->dir, sizeof(disk->dir), dir);
- 746 1579 : pathcpy(disk->uuid, sizeof(disk->uuid), uuid);
+ 743 1585 : disk = malloc_nofail(sizeof(struct snapraid_disk));
+ 744 1585 : pathcpy(disk->name, sizeof(disk->name), name);
+ 745 1585 : pathimport(disk->dir, sizeof(disk->dir), dir);
+ 746 1585 : pathcpy(disk->uuid, sizeof(disk->uuid), uuid);
747 :
748 : /* ensure that the dir terminate with "/" if it isn't empty */
- 749 1579 : pathslash(disk->dir, sizeof(disk->dir));
+ 749 1585 : pathslash(disk->dir, sizeof(disk->dir));
750 :
751 : #if HAVE_PTHREAD
- 752 1579 : thread_mutex_init(&disk->fs_mutex, 0);
+ 752 1585 : thread_mutex_init(&disk->fs_mutex, 0);
753 : #endif
754 :
- 755 1579 : disk->smartctl[0] = 0;
- 756 1579 : disk->device = dev;
- 757 1579 : disk->tick = 0;
- 758 1579 : disk->cached = 0;
- 759 1579 : disk->total_blocks = 0;
- 760 1579 : disk->free_blocks = 0;
- 761 1579 : disk->first_free_block = 0;
- 762 1579 : disk->has_volatile_inodes = 0;
- 763 1579 : disk->has_unreliable_physical = 0;
- 764 1579 : disk->has_different_uuid = 0;
- 765 1579 : disk->has_unsupported_uuid = *uuid == 0; /* empty UUID means unsupported */
- 766 1579 : disk->had_empty_uuid = 0;
- 767 1579 : disk->mapping_idx = -1;
- 768 1579 : disk->skip_access = skip;
- 769 1579 : tommy_list_init(&disk->filelist);
- 770 1579 : tommy_list_init(&disk->deletedlist);
- 771 1579 : tommy_hashdyn_init(&disk->inodeset);
- 772 1579 : tommy_hashdyn_init(&disk->pathset);
- 773 1579 : tommy_hashdyn_init(&disk->stampset);
- 774 1579 : tommy_list_init(&disk->linklist);
- 775 1579 : tommy_hashdyn_init(&disk->linkset);
- 776 1579 : tommy_list_init(&disk->dirlist);
- 777 1579 : tommy_hashdyn_init(&disk->dirset);
- 778 1579 : tommy_tree_init(&disk->fs_parity, extent_parity_compare);
- 779 1579 : tommy_tree_init(&disk->fs_file, extent_file_compare);
- 780 1579 : disk->fs_last = 0;
+ 755 1585 : disk->smartctl[0] = 0;
+ 756 1585 : disk->device = dev;
+ 757 1585 : disk->tick = 0;
+ 758 1585 : disk->cached = 0;
+ 759 1585 : disk->total_blocks = 0;
+ 760 1585 : disk->free_blocks = 0;
+ 761 1585 : disk->first_free_block = 0;
+ 762 1585 : disk->has_volatile_inodes = 0;
+ 763 1585 : disk->has_unreliable_physical = 0;
+ 764 1585 : disk->has_different_uuid = 0;
+ 765 1585 : disk->has_unsupported_uuid = *uuid == 0; /* empty UUID means unsupported */
+ 766 1585 : disk->had_empty_uuid = 0;
+ 767 1585 : disk->mapping_idx = -1;
+ 768 1585 : disk->skip_access = skip;
+ 769 1585 : tommy_list_init(&disk->filelist);
+ 770 1585 : tommy_list_init(&disk->deletedlist);
+ 771 1585 : tommy_hashdyn_init(&disk->inodeset);
+ 772 1585 : tommy_hashdyn_init(&disk->pathset);
+ 773 1585 : tommy_hashdyn_init(&disk->stampset);
+ 774 1585 : tommy_list_init(&disk->linklist);
+ 775 1585 : tommy_hashdyn_init(&disk->linkset);
+ 776 1585 : tommy_list_init(&disk->dirlist);
+ 777 1585 : tommy_hashdyn_init(&disk->dirset);
+ 778 1585 : tommy_tree_init(&disk->fs_parity, extent_parity_compare);
+ 779 1585 : tommy_tree_init(&disk->fs_file, extent_file_compare);
+ 780 1585 : disk->fs_last = 0;
781 :
- 782 1579 : return disk;
+ 782 1585 : return disk;
783 : }
784 :
785 1453 : void disk_free(struct snapraid_disk* disk)
@@ -864,23 +864,23 @@
802 1453 : free(disk);
803 1453 : }
804 :
- 805 53194369 : static inline void fs_lock(struct snapraid_disk* disk)
+ 805 53196480 : static inline void fs_lock(struct snapraid_disk* disk)
806 : {
807 : #if HAVE_PTHREAD
- 808 53194369 : thread_mutex_lock(&disk->fs_mutex);
+ 808 53196480 : thread_mutex_lock(&disk->fs_mutex);
809 : #else
810 : (void)disk;
811 : #endif
- 812 53194899 : }
+ 812 53197205 : }
813 :
- 814 53193869 : static inline void fs_unlock(struct snapraid_disk* disk)
+ 814 53196096 : static inline void fs_unlock(struct snapraid_disk* disk)
815 : {
816 : #if HAVE_PTHREAD
- 817 53193869 : thread_mutex_unlock(&disk->fs_mutex);
+ 817 53196096 : thread_mutex_unlock(&disk->fs_mutex);
818 : #else
819 : (void)disk;
820 : #endif
- 821 53194703 : }
+ 821 53197239 : }
822 :
823 : struct extent_disk_empty {
824 : block_off_t blockmax;
@@ -937,30 +937,30 @@
875 : *
876 : * The maximum parity position is stored as size.
877 : */
- 878 50483 : static int extent_disk_size_compare_unlock(const void* void_a, const void* void_b)
+ 878 50510 : static int extent_disk_size_compare_unlock(const void* void_a, const void* void_b)
879 : {
- 880 50483 : struct extent_disk_size* arg_a = (void*)void_a;
- 881 50483 : const struct snapraid_extent* arg_b = void_b;
+ 880 50510 : struct extent_disk_size* arg_a = (void*)void_a;
+ 881 50510 : const struct snapraid_extent* arg_b = void_b;
882 :
883 : /* get the maximum size */
- 884 50483 : if (arg_a->size < arg_b->parity_pos + arg_b->count)
- 885 50483 : arg_a->size = arg_b->parity_pos + arg_b->count;
+ 884 50510 : if (arg_a->size < arg_b->parity_pos + arg_b->count)
+ 885 50510 : arg_a->size = arg_b->parity_pos + arg_b->count;
886 :
887 : /* search always for a bigger one */
- 888 50483 : return 1;
+ 888 50510 : return 1;
889 : }
890 :
- 891 4339 : block_off_t fs_size(struct snapraid_disk* disk)
+ 891 4351 : block_off_t fs_size(struct snapraid_disk* disk)
892 : {
- 893 4339 : struct extent_disk_size arg = { 0 };
+ 893 4351 : struct extent_disk_size arg = { 0 };
894 :
- 895 4339 : fs_lock(disk);
+ 895 4351 : fs_lock(disk);
896 :
- 897 4339 : tommy_tree_search_compare(&disk->fs_parity, extent_disk_size_compare_unlock, &arg);
+ 897 4351 : tommy_tree_search_compare(&disk->fs_parity, extent_disk_size_compare_unlock, &arg);
898 :
- 899 4339 : fs_unlock(disk);
+ 899 4351 : fs_unlock(disk);
900 :
- 901 4339 : return arg.size;
+ 901 4351 : return arg.size;
902 : }
903 :
904 : struct extent_check {
@@ -968,23 +968,23 @@
906 : int result;
907 : };
908 :
- 909 6584437 : static void extent_parity_check_foreach_unlock(void* void_arg, void* void_obj)
+ 909 6584417 : static void extent_parity_check_foreach_unlock(void* void_arg, void* void_obj)
910 : {
- 911 6584437 : struct extent_check* arg = void_arg;
- 912 6584437 : const struct snapraid_extent* obj = void_obj;
- 913 6584437 : const struct snapraid_extent* prev = arg->prev;
+ 911 6584417 : struct extent_check* arg = void_arg;
+ 912 6584417 : const struct snapraid_extent* obj = void_obj;
+ 913 6584417 : const struct snapraid_extent* prev = arg->prev;
914 :
915 : /* set the next previous block */
- 916 6584437 : arg->prev = obj;
+ 916 6584417 : arg->prev = obj;
917 :
918 : /* stop reporting if too many errors */
- 919 6584437 : if (arg->result > 100) {
+ 919 6584417 : if (arg->result > 100) {
920 : /* LCOV_EXCL_START */
921 : return;
922 : /* LCOV_EXCL_STOP */
923 : }
924 :
- 925 6584437 : if (obj->count == 0) {
+ 925 6584417 : if (obj->count == 0) {
926 : /* LCOV_EXCL_START */
927 : log_fatal("Internal inconsistency in parity count zero for file '%s' at '%u'\n",
928 : obj->file->sub, obj->parity_pos);
@@ -994,11 +994,11 @@
932 : }
933 :
934 : /* check only if there is a previous block */
- 935 6584437 : if (!prev)
- 936 2708 : return;
+ 935 6584417 : if (!prev)
+ 936 2718 : return;
937 :
938 : /* check the order */
- 939 6581729 : if (prev->parity_pos >= obj->parity_pos) {
+ 939 6581699 : if (prev->parity_pos >= obj->parity_pos) {
940 : /* LCOV_EXCL_START */
941 : log_fatal("Internal inconsistency in parity order for files '%s' at '%u:%u' and '%s' at '%u:%u'\n",
942 : prev->file->sub, prev->parity_pos, prev->count, obj->file->sub, obj->parity_pos, obj->count);
@@ -1008,7 +1008,7 @@
946 : }
947 :
948 : /* check that the extents don't overlap */
- 949 6581729 : if (prev->parity_pos + prev->count > obj->parity_pos) {
+ 949 6581699 : if (prev->parity_pos + prev->count > obj->parity_pos) {
950 : /* LCOV_EXCL_START */
951 : log_fatal("Internal inconsistency for parity overlap for files '%s' at '%u:%u' and '%s' at '%u:%u'\n",
952 : prev->file->sub, prev->parity_pos, prev->count, obj->file->sub, obj->parity_pos, obj->count);
@@ -1018,23 +1018,23 @@
956 : }
957 : }
958 :
- 959 6584437 : static void extent_file_check_foreach_unlock(void* void_arg, void* void_obj)
+ 959 6584417 : static void extent_file_check_foreach_unlock(void* void_arg, void* void_obj)
960 : {
- 961 6584437 : struct extent_check* arg = void_arg;
- 962 6584437 : const struct snapraid_extent* obj = void_obj;
- 963 6584437 : const struct snapraid_extent* prev = arg->prev;
+ 961 6584417 : struct extent_check* arg = void_arg;
+ 962 6584417 : const struct snapraid_extent* obj = void_obj;
+ 963 6584417 : const struct snapraid_extent* prev = arg->prev;
964 :
965 : /* set the next previous block */
- 966 6584437 : arg->prev = obj;
+ 966 6584417 : arg->prev = obj;
967 :
968 : /* stop reporting if too many errors */
- 969 6584437 : if (arg->result > 100) {
+ 969 6584417 : if (arg->result > 100) {
970 : /* LCOV_EXCL_START */
971 : return;
972 : /* LCOV_EXCL_STOP */
973 : }
974 :
- 975 6584437 : if (obj->count == 0) {
+ 975 6584417 : if (obj->count == 0) {
976 : /* LCOV_EXCL_START */
977 : log_fatal("Internal inconsistency in file count zero for file '%s' at '%u'\n",
978 : obj->file->sub, obj->file_pos);
@@ -1046,9 +1046,9 @@
984 : /* note that for deleted files, some extents may be missing */
985 :
986 : /* if the files are different */
- 987 6584437 : if (!prev || prev->file != obj->file) {
- 988 6538233 : if (prev != 0) {
- 989 6535525 : if (file_flag_has(prev->file, FILE_IS_DELETED)) {
+ 987 6584417 : if (!prev || prev->file != obj->file) {
+ 988 6538257 : if (prev != 0) {
+ 989 6535539 : if (file_flag_has(prev->file, FILE_IS_DELETED)) {
990 : /* check that the extent doesn't overflow the file */
991 59759 : if (prev->file_pos + prev->count > prev->file->blockmax) {
992 : /* LCOV_EXCL_START */
@@ -1060,7 +1060,7 @@
998 : }
999 : } else {
1000 : /* check that the extent ends the file */
- 1001 6475766 : if (prev->file_pos + prev->count != prev->file->blockmax) {
+ 1001 6475780 : if (prev->file_pos + prev->count != prev->file->blockmax) {
1002 : /* LCOV_EXCL_START */
1003 : log_fatal("Internal inconsistency in file end for file '%s' at '%u:%u' instead of size '%u'\n",
1004 : prev->file->sub, prev->file_pos, prev->count, prev->file->blockmax);
@@ -1071,7 +1071,7 @@
1009 : }
1010 : }
1011 :
- 1012 13076466 : if (file_flag_has(obj->file, FILE_IS_DELETED)) {
+ 1012 13076514 : if (file_flag_has(obj->file, FILE_IS_DELETED)) {
1013 : /* check that the extent doesn't overflow the file */
1014 59842 : if (obj->file_pos + obj->count > obj->file->blockmax) {
1015 : /* LCOV_EXCL_START */
@@ -1083,7 +1083,7 @@
1021 : }
1022 : } else {
1023 : /* check that the extent starts the file */
- 1024 6478391 : if (obj->file_pos != 0) {
+ 1024 6478415 : if (obj->file_pos != 0) {
1025 : /* LCOV_EXCL_START */
1026 : log_fatal("Internal inconsistency in file start for file '%s' at '%u:%u'\n",
1027 : obj->file->sub, obj->file_pos, obj->count);
@@ -1094,7 +1094,7 @@
1032 : }
1033 : } else {
1034 : /* check the order */
- 1035 46204 : if (prev->file_pos >= obj->file_pos) {
+ 1035 46160 : if (prev->file_pos >= obj->file_pos) {
1036 : /* LCOV_EXCL_START */
1037 : log_fatal("Internal inconsistency in file order for file '%s' at '%u:%u' and at '%u:%u'\n",
1038 : prev->file->sub, prev->file_pos, prev->count, obj->file_pos, obj->count);
@@ -1103,7 +1103,7 @@
1041 : /* LCOV_EXCL_STOP */
1042 : }
1043 :
- 1044 46204 : if (file_flag_has(obj->file, FILE_IS_DELETED)) {
+ 1044 46160 : if (file_flag_has(obj->file, FILE_IS_DELETED)) {
1045 : /* check that the extents don't overlap */
1046 27 : if (prev->file_pos + prev->count > obj->file_pos) {
1047 : /* LCOV_EXCL_START */
@@ -1115,7 +1115,7 @@
1053 : }
1054 : } else {
1055 : /* check that the extents are sequential */
- 1056 46177 : if (prev->file_pos + prev->count != obj->file_pos) {
+ 1056 46133 : if (prev->file_pos + prev->count != obj->file_pos) {
1057 : /* LCOV_EXCL_START */
1058 : log_fatal("Internal inconsistency in file sequence for file '%s' at '%u:%u' and at '%u:%u'\n",
1059 : prev->file->sub, prev->file_pos, prev->count, obj->file_pos, obj->count);
@@ -1127,29 +1127,29 @@
1065 : }
1066 : }
1067 :
- 1068 2970 : int fs_check(struct snapraid_disk* disk)
+ 1068 2982 : int fs_check(struct snapraid_disk* disk)
1069 : {
1070 : struct extent_check arg;
1071 :
1072 : /* error count starts from 0 */
- 1073 2970 : arg.result = 0;
+ 1073 2982 : arg.result = 0;
1074 :
- 1075 2970 : fs_lock(disk);
+ 1075 2982 : fs_lock(disk);
1076 :
1077 : /* check parity sequence */
- 1078 2970 : arg.prev = 0;
- 1079 2970 : tommy_tree_foreach_arg(&disk->fs_parity, extent_parity_check_foreach_unlock, &arg);
+ 1078 2982 : arg.prev = 0;
+ 1079 2982 : tommy_tree_foreach_arg(&disk->fs_parity, extent_parity_check_foreach_unlock, &arg);
1080 :
1081 : /* check file sequence */
- 1082 2970 : arg.prev = 0;
- 1083 2970 : tommy_tree_foreach_arg(&disk->fs_file, extent_file_check_foreach_unlock, &arg);
+ 1082 2982 : arg.prev = 0;
+ 1083 2982 : tommy_tree_foreach_arg(&disk->fs_file, extent_file_check_foreach_unlock, &arg);
1084 :
- 1085 2970 : fs_unlock(disk);
+ 1085 2982 : fs_unlock(disk);
1086 :
- 1087 2970 : if (arg.result != 0)
+ 1087 2982 : if (arg.result != 0)
1088 0 : return -1;
1089 :
- 1090 2970 : return 0;
+ 1090 2982 : return 0;
1091 : }
1092 :
1093 : struct extent_parity_inside {
@@ -1159,17 +1159,17 @@
1097 : /**
1098 : * Compare the extent if containing the specified parity position.
1099 : */
- 1100 113816358 : static int extent_parity_inside_compare_unlock(const void* void_a, const void* void_b)
+ 1100 113835807 : static int extent_parity_inside_compare_unlock(const void* void_a, const void* void_b)
1101 : {
- 1102 113816358 : const struct extent_parity_inside* arg_a = void_a;
- 1103 113816358 : const struct snapraid_extent* arg_b = void_b;
+ 1102 113835807 : const struct extent_parity_inside* arg_a = void_a;
+ 1103 113835807 : const struct snapraid_extent* arg_b = void_b;
1104 :
- 1105 113816358 : if (arg_a->parity_pos < arg_b->parity_pos)
- 1106 40236710 : return -1;
- 1107 73579648 : if (arg_a->parity_pos >= arg_b->parity_pos + arg_b->count)
- 1108 64869306 : return 1;
+ 1105 113835807 : if (arg_a->parity_pos < arg_b->parity_pos)
+ 1106 40242517 : return -1;
+ 1107 73593290 : if (arg_a->parity_pos >= arg_b->parity_pos + arg_b->count)
+ 1108 64881921 : return 1;
1109 :
- 1110 8710342 : return 0;
+ 1110 8711369 : return 0;
1111 : }
1112 :
1113 : /**
@@ -1177,28 +1177,28 @@
1115 : * The search is optimized for sequential accesses.
1116 : * \return If not found return 0
1117 : */
- 1118 39142093 : static struct snapraid_extent* fs_par2extent_get_unlock(struct snapraid_disk* disk, struct snapraid_extent** fs_last, block_off_t parity_pos)
+ 1118 39144459 : static struct snapraid_extent* fs_par2extent_get_unlock(struct snapraid_disk* disk, struct snapraid_extent** fs_last, block_off_t parity_pos)
1119 : {
1120 : struct snapraid_extent* extent;
1121 :
1122 : /* check if the last accessed extent matches */
- 1123 39142093 : if (*fs_last
- 1124 39123712 : && parity_pos >= (*fs_last)->parity_pos
- 1125 38405576 : && parity_pos < (*fs_last)->parity_pos + (*fs_last)->count
+ 1123 39144459 : if (*fs_last
+ 1124 39126053 : && parity_pos >= (*fs_last)->parity_pos
+ 1125 38409539 : && parity_pos < (*fs_last)->parity_pos + (*fs_last)->count
1126 : ) {
- 1127 28847581 : extent = *fs_last;
+ 1127 28848823 : extent = *fs_last;
1128 : } else {
- 1129 10294512 : struct extent_parity_inside arg = { parity_pos };
- 1130 10294512 : extent = tommy_tree_search_compare(&disk->fs_parity, extent_parity_inside_compare_unlock, &arg);
+ 1129 10295636 : struct extent_parity_inside arg = { parity_pos };
+ 1130 10295636 : extent = tommy_tree_search_compare(&disk->fs_parity, extent_parity_inside_compare_unlock, &arg);
1131 : }
1132 :
- 1133 39141955 : if (!extent)
- 1134 1584132 : return 0;
+ 1133 39144338 : if (!extent)
+ 1134 1584242 : return 0;
1135 :
1136 : /* store the last accessed extent */
- 1137 37557823 : *fs_last = extent;
+ 1137 37560096 : *fs_last = extent;
1138 :
- 1139 37557823 : return extent;
+ 1139 37560096 : return extent;
1140 : }
1141 :
1142 : struct extent_file_inside {
@@ -1209,22 +1209,22 @@
1147 : /**
1148 : * Compare the extent if containing the specified file position.
1149 : */
- 1150 21314053 : static int extent_file_inside_compare_unlock(const void* void_a, const void* void_b)
+ 1150 21310663 : static int extent_file_inside_compare_unlock(const void* void_a, const void* void_b)
1151 : {
- 1152 21314053 : const struct extent_file_inside* arg_a = void_a;
- 1153 21314053 : const struct snapraid_extent* arg_b = void_b;
+ 1152 21310663 : const struct extent_file_inside* arg_a = void_a;
+ 1153 21310663 : const struct snapraid_extent* arg_b = void_b;
1154 :
- 1155 21314053 : if (arg_a->file < arg_b->file)
- 1156 8882877 : return -1;
- 1157 12431176 : if (arg_a->file > arg_b->file)
- 1158 10411547 : return 1;
+ 1155 21310663 : if (arg_a->file < arg_b->file)
+ 1156 8886240 : return -1;
+ 1157 12424423 : if (arg_a->file > arg_b->file)
+ 1158 10404719 : return 1;
1159 :
- 1160 2019629 : if (arg_a->file_pos < arg_b->file_pos)
- 1161 8339 : return -1;
- 1162 2011290 : if (arg_a->file_pos >= arg_b->file_pos + arg_b->count)
- 1163 7952 : return 1;
+ 1160 2019704 : if (arg_a->file_pos < arg_b->file_pos)
+ 1161 8320 : return -1;
+ 1162 2011384 : if (arg_a->file_pos >= arg_b->file_pos + arg_b->count)
+ 1163 7938 : return 1;
1164 :
- 1165 2003338 : return 0;
+ 1165 2003446 : return 0;
1166 : }
1167 :
1168 : /**
@@ -1232,88 +1232,88 @@
1170 : * The search is optimized for sequential accesses.
1171 : * \return If not found return 0
1172 : */
- 1173 10336325 : static struct snapraid_extent* fs_file2extent_get_unlock(struct snapraid_disk* disk, struct snapraid_extent** fs_last, struct snapraid_file* file, block_off_t file_pos)
+ 1173 10336351 : static struct snapraid_extent* fs_file2extent_get_unlock(struct snapraid_disk* disk, struct snapraid_extent** fs_last, struct snapraid_file* file, block_off_t file_pos)
1174 : {
1175 : struct snapraid_extent* extent;
1176 :
1177 : /* check if the last accessed extent matches */
- 1178 10336325 : if (*fs_last
- 1179 10312676 : && file == (*fs_last)->file
- 1180 8347214 : && file_pos >= (*fs_last)->file_pos
- 1181 8347214 : && file_pos < (*fs_last)->file_pos + (*fs_last)->count
+ 1178 10336351 : if (*fs_last
+ 1179 10312659 : && file == (*fs_last)->file
+ 1180 8347111 : && file_pos >= (*fs_last)->file_pos
+ 1181 8347111 : && file_pos < (*fs_last)->file_pos + (*fs_last)->count
1182 : ) {
- 1183 8332979 : extent = *fs_last;
+ 1183 8332897 : extent = *fs_last;
1184 : } else {
- 1185 2003346 : struct extent_file_inside arg = { file, file_pos };
- 1186 2003346 : extent = tommy_tree_search_compare(&disk->fs_file, extent_file_inside_compare_unlock, &arg);
+ 1185 2003454 : struct extent_file_inside arg = { file, file_pos };
+ 1186 2003454 : extent = tommy_tree_search_compare(&disk->fs_file, extent_file_inside_compare_unlock, &arg);
1187 : }
1188 :
- 1189 10336325 : if (!extent)
+ 1189 10336351 : if (!extent)
1190 8 : return 0;
1191 :
1192 : /* store the last accessed extent */
- 1193 10336317 : *fs_last = extent;
+ 1193 10336343 : *fs_last = extent;
1194 :
- 1195 10336317 : return extent;
+ 1195 10336343 : return extent;
1196 : }
1197 :
- 1198 39035232 : struct snapraid_file* fs_par2file_find(struct snapraid_disk* disk, block_off_t parity_pos, block_off_t* file_pos)
+ 1198 39037806 : struct snapraid_file* fs_par2file_find(struct snapraid_disk* disk, block_off_t parity_pos, block_off_t* file_pos)
1199 : {
1200 : struct snapraid_extent* extent;
1201 : struct snapraid_file* file;
1202 :
- 1203 39035232 : fs_lock(disk);
+ 1203 39037806 : fs_lock(disk);
1204 :
- 1205 39036374 : extent = fs_par2extent_get_unlock(disk, &disk->fs_last, parity_pos);
+ 1205 39038558 : extent = fs_par2extent_get_unlock(disk, &disk->fs_last, parity_pos);
1206 :
- 1207 39035521 : if (!extent) {
- 1208 1584134 : fs_unlock(disk);
- 1209 1584150 : return 0;
+ 1207 39037687 : if (!extent) {
+ 1208 1584243 : fs_unlock(disk);
+ 1209 1584263 : return 0;
1210 : }
1211 :
- 1212 37451387 : if (file_pos)
- 1213 37106669 : *file_pos = extent->file_pos + (parity_pos - extent->parity_pos);
+ 1212 37453444 : if (file_pos)
+ 1213 37108755 : *file_pos = extent->file_pos + (parity_pos - extent->parity_pos);
1214 :
- 1215 37451387 : file = extent->file;
+ 1215 37453444 : file = extent->file;
1216 :
- 1217 37451387 : fs_unlock(disk);
- 1218 37452141 : return file;
+ 1217 37453444 : fs_unlock(disk);
+ 1218 37454270 : return file;
1219 : }
1220 :
- 1221 4869535 : block_off_t fs_file2par_find(struct snapraid_disk* disk, struct snapraid_file* file, block_off_t file_pos)
+ 1221 4869582 : block_off_t fs_file2par_find(struct snapraid_disk* disk, struct snapraid_file* file, block_off_t file_pos)
1222 : {
1223 : struct snapraid_extent* extent;
1224 : block_off_t ret;
1225 :
- 1226 4869535 : fs_lock(disk);
+ 1226 4869582 : fs_lock(disk);
1227 :
- 1228 4869535 : extent = fs_file2extent_get_unlock(disk, &disk->fs_last, file, file_pos);
- 1229 4869535 : if (!extent) {
+ 1228 4869582 : extent = fs_file2extent_get_unlock(disk, &disk->fs_last, file, file_pos);
+ 1229 4869582 : if (!extent) {
1230 8 : fs_unlock(disk);
1231 8 : return POS_NULL;
1232 : }
1233 :
- 1234 4869527 : ret = extent->parity_pos + (file_pos - extent->file_pos);
+ 1234 4869574 : ret = extent->parity_pos + (file_pos - extent->file_pos);
1235 :
- 1236 4869527 : fs_unlock(disk);
- 1237 4869527 : return ret;
+ 1236 4869574 : fs_unlock(disk);
+ 1237 4869574 : return ret;
1238 : }
1239 :
- 1240 9175619 : void fs_allocate(struct snapraid_disk* disk, block_off_t parity_pos, struct snapraid_file* file, block_off_t file_pos)
+ 1240 9175524 : void fs_allocate(struct snapraid_disk* disk, block_off_t parity_pos, struct snapraid_file* file, block_off_t file_pos)
1241 : {
1242 : struct snapraid_extent* extent;
1243 : struct snapraid_extent* parity_extent;
1244 : struct snapraid_extent* file_extent;
1245 :
- 1246 9175619 : fs_lock(disk);
+ 1246 9175524 : fs_lock(disk);
1247 :
- 1248 9175619 : if (file_pos > 0) {
+ 1248 9175524 : if (file_pos > 0) {
1249 : /* search an existing extent for the previous file_pos */
- 1250 5466790 : extent = fs_file2extent_get_unlock(disk, &disk->fs_last, file, file_pos - 1);
+ 1250 5466769 : extent = fs_file2extent_get_unlock(disk, &disk->fs_last, file, file_pos - 1);
1251 :
- 1252 5466790 : if (extent != 0 && parity_pos == extent->parity_pos + extent->count) {
+ 1252 5466769 : if (extent != 0 && parity_pos == extent->parity_pos + extent->count) {
1253 : /* ensure that we are extending the extent at the end */
- 1254 5440128 : if (file_pos != extent->file_pos + extent->count) {
+ 1254 5440129 : if (file_pos != extent->file_pos + extent->count) {
1255 : /* LCOV_EXCL_START */
1256 : log_fatal("Internal inconsistency when allocating file '%s' at position '%u/%u' in the middle of extent '%u:%u' in disk '%s'\n", file->sub, file_pos, file->blockmax, extent->file_pos, extent->count, disk->name);
1257 : os_abort();
@@ -1321,21 +1321,21 @@
1259 : }
1260 :
1261 : /* extend the existing extent */
- 1262 5440128 : ++extent->count;
+ 1262 5440129 : ++extent->count;
1263 :
- 1264 5440128 : fs_unlock(disk);
- 1265 14615747 : return;
+ 1264 5440129 : fs_unlock(disk);
+ 1265 14615653 : return;
1266 : }
1267 : }
1268 :
1269 : /* a extent doesn't exist, and we have to create a new one */
- 1270 3735491 : extent = extent_alloc(parity_pos, file, file_pos, 1);
+ 1270 3735395 : extent = extent_alloc(parity_pos, file, file_pos, 1);
1271 :
1272 : /* insert the extent in the trees */
- 1273 3735491 : parity_extent = tommy_tree_insert(&disk->fs_parity, &extent->parity_node, extent);
- 1274 3735491 : file_extent = tommy_tree_insert(&disk->fs_file, &extent->file_node, extent);
+ 1273 3735395 : parity_extent = tommy_tree_insert(&disk->fs_parity, &extent->parity_node, extent);
+ 1274 3735395 : file_extent = tommy_tree_insert(&disk->fs_file, &extent->file_node, extent);
1275 :
- 1276 3735491 : if (parity_extent != extent || file_extent != extent) {
+ 1276 3735395 : if (parity_extent != extent || file_extent != extent) {
1277 : /* LCOV_EXCL_START */
1278 : log_fatal("Internal inconsistency when allocating file '%s' at position '%u/%u' for existing extent '%u:%u' in disk '%s'\n", file->sub, file_pos, file->blockmax, extent->file_pos, extent->count, disk->name);
1279 : os_abort();
@@ -1343,12 +1343,12 @@
1281 : }
1282 :
1283 : /* store the last accessed extent */
- 1284 3735491 : disk->fs_last = extent;
+ 1284 3735395 : disk->fs_last = extent;
1285 :
- 1286 3735491 : fs_unlock(disk);
+ 1286 3735395 : fs_unlock(disk);
1287 : }
1288 :
- 1289 106126 : void fs_deallocate(struct snapraid_disk* disk, block_off_t parity_pos)
+ 1289 106308 : void fs_deallocate(struct snapraid_disk* disk, block_off_t parity_pos)
1290 : {
1291 : struct snapraid_extent* extent;
1292 : struct snapraid_extent* second_extent;
@@ -1356,10 +1356,10 @@
1294 : struct snapraid_extent* file_extent;
1295 : block_off_t first_count, second_count;
1296 :
- 1297 106126 : fs_lock(disk);
+ 1297 106308 : fs_lock(disk);
1298 :
- 1299 106126 : extent = fs_par2extent_get_unlock(disk, &disk->fs_last, parity_pos);
- 1300 106126 : if (!extent) {
+ 1299 106308 : extent = fs_par2extent_get_unlock(disk, &disk->fs_last, parity_pos);
+ 1300 106308 : if (!extent) {
1301 : /* LCOV_EXCL_START */
1302 : log_fatal("Internal inconsistency when deallocating parity position '%u' for not existing extent in disk '%s'\n", parity_pos, disk->name);
1303 : os_abort();
@@ -1367,29 +1367,29 @@
1305 : }
1306 :
1307 : /* if it's the only block of the extent, delete it */
- 1308 106126 : if (extent->count == 1) {
+ 1308 106308 : if (extent->count == 1) {
1309 : /* remove from the trees */
- 1310 39610 : tommy_tree_remove(&disk->fs_parity, extent);
- 1311 39610 : tommy_tree_remove(&disk->fs_file, extent);
+ 1310 39667 : tommy_tree_remove(&disk->fs_parity, extent);
+ 1311 39667 : tommy_tree_remove(&disk->fs_file, extent);
1312 :
1313 : /* deallocate */
- 1314 39610 : extent_free(extent);
+ 1314 39667 : extent_free(extent);
1315 :
1316 : /* clear the last accessed extent */
- 1317 39610 : disk->fs_last = 0;
+ 1317 39667 : disk->fs_last = 0;
1318 :
- 1319 39610 : fs_unlock(disk);
- 1320 39610 : return;
+ 1319 39667 : fs_unlock(disk);
+ 1320 39667 : return;
1321 : }
1322 :
1323 : /* if it's at the start of the extent, shrink the extent */
- 1324 66516 : if (parity_pos == extent->parity_pos) {
- 1325 66514 : ++extent->parity_pos;
- 1326 66514 : ++extent->file_pos;
- 1327 66514 : --extent->count;
+ 1324 66641 : if (parity_pos == extent->parity_pos) {
+ 1325 66639 : ++extent->parity_pos;
+ 1326 66639 : ++extent->file_pos;
+ 1327 66639 : --extent->count;
1328 :
- 1329 66514 : fs_unlock(disk);
- 1330 66514 : return;
+ 1329 66639 : fs_unlock(disk);
+ 1330 66639 : return;
1331 : }
1332 :
1333 : /* if it's at the end of the extent, shrink the extent */
@@ -1427,42 +1427,42 @@
1365 1 : fs_unlock(disk);
1366 : }
1367 :
- 1368 44945080 : struct snapraid_block* fs_file2block_get(struct snapraid_file* file, block_off_t file_pos)
+ 1368 44946613 : struct snapraid_block* fs_file2block_get(struct snapraid_file* file, block_off_t file_pos)
1369 : {
- 1370 44945080 : if (file_pos >= file->blockmax) {
+ 1370 44946613 : if (file_pos >= file->blockmax) {
1371 : /* LCOV_EXCL_START */
1372 : log_fatal("Internal inconsistency when dereferencing file '%s' at position '%u/%u'\n", file->sub, file_pos, file->blockmax);
1373 : os_abort();
1374 : /* LCOV_EXCL_STOP */
1375 : }
1376 :
- 1377 44945080 : return file_block(file, file_pos);
+ 1377 44946613 : return file_block(file, file_pos);
1378 : }
1379 :
- 1380 27312315 : struct snapraid_block* fs_par2block_find(struct snapraid_disk* disk, block_off_t parity_pos)
+ 1380 27314040 : struct snapraid_block* fs_par2block_find(struct snapraid_disk* disk, block_off_t parity_pos)
1381 : {
1382 : struct snapraid_file* file;
1383 : block_off_t file_pos;
1384 :
- 1385 27312315 : file = fs_par2file_find(disk, parity_pos, &file_pos);
- 1386 27312544 : if (file == 0)
- 1387 1584149 : return BLOCK_NULL;
+ 1385 27314040 : file = fs_par2file_find(disk, parity_pos, &file_pos);
+ 1386 27314201 : if (file == 0)
+ 1387 1584227 : return BLOCK_NULL;
1388 :
- 1389 25728395 : return fs_file2block_get(file, file_pos);
+ 1389 25729974 : return fs_file2block_get(file, file_pos);
1390 : }
1391 :
- 1392 1549 : struct snapraid_map* map_alloc(const char* name, unsigned position, block_off_t total_blocks, block_off_t free_blocks, const char* uuid)
+ 1392 1555 : struct snapraid_map* map_alloc(const char* name, unsigned position, block_off_t total_blocks, block_off_t free_blocks, const char* uuid)
1393 : {
1394 : struct snapraid_map* map;
1395 :
- 1396 1549 : map = malloc_nofail(sizeof(struct snapraid_map));
- 1397 1549 : pathcpy(map->name, sizeof(map->name), name);
- 1398 1549 : map->position = position;
- 1399 1549 : map->total_blocks = total_blocks;
- 1400 1549 : map->free_blocks = free_blocks;
- 1401 1549 : pathcpy(map->uuid, sizeof(map->uuid), uuid);
+ 1396 1555 : map = malloc_nofail(sizeof(struct snapraid_map));
+ 1397 1555 : pathcpy(map->name, sizeof(map->name), name);
+ 1398 1555 : map->position = position;
+ 1399 1555 : map->total_blocks = total_blocks;
+ 1400 1555 : map->free_blocks = free_blocks;
+ 1401 1555 : pathcpy(map->uuid, sizeof(map->uuid), uuid);
1402 :
- 1403 1549 : return map;
+ 1403 1555 : return map;
1404 : }
1405 :
1406 1429 : void map_free(struct snapraid_map* map)
@@ -1470,16 +1470,16 @@
1408 1429 : free(map);
1409 1429 : }
1410 :
- 1411 684987 : int time_compare(const void* void_a, const void* void_b)
+ 1411 684203 : int time_compare(const void* void_a, const void* void_b)
1412 : {
- 1413 684987 : const time_t* time_a = void_a;
- 1414 684987 : const time_t* time_b = void_b;
+ 1413 684203 : const time_t* time_a = void_a;
+ 1414 684203 : const time_t* time_b = void_b;
1415 :
- 1416 684987 : if (*time_a < *time_b)
- 1417 16532 : return -1;
- 1418 668455 : if (*time_a > *time_b)
- 1419 119824 : return 1;
- 1420 548631 : return 0;
+ 1416 684203 : if (*time_a < *time_b)
+ 1417 16620 : return -1;
+ 1418 667583 : if (*time_a > *time_b)
+ 1419 119940 : return 1;
+ 1420 547643 : return 0;
1421 : }
1422 :
1423 : /****************************************************************************/
@@ -1499,14 +1499,14 @@
1437 : /**
1438 : * Format a path name for terminal reference
1439 : */
- 1440 356004 : const char* fmt_term(const struct snapraid_disk* disk, const char* str, char* buffer)
+ 1440 356075 : const char* fmt_term(const struct snapraid_disk* disk, const char* str, char* buffer)
1441 : {
1442 : const char* out[3];
1443 :
- 1444 356004 : switch (FMT_MODE) {
+ 1444 356075 : switch (FMT_MODE) {
1445 : case FMT_FILE :
1446 : default :
- 1447 331944 : return esc_shell(str, buffer);
+ 1447 332015 : return esc_shell(str, buffer);
1448 : case FMT_DISK :
1449 12030 : out[0] = disk->name;
1450 12030 : out[1] = ":";
diff --git a/cov/cmdline/elem.h.func-sort-c.html b/cov/cmdline/elem.h.func-sort-c.html
index 6462c4b2..3a1b0405 100644
--- a/cov/cmdline/elem.h.func-sort-c.html
+++ b/cov/cmdline/elem.h.func-sort-c.html
@@ -61,99 +61,99 @@
| block_sizeof |
- 58065323 |
+ 58066767 |
| file_block |
- 54351240 |
+ 54352792 |
| block_state_get |
- 52304798 |
+ 52307392 |
| file_flag_has |
- 34094547 |
+ 34094426 |
| block_state_set |
- 19117787 |
+ 19118268 |
| block_has_file |
- 14590544 |
+ 14591728 |
| block_has_invalid_parity |
- 12320061 |
+ 12320606 |
| fs_par2file_get |
- 11723736 |
+ 11723986 |
| hash_invalid_set |
- 9234472 |
+ 9234413 |
| file_stamp_hash |
- 6275914 |
+ 6275808 |
| file_flag_set |
- 5301349 |
+ 5301067 |
| info_get |
- 5098374 |
+ 5098627 |
| file_inode_hash |
- 5047846 |
+ 5047758 |
| fs_file2par_get |
- 4755380 |
+ 4755371 |
| file_path_hash |
- 3886074 |
+ 3885977 |
| filter_hidden |
- 3173124 |
+ 3173351 |
| block_has_past_hash |
- 2542743 |
+ 2542370 |
| block_has_updated_hash |
- 2217692 |
+ 2218141 |
| info_get_rehash |
- 2046653 |
+ 2046724 |
| info_set |
- 1697965 |
+ 1698098 |
| info_get_time |
- 883104 |
+ 883015 |
| hash_is_zero |
- 760617 |
+ 760471 |
| hash_is_invalid |
- 759156 |
+ 759009 |
| info_get_bad |
- 351943 |
+ 351958 |
| block_has_file_and_valid_parity |
@@ -161,11 +161,11 @@
| link_flag_has |
- 209329 |
+ 209328 |
| info_make |
- 194583 |
+ 194355 |
| link_name_hash |
@@ -181,11 +181,11 @@
| info_get_justsynced |
- 68535 |
+ 68446 |
| hash_is_unique |
- 44219 |
+ 44333 |
| link_flag_set |
@@ -193,7 +193,7 @@
| file_flag_clear |
- 16739 |
+ 16745 |
| fs_par2block_get |
diff --git a/cov/cmdline/elem.h.func.html b/cov/cmdline/elem.h.func.html
index db662b11..3407ad88 100644
--- a/cov/cmdline/elem.h.func.html
+++ b/cov/cmdline/elem.h.func.html
@@ -61,7 +61,7 @@
| block_has_file |
- 14590544 |
+ 14591728 |
| block_has_file_and_valid_parity |
@@ -69,27 +69,27 @@
| block_has_invalid_parity |
- 12320061 |
+ 12320606 |
| block_has_past_hash |
- 2542743 |
+ 2542370 |
| block_has_updated_hash |
- 2217692 |
+ 2218141 |
| block_sizeof |
- 58065323 |
+ 58066767 |
| block_state_get |
- 52304798 |
+ 52307392 |
| block_state_set |
- 19117787 |
+ 19118268 |
| dir_flag_has |
@@ -105,39 +105,39 @@
| file_block |
- 54351240 |
+ 54352792 |
| file_flag_clear |
- 16739 |
+ 16745 |
| file_flag_has |
- 34094547 |
+ 34094426 |
| file_flag_set |
- 5301349 |
+ 5301067 |
| file_inode_hash |
- 5047846 |
+ 5047758 |
| file_path_hash |
- 3886074 |
+ 3885977 |
| file_stamp_hash |
- 6275914 |
+ 6275808 |
| filter_hidden |
- 3173124 |
+ 3173351 |
| fs_file2par_get |
- 4755380 |
+ 4755371 |
| fs_par2block_get |
@@ -145,23 +145,23 @@
| fs_par2file_get |
- 11723736 |
+ 11723986 |
| hash_invalid_set |
- 9234472 |
+ 9234413 |
| hash_is_invalid |
- 759156 |
+ 759009 |
| hash_is_unique |
- 44219 |
+ 44333 |
| hash_is_zero |
- 760617 |
+ 760471 |
| hash_zero_set |
@@ -169,31 +169,31 @@
| info_get |
- 5098374 |
+ 5098627 |
| info_get_bad |
- 351943 |
+ 351958 |
| info_get_justsynced |
- 68535 |
+ 68446 |
| info_get_rehash |
- 2046653 |
+ 2046724 |
| info_get_time |
- 883104 |
+ 883015 |
| info_make |
- 194583 |
+ 194355 |
| info_set |
- 1697965 |
+ 1698098 |
| info_set_bad |
@@ -209,7 +209,7 @@
| link_flag_has |
- 209329 |
+ 209328 |
| link_flag_let |
diff --git a/cov/cmdline/elem.h.gcov.html b/cov/cmdline/elem.h.gcov.html
index 724a4396..d182c9e5 100644
--- a/cov/cmdline/elem.h.gcov.html
+++ b/cov/cmdline/elem.h.gcov.html
@@ -571,13 +571,13 @@
509 : * Filter hidden files.
510 : * Return !=0 if it matches and it should be excluded.
511 : */
- 512 3173124 : static inline int filter_hidden(int enable, struct dirent* dd)
+ 512 3173351 : static inline int filter_hidden(int enable, struct dirent* dd)
513 : {
- 514 3173124 : if (enable && dirent_hidden(dd)) {
+ 514 3173351 : if (enable && dirent_hidden(dd)) {
515 0 : return 1; /* filter out */
516 : }
517 :
- 518 3173124 : return 0;
+ 518 3173351 : return 0;
519 : }
520 :
521 : /**
@@ -628,19 +628,19 @@
566 : *
567 : * If working with reduced hash lengths, this function always return 0.
568 : */
- 569 759156 : static inline int hash_is_invalid(const unsigned char* hash)
+ 569 759009 : static inline int hash_is_invalid(const unsigned char* hash)
570 : {
571 : int i;
572 :
573 : /* if the hash is reduced, we cannot grant that it's a specific kind of hash */
- 574 759156 : if (BLOCK_HASH_SIZE != HASH_MAX)
+ 574 759009 : if (BLOCK_HASH_SIZE != HASH_MAX)
575 0 : return 0;
576 :
- 577 1179374 : for (i = 0; i < BLOCK_HASH_SIZE; ++i)
- 578 1153310 : if (hash[i] != 0x00)
- 579 733092 : return 0;
+ 577 1178755 : for (i = 0; i < BLOCK_HASH_SIZE; ++i)
+ 578 1152696 : if (hash[i] != 0x00)
+ 579 732950 : return 0;
580 :
- 581 26064 : return 1;
+ 581 26059 : return 1;
582 : }
583 :
584 : /**
@@ -650,19 +650,19 @@
588 : *
589 : * If working with reduced hash lengths, this function always return 0.
590 : */
- 591 760617 : static inline int hash_is_zero(const unsigned char* hash)
+ 591 760471 : static inline int hash_is_zero(const unsigned char* hash)
592 : {
593 : int i;
594 :
595 : /* if the hash is reduced, we cannot grant that it's a specific kind of hash */
- 596 760617 : if (BLOCK_HASH_SIZE != HASH_MAX)
+ 596 760471 : if (BLOCK_HASH_SIZE != HASH_MAX)
597 0 : return 0;
598 :
- 599 994968 : for (i = 0; i < BLOCK_HASH_SIZE; ++i)
- 600 980500 : if (hash[i] != 0xFF)
- 601 746149 : return 0;
+ 599 994894 : for (i = 0; i < BLOCK_HASH_SIZE; ++i)
+ 600 980425 : if (hash[i] != 0xFF)
+ 601 746002 : return 0;
602 :
- 603 14468 : return 1;
+ 603 14469 : return 1;
604 : }
605 :
606 : /**
@@ -670,22 +670,22 @@
608 : *
609 : * If working with reduced hash lengths, this function always return 0.
610 : */
- 611 44219 : static inline int hash_is_unique(const unsigned char* hash)
+ 611 44333 : static inline int hash_is_unique(const unsigned char* hash)
612 : {
613 : /* if the hash is reduced, we cannot grant that it's a specific kind of hash */
- 614 44219 : if (BLOCK_HASH_SIZE != HASH_MAX)
+ 614 44333 : if (BLOCK_HASH_SIZE != HASH_MAX)
615 0 : return 0;
616 :
- 617 44219 : return !hash_is_zero(hash) && !hash_is_invalid(hash);
+ 617 44333 : return !hash_is_zero(hash) && !hash_is_invalid(hash);
618 : }
619 :
620 : /**
621 : * Set the hash to the special INVALID value.
622 : */
- 623 9234472 : static inline void hash_invalid_set(unsigned char* hash)
+ 623 9234413 : static inline void hash_invalid_set(unsigned char* hash)
624 : {
- 625 9234472 : memset(hash, 0x00, BLOCK_HASH_SIZE);
- 626 9234472 : }
+ 625 9234413 : memset(hash, 0x00, BLOCK_HASH_SIZE);
+ 626 9234413 : }
627 :
628 : /**
629 : * Set the hash to the special ZERO value.
@@ -698,9 +698,9 @@
636 : /**
637 : * Allocated space for block.
638 : */
- 639 58065323 : static inline size_t block_sizeof(void)
+ 639 58066767 : static inline size_t block_sizeof(void)
640 : {
- 641 58065323 : return 1 + BLOCK_HASH_SIZE;
+ 641 58066767 : return 1 + BLOCK_HASH_SIZE;
642 : }
643 :
644 : /**
@@ -709,32 +709,32 @@
647 : * For this function, it's allowed to pass a NULL block
648 : * pointer than results in the BLOCK_STATE_EMPTY state.
649 : */
- 650 52304798 : static inline unsigned block_state_get(const struct snapraid_block* block)
+ 650 52307392 : static inline unsigned block_state_get(const struct snapraid_block* block)
651 : {
- 652 52304798 : if (block == BLOCK_NULL)
- 653 1721706 : return BLOCK_STATE_EMPTY;
+ 652 52307392 : if (block == BLOCK_NULL)
+ 653 1721808 : return BLOCK_STATE_EMPTY;
654 :
- 655 50583092 : return block->state;
+ 655 50585584 : return block->state;
656 : }
657 :
658 : /**
659 : * Set the state of the block.
660 : */
- 661 19117787 : static inline void block_state_set(struct snapraid_block* block, unsigned state)
+ 661 19118268 : static inline void block_state_set(struct snapraid_block* block, unsigned state)
662 : {
- 663 19117787 : block->state = state;
- 664 19117787 : }
+ 663 19118268 : block->state = state;
+ 664 19118268 : }
665 :
666 : /**
667 : * Check if the specified block has an updated hash.
668 : *
669 : * Note that EMPTY / CHG / DELETED return 0.
670 : */
- 671 2217692 : static inline int block_has_updated_hash(const struct snapraid_block* block)
+ 671 2218141 : static inline int block_has_updated_hash(const struct snapraid_block* block)
672 : {
- 673 2217692 : unsigned state = block_state_get(block);
+ 673 2218141 : unsigned state = block_state_get(block);
674 :
- 675 2217692 : return state == BLOCK_STATE_BLK || state == BLOCK_STATE_REP;
+ 675 2218141 : return state == BLOCK_STATE_BLK || state == BLOCK_STATE_REP;
676 : }
677 :
678 : /**
@@ -743,11 +743,11 @@
681 : *
682 : * Note that EMPTY / BLK / REP return 0.
683 : */
- 684 2542743 : static inline int block_has_past_hash(const struct snapraid_block* block)
+ 684 2542370 : static inline int block_has_past_hash(const struct snapraid_block* block)
685 : {
- 686 2542743 : unsigned state = block_state_get(block);
+ 686 2542370 : unsigned state = block_state_get(block);
687 :
- 688 2542743 : return state == BLOCK_STATE_CHG || state == BLOCK_STATE_DELETED;
+ 688 2542370 : return state == BLOCK_STATE_CHG || state == BLOCK_STATE_DELETED;
689 : }
690 :
691 : /**
@@ -755,12 +755,12 @@
693 : *
694 : * Note that EMPTY / DELETED return 0.
695 : */
- 696 14590544 : static inline int block_has_file(const struct snapraid_block* block)
+ 696 14591728 : static inline int block_has_file(const struct snapraid_block* block)
697 : {
- 698 14590544 : unsigned state = block_state_get(block);
+ 698 14591728 : unsigned state = block_state_get(block);
699 :
- 700 14590800 : return state == BLOCK_STATE_BLK
- 701 14590800 : || state == BLOCK_STATE_CHG || state == BLOCK_STATE_REP;
+ 700 14591975 : return state == BLOCK_STATE_BLK
+ 701 14591975 : || state == BLOCK_STATE_CHG || state == BLOCK_STATE_REP;
702 : }
703 :
704 : /**
@@ -768,12 +768,12 @@
706 : *
707 : * Note that EMPTY / BLK return 0.
708 : */
- 709 12320061 : static inline int block_has_invalid_parity(const struct snapraid_block* block)
+ 709 12320606 : static inline int block_has_invalid_parity(const struct snapraid_block* block)
710 : {
- 711 12320061 : unsigned state = block_state_get(block);
+ 711 12320606 : unsigned state = block_state_get(block);
712 :
- 713 12320061 : return state == BLOCK_STATE_DELETED
- 714 12320061 : || state == BLOCK_STATE_CHG || state == BLOCK_STATE_REP;
+ 713 12320606 : return state == BLOCK_STATE_DELETED
+ 714 12320606 : || state == BLOCK_STATE_CHG || state == BLOCK_STATE_REP;
715 : }
716 :
717 : /**
@@ -788,20 +788,20 @@
726 220959 : return state == BLOCK_STATE_BLK;
727 : }
728 :
- 729 34094547 : static inline int file_flag_has(const struct snapraid_file* file, unsigned mask)
+ 729 34094426 : static inline int file_flag_has(const struct snapraid_file* file, unsigned mask)
730 : {
- 731 34094547 : return (file->flag & mask) == mask;
+ 731 34094426 : return (file->flag & mask) == mask;
732 : }
733 :
- 734 5301349 : static inline void file_flag_set(struct snapraid_file* file, unsigned mask)
+ 734 5301067 : static inline void file_flag_set(struct snapraid_file* file, unsigned mask)
735 : {
- 736 5301349 : file->flag |= mask;
- 737 5301349 : }
+ 736 5301067 : file->flag |= mask;
+ 737 5301067 : }
738 :
- 739 16739 : static inline void file_flag_clear(struct snapraid_file* file, unsigned mask)
+ 739 16745 : static inline void file_flag_clear(struct snapraid_file* file, unsigned mask)
740 : {
- 741 16739 : file->flag &= ~mask;
- 742 16739 : }
+ 741 16745 : file->flag &= ~mask;
+ 742 16745 : }
743 :
744 : /**
745 : * Allocate a file.
@@ -833,11 +833,11 @@
771 : *
772 : * Note that the block size if a runtime value.
773 : */
- 774 54351240 : static inline struct snapraid_block* file_block(struct snapraid_file* file, size_t pos)
+ 774 54352792 : static inline struct snapraid_block* file_block(struct snapraid_file* file, size_t pos)
775 : {
- 776 54351240 : unsigned char* ptr = (unsigned char*)file->blockvec;
+ 776 54352792 : unsigned char* ptr = (unsigned char*)file->blockvec;
777 :
- 778 54351240 : return (struct snapraid_block*)(ptr + pos * block_sizeof());
+ 778 54352792 : return (struct snapraid_block*)(ptr + pos * block_sizeof());
779 : }
780 :
781 : /**
@@ -879,9 +879,9 @@
817 : /**
818 : * Compute the hash of a file inode.
819 : */
- 820 5047846 : static inline tommy_uint32_t file_inode_hash(uint64_t inode)
+ 820 5047758 : static inline tommy_uint32_t file_inode_hash(uint64_t inode)
821 : {
- 822 5047846 : return (tommy_uint32_t)tommy_inthash_u64(inode);
+ 822 5047758 : return (tommy_uint32_t)tommy_inthash_u64(inode);
823 : }
824 :
825 : /**
@@ -900,17 +900,17 @@
838 : /**
839 : * Compute the hash of a file path.
840 : */
- 841 3886074 : static inline tommy_uint32_t file_path_hash(const char* sub)
+ 841 3885977 : static inline tommy_uint32_t file_path_hash(const char* sub)
842 : {
- 843 3886074 : return tommy_hash_u32(0, sub, strlen(sub));
+ 843 3885977 : return tommy_hash_u32(0, sub, strlen(sub));
844 : }
845 :
846 : /**
847 : * Compute the hash of a file stamp.
848 : */
- 849 6275914 : static inline tommy_uint32_t file_stamp_hash(data_off_t size, int64_t mtime_sec, int mtime_nsec)
+ 849 6275808 : static inline tommy_uint32_t file_stamp_hash(data_off_t size, int64_t mtime_sec, int mtime_nsec)
850 : {
- 851 6275914 : return tommy_inthash_u32((tommy_uint32_t)size ^ tommy_inthash_u32(mtime_sec ^ tommy_inthash_u32(mtime_nsec)));
+ 851 6275808 : return tommy_inthash_u32((tommy_uint32_t)size ^ tommy_inthash_u32(mtime_sec ^ tommy_inthash_u32(mtime_nsec)));
852 : }
853 :
854 : /**
@@ -933,9 +933,9 @@
871 : */
872 : int extent_file_compare(const void* void_a, const void* void_b);
873 :
- 874 209329 : static inline int link_flag_has(const struct snapraid_link* slink, unsigned mask)
+ 874 209328 : static inline int link_flag_has(const struct snapraid_link* slink, unsigned mask)
875 : {
- 876 209329 : return (slink->flag & mask) == mask;
+ 876 209328 : return (slink->flag & mask) == mask;
877 : }
878 :
879 39461 : static inline void link_flag_set(struct snapraid_link* slink, unsigned mask)
@@ -1088,19 +1088,19 @@
1026 : /**
1027 : * Get the file position from the parity position.
1028 : */
- 1029 11723736 : static inline struct snapraid_file* fs_par2file_get(struct snapraid_disk* disk, block_off_t parity_pos, block_off_t* file_pos)
+ 1029 11723986 : static inline struct snapraid_file* fs_par2file_get(struct snapraid_disk* disk, block_off_t parity_pos, block_off_t* file_pos)
1030 : {
1031 : struct snapraid_file* ret;
1032 :
- 1033 11723736 : ret = fs_par2file_find(disk, parity_pos, file_pos);
- 1034 11723887 : if (ret == 0) {
+ 1033 11723986 : ret = fs_par2file_find(disk, parity_pos, file_pos);
+ 1034 11724450 : if (ret == 0) {
1035 : /* LCOV_EXCL_START */
1036 : log_fatal("Internal inconsistency when deresolving parity to file at position '%u' in disk '%s'\n", parity_pos, disk->name);
1037 : os_abort();
1038 : /* LCOV_EXCL_STOP */
1039 : }
1040 :
- 1041 11723887 : return ret;
+ 1041 11724450 : return ret;
1042 : }
1043 :
1044 : /**
@@ -1112,19 +1112,19 @@
1050 : /**
1051 : * Get the parity position from the file position.
1052 : */
- 1053 4755380 : static inline block_off_t fs_file2par_get(struct snapraid_disk* disk, struct snapraid_file* file, block_off_t file_pos)
+ 1053 4755371 : static inline block_off_t fs_file2par_get(struct snapraid_disk* disk, struct snapraid_file* file, block_off_t file_pos)
1054 : {
1055 : block_off_t ret;
1056 :
- 1057 4755380 : ret = fs_file2par_find(disk, file, file_pos);
- 1058 4755380 : if (ret == POS_NULL) {
+ 1057 4755371 : ret = fs_file2par_find(disk, file, file_pos);
+ 1058 4755371 : if (ret == POS_NULL) {
1059 : /* LCOV_EXCL_START */
1060 : log_fatal("Internal inconsistency when resolving file '%s' at position '%u/%u' in disk '%s'\n", file->sub, file_pos, file->blockmax, disk->name);
1061 : os_abort();
1062 : /* LCOV_EXCL_STOP */
1063 : }
1064 :
- 1065 4755380 : return ret;
+ 1065 4755371 : return ret;
1066 : }
1067 :
1068 : /**
@@ -1172,18 +1172,18 @@
1110 : /**
1111 : * Make an info.
1112 : */
- 1113 194583 : static inline snapraid_info info_make(time_t last_access, int error, int rehash, int justsynced)
+ 1113 194355 : static inline snapraid_info info_make(time_t last_access, int error, int rehash, int justsynced)
1114 : {
1115 : /* clear the lowest bits as reserved for other information */
- 1116 194583 : snapraid_info info = last_access & ~INFO_MASK;
+ 1116 194355 : snapraid_info info = last_access & ~INFO_MASK;
1117 :
- 1118 194583 : if (error != 0)
- 1119 5380 : info |= 0x1;
- 1120 194583 : if (rehash != 0)
+ 1118 194355 : if (error != 0)
+ 1119 5306 : info |= 0x1;
+ 1120 194355 : if (rehash != 0)
1121 14426 : info |= 0x2;
- 1122 194583 : if (justsynced != 0)
- 1123 142978 : info |= 0x4;
- 1124 194583 : return info;
+ 1122 194355 : if (justsynced != 0)
+ 1123 142922 : info |= 0x4;
+ 1124 194355 : return info;
1125 : }
1126 :
1127 : /**
@@ -1191,36 +1191,36 @@
1129 : * This is the last time when the block was know to be correct.
1130 : * The "scrubbed" info tells if the time is referreing at the latest sync or scrub.
1131 : */
- 1132 883104 : static inline time_t info_get_time(snapraid_info info)
+ 1132 883015 : static inline time_t info_get_time(snapraid_info info)
1133 : {
- 1134 883104 : return info & ~INFO_MASK;
+ 1134 883015 : return info & ~INFO_MASK;
1135 : }
1136 :
1137 : /**
1138 : * Extract the error information.
1139 : * Report if the block address had some problem.
1140 : */
- 1141 351943 : static inline int info_get_bad(snapraid_info info)
+ 1141 351958 : static inline int info_get_bad(snapraid_info info)
1142 : {
- 1143 351943 : return (info & 0x1) != 0;
+ 1143 351958 : return (info & 0x1) != 0;
1144 : }
1145 :
1146 : /**
1147 : * Extract the rehash information.
1148 : * Report if the block address is using the old hash and needs to be rehashed.
1149 : */
- 1150 2046653 : static inline int info_get_rehash(snapraid_info info)
+ 1150 2046724 : static inline int info_get_rehash(snapraid_info info)
1151 : {
- 1152 2046653 : return (info & 0x2) != 0;
+ 1152 2046724 : return (info & 0x2) != 0;
1153 : }
1154 :
1155 : /**
1156 : * Extract the scrubbed information.
1157 : * Report if the block address was never scrubbed.
1158 : */
- 1159 68535 : static inline int info_get_justsynced(snapraid_info info)
+ 1159 68446 : static inline int info_get_justsynced(snapraid_info info)
1160 : {
- 1161 68535 : return (info & 0x4) != 0;
+ 1161 68446 : return (info & 0x4) != 0;
1162 : }
1163 :
1164 : /**
@@ -1243,27 +1243,27 @@
1181 : * Set the info at the specified position.
1182 : * The position is allocated if not yet done.
1183 : */
- 1184 1697965 : static inline void info_set(tommy_arrayblkof* array, block_off_t pos, snapraid_info info)
+ 1184 1698098 : static inline void info_set(tommy_arrayblkof* array, block_off_t pos, snapraid_info info)
1185 : {
- 1186 1697965 : tommy_arrayblkof_grow(array, pos + 1);
+ 1186 1698098 : tommy_arrayblkof_grow(array, pos + 1);
1187 :
- 1188 1697965 : memcpy(tommy_arrayblkof_ref(array, pos), &info, sizeof(snapraid_info));
- 1189 1697965 : }
+ 1188 1698098 : memcpy(tommy_arrayblkof_ref(array, pos), &info, sizeof(snapraid_info));
+ 1189 1698098 : }
1190 :
1191 : /**
1192 : * Get the info at the specified position.
1193 : * For not allocated position, 0 is returned.
1194 : */
- 1195 5098374 : static inline snapraid_info info_get(tommy_arrayblkof* array, block_off_t pos)
+ 1195 5098627 : static inline snapraid_info info_get(tommy_arrayblkof* array, block_off_t pos)
1196 : {
1197 : snapraid_info info;
1198 :
- 1199 5098374 : if (pos >= tommy_arrayblkof_size(array))
+ 1199 5098627 : if (pos >= tommy_arrayblkof_size(array))
1200 262643 : return 0;
1201 :
- 1202 4835731 : memcpy(&info, tommy_arrayblkof_ref(array, pos), sizeof(snapraid_info));
+ 1202 4835984 : memcpy(&info, tommy_arrayblkof_ref(array, pos), sizeof(snapraid_info));
1203 :
- 1204 4835731 : return info;
+ 1204 4835984 : return info;
1205 : }
1206 :
1207 : /**
diff --git a/cov/cmdline/handle.c.func-sort-c.html b/cov/cmdline/handle.c.func-sort-c.html
index edff826c..ef921dc5 100644
--- a/cov/cmdline/handle.c.func-sort-c.html
+++ b/cov/cmdline/handle.c.func-sort-c.html
@@ -61,31 +61,31 @@
| handle_read |
- 5855349 |
+ 5856319 |
| handle_close |
- 4647511 |
+ 4647370 |
| handle_open |
- 2185867 |
+ 2186388 |
| handle_create |
- 771311 |
+ 771305 |
| handle_write |
- 288562 |
+ 288483 |
| handle_utime |
- 119431 |
+ 119471 |
| handle_truncate |
- 3222 |
+ 3180 |
| handle_mapping |
diff --git a/cov/cmdline/handle.c.func.html b/cov/cmdline/handle.c.func.html
index 6ead080c..f947889d 100644
--- a/cov/cmdline/handle.c.func.html
+++ b/cov/cmdline/handle.c.func.html
@@ -61,11 +61,11 @@
| handle_close |
- 4647511 |
+ 4647370 |
| handle_create |
- 771311 |
+ 771305 |
| handle_mapping |
@@ -73,23 +73,23 @@
| handle_open |
- 2185867 |
+ 2186388 |
| handle_read |
- 5855349 |
+ 5856319 |
| handle_truncate |
- 3222 |
+ 3180 |
| handle_utime |
- 119431 |
+ 119471 |
| handle_write |
- 288562 |
+ 288483 |
diff --git a/cov/cmdline/handle.c.gcov.html b/cov/cmdline/handle.c.gcov.html
index 98afa115..cbb1c184 100644
--- a/cov/cmdline/handle.c.gcov.html
+++ b/cov/cmdline/handle.c.gcov.html
@@ -86,64 +86,64 @@
24 : /****************************************************************************/
25 : /* handle */
26 :
- 27 771311 : int handle_create(struct snapraid_handle* handle, struct snapraid_file* file, int mode)
+ 27 771305 : 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 771311 : if (handle->file == file && handle->f != -1) {
+ 33 771305 : if (handle->file == file && handle->f != -1) {
34 0 : return 0;
35 : }
36 :
- 37 771311 : advise_init(&handle->advise, mode);
- 38 771311 : pathprint(handle->path, sizeof(handle->path), "%s%s", handle->disk->dir, file->sub);
+ 37 771305 : advise_init(&handle->advise, mode);
+ 38 771305 : pathprint(handle->path, sizeof(handle->path), "%s%s", handle->disk->dir, file->sub);
39 :
- 40 771311 : ret = mkancestor(handle->path);
- 41 771311 : if (ret != 0) {
+ 40 771305 : ret = mkancestor(handle->path);
+ 41 771305 : if (ret != 0) {
42 : /* LCOV_EXCL_START */
43 : return -1;
44 : /* LCOV_EXCL_STOP */
45 : }
46 :
47 : /* initial values, changed later if required */
- 48 771311 : handle->created = 0;
+ 48 771305 : handle->created = 0;
49 :
50 : /* flags for opening */
51 : /* O_BINARY: open as binary file (Windows only) */
52 : /* O_NOFOLLOW: do not follow links to ensure to open the real file */
- 53 771311 : flags = O_BINARY | O_NOFOLLOW | advise_flags(&handle->advise);
+ 53 771305 : flags = O_BINARY | O_NOFOLLOW | advise_flags(&handle->advise);
54 :
55 : /* open for read write */
- 56 771311 : handle->f = open(handle->path, flags | O_RDWR);
+ 56 771305 : handle->f = open(handle->path, flags | O_RDWR);
57 :
58 : /* if failed for missing write permission */
- 59 771311 : if (handle->f == -1 && (errno == EACCES || errno == EROFS)) {
+ 59 771305 : if (handle->f == -1 && (errno == EACCES || errno == EROFS)) {
60 : /* open for real-only */
61 0 : handle->f = open(handle->path, flags | O_RDONLY);
62 : }
63 :
64 : /* if failed for missing file */
- 65 771311 : if (handle->f == -1 && errno == ENOENT) {
+ 65 771305 : if (handle->f == -1 && errno == ENOENT) {
66 : char path_from[PATH_MAX];
67 :
68 : /* check if exists a .unrecoverable copy, and rename to the real one */
- 69 176417 : pathprint(path_from, sizeof(path_from), "%s.unrecoverable", handle->path);
+ 69 176353 : pathprint(path_from, sizeof(path_from), "%s.unrecoverable", handle->path);
70 :
- 71 176417 : if (rename(path_from, handle->path) == 0) {
+ 71 176353 : if (rename(path_from, handle->path) == 0) {
72 : /* open for read write */
- 73 63282 : handle->f = open(handle->path, flags | O_RDWR);
+ 73 63286 : handle->f = open(handle->path, flags | O_RDWR);
74 : } else {
75 : /* create it */
- 76 113135 : handle->f = open(handle->path, flags | O_RDWR | O_CREAT, 0600);
- 77 113135 : if (handle->f != -1) {
+ 76 113067 : handle->f = open(handle->path, flags | O_RDWR | O_CREAT, 0600);
+ 77 113067 : if (handle->f != -1) {
78 : /* mark it as created if really done */
- 79 113135 : handle->created = 1;
+ 79 113067 : handle->created = 1;
80 : }
81 : }
82 : }
83 :
- 84 771311 : if (handle->f == -1) {
+ 84 771305 : if (handle->f == -1) {
85 : /* LCOV_EXCL_START */
86 : /* invalidate for error */
87 : handle->file = 0;
@@ -156,11 +156,11 @@
94 : }
95 :
96 : /* just opened */
- 97 771311 : handle->file = file;
+ 97 771305 : handle->file = file;
98 :
99 : /* get the stat info */
- 100 771311 : ret = fstat(handle->f, &handle->st);
- 101 771311 : if (ret != 0) {
+ 100 771305 : ret = fstat(handle->f, &handle->st);
+ 101 771305 : if (ret != 0) {
102 : /* LCOV_EXCL_START */
103 : log_fatal("Error accessing file '%s'. %s.\n", handle->path, strerror(errno));
104 : return -1;
@@ -168,25 +168,25 @@
106 : }
107 :
108 : /* get the size of the existing data */
- 109 771311 : handle->valid_size = handle->st.st_size;
+ 109 771305 : handle->valid_size = handle->st.st_size;
110 :
- 111 771311 : ret = advise_open(&handle->advise, handle->f);
- 112 771311 : if (ret != 0) {
+ 111 771305 : ret = advise_open(&handle->advise, handle->f);
+ 112 771305 : if (ret != 0) {
113 : /* LCOV_EXCL_START */
114 : log_fatal("Error advising file '%s'. %s.\n", handle->path, strerror(errno));
115 : return -1;
116 : /* LCOV_EXCL_STOP */
117 : }
118 :
- 119 771311 : return 0;
+ 119 771305 : return 0;
120 : }
121 :
- 122 3222 : int handle_truncate(struct snapraid_handle* handle, struct snapraid_file* file)
+ 122 3180 : int handle_truncate(struct snapraid_handle* handle, struct snapraid_file* file)
123 : {
124 : int ret;
125 :
- 126 3222 : ret = ftruncate(handle->f, file->size);
- 127 3222 : if (ret != 0) {
+ 126 3180 : ret = ftruncate(handle->f, file->size);
+ 127 3180 : if (ret != 0) {
128 : /* LCOV_EXCL_START */
129 : if (errno == EACCES) {
130 : log_fatal("Failed to truncate file '%s' for missing write permission.\n", handle->path);
@@ -198,56 +198,56 @@
136 : }
137 :
138 : /* adjust the size to the truncated size */
- 139 3222 : handle->valid_size = file->size;
+ 139 3180 : handle->valid_size = file->size;
140 :
- 141 3222 : return 0;
+ 141 3180 : return 0;
142 : }
143 :
- 144 2185867 : int handle_open(struct snapraid_handle* handle, struct snapraid_file* file, int mode, fptr* out, fptr* out_missing)
+ 144 2186388 : int handle_open(struct snapraid_handle* handle, struct snapraid_file* file, int mode, fptr* out, fptr* out_missing)
145 : {
146 : int ret;
147 : int flags;
148 :
- 149 2185867 : if (!out_missing)
- 150 2185464 : out_missing = out;
+ 149 2186388 : if (!out_missing)
+ 150 2185969 : out_missing = out;
151 :
152 : /* if already opened, nothing to do */
- 153 2185867 : if (handle->file == file && handle->file != 0 && handle->f != -1) {
- 154 468345 : return 0;
+ 153 2186388 : if (handle->file == file && handle->file != 0 && handle->f != -1) {
+ 154 468756 : return 0;
155 : }
156 :
- 157 1717522 : advise_init(&handle->advise, mode);
- 158 1717676 : pathprint(handle->path, sizeof(handle->path), "%s%s", handle->disk->dir, file->sub);
+ 157 1717632 : advise_init(&handle->advise, mode);
+ 158 1717806 : pathprint(handle->path, sizeof(handle->path), "%s%s", handle->disk->dir, file->sub);
159 :
160 : /* for sure not created */
- 161 1717807 : handle->created = 0;
+ 161 1717916 : handle->created = 0;
162 :
163 : /* flags for opening */
164 : /* O_BINARY: open as binary file (Windows only) */
165 : /* O_NOFOLLOW: do not follow links to ensure to open the real file */
- 166 1717807 : flags = O_BINARY | O_NOFOLLOW | advise_flags(&handle->advise);
+ 166 1717916 : flags = O_BINARY | O_NOFOLLOW | advise_flags(&handle->advise);
167 :
168 : /* open for read */
- 169 1717764 : handle->f = open_noatime(handle->path, flags | O_RDONLY);
- 170 1717748 : if (handle->f == -1) {
+ 169 1717861 : handle->f = open_noatime(handle->path, flags | O_RDONLY);
+ 170 1717874 : if (handle->f == -1) {
171 : /* invalidate for error */
- 172 78757 : handle->file = 0;
- 173 78757 : handle->f = -1;
- 174 78757 : handle->valid_size = 0;
+ 172 78666 : handle->file = 0;
+ 173 78666 : handle->f = -1;
+ 174 78666 : handle->valid_size = 0;
175 :
- 176 78757 : if (errno == ENOENT)
- 177 78745 : out_missing("Missing file '%s'.\n", handle->path);
+ 176 78666 : if (errno == ENOENT)
+ 177 78654 : out_missing("Missing file '%s'.\n", handle->path);
178 : else
179 12 : out("Error opening file '%s'. %s.\n", handle->path, strerror(errno));
- 180 78757 : return -1;
+ 180 78666 : return -1;
181 : }
182 :
183 : /* just opened */
- 184 1638991 : handle->file = file;
+ 184 1639208 : handle->file = file;
185 :
186 : /* get the stat info */
- 187 1638991 : ret = fstat(handle->f, &handle->st);
- 188 1639031 : if (ret != 0) {
+ 187 1639208 : ret = fstat(handle->f, &handle->st);
+ 188 1639257 : if (ret != 0) {
189 : /* LCOV_EXCL_START */
190 : out("Error accessing file '%s'. %s.\n", handle->path, strerror(errno));
191 : return -1;
@@ -255,27 +255,27 @@
193 : }
194 :
195 : /* get the size of the existing data */
- 196 1639031 : handle->valid_size = handle->st.st_size;
+ 196 1639257 : handle->valid_size = handle->st.st_size;
197 :
- 198 1639031 : ret = advise_open(&handle->advise, handle->f);
- 199 1639026 : if (ret != 0) {
+ 198 1639257 : ret = advise_open(&handle->advise, handle->f);
+ 199 1639264 : if (ret != 0) {
200 : /* LCOV_EXCL_START */
201 : out("Error advising file '%s'. %s.\n", handle->path, strerror(errno));
202 : return -1;
203 : /* LCOV_EXCL_STOP */
204 : }
205 :
- 206 1639026 : return 0;
+ 206 1639264 : return 0;
207 : }
208 :
- 209 4647511 : int handle_close(struct snapraid_handle* handle)
+ 209 4647370 : int handle_close(struct snapraid_handle* handle)
210 : {
211 : int ret;
212 :
213 : /* close if open */
- 214 4647511 : if (handle->f != -1) {
- 215 2410343 : ret = close(handle->f);
- 216 2410377 : if (ret != 0) {
+ 214 4647370 : if (handle->f != -1) {
+ 215 2410548 : ret = close(handle->f);
+ 216 2410591 : if (ret != 0) {
217 : /* LCOV_EXCL_START */
218 : log_fatal("Error closing file '%s'. %s.\n", handle->file->sub, strerror(errno));
219 :
@@ -289,14 +289,14 @@
227 : }
228 :
229 : /* reset the descriptor */
- 230 4647545 : handle->file = 0;
- 231 4647545 : handle->f = -1;
- 232 4647545 : handle->valid_size = 0;
+ 230 4647413 : handle->file = 0;
+ 231 4647413 : handle->f = -1;
+ 232 4647413 : handle->valid_size = 0;
233 :
- 234 4647545 : return 0;
+ 234 4647413 : return 0;
235 : }
236 :
- 237 5855349 : int handle_read(struct snapraid_handle* handle, block_off_t file_pos, unsigned char* block_buffer, unsigned block_size, fptr* out, fptr* out_missing)
+ 237 5856319 : int handle_read(struct snapraid_handle* handle, block_off_t file_pos, unsigned char* block_buffer, unsigned block_size, fptr* out, fptr* out_missing)
238 : {
239 : ssize_t read_ret;
240 : data_off_t offset;
@@ -304,70 +304,70 @@
242 : unsigned count;
243 : int ret;
244 :
- 245 5855349 : offset = file_pos * (data_off_t)block_size;
+ 245 5856319 : offset = file_pos * (data_off_t)block_size;
246 :
- 247 5855349 : if (!out_missing)
- 248 5842393 : out_missing = out;
+ 247 5856319 : if (!out_missing)
+ 248 5843379 : out_missing = out;
249 :
250 : /* check if we are going to read only not initialized data */
- 251 5855349 : if (offset >= handle->valid_size) {
+ 251 5856319 : if (offset >= handle->valid_size) {
252 : /* if the file is missing, it's at 0 size, or it's rebuilt while reading */
- 253 433464 : if (offset == handle->valid_size || handle->valid_size == 0)
- 254 432215 : out_missing("Reading data from missing file '%s' at offset %" PRIu64 ".\n", handle->path, offset);
+ 253 433352 : if (offset == handle->valid_size || handle->valid_size == 0)
+ 254 431991 : out_missing("Reading data from missing file '%s' at offset %" PRIu64 ".\n", handle->path, offset);
255 : else
- 256 1249 : out("Reading missing data from file '%s' at offset %" PRIu64 ".\n", handle->path, offset);
- 257 433464 : return -1;
+ 256 1361 : out("Reading missing data from file '%s' at offset %" PRIu64 ".\n", handle->path, offset);
+ 257 433352 : return -1;
258 : }
259 :
- 260 5421885 : read_size = file_block_size(handle->file, file_pos, block_size);
+ 260 5422967 : read_size = file_block_size(handle->file, file_pos, block_size);
261 :
- 262 5421858 : count = 0;
+ 262 5422979 : count = 0;
263 : do {
264 : /* read the full block to support O_DIRECT */
- 265 5430464 : read_ret = pread(handle->f, block_buffer + count, block_size - count, offset + count);
- 266 5430098 : if (read_ret < 0) {
+ 265 5431676 : read_ret = pread(handle->f, block_buffer + count, block_size - count, offset + count);
+ 266 5431334 : if (read_ret < 0) {
267 : /* LCOV_EXCL_START */
268 : out("Error reading file '%s' at offset %" PRIu64 " for size %u. %s.\n", handle->path, offset + count, block_size - count, strerror(errno));
269 : return -1;
270 : /* LCOV_EXCL_STOP */
271 : }
- 272 5430098 : if (read_ret == 0) {
- 273 8705 : out("Unexpected end of file '%s' at offset %" PRIu64 ". %s.\n", handle->path, offset, strerror(errno));
- 274 8705 : return -1;
+ 272 5431334 : if (read_ret == 0) {
+ 273 8919 : out("Unexpected end of file '%s' at offset %" PRIu64 ". %s.\n", handle->path, offset, strerror(errno));
+ 274 8919 : return -1;
275 : }
276 :
- 277 5421393 : count += read_ret;
- 278 5421393 : } while (count < read_size);
+ 277 5422415 : count += read_ret;
+ 278 5422415 : } while (count < read_size);
279 :
280 : /* pad with 0 */
- 281 5412787 : if (read_size < block_size) {
- 282 2188487 : memset(block_buffer + read_size, 0, block_size - read_size);
+ 281 5413718 : if (read_size < block_size) {
+ 282 2188617 : memset(block_buffer + read_size, 0, block_size - read_size);
283 : }
284 :
- 285 5412787 : ret = advise_read(&handle->advise, handle->f, offset, block_size);
- 286 5412784 : if (ret != 0) {
+ 285 5413718 : ret = advise_read(&handle->advise, handle->f, offset, block_size);
+ 286 5413674 : if (ret != 0) {
287 : /* LCOV_EXCL_START */
288 : out("Error advising file '%s'. %s.\n", handle->path, strerror(errno));
289 : return -1;
290 : /* LCOV_EXCL_STOP */
291 : }
292 :
- 293 5412784 : return read_size;
+ 293 5413674 : return read_size;
294 : }
295 :
- 296 288562 : int handle_write(struct snapraid_handle* handle, block_off_t file_pos, unsigned char* block_buffer, unsigned block_size)
+ 296 288483 : int handle_write(struct snapraid_handle* handle, block_off_t file_pos, unsigned char* block_buffer, unsigned block_size)
297 : {
298 : ssize_t write_ret;
299 : data_off_t offset;
300 : unsigned write_size;
301 : int ret;
302 :
- 303 288562 : offset = file_pos * (data_off_t)block_size;
+ 303 288483 : offset = file_pos * (data_off_t)block_size;
304 :
- 305 288562 : write_size = file_block_size(handle->file, file_pos, block_size);
+ 305 288483 : write_size = file_block_size(handle->file, file_pos, block_size);
306 :
- 307 288562 : write_ret = pwrite(handle->f, block_buffer, write_size, offset);
- 308 288562 : if (write_ret != (ssize_t)write_size) { /* conversion is safe because block_size is always small */
+ 307 288483 : write_ret = pwrite(handle->f, block_buffer, write_size, offset);
+ 308 288483 : if (write_ret != (ssize_t)write_size) { /* conversion is safe because block_size is always small */
309 : /* LCOV_EXCL_START */
310 : log_fatal("Error writing file '%s'. %s.\n", handle->path, strerror(errno));
311 : return -1;
@@ -375,39 +375,39 @@
313 : }
314 :
315 : /* adjust the size of the valid data */
- 316 288562 : if (handle->valid_size < offset + write_size) {
- 317 282510 : handle->valid_size = offset + write_size;
+ 316 288483 : if (handle->valid_size < offset + write_size) {
+ 317 282399 : handle->valid_size = offset + write_size;
318 : }
319 :
- 320 288562 : ret = advise_write(&handle->advise, handle->f, offset, block_size);
- 321 288562 : if (ret != 0) {
+ 320 288483 : ret = advise_write(&handle->advise, handle->f, offset, block_size);
+ 321 288483 : if (ret != 0) {
322 : /* LCOV_EXCL_START */
323 : log_fatal("Error advising file '%s'. %s.\n", handle->path, strerror(errno));
324 : return -1;
325 : /* LCOV_EXCL_STOP */
326 : }
327 :
- 328 288562 : return 0;
+ 328 288483 : return 0;
329 : }
330 :
- 331 119431 : int handle_utime(struct snapraid_handle* handle)
+ 331 119471 : int handle_utime(struct snapraid_handle* handle)
332 : {
333 : int ret;
334 :
335 : /* do nothing if not opened */
- 336 119431 : if (handle->f == -1)
+ 336 119471 : if (handle->f == -1)
337 0 : return 0;
338 :
- 339 119431 : ret = fmtime(handle->f, handle->file->mtime_sec, handle->file->mtime_nsec);
+ 339 119471 : ret = fmtime(handle->f, handle->file->mtime_sec, handle->file->mtime_nsec);
340 :
- 341 119431 : if (ret != 0) {
+ 341 119471 : if (ret != 0) {
342 : /* LCOV_EXCL_START */
343 : log_fatal("Error timing file '%s'. %s.\n", handle->file->sub, strerror(errno));
344 : return -1;
345 : /* LCOV_EXCL_STOP */
346 : }
347 :
- 348 119431 : return 0;
+ 348 119471 : return 0;
349 : }
350 :
351 221 : struct snapraid_handle* handle_mapping(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 9c1827ee..6b8d8469 100644
--- a/cov/cmdline/import.c.func-sort-c.html
+++ b/cov/cmdline/import.c.func-sort-c.html
@@ -61,11 +61,11 @@
| import_block_hash |
- 657164 |
+ 656904 |
| state_import_fetch |
- 652692 |
+ 652432 |
| import_block_hash_compare |
diff --git a/cov/cmdline/import.c.func.html b/cov/cmdline/import.c.func.html
index 8e60bbce..3c94845a 100644
--- a/cov/cmdline/import.c.func.html
+++ b/cov/cmdline/import.c.func.html
@@ -61,7 +61,7 @@
| import_block_hash |
- 657164 |
+ 656904 |
| import_block_hash_compare |
@@ -89,7 +89,7 @@
| state_import_fetch |
- 652692 |
+ 652432 |
diff --git a/cov/cmdline/import.c.gcov.html b/cov/cmdline/import.c.gcov.html
index f65eeec5..2c5e2abe 100644
--- a/cov/cmdline/import.c.gcov.html
+++ b/cov/cmdline/import.c.gcov.html
@@ -108,10 +108,10 @@
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 657164 : static inline tommy_uint32_t import_block_hash(const unsigned char* hash)
+ 49 656904 : static inline tommy_uint32_t import_block_hash(const unsigned char* hash)
50 : {
51 : /* the hash data is not aligned, and we cannot access it with a direct cast */
- 52 657164 : return hash[0] | ((uint32_t)hash[1] << 8) | ((uint32_t)hash[2] << 16) | ((uint32_t)hash[3] << 24);
+ 52 656904 : return hash[0] | ((uint32_t)hash[1] << 8) | ((uint32_t)hash[2] << 16) | ((uint32_t)hash[3] << 24);
53 : }
54 :
55 1750 : static void import_file(struct snapraid_state* state, const char* path, uint64_t size)
@@ -207,24 +207,24 @@
145 1750 : free(file);
146 1750 : }
147 :
- 148 652692 : int state_import_fetch(struct snapraid_state* state, int rehash, struct snapraid_block* missing_block, unsigned char* buffer)
+ 148 652432 : int state_import_fetch(struct snapraid_state* state, int rehash, struct snapraid_block* missing_block, unsigned char* buffer)
149 : {
150 : struct snapraid_import_block* block;
151 : int ret;
152 : int f;
- 153 652692 : const unsigned char* hash = missing_block->hash;
- 154 652692 : unsigned block_size = state->block_size;
+ 153 652432 : const unsigned char* hash = missing_block->hash;
+ 154 652432 : unsigned block_size = state->block_size;
155 : unsigned read_size;
156 : unsigned char buffer_hash[HASH_MAX];
157 : const char* path;
158 :
- 159 652692 : if (rehash) {
+ 159 652432 : if (rehash) {
160 0 : block = tommy_hashdyn_search(&state->previmportset, import_block_prevhash_compare, hash, import_block_hash(hash));
161 : } else {
- 162 652692 : block = tommy_hashdyn_search(&state->importset, import_block_hash_compare, hash, import_block_hash(hash));
+ 162 652432 : block = tommy_hashdyn_search(&state->importset, import_block_hash_compare, hash, import_block_hash(hash));
163 : }
- 164 652692 : if (!block)
- 165 648220 : return -1;
+ 164 652432 : if (!block)
+ 165 647960 : return -1;
166 :
167 4472 : path = block->file->path;
168 4472 : read_size = block->size;
diff --git a/cov/cmdline/index-sort-f.html b/cov/cmdline/index-sort-f.html
index 598b0f01..41e4f2ef 100644
--- a/cov/cmdline/index-sort-f.html
+++ b/cov/cmdline/index-sort-f.html
@@ -31,9 +31,9 @@
|
-
-
-
+
+
+
@@ -122,10 +122,10 @@
| parity.c |
-
+
|
- 85.8 % |
- 206 / 240 |
+ 91.9 % |
+ 217 / 236 |
94.7 % |
18 / 19 |
@@ -292,10 +292,10 @@
| dry.c |
-
+
|
- 72.7 % |
- 120 / 165 |
+ 76.4 % |
+ 120 / 157 |
100.0 % |
5 / 5 |
@@ -312,10 +312,10 @@
| scrub.c |
-
+
|
- 78.7 % |
- 281 / 357 |
+ 80.5 % |
+ 281 / 349 |
100.0 % |
6 / 6 |
@@ -332,10 +332,10 @@
| sync.c |
-
+
|
- 89.5 % |
- 502 / 561 |
+ 91.9 % |
+ 502 / 546 |
100.0 % |
7 / 7 |
@@ -372,20 +372,20 @@
| check.c |
-
+
|
- 90.8 % |
- 709 / 781 |
+ 91.5 % |
+ 709 / 775 |
100.0 % |
9 / 9 |
| snapraid.c |
-
+
|
- 91.1 % |
- 494 / 542 |
+ 91.5 % |
+ 496 / 542 |
100.0 % |
9 / 9 |
@@ -402,10 +402,10 @@
| scan.c |
-
+
|
- 89.2 % |
- 563 / 631 |
+ 89.5 % |
+ 565 / 631 |
100.0 % |
23 / 23 |
diff --git a/cov/cmdline/index-sort-l.html b/cov/cmdline/index-sort-l.html
index 6dc33db4..d6502fac 100644
--- a/cov/cmdline/index-sort-l.html
+++ b/cov/cmdline/index-sort-l.html
@@ -31,9 +31,9 @@
|
-
-
-
+
+
+
@@ -82,23 +82,13 @@
| dry.c |
-
+
|
- 72.7 % |
- 120 / 165 |
+ 76.4 % |
+ 120 / 157 |
100.0 % |
5 / 5 |
-
- | scrub.c |
-
-
- |
- 78.7 % |
- 281 / 357 |
- 100.0 % |
- 6 / 6 |
-
| support.c |
@@ -110,34 +100,24 @@
| 60 / 62 |
- | parity.c |
+ scrub.c |
-
+
|
- 85.8 % |
- 206 / 240 |
- 94.7 % |
- 18 / 19 |
+ 80.5 % |
+ 281 / 349 |
+ 100.0 % |
+ 6 / 6 |
| scan.c |
-
- |
- 89.2 % |
- 563 / 631 |
- 100.0 % |
- 23 / 23 |
-
-
- | sync.c |
-
-
+
|
89.5 % |
- 502 / 561 |
+ 565 / 631 |
100.0 % |
- 7 / 7 |
+ 23 / 23 |
| state.c |
@@ -169,16 +149,6 @@
87.5 % |
7 / 8 |
-
- | check.c |
-
-
- |
- 90.8 % |
- 709 / 781 |
- 100.0 % |
- 9 / 9 |
-
| stream.c |
@@ -200,15 +170,45 @@
| 7 / 7 |
- | snapraid.c |
+ check.c |
-
+
|
- 91.1 % |
- 494 / 542 |
+ 91.5 % |
+ 709 / 775 |
100.0 % |
9 / 9 |
+
+ | snapraid.c |
+
+
+ |
+ 91.5 % |
+ 496 / 542 |
+ 100.0 % |
+ 9 / 9 |
+
+
+ | parity.c |
+
+
+ |
+ 91.9 % |
+ 217 / 236 |
+ 94.7 % |
+ 18 / 19 |
+
+
+ | sync.c |
+
+
+ |
+ 91.9 % |
+ 502 / 546 |
+ 100.0 % |
+ 7 / 7 |
+
| io.c |
diff --git a/cov/cmdline/index.html b/cov/cmdline/index.html
index f74b2cb2..b4260d2c 100644
--- a/cov/cmdline/index.html
+++ b/cov/cmdline/index.html
@@ -31,9 +31,9 @@
|
|
-
-
-
+
+
+
@@ -72,10 +72,10 @@
| check.c |
-
+
|
- 90.8 % |
- 709 / 781 |
+ 91.5 % |
+ 709 / 775 |
100.0 % |
9 / 9 |
@@ -92,10 +92,10 @@
| dry.c |
-
+
|
- 72.7 % |
- 120 / 165 |
+ 76.4 % |
+ 120 / 157 |
100.0 % |
5 / 5 |
@@ -202,10 +202,10 @@
| parity.c |
-
+
|
- 85.8 % |
- 206 / 240 |
+ 91.9 % |
+ 217 / 236 |
94.7 % |
18 / 19 |
@@ -242,20 +242,20 @@
| scan.c |
-
+
|
- 89.2 % |
- 563 / 631 |
+ 89.5 % |
+ 565 / 631 |
100.0 % |
23 / 23 |
| scrub.c |
-
+
|
- 78.7 % |
- 281 / 357 |
+ 80.5 % |
+ 281 / 349 |
100.0 % |
6 / 6 |
@@ -282,10 +282,10 @@
| snapraid.c |
-
+
|
- 91.1 % |
- 494 / 542 |
+ 91.5 % |
+ 496 / 542 |
100.0 % |
9 / 9 |
@@ -372,10 +372,10 @@
| sync.c |
-
+
|
- 89.5 % |
- 502 / 561 |
+ 91.9 % |
+ 502 / 546 |
100.0 % |
7 / 7 |
diff --git a/cov/cmdline/io.c.func-sort-c.html b/cov/cmdline/io.c.func-sort-c.html
index 5904027b..dde735d8 100644
--- a/cov/cmdline/io.c.func-sort-c.html
+++ b/cov/cmdline/io.c.func-sort-c.html
@@ -61,27 +61,27 @@
| io_reader_step |
- 1162427 |
+ 1163270 |
| io_task_read_thread |
- 1081698 |
+ 1082226 |
| io_reader_worker |
- 1081680 |
+ 1082209 |
| io_data_read_thread |
- 870894 |
+ 871422 |
| io_writer_step |
- 553871 |
+ 554398 |
| io_parity_write_thread |
- 553420 |
+ 553948 |
| io_parity_read_thread |
@@ -89,27 +89,27 @@
| io_position_next |
- 161997 |
+ 162085 |
| io_reader_sched |
- 161997 |
+ 162085 |
| io_read_next_thread |
- 145244 |
+ 145332 |
| io_writer_sched |
- 112401 |
+ 112474 |
| io_write_preset_thread |
- 110015 |
+ 110103 |
| io_write_next_thread |
- 110015 |
+ 110103 |
| io_task_read_mono |
@@ -137,11 +137,11 @@
| io_writer_sched_empty |
- 2301 |
+ 2316 |
| io_reader_thread |
- 647 |
+ 648 |
| io_writer_thread |
diff --git a/cov/cmdline/io.c.func.html b/cov/cmdline/io.c.func.html
index d5364ee0..75b86177 100644
--- a/cov/cmdline/io.c.func.html
+++ b/cov/cmdline/io.c.func.html
@@ -65,7 +65,7 @@
| io_data_read_thread |
- 870894 |
+ 871422 |
| io_done |
@@ -89,11 +89,11 @@
| io_parity_write_thread |
- 553420 |
+ 553948 |
| io_position_next |
- 161997 |
+ 162085 |
| io_read_next_mono |
@@ -101,23 +101,23 @@
| io_read_next_thread |
- 145244 |
+ 145332 |
| io_reader_sched |
- 161997 |
+ 162085 |
| io_reader_step |
- 1162427 |
+ 1163270 |
| io_reader_thread |
- 647 |
+ 648 |
| io_reader_worker |
- 1081680 |
+ 1082209 |
| io_refresh_mono |
@@ -149,7 +149,7 @@
| io_task_read_thread |
- 1081698 |
+ 1082226 |
| io_write_next_mono |
@@ -157,7 +157,7 @@
| io_write_next_thread |
- 110015 |
+ 110103 |
| io_write_preset_mono |
@@ -165,19 +165,19 @@
| io_write_preset_thread |
- 110015 |
+ 110103 |
| io_writer_sched |
- 112401 |
+ 112474 |
| io_writer_sched_empty |
- 2301 |
+ 2316 |
| io_writer_step |
- 553871 |
+ 554398 |
| io_writer_thread |
diff --git a/cov/cmdline/io.c.gcov.html b/cov/cmdline/io.c.gcov.html
index 448aa441..295b5f22 100644
--- a/cov/cmdline/io.c.gcov.html
+++ b/cov/cmdline/io.c.gcov.html
@@ -84,103 +84,103 @@
22 : /**
23 : * Get the next block position to process.
24 : */
- 25 161997 : static block_off_t io_position_next(struct snapraid_io* io)
+ 25 162085 : static block_off_t io_position_next(struct snapraid_io* io)
26 : {
27 : block_off_t blockcur;
28 :
29 : /* get the next position */
- 30 647430 : while (io->block_next < io->block_max && !io->block_is_enabled(io->block_arg, io->block_next))
- 31 323436 : ++io->block_next;
+ 30 647518 : while (io->block_next < io->block_max && !io->block_is_enabled(io->block_arg, io->block_next))
+ 31 323348 : ++io->block_next;
32 :
- 33 161997 : blockcur = io->block_next;
+ 33 162085 : blockcur = io->block_next;
34 :
35 : /* next block for the next call */
- 36 161997 : ++io->block_next;
+ 36 162085 : ++io->block_next;
37 :
- 38 161997 : return blockcur;
+ 38 162085 : return blockcur;
39 : }
40 :
41 : /**
42 : * Setup the next pending task for all readers.
43 : */
- 44 161997 : static void io_reader_sched(struct snapraid_io* io, int task_index, block_off_t blockcur)
+ 44 162085 : static void io_reader_sched(struct snapraid_io* io, int task_index, block_off_t blockcur)
45 : {
46 : unsigned i;
47 :
- 48 1354767 : for (i = 0; i < io->reader_max; ++i) {
- 49 1192770 : struct snapraid_worker* worker = &io->reader_map[i];
- 50 1192770 : struct snapraid_task* task = &worker->task_map[task_index];
+ 48 1355383 : for (i = 0; i < io->reader_max; ++i) {
+ 49 1193298 : struct snapraid_worker* worker = &io->reader_map[i];
+ 50 1193298 : struct snapraid_task* task = &worker->task_map[task_index];
51 :
52 : /* setup the new pending task */
- 53 1192770 : if (blockcur < io->block_max)
- 54 1109820 : task->state = TASK_STATE_READY;
+ 53 1193298 : if (blockcur < io->block_max)
+ 54 1110348 : task->state = TASK_STATE_READY;
55 : else
56 82950 : task->state = TASK_STATE_EMPTY;
57 :
- 58 1192770 : task->path[0] = 0;
- 59 1192770 : if (worker->handle)
- 60 971982 : task->disk = worker->handle->disk;
+ 58 1193298 : task->path[0] = 0;
+ 59 1193298 : if (worker->handle)
+ 60 972510 : task->disk = worker->handle->disk;
61 : else
62 220788 : task->disk = 0;
- 63 1192770 : task->buffer = io->buffer_map[task_index][worker->buffer_skew + i];
- 64 1192770 : task->position = blockcur;
- 65 1192770 : task->block = 0;
- 66 1192770 : task->file = 0;
- 67 1192770 : task->file_pos = 0;
- 68 1192770 : task->read_size = 0;
- 69 1192770 : task->is_timestamp_different = 0;
+ 63 1193298 : task->buffer = io->buffer_map[task_index][worker->buffer_skew + i];
+ 64 1193298 : task->position = blockcur;
+ 65 1193298 : task->block = 0;
+ 66 1193298 : task->file = 0;
+ 67 1193298 : task->file_pos = 0;
+ 68 1193298 : task->read_size = 0;
+ 69 1193298 : task->is_timestamp_different = 0;
70 : }
- 71 161997 : }
+ 71 162085 : }
72 :
73 : /**
74 : * Setup the next pending task for all writers.
75 : */
- 76 112401 : static void io_writer_sched(struct snapraid_io* io, int task_index, block_off_t blockcur)
+ 76 112474 : static void io_writer_sched(struct snapraid_io* io, int task_index, block_off_t blockcur)
77 : {
78 : unsigned i;
79 :
- 80 656702 : for (i = 0; i < io->writer_max; ++i) {
- 81 544301 : struct snapraid_worker* worker = &io->writer_map[i];
- 82 544301 : struct snapraid_task* task = &worker->task_map[task_index];
+ 80 657213 : for (i = 0; i < io->writer_max; ++i) {
+ 81 544739 : struct snapraid_worker* worker = &io->writer_map[i];
+ 82 544739 : struct snapraid_task* task = &worker->task_map[task_index];
83 :
84 : /* setup the new pending task */
- 85 544301 : task->state = TASK_STATE_READY;
- 86 544301 : task->path[0] = 0;
- 87 544301 : task->disk = 0;
- 88 544301 : task->buffer = io->buffer_map[task_index][worker->buffer_skew + i];
- 89 544301 : task->position = blockcur;
- 90 544301 : task->block = 0;
- 91 544301 : task->file = 0;
- 92 544301 : task->file_pos = 0;
- 93 544301 : task->read_size = 0;
- 94 544301 : task->is_timestamp_different = 0;
+ 85 544739 : task->state = TASK_STATE_READY;
+ 86 544739 : task->path[0] = 0;
+ 87 544739 : task->disk = 0;
+ 88 544739 : task->buffer = io->buffer_map[task_index][worker->buffer_skew + i];
+ 89 544739 : task->position = blockcur;
+ 90 544739 : task->block = 0;
+ 91 544739 : task->file = 0;
+ 92 544739 : task->file_pos = 0;
+ 93 544739 : task->read_size = 0;
+ 94 544739 : task->is_timestamp_different = 0;
95 : }
- 96 112401 : }
+ 96 112474 : }
97 :
98 : /**
99 : * Setup an empty next pending task for all writers.
100 : */
- 101 2301 : static void io_writer_sched_empty(struct snapraid_io* io, int task_index, block_off_t blockcur)
+ 101 2316 : static void io_writer_sched_empty(struct snapraid_io* io, int task_index, block_off_t blockcur)
102 : {
103 : unsigned i;
104 :
- 105 16107 : for (i = 0; i < io->writer_max; ++i) {
- 106 13806 : struct snapraid_worker* worker = &io->writer_map[i];
- 107 13806 : struct snapraid_task* task = &worker->task_map[task_index];
+ 105 16212 : for (i = 0; i < io->writer_max; ++i) {
+ 106 13896 : struct snapraid_worker* worker = &io->writer_map[i];
+ 107 13896 : struct snapraid_task* task = &worker->task_map[task_index];
108 :
109 : /* setup the new pending task */
- 110 13806 : task->state = TASK_STATE_EMPTY;
- 111 13806 : task->path[0] = 0;
- 112 13806 : task->disk = 0;
- 113 13806 : task->buffer = 0;
- 114 13806 : task->position = blockcur;
- 115 13806 : task->block = 0;
- 116 13806 : task->file = 0;
- 117 13806 : task->file_pos = 0;
- 118 13806 : task->read_size = 0;
- 119 13806 : task->is_timestamp_different = 0;
+ 110 13896 : task->state = TASK_STATE_EMPTY;
+ 111 13896 : task->path[0] = 0;
+ 112 13896 : task->disk = 0;
+ 113 13896 : task->buffer = 0;
+ 114 13896 : task->position = blockcur;
+ 115 13896 : task->block = 0;
+ 116 13896 : task->file = 0;
+ 117 13896 : task->file_pos = 0;
+ 118 13896 : task->read_size = 0;
+ 119 13896 : task->is_timestamp_different = 0;
120 : }
- 121 2301 : }
+ 121 2316 : }
122 :
123 : /*****************************************************************************/
124 : /* mono thread */
@@ -331,55 +331,55 @@
269 : *
270 : * This is the synchronization point for workers with the io.
271 : */
- 272 1162427 : static struct snapraid_task* io_reader_step(struct snapraid_worker* worker)
+ 272 1163270 : static struct snapraid_task* io_reader_step(struct snapraid_worker* worker)
273 : {
- 274 1162427 : struct snapraid_io* io = worker->io;
+ 274 1163270 : struct snapraid_io* io = worker->io;
275 :
276 : /* the synchronization is protected by the io mutex */
- 277 1162427 : thread_mutex_lock(&io->io_mutex);
+ 277 1163270 : thread_mutex_lock(&io->io_mutex);
278 :
279 : while (1) {
280 : unsigned next_index;
281 :
282 : /* check if the worker has to exit */
283 : /* even if there is work to do */
- 284 2113405 : if (io->done) {
+ 284 2115537 : if (io->done) {
285 648 : thread_mutex_unlock(&io->io_mutex);
286 648 : return 0;
287 : }
288 :
289 : /* get the next pending task */
- 290 2112757 : next_index = (worker->index + 1) % io->io_max;
+ 290 2114889 : next_index = (worker->index + 1) % io->io_max;
291 :
292 : /* if the queue of pending tasks is not empty */
- 293 2112757 : if (next_index != io->reader_index) {
+ 293 2114889 : if (next_index != io->reader_index) {
294 : struct snapraid_task* task;
295 :
296 : /* the index that the IO may be waiting for */
- 297 1162458 : unsigned waiting_index = io->reader_index;
+ 297 1163467 : unsigned waiting_index = io->reader_index;
298 :
299 : /* the index that worker just completed */
- 300 1162458 : unsigned done_index = worker->index;
+ 300 1163467 : unsigned done_index = worker->index;
301 :
302 : /* get the new working task */
- 303 1162458 : worker->index = next_index;
- 304 1162458 : task = &worker->task_map[worker->index];
+ 303 1163467 : worker->index = next_index;
+ 304 1163467 : task = &worker->task_map[worker->index];
305 :
306 : /* if the just completed task is at this index */
- 307 1162458 : if (done_index == waiting_index) {
+ 307 1163467 : if (done_index == waiting_index) {
308 : /* notify the IO that a new read is complete */
- 309 2144 : thread_cond_signal_and_unlock(&io->read_done, &io->io_mutex);
+ 309 1460 : thread_cond_signal_and_unlock(&io->read_done, &io->io_mutex);
310 : } else {
- 311 1160314 : thread_mutex_unlock(&io->io_mutex);
+ 311 1162007 : thread_mutex_unlock(&io->io_mutex);
312 : }
313 :
314 : /* return the new task */
- 315 1162363 : return task;
+ 315 1163329 : return task;
316 : }
317 :
318 : /* otherwise wait for a read_sched event */
- 319 950299 : thread_cond_wait(&io->read_sched, &io->io_mutex);
- 320 950299 : }
+ 319 951422 : thread_cond_wait(&io->read_sched, &io->io_mutex);
+ 320 951422 : }
321 : }
322 :
323 : /**
@@ -387,61 +387,61 @@
325 : *
326 : * This is the synchronization point for workers with the io.
327 : */
- 328 553871 : static struct snapraid_task* io_writer_step(struct snapraid_worker* worker, int state)
+ 328 554398 : static struct snapraid_task* io_writer_step(struct snapraid_worker* worker, int state)
329 : {
- 330 553871 : struct snapraid_io* io = worker->io;
+ 330 554398 : struct snapraid_io* io = worker->io;
331 : int error_index;
332 :
333 : /* the synchronization is protected by the io mutex */
- 334 553871 : thread_mutex_lock(&io->io_mutex);
+ 334 554398 : thread_mutex_lock(&io->io_mutex);
335 :
336 : /* counts the number of errors in the global state */
- 337 553882 : error_index = state - IO_WRITER_ERROR_BASE;
- 338 553882 : if (error_index >= 0 && error_index < IO_WRITER_ERROR_MAX)
+ 337 554410 : error_index = state - IO_WRITER_ERROR_BASE;
+ 338 554410 : if (error_index >= 0 && error_index < IO_WRITER_ERROR_MAX)
339 0 : ++io->writer_error[error_index];
340 :
341 : while (1) {
342 : unsigned next_index;
343 :
344 : /* get the next pending task */
- 345 630858 : next_index = (worker->index + 1) % io->io_max;
+ 345 631068 : next_index = (worker->index + 1) % io->io_max;
346 :
347 : /* if the queue of pending tasks is not empty */
- 348 630858 : if (next_index != io->writer_index) {
+ 348 631068 : if (next_index != io->writer_index) {
349 : struct snapraid_task* task;
350 :
351 : /* the index that the IO may be waiting for */
- 352 553420 : unsigned waiting_index = (io->writer_index + 1) % io->io_max;
+ 352 553948 : unsigned waiting_index = (io->writer_index + 1) % io->io_max;
353 :
354 : /* the index that worker just completed */
- 355 553420 : unsigned done_index = worker->index;
+ 355 553948 : unsigned done_index = worker->index;
356 :
357 : /* get the new working task */
- 358 553420 : worker->index = next_index;
- 359 553420 : task = &worker->task_map[worker->index];
+ 358 553948 : worker->index = next_index;
+ 359 553948 : task = &worker->task_map[worker->index];
360 :
361 : /* if the just completed task is at this index */
- 362 553420 : if (done_index == waiting_index) {
+ 362 553948 : if (done_index == waiting_index) {
363 : /* notify the IO that a new write is complete */
- 364 82404 : thread_cond_signal_and_unlock(&io->write_done, &io->io_mutex);
+ 364 81705 : thread_cond_signal_and_unlock(&io->write_done, &io->io_mutex);
365 : } else {
- 366 471016 : thread_mutex_unlock(&io->io_mutex);
+ 366 472243 : thread_mutex_unlock(&io->io_mutex);
367 : }
368 :
369 : /* return the new task */
- 370 553404 : return task;
+ 370 553938 : return task;
371 : }
372 :
373 : /* check if the worker has to exit */
374 : /* but only if there is no work to do */
- 375 77438 : if (io->done) {
+ 375 77120 : if (io->done) {
376 462 : thread_mutex_unlock(&io->io_mutex);
377 462 : return 0;
378 : }
379 :
380 : /* otherwise wait for a write_sched event */
- 381 76976 : thread_cond_wait(&io->write_sched, &io->io_mutex);
- 382 76976 : }
+ 381 76658 : thread_cond_wait(&io->write_sched, &io->io_mutex);
+ 382 76658 : }
383 : }
384 :
385 : /**
@@ -449,87 +449,87 @@
387 : *
388 : * This is the synchronization point for workers with the io.
389 : */
- 390 145244 : static block_off_t io_read_next_thread(struct snapraid_io* io, void*** buffer)
+ 390 145332 : static block_off_t io_read_next_thread(struct snapraid_io* io, void*** buffer)
391 : {
392 : block_off_t blockcur_schedule;
393 : block_off_t blockcur_caller;
394 : unsigned i;
395 :
396 : /* get the next parity position to process */
- 397 145244 : blockcur_schedule = io_position_next(io);
+ 397 145332 : blockcur_schedule = io_position_next(io);
398 :
399 : /* ensure that all data/parity was read */
- 400 145244 : assert(io->reader_list[0] == io->reader_max);
+ 400 145332 : assert(io->reader_list[0] == io->reader_max);
401 :
402 : /* setup the list of workers to process */
- 403 1372834 : for (i = 0; i <= io->reader_max; ++i)
- 404 1227590 : io->reader_list[i] = i;
+ 403 1373538 : for (i = 0; i <= io->reader_max; ++i)
+ 404 1228206 : io->reader_list[i] = i;
405 :
406 : /* the synchronization is protected by the io mutex */
- 407 145244 : thread_mutex_lock(&io->io_mutex);
+ 407 145332 : thread_mutex_lock(&io->io_mutex);
408 :
409 : /* schedule the next read */
- 410 145244 : io_reader_sched(io, io->reader_index, blockcur_schedule);
+ 410 145332 : io_reader_sched(io, io->reader_index, blockcur_schedule);
411 :
412 : /* set the index for the tasks to return to the caller */
- 413 145244 : io->reader_index = (io->reader_index + 1) % io->io_max;
+ 413 145332 : io->reader_index = (io->reader_index + 1) % io->io_max;
414 :
415 : /* get the position to operate at high level from one task */
- 416 145244 : blockcur_caller = io->reader_map[0].task_map[io->reader_index].position;
+ 416 145332 : blockcur_caller = io->reader_map[0].task_map[io->reader_index].position;
417 :
418 : /* set the buffer to use */
- 419 145244 : *buffer = io->buffer_map[io->reader_index];
+ 419 145332 : *buffer = io->buffer_map[io->reader_index];
420 :
421 : /* signal all the workers that there is a new pending task */
- 422 145244 : thread_cond_broadcast_and_unlock(&io->read_sched, &io->io_mutex);
+ 422 145332 : thread_cond_broadcast_and_unlock(&io->read_sched, &io->io_mutex);
423 :
- 424 145244 : return blockcur_caller;
+ 424 145332 : return blockcur_caller;
425 : }
426 :
- 427 110015 : static void io_write_preset_thread(struct snapraid_io* io, block_off_t blockcur, int skip)
+ 427 110103 : static void io_write_preset_thread(struct snapraid_io* io, block_off_t blockcur, int skip)
428 : {
429 : (void)io;
430 : (void)blockcur;
431 : (void)skip;
- 432 110015 : }
+ 432 110103 : }
433 :
- 434 110015 : static void io_write_next_thread(struct snapraid_io* io, block_off_t blockcur, int skip, int* writer_error)
+ 434 110103 : static void io_write_next_thread(struct snapraid_io* io, block_off_t blockcur, int skip, int* writer_error)
435 : {
436 : unsigned i;
437 :
438 : /* ensure that all parity was written */
- 439 110015 : assert(io->writer_list[0] == io->writer_max);
+ 439 110103 : assert(io->writer_list[0] == io->writer_max);
440 :
441 : /* setup the list of workers to process */
- 442 773450 : for (i = 0; i <= io->writer_max; ++i)
- 443 663435 : io->writer_list[i] = i;
+ 442 774154 : for (i = 0; i <= io->writer_max; ++i)
+ 443 664051 : io->writer_list[i] = i;
444 :
445 : /* the synchronization is protected by the io mutex */
- 446 110015 : thread_mutex_lock(&io->io_mutex);
+ 446 110103 : thread_mutex_lock(&io->io_mutex);
447 :
448 : /* report errors */
- 449 550075 : for (i = 0; i < IO_WRITER_ERROR_MAX; ++i) {
- 450 440060 : writer_error[i] = io->writer_error[i];
- 451 440060 : io->writer_error[i] = 0;
+ 449 550515 : for (i = 0; i < IO_WRITER_ERROR_MAX; ++i) {
+ 450 440412 : writer_error[i] = io->writer_error[i];
+ 451 440412 : io->writer_error[i] = 0;
452 : }
453 :
- 454 110015 : if (skip) {
+ 454 110103 : if (skip) {
455 : /* skip the next write */
- 456 2301 : io_writer_sched_empty(io, io->writer_index, blockcur);
+ 456 2316 : io_writer_sched_empty(io, io->writer_index, blockcur);
457 : } else {
458 : /* schedule the next write */
- 459 107714 : io_writer_sched(io, io->writer_index, blockcur);
+ 459 107787 : io_writer_sched(io, io->writer_index, blockcur);
460 : }
461 :
462 : /* at this point the writers must be in sync with the readers */
- 463 110015 : assert(io->writer_index == io->reader_index);
+ 463 110103 : assert(io->writer_index == io->reader_index);
464 :
465 : /* set the index to be used for the next write */
- 466 110015 : io->writer_index = (io->writer_index + 1) % io->io_max;
+ 466 110103 : io->writer_index = (io->writer_index + 1) % io->io_max;
467 :
468 : /* signal all the workers that there is a new pending task */
- 469 110015 : thread_cond_broadcast_and_unlock(&io->write_sched, &io->io_mutex);
- 470 110015 : }
+ 469 110103 : thread_cond_broadcast_and_unlock(&io->write_sched, &io->io_mutex);
+ 470 110103 : }
471 :
472 0 : static void io_refresh_thread(struct snapraid_io* io)
473 : {
@@ -577,18 +577,18 @@
515 0 : thread_mutex_unlock(&io->io_mutex);
516 0 : }
517 :
- 518 1081698 : static struct snapraid_task* io_task_read_thread(struct snapraid_io* io, unsigned base, unsigned count, unsigned* pos, unsigned* waiting_map, unsigned* waiting_mac)
+ 518 1082226 : static struct snapraid_task* io_task_read_thread(struct snapraid_io* io, unsigned base, unsigned count, unsigned* pos, unsigned* waiting_map, unsigned* waiting_mac)
519 : {
520 : unsigned waiting_cycle;
521 :
522 : /* count the waiting cycle */
- 523 1081698 : waiting_cycle = 0;
+ 523 1082226 : waiting_cycle = 0;
524 :
525 : /* clear the waiting indexes */
- 526 1081698 : *waiting_mac = 0;
+ 526 1082226 : *waiting_mac = 0;
527 :
528 : /* the synchronization is protected by the io mutex */
- 529 1081698 : thread_mutex_lock(&io->io_mutex);
+ 529 1082226 : thread_mutex_lock(&io->io_mutex);
530 :
531 : while (1) {
532 : unsigned char* let;
@@ -597,67 +597,67 @@
535 : /* get the index the IO is using */
536 : /* we must ensure that this index has not a read in progress */
537 : /* to avoid a concurrent access */
- 538 1083699 : busy_index = io->reader_index;
+ 538 1083535 : busy_index = io->reader_index;
539 :
540 : /* search for a worker that has already finished */
- 541 1083699 : let = &io->reader_list[0];
+ 541 1083535 : let = &io->reader_list[0];
542 : while (1) {
- 543 1091880 : unsigned i = *let;
+ 543 1090052 : unsigned i = *let;
544 :
545 : /* if we are at the end */
- 546 1091880 : if (i == io->reader_max)
- 547 2001 : break;
+ 546 1090052 : if (i == io->reader_max)
+ 547 1309 : break;
548 :
549 : /* if it's in range */
- 550 1089879 : if (base <= i && i < base + count) {
+ 550 1088743 : if (base <= i && i < base + count) {
551 : struct snapraid_worker* worker;
552 :
553 : /* if it's the first cycle */
- 554 1088355 : if (waiting_cycle == 0) {
+ 554 1087753 : if (waiting_cycle == 0) {
555 : /* store the waiting indexes */
- 556 1085928 : waiting_map[(*waiting_mac)++] = i - base;
+ 556 1086091 : waiting_map[(*waiting_mac)++] = i - base;
557 : }
558 :
- 559 1088355 : worker = &io->reader_map[i];
+ 559 1087753 : worker = &io->reader_map[i];
560 :
561 : /* if the worker has finished this index */
- 562 1088355 : if (busy_index != worker->index) {
+ 562 1087753 : if (busy_index != worker->index) {
563 : struct snapraid_task* task;
564 :
- 565 1081698 : task = &worker->task_map[io->reader_index];
+ 565 1082226 : task = &worker->task_map[io->reader_index];
566 :
- 567 1081698 : thread_mutex_unlock(&io->io_mutex);
+ 567 1082226 : thread_mutex_unlock(&io->io_mutex);
568 :
569 : /* mark the worker as processed */
570 : /* setting the previous one to point at the next one */
- 571 1081698 : *let = io->reader_list[i + 1];
+ 571 1082226 : *let = io->reader_list[i + 1];
572 :
573 : /* return the position */
- 574 1081698 : *pos = i - base;
+ 574 1082226 : *pos = i - base;
575 :
576 : /* on the first cycle, no one is waiting */
- 577 1081698 : if (waiting_cycle == 0)
- 578 1079732 : *waiting_mac = 0;
+ 577 1082226 : if (waiting_cycle == 0)
+ 578 1080944 : *waiting_mac = 0;
579 :
- 580 2163396 : return task;
+ 580 2164452 : return task;
581 : }
582 : }
583 :
584 : /* next position to check */
- 585 8181 : let = &io->reader_list[i + 1];
- 586 8181 : }
+ 585 6517 : let = &io->reader_list[i + 1];
+ 586 6517 : }
587 :
588 : /* if no worker is ready, wait for an event */
- 589 2001 : thread_cond_wait(&io->read_done, &io->io_mutex);
+ 589 1309 : thread_cond_wait(&io->read_done, &io->io_mutex);
590 :
591 : /* count the cycles */
- 592 2001 : ++waiting_cycle;
- 593 2001 : }
+ 592 1309 : ++waiting_cycle;
+ 593 1309 : }
594 : }
595 :
- 596 870894 : static struct snapraid_task* io_data_read_thread(struct snapraid_io* io, unsigned* pos, unsigned* waiting_map, unsigned* waiting_mac)
+ 596 871422 : static struct snapraid_task* io_data_read_thread(struct snapraid_io* io, unsigned* pos, unsigned* waiting_map, unsigned* waiting_mac)
597 : {
- 598 870894 : return io_task_read_thread(io, io->data_base, io->data_count, pos, waiting_map, waiting_mac);
+ 598 871422 : return io_task_read_thread(io, io->data_base, io->data_count, pos, waiting_map, waiting_mac);
599 : }
600 :
601 210804 : static struct snapraid_task* io_parity_read_thread(struct snapraid_io* io, unsigned* pos, unsigned* waiting_map, unsigned* waiting_mac)
@@ -665,18 +665,18 @@
603 210804 : return io_task_read_thread(io, io->parity_base, io->parity_count, pos, waiting_map, waiting_mac);
604 : }
605 :
- 606 553420 : static void io_parity_write_thread(struct snapraid_io* io, unsigned* pos, unsigned* waiting_map, unsigned* waiting_mac)
+ 606 553948 : static void io_parity_write_thread(struct snapraid_io* io, unsigned* pos, unsigned* waiting_map, unsigned* waiting_mac)
607 : {
608 : unsigned waiting_cycle;
609 :
610 : /* count the waiting cycle */
- 611 553420 : waiting_cycle = 0;
+ 611 553948 : waiting_cycle = 0;
612 :
613 : /* clear the waiting indexes */
- 614 553420 : *waiting_mac = 0;
+ 614 553948 : *waiting_mac = 0;
615 :
616 : /* the synchronization is protected by the io mutex */
- 617 553420 : thread_mutex_lock(&io->io_mutex);
+ 617 553948 : thread_mutex_lock(&io->io_mutex);
618 :
619 : while (1) {
620 : unsigned char* let;
@@ -687,96 +687,96 @@
625 : /* to avoid a concurrent access */
626 : /* note that we are already sure that a write is not in progress */
627 : /* at the index the IO is using at now */
- 628 619337 : busy_index = (io->writer_index + 1) % io->io_max;
+ 628 619618 : busy_index = (io->writer_index + 1) % io->io_max;
629 :
630 : /* search for a worker that has already finished */
- 631 619337 : let = &io->writer_list[0];
+ 631 619618 : let = &io->writer_list[0];
632 : while (1) {
- 633 866114 : unsigned i = *let;
+ 633 802324 : unsigned i = *let;
634 : struct snapraid_worker* worker;
635 :
636 : /* if we are at the end */
- 637 866114 : if (i == io->writer_max)
- 638 65917 : break;
+ 637 802324 : if (i == io->writer_max)
+ 638 65670 : break;
639 :
640 : /* if it's the first cycle */
- 641 800197 : if (waiting_cycle == 0) {
+ 641 736654 : if (waiting_cycle == 0) {
642 : /* store the waiting indexes */
- 643 733517 : waiting_map[(*waiting_mac)++] = i;
+ 643 670497 : waiting_map[(*waiting_mac)++] = i;
644 : }
645 :
- 646 800197 : worker = &io->writer_map[i];
+ 646 736654 : worker = &io->writer_map[i];
647 :
648 : /* the two indexes cannot be equal */
- 649 800197 : assert(io->writer_index != worker->index);
+ 649 736654 : assert(io->writer_index != worker->index);
650 :
651 : /* if the worker has finished this index */
- 652 800197 : if (busy_index != worker->index) {
- 653 553420 : thread_mutex_unlock(&io->io_mutex);
+ 652 736654 : if (busy_index != worker->index) {
+ 653 553948 : thread_mutex_unlock(&io->io_mutex);
654 :
655 : /* mark the worker as processed */
656 : /* setting the previous one to point at the next one */
- 657 553420 : *let = io->writer_list[i + 1];
+ 657 553948 : *let = io->writer_list[i + 1];
658 :
659 : /* return the position */
- 660 553420 : *pos = i;
+ 660 553948 : *pos = i;
661 :
662 : /* on the first cycle, no one is waiting */
- 663 553420 : if (waiting_cycle == 0)
- 664 487503 : *waiting_mac = 0;
+ 663 553948 : if (waiting_cycle == 0)
+ 664 488278 : *waiting_mac = 0;
665 :
- 666 1106840 : return;
+ 666 1107896 : return;
667 : }
668 :
669 : /* next position to check */
- 670 246777 : let = &io->writer_list[i + 1];
- 671 246777 : }
+ 670 182706 : let = &io->writer_list[i + 1];
+ 671 182706 : }
672 :
673 : /* if no worker is ready, wait for an event */
- 674 65917 : thread_cond_wait(&io->write_done, &io->io_mutex);
+ 674 65670 : thread_cond_wait(&io->write_done, &io->io_mutex);
675 :
676 : /* count the cycles */
- 677 65917 : ++waiting_cycle;
- 678 65917 : }
+ 677 65670 : ++waiting_cycle;
+ 678 65670 : }
679 : }
680 :
- 681 1081680 : static void io_reader_worker(struct snapraid_worker* worker, struct snapraid_task* task)
+ 681 1082209 : static void io_reader_worker(struct snapraid_worker* worker, struct snapraid_task* task)
682 : {
683 : /* if we reached the end */
- 684 1081680 : if (task->position >= worker->io->block_max) {
+ 684 1082209 : if (task->position >= worker->io->block_max) {
685 : /* complete a dummy task */
686 120 : task->state = TASK_STATE_EMPTY;
687 : } else {
- 688 1081560 : worker->func(worker, task);
+ 688 1082089 : worker->func(worker, task);
689 : }
- 690 1081228 : }
+ 690 1081822 : }
691 :
- 692 647 : static void* io_reader_thread(void* arg)
+ 692 648 : static void* io_reader_thread(void* arg)
693 : {
- 694 647 : struct snapraid_worker* worker = arg;
+ 694 648 : struct snapraid_worker* worker = arg;
695 :
696 : /* force completion of the first task */
- 697 647 : io_reader_worker(worker, &worker->task_map[0]);
+ 697 648 : io_reader_worker(worker, &worker->task_map[0]);
698 :
699 : while (1) {
700 : struct snapraid_task* task;
701 :
702 : /* get the new task */
- 703 1162533 : task = io_reader_step(worker);
+ 703 1163504 : task = io_reader_step(worker);
704 :
705 : /* if no task, it means to exit */
- 706 1162963 : if (!task)
+ 706 1163910 : if (!task)
707 648 : break;
708 :
709 : /* nothing more to do */
- 710 1162315 : if (task->state == TASK_STATE_EMPTY)
- 711 81255 : continue;
+ 710 1163262 : if (task->state == TASK_STATE_EMPTY)
+ 711 81670 : continue;
712 :
- 713 1081060 : assert(task->state == TASK_STATE_READY);
+ 713 1081592 : assert(task->state == TASK_STATE_READY);
714 :
715 : /* work on the assigned task */
- 716 1081060 : io_reader_worker(worker, task);
- 717 1161887 : }
+ 716 1081592 : io_reader_worker(worker, task);
+ 717 1162859 : }
718 :
719 648 : return 0;
720 : }
@@ -790,26 +790,26 @@
728 : struct snapraid_task* task;
729 :
730 : /* get the new task */
- 731 553873 : task = io_writer_step(worker, latest_state);
+ 731 554402 : task = io_writer_step(worker, latest_state);
732 :
733 : /* if no task, it means to exit */
- 734 553876 : if (!task)
+ 734 554405 : if (!task)
735 462 : break;
736 :
737 : /* nothing more to do */
- 738 553414 : if (task->state == TASK_STATE_EMPTY) {
- 739 13808 : latest_state = TASK_STATE_DONE;
- 740 13808 : continue;
+ 738 553943 : if (task->state == TASK_STATE_EMPTY) {
+ 739 13898 : latest_state = TASK_STATE_DONE;
+ 740 13898 : continue;
741 : }
742 :
- 743 539606 : assert(task->state == TASK_STATE_READY);
+ 743 540045 : assert(task->state == TASK_STATE_READY);
744 :
745 : /* work on the assigned task */
- 746 539606 : worker->func(worker, task);
+ 746 540045 : worker->func(worker, task);
747 :
748 : /* save the resulting state */
- 749 539603 : latest_state = task->state;
- 750 553411 : }
+ 749 540042 : latest_state = task->state;
+ 750 553940 : }
751 :
752 462 : return 0;
753 : }
diff --git a/cov/cmdline/mktest.c.func-sort-c.html b/cov/cmdline/mktest.c.func-sort-c.html
index 27d6466e..50149ba0 100644
--- a/cov/cmdline/mktest.c.func-sort-c.html
+++ b/cov/cmdline/mktest.c.func-sort-c.html
@@ -61,23 +61,23 @@
| rnd |
- 56057797 |
+ 56068924 |
| rndnz |
- 55646605 |
+ 55657385 |
| file_cmp |
- 146556 |
+ 146572 |
| rndnz_range |
- 32690 |
+ 32675 |
| rnd_name |
- 26841 |
+ 26852 |
| cmd_generate |
@@ -93,19 +93,19 @@
| cmd_write |
- 6226 |
+ 6254 |
| cmd_append |
- 3224 |
-
-
- | cmd_delete |
- 3222 |
+ 3181 |
| cmd_truncate |
- 3082 |
+ 3162 |
+
+
+ | cmd_delete |
+ 3155 |
| cmd_damage |
@@ -121,7 +121,7 @@
| cmd_generate_symlink |
- 932 |
+ 943 |
| main |
diff --git a/cov/cmdline/mktest.c.func.html b/cov/cmdline/mktest.c.func.html
index 18bde35a..8869dfc5 100644
--- a/cov/cmdline/mktest.c.func.html
+++ b/cov/cmdline/mktest.c.func.html
@@ -61,7 +61,7 @@
| cmd_append |
- 3224 |
+ 3181 |
| cmd_change |
@@ -73,7 +73,7 @@
| cmd_delete |
- 3222 |
+ 3155 |
| cmd_generate |
@@ -85,15 +85,15 @@
| cmd_generate_symlink |
- 932 |
+ 943 |
| cmd_truncate |
- 3082 |
+ 3162 |
| cmd_write |
- 6226 |
+ 6254 |
| fallback |
@@ -101,7 +101,7 @@
| file_cmp |
- 146556 |
+ 146572 |
| help |
@@ -113,15 +113,15 @@
| rnd |
- 56057797 |
+ 56068924 |
| rnd_name |
- 26841 |
+ 26852 |
| rndnz |
- 55646605 |
+ 55657385 |
| rndnz_damage |
@@ -129,7 +129,7 @@
| rndnz_range |
- 32690 |
+ 32675 |
diff --git a/cov/cmdline/mktest.c.gcov.html b/cov/cmdline/mktest.c.gcov.html
index 4c422f75..9de78039 100644
--- a/cov/cmdline/mktest.c.gcov.html
+++ b/cov/cmdline/mktest.c.gcov.html
@@ -89,28 +89,28 @@
27 : */
28 : unsigned long long seed = 0;
29 :
- 30 56057797 : unsigned rnd(unsigned max)
+ 30 56068924 : unsigned rnd(unsigned max)
31 : {
- 32 56057797 : seed = seed * 6364136223846793005LL + 1442695040888963407LL;
+ 32 56068924 : seed = seed * 6364136223846793005LL + 1442695040888963407LL;
33 :
- 34 56057797 : return (seed >> 32) % max;
+ 34 56068924 : return (seed >> 32) % max;
35 : }
36 :
- 37 55646605 : unsigned rndnz(unsigned max)
+ 37 55657385 : unsigned rndnz(unsigned max)
38 : {
- 39 55646605 : if (max <= 1)
+ 39 55657385 : if (max <= 1)
40 2831 : return 1;
41 : else
- 42 55643774 : return rnd(max - 1) + 1;
+ 42 55654554 : return rnd(max - 1) + 1;
43 : }
44 :
- 45 32690 : void rndnz_range(unsigned char* data, int size)
+ 45 32675 : void rndnz_range(unsigned char* data, int size)
46 : {
47 : int i;
48 :
- 49 55672532 : for (i = 0; i < size; ++i)
- 50 55639842 : data[i] = rndnz(256);
- 51 32690 : }
+ 49 55683297 : for (i = 0; i < size; ++i)
+ 50 55650622 : data[i] = rndnz(256);
+ 51 32675 : }
52 :
53 1821 : void rndnz_damage(unsigned char* data, int size)
54 : {
@@ -131,23 +131,23 @@
69 : char CHARSET[] = "qwertyuiopasdfghjklzxcvbnm1234567890 .-+";
70 : #define CHARSET_LEN (sizeof(CHARSET) - 1)
71 :
- 72 26841 : void rnd_name(char* file)
+ 72 26852 : void rnd_name(char* file)
73 : {
- 74 26841 : int l = 1 + rnd(20);
+ 74 26852 : int l = 1 + rnd(20);
75 :
- 76 335354 : while (l) {
- 77 281672 : *file++ = CHARSET[rnd(CHARSET_LEN)];
- 78 281672 : --l;
+ 76 335716 : while (l) {
+ 77 282012 : *file++ = CHARSET[rnd(CHARSET_LEN)];
+ 78 282012 : --l;
79 : }
- 80 26841 : *file = 0;
- 81 26841 : }
+ 80 26852 : *file = 0;
+ 81 26852 : }
82 :
83 : /****************************************************************************/
84 : /* file */
85 :
- 86 146556 : int file_cmp(const void* a, const void* b)
+ 86 146572 : int file_cmp(const void* a, const void* b)
87 : {
- 88 146556 : return strcmp(a, b);
+ 88 146572 : 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 932 : void cmd_generate_symlink(const char* path, const char* linkto)
+ 200 943 : void cmd_generate_symlink(const char* path, const char* linkto)
201 : {
202 : /* remove the existing file/symlink if any */
- 203 932 : if (remove(path) != 0) {
- 204 911 : if (errno != ENOENT) {
+ 203 943 : if (remove(path) != 0) {
+ 204 922 : 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 932 : if (symlink(linkto, path) != 0) {
+ 212 943 : 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 932 : }
+ 218 943 : }
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 6226 : void cmd_write(const char* path, int size)
+ 291 6254 : void cmd_write(const char* path, int size)
292 : {
293 : struct stat st;
294 :
- 295 6226 : if (lstat(path, &st) != 0) {
+ 295 6254 : 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 6226 : if (S_ISREG(st.st_mode)) {
+ 302 6254 : if (S_ISREG(st.st_mode)) {
303 : unsigned char* data;
304 : off_t off;
305 : int f;
306 :
307 : /* not over the end */
- 308 6199 : if (size > st.st_size)
- 309 687 : size = st.st_size;
+ 308 6227 : if (size > st.st_size)
+ 309 716 : size = st.st_size;
310 :
311 : /* start at random position inside the file */
- 312 6199 : if (size < st.st_size)
- 313 5511 : off = rnd(st.st_size - size);
+ 312 6227 : if (size < st.st_size)
+ 313 5510 : off = rnd(st.st_size - size);
314 : else
- 315 688 : off = 0;
+ 315 717 : off = 0;
316 :
- 317 6199 : data = malloc(size);
+ 317 6227 : data = malloc(size);
318 :
- 319 6199 : rndnz_range(data, size);
+ 319 6227 : rndnz_range(data, size);
320 :
- 321 6199 : f = open(path, O_WRONLY | O_BINARY | O_NOFOLLOW);
- 322 6199 : if (f < 0) {
+ 321 6227 : f = open(path, O_WRONLY | O_BINARY | O_NOFOLLOW);
+ 322 6227 : 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 6199 : if (lseek(f, off, SEEK_SET) != off) {
+ 329 6227 : 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 6199 : if (write(f, data, size) != size) {
+ 336 6227 : 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 6199 : if (close(f) != 0) {
+ 343 6227 : 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 6199 : free(data);
+ 350 6227 : free(data);
351 : }
- 352 6226 : }
+ 352 6254 : }
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 3224 : void cmd_append(const char* path, int size)
+ 459 3181 : void cmd_append(const char* path, int size)
460 : {
461 : struct stat st;
462 :
- 463 3224 : if (lstat(path, &st) != 0) {
+ 463 3181 : 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 3224 : if (S_ISREG(st.st_mode)) {
+ 470 3181 : if (S_ISREG(st.st_mode)) {
471 : unsigned char* data;
472 : int f;
473 :
- 474 3224 : data = malloc(size);
+ 474 3181 : data = malloc(size);
475 :
- 476 3224 : rndnz_range(data, size);
+ 476 3181 : rndnz_range(data, size);
477 :
- 478 3224 : f = open(path, O_WRONLY | O_APPEND | O_BINARY | O_NOFOLLOW);
- 479 3224 : if (f < 0) {
+ 478 3181 : f = open(path, O_WRONLY | O_APPEND | O_BINARY | O_NOFOLLOW);
+ 479 3181 : 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 3224 : if (write(f, data, size) != size) {
+ 486 3181 : 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 3224 : if (close(f) != 0) {
+ 493 3181 : 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 3224 : free(data);
+ 500 3181 : free(data);
501 : }
- 502 3224 : }
+ 502 3181 : }
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 3082 : void cmd_truncate(const char* path, int size)
+ 510 3162 : void cmd_truncate(const char* path, int size)
511 : {
512 : struct stat st;
513 :
- 514 3082 : if (lstat(path, &st) != 0) {
+ 514 3162 : 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 3082 : if (S_ISREG(st.st_mode)) {
+ 521 3162 : if (S_ISREG(st.st_mode)) {
522 : off_t off;
523 : int f;
524 :
525 : /* if file is empty, just rewrite it */
- 526 3082 : if (st.st_size == 0) {
- 527 7 : size = 0;
+ 526 3162 : if (st.st_size == 0) {
+ 527 4 : size = 0;
528 : } else {
529 : /* don't truncate files to 0 size to avoid ZERO file size protection */
- 530 3075 : if (size >= st.st_size)
- 531 185 : size = st.st_size - 1;
+ 530 3158 : if (size >= st.st_size)
+ 531 209 : size = st.st_size - 1;
532 : }
533 :
- 534 3082 : off = st.st_size - size;
+ 534 3162 : off = st.st_size - size;
535 :
- 536 3082 : f = open(path, O_WRONLY | O_BINARY | O_NOFOLLOW);
- 537 3082 : if (f < 0) {
+ 536 3162 : f = open(path, O_WRONLY | O_BINARY | O_NOFOLLOW);
+ 537 3162 : 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 3082 : if (ftruncate(f, off) != 0) {
+ 544 3162 : 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 3082 : if (close(f) != 0) {
+ 551 3162 : 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 3082 : }
+ 558 3162 : }
559 :
560 : /**
561 : * Delete a file.
562 : * - The file must exist.
563 : */
- 564 3222 : void cmd_delete(const char* path)
+ 564 3155 : void cmd_delete(const char* path)
565 : {
- 566 3222 : 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 3222 : }
+ 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 13157 : return;
+ 583 13160 : return;
584 :
- 585 13099 : if (lstat(path, &st) != 0) {
+ 585 13096 : 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 13099 : if (S_ISLNK(st.st_mode)) {
+ 592 13096 : if (S_ISLNK(st.st_mode)) {
593 : /* symlink */
- 594 394 : if (rnd(2) == 0) {
+ 594 393 : if (rnd(2) == 0) {
595 : /* delete */
- 596 195 : if (remove(path) != 0) {
+ 596 183 : 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 199 : if (remove(path) != 0) {
+ 606 210 : 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 199 : rnd_name(linkto);
+ 613 210 : rnd_name(linkto);
614 :
- 615 199 : cmd_generate_symlink(path, linkto);
+ 615 210 : cmd_generate_symlink(path, linkto);
616 : }
- 617 12705 : } else if (S_ISREG(st.st_mode)) {
+ 617 12703 : } else if (S_ISREG(st.st_mode)) {
618 : int r;
619 :
- 620 12705 : r = rnd(4);
+ 620 12703 : r = rnd(4);
621 :
- 622 12705 : if (r == 0) {
- 623 3177 : cmd_write(path, size);
- 624 9528 : } else if (r == 1) {
- 625 3224 : cmd_append(path, size);
- 626 6304 : } else if (r == 2) {
- 627 3082 : cmd_truncate(path, size);
+ 622 12703 : if (r == 0) {
+ 623 3205 : cmd_write(path, size);
+ 624 9498 : } else if (r == 1) {
+ 625 3181 : cmd_append(path, size);
+ 626 6317 : } else if (r == 2) {
+ 627 3162 : cmd_truncate(path, size);
628 : } else {
- 629 3222 : 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 db8791cf..36afb82e 100644
--- a/cov/cmdline/murmur3.c.func-sort-c.html
+++ b/cov/cmdline/murmur3.c.func-sort-c.html
@@ -61,11 +61,11 @@
| fmix32 |
- 8307308 |
+ 8307416 |
| MurmurHash3_x86_128 |
- 2076827 |
+ 2076854 |
diff --git a/cov/cmdline/murmur3.c.func.html b/cov/cmdline/murmur3.c.func.html
index 502e4614..4b31437b 100644
--- a/cov/cmdline/murmur3.c.func.html
+++ b/cov/cmdline/murmur3.c.func.html
@@ -61,11 +61,11 @@
| MurmurHash3_x86_128 |
- 2076827 |
+ 2076854 |
| fmix32 |
- 8307308 |
+ 8307416 |
diff --git a/cov/cmdline/murmur3.c.gcov.html b/cov/cmdline/murmur3.c.gcov.html
index 28177746..3d5c639f 100644
--- a/cov/cmdline/murmur3.c.gcov.html
+++ b/cov/cmdline/murmur3.c.gcov.html
@@ -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 8307308 : static inline uint32_t fmix32(uint32_t h)
+ 32 8307416 : static inline uint32_t fmix32(uint32_t h)
33 : {
- 34 8307308 : h ^= h >> 16;
- 35 8307308 : h *= 0x85ebca6b;
- 36 8307308 : h ^= h >> 13;
- 37 8307308 : h *= 0xc2b2ae35;
- 38 8307308 : h ^= h >> 16;
- 39 8307308 : return h;
+ 34 8307416 : h ^= h >> 16;
+ 35 8307416 : h *= 0x85ebca6b;
+ 36 8307416 : h ^= h >> 13;
+ 37 8307416 : h *= 0xc2b2ae35;
+ 38 8307416 : h ^= h >> 16;
+ 39 8307416 : return h;
40 : }
41 :
42 : /*
@@ -137,17 +137,17 @@
75 : uint32_t c3 = 0x38b34ae5;
76 : uint32_t c4 = 0xa1e38b93;
77 :
- 78 2076827 : void MurmurHash3_x86_128(const void* data, size_t size, const uint8_t* seed, void* digest)
+ 78 2076854 : 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 2076827 : uint32_t h1 = ((const uint32_t*)seed)[0];
- 86 2076827 : uint32_t h2 = ((const uint32_t*)seed)[1];
- 87 2076827 : uint32_t h3 = ((const uint32_t*)seed)[2];
- 88 2076827 : uint32_t h4 = ((const uint32_t*)seed)[3];
+ 85 2076854 : uint32_t h1 = ((const uint32_t*)seed)[0];
+ 86 2076854 : uint32_t h2 = ((const uint32_t*)seed)[1];
+ 87 2076854 : uint32_t h3 = ((const uint32_t*)seed)[2];
+ 88 2076854 : 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 2076827 : nblocks = size / 16;
- 98 2076827 : blocks = data;
- 99 2076827 : end = blocks + nblocks * 4;
+ 97 2076854 : nblocks = size / 16;
+ 98 2076854 : blocks = data;
+ 99 2076854 : end = blocks + nblocks * 4;
100 :
101 : /* body */
- 102 110683413 : while (blocks < end) {
- 103 106529759 : uint32_t k1 = blocks[0];
- 104 106529759 : uint32_t k2 = blocks[1];
- 105 106529759 : uint32_t k3 = blocks[2];
- 106 106529759 : uint32_t k4 = blocks[3];
+ 102 110685610 : while (blocks < end) {
+ 103 106531902 : uint32_t k1 = blocks[0];
+ 104 106531902 : uint32_t k2 = blocks[1];
+ 105 106531902 : uint32_t k3 = blocks[2];
+ 106 106531902 : 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 106529759 : k1 *= c1; k1 = util_rotl32(k1, 15); k1 *= c2; h1 ^= k1;
+ 115 106531902 : k1 *= c1; k1 = util_rotl32(k1, 15); k1 *= c2; h1 ^= k1;
116 :
- 117 106529759 : h1 = util_rotl32(h1, 19); h1 += h2; h1 = h1 * 5 + 0x561ccd1b;
+ 117 106531902 : h1 = util_rotl32(h1, 19); h1 += h2; h1 = h1 * 5 + 0x561ccd1b;
118 :
- 119 106529759 : k2 *= c2; k2 = util_rotl32(k2, 16); k2 *= c3; h2 ^= k2;
+ 119 106531902 : k2 *= c2; k2 = util_rotl32(k2, 16); k2 *= c3; h2 ^= k2;
120 :
- 121 106529759 : h2 = util_rotl32(h2, 17); h2 += h3; h2 = h2 * 5 + 0x0bcaa747;
+ 121 106531902 : h2 = util_rotl32(h2, 17); h2 += h3; h2 = h2 * 5 + 0x0bcaa747;
122 :
- 123 106529759 : k3 *= c3; k3 = util_rotl32(k3, 17); k3 *= c4; h3 ^= k3;
+ 123 106531902 : k3 *= c3; k3 = util_rotl32(k3, 17); k3 *= c4; h3 ^= k3;
124 :
- 125 106529759 : h3 = util_rotl32(h3, 15); h3 += h4; h3 = h3 * 5 + 0x96cd1c35;
+ 125 106531902 : h3 = util_rotl32(h3, 15); h3 += h4; h3 = h3 * 5 + 0x96cd1c35;
126 :
- 127 106529759 : k4 *= c4; k4 = util_rotl32(k4, 18); k4 *= c1; h4 ^= k4;
+ 127 106531902 : k4 *= c4; k4 = util_rotl32(k4, 18); k4 *= c1; h4 ^= k4;
128 :
- 129 106529759 : h4 = util_rotl32(h4, 13); h4 += h1; h4 = h4 * 5 + 0x32ac3b17;
+ 129 106531902 : h4 = util_rotl32(h4, 13); h4 += h1; h4 = h4 * 5 + 0x32ac3b17;
130 :
- 131 106529759 : blocks += 4;
+ 131 106531902 : blocks += 4;
132 : }
133 :
134 : /* tail */
- 135 2076827 : size_remainder = size & 15;
- 136 2076827 : if (size_remainder != 0) {
- 137 779267 : const uint8_t* tail = (const uint8_t*)blocks;
+ 135 2076854 : size_remainder = size & 15;
+ 136 2076854 : if (size_remainder != 0) {
+ 137 779239 : const uint8_t* tail = (const uint8_t*)blocks;
138 :
- 139 779267 : uint32_t k1 = 0;
- 140 779267 : uint32_t k2 = 0;
- 141 779267 : uint32_t k3 = 0;
- 142 779267 : uint32_t k4 = 0;
+ 139 779239 : uint32_t k1 = 0;
+ 140 779239 : uint32_t k2 = 0;
+ 141 779239 : uint32_t k3 = 0;
+ 142 779239 : uint32_t k4 = 0;
143 :
- 144 779267 : switch (size_remainder) {
- 145 51305 : case 15 : k4 ^= (uint32_t)tail[14] << 16;
- 146 104040 : case 14 : k4 ^= (uint32_t)tail[13] << 8;
- 147 156243 : case 13 : k4 ^= (uint32_t)tail[12] << 0;
- 148 156243 : k4 *= c4; k4 = util_rotl32(k4, 18); k4 *= c1; h4 ^= k4;
- 149 209005 : case 12 : k3 ^= (uint32_t)tail[11] << 24;
- 150 261544 : case 11 : k3 ^= (uint32_t)tail[10] << 16;
- 151 313728 : case 10 : k3 ^= (uint32_t)tail[ 9] << 8;
- 152 367016 : case 9 : k3 ^= (uint32_t)tail[ 8] << 0;
- 153 367016 : k3 *= c3; k3 = util_rotl32(k3, 17); k3 *= c4; h3 ^= k3;
- 154 420940 : case 8 : k2 ^= (uint32_t)tail[ 7] << 24;
- 155 470460 : case 7 : k2 ^= (uint32_t)tail[ 6] << 16;
- 156 523118 : case 6 : k2 ^= (uint32_t)tail[ 5] << 8;
- 157 573626 : case 5 : k2 ^= (uint32_t)tail[ 4] << 0;
- 158 573626 : k2 *= c2; k2 = util_rotl32(k2, 16); k2 *= c3; h2 ^= k2;
- 159 625593 : case 4 : k1 ^= (uint32_t)tail[ 3] << 24;
- 160 675926 : case 3 : k1 ^= (uint32_t)tail[ 2] << 16;
- 161 726993 : case 2 : k1 ^= (uint32_t)tail[ 1] << 8;
- 162 779267 : case 1 : k1 ^= (uint32_t)tail[ 0] << 0;
- 163 779267 : k1 *= c1; k1 = util_rotl32(k1, 15); k1 *= c2; h1 ^= k1;
+ 144 779239 : switch (size_remainder) {
+ 145 51287 : case 15 : k4 ^= (uint32_t)tail[14] << 16;
+ 146 104028 : case 14 : k4 ^= (uint32_t)tail[13] << 8;
+ 147 156205 : case 13 : k4 ^= (uint32_t)tail[12] << 0;
+ 148 156205 : k4 *= c4; k4 = util_rotl32(k4, 18); k4 *= c1; h4 ^= k4;
+ 149 208993 : case 12 : k3 ^= (uint32_t)tail[11] << 24;
+ 150 261517 : case 11 : k3 ^= (uint32_t)tail[10] << 16;
+ 151 313718 : case 10 : k3 ^= (uint32_t)tail[ 9] << 8;
+ 152 367026 : case 9 : k3 ^= (uint32_t)tail[ 8] << 0;
+ 153 367026 : k3 *= c3; k3 = util_rotl32(k3, 17); k3 *= c4; h3 ^= k3;
+ 154 420982 : case 8 : k2 ^= (uint32_t)tail[ 7] << 24;
+ 155 470474 : case 7 : k2 ^= (uint32_t)tail[ 6] << 16;
+ 156 523130 : case 6 : k2 ^= (uint32_t)tail[ 5] << 8;
+ 157 573642 : case 5 : k2 ^= (uint32_t)tail[ 4] << 0;
+ 158 573642 : k2 *= c2; k2 = util_rotl32(k2, 16); k2 *= c3; h2 ^= k2;
+ 159 625581 : case 4 : k1 ^= (uint32_t)tail[ 3] << 24;
+ 160 675936 : case 3 : k1 ^= (uint32_t)tail[ 2] << 16;
+ 161 726983 : case 2 : k1 ^= (uint32_t)tail[ 1] << 8;
+ 162 779239 : case 1 : k1 ^= (uint32_t)tail[ 0] << 0;
+ 163 779239 : k1 *= c1; k1 = util_rotl32(k1, 15); k1 *= c2; h1 ^= k1;
164 : }
165 : }
166 :
167 : /* finalization */
- 168 2076827 : h1 ^= size; h2 ^= size; h3 ^= size; h4 ^= size;
+ 168 2076854 : h1 ^= size; h2 ^= size; h3 ^= size; h4 ^= size;
169 :
- 170 2076827 : h1 += h2; h1 += h3; h1 += h4;
- 171 2076827 : h2 += h1; h3 += h1; h4 += h1;
+ 170 2076854 : h1 += h2; h1 += h3; h1 += h4;
+ 171 2076854 : h2 += h1; h3 += h1; h4 += h1;
172 :
- 173 2076827 : h1 = fmix32(h1);
- 174 2076827 : h2 = fmix32(h2);
- 175 2076827 : h3 = fmix32(h3);
- 176 2076827 : h4 = fmix32(h4);
+ 173 2076854 : h1 = fmix32(h1);
+ 174 2076854 : h2 = fmix32(h2);
+ 175 2076854 : h3 = fmix32(h3);
+ 176 2076854 : h4 = fmix32(h4);
177 :
- 178 2076827 : h1 += h2; h1 += h3; h1 += h4;
- 179 2076827 : h2 += h1; h3 += h1; h4 += h1;
+ 178 2076854 : h1 += h2; h1 += h3; h1 += h4;
+ 179 2076854 : 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 2076827 : ((uint32_t*)digest)[0] = h1;
- 189 2076827 : ((uint32_t*)digest)[1] = h2;
- 190 2076827 : ((uint32_t*)digest)[2] = h3;
- 191 2076827 : ((uint32_t*)digest)[3] = h4;
- 192 2076827 : }
+ 188 2076854 : ((uint32_t*)digest)[0] = h1;
+ 189 2076854 : ((uint32_t*)digest)[1] = h2;
+ 190 2076854 : ((uint32_t*)digest)[2] = h3;
+ 191 2076854 : ((uint32_t*)digest)[3] = h4;
+ 192 2076854 : }
193 :
diff --git a/cov/cmdline/parity.c.func-sort-c.html b/cov/cmdline/parity.c.func-sort-c.html
index 1dc217aa..83ea4f9a 100644
--- a/cov/cmdline/parity.c.func-sort-c.html
+++ b/cov/cmdline/parity.c.func-sort-c.html
@@ -31,9 +31,9 @@
|
-
-
-
+
+
+
@@ -60,16 +60,16 @@
Hit count  |
- | parity_split_find |
- 4113567 |
+ parity_split_find |
+ 4114025 |
- | parity_read |
+ parity_read |
3501825 |
- | parity_write |
- 611751 |
+ parity_write |
+ 612195 |
| parity_handle_chsize |
@@ -80,7 +80,7 @@
2460 |
- | parity_close |
+ parity_close |
1022 |
@@ -93,7 +93,7 @@
| parity_allocated_size |
- 638 |
+ 640 |
| parity_create |
@@ -108,11 +108,11 @@
487 |
- | parity_sync |
+ parity_sync |
469 |
- | parity_open |
+ parity_open |
402 |
@@ -129,7 +129,7 @@
| parity_is_invalid |
- 1 |
+ 2 |
| parity_overflow |
diff --git a/cov/cmdline/parity.c.func.html b/cov/cmdline/parity.c.func.html
index f1d24eff..fbee8fb6 100644
--- a/cov/cmdline/parity.c.func.html
+++ b/cov/cmdline/parity.c.func.html
@@ -31,9 +31,9 @@
|
-
-
-
+
+
+
@@ -65,14 +65,14 @@
| parity_allocated_size |
- 638 |
+ 640 |
| parity_chsize |
615 |
- | parity_close |
+ parity_close |
1022 |
@@ -97,10 +97,10 @@
| parity_is_invalid |
- 1 |
+ 2 |
- | parity_open |
+ parity_open |
402 |
@@ -108,7 +108,7 @@
| 0 |
- | parity_read |
+ parity_read |
3501825 |
@@ -116,15 +116,15 @@
| 487 |
- | parity_split_find |
- 4113567 |
+ parity_split_find |
+ 4114025 |
| parity_split_is_fixed |
2460 |
- | parity_sync |
+ parity_sync |
469 |
@@ -132,8 +132,8 @@
| 87 |
- | parity_write |
- 611751 |
+ parity_write |
+ 612195 |
diff --git a/cov/cmdline/parity.c.gcov.html b/cov/cmdline/parity.c.gcov.html
index 4ca2088e..d58b31ce 100644
--- a/cov/cmdline/parity.c.gcov.html
+++ b/cov/cmdline/parity.c.gcov.html
@@ -31,9 +31,9 @@
|
-
-
-
+
+
+
@@ -94,31 +94,31 @@
32 : /****************************************************************************/
33 : /* parity */
34 :
- 35 638 : block_off_t parity_allocated_size(struct snapraid_state* state)
+ 35 640 : block_off_t parity_allocated_size(struct snapraid_state* state)
36 : {
37 : block_off_t parity_block;
38 : tommy_node* i;
39 :
40 : /* compute the size of the parity file */
- 41 638 : parity_block = 0;
- 42 4456 : for (i = state->disklist; i != 0; i = i->next) {
- 43 3818 : struct snapraid_disk* disk = i->data;
+ 41 640 : parity_block = 0;
+ 42 4470 : for (i = state->disklist; i != 0; i = i->next) {
+ 43 3830 : struct snapraid_disk* disk = i->data;
44 :
45 : /* start from the declared size */
- 46 3818 : block_off_t block = fs_size(disk);
+ 46 3830 : block_off_t block = fs_size(disk);
47 :
48 : /* decrease the block until an allocated one, but part of a file */
49 : /* we don't stop at deleted blocks, because we want to have them cleared */
50 : /* if they are at the end of the parity */
- 51 190184 : while (block > parity_block && !block_has_file(fs_par2block_find(disk, block - 1)))
+ 51 190208 : while (block > parity_block && !block_has_file(fs_par2block_find(disk, block - 1)))
52 182548 : --block;
53 :
54 : /* get the highest value */
- 55 3818 : if (block > parity_block)
- 56 2263 : parity_block = block;
+ 55 3830 : if (block > parity_block)
+ 56 2265 : parity_block = block;
57 : }
58 :
- 59 638 : return parity_block;
+ 59 640 : return parity_block;
60 : }
61 :
62 87 : block_off_t parity_used_size(struct snapraid_state* state)
@@ -146,34 +146,34 @@
84 87 : return parity_block;
85 : }
86 :
- 87 1 : int parity_is_invalid(struct snapraid_state* state)
+ 87 2 : int parity_is_invalid(struct snapraid_state* state)
88 : {
89 : block_off_t blockmax;
90 : block_off_t i;
91 :
- 92 1 : blockmax = parity_allocated_size(state);
+ 92 2 : blockmax = parity_allocated_size(state);
93 :
- 94 1 : for (i = 0; i < blockmax; ++i) {
+ 94 2 : for (i = 0; i < blockmax; ++i) {
95 : tommy_node* node_disk;
96 : int one_invalid;
97 : int one_valid;
98 :
99 : /* for each disk */
- 100 0 : one_invalid = 0;
- 101 0 : one_valid = 0;
- 102 0 : for (node_disk = state->disklist; node_disk != 0; node_disk = node_disk->next) {
- 103 0 : struct snapraid_disk* disk = node_disk->data;
- 104 0 : struct snapraid_block* block = fs_par2block_find(disk, i);
+ 100 1 : one_invalid = 0;
+ 101 1 : one_valid = 0;
+ 102 7 : for (node_disk = state->disklist; node_disk != 0; node_disk = node_disk->next) {
+ 103 6 : struct snapraid_disk* disk = node_disk->data;
+ 104 6 : struct snapraid_block* block = fs_par2block_find(disk, i);
105 :
- 106 0 : if (block_has_file(block))
- 107 0 : one_valid = 1;
- 108 0 : if (block_has_invalid_parity(block))
- 109 0 : one_invalid = 1;
+ 106 6 : if (block_has_file(block))
+ 107 5 : one_valid = 1;
+ 108 6 : if (block_has_invalid_parity(block))
+ 109 2 : one_invalid = 1;
110 : }
111 :
112 : /* if both valid and invalid, we need to update */
- 113 0 : if (one_invalid && one_valid)
- 114 0 : return 1;
+ 113 1 : if (one_invalid && one_valid)
+ 114 1 : return 1;
115 : }
116 :
117 1 : return 0;
@@ -592,339 +592,347 @@
530 : /* mask of bits used by the block size */
531 615 : block_mask = ((data_off_t)block_size) - 1;
532 :
- 533 615 : if (size < 0)
- 534 0 : return -1;
- 535 :
- 536 3075 : for (s = 0;s < handle->split_mac;++s) {
- 537 2460 : struct snapraid_split_handle* split = &handle->split_map[s];
- 538 2460 : int is_fixed = parity_split_is_fixed(handle, s);
- 539 : data_off_t run;
- 540 :
- 541 2460 : if (is_fixed) {
- 542 : /* if the required size is smaller, we have to reduce also the file */
- 543 : /* ignoring the previous size */
- 544 611 : if (size <= split->size) {
- 545 : /* mark it as not fixed anymore for the later check */
- 546 10 : is_fixed = 0;
- 547 :
- 548 10 : run = size; /* allocate only the needed size */
- 549 : } else {
- 550 : /* if the size cannot be changed, use the fixed one */
- 551 601 : run = split->size;
- 552 :
- 553 601 : if ((run & block_mask) != 0) {
- 554 : /* LCOV_EXCL_START */
- 555 : log_fatal("Internal inconsistency in split '%s' size with extra '%" PRIu64 "' bytes.\n", split->path, run & block_mask);
- 556 : return -1;
- 557 : /* LCOV_EXCL_STOP */
- 558 : }
- 559 : }
- 560 : } else {
- 561 : /* otherwise tries to allocate all the needed remaining size */
- 562 1849 : run = size;
- 563 : }
- 564 :
- 565 2460 : ret = parity_handle_chsize(split, run, block_size, skip_fallocate, skip_space_holder);
- 566 2460 : if (ret != 0)
- 567 0 : return -1;
- 568 :
- 569 2460 : if (split->st.st_size > run) {
+ 533 615 : if (size < 0) {
+ 534 : /* LCOV_EXCL_START */
+ 535 : return -1;
+ 536 : /* LCOV_EXCL_STOP */
+ 537 : }
+ 538 :
+ 539 3075 : for (s = 0;s < handle->split_mac;++s) {
+ 540 2460 : struct snapraid_split_handle* split = &handle->split_map[s];
+ 541 2460 : int is_fixed = parity_split_is_fixed(handle, s);
+ 542 : data_off_t run;
+ 543 :
+ 544 2460 : if (is_fixed) {
+ 545 : /* if the required size is smaller, we have to reduce also the file */
+ 546 : /* ignoring the previous size */
+ 547 611 : if (size <= split->size) {
+ 548 : /* mark it as not fixed anymore for the later check */
+ 549 10 : is_fixed = 0;
+ 550 :
+ 551 10 : run = size; /* allocate only the needed size */
+ 552 : } else {
+ 553 : /* if the size cannot be changed, use the fixed one */
+ 554 601 : run = split->size;
+ 555 :
+ 556 601 : if ((run & block_mask) != 0) {
+ 557 : /* LCOV_EXCL_START */
+ 558 : log_fatal("Internal inconsistency in split '%s' size with extra '%" PRIu64 "' bytes.\n", split->path, run & block_mask);
+ 559 : return -1;
+ 560 : /* LCOV_EXCL_STOP */
+ 561 : }
+ 562 : }
+ 563 : } else {
+ 564 : /* otherwise tries to allocate all the needed remaining size */
+ 565 1849 : run = size;
+ 566 : }
+ 567 :
+ 568 2460 : ret = parity_handle_chsize(split, run, block_size, skip_fallocate, skip_space_holder);
+ 569 2460 : if (ret != 0) {
570 : /* LCOV_EXCL_START */
- 571 : log_fatal("Unexpected over resizing parity file '%s' to size %" PRIu64 " resulting in size %" PRIu64 ".\n", split->path, run, split->st.st_size);
- 572 : return -1;
- 573 : /* LCOV_EXCL_STOP */
- 574 2460 : } else if (is_fixed && split->st.st_size < run) {
- 575 : /* LCOV_EXCL_START */
- 576 : log_fatal("Failed restoring parity file '%s' to size %" PRIu64 " resulting in size %" PRIu64 ".\n", split->path, run, split->st.st_size);
- 577 : return -1;
- 578 : /* LCOV_EXCL_STOP */
- 579 : } else {
- 580 : /* here it's possible to get less than the requested size */
- 581 2460 : run = split->st.st_size;
- 582 :
- 583 2460 : if ((run & block_mask) != 0) {
- 584 : /* LCOV_EXCL_START */
- 585 : log_fatal("Internal inconsistency in final parity size %" PRIu64 " with block size %u\n", run, block_size);
- 586 : os_abort();
- 587 : /* LCOV_EXCL_STOP */
- 588 : }
- 589 :
- 590 : /* store what we have allocated */
- 591 2460 : split->size = run;
- 592 :
- 593 : /* decrease the remaining size */
- 594 2460 : size -= run;
- 595 : }
- 596 : }
- 597 :
- 598 : /* if we cannot allocate all the space */
- 599 615 : if (size != 0) {
- 600 0 : log_fatal("Failed to allocate all the required parity space. You miss %" PRIu64 " bytes.\n", size);
- 601 0 : return -1;
+ 571 : return -1;
+ 572 : /* LCOV_EXCL_STOP */
+ 573 : }
+ 574 :
+ 575 2460 : if (split->st.st_size > run) {
+ 576 : /* LCOV_EXCL_START */
+ 577 : log_fatal("Unexpected over resizing parity file '%s' to size %" PRIu64 " resulting in size %" PRIu64 ".\n", split->path, run, split->st.st_size);
+ 578 : return -1;
+ 579 : /* LCOV_EXCL_STOP */
+ 580 2460 : } else if (is_fixed && split->st.st_size < run) {
+ 581 : /* LCOV_EXCL_START */
+ 582 : log_fatal("Failed restoring parity file '%s' to size %" PRIu64 " resulting in size %" PRIu64 ".\n", split->path, run, split->st.st_size);
+ 583 : return -1;
+ 584 : /* LCOV_EXCL_STOP */
+ 585 : } else {
+ 586 : /* here it's possible to get less than the requested size */
+ 587 2460 : run = split->st.st_size;
+ 588 :
+ 589 2460 : if ((run & block_mask) != 0) {
+ 590 : /* LCOV_EXCL_START */
+ 591 : log_fatal("Internal inconsistency in final parity size %" PRIu64 " with block size %u\n", run, block_size);
+ 592 : os_abort();
+ 593 : /* LCOV_EXCL_STOP */
+ 594 : }
+ 595 :
+ 596 : /* store what we have allocated */
+ 597 2460 : split->size = run;
+ 598 :
+ 599 : /* decrease the remaining size */
+ 600 2460 : size -= run;
+ 601 : }
602 : }
603 :
- 604 : /* now copy the new size in the parity data */
- 605 615 : if (is_modified)
- 606 481 : *is_modified = 0;
- 607 :
- 608 3075 : for (s = 0;s < handle->split_mac;++s) {
- 609 2460 : struct snapraid_split_handle* split = &handle->split_map[s];
- 610 :
- 611 2460 : if (parity->split_map[s].size != split->size) {
- 612 320 : parity->split_map[s].size = split->size;
- 613 320 : if (is_modified)
- 614 264 : *is_modified = 1;
- 615 : }
- 616 : }
- 617 :
- 618 615 : return 0;
- 619 : }
- 620 :
- 621 402 : int parity_open(struct snapraid_parity_handle* handle, const struct snapraid_parity* parity, unsigned level, int mode, uint32_t block_size, data_off_t limit_size)
- 622 : {
- 623 : unsigned s;
- 624 : data_off_t block_mask;
+ 604 : /* if we cannot allocate all the space */
+ 605 615 : if (size != 0) {
+ 606 : /* LCOV_EXCL_START */
+ 607 : log_fatal("Failed to allocate all the required parity space. You miss %" PRIu64 " bytes.\n", size);
+ 608 : return -1;
+ 609 : /* LCOV_EXCL_STOP */
+ 610 : }
+ 611 :
+ 612 : /* now copy the new size in the parity data */
+ 613 615 : if (is_modified)
+ 614 481 : *is_modified = 0;
+ 615 :
+ 616 3075 : for (s = 0;s < handle->split_mac;++s) {
+ 617 2460 : struct snapraid_split_handle* split = &handle->split_map[s];
+ 618 :
+ 619 2460 : if (parity->split_map[s].size != split->size) {
+ 620 320 : parity->split_map[s].size = split->size;
+ 621 320 : if (is_modified)
+ 622 264 : *is_modified = 1;
+ 623 : }
+ 624 : }
625 :
- 626 402 : handle->level = level;
- 627 402 : handle->split_mac = 0;
+ 626 615 : return 0;
+ 627 : }
628 :
- 629 : /* mask of bits used by the block size */
- 630 402 : block_mask = ((data_off_t)block_size) - 1;
- 631 :
- 632 2006 : for (s = 0;s < parity->split_mac;++s) {
- 633 1605 : struct snapraid_split_handle* split = &handle->split_map[s];
- 634 : int ret;
- 635 : int flags;
+ 629 402 : int parity_open(struct snapraid_parity_handle* handle, const struct snapraid_parity* parity, unsigned level, int mode, uint32_t block_size, data_off_t limit_size)
+ 630 : {
+ 631 : unsigned s;
+ 632 : data_off_t block_mask;
+ 633 :
+ 634 402 : handle->level = level;
+ 635 402 : handle->split_mac = 0;
636 :
- 637 1605 : advise_init(&split->advise, mode);
- 638 1605 : pathcpy(split->path, sizeof(split->path), parity->split_map[s].path);
- 639 1605 : split->size = parity->split_map[s].size;
- 640 1605 : split->limit_size = PARITY_LIMIT(limit_size, s, level);
- 641 :
- 642 : /* open for read */
- 643 : /* O_NOATIME: do not change access time */
- 644 1605 : flags = O_RDONLY | O_BINARY | advise_flags(&split->advise);
- 645 :
- 646 1605 : split->f = open_noatime(split->path, flags);
- 647 1605 : if (split->f == -1) {
- 648 : /* LCOV_EXCL_START */
- 649 : log_fatal("Error opening parity file '%s'. %s.\n", split->path, strerror(errno));
- 650 : goto bail;
- 651 : /* LCOV_EXCL_STOP */
- 652 : }
+ 637 : /* mask of bits used by the block size */
+ 638 402 : block_mask = ((data_off_t)block_size) - 1;
+ 639 :
+ 640 2006 : for (s = 0;s < parity->split_mac;++s) {
+ 641 1605 : struct snapraid_split_handle* split = &handle->split_map[s];
+ 642 : int ret;
+ 643 : int flags;
+ 644 :
+ 645 1605 : advise_init(&split->advise, mode);
+ 646 1605 : pathcpy(split->path, sizeof(split->path), parity->split_map[s].path);
+ 647 1605 : split->size = parity->split_map[s].size;
+ 648 1605 : split->limit_size = PARITY_LIMIT(limit_size, s, level);
+ 649 :
+ 650 : /* open for read */
+ 651 : /* O_NOATIME: do not change access time */
+ 652 1605 : flags = O_RDONLY | O_BINARY | advise_flags(&split->advise);
653 :
- 654 : /* we have a valid file handle */
- 655 1604 : ++handle->split_mac;
- 656 :
- 657 : /* get the stat info */
- 658 1604 : ret = fstat(split->f, &split->st);
- 659 1604 : if (ret != 0) {
- 660 : /* LCOV_EXCL_START */
- 661 : log_fatal("Error accessing parity file '%s'. %s.\n", split->path, strerror(errno));
- 662 : goto bail;
- 663 : /* LCOV_EXCL_STOP */
- 664 : }
- 665 :
- 666 : /**
- 667 : * If the parity size is not yet set, set it now.
- 668 : * This happens when expanding the number of parities,
- 669 : * or when upgrading from a content file that has not split->size data.
- 670 : */
- 671 1604 : if (split->size == PARITY_SIZE_INVALID) {
- 672 40 : split->size = split->st.st_size;
+ 654 1605 : split->f = open_noatime(split->path, flags);
+ 655 1605 : if (split->f == -1) {
+ 656 : /* LCOV_EXCL_START */
+ 657 : log_fatal("Error opening parity file '%s'. %s.\n", split->path, strerror(errno));
+ 658 : goto bail;
+ 659 : /* LCOV_EXCL_STOP */
+ 660 : }
+ 661 :
+ 662 : /* we have a valid file handle */
+ 663 1604 : ++handle->split_mac;
+ 664 :
+ 665 : /* get the stat info */
+ 666 1604 : ret = fstat(split->f, &split->st);
+ 667 1604 : if (ret != 0) {
+ 668 : /* LCOV_EXCL_START */
+ 669 : log_fatal("Error accessing parity file '%s'. %s.\n", split->path, strerror(errno));
+ 670 : goto bail;
+ 671 : /* LCOV_EXCL_STOP */
+ 672 : }
673 :
- 674 : /* ensure that the resulting size if block aligned */
- 675 40 : if ((split->size & block_mask) != 0) {
- 676 : /* LCOV_EXCL_START */
- 677 : log_fatal("Error in preallocated size of parity file '%s' with size %" PRIu64 " and block %u .\n", split->path, split->size, block_size);
- 678 : goto bail;
- 679 : /* LCOV_EXCL_STOP */
- 680 : }
- 681 : }
- 682 :
- 683 1604 : ret = advise_open(&split->advise, split->f);
- 684 1604 : if (ret != 0) {
- 685 : /* LCOV_EXCL_START */
- 686 : log_fatal("Error advising parity file '%s'. %s.\n", split->path, strerror(errno));
- 687 : goto bail;
- 688 : /* LCOV_EXCL_STOP */
+ 674 : /**
+ 675 : * If the parity size is not yet set, set it now.
+ 676 : * This happens when expanding the number of parities,
+ 677 : * or when upgrading from a content file that has not split->size data.
+ 678 : */
+ 679 1604 : if (split->size == PARITY_SIZE_INVALID) {
+ 680 40 : split->size = split->st.st_size;
+ 681 :
+ 682 : /* ensure that the resulting size if block aligned */
+ 683 40 : if ((split->size & block_mask) != 0) {
+ 684 : /* LCOV_EXCL_START */
+ 685 : log_fatal("Error in preallocated size of parity file '%s' with size %" PRIu64 " and block %u .\n", split->path, split->size, block_size);
+ 686 : goto bail;
+ 687 : /* LCOV_EXCL_STOP */
+ 688 : }
689 : }
- 690 : }
- 691 :
- 692 401 : return 0;
- 693 :
- 694 : bail:
- 695 : /* LCOV_EXCL_START */
- 696 : for (s = 0;s < handle->split_mac;++s) {
- 697 : struct snapraid_split_handle* split = &handle->split_map[s];
- 698 : close(split->f);
- 699 : split->f = -1;
- 700 : }
- 701 : return -1;
- 702 : /* LCOV_EXCL_STOP */
- 703 : }
- 704 :
- 705 469 : int parity_sync(struct snapraid_parity_handle* handle)
- 706 : {
- 707 : #if HAVE_FSYNC
- 708 : unsigned s;
- 709 :
- 710 2345 : for (s = 0;s < handle->split_mac;++s) {
- 711 1876 : struct snapraid_split_handle* split = &handle->split_map[s];
- 712 : int ret;
- 713 :
- 714 : /* Ensure that data changes are written to disk. */
- 715 : /* This is required to ensure that parity is more updated than content */
- 716 : /* in case of a system crash. */
- 717 1876 : ret = fsync(split->f);
- 718 1876 : if (ret != 0) {
- 719 : /* LCOV_EXCL_START */
- 720 : log_fatal("Error synching parity file '%s'. %s.\n", split->path, strerror(errno));
- 721 : return -1;
- 722 : /* LCOV_EXCL_STOP */
- 723 : }
- 724 : }
- 725 : #endif
- 726 :
- 727 469 : return 0;
- 728 : }
- 729 :
- 730 1022 : int parity_close(struct snapraid_parity_handle* handle)
- 731 : {
- 732 : unsigned s;
- 733 1022 : int f_ret = 0;
+ 690 :
+ 691 1604 : ret = advise_open(&split->advise, split->f);
+ 692 1604 : if (ret != 0) {
+ 693 : /* LCOV_EXCL_START */
+ 694 : log_fatal("Error advising parity file '%s'. %s.\n", split->path, strerror(errno));
+ 695 : goto bail;
+ 696 : /* LCOV_EXCL_STOP */
+ 697 : }
+ 698 : }
+ 699 :
+ 700 401 : return 0;
+ 701 :
+ 702 : bail:
+ 703 : /* LCOV_EXCL_START */
+ 704 : for (s = 0;s < handle->split_mac;++s) {
+ 705 : struct snapraid_split_handle* split = &handle->split_map[s];
+ 706 : close(split->f);
+ 707 : split->f = -1;
+ 708 : }
+ 709 : return -1;
+ 710 : /* LCOV_EXCL_STOP */
+ 711 : }
+ 712 :
+ 713 469 : int parity_sync(struct snapraid_parity_handle* handle)
+ 714 : {
+ 715 : #if HAVE_FSYNC
+ 716 : unsigned s;
+ 717 :
+ 718 2345 : for (s = 0;s < handle->split_mac;++s) {
+ 719 1876 : struct snapraid_split_handle* split = &handle->split_map[s];
+ 720 : int ret;
+ 721 :
+ 722 : /* Ensure that data changes are written to disk. */
+ 723 : /* This is required to ensure that parity is more updated than content */
+ 724 : /* in case of a system crash. */
+ 725 1876 : ret = fsync(split->f);
+ 726 1876 : if (ret != 0) {
+ 727 : /* LCOV_EXCL_START */
+ 728 : log_fatal("Error synching parity file '%s'. %s.\n", split->path, strerror(errno));
+ 729 : return -1;
+ 730 : /* LCOV_EXCL_STOP */
+ 731 : }
+ 732 : }
+ 733 : #endif
734 :
- 735 5110 : for (s = 0;s < handle->split_mac;++s) {
- 736 4088 : struct snapraid_split_handle* split = &handle->split_map[s];
- 737 : int ret;
- 738 :
- 739 4088 : ret = close(split->f);
- 740 4088 : if (ret != 0) {
- 741 : /* LCOV_EXCL_START */
- 742 : /* This is a serious error, as it may be the result of a failed write */
- 743 : /* identified at later time. */
- 744 : /* In a normal file-system (not NFS) it should never happen */
- 745 : log_fatal("Error closing parity file '%s'. %s.\n", split->path, strerror(errno));
- 746 : f_ret = -1;
- 747 : /* LCOV_EXCL_STOP */
- 748 :
- 749 : /* continue to close the others */
- 750 : }
- 751 :
- 752 : /* reset the descriptor */
- 753 4088 : split->f = -1;
- 754 : }
- 755 :
- 756 1022 : return f_ret;
- 757 : }
- 758 :
- 759 4113567 : struct snapraid_split_handle* parity_split_find(struct snapraid_parity_handle* handle, data_off_t* offset)
- 760 : {
- 761 : unsigned s;
- 762 :
- 763 4113567 : if (*offset < 0)
- 764 0 : return 0;
- 765 :
- 766 6501737 : for (s = 0;s < handle->split_mac;++s) {
- 767 6490377 : struct snapraid_split_handle* split = &handle->split_map[s];
- 768 :
- 769 6490377 : if (*offset < split->size)
- 770 4102207 : return split;
- 771 :
- 772 2388170 : *offset -= split->size;
- 773 : }
- 774 :
- 775 11360 : return 0;
- 776 : }
- 777 :
- 778 611751 : int parity_write(struct snapraid_parity_handle* handle, block_off_t pos, unsigned char* block_buffer, unsigned block_size)
- 779 : {
- 780 : ssize_t write_ret;
- 781 : data_off_t offset;
- 782 : struct snapraid_split_handle* split;
- 783 : int ret;
- 784 :
- 785 611751 : offset = pos * (data_off_t)block_size;
- 786 :
- 787 611751 : split = parity_split_find(handle, &offset);
- 788 611746 : if (!split) {
- 789 : /* LCOV_EXCL_START */
- 790 : log_fatal("Writing parity data outside range at extra offset %" PRIu64 ".\n", offset);
- 791 : return -1;
- 792 : /* LCOV_EXCL_STOP */
- 793 : }
+ 735 469 : return 0;
+ 736 : }
+ 737 :
+ 738 1022 : int parity_close(struct snapraid_parity_handle* handle)
+ 739 : {
+ 740 : unsigned s;
+ 741 1022 : int f_ret = 0;
+ 742 :
+ 743 5110 : for (s = 0;s < handle->split_mac;++s) {
+ 744 4088 : struct snapraid_split_handle* split = &handle->split_map[s];
+ 745 : int ret;
+ 746 :
+ 747 4088 : ret = close(split->f);
+ 748 4088 : if (ret != 0) {
+ 749 : /* LCOV_EXCL_START */
+ 750 : /* This is a serious error, as it may be the result of a failed write */
+ 751 : /* identified at later time. */
+ 752 : /* In a normal file-system (not NFS) it should never happen */
+ 753 : log_fatal("Error closing parity file '%s'. %s.\n", split->path, strerror(errno));
+ 754 : f_ret = -1;
+ 755 : /* LCOV_EXCL_STOP */
+ 756 :
+ 757 : /* continue to close the others */
+ 758 : }
+ 759 :
+ 760 : /* reset the descriptor */
+ 761 4088 : split->f = -1;
+ 762 : }
+ 763 :
+ 764 1022 : return f_ret;
+ 765 : }
+ 766 :
+ 767 4114025 : struct snapraid_split_handle* parity_split_find(struct snapraid_parity_handle* handle, data_off_t* offset)
+ 768 : {
+ 769 : unsigned s;
+ 770 :
+ 771 4114025 : if (*offset < 0)
+ 772 0 : return 0;
+ 773 :
+ 774 6502383 : for (s = 0;s < handle->split_mac;++s) {
+ 775 6491023 : struct snapraid_split_handle* split = &handle->split_map[s];
+ 776 :
+ 777 6491023 : if (*offset < split->size)
+ 778 4102665 : return split;
+ 779 :
+ 780 2388358 : *offset -= split->size;
+ 781 : }
+ 782 :
+ 783 11360 : return 0;
+ 784 : }
+ 785 :
+ 786 612195 : int parity_write(struct snapraid_parity_handle* handle, block_off_t pos, unsigned char* block_buffer, unsigned block_size)
+ 787 : {
+ 788 : ssize_t write_ret;
+ 789 : data_off_t offset;
+ 790 : struct snapraid_split_handle* split;
+ 791 : int ret;
+ 792 :
+ 793 612195 : offset = pos * (data_off_t)block_size;
794 :
- 795 611746 : write_ret = pwrite(split->f, block_buffer, block_size, offset);
- 796 611756 : if (write_ret != (ssize_t)block_size) { /* conversion is safe because block_size is always small */
+ 795 612195 : split = parity_split_find(handle, &offset);
+ 796 612196 : if (!split) {
797 : /* LCOV_EXCL_START */
- 798 : if (errno == ENOSPC) {
- 799 : log_fatal("Failed to grow parity file '%s' using write due lack of space.\n", split->path);
- 800 : } else {
- 801 : log_fatal("Error writing file '%s'. %s.\n", split->path, strerror(errno));
- 802 : }
- 803 : return -1;
- 804 : /* LCOV_EXCL_STOP */
- 805 : }
- 806 :
- 807 611756 : ret = advise_write(&split->advise, split->f, offset, block_size);
- 808 611756 : if (ret != 0) {
- 809 : /* LCOV_EXCL_START */
- 810 : log_fatal("Error advising parity file '%s'. %s.\n", split->path, strerror(errno));
+ 798 : log_fatal("Writing parity data outside range at extra offset %" PRIu64 ".\n", offset);
+ 799 : return -1;
+ 800 : /* LCOV_EXCL_STOP */
+ 801 : }
+ 802 :
+ 803 612196 : write_ret = pwrite(split->f, block_buffer, block_size, offset);
+ 804 612199 : if (write_ret != (ssize_t)block_size) { /* conversion is safe because block_size is always small */
+ 805 : /* LCOV_EXCL_START */
+ 806 : if (errno == ENOSPC) {
+ 807 : log_fatal("Failed to grow parity file '%s' using write due lack of space.\n", split->path);
+ 808 : } else {
+ 809 : log_fatal("Error writing file '%s'. %s.\n", split->path, strerror(errno));
+ 810 : }
811 : return -1;
812 : /* LCOV_EXCL_STOP */
813 : }
814 :
- 815 611756 : return 0;
- 816 : }
- 817 :
- 818 3501825 : int parity_read(struct snapraid_parity_handle* handle, block_off_t pos, unsigned char* block_buffer, unsigned block_size, fptr* out)
- 819 : {
- 820 : ssize_t read_ret;
- 821 : data_off_t offset;
- 822 : unsigned count;
- 823 : struct snapraid_split_handle* split;
- 824 : int ret;
+ 815 612199 : ret = advise_write(&split->advise, split->f, offset, block_size);
+ 816 612194 : if (ret != 0) {
+ 817 : /* LCOV_EXCL_START */
+ 818 : log_fatal("Error advising parity file '%s'. %s.\n", split->path, strerror(errno));
+ 819 : return -1;
+ 820 : /* LCOV_EXCL_STOP */
+ 821 : }
+ 822 :
+ 823 612194 : return 0;
+ 824 : }
825 :
- 826 3501825 : offset = pos * (data_off_t)block_size;
- 827 :
- 828 3501825 : split = parity_split_find(handle, &offset);
- 829 3501816 : if (!split) {
- 830 : /* LCOV_EXCL_START */
- 831 : out("Reading parity data outside range at extra offset %" PRIu64 ".\n", offset);
- 832 : return -1;
- 833 : /* LCOV_EXCL_STOP */
- 834 : }
+ 826 3501825 : int parity_read(struct snapraid_parity_handle* handle, block_off_t pos, unsigned char* block_buffer, unsigned block_size, fptr* out)
+ 827 : {
+ 828 : ssize_t read_ret;
+ 829 : data_off_t offset;
+ 830 : unsigned count;
+ 831 : struct snapraid_split_handle* split;
+ 832 : int ret;
+ 833 :
+ 834 3501825 : offset = pos * (data_off_t)block_size;
835 :
- 836 3490456 : count = 0;
- 837 : do {
- 838 3490442 : read_ret = pread(split->f, block_buffer + count, block_size - count, offset + count);
- 839 3490403 : if (read_ret < 0) {
- 840 : /* LCOV_EXCL_START */
- 841 : out("Error reading file '%s' at offset %" PRIu64 " for size %u. %s.\n", split->path, offset + count, block_size - count, strerror(errno));
- 842 : return -1;
- 843 : /* LCOV_EXCL_STOP */
- 844 : }
- 845 3490403 : if (read_ret == 0) {
- 846 : /* LCOV_EXCL_START */
- 847 : out("Unexpected end of file '%s' at offset %" PRIu64 ". %s.\n", split->path, offset, strerror(errno));
- 848 : return -1;
- 849 : /* LCOV_EXCL_STOP */
- 850 : }
- 851 :
- 852 3490403 : count += read_ret;
- 853 3490403 : } while (count < block_size);
- 854 :
- 855 3490417 : ret = advise_read(&split->advise, split->f, offset, block_size);
- 856 3490399 : if (ret != 0) {
- 857 : /* LCOV_EXCL_START */
- 858 : out("Error advising parity file '%s'. %s.\n", split->path, strerror(errno));
- 859 : return -1;
- 860 : /* LCOV_EXCL_STOP */
- 861 : }
+ 836 3501825 : split = parity_split_find(handle, &offset);
+ 837 3501814 : if (!split) {
+ 838 : /* LCOV_EXCL_START */
+ 839 : out("Reading parity data outside range at extra offset %" PRIu64 ".\n", offset);
+ 840 : return -1;
+ 841 : /* LCOV_EXCL_STOP */
+ 842 : }
+ 843 :
+ 844 3490454 : count = 0;
+ 845 : do {
+ 846 3490458 : read_ret = pread(split->f, block_buffer + count, block_size - count, offset + count);
+ 847 3490424 : if (read_ret < 0) {
+ 848 : /* LCOV_EXCL_START */
+ 849 : out("Error reading file '%s' at offset %" PRIu64 " for size %u. %s.\n", split->path, offset + count, block_size - count, strerror(errno));
+ 850 : return -1;
+ 851 : /* LCOV_EXCL_STOP */
+ 852 : }
+ 853 3490424 : if (read_ret == 0) {
+ 854 : /* LCOV_EXCL_START */
+ 855 : out("Unexpected end of file '%s' at offset %" PRIu64 ". %s.\n", split->path, offset, strerror(errno));
+ 856 : return -1;
+ 857 : /* LCOV_EXCL_STOP */
+ 858 : }
+ 859 :
+ 860 3490424 : count += read_ret;
+ 861 3490424 : } while (count < block_size);
862 :
- 863 3490399 : return block_size;
- 864 : }
- 865 :
+ 863 3490420 : ret = advise_read(&split->advise, split->f, offset, block_size);
+ 864 3490421 : if (ret != 0) {
+ 865 : /* LCOV_EXCL_START */
+ 866 : out("Error advising parity file '%s'. %s.\n", split->path, strerror(errno));
+ 867 : return -1;
+ 868 : /* LCOV_EXCL_STOP */
+ 869 : }
+ 870 :
+ 871 3490421 : return block_size;
+ 872 : }
+ 873 :
diff --git a/cov/cmdline/scan.c.func-sort-c.html b/cov/cmdline/scan.c.func-sort-c.html
index 13da2ec3..a2a7949d 100644
--- a/cov/cmdline/scan.c.func-sort-c.html
+++ b/cov/cmdline/scan.c.func-sort-c.html
@@ -31,9 +31,9 @@
|
-
+
-
+
@@ -61,23 +61,23 @@
| dd_name_compare |
- 11526102 |
+ 11526118 |
| dstat |
- 1106198 |
+ 1106210 |
| scan_file |
- 1104927 |
+ 1104939 |
| scan_file_keep |
- 1025576 |
+ 1025539 |
| file_is_full_invalid_parity_and_stable |
- 1025576 |
+ 1025539 |
| dd_ino_compare |
@@ -85,27 +85,27 @@
| scan_file_delayed_allocate |
- 101836 |
+ 101892 |
| scan_file_insert |
- 101836 |
+ 101892 |
| scan_file_allocate |
- 101836 |
+ 101892 |
| scan_file_refresh |
- 79156 |
+ 79205 |
| scan_file_remove |
- 56970 |
+ 57026 |
| scan_file_deallocate |
- 56970 |
+ 57026 |
| scan_link |
@@ -121,7 +121,7 @@
| scan_dir |
- 1840 |
+ 1846 |
| scan_link_remove |
@@ -133,7 +133,7 @@
| state_diffscan |
- 95 |
+ 96 |
| state_scan |
@@ -145,7 +145,7 @@
| state_diff |
- 7 |
+ 8 |
| scan_emptydir_remove |
diff --git a/cov/cmdline/scan.c.func.html b/cov/cmdline/scan.c.func.html
index b1d3ee83..9105ea85 100644
--- a/cov/cmdline/scan.c.func.html
+++ b/cov/cmdline/scan.c.func.html
@@ -31,9 +31,9 @@
|
-
+
-
+
@@ -65,11 +65,11 @@
| dd_name_compare |
- 11526102 |
+ 11526118 |
| dstat |
- 1106198 |
+ 1106210 |
| file_is_full_hashed_and_stable |
@@ -77,11 +77,11 @@
| file_is_full_invalid_parity_and_stable |
- 1025576 |
+ 1025539 |
| scan_dir |
- 1840 |
+ 1846 |
| scan_emptydir |
@@ -97,35 +97,35 @@
| scan_file |
- 1104927 |
+ 1104939 |
| scan_file_allocate |
- 101836 |
+ 101892 |
| scan_file_deallocate |
- 56970 |
+ 57026 |
| scan_file_delayed_allocate |
- 101836 |
+ 101892 |
| scan_file_insert |
- 101836 |
+ 101892 |
| scan_file_keep |
- 1025576 |
+ 1025539 |
| scan_file_refresh |
- 79156 |
+ 79205 |
| scan_file_remove |
- 56970 |
+ 57026 |
| scan_link |
@@ -141,11 +141,11 @@
| state_diff |
- 7 |
+ 8 |
| state_diffscan |
- 95 |
+ 96 |
| state_scan |
diff --git a/cov/cmdline/scan.c.gcov.html b/cov/cmdline/scan.c.gcov.html
index d00d9cd4..4e68bddc 100644
--- a/cov/cmdline/scan.c.gcov.html
+++ b/cov/cmdline/scan.c.gcov.html
@@ -31,9 +31,9 @@
|
-
+
-
+
@@ -220,72 +220,72 @@
158 : /**
159 : * Insert the specified file in the parity.
160 : */
- 161 101836 : static void scan_file_allocate(struct snapraid_scan* scan, struct snapraid_file* file)
+ 161 101892 : static void scan_file_allocate(struct snapraid_scan* scan, struct snapraid_file* file)
162 : {
- 163 101836 : struct snapraid_state* state = scan->state;
- 164 101836 : struct snapraid_disk* disk = scan->disk;
+ 163 101892 : struct snapraid_state* state = scan->state;
+ 164 101892 : struct snapraid_disk* disk = scan->disk;
165 : block_off_t i;
166 : block_off_t parity_pos;
167 :
168 : /* state changed */
- 169 101836 : state->need_write = 1;
+ 169 101892 : state->need_write = 1;
170 :
171 : /* allocate the blocks of the file */
- 172 101836 : parity_pos = disk->first_free_block;
- 173 352922 : for (i = 0; i < file->blockmax; ++i) {
+ 172 101892 : parity_pos = disk->first_free_block;
+ 173 353160 : for (i = 0; i < file->blockmax; ++i) {
174 : struct snapraid_block* block;
175 : struct snapraid_block* over_block;
176 : snapraid_info info;
177 :
178 : /* increment the position until the first really free block */
- 179 1022464 : while (block_has_file(fs_par2block_find(disk, parity_pos)))
- 180 520292 : ++parity_pos;
+ 179 1022825 : while (block_has_file(fs_par2block_find(disk, parity_pos)))
+ 180 520289 : ++parity_pos;
181 :
182 : /* get block we are going to overwrite, if any */
- 183 251086 : over_block = fs_par2block_find(disk, parity_pos);
+ 183 251268 : over_block = fs_par2block_find(disk, parity_pos);
184 :
185 : /* deallocate it */
- 186 251086 : if (over_block != BLOCK_NULL)
- 187 95173 : fs_deallocate(disk, parity_pos);
+ 186 251268 : if (over_block != BLOCK_NULL)
+ 187 95355 : fs_deallocate(disk, parity_pos);
188 :
189 : /* get block specific info */
- 190 251086 : info = info_get(&state->infoarr, parity_pos);
+ 190 251268 : info = info_get(&state->infoarr, parity_pos);
191 :
192 : /* get the new block we are going to write */
- 193 251086 : block = fs_file2block_get(file, i);
+ 193 251268 : block = fs_file2block_get(file, i);
194 :
195 : /* if the file block already has an updated hash without rehash */
- 196 251086 : if (block_has_updated_hash(block) && !info_get_rehash(info)) {
+ 196 251268 : if (block_has_updated_hash(block) && !info_get_rehash(info)) {
197 : /* the only possible case is for REP blocks */
- 198 86199 : assert(block_state_get(block) == BLOCK_STATE_REP);
+ 198 86215 : assert(block_state_get(block) == BLOCK_STATE_REP);
199 :
200 : /* convert to a REP block */
- 201 86199 : block_state_set(block, BLOCK_STATE_REP);
+ 201 86215 : block_state_set(block, BLOCK_STATE_REP);
202 :
203 : /* and keep the hash as it's */
204 : } else {
205 : unsigned over_state;
206 :
207 : /* convert to a CHG block */
- 208 164887 : block_state_set(block, BLOCK_STATE_CHG);
+ 208 165053 : block_state_set(block, BLOCK_STATE_CHG);
209 :
210 : /* state of the block we are going to overwrite */
- 211 164887 : over_state = block_state_get(over_block);
+ 211 165053 : over_state = block_state_get(over_block);
212 :
213 : /* if the block is an empty one */
- 214 164887 : if (over_state == BLOCK_STATE_EMPTY) {
+ 214 165053 : if (over_state == BLOCK_STATE_EMPTY) {
215 : /* the block was empty and filled with zeros */
216 : /* set the hash to the special ZERO value */
217 115543 : hash_zero_set(block->hash);
218 : } else {
219 : /* otherwise it's a DELETED one */
- 220 49344 : assert(over_state == BLOCK_STATE_DELETED);
+ 220 49510 : assert(over_state == BLOCK_STATE_DELETED);
221 :
222 : /* copy the past hash of the block */
- 223 49344 : memcpy(block->hash, over_block->hash, BLOCK_HASH_SIZE);
+ 223 49510 : memcpy(block->hash, over_block->hash, BLOCK_HASH_SIZE);
224 :
225 : /* if we have not already cleared the past hash */
- 226 49344 : if (!state->clear_past_hash) {
+ 226 49510 : if (!state->clear_past_hash) {
227 : /* in this case we don't know if the old state is still the one */
228 : /* stored inside the parity, because after an aborted sync, the parity */
229 : /* may be or may be not have been updated with the new data */
@@ -296,21 +296,21 @@
234 : /* but without saving the content file representing this new state. */
235 : /* - Another file is added again (exactly here) */
236 : /* with the hash of DELETED block not representing the real parity state */
- 237 381 : hash_invalid_set(block->hash);
+ 237 421 : hash_invalid_set(block->hash);
238 : }
239 : }
240 : }
241 :
242 : /* store in the disk map, after invalidating all the other blocks */
- 243 251086 : fs_allocate(disk, parity_pos, file, i);
+ 243 251268 : fs_allocate(disk, parity_pos, file, i);
244 :
245 : /* set the new free position */
- 246 251086 : disk->first_free_block = parity_pos + 1;
+ 246 251268 : disk->first_free_block = parity_pos + 1;
247 : }
248 :
249 : /* insert in the list of contained files */
- 250 101836 : tommy_list_insert_tail(&disk->filelist, &file->nodelist, file);
- 251 101836 : }
+ 250 101892 : tommy_list_insert_tail(&disk->filelist, &file->nodelist, file);
+ 251 101892 : }
252 :
253 : /**
254 : * Delete the specified file from the parity.
@@ -319,23 +319,23 @@
257 : * The file is then inserted in the deleted set, and it should not be deallocated,
258 : * as the parity still references it.
259 : */
- 260 56970 : static void scan_file_deallocate(struct snapraid_scan* scan, struct snapraid_file* file)
+ 260 57026 : static void scan_file_deallocate(struct snapraid_scan* scan, struct snapraid_file* file)
261 : {
- 262 56970 : struct snapraid_state* state = scan->state;
- 263 56970 : struct snapraid_disk* disk = scan->disk;
+ 262 57026 : struct snapraid_state* state = scan->state;
+ 263 57026 : struct snapraid_disk* disk = scan->disk;
264 : block_off_t i;
265 :
266 : /* remove from the list of contained files */
- 267 56970 : tommy_list_remove_existing(&disk->filelist, &file->nodelist);
+ 267 57026 : tommy_list_remove_existing(&disk->filelist, &file->nodelist);
268 :
269 : /* state changed */
- 270 56970 : state->need_write = 1;
+ 270 57026 : state->need_write = 1;
271 :
272 : /* here we are supposed to adjust the ::first_free_block position */
273 : /* with the parity position we are deleting */
274 : /* but we also know that we do only delayed insert, after all the deletion, */
275 : /* so at this point ::first_free_block is always at 0, and we don't need to update it */
- 276 56970 : if (disk->first_free_block != 0) {
+ 276 57026 : if (disk->first_free_block != 0) {
277 : /* LCOV_EXCL_START */
278 : log_fatal("Internal inconsistency for first free position at '%u' deallocating file '%s'\n", disk->first_free_block, file->sub);
279 : os_abort();
@@ -343,20 +343,20 @@
281 : }
282 :
283 : /* free all the blocks of the file */
- 284 197441 : for (i = 0; i < file->blockmax; ++i) {
- 285 140471 : struct snapraid_block* block = fs_file2block_get(file, i);
+ 284 197679 : for (i = 0; i < file->blockmax; ++i) {
+ 285 140653 : struct snapraid_block* block = fs_file2block_get(file, i);
286 : unsigned block_state;
287 :
288 : /* in case we scan after an aborted sync, */
289 : /* we could get also intermediate states */
- 290 140471 : block_state = block_state_get(block);
- 291 140471 : switch (block_state) {
+ 290 140653 : block_state = block_state_get(block);
+ 291 140653 : switch (block_state) {
292 : case BLOCK_STATE_BLK :
293 : /* we keep the hash making it an "old" hash, because the parity is still containing data for it */
- 294 35530 : break;
+ 294 35656 : break;
295 : case BLOCK_STATE_CHG :
296 : /* if we have not already cleared the past hash */
- 297 28000 : if (!state->clear_past_hash) {
+ 297 28040 : if (!state->clear_past_hash) {
298 : /* in these cases we don't know if the old state is still the one */
299 : /* stored inside the parity, because after an aborted sync, the parity */
300 : /* may be or may be not have been updated with the data that it's now */
@@ -368,13 +368,13 @@
306 : /* - File is now deleted after the aborted sync */
307 : /* - Sync again, deleting the blocks (exactly here) */
308 : /* with the hash of CHG block not representing the real parity state */
- 309 0 : hash_invalid_set(block->hash);
+ 309 40 : hash_invalid_set(block->hash);
310 : }
- 311 28000 : break;
+ 311 28040 : break;
312 : case BLOCK_STATE_REP :
313 : /* we just don't know the old hash, and then we set it to invalid */
- 314 76941 : hash_invalid_set(block->hash);
- 315 76941 : break;
+ 314 76957 : hash_invalid_set(block->hash);
+ 315 76957 : break;
316 : default :
317 : /* LCOV_EXCL_START */
318 : log_fatal("Internal inconsistency in file '%s' deallocating block '%u:%u' state %u\n", file->sub, i, file->blockmax, block_state);
@@ -383,23 +383,23 @@
321 : }
322 :
323 : /* set the block as deleted */
- 324 140471 : block_state_set(block, BLOCK_STATE_DELETED);
+ 324 140653 : block_state_set(block, BLOCK_STATE_DELETED);
325 : }
326 :
327 : /* mark the file as deleted */
- 328 56970 : file_flag_set(file, FILE_IS_DELETED);
+ 328 57026 : file_flag_set(file, FILE_IS_DELETED);
329 :
330 : /* insert it in the list of deleted blocks */
- 331 56970 : tommy_list_insert_tail(&disk->deletedlist, &file->nodelist, file);
- 332 56970 : }
+ 331 57026 : tommy_list_insert_tail(&disk->deletedlist, &file->nodelist, file);
+ 332 57026 : }
333 :
- 334 101836 : static void scan_file_delayed_allocate(struct snapraid_scan* scan, struct snapraid_file* file)
+ 334 101892 : static void scan_file_delayed_allocate(struct snapraid_scan* scan, struct snapraid_file* file)
335 : {
- 336 101836 : struct snapraid_state* state = scan->state;
- 337 101836 : struct snapraid_disk* disk = scan->disk;
+ 336 101892 : struct snapraid_state* state = scan->state;
+ 337 101892 : struct snapraid_disk* disk = scan->disk;
338 :
339 : /* if we sort for physical offsets we have to read them for new files */
- 340 101836 : if (state->opt.force_order == SORT_PHYSICAL
+ 340 101892 : if (state->opt.force_order == SORT_PHYSICAL
341 11432 : && file->physical == FILEPHY_UNREAD_OFFSET
342 : ) {
343 : char path_next[PATH_MAX];
@@ -415,30 +415,30 @@
353 : }
354 :
355 : /* insert in the delayed list */
- 356 101836 : tommy_list_insert_tail(&scan->file_insert_list, &file->nodelist, file);
- 357 101836 : }
+ 356 101892 : tommy_list_insert_tail(&scan->file_insert_list, &file->nodelist, file);
+ 357 101892 : }
358 :
359 : /**
360 : * Check if a file is completely formed of blocks with invalid parity,
361 : * and no rehash is tagged, and if it has at least one block.
362 : */
- 363 1025576 : static int file_is_full_invalid_parity_and_stable(struct snapraid_state* state, struct snapraid_disk* disk, struct snapraid_file* file)
+ 363 1025539 : static int file_is_full_invalid_parity_and_stable(struct snapraid_state* state, struct snapraid_disk* disk, struct snapraid_file* file)
364 : {
365 : block_off_t i;
366 :
367 : /* with no block, it never has an invalid parity */
- 368 1025576 : if (file->blockmax == 0)
- 369 1436 : return 0;
+ 368 1025539 : if (file->blockmax == 0)
+ 369 1437 : return 0;
370 :
371 : /* check all blocks */
- 372 1080052 : for (i = 0; i < file->blockmax; ++i) {
+ 372 1080070 : for (i = 0; i < file->blockmax; ++i) {
373 : snapraid_info info;
- 374 1057372 : struct snapraid_block* block = fs_file2block_get(file, i);
+ 374 1057383 : struct snapraid_block* block = fs_file2block_get(file, i);
375 : block_off_t parity_pos;
376 :
377 : /* exclude blocks with parity */
- 378 1057372 : if (!block_has_invalid_parity(block))
- 379 1001460 : return 0;
+ 378 1057383 : if (!block_has_invalid_parity(block))
+ 379 1001415 : return 0;
380 :
381 : /*
382 : * Get the parity position.
@@ -448,20 +448,20 @@
386 : *
387 : * Anyway, checking for POS_NULL doesn't hurt.
388 : */
- 389 55912 : parity_pos = fs_file2par_find(disk, file, i);
+ 389 55968 : parity_pos = fs_file2par_find(disk, file, i);
390 :
391 : /* if it's not mapped, it cannot have rehash */
- 392 55912 : if (parity_pos != POS_NULL) {
+ 392 55968 : if (parity_pos != POS_NULL) {
393 : /* get block specific info */
- 394 55912 : info = info_get(&state->infoarr, parity_pos);
+ 394 55968 : info = info_get(&state->infoarr, parity_pos);
395 :
396 : /* if rehash fails */
- 397 55912 : if (info_get_rehash(info))
+ 397 55968 : if (info_get_rehash(info))
398 0 : return 0;
399 : }
400 : }
401 :
- 402 22680 : return 1;
+ 402 22687 : return 1;
403 : }
404 :
405 : /**
@@ -525,7 +525,7 @@
463 : *
464 : * If this happens, we read also the physical offset, to avoid to read it later.
465 : */
- 466 79156 : static void scan_file_refresh(struct snapraid_scan* scan, const char* sub, struct stat* st, uint64_t* physical)
+ 466 79205 : static void scan_file_refresh(struct snapraid_scan* scan, const char* sub, struct stat* st, uint64_t* physical)
467 : {
468 : #if HAVE_LSTAT_SYNC
469 : struct snapraid_state* state = scan->state;
@@ -597,43 +597,43 @@
535 : (void)st;
536 : (void)physical;
537 : #endif
- 538 79156 : }
+ 538 79205 : }
539 :
540 : /**
541 : * Insert the file in the data set.
542 : */
- 543 101836 : static void scan_file_insert(struct snapraid_scan* scan, struct snapraid_file* file)
+ 543 101892 : static void scan_file_insert(struct snapraid_scan* scan, struct snapraid_file* file)
544 : {
- 545 101836 : struct snapraid_disk* disk = scan->disk;
+ 545 101892 : struct snapraid_disk* disk = scan->disk;
546 :
547 : /* insert the file in the containers */
- 548 101836 : if (!file_flag_has(file, FILE_IS_WITHOUT_INODE))
- 549 101836 : tommy_hashdyn_insert(&disk->inodeset, &file->nodeset, file, file_inode_hash(file->inode));
- 550 101836 : tommy_hashdyn_insert(&disk->pathset, &file->pathset, file, file_path_hash(file->sub));
- 551 101836 : tommy_hashdyn_insert(&disk->stampset, &file->stampset, file, file_stamp_hash(file->size, file->mtime_sec, file->mtime_nsec));
+ 548 101892 : if (!file_flag_has(file, FILE_IS_WITHOUT_INODE))
+ 549 101892 : tommy_hashdyn_insert(&disk->inodeset, &file->nodeset, file, file_inode_hash(file->inode));
+ 550 101892 : tommy_hashdyn_insert(&disk->pathset, &file->pathset, file, file_path_hash(file->sub));
+ 551 101892 : tommy_hashdyn_insert(&disk->stampset, &file->stampset, file, file_stamp_hash(file->size, file->mtime_sec, file->mtime_nsec));
552 :
553 : /* delayed allocation of the parity */
- 554 101836 : scan_file_delayed_allocate(scan, file);
- 555 101836 : }
+ 554 101892 : scan_file_delayed_allocate(scan, file);
+ 555 101892 : }
556 :
557 : /**
558 : * Remove the file from the data set.
559 : *
560 : * File is then deleted.
561 : */
- 562 56970 : static void scan_file_remove(struct snapraid_scan* scan, struct snapraid_file* file)
+ 562 57026 : static void scan_file_remove(struct snapraid_scan* scan, struct snapraid_file* file)
563 : {
- 564 56970 : struct snapraid_disk* disk = scan->disk;
+ 564 57026 : struct snapraid_disk* disk = scan->disk;
565 :
566 : /* remove the file from the containers */
- 567 56970 : if (!file_flag_has(file, FILE_IS_WITHOUT_INODE))
- 568 56918 : tommy_hashdyn_remove_existing(&disk->inodeset, &file->nodeset);
- 569 56970 : tommy_hashdyn_remove_existing(&disk->pathset, &file->pathset);
- 570 56970 : tommy_hashdyn_remove_existing(&disk->stampset, &file->stampset);
+ 567 57026 : if (!file_flag_has(file, FILE_IS_WITHOUT_INODE))
+ 568 56974 : tommy_hashdyn_remove_existing(&disk->inodeset, &file->nodeset);
+ 569 57026 : tommy_hashdyn_remove_existing(&disk->pathset, &file->pathset);
+ 570 57026 : tommy_hashdyn_remove_existing(&disk->stampset, &file->stampset);
571 :
572 : /* deallocate the file from the parity */
- 573 56970 : scan_file_deallocate(scan, file);
- 574 56970 : }
+ 573 57026 : scan_file_deallocate(scan, file);
+ 574 57026 : }
575 :
576 : /**
577 : * Keep the file as it's (or with only a name/inode modification).
@@ -646,29 +646,29 @@
584 : * This could happen after a failed sync, when some other files are deleted,
585 : * and then new ones can be moved backward to fill the hole created.
586 : */
- 587 1025576 : static void scan_file_keep(struct snapraid_scan* scan, struct snapraid_file* file)
+ 587 1025539 : static void scan_file_keep(struct snapraid_scan* scan, struct snapraid_file* file)
588 : {
- 589 1025576 : struct snapraid_disk* disk = scan->disk;
+ 589 1025539 : struct snapraid_disk* disk = scan->disk;
590 :
591 : /* if the file is full invalid, schedule a reinsert at later stage */
- 592 1025576 : if (file_is_full_invalid_parity_and_stable(scan->state, disk, file)) {
- 593 22680 : struct snapraid_file* copy = file_dup(file);
+ 592 1025539 : if (file_is_full_invalid_parity_and_stable(scan->state, disk, file)) {
+ 593 22687 : struct snapraid_file* copy = file_dup(file);
594 :
595 : /* remove the file */
- 596 22680 : scan_file_remove(scan, file);
+ 596 22687 : scan_file_remove(scan, file);
597 :
598 : /* reinsert the copy in the delayed list */
- 599 22680 : scan_file_insert(scan, copy);
+ 599 22687 : scan_file_insert(scan, copy);
600 : }
- 601 1025576 : }
+ 601 1025539 : }
602 :
603 : /**
604 : * Process a file.
605 : */
- 606 1104927 : static void scan_file(struct snapraid_scan* scan, int is_diff, const char* sub, struct stat* st, uint64_t physical)
+ 606 1104939 : static void scan_file(struct snapraid_scan* scan, int is_diff, const char* sub, struct stat* st, uint64_t physical)
607 : {
- 608 1104927 : struct snapraid_state* state = scan->state;
- 609 1104927 : struct snapraid_disk* disk = scan->disk;
+ 608 1104939 : struct snapraid_state* state = scan->state;
+ 609 1104939 : struct snapraid_disk* disk = scan->disk;
610 : struct snapraid_file* file;
611 : tommy_node* i;
612 : int is_original_file_size_different_than_zero;
@@ -706,28 +706,28 @@
644 : * This ensures that no file is found with a past inode, but at the same time,
645 : * it allows to find new files with the same inode, to identify them as hardlinks.
646 : */
- 647 1104927 : int has_past_inodes = !disk->has_volatile_inodes && !disk->has_different_uuid && !disk->has_unsupported_uuid;
+ 647 1104939 : int has_past_inodes = !disk->has_volatile_inodes && !disk->has_different_uuid && !disk->has_unsupported_uuid;
648 :
649 : /* always search with the new inode, in the all new inodes found until now, */
650 : /* with the eventual presence of also the past inodes */
- 651 1104927 : uint64_t inode = st->st_ino;
+ 651 1104939 : uint64_t inode = st->st_ino;
652 :
- 653 1104927 : file = tommy_hashdyn_search(&disk->inodeset, file_inode_compare_to_arg, &inode, file_inode_hash(inode));
+ 653 1104939 : file = tommy_hashdyn_search(&disk->inodeset, file_inode_compare_to_arg, &inode, file_inode_hash(inode));
654 :
655 : /* identify moved files with past inodes and hardlinks with the new inodes */
- 656 1104927 : if (file) {
+ 656 1104939 : if (file) {
657 : /* check if the file is not changed */
- 658 949639 : if (file->size == st->st_size
- 659 935884 : && file->mtime_sec == st->st_mtime
- 660 932864 : && (file->mtime_nsec == STAT_NSEC(st)
+ 658 949678 : if (file->size == st->st_size
+ 659 935913 : && file->mtime_sec == st->st_mtime
+ 660 932896 : && (file->mtime_nsec == STAT_NSEC(st)
661 : /* always accept the stored value if it's STAT_NSEC_INVALID */
662 : /* it happens when upgrading from an old version of SnapRAID */
663 : /* not yet supporting the nanosecond field */
- 664 2 : || file->mtime_nsec == STAT_NSEC_INVALID
+ 664 1 : || file->mtime_nsec == STAT_NSEC_INVALID
665 : )
666 : ) {
667 : /* check if multiple files have the same inode */
- 668 932862 : if (file_flag_has(file, FILE_IS_PRESENT)) {
+ 668 932895 : if (file_flag_has(file, FILE_IS_PRESENT)) {
669 : #if HAVE_STRUCT_STAT_ST_NLINK
670 195 : if (st->st_nlink <= 1) {
671 : /* LCOV_EXCL_START */
@@ -742,11 +742,11 @@
680 : }
681 :
682 : /* mark as present */
- 683 932667 : file_flag_set(file, FILE_IS_PRESENT);
+ 683 932700 : file_flag_set(file, FILE_IS_PRESENT);
684 :
685 : /* update the nanoseconds mtime only if different */
686 : /* to avoid unneeded updates */
- 687 932667 : if (file->mtime_nsec == STAT_NSEC_INVALID
+ 687 932700 : if (file->mtime_nsec == STAT_NSEC_INVALID
688 0 : && STAT_NSEC(st) != file->mtime_nsec
689 : ) {
690 0 : file->mtime_nsec = STAT_NSEC(st);
@@ -755,7 +755,7 @@
693 0 : state->need_write = 1;
694 : }
695 :
- 696 932667 : if (strcmp(file->sub, sub) != 0) {
+ 696 932700 : if (strcmp(file->sub, sub) != 0) {
697 : /* if the path is different, it means a moved file with the same inode */
698 155 : ++scan->count_move;
699 :
@@ -777,18 +777,18 @@
715 155 : state->need_write = 1;
716 : } else {
717 : /* otherwise it's equal */
- 718 932512 : ++scan->count_equal;
+ 718 932545 : ++scan->count_equal;
719 :
- 720 932512 : if (state->opt.gui) {
- 721 22599 : log_tag("scan:equal:%s:%s\n", disk->name, esc_tag(file->sub, esc_buffer));
+ 720 932545 : if (state->opt.gui) {
+ 721 22611 : log_tag("scan:equal:%s:%s\n", disk->name, esc_tag(file->sub, esc_buffer));
722 : }
723 : }
724 :
725 : /* mark the file as kept */
- 726 932667 : scan_file_keep(scan, file);
+ 726 932700 : scan_file_keep(scan, file);
727 :
728 : /* nothing more to do */
- 729 932667 : return;
+ 729 932700 : return;
730 : }
731 :
732 : /* here the file matches the inode, but not the other info */
@@ -797,7 +797,7 @@
735 : /* or a file-system with not persistent inodes */
736 :
737 : /* for sure it cannot be already present */
- 738 16777 : if (file_flag_has(file, FILE_IS_PRESENT)) {
+ 738 16783 : if (file_flag_has(file, FILE_IS_PRESENT)) {
739 : /* LCOV_EXCL_START */
740 : 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);
741 : os_abort();
@@ -810,44 +810,44 @@
748 : /* otherwise, it will get removed */
749 :
750 : /* remove from the inode set */
- 751 16777 : tommy_hashdyn_remove_existing(&disk->inodeset, &file->nodeset);
+ 751 16783 : tommy_hashdyn_remove_existing(&disk->inodeset, &file->nodeset);
752 :
753 : /* clear the inode */
754 : /* this is not really needed for correct functionality */
755 : /* because we are going to set FILE_IS_WITHOUT_INODE */
756 : /* but it's easier for debugging to have invalid inodes set to 0 */
- 757 16777 : file->inode = 0;
+ 757 16783 : file->inode = 0;
758 :
759 : /* mark as missing inode */
- 760 16777 : file_flag_set(file, FILE_IS_WITHOUT_INODE);
+ 760 16783 : file_flag_set(file, FILE_IS_WITHOUT_INODE);
761 :
762 : /* go further to find it by name */
763 : }
764 :
765 : /* initialize for later overwrite */
- 766 172065 : is_file_reported = 0;
- 767 172065 : is_original_file_size_different_than_zero = 0;
+ 766 172044 : is_file_reported = 0;
+ 767 172044 : is_original_file_size_different_than_zero = 0;
768 :
769 : /* then try finding it by name */
- 770 172065 : file = tommy_hashdyn_search(&disk->pathset, file_path_compare_to_arg, sub, file_path_hash(sub));
+ 770 172044 : file = tommy_hashdyn_search(&disk->pathset, file_path_compare_to_arg, sub, file_path_hash(sub));
771 :
772 : /* keep track if the file already exists */
- 773 172065 : is_file_already_present = file != 0;
+ 773 172044 : is_file_already_present = file != 0;
774 :
- 775 172065 : if (is_file_already_present) {
+ 775 172044 : if (is_file_already_present) {
776 : /* if the file is without an inode */
- 777 97552 : if (file_flag_has(file, FILE_IS_WITHOUT_INODE)) {
+ 777 97531 : if (file_flag_has(file, FILE_IS_WITHOUT_INODE)) {
778 : /* set it now */
- 779 16739 : file->inode = st->st_ino;
+ 779 16745 : file->inode = st->st_ino;
780 :
781 : /* insert in the set */
- 782 16739 : tommy_hashdyn_insert(&disk->inodeset, &file->nodeset, file, file_inode_hash(file->inode));
+ 782 16745 : tommy_hashdyn_insert(&disk->inodeset, &file->nodeset, file, file_inode_hash(file->inode));
783 :
784 : /* unmark as missing inode */
- 785 16739 : file_flag_clear(file, FILE_IS_WITHOUT_INODE);
+ 785 16745 : file_flag_clear(file, FILE_IS_WITHOUT_INODE);
786 : } else {
787 : /* here the inode has to be different, otherwise we would have found it before */
- 788 80813 : if (file->inode == st->st_ino) {
+ 788 80786 : if (file->inode == st->st_ino) {
789 : /* LCOV_EXCL_START */
790 : log_fatal("Internal inconsistency in inode '%" PRIu64 "' for files '%s%s' as unexpected matching\n", file->inode, disk->dir, sub);
791 : os_abort();
@@ -856,7 +856,7 @@
794 : }
795 :
796 : /* for sure it cannot be already present */
- 797 97552 : if (file_flag_has(file, FILE_IS_PRESENT)) {
+ 797 97531 : if (file_flag_has(file, FILE_IS_PRESENT)) {
798 : /* LCOV_EXCL_START */
799 : log_fatal("Internal inconsistency in path for file '%s%s' matching and already present\n", disk->dir, sub);
800 : os_abort();
@@ -864,9 +864,9 @@
802 : }
803 :
804 : /* check if the file is not changed */
- 805 97552 : if (file->size == st->st_size
- 806 96956 : && file->mtime_sec == st->st_mtime
- 807 92909 : && (file->mtime_nsec == STAT_NSEC(st)
+ 805 97531 : if (file->size == st->st_size
+ 806 96935 : && file->mtime_sec == st->st_mtime
+ 807 92839 : && (file->mtime_nsec == STAT_NSEC(st)
808 : /* always accept the stored value if it's STAT_NSEC_INVALID */
809 : /* it happens when upgrading from an old version of SnapRAID */
810 : /* not yet supporting the nanosecond field */
@@ -874,11 +874,11 @@
812 : )
813 : ) {
814 : /* mark as present */
- 815 92909 : file_flag_set(file, FILE_IS_PRESENT);
+ 815 92839 : file_flag_set(file, FILE_IS_PRESENT);
816 :
817 : /* update the nano seconds mtime only if different */
818 : /* to avoid unneeded updates */
- 819 92909 : if (file->mtime_nsec == STAT_NSEC_INVALID
+ 819 92839 : if (file->mtime_nsec == STAT_NSEC_INVALID
820 0 : && STAT_NSEC(st) != STAT_NSEC_INVALID
821 : ) {
822 0 : file->mtime_nsec = STAT_NSEC(st);
@@ -888,30 +888,30 @@
826 : }
827 :
828 : /* if when processing the disk we used the past inodes values */
- 829 92909 : if (has_past_inodes) {
+ 829 92839 : if (has_past_inodes) {
830 : /* if persistent inodes are supported, we are sure that the inode number */
831 : /* is now different, because otherwise the file would have been found */
832 : /* when searching by inode. */
833 : /* if the inode is different, it means a rewritten file with the same path */
834 : /* like when restoring a backup that restores also the timestamp */
- 835 92895 : ++scan->count_restore;
+ 835 92825 : ++scan->count_restore;
836 :
- 837 92895 : log_tag("scan:restore:%s:%s\n", disk->name, esc_tag(sub, esc_buffer));
- 838 92895 : if (is_diff) {
+ 837 92825 : log_tag("scan:restore:%s:%s\n", disk->name, esc_tag(sub, esc_buffer));
+ 838 92825 : if (is_diff) {
839 0 : printf("restore %s\n", fmt_term(disk, sub, esc_buffer));
840 : }
841 :
842 : /* remove from the inode set */
- 843 92895 : tommy_hashdyn_remove_existing(&disk->inodeset, &file->nodeset);
+ 843 92825 : tommy_hashdyn_remove_existing(&disk->inodeset, &file->nodeset);
844 :
845 : /* save the new inode */
- 846 92895 : file->inode = st->st_ino;
+ 846 92825 : file->inode = st->st_ino;
847 :
848 : /* reinsert in the inode set */
- 849 92895 : tommy_hashdyn_insert(&disk->inodeset, &file->nodeset, file, file_inode_hash(file->inode));
+ 849 92825 : tommy_hashdyn_insert(&disk->inodeset, &file->nodeset, file, file_inode_hash(file->inode));
850 :
851 : /* we have to save the new inode */
- 852 92895 : state->need_write = 1;
+ 852 92825 : state->need_write = 1;
853 : } else {
854 : /* otherwise it's the case of not persistent inode, where doesn't */
855 : /* matter if the inode is different or equal, because they have no */
@@ -924,24 +924,24 @@
862 : }
863 :
864 : /* mark the file as kept */
- 865 92909 : scan_file_keep(scan, file);
+ 865 92839 : scan_file_keep(scan, file);
866 :
867 : /* nothing more to do */
- 868 92909 : return;
+ 868 92839 : return;
869 : }
870 :
871 : /* here if the file is changed but with the correct name */
872 :
873 : /* save the info for later printout */
- 874 4643 : file_already_present_size = file->size;
- 875 4643 : file_already_present_mtime_sec = file->mtime_sec;
- 876 4643 : file_already_present_mtime_nsec = file->mtime_nsec;
+ 874 4692 : file_already_present_size = file->size;
+ 875 4692 : file_already_present_mtime_sec = file->mtime_sec;
+ 876 4692 : file_already_present_mtime_nsec = file->mtime_nsec;
877 :
878 : /* keep track if the original file was not of zero size */
- 879 4643 : is_original_file_size_different_than_zero = file->size != 0;
+ 879 4692 : is_original_file_size_different_than_zero = file->size != 0;
880 :
881 : /* remove it, and continue to insert it again */
- 882 4643 : scan_file_remove(scan, file);
+ 882 4692 : scan_file_remove(scan, file);
883 :
884 : /* and continue to insert it again */
885 : } else {
@@ -953,13 +953,13 @@
891 : /* refresh the info, to ensure that they are synced, */
892 : /* note that we refresh only the info of the new or modified files */
893 : /* because this is slow operation */
- 894 79156 : scan_file_refresh(scan, sub, st, &physical);
+ 894 79205 : scan_file_refresh(scan, sub, st, &physical);
895 :
896 : #ifndef _WIN32
897 : /* do a safety check to ensure that the common ext4 case of zeroing */
898 : /* the size of a file after a crash doesn't propagate to the backup */
899 : /* this check is specific for Linux, so we disable it on Windows */
- 900 79156 : if (is_original_file_size_different_than_zero && st->st_size == 0) {
+ 900 79205 : if (is_original_file_size_different_than_zero && st->st_size == 0) {
901 0 : if (!state->opt.force_zero) {
902 : /* LCOV_EXCL_START */
903 : log_fatal("The file '%s%s' has unexpected zero size!\n", disk->dir, sub);
@@ -978,33 +978,33 @@
916 : #endif
917 :
918 : /* insert it */
- 919 79156 : file = file_alloc(state->block_size, sub, st->st_size, st->st_mtime, STAT_NSEC(st), st->st_ino, physical);
+ 919 79205 : file = file_alloc(state->block_size, sub, st->st_size, st->st_mtime, STAT_NSEC(st), st->st_ino, physical);
920 :
921 : /* mark it as present */
- 922 79156 : file_flag_set(file, FILE_IS_PRESENT);
+ 922 79205 : file_flag_set(file, FILE_IS_PRESENT);
923 :
924 : /* if copy detection is enabled */
925 : /* note that the copy detection is tried also for updated files */
926 : /* this makes sense because it may happen to have two different copies */
927 : /* of the same file, and we move the right one over the wrong one */
928 : /* in such case we have a "copy" over an "update" */
- 929 79156 : if (!state->opt.force_nocopy) {
- 930 79156 : tommy_uint32_t hash = file_stamp_hash(file->size, file->mtime_sec, file->mtime_nsec);
+ 929 79205 : if (!state->opt.force_nocopy) {
+ 930 79205 : tommy_uint32_t hash = file_stamp_hash(file->size, file->mtime_sec, file->mtime_nsec);
931 :
932 : /* search for a file with the same name and stamp in all the disks */
- 933 423144 : for (i = state->disklist; i != 0; i = i->next) {
- 934 367624 : struct snapraid_disk* other_disk = i->data;
+ 933 423487 : for (i = state->disklist; i != 0; i = i->next) {
+ 934 367918 : struct snapraid_disk* other_disk = i->data;
935 : struct snapraid_file* other_file;
936 :
937 : /* if the nanosecond part of the time stamp is valid, search */
938 : /* for name and stamp, otherwise for path and stamp */
- 939 367624 : if (file->mtime_nsec != 0 && file->mtime_nsec != STAT_NSEC_INVALID)
- 940 367516 : other_file = tommy_hashdyn_search(&other_disk->stampset, file_namestamp_compare, file, hash);
+ 939 367918 : if (file->mtime_nsec != 0 && file->mtime_nsec != STAT_NSEC_INVALID)
+ 940 367810 : other_file = tommy_hashdyn_search(&other_disk->stampset, file_namestamp_compare, file, hash);
941 : else
942 108 : other_file = tommy_hashdyn_search(&other_disk->stampset, file_pathstamp_compare, file, hash);
943 :
944 : /* if found, and it's a fully hashed file */
- 945 367624 : if (other_file && file_is_full_hashed_and_stable(scan->state, other_disk, other_file)) {
+ 945 367918 : if (other_file && file_is_full_hashed_and_stable(scan->state, other_disk, other_file)) {
946 : /* assume that the file is a copy, and reuse the hash */
947 23636 : file_copy(other_file, file);
948 :
@@ -1027,16 +1027,16 @@
965 :
966 : /* if not yet reported, do it now */
967 : /* we postpone this to avoid to print two times the copied files */
- 968 79156 : if (!is_file_reported) {
- 969 55520 : if (is_file_already_present) {
- 970 4643 : ++scan->count_change;
+ 968 79205 : if (!is_file_reported) {
+ 969 55569 : if (is_file_already_present) {
+ 970 4692 : ++scan->count_change;
971 :
- 972 13929 : log_tag("scan:update:%s:%s: %" PRIu64 " %" PRIu64 ".%d -> %" PRIu64 " %" PRIu64 ".%d\n", disk->name, esc_tag(sub, esc_buffer),
+ 972 14076 : log_tag("scan:update:%s:%s: %" PRIu64 " %" PRIu64 ".%d -> %" PRIu64 " %" PRIu64 ".%d\n", disk->name, esc_tag(sub, esc_buffer),
973 : (uint64_t)file_already_present_size, (uint64_t)file_already_present_mtime_sec, file_already_present_mtime_nsec,
- 974 9286 : (uint64_t)file->size, (uint64_t)file->mtime_sec, file->mtime_nsec
+ 974 9384 : (uint64_t)file->size, (uint64_t)file->mtime_sec, file->mtime_nsec
975 : );
976 :
- 977 4643 : if (is_diff) {
+ 977 4692 : if (is_diff) {
978 118 : printf("update %s\n", fmt_term(disk, sub, esc_buffer));
979 : }
980 : } else {
@@ -1050,7 +1050,7 @@
988 : }
989 :
990 : /* insert the file in the delayed list */
- 991 79156 : scan_file_insert(scan, file);
+ 991 79205 : scan_file_insert(scan, file);
992 : }
993 :
994 : /**
@@ -1157,12 +1157,12 @@
1095 : }
1096 : #endif
1097 :
- 1098 11526102 : static int dd_name_compare(const void* void_a, const void* void_b)
+ 1098 11526118 : static int dd_name_compare(const void* void_a, const void* void_b)
1099 : {
- 1100 11526102 : const struct dirent_sorted* a = void_a;
- 1101 11526102 : const struct dirent_sorted* b = void_b;
+ 1100 11526118 : const struct dirent_sorted* a = void_a;
+ 1101 11526118 : const struct dirent_sorted* b = void_b;
1102 :
- 1103 11526102 : return strcmp(a->d_name, b->d_name);
+ 1103 11526118 : return strcmp(a->d_name, b->d_name);
1104 : }
1105 :
1106 : /**
@@ -1176,15 +1176,15 @@
1114 : }
1115 : #else
1116 : #define DSTAT(file, dd, buf) dstat(file, buf)
- 1117 1106198 : struct stat* dstat(const char* file, struct stat* st)
+ 1117 1106210 : struct stat* dstat(const char* file, struct stat* st)
1118 : {
- 1119 1106198 : if (lstat(file, st) != 0) {
+ 1119 1106210 : if (lstat(file, st) != 0) {
1120 : /* LCOV_EXCL_START */
1121 : log_fatal("Error in stat file/directory '%s'. %s.\n", file, strerror(errno));
1122 : exit(EXIT_FAILURE);
1123 : /* LCOV_EXCL_STOP */
1124 : }
- 1125 1106198 : return st;
+ 1125 1106210 : return st;
1126 : }
1127 : #endif
1128 :
@@ -1192,19 +1192,19 @@
1130 : * Process a directory.
1131 : * Return != 0 if at least one file or link is processed.
1132 : */
- 1133 1840 : static int scan_dir(struct snapraid_scan* scan, int level, int is_diff, const char* dir, const char* sub)
+ 1133 1846 : static int scan_dir(struct snapraid_scan* scan, int level, int is_diff, const char* dir, const char* sub)
1134 : {
- 1135 1840 : struct snapraid_state* state = scan->state;
- 1136 1840 : struct snapraid_disk* disk = scan->disk;
- 1137 1840 : int processed = 0;
+ 1135 1846 : struct snapraid_state* state = scan->state;
+ 1136 1846 : struct snapraid_disk* disk = scan->disk;
+ 1137 1846 : int processed = 0;
1138 : DIR* d;
1139 : tommy_list list;
1140 : tommy_node* node;
1141 :
- 1142 1840 : tommy_list_init(&list);
+ 1142 1846 : tommy_list_init(&list);
1143 :
- 1144 1840 : d = opendir(dir);
- 1145 1840 : if (!d) {
+ 1144 1846 : d = opendir(dir);
+ 1145 1846 : if (!d) {
1146 : /* LCOV_EXCL_START */
1147 : log_fatal("Error opening directory '%s'. %s.\n", dir, strerror(errno));
1148 : if (level == 0)
@@ -1231,29 +1231,29 @@
1169 : * "If the end of the directory stream is reached, NULL is returned and errno is not changed.
1170 : * If an error occurs, NULL is returned and errno is set appropriately."
1171 : */
- 1172 1147707 : errno = 0;
- 1173 1147707 : dd = readdir(d);
- 1174 1147707 : if (dd == 0 && errno != 0) {
+ 1172 1147737 : errno = 0;
+ 1173 1147737 : dd = readdir(d);
+ 1174 1147737 : if (dd == 0 && errno != 0) {
1175 : /* LCOV_EXCL_START */
1176 : log_fatal("Error reading directory '%s'. %s.\n", dir, strerror(errno));
1177 : log_fatal("You can exclude it in the config file with:\n\texclude /%s\n", sub);
1178 : exit(EXIT_FAILURE);
1179 : /* LCOV_EXCL_STOP */
1180 : }
- 1181 1147707 : if (dd == 0) {
- 1182 1840 : break; /* finished */
+ 1181 1147737 : if (dd == 0) {
+ 1182 1846 : break; /* finished */
1183 : }
1184 :
1185 : /* skip "." and ".." files */
- 1186 1145867 : name = dd->d_name;
- 1187 1145867 : if (name[0] == '.' && (name[1] == 0 || (name[1] == '.' && name[2] == 0)))
- 1188 7360 : continue;
+ 1186 1145891 : name = dd->d_name;
+ 1187 1145891 : if (name[0] == '.' && (name[1] == 0 || (name[1] == '.' && name[2] == 0)))
+ 1188 7384 : continue;
1189 :
- 1190 1142187 : pathprint(path_next, sizeof(path_next), "%s%s", dir, name);
- 1191 1142187 : pathprint(sub_next, sizeof(sub_next), "%s%s", sub, name);
+ 1190 1142199 : pathprint(path_next, sizeof(path_next), "%s%s", dir, name);
+ 1191 1142199 : pathprint(sub_next, sizeof(sub_next), "%s%s", sub, name);
1192 :
1193 : /* check for not supported file names */
- 1194 1142187 : if (name[0] == 0) {
+ 1194 1142199 : if (name[0] == 0) {
1195 : /* LCOV_EXCL_START */
1196 : log_fatal("Unsupported name '%s' in file '%s'.\n", name, path_next);
1197 : exit(EXIT_FAILURE);
@@ -1261,26 +1261,26 @@
1199 : }
1200 :
1201 : /* exclude hidden files even before calling lstat() */
- 1202 1142187 : if (filter_hidden(state->filter_hidden, dd) != 0) {
+ 1202 1142199 : if (filter_hidden(state->filter_hidden, dd) != 0) {
1203 0 : msg_verbose("Excluding hidden '%s'\n", path_next);
1204 0 : continue;
1205 : }
1206 :
1207 : /* exclude content files even before calling lstat() */
- 1208 1142187 : if (filter_content(&state->contentlist, path_next) != 0) {
+ 1208 1142199 : if (filter_content(&state->contentlist, path_next) != 0) {
1209 0 : msg_verbose("Excluding content '%s'\n", path_next);
1210 0 : continue;
1211 : }
1212 :
- 1213 1142187 : name_len = strlen(dd->d_name);
- 1214 1142187 : entry = malloc_nofail(sizeof(struct dirent_sorted) + name_len + 1);
+ 1213 1142199 : name_len = strlen(dd->d_name);
+ 1214 1142199 : entry = malloc_nofail(sizeof(struct dirent_sorted) + name_len + 1);
1215 :
1216 : /* copy the dir entry */
1217 : #if HAVE_STRUCT_DIRENT_D_INO
- 1218 1142187 : entry->d_ino = dd->d_ino;
+ 1218 1142199 : entry->d_ino = dd->d_ino;
1219 : #endif
1220 : #if HAVE_STRUCT_DIRENT_D_TYPE
- 1221 1142187 : entry->d_type = dd->d_type;
+ 1221 1142199 : entry->d_type = dd->d_type;
1222 : #endif
1223 : #if HAVE_STRUCT_DIRENT_D_STAT
1224 : /* convert dirent to lstat result */
@@ -1288,24 +1288,24 @@
1226 :
1227 : /* note that at this point the st_mode may be 0 */
1228 : #endif
- 1229 1142187 : memcpy(entry->d_name, dd->d_name, name_len + 1);
+ 1229 1142199 : memcpy(entry->d_name, dd->d_name, name_len + 1);
1230 :
1231 : /* insert in the list */
- 1232 1142187 : tommy_list_insert_tail(&list, &entry->node, entry);
- 1233 1145867 : }
+ 1232 1142199 : tommy_list_insert_tail(&list, &entry->node, entry);
+ 1233 1145891 : }
1234 :
- 1235 1840 : if (closedir(d) != 0) {
+ 1235 1846 : if (closedir(d) != 0) {
1236 : /* LCOV_EXCL_START */
1237 : log_fatal("Error closing directory '%s'. %s.\n", dir, strerror(errno));
1238 : exit(EXIT_FAILURE);
1239 : /* LCOV_EXCL_STOP */
1240 : }
1241 :
- 1242 1840 : if (state->opt.force_order == SORT_ALPHA) {
+ 1242 1846 : if (state->opt.force_order == SORT_ALPHA) {
1243 : /* if requested sort alphabetically */
1244 : /* this is mainly done for testing to ensure to always */
1245 : /* process in the same way in different platforms */
- 1246 1804 : tommy_list_sort(&list, dd_name_compare);
+ 1246 1810 : tommy_list_sort(&list, dd_name_compare);
1247 : }
1248 : #if HAVE_STRUCT_DIRENT_D_INO
1249 36 : else if (!disk->has_volatile_inodes) {
@@ -1317,32 +1317,32 @@
1255 : #endif
1256 :
1257 : /* process the sorted dir entries */
- 1258 1840 : node = list;
- 1259 1145867 : while (node != 0) {
+ 1258 1846 : node = list;
+ 1259 1145891 : while (node != 0) {
1260 : char path_next[PATH_MAX];
1261 : char sub_next[PATH_MAX];
1262 : char out[PATH_MAX];
- 1263 1142187 : struct snapraid_filter* reason = 0;
- 1264 1142187 : struct dirent_sorted* dd = node->data;
- 1265 1142187 : const char* name = dd->d_name;
+ 1263 1142199 : struct snapraid_filter* reason = 0;
+ 1264 1142199 : struct dirent_sorted* dd = node->data;
+ 1265 1142199 : const char* name = dd->d_name;
1266 : struct stat* st;
1267 : int type;
1268 : #if !HAVE_STRUCT_DIRENT_D_STAT
1269 : struct stat st_buf;
1270 : #endif
1271 :
- 1272 1142187 : pathprint(path_next, sizeof(path_next), "%s%s", dir, name);
- 1273 1142187 : pathprint(sub_next, sizeof(sub_next), "%s%s", sub, name);
+ 1272 1142199 : pathprint(path_next, sizeof(path_next), "%s%s", dir, name);
+ 1273 1142199 : pathprint(sub_next, sizeof(sub_next), "%s%s", sub, name);
1274 :
1275 : /* start with an unknown type */
- 1276 1142187 : type = -1;
- 1277 1142187 : st = 0;
+ 1276 1142199 : type = -1;
+ 1277 1142199 : st = 0;
1278 :
1279 : /* if dirent has the type, use it */
1280 : #if HAVE_STRUCT_DIRENT_D_TYPE
- 1281 1142187 : switch (dd->d_type) {
+ 1281 1142199 : switch (dd->d_type) {
1282 0 : case DT_UNKNOWN : break;
- 1283 1104927 : case DT_REG : type = 0; break;
+ 1283 1104939 : case DT_REG : type = 0; break;
1284 35989 : case DT_LNK : type = 1; break;
1285 1271 : case DT_DIR : type = 2; break;
1286 0 : default : type = 3; break;
@@ -1350,7 +1350,7 @@
1288 : #endif
1289 :
1290 : /* if type is still unknown */
- 1291 1142187 : if (type < 0) {
+ 1291 1142199 : if (type < 0) {
1292 : /* get the type from stat */
1293 0 : st = DSTAT(path_next, dd, &st_buf);
1294 :
@@ -1380,12 +1380,12 @@
1318 0 : type = 3;
1319 : }
1320 :
- 1321 1142187 : if (type == 0) { /* REG */
- 1322 1104927 : if (filter_path(&state->filterlist, &reason, disk->name, sub_next) == 0) {
+ 1321 1142199 : if (type == 0) { /* REG */
+ 1322 1104939 : if (filter_path(&state->filterlist, &reason, disk->name, sub_next) == 0) {
1323 :
1324 : /* late stat, if not yet called */
- 1325 1104927 : if (!st)
- 1326 1104927 : st = DSTAT(path_next, dd, &st_buf);
+ 1325 1104939 : if (!st)
+ 1326 1104939 : st = DSTAT(path_next, dd, &st_buf);
1327 :
1328 : #if HAVE_LSTAT_SYNC
1329 : /* if the st_ino field is missing, takes care to fill it using the extended lstat() */
@@ -1400,8 +1400,8 @@
1338 : }
1339 : #endif
1340 :
- 1341 1104927 : scan_file(scan, is_diff, sub_next, st, FILEPHY_UNREAD_OFFSET);
- 1342 1104927 : processed = 1;
+ 1341 1104939 : scan_file(scan, is_diff, sub_next, st, FILEPHY_UNREAD_OFFSET);
+ 1342 1104939 : processed = 1;
1343 : } else {
1344 0 : msg_verbose("Excluding file '%s' for rule '%s'\n", path_next, filter_type(reason, out, sizeof(out)));
1345 : }
@@ -1478,16 +1478,16 @@
1416 : }
1417 :
1418 : /* next entry */
- 1419 1142187 : node = node->next;
+ 1419 1142199 : node = node->next;
1420 :
1421 : /* free the present one */
- 1422 1142187 : free(dd);
+ 1422 1142199 : free(dd);
1423 : }
1424 :
- 1425 1840 : return processed;
+ 1425 1846 : return processed;
1426 : }
1427 :
- 1428 95 : static int state_diffscan(struct snapraid_state* state, int is_diff)
+ 1428 96 : static int state_diffscan(struct snapraid_state* state, int is_diff)
1429 : {
1430 : tommy_node* i;
1431 : tommy_node* j;
@@ -1498,58 +1498,58 @@
1436 : int no_difference;
1437 : char esc_buffer[ESC_MAX];
1438 :
- 1439 95 : tommy_list_init(&scanlist);
+ 1439 96 : tommy_list_init(&scanlist);
1440 :
- 1441 95 : if (is_diff)
- 1442 7 : msg_progress("Comparing...\n");
+ 1441 96 : if (is_diff)
+ 1442 8 : msg_progress("Comparing...\n");
1443 :
1444 : /* first scan all the directory and find new and deleted files */
- 1445 664 : for (i = state->disklist; i != 0; i = i->next) {
- 1446 569 : struct snapraid_disk* disk = i->data;
+ 1445 671 : for (i = state->disklist; i != 0; i = i->next) {
+ 1446 575 : struct snapraid_disk* disk = i->data;
1447 : struct snapraid_scan* scan;
1448 : tommy_node* node;
1449 : int ret;
1450 : int has_persistent_inode;
1451 :
- 1452 569 : scan = malloc_nofail(sizeof(struct snapraid_scan));
- 1453 569 : scan->state = state;
- 1454 569 : scan->disk = disk;
- 1455 569 : scan->count_equal = 0;
- 1456 569 : scan->count_move = 0;
- 1457 569 : scan->count_copy = 0;
- 1458 569 : scan->count_restore = 0;
- 1459 569 : scan->count_change = 0;
- 1460 569 : scan->count_remove = 0;
- 1461 569 : scan->count_insert = 0;
- 1462 569 : tommy_list_init(&scan->file_insert_list);
- 1463 569 : tommy_list_init(&scan->link_insert_list);
- 1464 569 : tommy_list_init(&scan->dir_insert_list);
+ 1452 575 : scan = malloc_nofail(sizeof(struct snapraid_scan));
+ 1453 575 : scan->state = state;
+ 1454 575 : scan->disk = disk;
+ 1455 575 : scan->count_equal = 0;
+ 1456 575 : scan->count_move = 0;
+ 1457 575 : scan->count_copy = 0;
+ 1458 575 : scan->count_restore = 0;
+ 1459 575 : scan->count_change = 0;
+ 1460 575 : scan->count_remove = 0;
+ 1461 575 : scan->count_insert = 0;
+ 1462 575 : tommy_list_init(&scan->file_insert_list);
+ 1463 575 : tommy_list_init(&scan->link_insert_list);
+ 1464 575 : tommy_list_init(&scan->dir_insert_list);
1465 :
- 1466 569 : tommy_list_insert_tail(&scanlist, &scan->node, scan);
+ 1466 575 : tommy_list_insert_tail(&scanlist, &scan->node, scan);
1467 :
- 1468 569 : if (!is_diff)
+ 1468 575 : if (!is_diff)
1469 527 : msg_progress("Scanning disk %s...\n", disk->name);
1470 :
1471 : /* check if the disk supports persistent inodes */
- 1472 569 : ret = fsinfo(disk->dir, &has_persistent_inode, 0, 0);
- 1473 569 : if (ret < 0) {
+ 1472 575 : ret = fsinfo(disk->dir, &has_persistent_inode, 0, 0);
+ 1473 575 : if (ret < 0) {
1474 : /* LCOV_EXCL_START */
1475 : log_fatal("Error accessing disk '%s' to get file-system info. %s.\n", disk->dir, strerror(errno));
1476 : exit(EXIT_FAILURE);
1477 : /* LCOV_EXCL_STOP */
1478 : }
- 1479 569 : if (!has_persistent_inode) {
+ 1479 575 : if (!has_persistent_inode) {
1480 0 : disk->has_volatile_inodes = 1;
1481 : }
1482 :
1483 : /* if inodes or UUID are not persistent/changed/unsupported */
- 1484 569 : if (disk->has_volatile_inodes || disk->has_different_uuid || disk->has_unsupported_uuid) {
+ 1484 575 : if (disk->has_volatile_inodes || disk->has_different_uuid || disk->has_unsupported_uuid) {
1485 : /* remove all the inodes from the inode collection */
1486 : /* if they are not persistent, all of them could be changed now */
1487 : /* and we don't want to find false matching ones */
1488 : /* see scan_file() for more details */
- 1489 93 : node = disk->filelist;
- 1490 200 : while (node) {
+ 1489 94 : node = disk->filelist;
+ 1490 202 : while (node) {
1491 14 : struct snapraid_file* file = node->data;
1492 :
1493 14 : node = node->next;
@@ -1565,7 +1565,7 @@
1503 : }
1504 : }
1505 :
- 1506 569 : scan_dir(scan, 0, is_diff, disk->dir, "");
+ 1506 575 : scan_dir(scan, 0, is_diff, disk->dir, "");
1507 : }
1508 :
1509 : /* we split the search in two phases because to detect files */
@@ -1573,9 +1573,9 @@
1511 : /* only when all disks have all the new files found */
1512 :
1513 : /* now process all the new and deleted files */
- 1514 664 : for (i = scanlist; i != 0; i = i->next) {
- 1515 569 : struct snapraid_scan* scan = i->data;
- 1516 569 : struct snapraid_disk* disk = scan->disk;
+ 1514 671 : for (i = scanlist; i != 0; i = i->next) {
+ 1515 575 : struct snapraid_scan* scan = i->data;
+ 1516 575 : struct snapraid_disk* disk = scan->disk;
1517 : tommy_node* node;
1518 : unsigned phy_count;
1519 : unsigned phy_dup;
@@ -1583,15 +1583,15 @@
1521 : struct snapraid_file* phy_file_last;
1522 :
1523 : /* check for removed files */
- 1524 569 : node = disk->filelist;
- 1525 1033681 : while (node) {
- 1526 1032543 : struct snapraid_file* file = node->data;
+ 1524 575 : node = disk->filelist;
+ 1525 1033649 : while (node) {
+ 1526 1032499 : struct snapraid_file* file = node->data;
1527 :
1528 : /* next node */
- 1529 1032543 : node = node->next;
+ 1529 1032499 : node = node->next;
1530 :
1531 : /* remove if not present */
- 1532 1032543 : if (!file_flag_has(file, FILE_IS_PRESENT)) {
+ 1532 1032499 : if (!file_flag_has(file, FILE_IS_PRESENT)) {
1533 29647 : ++scan->count_remove;
1534 :
1535 29647 : log_tag("scan:remove:%s:%s\n", disk->name, esc_tag(file->sub, esc_buffer));
@@ -1604,8 +1604,8 @@
1542 : }
1543 :
1544 : /* check for removed links */
- 1545 569 : node = disk->linklist;
- 1546 35821 : while (node) {
+ 1545 575 : node = disk->linklist;
+ 1546 35833 : while (node) {
1547 34683 : struct snapraid_link* slink = node->data;
1548 :
1549 : /* next node */
@@ -1625,8 +1625,8 @@
1563 : }
1564 :
1565 : /* check for removed dirs */
- 1566 569 : node = disk->dirlist;
- 1567 1389 : while (node) {
+ 1566 575 : node = disk->dirlist;
+ 1567 1401 : while (node) {
1568 251 : struct snapraid_dir* dir = node->data;
1569 :
1570 : /* next node */
@@ -1641,7 +1641,7 @@
1579 : /* sort the files before inserting them */
1580 : /* we use a stable sort to ensure that if the reported physical offset/inode */
1581 : /* are always 0, we keep at least the directory order */
- 1582 569 : switch (state->opt.force_order) {
+ 1582 575 : switch (state->opt.force_order) {
1583 : case SORT_PHYSICAL :
1584 12 : tommy_list_sort(&scan->file_insert_list, file_physical_compare);
1585 12 : break;
@@ -1649,8 +1649,8 @@
1587 0 : tommy_list_sort(&scan->file_insert_list, file_inode_compare);
1588 0 : break;
1589 : case SORT_ALPHA :
- 1590 557 : tommy_list_sort(&scan->file_insert_list, file_path_compare);
- 1591 557 : break;
+ 1590 563 : tommy_list_sort(&scan->file_insert_list, file_path_compare);
+ 1591 563 : break;
1592 : case SORT_DIR :
1593 : /* already in order */
1594 0 : break;
@@ -1659,16 +1659,16 @@
1597 : /* insert all the new files, we insert them only after the deletion */
1598 : /* to reuse the just freed space */
1599 : /* also check if the physical offset reported are fakes or not */
- 1600 569 : node = scan->file_insert_list;
- 1601 569 : phy_count = 0;
- 1602 569 : phy_dup = 0;
- 1603 569 : phy_last = FILEPHY_UNREAD_OFFSET;
- 1604 569 : phy_file_last = 0;
- 1605 102974 : while (node) {
- 1606 101836 : struct snapraid_file* file = node->data;
+ 1600 575 : node = scan->file_insert_list;
+ 1601 575 : phy_count = 0;
+ 1602 575 : phy_dup = 0;
+ 1603 575 : phy_last = FILEPHY_UNREAD_OFFSET;
+ 1604 575 : phy_file_last = 0;
+ 1605 103042 : while (node) {
+ 1606 101892 : struct snapraid_file* file = node->data;
1607 :
1608 : /* if the file is not empty, count duplicate physical offsets */
- 1609 101836 : if (state->opt.force_order == SORT_PHYSICAL && file->size != 0) {
+ 1609 101892 : if (state->opt.force_order == SORT_PHYSICAL && file->size != 0) {
1610 11418 : if (phy_file_last != 0 && file->physical == phy_last
1611 : /* files without offset are expected to have duplicates */
1612 0 : && phy_last != FILEPHY_WITHOUT_OFFSET
@@ -1686,21 +1686,21 @@
1624 : }
1625 :
1626 : /* next node */
- 1627 101836 : node = node->next;
+ 1627 101892 : node = node->next;
1628 :
1629 : /* insert in the parity */
- 1630 101836 : scan_file_allocate(scan, file);
+ 1630 101892 : scan_file_allocate(scan, file);
1631 : }
1632 :
1633 : /* mark the disk without reliable physical offset if it has duplicates */
1634 : /* here it should never happen because we already sorted out hardlinks */
- 1635 569 : if (state->opt.force_order == SORT_PHYSICAL && phy_dup > 0) {
+ 1635 575 : if (state->opt.force_order == SORT_PHYSICAL && phy_dup > 0) {
1636 0 : disk->has_unreliable_physical = 1;
1637 : }
1638 :
1639 : /* insert all the new links */
- 1640 569 : node = scan->link_insert_list;
- 1641 3595 : while (node) {
+ 1640 575 : node = scan->link_insert_list;
+ 1641 3607 : while (node) {
1642 2457 : struct snapraid_link* slink = node->data;
1643 :
1644 : /* next node */
@@ -1711,8 +1711,8 @@
1649 : }
1650 :
1651 : /* insert all the new dirs */
- 1652 569 : node = scan->dir_insert_list;
- 1653 1148 : while (node) {
+ 1652 575 : node = scan->dir_insert_list;
+ 1653 1160 : while (node) {
1654 10 : struct snapraid_dir* dir = node->data;
1655 :
1656 : /* next node */
@@ -1724,18 +1724,18 @@
1662 : }
1663 :
1664 : /* check for disks where all the previously existing files where removed */
- 1665 95 : if (!state->opt.force_empty) {
- 1666 89 : int all_missing = 0;
- 1667 89 : int all_rewritten = 0;
- 1668 89 : done = 0;
- 1669 622 : for (i = state->disklist, j = scanlist; i != 0; i = i->next, j = j->next) {
- 1670 533 : struct snapraid_disk* disk = i->data;
- 1671 533 : struct snapraid_scan* scan = j->data;
+ 1665 96 : if (!state->opt.force_empty) {
+ 1666 90 : int all_missing = 0;
+ 1667 90 : int all_rewritten = 0;
+ 1668 90 : done = 0;
+ 1669 629 : for (i = state->disklist, j = scanlist; i != 0; i = i->next, j = j->next) {
+ 1670 539 : struct snapraid_disk* disk = i->data;
+ 1671 539 : struct snapraid_scan* scan = j->data;
1672 :
- 1673 533 : if (scan->count_equal == 0
- 1674 73 : && scan->count_move == 0
- 1675 73 : && scan->count_restore == 0
- 1676 73 : && (scan->count_remove != 0 || scan->count_change != 0)
+ 1673 539 : if (scan->count_equal == 0
+ 1674 74 : && scan->count_move == 0
+ 1675 74 : && scan->count_restore == 0
+ 1676 74 : && (scan->count_remove != 0 || scan->count_change != 0)
1677 : ) {
1678 1 : if (!done) {
1679 1 : done = 1;
@@ -1753,7 +1753,7 @@
1691 0 : all_rewritten = 1;
1692 : }
1693 : }
- 1694 89 : if (done) {
+ 1694 90 : if (done) {
1695 1 : log_fatal("\nare now missing or rewritten!\n");
1696 1 : if (all_rewritten) {
1697 0 : log_fatal("This could happen when restoring a disk with a backup\n");
@@ -1771,7 +1771,7 @@
1709 : }
1710 :
1711 : /* check for disks without the physical offset support */
- 1712 94 : if (state->opt.force_order == SORT_PHYSICAL) {
+ 1712 95 : if (state->opt.force_order == SORT_PHYSICAL) {
1713 2 : done = 0;
1714 14 : for (i = state->disklist; i != 0; i = i->next) {
1715 12 : struct snapraid_disk* disk = i->data;
@@ -1791,11 +1791,11 @@
1729 : }
1730 :
1731 : /* check for disks without persistent inodes */
- 1732 94 : done = 0;
- 1733 657 : for (i = state->disklist; i != 0; i = i->next) {
- 1734 563 : struct snapraid_disk* disk = i->data;
+ 1732 95 : done = 0;
+ 1733 664 : for (i = state->disklist; i != 0; i = i->next) {
+ 1734 569 : struct snapraid_disk* disk = i->data;
1735 :
- 1736 563 : if (disk->has_volatile_inodes) {
+ 1736 569 : if (disk->has_volatile_inodes) {
1737 0 : if (!done) {
1738 0 : done = 1;
1739 0 : log_fatal("WARNING! Inodes are not persistent for disks: '%s'", disk->name);
@@ -1804,20 +1804,20 @@
1742 : }
1743 : }
1744 : }
- 1745 94 : if (done) {
+ 1745 95 : if (done) {
1746 0 : log_fatal(". Move operations won't be optimal.\n");
1747 : }
1748 :
1749 : /* check for disks with changed UUID */
- 1750 94 : done = 0;
- 1751 657 : for (i = state->disklist; i != 0; i = i->next) {
- 1752 563 : struct snapraid_disk* disk = i->data;
+ 1750 95 : done = 0;
+ 1751 664 : for (i = state->disklist; i != 0; i = i->next) {
+ 1752 569 : struct snapraid_disk* disk = i->data;
1753 :
1754 : /* don't print the message if the UUID changed because before */
1755 : /* it was no set. */
1756 : /* this is the normal condition for an empty disk because it */
1757 : /* isn't stored */
- 1758 563 : if (disk->has_different_uuid && !disk->had_empty_uuid) {
+ 1758 569 : if (disk->has_different_uuid && !disk->had_empty_uuid) {
1759 4 : if (!done) {
1760 2 : done = 1;
1761 2 : log_fatal("WARNING! UUID is changed for disks: '%s'", disk->name);
@@ -1826,16 +1826,16 @@
1764 : }
1765 : }
1766 : }
- 1767 94 : if (done) {
+ 1767 95 : if (done) {
1768 2 : log_fatal(". Move operations won't be optimal.\n");
1769 : }
1770 :
1771 : /* check for disks with unsupported UUID */
- 1772 94 : done = 0;
- 1773 657 : for (i = state->disklist; i != 0; i = i->next) {
- 1774 563 : struct snapraid_disk* disk = i->data;
+ 1772 95 : done = 0;
+ 1773 664 : for (i = state->disklist; i != 0; i = i->next) {
+ 1774 569 : struct snapraid_disk* disk = i->data;
1775 :
- 1776 563 : if (disk->has_unsupported_uuid) {
+ 1776 569 : if (disk->has_unsupported_uuid) {
1777 0 : if (!done) {
1778 0 : done = 1;
1779 0 : log_fatal("WARNING! UUID is unsupported for disks: '%s'", disk->name);
@@ -1844,7 +1844,7 @@
1782 : }
1783 : }
1784 : }
- 1785 94 : if (done) {
+ 1785 95 : if (done) {
1786 0 : log_fatal(". Move operations won't be optimal.\n");
1787 : #if defined(_linux) && !HAVE_BLKID
1788 : log_fatal("The 'blkid' library is not linked in SnapRAID!\n");
@@ -1852,87 +1852,87 @@
1790 : #endif
1791 : }
1792 :
- 1793 94 : total.count_equal = 0;
- 1794 94 : total.count_move = 0;
- 1795 94 : total.count_copy = 0;
- 1796 94 : total.count_restore = 0;
- 1797 94 : total.count_change = 0;
- 1798 94 : total.count_remove = 0;
- 1799 94 : total.count_insert = 0;
+ 1793 95 : total.count_equal = 0;
+ 1794 95 : total.count_move = 0;
+ 1795 95 : total.count_copy = 0;
+ 1796 95 : total.count_restore = 0;
+ 1797 95 : total.count_change = 0;
+ 1798 95 : total.count_remove = 0;
+ 1799 95 : total.count_insert = 0;
1800 :
- 1801 657 : for (i = scanlist; i != 0; i = i->next) {
- 1802 563 : struct snapraid_scan* scan = i->data;
- 1803 563 : total.count_equal += scan->count_equal;
- 1804 563 : total.count_move += scan->count_move;
- 1805 563 : total.count_copy += scan->count_copy;
- 1806 563 : total.count_restore += scan->count_restore;
- 1807 563 : total.count_change += scan->count_change;
- 1808 563 : total.count_remove += scan->count_remove;
- 1809 563 : total.count_insert += scan->count_insert;
+ 1801 664 : for (i = scanlist; i != 0; i = i->next) {
+ 1802 569 : struct snapraid_scan* scan = i->data;
+ 1803 569 : total.count_equal += scan->count_equal;
+ 1804 569 : total.count_move += scan->count_move;
+ 1805 569 : total.count_copy += scan->count_copy;
+ 1806 569 : total.count_restore += scan->count_restore;
+ 1807 569 : total.count_change += scan->count_change;
+ 1808 569 : total.count_remove += scan->count_remove;
+ 1809 569 : total.count_insert += scan->count_insert;
1810 : }
1811 :
- 1812 94 : if (is_diff) {
- 1813 7 : msg_status("\n");
- 1814 7 : msg = msg_status;
+ 1812 95 : if (is_diff) {
+ 1813 8 : msg_status("\n");
+ 1814 8 : msg = msg_status;
1815 : } else {
1816 87 : msg = msg_verbose;
1817 : }
1818 :
- 1819 94 : msg("%8u equal\n", total.count_equal);
- 1820 94 : msg("%8u added\n", total.count_insert);
- 1821 94 : msg("%8u removed\n", total.count_remove);
- 1822 94 : msg("%8u updated\n", total.count_change);
- 1823 94 : msg("%8u moved\n", total.count_move);
- 1824 94 : msg("%8u copied\n", total.count_copy);
- 1825 94 : msg("%8u restored\n", total.count_restore);
+ 1819 95 : msg("%8u equal\n", total.count_equal);
+ 1820 95 : msg("%8u added\n", total.count_insert);
+ 1821 95 : msg("%8u removed\n", total.count_remove);
+ 1822 95 : msg("%8u updated\n", total.count_change);
+ 1823 95 : msg("%8u moved\n", total.count_move);
+ 1824 95 : msg("%8u copied\n", total.count_copy);
+ 1825 95 : msg("%8u restored\n", total.count_restore);
1826 :
- 1827 94 : log_tag("summary:equal:%u\n", total.count_equal);
- 1828 94 : log_tag("summary:added:%u\n", total.count_insert);
- 1829 94 : log_tag("summary:removed:%u\n", total.count_remove);
- 1830 94 : log_tag("summary:updated:%u\n", total.count_change);
- 1831 94 : log_tag("summary:moved:%u\n", total.count_move);
- 1832 94 : log_tag("summary:copied:%u\n", total.count_copy);
- 1833 94 : log_tag("summary:restored:%u\n", total.count_restore);
+ 1827 95 : log_tag("summary:equal:%u\n", total.count_equal);
+ 1828 95 : log_tag("summary:added:%u\n", total.count_insert);
+ 1829 95 : log_tag("summary:removed:%u\n", total.count_remove);
+ 1830 95 : log_tag("summary:updated:%u\n", total.count_change);
+ 1831 95 : log_tag("summary:moved:%u\n", total.count_move);
+ 1832 95 : log_tag("summary:copied:%u\n", total.count_copy);
+ 1833 95 : log_tag("summary:restored:%u\n", total.count_restore);
1834 :
- 1835 281 : no_difference = !total.count_move && !total.count_copy && !total.count_restore
- 1836 157 : && !total.count_change && !total.count_remove && !total.count_insert;
+ 1835 284 : no_difference = !total.count_move && !total.count_copy && !total.count_restore
+ 1836 159 : && !total.count_change && !total.count_remove && !total.count_insert;
1837 :
- 1838 94 : if (is_diff) {
- 1839 7 : if (no_difference) {
- 1840 1 : msg_status("No differences\n");
+ 1838 95 : if (is_diff) {
+ 1839 8 : if (no_difference) {
+ 1840 2 : msg_status("No differences\n");
1841 : } else {
1842 6 : msg_status("There are differences!\n");
1843 : }
1844 : }
1845 :
- 1846 94 : if (no_difference) {
- 1847 19 : log_tag("summary:exit:equal\n");
+ 1846 95 : if (no_difference) {
+ 1847 20 : log_tag("summary:exit:equal\n");
1848 : } else {
1849 75 : log_tag("summary:exit:diff\n");
1850 : }
- 1851 94 : log_flush();
+ 1851 95 : log_flush();
1852 :
- 1853 94 : tommy_list_foreach(&scanlist, (tommy_foreach_func*)free);
+ 1853 95 : tommy_list_foreach(&scanlist, (tommy_foreach_func*)free);
1854 :
1855 : /* check the file-system on all disks */
- 1856 94 : state_fscheck(state, "after scan");
+ 1856 95 : state_fscheck(state, "after scan");
1857 :
- 1858 94 : if (is_diff) {
+ 1858 95 : if (is_diff) {
1859 : /* check for file difference */
- 1860 7 : if (!no_difference)
+ 1860 8 : if (!no_difference)
1861 6 : return 1;
1862 :
1863 : /* check also for incomplete "sync" */
- 1864 1 : if (parity_is_invalid(state))
- 1865 0 : return 1;
+ 1864 2 : if (parity_is_invalid(state))
+ 1865 1 : return 1;
1866 : }
1867 :
1868 88 : return 0;
1869 : }
1870 :
- 1871 7 : int state_diff(struct snapraid_state* state)
+ 1871 8 : int state_diff(struct snapraid_state* state)
1872 : {
- 1873 7 : return state_diffscan(state, 1);
+ 1873 8 : return state_diffscan(state, 1);
1874 : }
1875 :
1876 88 : void state_scan(struct snapraid_state* state)
diff --git a/cov/cmdline/scrub.c.func-sort-c.html b/cov/cmdline/scrub.c.func-sort-c.html
index 30aeecf9..b33d4412 100644
--- a/cov/cmdline/scrub.c.func-sort-c.html
+++ b/cov/cmdline/scrub.c.func-sort-c.html
@@ -32,8 +32,8 @@
|
-
-
+
+
@@ -61,11 +61,11 @@
| scrub_parity_reader |
- 168183 |
+ 168187 |
| scrub_data_reader |
- 168180 |
+ 168181 |
| block_is_enabled |
@@ -76,11 +76,11 @@
11 |
- | state_scrub |
+ state_scrub |
11 |
- | md |
+ md |
2 |
diff --git a/cov/cmdline/scrub.c.func.html b/cov/cmdline/scrub.c.func.html
index 3d33634a..1095dd1c 100644
--- a/cov/cmdline/scrub.c.func.html
+++ b/cov/cmdline/scrub.c.func.html
@@ -32,8 +32,8 @@
|
-
-
+
+
@@ -64,19 +64,19 @@
| 112170 |
- | md |
+ md |
2 |
| scrub_data_reader |
- 168180 |
+ 168181 |
| scrub_parity_reader |
- 168183 |
+ 168187 |
- | state_scrub |
+ state_scrub |
11 |
diff --git a/cov/cmdline/scrub.c.gcov.html b/cov/cmdline/scrub.c.gcov.html
index e2b44b96..7e95cfe0 100644
--- a/cov/cmdline/scrub.c.gcov.html
+++ b/cov/cmdline/scrub.c.gcov.html
@@ -32,8 +32,8 @@
|
-
-
+
+
@@ -146,16 +146,16 @@
84 56244 : blocktime = info_get_time(info);
85 56244 : if (blocktime > plan->timelimit) {
86 : /* skip it */
- 87 9582 : return 0;
+ 87 9574 : return 0;
88 : }
89 :
90 : /* if the time is less than the limit, always include */
91 : /* otherwise, check if we reached the last limit count */
- 92 46662 : if (blocktime == plan->timelimit) {
+ 92 46670 : if (blocktime == plan->timelimit) {
93 : /* if we reached the count limit */
- 94 30124 : if (plan->countlast >= plan->lastlimit) {
+ 94 30132 : if (plan->countlast >= plan->lastlimit) {
95 : /* skip it */
- 96 24932 : return 0;
+ 96 24940 : return 0;
97 : }
98 :
99 5192 : ++plan->countlast;
@@ -164,19 +164,19 @@
102 21730 : return 1;
103 : }
104 :
- 105 168180 : static void scrub_data_reader(struct snapraid_worker* worker, struct snapraid_task* task)
+ 105 168181 : static void scrub_data_reader(struct snapraid_worker* worker, struct snapraid_task* task)
106 : {
- 107 168180 : struct snapraid_io* io = worker->io;
- 108 168180 : struct snapraid_state* state = io->state;
- 109 168180 : struct snapraid_handle* handle = worker->handle;
- 110 168180 : struct snapraid_disk* disk = handle->disk;
- 111 168180 : block_off_t blockcur = task->position;
- 112 168180 : unsigned char* buffer = task->buffer;
+ 107 168181 : struct snapraid_io* io = worker->io;
+ 108 168181 : struct snapraid_state* state = io->state;
+ 109 168181 : struct snapraid_handle* handle = worker->handle;
+ 110 168181 : struct snapraid_disk* disk = handle->disk;
+ 111 168181 : block_off_t blockcur = task->position;
+ 112 168181 : unsigned char* buffer = task->buffer;
113 : int ret;
114 : char esc_buffer[ESC_MAX];
115 :
116 : /* if the disk position is not used */
- 117 168180 : if (!disk) {
+ 117 168181 : if (!disk) {
118 : /* use an empty block */
119 0 : memset(buffer, 0, state->block_size);
120 0 : task->state = TASK_STATE_DONE;
@@ -184,10 +184,10 @@
122 : }
123 :
124 : /* get the block */
- 125 168180 : task->block = fs_par2block_find(disk, blockcur);
+ 125 168181 : task->block = fs_par2block_find(disk, blockcur);
126 :
127 : /* if the block is not used */
- 128 168136 : if (!block_has_file(task->block)) {
+ 128 168157 : if (!block_has_file(task->block)) {
129 : /* use an empty block */
130 1585 : memset(buffer, 0, state->block_size);
131 1585 : task->state = TASK_STATE_DONE;
@@ -195,14 +195,14 @@
133 : }
134 :
135 : /* get the file of this block */
- 136 166540 : task->file = fs_par2file_get(disk, blockcur, &task->file_pos);
+ 136 166558 : task->file = fs_par2file_get(disk, blockcur, &task->file_pos);
137 :
138 : /* if the file is different than the current one, close it */
- 139 166578 : if (handle->file != 0 && handle->file != task->file) {
+ 139 166581 : if (handle->file != 0 && handle->file != task->file) {
140 : /* keep a pointer at the file we are going to close for error reporting */
- 141 78089 : struct snapraid_file* report = handle->file;
- 142 78089 : ret = handle_close(handle);
- 143 78065 : if (ret == -1) {
+ 141 78085 : struct snapraid_file* report = handle->file;
+ 142 78085 : ret = handle_close(handle);
+ 143 78044 : if (ret == -1) {
144 : /* LCOV_EXCL_START */
145 : /* This one is really an unexpected error, because we are only reading */
146 : /* and closing a descriptor should never fail */
@@ -225,8 +225,8 @@
163 : }
164 : }
165 :
- 166 166554 : ret = handle_open(handle, task->file, state->file_mode, log_error, 0);
- 167 166583 : if (ret == -1) {
+ 166 166540 : ret = handle_open(handle, task->file, state->file_mode, log_error, 0);
+ 167 166589 : if (ret == -1) {
168 0 : if (errno == EIO) {
169 : /* LCOV_EXCL_START */
170 : log_tag("error:%u:%s:%s: Open EIO error. %s\n", blockcur, disk->name, esc_tag(task->file->sub, esc_buffer), strerror(errno));
@@ -244,9 +244,9 @@
182 : }
183 :
184 : /* check if the file is changed */
- 185 166583 : if (handle->st.st_size != task->file->size
- 186 166586 : || handle->st.st_mtime != task->file->mtime_sec
- 187 160991 : || STAT_NSEC(&handle->st) != task->file->mtime_nsec
+ 185 166589 : if (handle->st.st_size != task->file->size
+ 186 166587 : || handle->st.st_mtime != task->file->mtime_sec
+ 187 160995 : || STAT_NSEC(&handle->st) != task->file->mtime_nsec
188 : /* don't check the inode to support filesystem without persistent inodes */
189 : ) {
190 : /* report that the block and the file are not synced */
@@ -258,8 +258,8 @@
196 : /* from the last sync, as we are expected to return errors if running */
197 : /* in an unsynced array. This is just like the check command. */
198 :
- 199 166583 : task->read_size = handle_read(handle, task->file_pos, buffer, state->block_size, log_error, 0);
- 200 166516 : if (task->read_size == -1) {
+ 199 166589 : task->read_size = handle_read(handle, task->file_pos, buffer, state->block_size, log_error, 0);
+ 200 166506 : if (task->read_size == -1) {
201 0 : if (errno == EIO) {
202 0 : log_tag("error:%u:%s:%s: Read EIO error at position %u. %s\n", blockcur, disk->name, esc_tag(task->file->sub, esc_buffer), task->file_pos, strerror(errno));
203 0 : log_error("Input/Output error in file '%s' at position '%u'\n", handle->path, task->file_pos);
@@ -273,24 +273,24 @@
211 : }
212 :
213 : /* store the path of the opened file */
- 214 166516 : pathcpy(task->path, sizeof(task->path), handle->path);
+ 214 166506 : pathcpy(task->path, sizeof(task->path), handle->path);
215 :
- 216 166573 : task->state = TASK_STATE_DONE;
+ 216 166569 : task->state = TASK_STATE_DONE;
217 : }
218 :
- 219 168183 : static void scrub_parity_reader(struct snapraid_worker* worker, struct snapraid_task* task)
+ 219 168187 : static void scrub_parity_reader(struct snapraid_worker* worker, struct snapraid_task* task)
220 : {
- 221 168183 : struct snapraid_io* io = worker->io;
- 222 168183 : struct snapraid_state* state = io->state;
- 223 168183 : struct snapraid_parity_handle* parity_handle = worker->parity_handle;
- 224 168183 : unsigned level = parity_handle->level;
- 225 168183 : block_off_t blockcur = task->position;
- 226 168183 : unsigned char* buffer = task->buffer;
+ 221 168187 : struct snapraid_io* io = worker->io;
+ 222 168187 : struct snapraid_state* state = io->state;
+ 223 168187 : struct snapraid_parity_handle* parity_handle = worker->parity_handle;
+ 224 168187 : unsigned level = parity_handle->level;
+ 225 168187 : block_off_t blockcur = task->position;
+ 226 168187 : unsigned char* buffer = task->buffer;
227 : int ret;
228 :
229 : /* read the parity */
- 230 168183 : ret = parity_read(parity_handle, blockcur, buffer, state->block_size, log_error);
- 231 167659 : if (ret == -1) {
+ 230 168187 : ret = parity_read(parity_handle, blockcur, buffer, state->block_size, log_error);
+ 231 168166 : if (ret == -1) {
232 0 : if (errno == EIO) {
233 0 : log_tag("parity_error:%u:%s: Read EIO error. %s\n", blockcur, lev_config_name(level), strerror(errno));
234 0 : log_error("Input/Output error in parity '%s' at position '%u'\n", lev_config_name(level), blockcur);
@@ -303,7 +303,7 @@
241 0 : return;
242 : }
243 :
- 244 167659 : task->state = TASK_STATE_DONE;
+ 244 168166 : task->state = TASK_STATE_DONE;
245 : }
246 :
247 11 : static int state_scrub_process(struct snapraid_state* state, struct snapraid_parity_handle* parity_handle, block_off_t blockstart, block_off_t blockmax, struct snapraid_plan* plan, time_t now)
@@ -476,482 +476,490 @@
414 :
415 : /* handle error conditions */
416 166607 : if (task->state == TASK_STATE_IOERROR) {
- 417 0 : ++io_error;
- 418 0 : goto bail;
- 419 : }
- 420 166607 : if (task->state == TASK_STATE_ERROR) {
- 421 0 : ++error;
- 422 0 : goto bail;
- 423 : }
- 424 166607 : if (task->state == TASK_STATE_ERROR_CONTINUE) {
- 425 0 : ++error;
- 426 0 : error_on_this_block = 1;
- 427 0 : continue;
- 428 : }
- 429 166607 : if (task->state == TASK_STATE_IOERROR_CONTINUE) {
- 430 0 : ++io_error;
- 431 0 : if (io_error >= state->opt.io_error_limit) {
- 432 : /* LCOV_EXCL_START */
- 433 : log_fatal("DANGER! Too many input/output read error in a data disk, it isn't possible to scrub.\n");
- 434 : log_fatal("Ensure that disk '%s' is sane and that file '%s' can be accessed.\n", disk->dir, task->path);
- 435 : log_fatal("Stopping at block %u\n", blockcur);
- 436 : goto bail;
- 437 : /* LCOV_EXCL_STOP */
- 438 : }
- 439 :
- 440 : /* otherwise continue */
- 441 0 : io_error_on_this_block = 1;
- 442 0 : continue;
- 443 : }
- 444 166607 : if (task->state != TASK_STATE_DONE) {
- 445 : /* LCOV_EXCL_START */
- 446 : log_fatal("Internal inconsistency in task state\n");
- 447 : os_abort();
- 448 : /* LCOV_EXCL_STOP */
- 449 : }
- 450 :
- 451 166607 : countsize += read_size;
- 452 :
- 453 : /* now compute the hash */
- 454 166607 : if (rehash) {
- 455 27247 : memhash(state->prevhash, state->prevhashseed, hash, buffer[diskcur], read_size);
+ 417 : /* LCOV_EXCL_START */
+ 418 : ++io_error;
+ 419 : goto bail;
+ 420 : /* LCOV_EXCL_STOP */
+ 421 : }
+ 422 166607 : if (task->state == TASK_STATE_ERROR) {
+ 423 : /* LCOV_EXCL_START */
+ 424 : ++error;
+ 425 : goto bail;
+ 426 : /* LCOV_EXCL_STOP */
+ 427 : }
+ 428 166607 : if (task->state == TASK_STATE_ERROR_CONTINUE) {
+ 429 0 : ++error;
+ 430 0 : error_on_this_block = 1;
+ 431 0 : continue;
+ 432 : }
+ 433 166607 : if (task->state == TASK_STATE_IOERROR_CONTINUE) {
+ 434 0 : ++io_error;
+ 435 0 : if (io_error >= state->opt.io_error_limit) {
+ 436 : /* LCOV_EXCL_START */
+ 437 : log_fatal("DANGER! Too many input/output read error in a data disk, it isn't possible to scrub.\n");
+ 438 : log_fatal("Ensure that disk '%s' is sane and that file '%s' can be accessed.\n", disk->dir, task->path);
+ 439 : log_fatal("Stopping at block %u\n", blockcur);
+ 440 : goto bail;
+ 441 : /* LCOV_EXCL_STOP */
+ 442 : }
+ 443 :
+ 444 : /* otherwise continue */
+ 445 0 : io_error_on_this_block = 1;
+ 446 0 : continue;
+ 447 : }
+ 448 166607 : if (task->state != TASK_STATE_DONE) {
+ 449 : /* LCOV_EXCL_START */
+ 450 : log_fatal("Internal inconsistency in task state\n");
+ 451 : os_abort();
+ 452 : /* LCOV_EXCL_STOP */
+ 453 : }
+ 454 :
+ 455 166607 : countsize += read_size;
456 :
- 457 : /* compute the new hash, and store it */
- 458 27247 : rehandle[diskcur].block = block;
- 459 27247 : memhash(state->hash, state->hashseed, rehandle[diskcur].hash, buffer[diskcur], read_size);
- 460 : } else {
- 461 139360 : memhash(state->hash, state->hashseed, hash, buffer[diskcur], read_size);
- 462 : }
- 463 :
- 464 : /* until now is hash */
- 465 166607 : state_usage_hash(state);
- 466 :
- 467 166607 : if (block_has_updated_hash(block)) {
- 468 : /* compare the hash */
- 469 166607 : if (memcmp(hash, block->hash, BLOCK_HASH_SIZE) != 0) {
- 470 920 : unsigned diff = memdiff(hash, block->hash, BLOCK_HASH_SIZE);
- 471 :
- 472 920 : log_tag("error:%u:%s:%s: Data error at position %u, diff bits %u\n", blockcur, disk->name, esc_tag(file->sub, esc_buffer), file_pos, diff);
- 473 :
- 474 : /* it's a silent error only if we are dealing with synced files */
- 475 920 : if (file_is_unsynced) {
- 476 0 : ++error;
- 477 0 : error_on_this_block = 1;
- 478 : } else {
- 479 920 : log_error("Data error in file '%s' at position '%u', diff bits %u\n", task->path, file_pos, diff);
- 480 920 : ++silent_error;
- 481 920 : silent_error_on_this_block = 1;
- 482 : }
- 483 920 : continue;
- 484 : }
- 485 : }
- 486 : }
- 487 :
- 488 : /* buffers for parity read and not computed */
- 489 196224 : for (l = 0; l < state->level; ++l)
- 490 168192 : buffer_recov[l] = buffer[diskmax + state->level + l];
- 491 28032 : for (; l < LEV_MAX; ++l)
- 492 0 : buffer_recov[l] = 0;
- 493 :
- 494 : /* until now is misc */
- 495 28032 : state_usage_misc(state);
- 496 :
- 497 : /* read the parity */
- 498 196224 : for (l = 0; l < state->level; ++l) {
- 499 : struct snapraid_task* task;
- 500 : unsigned levcur;
- 501 :
- 502 168192 : task = io_parity_read(&io, &levcur, waiting_map, &waiting_mac);
- 503 :
- 504 : /* until now is parity */
- 505 168192 : state_usage_parity(state, waiting_map, waiting_mac);
- 506 :
- 507 : /* handle error conditions */
- 508 168192 : if (task->state == TASK_STATE_IOERROR) {
- 509 0 : ++io_error;
- 510 0 : goto bail;
- 511 : }
- 512 168192 : if (task->state == TASK_STATE_ERROR) {
- 513 0 : ++error;
- 514 0 : goto bail;
- 515 : }
- 516 168192 : if (task->state == TASK_STATE_ERROR_CONTINUE) {
- 517 0 : ++error;
- 518 0 : error_on_this_block = 1;
- 519 :
- 520 : /* if continuing on error, clear the missing buffer */
- 521 0 : buffer_recov[levcur] = 0;
- 522 0 : continue;
+ 457 : /* now compute the hash */
+ 458 166607 : if (rehash) {
+ 459 27247 : memhash(state->prevhash, state->prevhashseed, hash, buffer[diskcur], read_size);
+ 460 :
+ 461 : /* compute the new hash, and store it */
+ 462 27247 : rehandle[diskcur].block = block;
+ 463 27247 : memhash(state->hash, state->hashseed, rehandle[diskcur].hash, buffer[diskcur], read_size);
+ 464 : } else {
+ 465 139360 : memhash(state->hash, state->hashseed, hash, buffer[diskcur], read_size);
+ 466 : }
+ 467 :
+ 468 : /* until now is hash */
+ 469 166607 : state_usage_hash(state);
+ 470 :
+ 471 166607 : if (block_has_updated_hash(block)) {
+ 472 : /* compare the hash */
+ 473 166607 : if (memcmp(hash, block->hash, BLOCK_HASH_SIZE) != 0) {
+ 474 920 : unsigned diff = memdiff(hash, block->hash, BLOCK_HASH_SIZE);
+ 475 :
+ 476 920 : log_tag("error:%u:%s:%s: Data error at position %u, diff bits %u\n", blockcur, disk->name, esc_tag(file->sub, esc_buffer), file_pos, diff);
+ 477 :
+ 478 : /* it's a silent error only if we are dealing with synced files */
+ 479 920 : if (file_is_unsynced) {
+ 480 0 : ++error;
+ 481 0 : error_on_this_block = 1;
+ 482 : } else {
+ 483 920 : log_error("Data error in file '%s' at position '%u', diff bits %u\n", task->path, file_pos, diff);
+ 484 920 : ++silent_error;
+ 485 920 : silent_error_on_this_block = 1;
+ 486 : }
+ 487 920 : continue;
+ 488 : }
+ 489 : }
+ 490 : }
+ 491 :
+ 492 : /* buffers for parity read and not computed */
+ 493 196224 : for (l = 0; l < state->level; ++l)
+ 494 168192 : buffer_recov[l] = buffer[diskmax + state->level + l];
+ 495 28032 : for (; l < LEV_MAX; ++l)
+ 496 0 : buffer_recov[l] = 0;
+ 497 :
+ 498 : /* until now is misc */
+ 499 28032 : state_usage_misc(state);
+ 500 :
+ 501 : /* read the parity */
+ 502 196224 : for (l = 0; l < state->level; ++l) {
+ 503 : struct snapraid_task* task;
+ 504 : unsigned levcur;
+ 505 :
+ 506 168192 : task = io_parity_read(&io, &levcur, waiting_map, &waiting_mac);
+ 507 :
+ 508 : /* until now is parity */
+ 509 168192 : state_usage_parity(state, waiting_map, waiting_mac);
+ 510 :
+ 511 : /* handle error conditions */
+ 512 168192 : if (task->state == TASK_STATE_IOERROR) {
+ 513 : /* LCOV_EXCL_START */
+ 514 : ++io_error;
+ 515 : goto bail;
+ 516 : /* LCOV_EXCL_STOP */
+ 517 : }
+ 518 168192 : if (task->state == TASK_STATE_ERROR) {
+ 519 : /* LCOV_EXCL_START */
+ 520 : ++error;
+ 521 : goto bail;
+ 522 : /* LCOV_EXCL_STOP */
523 : }
- 524 168192 : if (task->state == TASK_STATE_IOERROR_CONTINUE) {
- 525 0 : ++io_error;
- 526 0 : if (io_error >= state->opt.io_error_limit) {
- 527 : /* LCOV_EXCL_START */
- 528 : log_fatal("DANGER! Too many input/output read error in the %s disk, it isn't possible to scrub.\n", lev_name(levcur));
- 529 : log_fatal("Ensure that disk '%s' is sane and can be read.\n", lev_config_name(levcur));
- 530 : log_fatal("Stopping at block %u\n", blockcur);
- 531 : goto bail;
- 532 : /* LCOV_EXCL_STOP */
- 533 : }
- 534 :
- 535 : /* otherwise continue */
- 536 0 : io_error_on_this_block = 1;
- 537 :
- 538 : /* if continuing on error, clear the missing buffer */
- 539 0 : buffer_recov[levcur] = 0;
- 540 0 : continue;
- 541 : }
- 542 168192 : if (task->state != TASK_STATE_DONE) {
- 543 : /* LCOV_EXCL_START */
- 544 : log_fatal("Internal inconsistency in task state\n");
- 545 : os_abort();
- 546 : /* LCOV_EXCL_STOP */
- 547 : }
- 548 : }
- 549 :
- 550 : /* if we have read all the data required and it's correct, proceed with the parity check */
- 551 28032 : if (!error_on_this_block && !silent_error_on_this_block && !io_error_on_this_block) {
- 552 :
- 553 : /* compute the parity */
- 554 27112 : raid_gen(diskmax, state->level, state->block_size, buffer);
- 555 :
- 556 : /* compare the parity */
- 557 189784 : for (l = 0; l < state->level; ++l) {
- 558 162672 : if (buffer_recov[l] && memcmp(buffer[diskmax + l], buffer_recov[l], state->block_size) != 0) {
- 559 0 : unsigned diff = memdiff(buffer[diskmax + l], buffer_recov[l], state->block_size);
+ 524 168192 : if (task->state == TASK_STATE_ERROR_CONTINUE) {
+ 525 0 : ++error;
+ 526 0 : error_on_this_block = 1;
+ 527 :
+ 528 : /* if continuing on error, clear the missing buffer */
+ 529 0 : buffer_recov[levcur] = 0;
+ 530 0 : continue;
+ 531 : }
+ 532 168192 : if (task->state == TASK_STATE_IOERROR_CONTINUE) {
+ 533 0 : ++io_error;
+ 534 0 : if (io_error >= state->opt.io_error_limit) {
+ 535 : /* LCOV_EXCL_START */
+ 536 : log_fatal("DANGER! Too many input/output read error in the %s disk, it isn't possible to scrub.\n", lev_name(levcur));
+ 537 : log_fatal("Ensure that disk '%s' is sane and can be read.\n", lev_config_name(levcur));
+ 538 : log_fatal("Stopping at block %u\n", blockcur);
+ 539 : goto bail;
+ 540 : /* LCOV_EXCL_STOP */
+ 541 : }
+ 542 :
+ 543 : /* otherwise continue */
+ 544 0 : io_error_on_this_block = 1;
+ 545 :
+ 546 : /* if continuing on error, clear the missing buffer */
+ 547 0 : buffer_recov[levcur] = 0;
+ 548 0 : continue;
+ 549 : }
+ 550 168192 : if (task->state != TASK_STATE_DONE) {
+ 551 : /* LCOV_EXCL_START */
+ 552 : log_fatal("Internal inconsistency in task state\n");
+ 553 : os_abort();
+ 554 : /* LCOV_EXCL_STOP */
+ 555 : }
+ 556 : }
+ 557 :
+ 558 : /* if we have read all the data required and it's correct, proceed with the parity check */
+ 559 28032 : if (!error_on_this_block && !silent_error_on_this_block && !io_error_on_this_block) {
560 :
- 561 0 : log_tag("parity_error:%u:%s: Data error, diff bits %u\n", blockcur, lev_config_name(l), diff);
- 562 :
- 563 : /* it's a silent error only if we are dealing with synced blocks */
- 564 0 : if (block_is_unsynced) {
- 565 0 : ++error;
- 566 0 : error_on_this_block = 1;
- 567 : } else {
- 568 0 : log_fatal("Data error in parity '%s' at position '%u', diff bits %u\n", lev_config_name(l), blockcur, diff);
- 569 0 : ++silent_error;
- 570 0 : silent_error_on_this_block = 1;
- 571 : }
- 572 : }
- 573 : }
- 574 :
- 575 : /* until now is raid */
- 576 27112 : state_usage_raid(state);
- 577 : }
- 578 :
- 579 28032 : if (silent_error_on_this_block || io_error_on_this_block) {
- 580 : /* set the error status keeping other info */
- 581 920 : info_set(&state->infoarr, blockcur, info_set_bad(info));
- 582 27112 : } else if (error_on_this_block) {
- 583 : /* do nothing, as this is a generic error */
- 584 : /* likely caused by a not synced array */
- 585 : } else {
- 586 : /* if rehash is needed */
- 587 27112 : if (rehash) {
- 588 : /* store all the new hash already computed */
- 589 32256 : for (j = 0; j < diskmax; ++j) {
- 590 27648 : if (rehandle[j].block)
- 591 27247 : memcpy(rehandle[j].block->hash, rehandle[j].hash, BLOCK_HASH_SIZE);
- 592 : }
- 593 : }
- 594 :
- 595 : /* update the time info of the block */
- 596 : /* and clear any other flag */
- 597 27112 : info_set(&state->infoarr, blockcur, info_make(now, 0, 0, 0));
- 598 : }
- 599 :
- 600 : /* mark the state as needing write */
- 601 28032 : state->need_write = 1;
+ 561 : /* compute the parity */
+ 562 27112 : raid_gen(diskmax, state->level, state->block_size, buffer);
+ 563 :
+ 564 : /* compare the parity */
+ 565 189784 : for (l = 0; l < state->level; ++l) {
+ 566 162672 : if (buffer_recov[l] && memcmp(buffer[diskmax + l], buffer_recov[l], state->block_size) != 0) {
+ 567 0 : unsigned diff = memdiff(buffer[diskmax + l], buffer_recov[l], state->block_size);
+ 568 :
+ 569 0 : log_tag("parity_error:%u:%s: Data error, diff bits %u\n", blockcur, lev_config_name(l), diff);
+ 570 :
+ 571 : /* it's a silent error only if we are dealing with synced blocks */
+ 572 0 : if (block_is_unsynced) {
+ 573 0 : ++error;
+ 574 0 : error_on_this_block = 1;
+ 575 : } else {
+ 576 0 : log_fatal("Data error in parity '%s' at position '%u', diff bits %u\n", lev_config_name(l), blockcur, diff);
+ 577 0 : ++silent_error;
+ 578 0 : silent_error_on_this_block = 1;
+ 579 : }
+ 580 : }
+ 581 : }
+ 582 :
+ 583 : /* until now is raid */
+ 584 27112 : state_usage_raid(state);
+ 585 : }
+ 586 :
+ 587 28032 : if (silent_error_on_this_block || io_error_on_this_block) {
+ 588 : /* set the error status keeping other info */
+ 589 920 : info_set(&state->infoarr, blockcur, info_set_bad(info));
+ 590 27112 : } else if (error_on_this_block) {
+ 591 : /* do nothing, as this is a generic error */
+ 592 : /* likely caused by a not synced array */
+ 593 : } else {
+ 594 : /* if rehash is needed */
+ 595 27112 : if (rehash) {
+ 596 : /* store all the new hash already computed */
+ 597 32256 : for (j = 0; j < diskmax; ++j) {
+ 598 27648 : if (rehandle[j].block)
+ 599 27247 : memcpy(rehandle[j].block->hash, rehandle[j].hash, BLOCK_HASH_SIZE);
+ 600 : }
+ 601 : }
602 :
- 603 : /* count the number of processed block */
- 604 28032 : ++countpos;
- 605 :
- 606 : /* progress */
- 607 28032 : if (state_progress(state, &io, blockcur, countpos, countmax, countsize)) {
- 608 : /* LCOV_EXCL_START */
- 609 : break;
- 610 : /* LCOV_EXCL_STOP */
- 611 : }
- 612 :
- 613 : /* autosave */
- 614 28032 : if (state->autosave != 0
- 615 0 : && autosavedone >= autosavelimit /* if we have reached the limit */
- 616 0 : && autosavemissing >= autosavelimit /* if we have at least a full step to do */
- 617 : ) {
- 618 0 : autosavedone = 0; /* restart the counter */
- 619 :
- 620 : /* until now is misc */
- 621 0 : state_usage_misc(state);
- 622 :
- 623 0 : state_progress_stop(state);
- 624 :
- 625 0 : msg_progress("Autosaving...\n");
- 626 0 : state_write(state);
+ 603 : /* update the time info of the block */
+ 604 : /* and clear any other flag */
+ 605 27112 : info_set(&state->infoarr, blockcur, info_make(now, 0, 0, 0));
+ 606 : }
+ 607 :
+ 608 : /* mark the state as needing write */
+ 609 28032 : state->need_write = 1;
+ 610 :
+ 611 : /* count the number of processed block */
+ 612 28032 : ++countpos;
+ 613 :
+ 614 : /* progress */
+ 615 28032 : if (state_progress(state, &io, blockcur, countpos, countmax, countsize)) {
+ 616 : /* LCOV_EXCL_START */
+ 617 : break;
+ 618 : /* LCOV_EXCL_STOP */
+ 619 : }
+ 620 :
+ 621 : /* autosave */
+ 622 28032 : if (state->autosave != 0
+ 623 0 : && autosavedone >= autosavelimit /* if we have reached the limit */
+ 624 0 : && autosavemissing >= autosavelimit /* if we have at least a full step to do */
+ 625 : ) {
+ 626 0 : autosavedone = 0; /* restart the counter */
627 :
- 628 0 : state_progress_restart(state);
- 629 :
- 630 : /* drop until now */
- 631 0 : state_usage_waste(state);
- 632 : }
- 633 28032 : }
- 634 :
- 635 11 : state_progress_end(state, countpos, countmax, countsize);
- 636 :
- 637 11 : state_usage_print(state);
- 638 :
- 639 11 : if (error || silent_error || io_error) {
- 640 1 : msg_status("\n");
- 641 1 : msg_status("%8u file errors\n", error);
- 642 1 : msg_status("%8u io errors\n", io_error);
- 643 1 : msg_status("%8u data errors\n", silent_error);
- 644 : } else {
- 645 : /* print the result only if processed something */
- 646 10 : if (countpos != 0)
- 647 9 : msg_status("Everything OK\n");
- 648 : }
- 649 :
- 650 11 : if (error)
- 651 0 : log_fatal("WARNING! Unexpected file errors!\n");
- 652 11 : if (io_error)
- 653 0 : log_fatal("DANGER! Unexpected input/output errors! The failing blocks are now marked as bad!\n");
- 654 11 : if (silent_error)
- 655 1 : log_fatal("DANGER! Unexpected data errors! The failing blocks are now marked as bad!\n");
- 656 11 : if (io_error || silent_error) {
- 657 1 : log_fatal("Use 'snapraid status' to list the bad blocks.\n");
- 658 1 : log_fatal("Use 'snapraid -e fix' to recover.\n");
- 659 : }
- 660 :
- 661 11 : log_tag("summary:error_file:%u\n", error);
- 662 11 : log_tag("summary:error_io:%u\n", io_error);
- 663 11 : log_tag("summary:error_data:%u\n", silent_error);
- 664 11 : if (error + silent_error + io_error == 0)
- 665 10 : log_tag("summary:exit:ok\n");
- 666 : else
- 667 1 : log_tag("summary:exit:error\n");
- 668 11 : log_flush();
- 669 :
- 670 : bail:
- 671 : /* stop all the worker threads */
- 672 11 : io_stop(&io);
- 673 :
- 674 77 : for (j = 0; j < diskmax; ++j) {
- 675 66 : struct snapraid_file* file = handle[j].file;
- 676 66 : struct snapraid_disk* disk = handle[j].disk;
- 677 66 : ret = handle_close(&handle[j]);
- 678 66 : if (ret == -1) {
- 679 : /* LCOV_EXCL_START */
- 680 : log_tag("error:%u:%s:%s: Close error. %s\n", blockcur, disk->name, esc_tag(file->sub, esc_buffer), strerror(errno));
- 681 : log_fatal("DANGER! Unexpected close error in a data disk.\n");
- 682 : ++error;
- 683 : /* continue, as we are already exiting */
- 684 : /* LCOV_EXCL_STOP */
- 685 : }
- 686 : }
- 687 :
- 688 11 : free(handle);
- 689 11 : free(rehandle_alloc);
- 690 11 : free(waiting_map);
- 691 11 : io_done(&io);
- 692 :
- 693 11 : if (state->opt.expect_recoverable) {
- 694 1 : if (error + silent_error + io_error == 0)
- 695 0 : return -1;
- 696 : } else {
- 697 10 : if (error + silent_error + io_error != 0)
- 698 0 : return -1;
- 699 : }
- 700 11 : return 0;
- 701 : }
- 702 :
- 703 : /**
- 704 : * Return a * b / c approximated to the upper value.
- 705 : */
- 706 2 : static uint32_t md(uint32_t a, uint32_t b, uint32_t c)
- 707 : {
- 708 2 : uint64_t v = a;
- 709 :
- 710 2 : v *= b;
- 711 2 : v += c - 1;
- 712 2 : v /= c;
- 713 :
- 714 2 : return v;
- 715 : }
- 716 :
- 717 11 : int state_scrub(struct snapraid_state* state, int plan, int olderthan)
- 718 : {
- 719 : block_off_t blockmax;
- 720 : block_off_t countlimit;
- 721 : block_off_t i;
- 722 : block_off_t count;
- 723 : time_t recentlimit;
- 724 : int ret;
- 725 : struct snapraid_parity_handle parity_handle[LEV_MAX];
- 726 : struct snapraid_plan ps;
- 727 : time_t* timemap;
- 728 : unsigned error;
- 729 : time_t now;
- 730 : unsigned l;
- 731 :
- 732 : /* get the present time */
- 733 11 : now = time(0);
- 734 :
- 735 11 : msg_progress("Initializing...\n");
- 736 :
- 737 11 : if ((plan == SCRUB_BAD || plan == SCRUB_NEW || plan == SCRUB_FULL)
- 738 4 : && olderthan >= 0) {
- 739 : /* LCOV_EXCL_START */
- 740 : log_fatal("You can specify -o, --older-than only with a numeric percentage.\n");
- 741 : exit(EXIT_FAILURE);
- 742 : /* LCOV_EXCL_STOP */
- 743 : }
+ 628 : /* until now is misc */
+ 629 0 : state_usage_misc(state);
+ 630 :
+ 631 0 : state_progress_stop(state);
+ 632 :
+ 633 0 : msg_progress("Autosaving...\n");
+ 634 0 : state_write(state);
+ 635 :
+ 636 0 : state_progress_restart(state);
+ 637 :
+ 638 : /* drop until now */
+ 639 0 : state_usage_waste(state);
+ 640 : }
+ 641 28032 : }
+ 642 :
+ 643 11 : state_progress_end(state, countpos, countmax, countsize);
+ 644 :
+ 645 11 : state_usage_print(state);
+ 646 :
+ 647 11 : if (error || silent_error || io_error) {
+ 648 1 : msg_status("\n");
+ 649 1 : msg_status("%8u file errors\n", error);
+ 650 1 : msg_status("%8u io errors\n", io_error);
+ 651 1 : msg_status("%8u data errors\n", silent_error);
+ 652 : } else {
+ 653 : /* print the result only if processed something */
+ 654 10 : if (countpos != 0)
+ 655 9 : msg_status("Everything OK\n");
+ 656 : }
+ 657 :
+ 658 11 : if (error)
+ 659 0 : log_fatal("WARNING! Unexpected file errors!\n");
+ 660 11 : if (io_error)
+ 661 0 : log_fatal("DANGER! Unexpected input/output errors! The failing blocks are now marked as bad!\n");
+ 662 11 : if (silent_error)
+ 663 1 : log_fatal("DANGER! Unexpected data errors! The failing blocks are now marked as bad!\n");
+ 664 11 : if (io_error || silent_error) {
+ 665 1 : log_fatal("Use 'snapraid status' to list the bad blocks.\n");
+ 666 1 : log_fatal("Use 'snapraid -e fix' to recover.\n");
+ 667 : }
+ 668 :
+ 669 11 : log_tag("summary:error_file:%u\n", error);
+ 670 11 : log_tag("summary:error_io:%u\n", io_error);
+ 671 11 : log_tag("summary:error_data:%u\n", silent_error);
+ 672 11 : if (error + silent_error + io_error == 0)
+ 673 10 : log_tag("summary:exit:ok\n");
+ 674 : else
+ 675 1 : log_tag("summary:exit:error\n");
+ 676 11 : log_flush();
+ 677 :
+ 678 : bail:
+ 679 : /* stop all the worker threads */
+ 680 11 : io_stop(&io);
+ 681 :
+ 682 77 : for (j = 0; j < diskmax; ++j) {
+ 683 66 : struct snapraid_file* file = handle[j].file;
+ 684 66 : struct snapraid_disk* disk = handle[j].disk;
+ 685 66 : ret = handle_close(&handle[j]);
+ 686 66 : if (ret == -1) {
+ 687 : /* LCOV_EXCL_START */
+ 688 : log_tag("error:%u:%s:%s: Close error. %s\n", blockcur, disk->name, esc_tag(file->sub, esc_buffer), strerror(errno));
+ 689 : log_fatal("DANGER! Unexpected close error in a data disk.\n");
+ 690 : ++error;
+ 691 : /* continue, as we are already exiting */
+ 692 : /* LCOV_EXCL_STOP */
+ 693 : }
+ 694 : }
+ 695 :
+ 696 11 : free(handle);
+ 697 11 : free(rehandle_alloc);
+ 698 11 : free(waiting_map);
+ 699 11 : io_done(&io);
+ 700 :
+ 701 11 : if (state->opt.expect_recoverable) {
+ 702 1 : if (error + silent_error + io_error == 0)
+ 703 0 : return -1;
+ 704 : } else {
+ 705 10 : if (error + silent_error + io_error != 0)
+ 706 0 : return -1;
+ 707 : }
+ 708 11 : return 0;
+ 709 : }
+ 710 :
+ 711 : /**
+ 712 : * Return a * b / c approximated to the upper value.
+ 713 : */
+ 714 2 : static uint32_t md(uint32_t a, uint32_t b, uint32_t c)
+ 715 : {
+ 716 2 : uint64_t v = a;
+ 717 :
+ 718 2 : v *= b;
+ 719 2 : v += c - 1;
+ 720 2 : v /= c;
+ 721 :
+ 722 2 : return v;
+ 723 : }
+ 724 :
+ 725 11 : int state_scrub(struct snapraid_state* state, int plan, int olderthan)
+ 726 : {
+ 727 : block_off_t blockmax;
+ 728 : block_off_t countlimit;
+ 729 : block_off_t i;
+ 730 : block_off_t count;
+ 731 : time_t recentlimit;
+ 732 : int ret;
+ 733 : struct snapraid_parity_handle parity_handle[LEV_MAX];
+ 734 : struct snapraid_plan ps;
+ 735 : time_t* timemap;
+ 736 : unsigned error;
+ 737 : time_t now;
+ 738 : unsigned l;
+ 739 :
+ 740 : /* get the present time */
+ 741 11 : now = time(0);
+ 742 :
+ 743 11 : msg_progress("Initializing...\n");
744 :
- 745 11 : blockmax = parity_allocated_size(state);
- 746 :
- 747 : /* preinitialize to avoid warnings */
- 748 11 : countlimit = 0;
- 749 11 : recentlimit = 0;
- 750 :
- 751 11 : ps.state = state;
- 752 11 : if (state->opt.force_scrub_even) {
- 753 1 : ps.plan = SCRUB_EVEN;
- 754 10 : } else if (plan == SCRUB_FULL) {
- 755 2 : ps.plan = SCRUB_FULL;
- 756 8 : } else if (plan == SCRUB_NEW) {
- 757 1 : ps.plan = SCRUB_NEW;
- 758 7 : } else if (plan == SCRUB_BAD) {
- 759 1 : ps.plan = SCRUB_BAD;
- 760 6 : } else if (state->opt.force_scrub_at) {
- 761 : /* scrub the specified amount of blocks */
- 762 4 : ps.plan = SCRUB_AUTO;
- 763 4 : countlimit = state->opt.force_scrub_at;
- 764 4 : recentlimit = now;
- 765 : } else {
- 766 2 : ps.plan = SCRUB_AUTO;
- 767 2 : if (plan >= 0) {
- 768 1 : countlimit = md(blockmax, plan, 100);
- 769 : } else {
- 770 : /* by default scrub 8.33% of the array (100/12=8.(3)) */
- 771 1 : countlimit = md(blockmax, 1, 12);
- 772 : }
- 773 :
- 774 2 : if (olderthan >= 0) {
- 775 1 : recentlimit = now - olderthan * 24 * 3600;
- 776 : } else {
- 777 : /* by default use a 10 day time limit */
- 778 1 : recentlimit = now - 10 * 24 * 3600;
- 779 : }
- 780 : }
+ 745 11 : if ((plan == SCRUB_BAD || plan == SCRUB_NEW || plan == SCRUB_FULL)
+ 746 4 : && olderthan >= 0) {
+ 747 : /* LCOV_EXCL_START */
+ 748 : log_fatal("You can specify -o, --older-than only with a numeric percentage.\n");
+ 749 : exit(EXIT_FAILURE);
+ 750 : /* LCOV_EXCL_STOP */
+ 751 : }
+ 752 :
+ 753 11 : blockmax = parity_allocated_size(state);
+ 754 :
+ 755 : /* preinitialize to avoid warnings */
+ 756 11 : countlimit = 0;
+ 757 11 : recentlimit = 0;
+ 758 :
+ 759 11 : ps.state = state;
+ 760 11 : if (state->opt.force_scrub_even) {
+ 761 1 : ps.plan = SCRUB_EVEN;
+ 762 10 : } else if (plan == SCRUB_FULL) {
+ 763 2 : ps.plan = SCRUB_FULL;
+ 764 8 : } else if (plan == SCRUB_NEW) {
+ 765 1 : ps.plan = SCRUB_NEW;
+ 766 7 : } else if (plan == SCRUB_BAD) {
+ 767 1 : ps.plan = SCRUB_BAD;
+ 768 6 : } else if (state->opt.force_scrub_at) {
+ 769 : /* scrub the specified amount of blocks */
+ 770 4 : ps.plan = SCRUB_AUTO;
+ 771 4 : countlimit = state->opt.force_scrub_at;
+ 772 4 : recentlimit = now;
+ 773 : } else {
+ 774 2 : ps.plan = SCRUB_AUTO;
+ 775 2 : if (plan >= 0) {
+ 776 1 : countlimit = md(blockmax, plan, 100);
+ 777 : } else {
+ 778 : /* by default scrub 8.33% of the array (100/12=8.(3)) */
+ 779 1 : countlimit = md(blockmax, 1, 12);
+ 780 : }
781 :
- 782 : /* identify the time limit */
- 783 : /* we sort all the block times, and we identify the time limit for which we reach the quota */
- 784 : /* this allow to process first the oldest blocks */
- 785 11 : timemap = malloc_nofail(blockmax * sizeof(time_t));
- 786 :
- 787 : /* copy the info in the temp vector */
- 788 11 : count = 0;
- 789 11 : log_tag("block_count:%u\n", blockmax);
- 790 56096 : for (i = 0; i < blockmax; ++i) {
- 791 56085 : snapraid_info info = info_get(&state->infoarr, i);
- 792 :
- 793 : /* skip unused blocks */
- 794 56085 : if (info == 0)
- 795 0 : continue;
- 796 :
- 797 56085 : timemap[count++] = info_get_time(info);
- 798 : }
- 799 :
- 800 11 : if (!count) {
- 801 : /* LCOV_EXCL_START */
- 802 : log_fatal("The array appears to be empty.\n");
- 803 : exit(EXIT_FAILURE);
- 804 : /* LCOV_EXCL_STOP */
- 805 : }
- 806 :
- 807 : /* sort it */
- 808 11 : qsort(timemap, count, sizeof(time_t), time_compare);
- 809 :
- 810 : /* output the info map */
- 811 11 : i = 0;
- 812 11 : log_tag("info_count:%u\n", count);
- 813 43 : while (i < count) {
- 814 21 : unsigned j = i + 1;
- 815 56106 : while (j < count && timemap[i] == timemap[j])
- 816 56064 : ++j;
- 817 21 : log_tag("info_time:%" PRIu64 ":%u\n", (uint64_t)timemap[i], j - i);
- 818 21 : i = j;
- 819 : }
- 820 :
- 821 : /* compute the limits from count/recentlimit */
- 822 11 : if (ps.plan == SCRUB_AUTO) {
- 823 : /* no more than the full count */
- 824 6 : if (countlimit > count)
- 825 2 : countlimit = count;
- 826 :
- 827 : /* decrease until we reach the specific recentlimit */
- 828 59 : while (countlimit > 0 && timemap[countlimit - 1] > recentlimit)
- 829 47 : --countlimit;
- 830 :
- 831 : /* if there is something to scrub */
- 832 6 : if (countlimit > 0) {
- 833 : /* get the most recent time we want to scrub */
- 834 5 : ps.timelimit = timemap[countlimit - 1];
- 835 :
- 836 : /* count how many entries for this exact time we have to scrub */
- 837 : /* if the blocks have all the same time, we end with countlimit == lastlimit */
- 838 5 : ps.lastlimit = 1;
- 839 2601 : while (countlimit > ps.lastlimit && timemap[countlimit - ps.lastlimit - 1] == ps.timelimit)
- 840 2591 : ++ps.lastlimit;
- 841 : } else {
- 842 : /* if nothing to scrub, disable also other limits */
- 843 1 : ps.timelimit = 0;
- 844 1 : ps.lastlimit = 0;
- 845 : }
- 846 :
- 847 6 : log_tag("count_limit:%u\n", countlimit);
- 848 6 : log_tag("time_limit:%" PRIu64 "\n", (uint64_t)ps.timelimit);
- 849 6 : log_tag("last_limit:%u\n", ps.lastlimit);
- 850 : }
- 851 :
- 852 : /* free the temp vector */
- 853 11 : free(timemap);
+ 782 2 : if (olderthan >= 0) {
+ 783 1 : recentlimit = now - olderthan * 24 * 3600;
+ 784 : } else {
+ 785 : /* by default use a 10 day time limit */
+ 786 1 : recentlimit = now - 10 * 24 * 3600;
+ 787 : }
+ 788 : }
+ 789 :
+ 790 : /* identify the time limit */
+ 791 : /* we sort all the block times, and we identify the time limit for which we reach the quota */
+ 792 : /* this allow to process first the oldest blocks */
+ 793 11 : timemap = malloc_nofail(blockmax * sizeof(time_t));
+ 794 :
+ 795 : /* copy the info in the temp vector */
+ 796 11 : count = 0;
+ 797 11 : log_tag("block_count:%u\n", blockmax);
+ 798 56096 : for (i = 0; i < blockmax; ++i) {
+ 799 56085 : snapraid_info info = info_get(&state->infoarr, i);
+ 800 :
+ 801 : /* skip unused blocks */
+ 802 56085 : if (info == 0)
+ 803 0 : continue;
+ 804 :
+ 805 56085 : timemap[count++] = info_get_time(info);
+ 806 : }
+ 807 :
+ 808 11 : if (!count) {
+ 809 : /* LCOV_EXCL_START */
+ 810 : log_fatal("The array appears to be empty.\n");
+ 811 : exit(EXIT_FAILURE);
+ 812 : /* LCOV_EXCL_STOP */
+ 813 : }
+ 814 :
+ 815 : /* sort it */
+ 816 11 : qsort(timemap, count, sizeof(time_t), time_compare);
+ 817 :
+ 818 : /* output the info map */
+ 819 11 : i = 0;
+ 820 11 : log_tag("info_count:%u\n", count);
+ 821 41 : while (i < count) {
+ 822 19 : unsigned j = i + 1;
+ 823 56104 : while (j < count && timemap[i] == timemap[j])
+ 824 56066 : ++j;
+ 825 19 : log_tag("info_time:%" PRIu64 ":%u\n", (uint64_t)timemap[i], j - i);
+ 826 19 : i = j;
+ 827 : }
+ 828 :
+ 829 : /* compute the limits from count/recentlimit */
+ 830 11 : if (ps.plan == SCRUB_AUTO) {
+ 831 : /* no more than the full count */
+ 832 6 : if (countlimit > count)
+ 833 2 : countlimit = count;
+ 834 :
+ 835 : /* decrease until we reach the specific recentlimit */
+ 836 59 : while (countlimit > 0 && timemap[countlimit - 1] > recentlimit)
+ 837 47 : --countlimit;
+ 838 :
+ 839 : /* if there is something to scrub */
+ 840 6 : if (countlimit > 0) {
+ 841 : /* get the most recent time we want to scrub */
+ 842 5 : ps.timelimit = timemap[countlimit - 1];
+ 843 :
+ 844 : /* count how many entries for this exact time we have to scrub */
+ 845 : /* if the blocks have all the same time, we end with countlimit == lastlimit */
+ 846 5 : ps.lastlimit = 1;
+ 847 2601 : while (countlimit > ps.lastlimit && timemap[countlimit - ps.lastlimit - 1] == ps.timelimit)
+ 848 2591 : ++ps.lastlimit;
+ 849 : } else {
+ 850 : /* if nothing to scrub, disable also other limits */
+ 851 1 : ps.timelimit = 0;
+ 852 1 : ps.lastlimit = 0;
+ 853 : }
854 :
- 855 : /* open the file for reading */
- 856 77 : for (l = 0; l < state->level; ++l) {
- 857 66 : ret = parity_open(&parity_handle[l], &state->parity[l], l, state->file_mode, state->block_size, state->opt.parity_limit_size);
- 858 66 : if (ret == -1) {
- 859 : /* LCOV_EXCL_START */
- 860 : log_fatal("WARNING! Without an accessible %s file, it isn't possible to scrub.\n", lev_name(l));
- 861 : exit(EXIT_FAILURE);
- 862 : /* LCOV_EXCL_STOP */
- 863 : }
- 864 : }
- 865 :
- 866 11 : msg_progress("Scrubbing...\n");
- 867 :
- 868 11 : error = 0;
- 869 :
- 870 11 : ret = state_scrub_process(state, parity_handle, 0, blockmax, &ps, now);
- 871 11 : if (ret == -1) {
- 872 0 : ++error;
- 873 : /* continue, as we are already exiting */
- 874 : }
+ 855 6 : log_tag("count_limit:%u\n", countlimit);
+ 856 6 : log_tag("time_limit:%" PRIu64 "\n", (uint64_t)ps.timelimit);
+ 857 6 : log_tag("last_limit:%u\n", ps.lastlimit);
+ 858 : }
+ 859 :
+ 860 : /* free the temp vector */
+ 861 11 : free(timemap);
+ 862 :
+ 863 : /* open the file for reading */
+ 864 77 : for (l = 0; l < state->level; ++l) {
+ 865 66 : ret = parity_open(&parity_handle[l], &state->parity[l], l, state->file_mode, state->block_size, state->opt.parity_limit_size);
+ 866 66 : if (ret == -1) {
+ 867 : /* LCOV_EXCL_START */
+ 868 : log_fatal("WARNING! Without an accessible %s file, it isn't possible to scrub.\n", lev_name(l));
+ 869 : exit(EXIT_FAILURE);
+ 870 : /* LCOV_EXCL_STOP */
+ 871 : }
+ 872 : }
+ 873 :
+ 874 11 : msg_progress("Scrubbing...\n");
875 :
- 876 77 : for (l = 0; l < state->level; ++l) {
- 877 66 : ret = parity_close(&parity_handle[l]);
- 878 66 : if (ret == -1) {
- 879 : /* LCOV_EXCL_START */
- 880 : log_fatal("DANGER! Unexpected close error in %s disk.\n", lev_name(l));
- 881 : ++error;
- 882 : /* continue, as we are already exiting */
- 883 : /* LCOV_EXCL_STOP */
- 884 : }
- 885 : }
- 886 :
- 887 : /* abort if required */
- 888 11 : if (error != 0)
- 889 0 : return -1;
- 890 11 : return 0;
- 891 : }
- 892 :
+ 876 11 : error = 0;
+ 877 :
+ 878 11 : ret = state_scrub_process(state, parity_handle, 0, blockmax, &ps, now);
+ 879 11 : if (ret == -1) {
+ 880 0 : ++error;
+ 881 : /* continue, as we are already exiting */
+ 882 : }
+ 883 :
+ 884 77 : for (l = 0; l < state->level; ++l) {
+ 885 66 : ret = parity_close(&parity_handle[l]);
+ 886 66 : if (ret == -1) {
+ 887 : /* LCOV_EXCL_START */
+ 888 : log_fatal("DANGER! Unexpected close error in %s disk.\n", lev_name(l));
+ 889 : ++error;
+ 890 : /* continue, as we are already exiting */
+ 891 : /* LCOV_EXCL_STOP */
+ 892 : }
+ 893 : }
+ 894 :
+ 895 : /* abort if required */
+ 896 11 : if (error != 0)
+ 897 0 : return -1;
+ 898 11 : return 0;
+ 899 : }
+ 900 :
diff --git a/cov/cmdline/search.c.func-sort-c.html b/cov/cmdline/search.c.func-sort-c.html
index 02721bee..80b5a3f0 100644
--- a/cov/cmdline/search.c.func-sort-c.html
+++ b/cov/cmdline/search.c.func-sort-c.html
@@ -61,19 +61,19 @@
| search_file |
- 1843728 |
+ 1843909 |
| search_file_free |
- 1843728 |
+ 1843909 |
| state_search_fetch |
- 639176 |
+ 638916 |
| search_file_compare |
- 20130 |
+ 20183 |
| search_dir |
diff --git a/cov/cmdline/search.c.func.html b/cov/cmdline/search.c.func.html
index fe7f744e..2dfdb1be 100644
--- a/cov/cmdline/search.c.func.html
+++ b/cov/cmdline/search.c.func.html
@@ -65,15 +65,15 @@
| search_file |
- 1843728 |
+ 1843909 |
| search_file_compare |
- 20130 |
+ 20183 |
| search_file_free |
- 1843728 |
+ 1843909 |
| state_search |
@@ -85,7 +85,7 @@
| state_search_fetch |
- 639176 |
+ 638916 |
diff --git a/cov/cmdline/search.c.gcov.html b/cov/cmdline/search.c.gcov.html
index fcd3b596..86339e03 100644
--- a/cov/cmdline/search.c.gcov.html
+++ b/cov/cmdline/search.c.gcov.html
@@ -85,27 +85,27 @@
23 : /****************************************************************************/
24 : /* search */
25 :
- 26 1843728 : static void search_file(struct snapraid_state* state, const char* path, data_off_t size, int64_t mtime_sec, int mtime_nsec)
+ 26 1843909 : 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 1843728 : file = malloc_nofail(sizeof(struct snapraid_search_file));
- 32 1843728 : file->path = strdup_nofail(path);
- 33 1843728 : file->size = size;
- 34 1843728 : file->mtime_sec = mtime_sec;
- 35 1843728 : file->mtime_nsec = mtime_nsec;
+ 31 1843909 : file = malloc_nofail(sizeof(struct snapraid_search_file));
+ 32 1843909 : file->path = strdup_nofail(path);
+ 33 1843909 : file->size = size;
+ 34 1843909 : file->mtime_sec = mtime_sec;
+ 35 1843909 : file->mtime_nsec = mtime_nsec;
36 :
- 37 1843728 : file_hash = file_stamp_hash(file->size, file->mtime_sec, file->mtime_nsec);
+ 37 1843909 : file_hash = file_stamp_hash(file->size, file->mtime_sec, file->mtime_nsec);
38 :
- 39 1843728 : tommy_hashdyn_insert(&state->searchset, &file->node, file, file_hash);
- 40 1843728 : }
+ 39 1843909 : tommy_hashdyn_insert(&state->searchset, &file->node, file, file_hash);
+ 40 1843909 : }
41 :
- 42 1843728 : void search_file_free(struct snapraid_search_file* file)
+ 42 1843909 : void search_file_free(struct snapraid_search_file* file)
43 : {
- 44 1843728 : free(file->path);
- 45 1843728 : free(file);
- 46 1843728 : }
+ 44 1843909 : free(file->path);
+ 45 1843909 : free(file);
+ 46 1843909 : }
47 :
48 : struct search_file_compare_arg {
49 : const struct snapraid_state* state;
@@ -117,29 +117,29 @@
55 : int prevhash;
56 : };
57 :
- 58 20130 : int search_file_compare(const void* void_arg, const void* void_data)
+ 58 20183 : int search_file_compare(const void* void_arg, const void* void_data)
59 : {
- 60 20130 : const struct search_file_compare_arg* arg = void_arg;
- 61 20130 : const struct snapraid_search_file* file = void_data;
- 62 20130 : const struct snapraid_state* state = arg->state;
+ 60 20183 : const struct search_file_compare_arg* arg = void_arg;
+ 61 20183 : const struct snapraid_search_file* file = void_data;
+ 62 20183 : const struct snapraid_state* state = arg->state;
63 : unsigned char buffer_hash[HASH_MAX];
- 64 20130 : const char* path = file->path;
+ 64 20183 : const char* path = file->path;
65 : int f;
66 : ssize_t ret;
67 :
68 : /* compare file info */
- 69 20130 : if (arg->file->size != file->size)
+ 69 20183 : if (arg->file->size != file->size)
70 0 : return -1;
71 :
- 72 20130 : if (arg->file->mtime_sec != file->mtime_sec)
+ 72 20183 : if (arg->file->mtime_sec != file->mtime_sec)
73 0 : return -1;
74 :
- 75 20130 : if (arg->file->mtime_nsec != file->mtime_nsec)
+ 75 20183 : if (arg->file->mtime_nsec != file->mtime_nsec)
76 0 : return -1;
77 :
78 : /* read the block and compare the hash */
- 79 20130 : f = open(path, O_RDONLY | O_BINARY);
- 80 20130 : if (f == -1) {
+ 79 20183 : f = open(path, O_RDONLY | O_BINARY);
+ 80 20183 : if (f == -1) {
81 : /* LCOV_EXCL_START */
82 : if (errno == ENOENT) {
83 : log_fatal("DANGER! file '%s' disappeared.\n", path);
@@ -151,16 +151,16 @@
89 : /* LCOV_EXCL_STOP */
90 : }
91 :
- 92 20130 : ret = pread(f, arg->buffer, arg->read_size, arg->offset);
- 93 20130 : if (ret < 0 || (unsigned)ret != arg->read_size) {
+ 92 20183 : ret = pread(f, arg->buffer, arg->read_size, arg->offset);
+ 93 20183 : if (ret < 0 || (unsigned)ret != arg->read_size) {
94 : /* LCOV_EXCL_START */
95 : log_fatal("Error reading file '%s'. %s.\n", path, strerror(errno));
96 : exit(EXIT_FAILURE);
97 : /* LCOV_EXCL_STOP */
98 : }
99 :
- 100 20130 : ret = close(f);
- 101 20130 : if (ret != 0) {
+ 100 20183 : ret = close(f);
+ 101 20183 : if (ret != 0) {
102 : /* LCOV_EXCL_START */
103 : log_fatal("Error closing file '%s'. %s.\n", path, strerror(errno));
104 : exit(EXIT_FAILURE);
@@ -168,14 +168,14 @@
106 : }
107 :
108 : /* compute the hash */
- 109 20130 : if (arg->prevhash)
+ 109 20183 : if (arg->prevhash)
110 0 : memhash(state->prevhash, state->prevhashseed, buffer_hash, arg->buffer, arg->read_size);
111 : else
- 112 20130 : memhash(state->hash, state->hashseed, buffer_hash, arg->buffer, arg->read_size);
+ 112 20183 : memhash(state->hash, state->hashseed, buffer_hash, arg->buffer, arg->read_size);
113 :
114 : /* check if the hash is matching */
- 115 20130 : if (memcmp(buffer_hash, arg->block->hash, BLOCK_HASH_SIZE) != 0)
- 116 2220 : return -1;
+ 115 20183 : if (memcmp(buffer_hash, arg->block->hash, BLOCK_HASH_SIZE) != 0)
+ 116 2273 : return -1;
117 :
118 17910 : if (arg->read_size != state->block_size) {
119 : /* fill the remaining with 0 */
@@ -185,26 +185,26 @@
123 17910 : return 0;
124 : }
125 :
- 126 639176 : 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)
+ 126 638916 : 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)
127 : {
128 : struct snapraid_search_file* file;
129 : tommy_uint32_t file_hash;
130 : struct search_file_compare_arg arg;
131 :
- 132 639176 : arg.state = state;
- 133 639176 : arg.block = missing_block;
- 134 639176 : arg.file = missing_file;
- 135 639176 : arg.buffer = buffer;
- 136 639176 : arg.offset = state->block_size * (data_off_t)missing_file_pos;
- 137 639176 : arg.read_size = file_block_size(missing_file, missing_file_pos, state->block_size);
- 138 639176 : arg.prevhash = prevhash;
+ 132 638916 : arg.state = state;
+ 133 638916 : arg.block = missing_block;
+ 134 638916 : arg.file = missing_file;
+ 135 638916 : arg.buffer = buffer;
+ 136 638916 : arg.offset = state->block_size * (data_off_t)missing_file_pos;
+ 137 638916 : arg.read_size = file_block_size(missing_file, missing_file_pos, state->block_size);
+ 138 638916 : arg.prevhash = prevhash;
139 :
- 140 639176 : file_hash = file_stamp_hash(arg.file->size, arg.file->mtime_sec, arg.file->mtime_nsec);
+ 140 638916 : file_hash = file_stamp_hash(arg.file->size, arg.file->mtime_sec, arg.file->mtime_nsec);
141 :
142 : /* search in the hashtable, and also check if the data matches the hash */
- 143 639176 : file = tommy_hashdyn_search(&state->searchset, search_file_compare, &arg, file_hash);
- 144 639176 : if (!file)
- 145 621266 : return -1;
+ 143 638916 : file = tommy_hashdyn_search(&state->searchset, search_file_compare, &arg, file_hash);
+ 144 638916 : if (!file)
+ 145 621006 : return -1;
146 :
147 : /* if found, buffer is already set with data */
148 17910 : return 0;
@@ -226,40 +226,40 @@
164 : char path_next[PATH_MAX];
165 : char sub_next[PATH_MAX];
166 : char out[PATH_MAX];
- 167 2040132 : struct snapraid_filter* reason = 0;
+ 167 2040347 : struct snapraid_filter* reason = 0;
168 : struct stat st;
169 : const char* name;
170 : struct dirent* dd;
171 :
172 : /* clear errno to detect erroneous conditions */
- 173 2040132 : errno = 0;
- 174 2040132 : dd = readdir(d);
- 175 2040132 : if (dd == 0 && errno != 0) {
+ 173 2040347 : errno = 0;
+ 174 2040347 : dd = readdir(d);
+ 175 2040347 : if (dd == 0 && errno != 0) {
176 : /* LCOV_EXCL_START */
177 : log_fatal("Error reading directory '%s'. %s.\n", dir, strerror(errno));
178 : exit(EXIT_FAILURE);
179 : /* LCOV_EXCL_STOP */
180 : }
- 181 2040132 : if (dd == 0) {
+ 181 2040347 : if (dd == 0) {
182 2462 : break; /* finished */
183 : }
184 :
185 : /* skip "." and ".." files */
- 186 2037670 : name = dd->d_name;
- 187 2037670 : if (name[0] == '.' && (name[1] == 0 || (name[1] == '.' && name[2] == 0)))
+ 186 2037885 : name = dd->d_name;
+ 187 2037885 : if (name[0] == '.' && (name[1] == 0 || (name[1] == '.' && name[2] == 0)))
188 9848 : continue;
189 :
- 190 2032746 : pathprint(path_next, sizeof(path_next), "%s%s", dir, name);
- 191 2032746 : pathprint(sub_next, sizeof(sub_next), "%s%s", sub, name);
+ 190 2032961 : pathprint(path_next, sizeof(path_next), "%s%s", dir, name);
+ 191 2032961 : pathprint(sub_next, sizeof(sub_next), "%s%s", sub, name);
192 :
193 : /* exclude hidden files even before calling lstat() */
- 194 2032746 : if (disk != 0 && filter_hidden(state->filter_hidden, dd) != 0) {
+ 194 2032961 : if (disk != 0 && filter_hidden(state->filter_hidden, dd) != 0) {
195 0 : msg_verbose("Excluding hidden '%s'\n", path_next);
196 0 : continue;
197 : }
198 :
199 : /* exclude content files even before calling lstat() */
- 200 2032746 : if (disk != 0 && filter_content(&state->contentlist, path_next) != 0) {
+ 200 2032961 : if (disk != 0 && filter_content(&state->contentlist, path_next) != 0) {
201 0 : msg_verbose("Excluding content '%s'\n", path_next);
202 0 : continue;
203 : }
@@ -283,7 +283,7 @@
221 : }
222 : #else
223 : /* get lstat info about the file */
- 224 2032746 : if (lstat(path_next, &st) != 0) {
+ 224 2032961 : if (lstat(path_next, &st) != 0) {
225 : /* LCOV_EXCL_START */
226 : log_fatal("Error in stat file/directory '%s'. %s.\n", path_next, strerror(errno));
227 : exit(EXIT_FAILURE);
@@ -291,13 +291,13 @@
229 : }
230 : #endif
231 :
- 232 2032746 : if (S_ISREG(st.st_mode)) {
- 233 1968447 : if (disk == 0 || filter_path(&state->filterlist, &reason, disk->name, sub_next) == 0) {
- 234 1843728 : search_file(state, path_next, st.st_size, st.st_mtime, STAT_NSEC(&st));
+ 232 2032961 : if (S_ISREG(st.st_mode)) {
+ 233 1968636 : if (disk == 0 || filter_path(&state->filterlist, &reason, disk->name, sub_next) == 0) {
+ 234 1843909 : search_file(state, path_next, st.st_size, st.st_mtime, STAT_NSEC(&st));
235 : } else {
- 236 124719 : msg_verbose("Excluding link '%s' for rule '%s'\n", path_next, filter_type(reason, out, sizeof(out)));
+ 236 124727 : msg_verbose("Excluding link '%s' for rule '%s'\n", path_next, filter_type(reason, out, sizeof(out)));
237 : }
- 238 64299 : } else if (S_ISDIR(st.st_mode)) {
+ 238 64325 : } else if (S_ISDIR(st.st_mode)) {
239 1781 : if (disk == 0 || filter_subdir(&state->filterlist, &reason, disk->name, sub_next) == 0) {
240 1781 : pathslash(path_next, sizeof(path_next));
241 1781 : pathslash(sub_next, sizeof(sub_next));
@@ -306,7 +306,7 @@
244 0 : msg_verbose("Excluding directory '%s' for rule '%s'\n", path_next, filter_type(reason, out, sizeof(out)));
245 : }
246 : }
- 247 2037670 : }
+ 247 2037885 : }
248 :
249 2462 : if (closedir(d) != 0) {
250 : /* LCOV_EXCL_START */
diff --git a/cov/cmdline/snapraid.c.func-sort-c.html b/cov/cmdline/snapraid.c.func-sort-c.html
index 287d95e5..44738806 100644
--- a/cov/cmdline/snapraid.c.func-sort-c.html
+++ b/cov/cmdline/snapraid.c.func-sort-c.html
@@ -31,9 +31,9 @@
|
-
+
-
+
@@ -61,19 +61,19 @@
| test |
- 275 |
+ 276 |
| main |
- 275 |
+ 276 |
| config |
- 274 |
+ 275 |
| log_open |
- 264 |
+ 265 |
| log_close |
diff --git a/cov/cmdline/snapraid.c.func.html b/cov/cmdline/snapraid.c.func.html
index 66557d82..3ea7476c 100644
--- a/cov/cmdline/snapraid.c.func.html
+++ b/cov/cmdline/snapraid.c.func.html
@@ -31,9 +31,9 @@
|
-
+
-
+
@@ -61,7 +61,7 @@
| config |
- 274 |
+ 275 |
| log_close |
@@ -69,11 +69,11 @@
| log_open |
- 264 |
+ 265 |
| main |
- 275 |
+ 276 |
| memory |
@@ -85,7 +85,7 @@
| test |
- 275 |
+ 276 |
| usage |
diff --git a/cov/cmdline/snapraid.c.gcov.html b/cov/cmdline/snapraid.c.gcov.html
index ea9d1eae..c470bc51 100644
--- a/cov/cmdline/snapraid.c.gcov.html
+++ b/cov/cmdline/snapraid.c.gcov.html
@@ -31,9 +31,9 @@
|
-
+
-
+
@@ -152,14 +152,14 @@
90 237 : msg_progress("Using %u MiB of memory for the FileSystem.\n", (unsigned)(malloc_counter_get() / MEBI));
91 237 : }
92 :
- 93 275 : void test(int argc, char* argv[])
+ 93 276 : void test(int argc, char* argv[])
94 : {
95 : int i;
96 : char buffer[ESC_MAX];
97 :
98 : /* special testing code for quoting */
- 99 275 : if (argc < 2 || strcmp(argv[1], "test") != 0)
- 100 548 : return;
+ 99 276 : if (argc < 2 || strcmp(argv[1], "test") != 0)
+ 100 550 : return;
101 :
102 1 : for (i = 2; i < argc; ++i) {
103 0 : printf("argv[%d]\n", i);
@@ -185,7 +185,7 @@
123 : /****************************************************************************/
124 : /* log */
125 :
- 126 264 : void log_open(const char* file)
+ 126 265 : void log_open(const char* file)
127 : {
128 : char path[PATH_MAX];
129 : const char* mode;
@@ -195,8 +195,8 @@
133 : struct tm* tm;
134 :
135 : /* leave stdlog at 0 if not specified */
- 136 264 : if (file == 0)
- 137 374 : return;
+ 136 265 : if (file == 0)
+ 137 376 : return;
138 :
139 80 : t = time(0);
140 80 : tm = localtime(&t);
@@ -286,7 +286,7 @@
224 : /****************************************************************************/
225 : /* config */
226 :
- 227 274 : void config(char* conf, size_t conf_size, const char* argv0)
+ 227 275 : void config(char* conf, size_t conf_size, const char* argv0)
228 : {
229 : #ifdef _WIN32
230 : char* slash;
@@ -303,9 +303,9 @@
241 : #else
242 : (void)argv0;
243 :
- 244 274 : pathcpy(conf, conf_size, "/etc/" PACKAGE ".conf");
+ 244 275 : pathcpy(conf, conf_size, "/etc/" PACKAGE ".conf");
245 : #endif
- 246 274 : }
+ 246 275 : }
247 :
248 : /****************************************************************************/
249 : /* main */
@@ -580,7 +580,7 @@
518 : #define OPERATION_DEVICES 16
519 : #define OPERATION_SMART 17
520 :
- 521 275 : int main(int argc, char* argv[])
+ 521 276 : int main(int argc, char* argv[])
522 : {
523 : int c;
524 : struct snapraid_option opt;
@@ -610,43 +610,43 @@
548 : struct tm* tm;
549 : int i;
550 :
- 551 275 : test(argc, argv);
+ 551 276 : test(argc, argv);
552 :
- 553 274 : lock_init();
+ 553 275 : lock_init();
554 :
555 : /* defaults */
- 556 274 : config(conf, sizeof(conf), argv[0]);
- 557 274 : memset(&opt, 0, sizeof(opt));
- 558 274 : opt.io_error_limit = 100;
- 559 274 : blockstart = 0;
- 560 274 : blockcount = 0;
- 561 274 : tommy_list_init(&filterlist_file);
- 562 274 : tommy_list_init(&filterlist_disk);
- 563 274 : period = 1000;
- 564 274 : filter_missing = 0;
- 565 274 : filter_error = 0;
- 566 274 : plan = SCRUB_AUTO;
- 567 274 : olderthan = SCRUB_AUTO;
- 568 274 : import_timestamp = 0;
- 569 274 : import_content = 0;
- 570 274 : log_file = 0;
- 571 274 : lock = 0;
- 572 274 : gen_conf = 0;
- 573 274 : speedtest = 0;
- 574 274 : run = 0;
+ 556 275 : config(conf, sizeof(conf), argv[0]);
+ 557 275 : memset(&opt, 0, sizeof(opt));
+ 558 275 : opt.io_error_limit = 100;
+ 559 275 : blockstart = 0;
+ 560 275 : blockcount = 0;
+ 561 275 : tommy_list_init(&filterlist_file);
+ 562 275 : tommy_list_init(&filterlist_disk);
+ 563 275 : period = 1000;
+ 564 275 : filter_missing = 0;
+ 565 275 : filter_error = 0;
+ 566 275 : plan = SCRUB_AUTO;
+ 567 275 : olderthan = SCRUB_AUTO;
+ 568 275 : import_timestamp = 0;
+ 569 275 : import_content = 0;
+ 570 275 : log_file = 0;
+ 571 275 : lock = 0;
+ 572 275 : gen_conf = 0;
+ 573 275 : speedtest = 0;
+ 574 275 : run = 0;
575 :
- 576 274 : opterr = 0;
- 577 3450 : while ((c =
+ 576 275 : opterr = 0;
+ 577 3463 : while ((c =
578 : #if HAVE_GETOPT_LONG
579 : getopt_long(argc, argv, OPTIONS, long_options, 0))
580 : #else
581 : getopt(argc, argv, OPTIONS))
582 : #endif
583 : != EOF) {
- 584 2907 : switch (c) {
+ 584 2918 : switch (c) {
585 : case 'c' :
- 586 267 : pathimport(conf, sizeof(conf), optarg);
- 587 267 : break;
+ 586 268 : pathimport(conf, sizeof(conf), optarg);
+ 587 268 : break;
588 : case 'f' : {
589 6 : struct snapraid_filter* filter = filter_alloc_file(1, optarg);
590 6 : if (!filter) {
@@ -787,14 +787,14 @@
725 7 : opt.prehash = 1;
726 7 : break;
727 : case 'v' :
- 728 25 : ++msg_level;
- 729 25 : break;
+ 728 26 : ++msg_level;
+ 729 26 : break;
730 : case 'q' :
731 726 : --msg_level;
732 726 : break;
733 : case 'G' :
- 734 25 : opt.gui = 1;
- 735 25 : break;
+ 734 26 : opt.gui = 1;
+ 735 26 : break;
736 : case 'H' :
737 1 : usage();
738 1 : exit(EXIT_SUCCESS);
@@ -817,8 +817,8 @@
755 23 : opt.expect_recoverable = 1;
756 23 : break;
757 : case OPT_TEST_SKIP_SELF :
- 758 267 : opt.skip_self = 1;
- 759 267 : break;
+ 758 268 : opt.skip_self = 1;
+ 759 268 : break;
760 : case OPT_TEST_SKIP_SIGN :
761 0 : opt.skip_sign = 1;
762 0 : break;
@@ -826,9 +826,9 @@
764 1 : opt.skip_fallocate = 1;
765 1 : break;
766 : case OPT_TEST_SKIP_DEVICE :
- 767 274 : opt.skip_device = 1;
- 768 274 : period = 50; /* reduce period of the speed test */
- 769 274 : break;
+ 767 275 : opt.skip_device = 1;
+ 768 275 : period = 50; /* reduce period of the speed test */
+ 769 275 : break;
770 : case OPT_TEST_SKIP_CONTENT_CHECK :
771 0 : opt.skip_content_check = 1;
772 0 : break;
@@ -854,8 +854,8 @@
792 0 : opt.force_order = SORT_INODE;
793 0 : break;
794 : case OPT_TEST_FORCE_ORDER_ALPHA :
- 795 265 : opt.force_order = SORT_ALPHA;
- 796 265 : break;
+ 795 266 : opt.force_order = SORT_ALPHA;
+ 796 266 : break;
797 : case OPT_TEST_FORCE_ORDER_DIR :
798 0 : opt.force_order = SORT_DIR;
799 0 : break;
@@ -875,9 +875,9 @@
813 19 : break;
814 : case OPT_TEST_EXPECT_NEED_SYNC :
815 : /* invert the exit codes */
- 816 6 : exit_success = 1;
- 817 6 : exit_sync_needed = 0;
- 818 6 : break;
+ 816 7 : exit_success = 1;
+ 817 7 : exit_sync_needed = 0;
+ 818 7 : break;
819 : case OPT_TEST_RUN :
820 10 : run = optarg;
821 10 : break;
@@ -885,8 +885,8 @@
823 0 : opt.force_scan_winfind = 1;
824 0 : break;
825 : case OPT_TEST_FORCE_PROGRESS :
- 826 267 : opt.force_progress = 1;
- 827 267 : break;
+ 826 268 : opt.force_progress = 1;
+ 827 268 : break;
828 : case OPT_TEST_FORCE_AUTOSAVE_AT :
829 1 : opt.force_autosave_at = atoi(optarg);
830 1 : break;
@@ -894,8 +894,8 @@
832 1 : opt.fake_device = 1;
833 1 : break;
834 : case OPT_NO_WARNINGS :
- 835 268 : opt.no_warnings = 1;
- 836 268 : break;
+ 835 269 : opt.no_warnings = 1;
+ 836 269 : break;
837 : case OPT_TEST_FAKE_UUID :
838 1 : opt.fake_uuid = 2;
839 1 : break;
@@ -915,8 +915,8 @@
853 : }
854 1 : break;
855 : case OPT_TEST_IO_STATS :
- 856 0 : opt.force_stats = 1;
- 857 0 : break;
+ 856 1 : opt.force_stats = 1;
+ 857 1 : break;
858 : case OPT_TEST_COND_SIGNAL_OUTSIDE :
859 : #if HAVE_PTHREAD
860 0 : thread_cond_signal_outside = 1;
@@ -944,8 +944,8 @@
882 0 : opt.file_mode = ADVISE_DIRECT;
883 0 : break;
884 : case OPT_TEST_PARITY_LIMIT :
- 885 267 : opt.parity_limit_size = atoll(optarg);
- 886 267 : break;
+ 885 268 : opt.parity_limit_size = atoll(optarg);
+ 886 268 : break;
887 : case OPT_TEST_SKIP_CONTENT_WRITE :
888 0 : opt.skip_content_write = 1;
889 0 : break;
@@ -974,32 +974,32 @@
912 : }
913 : }
914 :
- 915 269 : os_init(opt.force_scan_winfind);
- 916 269 : raid_init();
- 917 269 : crc32c_init();
+ 915 270 : os_init(opt.force_scan_winfind);
+ 916 270 : raid_init();
+ 917 270 : crc32c_init();
918 :
- 919 269 : if (speedtest != 0) {
+ 919 270 : if (speedtest != 0) {
920 4 : speed(period);
921 4 : os_done();
922 4 : exit(EXIT_SUCCESS);
923 : }
924 :
- 925 265 : if (gen_conf != 0) {
+ 925 266 : if (gen_conf != 0) {
926 1 : generate_configuration(gen_conf);
927 1 : os_done();
928 1 : exit(EXIT_SUCCESS);
929 : }
930 :
- 931 264 : if (optind + 1 != argc) {
+ 931 265 : if (optind + 1 != argc) {
932 : /* LCOV_EXCL_START */
933 : usage();
934 : exit(EXIT_FAILURE);
935 : /* LCOV_EXCL_STOP */
936 : }
937 :
- 938 264 : command = argv[optind];
- 939 264 : if (strcmp(command, "diff") == 0) {
- 940 7 : operation = OPERATION_DIFF;
+ 938 265 : command = argv[optind];
+ 939 265 : if (strcmp(command, "diff") == 0) {
+ 940 8 : operation = OPERATION_DIFF;
941 257 : } else if (strcmp(argv[optind], "sync") == 0) {
942 89 : operation = OPERATION_SYNC;
943 168 : } else if (strcmp(argv[optind], "check") == 0) {
@@ -1042,11 +1042,11 @@
980 : }
981 :
982 : /* check options compatibility */
- 983 264 : switch (operation) {
+ 983 265 : switch (operation) {
984 : case OPERATION_CHECK :
985 75 : break;
986 : default :
- 987 189 : if (opt.auditonly) {
+ 987 190 : if (opt.auditonly) {
988 : /* LCOV_EXCL_START */
989 : log_fatal("You cannot use -a, --audit-only with the '%s' command\n", command);
990 : exit(EXIT_FAILURE);
@@ -1054,12 +1054,12 @@
992 : }
993 : }
994 :
- 995 264 : switch (operation) {
+ 995 265 : switch (operation) {
996 : case OPERATION_FIX :
997 : case OPERATION_CHECK :
998 121 : break;
999 : default :
- 1000 143 : if (opt.force_device) {
+ 1000 144 : if (opt.force_device) {
1001 : /* LCOV_EXCL_START */
1002 : log_fatal("You cannot use -D, --force-device with the '%s' command\n", command);
1003 : exit(EXIT_FAILURE);
@@ -1067,13 +1067,13 @@
1005 : }
1006 : }
1007 :
- 1008 264 : switch (operation) {
+ 1008 265 : switch (operation) {
1009 : case OPERATION_SYNC :
1010 : case OPERATION_CHECK :
1011 : case OPERATION_FIX :
1012 210 : break;
1013 : default :
- 1014 54 : if (opt.force_nocopy) {
+ 1014 55 : if (opt.force_nocopy) {
1015 : /* LCOV_EXCL_START */
1016 : log_fatal("You cannot use -N, --force-nocopy with the '%s' command\n", command);
1017 : exit(EXIT_FAILURE);
@@ -1081,25 +1081,25 @@
1019 : }
1020 : }
1021 :
- 1022 264 : switch (operation) {
+ 1022 265 : switch (operation) {
1023 : case OPERATION_SYNC :
1024 89 : break;
1025 : default :
- 1026 175 : if (opt.prehash) {
+ 1026 176 : if (opt.prehash) {
1027 : /* LCOV_EXCL_START */
1028 : log_fatal("You cannot use -h, --pre-hash with the '%s' command\n", command);
1029 : exit(EXIT_FAILURE);
1030 : /* LCOV_EXCL_STOP */
1031 : }
1032 :
- 1033 175 : if (opt.force_full) {
+ 1033 176 : if (opt.force_full) {
1034 : /* LCOV_EXCL_START */
1035 : log_fatal("You cannot use -F, --force-full with the '%s' command\n", command);
1036 : exit(EXIT_FAILURE);
1037 : /* LCOV_EXCL_STOP */
1038 : }
1039 :
- 1040 175 : if (opt.force_realloc) {
+ 1040 176 : if (opt.force_realloc) {
1041 : /* LCOV_EXCL_START */
1042 : log_fatal("You cannot use -R, --force-realloc with the '%s' command\n", command);
1043 : exit(EXIT_FAILURE);
@@ -1107,41 +1107,41 @@
1045 : }
1046 : }
1047 :
- 1048 264 : if (opt.force_full && opt.force_nocopy) {
+ 1048 265 : if (opt.force_full && opt.force_nocopy) {
1049 : /* LCOV_EXCL_START */
1050 : log_fatal("You cannot use the -F, --force-full and -N, --force-nocopy options at the same time\n");
1051 : exit(EXIT_FAILURE);
1052 : /* LCOV_EXCL_STOP */
1053 : }
1054 :
- 1055 264 : if (opt.force_realloc && opt.force_nocopy) {
+ 1055 265 : if (opt.force_realloc && opt.force_nocopy) {
1056 : /* LCOV_EXCL_START */
1057 : log_fatal("You cannot use the -R, --force-realloc and -N, --force-nocopy options at the same time\n");
1058 : exit(EXIT_FAILURE);
1059 : /* LCOV_EXCL_STOP */
1060 : }
1061 :
- 1062 264 : if (opt.force_realloc && opt.force_full) {
+ 1062 265 : if (opt.force_realloc && opt.force_full) {
1063 : /* LCOV_EXCL_START */
1064 : log_fatal("You cannot use the -R, --force-realloc and -F, --force-full options at the same time\n");
1065 : exit(EXIT_FAILURE);
1066 : /* LCOV_EXCL_STOP */
1067 : }
1068 :
- 1069 264 : if (opt.prehash && opt.force_nocopy) {
+ 1069 265 : if (opt.prehash && opt.force_nocopy) {
1070 : /* LCOV_EXCL_START */
1071 : log_fatal("You cannot use the -h, --pre-hash and -N, --force-nocopy options at the same time\n");
1072 : exit(EXIT_FAILURE);
1073 : /* LCOV_EXCL_STOP */
1074 : }
1075 :
- 1076 264 : switch (operation) {
+ 1076 265 : switch (operation) {
1077 : case OPERATION_CHECK :
1078 : case OPERATION_FIX :
1079 : case OPERATION_DRY :
1080 123 : break;
1081 : default :
- 1082 139 : if (!tommy_list_empty(&filterlist_disk)) {
+ 1082 140 : if (!tommy_list_empty(&filterlist_disk)) {
1083 : /* LCOV_EXCL_START */
1084 : log_fatal("You cannot use -d, --filter-disk with the '%s' command\n", command);
1085 : exit(EXIT_FAILURE);
@@ -1150,19 +1150,19 @@
1088 : /* follow */
1089 : case OPERATION_SPINUP :
1090 : case OPERATION_SPINDOWN :
- 1091 141 : if (!tommy_list_empty(&filterlist_file)) {
+ 1091 142 : if (!tommy_list_empty(&filterlist_file)) {
1092 : /* LCOV_EXCL_START */
1093 : log_fatal("You cannot use -f, --filter with the '%s' command\n", command);
1094 : exit(EXIT_FAILURE);
1095 : /* LCOV_EXCL_STOP */
1096 : }
- 1097 141 : if (filter_missing != 0) {
+ 1097 142 : if (filter_missing != 0) {
1098 : /* LCOV_EXCL_START */
1099 : log_fatal("You cannot use -m, --filter-missing with the '%s' command\n", command);
1100 : exit(EXIT_FAILURE);
1101 : /* LCOV_EXCL_STOP */
1102 : }
- 1103 141 : if (filter_error != 0) {
+ 1103 142 : if (filter_error != 0) {
1104 : /* LCOV_EXCL_START */
1105 : log_fatal("You cannot use -e, --filter-error with the '%s' command\n", command);
1106 : exit(EXIT_FAILURE);
@@ -1172,19 +1172,19 @@
1110 :
1111 : /* errors must be always fixed on all disks */
1112 : /* because we don't keep the information on what disk is the error */
- 1113 264 : if (filter_error != 0 && !tommy_list_empty(&filterlist_disk)) {
+ 1113 265 : if (filter_error != 0 && !tommy_list_empty(&filterlist_disk)) {
1114 : /* LCOV_EXCL_START */
1115 : log_fatal("You cannot use -e, --filter-error and -d, --filter-disk at the same time\n");
1116 : exit(EXIT_FAILURE);
1117 : /* LCOV_EXCL_STOP */
1118 : }
1119 :
- 1120 264 : switch (operation) {
+ 1120 265 : switch (operation) {
1121 : case OPERATION_CHECK :
1122 : case OPERATION_FIX :
1123 121 : break;
1124 : default :
- 1125 143 : if (import_timestamp != 0 || import_content != 0) {
+ 1125 144 : if (import_timestamp != 0 || import_content != 0) {
1126 : /* LCOV_EXCL_START */
1127 : log_fatal("You cannot import with the '%s' command\n", command);
1128 : exit(EXIT_FAILURE);
@@ -1192,7 +1192,7 @@
1130 : }
1131 : }
1132 :
- 1133 264 : switch (operation) {
+ 1133 265 : switch (operation) {
1134 : case OPERATION_LIST :
1135 : case OPERATION_DUP :
1136 : case OPERATION_STATUS :
@@ -1205,7 +1205,7 @@
1143 26 : break;
1144 : }
1145 :
- 1146 264 : switch (operation) {
+ 1146 265 : switch (operation) {
1147 : case OPERATION_DIFF :
1148 : case OPERATION_LIST :
1149 : case OPERATION_DUP :
@@ -1217,11 +1217,11 @@
1155 : case OPERATION_TOUCH :
1156 : case OPERATION_SPINUP : /* we want to do it in different threads to avoid blocking */
1157 : /* avoid to check and access parity disks if not needed */
- 1158 37 : opt.skip_parity_access = 1;
- 1159 37 : break;
+ 1158 38 : opt.skip_parity_access = 1;
+ 1159 38 : break;
1160 : }
1161 :
- 1162 264 : switch (operation) {
+ 1162 265 : switch (operation) {
1163 : case OPERATION_FIX :
1164 : case OPERATION_CHECK :
1165 : /* avoid to stop processing if a content file is not accessible */
@@ -1229,7 +1229,7 @@
1167 121 : break;
1168 : }
1169 :
- 1170 264 : switch (operation) {
+ 1170 265 : switch (operation) {
1171 : case OPERATION_DIFF :
1172 : case OPERATION_LIST :
1173 : case OPERATION_DUP :
@@ -1239,11 +1239,11 @@
1177 : case OPERATION_SPINDOWN :
1178 : case OPERATION_DEVICES :
1179 : case OPERATION_SMART :
- 1180 24 : opt.skip_self = 1;
- 1181 24 : break;
+ 1180 25 : opt.skip_self = 1;
+ 1181 25 : break;
1182 : }
1183 :
- 1184 264 : switch (operation) {
+ 1184 265 : switch (operation) {
1185 : #if HAVE_DIRECT_IO
1186 : case OPERATION_SYNC :
1187 : case OPERATION_SCRUB :
@@ -1252,12 +1252,12 @@
1190 : #endif
1191 : default:
1192 : /* we allow direct IO only on some commands */
- 1193 162 : if (opt.file_mode == ADVISE_DIRECT)
+ 1193 163 : if (opt.file_mode == ADVISE_DIRECT)
1194 0 : opt.file_mode = ADVISE_SEQUENTIAL;
- 1195 162 : break;
+ 1195 163 : break;
1196 : }
1197 :
- 1198 264 : switch (operation) {
+ 1198 265 : switch (operation) {
1199 : case OPERATION_DEVICES :
1200 : case OPERATION_SMART :
1201 : /* we may need to use these commands during operations */
@@ -1265,7 +1265,7 @@
1203 3 : break;
1204 : }
1205 :
- 1206 264 : switch (operation) {
+ 1206 265 : switch (operation) {
1207 : case OPERATION_SMART :
1208 : /* allow to run without configuration file */
1209 2 : opt.auto_conf = 1;
@@ -1273,39 +1273,39 @@
1211 : }
1212 :
1213 : /* open the log file */
- 1214 264 : log_open(log_file);
+ 1214 265 : log_open(log_file);
1215 :
1216 : /* print generic info into the log */
- 1217 264 : t = time(0);
- 1218 264 : tm = localtime(&t);
- 1219 264 : log_tag("version:%s\n", PACKAGE_VERSION);
- 1220 264 : log_tag("unixtime:%" PRIi64 "\n", (int64_t)t);
- 1221 264 : if (tm) {
+ 1217 265 : t = time(0);
+ 1218 265 : tm = localtime(&t);
+ 1219 265 : log_tag("version:%s\n", PACKAGE_VERSION);
+ 1220 265 : log_tag("unixtime:%" PRIi64 "\n", (int64_t)t);
+ 1221 265 : if (tm) {
1222 : char datetime[64];
- 1223 264 : strftime(datetime, sizeof(datetime), "%Y-%m-%d %H:%M:%S", tm);
- 1224 264 : log_tag("time:%s\n", datetime);
+ 1223 265 : strftime(datetime, sizeof(datetime), "%Y-%m-%d %H:%M:%S", tm);
+ 1224 265 : log_tag("time:%s\n", datetime);
1225 : }
- 1226 264 : log_tag("command:%s\n", command);
- 1227 4037 : for (i = 0; i < argc; ++i)
- 1228 3773 : log_tag("argv:%u:%s\n", i, argv[i]);
- 1229 264 : log_flush();
+ 1226 265 : log_tag("command:%s\n", command);
+ 1227 4052 : for (i = 0; i < argc; ++i)
+ 1228 3787 : log_tag("argv:%u:%s\n", i, argv[i]);
+ 1229 265 : log_flush();
1230 :
- 1231 264 : if (!opt.skip_self)
+ 1231 265 : if (!opt.skip_self)
1232 1 : selftest();
1233 :
- 1234 264 : state_init(&state);
+ 1234 265 : state_init(&state);
1235 :
1236 : /* read the configuration file */
- 1237 264 : state_config(&state, conf, command, &opt, &filterlist_disk);
+ 1237 265 : state_config(&state, conf, command, &opt, &filterlist_disk);
1238 :
1239 : /* set the raid mode */
- 1240 263 : raid_mode(state.raid_mode);
+ 1240 264 : raid_mode(state.raid_mode);
1241 :
1242 : #if HAVE_LOCKFILE
1243 : /* create the lock file */
- 1244 263 : if (!opt.skip_lock && state.lockfile[0]) {
- 1245 260 : lock = lock_lock(state.lockfile);
- 1246 260 : if (lock == -1) {
+ 1244 264 : if (!opt.skip_lock && state.lockfile[0]) {
+ 1245 261 : lock = lock_lock(state.lockfile);
+ 1246 261 : if (lock == -1) {
1247 : /* LCOV_EXCL_START */
1248 : if (errno != EWOULDBLOCK) {
1249 : log_fatal("Error creating the lock file '%s'. %s.\n", state.lockfile, strerror(errno));
@@ -1321,14 +1321,14 @@
1259 : (void)lock;
1260 : #endif
1261 :
- 1262 263 : if (operation == OPERATION_DIFF) {
- 1263 7 : state_read(&state);
+ 1262 264 : if (operation == OPERATION_DIFF) {
+ 1263 8 : state_read(&state);
1264 :
- 1265 7 : ret = state_diff(&state);
+ 1265 8 : ret = state_diff(&state);
1266 :
1267 : /* abort if sync needed */
- 1268 7 : if (ret > 0)
- 1269 6 : exit(EXIT_SYNC_NEEDED);
+ 1268 8 : if (ret > 0)
+ 1269 7 : exit(EXIT_SYNC_NEEDED);
1270 256 : } else if (operation == OPERATION_SYNC) {
1271 :
1272 : /* in the next state read ensures to clear all the past hashes in case */
diff --git a/cov/cmdline/speed.c.func-sort-c.html b/cov/cmdline/speed.c.func-sort-c.html
index cf9aeb8c..e9db88b7 100644
--- a/cov/cmdline/speed.c.func-sort-c.html
+++ b/cov/cmdline/speed.c.func-sort-c.html
@@ -61,7 +61,7 @@
| diffgettimeofday |
- 1840 |
+ 1834 |
| speed |
diff --git a/cov/cmdline/speed.c.func.html b/cov/cmdline/speed.c.func.html
index 5fd0a53c..dc809ae1 100644
--- a/cov/cmdline/speed.c.func.html
+++ b/cov/cmdline/speed.c.func.html
@@ -61,7 +61,7 @@
| diffgettimeofday |
- 1840 |
+ 1834 |
| speed |
diff --git a/cov/cmdline/speed.c.gcov.html b/cov/cmdline/speed.c.gcov.html
index 53e5330e..e039e006 100644
--- a/cov/cmdline/speed.c.gcov.html
+++ b/cov/cmdline/speed.c.gcov.html
@@ -100,14 +100,14 @@
38 : /**
39 : * Differential us of two timeval.
40 : */
- 41 1840 : static int64_t diffgettimeofday(struct timeval *start, struct timeval *stop)
+ 41 1834 : static int64_t diffgettimeofday(struct timeval *start, struct timeval *stop)
42 : {
43 : int64_t d;
44 :
- 45 1840 : d = 1000000LL * (stop->tv_sec - start->tv_sec);
- 46 1840 : d += stop->tv_usec - start->tv_usec;
+ 45 1834 : d = 1000000LL * (stop->tv_sec - start->tv_sec);
+ 46 1834 : d += stop->tv_usec - start->tv_usec;
47 :
- 48 1840 : return d;
+ 48 1834 : return d;
49 : }
50 :
51 : /**
@@ -232,10 +232,10 @@
170 4 : printf("%8s", "memset");
171 4 : fflush(stdout);
172 :
- 173 380 : SPEED_START {
- 174 3384 : for (j = 0; j < nd; ++j)
- 175 3008 : memset(v[j], j, size);
- 176 376 : } SPEED_STOP
+ 173 386 : SPEED_START {
+ 174 3438 : for (j = 0; j < nd; ++j)
+ 175 3056 : memset(v[j], j, size);
+ 176 382 : } 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 47 : SPEED_START {
- 189 387 : for (j = 0; j < nd; ++j)
- 190 344 : side_effect += crc32c_gen(0, v[j], size);
- 191 43 : } SPEED_STOP
+ 188 45 : SPEED_START {
+ 189 369 : for (j = 0; j < nd; ++j)
+ 190 328 : side_effect += crc32c_gen(0, v[j], size);
+ 191 41 : } SPEED_STOP
192 :
193 4 : printf("%8" PRIu64, ds / dt);
194 4 : printf("\n");
@@ -260,10 +260,10 @@
198 :
199 : #if HAVE_SSE42
200 4 : if (raid_cpu_has_crc32()) {
- 201 60 : SPEED_START {
- 202 522 : for (j = 0; j < nd; ++j)
- 203 464 : side_effect += crc32c_x86(0, v[j], size);
- 204 58 : } SPEED_STOP
+ 201 59 : SPEED_START {
+ 202 513 : for (j = 0; j < nd; ++j)
+ 203 456 : side_effect += crc32c_x86(0, v[j], size);
+ 204 57 : } SPEED_STOP
205 :
206 2 : printf("%8" PRIu64, ds / dt);
207 : }
@@ -341,16 +341,16 @@
279 :
280 4 : printf("%8s", "");
281 :
- 282 113 : SPEED_START {
- 283 109 : raid_gen1_int32(nd, size, v);
- 284 109 : } SPEED_STOP
+ 282 118 : SPEED_START {
+ 283 114 : raid_gen1_int32(nd, size, v);
+ 284 114 : } SPEED_STOP
285 :
286 4 : printf("%8" PRIu64, ds / dt);
287 4 : fflush(stdout);
288 :
- 289 185 : SPEED_START {
- 290 181 : raid_gen1_int64(nd, size, v);
- 291 181 : } SPEED_STOP
+ 289 183 : SPEED_START {
+ 290 179 : raid_gen1_int64(nd, size, v);
+ 291 179 : } SPEED_STOP
292 :
293 4 : printf("%8" PRIu64, ds / dt);
294 4 : fflush(stdout);
@@ -358,9 +358,9 @@
296 : #ifdef CONFIG_X86
297 : #ifdef CONFIG_SSE2
298 4 : if (raid_cpu_has_sse2()) {
- 299 303 : SPEED_START {
- 300 299 : raid_gen1_sse2(nd, size, v);
- 301 299 : } SPEED_STOP
+ 299 304 : SPEED_START {
+ 300 300 : raid_gen1_sse2(nd, size, v);
+ 301 300 : } SPEED_STOP
302 :
303 4 : printf("%8" PRIu64, ds / dt);
304 4 : fflush(stdout);
@@ -401,9 +401,9 @@
339 4 : printf("%8" PRIu64, ds / dt);
340 4 : fflush(stdout);
341 :
- 342 48 : SPEED_START {
- 343 44 : raid_gen2_int64(nd, size, v);
- 344 44 : } SPEED_STOP
+ 342 46 : SPEED_START {
+ 343 42 : raid_gen2_int64(nd, size, v);
+ 344 42 : } SPEED_STOP
345 :
346 4 : printf("%8" PRIu64, ds / dt);
347 4 : fflush(stdout);
@@ -411,9 +411,9 @@
349 : #ifdef CONFIG_X86
350 : #ifdef CONFIG_SSE2
351 4 : if (raid_cpu_has_sse2()) {
- 352 144 : SPEED_START {
- 353 140 : raid_gen2_sse2(nd, size, v);
- 354 140 : } SPEED_STOP
+ 352 141 : SPEED_START {
+ 353 137 : raid_gen2_sse2(nd, size, v);
+ 354 137 : } SPEED_STOP
355 :
356 4 : printf("%8" PRIu64, ds / dt);
357 4 : fflush(stdout);
@@ -453,9 +453,9 @@
391 :
392 4 : printf("%8s", "");
393 :
- 394 32 : SPEED_START {
- 395 28 : raid_genz_int32(nd, size, v);
- 396 28 : } SPEED_STOP
+ 394 31 : SPEED_START {
+ 395 27 : raid_genz_int32(nd, size, v);
+ 396 27 : } SPEED_STOP
397 :
398 4 : printf("%8" PRIu64, ds / dt);
399 4 : fflush(stdout);
@@ -470,9 +470,9 @@
408 : #ifdef CONFIG_X86
409 : #ifdef CONFIG_SSE2
410 4 : if (raid_cpu_has_sse2()) {
- 411 86 : SPEED_START {
- 412 82 : raid_genz_sse2(nd, size, v);
- 413 82 : } SPEED_STOP
+ 411 85 : SPEED_START {
+ 412 81 : raid_genz_sse2(nd, size, v);
+ 413 81 : } SPEED_STOP
414 :
415 4 : printf("%8" PRIu64, ds / dt);
416 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 52 : SPEED_START {
+ 479 49 : raid_gen3_ssse3(nd, size, v);
+ 480 49 : } 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 36 : SPEED_START {
- 544 33 : raid_gen4_ssse3(nd, size, v);
- 545 33 : } SPEED_STOP
+ 543 35 : SPEED_START {
+ 544 32 : raid_gen4_ssse3(nd, size, v);
+ 545 32 : } SPEED_STOP
546 :
547 3 : printf("%8" PRIu64, ds / dt);
548 3 : fflush(stdout);
@@ -642,9 +642,9 @@
580 4 : printf("%8s", raid_gen5_tag());
581 4 : fflush(stdout);
582 :
- 583 12 : SPEED_START {
- 584 8 : raid_gen5_int8(nd, size, v);
- 585 8 : } SPEED_STOP
+ 583 11 : SPEED_START {
+ 584 7 : raid_gen5_int8(nd, size, v);
+ 585 7 : } SPEED_STOP
586 :
587 4 : printf("%8" PRIu64, ds / dt);
588 4 : fflush(stdout);
@@ -667,9 +667,9 @@
605 : #ifdef CONFIG_X86
606 : #ifdef CONFIG_SSSE3
607 4 : if (raid_cpu_has_ssse3()) {
- 608 25 : SPEED_START {
- 609 22 : raid_gen5_ssse3(nd, size, v);
- 610 22 : } SPEED_STOP
+ 608 24 : SPEED_START {
+ 609 21 : raid_gen5_ssse3(nd, size, v);
+ 610 21 : } 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 11 : SPEED_START {
- 649 7 : raid_gen6_int8(nd, size, v);
- 650 7 : } SPEED_STOP
+ 648 9 : SPEED_START {
+ 649 5 : raid_gen6_int8(nd, size, v);
+ 650 5 : } 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 6c0e404b..41e92e89 100644
--- a/cov/cmdline/spooky2.c.func-sort-c.html
+++ b/cov/cmdline/spooky2.c.func-sort-c.html
@@ -61,7 +61,7 @@
| SpookyHash128 |
- 3860981 |
+ 3861869 |
diff --git a/cov/cmdline/spooky2.c.func.html b/cov/cmdline/spooky2.c.func.html
index 3324da70..09b225e7 100644
--- a/cov/cmdline/spooky2.c.func.html
+++ b/cov/cmdline/spooky2.c.func.html
@@ -61,7 +61,7 @@
| SpookyHash128 |
- 3860981 |
+ 3861869 |
diff --git a/cov/cmdline/spooky2.c.gcov.html b/cov/cmdline/spooky2.c.gcov.html
index 4af0687c..6fe692aa 100644
--- a/cov/cmdline/spooky2.c.gcov.html
+++ b/cov/cmdline/spooky2.c.gcov.html
@@ -170,7 +170,7 @@
108 : //
109 : #define sc_const 0xdeadbeefdeadbeefLL
110 :
- 111 3860981 : void SpookyHash128(const void* data, size_t size, const uint8_t* seed, uint8_t* digest)
+ 111 3861869 : 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];
@@ -183,39 +183,39 @@
121 : unsigned i;
122 : #endif
123 :
- 124 3860981 : h9 = ((const uint64_t*)seed)[0];
- 125 3860981 : h10 = ((const uint64_t*)seed)[1];
+ 124 3861869 : h9 = ((const uint64_t*)seed)[0];
+ 125 3861869 : h10 = ((const uint64_t*)seed)[1];
126 :
127 : #if WORDS_BIGENDIAN
128 : h9 = util_swap64(h9);
129 : h10 = util_swap64(h10);
130 : #endif
131 :
- 132 3860981 : h0 = h3 = h6 = h9;
- 133 3860981 : h1 = h4 = h7 = h10;
- 134 3860981 : h2 = h5 = h8 = h11 = sc_const;
+ 132 3861869 : h0 = h3 = h6 = h9;
+ 133 3861869 : h1 = h4 = h7 = h10;
+ 134 3861869 : h2 = h5 = h8 = h11 = sc_const;
135 :
- 136 3860981 : nblocks = size / sc_blockSize;
- 137 3860981 : blocks = data;
- 138 3860981 : end = blocks + nblocks * sc_numVars;
+ 136 3861869 : nblocks = size / sc_blockSize;
+ 137 3861869 : blocks = data;
+ 138 3861869 : end = blocks + nblocks * sc_numVars;
139 :
140 : /* body */
- 141 38823778 : while (blocks < end) {
+ 141 38833261 : while (blocks < end) {
142 : #if WORDS_BIGENDIAN
143 : for (i = 0; i < sc_numVars; ++i)
144 : buf[i] = util_swap64(blocks[i]);
145 : Mix(buf, h0, h1, h2, h3, h4, h5, h6, h7, h8, h9, h10, h11);
146 : #else
- 147 31101816 : Mix(blocks, h0, h1, h2, h3, h4, h5, h6, h7, h8, h9, h10, h11);
+ 147 31109523 : Mix(blocks, h0, h1, h2, h3, h4, h5, h6, h7, h8, h9, h10, h11);
148 : #endif
- 149 31101816 : blocks += sc_numVars;
+ 149 31109523 : blocks += sc_numVars;
150 : }
151 :
152 : /* tail */
- 153 3860981 : size_remainder = (size - ((const uint8_t*)end - (const uint8_t*)data));
- 154 3860981 : memcpy(buf, end, size_remainder);
- 155 3860981 : memset(((uint8_t*)buf) + size_remainder, 0, sc_blockSize - size_remainder);
- 156 3860981 : ((uint8_t*)buf)[sc_blockSize - 1] = size_remainder;
+ 153 3861869 : size_remainder = (size - ((const uint8_t*)end - (const uint8_t*)data));
+ 154 3861869 : memcpy(buf, end, size_remainder);
+ 155 3861869 : memset(((uint8_t*)buf) + size_remainder, 0, sc_blockSize - size_remainder);
+ 156 3861869 : ((uint8_t*)buf)[sc_blockSize - 1] = size_remainder;
157 :
158 : /* finalization */
159 : #if WORDS_BIGENDIAN
@@ -223,16 +223,16 @@
161 : buf[i] = util_swap64(buf[i]);
162 : #endif
163 :
- 164 3860981 : End(buf, h0, h1, h2, h3, h4, h5, h6, h7, h8, h9, h10, h11);
+ 164 3861869 : End(buf, h0, h1, h2, h3, h4, h5, h6, h7, h8, h9, h10, h11);
165 :
166 : #if WORDS_BIGENDIAN
167 : h0 = util_swap64(h0);
168 : h1 = util_swap64(h1);
169 : #endif
170 :
- 171 3860981 : ((uint64_t*)digest)[0] = h0;
- 172 3860981 : ((uint64_t*)digest)[1] = h1;
- 173 3860981 : }
+ 171 3861869 : ((uint64_t*)digest)[0] = h0;
+ 172 3861869 : ((uint64_t*)digest)[1] = h1;
+ 173 3861869 : }
174 :
diff --git a/cov/cmdline/state.c.func-sort-c.html b/cov/cmdline/state.c.func-sort-c.html
index 69b487d1..a21de965 100644
--- a/cov/cmdline/state.c.func-sort-c.html
+++ b/cov/cmdline/state.c.func-sort-c.html
@@ -65,27 +65,27 @@
| fs_info_is_required |
- 1547811 |
+ 1547867 |
| state_progress |
- 1073409 |
+ 1073497 |
| state_usage_misc |
- 1063055 |
+ 1063671 |
| state_usage_disk |
- 912357 |
+ 912885 |
| state_usage_hash |
- 776808 |
+ 777357 |
| state_usage_parity |
- 774023 |
+ 774551 |
| fs_position_is_required |
@@ -93,23 +93,23 @@
| lev_config_name |
- 186548 |
+ 186570 |
| state_usage_sched |
- 149836 |
+ 149924 |
| state_usage_raid |
- 140365 |
+ 140438 |
| find_disk_by_name |
- 7021 |
+ 7037 |
| lev_config_scan |
- 6301 |
+ 6318 |
| state_verify_thread |
@@ -117,11 +117,11 @@
| state_fscheck |
- 496 |
+ 498 |
| state_progress_latest |
- 495 |
+ 477 |
| validate_smartctl |
@@ -129,35 +129,35 @@
| state_init |
- 265 |
+ 266 |
| state_config |
- 264 |
+ 265 |
| lev_raid_name |
- 263 |
+ 264 |
| state_config_check |
- 263 |
+ 264 |
| state_read |
- 259 |
+ 260 |
| state_map |
- 258 |
+ 259 |
| state_read_content |
- 252 |
+ 253 |
| state_content_check |
- 251 |
+ 252 |
| state_done |
diff --git a/cov/cmdline/state.c.func.html b/cov/cmdline/state.c.func.html
index 4ee01dd6..e633e134 100644
--- a/cov/cmdline/state.c.func.html
+++ b/cov/cmdline/state.c.func.html
@@ -65,7 +65,7 @@
| find_disk_by_name |
- 7021 |
+ 7037 |
| find_disk_by_uuid |
@@ -73,7 +73,7 @@
| fs_info_is_required |
- 1547811 |
+ 1547867 |
| fs_is_block_deleted |
@@ -93,11 +93,11 @@
| lev_config_name |
- 186548 |
+ 186570 |
| lev_config_scan |
- 6301 |
+ 6318 |
| lev_name |
@@ -105,19 +105,19 @@
| lev_raid_name |
- 263 |
-
-
- | state_config |
264 |
+
+ | state_config |
+ 265 |
+
| state_config_check |
- 263 |
+ 264 |
| state_content_check |
- 251 |
+ 252 |
| state_done |
@@ -129,19 +129,19 @@
| state_fscheck |
- 496 |
+ 498 |
| state_init |
- 265 |
+ 266 |
| state_map |
- 258 |
+ 259 |
| state_progress |
- 1073409 |
+ 1073497 |
| state_progress_begin |
@@ -157,7 +157,7 @@
| state_progress_latest |
- 495 |
+ 477 |
| state_progress_restart |
@@ -169,11 +169,11 @@
| state_read |
- 259 |
+ 260 |
| state_read_content |
- 252 |
+ 253 |
| state_refresh |
@@ -189,19 +189,19 @@
| state_usage_disk |
- 912357 |
+ 912885 |
| state_usage_hash |
- 776808 |
+ 777357 |
| state_usage_misc |
- 1063055 |
+ 1063671 |
| state_usage_parity |
- 774023 |
+ 774551 |
| state_usage_print |
@@ -209,11 +209,11 @@
| state_usage_raid |
- 140365 |
+ 140438 |
| state_usage_sched |
- 149836 |
+ 149924 |
| state_usage_waste |
diff --git a/cov/cmdline/state.c.gcov.html b/cov/cmdline/state.c.gcov.html
index c9beeecb..b088ec7a 100644
--- a/cov/cmdline/state.c.gcov.html
+++ b/cov/cmdline/state.c.gcov.html
@@ -125,10 +125,10 @@
63 0 : return 0;
64 : }
65 :
- 66 186548 : const char* lev_config_name(unsigned l)
+ 66 186570 : const char* lev_config_name(unsigned l)
67 : {
- 68 186548 : switch (l) {
- 69 86846 : case 0 : return "parity";
+ 68 186570 : switch (l) {
+ 69 86868 : case 0 : return "parity";
70 60620 : case 1 : return "2-parity";
71 9810 : case 2 : return "3-parity";
72 9785 : case 3 : return "4-parity";
@@ -139,52 +139,52 @@
77 0 : return 0;
78 : }
79 :
- 80 6301 : static int lev_config_scan(const char* s, unsigned* level, unsigned* mode)
+ 80 6318 : static int lev_config_scan(const char* s, unsigned* level, unsigned* mode)
81 : {
- 82 6301 : if (strcmp(s, "parity") == 0 || strcmp(s, "1-parity") == 0) {
- 83 446 : *level = 0;
- 84 446 : return 0;
+ 82 6318 : if (strcmp(s, "parity") == 0 || strcmp(s, "1-parity") == 0) {
+ 83 447 : *level = 0;
+ 84 447 : return 0;
85 : }
86 :
- 87 5855 : if (strcmp(s, "q-parity") == 0 || strcmp(s, "2-parity") == 0) {
+ 87 5871 : if (strcmp(s, "q-parity") == 0 || strcmp(s, "2-parity") == 0) {
88 224 : *level = 1;
89 224 : return 0;
90 : }
91 :
- 92 5631 : if (strcmp(s, "r-parity") == 0 || strcmp(s, "3-parity") == 0) {
+ 92 5647 : if (strcmp(s, "r-parity") == 0 || strcmp(s, "3-parity") == 0) {
93 199 : *level = 2;
94 199 : return 0;
95 : }
96 :
- 97 5432 : if (strcmp(s, "4-parity") == 0) {
+ 97 5448 : if (strcmp(s, "4-parity") == 0) {
98 196 : *level = 3;
99 196 : return 0;
100 : }
101 :
- 102 5236 : if (strcmp(s, "5-parity") == 0) {
+ 102 5252 : if (strcmp(s, "5-parity") == 0) {
103 193 : *level = 4;
104 193 : return 0;
105 : }
106 :
- 107 5043 : if (strcmp(s, "6-parity") == 0) {
+ 107 5059 : if (strcmp(s, "6-parity") == 0) {
108 189 : *level = 5;
109 189 : return 0;
110 : }
111 :
- 112 4854 : if (strcmp(s, "z-parity") == 0) {
+ 112 4870 : if (strcmp(s, "z-parity") == 0) {
113 0 : *level = 2;
114 0 : if (mode)
115 0 : *mode = RAID_MODE_VANDERMONDE;
116 0 : return 0;
117 : }
118 :
- 119 4854 : return -1;
+ 119 4870 : return -1;
120 : }
121 :
- 122 263 : const char* lev_raid_name(unsigned mode, unsigned n)
+ 122 264 : const char* lev_raid_name(unsigned mode, unsigned n)
123 : {
- 124 263 : switch (n) {
- 125 40 : case 1 : return "par1";
+ 124 264 : switch (n) {
+ 125 41 : case 1 : return "par1";
126 25 : case 2 : return "par2";
127 3 : case 3 : if (mode == RAID_MODE_CAUCHY)
128 3 : return "par3";
@@ -198,58 +198,58 @@
136 0 : return 0;
137 : }
138 :
- 139 265 : void state_init(struct snapraid_state* state)
+ 139 266 : void state_init(struct snapraid_state* state)
140 : {
141 : unsigned l, s;
142 :
- 143 265 : memset(&state->opt, 0, sizeof(state->opt));
- 144 265 : state->filter_hidden = 0;
- 145 265 : state->autosave = 0;
- 146 265 : state->need_write = 0;
- 147 265 : state->checked_read = 0;
- 148 265 : state->block_size = 256 * KIBI; /* default 256 KiB */
- 149 265 : state->raid_mode = RAID_MODE_CAUCHY;
- 150 265 : state->file_mode = ADVISE_DEFAULT;
- 151 1855 : for (l = 0; l < LEV_MAX; ++l) {
- 152 1590 : state->parity[l].split_mac = 0;
- 153 14310 : for (s = 0; s < SPLIT_MAX; ++s) {
- 154 12720 : state->parity[l].split_map[s].path[0] = 0;
- 155 12720 : state->parity[l].split_map[s].uuid[0] = 0;
- 156 12720 : state->parity[l].split_map[s].size = PARITY_SIZE_INVALID;
- 157 12720 : state->parity[l].split_map[s].device = 0;
+ 143 266 : memset(&state->opt, 0, sizeof(state->opt));
+ 144 266 : state->filter_hidden = 0;
+ 145 266 : state->autosave = 0;
+ 146 266 : state->need_write = 0;
+ 147 266 : state->checked_read = 0;
+ 148 266 : state->block_size = 256 * KIBI; /* default 256 KiB */
+ 149 266 : state->raid_mode = RAID_MODE_CAUCHY;
+ 150 266 : state->file_mode = ADVISE_DEFAULT;
+ 151 1862 : for (l = 0; l < LEV_MAX; ++l) {
+ 152 1596 : state->parity[l].split_mac = 0;
+ 153 14364 : for (s = 0; s < SPLIT_MAX; ++s) {
+ 154 12768 : state->parity[l].split_map[s].path[0] = 0;
+ 155 12768 : state->parity[l].split_map[s].uuid[0] = 0;
+ 156 12768 : state->parity[l].split_map[s].size = PARITY_SIZE_INVALID;
+ 157 12768 : state->parity[l].split_map[s].device = 0;
158 : }
- 159 1590 : state->parity[l].smartctl[0] = 0;
- 160 1590 : state->parity[l].total_blocks = 0;
- 161 1590 : state->parity[l].free_blocks = 0;
- 162 1590 : state->parity[l].skip_access = 0;
- 163 1590 : state->parity[l].tick = 0;
- 164 1590 : state->parity[l].cached = 0;
- 165 1590 : state->parity[l].is_excluded = 0;
+ 159 1596 : state->parity[l].smartctl[0] = 0;
+ 160 1596 : state->parity[l].total_blocks = 0;
+ 161 1596 : state->parity[l].free_blocks = 0;
+ 162 1596 : state->parity[l].skip_access = 0;
+ 163 1596 : state->parity[l].tick = 0;
+ 164 1596 : state->parity[l].cached = 0;
+ 165 1596 : state->parity[l].is_excluded = 0;
166 : }
- 167 265 : state->tick_io = 0;
- 168 265 : state->tick_misc = 0;
- 169 265 : state->tick_sched = 0;
- 170 265 : state->tick_raid = 0;
- 171 265 : state->tick_hash = 0;
- 172 265 : state->tick_last = tick();
- 173 265 : state->share[0] = 0;
- 174 265 : state->pool[0] = 0;
- 175 265 : state->pool_device = 0;
- 176 265 : state->lockfile[0] = 0;
- 177 265 : state->level = 1; /* default is the lowest protection */
- 178 265 : state->clear_past_hash = 0;
- 179 265 : state->no_conf = 0;
+ 167 266 : state->tick_io = 0;
+ 168 266 : state->tick_misc = 0;
+ 169 266 : state->tick_sched = 0;
+ 170 266 : state->tick_raid = 0;
+ 171 266 : state->tick_hash = 0;
+ 172 266 : state->tick_last = tick();
+ 173 266 : state->share[0] = 0;
+ 174 266 : state->pool[0] = 0;
+ 175 266 : state->pool_device = 0;
+ 176 266 : state->lockfile[0] = 0;
+ 177 266 : state->level = 1; /* default is the lowest protection */
+ 178 266 : state->clear_past_hash = 0;
+ 179 266 : state->no_conf = 0;
180 :
- 181 265 : tommy_list_init(&state->disklist);
- 182 265 : tommy_list_init(&state->maplist);
- 183 265 : tommy_list_init(&state->contentlist);
- 184 265 : tommy_list_init(&state->filterlist);
- 185 265 : tommy_list_init(&state->importlist);
- 186 265 : tommy_hashdyn_init(&state->importset);
- 187 265 : tommy_hashdyn_init(&state->previmportset);
- 188 265 : tommy_hashdyn_init(&state->searchset);
- 189 265 : tommy_arrayblkof_init(&state->infoarr, sizeof(snapraid_info));
- 190 265 : }
+ 181 266 : tommy_list_init(&state->disklist);
+ 182 266 : tommy_list_init(&state->maplist);
+ 183 266 : tommy_list_init(&state->contentlist);
+ 184 266 : tommy_list_init(&state->filterlist);
+ 185 266 : tommy_list_init(&state->importlist);
+ 186 266 : tommy_hashdyn_init(&state->importset);
+ 187 266 : tommy_hashdyn_init(&state->previmportset);
+ 188 266 : tommy_hashdyn_init(&state->searchset);
+ 189 266 : tommy_arrayblkof_init(&state->infoarr, sizeof(snapraid_info));
+ 190 266 : }
191 :
192 243 : void state_done(struct snapraid_state* state)
193 : {
@@ -268,13 +268,13 @@
206 : /**
207 : * Check the configuration.
208 : */
- 209 263 : static void state_config_check(struct snapraid_state* state, const char* path, tommy_list* filterlist_disk)
+ 209 264 : static void state_config_check(struct snapraid_state* state, const char* path, tommy_list* filterlist_disk)
210 : {
211 : tommy_node* i;
212 : unsigned l, s;
213 :
214 : /* check for parity level */
- 215 263 : if (state->raid_mode == RAID_MODE_VANDERMONDE) {
+ 215 264 : if (state->raid_mode == RAID_MODE_VANDERMONDE) {
216 0 : if (state->level > 3) {
217 : /* LCOV_EXCL_START */
218 : log_fatal("If you use the z-parity you cannot have more than 3 parities.\n");
@@ -292,7 +292,7 @@
230 : }
231 : }
232 :
- 233 263 : if (tommy_list_empty(&state->contentlist)) {
+ 233 264 : if (tommy_list_empty(&state->contentlist)) {
234 : /* LCOV_EXCL_START */
235 : log_fatal("No 'content' specification in '%s'\n", path);
236 : exit(EXIT_FAILURE);
@@ -300,12 +300,12 @@
238 : }
239 :
240 : /* check for equal paths */
- 241 1785 : for (i = state->contentlist; i != 0; i = i->next) {
- 242 1522 : struct snapraid_content* content = i->data;
+ 241 1788 : for (i = state->contentlist; i != 0; i = i->next) {
+ 242 1524 : struct snapraid_content* content = i->data;
243 :
- 244 9864 : for (l = 0; l < state->level; ++l) {
- 245 41710 : for (s = 0; s < state->parity[l].split_mac; ++s) {
- 246 33368 : if (pathcmp(state->parity[l].split_map[s].path, content->content) == 0) {
+ 244 9868 : for (l = 0; l < state->level; ++l) {
+ 245 41720 : for (s = 0; s < state->parity[l].split_mac; ++s) {
+ 246 33376 : if (pathcmp(state->parity[l].split_map[s].path, content->content) == 0) {
247 : /* LCOV_EXCL_START */
248 : log_fatal("Same path used for '%s' and 'content' as '%s'\n", lev_config_name(l), content->content);
249 : exit(EXIT_FAILURE);
@@ -316,7 +316,7 @@
254 : }
255 :
256 : /* check device of data disks */
- 257 263 : if (!state->opt.skip_device && !state->opt.skip_disk_access) {
+ 257 264 : if (!state->opt.skip_device && !state->opt.skip_disk_access) {
258 0 : for (i = state->disklist; i != 0; i = i->next) {
259 : tommy_node* j;
260 0 : struct snapraid_disk* disk = i->data;
@@ -401,7 +401,7 @@
339 : }
340 :
341 : /* check device of parity disks */
- 342 263 : if (!state->opt.skip_device && !state->opt.skip_parity_access) {
+ 342 264 : if (!state->opt.skip_device && !state->opt.skip_parity_access) {
343 0 : for (l = 0; l < state->level; ++l) {
344 0 : for (s = 0; s < state->parity[l].split_mac; ++s) {
345 : unsigned j,t;
@@ -481,7 +481,7 @@
419 : #endif
420 :
421 : /* count the content files */
- 422 263 : if (!state->opt.skip_device && !state->opt.skip_content_access) {
+ 422 264 : if (!state->opt.skip_device && !state->opt.skip_content_access) {
423 : unsigned content_count;
424 :
425 0 : content_count = 0;
@@ -514,7 +514,7 @@
452 :
453 : /* check for speed */
454 : #ifdef CONFIG_X86
- 455 263 : if (!raid_cpu_has_ssse3())
+ 455 264 : if (!raid_cpu_has_ssse3())
456 : #endif
457 0 : if (state->raid_mode == RAID_MODE_CAUCHY && !state->opt.no_warnings) {
458 0 : if (state->level == 3) {
@@ -527,7 +527,7 @@
465 : }
466 :
467 : /* ensure that specified filter disks are valid ones */
- 468 273 : for (i = tommy_list_head(filterlist_disk); i != 0; i = i->next) {
+ 468 274 : for (i = tommy_list_head(filterlist_disk); i != 0; i = i->next) {
469 : tommy_node* j;
470 10 : struct snapraid_filter* filter = i->data;
471 51 : for (j = state->disklist; j != 0; j = j->next) {
@@ -548,7 +548,7 @@
486 : }
487 : }
488 : }
- 489 263 : }
+ 489 264 : }
490 :
491 : /**
492 : * Validate the smartctl command.
@@ -580,7 +580,7 @@
518 364 : return 0;
519 : }
520 :
- 521 264 : void state_config(struct snapraid_state* state, const char* path, const char* command, struct snapraid_option* opt, tommy_list* filterlist_disk)
+ 521 265 : void state_config(struct snapraid_state* state, const char* path, const char* command, struct snapraid_option* opt, tommy_list* filterlist_disk)
522 : {
523 : STREAM* f;
524 : unsigned line;
@@ -588,27 +588,27 @@
526 : unsigned l, s;
527 :
528 : /* copy the options */
- 529 264 : state->opt = *opt;
+ 529 265 : state->opt = *opt;
530 :
531 : /* if unset, sort by physical order */
- 532 264 : if (!state->opt.force_order)
+ 532 265 : if (!state->opt.force_order)
533 1 : state->opt.force_order = SORT_PHYSICAL;
534 :
535 : /* adjust file mode */
- 536 264 : if (state->opt.file_mode != ADVISE_DEFAULT) {
+ 536 265 : if (state->opt.file_mode != ADVISE_DEFAULT) {
537 4 : state->file_mode = state->opt.file_mode;
538 : } else {
539 : /* default mode, if nothing is specified */
- 540 260 : state->file_mode = ADVISE_FLUSH;
+ 540 261 : state->file_mode = ADVISE_FLUSH;
541 : }
542 :
543 : /* store current command */
- 544 264 : state->command = command;
+ 544 265 : state->command = command;
545 :
- 546 264 : log_tag("conf:file:%s\n", path);
+ 546 265 : log_tag("conf:file:%s\n", path);
547 :
- 548 264 : f = sopen_read(path);
- 549 264 : if (!f) {
+ 548 265 : f = sopen_read(path);
+ 549 265 : if (!f) {
550 : /* LCOV_EXCL_START */
551 : if (errno == ENOENT) {
552 : if (state->opt.auto_conf) {
@@ -629,7 +629,7 @@
567 : /* LCOV_EXCL_STOP */
568 : }
569 :
- 570 264 : line = 1;
+ 570 265 : line = 1;
571 : while (1) {
572 : char tag[PATH_MAX];
573 : char buffer[PATH_MAX];
@@ -638,11 +638,11 @@
576 : unsigned level;
577 :
578 : /* skip initial spaces */
- 579 6201 : sgetspace(f);
+ 579 6219 : sgetspace(f);
580 :
581 : /* read the command */
- 582 6201 : ret = sgettok(f, tag, sizeof(tag));
- 583 6201 : if (ret < 0) {
+ 582 6219 : ret = sgettok(f, tag, sizeof(tag));
+ 583 6219 : if (ret < 0) {
584 : /* LCOV_EXCL_START */
585 : log_fatal("Error reading the configuration file '%s' at line %u\n", path, line);
586 : exit(EXIT_FAILURE);
@@ -650,40 +650,40 @@
588 : }
589 :
590 : /* skip spaces after the command */
- 591 6201 : sgetspace(f);
+ 591 6219 : sgetspace(f);
592 :
- 593 6201 : if (strcmp(tag, "blocksize") == 0
+ 593 6219 : if (strcmp(tag, "blocksize") == 0
594 : /* block_size is the old format of the option */
- 595 5937 : || strcmp(tag, "block_size") == 0) {
+ 595 5954 : || strcmp(tag, "block_size") == 0) {
596 :
- 597 264 : ret = sgetu32(f, &state->block_size);
- 598 264 : if (ret < 0) {
+ 597 265 : ret = sgetu32(f, &state->block_size);
+ 598 265 : if (ret < 0) {
599 : /* LCOV_EXCL_START */
600 : log_fatal("Invalid 'blocksize' specification in '%s' at line %u\n", path, line);
601 : exit(EXIT_FAILURE);
602 : /* LCOV_EXCL_STOP */
603 : }
- 604 264 : if (state->block_size < 1) {
+ 604 265 : if (state->block_size < 1) {
605 : /* LCOV_EXCL_START */
606 : log_fatal("Too small 'blocksize' specification in '%s' at line %u\n", path, line);
607 : exit(EXIT_FAILURE);
608 : /* LCOV_EXCL_STOP */
609 : }
- 610 264 : if (state->block_size > 16 * KIBI) {
+ 610 265 : if (state->block_size > 16 * KIBI) {
611 : /* LCOV_EXCL_START */
612 : log_fatal("Too big 'blocksize' specification in '%s' at line %u\n", path, line);
613 : exit(EXIT_FAILURE);
614 : /* LCOV_EXCL_STOP */
615 : }
616 : /* check if it's a power of 2 */
- 617 264 : if ((state->block_size & (state->block_size - 1)) != 0) {
+ 617 265 : if ((state->block_size & (state->block_size - 1)) != 0) {
618 : /* LCOV_EXCL_START */
619 : log_fatal("Not power of 2 'blocksize' specification in '%s' at line %u\n", path, line);
620 : exit(EXIT_FAILURE);
621 : /* LCOV_EXCL_STOP */
622 : }
- 623 264 : state->block_size *= KIBI;
- 624 5937 : } else if (strcmp(tag, "hash_size") == 0) {
+ 623 265 : state->block_size *= KIBI;
+ 624 5954 : } else if (strcmp(tag, "hash_size") == 0) {
625 : uint32_t hash_size;
626 :
627 0 : ret = sgetu32(f, &hash_size);
@@ -714,7 +714,7 @@
652 : }
653 :
654 0 : BLOCK_HASH_SIZE = hash_size;
- 655 5937 : } else if (lev_config_scan(tag, &level, &state->raid_mode) == 0) {
+ 655 5954 : } else if (lev_config_scan(tag, &level, &state->raid_mode) == 0) {
656 : char device[PATH_MAX];
657 : char* split_map[SPLIT_MAX+1];
658 : unsigned split_mac;
@@ -722,43 +722,43 @@
660 : uint64_t dev;
661 : int skip_access;
662 :
- 663 1265 : if (state->parity[level].split_mac != 0) {
+ 663 1266 : if (state->parity[level].split_mac != 0) {
664 : /* LCOV_EXCL_START */
665 : log_fatal("Multiple '%s' specification in '%s' at line %u\n", tag, path, line);
666 : exit(EXIT_FAILURE);
667 : /* LCOV_EXCL_STOP */
668 : }
669 :
- 670 1265 : ret = sgetlasttok(f, buffer, sizeof(buffer));
- 671 1265 : if (ret < 0) {
+ 670 1266 : ret = sgetlasttok(f, buffer, sizeof(buffer));
+ 671 1266 : if (ret < 0) {
672 : /* LCOV_EXCL_START */
673 : log_fatal("Invalid '%s' specification in '%s' at line %u\n", tag, path, line);
674 : exit(EXIT_FAILURE);
675 : /* LCOV_EXCL_STOP */
676 : }
677 :
- 678 1265 : if (!*buffer) {
+ 678 1266 : if (!*buffer) {
679 : /* LCOV_EXCL_START */
680 : log_fatal("Empty '%s' specification in '%s' at line %u\n", tag, path, line);
681 : exit(EXIT_FAILURE);
682 : /* LCOV_EXCL_STOP */
683 : }
684 :
- 685 1265 : split_mac = strsplit(split_map, SPLIT_MAX+1, buffer, ",");
+ 685 1266 : split_mac = strsplit(split_map, SPLIT_MAX+1, buffer, ",");
686 :
- 687 1265 : if (split_mac > SPLIT_MAX) {
+ 687 1266 : if (split_mac > SPLIT_MAX) {
688 : /* LCOV_EXCL_START */
689 : log_fatal("Too many files in '%s' specification in '%s' at line %u\n", tag, path, line);
690 : exit(EXIT_FAILURE);
691 : /* LCOV_EXCL_STOP */
692 : }
693 :
- 694 1265 : skip_access = 0;
- 695 1265 : state->parity[level].split_mac = split_mac;
- 696 6321 : for (s = 0; s < split_mac; ++s) {
- 697 5057 : pathimport(state->parity[level].split_map[s].path, sizeof(state->parity[level].split_map[s].path), split_map[s]);
+ 694 1266 : skip_access = 0;
+ 695 1266 : state->parity[level].split_mac = split_mac;
+ 696 6326 : for (s = 0; s < split_mac; ++s) {
+ 697 5061 : pathimport(state->parity[level].split_map[s].path, sizeof(state->parity[level].split_map[s].path), split_map[s]);
698 :
- 699 5057 : if (!state->opt.skip_parity_access) {
+ 699 5061 : if (!state->opt.skip_parity_access) {
700 : struct stat st;
701 :
702 : /* get the device of the directory containing the parity file */
@@ -792,101 +792,101 @@
730 : }
731 : } else {
732 : /* use a fake device */
- 733 708 : dev = 0;
+ 733 712 : dev = 0;
734 : }
735 :
- 736 5056 : state->parity[level].split_map[s].device = dev;
+ 736 5060 : state->parity[level].split_map[s].device = dev;
737 : }
738 :
739 : /* store the global parity skip_access */
- 740 1264 : state->parity[level].skip_access = skip_access;
+ 740 1265 : state->parity[level].skip_access = skip_access;
741 :
742 : /* adjust the level */
- 743 1264 : if (state->level < level + 1)
+ 743 1265 : if (state->level < level + 1)
744 1000 : state->level = level + 1;
- 745 4672 : } else if (strcmp(tag, "share") == 0) {
- 746 40 : if (*state->share) {
+ 745 4688 : } else if (strcmp(tag, "share") == 0) {
+ 746 41 : if (*state->share) {
747 : /* LCOV_EXCL_START */
748 : log_fatal("Multiple 'share' specification in '%s' at line %u\n", path, line);
749 : exit(EXIT_FAILURE);
750 : /* LCOV_EXCL_STOP */
751 : }
752 :
- 753 40 : ret = sgetlasttok(f, buffer, sizeof(buffer));
- 754 40 : if (ret < 0) {
+ 753 41 : ret = sgetlasttok(f, buffer, sizeof(buffer));
+ 754 41 : if (ret < 0) {
755 : /* LCOV_EXCL_START */
756 : log_fatal("Invalid 'share' specification in '%s' at line %u\n", path, line);
757 : exit(EXIT_FAILURE);
758 : /* LCOV_EXCL_STOP */
759 : }
760 :
- 761 40 : if (!*buffer) {
+ 761 41 : if (!*buffer) {
762 : /* LCOV_EXCL_START */
763 : log_fatal("Empty 'share' specification in '%s' at line %u\n", path, line);
764 : exit(EXIT_FAILURE);
765 : /* LCOV_EXCL_STOP */
766 : }
767 :
- 768 40 : pathimport(state->share, sizeof(state->share), buffer);
- 769 4632 : } else if (strcmp(tag, "pool") == 0) {
+ 768 41 : pathimport(state->share, sizeof(state->share), buffer);
+ 769 4647 : } else if (strcmp(tag, "pool") == 0) {
770 : struct stat st;
771 :
- 772 40 : if (*state->pool) {
+ 772 41 : if (*state->pool) {
773 : /* LCOV_EXCL_START */
774 : log_fatal("Multiple 'pool' specification in '%s' at line %u\n", path, line);
775 : exit(EXIT_FAILURE);
776 : /* LCOV_EXCL_STOP */
777 : }
778 :
- 779 40 : ret = sgetlasttok(f, buffer, sizeof(buffer));
- 780 40 : if (ret < 0) {
+ 779 41 : ret = sgetlasttok(f, buffer, sizeof(buffer));
+ 780 41 : if (ret < 0) {
781 : /* LCOV_EXCL_START */
782 : log_fatal("Invalid 'pool' specification in '%s' at line %u\n", path, line);
783 : exit(EXIT_FAILURE);
784 : /* LCOV_EXCL_STOP */
785 : }
786 :
- 787 40 : if (!*buffer) {
+ 787 41 : if (!*buffer) {
788 : /* LCOV_EXCL_START */
789 : log_fatal("Empty 'pool' specification in '%s' at line %u\n", path, line);
790 : exit(EXIT_FAILURE);
791 : /* LCOV_EXCL_STOP */
792 : }
793 :
- 794 40 : pathimport(state->pool, sizeof(state->pool), buffer);
+ 794 41 : pathimport(state->pool, sizeof(state->pool), buffer);
795 :
796 : /* get the device of the directory containing the pool tree */
- 797 40 : if (stat(buffer, &st) != 0) {
+ 797 41 : if (stat(buffer, &st) != 0) {
798 : /* LCOV_EXCL_START */
799 : log_fatal("Error accessing 'pool' dir '%s' specification in '%s' at line %u\n", buffer, path, line);
800 : exit(EXIT_FAILURE);
801 : /* LCOV_EXCL_STOP */
802 : }
803 :
- 804 40 : state->pool_device = st.st_dev;
- 805 4592 : } else if (strcmp(tag, "content") == 0) {
+ 804 41 : state->pool_device = st.st_dev;
+ 805 4606 : } else if (strcmp(tag, "content") == 0) {
806 : struct snapraid_content* content;
807 : char device[PATH_MAX];
808 : char* slash;
809 : struct stat st;
810 : uint64_t dev;
811 :
- 812 1522 : ret = sgetlasttok(f, buffer, sizeof(buffer));
- 813 1522 : if (ret < 0) {
+ 812 1524 : ret = sgetlasttok(f, buffer, sizeof(buffer));
+ 813 1524 : if (ret < 0) {
814 : /* LCOV_EXCL_START */
815 : log_fatal("Invalid 'content' specification in '%s' at line %u\n", path, line);
816 : exit(EXIT_FAILURE);
817 : /* LCOV_EXCL_STOP */
818 : }
819 :
- 820 1522 : if (pathcmp(buffer, "/dev/null") == 0 || pathcmp(buffer, "NUL") == 0) {
+ 820 1524 : if (pathcmp(buffer, "/dev/null") == 0 || pathcmp(buffer, "NUL") == 0) {
821 : /* LCOV_EXCL_START */
822 : log_fatal("You cannot use the null device as 'content' specification in '%s' at line %u\n", path, line);
823 : exit(EXIT_FAILURE);
824 : /* LCOV_EXCL_STOP */
825 : }
826 :
- 827 1522 : if (!*buffer) {
+ 827 1524 : if (!*buffer) {
828 : /* LCOV_EXCL_START */
829 : log_fatal("Empty 'content' specification in '%s' at line %u\n", path, line);
830 : exit(EXIT_FAILURE);
@@ -894,12 +894,12 @@
832 : }
833 :
834 : /* check if the content file is already specified */
- 835 5693 : for (i = state->contentlist; i != 0; i = i->next) {
- 836 4171 : content = i->data;
- 837 4171 : if (pathcmp(content->content, buffer) == 0)
+ 835 5696 : for (i = state->contentlist; i != 0; i = i->next) {
+ 836 4172 : content = i->data;
+ 837 4172 : if (pathcmp(content->content, buffer) == 0)
838 0 : break;
839 : }
- 840 1522 : if (i) {
+ 840 1524 : if (i) {
841 : /* LCOV_EXCL_START */
842 : log_fatal("Duplicate 'content' specification in '%s' at line %u\n", path, line);
843 : exit(EXIT_FAILURE);
@@ -907,14 +907,14 @@
845 : }
846 :
847 : /* get the device of the directory containing the content file */
- 848 1522 : pathimport(device, sizeof(device), buffer);
- 849 1522 : slash = strrchr(device, '/');
- 850 1522 : if (slash)
- 851 1522 : *slash = 0;
+ 848 1524 : pathimport(device, sizeof(device), buffer);
+ 849 1524 : slash = strrchr(device, '/');
+ 850 1524 : if (slash)
+ 851 1524 : *slash = 0;
852 : else
853 0 : pathcpy(device, sizeof(device), ".");
- 854 1522 : if (stat(device, &st) == 0) {
- 855 1521 : dev = st.st_dev;
+ 854 1524 : if (stat(device, &st) == 0) {
+ 855 1523 : dev = st.st_dev;
856 : } else {
857 1 : if (state->opt.skip_content_access) {
858 : /* use a fake device */
@@ -929,15 +929,15 @@
867 : }
868 :
869 : /* set the lock file at the first accessible content file */
- 870 1522 : if (state->lockfile[0] == 0 && dev != 0) {
- 871 263 : pathcpy(state->lockfile, sizeof(state->lockfile), buffer);
- 872 263 : pathcat(state->lockfile, sizeof(state->lockfile), ".lock");
+ 870 1524 : if (state->lockfile[0] == 0 && dev != 0) {
+ 871 264 : pathcpy(state->lockfile, sizeof(state->lockfile), buffer);
+ 872 264 : pathcat(state->lockfile, sizeof(state->lockfile), ".lock");
873 : }
874 :
- 875 1522 : content = content_alloc(buffer, dev);
+ 875 1524 : content = content_alloc(buffer, dev);
876 :
- 877 1522 : tommy_list_insert_tail(&state->contentlist, &content->node, content);
- 878 4643 : } else if (strcmp(tag, "data") == 0 || strcmp(tag, "disk") == 0) {
+ 877 1524 : tommy_list_insert_tail(&state->contentlist, &content->node, content);
+ 878 4661 : } else if (strcmp(tag, "data") == 0 || strcmp(tag, "disk") == 0) {
879 : /* "disk" is the deprecated name up to SnapRAID 9.x */
880 : char dir[PATH_MAX];
881 : char device[PATH_MAX];
@@ -946,32 +946,32 @@
884 : uint64_t dev;
885 : int skip_access;
886 :
- 887 1573 : ret = sgettok(f, buffer, sizeof(buffer));
- 888 1573 : if (ret < 0) {
+ 887 1579 : ret = sgettok(f, buffer, sizeof(buffer));
+ 888 1579 : if (ret < 0) {
889 : /* LCOV_EXCL_START */
890 : log_fatal("Invalid 'data' name specification in '%s' at line %u\n", path, line);
891 : exit(EXIT_FAILURE);
892 : /* LCOV_EXCL_STOP */
893 : }
894 :
- 895 1573 : if (!*buffer) {
+ 895 1579 : if (!*buffer) {
896 : /* LCOV_EXCL_START */
897 : log_fatal("Empty 'data' name specification in '%s' at line %u\n", path, line);
898 : exit(EXIT_FAILURE);
899 : /* LCOV_EXCL_STOP */
900 : }
901 :
- 902 1573 : sgetspace(f);
+ 902 1579 : sgetspace(f);
903 :
- 904 1573 : ret = sgetlasttok(f, dir, sizeof(dir));
- 905 1573 : if (ret < 0) {
+ 904 1579 : ret = sgetlasttok(f, dir, sizeof(dir));
+ 905 1579 : if (ret < 0) {
906 : /* LCOV_EXCL_START */
907 : log_fatal("Invalid 'data' dir specification in '%s' at line %u\n", path, line);
908 : exit(EXIT_FAILURE);
909 : /* LCOV_EXCL_STOP */
910 : }
911 :
- 912 1573 : if (!*dir) {
+ 912 1579 : if (!*dir) {
913 : /* LCOV_EXCL_START */
914 : log_fatal("Empty 'data' dir specification in '%s' at line %u\n", path, line);
915 : exit(EXIT_FAILURE);
@@ -979,15 +979,15 @@
917 : }
918 :
919 : /* get the device of the dir */
- 920 1573 : pathimport(device, sizeof(device), dir);
+ 920 1579 : pathimport(device, sizeof(device), dir);
921 :
922 : /* check if the disk name already exists */
- 923 5493 : for (i = state->disklist; i != 0; i = i->next) {
- 924 3920 : disk = i->data;
- 925 3920 : if (strcmp(disk->name, buffer) == 0)
+ 923 5514 : for (i = state->disklist; i != 0; i = i->next) {
+ 924 3935 : disk = i->data;
+ 925 3935 : if (strcmp(disk->name, buffer) == 0)
926 0 : break;
927 : }
- 928 1573 : if (i) {
+ 928 1579 : if (i) {
929 : /* LCOV_EXCL_START */
930 : log_fatal("Duplicate 'data' name '%s' at line %u\n", buffer, line);
931 : exit(EXIT_FAILURE);
@@ -995,20 +995,20 @@
933 : }
934 :
935 : /* if the disk has to be present */
- 936 1573 : skip_access = 0;
- 937 1573 : if (!state->opt.skip_disk_access) {
+ 936 1579 : skip_access = 0;
+ 937 1579 : if (!state->opt.skip_disk_access) {
938 : struct stat st;
939 :
- 940 1417 : if (stat(device, &st) == 0) {
- 941 1416 : dev = st.st_dev;
+ 940 1423 : if (stat(device, &st) == 0) {
+ 941 1422 : dev = st.st_dev;
942 :
943 : /* read the uuid, if unsupported use an empty one */
- 944 1416 : if (devuuid(dev, uuid, sizeof(uuid)) != 0) {
+ 944 1422 : if (devuuid(dev, uuid, sizeof(uuid)) != 0) {
945 0 : *uuid = 0;
946 : }
947 :
948 : /* fake a different UUID when testing */
- 949 1416 : if (state->opt.fake_uuid) {
+ 949 1422 : if (state->opt.fake_uuid) {
950 2 : snprintf(uuid, sizeof(uuid), "fake-uuid-%d", state->opt.fake_uuid);
951 2 : --state->opt.fake_uuid;
952 : }
@@ -1038,10 +1038,10 @@
976 156 : *uuid = 0;
977 : }
978 :
- 979 1573 : disk = disk_alloc(buffer, dir, dev, uuid, skip_access);
+ 979 1579 : disk = disk_alloc(buffer, dir, dev, uuid, skip_access);
980 :
- 981 1573 : tommy_list_insert_tail(&state->disklist, &disk->node, disk);
- 982 1497 : } else if (strcmp(tag, "smartctl") == 0) {
+ 981 1579 : tommy_list_insert_tail(&state->disklist, &disk->node, disk);
+ 982 1503 : } else if (strcmp(tag, "smartctl") == 0) {
983 : char custom[PATH_MAX];
984 :
985 364 : ret = sgettok(f, buffer, sizeof(buffer));
@@ -1118,83 +1118,83 @@
1056 :
1057 182 : pathcpy(disk->smartctl, sizeof(disk->smartctl), custom);
1058 : }
- 1059 1133 : } else if (strcmp(tag, "nohidden") == 0) {
+ 1059 1139 : } else if (strcmp(tag, "nohidden") == 0) {
1060 0 : state->filter_hidden = 1;
- 1061 1133 : } else if (strcmp(tag, "exclude") == 0) {
+ 1061 1139 : } else if (strcmp(tag, "exclude") == 0) {
1062 : struct snapraid_filter* filter;
1063 :
- 1064 263 : ret = sgetlasttok(f, buffer, sizeof(buffer));
- 1065 263 : if (ret < 0) {
+ 1064 264 : ret = sgetlasttok(f, buffer, sizeof(buffer));
+ 1065 264 : if (ret < 0) {
1066 : /* LCOV_EXCL_START */
1067 : log_fatal("Invalid 'exclude' specification in '%s' at line %u\n", path, line);
1068 : exit(EXIT_FAILURE);
1069 : /* LCOV_EXCL_STOP */
1070 : }
1071 :
- 1072 263 : if (!*buffer) {
+ 1072 264 : if (!*buffer) {
1073 : /* LCOV_EXCL_START */
1074 : log_fatal("Empty 'exclude' specification in '%s' at line %u\n", path, line);
1075 : exit(EXIT_FAILURE);
1076 : /* LCOV_EXCL_STOP */
1077 : }
1078 :
- 1079 263 : filter = filter_alloc_file(-1, buffer);
- 1080 263 : if (!filter) {
+ 1079 264 : filter = filter_alloc_file(-1, buffer);
+ 1080 264 : if (!filter) {
1081 : /* LCOV_EXCL_START */
1082 : log_fatal("Invalid 'exclude' specification '%s' in '%s' at line %u\n", buffer, path, line);
1083 : log_fatal("Filters using relative paths are not supported. Ensure to add an initial slash\n");
1084 : exit(EXIT_FAILURE);
1085 : /* LCOV_EXCL_STOP */
1086 : }
- 1087 263 : tommy_list_insert_tail(&state->filterlist, &filter->node, filter);
- 1088 870 : } else if (strcmp(tag, "include") == 0) {
+ 1087 264 : tommy_list_insert_tail(&state->filterlist, &filter->node, filter);
+ 1088 875 : } else if (strcmp(tag, "include") == 0) {
1089 : struct snapraid_filter* filter;
1090 :
- 1091 263 : ret = sgetlasttok(f, buffer, sizeof(buffer));
- 1092 263 : if (ret < 0) {
+ 1091 264 : ret = sgetlasttok(f, buffer, sizeof(buffer));
+ 1092 264 : if (ret < 0) {
1093 : /* LCOV_EXCL_START */
1094 : log_fatal("Invalid 'include' specification in '%s' at line %u\n", path, line);
1095 : exit(EXIT_FAILURE);
1096 : /* LCOV_EXCL_STOP */
1097 : }
1098 :
- 1099 263 : if (!*buffer) {
+ 1099 264 : if (!*buffer) {
1100 : /* LCOV_EXCL_START */
1101 : log_fatal("Empty 'include' specification in '%s' at line %u\n", path, line);
1102 : exit(EXIT_FAILURE);
1103 : /* LCOV_EXCL_STOP */
1104 : }
1105 :
- 1106 263 : filter = filter_alloc_file(1, buffer);
- 1107 263 : if (!filter) {
+ 1106 264 : filter = filter_alloc_file(1, buffer);
+ 1107 264 : if (!filter) {
1108 : /* LCOV_EXCL_START */
1109 : log_fatal("Invalid 'include' specification '%s' in '%s' at line %u\n", buffer, path, line);
1110 : log_fatal("Filters using relative paths are not supported. Ensure to add an initial slash\n");
1111 : exit(EXIT_FAILURE);
1112 : /* LCOV_EXCL_STOP */
1113 : }
- 1114 263 : tommy_list_insert_tail(&state->filterlist, &filter->node, filter);
- 1115 607 : } else if (strcmp(tag, "autosave") == 0) {
+ 1114 264 : tommy_list_insert_tail(&state->filterlist, &filter->node, filter);
+ 1115 611 : } else if (strcmp(tag, "autosave") == 0) {
1116 : char* e;
1117 :
- 1118 40 : ret = sgetlasttok(f, buffer, sizeof(buffer));
- 1119 40 : if (ret < 0) {
+ 1118 41 : ret = sgetlasttok(f, buffer, sizeof(buffer));
+ 1119 41 : if (ret < 0) {
1120 : /* LCOV_EXCL_START */
1121 : log_fatal("Invalid 'autosave' specification in '%s' at line %u\n", path, line);
1122 : exit(EXIT_FAILURE);
1123 : /* LCOV_EXCL_STOP */
1124 : }
1125 :
- 1126 40 : if (!*buffer) {
+ 1126 41 : if (!*buffer) {
1127 : /* LCOV_EXCL_START */
1128 : log_fatal("Empty 'autosave' specification in '%s' at line %u\n", path, line);
1129 : exit(EXIT_FAILURE);
1130 : /* LCOV_EXCL_STOP */
1131 : }
1132 :
- 1133 40 : state->autosave = strtoul(buffer, &e, 0);
+ 1133 41 : state->autosave = strtoul(buffer, &e, 0);
1134 :
- 1135 40 : if (!e || *e) {
+ 1135 41 : if (!e || *e) {
1136 : /* LCOV_EXCL_START */
1137 : log_fatal("Invalid 'autosave' specification in '%s' at line %u\n", path, line);
1138 : exit(EXIT_FAILURE);
@@ -1202,12 +1202,12 @@
1140 : }
1141 :
1142 : /* convert to GB */
- 1143 40 : state->autosave *= GIGA;
- 1144 567 : } else if (tag[0] == 0) {
+ 1143 41 : state->autosave *= GIGA;
+ 1144 570 : } else if (tag[0] == 0) {
1145 : /* allow empty lines */
- 1146 40 : } else if (tag[0] == '#') {
- 1147 40 : ret = sgetline(f, buffer, sizeof(buffer));
- 1148 40 : if (ret < 0) {
+ 1146 41 : } else if (tag[0] == '#') {
+ 1147 41 : ret = sgetline(f, buffer, sizeof(buffer));
+ 1148 41 : if (ret < 0) {
1149 : /* LCOV_EXCL_START */
1150 : log_fatal("Invalid comment in '%s' at line %u\n", path, line);
1151 : exit(EXIT_FAILURE);
@@ -1221,42 +1221,42 @@
1159 : }
1160 :
1161 : /* skip final spaces */
- 1162 6200 : sgetspace(f);
+ 1162 6218 : sgetspace(f);
1163 :
1164 : /* next line */
- 1165 6200 : c = sgeteol(f);
- 1166 6200 : if (c == EOF) {
- 1167 263 : break;
+ 1165 6218 : c = sgeteol(f);
+ 1166 6218 : if (c == EOF) {
+ 1167 264 : break;
1168 : }
- 1169 5937 : if (c != '\n') {
+ 1169 5954 : if (c != '\n') {
1170 : /* LCOV_EXCL_START */
1171 : log_fatal("Extra data in '%s' at line %u\n", path, line);
1172 : exit(EXIT_FAILURE);
1173 : /* LCOV_EXCL_STOP */
1174 : }
- 1175 5937 : ++line;
- 1176 5937 : }
+ 1175 5954 : ++line;
+ 1176 5954 : }
1177 :
- 1178 263 : if (serror(f)) {
+ 1178 264 : if (serror(f)) {
1179 : /* LCOV_EXCL_START */
1180 : log_fatal("Error reading the configuration file '%s' at line %u\n", path, line);
1181 : exit(EXIT_FAILURE);
1182 : /* LCOV_EXCL_STOP */
1183 : }
1184 :
- 1185 263 : sclose(f);
+ 1185 264 : sclose(f);
1186 :
- 1187 263 : state_config_check(state, path, filterlist_disk);
+ 1187 264 : state_config_check(state, path, filterlist_disk);
1188 :
1189 : /* select the default hash */
- 1190 263 : if (state->opt.force_murmur3) {
+ 1190 264 : if (state->opt.force_murmur3) {
1191 1 : state->besthash = HASH_MURMUR3;
- 1192 262 : } else if (state->opt.force_spooky2) {
+ 1192 263 : } else if (state->opt.force_spooky2) {
1193 1 : state->besthash = HASH_SPOOKY2;
1194 : } else {
1195 : #ifdef CONFIG_X86
- 1196 261 : if (sizeof(void*) == 4 && !raid_cpu_has_slowmult())
- 1197 261 : state->besthash = HASH_MURMUR3;
+ 1196 262 : if (sizeof(void*) == 4 && !raid_cpu_has_slowmult())
+ 1197 262 : state->besthash = HASH_MURMUR3;
1198 : else
1199 0 : state->besthash = HASH_SPOOKY2;
1200 : #else
@@ -1268,10 +1268,10 @@
1206 : }
1207 :
1208 : /* by default use the best hash */
- 1209 263 : state->hash = state->besthash;
+ 1209 264 : state->hash = state->besthash;
1210 :
1211 : /* by default use a random hash seed */
- 1212 263 : if (randomize(state->hashseed, HASH_MAX) != 0) {
+ 1212 264 : if (randomize(state->hashseed, HASH_MAX) != 0) {
1213 : /* LCOV_EXCL_START */
1214 : log_fatal("Failed to get random values.\n");
1215 : exit(EXIT_FAILURE);
@@ -1279,47 +1279,47 @@
1217 : }
1218 :
1219 : /* no previous hash by default */
- 1220 263 : state->prevhash = HASH_UNDEFINED;
+ 1220 264 : state->prevhash = HASH_UNDEFINED;
1221 :
1222 : /* intentionally not set the prevhashseed, if used valgrind will warn about it */
1223 :
- 1224 263 : log_tag("blocksize:%u\n", state->block_size);
- 1225 1836 : for (i = state->disklist; i != 0; i = i->next) {
- 1226 1573 : struct snapraid_disk* disk = i->data;
- 1227 1573 : log_tag("data:%s:%s\n", disk->name, disk->dir);
+ 1224 264 : log_tag("blocksize:%u\n", state->block_size);
+ 1225 1843 : for (i = state->disklist; i != 0; i = i->next) {
+ 1226 1579 : struct snapraid_disk* disk = i->data;
+ 1227 1579 : log_tag("data:%s:%s\n", disk->name, disk->dir);
1228 : }
1229 :
- 1230 263 : log_tag("mode:%s\n", lev_raid_name(state->raid_mode, state->level));
- 1231 1522 : for (l = 0; l < state->level; ++l)
- 1232 6295 : for (s = 0; s < state->parity[l].split_mac; ++s)
- 1233 5036 : log_tag("%s:%u:%s\n", lev_config_name(l), s, state->parity[l].split_map[s].path);
- 1234 263 : if (state->pool[0] != 0)
- 1235 40 : log_tag("pool:%s\n", state->pool);
- 1236 263 : if (state->share[0] != 0)
- 1237 40 : log_tag("share:%s\n", state->share);
- 1238 263 : if (state->autosave != 0)
- 1239 40 : log_tag("autosave:%" PRIu64 "\n", state->autosave);
- 1240 789 : for (i = tommy_list_head(&state->filterlist); i != 0; i = i->next) {
+ 1230 264 : log_tag("mode:%s\n", lev_raid_name(state->raid_mode, state->level));
+ 1231 1524 : for (l = 0; l < state->level; ++l)
+ 1232 6300 : for (s = 0; s < state->parity[l].split_mac; ++s)
+ 1233 5040 : log_tag("%s:%u:%s\n", lev_config_name(l), s, state->parity[l].split_map[s].path);
+ 1234 264 : if (state->pool[0] != 0)
+ 1235 41 : log_tag("pool:%s\n", state->pool);
+ 1236 264 : if (state->share[0] != 0)
+ 1237 41 : log_tag("share:%s\n", state->share);
+ 1238 264 : if (state->autosave != 0)
+ 1239 41 : log_tag("autosave:%" PRIu64 "\n", state->autosave);
+ 1240 792 : for (i = tommy_list_head(&state->filterlist); i != 0; i = i->next) {
1241 : char out[PATH_MAX];
- 1242 526 : struct snapraid_filter* filter = i->data;
- 1243 526 : log_tag("filter:%s\n", filter_type(filter, out, sizeof(out)));
+ 1242 528 : struct snapraid_filter* filter = i->data;
+ 1243 528 : log_tag("filter:%s\n", filter_type(filter, out, sizeof(out)));
1244 : }
- 1245 263 : if (state->filter_hidden)
+ 1245 264 : if (state->filter_hidden)
1246 0 : log_tag("filter:nohidden:\n");
- 1247 263 : log_flush();
+ 1247 264 : log_flush();
1248 : }
1249 :
1250 : /**
1251 : * Find a disk by name.
1252 : */
- 1253 7021 : static struct snapraid_disk* find_disk_by_name(struct snapraid_state* state, const char* name)
+ 1253 7037 : static struct snapraid_disk* find_disk_by_name(struct snapraid_state* state, const char* name)
1254 : {
1255 : tommy_node* i;
1256 :
- 1257 24503 : for (i = state->disklist; i != 0; i = i->next) {
- 1258 24495 : struct snapraid_disk* disk = i->data;
- 1259 24495 : if (strcmp(disk->name, name) == 0)
- 1260 7013 : return disk;
+ 1257 24556 : for (i = state->disklist; i != 0; i = i->next) {
+ 1258 24548 : struct snapraid_disk* disk = i->data;
+ 1259 24548 : if (strcmp(disk->name, name) == 0)
+ 1260 7029 : return disk;
1261 : }
1262 :
1263 8 : if (state->no_conf) {
@@ -1372,7 +1372,7 @@
1310 : /**
1311 : * Update the disk mapping if required.
1312 : */
- 1313 258 : static void state_map(struct snapraid_state* state)
+ 1313 259 : static void state_map(struct snapraid_state* state)
1314 : {
1315 : unsigned hole;
1316 : tommy_node* i;
@@ -1384,16 +1384,16 @@
1322 : /* this happens when a disk is removed from the configuration file */
1323 : /* From SnapRAID 4.0 mappings are automatically removed if a disk is not used */
1324 : /* when saving the content file, but we keep this code to import older content files. */
- 1325 1903 : for (i = state->maplist; i != 0; ) {
- 1326 1387 : struct snapraid_map* map = i->data;
+ 1325 1910 : for (i = state->maplist; i != 0; ) {
+ 1326 1392 : struct snapraid_map* map = i->data;
1327 : struct snapraid_disk* disk;
1328 :
- 1329 1387 : disk = find_disk_by_name(state, map->name);
+ 1329 1392 : disk = find_disk_by_name(state, map->name);
1330 :
1331 : /* go to the next mapping before removing */
- 1332 1387 : i = i->next;
+ 1332 1392 : i = i->next;
1333 :
- 1334 1387 : if (disk == 0) {
+ 1334 1392 : if (disk == 0) {
1335 : /* disk not found, remove the mapping */
1336 0 : tommy_list_remove_existing(&state->maplist, &map->node);
1337 0 : map_free(map);
@@ -1402,104 +1402,104 @@
1340 :
1341 : /* maps each unmapped disk present in the configuration file in the first available hole */
1342 : /* this happens when you add disks for the first time in the configuration file */
- 1343 258 : hole = 0; /* first position to try */
- 1344 1801 : for (i = state->disklist; i != 0; i = i->next) {
- 1345 1543 : struct snapraid_disk* disk = i->data;
+ 1343 259 : hole = 0; /* first position to try */
+ 1344 1808 : for (i = state->disklist; i != 0; i = i->next) {
+ 1345 1549 : struct snapraid_disk* disk = i->data;
1346 : struct snapraid_map* map;
1347 : tommy_node* j;
1348 :
1349 : /* check if the disk is already mapped */
- 1350 5388 : for (j = state->maplist; j != 0; j = j->next) {
- 1351 5232 : map = j->data;
- 1352 5232 : if (strcmp(disk->name, map->name) == 0) {
+ 1350 5409 : for (j = state->maplist; j != 0; j = j->next) {
+ 1351 5252 : map = j->data;
+ 1352 5252 : if (strcmp(disk->name, map->name) == 0) {
1353 : /* mapping found */
- 1354 1387 : break;
+ 1354 1392 : break;
1355 : }
1356 : }
- 1357 1543 : if (j != 0) {
+ 1357 1549 : if (j != 0) {
1358 : /* mapping is present, then copy the free blocks into to disk */
- 1359 1387 : disk->total_blocks = map->total_blocks;
- 1360 1387 : disk->free_blocks = map->free_blocks;
- 1361 1387 : continue;
+ 1359 1392 : disk->total_blocks = map->total_blocks;
+ 1360 1392 : disk->free_blocks = map->free_blocks;
+ 1361 1392 : continue;
1362 : }
1363 :
1364 : /* mapping not found, search for an hole */
1365 : while (1) {
- 1366 1060 : for (j = state->maplist; j != 0; j = j->next) {
- 1367 904 : map = j->data;
- 1368 904 : if (map->position == hole) {
+ 1366 1080 : for (j = state->maplist; j != 0; j = j->next) {
+ 1367 923 : map = j->data;
+ 1368 923 : if (map->position == hole) {
1369 : /* position already used */
- 1370 150 : break;
+ 1370 154 : break;
1371 : }
1372 : }
- 1373 306 : if (j == 0) {
+ 1373 311 : if (j == 0) {
1374 : /* hole found */
- 1375 156 : break;
+ 1375 157 : break;
1376 : }
1377 :
1378 : /* try with the next one */
- 1379 150 : ++hole;
- 1380 150 : }
+ 1379 154 : ++hole;
+ 1380 154 : }
1381 :
1382 : /* insert the new mapping */
- 1383 156 : map = map_alloc(disk->name, hole, 0, 0, "");
+ 1383 157 : map = map_alloc(disk->name, hole, 0, 0, "");
1384 :
- 1385 156 : tommy_list_insert_tail(&state->maplist, &map->node, map);
+ 1385 157 : tommy_list_insert_tail(&state->maplist, &map->node, map);
1386 : }
1387 :
1388 : /* without configuration don't check for number of data disks or uuid changes */
- 1389 258 : if (state->no_conf)
- 1390 259 : return;
+ 1389 259 : if (state->no_conf)
+ 1390 260 : return;
1391 :
1392 : /* counter for the number of UUID mismatches */
- 1393 257 : uuid_mismatch = 0;
+ 1393 258 : uuid_mismatch = 0;
1394 :
1395 : /* check if mapping match the disk uuid */
- 1396 257 : if (!state->opt.skip_disk_access) {
- 1397 1619 : for (i = state->maplist; i != 0; i = i->next) {
- 1398 1387 : struct snapraid_map* map = i->data;
+ 1396 258 : if (!state->opt.skip_disk_access) {
+ 1397 1626 : for (i = state->maplist; i != 0; i = i->next) {
+ 1398 1393 : struct snapraid_map* map = i->data;
1399 : struct snapraid_disk* disk;
1400 :
- 1401 1387 : disk = find_disk_by_name(state, map->name);
- 1402 1387 : if (disk == 0) {
+ 1401 1393 : disk = find_disk_by_name(state, map->name);
+ 1402 1393 : if (disk == 0) {
1403 : /* LCOV_EXCL_START */
1404 : log_fatal("Internal inconsistency for mapping '%s'\n", map->name);
1405 : os_abort();
1406 : /* LCOV_EXCL_STOP */
1407 : }
1408 :
- 1409 1387 : if (disk->has_unsupported_uuid) {
+ 1409 1393 : if (disk->has_unsupported_uuid) {
1410 : /* if uuid is not available, skip this one */
1411 1 : continue;
1412 : }
1413 :
1414 : /* if the uuid is changed */
- 1415 1386 : if (strcmp(disk->uuid, map->uuid) != 0) {
+ 1415 1392 : if (strcmp(disk->uuid, map->uuid) != 0) {
1416 : /* mark the disk as with an UUID change */
- 1417 112 : disk->has_different_uuid = 1;
+ 1417 113 : disk->has_different_uuid = 1;
1418 :
1419 : /* if the previous uuid is available */
- 1420 112 : if (map->uuid[0] != 0) {
+ 1420 113 : if (map->uuid[0] != 0) {
1421 : /* count the number of uuid change */
1422 4 : ++uuid_mismatch;
1423 4 : log_fatal("UUID change for disk '%s' from '%s' to '%s'\n", disk->name, map->uuid, disk->uuid);
1424 : } else {
1425 : /* no message here, because having a disk without */
1426 : /* UUID is the normal state of an empty disk */
- 1427 108 : disk->had_empty_uuid = 1;
+ 1427 109 : disk->had_empty_uuid = 1;
1428 : }
1429 :
1430 : /* update the uuid in the mapping, */
- 1431 112 : pathcpy(map->uuid, sizeof(map->uuid), disk->uuid);
+ 1431 113 : pathcpy(map->uuid, sizeof(map->uuid), disk->uuid);
1432 :
1433 : /* write the new state with the new uuid */
- 1434 112 : state->need_write = 1;
+ 1434 113 : state->need_write = 1;
1435 : }
1436 : }
1437 : }
1438 :
1439 : /* check the parity uuid */
- 1440 257 : if (!state->opt.skip_parity_access) {
+ 1440 258 : if (!state->opt.skip_parity_access) {
1441 1273 : for (l = 0; l < state->level; ++l) {
1442 5260 : for (s = 0; s < state->parity[l].split_mac; ++s) {
1443 : char uuid[UUID_MAX];
@@ -1530,7 +1530,7 @@
1468 : }
1469 : }
1470 :
- 1471 257 : if (!state->opt.force_uuid && uuid_mismatch > state->level) {
+ 1471 258 : if (!state->opt.force_uuid && uuid_mismatch > state->level) {
1472 : /* LCOV_EXCL_START */
1473 : log_fatal("Too many disks have UUID changed from the latest 'sync'.\n");
1474 : log_fatal("If this happens because you really replaced them,\n");
@@ -1542,16 +1542,16 @@
1480 : }
1481 :
1482 : /* count the number of data disks, including holes left after removing some */
- 1483 257 : diskcount = 0;
- 1484 1794 : for (i = state->maplist; i != 0; i = i->next) {
- 1485 1537 : struct snapraid_map* map = i->data;
+ 1483 258 : diskcount = 0;
+ 1484 1801 : for (i = state->maplist; i != 0; i = i->next) {
+ 1485 1543 : struct snapraid_map* map = i->data;
1486 :
- 1487 1537 : if (map->position + 1 > diskcount)
- 1488 1365 : diskcount = map->position + 1;
+ 1487 1543 : if (map->position + 1 > diskcount)
+ 1488 1366 : diskcount = map->position + 1;
1489 : }
1490 :
1491 : /* ensure to don't go over the limit of the RAID engine */
- 1492 257 : if (diskcount > RAID_DATA_MAX) {
+ 1492 258 : if (diskcount > RAID_DATA_MAX) {
1493 : /* LCOV_EXCL_START */
1494 : log_fatal("Too many data disks. No more than %u.\n", RAID_DATA_MAX);
1495 : exit(EXIT_FAILURE);
@@ -1559,10 +1559,10 @@
1497 : }
1498 :
1499 : /* now count the real number of data disks, excluding holes left after removing some */
- 1500 257 : diskcount = tommy_list_count(&state->maplist);
+ 1500 258 : diskcount = tommy_list_count(&state->maplist);
1501 :
1502 : /* recommend number of parities */
- 1503 257 : if (!state->opt.no_warnings) {
+ 1503 258 : if (!state->opt.no_warnings) {
1504 1 : if (diskcount >= 36 && state->level < 6) {
1505 0 : log_fatal("WARNING! With %u disks it's recommended to use six parity levels.\n", diskcount);
1506 1 : } else if (diskcount >= 29 && state->level < 5) {
@@ -1647,23 +1647,23 @@
1585 : /**
1586 : * Check the content.
1587 : */
- 1588 251 : static void state_content_check(struct snapraid_state* state, const char* path)
+ 1588 252 : static void state_content_check(struct snapraid_state* state, const char* path)
1589 : {
1590 : tommy_node* i;
1591 :
1592 : /* check that any map has different name and position */
- 1593 1752 : for (i = state->maplist; i != 0; i = i->next) {
- 1594 1501 : struct snapraid_map* map = i->data;
+ 1593 1759 : for (i = state->maplist; i != 0; i = i->next) {
+ 1594 1507 : struct snapraid_map* map = i->data;
1595 : tommy_node* j;
- 1596 5241 : for (j = i->next; j != 0; j = j->next) {
- 1597 3740 : struct snapraid_map* other = j->data;
- 1598 3740 : if (strcmp(map->name, other->name) == 0) {
+ 1596 5262 : for (j = i->next; j != 0; j = j->next) {
+ 1597 3755 : struct snapraid_map* other = j->data;
+ 1598 3755 : if (strcmp(map->name, other->name) == 0) {
1599 : /* LCOV_EXCL_START */
1600 : log_fatal("Colliding 'map' disk specification in '%s'\n", path);
1601 : exit(EXIT_FAILURE);
1602 : /* LCOV_EXCL_STOP */
1603 : }
- 1604 3740 : if (map->position == other->position) {
+ 1604 3755 : if (map->position == other->position) {
1605 : /* LCOV_EXCL_START */
1606 : log_fatal("Colliding 'map' index specification in '%s'\n", path);
1607 : exit(EXIT_FAILURE);
@@ -1671,7 +1671,7 @@
1609 : }
1610 : }
1611 : }
- 1612 251 : }
+ 1612 252 : }
1613 :
1614 : /**
1615 : * Check if the position is REQUIRED, or we can completely clear it from the state.
@@ -1707,21 +1707,21 @@
1645 : * Note also that not requiring an info block, doesn't mean that if present it
1646 : * can be discarded.
1647 : */
- 1648 1547811 : static int fs_info_is_required(struct snapraid_state* state, block_off_t pos)
+ 1648 1547867 : static int fs_info_is_required(struct snapraid_state* state, block_off_t pos)
1649 : {
1650 : tommy_node* i;
1651 :
1652 : /* check for each disk */
- 1653 2047992 : for (i = state->disklist; i != 0; i = i->next) {
- 1654 1989291 : struct snapraid_disk* disk = i->data;
- 1655 1989291 : struct snapraid_block* block = fs_par2block_find(disk, pos);
+ 1653 2048240 : for (i = state->disklist; i != 0; i = i->next) {
+ 1654 1989507 : struct snapraid_disk* disk = i->data;
+ 1655 1989507 : struct snapraid_block* block = fs_par2block_find(disk, pos);
1656 :
1657 : /* if we have at least one synced file, the info is required */
- 1658 1989291 : if (block_state_get(block) == BLOCK_STATE_BLK)
- 1659 1489110 : return 1;
+ 1658 1989507 : if (block_state_get(block) == BLOCK_STATE_BLK)
+ 1659 1489134 : return 1;
1660 : }
1661 :
- 1662 58701 : return 0;
+ 1662 58733 : return 0;
1663 : }
1664 :
1665 0 : static void fs_position_clear_deleted(struct snapraid_state* state, block_off_t pos)
@@ -1803,7 +1803,7 @@
1741 : }
1742 0 : }
1743 :
- 1744 252 : static void state_read_content(struct snapraid_state* state, const char* path, STREAM* f)
+ 1744 253 : static void state_read_content(struct snapraid_state* state, const char* path, STREAM* f)
1745 : {
1746 : block_off_t blockmax;
1747 : unsigned count_file;
@@ -1816,17 +1816,17 @@
1754 : tommy_array disk_mapping;
1755 : uint32_t mapping_max;
1756 :
- 1757 252 : blockmax = 0;
- 1758 252 : count_file = 0;
- 1759 252 : count_hardlink = 0;
- 1760 252 : count_symlink = 0;
- 1761 252 : count_dir = 0;
- 1762 252 : crc_checked = 0;
- 1763 252 : mapping_max = 0;
- 1764 252 : tommy_array_init(&disk_mapping);
+ 1757 253 : blockmax = 0;
+ 1758 253 : count_file = 0;
+ 1759 253 : count_hardlink = 0;
+ 1760 253 : count_symlink = 0;
+ 1761 253 : count_dir = 0;
+ 1762 253 : crc_checked = 0;
+ 1763 253 : mapping_max = 0;
+ 1764 253 : tommy_array_init(&disk_mapping);
1765 :
- 1766 252 : ret = sread(f, buffer, 12);
- 1767 252 : if (ret < 0) {
+ 1766 253 : ret = sread(f, buffer, 12);
+ 1767 253 : if (ret < 0) {
1768 : /* LCOV_EXCL_START */
1769 : decoding_error(path, f);
1770 : log_fatal("Invalid header!\n");
@@ -1844,9 +1844,9 @@
1782 : * - SNAPCNT3/SnapRAID 11.0 Adds entry 'Q' for multi parity file.
1783 : * The previous 'P' entry is now deprecated, but supported for importing.
1784 : */
- 1785 252 : if (memcmp(buffer, "SNAPCNT1\n\3\0\0", 12) != 0
- 1786 252 : && memcmp(buffer, "SNAPCNT2\n\3\0\0", 12) != 0
- 1787 252 : && memcmp(buffer, "SNAPCNT3\n\3\0\0", 12) != 0
+ 1785 253 : if (memcmp(buffer, "SNAPCNT1\n\3\0\0", 12) != 0
+ 1786 253 : && memcmp(buffer, "SNAPCNT2\n\3\0\0", 12) != 0
+ 1787 253 : && memcmp(buffer, "SNAPCNT3\n\3\0\0", 12) != 0
1788 : ) {
1789 : /* LCOV_EXCL_START */
1790 : if (memcmp(buffer, "SNAPCNT", 7) != 0) {
@@ -1864,12 +1864,12 @@
1802 : int c;
1803 :
1804 : /* read the command */
- 1805 3735825 : c = sgetc(f);
- 1806 3735825 : if (c == EOF) {
- 1807 251 : break;
+ 1805 3735717 : c = sgetc(f);
+ 1806 3735717 : if (c == EOF) {
+ 1807 252 : break;
1808 : }
1809 :
- 1810 3735574 : if (c == 'f') {
+ 1810 3735465 : if (c == 'f') {
1811 : /* file */
1812 : char sub[PATH_MAX];
1813 : uint64_t v_size;
@@ -1881,25 +1881,25 @@
1819 : struct snapraid_disk* disk;
1820 : uint32_t mapping;
1821 :
- 1822 3612018 : ret = sgetb32(f, &mapping);
- 1823 3612018 : if (ret < 0 || mapping >= mapping_max) {
+ 1822 3611886 : ret = sgetb32(f, &mapping);
+ 1823 3611886 : if (ret < 0 || mapping >= mapping_max) {
1824 : /* LCOV_EXCL_START */
1825 : decoding_error(path, f);
1826 : log_fatal("Internal inconsistency in mapping index!\n");
1827 : os_abort();
1828 : /* LCOV_EXCL_STOP */
1829 : }
- 1830 3612018 : disk = tommy_array_get(&disk_mapping, mapping);
+ 1830 3611886 : disk = tommy_array_get(&disk_mapping, mapping);
1831 :
- 1832 3612018 : ret = sgetb64(f, &v_size);
- 1833 3612018 : if (ret < 0) {
+ 1832 3611886 : ret = sgetb64(f, &v_size);
+ 1833 3611886 : if (ret < 0) {
1834 : /* LCOV_EXCL_START */
1835 : decoding_error(path, f);
1836 : os_abort();
1837 : /* LCOV_EXCL_STOP */
1838 : }
1839 :
- 1840 3612018 : if (state->block_size == 0) {
+ 1840 3611886 : if (state->block_size == 0) {
1841 : /* LCOV_EXCL_START */
1842 : decoding_error(path, f);
1843 : log_fatal("Internal incosistency due zero blocksize!\n");
@@ -1908,7 +1908,7 @@
1846 : }
1847 :
1848 : /* check for impossible file size to avoid to crash for a too big allocation */
- 1849 3612018 : if (v_size / state->block_size > blockmax) {
+ 1849 3611886 : if (v_size / state->block_size > blockmax) {
1850 : /* LCOV_EXCL_START */
1851 : decoding_error(path, f);
1852 : log_fatal("Internal inconsistency in file size too big!\n");
@@ -1916,16 +1916,16 @@
1854 : /* LCOV_EXCL_STOP */
1855 : }
1856 :
- 1857 3612018 : ret = sgetb64(f, &v_mtime_sec);
- 1858 3612018 : if (ret < 0) {
+ 1857 3611886 : ret = sgetb64(f, &v_mtime_sec);
+ 1858 3611886 : if (ret < 0) {
1859 : /* LCOV_EXCL_START */
1860 : decoding_error(path, f);
1861 : os_abort();
1862 : /* LCOV_EXCL_STOP */
1863 : }
1864 :
- 1865 3612018 : ret = sgetb32(f, &v_mtime_nsec);
- 1866 3612018 : if (ret < 0) {
+ 1865 3611886 : ret = sgetb32(f, &v_mtime_nsec);
+ 1866 3611886 : if (ret < 0) {
1867 : /* LCOV_EXCL_START */
1868 : decoding_error(path, f);
1869 : os_abort();
@@ -1933,27 +1933,27 @@
1871 : }
1872 :
1873 : /* STAT_NSEC_INVALID is encoded as 0 */
- 1874 3612018 : if (v_mtime_nsec == 0)
+ 1874 3611886 : if (v_mtime_nsec == 0)
1875 0 : v_mtime_nsec = STAT_NSEC_INVALID;
1876 : else
- 1877 3612018 : --v_mtime_nsec;
+ 1877 3611886 : --v_mtime_nsec;
1878 :
- 1879 3612018 : ret = sgetb64(f, &v_inode);
- 1880 3612018 : if (ret < 0) {
+ 1879 3611886 : ret = sgetb64(f, &v_inode);
+ 1880 3611886 : if (ret < 0) {
1881 : /* LCOV_EXCL_START */
1882 : decoding_error(path, f);
1883 : os_abort();
1884 : /* LCOV_EXCL_STOP */
1885 : }
1886 :
- 1887 3612018 : ret = sgetbs(f, sub, sizeof(sub));
- 1888 3612018 : if (ret < 0) {
+ 1887 3611886 : ret = sgetbs(f, sub, sizeof(sub));
+ 1888 3611886 : if (ret < 0) {
1889 : /* LCOV_EXCL_START */
1890 : decoding_error(path, f);
1891 : os_abort();
1892 : /* LCOV_EXCL_STOP */
1893 : }
- 1894 3612018 : if (!*sub) {
+ 1894 3611886 : if (!*sub) {
1895 : /* LCOV_EXCL_START */
1896 : decoding_error(path, f);
1897 : log_fatal("Internal inconsistency for null file!\n");
@@ -1962,40 +1962,40 @@
1900 : }
1901 :
1902 : /* allocate the file */
- 1903 3612018 : file = file_alloc(state->block_size, sub, v_size, v_mtime_sec, v_mtime_nsec, v_inode, 0);
+ 1903 3611886 : file = file_alloc(state->block_size, sub, v_size, v_mtime_sec, v_mtime_nsec, v_inode, 0);
1904 :
1905 : /* insert the file in the file containers */
- 1906 3612018 : tommy_hashdyn_insert(&disk->inodeset, &file->nodeset, file, file_inode_hash(file->inode));
- 1907 3612018 : tommy_hashdyn_insert(&disk->pathset, &file->pathset, file, file_path_hash(file->sub));
- 1908 3612018 : tommy_hashdyn_insert(&disk->stampset, &file->stampset, file, file_stamp_hash(file->size, file->mtime_sec, file->mtime_nsec));
- 1909 3612018 : tommy_list_insert_tail(&disk->filelist, &file->nodelist, file);
+ 1906 3611886 : tommy_hashdyn_insert(&disk->inodeset, &file->nodeset, file, file_inode_hash(file->inode));
+ 1907 3611886 : tommy_hashdyn_insert(&disk->pathset, &file->pathset, file, file_path_hash(file->sub));
+ 1908 3611886 : tommy_hashdyn_insert(&disk->stampset, &file->stampset, file, file_stamp_hash(file->size, file->mtime_sec, file->mtime_nsec));
+ 1909 3611886 : tommy_list_insert_tail(&disk->filelist, &file->nodelist, file);
1910 :
1911 : /* read all the blocks */
- 1912 3612018 : v_idx = 0;
- 1913 10856725 : while (v_idx < file->blockmax) {
+ 1912 3611886 : v_idx = 0;
+ 1913 10856319 : while (v_idx < file->blockmax) {
1914 : block_off_t v_pos;
1915 : uint32_t v_count;
1916 :
1917 : /* get the "subcommand */
- 1918 3632690 : c = sgetc(f);
+ 1918 3632547 : c = sgetc(f);
1919 :
- 1920 3632690 : ret = sgetb32(f, &v_pos);
- 1921 3632690 : if (ret < 0) {
+ 1920 3632547 : ret = sgetb32(f, &v_pos);
+ 1921 3632547 : if (ret < 0) {
1922 : /* LCOV_EXCL_START */
1923 : decoding_error(path, f);
1924 : os_abort();
1925 : /* LCOV_EXCL_STOP */
1926 : }
1927 :
- 1928 3632690 : ret = sgetb32(f, &v_count);
- 1929 3632690 : if (ret < 0) {
+ 1928 3632547 : ret = sgetb32(f, &v_count);
+ 1929 3632547 : if (ret < 0) {
1930 : /* LCOV_EXCL_START */
1931 : decoding_error(path, f);
1932 : os_abort();
1933 : /* LCOV_EXCL_STOP */
1934 : }
1935 :
- 1936 3632690 : if (v_idx + v_count > file->blockmax) {
+ 1936 3632547 : if (v_idx + v_count > file->blockmax) {
1937 : /* LCOV_EXCL_START */
1938 : decoding_error(path, f);
1939 : log_fatal("Internal inconsistency in block number!\n");
@@ -2003,7 +2003,7 @@
1941 : /* LCOV_EXCL_STOP */
1942 : }
1943 :
- 1944 3632689 : if (v_pos + v_count > blockmax) {
+ 1944 3632547 : if (v_pos + v_count > blockmax) {
1945 : /* LCOV_EXCL_START */
1946 : decoding_error(path, f);
1947 : log_fatal("Internal inconsistency in block size %u/%u!\n", blockmax, v_pos + v_count);
@@ -2038,9 +2038,9 @@
1976 : }
1977 :
1978 : /* read the hash only for 'blk/chg/rep', and not for 'new' */
- 1979 8896647 : if (c != 'n') {
- 1980 8896647 : ret = sread(f, block->hash, BLOCK_HASH_SIZE);
- 1981 8896647 : if (ret < 0) {
+ 1979 8896370 : if (c != 'n') {
+ 1980 8896370 : ret = sread(f, block->hash, BLOCK_HASH_SIZE);
+ 1981 8896370 : if (ret < 0) {
1982 : /* LCOV_EXCL_START */
1983 : decoding_error(path, f);
1984 : os_abort();
@@ -2053,8 +2053,8 @@
1991 :
1992 : /* if the block contains a hash of past data */
1993 : /* and we are clearing such indeterminate hashes */
- 1994 8896647 : if (state->clear_past_hash
- 1995 2542743 : && block_has_past_hash(block)
+ 1994 8896370 : if (state->clear_past_hash
+ 1995 2542370 : && block_has_past_hash(block)
1996 : ) {
1997 : /* set the hash value to INVALID */
1998 28006 : hash_invalid_set(block->hash);
@@ -2065,8 +2065,8 @@
2003 : /* in other sync commands */
2004 : /* note that this is required only in sync, and we detect */
2005 : /* this using the clear_past_hash flag */
- 2006 8896647 : if (state->clear_past_hash
- 2007 2542743 : && state->opt.force_nocopy
+ 2006 8896370 : if (state->clear_past_hash
+ 2007 2542370 : && state->opt.force_nocopy
2008 14195 : && block_state_get(block) == BLOCK_STATE_REP
2009 : ) {
2010 : /* set the hash value to INVALID */
@@ -2078,40 +2078,40 @@
2016 : /* if we want a full reallocation, marks block as invalid parity */
2017 : /* note that we do this after the force_nocopy option */
2018 : /* to avoid to mixup the two things */
- 2019 8896647 : if (state->opt.force_realloc
+ 2019 8896370 : if (state->opt.force_realloc
2020 27826 : && block_state_get(block) == BLOCK_STATE_BLK) {
2021 : /* convert from BLK to REP */
2022 27826 : block_state_set(block, BLOCK_STATE_REP);
2023 : }
2024 :
2025 : /* set the parity association */
- 2026 8896647 : fs_allocate(disk, v_pos, file, v_idx);
+ 2026 8896370 : fs_allocate(disk, v_pos, file, v_idx);
2027 :
2028 : /* go to the next block */
- 2029 8896647 : ++v_idx;
- 2030 8896647 : ++v_pos;
- 2031 8896647 : --v_count;
+ 2029 8896370 : ++v_idx;
+ 2030 8896370 : ++v_pos;
+ 2031 8896370 : --v_count;
2032 : }
2033 : }
2034 :
2035 : /* stat */
- 2036 3612017 : ++count_file;
- 2037 123556 : } else if (c == 'i') {
+ 2036 3611886 : ++count_file;
+ 2037 123579 : } else if (c == 'i') {
2038 : /* "inf" command */
2039 : snapraid_info info;
2040 : uint32_t v_pos;
2041 : uint32_t v_oldest;
2042 :
- 2043 251 : ret = sgetb32(f, &v_oldest);
- 2044 251 : if (ret < 0) {
+ 2043 252 : ret = sgetb32(f, &v_oldest);
+ 2044 252 : if (ret < 0) {
2045 : /* LCOV_EXCL_START */
2046 : decoding_error(path, f);
2047 : os_abort();
2048 : /* LCOV_EXCL_STOP */
2049 : }
2050 :
- 2051 251 : v_pos = 0;
- 2052 55933 : while (v_pos < blockmax) {
+ 2051 252 : v_pos = 0;
+ 2052 55630 : while (v_pos < blockmax) {
2053 : int bad;
2054 : int rehash;
2055 : int justsynced;
@@ -2119,15 +2119,15 @@
2057 : uint32_t flag;
2058 : uint32_t v_count;
2059 :
- 2060 55431 : ret = sgetb32(f, &v_count);
- 2061 55431 : if (ret < 0) {
+ 2060 55126 : ret = sgetb32(f, &v_count);
+ 2061 55126 : if (ret < 0) {
2062 : /* LCOV_EXCL_START */
2063 : decoding_error(path, f);
2064 : os_abort();
2065 : /* LCOV_EXCL_STOP */
2066 : }
2067 :
- 2068 55431 : if (v_pos + v_count > blockmax) {
+ 2068 55126 : if (v_pos + v_count > blockmax) {
2069 : /* LCOV_EXCL_START */
2070 : decoding_error(path, f);
2071 : log_fatal("Internal inconsistency in info size %u/%u!\n", blockmax, v_pos + v_count);
@@ -2135,8 +2135,8 @@
2073 : /* LCOV_EXCL_STOP */
2074 : }
2075 :
- 2076 55431 : ret = sgetb32(f, &flag);
- 2077 55431 : if (ret < 0) {
+ 2076 55126 : ret = sgetb32(f, &flag);
+ 2077 55126 : if (ret < 0) {
2078 : /* LCOV_EXCL_START */
2079 : decoding_error(path, f);
2080 : os_abort();
@@ -2144,10 +2144,10 @@
2082 : }
2083 :
2084 : /* if there is an info */
- 2085 55431 : if ((flag & 1) != 0) {
+ 2085 55126 : if ((flag & 1) != 0) {
2086 : /* read the time */
- 2087 55416 : ret = sgetb32(f, &t);
- 2088 55416 : if (ret < 0) {
+ 2087 55111 : ret = sgetb32(f, &t);
+ 2088 55111 : if (ret < 0) {
2089 : /* LCOV_EXCL_START */
2090 : decoding_error(path, f);
2091 : os_abort();
@@ -2155,11 +2155,11 @@
2093 : }
2094 :
2095 : /* analyze the flags */
- 2096 55416 : bad = (flag & 2) != 0;
- 2097 55416 : rehash = (flag & 4) != 0;
- 2098 55416 : justsynced = (flag & 8) != 0;
+ 2096 55111 : bad = (flag & 2) != 0;
+ 2097 55111 : rehash = (flag & 4) != 0;
+ 2098 55111 : justsynced = (flag & 8) != 0;
2099 :
- 2100 55416 : if (rehash && state->prevhash == HASH_UNDEFINED) {
+ 2100 55111 : if (rehash && state->prevhash == HASH_UNDEFINED) {
2101 : /* LCOV_EXCL_START */
2102 : decoding_error(path, f);
2103 : log_fatal("Internal inconsistency for missing previous checksum!\n");
@@ -2167,18 +2167,18 @@
2105 : /* LCOV_EXCL_STOP */
2106 : }
2107 :
- 2108 55416 : info = info_make(t + v_oldest, bad, rehash, justsynced);
+ 2108 55111 : info = info_make(t + v_oldest, bad, rehash, justsynced);
2109 : } else {
2110 15 : info = 0;
2111 : }
2112 :
- 2113 1658673 : while (v_count) {
+ 2113 1658119 : while (v_count) {
2114 : /* insert the info in the array */
- 2115 1547811 : info_set(&state->infoarr, v_pos, info);
+ 2115 1547867 : info_set(&state->infoarr, v_pos, info);
2116 :
2117 : /* ensure that an info is present only for used positions */
- 2118 1547811 : if (fs_info_is_required(state, v_pos)) {
- 2119 1489110 : if (!info) {
+ 2118 1547867 : if (fs_info_is_required(state, v_pos)) {
+ 2119 1489134 : if (!info) {
2120 : /* LCOV_EXCL_START */
2121 : decoding_error(path, f);
2122 : log_fatal("Internal inconsistency for missing info!\n");
@@ -2191,41 +2191,41 @@
2129 : }
2130 :
2131 : /* go to next block */
- 2132 1547811 : ++v_pos;
- 2133 1547811 : --v_count;
+ 2132 1547867 : ++v_pos;
+ 2133 1547867 : --v_count;
2134 : }
2135 : }
- 2136 123305 : } else if (c == 'h') {
+ 2136 123327 : } else if (c == 'h') {
2137 : /* hole */
2138 : uint32_t v_pos;
2139 : struct snapraid_disk* disk;
2140 : uint32_t mapping;
2141 :
- 2142 1387 : ret = sgetb32(f, &mapping);
- 2143 1387 : if (ret < 0 || mapping >= mapping_max) {
+ 2142 1392 : ret = sgetb32(f, &mapping);
+ 2143 1392 : if (ret < 0 || mapping >= mapping_max) {
2144 : /* LCOV_EXCL_START */
2145 : decoding_error(path, f);
2146 : log_fatal("Internal inconsistency in mapping index!\n");
2147 : os_abort();
2148 : /* LCOV_EXCL_STOP */
2149 : }
- 2150 1387 : disk = tommy_array_get(&disk_mapping, mapping);
+ 2150 1392 : disk = tommy_array_get(&disk_mapping, mapping);
2151 :
- 2152 1387 : v_pos = 0;
- 2153 4227 : while (v_pos < blockmax) {
+ 2152 1392 : v_pos = 0;
+ 2153 4242 : while (v_pos < blockmax) {
2154 : uint32_t v_idx;
2155 : uint32_t v_count;
2156 : struct snapraid_file* deleted;
2157 :
- 2158 1453 : ret = sgetb32(f, &v_count);
- 2159 1453 : if (ret < 0) {
+ 2158 1458 : ret = sgetb32(f, &v_count);
+ 2159 1458 : if (ret < 0) {
2160 : /* LCOV_EXCL_START */
2161 : decoding_error(path, f);
2162 : os_abort();
2163 : /* LCOV_EXCL_STOP */
2164 : }
2165 :
- 2166 1453 : if (v_pos + v_count > blockmax) {
+ 2166 1458 : if (v_pos + v_count > blockmax) {
2167 : /* LCOV_EXCL_START */
2168 : decoding_error(path, f);
2169 : log_fatal("Internal inconsistency in hole size %u/%u!\n", blockmax, v_pos + v_count);
@@ -2234,9 +2234,9 @@
2172 : }
2173 :
2174 : /* get the sub-command */
- 2175 1453 : c = sgetc(f);
+ 2175 1458 : c = sgetc(f);
2176 :
- 2177 1453 : switch (c) {
+ 2177 1458 : switch (c) {
2178 : case 'o' :
2179 : /* if it's a run of deleted blocks */
2180 :
@@ -2283,8 +2283,8 @@
2221 35 : break;
2222 : case 'O' :
2223 : /* go to the next run */
- 2224 1418 : v_pos += v_count;
- 2225 1418 : break;
+ 2224 1423 : v_pos += v_count;
+ 2225 1423 : break;
2226 : default :
2227 : /* LCOV_EXCL_START */
2228 : decoding_error(path, f);
@@ -2293,7 +2293,7 @@
2231 : /* LCOV_EXCL_STOP */
2232 : }
2233 : }
- 2234 121918 : } else if (c == 's') {
+ 2234 121935 : } else if (c == 's') {
2235 : /* symlink */
2236 : char sub[PATH_MAX];
2237 : char linkto[PATH_MAX];
@@ -2344,7 +2344,7 @@
2282 :
2283 : /* stat */
2284 116468 : ++count_symlink;
- 2285 5450 : } else if (c == 'a') {
+ 2285 5467 : } else if (c == 'a') {
2286 : /* hardlink */
2287 : char sub[PATH_MAX];
2288 : char linkto[PATH_MAX];
@@ -2403,7 +2403,7 @@
2341 :
2342 : /* stat */
2343 597 : ++count_hardlink;
- 2344 4853 : } else if (c == 'r') {
+ 2344 4870 : } else if (c == 'r') {
2345 : /* dir */
2346 : char sub[PATH_MAX];
2347 : struct snapraid_dir* dir;
@@ -2445,14 +2445,14 @@
2383 :
2384 : /* stat */
2385 790 : ++count_dir;
- 2386 4063 : } else if (c == 'c') {
+ 2386 4080 : } else if (c == 'c') {
2387 : /* get the subcommand */
- 2388 252 : c = sgetc(f);
+ 2388 253 : c = sgetc(f);
2389 :
- 2390 252 : switch (c) {
+ 2390 253 : switch (c) {
2391 : case 'u' :
- 2392 164 : state->hash = HASH_MURMUR3;
- 2393 164 : break;
+ 2392 165 : state->hash = HASH_MURMUR3;
+ 2393 165 : break;
2394 : case 'k' :
2395 88 : state->hash = HASH_SPOOKY2;
2396 88 : break;
@@ -2465,14 +2465,14 @@
2403 : }
2404 :
2405 : /* read the seed */
- 2406 252 : ret = sread(f, state->hashseed, HASH_MAX);
- 2407 252 : if (ret < 0) {
+ 2406 253 : ret = sread(f, state->hashseed, HASH_MAX);
+ 2407 253 : if (ret < 0) {
2408 : /* LCOV_EXCL_START */
2409 : decoding_error(path, f);
2410 : os_abort();
2411 : /* LCOV_EXCL_STOP */
2412 : }
- 2413 3811 : } else if (c == 'C') {
+ 2413 3827 : } else if (c == 'C') {
2414 : /* get the sub-command */
2415 4 : c = sgetc(f);
2416 :
@@ -2499,18 +2499,18 @@
2437 : os_abort();
2438 : /* LCOV_EXCL_STOP */
2439 : }
- 2440 3807 : } else if (c == 'z') {
+ 2440 3823 : } else if (c == 'z') {
2441 : uint32_t block_size;
2442 :
- 2443 252 : ret = sgetb32(f, &block_size);
- 2444 252 : if (ret < 0) {
+ 2443 253 : ret = sgetb32(f, &block_size);
+ 2444 253 : if (ret < 0) {
2445 : /* LCOV_EXCL_START */
2446 : decoding_error(path, f);
2447 : os_abort();
2448 : /* LCOV_EXCL_STOP */
2449 : }
2450 :
- 2451 252 : if (block_size == 0) {
+ 2451 253 : if (block_size == 0) {
2452 : /* LCOV_EXCL_START */
2453 : decoding_error(path, f);
2454 : log_fatal("Zero 'blocksize' specification in the content file!\n");
@@ -2519,11 +2519,11 @@
2457 : }
2458 :
2459 : /* without configuration, auto assign the block size */
- 2460 252 : if (state->no_conf) {
+ 2460 253 : if (state->no_conf) {
2461 1 : state->block_size = block_size;
2462 : }
2463 :
- 2464 252 : if (block_size != state->block_size) {
+ 2464 253 : if (block_size != state->block_size) {
2465 : /* LCOV_EXCL_START */
2466 : decoding_error(path, f);
2467 : log_fatal("Mismatching 'blocksize' specification in the content file!\n");
@@ -2531,18 +2531,18 @@
2469 : exit(EXIT_FAILURE);
2470 : /* LCOV_EXCL_STOP */
2471 : }
- 2472 3555 : } else if (c == 'y') {
+ 2472 3570 : } else if (c == 'y') {
2473 : uint32_t hash_size;
2474 :
- 2475 252 : ret = sgetb32(f, &hash_size);
- 2476 252 : if (ret < 0) {
+ 2475 253 : ret = sgetb32(f, &hash_size);
+ 2476 253 : if (ret < 0) {
2477 : /* LCOV_EXCL_START */
2478 : decoding_error(path, f);
2479 : os_abort();
2480 : /* LCOV_EXCL_STOP */
2481 : }
2482 :
- 2483 252 : if (hash_size < 2 || hash_size > HASH_MAX) {
+ 2483 253 : if (hash_size < 2 || hash_size > HASH_MAX) {
2484 : /* LCOV_EXCL_START */
2485 : decoding_error(path, f);
2486 : log_fatal("Invalid 'hashsize' specification in the content file!\n");
@@ -2551,11 +2551,11 @@
2489 : }
2490 :
2491 : /* without configuration, auto assign the block size */
- 2492 252 : if (state->no_conf) {
+ 2492 253 : if (state->no_conf) {
2493 1 : BLOCK_HASH_SIZE = hash_size;
2494 : }
2495 :
- 2496 252 : if ((int)hash_size != BLOCK_HASH_SIZE) {
+ 2496 253 : if ((int)hash_size != BLOCK_HASH_SIZE) {
2497 : /* LCOV_EXCL_START */
2498 : decoding_error(path, f);
2499 : log_fatal("Mismatching 'hashsize' specification in the content file!\n");
@@ -2563,15 +2563,15 @@
2501 : exit(EXIT_FAILURE);
2502 : /* LCOV_EXCL_STOP */
2503 : }
- 2504 3303 : } else if (c == 'x') {
- 2505 252 : ret = sgetb32(f, &blockmax);
- 2506 252 : if (ret < 0) {
+ 2504 3317 : } else if (c == 'x') {
+ 2505 253 : ret = sgetb32(f, &blockmax);
+ 2506 253 : if (ret < 0) {
2507 : /* LCOV_EXCL_START */
2508 : decoding_error(path, f);
2509 : os_abort();
2510 : /* LCOV_EXCL_STOP */
2511 : }
- 2512 4444 : } else if (c == 'm' || c == 'M') {
+ 2512 4462 : } else if (c == 'm' || c == 'M') {
2513 : struct snapraid_map* map;
2514 : char uuid[UUID_MAX];
2515 : uint32_t v_pos;
@@ -2579,16 +2579,16 @@
2517 : uint32_t v_free_blocks;
2518 : struct snapraid_disk* disk;
2519 :
- 2520 1393 : ret = sgetbs(f, buffer, sizeof(buffer));
- 2521 1393 : if (ret < 0) {
+ 2520 1398 : ret = sgetbs(f, buffer, sizeof(buffer));
+ 2521 1398 : if (ret < 0) {
2522 : /* LCOV_EXCL_START */
2523 : decoding_error(path, f);
2524 : os_abort();
2525 : /* LCOV_EXCL_STOP */
2526 : }
2527 :
- 2528 1393 : ret = sgetb32(f, &v_pos);
- 2529 1393 : if (ret < 0) {
+ 2528 1398 : ret = sgetb32(f, &v_pos);
+ 2529 1398 : if (ret < 0) {
2530 : /* LCOV_EXCL_START */
2531 : decoding_error(path, f);
2532 : os_abort();
@@ -2596,17 +2596,17 @@
2534 : }
2535 :
2536 : /* from SnapRAID 7.0 the 'M' command includes the free space */
- 2537 1393 : if (c == 'M') {
- 2538 1393 : ret = sgetb32(f, &v_total_blocks);
- 2539 1393 : if (ret < 0) {
+ 2537 1398 : if (c == 'M') {
+ 2538 1398 : ret = sgetb32(f, &v_total_blocks);
+ 2539 1398 : if (ret < 0) {
2540 : /* LCOV_EXCL_START */
2541 : decoding_error(path, f);
2542 : os_abort();
2543 : /* LCOV_EXCL_STOP */
2544 : }
2545 :
- 2546 1393 : ret = sgetb32(f, &v_free_blocks);
- 2547 1393 : if (ret < 0) {
+ 2546 1398 : ret = sgetb32(f, &v_free_blocks);
+ 2547 1398 : if (ret < 0) {
2548 : /* LCOV_EXCL_START */
2549 : decoding_error(path, f);
2550 : os_abort();
@@ -2618,8 +2618,8 @@
2556 : }
2557 :
2558 : /* read the uuid */
- 2559 1393 : ret = sgetbs(f, uuid, sizeof(uuid));
- 2560 1393 : if (ret < 0) {
+ 2559 1398 : ret = sgetbs(f, uuid, sizeof(uuid));
+ 2560 1398 : if (ret < 0) {
2561 : /* LCOV_EXCL_START */
2562 : decoding_error(path, f);
2563 : os_abort();
@@ -2627,8 +2627,8 @@
2565 : }
2566 :
2567 : /* find the disk */
- 2568 1393 : disk = find_disk_by_name(state, buffer);
- 2569 1393 : if (!disk) {
+ 2568 1398 : disk = find_disk_by_name(state, buffer);
+ 2569 1398 : if (!disk) {
2570 : /* search by UUID if renamed */
2571 2 : disk = find_disk_by_uuid(state, uuid);
2572 2 : if (disk) {
@@ -2638,7 +2638,7 @@
2576 2 : state->need_write = 1;
2577 : }
2578 : }
- 2579 1393 : if (!disk) {
+ 2579 1398 : if (!disk) {
2580 : /* LCOV_EXCL_START */
2581 : decoding_error(path, f);
2582 : log_fatal("Disk '%s' with uuid '%s' not present in the configuration file!\n", buffer, uuid);
@@ -2650,15 +2650,15 @@
2588 : /* LCOV_EXCL_STOP */
2589 : }
2590 :
- 2591 1393 : map = map_alloc(disk->name, v_pos, v_total_blocks, v_free_blocks, uuid);
+ 2591 1398 : map = map_alloc(disk->name, v_pos, v_total_blocks, v_free_blocks, uuid);
2592 :
- 2593 1393 : tommy_list_insert_tail(&state->maplist, &map->node, map);
+ 2593 1398 : tommy_list_insert_tail(&state->maplist, &map->node, map);
2594 :
2595 : /* insert in the mapping vector */
- 2596 1393 : tommy_array_grow(&disk_mapping, mapping_max + 1);
- 2597 1393 : tommy_array_set(&disk_mapping, mapping_max, disk);
- 2598 1393 : ++mapping_max;
- 2599 1658 : } else if (c == 'P') {
+ 2596 1398 : tommy_array_grow(&disk_mapping, mapping_max + 1);
+ 2597 1398 : tommy_array_set(&disk_mapping, mapping_max, disk);
+ 2598 1398 : ++mapping_max;
+ 2599 1666 : } else if (c == 'P') {
2600 : /* from SnapRAID 7.0 the 'P' command includes the free space */
2601 : /* from SnapRAID 11.0 the 'P' command is deprecated by 'Q' */
2602 : char v_uuid[UUID_MAX];
@@ -2720,7 +2720,7 @@
2658 0 : state->parity[v_level].total_blocks = v_total_blocks;
2659 0 : state->parity[v_level].free_blocks = v_free_blocks;
2660 : }
- 2661 1658 : } else if (c == 'Q') {
+ 2661 1666 : } else if (c == 'Q') {
2662 : /* from SnapRAID 11.0 the 'Q' command include size info and multi file support */
2663 : uint32_t v_level;
2664 : uint32_t v_total_blocks;
@@ -2728,39 +2728,39 @@
2666 : uint32_t v_split_mac;
2667 : unsigned s;
2668 :
- 2669 1407 : ret = sgetb32(f, &v_level);
- 2670 1407 : if (ret < 0) {
+ 2669 1414 : ret = sgetb32(f, &v_level);
+ 2670 1414 : if (ret < 0) {
2671 : /* LCOV_EXCL_START */
2672 : decoding_error(path, f);
2673 : os_abort();
2674 : /* LCOV_EXCL_STOP */
2675 : }
2676 :
- 2677 1407 : ret = sgetb32(f, &v_total_blocks);
- 2678 1407 : if (ret < 0) {
+ 2677 1414 : ret = sgetb32(f, &v_total_blocks);
+ 2678 1414 : if (ret < 0) {
2679 : /* LCOV_EXCL_START */
2680 : decoding_error(path, f);
2681 : os_abort();
2682 : /* LCOV_EXCL_STOP */
2683 : }
2684 :
- 2685 1407 : ret = sgetb32(f, &v_free_blocks);
- 2686 1407 : if (ret < 0) {
+ 2685 1414 : ret = sgetb32(f, &v_free_blocks);
+ 2686 1414 : if (ret < 0) {
2687 : /* LCOV_EXCL_START */
2688 : decoding_error(path, f);
2689 : os_abort();
2690 : /* LCOV_EXCL_STOP */
2691 : }
2692 :
- 2693 1407 : ret = sgetb32(f, &v_split_mac);
- 2694 1407 : if (ret < 0) {
+ 2693 1414 : ret = sgetb32(f, &v_split_mac);
+ 2694 1414 : if (ret < 0) {
2695 : /* LCOV_EXCL_START */
2696 : decoding_error(path, f);
2697 : os_abort();
2698 : /* LCOV_EXCL_STOP */
2699 : }
2700 :
- 2701 1407 : if (v_level >= LEV_MAX) {
+ 2701 1414 : if (v_level >= LEV_MAX) {
2702 : /* LCOV_EXCL_START */
2703 : decoding_error(path, f);
2704 : log_fatal("Invalid parity level '%u' in the configuration file!\n", v_level);
@@ -2769,7 +2769,7 @@
2707 : }
2708 :
2709 : /* auto configure if configuration is missing */
- 2710 1407 : if (state->no_conf) {
+ 2710 1414 : if (state->no_conf) {
2711 6 : if (v_level >= state->level)
2712 5 : state->level = v_level + 1;
2713 6 : if (state->parity[v_level].split_mac < v_split_mac)
@@ -2777,35 +2777,35 @@
2715 : }
2716 :
2717 : /* if we use this parity entry */
- 2718 1407 : if (v_level < state->level) {
+ 2718 1414 : if (v_level < state->level) {
2719 : /* set the parity info */
- 2720 1153 : state->parity[v_level].total_blocks = v_total_blocks;
- 2721 1153 : state->parity[v_level].free_blocks = v_free_blocks;
+ 2720 1155 : state->parity[v_level].total_blocks = v_total_blocks;
+ 2721 1155 : state->parity[v_level].free_blocks = v_free_blocks;
2722 : }
2723 :
- 2724 7035 : for (s = 0; s < v_split_mac; ++s) {
+ 2724 7066 : for (s = 0; s < v_split_mac; ++s) {
2725 : char v_path[PATH_MAX];
2726 : char v_uuid[UUID_MAX];
2727 : uint64_t v_size;
2728 :
- 2729 5628 : ret = sgetbs(f, v_path, sizeof(v_path));
- 2730 5628 : if (ret < 0) {
+ 2729 5653 : ret = sgetbs(f, v_path, sizeof(v_path));
+ 2730 5653 : if (ret < 0) {
2731 : /* LCOV_EXCL_START */
2732 : decoding_error(path, f);
2733 : os_abort();
2734 : /* LCOV_EXCL_STOP */
2735 : }
2736 :
- 2737 5628 : ret = sgetbs(f, v_uuid, sizeof(v_uuid));
- 2738 5628 : if (ret < 0) {
+ 2737 5652 : ret = sgetbs(f, v_uuid, sizeof(v_uuid));
+ 2738 5652 : if (ret < 0) {
2739 : /* LCOV_EXCL_START */
2740 : decoding_error(path, f);
2741 : os_abort();
2742 : /* LCOV_EXCL_STOP */
2743 : }
2744 :
- 2745 5628 : ret = sgetb64(f, &v_size);
- 2746 5628 : if (ret < 0) {
+ 2745 5652 : ret = sgetb64(f, &v_size);
+ 2746 5652 : if (ret < 0) {
2747 : /* LCOV_EXCL_START */
2748 : decoding_error(path, f);
2749 : os_abort();
@@ -2813,9 +2813,9 @@
2751 : }
2752 :
2753 : /* if we use this parity entry */
- 2754 5628 : if (v_level < state->level) {
+ 2754 5652 : if (v_level < state->level) {
2755 : /* if this split was removed from the configuration */
- 2756 4612 : if (s >= state->parity[v_level].split_mac) {
+ 2756 4616 : if (s >= state->parity[v_level].split_mac) {
2757 : /* if the file is used, we really need it */
2758 0 : if (v_size != 0) {
2759 : /* LCOV_EXCL_START */
@@ -2830,30 +2830,30 @@
2768 0 : log_fatal("WARNING! Dropping from '%s' unused split '%u'\n", lev_config_name(v_level), s);
2769 : } else {
2770 : /* we copy the path only if without configuration file */
- 2771 4612 : if (state->no_conf)
+ 2771 4616 : if (state->no_conf)
2772 24 : pathcpy(state->parity[v_level].split_map[s].path, sizeof(state->parity[v_level].split_map[s].path), v_path);
2773 :
2774 : /* set the split info */
- 2775 4612 : pathcpy(state->parity[v_level].split_map[s].uuid, sizeof(state->parity[v_level].split_map[s].uuid), v_uuid);
- 2776 4612 : state->parity[v_level].split_map[s].size = v_size;
+ 2775 4616 : pathcpy(state->parity[v_level].split_map[s].uuid, sizeof(state->parity[v_level].split_map[s].uuid), v_uuid);
+ 2776 4616 : state->parity[v_level].split_map[s].size = v_size;
2777 :
2778 : /* log the info read from the content file */
- 2779 9224 : log_tag("content:%s:%u:%s:%s:%" PRIi64 "\n", lev_config_name(v_level), s,
- 2780 4612 : state->parity[v_level].split_map[s].path,
- 2781 4612 : state->parity[v_level].split_map[s].uuid,
+ 2779 9232 : log_tag("content:%s:%u:%s:%s:%" PRIi64 "\n", lev_config_name(v_level), s,
+ 2780 4616 : state->parity[v_level].split_map[s].path,
+ 2781 4616 : state->parity[v_level].split_map[s].uuid,
2782 : state->parity[v_level].split_map[s].size);
2783 : }
2784 : }
2785 : }
- 2786 251 : } else if (c == 'N') {
+ 2786 252 : } else if (c == 'N') {
2787 : uint32_t crc_stored;
2788 : uint32_t crc_computed;
2789 :
2790 : /* get the crc before reading it from the file */
- 2791 251 : crc_computed = scrc(f);
+ 2791 252 : crc_computed = scrc(f);
2792 :
- 2793 251 : ret = sgetble32(f, &crc_stored);
- 2794 251 : if (ret < 0) {
+ 2793 252 : ret = sgetble32(f, &crc_stored);
+ 2794 252 : if (ret < 0) {
2795 : /* LCOV_EXCL_START */
2796 : /* here don't call decoding_error() because it's too late to get the crc */
2797 : log_fatal("Error reading the CRC in '%s' at offset %" PRIi64 "\n", path, stell(f));
@@ -2862,7 +2862,7 @@
2800 : /* LCOV_EXCL_STOP */
2801 : }
2802 :
- 2803 251 : if (crc_stored != crc_computed) {
+ 2803 252 : if (crc_stored != crc_computed) {
2804 : /* LCOV_EXCL_START */
2805 : /* here don't call decoding_error() because it's too late to get the crc */
2806 : log_fatal("Mismatching CRC in '%s'\n", path);
@@ -2871,7 +2871,7 @@
2809 : /* LCOV_EXCL_STOP */
2810 : }
2811 :
- 2812 251 : crc_checked = 1;
+ 2812 252 : crc_checked = 1;
2813 : } else {
2814 : /* LCOV_EXCL_START */
2815 : decoding_error(path, f);
@@ -2879,18 +2879,18 @@
2817 : os_abort();
2818 : /* LCOV_EXCL_STOP */
2819 : }
- 2820 3735573 : }
+ 2820 3735464 : }
2821 :
- 2822 251 : tommy_array_done(&disk_mapping);
+ 2822 252 : tommy_array_done(&disk_mapping);
2823 :
- 2824 251 : if (serror(f)) {
+ 2824 252 : if (serror(f)) {
2825 : /* LCOV_EXCL_START */
2826 : log_fatal("Error reading the content file '%s' at offset %" PRIi64 "\n", path, stell(f));
2827 : exit(EXIT_FAILURE);
2828 : /* LCOV_EXCL_STOP */
2829 : }
2830 :
- 2831 251 : if (!crc_checked) {
+ 2831 252 : if (!crc_checked) {
2832 : /* LCOV_EXCL_START */
2833 : log_fatal("Finished reading '%s' without finding the CRC\n", path);
2834 : log_fatal("This content file is truncated or damaged! Use an alternate copy.\n");
@@ -2899,10 +2899,10 @@
2837 : }
2838 :
2839 : /* check the file-system on all disks */
- 2840 251 : state_fscheck(state, "after read");
+ 2840 252 : state_fscheck(state, "after read");
2841 :
2842 : /* check that the stored parity size matches the loaded state */
- 2843 251 : if (blockmax != parity_allocated_size(state)) {
+ 2843 252 : if (blockmax != parity_allocated_size(state)) {
2844 : /* LCOV_EXCL_START */
2845 : log_fatal("Internal inconsistency in parity size %u/%u in '%s' at offset %" PRIi64 "\n", blockmax, parity_allocated_size(state), path, stell(f));
2846 : if (state->opt.skip_content_check) {
@@ -2914,11 +2914,11 @@
2852 : /* LCOV_EXCL_STOP */
2853 : }
2854 :
- 2855 251 : msg_verbose("%8u files\n", count_file);
- 2856 251 : msg_verbose("%8u hardlinks\n", count_hardlink);
- 2857 251 : msg_verbose("%8u symlinks\n", count_symlink);
- 2858 251 : msg_verbose("%8u empty dirs\n", count_dir);
- 2859 251 : }
+ 2855 252 : msg_verbose("%8u files\n", count_file);
+ 2856 252 : msg_verbose("%8u hardlinks\n", count_hardlink);
+ 2857 252 : msg_verbose("%8u symlinks\n", count_symlink);
+ 2858 252 : msg_verbose("%8u empty dirs\n", count_dir);
+ 2859 252 : }
2860 :
2861 : struct state_write_thread_context {
2862 : struct snapraid_state* state;
@@ -3141,30 +3141,30 @@
3079 :
3080 : /* for all the blocks of the file */
3081 1770884 : begin = 0;
- 3082 5322967 : while (begin < file->blockmax) {
- 3083 1781199 : unsigned v_state = block_state_get(fs_file2block_get(file, begin));
- 3084 1781199 : block_off_t v_pos = fs_file2par_get(disk, file, begin);
+ 3082 5322945 : while (begin < file->blockmax) {
+ 3083 1781177 : unsigned v_state = block_state_get(fs_file2block_get(file, begin));
+ 3084 1781177 : block_off_t v_pos = fs_file2par_get(disk, file, begin);
3085 : uint32_t v_count;
3086 :
3087 : block_off_t end;
3088 :
3089 : /* find the end of run of blocks */
- 3090 1781199 : end = begin + 1;
- 3091 6146339 : while (end < file->blockmax) {
+ 3090 1781177 : end = begin + 1;
+ 3091 6146317 : while (end < file->blockmax) {
3092 2596728 : if (v_state != block_state_get(fs_file2block_get(file, end)))
3093 12 : break;
3094 2596716 : if (v_pos + (end - begin) != fs_file2par_get(disk, file, end))
- 3095 12775 : break;
- 3096 2583941 : ++end;
+ 3095 12753 : break;
+ 3096 2583963 : ++end;
3097 : }
3098 :
- 3099 1781199 : switch (v_state) {
+ 3099 1781177 : switch (v_state) {
3100 : case BLOCK_STATE_BLK :
- 3101 1678581 : sputc('b', f);
- 3102 1678581 : break;
+ 3101 1678520 : sputc('b', f);
+ 3102 1678520 : break;
3103 : case BLOCK_STATE_CHG :
- 3104 67700 : sputc('g', f);
- 3105 67700 : break;
+ 3104 67739 : sputc('g', f);
+ 3105 67739 : break;
3106 : case BLOCK_STATE_REP :
3107 34918 : sputc('p', f);
3108 34918 : break;
@@ -3175,19 +3175,19 @@
3113 : /* LCOV_EXCL_STOP */
3114 : }
3115 :
- 3116 1781199 : sputb32(v_pos, f);
+ 3116 1781177 : sputb32(v_pos, f);
3117 :
- 3118 1781199 : v_count = end - begin;
- 3119 1781199 : sputb32(v_count, f);
+ 3118 1781177 : v_count = end - begin;
+ 3119 1781177 : sputb32(v_count, f);
3120 :
3121 : /* write hashes */
- 3122 6146339 : for (idx = begin; idx < end; ++idx) {
+ 3122 6146317 : for (idx = begin; idx < end; ++idx) {
3123 4365140 : struct snapraid_block* block = fs_file2block_get(file, idx);
3124 :
3125 4365140 : swrite(block->hash, BLOCK_HASH_SIZE, f);
3126 : }
3127 :
- 3128 1781199 : if (serror(f)) {
+ 3128 1781177 : if (serror(f)) {
3129 : /* LCOV_EXCL_START */
3130 : log_fatal("Error writing the content file '%s'. %s.\n", serrorfile(f), strerror(errno));
3131 : return context;
@@ -3195,7 +3195,7 @@
3133 : }
3134 :
3135 : /* next begin position */
- 3136 1781199 : begin = end;
+ 3136 1781177 : begin = end;
3137 : }
3138 :
3139 1770884 : ++count_file;
@@ -3304,44 +3304,44 @@
3242 151 : sputc('i', f);
3243 151 : sputb32(info_oldest, f);
3244 151 : begin = 0;
- 3245 19734 : while (begin < blockmax) {
+ 3245 19645 : while (begin < blockmax) {
3246 : snapraid_info info;
3247 : block_off_t end;
3248 : time_t t;
3249 : unsigned flag;
3250 :
- 3251 19432 : info = info_get(&state->infoarr, begin);
+ 3251 19343 : info = info_get(&state->infoarr, begin);
3252 :
3253 : /* find the end of run of blocks */
- 3254 19432 : end = begin + 1;
- 3255 775531 : while (end < blockmax
+ 3254 19343 : end = begin + 1;
+ 3255 775442 : while (end < blockmax
3256 755951 : && info == info_get(&state->infoarr, end)
3257 : ) {
- 3258 736667 : ++end;
+ 3258 736756 : ++end;
3259 : }
3260 :
- 3261 19432 : sputb32(end - begin, f);
+ 3261 19343 : sputb32(end - begin, f);
3262 :
3263 : /* if there is info */
- 3264 19432 : if (info) {
+ 3264 19343 : if (info) {
3265 : /* other flags */
- 3266 19409 : flag = 1; /* info is present */
- 3267 19409 : if (info_get_bad(info))
- 3268 1358 : flag |= 2;
- 3269 19409 : if (info_get_rehash(info))
+ 3266 19320 : flag = 1; /* info is present */
+ 3267 19320 : if (info_get_bad(info))
+ 3268 1340 : flag |= 2;
+ 3269 19320 : if (info_get_rehash(info))
3270 5212 : flag |= 4;
- 3271 19409 : if (info_get_justsynced(info))
- 3272 12050 : flag |= 8;
- 3273 19409 : sputb32(flag, f);
+ 3271 19320 : if (info_get_justsynced(info))
+ 3272 12001 : flag |= 8;
+ 3273 19320 : sputb32(flag, f);
3274 :
- 3275 19409 : t = info_get_time(info) - info_oldest;
- 3276 19409 : sputb32(t, f);
+ 3275 19320 : t = info_get_time(info) - info_oldest;
+ 3276 19320 : sputb32(t, f);
3277 : } else {
3278 : /* write a special 0 flag to mark missing info */
3279 23 : sputb32(0, f);
3280 : }
3281 :
- 3282 19432 : if (serror(f)) {
+ 3282 19343 : if (serror(f)) {
3283 : /* LCOV_EXCL_START */
3284 : log_fatal("Error writing the content file '%s'. %s.\n", serrorfile(f), strerror(errno));
3285 : return context;
@@ -3349,7 +3349,7 @@
3287 : }
3288 :
3289 : /* next begin position */
- 3290 19432 : begin = end;
+ 3290 19343 : begin = end;
3291 : }
3292 :
3293 151 : sputc('N', f);
@@ -3438,7 +3438,7 @@
3376 711614 : time_t info_time = info_get_time(info);
3377 :
3378 711614 : if (!info_oldest || info_time < info_oldest)
- 3379 150 : info_oldest = info_time;
+ 3379 151 : info_oldest = info_time;
3380 :
3381 711614 : if (info_get_rehash(info))
3382 13822 : info_has_rehash = 1;
@@ -3689,7 +3689,7 @@
3627 151 : *out_crc = crc;
3628 151 : }
3629 :
- 3630 259 : void state_read(struct snapraid_state* state)
+ 3630 260 : void state_read(struct snapraid_state* state)
3631 : {
3632 : STREAM* f;
3633 : char path[PATH_MAX];
@@ -3699,22 +3699,22 @@
3637 : int c;
3638 :
3639 : /* iterate over all the available content files and load the first one present */
- 3640 259 : f = 0;
- 3641 259 : node = tommy_list_head(&state->contentlist);
- 3642 568 : while (node) {
- 3643 302 : struct snapraid_content* content = node->data;
- 3644 302 : pathcpy(path, sizeof(path), content->content);
+ 3640 260 : f = 0;
+ 3641 260 : node = tommy_list_head(&state->contentlist);
+ 3642 570 : while (node) {
+ 3643 303 : struct snapraid_content* content = node->data;
+ 3644 303 : pathcpy(path, sizeof(path), content->content);
3645 :
- 3646 302 : if (!state->no_conf) {
- 3647 301 : log_tag("content:%s\n", path);
- 3648 301 : log_flush();
+ 3646 303 : if (!state->no_conf) {
+ 3647 302 : log_tag("content:%s\n", path);
+ 3648 302 : log_flush();
3649 : }
- 3650 302 : msg_progress("Loading state from %s...\n", path);
+ 3650 303 : msg_progress("Loading state from %s...\n", path);
3651 :
- 3652 302 : f = sopen_read(path);
- 3653 302 : if (f != 0) {
+ 3652 303 : f = sopen_read(path);
+ 3653 303 : if (f != 0) {
3654 : /* if opened stop the search */
- 3655 252 : break;
+ 3655 253 : break;
3656 : } else {
3657 : /* if it's real error of an existing file, abort */
3658 50 : if (errno != ENOENT) {
@@ -3738,17 +3738,17 @@
3676 : }
3677 :
3678 : /* if not found, assume empty */
- 3679 259 : if (!f) {
+ 3679 260 : if (!f) {
3680 7 : log_fatal("No content file found. Assuming empty.\n");
3681 :
3682 : /* create the initial mapping */
3683 7 : state_map(state);
- 3684 265 : return;
+ 3684 266 : return;
3685 : }
3686 :
3687 : /* get the stat of the content file */
- 3688 252 : ret = fstat(shandle(f), &st);
- 3689 252 : if (ret != 0) {
+ 3688 253 : ret = fstat(shandle(f), &st);
+ 3689 253 : if (ret != 0) {
3690 : /* LCOV_EXCL_START */
3691 : log_fatal("Error stating the content file '%s'. %s.\n", path, strerror(errno));
3692 : exit(EXIT_FAILURE);
@@ -3756,14 +3756,14 @@
3694 : }
3695 :
3696 : /* go further to check other content files */
- 3697 1942 : while (node) {
+ 3697 1946 : while (node) {
3698 : char other_path[PATH_MAX];
3699 : struct stat other_st;
- 3700 1438 : struct snapraid_content* content = node->data;
- 3701 1438 : pathcpy(other_path, sizeof(other_path), content->content);
+ 3700 1440 : struct snapraid_content* content = node->data;
+ 3701 1440 : pathcpy(other_path, sizeof(other_path), content->content);
3702 :
- 3703 1438 : ret = stat(other_path, &other_st);
- 3704 1438 : if (ret != 0) {
+ 3703 1440 : ret = stat(other_path, &other_st);
+ 3704 1440 : if (ret != 0) {
3705 : /* allow missing content files, but not any other kind of error */
3706 1 : if (errno != ENOENT) {
3707 : /* LCOV_EXCL_START */
@@ -3776,7 +3776,7 @@
3714 1 : state->need_write = 1;
3715 : } else {
3716 : /* if the size is different */
- 3717 1437 : if (other_st.st_size != st.st_size) {
+ 3717 1439 : if (other_st.st_size != st.st_size) {
3718 39 : log_fatal("WARNING! Content files '%s' and '%s' have a different size!\n", path, other_path);
3719 39 : log_fatal("Likely one of the two is broken!\n");
3720 :
@@ -3786,28 +3786,28 @@
3724 : }
3725 :
3726 : /* next content file */
- 3727 1438 : node = node->next;
+ 3727 1440 : node = node->next;
3728 : }
3729 :
3730 : /* start with a undefined default. */
3731 : /* it's for compatibility with version 1.0 where MD5 was implicit. */
- 3732 252 : state->hash = HASH_UNDEFINED;
+ 3732 253 : state->hash = HASH_UNDEFINED;
3733 :
3734 : /* start with a zero seed, it was the default in old versions */
- 3735 252 : memset(state->hashseed, 0, HASH_MAX);
+ 3735 253 : memset(state->hashseed, 0, HASH_MAX);
3736 :
3737 : /* previous hash, start with an undefined value */
- 3738 252 : state->prevhash = HASH_UNDEFINED;
+ 3738 253 : state->prevhash = HASH_UNDEFINED;
3739 :
3740 : /* intentionally not set the prevhashseed, if used valgrind will warn about it */
3741 :
3742 : /* get the first char to detect the file type */
- 3743 252 : c = sgetc(f);
- 3744 252 : sungetc(c, f);
+ 3743 253 : c = sgetc(f);
+ 3744 253 : sungetc(c, f);
3745 :
3746 : /* guess the file type from the first char */
- 3747 252 : if (c == 'S') {
- 3748 252 : state_read_content(state, path, f);
+ 3747 253 : if (c == 'S') {
+ 3748 253 : state_read_content(state, path, f);
3749 : } else {
3750 : /* LCOV_EXCL_START */
3751 : log_fatal("From SnapRAID v9.0 the text content file is not supported anymore.\n");
@@ -3816,9 +3816,9 @@
3754 : /* LCOV_EXCL_STOP */
3755 : }
3756 :
- 3757 251 : sclose(f);
+ 3757 252 : sclose(f);
3758 :
- 3759 251 : if (state->hash == HASH_UNDEFINED) {
+ 3759 252 : if (state->hash == HASH_UNDEFINED) {
3760 : /* LCOV_EXCL_START */
3761 : log_fatal("The checksum to use is not specified.\n");
3762 : log_fatal("This happens because you are likely upgrading from SnapRAID 1.0.\n");
@@ -3829,12 +3829,12 @@
3767 : }
3768 :
3769 : /* update the mapping */
- 3770 251 : state_map(state);
+ 3770 252 : state_map(state);
3771 :
- 3772 251 : state_content_check(state, path);
+ 3772 252 : state_content_check(state, path);
3773 :
3774 : /* mark that we read the content file, and it passed all the checks */
- 3775 251 : state->checked_read = 1;
+ 3775 252 : state->checked_read = 1;
3776 : }
3777 :
3778 : struct state_verify_thread_context {
@@ -3866,9 +3866,9 @@
3804 : }
3805 :
3806 : /* get the stored crc from the last four bytes */
- 3807 1012 : crc_stored = buf[0] | (uint32_t)buf[1] << 8 | (uint32_t)buf[2] << 16 | (uint32_t)buf[3] << 24;
+ 3807 1010 : crc_stored = buf[0] | (uint32_t)buf[1] << 8 | (uint32_t)buf[2] << 16 | (uint32_t)buf[3] << 24;
3808 :
- 3809 1012 : if (crc_stored != context->crc) {
+ 3809 1010 : if (crc_stored != context->crc) {
3810 : /* LCOV_EXCL_START */
3811 : log_fatal("DANGER! Wrong stored CRC in '%s'\n", serrorfile(f));
3812 : return context;
@@ -3876,7 +3876,7 @@
3814 : }
3815 :
3816 : /* get the computed crc */
- 3817 1012 : crc_computed = scrc(f);
+ 3817 1010 : crc_computed = scrc(f);
3818 :
3819 : /* adjust the stored crc to include itself */
3820 1012 : crc_stored = crc32c(crc_stored, buf, 4);
@@ -4089,7 +4089,7 @@
4027 78138 : || filter_existence(filter_missing, disk->dir, file->sub) != 0
4028 38646 : || filter_correctness(filter_error, &state->infoarr, disk, file) != 0
4029 : ) {
- 4030 109457 : file_flag_set(file, FILE_IS_EXCLUDED);
+ 4030 109466 : file_flag_set(file, FILE_IS_EXCLUDED);
4031 : }
4032 : }
4033 :
@@ -4229,23 +4229,23 @@
4167 : /**
4168 : * Set the latest tick data in the progress vector.
4169 : */
- 4170 495 : static void state_progress_latest(struct snapraid_state* state)
+ 4170 477 : static void state_progress_latest(struct snapraid_state* state)
4171 : {
4172 : tommy_node* i;
4173 : unsigned l;
4174 :
- 4175 495 : state->progress_tick_misc[state->progress_ptr] = state->tick_misc;
- 4176 495 : state->progress_tick_sched[state->progress_ptr] = state->tick_sched;
- 4177 495 : state->progress_tick_raid[state->progress_ptr] = state->tick_raid;
- 4178 495 : state->progress_tick_hash[state->progress_ptr] = state->tick_hash;
- 4179 495 : state->progress_tick_io[state->progress_ptr] = state->tick_io;
- 4180 3457 : for (i = state->disklist; i != 0; i = i->next) {
- 4181 2962 : struct snapraid_disk* disk = i->data;
- 4182 2962 : disk->progress_tick[state->progress_ptr] = disk->tick;
+ 4175 477 : state->progress_tick_misc[state->progress_ptr] = state->tick_misc;
+ 4176 477 : state->progress_tick_sched[state->progress_ptr] = state->tick_sched;
+ 4177 477 : state->progress_tick_raid[state->progress_ptr] = state->tick_raid;
+ 4178 477 : state->progress_tick_hash[state->progress_ptr] = state->tick_hash;
+ 4179 477 : state->progress_tick_io[state->progress_ptr] = state->tick_io;
+ 4180 3331 : for (i = state->disklist; i != 0; i = i->next) {
+ 4181 2854 : struct snapraid_disk* disk = i->data;
+ 4182 2854 : disk->progress_tick[state->progress_ptr] = disk->tick;
4183 : }
- 4184 2811 : for (l = 0; l < state->level; ++l)
- 4185 2316 : state->parity[l].progress_tick[state->progress_ptr] = state->parity[l].tick;
- 4186 495 : }
+ 4184 2740 : for (l = 0; l < state->level; ++l)
+ 4185 2263 : state->parity[l].progress_tick[state->progress_ptr] = state->parity[l].tick;
+ 4186 477 : }
4187 :
4188 : /**
4189 : * Number of columns
@@ -4395,45 +4395,45 @@
4333 1 : printf("\n");
4334 : }
4335 :
- 4336 1073409 : int state_progress(struct snapraid_state* state, struct snapraid_io* io, block_off_t blockpos, block_off_t countpos, block_off_t countmax, data_off_t countsize)
+ 4336 1073497 : int state_progress(struct snapraid_state* state, struct snapraid_io* io, block_off_t blockpos, block_off_t countpos, block_off_t countmax, data_off_t countsize)
4337 : {
4338 : time_t now;
4339 : int pred;
4340 :
- 4341 1073409 : now = time(0);
+ 4341 1073497 : now = time(0);
4342 :
4343 : /* previous position */
- 4344 1073409 : pred = state->progress_ptr + PROGRESS_MAX - 1;
- 4345 1073409 : if (pred >= PROGRESS_MAX)
- 4346 1073210 : pred -= PROGRESS_MAX;
+ 4344 1073497 : pred = state->progress_ptr + PROGRESS_MAX - 1;
+ 4345 1073497 : if (pred >= PROGRESS_MAX)
+ 4346 1073298 : pred -= PROGRESS_MAX;
4347 :
4348 : /* if the previous measure is different */
- 4349 1073409 : if (state->progress_tick == 0
- 4350 1073210 : || state->progress_time[pred] != now
+ 4349 1073497 : if (state->progress_tick == 0
+ 4350 1073298 : || state->progress_time[pred] != now
4351 : ) {
4352 : time_t elapsed;
- 4353 399 : unsigned out_perc = 0;
- 4354 399 : unsigned out_speed = 0;
- 4355 399 : unsigned out_cpu = 0;
- 4356 399 : unsigned out_eta = 0;
- 4357 399 : int out_computed = 0;
+ 4353 381 : unsigned out_perc = 0;
+ 4354 381 : unsigned out_speed = 0;
+ 4355 381 : unsigned out_cpu = 0;
+ 4356 381 : unsigned out_eta = 0;
+ 4357 381 : int out_computed = 0;
4358 :
4359 : /* store the new measure */
- 4360 399 : state->progress_time[state->progress_ptr] = now;
- 4361 399 : state->progress_pos[state->progress_ptr] = countpos;
- 4362 399 : state->progress_size[state->progress_ptr] = countsize;
- 4363 399 : state_progress_latest(state);
+ 4360 381 : state->progress_time[state->progress_ptr] = now;
+ 4361 381 : state->progress_pos[state->progress_ptr] = countpos;
+ 4362 381 : state->progress_size[state->progress_ptr] = countsize;
+ 4363 381 : state_progress_latest(state);
4364 :
- 4365 399 : elapsed = now - state->progress_whole_start - state->progress_wasted;
+ 4365 381 : elapsed = now - state->progress_whole_start - state->progress_wasted;
4366 :
4367 : /* completion percentage */
- 4368 399 : if (countmax)
- 4369 399 : out_perc = countpos * 100 / countmax;
+ 4368 381 : if (countmax)
+ 4369 381 : out_perc = countpos * 100 / countmax;
4370 :
4371 : /* if we have at least 5 measures */
- 4372 399 : if (state->progress_tick >= 5
+ 4372 381 : if (state->progress_tick >= 5
4373 : /* or if we are running in test mode, with at least one measure */
- 4374 378 : || (state->opt.force_progress && state->progress_tick >= 1)
+ 4374 365 : || (state->opt.force_progress && state->progress_tick >= 1)
4375 : ) {
4376 : int oldest;
4377 : int past;
@@ -4448,88 +4448,88 @@
4386 : uint64_t oldest_tick_total;
4387 :
4388 : /* number of past measures */
- 4389 200 : past = state->progress_tick;
+ 4389 182 : past = state->progress_tick;
4390 :
4391 : /* drop the oldest ones, to promptly */
4392 : /* skip the startup phase */
- 4393 200 : past -= past / 5;
+ 4393 182 : past -= past / 5;
4394 :
4395 : /* check how much we can go in the past */
- 4396 200 : if (past >= PROGRESS_MAX - 1) {
+ 4396 182 : if (past >= PROGRESS_MAX - 1) {
4397 : /* the vector is filled, so we are already in position */
4398 : /* to get the possible oldest one */
4399 0 : oldest = state->progress_ptr + 1;
4400 : } else {
4401 : /* go backward the number of positions selected */
- 4402 200 : oldest = state->progress_ptr + PROGRESS_MAX - past;
+ 4402 182 : oldest = state->progress_ptr + PROGRESS_MAX - past;
4403 : }
- 4404 200 : if (oldest >= PROGRESS_MAX)
- 4405 200 : oldest -= PROGRESS_MAX;
+ 4404 182 : if (oldest >= PROGRESS_MAX)
+ 4405 182 : oldest -= PROGRESS_MAX;
4406 :
- 4407 400 : tick_cpu = state->progress_tick_misc[state->progress_ptr]
- 4408 200 : + state->progress_tick_sched[state->progress_ptr]
- 4409 200 : + state->progress_tick_raid[state->progress_ptr]
- 4410 200 : + state->progress_tick_hash[state->progress_ptr];
- 4411 200 : tick_total = tick_cpu + state->progress_tick_io[state->progress_ptr];
+ 4407 364 : tick_cpu = state->progress_tick_misc[state->progress_ptr]
+ 4408 182 : + state->progress_tick_sched[state->progress_ptr]
+ 4409 182 : + state->progress_tick_raid[state->progress_ptr]
+ 4410 182 : + state->progress_tick_hash[state->progress_ptr];
+ 4411 182 : tick_total = tick_cpu + state->progress_tick_io[state->progress_ptr];
4412 :
- 4413 400 : oldest_tick_cpu = state->progress_tick_misc[oldest]
- 4414 200 : + state->progress_tick_sched[oldest]
- 4415 200 : + state->progress_tick_raid[oldest]
- 4416 200 : + state->progress_tick_hash[oldest];
- 4417 200 : oldest_tick_total = oldest_tick_cpu + state->progress_tick_io[oldest];
+ 4413 364 : oldest_tick_cpu = state->progress_tick_misc[oldest]
+ 4414 182 : + state->progress_tick_sched[oldest]
+ 4415 182 : + state->progress_tick_raid[oldest]
+ 4416 182 : + state->progress_tick_hash[oldest];
+ 4417 182 : oldest_tick_total = oldest_tick_cpu + state->progress_tick_io[oldest];
4418 :
- 4419 200 : delta_time = now - state->progress_time[oldest];
- 4420 200 : delta_pos = countpos - state->progress_pos[oldest];
- 4421 200 : delta_size = countsize - state->progress_size[oldest];
- 4422 200 : delta_tick_cpu = tick_cpu - oldest_tick_cpu;
- 4423 200 : delta_tick_total = tick_total - oldest_tick_total;
+ 4419 182 : delta_time = now - state->progress_time[oldest];
+ 4420 182 : delta_pos = countpos - state->progress_pos[oldest];
+ 4421 182 : delta_size = countsize - state->progress_size[oldest];
+ 4422 182 : delta_tick_cpu = tick_cpu - oldest_tick_cpu;
+ 4423 182 : delta_tick_total = tick_total - oldest_tick_total;
4424 :
4425 : /* estimate the speed in MB/s */
- 4426 200 : if (delta_time != 0)
- 4427 200 : out_speed = (unsigned)(delta_size / MEGA / delta_time);
+ 4426 182 : if (delta_time != 0)
+ 4427 182 : out_speed = (unsigned)(delta_size / MEGA / delta_time);
4428 :
4429 : /* estimate the cpu usage percentage */
- 4430 200 : if (delta_tick_total != 0)
- 4431 82 : out_cpu = (unsigned)(delta_tick_cpu * 100U / delta_tick_total);
+ 4430 182 : if (delta_tick_total != 0)
+ 4431 77 : out_cpu = (unsigned)(delta_tick_cpu * 100U / delta_tick_total);
4432 :
4433 : /* estimate the remaining time in minutes */
- 4434 200 : if (delta_pos != 0)
- 4435 200 : out_eta = (countmax - countpos) * delta_time / (60 * delta_pos);
+ 4434 182 : if (delta_pos != 0)
+ 4435 182 : out_eta = (countmax - countpos) * delta_time / (60 * delta_pos);
4436 :
- 4437 200 : if (state->opt.force_stats) {
+ 4437 182 : if (state->opt.force_stats) {
4438 0 : os_clear();
4439 0 : state_progress_graph(state, io, state->progress_ptr, oldest);
4440 : }
4441 :
4442 : /* we have the output value */
- 4443 200 : out_computed = 1;
+ 4443 182 : out_computed = 1;
4444 : }
4445 :
- 4446 399 : if (state->opt.gui) {
- 4447 6 : log_tag("run:pos:%u:%u:%" PRIu64 ":%u:%u:%u:%u:%" PRIu64 "\n", blockpos, countpos, countsize, out_perc, out_eta, out_speed, out_cpu, (uint64_t)elapsed);
- 4448 6 : log_flush();
+ 4446 381 : if (state->opt.gui) {
+ 4447 8 : log_tag("run:pos:%u:%u:%" PRIu64 ":%u:%u:%u:%u:%" PRIu64 "\n", blockpos, countpos, countsize, out_perc, out_eta, out_speed, out_cpu, (uint64_t)elapsed);
+ 4448 8 : log_flush();
4449 : } else {
- 4450 393 : msg_bar("%u%%, %u MB", out_perc, (unsigned)(countsize / MEGA));
- 4451 393 : if (out_computed) {
- 4452 199 : msg_bar(", %u MB/s", out_speed);
- 4453 199 : msg_bar(", CPU %u%%", out_cpu);
- 4454 199 : msg_bar(", %u:%02u ETA", out_eta / 60, out_eta % 60);
+ 4450 373 : msg_bar("%u%%, %u MB", out_perc, (unsigned)(countsize / MEGA));
+ 4451 373 : if (out_computed) {
+ 4452 179 : msg_bar(", %u MB/s", out_speed);
+ 4453 179 : msg_bar(", CPU %u%%", out_cpu);
+ 4454 179 : msg_bar(", %u:%02u ETA", out_eta / 60, out_eta % 60);
4455 : }
- 4456 393 : msg_bar("%s\r", PROGRESS_CLEAR);
- 4457 393 : msg_flush();
+ 4456 373 : msg_bar("%s\r", PROGRESS_CLEAR);
+ 4457 373 : msg_flush();
4458 : }
4459 :
4460 : /* next position to fill */
- 4461 399 : ++state->progress_ptr;
- 4462 399 : if (state->progress_ptr >= PROGRESS_MAX)
+ 4461 381 : ++state->progress_ptr;
+ 4462 381 : if (state->progress_ptr >= PROGRESS_MAX)
4463 0 : state->progress_ptr -= PROGRESS_MAX;
4464 :
4465 : /* one more measure */
- 4466 399 : ++state->progress_tick;
+ 4466 381 : ++state->progress_tick;
4467 : }
4468 :
4469 : /* stop if requested */
- 4470 1073409 : if (global_interrupt) {
+ 4470 1073497 : if (global_interrupt) {
4471 : /* LCOV_EXCL_START */
4472 : if (!state->opt.gui) {
4473 : log_fatal("\n");
@@ -4541,7 +4541,7 @@
4479 : /* LCOV_EXCL_STOP */
4480 : }
4481 :
- 4482 1073409 : return 0;
+ 4482 1073497 : return 0;
4483 : }
4484 :
4485 104 : void state_usage_waste(struct snapraid_state* state)
@@ -4551,83 +4551,83 @@
4489 104 : state->tick_last = now;
4490 104 : }
4491 :
- 4492 1063055 : void state_usage_misc(struct snapraid_state* state)
+ 4492 1063671 : void state_usage_misc(struct snapraid_state* state)
4493 : {
- 4494 1063055 : uint64_t now = tick();
- 4495 1063055 : uint64_t delta = now - state->tick_last;
+ 4494 1063671 : uint64_t now = tick();
+ 4495 1063671 : uint64_t delta = now - state->tick_last;
4496 :
4497 : /* increment the time spent in computations */
- 4498 1063055 : state->tick_misc += delta;
+ 4498 1063671 : state->tick_misc += delta;
4499 :
- 4500 1063055 : state->tick_last = now;
- 4501 1063055 : }
+ 4500 1063671 : state->tick_last = now;
+ 4501 1063671 : }
4502 :
- 4503 149836 : void state_usage_sched(struct snapraid_state* state)
+ 4503 149924 : void state_usage_sched(struct snapraid_state* state)
4504 : {
- 4505 149836 : uint64_t now = tick();
- 4506 149836 : uint64_t delta = now - state->tick_last;
+ 4505 149924 : uint64_t now = tick();
+ 4506 149924 : uint64_t delta = now - state->tick_last;
4507 :
4508 : /* increment the time spent in computations */
- 4509 149836 : state->tick_sched += delta;
+ 4509 149924 : state->tick_sched += delta;
4510 :
- 4511 149836 : state->tick_last = now;
- 4512 149836 : }
+ 4511 149924 : state->tick_last = now;
+ 4512 149924 : }
4513 :
- 4514 140365 : void state_usage_raid(struct snapraid_state* state)
+ 4514 140438 : void state_usage_raid(struct snapraid_state* state)
4515 : {
- 4516 140365 : uint64_t now = tick();
- 4517 140365 : uint64_t delta = now - state->tick_last;
+ 4516 140438 : uint64_t now = tick();
+ 4517 140438 : uint64_t delta = now - state->tick_last;
4518 :
4519 : /* increment the time spent in computations */
- 4520 140365 : state->tick_raid += delta;
+ 4520 140438 : state->tick_raid += delta;
4521 :
- 4522 140365 : state->tick_last = now;
- 4523 140365 : }
+ 4522 140438 : state->tick_last = now;
+ 4523 140438 : }
4524 :
- 4525 776808 : void state_usage_hash(struct snapraid_state* state)
+ 4525 777357 : void state_usage_hash(struct snapraid_state* state)
4526 : {
- 4527 776808 : uint64_t now = tick();
- 4528 776808 : uint64_t delta = now - state->tick_last;
+ 4527 777357 : uint64_t now = tick();
+ 4528 777357 : uint64_t delta = now - state->tick_last;
4529 :
4530 : /* increment the time spent in computations */
- 4531 776808 : state->tick_hash += delta;
+ 4531 777357 : state->tick_hash += delta;
4532 :
- 4533 776808 : state->tick_last = now;
- 4534 776808 : }
+ 4533 777357 : state->tick_last = now;
+ 4534 777357 : }
4535 :
- 4536 912357 : void state_usage_disk(struct snapraid_state* state, struct snapraid_handle* handle_map, unsigned* waiting_map, unsigned waiting_mac)
+ 4536 912885 : void state_usage_disk(struct snapraid_state* state, struct snapraid_handle* handle_map, unsigned* waiting_map, unsigned waiting_mac)
4537 : {
- 4538 912357 : uint64_t now = tick();
- 4539 912357 : uint64_t delta = now - state->tick_last;
+ 4538 912885 : uint64_t now = tick();
+ 4539 912885 : uint64_t delta = now - state->tick_last;
4540 : unsigned i;
4541 :
4542 : /* increment the time spent in the data disks */
- 4543 956230 : for (i = 0; i < waiting_mac; ++i) {
- 4544 43873 : struct snapraid_disk* disk = handle_map[waiting_map[i]].disk;
+ 4543 955948 : for (i = 0; i < waiting_mac; ++i) {
+ 4544 43063 : struct snapraid_disk* disk = handle_map[waiting_map[i]].disk;
4545 :
- 4546 43873 : if (!disk)
- 4547 6 : continue;
+ 4546 43063 : if (!disk)
+ 4547 16 : continue;
4548 :
- 4549 43867 : disk->tick += delta;
+ 4549 43047 : disk->tick += delta;
4550 : }
- 4551 912357 : state->tick_io += delta;
+ 4551 912885 : state->tick_io += delta;
4552 :
- 4553 912357 : state->tick_last = now;
- 4554 912357 : }
+ 4553 912885 : state->tick_last = now;
+ 4554 912885 : }
4555 :
- 4556 774023 : void state_usage_parity(struct snapraid_state* state, unsigned* waiting_map, unsigned waiting_mac)
+ 4556 774551 : void state_usage_parity(struct snapraid_state* state, unsigned* waiting_map, unsigned waiting_mac)
4557 : {
- 4558 774023 : uint64_t now = tick();
- 4559 774023 : uint64_t delta = now - state->tick_last;
+ 4558 774551 : uint64_t now = tick();
+ 4559 774551 : uint64_t delta = now - state->tick_last;
4560 : unsigned i;
4561 :
4562 : /* increment the time spent in the parity disk */
- 4563 851328 : for (i = 0; i < waiting_mac; ++i)
- 4564 77305 : state->parity[waiting_map[i]].tick += delta;
- 4565 774023 : state->tick_io += delta;
+ 4563 851244 : for (i = 0; i < waiting_mac; ++i)
+ 4564 76693 : state->parity[waiting_map[i]].tick += delta;
+ 4565 774551 : state->tick_io += delta;
4566 :
- 4567 774023 : state->tick_last = now;
- 4568 774023 : }
+ 4567 774551 : state->tick_last = now;
+ 4568 774551 : }
4569 :
4570 96 : void state_usage_print(struct snapraid_state* state)
4571 : {
@@ -4641,22 +4641,22 @@
4579 1 : state_progress_graph(state, 0, state->progress_ptr, PROGRESS_MAX);
4580 : }
4581 :
- 4582 496 : void state_fscheck(struct snapraid_state* state, const char* ope)
+ 4582 498 : void state_fscheck(struct snapraid_state* state, const char* ope)
4583 : {
4584 : tommy_node* i;
4585 :
4586 : /* check the file-system on all disks */
- 4587 3466 : for (i = state->disklist; i != 0; i = i->next) {
- 4588 2970 : struct snapraid_disk* disk = i->data;
+ 4587 3480 : for (i = state->disklist; i != 0; i = i->next) {
+ 4588 2982 : struct snapraid_disk* disk = i->data;
4589 :
- 4590 2970 : if (fs_check(disk) != 0) {
+ 4590 2982 : if (fs_check(disk) != 0) {
4591 : /* LCOV_EXCL_START */
4592 : log_fatal("Internal inconsistency in file-system for disk '%s' %s\n", disk->name, ope);
4593 : os_abort();
4594 : /* LCOV_EXCL_STOP */
4595 : }
4596 : }
- 4597 496 : }
+ 4597 498 : }
4598 :
4599 1 : void generate_configuration(const char* path)
4600 : {
diff --git a/cov/cmdline/status.c.gcov.html b/cov/cmdline/status.c.gcov.html
index 6945eda7..1d1e972c 100644
--- a/cov/cmdline/status.c.gcov.html
+++ b/cov/cmdline/status.c.gcov.html
@@ -395,10 +395,10 @@
333 39752 : scrub_time = info_get_time(info);
334 :
335 39752 : if (info_get_justsynced(info)) {
- 336 20453 : ++unscrubbed_blocks;
+ 336 20456 : ++unscrubbed_blocks;
337 :
338 : /* mark the time as not scrubbed */
- 339 20453 : scrub_time |= TIME_NEW;
+ 339 20456 : scrub_time |= TIME_NEW;
340 : }
341 :
342 39752 : timemap[count++] = scrub_time;
@@ -430,16 +430,16 @@
368 : /* output the info map */
369 8 : i = 0;
370 8 : log_tag("info_count:%u\n", count);
- 371 35 : while (i < count) {
- 372 19 : unsigned j = i + 1;
- 373 39771 : while (j < count && timemap[i] == timemap[j])
- 374 39733 : ++j;
- 375 19 : if ((timemap[i] & TIME_NEW) == 0) {
+ 371 33 : while (i < count) {
+ 372 17 : unsigned j = i + 1;
+ 373 39769 : while (j < count && timemap[i] == timemap[j])
+ 374 39735 : ++j;
+ 375 17 : if ((timemap[i] & TIME_NEW) == 0) {
376 7 : log_tag("info_time:%" PRIu64 ":%u:scrubbed\n", (uint64_t)timemap[i], j - i);
377 : } else {
- 378 12 : log_tag("info_time:%" PRIu64 ":%u:new\n", (uint64_t)(timemap[i] & ~TIME_NEW), j - i);
+ 378 10 : log_tag("info_time:%" PRIu64 ":%u:new\n", (uint64_t)(timemap[i] & ~TIME_NEW), j - i);
379 : }
- 380 19 : i = j;
+ 380 17 : i = j;
381 : }
382 :
383 8 : oldest = timemap[0];
@@ -462,9 +462,9 @@
400 560 : step_new = 0;
401 40872 : while (barpos < count && timemap[barpos] <= limit) {
402 39752 : if ((timemap[barpos] & TIME_NEW) != 0)
- 403 20453 : ++step_new;
+ 403 20456 : ++step_new;
404 : else
- 405 19299 : ++step_scrubbed;
+ 405 19296 : ++step_scrubbed;
406 39752 : ++barpos;
407 : }
408 :
@@ -494,20 +494,20 @@
432 8400 : unsigned scrubbed = bar_scrubbed[x];
433 :
434 8400 : if (both > pivot_upper) {
- 435 145 : if (scrubbed > pivot_lower)
+ 435 144 : if (scrubbed > pivot_lower)
436 63 : printf("*");
437 : else
- 438 82 : printf("o");
- 439 8255 : } else if (both > pivot_lower) {
- 440 19 : if (scrubbed == both)
+ 438 81 : printf("o");
+ 439 8256 : } else if (both > pivot_lower) {
+ 440 17 : if (scrubbed == both)
441 7 : printf("*");
442 : else
- 443 12 : printf("o");
+ 443 10 : printf("o");
444 : } else {
- 445 8236 : if (y == GRAPH_ROW - 1)
- 446 541 : printf("_");
+ 445 8239 : if (y == GRAPH_ROW - 1)
+ 446 543 : printf("_");
447 : else
- 448 7695 : printf(" ");
+ 448 7696 : printf(" ");
449 : }
450 : }
451 120 : printf("\n");
@@ -559,19 +559,19 @@
497 :
498 : /* print some of the errors */
499 2 : bad_print = 0;
- 500 720 : for (i = 0; i < blockmax; ++i) {
- 501 720 : snapraid_info info = info_get(&state->infoarr, i);
+ 500 723 : for (i = 0; i < blockmax; ++i) {
+ 501 723 : snapraid_info info = info_get(&state->infoarr, i);
502 :
503 : /* skip unused blocks */
- 504 720 : if (info == 0)
+ 504 723 : if (info == 0)
505 0 : continue;
506 :
- 507 720 : if (info_get_bad(info)) {
+ 507 723 : if (info_get_bad(info)) {
508 202 : printf(" %u", i);
509 202 : ++bad_print;
510 : }
511 :
- 512 720 : if (bad_print > 100) {
+ 512 723 : if (bad_print > 100) {
513 2 : printf(" and %u more...", bad - bad_print);
514 2 : break;
515 : }
diff --git a/cov/cmdline/stream.c.func-sort-c.html b/cov/cmdline/stream.c.func-sort-c.html
index 7f51850b..4f39cf2c 100644
--- a/cov/cmdline/stream.c.func-sort-c.html
+++ b/cov/cmdline/stream.c.func-sort-c.html
@@ -61,23 +61,23 @@
| swrite |
- 20725275 |
+ 20724964 |
| sgetb32 |
- 18668535 |
+ 18667054 |
| sread |
- 12810720 |
+ 12810372 |
| sgetb64 |
- 10849874 |
+ 10849502 |
| sputb32 |
- 9127648 |
+ 9127337 |
| sputb64 |
@@ -85,7 +85,7 @@
| sgetbs |
- 3877236 |
+ 3877163 |
| sputbs |
@@ -93,11 +93,11 @@
| sfill |
- 607111 |
+ 607122 |
| sgetc_uncached |
- 298847 |
+ 298855 |
| sflush |
@@ -105,31 +105,31 @@
| sgettok |
- 8138 |
+ 8162 |
| sgetline |
- 5410 |
+ 5425 |
| sgetlasttok |
- 5370 |
+ 5384 |
| sclose |
- 1949 |
+ 1951 |
| sopen_read |
- 1834 |
+ 1836 |
| scrc |
- 1687 |
+ 1688 |
| sdeplete |
- 1142 |
+ 1144 |
| sopen_multi_file |
@@ -137,15 +137,15 @@
| sgetble32 |
- 379 |
+ 380 |
| sgetu32 |
- 264 |
+ 265 |
| shandle |
- 252 |
+ 253 |
| scrc_stream |
diff --git a/cov/cmdline/stream.c.func.html b/cov/cmdline/stream.c.func.html
index 8191ded9..4739e4bf 100644
--- a/cov/cmdline/stream.c.func.html
+++ b/cov/cmdline/stream.c.func.html
@@ -61,11 +61,11 @@
| sclose |
- 1949 |
+ 1951 |
| scrc |
- 1687 |
+ 1688 |
| scrc_stream |
@@ -73,11 +73,11 @@
| sdeplete |
- 1142 |
+ 1144 |
| sfill |
- 607111 |
+ 607122 |
| sflush |
@@ -85,43 +85,43 @@
| sgetb32 |
- 18668535 |
+ 18667054 |
| sgetb64 |
- 10849874 |
+ 10849502 |
| sgetble32 |
- 379 |
+ 380 |
| sgetbs |
- 3877236 |
+ 3877163 |
| sgetc_uncached |
- 298847 |
+ 298855 |
| sgetlasttok |
- 5370 |
+ 5384 |
| sgetline |
- 5410 |
+ 5425 |
| sgettok |
- 8138 |
+ 8162 |
| sgetu32 |
- 264 |
+ 265 |
| shandle |
- 252 |
+ 253 |
| sopen_multi_file |
@@ -133,7 +133,7 @@
| sopen_read |
- 1834 |
+ 1836 |
| sopen_write |
@@ -141,7 +141,7 @@
| sputb32 |
- 9127648 |
+ 9127337 |
| sputb64 |
@@ -157,7 +157,7 @@
| sread |
- 12810720 |
+ 12810372 |
| ssync |
@@ -169,7 +169,7 @@
| swrite |
- 20725275 |
+ 20724964 |
diff --git a/cov/cmdline/stream.c.gcov.html b/cov/cmdline/stream.c.gcov.html
index ddbc7331..bec8536c 100644
--- a/cov/cmdline/stream.c.gcov.html
+++ b/cov/cmdline/stream.c.gcov.html
@@ -88,19 +88,19 @@
26 :
27 : unsigned STREAM_SIZE = 64 * 1024;
28 :
- 29 1834 : STREAM* sopen_read(const char* file)
+ 29 1836 : STREAM* sopen_read(const char* file)
30 : {
31 : #if HAVE_POSIX_FADVISE
32 : int ret;
33 : #endif
- 34 1834 : STREAM* s = malloc_nofail(sizeof(STREAM));
+ 34 1836 : STREAM* s = malloc_nofail(sizeof(STREAM));
35 :
- 36 1834 : s->handle_size = 1;
- 37 1834 : s->handle = malloc_nofail(sizeof(struct stream_handle));
+ 36 1836 : s->handle_size = 1;
+ 37 1836 : s->handle = malloc_nofail(sizeof(struct stream_handle));
38 :
- 39 1834 : pathcpy(s->handle[0].path, sizeof(s->handle[0].path), file);
- 40 1834 : s->handle[0].f = open(file, O_RDONLY | O_BINARY | O_SEQUENTIAL);
- 41 1834 : if (s->handle[0].f == -1) {
+ 39 1836 : pathcpy(s->handle[0].path, sizeof(s->handle[0].path), file);
+ 40 1836 : s->handle[0].f = open(file, O_RDONLY | O_BINARY | O_SEQUENTIAL);
+ 41 1836 : if (s->handle[0].f == -1) {
42 50 : free(s->handle);
43 50 : free(s);
44 50 : return 0;
@@ -108,13 +108,13 @@
46 :
47 : #if HAVE_POSIX_FADVISE
48 : /* advise sequential access */
- 49 1784 : ret = posix_fadvise(s->handle[0].f, 0, 0, POSIX_FADV_SEQUENTIAL);
- 50 1784 : if (ret == ENOSYS) {
+ 49 1786 : ret = posix_fadvise(s->handle[0].f, 0, 0, POSIX_FADV_SEQUENTIAL);
+ 50 1786 : if (ret == ENOSYS) {
51 0 : log_fatal("WARNING! fadvise() is not supported in this platform. Performance may not be optimal!\n");
52 : /* call is not supported, like in armhf, see posix_fadvise manpage */
53 0 : ret = 0;
54 : }
- 55 1784 : if (ret != 0) {
+ 55 1786 : if (ret != 0) {
56 : /* LCOV_EXCL_START */
57 : close(s->handle[0].f);
58 : free(s->handle);
@@ -125,18 +125,18 @@
63 : }
64 : #endif
65 :
- 66 1784 : s->buffer = malloc_nofail_test(STREAM_SIZE);
- 67 1784 : s->pos = s->buffer;
- 68 1784 : s->end = s->buffer;
- 69 1784 : s->state = STREAM_STATE_READ;
- 70 1784 : s->state_index = 0;
- 71 1784 : s->offset = 0;
- 72 1784 : s->offset_uncached = 0;
- 73 1784 : s->crc = 0;
- 74 1784 : s->crc_uncached = 0;
- 75 1784 : s->crc_stream = CRC_IV;
+ 66 1786 : s->buffer = malloc_nofail_test(STREAM_SIZE);
+ 67 1786 : s->pos = s->buffer;
+ 68 1786 : s->end = s->buffer;
+ 69 1786 : s->state = STREAM_STATE_READ;
+ 70 1786 : s->state_index = 0;
+ 71 1786 : s->offset = 0;
+ 72 1786 : s->offset_uncached = 0;
+ 73 1786 : s->crc = 0;
+ 74 1786 : s->crc_uncached = 0;
+ 75 1786 : s->crc_stream = CRC_IV;
76 :
- 77 1784 : return s;
+ 77 1786 : return s;
78 : }
79 :
80 167 : STREAM* sopen_multi_write(unsigned count)
@@ -214,12 +214,12 @@
152 0 : return s;
153 : }
154 :
- 155 1949 : int sclose(STREAM* s)
+ 155 1951 : int sclose(STREAM* s)
156 : {
- 157 1949 : int fail = 0;
+ 157 1951 : int fail = 0;
158 : unsigned i;
159 :
- 160 1949 : if (s->state == STREAM_STATE_WRITE) {
+ 160 1951 : if (s->state == STREAM_STATE_WRITE) {
161 167 : if (sflush(s) != 0) {
162 : /* LCOV_EXCL_START */
163 : fail = 1;
@@ -227,102 +227,102 @@
165 : }
166 : }
167 :
- 168 4871 : for (i = 0; i < s->handle_size; ++i) {
- 169 2922 : if (close(s->handle[i].f) != 0) {
+ 168 4875 : for (i = 0; i < s->handle_size; ++i) {
+ 169 2924 : if (close(s->handle[i].f) != 0) {
170 : /* LCOV_EXCL_START */
171 : fail = 1;
172 : /* LCOV_EXCL_STOP */
173 : }
174 : }
175 :
- 176 1949 : free(s->handle);
- 177 1949 : free(s->buffer);
- 178 1949 : free(s);
+ 176 1951 : free(s->handle);
+ 177 1951 : free(s->buffer);
+ 178 1951 : free(s);
179 :
- 180 1949 : if (fail) {
+ 180 1951 : if (fail) {
181 : /* LCOV_EXCL_START */
182 : return -1;
183 : /* LCOV_EXCL_STOP */
184 : }
185 :
- 186 1949 : return 0;
+ 186 1951 : return 0;
187 : }
188 :
- 189 252 : int shandle(STREAM* s)
+ 189 253 : int shandle(STREAM* s)
190 : {
- 191 252 : if (!s->handle_size) {
+ 191 253 : if (!s->handle_size) {
192 : /* LCOV_EXCL_START */
193 : return -1;
194 : /* LCOV_EXCL_STOP */
195 : }
196 :
- 197 252 : return s->handle[0].f;
+ 197 253 : return s->handle[0].f;
198 : }
199 :
200 : /**
201 : * Fill the read stream buffer.
202 : * \return 0 if at least on char is read, or EOF on error.
203 : */
- 204 607111 : static int sfill(STREAM* s)
+ 204 607122 : static int sfill(STREAM* s)
205 : {
206 : ssize_t ret;
207 :
- 208 607111 : if (s->state != STREAM_STATE_READ) {
+ 208 607122 : if (s->state != STREAM_STATE_READ) {
209 : /* LCOV_EXCL_START */
210 : return EOF;
211 : /* LCOV_EXCL_STOP */
212 : }
213 :
- 214 606059 : ret = read(s->handle[0].f, s->buffer, STREAM_SIZE);
+ 214 606066 : ret = read(s->handle[0].f, s->buffer, STREAM_SIZE);
215 :
- 216 606062 : if (ret < 0) {
+ 216 606066 : if (ret < 0) {
217 : /* LCOV_EXCL_START */
218 : s->state = STREAM_STATE_ERROR;
219 : return EOF;
220 : /* LCOV_EXCL_STOP */
221 : }
- 222 606062 : if (ret == 0) {
- 223 1655 : s->state = STREAM_STATE_EOF;
- 224 1655 : return EOF;
+ 222 606066 : if (ret == 0) {
+ 223 1657 : s->state = STREAM_STATE_EOF;
+ 224 1657 : return EOF;
225 : }
226 :
227 : /* update the crc */
- 228 604407 : s->crc_uncached = s->crc;
- 229 604407 : s->crc = crc32c(s->crc, s->buffer, ret);
+ 228 604409 : s->crc_uncached = s->crc;
+ 229 604409 : s->crc = crc32c(s->crc, s->buffer, ret);
230 :
231 : /* update the offset */
- 232 604404 : s->offset_uncached = s->offset;
- 233 604404 : s->offset += ret;
+ 232 604407 : s->offset_uncached = s->offset;
+ 233 604407 : s->offset += ret;
234 :
- 235 604404 : s->pos = s->buffer;
- 236 604404 : s->end = s->buffer + ret;
+ 235 604407 : s->pos = s->buffer;
+ 236 604407 : s->end = s->buffer + ret;
237 :
- 238 604404 : return 0;
+ 238 604407 : return 0;
239 : }
240 :
- 241 1142 : int sdeplete(STREAM* s, unsigned char* last)
+ 241 1144 : int sdeplete(STREAM* s, unsigned char* last)
242 : {
243 : /* last four bytes */
- 244 1142 : last[0] = 0;
- 245 1142 : last[1] = 0;
- 246 1142 : last[2] = 0;
- 247 1142 : last[3] = 0;
+ 244 1144 : last[0] = 0;
+ 245 1144 : last[1] = 0;
+ 246 1144 : last[2] = 0;
+ 247 1144 : last[3] = 0;
248 :
249 : while (1) {
250 : /* increase the position up to 4 bytes before the end */
- 251 308265 : if (s->pos + 4 <= s->end)
+ 251 308267 : if (s->pos + 4 <= s->end)
252 148388 : s->pos = s->end - 4;
253 :
254 : /* insert the last 4 bytes */
- 255 1469850 : while (s->pos < s->end) {
- 256 853320 : last[0] = last[1];
- 257 853320 : last[1] = last[2];
- 258 853320 : last[2] = last[3];
- 259 853320 : last[3] = *s->pos++;
+ 255 1469851 : while (s->pos < s->end) {
+ 256 853317 : last[0] = last[1];
+ 257 853317 : last[1] = last[2];
+ 258 853317 : last[2] = last[3];
+ 259 853317 : last[3] = *s->pos++;
260 : }
261 :
262 : /* fill again the buffer until the end of the file */
- 263 308265 : if (sfill(s) != 0) {
+ 263 308267 : if (sfill(s) != 0) {
264 : /* on error fail */
265 1141 : if (serror(s)) {
266 : /* LCOV_EXCL_START */
@@ -331,11 +331,11 @@
269 : }
270 :
271 : /* on EOF terminate */
- 272 1141 : break;
+ 272 1140 : break;
273 : }
274 307123 : }
275 :
- 276 1141 : return 0;
+ 276 1140 : return 0;
277 : }
278 :
279 39049 : int sflush(STREAM* s)
@@ -390,9 +390,9 @@
328 1 : return s->offset_uncached + (s->pos - s->buffer);
329 : }
330 :
- 331 1687 : uint32_t scrc(STREAM*s)
+ 331 1688 : uint32_t scrc(STREAM*s)
332 : {
- 333 1687 : return crc32c(s->crc_uncached, s->buffer, s->pos - s->buffer);
+ 333 1688 : return crc32c(s->crc_uncached, s->buffer, s->pos - s->buffer);
334 : }
335 :
336 167 : uint32_t scrc_stream(STREAM*s)
@@ -400,90 +400,90 @@
338 167 : return s->crc_stream ^ CRC_IV;
339 : }
340 :
- 341 298847 : int sgetc_uncached(STREAM* s)
+ 341 298855 : int sgetc_uncached(STREAM* s)
342 : {
343 : /* if at the end of the buffer, fill it */
- 344 298847 : if (s->pos == s->end && sfill(s) != 0)
- 345 1566 : return EOF;
- 346 297281 : return *s->pos++;
+ 344 298855 : if (s->pos == s->end && sfill(s) != 0)
+ 345 1572 : return EOF;
+ 346 297283 : return *s->pos++;
347 : }
348 :
- 349 8138 : int sgettok(STREAM* f, char* str, int size)
+ 349 8162 : int sgettok(STREAM* f, char* str, int size)
350 : {
- 351 8138 : char* i = str;
- 352 8138 : char* send = str + size;
+ 351 8162 : char* i = str;
+ 352 8162 : char* send = str + size;
353 : int c;
354 :
355 : while (1) {
- 356 54240 : c = sgetc(f);
- 357 54240 : if (c == EOF) {
- 358 263 : break;
+ 356 54379 : c = sgetc(f);
+ 357 54379 : if (c == EOF) {
+ 358 264 : break;
359 : }
- 360 53977 : if (c == ' ' || c == '\t') {
- 361 7611 : sungetc(c, f);
- 362 7611 : break;
+ 360 54115 : if (c == ' ' || c == '\t') {
+ 361 7633 : sungetc(c, f);
+ 362 7633 : break;
363 : }
- 364 46366 : if (c == '\n') {
+ 364 46482 : if (c == '\n') {
365 : /* remove ending carrige return to support the Windows CR+LF format */
- 366 264 : if (i != str && i[-1] == '\r')
+ 366 265 : if (i != str && i[-1] == '\r')
367 0 : --i;
- 368 264 : sungetc(c, f);
- 369 264 : break;
+ 368 265 : sungetc(c, f);
+ 369 265 : break;
370 : }
371 :
- 372 46102 : *i++ = c;
+ 372 46217 : *i++ = c;
373 :
- 374 46102 : if (i == send) {
+ 374 46217 : if (i == send) {
375 : /* LCOV_EXCL_START */
376 : return -1;
377 : /* LCOV_EXCL_STOP */
378 : }
- 379 46102 : }
+ 379 46217 : }
380 :
- 381 8138 : *i = 0;
+ 381 8162 : *i = 0;
382 :
- 383 8138 : return i - str;
+ 383 8162 : return i - str;
384 : }
385 :
- 386 12810720 : int sread(STREAM* f, void* void_data, unsigned size)
+ 386 12810372 : int sread(STREAM* f, void* void_data, unsigned size)
387 : {
- 388 12810720 : unsigned char* data = void_data;
+ 388 12810372 : unsigned char* data = void_data;
389 :
390 : /* if there is enough space in memory */
- 391 12810720 : if (sptrlookup(f, size)) {
+ 391 12810372 : if (sptrlookup(f, size)) {
392 : /* optimized version with all the data in memory */
- 393 12784282 : unsigned char* pos = sptrget(f);
+ 393 12784238 : unsigned char* pos = sptrget(f);
394 :
395 : /* copy it */
- 396 217726263 : while (size--)
- 397 192157699 : *data++ = *pos++;
+ 396 217725604 : while (size--)
+ 397 192157128 : *data++ = *pos++;
398 :
- 399 12784282 : sptrset(f, pos);
+ 399 12784238 : sptrset(f, pos);
400 : } else {
401 : /* standard version using sgetc() */
- 402 1380323 : while (size--) {
- 403 1327447 : int c = sgetc(f);
- 404 1327447 : if (c == EOF) {
+ 402 1375577 : while (size--) {
+ 403 1323309 : int c = sgetc(f);
+ 404 1323309 : if (c == EOF) {
405 : /* LCOV_EXCL_START */
406 : return -1;
407 : /* LCOV_EXCL_STOP */
408 : }
409 :
- 410 1327447 : *data++ = c;
+ 410 1323309 : *data++ = c;
411 : }
412 : }
413 :
- 414 12810720 : return 0;
+ 414 12810372 : return 0;
415 : }
416 :
- 417 5410 : int sgetline(STREAM* f, char* str, int size)
+ 417 5425 : int sgetline(STREAM* f, char* str, int size)
418 : {
- 419 5410 : char* i = str;
- 420 5410 : char* send = str + size;
+ 419 5425 : char* i = str;
+ 420 5425 : char* send = str + size;
421 : int c;
422 :
423 : /* if there is enough data in memory */
- 424 5410 : if (sptrlookup(f, size)) {
+ 424 5425 : if (sptrlookup(f, size)) {
425 : /* optimized version with all the data in memory */
426 0 : unsigned char* pos = sptrget(f);
427 :
@@ -509,75 +509,75 @@
447 0 : sptrset(f, pos);
448 : } else {
449 : while (1) {
- 450 139082 : c = sgetc(f);
- 451 139082 : if (c == EOF) {
+ 450 139326 : c = sgetc(f);
+ 451 139326 : if (c == EOF) {
452 : /* LCOV_EXCL_START */
453 : break;
454 : /* LCOV_EXCL_STOP */
455 : }
- 456 139082 : if (c == '\n') {
+ 456 139326 : if (c == '\n') {
457 : /* remove ending carrige return to support the Windows CR+LF format */
- 458 5410 : if (i != str && i[-1] == '\r')
+ 458 5425 : if (i != str && i[-1] == '\r')
459 0 : --i;
- 460 5410 : sungetc(c, f);
- 461 5410 : break;
+ 460 5425 : sungetc(c, f);
+ 461 5425 : break;
462 : }
463 :
- 464 133672 : *i++ = c;
+ 464 133901 : *i++ = c;
465 :
- 466 133672 : if (i == send) {
+ 466 133901 : if (i == send) {
467 : /* LCOV_EXCL_START */
468 : return -1;
469 : /* LCOV_EXCL_STOP */
470 : }
- 471 133672 : }
+ 471 133901 : }
472 : }
473 :
- 474 5410 : *i = 0;
+ 474 5425 : *i = 0;
475 :
- 476 5410 : return i - str;
+ 476 5425 : return i - str;
477 : }
478 :
- 479 5370 : int sgetlasttok(STREAM* f, char* str, int size)
+ 479 5384 : int sgetlasttok(STREAM* f, char* str, int size)
480 : {
481 : int ret;
482 :
- 483 5370 : ret = sgetline(f, str, size);
- 484 5370 : if (ret < 0) {
+ 483 5384 : ret = sgetline(f, str, size);
+ 484 5384 : if (ret < 0) {
485 : /* LCOV_EXCL_START */
486 : return ret;
487 : /* LCOV_EXCL_STOP */
488 : }
489 :
- 490 10740 : while (ret > 0 && (str[ret - 1] == ' ' || str[ret - 1] == '\t'))
+ 490 10768 : while (ret > 0 && (str[ret - 1] == ' ' || str[ret - 1] == '\t'))
491 0 : --ret;
492 :
- 493 5370 : str[ret] = 0;
+ 493 5384 : str[ret] = 0;
494 :
- 495 5370 : return ret;
+ 495 5384 : return ret;
496 : }
497 :
- 498 264 : int sgetu32(STREAM* f, uint32_t* value)
+ 498 265 : int sgetu32(STREAM* f, uint32_t* value)
499 : {
500 : int c;
501 :
- 502 264 : c = sgetc(f);
- 503 264 : if (c >= '0' && c <= '9') {
+ 502 265 : c = sgetc(f);
+ 503 265 : if (c >= '0' && c <= '9') {
504 : uint32_t v;
505 :
- 506 264 : v = c - '0';
+ 506 265 : v = c - '0';
507 :
- 508 264 : c = sgetc(f);
- 509 528 : while (c >= '0' && c <= '9') {
+ 508 265 : c = sgetc(f);
+ 509 530 : while (c >= '0' && c <= '9') {
510 0 : v *= 10;
511 0 : v += c - '0';
512 0 : c = sgetc(f);
513 : }
514 :
- 515 264 : *value = v;
+ 515 265 : *value = v;
516 :
- 517 264 : sungetc(c, f);
- 518 264 : return 0;
+ 517 265 : sungetc(c, f);
+ 518 265 : return 0;
519 : } else {
520 : /* LCOV_EXCL_START */
521 : /* nothing read */
@@ -586,122 +586,122 @@
524 : }
525 : }
526 :
- 527 18668535 : int sgetb32(STREAM* f, uint32_t* value)
+ 527 18667054 : int sgetb32(STREAM* f, uint32_t* value)
528 : {
529 : uint32_t v;
530 : unsigned char b;
531 : unsigned char s;
532 : int c;
533 :
- 534 18668535 : v = 0;
- 535 18668535 : s = 0;
+ 534 18667054 : v = 0;
+ 535 18667054 : s = 0;
536 : loop:
- 537 36576764 : c = sgetc(f);
- 538 36576764 : if (c == EOF) {
+ 537 35516819 : c = sgetc(f);
+ 538 35516819 : if (c == EOF) {
539 : /* LCOV_EXCL_START */
540 : return -1;
541 : /* LCOV_EXCL_STOP */
542 : }
543 :
- 544 36576764 : b = (unsigned char)c;
- 545 36576764 : if ((b & 0x80) == 0) {
- 546 17908229 : v |= (uint32_t)b << s;
- 547 17908229 : s += 7;
- 548 17908229 : if (s >= 32) {
+ 544 35516819 : b = (unsigned char)c;
+ 545 35516819 : if ((b & 0x80) == 0) {
+ 546 16849766 : v |= (uint32_t)b << s;
+ 547 16849766 : s += 7;
+ 548 16849766 : if (s >= 32) {
549 : /* LCOV_EXCL_START */
550 : return -1;
551 : /* LCOV_EXCL_STOP */
552 : }
- 553 17908229 : goto loop;
+ 553 16849765 : goto loop;
554 : }
555 :
- 556 18668535 : v |= (uint32_t)(b & 0x7f) << s;
+ 556 18667053 : v |= (uint32_t)(b & 0x7f) << s;
557 :
- 558 18668535 : *value = v;
+ 558 18667053 : *value = v;
559 :
- 560 18668535 : return 0;
+ 560 18667053 : return 0;
561 : }
562 :
- 563 10849874 : int sgetb64(STREAM* f, uint64_t* value)
+ 563 10849502 : int sgetb64(STREAM* f, uint64_t* value)
564 : {
565 : uint64_t v;
566 : unsigned char b;
567 : unsigned char s;
568 : int c;
569 :
- 570 10849874 : v = 0;
- 571 10849874 : s = 0;
+ 570 10849502 : v = 0;
+ 571 10849502 : s = 0;
572 : loop:
- 573 39668034 : c = sgetc(f);
- 574 39668034 : if (c == EOF) {
+ 573 39666625 : c = sgetc(f);
+ 574 39666625 : if (c == EOF) {
575 : /* LCOV_EXCL_START */
576 : return -1;
577 : /* LCOV_EXCL_STOP */
578 : }
579 :
- 580 39668034 : b = (unsigned char)c;
- 581 39668034 : if ((b & 0x80) == 0) {
- 582 28818160 : v |= (uint64_t)b << s;
- 583 28818160 : s += 7;
- 584 28818160 : if (s >= 64) {
+ 580 39666625 : b = (unsigned char)c;
+ 581 39666625 : if ((b & 0x80) == 0) {
+ 582 28817123 : v |= (uint64_t)b << s;
+ 583 28817123 : s += 7;
+ 584 28817123 : if (s >= 64) {
585 : /* LCOV_EXCL_START */
586 : return -1;
587 : /* LCOV_EXCL_STOP */
588 : }
- 589 28818160 : goto loop;
+ 589 28817123 : goto loop;
590 : }
591 :
- 592 10849874 : v |= (uint64_t)(b & 0x7f) << s;
+ 592 10849502 : v |= (uint64_t)(b & 0x7f) << s;
593 :
- 594 10849874 : *value = v;
+ 594 10849502 : *value = v;
595 :
- 596 10849874 : return 0;
+ 596 10849502 : return 0;
597 : }
598 :
- 599 379 : int sgetble32(STREAM* f, uint32_t* value)
+ 599 380 : int sgetble32(STREAM* f, uint32_t* value)
600 : {
601 : unsigned char buf[4];
602 :
- 603 379 : if (sread(f, buf, 4) != 0) {
+ 603 380 : if (sread(f, buf, 4) != 0) {
604 : /* LCOV_EXCL_START */
605 : return -1;
606 : /* LCOV_EXCL_STOP */
607 : }
608 :
- 609 379 : *value = buf[0] | (uint32_t)buf[1] << 8 | (uint32_t)buf[2] << 16 | (uint32_t)buf[3] << 24;
+ 609 380 : *value = buf[0] | (uint32_t)buf[1] << 8 | (uint32_t)buf[2] << 16 | (uint32_t)buf[3] << 24;
610 :
- 611 379 : return 0;
+ 611 380 : return 0;
612 : }
613 :
- 614 3877236 : int sgetbs(STREAM* f, char* str, int size)
+ 614 3877163 : int sgetbs(STREAM* f, char* str, int size)
615 : {
616 : uint32_t len;
617 :
- 618 3877236 : if (sgetb32(f, &len) < 0) {
+ 618 3877163 : if (sgetb32(f, &len) < 0) {
619 : /* LCOV_EXCL_START */
620 : return -1;
621 : /* LCOV_EXCL_STOP */
622 : }
623 :
- 624 3877236 : if (len + 1 > (uint32_t)size) {
+ 624 3877162 : if (len + 1 > (uint32_t)size) {
625 : /* LCOV_EXCL_START */
626 : return -1;
627 : /* LCOV_EXCL_STOP */
628 : }
629 :
- 630 3877236 : str[len] = 0;
+ 630 3877162 : str[len] = 0;
631 :
- 632 3877236 : return sread(f, str, (int)len);
+ 632 3877162 : return sread(f, str, (int)len);
633 : }
634 :
- 635 20725275 : int swrite(const void* void_data, unsigned size, STREAM* f)
+ 635 20724964 : int swrite(const void* void_data, unsigned size, STREAM* f)
636 : {
- 637 20725275 : const unsigned char* data = void_data;
+ 637 20724964 : const unsigned char* data = void_data;
638 :
639 : /* if there is enough space in memory */
- 640 20725275 : if (sptrlookup(f, size)) {
+ 640 20724964 : if (sptrlookup(f, size)) {
641 : /* optimized version with all the data in memory */
- 642 20719102 : unsigned char* pos = sptrget(f);
+ 642 20718802 : unsigned char* pos = sptrget(f);
643 :
644 : /**
645 : * Update the crc *before* writing the data in the buffer
@@ -710,17 +710,17 @@
648 : * to be able to detect memory errors on the buffer,
649 : * happening before we write it on the file.
650 : */
- 651 20719102 : f->crc_stream = crc32c_plain(f->crc_stream, data, size);
+ 651 20718802 : f->crc_stream = crc32c_plain(f->crc_stream, data, size);
652 :
653 : /* copy it */
- 654 173066513 : while (size--)
- 655 131628309 : *pos++ = *data++;
+ 654 172634823 : while (size--)
+ 655 131197219 : *pos++ = *data++;
656 :
- 657 20719102 : sptrset(f, pos);
+ 657 20718802 : sptrset(f, pos);
658 : } else {
659 : /* standard version using sputc() */
- 660 202070 : while (size--) {
- 661 189724 : if (sputc(*data++, f) != 0) {
+ 660 201254 : while (size--) {
+ 661 188930 : if (sputc(*data++, f) != 0) {
662 : /* LCOV_EXCL_START */
663 : return -1;
664 : /* LCOV_EXCL_STOP */
@@ -728,28 +728,28 @@
666 : }
667 : }
668 :
- 669 20725275 : return 0;
+ 669 20724964 : return 0;
670 : }
671 :
- 672 9127648 : int sputb32(uint32_t value, STREAM* s)
+ 672 9127337 : int sputb32(uint32_t value, STREAM* s)
673 : {
674 : unsigned char b;
675 : unsigned char buf[16];
676 : unsigned i;
677 :
- 678 9127648 : i = 0;
+ 678 9127337 : i = 0;
679 : loop:
- 680 17909297 : b = value & 0x7f;
- 681 17909297 : value >>= 7;
+ 680 17477413 : b = value & 0x7f;
+ 681 17477413 : value >>= 7;
682 :
- 683 17909297 : if (value) {
- 684 8781649 : buf[i++] = b;
- 685 8781649 : goto loop;
+ 683 17477413 : if (value) {
+ 684 8350076 : buf[i++] = b;
+ 685 8350076 : goto loop;
686 : }
687 :
- 688 9127648 : buf[i++] = b | 0x80;
+ 688 9127337 : buf[i++] = b | 0x80;
689 :
- 690 9127648 : return swrite(buf, i, s);
+ 690 9127337 : return swrite(buf, i, s);
691 : }
692 :
693 5317120 : int sputb64(uint64_t value, STREAM* s)
diff --git a/cov/cmdline/stream.h.func-sort-c.html b/cov/cmdline/stream.h.func-sort-c.html
index 75f8a41a..48c4ad62 100644
--- a/cov/cmdline/stream.h.func-sort-c.html
+++ b/cov/cmdline/stream.h.func-sort-c.html
@@ -61,39 +61,39 @@
| sgetc |
- 85203689 |
+ 84138438 |
| sptrlookup |
- 33541405 |
+ 33540761 |
| sptrset |
- 33503384 |
+ 33503040 |
| sptrget |
- 33503384 |
+ 33503040 |
| sputc |
- 3808841 |
+ 3808025 |
| serror |
- 3635503 |
+ 3635393 |
| sungetc |
- 34340 |
+ 34440 |
| sgetspace |
- 20539 |
+ 20599 |
| sgeteol |
- 6200 |
+ 6218 |
| seof |
diff --git a/cov/cmdline/stream.h.func.html b/cov/cmdline/stream.h.func.html
index 713353fa..fe9477a4 100644
--- a/cov/cmdline/stream.h.func.html
+++ b/cov/cmdline/stream.h.func.html
@@ -65,7 +65,7 @@
| serror |
- 3635503 |
+ 3635393 |
| serrorfile |
@@ -73,35 +73,35 @@
| sgetc |
- 85203689 |
+ 84138438 |
| sgeteol |
- 6200 |
+ 6218 |
| sgetspace |
- 20539 |
+ 20599 |
| sptrget |
- 33503384 |
+ 33503040 |
| sptrlookup |
- 33541405 |
+ 33540761 |
| sptrset |
- 33503384 |
+ 33503040 |
| sputc |
- 3808841 |
+ 3808025 |
| sungetc |
- 34340 |
+ 34440 |
diff --git a/cov/cmdline/stream.h.gcov.html b/cov/cmdline/stream.h.gcov.html
index 28434aaf..ecdcc42c 100644
--- a/cov/cmdline/stream.h.gcov.html
+++ b/cov/cmdline/stream.h.gcov.html
@@ -221,33 +221,33 @@
159 : /**
160 : * Check if the buffer has enough data loaded.
161 : */
- 162 33541405 : static inline int sptrlookup(STREAM* s, int size)
+ 162 33540761 : static inline int sptrlookup(STREAM* s, int size)
163 : {
- 164 33541405 : return s->pos + size <= s->end;
+ 164 33540761 : return s->pos + size <= s->end;
165 : }
166 :
167 : /**
168 : * Get the current stream ptr.
169 : */
- 170 33503384 : static inline unsigned char* sptrget(STREAM* s)
+ 170 33503040 : static inline unsigned char* sptrget(STREAM* s)
171 : {
- 172 33503384 : return s->pos;
+ 172 33503040 : return s->pos;
173 : }
174 :
175 : /**
176 : * Set the current stream ptr.
177 : */
- 178 33503384 : static inline void sptrset(STREAM* s, unsigned char* ptr)
+ 178 33503040 : static inline void sptrset(STREAM* s, unsigned char* ptr)
179 : {
- 180 33503384 : s->pos = ptr;
- 181 33503384 : }
+ 180 33503040 : s->pos = ptr;
+ 181 33503040 : }
182 :
183 : /**
184 : * Check the error status. Like ferror().
185 : */
- 186 3635503 : static inline int serror(STREAM* s)
+ 186 3635393 : static inline int serror(STREAM* s)
187 : {
- 188 3635503 : return s->state == STREAM_STATE_ERROR;
+ 188 3635393 : return s->state == STREAM_STATE_ERROR;
189 : }
190 :
191 : /**
@@ -291,22 +291,22 @@
229 : /**
230 : * Read a char. Like fgetc().
231 : */
- 232 85203689 : static inline int sgetc(STREAM* s)
+ 232 84138438 : static inline int sgetc(STREAM* s)
233 : {
- 234 85203689 : if (tommy_unlikely(s->pos == s->end))
- 235 298847 : return sgetc_uncached(s);
- 236 84904842 : return *s->pos++;
+ 234 84138438 : if (tommy_unlikely(s->pos == s->end))
+ 235 298855 : return sgetc_uncached(s);
+ 236 83839583 : return *s->pos++;
237 : }
238 :
239 : /**
240 : * Unread a char.
241 : * Like ungetc() but you have to unget the same char read.
242 : */
- 243 34340 : static inline void sungetc(int c, STREAM* s)
+ 243 34440 : static inline void sungetc(int c, STREAM* s)
244 : {
- 245 34340 : if (c != EOF)
- 246 33551 : --s->pos;
- 247 34340 : }
+ 245 34440 : if (c != EOF)
+ 246 33648 : --s->pos;
+ 247 34440 : }
248 :
249 : /**
250 : * Read a fixed amount of chars.
@@ -317,34 +317,34 @@
255 : /**
256 : * Get a char from a stream, ignoring one '\r'.
257 : */
- 258 6200 : static inline int sgeteol(STREAM* f)
+ 258 6218 : static inline int sgeteol(STREAM* f)
259 : {
260 : int c;
261 :
- 262 6200 : c = sgetc(f);
- 263 6200 : if (c == '\r')
+ 262 6218 : c = sgetc(f);
+ 263 6218 : if (c == '\r')
264 0 : c = sgetc(f);
265 :
- 266 6200 : return c;
+ 266 6218 : return c;
267 : }
268 :
269 : /**
270 : * Read all the spaces and tabs.
271 : * Return the number of spaces and tabs read.
272 : */
- 273 20539 : static inline int sgetspace(STREAM* f)
+ 273 20599 : static inline int sgetspace(STREAM* f)
274 : {
- 275 20539 : int count = 0;
+ 275 20599 : int count = 0;
276 : int c;
277 :
- 278 20539 : c = sgetc(f);
- 279 48689 : while (c == ' ' || c == '\t') {
- 280 7611 : ++count;
- 281 7611 : c = sgetc(f);
+ 278 20599 : c = sgetc(f);
+ 279 48831 : while (c == ' ' || c == '\t') {
+ 280 7633 : ++count;
+ 281 7633 : c = sgetc(f);
282 : }
283 :
- 284 20539 : sungetc(c, f);
- 285 20539 : return count;
+ 284 20599 : sungetc(c, f);
+ 285 20599 : return count;
286 : }
287 :
288 : /**
@@ -407,9 +407,9 @@
345 : * Write a char. Like fputc().
346 : * Return 0 on success or -1 on error.
347 : */
- 348 3808841 : static inline int sputc(int c, STREAM* s)
+ 348 3808025 : static inline int sputc(int c, STREAM* s)
349 : {
- 350 3808841 : if (s->pos == s->end) {
+ 350 3808025 : if (s->pos == s->end) {
351 38580 : if (sflush(s) != 0)
352 0 : return -1;
353 : }
@@ -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 3808841 : s->crc_stream = crc32c_plain_char(s->crc_stream, c);
+ 362 3808025 : s->crc_stream = crc32c_plain_char(s->crc_stream, c);
363 :
- 364 3808841 : *s->pos++ = c;
+ 364 3808025 : *s->pos++ = c;
365 :
- 366 3808841 : return 0;
+ 366 3808025 : 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 e2b16089..a64cfac2 100644
--- a/cov/cmdline/support.c.func-sort-c.html
+++ b/cov/cmdline/support.c.func-sort-c.html
@@ -61,123 +61,123 @@
| thread_mutex_unlock |
- 80857847 |
+ 80862235 |
| thread_mutex_lock |
- 80853291 |
+ 80858327 |
| pathcmp |
- 51888281 |
+ 51889998 |
| pathprint |
- 51562554 |
+ 51564205 |
| unlock_memory |
- 20174119 |
+ 20174230 |
| lock_memory |
- 20174119 |
+ 20174230 |
| malloc_counter_inc |
- 20173645 |
+ 20173756 |
| malloc_nofail |
- 14364256 |
+ 14364226 |
| advise_read |
- 8903012 |
+ 8903872 |
| pathcpy |
- 7891437 |
+ 7892425 |
| strdup_nofail |
- 5799372 |
-
-
- | unlock_msg |
- 3888570 |
+ 5799477 |
| lock_msg |
- 3888569 |
+ 3887429 |
+
+
+ | unlock_msg |
+ 3887429 |
| log_tag |
- 2908990 |
+ 2907978 |
| advise_flags |
- 2494931 |
+ 2495042 |
| advise_init |
- 2494857 |
+ 2494967 |
| esc_tag |
- 2429566 |
+ 2428739 |
| advise_open |
- 2416121 |
+ 2416234 |
| thread_cond_wait |
- 1095193 |
+ 1095059 |
| advise_write |
- 900323 |
+ 900676 |
| mkancestor |
- 793097 |
+ 793090 |
| log_error |
- 536153 |
+ 536045 |
| esc_shell_multi |
- 356012 |
+ 356083 |
| msg_info |
- 295787 |
+ 295858 |
| thread_cond_broadcast |
- 255449 |
+ 255625 |
| thread_cond_broadcast_and_unlock |
- 255259 |
+ 255435 |
| msg_verbose |
- 126951 |
+ 126963 |
| fmtime |
- 119601 |
+ 119641 |
| thread_cond_signal |
- 84548 |
+ 83165 |
| thread_cond_signal_and_unlock |
- 84548 |
+ 83165 |
| pathexport |
@@ -185,7 +185,7 @@
| pathimport |
- 16494 |
+ 16519 |
| log_expected |
@@ -193,19 +193,19 @@
| calloc_nofail |
- 10017 |
+ 10053 |
| pathslash |
- 7693 |
+ 7699 |
| msg_progress |
- 4445 |
+ 4447 |
| thread_mutex_init |
- 2268 |
+ 2276 |
| thread_create |
@@ -221,15 +221,15 @@
| msg_bar |
- 1778 |
+ 1678 |
| strsplit |
- 1465 |
+ 1466 |
| log_flush |
- 1190 |
+ 1196 |
| log_fatal |
@@ -241,11 +241,11 @@
| msg_status |
- 616 |
+ 625 |
| msg_flush |
- 591 |
+ 571 |
| malloc_counter_get |
@@ -261,11 +261,11 @@
| lock_init |
- 297 |
+ 298 |
| pathcat |
- 265 |
+ 266 |
| lock_done |
diff --git a/cov/cmdline/support.c.func.html b/cov/cmdline/support.c.func.html
index decef537..d22e86c9 100644
--- a/cov/cmdline/support.c.func.html
+++ b/cov/cmdline/support.c.func.html
@@ -61,39 +61,39 @@
| advise_flags |
- 2494931 |
+ 2495042 |
| advise_init |
- 2494857 |
+ 2494967 |
| advise_open |
- 2416121 |
+ 2416234 |
| advise_read |
- 8903012 |
+ 8903872 |
| advise_write |
- 900323 |
+ 900676 |
| calloc_nofail |
- 10017 |
+ 10053 |
| esc_shell_multi |
- 356012 |
+ 356083 |
| esc_tag |
- 2429566 |
+ 2428739 |
| fmtime |
- 119601 |
+ 119641 |
| lock_done |
@@ -101,19 +101,19 @@
| lock_init |
- 297 |
+ 298 |
| lock_memory |
- 20174119 |
+ 20174230 |
| lock_msg |
- 3888569 |
+ 3887429 |
| log_error |
- 536153 |
+ 536045 |
| log_expected |
@@ -125,11 +125,11 @@
| log_flush |
- 1190 |
+ 1196 |
| log_tag |
- 2908990 |
+ 2907978 |
| malloc_counter_get |
@@ -137,43 +137,43 @@
| malloc_counter_inc |
- 20173645 |
+ 20173756 |
| malloc_nofail |
- 14364256 |
+ 14364226 |
| mkancestor |
- 793097 |
+ 793090 |
| msg_bar |
- 1778 |
+ 1678 |
| msg_flush |
- 591 |
+ 571 |
| msg_info |
- 295787 |
+ 295858 |
| msg_progress |
- 4445 |
+ 4447 |
| msg_status |
- 616 |
+ 625 |
| msg_verbose |
- 126951 |
+ 126963 |
| pathcat |
- 265 |
+ 266 |
| pathcatc |
@@ -181,11 +181,11 @@
| pathcmp |
- 51888281 |
+ 51889998 |
| pathcpy |
- 7891437 |
+ 7892425 |
| pathcut |
@@ -197,15 +197,15 @@
| pathimport |
- 16494 |
+ 16519 |
| pathprint |
- 51562554 |
+ 51564205 |
| pathslash |
- 7693 |
+ 7699 |
| printc |
@@ -237,7 +237,7 @@
| strdup_nofail |
- 5799372 |
+ 5799477 |
| strpolish |
@@ -245,15 +245,15 @@
| strsplit |
- 1465 |
+ 1466 |
| thread_cond_broadcast |
- 255449 |
+ 255625 |
| thread_cond_broadcast_and_unlock |
- 255259 |
+ 255435 |
| thread_cond_destroy |
@@ -265,15 +265,15 @@
| thread_cond_signal |
- 84548 |
+ 83165 |
| thread_cond_signal_and_unlock |
- 84548 |
+ 83165 |
| thread_cond_wait |
- 1095193 |
+ 1095059 |
| thread_create |
@@ -289,23 +289,23 @@
| thread_mutex_init |
- 2268 |
+ 2276 |
| thread_mutex_lock |
- 80853291 |
+ 80858327 |
| thread_mutex_unlock |
- 80857847 |
+ 80862235 |
| unlock_memory |
- 20174119 |
+ 20174230 |
| unlock_msg |
- 3888570 |
+ 3887429 |
diff --git a/cov/cmdline/support.c.gcov.html b/cov/cmdline/support.c.gcov.html
index 41f959a4..96cd8100 100644
--- a/cov/cmdline/support.c.gcov.html
+++ b/cov/cmdline/support.c.gcov.html
@@ -92,42 +92,42 @@
30 : static pthread_mutex_t memory_lock;
31 : #endif
32 :
- 33 3888569 : void lock_msg(void)
+ 33 3887429 : void lock_msg(void)
34 : {
35 : #if HAVE_PTHREAD
- 36 3888569 : thread_mutex_lock(&msg_lock);
+ 36 3887429 : thread_mutex_lock(&msg_lock);
37 : #endif
- 38 3888570 : }
+ 38 3887429 : }
39 :
- 40 3888570 : void unlock_msg(void)
+ 40 3887429 : void unlock_msg(void)
41 : {
42 : #if HAVE_PTHREAD
- 43 3888570 : thread_mutex_unlock(&msg_lock);
+ 43 3887429 : thread_mutex_unlock(&msg_lock);
44 : #endif
- 45 3888570 : }
+ 45 3887429 : }
46 :
- 47 20174119 : void lock_memory(void)
+ 47 20174230 : void lock_memory(void)
48 : {
49 : #if HAVE_PTHREAD
- 50 20174119 : thread_mutex_lock(&memory_lock);
+ 50 20174230 : thread_mutex_lock(&memory_lock);
51 : #endif
- 52 20174119 : }
+ 52 20174230 : }
53 :
- 54 20174119 : void unlock_memory(void)
+ 54 20174230 : void unlock_memory(void)
55 : {
56 : #if HAVE_PTHREAD
- 57 20174119 : thread_mutex_unlock(&memory_lock);
+ 57 20174230 : thread_mutex_unlock(&memory_lock);
58 : #endif
- 59 20174119 : }
+ 59 20174230 : }
60 :
- 61 297 : void lock_init(void)
+ 61 298 : void lock_init(void)
62 : {
63 : #if HAVE_PTHREAD
64 : /* initialize the locks as first operation as log_fatal depends on them */
- 65 297 : thread_mutex_init(&msg_lock, 0);
- 66 297 : thread_mutex_init(&memory_lock, 0);
+ 65 298 : thread_mutex_init(&msg_lock, 0);
+ 66 298 : thread_mutex_init(&memory_lock, 0);
67 : #endif
- 68 297 : }
+ 68 298 : }
69 :
70 263 : void lock_done(void)
71 : {
@@ -176,18 +176,18 @@
114 809 : unlock_msg();
115 809 : }
116 :
- 117 536153 : void log_error(const char* format, ...)
+ 117 536045 : void log_error(const char* format, ...)
118 : {
119 : va_list ap;
120 :
- 121 536153 : lock_msg();
+ 121 536045 : lock_msg();
122 :
- 123 536153 : if (stdlog) {
- 124 534273 : va_start(ap, format);
- 125 534273 : fprintf(stdlog, "msg:error: ");
- 126 534273 : vfprintf(stdlog, format, ap);
- 127 534273 : fflush(stdlog);
- 128 534273 : va_end(ap);
+ 123 536045 : if (stdlog) {
+ 124 534165 : va_start(ap, format);
+ 125 534165 : fprintf(stdlog, "msg:error: ");
+ 126 534165 : vfprintf(stdlog, format, ap);
+ 127 534165 : fflush(stdlog);
+ 128 534165 : va_end(ap);
129 : } else {
130 1880 : va_start(ap, format);
131 1880 : vfprintf(stderr, format, ap);
@@ -195,8 +195,8 @@
133 1880 : va_end(ap);
134 : }
135 :
- 136 536153 : unlock_msg();
- 137 536153 : }
+ 136 536045 : unlock_msg();
+ 137 536045 : }
138 :
139 11259 : void log_expected(const char* format, ...)
140 : {
@@ -215,42 +215,42 @@
153 11259 : unlock_msg();
154 11259 : }
155 :
- 156 2908990 : void log_tag(const char* format, ...)
+ 156 2907978 : void log_tag(const char* format, ...)
157 : {
158 : va_list ap;
159 :
- 160 2908990 : lock_msg();
+ 160 2907978 : lock_msg();
161 :
- 162 2908991 : if (stdlog) {
- 163 2573555 : va_start(ap, format);
- 164 2573555 : vfprintf(stdlog, format, ap);
+ 162 2907978 : if (stdlog) {
+ 163 2572493 : va_start(ap, format);
+ 164 2572493 : vfprintf(stdlog, format, ap);
165 : /* here we intentionally don't flush */
166 : /* to make the output faster */
- 167 2573555 : va_end(ap);
+ 167 2572493 : va_end(ap);
168 : }
169 :
- 170 2908991 : unlock_msg();
- 171 2908991 : }
+ 170 2907978 : unlock_msg();
+ 171 2907978 : }
172 :
- 173 1190 : void log_flush(void)
+ 173 1196 : void log_flush(void)
174 : {
- 175 1190 : lock_msg();
+ 175 1196 : lock_msg();
176 :
- 177 1190 : if (stdlog)
- 178 338 : fflush(stdlog);
- 179 1190 : fflush(stdout);
- 180 1190 : fflush(stderr);
+ 177 1196 : if (stdlog)
+ 178 339 : fflush(stdlog);
+ 179 1196 : fflush(stdout);
+ 180 1196 : fflush(stderr);
181 :
- 182 1190 : unlock_msg();
- 183 1190 : }
+ 182 1196 : unlock_msg();
+ 183 1196 : }
184 :
- 185 616 : void msg_status(const char* format, ...)
+ 185 625 : void msg_status(const char* format, ...)
186 : {
187 : va_list ap;
188 :
- 189 616 : lock_msg();
+ 189 625 : lock_msg();
190 :
- 191 616 : if (stdlog) {
+ 191 625 : if (stdlog) {
192 275 : va_start(ap, format);
193 275 : fprintf(stdlog, "msg:status: ");
194 275 : vfprintf(stdlog, format, ap);
@@ -258,42 +258,42 @@
196 275 : va_end(ap);
197 : }
198 :
- 199 616 : if (msg_level >= MSG_STATUS) {
- 200 616 : va_start(ap, format);
- 201 616 : vfprintf(stdout, format, ap);
- 202 616 : fflush(stdout);
- 203 616 : va_end(ap);
+ 199 625 : if (msg_level >= MSG_STATUS) {
+ 200 625 : va_start(ap, format);
+ 201 625 : vfprintf(stdout, format, ap);
+ 202 625 : fflush(stdout);
+ 203 625 : va_end(ap);
204 : }
205 :
- 206 616 : unlock_msg();
- 207 616 : }
+ 206 625 : unlock_msg();
+ 207 625 : }
208 :
- 209 295787 : void msg_info(const char* format, ...)
+ 209 295858 : void msg_info(const char* format, ...)
210 : {
211 : va_list ap;
212 :
- 213 295787 : lock_msg();
+ 213 295858 : lock_msg();
214 :
215 : /* don't output in stdlog as these messages */
216 : /* are always paired with a msg_tag() call */
217 :
- 218 295787 : if (msg_level >= MSG_INFO) {
- 219 28811 : va_start(ap, format);
- 220 28811 : vfprintf(stdout, format, ap);
- 221 28811 : fflush(stdout);
- 222 28811 : va_end(ap);
+ 218 295858 : if (msg_level >= MSG_INFO) {
+ 219 28841 : va_start(ap, format);
+ 220 28841 : vfprintf(stdout, format, ap);
+ 221 28841 : fflush(stdout);
+ 222 28841 : va_end(ap);
223 : }
224 :
- 225 295787 : unlock_msg();
- 226 295787 : }
+ 225 295858 : unlock_msg();
+ 226 295858 : }
227 :
- 228 4445 : void msg_progress(const char* format, ...)
+ 228 4447 : void msg_progress(const char* format, ...)
229 : {
230 : va_list ap;
231 :
- 232 4445 : lock_msg();
+ 232 4447 : lock_msg();
233 :
- 234 4445 : if (stdlog) {
+ 234 4447 : if (stdlog) {
235 819 : va_start(ap, format);
236 819 : fprintf(stdlog, "msg:progress: ");
237 819 : vfprintf(stdlog, format, ap);
@@ -301,68 +301,68 @@
239 819 : va_end(ap);
240 : }
241 :
- 242 4445 : if (msg_level >= MSG_PROGRESS) {
- 243 159 : va_start(ap, format);
- 244 159 : vfprintf(stdout, format, ap);
- 245 159 : fflush(stdout);
- 246 159 : va_end(ap);
+ 242 4447 : if (msg_level >= MSG_PROGRESS) {
+ 243 161 : va_start(ap, format);
+ 244 161 : vfprintf(stdout, format, ap);
+ 245 161 : fflush(stdout);
+ 246 161 : va_end(ap);
247 : }
248 :
- 249 4445 : unlock_msg();
- 250 4445 : }
+ 249 4447 : unlock_msg();
+ 250 4447 : }
251 :
- 252 1778 : void msg_bar(const char* format, ...)
+ 252 1678 : void msg_bar(const char* format, ...)
253 : {
254 : va_list ap;
255 :
- 256 1778 : lock_msg();
+ 256 1678 : lock_msg();
257 :
258 : /* don't output in stdlog as these messages */
259 : /* are intended for screen only */
260 : /* also don't flush stdout as they are intended to be partial messages */
261 :
- 262 1778 : if (msg_level >= MSG_BAR) {
+ 262 1678 : if (msg_level >= MSG_BAR) {
263 0 : va_start(ap, format);
264 0 : vfprintf(stdout, format, ap);
265 0 : va_end(ap);
266 : }
267 :
- 268 1778 : unlock_msg();
- 269 1778 : }
+ 268 1678 : unlock_msg();
+ 269 1678 : }
270 :
- 271 126951 : void msg_verbose(const char* format, ...)
+ 271 126963 : void msg_verbose(const char* format, ...)
272 : {
273 : va_list ap;
274 :
- 275 126951 : lock_msg();
+ 275 126963 : lock_msg();
276 :
- 277 126951 : if (stdlog) {
- 278 125093 : va_start(ap, format);
- 279 125093 : fprintf(stdlog, "msg:verbose: ");
- 280 125093 : vfprintf(stdlog, format, ap);
- 281 125093 : fflush(stdlog);
- 282 125093 : va_end(ap);
+ 277 126963 : if (stdlog) {
+ 278 125101 : va_start(ap, format);
+ 279 125101 : fprintf(stdlog, "msg:verbose: ");
+ 280 125101 : vfprintf(stdlog, format, ap);
+ 281 125101 : fflush(stdlog);
+ 282 125101 : va_end(ap);
283 : }
284 :
- 285 126951 : if (msg_level >= MSG_VERBOSE) {
- 286 87 : va_start(ap, format);
- 287 87 : vfprintf(stdout, format, ap);
- 288 87 : fflush(stdout);
- 289 87 : va_end(ap);
+ 285 126963 : if (msg_level >= MSG_VERBOSE) {
+ 286 91 : va_start(ap, format);
+ 287 91 : vfprintf(stdout, format, ap);
+ 288 91 : fflush(stdout);
+ 289 91 : va_end(ap);
290 : }
291 :
- 292 126951 : unlock_msg();
- 293 126951 : }
+ 292 126963 : unlock_msg();
+ 293 126963 : }
294 :
- 295 591 : void msg_flush(void)
+ 295 571 : void msg_flush(void)
296 : {
- 297 591 : lock_msg();
+ 297 571 : lock_msg();
298 :
- 299 591 : fflush(stdout);
- 300 591 : fflush(stderr);
+ 299 571 : fflush(stdout);
+ 300 571 : fflush(stderr);
301 :
- 302 591 : unlock_msg();
- 303 591 : }
+ 302 571 : unlock_msg();
+ 303 571 : }
304 :
305 64 : void printc(char c, size_t pad)
306 : {
@@ -451,17 +451,17 @@
389 : *p++ = to; \
390 : break
391 :
- 392 2429566 : const char* esc_tag(const char* str, char* buffer)
+ 392 2428739 : const char* esc_tag(const char* str, char* buffer)
393 : {
- 394 2429566 : char* begin = buffer;
- 395 2429566 : char* end = begin + ESC_MAX;
- 396 2429566 : char* p = begin;
+ 394 2428739 : char* begin = buffer;
+ 395 2428739 : char* end = begin + ESC_MAX;
+ 396 2428739 : char* p = begin;
397 :
398 : /* copy string with escaping */
- 399 36399361 : while (*str) {
- 400 31540229 : char c = *str;
+ 399 36388202 : while (*str) {
+ 400 31530724 : char c = *str;
401 :
- 402 31540229 : switch (c) {
+ 402 31530724 : switch (c) {
403 :
404 0 : ESCAPE('\n', '\\', 'n');
405 0 : ESCAPE('\r', '\\', 'r');
@@ -469,21 +469,21 @@
407 0 : ESCAPE('\\', '\\', '\\');
408 :
409 : default:
- 410 31540229 : if (p == end)
+ 410 31530724 : if (p == end)
411 0 : goto bail;
- 412 31540229 : *p++ = c;
- 413 31540229 : break;
+ 412 31530724 : *p++ = c;
+ 413 31530724 : break;
414 : }
415 :
- 416 31540229 : ++str;
+ 416 31530724 : ++str;
417 : }
418 :
419 : /* put final 0 */
- 420 2429566 : if (p == end)
+ 420 2428739 : if (p == end)
421 0 : goto bail;
- 422 2429566 : *p = 0;
+ 422 2428739 : *p = 0;
423 :
- 424 4859132 : return begin;
+ 424 4857478 : return begin;
425 :
426 : bail:
427 : /* LCOV_EXCL_START */
@@ -492,11 +492,11 @@
430 : /* LCOV_EXCL_STOP */
431 : }
432 :
- 433 356012 : const char* esc_shell_multi(const char** str_map, unsigned str_max, char* buffer)
+ 433 356083 : const char* esc_shell_multi(const char** str_map, unsigned str_max, char* buffer)
434 : {
- 435 356012 : char* begin = buffer;
- 436 356012 : char* end = begin + ESC_MAX;
- 437 356012 : char* p = begin;
+ 435 356083 : char* begin = buffer;
+ 436 356083 : char* end = begin + ESC_MAX;
+ 437 356083 : char* p = begin;
438 : unsigned str_mac;
439 : const char* str;
440 :
@@ -517,24 +517,24 @@
455 : #endif
456 :
457 : /* copy string with escaping */
- 458 356012 : str_mac = 0;
- 459 356012 : str = str_map[str_mac];
+ 458 356083 : str_mac = 0;
+ 459 356083 : str = str_map[str_mac];
460 : while (1) {
461 : /* get the next char */
- 462 5124568 : char c = *str;
+ 462 5126024 : char c = *str;
463 :
464 : /* if one string is finished, go to the next */
- 465 10285226 : while (c == 0 && str_mac + 1 < str_max) {
+ 465 10288138 : while (c == 0 && str_mac + 1 < str_max) {
466 36090 : ++str_mac;
467 36090 : str = str_map[str_mac];
468 36090 : c = *str;
469 : }
470 :
471 : /* if we read all the strings, stop */
- 472 5124568 : if (!c)
- 473 356012 : break;
+ 472 5126024 : if (!c)
+ 473 356083 : break;
474 :
- 475 4768556 : switch (c) {
+ 475 4769941 : switch (c) {
476 : #ifdef _WIN32
477 : /*
478 : * Windows shell escape
@@ -609,24 +609,24 @@
547 : case '/' :
548 : case '-' :
549 : /* safe chars for all shells, unquoted */
- 550 4689540 : if (p == end)
+ 550 4690836 : if (p == end)
551 0 : goto bail;
- 552 4689540 : *p++ = c;
- 553 4689540 : break;
+ 552 4690836 : *p++ = c;
+ 553 4690836 : break;
554 : default :
555 : /* all the others are quoted with \ */
- 556 79016 : if (p == end)
+ 556 79105 : if (p == end)
557 0 : goto bail;
- 558 79016 : *p++ = '\\';
- 559 79016 : if (p == end)
+ 558 79105 : *p++ = '\\';
+ 559 79105 : if (p == end)
560 0 : goto bail;
- 561 79016 : *p++ = c;
- 562 79016 : break;
+ 561 79105 : *p++ = c;
+ 562 79105 : break;
563 : #endif
564 : }
565 :
- 566 4768556 : ++str;
- 567 4768556 : }
+ 566 4769941 : ++str;
+ 567 4769941 : }
568 :
569 : #ifdef _WIN32
570 : if (has_quote) {
@@ -637,11 +637,11 @@
575 : #endif
576 :
577 : /* put final 0 */
- 578 356012 : if (p == end)
+ 578 356083 : if (p == end)
579 0 : goto bail;
- 580 356012 : *p = 0;
+ 580 356083 : *p = 0;
581 :
- 582 712024 : return begin;
+ 582 712166 : return begin;
583 :
584 : bail:
585 : /* LCOV_EXCL_START */
@@ -663,63 +663,63 @@
601 0 : return s;
602 : }
603 :
- 604 1465 : unsigned strsplit(char** split_map, unsigned split_max, char* str, const char* delimiters)
+ 604 1466 : unsigned strsplit(char** split_map, unsigned split_max, char* str, const char* delimiters)
605 : {
- 606 1465 : unsigned mac = 0;
+ 606 1466 : unsigned mac = 0;
607 :
608 : /* skip initial delimiters */
- 609 1465 : str += strspn(str, delimiters);
+ 609 1466 : str += strspn(str, delimiters);
610 :
- 611 8890 : while (*str != 0 || mac == split_max) {
+ 611 8896 : while (*str != 0 || mac == split_max) {
612 : /* start of the token */
- 613 5960 : split_map[mac] = str;
- 614 5960 : ++mac;
+ 613 5964 : split_map[mac] = str;
+ 614 5964 : ++mac;
615 :
616 : /* find the first delimiter or the end of the string */
- 617 5960 : str += strcspn(str, delimiters);
+ 617 5964 : str += strcspn(str, delimiters);
618 :
619 : /* put the final terminator if missing */
- 620 5960 : if (*str != 0)
- 621 4595 : *str++ = 0;
+ 620 5964 : if (*str != 0)
+ 621 4598 : *str++ = 0;
622 :
623 : /* skip trailing delimiters */
- 624 5960 : str += strspn(str, delimiters);
+ 624 5964 : str += strspn(str, delimiters);
625 : }
626 :
- 627 1465 : return mac;
+ 627 1466 : return mac;
628 : }
629 :
630 : /****************************************************************************/
631 : /* path */
632 :
- 633 7891437 : void pathcpy(char* dst, size_t size, const char* src)
+ 633 7892425 : void pathcpy(char* dst, size_t size, const char* src)
634 : {
- 635 7891437 : size_t len = strlen(src);
+ 635 7892425 : size_t len = strlen(src);
636 :
- 637 7891437 : if (len + 1 > size) {
+ 637 7892425 : if (len + 1 > size) {
638 : /* LCOV_EXCL_START */
639 : log_fatal("Path too long '%s'\n", src);
640 : os_abort();
641 : /* LCOV_EXCL_STOP */
642 : }
643 :
- 644 7891437 : memcpy(dst, src, len + 1);
- 645 7891437 : }
+ 644 7892425 : memcpy(dst, src, len + 1);
+ 645 7892425 : }
646 :
- 647 265 : void pathcat(char* dst, size_t size, const char* src)
+ 647 266 : void pathcat(char* dst, size_t size, const char* src)
648 : {
- 649 265 : size_t dst_len = strlen(dst);
- 650 265 : size_t src_len = strlen(src);
+ 649 266 : size_t dst_len = strlen(dst);
+ 650 266 : size_t src_len = strlen(src);
651 :
- 652 265 : if (dst_len + src_len + 1 > size) {
+ 652 266 : if (dst_len + src_len + 1 > size) {
653 : /* LCOV_EXCL_START */
654 : log_fatal("Path too long '%s%s'\n", dst, src);
655 : os_abort();
656 : /* LCOV_EXCL_STOP */
657 : }
658 :
- 659 265 : memcpy(dst + dst_len, src, src_len + 1);
- 660 265 : }
+ 659 266 : memcpy(dst + dst_len, src, src_len + 1);
+ 660 266 : }
661 :
662 788 : void pathcatc(char* dst, size_t size, char c)
663 : {
@@ -736,9 +736,9 @@
674 788 : dst[dst_len + 1] = 0;
675 788 : }
676 :
- 677 16494 : void pathimport(char* dst, size_t size, const char* src)
+ 677 16519 : void pathimport(char* dst, size_t size, const char* src)
678 : {
- 679 16494 : pathcpy(dst, size, src);
+ 679 16519 : pathcpy(dst, size, src);
680 :
681 : #ifdef _WIN32
682 : /* convert the Windows dir separator '\' to C '/', */
@@ -755,7 +755,7 @@
693 : ++dst;
694 : }
695 : #endif
- 696 16494 : }
+ 696 16519 : }
697 :
698 17589 : void pathexport(char* dst, size_t size, const char* src)
699 : {
@@ -777,16 +777,16 @@
715 : #endif
716 17589 : }
717 :
- 718 51562554 : void pathprint(char* dst, size_t size, const char* format, ...)
+ 718 51564205 : void pathprint(char* dst, size_t size, const char* format, ...)
719 : {
720 : size_t len;
721 : va_list ap;
722 :
- 723 51562554 : va_start(ap, format);
- 724 51562554 : len = vsnprintf(dst, size, format, ap);
- 725 51562554 : va_end(ap);
+ 723 51564205 : va_start(ap, format);
+ 724 51564205 : len = vsnprintf(dst, size, format, ap);
+ 725 51564205 : va_end(ap);
726 :
- 727 51562554 : if (len >= size) {
+ 727 51564205 : if (len >= size) {
728 : /* LCOV_EXCL_START */
729 : if (size > 0) {
730 : dst[size - 1] = 0;
@@ -797,13 +797,13 @@
735 : os_abort();
736 : /* LCOV_EXCL_STOP */
737 : }
- 738 51562554 : }
+ 738 51564205 : }
739 :
- 740 7693 : void pathslash(char* dst, size_t size)
+ 740 7699 : void pathslash(char* dst, size_t size)
741 : {
- 742 7693 : size_t len = strlen(dst);
+ 742 7699 : size_t len = strlen(dst);
743 :
- 744 7693 : if (len > 0 && dst[len - 1] != '/') {
+ 744 7699 : if (len > 0 && dst[len - 1] != '/') {
745 6114 : if (len + 2 >= size) {
746 : /* LCOV_EXCL_START */
747 : log_fatal("Path too long '%s/'\n", dst);
@@ -814,7 +814,7 @@
752 6114 : dst[len] = '/';
753 6114 : dst[len + 1] = 0;
754 : }
- 755 7693 : }
+ 755 7699 : }
756 :
757 100 : void pathcut(char* dst)
758 : {
@@ -826,7 +826,7 @@
764 0 : dst[0] = 0;
765 100 : }
766 :
- 767 51888281 : int pathcmp(const char* a, const char* b)
+ 767 51889998 : int pathcmp(const char* a, const char* b)
768 : {
769 : #ifdef _WIN32
770 : char ai[PATH_MAX];
@@ -839,32 +839,32 @@
777 : /* case insensitive compare in Windows */
778 : return stricmp(ai, bi);
779 : #else
- 780 51888281 : return strcmp(a, b);
+ 780 51889998 : return strcmp(a, b);
781 : #endif
782 : }
783 :
784 : /****************************************************************************/
785 : /* file-system */
786 :
- 787 793097 : int mkancestor(const char* file)
+ 787 793090 : int mkancestor(const char* file)
788 : {
789 : char dir[PATH_MAX];
790 : struct stat st;
791 : char* c;
792 :
- 793 793097 : pathcpy(dir, sizeof(dir), file);
+ 793 793090 : pathcpy(dir, sizeof(dir), file);
794 :
- 795 793097 : c = strrchr(dir, '/');
- 796 793097 : if (!c) {
+ 795 793090 : c = strrchr(dir, '/');
+ 796 793090 : if (!c) {
797 : /* no ancestor */
798 0 : return 0;
799 : }
800 :
801 : /* clear the file */
- 802 793097 : *c = 0;
+ 802 793090 : *c = 0;
803 :
804 : /* if it's the root dir */
- 805 793097 : if (*dir == 0) {
+ 805 793090 : if (*dir == 0) {
806 : /* nothing more to do */
807 0 : return 0;
808 : }
@@ -887,9 +887,9 @@
825 : * Also in Windows it's better to use lstat() than stat() because it
826 : * doesn't need to open the dir with CreateFile().
827 : */
- 828 793097 : if (lstat(dir, &st) == 0) {
+ 828 793090 : if (lstat(dir, &st) == 0) {
829 : /* it already exists */
- 830 793017 : return 0;
+ 830 793010 : return 0;
831 : }
832 :
833 : /* recursively create them all */
@@ -910,7 +910,7 @@
848 80 : return 0;
849 : }
850 :
- 851 119601 : int fmtime(int f, int64_t mtime_sec, int mtime_nsec)
+ 851 119641 : int fmtime(int f, int64_t mtime_sec, int mtime_nsec)
852 : {
853 : #if HAVE_FUTIMENS
854 : struct timespec tv[2];
@@ -920,15 +920,15 @@
858 : int ret;
859 :
860 : #if HAVE_FUTIMENS /* futimens() is preferred because it gives nanosecond precision */
- 861 119601 : tv[0].tv_sec = mtime_sec;
- 862 119601 : if (mtime_nsec != STAT_NSEC_INVALID)
- 863 119601 : tv[0].tv_nsec = mtime_nsec;
+ 861 119641 : tv[0].tv_sec = mtime_sec;
+ 862 119641 : if (mtime_nsec != STAT_NSEC_INVALID)
+ 863 119641 : tv[0].tv_nsec = mtime_nsec;
864 : else
865 0 : tv[0].tv_nsec = 0;
- 866 119601 : tv[1].tv_sec = tv[0].tv_sec;
- 867 119601 : tv[1].tv_nsec = tv[0].tv_nsec;
+ 866 119641 : tv[1].tv_sec = tv[0].tv_sec;
+ 867 119641 : tv[1].tv_nsec = tv[0].tv_nsec;
868 :
- 869 119601 : ret = futimens(f, tv);
+ 869 119641 : ret = futimens(f, tv);
870 : #elif HAVE_FUTIMES /* fallback to futimes() if nanosecond precision is not available */
871 : tv[0].tv_sec = mtime_sec;
872 : if (mtime_nsec != STAT_NSEC_INVALID)
@@ -953,47 +953,47 @@
891 : #error No function available to set file timestamps with sub-second precision
892 : #endif
893 :
- 894 119601 : return ret;
+ 894 119641 : return ret;
895 : }
896 :
897 : /****************************************************************************/
898 : /* advise */
899 :
- 900 2494857 : void advise_init(struct advise_struct* advise, int mode)
+ 900 2494967 : void advise_init(struct advise_struct* advise, int mode)
901 : {
- 902 2494857 : advise->mode = mode;
- 903 2494857 : advise->dirty_begin = 0;
- 904 2494857 : advise->dirty_end = 0;
- 905 2494857 : }
+ 902 2494967 : advise->mode = mode;
+ 903 2494967 : advise->dirty_begin = 0;
+ 904 2494967 : advise->dirty_end = 0;
+ 905 2494967 : }
906 :
- 907 2494931 : int advise_flags(struct advise_struct* advise)
+ 907 2495042 : int advise_flags(struct advise_struct* advise)
908 : {
- 909 2494931 : int flags = 0;
+ 909 2495042 : int flags = 0;
910 :
- 911 2494931 : if (advise->mode == ADVISE_SEQUENTIAL
- 912 2483486 : || advise->mode == ADVISE_FLUSH
+ 911 2495042 : if (advise->mode == ADVISE_SEQUENTIAL
+ 912 2483696 : || advise->mode == ADVISE_FLUSH
913 34023 : || advise->mode == ADVISE_FLUSH_WINDOW
- 914 22684 : || advise->mode == ADVISE_DISCARD
- 915 22684 : || advise->mode == ADVISE_DISCARD_WINDOW
+ 914 22683 : || advise->mode == ADVISE_DISCARD
+ 915 22683 : || advise->mode == ADVISE_DISCARD_WINDOW
916 : )
- 917 2483585 : flags |= O_SEQUENTIAL;
+ 917 2483698 : flags |= O_SEQUENTIAL;
918 :
919 : #if HAVE_DIRECT_IO
- 920 2494931 : if (advise->mode == ADVISE_DIRECT)
+ 920 2495042 : if (advise->mode == ADVISE_DIRECT)
921 0 : flags |= O_DIRECT;
922 : #endif
923 :
- 924 2494931 : return flags;
+ 924 2495042 : return flags;
925 : }
926 :
- 927 2416121 : int advise_open(struct advise_struct* advise, int f)
+ 927 2416234 : int advise_open(struct advise_struct* advise, int f)
928 : {
929 : (void)advise;
930 : (void)f;
931 :
932 : #if HAVE_POSIX_FADVISE
- 933 2416121 : if (advise->mode == ADVISE_SEQUENTIAL
- 934 2404826 : || advise->mode == ADVISE_FLUSH
+ 933 2416234 : if (advise->mode == ADVISE_SEQUENTIAL
+ 934 2405052 : || advise->mode == ADVISE_FLUSH
935 34025 : || advise->mode == ADVISE_FLUSH_WINDOW
936 22684 : || advise->mode == ADVISE_DISCARD
937 22684 : || advise->mode == ADVISE_DISCARD_WINDOW
@@ -1001,12 +1001,12 @@
939 : int ret;
940 :
941 : /* advise sequential access */
- 942 2404810 : ret = posix_fadvise(f, 0, 0, POSIX_FADV_SEQUENTIAL);
- 943 2404853 : if (ret == ENOSYS) {
+ 942 2404908 : ret = posix_fadvise(f, 0, 0, POSIX_FADV_SEQUENTIAL);
+ 943 2405073 : if (ret == ENOSYS) {
944 : /* call is not supported, like in armhf, see posix_fadvise manpage */
945 0 : ret = 0;
946 : }
- 947 2404853 : if (ret != 0) {
+ 947 2405073 : if (ret != 0) {
948 : /* LCOV_EXCL_START */
949 : errno = ret; /* posix_fadvise return the error code */
950 : return -1;
@@ -1015,10 +1015,10 @@
953 : }
954 : #endif
955 :
- 956 2416164 : return 0;
+ 956 2416399 : return 0;
957 : }
958 :
- 959 900323 : int advise_write(struct advise_struct* advise, int f, data_off_t offset, data_off_t size)
+ 959 900676 : int advise_write(struct advise_struct* advise, int f, data_off_t offset, data_off_t size)
960 : {
961 : data_off_t flush_offset;
962 : data_off_t flush_size;
@@ -1031,10 +1031,10 @@
969 : (void)discard_offset;
970 : (void)discard_size;
971 :
- 972 900323 : flush_offset = 0;
- 973 900323 : flush_size = 0;
- 974 900323 : discard_offset = 0;
- 975 900323 : discard_size = 0;
+ 972 900676 : flush_offset = 0;
+ 973 900676 : flush_size = 0;
+ 974 900676 : discard_offset = 0;
+ 975 900676 : discard_size = 0;
976 :
977 : /*
978 : * Follow Linus recommendations about fast writes.
@@ -1089,11 +1089,11 @@
1027 : * ---
1028 : */
1029 :
- 1030 900323 : switch (advise->mode) {
+ 1030 900676 : switch (advise->mode) {
1031 : case ADVISE_FLUSH :
- 1032 881574 : flush_offset = offset;
- 1033 881574 : flush_size = size;
- 1034 881574 : break;
+ 1032 881928 : flush_offset = offset;
+ 1033 881928 : flush_size = size;
+ 1034 881928 : break;
1035 : case ADVISE_DISCARD :
1036 0 : discard_offset = offset;
1037 0 : discard_size = size;
@@ -1155,12 +1155,12 @@
1093 : }
1094 :
1095 : #if HAVE_SYNC_FILE_RANGE
- 1096 900323 : if (flush_size != 0) {
+ 1096 900676 : if (flush_size != 0) {
1097 : int ret;
1098 :
1099 : /* start writing immediately */
- 1100 881575 : ret = sync_file_range(f, flush_offset, flush_size, SYNC_FILE_RANGE_WRITE);
- 1101 881569 : if (ret != 0) {
+ 1100 881932 : ret = sync_file_range(f, flush_offset, flush_size, SYNC_FILE_RANGE_WRITE);
+ 1101 881933 : if (ret != 0) {
1102 : /* LCOV_EXCL_START */
1103 : return -1;
1104 : /* LCOV_EXCL_STOP */
@@ -1169,7 +1169,7 @@
1107 : #endif
1108 :
1109 : #if HAVE_SYNC_FILE_RANGE && HAVE_POSIX_FADVISE
- 1110 900317 : if (discard_size != 0) {
+ 1110 900677 : if (discard_size != 0) {
1111 : int ret;
1112 :
1113 : /* send the data to the disk and wait until it's written */
@@ -1192,10 +1192,10 @@
1130 : }
1131 : #endif
1132 :
- 1133 900317 : return 0;
+ 1133 900677 : return 0;
1134 : }
1135 :
- 1136 8903012 : int advise_read(struct advise_struct* advise, int f, data_off_t offset, data_off_t size)
+ 1136 8903872 : int advise_read(struct advise_struct* advise, int f, data_off_t offset, data_off_t size)
1137 : {
1138 : (void)advise;
1139 : (void)f;
@@ -1203,15 +1203,15 @@
1141 : (void)size;
1142 :
1143 : #if HAVE_POSIX_FADVISE
- 1144 8903012 : if (advise->mode == ADVISE_DISCARD
- 1145 8903128 : || advise->mode == ADVISE_DISCARD_WINDOW
+ 1144 8903872 : if (advise->mode == ADVISE_DISCARD
+ 1145 8904012 : || advise->mode == ADVISE_DISCARD_WINDOW
1146 : ) {
1147 : int ret;
1148 :
1149 : /* flush the data from the cache */
- 1150 27677 : ret = posix_fadvise(f, offset, size, POSIX_FADV_DONTNEED);
+ 1150 27735 : ret = posix_fadvise(f, offset, size, POSIX_FADV_DONTNEED);
1151 : /* for POSIX_FADV_DONTNEED we don't allow failure with ENOSYS */
- 1152 27824 : if (ret != 0) {
+ 1152 27825 : if (ret != 0) {
1153 : /* LCOV_EXCL_START */
1154 : errno = ret; /* posix_fadvise return the error code */
1155 : return -1;
@@ -1258,7 +1258,7 @@
1196 : * ---
1197 : */
1198 :
- 1199 8903159 : return 0;
+ 1199 8903962 : return 0;
1200 : }
1201 :
1202 : /****************************************************************************/
@@ -1282,14 +1282,14 @@
1220 474 : return ret;
1221 : }
1222 :
- 1223 20173645 : void malloc_counter_inc(size_t inc)
+ 1223 20173756 : void malloc_counter_inc(size_t inc)
1224 : {
- 1225 20173645 : lock_memory();
+ 1225 20173756 : lock_memory();
1226 :
- 1227 20173645 : mcounter += inc;
+ 1227 20173756 : mcounter += inc;
1228 :
- 1229 20173645 : unlock_memory();
- 1230 20173645 : }
+ 1229 20173756 : unlock_memory();
+ 1230 20173756 : }
1231 :
1232 : /* LCOV_EXCL_START */
1233 : static ssize_t malloc_print(int f, const char* str)
@@ -1341,11 +1341,11 @@
1279 : }
1280 : /* LCOV_EXCL_STOP */
1281 :
- 1282 14364256 : void* malloc_nofail(size_t size)
+ 1282 14364226 : void* malloc_nofail(size_t size)
1283 : {
- 1284 14364256 : void* ptr = malloc(size);
+ 1284 14364226 : void* ptr = malloc(size);
1285 :
- 1286 14364256 : if (!ptr) {
+ 1286 14364226 : if (!ptr) {
1287 : /* LCOV_EXCL_START */
1288 : malloc_fail(size);
1289 : exit(EXIT_FAILURE);
@@ -1359,58 +1359,58 @@
1297 : /* Filling the memory doesn't ensure to disable OOM, but it increase a lot the chances to */
1298 : /* get a real error from malloc() instead than a process killed. */
1299 : /* Note that calloc() doesn't have the same effect. */
- 1300 14364256 : memset(ptr, 0xA5, size);
+ 1300 14364226 : memset(ptr, 0xA5, size);
1301 : #endif
1302 :
- 1303 14364256 : malloc_counter_inc(size);
+ 1303 14364226 : malloc_counter_inc(size);
1304 :
- 1305 14364256 : return ptr;
+ 1305 14364226 : return ptr;
1306 : }
1307 :
- 1308 10017 : void* calloc_nofail(size_t count, size_t size)
+ 1308 10053 : void* calloc_nofail(size_t count, size_t size)
1309 : {
1310 : void* ptr;
1311 :
- 1312 10017 : size *= count;
+ 1312 10053 : size *= count;
1313 :
1314 : /* see the note in malloc_nofail() of why we don't use calloc() */
- 1315 10017 : ptr = malloc(size);
+ 1315 10053 : ptr = malloc(size);
1316 :
- 1317 10017 : if (!ptr) {
+ 1317 10053 : if (!ptr) {
1318 : /* LCOV_EXCL_START */
1319 : malloc_fail(size);
1320 : exit(EXIT_FAILURE);
1321 : /* LCOV_EXCL_STOP */
1322 : }
1323 :
- 1324 10017 : memset(ptr, 0, size);
+ 1324 10053 : memset(ptr, 0, size);
1325 :
- 1326 10017 : malloc_counter_inc(size);
+ 1326 10053 : malloc_counter_inc(size);
1327 :
- 1328 10017 : return ptr;
+ 1328 10053 : return ptr;
1329 : }
1330 :
- 1331 5799372 : char* strdup_nofail(const char* str)
+ 1331 5799477 : char* strdup_nofail(const char* str)
1332 : {
1333 : size_t size;
1334 : char* ptr;
1335 :
- 1336 5799372 : size = strlen(str) + 1;
+ 1336 5799477 : size = strlen(str) + 1;
1337 :
- 1338 5799372 : ptr = malloc(size);
+ 1338 5799477 : ptr = malloc(size);
1339 :
- 1340 5799372 : if (!ptr) {
+ 1340 5799477 : if (!ptr) {
1341 : /* LCOV_EXCL_START */
1342 : malloc_fail(size);
1343 : exit(EXIT_FAILURE);
1344 : /* LCOV_EXCL_STOP */
1345 : }
1346 :
- 1347 5799372 : memcpy(ptr, str, size);
+ 1347 5799477 : memcpy(ptr, str, size);
1348 :
- 1349 5799372 : malloc_counter_inc(size);
+ 1349 5799477 : malloc_counter_inc(size);
1350 :
- 1351 5799372 : return ptr;
+ 1351 5799477 : return ptr;
1352 : }
1353 :
1354 : /****************************************************************************/
@@ -1552,15 +1552,15 @@
1490 : /* thread */
1491 :
1492 : #if HAVE_PTHREAD
- 1493 2268 : void thread_mutex_init(pthread_mutex_t* mutex, pthread_mutexattr_t* attr)
+ 1493 2276 : void thread_mutex_init(pthread_mutex_t* mutex, pthread_mutexattr_t* attr)
1494 : {
- 1495 2268 : if (pthread_mutex_init(mutex, attr) != 0) {
+ 1495 2276 : if (pthread_mutex_init(mutex, attr) != 0) {
1496 : /* LCOV_EXCL_START */
1497 : log_fatal("Failed call to pthread_mutex_init().\n");
1498 : os_abort();
1499 : /* LCOV_EXCL_STOP */
1500 : }
- 1501 2268 : }
+ 1501 2276 : }
1502 :
1503 2074 : void thread_mutex_destroy(pthread_mutex_t* mutex)
1504 : {
@@ -1572,25 +1572,25 @@
1510 : }
1511 2074 : }
1512 :
- 1513 80853291 : void thread_mutex_lock(pthread_mutex_t* mutex)
+ 1513 80858327 : void thread_mutex_lock(pthread_mutex_t* mutex)
1514 : {
- 1515 80853291 : if (pthread_mutex_lock(mutex) != 0) {
+ 1515 80858327 : if (pthread_mutex_lock(mutex) != 0) {
1516 : /* LCOV_EXCL_START */
1517 : log_fatal("Failed call to pthread_mutex_lock().\n");
1518 : os_abort();
1519 : /* LCOV_EXCL_STOP */
1520 : }
- 1521 80859260 : }
+ 1521 80863166 : }
1522 :
- 1523 80857847 : void thread_mutex_unlock(pthread_mutex_t* mutex)
+ 1523 80862235 : void thread_mutex_unlock(pthread_mutex_t* mutex)
1524 : {
- 1525 80857847 : if (pthread_mutex_unlock(mutex) != 0) {
+ 1525 80862235 : if (pthread_mutex_unlock(mutex) != 0) {
1526 : /* LCOV_EXCL_START */
1527 : log_fatal("Failed call to pthread_mutex_unlock().\n");
1528 : os_abort();
1529 : /* LCOV_EXCL_STOP */
1530 : }
- 1531 80860763 : }
+ 1531 80864541 : }
1532 :
1533 380 : void thread_cond_init(pthread_cond_t* cond, pthread_condattr_t* attr)
1534 : {
@@ -1612,35 +1612,35 @@
1550 : }
1551 380 : }
1552 :
- 1553 84548 : void thread_cond_signal(pthread_cond_t* cond)
+ 1553 83165 : void thread_cond_signal(pthread_cond_t* cond)
1554 : {
- 1555 84548 : if (pthread_cond_signal(cond) != 0) {
+ 1555 83165 : if (pthread_cond_signal(cond) != 0) {
1556 : /* LCOV_EXCL_START */
1557 : log_fatal("Failed call to pthread_cond_signal().\n");
1558 : os_abort();
1559 : /* LCOV_EXCL_STOP */
1560 : }
- 1561 84548 : }
+ 1561 83165 : }
1562 :
- 1563 255449 : void thread_cond_broadcast(pthread_cond_t* cond)
+ 1563 255625 : void thread_cond_broadcast(pthread_cond_t* cond)
1564 : {
- 1565 255449 : if (pthread_cond_broadcast(cond) != 0) {
+ 1565 255625 : if (pthread_cond_broadcast(cond) != 0) {
1566 : /* LCOV_EXCL_START */
1567 : log_fatal("Failed call to pthread_cond_broadcast().\n");
1568 : os_abort();
1569 : /* LCOV_EXCL_STOP */
1570 : }
- 1571 255449 : }
+ 1571 255625 : }
1572 :
- 1573 1095193 : void thread_cond_wait(pthread_cond_t* cond, pthread_mutex_t* mutex)
+ 1573 1095059 : void thread_cond_wait(pthread_cond_t* cond, pthread_mutex_t* mutex)
1574 : {
- 1575 1095193 : if (pthread_cond_wait(cond, mutex) != 0) {
+ 1575 1095059 : if (pthread_cond_wait(cond, mutex) != 0) {
1576 : /* LCOV_EXCL_START */
1577 : log_fatal("Failed call to pthread_cond_wait().\n");
1578 : os_abort();
1579 : /* LCOV_EXCL_STOP */
1580 : }
- 1581 1095193 : }
+ 1581 1095059 : }
1582 :
1583 : /**
1584 : * Implementation note about conditional variables.
@@ -1671,39 +1671,39 @@
1609 : */
1610 : int thread_cond_signal_outside = 0;
1611 :
- 1612 84548 : void thread_cond_signal_and_unlock(pthread_cond_t* cond, pthread_mutex_t* mutex)
+ 1612 83165 : void thread_cond_signal_and_unlock(pthread_cond_t* cond, pthread_mutex_t* mutex)
1613 : {
- 1614 84548 : if (thread_cond_signal_outside) {
+ 1614 83165 : if (thread_cond_signal_outside) {
1615 : /* without the thread checker unlock before signaling, */
1616 : /* this reduces the number of context switches */
1617 0 : thread_mutex_unlock(mutex);
1618 : }
1619 :
- 1620 84548 : thread_cond_signal(cond);
+ 1620 83165 : thread_cond_signal(cond);
1621 :
- 1622 84548 : if (!thread_cond_signal_outside) {
+ 1622 83165 : if (!thread_cond_signal_outside) {
1623 : /* with the thread checker unlock after signaling */
1624 : /* to make explicit the condition and mutex relation */
- 1625 84548 : thread_mutex_unlock(mutex);
+ 1625 83165 : thread_mutex_unlock(mutex);
1626 : }
- 1627 84548 : }
+ 1627 83165 : }
1628 :
- 1629 255259 : void thread_cond_broadcast_and_unlock(pthread_cond_t* cond, pthread_mutex_t* mutex)
+ 1629 255435 : void thread_cond_broadcast_and_unlock(pthread_cond_t* cond, pthread_mutex_t* mutex)
1630 : {
- 1631 255259 : if (thread_cond_signal_outside) {
+ 1631 255435 : if (thread_cond_signal_outside) {
1632 : /* without the thread checker unlock before signaling, */
1633 : /* this reduces the number of context switches */
1634 0 : thread_mutex_unlock(mutex);
1635 : }
1636 :
- 1637 255259 : thread_cond_broadcast(cond);
+ 1637 255435 : thread_cond_broadcast(cond);
1638 :
- 1639 255259 : if (!thread_cond_signal_outside) {
+ 1639 255435 : if (!thread_cond_signal_outside) {
1640 : /* with the thread checker unlock after signaling */
1641 : /* to make explicit the condition and mutex relation */
- 1642 255259 : thread_mutex_unlock(mutex);
+ 1642 255435 : thread_mutex_unlock(mutex);
1643 : }
- 1644 255259 : }
+ 1644 255435 : }
1645 :
1646 2200 : void thread_create(pthread_t* thread, pthread_attr_t* attr, void *(* func)(void *), void *arg)
1647 : {
diff --git a/cov/cmdline/support.h.func-sort-c.html b/cov/cmdline/support.h.func-sort-c.html
index 67aa7b3e..cc007315 100644
--- a/cov/cmdline/support.h.func-sort-c.html
+++ b/cov/cmdline/support.h.func-sort-c.html
@@ -61,7 +61,7 @@
| esc_shell |
- 331952 |
+ 332023 |
diff --git a/cov/cmdline/support.h.func.html b/cov/cmdline/support.h.func.html
index c53895e0..64a447e5 100644
--- a/cov/cmdline/support.h.func.html
+++ b/cov/cmdline/support.h.func.html
@@ -61,7 +61,7 @@
| esc_shell |
- 331952 |
+ 332023 |
diff --git a/cov/cmdline/support.h.gcov.html b/cov/cmdline/support.h.gcov.html
index ba314b1d..b31be071 100644
--- a/cov/cmdline/support.h.gcov.html
+++ b/cov/cmdline/support.h.gcov.html
@@ -291,9 +291,9 @@
229 : * \param buffer Preallocated buffer of ESC_MAX size.
230 : */
231 : const char* esc_shell_multi(const char** str_map, unsigned str_max, char* buffer);
- 232 331952 : static inline const char* esc_shell(const char* str, char* buffer)
+ 232 332023 : static inline const char* esc_shell(const char* str, char* buffer)
233 : {
- 234 331952 : return esc_shell_multi(&str, 1, buffer);
+ 234 332023 : return esc_shell_multi(&str, 1, buffer);
235 : }
236 :
237 : /**
diff --git a/cov/cmdline/sync.c.func-sort-c.html b/cov/cmdline/sync.c.func-sort-c.html
index acebb02b..c9708a58 100644
--- a/cov/cmdline/sync.c.func-sort-c.html
+++ b/cov/cmdline/sync.c.func-sort-c.html
@@ -32,8 +32,8 @@
|
-
-
+
+
@@ -65,18 +65,18 @@
| sync_data_reader |
- 688117 |
+ 688658 |
| sync_parity_writer |
- 544283 |
+ 544725 |
| failed_compare_by_index |
852 |
- | state_sync |
+ state_sync |
87 |
diff --git a/cov/cmdline/sync.c.func.html b/cov/cmdline/sync.c.func.html
index be0b406f..78e40ea7 100644
--- a/cov/cmdline/sync.c.func.html
+++ b/cov/cmdline/sync.c.func.html
@@ -32,8 +32,8 @@
|
-
-
+
+
@@ -72,7 +72,7 @@
| 7 |
- | state_sync |
+ state_sync |
87 |
@@ -81,11 +81,11 @@
| sync_data_reader |
- 688117 |
+ 688658 |
| sync_parity_writer |
- 544283 |
+ 544725 |
diff --git a/cov/cmdline/sync.c.gcov.html b/cov/cmdline/sync.c.gcov.html
index e35cac7e..2387de92 100644
--- a/cov/cmdline/sync.c.gcov.html
+++ b/cov/cmdline/sync.c.gcov.html
@@ -32,8 +32,8 @@
|
-
-
+
+
@@ -483,9 +483,9 @@
421 852 : const struct failed_struct* b = void_b;
422 :
423 852 : if (a->index < b->index)
- 424 852 : return -1;
- 425 0 : if (a->index > b->index)
- 426 0 : return 1;
+ 424 850 : return -1;
+ 425 2 : if (a->index > b->index)
+ 426 2 : return 1;
427 0 : return 0;
428 : }
429 :
@@ -524,56 +524,56 @@
462 4688742 : one_valid = 1;
463 :
464 4911646 : if (block_has_invalid_parity(block) || plan->force_full)
- 465 753140 : one_invalid = 1;
+ 465 753392 : one_invalid = 1;
466 : }
467 :
468 : /* if none valid or none invalid, we don't need to update */
469 820170 : if (!one_invalid || !one_valid)
- 470 590766 : return 0;
+ 470 590590 : return 0;
471 :
- 472 229404 : return 1;
+ 472 229580 : return 1;
473 : }
474 :
- 475 688117 : static void sync_data_reader(struct snapraid_worker* worker, struct snapraid_task* task)
+ 475 688658 : static void sync_data_reader(struct snapraid_worker* worker, struct snapraid_task* task)
476 : {
- 477 688117 : struct snapraid_io* io = worker->io;
- 478 688117 : struct snapraid_state* state = io->state;
- 479 688117 : struct snapraid_handle* handle = worker->handle;
- 480 688117 : struct snapraid_disk* disk = handle->disk;
- 481 688117 : block_off_t blockcur = task->position;
- 482 688117 : unsigned char* buffer = task->buffer;
+ 477 688658 : struct snapraid_io* io = worker->io;
+ 478 688658 : struct snapraid_state* state = io->state;
+ 479 688658 : struct snapraid_handle* handle = worker->handle;
+ 480 688658 : struct snapraid_disk* disk = handle->disk;
+ 481 688658 : block_off_t blockcur = task->position;
+ 482 688658 : unsigned char* buffer = task->buffer;
483 : int ret;
484 : char esc_buffer[ESC_MAX];
485 :
486 : /* if the disk position is not used */
- 487 688117 : if (!disk) {
+ 487 688658 : if (!disk) {
488 : /* use an empty block */
- 489 1 : memset(buffer, 0, state->block_size);
- 490 1 : task->state = TASK_STATE_DONE;
- 491 92173 : return;
+ 489 0 : memset(buffer, 0, state->block_size);
+ 490 0 : task->state = TASK_STATE_DONE;
+ 491 92152 : return;
492 : }
493 :
494 : /* get the block */
- 495 688116 : task->block = fs_par2block_find(disk, blockcur);
+ 495 688660 : task->block = fs_par2block_find(disk, blockcur);
496 :
497 : /* if the block has no file, meaning that it's EMPTY or DELETED, */
498 : /* it doesn't participate in the new parity computation */
- 499 688081 : if (!block_has_file(task->block)) {
+ 499 688584 : if (!block_has_file(task->block)) {
500 : /* use an empty block */
- 501 92153 : memset(buffer, 0, state->block_size);
- 502 92153 : task->state = TASK_STATE_DONE;
- 503 92153 : return;
+ 501 92138 : memset(buffer, 0, state->block_size);
+ 502 92138 : task->state = TASK_STATE_DONE;
+ 503 92138 : return;
504 : }
505 :
506 : /* get the file of this block */
- 507 595895 : task->file = fs_par2file_get(disk, blockcur, &task->file_pos);
+ 507 596414 : task->file = fs_par2file_get(disk, blockcur, &task->file_pos);
508 :
509 : /* if the file is different than the current one, close it */
- 510 595951 : if (handle->file != 0 && handle->file != task->file) {
+ 510 596497 : if (handle->file != 0 && handle->file != task->file) {
511 : /* keep a pointer at the file we are going to close for error reporting */
- 512 245994 : struct snapraid_file* report = handle->file;
- 513 245994 : ret = handle_close(handle);
- 514 245950 : if (ret == -1) {
+ 512 246140 : struct snapraid_file* report = handle->file;
+ 513 246140 : ret = handle_close(handle);
+ 514 246086 : if (ret == -1) {
515 : /* LCOV_EXCL_START */
516 : /* This one is really an unexpected error, because we are only reading */
517 : /* and closing a descriptor should never fail */
@@ -596,8 +596,8 @@
534 : }
535 : }
536 :
- 537 595907 : ret = handle_open(handle, task->file, state->file_mode, log_error, 0);
- 538 595847 : if (ret == -1) {
+ 537 596443 : ret = handle_open(handle, task->file, state->file_mode, log_error, 0);
+ 538 596385 : if (ret == -1) {
539 12 : if (errno == EIO) {
540 : /* LCOV_EXCL_START */
541 : log_tag("error:%u:%s:%s: Open EIO error. %s\n", blockcur, disk->name, esc_tag(task->file->sub, esc_buffer), strerror(errno));
@@ -641,12 +641,12 @@
579 : }
580 :
581 : /* check if the file is changed */
- 582 595835 : if (handle->st.st_size != task->file->size
- 583 595862 : || handle->st.st_mtime != task->file->mtime_sec
- 584 595897 : || STAT_NSEC(&handle->st) != task->file->mtime_nsec
- 585 595892 : || handle->st.st_ino != task->file->inode
+ 582 596373 : if (handle->st.st_size != task->file->size
+ 583 596414 : || handle->st.st_mtime != task->file->mtime_sec
+ 584 596446 : || STAT_NSEC(&handle->st) != task->file->mtime_nsec
+ 585 596437 : || handle->st.st_ino != task->file->inode
586 : ) {
- 587 66 : log_tag("error:%u:%s:%s: Unexpected attribute change\n", blockcur, disk->name, esc_tag(task->file->sub, esc_buffer));
+ 587 50 : log_tag("error:%u:%s:%s: Unexpected attribute change\n", blockcur, disk->name, esc_tag(task->file->sub, esc_buffer));
588 6 : if (handle->st.st_size != task->file->size) {
589 2 : log_error("Unexpected size change at file '%s' from %" PRIu64 " to %" PRIu64 ".\n", handle->path, task->file->size, handle->st.st_size);
590 4 : } else if (handle->st.st_mtime != task->file->mtime_sec
@@ -663,8 +663,8 @@
601 6 : return;
602 : }
603 :
- 604 595769 : task->read_size = handle_read(handle, task->file_pos, buffer, state->block_size, log_error, 0);
- 605 595561 : if (task->read_size == -1) {
+ 604 596323 : task->read_size = handle_read(handle, task->file_pos, buffer, state->block_size, log_error, 0);
+ 605 596119 : if (task->read_size == -1) {
606 : /* LCOV_EXCL_START */
607 : if (errno == EIO) {
608 : log_tag("error:%u:%s:%s: Read EIO error at position %u. %s\n", blockcur, disk->name, esc_tag(task->file->sub, esc_buffer), task->file_pos, strerror(errno));
@@ -683,24 +683,24 @@
621 : }
622 :
623 : /* store the path of the opened file */
- 624 595561 : pathcpy(task->path, sizeof(task->path), handle->path);
+ 624 596119 : pathcpy(task->path, sizeof(task->path), handle->path);
625 :
- 626 595834 : task->state = TASK_STATE_DONE;
+ 626 596393 : task->state = TASK_STATE_DONE;
627 : }
628 :
- 629 544283 : static void sync_parity_writer(struct snapraid_worker* worker, struct snapraid_task* task)
+ 629 544725 : static void sync_parity_writer(struct snapraid_worker* worker, struct snapraid_task* task)
630 : {
- 631 544283 : struct snapraid_io* io = worker->io;
- 632 544283 : struct snapraid_state* state = io->state;
- 633 544283 : struct snapraid_parity_handle* parity_handle = worker->parity_handle;
- 634 544283 : unsigned level = parity_handle->level;
- 635 544283 : block_off_t blockcur = task->position;
- 636 544283 : unsigned char* buffer = task->buffer;
+ 631 544725 : struct snapraid_io* io = worker->io;
+ 632 544725 : struct snapraid_state* state = io->state;
+ 633 544725 : struct snapraid_parity_handle* parity_handle = worker->parity_handle;
+ 634 544725 : unsigned level = parity_handle->level;
+ 635 544725 : block_off_t blockcur = task->position;
+ 636 544725 : unsigned char* buffer = task->buffer;
637 : int ret;
638 :
639 : /* write parity */
- 640 544283 : ret = parity_write(parity_handle, blockcur, buffer, state->block_size);
- 641 544291 : if (ret == -1) {
+ 640 544725 : ret = parity_write(parity_handle, blockcur, buffer, state->block_size);
+ 641 544729 : if (ret == -1) {
642 : /* LCOV_EXCL_START */
643 : if (errno == EIO) {
644 : log_tag("parity_error:%u:%s: Write EIO error. %s\n", blockcur, lev_config_name(level), strerror(errno));
@@ -718,7 +718,7 @@
656 : /* LCOV_EXCL_STOP */
657 : }
658 :
- 659 544291 : task->state = TASK_STATE_DONE;
+ 659 544729 : task->state = TASK_STATE_DONE;
660 : }
661 :
662 83 : static int state_sync_process(struct snapraid_state* state, struct snapraid_parity_handle* parity_handle, block_off_t blockstart, block_off_t blockmax)
@@ -799,8 +799,8 @@
737 83 : plan.force_full = state->opt.force_full;
738 410168 : for (blockcur = blockstart; blockcur < blockmax; ++blockcur) {
739 410085 : if (!block_is_enabled(&plan, blockcur))
- 740 295383 : continue;
- 741 114702 : ++countmax;
+ 740 295295 : continue;
+ 741 114790 : ++countmax;
742 : }
743 :
744 : /* compute the autosave size for all disk, even if not read */
@@ -836,31 +836,31 @@
774 : int writer_error[IO_WRITER_ERROR_MAX];
775 :
776 : /* go to the next block */
- 777 114785 : blockcur = io_read_next(&io, &buffer);
- 778 114785 : if (blockcur >= blockmax)
+ 777 114873 : blockcur = io_read_next(&io, &buffer);
+ 778 114873 : if (blockcur >= blockmax)
779 166 : break;
780 :
781 : /* until now is scheduling */
- 782 114702 : state_usage_sched(state);
+ 782 114790 : state_usage_sched(state);
783 :
784 : /* one more block processed for autosave */
- 785 114702 : ++autosavedone;
- 786 114702 : --autosavemissing;
+ 785 114790 : ++autosavedone;
+ 786 114790 : --autosavemissing;
787 :
788 : /* by default process the block, and skip it if something goes wrong */
- 789 114702 : error_on_this_block = 0;
- 790 114702 : silent_error_on_this_block = 0;
- 791 114702 : io_error_on_this_block = 0;
- 792 114702 : fixed_error_on_this_block = 0;
+ 789 114790 : error_on_this_block = 0;
+ 790 114790 : silent_error_on_this_block = 0;
+ 791 114790 : io_error_on_this_block = 0;
+ 792 114790 : fixed_error_on_this_block = 0;
793 :
794 : /* keep track of the number of failed blocks */
- 795 114702 : failed_count = 0;
+ 795 114790 : failed_count = 0;
796 :
797 : /* get block specific info */
- 798 114702 : info = info_get(&state->infoarr, blockcur);
+ 798 114790 : info = info_get(&state->infoarr, blockcur);
799 :
800 : /* if we have to use the old hash */
- 801 114702 : rehash = info_get_rehash(info);
+ 801 114790 : rehash = info_get_rehash(info);
802 :
803 : /* if the parity requires to be updated */
804 : /* It could happens that all the blocks are EMPTY/BLK and CHG but with the hash */
@@ -869,18 +869,18 @@
807 : /* Note that CHG/DELETED blocks already present in the content file loaded */
808 : /* have the hash cleared (::clear_past_hash flag), and then they won't never match the hash. */
809 : /* We are treating only CHG blocks created at runtime. */
- 810 114702 : parity_needs_to_be_updated = state->opt.force_full || state->opt.force_parity_update;
+ 810 114790 : parity_needs_to_be_updated = state->opt.force_full || state->opt.force_parity_update;
811 :
812 : /* if the parity is going to be updated */
- 813 114702 : parity_going_to_be_updated = 0;
+ 813 114790 : parity_going_to_be_updated = 0;
814 :
815 : /* if the block is marked as bad, we force the parity update */
816 : /* because the bad block may be the result of a wrong parity */
- 817 114702 : if (info_get_bad(info))
+ 817 114790 : if (info_get_bad(info))
818 0 : parity_needs_to_be_updated = 1;
819 :
820 : /* for each disk, process the block */
- 821 802914 : for (j = 0; j < diskmax; ++j) {
+ 821 803530 : for (j = 0; j < diskmax; ++j) {
822 : struct snapraid_task* task;
823 : int read_size;
824 : unsigned char hash[HASH_MAX];
@@ -892,45 +892,45 @@
830 : unsigned diskcur;
831 :
832 : /* until now is misc */
- 833 688212 : state_usage_misc(state);
+ 833 688740 : state_usage_misc(state);
834 :
- 835 688212 : task = io_data_read(&io, &diskcur, waiting_map, &waiting_mac);
+ 835 688740 : task = io_data_read(&io, &diskcur, waiting_map, &waiting_mac);
836 :
837 : /* until now is disk */
- 838 688212 : state_usage_disk(state, handle, waiting_map, waiting_mac);
+ 838 688740 : state_usage_disk(state, handle, waiting_map, waiting_mac);
839 :
840 : /* get the results */
- 841 688212 : disk = task->disk;
- 842 688212 : block = task->block;
- 843 688212 : file = task->file;
- 844 688212 : file_pos = task->file_pos;
- 845 688212 : read_size = task->read_size;
+ 841 688740 : disk = task->disk;
+ 842 688740 : block = task->block;
+ 843 688740 : file = task->file;
+ 844 688740 : file_pos = task->file_pos;
+ 845 688740 : read_size = task->read_size;
846 :
847 : /* by default no rehash in case of "continue" */
- 848 688212 : rehandle[diskcur].block = 0;
+ 848 688740 : rehandle[diskcur].block = 0;
849 :
850 : /* if the disk position is not used */
- 851 688212 : if (!disk)
- 852 93057 : continue;
+ 851 688740 : if (!disk)
+ 852 93036 : continue;
853 :
854 : /* get the state of the block */
- 855 688212 : block_state = block_state_get(block);
+ 855 688740 : block_state = block_state_get(block);
856 :
857 : /* if the block has invalid parity, */
858 : /* we have to take care of it in case of recover */
- 859 688212 : if (block_has_invalid_parity(block)) {
+ 859 688740 : if (block_has_invalid_parity(block)) {
860 : /* store it in the failed set, because */
861 : /* the parity may be still computed with the previous content */
- 862 182772 : failed[failed_count].index = diskcur;
- 863 182772 : failed[failed_count].size = state->block_size;
- 864 182772 : failed[failed_count].block = block;
- 865 182772 : ++failed_count;
+ 862 182898 : failed[failed_count].index = diskcur;
+ 863 182898 : failed[failed_count].size = state->block_size;
+ 864 182898 : failed[failed_count].block = block;
+ 865 182898 : ++failed_count;
866 :
867 : /* if the block has invalid parity, we have to update the parity */
868 : /* to include this block change */
869 : /* This also apply to CHG blocks, but we are going to handle */
870 : /* later this case to do the updates only if really needed */
- 871 182772 : if (block_state != BLOCK_STATE_CHG)
+ 871 182898 : if (block_state != BLOCK_STATE_CHG)
872 88225 : parity_needs_to_be_updated = 1;
873 :
874 : /* note that DELETE blocks are skipped in the next check */
@@ -941,719 +941,731 @@
879 : }
880 :
881 : /* if the block is not used */
- 882 688212 : if (!block_has_file(block))
- 883 92186 : continue;
+ 882 688740 : if (!block_has_file(block))
+ 883 92165 : continue;
884 :
885 : /* handle error conditions */
- 886 596026 : if (task->state == TASK_STATE_IOERROR) {
- 887 0 : ++io_error;
- 888 0 : goto bail;
- 889 : }
- 890 596026 : if (task->state == TASK_STATE_ERROR) {
- 891 0 : ++error;
- 892 0 : goto bail;
- 893 : }
- 894 596026 : if (task->state == TASK_STATE_ERROR_CONTINUE) {
- 895 18 : ++error;
- 896 18 : error_on_this_block = 1;
- 897 18 : continue;
- 898 : }
- 899 596008 : if (task->state == TASK_STATE_IOERROR_CONTINUE) {
- 900 0 : ++io_error;
- 901 0 : if (io_error >= state->opt.io_error_limit) {
- 902 0 : log_fatal("DANGER! Unexpected input/output read error in a data disk, it isn't possible to sync.\n");
- 903 0 : log_fatal("Ensure that disk '%s' is sane and that file '%s' can be read.\n", disk->dir, task->path);
- 904 0 : log_fatal("Stopping at block %u\n", blockcur);
- 905 0 : goto bail;
- 906 : }
- 907 :
- 908 : /* otherwise continue */
- 909 0 : io_error_on_this_block = 1;
- 910 0 : continue;
- 911 : }
- 912 596008 : if (task->state != TASK_STATE_DONE) {
- 913 : /* LCOV_EXCL_START */
- 914 : log_fatal("Internal inconsistency in task state\n");
- 915 : os_abort();
- 916 : /* LCOV_EXCL_STOP */
+ 886 596575 : if (task->state == TASK_STATE_IOERROR) {
+ 887 : /* LCOV_EXCL_START */
+ 888 : ++io_error;
+ 889 : goto bail;
+ 890 : /* LCOV_EXCL_STOP */
+ 891 : }
+ 892 596575 : if (task->state == TASK_STATE_ERROR) {
+ 893 : /* LCOV_EXCL_START */
+ 894 : ++error;
+ 895 : goto bail;
+ 896 : /* LCOV_EXCL_STOP */
+ 897 : }
+ 898 596575 : if (task->state == TASK_STATE_ERROR_CONTINUE) {
+ 899 18 : ++error;
+ 900 18 : error_on_this_block = 1;
+ 901 18 : continue;
+ 902 : }
+ 903 596557 : if (task->state == TASK_STATE_IOERROR_CONTINUE) {
+ 904 0 : ++io_error;
+ 905 0 : if (io_error >= state->opt.io_error_limit) {
+ 906 : /* LCOV_EXCL_START */
+ 907 : log_fatal("DANGER! Unexpected input/output read error in a data disk, it isn't possible to sync.\n");
+ 908 : log_fatal("Ensure that disk '%s' is sane and that file '%s' can be read.\n", disk->dir, task->path);
+ 909 : log_fatal("Stopping at block %u\n", blockcur);
+ 910 : goto bail;
+ 911 : /* LCOV_EXCL_STOP */
+ 912 : }
+ 913 :
+ 914 : /* otherwise continue */
+ 915 0 : io_error_on_this_block = 1;
+ 916 0 : continue;
917 : }
- 918 :
- 919 596008 : countsize += read_size;
- 920 :
- 921 : /* now compute the hash */
- 922 596008 : if (rehash) {
- 923 27243 : memhash(state->prevhash, state->prevhashseed, hash, buffer[diskcur], read_size);
+ 918 596557 : if (task->state != TASK_STATE_DONE) {
+ 919 : /* LCOV_EXCL_START */
+ 920 : log_fatal("Internal inconsistency in task state\n");
+ 921 : os_abort();
+ 922 : /* LCOV_EXCL_STOP */
+ 923 : }
924 :
- 925 : /* compute the new hash, and store it */
- 926 27243 : rehandle[diskcur].block = block;
- 927 27243 : memhash(state->hash, state->hashseed, rehandle[diskcur].hash, buffer[diskcur], read_size);
- 928 : } else {
- 929 568765 : memhash(state->hash, state->hashseed, hash, buffer[diskcur], read_size);
- 930 : }
- 931 :
- 932 : /* until now is hash */
- 933 596008 : state_usage_hash(state);
- 934 :
- 935 596008 : if (block_has_updated_hash(block)) {
- 936 : /* compare the hash */
- 937 501479 : if (memcmp(hash, block->hash, BLOCK_HASH_SIZE) != 0) {
- 938 : /* if the file has invalid parity, it's a REP changed during the sync */
- 939 853 : if (block_has_invalid_parity(block)) {
- 940 1 : log_tag("error:%u:%s:%s: Unexpected data change\n", blockcur, disk->name, esc_tag(file->sub, esc_buffer));
- 941 1 : log_error("Data change at file '%s' at position '%u'\n", task->path, file_pos);
- 942 1 : log_error("WARNING! Unexpected data modification of a file without parity!\n");
- 943 :
- 944 1 : if (file_flag_has(file, FILE_IS_COPY)) {
- 945 0 : log_error("This file was detected as a copy of another file with the same name, size,\n");
- 946 0 : log_error("and timestamp, but the file data isn't matching the assumed copy.\n");
- 947 0 : log_error("If this is a false positive, and the files are expected to be different,\n");
- 948 0 : log_error("you can 'sync' anyway using 'snapraid --force-nocopy sync'\n");
- 949 : } else {
- 950 1 : log_error("Try removing the file from the array and rerun the 'sync' command!\n");
- 951 : }
- 952 :
- 953 1 : ++error;
- 954 :
- 955 : /* if the file is changed, it means that it was modified during sync */
- 956 : /* this isn't a serious error, so we skip this block, and continue with others */
- 957 1 : error_on_this_block = 1;
- 958 1 : continue;
- 959 : } else { /* otherwise it's a BLK with silent error */
- 960 852 : unsigned diff = memdiff(hash, block->hash, BLOCK_HASH_SIZE);
- 961 852 : log_tag("error:%u:%s:%s: Data error at position %u, diff bits %u\n", blockcur, disk->name, esc_tag(file->sub, esc_buffer), file_pos, diff);
- 962 852 : log_error("Data error in file '%s' at position '%u', diff bits %u\n", task->path, file_pos, diff);
- 963 :
- 964 : /* save the failed block for the fix */
- 965 852 : failed[failed_count].index = diskcur;
- 966 852 : failed[failed_count].size = read_size;
- 967 852 : failed[failed_count].block = block;
- 968 852 : ++failed_count;
+ 925 596557 : countsize += read_size;
+ 926 :
+ 927 : /* now compute the hash */
+ 928 596557 : if (rehash) {
+ 929 27243 : memhash(state->prevhash, state->prevhashseed, hash, buffer[diskcur], read_size);
+ 930 :
+ 931 : /* compute the new hash, and store it */
+ 932 27243 : rehandle[diskcur].block = block;
+ 933 27243 : memhash(state->hash, state->hashseed, rehandle[diskcur].hash, buffer[diskcur], read_size);
+ 934 : } else {
+ 935 569314 : memhash(state->hash, state->hashseed, hash, buffer[diskcur], read_size);
+ 936 : }
+ 937 :
+ 938 : /* until now is hash */
+ 939 596557 : state_usage_hash(state);
+ 940 :
+ 941 596557 : if (block_has_updated_hash(block)) {
+ 942 : /* compare the hash */
+ 943 501902 : if (memcmp(hash, block->hash, BLOCK_HASH_SIZE) != 0) {
+ 944 : /* if the file has invalid parity, it's a REP changed during the sync */
+ 945 853 : if (block_has_invalid_parity(block)) {
+ 946 1 : log_tag("error:%u:%s:%s: Unexpected data change\n", blockcur, disk->name, esc_tag(file->sub, esc_buffer));
+ 947 1 : log_error("Data change at file '%s' at position '%u'\n", task->path, file_pos);
+ 948 1 : log_error("WARNING! Unexpected data modification of a file without parity!\n");
+ 949 :
+ 950 1 : if (file_flag_has(file, FILE_IS_COPY)) {
+ 951 0 : log_error("This file was detected as a copy of another file with the same name, size,\n");
+ 952 0 : log_error("and timestamp, but the file data isn't matching the assumed copy.\n");
+ 953 0 : log_error("If this is a false positive, and the files are expected to be different,\n");
+ 954 0 : log_error("you can 'sync' anyway using 'snapraid --force-nocopy sync'\n");
+ 955 : } else {
+ 956 1 : log_error("Try removing the file from the array and rerun the 'sync' command!\n");
+ 957 : }
+ 958 :
+ 959 1 : ++error;
+ 960 :
+ 961 : /* if the file is changed, it means that it was modified during sync */
+ 962 : /* this isn't a serious error, so we skip this block, and continue with others */
+ 963 1 : error_on_this_block = 1;
+ 964 1 : continue;
+ 965 : } else { /* otherwise it's a BLK with silent error */
+ 966 852 : unsigned diff = memdiff(hash, block->hash, BLOCK_HASH_SIZE);
+ 967 852 : log_tag("error:%u:%s:%s: Data error at position %u, diff bits %u\n", blockcur, disk->name, esc_tag(file->sub, esc_buffer), file_pos, diff);
+ 968 852 : log_error("Data error in file '%s' at position '%u', diff bits %u\n", task->path, file_pos, diff);
969 :
- 970 : /* silent errors are very rare, and are not a signal that a disk */
- 971 : /* is going to fail. So, we just continue marking the block as bad */
- 972 : /* just like in scrub */
- 973 852 : ++silent_error;
- 974 852 : silent_error_on_this_block = 1;
- 975 852 : continue;
- 976 : }
- 977 : }
- 978 : } else {
- 979 : /* if until now the parity doesn't need to be updated */
- 980 94529 : if (!parity_needs_to_be_updated) {
- 981 : /* for sure it's a CHG block, because EMPTY are processed before with "continue" */
- 982 : /* and BLK and REP have "block_has_updated_hash()" as 1, and all the others */
- 983 : /* have "parity_needs_to_be_updated" already at 1 */
- 984 35175 : assert(block_state_get(block) == BLOCK_STATE_CHG);
- 985 :
- 986 : /* if the hash represents the data unequivocally */
- 987 35175 : if (hash_is_unique(block->hash)) {
- 988 : /* check if the hash is changed */
- 989 8502 : if (memcmp(hash, block->hash, BLOCK_HASH_SIZE) != 0) {
- 990 : /* the block is different, and we must update parity */
- 991 6003 : parity_needs_to_be_updated = 1;
- 992 : }
- 993 : } else {
- 994 : /* if the hash is already invalid, we update parity */
- 995 26673 : parity_needs_to_be_updated = 1;
- 996 : }
- 997 : }
- 998 :
- 999 : /* copy the hash in the block, but doesn't mark the block as hashed */
- 1000 : /* this allow in case of skipped block to do not save the failed computation */
- 1001 94529 : memcpy(block->hash, hash, BLOCK_HASH_SIZE);
- 1002 :
- 1003 : /* note that in case of rehash, this is the wrong hash, */
- 1004 : /* but it will be overwritten later */
- 1005 : }
- 1006 : }
- 1007 :
- 1008 : /* if we have only silent errors we can try to fix them on-the-fly */
- 1009 : /* note the the fix is not written to disk, but used only to */
- 1010 : /* compute the new parity */
- 1011 114702 : if (!error_on_this_block && !io_error_on_this_block && silent_error_on_this_block) {
- 1012 : unsigned failed_mac;
- 1013 852 : int something_to_recover = 0;
- 1014 :
- 1015 : /* sort the failed vector */
- 1016 : /* because with threads it may be in any order */
- 1017 : /* but RAID requires the indexes to be sorted */
- 1018 852 : qsort(failed, failed_count, sizeof(failed[0]), failed_compare_by_index);
- 1019 :
- 1020 : /* setup the blocks to recover */
- 1021 852 : failed_mac = 0;
- 1022 2556 : for (j = 0; j < failed_count; ++j) {
- 1023 1704 : unsigned char* block_buffer = buffer[failed[j].index];
- 1024 1704 : unsigned char* block_copy = copy[failed[j].index];
- 1025 1704 : unsigned block_state = block_state_get(failed[j].block);
- 1026 :
- 1027 : /* we try to recover only if at least one BLK is present */
- 1028 1704 : if (block_state == BLOCK_STATE_BLK)
- 1029 852 : something_to_recover = 1;
- 1030 :
- 1031 : /* save a copy of the content just read */
- 1032 : /* that it's going to be overwritten by the recovering function */
- 1033 1704 : memcpy(block_copy, block_buffer, state->block_size);
- 1034 :
- 1035 1704 : if (block_state == BLOCK_STATE_CHG
- 1036 852 : && hash_is_zero(failed[j].block->hash)
- 1037 : ) {
- 1038 : /* if the block was filled with 0, restore this state */
- 1039 : /* and avoid to recover it */
- 1040 0 : memset(block_buffer, 0, state->block_size);
- 1041 : } else {
- 1042 : /* if we have too many failures, we cannot recover */
- 1043 1704 : if (failed_mac >= state->level)
- 1044 0 : break;
- 1045 :
- 1046 : /* otherwise it has to be recovered */
- 1047 1704 : failed_map[failed_mac++] = failed[j].index;
- 1048 : }
- 1049 : }
- 1050 :
- 1051 : /* if we have something to recover and enough parity */
- 1052 852 : if (something_to_recover && j == failed_count) {
- 1053 : /* until now is misc */
- 1054 852 : state_usage_misc(state);
- 1055 :
- 1056 : /* read the parity */
- 1057 : /* we are sure that parity exists because */
- 1058 : /* we have at least one BLK block */
- 1059 5964 : for (l = 0; l < state->level; ++l) {
- 1060 5112 : ret = parity_read(&parity_handle[l], blockcur, buffer[diskmax + l], state->block_size, log_error);
- 1061 5112 : if (ret == -1) {
- 1062 : /* LCOV_EXCL_START */
- 1063 : if (errno == EIO) {
- 1064 : log_tag("parity_error:%u:%s: Read EIO error. %s\n", blockcur, lev_config_name(l), strerror(errno));
- 1065 : if (io_error >= state->opt.io_error_limit) {
- 1066 : log_fatal("DANGER! Unexpected input/output read error in the %s disk, it isn't possible to sync.\n", lev_name(l));
- 1067 : log_fatal("Ensure that disk '%s' is sane and can be read.\n", lev_config_name(l));
- 1068 : log_fatal("Stopping at block %u\n", blockcur);
- 1069 : ++io_error;
- 1070 : goto bail;
- 1071 : }
- 1072 :
- 1073 : log_error("Input/Output error in parity '%s' at position '%u'\n", lev_config_name(l), blockcur);
- 1074 : ++io_error;
- 1075 : io_error_on_this_block = 1;
- 1076 : continue;
- 1077 : }
+ 970 : /* save the failed block for the fix */
+ 971 852 : failed[failed_count].index = diskcur;
+ 972 852 : failed[failed_count].size = read_size;
+ 973 852 : failed[failed_count].block = block;
+ 974 852 : ++failed_count;
+ 975 :
+ 976 : /* silent errors are very rare, and are not a signal that a disk */
+ 977 : /* is going to fail. So, we just continue marking the block as bad */
+ 978 : /* just like in scrub */
+ 979 852 : ++silent_error;
+ 980 852 : silent_error_on_this_block = 1;
+ 981 852 : continue;
+ 982 : }
+ 983 : }
+ 984 : } else {
+ 985 : /* if until now the parity doesn't need to be updated */
+ 986 94655 : if (!parity_needs_to_be_updated) {
+ 987 : /* for sure it's a CHG block, because EMPTY are processed before with "continue" */
+ 988 : /* and BLK and REP have "block_has_updated_hash()" as 1, and all the others */
+ 989 : /* have "parity_needs_to_be_updated" already at 1 */
+ 990 35289 : assert(block_state_get(block) == BLOCK_STATE_CHG);
+ 991 :
+ 992 : /* if the hash represents the data unequivocally */
+ 993 35289 : if (hash_is_unique(block->hash)) {
+ 994 : /* check if the hash is changed */
+ 995 8620 : if (memcmp(hash, block->hash, BLOCK_HASH_SIZE) != 0) {
+ 996 : /* the block is different, and we must update parity */
+ 997 6075 : parity_needs_to_be_updated = 1;
+ 998 : }
+ 999 : } else {
+ 1000 : /* if the hash is already invalid, we update parity */
+ 1001 26669 : parity_needs_to_be_updated = 1;
+ 1002 : }
+ 1003 : }
+ 1004 :
+ 1005 : /* copy the hash in the block, but doesn't mark the block as hashed */
+ 1006 : /* this allow in case of skipped block to do not save the failed computation */
+ 1007 94655 : memcpy(block->hash, hash, BLOCK_HASH_SIZE);
+ 1008 :
+ 1009 : /* note that in case of rehash, this is the wrong hash, */
+ 1010 : /* but it will be overwritten later */
+ 1011 : }
+ 1012 : }
+ 1013 :
+ 1014 : /* if we have only silent errors we can try to fix them on-the-fly */
+ 1015 : /* note the the fix is not written to disk, but used only to */
+ 1016 : /* compute the new parity */
+ 1017 114790 : if (!error_on_this_block && !io_error_on_this_block && silent_error_on_this_block) {
+ 1018 : unsigned failed_mac;
+ 1019 852 : int something_to_recover = 0;
+ 1020 :
+ 1021 : /* sort the failed vector */
+ 1022 : /* because with threads it may be in any order */
+ 1023 : /* but RAID requires the indexes to be sorted */
+ 1024 852 : qsort(failed, failed_count, sizeof(failed[0]), failed_compare_by_index);
+ 1025 :
+ 1026 : /* setup the blocks to recover */
+ 1027 852 : failed_mac = 0;
+ 1028 2556 : for (j = 0; j < failed_count; ++j) {
+ 1029 1704 : unsigned char* block_buffer = buffer[failed[j].index];
+ 1030 1704 : unsigned char* block_copy = copy[failed[j].index];
+ 1031 1704 : unsigned block_state = block_state_get(failed[j].block);
+ 1032 :
+ 1033 : /* we try to recover only if at least one BLK is present */
+ 1034 1704 : if (block_state == BLOCK_STATE_BLK)
+ 1035 852 : something_to_recover = 1;
+ 1036 :
+ 1037 : /* save a copy of the content just read */
+ 1038 : /* that it's going to be overwritten by the recovering function */
+ 1039 1704 : memcpy(block_copy, block_buffer, state->block_size);
+ 1040 :
+ 1041 1704 : if (block_state == BLOCK_STATE_CHG
+ 1042 852 : && hash_is_zero(failed[j].block->hash)
+ 1043 : ) {
+ 1044 : /* if the block was filled with 0, restore this state */
+ 1045 : /* and avoid to recover it */
+ 1046 0 : memset(block_buffer, 0, state->block_size);
+ 1047 : } else {
+ 1048 : /* if we have too many failures, we cannot recover */
+ 1049 1704 : if (failed_mac >= state->level)
+ 1050 0 : break;
+ 1051 :
+ 1052 : /* otherwise it has to be recovered */
+ 1053 1704 : failed_map[failed_mac++] = failed[j].index;
+ 1054 : }
+ 1055 : }
+ 1056 :
+ 1057 : /* if we have something to recover and enough parity */
+ 1058 852 : if (something_to_recover && j == failed_count) {
+ 1059 : /* until now is misc */
+ 1060 852 : state_usage_misc(state);
+ 1061 :
+ 1062 : /* read the parity */
+ 1063 : /* we are sure that parity exists because */
+ 1064 : /* we have at least one BLK block */
+ 1065 5964 : for (l = 0; l < state->level; ++l) {
+ 1066 5112 : ret = parity_read(&parity_handle[l], blockcur, buffer[diskmax + l], state->block_size, log_error);
+ 1067 5112 : if (ret == -1) {
+ 1068 : /* LCOV_EXCL_START */
+ 1069 : if (errno == EIO) {
+ 1070 : log_tag("parity_error:%u:%s: Read EIO error. %s\n", blockcur, lev_config_name(l), strerror(errno));
+ 1071 : if (io_error >= state->opt.io_error_limit) {
+ 1072 : log_fatal("DANGER! Unexpected input/output read error in the %s disk, it isn't possible to sync.\n", lev_name(l));
+ 1073 : log_fatal("Ensure that disk '%s' is sane and can be read.\n", lev_config_name(l));
+ 1074 : log_fatal("Stopping at block %u\n", blockcur);
+ 1075 : ++io_error;
+ 1076 : goto bail;
+ 1077 : }
1078 :
- 1079 : log_tag("parity_error:%u:%s: Read error. %s\n", blockcur, lev_config_name(l), strerror(errno));
- 1080 : log_fatal("WARNING! Unexpected read error in the %s disk, it isn't possible to sync.\n", lev_name(l));
- 1081 : log_fatal("Ensure that disk '%s' can be read.\n", lev_config_name(l));
- 1082 : log_fatal("Stopping at block %u\n", blockcur);
- 1083 : ++error;
- 1084 : goto bail;
- 1085 : /* LCOV_EXCL_STOP */
- 1086 : }
- 1087 :
- 1088 : /* until now is parity */
- 1089 5112 : state_usage_parity(state, &l, 1);
- 1090 : }
- 1091 :
- 1092 : /* if no error in parity read */
- 1093 852 : if (!io_error_on_this_block) {
- 1094 : /* try to fix the data */
- 1095 : /* note that this is a simple fix algorithm, that doesn't take into */
- 1096 : /* account the case of a wrong parity */
- 1097 : /* only 'fix' supports the most advanced fixing */
- 1098 852 : raid_rec(failed_mac, failed_map, diskmax, state->level, state->block_size, buffer);
- 1099 :
- 1100 : /* until now is raid */
- 1101 852 : state_usage_raid(state);
- 1102 :
- 1103 : /* check the result and prepare the data */
- 1104 5112 : for (j = 0; j < failed_count; ++j) {
- 1105 : unsigned char hash[HASH_MAX];
- 1106 1704 : unsigned char* block_buffer = buffer[failed[j].index];
- 1107 1704 : unsigned char* block_copy = copy[failed[j].index];
- 1108 1704 : unsigned block_state = block_state_get(failed[j].block);
- 1109 :
- 1110 1704 : if (block_state == BLOCK_STATE_BLK) {
- 1111 852 : unsigned size = failed[j].size;
- 1112 :
- 1113 : /* compute the hash of the recovered block */
- 1114 852 : if (rehash) {
- 1115 0 : memhash(state->prevhash, state->prevhashseed, hash, block_buffer, size);
- 1116 : } else {
- 1117 852 : memhash(state->hash, state->hashseed, hash, block_buffer, size);
- 1118 : }
- 1119 :
- 1120 : /* until now is hash */
- 1121 852 : state_usage_hash(state);
- 1122 :
- 1123 : /* if the hash doesn't match */
- 1124 852 : if (memcmp(hash, failed[j].block->hash, BLOCK_HASH_SIZE) != 0) {
- 1125 : /* we have not recovered */
- 1126 0 : break;
- 1127 : }
+ 1079 : log_error("Input/Output error in parity '%s' at position '%u'\n", lev_config_name(l), blockcur);
+ 1080 : ++io_error;
+ 1081 : io_error_on_this_block = 1;
+ 1082 : continue;
+ 1083 : }
+ 1084 :
+ 1085 : log_tag("parity_error:%u:%s: Read error. %s\n", blockcur, lev_config_name(l), strerror(errno));
+ 1086 : log_fatal("WARNING! Unexpected read error in the %s disk, it isn't possible to sync.\n", lev_name(l));
+ 1087 : log_fatal("Ensure that disk '%s' can be read.\n", lev_config_name(l));
+ 1088 : log_fatal("Stopping at block %u\n", blockcur);
+ 1089 : ++error;
+ 1090 : goto bail;
+ 1091 : /* LCOV_EXCL_STOP */
+ 1092 : }
+ 1093 :
+ 1094 : /* until now is parity */
+ 1095 5112 : state_usage_parity(state, &l, 1);
+ 1096 : }
+ 1097 :
+ 1098 : /* if no error in parity read */
+ 1099 852 : if (!io_error_on_this_block) {
+ 1100 : /* try to fix the data */
+ 1101 : /* note that this is a simple fix algorithm, that doesn't take into */
+ 1102 : /* account the case of a wrong parity */
+ 1103 : /* only 'fix' supports the most advanced fixing */
+ 1104 852 : raid_rec(failed_mac, failed_map, diskmax, state->level, state->block_size, buffer);
+ 1105 :
+ 1106 : /* until now is raid */
+ 1107 852 : state_usage_raid(state);
+ 1108 :
+ 1109 : /* check the result and prepare the data */
+ 1110 5112 : for (j = 0; j < failed_count; ++j) {
+ 1111 : unsigned char hash[HASH_MAX];
+ 1112 1704 : unsigned char* block_buffer = buffer[failed[j].index];
+ 1113 1704 : unsigned char* block_copy = copy[failed[j].index];
+ 1114 1704 : unsigned block_state = block_state_get(failed[j].block);
+ 1115 :
+ 1116 1704 : if (block_state == BLOCK_STATE_BLK) {
+ 1117 852 : unsigned size = failed[j].size;
+ 1118 :
+ 1119 : /* compute the hash of the recovered block */
+ 1120 852 : if (rehash) {
+ 1121 0 : memhash(state->prevhash, state->prevhashseed, hash, block_buffer, size);
+ 1122 : } else {
+ 1123 852 : memhash(state->hash, state->hashseed, hash, block_buffer, size);
+ 1124 : }
+ 1125 :
+ 1126 : /* until now is hash */
+ 1127 852 : state_usage_hash(state);
1128 :
- 1129 : /* pad with 0 if needed */
- 1130 852 : if (size < state->block_size)
- 1131 349 : memset(block_buffer + size, 0, state->block_size - size);
- 1132 : } else {
- 1133 : /* otherwise restore the content */
- 1134 : /* because we are not interested in the old state */
- 1135 : /* that it's recovered for CHG, REP and DELETED blocks */
- 1136 852 : memcpy(block_buffer, block_copy, state->block_size);
- 1137 : }
- 1138 : }
- 1139 :
- 1140 : /* if all is processed, we have fixed it */
- 1141 852 : if (j == failed_count)
- 1142 852 : fixed_error_on_this_block = 1;
- 1143 : }
- 1144 : }
- 1145 : }
- 1146 :
- 1147 : /* if we have read all the data required and it's correct, proceed with the parity */
- 1148 114702 : if (!error_on_this_block && !io_error_on_this_block
- 1149 114683 : && (!silent_error_on_this_block || fixed_error_on_this_block)
- 1150 : ) {
- 1151 : /* update the parity only if really needed */
- 1152 114683 : if (parity_needs_to_be_updated) {
- 1153 : /* compute the parity */
- 1154 112401 : raid_gen(diskmax, state->level, state->block_size, buffer);
- 1155 :
- 1156 : /* until now is raid */
- 1157 112401 : state_usage_raid(state);
- 1158 :
- 1159 : /* mark that the parity is going to be written */
- 1160 112401 : parity_going_to_be_updated = 1;
- 1161 : }
- 1162 :
- 1163 : /* for each disk, mark the blocks as processed */
- 1164 802781 : for (j = 0; j < diskmax; ++j) {
- 1165 : struct snapraid_block* block;
- 1166 :
- 1167 688098 : if (!handle[j].disk)
- 1168 0 : continue;
- 1169 :
- 1170 688098 : block = fs_par2block_find(handle[j].disk, blockcur);
- 1171 :
- 1172 688098 : if (block == BLOCK_NULL) {
- 1173 : /* nothing to do */
- 1174 81231 : continue;
- 1175 : }
- 1176 :
- 1177 : /* if it's a deleted block */
- 1178 606867 : if (block_state_get(block) == BLOCK_STATE_DELETED) {
- 1179 : /* the parity is now updated without this block, so it's now empty */
- 1180 10953 : fs_deallocate(handle[j].disk, blockcur);
- 1181 10953 : continue;
- 1182 : }
- 1183 :
- 1184 : /* now all the blocks have the hash and the parity computed */
- 1185 595914 : block_state_set(block, BLOCK_STATE_BLK);
- 1186 : }
- 1187 :
- 1188 : /* we update the info block only if we really have updated the parity */
- 1189 : /* because otherwise the time/justsynced info would be misleading as we didn't */
- 1190 : /* wrote the parity at this time */
- 1191 : /* we also update the info block only if no silent error was found */
- 1192 : /* because has no sense to refresh the time for data that we know bad */
- 1193 114683 : if (parity_needs_to_be_updated
- 1194 112401 : && !silent_error_on_this_block
- 1195 : ) {
- 1196 : /* if rehash is needed */
- 1197 112055 : if (rehash) {
- 1198 : /* store all the new hash already computed */
- 1199 32249 : for (j = 0; j < diskmax; ++j) {
- 1200 27642 : if (rehandle[j].block)
- 1201 27243 : memcpy(rehandle[j].block->hash, rehandle[j].hash, BLOCK_HASH_SIZE);
- 1202 : }
- 1203 : }
- 1204 :
- 1205 : /* update the time info of the block */
- 1206 : /* we are also clearing any previous bad and rehash flag */
- 1207 112055 : info_set(&state->infoarr, blockcur, info_make(now, 0, 0, 1));
- 1208 : }
- 1209 : }
+ 1129 : /* if the hash doesn't match */
+ 1130 852 : if (memcmp(hash, failed[j].block->hash, BLOCK_HASH_SIZE) != 0) {
+ 1131 : /* we have not recovered */
+ 1132 0 : break;
+ 1133 : }
+ 1134 :
+ 1135 : /* pad with 0 if needed */
+ 1136 852 : if (size < state->block_size)
+ 1137 345 : memset(block_buffer + size, 0, state->block_size - size);
+ 1138 : } else {
+ 1139 : /* otherwise restore the content */
+ 1140 : /* because we are not interested in the old state */
+ 1141 : /* that it's recovered for CHG, REP and DELETED blocks */
+ 1142 852 : memcpy(block_buffer, block_copy, state->block_size);
+ 1143 : }
+ 1144 : }
+ 1145 :
+ 1146 : /* if all is processed, we have fixed it */
+ 1147 852 : if (j == failed_count)
+ 1148 852 : fixed_error_on_this_block = 1;
+ 1149 : }
+ 1150 : }
+ 1151 : }
+ 1152 :
+ 1153 : /* if we have read all the data required and it's correct, proceed with the parity */
+ 1154 114790 : if (!error_on_this_block && !io_error_on_this_block
+ 1155 114771 : && (!silent_error_on_this_block || fixed_error_on_this_block)
+ 1156 : ) {
+ 1157 : /* update the parity only if really needed */
+ 1158 114771 : if (parity_needs_to_be_updated) {
+ 1159 : /* compute the parity */
+ 1160 112474 : raid_gen(diskmax, state->level, state->block_size, buffer);
+ 1161 :
+ 1162 : /* until now is raid */
+ 1163 112474 : state_usage_raid(state);
+ 1164 :
+ 1165 : /* mark that the parity is going to be written */
+ 1166 112474 : parity_going_to_be_updated = 1;
+ 1167 : }
+ 1168 :
+ 1169 : /* for each disk, mark the blocks as processed */
+ 1170 803397 : for (j = 0; j < diskmax; ++j) {
+ 1171 : struct snapraid_block* block;
+ 1172 :
+ 1173 688626 : if (!handle[j].disk)
+ 1174 0 : continue;
+ 1175 :
+ 1176 688626 : block = fs_par2block_find(handle[j].disk, blockcur);
+ 1177 :
+ 1178 688626 : if (block == BLOCK_NULL) {
+ 1179 : /* nothing to do */
+ 1180 81210 : continue;
+ 1181 : }
+ 1182 :
+ 1183 : /* if it's a deleted block */
+ 1184 607416 : if (block_state_get(block) == BLOCK_STATE_DELETED) {
+ 1185 : /* the parity is now updated without this block, so it's now empty */
+ 1186 10953 : fs_deallocate(handle[j].disk, blockcur);
+ 1187 10953 : continue;
+ 1188 : }
+ 1189 :
+ 1190 : /* now all the blocks have the hash and the parity computed */
+ 1191 596463 : block_state_set(block, BLOCK_STATE_BLK);
+ 1192 : }
+ 1193 :
+ 1194 : /* we update the info block only if we really have updated the parity */
+ 1195 : /* because otherwise the time/justsynced info would be misleading as we didn't */
+ 1196 : /* wrote the parity at this time */
+ 1197 : /* we also update the info block only if no silent error was found */
+ 1198 : /* because has no sense to refresh the time for data that we know bad */
+ 1199 114771 : if (parity_needs_to_be_updated
+ 1200 112474 : && !silent_error_on_this_block
+ 1201 : ) {
+ 1202 : /* if rehash is needed */
+ 1203 112132 : if (rehash) {
+ 1204 : /* store all the new hash already computed */
+ 1205 32249 : for (j = 0; j < diskmax; ++j) {
+ 1206 27642 : if (rehandle[j].block)
+ 1207 27243 : memcpy(rehandle[j].block->hash, rehandle[j].hash, BLOCK_HASH_SIZE);
+ 1208 : }
+ 1209 : }
1210 :
- 1211 : /* if a silent (even if corrected) or input/output error was found */
- 1212 : /* mark the block as bad to have check/fix to handle it */
- 1213 : /* because our correction is in memory only and not yet written */
- 1214 114702 : if (silent_error_on_this_block || io_error_on_this_block) {
- 1215 : /* set the error status keeping the other info */
- 1216 852 : info_set(&state->infoarr, blockcur, info_set_bad(info));
- 1217 : }
- 1218 :
- 1219 : /* finally schedule parity write */
- 1220 : /* Note that the calls to io_parity_write() are mandatory */
- 1221 : /* even if the parity doesn't need to be updated */
- 1222 : /* This because we want to keep track of the time usage */
- 1223 114702 : state_usage_misc(state);
+ 1211 : /* update the time info of the block */
+ 1212 : /* we are also clearing any previous bad and rehash flag */
+ 1213 112132 : info_set(&state->infoarr, blockcur, info_make(now, 0, 0, 1));
+ 1214 : }
+ 1215 : }
+ 1216 :
+ 1217 : /* if a silent (even if corrected) or input/output error was found */
+ 1218 : /* mark the block as bad to have check/fix to handle it */
+ 1219 : /* because our correction is in memory only and not yet written */
+ 1220 114790 : if (silent_error_on_this_block || io_error_on_this_block) {
+ 1221 : /* set the error status keeping the other info */
+ 1222 852 : info_set(&state->infoarr, blockcur, info_set_bad(info));
+ 1223 : }
1224 :
- 1225 : /* write start */
- 1226 114702 : io_write_preset(&io, blockcur, !parity_going_to_be_updated);
- 1227 :
- 1228 : /* write the parity */
- 1229 672809 : for (l = 0; l < state->level; ++l) {
- 1230 : unsigned levcur;
- 1231 :
- 1232 558107 : io_parity_write(&io, &levcur, waiting_map, &waiting_mac);
+ 1225 : /* finally schedule parity write */
+ 1226 : /* Note that the calls to io_parity_write() are mandatory */
+ 1227 : /* even if the parity doesn't need to be updated */
+ 1228 : /* This because we want to keep track of the time usage */
+ 1229 114790 : state_usage_misc(state);
+ 1230 :
+ 1231 : /* write start */
+ 1232 114790 : io_write_preset(&io, blockcur, !parity_going_to_be_updated);
1233 :
- 1234 : /* until now is parity */
- 1235 558107 : state_usage_parity(state, waiting_map, waiting_mac);
- 1236 : }
+ 1234 : /* write the parity */
+ 1235 673425 : for (l = 0; l < state->level; ++l) {
+ 1236 : unsigned levcur;
1237 :
- 1238 : /* write finished */
- 1239 114702 : io_write_next(&io, blockcur, !parity_going_to_be_updated, writer_error);
- 1240 :
- 1241 : /* handle errors reported */
- 1242 573510 : for (j = 0; j < IO_WRITER_ERROR_MAX; ++j) {
- 1243 458808 : if (writer_error[j]) {
- 1244 0 : switch (j + IO_WRITER_ERROR_BASE) {
- 1245 : case TASK_STATE_IOERROR_CONTINUE :
- 1246 0 : ++io_error;
- 1247 0 : if (io_error >= state->opt.io_error_limit) {
- 1248 0 : log_fatal("DANGER! Unexpected input/output write error in a parity disk, it isn't possible to sync.\n");
- 1249 0 : log_fatal("Stopping at block %u\n", blockcur);
- 1250 0 : goto bail;
- 1251 : }
- 1252 0 : break;
- 1253 : case TASK_STATE_ERROR_CONTINUE :
- 1254 0 : ++error;
- 1255 0 : break;
- 1256 : case TASK_STATE_IOERROR :
- 1257 0 : ++io_error;
- 1258 0 : goto bail;
- 1259 : case TASK_STATE_ERROR :
- 1260 0 : ++error;
- 1261 0 : goto bail;
- 1262 : }
- 1263 : }
- 1264 : }
- 1265 :
- 1266 : /* mark the state as needing write */
- 1267 114702 : state->need_write = 1;
- 1268 :
- 1269 : /* count the number of processed block */
- 1270 114702 : ++countpos;
- 1271 :
- 1272 : /* progress */
- 1273 114702 : if (state_progress(state, &io, blockcur, countpos, countmax, countsize)) {
- 1274 : /* LCOV_EXCL_START */
- 1275 : break;
- 1276 : /* LCOV_EXCL_STOP */
- 1277 : }
- 1278 :
- 1279 : /* autosave */
- 1280 114702 : if ((state->autosave != 0
- 1281 26021 : && autosavedone >= autosavelimit /* if we have reached the limit */
- 1282 0 : && autosavemissing >= autosavelimit) /* if we have at least a full step to do */
- 1283 : /* or if we have a forced autosave at the specified block */
- 1284 114702 : || (state->opt.force_autosave_at != 0 && state->opt.force_autosave_at == blockcur)
- 1285 : ) {
- 1286 1 : autosavedone = 0; /* restart the counter */
- 1287 :
- 1288 : /* until now is misc */
- 1289 1 : state_usage_misc(state);
+ 1238 558635 : io_parity_write(&io, &levcur, waiting_map, &waiting_mac);
+ 1239 :
+ 1240 : /* until now is parity */
+ 1241 558635 : state_usage_parity(state, waiting_map, waiting_mac);
+ 1242 : }
+ 1243 :
+ 1244 : /* write finished */
+ 1245 114790 : io_write_next(&io, blockcur, !parity_going_to_be_updated, writer_error);
+ 1246 :
+ 1247 : /* handle errors reported */
+ 1248 573950 : for (j = 0; j < IO_WRITER_ERROR_MAX; ++j) {
+ 1249 459160 : if (writer_error[j]) {
+ 1250 0 : switch (j + IO_WRITER_ERROR_BASE) {
+ 1251 : case TASK_STATE_IOERROR_CONTINUE :
+ 1252 0 : ++io_error;
+ 1253 0 : if (io_error >= state->opt.io_error_limit) {
+ 1254 : /* LCOV_EXCL_START */
+ 1255 : log_fatal("DANGER! Unexpected input/output write error in a parity disk, it isn't possible to sync.\n");
+ 1256 : log_fatal("Stopping at block %u\n", blockcur);
+ 1257 : goto bail;
+ 1258 : /* LCOV_EXCL_STOP */
+ 1259 : }
+ 1260 0 : break;
+ 1261 : case TASK_STATE_ERROR_CONTINUE :
+ 1262 0 : ++error;
+ 1263 0 : break;
+ 1264 : case TASK_STATE_IOERROR :
+ 1265 : /* LCOV_EXCL_START */
+ 1266 : ++io_error;
+ 1267 : goto bail;
+ 1268 : /* LCOV_EXCL_STOP */
+ 1269 : case TASK_STATE_ERROR :
+ 1270 : /* LCOV_EXCL_START */
+ 1271 : ++error;
+ 1272 : goto bail;
+ 1273 : /* LCOV_EXCL_STOP */
+ 1274 : }
+ 1275 : }
+ 1276 : }
+ 1277 :
+ 1278 : /* mark the state as needing write */
+ 1279 114790 : state->need_write = 1;
+ 1280 :
+ 1281 : /* count the number of processed block */
+ 1282 114790 : ++countpos;
+ 1283 :
+ 1284 : /* progress */
+ 1285 114790 : if (state_progress(state, &io, blockcur, countpos, countmax, countsize)) {
+ 1286 : /* LCOV_EXCL_START */
+ 1287 : break;
+ 1288 : /* LCOV_EXCL_STOP */
+ 1289 : }
1290 :
- 1291 1 : state_progress_stop(state);
- 1292 :
- 1293 1 : msg_progress("Autosaving...\n");
- 1294 :
- 1295 : /* before writing the new content file we ensure that */
- 1296 : /* the parity is really written flushing the disk cache */
- 1297 7 : for (l = 0; l < state->level; ++l) {
- 1298 6 : ret = parity_sync(&parity_handle[l]);
- 1299 6 : if (ret == -1) {
- 1300 : /* LCOV_EXCL_START */
- 1301 : log_tag("parity_error:%u:%s: Sync error\n", blockcur, lev_config_name(l));
- 1302 : log_fatal("DANGER! Unexpected sync error in %s disk.\n", lev_name(l));
- 1303 : log_fatal("Ensure that disk '%s' is sane.\n", lev_config_name(l));
- 1304 : log_fatal("Stopping at block %u\n", blockcur);
- 1305 : ++error;
- 1306 : goto bail;
- 1307 : /* LCOV_EXCL_STOP */
- 1308 : }
- 1309 : }
- 1310 :
- 1311 : /* now we can safely write the content file */
- 1312 1 : state_write(state);
- 1313 :
- 1314 1 : state_progress_restart(state);
- 1315 :
- 1316 : /* drop until now */
- 1317 1 : state_usage_waste(state);
- 1318 : }
- 1319 114702 : }
- 1320 :
- 1321 : end:
- 1322 83 : state_progress_end(state, countpos, countmax, countsize);
- 1323 :
- 1324 83 : state_usage_print(state);
+ 1291 : /* autosave */
+ 1292 114790 : if ((state->autosave != 0
+ 1293 26021 : && autosavedone >= autosavelimit /* if we have reached the limit */
+ 1294 0 : && autosavemissing >= autosavelimit) /* if we have at least a full step to do */
+ 1295 : /* or if we have a forced autosave at the specified block */
+ 1296 114790 : || (state->opt.force_autosave_at != 0 && state->opt.force_autosave_at == blockcur)
+ 1297 : ) {
+ 1298 1 : autosavedone = 0; /* restart the counter */
+ 1299 :
+ 1300 : /* until now is misc */
+ 1301 1 : state_usage_misc(state);
+ 1302 :
+ 1303 1 : state_progress_stop(state);
+ 1304 :
+ 1305 1 : msg_progress("Autosaving...\n");
+ 1306 :
+ 1307 : /* before writing the new content file we ensure that */
+ 1308 : /* the parity is really written flushing the disk cache */
+ 1309 7 : for (l = 0; l < state->level; ++l) {
+ 1310 6 : ret = parity_sync(&parity_handle[l]);
+ 1311 6 : if (ret == -1) {
+ 1312 : /* LCOV_EXCL_START */
+ 1313 : log_tag("parity_error:%u:%s: Sync error\n", blockcur, lev_config_name(l));
+ 1314 : log_fatal("DANGER! Unexpected sync error in %s disk.\n", lev_name(l));
+ 1315 : log_fatal("Ensure that disk '%s' is sane.\n", lev_config_name(l));
+ 1316 : log_fatal("Stopping at block %u\n", blockcur);
+ 1317 : ++error;
+ 1318 : goto bail;
+ 1319 : /* LCOV_EXCL_STOP */
+ 1320 : }
+ 1321 : }
+ 1322 :
+ 1323 : /* now we can safely write the content file */
+ 1324 1 : state_write(state);
1325 :
- 1326 : /* before returning we ensure that */
- 1327 : /* the parity is really written flushing the disk cache */
- 1328 546 : for (l = 0; l < state->level; ++l) {
- 1329 463 : ret = parity_sync(&parity_handle[l]);
- 1330 463 : if (ret == -1) {
- 1331 : /* LCOV_EXCL_START */
- 1332 : log_tag("parity_error:%u:%s: Sync error\n", blockcur, lev_config_name(l));
- 1333 : log_fatal("DANGER! Unexpected sync error in %s disk.\n", lev_name(l));
- 1334 : log_fatal("Ensure that disk '%s' is sane.\n", lev_config_name(l));
- 1335 : log_fatal("Stopping at block %u\n", blockcur);
- 1336 : ++error;
- 1337 : goto bail;
- 1338 : /* LCOV_EXCL_STOP */
- 1339 : }
- 1340 : }
- 1341 :
- 1342 83 : if (error || silent_error || io_error) {
- 1343 12 : msg_status("\n");
- 1344 12 : msg_status("%8u file errors\n", error);
- 1345 12 : msg_status("%8u io errors\n", io_error);
- 1346 12 : msg_status("%8u data errors\n", silent_error);
- 1347 : } else {
- 1348 : /* print the result only if processed something */
- 1349 71 : if (countpos != 0)
- 1350 53 : msg_status("Everything OK\n");
- 1351 : }
- 1352 :
- 1353 83 : if (error)
- 1354 11 : log_fatal("WARNING! Unexpected file errors!\n");
- 1355 83 : if (io_error)
- 1356 0 : log_fatal("DANGER! Unexpected input/output errors! The failing blocks are now marked as bad!\n");
- 1357 83 : if (silent_error)
- 1358 1 : log_fatal("DANGER! Unexpected data errors! The failing blocks are now marked as bad!\n");
- 1359 83 : if (io_error || silent_error) {
- 1360 1 : log_fatal("Use 'snapraid status' to list the bad blocks.\n");
- 1361 1 : log_fatal("Use 'snapraid -e fix' to recover.\n");
- 1362 : }
- 1363 :
- 1364 83 : log_tag("summary:error_file:%u\n", error);
- 1365 83 : log_tag("summary:error_io:%u\n", io_error);
- 1366 83 : log_tag("summary:error_data:%u\n", silent_error);
- 1367 83 : if (error + silent_error + io_error == 0)
- 1368 71 : log_tag("summary:exit:ok\n");
- 1369 : else
- 1370 12 : log_tag("summary:exit:error\n");
- 1371 83 : log_flush();
- 1372 :
- 1373 : bail:
- 1374 : /* stop all the worker threads */
- 1375 83 : io_stop(&io);
- 1376 :
- 1377 581 : for (j = 0; j < diskmax; ++j) {
- 1378 498 : struct snapraid_file* file = handle[j].file;
- 1379 498 : struct snapraid_disk* disk = handle[j].disk;
- 1380 498 : ret = handle_close(&handle[j]);
- 1381 498 : if (ret == -1) {
- 1382 : /* LCOV_EXCL_START */
- 1383 : log_tag("error:%u:%s:%s: Close error. %s\n", blockcur, disk->name, esc_tag(file->sub, esc_buffer), strerror(errno));
- 1384 : log_fatal("DANGER! Unexpected close error in a data disk.\n");
- 1385 : ++error;
- 1386 : /* continue, as we are already exiting */
- 1387 : /* LCOV_EXCL_STOP */
- 1388 : }
- 1389 : }
- 1390 :
- 1391 83 : free(handle);
- 1392 83 : free(zero_alloc);
- 1393 83 : free(copy_alloc);
- 1394 83 : free(copy);
- 1395 83 : free(rehandle_alloc);
- 1396 83 : free(failed);
- 1397 83 : free(failed_map);
- 1398 83 : free(waiting_map);
- 1399 83 : io_done(&io);
- 1400 :
- 1401 83 : if (state->opt.expect_recoverable) {
- 1402 1 : if (error + silent_error + io_error == 0)
- 1403 0 : return -1;
- 1404 : } else {
- 1405 82 : if (error + silent_error + io_error != 0)
- 1406 11 : return -1;
- 1407 : }
- 1408 72 : return 0;
- 1409 : }
- 1410 :
- 1411 87 : int state_sync(struct snapraid_state* state, block_off_t blockstart, block_off_t blockcount)
- 1412 : {
- 1413 : block_off_t blockmax;
- 1414 : block_off_t used_paritymax;
- 1415 : block_off_t file_paritymax;
- 1416 : data_off_t size;
- 1417 : int ret;
- 1418 : struct snapraid_parity_handle parity_handle[LEV_MAX];
- 1419 : unsigned unrecoverable_error;
- 1420 : unsigned l;
- 1421 87 : int skip_sync = 0;
+ 1326 1 : state_progress_restart(state);
+ 1327 :
+ 1328 : /* drop until now */
+ 1329 1 : state_usage_waste(state);
+ 1330 : }
+ 1331 114790 : }
+ 1332 :
+ 1333 : end:
+ 1334 83 : state_progress_end(state, countpos, countmax, countsize);
+ 1335 :
+ 1336 83 : state_usage_print(state);
+ 1337 :
+ 1338 : /* before returning we ensure that */
+ 1339 : /* the parity is really written flushing the disk cache */
+ 1340 546 : for (l = 0; l < state->level; ++l) {
+ 1341 463 : ret = parity_sync(&parity_handle[l]);
+ 1342 463 : if (ret == -1) {
+ 1343 : /* LCOV_EXCL_START */
+ 1344 : log_tag("parity_error:%u:%s: Sync error\n", blockcur, lev_config_name(l));
+ 1345 : log_fatal("DANGER! Unexpected sync error in %s disk.\n", lev_name(l));
+ 1346 : log_fatal("Ensure that disk '%s' is sane.\n", lev_config_name(l));
+ 1347 : log_fatal("Stopping at block %u\n", blockcur);
+ 1348 : ++error;
+ 1349 : goto bail;
+ 1350 : /* LCOV_EXCL_STOP */
+ 1351 : }
+ 1352 : }
+ 1353 :
+ 1354 83 : if (error || silent_error || io_error) {
+ 1355 12 : msg_status("\n");
+ 1356 12 : msg_status("%8u file errors\n", error);
+ 1357 12 : msg_status("%8u io errors\n", io_error);
+ 1358 12 : msg_status("%8u data errors\n", silent_error);
+ 1359 : } else {
+ 1360 : /* print the result only if processed something */
+ 1361 71 : if (countpos != 0)
+ 1362 53 : msg_status("Everything OK\n");
+ 1363 : }
+ 1364 :
+ 1365 83 : if (error)
+ 1366 11 : log_fatal("WARNING! Unexpected file errors!\n");
+ 1367 83 : if (io_error)
+ 1368 0 : log_fatal("DANGER! Unexpected input/output errors! The failing blocks are now marked as bad!\n");
+ 1369 83 : if (silent_error)
+ 1370 1 : log_fatal("DANGER! Unexpected data errors! The failing blocks are now marked as bad!\n");
+ 1371 83 : if (io_error || silent_error) {
+ 1372 1 : log_fatal("Use 'snapraid status' to list the bad blocks.\n");
+ 1373 1 : log_fatal("Use 'snapraid -e fix' to recover.\n");
+ 1374 : }
+ 1375 :
+ 1376 83 : log_tag("summary:error_file:%u\n", error);
+ 1377 83 : log_tag("summary:error_io:%u\n", io_error);
+ 1378 83 : log_tag("summary:error_data:%u\n", silent_error);
+ 1379 83 : if (error + silent_error + io_error == 0)
+ 1380 71 : log_tag("summary:exit:ok\n");
+ 1381 : else
+ 1382 12 : log_tag("summary:exit:error\n");
+ 1383 83 : log_flush();
+ 1384 :
+ 1385 : bail:
+ 1386 : /* stop all the worker threads */
+ 1387 83 : io_stop(&io);
+ 1388 :
+ 1389 581 : for (j = 0; j < diskmax; ++j) {
+ 1390 498 : struct snapraid_file* file = handle[j].file;
+ 1391 498 : struct snapraid_disk* disk = handle[j].disk;
+ 1392 498 : ret = handle_close(&handle[j]);
+ 1393 498 : if (ret == -1) {
+ 1394 : /* LCOV_EXCL_START */
+ 1395 : log_tag("error:%u:%s:%s: Close error. %s\n", blockcur, disk->name, esc_tag(file->sub, esc_buffer), strerror(errno));
+ 1396 : log_fatal("DANGER! Unexpected close error in a data disk.\n");
+ 1397 : ++error;
+ 1398 : /* continue, as we are already exiting */
+ 1399 : /* LCOV_EXCL_STOP */
+ 1400 : }
+ 1401 : }
+ 1402 :
+ 1403 83 : free(handle);
+ 1404 83 : free(zero_alloc);
+ 1405 83 : free(copy_alloc);
+ 1406 83 : free(copy);
+ 1407 83 : free(rehandle_alloc);
+ 1408 83 : free(failed);
+ 1409 83 : free(failed_map);
+ 1410 83 : free(waiting_map);
+ 1411 83 : io_done(&io);
+ 1412 :
+ 1413 83 : if (state->opt.expect_recoverable) {
+ 1414 1 : if (error + silent_error + io_error == 0)
+ 1415 0 : return -1;
+ 1416 : } else {
+ 1417 82 : if (error + silent_error + io_error != 0)
+ 1418 11 : return -1;
+ 1419 : }
+ 1420 72 : return 0;
+ 1421 : }
1422 :
- 1423 87 : msg_progress("Initializing...\n");
- 1424 :
- 1425 87 : blockmax = parity_allocated_size(state);
- 1426 87 : size = blockmax * (data_off_t)state->block_size;
- 1427 :
- 1428 : /* minimum size of the parity files we expect */
- 1429 87 : used_paritymax = parity_used_size(state);
- 1430 :
- 1431 : /* effective size of the parity files */
- 1432 87 : file_paritymax = 0;
- 1433 :
- 1434 87 : if (blockstart > blockmax) {
- 1435 : /* LCOV_EXCL_START */
- 1436 : log_fatal("Error in the starting block %u. It's bigger than the parity size %u.\n", blockstart, blockmax);
- 1437 : exit(EXIT_FAILURE);
- 1438 : /* LCOV_EXCL_STOP */
- 1439 : }
- 1440 :
- 1441 : /* adjust the number of block to process */
- 1442 87 : if (blockcount != 0 && blockstart + blockcount < blockmax) {
- 1443 6 : blockmax = blockstart + blockcount;
- 1444 : }
+ 1423 87 : int state_sync(struct snapraid_state* state, block_off_t blockstart, block_off_t blockcount)
+ 1424 : {
+ 1425 : block_off_t blockmax;
+ 1426 : block_off_t used_paritymax;
+ 1427 : block_off_t file_paritymax;
+ 1428 : data_off_t size;
+ 1429 : int ret;
+ 1430 : struct snapraid_parity_handle parity_handle[LEV_MAX];
+ 1431 : unsigned unrecoverable_error;
+ 1432 : unsigned l;
+ 1433 87 : int skip_sync = 0;
+ 1434 :
+ 1435 87 : msg_progress("Initializing...\n");
+ 1436 :
+ 1437 87 : blockmax = parity_allocated_size(state);
+ 1438 87 : size = blockmax * (data_off_t)state->block_size;
+ 1439 :
+ 1440 : /* minimum size of the parity files we expect */
+ 1441 87 : used_paritymax = parity_used_size(state);
+ 1442 :
+ 1443 : /* effective size of the parity files */
+ 1444 87 : file_paritymax = 0;
1445 :
- 1446 574 : for (l = 0; l < state->level; ++l) {
- 1447 : data_off_t out_size;
- 1448 : block_off_t parityblocks;
- 1449 :
- 1450 : /* create the file and open for writing */
- 1451 487 : ret = parity_create(&parity_handle[l], &state->parity[l], l, state->file_mode, state->block_size, state->opt.parity_limit_size);
- 1452 487 : if (ret == -1) {
- 1453 : /* LCOV_EXCL_START */
- 1454 : log_fatal("WARNING! Without an accessible %s file, it isn't possible to sync.\n", lev_name(l));
- 1455 : exit(EXIT_FAILURE);
- 1456 : /* LCOV_EXCL_STOP */
- 1457 : }
- 1458 :
- 1459 : /* number of block in the parity file */
- 1460 487 : parity_size(&parity_handle[l], &out_size);
- 1461 487 : parityblocks = out_size / state->block_size;
- 1462 :
- 1463 : /* if the file is too small */
- 1464 487 : if (parityblocks < used_paritymax) {
- 1465 0 : log_fatal("WARNING! The %s parity has data only %u blocks instead of %u.\n", lev_name(l), parityblocks, used_paritymax);
- 1466 : }
- 1467 :
- 1468 : /* keep the smallest parity number of blocks */
- 1469 487 : if (l == 0 || file_paritymax > parityblocks)
- 1470 87 : file_paritymax = parityblocks;
- 1471 : }
- 1472 :
- 1473 : /* if we do a full parity realloc or computation, having a wrong parity size is expected */
- 1474 87 : if (!state->opt.force_realloc && !state->opt.force_full) {
- 1475 : /* if the parities are too small */
- 1476 80 : if (file_paritymax < used_paritymax) {
- 1477 : /* LCOV_EXCL_START */
- 1478 : log_fatal("DANGER! One or more the parity files are smaller than expected!\n");
- 1479 : if (file_paritymax != 0) {
- 1480 : log_fatal("If this happens because you are using an old content file,\n");
- 1481 : log_fatal("you can 'sync' anyway using 'snapraid --force-full sync'\n");
- 1482 : log_fatal("to force a full rebuild of the parity.\n");
- 1483 : } else {
- 1484 : log_fatal("It's possible that the parity disks are not mounted.\n");
- 1485 : log_fatal("If instead you are adding a new parity level, you can 'sync' using\n");
- 1486 : log_fatal("'snapraid --force-full sync' to force a full rebuild of the parity.\n");
- 1487 : }
- 1488 : exit(EXIT_FAILURE);
- 1489 : /* LCOV_EXCL_STOP */
- 1490 : }
- 1491 : }
- 1492 :
- 1493 87 : unrecoverable_error = 0;
- 1494 :
- 1495 87 : if (state->opt.prehash) {
- 1496 7 : msg_progress("Hashing...\n");
- 1497 :
- 1498 7 : ret = state_hash_process(state, blockstart, blockmax, &skip_sync);
- 1499 7 : if (ret == -1) {
- 1500 : /* LCOV_EXCL_START */
- 1501 : ++unrecoverable_error;
- 1502 : /* continue, in case also doing the sync if ::skip_sync is not set */
- 1503 : /* LCOV_EXCL_STOP */
- 1504 : }
- 1505 : }
+ 1446 87 : if (blockstart > blockmax) {
+ 1447 : /* LCOV_EXCL_START */
+ 1448 : log_fatal("Error in the starting block %u. It's bigger than the parity size %u.\n", blockstart, blockmax);
+ 1449 : exit(EXIT_FAILURE);
+ 1450 : /* LCOV_EXCL_STOP */
+ 1451 : }
+ 1452 :
+ 1453 : /* adjust the number of block to process */
+ 1454 87 : if (blockcount != 0 && blockstart + blockcount < blockmax) {
+ 1455 6 : blockmax = blockstart + blockcount;
+ 1456 : }
+ 1457 :
+ 1458 574 : for (l = 0; l < state->level; ++l) {
+ 1459 : data_off_t out_size;
+ 1460 : block_off_t parityblocks;
+ 1461 :
+ 1462 : /* create the file and open for writing */
+ 1463 487 : ret = parity_create(&parity_handle[l], &state->parity[l], l, state->file_mode, state->block_size, state->opt.parity_limit_size);
+ 1464 487 : if (ret == -1) {
+ 1465 : /* LCOV_EXCL_START */
+ 1466 : log_fatal("WARNING! Without an accessible %s file, it isn't possible to sync.\n", lev_name(l));
+ 1467 : exit(EXIT_FAILURE);
+ 1468 : /* LCOV_EXCL_STOP */
+ 1469 : }
+ 1470 :
+ 1471 : /* number of block in the parity file */
+ 1472 487 : parity_size(&parity_handle[l], &out_size);
+ 1473 487 : parityblocks = out_size / state->block_size;
+ 1474 :
+ 1475 : /* if the file is too small */
+ 1476 487 : if (parityblocks < used_paritymax) {
+ 1477 0 : log_fatal("WARNING! The %s parity has data only %u blocks instead of %u.\n", lev_name(l), parityblocks, used_paritymax);
+ 1478 : }
+ 1479 :
+ 1480 : /* keep the smallest parity number of blocks */
+ 1481 487 : if (l == 0 || file_paritymax > parityblocks)
+ 1482 87 : file_paritymax = parityblocks;
+ 1483 : }
+ 1484 :
+ 1485 : /* if we do a full parity realloc or computation, having a wrong parity size is expected */
+ 1486 87 : if (!state->opt.force_realloc && !state->opt.force_full) {
+ 1487 : /* if the parities are too small */
+ 1488 80 : if (file_paritymax < used_paritymax) {
+ 1489 : /* LCOV_EXCL_START */
+ 1490 : log_fatal("DANGER! One or more the parity files are smaller than expected!\n");
+ 1491 : if (file_paritymax != 0) {
+ 1492 : log_fatal("If this happens because you are using an old content file,\n");
+ 1493 : log_fatal("you can 'sync' anyway using 'snapraid --force-full sync'\n");
+ 1494 : log_fatal("to force a full rebuild of the parity.\n");
+ 1495 : } else {
+ 1496 : log_fatal("It's possible that the parity disks are not mounted.\n");
+ 1497 : log_fatal("If instead you are adding a new parity level, you can 'sync' using\n");
+ 1498 : log_fatal("'snapraid --force-full sync' to force a full rebuild of the parity.\n");
+ 1499 : }
+ 1500 : exit(EXIT_FAILURE);
+ 1501 : /* LCOV_EXCL_STOP */
+ 1502 : }
+ 1503 : }
+ 1504 :
+ 1505 87 : unrecoverable_error = 0;
1506 :
- 1507 87 : if (!skip_sync) {
- 1508 86 : msg_progress("Resizing...\n");
+ 1507 87 : if (state->opt.prehash) {
+ 1508 7 : msg_progress("Hashing...\n");
1509 :
- 1510 : /* now change the size of all parities */
- 1511 567 : for (l = 0; l < state->level; ++l) {
- 1512 : int is_modified;
- 1513 :
- 1514 : /* change the size of the parity file, truncating or extending it */
- 1515 : /* from this point all the DELETED blocks after the end of the parity are invalid */
- 1516 : /* and they are automatically removed when we save the new content file */
- 1517 481 : ret = parity_chsize(&parity_handle[l], &state->parity[l], &is_modified, size, state->block_size, state->opt.skip_fallocate, state->opt.skip_space_holder);
- 1518 481 : if (ret == -1) {
- 1519 : /* LCOV_EXCL_START */
- 1520 : data_off_t out_size;
- 1521 : parity_size(&parity_handle[l], &out_size);
- 1522 : parity_overflow(state, out_size);
- 1523 : log_fatal("WARNING! Without an unsable %s file, it isn't possible to sync.\n", lev_name(l));
- 1524 : exit(EXIT_FAILURE);
- 1525 : /* LCOV_EXCL_STOP */
- 1526 : }
- 1527 :
- 1528 481 : if (is_modified)
- 1529 175 : state->need_write = 1;
- 1530 : }
- 1531 :
- 1532 : /* after resizing parity files, refresh again the free info */
- 1533 86 : state_refresh(state);
- 1534 :
- 1535 : /**
- 1536 : * Save the new state before the sync but after the hashing phase
- 1537 : *
- 1538 : * This allows to recover after an aborted sync, and at the same time
- 1539 : * it allows to recover broken copied/moved files identified in the
- 1540 : * hashing phase.
- 1541 : *
- 1542 : * For example, think at this case:
- 1543 : * - Add some files at the array
- 1544 : * - Run a sync command, it will recompute the parity adding the new files
- 1545 : * - Abort the sync command before it stores the new content file
- 1546 : * - Delete the not yet synced files from the array
- 1547 : * - Run a new sync command
- 1548 : *
- 1549 : * The sync command has no way to know that the parity file was modified
- 1550 : * because the files triggering these changes are now deleted and they aren't
- 1551 : * listed in the content file.
- 1552 : * Instead, saving the new content file in advance, keeps track of all the parity
- 1553 : * that may be modified.
- 1554 : */
- 1555 86 : if (!state->opt.skip_content_write) {
- 1556 86 : if (state->need_write)
- 1557 79 : state_write(state);
- 1558 : } else {
- 1559 0 : log_fatal("WARNING! Skipped state write for --test-skip-content-write option.\n");
- 1560 : }
- 1561 :
- 1562 86 : msg_progress("Syncing...\n");
- 1563 :
- 1564 : /* skip degenerated cases of empty parity, or skipping all */
- 1565 86 : if (blockstart < blockmax) {
- 1566 83 : ret = state_sync_process(state, parity_handle, blockstart, blockmax);
- 1567 83 : if (ret == -1) {
- 1568 : /* LCOV_EXCL_START */
- 1569 : ++unrecoverable_error;
- 1570 : /* continue, as we are already exiting */
- 1571 : /* LCOV_EXCL_STOP */
- 1572 : }
- 1573 : } else {
- 1574 3 : msg_status("Nothing to do\n");
- 1575 : }
- 1576 : }
- 1577 :
- 1578 574 : for (l = 0; l < state->level; ++l) {
- 1579 487 : ret = parity_close(&parity_handle[l]);
- 1580 487 : if (ret == -1) {
- 1581 : /* LCOV_EXCL_START */
- 1582 : log_fatal("DANGER! Unexpected close error in %s disk.\n", lev_name(l));
- 1583 : ++unrecoverable_error;
- 1584 : /* continue, as we are already exiting */
- 1585 : /* LCOV_EXCL_STOP */
- 1586 : }
- 1587 : }
- 1588 :
- 1589 : /* abort if required */
- 1590 87 : if (unrecoverable_error != 0)
- 1591 12 : return -1;
- 1592 75 : return 0;
- 1593 : }
- 1594 :
+ 1510 7 : ret = state_hash_process(state, blockstart, blockmax, &skip_sync);
+ 1511 7 : if (ret == -1) {
+ 1512 : /* LCOV_EXCL_START */
+ 1513 : ++unrecoverable_error;
+ 1514 : /* continue, in case also doing the sync if ::skip_sync is not set */
+ 1515 : /* LCOV_EXCL_STOP */
+ 1516 : }
+ 1517 : }
+ 1518 :
+ 1519 87 : if (!skip_sync) {
+ 1520 86 : msg_progress("Resizing...\n");
+ 1521 :
+ 1522 : /* now change the size of all parities */
+ 1523 567 : for (l = 0; l < state->level; ++l) {
+ 1524 : int is_modified;
+ 1525 :
+ 1526 : /* change the size of the parity file, truncating or extending it */
+ 1527 : /* from this point all the DELETED blocks after the end of the parity are invalid */
+ 1528 : /* and they are automatically removed when we save the new content file */
+ 1529 481 : ret = parity_chsize(&parity_handle[l], &state->parity[l], &is_modified, size, state->block_size, state->opt.skip_fallocate, state->opt.skip_space_holder);
+ 1530 481 : if (ret == -1) {
+ 1531 : /* LCOV_EXCL_START */
+ 1532 : data_off_t out_size;
+ 1533 : parity_size(&parity_handle[l], &out_size);
+ 1534 : parity_overflow(state, out_size);
+ 1535 : log_fatal("WARNING! Without an unsable %s file, it isn't possible to sync.\n", lev_name(l));
+ 1536 : exit(EXIT_FAILURE);
+ 1537 : /* LCOV_EXCL_STOP */
+ 1538 : }
+ 1539 :
+ 1540 481 : if (is_modified)
+ 1541 175 : state->need_write = 1;
+ 1542 : }
+ 1543 :
+ 1544 : /* after resizing parity files, refresh again the free info */
+ 1545 86 : state_refresh(state);
+ 1546 :
+ 1547 : /**
+ 1548 : * Save the new state before the sync but after the hashing phase
+ 1549 : *
+ 1550 : * This allows to recover after an aborted sync, and at the same time
+ 1551 : * it allows to recover broken copied/moved files identified in the
+ 1552 : * hashing phase.
+ 1553 : *
+ 1554 : * For example, think at this case:
+ 1555 : * - Add some files at the array
+ 1556 : * - Run a sync command, it will recompute the parity adding the new files
+ 1557 : * - Abort the sync command before it stores the new content file
+ 1558 : * - Delete the not yet synced files from the array
+ 1559 : * - Run a new sync command
+ 1560 : *
+ 1561 : * The sync command has no way to know that the parity file was modified
+ 1562 : * because the files triggering these changes are now deleted and they aren't
+ 1563 : * listed in the content file.
+ 1564 : * Instead, saving the new content file in advance, keeps track of all the parity
+ 1565 : * that may be modified.
+ 1566 : */
+ 1567 86 : if (!state->opt.skip_content_write) {
+ 1568 86 : if (state->need_write)
+ 1569 79 : state_write(state);
+ 1570 : } else {
+ 1571 0 : log_fatal("WARNING! Skipped state write for --test-skip-content-write option.\n");
+ 1572 : }
+ 1573 :
+ 1574 86 : msg_progress("Syncing...\n");
+ 1575 :
+ 1576 : /* skip degenerated cases of empty parity, or skipping all */
+ 1577 86 : if (blockstart < blockmax) {
+ 1578 83 : ret = state_sync_process(state, parity_handle, blockstart, blockmax);
+ 1579 83 : if (ret == -1) {
+ 1580 : /* LCOV_EXCL_START */
+ 1581 : ++unrecoverable_error;
+ 1582 : /* continue, as we are already exiting */
+ 1583 : /* LCOV_EXCL_STOP */
+ 1584 : }
+ 1585 : } else {
+ 1586 3 : msg_status("Nothing to do\n");
+ 1587 : }
+ 1588 : }
+ 1589 :
+ 1590 574 : for (l = 0; l < state->level; ++l) {
+ 1591 487 : ret = parity_close(&parity_handle[l]);
+ 1592 487 : if (ret == -1) {
+ 1593 : /* LCOV_EXCL_START */
+ 1594 : log_fatal("DANGER! Unexpected close error in %s disk.\n", lev_name(l));
+ 1595 : ++unrecoverable_error;
+ 1596 : /* continue, as we are already exiting */
+ 1597 : /* LCOV_EXCL_STOP */
+ 1598 : }
+ 1599 : }
+ 1600 :
+ 1601 : /* abort if required */
+ 1602 87 : if (unrecoverable_error != 0)
+ 1603 12 : return -1;
+ 1604 75 : return 0;
+ 1605 : }
+ 1606 :
diff --git a/cov/cmdline/unix.c.func-sort-c.html b/cov/cmdline/unix.c.func-sort-c.html
index 9a1a9433..d6c41af0 100644
--- a/cov/cmdline/unix.c.func-sort-c.html
+++ b/cov/cmdline/unix.c.func-sort-c.html
@@ -61,11 +61,11 @@
| tick |
- 3816813 |
+ 3819196 |
| open_noatime |
- 1719371 |
+ 1719485 |
| filephy |
@@ -73,23 +73,23 @@
| devuuid |
- 5624 |
+ 5630 |
| devuuid_dev |
- 5620 |
+ 5626 |
| fsinfo |
- 5477 |
+ 5483 |
| randomize |
- 280 |
+ 281 |
| os_init |
- 269 |
+ 270 |
| os_done |
@@ -100,12 +100,12 @@
191 |
- | devresolve |
+ devresolve_sys |
191 |
- | devresolve_sys |
- 191 |
+ devresolve |
+ 172 |
| devread |
diff --git a/cov/cmdline/unix.c.func.html b/cov/cmdline/unix.c.func.html
index 0abc1827..6f1fae44 100644
--- a/cov/cmdline/unix.c.func.html
+++ b/cov/cmdline/unix.c.func.html
@@ -81,7 +81,7 @@
| devresolve |
- 191 |
+ 172 |
| devresolve_proc |
@@ -109,7 +109,7 @@
| devuuid |
- 5624 |
+ 5630 |
| devuuid_blkid |
@@ -117,7 +117,7 @@
| devuuid_dev |
- 5620 |
+ 5626 |
| direct_size |
@@ -133,11 +133,11 @@
| fsinfo |
- 5477 |
+ 5483 |
| open_noatime |
- 1719371 |
+ 1719485 |
| os_clear |
@@ -149,11 +149,11 @@
| os_init |
- 269 |
+ 270 |
| randomize |
- 280 |
+ 281 |
| stat_desc |
@@ -177,7 +177,7 @@
| tick |
- 3816813 |
+ 3819196 |
| tick_ms |
diff --git a/cov/cmdline/unix.c.gcov.html b/cov/cmdline/unix.c.gcov.html
index 4f7defe9..8cf5fd09 100644
--- a/cov/cmdline/unix.c.gcov.html
+++ b/cov/cmdline/unix.c.gcov.html
@@ -90,15 +90,15 @@
28 : int exit_failure = 1;
29 : int exit_sync_needed = 2;
30 :
- 31 1719371 : int open_noatime(const char* file, int flags)
+ 31 1719485 : int open_noatime(const char* file, int flags)
32 : {
33 : #ifdef O_NOATIME
- 34 1719371 : int f = open(file, flags | O_NOATIME);
+ 34 1719485 : int f = open(file, flags | O_NOATIME);
35 :
36 : /* only root is allowed to use O_NOATIME, in case retry without it */
- 37 1719426 : if (f == -1 && errno == EPERM)
+ 37 1719550 : if (f == -1 && errno == EPERM)
38 0 : f = open(file, flags);
- 39 1719420 : return f;
+ 39 1719558 : return f;
40 : #else
41 : return open(file, flags);
42 : #endif
@@ -324,23 +324,23 @@
262 : }
263 :
264 191 : ret = close(f);
- 265 190 : if (ret != 0) {
+ 265 191 : if (ret != 0) {
266 : /* LCOV_EXCL_START */
267 : log_fatal("Failed to close '%s'.\n", path);
268 : return -1;
269 : /* LCOV_EXCL_STOP */
270 : }
271 :
- 272 190 : buf[len] = 0;
- 273 190 : tag_len = strlen(tag);
+ 272 191 : buf[len] = 0;
+ 273 191 : tag_len = strlen(tag);
274 :
- 275 3321 : for (i = buf; *i; ++i) {
- 276 3321 : char* p = i;
+ 275 3324 : for (i = buf; *i; ++i) {
+ 276 3324 : char* p = i;
277 :
278 : /* start with a space */
- 279 3321 : if (p != buf) {
- 280 3130 : if (!isspace(*p))
- 281 2749 : continue;
+ 279 3324 : if (p != buf) {
+ 280 3133 : if (!isspace(*p))
+ 281 2751 : continue;
282 382 : ++p;
283 : }
284 :
@@ -368,18 +368,18 @@
306 191 : e = i;
307 1020 : while (*e != 0 && !isspace(*e))
308 638 : ++e;
- 309 190 : *e = 0;
+ 309 191 : *e = 0;
310 :
- 311 190 : if (!*i) {
+ 311 191 : if (!*i) {
312 : /* LCOV_EXCL_START */
313 : log_fatal("Empty tag '%s' for '%s'.\n", tag, path);
314 : return -1;
315 : /* LCOV_EXCL_STOP */
316 : }
317 :
- 318 190 : pathprint(value, value_size, "%s", i);
+ 318 191 : pathprint(value, value_size, "%s", i);
319 :
- 320 190 : return 0;
+ 320 191 : return 0;
321 : }
322 : #endif
323 :
@@ -407,7 +407,7 @@
345 : }
346 :
347 : /* set the real device path */
- 348 190 : pathprint(path, path_size, "/dev/%s", buf);
+ 348 191 : pathprint(path, path_size, "/dev/%s", buf);
349 :
350 : /* check the device */
351 191 : if (stat(path, &st) != 0) {
@@ -416,14 +416,14 @@
354 : return -1;
355 : /* LCOV_EXCL_STOP */
356 : }
- 357 190 : if (st.st_rdev != device) {
+ 357 191 : if (st.st_rdev != device) {
358 : /* LCOV_EXCL_START */
359 : log_tag("resolve:sys:%u:%u: unexpected device '%u:%u' for '%s'.\n", major(device), minor(device), major(st.st_rdev), minor(st.st_rdev), path);
360 : return -1;
361 : /* LCOV_EXCL_STOP */
362 : }
363 :
- 364 190 : log_tag("resolve:sys:%u:%u:%s: found\n", major(device), minor(device), path);
+ 364 191 : log_tag("resolve:sys:%u:%u:%s: found\n", major(device), minor(device), path);
365 :
366 191 : return 0;
367 : }
@@ -433,9 +433,9 @@
371 : * Get the device file from the device number.
372 : */
373 : #if HAVE_LINUX_DEVICE
- 374 191 : static int devresolve(uint64_t device, char* path, size_t path_size)
+ 374 172 : static int devresolve(uint64_t device, char* path, size_t path_size)
375 : {
- 376 191 : if (devresolve_sys(device, path, path_size) == 0)
+ 376 172 : if (devresolve_sys(device, path, path_size) == 0)
377 191 : return 0;
378 :
379 0 : return -1;
@@ -456,7 +456,7 @@
394 : * in /dev/disk/by-uuid/.
395 : */
396 : #if HAVE_LINUX_DEVICE
- 397 5620 : static int devuuid_dev(uint64_t device, char* uuid, size_t uuid_size)
+ 397 5626 : static int devuuid_dev(uint64_t device, char* uuid, size_t uuid_size)
398 : {
399 : int ret;
400 : DIR* d;
@@ -464,47 +464,47 @@
402 : struct stat st;
403 :
404 : /* scan the UUID directory searching for the device */
- 405 5620 : d = opendir("/dev/disk/by-uuid");
- 406 5620 : if (!d) {
+ 405 5626 : d = opendir("/dev/disk/by-uuid");
+ 406 5626 : if (!d) {
407 0 : log_tag("uuid:by-uuidd:%u:%u: opendir(/dev/disk/by-uuid) failed, %s\n", major(device), minor(device), strerror(errno));
408 : /* directory missing?, likely we are not in Linux */
409 0 : return -1;
410 : }
411 :
- 412 95540 : while ((dd = readdir(d)) != 0) {
+ 412 95642 : while ((dd = readdir(d)) != 0) {
413 : /* skip "." and ".." files, UUIDs never start with '.' */
- 414 89920 : if (dd->d_name[0] == '.')
- 415 11240 : continue;
+ 414 90016 : if (dd->d_name[0] == '.')
+ 415 11252 : continue;
416 :
- 417 78680 : ret = fstatat(dirfd(d), dd->d_name, &st, 0);
- 418 78680 : if (ret != 0) {
+ 417 78764 : ret = fstatat(dirfd(d), dd->d_name, &st, 0);
+ 418 78764 : if (ret != 0) {
419 0 : log_tag("uuid:by-uuidd:%u:%u: fstatat(%s) failed, %s\n", major(device), minor(device), dd->d_name, strerror(errno));
420 : /* generic error, ignore and continue the search */
421 0 : continue;
422 : }
423 :
424 : /* if it matches, we have the uuid */
- 425 78680 : if (S_ISBLK(st.st_mode) && st.st_rdev == (dev_t)device) {
+ 425 78764 : if (S_ISBLK(st.st_mode) && st.st_rdev == (dev_t)device) {
426 : char buf[PATH_MAX];
427 : char path[PATH_MAX];
428 :
429 : /* resolve the link */
- 430 5620 : pathprint(path, sizeof(path), "/dev/disk/by-uuid/%s", dd->d_name);
- 431 5620 : ret = readlink(path, buf, sizeof(buf));
- 432 5620 : if (ret < 0 || ret == sizeof(buf)) {
+ 430 5626 : pathprint(path, sizeof(path), "/dev/disk/by-uuid/%s", dd->d_name);
+ 431 5626 : ret = readlink(path, buf, sizeof(buf));
+ 432 5626 : if (ret < 0 || ret == sizeof(buf)) {
433 0 : log_tag("uuid:by-uuidd:%u:%u: readlink(/dev/disk/by-uuid/%s) failed, %s\n", major(device), minor(device), dd->d_name, strerror(errno));
434 : /* generic error, ignore and continue the search */
435 0 : continue;
436 : }
- 437 5620 : buf[ret] = 0;
+ 437 5626 : buf[ret] = 0;
438 :
439 : /* found */
- 440 5620 : pathcpy(uuid, uuid_size, dd->d_name);
+ 440 5626 : pathcpy(uuid, uuid_size, dd->d_name);
441 :
- 442 5620 : log_tag("uuid:by-uuid:%u:%u:%s: found %s\n", major(device), minor(device), uuid, buf);
+ 442 5626 : log_tag("uuid:by-uuid:%u:%u:%s: found %s\n", major(device), minor(device), uuid, buf);
443 :
- 444 5620 : closedir(d);
- 445 5620 : return 0;
+ 444 5626 : closedir(d);
+ 445 5626 : return 0;
446 : }
447 : }
448 :
@@ -555,11 +555,11 @@
493 : }
494 : #endif
495 :
- 496 5624 : int devuuid(uint64_t device, char* uuid, size_t uuid_size)
+ 496 5630 : int devuuid(uint64_t device, char* uuid, size_t uuid_size)
497 : {
498 : #if HAVE_LINUX_DEVICE
499 : /* if the major is the null device */
- 500 5624 : if (major(device) == 0) {
+ 500 5630 : if (major(device) == 0) {
501 : /* obtain the real device */
502 4 : if (devdereference(device, &device) != 0) {
503 : /* LCOV_EXCL_START */
@@ -571,8 +571,8 @@
509 :
510 : /* first try with the /dev/disk/by-uuid version */
511 : #if HAVE_LINUX_DEVICE
- 512 5620 : if (devuuid_dev(device, uuid, uuid_size) == 0)
- 513 5620 : return 0;
+ 512 5626 : if (devuuid_dev(device, uuid, uuid_size) == 0)
+ 513 5626 : return 0;
514 : #else
515 : log_tag("uuid:by-uuidd:%u:%u: by-uuid not supported\n", major(device), minor(device));
516 : #endif
@@ -687,7 +687,7 @@
625 0 : return 0;
626 : }
627 :
- 628 5477 : int fsinfo(const char* path, int* has_persistent_inode, uint64_t* total_space, uint64_t* free_space)
+ 628 5483 : int fsinfo(const char* path, int* has_persistent_inode, uint64_t* total_space, uint64_t* free_space)
629 : {
630 : char type[64];
631 : const char* ptype;
@@ -695,7 +695,7 @@
633 : #if HAVE_STATFS
634 : struct statfs st;
635 :
- 636 5477 : if (statfs(path, &st) != 0) {
+ 636 5483 : if (statfs(path, &st) != 0) {
637 : char dir[PATH_MAX];
638 : char* slash;
639 :
@@ -723,17 +723,17 @@
661 : #endif
662 :
663 : /* to get the fs type check "man stat" or "stat -f -t FILE" */
- 664 5477 : if (has_persistent_inode) {
+ 664 5483 : if (has_persistent_inode) {
665 : #if HAVE_STATFS && HAVE_STRUCT_STATFS_F_TYPE
- 666 569 : switch (st.f_type) {
+ 666 575 : switch (st.f_type) {
667 : case 0x65735546 : /* FUSE, "fuseblk" in the stat command */
668 : case 0x4d44 : /* VFAT, "msdos" in the stat command */
669 0 : *has_persistent_inode = 0;
670 0 : break;
671 : default :
672 : /* by default assume yes */
- 673 569 : *has_persistent_inode = 1;
- 674 569 : break;
+ 673 575 : *has_persistent_inode = 1;
+ 674 575 : break;
675 : }
676 : #else
677 : /* by default assume yes */
@@ -741,7 +741,7 @@
679 : #endif
680 : }
681 :
- 682 5477 : if (total_space) {
+ 682 5483 : if (total_space) {
683 : #if HAVE_STATFS
684 4908 : *total_space = st.f_bsize * (uint64_t)st.f_blocks;
685 : #else
@@ -749,7 +749,7 @@
687 : #endif
688 : }
689 :
- 690 5477 : if (free_space) {
+ 690 5483 : if (free_space) {
691 : #if HAVE_STATFS
692 4908 : *free_space = st.f_bsize * (uint64_t)st.f_bfree;
693 : #else
@@ -764,10 +764,10 @@
702 : #elif HAVE_STATFS && HAVE_STRUCT_STATFS_F_TYPE
703 : /* get the filesystem type from f_type (Linux) */
704 : /* from: https://github.com/influxdata/gopsutil/blob/master/disk/disk_linux.go */
- 705 5477 : switch (st.f_type) {
+ 705 5483 : switch (st.f_type) {
706 0 : case 0x65735546 : ptype = "fuseblk"; break;
707 0 : case 0x4D44 : ptype = "vfat/msdos"; break;
- 708 5477 : case 0xEF53 : ptype = "ext2/3/4"; break;
+ 708 5483 : case 0xEF53 : ptype = "ext2/3/4"; break;
709 0 : case 0x6969 : ptype = "nfs"; break; /* remote */
710 0 : case 0x6E667364 : ptype = "nfsd"; break; /* remote */
711 0 : case 0x517B : ptype = "smb"; break; /* remote */
@@ -786,12 +786,12 @@
724 : ptype = "unknown";
725 : #endif
726 :
- 727 5477 : log_tag("statfs:%s: %s \n", ptype, path);
+ 727 5483 : log_tag("statfs:%s: %s \n", ptype, path);
728 :
- 729 5477 : return 0;
+ 729 5483 : return 0;
730 : }
731 :
- 732 3816813 : uint64_t tick(void)
+ 732 3819196 : uint64_t tick(void)
733 : {
734 : #if HAVE_MACH_ABSOLUTE_TIME
735 : /* for Mac OS X */
@@ -802,14 +802,14 @@
740 :
741 : /* nanosecond precision with clock_gettime() */
742 : #if defined(CLOCK_MONOTONIC_RAW)
- 743 3816813 : if (clock_gettime(CLOCK_MONOTONIC_RAW, &tv) != 0) {
+ 743 3819196 : if (clock_gettime(CLOCK_MONOTONIC_RAW, &tv) != 0) {
744 : #else
745 : if (clock_gettime(CLOCK_MONOTONIC, &tv) != 0) {
746 : #endif
747 0 : return 0;
748 : }
749 :
- 750 3816813 : return tv.tv_sec * 1000000000ULL + tv.tv_nsec;
+ 750 3819196 : return tv.tv_sec * 1000000000ULL + tv.tv_nsec;
751 : #else
752 : /* other platforms */
753 : struct timeval tv;
@@ -833,25 +833,25 @@
771 65 : return tv.tv_sec * 1000ULL + tv.tv_usec / 1000;
772 : }
773 :
- 774 280 : int randomize(void* ptr, size_t size)
+ 774 281 : int randomize(void* ptr, size_t size)
775 : {
776 : int f;
777 : ssize_t ret;
778 :
- 779 280 : f = open("/dev/urandom", O_RDONLY);
- 780 280 : if (f == -1)
+ 779 281 : f = open("/dev/urandom", O_RDONLY);
+ 780 281 : if (f == -1)
781 0 : return -1;
782 :
- 783 280 : ret = read(f, ptr, size);
- 784 280 : if (ret < 0 || (size_t)ret != size) {
+ 783 281 : ret = read(f, ptr, size);
+ 784 281 : if (ret < 0 || (size_t)ret != size) {
785 0 : close(f);
786 0 : return -1;
787 : }
788 :
- 789 280 : if (close(f) != 0)
+ 789 281 : if (close(f) != 0)
790 0 : return -1;
791 :
- 792 280 : return 0;
+ 792 281 : return 0;
793 : }
794 :
795 : /**
@@ -1477,12 +1477,12 @@
1415 3 : return device_thread(low, func);
1416 : }
1417 :
- 1418 269 : void os_init(int opt)
+ 1418 270 : void os_init(int opt)
1419 : {
1420 : #if HAVE_BLKID
1421 : int ret;
- 1422 269 : ret = blkid_get_cache(&cache, NULL);
- 1423 269 : if (ret != 0) {
+ 1422 270 : ret = blkid_get_cache(&cache, NULL);
+ 1423 270 : if (ret != 0) {
1424 : /* LCOV_EXCL_START */
1425 : log_fatal("WARNING Failed to get blkid cache\n");
1426 : /* LCOV_EXCL_STOP */
@@ -1490,7 +1490,7 @@
1428 : #endif
1429 :
1430 : (void)opt;
- 1431 269 : }
+ 1431 270 : }
1432 :
1433 247 : void os_done(void)
1434 : {
diff --git a/cov/cmdline/util.c.func-sort-c.html b/cov/cmdline/util.c.func-sort-c.html
index 54bd9b21..9b60f2aa 100644
--- a/cov/cmdline/util.c.func-sort-c.html
+++ b/cov/cmdline/util.c.func-sort-c.html
@@ -61,23 +61,23 @@
| util_rotl32 |
- 854114224 |
+ 854131328 |
| util_rotl64 |
- 512217108 |
+ 512341560 |
| memhash |
- 5937808 |
+ 5938723 |
| crc32c_x86 |
- 646614 |
+ 646609 |
| memdiff |
- 93184 |
+ 93321 |
| malloc_nofail_vector_align |
@@ -85,27 +85,27 @@
| mtest_vector |
- 1951 |
+ 1953 |
| malloc_nofail_test |
- 1951 |
+ 1953 |
| fast_mtest_vector |
- 1951 |
+ 1953 |
| crc32c_gen |
- 361 |
+ 345 |
| crc32c_init |
- 285 |
+ 286 |
| lock_lock |
- 260 |
+ 261 |
| lock_unlock |
diff --git a/cov/cmdline/util.c.func.html b/cov/cmdline/util.c.func.html
index d471f99a..f2fb5161 100644
--- a/cov/cmdline/util.c.func.html
+++ b/cov/cmdline/util.c.func.html
@@ -61,19 +61,19 @@
| crc32c_gen |
- 361 |
+ 345 |
| crc32c_init |
- 285 |
+ 286 |
| crc32c_x86 |
- 646614 |
+ 646609 |
| fast_mtest_vector |
- 1951 |
+ 1953 |
| hash_config_name |
@@ -81,7 +81,7 @@
| lock_lock |
- 260 |
+ 261 |
| lock_unlock |
@@ -97,7 +97,7 @@
| malloc_nofail_test |
- 1951 |
+ 1953 |
| malloc_nofail_vector_align |
@@ -109,23 +109,23 @@
| memdiff |
- 93184 |
+ 93321 |
| memhash |
- 5937808 |
+ 5938723 |
| mtest_vector |
- 1951 |
+ 1953 |
| util_rotl32 |
- 854114224 |
+ 854131328 |
| util_rotl64 |
- 512217108 |
+ 512341560 |
diff --git a/cov/cmdline/util.c.gcov.html b/cov/cmdline/util.c.gcov.html
index 050d6610..467c0b8d 100644
--- a/cov/cmdline/util.c.gcov.html
+++ b/cov/cmdline/util.c.gcov.html
@@ -151,15 +151,15 @@
89 0 : return ptr;
90 : }
91 :
- 92 1951 : void* malloc_nofail_test(size_t size)
+ 92 1953 : void* malloc_nofail_test(size_t size)
93 : {
94 : void* ptr;
95 :
- 96 1951 : ptr = malloc_nofail(size);
+ 96 1953 : ptr = malloc_nofail(size);
97 :
- 98 1951 : mtest_vector(1, size, &ptr);
+ 98 1953 : mtest_vector(1, size, &ptr);
99 :
- 100 1951 : return ptr;
+ 100 1953 : return ptr;
101 : }
102 :
103 : /**
@@ -168,40 +168,40 @@
106 : * It's similar at raid_mtest_vector() but faster because
107 : * we have a lot of buffers to verify.
108 : */
- 109 1951 : static int fast_mtest_vector(int n, size_t size, void** vv)
+ 109 1953 : static int fast_mtest_vector(int n, size_t size, void** vv)
110 : {
111 : int i, j;
112 :
113 : /* test with all the bits */
- 114 17559 : for (i = 0; i < 8; ++i) {
- 115 15608 : unsigned char value = 1 << i;
+ 114 17577 : for (i = 0; i < 8; ++i) {
+ 115 15624 : unsigned char value = 1 << i;
116 :
117 : /* fill first */
- 118 15608 : memset(vv[0], value, size);
+ 118 15624 : memset(vv[0], value, size);
119 :
120 : /* copy to the next */
- 121 15608 : for (j = 1; j < n; ++j)
+ 121 15624 : for (j = 1; j < n; ++j)
122 0 : memcpy(vv[j], vv[j - 1], size);
123 :
124 : /* compare with the previous */
- 125 31216 : for (j = 1; j <= n; ++j)
- 126 15608 : if (memcmp(vv[j % n], vv[j - 1], size) != 0)
+ 125 31248 : for (j = 1; j <= n; ++j)
+ 126 15624 : if (memcmp(vv[j % n], vv[j - 1], size) != 0)
127 0 : return -1;
128 : }
129 :
- 130 1951 : return 0;
+ 130 1953 : return 0;
131 : }
132 :
- 133 1951 : void mtest_vector(int n, size_t size, void** vv)
+ 133 1953 : void mtest_vector(int n, size_t size, void** vv)
134 : {
- 135 1951 : if (fast_mtest_vector(n, size, vv) != 0) {
+ 135 1953 : if (fast_mtest_vector(n, size, vv) != 0) {
136 : /* LCOV_EXCL_START */
137 : log_fatal("DANGER! Your RAM memory is broken! DO NOT PROCEED UNTIL FIXED!\n");
138 : log_fatal("Try running a memory test like http://www.memtest86.com/\n");
139 : exit(EXIT_FAILURE);
140 : /* LCOV_EXCL_STOP */
141 : }
- 142 1951 : }
+ 142 1953 : }
143 :
144 : /****************************************************************************/
145 : /* crc */
@@ -478,42 +478,42 @@
416 : int crc_x86;
417 : #endif
418 :
- 419 361 : uint32_t crc32c_gen(uint32_t crc, const unsigned char* ptr, unsigned size)
+ 419 345 : uint32_t crc32c_gen(uint32_t crc, const unsigned char* ptr, unsigned size)
420 : {
- 421 361 : crc ^= CRC_IV;
+ 421 345 : crc ^= CRC_IV;
422 :
- 423 361 : crc = crc32c_gen_plain(crc, ptr, size);
+ 423 345 : crc = crc32c_gen_plain(crc, ptr, size);
424 :
- 425 361 : crc ^= CRC_IV;
+ 425 345 : crc ^= CRC_IV;
426 :
- 427 361 : return crc;
+ 427 345 : return crc;
428 : }
429 :
430 : #if HAVE_SSE42
- 431 646614 : uint32_t crc32c_x86(uint32_t crc, const unsigned char* ptr, unsigned size)
+ 431 646609 : uint32_t crc32c_x86(uint32_t crc, const unsigned char* ptr, unsigned size)
432 : {
- 433 646614 : crc ^= CRC_IV;
+ 433 646609 : crc ^= CRC_IV;
434 :
- 435 646614 : crc = crc32c_x86_plain(crc, ptr, size);
+ 435 646609 : crc = crc32c_x86_plain(crc, ptr, size);
436 :
- 437 646610 : crc ^= CRC_IV;
+ 437 646607 : crc ^= CRC_IV;
438 :
- 439 646610 : return crc;
+ 439 646607 : return crc;
440 : }
441 : #endif
442 :
443 : uint32_t (*crc32c)(uint32_t crc, const unsigned char* ptr, unsigned size);
444 :
- 445 285 : void crc32c_init(void)
+ 445 286 : void crc32c_init(void)
446 : {
- 447 285 : crc32c = crc32c_gen;
+ 447 286 : crc32c = crc32c_gen;
448 : #if HAVE_SSE42
- 449 285 : if (raid_cpu_has_crc32()) {
- 450 283 : crc_x86 = 1;
- 451 283 : crc32c = crc32c_x86;
+ 449 286 : if (raid_cpu_has_crc32()) {
+ 450 284 : crc_x86 = 1;
+ 451 284 : crc32c = crc32c_x86;
452 : }
453 : #endif
- 454 285 : }
+ 454 286 : }
455 :
456 : /****************************************************************************/
457 : /* byte operations */
@@ -522,14 +522,14 @@
460 : * Rotate left.
461 : * In x86/x64 they are optimized with a single assembler instruction.
462 : */
- 463 854114224 : static inline uint32_t util_rotl32(uint32_t x, int8_t r)
+ 463 854131328 : static inline uint32_t util_rotl32(uint32_t x, int8_t r)
464 : {
- 465 854114224 : return (x << r) | (x >> (32 - r));
+ 465 854131328 : return (x << r) | (x >> (32 - r));
466 : }
467 :
- 468 512217108 : static inline uint64_t util_rotl64(uint64_t x, int8_t r)
+ 468 512341560 : static inline uint64_t util_rotl64(uint64_t x, int8_t r)
469 : {
- 470 512217108 : return (x << r) | (x >> (64 - r));
+ 470 512341560 : return (x << r) | (x >> (64 - r));
471 : }
472 :
473 : /**
@@ -570,15 +570,15 @@
508 : #include "murmur3.c"
509 : #include "spooky2.c"
510 :
- 511 5937808 : void memhash(unsigned kind, const unsigned char* seed, void* digest, const void* src, size_t size)
+ 511 5938723 : void memhash(unsigned kind, const unsigned char* seed, void* digest, const void* src, size_t size)
512 : {
- 513 5937808 : switch (kind) {
+ 513 5938723 : switch (kind) {
514 : case HASH_MURMUR3 :
- 515 2076827 : MurmurHash3_x86_128(src, size, seed, digest);
- 516 2076827 : break;
+ 515 2076854 : MurmurHash3_x86_128(src, size, seed, digest);
+ 516 2076854 : break;
517 : case HASH_SPOOKY2 :
- 518 3860981 : SpookyHash128(src, size, seed, digest);
- 519 3860981 : break;
+ 518 3861869 : SpookyHash128(src, size, seed, digest);
+ 519 3861869 : break;
520 : default :
521 : /* LCOV_EXCL_START */
522 : log_fatal("Internal inconsistency in hash function %u\n", kind);
@@ -586,7 +586,7 @@
524 : break;
525 : /* LCOV_EXCL_STOP */
526 : }
- 527 5937808 : }
+ 527 5938723 : }
528 :
529 42 : const char* hash_config_name(unsigned kind)
530 : {
@@ -601,49 +601,49 @@
539 : }
540 : }
541 :
- 542 93184 : unsigned memdiff(const unsigned char* data1, const unsigned char* data2, size_t size)
+ 542 93321 : unsigned memdiff(const unsigned char* data1, const unsigned char* data2, size_t size)
543 : {
544 : size_t i;
545 : unsigned count;
546 :
- 547 93184 : count = 0;
- 548 80903648 : for (i = 0; i < size; ++i) {
+ 547 93321 : count = 0;
+ 548 80898921 : for (i = 0; i < size; ++i) {
549 : unsigned j;
- 550 80810464 : unsigned char diff = data1[i] ^ data2[i];
- 551 727294176 : for (j = 0; j < 8; ++j) {
- 552 646483712 : if ((diff & 1) != 0)
- 553 311410983 : ++count;
- 554 646483712 : diff >>= 1;
+ 550 80805600 : unsigned char diff = data1[i] ^ data2[i];
+ 551 727250400 : for (j = 0; j < 8; ++j) {
+ 552 646444800 : if ((diff & 1) != 0)
+ 553 311410136 : ++count;
+ 554 646444800 : diff >>= 1;
555 : }
556 : }
557 :
- 558 93184 : return count;
+ 558 93321 : return count;
559 : }
560 :
561 : /****************************************************************************/
562 : /* lock */
563 :
564 : #if HAVE_LOCKFILE
- 565 260 : int lock_lock(const char* file)
+ 565 261 : int lock_lock(const char* file)
566 : {
567 : int f;
568 :
- 569 260 : f = open(file, O_CREAT | O_TRUNC | O_WRONLY, 0600);
- 570 260 : if (f == -1) {
+ 569 261 : f = open(file, O_CREAT | O_TRUNC | O_WRONLY, 0600);
+ 570 261 : if (f == -1) {
571 : /* LCOV_EXCL_START */
572 : return -1;
573 : /* LCOV_EXCL_STOP */
574 : }
575 :
576 : /* exclusive lock, not blocking */
- 577 260 : if (flock(f, LOCK_EX | LOCK_NB) == -1) {
+ 577 261 : if (flock(f, LOCK_EX | LOCK_NB) == -1) {
578 : /* LCOV_EXCL_START */
579 : close(f);
580 : return -1;
581 : /* LCOV_EXCL_STOP */
582 : }
583 :
- 584 260 : return f;
+ 584 261 : return f;
585 : }
586 : #endif
587 :
diff --git a/cov/cmdline/util.h.func-sort-c.html b/cov/cmdline/util.h.func-sort-c.html
index 5f32bb8e..0fdb5fd3 100644
--- a/cov/cmdline/util.h.func-sort-c.html
+++ b/cov/cmdline/util.h.func-sort-c.html
@@ -61,19 +61,19 @@
| crc32c_x86_plain |
- 21365714 |
+ 21365408 |
| crc32c_plain |
- 20719102 |
+ 20718802 |
| crc32c_plain_char |
- 3808841 |
+ 3808025 |
| crc32c_gen_plain |
- 361 |
+ 345 |
diff --git a/cov/cmdline/util.h.func.html b/cov/cmdline/util.h.func.html
index bbede01b..2da812ac 100644
--- a/cov/cmdline/util.h.func.html
+++ b/cov/cmdline/util.h.func.html
@@ -61,19 +61,19 @@
| crc32c_gen_plain |
- 361 |
+ 345 |
| crc32c_plain |
- 20719102 |
+ 20718802 |
| crc32c_plain_char |
- 3808841 |
+ 3808025 |
| crc32c_x86_plain |
- 21365714 |
+ 21365408 |
diff --git a/cov/cmdline/util.h.gcov.html b/cov/cmdline/util.h.gcov.html
index 89321798..ec697472 100644
--- a/cov/cmdline/util.h.gcov.html
+++ b/cov/cmdline/util.h.gcov.html
@@ -144,12 +144,12 @@
82 : /**
83 : * Compute CRC-32 (Castagnoli) for a single byte without the IV.
84 : */
- 85 3808841 : static inline uint32_t crc32c_plain_char(uint32_t crc, unsigned char c)
+ 85 3808025 : static inline uint32_t crc32c_plain_char(uint32_t crc, unsigned char c)
86 : {
87 : #if HAVE_SSE42
- 88 3808841 : if (tommy_likely(crc_x86)) {
- 89 3808841 : asm("crc32b %1, %0\n" : "+r" (crc) : "m" (c));
- 90 3808841 : return crc;
+ 88 3808025 : if (tommy_likely(crc_x86)) {
+ 89 3808025 : asm("crc32b %1, %0\n" : "+r" (crc) : "m" (c));
+ 90 3808025 : return crc;
91 : }
92 : #endif
93 0 : return CRC32C_0[(crc ^ c) & 0xff] ^ (crc >> 8);
@@ -158,29 +158,29 @@
96 : /**
97 : * Compute the CRC-32 (Castagnoli) without the IV.
98 : */
- 99 361 : static inline uint32_t crc32c_gen_plain(uint32_t crc, const unsigned char* ptr, unsigned size)
+ 99 345 : static inline uint32_t crc32c_gen_plain(uint32_t crc, const unsigned char* ptr, unsigned size)
100 : {
- 101 22545273 : while (size >= 4) {
- 102 22544551 : crc ^= ptr[0] | (uint32_t)ptr[1] << 8 | (uint32_t)ptr[2] << 16 | (uint32_t)ptr[3] << 24;
- 103 22544551 : crc = CRC32C_3[crc & 0xff] ^ CRC32C_2[(crc >> 8) & 0xff] ^ CRC32C_1[(crc >> 16) & 0xff] ^ CRC32C_0[crc >> 24];
- 104 22544551 : ptr += 4;
- 105 22544551 : size -= 4;
+ 101 21496665 : while (size >= 4) {
+ 102 21495975 : crc ^= ptr[0] | (uint32_t)ptr[1] << 8 | (uint32_t)ptr[2] << 16 | (uint32_t)ptr[3] << 24;
+ 103 21495975 : crc = CRC32C_3[crc & 0xff] ^ CRC32C_2[(crc >> 8) & 0xff] ^ CRC32C_1[(crc >> 16) & 0xff] ^ CRC32C_0[crc >> 24];
+ 104 21495975 : ptr += 4;
+ 105 21495975 : size -= 4;
106 : }
107 :
- 108 731 : while (size) {
+ 108 699 : while (size) {
109 9 : crc = CRC32C_0[(crc ^ *ptr) & 0xff] ^ (crc >> 8);
110 9 : ++ptr;
111 9 : --size;
112 : }
113 :
- 114 361 : return crc;
+ 114 345 : return crc;
115 : }
116 :
117 : /**
118 : * Compute the CRC-32 (Castagnoli) without the IV.
119 : */
120 : #if HAVE_SSE42
- 121 21365714 : static inline uint32_t crc32c_x86_plain(uint32_t crc, const unsigned char* ptr, unsigned size)
+ 121 21365408 : static inline uint32_t crc32c_x86_plain(uint32_t crc, const unsigned char* ptr, unsigned size)
122 : {
123 : #ifdef CONFIG_X86_64
124 : uint64_t crc64 = crc;
@@ -191,30 +191,30 @@
129 : }
130 : crc = crc64;
131 : #else
- 132 387175791 : while (size >= 4) {
- 133 344444363 : asm("crc32l %1, %0\n" : "+r" (crc) : "m" (*(const uint32_t*)ptr));
- 134 344444363 : ptr += 4;
- 135 344444363 : size -= 4;
+ 132 381730335 : while (size >= 4) {
+ 133 338999519 : asm("crc32l %1, %0\n" : "+r" (crc) : "m" (*(const uint32_t*)ptr));
+ 134 338999519 : ptr += 4;
+ 135 338999519 : size -= 4;
136 : }
137 : #endif
- 138 62479703 : while (size) {
- 139 19748275 : asm("crc32b %1, %0\n" : "+r" (crc) : "m" (*ptr));
- 140 19748275 : ++ptr;
- 141 19748275 : --size;
+ 138 62071545 : while (size) {
+ 139 19340729 : asm("crc32b %1, %0\n" : "+r" (crc) : "m" (*ptr));
+ 140 19340729 : ++ptr;
+ 141 19340729 : --size;
142 : }
143 :
- 144 21365714 : return crc;
+ 144 21365408 : return crc;
145 : }
146 : #endif
147 :
148 : /**
149 : * Compute CRC-32 (Castagnoli) without the IV.
150 : */
- 151 20719102 : static inline uint32_t crc32c_plain(uint32_t crc, const unsigned char* ptr, unsigned size)
+ 151 20718802 : static inline uint32_t crc32c_plain(uint32_t crc, const unsigned char* ptr, unsigned size)
152 : {
153 : #if HAVE_SSE42
- 154 20719102 : if (tommy_likely(crc_x86)) {
- 155 20719102 : return crc32c_x86_plain(crc, ptr, size);
+ 154 20718802 : if (tommy_likely(crc_x86)) {
+ 155 20718802 : return crc32c_x86_plain(crc, ptr, size);
156 : }
157 : #endif
158 0 : return crc32c_gen_plain(crc, ptr, size);
diff --git a/cov/index-sort-f.html b/cov/index-sort-f.html
index 369519f1..dc826957 100644
--- a/cov/index-sort-f.html
+++ b/cov/index-sort-f.html
@@ -31,9 +31,9 @@
|
-
-
-
+
+
+
@@ -72,10 +72,10 @@
| cmdline |
-
+
|
- 89.7 % |
- 8598 / 9589 |
+ 90.2 % |
+ 8613 / 9548 |
96.6 % |
482 / 499 |
diff --git a/cov/index-sort-l.html b/cov/index-sort-l.html
index 8df6ac86..593255cc 100644
--- a/cov/index-sort-l.html
+++ b/cov/index-sort-l.html
@@ -31,9 +31,9 @@
|
-
-
-
+
+
+
@@ -72,10 +72,10 @@
| cmdline |
-
+
|
- 89.7 % |
- 8598 / 9589 |
+ 90.2 % |
+ 8613 / 9548 |
96.6 % |
482 / 499 |
diff --git a/cov/index.html b/cov/index.html
index aa99f509..e06fe00f 100644
--- a/cov/index.html
+++ b/cov/index.html
@@ -31,9 +31,9 @@
|
-
-
-
+
+
+
@@ -72,10 +72,10 @@
| cmdline |
-
+
|
- 89.7 % |
- 8598 / 9589 |
+ 90.2 % |
+ 8613 / 9548 |
96.6 % |
482 / 499 |
diff --git a/cov/raid/combo.h.gcov.html b/cov/raid/combo.h.gcov.html
index 8e4fbb08..d55520f8 100644
--- a/cov/raid/combo.h.gcov.html
+++ b/cov/raid/combo.h.gcov.html
@@ -170,10 +170,10 @@
108 : int i;
109 :
110 : (void)n; /* unused, but kept for clarity */
- 111 207805 : assert(0 < r && r <= n);
+ 111 207990 : assert(0 < r && r <= n);
112 :
- 113 689192 : for (i = 0; i < r; ++i)
- 114 481387 : c[i] = i;
+ 113 689341 : for (i = 0; i < r; ++i)
+ 114 481351 : 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 52183 : int i = r - 1; /* present position */
- 124 52183 : int h = n; /* high limit for this position */
+ 123 52204 : int i = r - 1; /* present position */
+ 124 52204 : int h = n; /* high limit for this position */
125 :
126 : recurse:
127 : /* next element at position i */
- 128 85056 : ++c[i];
+ 128 85077 : ++c[i];
129 :
130 : /* if the position has reached the max */
- 131 85056 : if (c[i] >= h) {
+ 131 85077 : if (c[i] >= h) {
132 :
133 : /* if we are at the first level, we have finished */
- 134 45028 : if (i == 0)
- 135 12155 : return 0;
+ 134 45035 : if (i == 0)
+ 135 12162 : return 0;
136 :
137 : /* increase the previous position */
138 32873 : --i;
@@ -202,16 +202,16 @@
140 : goto recurse;
141 : }
142 :
- 143 40028 : ++i;
+ 143 40042 : ++i;
144 :
145 : /* initialize all the next positions, if any */
- 146 62573 : while (i < r) {
+ 146 62587 : 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 40028 : return 1;
+ 152 40042 : 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 de749704..a6582f10 100644
--- a/cov/raid/cpu.h.func-sort-c.html
+++ b/cov/raid/cpu.h.func-sort-c.html
@@ -61,43 +61,43 @@
| raid_cpuid |
- 2079 |
+ 2086 |
| raid_cpu_match_sse |
- 1185 |
+ 1189 |
| raid_cpu_has_ssse3 |
- 587 |
+ 589 |
| raid_cpu_match_avx |
- 317 |
+ 318 |
| raid_cpu_has_avx2 |
- 317 |
+ 318 |
| raid_cpu_has_sse2 |
- 305 |
+ 306 |
| raid_cpu_has_crc32 |
- 293 |
+ 294 |
| raid_cpu_info |
- 277 |
+ 278 |
| raid_cpu_is_atom |
- 273 |
+ 274 |
| raid_cpu_has_slowmult |
- 269 |
+ 270 |
| raid_xgetbv |
diff --git a/cov/raid/cpu.h.func.html b/cov/raid/cpu.h.func.html
index f6f349fc..70b343e1 100644
--- a/cov/raid/cpu.h.func.html
+++ b/cov/raid/cpu.h.func.html
@@ -61,11 +61,11 @@
| raid_cpu_has_avx2 |
- 317 |
+ 318 |
| raid_cpu_has_crc32 |
- 293 |
+ 294 |
| raid_cpu_has_slowextendedreg |
@@ -73,35 +73,35 @@
| raid_cpu_has_slowmult |
- 269 |
+ 270 |
| raid_cpu_has_sse2 |
- 305 |
+ 306 |
| raid_cpu_has_ssse3 |
- 587 |
+ 589 |
| raid_cpu_info |
- 277 |
+ 278 |
| raid_cpu_is_atom |
- 273 |
+ 274 |
| raid_cpu_match_avx |
- 317 |
+ 318 |
| raid_cpu_match_sse |
- 1185 |
+ 1189 |
| raid_cpuid |
- 2079 |
+ 2086 |
| raid_xgetbv |
diff --git a/cov/raid/cpu.h.gcov.html b/cov/raid/cpu.h.gcov.html
index b0e1b857..27729847 100644
--- a/cov/raid/cpu.h.gcov.html
+++ b/cov/raid/cpu.h.gcov.html
@@ -79,9 +79,9 @@
17 :
18 : #ifdef CONFIG_X86
19 :
- 20 2079 : static inline void raid_cpuid(uint32_t func_eax, uint32_t sub_ecx, uint32_t *reg)
+ 20 2086 : static inline void raid_cpuid(uint32_t func_eax, uint32_t sub_ecx, uint32_t *reg)
21 : {
- 22 2079 : asm volatile (
+ 22 2086 : asm volatile (
23 : #if defined(__i386__) && defined(__PIC__)
24 : /* allow compilation in PIC mode saving ebx */
25 : "xchgl %%ebx, %1\n"
@@ -91,11 +91,11 @@
29 : : "0" (func_eax), "2" (sub_ecx)
30 : #else
31 : "cpuid\n"
- 32 2079 : : "=a" (reg[0]), "=b" (reg[1]), "=c" (reg[2]), "=d" (reg[3])
+ 32 2086 : : "=a" (reg[0]), "=b" (reg[1]), "=c" (reg[2]), "=d" (reg[3])
33 : : "0" (func_eax), "2" (sub_ecx)
34 : #endif
35 : );
- 36 2079 : }
+ 36 2086 : }
37 :
38 23 : static inline void raid_xgetbv(uint32_t* reg)
39 : {
@@ -112,26 +112,26 @@
50 :
51 : #define CPU_VENDOR_MAX 13
52 :
- 53 277 : static inline void raid_cpu_info(char *vendor, unsigned *family, unsigned *model)
+ 53 278 : static inline void raid_cpu_info(char *vendor, unsigned *family, unsigned *model)
54 : {
55 : uint32_t reg[4];
56 : unsigned f, ef, m, em;
57 :
- 58 277 : raid_cpuid(0, 0, reg);
+ 58 278 : raid_cpuid(0, 0, reg);
59 :
- 60 277 : ((uint32_t*)vendor)[0] = reg[1];
- 61 277 : ((uint32_t*)vendor)[1] = reg[3];
- 62 277 : ((uint32_t*)vendor)[2] = reg[2];
- 63 277 : vendor[12] = 0;
+ 60 278 : ((uint32_t*)vendor)[0] = reg[1];
+ 61 278 : ((uint32_t*)vendor)[1] = reg[3];
+ 62 278 : ((uint32_t*)vendor)[2] = reg[2];
+ 63 278 : vendor[12] = 0;
64 :
- 65 277 : raid_cpuid(1, 0, reg);
+ 65 278 : raid_cpuid(1, 0, reg);
66 :
- 67 277 : f = (reg[0] >> 8) & 0xF;
- 68 277 : ef = (reg[0] >> 20) & 0xFF;
- 69 277 : m = (reg[0] >> 4) & 0xF;
- 70 277 : em = (reg[0] >> 16) & 0xF;
+ 67 278 : f = (reg[0] >> 8) & 0xF;
+ 68 278 : ef = (reg[0] >> 20) & 0xFF;
+ 69 278 : m = (reg[0] >> 4) & 0xF;
+ 70 278 : em = (reg[0] >> 16) & 0xF;
71 :
- 72 277 : if (strcmp(vendor, "AuthenticAMD") == 0) {
+ 72 278 : if (strcmp(vendor, "AuthenticAMD") == 0) {
73 0 : if (f < 15) {
74 0 : *family = f;
75 0 : *model = m;
@@ -140,31 +140,31 @@
78 0 : *model = m + (em << 4);
79 : }
80 : } else {
- 81 277 : *family = f + ef;
- 82 277 : *model = m + (em << 4);
+ 81 278 : *family = f + ef;
+ 82 278 : *model = m + (em << 4);
83 : }
- 84 277 : }
+ 84 278 : }
85 :
- 86 1185 : static inline int raid_cpu_match_sse(uint32_t cpuid_1_ecx, uint32_t cpuid_1_edx)
+ 86 1189 : static inline int raid_cpu_match_sse(uint32_t cpuid_1_ecx, uint32_t cpuid_1_edx)
87 : {
88 : uint32_t reg[4];
89 :
- 90 1185 : raid_cpuid(1, 0, reg);
- 91 1185 : if ((reg[2] & cpuid_1_ecx) != cpuid_1_ecx)
+ 90 1189 : raid_cpuid(1, 0, reg);
+ 91 1189 : if ((reg[2] & cpuid_1_ecx) != cpuid_1_ecx)
92 18 : return 0;
- 93 1167 : if ((reg[3] & cpuid_1_edx) != cpuid_1_edx)
+ 93 1171 : if ((reg[3] & cpuid_1_edx) != cpuid_1_edx)
94 0 : return 0;
95 :
- 96 1167 : return 1;
+ 96 1171 : return 1;
97 : }
98 :
- 99 317 : static inline int raid_cpu_match_avx(uint32_t cpuid_1_ecx, uint32_t cpuid_7_ebx, uint32_t xcr0)
+ 99 318 : static inline int raid_cpu_match_avx(uint32_t cpuid_1_ecx, uint32_t cpuid_7_ebx, uint32_t xcr0)
100 : {
101 : uint32_t reg[4];
102 :
- 103 317 : raid_cpuid(1, 0, reg);
- 104 317 : if ((reg[2] & cpuid_1_ecx) != cpuid_1_ecx)
- 105 294 : return 0;
+ 103 318 : raid_cpuid(1, 0, reg);
+ 104 318 : if ((reg[2] & cpuid_1_ecx) != cpuid_1_ecx)
+ 105 295 : return 0;
106 :
107 23 : raid_xgetbv(reg);
108 23 : if ((reg[0] & xcr0) != xcr0)
@@ -177,7 +177,7 @@
115 23 : return 1;
116 : }
117 :
- 118 305 : static inline int raid_cpu_has_sse2(void)
+ 118 306 : static inline int raid_cpu_has_sse2(void)
119 : {
120 : /*
121 : * Intel® 64 and IA-32 Architectures Software Developer's Manual
@@ -191,12 +191,12 @@
129 : * 2. Check that the processor supports the SSE and/or SSE2 extensions (true if
130 : * CPUID.01H:EDX.SSE[bit 25] = 1 and/or CPUID.01H:EDX.SSE2[bit 26] = 1).
131 : */
- 132 305 : return raid_cpu_match_sse(
+ 132 306 : return raid_cpu_match_sse(
133 : 0,
134 : 1 << 26); /* SSE2 */
135 : }
136 :
- 137 587 : static inline int raid_cpu_has_ssse3(void)
+ 137 589 : static inline int raid_cpu_has_ssse3(void)
138 : {
139 : /*
140 : * Intel® 64 and IA-32 Architectures Software Developer's Manual
@@ -208,12 +208,12 @@
146 : * Next, use the additional step provided below:
147 : * Check that the processor supports SSSE3 (if CPUID.01H:ECX.SSSE3[bit 9] = 1).
148 : */
- 149 587 : return raid_cpu_match_sse(
+ 149 589 : return raid_cpu_match_sse(
150 : 1 << 9, /* SSSE3 */
151 : 1 << 26); /* SSE2 */
152 : }
153 :
- 154 293 : static inline int raid_cpu_has_crc32(void)
+ 154 294 : static inline int raid_cpu_has_crc32(void)
155 : {
156 : /*
157 : * Intel® 64 and IA-32 Architectures Software Developer's Manual
@@ -224,12 +224,12 @@
162 : * Before an application attempts to use the CRC32 instruction, it must check
163 : * that the processor supports SSE4.2 (if CPUID.01H:ECX.SSE4_2[bit 20] = 1).
164 : */
- 165 293 : return raid_cpu_match_sse(
+ 165 294 : return raid_cpu_match_sse(
166 : 1 << 20, /* CRC32 */
167 : 0);
168 : }
169 :
- 170 317 : static inline int raid_cpu_has_avx2(void)
+ 170 318 : static inline int raid_cpu_has_avx2(void)
171 : {
172 : /*
173 : * Intel Architecture Instruction Set Extensions Programming Reference
@@ -246,7 +246,7 @@
184 : * Application Software must identify that hardware supports AVX, after that it must
185 : * also detect support for AVX2 by checking CPUID.(EAX=07H, ECX=0H):EBX.AVX2[bit 5].
186 : */
- 187 317 : return raid_cpu_match_avx(
+ 187 318 : return raid_cpu_match_avx(
188 : (1 << 27) | (1 << 28), /* OSXSAVE and AVX */
189 : 1 << 5, /* AVX2 */
190 : 3 << 1); /* OS saves XMM and YMM registers */
@@ -277,9 +277,9 @@
215 : /**
216 : * Check if it's an Intel Atom CPU.
217 : */
- 218 273 : static inline int raid_cpu_is_atom(unsigned family, unsigned model)
+ 218 274 : static inline int raid_cpu_is_atom(unsigned family, unsigned model)
219 : {
- 220 273 : if (family != 6)
+ 220 274 : if (family != 6)
221 3 : return 0;
222 :
223 : /*
@@ -300,17 +300,17 @@
238 : * 4D (77) Atom 8C (22 nm) 4 MB L2 (AVN)
239 : * ?? Atom ?C (14 nm) ? MB L2 (DVN)
240 : */
- 241 540 : return model == 28 || model == 38 || model == 54
- 242 270 : || model == 39 || model == 53 || model == 74
- 243 270 : || model == 90 || model == 55 || model == 76
- 244 540 : || model == 93 || model == 77;
+ 241 542 : return model == 28 || model == 38 || model == 54
+ 242 271 : || model == 39 || model == 53 || model == 74
+ 243 271 : || model == 90 || model == 55 || model == 76
+ 244 542 : || model == 93 || model == 77;
245 : }
246 :
247 : /**
248 : * Check if the processor has a slow MULT implementation.
249 : * If yes, it's better to use a hash not based on multiplication.
250 : */
- 251 269 : static inline int raid_cpu_has_slowmult(void)
+ 251 270 : static inline int raid_cpu_has_slowmult(void)
252 : {
253 : char vendor[CPU_VENDOR_MAX];
254 : unsigned family;
@@ -320,9 +320,9 @@
258 : * In some cases Murmur3 based on MUL instruction,
259 : * is a LOT slower than Spooky2 based on SHIFTs.
260 : */
- 261 269 : raid_cpu_info(vendor, &family, &model);
+ 261 270 : raid_cpu_info(vendor, &family, &model);
262 :
- 263 269 : if (strcmp(vendor, "GenuineIntel") == 0) {
+ 263 270 : if (strcmp(vendor, "GenuineIntel") == 0) {
264 : /*
265 : * Intel Atom (Model 28)
266 : * murmur3:378 MB/s, spooky2:3413 MB/s (x86)
@@ -330,11 +330,11 @@
268 : * Intel Atom (Model 77)
269 : * murmur3:1311 MB/s, spooky2:4056 MB/s (x64)
270 : */
- 271 269 : if (raid_cpu_is_atom(family, model))
+ 271 270 : if (raid_cpu_is_atom(family, model))
272 0 : return 1;
273 : }
274 :
- 275 269 : return 0;
+ 275 270 : return 0;
276 : }
277 :
278 : /**
diff --git a/cov/raid/gf.h.gcov.html b/cov/raid/gf.h.gcov.html
index 7e9160c7..4eb56dc0 100644
--- a/cov/raid/gf.h.gcov.html
+++ b/cov/raid/gf.h.gcov.html
@@ -88,7 +88,7 @@
26 : */
27 : static __always_inline uint8_t mul(uint8_t a, uint8_t b)
28 : {
- 29 23795594 : return gfmul[a][b];
+ 29 23792058 : return gfmul[a][b];
30 : }
31 :
32 : /*
@@ -97,9 +97,9 @@
35 : */
36 : static __always_inline uint8_t inv(uint8_t v)
37 : {
- 38 635882 : BUG_ON(v == 0); /* division by zero */
+ 38 635454 : BUG_ON(v == 0); /* division by zero */
39 :
- 40 635882 : return gfinv[v];
+ 40 635454 : return gfinv[v];
41 : }
42 :
43 : /*
@@ -125,7 +125,7 @@
63 : */
64 : static __always_inline uint8_t A(int p, int d)
65 : {
- 66 2605358 : return gfgen[p][d];
+ 66 2604488 : return gfgen[p][d];
67 : }
68 :
69 : /*
@@ -148,12 +148,12 @@
86 : */
87 : static __always_inline uint32_t x2_32(uint32_t v)
88 : {
- 89 33036096 : uint32_t mask = v & 0x80808080U;
+ 89 32577344 : uint32_t mask = v & 0x80808080U;
90 :
- 91 33036096 : mask = (mask << 1) - (mask >> 7);
- 92 33036096 : v = (v << 1) & 0xfefefefeU;
- 93 33036096 : v ^= mask & 0x1d1d1d1dU;
- 94 33036096 : return v;
+ 91 32577344 : mask = (mask << 1) - (mask >> 7);
+ 92 32577344 : v = (v << 1) & 0xfefefefeU;
+ 93 32577344 : v ^= mask & 0x1d1d1d1dU;
+ 94 32577344 : return v;
95 : }
96 :
97 : /*
@@ -161,12 +161,12 @@
99 : */
100 : static __always_inline uint64_t x2_64(uint64_t v)
101 : {
- 102 16518048 : uint64_t mask = v & 0x8080808080808080ULL;
+ 102 16059296 : uint64_t mask = v & 0x8080808080808080ULL;
103 :
- 104 16518048 : mask = (mask << 1) - (mask >> 7);
- 105 16518048 : v = (v << 1) & 0xfefefefefefefefeULL;
- 106 16518048 : v ^= mask & 0x1d1d1d1d1d1d1d1dULL;
- 107 16518048 : return v;
+ 104 16059296 : mask = (mask << 1) - (mask >> 7);
+ 105 16059296 : v = (v << 1) & 0xfefefefefefefefeULL;
+ 106 16059296 : v ^= mask & 0x1d1d1d1d1d1d1d1dULL;
+ 107 16059296 : return v;
108 : }
109 :
110 : /*
@@ -174,12 +174,12 @@
112 : */
113 : static __always_inline uint32_t d2_32(uint32_t v)
114 : {
- 115 12847040 : uint32_t mask = v & 0x01010101U;
+ 115 12388288 : uint32_t mask = v & 0x01010101U;
116 :
- 117 12847040 : mask = (mask << 8) - mask;
- 118 12847040 : v = (v >> 1) & 0x7f7f7f7fU;
- 119 12847040 : v ^= mask & 0x8e8e8e8eU;
- 120 12847040 : return v;
+ 117 12388288 : mask = (mask << 8) - mask;
+ 118 12388288 : v = (v >> 1) & 0x7f7f7f7fU;
+ 119 12388288 : v ^= mask & 0x8e8e8e8eU;
+ 120 12388288 : return v;
121 : }
122 :
123 : /*
diff --git a/cov/raid/int.c.func-sort-c.html b/cov/raid/int.c.func-sort-c.html
index 47981ef9..ae0ae4fb 100644
--- a/cov/raid/int.c.func-sort-c.html
+++ b/cov/raid/int.c.func-sort-c.html
@@ -69,7 +69,7 @@
| raid_gen1_int64 |
- 184 |
+ 182 |
| raid_rec1_int8 |
@@ -77,16 +77,16 @@
| raid_gen1_int32 |
- 112 |
-
-
- | raid_gen2_int64 |
- 47 |
+ 117 |
| raid_gen2_int32 |
47 |
+
+ | raid_gen2_int64 |
+ 45 |
+
| raid_gen3_int8 |
26 |
@@ -97,11 +97,11 @@
| raid_gen5_int8 |
- 18 |
+ 17 |
| raid_gen6_int8 |
- 17 |
+ 15 |
diff --git a/cov/raid/int.c.func.html b/cov/raid/int.c.func.html
index e7929128..1fff2bee 100644
--- a/cov/raid/int.c.func.html
+++ b/cov/raid/int.c.func.html
@@ -61,11 +61,11 @@
| raid_gen1_int32 |
- 112 |
+ 117 |
| raid_gen1_int64 |
- 184 |
+ 182 |
| raid_gen2_int32 |
@@ -73,7 +73,7 @@
| raid_gen2_int64 |
- 47 |
+ 45 |
| raid_gen3_int8 |
@@ -85,11 +85,11 @@
| raid_gen5_int8 |
- 18 |
+ 17 |
| raid_gen6_int8 |
- 17 |
+ 15 |
| raid_rec1_int8 |
diff --git a/cov/raid/int.c.gcov.html b/cov/raid/int.c.gcov.html
index 268fab74..0dbb07c5 100644
--- a/cov/raid/int.c.gcov.html
+++ b/cov/raid/int.c.gcov.html
@@ -80,9 +80,9 @@
18 : /*
19 : * GEN1 (RAID5 with xor) 32bit C implementation
20 : */
- 21 112 : void raid_gen1_int32(int nd, size_t size, void **vv)
+ 21 117 : void raid_gen1_int32(int nd, size_t size, void **vv)
22 : {
- 23 112 : uint8_t **v = (uint8_t **)vv;
+ 23 117 : uint8_t **v = (uint8_t **)vv;
24 : uint8_t *p;
25 : int d, l;
26 : size_t i;
@@ -90,27 +90,27 @@
28 : uint32_t p0;
29 : uint32_t p1;
30 :
- 31 112 : l = nd - 1;
- 32 112 : p = v[nd];
+ 31 117 : l = nd - 1;
+ 32 117 : p = v[nd];
33 :
- 34 3571920 : for (i = 0; i < size; i += 8) {
- 35 3571808 : p0 = v_32(v[l][i]);
- 36 3571808 : p1 = v_32(v[l][i + 4]);
- 37 28575776 : for (d = l - 1; d >= 0; --d) {
- 38 25003968 : p0 ^= v_32(v[d][i]);
- 39 25003968 : p1 ^= v_32(v[d][i + 4]);
+ 34 3735765 : for (i = 0; i < size; i += 8) {
+ 35 3735648 : p0 = v_32(v[l][i]);
+ 36 3735648 : p1 = v_32(v[l][i + 4]);
+ 37 29886496 : for (d = l - 1; d >= 0; --d) {
+ 38 26150848 : p0 ^= v_32(v[d][i]);
+ 39 26150848 : p1 ^= v_32(v[d][i + 4]);
40 : }
- 41 3571808 : v_32(p[i]) = p0;
- 42 3571808 : v_32(p[i + 4]) = p1;
+ 41 3735648 : v_32(p[i]) = p0;
+ 42 3735648 : v_32(p[i + 4]) = p1;
43 : }
- 44 112 : }
+ 44 117 : }
45 :
46 : /*
47 : * GEN1 (RAID5 with xor) 64bit C implementation
48 : */
- 49 184 : void raid_gen1_int64(int nd, size_t size, void **vv)
+ 49 182 : void raid_gen1_int64(int nd, size_t size, void **vv)
50 : {
- 51 184 : uint8_t **v = (uint8_t **)vv;
+ 51 182 : uint8_t **v = (uint8_t **)vv;
52 : uint8_t *p;
53 : int d, l;
54 : size_t i;
@@ -118,20 +118,20 @@
56 : uint64_t p0;
57 : uint64_t p1;
58 :
- 59 184 : l = nd - 1;
- 60 184 : p = v[nd];
+ 59 182 : l = nd - 1;
+ 60 182 : p = v[nd];
61 :
- 62 2965736 : for (i = 0; i < size; i += 16) {
- 63 2965552 : p0 = v_64(v[l][i]);
- 64 2965552 : p1 = v_64(v[l][i + 8]);
- 65 23725072 : for (d = l - 1; d >= 0; --d) {
- 66 20759520 : p0 ^= v_64(v[d][i]);
- 67 20759520 : p1 ^= v_64(v[d][i + 8]);
+ 62 2932966 : for (i = 0; i < size; i += 16) {
+ 63 2932784 : p0 = v_64(v[l][i]);
+ 64 2932784 : p1 = v_64(v[l][i + 8]);
+ 65 23462928 : for (d = l - 1; d >= 0; --d) {
+ 66 20530144 : p0 ^= v_64(v[d][i]);
+ 67 20530144 : p1 ^= v_64(v[d][i + 8]);
68 : }
- 69 2965552 : v_64(p[i]) = p0;
- 70 2965552 : v_64(p[i + 8]) = p1;
+ 69 2932784 : v_64(p[i]) = p0;
+ 70 2932784 : v_64(p[i + 8]) = p1;
71 : }
- 72 184 : }
+ 72 182 : }
73 :
74 : /*
75 : * GEN2 (RAID6 with powers of 2) 32bit C implementation
@@ -177,9 +177,9 @@
115 : /*
116 : * GEN2 (RAID6 with powers of 2) 64bit C implementation
117 : */
- 118 47 : void raid_gen2_int64(int nd, size_t size, void **vv)
+ 118 45 : void raid_gen2_int64(int nd, size_t size, void **vv)
119 : {
- 120 47 : uint8_t **v = (uint8_t **)vv;
+ 120 45 : uint8_t **v = (uint8_t **)vv;
121 : uint8_t *p;
122 : uint8_t *q;
123 : int d, l;
@@ -188,32 +188,32 @@
126 : uint64_t d0, q0, p0;
127 : uint64_t d1, q1, p1;
128 :
- 129 47 : l = nd - 1;
- 130 47 : p = v[nd];
- 131 47 : q = v[nd + 1];
+ 129 45 : l = nd - 1;
+ 130 45 : p = v[nd];
+ 131 45 : q = v[nd + 1];
132 :
- 133 720991 : for (i = 0; i < size; i += 16) {
- 134 720944 : q0 = p0 = v_64(v[l][i]);
- 135 720944 : q1 = p1 = v_64(v[l][i + 8]);
- 136 5768208 : for (d = l - 1; d >= 0; --d) {
- 137 5047264 : d0 = v_64(v[d][i]);
- 138 5047264 : d1 = v_64(v[d][i + 8]);
+ 133 688221 : for (i = 0; i < size; i += 16) {
+ 134 688176 : q0 = p0 = v_64(v[l][i]);
+ 135 688176 : q1 = p1 = v_64(v[l][i + 8]);
+ 136 5506064 : for (d = l - 1; d >= 0; --d) {
+ 137 4817888 : d0 = v_64(v[d][i]);
+ 138 4817888 : d1 = v_64(v[d][i + 8]);
139 :
- 140 5047264 : p0 ^= d0;
- 141 5047264 : p1 ^= d1;
+ 140 4817888 : p0 ^= d0;
+ 141 4817888 : p1 ^= d1;
142 :
- 143 5047264 : q0 = x2_64(q0);
- 144 5047264 : q1 = x2_64(q1);
+ 143 4817888 : q0 = x2_64(q0);
+ 144 4817888 : q1 = x2_64(q1);
145 :
- 146 5047264 : q0 ^= d0;
- 147 5047264 : q1 ^= d1;
+ 146 4817888 : q0 ^= d0;
+ 147 4817888 : q1 ^= d1;
148 : }
- 149 720944 : v_64(p[i]) = p0;
- 150 720944 : v_64(p[i + 8]) = p1;
- 151 720944 : v_64(q[i]) = q0;
- 152 720944 : v_64(q[i + 8]) = q1;
+ 149 688176 : v_64(p[i]) = p0;
+ 150 688176 : v_64(p[i + 8]) = p1;
+ 151 688176 : v_64(q[i]) = q0;
+ 152 688176 : v_64(q[i + 8]) = q1;
153 : }
- 154 47 : }
+ 154 45 : }
155 :
156 : /*
157 : * GEN3 (triple parity with Cauchy matrix) 8bit C implementation
@@ -322,9 +322,9 @@
260 : * But this is only a kind of reference function, and we are not really
261 : * interested in speed.
262 : */
- 263 18 : void raid_gen5_int8(int nd, size_t size, void **vv)
+ 263 17 : void raid_gen5_int8(int nd, size_t size, void **vv)
264 : {
- 265 18 : uint8_t **v = (uint8_t **)vv;
+ 265 17 : uint8_t **v = (uint8_t **)vv;
266 : uint8_t *p;
267 : uint8_t *q;
268 : uint8_t *r;
@@ -335,41 +335,41 @@
273 :
274 : uint8_t d0, t0, s0, r0, q0, p0;
275 :
- 276 18 : l = nd - 1;
- 277 18 : p = v[nd];
- 278 18 : q = v[nd + 1];
- 279 18 : r = v[nd + 2];
- 280 18 : s = v[nd + 3];
- 281 18 : t = v[nd + 4];
+ 276 17 : l = nd - 1;
+ 277 17 : p = v[nd];
+ 278 17 : q = v[nd + 1];
+ 279 17 : r = v[nd + 2];
+ 280 17 : s = v[nd + 3];
+ 281 17 : t = v[nd + 4];
282 :
- 283 4194834 : for (i = 0; i < size; i += 1) {
- 284 4194816 : p0 = q0 = r0 = s0 = t0 = 0;
- 285 33562880 : for (d = l; d > 0; --d) {
- 286 29368064 : d0 = v_8(v[d][i]);
+ 283 3932689 : for (i = 0; i < size; i += 1) {
+ 284 3932672 : p0 = q0 = r0 = s0 = t0 = 0;
+ 285 31465728 : for (d = l; d > 0; --d) {
+ 286 27533056 : d0 = v_8(v[d][i]);
287 :
- 288 29368064 : p0 ^= d0;
- 289 29368064 : q0 ^= gfmul[d0][gfgen[1][d]];
- 290 29368064 : r0 ^= gfmul[d0][gfgen[2][d]];
- 291 29368064 : s0 ^= gfmul[d0][gfgen[3][d]];
- 292 29368064 : t0 ^= gfmul[d0][gfgen[4][d]];
+ 288 27533056 : p0 ^= d0;
+ 289 27533056 : q0 ^= gfmul[d0][gfgen[1][d]];
+ 290 27533056 : r0 ^= gfmul[d0][gfgen[2][d]];
+ 291 27533056 : s0 ^= gfmul[d0][gfgen[3][d]];
+ 292 27533056 : t0 ^= gfmul[d0][gfgen[4][d]];
293 : }
294 :
295 : /* first disk with all coefficients at 1 */
- 296 4194816 : d0 = v_8(v[0][i]);
+ 296 3932672 : d0 = v_8(v[0][i]);
297 :
- 298 4194816 : p0 ^= d0;
- 299 4194816 : q0 ^= d0;
- 300 4194816 : r0 ^= d0;
- 301 4194816 : s0 ^= d0;
- 302 4194816 : t0 ^= d0;
+ 298 3932672 : p0 ^= d0;
+ 299 3932672 : q0 ^= d0;
+ 300 3932672 : r0 ^= d0;
+ 301 3932672 : s0 ^= d0;
+ 302 3932672 : t0 ^= d0;
303 :
- 304 4194816 : v_8(p[i]) = p0;
- 305 4194816 : v_8(q[i]) = q0;
- 306 4194816 : v_8(r[i]) = r0;
- 307 4194816 : v_8(s[i]) = s0;
- 308 4194816 : v_8(t[i]) = t0;
+ 304 3932672 : v_8(p[i]) = p0;
+ 305 3932672 : v_8(q[i]) = q0;
+ 306 3932672 : v_8(r[i]) = r0;
+ 307 3932672 : v_8(s[i]) = s0;
+ 308 3932672 : v_8(t[i]) = t0;
309 : }
- 310 18 : }
+ 310 17 : }
311 :
312 : /*
313 : * GEN6 (hexa parity with Cauchy matrix) 8bit C implementation
@@ -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 17 : void raid_gen6_int8(int nd, size_t size, void **vv)
+ 320 15 : void raid_gen6_int8(int nd, size_t size, void **vv)
321 : {
- 322 17 : uint8_t **v = (uint8_t **)vv;
+ 322 15 : 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 17 : l = nd - 1;
- 335 17 : p = v[nd];
- 336 17 : q = v[nd + 1];
- 337 17 : r = v[nd + 2];
- 338 17 : s = v[nd + 3];
- 339 17 : t = v[nd + 4];
- 340 17 : u = v[nd + 5];
+ 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];
341 :
- 342 3932689 : for (i = 0; i < size; i += 1) {
- 343 3932672 : p0 = q0 = r0 = s0 = t0 = u0 = 0;
- 344 31465728 : for (d = l; d > 0; --d) {
- 345 27533056 : d0 = v_8(v[d][i]);
+ 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]);
346 :
- 347 27533056 : p0 ^= d0;
- 348 27533056 : q0 ^= gfmul[d0][gfgen[1][d]];
- 349 27533056 : r0 ^= gfmul[d0][gfgen[2][d]];
- 350 27533056 : s0 ^= gfmul[d0][gfgen[3][d]];
- 351 27533056 : t0 ^= gfmul[d0][gfgen[4][d]];
- 352 27533056 : u0 ^= gfmul[d0][gfgen[5][d]];
+ 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]];
353 : }
354 :
355 : /* first disk with all coefficients at 1 */
- 356 3932672 : d0 = v_8(v[0][i]);
+ 356 3408384 : d0 = v_8(v[0][i]);
357 :
- 358 3932672 : p0 ^= d0;
- 359 3932672 : q0 ^= d0;
- 360 3932672 : r0 ^= d0;
- 361 3932672 : s0 ^= d0;
- 362 3932672 : t0 ^= d0;
- 363 3932672 : u0 ^= d0;
+ 358 3408384 : p0 ^= d0;
+ 359 3408384 : q0 ^= d0;
+ 360 3408384 : r0 ^= d0;
+ 361 3408384 : s0 ^= d0;
+ 362 3408384 : t0 ^= d0;
+ 363 3408384 : u0 ^= d0;
364 :
- 365 3932672 : v_8(p[i]) = p0;
- 366 3932672 : v_8(q[i]) = q0;
- 367 3932672 : v_8(r[i]) = r0;
- 368 3932672 : v_8(s[i]) = s0;
- 369 3932672 : v_8(t[i]) = t0;
- 370 3932672 : v_8(u[i]) = u0;
+ 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;
371 : }
- 372 17 : }
+ 372 15 : }
373 :
374 : /*
375 : * Recover failure of one data block at index id[0] using parity at index
diff --git a/cov/raid/internal.h.gcov.html b/cov/raid/internal.h.gcov.html
index 2810fbf1..afad0a9c 100644
--- a/cov/raid/internal.h.gcov.html
+++ b/cov/raid/internal.h.gcov.html
@@ -169,11 +169,11 @@
107 : */
108 : static __always_inline void *__align_ptr(void *ptr, uintptr_t size)
109 : {
- 110 711847 : uintptr_t offset = (uintptr_t)ptr;
+ 110 711919 : uintptr_t offset = (uintptr_t)ptr;
111 :
- 112 711847 : offset = (offset + size - 1U) & ~(size - 1U);
+ 112 711919 : offset = (offset + size - 1U) & ~(size - 1U);
113 :
- 114 711847 : return (void *)offset;
+ 114 711919 : return (void *)offset;
115 : }
116 :
117 : /*
@@ -294,7 +294,7 @@
232 : /* that use a weak memory model. To ensure that other processors */
233 : /* see correctly the data written, we use a store-store memory */
234 : /* barrier at the end of the asm code */
- 235 1388678 : asm volatile ("sfence" : : : "memory");
+ 235 1388842 : asm volatile ("sfence" : : : "memory");
236 :
237 : /* clobbers registers used in the asm code */
238 : /* 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 f0eebc82..ffbcc252 100644
--- a/cov/raid/intz.c.func-sort-c.html
+++ b/cov/raid/intz.c.func-sort-c.html
@@ -65,7 +65,7 @@
| raid_genz_int32 |
- 29 |
+ 28 |
diff --git a/cov/raid/intz.c.func.html b/cov/raid/intz.c.func.html
index d03542db..6d2291be 100644
--- a/cov/raid/intz.c.func.html
+++ b/cov/raid/intz.c.func.html
@@ -61,7 +61,7 @@
| raid_genz_int32 |
- 29 |
+ 28 |
| raid_genz_int64 |
diff --git a/cov/raid/intz.c.gcov.html b/cov/raid/intz.c.gcov.html
index 90778a8f..635e0eb1 100644
--- a/cov/raid/intz.c.gcov.html
+++ b/cov/raid/intz.c.gcov.html
@@ -80,9 +80,9 @@
18 : /*
19 : * GENz (triple parity with powers of 2^-1) 32bit C implementation
20 : */
- 21 29 : void raid_genz_int32(int nd, size_t size, void **vv)
+ 21 28 : void raid_genz_int32(int nd, size_t size, void **vv)
22 : {
- 23 29 : uint8_t **v = (uint8_t**)vv;
+ 23 28 : uint8_t **v = (uint8_t**)vv;
24 : uint8_t *p;
25 : uint8_t *q;
26 : uint8_t *r;
@@ -92,41 +92,41 @@
30 : uint32_t d0, r0, q0, p0;
31 : uint32_t d1, r1, q1, p1;
32 :
- 33 29 : l = nd - 1;
- 34 29 : p = v[nd];
- 35 29 : q = v[nd + 1];
- 36 29 : r = v[nd + 2];
+ 33 28 : l = nd - 1;
+ 34 28 : p = v[nd];
+ 35 28 : q = v[nd + 1];
+ 36 28 : r = v[nd + 2];
37 :
- 38 917565 : for (i = 0; i < size; i += 8) {
- 39 917536 : r0 = q0 = p0 = v_32(v[l][i]);
- 40 917536 : r1 = q1 = p1 = v_32(v[l][i + 4]);
- 41 7341056 : for (d = l - 1; d >= 0; --d) {
- 42 6423520 : d0 = v_32(v[d][i]);
- 43 6423520 : d1 = v_32(v[d][i + 4]);
+ 38 884796 : for (i = 0; i < size; i += 8) {
+ 39 884768 : r0 = q0 = p0 = v_32(v[l][i]);
+ 40 884768 : r1 = q1 = p1 = v_32(v[l][i + 4]);
+ 41 7078912 : for (d = l - 1; d >= 0; --d) {
+ 42 6194144 : d0 = v_32(v[d][i]);
+ 43 6194144 : d1 = v_32(v[d][i + 4]);
44 :
- 45 6423520 : p0 ^= d0;
- 46 6423520 : p1 ^= d1;
+ 45 6194144 : p0 ^= d0;
+ 46 6194144 : p1 ^= d1;
47 :
- 48 6423520 : q0 = x2_32(q0);
- 49 6423520 : q1 = x2_32(q1);
+ 48 6194144 : q0 = x2_32(q0);
+ 49 6194144 : q1 = x2_32(q1);
50 :
- 51 6423520 : q0 ^= d0;
- 52 6423520 : q1 ^= d1;
+ 51 6194144 : q0 ^= d0;
+ 52 6194144 : q1 ^= d1;
53 :
- 54 6423520 : r0 = d2_32(r0);
- 55 6423520 : r1 = d2_32(r1);
+ 54 6194144 : r0 = d2_32(r0);
+ 55 6194144 : r1 = d2_32(r1);
56 :
- 57 6423520 : r0 ^= d0;
- 58 6423520 : r1 ^= d1;
+ 57 6194144 : r0 ^= d0;
+ 58 6194144 : r1 ^= d1;
59 : }
- 60 917536 : v_32(p[i]) = p0;
- 61 917536 : v_32(p[i + 4]) = p1;
- 62 917536 : v_32(q[i]) = q0;
- 63 917536 : v_32(q[i + 4]) = q1;
- 64 917536 : v_32(r[i]) = r0;
- 65 917536 : v_32(r[i + 4]) = r1;
+ 60 884768 : v_32(p[i]) = p0;
+ 61 884768 : v_32(p[i + 4]) = p1;
+ 62 884768 : v_32(q[i]) = q0;
+ 63 884768 : v_32(q[i + 4]) = q1;
+ 64 884768 : v_32(r[i]) = r0;
+ 65 884768 : v_32(r[i + 4]) = r1;
66 : }
- 67 29 : }
+ 67 28 : }
68 :
69 : /*
70 : * GENz (triple parity with powers of 2^-1) 64bit C implementation
diff --git a/cov/raid/memory.c.gcov.html b/cov/raid/memory.c.gcov.html
index 36942cce..c141cae2 100644
--- a/cov/raid/memory.c.gcov.html
+++ b/cov/raid/memory.c.gcov.html
@@ -94,7 +94,7 @@
32 12558 : offset = ((uintptr_t)ptr) % align_size;
33 :
34 12558 : if (offset != 0)
- 35 12172 : ptr += align_size - offset;
+ 35 12171 : ptr += align_size - offset;
36 :
37 12558 : return ptr;
38 : }
diff --git a/cov/raid/module.c.func-sort-c.html b/cov/raid/module.c.func-sort-c.html
index 39519b44..185903de 100644
--- a/cov/raid/module.c.func-sort-c.html
+++ b/cov/raid/module.c.func-sort-c.html
@@ -61,7 +61,7 @@
| raid_init |
- 269 |
+ 270 |
| raid_test_rec |
diff --git a/cov/raid/module.c.func.html b/cov/raid/module.c.func.html
index ec058144..7d71c214 100644
--- a/cov/raid/module.c.func.html
+++ b/cov/raid/module.c.func.html
@@ -65,7 +65,7 @@
| raid_init |
- 269 |
+ 270 |
| raid_selftest |
diff --git a/cov/raid/module.c.gcov.html b/cov/raid/module.c.gcov.html
index 3264dd75..4b69d7ae 100644
--- a/cov/raid/module.c.gcov.html
+++ b/cov/raid/module.c.gcov.html
@@ -81,34 +81,34 @@
19 : /*
20 : * Initializes and selects the best algorithm.
21 : */
- 22 269 : void raid_init(void)
+ 22 270 : void raid_init(void)
23 : {
- 24 269 : raid_gen3_ptr = raid_gen3_int8;
- 25 269 : raid_gen_ptr[3] = raid_gen4_int8;
- 26 269 : raid_gen_ptr[4] = raid_gen5_int8;
- 27 269 : raid_gen_ptr[5] = raid_gen6_int8;
+ 24 270 : raid_gen3_ptr = raid_gen3_int8;
+ 25 270 : raid_gen_ptr[3] = raid_gen4_int8;
+ 26 270 : raid_gen_ptr[4] = raid_gen5_int8;
+ 27 270 : raid_gen_ptr[5] = raid_gen6_int8;
28 :
29 : if (sizeof(void *) == 4) {
- 30 269 : raid_gen_ptr[0] = raid_gen1_int32;
- 31 269 : raid_gen_ptr[1] = raid_gen2_int32;
- 32 269 : raid_genz_ptr = raid_genz_int32;
+ 30 270 : raid_gen_ptr[0] = raid_gen1_int32;
+ 31 270 : raid_gen_ptr[1] = raid_gen2_int32;
+ 32 270 : raid_genz_ptr = raid_genz_int32;
33 : } else {
34 : raid_gen_ptr[0] = raid_gen1_int64;
35 : raid_gen_ptr[1] = raid_gen2_int64;
36 : raid_genz_ptr = raid_genz_int64;
37 : }
38 :
- 39 269 : raid_rec_ptr[0] = raid_rec1_int8;
- 40 269 : raid_rec_ptr[1] = raid_rec2_int8;
- 41 269 : raid_rec_ptr[2] = raid_recX_int8;
- 42 269 : raid_rec_ptr[3] = raid_recX_int8;
- 43 269 : raid_rec_ptr[4] = raid_recX_int8;
- 44 269 : raid_rec_ptr[5] = raid_recX_int8;
+ 39 270 : raid_rec_ptr[0] = raid_rec1_int8;
+ 40 270 : raid_rec_ptr[1] = raid_rec2_int8;
+ 41 270 : raid_rec_ptr[2] = raid_recX_int8;
+ 42 270 : raid_rec_ptr[3] = raid_recX_int8;
+ 43 270 : raid_rec_ptr[4] = raid_recX_int8;
+ 44 270 : raid_rec_ptr[5] = raid_recX_int8;
45 :
46 : #ifdef CONFIG_X86
47 : #ifdef CONFIG_SSE2
- 48 269 : if (raid_cpu_has_sse2()) {
- 49 269 : raid_gen_ptr[0] = raid_gen1_sse2;
+ 48 270 : if (raid_cpu_has_sse2()) {
+ 49 270 : raid_gen_ptr[0] = raid_gen1_sse2;
50 : #ifdef CONFIG_X86_64
51 : if (raid_cpu_has_slowextendedreg()) {
52 : raid_gen_ptr[1] = raid_gen2_sse2;
@@ -118,14 +118,14 @@
56 : /* note that raid_cpu_has_slowextendedreg() doesn't affect parz */
57 : raid_genz_ptr = raid_genz_sse2ext;
58 : #else
- 59 269 : raid_gen_ptr[1] = raid_gen2_sse2;
- 60 269 : raid_genz_ptr = raid_genz_sse2;
+ 59 270 : raid_gen_ptr[1] = raid_gen2_sse2;
+ 60 270 : raid_genz_ptr = raid_genz_sse2;
61 : #endif
62 : }
63 : #endif
64 :
65 : #ifdef CONFIG_SSSE3
- 66 269 : if (raid_cpu_has_ssse3()) {
+ 66 270 : if (raid_cpu_has_ssse3()) {
67 : #ifdef CONFIG_X86_64
68 : if (raid_cpu_has_slowextendedreg()) {
69 : raid_gen3_ptr = raid_gen3_ssse3;
@@ -139,22 +139,22 @@
77 : raid_gen_ptr[5] = raid_gen6_ssse3ext;
78 : }
79 : #else
- 80 268 : raid_gen3_ptr = raid_gen3_ssse3;
- 81 268 : raid_gen_ptr[3] = raid_gen4_ssse3;
- 82 268 : raid_gen_ptr[4] = raid_gen5_ssse3;
- 83 268 : raid_gen_ptr[5] = raid_gen6_ssse3;
+ 80 269 : raid_gen3_ptr = raid_gen3_ssse3;
+ 81 269 : raid_gen_ptr[3] = raid_gen4_ssse3;
+ 82 269 : raid_gen_ptr[4] = raid_gen5_ssse3;
+ 83 269 : raid_gen_ptr[5] = raid_gen6_ssse3;
84 : #endif
- 85 268 : raid_rec_ptr[0] = raid_rec1_ssse3;
- 86 268 : raid_rec_ptr[1] = raid_rec2_ssse3;
- 87 268 : raid_rec_ptr[2] = raid_recX_ssse3;
- 88 268 : raid_rec_ptr[3] = raid_recX_ssse3;
- 89 268 : raid_rec_ptr[4] = raid_recX_ssse3;
- 90 268 : raid_rec_ptr[5] = raid_recX_ssse3;
+ 85 269 : raid_rec_ptr[0] = raid_rec1_ssse3;
+ 86 269 : raid_rec_ptr[1] = raid_rec2_ssse3;
+ 87 269 : raid_rec_ptr[2] = raid_recX_ssse3;
+ 88 269 : raid_rec_ptr[3] = raid_recX_ssse3;
+ 89 269 : raid_rec_ptr[4] = raid_recX_ssse3;
+ 90 269 : raid_rec_ptr[5] = raid_recX_ssse3;
91 : }
92 : #endif
93 :
94 : #ifdef CONFIG_AVX2
- 95 269 : if (raid_cpu_has_avx2()) {
+ 95 270 : if (raid_cpu_has_avx2()) {
96 2 : raid_gen_ptr[0] = raid_gen1_avx2;
97 2 : raid_gen_ptr[1] = raid_gen2_avx2;
98 : #ifdef CONFIG_X86_64
@@ -175,8 +175,8 @@
113 : #endif /* CONFIG_X86 */
114 :
115 : /* set the default mode */
- 116 269 : raid_mode(RAID_MODE_CAUCHY);
- 117 269 : }
+ 116 270 : raid_mode(RAID_MODE_CAUCHY);
+ 117 270 : }
118 :
119 : /*
120 : * Reference parity computation.
diff --git a/cov/raid/raid.c.func-sort-c.html b/cov/raid/raid.c.func-sort-c.html
index 96d13cb1..1f035c3f 100644
--- a/cov/raid/raid.c.func-sort-c.html
+++ b/cov/raid/raid.c.func-sort-c.html
@@ -61,23 +61,23 @@
| raid_gen |
- 1235540 |
+ 1235917 |
| raid_data |
- 214715 |
+ 214914 |
| raid_invert |
- 172728 |
+ 172507 |
| raid_delta_gen |
- 171710 |
+ 171503 |
| raid_rec1of1 |
- 101386 |
+ 101792 |
| raid_rec |
@@ -85,7 +85,7 @@
| raid_mode |
- 537 |
+ 539 |
| raid_zero |
diff --git a/cov/raid/raid.c.func.html b/cov/raid/raid.c.func.html
index 90b2af40..1758cd6d 100644
--- a/cov/raid/raid.c.func.html
+++ b/cov/raid/raid.c.func.html
@@ -61,23 +61,23 @@
| raid_data |
- 214715 |
+ 214914 |
| raid_delta_gen |
- 171710 |
+ 171503 |
| raid_gen |
- 1235540 |
+ 1235917 |
| raid_invert |
- 172728 |
+ 172507 |
| raid_mode |
- 537 |
+ 539 |
| raid_rec |
@@ -85,7 +85,7 @@
| raid_rec1of1 |
- 101386 |
+ 101792 |
| raid_rec2of2_int8 |
diff --git a/cov/raid/raid.c.gcov.html b/cov/raid/raid.c.gcov.html
index 3319701e..9923f537 100644
--- a/cov/raid/raid.c.gcov.html
+++ b/cov/raid/raid.c.gcov.html
@@ -235,16 +235,16 @@
173 : */
174 : const uint8_t (*raid_gfgen)[256];
175 :
- 176 537 : void raid_mode(int mode)
+ 176 539 : void raid_mode(int mode)
177 : {
- 178 537 : if (mode == RAID_MODE_VANDERMONDE) {
+ 178 539 : if (mode == RAID_MODE_VANDERMONDE) {
179 2 : raid_gen_ptr[2] = raid_genz_ptr;
180 2 : raid_gfgen = gfvandermonde;
181 : } else {
- 182 535 : raid_gen_ptr[2] = raid_gen3_ptr;
- 183 535 : raid_gfgen = gfcauchy;
+ 182 537 : raid_gen_ptr[2] = raid_gen3_ptr;
+ 183 537 : raid_gfgen = gfcauchy;
184 : }
- 185 537 : }
+ 185 539 : }
186 :
187 : /**
188 : * Buffer filled with 0 used in recovering.
@@ -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 1235540 : void raid_gen(int nd, int np, size_t size, void **v)
+ 223 1235917 : void raid_gen(int nd, int np, size_t size, void **v)
224 : {
225 : /* enforce limit on size */
- 226 1235540 : BUG_ON(size % 64 != 0);
+ 226 1235917 : BUG_ON(size % 64 != 0);
227 :
228 : /* enforce limit on number of failures */
- 229 1235540 : BUG_ON(np < 1);
- 230 1235540 : BUG_ON(np > RAID_PARITY_MAX);
+ 229 1235917 : BUG_ON(np < 1);
+ 230 1235917 : BUG_ON(np > RAID_PARITY_MAX);
231 :
- 232 1235540 : raid_gen_ptr[np - 1](nd, size, v);
- 233 1235540 : }
+ 232 1235917 : raid_gen_ptr[np - 1](nd, size, v);
+ 233 1235917 : }
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 172728 : void raid_invert(uint8_t *M, uint8_t *V, int n)
+ 246 172507 : 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 798241 : for (i = 0; i < n; ++i)
- 252 3220766 : for (j = 0; j < n; ++j)
- 253 2595253 : V[i * n + j] = i == j;
+ 251 797578 : for (i = 0; i < n; ++i)
+ 252 3219440 : for (j = 0; j < n; ++j)
+ 253 2594369 : V[i * n + j] = i == j;
254 :
255 : /* for each element in the diagonal */
- 256 798241 : for (k = 0; k < n; ++k) {
+ 256 797578 : 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 625513 : BUG_ON(M[k * n + k] == 0);
+ 262 625071 : BUG_ON(M[k * n + k] == 0);
263 :
264 : /* make the diagonal element to be 1 */
- 265 1251026 : f = inv(M[k * n + k]);
- 266 3220766 : for (j = 0; j < n; ++j) {
- 267 5190506 : M[k * n + j] = mul(f, M[k * n + j]);
- 268 5190506 : V[k * n + j] = mul(f, V[k * n + j]);
+ 265 1250142 : f = inv(M[k * n + k]);
+ 266 3219440 : for (j = 0; j < n; ++j) {
+ 267 5188738 : M[k * n + j] = mul(f, M[k * n + j]);
+ 268 5188738 : 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 3220766 : for (i = 0; i < n; ++i) {
- 274 2595253 : if (i == k)
- 275 625513 : continue;
- 276 1969740 : f = M[i * n + k];
- 277 11272284 : for (j = 0; j < n; ++j) {
- 278 18605088 : M[i * n + j] ^= mul(f, M[k * n + j]);
- 279 18605088 : V[i * n + j] ^= mul(f, V[k * n + j]);
+ 273 3219440 : for (i = 0; i < n; ++i) {
+ 274 2594369 : if (i == k)
+ 275 625071 : continue;
+ 276 1969298 : f = M[i * n + k];
+ 277 11270958 : for (j = 0; j < n; ++j) {
+ 278 18603320 : M[i * n + j] ^= mul(f, M[k * n + j]);
+ 279 18603320 : V[i * n + j] ^= mul(f, V[k * n + j]);
280 : }
281 : }
282 : }
- 283 172728 : }
+ 283 172507 : }
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 171710 : void raid_delta_gen(int nr, int *id, int *ip, int nd, size_t size, void **v)
+ 291 171503 : 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 171710 : np = ip[nr - 1] + 1;
+ 301 171503 : np = ip[nr - 1] + 1;
302 :
303 : /* latest missing data block */
- 304 171710 : latest = v[id[nr - 1]];
+ 304 171503 : latest = v[id[nr - 1]];
305 :
306 : /* setup pointers for delta computation */
- 307 873674 : for (i = 0, j = 0; i < np; ++i) {
+ 307 873053 : for (i = 0, j = 0; i < np; ++i) {
308 : /* keep a copy of the original parity vector */
- 309 701964 : p[i] = v[nd + i];
+ 309 701550 : p[i] = v[nd + i];
310 :
- 311 701964 : if (ip[j] == i) {
+ 311 701550 : 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 605821 : BUG_ON(j >= nr);
+ 322 605393 : BUG_ON(j >= nr);
323 :
324 : /* buffer for missing data blocks */
- 325 605821 : pa[j] = v[id[j]];
+ 325 605393 : pa[j] = v[id[j]];
326 :
327 : /* set at zero the missing data blocks */
- 328 605821 : v[id[j]] = raid_zero_block;
+ 328 605393 : v[id[j]] = raid_zero_block;
329 :
330 : /* compute the parity over the missing data blocks */
- 331 605821 : v[nd + i] = pa[j];
+ 331 605393 : v[nd + i] = pa[j];
332 :
333 : /* check for the next used entry */
- 334 605821 : ++j;
+ 334 605393 : ++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 96143 : v[nd + i] = latest;
+ 354 96157 : v[nd + i] = latest;
355 : }
356 : }
357 :
358 : /* all the parities have to be processed */
- 359 171710 : BUG_ON(j != nr);
+ 359 171503 : BUG_ON(j != nr);
360 :
361 : /* recompute the parity, note that np may be smaller than the */
362 : /* total number of parities available */
- 363 171710 : raid_gen(nd, np, size, v);
+ 363 171503 : raid_gen(nd, np, size, v);
364 :
365 : /* restore data buffers as before */
- 366 777531 : for (j = 0; j < nr; ++j)
- 367 605821 : v[id[j]] = pa[j];
+ 366 776896 : for (j = 0; j < nr; ++j)
+ 367 605393 : v[id[j]] = pa[j];
368 :
369 : /* restore parity buffers as before */
- 370 873674 : for (i = 0; i < np; ++i)
- 371 701964 : v[nd + i] = p[i];
- 372 171710 : }
+ 370 873053 : for (i = 0; i < np; ++i)
+ 371 701550 : v[nd + i] = p[i];
+ 372 171503 : }
373 :
374 : /**
375 : * Recover failure of one data block for PAR1.
@@ -444,29 +444,29 @@
382 : *
383 : * Dx = Pd
384 : */
- 385 101386 : void raid_rec1of1(int *id, int nd, size_t size, void **v)
+ 385 101792 : 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 101386 : p = v[nd];
- 393 101386 : pa = v[id[0]];
+ 392 101792 : p = v[nd];
+ 393 101792 : pa = v[id[0]];
394 :
395 : /* use the parity as missing data block */
- 396 101386 : v[id[0]] = p;
+ 396 101792 : v[id[0]] = p;
397 :
398 : /* compute the parity over the missing data block */
- 399 101386 : v[nd] = pa;
+ 399 101792 : v[nd] = pa;
400 :
401 : /* compute */
- 402 101386 : raid_gen(nd, 1, size, v);
+ 402 101792 : raid_gen(nd, 1, size, v);
403 :
404 : /* restore as before */
- 405 101386 : v[id[0]] = pa;
- 406 101386 : v[nd] = p;
- 407 101386 : }
+ 405 101792 : v[id[0]] = pa;
+ 406 101792 : v[nd] = p;
+ 407 101792 : }
408 :
409 : /**
410 : * Recover failure of two data blocks for PAR2.
@@ -615,36 +615,36 @@
553 12 : raid_gen(nd, ir[nr - 1] - nd + 1, size, v);
554 870 : }
555 :
- 556 214715 : void raid_data(int nr, int *id, int *ip, int nd, size_t size, void **v)
+ 556 214914 : void raid_data(int nr, int *id, int *ip, int nd, size_t size, void **v)
557 : {
558 : /* enforce limit on size */
- 559 214715 : BUG_ON(size % 64 != 0);
+ 559 214914 : BUG_ON(size % 64 != 0);
560 :
561 : /* enforce limit on number of failures */
- 562 214715 : BUG_ON(nr > nd);
- 563 214715 : BUG_ON(nr > RAID_PARITY_MAX);
+ 562 214914 : BUG_ON(nr > nd);
+ 563 214914 : BUG_ON(nr > RAID_PARITY_MAX);
564 :
565 : /* enforce order in index vector for data */
- 566 214715 : BUG_ON(nr >= 2 && id[0] >= id[1]);
- 567 214715 : BUG_ON(nr >= 3 && id[1] >= id[2]);
- 568 214715 : BUG_ON(nr >= 4 && id[2] >= id[3]);
- 569 214715 : BUG_ON(nr >= 5 && id[3] >= id[4]);
- 570 214715 : BUG_ON(nr >= 6 && id[4] >= id[5]);
+ 566 214914 : BUG_ON(nr >= 2 && id[0] >= id[1]);
+ 567 214914 : BUG_ON(nr >= 3 && id[1] >= id[2]);
+ 568 214914 : BUG_ON(nr >= 4 && id[2] >= id[3]);
+ 569 214914 : BUG_ON(nr >= 5 && id[3] >= id[4]);
+ 570 214914 : BUG_ON(nr >= 6 && id[4] >= id[5]);
571 :
572 : /* enforce limit on index vector for data */
- 573 214715 : BUG_ON(nr > 0 && id[nr-1] >= nd);
+ 573 214914 : BUG_ON(nr > 0 && id[nr-1] >= nd);
574 :
575 : /* enforce order in index vector for parity */
- 576 214715 : BUG_ON(nr >= 2 && ip[0] >= ip[1]);
- 577 214715 : BUG_ON(nr >= 3 && ip[1] >= ip[2]);
- 578 214715 : BUG_ON(nr >= 4 && ip[2] >= ip[3]);
- 579 214715 : BUG_ON(nr >= 5 && ip[3] >= ip[4]);
- 580 214715 : BUG_ON(nr >= 6 && ip[4] >= ip[5]);
+ 576 214914 : BUG_ON(nr >= 2 && ip[0] >= ip[1]);
+ 577 214914 : BUG_ON(nr >= 3 && ip[1] >= ip[2]);
+ 578 214914 : BUG_ON(nr >= 4 && ip[2] >= ip[3]);
+ 579 214914 : BUG_ON(nr >= 5 && ip[3] >= ip[4]);
+ 580 214914 : BUG_ON(nr >= 6 && ip[4] >= ip[5]);
581 :
582 : /* if failed data is present */
- 583 214715 : if (nr != 0)
- 584 214713 : raid_rec_ptr[nr - 1](nr, id, ip, nd, size, v);
- 585 214715 : }
+ 583 214914 : if (nr != 0)
+ 584 214912 : raid_rec_ptr[nr - 1](nr, id, ip, nd, size, v);
+ 585 214914 : }
586 :
diff --git a/cov/raid/x86.c.func-sort-c.html b/cov/raid/x86.c.func-sort-c.html
index f981eaff..52148a1e 100644
--- a/cov/raid/x86.c.func-sort-c.html
+++ b/cov/raid/x86.c.func-sort-c.html
@@ -61,19 +61,19 @@
| raid_gen6_ssse3 |
- 564140 |
+ 564213 |
| raid_gen1_sse2 |
- 288654 |
+ 289166 |
| raid_gen2_sse2 |
- 268936 |
+ 268726 |
| raid_rec1_ssse3 |
- 111201 |
+ 111621 |
| raid_recX_ssse3 |
@@ -81,19 +81,19 @@
| raid_gen5_ssse3 |
- 50654 |
+ 50653 |
| raid_rec2_ssse3 |
- 44277 |
+ 44056 |
| raid_gen4_ssse3 |
- 32471 |
+ 32470 |
| raid_gen3_ssse3 |
- 29543 |
+ 29542 |
| raid_recX_avx2 |
diff --git a/cov/raid/x86.c.func.html b/cov/raid/x86.c.func.html
index 2309dbdc..e0e39976 100644
--- a/cov/raid/x86.c.func.html
+++ b/cov/raid/x86.c.func.html
@@ -65,7 +65,7 @@
| raid_gen1_sse2 |
- 288654 |
+ 289166 |
| raid_gen2_avx2 |
@@ -73,23 +73,23 @@
| raid_gen2_sse2 |
- 268936 |
+ 268726 |
| raid_gen3_ssse3 |
- 29543 |
+ 29542 |
| raid_gen4_ssse3 |
- 32471 |
+ 32470 |
| raid_gen5_ssse3 |
- 50654 |
+ 50653 |
| raid_gen6_ssse3 |
- 564140 |
+ 564213 |
| raid_rec1_avx2 |
@@ -97,7 +97,7 @@
| raid_rec1_ssse3 |
- 111201 |
+ 111621 |
| raid_rec2_avx2 |
@@ -105,7 +105,7 @@
| raid_rec2_ssse3 |
- 44277 |
+ 44056 |
| raid_recX_avx2 |
diff --git a/cov/raid/x86.c.gcov.html b/cov/raid/x86.c.gcov.html
index 0722716b..04aeec56 100644
--- a/cov/raid/x86.c.gcov.html
+++ b/cov/raid/x86.c.gcov.html
@@ -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 288654 : void raid_gen1_sse2(int nd, size_t size, void **vv)
+ 36 289166 : void raid_gen1_sse2(int nd, size_t size, void **vv)
37 : {
- 38 288654 : uint8_t **v = (uint8_t **)vv;
+ 38 289166 : uint8_t **v = (uint8_t **)vv;
39 : uint8_t *p;
40 : int d, l;
41 : size_t i;
42 :
- 43 288654 : l = nd - 1;
- 44 288654 : p = v[nd];
+ 43 289166 : l = nd - 1;
+ 44 289166 : p = v[nd];
45 :
46 : raid_sse_begin();
47 :
- 48 6127002 : for (i = 0; i < size; i += 64) {
- 49 5838348 : asm volatile ("movdqa %0,%%xmm0" : : "m" (v[l][i]));
- 50 5838348 : asm volatile ("movdqa %0,%%xmm1" : : "m" (v[l][i + 16]));
- 51 5838348 : asm volatile ("movdqa %0,%%xmm2" : : "m" (v[l][i + 32]));
- 52 5838348 : asm volatile ("movdqa %0,%%xmm3" : : "m" (v[l][i + 48]));
- 53 37479684 : for (d = l - 1; d >= 0; --d) {
- 54 31641336 : asm volatile ("pxor %0,%%xmm0" : : "m" (v[d][i]));
- 55 31641336 : asm volatile ("pxor %0,%%xmm1" : : "m" (v[d][i + 16]));
- 56 31641336 : asm volatile ("pxor %0,%%xmm2" : : "m" (v[d][i + 32]));
- 57 31641336 : asm volatile ("pxor %0,%%xmm3" : : "m" (v[d][i + 48]));
+ 48 6139786 : for (i = 0; i < size; i += 64) {
+ 49 5850620 : asm volatile ("movdqa %0,%%xmm0" : : "m" (v[l][i]));
+ 50 5850620 : asm volatile ("movdqa %0,%%xmm1" : : "m" (v[l][i + 16]));
+ 51 5850620 : asm volatile ("movdqa %0,%%xmm2" : : "m" (v[l][i + 32]));
+ 52 5850620 : asm volatile ("movdqa %0,%%xmm3" : : "m" (v[l][i + 48]));
+ 53 37561508 : for (d = l - 1; d >= 0; --d) {
+ 54 31710888 : asm volatile ("pxor %0,%%xmm0" : : "m" (v[d][i]));
+ 55 31710888 : asm volatile ("pxor %0,%%xmm1" : : "m" (v[d][i + 16]));
+ 56 31710888 : asm volatile ("pxor %0,%%xmm2" : : "m" (v[d][i + 32]));
+ 57 31710888 : asm volatile ("pxor %0,%%xmm3" : : "m" (v[d][i + 48]));
58 : }
- 59 5838348 : asm volatile ("movntdq %%xmm0,%0" : "=m" (p[i]));
- 60 5838348 : asm volatile ("movntdq %%xmm1,%0" : "=m" (p[i + 16]));
- 61 5838348 : asm volatile ("movntdq %%xmm2,%0" : "=m" (p[i + 32]));
- 62 5838348 : asm volatile ("movntdq %%xmm3,%0" : "=m" (p[i + 48]));
+ 59 5850620 : asm volatile ("movntdq %%xmm0,%0" : "=m" (p[i]));
+ 60 5850620 : asm volatile ("movntdq %%xmm1,%0" : "=m" (p[i + 16]));
+ 61 5850620 : asm volatile ("movntdq %%xmm2,%0" : "=m" (p[i + 32]));
+ 62 5850620 : asm volatile ("movntdq %%xmm3,%0" : "=m" (p[i + 48]));
63 : }
64 :
65 : raid_sse_end();
- 66 288654 : }
+ 66 289166 : }
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 268936 : void raid_gen2_sse2(int nd, size_t size, void **vv)
+ 124 268726 : void raid_gen2_sse2(int nd, size_t size, void **vv)
125 : {
- 126 268936 : uint8_t **v = (uint8_t **)vv;
+ 126 268726 : uint8_t **v = (uint8_t **)vv;
127 : uint8_t *p;
128 : uint8_t *q;
129 : int d, l;
130 : size_t i;
131 :
- 132 268936 : l = nd - 1;
- 133 268936 : p = v[nd];
- 134 268936 : q = v[nd + 1];
+ 132 268726 : l = nd - 1;
+ 133 268726 : p = v[nd];
+ 134 268726 : q = v[nd + 1];
135 :
136 : raid_sse_begin();
137 :
- 138 268936 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.poly[0]));
+ 138 268726 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.poly[0]));
139 :
- 140 10800576 : for (i = 0; i < size; i += 32) {
- 141 10531640 : asm volatile ("movdqa %0,%%xmm0" : : "m" (v[l][i]));
- 142 10531640 : asm volatile ("movdqa %0,%%xmm1" : : "m" (v[l][i + 16]));
- 143 10531640 : asm volatile ("movdqa %xmm0,%xmm2");
- 144 10531640 : asm volatile ("movdqa %xmm1,%xmm3");
- 145 67056840 : for (d = l - 1; d >= 0; --d) {
- 146 56525200 : asm volatile ("pxor %xmm4,%xmm4");
- 147 56525200 : asm volatile ("pxor %xmm5,%xmm5");
- 148 56525200 : asm volatile ("pcmpgtb %xmm2,%xmm4");
- 149 56525200 : asm volatile ("pcmpgtb %xmm3,%xmm5");
- 150 56525200 : asm volatile ("paddb %xmm2,%xmm2");
- 151 56525200 : asm volatile ("paddb %xmm3,%xmm3");
- 152 56525200 : asm volatile ("pand %xmm7,%xmm4");
- 153 56525200 : asm volatile ("pand %xmm7,%xmm5");
- 154 56525200 : asm volatile ("pxor %xmm4,%xmm2");
- 155 56525200 : asm volatile ("pxor %xmm5,%xmm3");
+ 140 10769166 : for (i = 0; i < size; i += 32) {
+ 141 10500440 : asm volatile ("movdqa %0,%%xmm0" : : "m" (v[l][i]));
+ 142 10500440 : asm volatile ("movdqa %0,%%xmm1" : : "m" (v[l][i + 16]));
+ 143 10500440 : asm volatile ("movdqa %xmm0,%xmm2");
+ 144 10500440 : asm volatile ("movdqa %xmm1,%xmm3");
+ 145 66820488 : for (d = l - 1; d >= 0; --d) {
+ 146 56320048 : asm volatile ("pxor %xmm4,%xmm4");
+ 147 56320048 : asm volatile ("pxor %xmm5,%xmm5");
+ 148 56320048 : asm volatile ("pcmpgtb %xmm2,%xmm4");
+ 149 56320048 : asm volatile ("pcmpgtb %xmm3,%xmm5");
+ 150 56320048 : asm volatile ("paddb %xmm2,%xmm2");
+ 151 56320048 : asm volatile ("paddb %xmm3,%xmm3");
+ 152 56320048 : asm volatile ("pand %xmm7,%xmm4");
+ 153 56320048 : asm volatile ("pand %xmm7,%xmm5");
+ 154 56320048 : asm volatile ("pxor %xmm4,%xmm2");
+ 155 56320048 : asm volatile ("pxor %xmm5,%xmm3");
156 :
- 157 56525200 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[d][i]));
- 158 56525200 : asm volatile ("movdqa %0,%%xmm5" : : "m" (v[d][i + 16]));
- 159 56525200 : asm volatile ("pxor %xmm4,%xmm0");
- 160 56525200 : asm volatile ("pxor %xmm5,%xmm1");
- 161 56525200 : asm volatile ("pxor %xmm4,%xmm2");
- 162 56525200 : asm volatile ("pxor %xmm5,%xmm3");
+ 157 56320048 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[d][i]));
+ 158 56320048 : asm volatile ("movdqa %0,%%xmm5" : : "m" (v[d][i + 16]));
+ 159 56320048 : asm volatile ("pxor %xmm4,%xmm0");
+ 160 56320048 : asm volatile ("pxor %xmm5,%xmm1");
+ 161 56320048 : asm volatile ("pxor %xmm4,%xmm2");
+ 162 56320048 : asm volatile ("pxor %xmm5,%xmm3");
163 : }
- 164 10531640 : asm volatile ("movntdq %%xmm0,%0" : "=m" (p[i]));
- 165 10531640 : asm volatile ("movntdq %%xmm1,%0" : "=m" (p[i + 16]));
- 166 10531640 : asm volatile ("movntdq %%xmm2,%0" : "=m" (q[i]));
- 167 10531640 : asm volatile ("movntdq %%xmm3,%0" : "=m" (q[i + 16]));
+ 164 10500440 : asm volatile ("movntdq %%xmm0,%0" : "=m" (p[i]));
+ 165 10500440 : asm volatile ("movntdq %%xmm1,%0" : "=m" (p[i + 16]));
+ 166 10500440 : asm volatile ("movntdq %%xmm2,%0" : "=m" (q[i]));
+ 167 10500440 : asm volatile ("movntdq %%xmm3,%0" : "=m" (q[i + 16]));
168 : }
169 :
170 : raid_sse_end();
- 171 268936 : }
+ 171 268726 : }
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 29543 : void raid_gen3_ssse3(int nd, size_t size, void **vv)
+ 311 29542 : void raid_gen3_ssse3(int nd, size_t size, void **vv)
312 : {
- 313 29543 : uint8_t **v = (uint8_t **)vv;
+ 313 29542 : 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 29543 : l = nd - 1;
- 321 29543 : p = v[nd];
- 322 29543 : q = v[nd + 1];
- 323 29543 : r = v[nd + 2];
+ 320 29542 : l = nd - 1;
+ 321 29542 : p = v[nd];
+ 322 29542 : q = v[nd + 1];
+ 323 29542 : r = v[nd + 2];
324 :
325 : /* special case with only one data disk */
- 326 29543 : if (l == 0) {
+ 326 29542 : if (l == 0) {
327 4 : for (i = 0; i < 3; ++i)
328 3 : memcpy(v[1 + i], v[0], size);
- 329 29544 : return;
+ 329 29543 : return;
330 : }
331 :
332 : raid_sse_begin();
333 :
334 : /* generic case with at least two data disks */
- 335 29542 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfconst16.poly[0]));
- 336 29542 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0]));
+ 335 29541 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfconst16.poly[0]));
+ 336 29541 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0]));
337 :
- 338 4905206 : for (i = 0; i < size; i += 16) {
+ 338 4888821 : for (i = 0; i < size; i += 16) {
339 : /* last disk without the by two multiplication */
- 340 4875664 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[l][i]));
+ 340 4859280 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[l][i]));
341 :
- 342 4875664 : asm volatile ("movdqa %xmm4,%xmm0");
- 343 4875664 : asm volatile ("movdqa %xmm4,%xmm1");
+ 342 4859280 : asm volatile ("movdqa %xmm4,%xmm0");
+ 343 4859280 : asm volatile ("movdqa %xmm4,%xmm1");
344 :
- 345 4875664 : asm volatile ("movdqa %xmm4,%xmm5");
- 346 4875664 : asm volatile ("psrlw $4,%xmm5");
- 347 4875664 : asm volatile ("pand %xmm7,%xmm4");
- 348 4875664 : asm volatile ("pand %xmm7,%xmm5");
+ 345 4859280 : asm volatile ("movdqa %xmm4,%xmm5");
+ 346 4859280 : asm volatile ("psrlw $4,%xmm5");
+ 347 4859280 : asm volatile ("pand %xmm7,%xmm4");
+ 348 4859280 : asm volatile ("pand %xmm7,%xmm5");
349 :
- 350 4875664 : asm volatile ("movdqa %0,%%xmm2" : : "m" (gfgenpshufb[l][0][0][0]));
- 351 4875664 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[l][0][1][0]));
- 352 4875664 : asm volatile ("pshufb %xmm4,%xmm2");
- 353 4875664 : asm volatile ("pshufb %xmm5,%xmm6");
- 354 4875664 : asm volatile ("pxor %xmm6,%xmm2");
+ 350 4859280 : asm volatile ("movdqa %0,%%xmm2" : : "m" (gfgenpshufb[l][0][0][0]));
+ 351 4859280 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[l][0][1][0]));
+ 352 4859280 : asm volatile ("pshufb %xmm4,%xmm2");
+ 353 4859280 : asm volatile ("pshufb %xmm5,%xmm6");
+ 354 4859280 : asm volatile ("pxor %xmm6,%xmm2");
355 :
356 : /* intermediate disks */
- 357 30604016 : for (d = l - 1; d > 0; --d) {
- 358 25728352 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[d][i]));
+ 357 30489328 : for (d = l - 1; d > 0; --d) {
+ 358 25630048 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[d][i]));
359 :
- 360 25728352 : asm volatile ("pxor %xmm5,%xmm5");
- 361 25728352 : asm volatile ("pcmpgtb %xmm1,%xmm5");
- 362 25728352 : asm volatile ("paddb %xmm1,%xmm1");
- 363 25728352 : asm volatile ("pand %xmm3,%xmm5");
- 364 25728352 : asm volatile ("pxor %xmm5,%xmm1");
+ 360 25630048 : asm volatile ("pxor %xmm5,%xmm5");
+ 361 25630048 : asm volatile ("pcmpgtb %xmm1,%xmm5");
+ 362 25630048 : asm volatile ("paddb %xmm1,%xmm1");
+ 363 25630048 : asm volatile ("pand %xmm3,%xmm5");
+ 364 25630048 : asm volatile ("pxor %xmm5,%xmm1");
365 :
- 366 25728352 : asm volatile ("pxor %xmm4,%xmm0");
- 367 25728352 : asm volatile ("pxor %xmm4,%xmm1");
+ 366 25630048 : asm volatile ("pxor %xmm4,%xmm0");
+ 367 25630048 : asm volatile ("pxor %xmm4,%xmm1");
368 :
- 369 25728352 : asm volatile ("movdqa %xmm4,%xmm5");
- 370 25728352 : asm volatile ("psrlw $4,%xmm5");
- 371 25728352 : asm volatile ("pand %xmm7,%xmm4");
- 372 25728352 : asm volatile ("pand %xmm7,%xmm5");
+ 369 25630048 : asm volatile ("movdqa %xmm4,%xmm5");
+ 370 25630048 : asm volatile ("psrlw $4,%xmm5");
+ 371 25630048 : asm volatile ("pand %xmm7,%xmm4");
+ 372 25630048 : asm volatile ("pand %xmm7,%xmm5");
373 :
- 374 25728352 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][0][0][0]));
- 375 25728352 : asm volatile ("pshufb %xmm4,%xmm6");
- 376 25728352 : asm volatile ("pxor %xmm6,%xmm2");
- 377 25728352 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][0][1][0]));
- 378 25728352 : asm volatile ("pshufb %xmm5,%xmm6");
- 379 25728352 : asm volatile ("pxor %xmm6,%xmm2");
+ 374 25630048 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][0][0][0]));
+ 375 25630048 : asm volatile ("pshufb %xmm4,%xmm6");
+ 376 25630048 : asm volatile ("pxor %xmm6,%xmm2");
+ 377 25630048 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][0][1][0]));
+ 378 25630048 : asm volatile ("pshufb %xmm5,%xmm6");
+ 379 25630048 : asm volatile ("pxor %xmm6,%xmm2");
380 : }
381 :
382 : /* first disk with all coefficients at 1 */
- 383 4875664 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[0][i]));
+ 383 4859280 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[0][i]));
384 :
- 385 4875664 : asm volatile ("pxor %xmm5,%xmm5");
- 386 4875664 : asm volatile ("pcmpgtb %xmm1,%xmm5");
- 387 4875664 : asm volatile ("paddb %xmm1,%xmm1");
- 388 4875664 : asm volatile ("pand %xmm3,%xmm5");
- 389 4875664 : asm volatile ("pxor %xmm5,%xmm1");
+ 385 4859280 : asm volatile ("pxor %xmm5,%xmm5");
+ 386 4859280 : asm volatile ("pcmpgtb %xmm1,%xmm5");
+ 387 4859280 : asm volatile ("paddb %xmm1,%xmm1");
+ 388 4859280 : asm volatile ("pand %xmm3,%xmm5");
+ 389 4859280 : asm volatile ("pxor %xmm5,%xmm1");
390 :
- 391 4875664 : asm volatile ("pxor %xmm4,%xmm0");
- 392 4875664 : asm volatile ("pxor %xmm4,%xmm1");
- 393 4875664 : asm volatile ("pxor %xmm4,%xmm2");
+ 391 4859280 : asm volatile ("pxor %xmm4,%xmm0");
+ 392 4859280 : asm volatile ("pxor %xmm4,%xmm1");
+ 393 4859280 : asm volatile ("pxor %xmm4,%xmm2");
394 :
- 395 4875664 : asm volatile ("movntdq %%xmm0,%0" : "=m" (p[i]));
- 396 4875664 : asm volatile ("movntdq %%xmm1,%0" : "=m" (q[i]));
- 397 4875664 : asm volatile ("movntdq %%xmm2,%0" : "=m" (r[i]));
+ 395 4859280 : asm volatile ("movntdq %%xmm0,%0" : "=m" (p[i]));
+ 396 4859280 : asm volatile ("movntdq %%xmm1,%0" : "=m" (q[i]));
+ 397 4859280 : 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 32471 : void raid_gen4_ssse3(int nd, size_t size, void **vv)
+ 682 32470 : void raid_gen4_ssse3(int nd, size_t size, void **vv)
683 : {
- 684 32471 : uint8_t **v = (uint8_t **)vv;
+ 684 32470 : 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 32471 : l = nd - 1;
- 693 32471 : p = v[nd];
- 694 32471 : q = v[nd + 1];
- 695 32471 : r = v[nd + 2];
- 696 32471 : s = v[nd + 3];
+ 692 32470 : l = nd - 1;
+ 693 32470 : p = v[nd];
+ 694 32470 : q = v[nd + 1];
+ 695 32470 : r = v[nd + 2];
+ 696 32470 : s = v[nd + 3];
697 :
698 : /* special case with only one data disk */
- 699 32471 : if (l == 0) {
+ 699 32470 : if (l == 0) {
700 5 : for (i = 0; i < 4; ++i)
701 4 : memcpy(v[1 + i], v[0], size);
- 702 32472 : return;
+ 702 32471 : return;
703 : }
704 :
705 : raid_sse_begin();
706 :
707 : /* generic case with at least two data disks */
- 708 3367574 : for (i = 0; i < size; i += 16) {
+ 708 3351189 : for (i = 0; i < size; i += 16) {
709 : /* last disk without the by two multiplication */
- 710 3335104 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0]));
- 711 3335104 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[l][i]));
+ 710 3318720 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0]));
+ 711 3318720 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[l][i]));
712 :
- 713 3335104 : asm volatile ("movdqa %xmm4,%xmm0");
- 714 3335104 : asm volatile ("movdqa %xmm4,%xmm1");
+ 713 3318720 : asm volatile ("movdqa %xmm4,%xmm0");
+ 714 3318720 : asm volatile ("movdqa %xmm4,%xmm1");
715 :
- 716 3335104 : asm volatile ("movdqa %xmm4,%xmm5");
- 717 3335104 : asm volatile ("psrlw $4,%xmm5");
- 718 3335104 : asm volatile ("pand %xmm7,%xmm4");
- 719 3335104 : asm volatile ("pand %xmm7,%xmm5");
+ 716 3318720 : asm volatile ("movdqa %xmm4,%xmm5");
+ 717 3318720 : asm volatile ("psrlw $4,%xmm5");
+ 718 3318720 : asm volatile ("pand %xmm7,%xmm4");
+ 719 3318720 : asm volatile ("pand %xmm7,%xmm5");
720 :
- 721 3335104 : asm volatile ("movdqa %0,%%xmm2" : : "m" (gfgenpshufb[l][0][0][0]));
- 722 3335104 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][0][1][0]));
- 723 3335104 : asm volatile ("pshufb %xmm4,%xmm2");
- 724 3335104 : asm volatile ("pshufb %xmm5,%xmm7");
- 725 3335104 : asm volatile ("pxor %xmm7,%xmm2");
+ 721 3318720 : asm volatile ("movdqa %0,%%xmm2" : : "m" (gfgenpshufb[l][0][0][0]));
+ 722 3318720 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][0][1][0]));
+ 723 3318720 : asm volatile ("pshufb %xmm4,%xmm2");
+ 724 3318720 : asm volatile ("pshufb %xmm5,%xmm7");
+ 725 3318720 : asm volatile ("pxor %xmm7,%xmm2");
726 :
- 727 3335104 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfgenpshufb[l][1][0][0]));
- 728 3335104 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][1][1][0]));
- 729 3335104 : asm volatile ("pshufb %xmm4,%xmm3");
- 730 3335104 : asm volatile ("pshufb %xmm5,%xmm7");
- 731 3335104 : asm volatile ("pxor %xmm7,%xmm3");
+ 727 3318720 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfgenpshufb[l][1][0][0]));
+ 728 3318720 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][1][1][0]));
+ 729 3318720 : asm volatile ("pshufb %xmm4,%xmm3");
+ 730 3318720 : asm volatile ("pshufb %xmm5,%xmm7");
+ 731 3318720 : asm volatile ("pxor %xmm7,%xmm3");
732 :
733 : /* intermediate disks */
- 734 20000768 : for (d = l - 1; d > 0; --d) {
- 735 16665664 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.poly[0]));
- 736 16665664 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[d][i]));
+ 734 19886080 : for (d = l - 1; d > 0; --d) {
+ 735 16567360 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.poly[0]));
+ 736 16567360 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[d][i]));
737 :
- 738 16665664 : asm volatile ("pxor %xmm5,%xmm5");
- 739 16665664 : asm volatile ("pcmpgtb %xmm1,%xmm5");
- 740 16665664 : asm volatile ("paddb %xmm1,%xmm1");
- 741 16665664 : asm volatile ("pand %xmm7,%xmm5");
- 742 16665664 : asm volatile ("pxor %xmm5,%xmm1");
+ 738 16567360 : asm volatile ("pxor %xmm5,%xmm5");
+ 739 16567360 : asm volatile ("pcmpgtb %xmm1,%xmm5");
+ 740 16567360 : asm volatile ("paddb %xmm1,%xmm1");
+ 741 16567360 : asm volatile ("pand %xmm7,%xmm5");
+ 742 16567360 : asm volatile ("pxor %xmm5,%xmm1");
743 :
- 744 16665664 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0]));
+ 744 16567360 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0]));
745 :
- 746 16665664 : asm volatile ("pxor %xmm4,%xmm0");
- 747 16665664 : asm volatile ("pxor %xmm4,%xmm1");
+ 746 16567360 : asm volatile ("pxor %xmm4,%xmm0");
+ 747 16567360 : asm volatile ("pxor %xmm4,%xmm1");
748 :
- 749 16665664 : asm volatile ("movdqa %xmm4,%xmm5");
- 750 16665664 : asm volatile ("psrlw $4,%xmm5");
- 751 16665664 : asm volatile ("pand %xmm7,%xmm4");
- 752 16665664 : asm volatile ("pand %xmm7,%xmm5");
+ 749 16567360 : asm volatile ("movdqa %xmm4,%xmm5");
+ 750 16567360 : asm volatile ("psrlw $4,%xmm5");
+ 751 16567360 : asm volatile ("pand %xmm7,%xmm4");
+ 752 16567360 : asm volatile ("pand %xmm7,%xmm5");
753 :
- 754 16665664 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][0][0][0]));
- 755 16665664 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][0][1][0]));
- 756 16665664 : asm volatile ("pshufb %xmm4,%xmm6");
- 757 16665664 : asm volatile ("pshufb %xmm5,%xmm7");
- 758 16665664 : asm volatile ("pxor %xmm6,%xmm2");
- 759 16665664 : asm volatile ("pxor %xmm7,%xmm2");
+ 754 16567360 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][0][0][0]));
+ 755 16567360 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][0][1][0]));
+ 756 16567360 : asm volatile ("pshufb %xmm4,%xmm6");
+ 757 16567360 : asm volatile ("pshufb %xmm5,%xmm7");
+ 758 16567360 : asm volatile ("pxor %xmm6,%xmm2");
+ 759 16567360 : asm volatile ("pxor %xmm7,%xmm2");
760 :
- 761 16665664 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][1][0][0]));
- 762 16665664 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][1][1][0]));
- 763 16665664 : asm volatile ("pshufb %xmm4,%xmm6");
- 764 16665664 : asm volatile ("pshufb %xmm5,%xmm7");
- 765 16665664 : asm volatile ("pxor %xmm6,%xmm3");
- 766 16665664 : asm volatile ("pxor %xmm7,%xmm3");
+ 761 16567360 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][1][0][0]));
+ 762 16567360 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][1][1][0]));
+ 763 16567360 : asm volatile ("pshufb %xmm4,%xmm6");
+ 764 16567360 : asm volatile ("pshufb %xmm5,%xmm7");
+ 765 16567360 : asm volatile ("pxor %xmm6,%xmm3");
+ 766 16567360 : asm volatile ("pxor %xmm7,%xmm3");
767 : }
768 :
769 : /* first disk with all coefficients at 1 */
- 770 3335104 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.poly[0]));
- 771 3335104 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[0][i]));
+ 770 3318720 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.poly[0]));
+ 771 3318720 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[0][i]));
772 :
- 773 3335104 : asm volatile ("pxor %xmm5,%xmm5");
- 774 3335104 : asm volatile ("pcmpgtb %xmm1,%xmm5");
- 775 3335104 : asm volatile ("paddb %xmm1,%xmm1");
- 776 3335104 : asm volatile ("pand %xmm7,%xmm5");
- 777 3335104 : asm volatile ("pxor %xmm5,%xmm1");
+ 773 3318720 : asm volatile ("pxor %xmm5,%xmm5");
+ 774 3318720 : asm volatile ("pcmpgtb %xmm1,%xmm5");
+ 775 3318720 : asm volatile ("paddb %xmm1,%xmm1");
+ 776 3318720 : asm volatile ("pand %xmm7,%xmm5");
+ 777 3318720 : asm volatile ("pxor %xmm5,%xmm1");
778 :
- 779 3335104 : asm volatile ("pxor %xmm4,%xmm0");
- 780 3335104 : asm volatile ("pxor %xmm4,%xmm1");
- 781 3335104 : asm volatile ("pxor %xmm4,%xmm2");
- 782 3335104 : asm volatile ("pxor %xmm4,%xmm3");
+ 779 3318720 : asm volatile ("pxor %xmm4,%xmm0");
+ 780 3318720 : asm volatile ("pxor %xmm4,%xmm1");
+ 781 3318720 : asm volatile ("pxor %xmm4,%xmm2");
+ 782 3318720 : asm volatile ("pxor %xmm4,%xmm3");
783 :
- 784 3335104 : asm volatile ("movntdq %%xmm0,%0" : "=m" (p[i]));
- 785 3335104 : asm volatile ("movntdq %%xmm1,%0" : "=m" (q[i]));
- 786 3335104 : asm volatile ("movntdq %%xmm2,%0" : "=m" (r[i]));
- 787 3335104 : asm volatile ("movntdq %%xmm3,%0" : "=m" (s[i]));
+ 784 3318720 : asm volatile ("movntdq %%xmm0,%0" : "=m" (p[i]));
+ 785 3318720 : asm volatile ("movntdq %%xmm1,%0" : "=m" (q[i]));
+ 786 3318720 : asm volatile ("movntdq %%xmm2,%0" : "=m" (r[i]));
+ 787 3318720 : 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 50654 : void raid_gen5_ssse3(int nd, size_t size, void **vv)
+ 1132 50653 : void raid_gen5_ssse3(int nd, size_t size, void **vv)
1133 : {
- 1134 50654 : uint8_t **v = (uint8_t **)vv;
+ 1134 50653 : 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 50654 : uint8_t *pd = __align_ptr(buffer, 16);
+ 1143 50653 : uint8_t *pd = __align_ptr(buffer, 16);
1144 :
- 1145 50654 : l = nd - 1;
- 1146 50654 : p = v[nd];
- 1147 50654 : q = v[nd + 1];
- 1148 50654 : r = v[nd + 2];
- 1149 50654 : s = v[nd + 3];
- 1150 50654 : t = v[nd + 4];
+ 1145 50653 : l = nd - 1;
+ 1146 50653 : p = v[nd];
+ 1147 50653 : q = v[nd + 1];
+ 1148 50653 : r = v[nd + 2];
+ 1149 50653 : s = v[nd + 3];
+ 1150 50653 : t = v[nd + 4];
1151 :
1152 : /* special case with only one data disk */
- 1153 50654 : if (l == 0) {
+ 1153 50653 : if (l == 0) {
1154 6 : for (i = 0; i < 5; ++i)
1155 5 : memcpy(v[1 + i], v[0], size);
- 1156 50655 : return;
+ 1156 50654 : return;
1157 : }
1158 :
1159 : raid_sse_begin();
1160 :
1161 : /* generic case with at least two data disks */
- 1162 3937517 : for (i = 0; i < size; i += 16) {
+ 1162 3921132 : for (i = 0; i < size; i += 16) {
1163 : /* last disk without the by two multiplication */
- 1164 3886864 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[l][i]));
+ 1164 3870480 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[l][i]));
1165 :
- 1166 3886864 : asm volatile ("movdqa %xmm4,%xmm0");
- 1167 3886864 : asm volatile ("movdqa %%xmm4,%0" : "=m" (pd[0]));
+ 1166 3870480 : asm volatile ("movdqa %xmm4,%xmm0");
+ 1167 3870480 : asm volatile ("movdqa %%xmm4,%0" : "=m" (pd[0]));
1168 :
- 1169 3886864 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0]));
- 1170 3886864 : asm volatile ("movdqa %xmm4,%xmm5");
- 1171 3886864 : asm volatile ("psrlw $4,%xmm5");
- 1172 3886864 : asm volatile ("pand %xmm7,%xmm4");
- 1173 3886864 : asm volatile ("pand %xmm7,%xmm5");
+ 1169 3870480 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0]));
+ 1170 3870480 : asm volatile ("movdqa %xmm4,%xmm5");
+ 1171 3870480 : asm volatile ("psrlw $4,%xmm5");
+ 1172 3870480 : asm volatile ("pand %xmm7,%xmm4");
+ 1173 3870480 : asm volatile ("pand %xmm7,%xmm5");
1174 :
- 1175 3886864 : asm volatile ("movdqa %0,%%xmm1" : : "m" (gfgenpshufb[l][0][0][0]));
- 1176 3886864 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][0][1][0]));
- 1177 3886864 : asm volatile ("pshufb %xmm4,%xmm1");
- 1178 3886864 : asm volatile ("pshufb %xmm5,%xmm7");
- 1179 3886864 : asm volatile ("pxor %xmm7,%xmm1");
+ 1175 3870480 : asm volatile ("movdqa %0,%%xmm1" : : "m" (gfgenpshufb[l][0][0][0]));
+ 1176 3870480 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][0][1][0]));
+ 1177 3870480 : asm volatile ("pshufb %xmm4,%xmm1");
+ 1178 3870480 : asm volatile ("pshufb %xmm5,%xmm7");
+ 1179 3870480 : asm volatile ("pxor %xmm7,%xmm1");
1180 :
- 1181 3886864 : asm volatile ("movdqa %0,%%xmm2" : : "m" (gfgenpshufb[l][1][0][0]));
- 1182 3886864 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][1][1][0]));
- 1183 3886864 : asm volatile ("pshufb %xmm4,%xmm2");
- 1184 3886864 : asm volatile ("pshufb %xmm5,%xmm7");
- 1185 3886864 : asm volatile ("pxor %xmm7,%xmm2");
+ 1181 3870480 : asm volatile ("movdqa %0,%%xmm2" : : "m" (gfgenpshufb[l][1][0][0]));
+ 1182 3870480 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][1][1][0]));
+ 1183 3870480 : asm volatile ("pshufb %xmm4,%xmm2");
+ 1184 3870480 : asm volatile ("pshufb %xmm5,%xmm7");
+ 1185 3870480 : asm volatile ("pxor %xmm7,%xmm2");
1186 :
- 1187 3886864 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfgenpshufb[l][2][0][0]));
- 1188 3886864 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][2][1][0]));
- 1189 3886864 : asm volatile ("pshufb %xmm4,%xmm3");
- 1190 3886864 : asm volatile ("pshufb %xmm5,%xmm7");
- 1191 3886864 : asm volatile ("pxor %xmm7,%xmm3");
+ 1187 3870480 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfgenpshufb[l][2][0][0]));
+ 1188 3870480 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][2][1][0]));
+ 1189 3870480 : asm volatile ("pshufb %xmm4,%xmm3");
+ 1190 3870480 : asm volatile ("pshufb %xmm5,%xmm7");
+ 1191 3870480 : asm volatile ("pxor %xmm7,%xmm3");
1192 :
1193 : /* intermediate disks */
- 1194 23263984 : for (d = l - 1; d > 0; --d) {
- 1195 19377120 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[d][i]));
- 1196 19377120 : asm volatile ("movdqa %0,%%xmm6" : : "m" (pd[0]));
- 1197 19377120 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.poly[0]));
+ 1194 23149296 : for (d = l - 1; d > 0; --d) {
+ 1195 19278816 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[d][i]));
+ 1196 19278816 : asm volatile ("movdqa %0,%%xmm6" : : "m" (pd[0]));
+ 1197 19278816 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.poly[0]));
1198 :
- 1199 19377120 : asm volatile ("pxor %xmm5,%xmm5");
- 1200 19377120 : asm volatile ("pcmpgtb %xmm0,%xmm5");
- 1201 19377120 : asm volatile ("paddb %xmm0,%xmm0");
- 1202 19377120 : asm volatile ("pand %xmm7,%xmm5");
- 1203 19377120 : asm volatile ("pxor %xmm5,%xmm0");
+ 1199 19278816 : asm volatile ("pxor %xmm5,%xmm5");
+ 1200 19278816 : asm volatile ("pcmpgtb %xmm0,%xmm5");
+ 1201 19278816 : asm volatile ("paddb %xmm0,%xmm0");
+ 1202 19278816 : asm volatile ("pand %xmm7,%xmm5");
+ 1203 19278816 : asm volatile ("pxor %xmm5,%xmm0");
1204 :
- 1205 19377120 : asm volatile ("pxor %xmm4,%xmm0");
- 1206 19377120 : asm volatile ("pxor %xmm4,%xmm6");
- 1207 19377120 : asm volatile ("movdqa %%xmm6,%0" : "=m" (pd[0]));
+ 1205 19278816 : asm volatile ("pxor %xmm4,%xmm0");
+ 1206 19278816 : asm volatile ("pxor %xmm4,%xmm6");
+ 1207 19278816 : asm volatile ("movdqa %%xmm6,%0" : "=m" (pd[0]));
1208 :
- 1209 19377120 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0]));
- 1210 19377120 : asm volatile ("movdqa %xmm4,%xmm5");
- 1211 19377120 : asm volatile ("psrlw $4,%xmm5");
- 1212 19377120 : asm volatile ("pand %xmm7,%xmm4");
- 1213 19377120 : asm volatile ("pand %xmm7,%xmm5");
+ 1209 19278816 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0]));
+ 1210 19278816 : asm volatile ("movdqa %xmm4,%xmm5");
+ 1211 19278816 : asm volatile ("psrlw $4,%xmm5");
+ 1212 19278816 : asm volatile ("pand %xmm7,%xmm4");
+ 1213 19278816 : asm volatile ("pand %xmm7,%xmm5");
1214 :
- 1215 19377120 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][0][0][0]));
- 1216 19377120 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][0][1][0]));
- 1217 19377120 : asm volatile ("pshufb %xmm4,%xmm6");
- 1218 19377120 : asm volatile ("pshufb %xmm5,%xmm7");
- 1219 19377120 : asm volatile ("pxor %xmm6,%xmm1");
- 1220 19377120 : asm volatile ("pxor %xmm7,%xmm1");
+ 1215 19278816 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][0][0][0]));
+ 1216 19278816 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][0][1][0]));
+ 1217 19278816 : asm volatile ("pshufb %xmm4,%xmm6");
+ 1218 19278816 : asm volatile ("pshufb %xmm5,%xmm7");
+ 1219 19278816 : asm volatile ("pxor %xmm6,%xmm1");
+ 1220 19278816 : asm volatile ("pxor %xmm7,%xmm1");
1221 :
- 1222 19377120 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][1][0][0]));
- 1223 19377120 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][1][1][0]));
- 1224 19377120 : asm volatile ("pshufb %xmm4,%xmm6");
- 1225 19377120 : asm volatile ("pshufb %xmm5,%xmm7");
- 1226 19377120 : asm volatile ("pxor %xmm6,%xmm2");
- 1227 19377120 : asm volatile ("pxor %xmm7,%xmm2");
+ 1222 19278816 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][1][0][0]));
+ 1223 19278816 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][1][1][0]));
+ 1224 19278816 : asm volatile ("pshufb %xmm4,%xmm6");
+ 1225 19278816 : asm volatile ("pshufb %xmm5,%xmm7");
+ 1226 19278816 : asm volatile ("pxor %xmm6,%xmm2");
+ 1227 19278816 : asm volatile ("pxor %xmm7,%xmm2");
1228 :
- 1229 19377120 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][2][0][0]));
- 1230 19377120 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][2][1][0]));
- 1231 19377120 : asm volatile ("pshufb %xmm4,%xmm6");
- 1232 19377120 : asm volatile ("pshufb %xmm5,%xmm7");
- 1233 19377120 : asm volatile ("pxor %xmm6,%xmm3");
- 1234 19377120 : asm volatile ("pxor %xmm7,%xmm3");
+ 1229 19278816 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][2][0][0]));
+ 1230 19278816 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][2][1][0]));
+ 1231 19278816 : asm volatile ("pshufb %xmm4,%xmm6");
+ 1232 19278816 : asm volatile ("pshufb %xmm5,%xmm7");
+ 1233 19278816 : asm volatile ("pxor %xmm6,%xmm3");
+ 1234 19278816 : asm volatile ("pxor %xmm7,%xmm3");
1235 : }
1236 :
1237 : /* first disk with all coefficients at 1 */
- 1238 3886864 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[0][i]));
- 1239 3886864 : asm volatile ("movdqa %0,%%xmm6" : : "m" (pd[0]));
- 1240 3886864 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.poly[0]));
+ 1238 3870480 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[0][i]));
+ 1239 3870480 : asm volatile ("movdqa %0,%%xmm6" : : "m" (pd[0]));
+ 1240 3870480 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.poly[0]));
1241 :
- 1242 3886864 : asm volatile ("pxor %xmm5,%xmm5");
- 1243 3886864 : asm volatile ("pcmpgtb %xmm0,%xmm5");
- 1244 3886864 : asm volatile ("paddb %xmm0,%xmm0");
- 1245 3886864 : asm volatile ("pand %xmm7,%xmm5");
- 1246 3886864 : asm volatile ("pxor %xmm5,%xmm0");
+ 1242 3870480 : asm volatile ("pxor %xmm5,%xmm5");
+ 1243 3870480 : asm volatile ("pcmpgtb %xmm0,%xmm5");
+ 1244 3870480 : asm volatile ("paddb %xmm0,%xmm0");
+ 1245 3870480 : asm volatile ("pand %xmm7,%xmm5");
+ 1246 3870480 : asm volatile ("pxor %xmm5,%xmm0");
1247 :
- 1248 3886864 : asm volatile ("pxor %xmm4,%xmm0");
- 1249 3886864 : asm volatile ("pxor %xmm4,%xmm1");
- 1250 3886864 : asm volatile ("pxor %xmm4,%xmm2");
- 1251 3886864 : asm volatile ("pxor %xmm4,%xmm3");
- 1252 3886864 : asm volatile ("pxor %xmm4,%xmm6");
+ 1248 3870480 : asm volatile ("pxor %xmm4,%xmm0");
+ 1249 3870480 : asm volatile ("pxor %xmm4,%xmm1");
+ 1250 3870480 : asm volatile ("pxor %xmm4,%xmm2");
+ 1251 3870480 : asm volatile ("pxor %xmm4,%xmm3");
+ 1252 3870480 : asm volatile ("pxor %xmm4,%xmm6");
1253 :
- 1254 3886864 : asm volatile ("movntdq %%xmm6,%0" : "=m" (p[i]));
- 1255 3886864 : asm volatile ("movntdq %%xmm0,%0" : "=m" (q[i]));
- 1256 3886864 : asm volatile ("movntdq %%xmm1,%0" : "=m" (r[i]));
- 1257 3886864 : asm volatile ("movntdq %%xmm2,%0" : "=m" (s[i]));
- 1258 3886864 : asm volatile ("movntdq %%xmm3,%0" : "=m" (t[i]));
+ 1254 3870480 : asm volatile ("movntdq %%xmm6,%0" : "=m" (p[i]));
+ 1255 3870480 : asm volatile ("movntdq %%xmm0,%0" : "=m" (q[i]));
+ 1256 3870480 : asm volatile ("movntdq %%xmm1,%0" : "=m" (r[i]));
+ 1257 3870480 : asm volatile ("movntdq %%xmm2,%0" : "=m" (s[i]));
+ 1258 3870480 : 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 564140 : void raid_gen6_ssse3(int nd, size_t size, void **vv)
+ 1532 564213 : void raid_gen6_ssse3(int nd, size_t size, void **vv)
1533 : {
- 1534 564140 : uint8_t **v = (uint8_t **)vv;
+ 1534 564213 : 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 564140 : uint8_t *pd = __align_ptr(buffer, 16);
+ 1544 564213 : uint8_t *pd = __align_ptr(buffer, 16);
1545 :
- 1546 564140 : l = nd - 1;
- 1547 564140 : p = v[nd];
- 1548 564140 : q = v[nd + 1];
- 1549 564140 : r = v[nd + 2];
- 1550 564140 : s = v[nd + 3];
- 1551 564140 : t = v[nd + 4];
- 1552 564140 : u = v[nd + 5];
+ 1546 564213 : l = nd - 1;
+ 1547 564213 : p = v[nd];
+ 1548 564213 : q = v[nd + 1];
+ 1549 564213 : r = v[nd + 2];
+ 1550 564213 : s = v[nd + 3];
+ 1551 564213 : t = v[nd + 4];
+ 1552 564213 : u = v[nd + 5];
1553 :
1554 : /* special case with only one data disk */
- 1555 564140 : if (l == 0) {
+ 1555 564213 : if (l == 0) {
1556 7 : for (i = 0; i < 6; ++i)
1557 6 : memcpy(v[1 + i], v[0], size);
- 1558 564141 : return;
+ 1558 564214 : return;
1559 : }
1560 :
1561 : raid_sse_begin();
1562 :
1563 : /* generic case with at least two data disks */
- 1564 36095675 : for (i = 0; i < size; i += 16) {
+ 1564 36100420 : for (i = 0; i < size; i += 16) {
1565 : /* last disk without the by two multiplication */
- 1566 35531536 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[l][i]));
+ 1566 35536208 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[l][i]));
1567 :
- 1568 35531536 : asm volatile ("movdqa %%xmm4,%0" : "=m" (pd[0]));
- 1569 35531536 : asm volatile ("movdqa %%xmm4,%0" : "=m" (pd[16]));
+ 1568 35536208 : asm volatile ("movdqa %%xmm4,%0" : "=m" (pd[0]));
+ 1569 35536208 : asm volatile ("movdqa %%xmm4,%0" : "=m" (pd[16]));
1570 :
- 1571 35531536 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0]));
- 1572 35531536 : asm volatile ("movdqa %xmm4,%xmm5");
- 1573 35531536 : asm volatile ("psrlw $4,%xmm5");
- 1574 35531536 : asm volatile ("pand %xmm7,%xmm4");
- 1575 35531536 : asm volatile ("pand %xmm7,%xmm5");
+ 1571 35536208 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0]));
+ 1572 35536208 : asm volatile ("movdqa %xmm4,%xmm5");
+ 1573 35536208 : asm volatile ("psrlw $4,%xmm5");
+ 1574 35536208 : asm volatile ("pand %xmm7,%xmm4");
+ 1575 35536208 : asm volatile ("pand %xmm7,%xmm5");
1576 :
- 1577 35531536 : asm volatile ("movdqa %0,%%xmm0" : : "m" (gfgenpshufb[l][0][0][0]));
- 1578 35531536 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][0][1][0]));
- 1579 35531536 : asm volatile ("pshufb %xmm4,%xmm0");
- 1580 35531536 : asm volatile ("pshufb %xmm5,%xmm7");
- 1581 35531536 : asm volatile ("pxor %xmm7,%xmm0");
+ 1577 35536208 : asm volatile ("movdqa %0,%%xmm0" : : "m" (gfgenpshufb[l][0][0][0]));
+ 1578 35536208 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][0][1][0]));
+ 1579 35536208 : asm volatile ("pshufb %xmm4,%xmm0");
+ 1580 35536208 : asm volatile ("pshufb %xmm5,%xmm7");
+ 1581 35536208 : asm volatile ("pxor %xmm7,%xmm0");
1582 :
- 1583 35531536 : asm volatile ("movdqa %0,%%xmm1" : : "m" (gfgenpshufb[l][1][0][0]));
- 1584 35531536 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][1][1][0]));
- 1585 35531536 : asm volatile ("pshufb %xmm4,%xmm1");
- 1586 35531536 : asm volatile ("pshufb %xmm5,%xmm7");
- 1587 35531536 : asm volatile ("pxor %xmm7,%xmm1");
+ 1583 35536208 : asm volatile ("movdqa %0,%%xmm1" : : "m" (gfgenpshufb[l][1][0][0]));
+ 1584 35536208 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][1][1][0]));
+ 1585 35536208 : asm volatile ("pshufb %xmm4,%xmm1");
+ 1586 35536208 : asm volatile ("pshufb %xmm5,%xmm7");
+ 1587 35536208 : asm volatile ("pxor %xmm7,%xmm1");
1588 :
- 1589 35531536 : asm volatile ("movdqa %0,%%xmm2" : : "m" (gfgenpshufb[l][2][0][0]));
- 1590 35531536 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][2][1][0]));
- 1591 35531536 : asm volatile ("pshufb %xmm4,%xmm2");
- 1592 35531536 : asm volatile ("pshufb %xmm5,%xmm7");
- 1593 35531536 : asm volatile ("pxor %xmm7,%xmm2");
+ 1589 35536208 : asm volatile ("movdqa %0,%%xmm2" : : "m" (gfgenpshufb[l][2][0][0]));
+ 1590 35536208 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][2][1][0]));
+ 1591 35536208 : asm volatile ("pshufb %xmm4,%xmm2");
+ 1592 35536208 : asm volatile ("pshufb %xmm5,%xmm7");
+ 1593 35536208 : asm volatile ("pxor %xmm7,%xmm2");
1594 :
- 1595 35531536 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfgenpshufb[l][3][0][0]));
- 1596 35531536 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][3][1][0]));
- 1597 35531536 : asm volatile ("pshufb %xmm4,%xmm3");
- 1598 35531536 : asm volatile ("pshufb %xmm5,%xmm7");
- 1599 35531536 : asm volatile ("pxor %xmm7,%xmm3");
+ 1595 35536208 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfgenpshufb[l][3][0][0]));
+ 1596 35536208 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][3][1][0]));
+ 1597 35536208 : asm volatile ("pshufb %xmm4,%xmm3");
+ 1598 35536208 : asm volatile ("pshufb %xmm5,%xmm7");
+ 1599 35536208 : asm volatile ("pxor %xmm7,%xmm3");
1600 :
1601 : /* intermediate disks */
- 1602 183662576 : for (d = l - 1; d > 0; --d) {
- 1603 148131040 : asm volatile ("movdqa %0,%%xmm5" : : "m" (pd[0]));
- 1604 148131040 : asm volatile ("movdqa %0,%%xmm6" : : "m" (pd[16]));
- 1605 148131040 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.poly[0]));
+ 1602 183685936 : for (d = l - 1; d > 0; --d) {
+ 1603 148149728 : asm volatile ("movdqa %0,%%xmm5" : : "m" (pd[0]));
+ 1604 148149728 : asm volatile ("movdqa %0,%%xmm6" : : "m" (pd[16]));
+ 1605 148149728 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.poly[0]));
1606 :
- 1607 148131040 : asm volatile ("pxor %xmm4,%xmm4");
- 1608 148131040 : asm volatile ("pcmpgtb %xmm6,%xmm4");
- 1609 148131040 : asm volatile ("paddb %xmm6,%xmm6");
- 1610 148131040 : asm volatile ("pand %xmm7,%xmm4");
- 1611 148131040 : asm volatile ("pxor %xmm4,%xmm6");
+ 1607 148149728 : asm volatile ("pxor %xmm4,%xmm4");
+ 1608 148149728 : asm volatile ("pcmpgtb %xmm6,%xmm4");
+ 1609 148149728 : asm volatile ("paddb %xmm6,%xmm6");
+ 1610 148149728 : asm volatile ("pand %xmm7,%xmm4");
+ 1611 148149728 : asm volatile ("pxor %xmm4,%xmm6");
1612 :
- 1613 148131040 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[d][i]));
+ 1613 148149728 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[d][i]));
1614 :
- 1615 148131040 : asm volatile ("pxor %xmm4,%xmm5");
- 1616 148131040 : asm volatile ("pxor %xmm4,%xmm6");
- 1617 148131040 : asm volatile ("movdqa %%xmm5,%0" : "=m" (pd[0]));
- 1618 148131040 : asm volatile ("movdqa %%xmm6,%0" : "=m" (pd[16]));
+ 1615 148149728 : asm volatile ("pxor %xmm4,%xmm5");
+ 1616 148149728 : asm volatile ("pxor %xmm4,%xmm6");
+ 1617 148149728 : asm volatile ("movdqa %%xmm5,%0" : "=m" (pd[0]));
+ 1618 148149728 : asm volatile ("movdqa %%xmm6,%0" : "=m" (pd[16]));
1619 :
- 1620 148131040 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0]));
- 1621 148131040 : asm volatile ("movdqa %xmm4,%xmm5");
- 1622 148131040 : asm volatile ("psrlw $4,%xmm5");
- 1623 148131040 : asm volatile ("pand %xmm7,%xmm4");
- 1624 148131040 : asm volatile ("pand %xmm7,%xmm5");
+ 1620 148149728 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0]));
+ 1621 148149728 : asm volatile ("movdqa %xmm4,%xmm5");
+ 1622 148149728 : asm volatile ("psrlw $4,%xmm5");
+ 1623 148149728 : asm volatile ("pand %xmm7,%xmm4");
+ 1624 148149728 : asm volatile ("pand %xmm7,%xmm5");
1625 :
- 1626 148131040 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][0][0][0]));
- 1627 148131040 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][0][1][0]));
- 1628 148131040 : asm volatile ("pshufb %xmm4,%xmm6");
- 1629 148131040 : asm volatile ("pshufb %xmm5,%xmm7");
- 1630 148131040 : asm volatile ("pxor %xmm6,%xmm0");
- 1631 148131040 : asm volatile ("pxor %xmm7,%xmm0");
+ 1626 148149728 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][0][0][0]));
+ 1627 148149728 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][0][1][0]));
+ 1628 148149728 : asm volatile ("pshufb %xmm4,%xmm6");
+ 1629 148149728 : asm volatile ("pshufb %xmm5,%xmm7");
+ 1630 148149728 : asm volatile ("pxor %xmm6,%xmm0");
+ 1631 148149728 : asm volatile ("pxor %xmm7,%xmm0");
1632 :
- 1633 148131040 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][1][0][0]));
- 1634 148131040 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][1][1][0]));
- 1635 148131040 : asm volatile ("pshufb %xmm4,%xmm6");
- 1636 148131040 : asm volatile ("pshufb %xmm5,%xmm7");
- 1637 148131040 : asm volatile ("pxor %xmm6,%xmm1");
- 1638 148131040 : asm volatile ("pxor %xmm7,%xmm1");
+ 1633 148149728 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][1][0][0]));
+ 1634 148149728 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][1][1][0]));
+ 1635 148149728 : asm volatile ("pshufb %xmm4,%xmm6");
+ 1636 148149728 : asm volatile ("pshufb %xmm5,%xmm7");
+ 1637 148149728 : asm volatile ("pxor %xmm6,%xmm1");
+ 1638 148149728 : asm volatile ("pxor %xmm7,%xmm1");
1639 :
- 1640 148131040 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][2][0][0]));
- 1641 148131040 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][2][1][0]));
- 1642 148131040 : asm volatile ("pshufb %xmm4,%xmm6");
- 1643 148131040 : asm volatile ("pshufb %xmm5,%xmm7");
- 1644 148131040 : asm volatile ("pxor %xmm6,%xmm2");
- 1645 148131040 : asm volatile ("pxor %xmm7,%xmm2");
+ 1640 148149728 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][2][0][0]));
+ 1641 148149728 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][2][1][0]));
+ 1642 148149728 : asm volatile ("pshufb %xmm4,%xmm6");
+ 1643 148149728 : asm volatile ("pshufb %xmm5,%xmm7");
+ 1644 148149728 : asm volatile ("pxor %xmm6,%xmm2");
+ 1645 148149728 : asm volatile ("pxor %xmm7,%xmm2");
1646 :
- 1647 148131040 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][3][0][0]));
- 1648 148131040 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][3][1][0]));
- 1649 148131040 : asm volatile ("pshufb %xmm4,%xmm6");
- 1650 148131040 : asm volatile ("pshufb %xmm5,%xmm7");
- 1651 148131040 : asm volatile ("pxor %xmm6,%xmm3");
- 1652 148131040 : asm volatile ("pxor %xmm7,%xmm3");
+ 1647 148149728 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][3][0][0]));
+ 1648 148149728 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][3][1][0]));
+ 1649 148149728 : asm volatile ("pshufb %xmm4,%xmm6");
+ 1650 148149728 : asm volatile ("pshufb %xmm5,%xmm7");
+ 1651 148149728 : asm volatile ("pxor %xmm6,%xmm3");
+ 1652 148149728 : asm volatile ("pxor %xmm7,%xmm3");
1653 : }
1654 :
1655 : /* first disk with all coefficients at 1 */
- 1656 35531536 : asm volatile ("movdqa %0,%%xmm5" : : "m" (pd[0]));
- 1657 35531536 : asm volatile ("movdqa %0,%%xmm6" : : "m" (pd[16]));
- 1658 35531536 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.poly[0]));
+ 1656 35536208 : asm volatile ("movdqa %0,%%xmm5" : : "m" (pd[0]));
+ 1657 35536208 : asm volatile ("movdqa %0,%%xmm6" : : "m" (pd[16]));
+ 1658 35536208 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.poly[0]));
1659 :
- 1660 35531536 : asm volatile ("pxor %xmm4,%xmm4");
- 1661 35531536 : asm volatile ("pcmpgtb %xmm6,%xmm4");
- 1662 35531536 : asm volatile ("paddb %xmm6,%xmm6");
- 1663 35531536 : asm volatile ("pand %xmm7,%xmm4");
- 1664 35531536 : asm volatile ("pxor %xmm4,%xmm6");
+ 1660 35536208 : asm volatile ("pxor %xmm4,%xmm4");
+ 1661 35536208 : asm volatile ("pcmpgtb %xmm6,%xmm4");
+ 1662 35536208 : asm volatile ("paddb %xmm6,%xmm6");
+ 1663 35536208 : asm volatile ("pand %xmm7,%xmm4");
+ 1664 35536208 : asm volatile ("pxor %xmm4,%xmm6");
1665 :
- 1666 35531536 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[0][i]));
- 1667 35531536 : asm volatile ("pxor %xmm4,%xmm0");
- 1668 35531536 : asm volatile ("pxor %xmm4,%xmm1");
- 1669 35531536 : asm volatile ("pxor %xmm4,%xmm2");
- 1670 35531536 : asm volatile ("pxor %xmm4,%xmm3");
- 1671 35531536 : asm volatile ("pxor %xmm4,%xmm5");
- 1672 35531536 : asm volatile ("pxor %xmm4,%xmm6");
+ 1666 35536208 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[0][i]));
+ 1667 35536208 : asm volatile ("pxor %xmm4,%xmm0");
+ 1668 35536208 : asm volatile ("pxor %xmm4,%xmm1");
+ 1669 35536208 : asm volatile ("pxor %xmm4,%xmm2");
+ 1670 35536208 : asm volatile ("pxor %xmm4,%xmm3");
+ 1671 35536208 : asm volatile ("pxor %xmm4,%xmm5");
+ 1672 35536208 : asm volatile ("pxor %xmm4,%xmm6");
1673 :
- 1674 35531536 : asm volatile ("movntdq %%xmm5,%0" : "=m" (p[i]));
- 1675 35531536 : asm volatile ("movntdq %%xmm6,%0" : "=m" (q[i]));
- 1676 35531536 : asm volatile ("movntdq %%xmm0,%0" : "=m" (r[i]));
- 1677 35531536 : asm volatile ("movntdq %%xmm1,%0" : "=m" (s[i]));
- 1678 35531536 : asm volatile ("movntdq %%xmm2,%0" : "=m" (t[i]));
- 1679 35531536 : asm volatile ("movntdq %%xmm3,%0" : "=m" (u[i]));
+ 1674 35536208 : asm volatile ("movntdq %%xmm5,%0" : "=m" (p[i]));
+ 1675 35536208 : asm volatile ("movntdq %%xmm6,%0" : "=m" (q[i]));
+ 1676 35536208 : asm volatile ("movntdq %%xmm0,%0" : "=m" (r[i]));
+ 1677 35536208 : asm volatile ("movntdq %%xmm1,%0" : "=m" (s[i]));
+ 1678 35536208 : asm volatile ("movntdq %%xmm2,%0" : "=m" (t[i]));
+ 1679 35536208 : 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 111201 : void raid_rec1_ssse3(int nr, int *id, int *ip, int nd, size_t size, void **vv)
+ 1987 111621 : void raid_rec1_ssse3(int nr, int *id, int *ip, int nd, size_t size, void **vv)
1988 : {
- 1989 111201 : uint8_t **v = (uint8_t **)vv;
+ 1989 111621 : 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 111201 : if (ip[0] == 0) {
- 2000 101332 : raid_rec1of1(id, nd, size, vv);
- 2001 212533 : return;
+ 1999 111621 : if (ip[0] == 0) {
+ 2000 101738 : raid_rec1of1(id, nd, size, vv);
+ 2001 213359 : return;
2002 : }
2003 :
2004 : /* setup the coefficients matrix */
- 2005 19738 : G = A(ip[0], id[0]);
+ 2005 19766 : G = A(ip[0], id[0]);
2006 :
2007 : /* invert it to solve the system of linear equations */
- 2008 19738 : V = inv(G);
+ 2008 19766 : V = inv(G);
2009 :
2010 : /* compute delta parity */
- 2011 9869 : raid_delta_gen(1, id, ip, nd, size, vv);
+ 2011 9883 : raid_delta_gen(1, id, ip, nd, size, vv);
2012 :
- 2013 9869 : p = v[nd + ip[0]];
- 2014 9869 : pa = v[id[0]];
+ 2013 9883 : p = v[nd + ip[0]];
+ 2014 9883 : pa = v[id[0]];
2015 :
2016 : raid_sse_begin();
2017 :
- 2018 9869 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0]));
- 2019 9869 : asm volatile ("movdqa %0,%%xmm4" : : "m" (gfmulpshufb[V][0][0]));
- 2020 9869 : asm volatile ("movdqa %0,%%xmm5" : : "m" (gfmulpshufb[V][1][0]));
+ 2018 9883 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0]));
+ 2019 9883 : asm volatile ("movdqa %0,%%xmm4" : : "m" (gfmulpshufb[V][0][0]));
+ 2020 9883 : asm volatile ("movdqa %0,%%xmm5" : : "m" (gfmulpshufb[V][1][0]));
2021 :
- 2022 1551373 : for (i = 0; i < size; i += 16) {
- 2023 1541504 : asm volatile ("movdqa %0,%%xmm0" : : "m" (p[i]));
- 2024 1541504 : asm volatile ("movdqa %0,%%xmm1" : : "m" (pa[i]));
- 2025 1541504 : asm volatile ("movdqa %xmm4,%xmm2");
- 2026 1541504 : asm volatile ("movdqa %xmm5,%xmm3");
- 2027 1541504 : asm volatile ("pxor %xmm0,%xmm1");
- 2028 1541504 : asm volatile ("movdqa %xmm1,%xmm0");
- 2029 1541504 : asm volatile ("psrlw $4,%xmm1");
- 2030 1541504 : asm volatile ("pand %xmm7,%xmm0");
- 2031 1541504 : asm volatile ("pand %xmm7,%xmm1");
- 2032 1541504 : asm volatile ("pshufb %xmm0,%xmm2");
- 2033 1541504 : asm volatile ("pshufb %xmm1,%xmm3");
- 2034 1541504 : asm volatile ("pxor %xmm3,%xmm2");
- 2035 1541504 : asm volatile ("movdqa %%xmm2,%0" : "=m" (pa[i]));
+ 2022 1552283 : for (i = 0; i < size; i += 16) {
+ 2023 1542400 : asm volatile ("movdqa %0,%%xmm0" : : "m" (p[i]));
+ 2024 1542400 : asm volatile ("movdqa %0,%%xmm1" : : "m" (pa[i]));
+ 2025 1542400 : asm volatile ("movdqa %xmm4,%xmm2");
+ 2026 1542400 : asm volatile ("movdqa %xmm5,%xmm3");
+ 2027 1542400 : asm volatile ("pxor %xmm0,%xmm1");
+ 2028 1542400 : asm volatile ("movdqa %xmm1,%xmm0");
+ 2029 1542400 : asm volatile ("psrlw $4,%xmm1");
+ 2030 1542400 : asm volatile ("pand %xmm7,%xmm0");
+ 2031 1542400 : asm volatile ("pand %xmm7,%xmm1");
+ 2032 1542400 : asm volatile ("pshufb %xmm0,%xmm2");
+ 2033 1542400 : asm volatile ("pshufb %xmm1,%xmm3");
+ 2034 1542400 : asm volatile ("pxor %xmm3,%xmm2");
+ 2035 1542400 : 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 44277 : void raid_rec2_ssse3(int nr, int *id, int *ip, int nd, size_t size, void **vv)
+ 2046 44056 : void raid_rec2_ssse3(int nr, int *id, int *ip, int nd, size_t size, void **vv)
2047 : {
- 2048 44277 : uint8_t **v = (uint8_t **)vv;
- 2049 44277 : const int N = 2;
- 2050 44277 : uint8_t *p[N];
- 2051 44277 : uint8_t *pa[N];
- 2052 44277 : uint8_t G[N * N];
- 2053 44277 : uint8_t V[N * N];
+ 2048 44056 : uint8_t **v = (uint8_t **)vv;
+ 2049 44056 : const int N = 2;
+ 2050 44056 : uint8_t *p[N];
+ 2051 44056 : uint8_t *pa[N];
+ 2052 44056 : uint8_t G[N * N];
+ 2053 44056 : 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 132831 : for (j = 0; j < N; ++j)
- 2061 265662 : for (k = 0; k < N; ++k)
- 2062 354216 : G[j * N + k] = A(ip[j], id[k]);
+ 2060 132168 : for (j = 0; j < N; ++j)
+ 2061 264336 : for (k = 0; k < N; ++k)
+ 2062 352448 : G[j * N + k] = A(ip[j], id[k]);
2063 :
2064 : /* invert it to solve the system of linear equations */
- 2065 44277 : raid_invert(G, V, N);
+ 2065 44056 : raid_invert(G, V, N);
2066 :
2067 : /* compute delta parity */
- 2068 44277 : raid_delta_gen(N, id, ip, nd, size, vv);
+ 2068 44056 : raid_delta_gen(N, id, ip, nd, size, vv);
2069 :
- 2070 132831 : for (j = 0; j < N; ++j) {
- 2071 88554 : p[j] = v[nd + ip[j]];
- 2072 88554 : pa[j] = v[id[j]];
+ 2070 132168 : for (j = 0; j < N; ++j) {
+ 2071 88112 : p[j] = v[nd + ip[j]];
+ 2072 88112 : pa[j] = v[id[j]];
2073 : }
2074 :
2075 : raid_sse_begin();
2076 :
- 2077 44277 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0]));
+ 2077 44056 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0]));
2078 :
- 2079 3604341 : for (i = 0; i < size; i += 16) {
- 2080 3560064 : asm volatile ("movdqa %0,%%xmm0" : : "m" (p[0][i]));
- 2081 3560064 : asm volatile ("movdqa %0,%%xmm2" : : "m" (pa[0][i]));
- 2082 3560064 : asm volatile ("movdqa %0,%%xmm1" : : "m" (p[1][i]));
- 2083 3560064 : asm volatile ("movdqa %0,%%xmm3" : : "m" (pa[1][i]));
- 2084 3560064 : asm volatile ("pxor %xmm2,%xmm0");
- 2085 3560064 : asm volatile ("pxor %xmm3,%xmm1");
+ 2079 3589976 : for (i = 0; i < size; i += 16) {
+ 2080 3545920 : asm volatile ("movdqa %0,%%xmm0" : : "m" (p[0][i]));
+ 2081 3545920 : asm volatile ("movdqa %0,%%xmm2" : : "m" (pa[0][i]));
+ 2082 3545920 : asm volatile ("movdqa %0,%%xmm1" : : "m" (p[1][i]));
+ 2083 3545920 : asm volatile ("movdqa %0,%%xmm3" : : "m" (pa[1][i]));
+ 2084 3545920 : asm volatile ("pxor %xmm2,%xmm0");
+ 2085 3545920 : asm volatile ("pxor %xmm3,%xmm1");
2086 :
- 2087 3560064 : asm volatile ("pxor %xmm6,%xmm6");
+ 2087 3545920 : asm volatile ("pxor %xmm6,%xmm6");
2088 :
- 2089 3560064 : asm volatile ("movdqa %0,%%xmm2" : : "m" (gfmulpshufb[V[0]][0][0]));
- 2090 3560064 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfmulpshufb[V[0]][1][0]));
- 2091 3560064 : asm volatile ("movdqa %xmm0,%xmm4");
- 2092 3560064 : asm volatile ("movdqa %xmm0,%xmm5");
- 2093 3560064 : asm volatile ("psrlw $4,%xmm5");
- 2094 3560064 : asm volatile ("pand %xmm7,%xmm4");
- 2095 3560064 : asm volatile ("pand %xmm7,%xmm5");
- 2096 3560064 : asm volatile ("pshufb %xmm4,%xmm2");
- 2097 3560064 : asm volatile ("pshufb %xmm5,%xmm3");
- 2098 3560064 : asm volatile ("pxor %xmm2,%xmm6");
- 2099 3560064 : asm volatile ("pxor %xmm3,%xmm6");
+ 2089 3545920 : asm volatile ("movdqa %0,%%xmm2" : : "m" (gfmulpshufb[V[0]][0][0]));
+ 2090 3545920 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfmulpshufb[V[0]][1][0]));
+ 2091 3545920 : asm volatile ("movdqa %xmm0,%xmm4");
+ 2092 3545920 : asm volatile ("movdqa %xmm0,%xmm5");
+ 2093 3545920 : asm volatile ("psrlw $4,%xmm5");
+ 2094 3545920 : asm volatile ("pand %xmm7,%xmm4");
+ 2095 3545920 : asm volatile ("pand %xmm7,%xmm5");
+ 2096 3545920 : asm volatile ("pshufb %xmm4,%xmm2");
+ 2097 3545920 : asm volatile ("pshufb %xmm5,%xmm3");
+ 2098 3545920 : asm volatile ("pxor %xmm2,%xmm6");
+ 2099 3545920 : asm volatile ("pxor %xmm3,%xmm6");
2100 :
- 2101 3560064 : asm volatile ("movdqa %0,%%xmm2" : : "m" (gfmulpshufb[V[1]][0][0]));
- 2102 3560064 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfmulpshufb[V[1]][1][0]));
- 2103 3560064 : asm volatile ("movdqa %xmm1,%xmm4");
- 2104 3560064 : asm volatile ("movdqa %xmm1,%xmm5");
- 2105 3560064 : asm volatile ("psrlw $4,%xmm5");
- 2106 3560064 : asm volatile ("pand %xmm7,%xmm4");
- 2107 3560064 : asm volatile ("pand %xmm7,%xmm5");
- 2108 3560064 : asm volatile ("pshufb %xmm4,%xmm2");
- 2109 3560064 : asm volatile ("pshufb %xmm5,%xmm3");
- 2110 3560064 : asm volatile ("pxor %xmm2,%xmm6");
- 2111 3560064 : asm volatile ("pxor %xmm3,%xmm6");
+ 2101 3545920 : asm volatile ("movdqa %0,%%xmm2" : : "m" (gfmulpshufb[V[1]][0][0]));
+ 2102 3545920 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfmulpshufb[V[1]][1][0]));
+ 2103 3545920 : asm volatile ("movdqa %xmm1,%xmm4");
+ 2104 3545920 : asm volatile ("movdqa %xmm1,%xmm5");
+ 2105 3545920 : asm volatile ("psrlw $4,%xmm5");
+ 2106 3545920 : asm volatile ("pand %xmm7,%xmm4");
+ 2107 3545920 : asm volatile ("pand %xmm7,%xmm5");
+ 2108 3545920 : asm volatile ("pshufb %xmm4,%xmm2");
+ 2109 3545920 : asm volatile ("pshufb %xmm5,%xmm3");
+ 2110 3545920 : asm volatile ("pxor %xmm2,%xmm6");
+ 2111 3545920 : asm volatile ("pxor %xmm3,%xmm6");
2112 :
- 2113 3560064 : asm volatile ("movdqa %%xmm6,%0" : "=m" (pa[0][i]));
+ 2113 3545920 : asm volatile ("movdqa %%xmm6,%0" : "=m" (pa[0][i]));
2114 :
- 2115 3560064 : asm volatile ("pxor %xmm6,%xmm6");
+ 2115 3545920 : asm volatile ("pxor %xmm6,%xmm6");
2116 :
- 2117 3560064 : asm volatile ("movdqa %0,%%xmm2" : : "m" (gfmulpshufb[V[2]][0][0]));
- 2118 3560064 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfmulpshufb[V[2]][1][0]));
- 2119 3560064 : asm volatile ("movdqa %xmm0,%xmm4");
- 2120 3560064 : asm volatile ("movdqa %xmm0,%xmm5");
- 2121 3560064 : asm volatile ("psrlw $4,%xmm5");
- 2122 3560064 : asm volatile ("pand %xmm7,%xmm4");
- 2123 3560064 : asm volatile ("pand %xmm7,%xmm5");
- 2124 3560064 : asm volatile ("pshufb %xmm4,%xmm2");
- 2125 3560064 : asm volatile ("pshufb %xmm5,%xmm3");
- 2126 3560064 : asm volatile ("pxor %xmm2,%xmm6");
- 2127 3560064 : asm volatile ("pxor %xmm3,%xmm6");
+ 2117 3545920 : asm volatile ("movdqa %0,%%xmm2" : : "m" (gfmulpshufb[V[2]][0][0]));
+ 2118 3545920 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfmulpshufb[V[2]][1][0]));
+ 2119 3545920 : asm volatile ("movdqa %xmm0,%xmm4");
+ 2120 3545920 : asm volatile ("movdqa %xmm0,%xmm5");
+ 2121 3545920 : asm volatile ("psrlw $4,%xmm5");
+ 2122 3545920 : asm volatile ("pand %xmm7,%xmm4");
+ 2123 3545920 : asm volatile ("pand %xmm7,%xmm5");
+ 2124 3545920 : asm volatile ("pshufb %xmm4,%xmm2");
+ 2125 3545920 : asm volatile ("pshufb %xmm5,%xmm3");
+ 2126 3545920 : asm volatile ("pxor %xmm2,%xmm6");
+ 2127 3545920 : asm volatile ("pxor %xmm3,%xmm6");
2128 :
- 2129 3560064 : asm volatile ("movdqa %0,%%xmm2" : : "m" (gfmulpshufb[V[3]][0][0]));
- 2130 3560064 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfmulpshufb[V[3]][1][0]));
- 2131 3560064 : asm volatile ("movdqa %xmm1,%xmm4");
- 2132 3560064 : asm volatile ("movdqa %xmm1,%xmm5");
- 2133 3560064 : asm volatile ("psrlw $4,%xmm5");
- 2134 3560064 : asm volatile ("pand %xmm7,%xmm4");
- 2135 3560064 : asm volatile ("pand %xmm7,%xmm5");
- 2136 3560064 : asm volatile ("pshufb %xmm4,%xmm2");
- 2137 3560064 : asm volatile ("pshufb %xmm5,%xmm3");
- 2138 3560064 : asm volatile ("pxor %xmm2,%xmm6");
- 2139 3560064 : asm volatile ("pxor %xmm3,%xmm6");
+ 2129 3545920 : asm volatile ("movdqa %0,%%xmm2" : : "m" (gfmulpshufb[V[3]][0][0]));
+ 2130 3545920 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfmulpshufb[V[3]][1][0]));
+ 2131 3545920 : asm volatile ("movdqa %xmm1,%xmm4");
+ 2132 3545920 : asm volatile ("movdqa %xmm1,%xmm5");
+ 2133 3545920 : asm volatile ("psrlw $4,%xmm5");
+ 2134 3545920 : asm volatile ("pand %xmm7,%xmm4");
+ 2135 3545920 : asm volatile ("pand %xmm7,%xmm5");
+ 2136 3545920 : asm volatile ("pshufb %xmm4,%xmm2");
+ 2137 3545920 : asm volatile ("pshufb %xmm5,%xmm3");
+ 2138 3545920 : asm volatile ("pxor %xmm2,%xmm6");
+ 2139 3545920 : asm volatile ("pxor %xmm3,%xmm6");
2140 :
- 2141 3560064 : asm volatile ("movdqa %%xmm6,%0" : "=m" (pa[1][i]));
+ 2141 3545920 : asm volatile ("movdqa %%xmm6,%0" : "=m" (pa[1][i]));
2142 : }
2143 :
2144 : raid_sse_end();
- 2145 44277 : }
+ 2145 44056 : }
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 66ea680d..1631ce5f 100644
--- a/cov/raid/x86z.c.func-sort-c.html
+++ b/cov/raid/x86z.c.func-sort-c.html
@@ -61,7 +61,7 @@
| raid_genz_sse2 |
- 1175 |
+ 1174 |
diff --git a/cov/raid/x86z.c.func.html b/cov/raid/x86z.c.func.html
index 35e764a4..4a83023c 100644
--- a/cov/raid/x86z.c.func.html
+++ b/cov/raid/x86z.c.func.html
@@ -61,7 +61,7 @@
| raid_genz_sse2 |
- 1175 |
+ 1174 |
diff --git a/cov/raid/x86z.c.gcov.html b/cov/raid/x86z.c.gcov.html
index 98fd341d..74725de8 100644
--- a/cov/raid/x86z.c.gcov.html
+++ b/cov/raid/x86z.c.gcov.html
@@ -102,58 +102,58 @@
40 : /*
41 : * GENz (triple parity with powers of 2^-1) SSE2 implementation
42 : */
- 43 1175 : void raid_genz_sse2(int nd, size_t size, void **vv)
+ 43 1174 : void raid_genz_sse2(int nd, size_t size, void **vv)
44 : {
- 45 1175 : uint8_t **v = (uint8_t**)vv;
+ 45 1174 : uint8_t **v = (uint8_t**)vv;
46 : uint8_t *p;
47 : uint8_t *q;
48 : uint8_t *r;
49 : int d, l;
50 : size_t i;
51 :
- 52 1175 : l = nd - 1;
- 53 1175 : p = v[nd];
- 54 1175 : q = v[nd + 1];
- 55 1175 : r = v[nd + 2];
+ 52 1174 : l = nd - 1;
+ 53 1174 : p = v[nd];
+ 54 1174 : q = v[nd + 1];
+ 55 1174 : r = v[nd + 2];
56 :
57 : raid_sse_begin();
58 :
- 59 1175 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfzconst16.poly[0]));
- 60 1175 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfzconst16.half[0]));
- 61 1175 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfzconst16.low7[0]));
+ 59 1174 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfzconst16.poly[0]));
+ 60 1174 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfzconst16.half[0]));
+ 61 1174 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfzconst16.low7[0]));
62 :
- 63 1362151 : for (i = 0; i < size; i += 16) {
- 64 1360976 : asm volatile ("movdqa %0,%%xmm0" : : "m" (v[l][i]));
- 65 1360976 : asm volatile ("movdqa %xmm0,%xmm1");
- 66 1360976 : asm volatile ("movdqa %xmm0,%xmm2");
- 67 10958080 : for (d = l - 1; d >= 0; --d) {
- 68 9597104 : asm volatile ("pxor %xmm4,%xmm4");
- 69 9597104 : asm volatile ("pcmpgtb %xmm1,%xmm4");
- 70 9597104 : asm volatile ("paddb %xmm1,%xmm1");
- 71 9597104 : asm volatile ("pand %xmm7,%xmm4");
- 72 9597104 : asm volatile ("pxor %xmm4,%xmm1");
+ 63 1345766 : for (i = 0; i < size; i += 16) {
+ 64 1344592 : asm volatile ("movdqa %0,%%xmm0" : : "m" (v[l][i]));
+ 65 1344592 : asm volatile ("movdqa %xmm0,%xmm1");
+ 66 1344592 : asm volatile ("movdqa %xmm0,%xmm2");
+ 67 10827008 : for (d = l - 1; d >= 0; --d) {
+ 68 9482416 : asm volatile ("pxor %xmm4,%xmm4");
+ 69 9482416 : asm volatile ("pcmpgtb %xmm1,%xmm4");
+ 70 9482416 : asm volatile ("paddb %xmm1,%xmm1");
+ 71 9482416 : asm volatile ("pand %xmm7,%xmm4");
+ 72 9482416 : asm volatile ("pxor %xmm4,%xmm1");
73 :
- 74 9597104 : asm volatile ("movdqa %xmm2,%xmm4");
- 75 9597104 : asm volatile ("pxor %xmm5,%xmm5");
- 76 9597104 : asm volatile ("psllw $7,%xmm4");
- 77 9597104 : asm volatile ("psrlw $1,%xmm2");
- 78 9597104 : asm volatile ("pcmpgtb %xmm4,%xmm5");
- 79 9597104 : asm volatile ("pand %xmm6,%xmm2");
- 80 9597104 : asm volatile ("pand %xmm3,%xmm5");
- 81 9597104 : asm volatile ("pxor %xmm5,%xmm2");
+ 74 9482416 : asm volatile ("movdqa %xmm2,%xmm4");
+ 75 9482416 : asm volatile ("pxor %xmm5,%xmm5");
+ 76 9482416 : asm volatile ("psllw $7,%xmm4");
+ 77 9482416 : asm volatile ("psrlw $1,%xmm2");
+ 78 9482416 : asm volatile ("pcmpgtb %xmm4,%xmm5");
+ 79 9482416 : asm volatile ("pand %xmm6,%xmm2");
+ 80 9482416 : asm volatile ("pand %xmm3,%xmm5");
+ 81 9482416 : asm volatile ("pxor %xmm5,%xmm2");
82 :
- 83 9597104 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[d][i]));
- 84 9597104 : asm volatile ("pxor %xmm4,%xmm0");
- 85 9597104 : asm volatile ("pxor %xmm4,%xmm1");
- 86 9597104 : asm volatile ("pxor %xmm4,%xmm2");
+ 83 9482416 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[d][i]));
+ 84 9482416 : asm volatile ("pxor %xmm4,%xmm0");
+ 85 9482416 : asm volatile ("pxor %xmm4,%xmm1");
+ 86 9482416 : asm volatile ("pxor %xmm4,%xmm2");
87 : }
- 88 1360976 : asm volatile ("movntdq %%xmm0,%0" : "=m" (p[i]));
- 89 1360976 : asm volatile ("movntdq %%xmm1,%0" : "=m" (q[i]));
- 90 1360976 : asm volatile ("movntdq %%xmm2,%0" : "=m" (r[i]));
+ 88 1344592 : asm volatile ("movntdq %%xmm0,%0" : "=m" (p[i]));
+ 89 1344592 : asm volatile ("movntdq %%xmm1,%0" : "=m" (q[i]));
+ 90 1344592 : asm volatile ("movntdq %%xmm2,%0" : "=m" (r[i]));
91 : }
92 :
93 : raid_sse_end();
- 94 1175 : }
+ 94 1174 : }
95 : #endif
96 :
97 : #if defined(CONFIG_X86_64) && defined(CONFIG_SSE2)
diff --git a/cov/tommyds/tommyarray.c.func-sort-c.html b/cov/tommyds/tommyarray.c.func-sort-c.html
index 30dfbc0e..e115e780 100644
--- a/cov/tommyds/tommyarray.c.func-sort-c.html
+++ b/cov/tommyds/tommyarray.c.func-sort-c.html
@@ -61,15 +61,15 @@
| tommy_array_grow |
- 2202 |
+ 2208 |
| tommy_array_init |
- 519 |
+ 521 |
| tommy_array_done |
- 496 |
+ 497 |
| tommy_array_memory_usage |
diff --git a/cov/tommyds/tommyarray.c.func.html b/cov/tommyds/tommyarray.c.func.html
index 5d86fce0..7c16efad 100644
--- a/cov/tommyds/tommyarray.c.func.html
+++ b/cov/tommyds/tommyarray.c.func.html
@@ -61,15 +61,15 @@
| tommy_array_done |
- 496 |
+ 497 |
| tommy_array_grow |
- 2202 |
+ 2208 |
| tommy_array_init |
- 519 |
+ 521 |
| tommy_array_memory_usage |
diff --git a/cov/tommyds/tommyarray.c.gcov.html b/cov/tommyds/tommyarray.c.gcov.html
index a9f1e57f..0a0f2952 100644
--- a/cov/tommyds/tommyarray.c.gcov.html
+++ b/cov/tommyds/tommyarray.c.gcov.html
@@ -92,38 +92,38 @@
30 : /******************************************************************************/
31 : /* array */
32 :
- 33 519 : void tommy_array_init(tommy_array* array)
+ 33 521 : void tommy_array_init(tommy_array* array)
34 : {
35 : tommy_uint_t i;
36 :
37 : /* fixed initial size */
- 38 519 : array->bucket_bit = TOMMY_ARRAY_BIT;
- 39 519 : array->bucket_max = 1 << array->bucket_bit;
- 40 519 : array->bucket[0] = tommy_cast(void**, tommy_calloc(array->bucket_max, sizeof(void*)));
- 41 3114 : for (i = 1; i < TOMMY_ARRAY_BIT; ++i)
- 42 2595 : array->bucket[i] = array->bucket[0];
+ 38 521 : array->bucket_bit = TOMMY_ARRAY_BIT;
+ 39 521 : array->bucket_max = 1 << array->bucket_bit;
+ 40 521 : array->bucket[0] = tommy_cast(void**, tommy_calloc(array->bucket_max, sizeof(void*)));
+ 41 3126 : for (i = 1; i < TOMMY_ARRAY_BIT; ++i)
+ 42 2605 : array->bucket[i] = array->bucket[0];
43 :
- 44 519 : array->count = 0;
- 45 519 : }
+ 44 521 : array->count = 0;
+ 45 521 : }
46 :
- 47 496 : void tommy_array_done(tommy_array* array)
+ 47 497 : void tommy_array_done(tommy_array* array)
48 : {
49 : tommy_uint_t i;
50 :
- 51 496 : tommy_free(array->bucket[0]);
- 52 498 : for (i = TOMMY_ARRAY_BIT; i < array->bucket_bit; ++i) {
+ 51 497 : tommy_free(array->bucket[0]);
+ 52 499 : for (i = TOMMY_ARRAY_BIT; i < array->bucket_bit; ++i) {
53 2 : void** segment = array->bucket[i];
54 2 : tommy_free(&segment[((tommy_ptrdiff_t)1) << i]);
55 : }
- 56 496 : }
+ 56 497 : }
57 :
- 58 2202 : void tommy_array_grow(tommy_array* array, tommy_count_t count)
+ 58 2208 : void tommy_array_grow(tommy_array* array, tommy_count_t count)
59 : {
- 60 2202 : if (array->count >= count)
- 61 2202 : return;
- 62 2202 : array->count = count;
+ 60 2208 : if (array->count >= count)
+ 61 2208 : return;
+ 62 2208 : array->count = count;
63 :
- 64 4406 : while (count > array->bucket_max) {
+ 64 4418 : while (count > array->bucket_max) {
65 : void** segment;
66 :
67 : /* allocate one more segment */
diff --git a/cov/tommyds/tommyarray.h.func-sort-c.html b/cov/tommyds/tommyarray.h.func-sort-c.html
index 5c231686..95ea2d0e 100644
--- a/cov/tommyds/tommyarray.h.func-sort-c.html
+++ b/cov/tommyds/tommyarray.h.func-sort-c.html
@@ -61,19 +61,19 @@
| tommy_array_ref |
- 10268450 |
+ 10268715 |
| tommy_array_get |
- 10266248 |
+ 10266507 |
| tommy_array_size |
- 1575664 |
+ 1575720 |
| tommy_array_set |
- 2202 |
+ 2208 |
| tommy_array_insert |
diff --git a/cov/tommyds/tommyarray.h.func.html b/cov/tommyds/tommyarray.h.func.html
index 81a02afe..cf45dc82 100644
--- a/cov/tommyds/tommyarray.h.func.html
+++ b/cov/tommyds/tommyarray.h.func.html
@@ -61,7 +61,7 @@
| tommy_array_get |
- 10266248 |
+ 10266507 |
| tommy_array_insert |
@@ -69,15 +69,15 @@
| tommy_array_ref |
- 10268450 |
+ 10268715 |
| tommy_array_set |
- 2202 |
+ 2208 |
| tommy_array_size |
- 1575664 |
+ 1575720 |
diff --git a/cov/tommyds/tommyarray.h.gcov.html b/cov/tommyds/tommyarray.h.gcov.html
index c6b33ddb..1015219a 100644
--- a/cov/tommyds/tommyarray.h.gcov.html
+++ b/cov/tommyds/tommyarray.h.gcov.html
@@ -152,16 +152,16 @@
90 : * You must be sure that space for this position is already
91 : * allocated calling tommy_array_grow().
92 : */
- 93 10268450 : tommy_inline void** tommy_array_ref(tommy_array* array, tommy_count_t pos)
+ 93 10268715 : tommy_inline void** tommy_array_ref(tommy_array* array, tommy_count_t pos)
94 : {
95 : tommy_uint_t bsr;
96 :
- 97 10268450 : assert(pos < array->count);
+ 97 10268715 : assert(pos < array->count);
98 :
99 : /* get the highest bit set, in case of all 0, return 0 */
- 100 10268450 : bsr = tommy_ilog2_u32(pos | 1);
+ 100 10268715 : bsr = tommy_ilog2_u32(pos | 1);
101 :
- 102 10268450 : return &array->bucket[bsr][pos];
+ 102 10268715 : return &array->bucket[bsr][pos];
103 : }
104 :
105 : /**
@@ -169,19 +169,19 @@
107 : * You must be sure that space for this position is already
108 : * allocated calling tommy_array_grow().
109 : */
- 110 2202 : tommy_inline void tommy_array_set(tommy_array* array, tommy_count_t pos, void* element)
+ 110 2208 : tommy_inline void tommy_array_set(tommy_array* array, tommy_count_t pos, void* element)
111 : {
- 112 2202 : *tommy_array_ref(array, pos) = element;
- 113 2202 : }
+ 112 2208 : *tommy_array_ref(array, pos) = element;
+ 113 2208 : }
114 :
115 : /**
116 : * Gets the element at the specified position.
117 : * You must be sure that space for this position is already
118 : * allocated calling tommy_array_grow().
119 : */
- 120 10266248 : tommy_inline void* tommy_array_get(tommy_array* array, tommy_count_t pos)
+ 120 10266507 : tommy_inline void* tommy_array_get(tommy_array* array, tommy_count_t pos)
121 : {
- 122 10266248 : return *tommy_array_ref(array, pos);
+ 122 10266507 : return *tommy_array_ref(array, pos);
123 : }
124 :
125 : /**
@@ -199,9 +199,9 @@
137 : /**
138 : * Gets the initialized size of the array.
139 : */
- 140 1575664 : tommy_inline tommy_count_t tommy_array_size(tommy_array* array)
+ 140 1575720 : tommy_inline tommy_count_t tommy_array_size(tommy_array* array)
141 : {
- 142 1575664 : return array->count;
+ 142 1575720 : return array->count;
143 : }
144 :
145 : /**
diff --git a/cov/tommyds/tommyarrayblkof.c.func-sort-c.html b/cov/tommyds/tommyarrayblkof.c.func-sort-c.html
index 3eaf9665..1655a127 100644
--- a/cov/tommyds/tommyarrayblkof.c.func-sort-c.html
+++ b/cov/tommyds/tommyarrayblkof.c.func-sort-c.html
@@ -61,11 +61,11 @@
| tommy_arrayblkof_grow |
- 1698221 |
+ 1698354 |
| tommy_arrayblkof_init |
- 266 |
+ 267 |
| tommy_arrayblkof_done |
diff --git a/cov/tommyds/tommyarrayblkof.c.func.html b/cov/tommyds/tommyarrayblkof.c.func.html
index 2887d111..0298d5a6 100644
--- a/cov/tommyds/tommyarrayblkof.c.func.html
+++ b/cov/tommyds/tommyarrayblkof.c.func.html
@@ -65,11 +65,11 @@
| tommy_arrayblkof_grow |
- 1698221 |
+ 1698354 |
| tommy_arrayblkof_init |
- 266 |
+ 267 |
| tommy_arrayblkof_memory_usage |
diff --git a/cov/tommyds/tommyarrayblkof.c.gcov.html b/cov/tommyds/tommyarrayblkof.c.gcov.html
index e03fe466..86df9035 100644
--- a/cov/tommyds/tommyarrayblkof.c.gcov.html
+++ b/cov/tommyds/tommyarrayblkof.c.gcov.html
@@ -92,13 +92,13 @@
30 : /******************************************************************************/
31 : /* array */
32 :
- 33 266 : void tommy_arrayblkof_init(tommy_arrayblkof* array, tommy_size_t element_size)
+ 33 267 : void tommy_arrayblkof_init(tommy_arrayblkof* array, tommy_size_t element_size)
34 : {
- 35 266 : tommy_array_init(&array->block);
+ 35 267 : tommy_array_init(&array->block);
36 :
- 37 266 : array->element_size = element_size;
- 38 266 : array->count = 0;
- 39 266 : }
+ 37 267 : array->element_size = element_size;
+ 38 267 : array->count = 0;
+ 39 267 : }
40 :
41 244 : void tommy_arrayblkof_done(tommy_arrayblkof* array)
42 : {
@@ -110,30 +110,30 @@
48 244 : tommy_array_done(&array->block);
49 244 : }
50 :
- 51 1698221 : void tommy_arrayblkof_grow(tommy_arrayblkof* array, tommy_count_t count)
+ 51 1698354 : 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 1698221 : if (array->count >= count)
- 57 1821547 : return;
- 58 1574895 : array->count = count;
+ 56 1698354 : if (array->count >= count)
+ 57 1821757 : return;
+ 58 1574951 : array->count = count;
59 :
- 60 1574895 : block_max = (count + TOMMY_ARRAYBLKOF_SIZE - 1) / TOMMY_ARRAYBLKOF_SIZE;
- 61 1574895 : block_mac = tommy_array_size(&array->block);
+ 60 1574951 : block_max = (count + TOMMY_ARRAYBLKOF_SIZE - 1) / TOMMY_ARRAYBLKOF_SIZE;
+ 61 1574951 : block_mac = tommy_array_size(&array->block);
62 :
- 63 1574895 : if (block_mac < block_max) {
+ 63 1574951 : if (block_mac < block_max) {
64 : /* grow the block array */
- 65 553 : tommy_array_grow(&array->block, block_max);
+ 65 554 : tommy_array_grow(&array->block, block_max);
66 :
67 : /* allocate new blocks */
- 68 1659 : while (block_mac < block_max) {
- 69 553 : void** ptr = tommy_cast(void**, tommy_calloc(TOMMY_ARRAYBLKOF_SIZE, array->element_size));
+ 68 1662 : while (block_mac < block_max) {
+ 69 554 : void** ptr = tommy_cast(void**, tommy_calloc(TOMMY_ARRAYBLKOF_SIZE, array->element_size));
70 :
71 : /* set the new block */
- 72 553 : tommy_array_set(&array->block, block_mac, ptr);
+ 72 554 : tommy_array_set(&array->block, block_mac, ptr);
73 :
- 74 553 : ++block_mac;
+ 74 554 : ++block_mac;
75 : }
76 : }
77 : }
diff --git a/cov/tommyds/tommyarrayblkof.h.func-sort-c.html b/cov/tommyds/tommyarrayblkof.h.func-sort-c.html
index 5225e0d5..671bddbe 100644
--- a/cov/tommyds/tommyarrayblkof.h.func-sort-c.html
+++ b/cov/tommyds/tommyarrayblkof.h.func-sort-c.html
@@ -61,11 +61,11 @@
| tommy_arrayblkof_ref |
- 6534208 |
+ 6534594 |
| tommy_arrayblkof_size |
- 5098374 |
+ 5098627 |
diff --git a/cov/tommyds/tommyarrayblkof.h.func.html b/cov/tommyds/tommyarrayblkof.h.func.html
index 5a41dd06..254995bd 100644
--- a/cov/tommyds/tommyarrayblkof.h.func.html
+++ b/cov/tommyds/tommyarrayblkof.h.func.html
@@ -61,11 +61,11 @@
| tommy_arrayblkof_ref |
- 6534208 |
+ 6534594 |
| tommy_arrayblkof_size |
- 5098374 |
+ 5098627 |
diff --git a/cov/tommyds/tommyarrayblkof.h.gcov.html b/cov/tommyds/tommyarrayblkof.h.gcov.html
index 4116fde7..edffddf2 100644
--- a/cov/tommyds/tommyarrayblkof.h.gcov.html
+++ b/cov/tommyds/tommyarrayblkof.h.gcov.html
@@ -148,23 +148,23 @@
86 : * You must be sure that space for this position is already
87 : * allocated calling tommy_arrayblkof_grow().
88 : */
- 89 6534208 : tommy_inline void* tommy_arrayblkof_ref(tommy_arrayblkof* array, tommy_count_t pos)
+ 89 6534594 : tommy_inline void* tommy_arrayblkof_ref(tommy_arrayblkof* array, tommy_count_t pos)
90 : {
91 : unsigned char* base;
92 :
- 93 6534208 : assert(pos < array->count);
+ 93 6534594 : assert(pos < array->count);
94 :
- 95 6534208 : base = tommy_cast(unsigned char*, tommy_array_get(&array->block, pos / TOMMY_ARRAYBLKOF_SIZE));
+ 95 6534594 : base = tommy_cast(unsigned char*, tommy_array_get(&array->block, pos / TOMMY_ARRAYBLKOF_SIZE));
96 :
- 97 6534208 : return base + (pos % TOMMY_ARRAYBLKOF_SIZE) * array->element_size;
+ 97 6534594 : return base + (pos % TOMMY_ARRAYBLKOF_SIZE) * array->element_size;
98 : }
99 :
100 : /**
101 : * Gets the initialized size of the array.
102 : */
- 103 5098374 : tommy_inline tommy_count_t tommy_arrayblkof_size(tommy_arrayblkof* array)
+ 103 5098627 : tommy_inline tommy_count_t tommy_arrayblkof_size(tommy_arrayblkof* array)
104 : {
- 105 5098374 : return array->count;
+ 105 5098627 : 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 aff5319b..cd51b466 100644
--- a/cov/tommyds/tommychain.h.func-sort-c.html
+++ b/cov/tommyds/tommychain.h.func-sort-c.html
@@ -61,23 +61,23 @@
| tommy_chain_splice |
- 4502405 |
+ 4492296 |
| tommy_chain_merge_degenerated |
- 1283232 |
+ 1283291 |
| tommy_chain_concat |
- 1276403 |
+ 1276680 |
| tommy_chain_merge |
- 471088 |
+ 470675 |
| tommy_chain_mergesort |
- 1684 |
+ 1693 |
diff --git a/cov/tommyds/tommychain.h.func.html b/cov/tommyds/tommychain.h.func.html
index 9025ad4e..7584db51 100644
--- a/cov/tommyds/tommychain.h.func.html
+++ b/cov/tommyds/tommychain.h.func.html
@@ -61,23 +61,23 @@
| tommy_chain_concat |
- 1276403 |
+ 1276680 |
| tommy_chain_merge |
- 471088 |
+ 470675 |
| tommy_chain_merge_degenerated |
- 1283232 |
+ 1283291 |
| tommy_chain_mergesort |
- 1684 |
+ 1693 |
| tommy_chain_splice |
- 4502405 |
+ 4492296 |
diff --git a/cov/tommyds/tommychain.h.gcov.html b/cov/tommyds/tommychain.h.gcov.html
index d8fd9841..ac4fc97a 100644
--- a/cov/tommyds/tommychain.h.gcov.html
+++ b/cov/tommyds/tommychain.h.gcov.html
@@ -119,83 +119,83 @@
57 : /**
58 : * Splices a chain in the middle of another chain.
59 : */
- 60 4502405 : tommy_inline void tommy_chain_splice(tommy_node* first_before, tommy_node* first_after, tommy_node* second_head, tommy_node* second_tail)
+ 60 4492296 : 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 4502405 : first_after->prev = second_tail;
- 64 4502405 : second_head->prev = first_before;
+ 63 4492296 : first_after->prev = second_tail;
+ 64 4492296 : second_head->prev = first_before;
65 :
66 : /* set the next list */
- 67 4502405 : first_before->next = second_head;
- 68 4502405 : second_tail->next = first_after;
- 69 4502405 : }
+ 67 4492296 : first_before->next = second_head;
+ 68 4492296 : second_tail->next = first_after;
+ 69 4492296 : }
70 :
71 : /**
72 : * Concats two chains.
73 : */
- 74 1276403 : tommy_inline void tommy_chain_concat(tommy_node* first_tail, tommy_node* second_head)
+ 74 1276680 : tommy_inline void tommy_chain_concat(tommy_node* first_tail, tommy_node* second_head)
75 : {
76 : /* set the prev list */
- 77 1276403 : second_head->prev = first_tail;
+ 77 1276680 : second_head->prev = first_tail;
78 :
79 : /* set the next list */
- 80 1276403 : first_tail->next = second_head;
- 81 1276403 : }
+ 80 1276680 : first_tail->next = second_head;
+ 81 1276680 : }
82 :
83 : /**
84 : * Merges two chains.
85 : */
- 86 471088 : tommy_inline void tommy_chain_merge(tommy_chain* first, tommy_chain* second, tommy_compare_func* cmp)
+ 86 470675 : tommy_inline void tommy_chain_merge(tommy_chain* first, tommy_chain* second, tommy_compare_func* cmp)
87 : {
- 88 471088 : tommy_node* first_i = first->head;
- 89 471088 : tommy_node* second_i = second->head;
+ 88 470675 : tommy_node* first_i = first->head;
+ 89 470675 : tommy_node* second_i = second->head;
90 :
91 : /* merge */
92 : while (1) {
- 93 9796567 : if (cmp(first_i->data, second_i->data) > 0) {
- 94 4734738 : tommy_node* next = second_i->next;
- 95 4734738 : if (first_i == first->head) {
- 96 232333 : tommy_chain_concat(second_i, first_i);
- 97 232333 : first->head = second_i;
+ 93 9777862 : if (cmp(first_i->data, second_i->data) > 0) {
+ 94 4724569 : tommy_node* next = second_i->next;
+ 95 4724569 : if (first_i == first->head) {
+ 96 232273 : tommy_chain_concat(second_i, first_i);
+ 97 232273 : first->head = second_i;
98 : } else {
- 99 4502405 : tommy_chain_splice(first_i->prev, first_i, second_i, second_i);
+ 99 4492296 : tommy_chain_splice(first_i->prev, first_i, second_i, second_i);
100 : }
- 101 4734738 : if (second_i == second->tail)
- 102 239162 : break;
- 103 4495576 : second_i = next;
+ 101 4724569 : if (second_i == second->tail)
+ 102 238884 : break;
+ 103 4485685 : second_i = next;
104 : } else {
- 105 5061829 : if (first_i == first->tail) {
- 106 231926 : tommy_chain_concat(first_i, second_i);
- 107 231926 : first->tail = second->tail;
- 108 231926 : break;
+ 105 5053293 : if (first_i == first->tail) {
+ 106 231791 : tommy_chain_concat(first_i, second_i);
+ 107 231791 : first->tail = second->tail;
+ 108 231791 : break;
109 : }
- 110 4829903 : first_i = first_i->next;
+ 110 4821502 : first_i = first_i->next;
111 : }
- 112 9325479 : }
- 113 471088 : }
+ 112 9307187 : }
+ 113 470675 : }
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 1283232 : tommy_inline void tommy_chain_merge_degenerated(tommy_chain* first, tommy_chain* second, tommy_compare_func* cmp)
+ 119 1283291 : 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 1283232 : if (cmp(first->tail->data, second->head->data) <= 0) {
- 123 477330 : tommy_chain_concat(first->tail, second->head);
- 124 477330 : first->tail = second->tail;
- 125 477330 : return;
+ 122 1283291 : if (cmp(first->tail->data, second->head->data) <= 0) {
+ 123 477903 : tommy_chain_concat(first->tail, second->head);
+ 124 477903 : first->tail = second->tail;
+ 125 477903 : return;
126 : }
127 :
128 : /* identify the condition second < first */
129 : /* here we must be strict on comparison to keep the sort stable */
- 130 805902 : if (cmp(second->tail->data, first->head->data) < 0) {
- 131 334814 : tommy_chain_concat(second->tail, first->head);
- 132 334814 : first->head = second->head;
- 133 334814 : return;
+ 130 805388 : if (cmp(second->tail->data, first->head->data) < 0) {
+ 131 334713 : tommy_chain_concat(second->tail, first->head);
+ 132 334713 : first->head = second->head;
+ 133 334713 : return;
134 : }
135 :
- 136 471088 : tommy_chain_merge(first, second, cmp);
+ 136 470675 : tommy_chain_merge(first, second, cmp);
137 : }
138 :
139 : /**
@@ -215,7 +215,7 @@
153 : * Linux Kernel lib/list_sort.c
154 : * http://lxr.linux.no/#linux+v2.6.36/lib/list_sort.c
155 : */
- 156 1684 : tommy_inline void tommy_chain_mergesort(tommy_chain* chain, tommy_compare_func* cmp)
+ 156 1693 : tommy_inline void tommy_chain_mergesort(tommy_chain* chain, tommy_compare_func* cmp)
157 : {
158 : /*
159 : * Bit buckets of chains.
@@ -230,57 +230,57 @@
168 : * It's used to know which bucket is empty of full.
169 : */
170 : tommy_count_t counter;
- 171 1684 : tommy_node* node = chain->head;
- 172 1684 : tommy_node* tail = chain->tail;
+ 171 1693 : tommy_node* node = chain->head;
+ 172 1693 : tommy_node* tail = chain->tail;
173 : tommy_count_t mask;
174 : tommy_count_t i;
175 :
- 176 1684 : counter = 0;
+ 176 1693 : counter = 0;
177 : while (1) {
178 : tommy_node* next;
179 : tommy_chain* last;
180 :
181 : /* carry bit to add */
- 182 1284916 : last = &bit[TOMMY_CHAIN_BIT_MAX];
- 183 1284916 : bit[TOMMY_CHAIN_BIT_MAX].head = node;
- 184 1284916 : bit[TOMMY_CHAIN_BIT_MAX].tail = node;
- 185 1284916 : next = node->next;
+ 182 1284984 : last = &bit[TOMMY_CHAIN_BIT_MAX];
+ 183 1284984 : bit[TOMMY_CHAIN_BIT_MAX].head = node;
+ 184 1284984 : bit[TOMMY_CHAIN_BIT_MAX].tail = node;
+ 185 1284984 : next = node->next;
186 :
187 : /* add the bit, propagating the carry */
- 188 1284916 : i = 0;
- 189 1284916 : mask = counter;
- 190 3847013 : while ((mask & 1) != 0) {
- 191 1277181 : tommy_chain_merge_degenerated(&bit[i], last, cmp);
- 192 1277181 : mask >>= 1;
- 193 1277181 : last = &bit[i];
- 194 1277181 : ++i;
+ 188 1284984 : i = 0;
+ 189 1284984 : mask = counter;
+ 190 3847206 : while ((mask & 1) != 0) {
+ 191 1277238 : tommy_chain_merge_degenerated(&bit[i], last, cmp);
+ 192 1277238 : mask >>= 1;
+ 193 1277238 : last = &bit[i];
+ 194 1277238 : ++i;
195 : }
196 :
197 : /* copy the carry in the first empty bit */
- 198 1284916 : bit[i] = *last;
+ 198 1284984 : bit[i] = *last;
199 :
200 : /* add the carry in the counter */
- 201 1284916 : ++counter;
+ 201 1284984 : ++counter;
202 :
- 203 1284916 : if (node == tail)
- 204 1684 : break;
- 205 1283232 : node = next;
- 206 1283232 : }
+ 203 1284984 : if (node == tail)
+ 204 1693 : break;
+ 205 1283291 : node = next;
+ 206 1283291 : }
207 :
208 : /* merge the buckets */
- 209 1684 : i = tommy_ctz_u32(counter);
- 210 1684 : mask = counter >> i;
- 211 12396 : while (mask != 1) {
- 212 9028 : mask >>= 1;
- 213 9028 : if (mask & 1)
- 214 6051 : tommy_chain_merge_degenerated(&bit[i + 1], &bit[i], cmp);
+ 209 1693 : i = tommy_ctz_u32(counter);
+ 210 1693 : mask = counter >> i;
+ 211 12413 : while (mask != 1) {
+ 212 9027 : mask >>= 1;
+ 213 9027 : if (mask & 1)
+ 214 6053 : tommy_chain_merge_degenerated(&bit[i + 1], &bit[i], cmp);
215 : else
- 216 2977 : bit[i + 1] = bit[i];
- 217 9028 : ++i;
+ 216 2974 : bit[i + 1] = bit[i];
+ 217 9027 : ++i;
218 : }
219 :
- 220 1684 : *chain = bit[i];
- 221 1684 : }
+ 220 1693 : *chain = bit[i];
+ 221 1693 : }
222 :
223 : #endif
224 :
diff --git a/cov/tommyds/tommyhash.c.func-sort-c.html b/cov/tommyds/tommyhash.c.func-sort-c.html
index 0e1009a9..d59abafe 100644
--- a/cov/tommyds/tommyhash.c.func-sort-c.html
+++ b/cov/tommyds/tommyhash.c.func-sort-c.html
@@ -61,11 +61,11 @@
| tommy_le_uint32_read |
- 11587716 |
+ 11587314 |
| tommy_hash_u32 |
- 4059834 |
+ 4059737 |
| tommy_strhash_u32 |
diff --git a/cov/tommyds/tommyhash.c.func.html b/cov/tommyds/tommyhash.c.func.html
index 1dc814cc..217f4d7a 100644
--- a/cov/tommyds/tommyhash.c.func.html
+++ b/cov/tommyds/tommyhash.c.func.html
@@ -61,7 +61,7 @@
| tommy_hash_u32 |
- 4059834 |
+ 4059737 |
| tommy_hash_u64 |
@@ -69,7 +69,7 @@
| tommy_le_uint32_read |
- 11587716 |
+ 11587314 |
| tommy_strhash_u32 |
diff --git a/cov/tommyds/tommyhash.c.gcov.html b/cov/tommyds/tommyhash.c.gcov.html
index 9fd8bf6e..998b4290 100644
--- a/cov/tommyds/tommyhash.c.gcov.html
+++ b/cov/tommyds/tommyhash.c.gcov.html
@@ -92,12 +92,12 @@
30 : /******************************************************************************/
31 : /* hash */
32 :
- 33 11587716 : tommy_inline tommy_uint32_t tommy_le_uint32_read(const void* ptr)
+ 33 11587314 : 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 11587716 : return *(const tommy_uint32_t*)ptr;
+ 38 11587314 : 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 4059834 : tommy_uint32_t tommy_hash_u32(tommy_uint32_t init_val, const void* void_key, tommy_size_t key_len)
+ 69 4059737 : tommy_uint32_t tommy_hash_u32(tommy_uint32_t init_val, const void* void_key, tommy_size_t key_len)
70 : {
- 71 4059834 : const unsigned char* key = tommy_cast(const unsigned char*, void_key);
+ 71 4059737 : const unsigned char* key = tommy_cast(const unsigned char*, void_key);
72 : tommy_uint32_t a, b, c;
73 :
- 74 4059834 : a = b = c = 0xdeadbeef + ((tommy_uint32_t)key_len) + init_val;
+ 74 4059737 : a = b = c = 0xdeadbeef + ((tommy_uint32_t)key_len) + init_val;
75 :
- 76 10239927 : while (key_len > 12) {
- 77 2120259 : a += tommy_le_uint32_read(key + 0);
- 78 2120259 : b += tommy_le_uint32_read(key + 4);
- 79 2120259 : c += tommy_le_uint32_read(key + 8);
+ 76 10239675 : while (key_len > 12) {
+ 77 2120201 : a += tommy_le_uint32_read(key + 0);
+ 78 2120201 : b += tommy_le_uint32_read(key + 4);
+ 79 2120201 : c += tommy_le_uint32_read(key + 8);
80 :
- 81 2120259 : tommy_mix(a, b, c);
+ 81 2120201 : tommy_mix(a, b, c);
82 :
- 83 2120259 : key_len -= 12;
- 84 2120259 : key += 12;
+ 83 2120201 : key_len -= 12;
+ 84 2120201 : key += 12;
85 : }
86 :
- 87 4059834 : switch (key_len) {
+ 87 4059737 : switch (key_len) {
88 : case 0 :
89 1 : return c; /* used only when called with a zero length */
90 : case 12 :
- 91 207749 : c += tommy_le_uint32_read(key + 8);
- 92 207749 : b += tommy_le_uint32_read(key + 4);
- 93 207749 : a += tommy_le_uint32_read(key + 0);
- 94 207749 : break;
- 95 217406 : case 11 : c += ((tommy_uint32_t)key[10]) << 16;
- 96 640298 : case 10 : c += ((tommy_uint32_t)key[9]) << 8;
- 97 1060028 : case 9 : c += key[8];
+ 91 207727 : c += tommy_le_uint32_read(key + 8);
+ 92 207727 : b += tommy_le_uint32_read(key + 4);
+ 93 207727 : a += tommy_le_uint32_read(key + 0);
+ 94 207727 : break;
+ 95 217400 : case 11 : c += ((tommy_uint32_t)key[10]) << 16;
+ 96 640250 : case 10 : c += ((tommy_uint32_t)key[9]) << 8;
+ 97 1059946 : case 9 : c += key[8];
98 : case 8 :
- 99 1470945 : b += tommy_le_uint32_read(key + 4);
- 100 1470945 : a += tommy_le_uint32_read(key + 0);
- 101 1470945 : break;
- 102 413147 : case 7 : b += ((tommy_uint32_t)key[6]) << 16;
- 103 812922 : case 6 : b += ((tommy_uint32_t)key[5]) << 8;
- 104 1229617 : case 5 : b += key[4];
+ 99 1470855 : b += tommy_le_uint32_read(key + 4);
+ 100 1470855 : a += tommy_le_uint32_read(key + 0);
+ 101 1470855 : break;
+ 102 413128 : case 7 : b += ((tommy_uint32_t)key[6]) << 16;
+ 103 812916 : case 6 : b += ((tommy_uint32_t)key[5]) << 8;
+ 104 1229635 : case 5 : b += key[4];
105 : case 4 :
- 106 1661668 : a += tommy_le_uint32_read(key + 0);
- 107 1661668 : break;
- 108 301716 : case 3 : a += ((tommy_uint32_t)key[2]) << 16;
- 109 509499 : case 2 : a += ((tommy_uint32_t)key[1]) << 8;
- 110 719471 : case 1 : a += key[0];
+ 106 1661686 : a += tommy_le_uint32_read(key + 0);
+ 107 1661686 : break;
+ 108 301707 : case 3 : a += ((tommy_uint32_t)key[2]) << 16;
+ 109 509493 : case 2 : a += ((tommy_uint32_t)key[1]) << 8;
+ 110 719468 : case 1 : a += key[0];
111 : }
112 :
- 113 4059833 : tommy_final(a, b, c);
+ 113 4059736 : tommy_final(a, b, c);
114 :
- 115 4059833 : return c;
+ 115 4059736 : 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 cd71c362..16a1ee22 100644
--- a/cov/tommyds/tommyhash.h.func-sort-c.html
+++ b/cov/tommyds/tommyhash.h.func-sort-c.html
@@ -61,11 +61,11 @@
| tommy_inthash_u32 |
- 18827742 |
+ 18827424 |
| tommy_inthash_u64 |
- 5047846 |
+ 5047758 |
diff --git a/cov/tommyds/tommyhash.h.func.html b/cov/tommyds/tommyhash.h.func.html
index 85bde6e0..1933c0e3 100644
--- a/cov/tommyds/tommyhash.h.func.html
+++ b/cov/tommyds/tommyhash.h.func.html
@@ -61,11 +61,11 @@
| tommy_inthash_u32 |
- 18827742 |
+ 18827424 |
| tommy_inthash_u64 |
- 5047846 |
+ 5047758 |
diff --git a/cov/tommyds/tommyhash.h.gcov.html b/cov/tommyds/tommyhash.h.gcov.html
index 0f8705fe..12405e14 100644
--- a/cov/tommyds/tommyhash.h.gcov.html
+++ b/cov/tommyds/tommyhash.h.gcov.html
@@ -167,17 +167,17 @@
105 : * Implementation of the Robert Jenkins "4-byte Integer Hashing",
106 : * from http://burtleburtle.net/bob/hash/integer.html
107 : */
- 108 18827742 : tommy_inline tommy_uint32_t tommy_inthash_u32(tommy_uint32_t key)
+ 108 18827424 : tommy_inline tommy_uint32_t tommy_inthash_u32(tommy_uint32_t key)
109 : {
- 110 18827742 : key -= key << 6;
- 111 18827742 : key ^= key >> 17;
- 112 18827742 : key -= key << 9;
- 113 18827742 : key ^= key << 4;
- 114 18827742 : key -= key << 3;
- 115 18827742 : key ^= key << 10;
- 116 18827742 : key ^= key >> 15;
+ 110 18827424 : key -= key << 6;
+ 111 18827424 : key ^= key >> 17;
+ 112 18827424 : key -= key << 9;
+ 113 18827424 : key ^= key << 4;
+ 114 18827424 : key -= key << 3;
+ 115 18827424 : key ^= key << 10;
+ 116 18827424 : key ^= key >> 15;
117 :
- 118 18827742 : return key;
+ 118 18827424 : return key;
119 : }
120 :
121 : /**
@@ -185,17 +185,17 @@
123 : * Implementation of the Thomas Wang "Integer Hash Function",
124 : * from http://web.archive.org/web/20071223173210/http://www.concentric.net/~Ttwang/tech/inthash.htm
125 : */
- 126 5047846 : tommy_inline tommy_uint64_t tommy_inthash_u64(tommy_uint64_t key)
+ 126 5047758 : tommy_inline tommy_uint64_t tommy_inthash_u64(tommy_uint64_t key)
127 : {
- 128 5047846 : key = ~key + (key << 21);
- 129 5047846 : key = key ^ (key >> 24);
- 130 5047846 : key = key + (key << 3) + (key << 8);
- 131 5047846 : key = key ^ (key >> 14);
- 132 5047846 : key = key + (key << 2) + (key << 4);
- 133 5047846 : key = key ^ (key >> 28);
- 134 5047846 : key = key + (key << 31);
+ 128 5047758 : key = ~key + (key << 21);
+ 129 5047758 : key = key ^ (key >> 24);
+ 130 5047758 : key = key + (key << 3) + (key << 8);
+ 131 5047758 : key = key ^ (key >> 14);
+ 132 5047758 : key = key + (key << 2) + (key << 4);
+ 133 5047758 : key = key ^ (key >> 28);
+ 134 5047758 : key = key + (key << 31);
135 :
- 136 5047846 : return key;
+ 136 5047758 : return key;
137 : }
138 :
139 : #endif
diff --git a/cov/tommyds/tommyhashdyn.c.func-sort-c.html b/cov/tommyds/tommyhashdyn.c.func-sort-c.html
index 5ef41753..543ff5f0 100644
--- a/cov/tommyds/tommyhashdyn.c.func-sort-c.html
+++ b/cov/tommyds/tommyhashdyn.c.func-sort-c.html
@@ -61,27 +61,27 @@
| hashdyn_grow_step |
- 13237087 |
+ 13236976 |
| tommy_hashdyn_insert |
- 13237087 |
+ 13236976 |
| hashdyn_shrink_step |
- 281913 |
+ 282017 |
| tommy_hashdyn_remove_existing |
- 281785 |
+ 281889 |
| tommy_hashdyn_resize |
- 41541 |
+ 41538 |
| tommy_hashdyn_init |
- 8694 |
+ 8727 |
| tommy_hashdyn_done |
diff --git a/cov/tommyds/tommyhashdyn.c.func.html b/cov/tommyds/tommyhashdyn.c.func.html
index b5f91fa9..ef5510c7 100644
--- a/cov/tommyds/tommyhashdyn.c.func.html
+++ b/cov/tommyds/tommyhashdyn.c.func.html
@@ -61,11 +61,11 @@
| hashdyn_grow_step |
- 13237087 |
+ 13236976 |
| hashdyn_shrink_step |
- 281913 |
+ 282017 |
| tommy_hashdyn_done |
@@ -81,11 +81,11 @@
| tommy_hashdyn_init |
- 8694 |
+ 8727 |
| tommy_hashdyn_insert |
- 13237087 |
+ 13236976 |
| tommy_hashdyn_memory_usage |
@@ -97,11 +97,11 @@
| tommy_hashdyn_remove_existing |
- 281785 |
+ 281889 |
| tommy_hashdyn_resize |
- 41541 |
+ 41538 |
diff --git a/cov/tommyds/tommyhashdyn.c.gcov.html b/cov/tommyds/tommyhashdyn.c.gcov.html
index c8b02295..e0494f88 100644
--- a/cov/tommyds/tommyhashdyn.c.gcov.html
+++ b/cov/tommyds/tommyhashdyn.c.gcov.html
@@ -93,16 +93,16 @@
31 : /******************************************************************************/
32 : /* hashdyn */
33 :
- 34 8694 : void tommy_hashdyn_init(tommy_hashdyn* hashdyn)
+ 34 8727 : void tommy_hashdyn_init(tommy_hashdyn* hashdyn)
35 : {
36 : /* fixed initial size */
- 37 8694 : hashdyn->bucket_bit = TOMMY_HASHDYN_BIT;
- 38 8694 : hashdyn->bucket_max = 1 << hashdyn->bucket_bit;
- 39 8694 : hashdyn->bucket_mask = hashdyn->bucket_max - 1;
- 40 8694 : hashdyn->bucket = tommy_cast(tommy_hashdyn_node**, tommy_calloc(hashdyn->bucket_max, sizeof(tommy_hashdyn_node*)));
+ 37 8727 : hashdyn->bucket_bit = TOMMY_HASHDYN_BIT;
+ 38 8727 : hashdyn->bucket_max = 1 << hashdyn->bucket_bit;
+ 39 8727 : hashdyn->bucket_mask = hashdyn->bucket_max - 1;
+ 40 8727 : hashdyn->bucket = tommy_cast(tommy_hashdyn_node**, tommy_calloc(hashdyn->bucket_max, sizeof(tommy_hashdyn_node*)));
41 :
- 42 8694 : hashdyn->count = 0;
- 43 8694 : }
+ 42 8727 : hashdyn->count = 0;
+ 43 8727 : }
44 :
45 7998 : void tommy_hashdyn_done(tommy_hashdyn* hashdyn)
46 : {
@@ -112,7 +112,7 @@
50 : /**
51 : * Resize the bucket vector.
52 : */
- 53 41541 : static void tommy_hashdyn_resize(tommy_hashdyn* hashdyn, tommy_count_t new_bucket_bit)
+ 53 41538 : 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 41541 : bucket_bit = hashdyn->bucket_bit;
- 62 41541 : bucket_max = hashdyn->bucket_max;
+ 61 41538 : bucket_bit = hashdyn->bucket_bit;
+ 62 41538 : bucket_max = hashdyn->bucket_max;
63 :
- 64 41541 : new_bucket_max = 1 << new_bucket_bit;
- 65 41541 : new_bucket_mask = new_bucket_max - 1;
+ 64 41538 : new_bucket_max = 1 << new_bucket_bit;
+ 65 41538 : 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 41541 : new_bucket = tommy_cast(tommy_hashdyn_node**, tommy_malloc(new_bucket_max * sizeof(tommy_hashdyn_node*)));
+ 69 41538 : new_bucket = tommy_cast(tommy_hashdyn_node**, tommy_malloc(new_bucket_max * sizeof(tommy_hashdyn_node*)));
70 :
71 : /* reinsert all the elements */
- 72 41541 : if (new_bucket_bit > bucket_bit) {
+ 72 41538 : if (new_bucket_bit > bucket_bit) {
73 : tommy_count_t i;
74 :
75 : /* grow */
- 76 32198548 : for (i = 0; i < bucket_max; ++i) {
+ 76 32197009 : for (i = 0; i < bucket_max; ++i) {
77 : tommy_hashdyn_node* j;
78 :
79 : /* setup the new two buckets */
- 80 32157056 : new_bucket[i] = 0;
- 81 32157056 : new_bucket[i + bucket_max] = 0;
+ 80 32155520 : new_bucket[i] = 0;
+ 81 32155520 : new_bucket[i + bucket_max] = 0;
82 :
83 : /* reinsert the bucket */
- 84 32157056 : j = hashdyn->bucket[i];
- 85 80392640 : while (j) {
- 86 16078528 : tommy_hashdyn_node* j_next = j->next;
- 87 16078528 : tommy_count_t pos = j->key & new_bucket_mask;
- 88 16078528 : if (new_bucket[pos])
- 89 1915427 : tommy_list_insert_tail_not_empty(new_bucket[pos], j);
+ 84 32155520 : j = hashdyn->bucket[i];
+ 85 80388800 : while (j) {
+ 86 16077760 : tommy_hashdyn_node* j_next = j->next;
+ 87 16077760 : tommy_count_t pos = j->key & new_bucket_mask;
+ 88 16077760 : if (new_bucket[pos])
+ 89 1915117 : tommy_list_insert_tail_not_empty(new_bucket[pos], j);
90 : else
- 91 14163101 : tommy_list_insert_first(&new_bucket[pos], j);
- 92 16078528 : j = j_next;
+ 91 14162643 : tommy_list_insert_first(&new_bucket[pos], j);
+ 92 16077760 : j = j_next;
93 : }
94 : }
95 : } else {
@@ -167,59 +167,59 @@
105 : }
106 : }
107 :
- 108 41541 : tommy_free(hashdyn->bucket);
+ 108 41538 : tommy_free(hashdyn->bucket);
109 :
110 : /* setup */
- 111 41541 : hashdyn->bucket_bit = new_bucket_bit;
- 112 41541 : hashdyn->bucket_max = new_bucket_max;
- 113 41541 : hashdyn->bucket_mask = new_bucket_mask;
- 114 41541 : hashdyn->bucket = new_bucket;
- 115 41541 : }
+ 111 41538 : hashdyn->bucket_bit = new_bucket_bit;
+ 112 41538 : hashdyn->bucket_max = new_bucket_max;
+ 113 41538 : hashdyn->bucket_mask = new_bucket_mask;
+ 114 41538 : hashdyn->bucket = new_bucket;
+ 115 41538 : }
116 :
117 : /**
118 : * Grow.
119 : */
- 120 13237087 : tommy_inline void hashdyn_grow_step(tommy_hashdyn* hashdyn)
+ 120 13236976 : tommy_inline void hashdyn_grow_step(tommy_hashdyn* hashdyn)
121 : {
122 : /* grow if more than 50% full */
- 123 13237087 : if (hashdyn->count >= hashdyn->bucket_max / 2)
- 124 41492 : tommy_hashdyn_resize(hashdyn, hashdyn->bucket_bit + 1);
- 125 13237087 : }
+ 123 13236976 : if (hashdyn->count >= hashdyn->bucket_max / 2)
+ 124 41489 : tommy_hashdyn_resize(hashdyn, hashdyn->bucket_bit + 1);
+ 125 13236976 : }
126 :
127 : /**
128 : * Shrink.
129 : */
- 130 281913 : tommy_inline void hashdyn_shrink_step(tommy_hashdyn* hashdyn)
+ 130 282017 : tommy_inline void hashdyn_shrink_step(tommy_hashdyn* hashdyn)
131 : {
132 : /* shrink if less than 12.5% full */
- 133 281913 : if (hashdyn->count <= hashdyn->bucket_max / 8 && hashdyn->bucket_bit > TOMMY_HASHDYN_BIT)
+ 133 282017 : if (hashdyn->count <= hashdyn->bucket_max / 8 && hashdyn->bucket_bit > TOMMY_HASHDYN_BIT)
134 49 : tommy_hashdyn_resize(hashdyn, hashdyn->bucket_bit - 1);
- 135 281913 : }
+ 135 282017 : }
136 :
- 137 13237087 : void tommy_hashdyn_insert(tommy_hashdyn* hashdyn, tommy_hashdyn_node* node, void* data, tommy_hash_t hash)
+ 137 13236976 : void tommy_hashdyn_insert(tommy_hashdyn* hashdyn, tommy_hashdyn_node* node, void* data, tommy_hash_t hash)
138 : {
- 139 13237087 : tommy_count_t pos = hash & hashdyn->bucket_mask;
+ 139 13236976 : tommy_count_t pos = hash & hashdyn->bucket_mask;
140 :
- 141 13237087 : tommy_list_insert_tail(&hashdyn->bucket[pos], node, data);
+ 141 13236976 : tommy_list_insert_tail(&hashdyn->bucket[pos], node, data);
142 :
- 143 13237087 : node->key = hash;
+ 143 13236976 : node->key = hash;
144 :
- 145 13237087 : ++hashdyn->count;
+ 145 13236976 : ++hashdyn->count;
146 :
- 147 13237087 : hashdyn_grow_step(hashdyn);
- 148 13237087 : }
+ 147 13236976 : hashdyn_grow_step(hashdyn);
+ 148 13236976 : }
149 :
- 150 281785 : void* tommy_hashdyn_remove_existing(tommy_hashdyn* hashdyn, tommy_hashdyn_node* node)
+ 150 281889 : void* tommy_hashdyn_remove_existing(tommy_hashdyn* hashdyn, tommy_hashdyn_node* node)
151 : {
- 152 281785 : tommy_count_t pos = node->key & hashdyn->bucket_mask;
+ 152 281889 : tommy_count_t pos = node->key & hashdyn->bucket_mask;
153 :
- 154 281785 : tommy_list_remove_existing(&hashdyn->bucket[pos], node);
+ 154 281889 : tommy_list_remove_existing(&hashdyn->bucket[pos], node);
155 :
- 156 281785 : --hashdyn->count;
+ 156 281889 : --hashdyn->count;
157 :
- 158 281785 : hashdyn_shrink_step(hashdyn);
+ 158 281889 : hashdyn_shrink_step(hashdyn);
159 :
- 160 281785 : return node->data;
+ 160 281889 : 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 5812535 : for (pos = 0; pos < bucket_max; ++pos) {
192 5812288 : tommy_hashdyn_node* node = bucket[pos];
193 :
- 194 13485518 : while (node) {
- 195 1860942 : void* data = node->data;
- 196 1860942 : node = node->next;
- 197 1860942 : func(data);
+ 194 13485699 : while (node) {
+ 195 1861123 : void* data = node->data;
+ 196 1861123 : node = node->next;
+ 197 1861123 : func(data);
198 : }
199 : }
200 247 : }
diff --git a/cov/tommyds/tommyhashdyn.h.func-sort-c.html b/cov/tommyds/tommyhashdyn.h.func-sort-c.html
index c86e887e..f39065be 100644
--- a/cov/tommyds/tommyhashdyn.h.func-sort-c.html
+++ b/cov/tommyds/tommyhashdyn.h.func-sort-c.html
@@ -61,11 +61,11 @@
| tommy_hashdyn_bucket |
- 3109334 |
+ 3109139 |
| tommy_hashdyn_search |
- 3109334 |
+ 3109139 |
| tommy_hashdyn_count |
diff --git a/cov/tommyds/tommyhashdyn.h.func.html b/cov/tommyds/tommyhashdyn.h.func.html
index adf7080e..79320b42 100644
--- a/cov/tommyds/tommyhashdyn.h.func.html
+++ b/cov/tommyds/tommyhashdyn.h.func.html
@@ -61,7 +61,7 @@
| tommy_hashdyn_bucket |
- 3109334 |
+ 3109139 |
| tommy_hashdyn_count |
@@ -69,7 +69,7 @@
| tommy_hashdyn_search |
- 3109334 |
+ 3109139 |
diff --git a/cov/tommyds/tommyhashdyn.h.gcov.html b/cov/tommyds/tommyhashdyn.h.gcov.html
index f1320b97..713bad9b 100644
--- a/cov/tommyds/tommyhashdyn.h.gcov.html
+++ b/cov/tommyds/tommyhashdyn.h.gcov.html
@@ -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 3109334 : tommy_inline tommy_hashdyn_node* tommy_hashdyn_bucket(tommy_hashdyn* hashdyn, tommy_hash_t hash)
+ 208 3109139 : tommy_inline tommy_hashdyn_node* tommy_hashdyn_bucket(tommy_hashdyn* hashdyn, tommy_hash_t hash)
209 : {
- 210 3109334 : return hashdyn->bucket[hash & hashdyn->bucket_mask];
+ 210 3109139 : 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 3109334 : tommy_inline void* tommy_hashdyn_search(tommy_hashdyn* hashdyn, tommy_search_func* cmp, const void* cmp_arg, tommy_hash_t hash)
+ 223 3109139 : tommy_inline void* tommy_hashdyn_search(tommy_hashdyn* hashdyn, tommy_search_func* cmp, const void* cmp_arg, tommy_hash_t hash)
224 : {
- 225 3109334 : tommy_hashdyn_node* i = tommy_hashdyn_bucket(hashdyn, hash);
+ 225 3109139 : tommy_hashdyn_node* i = tommy_hashdyn_bucket(hashdyn, hash);
226 :
- 227 6902625 : while (i) {
+ 227 6897799 : while (i) {
228 : /* we first check if the hash matches, as in the same bucket we may have multiples hash values */
- 229 1848605 : if (i->key == hash && cmp(cmp_arg, i->data) == 0)
- 230 1164648 : return i->data;
- 231 683957 : i = i->next;
+ 229 1844197 : if (i->key == hash && cmp(cmp_arg, i->data) == 0)
+ 230 1164676 : return i->data;
+ 231 679521 : i = i->next;
232 : }
- 233 1944686 : return 0;
+ 233 1944463 : 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 c7f7ae85..fbb6a7a9 100644
--- a/cov/tommyds/tommylist.c.func-sort-c.html
+++ b/cov/tommyds/tommylist.c.func-sort-c.html
@@ -61,11 +61,11 @@
| tommy_list_sort |
- 2469 |
+ 2481 |
| tommy_list_set |
- 1684 |
+ 1693 |
diff --git a/cov/tommyds/tommylist.c.func.html b/cov/tommyds/tommylist.c.func.html
index 1d205156..9a83a9d4 100644
--- a/cov/tommyds/tommylist.c.func.html
+++ b/cov/tommyds/tommylist.c.func.html
@@ -61,11 +61,11 @@
| tommy_list_set |
- 1684 |
+ 1693 |
| tommy_list_sort |
- 2469 |
+ 2481 |
diff --git a/cov/tommyds/tommylist.c.gcov.html b/cov/tommyds/tommylist.c.gcov.html
index 05b56801..a168b925 100644
--- a/cov/tommyds/tommylist.c.gcov.html
+++ b/cov/tommyds/tommylist.c.gcov.html
@@ -93,31 +93,31 @@
31 : /** \internal
32 : * Setup a list.
33 : */
- 34 1684 : tommy_inline void tommy_list_set(tommy_list* list, tommy_node* head, tommy_node* tail)
+ 34 1693 : tommy_inline void tommy_list_set(tommy_list* list, tommy_node* head, tommy_node* tail)
35 : {
- 36 1684 : head->prev = tail;
- 37 1684 : tail->next = 0;
- 38 1684 : *list = head;
- 39 1684 : }
+ 36 1693 : head->prev = tail;
+ 37 1693 : tail->next = 0;
+ 38 1693 : *list = head;
+ 39 1693 : }
40 :
- 41 2469 : void tommy_list_sort(tommy_list* list, tommy_compare_func* cmp)
+ 41 2481 : void tommy_list_sort(tommy_list* list, tommy_compare_func* cmp)
42 : {
43 : tommy_chain chain;
44 : tommy_node* head;
45 :
- 46 2469 : if (tommy_list_empty(list))
- 47 3254 : return;
+ 46 2481 : if (tommy_list_empty(list))
+ 47 3269 : return;
48 :
- 49 1684 : head = tommy_list_head(list);
+ 49 1693 : head = tommy_list_head(list);
50 :
51 : /* create a chain from the list */
- 52 1684 : chain.head = head;
- 53 1684 : chain.tail = head->prev;
+ 52 1693 : chain.head = head;
+ 53 1693 : chain.tail = head->prev;
54 :
- 55 1684 : tommy_chain_mergesort(&chain, cmp);
+ 55 1693 : tommy_chain_mergesort(&chain, cmp);
56 :
57 : /* restore the list */
- 58 1684 : tommy_list_set(list, chain.head, chain.tail);
+ 58 1693 : tommy_list_set(list, chain.head, chain.tail);
59 : }
60 :
diff --git a/cov/tommyds/tommylist.h.func-sort-c.html b/cov/tommyds/tommylist.h.func-sort-c.html
index e3c06b4f..2f8e1e22 100644
--- a/cov/tommyds/tommylist.h.func-sort-c.html
+++ b/cov/tommyds/tommylist.h.func-sort-c.html
@@ -61,23 +61,23 @@
| tommy_list_head |
- 25314296 |
+ 25314845 |
| tommy_list_insert_first |
- 23369043 |
+ 23362955 |
| tommy_list_insert_tail |
- 18382517 |
+ 18382476 |
| tommy_list_insert_tail_not_empty |
- 11092002 |
+ 11097281 |
| tommy_list_remove_existing |
- 339841 |
+ 340001 |
| tommy_list_concat |
@@ -85,19 +85,19 @@
| tommy_list_init |
- 11842 |
+ 11898 |
| tommy_list_foreach |
- 7613 |
+ 7614 |
| tommy_list_empty |
- 4369 |
+ 4384 |
| tommy_list_count |
- 258 |
+ 259 |
| tommy_list_tail |
diff --git a/cov/tommyds/tommylist.h.func.html b/cov/tommyds/tommylist.h.func.html
index a181f52a..9e435b68 100644
--- a/cov/tommyds/tommylist.h.func.html
+++ b/cov/tommyds/tommylist.h.func.html
@@ -65,39 +65,39 @@
| tommy_list_count |
- 258 |
+ 259 |
| tommy_list_empty |
- 4369 |
+ 4384 |
| tommy_list_foreach |
- 7613 |
+ 7614 |
| tommy_list_head |
- 25314296 |
+ 25314845 |
| tommy_list_init |
- 11842 |
+ 11898 |
| tommy_list_insert_first |
- 23369043 |
+ 23362955 |
| tommy_list_insert_tail |
- 18382517 |
+ 18382476 |
| tommy_list_insert_tail_not_empty |
- 11092002 |
+ 11097281 |
| tommy_list_remove_existing |
- 339841 |
+ 340001 |
| tommy_list_tail |
diff --git a/cov/tommyds/tommylist.h.gcov.html b/cov/tommyds/tommylist.h.gcov.html
index 147bca17..f7401298 100644
--- a/cov/tommyds/tommylist.h.gcov.html
+++ b/cov/tommyds/tommylist.h.gcov.html
@@ -173,18 +173,18 @@
111 : * Initializes the list.
112 : * The list is completely inplace, so it doesn't need to be deinitialized.
113 : */
- 114 11842 : tommy_inline void tommy_list_init(tommy_list* list)
+ 114 11898 : tommy_inline void tommy_list_init(tommy_list* list)
115 : {
- 116 11842 : *list = 0;
- 117 11842 : }
+ 116 11898 : *list = 0;
+ 117 11898 : }
118 :
119 : /**
120 : * Gets the head of the list.
121 : * \return The head node. For empty lists 0 is returned.
122 : */
- 123 25314296 : tommy_inline tommy_node* tommy_list_head(tommy_list* list)
+ 123 25314845 : tommy_inline tommy_node* tommy_list_head(tommy_list* list)
124 : {
- 125 25314296 : return *list;
+ 125 25314845 : return *list;
126 : }
127 :
128 : /**
@@ -206,16 +206,16 @@
144 : * \param list The list to initialize.
145 : * \param node The node to insert.
146 : */
- 147 23369043 : tommy_inline void tommy_list_insert_first(tommy_list* list, tommy_node* node)
+ 147 23362955 : tommy_inline void tommy_list_insert_first(tommy_list* list, tommy_node* node)
148 : {
149 : /* one element "circular" prev list */
- 150 23369043 : node->prev = node;
+ 150 23362955 : node->prev = node;
151 :
152 : /* one element "0 terminated" next list */
- 153 23369043 : node->next = 0;
+ 153 23362955 : node->next = 0;
154 :
- 155 23369043 : *list = node;
- 156 23369043 : }
+ 155 23362955 : *list = node;
+ 156 23362955 : }
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 11092002 : tommy_inline void tommy_list_insert_tail_not_empty(tommy_node* head, tommy_node* node)
+ 184 11097281 : tommy_inline void tommy_list_insert_tail_not_empty(tommy_node* head, tommy_node* node)
185 : {
186 : /* insert in the "circular" prev list */
- 187 11092002 : node->prev = head->prev;
- 188 11092002 : head->prev = node;
+ 187 11097281 : node->prev = head->prev;
+ 188 11097281 : head->prev = node;
189 :
190 : /* insert in the "0 terminated" next list */
- 191 11092002 : node->next = 0;
- 192 11092002 : node->prev->next = node;
- 193 11092002 : }
+ 191 11097281 : node->next = 0;
+ 192 11097281 : node->prev->next = node;
+ 193 11097281 : }
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 18382517 : tommy_inline void tommy_list_insert_tail(tommy_list* list, tommy_node* node, void* data)
+ 217 18382476 : tommy_inline void tommy_list_insert_tail(tommy_list* list, tommy_node* node, void* data)
218 : {
- 219 18382517 : tommy_node* head = tommy_list_head(list);
+ 219 18382476 : tommy_node* head = tommy_list_head(list);
220 :
- 221 18382517 : if (head)
- 222 9176575 : tommy_list_insert_tail_not_empty(head, node);
+ 221 18382476 : if (head)
+ 222 9182164 : tommy_list_insert_tail_not_empty(head, node);
223 : else
- 224 9205942 : tommy_list_insert_first(list, node);
+ 224 9200312 : tommy_list_insert_first(list, node);
225 :
- 226 18382517 : node->data = data;
- 227 18382517 : }
+ 226 18382476 : node->data = data;
+ 227 18382476 : }
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 339841 : tommy_inline void* tommy_list_remove_existing(tommy_list* list, tommy_node* node)
+ 255 340001 : tommy_inline void* tommy_list_remove_existing(tommy_list* list, tommy_node* node)
256 : {
- 257 339841 : tommy_node* head = tommy_list_head(list);
+ 257 340001 : tommy_node* head = tommy_list_head(list);
258 :
259 : /* remove from the "circular" prev list */
- 260 339841 : if (node->next)
- 261 116843 : node->next->prev = node->prev;
+ 260 340001 : if (node->next)
+ 261 117029 : node->next->prev = node->prev;
262 : else
- 263 222998 : head->prev = node->prev; /* the last */
+ 263 222972 : head->prev = node->prev; /* the last */
264 :
265 : /* remove from the "0 terminated" next list */
- 266 339841 : if (head == node)
- 267 237549 : *list = node->next; /* the new head, in case 0 */
+ 266 340001 : if (head == node)
+ 267 237639 : *list = node->next; /* the new head, in case 0 */
268 : else
- 269 102292 : node->prev->next = node->next;
+ 269 102362 : node->prev->next = node->next;
270 :
- 271 339841 : return node->data;
+ 271 340001 : return node->data;
272 : }
273 :
274 : /**
@@ -349,24 +349,24 @@
287 : /* if the second is empty, nothing to do */
288 63152 : second_head = tommy_list_head(second);
289 63152 : if (second_head == 0)
- 290 55791 : return;
+ 290 55818 : return;
291 :
292 : /* if the first is empty, copy the second */
- 293 7361 : first_head = tommy_list_head(first);
- 294 7361 : if (first_head == 0) {
- 295 6496 : *first = *second;
- 296 6496 : return;
+ 293 7334 : first_head = tommy_list_head(first);
+ 294 7334 : if (first_head == 0) {
+ 295 6443 : *first = *second;
+ 296 6443 : return;
297 : }
298 :
299 : /* tail of the first list */
- 300 865 : first_tail = first_head->prev;
+ 300 891 : first_tail = first_head->prev;
301 :
302 : /* set the "circular" prev list */
- 303 865 : first_head->prev = second_head->prev;
- 304 865 : second_head->prev = first_tail;
+ 303 891 : first_head->prev = second_head->prev;
+ 304 891 : second_head->prev = first_tail;
305 :
306 : /* set the "0 terminated" next list */
- 307 865 : first_tail->next = second_head;
+ 307 891 : first_tail->next = second_head;
308 : }
309 :
310 : /**
@@ -382,26 +382,26 @@
320 : * Checks if empty.
321 : * \return If the list is empty.
322 : */
- 323 4369 : tommy_inline tommy_bool_t tommy_list_empty(tommy_list* list)
+ 323 4384 : tommy_inline tommy_bool_t tommy_list_empty(tommy_list* list)
324 : {
- 325 4369 : return tommy_list_head(list) == 0;
+ 325 4384 : return tommy_list_head(list) == 0;
326 : }
327 :
328 : /**
329 : * Gets the number of elements.
330 : * \note This operation is O(n).
331 : */
- 332 258 : tommy_inline tommy_count_t tommy_list_count(tommy_list* list)
+ 332 259 : tommy_inline tommy_count_t tommy_list_count(tommy_list* list)
333 : {
- 334 258 : tommy_count_t count = 0;
- 335 258 : tommy_node* i = tommy_list_head(list);
+ 334 259 : tommy_count_t count = 0;
+ 335 259 : tommy_node* i = tommy_list_head(list);
336 :
- 337 2059 : while (i) {
- 338 1543 : ++count;
- 339 1543 : i = i->next;
+ 337 2067 : while (i) {
+ 338 1549 : ++count;
+ 339 1549 : i = i->next;
340 : }
341 :
- 342 258 : return count;
+ 342 259 : return count;
343 : }
344 :
345 : /**
@@ -432,16 +432,16 @@
370 : * tommy_list_foreach(&list, free);
371 : * \endcode
372 : */
- 373 7613 : tommy_inline void tommy_list_foreach(tommy_list* list, tommy_foreach_func* func)
+ 373 7614 : tommy_inline void tommy_list_foreach(tommy_list* list, tommy_foreach_func* func)
374 : {
- 375 7613 : tommy_node* node = tommy_list_head(list);
+ 375 7614 : tommy_node* node = tommy_list_head(list);
376 :
- 377 3679790 : while (node) {
- 378 3664564 : void* data = node->data;
- 379 3664564 : node = node->next;
- 380 3664564 : func(data);
+ 377 3679847 : while (node) {
+ 378 3664619 : void* data = node->data;
+ 379 3664619 : node = node->next;
+ 380 3664619 : func(data);
381 : }
- 382 7613 : }
+ 382 7614 : }
383 :
384 : /**
385 : * Calls the specified function with an argument for each element in the list.
diff --git a/cov/tommyds/tommytree.c.func-sort-c.html b/cov/tommyds/tommytree.c.func-sort-c.html
index 7d9ddaea..027f2e99 100644
--- a/cov/tommyds/tommytree.c.func-sort-c.html
+++ b/cov/tommyds/tommytree.c.func-sort-c.html
@@ -61,63 +61,63 @@
| tommy_tree_search_node |
- 136763359 |
+ 136779062 |
| tommy_tree_delta |
- 112389685 |
+ 112389261 |
| tommy_tree_balance |
- 104883364 |
+ 104882737 |
| tommy_tree_insert_node |
- 96203762 |
+ 96201715 |
| tommy_tree_foreach_arg_node |
- 26344201 |
+ 26344145 |
| tommy_tree_search_compare |
- 12302451 |
+ 12303747 |
| tommy_tree_rotate_left |
- 7494888 |
+ 7495135 |
| tommy_tree_insert |
- 7471241 |
+ 7471049 |
| tommy_tree_foreach_node |
- 7052356 |
+ 7052312 |
| tommy_tree_remove_node |
- 790764 |
+ 791807 |
| tommy_tree_move_right |
- 186865 |
+ 187170 |
| tommy_tree_rotate_right |
- 171259 |
+ 171066 |
| tommy_tree_remove |
- 79604 |
+ 79718 |
| tommy_tree_foreach_arg |
- 5941 |
+ 5965 |
| tommy_tree_init |
- 3159 |
+ 3171 |
| tommy_tree_foreach |
diff --git a/cov/tommyds/tommytree.c.func.html b/cov/tommyds/tommytree.c.func.html
index df90989b..36001430 100644
--- a/cov/tommyds/tommytree.c.func.html
+++ b/cov/tommyds/tommytree.c.func.html
@@ -61,11 +61,11 @@
| tommy_tree_balance |
- 104883364 |
+ 104882737 |
| tommy_tree_delta |
- 112389685 |
+ 112389261 |
| tommy_tree_foreach |
@@ -73,27 +73,27 @@
| tommy_tree_foreach_arg |
- 5941 |
+ 5965 |
| tommy_tree_foreach_arg_node |
- 26344201 |
+ 26344145 |
| tommy_tree_foreach_node |
- 7052356 |
+ 7052312 |
| tommy_tree_init |
- 3159 |
+ 3171 |
| tommy_tree_insert |
- 7471241 |
+ 7471049 |
| tommy_tree_insert_node |
- 96203762 |
+ 96201715 |
| tommy_tree_memory_usage |
@@ -101,11 +101,11 @@
| tommy_tree_move_right |
- 186865 |
+ 187170 |
| tommy_tree_remove |
- 79604 |
+ 79718 |
| tommy_tree_remove_existing |
@@ -113,15 +113,15 @@
| tommy_tree_remove_node |
- 790764 |
+ 791807 |
| tommy_tree_rotate_left |
- 7494888 |
+ 7495135 |
| tommy_tree_rotate_right |
- 171259 |
+ 171066 |
| tommy_tree_search |
@@ -129,11 +129,11 @@
| tommy_tree_search_compare |
- 12302451 |
+ 12303747 |
| tommy_tree_search_node |
- 136763359 |
+ 136779062 |
diff --git a/cov/tommyds/tommytree.c.gcov.html b/cov/tommyds/tommytree.c.gcov.html
index cfbcb983..ffe0c07f 100644
--- a/cov/tommyds/tommytree.c.gcov.html
+++ b/cov/tommyds/tommytree.c.gcov.html
@@ -94,104 +94,104 @@
32 : /******************************************************************************/
33 : /* tree */
34 :
- 35 3159 : void tommy_tree_init(tommy_tree* tree, tommy_compare_func* cmp)
+ 35 3171 : void tommy_tree_init(tommy_tree* tree, tommy_compare_func* cmp)
36 : {
- 37 3159 : tree->root = 0;
- 38 3159 : tree->count = 0;
- 39 3159 : tree->cmp = cmp;
- 40 3159 : }
+ 37 3171 : tree->root = 0;
+ 38 3171 : tree->count = 0;
+ 39 3171 : tree->cmp = cmp;
+ 40 3171 : }
41 :
- 42 112389685 : static int tommy_tree_delta(tommy_tree_node* root)
+ 42 112389261 : static int tommy_tree_delta(tommy_tree_node* root)
43 : {
- 44 112389685 : int left_height = root->prev ? root->prev->key : 0;
- 45 112389685 : int right_height = root->next ? root->next->key : 0;
+ 44 112389261 : int left_height = root->prev ? root->prev->key : 0;
+ 45 112389261 : int right_height = root->next ? root->next->key : 0;
46 :
- 47 112389685 : return left_height - right_height;
+ 47 112389261 : return left_height - right_height;
48 : }
49 :
50 : /* AVL tree operations */
51 : static tommy_tree_node* tommy_tree_balance(tommy_tree_node*);
52 :
- 53 7494888 : static tommy_tree_node* tommy_tree_rotate_left(tommy_tree_node* root)
+ 53 7495135 : static tommy_tree_node* tommy_tree_rotate_left(tommy_tree_node* root)
54 : {
- 55 7494888 : tommy_tree_node* next = root->next;
+ 55 7495135 : tommy_tree_node* next = root->next;
56 :
- 57 7494888 : root->next = next->prev;
+ 57 7495135 : root->next = next->prev;
58 :
- 59 7494888 : next->prev = tommy_tree_balance(root);
+ 59 7495135 : next->prev = tommy_tree_balance(root);
60 :
- 61 7494888 : return tommy_tree_balance(next);
+ 61 7495135 : return tommy_tree_balance(next);
62 : }
63 :
- 64 171259 : static tommy_tree_node* tommy_tree_rotate_right(tommy_tree_node* root)
+ 64 171066 : static tommy_tree_node* tommy_tree_rotate_right(tommy_tree_node* root)
65 : {
- 66 171259 : tommy_tree_node* prev = root->prev;
+ 66 171066 : tommy_tree_node* prev = root->prev;
67 :
- 68 171259 : root->prev = prev->next;
+ 68 171066 : root->prev = prev->next;
69 :
- 70 171259 : prev->next = tommy_tree_balance(root);
+ 70 171066 : prev->next = tommy_tree_balance(root);
71 :
- 72 171259 : return tommy_tree_balance(prev);
+ 72 171066 : return tommy_tree_balance(prev);
73 : }
74 :
- 75 186865 : static tommy_tree_node* tommy_tree_move_right(tommy_tree_node* root, tommy_tree_node* node)
+ 75 187170 : static tommy_tree_node* tommy_tree_move_right(tommy_tree_node* root, tommy_tree_node* node)
76 : {
- 77 186865 : if (!root)
- 78 79476 : return node;
+ 77 187170 : if (!root)
+ 78 79590 : return node;
79 :
- 80 107389 : root->next = tommy_tree_move_right(root->next, node);
+ 80 107580 : root->next = tommy_tree_move_right(root->next, node);
81 :
- 82 107389 : return tommy_tree_balance(root);
+ 82 107580 : return tommy_tree_balance(root);
83 : }
84 :
- 85 104883364 : static tommy_tree_node* tommy_tree_balance(tommy_tree_node* root)
+ 85 104882737 : static tommy_tree_node* tommy_tree_balance(tommy_tree_node* root)
86 : {
- 87 104883364 : int delta = tommy_tree_delta(root);
+ 87 104882737 : int delta = tommy_tree_delta(root);
88 :
- 89 104883364 : if (delta < -1) {
- 90 7377984 : if (tommy_tree_delta(root->next) > 0)
- 91 42922 : root->next = tommy_tree_rotate_right(root->next);
- 92 7377984 : return tommy_tree_rotate_left(root);
+ 89 104882737 : if (delta < -1) {
+ 90 7378375 : if (tommy_tree_delta(root->next) > 0)
+ 91 42917 : root->next = tommy_tree_rotate_right(root->next);
+ 92 7378375 : return tommy_tree_rotate_left(root);
93 : }
94 :
- 95 97505380 : if (delta > 1) {
- 96 128337 : if (tommy_tree_delta(root->prev) < 0)
- 97 116904 : root->prev = tommy_tree_rotate_left(root->prev);
- 98 128337 : return tommy_tree_rotate_right(root);
+ 95 97504362 : if (delta > 1) {
+ 96 128149 : if (tommy_tree_delta(root->prev) < 0)
+ 97 116760 : root->prev = tommy_tree_rotate_left(root->prev);
+ 98 128149 : return tommy_tree_rotate_right(root);
99 : }
100 :
101 : /* recompute key */
- 102 97377043 : root->key = 0;
+ 102 97376213 : root->key = 0;
103 :
- 104 97377043 : if (root->prev && root->prev->key > root->key)
- 105 78773858 : root->key = root->prev->key;
+ 104 97376213 : if (root->prev && root->prev->key > root->key)
+ 105 78773173 : root->key = root->prev->key;
106 :
- 107 97377043 : if (root->next && root->next->key > root->key)
- 108 44909116 : root->key = root->next->key;
+ 107 97376213 : if (root->next && root->next->key > root->key)
+ 108 44912285 : root->key = root->next->key;
109 :
110 : /* count itself */
- 111 97377043 : root->key += 1;
+ 111 97376213 : root->key += 1;
112 :
- 113 97377043 : return root;
+ 113 97376213 : return root;
114 : }
115 :
- 116 96203762 : static tommy_tree_node* tommy_tree_insert_node(tommy_compare_func* cmp, tommy_tree_node* root, tommy_tree_node** let)
+ 116 96201715 : 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 96203762 : if (!root)
- 121 7471240 : return *let;
+ 120 96201715 : if (!root)
+ 121 7471048 : return *let;
122 :
- 123 88732522 : c = cmp((*let)->data, root->data);
+ 123 88730667 : c = cmp((*let)->data, root->data);
124 :
- 125 88732522 : if (c < 0) {
- 126 1537706 : root->prev = tommy_tree_insert_node(cmp, root->prev, let);
- 127 1537706 : return tommy_tree_balance(root);
+ 125 88730667 : if (c < 0) {
+ 126 1532013 : root->prev = tommy_tree_insert_node(cmp, root->prev, let);
+ 127 1532013 : return tommy_tree_balance(root);
128 : }
129 :
- 130 87194816 : if (c > 0) {
- 131 87194815 : root->next = tommy_tree_insert_node(cmp, root->next, let);
- 132 87194815 : return tommy_tree_balance(root);
+ 130 87198654 : if (c > 0) {
+ 131 87198653 : root->next = tommy_tree_insert_node(cmp, root->next, let);
+ 132 87198653 : 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 7471241 : void* tommy_tree_insert(tommy_tree* tree, tommy_tree_node* node, void* data)
+ 141 7471049 : void* tommy_tree_insert(tommy_tree* tree, tommy_tree_node* node, void* data)
142 : {
- 143 7471241 : tommy_tree_node* insert = node;
+ 143 7471049 : tommy_tree_node* insert = node;
144 :
- 145 7471241 : insert->data = data;
- 146 7471241 : insert->prev = 0;
- 147 7471241 : insert->next = 0;
- 148 7471241 : insert->key = 0;
+ 145 7471049 : insert->data = data;
+ 146 7471049 : insert->prev = 0;
+ 147 7471049 : insert->next = 0;
+ 148 7471049 : insert->key = 0;
149 :
- 150 7471241 : tree->root = tommy_tree_insert_node(tree->cmp, tree->root, &insert);
+ 150 7471049 : tree->root = tommy_tree_insert_node(tree->cmp, tree->root, &insert);
151 :
- 152 7471241 : if (insert == node)
- 153 7471240 : ++tree->count;
+ 152 7471049 : if (insert == node)
+ 153 7471048 : ++tree->count;
154 :
- 155 7471241 : return insert->data;
+ 155 7471049 : return insert->data;
156 : }
157 :
- 158 790764 : static tommy_tree_node* tommy_tree_remove_node(tommy_compare_func* cmp, tommy_tree_node* root, void* data, tommy_tree_node** let)
+ 158 791807 : 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 790764 : if (!root)
+ 162 791807 : if (!root)
163 128 : return 0;
164 :
- 165 790636 : c = cmp(data, root->data);
+ 165 791679 : c = cmp(data, root->data);
166 :
- 167 790636 : if (c < 0) {
- 168 303798 : root->prev = tommy_tree_remove_node(cmp, root->prev, data, let);
- 169 303798 : return tommy_tree_balance(root);
+ 167 791679 : if (c < 0) {
+ 168 304695 : root->prev = tommy_tree_remove_node(cmp, root->prev, data, let);
+ 169 304695 : return tommy_tree_balance(root);
170 : }
171 :
- 172 486838 : if (c > 0) {
- 173 407362 : root->next = tommy_tree_remove_node(cmp, root->next, data, let);
- 174 407362 : return tommy_tree_balance(root);
+ 172 486984 : if (c > 0) {
+ 173 407394 : root->next = tommy_tree_remove_node(cmp, root->next, data, let);
+ 174 407394 : return tommy_tree_balance(root);
175 : }
176 :
177 : /* found */
- 178 79476 : *let = root;
+ 178 79590 : *let = root;
179 :
- 180 79476 : return tommy_tree_move_right(root->prev, root->next);
+ 180 79590 : return tommy_tree_move_right(root->prev, root->next);
181 : }
182 :
- 183 79604 : void* tommy_tree_remove(tommy_tree* tree, void* data)
+ 183 79718 : void* tommy_tree_remove(tommy_tree* tree, void* data)
184 : {
- 185 79604 : tommy_tree_node* node = 0;
+ 185 79718 : tommy_tree_node* node = 0;
186 :
- 187 79604 : tree->root = tommy_tree_remove_node(tree->cmp, tree->root, data, &node);
+ 187 79718 : tree->root = tommy_tree_remove_node(tree->cmp, tree->root, data, &node);
188 :
- 189 79604 : if (!node)
+ 189 79718 : if (!node)
190 128 : return 0;
191 :
- 192 79476 : --tree->count;
+ 192 79590 : --tree->count;
193 :
- 194 79476 : return node->data;
+ 194 79590 : return node->data;
195 : }
196 :
- 197 136763359 : static tommy_tree_node* tommy_tree_search_node(tommy_compare_func* cmp, tommy_tree_node* root, void* data)
+ 197 136779062 : static tommy_tree_node* tommy_tree_search_node(tommy_compare_func* cmp, tommy_tree_node* root, void* data)
198 : {
199 : int c;
200 :
- 201 136763359 : if (!root)
- 202 1588540 : return 0;
+ 201 136779062 : if (!root)
+ 202 1588658 : return 0;
203 :
- 204 135174819 : c = cmp(data, root->data);
+ 204 135190404 : c = cmp(data, root->data);
205 :
- 206 135179988 : if (c < 0)
- 207 49127582 : return tommy_tree_search_node(cmp, root->prev, data);
+ 206 135195696 : if (c < 0)
+ 207 49136499 : return tommy_tree_search_node(cmp, root->prev, data);
208 :
- 209 86052406 : if (c > 0)
- 210 75338711 : return tommy_tree_search_node(cmp, root->next, data);
+ 209 86059197 : if (c > 0)
+ 210 75344385 : return tommy_tree_search_node(cmp, root->next, data);
211 :
- 212 10713695 : return root;
+ 212 10714812 : 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 12302451 : void* tommy_tree_search_compare(tommy_tree* tree, tommy_compare_func* cmp, void* cmp_arg)
+ 225 12303747 : void* tommy_tree_search_compare(tommy_tree* tree, tommy_compare_func* cmp, void* cmp_arg)
226 : {
- 227 12302451 : tommy_tree_node* node = tommy_tree_search_node(cmp, tree->root, cmp_arg);
+ 227 12303747 : tommy_tree_node* node = tommy_tree_search_node(cmp, tree->root, cmp_arg);
228 :
- 229 12302205 : if (!node)
- 230 1588572 : return 0;
+ 229 12303453 : if (!node)
+ 230 1588690 : return 0;
231 :
- 232 10713633 : return node->data;
+ 232 10714763 : 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 7052356 : static void tommy_tree_foreach_node(tommy_tree_node* root, tommy_foreach_func* func)
+ 244 7052312 : static void tommy_tree_foreach_node(tommy_tree_node* root, tommy_foreach_func* func)
245 : {
246 : tommy_tree_node* next;
247 :
- 248 7052356 : if (!root)
- 249 10579261 : return;
+ 248 7052312 : if (!root)
+ 249 10579195 : return;
250 :
- 251 3525451 : tommy_tree_foreach_node(root->prev, func);
+ 251 3525429 : tommy_tree_foreach_node(root->prev, func);
252 :
253 : /* make a copy in case func is free() */
- 254 3525451 : next = root->next;
+ 254 3525429 : next = root->next;
255 :
- 256 3525451 : func(root->data);
+ 256 3525429 : func(root->data);
257 :
- 258 3525451 : tommy_tree_foreach_node(next, func);
+ 258 3525429 : tommy_tree_foreach_node(next, func);
259 : }
260 :
261 1454 : void tommy_tree_foreach(tommy_tree* tree, tommy_foreach_func* func)
@@ -325,27 +325,27 @@
263 1454 : tommy_tree_foreach_node(tree->root, func);
264 1454 : }
265 :
- 266 26344201 : static void tommy_tree_foreach_arg_node(tommy_tree_node* root, tommy_foreach_arg_func* func, void* arg)
+ 266 26344145 : 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 26344201 : if (!root)
- 271 39519272 : return;
+ 270 26344145 : if (!root)
+ 271 39519200 : return;
272 :
- 273 13169130 : tommy_tree_foreach_arg_node(root->prev, func, arg);
+ 273 13169090 : tommy_tree_foreach_arg_node(root->prev, func, arg);
274 :
275 : /* make a copy in case func is free() */
- 276 13169130 : next = root->next;
+ 276 13169090 : next = root->next;
277 :
- 278 13169130 : func(arg, root->data);
+ 278 13169090 : func(arg, root->data);
279 :
- 280 13169130 : tommy_tree_foreach_arg_node(next, func, arg);
+ 280 13169090 : tommy_tree_foreach_arg_node(next, func, arg);
281 : }
282 :
- 283 5941 : void tommy_tree_foreach_arg(tommy_tree* tree, tommy_foreach_arg_func* func, void* arg)
+ 283 5965 : void tommy_tree_foreach_arg(tommy_tree* tree, tommy_foreach_arg_func* func, void* arg)
284 : {
- 285 5941 : tommy_tree_foreach_arg_node(tree->root, func, arg);
- 286 5941 : }
+ 285 5965 : tommy_tree_foreach_arg_node(tree->root, func, arg);
+ 286 5965 : }
287 :
288 1 : tommy_size_t tommy_tree_memory_usage(tommy_tree* tree)
289 : {
diff --git a/cov/tommyds/tommytypes.h.func-sort-c.html b/cov/tommyds/tommytypes.h.func-sort-c.html
index 0eadd42d..b3aeebb1 100644
--- a/cov/tommyds/tommytypes.h.func-sort-c.html
+++ b/cov/tommyds/tommytypes.h.func-sort-c.html
@@ -61,11 +61,11 @@
| tommy_ilog2_u32 |
- 10268450 |
+ 10268715 |
| tommy_ctz_u32 |
- 1684 |
+ 1693 |
| tommy_haszero_u32 |
diff --git a/cov/tommyds/tommytypes.h.func.html b/cov/tommyds/tommytypes.h.func.html
index 94c5e7af..c63029e2 100644
--- a/cov/tommyds/tommytypes.h.func.html
+++ b/cov/tommyds/tommytypes.h.func.html
@@ -61,7 +61,7 @@
| tommy_ctz_u32 |
- 1684 |
+ 1693 |
| tommy_haszero_u32 |
@@ -69,7 +69,7 @@
| tommy_ilog2_u32 |
- 10268450 |
+ 10268715 |
diff --git a/cov/tommyds/tommytypes.h.gcov.html b/cov/tommyds/tommytypes.h.gcov.html
index 7eedf268..6244d621 100644
--- a/cov/tommyds/tommytypes.h.gcov.html
+++ b/cov/tommyds/tommytypes.h.gcov.html
@@ -390,7 +390,7 @@
328 : * \param value Value to scan. 0 is not allowed.
329 : * \return The index of the most significant bit set.
330 : */
- 331 10268450 : tommy_inline tommy_uint_t tommy_ilog2_u32(tommy_uint32_t value)
+ 331 10268715 : tommy_inline tommy_uint_t tommy_ilog2_u32(tommy_uint32_t value)
332 : {
333 : #if defined(_MSC_VER)
334 : unsigned long count;
@@ -406,7 +406,7 @@
344 : * So we write "__builtin_clz(x) ^ 31" instead of "31 - __builtin_clz(x)",
345 : * to allow the double xor to be optimized out.
346 : */
- 347 10268450 : return __builtin_clz(value) ^ 31;
+ 347 10268715 : return __builtin_clz(value) ^ 31;
348 : #else
349 : /* Find the log base 2 of an N-bit integer in O(lg(N)) operations with multiply and lookup */
350 : /* from http://graphics.stanford.edu/~seander/bithacks.html */
@@ -433,14 +433,14 @@
371 : * \param value Value to scan. 0 is not allowed.
372 : * \return The index of the least significant bit set.
373 : */
- 374 1684 : tommy_inline tommy_uint_t tommy_ctz_u32(tommy_uint32_t value)
+ 374 1693 : tommy_inline tommy_uint_t tommy_ctz_u32(tommy_uint32_t value)
375 : {
376 : #if defined(_MSC_VER)
377 : unsigned long count;
378 : _BitScanForward(&count, value);
379 : return count;
380 : #elif defined(__GNUC__)
- 381 1684 : return __builtin_ctz(value);
+ 381 1693 : return __builtin_ctz(value);
382 : #else
383 : /* Count the consecutive zero bits (trailing) on the right with multiply and lookup */
384 : /* from http://graphics.stanford.edu/~seander/bithacks.html */