diff --git a/cov/cmdline/bw.c.func-sort-c.html b/cov/cmdline/bw.c.func-sort-c.html
index 158c5d47..2d01b03a 100644
--- a/cov/cmdline/bw.c.func-sort-c.html
+++ b/cov/cmdline/bw.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -65,7 +65,7 @@
| bw_limit |
- 9766068 |
+ 9765411 |
diff --git a/cov/cmdline/bw.c.func.html b/cov/cmdline/bw.c.func.html
index c4056475..c67434d5 100644
--- a/cov/cmdline/bw.c.func.html
+++ b/cov/cmdline/bw.c.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -65,7 +65,7 @@
| bw_limit |
- 9766068 |
+ 9765411 |
diff --git a/cov/cmdline/bw.c.gcov.html b/cov/cmdline/bw.c.gcov.html
index a3173a17..19865db2 100644
--- a/cov/cmdline/bw.c.gcov.html
+++ b/cov/cmdline/bw.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -88,10 +88,10 @@
26 220 : bw->start = tick_ms();
27 220 : }
28 :
- 29 9766068 : void bw_limit(struct snapraid_bw* bw, uint64_t bytes)
+ 29 9765411 : void bw_limit(struct snapraid_bw* bw, uint64_t bytes)
30 : {
- 31 9766068 : if (!bw || bw->limit == 0)
- 32 9766012 : return;
+ 31 9765411 : if (!bw || bw->limit == 0)
+ 32 9765355 : return;
33 :
34 56 : uint64_t elapsed = tick_ms() - bw->start;
35 : uint64_t done;
diff --git a/cov/cmdline/check.c.func-sort-c.html b/cov/cmdline/check.c.func-sort-c.html
index 31bacb5b..de06c869 100644
--- a/cov/cmdline/check.c.func-sort-c.html
+++ b/cov/cmdline/check.c.func-sort-c.html
@@ -31,13 +31,13 @@
|
-
+
-
+
-
+
|
@@ -73,19 +73,19 @@
| is_hash_matching |
- 210036 |
+ 210236 |
| repair_step |
- 252597 |
+ 252818 |
| blockcmp |
- 468600 |
+ 468795 |
| es |
- 731365 |
+ 731403 |
| repair |
diff --git a/cov/cmdline/check.c.func.html b/cov/cmdline/check.c.func.html
index 5979533f..41f82be8 100644
--- a/cov/cmdline/check.c.func.html
+++ b/cov/cmdline/check.c.func.html
@@ -31,13 +31,13 @@
|
-
+
-
+
-
+
|
@@ -65,11 +65,11 @@
| blockcmp |
- 468600 |
+ 468795 |
| es |
- 731365 |
+ 731403 |
| file_post |
@@ -77,7 +77,7 @@
| is_hash_matching |
- 210036 |
+ 210236 |
| is_parity_matching |
@@ -89,7 +89,7 @@
| repair_step |
- 252597 |
+ 252818 |
| state_check |
diff --git a/cov/cmdline/check.c.gcov.html b/cov/cmdline/check.c.gcov.html
index b848cf93..f5f15d66 100644
--- a/cov/cmdline/check.c.gcov.html
+++ b/cov/cmdline/check.c.gcov.html
@@ -31,13 +31,13 @@
|
-
+
-
+
-
+
|
@@ -93,12 +93,12 @@
31 : /****************************************************************************/
32 : /* check */
33 :
- 34 731365 : static const char* es(int err)
+ 34 731403 : static const char* es(int err)
35 : {
- 36 731365 : if (is_hw(err))
+ 36 731403 : if (is_hw(err))
37 0 : return "error_io";
38 : else
- 39 731365 : return "error";
+ 39 731403 : return "error";
40 : }
41 :
42 : /**
@@ -137,64 +137,64 @@
75 : * Check if a block hash matches the specified buffer.
76 : * Return ==0 if equal
77 : */
- 78 468600 : static int blockcmp(struct snapraid_state* state, int rehash, struct snapraid_block* block, unsigned pos_size, unsigned char* buffer, unsigned char* buffer_zero)
+ 78 468795 : static int blockcmp(struct snapraid_state* state, int rehash, struct snapraid_block* block, unsigned pos_size, unsigned char* buffer, unsigned char* buffer_zero)
79 : {
80 : unsigned char hash[HASH_MAX];
81 :
82 : /* now compute the hash of the valid part */
- 83 468600 : if (rehash) {
+ 83 468795 : if (rehash) {
84 0 : memhash(state->prevhash, state->prevhashseed, hash, buffer, pos_size);
85 : } else {
- 86 468600 : memhash(state->hash, state->hashseed, hash, buffer, pos_size);
+ 86 468795 : memhash(state->hash, state->hashseed, hash, buffer, pos_size);
87 : }
88 :
89 : /* compare the hash */
- 90 468600 : if (memcmp(hash, block->hash, BLOCK_HASH_SIZE) != 0) {
- 91 14376 : return -1;
+ 90 468795 : if (memcmp(hash, block->hash, BLOCK_HASH_SIZE) != 0) {
+ 91 14403 : return -1;
92 : }
93 :
94 : /* compare to the end of the block */
- 95 454224 : if (pos_size < state->block_size) {
- 96 187417 : if (memcmp(buffer + pos_size, buffer_zero + pos_size, state->block_size - pos_size) != 0) {
- 97 42 : return -1;
+ 95 454392 : if (pos_size < state->block_size) {
+ 96 187544 : if (memcmp(buffer + pos_size, buffer_zero + pos_size, state->block_size - pos_size) != 0) {
+ 97 45 : return -1;
98 : }
99 : }
100 :
- 101 454182 : return 0;
+ 101 454347 : return 0;
102 : }
103 :
104 : /**
105 : * Check if the hash of all the failed blocks we are expecting to recover are now matching.
106 : */
- 107 210036 : 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)
+ 107 210236 : 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)
108 : {
109 : unsigned j;
110 : int hash_checked;
111 :
- 112 210036 : hash_checked = 0; /* keep track if we check at least one block */
+ 112 210236 : hash_checked = 0; /* keep track if we check at least one block */
113 :
114 : /* check if the recovered blocks are OK */
- 115 668740 : for (j = 0; j < failed_count; ++j) {
+ 115 669105 : for (j = 0; j < failed_count; ++j) {
116 : /* if we are expected to recover this block */
- 117 473122 : if (!failed[failed_map[j]].is_outofdate
+ 117 473317 : if (!failed[failed_map[j]].is_outofdate
118 : /* if the block has a hash to check */
- 119 468600 : && block_has_updated_hash(failed[failed_map[j]].block)
+ 119 468795 : && block_has_updated_hash(failed[failed_map[j]].block)
120 : ) {
121 : /* if a hash doesn't match, fail the check */
- 122 468600 : unsigned pos_size = file_block_size(failed[failed_map[j]].file, failed[failed_map[j]].file_pos, state->block_size);
- 123 468600 : if (blockcmp(state, rehash, failed[failed_map[j]].block, pos_size, buffer[failed[failed_map[j]].index], buffer_zero) != 0) {
- 124 14418 : log_tag("repair_hash_error:%u: Hash mismatch\n", failed_map[j]);
- 125 14418 : return 0;
+ 122 468795 : unsigned pos_size = file_block_size(failed[failed_map[j]].file, failed[failed_map[j]].file_pos, state->block_size);
+ 123 468795 : if (blockcmp(state, rehash, failed[failed_map[j]].block, pos_size, buffer[failed[failed_map[j]].index], buffer_zero) != 0) {
+ 124 14448 : log_tag("repair_hash_error:%u: Hash mismatch\n", failed_map[j]);
+ 125 14448 : return 0;
126 : }
127 :
- 128 454182 : hash_checked = 1;
+ 128 454347 : hash_checked = 1;
129 : }
130 : }
131 :
132 : /* if nothing checked, we reject it */
133 : /* note that we are excluding this case at upper level */
134 : /* but checking again doesn't hurt */
- 135 195618 : if (!hash_checked) {
+ 135 195788 : if (!hash_checked) {
136 : /* LCOV_EXCL_START */
137 : return 0;
138 : /* LCOV_EXCL_STOP */
@@ -202,8 +202,8 @@
140 :
141 : /* if we checked something, and no block failed the check */
142 : /* recompute all the redundancy information */
- 143 195618 : raid_gen(diskmax, state->level, state->block_size, buffer);
- 144 195618 : return 1;
+ 143 195788 : raid_gen(diskmax, state->level, state->block_size, buffer);
+ 144 195788 : return 1;
145 : }
146 :
147 : /**
@@ -229,7 +229,7 @@
167 : * Return <0 if failure for missing strategy, >0 if data is wrong and we cannot rebuild correctly, 0 on success.
168 : * If success, the parity is computed in the buffer variable.
169 : */
- 170 252597 : 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)
+ 170 252818 : 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)
171 : {
172 : unsigned i, n;
173 : int error;
@@ -238,7 +238,7 @@
176 : int ip[LEV_MAX];
177 :
178 : /* no fix required, already checked at higher level, but just to be sure */
- 179 252597 : if (failed_count == 0) {
+ 179 252818 : if (failed_count == 0) {
180 : /* LCOV_EXCL_START */
181 : /* recompute only the parity */
182 : raid_gen(diskmax, state->level, state->block_size, buffer);
@@ -246,28 +246,28 @@
184 : /* LCOV_EXCL_STOP */
185 : }
186 :
- 187 252597 : n = state->level;
- 188 252597 : error = 0;
+ 187 252818 : n = state->level;
+ 188 252818 : error = 0;
189 :
190 : /* setup vector of failed disk indexes */
- 191 891533 : for (i = 0; i < failed_count; ++i)
- 192 638936 : id[i] = failed[failed_map[i]].index;
+ 191 892011 : for (i = 0; i < failed_count; ++i)
+ 192 639193 : id[i] = failed[failed_map[i]].index;
193 :
194 : /* check if there is at least a failed block that can be checked for correctness using the hash */
195 : /* if there isn't, we have to sacrifice a parity block to check that the result is correct */
- 196 252597 : has_hash = 0;
- 197 891533 : for (i = 0; i < failed_count; ++i) {
+ 196 252818 : has_hash = 0;
+ 197 892011 : for (i = 0; i < failed_count; ++i) {
198 : /* if we are expected to recover this block */
- 199 638936 : if (!failed[failed_map[i]].is_outofdate
+ 199 639193 : if (!failed[failed_map[i]].is_outofdate
200 : /* if the block has a hash to check */
- 201 629892 : && block_has_updated_hash(failed[failed_map[i]].block)
+ 201 630149 : && block_has_updated_hash(failed[failed_map[i]].block)
202 : )
- 203 629884 : has_hash = 1;
+ 203 630141 : has_hash = 1;
204 : }
205 :
206 : /* if we don't have a hash, but we have an extra parity */
207 : /* (strictly-less failures than number of parities) */
- 208 252597 : if (!has_hash && failed_count < n) {
+ 208 252818 : if (!has_hash && failed_count < n) {
209 : /* number of parity to use, one more to check the recovering */
210 8 : unsigned r = failed_count + 1;
211 :
@@ -307,51 +307,51 @@
245 :
246 : /* if we have a hash, and enough parities */
247 : /* (less-or-equal failures than number of parities) */
- 248 252589 : if (has_hash && failed_count <= n) {
+ 248 252810 : if (has_hash && failed_count <= n) {
249 : /* number of parities to use equal to the number of failures */
- 250 204946 : unsigned r = failed_count;
+ 250 205126 : unsigned r = failed_count;
251 :
252 : /* all combinations (r of n) parities */
- 253 204946 : combination_first(r, n, ip);
+ 253 205126 : combination_first(r, n, ip);
254 : do {
255 : /* if a parity is missing, do nothing */
- 256 687807 : for (i = 0; i < r; ++i) {
- 257 477771 : if (buffer_recov[ip[i]] == 0)
+ 256 688202 : for (i = 0; i < r; ++i) {
+ 257 477966 : if (buffer_recov[ip[i]] == 0)
258 4649 : break;
259 : }
- 260 214685 : if (i != r)
+ 260 214885 : if (i != r)
261 4649 : continue;
262 :
263 : /* copy the parities to use */
- 264 683158 : for (i = 0; i < r; ++i)
- 265 473122 : memcpy(buffer[diskmax + ip[i]], buffer_recov[ip[i]], state->block_size);
+ 264 683553 : for (i = 0; i < r; ++i)
+ 265 473317 : memcpy(buffer[diskmax + ip[i]], buffer_recov[ip[i]], state->block_size);
266 :
267 : /* recover */
- 268 210036 : raid_data(r, id, ip, diskmax, state->block_size, buffer);
+ 268 210236 : raid_data(r, id, ip, diskmax, state->block_size, buffer);
269 :
270 : /* use the hash to check the result */
- 271 210036 : if (is_hash_matching(state, rehash, diskmax, failed, failed_map, failed_count, buffer, buffer_zero))
- 272 195618 : return 0;
+ 271 210236 : if (is_hash_matching(state, rehash, diskmax, failed, failed_map, failed_count, buffer, buffer_zero))
+ 272 195788 : return 0;
273 :
274 : /* log */
- 275 14418 : log_tag("recover_hash_error:%u:", pos);
- 276 28836 : for (i = 0; i < r; ++i) {
- 277 14418 : if (i != 0)
+ 275 14448 : log_tag("recover_hash_error:%u:", pos);
+ 276 28896 : for (i = 0; i < r; ++i) {
+ 277 14448 : if (i != 0)
278 0 : log_tag("/");
- 279 14418 : log_tag("%s", lev_config_name(ip[i]));
+ 279 14448 : log_tag("%s", lev_config_name(ip[i]));
280 : }
- 281 14418 : log_tag(": Hash mismatch\n");
- 282 14418 : ++error;
- 283 38134 : } while (combination_next(r, n, ip));
+ 281 14448 : log_tag(": Hash mismatch\n");
+ 282 14448 : ++error;
+ 283 38194 : } while (combination_next(r, n, ip));
284 : }
285 :
286 : /* return the number of failed attempts, or -1 if no strategy */
- 287 56971 : if (error)
- 288 9328 : return error;
+ 287 57022 : if (error)
+ 288 9338 : return error;
289 :
- 290 47643 : log_tag("recover_strategy_error:%u: No strategy to recover from %u failures with %u parity %s hash\n",
+ 290 47684 : log_tag("recover_strategy_error:%u: No strategy to recover from %u failures with %u parity %s hash\n",
291 : pos, failed_count, n, has_hash ? "with" : "without");
- 292 47643 : return -1;
+ 292 47684 : return -1;
293 : }
294 :
295 872338 : 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)
@@ -368,47 +368,47 @@
306 :
307 : /* if nothing failed, just recompute the parity */
308 872338 : if (failed_count == 0) {
- 309 584829 : raid_gen(diskmax, state->level, state->block_size, buffer);
- 310 584829 : return 0;
+ 309 584608 : raid_gen(diskmax, state->level, state->block_size, buffer);
+ 310 584608 : return 0;
311 : }
312 :
313 : /* logs the status */
- 314 1016464 : for (j = 0; j < failed_count; ++j) {
+ 314 1016942 : for (j = 0; j < failed_count; ++j) {
315 : const char* desc;
316 : const char* hash;
317 : const char* data;
- 318 728955 : struct snapraid_block* block = failed[j].block;
- 319 728955 : unsigned block_state = block_state_get(block);
+ 318 729212 : struct snapraid_block* block = failed[j].block;
+ 319 729212 : unsigned block_state = block_state_get(block);
320 :
- 321 728955 : switch (block_state) {
+ 321 729212 : switch (block_state) {
322 18454 : case BLOCK_STATE_DELETED : desc = "delete"; break;
323 13851 : case BLOCK_STATE_CHG : desc = "change"; break;
324 62282 : case BLOCK_STATE_REP : desc = "replace"; break;
- 325 634368 : case BLOCK_STATE_BLK : desc = "block"; break;
+ 325 634625 : case BLOCK_STATE_BLK : desc = "block"; break;
326 : /* LCOV_EXCL_START */
327 : default : desc = "unknown"; break;
328 : /* LCOV_EXCL_STOP */
329 : }
330 :
- 331 728955 : if (hash_is_invalid(block->hash)) {
+ 331 729212 : if (hash_is_invalid(block->hash)) {
332 13843 : hash = "lost";
- 333 715112 : } else if (hash_is_zero(block->hash)) {
+ 333 715369 : } else if (hash_is_zero(block->hash)) {
334 8 : hash = "zero";
335 : } else {
- 336 715104 : hash = "known";
+ 336 715361 : hash = "known";
337 : }
338 :
- 339 728955 : if (failed[j].is_bad)
- 340 643230 : data = "bad";
+ 339 729212 : if (failed[j].is_bad)
+ 340 643487 : data = "bad";
341 : else
342 85725 : data = "good";
343 :
- 344 728955 : if (failed[j].file) {
- 345 710501 : struct snapraid_disk* disk = failed[j].disk;
- 346 710501 : struct snapraid_file* file = failed[j].file;
- 347 710501 : block_off_t file_pos = failed[j].file_pos;
+ 344 729212 : if (failed[j].file) {
+ 345 710758 : struct snapraid_disk* disk = failed[j].disk;
+ 346 710758 : struct snapraid_file* file = failed[j].file;
+ 347 710758 : block_off_t file_pos = failed[j].file_pos;
348 :
- 349 710501 : log_tag("repair_entry:%u:%s:%s:%s:%s:%s:%u:\n", j, desc, hash, data, disk->name, esc_tag(file->sub, esc_buffer), file_pos);
+ 349 710758 : log_tag("repair_entry:%u:%s:%s:%s:%s:%s:%u:\n", j, desc, hash, data, disk->name, esc_tag(file->sub, esc_buffer), file_pos);
350 : } else {
351 18454 : log_tag("repair_entry:%u:%s:%s:%s:\n", j, desc, hash, data);
352 : }
@@ -430,35 +430,35 @@
368 : /* We are interested to recover BLK, REP and CHG blocks if they are marked as bad, */
369 : /* but we are not interested in DELETED ones. */
370 :
- 371 287509 : n = 0;
- 372 287509 : something_to_recover = 0; /* keep track if there is at least one block to fix */
- 373 1016464 : for (j = 0; j < failed_count; ++j) {
- 374 728955 : if (failed[j].is_bad) {
- 375 643230 : unsigned block_state = block_state_get(failed[j].block);
+ 371 287730 : n = 0;
+ 372 287730 : something_to_recover = 0; /* keep track if there is at least one block to fix */
+ 373 1016942 : for (j = 0; j < failed_count; ++j) {
+ 374 729212 : if (failed[j].is_bad) {
+ 375 643487 : unsigned block_state = block_state_get(failed[j].block);
376 :
- 377 643230 : assert(block_state != BLOCK_STATE_DELETED); /* we cannot have bad DELETED blocks */
+ 377 643487 : assert(block_state != BLOCK_STATE_DELETED); /* we cannot have bad DELETED blocks */
378 :
379 : /* if we have the hash for it */
- 380 643230 : if ((block_state == BLOCK_STATE_BLK || block_state == BLOCK_STATE_REP)
+ 380 643487 : if ((block_state == BLOCK_STATE_BLK || block_state == BLOCK_STATE_REP)
381 : /* try to fetch the block using the known hash */
- 382 643222 : && (state_import_fetch(state, rehash, failed[j].block, buffer[failed[j].index]) == 0
- 383 638750 : || state_search_fetch(state, rehash, failed[j].file, failed[j].file_pos, failed[j].block, buffer[failed[j].index]) == 0)
+ 382 643479 : && (state_import_fetch(state, rehash, failed[j].block, buffer[failed[j].index]) == 0
+ 383 639007 : || state_search_fetch(state, rehash, failed[j].file, failed[j].file_pos, failed[j].block, buffer[failed[j].index]) == 0)
384 : ) {
385 : /* we already have corrected it! */
386 22382 : log_tag("repair_hash_import:%u: Fixed by import\n", j);
387 : } else {
388 : /* otherwise try to recover it */
- 389 620848 : failed_map[n] = j;
- 390 620848 : ++n;
+ 389 621105 : failed_map[n] = j;
+ 390 621105 : ++n;
391 :
392 : /* we have something to try to recover */
- 393 620848 : something_to_recover = 1;
+ 393 621105 : something_to_recover = 1;
394 : }
395 : }
396 : }
397 :
398 : /* if nothing to fix */
- 399 287509 : if (!something_to_recover) {
+ 399 287730 : if (!something_to_recover) {
400 43956 : log_tag("recover_sync:%u:%u: Skipped for already recovered\n", pos, n);
401 :
402 : /* recompute only the parity */
@@ -466,22 +466,22 @@
404 43956 : return 0;
405 : }
406 :
- 407 243553 : ret = repair_step(state, rehash, pos, diskmax, failed, failed_map, n, buffer, buffer_recov, buffer_zero);
- 408 243553 : if (ret == 0) {
+ 407 243774 : ret = repair_step(state, rehash, pos, diskmax, failed, failed_map, n, buffer, buffer_recov, buffer_zero);
+ 408 243774 : if (ret == 0) {
409 : /* reprocess the CHG blocks, for which we don't have a hash to check */
410 : /* if they were BAD we have to use some heuristics to ensure that we have recovered */
411 : /* the state after the sync. If unsure, we assume the worst case */
412 :
- 413 667399 : for (j = 0; j < failed_count; ++j) {
+ 413 667734 : for (j = 0; j < failed_count; ++j) {
414 : /* we take care only of BAD blocks we have to write back */
- 415 476295 : if (failed[j].is_bad) {
- 416 462823 : unsigned block_state = block_state_get(failed[j].block);
+ 415 476460 : if (failed[j].is_bad) {
+ 416 462988 : unsigned block_state = block_state_get(failed[j].block);
417 :
418 : /* BLK and REP blocks are always OK, because at this point */
419 : /* we have already checked their hash */
- 420 462823 : if (block_state != BLOCK_STATE_CHG) {
- 421 462815 : assert(block_state == BLOCK_STATE_BLK || block_state == BLOCK_STATE_REP);
- 422 462815 : continue;
+ 420 462988 : if (block_state != BLOCK_STATE_CHG) {
+ 421 462980 : assert(block_state == BLOCK_STATE_BLK || block_state == BLOCK_STATE_REP);
+ 422 462980 : continue;
423 : }
424 :
425 : /* for CHG blocks we have to 'guess' if they are correct or not */
@@ -523,15 +523,15 @@
461 : }
462 : }
463 :
- 464 191104 : return 0;
+ 464 191274 : return 0;
465 : }
- 466 52449 : if (ret > 0)
- 467 9328 : error += ret;
+ 466 52500 : if (ret > 0)
+ 467 9338 : error += ret;
468 :
- 469 52449 : if (ret < 0)
- 470 43121 : log_tag("recover_sync:%u:%u: Failed with no attempts\n", pos, n);
+ 469 52500 : if (ret < 0)
+ 470 43162 : log_tag("recover_sync:%u:%u: Failed with no attempts\n", pos, n);
471 : else
- 472 9328 : log_tag("recover_sync:%u:%u: Failed with %d attempts\n", pos, n, ret);
+ 472 9338 : log_tag("recover_sync:%u:%u: Failed with %d attempts\n", pos, n, ret);
473 :
474 : /* Now assume that the parity IS NOT updated at the current state, */
475 : /* but still represent the state before the last 'sync' process. */
@@ -541,15 +541,15 @@
479 : /* but we are not interested to recover CHG (new version) and REP (new version) blocks, */
480 : /* even if marked as bad, because we don't have parity for them and it's just impossible, */
481 : /* and we are not interested to recover DELETED ones. */
- 482 52449 : n = 0;
- 483 52449 : something_to_recover = 0; /* keep track if there is at least one block to fix */
- 484 52449 : something_unsynced = 0; /* keep track if we have some unsynced info to process */
- 485 232673 : for (j = 0; j < failed_count; ++j) {
- 486 180224 : unsigned block_state = block_state_get(failed[j].block);
+ 482 52500 : n = 0;
+ 483 52500 : something_to_recover = 0; /* keep track if there is at least one block to fix */
+ 484 52500 : something_unsynced = 0; /* keep track if we have some unsynced info to process */
+ 485 232816 : for (j = 0; j < failed_count; ++j) {
+ 486 180316 : unsigned block_state = block_state_get(failed[j].block);
487 :
- 488 180224 : if (block_state == BLOCK_STATE_DELETED
- 489 171180 : || block_state == BLOCK_STATE_CHG
- 490 171180 : || block_state == BLOCK_STATE_REP
+ 488 180316 : if (block_state == BLOCK_STATE_DELETED
+ 489 171272 : || block_state == BLOCK_STATE_CHG
+ 490 171272 : || block_state == BLOCK_STATE_REP
491 : ) {
492 : /* If the block is CHG, REP or DELETED, we don't have the original content of block, */
493 : /* and we must try to recover it. */
@@ -591,24 +591,24 @@
529 : /* it also applies to CHG and DELETE blocks because we want to have */
530 : /* a successful recovering only if a BLK one is matching */
531 9044 : failed[j].is_outofdate = 1;
- 532 171180 : } else if (failed[j].is_bad) {
+ 532 171272 : } else if (failed[j].is_bad) {
533 : /* If the block is bad we don't know its content, and we try to recover it */
534 : /* At this point, we can have only BLK ones */
535 :
- 536 171180 : assert(block_state == BLOCK_STATE_BLK);
+ 536 171272 : assert(block_state == BLOCK_STATE_BLK);
537 :
538 : /* we have something we are interested to recover */
- 539 171180 : something_to_recover = 1;
+ 539 171272 : something_to_recover = 1;
540 :
541 : /* we try to recover it */
- 542 171180 : failed_map[n] = j;
- 543 171180 : ++n;
+ 542 171272 : failed_map[n] = j;
+ 543 171272 : ++n;
544 : }
545 : }
546 :
547 : /* if nothing to fix, we just don't try */
548 : /* if nothing unsynced we also don't retry, because it's the same try as before */
- 549 52449 : if (something_to_recover && something_unsynced) {
+ 549 52500 : if (something_to_recover && something_unsynced) {
550 9044 : ret = repair_step(state, rehash, pos, diskmax, failed, failed_map, n, buffer, buffer_recov, buffer_zero);
551 9044 : if (ret == 0) {
552 : /* reprocess the REP and CHG blocks, for which we have recovered an old state */
@@ -642,17 +642,17 @@
580 : else
581 0 : log_tag("recover_unsync:%u:%u: Failed with %d attempts\n", pos, n, ret);
582 : } else {
- 583 43405 : log_tag("recover_unsync:%u:%u: Skipped for%s%s\n", pos, n,
+ 583 43456 : log_tag("recover_unsync:%u:%u: Skipped for%s%s\n", pos, n,
584 : !something_to_recover ? " nothing to recover" : "",
585 : !something_unsynced ? " nothing unsynced" : ""
586 : );
587 : }
588 :
589 : /* return the number of failed attempts, or -1 if no strategy */
- 590 47927 : if (error)
- 591 4806 : return error;
+ 590 47978 : if (error)
+ 591 4816 : return error;
592 : else
- 593 43121 : return -1;
+ 593 43162 : return -1;
594 : }
595 :
596 : /**
@@ -686,7 +686,7 @@
624 5469678 : disk = handle[j].disk;
625 5469678 : if (!disk) {
626 : /* if no disk, nothing to do */
- 627 3341616 : continue;
+ 627 3341619 : continue;
628 : }
629 :
630 5455617 : block = fs_par2block_find(disk, i);
@@ -700,35 +700,35 @@
638 : /* if it isn't the last block in the file */
639 5245100 : if (!file_block_is_last(file, file_pos)) {
640 : /* nothing to do */
- 641 3117038 : continue;
+ 641 3117041 : continue;
642 : }
643 :
644 : /* if the file is excluded, we have nothing to adjust as the file is never written */
- 645 2128062 : if (file_flag_has(file, FILE_IS_EXCLUDED)
- 646 2070660 : || (state->opt.syncedonly && file_flag_has(file, FILE_IS_UNSYNCED))) {
+ 645 2128059 : if (file_flag_has(file, FILE_IS_EXCLUDED)
+ 646 2070705 : || (state->opt.syncedonly && file_flag_has(file, FILE_IS_UNSYNCED))) {
647 : /* nothing to do, but close the file */
- 648 57402 : goto close_and_continue;
+ 648 57354 : goto close_and_continue;
649 : }
650 :
651 : /* finish the fix process if it's the last block of the files */
- 652 2070660 : if (fix) {
+ 652 2070705 : if (fix) {
653 : /* mark that we finished with this file */
654 : /* to identify later any NOT finished ones */
- 655 765508 : file_flag_set(file, FILE_IS_FINISHED);
+ 655 765553 : file_flag_set(file, FILE_IS_FINISHED);
656 :
657 : /* if the file is damaged, meaning that a fix failed */
- 658 765508 : if (file_flag_has(file, FILE_IS_DAMAGED)) {
+ 658 765553 : if (file_flag_has(file, FILE_IS_DAMAGED)) {
659 : /* rename it to .unrecoverable */
660 : char path[PATH_MAX];
661 : char path_to[PATH_MAX];
662 :
- 663 63262 : pathprint(path, sizeof(path), "%s%s", disk->dir, file->sub);
- 664 63262 : pathprint(path_to, sizeof(path_to), "%s%s.unrecoverable", disk->dir, file->sub);
+ 663 63301 : pathprint(path, sizeof(path), "%s%s", disk->dir, file->sub);
+ 664 63301 : pathprint(path_to, sizeof(path_to), "%s%s.unrecoverable", disk->dir, file->sub);
665 :
666 : /* ensure to close the file before renaming */
- 667 63262 : if (handle[j].file == file) {
- 668 63262 : ret = handle_close(&handle[j]);
- 669 63262 : if (ret != 0) {
+ 667 63301 : if (handle[j].file == file) {
+ 668 63301 : ret = handle_close(&handle[j]);
+ 669 63301 : if (ret != 0) {
670 : /* LCOV_EXCL_START */
671 : log_tag("%s:%u:%s:%s: Close error. %s.\n", es(errno), i, disk->name, esc_tag(file->sub, esc_buffer), strerror(errno));
672 : log_fatal_errno(errno, disk->name);
@@ -737,8 +737,8 @@
675 : }
676 : }
677 :
- 678 63262 : ret = rename(path, path_to);
- 679 63262 : if (ret != 0) {
+ 678 63301 : ret = rename(path, path_to);
+ 679 63301 : if (ret != 0) {
680 : /* LCOV_EXCL_START */
681 : log_fatal(errno, "Error renaming '%s%s'. %s.\n", disk->dir, file->sub, strerror(errno));
682 : log_tag("%s:%u:%s:%s: Rename error. %s.\n", es(errno), i, disk->name, esc_tag(file->sub, esc_buffer), strerror(errno));
@@ -747,22 +747,22 @@
685 : /* LCOV_EXCL_STOP */
686 : }
687 :
- 688 63262 : log_tag("status:unrecoverable:%s:%s\n", disk->name, esc_tag(file->sub, esc_buffer));
- 689 63262 : msg_info("unrecoverable %s\n", fmt_term(disk, file->sub, esc_buffer));
+ 688 63301 : log_tag("status:unrecoverable:%s:%s\n", disk->name, esc_tag(file->sub, esc_buffer));
+ 689 63301 : msg_info("unrecoverable %s\n", fmt_term(disk, file->sub, esc_buffer));
690 :
691 : /* and do not set the time if damaged */
- 692 63262 : goto close_and_continue;
+ 692 63301 : goto close_and_continue;
693 : }
694 :
695 : /* if the file is not fixed, meaning that it is untouched */
- 696 702246 : if (!file_flag_has(file, FILE_IS_FIXED)) {
+ 696 702252 : if (!file_flag_has(file, FILE_IS_FIXED)) {
697 : /* nothing to do, but close the file */
- 698 581072 : goto close_and_continue;
+ 698 581048 : goto close_and_continue;
699 : }
700 :
701 : /* if the file is closed or different than the one expected, reopen it */
702 : /* a different open file could happen when filtering for bad blocks */
- 703 121174 : if (handle[j].file != file) {
+ 703 121204 : if (handle[j].file != file) {
704 : /* keep a pointer at the file we are going to close for error reporting */
705 0 : struct snapraid_file* report = handle[j].file;
706 0 : ret = handle_close(&handle[j]);
@@ -786,13 +786,13 @@
724 : }
725 : }
726 :
- 727 121174 : log_tag("status:recovered:%s:%s\n", disk->name, esc_tag(file->sub, esc_buffer));
- 728 121174 : msg_info("recovered %s\n", fmt_term(disk, file->sub, esc_buffer));
+ 727 121204 : log_tag("status:recovered:%s:%s\n", disk->name, esc_tag(file->sub, esc_buffer));
+ 728 121204 : msg_info("recovered %s\n", fmt_term(disk, file->sub, esc_buffer));
729 :
- 730 121174 : inode = handle[j].st.st_ino;
+ 730 121204 : inode = handle[j].st.st_ino;
731 :
732 : /* search for the corresponding inode */
- 733 121174 : collide_file = tommy_hashdyn_search(&disk->inodeset, file_inode_compare_to_arg, &inode, file_inode_hash(inode));
+ 733 121204 : collide_file = tommy_hashdyn_search(&disk->inodeset, file_inode_compare_to_arg, &inode, file_inode_hash(inode));
734 :
735 : /* if the inode is already in the database and it refers to a different file name, */
736 : /* we can fix the file time ONLY if the time and size allow to differentiate */
@@ -802,15 +802,15 @@
740 : /* when recreating them the inodes may be reused in a different order, */
741 : /* and at the next sync some files may have matching inode/size/time even if different name */
742 : /* not allowing sync to detect that the file is changed and not renamed */
- 743 121174 : if (!collide_file /* if not in the database, there is no collision */
- 744 42214 : || strcmp(collide_file->sub, file->sub) == 0 /* if the name is the same, it's the right collision */
- 745 33405 : || collide_file->size != file->size /* if the size is different, the collision is identified */
+ 743 121204 : if (!collide_file /* if not in the database, there is no collision */
+ 744 44180 : || strcmp(collide_file->sub, file->sub) == 0 /* if the name is the same, it's the right collision */
+ 745 35319 : || collide_file->size != file->size /* if the size is different, the collision is identified */
746 9 : || collide_file->mtime_sec != file->mtime_sec /* if the mtime is different, the collision is identified */
- 747 5 : || collide_file->mtime_nsec != file->mtime_nsec /* same for mtime_nsec */
+ 747 8 : || collide_file->mtime_nsec != file->mtime_nsec /* same for mtime_nsec */
748 : ) {
749 : /* set the original modification time */
- 750 121173 : ret = handle_utime(&handle[j]);
- 751 121173 : if (ret == -1) {
+ 750 121204 : ret = handle_utime(&handle[j]);
+ 751 121204 : if (ret == -1) {
752 : /* LCOV_EXCL_START */
753 : log_tag("%s:%u:%s:%s: Time error. %s.\n", es(errno), i, disk->name, esc_tag(file->sub, esc_buffer), strerror(errno));
754 : log_fatal_errno(errno, disk->name);
@@ -821,35 +821,35 @@
759 : /* LCOV_EXCL_STOP */
760 : }
761 : } else {
- 762 1 : log_tag("collision:%s:%s:%s: Not setting modification time to avoid inode collision\n", disk->name, esc_tag(file->sub, esc_buffer), esc_tag(collide_file->sub, esc_buffer_alt));
+ 762 0 : log_tag("collision:%s:%s:%s: Not setting modification time to avoid inode collision\n", disk->name, esc_tag(file->sub, esc_buffer), esc_tag(collide_file->sub, esc_buffer_alt));
763 : }
764 : } else {
765 : /* we are not fixing, but only checking */
766 : /* print just the final status */
767 1305152 : if (file_flag_has(file, FILE_IS_DAMAGED)) {
- 768 9430 : log_tag("status:unrecoverable:%s:%s\n", disk->name, esc_tag(file->sub, esc_buffer));
- 769 9430 : msg_info("unrecoverable %s\n", fmt_term(disk, file->sub, esc_buffer));
- 770 1295722 : } else if (file_flag_has(file, FILE_IS_FIXED)) {
- 771 76206 : log_tag("status:recoverable:%s:%s\n", disk->name, esc_tag(file->sub, esc_buffer));
- 772 76206 : msg_info("recoverable %s\n", fmt_term(disk, file->sub, esc_buffer));
+ 768 9483 : log_tag("status:unrecoverable:%s:%s\n", disk->name, esc_tag(file->sub, esc_buffer));
+ 769 9483 : msg_info("unrecoverable %s\n", fmt_term(disk, file->sub, esc_buffer));
+ 770 1295669 : } else if (file_flag_has(file, FILE_IS_FIXED)) {
+ 771 76272 : log_tag("status:recoverable:%s:%s\n", disk->name, esc_tag(file->sub, esc_buffer));
+ 772 76272 : msg_info("recoverable %s\n", fmt_term(disk, file->sub, esc_buffer));
773 : } else {
774 : /* we don't use msg_verbose() because it also goes into the log */
- 775 1219516 : if (msg_level >= MSG_VERBOSE) {
- 776 20373 : log_tag("status:correct:%s:%s\n", disk->name, esc_tag(file->sub, esc_buffer));
- 777 20373 : msg_info("correct %s\n", fmt_term(disk, file->sub, esc_buffer));
+ 775 1219397 : if (msg_level >= MSG_VERBOSE) {
+ 776 20355 : log_tag("status:correct:%s:%s\n", disk->name, esc_tag(file->sub, esc_buffer));
+ 777 20355 : msg_info("correct %s\n", fmt_term(disk, file->sub, esc_buffer));
778 : }
779 : }
780 : }
781 :
- 782 1199143 : close_and_continue:
+ 782 1199042 : close_and_continue:
783 : /* if the opened file is the correct one, close it */
784 : /* in case of excluded and fragmented files it's possible */
785 : /* that the opened file is not the current one */
- 786 2128062 : if (handle[j].file == file) {
+ 786 2128059 : if (handle[j].file == file) {
787 : /* ensure to close the file just after finishing with it */
788 : /* to avoid keeping it open without any possible use */
- 789 1986088 : ret = handle_close(&handle[j]);
- 790 1986088 : if (ret != 0) {
+ 789 1986081 : ret = handle_close(&handle[j]);
+ 790 1986081 : if (ret != 0) {
791 : /* LCOV_EXCL_START */
792 : log_tag("%s:%u:%s:%s: Close error. %s.\n", es(errno), i, disk->name, esc_tag(file->sub, esc_buffer), strerror(errno));
793 : log_fatal_errno(errno, disk->name);
@@ -902,7 +902,7 @@
840 : * the bad blocks.
841 : */
842 9374 : if (info_get_bad(info))
- 843 1771 : return 1;
+ 843 1772 : return 1;
844 : } else {
845 : /* if a parity is not excluded, include all blocks, even unused ones */
846 1061137 : for (l = 0; l < state->level; ++l) {
@@ -913,21 +913,21 @@
851 : }
852 :
853 : /* filter for the files */
- 854 238634 : for (j = 0; j < diskmax; ++j) {
+ 854 238648 : for (j = 0; j < diskmax; ++j) {
855 : struct snapraid_block* block;
856 :
857 : /* if no disk, nothing to check */
- 858 214768 : if (!handle[j].disk)
+ 858 214782 : if (!handle[j].disk)
859 0 : continue;
860 :
- 861 214768 : block = fs_par2block_find(handle[j].disk, i);
+ 861 214782 : block = fs_par2block_find(handle[j].disk, i);
862 :
863 : /* try to recover all files, even the ones without hash */
864 : /* because in some cases we can recover also them */
- 865 214768 : if (block_has_file(block)) {
- 866 210845 : struct snapraid_file* file = fs_par2file_get(handle[j].disk, i, 0);
- 867 210845 : if (!file_flag_has(file, FILE_IS_EXCLUDED)) { /* only if the file is not filtered out */
- 868 25427 : return 1;
+ 865 214782 : if (block_has_file(block)) {
+ 866 210859 : struct snapraid_file* file = fs_par2file_get(handle[j].disk, i, 0);
+ 867 210859 : if (!file_flag_has(file, FILE_IS_EXCLUDED)) { /* only if the file is not filtered out */
+ 868 25426 : return 1;
869 : }
870 : }
871 : }
@@ -1068,7 +1068,7 @@
1006 5469678 : if (!disk) {
1007 : /* use an empty block */
1008 14061 : memset(buffer[j], 0, state->block_size);
- 1009 940909 : continue;
+ 1009 941260 : continue;
1010 : }
1011 :
1012 : /* if the disk block is not used */
@@ -1127,9 +1127,9 @@
1065 : /* if the file is closed or different than the current one */
1066 5245100 : if (handle[j].file == 0 || handle[j].file != file) {
1067 : /* keep a pointer at the file we are going to close for error reporting */
- 1068 2259176 : struct snapraid_file* report = handle[j].file;
- 1069 2259176 : ret = handle_close(&handle[j]);
- 1070 2259176 : if (ret == -1) {
+ 1068 2259318 : struct snapraid_file* report = handle[j].file;
+ 1069 2259318 : ret = handle_close(&handle[j]);
+ 1070 2259318 : if (ret == -1) {
1071 : /* LCOV_EXCL_START */
1072 : log_tag("%s:%u:%s:%s: Close error. %s.\n", es(errno), i, disk->name, esc_tag(report->sub, esc_buffer), strerror(errno));
1073 : log_fatal_errno(errno, disk->name);
@@ -1141,10 +1141,10 @@
1079 : }
1080 :
1081 : /* if fixing, and the file is not excluded, we must open for writing */
- 1082 2259176 : if (fix && !file_flag_has(file, FILE_IS_EXCLUDED)) {
+ 1082 2259318 : if (fix && !file_flag_has(file, FILE_IS_EXCLUDED)) {
1083 : /* if fixing, create the file, open for writing and resize if required */
- 1084 771292 : ret = handle_create(&handle[j], file, state->file_mode);
- 1085 771292 : if (ret == -1) {
+ 1084 771350 : ret = handle_create(&handle[j], file, state->file_mode);
+ 1085 771350 : if (ret == -1) {
1086 : /* LCOV_EXCL_START */
1087 : log_tag("%s:%u:%s:%s: Create error. %s.\n", es(errno), i, disk->name, esc_tag(file->sub, esc_buffer), strerror(errno));
1088 : log_fatal_errno(errno, disk->name);
@@ -1156,75 +1156,75 @@
1094 : }
1095 :
1096 : /* check if the file was just created */
- 1097 771292 : if (handle[j].created != 0) {
+ 1097 771350 : if (handle[j].created != 0) {
1098 : /* if fragmented, it may be reopened, so remember that the file */
1099 : /* was originally missing */
- 1100 113113 : file_flag_set(file, FILE_IS_CREATED);
+ 1100 113069 : file_flag_set(file, FILE_IS_CREATED);
1101 : }
1102 : } else {
1103 : /* open the file only for reading */
- 1104 1487884 : if (!file_flag_has(file, FILE_IS_MISSING)) {
- 1105 1372280 : ret = handle_open(&handle[j], file, state->file_mode, log_error, state->opt.expected_missing ? log_expected : 0);
+ 1104 1487968 : if (!file_flag_has(file, FILE_IS_MISSING)) {
+ 1105 1372199 : ret = handle_open(&handle[j], file, state->file_mode, log_error, state->opt.expected_missing ? log_expected : 0);
1106 : } else {
- 1107 115604 : errno = ENOENT;
- 1108 115604 : ret = -1; /* if the file is missing, we cannot open it */
+ 1107 115769 : errno = ENOENT;
+ 1108 115769 : ret = -1; /* if the file is missing, we cannot open it */
1109 : }
- 1110 1487884 : if (ret == -1) {
+ 1110 1487968 : if (ret == -1) {
1111 : /* save the failed block for the check/fix */
- 1112 194317 : failed[failed_count].is_bad = 1;
- 1113 194317 : failed[failed_count].is_outofdate = 0;
- 1114 194317 : failed[failed_count].index = j;
- 1115 194317 : failed[failed_count].block = block;
- 1116 194317 : failed[failed_count].disk = disk;
- 1117 194317 : failed[failed_count].file = file;
- 1118 194317 : failed[failed_count].file_pos = file_pos;
- 1119 194317 : failed[failed_count].handle = &handle[j];
- 1120 194317 : ++failed_count;
+ 1112 194447 : failed[failed_count].is_bad = 1;
+ 1113 194447 : failed[failed_count].is_outofdate = 0;
+ 1114 194447 : failed[failed_count].index = j;
+ 1115 194447 : failed[failed_count].block = block;
+ 1116 194447 : failed[failed_count].disk = disk;
+ 1117 194447 : failed[failed_count].file = file;
+ 1118 194447 : failed[failed_count].file_pos = file_pos;
+ 1119 194447 : failed[failed_count].handle = &handle[j];
+ 1120 194447 : ++failed_count;
1121 :
- 1122 194317 : log_tag("%s:%u:%s:%s: Open error at position %u. %s.\n", es(errno), i, disk->name, esc_tag(file->sub, esc_buffer), file_pos, strerror(errno));
+ 1122 194447 : log_tag("%s:%u:%s:%s: Open error at position %u. %s.\n", es(errno), i, disk->name, esc_tag(file->sub, esc_buffer), file_pos, strerror(errno));
1123 :
- 1124 194317 : if (is_hw(errno)) {
+ 1124 194447 : if (is_hw(errno)) {
1125 0 : ++io_error;
1126 : } else {
- 1127 194317 : ++soft_error;
+ 1127 194447 : ++soft_error;
1128 : }
1129 :
1130 : /* mark the file as missing, to avoid to retry to open it again */
1131 : /* note that this can be done only if we are not fixing it */
1132 : /* otherwise, it could be recreated */
- 1133 194317 : file_flag_set(file, FILE_IS_MISSING);
- 1134 194317 : continue;
+ 1133 194447 : file_flag_set(file, FILE_IS_MISSING);
+ 1134 194447 : continue;
1135 : }
1136 : }
1137 :
1138 : /* if it's the first open, and not excluded */
- 1139 2064859 : if (!file_flag_has(file, FILE_IS_OPENED)
- 1140 2049425 : && !file_flag_has(file, FILE_IS_EXCLUDED)) {
+ 1139 2064871 : if (!file_flag_has(file, FILE_IS_OPENED)
+ 1140 2049466 : && !file_flag_has(file, FILE_IS_EXCLUDED)) {
1141 :
1142 : /* check if the file is changed */
- 1143 1995721 : if (handle[j].st.st_size != file->size
- 1144 1802900 : || handle[j].st.st_mtime != file->mtime_sec
- 1145 1779966 : || STAT_NSEC(&handle[j].st) != file->mtime_nsec
+ 1143 1995801 : if (handle[j].st.st_size != file->size
+ 1144 1803079 : || handle[j].st.st_mtime != file->mtime_sec
+ 1145 1780127 : || STAT_NSEC(&handle[j].st) != file->mtime_nsec
1146 : /* don't check the inode to support file-system without persistent inodes */
1147 : ) {
1148 : /* report that the file is not synced */
- 1149 215755 : file_flag_set(file, FILE_IS_UNSYNCED);
+ 1149 215674 : file_flag_set(file, FILE_IS_UNSYNCED);
1150 : }
1151 : }
1152 :
1153 : /* if it's the first open, and not excluded and larger */
- 1154 2064859 : if (!file_flag_has(file, FILE_IS_OPENED)
- 1155 2049425 : && !file_flag_has(file, FILE_IS_EXCLUDED)
- 1156 1995721 : && !(state->opt.syncedonly && file_flag_has(file, FILE_IS_UNSYNCED))
- 1157 1995721 : && handle[j].st.st_size > file->size
+ 1154 2064871 : if (!file_flag_has(file, FILE_IS_OPENED)
+ 1155 2049466 : && !file_flag_has(file, FILE_IS_EXCLUDED)
+ 1156 1995801 : && !(state->opt.syncedonly && file_flag_has(file, FILE_IS_UNSYNCED))
+ 1157 1995801 : && handle[j].st.st_size > file->size
1158 : ) {
- 1159 8795 : log_error(ESOFT, "File '%s' is larger than expected.\n", handle[j].path);
- 1160 8795 : log_tag("error:%u:%s:%s: Size error\n", i, disk->name, esc_tag(file->sub, esc_buffer));
- 1161 8795 : ++soft_error;
+ 1159 8695 : log_error(ESOFT, "File '%s' is larger than expected.\n", handle[j].path);
+ 1160 8695 : log_tag("error:%u:%s:%s: Size error\n", i, disk->name, esc_tag(file->sub, esc_buffer));
+ 1161 8695 : ++soft_error;
1162 :
- 1163 8795 : if (fix) {
- 1164 3256 : ret = handle_truncate(&handle[j], file);
- 1165 3256 : if (ret == -1) {
+ 1163 8695 : if (fix) {
+ 1164 3213 : ret = handle_truncate(&handle[j], file);
+ 1165 3213 : if (ret == -1) {
1166 : /* LCOV_EXCL_START */
1167 : log_tag("%s:%u:%s:%s: Truncate error. %s.\n", es(errno), i, disk->name, esc_tag(file->sub, esc_buffer), strerror(errno));
1168 : log_fatal_errno(errno, disk->name);
@@ -1235,58 +1235,58 @@
1173 : /* LCOV_EXCL_STOP */
1174 : }
1175 :
- 1176 3256 : log_tag("fixed:%u:%s:%s: Fixed size\n", i, disk->name, esc_tag(file->sub, esc_buffer));
- 1177 3256 : ++recovered_error;
+ 1176 3213 : log_tag("fixed:%u:%s:%s: Fixed size\n", i, disk->name, esc_tag(file->sub, esc_buffer));
+ 1177 3213 : ++recovered_error;
1178 : }
1179 : }
1180 :
1181 : /* mark the file as opened at least one time */
1182 : /* this is used to avoid to check the unsynced and size */
1183 : /* more than one time, in case the file is reopened later */
- 1184 2064859 : file_flag_set(file, FILE_IS_OPENED);
+ 1184 2064871 : file_flag_set(file, FILE_IS_OPENED);
1185 : }
1186 :
1187 : /* read from the file */
- 1188 5050783 : if (file_flag_has(file, FILE_IS_MISSING)) {
+ 1188 5050653 : if (file_flag_has(file, FILE_IS_MISSING)) {
1189 : /* if the file is reported missing, don't even try to read it */
- 1190 256474 : errno = ENOENT;
- 1191 256474 : read_size = -1;
+ 1190 256551 : errno = ENOENT;
+ 1191 256551 : read_size = -1;
1192 : } else {
- 1193 4794309 : read_size = handle_read(&handle[j], file_pos, buffer[j], state->block_size, log_error, state->opt.expected_missing ? log_expected : 0);
+ 1193 4794102 : read_size = handle_read(&handle[j], file_pos, buffer[j], state->block_size, log_error, state->opt.expected_missing ? log_expected : 0);
1194 : }
- 1195 5050783 : if (read_size == -1) {
+ 1195 5050653 : if (read_size == -1) {
1196 : /* save the failed block for the check/fix */
- 1197 442171 : failed[failed_count].is_bad = 1; /* it's bad because we cannot read it */
- 1198 442171 : failed[failed_count].is_outofdate = 0;
- 1199 442171 : failed[failed_count].index = j;
- 1200 442171 : failed[failed_count].block = block;
- 1201 442171 : failed[failed_count].disk = disk;
- 1202 442171 : failed[failed_count].file = file;
- 1203 442171 : failed[failed_count].file_pos = file_pos;
- 1204 442171 : failed[failed_count].handle = &handle[j];
- 1205 442171 : ++failed_count;
+ 1197 442068 : failed[failed_count].is_bad = 1; /* it's bad because we cannot read it */
+ 1198 442068 : failed[failed_count].is_outofdate = 0;
+ 1199 442068 : failed[failed_count].index = j;
+ 1200 442068 : failed[failed_count].block = block;
+ 1201 442068 : failed[failed_count].disk = disk;
+ 1202 442068 : failed[failed_count].file = file;
+ 1203 442068 : failed[failed_count].file_pos = file_pos;
+ 1204 442068 : failed[failed_count].handle = &handle[j];
+ 1205 442068 : ++failed_count;
1206 :
- 1207 442171 : log_tag("%s:%u:%s:%s: Read error at position %u. %s.\n", es(errno), i, disk->name, esc_tag(file->sub, esc_buffer), file_pos, strerror(errno));
+ 1207 442068 : log_tag("%s:%u:%s:%s: Read error at position %u. %s.\n", es(errno), i, disk->name, esc_tag(file->sub, esc_buffer), file_pos, strerror(errno));
1208 :
- 1209 442171 : if (is_hw(errno)) {
+ 1209 442068 : if (is_hw(errno)) {
1210 0 : ++io_error;
1211 : } else {
- 1212 442171 : ++soft_error;
+ 1212 442068 : ++soft_error;
1213 : }
1214 :
1215 : /* if we are reading at the end, mark the file as missing to avoid to try to read it again at the next block */
- 1216 442171 : if (errno == ENOENT) {
- 1217 432266 : file_flag_set(file, FILE_IS_MISSING);
+ 1216 442068 : if (errno == ENOENT) {
+ 1217 432259 : file_flag_set(file, FILE_IS_MISSING);
1218 : }
- 1219 442171 : continue;
+ 1219 442068 : continue;
1220 : }
1221 :
- 1222 4608612 : countsize += read_size;
+ 1222 4608585 : countsize += read_size;
1223 :
1224 : /* always insert CHG blocks, the repair functions needs all of them */
1225 : /* because the parity may be still referring at the old state */
1226 : /* and the repair must be aware of it */
- 1227 4608612 : if (block_state == BLOCK_STATE_CHG) {
+ 1227 4608585 : if (block_state == BLOCK_STATE_CHG) {
1228 : /* we DO NOT mark them as bad to avoid to overwrite them with wrong data. */
1229 : /* if we don't have a hash, we always assume the first read of the block correct. */
1230 13843 : failed[failed_count].is_bad = 0; /* we assume the CHG block correct */
@@ -1301,39 +1301,39 @@
1239 13843 : continue;
1240 : }
1241 :
- 1242 4594769 : assert(block_state == BLOCK_STATE_BLK || block_state == BLOCK_STATE_REP);
+ 1242 4594742 : assert(block_state == BLOCK_STATE_BLK || block_state == BLOCK_STATE_REP);
1243 :
1244 : /* compute the hash of the block just read */
- 1245 4594769 : if (rehash) {
+ 1245 4594742 : if (rehash) {
1246 27243 : memhash(state->prevhash, state->prevhashseed, hash, buffer[j], read_size);
1247 : } else {
- 1248 4567526 : memhash(state->hash, state->hashseed, hash, buffer[j], read_size);
+ 1248 4567499 : memhash(state->hash, state->hashseed, hash, buffer[j], read_size);
1249 : }
1250 :
1251 : /* compare the hash */
- 1252 4594769 : if (memcmp(hash, block->hash, BLOCK_HASH_SIZE) != 0) {
- 1253 12572 : unsigned diff = memdiff(hash, block->hash, BLOCK_HASH_SIZE);
+ 1252 4594742 : if (memcmp(hash, block->hash, BLOCK_HASH_SIZE) != 0) {
+ 1253 12896 : unsigned diff = memdiff(hash, block->hash, BLOCK_HASH_SIZE);
1254 :
1255 : /* save the failed block for the check/fix */
- 1256 12572 : failed[failed_count].is_bad = 1; /* it's bad because the hash doesn't match */
- 1257 12572 : failed[failed_count].is_outofdate = 0;
- 1258 12572 : failed[failed_count].index = j;
- 1259 12572 : failed[failed_count].block = block;
- 1260 12572 : failed[failed_count].disk = disk;
- 1261 12572 : failed[failed_count].file = file;
- 1262 12572 : failed[failed_count].file_pos = file_pos;
- 1263 12572 : failed[failed_count].handle = &handle[j];
- 1264 12572 : ++failed_count;
+ 1256 12896 : failed[failed_count].is_bad = 1; /* it's bad because the hash doesn't match */
+ 1257 12896 : failed[failed_count].is_outofdate = 0;
+ 1258 12896 : failed[failed_count].index = j;
+ 1259 12896 : failed[failed_count].block = block;
+ 1260 12896 : failed[failed_count].disk = disk;
+ 1261 12896 : failed[failed_count].file = file;
+ 1262 12896 : failed[failed_count].file_pos = file_pos;
+ 1263 12896 : failed[failed_count].handle = &handle[j];
+ 1264 12896 : ++failed_count;
1265 :
- 1266 12572 : log_tag("error:%u:%s:%s: Data error at position %u, diff hash bits %u/%u\n", i, disk->name, esc_tag(file->sub, esc_buffer), file_pos, diff, BLOCK_HASH_SIZE * 8);
- 1267 12572 : ++silent_error;
- 1268 12572 : continue;
+ 1266 12896 : log_tag("error:%u:%s:%s: Data error at position %u, diff hash bits %u/%u\n", i, disk->name, esc_tag(file->sub, esc_buffer), file_pos, diff, BLOCK_HASH_SIZE * 8);
+ 1267 12896 : ++silent_error;
+ 1268 12896 : continue;
1269 : }
1270 :
1271 : /* always insert REP blocks, the repair functions needs all of them */
1272 : /* because the parity may be still referring at the old state */
1273 : /* and the repair must be aware of it */
- 1274 4582197 : if (block_state == BLOCK_STATE_REP) {
+ 1274 4581846 : if (block_state == BLOCK_STATE_REP) {
1275 53428 : failed[failed_count].is_bad = 0; /* it's not bad */
1276 53428 : failed[failed_count].is_outofdate = 0;
1277 53428 : failed[failed_count].index = j;
@@ -1385,35 +1385,35 @@
1323 872338 : ret = repair(state, rehash, i, diskmax, failed, failed_map, failed_count, buffer, buffer_recov, buffer_zero);
1324 872338 : if (ret != 0) {
1325 : /* increment the number of errors */
- 1326 47927 : if (ret > 0)
- 1327 4806 : silent_error += ret;
- 1328 47927 : ++unrecoverable_error;
+ 1326 47978 : if (ret > 0)
+ 1327 4816 : silent_error += ret;
+ 1328 47978 : ++unrecoverable_error;
1329 :
1330 : /* print a list of all the errors in files */
- 1331 219107 : for (j = 0; j < failed_count; ++j) {
- 1332 171180 : if (failed[j].is_bad)
- 1333 166658 : 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);
+ 1331 219250 : for (j = 0; j < failed_count; ++j) {
+ 1332 171272 : if (failed[j].is_bad)
+ 1333 166750 : 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);
1334 : }
1335 :
1336 : /* keep track of damaged files */
- 1337 219107 : for (j = 0; j < failed_count; ++j) {
- 1338 171180 : if (failed[j].is_bad)
- 1339 166658 : file_flag_set(failed[j].file, FILE_IS_DAMAGED);
+ 1337 219250 : for (j = 0; j < failed_count; ++j) {
+ 1338 171272 : if (failed[j].is_bad)
+ 1339 166750 : file_flag_set(failed[j].file, FILE_IS_DAMAGED);
1340 : }
1341 : } else {
1342 : /* now counts partial recovers */
1343 : /* note that this could happen only when we have an incomplete 'sync' */
1344 : /* and that we have recovered is the state before the 'sync' */
- 1345 824411 : int partial_recover_error = 0;
+ 1345 824360 : int partial_recover_error = 0;
1346 :
1347 : /* print a list of all the errors in files */
- 1348 1382186 : for (j = 0; j < failed_count; ++j) {
- 1349 557775 : if (failed[j].is_bad && failed[j].is_outofdate) {
+ 1348 1382300 : for (j = 0; j < failed_count; ++j) {
+ 1349 557940 : if (failed[j].is_bad && failed[j].is_outofdate) {
1350 8 : ++partial_recover_error;
1351 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);
1352 : }
1353 : }
- 1354 824411 : if (partial_recover_error != 0) {
+ 1354 824360 : if (partial_recover_error != 0) {
1355 8 : silent_error += partial_recover_error;
1356 8 : ++unrecoverable_error;
1357 : }
@@ -1427,36 +1427,36 @@
1365 : * It's also OK to have data errors on unused parity, because sync doesn't
1366 : * update it.
1367 : */
- 1368 824411 : if (used_parity && valid_parity) {
+ 1368 824360 : if (used_parity && valid_parity) {
1369 : /* check the parity */
- 1370 3738622 : for (l = 0; l < state->level; ++l) {
- 1371 2975796 : if (buffer_recov[l] != 0 && memcmp(buffer_recov[l], buffer[diskmax + l], state->block_size) != 0) {
- 1372 21250 : unsigned diff = memdiff(buffer_recov[l], buffer[diskmax + l], state->block_size);
+ 1370 3738520 : for (l = 0; l < state->level; ++l) {
+ 1371 2975745 : if (buffer_recov[l] != 0 && memcmp(buffer_recov[l], buffer[diskmax + l], state->block_size) != 0) {
+ 1372 21240 : unsigned diff = memdiff(buffer_recov[l], buffer[diskmax + l], state->block_size);
1373 :
1374 : /* mark that the read parity is wrong, setting ptr to 0 */
- 1375 21250 : buffer_recov[l] = 0;
+ 1375 21240 : buffer_recov[l] = 0;
1376 :
- 1377 21250 : log_tag("parity_error:%u:%s: Data error, diff parity bits %u/%u\n", i, lev_config_name(l), diff, state->block_size * 8);
- 1378 21250 : ++silent_error;
+ 1377 21240 : log_tag("parity_error:%u:%s: Data error, diff parity bits %u/%u\n", i, lev_config_name(l), diff, state->block_size * 8);
+ 1378 21240 : ++silent_error;
1379 : }
1380 : }
1381 : }
1382 :
1383 : /* now write recovered files */
- 1384 824411 : if (fix) {
+ 1384 824360 : if (fix) {
1385 : /* update the fixed files */
- 1386 655355 : for (j = 0; j < failed_count; ++j) {
+ 1386 655347 : for (j = 0; j < failed_count; ++j) {
1387 : /* nothing to do if it doesn't need recovering */
- 1388 338027 : if (!failed[j].is_bad)
+ 1388 338061 : if (!failed[j].is_bad)
1389 40318 : continue;
1390 :
1391 : /* do not fix if the file is excluded */
- 1392 297709 : if (file_flag_has(failed[j].file, FILE_IS_EXCLUDED)
- 1393 288429 : || (state->opt.syncedonly && file_flag_has(failed[j].file, FILE_IS_UNSYNCED)))
+ 1392 297743 : if (file_flag_has(failed[j].file, FILE_IS_EXCLUDED)
+ 1393 288463 : || (state->opt.syncedonly && file_flag_has(failed[j].file, FILE_IS_UNSYNCED)))
1394 9280 : continue;
1395 :
- 1396 288429 : ret = handle_write(failed[j].handle, failed[j].file_pos, buffer[failed[j].index], state->block_size);
- 1397 288429 : if (ret == -1) {
+ 1396 288463 : ret = handle_write(failed[j].handle, failed[j].file_pos, buffer[failed[j].index], state->block_size);
+ 1397 288463 : if (ret == -1) {
1398 : /* LCOV_EXCL_START */
1399 : log_tag("%s:%u:%s:%s: Write error. %s.\n", es(errno), i, failed[j].disk->name, esc_tag(failed[j].file->sub, esc_buffer), strerror(errno));
1400 : log_fatal_errno(errno, failed[j].disk->name);
@@ -1471,7 +1471,7 @@
1409 : }
1410 :
1411 : /* if we are not sure that the recovered content is uptodate */
- 1412 288429 : if (failed[j].is_outofdate) {
+ 1412 288463 : if (failed[j].is_outofdate) {
1413 : /* mark the file as damaged */
1414 8 : file_flag_set(failed[j].file, FILE_IS_DAMAGED);
1415 8 : continue;
@@ -1479,10 +1479,10 @@
1417 :
1418 : /* mark the file as containing some fixes */
1419 : /* note that it could be also marked as damaged in other iterations */
- 1420 288421 : file_flag_set(failed[j].file, FILE_IS_FIXED);
+ 1420 288455 : file_flag_set(failed[j].file, FILE_IS_FIXED);
1421 :
- 1422 288421 : 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);
- 1423 288421 : ++recovered_error;
+ 1422 288455 : 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);
+ 1423 288455 : ++recovered_error;
1424 : }
1425 :
1426 : /*
@@ -1495,11 +1495,11 @@
1433 : * we already have allocated space for it on parity file creation,
1434 : * and its content doesn't matter.
1435 : */
- 1436 317328 : if (used_parity && valid_parity) {
+ 1436 317286 : if (used_parity && valid_parity) {
1437 : /* update the parity */
- 1438 982581 : for (l = 0; l < state->level; ++l) {
+ 1438 982497 : for (l = 0; l < state->level; ++l) {
1439 : /* if the parity on disk is wrong */
- 1440 714433 : if (buffer_recov[l] == 0
+ 1440 714391 : if (buffer_recov[l] == 0
1441 : /* and we have access at the parity */
1442 72150 : && parity[l] != 0
1443 : /* and the parity is not excluded */
@@ -1525,9 +1525,9 @@
1463 : } else {
1464 : /* if we are not fixing, we just set the FIXED flag */
1465 : /* meaning that we could fix this file if we try */
- 1466 726831 : for (j = 0; j < failed_count; ++j) {
- 1467 219748 : if (failed[j].is_bad) {
- 1468 178863 : file_flag_set(failed[j].file, FILE_IS_FIXED);
+ 1466 726953 : for (j = 0; j < failed_count; ++j) {
+ 1467 219879 : if (failed[j].is_bad) {
+ 1468 178994 : file_flag_set(failed[j].file, FILE_IS_FIXED);
1469 : }
1470 : }
1471 : }
@@ -1535,9 +1535,9 @@
1473 : } else {
1474 : /* if we are not checking, we just set the DAMAGED flag */
1475 : /* to report that the file is damaged, and we don't know if we can fix it */
- 1476 45105 : for (j = 0; j < failed_count; ++j) {
- 1477 5830 : if (failed[j].is_bad) {
- 1478 5830 : file_flag_set(failed[j].file, FILE_IS_DAMAGED);
+ 1476 45199 : for (j = 0; j < failed_count; ++j) {
+ 1477 5924 : if (failed[j].is_bad) {
+ 1478 5924 : file_flag_set(failed[j].file, FILE_IS_DAMAGED);
1479 : }
1480 : }
1481 : }
@@ -1613,23 +1613,23 @@
1551 2779 : pathprint(path, sizeof(path), "%s%s", disk->dir, file->sub);
1552 2779 : ret = stat(path, &st);
1553 2779 : if (ret == -1) {
- 1554 179 : unsuccessful = 1;
+ 1554 176 : unsuccessful = 1;
1555 :
- 1556 179 : log_error(errno, "Error stating empty file '%s'. %s.\n", path, strerror(errno));
- 1557 179 : log_tag("empty_%s:%s:%s: Empty file stat error\n", es(errno), disk->name, esc_tag(file->sub, esc_buffer));
+ 1556 176 : log_error(errno, "Error stating empty file '%s'. %s.\n", path, strerror(errno));
+ 1557 176 : log_tag("empty_%s:%s:%s: Empty file stat error\n", es(errno), disk->name, esc_tag(file->sub, esc_buffer));
1558 :
- 1559 179 : if (is_hw(errno)) {
+ 1559 176 : if (is_hw(errno)) {
1560 0 : ++io_error;
1561 : } else {
- 1562 179 : ++soft_error;
+ 1562 176 : ++soft_error;
1563 : }
- 1564 2600 : } else if (!S_ISREG(st.st_mode)) {
+ 1564 2603 : } else if (!S_ISREG(st.st_mode)) {
1565 0 : unsuccessful = 1;
1566 :
1567 0 : log_error(ESOFT, "Error stating empty file '%s' for not regular file.\n", path);
1568 0 : log_tag("empty_error:%s:%s: Empty file error for not regular file\n", disk->name, esc_tag(file->sub, esc_buffer));
1569 0 : ++soft_error;
- 1570 2600 : } else if (st.st_size != 0) {
+ 1570 2603 : } else if (st.st_size != 0) {
1571 5 : unsuccessful = 1;
1572 :
1573 5 : log_error(ESOFT, "Error stating empty file '%s' for not empty file.\n", path);
@@ -1641,8 +1641,8 @@
1579 : int f;
1580 :
1581 : /* create the ancestor directories */
- 1582 159 : ret = mkancestor(path);
- 1583 159 : if (ret != 0) {
+ 1582 158 : ret = mkancestor(path);
+ 1583 158 : if (ret != 0) {
1584 : /* LCOV_EXCL_START */
1585 : log_fatal(errno, "Error creating ancestor '%s%s'. %s.\n", disk->dir, file->sub, strerror(errno));
1586 : log_tag("empty_%s:%u:%s:%s: Create ancestor error. %s.\n", es(errno), i, disk->name, esc_tag(file->sub, esc_buffer), strerror(errno));
@@ -1656,8 +1656,8 @@
1594 :
1595 : /* create it */
1596 : /* O_NOFOLLOW: do not follow links to ensure to open the real file */
- 1597 159 : f = open(path, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_NOFOLLOW, 0600);
- 1598 159 : if (f == -1) {
+ 1597 158 : f = open(path, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_NOFOLLOW, 0600);
+ 1598 158 : if (f == -1) {
1599 : /* LCOV_EXCL_START */
1600 : log_fatal(errno, "Error creating '%s%s'. %s.\n", disk->dir, file->sub, strerror(errno));
1601 : log_tag("empty_%s:%u:%s:%s: Create error. %s.\n", es(errno), i, disk->name, esc_tag(file->sub, esc_buffer), strerror(errno));
@@ -1670,8 +1670,8 @@
1608 : }
1609 :
1610 : /* set the original modification time */
- 1611 159 : ret = fmtime(f, file->mtime_sec, file->mtime_nsec);
- 1612 159 : if (ret != 0) {
+ 1611 158 : ret = fmtime(f, file->mtime_sec, file->mtime_nsec);
+ 1612 158 : if (ret != 0) {
1613 : /* LCOV_EXCL_START */
1614 : log_fatal(errno, "Error timing '%s%s'. %s.\n", disk->dir, file->sub, strerror(errno));
1615 : log_tag("empty_%s:%u:%s:%s: Time error. %s.\n", es(errno), i, disk->name, esc_tag(file->sub, esc_buffer), strerror(errno));
@@ -1686,8 +1686,8 @@
1624 : }
1625 :
1626 : /* close it */
- 1627 159 : ret = close(f);
- 1628 159 : if (ret != 0) {
+ 1627 158 : ret = close(f);
+ 1628 158 : if (ret != 0) {
1629 : /* LCOV_EXCL_START */
1630 : log_fatal(errno, "Error closing '%s%s'. %s.\n", disk->dir, file->sub, strerror(errno));
1631 : log_tag("empty_%s:%u:%s:%s: Close error. %s.\n", es(errno), i, disk->name, esc_tag(file->sub, esc_buffer), strerror(errno));
@@ -1699,11 +1699,11 @@
1637 : /* LCOV_EXCL_STOP */
1638 : }
1639 :
- 1640 159 : log_tag("empty_fixed:%s:%s: Fixed empty file\n", disk->name, esc_tag(file->sub, esc_buffer));
- 1641 159 : ++recovered_error;
+ 1640 158 : log_tag("empty_fixed:%s:%s: Fixed empty file\n", disk->name, esc_tag(file->sub, esc_buffer));
+ 1641 158 : ++recovered_error;
1642 :
- 1643 159 : log_tag("status:recovered:%s:%s\n", disk->name, esc_tag(file->sub, esc_buffer));
- 1644 159 : msg_info("recovered %s\n", fmt_term(disk, file->sub, esc_buffer));
+ 1643 158 : log_tag("status:recovered:%s:%s\n", disk->name, esc_tag(file->sub, esc_buffer));
+ 1644 158 : msg_info("recovered %s\n", fmt_term(disk, file->sub, esc_buffer));
1645 : }
1646 : }
1647 :
@@ -1795,30 +1795,30 @@
1733 66426 : pathprint(path, sizeof(path), "%s%s", disk->dir, slink->sub);
1734 66426 : ret = readlink(path, linkto, sizeof(linkto));
1735 66426 : if (ret < 0) {
- 1736 4279 : unsuccessful = 1;
+ 1736 4293 : unsuccessful = 1;
1737 :
- 1738 4279 : log_error(errno, "Error reading symlink '%s'. %s.\n", path, strerror(errno));
- 1739 4279 : log_tag("symlink_%s:%s:%s: Symlink read error. %s.\n", es(errno), disk->name, esc_tag(slink->sub, esc_buffer), strerror(errno));
+ 1738 4293 : log_error(errno, "Error reading symlink '%s'. %s.\n", path, strerror(errno));
+ 1739 4293 : log_tag("symlink_%s:%s:%s: Symlink read error. %s.\n", es(errno), disk->name, esc_tag(slink->sub, esc_buffer), strerror(errno));
1740 :
- 1741 4279 : if (is_hw(errno)) {
+ 1741 4293 : if (is_hw(errno)) {
1742 0 : ++io_error;
1743 : } else {
- 1744 4279 : ++soft_error;
+ 1744 4293 : ++soft_error;
1745 : }
- 1746 62147 : } else if (ret >= PATH_MAX) {
+ 1746 62133 : } else if (ret >= PATH_MAX) {
1747 0 : unsuccessful = 1;
1748 :
1749 0 : log_error(ESOFT, "Error reading symlink '%s'. Symlink too long.\n", path);
1750 0 : log_tag("symlink_error:%s:%s: Symlink too long\n", disk->name, esc_tag(slink->sub, esc_buffer));
1751 0 : ++soft_error;
1752 : } else {
- 1753 62147 : linkto[ret] = 0;
+ 1753 62133 : linkto[ret] = 0;
1754 :
- 1755 62147 : if (strcmp(linkto, slink->linkto) != 0) {
- 1756 557 : unsuccessful = 1;
+ 1755 62133 : if (strcmp(linkto, slink->linkto) != 0) {
+ 1756 543 : unsuccessful = 1;
1757 :
- 1758 557 : 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);
- 1759 557 : ++soft_error;
+ 1758 543 : 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);
+ 1759 543 : ++soft_error;
1760 : }
1761 : }
1762 : }
@@ -2018,9 +2018,9 @@
1956 : }
1957 :
1958 : /* if processing was finished */
- 1959 113113 : if (file_flag_has(file, FILE_IS_FINISHED)) {
+ 1959 113069 : if (file_flag_has(file, FILE_IS_FINISHED)) {
1960 : /* nothing to do */
- 1961 113113 : continue;
+ 1961 113069 : continue;
1962 : }
1963 :
1964 : /* if the file was originally missing, and processing not yet finished */
diff --git a/cov/cmdline/device.c.func-sort-c.html b/cov/cmdline/device.c.func-sort-c.html
index 31512a0d..27cd899a 100644
--- a/cov/cmdline/device.c.func-sort-c.html
+++ b/cov/cmdline/device.c.func-sort-c.html
@@ -31,18 +31,18 @@
|
-
+
-
+
-
+
|
-
-
+
+
 |
@@ -59,29 +59,29 @@
Function Name  |
Hit count  |
-
- | smart_afr_value |
- 0 |
-
-
- | poisson_prob_at_least_one_failure |
- 1 |
-
| state_smart |
1 |
- | state_probe |
+ poisson_prob_at_least_one_failure |
2 |
+
+ | smart_afr_value |
+ 2 |
+
+
+ | state_probe |
+ 3 |
+
| state_stat |
- 4 |
+ 5 |
| state_device |
- 6 |
+ 7 |
| raid_prob_of_one_or_more_failures |
@@ -97,23 +97,23 @@
| smart_afr |
- 72568 |
+ 72582 |
| state_info_log |
- 72570 |
+ 72584 |
| state_smart_ignore |
- 72570 |
+ 72584 |
| state_smart_log |
- 72570 |
+ 72584 |
| device_name_set |
- 72635 |
+ 72647 |
diff --git a/cov/cmdline/device.c.func.html b/cov/cmdline/device.c.func.html
index 5a10b9c1..f8820d32 100644
--- a/cov/cmdline/device.c.func.html
+++ b/cov/cmdline/device.c.func.html
@@ -31,18 +31,18 @@
|
-
+
-
+
-
+
|
-
-
+
+
 |
@@ -61,7 +61,7 @@
| device_name_set |
- 72635 |
+ 72647 |
| devtest |
@@ -69,7 +69,7 @@
| poisson_prob_at_least_one_failure |
- 1 |
+ 2 |
| raid_prob_of_one_or_more_failures |
@@ -77,11 +77,11 @@
| smart_afr |
- 72568 |
+ 72582 |
| smart_afr_value |
- 0 |
+ 2 |
| state_attr |
@@ -89,15 +89,15 @@
| state_device |
- 6 |
+ 7 |
| state_info_log |
- 72570 |
+ 72584 |
| state_probe |
- 2 |
+ 3 |
| state_smart |
@@ -105,15 +105,15 @@
| state_smart_ignore |
- 72570 |
+ 72584 |
| state_smart_log |
- 72570 |
+ 72584 |
| state_stat |
- 4 |
+ 5 |
diff --git a/cov/cmdline/device.c.gcov.html b/cov/cmdline/device.c.gcov.html
index 0ebe20f8..39031fe8 100644
--- a/cov/cmdline/device.c.gcov.html
+++ b/cov/cmdline/device.c.gcov.html
@@ -31,18 +31,18 @@
|
-
+
-
+
-
+
|
-
-
+
+
 |
@@ -83,13 +83,13 @@
21 : #include "state.h"
22 : #include "raid/raid.h"
23 :
- 24 72635 : void device_name_set(devinfo_t* dev, const char* name, int index)
+ 24 72647 : void device_name_set(devinfo_t* dev, const char* name, int index)
25 : {
- 26 72635 : if (index == 0)
- 27 29054 : pathcpy(dev->name, sizeof(dev->name), name);
+ 26 72647 : if (index == 0)
+ 27 29066 : pathcpy(dev->name, sizeof(dev->name), name);
28 : else
29 43581 : pathprint(dev->name, sizeof(dev->name), "%s/%d", name, index);
- 30 72635 : }
+ 30 72647 : }
31 :
32 : /**
33 : * The following are Failure Rate tables computed from the data that
@@ -442,15 +442,15 @@
380 : /**
381 : * Computes the estimated Annual Failure Rate from the specified table.
382 : */
- 383 0 : static double smart_afr_value(double* tab, unsigned step, uint64_t value)
+ 383 2 : static double smart_afr_value(double* tab, unsigned step, uint64_t value)
384 : {
- 385 0 : value /= step;
+ 385 2 : value /= step;
386 :
- 387 0 : if (value >= SMART_MEASURES)
+ 387 2 : if (value >= SMART_MEASURES)
388 0 : value = SMART_MEASURES - 1;
389 :
390 : /* table rates are for a month, so we scale to a year */
- 391 0 : return 365.0 / 30.0 * tab[value];
+ 391 2 : return 365.0 / 30.0 * tab[value];
392 : }
393 :
394 : /**
@@ -470,31 +470,31 @@
408 : * we use the maximum rate reported, and we do not sum them,
409 : * because the attributes are not independent.
410 : */
- 411 72568 : static double smart_afr(struct smart_attr* smart, const char* model)
+ 411 72582 : static double smart_afr(struct smart_attr* smart, const char* model)
412 : {
- 413 72568 : double afr = 0;
- 414 72568 : uint64_t mask32 = 0xffffffffU;
- 415 72568 : uint64_t mask16 = 0xffffU;
+ 413 72582 : double afr = 0;
+ 414 72582 : uint64_t mask32 = 0xffffffffU;
+ 415 72582 : uint64_t mask16 = 0xffffU;
416 :
417 : /* do not estimate for not rotational */
- 418 72568 : if (smart[INFO_ROTATION_RATE].raw == 0)
- 419 70149 : return 0;
+ 418 72582 : if (smart[INFO_ROTATION_RATE].raw == 0)
+ 419 70150 : return 0;
420 :
- 421 2419 : if (smart[5].raw != SMART_UNASSIGNED) {
- 422 0 : double r = smart_afr_value(SMART_5_R, SMART_5_STEP, smart[5].raw & mask32);
- 423 0 : if (afr < r)
- 424 0 : afr = r;
+ 421 2432 : if (smart[5].raw != SMART_UNASSIGNED) {
+ 422 1 : double r = smart_afr_value(SMART_5_R, SMART_5_STEP, smart[5].raw & mask32);
+ 423 1 : if (afr < r)
+ 424 1 : afr = r;
425 : }
426 :
- 427 2419 : if (smart[187].raw != SMART_UNASSIGNED) {
+ 427 2432 : if (smart[187].raw != SMART_UNASSIGNED) {
428 : /* with some disks, only the lower 16 bits are significant */
429 : /* See: http://web.archive.org/web/20130507072056/http://media.kingston.com/support/downloads/MKP_306_SMART_attribute.pdf */
- 430 0 : double r = smart_afr_value(SMART_187_R, SMART_187_STEP, smart[187].raw & mask16);
- 431 0 : if (afr < r)
- 432 0 : afr = r;
+ 430 1 : double r = smart_afr_value(SMART_187_R, SMART_187_STEP, smart[187].raw & mask16);
+ 431 1 : if (afr < r)
+ 432 1 : afr = r;
433 : }
434 :
- 435 2419 : if (
+ 435 2432 : if (
436 : /**
437 : * Don't check Command_Timeout (188) for Seagate disks.
438 : *
@@ -502,7 +502,7 @@
440 : * and IronWolf disks to be a not significant test as
441 : * this value increases too often also on sane disks.
442 : */
- 443 2419 : strncmp(model, "ST", 2) != 0 && smart[188].raw != SMART_UNASSIGNED
+ 443 2432 : strncmp(model, "ST", 2) != 0 && smart[188].raw != SMART_UNASSIGNED
444 : ) {
445 : /* with Seagate disks, there are three different 16 bits value reported */
446 : /* the lowest one is the most significant */
@@ -511,19 +511,19 @@
449 0 : afr = r;
450 : }
451 :
- 452 2419 : if (smart[197].raw != SMART_UNASSIGNED) {
+ 452 2432 : if (smart[197].raw != SMART_UNASSIGNED) {
453 0 : double r = smart_afr_value(SMART_197_R, SMART_197_STEP, smart[197].raw & mask32);
454 0 : if (afr < r)
455 0 : afr = r;
456 : }
457 :
- 458 2419 : if (smart[198].raw != SMART_UNASSIGNED) {
+ 458 2432 : if (smart[198].raw != SMART_UNASSIGNED) {
459 0 : double r = smart_afr_value(SMART_198_R, SMART_198_STEP, smart[198].raw & mask32);
460 0 : if (afr < r)
461 0 : afr = r;
462 : }
463 :
- 464 2419 : return afr;
+ 464 2432 : return afr;
465 : }
466 :
467 : /**
@@ -533,9 +533,9 @@
471 : * @param afr The aggregate Annual Failure Rate (lambda).
472 : * @return The probability as a double between 0 and 1.
473 : */
- 474 1 : static double poisson_prob_at_least_one_failure(double rate)
+ 474 2 : static double poisson_prob_at_least_one_failure(double rate)
475 : {
- 476 1 : return 1.0 - exp(-rate);
+ 476 2 : return 1.0 - exp(-rate);
477 : }
478 :
479 : /**
@@ -582,81 +582,81 @@
520 0 : return poisson_prob_at_least_one_failure(raid_failure_rate);
521 : }
522 :
- 523 72570 : static void state_info_log(devinfo_t* devinfo)
+ 523 72584 : static void state_info_log(devinfo_t* devinfo)
524 : {
525 : char esc_buffer[ESC_MAX];
526 :
- 527 72570 : log_tag("info:%s:%s\n", devinfo->file, devinfo->name);
- 528 72570 : if (devinfo->serial[0])
- 529 72570 : log_tag("attr:%s:%s:serial:%s\n", devinfo->file, devinfo->name, esc_tag(devinfo->serial, esc_buffer));
- 530 72570 : if (devinfo->family[0])
- 531 72570 : log_tag("attr:%s:%s:family:%s\n", devinfo->file, devinfo->name, esc_tag(devinfo->family, esc_buffer));
- 532 72570 : if (devinfo->model[0])
- 533 72570 : log_tag("attr:%s:%s:model:%s\n", devinfo->file, devinfo->name, esc_tag(devinfo->model, esc_buffer));
- 534 72570 : if (devinfo->interf[0])
- 535 72570 : log_tag("attr:%s:%s:interface:%s\n", devinfo->file, devinfo->name, esc_tag(devinfo->interf, esc_buffer));
- 536 72570 : if (devinfo->info[INFO_SIZE] != SMART_UNASSIGNED)
- 537 72570 : log_tag("attr:%s:%s:size:%" PRIu64 "\n", devinfo->file, devinfo->name, devinfo->info[INFO_SIZE]);
- 538 72570 : if (devinfo->info[INFO_ROTATION_RATE] != SMART_UNASSIGNED)
- 539 72570 : log_tag("attr:%s:%s:rotationrate:%" PRIu64 "\n", devinfo->file, devinfo->name, devinfo->info[INFO_ROTATION_RATE]);
- 540 72570 : }
+ 527 72584 : log_tag("info:%s:%s\n", devinfo->file, devinfo->name);
+ 528 72584 : if (devinfo->serial[0])
+ 529 72584 : log_tag("attr:%s:%s:serial:%s\n", devinfo->file, devinfo->name, esc_tag(devinfo->serial, esc_buffer));
+ 530 72584 : if (devinfo->family[0])
+ 531 72572 : log_tag("attr:%s:%s:family:%s\n", devinfo->file, devinfo->name, esc_tag(devinfo->family, esc_buffer));
+ 532 72584 : if (devinfo->model[0])
+ 533 72584 : log_tag("attr:%s:%s:model:%s\n", devinfo->file, devinfo->name, esc_tag(devinfo->model, esc_buffer));
+ 534 72584 : if (devinfo->interf[0])
+ 535 72572 : log_tag("attr:%s:%s:interface:%s\n", devinfo->file, devinfo->name, esc_tag(devinfo->interf, esc_buffer));
+ 536 72584 : if (devinfo->info[INFO_SIZE] != SMART_UNASSIGNED)
+ 537 72584 : log_tag("attr:%s:%s:size:%" PRIu64 "\n", devinfo->file, devinfo->name, devinfo->info[INFO_SIZE]);
+ 538 72584 : if (devinfo->info[INFO_ROTATION_RATE] != SMART_UNASSIGNED)
+ 539 72584 : log_tag("attr:%s:%s:rotationrate:%" PRIu64 "\n", devinfo->file, devinfo->name, devinfo->info[INFO_ROTATION_RATE]);
+ 540 72584 : }
541 :
- 542 72570 : static void state_smart_ignore(struct snapraid_state* state, devinfo_t* devinfo)
+ 542 72584 : static void state_smart_ignore(struct snapraid_state* state, devinfo_t* devinfo)
543 : {
544 : /* clear attributes to ignore */
- 545 362850 : for (int i = 0; i < SMART_IGNORE_MAX; ++i) {
- 546 290280 : devinfo->smart[state->smartignore[i]].raw = SMART_UNASSIGNED;
- 547 290280 : devinfo->smart[devinfo->smartignore[i]].raw = SMART_UNASSIGNED;
+ 545 362920 : for (int i = 0; i < SMART_IGNORE_MAX; ++i) {
+ 546 290336 : devinfo->smart[state->smartignore[i]].raw = SMART_UNASSIGNED;
+ 547 290336 : devinfo->smart[devinfo->smartignore[i]].raw = SMART_UNASSIGNED;
548 : }
- 549 72570 : }
+ 549 72584 : }
550 :
- 551 72570 : static void state_smart_log(devinfo_t* devinfo, double afr)
+ 551 72584 : static void state_smart_log(devinfo_t* devinfo, double afr)
552 : {
553 : unsigned j;
554 :
- 555 72570 : log_tag("smart:%s:%s\n", devinfo->file, devinfo->name);
- 556 72570 : if (devinfo->smart[SMART_ERROR_PROTOCOL].raw != SMART_UNASSIGNED)
- 557 72570 : log_tag("attr:%s:%s:error_protocol:%" PRIu64 "\n", devinfo->file, devinfo->name, devinfo->smart[SMART_ERROR_PROTOCOL].raw);
- 558 72570 : if (devinfo->smart[SMART_ERROR_MEDIUM].raw != SMART_UNASSIGNED)
+ 555 72584 : log_tag("smart:%s:%s\n", devinfo->file, devinfo->name);
+ 556 72584 : if (devinfo->smart[SMART_ERROR_PROTOCOL].raw != SMART_UNASSIGNED)
+ 557 72572 : log_tag("attr:%s:%s:error_protocol:%" PRIu64 "\n", devinfo->file, devinfo->name, devinfo->smart[SMART_ERROR_PROTOCOL].raw);
+ 558 72584 : if (devinfo->smart[SMART_ERROR_MEDIUM].raw != SMART_UNASSIGNED)
559 72570 : log_tag("attr:%s:%s:error_medium:%" PRIu64 "\n", devinfo->file, devinfo->name, devinfo->smart[SMART_ERROR_MEDIUM].raw);
- 560 72570 : if (devinfo->smart[SMART_WEAR_LEVEL].raw != SMART_UNASSIGNED)
- 561 72570 : log_tag("attr:%s:%s:wear_level:%" PRIu64 "\n", devinfo->file, devinfo->name, devinfo->smart[SMART_WEAR_LEVEL].raw);
- 562 72570 : if (devinfo->smart[SMART_FLAGS].raw != SMART_UNASSIGNED)
- 563 19352 : log_tag("attr:%s:%s:flags:%" PRIu64 ":%" PRIx64 "\n", devinfo->file, devinfo->name, devinfo->smart[SMART_FLAGS].raw, devinfo->smart[SMART_FLAGS].raw);
+ 560 72584 : if (devinfo->smart[SMART_WEAR_LEVEL].raw != SMART_UNASSIGNED)
+ 561 72571 : log_tag("attr:%s:%s:wear_level:%" PRIu64 "\n", devinfo->file, devinfo->name, devinfo->smart[SMART_WEAR_LEVEL].raw);
+ 562 72584 : if (devinfo->smart[SMART_FLAGS].raw != SMART_UNASSIGNED)
+ 563 19354 : log_tag("attr:%s:%s:flags:%" PRIu64 ":%" PRIx64 "\n", devinfo->file, devinfo->name, devinfo->smart[SMART_FLAGS].raw, devinfo->smart[SMART_FLAGS].raw);
564 :
- 565 72570 : if (afr != 0)
- 566 0 : log_tag("attr:%s:%s:afr:%g:%g\n", devinfo->file, devinfo->name, afr, poisson_prob_at_least_one_failure(afr));
+ 565 72584 : if (afr != 0)
+ 566 1 : log_tag("attr:%s:%s:afr:%g:%g\n", devinfo->file, devinfo->name, afr, poisson_prob_at_least_one_failure(afr));
567 :
- 568 18650490 : for (j = 0; j < 256; ++j) {
- 569 18577920 : struct smart_attr* attr = &devinfo->smart[j];
- 570 18577920 : if (attr->raw != SMART_UNASSIGNED) {
- 571 17890837 : const char* type = "";;
- 572 17890837 : const char* updated = "";
- 573 17890837 : const char* when_failed = "";
+ 568 18654088 : for (j = 0; j < 256; ++j) {
+ 569 18581504 : struct smart_attr* attr = &devinfo->smart[j];
+ 570 18581504 : if (attr->raw != SMART_UNASSIGNED) {
+ 571 17890868 : const char* type = "";;
+ 572 17890868 : const char* updated = "";
+ 573 17890868 : const char* when_failed = "";
574 :
- 575 17890837 : if (attr->flags & SMART_ATTR_TYPE_PREFAIL)
- 576 0 : type = "prefail";
- 577 17890837 : else if (attr->flags & SMART_ATTR_TYPE_OLDAGE)
- 578 0 : type = "oldage";
- 579 17890837 : if (attr->flags & SMART_ATTR_UPDATE_ALWAYS)
- 580 0 : updated = "always";
- 581 17890837 : else if (attr->flags & SMART_ATTR_UPDATE_OFFLINE)
- 582 0 : updated = "offline";
- 583 17890837 : if (attr->flags & SMART_ATTR_WHEN_FAILED_NOW)
+ 575 17890868 : if (attr->flags & SMART_ATTR_TYPE_PREFAIL)
+ 576 11 : type = "prefail";
+ 577 17890857 : else if (attr->flags & SMART_ATTR_TYPE_OLDAGE)
+ 578 20 : type = "oldage";
+ 579 17890868 : if (attr->flags & SMART_ATTR_UPDATE_ALWAYS)
+ 580 28 : updated = "always";
+ 581 17890840 : else if (attr->flags & SMART_ATTR_UPDATE_OFFLINE)
+ 582 3 : updated = "offline";
+ 583 17890868 : if (attr->flags & SMART_ATTR_WHEN_FAILED_NOW)
584 0 : when_failed = "now";
- 585 17890837 : else if (attr->flags & SMART_ATTR_WHEN_FAILED_PAST)
+ 585 17890868 : else if (attr->flags & SMART_ATTR_WHEN_FAILED_PAST)
586 0 : when_failed = "past";
- 587 17890837 : else if (attr->flags & SMART_ATTR_WHEN_FAILED_NEVER)
- 588 0 : when_failed = "never";
+ 587 17890868 : else if (attr->flags & SMART_ATTR_WHEN_FAILED_NEVER)
+ 588 31 : when_failed = "never";
589 :
- 590 17890837 : log_tag("attr:%s:%s:%u:%" PRIu64 ":%" PRIx64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%s:%s:%s:%s\n", devinfo->file, devinfo->name, j, attr->raw, attr->raw, attr->norm, attr->worst, attr->thresh, attr->name, type, updated, when_failed);
+ 590 17890868 : log_tag("attr:%s:%s:%u:%" PRIu64 ":%" PRIx64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%s:%s:%s:%s\n", devinfo->file, devinfo->name, j, attr->raw, attr->raw, attr->norm, attr->worst, attr->thresh, attr->name, type, updated, when_failed);
591 : }
592 : }
593 :
- 594 72570 : int temp = smart_temp(devinfo);
- 595 72570 : if (temp >= 0)
- 596 72570 : log_tag("attr:%s:%s:temperature:%d\n", devinfo->file, devinfo->name, temp);
- 597 72570 : }
+ 594 72584 : int temp = smart_temp(devinfo);
+ 595 72584 : if (temp >= 0)
+ 596 72572 : log_tag("attr:%s:%s:temperature:%d\n", devinfo->file, devinfo->name, temp);
+ 597 72584 : }
598 :
599 1 : static void state_smart(struct snapraid_state* state, unsigned n, tommy_list* low)
600 : {
@@ -894,7 +894,7 @@
832 : }
833 2416 : }
834 :
- 835 2 : static void state_probe(struct snapraid_state* state, tommy_list* low)
+ 835 3 : static void state_probe(struct snapraid_state* state, tommy_list* low)
836 : {
837 : tommy_node* i;
838 : size_t device_pad;
@@ -902,80 +902,80 @@
840 : (void)state;
841 :
842 : /* compute lengths for padding */
- 843 2 : device_pad = 0;
- 844 62 : for (i = tommy_list_head(low); i != 0; i = i->next) {
+ 843 3 : device_pad = 0;
+ 844 77 : for (i = tommy_list_head(low); i != 0; i = i->next) {
845 : size_t len;
- 846 60 : devinfo_t* devinfo = i->data;
+ 846 74 : devinfo_t* devinfo = i->data;
847 :
- 848 60 : state_smart_ignore(state, devinfo);
+ 848 74 : state_smart_ignore(state, devinfo);
849 :
- 850 60 : len = strlen(devinfo->file);
- 851 60 : if (len > device_pad)
- 852 2 : device_pad = len;
+ 850 74 : len = strlen(devinfo->file);
+ 851 74 : if (len > device_pad)
+ 852 3 : device_pad = len;
853 :
- 854 60 : double afr = smart_afr(devinfo->smart, devinfo->model);
+ 854 74 : double afr = smart_afr(devinfo->smart, devinfo->model);
855 :
- 856 60 : state_info_log(devinfo);
- 857 60 : state_smart_log(devinfo, afr);
+ 856 74 : state_info_log(devinfo);
+ 857 74 : state_smart_log(devinfo, afr);
858 : }
859 :
- 860 2 : printf("SnapRAID PROBE report:\n");
- 861 2 : printf("\n");
- 862 2 : printf(" State ");
- 863 2 : printf(" ");
- 864 2 : printl("Device", device_pad);
- 865 2 : printf(" Disk");
- 866 2 : printf("\n");
+ 860 3 : printf("SnapRAID PROBE report:\n");
+ 861 3 : printf("\n");
+ 862 3 : printf(" State ");
+ 863 3 : printf(" ");
+ 864 3 : printl("Device", device_pad);
+ 865 3 : printf(" Disk");
+ 866 3 : printf("\n");
867 : /* |<##################################################################72>|####80>| */
- 868 2 : printf(" -----------------------------------------------------------------------\n");
+ 868 3 : printf(" -----------------------------------------------------------------------\n");
869 :
- 870 62 : for (i = tommy_list_head(low); i != 0; i = i->next) {
- 871 60 : devinfo_t* devinfo = i->data;
+ 870 77 : for (i = tommy_list_head(low); i != 0; i = i->next) {
+ 871 74 : devinfo_t* devinfo = i->data;
872 :
- 873 60 : printf(" ");
+ 873 74 : printf(" ");
874 :
- 875 60 : switch (devinfo->power) {
- 876 0 : case POWER_STANDBY : printf("StandBy"); break;
- 877 60 : case POWER_ACTIVE : printf(" Active"); break;
+ 875 74 : switch (devinfo->power) {
+ 876 12 : case POWER_STANDBY : printf("StandBy"); break;
+ 877 62 : case POWER_ACTIVE : printf(" Active"); break;
878 0 : default : printf("Unknown"); break;
879 : }
880 :
- 881 60 : printf(" ");
- 882 60 : if (*devinfo->file)
- 883 60 : printl(devinfo->file, device_pad);
+ 881 74 : printf(" ");
+ 882 74 : if (*devinfo->file)
+ 883 74 : printl(devinfo->file, device_pad);
884 : else
885 0 : printl("-", device_pad);
886 :
- 887 60 : printf(" ");
- 888 60 : if (*devinfo->name)
- 889 60 : printf("%s", devinfo->name);
+ 887 74 : printf(" ");
+ 888 74 : if (*devinfo->name)
+ 889 72 : printf("%s", devinfo->name);
890 : else
- 891 0 : printf("-");
+ 891 2 : printf("-");
892 :
- 893 60 : printf("\n");
+ 893 74 : printf("\n");
894 :
- 895 60 : log_tag("probe:%s:%s:%d\n", devinfo->file, devinfo->name, devinfo->power);
+ 895 74 : log_tag("probe:%s:%s:%d\n", devinfo->file, devinfo->name, devinfo->power);
896 : }
897 :
- 898 2 : printf("\n");
- 899 2 : }
+ 898 3 : printf("\n");
+ 899 3 : }
900 :
- 901 4 : static void state_stat(struct snapraid_state* state, tommy_list* high)
+ 901 5 : static void state_stat(struct snapraid_state* state, tommy_list* high)
902 : {
903 : tommy_node* i;
904 :
905 : (void)state;
906 :
907 : /* compute lengths for padding */
- 908 124 : for (i = tommy_list_head(high); i != 0; i = i->next) {
- 909 120 : devinfo_t* devinfo = i->data;
+ 908 137 : for (i = tommy_list_head(high); i != 0; i = i->next) {
+ 909 132 : devinfo_t* devinfo = i->data;
910 :
911 : /* print disk access_stat (not split) */
- 912 120 : if (devinfo->split == 0 && devinfo->access_stat != 0) {
- 913 12 : log_tag("stat:%s:%" PRIu64 "\n", devinfo->name, devinfo->access_stat);
+ 912 132 : if (devinfo->split == 0 && devinfo->access_stat != 0) {
+ 913 24 : log_tag("stat:%s:%" PRIu64 "\n", devinfo->name, devinfo->access_stat);
914 : }
915 : }
- 916 4 : }
+ 916 5 : }
917 :
918 2419 : int devtest(tommy_list* high, tommy_list* low, int operation)
919 : {
@@ -1046,88 +1046,88 @@
984 2419 : return 0;
985 : }
986 :
- 987 6 : void state_device(struct snapraid_state* state, int operation, tommy_list* filterlist_disk)
+ 987 7 : void state_device(struct snapraid_state* state, int operation, tommy_list* filterlist_disk)
988 : {
989 : tommy_node* i;
990 : unsigned j;
991 : tommy_list high;
992 : tommy_list low;
993 : int ret;
- 994 6 : time_t now = time(0);
+ 994 7 : time_t now = time(0);
995 :
- 996 6 : switch (operation) {
+ 996 7 : switch (operation) {
997 1 : case DEVICE_UP : msg_progress("Spinup...\n"); break;
998 1 : case DEVICE_DOWN : msg_progress("Spindown...\n"); break;
999 : }
1000 :
- 1001 6 : tommy_list_init(&high);
- 1002 6 : tommy_list_init(&low);
+ 1001 7 : tommy_list_init(&high);
+ 1002 7 : tommy_list_init(&low);
1003 :
1004 : /* for all disks */
- 1005 42 : for (i = state->disklist; i != 0; i = i->next) {
- 1006 36 : struct snapraid_disk* disk = i->data;
+ 1005 53 : for (i = state->disklist; i != 0; i = i->next) {
+ 1006 46 : struct snapraid_disk* disk = i->data;
1007 : devinfo_t* entry;
1008 :
- 1009 36 : if (filterlist_disk != 0 && filter_path(filterlist_disk, 0, disk->name, 0) != 0)
+ 1009 46 : if (filterlist_disk != 0 && filter_path(filterlist_disk, 0, disk->name, 0) != 0)
1010 5 : continue;
1011 :
- 1012 31 : entry = calloc_nofail(1, sizeof(devinfo_t));
+ 1012 41 : entry = calloc_nofail(1, sizeof(devinfo_t));
1013 :
- 1014 31 : entry->device = disk->device;
- 1015 31 : device_name_set(entry, disk->name, 0);
- 1016 31 : pathcpy(entry->mount, sizeof(entry->mount), disk->dir);
- 1017 31 : pathcpy(entry->smartctl, sizeof(entry->smartctl), disk->smartctl);
- 1018 31 : memcpy(entry->smartignore, disk->smartignore, sizeof(entry->smartignore));
+ 1014 41 : entry->device = disk->device;
+ 1015 41 : device_name_set(entry, disk->name, 0);
+ 1016 41 : pathcpy(entry->mount, sizeof(entry->mount), disk->dir);
+ 1017 41 : pathcpy(entry->smartctl, sizeof(entry->smartctl), disk->smartctl);
+ 1018 41 : memcpy(entry->smartignore, disk->smartignore, sizeof(entry->smartignore));
1019 :
- 1020 31 : tommy_list_insert_tail(&high, &entry->node, entry);
+ 1020 41 : tommy_list_insert_tail(&high, &entry->node, entry);
1021 : }
1022 :
1023 : /* for all parities */
- 1024 42 : for (j = 0; j < state->level; ++j) {
+ 1024 45 : for (j = 0; j < state->level; ++j) {
1025 : devinfo_t* entry;
1026 : devinfo_t* split;
1027 : unsigned s;
1028 :
- 1029 36 : if (filterlist_disk != 0 && filter_path(filterlist_disk, 0, lev_config_name(j), 0) != 0)
+ 1029 38 : if (filterlist_disk != 0 && filter_path(filterlist_disk, 0, lev_config_name(j), 0) != 0)
1030 5 : continue;
1031 :
- 1032 155 : for (s = 0; s < state->parity[j].split_mac; ++s) {
- 1033 124 : entry = calloc_nofail(1, sizeof(devinfo_t));
+ 1032 159 : for (s = 0; s < state->parity[j].split_mac; ++s) {
+ 1033 126 : entry = calloc_nofail(1, sizeof(devinfo_t));
1034 :
1035 : /* keep track of the first split */
- 1036 124 : if (s == 0)
- 1037 31 : split = entry;
+ 1036 126 : if (s == 0)
+ 1037 33 : split = entry;
1038 : else
1039 93 : entry->split = split;
1040 :
- 1041 124 : entry->device = state->parity[j].split_map[s].device;
- 1042 124 : device_name_set(entry, lev_config_name(j), s);
- 1043 124 : pathcpy(entry->mount, sizeof(entry->mount), state->parity[j].split_map[s].path);
- 1044 124 : pathcpy(entry->smartctl, sizeof(entry->smartctl), state->parity[j].smartctl);
- 1045 124 : memcpy(entry->smartignore, state->parity[j].smartignore, sizeof(entry->smartignore));
- 1046 124 : pathcut(entry->mount); /* remove the parity file */
+ 1041 126 : entry->device = state->parity[j].split_map[s].device;
+ 1042 126 : device_name_set(entry, lev_config_name(j), s);
+ 1043 126 : pathcpy(entry->mount, sizeof(entry->mount), state->parity[j].split_map[s].path);
+ 1044 126 : pathcpy(entry->smartctl, sizeof(entry->smartctl), state->parity[j].smartctl);
+ 1045 126 : memcpy(entry->smartignore, state->parity[j].smartignore, sizeof(entry->smartignore));
+ 1046 126 : pathcut(entry->mount); /* remove the parity file */
1047 :
- 1048 124 : tommy_list_insert_tail(&high, &entry->node, entry);
+ 1048 126 : tommy_list_insert_tail(&high, &entry->node, entry);
1049 : }
1050 : }
1051 :
1052 : /* with a GUI always gives time reference */
- 1053 6 : if (state->opt.gui)
+ 1053 7 : if (state->opt.gui)
1054 3 : log_tag("unixtime:%" PRIi64 "\n", (int64_t)now);
1055 :
- 1056 6 : if (state->opt.fake_device) {
+ 1056 7 : if (state->opt.fake_device) {
1057 3 : ret = devtest(&high, &low, operation);
1058 : } else {
- 1059 3 : int others = operation == DEVICE_SMART || operation == DEVICE_PROBE;
+ 1059 4 : int others = operation == DEVICE_SMART || operation == DEVICE_PROBE;
1060 :
- 1061 3 : ret = devquery(&high, &low, operation, others);
+ 1061 4 : ret = devquery(&high, &low, operation, others);
1062 : }
1063 :
1064 : /* if the list is empty, it's not supported in this platform */
- 1065 6 : if (ret == 0 && tommy_list_empty(&low))
+ 1065 7 : if (ret == 0 && tommy_list_empty(&low))
1066 0 : ret = -1;
1067 :
- 1068 6 : if (ret != 0) {
+ 1068 7 : if (ret != 0) {
1069 2 : const char* ope = 0;
1070 2 : switch (operation) {
1071 1 : case DEVICE_UP : ope = "Spinup"; break;
@@ -1139,7 +1139,7 @@
1077 : }
1078 2 : log_fatal(ESOFT, "%s is unsupported in this platform.\n", ope);
1079 : } else {
- 1080 4 : if (operation == DEVICE_LIST) {
+ 1080 5 : if (operation == DEVICE_LIST) {
1081 31 : for (i = tommy_list_head(&low); i != 0; i = i->next) {
1082 30 : devinfo_t* devinfo = i->data;
1083 30 : devinfo_t* parent = devinfo->parent;
@@ -1151,21 +1151,21 @@
1089 : }
1090 : }
1091 :
- 1092 4 : state_stat(state, &high);
+ 1092 5 : state_stat(state, &high);
1093 :
- 1094 4 : if (operation == DEVICE_SMART)
+ 1094 5 : if (operation == DEVICE_SMART)
1095 1 : state_smart(state, state->level + tommy_list_count(&state->disklist), &low);
1096 :
- 1097 3 : if (operation == DEVICE_PROBE)
- 1098 2 : state_probe(state, &low);
+ 1097 4 : if (operation == DEVICE_PROBE)
+ 1098 3 : state_probe(state, &low);
1099 :
- 1100 3 : if (operation == DEVICE_UP)
+ 1100 4 : if (operation == DEVICE_UP)
1101 0 : state_attr(state, &low);
1102 : }
1103 :
- 1104 5 : tommy_list_foreach(&high, free);
- 1105 5 : tommy_list_foreach(&low, free);
- 1106 5 : }
+ 1104 6 : tommy_list_foreach(&high, free);
+ 1105 6 : tommy_list_foreach(&low, free);
+ 1106 6 : }
1107 :
diff --git a/cov/cmdline/dry.c.func-sort-c.html b/cov/cmdline/dry.c.func-sort-c.html
index f252ce7a..569846cb 100644
--- a/cov/cmdline/dry.c.func-sort-c.html
+++ b/cov/cmdline/dry.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/cmdline/dry.c.func.html b/cov/cmdline/dry.c.func.html
index 8bc46275..887c3efb 100644
--- a/cov/cmdline/dry.c.func.html
+++ b/cov/cmdline/dry.c.func.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/cmdline/dry.c.gcov.html b/cov/cmdline/dry.c.gcov.html
index dfe1cb38..36dad312 100644
--- a/cov/cmdline/dry.c.gcov.html
+++ b/cov/cmdline/dry.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/cmdline/dup.c.func-sort-c.html b/cov/cmdline/dup.c.func-sort-c.html
index 1f553993..39fa51cc 100644
--- a/cov/cmdline/dup.c.func-sort-c.html
+++ b/cov/cmdline/dup.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -65,7 +65,7 @@
| hash_compare |
- 20 |
+ 18 |
| hash_alloc |
diff --git a/cov/cmdline/dup.c.func.html b/cov/cmdline/dup.c.func.html
index 8b81da74..c3ab35fb 100644
--- a/cov/cmdline/dup.c.func.html
+++ b/cov/cmdline/dup.c.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -65,7 +65,7 @@
| hash_compare |
- 20 |
+ 18 |
| hash_free |
diff --git a/cov/cmdline/dup.c.gcov.html b/cov/cmdline/dup.c.gcov.html
index fb238dff..259212b4 100644
--- a/cov/cmdline/dup.c.gcov.html
+++ b/cov/cmdline/dup.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -141,12 +141,12 @@
79 16976 : free(hash);
80 16976 : }
81 :
- 82 20 : int hash_compare(const void* void_arg, const void* void_data)
+ 82 18 : int hash_compare(const void* void_arg, const void* void_data)
83 : {
- 84 20 : const char* arg = void_arg;
- 85 20 : const struct snapraid_hash* hash = void_data;
+ 84 18 : const char* arg = void_arg;
+ 85 18 : const struct snapraid_hash* hash = void_data;
86 :
- 87 20 : return memcmp(arg, hash->hash, HASH_MAX);
+ 87 18 : return memcmp(arg, hash->hash, HASH_MAX);
88 : }
89 :
90 3 : void state_dup(struct snapraid_state* state)
diff --git a/cov/cmdline/elem.c.func-sort-c.html b/cov/cmdline/elem.c.func-sort-c.html
index 42d47b7e..67a5f3de 100644
--- a/cov/cmdline/elem.c.func-sort-c.html
+++ b/cov/cmdline/elem.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -97,23 +97,23 @@
| bucket_to_list |
- 421 |
-
-
- | filter_free |
- 547 |
-
-
- | filter_alloc_file |
- 559 |
+ 420 |
| bucket_cmp |
- 711 |
+ 521 |
+
+
+ | filter_free |
+ 552 |
+
+
+ | filter_alloc_file |
+ 564 |
| bucket_free |
- 746 |
+ 705 |
| dir_free |
@@ -125,23 +125,23 @@
| fs_is_empty |
- 942 |
+ 936 |
| content_free |
- 1551 |
+ 1555 |
| map_free |
1573 |
- | disk_free |
- 1603 |
+ content_alloc |
+ 1610 |
- | content_alloc |
- 1606 |
+ disk_free |
+ 1613 |
| map_alloc |
@@ -149,11 +149,11 @@
| disk_alloc |
- 1663 |
+ 1673 |
| fs_check |
- 3120 |
+ 3114 |
| link_alpha_compare |
@@ -165,7 +165,7 @@
| fs_size |
- 4549 |
+ 4543 |
| file_dup |
@@ -177,15 +177,15 @@
| file_stamp_compare |
- 23671 |
+ 23670 |
| file_name_compare |
- 23856 |
+ 23865 |
| file_namestamp_compare |
- 23856 |
+ 23865 |
| link_name_compare_to_arg |
@@ -197,31 +197,31 @@
| file_name |
- 47712 |
+ 47730 |
| extent_disk_size_compare_unlock |
- 52890 |
+ 52796 |
| bucket_insert |
- 72052 |
+ 55958 |
| filter_existence |
77701 |
- | file_path_compare_to_arg |
- 97862 |
+ file_physical_compare |
+ 96760 |
- | file_physical_compare |
- 99756 |
+ file_path_compare_to_arg |
+ 97805 |
| fs_deallocate |
- 102986 |
+ 102931 |
| link_free |
@@ -233,47 +233,47 @@
| filter_type |
- 125231 |
+ 125314 |
| file_path_compare |
- 187689 |
+ 187677 |
| fmt_term |
- 366067 |
+ 366236 |
| file_inode_compare_to_arg |
- 1043743 |
+ 1046316 |
| filter_content |
- 3231524 |
+ 3231650 |
| file_free |
- 3784741 |
+ 3784728 |
| extent_free |
- 3806435 |
+ 3806358 |
| file_alloc |
- 3807696 |
+ 3807720 |
| extent_alloc |
- 3852016 |
+ 3851976 |
| filter_path |
- 4587023 |
+ 4587158 |
| filter_element |
- 4591561 |
+ 4591696 |
| file_block_is_last |
@@ -281,71 +281,71 @@
| fs_file2par_find |
- 5301463 |
+ 5260119 |
| filter_apply |
- 6355925 |
+ 6356195 |
| file_block_size |
- 6817779 |
+ 6817866 |
| extent_file_check_foreach_unlock |
- 6837675 |
+ 6820724 |
| extent_parity_check_foreach_unlock |
- 6837675 |
+ 6820724 |
| fs_allocate |
- 9473576 |
+ 9473620 |
| fs_file2extent_get_unlock |
- 10949888 |
+ 10908566 |
| extent_file_inside_compare_unlock |
- 22976989 |
+ 22802303 |
| fs_par2block_find |
- 38360216 |
+ 38266700 |
| extent_parity_compare |
- 45768745 |
+ 45767042 |
| extent_file_compare |
- 46158505 |
+ 46157545 |
| fs_par2file_find |
- 49865865 |
+ 49771977 |
| fs_par2extent_get_unlock |
- 49968851 |
+ 49874908 |
| fs_file2block_get |
- 56447214 |
+ 56273071 |
| fs_lock |
- 64751658 |
+ 64616403 |
| fs_unlock |
- 64751658 |
+ 64616403 |
| extent_parity_inside_compare_unlock |
- 158551658 |
+ 158133634 |
diff --git a/cov/cmdline/elem.c.func.html b/cov/cmdline/elem.c.func.html
index 3e47a0a9..2e65d1fc 100644
--- a/cov/cmdline/elem.c.func.html
+++ b/cov/cmdline/elem.c.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,27 +61,27 @@
| bucket_cmp |
- 711 |
+ 521 |
| bucket_free |
- 746 |
+ 705 |
| bucket_insert |
- 72052 |
+ 55958 |
| bucket_to_list |
- 421 |
+ 420 |
| content_alloc |
- 1606 |
+ 1610 |
| content_free |
- 1551 |
+ 1555 |
| dir_alloc |
@@ -97,15 +97,15 @@
| disk_alloc |
- 1663 |
+ 1673 |
| disk_free |
- 1603 |
+ 1613 |
| extent_alloc |
- 3852016 |
+ 3851976 |
| extent_disk_empty_compare_unlock |
@@ -113,39 +113,39 @@
| extent_disk_size_compare_unlock |
- 52890 |
+ 52796 |
| extent_file_check_foreach_unlock |
- 6837675 |
+ 6820724 |
| extent_file_compare |
- 46158505 |
+ 46157545 |
| extent_file_inside_compare_unlock |
- 22976989 |
+ 22802303 |
| extent_free |
- 3806435 |
+ 3806358 |
| extent_parity_check_foreach_unlock |
- 6837675 |
+ 6820724 |
| extent_parity_compare |
- 45768745 |
+ 45767042 |
| extent_parity_inside_compare_unlock |
- 158551658 |
+ 158133634 |
| file_alloc |
- 3807696 |
+ 3807720 |
| file_block_is_last |
@@ -153,7 +153,7 @@
| file_block_size |
- 6817779 |
+ 6817866 |
| file_copy |
@@ -165,7 +165,7 @@
| file_free |
- 3784741 |
+ 3784728 |
| file_inode_compare |
@@ -173,27 +173,27 @@
| file_inode_compare_to_arg |
- 1043743 |
+ 1046316 |
| file_name |
- 47712 |
+ 47730 |
| file_name_compare |
- 23856 |
+ 23865 |
| file_namestamp_compare |
- 23856 |
+ 23865 |
| file_path_compare |
- 187689 |
+ 187677 |
| file_path_compare_to_arg |
- 97862 |
+ 97805 |
| file_pathstamp_compare |
@@ -201,7 +201,7 @@
| file_physical_compare |
- 99756 |
+ 96760 |
| file_rename |
@@ -209,7 +209,7 @@
| file_stamp_compare |
- 23671 |
+ 23670 |
| filter_alloc_disk |
@@ -217,15 +217,15 @@
| filter_alloc_file |
- 559 |
+ 564 |
| filter_apply |
- 6355925 |
+ 6356195 |
| filter_content |
- 3231524 |
+ 3231650 |
| filter_correctness |
@@ -233,7 +233,7 @@
| filter_element |
- 4591561 |
+ 4591696 |
| filter_emptydir |
@@ -245,11 +245,11 @@
| filter_free |
- 547 |
+ 552 |
| filter_path |
- 4587023 |
+ 4587158 |
| filter_subdir |
@@ -257,7 +257,7 @@
| filter_type |
- 125231 |
+ 125314 |
| fmt_poll |
@@ -269,59 +269,59 @@
| fmt_term |
- 366067 |
+ 366236 |
| fs_allocate |
- 9473576 |
+ 9473620 |
| fs_check |
- 3120 |
+ 3114 |
| fs_deallocate |
- 102986 |
+ 102931 |
| fs_file2block_get |
- 56447214 |
+ 56273071 |
| fs_file2extent_get_unlock |
- 10949888 |
+ 10908566 |
| fs_file2par_find |
- 5301463 |
+ 5260119 |
| fs_is_empty |
- 942 |
+ 936 |
| fs_lock |
- 64751658 |
+ 64616403 |
| fs_par2block_find |
- 38360216 |
+ 38266700 |
| fs_par2extent_get_unlock |
- 49968851 |
+ 49874908 |
| fs_par2file_find |
- 49865865 |
+ 49771977 |
| fs_size |
- 4549 |
+ 4543 |
| fs_unlock |
- 64751658 |
+ 64616403 |
| link_alloc |
diff --git a/cov/cmdline/elem.c.gcov.html b/cov/cmdline/elem.c.gcov.html
index 5b3a0c0c..238b5d8e 100644
--- a/cov/cmdline/elem.c.gcov.html
+++ b/cov/cmdline/elem.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -89,23 +89,23 @@
27 :
28 : int BLOCK_HASH_SIZE = HASH_MAX;
29 :
- 30 1606 : struct snapraid_content* content_alloc(const char* path, uint64_t dev)
+ 30 1610 : struct snapraid_content* content_alloc(const char* path, uint64_t dev)
31 : {
32 : struct snapraid_content* content;
33 :
- 34 1606 : content = malloc_nofail(sizeof(struct snapraid_content));
- 35 1606 : pathimport(content->content, sizeof(content->content), path);
- 36 1606 : content->device = dev;
+ 34 1610 : content = malloc_nofail(sizeof(struct snapraid_content));
+ 35 1610 : pathimport(content->content, sizeof(content->content), path);
+ 36 1610 : content->device = dev;
37 :
- 38 1606 : return content;
+ 38 1610 : return content;
39 : }
40 :
- 41 1551 : void content_free(struct snapraid_content* content)
+ 41 1555 : void content_free(struct snapraid_content* content)
42 : {
- 43 1551 : free(content);
- 44 1551 : }
+ 43 1555 : free(content);
+ 44 1555 : }
45 :
- 46 559 : struct snapraid_filter* filter_alloc_file(int direction, const char* root, const char* pattern)
+ 46 564 : struct snapraid_filter* filter_alloc_file(int direction, const char* root, const char* pattern)
47 : {
48 : struct snapraid_filter* filter;
49 : char* i;
@@ -114,72 +114,72 @@
52 : int token_is_valid;
53 : int token_is_filled;
54 :
- 55 559 : filter = malloc_nofail(sizeof(struct snapraid_filter));
- 56 559 : pathimport(filter->pattern, sizeof(filter->pattern), pattern);
- 57 559 : pathimport(filter->root, sizeof(filter->root), root);
- 58 559 : filter->direction = direction;
+ 55 564 : filter = malloc_nofail(sizeof(struct snapraid_filter));
+ 56 564 : pathimport(filter->pattern, sizeof(filter->pattern), pattern);
+ 57 564 : pathimport(filter->root, sizeof(filter->root), root);
+ 58 564 : filter->direction = direction;
59 :
60 : /* find first and last slash */
- 61 559 : first = 0;
- 62 559 : last = 0;
+ 61 564 : first = 0;
+ 62 564 : last = 0;
63 :
64 : /* reject invalid tokens, like "<empty>", ".", ".." and more dots */
- 65 559 : token_is_valid = 0;
- 66 559 : token_is_filled = 0;
- 67 6943 : for (i = filter->pattern; *i; ++i) {
- 68 6385 : if (*i == '/') {
+ 65 564 : token_is_valid = 0;
+ 66 564 : token_is_filled = 0;
+ 67 6984 : for (i = filter->pattern; *i; ++i) {
+ 68 6421 : if (*i == '/') {
69 : /* reject invalid tokens, but accept an empty one as first */
- 70 4 : if (!token_is_valid && (first != 0 || token_is_filled)) {
+ 70 8 : if (!token_is_valid && (first != 0 || token_is_filled)) {
71 1 : free(filter);
72 1 : return 0;
73 : }
- 74 3 : token_is_valid = 0;
- 75 3 : token_is_filled = 0;
+ 74 7 : token_is_valid = 0;
+ 75 7 : token_is_filled = 0;
76 :
77 : /* update slash position */
- 78 3 : if (!first)
- 79 2 : first = i;
- 80 3 : last = i;
- 81 6381 : } else if (*i != '.') {
- 82 5825 : token_is_valid = 1;
- 83 5825 : token_is_filled = 1;
+ 78 7 : if (!first)
+ 79 5 : first = i;
+ 80 7 : last = i;
+ 81 6413 : } else if (*i != '.') {
+ 82 5855 : token_is_valid = 1;
+ 83 5855 : token_is_filled = 1;
84 : } else {
- 85 556 : token_is_filled = 1;
+ 85 558 : token_is_filled = 1;
86 : }
87 : }
88 :
89 : /* reject invalid tokens, but accept an empty one as last, but not if it's the only one */
- 90 558 : if (!token_is_valid && (first == 0 || token_is_filled)) {
+ 90 563 : if (!token_is_valid && (first == 0 || token_is_filled)) {
91 1 : free(filter);
92 1 : return 0;
93 : }
94 :
95 : /* it's a file filter */
- 96 557 : filter->is_disk = 0;
+ 96 562 : filter->is_disk = 0;
97 :
- 98 557 : if (first == 0) {
+ 98 562 : if (first == 0) {
99 : /* no slash */
- 100 555 : filter->is_abs = 0;
- 101 555 : filter->is_dir = 0;
+ 100 557 : filter->is_abs = 0;
+ 101 557 : filter->is_dir = 0;
102 : } else {
- 103 2 : if (first == filter->pattern) {
+ 103 5 : if (first == filter->pattern) {
104 : /* slash at the start */
- 105 1 : filter->is_abs = 1;
+ 105 2 : filter->is_abs = 1;
106 : } else {
107 : /* no slash at the start */
- 108 1 : filter->is_abs = 0;
+ 108 3 : filter->is_abs = 0;
109 : }
- 110 2 : if (last[1] == 0) {
+ 110 5 : if (last[1] == 0) {
111 : /* slash at the end */
- 112 1 : filter->is_dir = 1;
- 113 1 : last[0] = 0; /* clear the slash */
+ 112 4 : filter->is_dir = 1;
+ 113 4 : last[0] = 0; /* clear the slash */
114 : } else {
115 : /* no slash at the end */
116 1 : filter->is_dir = 0;
117 : }
118 : }
119 :
- 120 557 : return filter;
+ 120 562 : return filter;
121 : }
122 :
123 10 : struct snapraid_filter* filter_alloc_disk(int direction, const char* pattern)
@@ -206,28 +206,28 @@
144 10 : return filter;
145 : }
146 :
- 147 547 : void filter_free(void* filter)
+ 147 552 : void filter_free(void* filter)
148 : {
- 149 547 : free(filter);
- 150 547 : }
+ 149 552 : free(filter);
+ 150 552 : }
151 :
- 152 125231 : const char* filter_type(struct snapraid_filter* filter, char* out, size_t out_size)
+ 152 125314 : const char* filter_type(struct snapraid_filter* filter, char* out, size_t out_size)
153 : {
154 : const char* direction;
155 :
- 156 125231 : if (filter->direction < 0)
- 157 124954 : direction = "exclude";
+ 156 125314 : if (filter->direction < 0)
+ 157 125037 : direction = "exclude";
158 : else
159 277 : direction = "include";
160 :
- 161 125231 : if (filter->is_disk)
+ 161 125314 : if (filter->is_disk)
162 0 : pathprint(out, out_size, "%s %s:", direction, filter->pattern);
- 163 125231 : else if (filter->is_dir)
- 164 0 : pathprint(out, out_size, "%s %s/", direction, filter->pattern);
+ 163 125314 : else if (filter->is_dir)
+ 164 3 : pathprint(out, out_size, "%s %s/", direction, filter->pattern);
165 : else
- 166 125231 : pathprint(out, out_size, "%s %s", direction, filter->pattern);
+ 166 125311 : pathprint(out, out_size, "%s %s", direction, filter->pattern);
167 :
- 168 125231 : return out;
+ 168 125314 : return out;
169 : }
170 :
171 : /**
@@ -239,9 +239,9 @@
177 : * @param is_dir if the path refers to a directory, otherwise to a file.
178 : * @return < 0 if the path is excluded, > 0 if the path is included, 0 if the filter doesn't apply.
179 : */
- 180 6355925 : static int filter_apply(struct snapraid_filter* filter, struct snapraid_filter** reason, const char* path, int is_dir)
+ 180 6356195 : static int filter_apply(struct snapraid_filter* filter, struct snapraid_filter** reason, const char* path, int is_dir)
181 : {
- 182 6355925 : if (filter->root[0] != 0) { /* if it's a local filter */
+ 182 6356195 : if (filter->root[0] != 0) { /* if it's a local filter */
183 0 : if (!path_is_root_of(filter->root, path)) /* applies it only if it matches the root */
184 0 : return 0;
185 : /* advance the path to compare to make it local */
@@ -249,39 +249,39 @@
187 : }
188 :
189 : /* match dirs with dirs and files with files */
- 190 6355925 : if (filter->is_dir && !is_dir)
+ 190 6356195 : if (filter->is_dir && !is_dir)
191 5939 : return 0;
- 192 6349986 : if (!filter->is_dir && is_dir)
+ 192 6350256 : if (!filter->is_dir && is_dir)
193 6274 : return 0;
194 :
- 195 6343712 : int ret = 0;
+ 195 6343982 : int ret = 0;
196 :
- 197 6343712 : if (filter->is_abs) {
+ 197 6343982 : if (filter->is_abs) {
198 : /* skip initial slash, as always missing in the path */
199 5939 : if (wnmatch(filter->pattern + 1, path) == 0)
200 0 : ret = filter->direction;
201 : } else {
202 : /* the path is relative, first try to match from the root */
- 203 6337773 : if (wnmatch(filter->pattern, path) == 0) {
+ 203 6338043 : if (wnmatch(filter->pattern, path) == 0) {
204 92 : ret = filter->direction;
205 : } else {
206 : /* then try to match after all the / presents */
- 207 6337681 : char* slash = strchr(path, '/');
- 208 12543215 : while (slash) {
- 209 6330119 : if (wnmatch(filter->pattern, slash + 1) == 0) {
- 210 124585 : ret = filter->direction;
- 211 124585 : break;
+ 207 6337951 : char* slash = strchr(path, '/');
+ 208 12543677 : while (slash) {
+ 209 6330389 : if (wnmatch(filter->pattern, slash + 1) == 0) {
+ 210 124663 : ret = filter->direction;
+ 211 124663 : break;
212 : }
213 :
- 214 6205534 : slash = strchr(slash + 1, '/');
+ 214 6205726 : slash = strchr(slash + 1, '/');
215 : }
216 : }
217 : }
218 :
- 219 6343712 : if (reason != 0 && ret < 0)
- 220 124677 : *reason = filter;
+ 219 6343982 : if (reason != 0 && ret < 0)
+ 220 124755 : *reason = filter;
221 :
- 222 6343712 : return ret;
+ 222 6343982 : return ret;
223 : }
224 :
225 : /**
@@ -296,7 +296,7 @@
234 : * @return < 0 if the path is excluded, == 0 if the path is included.
235 : */
236 :
- 237 4591561 : static int filter_element(tommy_list* filterlist, struct snapraid_filter** reason, const char* disk, const char* sub, int is_dir, int is_def_include)
+ 237 4591696 : static int filter_element(tommy_list* filterlist, struct snapraid_filter** reason, const char* disk, const char* sub, int is_dir, int is_def_include)
238 : {
239 : tommy_node* i;
240 :
@@ -308,14 +308,14 @@
246 : * If the latest filter is an 'inclusion' filter, the default is to exclude.
247 : * If there are no filter, the default is to include.
248 : */
- 249 4591561 : int default_direction = 1;
+ 249 4591696 : int default_direction = 1;
250 :
251 : /* for each filter */
- 252 10924117 : for (i = tommy_list_head(filterlist); i != 0; i = i->next) {
+ 252 10924444 : for (i = tommy_list_head(filterlist); i != 0; i = i->next) {
253 : int ret;
- 254 6465913 : struct snapraid_filter* filter = i->data;
+ 254 6466183 : struct snapraid_filter* filter = i->data;
255 :
- 256 6465913 : if (filter->is_disk) {
+ 256 6466183 : if (filter->is_disk) {
257 109988 : if (wnmatch(filter->pattern, disk) == 0) {
258 8680 : ret = filter->direction;
259 : } else {
@@ -324,39 +324,39 @@
262 109988 : if (reason != 0 && ret < 0)
263 0 : *reason = filter;
264 : } else {
- 265 6355925 : ret = filter_apply(filter, reason, sub, is_dir);
+ 265 6356195 : ret = filter_apply(filter, reason, sub, is_dir);
266 : }
267 :
- 268 6465913 : if (ret > 0) {
+ 268 6466183 : if (ret > 0) {
269 : /* include the file */
270 8680 : return 0;
- 271 6457233 : } else if (ret < 0) {
+ 271 6457503 : } else if (ret < 0) {
272 : /* exclude the file */
- 273 124677 : return -1;
+ 273 124755 : return -1;
274 : } else {
275 : /* default is opposite of the last filter */
- 276 6332556 : default_direction = -filter->direction;
- 277 6332556 : if (reason != 0 && default_direction < 0)
- 278 3169054 : *reason = filter;
+ 276 6332748 : default_direction = -filter->direction;
+ 277 6332748 : if (reason != 0 && default_direction < 0)
+ 278 3169189 : *reason = filter;
279 : /* continue with the next one */
280 : }
281 : }
282 :
283 : /* directories are always included by default, otherwise we cannot apply rules */
284 : /* to the contained files */
- 285 4458204 : if (is_def_include)
+ 285 4458261 : if (is_def_include)
286 4493 : return 0;
287 :
288 : /* files are excluded/included depending of the last rule processed */
- 289 4453711 : if (default_direction < 0)
+ 289 4453768 : if (default_direction < 0)
290 60598 : return -1;
291 :
- 292 4393113 : return 0;
+ 292 4393170 : return 0;
293 : }
294 :
- 295 4587023 : int filter_path(tommy_list* filterlist, struct snapraid_filter** reason, const char* disk, const char* sub)
+ 295 4587158 : int filter_path(tommy_list* filterlist, struct snapraid_filter** reason, const char* disk, const char* sub)
296 : {
- 297 4587023 : return filter_element(filterlist, reason, disk, sub, 0, 0);
+ 297 4587158 : return filter_element(filterlist, reason, disk, sub, 0, 0);
298 : }
299 :
300 4493 : int filter_subdir(tommy_list* filterlist, struct snapraid_filter** reason, const char* disk, const char* sub)
@@ -402,67 +402,67 @@
340 13214 : return 0;
341 :
342 : /* check each block of the file */
- 343 60662 : for (i = 0; i < file->blockmax; ++i) {
- 344 46388 : block_off_t parity_pos = fs_file2par_get(disk, file, i);
- 345 46388 : snapraid_info info = info_get(infoarr, parity_pos);
+ 343 60694 : for (i = 0; i < file->blockmax; ++i) {
+ 344 46465 : block_off_t parity_pos = fs_file2par_get(disk, file, i);
+ 345 46465 : snapraid_info info = info_get(infoarr, parity_pos);
346 :
347 : /* if the file has a bad block, don't exclude it */
- 348 46388 : if (info_get_bad(info))
- 349 8274 : return 0;
+ 348 46465 : if (info_get_bad(info))
+ 349 8319 : return 0;
350 : }
351 :
352 : /* the file is correct, so we filter it out */
- 353 14274 : return 1;
+ 353 14229 : return 1;
354 : }
355 :
- 356 3231524 : int filter_content(tommy_list* contentlist, const char* path)
+ 356 3231650 : int filter_content(tommy_list* contentlist, const char* path)
357 : {
358 : tommy_node* i;
359 :
- 360 20922616 : for (i = tommy_list_head(contentlist); i != 0; i = i->next) {
- 361 17691092 : struct snapraid_content* content = i->data;
+ 360 20923098 : for (i = tommy_list_head(contentlist); i != 0; i = i->next) {
+ 361 17691448 : struct snapraid_content* content = i->data;
362 : char tmp[PATH_MAX];
363 :
- 364 17691092 : if (pathcmp(content->content, path) == 0)
+ 364 17691448 : if (pathcmp(content->content, path) == 0)
365 0 : return -1;
366 :
367 : /* exclude also the ".tmp" copy used to save it */
- 368 17691092 : pathprint(tmp, sizeof(tmp), "%s.tmp", content->content);
- 369 17691092 : if (pathcmp(tmp, path) == 0)
+ 368 17691448 : pathprint(tmp, sizeof(tmp), "%s.tmp", content->content);
+ 369 17691448 : if (pathcmp(tmp, path) == 0)
370 0 : return -1;
371 :
372 : /* exclude also the ".lock" file */
- 373 17691092 : pathprint(tmp, sizeof(tmp), "%s.lock", content->content);
- 374 17691092 : if (pathcmp(tmp, path) == 0)
+ 373 17691448 : pathprint(tmp, sizeof(tmp), "%s.lock", content->content);
+ 374 17691448 : if (pathcmp(tmp, path) == 0)
375 0 : return -1;
376 : }
377 :
- 378 3231524 : return 0;
+ 378 3231650 : return 0;
379 : }
380 :
- 381 3807696 : 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)
+ 381 3807720 : 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)
382 : {
383 : struct snapraid_file* file;
384 : block_off_t i;
385 :
- 386 3807696 : file = malloc_nofail(sizeof(struct snapraid_file));
- 387 3807696 : file->sub = strdup_nofail(sub);
- 388 3807696 : file->size = size;
- 389 3807696 : file->blockmax = (size + block_size - 1) / block_size;
- 390 3807696 : file->mtime_sec = mtime_sec;
- 391 3807696 : file->mtime_nsec = mtime_nsec;
- 392 3807696 : file->inode = inode;
- 393 3807696 : file->physical = physical;
- 394 3807696 : file->flag = 0;
- 395 3807696 : file->blockvec = malloc_nofail(file->blockmax * block_sizeof());
+ 386 3807720 : file = malloc_nofail(sizeof(struct snapraid_file));
+ 387 3807720 : file->sub = strdup_nofail(sub);
+ 388 3807720 : file->size = size;
+ 389 3807720 : file->blockmax = (size + block_size - 1) / block_size;
+ 390 3807720 : file->mtime_sec = mtime_sec;
+ 391 3807720 : file->mtime_nsec = mtime_nsec;
+ 392 3807720 : file->inode = inode;
+ 393 3807720 : file->physical = physical;
+ 394 3807720 : file->flag = 0;
+ 395 3807720 : file->blockvec = malloc_nofail(file->blockmax * block_sizeof());
396 :
- 397 13224281 : for (i = 0; i < file->blockmax; ++i) {
- 398 9416585 : struct snapraid_block* block = file_block(file, i);
- 399 9416585 : block_state_set(block, BLOCK_STATE_CHG);
- 400 9416585 : hash_invalid_set(block->hash);
+ 397 13224349 : for (i = 0; i < file->blockmax; ++i) {
+ 398 9416629 : struct snapraid_block* block = file_block(file, i);
+ 399 9416629 : block_state_set(block, BLOCK_STATE_CHG);
+ 400 9416629 : hash_invalid_set(block->hash);
401 : }
402 :
- 403 3807696 : return file;
+ 403 3807720 : return file;
404 : }
405 :
406 22687 : struct snapraid_file* file_dup(struct snapraid_file* copy)
@@ -491,14 +491,14 @@
429 22687 : return file;
430 : }
431 :
- 432 3784741 : void file_free(struct snapraid_file* file)
+ 432 3784728 : void file_free(struct snapraid_file* file)
433 : {
- 434 3784741 : free(file->sub);
- 435 3784741 : file->sub = 0;
- 436 3784741 : free(file->blockvec);
- 437 3784741 : file->blockvec = 0;
- 438 3784741 : free(file);
- 439 3784741 : }
+ 434 3784728 : free(file->sub);
+ 435 3784728 : file->sub = 0;
+ 436 3784728 : free(file->blockvec);
+ 437 3784728 : file->blockvec = 0;
+ 438 3784728 : free(file);
+ 439 3784728 : }
440 :
441 155 : void file_rename(struct snapraid_file* file, const char* sub)
442 : {
@@ -542,31 +542,31 @@
480 23637 : file_flag_set(dst_file, FILE_IS_COPY);
481 23637 : }
482 :
- 483 47712 : const char* file_name(const struct snapraid_file* file)
+ 483 47730 : const char* file_name(const struct snapraid_file* file)
484 : {
- 485 47712 : const char* r = strrchr(file->sub, '/');
+ 485 47730 : const char* r = strrchr(file->sub, '/');
486 :
- 487 47712 : if (!r)
- 488 80 : r = file->sub;
+ 487 47730 : if (!r)
+ 488 78 : r = file->sub;
489 : else
- 490 47632 : ++r;
- 491 47712 : return r;
+ 490 47652 : ++r;
+ 491 47730 : return r;
492 : }
493 :
- 494 6817779 : unsigned file_block_size(struct snapraid_file* file, block_off_t file_pos, unsigned block_size)
+ 494 6817866 : unsigned file_block_size(struct snapraid_file* file, block_off_t file_pos, unsigned block_size)
495 : {
496 : /* if it's the last block */
- 497 6817779 : if (file_pos + 1 == file->blockmax) {
+ 497 6817866 : if (file_pos + 1 == file->blockmax) {
498 : unsigned block_remainder;
- 499 2771709 : if (file->size == 0)
+ 499 2772053 : if (file->size == 0)
500 0 : return 0;
- 501 2771709 : block_remainder = file->size % block_size;
- 502 2771709 : if (block_remainder == 0)
- 503 3046 : block_remainder = block_size;
- 504 2771709 : return block_remainder;
+ 501 2772053 : block_remainder = file->size % block_size;
+ 502 2772053 : if (block_remainder == 0)
+ 503 3053 : block_remainder = block_size;
+ 504 2772053 : return block_remainder;
505 : }
506 :
- 507 4046070 : return block_size;
+ 507 4045813 : return block_size;
508 : }
509 :
510 5245100 : int file_block_is_last(struct snapraid_file* file, block_off_t file_pos)
@@ -584,16 +584,16 @@
522 5245100 : return file_pos == file->blockmax - 1;
523 : }
524 :
- 525 1043743 : int file_inode_compare_to_arg(const void* void_arg, const void* void_data)
+ 525 1046316 : int file_inode_compare_to_arg(const void* void_arg, const void* void_data)
526 : {
- 527 1043743 : const uint64_t* arg = void_arg;
- 528 1043743 : const struct snapraid_file* file = void_data;
+ 527 1046316 : const uint64_t* arg = void_arg;
+ 528 1046316 : const struct snapraid_file* file = void_data;
529 :
- 530 1043743 : if (*arg < file->inode)
+ 530 1046316 : if (*arg < file->inode)
531 0 : return -1;
- 532 1043743 : if (*arg > file->inode)
+ 532 1046316 : if (*arg > file->inode)
533 0 : return 1;
- 534 1043743 : return 0;
+ 534 1046316 : return 0;
535 : }
536 :
537 0 : int file_inode_compare(const void* void_a, const void* void_b)
@@ -608,76 +608,76 @@
546 0 : return 0;
547 : }
548 :
- 549 187689 : int file_path_compare(const void* void_a, const void* void_b)
+ 549 187677 : int file_path_compare(const void* void_a, const void* void_b)
550 : {
- 551 187689 : const struct snapraid_file* file_a = void_a;
- 552 187689 : const struct snapraid_file* file_b = void_b;
+ 551 187677 : const struct snapraid_file* file_a = void_a;
+ 552 187677 : const struct snapraid_file* file_b = void_b;
553 :
- 554 187689 : return strcmp(file_a->sub, file_b->sub);
+ 554 187677 : return strcmp(file_a->sub, file_b->sub);
555 : }
556 :
- 557 99756 : int file_physical_compare(const void* void_a, const void* void_b)
+ 557 96760 : int file_physical_compare(const void* void_a, const void* void_b)
558 : {
- 559 99756 : const struct snapraid_file* file_a = void_a;
- 560 99756 : const struct snapraid_file* file_b = void_b;
+ 559 96760 : const struct snapraid_file* file_a = void_a;
+ 560 96760 : const struct snapraid_file* file_b = void_b;
561 :
- 562 99756 : if (file_a->physical < file_b->physical)
- 563 52632 : return -1;
- 564 47124 : if (file_a->physical > file_b->physical)
- 565 47122 : return 1;
+ 562 96760 : if (file_a->physical < file_b->physical)
+ 563 52606 : return -1;
+ 564 44154 : if (file_a->physical > file_b->physical)
+ 565 44152 : return 1;
566 2 : return 0;
567 : }
568 :
- 569 97862 : int file_path_compare_to_arg(const void* void_arg, const void* void_data)
+ 569 97805 : int file_path_compare_to_arg(const void* void_arg, const void* void_data)
570 : {
- 571 97862 : const char* arg = void_arg;
- 572 97862 : const struct snapraid_file* file = void_data;
+ 571 97805 : const char* arg = void_arg;
+ 572 97805 : const struct snapraid_file* file = void_data;
573 :
- 574 97862 : return strcmp(arg, file->sub);
+ 574 97805 : return strcmp(arg, file->sub);
575 : }
576 :
- 577 23856 : int file_name_compare(const void* void_a, const void* void_b)
+ 577 23865 : int file_name_compare(const void* void_a, const void* void_b)
578 : {
- 579 23856 : const struct snapraid_file* file_a = void_a;
- 580 23856 : const struct snapraid_file* file_b = void_b;
- 581 23856 : const char* name_a = file_name(file_a);
- 582 23856 : const char* name_b = file_name(file_b);
+ 579 23865 : const struct snapraid_file* file_a = void_a;
+ 580 23865 : const struct snapraid_file* file_b = void_b;
+ 581 23865 : const char* name_a = file_name(file_a);
+ 582 23865 : const char* name_b = file_name(file_b);
583 :
- 584 23856 : return strcmp(name_a, name_b);
+ 584 23865 : return strcmp(name_a, name_b);
585 : }
586 :
- 587 23671 : int file_stamp_compare(const void* void_a, const void* void_b)
+ 587 23670 : int file_stamp_compare(const void* void_a, const void* void_b)
588 : {
- 589 23671 : const struct snapraid_file* file_a = void_a;
- 590 23671 : const struct snapraid_file* file_b = void_b;
+ 589 23670 : const struct snapraid_file* file_a = void_a;
+ 590 23670 : const struct snapraid_file* file_b = void_b;
591 :
- 592 23671 : if (file_a->size < file_b->size)
+ 592 23670 : if (file_a->size < file_b->size)
593 0 : return -1;
- 594 23671 : if (file_a->size > file_b->size)
+ 594 23670 : if (file_a->size > file_b->size)
595 0 : return 1;
596 :
- 597 23671 : if (file_a->mtime_sec < file_b->mtime_sec)
+ 597 23670 : if (file_a->mtime_sec < file_b->mtime_sec)
598 0 : return -1;
- 599 23671 : if (file_a->mtime_sec > file_b->mtime_sec)
+ 599 23670 : if (file_a->mtime_sec > file_b->mtime_sec)
600 0 : return 1;
601 :
- 602 23671 : if (file_a->mtime_nsec < file_b->mtime_nsec)
+ 602 23670 : if (file_a->mtime_nsec < file_b->mtime_nsec)
603 0 : return -1;
- 604 23671 : if (file_a->mtime_nsec > file_b->mtime_nsec)
+ 604 23670 : if (file_a->mtime_nsec > file_b->mtime_nsec)
605 0 : return 1;
606 :
- 607 23671 : return 0;
+ 607 23670 : return 0;
608 : }
609 :
- 610 23856 : int file_namestamp_compare(const void* void_a, const void* void_b)
+ 610 23865 : int file_namestamp_compare(const void* void_a, const void* void_b)
611 : {
612 : int ret;
613 :
- 614 23856 : ret = file_name_compare(void_a, void_b);
- 615 23856 : if (ret != 0)
- 616 185 : return ret;
+ 614 23865 : ret = file_name_compare(void_a, void_b);
+ 615 23865 : if (ret != 0)
+ 616 195 : return ret;
617 :
- 618 23671 : return file_stamp_compare(void_a, void_b);
+ 618 23670 : return file_stamp_compare(void_a, void_b);
619 : }
620 :
621 0 : int file_pathstamp_compare(const void* void_a, const void* void_b)
@@ -691,66 +691,66 @@
629 0 : return file_stamp_compare(void_a, void_b);
630 : }
631 :
- 632 3852016 : struct snapraid_extent* extent_alloc(block_off_t parity_pos, struct snapraid_file* file, block_off_t file_pos, block_off_t count)
+ 632 3851976 : struct snapraid_extent* extent_alloc(block_off_t parity_pos, struct snapraid_file* file, block_off_t file_pos, block_off_t count)
633 : {
634 : struct snapraid_extent* extent;
635 :
- 636 3852016 : if (count == 0) {
+ 636 3851976 : if (count == 0) {
637 : /* LCOV_EXCL_START */
638 : log_fatal(EINTERNAL, "Internal inconsistency: Allocating empty extent for file '%s' at position '%u/%u'\n", file->sub, file_pos, file->blockmax);
639 : os_abort();
640 : /* LCOV_EXCL_STOP */
641 : }
- 642 3852016 : if (file_pos + count > file->blockmax) {
+ 642 3851976 : if (file_pos + count > file->blockmax) {
643 : /* LCOV_EXCL_START */
644 : log_fatal(EINTERNAL, "Internal inconsistency: Allocating overflowing extent for file '%s' at position '%u:%u/%u'\n", file->sub, file_pos, count, file->blockmax);
645 : os_abort();
646 : /* LCOV_EXCL_STOP */
647 : }
648 :
- 649 3852016 : extent = malloc_nofail(sizeof(struct snapraid_extent));
- 650 3852016 : extent->parity_pos = parity_pos;
- 651 3852016 : extent->file = file;
- 652 3852016 : extent->file_pos = file_pos;
- 653 3852016 : extent->count = count;
+ 649 3851976 : extent = malloc_nofail(sizeof(struct snapraid_extent));
+ 650 3851976 : extent->parity_pos = parity_pos;
+ 651 3851976 : extent->file = file;
+ 652 3851976 : extent->file_pos = file_pos;
+ 653 3851976 : extent->count = count;
654 :
- 655 3852016 : return extent;
+ 655 3851976 : return extent;
656 : }
657 :
- 658 3806435 : void extent_free(struct snapraid_extent* extent)
+ 658 3806358 : void extent_free(struct snapraid_extent* extent)
659 : {
- 660 3806435 : free(extent);
- 661 3806435 : }
+ 660 3806358 : free(extent);
+ 661 3806358 : }
662 :
- 663 45768745 : int extent_parity_compare(const void* void_a, const void* void_b)
+ 663 45767042 : int extent_parity_compare(const void* void_a, const void* void_b)
664 : {
- 665 45768745 : const struct snapraid_extent* arg_a = void_a;
- 666 45768745 : const struct snapraid_extent* arg_b = void_b;
+ 665 45767042 : const struct snapraid_extent* arg_a = void_a;
+ 666 45767042 : const struct snapraid_extent* arg_b = void_b;
667 :
- 668 45768745 : if (arg_a->parity_pos < arg_b->parity_pos)
- 669 939508 : return -1;
- 670 44829237 : if (arg_a->parity_pos > arg_b->parity_pos)
- 671 44791372 : return 1;
+ 668 45767042 : if (arg_a->parity_pos < arg_b->parity_pos)
+ 669 940645 : return -1;
+ 670 44826397 : if (arg_a->parity_pos > arg_b->parity_pos)
+ 671 44788547 : return 1;
672 :
- 673 37865 : return 0;
+ 673 37850 : return 0;
674 : }
675 :
- 676 46158505 : int extent_file_compare(const void* void_a, const void* void_b)
+ 676 46157545 : int extent_file_compare(const void* void_a, const void* void_b)
677 : {
- 678 46158505 : const struct snapraid_extent* arg_a = void_a;
- 679 46158505 : const struct snapraid_extent* arg_b = void_b;
+ 678 46157545 : const struct snapraid_extent* arg_a = void_a;
+ 679 46157545 : const struct snapraid_extent* arg_b = void_b;
680 :
- 681 46158505 : if (arg_a->file < arg_b->file)
- 682 1049004 : return -1;
- 683 45109501 : if (arg_a->file > arg_b->file)
- 684 45040264 : return 1;
+ 681 46157545 : if (arg_a->file < arg_b->file)
+ 682 1039297 : return -1;
+ 683 45118248 : if (arg_a->file > arg_b->file)
+ 684 45049105 : return 1;
685 :
- 686 69237 : if (arg_a->file_pos < arg_b->file_pos)
- 687 183 : return -1;
- 688 69054 : if (arg_a->file_pos > arg_b->file_pos)
- 689 31189 : return 1;
+ 686 69143 : if (arg_a->file_pos < arg_b->file_pos)
+ 687 186 : return -1;
+ 688 68957 : if (arg_a->file_pos > arg_b->file_pos)
+ 689 31107 : return 1;
690 :
- 691 37865 : return 0;
+ 691 37850 : return 0;
692 : }
693 :
694 123513 : struct snapraid_link* link_alloc(const char* sub, const char* linkto, unsigned link_flag)
@@ -813,96 +813,96 @@
751 269 : return strcmp(arg, dir->sub);
752 : }
753 :
- 754 1663 : struct snapraid_disk* disk_alloc(const char* name, const char* dir, uint64_t dev, const char* uuid, int skip_access)
+ 754 1673 : struct snapraid_disk* disk_alloc(const char* name, const char* dir, uint64_t dev, const char* uuid, int skip_access)
755 : {
756 : struct snapraid_disk* disk;
757 : unsigned i;
758 :
- 759 1663 : disk = malloc_nofail(sizeof(struct snapraid_disk));
- 760 1663 : pathcpy(disk->name, sizeof(disk->name), name);
- 761 1663 : pathimport(disk->dir, sizeof(disk->dir), dir);
- 762 1663 : pathcpy(disk->uuid, sizeof(disk->uuid), uuid);
+ 759 1673 : disk = malloc_nofail(sizeof(struct snapraid_disk));
+ 760 1673 : pathcpy(disk->name, sizeof(disk->name), name);
+ 761 1673 : pathimport(disk->dir, sizeof(disk->dir), dir);
+ 762 1673 : pathcpy(disk->uuid, sizeof(disk->uuid), uuid);
763 :
764 : /* ensure that the dir terminate with "/" if it isn't empty */
- 765 1663 : pathslash(disk->dir, sizeof(disk->dir));
+ 765 1673 : pathslash(disk->dir, sizeof(disk->dir));
766 :
767 : #if HAVE_THREAD
- 768 1663 : thread_mutex_init(&disk->fs_mutex);
+ 768 1673 : thread_mutex_init(&disk->fs_mutex);
769 : #endif
770 :
- 771 1663 : disk->smartctl[0] = 0;
- 772 8315 : for (i = 0; i < SMART_IGNORE_MAX; ++i)
- 773 6652 : disk->smartignore[i] = 0;
- 774 1663 : disk->fstype[0] = 0;
- 775 1663 : disk->fslabel[0] = 0;
- 776 1663 : disk->device = dev;
- 777 1663 : disk->tick = 0;
- 778 1663 : disk->cached_blocks = 0;
- 779 1663 : disk->progress_file = 0;
- 780 1663 : disk->total_blocks = 0;
- 781 1663 : disk->free_blocks = 0;
- 782 1663 : disk->first_free_block = 0;
- 783 1663 : disk->has_volatile_inodes = 0;
- 784 1663 : disk->has_volatile_hardlinks = 0;
- 785 1663 : disk->has_unreliable_physical = 0;
- 786 1663 : disk->has_different_uuid = 0;
- 787 1663 : disk->has_unsupported_uuid = *uuid == 0; /* empty UUID means unsupported */
- 788 1663 : disk->had_empty_uuid = 0;
- 789 1663 : disk->mapping_idx = -1;
- 790 1663 : disk->skip_access = skip_access;
- 791 1663 : tommy_list_init(&disk->filelist);
- 792 1663 : tommy_list_init(&disk->deletedlist);
- 793 1663 : tommy_hashdyn_init(&disk->inodeset);
- 794 1663 : tommy_hashdyn_init(&disk->pathset);
- 795 1663 : tommy_hashdyn_init(&disk->stampset);
- 796 1663 : tommy_list_init(&disk->linklist);
- 797 1663 : tommy_hashdyn_init(&disk->linkset);
- 798 1663 : tommy_list_init(&disk->dirlist);
- 799 1663 : tommy_hashdyn_init(&disk->dirset);
- 800 1663 : tommy_tree_init(&disk->fs_parity, extent_parity_compare);
- 801 1663 : tommy_tree_init(&disk->fs_file, extent_file_compare);
- 802 1663 : disk->fs_last = 0;
+ 771 1673 : disk->smartctl[0] = 0;
+ 772 8365 : for (i = 0; i < SMART_IGNORE_MAX; ++i)
+ 773 6692 : disk->smartignore[i] = 0;
+ 774 1673 : disk->fstype[0] = 0;
+ 775 1673 : disk->fslabel[0] = 0;
+ 776 1673 : disk->device = dev;
+ 777 1673 : disk->tick = 0;
+ 778 1673 : disk->cached_blocks = 0;
+ 779 1673 : disk->progress_file = 0;
+ 780 1673 : disk->total_blocks = 0;
+ 781 1673 : disk->free_blocks = 0;
+ 782 1673 : disk->first_free_block = 0;
+ 783 1673 : disk->has_volatile_inodes = 0;
+ 784 1673 : disk->has_volatile_hardlinks = 0;
+ 785 1673 : disk->has_unreliable_physical = 0;
+ 786 1673 : disk->has_different_uuid = 0;
+ 787 1673 : disk->has_unsupported_uuid = *uuid == 0; /* empty UUID means unsupported */
+ 788 1673 : disk->had_empty_uuid = 0;
+ 789 1673 : disk->mapping_idx = -1;
+ 790 1673 : disk->skip_access = skip_access;
+ 791 1673 : tommy_list_init(&disk->filelist);
+ 792 1673 : tommy_list_init(&disk->deletedlist);
+ 793 1673 : tommy_hashdyn_init(&disk->inodeset);
+ 794 1673 : tommy_hashdyn_init(&disk->pathset);
+ 795 1673 : tommy_hashdyn_init(&disk->stampset);
+ 796 1673 : tommy_list_init(&disk->linklist);
+ 797 1673 : tommy_hashdyn_init(&disk->linkset);
+ 798 1673 : tommy_list_init(&disk->dirlist);
+ 799 1673 : tommy_hashdyn_init(&disk->dirset);
+ 800 1673 : tommy_tree_init(&disk->fs_parity, extent_parity_compare);
+ 801 1673 : tommy_tree_init(&disk->fs_file, extent_file_compare);
+ 802 1673 : disk->fs_last = 0;
803 :
- 804 1663 : return disk;
+ 804 1673 : return disk;
805 : }
806 :
- 807 1603 : void disk_free(struct snapraid_disk* disk)
+ 807 1613 : void disk_free(struct snapraid_disk* disk)
808 : {
- 809 1603 : tommy_list_foreach(&disk->filelist, (tommy_foreach_func*)file_free);
- 810 1603 : tommy_list_foreach(&disk->deletedlist, (tommy_foreach_func*)file_free);
- 811 1603 : tommy_tree_foreach(&disk->fs_file, (tommy_foreach_func*)extent_free);
- 812 1603 : tommy_hashdyn_done(&disk->inodeset);
- 813 1603 : tommy_hashdyn_done(&disk->pathset);
- 814 1603 : tommy_hashdyn_done(&disk->stampset);
- 815 1603 : tommy_list_foreach(&disk->linklist, (tommy_foreach_func*)link_free);
- 816 1603 : tommy_hashdyn_done(&disk->linkset);
- 817 1603 : tommy_list_foreach(&disk->dirlist, (tommy_foreach_func*)dir_free);
- 818 1603 : tommy_hashdyn_done(&disk->dirset);
+ 809 1613 : tommy_list_foreach(&disk->filelist, (tommy_foreach_func*)file_free);
+ 810 1613 : tommy_list_foreach(&disk->deletedlist, (tommy_foreach_func*)file_free);
+ 811 1613 : tommy_tree_foreach(&disk->fs_file, (tommy_foreach_func*)extent_free);
+ 812 1613 : tommy_hashdyn_done(&disk->inodeset);
+ 813 1613 : tommy_hashdyn_done(&disk->pathset);
+ 814 1613 : tommy_hashdyn_done(&disk->stampset);
+ 815 1613 : tommy_list_foreach(&disk->linklist, (tommy_foreach_func*)link_free);
+ 816 1613 : tommy_hashdyn_done(&disk->linkset);
+ 817 1613 : tommy_list_foreach(&disk->dirlist, (tommy_foreach_func*)dir_free);
+ 818 1613 : tommy_hashdyn_done(&disk->dirset);
819 :
820 : #if HAVE_THREAD
- 821 1603 : thread_mutex_destroy(&disk->fs_mutex);
+ 821 1613 : thread_mutex_destroy(&disk->fs_mutex);
822 : #endif
823 :
- 824 1603 : free(disk);
- 825 1603 : }
+ 824 1613 : free(disk);
+ 825 1613 : }
826 :
- 827 64751658 : static inline void fs_lock(struct snapraid_disk* disk)
+ 827 64616403 : static inline void fs_lock(struct snapraid_disk* disk)
828 : {
829 : #if HAVE_THREAD
- 830 64751658 : thread_mutex_lock(&disk->fs_mutex);
+ 830 64616403 : thread_mutex_lock(&disk->fs_mutex);
831 : #else
832 : (void)disk;
833 : #endif
- 834 64751658 : }
+ 834 64616403 : }
835 :
- 836 64751658 : static inline void fs_unlock(struct snapraid_disk* disk)
+ 836 64616403 : static inline void fs_unlock(struct snapraid_disk* disk)
837 : {
838 : #if HAVE_THREAD
- 839 64751658 : thread_mutex_unlock(&disk->fs_mutex);
+ 839 64616403 : thread_mutex_unlock(&disk->fs_mutex);
840 : #else
841 : (void)disk;
842 : #endif
- 843 64751658 : }
+ 843 64616403 : }
844 :
845 : struct extent_disk_empty {
846 : block_off_t blockmax;
@@ -924,14 +924,14 @@
862 5 : return -1;
863 : }
864 :
- 865 942 : int fs_is_empty(struct snapraid_disk* disk, block_off_t blockmax)
+ 865 936 : int fs_is_empty(struct snapraid_disk* disk, block_off_t blockmax)
866 : {
- 867 942 : struct extent_disk_empty arg = { blockmax };
+ 867 936 : struct extent_disk_empty arg = { blockmax };
868 :
869 : /* if there is an element, it's not empty */
870 : /* even if links and dirs have no block allocation */
- 871 942 : if (!tommy_list_empty(&disk->filelist))
- 872 843 : return 0;
+ 871 936 : if (!tommy_list_empty(&disk->filelist))
+ 872 837 : return 0;
873 99 : if (!tommy_list_empty(&disk->linklist))
874 0 : return 0;
875 99 : if (!tommy_list_empty(&disk->dirlist))
@@ -959,30 +959,30 @@
897 : *
898 : * The maximum parity position is stored as size.
899 : */
- 900 52890 : static int extent_disk_size_compare_unlock(const void* void_a, const void* void_b)
+ 900 52796 : static int extent_disk_size_compare_unlock(const void* void_a, const void* void_b)
901 : {
- 902 52890 : struct extent_disk_size* arg_a = (void*)void_a;
- 903 52890 : const struct snapraid_extent* arg_b = void_b;
+ 902 52796 : struct extent_disk_size* arg_a = (void*)void_a;
+ 903 52796 : const struct snapraid_extent* arg_b = void_b;
904 :
905 : /* get the maximum size */
- 906 52890 : if (arg_a->size < arg_b->parity_pos + arg_b->count)
- 907 52890 : arg_a->size = arg_b->parity_pos + arg_b->count;
+ 906 52796 : if (arg_a->size < arg_b->parity_pos + arg_b->count)
+ 907 52796 : arg_a->size = arg_b->parity_pos + arg_b->count;
908 :
909 : /* search always for a bigger one */
- 910 52890 : return 1;
+ 910 52796 : return 1;
911 : }
912 :
- 913 4549 : block_off_t fs_size(struct snapraid_disk* disk)
+ 913 4543 : block_off_t fs_size(struct snapraid_disk* disk)
914 : {
- 915 4549 : struct extent_disk_size arg = { 0 };
+ 915 4543 : struct extent_disk_size arg = { 0 };
916 :
- 917 4549 : fs_lock(disk);
+ 917 4543 : fs_lock(disk);
918 :
- 919 4549 : tommy_tree_search_compare(&disk->fs_parity, extent_disk_size_compare_unlock, &arg);
+ 919 4543 : tommy_tree_search_compare(&disk->fs_parity, extent_disk_size_compare_unlock, &arg);
920 :
- 921 4549 : fs_unlock(disk);
+ 921 4543 : fs_unlock(disk);
922 :
- 923 4549 : return arg.size;
+ 923 4543 : return arg.size;
924 : }
925 :
926 : struct extent_check {
@@ -990,23 +990,23 @@
928 : int result;
929 : };
930 :
- 931 6837675 : static void extent_parity_check_foreach_unlock(void* void_arg, void* void_obj)
+ 931 6820724 : static void extent_parity_check_foreach_unlock(void* void_arg, void* void_obj)
932 : {
- 933 6837675 : struct extent_check* arg = void_arg;
- 934 6837675 : const struct snapraid_extent* obj = void_obj;
- 935 6837675 : const struct snapraid_extent* prev = arg->prev;
+ 933 6820724 : struct extent_check* arg = void_arg;
+ 934 6820724 : const struct snapraid_extent* obj = void_obj;
+ 935 6820724 : const struct snapraid_extent* prev = arg->prev;
936 :
937 : /* set the next previous block */
- 938 6837675 : arg->prev = obj;
+ 938 6820724 : arg->prev = obj;
939 :
940 : /* stop reporting if too many errors */
- 941 6837675 : if (arg->result > 100) {
+ 941 6820724 : if (arg->result > 100) {
942 : /* LCOV_EXCL_START */
943 : return;
944 : /* LCOV_EXCL_STOP */
945 : }
946 :
- 947 6837675 : if (obj->count == 0) {
+ 947 6820724 : if (obj->count == 0) {
948 : /* LCOV_EXCL_START */
949 : log_fatal(EINTERNAL, "Internal inconsistency: Parity count zero for file '%s' at '%u'\n",
950 : obj->file->sub, obj->parity_pos);
@@ -1016,11 +1016,11 @@
954 : }
955 :
956 : /* check only if there is a previous block */
- 957 6837675 : if (!prev)
- 958 2855 : return;
+ 957 6820724 : if (!prev)
+ 958 2849 : return;
959 :
960 : /* check the order */
- 961 6834820 : if (prev->parity_pos >= obj->parity_pos) {
+ 961 6817875 : if (prev->parity_pos >= obj->parity_pos) {
962 : /* LCOV_EXCL_START */
963 : log_fatal(EINTERNAL, "Internal inconsistency: Parity order for files '%s' at '%u:%u' and '%s' at '%u:%u'\n",
964 : prev->file->sub, prev->parity_pos, prev->count, obj->file->sub, obj->parity_pos, obj->count);
@@ -1030,7 +1030,7 @@
968 : }
969 :
970 : /* check that the extents don't overlap */
- 971 6834820 : if (prev->parity_pos + prev->count > obj->parity_pos) {
+ 971 6817875 : if (prev->parity_pos + prev->count > obj->parity_pos) {
972 : /* LCOV_EXCL_START */
973 : log_fatal(EINTERNAL, "Internal inconsistency: Parity overlap for files '%s' at '%u:%u' and '%s' at '%u:%u'\n",
974 : prev->file->sub, prev->parity_pos, prev->count, obj->file->sub, obj->parity_pos, obj->count);
@@ -1040,23 +1040,23 @@
978 : }
979 : }
980 :
- 981 6837675 : static void extent_file_check_foreach_unlock(void* void_arg, void* void_obj)
+ 981 6820724 : static void extent_file_check_foreach_unlock(void* void_arg, void* void_obj)
982 : {
- 983 6837675 : struct extent_check* arg = void_arg;
- 984 6837675 : const struct snapraid_extent* obj = void_obj;
- 985 6837675 : const struct snapraid_extent* prev = arg->prev;
+ 983 6820724 : struct extent_check* arg = void_arg;
+ 984 6820724 : const struct snapraid_extent* obj = void_obj;
+ 985 6820724 : const struct snapraid_extent* prev = arg->prev;
986 :
987 : /* set the next previous block */
- 988 6837675 : arg->prev = obj;
+ 988 6820724 : arg->prev = obj;
989 :
990 : /* stop reporting if too many errors */
- 991 6837675 : if (arg->result > 100) {
+ 991 6820724 : if (arg->result > 100) {
992 : /* LCOV_EXCL_START */
993 : return;
994 : /* LCOV_EXCL_STOP */
995 : }
996 :
- 997 6837675 : if (obj->count == 0) {
+ 997 6820724 : if (obj->count == 0) {
998 : /* LCOV_EXCL_START */
999 : log_fatal(EINTERNAL, "Internal inconsistency: File count zero for file '%s' at '%u'\n",
1000 : obj->file->sub, obj->file_pos);
@@ -1068,9 +1068,9 @@
1006 : /* note that for deleted files, some extents may be missing */
1007 :
1008 : /* if the files are different */
- 1009 6837675 : if (!prev || prev->file != obj->file) {
- 1010 6791430 : if (prev != 0) {
- 1011 6788575 : if (file_flag_has(prev->file, FILE_IS_DELETED)) {
+ 1009 6820724 : if (!prev || prev->file != obj->file) {
+ 1010 6774697 : if (prev != 0) {
+ 1011 6771848 : if (file_flag_has(prev->file, FILE_IS_DELETED)) {
1012 : /* check that the extent doesn't overflow the file */
1013 59775 : if (prev->file_pos + prev->count > prev->file->blockmax) {
1014 : /* LCOV_EXCL_START */
@@ -1082,7 +1082,7 @@
1020 : }
1021 : } else {
1022 : /* check that the extent ends the file */
- 1023 6728800 : if (prev->file_pos + prev->count != prev->file->blockmax) {
+ 1023 6712073 : if (prev->file_pos + prev->count != prev->file->blockmax) {
1024 : /* LCOV_EXCL_START */
1025 : log_fatal(EINTERNAL, "Internal inconsistency: File end for file '%s' at '%u:%u' instead of size '%u'\n",
1026 : prev->file->sub, prev->file_pos, prev->count, prev->file->blockmax);
@@ -1093,7 +1093,7 @@
1031 : }
1032 : }
1033 :
- 1034 6791430 : if (file_flag_has(obj->file, FILE_IS_DELETED)) {
+ 1034 6774697 : if (file_flag_has(obj->file, FILE_IS_DELETED)) {
1035 : /* check that the extent doesn't overflow the file */
1036 59852 : if (obj->file_pos + obj->count > obj->file->blockmax) {
1037 : /* LCOV_EXCL_START */
@@ -1105,7 +1105,7 @@
1043 : }
1044 : } else {
1045 : /* check that the extent starts the file */
- 1046 6731578 : if (obj->file_pos != 0) {
+ 1046 6714845 : if (obj->file_pos != 0) {
1047 : /* LCOV_EXCL_START */
1048 : log_fatal(EINTERNAL, "Internal inconsistency: File start for file '%s' at '%u:%u'\n",
1049 : obj->file->sub, obj->file_pos, obj->count);
@@ -1116,7 +1116,7 @@
1054 : }
1055 : } else {
1056 : /* check the order */
- 1057 46245 : if (prev->file_pos >= obj->file_pos) {
+ 1057 46027 : if (prev->file_pos >= obj->file_pos) {
1058 : /* LCOV_EXCL_START */
1059 : log_fatal(EINTERNAL, "Internal inconsistency: File order for file '%s' at '%u:%u' and at '%u:%u'\n",
1060 : prev->file->sub, prev->file_pos, prev->count, obj->file_pos, obj->count);
@@ -1125,7 +1125,7 @@
1063 : /* LCOV_EXCL_STOP */
1064 : }
1065 :
- 1066 46245 : if (file_flag_has(obj->file, FILE_IS_DELETED)) {
+ 1066 46027 : if (file_flag_has(obj->file, FILE_IS_DELETED)) {
1067 : /* check that the extents don't overlap */
1068 27 : if (prev->file_pos + prev->count > obj->file_pos) {
1069 : /* LCOV_EXCL_START */
@@ -1137,7 +1137,7 @@
1075 : }
1076 : } else {
1077 : /* check that the extents are sequential */
- 1078 46218 : if (prev->file_pos + prev->count != obj->file_pos) {
+ 1078 46000 : if (prev->file_pos + prev->count != obj->file_pos) {
1079 : /* LCOV_EXCL_START */
1080 : log_fatal(EINTERNAL, "Internal inconsistency: File sequence for file '%s' at '%u:%u' and at '%u:%u'\n",
1081 : prev->file->sub, prev->file_pos, prev->count, obj->file_pos, obj->count);
@@ -1149,29 +1149,29 @@
1087 : }
1088 : }
1089 :
- 1090 3120 : int fs_check(struct snapraid_disk* disk)
+ 1090 3114 : int fs_check(struct snapraid_disk* disk)
1091 : {
1092 : struct extent_check arg;
1093 :
1094 : /* error count starts from 0 */
- 1095 3120 : arg.result = 0;
+ 1095 3114 : arg.result = 0;
1096 :
- 1097 3120 : fs_lock(disk);
+ 1097 3114 : fs_lock(disk);
1098 :
1099 : /* check parity sequence */
- 1100 3120 : arg.prev = 0;
- 1101 3120 : tommy_tree_foreach_arg(&disk->fs_parity, extent_parity_check_foreach_unlock, &arg);
+ 1100 3114 : arg.prev = 0;
+ 1101 3114 : tommy_tree_foreach_arg(&disk->fs_parity, extent_parity_check_foreach_unlock, &arg);
1102 :
1103 : /* check file sequence */
- 1104 3120 : arg.prev = 0;
- 1105 3120 : tommy_tree_foreach_arg(&disk->fs_file, extent_file_check_foreach_unlock, &arg);
+ 1104 3114 : arg.prev = 0;
+ 1105 3114 : tommy_tree_foreach_arg(&disk->fs_file, extent_file_check_foreach_unlock, &arg);
1106 :
- 1107 3120 : fs_unlock(disk);
+ 1107 3114 : fs_unlock(disk);
1108 :
- 1109 3120 : if (arg.result != 0)
+ 1109 3114 : if (arg.result != 0)
1110 0 : return -1;
1111 :
- 1112 3120 : return 0;
+ 1112 3114 : return 0;
1113 : }
1114 :
1115 : struct extent_parity_inside {
@@ -1181,17 +1181,17 @@
1119 : /**
1120 : * Compare the extent if containing the specified parity position.
1121 : */
- 1122 158551658 : static int extent_parity_inside_compare_unlock(const void* void_a, const void* void_b)
+ 1122 158133634 : static int extent_parity_inside_compare_unlock(const void* void_a, const void* void_b)
1123 : {
- 1124 158551658 : const struct extent_parity_inside* arg_a = void_a;
- 1125 158551658 : const struct snapraid_extent* arg_b = void_b;
+ 1124 158133634 : const struct extent_parity_inside* arg_a = void_a;
+ 1125 158133634 : const struct snapraid_extent* arg_b = void_b;
1126 :
- 1127 158551658 : if (arg_a->parity_pos < arg_b->parity_pos)
- 1128 58193079 : return -1;
- 1129 100358579 : if (arg_a->parity_pos >= arg_b->parity_pos + arg_b->count)
- 1130 87784588 : return 1;
+ 1127 158133634 : if (arg_a->parity_pos < arg_b->parity_pos)
+ 1128 58032399 : return -1;
+ 1129 100101235 : if (arg_a->parity_pos >= arg_b->parity_pos + arg_b->count)
+ 1130 87563112 : return 1;
1131 :
- 1132 12573991 : return 0;
+ 1132 12538123 : return 0;
1133 : }
1134 :
1135 : /**
@@ -1199,28 +1199,28 @@
1137 : * The search is optimized for sequential accesses.
1138 : * \return If not found return 0
1139 : */
- 1140 49968851 : static struct snapraid_extent* fs_par2extent_get_unlock(struct snapraid_disk* disk, struct snapraid_extent** fs_last, block_off_t parity_pos)
+ 1140 49874908 : static struct snapraid_extent* fs_par2extent_get_unlock(struct snapraid_disk* disk, struct snapraid_extent** fs_last, block_off_t parity_pos)
1141 : {
1142 : struct snapraid_extent* extent;
1143 :
1144 : /* check if the last accessed extent matches */
- 1145 49968851 : if (*fs_last
- 1146 49934657 : && parity_pos >= (*fs_last)->parity_pos
- 1147 49256770 : && parity_pos < (*fs_last)->parity_pos + (*fs_last)->count
+ 1145 49874908 : if (*fs_last
+ 1146 49840714 : && parity_pos >= (*fs_last)->parity_pos
+ 1147 49161414 : && parity_pos < (*fs_last)->parity_pos + (*fs_last)->count
1148 : ) {
- 1149 35471955 : extent = *fs_last;
+ 1149 35415936 : extent = *fs_last;
1150 : } else {
- 1151 14496896 : struct extent_parity_inside arg = { parity_pos };
- 1152 14496896 : extent = tommy_tree_search_compare(&disk->fs_parity, extent_parity_inside_compare_unlock, &arg);
+ 1151 14458972 : struct extent_parity_inside arg = { parity_pos };
+ 1152 14458972 : extent = tommy_tree_search_compare(&disk->fs_parity, extent_parity_inside_compare_unlock, &arg);
1153 : }
1154 :
- 1155 49968851 : if (!extent)
- 1156 1922905 : return 0;
+ 1155 49874908 : if (!extent)
+ 1156 1920849 : return 0;
1157 :
1158 : /* store the last accessed extent */
- 1159 48045946 : *fs_last = extent;
+ 1159 47954059 : *fs_last = extent;
1160 :
- 1161 48045946 : return extent;
+ 1161 47954059 : return extent;
1162 : }
1163 :
1164 : struct extent_file_inside {
@@ -1231,22 +1231,22 @@
1169 : /**
1170 : * Compare the extent if containing the specified file position.
1171 : */
- 1172 22976989 : static int extent_file_inside_compare_unlock(const void* void_a, const void* void_b)
+ 1172 22802303 : static int extent_file_inside_compare_unlock(const void* void_a, const void* void_b)
1173 : {
- 1174 22976989 : const struct extent_file_inside* arg_a = void_a;
- 1175 22976989 : const struct snapraid_extent* arg_b = void_b;
+ 1174 22802303 : const struct extent_file_inside* arg_a = void_a;
+ 1175 22802303 : const struct snapraid_extent* arg_b = void_b;
1176 :
- 1177 22976989 : if (arg_a->file < arg_b->file)
- 1178 9660370 : return -1;
- 1179 13316619 : if (arg_a->file > arg_b->file)
- 1180 11130615 : return 1;
+ 1177 22802303 : if (arg_a->file < arg_b->file)
+ 1178 9581099 : return -1;
+ 1179 13221204 : if (arg_a->file > arg_b->file)
+ 1180 11052341 : return 1;
1181 :
- 1182 2186004 : if (arg_a->file_pos < arg_b->file_pos)
- 1183 7579 : return -1;
- 1184 2178425 : if (arg_a->file_pos >= arg_b->file_pos + arg_b->count)
- 1185 8807 : return 1;
+ 1182 2168863 : if (arg_a->file_pos < arg_b->file_pos)
+ 1183 7628 : return -1;
+ 1184 2161235 : if (arg_a->file_pos >= arg_b->file_pos + arg_b->count)
+ 1185 8545 : return 1;
1186 :
- 1187 2169618 : return 0;
+ 1187 2152690 : return 0;
1188 : }
1189 :
1190 : /**
@@ -1254,88 +1254,88 @@
1192 : * The search is optimized for sequential accesses.
1193 : * \return If not found return 0
1194 : */
- 1195 10949888 : 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)
+ 1195 10908566 : 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)
1196 : {
1197 : struct snapraid_extent* extent;
1198 :
1199 : /* check if the last accessed extent matches */
- 1200 10949888 : if (*fs_last
- 1201 10927396 : && file == (*fs_last)->file
- 1202 8794650 : && file_pos >= (*fs_last)->file_pos
- 1203 8794650 : && file_pos < (*fs_last)->file_pos + (*fs_last)->count
+ 1200 10908566 : if (*fs_last
+ 1201 10886120 : && file == (*fs_last)->file
+ 1202 8770101 : && file_pos >= (*fs_last)->file_pos
+ 1203 8770101 : && file_pos < (*fs_last)->file_pos + (*fs_last)->count
1204 : ) {
- 1205 8780262 : extent = *fs_last;
+ 1205 8755868 : extent = *fs_last;
1206 : } else {
- 1207 2169626 : struct extent_file_inside arg = { file, file_pos };
- 1208 2169626 : extent = tommy_tree_search_compare(&disk->fs_file, extent_file_inside_compare_unlock, &arg);
+ 1207 2152698 : struct extent_file_inside arg = { file, file_pos };
+ 1208 2152698 : extent = tommy_tree_search_compare(&disk->fs_file, extent_file_inside_compare_unlock, &arg);
1209 : }
1210 :
- 1211 10949888 : if (!extent)
+ 1211 10908566 : if (!extent)
1212 8 : return 0;
1213 :
1214 : /* store the last accessed extent */
- 1215 10949880 : *fs_last = extent;
+ 1215 10908558 : *fs_last = extent;
1216 :
- 1217 10949880 : return extent;
+ 1217 10908558 : return extent;
1218 : }
1219 :
- 1220 49865865 : struct snapraid_file* fs_par2file_find(struct snapraid_disk* disk, block_off_t parity_pos, block_off_t* file_pos)
+ 1220 49771977 : struct snapraid_file* fs_par2file_find(struct snapraid_disk* disk, block_off_t parity_pos, block_off_t* file_pos)
1221 : {
1222 : struct snapraid_extent* extent;
1223 : struct snapraid_file* file;
1224 :
- 1225 49865865 : fs_lock(disk);
+ 1225 49771977 : fs_lock(disk);
1226 :
- 1227 49865865 : extent = fs_par2extent_get_unlock(disk, &disk->fs_last, parity_pos);
+ 1227 49771977 : extent = fs_par2extent_get_unlock(disk, &disk->fs_last, parity_pos);
1228 :
- 1229 49865865 : if (!extent) {
- 1230 1922905 : fs_unlock(disk);
- 1231 1922905 : return 0;
+ 1229 49771977 : if (!extent) {
+ 1230 1920849 : fs_unlock(disk);
+ 1231 1920849 : return 0;
1232 : }
1233 :
- 1234 47942960 : if (file_pos)
- 1235 47732115 : *file_pos = extent->file_pos + (parity_pos - extent->parity_pos);
+ 1234 47851128 : if (file_pos)
+ 1235 47640269 : *file_pos = extent->file_pos + (parity_pos - extent->parity_pos);
1236 :
- 1237 47942960 : file = extent->file;
+ 1237 47851128 : file = extent->file;
1238 :
- 1239 47942960 : fs_unlock(disk);
- 1240 47942960 : return file;
+ 1239 47851128 : fs_unlock(disk);
+ 1240 47851128 : return file;
1241 : }
1242 :
- 1243 5301463 : block_off_t fs_file2par_find(struct snapraid_disk* disk, struct snapraid_file* file, block_off_t file_pos)
+ 1243 5260119 : block_off_t fs_file2par_find(struct snapraid_disk* disk, struct snapraid_file* file, block_off_t file_pos)
1244 : {
1245 : struct snapraid_extent* extent;
1246 : block_off_t ret;
1247 :
- 1248 5301463 : fs_lock(disk);
+ 1248 5260119 : fs_lock(disk);
1249 :
- 1250 5301463 : extent = fs_file2extent_get_unlock(disk, &disk->fs_last, file, file_pos);
- 1251 5301463 : if (!extent) {
+ 1250 5260119 : extent = fs_file2extent_get_unlock(disk, &disk->fs_last, file, file_pos);
+ 1251 5260119 : if (!extent) {
1252 8 : fs_unlock(disk);
1253 8 : return POS_NULL;
1254 : }
1255 :
- 1256 5301455 : ret = extent->parity_pos + (file_pos - extent->file_pos);
+ 1256 5260111 : ret = extent->parity_pos + (file_pos - extent->file_pos);
1257 :
- 1258 5301455 : fs_unlock(disk);
- 1259 5301455 : return ret;
+ 1258 5260111 : fs_unlock(disk);
+ 1259 5260111 : return ret;
1260 : }
1261 :
- 1262 9473576 : void fs_allocate(struct snapraid_disk* disk, block_off_t parity_pos, struct snapraid_file* file, block_off_t file_pos)
+ 1262 9473620 : void fs_allocate(struct snapraid_disk* disk, block_off_t parity_pos, struct snapraid_file* file, block_off_t file_pos)
1263 : {
1264 : struct snapraid_extent* extent;
1265 : struct snapraid_extent* parity_extent;
1266 : struct snapraid_extent* file_extent;
1267 :
- 1268 9473576 : fs_lock(disk);
+ 1268 9473620 : fs_lock(disk);
1269 :
- 1270 9473576 : if (file_pos > 0) {
+ 1270 9473620 : if (file_pos > 0) {
1271 : /* search an existing extent for the previous file_pos */
- 1272 5648425 : extent = fs_file2extent_get_unlock(disk, &disk->fs_last, file, file_pos - 1);
+ 1272 5648447 : extent = fs_file2extent_get_unlock(disk, &disk->fs_last, file, file_pos - 1);
1273 :
- 1274 5648425 : if (extent != 0 && parity_pos == extent->parity_pos + extent->count) {
+ 1274 5648447 : if (extent != 0 && parity_pos == extent->parity_pos + extent->count) {
1275 : /* ensure that we are extending the extent at the end */
- 1276 5621562 : if (file_pos != extent->file_pos + extent->count) {
+ 1276 5621646 : if (file_pos != extent->file_pos + extent->count) {
1277 : /* LCOV_EXCL_START */
1278 : log_fatal(EINTERNAL, "Internal inconsistency: 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);
1279 : os_abort();
@@ -1343,21 +1343,21 @@
1281 : }
1282 :
1283 : /* extend the existing extent */
- 1284 5621562 : ++extent->count;
+ 1284 5621646 : ++extent->count;
1285 :
- 1286 5621562 : fs_unlock(disk);
- 1287 5621562 : return;
+ 1286 5621646 : fs_unlock(disk);
+ 1287 5621646 : return;
1288 : }
1289 : }
1290 :
1291 : /* a extent doesn't exist, and we have to create a new one */
- 1292 3852014 : extent = extent_alloc(parity_pos, file, file_pos, 1);
+ 1292 3851974 : extent = extent_alloc(parity_pos, file, file_pos, 1);
1293 :
1294 : /* insert the extent in the trees */
- 1295 3852014 : parity_extent = tommy_tree_insert(&disk->fs_parity, &extent->parity_node, extent);
- 1296 3852014 : file_extent = tommy_tree_insert(&disk->fs_file, &extent->file_node, extent);
+ 1295 3851974 : parity_extent = tommy_tree_insert(&disk->fs_parity, &extent->parity_node, extent);
+ 1296 3851974 : file_extent = tommy_tree_insert(&disk->fs_file, &extent->file_node, extent);
1297 :
- 1298 3852014 : if (parity_extent != extent || file_extent != extent) {
+ 1298 3851974 : if (parity_extent != extent || file_extent != extent) {
1299 : /* LCOV_EXCL_START */
1300 : log_fatal(EINTERNAL, "Internal inconsistency: 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);
1301 : os_abort();
@@ -1365,12 +1365,12 @@
1303 : }
1304 :
1305 : /* store the last accessed extent */
- 1306 3852014 : disk->fs_last = extent;
+ 1306 3851974 : disk->fs_last = extent;
1307 :
- 1308 3852014 : fs_unlock(disk);
+ 1308 3851974 : fs_unlock(disk);
1309 : }
1310 :
- 1311 102986 : void fs_deallocate(struct snapraid_disk* disk, block_off_t parity_pos)
+ 1311 102931 : void fs_deallocate(struct snapraid_disk* disk, block_off_t parity_pos)
1312 : {
1313 : struct snapraid_extent* extent;
1314 : struct snapraid_extent* second_extent;
@@ -1378,10 +1378,10 @@
1316 : struct snapraid_extent* file_extent;
1317 : block_off_t first_count, second_count;
1318 :
- 1319 102986 : fs_lock(disk);
+ 1319 102931 : fs_lock(disk);
1320 :
- 1321 102986 : extent = fs_par2extent_get_unlock(disk, &disk->fs_last, parity_pos);
- 1322 102986 : if (!extent) {
+ 1321 102931 : extent = fs_par2extent_get_unlock(disk, &disk->fs_last, parity_pos);
+ 1322 102931 : if (!extent) {
1323 : /* LCOV_EXCL_START */
1324 : log_fatal(EINTERNAL, "Internal inconsistency: Deallocating parity position '%u' for not existing extent in disk '%s'\n", parity_pos, disk->name);
1325 : os_abort();
@@ -1389,29 +1389,29 @@
1327 : }
1328 :
1329 : /* if it's the only block of the extent, delete it */
- 1330 102986 : if (extent->count == 1) {
+ 1330 102931 : if (extent->count == 1) {
1331 : /* remove from the trees */
- 1332 37865 : tommy_tree_remove(&disk->fs_parity, extent);
- 1333 37865 : tommy_tree_remove(&disk->fs_file, extent);
+ 1332 37850 : tommy_tree_remove(&disk->fs_parity, extent);
+ 1333 37850 : tommy_tree_remove(&disk->fs_file, extent);
1334 :
1335 : /* deallocate */
- 1336 37865 : extent_free(extent);
+ 1336 37850 : extent_free(extent);
1337 :
1338 : /* clear the last accessed extent */
- 1339 37865 : disk->fs_last = 0;
+ 1339 37850 : disk->fs_last = 0;
1340 :
- 1341 37865 : fs_unlock(disk);
- 1342 37865 : return;
+ 1341 37850 : fs_unlock(disk);
+ 1342 37850 : return;
1343 : }
1344 :
1345 : /* if it's at the start of the extent, shrink the extent */
- 1346 65121 : if (parity_pos == extent->parity_pos) {
- 1347 65118 : ++extent->parity_pos;
- 1348 65118 : ++extent->file_pos;
- 1349 65118 : --extent->count;
+ 1346 65081 : if (parity_pos == extent->parity_pos) {
+ 1347 65078 : ++extent->parity_pos;
+ 1348 65078 : ++extent->file_pos;
+ 1349 65078 : --extent->count;
1350 :
- 1351 65118 : fs_unlock(disk);
- 1352 65118 : return;
+ 1351 65078 : fs_unlock(disk);
+ 1352 65078 : return;
1353 : }
1354 :
1355 : /* if it's at the end of the extent, shrink the extent */
@@ -1449,28 +1449,28 @@
1387 2 : fs_unlock(disk);
1388 : }
1389 :
- 1390 56447214 : struct snapraid_block* fs_file2block_get(struct snapraid_file* file, block_off_t file_pos)
+ 1390 56273071 : struct snapraid_block* fs_file2block_get(struct snapraid_file* file, block_off_t file_pos)
1391 : {
- 1392 56447214 : if (file_pos >= file->blockmax) {
+ 1392 56273071 : if (file_pos >= file->blockmax) {
1393 : /* LCOV_EXCL_START */
1394 : log_fatal(EINTERNAL, "Internal inconsistency: Dereferencing file '%s' at position '%u/%u'\n", file->sub, file_pos, file->blockmax);
1395 : os_abort();
1396 : /* LCOV_EXCL_STOP */
1397 : }
1398 :
- 1399 56447214 : return file_block(file, file_pos);
+ 1399 56273071 : return file_block(file, file_pos);
1400 : }
1401 :
- 1402 38360216 : struct snapraid_block* fs_par2block_find(struct snapraid_disk* disk, block_off_t parity_pos)
+ 1402 38266700 : struct snapraid_block* fs_par2block_find(struct snapraid_disk* disk, block_off_t parity_pos)
1403 : {
1404 : struct snapraid_file* file;
1405 : block_off_t file_pos;
1406 :
- 1407 38360216 : file = fs_par2file_find(disk, parity_pos, &file_pos);
- 1408 38360216 : if (file == 0)
- 1409 1922905 : return BLOCK_NULL;
+ 1407 38266700 : file = fs_par2file_find(disk, parity_pos, &file_pos);
+ 1408 38266700 : if (file == 0)
+ 1409 1920849 : return BLOCK_NULL;
1410 :
- 1411 36437311 : return fs_file2block_get(file, file_pos);
+ 1411 36345851 : return fs_file2block_get(file, file_pos);
1412 : }
1413 :
1414 1627 : struct snapraid_map* map_alloc(const char* name, unsigned position, block_off_t total_blocks, block_off_t free_blocks, const char* uuid)
@@ -1495,78 +1495,78 @@
1433 : /****************************************************************************/
1434 : /* bucket */
1435 :
- 1436 711 : static int bucket_cmp(const void* void_a, const void* void_b)
+ 1436 521 : static int bucket_cmp(const void* void_a, const void* void_b)
1437 : {
- 1438 711 : const struct snapraid_bucket* a = void_a;
- 1439 711 : const struct snapraid_bucket* b = void_b;
- 1440 711 : if (a->time_at < b->time_at)
- 1441 355 : return -1;
- 1442 356 : if (a->time_at > b->time_at)
- 1443 356 : return 1;
+ 1438 521 : const struct snapraid_bucket* a = void_a;
+ 1439 521 : const struct snapraid_bucket* b = void_b;
+ 1440 521 : if (a->time_at < b->time_at)
+ 1441 314 : return -1;
+ 1442 207 : if (a->time_at > b->time_at)
+ 1443 207 : return 1;
1444 0 : return 0;
1445 : }
1446 :
- 1447 746 : void bucket_free(struct snapraid_bucket* bucket)
+ 1447 705 : void bucket_free(struct snapraid_bucket* bucket)
1448 : {
- 1449 746 : free(bucket);
- 1450 746 : }
+ 1449 705 : free(bucket);
+ 1450 705 : }
1451 :
- 1452 72052 : void bucket_insert(tommy_hashdyn* bucket_hash, time_t time_at, block_off_t count, int justsynced)
+ 1452 55958 : void bucket_insert(tommy_hashdyn* bucket_hash, time_t time_at, block_off_t count, int justsynced)
1453 : {
- 1454 72052 : tommy_hash_t hash = tommy_inthash_u64(time_at);
- 1455 72052 : tommy_node* i = tommy_hashdyn_bucket(bucket_hash, hash);
- 1456 72078 : while (i) {
- 1457 71322 : struct snapraid_bucket* entry = i->data;
- 1458 71322 : if (entry->time_at == time_at) {
- 1459 71296 : if (justsynced)
- 1460 43455 : entry->count_justsynced += count;
+ 1454 55958 : tommy_hash_t hash = tommy_inthash_u64(time_at);
+ 1455 55958 : tommy_node* i = tommy_hashdyn_bucket(bucket_hash, hash);
+ 1456 55958 : while (i) {
+ 1457 55242 : struct snapraid_bucket* entry = i->data;
+ 1458 55242 : if (entry->time_at == time_at) {
+ 1459 55242 : if (justsynced)
+ 1460 27409 : entry->count_justsynced += count;
1461 : else
- 1462 27841 : entry->count_scrubbed += count;
- 1463 71296 : return;
+ 1462 27833 : entry->count_scrubbed += count;
+ 1463 55242 : return;
1464 : }
- 1465 26 : i = i->next;
+ 1465 0 : i = i->next;
1466 : }
1467 :
- 1468 756 : struct snapraid_bucket* entry = malloc_nofail(sizeof(struct snapraid_bucket));
- 1469 756 : entry->time_at = time_at;
- 1470 756 : if (justsynced) {
- 1471 683 : entry->count_justsynced = count;
- 1472 683 : entry->count_scrubbed = 0;
+ 1468 716 : struct snapraid_bucket* entry = malloc_nofail(sizeof(struct snapraid_bucket));
+ 1469 716 : entry->time_at = time_at;
+ 1470 716 : if (justsynced) {
+ 1471 643 : entry->count_justsynced = count;
+ 1472 643 : entry->count_scrubbed = 0;
1473 : } else {
1474 73 : entry->count_justsynced = 0;
1475 73 : entry->count_scrubbed = count;
1476 : }
1477 :
- 1478 756 : tommy_hashdyn_insert(bucket_hash, &entry->node, entry, hash);
+ 1478 716 : tommy_hashdyn_insert(bucket_hash, &entry->node, entry, hash);
1479 : }
1480 :
- 1481 421 : void bucket_to_list(tommy_hashdyn* bucket_hash, tommy_list* bucket_list, block_off_t* bucketcount)
+ 1481 420 : void bucket_to_list(tommy_hashdyn* bucket_hash, tommy_list* bucket_list, block_off_t* bucketcount)
1482 : {
1483 : /* clear previous list */
- 1484 421 : tommy_list_foreach(bucket_list, (tommy_foreach_func*)bucket_free);
- 1485 421 : tommy_list_init(bucket_list);
+ 1484 420 : tommy_list_foreach(bucket_list, (tommy_foreach_func*)bucket_free);
+ 1485 420 : tommy_list_init(bucket_list);
1486 :
- 1487 421 : log_tag("list:bucket_begin\n");
+ 1487 420 : log_tag("list:bucket_begin\n");
1488 :
- 1489 421 : log_tag("bucket:count:%" PRIu64 "\n", (uint64_t)tommy_hashdyn_count(bucket_hash));
+ 1489 420 : log_tag("bucket:count:%" PRIu64 "\n", (uint64_t)tommy_hashdyn_count(bucket_hash));
1490 :
- 1491 421 : tommy_hashdyn_to_list(bucket_hash, bucket_list);
+ 1491 420 : tommy_hashdyn_to_list(bucket_hash, bucket_list);
1492 :
- 1493 421 : tommy_list_sort(bucket_list, bucket_cmp);
+ 1493 420 : tommy_list_sort(bucket_list, bucket_cmp);
1494 :
- 1495 421 : block_off_t count = 0;
- 1496 1177 : for (tommy_node* i = tommy_list_head(bucket_list); i != 0; i = i->next) {
- 1497 756 : struct snapraid_bucket* entry = i->data;
- 1498 756 : count += entry->count_scrubbed + entry->count_justsynced;
- 1499 756 : log_tag("bucket:entry:%" PRIu64 ":%u:%u\n", (uint64_t)entry->time_at, entry->count_scrubbed, entry->count_justsynced);
+ 1495 420 : block_off_t count = 0;
+ 1496 1136 : for (tommy_node* i = tommy_list_head(bucket_list); i != 0; i = i->next) {
+ 1497 716 : struct snapraid_bucket* entry = i->data;
+ 1498 716 : count += entry->count_scrubbed + entry->count_justsynced;
+ 1499 716 : log_tag("bucket:entry:%" PRIu64 ":%u:%u\n", (uint64_t)entry->time_at, entry->count_scrubbed, entry->count_justsynced);
1500 : }
1501 :
- 1502 421 : log_tag("bucket:block_count:%u\n", count);
+ 1502 420 : log_tag("bucket:block_count:%u\n", count);
1503 :
- 1504 421 : log_tag("list:bucket_end\n");
+ 1504 420 : log_tag("list:bucket_end\n");
1505 :
- 1506 421 : *bucketcount = count;
- 1507 421 : }
+ 1506 420 : *bucketcount = count;
+ 1507 420 : }
1508 :
1509 : /****************************************************************************/
1510 : /* format */
@@ -1585,14 +1585,14 @@
1523 : /**
1524 : * Format a path name for terminal reference
1525 : */
- 1526 366067 : const char* fmt_term(const struct snapraid_disk* disk, const char* str, char* buffer)
+ 1526 366236 : const char* fmt_term(const struct snapraid_disk* disk, const char* str, char* buffer)
1527 : {
1528 : const char* out[3];
1529 :
- 1530 366067 : switch (FMT_MODE) {
- 1531 342002 : case FMT_FILE :
+ 1530 366236 : switch (FMT_MODE) {
+ 1531 342171 : case FMT_FILE :
1532 : default :
- 1533 342002 : return esc_shell(str, buffer);
+ 1533 342171 : return esc_shell(str, buffer);
1534 12030 : case FMT_DISK :
1535 12030 : out[0] = disk->name;
1536 12030 : out[1] = ":";
diff --git a/cov/cmdline/elem.h.func-sort-c.html b/cov/cmdline/elem.h.func-sort-c.html
index a7fb7cd8..038b35bf 100644
--- a/cov/cmdline/elem.h.func-sort-c.html
+++ b/cov/cmdline/elem.h.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -77,7 +77,7 @@
| info_set_bad |
- 1771 |
+ 1772 |
| info_set_rehash |
@@ -85,7 +85,7 @@
| file_flag_clear |
- 12545 |
+ 13077 |
| fs_par2block_get |
@@ -93,7 +93,7 @@
| info_get_justsynced |
- 23836 |
+ 18930 |
| link_flag_set |
@@ -101,11 +101,11 @@
| hash_is_unique |
- 44043 |
+ 43988 |
| link_flag_get |
- 96285 |
+ 95741 |
| hash_zero_set |
@@ -117,7 +117,7 @@
| info_make |
- 191697 |
+ 180457 |
| link_flag_has |
@@ -125,103 +125,103 @@
| block_has_file_and_valid_parity |
- 226094 |
+ 226098 |
| info_get_bad |
- 247612 |
+ 242727 |
| hash_is_invalid |
- 756505 |
+ 756707 |
| hash_is_zero |
- 760014 |
+ 760217 |
| info_get_time |
- 798417 |
+ 786514 |
| info_set |
- 1757573 |
+ 1757522 |
| info_get_rehash |
- 2048435 |
+ 2036469 |
| block_has_updated_hash |
- 2188335 |
+ 2188345 |
| block_has_past_hash |
- 2686312 |
+ 2686411 |
| info_get |
- 3171512 |
+ 3152579 |
| filter_hidden |
- 3231524 |
+ 3231650 |
| file_path_hash |
- 4002881 |
+ 4002848 |
| fs_file2par_get |
- 4959524 |
+ 4918180 |
| file_inode_hash |
- 5220350 |
+ 5220892 |
| file_flag_set |
- 5792498 |
+ 5793396 |
| file_stamp_hash |
- 6390305 |
+ 6390630 |
| hash_invalid_set |
- 9532465 |
+ 9532509 |
| fs_par2file_get |
- 11505649 |
+ 11505277 |
| block_state_set |
- 19703104 |
+ 19702751 |
| block_has_invalid_parity |
- 23228801 |
+ 23186776 |
| block_has_file |
- 25304571 |
+ 25253088 |
| file_flag_has |
- 39608750 |
+ 39575710 |
| file_block |
- 66152513 |
+ 65978414 |
| block_sizeof |
- 69982896 |
+ 69808821 |
| block_state_get |
- 74577257 |
+ 74400305 |
diff --git a/cov/cmdline/elem.h.func.html b/cov/cmdline/elem.h.func.html
index bf49b1bf..3a131467 100644
--- a/cov/cmdline/elem.h.func.html
+++ b/cov/cmdline/elem.h.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,35 +61,35 @@
| block_has_file |
- 25304571 |
+ 25253088 |
| block_has_file_and_valid_parity |
- 226094 |
+ 226098 |
| block_has_invalid_parity |
- 23228801 |
+ 23186776 |
| block_has_past_hash |
- 2686312 |
+ 2686411 |
| block_has_updated_hash |
- 2188335 |
+ 2188345 |
| block_sizeof |
- 69982896 |
+ 69808821 |
| block_state_get |
- 74577257 |
+ 74400305 |
| block_state_set |
- 19703104 |
+ 19702751 |
| dir_flag_has |
@@ -105,39 +105,39 @@
| file_block |
- 66152513 |
+ 65978414 |
| file_flag_clear |
- 12545 |
+ 13077 |
| file_flag_has |
- 39608750 |
+ 39575710 |
| file_flag_set |
- 5792498 |
+ 5793396 |
| file_inode_hash |
- 5220350 |
+ 5220892 |
| file_path_hash |
- 4002881 |
+ 4002848 |
| file_stamp_hash |
- 6390305 |
+ 6390630 |
| filter_hidden |
- 3231524 |
+ 3231650 |
| fs_file2par_get |
- 4959524 |
+ 4918180 |
| fs_par2block_get |
@@ -145,23 +145,23 @@
| fs_par2file_get |
- 11505649 |
+ 11505277 |
| hash_invalid_set |
- 9532465 |
+ 9532509 |
| hash_is_invalid |
- 756505 |
+ 756707 |
| hash_is_unique |
- 44043 |
+ 43988 |
| hash_is_zero |
- 760014 |
+ 760217 |
| hash_zero_set |
@@ -169,35 +169,35 @@
| info_get |
- 3171512 |
+ 3152579 |
| info_get_bad |
- 247612 |
+ 242727 |
| info_get_justsynced |
- 23836 |
+ 18930 |
| info_get_rehash |
- 2048435 |
+ 2036469 |
| info_get_time |
- 798417 |
+ 786514 |
| info_make |
- 191697 |
+ 180457 |
| info_set |
- 1757573 |
+ 1757522 |
| info_set_bad |
- 1771 |
+ 1772 |
| info_set_rehash |
@@ -205,7 +205,7 @@
| link_flag_get |
- 96285 |
+ 95741 |
| link_flag_has |
diff --git a/cov/cmdline/elem.h.gcov.html b/cov/cmdline/elem.h.gcov.html
index 39ac75c1..7fbcc909 100644
--- a/cov/cmdline/elem.h.gcov.html
+++ b/cov/cmdline/elem.h.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -594,13 +594,13 @@
532 : * Filter hidden files.
533 : * Return !=0 if it matches and it should be excluded.
534 : */
- 535 3231524 : static inline int filter_hidden(int enable, struct dirent* dd)
+ 535 3231650 : static inline int filter_hidden(int enable, struct dirent* dd)
536 : {
- 537 3231524 : if (enable && dirent_hidden(dd)) {
+ 537 3231650 : if (enable && dirent_hidden(dd)) {
538 0 : return 1; /* filter out */
539 : }
540 :
- 541 3231524 : return 0;
+ 541 3231650 : return 0;
542 : }
543 :
544 : /**
@@ -651,17 +651,17 @@
589 : *
590 : * If working with reduced hash lengths, this function always return 0.
591 : */
- 592 756505 : static inline int hash_is_invalid(const unsigned char* hash)
+ 592 756707 : static inline int hash_is_invalid(const unsigned char* hash)
593 : {
594 : int i;
595 :
596 : /* if the hash is reduced, we cannot grant that it's a specific kind of hash */
- 597 756505 : if (BLOCK_HASH_SIZE != HASH_MAX)
+ 597 756707 : if (BLOCK_HASH_SIZE != HASH_MAX)
598 0 : return 0;
599 :
- 600 1176105 : for (i = 0; i < BLOCK_HASH_SIZE; ++i)
- 601 1150041 : if (hash[i] != 0x00)
- 602 730441 : return 0;
+ 600 1176704 : for (i = 0; i < BLOCK_HASH_SIZE; ++i)
+ 601 1150640 : if (hash[i] != 0x00)
+ 602 730643 : return 0;
603 :
604 26064 : return 1;
605 : }
@@ -673,17 +673,17 @@
611 : *
612 : * If working with reduced hash lengths, this function always return 0.
613 : */
- 614 760014 : static inline int hash_is_zero(const unsigned char* hash)
+ 614 760217 : static inline int hash_is_zero(const unsigned char* hash)
615 : {
616 : int i;
617 :
618 : /* if the hash is reduced, we cannot grant that it's a specific kind of hash */
- 619 760014 : if (BLOCK_HASH_SIZE != HASH_MAX)
+ 619 760217 : if (BLOCK_HASH_SIZE != HASH_MAX)
620 0 : return 0;
621 :
- 622 1027474 : for (i = 0; i < BLOCK_HASH_SIZE; ++i)
- 623 1010957 : if (hash[i] != 0xFF)
- 624 743497 : return 0;
+ 622 1027299 : for (i = 0; i < BLOCK_HASH_SIZE; ++i)
+ 623 1010782 : if (hash[i] != 0xFF)
+ 624 743700 : return 0;
625 :
626 16517 : return 1;
627 : }
@@ -693,22 +693,22 @@
631 : *
632 : * If working with reduced hash lengths, this function always return 0.
633 : */
- 634 44043 : static inline int hash_is_unique(const unsigned char* hash)
+ 634 43988 : static inline int hash_is_unique(const unsigned char* hash)
635 : {
636 : /* if the hash is reduced, we cannot grant that it's a specific kind of hash */
- 637 44043 : if (BLOCK_HASH_SIZE != HASH_MAX)
+ 637 43988 : if (BLOCK_HASH_SIZE != HASH_MAX)
638 0 : return 0;
639 :
- 640 44043 : return !hash_is_zero(hash) && !hash_is_invalid(hash);
+ 640 43988 : return !hash_is_zero(hash) && !hash_is_invalid(hash);
641 : }
642 :
643 : /**
644 : * Set the hash to the special INVALID value.
645 : */
- 646 9532465 : static inline void hash_invalid_set(unsigned char* hash)
+ 646 9532509 : static inline void hash_invalid_set(unsigned char* hash)
647 : {
- 648 9532465 : memset(hash, 0x00, BLOCK_HASH_SIZE);
- 649 9532465 : }
+ 648 9532509 : memset(hash, 0x00, BLOCK_HASH_SIZE);
+ 649 9532509 : }
650 :
651 : /**
652 : * Set the hash to the special ZERO value.
@@ -721,9 +721,9 @@
659 : /**
660 : * Allocated space for block.
661 : */
- 662 69982896 : static inline size_t block_sizeof(void)
+ 662 69808821 : static inline size_t block_sizeof(void)
663 : {
- 664 69982896 : return 1 + BLOCK_HASH_SIZE;
+ 664 69808821 : return 1 + BLOCK_HASH_SIZE;
665 : }
666 :
667 : /**
@@ -732,32 +732,32 @@
670 : * For this function, it's allowed to pass a NULL block
671 : * pointer than results in the BLOCK_STATE_EMPTY state.
672 : */
- 673 74577257 : static inline unsigned block_state_get(const struct snapraid_block* block)
+ 673 74400305 : static inline unsigned block_state_get(const struct snapraid_block* block)
674 : {
- 675 74577257 : if (block == BLOCK_NULL)
- 676 2302380 : return BLOCK_STATE_EMPTY;
+ 675 74400305 : if (block == BLOCK_NULL)
+ 676 2299617 : return BLOCK_STATE_EMPTY;
677 :
- 678 72274877 : return block->state;
+ 678 72100688 : return block->state;
679 : }
680 :
681 : /**
682 : * Set the state of the block.
683 : */
- 684 19703104 : static inline void block_state_set(struct snapraid_block* block, unsigned state)
+ 684 19702751 : static inline void block_state_set(struct snapraid_block* block, unsigned state)
685 : {
- 686 19703104 : block->state = state;
- 687 19703104 : }
+ 686 19702751 : block->state = state;
+ 687 19702751 : }
688 :
689 : /**
690 : * Check if the specified block has an updated hash.
691 : *
692 : * Note that EMPTY / CHG / DELETED return 0.
693 : */
- 694 2188335 : static inline int block_has_updated_hash(const struct snapraid_block* block)
+ 694 2188345 : static inline int block_has_updated_hash(const struct snapraid_block* block)
695 : {
- 696 2188335 : unsigned state = block_state_get(block);
+ 696 2188345 : unsigned state = block_state_get(block);
697 :
- 698 2188335 : return state == BLOCK_STATE_BLK || state == BLOCK_STATE_REP;
+ 698 2188345 : return state == BLOCK_STATE_BLK || state == BLOCK_STATE_REP;
699 : }
700 :
701 : /**
@@ -766,11 +766,11 @@
704 : *
705 : * Note that EMPTY / BLK / REP return 0.
706 : */
- 707 2686312 : static inline int block_has_past_hash(const struct snapraid_block* block)
+ 707 2686411 : static inline int block_has_past_hash(const struct snapraid_block* block)
708 : {
- 709 2686312 : unsigned state = block_state_get(block);
+ 709 2686411 : unsigned state = block_state_get(block);
710 :
- 711 2686312 : return state == BLOCK_STATE_CHG || state == BLOCK_STATE_DELETED;
+ 711 2686411 : return state == BLOCK_STATE_CHG || state == BLOCK_STATE_DELETED;
712 : }
713 :
714 : /**
@@ -778,12 +778,12 @@
716 : *
717 : * Note that EMPTY / DELETED return 0.
718 : */
- 719 25304571 : static inline int block_has_file(const struct snapraid_block* block)
+ 719 25253088 : static inline int block_has_file(const struct snapraid_block* block)
720 : {
- 721 25304571 : unsigned state = block_state_get(block);
+ 721 25253088 : unsigned state = block_state_get(block);
722 :
723 : return state == BLOCK_STATE_BLK
- 724 25304571 : || state == BLOCK_STATE_CHG || state == BLOCK_STATE_REP;
+ 724 25253088 : || state == BLOCK_STATE_CHG || state == BLOCK_STATE_REP;
725 : }
726 :
727 : /**
@@ -791,12 +791,12 @@
729 : *
730 : * Note that EMPTY / BLK return 0.
731 : */
- 732 23228801 : static inline int block_has_invalid_parity(const struct snapraid_block* block)
+ 732 23186776 : static inline int block_has_invalid_parity(const struct snapraid_block* block)
733 : {
- 734 23228801 : unsigned state = block_state_get(block);
+ 734 23186776 : unsigned state = block_state_get(block);
735 :
736 : return state == BLOCK_STATE_DELETED
- 737 23228801 : || state == BLOCK_STATE_CHG || state == BLOCK_STATE_REP;
+ 737 23186776 : || state == BLOCK_STATE_CHG || state == BLOCK_STATE_REP;
738 : }
739 :
740 : /**
@@ -804,27 +804,27 @@
742 : *
743 : * Note that anything different than BLK return 0.
744 : */
- 745 226094 : static inline int block_has_file_and_valid_parity(const struct snapraid_block* block)
+ 745 226098 : static inline int block_has_file_and_valid_parity(const struct snapraid_block* block)
746 : {
- 747 226094 : unsigned state = block_state_get(block);
+ 747 226098 : unsigned state = block_state_get(block);
748 :
- 749 226094 : return state == BLOCK_STATE_BLK;
+ 749 226098 : return state == BLOCK_STATE_BLK;
750 : }
751 :
- 752 39608750 : static inline int file_flag_has(const struct snapraid_file* file, unsigned mask)
+ 752 39575710 : static inline int file_flag_has(const struct snapraid_file* file, unsigned mask)
753 : {
- 754 39608750 : return (file->flag & mask) == mask;
+ 754 39575710 : return (file->flag & mask) == mask;
755 : }
756 :
- 757 5792498 : static inline void file_flag_set(struct snapraid_file* file, unsigned mask)
+ 757 5793396 : static inline void file_flag_set(struct snapraid_file* file, unsigned mask)
758 : {
- 759 5792498 : file->flag |= mask;
- 760 5792498 : }
+ 759 5793396 : file->flag |= mask;
+ 760 5793396 : }
761 :
- 762 12545 : static inline void file_flag_clear(struct snapraid_file* file, unsigned mask)
+ 762 13077 : static inline void file_flag_clear(struct snapraid_file* file, unsigned mask)
763 : {
- 764 12545 : file->flag &= ~mask;
- 765 12545 : }
+ 764 13077 : file->flag &= ~mask;
+ 765 13077 : }
766 :
767 : /**
768 : * Allocate a file.
@@ -856,11 +856,11 @@
794 : *
795 : * Note that the block size if a runtime value.
796 : */
- 797 66152513 : static inline struct snapraid_block* file_block(struct snapraid_file* file, size_t pos)
+ 797 65978414 : static inline struct snapraid_block* file_block(struct snapraid_file* file, size_t pos)
798 : {
- 799 66152513 : unsigned char* ptr = (unsigned char*)file->blockvec;
+ 799 65978414 : unsigned char* ptr = (unsigned char*)file->blockvec;
800 :
- 801 66152513 : return (struct snapraid_block*)(ptr + pos * block_sizeof());
+ 801 65978414 : return (struct snapraid_block*)(ptr + pos * block_sizeof());
802 : }
803 :
804 : /**
@@ -902,9 +902,9 @@
840 : /**
841 : * Compute the hash of a file inode.
842 : */
- 843 5220350 : static inline tommy_uint32_t file_inode_hash(uint64_t inode)
+ 843 5220892 : static inline tommy_uint32_t file_inode_hash(uint64_t inode)
844 : {
- 845 5220350 : return (tommy_uint32_t)tommy_inthash_u64(inode);
+ 845 5220892 : return (tommy_uint32_t)tommy_inthash_u64(inode);
846 : }
847 :
848 : /**
@@ -923,17 +923,17 @@
861 : /**
862 : * Compute the hash of a file path.
863 : */
- 864 4002881 : static inline tommy_uint32_t file_path_hash(const char* sub)
+ 864 4002848 : static inline tommy_uint32_t file_path_hash(const char* sub)
865 : {
- 866 4002881 : return tommy_hash_u32(0, sub, strlen(sub));
+ 866 4002848 : return tommy_hash_u32(0, sub, strlen(sub));
867 : }
868 :
869 : /**
870 : * Compute the hash of a file stamp.
871 : */
- 872 6390305 : static inline tommy_uint32_t file_stamp_hash(data_off_t size, int64_t mtime_sec, int mtime_nsec)
+ 872 6390630 : static inline tommy_uint32_t file_stamp_hash(data_off_t size, int64_t mtime_sec, int mtime_nsec)
873 : {
- 874 6390305 : return tommy_inthash_u32((tommy_uint32_t)size ^ tommy_inthash_u32(mtime_sec ^ tommy_inthash_u32(mtime_nsec)));
+ 874 6390630 : return tommy_inthash_u32((tommy_uint32_t)size ^ tommy_inthash_u32(mtime_sec ^ tommy_inthash_u32(mtime_nsec)));
875 : }
876 :
877 : /**
@@ -977,9 +977,9 @@
915 6 : slink->flag |= flag & mask;
916 6 : }
917 :
- 918 96285 : static inline unsigned link_flag_get(struct snapraid_link* slink, unsigned mask)
+ 918 95741 : static inline unsigned link_flag_get(struct snapraid_link* slink, unsigned mask)
919 : {
- 920 96285 : return slink->flag & mask;
+ 920 95741 : return slink->flag & mask;
921 : }
922 :
923 : /**
@@ -1111,19 +1111,19 @@
1049 : /**
1050 : * Get the file position from the parity position.
1051 : */
- 1052 11505649 : static inline struct snapraid_file* fs_par2file_get(struct snapraid_disk* disk, block_off_t parity_pos, block_off_t* file_pos)
+ 1052 11505277 : static inline struct snapraid_file* fs_par2file_get(struct snapraid_disk* disk, block_off_t parity_pos, block_off_t* file_pos)
1053 : {
1054 : struct snapraid_file* ret;
1055 :
- 1056 11505649 : ret = fs_par2file_find(disk, parity_pos, file_pos);
- 1057 11505649 : if (ret == 0) {
+ 1056 11505277 : ret = fs_par2file_find(disk, parity_pos, file_pos);
+ 1057 11505277 : if (ret == 0) {
1058 : /* LCOV_EXCL_START */
1059 : log_fatal(EINTERNAL, "Internal inconsistency: Deresolving parity to file at position '%u' in disk '%s'\n", parity_pos, disk->name);
1060 : os_abort();
1061 : /* LCOV_EXCL_STOP */
1062 : }
1063 :
- 1064 11505649 : return ret;
+ 1064 11505277 : return ret;
1065 : }
1066 :
1067 : /**
@@ -1135,19 +1135,19 @@
1073 : /**
1074 : * Get the parity position from the file position.
1075 : */
- 1076 4959524 : static inline block_off_t fs_file2par_get(struct snapraid_disk* disk, struct snapraid_file* file, block_off_t file_pos)
+ 1076 4918180 : static inline block_off_t fs_file2par_get(struct snapraid_disk* disk, struct snapraid_file* file, block_off_t file_pos)
1077 : {
1078 : block_off_t ret;
1079 :
- 1080 4959524 : ret = fs_file2par_find(disk, file, file_pos);
- 1081 4959524 : if (ret == POS_NULL) {
+ 1080 4918180 : ret = fs_file2par_find(disk, file, file_pos);
+ 1081 4918180 : if (ret == POS_NULL) {
1082 : /* LCOV_EXCL_START */
1083 : log_fatal(EINTERNAL, "Internal inconsistency: Resolving file '%s' at position '%u/%u' in disk '%s'\n", file->sub, file_pos, file->blockmax, disk->name);
1084 : os_abort();
1085 : /* LCOV_EXCL_STOP */
1086 : }
1087 :
- 1088 4959524 : return ret;
+ 1088 4918180 : return ret;
1089 : }
1090 :
1091 : /**
@@ -1195,18 +1195,18 @@
1133 : /**
1134 : * Make an info.
1135 : */
- 1136 191697 : static inline snapraid_info info_make(time_t last_access, int error, int rehash, int justsynced)
+ 1136 180457 : static inline snapraid_info info_make(time_t last_access, int error, int rehash, int justsynced)
1137 : {
1138 : /* clear the lowest bits as reserved for other information */
- 1139 191697 : snapraid_info info = last_access & ~INFO_MASK;
+ 1139 180457 : snapraid_info info = last_access & ~INFO_MASK;
1140 :
- 1141 191697 : if (error != 0)
- 1142 5274 : info |= 0x1;
- 1143 191697 : if (rehash != 0)
- 1144 14426 : info |= 0x2;
- 1145 191697 : if (justsynced != 0)
- 1146 145610 : info |= 0x4;
- 1147 191697 : return info;
+ 1141 180457 : if (error != 0)
+ 1142 5276 : info |= 0x1;
+ 1143 180457 : if (rehash != 0)
+ 1144 14181 : info |= 0x2;
+ 1145 180457 : if (justsynced != 0)
+ 1146 134376 : info |= 0x4;
+ 1147 180457 : return info;
1148 : }
1149 :
1150 : /**
@@ -1214,44 +1214,44 @@
1152 : * This is the last time when the block was know to be correct.
1153 : * The "scrubbed" info tells if the time is referring at the latest sync or scrub.
1154 : */
- 1155 798417 : static inline time_t info_get_time(snapraid_info info)
+ 1155 786514 : static inline time_t info_get_time(snapraid_info info)
1156 : {
- 1157 798417 : return info & ~INFO_MASK;
+ 1157 786514 : return info & ~INFO_MASK;
1158 : }
1159 :
1160 : /**
1161 : * Extract the error information.
1162 : * Report if the block address had some problem.
1163 : */
- 1164 247612 : static inline int info_get_bad(snapraid_info info)
+ 1164 242727 : static inline int info_get_bad(snapraid_info info)
1165 : {
- 1166 247612 : return (info & 0x1) != 0;
+ 1166 242727 : return (info & 0x1) != 0;
1167 : }
1168 :
1169 : /**
1170 : * Extract the rehash information.
1171 : * Report if the block address is using the old hash and needs to be rehashed.
1172 : */
- 1173 2048435 : static inline int info_get_rehash(snapraid_info info)
+ 1173 2036469 : static inline int info_get_rehash(snapraid_info info)
1174 : {
- 1175 2048435 : return (info & 0x2) != 0;
+ 1175 2036469 : return (info & 0x2) != 0;
1176 : }
1177 :
1178 : /**
1179 : * Extract the scrubbed information.
1180 : * Report if the block address was never scrubbed.
1181 : */
- 1182 23836 : static inline int info_get_justsynced(snapraid_info info)
+ 1182 18930 : static inline int info_get_justsynced(snapraid_info info)
1183 : {
- 1184 23836 : return (info & 0x4) != 0;
+ 1184 18930 : return (info & 0x4) != 0;
1185 : }
1186 :
1187 : /**
1188 : * Mark the block address as with error.
1189 : */
- 1190 1771 : static inline snapraid_info info_set_bad(snapraid_info info)
+ 1190 1772 : static inline snapraid_info info_set_bad(snapraid_info info)
1191 : {
- 1192 1771 : return info | 0x1;
+ 1192 1772 : return info | 0x1;
1193 : }
1194 :
1195 : /**
@@ -1266,27 +1266,27 @@
1204 : * Set the info at the specified position.
1205 : * The position is allocated if not yet done.
1206 : */
- 1207 1757573 : static inline void info_set(tommy_arrayblkof* array, block_off_t pos, snapraid_info info)
+ 1207 1757522 : static inline void info_set(tommy_arrayblkof* array, block_off_t pos, snapraid_info info)
1208 : {
- 1209 1757573 : tommy_arrayblkof_grow(array, pos + 1);
+ 1209 1757522 : tommy_arrayblkof_grow(array, pos + 1);
1210 :
- 1211 1757573 : memcpy(tommy_arrayblkof_ref(array, pos), &info, sizeof(snapraid_info));
- 1212 1757573 : }
+ 1211 1757522 : memcpy(tommy_arrayblkof_ref(array, pos), &info, sizeof(snapraid_info));
+ 1212 1757522 : }
1213 :
1214 : /**
1215 : * Get the info at the specified position.
1216 : * For not allocated position, 0 is returned.
1217 : */
- 1218 3171512 : static inline snapraid_info info_get(tommy_arrayblkof* array, block_off_t pos)
+ 1218 3152579 : static inline snapraid_info info_get(tommy_arrayblkof* array, block_off_t pos)
1219 : {
1220 : snapraid_info info;
1221 :
- 1222 3171512 : if (pos >= tommy_arrayblkof_size(array))
+ 1222 3152579 : if (pos >= tommy_arrayblkof_size(array))
1223 270497 : return 0;
1224 :
- 1225 2901015 : memcpy(&info, tommy_arrayblkof_ref(array, pos), sizeof(snapraid_info));
+ 1225 2882082 : memcpy(&info, tommy_arrayblkof_ref(array, pos), sizeof(snapraid_info));
1226 :
- 1227 2901015 : return info;
+ 1227 2882082 : return info;
1228 : }
1229 :
1230 : /****************************************************************************/
diff --git a/cov/cmdline/handle.c.func-sort-c.html b/cov/cmdline/handle.c.func-sort-c.html
index 68af7fbe..81e68a67 100644
--- a/cov/cmdline/handle.c.func-sort-c.html
+++ b/cov/cmdline/handle.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -65,31 +65,31 @@
| handle_truncate |
- 3256 |
+ 3213 |
| handle_utime |
- 121173 |
+ 121204 |
| handle_write |
- 288429 |
+ 288463 |
| handle_create |
- 771292 |
+ 771350 |
| handle_open |
- 2176884 |
+ 2176417 |
| handle_close |
- 4649470 |
+ 4649540 |
| handle_read |
- 5598886 |
+ 5598293 |
diff --git a/cov/cmdline/handle.c.func.html b/cov/cmdline/handle.c.func.html
index b027534b..104333b0 100644
--- a/cov/cmdline/handle.c.func.html
+++ b/cov/cmdline/handle.c.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,11 +61,11 @@
| handle_close |
- 4649470 |
+ 4649540 |
| handle_create |
- 771292 |
+ 771350 |
| handle_mapping |
@@ -73,23 +73,23 @@
| handle_open |
- 2176884 |
+ 2176417 |
| handle_read |
- 5598886 |
+ 5598293 |
| handle_truncate |
- 3256 |
+ 3213 |
| handle_utime |
- 121173 |
+ 121204 |
| handle_write |
- 288429 |
+ 288463 |
diff --git a/cov/cmdline/handle.c.gcov.html b/cov/cmdline/handle.c.gcov.html
index b80dbaca..57f018e4 100644
--- a/cov/cmdline/handle.c.gcov.html
+++ b/cov/cmdline/handle.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -86,64 +86,64 @@
24 : /****************************************************************************/
25 : /* handle */
26 :
- 27 771292 : int handle_create(struct snapraid_handle* handle, struct snapraid_file* file, int mode)
+ 27 771350 : 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 771292 : if (handle->file == file && handle->f != -1) {
+ 33 771350 : if (handle->file == file && handle->f != -1) {
34 0 : return 0;
35 : }
36 :
- 37 771292 : advise_init(&handle->advise, mode);
- 38 771292 : pathprint(handle->path, sizeof(handle->path), "%s%s", handle->disk->dir, file->sub);
+ 37 771350 : advise_init(&handle->advise, mode);
+ 38 771350 : pathprint(handle->path, sizeof(handle->path), "%s%s", handle->disk->dir, file->sub);
39 :
- 40 771292 : ret = mkancestor(handle->path);
- 41 771292 : if (ret != 0) {
+ 40 771350 : ret = mkancestor(handle->path);
+ 41 771350 : if (ret != 0) {
42 : /* LCOV_EXCL_START */
43 : return -1;
44 : /* LCOV_EXCL_STOP */
45 : }
46 :
47 : /* initial values, changed later if required */
- 48 771292 : handle->created = 0;
+ 48 771350 : 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 771292 : flags = O_BINARY | O_NOFOLLOW | advise_flags(&handle->advise);
+ 53 771350 : flags = O_BINARY | O_NOFOLLOW | advise_flags(&handle->advise);
54 :
55 : /* open for read write */
- 56 771292 : handle->f = open(handle->path, flags | O_RDWR);
+ 56 771350 : handle->f = open(handle->path, flags | O_RDWR);
57 :
58 : /* if failed for missing write permission */
- 59 771292 : if (handle->f == -1 && (errno == EACCES || errno == EROFS)) {
+ 59 771350 : if (handle->f == -1 && (errno == EACCES || errno == EROFS)) {
60 : /* open for read-only */
61 0 : handle->f = open(handle->path, flags | O_RDONLY);
62 : }
63 :
64 : /* if failed for missing file */
- 65 771292 : if (handle->f == -1 && errno == ENOENT) {
+ 65 771350 : 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 176374 : pathprint(path_from, sizeof(path_from), "%s.unrecoverable", handle->path);
+ 69 176369 : pathprint(path_from, sizeof(path_from), "%s.unrecoverable", handle->path);
70 :
- 71 176374 : if (rename(path_from, handle->path) == 0) {
+ 71 176369 : if (rename(path_from, handle->path) == 0) {
72 : /* open for read write */
- 73 63261 : handle->f = open(handle->path, flags | O_RDWR);
+ 73 63300 : handle->f = open(handle->path, flags | O_RDWR);
74 : } else {
75 : /* create it */
- 76 113113 : handle->f = open(handle->path, flags | O_RDWR | O_CREAT, 0600);
- 77 113113 : if (handle->f != -1) {
+ 76 113069 : handle->f = open(handle->path, flags | O_RDWR | O_CREAT, 0600);
+ 77 113069 : if (handle->f != -1) {
78 : /* mark it as created if really done */
- 79 113113 : handle->created = 1;
+ 79 113069 : handle->created = 1;
80 : }
81 : }
82 : }
83 :
- 84 771292 : if (handle->f == -1) {
+ 84 771350 : 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 771292 : handle->file = file;
+ 97 771350 : handle->file = file;
98 :
99 : /* get the stat info */
- 100 771292 : ret = fstat(handle->f, &handle->st);
- 101 771292 : if (ret != 0) {
+ 100 771350 : ret = fstat(handle->f, &handle->st);
+ 101 771350 : if (ret != 0) {
102 : /* LCOV_EXCL_START */
103 : log_fatal(errno, "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 771292 : handle->valid_size = handle->st.st_size;
+ 109 771350 : handle->valid_size = handle->st.st_size;
110 :
- 111 771292 : ret = advise_open(&handle->advise, handle->f);
- 112 771292 : if (ret != 0) {
+ 111 771350 : ret = advise_open(&handle->advise, handle->f);
+ 112 771350 : if (ret != 0) {
113 : /* LCOV_EXCL_START */
114 : log_fatal(errno, "Error advising file '%s'. %s.\n", handle->path, strerror(errno));
115 : return -1;
116 : /* LCOV_EXCL_STOP */
117 : }
118 :
- 119 771292 : return 0;
+ 119 771350 : return 0;
120 : }
121 :
- 122 3256 : int handle_truncate(struct snapraid_handle* handle, struct snapraid_file* file)
+ 122 3213 : int handle_truncate(struct snapraid_handle* handle, struct snapraid_file* file)
123 : {
124 : int ret;
125 :
- 126 3256 : ret = ftruncate(handle->f, file->size);
- 127 3256 : if (ret != 0) {
+ 126 3213 : ret = ftruncate(handle->f, file->size);
+ 127 3213 : if (ret != 0) {
128 : /* LCOV_EXCL_START */
129 : if (errno == EACCES) {
130 : log_fatal(errno, "Failed to truncate file '%s' for missing write permission.\n", handle->path);
@@ -198,58 +198,58 @@
136 : }
137 :
138 : /* adjust the size to the truncated size */
- 139 3256 : handle->valid_size = file->size;
+ 139 3213 : handle->valid_size = file->size;
140 :
- 141 3256 : return 0;
+ 141 3213 : return 0;
142 : }
143 :
- 144 2176884 : int handle_open(struct snapraid_handle* handle, struct snapraid_file* file, int mode, log_ptr* out, log_ptr* out_missing)
+ 144 2176417 : int handle_open(struct snapraid_handle* handle, struct snapraid_file* file, int mode, log_ptr* out, log_ptr* out_missing)
145 : {
146 : int ret;
147 : int flags;
148 :
- 149 2176884 : if (!out_missing)
- 150 1576375 : out_missing = out;
+ 149 2176417 : if (!out_missing)
+ 150 1576294 : out_missing = out;
151 :
152 : /* if already opened, nothing to do */
- 153 2176884 : if (handle->file == file && handle->file != 0 && handle->f != -1) {
- 154 464548 : return 0;
+ 153 2176417 : if (handle->file == file && handle->file != 0 && handle->f != -1) {
+ 154 464272 : return 0;
155 : }
156 :
- 157 1712336 : advise_init(&handle->advise, mode);
- 158 1712336 : pathprint(handle->path, sizeof(handle->path), "%s%s", handle->disk->dir, file->sub);
+ 157 1712145 : advise_init(&handle->advise, mode);
+ 158 1712145 : pathprint(handle->path, sizeof(handle->path), "%s%s", handle->disk->dir, file->sub);
159 :
160 : /* for sure not created */
- 161 1712336 : handle->created = 0;
+ 161 1712145 : 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 1712336 : flags = O_BINARY | O_NOFOLLOW | advise_flags(&handle->advise);
+ 166 1712145 : flags = O_BINARY | O_NOFOLLOW | advise_flags(&handle->advise);
167 :
168 : /* open for read */
- 169 1712336 : handle->f = open_noatime(handle->path, flags | O_RDONLY);
- 170 1712336 : if (handle->f == -1) {
+ 169 1712145 : handle->f = open_noatime(handle->path, flags | O_RDONLY);
+ 170 1712145 : if (handle->f == -1) {
171 : /* invalidate for error */
- 172 78731 : handle->file = 0;
- 173 78731 : handle->f = -1;
- 174 78731 : handle->valid_size = 0;
+ 172 78696 : handle->file = 0;
+ 173 78696 : handle->f = -1;
+ 174 78696 : handle->valid_size = 0;
175 :
- 176 78731 : if (errno == ENOENT)
- 177 78719 : out_missing(errno, "Missing file '%s'.\n", handle->path);
+ 176 78696 : if (errno == ENOENT)
+ 177 78684 : out_missing(errno, "Missing file '%s'.\n", handle->path);
178 12 : else if (errno == EACCES)
179 12 : out(errno, "Permission denied for file '%s'.\n", handle->path);
180 : else
181 0 : out(errno, "Error opening file '%s'. %s.\n", handle->path, strerror(errno));
- 182 78731 : return -1;
+ 182 78696 : return -1;
183 : }
184 :
185 : /* just opened */
- 186 1633605 : handle->file = file;
+ 186 1633449 : handle->file = file;
187 :
188 : /* get the stat info */
- 189 1633605 : ret = fstat(handle->f, &handle->st);
- 190 1633605 : if (ret != 0) {
+ 189 1633449 : ret = fstat(handle->f, &handle->st);
+ 190 1633449 : if (ret != 0) {
191 : /* LCOV_EXCL_START */
192 : out(errno, "Error accessing file '%s'. %s.\n", handle->path, strerror(errno));
193 : return -1;
@@ -257,27 +257,27 @@
195 : }
196 :
197 : /* get the size of the existing data */
- 198 1633605 : handle->valid_size = handle->st.st_size;
+ 198 1633449 : handle->valid_size = handle->st.st_size;
199 :
- 200 1633605 : ret = advise_open(&handle->advise, handle->f);
- 201 1633605 : if (ret != 0) {
+ 200 1633449 : ret = advise_open(&handle->advise, handle->f);
+ 201 1633449 : if (ret != 0) {
202 : /* LCOV_EXCL_START */
203 : out(errno, "Error advising file '%s'. %s.\n", handle->path, strerror(errno));
204 : return -1;
205 : /* LCOV_EXCL_STOP */
206 : }
207 :
- 208 1633605 : return 0;
+ 208 1633449 : return 0;
209 : }
210 :
- 211 4649470 : int handle_close(struct snapraid_handle* handle)
+ 211 4649540 : int handle_close(struct snapraid_handle* handle)
212 : {
213 : int ret;
214 :
215 : /* close if open */
- 216 4649470 : if (handle->f != -1) {
- 217 2404897 : ret = close(handle->f);
- 218 2404897 : if (ret != 0) {
+ 216 4649540 : if (handle->f != -1) {
+ 217 2404799 : ret = close(handle->f);
+ 218 2404799 : if (ret != 0) {
219 : /* LCOV_EXCL_START */
220 : log_fatal(errno, "Error closing file '%s'. %s.\n", handle->file->sub, strerror(errno));
221 :
@@ -291,14 +291,14 @@
229 : }
230 :
231 : /* reset the descriptor */
- 232 4649470 : handle->file = 0;
- 233 4649470 : handle->f = -1;
- 234 4649470 : handle->valid_size = 0;
+ 232 4649540 : handle->file = 0;
+ 233 4649540 : handle->f = -1;
+ 234 4649540 : handle->valid_size = 0;
235 :
- 236 4649470 : return 0;
+ 236 4649540 : return 0;
237 : }
238 :
- 239 5598886 : int handle_read(struct snapraid_handle* handle, block_off_t file_pos, unsigned char* block_buffer, unsigned block_size, log_ptr* out, log_ptr* out_missing)
+ 239 5598293 : int handle_read(struct snapraid_handle* handle, block_off_t file_pos, unsigned char* block_buffer, unsigned block_size, log_ptr* out, log_ptr* out_missing)
240 : {
241 : ssize_t read_ret;
242 : data_off_t offset;
@@ -306,43 +306,43 @@
244 : unsigned count;
245 : int ret;
246 :
- 247 5598886 : offset = file_pos * (data_off_t)block_size;
+ 247 5598293 : offset = file_pos * (data_off_t)block_size;
248 :
- 249 5598886 : if (!out_missing)
- 250 5592557 : out_missing = out;
+ 249 5598293 : if (!out_missing)
+ 250 5591964 : out_missing = out;
251 :
252 : /* check if we are going to read only not initialized data */
- 253 5598886 : if (offset >= handle->valid_size) {
+ 253 5598293 : if (offset >= handle->valid_size) {
254 : /* if the file is missing, it's at 0 size, or it's rebuilt while reading */
- 255 176886 : if (offset == handle->valid_size || handle->valid_size == 0) {
- 256 175792 : errno = ENOENT;
- 257 175792 : if (offset == 0) {
- 258 174839 : out_missing(errno, "Missing file '%s'.\n", handle->path);
+ 255 176692 : if (offset == handle->valid_size || handle->valid_size == 0) {
+ 256 175708 : errno = ENOENT;
+ 257 175708 : if (offset == 0) {
+ 258 174804 : out_missing(errno, "Missing file '%s'.\n", handle->path);
259 : } else {
- 260 953 : out_missing(errno, "Missing data in file '%s' at offset %" PRIu64 ".\n", handle->path, offset);
+ 260 904 : out_missing(errno, "Missing data in file '%s' at offset %" PRIu64 ".\n", handle->path, offset);
261 : }
262 : } else {
- 263 1094 : errno = ENXIO;
- 264 1094 : out(errno, "Reading over the end from file '%s' at offset %" PRIu64 ".\n", handle->path, offset);
+ 263 984 : errno = ENXIO;
+ 264 984 : out(errno, "Reading over the end from file '%s' at offset %" PRIu64 ".\n", handle->path, offset);
265 : }
- 266 176886 : return -1;
+ 266 176692 : return -1;
267 : }
268 :
- 269 5422000 : read_size = file_block_size(handle->file, file_pos, block_size);
+ 269 5421601 : read_size = file_block_size(handle->file, file_pos, block_size);
270 :
- 271 5422000 : count = 0;
- 272 5422000 : errno = 0;
+ 271 5421601 : count = 0;
+ 272 5421601 : errno = 0;
273 : do {
- 274 5430811 : bw_limit(handle->bw, block_size - count);
+ 274 5430426 : bw_limit(handle->bw, block_size - count);
275 :
- 276 5430811 : read_ret = pread(handle->f, block_buffer + count, block_size - count, offset + count);
- 277 5430811 : if (read_ret == -1) {
+ 276 5430426 : read_ret = pread(handle->f, block_buffer + count, block_size - count, offset + count);
+ 277 5430426 : if (read_ret == -1) {
278 : /* LCOV_EXCL_START */
279 : out(errno, "Error reading file '%s' at offset %" PRIu64 " for size %u. %s.\n", handle->path, offset + count, block_size - count, strerror(errno));
280 : return -1;
281 : /* LCOV_EXCL_STOP */
282 : }
- 283 5430811 : if (read_ret == 0) {
+ 283 5430426 : if (read_ret == 0) {
284 : /* LCOV_EXCL_START */
285 : if (errno == 0)
286 : errno = ENXIO;
@@ -351,26 +351,26 @@
289 : /* LCOV_EXCL_STOP */
290 : }
291 :
- 292 5422000 : count += read_ret;
- 293 5422000 : } while (count < read_size);
+ 292 5421601 : count += read_ret;
+ 293 5421601 : } while (count < read_size);
294 :
295 : /* pad with 0 */
- 296 5413189 : if (read_size < block_size) {
- 297 2187257 : memset(block_buffer + read_size, 0, block_size - read_size);
+ 296 5412776 : if (read_size < block_size) {
+ 297 2187169 : memset(block_buffer + read_size, 0, block_size - read_size);
298 : }
299 :
- 300 5413189 : ret = advise_read(&handle->advise, handle->f, offset, block_size);
- 301 5413189 : if (ret != 0) {
+ 300 5412776 : ret = advise_read(&handle->advise, handle->f, offset, block_size);
+ 301 5412776 : if (ret != 0) {
302 : /* LCOV_EXCL_START */
303 : out(errno, "Error advising file '%s'. %s.\n", handle->path, strerror(errno));
304 : return -1;
305 : /* LCOV_EXCL_STOP */
306 : }
307 :
- 308 5413189 : return read_size;
+ 308 5412776 : return read_size;
309 : }
310 :
- 311 288429 : int handle_write(struct snapraid_handle* handle, block_off_t file_pos, unsigned char* block_buffer, unsigned block_size)
+ 311 288463 : int handle_write(struct snapraid_handle* handle, block_off_t file_pos, unsigned char* block_buffer, unsigned block_size)
312 : {
313 : ssize_t write_ret;
314 : data_off_t offset;
@@ -378,22 +378,22 @@
316 : unsigned count;
317 : int ret;
318 :
- 319 288429 : offset = file_pos * (data_off_t)block_size;
+ 319 288463 : offset = file_pos * (data_off_t)block_size;
320 :
- 321 288429 : write_size = file_block_size(handle->file, file_pos, block_size);
+ 321 288463 : write_size = file_block_size(handle->file, file_pos, block_size);
322 :
- 323 288429 : count = 0;
+ 323 288463 : count = 0;
324 : do {
- 325 288429 : bw_limit(handle->bw, write_size - count);
+ 325 288463 : bw_limit(handle->bw, write_size - count);
326 :
- 327 288429 : write_ret = pwrite(handle->f, block_buffer + count, write_size - count, offset + count);
- 328 288429 : if (write_ret == -1) {
+ 327 288463 : write_ret = pwrite(handle->f, block_buffer + count, write_size - count, offset + count);
+ 328 288463 : if (write_ret == -1) {
329 : /* LCOV_EXCL_START */
330 : log_fatal(errno, "Error writing file '%s'. %s.\n", handle->path, strerror(errno));
331 : return -1;
332 : /* LCOV_EXCL_STOP */
333 : }
- 334 288429 : if (write_ret == 0) {
+ 334 288463 : if (write_ret == 0) {
335 : /* LCOV_EXCL_START */
336 : errno = ENXIO;
337 : log_fatal(errno, "Unexpected 0 write to file '%s'. %s.\n", handle->path, strerror(errno));
@@ -401,43 +401,43 @@
339 : /* LCOV_EXCL_STOP */
340 : }
341 :
- 342 288429 : count += write_ret;
- 343 288429 : } while (count < write_size);
+ 342 288463 : count += write_ret;
+ 343 288463 : } while (count < write_size);
344 :
345 : /* adjust the size of the valid data */
- 346 288429 : if (handle->valid_size < offset + write_size) {
- 347 282456 : handle->valid_size = offset + write_size;
+ 346 288463 : if (handle->valid_size < offset + write_size) {
+ 347 282376 : handle->valid_size = offset + write_size;
348 : }
349 :
- 350 288429 : ret = advise_write(&handle->advise, handle->f, offset, block_size);
- 351 288429 : if (ret != 0) {
+ 350 288463 : ret = advise_write(&handle->advise, handle->f, offset, block_size);
+ 351 288463 : if (ret != 0) {
352 : /* LCOV_EXCL_START */
353 : log_fatal(errno, "Error advising file '%s'. %s.\n", handle->path, strerror(errno));
354 : return -1;
355 : /* LCOV_EXCL_STOP */
356 : }
357 :
- 358 288429 : return 0;
+ 358 288463 : return 0;
359 : }
360 :
- 361 121173 : int handle_utime(struct snapraid_handle* handle)
+ 361 121204 : int handle_utime(struct snapraid_handle* handle)
362 : {
363 : int ret;
364 :
365 : /* do nothing if not opened */
- 366 121173 : if (handle->f == -1)
+ 366 121204 : if (handle->f == -1)
367 0 : return 0;
368 :
- 369 121173 : ret = fmtime(handle->f, handle->file->mtime_sec, handle->file->mtime_nsec);
+ 369 121204 : ret = fmtime(handle->f, handle->file->mtime_sec, handle->file->mtime_nsec);
370 :
- 371 121173 : if (ret != 0) {
+ 371 121204 : if (ret != 0) {
372 : /* LCOV_EXCL_START */
373 : log_fatal(errno, "Error timing file '%s'. %s.\n", handle->file->sub, strerror(errno));
374 : return -1;
375 : /* LCOV_EXCL_STOP */
376 : }
377 :
- 378 121173 : return 0;
+ 378 121204 : return 0;
379 : }
380 :
381 227 : 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 d528c811..93da1ca4 100644
--- a/cov/cmdline/import.c.func-sort-c.html
+++ b/cov/cmdline/import.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -85,11 +85,11 @@
| state_import_fetch |
- 652266 |
+ 652523 |
| import_block_hash |
- 656738 |
+ 656995 |
diff --git a/cov/cmdline/import.c.func.html b/cov/cmdline/import.c.func.html
index 207bcbe6..0739502b 100644
--- a/cov/cmdline/import.c.func.html
+++ b/cov/cmdline/import.c.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,7 +61,7 @@
| import_block_hash |
- 656738 |
+ 656995 |
| import_block_hash_compare |
@@ -89,7 +89,7 @@
| state_import_fetch |
- 652266 |
+ 652523 |
diff --git a/cov/cmdline/import.c.gcov.html b/cov/cmdline/import.c.gcov.html
index 1aca67ec..804a8f6a 100644
--- a/cov/cmdline/import.c.gcov.html
+++ b/cov/cmdline/import.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -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 656738 : static inline tommy_uint32_t import_block_hash(const unsigned char* hash)
+ 49 656995 : 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 656738 : return hash[0] | ((uint32_t)hash[1] << 8) | ((uint32_t)hash[2] << 16) | ((uint32_t)hash[3] << 24);
+ 52 656995 : 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 652266 : int state_import_fetch(struct snapraid_state* state, int rehash, struct snapraid_block* missing_block, unsigned char* buffer)
+ 148 652523 : 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 652266 : const unsigned char* hash = missing_block->hash;
- 154 652266 : unsigned block_size = state->block_size;
+ 153 652523 : const unsigned char* hash = missing_block->hash;
+ 154 652523 : unsigned block_size = state->block_size;
155 : unsigned read_size;
156 : unsigned char buffer_hash[HASH_MAX];
157 : const char* path;
158 :
- 159 652266 : if (rehash) {
+ 159 652523 : if (rehash) {
160 0 : block = tommy_hashdyn_search(&state->previmportset, import_block_prevhash_compare, hash, import_block_hash(hash));
161 : } else {
- 162 652266 : block = tommy_hashdyn_search(&state->importset, import_block_hash_compare, hash, import_block_hash(hash));
+ 162 652523 : block = tommy_hashdyn_search(&state->importset, import_block_hash_compare, hash, import_block_hash(hash));
163 : }
- 164 652266 : if (!block)
- 165 647794 : return -1;
+ 164 652523 : if (!block)
+ 165 648051 : 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 dbaa53cc..453e36a3 100644
--- a/cov/cmdline/index-sort-f.html
+++ b/cov/cmdline/index-sort-f.html
@@ -31,18 +31,18 @@
|
-
-
-
+
+
+
-
+
|
-
+
-
+
 |
@@ -69,16 +69,6 @@
Line Coverage  |
Functions  |
-
- | unix.c |
-
-
- |
- 56.2 % |
- 381 / 678 |
- 73.8 % |
- 31 / 42 |
-
| dry.c |
@@ -90,14 +80,14 @@
| 4 / 5 |
- | scrub.c |
+ unix.c |
-
+
|
- 79.3 % |
- 303 / 382 |
- 85.7 % |
- 6 / 7 |
+ 70.6 % |
+ 475 / 673 |
+ 83.3 % |
+ 35 / 42 |
| thermal.c |
@@ -109,6 +99,16 @@
85.7 % |
6 / 7 |
+
+ | scrub.c |
+
+
+ |
+ 79.3 % |
+ 303 / 382 |
+ 85.7 % |
+ 6 / 7 |
+
| import.c |
@@ -119,16 +119,6 @@
| 87.5 % |
7 / 8 |
-
- | support.c |
-
-
- |
- 63.9 % |
- 633 / 991 |
- 89.3 % |
- 75 / 84 |
-
| stream.h |
@@ -140,14 +130,14 @@
| 10 / 11 |
- | device.c |
+ support.c |
-
+
|
- 84.4 % |
- 345 / 409 |
+ 80.4 % |
+ 769 / 956 |
92.9 % |
- 13 / 14 |
+ 78 / 84 |
| io.c |
@@ -172,10 +162,10 @@
| state.c |
-
+
|
- 88.9 % |
- 1737 / 1954 |
+ 90.3 % |
+ 1765 / 1954 |
96.1 % |
49 / 51 |
@@ -209,26 +199,6 @@
97.2 % |
70 / 72 |
-
- | spooky2.c |
-
-
- |
- 100.0 % |
- 20 / 20 |
- 100.0 % |
- 1 / 1 |
-
-
- | portable.h |
-
-
- |
- 100.0 % |
- 2 / 2 |
- 100.0 % |
- 1 / 1 |
-
| list.c |
@@ -239,26 +209,6 @@
| 100.0 % |
1 / 1 |
-
- | rehash.c |
-
-
- |
- 95.2 % |
- 20 / 21 |
- 100.0 % |
- 1 / 1 |
-
-
- | touch.c |
-
-
- |
- 100.0 % |
- 28 / 28 |
- 100.0 % |
- 1 / 1 |
-
| museair.c |
@@ -279,6 +229,36 @@
| 100.0 % |
1 / 1 |
+
+ | portable.h |
+
+
+ |
+ 100.0 % |
+ 2 / 2 |
+ 100.0 % |
+ 1 / 1 |
+
+
+ | touch.c |
+
+
+ |
+ 100.0 % |
+ 28 / 28 |
+ 100.0 % |
+ 1 / 1 |
+
+
+ | rehash.c |
+
+
+ |
+ 95.2 % |
+ 20 / 21 |
+ 100.0 % |
+ 1 / 1 |
+
| metro.c |
@@ -290,12 +270,22 @@
| 1 / 1 |
- | main.c |
+ spooky2.c |
-
+
|
- 83.6 % |
- 51 / 61 |
+ 100.0 % |
+ 20 / 20 |
+ 100.0 % |
+ 1 / 1 |
+
+
+ | speed.c |
+
+
+ |
+ 99.6 % |
+ 490 / 492 |
100.0 % |
2 / 2 |
@@ -310,32 +300,12 @@
2 / 2 |
- | mkstream.c |
+ main.c |
-
+
|
- 100.0 % |
- 69 / 69 |
- 100.0 % |
- 2 / 2 |
-
-
- | status.c |
-
-
- |
- 96.2 % |
- 256 / 266 |
- 100.0 % |
- 2 / 2 |
-
-
- | speed.c |
-
-
- |
- 99.6 % |
- 490 / 492 |
+ 83.6 % |
+ 51 / 61 |
100.0 % |
2 / 2 |
@@ -349,6 +319,26 @@
100.0 % |
2 / 2 |
+
+ | status.c |
+
+
+ |
+ 96.2 % |
+ 256 / 266 |
+ 100.0 % |
+ 2 / 2 |
+
+
+ | mkstream.c |
+
+
+ |
+ 100.0 % |
+ 69 / 69 |
+ 100.0 % |
+ 2 / 2 |
+
| dup.c |
@@ -359,16 +349,6 @@
| 100.0 % |
5 / 5 |
-
- | locate.c |
-
-
- |
- 94.4 % |
- 119 / 126 |
- 100.0 % |
- 7 / 7 |
-
| util.h |
@@ -382,10 +362,20 @@
|
| search.c |
-
+
|
- 90.9 % |
- 90 / 99 |
+ 91.9 % |
+ 91 / 99 |
+ 100.0 % |
+ 7 / 7 |
+
+
+ | locate.c |
+
+
+ |
+ 94.4 % |
+ 119 / 126 |
100.0 % |
7 / 7 |
@@ -429,16 +419,6 @@
100.0 % |
9 / 9 |
-
- | check.c |
-
-
- |
- 88.9 % |
- 766 / 862 |
- 100.0 % |
- 10 / 10 |
-
| snapraid.c |
@@ -449,13 +429,33 @@
| 100.0 % |
10 / 10 |
+
+ | check.c |
+
+
+ |
+ 88.7 % |
+ 765 / 862 |
+ 100.0 % |
+ 10 / 10 |
+
+
+ | device.c |
+
+
+ |
+ 88.8 % |
+ 363 / 409 |
+ 100.0 % |
+ 14 / 14 |
+
| mktest.c |
-
+
|
- 92.8 % |
- 220 / 237 |
+ 93.2 % |
+ 221 / 237 |
100.0 % |
18 / 18 |
diff --git a/cov/cmdline/index-sort-l.html b/cov/cmdline/index-sort-l.html
index be52e4cc..c91a2d2f 100644
--- a/cov/cmdline/index-sort-l.html
+++ b/cov/cmdline/index-sort-l.html
@@ -31,18 +31,18 @@
|
-
-
-
+
+
+
-
+
|
-
+
-
+
 |
@@ -72,22 +72,12 @@
| unix.c |
-
+
|
- 56.2 % |
- 381 / 678 |
- 73.8 % |
- 31 / 42 |
-
-
- | support.c |
-
-
- |
- 63.9 % |
- 633 / 991 |
- 89.3 % |
- 75 / 84 |
+ 70.6 % |
+ 475 / 673 |
+ 83.3 % |
+ 35 / 42 |
| dry.c |
@@ -109,6 +99,16 @@
85.7 % |
6 / 7 |
+
+ | support.c |
+
+
+ |
+ 80.4 % |
+ 769 / 956 |
+ 92.9 % |
+ 78 / 84 |
+
| thermal.c |
@@ -129,16 +129,6 @@
| 100.0 % |
2 / 2 |
-
- | device.c |
-
-
- |
- 84.4 % |
- 345 / 409 |
- 92.9 % |
- 13 / 14 |
-
| snapraid.c |
@@ -150,24 +140,24 @@
| 10 / 10 |
- | check.c |
+ device.c |
-
+
|
- 88.9 % |
- 766 / 862 |
+ 88.8 % |
+ 363 / 409 |
100.0 % |
- 10 / 10 |
+ 14 / 14 |
- | state.c |
+ check.c |
-
+
|
- 88.9 % |
- 1737 / 1954 |
- 96.1 % |
- 49 / 51 |
+ 88.7 % |
+ 765 / 862 |
+ 100.0 % |
+ 10 / 10 |
| scan.c |
@@ -199,6 +189,16 @@
87.5 % |
7 / 8 |
+
+ | state.c |
+
+
+ |
+ 90.3 % |
+ 1765 / 1954 |
+ 96.1 % |
+ 49 / 51 |
+
| stream.h |
@@ -219,16 +219,6 @@
| 96.4 % |
27 / 28 |
-
- | search.c |
-
-
- |
- 90.9 % |
- 90 / 99 |
- 100.0 % |
- 7 / 7 |
-
| parity.c |
@@ -249,6 +239,16 @@
| 100.0 % |
1 / 1 |
+
+ | search.c |
+
+
+ |
+ 91.9 % |
+ 91 / 99 |
+ 100.0 % |
+ 7 / 7 |
+
| util.c |
@@ -262,10 +262,10 @@
|
| mktest.c |
-
+
|
- 92.8 % |
- 220 / 237 |
+ 93.2 % |
+ 221 / 237 |
100.0 % |
18 / 18 |
@@ -390,7 +390,7 @@
2 / 2 |
- | portable.h |
+ support.h |
|
@@ -400,7 +400,7 @@
1 / 1 |
- | support.h |
+ portable.h |
|
diff --git a/cov/cmdline/index.html b/cov/cmdline/index.html
index d9ff2cc8..8ee7a2f1 100644
--- a/cov/cmdline/index.html
+++ b/cov/cmdline/index.html
@@ -31,18 +31,18 @@
|
-
-
-
+
+
+
-
+
|
-
+
-
+
 |
@@ -82,22 +82,22 @@
| check.c |
-
+
|
- 88.9 % |
- 766 / 862 |
+ 88.7 % |
+ 765 / 862 |
100.0 % |
10 / 10 |
| device.c |
-
+
|
- 84.4 % |
- 345 / 409 |
- 92.9 % |
- 13 / 14 |
+ 88.8 % |
+ 363 / 409 |
+ 100.0 % |
+ 14 / 14 |
| dry.c |
@@ -222,10 +222,10 @@
| mktest.c |
-
+
|
- 92.8 % |
- 220 / 237 |
+ 93.2 % |
+ 221 / 237 |
100.0 % |
18 / 18 |
@@ -312,10 +312,10 @@
| search.c |
-
+
|
- 90.9 % |
- 90 / 99 |
+ 91.9 % |
+ 91 / 99 |
100.0 % |
7 / 7 |
@@ -362,10 +362,10 @@
| state.c |
-
+
|
- 88.9 % |
- 1737 / 1954 |
+ 90.3 % |
+ 1765 / 1954 |
96.1 % |
49 / 51 |
@@ -402,12 +402,12 @@
| support.c |
-
+
|
- 63.9 % |
- 633 / 991 |
- 89.3 % |
- 75 / 84 |
+ 80.4 % |
+ 769 / 956 |
+ 92.9 % |
+ 78 / 84 |
| support.h |
@@ -452,12 +452,12 @@
| unix.c |
-
+
|
- 56.2 % |
- 381 / 678 |
- 73.8 % |
- 31 / 42 |
+ 70.6 % |
+ 475 / 673 |
+ 83.3 % |
+ 35 / 42 |
| util.c |
diff --git a/cov/cmdline/io.c.func-sort-c.html b/cov/cmdline/io.c.func-sort-c.html
index 3f6abcaf..87f7601d 100644
--- a/cov/cmdline/io.c.func-sort-c.html
+++ b/cov/cmdline/io.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -113,7 +113,7 @@
| io_writer_sched_empty |
- 931 |
+ 920 |
| io_parity_write_mono |
@@ -141,27 +141,27 @@
| io_write_next_thread |
- 111042 |
+ 110979 |
| io_write_preset_thread |
- 111042 |
+ 110979 |
| io_writer_sched |
- 114798 |
+ 114746 |
| io_read_next_thread |
- 146427 |
+ 146364 |
| io_position_next |
- 163942 |
+ 163879 |
| io_reader_sched |
- 163942 |
+ 163879 |
| io_parity_read_thread |
@@ -169,27 +169,27 @@
| io_parity_write_thread |
- 559582 |
+ 559204 |
| io_writer_step |
- 560074 |
+ 559696 |
| io_data_read_thread |
- 877956 |
+ 877578 |
| io_task_read_thread |
- 1089660 |
+ 1089282 |
| io_reader_worker |
- 1089792 |
+ 1089420 |
| io_reader_step |
- 1177886 |
+ 1177263 |
diff --git a/cov/cmdline/io.c.func.html b/cov/cmdline/io.c.func.html
index 7aada686..fc6ac5db 100644
--- a/cov/cmdline/io.c.func.html
+++ b/cov/cmdline/io.c.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -65,7 +65,7 @@
| io_data_read_thread |
- 877956 |
+ 877578 |
| io_done |
@@ -97,11 +97,11 @@
| io_parity_write_thread |
- 559582 |
+ 559204 |
| io_position_next |
- 163942 |
+ 163879 |
| io_read_next_mono |
@@ -109,15 +109,15 @@
| io_read_next_thread |
- 146427 |
+ 146364 |
| io_reader_sched |
- 163942 |
+ 163879 |
| io_reader_step |
- 1177886 |
+ 1177263 |
| io_reader_thread |
@@ -125,7 +125,7 @@
| io_reader_worker |
- 1089792 |
+ 1089420 |
| io_refresh_mono |
@@ -157,7 +157,7 @@
| io_task_read_thread |
- 1089660 |
+ 1089282 |
| io_write_next_mono |
@@ -165,7 +165,7 @@
| io_write_next_thread |
- 111042 |
+ 110979 |
| io_write_preset_mono |
@@ -173,19 +173,19 @@
| io_write_preset_thread |
- 111042 |
+ 110979 |
| io_writer_sched |
- 114798 |
+ 114746 |
| io_writer_sched_empty |
- 931 |
+ 920 |
| io_writer_step |
- 560074 |
+ 559696 |
| io_writer_thread |
diff --git a/cov/cmdline/io.c.gcov.html b/cov/cmdline/io.c.gcov.html
index 25ad9bba..652a74b8 100644
--- a/cov/cmdline/io.c.gcov.html
+++ b/cov/cmdline/io.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -97,108 +97,108 @@
35 : /**
36 : * Get the next block position to process.
37 : */
- 38 163942 : static block_off_t io_position_next(struct snapraid_io* io)
+ 38 163879 : static block_off_t io_position_next(struct snapraid_io* io)
39 : {
40 : block_off_t blockcur;
41 :
42 : /* get the next position */
- 43 163942 : if (io->block_enabled) {
+ 43 163879 : if (io->block_enabled) {
44 507954 : while (io->block_next < io->block_max && !bit_vect_test(io->block_enabled, io->block_next))
- 45 353913 : ++io->block_next;
+ 45 353976 : ++io->block_next;
46 : }
47 :
- 48 163942 : blockcur = io->block_next;
+ 48 163879 : blockcur = io->block_next;
49 :
50 : /* next block for the next call */
- 51 163942 : ++io->block_next;
+ 51 163879 : ++io->block_next;
52 :
- 53 163942 : return blockcur;
+ 53 163879 : return blockcur;
54 : }
55 :
56 : /**
57 : * Setup the next pending task for all readers.
58 : */
- 59 163942 : static void io_reader_sched(struct snapraid_io* io, int task_index, block_off_t blockcur)
+ 59 163879 : static void io_reader_sched(struct snapraid_io* io, int task_index, block_off_t blockcur)
60 : {
61 : unsigned i;
62 :
- 63 1370050 : for (i = 0; i < io->reader_max; ++i) {
- 64 1206108 : struct snapraid_worker* worker = &io->reader_map[i];
- 65 1206108 : struct snapraid_task* task = &worker->task_map[task_index];
+ 63 1369609 : for (i = 0; i < io->reader_max; ++i) {
+ 64 1205730 : struct snapraid_worker* worker = &io->reader_map[i];
+ 65 1205730 : struct snapraid_task* task = &worker->task_map[task_index];
66 :
67 : /* setup the new pending task */
- 68 1206108 : if (blockcur < io->block_max)
- 69 1117782 : task->state = TASK_STATE_READY;
+ 68 1205730 : if (blockcur < io->block_max)
+ 69 1117404 : task->state = TASK_STATE_READY;
70 : else
71 88326 : task->state = TASK_STATE_EMPTY;
72 :
- 73 1206108 : task->path[0] = 0;
- 74 1206108 : if (worker->handle)
- 75 983652 : task->disk = worker->handle->disk;
+ 73 1205730 : task->path[0] = 0;
+ 74 1205730 : if (worker->handle)
+ 75 983274 : task->disk = worker->handle->disk;
76 : else
77 222456 : task->disk = 0;
78 :
- 79 1206108 : assert(worker->buffer_skew + i < io->buffer_max);
+ 79 1205730 : assert(worker->buffer_skew + i < io->buffer_max);
80 :
- 81 1206108 : task->buffer = io->buffer_map[task_index][worker->buffer_skew + i];
- 82 1206108 : task->position = blockcur;
- 83 1206108 : task->block = 0;
- 84 1206108 : task->file = 0;
- 85 1206108 : task->file_pos = 0;
- 86 1206108 : task->read_size = 0;
- 87 1206108 : task->is_timestamp_different = 0;
+ 81 1205730 : task->buffer = io->buffer_map[task_index][worker->buffer_skew + i];
+ 82 1205730 : task->position = blockcur;
+ 83 1205730 : task->block = 0;
+ 84 1205730 : task->file = 0;
+ 85 1205730 : task->file_pos = 0;
+ 86 1205730 : task->read_size = 0;
+ 87 1205730 : task->is_timestamp_different = 0;
88 : }
- 89 163942 : }
+ 89 163879 : }
90 :
91 : /**
92 : * Setup the next pending task for all writers.
93 : */
- 94 114798 : static void io_writer_sched(struct snapraid_io* io, int task_index, block_off_t blockcur)
+ 94 114746 : static void io_writer_sched(struct snapraid_io* io, int task_index, block_off_t blockcur)
95 : {
96 : unsigned i;
97 :
- 98 673481 : for (i = 0; i < io->writer_max; ++i) {
- 99 558683 : struct snapraid_worker* worker = &io->writer_map[i];
- 100 558683 : struct snapraid_task* task = &worker->task_map[task_index];
+ 98 673117 : for (i = 0; i < io->writer_max; ++i) {
+ 99 558371 : struct snapraid_worker* worker = &io->writer_map[i];
+ 100 558371 : struct snapraid_task* task = &worker->task_map[task_index];
101 :
102 : /* setup the new pending task */
- 103 558683 : task->state = TASK_STATE_READY;
- 104 558683 : task->path[0] = 0;
- 105 558683 : task->disk = 0;
- 106 558683 : task->buffer = io->buffer_map[task_index][worker->buffer_skew + i];
- 107 558683 : task->position = blockcur;
- 108 558683 : task->block = 0;
- 109 558683 : task->file = 0;
- 110 558683 : task->file_pos = 0;
- 111 558683 : task->read_size = 0;
- 112 558683 : task->is_timestamp_different = 0;
+ 103 558371 : task->state = TASK_STATE_READY;
+ 104 558371 : task->path[0] = 0;
+ 105 558371 : task->disk = 0;
+ 106 558371 : task->buffer = io->buffer_map[task_index][worker->buffer_skew + i];
+ 107 558371 : task->position = blockcur;
+ 108 558371 : task->block = 0;
+ 109 558371 : task->file = 0;
+ 110 558371 : task->file_pos = 0;
+ 111 558371 : task->read_size = 0;
+ 112 558371 : task->is_timestamp_different = 0;
113 : }
- 114 114798 : }
+ 114 114746 : }
115 :
116 : /**
117 : * Setup an empty next pending task for all writers.
118 : */
- 119 931 : static void io_writer_sched_empty(struct snapraid_io* io, int task_index, block_off_t blockcur)
+ 119 920 : static void io_writer_sched_empty(struct snapraid_io* io, int task_index, block_off_t blockcur)
120 : {
121 : unsigned i;
122 :
- 123 6517 : for (i = 0; i < io->writer_max; ++i) {
- 124 5586 : struct snapraid_worker* worker = &io->writer_map[i];
- 125 5586 : struct snapraid_task* task = &worker->task_map[task_index];
+ 123 6440 : for (i = 0; i < io->writer_max; ++i) {
+ 124 5520 : struct snapraid_worker* worker = &io->writer_map[i];
+ 125 5520 : struct snapraid_task* task = &worker->task_map[task_index];
126 :
127 : /* setup the new pending task */
- 128 5586 : task->state = TASK_STATE_EMPTY;
- 129 5586 : task->path[0] = 0;
- 130 5586 : task->disk = 0;
- 131 5586 : task->buffer = 0;
- 132 5586 : task->position = blockcur;
- 133 5586 : task->block = 0;
- 134 5586 : task->file = 0;
- 135 5586 : task->file_pos = 0;
- 136 5586 : task->read_size = 0;
- 137 5586 : task->is_timestamp_different = 0;
+ 128 5520 : task->state = TASK_STATE_EMPTY;
+ 129 5520 : task->path[0] = 0;
+ 130 5520 : task->disk = 0;
+ 131 5520 : task->buffer = 0;
+ 132 5520 : task->position = blockcur;
+ 133 5520 : task->block = 0;
+ 134 5520 : task->file = 0;
+ 135 5520 : task->file_pos = 0;
+ 136 5520 : task->read_size = 0;
+ 137 5520 : task->is_timestamp_different = 0;
138 : }
- 139 931 : }
+ 139 920 : }
140 :
141 : /*****************************************************************************/
142 : /* mono thread */
@@ -353,54 +353,54 @@
291 : *
292 : * This is the synchronization point for workers with the io.
293 : */
- 294 1177886 : static struct snapraid_task* io_reader_step(struct snapraid_worker* worker)
+ 294 1177263 : static struct snapraid_task* io_reader_step(struct snapraid_worker* worker)
295 : {
- 296 1177886 : struct snapraid_io* io = worker->io;
+ 296 1177263 : struct snapraid_io* io = worker->io;
297 :
298 : /* the synchronization is protected by the io mutex */
- 299 1177886 : thread_mutex_lock(&io->io_mutex);
+ 299 1177263 : thread_mutex_lock(&io->io_mutex);
300 :
- 301 1004268 : while (1) {
+ 301 1002477 : while (1) {
302 : unsigned next_index;
303 :
304 : /* check if the worker has to exit */
305 : /* even if there is work to do */
- 306 2182154 : if (io->done) {
+ 306 2179740 : if (io->done) {
307 690 : thread_mutex_unlock(&io->io_mutex);
308 690 : return 0;
309 : }
310 :
311 : /* get the next pending task */
- 312 2181464 : next_index = (worker->index + 1) % io->io_max;
+ 312 2179050 : next_index = (worker->index + 1) % io->io_max;
313 :
314 : /* if the queue of pending tasks is not empty */
- 315 2181464 : if (next_index != io->reader_index) {
+ 315 2179050 : if (next_index != io->reader_index) {
316 : struct snapraid_task* task;
317 :
318 : /* the index that the IO may be waiting for */
- 319 1177196 : unsigned waiting_index = io->reader_index;
+ 319 1176573 : unsigned waiting_index = io->reader_index;
320 :
321 : /* the index that worker just completed */
- 322 1177196 : unsigned done_index = worker->index;
+ 322 1176573 : unsigned done_index = worker->index;
323 :
324 : /* get the new working task */
- 325 1177196 : worker->index = next_index;
- 326 1177196 : task = &worker->task_map[worker->index];
+ 325 1176573 : worker->index = next_index;
+ 326 1176573 : task = &worker->task_map[worker->index];
327 :
328 : /* if the just completed task is at this index */
- 329 1177196 : if (done_index == waiting_index) {
+ 329 1176573 : if (done_index == waiting_index) {
330 : /* notify the IO that a new read is complete */
- 331 668 : thread_cond_signal_and_unlock(&io->read_done, &io->io_mutex);
+ 331 827 : thread_cond_signal_and_unlock(&io->read_done, &io->io_mutex);
332 : } else {
- 333 1176528 : thread_mutex_unlock(&io->io_mutex);
+ 333 1175746 : thread_mutex_unlock(&io->io_mutex);
334 : }
335 :
336 : /* return the new task */
- 337 1177196 : return task;
+ 337 1176573 : return task;
338 : }
339 :
340 : /* otherwise wait for a read_sched event */
- 341 1004268 : thread_cond_wait(&io->read_sched, &io->io_mutex);
+ 341 1002477 : thread_cond_wait(&io->read_sched, &io->io_mutex);
342 : }
343 : }
344 :
@@ -409,60 +409,60 @@
347 : *
348 : * This is the synchronization point for workers with the io.
349 : */
- 350 560074 : static struct snapraid_task* io_writer_step(struct snapraid_worker* worker, int state)
+ 350 559696 : static struct snapraid_task* io_writer_step(struct snapraid_worker* worker, int state)
351 : {
- 352 560074 : struct snapraid_io* io = worker->io;
+ 352 559696 : struct snapraid_io* io = worker->io;
353 : int error_index;
354 :
355 : /* the synchronization is protected by the io mutex */
- 356 560074 : thread_mutex_lock(&io->io_mutex);
+ 356 559696 : thread_mutex_lock(&io->io_mutex);
357 :
358 : /* counts the number of errors in the global state */
- 359 560074 : error_index = state - IO_WRITER_ERROR_BASE;
- 360 560074 : if (error_index >= 0 && error_index < IO_WRITER_ERROR_MAX)
+ 359 559696 : error_index = state - IO_WRITER_ERROR_BASE;
+ 360 559696 : if (error_index >= 0 && error_index < IO_WRITER_ERROR_MAX)
361 0 : ++io->writer_error[error_index];
362 :
- 363 549486 : while (1) {
+ 363 551113 : while (1) {
364 : unsigned next_index;
365 :
366 : /* get the next pending task */
- 367 1109560 : next_index = (worker->index + 1) % io->io_max;
+ 367 1110809 : next_index = (worker->index + 1) % io->io_max;
368 :
369 : /* if the queue of pending tasks is not empty */
- 370 1109560 : if (next_index != io->writer_index) {
+ 370 1110809 : if (next_index != io->writer_index) {
371 : struct snapraid_task* task;
372 :
373 : /* the index that the IO may be waiting for */
- 374 559582 : unsigned waiting_index = (io->writer_index + 1) % io->io_max;
+ 374 559204 : unsigned waiting_index = (io->writer_index + 1) % io->io_max;
375 :
376 : /* the index that worker just completed */
- 377 559582 : unsigned done_index = worker->index;
+ 377 559204 : unsigned done_index = worker->index;
378 :
379 : /* get the new working task */
- 380 559582 : worker->index = next_index;
- 381 559582 : task = &worker->task_map[worker->index];
+ 380 559204 : worker->index = next_index;
+ 381 559204 : task = &worker->task_map[worker->index];
382 :
383 : /* if the just completed task is at this index */
- 384 559582 : if (done_index == waiting_index) {
+ 384 559204 : if (done_index == waiting_index) {
385 : /* notify the IO that a new write is complete */
386 0 : thread_cond_signal_and_unlock(&io->write_done, &io->io_mutex);
387 : } else {
- 388 559582 : thread_mutex_unlock(&io->io_mutex);
+ 388 559204 : thread_mutex_unlock(&io->io_mutex);
389 : }
390 :
391 : /* return the new task */
- 392 559582 : return task;
+ 392 559204 : return task;
393 : }
394 :
395 : /* check if the worker has to exit */
396 : /* but only if there is no work to do */
- 397 549978 : if (io->done) {
+ 397 551605 : if (io->done) {
398 492 : thread_mutex_unlock(&io->io_mutex);
399 492 : return 0;
400 : }
401 :
402 : /* otherwise wait for a write_sched event */
- 403 549486 : thread_cond_wait(&io->write_sched, &io->io_mutex);
+ 403 551113 : thread_cond_wait(&io->write_sched, &io->io_mutex);
404 : }
405 : }
406 :
@@ -471,87 +471,87 @@
409 : *
410 : * This is the synchronization point for workers with the io.
411 : */
- 412 146427 : static block_off_t io_read_next_thread(struct snapraid_io* io, void*** buffer)
+ 412 146364 : static block_off_t io_read_next_thread(struct snapraid_io* io, void*** buffer)
413 : {
414 : block_off_t blockcur_schedule;
415 : block_off_t blockcur_caller;
416 : unsigned i;
417 :
418 : /* get the next parity position to process */
- 419 146427 : blockcur_schedule = io_position_next(io);
+ 419 146364 : blockcur_schedule = io_position_next(io);
420 :
421 : /* ensure that all data/parity was read */
- 422 146427 : assert(io->reader_list[0] == io->reader_max);
+ 422 146364 : assert(io->reader_list[0] == io->reader_max);
423 :
424 : /* setup the list of workers to process */
- 425 1383204 : for (i = 0; i <= io->reader_max; ++i)
- 426 1236777 : io->reader_list[i] = i;
+ 425 1382700 : for (i = 0; i <= io->reader_max; ++i)
+ 426 1236336 : io->reader_list[i] = i;
427 :
428 : /* the synchronization is protected by the io mutex */
- 429 146427 : thread_mutex_lock(&io->io_mutex);
+ 429 146364 : thread_mutex_lock(&io->io_mutex);
430 :
431 : /* schedule the next read */
- 432 146427 : io_reader_sched(io, io->reader_index, blockcur_schedule);
+ 432 146364 : io_reader_sched(io, io->reader_index, blockcur_schedule);
433 :
434 : /* set the index for the tasks to return to the caller */
- 435 146427 : io->reader_index = (io->reader_index + 1) % io->io_max;
+ 435 146364 : io->reader_index = (io->reader_index + 1) % io->io_max;
436 :
437 : /* get the position to operate at high level from one task */
- 438 146427 : blockcur_caller = io->reader_map[0].task_map[io->reader_index].position;
+ 438 146364 : blockcur_caller = io->reader_map[0].task_map[io->reader_index].position;
439 :
440 : /* set the buffer to use */
- 441 146427 : *buffer = io->buffer_map[io->reader_index];
+ 441 146364 : *buffer = io->buffer_map[io->reader_index];
442 :
443 : /* signal all the workers that there is a new pending task */
- 444 146427 : thread_cond_broadcast_and_unlock(&io->read_sched, &io->io_mutex);
+ 444 146364 : thread_cond_broadcast_and_unlock(&io->read_sched, &io->io_mutex);
445 :
- 446 146427 : return blockcur_caller;
+ 446 146364 : return blockcur_caller;
447 : }
448 :
- 449 111042 : static void io_write_preset_thread(struct snapraid_io* io, block_off_t blockcur, int skip)
+ 449 110979 : static void io_write_preset_thread(struct snapraid_io* io, block_off_t blockcur, int skip)
450 : {
451 : (void)io;
452 : (void)blockcur;
453 : (void)skip;
- 454 111042 : }
+ 454 110979 : }
455 :
- 456 111042 : static void io_write_next_thread(struct snapraid_io* io, block_off_t blockcur, int skip, int* writer_error)
+ 456 110979 : static void io_write_next_thread(struct snapraid_io* io, block_off_t blockcur, int skip, int* writer_error)
457 : {
458 : unsigned i;
459 :
460 : /* ensure that all parity was written */
- 461 111042 : assert(io->writer_list[0] == io->writer_max);
+ 461 110979 : assert(io->writer_list[0] == io->writer_max);
462 :
463 : /* setup the list of workers to process */
- 464 781666 : for (i = 0; i <= io->writer_max; ++i)
- 465 670624 : io->writer_list[i] = i;
+ 464 781162 : for (i = 0; i <= io->writer_max; ++i)
+ 465 670183 : io->writer_list[i] = i;
466 :
467 : /* the synchronization is protected by the io mutex */
- 468 111042 : thread_mutex_lock(&io->io_mutex);
+ 468 110979 : thread_mutex_lock(&io->io_mutex);
469 :
470 : /* report errors */
- 471 555210 : for (i = 0; i < IO_WRITER_ERROR_MAX; ++i) {
- 472 444168 : writer_error[i] = io->writer_error[i];
- 473 444168 : io->writer_error[i] = 0;
+ 471 554895 : for (i = 0; i < IO_WRITER_ERROR_MAX; ++i) {
+ 472 443916 : writer_error[i] = io->writer_error[i];
+ 473 443916 : io->writer_error[i] = 0;
474 : }
475 :
- 476 111042 : if (skip) {
+ 476 110979 : if (skip) {
477 : /* skip the next write */
- 478 931 : io_writer_sched_empty(io, io->writer_index, blockcur);
+ 478 920 : io_writer_sched_empty(io, io->writer_index, blockcur);
479 : } else {
480 : /* schedule the next write */
- 481 110111 : io_writer_sched(io, io->writer_index, blockcur);
+ 481 110059 : io_writer_sched(io, io->writer_index, blockcur);
482 : }
483 :
484 : /* at this point the writers must be in sync with the readers */
- 485 111042 : assert(io->writer_index == io->reader_index);
+ 485 110979 : assert(io->writer_index == io->reader_index);
486 :
487 : /* set the index to be used for the next write */
- 488 111042 : io->writer_index = (io->writer_index + 1) % io->io_max;
+ 488 110979 : io->writer_index = (io->writer_index + 1) % io->io_max;
489 :
490 : /* signal all the workers that there is a new pending task */
- 491 111042 : thread_cond_broadcast_and_unlock(&io->write_sched, &io->io_mutex);
- 492 111042 : }
+ 491 110979 : thread_cond_broadcast_and_unlock(&io->write_sched, &io->io_mutex);
+ 492 110979 : }
493 :
494 1 : static void io_refresh_thread(struct snapraid_io* io)
495 : {
@@ -599,120 +599,120 @@
537 1 : thread_mutex_unlock(&io->io_mutex);
538 1 : }
539 :
- 540 105587 : static void io_flush_thread(struct snapraid_io* io)
+ 540 108200 : static void io_flush_thread(struct snapraid_io* io)
541 : {
542 : unsigned i;
543 :
- 544 105499 : while (1) {
- 545 105587 : int all_done = 1;
+ 544 108112 : while (1) {
+ 545 108200 : int all_done = 1;
546 :
547 : /* the synchronization is protected by the io mutex */
- 548 105587 : thread_mutex_lock(&io->io_mutex);
+ 548 108200 : thread_mutex_lock(&io->io_mutex);
549 :
- 550 161400 : for (i = 0; i < io->writer_max; ++i) {
- 551 161312 : struct snapraid_worker* worker = &io->writer_map[i];
+ 550 194281 : for (i = 0; i < io->writer_max; ++i) {
+ 551 194193 : struct snapraid_worker* worker = &io->writer_map[i];
552 :
553 : /* get the next pending task */
- 554 161312 : unsigned next_index = (worker->index + 1) % io->io_max;
+ 554 194193 : unsigned next_index = (worker->index + 1) % io->io_max;
555 :
556 : /* if the queue of pending tasks is not empty */
- 557 161312 : if (next_index != io->writer_index) {
- 558 105499 : all_done = 0;
- 559 105499 : break;
+ 557 194193 : if (next_index != io->writer_index) {
+ 558 108112 : all_done = 0;
+ 559 108112 : break;
560 : }
561 : }
562 :
- 563 105587 : thread_mutex_unlock(&io->io_mutex);
+ 563 108200 : thread_mutex_unlock(&io->io_mutex);
564 :
- 565 105587 : if (all_done)
+ 565 108200 : if (all_done)
566 88 : break;
567 :
568 : /* wait for something to complete */
- 569 105499 : thread_yield();
+ 569 108112 : thread_yield();
570 : }
571 88 : }
572 :
- 573 1089660 : static struct snapraid_task* io_task_read_thread(struct snapraid_io* io, unsigned base, unsigned count, unsigned* pos, unsigned* waiting_map, unsigned* waiting_mac)
+ 573 1089282 : static struct snapraid_task* io_task_read_thread(struct snapraid_io* io, unsigned base, unsigned count, unsigned* pos, unsigned* waiting_map, unsigned* waiting_mac)
574 : {
575 : unsigned waiting_cycle;
576 :
577 : /* count the waiting cycle */
- 578 1089660 : waiting_cycle = 0;
+ 578 1089282 : waiting_cycle = 0;
579 :
580 : /* clear the waiting indexes */
- 581 1089660 : *waiting_mac = 0;
+ 581 1089282 : *waiting_mac = 0;
582 :
583 : /* the synchronization is protected by the io mutex */
- 584 1089660 : thread_mutex_lock(&io->io_mutex);
+ 584 1089282 : thread_mutex_lock(&io->io_mutex);
585 :
- 586 576 : while (1) {
+ 586 700 : while (1) {
587 : unsigned char* let;
588 : unsigned busy_index;
589 :
590 : /* get the index the IO is using */
591 : /* we must ensure that this index has not a read in progress */
592 : /* to avoid a concurrent access */
- 593 1090236 : busy_index = io->reader_index;
+ 593 1089982 : busy_index = io->reader_index;
594 :
595 : /* search for a worker that has already finished */
- 596 1090236 : let = &io->reader_list[0];
- 597 4632 : while (1) {
- 598 1094868 : unsigned i = *let;
+ 596 1089982 : let = &io->reader_list[0];
+ 597 5383 : while (1) {
+ 598 1095365 : unsigned i = *let;
599 :
600 : /* if we are at the end */
- 601 1094868 : if (i == io->reader_max)
- 602 576 : break;
+ 601 1095365 : if (i == io->reader_max)
+ 602 700 : break;
603 :
604 : /* if it's in range */
- 605 1094292 : if (base <= i && i < base + count) {
+ 605 1094665 : if (base <= i && i < base + count) {
606 : struct snapraid_worker* worker;
607 :
608 : /* if it's the first cycle */
- 609 1091472 : if (waiting_cycle == 0) {
+ 609 1091581 : if (waiting_cycle == 0) {
610 : /* store the waiting indexes */
- 611 1090868 : waiting_map[(*waiting_mac)++] = i - base;
+ 611 1090833 : waiting_map[(*waiting_mac)++] = i - base;
612 : }
613 :
- 614 1091472 : worker = &io->reader_map[i];
+ 614 1091581 : worker = &io->reader_map[i];
615 :
616 : /* if the worker has finished this index */
- 617 1091472 : if (busy_index != worker->index) {
+ 617 1091581 : if (busy_index != worker->index) {
618 : struct snapraid_task* task;
619 :
- 620 1089660 : task = &worker->task_map[io->reader_index];
+ 620 1089282 : task = &worker->task_map[io->reader_index];
621 :
- 622 1089660 : thread_mutex_unlock(&io->io_mutex);
+ 622 1089282 : thread_mutex_unlock(&io->io_mutex);
623 :
624 : /* mark the worker as processed */
625 : /* setting the previous one to point at the next one */
- 626 1089660 : *let = io->reader_list[i + 1];
+ 626 1089282 : *let = io->reader_list[i + 1];
627 :
628 : /* return the position */
- 629 1089660 : *pos = i - base;
+ 629 1089282 : *pos = i - base;
630 :
631 : /* on the first cycle, no one is waiting */
- 632 1089660 : if (waiting_cycle == 0)
- 633 1089084 : *waiting_mac = 0;
+ 632 1089282 : if (waiting_cycle == 0)
+ 633 1088587 : *waiting_mac = 0;
634 :
- 635 1089660 : return task;
+ 635 1089282 : return task;
636 : }
637 : }
638 :
639 : /* next position to check */
- 640 4632 : let = &io->reader_list[i + 1];
+ 640 5383 : let = &io->reader_list[i + 1];
641 : }
642 :
643 : /* if no worker is ready, wait for an event */
- 644 576 : thread_cond_wait(&io->read_done, &io->io_mutex);
+ 644 700 : thread_cond_wait(&io->read_done, &io->io_mutex);
645 :
646 : /* count the cycles */
- 647 576 : ++waiting_cycle;
+ 647 700 : ++waiting_cycle;
648 : }
649 : }
650 :
- 651 877956 : static struct snapraid_task* io_data_read_thread(struct snapraid_io* io, unsigned* pos, unsigned* waiting_map, unsigned* waiting_mac)
+ 651 877578 : static struct snapraid_task* io_data_read_thread(struct snapraid_io* io, unsigned* pos, unsigned* waiting_map, unsigned* waiting_mac)
652 : {
- 653 877956 : return io_task_read_thread(io, io->data_base, io->data_count, pos, waiting_map, waiting_mac);
+ 653 877578 : return io_task_read_thread(io, io->data_base, io->data_count, pos, waiting_map, waiting_mac);
654 : }
655 :
656 211704 : static struct snapraid_task* io_parity_read_thread(struct snapraid_io* io, unsigned* pos, unsigned* waiting_map, unsigned* waiting_mac)
@@ -720,18 +720,18 @@
658 211704 : return io_task_read_thread(io, io->parity_base, io->parity_count, pos, waiting_map, waiting_mac);
659 : }
660 :
- 661 559582 : static void io_parity_write_thread(struct snapraid_io* io, unsigned* pos, unsigned* waiting_map, unsigned* waiting_mac)
+ 661 559204 : static void io_parity_write_thread(struct snapraid_io* io, unsigned* pos, unsigned* waiting_map, unsigned* waiting_mac)
662 : {
663 : unsigned waiting_cycle;
664 :
665 : /* count the waiting cycle */
- 666 559582 : waiting_cycle = 0;
+ 666 559204 : waiting_cycle = 0;
667 :
668 : /* clear the waiting indexes */
- 669 559582 : *waiting_mac = 0;
+ 669 559204 : *waiting_mac = 0;
670 :
671 : /* the synchronization is protected by the io mutex */
- 672 559582 : thread_mutex_lock(&io->io_mutex);
+ 672 559204 : thread_mutex_lock(&io->io_mutex);
673 :
674 0 : while (1) {
675 : unsigned char* let;
@@ -742,45 +742,45 @@
680 : /* to avoid a concurrent access */
681 : /* note that we are already sure that a write is not in progress */
682 : /* at the index the IO is using at now */
- 683 559582 : busy_index = (io->writer_index + 1) % io->io_max;
+ 683 559204 : busy_index = (io->writer_index + 1) % io->io_max;
684 :
685 : /* search for a worker that has already finished */
- 686 559582 : let = &io->writer_list[0];
+ 686 559204 : let = &io->writer_list[0];
687 0 : while (1) {
- 688 559582 : unsigned i = *let;
+ 688 559204 : unsigned i = *let;
689 : struct snapraid_worker* worker;
690 :
691 : /* if we are at the end */
- 692 559582 : if (i == io->writer_max)
+ 692 559204 : if (i == io->writer_max)
693 0 : break;
694 :
695 : /* if it's the first cycle */
- 696 559582 : if (waiting_cycle == 0) {
+ 696 559204 : if (waiting_cycle == 0) {
697 : /* store the waiting indexes */
- 698 559582 : waiting_map[(*waiting_mac)++] = i;
+ 698 559204 : waiting_map[(*waiting_mac)++] = i;
699 : }
700 :
- 701 559582 : worker = &io->writer_map[i];
+ 701 559204 : worker = &io->writer_map[i];
702 :
703 : /* the two indexes cannot be equal */
- 704 559582 : assert(io->writer_index != worker->index);
+ 704 559204 : assert(io->writer_index != worker->index);
705 :
706 : /* if the worker has finished this index */
- 707 559582 : if (busy_index != worker->index) {
- 708 559582 : thread_mutex_unlock(&io->io_mutex);
+ 707 559204 : if (busy_index != worker->index) {
+ 708 559204 : thread_mutex_unlock(&io->io_mutex);
709 :
710 : /* mark the worker as processed */
711 : /* setting the previous one to point at the next one */
- 712 559582 : *let = io->writer_list[i + 1];
+ 712 559204 : *let = io->writer_list[i + 1];
713 :
714 : /* return the position */
- 715 559582 : *pos = i;
+ 715 559204 : *pos = i;
716 :
717 : /* on the first cycle, no one is waiting */
- 718 559582 : if (waiting_cycle == 0)
- 719 559582 : *waiting_mac = 0;
+ 718 559204 : if (waiting_cycle == 0)
+ 719 559204 : *waiting_mac = 0;
720 :
- 721 559582 : return;
+ 721 559204 : return;
722 : }
723 :
724 : /* next position to check */
@@ -795,16 +795,16 @@
733 : }
734 : }
735 :
- 736 1089792 : static void io_reader_worker(struct snapraid_worker* worker, struct snapraid_task* task)
+ 736 1089420 : static void io_reader_worker(struct snapraid_worker* worker, struct snapraid_task* task)
737 : {
738 : /* if we reached the end */
- 739 1089792 : if (task->position >= worker->io->block_max) {
+ 739 1089420 : if (task->position >= worker->io->block_max) {
740 : /* complete a dummy task */
- 741 132 : task->state = TASK_STATE_EMPTY;
+ 741 138 : task->state = TASK_STATE_EMPTY;
742 : } else {
- 743 1089660 : worker->func(worker, task);
+ 743 1089282 : worker->func(worker, task);
744 : }
- 745 1089792 : }
+ 745 1089420 : }
746 :
747 690 : static void* io_reader_thread(void* arg)
748 : {
@@ -813,24 +813,24 @@
751 : /* force completion of the first task */
752 690 : io_reader_worker(worker, &worker->task_map[0]);
753 :
- 754 1177196 : while (1) {
+ 754 1176573 : while (1) {
755 : struct snapraid_task* task;
756 :
757 : /* get the new task */
- 758 1177886 : task = io_reader_step(worker);
+ 758 1177263 : task = io_reader_step(worker);
759 :
760 : /* if no task, it means to exit */
- 761 1177886 : if (!task)
+ 761 1177263 : if (!task)
762 690 : break;
763 :
764 : /* nothing more to do */
- 765 1177196 : if (task->state == TASK_STATE_EMPTY)
- 766 88094 : continue;
+ 765 1176573 : if (task->state == TASK_STATE_EMPTY)
+ 766 87843 : continue;
767 :
- 768 1089102 : assert(task->state == TASK_STATE_READY);
+ 768 1088730 : assert(task->state == TASK_STATE_READY);
769 :
770 : /* work on the assigned task */
- 771 1089102 : io_reader_worker(worker, task);
+ 771 1088730 : io_reader_worker(worker, task);
772 : }
773 :
774 690 : return 0;
@@ -841,29 +841,29 @@
779 492 : struct snapraid_worker* worker = arg;
780 492 : int latest_state = TASK_STATE_DONE;
781 :
- 782 559582 : while (1) {
+ 782 559204 : while (1) {
783 : struct snapraid_task* task;
784 :
785 : /* get the new task */
- 786 560074 : task = io_writer_step(worker, latest_state);
+ 786 559696 : task = io_writer_step(worker, latest_state);
787 :
788 : /* if no task, it means to exit */
- 789 560074 : if (!task)
+ 789 559696 : if (!task)
790 492 : break;
791 :
792 : /* nothing more to do */
- 793 559582 : if (task->state == TASK_STATE_EMPTY) {
- 794 5586 : latest_state = TASK_STATE_DONE;
- 795 5586 : continue;
+ 793 559204 : if (task->state == TASK_STATE_EMPTY) {
+ 794 5520 : latest_state = TASK_STATE_DONE;
+ 795 5520 : continue;
796 : }
797 :
- 798 553996 : assert(task->state == TASK_STATE_READY);
+ 798 553684 : assert(task->state == TASK_STATE_READY);
799 :
800 : /* work on the assigned task */
- 801 553996 : worker->func(worker, task);
+ 801 553684 : worker->func(worker, task);
802 :
803 : /* save the resulting state */
- 804 553996 : latest_state = task->state;
+ 804 553684 : latest_state = task->state;
805 : }
806 :
807 492 : return 0;
diff --git a/cov/cmdline/list.c.func-sort-c.html b/cov/cmdline/list.c.func-sort-c.html
index 6160af18..b8ed0eb3 100644
--- a/cov/cmdline/list.c.func-sort-c.html
+++ b/cov/cmdline/list.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/cmdline/list.c.func.html b/cov/cmdline/list.c.func.html
index 74144636..c8ff02a0 100644
--- a/cov/cmdline/list.c.func.html
+++ b/cov/cmdline/list.c.func.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/cmdline/list.c.gcov.html b/cov/cmdline/list.c.gcov.html
index d365932e..c7963829 100644
--- a/cov/cmdline/list.c.gcov.html
+++ b/cov/cmdline/list.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/cmdline/main.c.func-sort-c.html b/cov/cmdline/main.c.func-sort-c.html
index 04900a31..948dc1f3 100644
--- a/cov/cmdline/main.c.func-sort-c.html
+++ b/cov/cmdline/main.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -65,7 +65,7 @@
| main |
- 289 |
+ 290 |
diff --git a/cov/cmdline/main.c.func.html b/cov/cmdline/main.c.func.html
index 9e64c6f8..e705c789 100644
--- a/cov/cmdline/main.c.func.html
+++ b/cov/cmdline/main.c.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -65,7 +65,7 @@
| main |
- 289 |
+ 290 |
diff --git a/cov/cmdline/main.c.gcov.html b/cov/cmdline/main.c.gcov.html
index 06014c51..3a071ce0 100644
--- a/cov/cmdline/main.c.gcov.html
+++ b/cov/cmdline/main.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -381,27 +381,27 @@
319 : }
320 : /* LCOV_EXCL_STOP */
321 :
- 322 289 : int main(int argc, char* argv[])
+ 322 290 : int main(int argc, char* argv[])
323 : {
324 : int mode;
325 : int i, j;
326 : int ret;
327 :
- 328 289 : mode = MODE_DEFAULT;
- 329 289 : j = 1;
- 330 4328 : for (i = 1; i < argc; ++i) {
- 331 4039 : if (strcmp(argv[i], "-s") == 0 || strcmp(argv[i], "--spin-down-on-error") == 0) {
+ 328 290 : mode = MODE_DEFAULT;
+ 329 290 : j = 1;
+ 330 4330 : for (i = 1; i < argc; ++i) {
+ 331 4040 : if (strcmp(argv[i], "-s") == 0 || strcmp(argv[i], "--spin-down-on-error") == 0) {
332 1 : mode = MODE_SPINDOWN;
333 : } else {
- 334 4038 : argv[j] = argv[i];
- 335 4038 : ++j;
+ 334 4039 : argv[j] = argv[i];
+ 335 4039 : ++j;
336 : }
337 : }
- 338 289 : argc = j;
- 339 289 : argv[argc] = 0;
+ 338 290 : argc = j;
+ 339 290 : argv[argc] = 0;
340 :
- 341 289 : if (mode == MODE_DEFAULT) {
- 342 288 : ret = snapraid_main(argc, argv);
+ 341 290 : if (mode == MODE_DEFAULT) {
+ 342 289 : ret = snapraid_main(argc, argv);
343 : } else {
344 : struct sigaction sa;
345 :
@@ -499,7 +499,7 @@
437 : }
438 : }
439 :
- 440 256 : return ret;
+ 440 257 : return ret;
441 : }
442 : #endif
443 :
diff --git a/cov/cmdline/metro.c.func-sort-c.html b/cov/cmdline/metro.c.func-sort-c.html
index b66d3e97..1a4c21ca 100644
--- a/cov/cmdline/metro.c.func-sort-c.html
+++ b/cov/cmdline/metro.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,7 +61,7 @@
| MetroHash128 |
- 369 |
+ 393 |
diff --git a/cov/cmdline/metro.c.func.html b/cov/cmdline/metro.c.func.html
index 5e61b75e..e219fd9b 100644
--- a/cov/cmdline/metro.c.func.html
+++ b/cov/cmdline/metro.c.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,7 +61,7 @@
| MetroHash128 |
- 369 |
+ 393 |
diff --git a/cov/cmdline/metro.c.gcov.html b/cov/cmdline/metro.c.gcov.html
index 817ebc45..436f25b5 100644
--- a/cov/cmdline/metro.c.gcov.html
+++ b/cov/cmdline/metro.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -107,9 +107,9 @@
45 : static const uint64_t k2 = 0x7BDEC03B;
46 : static const uint64_t k3 = 0x2F5870A5;
47 :
- 48 369 : void MetroHash128(const void* data, size_t size, const uint8_t* seed, uint8_t* digest)
+ 48 393 : void MetroHash128(const void* data, size_t size, const uint8_t* seed, uint8_t* digest)
49 : {
- 50 369 : const uint8_t* ptr = data;
+ 50 393 : const uint8_t* ptr = data;
51 : uint64_t v[4];
52 :
53 : /*
@@ -120,10 +120,10 @@
58 : * v[0] = (static_cast<uint64_t>(seed) - k0) * k3;
59 : * v[1] = (static_cast<uint64_t>(seed) + k1) * k2;
60 : */
- 61 369 : v[0] = (util_read64(seed) - k0) * k3;
- 62 369 : v[1] = (util_read64(seed + 8) + k1) * k2;
+ 61 393 : v[0] = (util_read64(seed) - k0) * k3;
+ 62 393 : v[1] = (util_read64(seed + 8) + k1) * k2;
63 :
- 64 369 : if (size >= 32) {
+ 64 393 : if (size >= 32) {
65 : /*
66 : * EXTENSION: Initialize secondary state using both halves of the 128-bit seed
67 : *
@@ -131,24 +131,24 @@
69 : * v[2] = (static_cast<uint64_t>(seed) + k0) * k2;
70 : * v[3] = (static_cast<uint64_t>(seed) - k1) * k3;
71 : */
- 72 333 : v[2] = (util_read64(seed) + k0) * k2;
- 73 333 : v[3] = (util_read64(seed + 8) - k1) * k3;
+ 72 357 : v[2] = (util_read64(seed) + k0) * k2;
+ 73 357 : v[3] = (util_read64(seed + 8) - k1) * k3;
74 :
75 : do {
- 76 852876 : v[0] += util_read64(ptr) * k0; ptr += 8; v[0] = util_rotr64(v[0], 29) + v[2];
- 77 852876 : v[1] += util_read64(ptr) * k1; ptr += 8; v[1] = util_rotr64(v[1], 29) + v[3];
- 78 852876 : v[2] += util_read64(ptr) * k2; ptr += 8; v[2] = util_rotr64(v[2], 29) + v[0];
- 79 852876 : v[3] += util_read64(ptr) * k3; ptr += 8; v[3] = util_rotr64(v[3], 29) + v[1];
- 80 852876 : size -= 32;
- 81 852876 : } while (size >= 32);
+ 76 1049484 : v[0] += util_read64(ptr) * k0; ptr += 8; v[0] = util_rotr64(v[0], 29) + v[2];
+ 77 1049484 : v[1] += util_read64(ptr) * k1; ptr += 8; v[1] = util_rotr64(v[1], 29) + v[3];
+ 78 1049484 : v[2] += util_read64(ptr) * k2; ptr += 8; v[2] = util_rotr64(v[2], 29) + v[0];
+ 79 1049484 : v[3] += util_read64(ptr) * k3; ptr += 8; v[3] = util_rotr64(v[3], 29) + v[1];
+ 80 1049484 : size -= 32;
+ 81 1049484 : } while (size >= 32);
82 :
- 83 333 : v[2] ^= util_rotr64(((v[0] + v[3]) * k0) + v[1], 21) * k1;
- 84 333 : v[3] ^= util_rotr64(((v[1] + v[2]) * k1) + v[0], 21) * k0;
- 85 333 : v[0] ^= util_rotr64(((v[0] + v[2]) * k0) + v[3], 21) * k1;
- 86 333 : v[1] ^= util_rotr64(((v[1] + v[3]) * k1) + v[2], 21) * k0;
+ 83 357 : v[2] ^= util_rotr64(((v[0] + v[3]) * k0) + v[1], 21) * k1;
+ 84 357 : v[3] ^= util_rotr64(((v[1] + v[2]) * k1) + v[0], 21) * k0;
+ 85 357 : v[0] ^= util_rotr64(((v[0] + v[2]) * k0) + v[3], 21) * k1;
+ 86 357 : v[1] ^= util_rotr64(((v[1] + v[3]) * k1) + v[2], 21) * k0;
87 : }
88 :
- 89 369 : if (size >= 16) {
+ 89 393 : if (size >= 16) {
90 132 : v[0] += util_read64(ptr) * k2; ptr += 8; v[0] = util_rotr64(v[0], 33) * k3;
91 132 : v[1] += util_read64(ptr) * k2; ptr += 8; v[1] = util_rotr64(v[1], 33) * k3;
92 132 : v[0] ^= util_rotr64((v[0] * k2) + v[1], 45) * k1;
@@ -156,37 +156,37 @@
94 132 : size -= 16;
95 : }
96 :
- 97 369 : if (size >= 8) {
+ 97 393 : if (size >= 8) {
98 134 : v[0] += util_read64(ptr) * k2; ptr += 8; v[0] = util_rotr64(v[0], 33) * k3;
99 134 : v[0] ^= util_rotr64((v[0] * k2) + v[1], 27) * k1;
100 134 : size -= 8;
101 : }
102 :
- 103 369 : if (size >= 4) {
+ 103 393 : if (size >= 4) {
104 132 : v[1] += util_read32(ptr) * k2; ptr += 4; v[1] = util_rotr64(v[1], 33) * k3;
105 132 : v[1] ^= util_rotr64((v[1] * k3) + v[0], 46) * k0;
106 132 : size -= 4;
107 : }
108 :
- 109 369 : if (size >= 2) {
+ 109 393 : if (size >= 2) {
110 135 : v[0] += util_read16(ptr) * k2; ptr += 2; v[0] = util_rotr64(v[0], 33) * k3;
111 135 : v[0] ^= util_rotr64((v[0] * k2) + v[1], 22) * k1;
112 135 : size -= 2;
113 : }
114 :
- 115 369 : if (size >= 1) {
+ 115 393 : if (size >= 1) {
116 133 : v[1] += util_read8(ptr) * k2; v[1] = util_rotr64(v[1], 33) * k3;
117 133 : v[1] ^= util_rotr64((v[1] * k3) + v[0], 58) * k0;
118 : }
119 :
- 120 369 : v[0] += util_rotr64((v[0] * k0) + v[1], 13);
- 121 369 : v[1] += util_rotr64((v[1] * k1) + v[0], 37);
- 122 369 : v[0] += util_rotr64((v[0] * k2) + v[1], 13);
- 123 369 : v[1] += util_rotr64((v[1] * k3) + v[0], 37);
+ 120 393 : v[0] += util_rotr64((v[0] * k0) + v[1], 13);
+ 121 393 : v[1] += util_rotr64((v[1] * k1) + v[0], 37);
+ 122 393 : v[0] += util_rotr64((v[0] * k2) + v[1], 13);
+ 123 393 : v[1] += util_rotr64((v[1] * k3) + v[0], 37);
124 :
- 125 369 : util_write64(digest, v[0]);
- 126 369 : util_write64(digest + 8, v[1]);
- 127 369 : }
+ 125 393 : util_write64(digest, v[0]);
+ 126 393 : util_write64(digest + 8, v[1]);
+ 127 393 : }
128 :
diff --git a/cov/cmdline/mkstream.c.func-sort-c.html b/cov/cmdline/mkstream.c.func-sort-c.html
index 9f99c180..5c259716 100644
--- a/cov/cmdline/mkstream.c.func-sort-c.html
+++ b/cov/cmdline/mkstream.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/cmdline/mkstream.c.func.html b/cov/cmdline/mkstream.c.func.html
index 18ef917b..31f6e1d2 100644
--- a/cov/cmdline/mkstream.c.func.html
+++ b/cov/cmdline/mkstream.c.func.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/cmdline/mkstream.c.gcov.html b/cov/cmdline/mkstream.c.gcov.html
index 0e3663c9..d58651cd 100644
--- a/cov/cmdline/mkstream.c.gcov.html
+++ b/cov/cmdline/mkstream.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/cmdline/mktest.c.func-sort-c.html b/cov/cmdline/mktest.c.func-sort-c.html
index ddc4e72b..d7479dd2 100644
--- a/cov/cmdline/mktest.c.func-sort-c.html
+++ b/cov/cmdline/mktest.c.func-sort-c.html
@@ -31,13 +31,13 @@
|
-
+
-
+
-
+
|
@@ -69,7 +69,7 @@
| cmd_generate_symlink |
- 940 |
+ 932 |
| fallback |
@@ -85,19 +85,19 @@
| cmd_truncate |
- 3121 |
+ 3136 |
| cmd_delete |
- 3205 |
+ 3160 |
| cmd_append |
- 3258 |
+ 3215 |
| cmd_write |
- 6176 |
+ 6236 |
| cmd_change |
@@ -113,23 +113,23 @@
| rnd_name |
- 26849 |
+ 26841 |
| rndnz_range |
- 32674 |
+ 32691 |
| file_cmp |
- 146738 |
+ 146742 |
| rndnz |
- 55633505 |
+ 55624443 |
| rnd |
- 56044755 |
+ 56035837 |
diff --git a/cov/cmdline/mktest.c.func.html b/cov/cmdline/mktest.c.func.html
index 63678c03..526da4d8 100644
--- a/cov/cmdline/mktest.c.func.html
+++ b/cov/cmdline/mktest.c.func.html
@@ -31,13 +31,13 @@
|
-
+
-
+
-
+
|
@@ -61,7 +61,7 @@
| cmd_append |
- 3258 |
+ 3215 |
| cmd_change |
@@ -73,7 +73,7 @@
| cmd_delete |
- 3205 |
+ 3160 |
| cmd_generate |
@@ -85,15 +85,15 @@
| cmd_generate_symlink |
- 940 |
+ 932 |
| cmd_truncate |
- 3121 |
+ 3136 |
| cmd_write |
- 6176 |
+ 6236 |
| fallback |
@@ -101,7 +101,7 @@
| file_cmp |
- 146738 |
+ 146742 |
| help |
@@ -113,15 +113,15 @@
| rnd |
- 56044755 |
+ 56035837 |
| rnd_name |
- 26849 |
+ 26841 |
| rndnz |
- 55633505 |
+ 55624443 |
| rndnz_damage |
@@ -129,7 +129,7 @@
| rndnz_range |
- 32674 |
+ 32691 |
diff --git a/cov/cmdline/mktest.c.gcov.html b/cov/cmdline/mktest.c.gcov.html
index fcec551c..ee7112ef 100644
--- a/cov/cmdline/mktest.c.gcov.html
+++ b/cov/cmdline/mktest.c.gcov.html
@@ -31,13 +31,13 @@
|
-
+
-
+
-
+
|
@@ -91,28 +91,28 @@
29 : */
30 : unsigned long long seed = 0;
31 :
- 32 56044755 : unsigned rnd(unsigned max)
+ 32 56035837 : unsigned rnd(unsigned max)
33 : {
- 34 56044755 : seed = seed * 6364136223846793005LL + 1442695040888963407LL;
+ 34 56035837 : seed = seed * 6364136223846793005LL + 1442695040888963407LL;
35 :
- 36 56044755 : return (seed >> 32) % max;
+ 36 56035837 : return (seed >> 32) % max;
37 : }
38 :
- 39 55633505 : unsigned rndnz(unsigned max)
+ 39 55624443 : unsigned rndnz(unsigned max)
40 : {
- 41 55633505 : if (max <= 1)
+ 41 55624443 : if (max <= 1)
42 2831 : return 1;
43 : else
- 44 55630674 : return rnd(max - 1) + 1;
+ 44 55621612 : return rnd(max - 1) + 1;
45 : }
46 :
- 47 32674 : void rndnz_range(unsigned char* data, int size)
+ 47 32691 : void rndnz_range(unsigned char* data, int size)
48 : {
49 : int i;
50 :
- 51 55659420 : for (i = 0; i < size; ++i)
- 52 55626746 : data[i] = rndnz(256);
- 53 32674 : }
+ 51 55650371 : for (i = 0; i < size; ++i)
+ 52 55617680 : data[i] = rndnz(256);
+ 53 32691 : }
54 :
55 1821 : void rndnz_damage(unsigned char* data, int size)
56 : {
@@ -123,8 +123,8 @@
61 : unsigned char c;
62 :
63 : do {
- 64 1828 : c = rndnz(256);
- 65 1828 : } while (c == data[i]);
+ 64 1832 : c = rndnz(256);
+ 65 1832 : } while (c == data[i]);
66 :
67 1821 : data[i] = c;
68 : }
@@ -133,23 +133,23 @@
71 : char CHARSET[] = "qwertyuiopasdfghjklzxcvbnm1234567890 .-+";
72 : #define CHARSET_LEN (sizeof(CHARSET) - 1)
73 :
- 74 26849 : void rnd_name(char* file)
+ 74 26841 : void rnd_name(char* file)
75 : {
- 76 26849 : int l = 1 + rnd(20);
+ 76 26841 : int l = 1 + rnd(20);
77 :
- 78 308613 : while (l) {
- 79 281764 : *file++ = CHARSET[rnd(CHARSET_LEN)];
- 80 281764 : --l;
+ 78 308703 : while (l) {
+ 79 281862 : *file++ = CHARSET[rnd(CHARSET_LEN)];
+ 80 281862 : --l;
81 : }
- 82 26849 : *file = 0;
- 83 26849 : }
+ 82 26841 : *file = 0;
+ 83 26841 : }
84 :
85 : /****************************************************************************/
86 : /* file */
87 :
- 88 146738 : int file_cmp(const void* a, const void* b)
+ 88 146742 : int file_cmp(const void* a, const void* b)
89 : {
- 90 146738 : return strcmp(a, b);
+ 90 146742 : return strcmp(a, b);
91 : }
92 :
93 1821 : int fallback(int f, struct stat* st)
@@ -261,11 +261,11 @@
199 : * Create a symlink.
200 : * - If the file already exists, it's removed.
201 : */
- 202 940 : void cmd_generate_symlink(const char* path, const char* linkto)
+ 202 932 : void cmd_generate_symlink(const char* path, const char* linkto)
203 : {
204 : /* remove the existing file/symlink if any */
- 205 940 : if (remove(path) != 0) {
- 206 919 : if (errno != ENOENT) {
+ 205 932 : if (remove(path) != 0) {
+ 206 911 : if (errno != ENOENT) {
207 : /* LCOV_EXCL_START */
208 : log_fatal(errno, "Error removing file %s\n", path);
209 : exit(EXIT_FAILURE);
@@ -273,13 +273,13 @@
211 : }
212 : }
213 :
- 214 940 : if (symlink(linkto, path) != 0) {
+ 214 932 : if (symlink(linkto, path) != 0) {
215 : /* LCOV_EXCL_START */
216 : log_fatal(errno, "Error writing symlink %s\n", path);
217 : exit(EXIT_FAILURE);
218 : /* LCOV_EXCL_STOP */
219 : }
- 220 940 : }
+ 220 932 : }
221 :
222 : /**
223 : * Create a file or a symlink with a random name.
@@ -352,68 +352,68 @@
290 : * - The written data may be equal or not at the already existing one.
291 : * - If it's a symlink nothing is done.
292 : */
- 293 6176 : void cmd_write(const char* path, int size)
+ 293 6236 : void cmd_write(const char* path, int size)
294 : {
295 : struct stat st;
296 :
- 297 6176 : if (lstat(path, &st) != 0) {
+ 297 6236 : if (lstat(path, &st) != 0) {
298 : /* LCOV_EXCL_START */
299 : log_fatal(errno, "Error accessing %s\n", path);
300 : exit(EXIT_FAILURE);
301 : /* LCOV_EXCL_STOP */
302 : }
303 :
- 304 6176 : if (S_ISREG(st.st_mode)) {
+ 304 6236 : if (S_ISREG(st.st_mode)) {
305 : unsigned char* data;
306 : off_t off;
307 : int f;
308 :
309 : /* not over the end */
- 310 6149 : if (size > st.st_size)
- 311 686 : size = st.st_size;
+ 310 6209 : if (size > st.st_size)
+ 311 677 : size = st.st_size;
312 :
313 : /* start at random position inside the file */
- 314 6149 : if (size < st.st_size)
- 315 5463 : off = rnd(st.st_size - size);
+ 314 6209 : if (size < st.st_size)
+ 315 5530 : off = rnd(st.st_size - size);
316 : else
- 317 686 : off = 0;
+ 317 679 : off = 0;
318 :
- 319 6149 : data = malloc(size);
+ 319 6209 : data = malloc(size);
320 :
- 321 6149 : rndnz_range(data, size);
+ 321 6209 : rndnz_range(data, size);
322 :
- 323 6149 : f = open(path, O_WRONLY | O_BINARY | O_NOFOLLOW);
- 324 6149 : if (f < 0) {
+ 323 6209 : f = open(path, O_WRONLY | O_BINARY | O_NOFOLLOW);
+ 324 6209 : if (f < 0) {
325 : /* LCOV_EXCL_START */
326 : log_fatal(errno, "Error creating file %s\n", path);
327 : exit(EXIT_FAILURE);
328 : /* LCOV_EXCL_STOP */
329 : }
330 :
- 331 6149 : if (lseek(f, off, SEEK_SET) != off) {
+ 331 6209 : if (lseek(f, off, SEEK_SET) != off) {
332 : /* LCOV_EXCL_START */
333 : log_fatal(errno, "Error seeking file %s\n", path);
334 : exit(EXIT_FAILURE);
335 : /* LCOV_EXCL_STOP */
336 : }
337 :
- 338 6149 : if (write(f, data, size) != size) {
+ 338 6209 : if (write(f, data, size) != size) {
339 : /* LCOV_EXCL_START */
340 : log_fatal(errno, "Error writing file %s\n", path);
341 : exit(EXIT_FAILURE);
342 : /* LCOV_EXCL_STOP */
343 : }
344 :
- 345 6149 : if (close(f) != 0) {
+ 345 6209 : if (close(f) != 0) {
346 : /* LCOV_EXCL_START */
347 : log_fatal(errno, "Error closing file %s\n", path);
348 : exit(EXIT_FAILURE);
349 : /* LCOV_EXCL_STOP */
350 : }
351 :
- 352 6149 : free(data);
+ 352 6209 : free(data);
353 : }
- 354 6176 : }
+ 354 6236 : }
355 :
356 : /**
357 : * Damage a file.
@@ -520,50 +520,50 @@
458 : * - The file must exist.
459 : * - If it's a symlink nothing is done.
460 : */
- 461 3258 : void cmd_append(const char* path, int size)
+ 461 3215 : void cmd_append(const char* path, int size)
462 : {
463 : struct stat st;
464 :
- 465 3258 : if (lstat(path, &st) != 0) {
+ 465 3215 : if (lstat(path, &st) != 0) {
466 : /* LCOV_EXCL_START */
467 : log_fatal(errno, "Error accessing %s\n", path);
468 : exit(EXIT_FAILURE);
469 : /* LCOV_EXCL_STOP */
470 : }
471 :
- 472 3258 : if (S_ISREG(st.st_mode)) {
+ 472 3215 : if (S_ISREG(st.st_mode)) {
473 : unsigned char* data;
474 : int f;
475 :
- 476 3258 : data = malloc(size);
+ 476 3215 : data = malloc(size);
477 :
- 478 3258 : rndnz_range(data, size);
+ 478 3215 : rndnz_range(data, size);
479 :
- 480 3258 : f = open(path, O_WRONLY | O_APPEND | O_BINARY | O_NOFOLLOW);
- 481 3258 : if (f < 0) {
+ 480 3215 : f = open(path, O_WRONLY | O_APPEND | O_BINARY | O_NOFOLLOW);
+ 481 3215 : if (f < 0) {
482 : /* LCOV_EXCL_START */
483 : log_fatal(errno, "Error opening file %s\n", path);
484 : exit(EXIT_FAILURE);
485 : /* LCOV_EXCL_STOP */
486 : }
487 :
- 488 3258 : if (write(f, data, size) != size) {
+ 488 3215 : if (write(f, data, size) != size) {
489 : /* LCOV_EXCL_START */
490 : log_fatal(errno, "Error writing file %s\n", path);
491 : exit(EXIT_FAILURE);
492 : /* LCOV_EXCL_STOP */
493 : }
494 :
- 495 3258 : if (close(f) != 0) {
+ 495 3215 : if (close(f) != 0) {
496 : /* LCOV_EXCL_START */
497 : log_fatal(errno, "Error closing file %s\n", path);
498 : exit(EXIT_FAILURE);
499 : /* LCOV_EXCL_STOP */
500 : }
501 :
- 502 3258 : free(data);
+ 502 3215 : free(data);
503 : }
- 504 3258 : }
+ 504 3215 : }
505 :
506 : /**
507 : * Truncate a file.
@@ -571,69 +571,69 @@
509 : * - The file is NEVER truncated to 0.
510 : * - If it's a symlink nothing is done.
511 : */
- 512 3121 : void cmd_truncate(const char* path, int size)
+ 512 3136 : void cmd_truncate(const char* path, int size)
513 : {
514 : struct stat st;
515 :
- 516 3121 : if (lstat(path, &st) != 0) {
+ 516 3136 : if (lstat(path, &st) != 0) {
517 : /* LCOV_EXCL_START */
518 : log_fatal(errno, "Error accessing %s\n", path);
519 : exit(EXIT_FAILURE);
520 : /* LCOV_EXCL_STOP */
521 : }
522 :
- 523 3121 : if (S_ISREG(st.st_mode)) {
+ 523 3136 : if (S_ISREG(st.st_mode)) {
524 : off_t off;
525 : int f;
526 :
527 : /* if file is empty, just rewrite it */
- 528 3121 : if (st.st_size == 0) {
- 529 0 : size = 0;
+ 528 3136 : if (st.st_size == 0) {
+ 529 4 : size = 0;
530 : } else {
531 : /* don't truncate files to 0 size to avoid ZERO file size protection */
- 532 3121 : if (size >= st.st_size)
- 533 196 : size = st.st_size - 1;
+ 532 3132 : if (size >= st.st_size)
+ 533 182 : size = st.st_size - 1;
534 : }
535 :
- 536 3121 : off = st.st_size - size;
+ 536 3136 : off = st.st_size - size;
537 :
- 538 3121 : f = open(path, O_WRONLY | O_BINARY | O_NOFOLLOW);
- 539 3121 : if (f < 0) {
+ 538 3136 : f = open(path, O_WRONLY | O_BINARY | O_NOFOLLOW);
+ 539 3136 : if (f < 0) {
540 : /* LCOV_EXCL_START */
541 : log_fatal(errno, "Error opening file %s\n", path);
542 : exit(EXIT_FAILURE);
543 : /* LCOV_EXCL_STOP */
544 : }
545 :
- 546 3121 : if (ftruncate(f, off) != 0) {
+ 546 3136 : if (ftruncate(f, off) != 0) {
547 : /* LCOV_EXCL_START */
548 : log_fatal(errno, "Error truncating file %s\n", path);
549 : exit(EXIT_FAILURE);
550 : /* LCOV_EXCL_STOP */
551 : }
552 :
- 553 3121 : if (close(f) != 0) {
+ 553 3136 : if (close(f) != 0) {
554 : /* LCOV_EXCL_START */
555 : log_fatal(errno, "Error closing file %s\n", path);
556 : exit(EXIT_FAILURE);
557 : /* LCOV_EXCL_STOP */
558 : }
559 : }
- 560 3121 : }
+ 560 3136 : }
561 :
562 : /**
563 : * Delete a file.
564 : * - The file must exist.
565 : */
- 566 3205 : void cmd_delete(const char* path)
+ 566 3160 : void cmd_delete(const char* path)
567 : {
- 568 3205 : if (remove(path) != 0) {
+ 568 3160 : if (remove(path) != 0) {
569 : /* LCOV_EXCL_START */
570 : log_fatal(errno, "Error removing %s\n", path);
571 : exit(EXIT_FAILURE);
572 : /* LCOV_EXCL_STOP */
573 : }
- 574 3205 : }
+ 574 3160 : }
575 :
576 : /**
577 : * Change a file. Or deleted/truncated/append/created.
@@ -644,20 +644,20 @@
582 : struct stat st;
583 :
584 13128 : if (!size)
- 585 23 : return;
+ 585 36 : return;
586 :
- 587 13105 : if (lstat(path, &st) != 0) {
+ 587 13092 : if (lstat(path, &st) != 0) {
588 : /* LCOV_EXCL_START */
589 : log_fatal(errno, "Error accessing %s\n", path);
590 : exit(EXIT_FAILURE);
591 : /* LCOV_EXCL_STOP */
592 : }
593 :
- 594 13105 : if (S_ISLNK(st.st_mode)) {
+ 594 13092 : if (S_ISLNK(st.st_mode)) {
595 : /* symlink */
596 394 : if (rnd(2) == 0) {
597 : /* delete */
- 598 187 : if (remove(path) != 0) {
+ 598 195 : if (remove(path) != 0) {
599 : /* LCOV_EXCL_START */
600 : log_fatal(errno, "Error removing %s\n", path);
601 : exit(EXIT_FAILURE);
@@ -667,30 +667,30 @@
605 : /* recreate */
606 : char linkto[PATH_MAX];
607 :
- 608 207 : if (remove(path) != 0) {
+ 608 199 : if (remove(path) != 0) {
609 : /* LCOV_EXCL_START */
610 : log_fatal(errno, "Error removing %s\n", path);
611 : exit(EXIT_FAILURE);
612 : /* LCOV_EXCL_STOP */
613 : }
614 :
- 615 207 : rnd_name(linkto);
+ 615 199 : rnd_name(linkto);
616 :
- 617 207 : cmd_generate_symlink(path, linkto);
+ 617 199 : cmd_generate_symlink(path, linkto);
618 : }
- 619 12711 : } else if (S_ISREG(st.st_mode)) {
+ 619 12698 : } else if (S_ISREG(st.st_mode)) {
620 : int r;
621 :
- 622 12711 : r = rnd(4);
+ 622 12698 : r = rnd(4);
623 :
- 624 12711 : if (r == 0) {
- 625 3127 : cmd_write(path, size);
- 626 9584 : } else if (r == 1) {
- 627 3258 : cmd_append(path, size);
- 628 6326 : } else if (r == 2) {
- 629 3121 : cmd_truncate(path, size);
+ 624 12698 : if (r == 0) {
+ 625 3187 : cmd_write(path, size);
+ 626 9511 : } else if (r == 1) {
+ 627 3215 : cmd_append(path, size);
+ 628 6296 : } else if (r == 2) {
+ 629 3136 : cmd_truncate(path, size);
630 : } else {
- 631 3205 : cmd_delete(path);
+ 631 3160 : cmd_delete(path);
632 : }
633 : }
634 : }
diff --git a/cov/cmdline/murmur3.c.func-sort-c.html b/cov/cmdline/murmur3.c.func-sort-c.html
index 7e43ceaa..7a3d6086 100644
--- a/cov/cmdline/murmur3.c.func-sort-c.html
+++ b/cov/cmdline/murmur3.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,11 +61,11 @@
| MurmurHash3_x86_128 |
- 2030257 |
+ 2030240 |
| fmix32 |
- 8121028 |
+ 8120960 |
diff --git a/cov/cmdline/murmur3.c.func.html b/cov/cmdline/murmur3.c.func.html
index 513f9246..88612806 100644
--- a/cov/cmdline/murmur3.c.func.html
+++ b/cov/cmdline/murmur3.c.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,11 +61,11 @@
| MurmurHash3_x86_128 |
- 2030257 |
+ 2030240 |
| fmix32 |
- 8121028 |
+ 8120960 |
diff --git a/cov/cmdline/murmur3.c.gcov.html b/cov/cmdline/murmur3.c.gcov.html
index ac27494b..ab19a90a 100644
--- a/cov/cmdline/murmur3.c.gcov.html
+++ b/cov/cmdline/murmur3.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -91,14 +91,14 @@
29 : // domain. The author hereby disclaims copyright to this source code.
30 :
31 : /* Finalization mix - force all bits of a hash block to avalanche */
- 32 8121028 : static inline uint32_t fmix32(uint32_t h)
+ 32 8120960 : static inline uint32_t fmix32(uint32_t h)
33 : {
- 34 8121028 : h ^= h >> 16;
- 35 8121028 : h *= 0x85ebca6b;
- 36 8121028 : h ^= h >> 13;
- 37 8121028 : h *= 0xc2b2ae35;
- 38 8121028 : h ^= h >> 16;
- 39 8121028 : return h;
+ 34 8120960 : h ^= h >> 16;
+ 35 8120960 : h *= 0x85ebca6b;
+ 36 8120960 : h ^= h >> 13;
+ 37 8120960 : h *= 0xc2b2ae35;
+ 38 8120960 : h ^= h >> 16;
+ 39 8120960 : return h;
40 : }
41 :
42 : /*
@@ -137,7 +137,7 @@
75 : uint32_t c3 = 0x38b34ae5;
76 : uint32_t c4 = 0xa1e38b93;
77 :
- 78 2030257 : void MurmurHash3_x86_128(const void* data, size_t size, const uint8_t* seed, void* digest)
+ 78 2030240 : 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;
@@ -145,21 +145,21 @@
83 : size_t size_remainder;
84 : uint32_t h1, h2, h3, h4;
85 :
- 86 2030257 : h1 = util_read32(seed + 0);
- 87 2030257 : h2 = util_read32(seed + 4);
- 88 2030257 : h3 = util_read32(seed + 8);
- 89 2030257 : h4 = util_read32(seed + 12);
+ 86 2030240 : h1 = util_read32(seed + 0);
+ 87 2030240 : h2 = util_read32(seed + 4);
+ 88 2030240 : h3 = util_read32(seed + 8);
+ 89 2030240 : h4 = util_read32(seed + 12);
90 :
- 91 2030257 : nblocks = size / 16;
- 92 2030257 : blocks = data;
- 93 2030257 : end = blocks + nblocks * 4;
+ 91 2030240 : nblocks = size / 16;
+ 92 2030240 : blocks = data;
+ 93 2030240 : end = blocks + nblocks * 4;
94 :
95 : /* body */
- 96 105999566 : while (blocks < end) {
- 97 103969309 : uint32_t k1 = blocks[0];
- 98 103969309 : uint32_t k2 = blocks[1];
- 99 103969309 : uint32_t k3 = blocks[2];
- 100 103969309 : uint32_t k4 = blocks[3];
+ 96 106001256 : while (blocks < end) {
+ 97 103971016 : uint32_t k1 = blocks[0];
+ 98 103971016 : uint32_t k2 = blocks[1];
+ 99 103971016 : uint32_t k3 = blocks[2];
+ 100 103971016 : uint32_t k4 = blocks[3];
101 :
102 : #if WORDS_BIGENDIAN
103 : k1 = util_swap32(k1);
@@ -168,81 +168,81 @@
106 : k4 = util_swap32(k4);
107 : #endif
108 :
- 109 103969309 : k1 *= c1; k1 = util_rotl32(k1, 15); k1 *= c2; h1 ^= k1;
+ 109 103971016 : k1 *= c1; k1 = util_rotl32(k1, 15); k1 *= c2; h1 ^= k1;
110 :
- 111 103969309 : h1 = util_rotl32(h1, 19); h1 += h2; h1 = h1 * 5 + 0x561ccd1b;
+ 111 103971016 : h1 = util_rotl32(h1, 19); h1 += h2; h1 = h1 * 5 + 0x561ccd1b;
112 :
- 113 103969309 : k2 *= c2; k2 = util_rotl32(k2, 16); k2 *= c3; h2 ^= k2;
+ 113 103971016 : k2 *= c2; k2 = util_rotl32(k2, 16); k2 *= c3; h2 ^= k2;
114 :
- 115 103969309 : h2 = util_rotl32(h2, 17); h2 += h3; h2 = h2 * 5 + 0x0bcaa747;
+ 115 103971016 : h2 = util_rotl32(h2, 17); h2 += h3; h2 = h2 * 5 + 0x0bcaa747;
116 :
- 117 103969309 : k3 *= c3; k3 = util_rotl32(k3, 17); k3 *= c4; h3 ^= k3;
+ 117 103971016 : k3 *= c3; k3 = util_rotl32(k3, 17); k3 *= c4; h3 ^= k3;
118 :
- 119 103969309 : h3 = util_rotl32(h3, 15); h3 += h4; h3 = h3 * 5 + 0x96cd1c35;
+ 119 103971016 : h3 = util_rotl32(h3, 15); h3 += h4; h3 = h3 * 5 + 0x96cd1c35;
120 :
- 121 103969309 : k4 *= c4; k4 = util_rotl32(k4, 18); k4 *= c1; h4 ^= k4;
+ 121 103971016 : k4 *= c4; k4 = util_rotl32(k4, 18); k4 *= c1; h4 ^= k4;
122 :
- 123 103969309 : h4 = util_rotl32(h4, 13); h4 += h1; h4 = h4 * 5 + 0x32ac3b17;
+ 123 103971016 : h4 = util_rotl32(h4, 13); h4 += h1; h4 = h4 * 5 + 0x32ac3b17;
124 :
- 125 103969309 : blocks += 4;
+ 125 103971016 : blocks += 4;
126 : }
127 :
128 : /* tail */
- 129 2030257 : size_remainder = size & 15;
- 130 2030257 : if (size_remainder != 0) {
- 131 767192 : const uint8_t* tail = (const uint8_t*)blocks;
+ 129 2030240 : size_remainder = size & 15;
+ 130 2030240 : if (size_remainder != 0) {
+ 131 767156 : const uint8_t* tail = (const uint8_t*)blocks;
132 :
- 133 767192 : uint32_t k1 = 0;
- 134 767192 : uint32_t k2 = 0;
- 135 767192 : uint32_t k3 = 0;
- 136 767192 : uint32_t k4 = 0;
+ 133 767156 : uint32_t k1 = 0;
+ 134 767156 : uint32_t k2 = 0;
+ 135 767156 : uint32_t k3 = 0;
+ 136 767156 : uint32_t k4 = 0;
137 :
- 138 767192 : switch (size_remainder) {
- 139 50471 : case 15 : k4 ^= (uint32_t)tail[14] << 16; /* fallthrough */
- 140 102429 : case 14 : k4 ^= (uint32_t)tail[13] << 8; /* fallthrough */
- 141 153813 : case 13 : k4 ^= (uint32_t)tail[12] << 0; /* fallthrough */
- 142 153813 : k4 *= c4; k4 = util_rotl32(k4, 18); k4 *= c1; h4 ^= k4;
+ 138 767156 : switch (size_remainder) {
+ 139 50451 : case 15 : k4 ^= (uint32_t)tail[14] << 16; /* fallthrough */
+ 140 102402 : case 14 : k4 ^= (uint32_t)tail[13] << 8; /* fallthrough */
+ 141 153791 : case 13 : k4 ^= (uint32_t)tail[12] << 0; /* fallthrough */
+ 142 153791 : k4 *= c4; k4 = util_rotl32(k4, 18); k4 *= c1; h4 ^= k4;
143 : /* fallthrough */
- 144 205844 : case 12 : k3 ^= (uint32_t)tail[11] << 24; /* fallthrough */
- 145 257558 : case 11 : k3 ^= (uint32_t)tail[10] << 16; /* fallthrough */
- 146 308901 : case 10 : k3 ^= (uint32_t)tail[ 9] << 8; /* fallthrough */
- 147 361309 : case 9 : k3 ^= (uint32_t)tail[ 8] << 0; /* fallthrough */
- 148 361309 : k3 *= c3; k3 = util_rotl32(k3, 17); k3 *= c4; h3 ^= k3;
+ 144 205797 : case 12 : k3 ^= (uint32_t)tail[11] << 24; /* fallthrough */
+ 145 257494 : case 11 : k3 ^= (uint32_t)tail[10] << 16; /* fallthrough */
+ 146 308851 : case 10 : k3 ^= (uint32_t)tail[ 9] << 8; /* fallthrough */
+ 147 361271 : case 9 : k3 ^= (uint32_t)tail[ 8] << 0; /* fallthrough */
+ 148 361271 : k3 *= c3; k3 = util_rotl32(k3, 17); k3 *= c4; h3 ^= k3;
149 : /* fallthrough */
- 150 414370 : case 8 : k2 ^= (uint32_t)tail[ 7] << 24; /* fallthrough */
- 151 463089 : case 7 : k2 ^= (uint32_t)tail[ 6] << 16; /* fallthrough */
- 152 514935 : case 6 : k2 ^= (uint32_t)tail[ 5] << 8; /* fallthrough */
- 153 564647 : case 5 : k2 ^= (uint32_t)tail[ 4] << 0; /* fallthrough */
- 154 564647 : k2 *= c2; k2 = util_rotl32(k2, 16); k2 *= c3; h2 ^= k2;
+ 150 414299 : case 8 : k2 ^= (uint32_t)tail[ 7] << 24; /* fallthrough */
+ 151 463009 : case 7 : k2 ^= (uint32_t)tail[ 6] << 16; /* fallthrough */
+ 152 514868 : case 6 : k2 ^= (uint32_t)tail[ 5] << 8; /* fallthrough */
+ 153 564597 : case 5 : k2 ^= (uint32_t)tail[ 4] << 0; /* fallthrough */
+ 154 564597 : k2 *= c2; k2 = util_rotl32(k2, 16); k2 *= c3; h2 ^= k2;
155 : /* fallthrough */
- 156 615781 : case 4 : k1 ^= (uint32_t)tail[ 3] << 24; /* fallthrough */
- 157 665404 : case 3 : k1 ^= (uint32_t)tail[ 2] << 16; /* fallthrough */
- 158 715694 : case 2 : k1 ^= (uint32_t)tail[ 1] << 8; /* fallthrough */
- 159 767192 : case 1 : k1 ^= (uint32_t)tail[ 0] << 0; /* fallthrough */
- 160 767192 : k1 *= c1; k1 = util_rotl32(k1, 15); k1 *= c2; h1 ^= k1;
+ 156 615741 : case 4 : k1 ^= (uint32_t)tail[ 3] << 24; /* fallthrough */
+ 157 665352 : case 3 : k1 ^= (uint32_t)tail[ 2] << 16; /* fallthrough */
+ 158 715670 : case 2 : k1 ^= (uint32_t)tail[ 1] << 8; /* fallthrough */
+ 159 767156 : case 1 : k1 ^= (uint32_t)tail[ 0] << 0; /* fallthrough */
+ 160 767156 : k1 *= c1; k1 = util_rotl32(k1, 15); k1 *= c2; h1 ^= k1;
161 : /* fallthrough */
162 : }
163 : }
164 :
165 : /* finalization */
- 166 2030257 : h1 ^= size; h2 ^= size; h3 ^= size; h4 ^= size;
+ 166 2030240 : h1 ^= size; h2 ^= size; h3 ^= size; h4 ^= size;
167 :
- 168 2030257 : h1 += h2; h1 += h3; h1 += h4;
- 169 2030257 : h2 += h1; h3 += h1; h4 += h1;
+ 168 2030240 : h1 += h2; h1 += h3; h1 += h4;
+ 169 2030240 : h2 += h1; h3 += h1; h4 += h1;
170 :
- 171 2030257 : h1 = fmix32(h1);
- 172 2030257 : h2 = fmix32(h2);
- 173 2030257 : h3 = fmix32(h3);
- 174 2030257 : h4 = fmix32(h4);
+ 171 2030240 : h1 = fmix32(h1);
+ 172 2030240 : h2 = fmix32(h2);
+ 173 2030240 : h3 = fmix32(h3);
+ 174 2030240 : h4 = fmix32(h4);
175 :
- 176 2030257 : h1 += h2; h1 += h3; h1 += h4;
- 177 2030257 : h2 += h1; h3 += h1; h4 += h1;
+ 176 2030240 : h1 += h2; h1 += h3; h1 += h4;
+ 177 2030240 : h2 += h1; h3 += h1; h4 += h1;
178 :
- 179 2030257 : util_write32(digest + 0, h1);
- 180 2030257 : util_write32(digest + 4, h2);
- 181 2030257 : util_write32(digest + 8, h3);
- 182 2030257 : util_write32(digest + 12, h4);
- 183 2030257 : }
+ 179 2030240 : util_write32(digest + 0, h1);
+ 180 2030240 : util_write32(digest + 4, h2);
+ 181 2030240 : util_write32(digest + 8, h3);
+ 182 2030240 : util_write32(digest + 12, h4);
+ 183 2030240 : }
184 :
diff --git a/cov/cmdline/parity.c.func-sort-c.html b/cov/cmdline/parity.c.func-sort-c.html
index 889e3488..fc232c83 100644
--- a/cov/cmdline/parity.c.func-sort-c.html
+++ b/cov/cmdline/parity.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -101,7 +101,7 @@
| parity_allocated_size |
- 668 |
+ 667 |
| hbit_u64 |
@@ -125,15 +125,15 @@
| parity_write |
- 626146 |
+ 625834 |
| parity_read |
- 3511017 |
+ 3511023 |
| parity_split_find |
- 4137163 |
+ 4136857 |
diff --git a/cov/cmdline/parity.c.func.html b/cov/cmdline/parity.c.func.html
index 7ae69d2d..88f29a3c 100644
--- a/cov/cmdline/parity.c.func.html
+++ b/cov/cmdline/parity.c.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -65,7 +65,7 @@
| parity_allocated_size |
- 668 |
+ 667 |
| parity_chsize |
@@ -105,7 +105,7 @@
| parity_read |
- 3511017 |
+ 3511023 |
| parity_size |
@@ -113,7 +113,7 @@
| parity_split_find |
- 4137163 |
+ 4136857 |
| parity_split_is_fixed |
@@ -133,7 +133,7 @@
| parity_write |
- 626146 |
+ 625834 |
diff --git a/cov/cmdline/parity.c.gcov.html b/cov/cmdline/parity.c.gcov.html
index 4977beba..2e2b96f5 100644
--- a/cov/cmdline/parity.c.gcov.html
+++ b/cov/cmdline/parity.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -94,31 +94,31 @@
32 : /****************************************************************************/
33 : /* parity */
34 :
- 35 668 : block_off_t parity_allocated_size(struct snapraid_state* state)
+ 35 667 : 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 668 : parity_block = 0;
- 42 4666 : for (i = state->disklist; i != 0; i = i->next) {
- 43 3998 : struct snapraid_disk* disk = i->data;
+ 41 667 : parity_block = 0;
+ 42 4659 : for (i = state->disklist; i != 0; i = i->next) {
+ 43 3992 : struct snapraid_disk* disk = i->data;
44 :
45 : /* start from the declared size */
- 46 3998 : block_off_t block = fs_size(disk);
+ 46 3992 : 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 192692 : while (block > parity_block && !block_has_file(fs_par2block_find(disk, block - 1)))
+ 51 192686 : while (block > parity_block && !block_has_file(fs_par2block_find(disk, block - 1)))
52 188694 : --block;
53 :
54 : /* get the highest value */
- 55 3998 : if (block > parity_block)
- 56 2313 : parity_block = block;
+ 55 3992 : if (block > parity_block)
+ 56 2308 : parity_block = block;
57 : }
58 :
- 59 668 : return parity_block;
+ 59 667 : return parity_block;
60 : }
61 :
62 92 : block_off_t parity_used_size(struct snapraid_state* state)
@@ -135,8 +135,8 @@
73 551 : block_off_t block = fs_size(disk);
74 :
75 : /* decrease the block until an used one */
- 76 226345 : while (block > parity_block && !block_has_file_and_valid_parity(fs_par2block_find(disk, block - 1)))
- 77 225794 : --block;
+ 76 226349 : while (block > parity_block && !block_has_file_and_valid_parity(fs_par2block_find(disk, block - 1)))
+ 77 225798 : --block;
78 :
79 : /* get the highest value */
80 551 : if (block > parity_block)
@@ -859,26 +859,26 @@
797 1058 : return f_ret;
798 : }
799 :
- 800 4137163 : struct snapraid_split_handle* parity_split_find(struct snapraid_parity_handle* handle, data_off_t* offset)
+ 800 4136857 : struct snapraid_split_handle* parity_split_find(struct snapraid_parity_handle* handle, data_off_t* offset)
801 : {
802 : unsigned s;
803 :
- 804 4137163 : if (*offset < 0)
+ 804 4136857 : if (*offset < 0)
805 0 : return 0;
806 :
- 807 6542594 : for (s = 0; s < handle->split_mac; ++s) {
- 808 6531234 : struct snapraid_split_handle* split = &handle->split_map[s];
+ 807 6542370 : for (s = 0; s < handle->split_mac; ++s) {
+ 808 6531010 : struct snapraid_split_handle* split = &handle->split_map[s];
809 :
- 810 6531234 : if (*offset < split->size)
- 811 4125803 : return split;
+ 810 6531010 : if (*offset < split->size)
+ 811 4125497 : return split;
812 :
- 813 2405431 : *offset -= split->size;
+ 813 2405513 : *offset -= split->size;
814 : }
815 :
816 11360 : return 0;
817 : }
818 :
- 819 626146 : int parity_write(struct snapraid_parity_handle* handle, block_off_t pos, unsigned char* block_buffer, unsigned block_size)
+ 819 625834 : int parity_write(struct snapraid_parity_handle* handle, block_off_t pos, unsigned char* block_buffer, unsigned block_size)
820 : {
821 : ssize_t write_ret;
822 : data_off_t offset;
@@ -886,10 +886,10 @@
824 : unsigned count;
825 : int ret;
826 :
- 827 626146 : offset = pos * (data_off_t)block_size;
+ 827 625834 : offset = pos * (data_off_t)block_size;
828 :
- 829 626146 : split = parity_split_find(handle, &offset);
- 830 626146 : if (!split) {
+ 829 625834 : split = parity_split_find(handle, &offset);
+ 830 625834 : if (!split) {
831 : /* LCOV_EXCL_START */
832 : errno = ENXIO;
833 : log_fatal(errno, "Writing parity data outside range at extra offset %" PRIu64 ".\n", offset);
@@ -898,15 +898,15 @@
836 : }
837 :
838 : /* update the valid range */
- 839 626146 : if (split->valid_size < offset + block_size)
+ 839 625834 : if (split->valid_size < offset + block_size)
840 182791 : split->valid_size = offset + block_size;
841 :
- 842 626146 : count = 0;
+ 842 625834 : count = 0;
843 : do {
- 844 626146 : bw_limit(handle->bw, block_size - count);
+ 844 625834 : bw_limit(handle->bw, block_size - count);
845 :
- 846 626146 : write_ret = pwrite(split->f, block_buffer + count, block_size - count, offset + count);
- 847 626146 : if (write_ret == -1) {
+ 846 625834 : write_ret = pwrite(split->f, block_buffer + count, block_size - count, offset + count);
+ 847 625834 : if (write_ret == -1) {
848 : /* LCOV_EXCL_START */
849 : if (errno == ENOSPC) {
850 : log_fatal(errno, "Failed to grow parity file '%s' using write due lack of space.\n", split->path);
@@ -916,7 +916,7 @@
854 : return -1;
855 : /* LCOV_EXCL_STOP */
856 : }
- 857 626146 : if (write_ret == 0) {
+ 857 625834 : if (write_ret == 0) {
858 : /* LCOV_EXCL_START */
859 : errno = ENXIO;
860 : log_fatal(errno, "Unexpected 0 write to file '%s'. %s.\n", split->path, strerror(errno));
@@ -924,21 +924,21 @@
862 : /* LCOV_EXCL_STOP */
863 : }
864 :
- 865 626146 : count += write_ret;
- 866 626146 : } while (count < block_size);
+ 865 625834 : count += write_ret;
+ 866 625834 : } while (count < block_size);
867 :
- 868 626146 : ret = advise_write(&split->advise, split->f, offset, block_size);
- 869 626146 : if (ret != 0) {
+ 868 625834 : ret = advise_write(&split->advise, split->f, offset, block_size);
+ 869 625834 : if (ret != 0) {
870 : /* LCOV_EXCL_START */
871 : log_fatal(errno, "Error advising parity file '%s'. %s.\n", split->path, strerror(errno));
872 : return -1;
873 : /* LCOV_EXCL_STOP */
874 : }
875 :
- 876 626146 : return 0;
+ 876 625834 : return 0;
877 : }
878 :
- 879 3511017 : int parity_read(struct snapraid_parity_handle* handle, block_off_t pos, unsigned char* block_buffer, unsigned block_size, log_ptr* out)
+ 879 3511023 : int parity_read(struct snapraid_parity_handle* handle, block_off_t pos, unsigned char* block_buffer, unsigned block_size, log_ptr* out)
880 : {
881 : ssize_t read_ret;
882 : data_off_t offset;
@@ -946,10 +946,10 @@
884 : struct snapraid_split_handle* split;
885 : int ret;
886 :
- 887 3511017 : offset = pos * (data_off_t)block_size;
+ 887 3511023 : offset = pos * (data_off_t)block_size;
888 :
- 889 3511017 : split = parity_split_find(handle, &offset);
- 890 3511017 : if (!split) {
+ 889 3511023 : split = parity_split_find(handle, &offset);
+ 890 3511023 : if (!split) {
891 : /* LCOV_EXCL_START */
892 : errno = ENXIO;
893 : out(errno, "Reading parity data outside range at extra offset %" PRIu64 ".\n", offset);
@@ -958,7 +958,7 @@
896 : }
897 :
898 : /* if read is completely out of the valid range */
- 899 3499657 : if (offset >= split->valid_size) {
+ 899 3499663 : if (offset >= split->valid_size) {
900 : /* LCOV_EXCL_START */
901 : errno = ENXIO;
902 : out(errno, "Reading over the end from parity file '%s' at offset %" PRIu64 " for size %u.\n", split->path, offset, block_size);
@@ -966,19 +966,19 @@
904 : /* LCOV_EXCL_STOP */
905 : }
906 :
- 907 3420682 : count = 0;
- 908 3420682 : errno = 0;
+ 907 3420688 : count = 0;
+ 908 3420688 : errno = 0;
909 : do {
- 910 3420682 : bw_limit(handle->bw, block_size - count);
+ 910 3420688 : bw_limit(handle->bw, block_size - count);
911 :
- 912 3420682 : read_ret = pread(split->f, block_buffer + count, block_size - count, offset + count);
- 913 3420682 : if (read_ret == -1) {
+ 912 3420688 : read_ret = pread(split->f, block_buffer + count, block_size - count, offset + count);
+ 913 3420688 : if (read_ret == -1) {
914 : /* LCOV_EXCL_START */
915 : out(errno, "Error reading parity file '%s' at offset %" PRIu64 " for size %u. %s.\n", split->path, offset + count, block_size - count, strerror(errno));
916 : return -1;
917 : /* LCOV_EXCL_STOP */
918 : }
- 919 3420682 : if (read_ret == 0) {
+ 919 3420688 : if (read_ret == 0) {
920 : /* LCOV_EXCL_START */
921 : if (errno == 0)
922 : errno = ENXIO;
@@ -987,18 +987,18 @@
925 : /* LCOV_EXCL_STOP */
926 : }
927 :
- 928 3420682 : count += read_ret;
- 929 3420682 : } while (count < block_size);
+ 928 3420688 : count += read_ret;
+ 929 3420688 : } while (count < block_size);
930 :
- 931 3420682 : ret = advise_read(&split->advise, split->f, offset, block_size);
- 932 3420682 : if (ret != 0) {
+ 931 3420688 : ret = advise_read(&split->advise, split->f, offset, block_size);
+ 932 3420688 : if (ret != 0) {
933 : /* LCOV_EXCL_START */
934 : out(errno, "Error advising parity file '%s'. %s.\n", split->path, strerror(errno));
935 : return -1;
936 : /* LCOV_EXCL_STOP */
937 : }
938 :
- 939 3420682 : return block_size;
+ 939 3420688 : return block_size;
940 : }
941 :
diff --git a/cov/cmdline/pool.c.func-sort-c.html b/cov/cmdline/pool.c.func-sort-c.html
index 5d27197f..1ddb6947 100644
--- a/cov/cmdline/pool.c.func-sort-c.html
+++ b/cov/cmdline/pool.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/cmdline/pool.c.func.html b/cov/cmdline/pool.c.func.html
index 411287e8..a37a2b51 100644
--- a/cov/cmdline/pool.c.func.html
+++ b/cov/cmdline/pool.c.func.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/cmdline/pool.c.gcov.html b/cov/cmdline/pool.c.gcov.html
index de4a6006..05536db4 100644
--- a/cov/cmdline/pool.c.gcov.html
+++ b/cov/cmdline/pool.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -392,7 +392,7 @@
330 :
331 : /* check if the info match */
332 5690 : if (found->mtime_sec == mtime_sec
- 333 5399 : && found->mtime_nsec == mtime_nsec
+ 333 5406 : && found->mtime_nsec == mtime_nsec
334 5385 : && strcmp(found->linkto, linkto) == 0
335 : ) {
336 : /* nothing to do */
diff --git a/cov/cmdline/portable.h.func-sort-c.html b/cov/cmdline/portable.h.func-sort-c.html
index 2d001c82..ce670742 100644
--- a/cov/cmdline/portable.h.func-sort-c.html
+++ b/cov/cmdline/portable.h.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/cmdline/portable.h.func.html b/cov/cmdline/portable.h.func.html
index 178ea9e0..c09b0f5c 100644
--- a/cov/cmdline/portable.h.func.html
+++ b/cov/cmdline/portable.h.func.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/cmdline/portable.h.gcov.html b/cov/cmdline/portable.h.gcov.html
index 01522dd0..330dd262 100644
--- a/cov/cmdline/portable.h.gcov.html
+++ b/cov/cmdline/portable.h.gcov.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/cmdline/rehash.c.func-sort-c.html b/cov/cmdline/rehash.c.func-sort-c.html
index 7182d3c8..9efd3408 100644
--- a/cov/cmdline/rehash.c.func-sort-c.html
+++ b/cov/cmdline/rehash.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/cmdline/rehash.c.func.html b/cov/cmdline/rehash.c.func.html
index d5f81867..fefc25ea 100644
--- a/cov/cmdline/rehash.c.func.html
+++ b/cov/cmdline/rehash.c.func.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/cmdline/rehash.c.gcov.html b/cov/cmdline/rehash.c.gcov.html
index 07606a7d..32f3df23 100644
--- a/cov/cmdline/rehash.c.gcov.html
+++ b/cov/cmdline/rehash.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/cmdline/scan.c.func-sort-c.html b/cov/cmdline/scan.c.func-sort-c.html
index 2478ee8e..5910e578 100644
--- a/cov/cmdline/scan.c.func-sort-c.html
+++ b/cov/cmdline/scan.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -113,7 +113,7 @@
| file_is_full_hashed_and_stable |
- 23671 |
+ 23670 |
| scan_link |
@@ -121,27 +121,27 @@
| scan_file_deallocate |
- 55231 |
+ 55218 |
| scan_file_remove |
- 55231 |
+ 55218 |
| scan_file_refresh |
- 77410 |
+ 77397 |
| scan_file_allocate |
- 100097 |
+ 100084 |
| scan_file_delayed_allocate |
- 100097 |
+ 100084 |
| scan_file_insert |
- 100097 |
+ 100084 |
| dd_ino_compare |
@@ -149,19 +149,19 @@
| stamp_lock |
- 512471 |
+ 512368 |
| stamp_unlock |
- 512471 |
+ 512368 |
| file_is_full_invalid_parity_and_stable |
- 1083709 |
+ 1083722 |
| scan_file_keep |
- 1083709 |
+ 1083722 |
| scan_file |
diff --git a/cov/cmdline/scan.c.func.html b/cov/cmdline/scan.c.func.html
index 87041753..8ed9eb89 100644
--- a/cov/cmdline/scan.c.func.html
+++ b/cov/cmdline/scan.c.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -73,11 +73,11 @@
| file_is_full_hashed_and_stable |
- 23671 |
+ 23670 |
| file_is_full_invalid_parity_and_stable |
- 1083709 |
+ 1083722 |
| scan_alloc |
@@ -109,31 +109,31 @@
| scan_file_allocate |
- 100097 |
+ 100084 |
| scan_file_deallocate |
- 55231 |
+ 55218 |
| scan_file_delayed_allocate |
- 100097 |
+ 100084 |
| scan_file_insert |
- 100097 |
+ 100084 |
| scan_file_keep |
- 1083709 |
+ 1083722 |
| scan_file_refresh |
- 77410 |
+ 77397 |
| scan_file_remove |
- 55231 |
+ 55218 |
| scan_free |
@@ -157,11 +157,11 @@
| stamp_lock |
- 512471 |
+ 512368 |
| stamp_unlock |
- 512471 |
+ 512368 |
| state_diff |
diff --git a/cov/cmdline/scan.c.gcov.html b/cov/cmdline/scan.c.gcov.html
index 76c4b158..1297c5e1 100644
--- a/cov/cmdline/scan.c.gcov.html
+++ b/cov/cmdline/scan.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -156,23 +156,23 @@
94 599 : free(scan);
95 599 : }
96 :
- 97 512471 : static void stamp_lock(struct snapraid_disk* disk)
+ 97 512368 : static void stamp_lock(struct snapraid_disk* disk)
98 : {
99 : #if HAVE_THREAD
- 100 512471 : thread_mutex_lock(&disk->stamp_mutex);
+ 100 512368 : thread_mutex_lock(&disk->stamp_mutex);
101 : #else
102 : (void)disk;
103 : #endif
- 104 512471 : }
+ 104 512368 : }
105 :
- 106 512471 : static void stamp_unlock(struct snapraid_disk* disk)
+ 106 512368 : static void stamp_unlock(struct snapraid_disk* disk)
107 : {
108 : #if HAVE_THREAD
- 109 512471 : thread_mutex_unlock(&disk->stamp_mutex);
+ 109 512368 : thread_mutex_unlock(&disk->stamp_mutex);
110 : #else
111 : (void)disk;
112 : #endif
- 113 512471 : }
+ 113 512368 : }
114 :
115 : /**
116 : * Remove the specified link from the data set.
@@ -285,42 +285,42 @@
223 : /**
224 : * Insert the specified file in the parity.
225 : */
- 226 100097 : static void scan_file_allocate(struct snapraid_scan* scan, struct snapraid_file* file)
+ 226 100084 : static void scan_file_allocate(struct snapraid_scan* scan, struct snapraid_file* file)
227 : {
- 228 100097 : struct snapraid_state* state = scan->state;
- 229 100097 : struct snapraid_disk* disk = scan->disk;
+ 228 100084 : struct snapraid_state* state = scan->state;
+ 229 100084 : struct snapraid_disk* disk = scan->disk;
230 : block_off_t i;
231 : block_off_t parity_pos;
232 :
233 : /* state changed */
- 234 100097 : scan->need_write = 1;
+ 234 100084 : scan->need_write = 1;
235 :
236 : /* allocate the blocks of the file */
- 237 100097 : parity_pos = disk->first_free_block;
- 238 350007 : for (i = 0; i < file->blockmax; ++i) {
+ 237 100084 : parity_pos = disk->first_free_block;
+ 238 349939 : for (i = 0; i < file->blockmax; ++i) {
239 : struct snapraid_block* block;
240 : struct snapraid_block* over_block;
241 : snapraid_info info;
242 :
243 : /* increment the position until the first really free block */
- 244 784407 : while (block_has_file(fs_par2block_find(disk, parity_pos)))
- 245 534497 : ++parity_pos;
+ 244 782963 : while (block_has_file(fs_par2block_find(disk, parity_pos)))
+ 245 533108 : ++parity_pos;
246 :
247 : /* get block we are going to overwrite, if any */
- 248 249910 : over_block = fs_par2block_find(disk, parity_pos);
+ 248 249855 : over_block = fs_par2block_find(disk, parity_pos);
249 :
250 : /* deallocate it */
- 251 249910 : if (over_block != BLOCK_NULL)
- 252 90924 : fs_deallocate(disk, parity_pos);
+ 251 249855 : if (over_block != BLOCK_NULL)
+ 252 90869 : fs_deallocate(disk, parity_pos);
253 :
254 : /* get block specific info */
- 255 249910 : info = info_get(&state->infoarr, parity_pos);
+ 255 249855 : info = info_get(&state->infoarr, parity_pos);
256 :
257 : /* get the new block we are going to write */
- 258 249910 : block = fs_file2block_get(file, i);
+ 258 249855 : block = fs_file2block_get(file, i);
259 :
260 : /* if the file block already has an updated hash without rehash */
- 261 249910 : if (block_has_updated_hash(block) && !info_get_rehash(info)) {
+ 261 249855 : if (block_has_updated_hash(block) && !info_get_rehash(info)) {
262 : /* the only possible case is for REP blocks */
263 87239 : assert(block_state_get(block) == BLOCK_STATE_REP);
264 :
@@ -332,25 +332,25 @@
270 : unsigned over_state;
271 :
272 : /* convert to a CHG block */
- 273 162671 : block_state_set(block, BLOCK_STATE_CHG);
+ 273 162616 : block_state_set(block, BLOCK_STATE_CHG);
274 :
275 : /* state of the block we are going to overwrite */
- 276 162671 : over_state = block_state_get(over_block);
+ 276 162616 : over_state = block_state_get(over_block);
277 :
278 : /* if the block is an empty one */
- 279 162671 : if (over_state == BLOCK_STATE_EMPTY) {
+ 279 162616 : if (over_state == BLOCK_STATE_EMPTY) {
280 : /* the block was empty and filled with zeros */
281 : /* set the hash to the special ZERO value */
282 117591 : hash_zero_set(block->hash);
283 : } else {
284 : /* otherwise it's a DELETED one */
- 285 45080 : assert(over_state == BLOCK_STATE_DELETED);
+ 285 45025 : assert(over_state == BLOCK_STATE_DELETED);
286 :
287 : /* copy the past hash of the block */
- 288 45080 : memcpy(block->hash, over_block->hash, BLOCK_HASH_SIZE);
+ 288 45025 : memcpy(block->hash, over_block->hash, BLOCK_HASH_SIZE);
289 :
290 : /* if we have not already cleared the past hash */
- 291 45080 : if (!state->clear_past_hash) {
+ 291 45025 : if (!state->clear_past_hash) {
292 : /* in this case we don't know if the old state is still the one */
293 : /* stored inside the parity, because after an aborted sync, the parity */
294 : /* may be or may be not have been updated with the new data */
@@ -367,15 +367,15 @@
305 : }
306 :
307 : /* store in the disk map, after invalidating all the other blocks */
- 308 249910 : fs_allocate(disk, parity_pos, file, i);
+ 308 249855 : fs_allocate(disk, parity_pos, file, i);
309 :
310 : /* set the new free position */
- 311 249910 : disk->first_free_block = parity_pos + 1;
+ 311 249855 : disk->first_free_block = parity_pos + 1;
312 : }
313 :
314 : /* insert in the list of contained files */
- 315 100097 : tommy_list_insert_tail(&disk->filelist, &file->nodelist, file);
- 316 100097 : }
+ 315 100084 : tommy_list_insert_tail(&disk->filelist, &file->nodelist, file);
+ 316 100084 : }
317 :
318 : /**
319 : * Delete the specified file from the parity.
@@ -384,23 +384,23 @@
322 : * The file is then inserted in the deleted set, and it should not be deallocated,
323 : * as the parity still references it.
324 : */
- 325 55231 : static void scan_file_deallocate(struct snapraid_scan* scan, struct snapraid_file* file)
+ 325 55218 : static void scan_file_deallocate(struct snapraid_scan* scan, struct snapraid_file* file)
326 : {
- 327 55231 : struct snapraid_state* state = scan->state;
- 328 55231 : struct snapraid_disk* disk = scan->disk;
+ 327 55218 : struct snapraid_state* state = scan->state;
+ 328 55218 : struct snapraid_disk* disk = scan->disk;
329 : block_off_t i;
330 :
331 : /* remove from the list of contained files */
- 332 55231 : tommy_list_remove_existing(&disk->filelist, &file->nodelist);
+ 332 55218 : tommy_list_remove_existing(&disk->filelist, &file->nodelist);
333 :
334 : /* state changed */
- 335 55231 : scan->need_write = 1;
+ 335 55218 : scan->need_write = 1;
336 :
337 : /* here we are supposed to adjust the ::first_free_block position */
338 : /* with the parity position we are deleting */
339 : /* but we also know that we do only delayed insert, after all the deletion, */
340 : /* so at this point ::first_free_block is always at 0, and we don't need to update it */
- 341 55231 : if (disk->first_free_block != 0) {
+ 341 55218 : if (disk->first_free_block != 0) {
342 : /* LCOV_EXCL_START */
343 : log_fatal(EINTERNAL, "Internal inconsistency for first free position at '%u' deallocating file '%s'\n", disk->first_free_block, file->sub);
344 : os_abort();
@@ -408,17 +408,17 @@
346 : }
347 :
348 : /* free all the blocks of the file */
- 349 194526 : for (i = 0; i < file->blockmax; ++i) {
- 350 139295 : struct snapraid_block* block = fs_file2block_get(file, i);
+ 349 194458 : for (i = 0; i < file->blockmax; ++i) {
+ 350 139240 : struct snapraid_block* block = fs_file2block_get(file, i);
351 : unsigned block_state;
352 :
353 : /* in case we scan after an aborted sync, */
354 : /* we could get also intermediate states */
- 355 139295 : block_state = block_state_get(block);
- 356 139295 : switch (block_state) {
- 357 33275 : case BLOCK_STATE_BLK :
+ 355 139240 : block_state = block_state_get(block);
+ 356 139240 : switch (block_state) {
+ 357 33220 : case BLOCK_STATE_BLK :
358 : /* we keep the hash making it an "old" hash, because the parity is still containing data for it */
- 359 33275 : break;
+ 359 33220 : break;
360 28040 : case BLOCK_STATE_CHG :
361 : /* if we have not already cleared the past hash */
362 28040 : if (!state->clear_past_hash) {
@@ -448,23 +448,23 @@
386 : }
387 :
388 : /* set the block as deleted */
- 389 139295 : block_state_set(block, BLOCK_STATE_DELETED);
+ 389 139240 : block_state_set(block, BLOCK_STATE_DELETED);
390 : }
391 :
392 : /* mark the file as deleted */
- 393 55231 : file_flag_set(file, FILE_IS_DELETED);
+ 393 55218 : file_flag_set(file, FILE_IS_DELETED);
394 :
395 : /* insert it in the list of deleted blocks */
- 396 55231 : tommy_list_insert_tail(&disk->deletedlist, &file->nodelist, file);
- 397 55231 : }
+ 396 55218 : tommy_list_insert_tail(&disk->deletedlist, &file->nodelist, file);
+ 397 55218 : }
398 :
- 399 100097 : static void scan_file_delayed_allocate(struct snapraid_scan* scan, struct snapraid_file* file)
+ 399 100084 : static void scan_file_delayed_allocate(struct snapraid_scan* scan, struct snapraid_file* file)
400 : {
- 401 100097 : struct snapraid_state* state = scan->state;
- 402 100097 : struct snapraid_disk* disk = scan->disk;
+ 401 100084 : struct snapraid_state* state = scan->state;
+ 402 100084 : struct snapraid_disk* disk = scan->disk;
403 :
404 : /* if we sort for physical offsets we have to read them for new files */
- 405 100097 : if (state->opt.force_order == SORT_PHYSICAL
+ 405 100084 : if (state->opt.force_order == SORT_PHYSICAL
406 11432 : && file->physical == FILEPHY_UNREAD_OFFSET
407 : ) {
408 : char path_next[PATH_MAX];
@@ -480,30 +480,30 @@
418 : }
419 :
420 : /* insert in the delayed list */
- 421 100097 : tommy_list_insert_tail(&scan->file_insert_list, &file->nodelist, file);
- 422 100097 : }
+ 421 100084 : tommy_list_insert_tail(&scan->file_insert_list, &file->nodelist, file);
+ 422 100084 : }
423 :
424 : /**
425 : * Check if a file is completely formed of blocks with invalid parity,
426 : * and no rehash is tagged, and if it has at least one block.
427 : */
- 428 1083709 : static int file_is_full_invalid_parity_and_stable(struct snapraid_state* state, struct snapraid_disk* disk, struct snapraid_file* file)
+ 428 1083722 : static int file_is_full_invalid_parity_and_stable(struct snapraid_state* state, struct snapraid_disk* disk, struct snapraid_file* file)
429 : {
430 : block_off_t i;
431 :
432 : /* with no block, it never has an invalid parity */
- 433 1083709 : if (file->blockmax == 0)
- 434 1525 : return 0;
+ 433 1083722 : if (file->blockmax == 0)
+ 434 1523 : return 0;
435 :
436 : /* check all blocks */
- 437 1139175 : for (i = 0; i < file->blockmax; ++i) {
+ 437 1139190 : for (i = 0; i < file->blockmax; ++i) {
438 : snapraid_info info;
- 439 1116488 : struct snapraid_block* block = fs_file2block_get(file, i);
+ 439 1116503 : struct snapraid_block* block = fs_file2block_get(file, i);
440 : block_off_t parity_pos;
441 :
442 : /* exclude blocks with parity */
- 443 1116488 : if (!block_has_invalid_parity(block))
- 444 1059497 : return 0;
+ 443 1116503 : if (!block_has_invalid_parity(block))
+ 444 1059512 : return 0;
445 :
446 : /*
447 : * Get the parity position.
@@ -533,23 +533,23 @@
471 : * Check if a file is completely formed of blocks with an updated hash,
472 : * and no rehash is tagged, and if it has at least one block.
473 : */
- 474 23671 : static int file_is_full_hashed_and_stable(struct snapraid_state* state, struct snapraid_disk* disk, struct snapraid_file* file)
+ 474 23670 : static int file_is_full_hashed_and_stable(struct snapraid_state* state, struct snapraid_disk* disk, struct snapraid_file* file)
475 : {
476 : block_off_t i;
477 :
478 : /* with no block, it never has a hash */
- 479 23671 : if (file->blockmax == 0)
+ 479 23670 : if (file->blockmax == 0)
480 27 : return 0;
481 :
482 : /* check all blocks */
- 483 81888 : for (i = 0; i < file->blockmax; ++i) {
+ 483 81887 : for (i = 0; i < file->blockmax; ++i) {
484 : snapraid_info info;
- 485 58251 : struct snapraid_block* block = fs_file2block_get(file, i);
+ 485 58250 : struct snapraid_block* block = fs_file2block_get(file, i);
486 : block_off_t parity_pos;
487 :
488 : /* exclude blocks without hash */
- 489 58251 : if (!block_has_updated_hash(block))
- 490 7 : return 0;
+ 489 58250 : if (!block_has_updated_hash(block))
+ 490 6 : return 0;
491 :
492 : /*
493 : * Get the parity position.
@@ -590,7 +590,7 @@
528 : *
529 : * If this happens, we read also the physical offset, to avoid to read it later.
530 : */
- 531 77410 : static void scan_file_refresh(struct snapraid_scan* scan, const char* sub, struct stat* st, uint64_t* physical)
+ 531 77397 : static void scan_file_refresh(struct snapraid_scan* scan, const char* sub, struct stat* st, uint64_t* physical)
532 : {
533 : #if HAVE_LSTAT_SYNC
534 : struct snapraid_state* state = scan->state;
@@ -678,49 +678,49 @@
616 : (void)st;
617 : (void)physical;
618 : #endif
- 619 77410 : }
+ 619 77397 : }
620 :
621 : /**
622 : * Insert the file in the data set.
623 : */
- 624 100097 : static void scan_file_insert(struct snapraid_scan* scan, struct snapraid_file* file)
+ 624 100084 : static void scan_file_insert(struct snapraid_scan* scan, struct snapraid_file* file)
625 : {
- 626 100097 : struct snapraid_disk* disk = scan->disk;
+ 626 100084 : struct snapraid_disk* disk = scan->disk;
627 :
628 : /* insert the file in the containers */
- 629 100097 : if (!file_flag_has(file, FILE_IS_WITHOUT_INODE))
- 630 100097 : tommy_hashdyn_insert(&disk->inodeset, &file->nodeset, file, file_inode_hash(file->inode));
+ 629 100084 : if (!file_flag_has(file, FILE_IS_WITHOUT_INODE))
+ 630 100084 : tommy_hashdyn_insert(&disk->inodeset, &file->nodeset, file, file_inode_hash(file->inode));
631 :
- 632 100097 : stamp_lock(disk);
- 633 100097 : tommy_hashdyn_insert(&disk->pathset, &file->pathset, file, file_path_hash(file->sub));
- 634 100097 : tommy_hashdyn_insert(&disk->stampset, &file->stampset, file, file_stamp_hash(file->size, file->mtime_sec, file->mtime_nsec));
- 635 100097 : stamp_unlock(disk);
+ 632 100084 : stamp_lock(disk);
+ 633 100084 : tommy_hashdyn_insert(&disk->pathset, &file->pathset, file, file_path_hash(file->sub));
+ 634 100084 : tommy_hashdyn_insert(&disk->stampset, &file->stampset, file, file_stamp_hash(file->size, file->mtime_sec, file->mtime_nsec));
+ 635 100084 : stamp_unlock(disk);
636 :
637 : /* delayed allocation of the parity */
- 638 100097 : scan_file_delayed_allocate(scan, file);
- 639 100097 : }
+ 638 100084 : scan_file_delayed_allocate(scan, file);
+ 639 100084 : }
640 :
641 : /**
642 : * Remove the file from the data set.
643 : *
644 : * File is then deleted.
645 : */
- 646 55231 : static void scan_file_remove(struct snapraid_scan* scan, struct snapraid_file* file)
+ 646 55218 : static void scan_file_remove(struct snapraid_scan* scan, struct snapraid_file* file)
647 : {
- 648 55231 : struct snapraid_disk* disk = scan->disk;
+ 648 55218 : struct snapraid_disk* disk = scan->disk;
649 :
650 : /* remove the file from the containers */
- 651 55231 : if (!file_flag_has(file, FILE_IS_WITHOUT_INODE))
- 652 55184 : tommy_hashdyn_remove_existing(&disk->inodeset, &file->nodeset);
- 653 55231 : tommy_hashdyn_remove_existing(&disk->pathset, &file->pathset);
+ 651 55218 : if (!file_flag_has(file, FILE_IS_WITHOUT_INODE))
+ 652 55153 : tommy_hashdyn_remove_existing(&disk->inodeset, &file->nodeset);
+ 653 55218 : tommy_hashdyn_remove_existing(&disk->pathset, &file->pathset);
654 :
- 655 55231 : stamp_lock(disk);
- 656 55231 : tommy_hashdyn_remove_existing(&disk->stampset, &file->stampset);
- 657 55231 : stamp_unlock(disk);
+ 655 55218 : stamp_lock(disk);
+ 656 55218 : tommy_hashdyn_remove_existing(&disk->stampset, &file->stampset);
+ 657 55218 : stamp_unlock(disk);
658 :
659 : /* deallocate the file from the parity */
- 660 55231 : scan_file_deallocate(scan, file);
- 661 55231 : }
+ 660 55218 : scan_file_deallocate(scan, file);
+ 661 55218 : }
662 :
663 : /**
664 : * Keep the file as it's (or with only a name/inode modification).
@@ -733,12 +733,12 @@
671 : * This could happen after a failed sync, when some other files are deleted,
672 : * and then new ones can be moved backward to fill the hole created.
673 : */
- 674 1083709 : static void scan_file_keep(struct snapraid_scan* scan, struct snapraid_file* file)
+ 674 1083722 : static void scan_file_keep(struct snapraid_scan* scan, struct snapraid_file* file)
675 : {
- 676 1083709 : struct snapraid_disk* disk = scan->disk;
+ 676 1083722 : struct snapraid_disk* disk = scan->disk;
677 :
678 : /* if the file is full invalid, schedule a reinsert at later stage */
- 679 1083709 : if (file_is_full_invalid_parity_and_stable(scan->state, disk, file)) {
+ 679 1083722 : if (file_is_full_invalid_parity_and_stable(scan->state, disk, file)) {
680 22687 : struct snapraid_file* copy = file_dup(file);
681 :
682 : /* remove the file */
@@ -747,7 +747,7 @@
685 : /* reinsert the copy in the delayed list */
686 22687 : scan_file_insert(scan, copy);
687 : }
- 688 1083709 : }
+ 688 1083722 : }
689 :
690 : /**
691 : * Process a file.
@@ -804,17 +804,17 @@
742 : /* identify moved files with past inodes and hardlinks with the new inodes */
743 1161329 : if (file) {
744 : /* check if the file is not changed */
- 745 1001529 : if (file->size == st->st_size
- 746 990214 : && file->mtime_sec == st->st_mtime
- 747 988959 : && (file->mtime_nsec == STAT_NSEC(st)
+ 745 1002136 : if (file->size == st->st_size
+ 746 990273 : && file->mtime_sec == st->st_mtime
+ 747 989015 : && (file->mtime_nsec == STAT_NSEC(st)
748 : /* always accept the stored value if it's STAT_NSEC_INVALID */
749 : /* it happens when upgrading from an old version of SnapRAID */
750 : /* not yet supporting the nanosecond field */
- 751 8 : || file->mtime_nsec == STAT_NSEC_INVALID
+ 751 7 : || file->mtime_nsec == STAT_NSEC_INVALID
752 : )
753 : ) {
754 : /* check if multiple files have the same inode */
- 755 988951 : if (file_flag_has(file, FILE_IS_PRESENT)) {
+ 755 989008 : if (file_flag_has(file, FILE_IS_PRESENT)) {
756 : /* if has_volatile_hardlinks is true, the nlink value is not reliable */
757 210 : if (!disk->has_volatile_hardlinks && st->st_nlink == 1) {
758 : /* LCOV_EXCL_START */
@@ -825,15 +825,15 @@
763 :
764 : /* it's a hardlink */
765 210 : scan_link(scan, is_diff, sub, file->sub, FILE_IS_HARDLINK);
- 766 1083919 : return;
+ 766 1083932 : return;
767 : }
768 :
769 : /* mark as present */
- 770 988741 : file_flag_set(file, FILE_IS_PRESENT);
+ 770 988798 : file_flag_set(file, FILE_IS_PRESENT);
771 :
772 : /* update the nanoseconds mtime only if different */
773 : /* to avoid unneeded updates */
- 774 988741 : if (file->mtime_nsec == STAT_NSEC_INVALID
+ 774 988798 : if (file->mtime_nsec == STAT_NSEC_INVALID
775 0 : && STAT_NSEC(st) != file->mtime_nsec
776 : ) {
777 0 : file->mtime_nsec = STAT_NSEC(st);
@@ -842,7 +842,7 @@
780 0 : scan->need_write = 1;
781 : }
782 :
- 783 988741 : if (strcmp(file->sub, sub) != 0) {
+ 783 988798 : if (strcmp(file->sub, sub) != 0) {
784 : /* if the path is different, it means a moved file with the same inode */
785 155 : ++scan->count_move;
786 :
@@ -864,18 +864,18 @@
802 155 : scan->need_write = 1;
803 : } else {
804 : /* otherwise it's equal */
- 805 988586 : ++scan->count_equal;
+ 805 988643 : ++scan->count_equal;
806 :
- 807 988586 : if (state->opt.gui_verbose) {
+ 807 988643 : if (state->opt.gui_verbose) {
808 0 : log_tag("scan:equal:%s:%s\n", disk->name, esc_tag(file->sub, esc_buffer));
809 : }
810 : }
811 :
812 : /* mark the file as kept */
- 813 988741 : scan_file_keep(scan, file);
+ 813 988798 : scan_file_keep(scan, file);
814 :
815 : /* nothing more to do */
- 816 988741 : return;
+ 816 988798 : return;
817 : }
818 :
819 : /*
@@ -897,7 +897,7 @@
835 : * C:> dir
836 : * ...both time and size of A and B don't match!
837 : */
- 838 12578 : if (file_flag_has(file, FILE_IS_PRESENT)) {
+ 838 13128 : if (file_flag_has(file, FILE_IS_PRESENT)) {
839 : /* if has_volatile_hardlinks is true, the nlink value is not reliable */
840 0 : if (!disk->has_volatile_hardlinks && st->st_nlink == 1) {
841 : /* LCOV_EXCL_START */
@@ -923,44 +923,44 @@
861 : /* otherwise, it will get removed */
862 :
863 : /* remove from the inode set */
- 864 12578 : tommy_hashdyn_remove_existing(&disk->inodeset, &file->nodeset);
+ 864 13128 : tommy_hashdyn_remove_existing(&disk->inodeset, &file->nodeset);
865 :
866 : /* clear the inode */
867 : /* this is not really needed for correct functionality */
868 : /* because we are going to set FILE_IS_WITHOUT_INODE */
869 : /* but it's easier for debugging to have invalid inodes set to 0 */
- 870 12578 : file->inode = 0;
+ 870 13128 : file->inode = 0;
871 :
872 : /* mark as missing inode */
- 873 12578 : file_flag_set(file, FILE_IS_WITHOUT_INODE);
+ 873 13128 : file_flag_set(file, FILE_IS_WITHOUT_INODE);
874 :
875 : /* go further to find it by name */
876 : }
877 :
878 : /* initialize for later overwrite */
- 879 172378 : is_file_reported = 0;
- 880 172378 : is_original_file_size_different_than_zero = 0;
+ 879 172321 : is_file_reported = 0;
+ 880 172321 : is_original_file_size_different_than_zero = 0;
881 :
882 : /* then try finding it by name */
- 883 172378 : file = tommy_hashdyn_search(&disk->pathset, file_path_compare_to_arg, sub, file_path_hash(sub));
+ 883 172321 : file = tommy_hashdyn_search(&disk->pathset, file_path_compare_to_arg, sub, file_path_hash(sub));
884 :
885 : /* keep track if the file already exists */
- 886 172378 : is_file_already_present = file != 0;
+ 886 172321 : is_file_already_present = file != 0;
887 :
- 888 172378 : if (is_file_already_present) {
+ 888 172321 : if (is_file_already_present) {
889 : /* if the file is without an inode */
- 890 97862 : if (file_flag_has(file, FILE_IS_WITHOUT_INODE)) {
+ 890 97805 : if (file_flag_has(file, FILE_IS_WITHOUT_INODE)) {
891 : /* set it now */
- 892 12545 : file->inode = st->st_ino;
+ 892 13077 : file->inode = st->st_ino;
893 :
894 : /* insert in the set */
- 895 12545 : tommy_hashdyn_insert(&disk->inodeset, &file->nodeset, file, file_inode_hash(file->inode));
+ 895 13077 : tommy_hashdyn_insert(&disk->inodeset, &file->nodeset, file, file_inode_hash(file->inode));
896 :
897 : /* unmark as missing inode */
- 898 12545 : file_flag_clear(file, FILE_IS_WITHOUT_INODE);
+ 898 13077 : file_flag_clear(file, FILE_IS_WITHOUT_INODE);
899 : } else {
900 : /* here the inode has to be different, otherwise we would have found it before */
- 901 85317 : if (file->inode == st->st_ino) {
+ 901 84728 : if (file->inode == st->st_ino) {
902 : /* LCOV_EXCL_START */
903 : log_fatal(EINTERNAL, "Internal inconsistency in inode '%" PRIu64 "' for files '%s%s' as unexpected matching\n", file->inode, disk->dir, sub);
904 : os_abort();
@@ -969,7 +969,7 @@
907 : }
908 :
909 : /* for sure it cannot be already present */
- 910 97862 : if (file_flag_has(file, FILE_IS_PRESENT)) {
+ 910 97805 : if (file_flag_has(file, FILE_IS_PRESENT)) {
911 : /* LCOV_EXCL_START */
912 : log_fatal(EINTERNAL, "Internal inconsistency in path for file '%s%s' matching and already present\n", disk->dir, sub);
913 : os_abort();
@@ -977,9 +977,9 @@
915 : }
916 :
917 : /* check if the file is not changed */
- 918 97862 : if (file->size == st->st_size
- 919 97266 : && file->mtime_sec == st->st_mtime
- 920 94970 : && (file->mtime_nsec == STAT_NSEC(st)
+ 918 97805 : if (file->size == st->st_size
+ 919 97209 : && file->mtime_sec == st->st_mtime
+ 920 94926 : && (file->mtime_nsec == STAT_NSEC(st)
921 : /* always accept the stored value if it's STAT_NSEC_INVALID */
922 : /* it happens when upgrading from an old version of SnapRAID */
923 : /* not yet supporting the nanosecond field */
@@ -987,11 +987,11 @@
925 : )
926 : ) {
927 : /* mark as present */
- 928 94968 : file_flag_set(file, FILE_IS_PRESENT);
+ 928 94924 : file_flag_set(file, FILE_IS_PRESENT);
929 :
930 : /* update the nano seconds mtime only if different */
931 : /* to avoid unneeded updates */
- 932 94968 : if (file->mtime_nsec == STAT_NSEC_INVALID
+ 932 94924 : if (file->mtime_nsec == STAT_NSEC_INVALID
933 0 : && STAT_NSEC(st) != STAT_NSEC_INVALID
934 : ) {
935 0 : file->mtime_nsec = STAT_NSEC(st);
@@ -1001,30 +1001,30 @@
939 : }
940 :
941 : /* if when processing the disk we used the past inodes values */
- 942 94968 : if (has_past_inodes) {
+ 942 94924 : if (has_past_inodes) {
943 : /* if persistent inodes are supported, we are sure that the inode number */
944 : /* is now different, because otherwise the file would have been found */
945 : /* when searching by inode. */
946 : /* if the inode is different, it means a rewritten file with the same path */
947 : /* like when restoring a backup that restores also the timestamp */
- 948 94954 : ++scan->count_restore;
+ 948 94910 : ++scan->count_restore;
949 :
- 950 94954 : log_tag("scan:restore:%s:%s\n", disk->name, esc_tag(sub, esc_buffer));
- 951 94954 : if (is_diff) {
+ 950 94910 : log_tag("scan:restore:%s:%s\n", disk->name, esc_tag(sub, esc_buffer));
+ 951 94910 : if (is_diff) {
952 0 : msg_info("restore %s\n", fmt_term(disk, sub, esc_buffer));
953 : }
954 :
955 : /* remove from the inode set */
- 956 94954 : tommy_hashdyn_remove_existing(&disk->inodeset, &file->nodeset);
+ 956 94910 : tommy_hashdyn_remove_existing(&disk->inodeset, &file->nodeset);
957 :
958 : /* save the new inode */
- 959 94954 : file->inode = st->st_ino;
+ 959 94910 : file->inode = st->st_ino;
960 :
961 : /* reinsert in the inode set */
- 962 94954 : tommy_hashdyn_insert(&disk->inodeset, &file->nodeset, file, file_inode_hash(file->inode));
+ 962 94910 : tommy_hashdyn_insert(&disk->inodeset, &file->nodeset, file, file_inode_hash(file->inode));
963 :
964 : /* we have to save the new inode */
- 965 94954 : scan->need_write = 1;
+ 965 94910 : scan->need_write = 1;
966 : } else {
967 : /* otherwise it's the case of not persistent inode, where doesn't */
968 : /* matter if the inode is different or equal, because they have no */
@@ -1037,24 +1037,24 @@
975 : }
976 :
977 : /* mark the file as kept */
- 978 94968 : scan_file_keep(scan, file);
+ 978 94924 : scan_file_keep(scan, file);
979 :
980 : /* nothing more to do */
- 981 94968 : return;
+ 981 94924 : return;
982 : }
983 :
984 : /* here if the file is changed but with the correct name */
985 :
986 : /* save the info for later printout */
- 987 2894 : file_already_present_size = file->size;
- 988 2894 : file_already_present_mtime_sec = file->mtime_sec;
- 989 2894 : file_already_present_mtime_nsec = file->mtime_nsec;
+ 987 2881 : file_already_present_size = file->size;
+ 988 2881 : file_already_present_mtime_sec = file->mtime_sec;
+ 989 2881 : file_already_present_mtime_nsec = file->mtime_nsec;
990 :
991 : /* keep track if the original file was not of zero size */
- 992 2894 : is_original_file_size_different_than_zero = file->size != 0;
+ 992 2881 : is_original_file_size_different_than_zero = file->size != 0;
993 :
994 : /* remove it, and continue to insert it again */
- 995 2894 : scan_file_remove(scan, file);
+ 995 2881 : scan_file_remove(scan, file);
996 :
997 : /* and continue to insert it again */
998 : } else {
@@ -1066,13 +1066,13 @@
1004 : /* refresh the info, to ensure that they are synced, */
1005 : /* note that we refresh only the info of the new or modified files */
1006 : /* because this is slow operation */
- 1007 77410 : scan_file_refresh(scan, sub, st, &physical);
+ 1007 77397 : scan_file_refresh(scan, sub, st, &physical);
1008 :
1009 : #ifndef _WIN32
1010 : /* do a safety check to ensure that the common ext4 case of zeroing */
1011 : /* the size of a file after a crash doesn't propagate to the backup */
1012 : /* this check is specific for Linux, so we disable it on Windows */
- 1013 77410 : if (is_original_file_size_different_than_zero && st->st_size == 0) {
+ 1013 77397 : if (is_original_file_size_different_than_zero && st->st_size == 0) {
1014 0 : if (!state->opt.force_zero) {
1015 : /* LCOV_EXCL_START */
1016 : log_fatal(ESOFT, "The file '%s%s' has unexpected zero size!\n", disk->dir, sub);
@@ -1091,35 +1091,35 @@
1029 : #endif
1030 :
1031 : /* insert it */
- 1032 77410 : file = file_alloc(state->block_size, sub, st->st_size, st->st_mtime, STAT_NSEC(st), st->st_ino, physical);
+ 1032 77397 : file = file_alloc(state->block_size, sub, st->st_size, st->st_mtime, STAT_NSEC(st), st->st_ino, physical);
1033 :
1034 : /* mark it as present */
- 1035 77410 : file_flag_set(file, FILE_IS_PRESENT);
+ 1035 77397 : file_flag_set(file, FILE_IS_PRESENT);
1036 :
1037 : /* if copy detection is enabled */
1038 : /* note that the copy detection is tried also for updated files */
1039 : /* this makes sense because it may happen to have two different copies */
1040 : /* of the same file, and we move the right one over the wrong one */
1041 : /* in such case we have a "copy" over an "update" */
- 1042 77410 : if (!state->opt.force_nocopy) {
- 1043 77410 : tommy_uint32_t hash = file_stamp_hash(file->size, file->mtime_sec, file->mtime_nsec);
+ 1042 77397 : if (!state->opt.force_nocopy) {
+ 1043 77397 : tommy_uint32_t hash = file_stamp_hash(file->size, file->mtime_sec, file->mtime_nsec);
1044 :
1045 : /* search for a file with the same name and stamp in all the disks */
- 1046 410916 : for (i = state->disklist; i != 0; i = i->next) {
- 1047 357143 : struct snapraid_disk* other_disk = i->data;
+ 1046 410826 : for (i = state->disklist; i != 0; i = i->next) {
+ 1047 357066 : struct snapraid_disk* other_disk = i->data;
1048 : struct snapraid_file* other_file;
1049 :
- 1050 357143 : stamp_lock(other_disk);
+ 1050 357066 : stamp_lock(other_disk);
1051 : /* if the nanosecond part of the time stamp is valid, search */
1052 : /* for name and stamp, otherwise for path and stamp */
- 1053 357143 : if (file->mtime_nsec != 0 && file->mtime_nsec != STAT_NSEC_INVALID)
- 1054 357035 : other_file = tommy_hashdyn_search(&other_disk->stampset, file_namestamp_compare, file, hash);
+ 1053 357066 : if (file->mtime_nsec != 0 && file->mtime_nsec != STAT_NSEC_INVALID)
+ 1054 356958 : other_file = tommy_hashdyn_search(&other_disk->stampset, file_namestamp_compare, file, hash);
1055 : else
1056 108 : other_file = tommy_hashdyn_search(&other_disk->stampset, file_pathstamp_compare, file, hash);
- 1057 357143 : stamp_unlock(other_disk);
+ 1057 357066 : stamp_unlock(other_disk);
1058 :
1059 : /* if found, and it's a fully hashed file */
- 1060 357143 : if (other_file && file_is_full_hashed_and_stable(scan->state, other_disk, other_file)) {
+ 1060 357066 : if (other_file && file_is_full_hashed_and_stable(scan->state, other_disk, other_file)) {
1061 : /* assume that the file is a copy, and reuse the hash */
1062 23637 : file_copy(other_file, file);
1063 :
@@ -1142,16 +1142,16 @@
1080 :
1081 : /* if not yet reported, do it now */
1082 : /* we postpone this to avoid to print two times the copied files */
- 1083 77410 : if (!is_file_reported) {
- 1084 53773 : if (is_file_already_present) {
- 1085 2894 : ++scan->count_change;
+ 1083 77397 : if (!is_file_reported) {
+ 1084 53760 : if (is_file_already_present) {
+ 1085 2881 : ++scan->count_change;
1086 :
- 1087 2894 : log_tag("scan:update:%s:%s: %" PRIu64 " %" PRIu64 ".%d -> %" PRIu64 " %" PRIu64 ".%d\n", disk->name, esc_tag(sub, esc_buffer),
+ 1087 2881 : log_tag("scan:update:%s:%s: %" PRIu64 " %" PRIu64 ".%d -> %" PRIu64 " %" PRIu64 ".%d\n", disk->name, esc_tag(sub, esc_buffer),
1088 : file_already_present_size, file_already_present_mtime_sec, file_already_present_mtime_nsec,
1089 : file->size, file->mtime_sec, file->mtime_nsec
1090 : );
1091 :
- 1092 2894 : if (is_diff) {
+ 1092 2881 : if (is_diff) {
1093 118 : msg_info("update %s\n", fmt_term(disk, sub, esc_buffer));
1094 : }
1095 : } else {
@@ -1165,7 +1165,7 @@
1103 : }
1104 :
1105 : /* insert the file in the delayed list */
- 1106 77410 : scan_file_insert(scan, file);
+ 1106 77397 : scan_file_insert(scan, file);
1107 : }
1108 :
1109 : /**
@@ -1754,14 +1754,14 @@
1692 :
1693 : /* check for removed files */
1694 605 : node = disk->filelist;
- 1695 1091277 : while (node) {
- 1696 1090672 : struct snapraid_file* file = node->data;
+ 1695 1091290 : while (node) {
+ 1696 1090685 : struct snapraid_file* file = node->data;
1697 :
1698 : /* next node */
- 1699 1090672 : node = node->next;
+ 1699 1090685 : node = node->next;
1700 :
1701 : /* remove if not present */
- 1702 1090672 : if (!file_flag_has(file, FILE_IS_PRESENT)) {
+ 1702 1090685 : if (!file_flag_has(file, FILE_IS_PRESENT)) {
1703 29650 : ++scan->count_remove;
1704 :
1705 29650 : log_tag("scan:remove:%s:%s\n", disk->name, esc_tag(file->sub, esc_buffer));
@@ -1833,11 +1833,11 @@
1771 605 : phy_dup = 0;
1772 605 : phy_last = FILEPHY_UNREAD_OFFSET;
1773 605 : phy_file_last = 0;
- 1774 100702 : while (node) {
- 1775 100097 : struct snapraid_file* file = node->data;
+ 1774 100689 : while (node) {
+ 1775 100084 : struct snapraid_file* file = node->data;
1776 :
1777 : /* if the file is not empty, count duplicate physical offsets */
- 1778 100097 : if (state->opt.force_order == SORT_PHYSICAL && file->size != 0) {
+ 1778 100084 : if (state->opt.force_order == SORT_PHYSICAL && file->size != 0) {
1779 11418 : if (phy_file_last != 0 && file->physical == phy_last
1780 : /* files without offset are expected to have duplicates */
1781 0 : && phy_last != FILEPHY_WITHOUT_OFFSET
@@ -1854,10 +1854,10 @@
1792 : }
1793 :
1794 : /* next node */
- 1795 100097 : node = node->next;
+ 1795 100084 : node = node->next;
1796 :
1797 : /* insert in the parity */
- 1798 100097 : scan_file_allocate(scan, file);
+ 1798 100084 : scan_file_allocate(scan, file);
1799 : }
1800 :
1801 : /* mark the disk without reliable physical offset if it has duplicates */
diff --git a/cov/cmdline/scrub.c.func-sort-c.html b/cov/cmdline/scrub.c.func-sort-c.html
index a3c92b38..2939451b 100644
--- a/cov/cmdline/scrub.c.func-sort-c.html
+++ b/cov/cmdline/scrub.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/cmdline/scrub.c.func.html b/cov/cmdline/scrub.c.func.html
index c8189fcc..1ee8f66b 100644
--- a/cov/cmdline/scrub.c.func.html
+++ b/cov/cmdline/scrub.c.func.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/cmdline/scrub.c.gcov.html b/cov/cmdline/scrub.c.gcov.html
index a93ec933..0d0e8b93 100644
--- a/cov/cmdline/scrub.c.gcov.html
+++ b/cov/cmdline/scrub.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -131,12 +131,12 @@
69 :
70 : /* bad blocks are always scrubbed in all plans */
71 56085 : if (info_get_bad(info))
- 72 1771 : return 1;
+ 72 1772 : return 1;
73 :
- 74 54314 : switch (plan->plan) {
- 75 8523 : case SCRUB_FULL :
+ 74 54313 : switch (plan->plan) {
+ 75 8522 : case SCRUB_FULL :
76 : /* in 'full' plan everything is scrubbed */
- 77 8523 : return 1;
+ 77 8522 : return 1;
78 9215 : case SCRUB_EVEN :
79 : /* in 'even' plan, scrub only even blocks */
80 9215 : return i % 2 == 0;
@@ -206,9 +206,9 @@
144 : /* if the file is different than the current one, close it */
145 153017 : if (handle->file != 0 && handle->file != task->file) {
146 : /* keep a pointer at the file we are going to close for error reporting */
- 147 72541 : struct snapraid_file* report = handle->file;
- 148 72541 : ret = handle_close(handle);
- 149 72541 : if (ret == -1) {
+ 147 72572 : struct snapraid_file* report = handle->file;
+ 148 72572 : ret = handle_close(handle);
+ 149 72572 : if (ret == -1) {
150 : /* LCOV_EXCL_START */
151 : /* This one is really an unexpected error, because we are only reading */
152 : /* and closing a descriptor should never fail */
@@ -907,9 +907,9 @@
845 : }
846 :
847 11 : count = 0;
- 848 29 : for (tommy_node* j = tommy_list_head(&state->bucketlist); j != 0; j = j->next) {
- 849 18 : struct snapraid_bucket* bucket = j->data;
- 850 18 : count += bucket->count_scrubbed + bucket->count_justsynced;
+ 848 27 : for (tommy_node* j = tommy_list_head(&state->bucketlist); j != 0; j = j->next) {
+ 849 16 : struct snapraid_bucket* bucket = j->data;
+ 850 16 : count += bucket->count_scrubbed + bucket->count_justsynced;
851 : }
852 :
853 11 : if (!count) {
diff --git a/cov/cmdline/search.c.func-sort-c.html b/cov/cmdline/search.c.func-sort-c.html
index 5972d4f2..8710bd57 100644
--- a/cov/cmdline/search.c.func-sort-c.html
+++ b/cov/cmdline/search.c.func-sort-c.html
@@ -31,13 +31,13 @@
|
-
+
-
+
-
+
|
@@ -73,19 +73,19 @@
| search_file_compare |
- 20005 |
+ 20083 |
| state_search_fetch |
- 638750 |
+ 639007 |
| search_file |
- 1843797 |
+ 1843854 |
| search_file_free |
- 1843797 |
+ 1843854 |
diff --git a/cov/cmdline/search.c.func.html b/cov/cmdline/search.c.func.html
index 32bfdb02..3dd332ef 100644
--- a/cov/cmdline/search.c.func.html
+++ b/cov/cmdline/search.c.func.html
@@ -31,13 +31,13 @@
|
-
+
-
+
-
+
|
@@ -65,15 +65,15 @@
| search_file |
- 1843797 |
+ 1843854 |
| search_file_compare |
- 20005 |
+ 20083 |
| search_file_free |
- 1843797 |
+ 1843854 |
| state_search |
@@ -85,7 +85,7 @@
| state_search_fetch |
- 638750 |
+ 639007 |
diff --git a/cov/cmdline/search.c.gcov.html b/cov/cmdline/search.c.gcov.html
index 1a782acd..5218e3d8 100644
--- a/cov/cmdline/search.c.gcov.html
+++ b/cov/cmdline/search.c.gcov.html
@@ -31,13 +31,13 @@
|
-
+
-
+
-
+
|
@@ -85,27 +85,27 @@
23 : /****************************************************************************/
24 : /* search */
25 :
- 26 1843797 : static void search_file(struct snapraid_state* state, const char* path, data_off_t size, int64_t mtime_sec, int mtime_nsec)
+ 26 1843854 : 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 1843797 : file = malloc_nofail(sizeof(struct snapraid_search_file));
- 32 1843797 : file->path = strdup_nofail(path);
- 33 1843797 : file->size = size;
- 34 1843797 : file->mtime_sec = mtime_sec;
- 35 1843797 : file->mtime_nsec = mtime_nsec;
+ 31 1843854 : file = malloc_nofail(sizeof(struct snapraid_search_file));
+ 32 1843854 : file->path = strdup_nofail(path);
+ 33 1843854 : file->size = size;
+ 34 1843854 : file->mtime_sec = mtime_sec;
+ 35 1843854 : file->mtime_nsec = mtime_nsec;
36 :
- 37 1843797 : file_hash = file_stamp_hash(file->size, file->mtime_sec, file->mtime_nsec);
+ 37 1843854 : file_hash = file_stamp_hash(file->size, file->mtime_sec, file->mtime_nsec);
38 :
- 39 1843797 : tommy_hashdyn_insert(&state->searchset, &file->node, file, file_hash);
- 40 1843797 : }
+ 39 1843854 : tommy_hashdyn_insert(&state->searchset, &file->node, file, file_hash);
+ 40 1843854 : }
41 :
- 42 1843797 : void search_file_free(struct snapraid_search_file* file)
+ 42 1843854 : void search_file_free(struct snapraid_search_file* file)
43 : {
- 44 1843797 : free(file->path);
- 45 1843797 : free(file);
- 46 1843797 : }
+ 44 1843854 : free(file->path);
+ 45 1843854 : free(file);
+ 46 1843854 : }
47 :
48 : struct search_file_compare_arg {
49 : const struct snapraid_state* state;
@@ -117,29 +117,29 @@
55 : int prevhash;
56 : };
57 :
- 58 20005 : int search_file_compare(const void* void_arg, const void* void_data)
+ 58 20083 : int search_file_compare(const void* void_arg, const void* void_data)
59 : {
- 60 20005 : const struct search_file_compare_arg* arg = void_arg;
- 61 20005 : const struct snapraid_search_file* file = void_data;
- 62 20005 : const struct snapraid_state* state = arg->state;
+ 60 20083 : const struct search_file_compare_arg* arg = void_arg;
+ 61 20083 : const struct snapraid_search_file* file = void_data;
+ 62 20083 : const struct snapraid_state* state = arg->state;
63 : unsigned char buffer_hash[HASH_MAX];
- 64 20005 : const char* path = file->path;
+ 64 20083 : const char* path = file->path;
65 : int f;
66 : ssize_t ret;
67 :
68 : /* compare file info */
- 69 20005 : if (arg->file->size != file->size)
- 70 0 : return -1;
+ 69 20083 : if (arg->file->size != file->size)
+ 70 20 : return -1;
71 :
- 72 20005 : if (arg->file->mtime_sec != file->mtime_sec)
+ 72 20063 : if (arg->file->mtime_sec != file->mtime_sec)
73 0 : return -1;
74 :
- 75 20005 : if (arg->file->mtime_nsec != file->mtime_nsec)
+ 75 20063 : if (arg->file->mtime_nsec != file->mtime_nsec)
76 0 : return -1;
77 :
78 : /* read the block and compare the hash */
- 79 20005 : f = open(path, O_RDONLY | O_BINARY);
- 80 20005 : if (f == -1) {
+ 79 20063 : f = open(path, O_RDONLY | O_BINARY);
+ 80 20063 : if (f == -1) {
81 : /* LCOV_EXCL_START */
82 : if (errno == ENOENT) {
83 : log_fatal(EUSER, "DANGER! file '%s' disappeared.\n", path);
@@ -151,16 +151,16 @@
89 : /* LCOV_EXCL_STOP */
90 : }
91 :
- 92 20005 : ret = pread(f, arg->buffer, arg->read_size, arg->offset);
- 93 20005 : if (ret < 0 || (unsigned)ret != arg->read_size) {
+ 92 20063 : ret = pread(f, arg->buffer, arg->read_size, arg->offset);
+ 93 20063 : if (ret < 0 || (unsigned)ret != arg->read_size) {
94 : /* LCOV_EXCL_START */
95 : log_fatal(errno, "Error reading file '%s'. %s.\n", path, strerror(errno));
96 : exit(EXIT_FAILURE);
97 : /* LCOV_EXCL_STOP */
98 : }
99 :
- 100 20005 : ret = close(f);
- 101 20005 : if (ret != 0) {
+ 100 20063 : ret = close(f);
+ 101 20063 : if (ret != 0) {
102 : /* LCOV_EXCL_START */
103 : log_fatal(errno, "Error closing file '%s'. %s.\n", path, strerror(errno));
104 : exit(EXIT_FAILURE);
@@ -168,14 +168,14 @@
106 : }
107 :
108 : /* compute the hash */
- 109 20005 : if (arg->prevhash)
+ 109 20063 : if (arg->prevhash)
110 0 : memhash(state->prevhash, state->prevhashseed, buffer_hash, arg->buffer, arg->read_size);
111 : else
- 112 20005 : memhash(state->hash, state->hashseed, buffer_hash, arg->buffer, arg->read_size);
+ 112 20063 : memhash(state->hash, state->hashseed, buffer_hash, arg->buffer, arg->read_size);
113 :
114 : /* check if the hash is matching */
- 115 20005 : if (memcmp(buffer_hash, arg->block->hash, BLOCK_HASH_SIZE) != 0)
- 116 2095 : return -1;
+ 115 20063 : if (memcmp(buffer_hash, arg->block->hash, BLOCK_HASH_SIZE) != 0)
+ 116 2153 : 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 638750 : 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 639007 : 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 638750 : arg.state = state;
- 133 638750 : arg.block = missing_block;
- 134 638750 : arg.file = missing_file;
- 135 638750 : arg.buffer = buffer;
- 136 638750 : arg.offset = state->block_size * (data_off_t)missing_file_pos;
- 137 638750 : arg.read_size = file_block_size(missing_file, missing_file_pos, state->block_size);
- 138 638750 : arg.prevhash = prevhash;
+ 132 639007 : arg.state = state;
+ 133 639007 : arg.block = missing_block;
+ 134 639007 : arg.file = missing_file;
+ 135 639007 : arg.buffer = buffer;
+ 136 639007 : arg.offset = state->block_size * (data_off_t)missing_file_pos;
+ 137 639007 : arg.read_size = file_block_size(missing_file, missing_file_pos, state->block_size);
+ 138 639007 : arg.prevhash = prevhash;
139 :
- 140 638750 : file_hash = file_stamp_hash(arg.file->size, arg.file->mtime_sec, arg.file->mtime_nsec);
+ 140 639007 : 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 638750 : file = tommy_hashdyn_search(&state->searchset, search_file_compare, &arg, file_hash);
- 144 638750 : if (!file)
- 145 620840 : return -1;
+ 143 639007 : file = tommy_hashdyn_search(&state->searchset, search_file_compare, &arg, file_hash);
+ 144 639007 : if (!file)
+ 145 621097 : return -1;
146 :
147 : /* if found, buffer is already set with data */
148 17910 : return 0;
@@ -222,44 +222,44 @@
160 : /* LCOV_EXCL_STOP */
161 : }
162 :
- 163 2037708 : while (1) {
+ 163 2037834 : while (1) {
164 : char path_next[PATH_MAX];
165 : char sub_next[PATH_MAX];
166 : char out[PATH_MAX];
- 167 2040170 : struct snapraid_filter* reason = 0;
+ 167 2040296 : 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 2040170 : errno = 0;
- 174 2040170 : dd = readdir(d);
- 175 2040170 : if (dd == 0 && errno != 0) {
+ 173 2040296 : errno = 0;
+ 174 2040296 : dd = readdir(d);
+ 175 2040296 : if (dd == 0 && errno != 0) {
176 : /* LCOV_EXCL_START */
177 : log_fatal(errno, "Error reading directory '%s'. %s.\n", dir, strerror(errno));
178 : exit(EXIT_FAILURE);
179 : /* LCOV_EXCL_STOP */
180 : }
- 181 2040170 : if (dd == 0) {
+ 181 2040296 : if (dd == 0) {
182 2462 : break; /* finished */
183 : }
184 :
185 : /* skip "." and ".." files */
- 186 2037708 : name = dd->d_name;
- 187 2037708 : if (name[0] == '.' && (name[1] == 0 || (name[1] == '.' && name[2] == 0)))
+ 186 2037834 : name = dd->d_name;
+ 187 2037834 : if (name[0] == '.' && (name[1] == 0 || (name[1] == '.' && name[2] == 0)))
188 4924 : continue;
189 :
- 190 2032784 : pathprint(path_next, sizeof(path_next), "%s%s", dir, name);
- 191 2032784 : pathprint(sub_next, sizeof(sub_next), "%s%s", sub, name);
+ 190 2032910 : pathprint(path_next, sizeof(path_next), "%s%s", dir, name);
+ 191 2032910 : pathprint(sub_next, sizeof(sub_next), "%s%s", sub, name);
192 :
193 : /* exclude hidden files even before calling lstat() */
- 194 2032784 : if (disk != 0 && filter_hidden(state->filter_hidden, dd) != 0) {
+ 194 2032910 : 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 2032784 : if (disk != 0 && filter_content(&state->contentlist, path_next) != 0) {
+ 200 2032910 : 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 2032784 : if (lstat(path_next, &st) != 0) {
+ 224 2032910 : if (lstat(path_next, &st) != 0) {
225 : /* LCOV_EXCL_START */
226 : log_fatal(errno, "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 2032784 : if (S_ISREG(st.st_mode)) {
- 233 1968474 : if (disk == 0 || filter_path(&state->filterlist, &reason, disk->name, sub_next) == 0) {
- 234 1843797 : search_file(state, path_next, st.st_size, st.st_mtime, STAT_NSEC(&st));
+ 232 2032910 : if (S_ISREG(st.st_mode)) {
+ 233 1968609 : if (disk == 0 || filter_path(&state->filterlist, &reason, disk->name, sub_next) == 0) {
+ 234 1843854 : search_file(state, path_next, st.st_size, st.st_mtime, STAT_NSEC(&st));
235 : } else {
- 236 124677 : msg_verbose("Excluding link '%s' for rule '%s'\n", path_next, filter_type(reason, out, sizeof(out)));
+ 236 124755 : msg_verbose("Excluding link '%s' for rule '%s'\n", path_next, filter_type(reason, out, sizeof(out)));
237 : }
- 238 64310 : } else if (S_ISDIR(st.st_mode)) {
+ 238 64301 : } 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));
diff --git a/cov/cmdline/selftest.c.func-sort-c.html b/cov/cmdline/selftest.c.func-sort-c.html
index d693c961..5b445e68 100644
--- a/cov/cmdline/selftest.c.func-sort-c.html
+++ b/cov/cmdline/selftest.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/cmdline/selftest.c.func.html b/cov/cmdline/selftest.c.func.html
index 4fdb12a7..0a61b811 100644
--- a/cov/cmdline/selftest.c.func.html
+++ b/cov/cmdline/selftest.c.func.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/cmdline/selftest.c.gcov.html b/cov/cmdline/selftest.c.gcov.html
index 6939bd88..987dc1e0 100644
--- a/cov/cmdline/selftest.c.gcov.html
+++ b/cov/cmdline/selftest.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/cmdline/snapraid.c.func-sort-c.html b/cov/cmdline/snapraid.c.func-sort-c.html
index 6321b0f0..4ee91916 100644
--- a/cov/cmdline/snapraid.c.func-sort-c.html
+++ b/cov/cmdline/snapraid.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -81,23 +81,23 @@
| log_close |
- 267 |
+ 268 |
| log_open |
- 278 |
+ 279 |
| config |
- 287 |
+ 288 |
| snapraid_main |
- 288 |
+ 289 |
| test |
- 288 |
+ 289 |
diff --git a/cov/cmdline/snapraid.c.func.html b/cov/cmdline/snapraid.c.func.html
index e2c2747d..18d601dc 100644
--- a/cov/cmdline/snapraid.c.func.html
+++ b/cov/cmdline/snapraid.c.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,15 +61,15 @@
| config |
- 287 |
+ 288 |
| log_close |
- 267 |
+ 268 |
| log_open |
- 278 |
+ 279 |
| memory |
@@ -85,11 +85,11 @@
| snapraid_main |
- 288 |
+ 289 |
| test |
- 288 |
+ 289 |
| usage |
diff --git a/cov/cmdline/snapraid.c.gcov.html b/cov/cmdline/snapraid.c.gcov.html
index ab932c2d..30882961 100644
--- a/cov/cmdline/snapraid.c.gcov.html
+++ b/cov/cmdline/snapraid.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -158,14 +158,14 @@
96 244 : msg_progress("Using %u MiB of memory for the file-system.\n", (unsigned)(malloc_counter_get() / MEBI));
97 244 : }
98 :
- 99 288 : void test(int argc, char* argv[])
+ 99 289 : void test(int argc, char* argv[])
100 : {
101 : int i;
102 : char buffer[ESC_MAX];
103 :
104 : /* special testing code for quoting */
- 105 288 : if (argc < 2 || strcmp(argv[1], "test") != 0)
- 106 287 : return;
+ 105 289 : if (argc < 2 || strcmp(argv[1], "test") != 0)
+ 106 288 : return;
107 :
108 1 : assert(strcmp(strpolish(strcpy(buffer, "\r \n\xFF")), " ") == 0);
109 1 : assert(strcmp(strtrim(strcpy(buffer, " trim trim \n\r")), "trim trim") == 0);
@@ -556,7 +556,7 @@
494 : /****************************************************************************/
495 : /* log */
496 :
- 497 278 : void log_open(const char* file)
+ 497 279 : void log_open(const char* file)
498 : {
499 : char path[PATH_MAX];
500 : const char* mode;
@@ -569,8 +569,8 @@
507 : #endif
508 :
509 : /* leave stdlog at 0 if not specified */
- 510 278 : if (file == 0)
- 511 204 : return;
+ 510 279 : if (file == 0)
+ 511 205 : return;
512 :
513 80 : t = time(0);
514 : #if HAVE_LOCALTIME_R
@@ -647,9 +647,9 @@
585 : }
586 : }
587 :
- 588 267 : void log_close(const char* file)
+ 588 268 : void log_close(const char* file)
589 : {
- 590 267 : if (stdlog != stdout && stdlog != stderr && stdlog != 0) {
+ 590 268 : if (stdlog != stdout && stdlog != stderr && stdlog != 0) {
591 74 : if (fclose(stdlog) != 0) {
592 : /* LCOV_EXCL_START */
593 : log_fatal(errno, "Error closing the log file '%s'. %s.\n", file, strerror(errno));
@@ -658,13 +658,13 @@
596 : }
597 : }
598 :
- 599 267 : stdlog = 0;
- 600 267 : }
+ 599 268 : stdlog = 0;
+ 600 268 : }
601 :
602 : /****************************************************************************/
603 : /* config */
604 :
- 605 287 : void config(char* conf, size_t conf_size, const char* argv0)
+ 605 288 : void config(char* conf, size_t conf_size, const char* argv0)
606 : {
607 : #ifdef _WIN32
608 : char* slash;
@@ -683,15 +683,15 @@
621 :
622 : #ifdef SYSCONFDIR
623 : /* if it exists, give precedence at sysconfdir, usually /usr/local/etc */
- 624 287 : if (access(SYSCONFDIR "/" PACKAGE ".conf", F_OK) == 0) {
+ 624 288 : if (access(SYSCONFDIR "/" PACKAGE ".conf", F_OK) == 0) {
625 0 : pathcpy(conf, conf_size, SYSCONFDIR "/" PACKAGE ".conf");
626 : } else /* otherwise fallback to plain /etc */
627 : #endif
628 : {
- 629 287 : pathcpy(conf, conf_size, "/etc/" PACKAGE ".conf");
+ 629 288 : pathcpy(conf, conf_size, "/etc/" PACKAGE ".conf");
630 : }
631 : #endif
- 632 287 : }
+ 632 288 : }
633 :
634 : /****************************************************************************/
635 : /* main */
@@ -1029,7 +1029,7 @@
967 : #define OPERATION_PROBE 18
968 : #define OPERATION_LOCATE 19
969 :
- 970 288 : int snapraid_main(int argc, char* argv[])
+ 970 289 : int snapraid_main(int argc, char* argv[])
971 : {
972 : int c;
973 : struct snapraid_option opt;
@@ -1064,41 +1064,41 @@
1002 : #endif
1003 : int i;
1004 :
- 1005 288 : test(argc, argv);
+ 1005 289 : test(argc, argv);
1006 :
- 1007 287 : lock_init();
+ 1007 288 : lock_init();
1008 :
1009 : /* defaults */
- 1010 287 : config(conf, sizeof(conf), argv[0]);
- 1011 287 : memset(&opt, 0, sizeof(opt));
- 1012 287 : opt.io_error_limit = 100;
- 1013 287 : blockstart = 0;
- 1014 287 : blockcount = 0;
- 1015 287 : tommy_list_init(&filterlist_file);
- 1016 287 : tommy_list_init(&filterlist_disk);
- 1017 287 : speed_test_period = -1;
- 1018 287 : speed_test_blocks_size = -1;
- 1019 287 : speed_test_disks_number = -1;
- 1020 287 : filter_missing = 0;
- 1021 287 : filter_error = 0;
- 1022 287 : plan100 = SCRUB_AUTO;
- 1023 287 : olderthan = SCRUB_AUTO;
- 1024 287 : import_timestamp = 0;
- 1025 287 : import_content = 0;
- 1026 287 : log_file = 0;
- 1027 287 : lock = 0;
- 1028 287 : gen_conf = 0;
- 1029 287 : speedtest = 0;
- 1030 287 : run = 0;
+ 1010 288 : config(conf, sizeof(conf), argv[0]);
+ 1011 288 : memset(&opt, 0, sizeof(opt));
+ 1012 288 : opt.io_error_limit = 100;
+ 1013 288 : blockstart = 0;
+ 1014 288 : blockcount = 0;
+ 1015 288 : tommy_list_init(&filterlist_file);
+ 1016 288 : tommy_list_init(&filterlist_disk);
+ 1017 288 : speed_test_period = -1;
+ 1018 288 : speed_test_blocks_size = -1;
+ 1019 288 : speed_test_disks_number = -1;
+ 1020 288 : filter_missing = 0;
+ 1021 288 : filter_error = 0;
+ 1022 288 : plan100 = SCRUB_AUTO;
+ 1023 288 : olderthan = SCRUB_AUTO;
+ 1024 288 : import_timestamp = 0;
+ 1025 288 : import_content = 0;
+ 1026 288 : log_file = 0;
+ 1027 288 : lock = 0;
+ 1028 288 : gen_conf = 0;
+ 1029 288 : speedtest = 0;
+ 1030 288 : run = 0;
1031 :
- 1032 287 : opterr = 0;
- 1033 287 : while ((c =
+ 1032 288 : opterr = 0;
+ 1033 288 : while ((c =
1034 : #if HAVE_GETOPT_LONG
- 1035 3607 : getopt_long(argc, argv, OPTIONS, long_options, 0))
+ 1035 3608 : getopt_long(argc, argv, OPTIONS, long_options, 0))
1036 : #else
1037 : getopt(argc, argv, OPTIONS))
1038 : #endif
- 1039 3607 : != EOF) {
+ 1039 3608 : != EOF) {
1040 3324 : switch (c) {
1041 280 : case 'c' :
1042 280 : pathimport(conf, sizeof(conf), optarg);
@@ -1510,69 +1510,69 @@
1448 : }
1449 : }
1450 :
- 1451 283 : os_init(opt.force_scan_winfind);
- 1452 283 : raid_init();
- 1453 283 : crc32c_init();
- 1454 283 : random_reseed();
+ 1451 284 : os_init(opt.force_scan_winfind);
+ 1452 284 : raid_init();
+ 1453 284 : crc32c_init();
+ 1454 284 : random_reseed();
1455 :
- 1456 283 : if (speedtest != 0) {
+ 1456 284 : if (speedtest != 0) {
1457 4 : speed(speed_test_period, speed_test_disks_number, speed_test_blocks_size);
1458 4 : os_done();
1459 4 : exit(EXIT_SUCCESS);
1460 : }
1461 :
- 1462 279 : if (gen_conf != 0) {
+ 1462 280 : if (gen_conf != 0) {
1463 1 : generate_configuration(gen_conf);
1464 1 : os_done();
1465 1 : exit(EXIT_SUCCESS);
1466 : }
1467 :
- 1468 278 : if (optind + 1 != argc) {
+ 1468 279 : if (optind + 1 != argc) {
1469 : /* LCOV_EXCL_START */
1470 : usage(conf);
1471 : exit(EXIT_FAILURE);
1472 : /* LCOV_EXCL_STOP */
1473 : }
1474 :
- 1475 278 : command = argv[optind];
- 1476 278 : if (strcmp(command, "diff") == 0) {
+ 1475 279 : command = argv[optind];
+ 1476 279 : if (strcmp(command, "diff") == 0) {
1477 8 : operation = OPERATION_DIFF;
- 1478 270 : } else if (strcmp(argv[optind], "sync") == 0) {
+ 1478 271 : } else if (strcmp(argv[optind], "sync") == 0) {
1479 94 : operation = OPERATION_SYNC;
- 1480 176 : } else if (strcmp(argv[optind], "check") == 0) {
+ 1480 177 : } else if (strcmp(argv[optind], "check") == 0) {
1481 75 : operation = OPERATION_CHECK;
- 1482 101 : } else if (strcmp(argv[optind], "fix") == 0) {
+ 1482 102 : } else if (strcmp(argv[optind], "fix") == 0) {
1483 46 : operation = OPERATION_FIX;
- 1484 55 : } else if (strcmp(argv[optind], "test-dry") == 0) {
+ 1484 56 : } else if (strcmp(argv[optind], "test-dry") == 0) {
1485 3 : operation = OPERATION_DRY;
- 1486 52 : } else if (strcmp(argv[optind], "dup") == 0) {
+ 1486 53 : } else if (strcmp(argv[optind], "dup") == 0) {
1487 3 : operation = OPERATION_DUP;
- 1488 49 : } else if (strcmp(argv[optind], "list") == 0) {
+ 1488 50 : } else if (strcmp(argv[optind], "list") == 0) {
1489 5 : operation = OPERATION_LIST;
- 1490 44 : } else if (strcmp(argv[optind], "pool") == 0) {
+ 1490 45 : } else if (strcmp(argv[optind], "pool") == 0) {
1491 3 : operation = OPERATION_POOL;
- 1492 41 : } else if (strcmp(argv[optind], "rehash") == 0) {
+ 1492 42 : } else if (strcmp(argv[optind], "rehash") == 0) {
1493 1 : operation = OPERATION_REHASH;
- 1494 40 : } else if (strcmp(argv[optind], "scrub") == 0) {
+ 1494 41 : } else if (strcmp(argv[optind], "scrub") == 0) {
1495 11 : operation = OPERATION_SCRUB;
- 1496 29 : } else if (strcmp(argv[optind], "status") == 0) {
+ 1496 30 : } else if (strcmp(argv[optind], "status") == 0) {
1497 15 : operation = OPERATION_STATUS;
- 1498 14 : } else if (strcmp(argv[optind], "test-rewrite") == 0) {
+ 1498 15 : } else if (strcmp(argv[optind], "test-rewrite") == 0) {
1499 1 : operation = OPERATION_REWRITE;
- 1500 13 : } else if (strcmp(argv[optind], "read") == 0) {
+ 1500 14 : } else if (strcmp(argv[optind], "read") == 0) {
1501 1 : operation = OPERATION_READ;
- 1502 12 : } else if (strcmp(argv[optind], "touch") == 0) {
+ 1502 13 : } else if (strcmp(argv[optind], "touch") == 0) {
1503 1 : operation = OPERATION_TOUCH;
- 1504 11 : } else if (strcmp(argv[optind], "up") == 0) {
+ 1504 12 : } else if (strcmp(argv[optind], "up") == 0) {
1505 1 : operation = OPERATION_SPINUP;
- 1506 10 : } else if (strcmp(argv[optind], "down") == 0) {
+ 1506 11 : } else if (strcmp(argv[optind], "down") == 0) {
1507 1 : operation = OPERATION_SPINDOWN;
- 1508 9 : } else if (strcmp(argv[optind], "devices") == 0) {
+ 1508 10 : } else if (strcmp(argv[optind], "devices") == 0) {
1509 1 : operation = OPERATION_DEVICES;
- 1510 8 : } else if (strcmp(argv[optind], "smart") == 0) {
+ 1510 9 : } else if (strcmp(argv[optind], "smart") == 0) {
1511 1 : operation = OPERATION_SMART;
- 1512 7 : } else if (strcmp(argv[optind], "probe") == 0) {
- 1513 2 : operation = OPERATION_PROBE;
+ 1512 8 : } else if (strcmp(argv[optind], "probe") == 0) {
+ 1513 3 : operation = OPERATION_PROBE;
1514 5 : } else if (strcmp(argv[optind], "locate") == 0) {
1515 5 : operation = OPERATION_LOCATE;
1516 : } else {
@@ -1583,11 +1583,11 @@
1521 : }
1522 :
1523 : /* check options compatibility */
- 1524 278 : switch (operation) {
+ 1524 279 : switch (operation) {
1525 75 : case OPERATION_CHECK :
1526 75 : break;
- 1527 203 : default :
- 1528 203 : if (opt.auditonly) {
+ 1527 204 : default :
+ 1528 204 : if (opt.auditonly) {
1529 : /* LCOV_EXCL_START */
1530 : log_fatal(EUSER, "You cannot use -a, --audit-only with the '%s' command\n", command);
1531 : exit(EXIT_FAILURE);
@@ -1595,15 +1595,15 @@
1533 : }
1534 : }
1535 :
- 1536 278 : switch (operation) {
- 1537 127 : case OPERATION_FIX :
+ 1536 279 : switch (operation) {
+ 1537 128 : case OPERATION_FIX :
1538 : case OPERATION_CHECK :
1539 : case OPERATION_SMART :
1540 : case OPERATION_PROBE :
1541 : case OPERATION_DEVICES :
1542 : case OPERATION_SPINUP :
1543 : case OPERATION_SPINDOWN :
- 1544 127 : break;
+ 1544 128 : break;
1545 151 : default :
1546 151 : if (opt.force_device) {
1547 : /* LCOV_EXCL_START */
@@ -1613,13 +1613,13 @@
1551 : }
1552 : }
1553 :
- 1554 278 : switch (operation) {
+ 1554 279 : switch (operation) {
1555 215 : case OPERATION_SYNC :
1556 : case OPERATION_CHECK :
1557 : case OPERATION_FIX :
1558 215 : break;
- 1559 63 : default :
- 1560 63 : if (opt.force_nocopy) {
+ 1559 64 : default :
+ 1560 64 : if (opt.force_nocopy) {
1561 : /* LCOV_EXCL_START */
1562 : log_fatal(EUSER, "You cannot use -N, --force-nocopy with the '%s' command\n", command);
1563 : exit(EXIT_FAILURE);
@@ -1627,25 +1627,25 @@
1565 : }
1566 : }
1567 :
- 1568 278 : switch (operation) {
+ 1568 279 : switch (operation) {
1569 94 : case OPERATION_SYNC :
1570 94 : break;
- 1571 184 : default :
- 1572 184 : if (opt.prehash) {
+ 1571 185 : default :
+ 1572 185 : if (opt.prehash) {
1573 : /* LCOV_EXCL_START */
1574 : log_fatal(EUSER, "You cannot use -h, --pre-hash with the '%s' command\n", command);
1575 : exit(EXIT_FAILURE);
1576 : /* LCOV_EXCL_STOP */
1577 : }
1578 :
- 1579 184 : if (opt.force_full) {
+ 1579 185 : if (opt.force_full) {
1580 : /* LCOV_EXCL_START */
1581 : log_fatal(EUSER, "You cannot use -F, --force-full with the '%s' command\n", command);
1582 : exit(EXIT_FAILURE);
1583 : /* LCOV_EXCL_STOP */
1584 : }
1585 :
- 1586 184 : if (opt.force_realloc) {
+ 1586 185 : if (opt.force_realloc) {
1587 : /* LCOV_EXCL_START */
1588 : log_fatal(EUSER, "You cannot use -R, --force-realloc with the '%s' command\n", command);
1589 : exit(EXIT_FAILURE);
@@ -1653,41 +1653,41 @@
1591 : }
1592 : }
1593 :
- 1594 278 : if (opt.force_full && opt.force_nocopy) {
+ 1594 279 : if (opt.force_full && opt.force_nocopy) {
1595 : /* LCOV_EXCL_START */
1596 : log_fatal(EUSER, "You cannot use the -F, --force-full and -N, --force-nocopy options simultaneously\n");
1597 : exit(EXIT_FAILURE);
1598 : /* LCOV_EXCL_STOP */
1599 : }
1600 :
- 1601 278 : if (opt.force_realloc && opt.force_nocopy) {
+ 1601 279 : if (opt.force_realloc && opt.force_nocopy) {
1602 : /* LCOV_EXCL_START */
1603 : log_fatal(EUSER, "You cannot use the -R, --force-realloc and -N, --force-nocopy options simultaneously\n");
1604 : exit(EXIT_FAILURE);
1605 : /* LCOV_EXCL_STOP */
1606 : }
1607 :
- 1608 278 : if (opt.force_realloc && opt.force_full) {
+ 1608 279 : if (opt.force_realloc && opt.force_full) {
1609 : /* LCOV_EXCL_START */
1610 : log_fatal(EUSER, "You cannot use the -R, --force-realloc and -F, --force-full options simultaneously\n");
1611 : exit(EXIT_FAILURE);
1612 : /* LCOV_EXCL_STOP */
1613 : }
1614 :
- 1615 278 : if (opt.prehash && opt.force_nocopy) {
+ 1615 279 : if (opt.prehash && opt.force_nocopy) {
1616 : /* LCOV_EXCL_START */
1617 : log_fatal(EUSER, "You cannot use the -h, --pre-hash and -N, --force-nocopy options simultaneously\n");
1618 : exit(EXIT_FAILURE);
1619 : /* LCOV_EXCL_STOP */
1620 : }
1621 :
- 1622 278 : switch (operation) {
+ 1622 279 : switch (operation) {
1623 124 : case OPERATION_CHECK :
1624 : case OPERATION_FIX :
1625 : case OPERATION_DRY :
1626 124 : break;
- 1627 152 : default :
- 1628 152 : if (!tommy_list_empty(&filterlist_disk)) {
+ 1627 153 : default :
+ 1628 153 : if (!tommy_list_empty(&filterlist_disk)) {
1629 : /* LCOV_EXCL_START */
1630 : log_fatal(EUSER, "You cannot use -d, --filter-disk with the '%s' command\n", command);
1631 : exit(EXIT_FAILURE);
@@ -1696,19 +1696,19 @@
1634 : /* fallthrough */
1635 : case OPERATION_SPINUP :
1636 : case OPERATION_SPINDOWN :
- 1637 154 : if (!tommy_list_empty(&filterlist_file)) {
+ 1637 155 : if (!tommy_list_empty(&filterlist_file)) {
1638 : /* LCOV_EXCL_START */
1639 : log_fatal(EUSER, "You cannot use -f, --filter with the '%s' command\n", command);
1640 : exit(EXIT_FAILURE);
1641 : /* LCOV_EXCL_STOP */
1642 : }
- 1643 154 : if (filter_missing != 0) {
+ 1643 155 : if (filter_missing != 0) {
1644 : /* LCOV_EXCL_START */
1645 : log_fatal(EUSER, "You cannot use -m, --filter-missing with the '%s' command\n", command);
1646 : exit(EXIT_FAILURE);
1647 : /* LCOV_EXCL_STOP */
1648 : }
- 1649 154 : if (filter_error != 0) {
+ 1649 155 : if (filter_error != 0) {
1650 : /* LCOV_EXCL_START */
1651 : log_fatal(EUSER, "You cannot use -e, --filter-error with the '%s' command\n", command);
1652 : exit(EXIT_FAILURE);
@@ -1718,19 +1718,19 @@
1656 :
1657 : /* errors must be always fixed on all disks */
1658 : /* because we don't keep the information on what disk is the error */
- 1659 278 : if (filter_error != 0 && !tommy_list_empty(&filterlist_disk)) {
+ 1659 279 : if (filter_error != 0 && !tommy_list_empty(&filterlist_disk)) {
1660 : /* LCOV_EXCL_START */
1661 : log_fatal(EUSER, "You cannot use -e, --filter-error and -d, --filter-disk simultaneously\n");
1662 : exit(EXIT_FAILURE);
1663 : /* LCOV_EXCL_STOP */
1664 : }
1665 :
- 1666 278 : switch (operation) {
+ 1666 279 : switch (operation) {
1667 121 : case OPERATION_CHECK :
1668 : case OPERATION_FIX :
1669 121 : break;
- 1670 157 : default :
- 1671 157 : if (import_timestamp != 0 || import_content != 0) {
+ 1670 158 : default :
+ 1671 158 : if (import_timestamp != 0 || import_content != 0) {
1672 : /* LCOV_EXCL_START */
1673 : log_fatal(EUSER, "Import not allowed with the '%s' command\n", command);
1674 : exit(EXIT_FAILURE);
@@ -1738,7 +1738,7 @@
1676 : }
1677 : }
1678 :
- 1679 278 : switch (operation) {
+ 1679 279 : switch (operation) {
1680 26 : case OPERATION_LIST :
1681 : case OPERATION_DUP :
1682 : case OPERATION_STATUS :
@@ -1750,7 +1750,7 @@
1688 26 : break;
1689 : }
1690 :
- 1691 278 : switch (operation) {
+ 1691 279 : switch (operation) {
1692 38 : case OPERATION_DIFF :
1693 : case OPERATION_LIST :
1694 : case OPERATION_DUP :
@@ -1765,7 +1765,7 @@
1703 38 : break;
1704 : }
1705 :
- 1706 278 : switch (operation) {
+ 1706 279 : switch (operation) {
1707 121 : case OPERATION_FIX :
1708 : case OPERATION_CHECK :
1709 : /* avoid to stop processing if a content file is not accessible */
@@ -1773,8 +1773,8 @@
1711 121 : break;
1712 : }
1713 :
- 1714 278 : switch (operation) {
- 1715 26 : case OPERATION_DIFF :
+ 1714 279 : switch (operation) {
+ 1715 27 : case OPERATION_DIFF :
1716 : case OPERATION_LIST :
1717 : case OPERATION_DUP :
1718 : case OPERATION_POOL :
@@ -1784,77 +1784,77 @@
1722 : case OPERATION_DEVICES :
1723 : case OPERATION_SMART :
1724 : case OPERATION_PROBE :
- 1725 26 : opt.skip_self = 1;
- 1726 26 : break;
+ 1725 27 : opt.skip_self = 1;
+ 1726 27 : break;
1727 : }
1728 :
- 1729 278 : switch (operation) {
+ 1729 279 : switch (operation) {
1730 : #if HAVE_DIRECT_IO
1731 108 : case OPERATION_SYNC :
1732 : case OPERATION_SCRUB :
1733 : case OPERATION_DRY :
1734 108 : break;
1735 : #endif
- 1736 170 : default :
+ 1736 171 : default :
1737 : /* we allow direct IO only on some commands */
- 1738 170 : if (opt.file_mode == ADVISE_DIRECT)
+ 1738 171 : if (opt.file_mode == ADVISE_DIRECT)
1739 0 : opt.file_mode = ADVISE_SEQUENTIAL;
- 1740 170 : break;
+ 1740 171 : break;
1741 : }
1742 :
- 1743 278 : switch (operation) {
- 1744 4 : case OPERATION_DEVICES :
+ 1743 279 : switch (operation) {
+ 1744 5 : case OPERATION_DEVICES :
1745 : case OPERATION_SMART :
1746 : case OPERATION_PROBE :
1747 : /* we may need to use these commands during operations */
- 1748 4 : opt.skip_lock = 1;
- 1749 4 : break;
+ 1748 5 : opt.skip_lock = 1;
+ 1749 5 : break;
1750 : }
1751 :
- 1752 278 : switch (operation) {
- 1753 3 : case OPERATION_SMART :
+ 1752 279 : switch (operation) {
+ 1753 4 : case OPERATION_SMART :
1754 : case OPERATION_PROBE :
1755 : /* allow to run without configuration file */
- 1756 3 : opt.auto_conf = 1;
- 1757 3 : break;
+ 1756 4 : opt.auto_conf = 1;
+ 1757 4 : break;
1758 : }
1759 :
1760 : /* open the log file */
- 1761 278 : log_open(log_file);
+ 1761 279 : log_open(log_file);
1762 :
1763 : /* print generic info into the log */
- 1764 278 : t = time(0);
+ 1764 279 : t = time(0);
1765 : #if HAVE_LOCALTIME_R
- 1766 278 : tm = localtime_r(&t, &tm_res);
+ 1766 279 : tm = localtime_r(&t, &tm_res);
1767 : #else
1768 : tm = localtime(&t);
1769 : #endif
- 1770 278 : log_tag("version:%s\n", PACKAGE_VERSION);
- 1771 278 : log_tag("unixtime:%" PRIi64 "\n", (int64_t)t);
- 1772 278 : if (tm) {
+ 1770 279 : log_tag("version:%s\n", PACKAGE_VERSION);
+ 1771 279 : log_tag("unixtime:%" PRIi64 "\n", (int64_t)t);
+ 1772 279 : if (tm) {
1773 : char datetime[64];
- 1774 278 : strftime(datetime, sizeof(datetime), "%Y-%m-%d %H:%M:%S", tm);
- 1775 278 : log_tag("time:%s\n", datetime);
+ 1774 279 : strftime(datetime, sizeof(datetime), "%Y-%m-%d %H:%M:%S", tm);
+ 1775 279 : log_tag("time:%s\n", datetime);
1776 : }
- 1777 278 : log_tag("command:%s\n", command);
- 1778 4526 : for (i = 0; i < argc; ++i)
- 1779 4248 : log_tag("argv:%u:%s\n", i, argv[i]);
- 1780 278 : log_flush();
+ 1777 279 : log_tag("command:%s\n", command);
+ 1778 4529 : for (i = 0; i < argc; ++i)
+ 1779 4250 : log_tag("argv:%u:%s\n", i, argv[i]);
+ 1780 279 : log_flush();
1781 :
- 1782 278 : if (!opt.skip_self)
+ 1782 279 : if (!opt.skip_self)
1783 1 : selftest();
1784 :
- 1785 278 : state_init(&state);
+ 1785 279 : state_init(&state);
1786 :
1787 : /* read the configuration file */
- 1788 278 : state_config(&state, conf, command, &opt, &filterlist_disk);
+ 1788 279 : state_config(&state, conf, command, &opt, &filterlist_disk);
1789 :
1790 : /* set the raid mode */
- 1791 277 : raid_mode(state.raid_mode);
+ 1791 278 : raid_mode(state.raid_mode);
1792 :
1793 : #if HAVE_LOCKFILE
1794 : /* create the lock file */
- 1795 277 : if (!opt.skip_lock && state.lockfile[0]) {
+ 1795 278 : if (!opt.skip_lock && state.lockfile[0]) {
1796 273 : lock = lock_lock(state.lockfile);
1797 273 : if (lock == -1) {
1798 : /* LCOV_EXCL_START */
@@ -1872,8 +1872,8 @@
1810 : (void)lock;
1811 : #endif
1812 :
- 1813 277 : ret = 0;
- 1814 277 : if (operation == OPERATION_DIFF) {
+ 1813 278 : ret = 0;
+ 1814 278 : if (operation == OPERATION_DIFF) {
1815 8 : state_read(&state);
1816 :
1817 : /* refresh the size info to log correct info */
@@ -1884,7 +1884,7 @@
1822 : /* abort if sync needed */
1823 8 : if (ret > 0)
1824 7 : exit(EXIT_SYNC_NEEDED);
- 1825 269 : } else if (operation == OPERATION_SYNC) {
+ 1825 270 : } else if (operation == OPERATION_SYNC) {
1826 :
1827 : /* in the next state read ensures to clear all the past hashes in case */
1828 : /* we are reading from an incomplete sync */
@@ -1962,7 +1962,7 @@
1900 0 : sleep(2);
1901 :
1902 92 : ret = state_sync(&state, blockstart, blockcount);
- 1903 175 : } else if (operation == OPERATION_DRY) {
+ 1903 176 : } else if (operation == OPERATION_DRY) {
1904 3 : state_read(&state);
1905 :
1906 : /* refresh the size info to log correct info */
@@ -1978,7 +1978,7 @@
1916 3 : signal_init();
1917 :
1918 3 : ret = state_dry(&state, blockstart, blockcount);
- 1919 172 : } else if (operation == OPERATION_REHASH) {
+ 1919 173 : } else if (operation == OPERATION_REHASH) {
1920 1 : state_read(&state);
1921 :
1922 : /* intercept signals while operating */
@@ -1989,7 +1989,7 @@
1927 : /* save the new state if required */
1928 1 : if (state.need_write)
1929 1 : state_write(&state);
- 1930 171 : } else if (operation == OPERATION_SCRUB) {
+ 1930 172 : } else if (operation == OPERATION_SCRUB) {
1931 11 : state_read(&state);
1932 :
1933 : /* refresh the size info before the content write */
@@ -2001,7 +2001,7 @@
1939 11 : signal_init();
1940 :
1941 11 : ret = state_scrub(&state, plan100, olderthan);
- 1942 160 : } else if (operation == OPERATION_REWRITE) {
+ 1942 161 : } else if (operation == OPERATION_REWRITE) {
1943 1 : state_read(&state);
1944 :
1945 : /* intercept signals while operating */
@@ -2010,11 +2010,11 @@
1948 1 : state_write(&state);
1949 :
1950 1 : memory();
- 1951 159 : } else if (operation == OPERATION_READ) {
+ 1951 160 : } else if (operation == OPERATION_READ) {
1952 1 : state_read(&state);
1953 :
1954 1 : memory();
- 1955 158 : } else if (operation == OPERATION_TOUCH) {
+ 1955 159 : } else if (operation == OPERATION_TOUCH) {
1956 1 : state_read(&state);
1957 :
1958 1 : memory();
@@ -2025,16 +2025,16 @@
1963 1 : signal_init();
1964 :
1965 1 : state_write(&state);
- 1966 157 : } else if (operation == OPERATION_SPINUP) {
+ 1966 158 : } else if (operation == OPERATION_SPINUP) {
1967 1 : state_device(&state, DEVICE_UP, &filterlist_disk);
- 1968 156 : } else if (operation == OPERATION_SPINDOWN) {
+ 1968 157 : } else if (operation == OPERATION_SPINDOWN) {
1969 1 : state_device(&state, DEVICE_DOWN, &filterlist_disk);
- 1970 155 : } else if (operation == OPERATION_DEVICES) {
+ 1970 156 : } else if (operation == OPERATION_DEVICES) {
1971 1 : state_device(&state, DEVICE_LIST, 0);
- 1972 154 : } else if (operation == OPERATION_SMART) {
+ 1972 155 : } else if (operation == OPERATION_SMART) {
1973 1 : state_device(&state, DEVICE_SMART, 0);
- 1974 153 : } else if (operation == OPERATION_PROBE) {
- 1975 2 : state_device(&state, DEVICE_PROBE, 0);
+ 1974 154 : } else if (operation == OPERATION_PROBE) {
+ 1975 3 : state_device(&state, DEVICE_PROBE, 0);
1976 151 : } else if (operation == OPERATION_STATUS) {
1977 15 : state_read(&state);
1978 :
@@ -2100,10 +2100,10 @@
2038 : }
2039 :
2040 : /* close log file */
- 2041 267 : log_close(log_file);
+ 2041 268 : log_close(log_file);
2042 :
2043 : #if HAVE_LOCKFILE
- 2044 267 : if (!opt.skip_lock && state.lockfile[0]) {
+ 2044 268 : if (!opt.skip_lock && state.lockfile[0]) {
2045 264 : if (lock_unlock(lock) == -1) {
2046 : /* LCOV_EXCL_START */
2047 : log_fatal(errno, "Failed to close the lock file '%s'. %s.\n", state.lockfile, strerror(errno));
@@ -2113,20 +2113,20 @@
2051 : }
2052 : #endif
2053 :
- 2054 267 : state_done(&state);
- 2055 267 : tommy_list_foreach(&filterlist_file, (tommy_foreach_func*)filter_free);
- 2056 267 : tommy_list_foreach(&filterlist_disk, (tommy_foreach_func*)filter_free);
+ 2054 268 : state_done(&state);
+ 2055 268 : tommy_list_foreach(&filterlist_file, (tommy_foreach_func*)filter_free);
+ 2056 268 : tommy_list_foreach(&filterlist_disk, (tommy_foreach_func*)filter_free);
2057 :
- 2058 267 : os_done();
- 2059 267 : lock_done();
+ 2058 268 : os_done();
+ 2059 268 : lock_done();
2060 :
2061 : /* abort if required */
- 2062 267 : if (ret != 0) {
+ 2062 268 : if (ret != 0) {
2063 : /* LCOV_EXCL_START */
2064 : exit(EXIT_FAILURE);
2065 : /* LCOV_EXCL_STOP */
2066 : }
- 2067 255 : if (global_interrupt) {
+ 2067 256 : if (global_interrupt) {
2068 : /* LCOV_EXCL_START */
2069 : #ifdef _WIN32
2070 : exit(STATUS_CONTROL_C_EXIT);
@@ -2143,7 +2143,7 @@
2081 : /* LCOV_EXCL_STOP */
2082 : }
2083 :
- 2084 255 : return EXIT_SUCCESS;
+ 2084 256 : return EXIT_SUCCESS;
2085 : }
2086 :
diff --git a/cov/cmdline/speed.c.func-sort-c.html b/cov/cmdline/speed.c.func-sort-c.html
index 227dbab6..4c45a6ba 100644
--- a/cov/cmdline/speed.c.func-sort-c.html
+++ b/cov/cmdline/speed.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -65,7 +65,7 @@
| diffgettimeofday |
- 1643 |
+ 1617 |
diff --git a/cov/cmdline/speed.c.func.html b/cov/cmdline/speed.c.func.html
index 90e32ecd..7299055d 100644
--- a/cov/cmdline/speed.c.func.html
+++ b/cov/cmdline/speed.c.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,7 +61,7 @@
| diffgettimeofday |
- 1643 |
+ 1617 |
| speed |
diff --git a/cov/cmdline/speed.c.gcov.html b/cov/cmdline/speed.c.gcov.html
index 2ed597f7..eb8353ed 100644
--- a/cov/cmdline/speed.c.gcov.html
+++ b/cov/cmdline/speed.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -90,14 +90,14 @@
28 : /**
29 : * Differential us of two timeval.
30 : */
- 31 1643 : static int64_t diffgettimeofday(struct timeval* start, struct timeval* stop)
+ 31 1617 : static int64_t diffgettimeofday(struct timeval* start, struct timeval* stop)
32 : {
33 : int64_t d;
34 :
- 35 1643 : d = 1000000LL * (stop->tv_sec - start->tv_sec);
- 36 1643 : d += stop->tv_usec - start->tv_usec;
+ 35 1617 : d = 1000000LL * (stop->tv_sec - start->tv_sec);
+ 36 1617 : d += stop->tv_usec - start->tv_usec;
37 :
- 38 1643 : return d;
+ 38 1617 : return d;
39 : }
40 :
41 : /**
@@ -233,10 +233,10 @@
171 4 : printf("%8s", "memset");
172 4 : fflush(stdout);
173 :
- 174 1292 : SPEED_START {
- 175 5814 : for (j = 0; j < nd; ++j)
- 176 5168 : memset(v[j], j, size);
- 177 646 : } SPEED_STOP
+ 174 1284 : SPEED_START {
+ 175 5778 : for (j = 0; j < nd; ++j)
+ 176 5136 : memset(v[j], j, size);
+ 177 642 : } SPEED_STOP
178 :
179 4 : printf("%8" PRIu64, ds / dt);
180 4 : printf("\n");
@@ -248,10 +248,10 @@
186 4 : printf("%8s", "table");
187 4 : fflush(stdout);
188 :
- 189 74 : SPEED_START {
- 190 333 : for (j = 0; j < nd; ++j)
- 191 296 : side_effect += crc32c_gen(0, v[j], size);
- 192 37 : } SPEED_STOP
+ 189 62 : SPEED_START {
+ 190 279 : for (j = 0; j < nd; ++j)
+ 191 248 : side_effect += crc32c_gen(0, v[j], size);
+ 192 31 : } SPEED_STOP
193 :
194 4 : printf("%8" PRIu64, ds / dt);
195 4 : printf("\n");
@@ -261,10 +261,10 @@
199 :
200 : #if HAVE_SSE42
201 4 : if (raid_cpu_has_crc32()) {
- 202 82 : SPEED_START {
- 203 369 : for (j = 0; j < nd; ++j)
- 204 328 : side_effect += crc32c_x86(0, v[j], size);
- 205 41 : } SPEED_STOP
+ 202 92 : SPEED_START {
+ 203 414 : for (j = 0; j < nd; ++j)
+ 204 368 : side_effect += crc32c_x86(0, v[j], size);
+ 205 46 : } SPEED_STOP
206 :
207 2 : printf("%8" PRIu64, ds / dt);
208 : }
@@ -295,26 +295,26 @@
233 4 : printf("%8" PRIu64, ds / dt);
234 4 : fflush(stdout);
235 :
- 236 36 : SPEED_START {
- 237 162 : for (j = 0; j < nd; ++j)
- 238 144 : memhash(HASH_SPOOKY2, seed, digest, v[j], size);
- 239 18 : } SPEED_STOP
+ 236 42 : SPEED_START {
+ 237 189 : for (j = 0; j < nd; ++j)
+ 238 168 : memhash(HASH_SPOOKY2, seed, digest, v[j], size);
+ 239 21 : } SPEED_STOP
240 :
241 4 : printf("%8" PRIu64, ds / dt);
242 4 : fflush(stdout);
243 :
- 244 26 : SPEED_START {
- 245 117 : for (j = 0; j < nd; ++j)
- 246 104 : memhash(HASH_METRO, seed, digest, v[j], size);
- 247 13 : } SPEED_STOP
+ 244 32 : SPEED_START {
+ 245 144 : for (j = 0; j < nd; ++j)
+ 246 128 : memhash(HASH_METRO, seed, digest, v[j], size);
+ 247 16 : } SPEED_STOP
248 :
249 4 : printf("%8" PRIu64, ds / dt);
250 4 : fflush(stdout);
251 :
- 252 32 : SPEED_START {
- 253 144 : for (j = 0; j < nd; ++j)
- 254 128 : memhash(HASH_MUSEAIR, seed, digest, v[j], size);
- 255 16 : } SPEED_STOP
+ 252 34 : SPEED_START {
+ 253 153 : for (j = 0; j < nd; ++j)
+ 254 136 : memhash(HASH_MUSEAIR, seed, digest, v[j], size);
+ 255 17 : } SPEED_STOP
256 :
257 4 : printf("%8" PRIu64, ds / dt);
258 4 : printf("\n");
@@ -350,16 +350,16 @@
288 :
289 4 : printf("%8s", "");
290 :
- 291 168 : SPEED_START {
- 292 84 : raid_gen1_int32(nd, size, v);
- 293 84 : } SPEED_STOP
+ 291 156 : SPEED_START {
+ 292 78 : raid_gen1_int32(nd, size, v);
+ 293 78 : } SPEED_STOP
294 :
295 4 : printf("%8" PRIu64, ds / dt);
296 4 : fflush(stdout);
297 :
- 298 334 : SPEED_START {
- 299 167 : raid_gen1_int64(nd, size, v);
- 300 167 : } SPEED_STOP
+ 298 312 : SPEED_START {
+ 299 156 : raid_gen1_int64(nd, size, v);
+ 300 156 : } SPEED_STOP
301 :
302 4 : printf("%8" PRIu64, ds / dt);
303 4 : fflush(stdout);
@@ -367,9 +367,9 @@
305 : #ifdef CONFIG_X86
306 : #ifdef CONFIG_SSE2
307 4 : if (raid_cpu_has_sse2()) {
- 308 100 : SPEED_START {
- 309 50 : raid_gen1_sse2(nd, size, v);
- 310 50 : } SPEED_STOP
+ 308 96 : SPEED_START {
+ 309 48 : raid_gen1_sse2(nd, size, v);
+ 310 48 : } SPEED_STOP
311 :
312 4 : printf("%8" PRIu64, ds / dt);
313 4 : fflush(stdout);
@@ -385,9 +385,9 @@
323 : #endif
324 : #ifdef CONFIG_AVX2
325 4 : if (raid_cpu_has_avx2()) {
- 326 24 : SPEED_START {
- 327 12 : raid_gen1_avx2(nd, size, v);
- 328 12 : } SPEED_STOP
+ 326 22 : SPEED_START {
+ 327 11 : raid_gen1_avx2(nd, size, v);
+ 328 11 : } SPEED_STOP
329 :
330 1 : printf("%8" PRIu64, ds / dt);
331 1 : fflush(stdout);
@@ -403,16 +403,16 @@
341 :
342 4 : printf("%8s", "");
343 :
- 344 80 : SPEED_START {
- 345 40 : raid_gen2_int32(nd, size, v);
- 346 40 : } SPEED_STOP
+ 344 84 : SPEED_START {
+ 345 42 : raid_gen2_int32(nd, size, v);
+ 346 42 : } SPEED_STOP
347 :
348 4 : printf("%8" PRIu64, ds / dt);
349 4 : fflush(stdout);
350 :
- 351 164 : SPEED_START {
- 352 82 : raid_gen2_int64(nd, size, v);
- 353 82 : } SPEED_STOP
+ 351 156 : SPEED_START {
+ 352 78 : raid_gen2_int64(nd, size, v);
+ 353 78 : } SPEED_STOP
354 :
355 4 : printf("%8" PRIu64, ds / dt);
356 4 : fflush(stdout);
@@ -444,9 +444,9 @@
382 : #endif
383 : #ifdef CONFIG_AVX2
384 4 : if (raid_cpu_has_avx2()) {
- 385 6 : SPEED_START {
- 386 3 : raid_gen2_avx2(nd, size, v);
- 387 3 : } SPEED_STOP
+ 385 4 : SPEED_START {
+ 386 2 : raid_gen2_avx2(nd, size, v);
+ 387 2 : } SPEED_STOP
388 :
389 1 : printf("%8" PRIu64, ds / dt);
390 1 : fflush(stdout);
@@ -469,9 +469,9 @@
407 4 : printf("%8" PRIu64, ds / dt);
408 4 : fflush(stdout);
409 :
- 410 98 : SPEED_START {
- 411 49 : raid_genz_int64(nd, size, v);
- 412 49 : } SPEED_STOP
+ 410 102 : SPEED_START {
+ 411 51 : raid_genz_int64(nd, size, v);
+ 412 51 : } SPEED_STOP
413 :
414 4 : printf("%8" PRIu64, ds / dt);
415 4 : fflush(stdout);
@@ -479,9 +479,9 @@
417 : #ifdef CONFIG_X86
418 : #ifdef CONFIG_SSE2
419 4 : if (raid_cpu_has_sse2()) {
- 420 24 : SPEED_START {
- 421 12 : raid_genz_sse2(nd, size, v);
- 422 12 : } SPEED_STOP
+ 420 20 : SPEED_START {
+ 421 10 : raid_genz_sse2(nd, size, v);
+ 422 10 : } SPEED_STOP
423 :
424 4 : printf("%8" PRIu64, ds / dt);
425 4 : fflush(stdout);
@@ -523,9 +523,9 @@
461 4 : printf("%8s", raid_gen3_tag());
462 4 : fflush(stdout);
463 :
- 464 20 : SPEED_START {
- 465 10 : raid_gen3_int8(nd, size, v);
- 466 10 : } SPEED_STOP
+ 464 18 : SPEED_START {
+ 465 9 : raid_gen3_int8(nd, size, v);
+ 466 9 : } SPEED_STOP
467 :
468 4 : printf("%8" PRIu64, ds / dt);
469 4 : fflush(stdout);
@@ -546,9 +546,9 @@
484 : #ifdef CONFIG_X86
485 : #ifdef CONFIG_SSSE3
486 4 : if (raid_cpu_has_ssse3()) {
- 487 18 : SPEED_START {
- 488 9 : raid_gen3_ssse3(nd, size, v);
- 489 9 : } SPEED_STOP
+ 487 14 : SPEED_START {
+ 488 7 : raid_gen3_ssse3(nd, size, v);
+ 489 7 : } SPEED_STOP
490 :
491 3 : printf("%8" PRIu64, ds / dt);
492 3 : fflush(stdout);
@@ -716,9 +716,9 @@
654 4 : printf("%8s", raid_gen6_tag());
655 4 : fflush(stdout);
656 :
- 657 16 : SPEED_START {
- 658 8 : raid_gen6_int8(nd, size, v);
- 659 8 : } SPEED_STOP
+ 657 14 : SPEED_START {
+ 658 7 : raid_gen6_int8(nd, size, v);
+ 659 7 : } SPEED_STOP
660 :
661 4 : printf("%8" PRIu64, ds / dt);
662 4 : fflush(stdout);
@@ -749,9 +749,9 @@
687 3 : fflush(stdout);
688 :
689 : #ifdef CONFIG_X86_64
- 690 8 : SPEED_START {
- 691 4 : raid_gen6_ssse3ext(nd, size, v);
- 692 4 : } SPEED_STOP
+ 690 6 : SPEED_START {
+ 691 3 : raid_gen6_ssse3ext(nd, size, v);
+ 692 3 : } SPEED_STOP
693 :
694 3 : printf("%8" PRIu64, ds / dt);
695 3 : fflush(stdout);
diff --git a/cov/cmdline/spooky2.c.func-sort-c.html b/cov/cmdline/spooky2.c.func-sort-c.html
index 491565a2..759c15c5 100644
--- a/cov/cmdline/spooky2.c.func-sort-c.html
+++ b/cov/cmdline/spooky2.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,7 +61,7 @@
| SpookyHash128 |
- 3888115 |
+ 3887997 |
diff --git a/cov/cmdline/spooky2.c.func.html b/cov/cmdline/spooky2.c.func.html
index 691ce22a..0dc90f5f 100644
--- a/cov/cmdline/spooky2.c.func.html
+++ b/cov/cmdline/spooky2.c.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,7 +61,7 @@
| SpookyHash128 |
- 3888115 |
+ 3887997 |
diff --git a/cov/cmdline/spooky2.c.gcov.html b/cov/cmdline/spooky2.c.gcov.html
index 73f1c05d..f3c85dd0 100644
--- a/cov/cmdline/spooky2.c.gcov.html
+++ b/cov/cmdline/spooky2.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -170,7 +170,7 @@
108 : //
109 : #define sc_const 0xdeadbeefdeadbeefLL
110 :
- 111 3888115 : void SpookyHash128(const void* data, size_t size, const uint8_t* seed, uint8_t* digest)
+ 111 3887997 : void SpookyHash128(const void* data, size_t size, const uint8_t* seed, uint8_t* digest)
112 : {
113 : uint64_t h0, h1, h2, h3, h4, h5, h6, h7, h8, h9, h10, h11;
114 : uint64_t buf[sc_numVars];
@@ -182,45 +182,45 @@
120 : unsigned i;
121 : #endif
122 :
- 123 3888115 : h9 = util_read64(seed + 0);
- 124 3888115 : h10 = util_read64(seed + 8);
+ 123 3887997 : h9 = util_read64(seed + 0);
+ 124 3887997 : h10 = util_read64(seed + 8);
125 :
- 126 3888115 : h0 = h3 = h6 = h9;
- 127 3888115 : h1 = h4 = h7 = h10;
- 128 3888115 : h2 = h5 = h8 = h11 = sc_const;
+ 126 3887997 : h0 = h3 = h6 = h9;
+ 127 3887997 : h1 = h4 = h7 = h10;
+ 128 3887997 : h2 = h5 = h8 = h11 = sc_const;
129 :
- 130 3888115 : nblocks = size / sc_blockSize;
- 131 3888115 : blocks = data;
- 132 3888115 : end = blocks + nblocks * sc_numVars;
+ 130 3887997 : nblocks = size / sc_blockSize;
+ 131 3887997 : blocks = data;
+ 132 3887997 : end = blocks + nblocks * sc_numVars;
133 :
134 : /* body */
- 135 34766493 : while (blocks < end) {
+ 135 34830303 : while (blocks < end) {
136 : #if WORDS_BIGENDIAN
137 : for (i = 0; i < sc_numVars; ++i)
138 : buf[i] = util_swap64(blocks[i]);
139 : Mix(buf, h0, h1, h2, h3, h4, h5, h6, h7, h8, h9, h10, h11);
140 : #else
- 141 30878378 : Mix(blocks, h0, h1, h2, h3, h4, h5, h6, h7, h8, h9, h10, h11);
+ 141 30942306 : Mix(blocks, h0, h1, h2, h3, h4, h5, h6, h7, h8, h9, h10, h11);
142 : #endif
- 143 30878378 : blocks += sc_numVars;
+ 143 30942306 : blocks += sc_numVars;
144 : }
145 :
146 : /* tail */
- 147 3888115 : size_remainder = (size - ((const uint8_t*)end - (const uint8_t*)data));
- 148 3888115 : memcpy(buf, end, size_remainder);
- 149 3888115 : memset(((uint8_t*)buf) + size_remainder, 0, sc_blockSize - size_remainder);
- 150 3888115 : ((uint8_t*)buf)[sc_blockSize - 1] = size_remainder;
+ 147 3887997 : size_remainder = (size - ((const uint8_t*)end - (const uint8_t*)data));
+ 148 3887997 : memcpy(buf, end, size_remainder);
+ 149 3887997 : memset(((uint8_t*)buf) + size_remainder, 0, sc_blockSize - size_remainder);
+ 150 3887997 : ((uint8_t*)buf)[sc_blockSize - 1] = size_remainder;
151 :
152 : /* finalization */
153 : #if WORDS_BIGENDIAN
154 : for (i = 0; i < sc_numVars; ++i)
155 : buf[i] = util_swap64(buf[i]);
156 : #endif
- 157 3888115 : End(buf, h0, h1, h2, h3, h4, h5, h6, h7, h8, h9, h10, h11);
+ 157 3887997 : End(buf, h0, h1, h2, h3, h4, h5, h6, h7, h8, h9, h10, h11);
158 :
- 159 3888115 : util_write64(digest + 0, h0);
- 160 3888115 : util_write64(digest + 8, h1);
- 161 3888115 : }
+ 159 3887997 : util_write64(digest + 0, h0);
+ 160 3887997 : util_write64(digest + 8, h1);
+ 161 3887997 : }
162 :
diff --git a/cov/cmdline/state.c.func-sort-c.html b/cov/cmdline/state.c.func-sort-c.html
index a13141ff..b282e74b 100644
--- a/cov/cmdline/state.c.func-sort-c.html
+++ b/cov/cmdline/state.c.func-sort-c.html
@@ -31,13 +31,13 @@
|
-
+
-
+
-
+
|
@@ -117,23 +117,23 @@
| state_rename_content |
- 157 |
+ 156 |
| state_verify_content |
- 157 |
+ 156 |
| state_write |
- 157 |
+ 156 |
| state_write_content |
- 157 |
+ 156 |
| state_write_thread |
- 157 |
+ 156 |
| state_refresh |
@@ -157,7 +157,7 @@
| state_done |
- 268 |
+ 269 |
| state_map |
@@ -169,35 +169,35 @@
| lev_raid_name |
- 277 |
-
-
- | state_config_check |
- 277 |
-
-
- | state_config |
278 |
- | state_init |
+ state_config_check |
+ 278 |
+
+
+ | state_config |
279 |
+
+ | state_init |
+ 280 |
+
| validate_smartctl |
384 |
| state_progress_latest |
- 493 |
+ 481 |
| state_fscheck |
- 521 |
+ 520 |
| state_verify_thread |
- 1054 |
+ 1047 |
| fs_position_clear_deleted |
@@ -205,51 +205,51 @@
| lev_config_scan |
- 6985 |
+ 7028 |
| find_disk_by_name |
- 7508 |
+ 7496 |
| state_usage_raid |
- 140496 |
+ 140445 |
| state_usage_sched |
- 151013 |
+ 150950 |
| lev_config_name |
- 273686 |
+ 273680 |
| state_usage_hash |
- 753854 |
+ 753469 |
| state_usage_parity |
- 781079 |
+ 780707 |
| fs_position_is_required |
- 800411 |
+ 793414 |
| state_usage_file |
- 914732 |
+ 914354 |
| state_usage_disk |
- 919419 |
+ 919041 |
| state_usage_misc |
- 1071293 |
+ 1070853 |
| state_progress |
- 1075966 |
+ 1075903 |
| fs_info_is_required |
@@ -257,11 +257,11 @@
| fs_is_block_unsynced |
- 2406326 |
+ 2399329 |
| fs_is_block_deleted |
- 4795496 |
+ 4753514 |
diff --git a/cov/cmdline/state.c.func.html b/cov/cmdline/state.c.func.html
index bb510bac..14e0e84c 100644
--- a/cov/cmdline/state.c.func.html
+++ b/cov/cmdline/state.c.func.html
@@ -31,13 +31,13 @@
|
-
+
-
+
-
+
|
@@ -65,7 +65,7 @@
| find_disk_by_name |
- 7508 |
+ 7496 |
| find_disk_by_uuid |
@@ -77,11 +77,11 @@
| fs_is_block_deleted |
- 4795496 |
+ 4753514 |
| fs_is_block_unsynced |
- 2406326 |
+ 2399329 |
| fs_position_clear_deleted |
@@ -89,7 +89,7 @@
| fs_position_is_required |
- 800411 |
+ 793414 |
| generate_configuration |
@@ -97,11 +97,11 @@
| lev_config_name |
- 273686 |
+ 273680 |
| lev_config_scan |
- 6985 |
+ 7028 |
| lev_name |
@@ -109,15 +109,15 @@
| lev_raid_name |
- 277 |
-
-
- | state_config |
278 |
+
+ | state_config |
+ 279 |
+
| state_config_check |
- 277 |
+ 278 |
| state_content_check |
@@ -125,7 +125,7 @@
| state_done |
- 268 |
+ 269 |
| state_filter |
@@ -137,11 +137,11 @@
| state_fscheck |
- 521 |
+ 520 |
| state_init |
- 279 |
+ 280 |
| state_load_ignore_file |
@@ -153,7 +153,7 @@
| state_progress |
- 1075966 |
+ 1075903 |
| state_progress_begin |
@@ -169,7 +169,7 @@
| state_progress_latest |
- 493 |
+ 481 |
| state_progress_restart |
@@ -193,7 +193,7 @@
| state_rename_content |
- 157 |
+ 156 |
| state_skip |
@@ -205,23 +205,23 @@
| state_usage_disk |
- 919419 |
+ 919041 |
| state_usage_file |
- 914732 |
+ 914354 |
| state_usage_hash |
- 753854 |
+ 753469 |
| state_usage_misc |
- 1071293 |
+ 1070853 |
| state_usage_parity |
- 781079 |
+ 780707 |
| state_usage_print |
@@ -229,11 +229,11 @@
| state_usage_raid |
- 140496 |
+ 140445 |
| state_usage_sched |
- 151013 |
+ 150950 |
| state_usage_waste |
@@ -241,23 +241,23 @@
| state_verify_content |
- 157 |
+ 156 |
| state_verify_thread |
- 1054 |
+ 1047 |
| state_write |
- 157 |
+ 156 |
| state_write_content |
- 157 |
+ 156 |
| state_write_thread |
- 157 |
+ 156 |
| validate_smartctl |
diff --git a/cov/cmdline/state.c.gcov.html b/cov/cmdline/state.c.gcov.html
index f6d21b9d..488bfc2f 100644
--- a/cov/cmdline/state.c.gcov.html
+++ b/cov/cmdline/state.c.gcov.html
@@ -31,13 +31,13 @@
|
-
+
-
+
-
+
|
@@ -122,67 +122,67 @@
60 0 : return "invalid";
61 : }
62 :
- 63 273686 : const char* lev_config_name(unsigned l)
+ 63 273680 : const char* lev_config_name(unsigned l)
64 : {
- 65 273686 : switch (l) {
- 66 94064 : case 0 : return "parity";
- 67 76604 : case 1 : return "2-parity";
- 68 25794 : case 2 : return "3-parity";
- 69 25769 : case 3 : return "4-parity";
- 70 25744 : case 4 : return "5-parity";
- 71 25711 : case 5 : return "6-parity";
+ 65 273680 : switch (l) {
+ 66 94081 : case 0 : return "parity";
+ 67 76601 : case 1 : return "2-parity";
+ 68 25789 : case 2 : return "3-parity";
+ 69 25764 : case 3 : return "4-parity";
+ 70 25739 : case 4 : return "5-parity";
+ 71 25706 : case 5 : return "6-parity";
72 : }
73 :
74 0 : return "invalid";
75 : }
76 :
- 77 6985 : static int lev_config_scan(const char* s, unsigned* level, unsigned* mode)
+ 77 7028 : static int lev_config_scan(const char* s, unsigned* level, unsigned* mode)
78 : {
- 79 6985 : if (strcmp(s, "parity") == 0 || strcmp(s, "1-parity") == 0) {
- 80 661 : *level = 0;
- 81 661 : return 0;
+ 79 7028 : if (strcmp(s, "parity") == 0 || strcmp(s, "1-parity") == 0) {
+ 80 662 : *level = 0;
+ 81 662 : return 0;
82 : }
83 :
- 84 6324 : if (strcmp(s, "q-parity") == 0 || strcmp(s, "2-parity") == 0) {
- 85 235 : *level = 1;
- 86 235 : return 0;
+ 84 6366 : if (strcmp(s, "q-parity") == 0 || strcmp(s, "2-parity") == 0) {
+ 85 236 : *level = 1;
+ 86 236 : return 0;
87 : }
88 :
- 89 6089 : if (strcmp(s, "r-parity") == 0 || strcmp(s, "3-parity") == 0) {
+ 89 6130 : if (strcmp(s, "r-parity") == 0 || strcmp(s, "3-parity") == 0) {
90 210 : *level = 2;
91 210 : return 0;
92 : }
93 :
- 94 5879 : if (strcmp(s, "4-parity") == 0) {
+ 94 5920 : if (strcmp(s, "4-parity") == 0) {
95 207 : *level = 3;
96 207 : return 0;
97 : }
98 :
- 99 5672 : if (strcmp(s, "5-parity") == 0) {
+ 99 5713 : if (strcmp(s, "5-parity") == 0) {
100 204 : *level = 4;
101 204 : return 0;
102 : }
103 :
- 104 5468 : if (strcmp(s, "6-parity") == 0) {
+ 104 5509 : if (strcmp(s, "6-parity") == 0) {
105 200 : *level = 5;
106 200 : return 0;
107 : }
108 :
- 109 5268 : if (strcmp(s, "z-parity") == 0) {
+ 109 5309 : if (strcmp(s, "z-parity") == 0) {
110 0 : *level = 2;
111 0 : if (mode)
112 0 : *mode = RAID_MODE_VANDERMONDE;
113 0 : return 0;
114 : }
115 :
- 116 5268 : return -1;
+ 116 5309 : return -1;
117 : }
118 :
- 119 277 : const char* lev_raid_name(unsigned mode, unsigned n)
+ 119 278 : const char* lev_raid_name(unsigned mode, unsigned n)
120 : {
- 121 277 : switch (n) {
+ 121 278 : switch (n) {
122 43 : case 1 : return "par1";
- 123 25 : case 2 : return "par2";
+ 123 26 : case 2 : return "par2";
124 3 : case 3 : if (mode == RAID_MODE_CAUCHY)
125 3 : return "par3";
126 : else
@@ -195,105 +195,105 @@
133 0 : return 0;
134 : }
135 :
- 136 279 : void state_init(struct snapraid_state* state)
+ 136 280 : void state_init(struct snapraid_state* state)
137 : {
138 : unsigned l, s, i;
139 :
- 140 279 : memset(&state->opt, 0, sizeof(state->opt));
- 141 279 : state->filter_hidden = 0;
- 142 279 : state->autosave = 0;
- 143 279 : state->need_write = 0;
- 144 279 : state->written = 0;
- 145 279 : state->checked_read = 0;
- 146 279 : state->block_size = 256 * KIBI; /* default 256 KiB */
- 147 279 : state->raid_mode = RAID_MODE_CAUCHY;
- 148 279 : state->file_mode = ADVISE_DEFAULT;
- 149 1953 : for (l = 0; l < LEV_MAX; ++l) {
- 150 1674 : state->parity[l].split_mac = 0;
- 151 15066 : for (s = 0; s < SPLIT_MAX; ++s) {
- 152 13392 : state->parity[l].split_map[s].path[0] = 0;
- 153 13392 : state->parity[l].split_map[s].uuid[0] = 0;
- 154 13392 : state->parity[l].split_map[s].fstype[0] = 0;
- 155 13392 : state->parity[l].split_map[s].fslabel[0] = 0;
- 156 13392 : state->parity[l].split_map[s].size = PARITY_SIZE_INVALID;
- 157 13392 : state->parity[l].split_map[s].device = 0;
+ 140 280 : memset(&state->opt, 0, sizeof(state->opt));
+ 141 280 : state->filter_hidden = 0;
+ 142 280 : state->autosave = 0;
+ 143 280 : state->need_write = 0;
+ 144 280 : state->written = 0;
+ 145 280 : state->checked_read = 0;
+ 146 280 : state->block_size = 256 * KIBI; /* default 256 KiB */
+ 147 280 : state->raid_mode = RAID_MODE_CAUCHY;
+ 148 280 : state->file_mode = ADVISE_DEFAULT;
+ 149 1960 : for (l = 0; l < LEV_MAX; ++l) {
+ 150 1680 : state->parity[l].split_mac = 0;
+ 151 15120 : for (s = 0; s < SPLIT_MAX; ++s) {
+ 152 13440 : state->parity[l].split_map[s].path[0] = 0;
+ 153 13440 : state->parity[l].split_map[s].uuid[0] = 0;
+ 154 13440 : state->parity[l].split_map[s].fstype[0] = 0;
+ 155 13440 : state->parity[l].split_map[s].fslabel[0] = 0;
+ 156 13440 : state->parity[l].split_map[s].size = PARITY_SIZE_INVALID;
+ 157 13440 : state->parity[l].split_map[s].device = 0;
158 : }
- 159 1674 : state->parity[l].smartctl[0] = 0;
- 160 8370 : for (i = 0; i < SMART_IGNORE_MAX; ++i)
- 161 6696 : state->parity[l].smartignore[i] = 0;
- 162 1674 : state->parity[l].total_blocks = 0;
- 163 1674 : state->parity[l].free_blocks = 0;
- 164 1674 : state->parity[l].skip_access = 0;
- 165 1674 : state->parity[l].tick = 0;
- 166 1674 : state->parity[l].cached_blocks = 0;
- 167 1674 : state->parity[l].is_excluded_by_filter = 0;
+ 159 1680 : state->parity[l].smartctl[0] = 0;
+ 160 8400 : for (i = 0; i < SMART_IGNORE_MAX; ++i)
+ 161 6720 : state->parity[l].smartignore[i] = 0;
+ 162 1680 : state->parity[l].total_blocks = 0;
+ 163 1680 : state->parity[l].free_blocks = 0;
+ 164 1680 : state->parity[l].skip_access = 0;
+ 165 1680 : state->parity[l].tick = 0;
+ 166 1680 : state->parity[l].cached_blocks = 0;
+ 167 1680 : state->parity[l].is_excluded_by_filter = 0;
168 : }
- 169 279 : state->tick_io = 0;
- 170 279 : state->tick_misc = 0;
- 171 279 : state->tick_sched = 0;
- 172 279 : state->tick_raid = 0;
- 173 279 : state->tick_hash = 0;
- 174 279 : state->tick_last = tick();
- 175 279 : state->share[0] = 0;
- 176 279 : state->pool[0] = 0;
- 177 279 : state->pool_device = 0;
- 178 279 : state->lockfile[0] = 0;
- 179 279 : state->level = 1; /* default is the lowest protection */
- 180 279 : state->clear_past_hash = 0;
- 181 279 : state->no_conf = 0;
- 182 1395 : for (i = 0; i < SMART_IGNORE_MAX; ++i)
- 183 1116 : state->smartignore[i] = 0;
- 184 279 : state->rehash_blocks = 0;
- 185 279 : state->bad_blocks = 0;
- 186 279 : state->unsynced_blocks = 0;
- 187 279 : state->unscrubbed_blocks = 0;
- 188 279 : state->thermal_stop_gathering = 0;
- 189 279 : state->thermal_ambient_temperature = 0;
- 190 279 : state->thermal_highest_temperature = 0;
- 191 279 : state->thermal_first = 0;
- 192 279 : state->thermal_latest = 0;
- 193 279 : state->thermal_temperature_limit = 0;
- 194 279 : state->thermal_cooldown_time = 0;
+ 169 280 : state->tick_io = 0;
+ 170 280 : state->tick_misc = 0;
+ 171 280 : state->tick_sched = 0;
+ 172 280 : state->tick_raid = 0;
+ 173 280 : state->tick_hash = 0;
+ 174 280 : state->tick_last = tick();
+ 175 280 : state->share[0] = 0;
+ 176 280 : state->pool[0] = 0;
+ 177 280 : state->pool_device = 0;
+ 178 280 : state->lockfile[0] = 0;
+ 179 280 : state->level = 1; /* default is the lowest protection */
+ 180 280 : state->clear_past_hash = 0;
+ 181 280 : state->no_conf = 0;
+ 182 1400 : for (i = 0; i < SMART_IGNORE_MAX; ++i)
+ 183 1120 : state->smartignore[i] = 0;
+ 184 280 : state->rehash_blocks = 0;
+ 185 280 : state->bad_blocks = 0;
+ 186 280 : state->unsynced_blocks = 0;
+ 187 280 : state->unscrubbed_blocks = 0;
+ 188 280 : state->thermal_stop_gathering = 0;
+ 189 280 : state->thermal_ambient_temperature = 0;
+ 190 280 : state->thermal_highest_temperature = 0;
+ 191 280 : state->thermal_first = 0;
+ 192 280 : state->thermal_latest = 0;
+ 193 280 : state->thermal_temperature_limit = 0;
+ 194 280 : state->thermal_cooldown_time = 0;
195 :
- 196 279 : tommy_list_init(&state->disklist);
- 197 279 : tommy_list_init(&state->maplist);
- 198 279 : tommy_list_init(&state->contentlist);
- 199 279 : tommy_list_init(&state->filterlist);
- 200 279 : tommy_list_init(&state->importlist);
- 201 279 : tommy_list_init(&state->thermallist);
- 202 279 : tommy_hashdyn_init(&state->importset);
- 203 279 : tommy_hashdyn_init(&state->previmportset);
- 204 279 : tommy_hashdyn_init(&state->searchset);
- 205 279 : tommy_arrayblkof_init(&state->infoarr, sizeof(snapraid_info));
- 206 279 : tommy_list_init(&state->bucketlist);
- 207 279 : }
+ 196 280 : tommy_list_init(&state->disklist);
+ 197 280 : tommy_list_init(&state->maplist);
+ 198 280 : tommy_list_init(&state->contentlist);
+ 199 280 : tommy_list_init(&state->filterlist);
+ 200 280 : tommy_list_init(&state->importlist);
+ 201 280 : tommy_list_init(&state->thermallist);
+ 202 280 : tommy_hashdyn_init(&state->importset);
+ 203 280 : tommy_hashdyn_init(&state->previmportset);
+ 204 280 : tommy_hashdyn_init(&state->searchset);
+ 205 280 : tommy_arrayblkof_init(&state->infoarr, sizeof(snapraid_info));
+ 206 280 : tommy_list_init(&state->bucketlist);
+ 207 280 : }
208 :
- 209 268 : void state_done(struct snapraid_state* state)
+ 209 269 : void state_done(struct snapraid_state* state)
210 : {
- 211 268 : tommy_list_foreach(&state->disklist, (tommy_foreach_func*)disk_free);
- 212 268 : tommy_list_foreach(&state->maplist, (tommy_foreach_func*)map_free);
- 213 268 : tommy_list_foreach(&state->contentlist, (tommy_foreach_func*)content_free);
- 214 268 : tommy_list_foreach(&state->filterlist, (tommy_foreach_func*)filter_free);
- 215 268 : tommy_list_foreach(&state->importlist, (tommy_foreach_func*)import_file_free);
- 216 268 : tommy_list_foreach(&state->thermallist, (tommy_foreach_func*)thermal_free);
- 217 268 : tommy_hashdyn_foreach(&state->searchset, (tommy_foreach_func*)search_file_free);
- 218 268 : tommy_hashdyn_done(&state->importset);
- 219 268 : tommy_hashdyn_done(&state->previmportset);
- 220 268 : tommy_hashdyn_done(&state->searchset);
- 221 268 : tommy_arrayblkof_done(&state->infoarr);
- 222 268 : tommy_list_foreach(&state->bucketlist, (tommy_foreach_func*)bucket_free);
- 223 268 : }
+ 211 269 : tommy_list_foreach(&state->disklist, (tommy_foreach_func*)disk_free);
+ 212 269 : tommy_list_foreach(&state->maplist, (tommy_foreach_func*)map_free);
+ 213 269 : tommy_list_foreach(&state->contentlist, (tommy_foreach_func*)content_free);
+ 214 269 : tommy_list_foreach(&state->filterlist, (tommy_foreach_func*)filter_free);
+ 215 269 : tommy_list_foreach(&state->importlist, (tommy_foreach_func*)import_file_free);
+ 216 269 : tommy_list_foreach(&state->thermallist, (tommy_foreach_func*)thermal_free);
+ 217 269 : tommy_hashdyn_foreach(&state->searchset, (tommy_foreach_func*)search_file_free);
+ 218 269 : tommy_hashdyn_done(&state->importset);
+ 219 269 : tommy_hashdyn_done(&state->previmportset);
+ 220 269 : tommy_hashdyn_done(&state->searchset);
+ 221 269 : tommy_arrayblkof_done(&state->infoarr);
+ 222 269 : tommy_list_foreach(&state->bucketlist, (tommy_foreach_func*)bucket_free);
+ 223 269 : }
224 :
225 : /**
226 : * Check the configuration.
227 : */
- 228 277 : static void state_config_check(struct snapraid_state* state, const char* path, tommy_list* filterlist_disk)
+ 228 278 : static void state_config_check(struct snapraid_state* state, const char* path, tommy_list* filterlist_disk)
229 : {
230 : tommy_node* i;
231 : unsigned l, s;
232 :
233 : /* check for parity level */
- 234 277 : if (state->raid_mode == RAID_MODE_VANDERMONDE) {
+ 234 278 : if (state->raid_mode == RAID_MODE_VANDERMONDE) {
235 0 : if (state->level > 3) {
236 : /* LCOV_EXCL_START */
237 : log_fatal(EUSER, "Using z-parity limits you to a maximum of 3 parities.\n");
@@ -311,7 +311,7 @@
249 : }
250 : }
251 :
- 252 277 : if (tommy_list_empty(&state->contentlist)) {
+ 252 278 : if (tommy_list_empty(&state->contentlist)) {
253 : /* LCOV_EXCL_START */
254 : log_fatal(EUSER, "Missing 'content' specification in '%s'\n", path);
255 : exit(EXIT_FAILURE);
@@ -319,12 +319,12 @@
257 : }
258 :
259 : /* check for equal paths */
- 260 1882 : for (i = state->contentlist; i != 0; i = i->next) {
- 261 1605 : struct snapraid_content* content = i->data;
+ 260 1887 : for (i = state->contentlist; i != 0; i = i->next) {
+ 261 1609 : struct snapraid_content* content = i->data;
262 :
- 263 10415 : for (l = 0; l < state->level; ++l) {
- 264 44050 : for (s = 0; s < state->parity[l].split_mac; ++s) {
- 265 35240 : if (pathcmp(state->parity[l].split_map[s].path, content->content) == 0) {
+ 263 10427 : for (l = 0; l < state->level; ++l) {
+ 264 44066 : for (s = 0; s < state->parity[l].split_mac; ++s) {
+ 265 35248 : if (pathcmp(state->parity[l].split_map[s].path, content->content) == 0) {
266 : /* LCOV_EXCL_START */
267 : log_fatal(EUSER, "Same path used for '%s' and 'content' as '%s'\n", lev_config_name(l), content->content);
268 : exit(EXIT_FAILURE);
@@ -335,13 +335,13 @@
273 : }
274 :
275 : /* check device of data disks */
- 276 277 : if (!state->opt.skip_device && !state->opt.skip_disk_access) {
- 277 0 : for (i = state->disklist; i != 0; i = i->next) {
+ 276 278 : if (!state->opt.skip_device && !state->opt.skip_disk_access) {
+ 277 11 : for (i = state->disklist; i != 0; i = i->next) {
278 : tommy_node* j;
- 279 0 : struct snapraid_disk* disk = i->data;
+ 279 10 : struct snapraid_disk* disk = i->data;
280 :
281 : /* skip data disks that are not accessible */
- 282 0 : if (disk->skip_access)
+ 282 10 : if (disk->skip_access)
283 0 : continue;
284 :
285 : #ifdef _WIN32
@@ -356,9 +356,9 @@
294 : }
295 : #endif
296 :
- 297 0 : for (j = i->next; j != 0; j = j->next) {
- 298 0 : struct snapraid_disk* other = j->data;
- 299 0 : if (disk->device == other->device) {
+ 297 55 : for (j = i->next; j != 0; j = j->next) {
+ 298 45 : struct snapraid_disk* other = j->data;
+ 299 45 : if (disk->device == other->device) {
300 0 : if (state->opt.force_device) {
301 : /* note that we just ignore the issue */
302 : /* and we DON'T mark the disk to be skipped */
@@ -384,13 +384,13 @@
322 : }
323 :
324 : /* skip data disks that are not accessible */
- 325 0 : if (disk->skip_access)
+ 325 10 : if (disk->skip_access)
326 0 : continue;
327 :
- 328 0 : if (!state->opt.skip_parity_access) {
- 329 0 : for (l = 0; l < state->level; ++l) {
- 330 0 : for (s = 0; s < state->parity[l].split_mac; ++s) {
- 331 0 : if (disk->device == state->parity[l].split_map[s].device) {
+ 328 10 : if (!state->opt.skip_parity_access) {
+ 329 30 : for (l = 0; l < state->level; ++l) {
+ 330 40 : for (s = 0; s < state->parity[l].split_mac; ++s) {
+ 331 20 : if (disk->device == state->parity[l].split_map[s].device) {
332 0 : if (state->opt.force_device) {
333 : /* note that we just ignore the issue */
334 : /* and we DON'T mark the disk to be skipped */
@@ -413,7 +413,7 @@
351 : }
352 : }
353 :
- 354 0 : if (state->pool[0] != 0 && disk->device == state->pool_device) {
+ 354 10 : if (state->pool[0] != 0 && disk->device == state->pool_device) {
355 : /* LCOV_EXCL_START */
356 : log_fatal(ESOFT, "Disk '%s' and pool '%s' are on the same device.\n", disk->dir, state->pool);
357 : #ifdef _WIN32
@@ -428,13 +428,13 @@
366 : }
367 :
368 : /* check device of parity disks */
- 369 277 : if (!state->opt.skip_device && !state->opt.skip_parity_access) {
- 370 0 : for (l = 0; l < state->level; ++l) {
- 371 0 : for (s = 0; s < state->parity[l].split_mac; ++s) {
+ 369 278 : if (!state->opt.skip_device && !state->opt.skip_parity_access) {
+ 370 3 : for (l = 0; l < state->level; ++l) {
+ 371 4 : for (s = 0; s < state->parity[l].split_mac; ++s) {
372 : unsigned j, t;
373 :
374 : /* skip parity disks that are not accessible */
- 375 0 : if (state->parity[l].skip_access)
+ 375 2 : if (state->parity[l].skip_access)
376 0 : continue;
377 :
378 : #ifdef _WIN32
@@ -449,9 +449,9 @@
387 : }
388 : #endif
389 :
- 390 0 : for (j = l + 1; j < state->level; ++j) {
- 391 0 : for (t = 0; t < state->parity[j].split_mac; ++t) {
- 392 0 : if (state->parity[l].split_map[s].device == state->parity[j].split_map[t].device) {
+ 390 3 : for (j = l + 1; j < state->level; ++j) {
+ 391 2 : for (t = 0; t < state->parity[j].split_mac; ++t) {
+ 392 1 : if (state->parity[l].split_map[s].device == state->parity[j].split_map[t].device) {
393 0 : if (state->opt.force_device) {
394 : /* note that we just ignore the issue */
395 : /* and we DON'T mark the disk to be skipped */
@@ -477,7 +477,7 @@
415 : }
416 : }
417 :
- 418 0 : if (state->pool[0] != 0 && state->pool_device == state->parity[l].split_map[s].device) {
+ 418 2 : if (state->pool[0] != 0 && state->pool_device == state->parity[l].split_map[s].device) {
419 : /* LCOV_EXCL_START */
420 : log_fatal(ESOFT, "Pool '%s' and parity '%s' are on the same device.\n", state->pool, state->parity[l].split_map[s].path);
421 : #ifdef _WIN32
@@ -508,31 +508,31 @@
446 : #endif
447 :
448 : /* count the content files */
- 449 277 : if (!state->opt.skip_device && !state->opt.skip_content_access) {
+ 449 278 : if (!state->opt.skip_device && !state->opt.skip_content_access) {
450 : unsigned content_count;
451 :
- 452 0 : content_count = 0;
- 453 0 : for (i = state->contentlist; i != 0; i = i->next) {
+ 452 1 : content_count = 0;
+ 453 5 : for (i = state->contentlist; i != 0; i = i->next) {
454 : tommy_node* j;
- 455 0 : struct snapraid_content* content = i->data;
+ 455 4 : struct snapraid_content* content = i->data;
456 :
457 : /* check if there are others in the same disk */
- 458 0 : for (j = i->next; j != 0; j = j->next) {
- 459 0 : struct snapraid_content* other = j->data;
- 460 0 : if (content->device == other->device) {
+ 458 10 : for (j = i->next; j != 0; j = j->next) {
+ 459 6 : struct snapraid_content* other = j->data;
+ 460 6 : if (content->device == other->device) {
461 0 : log_fatal(ESOFT, "WARNING! Content files on the same disk: '%s' and '%s'.\n", content->content, other->content);
462 0 : break;
463 : }
464 : }
- 465 0 : if (j != 0) {
+ 465 4 : if (j != 0) {
466 : /* skip it */
467 0 : continue;
468 : }
469 :
- 470 0 : ++content_count;
+ 470 4 : ++content_count;
471 : }
472 :
- 473 0 : if (content_count < state->level + 1) {
+ 473 1 : if (content_count < state->level + 1) {
474 : /* LCOV_EXCL_START */
475 : log_fatal(EUSER, "You must have at least %d 'content' files in different disks.\n", state->level + 1);
476 : exit(EXIT_FAILURE);
@@ -542,7 +542,7 @@
480 :
481 : /* check for speed */
482 : #ifdef CONFIG_X86
- 483 277 : if (!raid_cpu_has_ssse3())
+ 483 278 : if (!raid_cpu_has_ssse3())
484 : #endif
485 0 : if (state->raid_mode == RAID_MODE_CAUCHY && !state->opt.no_warnings) {
486 0 : if (state->level == 3) {
@@ -555,7 +555,7 @@
493 : }
494 :
495 : /* ensure that specified filter disks are valid ones */
- 496 287 : for (i = tommy_list_head(filterlist_disk); i != 0; i = i->next) {
+ 496 288 : for (i = tommy_list_head(filterlist_disk); i != 0; i = i->next) {
497 : tommy_node* j;
498 10 : struct snapraid_filter* filter = i->data;
499 51 : for (j = state->disklist; j != 0; j = j->next) {
@@ -576,7 +576,7 @@
514 : }
515 : }
516 : }
- 517 277 : }
+ 517 278 : }
518 :
519 : /**
520 : * Validate the smartctl command.
@@ -608,7 +608,7 @@
546 384 : return 0;
547 : }
548 :
- 549 278 : void state_config(struct snapraid_state* state, const char* path, const char* command, struct snapraid_option* opt, tommy_list* filterlist_disk)
+ 549 279 : void state_config(struct snapraid_state* state, const char* path, const char* command, struct snapraid_option* opt, tommy_list* filterlist_disk)
550 : {
551 : STREAM* f;
552 : unsigned line;
@@ -616,27 +616,27 @@
554 : unsigned l, s;
555 :
556 : /* copy the options */
- 557 278 : state->opt = *opt;
+ 557 279 : state->opt = *opt;
558 :
559 : /* if unset, sort by physical order */
- 560 278 : if (!state->opt.force_order)
- 561 1 : state->opt.force_order = SORT_PHYSICAL;
+ 560 279 : if (!state->opt.force_order)
+ 561 2 : state->opt.force_order = SORT_PHYSICAL;
562 :
563 : /* adjust file mode */
- 564 278 : if (state->opt.file_mode != ADVISE_DEFAULT) {
+ 564 279 : if (state->opt.file_mode != ADVISE_DEFAULT) {
565 277 : state->file_mode = state->opt.file_mode;
566 : } else {
567 : /* default mode, if nothing is specified */
- 568 1 : state->file_mode = ADVISE_DISCARD;
+ 568 2 : state->file_mode = ADVISE_DISCARD;
569 : }
570 :
571 : /* store current command */
- 572 278 : state->command = command;
+ 572 279 : state->command = command;
573 :
- 574 278 : log_tag("conf:file:%s\n", path);
+ 574 279 : log_tag("conf:file:%s\n", path);
575 :
- 576 278 : f = sopen_read(path, 0);
- 577 278 : if (!f) {
+ 576 279 : f = sopen_read(path, 0);
+ 577 279 : if (!f) {
578 : /* LCOV_EXCL_START */
579 : if (errno == ENOENT) {
580 : if (state->opt.auto_conf) {
@@ -657,8 +657,8 @@
595 : /* LCOV_EXCL_STOP */
596 : }
597 :
- 598 278 : line = 1;
- 599 6410 : while (1) {
+ 598 279 : line = 1;
+ 599 6453 : while (1) {
600 : char tag[PATH_MAX];
601 : char buffer[PATH_MAX];
602 : int ret;
@@ -666,11 +666,11 @@
604 : unsigned level;
605 :
606 : /* skip initial spaces */
- 607 6688 : sgetspace(f);
+ 607 6732 : sgetspace(f);
608 :
609 : /* read the command */
- 610 6688 : ret = sgettok(f, tag, sizeof(tag));
- 611 6688 : if (ret < 0) {
+ 610 6732 : ret = sgettok(f, tag, sizeof(tag));
+ 611 6732 : if (ret < 0) {
612 : /* LCOV_EXCL_START */
613 : log_fatal(EUSER, "Error reading the configuration file '%s' at line %u\n", path, line);
614 : exit(EXIT_FAILURE);
@@ -678,41 +678,41 @@
616 : }
617 :
618 : /* skip spaces after the command */
- 619 6688 : sgetspace(f);
+ 619 6732 : sgetspace(f);
620 :
- 621 6688 : if (strcmp(tag, "blocksize") == 0
+ 621 6732 : if (strcmp(tag, "blocksize") == 0
622 : /* block_size is the old format of the option */
- 623 6410 : || strcmp(tag, "block_size") == 0) {
+ 623 6454 : || strcmp(tag, "block_size") == 0) {
624 :
- 625 278 : ret = sgetu32(f, &state->block_size);
- 626 278 : if (ret < 0) {
+ 625 279 : ret = sgetu32(f, &state->block_size);
+ 626 279 : if (ret < 0) {
627 : /* LCOV_EXCL_START */
628 : log_fatal(EUSER, "Invalid 'blocksize' specification in '%s' at line %u\n", path, line);
629 : exit(EXIT_FAILURE);
630 : /* LCOV_EXCL_STOP */
631 : }
- 632 278 : if (state->block_size < 1) {
+ 632 279 : if (state->block_size < 1) {
633 : /* LCOV_EXCL_START */
634 : log_fatal(EUSER, "Too small 'blocksize' specification in '%s' at line %u\n", path, line);
635 : exit(EXIT_FAILURE);
636 : /* LCOV_EXCL_STOP */
637 : }
- 638 278 : if (state->block_size > 16 * KIBI) {
+ 638 279 : if (state->block_size > 16 * KIBI) {
639 : /* LCOV_EXCL_START */
640 : log_fatal(EUSER, "Too big 'blocksize' specification in '%s' at line %u\n", path, line);
641 : exit(EXIT_FAILURE);
642 : /* LCOV_EXCL_STOP */
643 : }
644 : /* check if it's a power of 2 */
- 645 278 : if ((state->block_size & (state->block_size - 1)) != 0) {
+ 645 279 : if ((state->block_size & (state->block_size - 1)) != 0) {
646 : /* LCOV_EXCL_START */
647 : log_fatal(EUSER, "Not power of 2 'blocksize' specification in '%s' at line %u\n", path, line);
648 : exit(EXIT_FAILURE);
649 : /* LCOV_EXCL_STOP */
650 : }
- 651 278 : state->block_size *= KIBI;
- 652 6410 : } else if (strcmp(tag, "hashsize") == 0
- 653 6410 : || strcmp(tag, "hash_size") == 0 /* v11.0 used incorrectly this one, kept now for backward compatibility */
+ 651 279 : state->block_size *= KIBI;
+ 652 6453 : } else if (strcmp(tag, "hashsize") == 0
+ 653 6453 : || strcmp(tag, "hash_size") == 0 /* v11.0 used incorrectly this one, kept now for backward compatibility */
654 0 : ) {
655 : uint32_t hash_size;
656 :
@@ -744,7 +744,7 @@
682 : }
683 :
684 0 : BLOCK_HASH_SIZE = hash_size;
- 685 6410 : } else if (lev_config_scan(tag, &level, &state->raid_mode) == 0) {
+ 685 6453 : } else if (lev_config_scan(tag, &level, &state->raid_mode) == 0) {
686 : char device[PATH_MAX];
687 : char* split_map[SPLIT_MAX + 1];
688 : unsigned split_mac;
@@ -752,59 +752,59 @@
690 : uint64_t dev;
691 : int skip_access;
692 :
- 693 1334 : if (state->parity[level].split_mac != 0) {
+ 693 1336 : if (state->parity[level].split_mac != 0) {
694 : /* LCOV_EXCL_START */
695 : log_fatal(EUSER, "Multiple '%s' specification in '%s' at line %u\n", tag, path, line);
696 : exit(EXIT_FAILURE);
697 : /* LCOV_EXCL_STOP */
698 : }
699 :
- 700 1334 : ret = sgetlasttok(f, buffer, sizeof(buffer));
- 701 1334 : if (ret < 0) {
+ 700 1336 : ret = sgetlasttok(f, buffer, sizeof(buffer));
+ 701 1336 : if (ret < 0) {
702 : /* LCOV_EXCL_START */
703 : log_fatal(EUSER, "Invalid '%s' specification in '%s' at line %u\n", tag, path, line);
704 : exit(EXIT_FAILURE);
705 : /* LCOV_EXCL_STOP */
706 : }
707 :
- 708 1334 : if (!*buffer) {
+ 708 1336 : if (!*buffer) {
709 : /* LCOV_EXCL_START */
710 : log_fatal(EUSER, "Empty '%s' specification in '%s' at line %u\n", tag, path, line);
711 : exit(EXIT_FAILURE);
712 : /* LCOV_EXCL_STOP */
713 : }
714 :
- 715 1334 : split_mac = strsplit(split_map, SPLIT_MAX + 1, buffer, ",");
+ 715 1336 : split_mac = strsplit(split_map, SPLIT_MAX + 1, buffer, ",");
716 :
- 717 1334 : if (split_mac > SPLIT_MAX) {
+ 717 1336 : if (split_mac > SPLIT_MAX) {
718 : /* LCOV_EXCL_START */
719 : log_fatal(EUSER, "Too many files in '%s' specification in '%s' at line %u\n", tag, path, line);
720 : exit(EXIT_FAILURE);
721 : /* LCOV_EXCL_STOP */
722 : }
723 :
- 724 1334 : skip_access = 0;
- 725 1334 : state->parity[level].split_mac = split_mac;
- 726 6666 : for (s = 0; s < split_mac; ++s) {
+ 724 1336 : skip_access = 0;
+ 725 1336 : state->parity[level].split_mac = split_mac;
+ 726 6670 : for (s = 0; s < split_mac; ++s) {
727 : char uuid[UUID_MAX];
- 728 5333 : pathimport(state->parity[level].split_map[s].path, sizeof(state->parity[level].split_map[s].path), split_map[s]);
+ 728 5335 : pathimport(state->parity[level].split_map[s].path, sizeof(state->parity[level].split_map[s].path), split_map[s]);
729 :
- 730 5333 : if (!state->opt.skip_parity_access) {
+ 730 5335 : if (!state->opt.skip_parity_access) {
731 : struct stat st;
732 :
733 : /* get the device of the directory containing the parity file */
- 734 4621 : pathimport(device, sizeof(device), split_map[s]);
- 735 4621 : slash = strrchr(device, '/');
- 736 4621 : if (slash)
- 737 4621 : *slash = 0;
+ 734 4623 : pathimport(device, sizeof(device), split_map[s]);
+ 735 4623 : slash = strrchr(device, '/');
+ 736 4623 : if (slash)
+ 737 4623 : *slash = 0;
738 : else
739 0 : pathcpy(device, sizeof(device), ".");
740 :
- 741 4621 : if (stat(device, &st) == 0) {
- 742 4616 : dev = st.st_dev;
+ 741 4623 : if (stat(device, &st) == 0) {
+ 742 4618 : dev = st.st_dev;
743 :
744 : /* read the uuid, if unsupported use an empty one */
- 745 4616 : if (devuuid(dev, split_map[s], uuid, sizeof(uuid)) != 0) {
+ 745 4618 : if (devuuid(dev, split_map[s], uuid, sizeof(uuid)) != 0) {
746 0 : *uuid = 0;
747 : }
748 : } else {
@@ -833,17 +833,17 @@
771 712 : *uuid = 0;
772 : }
773 :
- 774 5332 : state->parity[level].split_map[s].device = dev;
- 775 5332 : pathcpy(state->parity[level].split_map[s].uuid, sizeof(state->parity[level].split_map[s].uuid), uuid);
+ 774 5334 : state->parity[level].split_map[s].device = dev;
+ 775 5334 : pathcpy(state->parity[level].split_map[s].uuid, sizeof(state->parity[level].split_map[s].uuid), uuid);
776 : }
777 :
778 : /* store the global parity skip_access */
- 779 1333 : state->parity[level].skip_access = skip_access;
+ 779 1335 : state->parity[level].skip_access = skip_access;
780 :
781 : /* adjust the level */
- 782 1333 : if (state->level < level + 1)
- 783 1055 : state->level = level + 1;
- 784 5076 : } else if (strcmp(tag, "share") == 0) {
+ 782 1335 : if (state->level < level + 1)
+ 783 1056 : state->level = level + 1;
+ 784 5117 : } else if (strcmp(tag, "share") == 0) {
785 43 : if (*state->share) {
786 : /* LCOV_EXCL_START */
787 : log_fatal(EUSER, "Multiple 'share' specification in '%s' at line %u\n", path, line);
@@ -867,65 +867,65 @@
805 : }
806 :
807 43 : pathimport(state->share, sizeof(state->share), buffer);
- 808 5033 : } else if (strcmp(tag, "pool") == 0) {
+ 808 5074 : } else if (strcmp(tag, "pool") == 0) {
809 : struct stat st;
810 :
- 811 43 : if (*state->pool) {
+ 811 44 : if (*state->pool) {
812 : /* LCOV_EXCL_START */
813 : log_fatal(EUSER, "Multiple 'pool' specification in '%s' at line %u\n", path, line);
814 : exit(EXIT_FAILURE);
815 : /* LCOV_EXCL_STOP */
816 : }
817 :
- 818 43 : ret = sgetlasttok(f, buffer, sizeof(buffer));
- 819 43 : if (ret < 0) {
+ 818 44 : ret = sgetlasttok(f, buffer, sizeof(buffer));
+ 819 44 : if (ret < 0) {
820 : /* LCOV_EXCL_START */
821 : log_fatal(EUSER, "Invalid 'pool' specification in '%s' at line %u\n", path, line);
822 : exit(EXIT_FAILURE);
823 : /* LCOV_EXCL_STOP */
824 : }
825 :
- 826 43 : if (!*buffer) {
+ 826 44 : if (!*buffer) {
827 : /* LCOV_EXCL_START */
828 : log_fatal(EUSER, "Empty 'pool' specification in '%s' at line %u\n", path, line);
829 : exit(EXIT_FAILURE);
830 : /* LCOV_EXCL_STOP */
831 : }
832 :
- 833 43 : pathimport(state->pool, sizeof(state->pool), buffer);
+ 833 44 : pathimport(state->pool, sizeof(state->pool), buffer);
834 :
835 : /* get the device of the directory containing the pool tree */
- 836 43 : if (stat(buffer, &st) != 0) {
+ 836 44 : if (stat(buffer, &st) != 0) {
837 : /* LCOV_EXCL_START */
838 : log_fatal(errno, "Error accessing 'pool' dir '%s' specification in '%s' at line %u\n", buffer, path, line);
839 : exit(EXIT_FAILURE);
840 : /* LCOV_EXCL_STOP */
841 : }
842 :
- 843 43 : state->pool_device = st.st_dev;
- 844 4990 : } else if (strcmp(tag, "content") == 0) {
+ 843 44 : state->pool_device = st.st_dev;
+ 844 5030 : } else if (strcmp(tag, "content") == 0) {
845 : struct snapraid_content* content;
846 : char device[PATH_MAX];
847 : char* slash;
848 : struct stat st;
849 : uint64_t dev;
850 :
- 851 1605 : ret = sgetlasttok(f, buffer, sizeof(buffer));
- 852 1605 : if (ret < 0) {
+ 851 1609 : ret = sgetlasttok(f, buffer, sizeof(buffer));
+ 852 1609 : if (ret < 0) {
853 : /* LCOV_EXCL_START */
854 : log_fatal(EUSER, "Invalid 'content' specification in '%s' at line %u\n", path, line);
855 : exit(EXIT_FAILURE);
856 : /* LCOV_EXCL_STOP */
857 : }
858 :
- 859 1605 : if (pathcmp(buffer, "/dev/null") == 0 || pathcmp(buffer, "NUL") == 0) {
+ 859 1609 : if (pathcmp(buffer, "/dev/null") == 0 || pathcmp(buffer, "NUL") == 0) {
860 : /* LCOV_EXCL_START */
861 : log_fatal(EUSER, "You cannot use the null device as 'content' specification in '%s' at line %u\n", path, line);
862 : exit(EXIT_FAILURE);
863 : /* LCOV_EXCL_STOP */
864 : }
865 :
- 866 1605 : if (!*buffer) {
+ 866 1609 : if (!*buffer) {
867 : /* LCOV_EXCL_START */
868 : log_fatal(EUSER, "Empty 'content' specification in '%s' at line %u\n", path, line);
869 : exit(EXIT_FAILURE);
@@ -933,12 +933,12 @@
871 : }
872 :
873 : /* check if the content file is already specified */
- 874 6010 : for (i = state->contentlist; i != 0; i = i->next) {
- 875 4405 : content = i->data;
- 876 4405 : if (pathcmp(content->content, buffer) == 0)
+ 874 6020 : for (i = state->contentlist; i != 0; i = i->next) {
+ 875 4411 : content = i->data;
+ 876 4411 : if (pathcmp(content->content, buffer) == 0)
877 0 : break;
878 : }
- 879 1605 : if (i) {
+ 879 1609 : if (i) {
880 : /* LCOV_EXCL_START */
881 : log_fatal(EUSER, "Duplicate 'content' specification in '%s' at line %u\n", path, line);
882 : exit(EXIT_FAILURE);
@@ -946,14 +946,14 @@
884 : }
885 :
886 : /* get the device of the directory containing the content file */
- 887 1605 : pathimport(device, sizeof(device), buffer);
- 888 1605 : slash = strrchr(device, '/');
- 889 1605 : if (slash)
- 890 1605 : *(slash + 1) = 0;
+ 887 1609 : pathimport(device, sizeof(device), buffer);
+ 888 1609 : slash = strrchr(device, '/');
+ 889 1609 : if (slash)
+ 890 1609 : *(slash + 1) = 0;
891 : else
892 0 : pathcpy(device, sizeof(device), ".");
- 893 1605 : if (stat(device, &st) == 0) {
- 894 1604 : dev = st.st_dev;
+ 893 1609 : if (stat(device, &st) == 0) {
+ 894 1608 : dev = st.st_dev;
895 : } else {
896 1 : if (state->opt.skip_content_access) {
897 : /* use a fake device */
@@ -968,15 +968,15 @@
906 : }
907 :
908 : /* set the lock file at the first accessible content file */
- 909 1605 : if (state->lockfile[0] == 0 && dev != 0) {
- 910 277 : pathcpy(state->lockfile, sizeof(state->lockfile), buffer);
- 911 277 : pathcat(state->lockfile, sizeof(state->lockfile), ".lock");
+ 909 1609 : if (state->lockfile[0] == 0 && dev != 0) {
+ 910 278 : pathcpy(state->lockfile, sizeof(state->lockfile), buffer);
+ 911 278 : pathcat(state->lockfile, sizeof(state->lockfile), ".lock");
912 : }
913 :
- 914 1605 : content = content_alloc(buffer, dev);
+ 914 1609 : content = content_alloc(buffer, dev);
915 :
- 916 1605 : tommy_list_insert_tail(&state->contentlist, &content->node, content);
- 917 5042 : } else if (strcmp(tag, "data") == 0 || strcmp(tag, "disk") == 0) {
+ 916 1609 : tommy_list_insert_tail(&state->contentlist, &content->node, content);
+ 917 5088 : } else if (strcmp(tag, "data") == 0 || strcmp(tag, "disk") == 0) {
918 : /* "disk" is the deprecated name up to SnapRAID 9.x */
919 : char dir[PATH_MAX];
920 : char device[PATH_MAX];
@@ -985,32 +985,32 @@
923 : uint64_t dev;
924 : int skip_access;
925 :
- 926 1657 : ret = sgettok(f, buffer, sizeof(buffer));
- 927 1657 : if (ret < 0) {
+ 926 1667 : ret = sgettok(f, buffer, sizeof(buffer));
+ 927 1667 : if (ret < 0) {
928 : /* LCOV_EXCL_START */
929 : log_fatal(EUSER, "Invalid 'data' name specification in '%s' at line %u\n", path, line);
930 : exit(EXIT_FAILURE);
931 : /* LCOV_EXCL_STOP */
932 : }
933 :
- 934 1657 : if (!*buffer) {
+ 934 1667 : if (!*buffer) {
935 : /* LCOV_EXCL_START */
936 : log_fatal(EUSER, "Empty 'data' name specification in '%s' at line %u\n", path, line);
937 : exit(EXIT_FAILURE);
938 : /* LCOV_EXCL_STOP */
939 : }
940 :
- 941 1657 : sgetspace(f);
+ 941 1667 : sgetspace(f);
942 :
- 943 1657 : ret = sgetlasttok(f, dir, sizeof(dir));
- 944 1657 : if (ret < 0) {
+ 943 1667 : ret = sgetlasttok(f, dir, sizeof(dir));
+ 944 1667 : if (ret < 0) {
945 : /* LCOV_EXCL_START */
946 : log_fatal(EUSER, "Invalid 'data' dir specification in '%s' at line %u\n", path, line);
947 : exit(EXIT_FAILURE);
948 : /* LCOV_EXCL_STOP */
949 : }
950 :
- 951 1657 : if (!*dir) {
+ 951 1667 : if (!*dir) {
952 : /* LCOV_EXCL_START */
953 : log_fatal(EUSER, "Empty 'data' dir specification in '%s' at line %u\n", path, line);
954 : exit(EXIT_FAILURE);
@@ -1018,15 +1018,15 @@
956 : }
957 :
958 : /* get the device of the dir */
- 959 1657 : pathimport(device, sizeof(device), dir);
+ 959 1667 : pathimport(device, sizeof(device), dir);
960 :
961 : /* check if the disk name already exists */
- 962 5787 : for (i = state->disklist; i != 0; i = i->next) {
- 963 4130 : disk = i->data;
- 964 4130 : if (strcmp(disk->name, buffer) == 0)
+ 962 5842 : for (i = state->disklist; i != 0; i = i->next) {
+ 963 4175 : disk = i->data;
+ 964 4175 : if (strcmp(disk->name, buffer) == 0)
965 0 : break;
966 : }
- 967 1657 : if (i) {
+ 967 1667 : if (i) {
968 : /* LCOV_EXCL_START */
969 : log_fatal(EUSER, "Duplicate 'data' name '%s' at line %u\n", buffer, line);
970 : exit(EXIT_FAILURE);
@@ -1034,20 +1034,20 @@
972 : }
973 :
974 : /* if the disk has to be present */
- 975 1657 : skip_access = 0;
- 976 1657 : if (!state->opt.skip_disk_access) {
+ 975 1667 : skip_access = 0;
+ 976 1667 : if (!state->opt.skip_disk_access) {
977 : struct stat st;
978 :
- 979 1501 : if (stat(device, &st) == 0) {
- 980 1500 : dev = st.st_dev;
+ 979 1511 : if (stat(device, &st) == 0) {
+ 980 1510 : dev = st.st_dev;
981 :
982 : /* read the uuid, if unsupported use an empty one */
- 983 1500 : if (devuuid(dev, dir, uuid, sizeof(uuid)) != 0) {
+ 983 1510 : if (devuuid(dev, dir, uuid, sizeof(uuid)) != 0) {
984 0 : *uuid = 0;
985 : }
986 :
987 : /* fake a different UUID when testing */
- 988 1500 : if (state->opt.fake_uuid) {
+ 988 1510 : if (state->opt.fake_uuid) {
989 2 : snprintf(uuid, sizeof(uuid), "fake-uuid-%d", state->opt.fake_uuid);
990 2 : --state->opt.fake_uuid;
991 : }
@@ -1077,10 +1077,10 @@
1015 156 : *uuid = 0;
1016 : }
1017 :
- 1018 1657 : disk = disk_alloc(buffer, dir, dev, uuid, skip_access);
+ 1018 1667 : disk = disk_alloc(buffer, dir, dev, uuid, skip_access);
1019 :
- 1020 1657 : tommy_list_insert_tail(&state->disklist, &disk->node, disk);
- 1021 1728 : } else if (strcmp(tag, "smartctl") == 0) {
+ 1020 1667 : tommy_list_insert_tail(&state->disklist, &disk->node, disk);
+ 1021 1754 : } else if (strcmp(tag, "smartctl") == 0) {
1022 : char custom[PATH_MAX];
1023 :
1024 384 : ret = sgettok(f, buffer, sizeof(buffer));
@@ -1157,7 +1157,7 @@
1095 :
1096 192 : pathcpy(disk->smartctl, sizeof(disk->smartctl), custom);
1097 : }
- 1098 1344 : } else if (strcmp(tag, "smartignore") == 0) {
+ 1098 1370 : } else if (strcmp(tag, "smartignore") == 0) {
1099 : int* smart;
1100 :
1101 382 : ret = sgettok(f, buffer, sizeof(buffer));
@@ -1244,71 +1244,71 @@
1182 : exit(EXIT_FAILURE);
1183 : /* LCOV_EXCL_STOP */
1184 : }
- 1185 962 : } else if (strcmp(tag, "temp_limit") == 0) {
+ 1185 988 : } else if (strcmp(tag, "temp_limit") == 0) {
1186 : unsigned temp;
1187 :
- 1188 1 : ret = sgetu32(f, &temp);
- 1189 1 : if (ret < 0) {
+ 1188 2 : ret = sgetu32(f, &temp);
+ 1189 2 : if (ret < 0) {
1190 : /* LCOV_EXCL_START */
1191 : log_fatal(EUSER, "Invalid 'temp_limit' specification in '%s' at line %u\n", path, line);
1192 : exit(EXIT_FAILURE);
1193 : /* LCOV_EXCL_STOP */
1194 : }
- 1195 1 : if (temp < 40 || temp > 70) {
+ 1195 2 : if (temp < 40 || temp > 70) {
1196 : /* LCOV_EXCL_START */
1197 : log_fatal(EUSER, "Invalid 'temp_limit' temperature specification in '%s' at line %u. It must be between 40 and 70\n", path, line);
1198 : exit(EXIT_FAILURE);
1199 : /* LCOV_EXCL_STOP */
1200 : }
1201 :
- 1202 1 : state->thermal_temperature_limit = temp;
- 1203 961 : } else if (strcmp(tag, "temp_sleep") == 0) {
+ 1202 2 : state->thermal_temperature_limit = temp;
+ 1203 986 : } else if (strcmp(tag, "temp_sleep") == 0) {
1204 : unsigned time;
1205 :
- 1206 1 : ret = sgetu32(f, &time);
- 1207 1 : if (ret < 0) {
+ 1206 2 : ret = sgetu32(f, &time);
+ 1207 2 : if (ret < 0) {
1208 : /* LCOV_EXCL_START */
1209 : log_fatal(EUSER, "Invalid 'temp_sleep' specification in '%s' at line %u\n", path, line);
1210 : exit(EXIT_FAILURE);
1211 : /* LCOV_EXCL_STOP */
1212 : }
- 1213 1 : if (time < 3 || time > 120) {
+ 1213 2 : if (time < 3 || time > 120) {
1214 : /* LCOV_EXCL_START */
1215 : log_fatal(EUSER, "Invalid 'temp_sleep' temperature specification in '%s' at line %u. It must be between 3 and 120\n", path, line);
1216 : exit(EXIT_FAILURE);
1217 : /* LCOV_EXCL_STOP */
1218 : }
1219 :
- 1220 1 : state->thermal_cooldown_time = time * 60;
- 1221 960 : } else if (strcmp(tag, "nohidden") == 0) {
+ 1220 2 : state->thermal_cooldown_time = time * 60;
+ 1221 984 : } else if (strcmp(tag, "nohidden") == 0) {
1222 0 : state->filter_hidden = 1;
- 1223 960 : } else if (strcmp(tag, "exclude") == 0) {
+ 1223 984 : } else if (strcmp(tag, "exclude") == 0) {
1224 : struct snapraid_filter* filter;
1225 :
- 1226 277 : ret = sgetlasttok(f, buffer, sizeof(buffer));
- 1227 277 : if (ret < 0) {
+ 1226 282 : ret = sgetlasttok(f, buffer, sizeof(buffer));
+ 1227 282 : if (ret < 0) {
1228 : /* LCOV_EXCL_START */
1229 : log_fatal(EUSER, "Invalid 'exclude' specification in '%s' at line %u\n", path, line);
1230 : exit(EXIT_FAILURE);
1231 : /* LCOV_EXCL_STOP */
1232 : }
1233 :
- 1234 277 : if (!*buffer) {
+ 1234 282 : if (!*buffer) {
1235 : /* LCOV_EXCL_START */
1236 : log_fatal(EUSER, "Empty 'exclude' specification in '%s' at line %u\n", path, line);
1237 : exit(EXIT_FAILURE);
1238 : /* LCOV_EXCL_STOP */
1239 : }
1240 :
- 1241 277 : filter = filter_alloc_file(-1, "", buffer);
- 1242 277 : if (!filter) {
+ 1241 282 : filter = filter_alloc_file(-1, "", buffer);
+ 1242 282 : if (!filter) {
1243 : /* LCOV_EXCL_START */
1244 : log_fatal(EUSER, "Invalid 'exclude' specification '%s' in '%s' at line %u\n", buffer, path, line);
1245 : exit(EXIT_FAILURE);
1246 : /* LCOV_EXCL_STOP */
1247 : }
- 1248 277 : tommy_list_insert_tail(&state->filterlist, &filter->node, filter);
- 1249 683 : } else if (strcmp(tag, "include") == 0) {
+ 1248 282 : tommy_list_insert_tail(&state->filterlist, &filter->node, filter);
+ 1249 702 : } else if (strcmp(tag, "include") == 0) {
1250 : struct snapraid_filter* filter;
1251 :
1252 277 : ret = sgetlasttok(f, buffer, sizeof(buffer));
@@ -1334,27 +1334,27 @@
1272 : /* LCOV_EXCL_STOP */
1273 : }
1274 277 : tommy_list_insert_tail(&state->filterlist, &filter->node, filter);
- 1275 406 : } else if (strcmp(tag, "autosave") == 0) {
+ 1275 425 : } else if (strcmp(tag, "autosave") == 0) {
1276 : char* e;
1277 :
- 1278 43 : ret = sgetlasttok(f, buffer, sizeof(buffer));
- 1279 43 : if (ret < 0) {
+ 1278 44 : ret = sgetlasttok(f, buffer, sizeof(buffer));
+ 1279 44 : if (ret < 0) {
1280 : /* LCOV_EXCL_START */
1281 : log_fatal(EUSER, "Invalid 'autosave' specification in '%s' at line %u\n", path, line);
1282 : exit(EXIT_FAILURE);
1283 : /* LCOV_EXCL_STOP */
1284 : }
1285 :
- 1286 43 : if (!*buffer) {
+ 1286 44 : if (!*buffer) {
1287 : /* LCOV_EXCL_START */
1288 : log_fatal(EUSER, "Empty 'autosave' specification in '%s' at line %u\n", path, line);
1289 : exit(EXIT_FAILURE);
1290 : /* LCOV_EXCL_STOP */
1291 : }
1292 :
- 1293 43 : state->autosave = strtoul(buffer, &e, 0);
+ 1293 44 : state->autosave = strtoul(buffer, &e, 0);
1294 :
- 1295 43 : if (!e || *e) {
+ 1295 44 : if (!e || *e) {
1296 : /* LCOV_EXCL_START */
1297 : log_fatal(EUSER, "Invalid 'autosave' specification in '%s' at line %u\n", path, line);
1298 : exit(EXIT_FAILURE);
@@ -1362,12 +1362,12 @@
1300 : }
1301 :
1302 : /* convert to GB */
- 1303 43 : state->autosave *= GIGA;
- 1304 363 : } else if (tag[0] == 0) {
+ 1303 44 : state->autosave *= GIGA;
+ 1304 381 : } else if (tag[0] == 0) {
1305 : /* allow empty lines */
- 1306 43 : } else if (tag[0] == '#') {
- 1307 43 : ret = sgetline(f, buffer, sizeof(buffer));
- 1308 43 : if (ret < 0) {
+ 1306 52 : } else if (tag[0] == '#') {
+ 1307 52 : ret = sgetline(f, buffer, sizeof(buffer));
+ 1308 52 : if (ret < 0) {
1309 : /* LCOV_EXCL_START */
1310 : log_fatal(EUSER, "Invalid comment in '%s' at line %u\n", path, line);
1311 : exit(EXIT_FAILURE);
@@ -1381,47 +1381,47 @@
1319 : }
1320 :
1321 : /* skip final spaces */
- 1322 6687 : sgetspace(f);
+ 1322 6731 : sgetspace(f);
1323 :
1324 : /* next line */
- 1325 6687 : c = sgeteol(f);
- 1326 6687 : if (c == EOF) {
- 1327 277 : break;
+ 1325 6731 : c = sgeteol(f);
+ 1326 6731 : if (c == EOF) {
+ 1327 278 : break;
1328 : }
- 1329 6410 : if (c != '\n') {
+ 1329 6453 : if (c != '\n') {
1330 : /* LCOV_EXCL_START */
1331 : log_fatal(EUSER, "Extra data in '%s' at line %u\n", path, line);
1332 : exit(EXIT_FAILURE);
1333 : /* LCOV_EXCL_STOP */
1334 : }
- 1335 6410 : ++line;
+ 1335 6453 : ++line;
1336 : }
1337 :
- 1338 277 : if (serror(f)) {
+ 1338 278 : if (serror(f)) {
1339 : /* LCOV_EXCL_START */
1340 : log_fatal(errno, "Error reading the configuration file '%s' at line %u\n", path, line);
1341 : exit(EXIT_FAILURE);
1342 : /* LCOV_EXCL_STOP */
1343 : }
1344 :
- 1345 277 : sclose(f);
+ 1345 278 : sclose(f);
1346 :
- 1347 277 : state_config_check(state, path, filterlist_disk);
+ 1347 278 : state_config_check(state, path, filterlist_disk);
1348 :
1349 : /* select the default hash */
- 1350 277 : if (state->opt.force_murmur3) {
+ 1350 278 : if (state->opt.force_murmur3) {
1351 1 : state->besthash = HASH_MURMUR3;
- 1352 276 : } else if (state->opt.force_spooky2) {
+ 1352 277 : } else if (state->opt.force_spooky2) {
1353 1 : state->besthash = HASH_SPOOKY2;
1354 : } else {
- 1355 275 : state->besthash = membesthash();
+ 1355 276 : state->besthash = membesthash();
1356 : }
1357 :
1358 : /* by default use the best hash */
- 1359 277 : state->hash = state->besthash;
+ 1359 278 : state->hash = state->besthash;
1360 :
1361 : /* by default use a random hash seed */
- 1362 277 : if (randomize(state->hashseed, HASH_MAX) != 0) {
+ 1362 278 : if (randomize(state->hashseed, HASH_MAX) != 0) {
1363 : /* LCOV_EXCL_START */
1364 : log_fatal(errno, "Failed to retrieve random values.\n");
1365 : exit(EXIT_FAILURE);
@@ -1429,50 +1429,50 @@
1367 : }
1368 :
1369 : /* no previous hash by default */
- 1370 277 : state->prevhash = HASH_UNDEFINED;
+ 1370 278 : state->prevhash = HASH_UNDEFINED;
1371 :
1372 : /* intentionally not set the prevhashseed, if used valgrind will warn about it */
1373 :
- 1374 277 : log_tag("blocksize:%u\n", state->block_size);
- 1375 1934 : for (i = state->disklist; i != 0; i = i->next) {
- 1376 1657 : struct snapraid_disk* disk = i->data;
- 1377 1657 : log_tag("data:%s:%s:%s\n", disk->name, disk->dir, disk->uuid);
+ 1374 278 : log_tag("blocksize:%u\n", state->block_size);
+ 1375 1945 : for (i = state->disklist; i != 0; i = i->next) {
+ 1376 1667 : struct snapraid_disk* disk = i->data;
+ 1377 1667 : log_tag("data:%s:%s:%s\n", disk->name, disk->dir, disk->uuid);
1378 : }
1379 :
- 1380 277 : log_tag("mode:%s\n", lev_raid_name(state->raid_mode, state->level));
- 1381 1605 : for (l = 0; l < state->level; ++l) {
- 1382 1328 : log_tag("%s:%s:%s\n", lev_config_name(l), state->parity[l].split_map[0].path, state->parity[l].split_map[0].uuid);
- 1383 5312 : for (s = 1; s < state->parity[l].split_mac; ++s) {
+ 1380 278 : log_tag("mode:%s\n", lev_raid_name(state->raid_mode, state->level));
+ 1381 1608 : for (l = 0; l < state->level; ++l) {
+ 1382 1330 : log_tag("%s:%s:%s\n", lev_config_name(l), state->parity[l].split_map[0].path, state->parity[l].split_map[0].uuid);
+ 1383 5314 : for (s = 1; s < state->parity[l].split_mac; ++s) {
1384 3984 : log_tag("%s/%u:%s:%s\n", lev_config_name(l), s, state->parity[l].split_map[s].path, state->parity[l].split_map[s].uuid);
1385 : }
1386 : }
- 1387 277 : if (state->pool[0] != 0)
- 1388 43 : log_tag("pool:%s\n", state->pool);
- 1389 277 : if (state->share[0] != 0)
+ 1387 278 : if (state->pool[0] != 0)
+ 1388 44 : log_tag("pool:%s\n", state->pool);
+ 1389 278 : if (state->share[0] != 0)
1390 43 : log_tag("share:%s\n", state->share);
- 1391 277 : if (state->autosave != 0)
- 1392 43 : log_tag("autosave:%" PRIu64 "\n", state->autosave);
- 1393 831 : for (i = tommy_list_head(&state->filterlist); i != 0; i = i->next) {
+ 1391 278 : if (state->autosave != 0)
+ 1392 44 : log_tag("autosave:%" PRIu64 "\n", state->autosave);
+ 1393 837 : for (i = tommy_list_head(&state->filterlist); i != 0; i = i->next) {
1394 : char out[PATH_MAX];
- 1395 554 : struct snapraid_filter* filter = i->data;
- 1396 554 : log_tag("filter:%s\n", filter_type(filter, out, sizeof(out)));
+ 1395 559 : struct snapraid_filter* filter = i->data;
+ 1396 559 : log_tag("filter:%s\n", filter_type(filter, out, sizeof(out)));
1397 : }
- 1398 277 : if (state->filter_hidden)
+ 1398 278 : if (state->filter_hidden)
1399 0 : log_tag("filter:nohidden:\n");
- 1400 277 : log_flush();
+ 1400 278 : log_flush();
1401 : }
1402 :
1403 : /**
1404 : * Find a disk by name.
1405 : */
- 1406 7508 : static struct snapraid_disk* find_disk_by_name(struct snapraid_state* state, const char* name)
+ 1406 7496 : static struct snapraid_disk* find_disk_by_name(struct snapraid_state* state, const char* name)
1407 : {
1408 : tommy_node* i;
1409 :
- 1410 26199 : for (i = state->disklist; i != 0; i = i->next) {
- 1411 26191 : struct snapraid_disk* disk = i->data;
- 1412 26191 : if (strcmp(disk->name, name) == 0)
- 1413 7500 : return disk;
+ 1410 26157 : for (i = state->disklist; i != 0; i = i->next) {
+ 1411 26149 : struct snapraid_disk* disk = i->data;
+ 1412 26149 : if (strcmp(disk->name, name) == 0)
+ 1413 7488 : return disk;
1414 : }
1415 :
1416 8 : if (state->no_conf) {
@@ -1859,18 +1859,18 @@
1797 : *
1798 : * Note that position with only DELETED blocks are discharged.
1799 : */
- 1800 800411 : static int fs_position_is_required(struct snapraid_state* state, block_off_t pos)
+ 1800 793414 : static int fs_position_is_required(struct snapraid_state* state, block_off_t pos)
1801 : {
1802 : tommy_node* i;
1803 :
1804 : /* check for each disk */
- 1805 858937 : for (i = state->disklist; i != 0; i = i->next) {
- 1806 857059 : struct snapraid_disk* disk = i->data;
- 1807 857059 : struct snapraid_block* block = fs_par2block_find(disk, pos);
+ 1805 851308 : for (i = state->disklist; i != 0; i = i->next) {
+ 1806 849430 : struct snapraid_disk* disk = i->data;
+ 1807 849430 : struct snapraid_block* block = fs_par2block_find(disk, pos);
1808 :
1809 : /* if we have at least one file, the position is needed */
- 1810 857059 : if (block_has_file(block))
- 1811 798533 : return 1;
+ 1810 849430 : if (block_has_file(block))
+ 1811 791536 : return 1;
1812 : }
1813 :
1814 1878 : return 0;
@@ -1925,11 +1925,11 @@
1863 : /**
1864 : * Check if a block position in a disk is deleted.
1865 : */
- 1866 4795496 : static int fs_is_block_deleted(struct snapraid_disk* disk, block_off_t pos)
+ 1866 4753514 : static int fs_is_block_deleted(struct snapraid_disk* disk, block_off_t pos)
1867 : {
- 1868 4795496 : struct snapraid_block* block = fs_par2block_find(disk, pos);
+ 1868 4753514 : struct snapraid_block* block = fs_par2block_find(disk, pos);
1869 :
- 1870 4795496 : return block_state_get(block) == BLOCK_STATE_DELETED;
+ 1870 4753514 : return block_state_get(block) == BLOCK_STATE_DELETED;
1871 : }
1872 :
1873 : /**
@@ -1940,24 +1940,24 @@
1878 : *
1879 : * This means that DELETED blocks won't necessarily imply an invalid parity.
1880 : */
- 1881 2406326 : static int fs_is_block_unsynced(struct snapraid_state* state, block_off_t pos)
+ 1881 2399329 : static int fs_is_block_unsynced(struct snapraid_state* state, block_off_t pos)
1882 : {
- 1883 2406326 : int one_invalid = 0;
- 1884 2406326 : int one_valid = 0;
- 1885 15549374 : for (tommy_node* i = state->disklist; i != 0; i = i->next) {
- 1886 13367674 : struct snapraid_disk* disk = i->data;
- 1887 13367674 : struct snapraid_block* block = fs_par2block_find(disk, pos);
+ 1883 2399329 : int one_invalid = 0;
+ 1884 2399329 : int one_valid = 0;
+ 1885 15500777 : for (tommy_node* i = state->disklist; i != 0; i = i->next) {
+ 1886 13326011 : struct snapraid_disk* disk = i->data;
+ 1887 13326011 : struct snapraid_block* block = fs_par2block_find(disk, pos);
1888 :
- 1889 13367674 : if (block_has_file(block))
- 1890 13039655 : one_valid = 1;
- 1891 13367674 : if (block_has_invalid_parity(block))
- 1892 225298 : one_invalid = 1;
+ 1889 13326011 : if (block_has_file(block))
+ 1890 12998715 : one_valid = 1;
+ 1891 13326011 : if (block_has_invalid_parity(block))
+ 1892 225235 : one_invalid = 1;
1893 :
- 1894 13367674 : if (one_invalid && one_valid)
- 1895 224626 : return 1;
+ 1894 13326011 : if (one_invalid && one_valid)
+ 1895 224563 : return 1;
1896 : }
1897 :
- 1898 2181700 : return 0;
+ 1898 2174766 : return 0;
1899 : }
1900 :
1901 : /**
@@ -2079,16 +2079,16 @@
2017 : /* LCOV_EXCL_STOP */
2018 : }
2019 :
- 2020 3858136 : while (1) {
+ 2020 3858173 : while (1) {
2021 : int c;
2022 :
2023 : /* read the command */
- 2024 3858401 : c = sgetc(f);
- 2025 3858401 : if (c == EOF) {
+ 2024 3858438 : c = sgetc(f);
+ 2025 3858438 : if (c == EOF) {
2026 264 : break;
2027 : }
2028 :
- 2029 3858137 : if (c == 'f') {
+ 2029 3858174 : if (c == 'f') {
2030 : /* file */
2031 : char sub[PATH_MAX];
2032 : uint64_t v_size;
@@ -2100,25 +2100,25 @@
2038 : struct snapraid_disk* disk;
2039 : uint32_t mapping;
2040 :
- 2041 3730251 : ret = sgetb32(f, &mapping);
- 2042 3730251 : if (ret < 0 || mapping >= mapping_max) {
+ 2041 3730288 : ret = sgetb32(f, &mapping);
+ 2042 3730288 : if (ret < 0 || mapping >= mapping_max) {
2043 : /* LCOV_EXCL_START */
2044 : decoding_error(path, f);
2045 : log_fatal(EINTERNAL, "Internal inconsistency: File mapping index out of range\n");
2046 : os_abort();
2047 : /* LCOV_EXCL_STOP */
2048 : }
- 2049 3730251 : disk = tommy_array_get(&disk_mapping, mapping);
+ 2049 3730288 : disk = tommy_array_get(&disk_mapping, mapping);
2050 :
- 2051 3730251 : ret = sgetb64(f, &v_size);
- 2052 3730251 : if (ret < 0) {
+ 2051 3730288 : ret = sgetb64(f, &v_size);
+ 2052 3730288 : if (ret < 0) {
2053 : /* LCOV_EXCL_START */
2054 : decoding_error(path, f);
2055 : os_abort();
2056 : /* LCOV_EXCL_STOP */
2057 : }
2058 :
- 2059 3730251 : if (state->block_size == 0) {
+ 2059 3730288 : if (state->block_size == 0) {
2060 : /* LCOV_EXCL_START */
2061 : decoding_error(path, f);
2062 : log_fatal(EINTERNAL, "Internal inconsistency: Zero blocksize\n");
@@ -2127,7 +2127,7 @@
2065 : }
2066 :
2067 : /* check for impossible file size to avoid to crash for a too big allocation */
- 2068 3730251 : if (v_size / state->block_size > blockmax) {
+ 2068 3730288 : if (v_size / state->block_size > blockmax) {
2069 : /* LCOV_EXCL_START */
2070 : decoding_error(path, f);
2071 : log_fatal(EINTERNAL, "Internal inconsistency: File size too big!\n");
@@ -2135,16 +2135,16 @@
2073 : /* LCOV_EXCL_STOP */
2074 : }
2075 :
- 2076 3730251 : ret = sgetb64(f, &v_mtime_sec);
- 2077 3730251 : if (ret < 0) {
+ 2076 3730288 : ret = sgetb64(f, &v_mtime_sec);
+ 2077 3730288 : if (ret < 0) {
2078 : /* LCOV_EXCL_START */
2079 : decoding_error(path, f);
2080 : os_abort();
2081 : /* LCOV_EXCL_STOP */
2082 : }
2083 :
- 2084 3730251 : ret = sgetb32(f, &v_mtime_nsec);
- 2085 3730251 : if (ret < 0) {
+ 2084 3730288 : ret = sgetb32(f, &v_mtime_nsec);
+ 2085 3730288 : if (ret < 0) {
2086 : /* LCOV_EXCL_START */
2087 : decoding_error(path, f);
2088 : os_abort();
@@ -2152,27 +2152,27 @@
2090 : }
2091 :
2092 : /* STAT_NSEC_INVALID is encoded as 0 */
- 2093 3730251 : if (v_mtime_nsec == 0)
+ 2093 3730288 : if (v_mtime_nsec == 0)
2094 0 : v_mtime_nsec = STAT_NSEC_INVALID;
2095 : else
- 2096 3730251 : --v_mtime_nsec;
+ 2096 3730288 : --v_mtime_nsec;
2097 :
- 2098 3730251 : ret = sgetb64(f, &v_inode);
- 2099 3730251 : if (ret < 0) {
+ 2098 3730288 : ret = sgetb64(f, &v_inode);
+ 2099 3730288 : if (ret < 0) {
2100 : /* LCOV_EXCL_START */
2101 : decoding_error(path, f);
2102 : os_abort();
2103 : /* LCOV_EXCL_STOP */
2104 : }
2105 :
- 2106 3730251 : ret = sgetbs(f, sub, sizeof(sub));
- 2107 3730251 : if (ret < 0) {
+ 2106 3730288 : ret = sgetbs(f, sub, sizeof(sub));
+ 2107 3730288 : if (ret < 0) {
2108 : /* LCOV_EXCL_START */
2109 : decoding_error(path, f);
2110 : os_abort();
2111 : /* LCOV_EXCL_STOP */
2112 : }
- 2113 3730251 : if (!*sub) {
+ 2113 3730288 : if (!*sub) {
2114 : /* LCOV_EXCL_START */
2115 : decoding_error(path, f);
2116 : log_fatal(EINTERNAL, "Internal inconsistency: Null file!\n");
@@ -2181,40 +2181,40 @@
2119 : }
2120 :
2121 : /* allocate the file */
- 2122 3730251 : file = file_alloc(state->block_size, sub, v_size, v_mtime_sec, v_mtime_nsec, v_inode, 0);
+ 2122 3730288 : file = file_alloc(state->block_size, sub, v_size, v_mtime_sec, v_mtime_nsec, v_inode, 0);
2123 :
2124 : /* insert the file in the file containers */
- 2125 3730251 : tommy_hashdyn_insert(&disk->inodeset, &file->nodeset, file, file_inode_hash(file->inode));
- 2126 3730251 : tommy_hashdyn_insert(&disk->pathset, &file->pathset, file, file_path_hash(file->sub));
- 2127 3730251 : tommy_hashdyn_insert(&disk->stampset, &file->stampset, file, file_stamp_hash(file->size, file->mtime_sec, file->mtime_nsec));
- 2128 3730251 : tommy_list_insert_tail(&disk->filelist, &file->nodelist, file);
+ 2125 3730288 : tommy_hashdyn_insert(&disk->inodeset, &file->nodeset, file, file_inode_hash(file->inode));
+ 2126 3730288 : tommy_hashdyn_insert(&disk->pathset, &file->pathset, file, file_path_hash(file->sub));
+ 2127 3730288 : tommy_hashdyn_insert(&disk->stampset, &file->stampset, file, file_stamp_hash(file->size, file->mtime_sec, file->mtime_nsec));
+ 2128 3730288 : tommy_list_insert_tail(&disk->filelist, &file->nodelist, file);
2129 :
2130 : /* read all the blocks */
- 2131 3730251 : v_idx = 0;
- 2132 7481190 : while (v_idx < file->blockmax) {
+ 2131 3730288 : v_idx = 0;
+ 2132 7481233 : while (v_idx < file->blockmax) {
2133 : block_off_t v_pos;
2134 : uint32_t v_count;
2135 :
2136 : /* get the "subcommand */
- 2137 3750939 : c = sgetc(f);
+ 2137 3750945 : c = sgetc(f);
2138 :
- 2139 3750939 : ret = sgetb32(f, &v_pos);
- 2140 3750939 : if (ret < 0) {
+ 2139 3750945 : ret = sgetb32(f, &v_pos);
+ 2140 3750945 : if (ret < 0) {
2141 : /* LCOV_EXCL_START */
2142 : decoding_error(path, f);
2143 : os_abort();
2144 : /* LCOV_EXCL_STOP */
2145 : }
2146 :
- 2147 3750939 : ret = sgetb32(f, &v_count);
- 2148 3750939 : if (ret < 0) {
+ 2147 3750945 : ret = sgetb32(f, &v_count);
+ 2148 3750945 : if (ret < 0) {
2149 : /* LCOV_EXCL_START */
2150 : decoding_error(path, f);
2151 : os_abort();
2152 : /* LCOV_EXCL_STOP */
2153 : }
2154 :
- 2155 3750939 : if (v_idx + v_count > file->blockmax) {
+ 2155 3750945 : if (v_idx + v_count > file->blockmax) {
2156 : /* LCOV_EXCL_START */
2157 : decoding_error(path, f);
2158 : log_fatal(EINTERNAL, "Internal inconsistency: Block number out of range\n");
@@ -2222,7 +2222,7 @@
2160 : /* LCOV_EXCL_STOP */
2161 : }
2162 :
- 2163 3750939 : if (v_pos + v_count > blockmax) {
+ 2163 3750945 : if (v_pos + v_count > blockmax) {
2164 : /* LCOV_EXCL_START */
2165 : decoding_error(path, f);
2166 : log_fatal(EINTERNAL, "Internal inconsistency: Block size %u/%u!\n", blockmax, v_pos + v_count);
@@ -2257,9 +2257,9 @@
2195 : }
2196 :
2197 : /* read the hash only for 'blk/chg/rep', and not for 'new' */
- 2198 9195780 : if (c != 'n') {
- 2199 9195780 : ret = sread(f, block->hash, BLOCK_HASH_SIZE);
- 2200 9195780 : if (ret < 0) {
+ 2198 9195879 : if (c != 'n') {
+ 2199 9195879 : ret = sread(f, block->hash, BLOCK_HASH_SIZE);
+ 2200 9195879 : if (ret < 0) {
2201 : /* LCOV_EXCL_START */
2202 : decoding_error(path, f);
2203 : os_abort();
@@ -2272,8 +2272,8 @@
2210 :
2211 : /* if the block contains a hash of past data */
2212 : /* and we are clearing such indeterminate hashes */
- 2213 9195780 : if (state->clear_past_hash
- 2214 2686312 : && block_has_past_hash(block)
+ 2213 9195879 : if (state->clear_past_hash
+ 2214 2686411 : && block_has_past_hash(block)
2215 : ) {
2216 : /* set the hash value to INVALID */
2217 28006 : hash_invalid_set(block->hash);
@@ -2284,8 +2284,8 @@
2222 : /* in other sync commands */
2223 : /* note that this is required only in sync, and we detect */
2224 : /* this using the clear_past_hash flag */
- 2225 9195780 : if (state->clear_past_hash
- 2226 2686312 : && state->opt.force_nocopy
+ 2225 9195879 : if (state->clear_past_hash
+ 2226 2686411 : && state->opt.force_nocopy
2227 14195 : && block_state_get(block) == BLOCK_STATE_REP
2228 : ) {
2229 : /* set the hash value to INVALID */
@@ -2295,17 +2295,17 @@
2233 : }
2234 :
2235 : /* set the parity association */
- 2236 9195780 : fs_allocate(disk, v_pos, file, v_idx);
+ 2236 9195879 : fs_allocate(disk, v_pos, file, v_idx);
2237 :
2238 : /* go to the next block */
- 2239 9195780 : ++v_idx;
- 2240 9195780 : ++v_pos;
- 2241 9195780 : --v_count;
+ 2239 9195879 : ++v_idx;
+ 2240 9195879 : ++v_pos;
+ 2241 9195879 : --v_count;
2242 : }
2243 : }
2244 :
2245 : /* stat */
- 2246 3730251 : ++count_file;
+ 2246 3730288 : ++count_file;
2247 127886 : } else if (c == 'i') {
2248 : /* "inf" command */
2249 : snapraid_info info;
@@ -2321,7 +2321,7 @@
2259 : }
2260 :
2261 264 : v_pos = 0;
- 2262 53184 : while (v_pos < blockmax) {
+ 2262 41996 : while (v_pos < blockmax) {
2263 : int bad;
2264 : int rehash;
2265 : int justsynced;
@@ -2329,15 +2329,15 @@
2267 : uint32_t flag;
2268 : uint32_t v_count;
2269 :
- 2270 52920 : ret = sgetb32(f, &v_count);
- 2271 52920 : if (ret < 0) {
+ 2270 41732 : ret = sgetb32(f, &v_count);
+ 2271 41732 : if (ret < 0) {
2272 : /* LCOV_EXCL_START */
2273 : decoding_error(path, f);
2274 : os_abort();
2275 : /* LCOV_EXCL_STOP */
2276 : }
2277 :
- 2278 52920 : if (v_pos + v_count > blockmax) {
+ 2278 41732 : if (v_pos + v_count > blockmax) {
2279 : /* LCOV_EXCL_START */
2280 : decoding_error(path, f);
2281 : log_fatal(EINTERNAL, "Internal inconsistency: Info size %u/%u!\n", blockmax, v_pos + v_count);
@@ -2345,8 +2345,8 @@
2283 : /* LCOV_EXCL_STOP */
2284 : }
2285 :
- 2286 52920 : ret = sgetb32(f, &flag);
- 2287 52920 : if (ret < 0) {
+ 2286 41732 : ret = sgetb32(f, &flag);
+ 2287 41732 : if (ret < 0) {
2288 : /* LCOV_EXCL_START */
2289 : decoding_error(path, f);
2290 : os_abort();
@@ -2354,10 +2354,10 @@
2292 : }
2293 :
2294 : /* if there is an info */
- 2295 52920 : if ((flag & 1) != 0) {
+ 2295 41732 : if ((flag & 1) != 0) {
2296 : /* read the time */
- 2297 52903 : ret = sgetb64(f, &t64);
- 2298 52903 : if (ret < 0) {
+ 2297 41715 : ret = sgetb64(f, &t64);
+ 2298 41715 : if (ret < 0) {
2299 : /* LCOV_EXCL_START */
2300 : decoding_error(path, f);
2301 : os_abort();
@@ -2365,18 +2365,18 @@
2303 : }
2304 :
2305 : /* analyze the flags */
- 2306 52903 : bad = (flag & 2) != 0;
- 2307 52903 : rehash = (flag & 4) != 0;
- 2308 52903 : justsynced = (flag & 8) != 0;
+ 2306 41715 : bad = (flag & 2) != 0;
+ 2307 41715 : rehash = (flag & 4) != 0;
+ 2308 41715 : justsynced = (flag & 8) != 0;
2309 :
- 2310 52903 : if (bad)
- 2311 5274 : count_bad += v_count;
- 2312 52903 : if (rehash)
- 2313 14426 : count_rehash += v_count;
- 2314 52903 : if (justsynced)
- 2315 31663 : count_unscrubbed += v_count;
+ 2310 41715 : if (bad)
+ 2311 5276 : count_bad += v_count;
+ 2312 41715 : if (rehash)
+ 2313 14181 : count_rehash += v_count;
+ 2314 41715 : if (justsynced)
+ 2315 20481 : count_unscrubbed += v_count;
2316 :
- 2317 52903 : if (rehash && state->prevhash == HASH_UNDEFINED) {
+ 2317 41715 : if (rehash && state->prevhash == HASH_UNDEFINED) {
2318 : /* LCOV_EXCL_START */
2319 : decoding_error(path, f);
2320 : log_fatal(EINTERNAL, "Internal inconsistency: Missing previous checksum!\n");
@@ -2384,14 +2384,14 @@
2322 : /* LCOV_EXCL_STOP */
2323 : }
2324 :
- 2325 52903 : info = info_make(t64 + v_oldest, bad, rehash, justsynced);
+ 2325 41715 : info = info_make(t64 + v_oldest, bad, rehash, justsynced);
2326 :
- 2327 52903 : bucket_insert(&bucket_hash, t64 + v_oldest, v_count, justsynced);
+ 2327 41715 : bucket_insert(&bucket_hash, t64 + v_oldest, v_count, justsynced);
2328 : } else {
2329 17 : info = 0;
2330 : }
2331 :
- 2332 1658835 : while (v_count) {
+ 2332 1647647 : while (v_count) {
2333 : /* insert the info in the array */
2334 1605915 : info_set(&state->infoarr, v_pos, info);
2335 :
@@ -3227,15 +3227,15 @@
3165 : unsigned count_unscrubbed;
3166 : };
3167 :
- 3168 157 : static void* state_write_thread(void* arg)
+ 3168 156 : static void* state_write_thread(void* arg)
3169 : {
- 3170 157 : struct state_write_thread_context* context = arg;
- 3171 157 : struct snapraid_state* state = context->state;
- 3172 157 : block_off_t blockmax = context->blockmax;
- 3173 157 : time_t info_oldest = context->info_oldest;
- 3174 157 : time_t info_now = context->info_now;
- 3175 157 : int info_has_rehash = context->info_has_rehash;
- 3176 157 : STREAM* f = context->f;
+ 3170 156 : struct state_write_thread_context* context = arg;
+ 3171 156 : struct snapraid_state* state = context->state;
+ 3172 156 : block_off_t blockmax = context->blockmax;
+ 3173 156 : time_t info_oldest = context->info_oldest;
+ 3174 156 : time_t info_now = context->info_now;
+ 3175 156 : int info_has_rehash = context->info_has_rehash;
+ 3176 156 : STREAM* f = context->f;
3177 : uint32_t crc;
3178 : uint64_t t64;
3179 : unsigned count_file;
@@ -3252,40 +3252,40 @@
3190 : unsigned l, s;
3191 : tommy_hashdyn bucket_hash;
3192 :
- 3193 157 : count_file = 0;
- 3194 157 : count_hardlink = 0;
- 3195 157 : count_symlink = 0;
- 3196 157 : count_dir = 0;
- 3197 157 : count_bad = 0;
- 3198 157 : count_rehash = 0;
- 3199 157 : count_unsynced = 0;
- 3200 157 : count_unscrubbed = 0;
- 3201 157 : tommy_hashdyn_init(&bucket_hash);
+ 3193 156 : count_file = 0;
+ 3194 156 : count_hardlink = 0;
+ 3195 156 : count_symlink = 0;
+ 3196 156 : count_dir = 0;
+ 3197 156 : count_bad = 0;
+ 3198 156 : count_rehash = 0;
+ 3199 156 : count_unsynced = 0;
+ 3200 156 : count_unscrubbed = 0;
+ 3201 156 : tommy_hashdyn_init(&bucket_hash);
3202 :
3203 : /* force version 3 a we want to always store the parity size */
3204 : /* write header */
- 3205 157 : swrite("SNAPCNT3\n\3\0\0", 12, f);
+ 3205 156 : swrite("SNAPCNT3\n\3\0\0", 12, f);
3206 :
3207 : /* write block size and block max */
- 3208 157 : sputc('z', f);
- 3209 157 : sputb32(state->block_size, f);
- 3210 157 : sputc('x', f);
- 3211 157 : sputb32(blockmax, f);
+ 3208 156 : sputc('z', f);
+ 3209 156 : sputb32(state->block_size, f);
+ 3210 156 : sputc('x', f);
+ 3211 156 : sputb32(blockmax, f);
3212 :
3213 : /* hash size */
- 3214 157 : sputc('y', f);
- 3215 157 : sputb32(BLOCK_HASH_SIZE, f);
+ 3214 156 : sputc('y', f);
+ 3215 156 : sputb32(BLOCK_HASH_SIZE, f);
3216 :
- 3217 157 : if (serror(f)) {
+ 3217 156 : if (serror(f)) {
3218 : /* LCOV_EXCL_START */
3219 : log_fatal(errno, "Error writing the content file '%s'. %s.\n", serrorfile(f), strerror(errno));
3220 : goto bail;
3221 : /* LCOV_EXCL_STOP */
3222 : }
3223 :
- 3224 157 : sputc('c', f);
- 3225 157 : if (state->hash == HASH_MURMUR3) {
- 3226 102 : sputc('u', f);
+ 3224 156 : sputc('c', f);
+ 3225 156 : if (state->hash == HASH_MURMUR3) {
+ 3226 101 : sputc('u', f);
3227 55 : } else if (state->hash == HASH_SPOOKY2) {
3228 55 : sputc('k', f);
3229 0 : } else if (state->hash == HASH_METRO) {
@@ -3296,8 +3296,8 @@
3234 : goto bail;
3235 : /* LCOV_EXCL_STOP */
3236 : }
- 3237 157 : swrite(state->hashseed, HASH_MAX, f);
- 3238 157 : if (serror(f)) {
+ 3237 156 : swrite(state->hashseed, HASH_MAX, f);
+ 3238 156 : if (serror(f)) {
3239 : /* LCOV_EXCL_START */
3240 : log_fatal(errno, "Error writing the content file '%s'. %s.\n", serrorfile(f), strerror(errno));
3241 : goto bail;
@@ -3305,7 +3305,7 @@
3243 : }
3244 :
3245 : /* previous hash only present */
- 3246 157 : if (state->prevhash != HASH_UNDEFINED) {
+ 3246 156 : if (state->prevhash != HASH_UNDEFINED) {
3247 : /* if at least one rehash tag found, we have to save the previous hash */
3248 3 : if (info_has_rehash) {
3249 2 : sputc('C', f);
@@ -3332,13 +3332,13 @@
3270 : }
3271 :
3272 : /* for each map */
- 3273 1099 : for (i = state->maplist; i != 0; i = i->next) {
- 3274 942 : struct snapraid_map* map = i->data;
+ 3273 1092 : for (i = state->maplist; i != 0; i = i->next) {
+ 3274 936 : struct snapraid_map* map = i->data;
3275 : struct snapraid_disk* disk;
3276 :
3277 : /* find the disk for this mapping */
- 3278 942 : disk = find_disk_by_name(state, map->name);
- 3279 942 : if (!disk) {
+ 3278 936 : disk = find_disk_by_name(state, map->name);
+ 3279 936 : if (!disk) {
3280 : /* LCOV_EXCL_START */
3281 : log_fatal(EINTERNAL, "Internal inconsistency: Unmapped disk '%s'\n", map->name);
3282 : goto bail;
@@ -3346,23 +3346,23 @@
3284 : }
3285 :
3286 : /* save the mapping only if disk is mapped */
- 3287 942 : if (disk->mapping_idx != -1) {
- 3288 850 : sputc('M', f);
- 3289 850 : sputbs(map->name, f);
- 3290 850 : sputb32(map->position, f);
- 3291 850 : sputb32(map->total_blocks, f);
- 3292 850 : sputb32(map->free_blocks, f);
- 3293 850 : sputbs(map->uuid, f);
- 3294 850 : if (context->first) {
- 3295 850 : log_tag("content_data:%s:%" PRIi64 ":%" PRIi64 "\n",
- 3296 850 : map->name,
- 3297 850 : map->total_blocks * (uint64_t)state->block_size,
- 3298 850 : map->free_blocks * (uint64_t)state->block_size);
- 3299 850 : log_tag("content_data_split:%s:%s\n",
- 3300 850 : map->name,
- 3301 850 : map->uuid);
+ 3287 936 : if (disk->mapping_idx != -1) {
+ 3288 844 : sputc('M', f);
+ 3289 844 : sputbs(map->name, f);
+ 3290 844 : sputb32(map->position, f);
+ 3291 844 : sputb32(map->total_blocks, f);
+ 3292 844 : sputb32(map->free_blocks, f);
+ 3293 844 : sputbs(map->uuid, f);
+ 3294 844 : if (context->first) {
+ 3295 844 : log_tag("content_data:%s:%" PRIi64 ":%" PRIi64 "\n",
+ 3296 844 : map->name,
+ 3297 844 : map->total_blocks * (uint64_t)state->block_size,
+ 3298 844 : map->free_blocks * (uint64_t)state->block_size);
+ 3299 844 : log_tag("content_data_split:%s:%s\n",
+ 3300 844 : map->name,
+ 3301 844 : map->uuid);
3302 : }
- 3303 850 : if (serror(f)) {
+ 3303 844 : if (serror(f)) {
3304 : /* LCOV_EXCL_START */
3305 : log_fatal(errno, "Error writing the content file '%s'. %s.\n", serrorfile(f), strerror(errno));
3306 : goto bail;
@@ -3372,36 +3372,36 @@
3310 : }
3311 :
3312 : /* for each parity */
- 3313 1054 : for (l = 0; l < state->level; ++l) {
- 3314 897 : sputc('Q', f);
- 3315 897 : sputb32(l, f);
- 3316 897 : sputb32(state->parity[l].total_blocks, f);
- 3317 897 : sputb32(state->parity[l].free_blocks, f);
- 3318 897 : if (context->first) {
- 3319 897 : log_tag("content_parity:%s:%" PRIi64 ":%" PRIi64 "\n",
+ 3313 1047 : for (l = 0; l < state->level; ++l) {
+ 3314 891 : sputc('Q', f);
+ 3315 891 : sputb32(l, f);
+ 3316 891 : sputb32(state->parity[l].total_blocks, f);
+ 3317 891 : sputb32(state->parity[l].free_blocks, f);
+ 3318 891 : if (context->first) {
+ 3319 891 : log_tag("content_parity:%s:%" PRIi64 ":%" PRIi64 "\n",
3320 : lev_config_name(l),
- 3321 897 : state->parity[l].total_blocks * (uint64_t)state->block_size,
- 3322 897 : state->parity[l].free_blocks * (uint64_t)state->block_size);
+ 3321 891 : state->parity[l].total_blocks * (uint64_t)state->block_size,
+ 3322 891 : state->parity[l].free_blocks * (uint64_t)state->block_size);
3323 : }
- 3324 897 : sputb32(state->parity[l].split_mac, f);
- 3325 4485 : for (s = 0; s < state->parity[l].split_mac; ++s) {
+ 3324 891 : sputb32(state->parity[l].split_mac, f);
+ 3325 4455 : for (s = 0; s < state->parity[l].split_mac; ++s) {
3326 : char parity_name[64];
- 3327 3588 : sputbs(state->parity[l].split_map[s].path, f);
- 3328 3588 : sputbs(state->parity[l].split_map[s].uuid, f);
- 3329 3588 : sputb64(state->parity[l].split_map[s].size, f);
- 3330 3588 : if (s == 0)
- 3331 897 : pathcpy(parity_name, sizeof(parity_name), lev_config_name(l));
+ 3327 3564 : sputbs(state->parity[l].split_map[s].path, f);
+ 3328 3564 : sputbs(state->parity[l].split_map[s].uuid, f);
+ 3329 3564 : sputb64(state->parity[l].split_map[s].size, f);
+ 3330 3564 : if (s == 0)
+ 3331 891 : pathcpy(parity_name, sizeof(parity_name), lev_config_name(l));
3332 : else
- 3333 2691 : pathprint(parity_name, sizeof(parity_name), "%s/%u", lev_config_name(l), s);
- 3334 3588 : if (context->first) {
- 3335 3588 : log_tag("content_parity_split:%s:%s:%s:%" PRIi64 "\n",
+ 3333 2673 : pathprint(parity_name, sizeof(parity_name), "%s/%u", lev_config_name(l), s);
+ 3334 3564 : if (context->first) {
+ 3335 3564 : log_tag("content_parity_split:%s:%s:%s:%" PRIi64 "\n",
3336 : parity_name,
- 3337 3588 : state->parity[l].split_map[s].uuid,
- 3338 3588 : state->parity[l].split_map[s].path,
+ 3337 3564 : state->parity[l].split_map[s].uuid,
+ 3338 3564 : state->parity[l].split_map[s].path,
3339 : state->parity[l].split_map[s].size);
3340 : }
3341 : }
- 3342 897 : if (serror(f)) {
+ 3342 891 : if (serror(f)) {
3343 : /* LCOV_EXCL_START */
3344 : log_fatal(errno, "Error writing the content file '%s'. %s.\n", serrorfile(f), strerror(errno));
3345 : goto bail;
@@ -3410,39 +3410,39 @@
3348 : }
3349 :
3350 : /* for each disk */
- 3351 1099 : for (i = state->disklist; i != 0; i = i->next) {
+ 3351 1092 : for (i = state->disklist; i != 0; i = i->next) {
3352 : tommy_node* j;
- 3353 942 : struct snapraid_disk* disk = i->data;
+ 3353 936 : struct snapraid_disk* disk = i->data;
3354 :
3355 : /* if the disk is not mapped, skip it */
- 3356 942 : if (disk->mapping_idx < 0)
+ 3356 936 : if (disk->mapping_idx < 0)
3357 92 : continue;
3358 :
3359 : /* for each file */
- 3360 1850418 : for (j = disk->filelist; j != 0; j = j->next) {
- 3361 1849568 : struct snapraid_file* file = j->data;
+ 3360 1833655 : for (j = disk->filelist; j != 0; j = j->next) {
+ 3361 1832811 : struct snapraid_file* file = j->data;
3362 : uint64_t size;
3363 : uint64_t mtime_sec;
3364 : int32_t mtime_nsec;
3365 : uint64_t inode;
3366 :
- 3367 1849568 : size = file->size;
- 3368 1849568 : mtime_sec = file->mtime_sec;
- 3369 1849568 : mtime_nsec = file->mtime_nsec;
- 3370 1849568 : inode = file->inode;
+ 3367 1832811 : size = file->size;
+ 3368 1832811 : mtime_sec = file->mtime_sec;
+ 3369 1832811 : mtime_nsec = file->mtime_nsec;
+ 3370 1832811 : inode = file->inode;
3371 :
- 3372 1849568 : sputc('f', f);
- 3373 1849568 : sputb32(disk->mapping_idx, f);
- 3374 1849568 : sputb64(size, f);
- 3375 1849568 : sputb64(mtime_sec, f);
+ 3372 1832811 : sputc('f', f);
+ 3373 1832811 : sputb32(disk->mapping_idx, f);
+ 3374 1832811 : sputb64(size, f);
+ 3375 1832811 : sputb64(mtime_sec, f);
3376 : /* encode STAT_NSEC_INVALID as 0 */
- 3377 1849568 : if (mtime_nsec == STAT_NSEC_INVALID)
+ 3377 1832811 : if (mtime_nsec == STAT_NSEC_INVALID)
3378 0 : sputb32(0, f);
3379 : else
- 3380 1849568 : sputb32(mtime_nsec + 1, f);
- 3381 1849568 : sputb64(inode, f);
- 3382 1849568 : sputbs(file->sub, f);
- 3383 1849568 : if (serror(f)) {
+ 3380 1832811 : sputb32(mtime_nsec + 1, f);
+ 3381 1832811 : sputb64(inode, f);
+ 3382 1832811 : sputbs(file->sub, f);
+ 3383 1832811 : if (serror(f)) {
3384 : /* LCOV_EXCL_START */
3385 : log_fatal(errno, "Error writing the content file '%s'. %s.\n", serrorfile(f), strerror(errno));
3386 : goto bail;
@@ -3450,31 +3450,31 @@
3388 : }
3389 :
3390 : /* for all the blocks of the file */
- 3391 1849568 : begin = 0;
- 3392 3709156 : while (begin < file->blockmax) {
- 3393 1859588 : unsigned v_state = block_state_get(fs_file2block_get(file, begin));
- 3394 1859588 : block_off_t v_pos = fs_file2par_get(disk, file, begin);
+ 3391 1832811 : begin = 0;
+ 3392 3675510 : while (begin < file->blockmax) {
+ 3393 1842699 : unsigned v_state = block_state_get(fs_file2block_get(file, begin));
+ 3394 1842699 : block_off_t v_pos = fs_file2par_get(disk, file, begin);
3395 : uint32_t v_count;
3396 :
3397 : block_off_t end;
3398 :
3399 : /* find the end of run of blocks */
- 3400 1859588 : end = begin + 1;
- 3401 4569406 : while (end < file->blockmax) {
- 3402 2722429 : if (v_state != block_state_get(fs_file2block_get(file, end)))
+ 3400 1842699 : end = begin + 1;
+ 3401 4528141 : while (end < file->blockmax) {
+ 3402 2697897 : if (v_state != block_state_get(fs_file2block_get(file, end)))
3403 12 : break;
- 3404 2722417 : if (v_pos + (end - begin) != fs_file2par_get(disk, file, end))
- 3405 12599 : break;
- 3406 2709818 : ++end;
+ 3404 2697885 : if (v_pos + (end - begin) != fs_file2par_get(disk, file, end))
+ 3405 12443 : break;
+ 3406 2685442 : ++end;
3407 : }
3408 :
- 3409 1859588 : switch (v_state) {
- 3410 1758705 : case BLOCK_STATE_BLK :
- 3411 1758705 : sputc('b', f);
- 3412 1758705 : break;
- 3413 65965 : case BLOCK_STATE_CHG :
- 3414 65965 : sputc('g', f);
- 3415 65965 : break;
+ 3409 1842699 : switch (v_state) {
+ 3410 1741862 : case BLOCK_STATE_BLK :
+ 3411 1741862 : sputc('b', f);
+ 3412 1741862 : break;
+ 3413 65919 : case BLOCK_STATE_CHG :
+ 3414 65919 : sputc('g', f);
+ 3415 65919 : break;
3416 34918 : case BLOCK_STATE_REP :
3417 34918 : sputc('p', f);
3418 34918 : break;
@@ -3485,19 +3485,19 @@
3423 : /* LCOV_EXCL_STOP */
3424 : }
3425 :
- 3426 1859588 : sputb32(v_pos, f);
+ 3426 1842699 : sputb32(v_pos, f);
3427 :
- 3428 1859588 : v_count = end - begin;
- 3429 1859588 : sputb32(v_count, f);
+ 3428 1842699 : v_count = end - begin;
+ 3429 1842699 : sputb32(v_count, f);
3430 :
3431 : /* write hashes */
- 3432 6428994 : for (idx = begin; idx < end; ++idx) {
- 3433 4569406 : struct snapraid_block* block = fs_file2block_get(file, idx);
+ 3432 6370840 : for (idx = begin; idx < end; ++idx) {
+ 3433 4528141 : struct snapraid_block* block = fs_file2block_get(file, idx);
3434 :
- 3435 4569406 : swrite(block->hash, BLOCK_HASH_SIZE, f);
+ 3435 4528141 : swrite(block->hash, BLOCK_HASH_SIZE, f);
3436 : }
3437 :
- 3438 1859588 : if (serror(f)) {
+ 3438 1842699 : if (serror(f)) {
3439 : /* LCOV_EXCL_START */
3440 : log_fatal(errno, "Error writing the content file '%s'. %s.\n", serrorfile(f), strerror(errno));
3441 : goto bail;
@@ -3505,31 +3505,31 @@
3443 : }
3444 :
3445 : /* next begin position */
- 3446 1859588 : begin = end;
+ 3446 1842699 : begin = end;
3447 : }
3448 :
- 3449 1849568 : ++count_file;
+ 3449 1832811 : ++count_file;
3450 : }
3451 :
3452 : /* for each link */
- 3453 61524 : for (j = disk->linklist; j != 0; j = j->next) {
- 3454 60674 : struct snapraid_link* slink = j->data;
+ 3453 60974 : for (j = disk->linklist; j != 0; j = j->next) {
+ 3454 60130 : struct snapraid_link* slink = j->data;
3455 :
- 3456 60674 : switch (link_flag_get(slink, FILE_IS_LINK_MASK)) {
- 3457 342 : case FILE_IS_HARDLINK :
- 3458 342 : sputc('a', f);
- 3459 342 : ++count_hardlink;
- 3460 342 : break;
- 3461 60332 : case FILE_IS_SYMLINK :
- 3462 60332 : sputc('s', f);
- 3463 60332 : ++count_symlink;
- 3464 60332 : break;
+ 3456 60130 : switch (link_flag_get(slink, FILE_IS_LINK_MASK)) {
+ 3457 339 : case FILE_IS_HARDLINK :
+ 3458 339 : sputc('a', f);
+ 3459 339 : ++count_hardlink;
+ 3460 339 : break;
+ 3461 59791 : case FILE_IS_SYMLINK :
+ 3462 59791 : sputc('s', f);
+ 3463 59791 : ++count_symlink;
+ 3464 59791 : break;
3465 : }
3466 :
- 3467 60674 : sputb32(disk->mapping_idx, f);
- 3468 60674 : sputbs(slink->sub, f);
- 3469 60674 : sputbs(slink->linkto, f);
- 3470 60674 : if (serror(f)) {
+ 3467 60130 : sputb32(disk->mapping_idx, f);
+ 3468 60130 : sputbs(slink->sub, f);
+ 3469 60130 : sputbs(slink->linkto, f);
+ 3470 60130 : if (serror(f)) {
3471 : /* LCOV_EXCL_START */
3472 : log_fatal(errno, "Error writing the content file '%s'. %s.\n", serrorfile(f), strerror(errno));
3473 : goto bail;
@@ -3538,49 +3538,49 @@
3476 : }
3477 :
3478 : /* for each dir */
- 3479 1305 : for (j = disk->dirlist; j != 0; j = j->next) {
- 3480 455 : struct snapraid_dir* dir = j->data;
+ 3479 1295 : for (j = disk->dirlist; j != 0; j = j->next) {
+ 3480 451 : struct snapraid_dir* dir = j->data;
3481 :
- 3482 455 : sputc('r', f);
- 3483 455 : sputb32(disk->mapping_idx, f);
- 3484 455 : sputbs(dir->sub, f);
- 3485 455 : if (serror(f)) {
+ 3482 451 : sputc('r', f);
+ 3483 451 : sputb32(disk->mapping_idx, f);
+ 3484 451 : sputbs(dir->sub, f);
+ 3485 451 : if (serror(f)) {
3486 : /* LCOV_EXCL_START */
3487 : log_fatal(errno, "Error writing the content file '%s'. %s.\n", serrorfile(f), strerror(errno));
3488 : goto bail;
3489 : /* LCOV_EXCL_STOP */
3490 : }
3491 :
- 3492 455 : ++count_dir;
+ 3492 451 : ++count_dir;
3493 : }
3494 :
3495 : /* deleted blocks of the disk */
- 3496 850 : sputc('h', f);
- 3497 850 : sputb32(disk->mapping_idx, f);
- 3498 850 : if (serror(f)) {
+ 3496 844 : sputc('h', f);
+ 3497 844 : sputb32(disk->mapping_idx, f);
+ 3498 844 : if (serror(f)) {
3499 : /* LCOV_EXCL_START */
3500 : log_fatal(errno, "Error writing the content file '%s'. %s.\n", serrorfile(f), strerror(errno));
3501 : goto bail;
3502 : /* LCOV_EXCL_STOP */
3503 : }
- 3504 850 : begin = 0;
- 3505 1777 : while (begin < blockmax) {
+ 3504 844 : begin = 0;
+ 3505 1765 : while (begin < blockmax) {
3506 : int is_deleted;
3507 : block_off_t end;
3508 :
- 3509 927 : is_deleted = fs_is_block_deleted(disk, begin);
+ 3509 921 : is_deleted = fs_is_block_deleted(disk, begin);
3510 :
3511 : /* find the end of run of blocks */
- 3512 927 : end = begin + 1;
- 3513 927 : while (end < blockmax
- 3514 4795419 : && is_deleted == fs_is_block_deleted(disk, end)
+ 3512 921 : end = begin + 1;
+ 3513 921 : while (end < blockmax
+ 3514 4753437 : && is_deleted == fs_is_block_deleted(disk, end)
3515 : ) {
- 3516 4794492 : ++end;
+ 3516 4752516 : ++end;
3517 : }
3518 :
- 3519 927 : sputb32(end - begin, f);
+ 3519 921 : sputb32(end - begin, f);
3520 :
- 3521 927 : if (is_deleted) {
+ 3521 921 : if (is_deleted) {
3522 : /* write the run of deleted blocks with hash */
3523 49 : sputc('o', f);
3524 :
@@ -3595,13 +3595,13 @@
3533 : } else {
3534 : /* write the run of blocks without hash */
3535 : /* they can be either used or empty blocks */
- 3536 878 : sputc('O', f);
+ 3536 872 : sputc('O', f);
3537 :
3538 : /* next begin position */
- 3539 878 : begin = end;
+ 3539 872 : begin = end;
3540 : }
3541 :
- 3542 927 : if (serror(f)) {
+ 3542 921 : if (serror(f)) {
3543 : /* LCOV_EXCL_START */
3544 : log_fatal(errno, "Error writing the content file '%s'. %s.\n", serrorfile(f), strerror(errno));
3545 : goto bail;
@@ -3611,82 +3611,82 @@
3549 : }
3550 :
3551 : /* write the info for each block */
- 3552 157 : sputc('i', f);
+ 3552 156 : sputc('i', f);
3553 : /* ensure to write a 64 bit time */
- 3554 157 : t64 = info_oldest;
- 3555 157 : sputb64(t64, f);
- 3556 157 : begin = 0;
- 3557 19334 : while (begin < blockmax) {
+ 3554 156 : t64 = info_oldest;
+ 3555 156 : sputb64(t64, f);
+ 3556 156 : begin = 0;
+ 3557 14427 : while (begin < blockmax) {
3558 : snapraid_info info;
3559 : block_off_t end;
3560 : block_off_t count;
3561 : time_t t;
3562 : unsigned flag;
3563 :
- 3564 19177 : info = info_get(&state->infoarr, begin);
+ 3564 14271 : info = info_get(&state->infoarr, begin);
3565 :
3566 : /* avoid this slow operation if not needed */
- 3567 19177 : if (context->first && fs_is_block_unsynced(state, begin))
- 3568 197 : ++count_unsynced;
+ 3567 14271 : if (context->first && fs_is_block_unsynced(state, begin))
+ 3568 105 : ++count_unsynced;
3569 :
3570 : /* find the end of run of blocks */
- 3571 19177 : end = begin + 1;
- 3572 19177 : while (end < blockmax
- 3573 800411 : && info == info_get(&state->infoarr, end)
+ 3571 14271 : end = begin + 1;
+ 3572 14271 : while (end < blockmax
+ 3573 793414 : && info == info_get(&state->infoarr, end)
3574 : ) {
- 3575 781234 : if (context->first && fs_is_block_unsynced(state, end))
- 3576 111131 : ++count_unsynced;
- 3577 781234 : ++end;
+ 3575 779143 : if (context->first && fs_is_block_unsynced(state, end))
+ 3576 111160 : ++count_unsynced;
+ 3577 779143 : ++end;
3578 : }
3579 :
- 3580 19177 : count = end - begin;
- 3581 19177 : sputb32(count, f);
+ 3580 14271 : count = end - begin;
+ 3581 14271 : sputb32(count, f);
3582 :
3583 : /* if there is info */
- 3584 19177 : if (info) {
+ 3584 14271 : if (info) {
3585 : /* other flags */
- 3586 19149 : flag = 1; /* info is present */
- 3587 19149 : if (info_get_bad(info)) {
+ 3586 14243 : flag = 1; /* info is present */
+ 3587 14243 : if (info_get_bad(info)) {
3588 1326 : flag |= 2;
3589 1326 : if (context->first)
3590 1326 : count_bad += count;
3591 : }
- 3592 19149 : if (info_get_rehash(info)) {
- 3593 5212 : flag |= 4;
- 3594 5212 : if (context->first)
- 3595 5212 : count_rehash += count;
+ 3592 14243 : if (info_get_rehash(info)) {
+ 3593 4967 : flag |= 4;
+ 3594 4967 : if (context->first)
+ 3595 4967 : count_rehash += count;
3596 : }
- 3597 19149 : if (info_get_justsynced(info)) {
- 3598 12475 : flag |= 8;
- 3599 12475 : if (context->first)
- 3600 12475 : count_unscrubbed += count;
+ 3597 14243 : if (info_get_justsynced(info)) {
+ 3598 7571 : flag |= 8;
+ 3599 7571 : if (context->first)
+ 3600 7571 : count_unscrubbed += count;
3601 : }
- 3602 19149 : sputb32(flag, f);
+ 3602 14243 : sputb32(flag, f);
3603 :
- 3604 19149 : t = info_get_time(info);
+ 3604 14243 : t = info_get_time(info);
3605 :
- 3606 19149 : if (context->first)
- 3607 19149 : bucket_insert(&bucket_hash, t, count, flag & 8);
+ 3606 14243 : if (context->first)
+ 3607 14243 : bucket_insert(&bucket_hash, t, count, flag & 8);
3608 :
3609 : /* truncate any time that is in the future */
- 3610 19149 : if (t > info_now)
+ 3610 14243 : if (t > info_now)
3611 0 : t = info_now;
3612 :
3613 : /* the oldest info is computed only on required blocks, so it may not be the absolute oldest */
- 3614 19149 : if (t < info_oldest)
+ 3614 14243 : if (t < info_oldest)
3615 0 : t = 0;
3616 : else
- 3617 19149 : t -= info_oldest;
+ 3617 14243 : t -= info_oldest;
3618 :
3619 : /* ensure to write a 64 bit time */
- 3620 19149 : t64 = t;
- 3621 19149 : sputb64(t64, f);
+ 3620 14243 : t64 = t;
+ 3621 14243 : sputb64(t64, f);
3622 : } else {
3623 : /* write a special 0 flag to mark missing info */
3624 28 : sputb32(0, f);
3625 : }
3626 :
- 3627 19177 : if (serror(f)) {
+ 3627 14271 : if (serror(f)) {
3628 : /* LCOV_EXCL_START */
3629 : log_fatal(errno, "Error writing the content file '%s'. %s.\n", serrorfile(f), strerror(errno));
3630 : goto bail;
@@ -3694,13 +3694,13 @@
3632 : }
3633 :
3634 : /* next begin position */
- 3635 19177 : begin = end;
+ 3635 14271 : begin = end;
3636 : }
3637 :
- 3638 157 : sputc('N', f);
+ 3638 156 : sputc('N', f);
3639 :
3640 : /* flush data written to the disk */
- 3641 157 : if (sflush(f)) {
+ 3641 156 : if (sflush(f)) {
3642 : /* LCOV_EXCL_START */
3643 : log_fatal(errno, "Error writing the content file '%s' (in flush before crc). %s.\n", serrorfile(f), strerror(errno));
3644 : goto bail;
@@ -3708,11 +3708,11 @@
3646 : }
3647 :
3648 : /* get the file crc */
- 3649 157 : crc = scrc(f);
+ 3649 156 : crc = scrc(f);
3650 :
3651 : /* compare the crc of the data written to file */
3652 : /* with the one of the data written to the stream */
- 3653 157 : if (crc != scrc_stream(f)) {
+ 3653 156 : if (crc != scrc_stream(f)) {
3654 : /* LCOV_EXCL_START */
3655 : log_fatal(ECONTENT, "CRC mismatch while writing the content stream.\n");
3656 : log_fatal(ECONTENT, "DANGER! Your RAM memory is faulty! DO NOT PROCEED UNTIL FIXED!\n");
@@ -3721,8 +3721,8 @@
3659 : /* LCOV_EXCL_STOP */
3660 : }
3661 :
- 3662 157 : sputble32(crc, f);
- 3663 157 : if (serror(f)) {
+ 3662 156 : sputble32(crc, f);
+ 3663 156 : if (serror(f)) {
3664 : /* LCOV_EXCL_START */
3665 : log_fatal(errno, "Error writing the content file '%s'. %s.\n", serrorfile(f), strerror(errno));
3666 : goto bail;
@@ -3730,29 +3730,29 @@
3668 : }
3669 :
3670 : /* set output variables */
- 3671 157 : context->crc = crc;
- 3672 157 : context->count_file = count_file;
- 3673 157 : context->count_hardlink = count_hardlink;
- 3674 157 : context->count_symlink = count_symlink;
- 3675 157 : context->count_dir = count_dir;
- 3676 157 : context->count_bad = count_bad;
- 3677 157 : context->count_rehash = count_rehash;
- 3678 157 : context->count_unsynced = count_unsynced;
- 3679 157 : context->count_unscrubbed = count_unscrubbed;
+ 3671 156 : context->crc = crc;
+ 3672 156 : context->count_file = count_file;
+ 3673 156 : context->count_hardlink = count_hardlink;
+ 3674 156 : context->count_symlink = count_symlink;
+ 3675 156 : context->count_dir = count_dir;
+ 3676 156 : context->count_bad = count_bad;
+ 3677 156 : context->count_rehash = count_rehash;
+ 3678 156 : context->count_unsynced = count_unsynced;
+ 3679 156 : context->count_unscrubbed = count_unscrubbed;
3680 :
3681 : /* store the bucket info list */
- 3682 157 : if (context->first)
- 3683 157 : bucket_to_list(&bucket_hash, &state->bucketlist, &state->bucketcount);
+ 3682 156 : if (context->first)
+ 3683 156 : bucket_to_list(&bucket_hash, &state->bucketlist, &state->bucketcount);
3684 :
- 3685 157 : tommy_hashdyn_done(&bucket_hash);
- 3686 157 : return 0;
+ 3685 156 : tommy_hashdyn_done(&bucket_hash);
+ 3686 156 : return 0;
3687 :
3688 0 : bail:
3689 0 : tommy_hashdyn_done(&bucket_hash);
3690 0 : return context;
3691 : }
3692 :
- 3693 157 : static void state_write_content(struct snapraid_state* state, uint32_t* out_crc)
+ 3693 156 : static void state_write_content(struct snapraid_state* state, uint32_t* out_crc)
3694 : {
3695 : #if HAVE_MT_WRITE
3696 : int fail;
@@ -3782,29 +3782,29 @@
3720 : unsigned count_unscrubbed;
3721 :
3722 : /* blocks of all array */
- 3723 157 : blockmax = parity_allocated_size(state);
+ 3723 156 : blockmax = parity_allocated_size(state);
3724 :
3725 : /* check the file-system on all disks */
- 3726 157 : state_fscheck(state, "before write");
+ 3726 156 : state_fscheck(state, "before write");
3727 :
3728 : /* clear the info for unused blocks */
3729 : /* and get some other info */
- 3730 157 : info_oldest = 0; /* oldest time in info */
- 3731 157 : info_now = time(0); /* get the present time */
- 3732 157 : info_has_rehash = 0; /* if there is a rehash info */
- 3733 800568 : for (idx = 0; idx < blockmax; ++idx) {
+ 3730 156 : info_oldest = 0; /* oldest time in info */
+ 3731 156 : info_now = time(0); /* get the present time */
+ 3732 156 : info_has_rehash = 0; /* if there is a rehash info */
+ 3733 793570 : for (idx = 0; idx < blockmax; ++idx) {
3734 : /* if the position is used */
- 3735 800411 : if (fs_position_is_required(state, idx)) {
- 3736 798533 : snapraid_info info = info_get(&state->infoarr, idx);
+ 3735 793414 : if (fs_position_is_required(state, idx)) {
+ 3736 791536 : snapraid_info info = info_get(&state->infoarr, idx);
3737 :
3738 : /* only if there is some info to store */
- 3739 798533 : if (info) {
- 3740 751146 : time_t info_time = info_get_time(info);
+ 3739 791536 : if (info) {
+ 3740 744149 : time_t info_time = info_get_time(info);
3741 :
- 3742 751146 : if (!info_oldest || info_time < info_oldest)
- 3743 156 : info_oldest = info_time;
+ 3742 744149 : if (!info_oldest || info_time < info_oldest)
+ 3743 155 : info_oldest = info_time;
3744 :
- 3745 751146 : if (info_get_rehash(info))
+ 3745 744149 : if (info_get_rehash(info))
3746 13822 : info_has_rehash = 1;
3747 : }
3748 : } else {
@@ -3817,14 +3817,14 @@
3755 : }
3756 :
3757 : /* map disks */
- 3758 157 : mapping_idx = 0;
- 3759 1099 : for (i = state->maplist; i != 0; i = i->next) {
- 3760 942 : struct snapraid_map* map = i->data;
+ 3758 156 : mapping_idx = 0;
+ 3759 1092 : for (i = state->maplist; i != 0; i = i->next) {
+ 3760 936 : struct snapraid_map* map = i->data;
3761 : struct snapraid_disk* disk;
3762 :
3763 : /* find the disk for this mapping */
- 3764 942 : disk = find_disk_by_name(state, map->name);
- 3765 942 : if (!disk) {
+ 3764 936 : disk = find_disk_by_name(state, map->name);
+ 3765 936 : if (!disk) {
3766 : /* LCOV_EXCL_START */
3767 : log_fatal(EINTERNAL, "Internal inconsistency: Unmapped disk '%s'\n", map->name);
3768 : os_abort();
@@ -3832,10 +3832,10 @@
3770 : }
3771 :
3772 : /* save the mapping only for not empty disks */
- 3773 942 : if (!fs_is_empty(disk, blockmax)) {
+ 3773 936 : if (!fs_is_empty(disk, blockmax)) {
3774 : /* assign the mapping index used to identify disks */
- 3775 850 : disk->mapping_idx = mapping_idx;
- 3776 850 : ++mapping_idx;
+ 3775 844 : disk->mapping_idx = mapping_idx;
+ 3776 844 : ++mapping_idx;
3777 : } else {
3778 : /* mark the disk as without mapping */
3779 92 : disk->mapping_idx = -1;
@@ -3983,34 +3983,34 @@
3921 : }
3922 : #else
3923 : /* count the content files */
- 3924 157 : count_content = 0;
- 3925 157 : i = tommy_list_head(&state->contentlist);
- 3926 1211 : while (i) {
- 3927 1054 : struct snapraid_content* content = i->data;
- 3928 1054 : msg_progress("Saving state to %s...\n", content->content);
- 3929 1054 : ++count_content;
- 3930 1054 : i = i->next;
+ 3924 156 : count_content = 0;
+ 3925 156 : i = tommy_list_head(&state->contentlist);
+ 3926 1203 : while (i) {
+ 3927 1047 : struct snapraid_content* content = i->data;
+ 3928 1047 : msg_progress("Saving state to %s...\n", content->content);
+ 3929 1047 : ++count_content;
+ 3930 1047 : i = i->next;
3931 : }
3932 :
3933 : /* open all the content files */
- 3934 157 : f = sopen_multi_write(count_content, STREAM_FLAGS_SEQUENTIAL | STREAM_FLAGS_CRC);
- 3935 157 : if (!f) {
+ 3934 156 : f = sopen_multi_write(count_content, STREAM_FLAGS_SEQUENTIAL | STREAM_FLAGS_CRC);
+ 3935 156 : if (!f) {
3936 : /* LCOV_EXCL_START */
3937 : log_fatal(errno, "Error opening the content files.\n");
3938 : exit(EXIT_FAILURE);
3939 : /* LCOV_EXCL_STOP */
3940 : }
3941 :
- 3942 157 : k = 0;
- 3943 157 : i = tommy_list_head(&state->contentlist);
- 3944 1211 : while (i) {
- 3945 1054 : struct snapraid_content* content = i->data;
+ 3942 156 : k = 0;
+ 3943 156 : i = tommy_list_head(&state->contentlist);
+ 3944 1203 : while (i) {
+ 3945 1047 : struct snapraid_content* content = i->data;
3946 : char tmp[PATH_MAX];
- 3947 1054 : pathprint(tmp, sizeof(tmp), "%s.tmp", content->content);
+ 3947 1047 : pathprint(tmp, sizeof(tmp), "%s.tmp", content->content);
3948 :
3949 : /* ensure to delete a previous stale file */
- 3950 1054 : if (remove(tmp) != 0) {
- 3951 1054 : if (errno != ENOENT) {
+ 3950 1047 : if (remove(tmp) != 0) {
+ 3951 1047 : if (errno != ENOENT) {
3952 : /* LCOV_EXCL_START */
3953 : log_fatal(errno, "Error removing the stale content file '%s'. %s.\n", tmp, strerror(errno));
3954 : exit(EXIT_FAILURE);
@@ -4018,33 +4018,33 @@
3956 : }
3957 : }
3958 :
- 3959 1054 : if (sopen_multi_file(f, k, tmp) != 0) {
+ 3959 1047 : if (sopen_multi_file(f, k, tmp) != 0) {
3960 : /* LCOV_EXCL_START */
3961 : log_fatal(errno, "Error opening the temporary content file '%s'. %s.\n", tmp, strerror(errno));
3962 : exit(EXIT_FAILURE);
3963 : /* LCOV_EXCL_STOP */
3964 : }
3965 :
- 3966 1054 : ++k;
- 3967 1054 : i = i->next;
+ 3966 1047 : ++k;
+ 3967 1047 : i = i->next;
3968 : }
3969 :
3970 : /* allocate the thread context */
- 3971 157 : context = malloc_nofail(sizeof(struct state_write_thread_context));
+ 3971 156 : context = malloc_nofail(sizeof(struct state_write_thread_context));
3972 :
3973 : /* initialize */
- 3974 157 : context->state = state;
- 3975 157 : context->blockmax = blockmax;
- 3976 157 : context->info_oldest = info_oldest;
- 3977 157 : context->info_now = info_now;
- 3978 157 : context->info_has_rehash = info_has_rehash;
- 3979 157 : context->f = f;
- 3980 157 : context->first = 1;
+ 3974 156 : context->state = state;
+ 3975 156 : context->blockmax = blockmax;
+ 3976 156 : context->info_oldest = info_oldest;
+ 3977 156 : context->info_now = info_now;
+ 3978 156 : context->info_has_rehash = info_has_rehash;
+ 3979 156 : context->f = f;
+ 3980 156 : context->first = 1;
3981 :
- 3982 157 : retval = state_write_thread(context);
+ 3982 156 : retval = state_write_thread(context);
3983 :
3984 : /* abort on failure */
- 3985 157 : if (retval) {
+ 3985 156 : if (retval) {
3986 : /* LCOV_EXCL_START */
3987 : exit(EXIT_FAILURE);
3988 : /* LCOV_EXCL_STOP */
@@ -4052,7 +4052,7 @@
3990 :
3991 : /* Use the sequence fflush() -> fsync() -> fclose() -> rename() to ensure */
3992 : /* than even in a system crash event we have one valid copy of the file. */
- 3993 157 : if (sflush(f) != 0) {
+ 3993 156 : if (sflush(f) != 0) {
3994 : /* LCOV_EXCL_START */
3995 : log_fatal(errno, "Error writing the content file '%s', in flush(). %s.\n", serrorfile(f), strerror(errno));
3996 : exit(EXIT_FAILURE);
@@ -4060,7 +4060,7 @@
3998 : }
3999 :
4000 : #if HAVE_FSYNC
- 4001 157 : if (ssync(f) != 0) {
+ 4001 156 : if (ssync(f) != 0) {
4002 : /* LCOV_EXCL_START */
4003 : log_fatal(errno, "Error writing the content file '%s' in sync(). %s.\n", serrorfile(f), strerror(errno));
4004 : exit(EXIT_FAILURE);
@@ -4068,50 +4068,50 @@
4006 : }
4007 : #endif
4008 :
- 4009 157 : if (sclose(f) != 0) {
+ 4009 156 : if (sclose(f) != 0) {
4010 : /* LCOV_EXCL_START */
4011 : log_fatal(errno, "Error closing the content file. %s.\n", strerror(errno));
4012 : exit(EXIT_FAILURE);
4013 : /* LCOV_EXCL_STOP */
4014 : }
4015 :
- 4016 157 : crc = context->crc;
- 4017 157 : count_file = context->count_file;
- 4018 157 : count_hardlink = context->count_hardlink;
- 4019 157 : count_symlink = context->count_symlink;
- 4020 157 : count_dir = context->count_dir;
- 4021 157 : count_bad = context->count_bad;
- 4022 157 : count_rehash = context->count_rehash;
- 4023 157 : count_unsynced = context->count_unsynced;
- 4024 157 : count_unscrubbed = context->count_unscrubbed;
+ 4016 156 : crc = context->crc;
+ 4017 156 : count_file = context->count_file;
+ 4018 156 : count_hardlink = context->count_hardlink;
+ 4019 156 : count_symlink = context->count_symlink;
+ 4020 156 : count_dir = context->count_dir;
+ 4021 156 : count_bad = context->count_bad;
+ 4022 156 : count_rehash = context->count_rehash;
+ 4023 156 : count_unsynced = context->count_unsynced;
+ 4024 156 : count_unscrubbed = context->count_unscrubbed;
4025 :
- 4026 157 : free(context);
+ 4026 156 : free(context);
4027 : #endif
4028 :
- 4029 157 : msg_verbose("%8u files\n", count_file);
- 4030 157 : msg_verbose("%8u hardlinks\n", count_hardlink);
- 4031 157 : msg_verbose("%8u symlinks\n", count_symlink);
- 4032 157 : msg_verbose("%8u empty dirs\n", count_dir);
+ 4029 156 : msg_verbose("%8u files\n", count_file);
+ 4030 156 : msg_verbose("%8u hardlinks\n", count_hardlink);
+ 4031 156 : msg_verbose("%8u symlinks\n", count_symlink);
+ 4032 156 : msg_verbose("%8u empty dirs\n", count_dir);
4033 :
- 4034 157 : log_tag("content_info:file:%u\n", count_file);
- 4035 157 : log_tag("content_info:hardlink:%u\n", count_hardlink);
- 4036 157 : log_tag("content_info:symlink:%u\n", count_symlink);
- 4037 157 : log_tag("content_info:dir_empty:%u\n", count_dir);
+ 4034 156 : log_tag("content_info:file:%u\n", count_file);
+ 4035 156 : log_tag("content_info:hardlink:%u\n", count_hardlink);
+ 4036 156 : log_tag("content_info:symlink:%u\n", count_symlink);
+ 4037 156 : log_tag("content_info:dir_empty:%u\n", count_dir);
4038 :
- 4039 157 : log_tag("content_info:block:%u\n", blockmax);
- 4040 157 : log_tag("content_info:block_bad:%u\n", count_bad);
- 4041 157 : log_tag("content_info:block_rehash:%u\n", count_rehash);
- 4042 157 : log_tag("content_info:block_unsynced:%u\n", count_unsynced);
- 4043 157 : log_tag("content_info:block_unscrubbed:%u\n", count_unscrubbed);
+ 4039 156 : log_tag("content_info:block:%u\n", blockmax);
+ 4040 156 : log_tag("content_info:block_bad:%u\n", count_bad);
+ 4041 156 : log_tag("content_info:block_rehash:%u\n", count_rehash);
+ 4042 156 : log_tag("content_info:block_unsynced:%u\n", count_unsynced);
+ 4043 156 : log_tag("content_info:block_unscrubbed:%u\n", count_unscrubbed);
4044 :
4045 : /* store the blocks counters */
- 4046 157 : state->rehash_blocks = count_rehash;
- 4047 157 : state->bad_blocks = count_bad;
- 4048 157 : state->unsynced_blocks = count_unsynced;
- 4049 157 : state->unscrubbed_blocks = count_unscrubbed;
+ 4046 156 : state->rehash_blocks = count_rehash;
+ 4047 156 : state->bad_blocks = count_bad;
+ 4048 156 : state->unsynced_blocks = count_unsynced;
+ 4049 156 : state->unscrubbed_blocks = count_unscrubbed;
4050 :
- 4051 157 : *out_crc = crc;
- 4052 157 : }
+ 4051 156 : *out_crc = crc;
+ 4052 156 : }
4053 :
4054 272 : void state_read(struct snapraid_state* state)
4055 : {
@@ -4275,19 +4275,19 @@
4213 : STREAM* f;
4214 : };
4215 :
- 4216 1054 : static void* state_verify_thread(void* arg)
+ 4216 1047 : static void* state_verify_thread(void* arg)
4217 : {
- 4218 1054 : struct state_verify_thread_context* context = arg;
- 4219 1054 : struct snapraid_content* content = context->content;
- 4220 1054 : STREAM* f = context->f;
+ 4218 1047 : struct state_verify_thread_context* context = arg;
+ 4219 1047 : struct snapraid_content* content = context->content;
+ 4220 1047 : STREAM* f = context->f;
4221 : unsigned char buf[4];
4222 : uint32_t crc_stored;
4223 : uint32_t crc_computed;
4224 : uint64_t start;
4225 :
- 4226 1054 : start = tick_ms();
+ 4226 1047 : start = tick_ms();
4227 :
- 4228 1054 : if (sdeplete(f, buf) != 0) {
+ 4228 1047 : if (sdeplete(f, buf) != 0) {
4229 : /* LCOV_EXCL_START */
4230 : log_fatal(errno, "Failed to flush content file '%s'. %s.\n", serrorfile(f), strerror(errno));
4231 : return context;
@@ -4295,9 +4295,9 @@
4233 : }
4234 :
4235 : /* get the stored crc from the last four bytes */
- 4236 1054 : crc_stored = buf[0] | (uint32_t)buf[1] << 8 | (uint32_t)buf[2] << 16 | (uint32_t)buf[3] << 24;
+ 4236 1047 : crc_stored = buf[0] | (uint32_t)buf[1] << 8 | (uint32_t)buf[2] << 16 | (uint32_t)buf[3] << 24;
4237 :
- 4238 1054 : if (crc_stored != context->crc) {
+ 4238 1047 : if (crc_stored != context->crc) {
4239 : /* LCOV_EXCL_START */
4240 : log_fatal(ECONTENT, "DANGER! Wrong stored CRC in '%s'\n", serrorfile(f));
4241 : return context;
@@ -4305,41 +4305,41 @@
4243 : }
4244 :
4245 : /* get the computed crc */
- 4246 1054 : crc_computed = scrc(f);
+ 4246 1047 : crc_computed = scrc(f);
4247 :
4248 : /* adjust the stored crc to include itself */
- 4249 1054 : crc_stored = crc32c(crc_stored, buf, 4);
+ 4249 1047 : crc_stored = crc32c(crc_stored, buf, 4);
4250 :
- 4251 1054 : if (crc_computed != crc_stored) {
+ 4251 1047 : if (crc_computed != crc_stored) {
4252 : /* LCOV_EXCL_START */
4253 : log_fatal(ECONTENT, "DANGER! Wrong file CRC in '%s'\n", serrorfile(f));
4254 : return context;
4255 : /* LCOV_EXCL_STOP */
4256 : }
4257 :
- 4258 1054 : msg_progress("Verified %s in %" PRIu64 " seconds\n", content->content, (tick_ms() - start) / 1000);
+ 4258 1047 : msg_progress("Verified %s in %" PRIu64 " seconds\n", content->content, (tick_ms() - start) / 1000);
4259 :
- 4260 1054 : return 0;
+ 4260 1047 : return 0;
4261 : }
4262 :
- 4263 157 : static void state_verify_content(struct snapraid_state* state, uint32_t crc)
+ 4263 156 : static void state_verify_content(struct snapraid_state* state, uint32_t crc)
4264 : {
4265 : tommy_node* i;
4266 : int fail;
4267 :
- 4268 157 : msg_progress("Verifying...\n");
+ 4268 156 : msg_progress("Verifying...\n");
4269 :
4270 : /* start all reading threads */
- 4271 157 : i = tommy_list_head(&state->contentlist);
- 4272 1211 : while (i) {
- 4273 1054 : struct snapraid_content* content = i->data;
+ 4271 156 : i = tommy_list_head(&state->contentlist);
+ 4272 1203 : while (i) {
+ 4273 1047 : struct snapraid_content* content = i->data;
4274 : struct state_verify_thread_context* context;
4275 : char tmp[PATH_MAX];
4276 : STREAM* f;
4277 :
- 4278 1054 : pathprint(tmp, sizeof(tmp), "%s.tmp", content->content);
- 4279 1054 : f = sopen_read(tmp, STREAM_FLAGS_SEQUENTIAL | STREAM_FLAGS_CRC);
- 4280 1054 : if (f == 0) {
+ 4278 1047 : pathprint(tmp, sizeof(tmp), "%s.tmp", content->content);
+ 4279 1047 : f = sopen_read(tmp, STREAM_FLAGS_SEQUENTIAL | STREAM_FLAGS_CRC);
+ 4280 1047 : if (f == 0) {
4281 : /* LCOV_EXCL_START */
4282 : log_fatal(errno, "Error reopening the temporary content file '%s'. %s.\n", tmp, strerror(errno));
4283 : exit(EXIT_FAILURE);
@@ -4347,45 +4347,45 @@
4285 : }
4286 :
4287 : /* allocate the thread context */
- 4288 1054 : context = malloc_nofail(sizeof(struct state_verify_thread_context));
- 4289 1054 : content->context = context;
+ 4288 1047 : context = malloc_nofail(sizeof(struct state_verify_thread_context));
+ 4289 1047 : content->context = context;
4290 :
4291 : /* initialize */
- 4292 1054 : context->state = state;
- 4293 1054 : context->content = content;
- 4294 1054 : context->crc = crc;
- 4295 1054 : context->f = f;
+ 4292 1047 : context->state = state;
+ 4293 1047 : context->content = content;
+ 4294 1047 : context->crc = crc;
+ 4295 1047 : context->f = f;
4296 :
4297 : #if HAVE_MT_VERIFY
- 4298 1054 : thread_create(&context->thread, state_verify_thread, context);
+ 4298 1047 : thread_create(&context->thread, state_verify_thread, context);
4299 : #else
4300 : context->retval = state_verify_thread(context);
4301 : #endif
4302 :
- 4303 1054 : i = i->next;
+ 4303 1047 : i = i->next;
4304 : }
4305 :
4306 : /* join all thread */
- 4307 157 : fail = 0;
- 4308 157 : i = tommy_list_head(&state->contentlist);
- 4309 1211 : while (i) {
- 4310 1054 : struct snapraid_content* content = i->data;
- 4311 1054 : struct state_verify_thread_context* context = content->context;
+ 4307 156 : fail = 0;
+ 4308 156 : i = tommy_list_head(&state->contentlist);
+ 4309 1203 : while (i) {
+ 4310 1047 : struct snapraid_content* content = i->data;
+ 4311 1047 : struct state_verify_thread_context* context = content->context;
4312 : void* retval;
4313 :
4314 : #if HAVE_MT_VERIFY
- 4315 1054 : thread_join(context->thread, &retval);
+ 4315 1047 : thread_join(context->thread, &retval);
4316 : #else
4317 : retval = context->retval;
4318 : #endif
- 4319 1054 : if (retval) {
+ 4319 1047 : if (retval) {
4320 : /* LCOV_EXCL_START */
4321 : fail = 1;
4322 : /* LCOV_EXCL_STOP */
4323 : } else {
- 4324 1054 : STREAM* f = context->f;
+ 4324 1047 : STREAM* f = context->f;
4325 :
- 4326 1054 : if (sclose(f) != 0) {
+ 4326 1047 : if (sclose(f) != 0) {
4327 : /* LCOV_EXCL_START */
4328 : log_fatal(errno, "Error closing the content file. %s.\n", strerror(errno));
4329 : exit(EXIT_FAILURE);
@@ -4393,20 +4393,20 @@
4331 : }
4332 : }
4333 :
- 4334 1054 : free(context);
+ 4334 1047 : free(context);
4335 :
- 4336 1054 : i = i->next;
+ 4336 1047 : i = i->next;
4337 : }
4338 :
4339 : /* abort on failure */
- 4340 157 : if (fail) {
+ 4340 156 : if (fail) {
4341 : /* LCOV_EXCL_START */
4342 : exit(EXIT_FAILURE);
4343 : /* LCOV_EXCL_STOP */
4344 : }
- 4345 157 : }
+ 4345 156 : }
4346 :
- 4347 157 : static void state_rename_content(struct snapraid_state* state)
+ 4347 156 : static void state_rename_content(struct snapraid_state* state)
4348 : {
4349 : tommy_node* i;
4350 :
@@ -4463,42 +4463,42 @@
4401 : i = i->next;
4402 : }
4403 : #else
- 4404 157 : i = tommy_list_head(&state->contentlist);
- 4405 1211 : while (i) {
- 4406 1054 : struct snapraid_content* content = i->data;
+ 4404 156 : i = tommy_list_head(&state->contentlist);
+ 4405 1203 : while (i) {
+ 4406 1047 : struct snapraid_content* content = i->data;
4407 : char tmp[PATH_MAX];
4408 :
4409 : /* now renames the just written copy with the correct name */
- 4410 1054 : pathprint(tmp, sizeof(tmp), "%s.tmp", content->content);
- 4411 1054 : if (rename(tmp, content->content) != 0) {
+ 4410 1047 : pathprint(tmp, sizeof(tmp), "%s.tmp", content->content);
+ 4411 1047 : if (rename(tmp, content->content) != 0) {
4412 : /* LCOV_EXCL_START */
4413 : log_fatal(errno, "Error renaming the content file '%s' to '%s' in rename(). %s.\n", tmp, content->content, strerror(errno));
4414 : exit(EXIT_FAILURE);
4415 : /* LCOV_EXCL_STOP */
4416 : }
4417 :
- 4418 1054 : i = i->next;
+ 4418 1047 : i = i->next;
4419 : }
4420 : #endif
- 4421 157 : }
+ 4421 156 : }
4422 :
- 4423 157 : void state_write(struct snapraid_state* state)
+ 4423 156 : void state_write(struct snapraid_state* state)
4424 : {
4425 : uint32_t crc;
4426 :
4427 : /* write all the content files */
- 4428 157 : state_write_content(state, &crc);
+ 4428 156 : state_write_content(state, &crc);
4429 :
4430 : /* verify the just written files */
- 4431 157 : state_verify_content(state, crc);
+ 4431 156 : state_verify_content(state, crc);
4432 :
4433 : /* rename the new files, over the old ones */
- 4434 157 : state_rename_content(state);
+ 4434 156 : state_rename_content(state);
4435 :
- 4436 157 : state->need_write = 0; /* no write needed anymore */
- 4437 157 : state->checked_read = 0; /* what we wrote is not checked in read */
- 4438 157 : state->written = 1;
- 4439 157 : }
+ 4436 156 : state->need_write = 0; /* no write needed anymore */
+ 4437 156 : state->checked_read = 0; /* what we wrote is not checked in read */
+ 4438 156 : state->written = 1;
+ 4439 156 : }
4440 :
4441 123 : void state_skip(struct snapraid_state* state)
4442 : {
@@ -4574,7 +4574,7 @@
4512 75254 : || filter_existence(filter_missing, disk->dir, file->sub) != 0
4513 35762 : || filter_correctness(filter_error, &state->infoarr, disk, file) != 0
4514 : ) {
- 4515 112402 : file_flag_set(file, FILE_IS_EXCLUDED);
+ 4515 112357 : file_flag_set(file, FILE_IS_EXCLUDED);
4516 : }
4517 : }
4518 :
@@ -4665,8 +4665,8 @@
4603 5 : log_tag("run:end\n");
4604 5 : log_flush();
4605 222 : } else if (countmax == 0) {
- 4606 20 : if (state->need_write || state->written) {
- 4607 15 : msg_status("100%% completed\n");
+ 4606 21 : if (state->need_write || state->written) {
+ 4607 16 : msg_status("100%% completed\n");
4608 : } else {
4609 5 : msg_status("%s", msg);
4610 : }
@@ -4674,18 +4674,18 @@
4612 : time_t now;
4613 : time_t elapsed;
4614 :
- 4615 202 : unsigned countsize_MB = (countsize + MEGA - 1) / MEGA;
+ 4615 201 : unsigned countsize_MB = (countsize + MEGA - 1) / MEGA;
4616 :
- 4617 202 : now = time(0);
+ 4617 201 : now = time(0);
4618 :
- 4619 202 : elapsed = now - state->progress_whole_start - state->progress_wasted;
+ 4619 201 : elapsed = now - state->progress_whole_start - state->progress_wasted;
4620 :
- 4621 202 : msg_bar("%u%% completed, %u MB accessed", muldiv(countpos, 100, countmax), countsize_MB);
+ 4621 201 : msg_bar("%u%% completed, %u MB accessed", muldiv(countpos, 100, countmax), countsize_MB);
4622 :
- 4623 202 : msg_bar(" in %u:%02u", (unsigned)(elapsed / 3600), (unsigned)((elapsed % 3600) / 60));
+ 4623 201 : msg_bar(" in %u:%02u", (unsigned)(elapsed / 3600), (unsigned)((elapsed % 3600) / 60));
4624 :
- 4625 202 : msg_bar("\n");
- 4626 202 : msg_flush();
+ 4625 201 : msg_bar("\n");
+ 4626 201 : msg_flush();
4627 : }
4628 227 : }
4629 :
@@ -4715,23 +4715,23 @@
4653 : /**
4654 : * Set the latest tick data in the progress vector.
4655 : */
- 4656 493 : static void state_progress_latest(struct snapraid_state* state)
+ 4656 481 : static void state_progress_latest(struct snapraid_state* state)
4657 : {
4658 : tommy_node* i;
4659 : unsigned l;
4660 :
- 4661 493 : state->progress_tick_misc[state->progress_ptr] = state->tick_misc;
- 4662 493 : state->progress_tick_sched[state->progress_ptr] = state->tick_sched;
- 4663 493 : state->progress_tick_raid[state->progress_ptr] = state->tick_raid;
- 4664 493 : state->progress_tick_hash[state->progress_ptr] = state->tick_hash;
- 4665 493 : state->progress_tick_io[state->progress_ptr] = state->tick_io;
- 4666 3442 : for (i = state->disklist; i != 0; i = i->next) {
- 4667 2949 : struct snapraid_disk* disk = i->data;
- 4668 2949 : disk->progress_tick[state->progress_ptr] = disk->tick;
+ 4661 481 : state->progress_tick_misc[state->progress_ptr] = state->tick_misc;
+ 4662 481 : state->progress_tick_sched[state->progress_ptr] = state->tick_sched;
+ 4663 481 : state->progress_tick_raid[state->progress_ptr] = state->tick_raid;
+ 4664 481 : state->progress_tick_hash[state->progress_ptr] = state->tick_hash;
+ 4665 481 : state->progress_tick_io[state->progress_ptr] = state->tick_io;
+ 4666 3358 : for (i = state->disklist; i != 0; i = i->next) {
+ 4667 2877 : struct snapraid_disk* disk = i->data;
+ 4668 2877 : disk->progress_tick[state->progress_ptr] = disk->tick;
4669 : }
- 4670 2881 : for (l = 0; l < state->level; ++l)
- 4671 2388 : state->parity[l].progress_tick[state->progress_ptr] = state->parity[l].tick;
- 4672 493 : }
+ 4670 2837 : for (l = 0; l < state->level; ++l)
+ 4671 2356 : state->parity[l].progress_tick[state->progress_ptr] = state->parity[l].tick;
+ 4672 481 : }
4673 :
4674 : /**
4675 : * Number of columns
@@ -4964,54 +4964,54 @@
4902 2 : printf("\n");
4903 : }
4904 :
- 4905 1075966 : 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)
+ 4905 1075903 : 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)
4906 : {
4907 : time_t now;
4908 : int pred;
4909 :
- 4910 1075966 : now = time(0);
+ 4910 1075903 : now = time(0);
4911 :
4912 : /* thermal measure */
- 4913 1075966 : if (now > state->thermal_latest + THERMAL_PERIOD_SECONDS || state->opt.fake_device) {
- 4914 2613 : state->thermal_latest = now;
- 4915 2613 : state_thermal(state, now);
+ 4913 1075903 : if (now > state->thermal_latest + THERMAL_PERIOD_SECONDS || state->opt.fake_device) {
+ 4914 2612 : state->thermal_latest = now;
+ 4915 2612 : state_thermal(state, now);
4916 : }
4917 :
4918 : /* previous position */
- 4919 1075966 : pred = state->progress_ptr + PROGRESS_MAX - 1;
- 4920 1075966 : if (pred >= PROGRESS_MAX)
- 4921 1075763 : pred -= PROGRESS_MAX;
+ 4919 1075903 : pred = state->progress_ptr + PROGRESS_MAX - 1;
+ 4920 1075903 : if (pred >= PROGRESS_MAX)
+ 4921 1075701 : pred -= PROGRESS_MAX;
4922 :
4923 : /* if the previous measure is different */
- 4924 1075966 : if (state->progress_tick == 0
- 4925 1075763 : || state->progress_time[pred] != now
+ 4924 1075903 : if (state->progress_tick == 0
+ 4925 1075701 : || state->progress_time[pred] != now
4926 : ) {
4927 : time_t elapsed;
- 4928 391 : unsigned out_perc = 0;
- 4929 391 : unsigned out_size_speed = 0;
- 4930 391 : unsigned out_block_speed = 0;
- 4931 391 : unsigned out_cpu = 0;
- 4932 391 : unsigned out_eta = 0;
- 4933 391 : int out_temperature = 0;
- 4934 391 : int out_steady = 0;
- 4935 391 : int out_computed = 0;
+ 4928 379 : unsigned out_perc = 0;
+ 4929 379 : unsigned out_size_speed = 0;
+ 4930 379 : unsigned out_block_speed = 0;
+ 4931 379 : unsigned out_cpu = 0;
+ 4932 379 : unsigned out_eta = 0;
+ 4933 379 : int out_temperature = 0;
+ 4934 379 : int out_steady = 0;
+ 4935 379 : int out_computed = 0;
4936 :
4937 : /* store the new measure */
- 4938 391 : state->progress_time[state->progress_ptr] = now;
- 4939 391 : state->progress_pos[state->progress_ptr] = countpos;
- 4940 391 : state->progress_size[state->progress_ptr] = countsize;
- 4941 391 : state_progress_latest(state);
+ 4938 379 : state->progress_time[state->progress_ptr] = now;
+ 4939 379 : state->progress_pos[state->progress_ptr] = countpos;
+ 4940 379 : state->progress_size[state->progress_ptr] = countsize;
+ 4941 379 : state_progress_latest(state);
4942 :
- 4943 391 : elapsed = now - state->progress_whole_start - state->progress_wasted;
+ 4943 379 : elapsed = now - state->progress_whole_start - state->progress_wasted;
4944 :
4945 : /* completion percentage */
- 4946 391 : if (countmax)
- 4947 391 : out_perc = muldiv(countpos, 100, countmax);
+ 4946 379 : if (countmax)
+ 4947 379 : out_perc = muldiv(countpos, 100, countmax);
4948 :
4949 : /* if we have at least 5 measures */
- 4950 391 : if (state->progress_tick >= 5
+ 4950 379 : if (state->progress_tick >= 5
4951 : /* or if we are running in test mode, with at least one measure */
- 4952 390 : || (state->opt.force_progress && state->progress_tick >= 1)
+ 4952 377 : || (state->opt.force_progress && state->progress_tick >= 1)
4953 : ) {
4954 : int oldest;
4955 : int past;
@@ -5027,142 +5027,142 @@
4965 : tommy_node* i;
4966 :
4967 : /* number of past measures */
- 4968 188 : past = state->progress_tick;
+ 4968 177 : past = state->progress_tick;
4969 :
4970 : /* drop the oldest ones, to promptly */
4971 : /* skip the startup phase */
- 4972 188 : past -= past / 5;
+ 4972 177 : past -= past / 5;
4973 :
4974 : /* check how much we can go in the past */
- 4975 188 : if (past >= PROGRESS_MAX - 1) {
+ 4975 177 : if (past >= PROGRESS_MAX - 1) {
4976 : /* the vector is filled, so we are already in position */
4977 : /* to get the possible oldest one */
4978 0 : oldest = state->progress_ptr + 1;
4979 : } else {
4980 : /* go backward the number of positions selected */
- 4981 188 : oldest = state->progress_ptr + PROGRESS_MAX - past;
+ 4981 177 : oldest = state->progress_ptr + PROGRESS_MAX - past;
4982 : }
- 4983 188 : if (oldest >= PROGRESS_MAX)
- 4984 188 : oldest -= PROGRESS_MAX;
+ 4983 177 : if (oldest >= PROGRESS_MAX)
+ 4984 177 : oldest -= PROGRESS_MAX;
4985 :
- 4986 188 : tick_cpu = state->progress_tick_misc[state->progress_ptr]
- 4987 188 : + state->progress_tick_sched[state->progress_ptr]
- 4988 188 : + state->progress_tick_raid[state->progress_ptr]
- 4989 188 : + state->progress_tick_hash[state->progress_ptr];
- 4990 188 : tick_total = tick_cpu + state->progress_tick_io[state->progress_ptr];
+ 4986 177 : tick_cpu = state->progress_tick_misc[state->progress_ptr]
+ 4987 177 : + state->progress_tick_sched[state->progress_ptr]
+ 4988 177 : + state->progress_tick_raid[state->progress_ptr]
+ 4989 177 : + state->progress_tick_hash[state->progress_ptr];
+ 4990 177 : tick_total = tick_cpu + state->progress_tick_io[state->progress_ptr];
4991 :
- 4992 188 : oldest_tick_cpu = state->progress_tick_misc[oldest]
- 4993 188 : + state->progress_tick_sched[oldest]
- 4994 188 : + state->progress_tick_raid[oldest]
- 4995 188 : + state->progress_tick_hash[oldest];
- 4996 188 : oldest_tick_total = oldest_tick_cpu + state->progress_tick_io[oldest];
+ 4992 177 : oldest_tick_cpu = state->progress_tick_misc[oldest]
+ 4993 177 : + state->progress_tick_sched[oldest]
+ 4994 177 : + state->progress_tick_raid[oldest]
+ 4995 177 : + state->progress_tick_hash[oldest];
+ 4996 177 : oldest_tick_total = oldest_tick_cpu + state->progress_tick_io[oldest];
4997 :
- 4998 188 : delta_time = now - state->progress_time[oldest];
- 4999 188 : delta_pos = countpos - state->progress_pos[oldest];
- 5000 188 : delta_size = countsize - state->progress_size[oldest];
- 5001 188 : delta_tick_cpu = tick_cpu - oldest_tick_cpu;
- 5002 188 : delta_tick_total = tick_total - oldest_tick_total;
+ 4998 177 : delta_time = now - state->progress_time[oldest];
+ 4999 177 : delta_pos = countpos - state->progress_pos[oldest];
+ 5000 177 : delta_size = countsize - state->progress_size[oldest];
+ 5001 177 : delta_tick_cpu = tick_cpu - oldest_tick_cpu;
+ 5002 177 : delta_tick_total = tick_total - oldest_tick_total;
5003 :
5004 : /* estimate the speed in MB/s */
- 5005 188 : if (delta_time != 0)
- 5006 188 : out_size_speed = (unsigned)(delta_size / MEGA / delta_time);
+ 5005 177 : if (delta_time != 0)
+ 5006 177 : out_size_speed = (unsigned)(delta_size / MEGA / delta_time);
5007 :
5008 : /* estimate the speed in block/s */
- 5009 188 : if (delta_time != 0)
- 5010 188 : out_block_speed = (unsigned)(delta_pos / delta_time);
+ 5009 177 : if (delta_time != 0)
+ 5010 177 : out_block_speed = (unsigned)(delta_pos / delta_time);
5011 :
5012 : /* estimate the cpu usage percentage */
- 5013 188 : if (delta_tick_total != 0)
- 5014 33 : out_cpu = muldiv(delta_tick_cpu, 100, delta_tick_total);
+ 5013 177 : if (delta_tick_total != 0)
+ 5014 34 : out_cpu = muldiv(delta_tick_cpu, 100, delta_tick_total);
5015 :
5016 : /* estimate the remaining time in minutes */
- 5017 188 : if (delta_pos != 0)
- 5018 188 : out_eta = muldiv(countmax - countpos, delta_time, delta_pos);
+ 5017 177 : if (delta_pos != 0)
+ 5018 177 : out_eta = muldiv(countmax - countpos, delta_time, delta_pos);
5019 :
- 5020 188 : if (state->opt.force_stats) {
+ 5020 177 : if (state->opt.force_stats) {
5021 1 : os_clear();
5022 1 : state_progress_graph(state, io, state->progress_ptr, oldest);
5023 : }
5024 :
- 5025 188 : if (state->thermal_temperature_limit != 0) {
+ 5025 177 : if (state->thermal_temperature_limit != 0) {
5026 : /* get the max temperature */
- 5027 4 : out_temperature = 0;
- 5028 124 : for (i = tommy_list_head(&state->thermallist); i != 0; i = i->next) {
- 5029 120 : struct snapraid_thermal* thermal = i->data;
- 5030 120 : if (out_temperature < thermal->latest_temperature) {
- 5031 4 : out_temperature = thermal->latest_temperature;
- 5032 4 : if (thermal->params.r_squared >= THERMAL_R_SQUARED_LIMIT)
- 5033 4 : out_steady = thermal->params.t_steady;
+ 5027 5 : out_temperature = 0;
+ 5028 155 : for (i = tommy_list_head(&state->thermallist); i != 0; i = i->next) {
+ 5029 150 : struct snapraid_thermal* thermal = i->data;
+ 5030 150 : if (out_temperature < thermal->latest_temperature) {
+ 5031 5 : out_temperature = thermal->latest_temperature;
+ 5032 5 : if (thermal->params.r_squared >= THERMAL_R_SQUARED_LIMIT)
+ 5033 5 : out_steady = thermal->params.t_steady;
5034 : else
5035 0 : out_steady = 0;
5036 : }
5037 : }
5038 : } else {
- 5039 184 : out_temperature = 0;
- 5040 184 : out_steady = 0;
+ 5039 172 : out_temperature = 0;
+ 5040 172 : out_steady = 0;
5041 : }
5042 :
5043 : /* we have the output value */
- 5044 188 : out_computed = 1;
+ 5044 177 : out_computed = 1;
5045 : }
5046 :
- 5047 391 : if (state->opt.gui) {
+ 5047 379 : if (state->opt.gui) {
5048 : char str_eta[32];
5049 : char str_size_speed[32];
5050 : char str_cpu[32];
5051 : char str_temp[32];
5052 : char str_steady[32];
- 5053 7 : if (out_computed) {
- 5054 3 : snprintf(str_eta, sizeof(str_eta), "%u", out_eta);
- 5055 3 : snprintf(str_size_speed, sizeof(str_size_speed), "%u", out_size_speed);
- 5056 3 : snprintf(str_cpu, sizeof(str_cpu), "%u", out_cpu);
+ 5053 8 : if (out_computed) {
+ 5054 4 : snprintf(str_eta, sizeof(str_eta), "%u", out_eta);
+ 5055 4 : snprintf(str_size_speed, sizeof(str_size_speed), "%u", out_size_speed);
+ 5056 4 : snprintf(str_cpu, sizeof(str_cpu), "%u", out_cpu);
5057 : } else {
5058 4 : str_eta[0] = 0;
5059 4 : str_size_speed[0] = 0;
5060 4 : str_cpu[0] = 0;
5061 : }
- 5062 7 : if (out_temperature) {
+ 5062 8 : if (out_temperature) {
5063 0 : snprintf(str_temp, sizeof(str_eta), "%u", out_temperature);
5064 : } else {
- 5065 7 : str_temp[0] = 0;
+ 5065 8 : str_temp[0] = 0;
5066 : }
- 5067 7 : if (out_steady) {
+ 5067 8 : if (out_steady) {
5068 0 : snprintf(str_steady, sizeof(str_steady), "%u", out_steady);
5069 : } else {
- 5070 7 : str_steady[0] = 0;
+ 5070 8 : str_steady[0] = 0;
5071 : }
- 5072 7 : log_tag("run:pos:%u:%u:%" PRIu64 ":%u:%s:%s:%s:%" PRIu64 ":%s:%s\n", blockpos, countpos, countsize, out_perc, str_eta, str_size_speed, str_cpu, (uint64_t)elapsed, str_temp, str_steady);
- 5073 7 : log_flush();
+ 5072 8 : log_tag("run:pos:%u:%u:%" PRIu64 ":%u:%s:%s:%s:%" PRIu64 ":%s:%s\n", blockpos, countpos, countsize, out_perc, str_eta, str_size_speed, str_cpu, (uint64_t)elapsed, str_temp, str_steady);
+ 5073 8 : log_flush();
5074 : } else {
- 5075 384 : msg_bar("%u%%, %u MB", out_perc, (unsigned)(countsize / MEGA));
- 5076 384 : if (out_computed) {
- 5077 185 : msg_bar(", %u MB/s", out_size_speed);
- 5078 185 : msg_bar(", %u stripe/s", out_block_speed);
- 5079 185 : msg_bar(", CPU %u%%", out_cpu);
- 5080 185 : if (out_temperature != 0) {
- 5081 4 : if (out_steady != 0)
- 5082 4 : msg_bar(", Tmax %u (%u)", out_temperature, out_steady);
+ 5075 371 : msg_bar("%u%%, %u MB", out_perc, (unsigned)(countsize / MEGA));
+ 5076 371 : if (out_computed) {
+ 5077 173 : msg_bar(", %u MB/s", out_size_speed);
+ 5078 173 : msg_bar(", %u stripe/s", out_block_speed);
+ 5079 173 : msg_bar(", CPU %u%%", out_cpu);
+ 5080 173 : if (out_temperature != 0) {
+ 5081 5 : if (out_steady != 0)
+ 5082 5 : msg_bar(", Tmax %u (%u)", out_temperature, out_steady);
5083 : else
5084 0 : msg_bar(", Tmax %u", out_temperature);
5085 : }
- 5086 185 : unsigned out_eta_minutes = out_eta / 60; /* minutes */
- 5087 185 : msg_bar(", %u:%02u ETA", out_eta_minutes / 60, out_eta_minutes % 60);
+ 5086 173 : unsigned out_eta_minutes = out_eta / 60; /* minutes */
+ 5087 173 : msg_bar(", %u:%02u ETA", out_eta_minutes / 60, out_eta_minutes % 60);
5088 : }
- 5089 384 : msg_bar("\r");
- 5090 384 : msg_flush();
+ 5089 371 : msg_bar("\r");
+ 5090 371 : msg_flush();
5091 : }
5092 :
5093 : /* next position to fill */
- 5094 391 : ++state->progress_ptr;
- 5095 391 : if (state->progress_ptr >= PROGRESS_MAX)
+ 5094 379 : ++state->progress_ptr;
+ 5095 379 : if (state->progress_ptr >= PROGRESS_MAX)
5096 0 : state->progress_ptr -= PROGRESS_MAX;
5097 :
5098 : /* one more measure */
- 5099 391 : ++state->progress_tick;
+ 5099 379 : ++state->progress_tick;
5100 : }
5101 :
5102 : /* stop if requested */
- 5103 1075966 : if (global_interrupt) {
+ 5103 1075903 : if (global_interrupt) {
5104 : /* LCOV_EXCL_START */
5105 : if (!state->opt.gui) {
5106 : log_fatal(EUSER, "\n");
@@ -5174,7 +5174,7 @@
5112 : /* LCOV_EXCL_STOP */
5113 : }
5114 :
- 5115 1075966 : return 0;
+ 5115 1075903 : return 0;
5116 : }
5117 :
5118 110 : void state_usage_waste(struct snapraid_state* state)
@@ -5184,90 +5184,90 @@
5122 110 : state->tick_last = now;
5123 110 : }
5124 :
- 5125 1071293 : void state_usage_misc(struct snapraid_state* state)
+ 5125 1070853 : void state_usage_misc(struct snapraid_state* state)
5126 : {
- 5127 1071293 : uint64_t now = tick();
- 5128 1071293 : uint64_t delta = now - state->tick_last;
+ 5127 1070853 : uint64_t now = tick();
+ 5128 1070853 : uint64_t delta = now - state->tick_last;
5129 :
5130 : /* increment the time spent in computations */
- 5131 1071293 : state->tick_misc += delta;
+ 5131 1070853 : state->tick_misc += delta;
5132 :
- 5133 1071293 : state->tick_last = now;
- 5134 1071293 : }
+ 5133 1070853 : state->tick_last = now;
+ 5134 1070853 : }
5135 :
- 5136 151013 : void state_usage_sched(struct snapraid_state* state)
+ 5136 150950 : void state_usage_sched(struct snapraid_state* state)
5137 : {
- 5138 151013 : uint64_t now = tick();
- 5139 151013 : uint64_t delta = now - state->tick_last;
+ 5138 150950 : uint64_t now = tick();
+ 5139 150950 : uint64_t delta = now - state->tick_last;
5140 :
5141 : /* increment the time spent in computations */
- 5142 151013 : state->tick_sched += delta;
+ 5142 150950 : state->tick_sched += delta;
5143 :
- 5144 151013 : state->tick_last = now;
- 5145 151013 : }
+ 5144 150950 : state->tick_last = now;
+ 5145 150950 : }
5146 :
- 5147 140496 : void state_usage_raid(struct snapraid_state* state)
+ 5147 140445 : void state_usage_raid(struct snapraid_state* state)
5148 : {
- 5149 140496 : uint64_t now = tick();
- 5150 140496 : uint64_t delta = now - state->tick_last;
+ 5149 140445 : uint64_t now = tick();
+ 5150 140445 : uint64_t delta = now - state->tick_last;
5151 :
5152 : /* increment the time spent in computations */
- 5153 140496 : state->tick_raid += delta;
+ 5153 140445 : state->tick_raid += delta;
5154 :
- 5155 140496 : state->tick_last = now;
- 5156 140496 : }
+ 5155 140445 : state->tick_last = now;
+ 5156 140445 : }
5157 :
- 5158 753854 : void state_usage_hash(struct snapraid_state* state)
+ 5158 753469 : void state_usage_hash(struct snapraid_state* state)
5159 : {
- 5160 753854 : uint64_t now = tick();
- 5161 753854 : uint64_t delta = now - state->tick_last;
+ 5160 753469 : uint64_t now = tick();
+ 5161 753469 : uint64_t delta = now - state->tick_last;
5162 :
5163 : /* increment the time spent in computations */
- 5164 753854 : state->tick_hash += delta;
+ 5164 753469 : state->tick_hash += delta;
5165 :
- 5166 753854 : state->tick_last = now;
- 5167 753854 : }
+ 5166 753469 : state->tick_last = now;
+ 5167 753469 : }
5168 :
- 5169 914732 : void state_usage_file(struct snapraid_state* state, struct snapraid_disk* disk, struct snapraid_file* file)
+ 5169 914354 : void state_usage_file(struct snapraid_state* state, struct snapraid_disk* disk, struct snapraid_file* file)
5170 : {
5171 : (void)state;
5172 :
- 5173 914732 : disk->progress_file = file;
- 5174 914732 : }
+ 5173 914354 : disk->progress_file = file;
+ 5174 914354 : }
5175 :
- 5176 919419 : void state_usage_disk(struct snapraid_state* state, struct snapraid_handle* handle_map, unsigned* waiting_map, unsigned waiting_mac)
+ 5176 919041 : void state_usage_disk(struct snapraid_state* state, struct snapraid_handle* handle_map, unsigned* waiting_map, unsigned waiting_mac)
5177 : {
- 5178 919419 : uint64_t now = tick();
- 5179 919419 : uint64_t delta = now - state->tick_last;
+ 5178 919041 : uint64_t now = tick();
+ 5179 919041 : uint64_t delta = now - state->tick_last;
5180 : unsigned i;
5181 :
5182 : /* increment the time spent in the data disks */
- 5183 961474 : for (i = 0; i < waiting_mac; ++i) {
- 5184 42055 : struct snapraid_disk* disk = handle_map[waiting_map[i]].disk;
+ 5183 961157 : for (i = 0; i < waiting_mac; ++i) {
+ 5184 42116 : struct snapraid_disk* disk = handle_map[waiting_map[i]].disk;
5185 :
- 5186 42055 : if (!disk)
+ 5186 42116 : if (!disk)
5187 0 : continue;
5188 :
- 5189 42055 : disk->tick += delta;
+ 5189 42116 : disk->tick += delta;
5190 : }
- 5191 919419 : state->tick_io += delta;
+ 5191 919041 : state->tick_io += delta;
5192 :
- 5193 919419 : state->tick_last = now;
- 5194 919419 : }
+ 5193 919041 : state->tick_last = now;
+ 5194 919041 : }
5195 :
- 5196 781079 : void state_usage_parity(struct snapraid_state* state, unsigned* waiting_map, unsigned waiting_mac)
+ 5196 780707 : void state_usage_parity(struct snapraid_state* state, unsigned* waiting_map, unsigned waiting_mac)
5197 : {
- 5198 781079 : uint64_t now = tick();
- 5199 781079 : uint64_t delta = now - state->tick_last;
+ 5198 780707 : uint64_t now = tick();
+ 5199 780707 : uint64_t delta = now - state->tick_last;
5200 : unsigned i;
5201 :
5202 : /* increment the time spent in the parity disk */
- 5203 790921 : for (i = 0; i < waiting_mac; ++i)
- 5204 9842 : state->parity[waiting_map[i]].tick += delta;
- 5205 781079 : state->tick_io += delta;
+ 5203 790636 : for (i = 0; i < waiting_mac; ++i)
+ 5204 9929 : state->parity[waiting_map[i]].tick += delta;
+ 5205 780707 : state->tick_io += delta;
5206 :
- 5207 781079 : state->tick_last = now;
- 5208 781079 : }
+ 5207 780707 : state->tick_last = now;
+ 5208 780707 : }
5209 :
5210 102 : void state_usage_print(struct snapraid_state* state)
5211 : {
@@ -5281,22 +5281,22 @@
5219 1 : state_progress_graph(state, 0, state->progress_ptr, PROGRESS_MAX);
5220 : }
5221 :
- 5222 521 : void state_fscheck(struct snapraid_state* state, const char* ope)
+ 5222 520 : void state_fscheck(struct snapraid_state* state, const char* ope)
5223 : {
5224 : tommy_node* i;
5225 :
5226 : /* check the file-system on all disks */
- 5227 3641 : for (i = state->disklist; i != 0; i = i->next) {
- 5228 3120 : struct snapraid_disk* disk = i->data;
+ 5227 3634 : for (i = state->disklist; i != 0; i = i->next) {
+ 5228 3114 : struct snapraid_disk* disk = i->data;
5229 :
- 5230 3120 : if (fs_check(disk) != 0) {
+ 5230 3114 : if (fs_check(disk) != 0) {
5231 : /* LCOV_EXCL_START */
5232 : log_fatal(EINTERNAL, "Internal inconsistency: File-system check for disk '%s' %s\n", disk->name, ope);
5233 : os_abort();
5234 : /* LCOV_EXCL_STOP */
5235 : }
5236 : }
- 5237 521 : }
+ 5237 520 : }
5238 :
5239 1 : void generate_configuration(const char* path)
5240 : {
diff --git a/cov/cmdline/status.c.func-sort-c.html b/cov/cmdline/status.c.func-sort-c.html
index 98428a8a..bbff8974 100644
--- a/cov/cmdline/status.c.func-sort-c.html
+++ b/cov/cmdline/status.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/cmdline/status.c.func.html b/cov/cmdline/status.c.func.html
index a6973a39..e8c15562 100644
--- a/cov/cmdline/status.c.func.html
+++ b/cov/cmdline/status.c.func.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/cmdline/status.c.gcov.html b/cov/cmdline/status.c.gcov.html
index 458a4da3..c5fcd73b 100644
--- a/cov/cmdline/status.c.gcov.html
+++ b/cov/cmdline/status.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -148,7 +148,7 @@
86 90 : log_tag("summary:parity_block_total:%s:%u\n", lev_config_name(l), state->parity[l].total_blocks);
87 90 : log_tag("summary:parity_block_free:%s:%u\n", lev_config_name(l), state->parity[l].free_blocks);
88 90 : if (state->parity[l].free_blocks < parity_block_free)
- 89 4 : parity_block_free = state->parity[l].free_blocks;
+ 89 1 : parity_block_free = state->parity[l].free_blocks;
90 90 : if (state->parity[l].free_blocks != 0)
91 79 : free_not_zero = 1;
92 : }
@@ -226,7 +226,7 @@
164 : /* keep track of latest block used */
165 95396 : last_pos = fs_file2par_get(disk, file, file->blockmax - 1);
166 95396 : if (last_pos > disk_block_latest_used) {
- 167 92536 : disk_block_latest_used = last_pos;
+ 167 92537 : disk_block_latest_used = last_pos;
168 : }
169 :
170 95396 : if (fragmented) {
@@ -348,17 +348,17 @@
286 15 : median = 0;
287 15 : newest = 0;
288 15 : count = 0;
- 289 32 : for (tommy_node* j = tommy_list_head(&state->bucketlist); j != 0; j = j->next) {
- 290 17 : struct snapraid_bucket* bucket = j->data;
- 291 17 : block_off_t bucket_count = bucket->count_scrubbed + bucket->count_justsynced;
+ 289 30 : for (tommy_node* j = tommy_list_head(&state->bucketlist); j != 0; j = j->next) {
+ 290 15 : struct snapraid_bucket* bucket = j->data;
+ 291 15 : block_off_t bucket_count = bucket->count_scrubbed + bucket->count_justsynced;
292 :
- 293 17 : if (count == 0)
+ 293 15 : if (count == 0)
294 9 : oldest = bucket->time_at;
- 295 17 : if (count < state->bucketcount / 2)
- 296 14 : median = bucket->time_at;
- 297 17 : newest = bucket->time_at;
+ 295 15 : if (count < state->bucketcount / 2)
+ 296 12 : median = bucket->time_at;
+ 297 15 : newest = bucket->time_at;
298 :
- 299 17 : count += bucket_count;
+ 299 15 : count += bucket_count;
300 : }
301 :
302 15 : if (!count) {
@@ -378,15 +378,15 @@
316 9 : barmax = 0;
317 9 : memset(bar_scrubbed, 0, sizeof(bar_scrubbed));
318 9 : memset(bar_new, 0, sizeof(bar_new));
- 319 26 : for (tommy_node* j = tommy_list_head(&state->bucketlist); j != 0; j = j->next) {
- 320 17 : struct snapraid_bucket* bucket = j->data;
+ 319 24 : for (tommy_node* j = tommy_list_head(&state->bucketlist); j != 0; j = j->next) {
+ 320 15 : struct snapraid_bucket* bucket = j->data;
321 :
- 322 17 : unsigned column = muldiv(bucket->time_at - oldest, GRAPH_COLUMN, newest - oldest + 1);
+ 322 15 : unsigned column = muldiv(bucket->time_at - oldest, GRAPH_COLUMN, newest - oldest + 1);
323 :
- 324 17 : bar_scrubbed[column] += bucket->count_scrubbed;
- 325 17 : bar_new[column] += bucket->count_justsynced;
+ 324 15 : bar_scrubbed[column] += bucket->count_scrubbed;
+ 325 15 : bar_new[column] += bucket->count_justsynced;
326 :
- 327 17 : if (bar_scrubbed[column] + bar_new[column] > barmax)
+ 327 15 : if (bar_scrubbed[column] + bar_new[column] > barmax)
328 12 : barmax = bar_scrubbed[column] + bar_new[column];
329 : }
330 :
@@ -416,20 +416,20 @@
354 9450 : unsigned scrubbed = bar_scrubbed[x];
355 :
356 9450 : if (both > pivot_upper) {
- 357 156 : if (scrubbed > pivot_lower)
+ 357 157 : if (scrubbed > pivot_lower)
358 60 : printf("*");
359 : else
- 360 96 : printf("o");
- 361 9294 : } else if (both > pivot_lower) {
- 362 17 : if (scrubbed == both)
+ 360 97 : printf("o");
+ 361 9293 : } else if (both > pivot_lower) {
+ 362 15 : if (scrubbed == both)
363 6 : printf("*");
364 : else
- 365 11 : printf("o");
+ 365 9 : printf("o");
366 : } else {
- 367 9277 : if (y == GRAPH_ROW - 1)
- 368 613 : printf("_");
+ 367 9278 : if (y == GRAPH_ROW - 1)
+ 368 615 : printf("_");
369 : else
- 370 8664 : printf(" ");
+ 370 8663 : printf(" ");
371 : }
372 : }
373 135 : printf("\n");
@@ -491,27 +491,27 @@
429 2 : bad_count = 0;
430 2 : range_start = 0;
431 2 : range_count = 0;
- 432 887 : for (i = 0; i <= blockmax; ++i) { /* one extra iteration to print the final range */
- 433 887 : snapraid_info info = 0;
- 434 887 : int is_bad = 0;
+ 432 894 : for (i = 0; i <= blockmax; ++i) { /* one extra iteration to print the final range */
+ 433 894 : snapraid_info info = 0;
+ 434 894 : int is_bad = 0;
435 :
- 436 887 : if (i < blockmax) {
- 437 887 : info = info_get(&state->infoarr, i);
- 438 887 : if (info != 0) /* unused blocks are never bad */
- 439 887 : is_bad = info_get_bad(info);
+ 436 894 : if (i < blockmax) {
+ 437 894 : info = info_get(&state->infoarr, i);
+ 438 894 : if (info != 0) /* unused blocks are never bad */
+ 439 894 : is_bad = info_get_bad(info);
440 : }
- 441 887 : if (is_bad) {
+ 441 894 : if (is_bad) {
442 : /* create or extend the range */
- 443 259 : if (!range_count)
+ 443 263 : if (!range_count)
444 202 : range_start = i;
- 445 259 : ++range_count;
+ 445 263 : ++range_count;
446 : } else {
447 : /* break the range */
- 448 628 : if (range_count) {
+ 448 631 : if (range_count) {
449 202 : if (range_count == 1) {
- 450 153 : printf(" %u", range_start);
+ 450 155 : printf(" %u", range_start);
451 : } else {
- 452 49 : printf(" %u-%u", range_start, range_start + range_count - 1);
+ 452 47 : printf(" %u-%u", range_start, range_start + range_count - 1);
453 : }
454 202 : bad_count += range_count;
455 202 : ++bad_range;
@@ -519,7 +519,7 @@
457 : }
458 : }
459 :
- 460 887 : if (bad_range > 100) {
+ 460 894 : if (bad_range > 100) {
461 2 : printf(" and %u more...", state->bad_blocks - bad_count);
462 2 : break;
463 : }
diff --git a/cov/cmdline/stream.c.func-sort-c.html b/cov/cmdline/stream.c.func-sort-c.html
index fa9c6041..740c4771 100644
--- a/cov/cmdline/stream.c.func-sort-c.html
+++ b/cov/cmdline/stream.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -69,19 +69,19 @@
| ssync |
- 157 |
+ 156 |
| scrc_stream |
- 173 |
+ 172 |
| sopen_multi_write |
- 173 |
+ 172 |
| sputble32 |
- 173 |
+ 172 |
| shandle |
@@ -89,7 +89,7 @@
| sgetu32 |
- 280 |
+ 283 |
| sgetble32 |
@@ -97,79 +97,79 @@
| sopen_multi_file |
- 1182 |
+ 1175 |
| sdeplete |
- 1183 |
+ 1176 |
| scrc |
- 1748 |
+ 1740 |
| sopen_read |
- 1903 |
+ 1897 |
| sclose |
- 2024 |
+ 2017 |
| sgetlasttok |
- 5663 |
+ 5686 |
| sgetline |
- 5706 |
+ 5738 |
| sgettok |
- 9875 |
+ 9929 |
| sflush |
- 39158 |
+ 39136 |
| sgetc_uncached |
- 299093 |
+ 299099 |
| sfill |
- 608081 |
+ 607940 |
| sputbs |
- 1982279 |
+ 1964370 |
| sgetbs |
- 4004187 |
+ 4004224 |
| sputb64 |
- 5572622 |
+ 5517420 |
| sputb32 |
- 9508972 |
+ 9413354 |
| sgetb64 |
- 11258012 |
+ 11246935 |
| sread |
- 13236843 |
+ 13236979 |
| sgetb32 |
- 19212483 |
+ 19190230 |
| swrite |
- 21650829 |
+ 21440832 |
diff --git a/cov/cmdline/stream.c.func.html b/cov/cmdline/stream.c.func.html
index e4e635a3..81e17132 100644
--- a/cov/cmdline/stream.c.func.html
+++ b/cov/cmdline/stream.c.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,35 +61,35 @@
| sclose |
- 2024 |
+ 2017 |
| scrc |
- 1748 |
+ 1740 |
| scrc_stream |
- 173 |
+ 172 |
| sdeplete |
- 1183 |
+ 1176 |
| sfill |
- 608081 |
+ 607940 |
| sflush |
- 39158 |
+ 39136 |
| sgetb32 |
- 19212483 |
+ 19190230 |
| sgetb64 |
- 11258012 |
+ 11246935 |
| sgetble32 |
@@ -97,27 +97,27 @@
| sgetbs |
- 4004187 |
+ 4004224 |
| sgetc_uncached |
- 299093 |
+ 299099 |
| sgetlasttok |
- 5663 |
+ 5686 |
| sgetline |
- 5706 |
+ 5738 |
| sgettok |
- 9875 |
+ 9929 |
| sgetu32 |
- 280 |
+ 283 |
| shandle |
@@ -125,15 +125,15 @@
| sopen_multi_file |
- 1182 |
+ 1175 |
| sopen_multi_write |
- 173 |
+ 172 |
| sopen_read |
- 1903 |
+ 1897 |
| sopen_write |
@@ -141,27 +141,27 @@
| sputb32 |
- 9508972 |
+ 9413354 |
| sputb64 |
- 5572622 |
+ 5517420 |
| sputble32 |
- 173 |
+ 172 |
| sputbs |
- 1982279 |
+ 1964370 |
| sread |
- 13236843 |
+ 13236979 |
| ssync |
- 157 |
+ 156 |
| stell |
@@ -169,7 +169,7 @@
| swrite |
- 21650829 |
+ 21440832 |
diff --git a/cov/cmdline/stream.c.gcov.html b/cov/cmdline/stream.c.gcov.html
index 6b451924..7db6643f 100644
--- a/cov/cmdline/stream.c.gcov.html
+++ b/cov/cmdline/stream.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -88,50 +88,50 @@
26 :
27 : unsigned STREAM_SIZE = 64 * 1024;
28 :
- 29 1903 : STREAM* sopen_read(const char* file, int flags)
+ 29 1897 : STREAM* sopen_read(const char* file, int flags)
30 : {
31 : #if HAVE_POSIX_FADVISE
32 : int ret;
33 : #endif
- 34 1903 : STREAM* s = malloc_nofail(sizeof(STREAM));
+ 34 1897 : STREAM* s = malloc_nofail(sizeof(STREAM));
35 : struct stat st;
36 :
- 37 1903 : s->handle_size = 1;
- 38 1903 : s->handle = malloc_nofail(sizeof(struct stream_handle));
- 39 1903 : s->flags = flags;
+ 37 1897 : s->handle_size = 1;
+ 38 1897 : s->handle = malloc_nofail(sizeof(struct stream_handle));
+ 39 1897 : s->flags = flags;
40 :
- 41 1903 : int open_flags = O_RDONLY | O_BINARY;
- 42 1903 : if (s->flags & STREAM_FLAGS_SEQUENTIAL)
- 43 1369 : open_flags |= O_SEQUENTIAL;
+ 41 1897 : int open_flags = O_RDONLY | O_BINARY;
+ 42 1897 : if (s->flags & STREAM_FLAGS_SEQUENTIAL)
+ 43 1362 : open_flags |= O_SEQUENTIAL;
44 :
- 45 1903 : pathcpy(s->handle[0].path, sizeof(s->handle[0].path), file);
- 46 1903 : s->handle[0].f = open(file, open_flags);
- 47 1903 : if (s->handle[0].f == -1) {
+ 45 1897 : pathcpy(s->handle[0].path, sizeof(s->handle[0].path), file);
+ 46 1897 : s->handle[0].f = open(file, open_flags);
+ 47 1897 : if (s->handle[0].f == -1) {
48 50 : free(s->handle);
49 50 : free(s);
50 50 : return 0;
51 : }
52 :
53 : /* get file info */
- 54 1853 : if (fstat(s->handle[0].f, &st) != 0) {
+ 54 1847 : if (fstat(s->handle[0].f, &st) != 0) {
55 0 : close(s->handle[0].f);
56 0 : free(s->handle);
57 0 : free(s);
58 0 : return 0;
59 : }
60 :
- 61 1853 : s->size = st.st_size;
+ 61 1847 : s->size = st.st_size;
62 :
63 : #if HAVE_POSIX_FADVISE
- 64 1853 : if (s->flags & STREAM_FLAGS_SEQUENTIAL) {
+ 64 1847 : if (s->flags & STREAM_FLAGS_SEQUENTIAL) {
65 : /* advise sequential access */
- 66 1319 : ret = posix_fadvise(s->handle[0].f, 0, 0, POSIX_FADV_SEQUENTIAL);
- 67 1319 : if (ret == ENOSYS) {
+ 66 1312 : ret = posix_fadvise(s->handle[0].f, 0, 0, POSIX_FADV_SEQUENTIAL);
+ 67 1312 : if (ret == ENOSYS) {
68 0 : log_fatal(errno, "WARNING! fadvise() is not supported in this platform. Performance may not be optimal!\n");
69 : /* call is not supported, like in armhf, see posix_fadvise manpage */
70 0 : ret = 0;
71 : }
- 72 1319 : if (ret != 0) {
+ 72 1312 : if (ret != 0) {
73 : /* LCOV_EXCL_START */
74 : close(s->handle[0].f);
75 : free(s->handle);
@@ -143,82 +143,82 @@
81 : }
82 : #endif
83 :
- 84 1853 : s->buffer_size = STREAM_SIZE;
- 85 1853 : if (s->buffer_size > s->size)
- 86 473 : s->buffer_size = s->size; /* allocate only what is necessary */
- 87 1853 : s->buffer = malloc_nofail_test(s->buffer_size);
- 88 1853 : s->pos = s->buffer;
- 89 1853 : s->end = s->buffer;
- 90 1853 : s->state = STREAM_STATE_READ;
- 91 1853 : s->state_index = 0;
- 92 1853 : s->offset = 0;
- 93 1853 : s->offset_uncached = 0;
- 94 1853 : s->crc = 0;
- 95 1853 : s->crc_uncached = 0;
- 96 1853 : s->crc_stream = CRC_IV;
+ 84 1847 : s->buffer_size = STREAM_SIZE;
+ 85 1847 : if (s->buffer_size > s->size)
+ 86 474 : s->buffer_size = s->size; /* allocate only what is necessary */
+ 87 1847 : s->buffer = malloc_nofail_test(s->buffer_size);
+ 88 1847 : s->pos = s->buffer;
+ 89 1847 : s->end = s->buffer;
+ 90 1847 : s->state = STREAM_STATE_READ;
+ 91 1847 : s->state_index = 0;
+ 92 1847 : s->offset = 0;
+ 93 1847 : s->offset_uncached = 0;
+ 94 1847 : s->crc = 0;
+ 95 1847 : s->crc_uncached = 0;
+ 96 1847 : s->crc_stream = CRC_IV;
97 :
- 98 1853 : return s;
+ 98 1847 : return s;
99 : }
100 :
- 101 173 : STREAM* sopen_multi_write(unsigned count, int flags)
+ 101 172 : STREAM* sopen_multi_write(unsigned count, int flags)
102 : {
103 : unsigned i;
104 :
- 105 173 : STREAM* s = malloc_nofail(sizeof(STREAM));
+ 105 172 : STREAM* s = malloc_nofail(sizeof(STREAM));
106 :
- 107 173 : s->handle_size = count;
- 108 173 : s->handle = malloc_nofail(count * sizeof(struct stream_handle));
- 109 173 : s->flags = flags;
+ 107 172 : s->handle_size = count;
+ 108 172 : s->handle = malloc_nofail(count * sizeof(struct stream_handle));
+ 109 172 : s->flags = flags;
110 :
- 111 1355 : for (i = 0; i < count; ++i)
- 112 1182 : s->handle[i].f = -1;
+ 111 1347 : for (i = 0; i < count; ++i)
+ 112 1175 : s->handle[i].f = -1;
113 :
- 114 173 : s->buffer_size = STREAM_SIZE;
- 115 173 : s->buffer = malloc_nofail_test(s->buffer_size);
- 116 173 : s->pos = s->buffer;
- 117 173 : s->end = s->buffer + s->buffer_size;
- 118 173 : s->state = STREAM_STATE_WRITE;
- 119 173 : s->state_index = 0;
- 120 173 : s->size = 0;
- 121 173 : s->offset = 0;
- 122 173 : s->offset_uncached = 0;
- 123 173 : s->crc = 0;
- 124 173 : s->crc_uncached = 0;
- 125 173 : s->crc_stream = CRC_IV;
+ 114 172 : s->buffer_size = STREAM_SIZE;
+ 115 172 : s->buffer = malloc_nofail_test(s->buffer_size);
+ 116 172 : s->pos = s->buffer;
+ 117 172 : s->end = s->buffer + s->buffer_size;
+ 118 172 : s->state = STREAM_STATE_WRITE;
+ 119 172 : s->state_index = 0;
+ 120 172 : s->size = 0;
+ 121 172 : s->offset = 0;
+ 122 172 : s->offset_uncached = 0;
+ 123 172 : s->crc = 0;
+ 124 172 : s->crc_uncached = 0;
+ 125 172 : s->crc_stream = CRC_IV;
126 :
- 127 173 : return s;
+ 127 172 : return s;
128 : }
129 :
- 130 1182 : int sopen_multi_file(STREAM* s, unsigned i, const char* file)
+ 130 1175 : int sopen_multi_file(STREAM* s, unsigned i, const char* file)
131 : {
132 : #if HAVE_POSIX_FADVISE
133 : int ret;
134 : #endif
135 : int f;
136 :
- 137 1182 : pathcpy(s->handle[i].path, sizeof(s->handle[i].path), file);
+ 137 1175 : pathcpy(s->handle[i].path, sizeof(s->handle[i].path), file);
138 :
- 139 1182 : int open_flags = O_WRONLY | O_CREAT | O_EXCL | O_BINARY;
- 140 1182 : if (s->flags & STREAM_FLAGS_SEQUENTIAL)
- 141 1054 : open_flags |= O_SEQUENTIAL; ;
+ 139 1175 : int open_flags = O_WRONLY | O_CREAT | O_EXCL | O_BINARY;
+ 140 1175 : if (s->flags & STREAM_FLAGS_SEQUENTIAL)
+ 141 1047 : open_flags |= O_SEQUENTIAL; ;
142 :
143 : /* O_EXCL to be resilient ensure to always create a new file and not use a stale link to the original file */
- 144 1182 : f = open(file, open_flags, 0600);
- 145 1182 : if (f == -1) {
+ 144 1175 : f = open(file, open_flags, 0600);
+ 145 1175 : if (f == -1) {
146 : /* LCOV_EXCL_START */
147 : return -1;
148 : /* LCOV_EXCL_STOP */
149 : }
150 :
151 : #if HAVE_POSIX_FADVISE
- 152 1182 : if (s->flags & STREAM_FLAGS_SEQUENTIAL) {
+ 152 1175 : if (s->flags & STREAM_FLAGS_SEQUENTIAL) {
153 : /* advise sequential access */
- 154 1054 : ret = posix_fadvise(f, 0, 0, POSIX_FADV_SEQUENTIAL);
- 155 1054 : if (ret == ENOSYS) {
+ 154 1047 : ret = posix_fadvise(f, 0, 0, POSIX_FADV_SEQUENTIAL);
+ 155 1047 : if (ret == ENOSYS) {
156 : /* call is not supported, like in armhf, see posix_fadvise manpage */
157 0 : ret = 0;
158 : }
- 159 1054 : if (ret != 0) {
+ 159 1047 : if (ret != 0) {
160 : /* LCOV_EXCL_START */
161 : close(f);
162 : errno = ret; /* posix_fadvise return the error code */
@@ -228,9 +228,9 @@
166 : }
167 : #endif
168 :
- 169 1182 : s->handle[i].f = f;
+ 169 1175 : s->handle[i].f = f;
170 :
- 171 1182 : return 0;
+ 171 1175 : return 0;
172 : }
173 :
174 0 : STREAM* sopen_write(const char* file, int flags)
@@ -245,38 +245,38 @@
183 0 : return s;
184 : }
185 :
- 186 2024 : int sclose(STREAM* s)
+ 186 2017 : int sclose(STREAM* s)
187 : {
- 188 2024 : int fail = 0;
+ 188 2017 : int fail = 0;
189 : unsigned i;
190 :
- 191 2024 : if (s->state == STREAM_STATE_WRITE) {
- 192 173 : if (sflush(s) != 0) {
+ 191 2017 : if (s->state == STREAM_STATE_WRITE) {
+ 192 172 : if (sflush(s) != 0) {
193 : /* LCOV_EXCL_START */
194 : fail = 1;
195 : /* LCOV_EXCL_STOP */
196 : }
197 : }
198 :
- 199 5057 : for (i = 0; i < s->handle_size; ++i) {
- 200 3033 : if (close(s->handle[i].f) != 0) {
+ 199 5037 : for (i = 0; i < s->handle_size; ++i) {
+ 200 3020 : if (close(s->handle[i].f) != 0) {
201 : /* LCOV_EXCL_START */
202 : fail = 1;
203 : /* LCOV_EXCL_STOP */
204 : }
205 : }
206 :
- 207 2024 : free(s->handle);
- 208 2024 : free(s->buffer);
- 209 2024 : free(s);
+ 207 2017 : free(s->handle);
+ 208 2017 : free(s->buffer);
+ 209 2017 : free(s);
210 :
- 211 2024 : if (fail) {
+ 211 2017 : if (fail) {
212 : /* LCOV_EXCL_START */
213 : return -1;
214 : /* LCOV_EXCL_STOP */
215 : }
216 :
- 217 2024 : return 0;
+ 217 2017 : return 0;
218 : }
219 :
220 265 : int shandle(STREAM* s)
@@ -294,30 +294,30 @@
232 : * Fill the read stream buffer.
233 : * \return 0 if at least on char is read, or EOF on error.
234 : */
- 235 608081 : static int sfill(STREAM* s)
+ 235 607940 : static int sfill(STREAM* s)
236 : {
237 : ssize_t ret;
238 :
- 239 608081 : if (s->state != STREAM_STATE_READ) {
+ 239 607940 : if (s->state != STREAM_STATE_READ) {
240 : /* LCOV_EXCL_START */
241 : return EOF;
242 : /* LCOV_EXCL_STOP */
243 : }
244 :
245 : /* if we reached the end, doesn't try to read */
- 246 608081 : if (s->offset >= s->size) {
- 247 2832 : return EOF;
+ 246 607940 : if (s->offset >= s->size) {
+ 247 2830 : return EOF;
248 : }
249 :
- 250 605249 : ret = read(s->handle[0].f, s->buffer, s->buffer_size);
+ 250 605110 : ret = read(s->handle[0].f, s->buffer, s->buffer_size);
251 :
- 252 605249 : if (ret < 0) {
+ 252 605110 : if (ret < 0) {
253 : /* LCOV_EXCL_START */
254 : s->state = STREAM_STATE_ERROR;
255 : return EOF;
256 : /* LCOV_EXCL_STOP */
257 : }
- 258 605249 : if (ret == 0) {
+ 258 605110 : if (ret == 0) {
259 : /* nothing mode to read */
260 0 : s->state = STREAM_STATE_EOF;
261 0 : return EOF;
@@ -325,79 +325,79 @@
263 : /* assume that it can be a shorter read, so ret < s->buffer_size doesn't mean that we reached EOF */
264 :
265 : /* update the crc */
- 266 605249 : if (s->flags & STREAM_FLAGS_CRC) {
- 267 604971 : s->crc_uncached = s->crc;
- 268 604971 : s->crc = crc32c(s->crc, s->buffer, ret);
+ 266 605110 : if (s->flags & STREAM_FLAGS_CRC) {
+ 267 604831 : s->crc_uncached = s->crc;
+ 268 604831 : s->crc = crc32c(s->crc, s->buffer, ret);
269 : }
270 :
271 : /* update the offset */
- 272 605249 : s->offset_uncached = s->offset;
- 273 605249 : s->offset += ret;
+ 272 605110 : s->offset_uncached = s->offset;
+ 273 605110 : s->offset += ret;
274 :
- 275 605249 : s->pos = s->buffer;
- 276 605249 : s->end = s->buffer + ret;
+ 275 605110 : s->pos = s->buffer;
+ 276 605110 : s->end = s->buffer + ret;
277 :
- 278 605249 : return 0;
+ 278 605110 : return 0;
279 : }
280 :
- 281 1183 : int sdeplete(STREAM* s, unsigned char* last)
+ 281 1176 : int sdeplete(STREAM* s, unsigned char* last)
282 : {
283 : /* last four bytes */
- 284 1183 : last[0] = 0;
- 285 1183 : last[1] = 0;
- 286 1183 : last[2] = 0;
- 287 1183 : last[3] = 0;
+ 284 1176 : last[0] = 0;
+ 285 1176 : last[1] = 0;
+ 286 1176 : last[2] = 0;
+ 287 1176 : last[3] = 0;
288 :
289 : while (1) {
290 : /* increase the position up to 4 bytes before the end */
- 291 308988 : if (s->pos + 4 <= s->end)
- 292 149070 : s->pos = s->end - 4;
+ 291 308841 : if (s->pos + 4 <= s->end)
+ 292 148930 : s->pos = s->end - 4;
293 :
294 : /* insert the last 4 bytes */
- 295 1165036 : while (s->pos < s->end) {
- 296 856048 : last[0] = last[1];
- 297 856048 : last[1] = last[2];
- 298 856048 : last[2] = last[3];
- 299 856048 : last[3] = *s->pos++;
+ 295 1164329 : while (s->pos < s->end) {
+ 296 855488 : last[0] = last[1];
+ 297 855488 : last[1] = last[2];
+ 298 855488 : last[2] = last[3];
+ 299 855488 : last[3] = *s->pos++;
300 : }
301 :
302 : /* fill again the buffer until the end of the file */
- 303 308988 : if (sfill(s) != 0) {
+ 303 308841 : if (sfill(s) != 0) {
304 : /* on error fail */
- 305 1183 : if (serror(s)) {
+ 305 1176 : if (serror(s)) {
306 : /* LCOV_EXCL_START */
307 : return EOF;
308 : /* LCOV_EXCL_STOP */
309 : }
310 :
311 : /* on EOF terminate */
- 312 1183 : break;
+ 312 1176 : break;
313 : }
314 : }
315 :
- 316 1183 : return 0;
+ 316 1176 : return 0;
317 : }
318 :
- 319 39158 : int sflush(STREAM* s)
+ 319 39136 : int sflush(STREAM* s)
320 : {
321 : ssize_t ret;
322 : ssize_t size;
323 : unsigned i;
324 :
- 325 39158 : if (s->state != STREAM_STATE_WRITE) {
+ 325 39136 : if (s->state != STREAM_STATE_WRITE) {
326 : /* LCOV_EXCL_START */
327 : return EOF;
328 : /* LCOV_EXCL_STOP */
329 : }
330 :
- 331 39158 : size = s->pos - s->buffer;
- 332 39158 : if (!size)
- 333 157 : return 0;
+ 331 39136 : size = s->pos - s->buffer;
+ 332 39136 : if (!size)
+ 333 156 : return 0;
334 :
- 335 347847 : for (i = 0; i < s->handle_size; ++i) {
- 336 308846 : ret = write(s->handle[i].f, s->buffer, size);
+ 335 347679 : for (i = 0; i < s->handle_size; ++i) {
+ 336 308699 : ret = write(s->handle[i].f, s->buffer, size);
337 :
- 338 308846 : if (ret != size) {
+ 338 308699 : if (ret != size) {
339 : /* LCOV_EXCL_START */
340 : s->state = STREAM_STATE_ERROR;
341 : s->state_index = i;
@@ -413,18 +413,18 @@
351 : * to be able to detect memory errors on the buffer,
352 : * happening during the write.
353 : */
- 354 39001 : if (s->flags & STREAM_FLAGS_CRC) {
- 355 39001 : s->crc = crc32c(s->crc, s->buffer, size);
- 356 39001 : s->crc_uncached = s->crc;
+ 354 38980 : if (s->flags & STREAM_FLAGS_CRC) {
+ 355 38980 : s->crc = crc32c(s->crc, s->buffer, size);
+ 356 38980 : s->crc_uncached = s->crc;
357 : }
358 :
359 : /* update the offset */
- 360 39001 : s->offset += size;
- 361 39001 : s->offset_uncached = s->offset;
+ 360 38980 : s->offset += size;
+ 361 38980 : s->offset_uncached = s->offset;
362 :
- 363 39001 : s->pos = s->buffer;
+ 363 38980 : s->pos = s->buffer;
364 :
- 365 39001 : return 0;
+ 365 38980 : return 0;
366 : }
367 :
368 1 : int64_t stell(STREAM* s)
@@ -432,102 +432,102 @@
370 1 : return s->offset_uncached + (s->pos - s->buffer);
371 : }
372 :
- 373 1748 : uint32_t scrc(STREAM* s)
+ 373 1740 : uint32_t scrc(STREAM* s)
374 : {
- 375 1748 : assert(s->flags & STREAM_FLAGS_CRC);
- 376 1748 : return crc32c(s->crc_uncached, s->buffer, s->pos - s->buffer);
+ 375 1740 : assert(s->flags & STREAM_FLAGS_CRC);
+ 376 1740 : return crc32c(s->crc_uncached, s->buffer, s->pos - s->buffer);
377 : }
378 :
- 379 173 : uint32_t scrc_stream(STREAM* s)
+ 379 172 : uint32_t scrc_stream(STREAM* s)
380 : {
- 381 173 : assert(s->flags & STREAM_FLAGS_CRC);
- 382 173 : return s->crc_stream ^ CRC_IV;
+ 381 172 : assert(s->flags & STREAM_FLAGS_CRC);
+ 382 172 : return s->crc_stream ^ CRC_IV;
383 : }
384 :
- 385 299093 : int sgetc_uncached(STREAM* s)
+ 385 299099 : int sgetc_uncached(STREAM* s)
386 : {
387 : /* if at the end of the buffer, fill it */
- 388 299093 : if (s->pos == s->end && sfill(s) != 0)
- 389 1649 : return EOF;
- 390 297444 : return *s->pos++;
+ 388 299099 : if (s->pos == s->end && sfill(s) != 0)
+ 389 1654 : return EOF;
+ 390 297445 : return *s->pos++;
391 : }
392 :
- 393 9875 : int sgettok(STREAM* f, char* str, int size)
+ 393 9929 : int sgettok(STREAM* f, char* str, int size)
394 : {
- 395 9875 : char* i = str;
- 396 9875 : char* send = str + size;
+ 395 9929 : char* i = str;
+ 396 9929 : char* send = str + size;
397 : int c;
398 :
399 : while (1) {
- 400 65189 : c = sgetc(f);
- 401 65189 : if (c == EOF) {
- 402 277 : break;
+ 400 65431 : c = sgetc(f);
+ 401 65431 : if (c == EOF) {
+ 402 278 : break;
403 : }
- 404 64912 : if (c == ' ' || c == '\t') {
- 405 8791 : sungetc(c, f);
- 406 8791 : break;
+ 404 65153 : if (c == ' ' || c == '\t') {
+ 405 8836 : sungetc(c, f);
+ 406 8836 : break;
407 : }
- 408 56121 : if (c == '\n') {
+ 408 56317 : if (c == '\n') {
409 : /* remove ending carriage return to support the Windows CR+LF format */
- 410 807 : if (i != str && i[-1] == '\r')
+ 410 815 : if (i != str && i[-1] == '\r')
411 0 : --i;
- 412 807 : sungetc(c, f);
- 413 807 : break;
+ 412 815 : sungetc(c, f);
+ 413 815 : break;
414 : }
415 :
- 416 55314 : *i++ = c;
+ 416 55502 : *i++ = c;
417 :
- 418 55314 : if (i == send) {
+ 418 55502 : if (i == send) {
419 : /* LCOV_EXCL_START */
420 : return -1;
421 : /* LCOV_EXCL_STOP */
422 : }
423 : }
424 :
- 425 9875 : *i = 0;
+ 425 9929 : *i = 0;
426 :
- 427 9875 : return i - str;
+ 427 9929 : return i - str;
428 : }
429 :
- 430 13236843 : int sread(STREAM* f, void* void_data, unsigned size)
+ 430 13236979 : int sread(STREAM* f, void* void_data, unsigned size)
431 : {
- 432 13236843 : unsigned char* data = void_data;
+ 432 13236979 : unsigned char* data = void_data;
433 :
434 : /* if there is enough space in memory */
- 435 13236843 : if (sptrlookup(f, size)) {
+ 435 13236979 : if (sptrlookup(f, size)) {
436 : /* optimized version with all the data in memory */
- 437 13210539 : unsigned char* pos = sptrget(f);
+ 437 13210923 : unsigned char* pos = sptrget(f);
438 :
439 : /* copy it */
- 440 211762965 : while (size--)
- 441 198552426 : *data++ = *pos++;
+ 440 211770491 : while (size--)
+ 441 198559568 : *data++ = *pos++;
442 :
- 443 13210539 : sptrset(f, pos);
+ 443 13210923 : sptrset(f, pos);
444 : } else {
445 : /* standard version using sgetc() */
- 446 1352124 : while (size--) {
- 447 1325820 : int c = sgetc(f);
- 448 1325820 : if (c == EOF) {
+ 446 1346793 : while (size--) {
+ 447 1320737 : int c = sgetc(f);
+ 448 1320737 : if (c == EOF) {
449 : /* LCOV_EXCL_START */
450 : return -1;
451 : /* LCOV_EXCL_STOP */
452 : }
453 :
- 454 1325820 : *data++ = c;
+ 454 1320737 : *data++ = c;
455 : }
456 : }
457 :
- 458 13236843 : return 0;
+ 458 13236979 : return 0;
459 : }
460 :
- 461 5706 : int sgetline(STREAM* f, char* str, int size)
+ 461 5738 : int sgetline(STREAM* f, char* str, int size)
462 : {
- 463 5706 : char* i = str;
- 464 5706 : char* send = str + size;
+ 463 5738 : char* i = str;
+ 464 5738 : char* send = str + size;
465 : int c;
466 :
467 : /* if there is enough data in memory */
- 468 5706 : if (sptrlookup(f, size)) {
+ 468 5738 : if (sptrlookup(f, size)) {
469 : /* optimized version with all the data in memory */
470 0 : unsigned char* pos = sptrget(f);
471 :
@@ -556,22 +556,22 @@
494 0 : sptrset(f, pos);
495 : } else {
496 : while (1) {
- 497 146677 : c = sgetc(f);
- 498 146677 : if (c == EOF) {
+ 497 147172 : c = sgetc(f);
+ 498 147172 : if (c == EOF) {
499 : /* LCOV_EXCL_START */
500 : break;
501 : /* LCOV_EXCL_STOP */
502 : }
503 :
- 504 146677 : if (c == '\n') {
+ 504 147172 : if (c == '\n') {
505 : /* remove ending carriage return to support the Windows CR+LF format */
- 506 5706 : if (i != str && i[-1] == '\r')
+ 506 5738 : if (i != str && i[-1] == '\r')
507 0 : --i;
- 508 5706 : sungetc(c, f);
- 509 5706 : break;
+ 508 5738 : sungetc(c, f);
+ 509 5738 : break;
510 : }
511 :
- 512 140971 : if (i + 1 >= send) {
+ 512 141434 : if (i + 1 >= send) {
513 : /* LCOV_EXCL_START */
514 : *i = 0;
515 : sungetc(c, f);
@@ -579,74 +579,74 @@
517 : /* LCOV_EXCL_STOP */
518 : }
519 :
- 520 140971 : *i++ = c;
+ 520 141434 : *i++ = c;
521 : }
522 : }
523 :
- 524 5706 : *i = 0;
+ 524 5738 : *i = 0;
525 :
- 526 5706 : return i - str;
+ 526 5738 : return i - str;
527 : }
528 :
- 529 5663 : int sgetlasttok(STREAM* f, char* str, int size)
+ 529 5686 : int sgetlasttok(STREAM* f, char* str, int size)
530 : {
531 : int ret;
532 :
- 533 5663 : ret = sgetline(f, str, size);
- 534 5663 : if (ret < 0) {
+ 533 5686 : ret = sgetline(f, str, size);
+ 534 5686 : if (ret < 0) {
535 : /* LCOV_EXCL_START */
536 : return ret;
537 : /* LCOV_EXCL_STOP */
538 : }
539 :
- 540 5663 : while (ret > 0 && (str[ret - 1] == ' ' || str[ret - 1] == '\t'))
+ 540 5686 : while (ret > 0 && (str[ret - 1] == ' ' || str[ret - 1] == '\t'))
541 0 : --ret;
542 :
- 543 5663 : str[ret] = 0;
+ 543 5686 : str[ret] = 0;
544 :
- 545 5663 : return ret;
+ 545 5686 : return ret;
546 : }
547 :
- 548 280 : int sgetu32(STREAM* f, uint32_t* value)
+ 548 283 : int sgetu32(STREAM* f, uint32_t* value)
549 : {
550 : int c;
551 :
- 552 280 : c = sgetc(f);
- 553 280 : if (c == '0') {
+ 552 283 : c = sgetc(f);
+ 553 283 : if (c == '0') {
554 0 : *value = 0;
555 0 : return 0;
- 556 280 : } else if (c >= '1' && c <= '9') {
+ 556 283 : } else if (c >= '1' && c <= '9') {
557 : uint32_t v;
558 :
- 559 280 : v = c - '0';
+ 559 283 : v = c - '0';
560 :
- 561 280 : c = sgetc(f);
- 562 281 : while (c >= '0' && c <= '9') {
+ 561 283 : c = sgetc(f);
+ 562 287 : while (c >= '0' && c <= '9') {
563 : uint32_t digit;
- 564 1 : if (v > 0xFFFFFFFFU / 10) {
+ 564 4 : if (v > 0xFFFFFFFFU / 10) {
565 : /* LCOV_EXCL_START */
566 : /* overflow */
567 : return -1;
568 : /* LCOV_EXCL_STOP */
569 : }
- 570 1 : v *= 10;
+ 570 4 : v *= 10;
571 :
- 572 1 : digit = c - '0';
- 573 1 : if (v > 0xFFFFFFFFU - digit) {
+ 572 4 : digit = c - '0';
+ 573 4 : if (v > 0xFFFFFFFFU - digit) {
574 : /* LCOV_EXCL_START */
575 : /* overflow */
576 : return -1;
577 : /* LCOV_EXCL_STOP */
578 : }
- 579 1 : v += digit;
+ 579 4 : v += digit;
580 :
- 581 1 : c = sgetc(f);
+ 581 4 : c = sgetc(f);
582 : }
583 :
- 584 280 : *value = v;
+ 584 283 : *value = v;
585 :
- 586 280 : sungetc(c, f);
- 587 280 : return 0;
+ 586 283 : sungetc(c, f);
+ 587 283 : return 0;
588 : } else {
589 : /* LCOV_EXCL_START */
590 : /* nothing read */
@@ -655,76 +655,76 @@
593 : }
594 : }
595 :
- 596 19212483 : int sgetb32(STREAM* f, uint32_t* value)
+ 596 19190230 : int sgetb32(STREAM* f, uint32_t* value)
597 : {
598 : uint32_t v;
599 : unsigned char b;
600 : unsigned char s;
601 : int c;
602 :
- 603 19212483 : v = 0;
- 604 19212483 : s = 0;
- 605 36660649 : loop:
- 606 36660649 : c = sgetc(f);
- 607 36660649 : if (c == EOF) {
+ 603 19190230 : v = 0;
+ 604 19190230 : s = 0;
+ 605 36975859 : loop:
+ 606 36975859 : c = sgetc(f);
+ 607 36975859 : if (c == EOF) {
608 : /* LCOV_EXCL_START */
609 : return -1;
610 : /* LCOV_EXCL_STOP */
611 : }
612 :
- 613 36660649 : b = (unsigned char)c;
- 614 36660649 : if ((b & 0x80) == 0) {
- 615 17448166 : v |= (uint32_t)b << s;
- 616 17448166 : s += 7;
- 617 17448166 : if (s >= 32) {
+ 613 36975859 : b = (unsigned char)c;
+ 614 36975859 : if ((b & 0x80) == 0) {
+ 615 17785629 : v |= (uint32_t)b << s;
+ 616 17785629 : s += 7;
+ 617 17785629 : if (s >= 32) {
618 : /* LCOV_EXCL_START */
619 : return -1;
620 : /* LCOV_EXCL_STOP */
621 : }
- 622 17448166 : goto loop;
+ 622 17785629 : goto loop;
623 : }
624 :
- 625 19212483 : v |= (uint32_t)(b & 0x7f) << s;
+ 625 19190230 : v |= (uint32_t)(b & 0x7f) << s;
626 :
- 627 19212483 : *value = v;
+ 627 19190230 : *value = v;
628 :
- 629 19212483 : return 0;
+ 629 19190230 : return 0;
630 : }
631 :
- 632 11258012 : int sgetb64(STREAM* f, uint64_t* value)
+ 632 11246935 : int sgetb64(STREAM* f, uint64_t* value)
633 : {
634 : uint64_t v;
635 : unsigned char b;
636 : unsigned char s;
637 : int c;
638 :
- 639 11258012 : v = 0;
- 640 11258012 : s = 0;
- 641 41020058 : loop:
- 642 41020058 : c = sgetc(f);
- 643 41020058 : if (c == EOF) {
+ 639 11246935 : v = 0;
+ 640 11246935 : s = 0;
+ 641 41009253 : loop:
+ 642 41009253 : c = sgetc(f);
+ 643 41009253 : if (c == EOF) {
644 : /* LCOV_EXCL_START */
645 : return -1;
646 : /* LCOV_EXCL_STOP */
647 : }
648 :
- 649 41020058 : b = (unsigned char)c;
- 650 41020058 : if ((b & 0x80) == 0) {
- 651 29762046 : v |= (uint64_t)b << s;
- 652 29762046 : s += 7;
- 653 29762046 : if (s >= 64) {
+ 649 41009253 : b = (unsigned char)c;
+ 650 41009253 : if ((b & 0x80) == 0) {
+ 651 29762318 : v |= (uint64_t)b << s;
+ 652 29762318 : s += 7;
+ 653 29762318 : if (s >= 64) {
654 : /* LCOV_EXCL_START */
655 : return -1;
656 : /* LCOV_EXCL_STOP */
657 : }
- 658 29762046 : goto loop;
+ 658 29762318 : goto loop;
659 : }
660 :
- 661 11258012 : v |= (uint64_t)(b & 0x7f) << s;
+ 661 11246935 : v |= (uint64_t)(b & 0x7f) << s;
662 :
- 663 11258012 : *value = v;
+ 663 11246935 : *value = v;
664 :
- 665 11258012 : return 0;
+ 665 11246935 : return 0;
666 : }
667 :
668 392 : int sgetble32(STREAM* f, uint32_t* value)
@@ -742,35 +742,35 @@
680 392 : return 0;
681 : }
682 :
- 683 4004187 : int sgetbs(STREAM* f, char* str, int size)
+ 683 4004224 : int sgetbs(STREAM* f, char* str, int size)
684 : {
685 : uint32_t len;
686 :
- 687 4004187 : if (sgetb32(f, &len) < 0) {
+ 687 4004224 : if (sgetb32(f, &len) < 0) {
688 : /* LCOV_EXCL_START */
689 : return -1;
690 : /* LCOV_EXCL_STOP */
691 : }
692 :
- 693 4004187 : if (len + 1 > (uint32_t)size) {
+ 693 4004224 : if (len + 1 > (uint32_t)size) {
694 : /* LCOV_EXCL_START */
695 : return -1;
696 : /* LCOV_EXCL_STOP */
697 : }
698 :
- 699 4004187 : str[len] = 0;
+ 699 4004224 : str[len] = 0;
700 :
- 701 4004187 : return sread(f, str, (int)len);
+ 701 4004224 : return sread(f, str, (int)len);
702 : }
703 :
- 704 21650829 : int swrite(const void* void_data, unsigned size, STREAM* f)
+ 704 21440832 : int swrite(const void* void_data, unsigned size, STREAM* f)
705 : {
- 706 21650829 : const unsigned char* data = void_data;
+ 706 21440832 : const unsigned char* data = void_data;
707 :
708 : /* if there is enough space in memory */
- 709 21650829 : if (sptrlookup(f, size)) {
+ 709 21440832 : if (sptrlookup(f, size)) {
710 : /* optimized version with all the data in memory */
- 711 21644594 : unsigned char* pos = sptrget(f);
+ 711 21434636 : unsigned char* pos = sptrget(f);
712 :
713 : /**
714 : * Update the crc *before* writing the data in the buffer
@@ -779,19 +779,19 @@
717 : * to be able to detect memory errors on the buffer,
718 : * happening before we write it on the file.
719 : */
- 720 21644594 : if (f->flags & STREAM_FLAGS_CRC) {
- 721 21644594 : f->crc_stream = crc32c_plain(f->crc_stream, data, size);
+ 720 21434636 : if (f->flags & STREAM_FLAGS_CRC) {
+ 721 21434636 : f->crc_stream = crc32c_plain(f->crc_stream, data, size);
722 : }
723 :
724 : /* copy it */
- 725 158733264 : while (size--)
- 726 137088670 : *pos++ = *data++;
+ 725 157447190 : while (size--)
+ 726 136012554 : *pos++ = *data++;
727 :
- 728 21644594 : sptrset(f, pos);
+ 728 21434636 : sptrset(f, pos);
729 : } else {
730 : /* standard version using sputc() */
- 731 196188 : while (size--) {
- 732 189953 : if (sputc(*data++, f) != 0) {
+ 731 194484 : while (size--) {
+ 732 188288 : if (sputc(*data++, f) != 0) {
733 : /* LCOV_EXCL_START */
734 : return -1;
735 : /* LCOV_EXCL_STOP */
@@ -799,83 +799,83 @@
737 : }
738 : }
739 :
- 740 21650829 : return 0;
+ 740 21440832 : return 0;
741 : }
742 :
- 743 9508972 : int sputb32(uint32_t value, STREAM* s)
+ 743 9413354 : int sputb32(uint32_t value, STREAM* s)
744 : {
745 : unsigned char b;
746 : unsigned char buf[16];
747 : unsigned i;
748 :
- 749 9508972 : i = 0;
- 750 18146612 : loop:
- 751 18146612 : b = value & 0x7f;
- 752 18146612 : value >>= 7;
+ 749 9413354 : i = 0;
+ 750 18145593 : loop:
+ 751 18145593 : b = value & 0x7f;
+ 752 18145593 : value >>= 7;
753 :
- 754 18146612 : if (value) {
- 755 8637640 : buf[i++] = b;
- 756 8637640 : goto loop;
+ 754 18145593 : if (value) {
+ 755 8732239 : buf[i++] = b;
+ 756 8732239 : goto loop;
757 : }
758 :
- 759 9508972 : buf[i++] = b | 0x80;
+ 759 9413354 : buf[i++] = b | 0x80;
760 :
- 761 9508972 : return swrite(buf, i, s);
+ 761 9413354 : return swrite(buf, i, s);
762 : }
763 :
- 764 5572622 : int sputb64(uint64_t value, STREAM* s)
+ 764 5517420 : int sputb64(uint64_t value, STREAM* s)
765 : {
766 : unsigned char b;
767 : unsigned char buf[16];
768 : unsigned i;
769 :
- 770 5572622 : i = 0;
- 771 20318073 : loop:
- 772 20318073 : b = value & 0x7f;
- 773 20318073 : value >>= 7;
+ 770 5517420 : i = 0;
+ 771 20129323 : loop:
+ 772 20129323 : b = value & 0x7f;
+ 773 20129323 : value >>= 7;
774 :
- 775 20318073 : if (value) {
- 776 14745451 : buf[i++] = b;
- 777 14745451 : goto loop;
+ 775 20129323 : if (value) {
+ 776 14611903 : buf[i++] = b;
+ 777 14611903 : goto loop;
778 : }
779 :
- 780 5572622 : buf[i++] = b | 0x80;
+ 780 5517420 : buf[i++] = b | 0x80;
781 :
- 782 5572622 : return swrite(buf, i, s);
+ 782 5517420 : return swrite(buf, i, s);
783 : }
784 :
- 785 173 : int sputble32(uint32_t value, STREAM* s)
+ 785 172 : int sputble32(uint32_t value, STREAM* s)
786 : {
787 : unsigned char buf[4];
788 :
- 789 173 : buf[0] = value & 0xFF;
- 790 173 : buf[1] = (value >> 8) & 0xFF;
- 791 173 : buf[2] = (value >> 16) & 0xFF;
- 792 173 : buf[3] = (value >> 24) & 0xFF;
+ 789 172 : buf[0] = value & 0xFF;
+ 790 172 : buf[1] = (value >> 8) & 0xFF;
+ 791 172 : buf[2] = (value >> 16) & 0xFF;
+ 792 172 : buf[3] = (value >> 24) & 0xFF;
793 :
- 794 173 : return swrite(buf, 4, s);
+ 794 172 : return swrite(buf, 4, s);
795 : }
796 :
- 797 1982279 : int sputbs(const char* str, STREAM* f)
+ 797 1964370 : int sputbs(const char* str, STREAM* f)
798 : {
- 799 1982279 : size_t len = strlen(str);
+ 799 1964370 : size_t len = strlen(str);
800 :
- 801 1982279 : if (sputb32(len, f) != 0) {
+ 801 1964370 : if (sputb32(len, f) != 0) {
802 : /* LCOV_EXCL_START */
803 : return -1;
804 : /* LCOV_EXCL_STOP */
805 : }
806 :
- 807 1982279 : return swrite(str, len, f);
+ 807 1964370 : return swrite(str, len, f);
808 : }
809 :
810 : #if HAVE_FSYNC
- 811 157 : int ssync(STREAM* s)
+ 811 156 : int ssync(STREAM* s)
812 : {
813 : unsigned i;
814 :
- 815 1211 : for (i = 0; i < s->handle_size; ++i) {
- 816 1054 : if (fsync(s->handle[i].f) != 0) {
+ 815 1203 : for (i = 0; i < s->handle_size; ++i) {
+ 816 1047 : if (fsync(s->handle[i].f) != 0) {
817 : /* LCOV_EXCL_START */
818 : s->state = STREAM_STATE_ERROR;
819 : s->state_index = i;
@@ -884,7 +884,7 @@
822 : }
823 : }
824 :
- 825 157 : return 0;
+ 825 156 : return 0;
826 : }
827 : #endif
828 :
diff --git a/cov/cmdline/stream.h.func-sort-c.html b/cov/cmdline/stream.h.func-sort-c.html
index 795eccde..5ea9bb08 100644
--- a/cov/cmdline/stream.h.func-sort-c.html
+++ b/cov/cmdline/stream.h.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -69,39 +69,39 @@
| sgeteol |
- 6687 |
+ 6731 |
| sgetspace |
- 22868 |
+ 23010 |
| sungetc |
- 38717 |
+ 38947 |
| serror |
- 3795184 |
+ 3756051 |
| sputc |
- 3968961 |
+ 3933071 |
| sptrget |
- 34855133 |
+ 34645559 |
| sptrset |
- 34855133 |
+ 34645559 |
| sptrlookup |
- 34893378 |
+ 34683549 |
| sgetc |
- 86901471 |
+ 87201813 |
diff --git a/cov/cmdline/stream.h.func.html b/cov/cmdline/stream.h.func.html
index d6052605..cc1a51e4 100644
--- a/cov/cmdline/stream.h.func.html
+++ b/cov/cmdline/stream.h.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -65,7 +65,7 @@
| serror |
- 3795184 |
+ 3756051 |
| serrorfile |
@@ -73,35 +73,35 @@
| sgetc |
- 86901471 |
+ 87201813 |
| sgeteol |
- 6687 |
+ 6731 |
| sgetspace |
- 22868 |
+ 23010 |
| sptrget |
- 34855133 |
+ 34645559 |
| sptrlookup |
- 34893378 |
+ 34683549 |
| sptrset |
- 34855133 |
+ 34645559 |
| sputc |
- 3968961 |
+ 3933071 |
| sungetc |
- 38717 |
+ 38947 |
diff --git a/cov/cmdline/stream.h.gcov.html b/cov/cmdline/stream.h.gcov.html
index e22695d2..87eca41e 100644
--- a/cov/cmdline/stream.h.gcov.html
+++ b/cov/cmdline/stream.h.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -228,33 +228,33 @@
166 : /**
167 : * Check if the buffer has enough data loaded.
168 : */
- 169 34893378 : static inline int sptrlookup(STREAM* s, int size)
+ 169 34683549 : static inline int sptrlookup(STREAM* s, int size)
170 : {
- 171 34893378 : return s->pos + size <= s->end;
+ 171 34683549 : return s->pos + size <= s->end;
172 : }
173 :
174 : /**
175 : * Get the current stream ptr.
176 : */
- 177 34855133 : static inline unsigned char* sptrget(STREAM* s)
+ 177 34645559 : static inline unsigned char* sptrget(STREAM* s)
178 : {
- 179 34855133 : return s->pos;
+ 179 34645559 : return s->pos;
180 : }
181 :
182 : /**
183 : * Set the current stream ptr.
184 : */
- 185 34855133 : static inline void sptrset(STREAM* s, unsigned char* ptr)
+ 185 34645559 : static inline void sptrset(STREAM* s, unsigned char* ptr)
186 : {
- 187 34855133 : s->pos = ptr;
- 188 34855133 : }
+ 187 34645559 : s->pos = ptr;
+ 188 34645559 : }
189 :
190 : /**
191 : * Check the error status. Like ferror().
192 : */
- 193 3795184 : static inline int serror(STREAM* s)
+ 193 3756051 : static inline int serror(STREAM* s)
194 : {
- 195 3795184 : return s->state == STREAM_STATE_ERROR;
+ 195 3756051 : return s->state == STREAM_STATE_ERROR;
196 : }
197 :
198 : /**
@@ -298,22 +298,22 @@
236 : /**
237 : * Read a char. Like fgetc().
238 : */
- 239 86901471 : static inline int sgetc(STREAM* s)
+ 239 87201813 : static inline int sgetc(STREAM* s)
240 : {
- 241 86901471 : if (tommy_unlikely(s->pos == s->end))
- 242 299093 : return sgetc_uncached(s);
- 243 86602378 : return *s->pos++;
+ 241 87201813 : if (tommy_unlikely(s->pos == s->end))
+ 242 299099 : return sgetc_uncached(s);
+ 243 86902714 : return *s->pos++;
244 : }
245 :
246 : /**
247 : * Unread a char.
248 : * Like ungetc() but you have to unget the same char read.
249 : */
- 250 38717 : static inline void sungetc(int c, STREAM* s)
+ 250 38947 : static inline void sungetc(int c, STREAM* s)
251 : {
- 252 38717 : if (c != EOF)
- 253 37886 : --s->pos;
- 254 38717 : }
+ 252 38947 : if (c != EOF)
+ 253 38113 : --s->pos;
+ 254 38947 : }
255 :
256 : /**
257 : * Read a fixed amount of chars.
@@ -324,34 +324,34 @@
262 : /**
263 : * Get a char from a stream, ignoring one '\r'.
264 : */
- 265 6687 : static inline int sgeteol(STREAM* f)
+ 265 6731 : static inline int sgeteol(STREAM* f)
266 : {
267 : int c;
268 :
- 269 6687 : c = sgetc(f);
- 270 6687 : if (c == '\r')
+ 269 6731 : c = sgetc(f);
+ 270 6731 : if (c == '\r')
271 0 : c = sgetc(f);
272 :
- 273 6687 : return c;
+ 273 6731 : return c;
274 : }
275 :
276 : /**
277 : * Read all the spaces and tabs.
278 : * Return the number of spaces and tabs read.
279 : */
- 280 22868 : static inline int sgetspace(STREAM* f)
+ 280 23010 : static inline int sgetspace(STREAM* f)
281 : {
- 282 22868 : int count = 0;
+ 282 23010 : int count = 0;
283 : int c;
284 :
- 285 22868 : c = sgetc(f);
- 286 31659 : while (c == ' ' || c == '\t') {
- 287 8791 : ++count;
- 288 8791 : c = sgetc(f);
+ 285 23010 : c = sgetc(f);
+ 286 31846 : while (c == ' ' || c == '\t') {
+ 287 8836 : ++count;
+ 288 8836 : c = sgetc(f);
289 : }
290 :
- 291 22868 : sungetc(c, f);
- 292 22868 : return count;
+ 291 23010 : sungetc(c, f);
+ 292 23010 : return count;
293 : }
294 :
295 : /**
@@ -414,10 +414,10 @@
352 : * Write a char. Like fputc().
353 : * Return 0 on success or -1 on error.
354 : */
- 355 3968961 : static inline int sputc(int c, STREAM* s)
+ 355 3933071 : static inline int sputc(int c, STREAM* s)
356 : {
- 357 3968961 : if (s->pos == s->end) {
- 358 38671 : if (sflush(s) != 0)
+ 357 3933071 : if (s->pos == s->end) {
+ 358 38652 : if (sflush(s) != 0)
359 0 : return -1;
360 : }
361 :
@@ -428,12 +428,12 @@
366 : * to be able to detect memory errors on the buffer,
367 : * happening before we write it on the file.
368 : */
- 369 3968961 : if (s->flags & STREAM_FLAGS_CRC)
- 370 3968961 : s->crc_stream = crc32c_plain_char(s->crc_stream, c);
+ 369 3933071 : if (s->flags & STREAM_FLAGS_CRC)
+ 370 3933071 : s->crc_stream = crc32c_plain_char(s->crc_stream, c);
371 :
- 372 3968961 : *s->pos++ = c;
+ 372 3933071 : *s->pos++ = c;
373 :
- 374 3968961 : return 0;
+ 374 3933071 : return 0;
375 : }
376 :
377 : /**
diff --git a/cov/cmdline/support.c.func-sort-c.html b/cov/cmdline/support.c.func-sort-c.html
index dd03490b..a44989a5 100644
--- a/cov/cmdline/support.c.func-sort-c.html
+++ b/cov/cmdline/support.c.func-sort-c.html
@@ -31,18 +31,18 @@
|
-
-
-
+
+
+
-
+
|
-
+
-
+
 |
@@ -64,11 +64,11 @@
0 |
- | log_fatal_errno |
+ log_fatal_errno |
0 |
- | path_is_root_of |
+ path_is_root_of |
0 |
@@ -79,321 +79,321 @@
| random_u8 |
0 |
-
- | scomma |
- 0 |
-
-
- | smartctl_attribute |
- 0 |
-
-
- | smatch |
- 0 |
-
| unlock_random |
0 |
- | strlwr |
+ strlwr |
2 |
- | smartctl_flush |
+ smartctl_flush |
5 |
- | worddigitstr |
+ worddigitstr |
11 |
- | strtrim |
- 13 |
+ smartctl_attribute |
+ 14 |
- | printp |
+ printp |
18 |
- | strpolish |
- 21 |
-
-
- | log_error_errno |
+ log_error_errno |
27 |
- | match_class |
+ match_class |
28 |
- | printr |
+ printr |
34 |
- | printc |
- 77 |
+ strtrim |
+ 67 |
- | printl |
- 142 |
+ printc |
+ 78 |
- | pathcat |
- 279 |
+ printl |
+ 157 |
+
+
+ | strpolish |
+ 256 |
+
+
+ | pathcat |
+ 280 |
| random_reseed |
- 283 |
+ 284 |
| lock_done |
- 288 |
+ 289 |
| lock_init |
- 310 |
+ 311 |
- | thread_cond_destroy |
+ thread_cond_destroy |
404 |
- | thread_cond_init |
+ thread_cond_init |
404 |
- | malloc_counter_get |
+ malloc_counter_get |
488 |
- | msg_flush |
- 586 |
+ msg_flush |
+ 572 |
- | thread_cond_signal |
- 668 |
-
-
- | thread_cond_signal_and_unlock |
- 668 |
-
-
- | msg_status |
+ msg_status |
743 |
- | pathcatc |
+ pathcatc |
788 |
- | log_fatal |
+ log_fatal |
803 |
- | strsplit |
- 1718 |
+ thread_cond_signal |
+ 827 |
- | msg_bar |
- 2118 |
+ thread_cond_signal_and_unlock |
+ 827 |
- | thread_create |
- 2876 |
+ strsplit |
+ 1720 |
- | thread_join |
- 2876 |
+ smatch |
+ 1779 |
- | thread_mutex_destroy |
- 3167 |
+ msg_bar |
+ 2042 |
- | thread_mutex_init |
- 3299 |
+ scomma |
+ 2316 |
- | log_flush |
- 3649 |
+ thread_create |
+ 2883 |
- | log_expected |
+ thread_join |
+ 2883 |
+
+
+ | thread_mutex_destroy |
+ 3180 |
+
+
+ | thread_mutex_init |
+ 3312 |
+
+
+ | log_flush |
+ 3652 |
+
+
+ | log_expected |
4697 |
- | msg_progress |
- 5081 |
+ msg_progress |
+ 5066 |
- | pathslash |
- 7949 |
+ pathslash |
+ 7959 |
- | lmtime |
+ lmtime |
11645 |
- | pathexport |
+ pathexport |
12234 |
- | pathimport |
- 17981 |
+ pathimport |
+ 18024 |
- | vmsg |
- 41543 |
+ vmsg |
+ 41562 |
- | pathcut |
- 58108 |
+ pathcut |
+ 58110 |
- | thread_yield |
- 105499 |
+ thread_yield |
+ 108112 |
- | fmtime |
- 121348 |
+ fmtime |
+ 121378 |
- | msg_verbose |
- 127020 |
+ msg_verbose |
+ 127094 |
- | smart_temp |
- 145110 |
+ smart_temp |
+ 145124 |
- | calloc_nofail |
- 156192 |
+ calloc_nofail |
+ 156271 |
- | thread_cond_broadcast_and_unlock |
- 257469 |
+ thread_cond_broadcast_and_unlock |
+ 257343 |
- | thread_cond_broadcast |
- 257671 |
+ thread_cond_broadcast |
+ 257545 |
- | msg_info |
- 312495 |
+ msg_info |
+ 312664 |
- | log_error |
- 365227 |
+ log_error |
+ 364924 |
- | esc_shell_multi |
- 366218 |
+ esc_shell_multi |
+ 366387 |
- | mkancestor |
- 787726 |
+ mkancestor |
+ 787783 |
- | advise_write |
- 914575 |
+ advise_write |
+ 914297 |
- | thread_cond_wait |
- 1554330 |
+ thread_cond_wait |
+ 1554290 |
| is_hw |
- 1830939 |
+ 1830711 |
- | pathcpy |
- 1902922 |
+ pathcpy |
+ 1902784 |
- | advise_open |
- 2410879 |
+ advise_open |
+ 2410781 |
- | advise_flags |
- 2489611 |
+ advise_flags |
+ 2489478 |
- | advise_init |
- 2489611 |
+ advise_init |
+ 2489478 |
- | esc_tag |
- 2652388 |
+ esc_tag |
+ 2653118 |
- | pathcatl |
+ pathcatl |
3601926 |
- | ssget |
- 5261663 |
+ ssget |
+ 5265543 |
- | strdup_nofail |
- 5965500 |
+ strdup_nofail |
+ 5965600 |
- | advise_read |
- 8833871 |
+ advise_read |
+ 8833464 |
- | malloc_nofail |
- 14819123 |
+ malloc_nofail |
+ 14819141 |
- | malloc_counter_inc |
- 20940815 |
+ malloc_counter_inc |
+ 20941012 |
| lock_memory |
- 20941303 |
+ 20941500 |
| unlock_memory |
- 20941303 |
+ 20941500 |
- | log_tag |
- 21732148 |
+ log_tag |
+ 21733516 |
| lock_msg |
- 22554567 |
+ 22555773 |
| unlock_msg |
- 22554567 |
+ 22555773 |
- | pathprint |
- 42979947 |
+ pathprint |
+ 42981264 |
- | pathcmp |
- 53116131 |
+ pathcmp |
+ 53117221 |
- | char_match |
- 86982601 |
+ char_match |
+ 86985273 |
- | wnmatch |
- 102260599 |
+ wnmatch |
+ 102263029 |
- | thread_mutex_lock |
- 112510359 |
+ thread_mutex_lock |
+ 112377134 |
- | thread_mutex_unlock |
- 112510359 |
+ thread_mutex_unlock |
+ 112377134 |
diff --git a/cov/cmdline/support.c.func.html b/cov/cmdline/support.c.func.html
index 7de0aca5..b5f7b1cc 100644
--- a/cov/cmdline/support.c.func.html
+++ b/cov/cmdline/support.c.func.html
@@ -31,18 +31,18 @@
|
-
-
-
+
+
+
-
+
|
-
+
-
+
 |
@@ -60,208 +60,208 @@
Hit count  |
- | advise_flags |
- 2489611 |
+ advise_flags |
+ 2489478 |
- | advise_init |
- 2489611 |
+ advise_init |
+ 2489478 |
- | advise_open |
- 2410879 |
+ advise_open |
+ 2410781 |
- | advise_read |
- 8833871 |
+ advise_read |
+ 8833464 |
- | advise_write |
- 914575 |
+ advise_write |
+ 914297 |
- | calloc_nofail |
- 156192 |
+ calloc_nofail |
+ 156271 |
- | char_match |
- 86982601 |
+ char_match |
+ 86985273 |
- | esc_shell_multi |
- 366218 |
+ esc_shell_multi |
+ 366387 |
- | esc_tag |
- 2652388 |
+ esc_tag |
+ 2653118 |
- | fmtime |
- 121348 |
+ fmtime |
+ 121378 |
| is_hw |
- 1830939 |
+ 1830711 |
- | lmtime |
+ lmtime |
11645 |
| lock_done |
- 288 |
+ 289 |
| lock_init |
- 310 |
+ 311 |
| lock_memory |
- 20941303 |
+ 20941500 |
| lock_msg |
- 22554567 |
+ 22555773 |
| lock_random |
0 |
- | log_error |
- 365227 |
+ log_error |
+ 364924 |
- | log_error_errno |
+ log_error_errno |
27 |
- | log_expected |
+ log_expected |
4697 |
- | log_fatal |
+ log_fatal |
803 |
- | log_fatal_errno |
+ log_fatal_errno |
0 |
- | log_flush |
- 3649 |
+ log_flush |
+ 3652 |
- | log_tag |
- 21732148 |
+ log_tag |
+ 21733516 |
- | malloc_counter_get |
+ malloc_counter_get |
488 |
- | malloc_counter_inc |
- 20940815 |
+ malloc_counter_inc |
+ 20941012 |
- | malloc_nofail |
- 14819123 |
+ malloc_nofail |
+ 14819141 |
- | match_class |
+ match_class |
28 |
- | mkancestor |
- 787726 |
+ mkancestor |
+ 787783 |
- | msg_bar |
- 2118 |
+ msg_bar |
+ 2042 |
- | msg_flush |
- 586 |
+ msg_flush |
+ 572 |
- | msg_info |
- 312495 |
+ msg_info |
+ 312664 |
- | msg_progress |
- 5081 |
+ msg_progress |
+ 5066 |
- | msg_status |
+ msg_status |
743 |
- | msg_verbose |
- 127020 |
+ msg_verbose |
+ 127094 |
- | path_is_root_of |
+ path_is_root_of |
0 |
- | pathcat |
- 279 |
+ pathcat |
+ 280 |
- | pathcatc |
+ pathcatc |
788 |
- | pathcatl |
+ pathcatl |
3601926 |
- | pathcmp |
- 53116131 |
+ pathcmp |
+ 53117221 |
- | pathcpy |
- 1902922 |
+ pathcpy |
+ 1902784 |
- | pathcut |
- 58108 |
+ pathcut |
+ 58110 |
- | pathexport |
+ pathexport |
12234 |
- | pathimport |
- 17981 |
+ pathimport |
+ 18024 |
- | pathprint |
- 42979947 |
+ pathprint |
+ 42981264 |
- | pathslash |
- 7949 |
+ pathslash |
+ 7959 |
- | printc |
- 77 |
+ printc |
+ 78 |
- | printl |
- 142 |
+ printl |
+ 157 |
- | printp |
+ printp |
18 |
- | printr |
+ printr |
34 |
| random_reseed |
- 283 |
+ 284 |
| random_u64 |
@@ -272,127 +272,127 @@
0 |
- | scomma |
- 0 |
+ scomma |
+ 2316 |
- | smart_temp |
- 145110 |
+ smart_temp |
+ 145124 |
- | smartctl_attribute |
- 0 |
+ smartctl_attribute |
+ 14 |
- | smartctl_flush |
+ smartctl_flush |
5 |
- | smatch |
- 0 |
+ smatch |
+ 1779 |
- | ssget |
- 5261663 |
+ ssget |
+ 5265543 |
- | strdup_nofail |
- 5965500 |
+ strdup_nofail |
+ 5965600 |
- | strlwr |
+ strlwr |
2 |
- | strpolish |
- 21 |
+ strpolish |
+ 256 |
- | strsplit |
- 1718 |
+ strsplit |
+ 1720 |
- | strtrim |
- 13 |
+ strtrim |
+ 67 |
- | thread_cond_broadcast |
- 257671 |
+ thread_cond_broadcast |
+ 257545 |
- | thread_cond_broadcast_and_unlock |
- 257469 |
+ thread_cond_broadcast_and_unlock |
+ 257343 |
- | thread_cond_destroy |
+ thread_cond_destroy |
404 |
- | thread_cond_init |
+ thread_cond_init |
404 |
- | thread_cond_signal |
- 668 |
+ thread_cond_signal |
+ 827 |
- | thread_cond_signal_and_unlock |
- 668 |
+ thread_cond_signal_and_unlock |
+ 827 |
- | thread_cond_wait |
- 1554330 |
+ thread_cond_wait |
+ 1554290 |
- | thread_create |
- 2876 |
+ thread_create |
+ 2883 |
- | thread_join |
- 2876 |
+ thread_join |
+ 2883 |
- | thread_mutex_destroy |
- 3167 |
+ thread_mutex_destroy |
+ 3180 |
- | thread_mutex_init |
- 3299 |
+ thread_mutex_init |
+ 3312 |
- | thread_mutex_lock |
- 112510359 |
+ thread_mutex_lock |
+ 112377134 |
- | thread_mutex_unlock |
- 112510359 |
+ thread_mutex_unlock |
+ 112377134 |
- | thread_yield |
- 105499 |
+ thread_yield |
+ 108112 |
| unlock_memory |
- 20941303 |
+ 20941500 |
| unlock_msg |
- 22554567 |
+ 22555773 |
| unlock_random |
0 |
- | vmsg |
- 41543 |
+ vmsg |
+ 41562 |
- | wnmatch |
- 102260599 |
+ wnmatch |
+ 102263029 |
- | worddigitstr |
+ worddigitstr |
11 |
diff --git a/cov/cmdline/support.c.gcov.html b/cov/cmdline/support.c.gcov.html
index a91b3552..17ab328d 100644
--- a/cov/cmdline/support.c.gcov.html
+++ b/cov/cmdline/support.c.gcov.html
@@ -31,18 +31,18 @@
|
-
-
-
+
+
+
-
+
|
-
+
-
+
 |
@@ -93,33 +93,33 @@
31 : static thread_mutex_t random_lock;
32 : #endif
33 :
- 34 22554567 : void lock_msg(void)
+ 34 22555773 : void lock_msg(void)
35 : {
36 : #if HAVE_THREAD
- 37 22554567 : thread_mutex_lock(&msg_lock);
+ 37 22555773 : thread_mutex_lock(&msg_lock);
38 : #endif
- 39 22554567 : }
+ 39 22555773 : }
40 :
- 41 22554567 : void unlock_msg(void)
+ 41 22555773 : void unlock_msg(void)
42 : {
43 : #if HAVE_THREAD
- 44 22554567 : thread_mutex_unlock(&msg_lock);
+ 44 22555773 : thread_mutex_unlock(&msg_lock);
45 : #endif
- 46 22554567 : }
+ 46 22555773 : }
47 :
- 48 20941303 : void lock_memory(void)
+ 48 20941500 : void lock_memory(void)
49 : {
50 : #if HAVE_THREAD
- 51 20941303 : thread_mutex_lock(&memory_lock);
+ 51 20941500 : thread_mutex_lock(&memory_lock);
52 : #endif
- 53 20941303 : }
+ 53 20941500 : }
54 :
- 55 20941303 : void unlock_memory(void)
+ 55 20941500 : void unlock_memory(void)
56 : {
57 : #if HAVE_THREAD
- 58 20941303 : thread_mutex_unlock(&memory_lock);
+ 58 20941500 : thread_mutex_unlock(&memory_lock);
59 : #endif
- 60 20941303 : }
+ 60 20941500 : }
61 :
62 0 : void lock_random(void)
63 : {
@@ -136,34 +136,34 @@
74 0 : }
75 :
76 :
- 77 310 : void lock_init(void)
+ 77 311 : void lock_init(void)
78 : {
79 : #if HAVE_THREAD
80 : /* initialize the locks as first operation as log_fatal depends on them */
- 81 310 : thread_mutex_init(&msg_lock);
- 82 310 : thread_mutex_init(&memory_lock);
- 83 310 : thread_mutex_init(&random_lock);
+ 81 311 : thread_mutex_init(&msg_lock);
+ 82 311 : thread_mutex_init(&memory_lock);
+ 83 311 : thread_mutex_init(&random_lock);
84 : #endif
- 85 310 : }
+ 85 311 : }
86 :
- 87 288 : void lock_done(void)
+ 87 289 : void lock_done(void)
88 : {
89 : #if HAVE_THREAD
- 90 288 : thread_mutex_destroy(&msg_lock);
- 91 288 : thread_mutex_destroy(&memory_lock);
- 92 288 : thread_mutex_destroy(&random_lock);
+ 90 289 : thread_mutex_destroy(&msg_lock);
+ 91 289 : thread_mutex_destroy(&memory_lock);
+ 92 289 : thread_mutex_destroy(&random_lock);
93 : #endif
- 94 288 : }
+ 94 289 : }
95 :
96 : /****************************************************************************/
97 : /* random */
98 :
99 : static uint64_t random_state = 1;
100 :
- 101 283 : void random_reseed(void)
+ 101 284 : void random_reseed(void)
102 : {
- 103 283 : random_state = tick();
- 104 283 : }
+ 103 284 : random_state = tick();
+ 104 284 : }
105 :
106 0 : unsigned char random_u8(void)
107 : {
@@ -198,2494 +198,2500 @@
136 : /****************************************************************************/
137 : /* error */
138 :
- 139 1830939 : int is_hw(int err)
+ 139 1830711 : int is_hw(int err)
140 : {
- 141 1830939 : if (err == EIO)
- 142 12 : return 1;
- 143 : #ifdef EFSCORRUPTED
- 144 : if (err == EFSCORRUPTED) /* used by XFS inside the kernel - never expected in user mode as converted to EUCLEAN */
- 145 : return 1;
- 146 : #endif
- 147 : #ifdef EUCLEAN
- 148 1830927 : if (err == EUCLEAN) /* used by XFS at user level instead of EFSCORRUPTED */
- 149 0 : return 1;
- 150 : #endif
- 151 : #ifdef EBADCRC
- 152 : if (err == EBADCRC) /* used by BTRFS - never expected in user mode as converted to EIO */
- 153 : return 1;
- 154 : #endif
- 155 : #ifdef EBADMSG
- 156 1830927 : if (err == EBADMSG) /* used by BTRFS - never expected in user mode as converted to EIO */
- 157 0 : return 1;
- 158 : #endif
- 159 : #ifdef ENOMEDIUM
- 160 1830927 : if (err == ENOMEDIUM) /* medium removed */
- 161 0 : return 1;
- 162 : #endif
- 163 : #ifdef EHWPOISON
- 164 1830927 : if (err == EHWPOISON) /* hardware memory error */
- 165 0 : return 1;
- 166 : #endif
- 167 1830927 : return 0;
- 168 : }
- 169 :
- 170 0 : void log_fatal_errno(int err, const char* name)
- 171 : {
- 172 0 : if (err == EIO) {
- 173 0 : log_fatal(err, "DANGER! Unexpected input/output error in disk %s. It isn't possible to continue.\n", name);
- 174 : #ifdef EFSCORRUPTED
- 175 : } else if (err == EFSCORRUPTED) {
- 176 : log_fatal(err, "DANGER! Unexpected corrupted error in disk %s. It isn't possible to continue.\n", name);
- 177 : #endif
- 178 : #ifdef EUCLEAN
- 179 0 : } else if (err == EUCLEAN) {
- 180 0 : log_fatal(err, "DANGER! Unexpected corrupted error in disk %s. It isn't possible to continue.\n", name);
- 181 : #endif
- 182 : #ifdef EBADCRC
- 183 : } else if (err == EBADCRC) {
- 184 : log_fatal(err, "DANGER! Unexpected bad crc error in disk %s. It isn't possible to continue.\n", name);
- 185 : #endif
- 186 : #ifdef EBADMSG
- 187 0 : } else if (err == EBADMSG) {
- 188 0 : log_fatal(err, "DANGER! Unexpected bad crc error in disk %s. It isn't possible to continue.\n", name);
- 189 : #endif
- 190 : #ifdef ENOMEDIUM
- 191 0 : } else if (err == ENOMEDIUM) {
- 192 0 : log_fatal(err, "DANGER! Unexpected medium removed in disk %s. It isn't possible to continue.\n", name);
- 193 : #endif
- 194 : #ifdef EHWPOISON
- 195 0 : } else if (err == EHWPOISON) {
- 196 0 : log_fatal(err, "DANGER! Unexpected memory error in disk %s. It isn't possible to continue.\n", name);
- 197 : #endif
- 198 0 : } else if (err == EACCES) {
- 199 0 : log_fatal(err, "WARNING! Grant permission in the disk %s. It isn't possible to continue.\n", name);
- 200 0 : } else if (err == ENOSPC) {
- 201 0 : log_fatal(err, "WARNING! Ensure there is free space on the disk %s. It isn't possible to continue.\n", name);
- 202 : } else {
- 203 0 : log_fatal(err, "WARNING! Without a working %s disk, it isn't possible to continue.\n", name);
- 204 : }
- 205 0 : }
- 206 :
- 207 27 : void log_error_errno(int err, const char* name)
- 208 : {
- 209 27 : if (err == EIO) {
- 210 0 : log_fatal(err, "DANGER! Unexpected input/output error in disk %s.\n", name);
- 211 : #ifdef EFSCORRUPTED
- 212 : } else if (err == EFSCORRUPTED) {
- 213 : log_fatal(err, "DANGER! Unexpected corrupted error in disk %s.\n", name);
- 214 : #endif
- 215 : #ifdef EUCLEAN
- 216 27 : } else if (err == EUCLEAN) {
- 217 0 : log_fatal(err, "DANGER! Unexpected corrupted error in disk %s.\n", name);
- 218 : #endif
- 219 : #ifdef EBADCRC
- 220 : } else if (err == EBADCRC) {
- 221 : log_fatal(err, "DANGER! Unexpected bad crc error in disk %s.\n", name);
- 222 : #endif
- 223 : #ifdef EBADMSG
- 224 27 : } else if (err == EBADMSG) {
- 225 0 : log_fatal(err, "DANGER! Unexpected bad crc error in disk %s.\n", name);
- 226 : #endif
- 227 : #ifdef ENOMEDIUM
- 228 27 : } else if (err == ENOMEDIUM) {
- 229 0 : log_fatal(err, "DANGER! Unexpected medium removed in disk %s.\n", name);
- 230 : #endif
- 231 : #ifdef EHWPOISON
- 232 27 : } else if (err == EHWPOISON) {
- 233 0 : log_fatal(err, "DANGER! Unexpected memory error in disk %s.\n", name);
- 234 : #endif
- 235 27 : } else if (err == EACCES) {
- 236 12 : log_error(err, "WARNING! Grant permission in the disk %s.\n", name);
- 237 15 : } else if (err == ENOSPC) {
- 238 0 : log_error(err, "WARNING! Ensure there is free space on the disk %s.\n", name);
- 239 15 : } else if (err == ENOENT) {
- 240 15 : log_error(err, "WARNING! You cannot modify files while running.\n");
- 241 : }
- 242 27 : }
- 243 :
- 244 : /****************************************************************************/
- 245 : /* print */
- 246 :
- 247 : int msg_level = 0;
- 248 : FILE* stdlog = 0;
- 249 : int msg_line_prev = 0; /**< Previous line width on stdout */
- 250 : int msg_line_curr = 0; /**< Current line width on stdout */
- 251 :
- 252 : /*
- 253 : * Note that in the following functions we always flush both
- 254 : * stdout and stderr, because we want to ensure that they mixes
- 255 : * well when redirected to files
- 256 : *
- 257 : * The buffering is similar at the "line buffered" one, that
- 258 : * is not available on Windows, so we emulate it in this way.
- 259 : *
- 260 : * For stdlog flushing is limited. To ensure flushing the
- 261 : * caller should use log_flush().
- 262 : */
- 263 :
- 264 41543 : static void vmsg(FILE* out, const char* format, va_list ap)
- 265 : {
- 266 41543 : char* dup = strdup_nofail(format);
- 267 41543 : int len = strlen(dup);
- 268 41543 : int written = 0;
- 269 41543 : char control = 0;
- 270 :
- 271 41543 : if (len > 0) {
- 272 41543 : if (dup[len - 1] == '\n') {
- 273 41533 : dup[len - 1] = 0;
- 274 41533 : control = '\n';
- 275 10 : } else if (dup[len - 1] == '\r') {
- 276 0 : dup[len - 1] = 0;
- 277 0 : control = '\r';
- 278 : }
- 279 : }
- 280 :
- 281 41543 : if (dup[0]) {
- 282 41440 : written = vfprintf(out, dup, ap);
- 283 : }
- 284 :
- 285 41543 : switch (control) {
- 286 10 : case 0 :
- 287 10 : msg_line_curr += written;
- 288 10 : break;
- 289 41533 : case '\n' :
- 290 41533 : msg_line_curr += written;
- 291 : /* writes spaces to overwrite any previous char */
- 292 41533 : while (msg_line_curr < msg_line_prev) {
- 293 0 : fprintf(out, " ");
- 294 0 : --msg_line_prev;
- 295 : }
- 296 41533 : msg_line_prev = 0;
- 297 41533 : msg_line_curr = 0;
- 298 41533 : fprintf(out, "\n");
- 299 41533 : break;
- 300 0 : case '\r' :
- 301 0 : msg_line_curr += written;
- 302 : /* writes spaces to overwrite any previous char */
- 303 0 : while (msg_line_curr < msg_line_prev) {
- 304 0 : fprintf(out, " ");
- 305 0 : --msg_line_prev;
- 306 : }
- 307 0 : msg_line_prev = msg_line_curr;
- 308 0 : msg_line_curr = 0;
- 309 0 : fprintf(out, "\r");
- 310 : }
- 311 :
- 312 41543 : free(dup);
- 313 41543 : }
- 314 :
- 315 803 : void log_fatal(int err, const char* format, ...)
- 316 : {
- 317 : va_list ap;
- 318 :
- 319 803 : lock_msg();
+ 141 : /* LCOV_EXCL_START */
+ 142 : if (err == EIO)
+ 143 : return 1;
+ 144 : #ifdef EFSCORRUPTED
+ 145 : if (err == EFSCORRUPTED) /* used by XFS inside the kernel - never expected in user mode as converted to EUCLEAN */
+ 146 : return 1;
+ 147 : #endif
+ 148 : #ifdef EUCLEAN
+ 149 : if (err == EUCLEAN) /* used by XFS at user level instead of EFSCORRUPTED */
+ 150 : return 1;
+ 151 : #endif
+ 152 : #ifdef EBADCRC
+ 153 : if (err == EBADCRC) /* used by BTRFS - never expected in user mode as converted to EIO */
+ 154 : return 1;
+ 155 : #endif
+ 156 : #ifdef EBADMSG
+ 157 : if (err == EBADMSG) /* used by BTRFS - never expected in user mode as converted to EIO */
+ 158 : return 1;
+ 159 : #endif
+ 160 : #ifdef ENOMEDIUM
+ 161 : if (err == ENOMEDIUM) /* medium removed */
+ 162 : return 1;
+ 163 : #endif
+ 164 : #ifdef EHWPOISON
+ 165 : if (err == EHWPOISON) /* hardware memory error */
+ 166 : return 1;
+ 167 : #endif
+ 168 : /* LCOV_EXCL_STOP */
+ 169 1830699 : return 0;
+ 170 : }
+ 171 :
+ 172 0 : void log_fatal_errno(int err, const char* name)
+ 173 : {
+ 174 : /* LCOV_EXCL_START */
+ 175 : if (err == EIO) {
+ 176 : log_fatal(err, "DANGER! Unexpected input/output error in disk %s. It isn't possible to continue.\n", name);
+ 177 : #ifdef EFSCORRUPTED
+ 178 : } else if (err == EFSCORRUPTED) {
+ 179 : log_fatal(err, "DANGER! Unexpected corrupted error in disk %s. It isn't possible to continue.\n", name);
+ 180 : #endif
+ 181 : #ifdef EUCLEAN
+ 182 : } else if (err == EUCLEAN) {
+ 183 : log_fatal(err, "DANGER! Unexpected corrupted error in disk %s. It isn't possible to continue.\n", name);
+ 184 : #endif
+ 185 : #ifdef EBADCRC
+ 186 : } else if (err == EBADCRC) {
+ 187 : log_fatal(err, "DANGER! Unexpected bad crc error in disk %s. It isn't possible to continue.\n", name);
+ 188 : #endif
+ 189 : #ifdef EBADMSG
+ 190 : } else if (err == EBADMSG) {
+ 191 : log_fatal(err, "DANGER! Unexpected bad crc error in disk %s. It isn't possible to continue.\n", name);
+ 192 : #endif
+ 193 : #ifdef ENOMEDIUM
+ 194 : } else if (err == ENOMEDIUM) {
+ 195 : log_fatal(err, "DANGER! Unexpected medium removed in disk %s. It isn't possible to continue.\n", name);
+ 196 : #endif
+ 197 : #ifdef EHWPOISON
+ 198 : } else if (err == EHWPOISON) {
+ 199 : log_fatal(err, "DANGER! Unexpected memory error in disk %s. It isn't possible to continue.\n", name);
+ 200 : #endif
+ 201 : } else if (err == EACCES) {
+ 202 : log_fatal(err, "WARNING! Grant permission in the disk %s. It isn't possible to continue.\n", name);
+ 203 : } else if (err == ENOSPC) {
+ 204 : log_fatal(err, "WARNING! Ensure there is free space on the disk %s. It isn't possible to continue.\n", name);
+ 205 : } else {
+ 206 : log_fatal(err, "WARNING! Without a working %s disk, it isn't possible to continue.\n", name);
+ 207 : }
+ 208 : /* LCOV_EXCL_STOP */
+ 209 0 : }
+ 210 :
+ 211 27 : void log_error_errno(int err, const char* name)
+ 212 : {
+ 213 : /* LCOV_EXCL_START */
+ 214 : if (err == EIO) {
+ 215 : log_fatal(err, "DANGER! Unexpected input/output error in disk %s.\n", name);
+ 216 : #ifdef EFSCORRUPTED
+ 217 : } else if (err == EFSCORRUPTED) {
+ 218 : log_fatal(err, "DANGER! Unexpected corrupted error in disk %s.\n", name);
+ 219 : #endif
+ 220 : #ifdef EUCLEAN
+ 221 : } else if (err == EUCLEAN) {
+ 222 : log_fatal(err, "DANGER! Unexpected corrupted error in disk %s.\n", name);
+ 223 : #endif
+ 224 : #ifdef EBADCRC
+ 225 : } else if (err == EBADCRC) {
+ 226 : log_fatal(err, "DANGER! Unexpected bad crc error in disk %s.\n", name);
+ 227 : #endif
+ 228 : #ifdef EBADMSG
+ 229 : } else if (err == EBADMSG) {
+ 230 : log_fatal(err, "DANGER! Unexpected bad crc error in disk %s.\n", name);
+ 231 : #endif
+ 232 : #ifdef ENOMEDIUM
+ 233 : } else if (err == ENOMEDIUM) {
+ 234 : log_fatal(err, "DANGER! Unexpected medium removed in disk %s.\n", name);
+ 235 : #endif
+ 236 : #ifdef EHWPOISON
+ 237 : } else if (err == EHWPOISON) {
+ 238 : log_fatal(err, "DANGER! Unexpected memory error in disk %s.\n", name);
+ 239 : #endif
+ 240 : /* LCOV_EXCL_STOP */
+ 241 27 : } else if (err == EACCES) {
+ 242 12 : log_error(err, "WARNING! Grant permission in the disk %s.\n", name);
+ 243 15 : } else if (err == ENOSPC) {
+ 244 0 : log_error(err, "WARNING! Ensure there is free space on the disk %s.\n", name);
+ 245 15 : } else if (err == ENOENT) {
+ 246 15 : log_error(err, "WARNING! You cannot modify files while running.\n");
+ 247 : }
+ 248 27 : }
+ 249 :
+ 250 : /****************************************************************************/
+ 251 : /* print */
+ 252 :
+ 253 : int msg_level = 0;
+ 254 : FILE* stdlog = 0;
+ 255 : int msg_line_prev = 0; /**< Previous line width on stdout */
+ 256 : int msg_line_curr = 0; /**< Current line width on stdout */
+ 257 :
+ 258 : /*
+ 259 : * Note that in the following functions we always flush both
+ 260 : * stdout and stderr, because we want to ensure that they mixes
+ 261 : * well when redirected to files
+ 262 : *
+ 263 : * The buffering is similar at the "line buffered" one, that
+ 264 : * is not available on Windows, so we emulate it in this way.
+ 265 : *
+ 266 : * For stdlog flushing is limited. To ensure flushing the
+ 267 : * caller should use log_flush().
+ 268 : */
+ 269 :
+ 270 41562 : static void vmsg(FILE* out, const char* format, va_list ap)
+ 271 : {
+ 272 41562 : char* dup = strdup_nofail(format);
+ 273 41562 : int len = strlen(dup);
+ 274 41562 : int written = 0;
+ 275 41562 : char control = 0;
+ 276 :
+ 277 41562 : if (len > 0) {
+ 278 41562 : if (dup[len - 1] == '\n') {
+ 279 41552 : dup[len - 1] = 0;
+ 280 41552 : control = '\n';
+ 281 10 : } else if (dup[len - 1] == '\r') {
+ 282 0 : dup[len - 1] = 0;
+ 283 0 : control = '\r';
+ 284 : }
+ 285 : }
+ 286 :
+ 287 41562 : if (dup[0]) {
+ 288 41459 : written = vfprintf(out, dup, ap);
+ 289 : }
+ 290 :
+ 291 41562 : switch (control) {
+ 292 10 : case 0 :
+ 293 10 : msg_line_curr += written;
+ 294 10 : break;
+ 295 41552 : case '\n' :
+ 296 41552 : msg_line_curr += written;
+ 297 : /* writes spaces to overwrite any previous char */
+ 298 41552 : while (msg_line_curr < msg_line_prev) {
+ 299 0 : fprintf(out, " ");
+ 300 0 : --msg_line_prev;
+ 301 : }
+ 302 41552 : msg_line_prev = 0;
+ 303 41552 : msg_line_curr = 0;
+ 304 41552 : fprintf(out, "\n");
+ 305 41552 : break;
+ 306 0 : case '\r' :
+ 307 0 : msg_line_curr += written;
+ 308 : /* writes spaces to overwrite any previous char */
+ 309 0 : while (msg_line_curr < msg_line_prev) {
+ 310 0 : fprintf(out, " ");
+ 311 0 : --msg_line_prev;
+ 312 : }
+ 313 0 : msg_line_prev = msg_line_curr;
+ 314 0 : msg_line_curr = 0;
+ 315 0 : fprintf(out, "\r");
+ 316 : }
+ 317 :
+ 318 41562 : free(dup);
+ 319 41562 : }
320 :
- 321 803 : if (stdlog) {
- 322 105 : if (is_hw(err))
- 323 12 : fprintf(stdlog, "msg:fatal_hardware: ");
- 324 : else
- 325 93 : fprintf(stdlog, "msg:fatal: ");
+ 321 803 : void log_fatal(int err, const char* format, ...)
+ 322 : {
+ 323 : va_list ap;
+ 324 :
+ 325 803 : lock_msg();
326 :
- 327 105 : va_start(ap, format);
- 328 105 : vfprintf(stdlog, format, ap);
- 329 105 : va_end(ap);
- 330 :
- 331 105 : fflush(stdlog);
- 332 : }
- 333 :
- 334 803 : va_start(ap, format);
- 335 803 : vmsg(stderr, format, ap);
- 336 803 : va_end(ap);
- 337 :
- 338 803 : fflush(stderr);
+ 327 803 : if (stdlog) {
+ 328 105 : if (is_hw(err))
+ 329 12 : fprintf(stdlog, "msg:fatal_hardware: ");
+ 330 : else
+ 331 93 : fprintf(stdlog, "msg:fatal: ");
+ 332 :
+ 333 105 : va_start(ap, format);
+ 334 105 : vfprintf(stdlog, format, ap);
+ 335 105 : va_end(ap);
+ 336 :
+ 337 105 : fflush(stdlog);
+ 338 : }
339 :
- 340 803 : unlock_msg();
- 341 803 : }
- 342 :
- 343 365227 : void log_error(int err, const char* format, ...)
- 344 : {
- 345 : va_list ap;
- 346 :
- 347 365227 : lock_msg();
+ 340 803 : va_start(ap, format);
+ 341 803 : vmsg(stderr, format, ap);
+ 342 803 : va_end(ap);
+ 343 :
+ 344 803 : fflush(stderr);
+ 345 :
+ 346 803 : unlock_msg();
+ 347 803 : }
348 :
- 349 365227 : if (stdlog) {
- 350 363389 : if (is_hw(err))
- 351 0 : fprintf(stdlog, "msg:error_hardware: ");
- 352 : else
- 353 363389 : fprintf(stdlog, "msg:error: ");
+ 349 364924 : void log_error(int err, const char* format, ...)
+ 350 : {
+ 351 : va_list ap;
+ 352 :
+ 353 364924 : lock_msg();
354 :
- 355 363389 : va_start(ap, format);
- 356 363389 : vfprintf(stdlog, format, ap);
- 357 363389 : va_end(ap);
- 358 :
- 359 363389 : fflush(stdlog);
- 360 : } else {
- 361 1838 : va_start(ap, format);
- 362 1838 : vmsg(stderr, format, ap);
- 363 1838 : va_end(ap);
+ 355 364924 : if (stdlog) {
+ 356 363085 : if (is_hw(err))
+ 357 0 : fprintf(stdlog, "msg:error_hardware: ");
+ 358 : else
+ 359 363085 : fprintf(stdlog, "msg:error: ");
+ 360 :
+ 361 363085 : va_start(ap, format);
+ 362 363085 : vfprintf(stdlog, format, ap);
+ 363 363085 : va_end(ap);
364 :
- 365 1838 : fflush(stderr);
- 366 : }
- 367 :
- 368 365227 : unlock_msg();
- 369 365227 : }
+ 365 363085 : fflush(stdlog);
+ 366 : } else {
+ 367 1839 : va_start(ap, format);
+ 368 1839 : vmsg(stderr, format, ap);
+ 369 1839 : va_end(ap);
370 :
- 371 4697 : void log_expected(int err, const char* format, ...)
- 372 : {
- 373 : va_list ap;
- 374 :
- 375 4697 : lock_msg();
+ 371 1839 : fflush(stderr);
+ 372 : }
+ 373 :
+ 374 364924 : unlock_msg();
+ 375 364924 : }
376 :
- 377 4697 : if (stdlog) {
- 378 4697 : if (is_hw(err))
- 379 0 : fprintf(stdlog, "msg:error_hardware: "); /* we never expect an hardware error */
- 380 : else
- 381 4697 : fprintf(stdlog, "msg:expected: ");
+ 377 4697 : void log_expected(int err, const char* format, ...)
+ 378 : {
+ 379 : va_list ap;
+ 380 :
+ 381 4697 : lock_msg();
382 :
- 383 4697 : va_start(ap, format);
- 384 4697 : vfprintf(stdlog, format, ap);
- 385 4697 : va_end(ap);
- 386 :
- 387 4697 : fflush(stdlog);
- 388 : }
- 389 :
- 390 4697 : unlock_msg();
- 391 4697 : }
+ 383 4697 : if (stdlog) {
+ 384 4697 : if (is_hw(err))
+ 385 0 : fprintf(stdlog, "msg:error_hardware: "); /* we never expect an hardware error */
+ 386 : else
+ 387 4697 : fprintf(stdlog, "msg:expected: ");
+ 388 :
+ 389 4697 : va_start(ap, format);
+ 390 4697 : vfprintf(stdlog, format, ap);
+ 391 4697 : va_end(ap);
392 :
- 393 21732148 : void log_tag(const char* format, ...)
- 394 : {
- 395 : va_list ap;
- 396 :
- 397 21732148 : lock_msg();
+ 393 4697 : fflush(stdlog);
+ 394 : }
+ 395 :
+ 396 4697 : unlock_msg();
+ 397 4697 : }
398 :
- 399 21732148 : if (stdlog) {
- 400 2567733 : va_start(ap, format);
- 401 2567733 : vfprintf(stdlog, format, ap);
- 402 2567733 : va_end(ap);
- 403 :
- 404 : /* here we intentionally don't flush to make the output faster */
- 405 : }
- 406 :
- 407 21732148 : unlock_msg();
- 408 21732148 : }
+ 399 21733516 : void log_tag(const char* format, ...)
+ 400 : {
+ 401 : va_list ap;
+ 402 :
+ 403 21733516 : lock_msg();
+ 404 :
+ 405 21733516 : if (stdlog) {
+ 406 2568745 : va_start(ap, format);
+ 407 2568745 : vfprintf(stdlog, format, ap);
+ 408 2568745 : va_end(ap);
409 :
- 410 3649 : void log_flush(void)
- 411 : {
- 412 3649 : lock_msg();
- 413 :
- 414 3649 : if (stdlog)
- 415 334 : fflush(stdlog);
- 416 3649 : fflush(stdout);
- 417 3649 : fflush(stderr);
- 418 :
- 419 3649 : unlock_msg();
- 420 3649 : }
- 421 :
- 422 743 : void msg_status(const char* format, ...)
- 423 : {
- 424 : va_list ap;
- 425 :
- 426 743 : lock_msg();
+ 410 : /* here we intentionally don't flush to make the output faster */
+ 411 : }
+ 412 :
+ 413 21733516 : unlock_msg();
+ 414 21733516 : }
+ 415 :
+ 416 3652 : void log_flush(void)
+ 417 : {
+ 418 3652 : lock_msg();
+ 419 :
+ 420 3652 : if (stdlog)
+ 421 335 : fflush(stdlog);
+ 422 3652 : fflush(stdout);
+ 423 3652 : fflush(stderr);
+ 424 :
+ 425 3652 : unlock_msg();
+ 426 3652 : }
427 :
- 428 743 : if (stdlog) {
- 429 407 : fprintf(stdlog, "msg:status: ");
- 430 :
- 431 407 : va_start(ap, format);
- 432 407 : vfprintf(stdlog, format, ap);
- 433 407 : va_end(ap);
- 434 :
- 435 407 : fflush(stdlog);
- 436 : }
- 437 :
- 438 743 : if (msg_level >= MSG_STATUS) {
- 439 743 : va_start(ap, format);
- 440 743 : vmsg(stdout, format, ap);
- 441 743 : va_end(ap);
+ 428 743 : void msg_status(const char* format, ...)
+ 429 : {
+ 430 : va_list ap;
+ 431 :
+ 432 743 : lock_msg();
+ 433 :
+ 434 743 : if (stdlog) {
+ 435 407 : fprintf(stdlog, "msg:status: ");
+ 436 :
+ 437 407 : va_start(ap, format);
+ 438 407 : vfprintf(stdlog, format, ap);
+ 439 407 : va_end(ap);
+ 440 :
+ 441 407 : fflush(stdlog);
442 : }
443 :
- 444 743 : unlock_msg();
- 445 743 : }
- 446 :
- 447 312495 : void msg_info(const char* format, ...)
- 448 : {
- 449 : va_list ap;
- 450 :
- 451 312495 : lock_msg();
+ 444 743 : if (msg_level >= MSG_STATUS) {
+ 445 743 : va_start(ap, format);
+ 446 743 : vmsg(stdout, format, ap);
+ 447 743 : va_end(ap);
+ 448 : }
+ 449 :
+ 450 743 : unlock_msg();
+ 451 743 : }
452 :
- 453 : /* don't output in stdlog as these messages */
- 454 : /* are always paired with a msg_tag() call */
- 455 :
- 456 312495 : if (msg_level >= MSG_INFO) {
- 457 37886 : va_start(ap, format);
- 458 37886 : vmsg(stdout, format, ap);
- 459 37886 : va_end(ap);
- 460 :
- 461 37886 : fflush(stdout);
- 462 : }
- 463 :
- 464 312495 : unlock_msg();
- 465 312495 : }
+ 453 312664 : void msg_info(const char* format, ...)
+ 454 : {
+ 455 : va_list ap;
+ 456 :
+ 457 312664 : lock_msg();
+ 458 :
+ 459 : /* don't output in stdlog as these messages */
+ 460 : /* are always paired with a msg_tag() call */
+ 461 :
+ 462 312664 : if (msg_level >= MSG_INFO) {
+ 463 37904 : va_start(ap, format);
+ 464 37904 : vmsg(stdout, format, ap);
+ 465 37904 : va_end(ap);
466 :
- 467 5081 : void msg_progress(const char* format, ...)
- 468 : {
- 469 : va_list ap;
- 470 :
- 471 5081 : lock_msg();
+ 467 37904 : fflush(stdout);
+ 468 : }
+ 469 :
+ 470 312664 : unlock_msg();
+ 471 312664 : }
472 :
- 473 5081 : if (stdlog) {
- 474 901 : fprintf(stdlog, "msg:progress: ");
- 475 :
- 476 901 : va_start(ap, format);
- 477 901 : vfprintf(stdlog, format, ap);
- 478 901 : va_end(ap);
- 479 :
- 480 901 : fflush(stdlog);
- 481 : }
- 482 :
- 483 5081 : if (msg_level >= MSG_PROGRESS) {
- 484 174 : va_start(ap, format);
- 485 174 : vmsg(stdout, format, ap);
- 486 174 : va_end(ap);
- 487 :
- 488 174 : fflush(stdout);
- 489 : }
- 490 :
- 491 5081 : unlock_msg();
- 492 5081 : }
+ 473 5066 : void msg_progress(const char* format, ...)
+ 474 : {
+ 475 : va_list ap;
+ 476 :
+ 477 5066 : lock_msg();
+ 478 :
+ 479 5066 : if (stdlog) {
+ 480 901 : fprintf(stdlog, "msg:progress: ");
+ 481 :
+ 482 901 : va_start(ap, format);
+ 483 901 : vfprintf(stdlog, format, ap);
+ 484 901 : va_end(ap);
+ 485 :
+ 486 901 : fflush(stdlog);
+ 487 : }
+ 488 :
+ 489 5066 : if (msg_level >= MSG_PROGRESS) {
+ 490 174 : va_start(ap, format);
+ 491 174 : vmsg(stdout, format, ap);
+ 492 174 : va_end(ap);
493 :
- 494 2118 : void msg_bar(const char* format, ...)
- 495 : {
- 496 : va_list ap;
- 497 :
- 498 2118 : lock_msg();
+ 494 174 : fflush(stdout);
+ 495 : }
+ 496 :
+ 497 5066 : unlock_msg();
+ 498 5066 : }
499 :
- 500 : /* don't output in stdlog as these messages */
- 501 : /* are intended for screen only */
- 502 : /* also don't flush stdout as they are intended to be partial messages */
+ 500 2042 : void msg_bar(const char* format, ...)
+ 501 : {
+ 502 : va_list ap;
503 :
- 504 2118 : if (msg_level >= MSG_BAR) {
- 505 0 : va_start(ap, format);
- 506 0 : vmsg(stdout, format, ap);
- 507 0 : va_end(ap);
- 508 : }
+ 504 2042 : lock_msg();
+ 505 :
+ 506 : /* don't output in stdlog as these messages */
+ 507 : /* are intended for screen only */
+ 508 : /* also don't flush stdout as they are intended to be partial messages */
509 :
- 510 2118 : unlock_msg();
- 511 2118 : }
- 512 :
- 513 127020 : void msg_verbose(const char* format, ...)
- 514 : {
- 515 : va_list ap;
- 516 :
- 517 127020 : lock_msg();
+ 510 2042 : if (msg_level >= MSG_BAR) {
+ 511 0 : va_start(ap, format);
+ 512 0 : vmsg(stdout, format, ap);
+ 513 0 : va_end(ap);
+ 514 : }
+ 515 :
+ 516 2042 : unlock_msg();
+ 517 2042 : }
518 :
- 519 127020 : if (stdlog) {
- 520 125051 : fprintf(stdlog, "msg:verbose: ");
- 521 :
- 522 125051 : va_start(ap, format);
- 523 125051 : vfprintf(stdlog, format, ap);
- 524 125051 : va_end(ap);
- 525 :
- 526 125051 : fflush(stdlog);
- 527 : }
- 528 :
- 529 127020 : if (msg_level >= MSG_VERBOSE) {
- 530 99 : va_start(ap, format);
- 531 99 : vmsg(stdout, format, ap);
- 532 99 : va_end(ap);
- 533 :
- 534 99 : fflush(stdout);
- 535 : }
- 536 :
- 537 127020 : unlock_msg();
- 538 127020 : }
+ 519 127094 : void msg_verbose(const char* format, ...)
+ 520 : {
+ 521 : va_list ap;
+ 522 :
+ 523 127094 : lock_msg();
+ 524 :
+ 525 127094 : if (stdlog) {
+ 526 125129 : fprintf(stdlog, "msg:verbose: ");
+ 527 :
+ 528 125129 : va_start(ap, format);
+ 529 125129 : vfprintf(stdlog, format, ap);
+ 530 125129 : va_end(ap);
+ 531 :
+ 532 125129 : fflush(stdlog);
+ 533 : }
+ 534 :
+ 535 127094 : if (msg_level >= MSG_VERBOSE) {
+ 536 99 : va_start(ap, format);
+ 537 99 : vmsg(stdout, format, ap);
+ 538 99 : va_end(ap);
539 :
- 540 586 : void msg_flush(void)
- 541 : {
- 542 586 : lock_msg();
- 543 :
- 544 586 : fflush(stdout);
- 545 586 : fflush(stderr);
- 546 :
- 547 586 : unlock_msg();
- 548 586 : }
+ 540 99 : fflush(stdout);
+ 541 : }
+ 542 :
+ 543 127094 : unlock_msg();
+ 544 127094 : }
+ 545 :
+ 546 572 : void msg_flush(void)
+ 547 : {
+ 548 572 : lock_msg();
549 :
- 550 77 : void printc(char c, size_t pad)
- 551 : {
- 552 135 : while (pad) {
- 553 : /* group writes in long pieces */
- 554 : char buf[128];
- 555 58 : size_t len = pad;
- 556 :
- 557 58 : if (len >= sizeof(buf))
- 558 0 : len = sizeof(buf) - 1;
- 559 :
- 560 58 : memset(buf, c, len);
- 561 58 : buf[len] = 0;
+ 550 572 : fflush(stdout);
+ 551 572 : fflush(stderr);
+ 552 :
+ 553 572 : unlock_msg();
+ 554 572 : }
+ 555 :
+ 556 78 : void printc(char c, size_t pad)
+ 557 : {
+ 558 137 : while (pad) {
+ 559 : /* group writes in long pieces */
+ 560 : char buf[128];
+ 561 59 : size_t len = pad;
562 :
- 563 58 : fputs(buf, stdout);
- 564 :
- 565 58 : pad -= len;
- 566 : }
- 567 77 : }
+ 563 59 : if (len >= sizeof(buf))
+ 564 0 : len = sizeof(buf) - 1;
+ 565 :
+ 566 59 : memset(buf, c, len);
+ 567 59 : buf[len] = 0;
568 :
- 569 34 : void printr(const char* str, size_t pad)
- 570 : {
- 571 : size_t len;
- 572 :
- 573 34 : len = strlen(str);
+ 569 59 : fputs(buf, stdout);
+ 570 :
+ 571 59 : pad -= len;
+ 572 : }
+ 573 78 : }
574 :
- 575 34 : if (len < pad)
- 576 34 : printc(' ', pad - len);
- 577 :
- 578 34 : fputs(str, stdout);
- 579 34 : }
+ 575 34 : void printr(const char* str, size_t pad)
+ 576 : {
+ 577 : size_t len;
+ 578 :
+ 579 34 : len = strlen(str);
580 :
- 581 142 : void printl(const char* str, size_t pad)
- 582 : {
- 583 : size_t len;
- 584 :
- 585 142 : fputs(str, stdout);
+ 581 34 : if (len < pad)
+ 582 34 : printc(' ', pad - len);
+ 583 :
+ 584 34 : fputs(str, stdout);
+ 585 34 : }
586 :
- 587 142 : len = strlen(str);
- 588 :
- 589 142 : if (len < pad)
- 590 6 : printc(' ', pad - len);
- 591 142 : }
+ 587 157 : void printl(const char* str, size_t pad)
+ 588 : {
+ 589 : size_t len;
+ 590 :
+ 591 157 : fputs(str, stdout);
592 :
- 593 18 : void printp(double v, size_t pad)
- 594 : {
- 595 : char buf[64];
- 596 18 : const char* s = "%";
- 597 :
- 598 18 : if (v > 0.1)
- 599 0 : snprintf(buf, sizeof(buf), "%5.2f%s", v, s);
- 600 18 : else if (v > 0.01)
- 601 0 : snprintf(buf, sizeof(buf), "%6.3f%s", v, s);
- 602 18 : else if (v > 0.001)
- 603 0 : snprintf(buf, sizeof(buf), "%7.4f%s", v, s);
- 604 18 : else if (v > 0.0001)
- 605 0 : snprintf(buf, sizeof(buf), "%8.5f%s", v, s);
- 606 18 : else if (v > 0.00001)
- 607 0 : snprintf(buf, sizeof(buf), "%9.6f%s", v, s);
- 608 18 : else if (v > 0.000001)
- 609 0 : snprintf(buf, sizeof(buf), "%10.7f%s", v, s);
- 610 18 : else if (v > 0.0000001)
- 611 0 : snprintf(buf, sizeof(buf), "%11.8f%s", v, s);
- 612 18 : else if (v > 0.00000001)
- 613 0 : snprintf(buf, sizeof(buf), "%12.9f%s", v, s);
- 614 18 : else if (v > 0.000000001)
- 615 0 : snprintf(buf, sizeof(buf), "%13.10f%s", v, s);
- 616 18 : else if (v > 0.0000000001)
- 617 0 : snprintf(buf, sizeof(buf), "%14.11f%s", v, s);
- 618 18 : else if (v > 0.00000000001)
- 619 0 : snprintf(buf, sizeof(buf), "%15.12f%s", v, s);
- 620 18 : else if (v > 0.000000000001)
- 621 0 : snprintf(buf, sizeof(buf), "%16.13f%s", v, s);
- 622 : else
- 623 18 : snprintf(buf, sizeof(buf), "%17.14f%s", v, s);
- 624 18 : printl(buf, pad);
- 625 18 : }
- 626 :
- 627 : #define charcat(c) \
- 628 : do { \
- 629 : if (p == end) { \
- 630 : goto bail; \
- 631 : } \
- 632 : *p++ = (c); \
- 633 : } while (0)
- 634 :
- 635 2652388 : const char* esc_tag(const char* str, char* buffer)
- 636 : {
- 637 2652388 : char* begin = buffer;
- 638 2652388 : char* end = begin + ESC_MAX;
- 639 2652388 : char* p = begin;
+ 593 157 : len = strlen(str);
+ 594 :
+ 595 157 : if (len < pad)
+ 596 7 : printc(' ', pad - len);
+ 597 157 : }
+ 598 :
+ 599 18 : void printp(double v, size_t pad)
+ 600 : {
+ 601 : char buf[64];
+ 602 18 : const char* s = "%";
+ 603 :
+ 604 18 : if (v > 0.1)
+ 605 0 : snprintf(buf, sizeof(buf), "%5.2f%s", v, s);
+ 606 18 : else if (v > 0.01)
+ 607 0 : snprintf(buf, sizeof(buf), "%6.3f%s", v, s);
+ 608 18 : else if (v > 0.001)
+ 609 0 : snprintf(buf, sizeof(buf), "%7.4f%s", v, s);
+ 610 18 : else if (v > 0.0001)
+ 611 0 : snprintf(buf, sizeof(buf), "%8.5f%s", v, s);
+ 612 18 : else if (v > 0.00001)
+ 613 0 : snprintf(buf, sizeof(buf), "%9.6f%s", v, s);
+ 614 18 : else if (v > 0.000001)
+ 615 0 : snprintf(buf, sizeof(buf), "%10.7f%s", v, s);
+ 616 18 : else if (v > 0.0000001)
+ 617 0 : snprintf(buf, sizeof(buf), "%11.8f%s", v, s);
+ 618 18 : else if (v > 0.00000001)
+ 619 0 : snprintf(buf, sizeof(buf), "%12.9f%s", v, s);
+ 620 18 : else if (v > 0.000000001)
+ 621 0 : snprintf(buf, sizeof(buf), "%13.10f%s", v, s);
+ 622 18 : else if (v > 0.0000000001)
+ 623 0 : snprintf(buf, sizeof(buf), "%14.11f%s", v, s);
+ 624 18 : else if (v > 0.00000000001)
+ 625 0 : snprintf(buf, sizeof(buf), "%15.12f%s", v, s);
+ 626 18 : else if (v > 0.000000000001)
+ 627 0 : snprintf(buf, sizeof(buf), "%16.13f%s", v, s);
+ 628 : else
+ 629 18 : snprintf(buf, sizeof(buf), "%17.14f%s", v, s);
+ 630 18 : printl(buf, pad);
+ 631 18 : }
+ 632 :
+ 633 : #define charcat(c) \
+ 634 : do { \
+ 635 : if (p == end) { \
+ 636 : goto bail; \
+ 637 : } \
+ 638 : *p++ = (c); \
+ 639 : } while (0)
640 :
- 641 : /* copy string with escaping */
- 642 34792293 : while (*str) {
- 643 32139905 : char c = *str++;
- 644 :
- 645 32139905 : switch (c) {
- 646 3 : case '\n' :
- 647 3 : charcat('\\');
- 648 3 : charcat('n');
- 649 3 : break;
- 650 3 : case '\r' :
- 651 3 : charcat('\\');
- 652 3 : charcat('r');
- 653 3 : break;
- 654 4 : case ':' :
- 655 4 : charcat('\\');
- 656 4 : charcat('d');
- 657 4 : break;
- 658 6 : case '\\' :
- 659 6 : charcat('\\');
- 660 6 : charcat('\\');
- 661 6 : break;
- 662 32139889 : default :
- 663 32139889 : charcat(c);
- 664 32139889 : break;
- 665 : }
- 666 : }
- 667 :
- 668 : /* put final 0 */
- 669 2652388 : if (p == end)
- 670 0 : goto bail;
- 671 2652388 : *p = 0;
- 672 :
- 673 2652388 : return begin;
- 674 :
- 675 0 : bail:
- 676 : /* LCOV_EXCL_START */
- 677 : log_fatal(EINTERNAL, "Escape for log is too long\n");
- 678 : exit(EXIT_FAILURE);
- 679 : /* LCOV_EXCL_STOP */
- 680 : }
- 681 :
- 682 : #ifdef _WIN32
- 683 : static int needs_quote(const char* arg)
- 684 : {
- 685 : while (*arg) {
- 686 : char c = *arg;
- 687 : if (c == ' ' || c == '\t' || c == '\n' || c == '\r' ||
- 688 : c == '&' || c == '|' || c == '(' || c == ')' ||
- 689 : c == '<' || c == '>' || c == '^' || c == '"' ||
- 690 : c == '%' || c == '!' || c == '=' || c == ';' ||
- 691 : (unsigned char)c < 32 || c == 127)
- 692 : return 1;
- 693 : ++arg;
- 694 : }
- 695 :
- 696 : return 0;
- 697 : }
- 698 : #endif
- 699 :
- 700 : struct stream {
- 701 : const char* str;
- 702 : unsigned idx;
- 703 : const char** map;
- 704 : unsigned max;
- 705 : };
- 706 :
- 707 5261663 : static inline char ssget(struct stream* ss)
- 708 : {
- 709 : /* get the next char */
- 710 5261663 : char c = *ss->str++;
- 711 :
- 712 : /* if one string is finished, go to the next */
- 713 5297758 : while (c == 0 && ss->idx + 1 < ss->max) {
- 714 36095 : ss->str = ss->map[++ss->idx];
- 715 36095 : c = *ss->str++;
- 716 : }
+ 641 2653118 : const char* esc_tag(const char* str, char* buffer)
+ 642 : {
+ 643 2653118 : char* begin = buffer;
+ 644 2653118 : char* end = begin + ESC_MAX;
+ 645 2653118 : char* p = begin;
+ 646 :
+ 647 : /* copy string with escaping */
+ 648 34809715 : while (*str) {
+ 649 32156597 : char c = *str++;
+ 650 :
+ 651 32156597 : switch (c) {
+ 652 3 : case '\n' :
+ 653 3 : charcat('\\');
+ 654 3 : charcat('n');
+ 655 3 : break;
+ 656 3 : case '\r' :
+ 657 3 : charcat('\\');
+ 658 3 : charcat('r');
+ 659 3 : break;
+ 660 4 : case ':' :
+ 661 4 : charcat('\\');
+ 662 4 : charcat('d');
+ 663 4 : break;
+ 664 6 : case '\\' :
+ 665 6 : charcat('\\');
+ 666 6 : charcat('\\');
+ 667 6 : break;
+ 668 32156581 : default :
+ 669 32156581 : charcat(c);
+ 670 32156581 : break;
+ 671 : }
+ 672 : }
+ 673 :
+ 674 : /* put final 0 */
+ 675 2653118 : if (p == end)
+ 676 0 : goto bail;
+ 677 2653118 : *p = 0;
+ 678 :
+ 679 2653118 : return begin;
+ 680 :
+ 681 0 : bail:
+ 682 : /* LCOV_EXCL_START */
+ 683 : log_fatal(EINTERNAL, "Escape for log is too long\n");
+ 684 : exit(EXIT_FAILURE);
+ 685 : /* LCOV_EXCL_STOP */
+ 686 : }
+ 687 :
+ 688 : #ifdef _WIN32
+ 689 : static int needs_quote(const char* arg)
+ 690 : {
+ 691 : while (*arg) {
+ 692 : char c = *arg;
+ 693 : if (c == ' ' || c == '\t' || c == '\n' || c == '\r' ||
+ 694 : c == '&' || c == '|' || c == '(' || c == ')' ||
+ 695 : c == '<' || c == '>' || c == '^' || c == '"' ||
+ 696 : c == '%' || c == '!' || c == '=' || c == ';' ||
+ 697 : (unsigned char)c < 32 || c == 127)
+ 698 : return 1;
+ 699 : ++arg;
+ 700 : }
+ 701 :
+ 702 : return 0;
+ 703 : }
+ 704 : #endif
+ 705 :
+ 706 : struct stream {
+ 707 : const char* str;
+ 708 : unsigned idx;
+ 709 : const char** map;
+ 710 : unsigned max;
+ 711 : };
+ 712 :
+ 713 5265543 : static inline char ssget(struct stream* ss)
+ 714 : {
+ 715 : /* get the next char */
+ 716 5265543 : char c = *ss->str++;
717 :
- 718 5261663 : return c;
- 719 : }
- 720 :
- 721 : #ifdef _WIN32
- 722 : const char* esc_shell_multi(const char** str_map, unsigned str_max, char* buffer)
- 723 : {
- 724 : char* begin = buffer;
- 725 : char* end = begin + ESC_MAX;
- 726 : char* p = begin;
- 727 : struct stream ss;
- 728 : char c;
- 729 : unsigned i;
- 730 : int has_quote;
- 731 :
- 732 : has_quote = 0;
- 733 : for (i = 0; i < str_max; ++i) {
- 734 : if (needs_quote(str_map[i]))
- 735 : has_quote = 1;
- 736 : }
+ 718 : /* if one string is finished, go to the next */
+ 719 5301638 : while (c == 0 && ss->idx + 1 < ss->max) {
+ 720 36095 : ss->str = ss->map[++ss->idx];
+ 721 36095 : c = *ss->str++;
+ 722 : }
+ 723 :
+ 724 5265543 : return c;
+ 725 : }
+ 726 :
+ 727 : #ifdef _WIN32
+ 728 : const char* esc_shell_multi(const char** str_map, unsigned str_max, char* buffer)
+ 729 : {
+ 730 : char* begin = buffer;
+ 731 : char* end = begin + ESC_MAX;
+ 732 : char* p = begin;
+ 733 : struct stream ss;
+ 734 : char c;
+ 735 : unsigned i;
+ 736 : int has_quote;
737 :
- 738 : ss.idx = 0;
- 739 : ss.str = str_map[0];
- 740 : ss.map = str_map;
- 741 : ss.max = str_max;
- 742 :
- 743 : if (!has_quote) {
- 744 : c = ssget(&ss);
- 745 : while (c) {
- 746 : charcat(c);
- 747 : c = ssget(&ss);
- 748 : }
- 749 : } else {
- 750 : /* starting quote */
- 751 : charcat('"');
- 752 :
- 753 : c = ssget(&ss);
- 754 : while (c) {
- 755 : int bl = 0;
- 756 : while (c == '\\') {
- 757 : ++bl;
- 758 : c = ssget(&ss);
- 759 : }
- 760 :
- 761 : if (c == 0) {
- 762 : /* double backslashes before closing quote */
- 763 : bl = bl * 2;
- 764 : while (bl--)
- 765 : charcat('\\');
- 766 : break;
- 767 : } else if (c == '"') {
- 768 : /* double backslashes + escape the quote */
- 769 : bl = bl * 2 + 1;
+ 738 : has_quote = 0;
+ 739 : for (i = 0; i < str_max; ++i) {
+ 740 : if (needs_quote(str_map[i]))
+ 741 : has_quote = 1;
+ 742 : }
+ 743 :
+ 744 : ss.idx = 0;
+ 745 : ss.str = str_map[0];
+ 746 : ss.map = str_map;
+ 747 : ss.max = str_max;
+ 748 :
+ 749 : if (!has_quote) {
+ 750 : c = ssget(&ss);
+ 751 : while (c) {
+ 752 : charcat(c);
+ 753 : c = ssget(&ss);
+ 754 : }
+ 755 : } else {
+ 756 : /* starting quote */
+ 757 : charcat('"');
+ 758 :
+ 759 : c = ssget(&ss);
+ 760 : while (c) {
+ 761 : int bl = 0;
+ 762 : while (c == '\\') {
+ 763 : ++bl;
+ 764 : c = ssget(&ss);
+ 765 : }
+ 766 :
+ 767 : if (c == 0) {
+ 768 : /* double backslashes before closing quote */
+ 769 : bl = bl * 2;
770 : while (bl--)
771 : charcat('\\');
- 772 : charcat('"');
- 773 : } else {
- 774 : /* normal backslashes */
- 775 : while (bl--)
- 776 : charcat('\\');
- 777 : charcat(c);
- 778 : }
- 779 :
- 780 : c = ssget(&ss);
- 781 : }
- 782 :
- 783 : /* ending quote */
- 784 : charcat('"');
- 785 : }
- 786 :
- 787 : /* put final 0 */
- 788 : charcat(0);
- 789 :
- 790 : return begin;
- 791 :
- 792 : bail:
- 793 : /* LCOV_EXCL_START */
- 794 : log_fatal(EINTERNAL, "Escape for shell is too long\n");
- 795 : exit(EXIT_FAILURE);
- 796 : /* LCOV_EXCL_STOP */
- 797 : }
- 798 : #else
- 799 366218 : const char* esc_shell_multi(const char** str_map, unsigned str_max, char* buffer)
- 800 : {
- 801 366218 : char* begin = buffer;
- 802 366218 : char* end = begin + ESC_MAX;
- 803 366218 : char* p = begin;
- 804 : struct stream ss;
- 805 : char c;
- 806 :
- 807 366218 : ss.idx = 0;
- 808 366218 : ss.str = str_map[0];
- 809 366218 : ss.map = str_map;
- 810 366218 : ss.max = str_max;
- 811 :
- 812 366218 : c = ssget(&ss);
- 813 5261663 : while (c) {
- 814 4895445 : switch (c) {
- 815 : /* special chars that need to be quoted */
- 816 81442 : case ' ' : /* space */
- 817 : case '\t' : /* tab */
- 818 : case '\n' : /* newline */
- 819 : case '\r' : /* carriage return */
- 820 : case '~' : /* home */
- 821 : case '`' : /* command */
- 822 : case '#' : /* comment */
- 823 : case '$' : /* variable */
- 824 : case '&' : /* background job */
- 825 : case '*' : /* wildcard */
- 826 : case '(' : /* shell */
- 827 : case ')' : /* shell */
- 828 : case '\\' : /* quote */
- 829 : case '|' : /* pipe */
- 830 : case '[' : /* wildcard */
- 831 : case ']' : /* wildcard */
- 832 : case '{' : /* code */
- 833 : case '}' : /* code */
- 834 : case ';' : /* separator */
- 835 : case '\'' : /* quote */
- 836 : case '"' : /* quote */
- 837 : case '<' : /* redirect */
- 838 : case '>' : /* redirect */
- 839 : case '?' : /* wildcard */
- 840 : case '=' : /* assignment */
- 841 : case '!' : /* history expansion */
- 842 81442 : charcat('\\');
- 843 81442 : charcat(c);
- 844 81442 : break;
- 845 4814003 : default :
- 846 : /* check for control characters */
- 847 4814003 : if ((unsigned char)c < 32 || c == 127) {
- 848 6 : charcat('\\');
- 849 6 : charcat(c);
- 850 : } else {
- 851 4813997 : charcat(c);
- 852 : }
- 853 4814003 : break;
- 854 : }
- 855 :
- 856 4895445 : c = ssget(&ss);
- 857 : }
- 858 :
- 859 : /* put final 0 */
- 860 366218 : charcat(0);
+ 772 : break;
+ 773 : } else if (c == '"') {
+ 774 : /* double backslashes + escape the quote */
+ 775 : bl = bl * 2 + 1;
+ 776 : while (bl--)
+ 777 : charcat('\\');
+ 778 : charcat('"');
+ 779 : } else {
+ 780 : /* normal backslashes */
+ 781 : while (bl--)
+ 782 : charcat('\\');
+ 783 : charcat(c);
+ 784 : }
+ 785 :
+ 786 : c = ssget(&ss);
+ 787 : }
+ 788 :
+ 789 : /* ending quote */
+ 790 : charcat('"');
+ 791 : }
+ 792 :
+ 793 : /* put final 0 */
+ 794 : charcat(0);
+ 795 :
+ 796 : return begin;
+ 797 :
+ 798 : bail:
+ 799 : /* LCOV_EXCL_START */
+ 800 : log_fatal(EINTERNAL, "Escape for shell is too long\n");
+ 801 : exit(EXIT_FAILURE);
+ 802 : /* LCOV_EXCL_STOP */
+ 803 : }
+ 804 : #else
+ 805 366387 : const char* esc_shell_multi(const char** str_map, unsigned str_max, char* buffer)
+ 806 : {
+ 807 366387 : char* begin = buffer;
+ 808 366387 : char* end = begin + ESC_MAX;
+ 809 366387 : char* p = begin;
+ 810 : struct stream ss;
+ 811 : char c;
+ 812 :
+ 813 366387 : ss.idx = 0;
+ 814 366387 : ss.str = str_map[0];
+ 815 366387 : ss.map = str_map;
+ 816 366387 : ss.max = str_max;
+ 817 :
+ 818 366387 : c = ssget(&ss);
+ 819 5265543 : while (c) {
+ 820 4899156 : switch (c) {
+ 821 : /* special chars that need to be quoted */
+ 822 81659 : case ' ' : /* space */
+ 823 : case '\t' : /* tab */
+ 824 : case '\n' : /* newline */
+ 825 : case '\r' : /* carriage return */
+ 826 : case '~' : /* home */
+ 827 : case '`' : /* command */
+ 828 : case '#' : /* comment */
+ 829 : case '$' : /* variable */
+ 830 : case '&' : /* background job */
+ 831 : case '*' : /* wildcard */
+ 832 : case '(' : /* shell */
+ 833 : case ')' : /* shell */
+ 834 : case '\\' : /* quote */
+ 835 : case '|' : /* pipe */
+ 836 : case '[' : /* wildcard */
+ 837 : case ']' : /* wildcard */
+ 838 : case '{' : /* code */
+ 839 : case '}' : /* code */
+ 840 : case ';' : /* separator */
+ 841 : case '\'' : /* quote */
+ 842 : case '"' : /* quote */
+ 843 : case '<' : /* redirect */
+ 844 : case '>' : /* redirect */
+ 845 : case '?' : /* wildcard */
+ 846 : case '=' : /* assignment */
+ 847 : case '!' : /* history expansion */
+ 848 81659 : charcat('\\');
+ 849 81659 : charcat(c);
+ 850 81659 : break;
+ 851 4817497 : default :
+ 852 : /* check for control characters */
+ 853 4817497 : if ((unsigned char)c < 32 || c == 127) {
+ 854 6 : charcat('\\');
+ 855 6 : charcat(c);
+ 856 : } else {
+ 857 4817491 : charcat(c);
+ 858 : }
+ 859 4817497 : break;
+ 860 : }
861 :
- 862 366218 : return begin;
- 863 :
- 864 0 : bail:
- 865 : /* LCOV_EXCL_START */
- 866 : log_fatal(EINTERNAL, "Escape for shell is too long\n");
- 867 : exit(EXIT_FAILURE);
- 868 : /* LCOV_EXCL_STOP */
- 869 : }
- 870 : #endif
- 871 :
- 872 21 : char* strpolish(char* s)
- 873 : {
- 874 21 : char* i = s;
- 875 :
- 876 1030 : while (*i) {
- 877 1009 : if (isspace(*i) || !isprint(*i))
- 878 119 : *i = ' ';
- 879 1009 : ++i;
- 880 : }
+ 862 4899156 : c = ssget(&ss);
+ 863 : }
+ 864 :
+ 865 : /* put final 0 */
+ 866 366387 : charcat(0);
+ 867 :
+ 868 366387 : return begin;
+ 869 :
+ 870 0 : bail:
+ 871 : /* LCOV_EXCL_START */
+ 872 : log_fatal(EINTERNAL, "Escape for shell is too long\n");
+ 873 : exit(EXIT_FAILURE);
+ 874 : /* LCOV_EXCL_STOP */
+ 875 : }
+ 876 : #endif
+ 877 :
+ 878 256 : char* strpolish(char* s)
+ 879 : {
+ 880 256 : char* i = s;
881 :
- 882 21 : return s;
- 883 : }
- 884 :
- 885 1718 : unsigned strsplit(char** split_map, unsigned split_max, char* str, const char* delimiters)
- 886 : {
- 887 1718 : unsigned mac = 0;
- 888 :
- 889 : /* skip initial delimiters */
- 890 1718 : str += strspn(str, delimiters);
- 891 :
- 892 8782 : while (*str != 0 || mac == split_max) {
- 893 : /* start of the token */
- 894 7064 : split_map[mac] = str;
- 895 7064 : ++mac;
- 896 :
- 897 : /* find the first delimiter or the end of the string */
- 898 7064 : str += strcspn(str, delimiters);
- 899 :
- 900 : /* put the final terminator if missing */
- 901 7064 : if (*str != 0)
- 902 5538 : *str++ = 0;
- 903 :
- 904 : /* skip trailing delimiters */
- 905 7064 : str += strspn(str, delimiters);
- 906 : }
- 907 :
- 908 1718 : return mac;
- 909 : }
- 910 :
- 911 13 : char* strtrim(char* str)
- 912 : {
- 913 : char* begin;
- 914 : char* end;
- 915 :
- 916 13 : begin = str;
- 917 14 : while (begin[0] && isspace((unsigned char)begin[0]))
- 918 1 : ++begin;
- 919 :
- 920 13 : end = begin + strlen(begin);
- 921 28 : while (end > begin && isspace((unsigned char)end[-1]))
- 922 15 : --end;
- 923 :
- 924 13 : end[0] = 0;
+ 882 12430 : while (*i) {
+ 883 12174 : if (isspace(*i) || !isprint(*i))
+ 884 2975 : *i = ' ';
+ 885 12174 : ++i;
+ 886 : }
+ 887 :
+ 888 256 : return s;
+ 889 : }
+ 890 :
+ 891 1720 : unsigned strsplit(char** split_map, unsigned split_max, char* str, const char* delimiters)
+ 892 : {
+ 893 1720 : unsigned mac = 0;
+ 894 :
+ 895 : /* skip initial delimiters */
+ 896 1720 : str += strspn(str, delimiters);
+ 897 :
+ 898 8786 : while (*str != 0 || mac == split_max) {
+ 899 : /* start of the token */
+ 900 7066 : split_map[mac] = str;
+ 901 7066 : ++mac;
+ 902 :
+ 903 : /* find the first delimiter or the end of the string */
+ 904 7066 : str += strcspn(str, delimiters);
+ 905 :
+ 906 : /* put the final terminator if missing */
+ 907 7066 : if (*str != 0)
+ 908 5538 : *str++ = 0;
+ 909 :
+ 910 : /* skip trailing delimiters */
+ 911 7066 : str += strspn(str, delimiters);
+ 912 : }
+ 913 :
+ 914 1720 : return mac;
+ 915 : }
+ 916 :
+ 917 67 : char* strtrim(char* str)
+ 918 : {
+ 919 : char* begin;
+ 920 : char* end;
+ 921 :
+ 922 67 : begin = str;
+ 923 97 : while (begin[0] && isspace((unsigned char)begin[0]))
+ 924 30 : ++begin;
925 :
- 926 13 : if (begin != end)
- 927 13 : memmove(str, begin, end - begin + 1);
- 928 :
- 929 13 : return str;
- 930 : }
+ 926 67 : end = begin + strlen(begin);
+ 927 247 : while (end > begin && isspace((unsigned char)end[-1]))
+ 928 180 : --end;
+ 929 :
+ 930 67 : end[0] = 0;
931 :
- 932 2 : char* strlwr(char* str)
- 933 : {
- 934 2 : char* s = str;
- 935 :
- 936 24 : while (*s) {
- 937 22 : *s = tolower((unsigned char)*s);
- 938 22 : ++s;
- 939 : }
- 940 :
- 941 2 : return str;
- 942 : }
- 943 :
- 944 11 : char* worddigitstr(const char* haystack, const char* needle)
- 945 : {
- 946 11 : size_t len = strlen(needle);
- 947 : const char* s;
- 948 :
- 949 11 : if (len == 0)
- 950 1 : return NULL;
- 951 :
- 952 11 : for (s = haystack; (s = strstr(s, needle)) != NULL; ++s) {
- 953 :
- 954 : /* left boundary */
- 955 8 : if (s == haystack || isspace((unsigned char)s[-1]) || isdigit((unsigned char)s[-1])) {
- 956 : /* right boundary */
- 957 7 : if (s[len] == '\0' || isspace((unsigned char)s[len]) || isdigit((unsigned char)s[len])) {
- 958 7 : return (char*)s;
- 959 : }
- 960 : }
- 961 : }
- 962 :
- 963 3 : return NULL;
- 964 : }
- 965 :
- 966 : /****************************************************************************/
- 967 : /* path */
+ 932 67 : if (begin != end)
+ 933 67 : memmove(str, begin, end - begin + 1);
+ 934 :
+ 935 67 : return str;
+ 936 : }
+ 937 :
+ 938 2 : char* strlwr(char* str)
+ 939 : {
+ 940 2 : char* s = str;
+ 941 :
+ 942 24 : while (*s) {
+ 943 22 : *s = tolower((unsigned char)*s);
+ 944 22 : ++s;
+ 945 : }
+ 946 :
+ 947 2 : return str;
+ 948 : }
+ 949 :
+ 950 11 : char* worddigitstr(const char* haystack, const char* needle)
+ 951 : {
+ 952 11 : size_t len = strlen(needle);
+ 953 : const char* s;
+ 954 :
+ 955 11 : if (len == 0)
+ 956 1 : return NULL;
+ 957 :
+ 958 11 : for (s = haystack; (s = strstr(s, needle)) != NULL; ++s) {
+ 959 :
+ 960 : /* left boundary */
+ 961 8 : if (s == haystack || isspace((unsigned char)s[-1]) || isdigit((unsigned char)s[-1])) {
+ 962 : /* right boundary */
+ 963 7 : if (s[len] == '\0' || isspace((unsigned char)s[len]) || isdigit((unsigned char)s[len])) {
+ 964 7 : return (char*)s;
+ 965 : }
+ 966 : }
+ 967 : }
968 :
- 969 1902922 : void pathcpy(char* dst, size_t size, const char* src)
- 970 : {
- 971 1902922 : size_t len = strlen(src);
- 972 :
- 973 1902922 : if (len + 1 > size) {
- 974 : /* LCOV_EXCL_START */
- 975 : log_fatal(EINTERNAL, "Path too long '%s'\n", src);
- 976 : os_abort();
- 977 : /* LCOV_EXCL_STOP */
- 978 : }
- 979 :
- 980 1902922 : memcpy(dst, src, len + 1);
- 981 1902922 : }
- 982 :
- 983 279 : void pathcat(char* dst, size_t size, const char* src)
- 984 : {
- 985 279 : size_t dst_len = strlen(dst);
- 986 279 : size_t src_len = strlen(src);
- 987 :
- 988 279 : if (dst_len + src_len + 1 > size) {
- 989 : /* LCOV_EXCL_START */
- 990 : log_fatal(EINTERNAL, "Path too long '%s%s'\n", dst, src);
- 991 : os_abort();
- 992 : /* LCOV_EXCL_STOP */
- 993 : }
- 994 :
- 995 279 : memcpy(dst + dst_len, src, src_len + 1);
- 996 279 : }
- 997 :
- 998 3601926 : void pathcatl(char* dst, size_t dst_len, size_t size, const char* src)
- 999 : {
- 1000 3601926 : size_t src_len = strlen(src);
- 1001 :
- 1002 3601926 : if (dst_len + src_len + 1 > size) {
- 1003 : /* LCOV_EXCL_START */
- 1004 : log_fatal(EINTERNAL, "Path too long '%s%s'\n", dst, src);
- 1005 : os_abort();
- 1006 : /* LCOV_EXCL_STOP */
- 1007 : }
- 1008 :
- 1009 3601926 : memcpy(dst + dst_len, src, src_len + 1);
- 1010 3601926 : }
- 1011 :
- 1012 788 : void pathcatc(char* dst, size_t size, char c)
- 1013 : {
- 1014 788 : size_t dst_len = strlen(dst);
- 1015 :
- 1016 788 : if (dst_len + 2 > size) {
- 1017 : /* LCOV_EXCL_START */
- 1018 : log_fatal(EINTERNAL, "Path too long '%s%c'\n", dst, c);
- 1019 : os_abort();
- 1020 : /* LCOV_EXCL_STOP */
- 1021 : }
- 1022 :
- 1023 788 : dst[dst_len] = c;
- 1024 788 : dst[dst_len + 1] = 0;
- 1025 788 : }
- 1026 :
- 1027 17981 : void pathimport(char* dst, size_t size, const char* src)
- 1028 : {
- 1029 17981 : pathcpy(dst, size, src);
- 1030 :
- 1031 : #ifdef _WIN32
- 1032 : /* convert the Windows dir separator '\' to C '/', */
- 1033 : /* and the Windows escaping char '^' to the fnmatch '\' */
- 1034 : while (*dst) {
- 1035 : switch (*dst) {
- 1036 : case '\\' :
- 1037 : *dst = '/';
- 1038 : break;
- 1039 : case '^' :
- 1040 : *dst = '\\';
- 1041 : break;
- 1042 : }
- 1043 : ++dst;
- 1044 : }
- 1045 : #endif
- 1046 17981 : }
- 1047 :
- 1048 12234 : void pathexport(char* dst, size_t size, const char* src)
- 1049 : {
- 1050 12234 : pathcpy(dst, size, src);
- 1051 :
- 1052 : #ifdef _WIN32
- 1053 : /* invert the import */
- 1054 : while (*dst) {
- 1055 : switch (*dst) {
- 1056 : case '/' :
- 1057 : *dst = '\\';
- 1058 : break;
- 1059 : case '\\' :
- 1060 : *dst = '^';
- 1061 : break;
- 1062 : }
- 1063 : ++dst;
- 1064 : }
- 1065 : #endif
- 1066 12234 : }
- 1067 :
- 1068 42979947 : void pathprint(char* dst, size_t size, const char* format, ...)
- 1069 : {
- 1070 : size_t len;
- 1071 : va_list ap;
- 1072 :
- 1073 42979947 : va_start(ap, format);
- 1074 42979947 : len = vsnprintf(dst, size, format, ap);
- 1075 42979947 : va_end(ap);
- 1076 :
- 1077 42979947 : if (len >= size) {
- 1078 : /* LCOV_EXCL_START */
- 1079 : if (size > 0) {
- 1080 : dst[size - 1] = 0;
- 1081 : log_fatal(EINTERNAL, "Path too long '%s...'\n", dst);
- 1082 : } else {
- 1083 : log_fatal(EINTERNAL, "Path too long for empty size'\n");
- 1084 : }
- 1085 : os_abort();
- 1086 : /* LCOV_EXCL_STOP */
- 1087 : }
- 1088 42979947 : }
- 1089 :
- 1090 7949 : void pathslash(char* dst, size_t size)
- 1091 : {
- 1092 7949 : size_t len = strlen(dst);
- 1093 :
- 1094 7949 : if (len > 0 && dst[len - 1] != '/') {
- 1095 6286 : if (len + 2 >= size) {
- 1096 : /* LCOV_EXCL_START */
- 1097 : log_fatal(EINTERNAL, "Path too long '%s/'\n", dst);
- 1098 : os_abort();
- 1099 : /* LCOV_EXCL_STOP */
- 1100 : }
- 1101 :
- 1102 6286 : dst[len] = '/';
- 1103 6286 : dst[len + 1] = 0;
- 1104 : }
- 1105 7949 : }
- 1106 :
- 1107 58108 : void pathcut(char* dst)
- 1108 : {
- 1109 58108 : char* slash = strrchr(dst, '/');
- 1110 :
- 1111 58108 : if (slash)
- 1112 58108 : slash[1] = 0;
- 1113 : else
- 1114 0 : dst[0] = 0;
- 1115 58108 : }
+ 969 3 : return NULL;
+ 970 : }
+ 971 :
+ 972 : /****************************************************************************/
+ 973 : /* path */
+ 974 :
+ 975 1902784 : void pathcpy(char* dst, size_t size, const char* src)
+ 976 : {
+ 977 1902784 : size_t len = strlen(src);
+ 978 :
+ 979 1902784 : if (len + 1 > size) {
+ 980 : /* LCOV_EXCL_START */
+ 981 : log_fatal(EINTERNAL, "Path too long '%s'\n", src);
+ 982 : os_abort();
+ 983 : /* LCOV_EXCL_STOP */
+ 984 : }
+ 985 :
+ 986 1902784 : memcpy(dst, src, len + 1);
+ 987 1902784 : }
+ 988 :
+ 989 280 : void pathcat(char* dst, size_t size, const char* src)
+ 990 : {
+ 991 280 : size_t dst_len = strlen(dst);
+ 992 280 : size_t src_len = strlen(src);
+ 993 :
+ 994 280 : if (dst_len + src_len + 1 > size) {
+ 995 : /* LCOV_EXCL_START */
+ 996 : log_fatal(EINTERNAL, "Path too long '%s%s'\n", dst, src);
+ 997 : os_abort();
+ 998 : /* LCOV_EXCL_STOP */
+ 999 : }
+ 1000 :
+ 1001 280 : memcpy(dst + dst_len, src, src_len + 1);
+ 1002 280 : }
+ 1003 :
+ 1004 3601926 : void pathcatl(char* dst, size_t dst_len, size_t size, const char* src)
+ 1005 : {
+ 1006 3601926 : size_t src_len = strlen(src);
+ 1007 :
+ 1008 3601926 : if (dst_len + src_len + 1 > size) {
+ 1009 : /* LCOV_EXCL_START */
+ 1010 : log_fatal(EINTERNAL, "Path too long '%s%s'\n", dst, src);
+ 1011 : os_abort();
+ 1012 : /* LCOV_EXCL_STOP */
+ 1013 : }
+ 1014 :
+ 1015 3601926 : memcpy(dst + dst_len, src, src_len + 1);
+ 1016 3601926 : }
+ 1017 :
+ 1018 788 : void pathcatc(char* dst, size_t size, char c)
+ 1019 : {
+ 1020 788 : size_t dst_len = strlen(dst);
+ 1021 :
+ 1022 788 : if (dst_len + 2 > size) {
+ 1023 : /* LCOV_EXCL_START */
+ 1024 : log_fatal(EINTERNAL, "Path too long '%s%c'\n", dst, c);
+ 1025 : os_abort();
+ 1026 : /* LCOV_EXCL_STOP */
+ 1027 : }
+ 1028 :
+ 1029 788 : dst[dst_len] = c;
+ 1030 788 : dst[dst_len + 1] = 0;
+ 1031 788 : }
+ 1032 :
+ 1033 18024 : void pathimport(char* dst, size_t size, const char* src)
+ 1034 : {
+ 1035 18024 : pathcpy(dst, size, src);
+ 1036 :
+ 1037 : #ifdef _WIN32
+ 1038 : /* convert the Windows dir separator '\' to C '/', */
+ 1039 : /* and the Windows escaping char '^' to the fnmatch '\' */
+ 1040 : while (*dst) {
+ 1041 : switch (*dst) {
+ 1042 : case '\\' :
+ 1043 : *dst = '/';
+ 1044 : break;
+ 1045 : case '^' :
+ 1046 : *dst = '\\';
+ 1047 : break;
+ 1048 : }
+ 1049 : ++dst;
+ 1050 : }
+ 1051 : #endif
+ 1052 18024 : }
+ 1053 :
+ 1054 12234 : void pathexport(char* dst, size_t size, const char* src)
+ 1055 : {
+ 1056 12234 : pathcpy(dst, size, src);
+ 1057 :
+ 1058 : #ifdef _WIN32
+ 1059 : /* invert the import */
+ 1060 : while (*dst) {
+ 1061 : switch (*dst) {
+ 1062 : case '/' :
+ 1063 : *dst = '\\';
+ 1064 : break;
+ 1065 : case '\\' :
+ 1066 : *dst = '^';
+ 1067 : break;
+ 1068 : }
+ 1069 : ++dst;
+ 1070 : }
+ 1071 : #endif
+ 1072 12234 : }
+ 1073 :
+ 1074 42981264 : void pathprint(char* dst, size_t size, const char* format, ...)
+ 1075 : {
+ 1076 : size_t len;
+ 1077 : va_list ap;
+ 1078 :
+ 1079 42981264 : va_start(ap, format);
+ 1080 42981264 : len = vsnprintf(dst, size, format, ap);
+ 1081 42981264 : va_end(ap);
+ 1082 :
+ 1083 42981264 : if (len >= size) {
+ 1084 : /* LCOV_EXCL_START */
+ 1085 : if (size > 0) {
+ 1086 : dst[size - 1] = 0;
+ 1087 : log_fatal(EINTERNAL, "Path too long '%s...'\n", dst);
+ 1088 : } else {
+ 1089 : log_fatal(EINTERNAL, "Path too long for empty size'\n");
+ 1090 : }
+ 1091 : os_abort();
+ 1092 : /* LCOV_EXCL_STOP */
+ 1093 : }
+ 1094 42981264 : }
+ 1095 :
+ 1096 7959 : void pathslash(char* dst, size_t size)
+ 1097 : {
+ 1098 7959 : size_t len = strlen(dst);
+ 1099 :
+ 1100 7959 : if (len > 0 && dst[len - 1] != '/') {
+ 1101 6286 : if (len + 2 >= size) {
+ 1102 : /* LCOV_EXCL_START */
+ 1103 : log_fatal(EINTERNAL, "Path too long '%s/'\n", dst);
+ 1104 : os_abort();
+ 1105 : /* LCOV_EXCL_STOP */
+ 1106 : }
+ 1107 :
+ 1108 6286 : dst[len] = '/';
+ 1109 6286 : dst[len + 1] = 0;
+ 1110 : }
+ 1111 7959 : }
+ 1112 :
+ 1113 58110 : void pathcut(char* dst)
+ 1114 : {
+ 1115 58110 : char* slash = strrchr(dst, '/');
1116 :
- 1117 53116131 : int pathcmp(const char* a, const char* b)
- 1118 : {
- 1119 : #ifdef _WIN32
- 1120 : char ai[PATH_MAX];
- 1121 : char bi[PATH_MAX];
+ 1117 58110 : if (slash)
+ 1118 58110 : slash[1] = 0;
+ 1119 : else
+ 1120 0 : dst[0] = 0;
+ 1121 58110 : }
1122 :
- 1123 : /* import to convert \ to / */
- 1124 : pathimport(ai, sizeof(ai), a);
- 1125 : pathimport(bi, sizeof(bi), b);
- 1126 :
- 1127 : /* case insensitive compare in Windows */
- 1128 : return stricmp(ai, bi);
- 1129 : #else
- 1130 53116131 : return strcmp(a, b);
- 1131 : #endif
- 1132 : }
- 1133 :
- 1134 0 : int path_is_root_of(const char* root, const char* path)
- 1135 : {
- 1136 0 : while (*root && *path) {
- 1137 : #ifdef _WIN32
- 1138 : /* case insensitive compare in Windows */
- 1139 : char r = tolower((unsigned char)*root);
- 1140 : char p = tolower((unsigned char)*path);
- 1141 : if (r == '\\')
- 1142 : r = '/';
- 1143 : if (p == '\\')
- 1144 : p = '/';
- 1145 : if (r != p)
- 1146 : return 0;
- 1147 : #else
- 1148 0 : if (*root != *path)
- 1149 0 : return 0;
- 1150 : #endif
- 1151 0 : ++root;
- 1152 0 : ++path;
- 1153 : }
- 1154 :
- 1155 0 : return *root == 0 && *path != 0;
- 1156 : }
- 1157 :
- 1158 : /****************************************************************************/
- 1159 : /* file-system */
+ 1123 53117221 : int pathcmp(const char* a, const char* b)
+ 1124 : {
+ 1125 : #ifdef _WIN32
+ 1126 : char ai[PATH_MAX];
+ 1127 : char bi[PATH_MAX];
+ 1128 :
+ 1129 : /* import to convert \ to / */
+ 1130 : pathimport(ai, sizeof(ai), a);
+ 1131 : pathimport(bi, sizeof(bi), b);
+ 1132 :
+ 1133 : /* case insensitive compare in Windows */
+ 1134 : return stricmp(ai, bi);
+ 1135 : #else
+ 1136 53117221 : return strcmp(a, b);
+ 1137 : #endif
+ 1138 : }
+ 1139 :
+ 1140 0 : int path_is_root_of(const char* root, const char* path)
+ 1141 : {
+ 1142 0 : while (*root && *path) {
+ 1143 : #ifdef _WIN32
+ 1144 : /* case insensitive compare in Windows */
+ 1145 : char r = tolower((unsigned char)*root);
+ 1146 : char p = tolower((unsigned char)*path);
+ 1147 : if (r == '\\')
+ 1148 : r = '/';
+ 1149 : if (p == '\\')
+ 1150 : p = '/';
+ 1151 : if (r != p)
+ 1152 : return 0;
+ 1153 : #else
+ 1154 0 : if (*root != *path)
+ 1155 0 : return 0;
+ 1156 : #endif
+ 1157 0 : ++root;
+ 1158 0 : ++path;
+ 1159 : }
1160 :
- 1161 787726 : int mkancestor(const char* file)
- 1162 : {
- 1163 : char dir[PATH_MAX];
- 1164 : struct stat st;
- 1165 : char* c;
+ 1161 0 : return *root == 0 && *path != 0;
+ 1162 : }
+ 1163 :
+ 1164 : /****************************************************************************/
+ 1165 : /* file-system */
1166 :
- 1167 787726 : pathcpy(dir, sizeof(dir), file);
- 1168 :
- 1169 787726 : c = strrchr(dir, '/');
- 1170 787726 : if (!c) {
- 1171 : /* no ancestor */
- 1172 0 : return 0;
- 1173 : }
+ 1167 787783 : int mkancestor(const char* file)
+ 1168 : {
+ 1169 : char dir[PATH_MAX];
+ 1170 : struct stat st;
+ 1171 : char* c;
+ 1172 :
+ 1173 787783 : pathcpy(dir, sizeof(dir), file);
1174 :
- 1175 : /* clear the file */
- 1176 787726 : *c = 0;
- 1177 :
- 1178 : /* if it's the root dir */
- 1179 787726 : if (*dir == 0) {
- 1180 : /* nothing more to do */
- 1181 0 : return 0;
- 1182 : }
+ 1175 787783 : c = strrchr(dir, '/');
+ 1176 787783 : if (!c) {
+ 1177 : /* no ancestor */
+ 1178 0 : return 0;
+ 1179 : }
+ 1180 :
+ 1181 : /* clear the file */
+ 1182 787783 : *c = 0;
1183 :
- 1184 : #ifdef _WIN32
- 1185 : /* if it's a drive specification like "C:" */
- 1186 : if (isalpha(dir[0]) && dir[1] == ':' && dir[2] == 0) {
- 1187 : /* nothing more to do */
- 1188 : return 0;
- 1189 : }
- 1190 : #endif
- 1191 :
- 1192 : /*
- 1193 : * Check if the dir already exists using lstat().
- 1194 : *
- 1195 : * Note that in Windows when dealing with read-only media
- 1196 : * you cannot try to create the directory, and expecting
- 1197 : * the EEXIST error because the call will fail with ERROR_WRITE_PROTECTED.
- 1198 : *
- 1199 : * Also in Windows it's better to use lstat() than stat() because it
- 1200 : * doesn't need to open the dir with CreateFile().
- 1201 : */
- 1202 787726 : if (lstat(dir, &st) == 0) {
- 1203 : /* it already exists */
- 1204 787648 : return 0;
- 1205 : }
- 1206 :
- 1207 : /* recursively create them all */
- 1208 78 : if (mkancestor(dir) != 0) {
- 1209 : /* LCOV_EXCL_START */
- 1210 : return -1;
- 1211 : /* LCOV_EXCL_STOP */
- 1212 : }
- 1213 :
- 1214 : /* create it */
- 1215 78 : if (mkdir(dir, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) != 0) {
- 1216 : /* LCOV_EXCL_START */
- 1217 : log_fatal(errno, "Error creating directory '%s'. %s.\n", dir, strerror(errno));
- 1218 : return -1;
- 1219 : /* LCOV_EXCL_STOP */
- 1220 : }
- 1221 :
- 1222 78 : return 0;
- 1223 : }
- 1224 :
- 1225 121348 : int fmtime(int f, int64_t mtime_sec, int mtime_nsec)
- 1226 : {
- 1227 : #if HAVE_FUTIMENS
- 1228 : struct timespec tv[2];
- 1229 : #else
- 1230 : struct timeval tv[2];
- 1231 : #endif
- 1232 : int ret;
- 1233 :
- 1234 : #if HAVE_FUTIMENS /* futimens() is preferred because it gives nanosecond precision */
- 1235 121348 : tv[0].tv_sec = mtime_sec;
- 1236 121348 : if (mtime_nsec != STAT_NSEC_INVALID)
- 1237 121348 : tv[0].tv_nsec = mtime_nsec;
- 1238 : else
- 1239 0 : tv[0].tv_nsec = 0;
- 1240 121348 : tv[1].tv_sec = tv[0].tv_sec;
- 1241 121348 : tv[1].tv_nsec = tv[0].tv_nsec;
- 1242 :
- 1243 121348 : ret = futimens(f, tv);
- 1244 : #elif HAVE_FUTIMES /* fallback to futimes() if nanosecond precision is not available */
- 1245 : tv[0].tv_sec = mtime_sec;
- 1246 : if (mtime_nsec != STAT_NSEC_INVALID)
- 1247 : tv[0].tv_usec = mtime_nsec / 1000;
- 1248 : else
- 1249 : tv[0].tv_usec = 0;
- 1250 : tv[1].tv_sec = tv[0].tv_sec;
- 1251 : tv[1].tv_usec = tv[0].tv_usec;
- 1252 :
- 1253 : ret = futimes(f, tv);
- 1254 : #elif HAVE_FUTIMESAT /* fallback to futimesat() for Solaris, it only has futimesat() */
- 1255 : tv[0].tv_sec = mtime_sec;
- 1256 : if (mtime_nsec != STAT_NSEC_INVALID)
- 1257 : tv[0].tv_usec = mtime_nsec / 1000;
- 1258 : else
- 1259 : tv[0].tv_usec = 0;
- 1260 : tv[1].tv_sec = tv[0].tv_sec;
- 1261 : tv[1].tv_usec = tv[0].tv_usec;
- 1262 :
- 1263 : ret = futimesat(f, 0, tv);
- 1264 : #else
- 1265 : #error No function available to set file timestamps with sub-second precision
- 1266 : #endif
- 1267 :
- 1268 121348 : return ret;
- 1269 : }
- 1270 :
- 1271 11645 : int lmtime(const char* path, int64_t mtime_sec, int mtime_nsec)
- 1272 : {
- 1273 : #if HAVE_UTIMENSAT
- 1274 : struct timespec tv[2];
- 1275 : #else
- 1276 : struct timeval tv[2];
- 1277 : #endif
- 1278 : int ret;
- 1279 :
- 1280 : #if HAVE_UTIMENSAT /* utimensat() is preferred because it gives nanosecond precision */
- 1281 11645 : tv[0].tv_sec = mtime_sec;
- 1282 11645 : if (mtime_nsec != STAT_NSEC_INVALID)
- 1283 11645 : tv[0].tv_nsec = mtime_nsec;
- 1284 : else
- 1285 0 : tv[0].tv_nsec = 0;
- 1286 11645 : tv[1].tv_sec = tv[0].tv_sec;
- 1287 11645 : tv[1].tv_nsec = tv[0].tv_nsec;
- 1288 :
- 1289 11645 : ret = utimensat(AT_FDCWD, path, tv, AT_SYMLINK_NOFOLLOW);
- 1290 : #elif HAVE_LUTIMES /* fallback to lutimes() if nanosecond precision is not available */
- 1291 : tv[0].tv_sec = mtime_sec;
- 1292 : if (mtime_nsec != STAT_NSEC_INVALID)
- 1293 : tv[0].tv_usec = mtime_nsec / 1000;
- 1294 : else
- 1295 : tv[0].tv_usec = 0;
- 1296 : tv[1].tv_sec = tv[0].tv_sec;
- 1297 : tv[1].tv_usec = tv[0].tv_usec;
- 1298 :
- 1299 : ret = lutimes(path, tv);
- 1300 : #elif HAVE_FUTIMESAT /* fallback to futimesat() for Solaris, it only has futimesat() */
- 1301 : tv[0].tv_sec = mtime_sec;
- 1302 : if (mtime_nsec != STAT_NSEC_INVALID)
- 1303 : tv[0].tv_usec = mtime_nsec / 1000;
- 1304 : else
- 1305 : tv[0].tv_usec = 0;
- 1306 : tv[1].tv_sec = tv[0].tv_sec;
- 1307 : tv[1].tv_usec = tv[0].tv_usec;
- 1308 :
- 1309 : ret = futimesat(AT_FDCWD, path, tv);
- 1310 : #else
- 1311 : #error No function available to set file timestamps with sub-second precision
- 1312 : #endif
- 1313 :
- 1314 11645 : return ret;
- 1315 : }
- 1316 :
- 1317 : /****************************************************************************/
- 1318 : /* advise */
+ 1184 : /* if it's the root dir */
+ 1185 787783 : if (*dir == 0) {
+ 1186 : /* nothing more to do */
+ 1187 0 : return 0;
+ 1188 : }
+ 1189 :
+ 1190 : #ifdef _WIN32
+ 1191 : /* if it's a drive specification like "C:" */
+ 1192 : if (isalpha(dir[0]) && dir[1] == ':' && dir[2] == 0) {
+ 1193 : /* nothing more to do */
+ 1194 : return 0;
+ 1195 : }
+ 1196 : #endif
+ 1197 :
+ 1198 : /*
+ 1199 : * Check if the dir already exists using lstat().
+ 1200 : *
+ 1201 : * Note that in Windows when dealing with read-only media
+ 1202 : * you cannot try to create the directory, and expecting
+ 1203 : * the EEXIST error because the call will fail with ERROR_WRITE_PROTECTED.
+ 1204 : *
+ 1205 : * Also in Windows it's better to use lstat() than stat() because it
+ 1206 : * doesn't need to open the dir with CreateFile().
+ 1207 : */
+ 1208 787783 : if (lstat(dir, &st) == 0) {
+ 1209 : /* it already exists */
+ 1210 787705 : return 0;
+ 1211 : }
+ 1212 :
+ 1213 : /* recursively create them all */
+ 1214 78 : if (mkancestor(dir) != 0) {
+ 1215 : /* LCOV_EXCL_START */
+ 1216 : return -1;
+ 1217 : /* LCOV_EXCL_STOP */
+ 1218 : }
+ 1219 :
+ 1220 : /* create it */
+ 1221 78 : if (mkdir(dir, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) != 0) {
+ 1222 : /* LCOV_EXCL_START */
+ 1223 : log_fatal(errno, "Error creating directory '%s'. %s.\n", dir, strerror(errno));
+ 1224 : return -1;
+ 1225 : /* LCOV_EXCL_STOP */
+ 1226 : }
+ 1227 :
+ 1228 78 : return 0;
+ 1229 : }
+ 1230 :
+ 1231 121378 : int fmtime(int f, int64_t mtime_sec, int mtime_nsec)
+ 1232 : {
+ 1233 : #if HAVE_FUTIMENS
+ 1234 : struct timespec tv[2];
+ 1235 : #else
+ 1236 : struct timeval tv[2];
+ 1237 : #endif
+ 1238 : int ret;
+ 1239 :
+ 1240 : #if HAVE_FUTIMENS /* futimens() is preferred because it gives nanosecond precision */
+ 1241 121378 : tv[0].tv_sec = mtime_sec;
+ 1242 121378 : if (mtime_nsec != STAT_NSEC_INVALID)
+ 1243 121378 : tv[0].tv_nsec = mtime_nsec;
+ 1244 : else
+ 1245 0 : tv[0].tv_nsec = 0;
+ 1246 121378 : tv[1].tv_sec = tv[0].tv_sec;
+ 1247 121378 : tv[1].tv_nsec = tv[0].tv_nsec;
+ 1248 :
+ 1249 121378 : ret = futimens(f, tv);
+ 1250 : #elif HAVE_FUTIMES /* fallback to futimes() if nanosecond precision is not available */
+ 1251 : tv[0].tv_sec = mtime_sec;
+ 1252 : if (mtime_nsec != STAT_NSEC_INVALID)
+ 1253 : tv[0].tv_usec = mtime_nsec / 1000;
+ 1254 : else
+ 1255 : tv[0].tv_usec = 0;
+ 1256 : tv[1].tv_sec = tv[0].tv_sec;
+ 1257 : tv[1].tv_usec = tv[0].tv_usec;
+ 1258 :
+ 1259 : ret = futimes(f, tv);
+ 1260 : #elif HAVE_FUTIMESAT /* fallback to futimesat() for Solaris, it only has futimesat() */
+ 1261 : tv[0].tv_sec = mtime_sec;
+ 1262 : if (mtime_nsec != STAT_NSEC_INVALID)
+ 1263 : tv[0].tv_usec = mtime_nsec / 1000;
+ 1264 : else
+ 1265 : tv[0].tv_usec = 0;
+ 1266 : tv[1].tv_sec = tv[0].tv_sec;
+ 1267 : tv[1].tv_usec = tv[0].tv_usec;
+ 1268 :
+ 1269 : ret = futimesat(f, 0, tv);
+ 1270 : #else
+ 1271 : #error No function available to set file timestamps with sub-second precision
+ 1272 : #endif
+ 1273 :
+ 1274 121378 : return ret;
+ 1275 : }
+ 1276 :
+ 1277 11645 : int lmtime(const char* path, int64_t mtime_sec, int mtime_nsec)
+ 1278 : {
+ 1279 : #if HAVE_UTIMENSAT
+ 1280 : struct timespec tv[2];
+ 1281 : #else
+ 1282 : struct timeval tv[2];
+ 1283 : #endif
+ 1284 : int ret;
+ 1285 :
+ 1286 : #if HAVE_UTIMENSAT /* utimensat() is preferred because it gives nanosecond precision */
+ 1287 11645 : tv[0].tv_sec = mtime_sec;
+ 1288 11645 : if (mtime_nsec != STAT_NSEC_INVALID)
+ 1289 11645 : tv[0].tv_nsec = mtime_nsec;
+ 1290 : else
+ 1291 0 : tv[0].tv_nsec = 0;
+ 1292 11645 : tv[1].tv_sec = tv[0].tv_sec;
+ 1293 11645 : tv[1].tv_nsec = tv[0].tv_nsec;
+ 1294 :
+ 1295 11645 : ret = utimensat(AT_FDCWD, path, tv, AT_SYMLINK_NOFOLLOW);
+ 1296 : #elif HAVE_LUTIMES /* fallback to lutimes() if nanosecond precision is not available */
+ 1297 : tv[0].tv_sec = mtime_sec;
+ 1298 : if (mtime_nsec != STAT_NSEC_INVALID)
+ 1299 : tv[0].tv_usec = mtime_nsec / 1000;
+ 1300 : else
+ 1301 : tv[0].tv_usec = 0;
+ 1302 : tv[1].tv_sec = tv[0].tv_sec;
+ 1303 : tv[1].tv_usec = tv[0].tv_usec;
+ 1304 :
+ 1305 : ret = lutimes(path, tv);
+ 1306 : #elif HAVE_FUTIMESAT /* fallback to futimesat() for Solaris, it only has futimesat() */
+ 1307 : tv[0].tv_sec = mtime_sec;
+ 1308 : if (mtime_nsec != STAT_NSEC_INVALID)
+ 1309 : tv[0].tv_usec = mtime_nsec / 1000;
+ 1310 : else
+ 1311 : tv[0].tv_usec = 0;
+ 1312 : tv[1].tv_sec = tv[0].tv_sec;
+ 1313 : tv[1].tv_usec = tv[0].tv_usec;
+ 1314 :
+ 1315 : ret = futimesat(AT_FDCWD, path, tv);
+ 1316 : #else
+ 1317 : #error No function available to set file timestamps with sub-second precision
+ 1318 : #endif
1319 :
- 1320 2489611 : void advise_init(struct advise_struct* advise, int mode)
- 1321 : {
- 1322 2489611 : advise->mode = mode;
- 1323 2489611 : advise->dirty_begin = 0;
- 1324 2489611 : advise->dirty_end = 0;
- 1325 2489611 : }
- 1326 :
- 1327 2489611 : int advise_flags(struct advise_struct* advise)
- 1328 : {
- 1329 2489611 : int flags = 0;
- 1330 :
- 1331 2489611 : if (advise->mode == ADVISE_SEQUENTIAL
- 1332 2478269 : || advise->mode == ADVISE_FLUSH
- 1333 2478269 : || advise->mode == ADVISE_FLUSH_WINDOW
- 1334 2466927 : || advise->mode == ADVISE_DISCARD
- 1335 2466927 : || advise->mode == ADVISE_DISCARD_WINDOW
- 1336 : )
- 1337 34026 : flags |= O_SEQUENTIAL;
- 1338 :
- 1339 : #if HAVE_DIRECT_IO
- 1340 2489611 : if (advise->mode == ADVISE_DIRECT)
- 1341 0 : flags |= O_DIRECT;
- 1342 : #endif
- 1343 :
- 1344 2489611 : return flags;
- 1345 : }
- 1346 :
- 1347 2410879 : int advise_open(struct advise_struct* advise, int f)
- 1348 : {
- 1349 : (void)advise;
- 1350 : (void)f;
- 1351 :
- 1352 : #if HAVE_POSIX_FADVISE
- 1353 2410879 : if (advise->mode == ADVISE_SEQUENTIAL
- 1354 2399537 : || advise->mode == ADVISE_FLUSH
- 1355 2399537 : || advise->mode == ADVISE_FLUSH_WINDOW
- 1356 2388195 : || advise->mode == ADVISE_DISCARD
- 1357 2388195 : || advise->mode == ADVISE_DISCARD_WINDOW
- 1358 : ) {
- 1359 : int ret;
- 1360 :
- 1361 : /* advise noreuse access, this avoids to pollute the page cache */
- 1362 : /* supported from Linux Kernel 6.3 with this commit: https://github.com/torvalds/linux/commit/17e810229cb3068b692fa078bd9b3a6527e0866a */
- 1363 34026 : ret = posix_fadvise(f, 0, 0, POSIX_FADV_NOREUSE);
- 1364 34026 : if (ret == ENOSYS) {
- 1365 : /* call is not supported */
- 1366 0 : ret = 0;
- 1367 : }
- 1368 34026 : if (ret != 0) {
- 1369 : /* LCOV_EXCL_START */
- 1370 : errno = ret; /* posix_fadvise return the error code */
- 1371 : return -1;
- 1372 : /* LCOV_EXCL_STOP */
+ 1320 11645 : return ret;
+ 1321 : }
+ 1322 :
+ 1323 : /****************************************************************************/
+ 1324 : /* advise */
+ 1325 :
+ 1326 2489478 : void advise_init(struct advise_struct* advise, int mode)
+ 1327 : {
+ 1328 2489478 : advise->mode = mode;
+ 1329 2489478 : advise->dirty_begin = 0;
+ 1330 2489478 : advise->dirty_end = 0;
+ 1331 2489478 : }
+ 1332 :
+ 1333 2489478 : int advise_flags(struct advise_struct* advise)
+ 1334 : {
+ 1335 2489478 : int flags = 0;
+ 1336 :
+ 1337 2489478 : if (advise->mode == ADVISE_SEQUENTIAL
+ 1338 2478136 : || advise->mode == ADVISE_FLUSH
+ 1339 2478136 : || advise->mode == ADVISE_FLUSH_WINDOW
+ 1340 2466794 : || advise->mode == ADVISE_DISCARD
+ 1341 2466794 : || advise->mode == ADVISE_DISCARD_WINDOW
+ 1342 : )
+ 1343 34026 : flags |= O_SEQUENTIAL;
+ 1344 :
+ 1345 : #if HAVE_DIRECT_IO
+ 1346 2489478 : if (advise->mode == ADVISE_DIRECT)
+ 1347 0 : flags |= O_DIRECT;
+ 1348 : #endif
+ 1349 :
+ 1350 2489478 : return flags;
+ 1351 : }
+ 1352 :
+ 1353 2410781 : int advise_open(struct advise_struct* advise, int f)
+ 1354 : {
+ 1355 : (void)advise;
+ 1356 : (void)f;
+ 1357 :
+ 1358 : #if HAVE_POSIX_FADVISE
+ 1359 2410781 : if (advise->mode == ADVISE_SEQUENTIAL
+ 1360 2399439 : || advise->mode == ADVISE_FLUSH
+ 1361 2399439 : || advise->mode == ADVISE_FLUSH_WINDOW
+ 1362 2388097 : || advise->mode == ADVISE_DISCARD
+ 1363 2388097 : || advise->mode == ADVISE_DISCARD_WINDOW
+ 1364 : ) {
+ 1365 : int ret;
+ 1366 :
+ 1367 : /* advise noreuse access, this avoids to pollute the page cache */
+ 1368 : /* supported from Linux Kernel 6.3 with this commit: https://github.com/torvalds/linux/commit/17e810229cb3068b692fa078bd9b3a6527e0866a */
+ 1369 34026 : ret = posix_fadvise(f, 0, 0, POSIX_FADV_NOREUSE);
+ 1370 34026 : if (ret == ENOSYS) {
+ 1371 : /* call is not supported */
+ 1372 0 : ret = 0;
1373 : }
- 1374 :
- 1375 : /* advise sequential access, this doubles the read-ahead window size */
- 1376 34026 : ret = posix_fadvise(f, 0, 0, POSIX_FADV_SEQUENTIAL);
- 1377 34026 : if (ret == ENOSYS) {
- 1378 : /* call is not supported, like in armhf, see posix_fadvise manpage */
- 1379 0 : ret = 0;
- 1380 : }
- 1381 34026 : if (ret != 0) {
- 1382 : /* LCOV_EXCL_START */
- 1383 : errno = ret; /* posix_fadvise return the error code */
- 1384 : return -1;
- 1385 : /* LCOV_EXCL_STOP */
+ 1374 34026 : if (ret != 0) {
+ 1375 : /* LCOV_EXCL_START */
+ 1376 : errno = ret; /* posix_fadvise return the error code */
+ 1377 : return -1;
+ 1378 : /* LCOV_EXCL_STOP */
+ 1379 : }
+ 1380 :
+ 1381 : /* advise sequential access, this doubles the read-ahead window size */
+ 1382 34026 : ret = posix_fadvise(f, 0, 0, POSIX_FADV_SEQUENTIAL);
+ 1383 34026 : if (ret == ENOSYS) {
+ 1384 : /* call is not supported, like in armhf, see posix_fadvise manpage */
+ 1385 0 : ret = 0;
1386 : }
- 1387 : }
- 1388 : #endif
- 1389 :
- 1390 2410879 : return 0;
- 1391 : }
- 1392 :
- 1393 914575 : int advise_write(struct advise_struct* advise, int f, data_off_t offset, data_off_t size)
- 1394 : {
- 1395 : data_off_t flush_offset;
- 1396 : data_off_t flush_size;
- 1397 : data_off_t discard_offset;
- 1398 : data_off_t discard_size;
- 1399 :
- 1400 : (void)f;
- 1401 : (void)flush_offset;
- 1402 : (void)flush_size;
- 1403 : (void)discard_offset;
- 1404 : (void)discard_size;
+ 1387 34026 : if (ret != 0) {
+ 1388 : /* LCOV_EXCL_START */
+ 1389 : errno = ret; /* posix_fadvise return the error code */
+ 1390 : return -1;
+ 1391 : /* LCOV_EXCL_STOP */
+ 1392 : }
+ 1393 : }
+ 1394 : #endif
+ 1395 :
+ 1396 2410781 : return 0;
+ 1397 : }
+ 1398 :
+ 1399 914297 : int advise_write(struct advise_struct* advise, int f, data_off_t offset, data_off_t size)
+ 1400 : {
+ 1401 : data_off_t flush_offset;
+ 1402 : data_off_t flush_size;
+ 1403 : data_off_t discard_offset;
+ 1404 : data_off_t discard_size;
1405 :
- 1406 914575 : flush_offset = 0;
- 1407 914575 : flush_size = 0;
- 1408 914575 : discard_offset = 0;
- 1409 914575 : discard_size = 0;
- 1410 :
- 1411 : /*
- 1412 : * Follow Linus recommendations about fast writes.
- 1413 : *
- 1414 : * Linus "Unexpected splice "always copy" behavior observed"
- 1415 : * http://thread.gmane.org/gmane.linux.kernel/987247/focus=988070
- 1416 : * ---
- 1417 : * I have had _very_ good experiences with even a rather trivial
- 1418 : * file writer that basically used (iirc) 8MB windows, and the logic was very
- 1419 : * trivial:
- 1420 : *
- 1421 : * - before writing a new 8M window, do "start writeback"
- 1422 : * (SYNC_FILE_RANGE_WRITE) on the previous window, and do
- 1423 : * a wait (SYNC_FILE_RANGE_WAIT_AFTER) on the window before that.
- 1424 : *
- 1425 : * in fact, in its simplest form, you can do it like this (this is from my
- 1426 : * "overwrite disk images" program that I use on old disks):
- 1427 : *
- 1428 : * for (index = 0; index < max_index ;index++) {
- 1429 : * if (write(fd, buffer, BUFSIZE) != BUFSIZE)
- 1430 : * break;
- 1431 : * // This won't block, but will start writeout asynchronously
- 1432 : * sync_file_range(fd, index*BUFSIZE, BUFSIZE, SYNC_FILE_RANGE_WRITE);
- 1433 : * // This does a blocking write-and-wait on any old ranges
- 1434 : * if (index)
- 1435 : * sync_file_range(fd, (index-1)*BUFSIZE, BUFSIZE, SYNC_FILE_RANGE_WAIT_BEFORE|SYNC_FILE_RANGE_WRITE|SYNC_FILE_RANGE_WAIT_AFTER);
- 1436 : * }
- 1437 : *
- 1438 : * and even if you don't actually do a discard (maybe we should add a
- 1439 : * SYNC_FILE_RANGE_DISCARD bit, right now you'd need to do a separate
- 1440 : * fadvise(FADV_DONTNEED) to throw it out) the system behavior is pretty
- 1441 : * nice, because the heavy writer gets good IO performance _and_ leaves only
- 1442 : * easy-to-free pages around after itself.
- 1443 : * ---
- 1444 : *
- 1445 : * Linus "Unexpected splice "always copy" behavior observed"
- 1446 : * http://thread.gmane.org/gmane.linux.kernel/987247/focus=988176
- 1447 : * ---
- 1448 : * The behavior for dirty page writeback is _not_ well defined, and
- 1449 : * if you do POSIX_FADV_DONTNEED, I would suggest you do it as part of that
- 1450 : * writeback logic, ie you do it only on ranges that you have just waited on.
- 1451 : *
- 1452 : * IOW, in my example, you'd couple the
- 1453 : *
- 1454 : * sync_file_range(fd, (index-1)*BUFSIZE, BUFSIZE, SYNC_FILE_RANGE_WAIT_BEFORE|SYNC_FILE_RANGE_WRITE|SYNC_FILE_RANGE_WAIT_AFTER);
- 1455 : *
- 1456 : * with a
+ 1406 : (void)f;
+ 1407 : (void)flush_offset;
+ 1408 : (void)flush_size;
+ 1409 : (void)discard_offset;
+ 1410 : (void)discard_size;
+ 1411 :
+ 1412 914297 : flush_offset = 0;
+ 1413 914297 : flush_size = 0;
+ 1414 914297 : discard_offset = 0;
+ 1415 914297 : discard_size = 0;
+ 1416 :
+ 1417 : /*
+ 1418 : * Follow Linus recommendations about fast writes.
+ 1419 : *
+ 1420 : * Linus "Unexpected splice "always copy" behavior observed"
+ 1421 : * http://thread.gmane.org/gmane.linux.kernel/987247/focus=988070
+ 1422 : * ---
+ 1423 : * I have had _very_ good experiences with even a rather trivial
+ 1424 : * file writer that basically used (iirc) 8MB windows, and the logic was very
+ 1425 : * trivial:
+ 1426 : *
+ 1427 : * - before writing a new 8M window, do "start writeback"
+ 1428 : * (SYNC_FILE_RANGE_WRITE) on the previous window, and do
+ 1429 : * a wait (SYNC_FILE_RANGE_WAIT_AFTER) on the window before that.
+ 1430 : *
+ 1431 : * in fact, in its simplest form, you can do it like this (this is from my
+ 1432 : * "overwrite disk images" program that I use on old disks):
+ 1433 : *
+ 1434 : * for (index = 0; index < max_index ;index++) {
+ 1435 : * if (write(fd, buffer, BUFSIZE) != BUFSIZE)
+ 1436 : * break;
+ 1437 : * // This won't block, but will start writeout asynchronously
+ 1438 : * sync_file_range(fd, index*BUFSIZE, BUFSIZE, SYNC_FILE_RANGE_WRITE);
+ 1439 : * // This does a blocking write-and-wait on any old ranges
+ 1440 : * if (index)
+ 1441 : * sync_file_range(fd, (index-1)*BUFSIZE, BUFSIZE, SYNC_FILE_RANGE_WAIT_BEFORE|SYNC_FILE_RANGE_WRITE|SYNC_FILE_RANGE_WAIT_AFTER);
+ 1442 : * }
+ 1443 : *
+ 1444 : * and even if you don't actually do a discard (maybe we should add a
+ 1445 : * SYNC_FILE_RANGE_DISCARD bit, right now you'd need to do a separate
+ 1446 : * fadvise(FADV_DONTNEED) to throw it out) the system behavior is pretty
+ 1447 : * nice, because the heavy writer gets good IO performance _and_ leaves only
+ 1448 : * easy-to-free pages around after itself.
+ 1449 : * ---
+ 1450 : *
+ 1451 : * Linus "Unexpected splice "always copy" behavior observed"
+ 1452 : * http://thread.gmane.org/gmane.linux.kernel/987247/focus=988176
+ 1453 : * ---
+ 1454 : * The behavior for dirty page writeback is _not_ well defined, and
+ 1455 : * if you do POSIX_FADV_DONTNEED, I would suggest you do it as part of that
+ 1456 : * writeback logic, ie you do it only on ranges that you have just waited on.
1457 : *
- 1458 : * posix_fadvise(fd, (index-1)*BUFSIZE, BUFSIZE, POSIX_FADV_DONTNEED);
+ 1458 : * IOW, in my example, you'd couple the
1459 : *
- 1460 : * afterwards to throw out the pages that you just waited for.
- 1461 : * ---
- 1462 : */
- 1463 :
- 1464 914575 : switch (advise->mode) {
- 1465 0 : case ADVISE_FLUSH :
- 1466 0 : flush_offset = offset;
- 1467 0 : flush_size = size;
- 1468 0 : break;
- 1469 0 : case ADVISE_DISCARD :
- 1470 0 : discard_offset = offset;
- 1471 0 : discard_size = size;
- 1472 0 : break;
- 1473 4687 : case ADVISE_FLUSH_WINDOW :
- 1474 : /* if the dirty range can be extended */
- 1475 4687 : if (advise->dirty_end == offset) {
- 1476 : /* extent the dirty range */
- 1477 4687 : advise->dirty_end += size;
- 1478 :
- 1479 : /* if we reached the window size */
- 1480 4687 : if (advise->dirty_end - advise->dirty_begin >= ADVISE_WINDOW_SIZE) {
- 1481 : /* flush the window */
- 1482 0 : flush_offset = advise->dirty_begin;
- 1483 0 : flush_size = ADVISE_WINDOW_SIZE;
+ 1460 : * sync_file_range(fd, (index-1)*BUFSIZE, BUFSIZE, SYNC_FILE_RANGE_WAIT_BEFORE|SYNC_FILE_RANGE_WRITE|SYNC_FILE_RANGE_WAIT_AFTER);
+ 1461 : *
+ 1462 : * with a
+ 1463 : *
+ 1464 : * posix_fadvise(fd, (index-1)*BUFSIZE, BUFSIZE, POSIX_FADV_DONTNEED);
+ 1465 : *
+ 1466 : * afterwards to throw out the pages that you just waited for.
+ 1467 : * ---
+ 1468 : */
+ 1469 :
+ 1470 914297 : switch (advise->mode) {
+ 1471 0 : case ADVISE_FLUSH :
+ 1472 0 : flush_offset = offset;
+ 1473 0 : flush_size = size;
+ 1474 0 : break;
+ 1475 0 : case ADVISE_DISCARD :
+ 1476 0 : discard_offset = offset;
+ 1477 0 : discard_size = size;
+ 1478 0 : break;
+ 1479 4687 : case ADVISE_FLUSH_WINDOW :
+ 1480 : /* if the dirty range can be extended */
+ 1481 4687 : if (advise->dirty_end == offset) {
+ 1482 : /* extent the dirty range */
+ 1483 4687 : advise->dirty_end += size;
1484 :
- 1485 : /* remove it from the dirty range */
- 1486 0 : advise->dirty_begin += ADVISE_WINDOW_SIZE;
- 1487 : }
- 1488 : } else {
- 1489 : /* otherwise flush the existing dirty */
- 1490 0 : flush_offset = advise->dirty_begin;
- 1491 0 : flush_size = advise->dirty_end - advise->dirty_begin;
- 1492 :
- 1493 : /* and set the new range as dirty */
- 1494 0 : advise->dirty_begin = offset;
- 1495 0 : advise->dirty_end = offset + size;
- 1496 : }
- 1497 4687 : break;
- 1498 4687 : case ADVISE_DISCARD_WINDOW :
- 1499 : /* if the dirty range can be extended */
- 1500 4687 : if (advise->dirty_end == offset) {
- 1501 : /* extent the dirty range */
- 1502 4687 : advise->dirty_end += size;
- 1503 :
- 1504 : /* if we reached the double window size */
- 1505 4687 : if (advise->dirty_end - advise->dirty_begin >= 2 * ADVISE_WINDOW_SIZE) {
- 1506 : /* discard the first window */
- 1507 0 : discard_offset = advise->dirty_begin;
- 1508 0 : discard_size = ADVISE_WINDOW_SIZE;
+ 1485 : /* if we reached the window size */
+ 1486 4687 : if (advise->dirty_end - advise->dirty_begin >= ADVISE_WINDOW_SIZE) {
+ 1487 : /* flush the window */
+ 1488 0 : flush_offset = advise->dirty_begin;
+ 1489 0 : flush_size = ADVISE_WINDOW_SIZE;
+ 1490 :
+ 1491 : /* remove it from the dirty range */
+ 1492 0 : advise->dirty_begin += ADVISE_WINDOW_SIZE;
+ 1493 : }
+ 1494 : } else {
+ 1495 : /* otherwise flush the existing dirty */
+ 1496 0 : flush_offset = advise->dirty_begin;
+ 1497 0 : flush_size = advise->dirty_end - advise->dirty_begin;
+ 1498 :
+ 1499 : /* and set the new range as dirty */
+ 1500 0 : advise->dirty_begin = offset;
+ 1501 0 : advise->dirty_end = offset + size;
+ 1502 : }
+ 1503 4687 : break;
+ 1504 4687 : case ADVISE_DISCARD_WINDOW :
+ 1505 : /* if the dirty range can be extended */
+ 1506 4687 : if (advise->dirty_end == offset) {
+ 1507 : /* extent the dirty range */
+ 1508 4687 : advise->dirty_end += size;
1509 :
- 1510 : /* remove it from the dirty range */
- 1511 0 : advise->dirty_begin += ADVISE_WINDOW_SIZE;
- 1512 :
- 1513 : /* flush the second window */
- 1514 0 : flush_offset = advise->dirty_begin;
- 1515 0 : flush_size = ADVISE_WINDOW_SIZE;
- 1516 : }
- 1517 : } else {
- 1518 : /* otherwise discard the existing dirty */
- 1519 0 : discard_offset = advise->dirty_begin;
- 1520 0 : discard_size = advise->dirty_end - advise->dirty_begin;
- 1521 :
- 1522 : /* and set the new range as dirty */
- 1523 0 : advise->dirty_begin = offset;
- 1524 0 : advise->dirty_end = offset + size;
- 1525 : }
- 1526 4687 : break;
- 1527 : }
- 1528 :
- 1529 : #if HAVE_SYNC_FILE_RANGE
- 1530 914575 : if (flush_size != 0) {
- 1531 : int ret;
- 1532 :
- 1533 : /* start writing immediately */
- 1534 0 : ret = sync_file_range(f, flush_offset, flush_size, SYNC_FILE_RANGE_WRITE);
- 1535 0 : if (ret != 0) {
- 1536 : /* LCOV_EXCL_START */
- 1537 : return -1;
- 1538 : /* LCOV_EXCL_STOP */
- 1539 : }
- 1540 : }
- 1541 : #endif
- 1542 :
- 1543 : #if HAVE_SYNC_FILE_RANGE && HAVE_POSIX_FADVISE
- 1544 914575 : if (discard_size != 0) {
- 1545 : int ret;
- 1546 :
- 1547 : /* send the data to the disk and wait until it's written */
- 1548 0 : ret = sync_file_range(f, discard_offset, discard_size, SYNC_FILE_RANGE_WAIT_BEFORE | SYNC_FILE_RANGE_WRITE | SYNC_FILE_RANGE_WAIT_AFTER);
- 1549 0 : if (ret != 0) {
- 1550 : /* LCOV_EXCL_START */
- 1551 : return -1;
- 1552 : /* LCOV_EXCL_STOP */
- 1553 : }
- 1554 :
- 1555 : /* flush the data from the cache */
- 1556 0 : ret = posix_fadvise(f, discard_offset, discard_size, POSIX_FADV_DONTNEED);
- 1557 : /* for POSIX_FADV_DONTNEED we don't allow failure with ENOSYS */
- 1558 0 : if (ret != 0) {
- 1559 : /* LCOV_EXCL_START */
- 1560 : errno = ret; /* posix_fadvise return the error code */
- 1561 : return -1;
- 1562 : /* LCOV_EXCL_STOP */
- 1563 : }
- 1564 : }
- 1565 : #endif
- 1566 :
- 1567 914575 : return 0;
- 1568 : }
- 1569 :
- 1570 8833871 : int advise_read(struct advise_struct* advise, int f, data_off_t offset, data_off_t size)
- 1571 : {
- 1572 : (void)advise;
- 1573 : (void)f;
- 1574 : (void)offset;
- 1575 : (void)size;
- 1576 :
- 1577 : #if HAVE_POSIX_FADVISE
- 1578 8833871 : if (advise->mode == ADVISE_DISCARD
- 1579 8833871 : || advise->mode == ADVISE_DISCARD_WINDOW
- 1580 : ) {
- 1581 : int ret;
+ 1510 : /* if we reached the double window size */
+ 1511 4687 : if (advise->dirty_end - advise->dirty_begin >= 2 * ADVISE_WINDOW_SIZE) {
+ 1512 : /* discard the first window */
+ 1513 0 : discard_offset = advise->dirty_begin;
+ 1514 0 : discard_size = ADVISE_WINDOW_SIZE;
+ 1515 :
+ 1516 : /* remove it from the dirty range */
+ 1517 0 : advise->dirty_begin += ADVISE_WINDOW_SIZE;
+ 1518 :
+ 1519 : /* flush the second window */
+ 1520 0 : flush_offset = advise->dirty_begin;
+ 1521 0 : flush_size = ADVISE_WINDOW_SIZE;
+ 1522 : }
+ 1523 : } else {
+ 1524 : /* otherwise discard the existing dirty */
+ 1525 0 : discard_offset = advise->dirty_begin;
+ 1526 0 : discard_size = advise->dirty_end - advise->dirty_begin;
+ 1527 :
+ 1528 : /* and set the new range as dirty */
+ 1529 0 : advise->dirty_begin = offset;
+ 1530 0 : advise->dirty_end = offset + size;
+ 1531 : }
+ 1532 4687 : break;
+ 1533 : }
+ 1534 :
+ 1535 : #if HAVE_SYNC_FILE_RANGE
+ 1536 914297 : if (flush_size != 0) {
+ 1537 : int ret;
+ 1538 :
+ 1539 : /* start writing immediately */
+ 1540 0 : ret = sync_file_range(f, flush_offset, flush_size, SYNC_FILE_RANGE_WRITE);
+ 1541 0 : if (ret != 0) {
+ 1542 : /* LCOV_EXCL_START */
+ 1543 : return -1;
+ 1544 : /* LCOV_EXCL_STOP */
+ 1545 : }
+ 1546 : }
+ 1547 : #endif
+ 1548 :
+ 1549 : #if HAVE_SYNC_FILE_RANGE && HAVE_POSIX_FADVISE
+ 1550 914297 : if (discard_size != 0) {
+ 1551 : int ret;
+ 1552 :
+ 1553 : /* send the data to the disk and wait until it's written */
+ 1554 0 : ret = sync_file_range(f, discard_offset, discard_size, SYNC_FILE_RANGE_WAIT_BEFORE | SYNC_FILE_RANGE_WRITE | SYNC_FILE_RANGE_WAIT_AFTER);
+ 1555 0 : if (ret != 0) {
+ 1556 : /* LCOV_EXCL_START */
+ 1557 : return -1;
+ 1558 : /* LCOV_EXCL_STOP */
+ 1559 : }
+ 1560 :
+ 1561 : /* flush the data from the cache */
+ 1562 0 : ret = posix_fadvise(f, discard_offset, discard_size, POSIX_FADV_DONTNEED);
+ 1563 : /* for POSIX_FADV_DONTNEED we don't allow failure with ENOSYS */
+ 1564 0 : if (ret != 0) {
+ 1565 : /* LCOV_EXCL_START */
+ 1566 : errno = ret; /* posix_fadvise return the error code */
+ 1567 : return -1;
+ 1568 : /* LCOV_EXCL_STOP */
+ 1569 : }
+ 1570 : }
+ 1571 : #endif
+ 1572 :
+ 1573 914297 : return 0;
+ 1574 : }
+ 1575 :
+ 1576 8833464 : int advise_read(struct advise_struct* advise, int f, data_off_t offset, data_off_t size)
+ 1577 : {
+ 1578 : (void)advise;
+ 1579 : (void)f;
+ 1580 : (void)offset;
+ 1581 : (void)size;
1582 :
- 1583 : /* flush the data from the cache */
- 1584 27825 : ret = posix_fadvise(f, offset, size, POSIX_FADV_DONTNEED);
- 1585 : /* for POSIX_FADV_DONTNEED we don't allow failure with ENOSYS */
- 1586 27825 : if (ret != 0) {
- 1587 : /* LCOV_EXCL_START */
- 1588 : errno = ret; /* posix_fadvise return the error code */
- 1589 : return -1;
- 1590 : /* LCOV_EXCL_STOP */
- 1591 : }
- 1592 : }
- 1593 : #endif
- 1594 :
- 1595 : /*
- 1596 : * Here we cannot call posix_fadvise(..., POSIX_FADV_WILLNEED) for the next block
- 1597 : * because it may be blocking.
- 1598 : *
- 1599 : * Ted Ts'o "posix_fadvise(POSIX_FADV_WILLNEED) waits before returning?"
- 1600 : * https://lkml.org/lkml/2010/12/6/122
- 1601 : * ---
- 1602 : * readahead and posix_fadvise(POSIX_FADV_WILLNEED) work exactly the same
- 1603 : * way, and in fact share mostly the same code path (see
- 1604 : * force_page_cache_readahead() in mm/readahead.c).
- 1605 : *
- 1606 : * They are asynchronous in that there is no guarantee the pages will be
- 1607 : * in the page cache by the time they return. But at the same time, they
- 1608 : * are not guaranteed to be non-blocking. That is, the work of doing the
- 1609 : * readahead does not take place in a kernel thread. So if you try to
- 1610 : * request I/O than will fit in the request queue, the system call will
- 1611 : * block until some I/O is completed so that more I/O requested cam be
- 1612 : * loaded onto the request queue.
- 1613 : *
- 1614 : * The only way to fix this would be to either put the work on a kernel
- 1615 : * thread (i.e., some kind of workqueue) or in a userspace thread. For
- 1616 : * ion programmer wondering what to do today, I'd suggest the
- 1617 : * latter since it will be more portable across various kernel versions.
- 1618 : *
- 1619 : * This does leave the question about whether we should change the kernel
- 1620 : * to allow readahead() and posix_fadvise(POSIX_FADV_WILLNEED) to be
- 1621 : * non-blocking and do this work in a workqueue (or via some kind of
- 1622 : * callback/continuation scheme). My worry is just doing this if a user
- 1623 : * application does something crazy, like request gigabytes and gigabytes
- 1624 : * of readahead, and then repented of their craziness, there should be a
- 1625 : * way of cancelling the readahead request. Today, the user can just
- 1626 : * kill the application. But if we simply shove the work to a kernel
- 1627 : * thread, it becomes a lot harder to cancel the readahead request. We'd
- 1628 : * have to invent a new API, and then have a way to know whether the user
- 1629 : * has access to kill a particular readahead request, etc.
- 1630 : * ---
- 1631 : */
- 1632 :
- 1633 8833871 : return 0;
- 1634 : }
- 1635 :
- 1636 : /****************************************************************************/
- 1637 : /* memory */
+ 1583 : #if HAVE_POSIX_FADVISE
+ 1584 8833464 : if (advise->mode == ADVISE_DISCARD
+ 1585 8833464 : || advise->mode == ADVISE_DISCARD_WINDOW
+ 1586 : ) {
+ 1587 : int ret;
+ 1588 :
+ 1589 : /* flush the data from the cache */
+ 1590 27825 : ret = posix_fadvise(f, offset, size, POSIX_FADV_DONTNEED);
+ 1591 : /* for POSIX_FADV_DONTNEED we don't allow failure with ENOSYS */
+ 1592 27825 : if (ret != 0) {
+ 1593 : /* LCOV_EXCL_START */
+ 1594 : errno = ret; /* posix_fadvise return the error code */
+ 1595 : return -1;
+ 1596 : /* LCOV_EXCL_STOP */
+ 1597 : }
+ 1598 : }
+ 1599 : #endif
+ 1600 :
+ 1601 : /*
+ 1602 : * Here we cannot call posix_fadvise(..., POSIX_FADV_WILLNEED) for the next block
+ 1603 : * because it may be blocking.
+ 1604 : *
+ 1605 : * Ted Ts'o "posix_fadvise(POSIX_FADV_WILLNEED) waits before returning?"
+ 1606 : * https://lkml.org/lkml/2010/12/6/122
+ 1607 : * ---
+ 1608 : * readahead and posix_fadvise(POSIX_FADV_WILLNEED) work exactly the same
+ 1609 : * way, and in fact share mostly the same code path (see
+ 1610 : * force_page_cache_readahead() in mm/readahead.c).
+ 1611 : *
+ 1612 : * They are asynchronous in that there is no guarantee the pages will be
+ 1613 : * in the page cache by the time they return. But at the same time, they
+ 1614 : * are not guaranteed to be non-blocking. That is, the work of doing the
+ 1615 : * readahead does not take place in a kernel thread. So if you try to
+ 1616 : * request I/O than will fit in the request queue, the system call will
+ 1617 : * block until some I/O is completed so that more I/O requested cam be
+ 1618 : * loaded onto the request queue.
+ 1619 : *
+ 1620 : * The only way to fix this would be to either put the work on a kernel
+ 1621 : * thread (i.e., some kind of workqueue) or in a userspace thread. For
+ 1622 : * ion programmer wondering what to do today, I'd suggest the
+ 1623 : * latter since it will be more portable across various kernel versions.
+ 1624 : *
+ 1625 : * This does leave the question about whether we should change the kernel
+ 1626 : * to allow readahead() and posix_fadvise(POSIX_FADV_WILLNEED) to be
+ 1627 : * non-blocking and do this work in a workqueue (or via some kind of
+ 1628 : * callback/continuation scheme). My worry is just doing this if a user
+ 1629 : * application does something crazy, like request gigabytes and gigabytes
+ 1630 : * of readahead, and then repented of their craziness, there should be a
+ 1631 : * way of cancelling the readahead request. Today, the user can just
+ 1632 : * kill the application. But if we simply shove the work to a kernel
+ 1633 : * thread, it becomes a lot harder to cancel the readahead request. We'd
+ 1634 : * have to invent a new API, and then have a way to know whether the user
+ 1635 : * has access to kill a particular readahead request, etc.
+ 1636 : * ---
+ 1637 : */
1638 :
- 1639 : /**
- 1640 : * Total amount of memory allocated.
- 1641 : */
- 1642 : static size_t mcounter;
- 1643 :
- 1644 488 : size_t malloc_counter_get(void)
- 1645 : {
- 1646 : size_t ret;
- 1647 :
- 1648 488 : lock_memory();
+ 1639 8833464 : return 0;
+ 1640 : }
+ 1641 :
+ 1642 : /****************************************************************************/
+ 1643 : /* memory */
+ 1644 :
+ 1645 : /**
+ 1646 : * Total amount of memory allocated.
+ 1647 : */
+ 1648 : static size_t mcounter;
1649 :
- 1650 488 : ret = mcounter;
- 1651 :
- 1652 488 : unlock_memory();
+ 1650 488 : size_t malloc_counter_get(void)
+ 1651 : {
+ 1652 : size_t ret;
1653 :
- 1654 488 : return ret;
- 1655 : }
- 1656 :
- 1657 20940815 : void malloc_counter_inc(size_t inc)
- 1658 : {
- 1659 20940815 : lock_memory();
- 1660 :
- 1661 20940815 : mcounter += inc;
+ 1654 488 : lock_memory();
+ 1655 :
+ 1656 488 : ret = mcounter;
+ 1657 :
+ 1658 488 : unlock_memory();
+ 1659 :
+ 1660 488 : return ret;
+ 1661 : }
1662 :
- 1663 20940815 : unlock_memory();
- 1664 20940815 : }
- 1665 :
- 1666 : /* LCOV_EXCL_START */
- 1667 : static ssize_t malloc_print(int f, const char* str)
- 1668 : {
- 1669 : ssize_t len = 0;
- 1670 :
- 1671 : while (str[len])
- 1672 : ++len;
- 1673 : return write(f, str, len);
- 1674 : }
- 1675 : /* LCOV_EXCL_STOP */
+ 1663 20941012 : void malloc_counter_inc(size_t inc)
+ 1664 : {
+ 1665 20941012 : lock_memory();
+ 1666 :
+ 1667 20941012 : mcounter += inc;
+ 1668 :
+ 1669 20941012 : unlock_memory();
+ 1670 20941012 : }
+ 1671 :
+ 1672 : /* LCOV_EXCL_START */
+ 1673 : static ssize_t malloc_print(int f, const char* str)
+ 1674 : {
+ 1675 : ssize_t len = 0;
1676 :
- 1677 : /* LCOV_EXCL_START */
- 1678 : static ssize_t malloc_printn(int f, size_t value)
- 1679 : {
- 1680 : char buf[32];
- 1681 : int i;
+ 1677 : while (str[len])
+ 1678 : ++len;
+ 1679 : return write(f, str, len);
+ 1680 : }
+ 1681 : /* LCOV_EXCL_STOP */
1682 :
- 1683 : if (!value)
- 1684 : return write(f, "0", 1);
- 1685 :
- 1686 : i = sizeof(buf);
- 1687 : while (value) {
- 1688 : buf[--i] = (value % 10) + '0';
- 1689 : value /= 10;
- 1690 : }
+ 1683 : /* LCOV_EXCL_START */
+ 1684 : static ssize_t malloc_printn(int f, size_t value)
+ 1685 : {
+ 1686 : char buf[32];
+ 1687 : int i;
+ 1688 :
+ 1689 : if (!value)
+ 1690 : return write(f, "0", 1);
1691 :
- 1692 : return write(f, buf + i, sizeof(buf) - i);
- 1693 : }
- 1694 : /* LCOV_EXCL_STOP */
- 1695 :
- 1696 : /* LCOV_EXCL_START */
- 1697 : void malloc_fail(size_t size)
- 1698 : {
- 1699 : /* don't use printf to avoid any possible extra allocation */
- 1700 : int f = 2; /* stderr */
+ 1692 : i = sizeof(buf);
+ 1693 : while (value) {
+ 1694 : buf[--i] = (value % 10) + '0';
+ 1695 : value /= 10;
+ 1696 : }
+ 1697 :
+ 1698 : return write(f, buf + i, sizeof(buf) - i);
+ 1699 : }
+ 1700 : /* LCOV_EXCL_STOP */
1701 :
- 1702 : malloc_print(f, "Failed for Low Memory!\n");
- 1703 : malloc_print(f, "Allocating ");
- 1704 : malloc_printn(f, size);
- 1705 : malloc_print(f, " bytes.\n");
- 1706 : malloc_print(f, "Already allocated ");
- 1707 : malloc_printn(f, malloc_counter_get());
- 1708 : malloc_print(f, " bytes.\n");
- 1709 : if (sizeof(void*) == 4) {
- 1710 : malloc_print(f, "You are currently using a 32 bits executable.\n");
- 1711 : malloc_print(f, "If you have more than 4GB of memory, please upgrade to a 64 bits one.\n");
- 1712 : }
- 1713 : }
- 1714 : /* LCOV_EXCL_STOP */
- 1715 :
- 1716 14819123 : void* malloc_nofail(size_t size)
- 1717 : {
- 1718 14819123 : void* ptr = malloc(size);
- 1719 :
- 1720 14819123 : if (!ptr) {
- 1721 : /* LCOV_EXCL_START */
- 1722 : malloc_fail(size);
- 1723 : exit(EXIT_FAILURE);
- 1724 : /* LCOV_EXCL_STOP */
- 1725 : }
- 1726 :
- 1727 : #ifndef CHECKER /* Don't preinitialize when running for valgrind */
- 1728 : /* Here we preinitialize the memory to ensure that the OS is really allocating it */
- 1729 : /* and not only reserving the addressable space. */
- 1730 : /* Otherwise we are risking that the OOM (Out Of Memory) killer in Linux will kill the process. */
- 1731 : /* Filling the memory doesn't ensure to disable OOM, but it increase a lot the chances to */
- 1732 : /* get a real error from malloc() instead than a process killed. */
- 1733 : /* Note that calloc() doesn't have the same effect. */
- 1734 14819123 : memset(ptr, 0xA5, size);
- 1735 : #endif
- 1736 :
- 1737 14819123 : malloc_counter_inc(size);
- 1738 :
- 1739 14819123 : return ptr;
- 1740 : }
- 1741 :
- 1742 156192 : void* calloc_nofail(size_t count, size_t size)
- 1743 : {
- 1744 : void* ptr;
- 1745 :
- 1746 156192 : size *= count;
+ 1702 : /* LCOV_EXCL_START */
+ 1703 : void malloc_fail(size_t size)
+ 1704 : {
+ 1705 : /* don't use printf to avoid any possible extra allocation */
+ 1706 : int f = 2; /* stderr */
+ 1707 :
+ 1708 : malloc_print(f, "Failed for Low Memory!\n");
+ 1709 : malloc_print(f, "Allocating ");
+ 1710 : malloc_printn(f, size);
+ 1711 : malloc_print(f, " bytes.\n");
+ 1712 : malloc_print(f, "Already allocated ");
+ 1713 : malloc_printn(f, malloc_counter_get());
+ 1714 : malloc_print(f, " bytes.\n");
+ 1715 : if (sizeof(void*) == 4) {
+ 1716 : malloc_print(f, "You are currently using a 32 bits executable.\n");
+ 1717 : malloc_print(f, "If you have more than 4GB of memory, please upgrade to a 64 bits one.\n");
+ 1718 : }
+ 1719 : }
+ 1720 : /* LCOV_EXCL_STOP */
+ 1721 :
+ 1722 14819141 : void* malloc_nofail(size_t size)
+ 1723 : {
+ 1724 14819141 : void* ptr = malloc(size);
+ 1725 :
+ 1726 14819141 : if (!ptr) {
+ 1727 : /* LCOV_EXCL_START */
+ 1728 : malloc_fail(size);
+ 1729 : exit(EXIT_FAILURE);
+ 1730 : /* LCOV_EXCL_STOP */
+ 1731 : }
+ 1732 :
+ 1733 : #ifndef CHECKER /* Don't preinitialize when running for valgrind */
+ 1734 : /* Here we preinitialize the memory to ensure that the OS is really allocating it */
+ 1735 : /* and not only reserving the addressable space. */
+ 1736 : /* Otherwise we are risking that the OOM (Out Of Memory) killer in Linux will kill the process. */
+ 1737 : /* Filling the memory doesn't ensure to disable OOM, but it increase a lot the chances to */
+ 1738 : /* get a real error from malloc() instead than a process killed. */
+ 1739 : /* Note that calloc() doesn't have the same effect. */
+ 1740 14819141 : memset(ptr, 0xA5, size);
+ 1741 : #endif
+ 1742 :
+ 1743 14819141 : malloc_counter_inc(size);
+ 1744 :
+ 1745 14819141 : return ptr;
+ 1746 : }
1747 :
- 1748 : /* see the note in malloc_nofail() of why we don't use calloc() */
- 1749 156192 : ptr = malloc(size);
- 1750 :
- 1751 156192 : if (!ptr) {
- 1752 : /* LCOV_EXCL_START */
- 1753 : malloc_fail(size);
- 1754 : exit(EXIT_FAILURE);
- 1755 : /* LCOV_EXCL_STOP */
- 1756 : }
- 1757 :
- 1758 156192 : memset(ptr, 0, size);
- 1759 :
- 1760 156192 : malloc_counter_inc(size);
- 1761 :
- 1762 156192 : return ptr;
- 1763 : }
- 1764 :
- 1765 5965500 : char* strdup_nofail(const char* str)
- 1766 : {
- 1767 : size_t size;
- 1768 : char* ptr;
- 1769 :
- 1770 5965500 : size = strlen(str) + 1;
- 1771 :
- 1772 5965500 : ptr = malloc(size);
- 1773 :
- 1774 5965500 : if (!ptr) {
- 1775 : /* LCOV_EXCL_START */
- 1776 : malloc_fail(size);
- 1777 : exit(EXIT_FAILURE);
- 1778 : /* LCOV_EXCL_STOP */
- 1779 : }
- 1780 :
- 1781 5965500 : memcpy(ptr, str, size);
- 1782 :
- 1783 5965500 : malloc_counter_inc(size);
- 1784 :
- 1785 5965500 : return ptr;
- 1786 : }
- 1787 :
- 1788 : /****************************************************************************/
- 1789 : /* smartctl */
+ 1748 156271 : void* calloc_nofail(size_t count, size_t size)
+ 1749 : {
+ 1750 : void* ptr;
+ 1751 :
+ 1752 156271 : size *= count;
+ 1753 :
+ 1754 : /* see the note in malloc_nofail() of why we don't use calloc() */
+ 1755 156271 : ptr = malloc(size);
+ 1756 :
+ 1757 156271 : if (!ptr) {
+ 1758 : /* LCOV_EXCL_START */
+ 1759 : malloc_fail(size);
+ 1760 : exit(EXIT_FAILURE);
+ 1761 : /* LCOV_EXCL_STOP */
+ 1762 : }
+ 1763 :
+ 1764 156271 : memset(ptr, 0, size);
+ 1765 :
+ 1766 156271 : malloc_counter_inc(size);
+ 1767 :
+ 1768 156271 : return ptr;
+ 1769 : }
+ 1770 :
+ 1771 5965600 : char* strdup_nofail(const char* str)
+ 1772 : {
+ 1773 : size_t size;
+ 1774 : char* ptr;
+ 1775 :
+ 1776 5965600 : size = strlen(str) + 1;
+ 1777 :
+ 1778 5965600 : ptr = malloc(size);
+ 1779 :
+ 1780 5965600 : if (!ptr) {
+ 1781 : /* LCOV_EXCL_START */
+ 1782 : malloc_fail(size);
+ 1783 : exit(EXIT_FAILURE);
+ 1784 : /* LCOV_EXCL_STOP */
+ 1785 : }
+ 1786 :
+ 1787 5965600 : memcpy(ptr, str, size);
+ 1788 :
+ 1789 5965600 : malloc_counter_inc(size);
1790 :
- 1791 : /**
- 1792 : * Match a string with the specified pattern.
- 1793 : * Like sscanf() a space match any sequence of spaces.
- 1794 : * Return 0 if it matches.
- 1795 : */
- 1796 0 : static int smatch(const char* str, const char* pattern)
- 1797 : {
- 1798 0 : while (*pattern) {
- 1799 0 : if (isspace(*pattern)) {
- 1800 0 : ++pattern;
- 1801 0 : while (isspace(*str))
- 1802 0 : ++str;
- 1803 0 : } else if (*pattern == *str) {
- 1804 0 : ++pattern;
- 1805 0 : ++str;
- 1806 : } else
- 1807 0 : return -1;
- 1808 : }
- 1809 :
- 1810 0 : return 0;
- 1811 : }
- 1812 :
- 1813 : /*
- 1814 : * scomma()
- 1815 : *
- 1816 : * Matches a literal prefix (the second argument), then parses the following
- 1817 : * unsigned 64-bit integer, allowing comma thousand separators (U.S. style).
- 1818 : *
- 1819 : * Whitespace is flexible around the prefix and before the number.
- 1820 : * Commas are ignored during number parsing but basic validation is applied.
+ 1791 5965600 : return ptr;
+ 1792 : }
+ 1793 :
+ 1794 : /****************************************************************************/
+ 1795 : /* smartctl */
+ 1796 :
+ 1797 : /**
+ 1798 : * Match a string with the specified pattern.
+ 1799 : * Like sscanf() a space match any sequence of spaces.
+ 1800 : * Return 0 if it matches.
+ 1801 : */
+ 1802 1779 : static int smatch(const char* str, const char* pattern)
+ 1803 : {
+ 1804 2026 : while (*pattern) {
+ 1805 2015 : if (isspace(*pattern)) {
+ 1806 24 : ++pattern;
+ 1807 54 : while (isspace(*str))
+ 1808 30 : ++str;
+ 1809 1991 : } else if (*pattern == *str) {
+ 1810 223 : ++pattern;
+ 1811 223 : ++str;
+ 1812 : } else
+ 1813 1768 : return -1;
+ 1814 : }
+ 1815 :
+ 1816 11 : return 0;
+ 1817 : }
+ 1818 :
+ 1819 : /*
+ 1820 : * scomma()
1821 : *
- 1822 : * Returns:
- 1823 : * 1 - successfully parsed a valid uint64_t
- 1824 : * 0 - prefix mismatch, no digits found, invalid format or overflow
- 1825 : */
- 1826 0 : int scomma(const char* str, const char* prefix, uint64_t* value)
- 1827 : {
- 1828 0 : const char* s = str;
- 1829 0 : const char* f = prefix;
- 1830 :
- 1831 : /* match literal prefix, tolerating whitespace differences */
- 1832 0 : while (*f) {
- 1833 : /* skip whitespace in both strings */
- 1834 0 : while (isspace((unsigned char)*f))
- 1835 0 : ++f;
- 1836 0 : while (isspace((unsigned char)*s))
- 1837 0 : ++s;
- 1838 :
- 1839 0 : if (*f == 0)
- 1840 0 : break;
- 1841 0 : if (*s != *f)
- 1842 0 : return 0; /* prefix mismatch */
- 1843 :
- 1844 0 : ++s;
- 1845 0 : ++f;
- 1846 : }
- 1847 :
- 1848 : /* skip whitespace before the number starts */
- 1849 0 : while (isspace((unsigned char)*s))
- 1850 0 : ++s;
- 1851 :
- 1852 0 : uint64_t num = 0;
- 1853 0 : int digits_seen = 0;
- 1854 0 : int comma_seen = 0;
- 1855 :
- 1856 : /* parse digits, ignoring commas */
- 1857 0 : while (*s) {
- 1858 0 : if (*s >= '0' && *s <= '9') {
- 1859 0 : unsigned digit = (unsigned)(*s - '0');
- 1860 :
- 1861 : /* check for uint64_t overflow before multiplying */
- 1862 0 : if (num > (UINT64_MAX - digit) / 10ULL)
- 1863 0 : return 0;
- 1864 :
- 1865 0 : num = num * 10ULL + digit;
- 1866 0 : ++digits_seen;
- 1867 0 : comma_seen = 0;
- 1868 0 : } else if (*s == ',') {
- 1869 : /* disallow leading commas */
- 1870 0 : if (digits_seen == 0)
- 1871 0 : return 0;
- 1872 :
- 1873 : /* if two consecutive commas, stop parsing */
- 1874 0 : if (comma_seen)
- 1875 0 : break;
- 1876 :
- 1877 0 : comma_seen = 1;
- 1878 : } else {
- 1879 : /* any other character ends the number */
- 1880 0 : break;
- 1881 : }
+ 1822 : * Matches a literal prefix (the second argument), then parses the following
+ 1823 : * unsigned 64-bit integer, allowing comma thousand separators (U.S. style).
+ 1824 : *
+ 1825 : * Whitespace is flexible around the prefix and before the number.
+ 1826 : * Commas are ignored during number parsing but basic validation is applied.
+ 1827 : *
+ 1828 : * Returns:
+ 1829 : * 1 - successfully parsed a valid uint64_t
+ 1830 : * 0 - prefix mismatch, no digits found, invalid format or overflow
+ 1831 : */
+ 1832 2316 : int scomma(const char* str, const char* prefix, uint64_t* value)
+ 1833 : {
+ 1834 2316 : const char* s = str;
+ 1835 2316 : const char* f = prefix;
+ 1836 :
+ 1837 : /* match literal prefix, tolerating whitespace differences */
+ 1838 2418 : while (*f) {
+ 1839 : /* skip whitespace in both strings */
+ 1840 2424 : while (isspace((unsigned char)*f))
+ 1841 6 : ++f;
+ 1842 2424 : while (isspace((unsigned char)*s))
+ 1843 6 : ++s;
+ 1844 :
+ 1845 2418 : if (*f == 0)
+ 1846 0 : break;
+ 1847 2418 : if (*s != *f)
+ 1848 2316 : return 0; /* prefix mismatch */
+ 1849 :
+ 1850 102 : ++s;
+ 1851 102 : ++f;
+ 1852 : }
+ 1853 :
+ 1854 : /* skip whitespace before the number starts */
+ 1855 0 : while (isspace((unsigned char)*s))
+ 1856 0 : ++s;
+ 1857 :
+ 1858 0 : uint64_t num = 0;
+ 1859 0 : int digits_seen = 0;
+ 1860 0 : int comma_seen = 0;
+ 1861 :
+ 1862 : /* parse digits, ignoring commas */
+ 1863 0 : while (*s) {
+ 1864 0 : if (*s >= '0' && *s <= '9') {
+ 1865 0 : unsigned digit = (unsigned)(*s - '0');
+ 1866 :
+ 1867 : /* check for uint64_t overflow before multiplying */
+ 1868 0 : if (num > (UINT64_MAX - digit) / 10ULL)
+ 1869 0 : return 0;
+ 1870 :
+ 1871 0 : num = num * 10ULL + digit;
+ 1872 0 : ++digits_seen;
+ 1873 0 : comma_seen = 0;
+ 1874 0 : } else if (*s == ',') {
+ 1875 : /* disallow leading commas */
+ 1876 0 : if (digits_seen == 0)
+ 1877 0 : return 0;
+ 1878 :
+ 1879 : /* if two consecutive commas, stop parsing */
+ 1880 0 : if (comma_seen)
+ 1881 0 : break;
1882 :
- 1883 0 : ++s;
- 1884 : }
- 1885 :
- 1886 : /* require at least one digit */
- 1887 0 : if (digits_seen == 0)
- 1888 0 : return 0;
- 1889 :
- 1890 0 : *value = num;
- 1891 0 : return 1;
- 1892 : }
- 1893 :
- 1894 0 : int smartctl_attribute(FILE* f, const char* file, const char* name, struct smart_attr* smart, uint64_t* info, char* serial, char* family, char* model, char* inter)
- 1895 : {
- 1896 : unsigned i;
- 1897 : int inside;
- 1898 : struct smart_attr dummy_smart[SMART_COUNT];
- 1899 : uint64_t dummy_info[INFO_COUNT];
- 1900 : char dummy_serial[SMART_MAX];
- 1901 : char dummy_family[SMART_MAX];
- 1902 : char dummy_model[SMART_MAX];
- 1903 : char dummy_interface[SMART_MAX];
- 1904 :
- 1905 : /* dummy attributes */
- 1906 0 : if (!smart)
- 1907 0 : smart = dummy_smart;
- 1908 0 : if (!info)
- 1909 0 : info = dummy_info;
- 1910 0 : if (!serial)
- 1911 0 : serial = dummy_serial;
- 1912 0 : if (!family)
- 1913 0 : family = dummy_family;
- 1914 0 : if (!model)
- 1915 0 : model = dummy_model;
- 1916 0 : if (!inter)
- 1917 0 : inter = dummy_interface;
- 1918 :
- 1919 : /* preclear attributes */
- 1920 0 : *serial = 0;
- 1921 0 : *family = 0;
- 1922 0 : *model = 0;
- 1923 0 : *inter = 0;
- 1924 0 : memset(smart, 0, sizeof(struct smart_attr) * SMART_COUNT);
- 1925 0 : for (i = 0; i < SMART_COUNT; ++i)
- 1926 0 : smart[i].raw = SMART_UNASSIGNED;
- 1927 0 : for (i = 0; i < INFO_COUNT; ++i)
- 1928 0 : info[i] = SMART_UNASSIGNED;
- 1929 :
- 1930 : /* read the file */
- 1931 0 : inside = 0;
- 1932 0 : while (1) {
- 1933 : char buf[256];
- 1934 : unsigned id;
- 1935 : uint64_t raw;
- 1936 : uint64_t norm;
- 1937 : uint64_t worst;
- 1938 : uint64_t thresh;
- 1939 : char* s;
- 1940 :
- 1941 0 : s = fgets(buf, sizeof(buf), f);
- 1942 0 : if (s == 0)
- 1943 0 : break;
- 1944 :
- 1945 : /* remove extraneous chars */
- 1946 0 : s = strpolish(buf);
- 1947 :
- 1948 0 : log_tag("smartctl:%s:%s:out: %s\n", file, name, s);
- 1949 :
- 1950 : /* skip initial spaces */
- 1951 0 : while (isspace(*s))
- 1952 0 : ++s;
+ 1883 0 : comma_seen = 1;
+ 1884 : } else {
+ 1885 : /* any other character ends the number */
+ 1886 0 : break;
+ 1887 : }
+ 1888 :
+ 1889 0 : ++s;
+ 1890 : }
+ 1891 :
+ 1892 : /* require at least one digit */
+ 1893 0 : if (digits_seen == 0)
+ 1894 0 : return 0;
+ 1895 :
+ 1896 0 : *value = num;
+ 1897 0 : return 1;
+ 1898 : }
+ 1899 :
+ 1900 14 : int smartctl_attribute(FILE* f, const char* file, const char* name, struct smart_attr* smart, uint64_t* info, char* serial, char* family, char* model, char* inter)
+ 1901 : {
+ 1902 : unsigned i;
+ 1903 : int inside;
+ 1904 : struct smart_attr dummy_smart[SMART_COUNT];
+ 1905 : uint64_t dummy_info[INFO_COUNT];
+ 1906 : char dummy_serial[SMART_MAX];
+ 1907 : char dummy_family[SMART_MAX];
+ 1908 : char dummy_model[SMART_MAX];
+ 1909 : char dummy_interface[SMART_MAX];
+ 1910 :
+ 1911 : /* dummy attributes */
+ 1912 14 : if (!smart)
+ 1913 0 : smart = dummy_smart;
+ 1914 14 : if (!info)
+ 1915 0 : info = dummy_info;
+ 1916 14 : if (!serial)
+ 1917 0 : serial = dummy_serial;
+ 1918 14 : if (!family)
+ 1919 0 : family = dummy_family;
+ 1920 14 : if (!model)
+ 1921 0 : model = dummy_model;
+ 1922 14 : if (!inter)
+ 1923 0 : inter = dummy_interface;
+ 1924 :
+ 1925 : /* preclear attributes */
+ 1926 14 : *serial = 0;
+ 1927 14 : *family = 0;
+ 1928 14 : *model = 0;
+ 1929 14 : *inter = 0;
+ 1930 14 : memset(smart, 0, sizeof(struct smart_attr) * SMART_COUNT);
+ 1931 3654 : for (i = 0; i < SMART_COUNT; ++i)
+ 1932 3640 : smart[i].raw = SMART_UNASSIGNED;
+ 1933 42 : for (i = 0; i < INFO_COUNT; ++i)
+ 1934 28 : info[i] = SMART_UNASSIGNED;
+ 1935 :
+ 1936 : /* read the file */
+ 1937 14 : inside = 0;
+ 1938 235 : while (1) {
+ 1939 : char buf[256];
+ 1940 : unsigned id;
+ 1941 : uint64_t raw;
+ 1942 : uint64_t norm;
+ 1943 : uint64_t worst;
+ 1944 : uint64_t thresh;
+ 1945 : char* s;
+ 1946 :
+ 1947 249 : s = fgets(buf, sizeof(buf), f);
+ 1948 249 : if (s == 0)
+ 1949 14 : break;
+ 1950 :
+ 1951 : /* remove extraneous chars */
+ 1952 235 : s = strpolish(buf);
1953 :
- 1954 0 : if (*s == 0) {
- 1955 0 : inside = 0;
- 1956 : /* common */
- 1957 0 : } else if (smatch(s, "Rotation Rate: Solid State") == 0) {
- 1958 0 : info[INFO_ROTATION_RATE] = 0;
- 1959 0 : } else if (sscanf(s, "Rotation Rate: %" SCNu64, &info[INFO_ROTATION_RATE]) == 1) {
- 1960 0 : } else if (smatch(s, "User Capacity:") == 0) {
- 1961 0 : char* begin = strchr(s, ':');
- 1962 0 : char* end = strstr(s, "bytes");
- 1963 0 : if (begin != 0 && end != 0 && begin < end) {
- 1964 : char* p;
- 1965 0 : info[INFO_SIZE] = 0;
- 1966 0 : for (p = begin; p != end; ++p) {
- 1967 0 : if (isdigit(*p)) {
- 1968 0 : info[INFO_SIZE] *= 10;
- 1969 0 : info[INFO_SIZE] += *p - '0';
- 1970 : }
- 1971 : }
- 1972 : }
- 1973 0 : } else if (sscanf(s, "Model Family: %63[^\n]", family) == 1) {
- 1974 0 : strtrim(family);
- 1975 0 : } else if (sscanf(s, "Device Model: %63[^\n]", model) == 1) {
- 1976 0 : strtrim(model);
- 1977 0 : } else if (sscanf(s, "Serial number: %63s", serial) == 1) {
- 1978 0 : strtrim(serial);
- 1979 : /* SCSI */
- 1980 : /*
- 1981 : Vendor: WD
- 1982 : Product: WD4001FYYG-01SL3
- 1983 : Revision: VR08
- 1984 : Compliance: SPC-4
- 1985 : User Capacity: 4,000,787,030,016 bytes [4.00 TB]
- 1986 : Logical block size: 512 bytes
- 1987 : Rotation Rate: 7200 rpm
- 1988 : Form Factor: 3.5 inches
- 1989 : Logical Unit id: 0x50000c0f01f55dd0
- 1990 : Serial number: WMC1F0D41KD5
- 1991 : Device type: disk
- 1992 : Transport protocol: SAS (SPL-3)
- 1993 : Local Time is: Fri Jan 28 14:14:51 2022 CET
- 1994 : SMART support is: Available - device has SMART capability.
- 1995 : SMART support is: Enabled
- 1996 : Temperature Warning: Enabled
- 1997 :
- 1998 : Current Drive Temperature: 38 C
- 1999 : Drive Trip Temperature: 65 C
- 2000 :
- 2001 : Manufactured in week 25 of year 2012
- 2002 : Specified cycle count over device lifetime: 10000
- 2003 : Accumulated start-stop cycles: 103
- 2004 : Specified load-unload count over device lifetime: 300000
- 2005 : Accumulated load-unload cycles: 103
- 2006 : Elements in grown defect list: 5
- 2007 :
- 2008 : Vendor (Seagate) cache information
- 2009 : Blocks sent to initiator = 569127595
- 2010 : Blocks received from initiator = 2633690060
- 2011 : Blocks read from cache and sent to initiator = 1881027254
- 2012 : Number of read and write commands whose size <= segment size = 181284019
- 2013 : Number of read and write commands whose size > segment size = 0
- 2014 :
- 2015 : Vendor (Seagate/Hitachi) factory information
- 2016 : number of hours powered up = 25024.80
- 2017 : number of minutes until next internal SMART test = 42
- 2018 :
- 2019 : */
- 2020 0 : } else if (sscanf(s, "Transport protocol: %63[^\n]", inter) == 1) {
- 2021 0 : if (strcmp(inter, "Fibre channel (FCP-4)") == 0)
- 2022 0 : strcpy(inter, "Fibre");
- 2023 0 : else if (strcmp(inter, "SSA") == 0)
- 2024 0 : strcpy(inter, "SSA");
- 2025 0 : else if (strcmp(inter, "IEEE 1394 (SBP-3)") == 0)
- 2026 0 : strcpy(inter, "FireWire");
- 2027 0 : else if (strcmp(inter, "RDMA (SRP)") == 0)
- 2028 0 : strcpy(inter, "SCSI");
- 2029 0 : else if (strcmp(inter, "iSCSI") == 0)
- 2030 0 : strcpy(inter, "iSCSI");
- 2031 0 : else if (strcmp(inter, "SAS (SPL-4)") == 0)
- 2032 0 : strcpy(inter, "SAS");
- 2033 0 : else if (strcmp(inter, "ADT") == 0)
+ 1954 235 : log_tag("smartctl:%s:%s:out: %s\n", file, name, s);
+ 1955 :
+ 1956 : /* skip initial spaces */
+ 1957 504 : while (isspace(*s))
+ 1958 269 : ++s;
+ 1959 :
+ 1960 235 : if (*s == 0) {
+ 1961 28 : inside = 0;
+ 1962 : /* common */
+ 1963 207 : } else if (smatch(s, "Rotation Rate: Solid State") == 0) {
+ 1964 1 : info[INFO_ROTATION_RATE] = 0;
+ 1965 206 : } else if (sscanf(s, "Rotation Rate: %" SCNu64, &info[INFO_ROTATION_RATE]) == 1) {
+ 1966 205 : } else if (smatch(s, "User Capacity:") == 0) {
+ 1967 2 : char* begin = strchr(s, ':');
+ 1968 2 : char* end = strstr(s, "bytes");
+ 1969 2 : if (begin != 0 && end != 0 && begin < end) {
+ 1970 : char* p;
+ 1971 2 : info[INFO_SIZE] = 0;
+ 1972 46 : for (p = begin; p != end; ++p) {
+ 1973 44 : if (isdigit(*p)) {
+ 1974 25 : info[INFO_SIZE] *= 10;
+ 1975 25 : info[INFO_SIZE] += *p - '0';
+ 1976 : }
+ 1977 : }
+ 1978 : }
+ 1979 203 : } else if (sscanf(s, "Model Family: %63[^\n]", family) == 1) {
+ 1980 2 : strtrim(family);
+ 1981 201 : } else if (sscanf(s, "Device Model: %63[^\n]", model) == 1) {
+ 1982 2 : strtrim(model);
+ 1983 199 : } else if (sscanf(s, "Serial number: %63s", serial) == 1) {
+ 1984 0 : strtrim(serial);
+ 1985 : /* SCSI */
+ 1986 : /*
+ 1987 : Vendor: WD
+ 1988 : Product: WD4001FYYG-01SL3
+ 1989 : Revision: VR08
+ 1990 : Compliance: SPC-4
+ 1991 : User Capacity: 4,000,787,030,016 bytes [4.00 TB]
+ 1992 : Logical block size: 512 bytes
+ 1993 : Rotation Rate: 7200 rpm
+ 1994 : Form Factor: 3.5 inches
+ 1995 : Logical Unit id: 0x50000c0f01f55dd0
+ 1996 : Serial number: WMC1F0D41KD5
+ 1997 : Device type: disk
+ 1998 : Transport protocol: SAS (SPL-3)
+ 1999 : Local Time is: Fri Jan 28 14:14:51 2022 CET
+ 2000 : SMART support is: Available - device has SMART capability.
+ 2001 : SMART support is: Enabled
+ 2002 : Temperature Warning: Enabled
+ 2003 :
+ 2004 : Current Drive Temperature: 38 C
+ 2005 : Drive Trip Temperature: 65 C
+ 2006 :
+ 2007 : Manufactured in week 25 of year 2012
+ 2008 : Specified cycle count over device lifetime: 10000
+ 2009 : Accumulated start-stop cycles: 103
+ 2010 : Specified load-unload count over device lifetime: 300000
+ 2011 : Accumulated load-unload cycles: 103
+ 2012 : Elements in grown defect list: 5
+ 2013 :
+ 2014 : Vendor (Seagate) cache information
+ 2015 : Blocks sent to initiator = 569127595
+ 2016 : Blocks received from initiator = 2633690060
+ 2017 : Blocks read from cache and sent to initiator = 1881027254
+ 2018 : Number of read and write commands whose size <= segment size = 181284019
+ 2019 : Number of read and write commands whose size > segment size = 0
+ 2020 :
+ 2021 : Vendor (Seagate/Hitachi) factory information
+ 2022 : number of hours powered up = 25024.80
+ 2023 : number of minutes until next internal SMART test = 42
+ 2024 :
+ 2025 : */
+ 2026 199 : } else if (sscanf(s, "Transport protocol: %63[^\n]", inter) == 1) {
+ 2027 0 : if (strcmp(inter, "Fibre channel (FCP-4)") == 0)
+ 2028 0 : strcpy(inter, "Fibre");
+ 2029 0 : else if (strcmp(inter, "SSA") == 0)
+ 2030 0 : strcpy(inter, "SSA");
+ 2031 0 : else if (strcmp(inter, "IEEE 1394 (SBP-3)") == 0)
+ 2032 0 : strcpy(inter, "FireWire");
+ 2033 0 : else if (strcmp(inter, "RDMA (SRP)") == 0)
2034 0 : strcpy(inter, "SCSI");
- 2035 0 : else if (strcmp(inter, "ATA (ACS-2)") == 0)
- 2036 0 : strcpy(inter, "SATA");
- 2037 0 : else if (strcmp(inter, "UAS") == 0)
- 2038 0 : strcpy(inter, "USB");
- 2039 0 : else if (strcmp(inter, "SOP") == 0)
- 2040 0 : strcpy(inter, "NVMe");
- 2041 0 : else if (strcmp(inter, "PCIe") == 0)
- 2042 0 : strcpy(inter, "PCIe");
- 2043 : else
- 2044 0 : strcpy(inter, "SCSI");
- 2045 : /* map generic attributes to SMART attr */
- 2046 0 : } else if (sscanf(s, "Elements in grown defect list: %" SCNu64, &smart[SMART_REALLOCATED_SECTOR_COUNT].raw) == 1) {
- 2047 0 : pathcpy(smart[SMART_REALLOCATED_SECTOR_COUNT].name, sizeof(smart[SMART_REALLOCATED_SECTOR_COUNT].name), "Elements_In_Grown_Defect_List");
- 2048 0 : } else if (sscanf(s, "Current Drive Temperature: %" SCNu64, &smart[SMART_TEMPERATURE_CELSIUS].raw) == 1) {
- 2049 0 : pathcpy(smart[SMART_TEMPERATURE_CELSIUS].name, sizeof(smart[SMART_TEMPERATURE_CELSIUS].name), "Current_Drive_Temperature");
- 2050 0 : } else if (sscanf(s, "Drive Trip Temperature: %" SCNu64, &smart[SMART_AIRFLOW_TEMPERATURE_CELSIUS].raw) == 1) {
- 2051 0 : pathcpy(smart[SMART_AIRFLOW_TEMPERATURE_CELSIUS].name, sizeof(smart[SMART_AIRFLOW_TEMPERATURE_CELSIUS].name), "Drive_Trip_Temperature");
- 2052 0 : } else if (sscanf(s, "Accumulated start-stop cycles: %" SCNu64, &smart[SMART_START_STOP_COUNT].raw) == 1) {
- 2053 0 : pathcpy(smart[SMART_START_STOP_COUNT].name, sizeof(smart[SMART_START_STOP_COUNT].name), "Accumulated_Start-Stop_Cycles");
- 2054 0 : } else if (sscanf(s, "Accumulated load-unload cycles: %" SCNu64, &smart[SMART_LOAD_CYCLE_COUNT].raw) == 1) {
- 2055 0 : pathcpy(smart[SMART_LOAD_CYCLE_COUNT].name, sizeof(smart[SMART_LOAD_CYCLE_COUNT].name), "Accumulated_Load-Unload_Cycles");
- 2056 0 : } else if (sscanf(s, " number of hours powered up = %" SCNu64, &smart[SMART_POWER_ON_HOURS].raw) == 1) { /* note "n" of "number" lower case */
- 2057 0 : pathcpy(smart[SMART_POWER_ON_HOURS].name, sizeof(smart[SMART_POWER_ON_HOURS].name), "Number_Of_Hours_Powered_Up");
- 2058 : /* special entries */
- 2059 0 : } else if (sscanf(s, "Non-medium error count: %" SCNu64, &raw) == 1) {
- 2060 0 : smart[SMART_ERROR_PROTOCOL].raw = raw;
- 2061 : /* ATA */
- 2062 : /*
- 2063 : ID# ATTRIBUTE_NAME FLAG VALUE WORST THRESH TYPE UPDATED WHEN_FAILED RAW_VALUE
- 2064 : 1 Raw_Read_Error_Rate 0x002f 200 200 051 Pre-fail Always - 0
- 2065 : 3 Spin_Up_Time 0x0027 172 169 021 Pre-fail Always - 8383
- 2066 : 4 Start_Stop_Count 0x0032 100 100 000 Old_age Always - 24
- 2067 : 5 Reallocated_Sector_Ct 0x0033 200 200 140 Pre-fail Always - 0
- 2068 : 7 Seek_Error_Rate 0x002e 200 200 000 Old_age Always - 0
- 2069 : 9 Power_On_Hours 0x0032 083 083 000 Old_age Always - 12471
- 2070 : 10 Spin_Retry_Count 0x0032 100 253 000 Old_age Always - 0
- 2071 : 11 Calibration_Retry_Count 0x0032 100 253 000 Old_age Always - 0
- 2072 : 12 Power_Cycle_Count 0x0032 100 100 000 Old_age Always - 24
- 2073 : 192 Power-Off_Retract_Count 0x0032 200 200 000 Old_age Always - 9
- 2074 : 193 Load_Cycle_Count 0x0032 157 157 000 Old_age Always - 131565
- 2075 : 194 Temperature_Celsius 0x0022 127 119 000 Old_age Always - 25
- 2076 : 196 Reallocated_Event_Count 0x0032 200 200 000 Old_age Always - 0
- 2077 : 197 Current_Pending_Sector 0x0032 200 200 000 Old_age Always - 0
- 2078 : 198 Offline_Uncorrectable 0x0030 100 253 000 Old_age Offline - 0
- 2079 : 199 UDMA_CRC_Error_Count 0x0032 200 200 000 Old_age Always - 0
- 2080 : 200 Multi_Zone_Error_Rate 0x0008 200 200 000 Old_age Offline - 0
- 2081 : */
- 2082 0 : } else if (smatch(s, "ATA Version is:") == 0) {
- 2083 0 : strcpy(inter, "ATA");
- 2084 0 : } else if (smatch(s, "SATA Version is:") == 0) {
- 2085 0 : strcpy(inter, "SATA");
- 2086 0 : } else if (smatch(s, "Transport Type: PCIe") == 0) {
- 2087 0 : strcpy(inter, "PCIe");
- 2088 0 : } else if (smatch(s, "Transport Type: Parallel") == 0) {
- 2089 0 : strcpy(inter, "PATA");
- 2090 : /* special entries */
- 2091 0 : } else if (smatch(s, "No Errors Logged") == 0) {
- 2092 0 : smart[SMART_ERROR_PROTOCOL].raw = 0;
- 2093 0 : } else if (sscanf(s, "ATA Error Count: %" SCNu64, &raw) == 1) {
- 2094 0 : smart[SMART_ERROR_PROTOCOL].raw = raw;
- 2095 : /* NVME */
- 2096 : /*
- 2097 : Critical Warning: 0x00
- 2098 : Temperature: 55 Celsius
- 2099 : Available Spare: 100%
- 2100 : Available Spare Threshold: 10%
- 2101 : Percentage Used: 8%
- 2102 : Data Units Read: 213,006,510 [109 TB]
- 2103 : Data Units Written: 549,370,112 [281 TB]
- 2104 : Host Read Commands: 11,210,192,197
- 2105 : Host Write Commands: 20,687,602,229
- 2106 : Controller Busy Time: 14,055
- 2107 : Power Cycles: 39
- 2108 : Power On Hours: 4,204
- 2109 : Unsafe Shutdowns: 9
- 2110 : Media and Data Integrity Errors: 0
- 2111 : Error Information Log Entries: 1,479,242
- 2112 : Warning Comp. Temperature Time: 0
- 2113 : Critical Comp. Temperature Time: 0
- 2114 : Temperature Sensor 2: 75 Celsius
- 2115 : Thermal Temp. 1 Total Time: 58745
- 2116 : */
- 2117 0 : } else if (smatch(s, "NVMe Version:") == 0) {
- 2118 0 : strcpy(inter, "NVMe");
- 2119 : /* special entries */
- 2120 0 : } else if (scomma(s, "Media and Data Integrity Errors:", &raw) == 1) {
- 2121 0 : smart[SMART_ERROR_MEDIUM].raw = raw;
- 2122 0 : } else if (scomma(s, "Error Information Log Entries:", &raw) == 1) {
- 2123 0 : smart[SMART_ERROR_PROTOCOL].raw = raw;
- 2124 0 : } else if (sscanf(s, "Percentage Used: %" SCNu64 "%%", &raw) == 1) {
- 2125 0 : smart[SMART_WEAR_LEVEL].raw = raw; /* take care that it can be greather than 100%, meaning that it's used over the expected lifetime */
- 2126 : /* map generic attributes to SMART attr */
- 2127 0 : } else if (sscanf(s, "Temperature: %" SCNu64, &smart[SMART_TEMPERATURE_CELSIUS].raw) == 1) {
- 2128 0 : pathcpy(smart[SMART_TEMPERATURE_CELSIUS].name, sizeof(smart[SMART_TEMPERATURE_CELSIUS].name), "Temperature");
- 2129 0 : } else if (scomma(s, "Power On Hours:", &smart[SMART_POWER_ON_HOURS].raw) == 1) {
- 2130 0 : pathcpy(smart[SMART_POWER_ON_HOURS].name, sizeof(smart[SMART_POWER_ON_HOURS].name), "Power_On_Hours");
- 2131 0 : } else if (scomma(s, "Power Cycles:", &smart[SMART_POWER_CYCLE_COUNT].raw) == 1) {
- 2132 0 : pathcpy(smart[SMART_POWER_CYCLE_COUNT].name, sizeof(smart[SMART_POWER_CYCLE_COUNT].name), "Power_Cycles");
- 2133 : /* map specific attributes to UNUSED SMART attr */
- 2134 0 : } else if (sscanf(s, "Critical Warning: %" SCNx64, &smart[SMART_NVME_CRITICAL_WARNING].raw) == 1) {
- 2135 0 : pathcpy(smart[SMART_NVME_CRITICAL_WARNING].name, sizeof(smart[SMART_NVME_CRITICAL_WARNING].name), "Critical_Warning");
- 2136 0 : } else if (sscanf(s, "Available Spare: %" SCNu64 "%%", &smart[SMART_NVME_AVAILABLE_SPARE].raw) == 1) {
- 2137 0 : pathcpy(smart[SMART_NVME_AVAILABLE_SPARE].name, sizeof(smart[SMART_NVME_AVAILABLE_SPARE].name), "Available_Spare");
- 2138 0 : } else if (scomma(s, "Data Units Read:", &smart[SMART_NVME_DATA_UNITS_READ].raw) == 1) {
- 2139 0 : pathcpy(smart[SMART_NVME_DATA_UNITS_READ].name, sizeof(smart[SMART_NVME_DATA_UNITS_READ].name), "Data_Units_Read");
- 2140 0 : } else if (scomma(s, "Data Units Written:", &smart[SMART_NVME_DATA_UNITS_WRITTEN].raw) == 1) {
- 2141 0 : pathcpy(smart[SMART_NVME_DATA_UNITS_WRITTEN].name, sizeof(smart[SMART_NVME_DATA_UNITS_WRITTEN].name), "Data_Units_Written");
- 2142 0 : } else if (scomma(s, "Host Read Commands:", &smart[SMART_NVME_HOST_READ_COMMANDS].raw) == 1) {
- 2143 0 : pathcpy(smart[SMART_NVME_HOST_READ_COMMANDS].name, sizeof(smart[SMART_NVME_HOST_READ_COMMANDS].name), "Host_Read_Commands");
- 2144 0 : } else if (scomma(s, "Host Write Commands:", &smart[SMART_NVME_HOST_WRITE_COMMANDS].raw) == 1) {
- 2145 0 : pathcpy(smart[SMART_NVME_HOST_WRITE_COMMANDS].name, sizeof(smart[SMART_NVME_HOST_WRITE_COMMANDS].name), "Host_Write_Commands");
- 2146 0 : } else if (scomma(s, "Controller Busy Time:", &smart[SMART_NVME_CONTROLLER_BUSY_TIME].raw) == 1) {
- 2147 0 : pathcpy(smart[SMART_NVME_CONTROLLER_BUSY_TIME].name, sizeof(smart[SMART_NVME_CONTROLLER_BUSY_TIME].name), "Controller_Busy_Time");
- 2148 0 : } else if (scomma(s, "Unsafe Shutdowns:", &smart[SMART_NVME_UNSAFE_SHUTDOWNS].raw) == 1) {
- 2149 0 : pathcpy(smart[SMART_NVME_UNSAFE_SHUTDOWNS].name, sizeof(smart[SMART_NVME_UNSAFE_SHUTDOWNS].name), "Unsafe_Shutdowns");
- 2150 : /* smartctl doesn't print this with command, but %d */
- 2151 0 : } else if (scomma(s, "Warning Comp. Temperature Time:", &smart[SMART_NVME_WARNING_COMP_TEMPERATURE_TIME].raw) == 1) {
- 2152 0 : pathcpy(smart[SMART_NVME_WARNING_COMP_TEMPERATURE_TIME].name, sizeof(smart[SMART_NVME_WARNING_COMP_TEMPERATURE_TIME].name), "Warning_Comp_Temperature_Time");
- 2153 : /* smartctl doesn't print this with command, but %d */
- 2154 0 : } else if (scomma(s, "Critical Comp. Temperature Time:", &smart[SMART_NVME_CRITICAL_COMP_TEMPERATURE_TIME].raw) == 1) {
- 2155 0 : pathcpy(smart[SMART_NVME_CRITICAL_COMP_TEMPERATURE_TIME].name, sizeof(smart[SMART_NVME_CRITICAL_COMP_TEMPERATURE_TIME].name), "Critical_Comp_Temperature_Time");
- 2156 : /* ATA Attributes table */
- 2157 0 : } else if (smatch(s, "ID#") == 0) {
- 2158 0 : inside = 1;
- 2159 0 : } else if (inside) {
- 2160 0 : char id_name[128] = { 0 };
- 2161 0 : char type[64] = { 0 };
- 2162 0 : char updated[64] = { 0 };
- 2163 0 : char when_failed[64] = { 0 };
- 2164 : uint64_t min, max;
- 2165 : int minmax;
- 2166 : int flags;
- 2167 :
- 2168 0 : if (sscanf(s, "%u %127s %*s %" SCNu64 " %" SCNu64 " %" SCNu64 " %63s %63s %63s %" SCNu64 " (Min/Max %" SCNu64 "/%" SCNu64 ")", &id, id_name, &norm, &worst, &thresh, type, updated, when_failed, &raw, &min, &max) == 11) {
- 2169 0 : minmax = 1;
- 2170 0 : } else if (sscanf(s, "%u %127s %*s %" SCNu64 " %" SCNu64 " %" SCNu64 " %63s %63s %63s %" SCNu64, &id, id_name, &norm, &worst, &thresh, type, updated, when_failed, &raw) == 9) {
- 2171 0 : minmax = 0;
- 2172 : } else {
- 2173 0 : log_fatal(EEXTERNAL, "Invalid smartctl line '%s'.\n", s);
- 2174 0 : return -1;
- 2175 : }
- 2176 :
- 2177 0 : if (id >= 256) {
- 2178 : /* LCOV_EXCL_START */
- 2179 : log_fatal(EEXTERNAL, "Invalid SMART id '%u'.\n", id);
- 2180 : return -1;
- 2181 : /* LCOV_EXCL_STOP */
- 2182 : }
- 2183 :
- 2184 0 : flags = 0;
- 2185 0 : if (strcmp(type, "Pre-fail") == 0)
- 2186 0 : flags |= SMART_ATTR_TYPE_PREFAIL;
- 2187 0 : else if (strcmp(type, "Old_age") == 0)
- 2188 0 : flags |= SMART_ATTR_TYPE_OLDAGE;
- 2189 0 : if (strcmp(updated, "Always") == 0)
- 2190 0 : flags |= SMART_ATTR_UPDATE_ALWAYS;
- 2191 0 : else if (strcmp(updated, "Offline") == 0)
- 2192 0 : flags |= SMART_ATTR_UPDATE_OFFLINE;
- 2193 0 : if (strcmp(when_failed, "FAILING_NOW") == 0)
- 2194 0 : flags |= SMART_ATTR_WHEN_FAILED_NOW;
- 2195 0 : else if (strcmp(when_failed, "In_the_past") == 0)
- 2196 0 : flags |= SMART_ATTR_WHEN_FAILED_PAST;
- 2197 0 : else if (strcmp(when_failed, "-") == 0)
- 2198 0 : flags |= SMART_ATTR_WHEN_FAILED_NEVER;
- 2199 :
- 2200 : /* revert the min/max decoding done by smartctl */
- 2201 0 : if (minmax
- 2202 0 : && raw <= 0xFFFFUL
- 2203 0 : && min <= 0xFFFFUL
- 2204 0 : && max <= 0xFFFFUL) {
- 2205 0 : raw |= min << 16;
- 2206 0 : raw |= max << 32;
- 2207 : }
- 2208 :
- 2209 0 : smart[id].raw = raw;
- 2210 0 : smart[id].norm = norm;
- 2211 0 : smart[id].worst = worst;
- 2212 0 : smart[id].thresh = thresh;
- 2213 0 : smart[id].flags = flags;
- 2214 0 : pathcpy(smart[id].name, sizeof(smart[id].name), id_name);
- 2215 :
- 2216 : /*
- 2217 : * Map normalized health percentage to our unified wear level for SSDs
- 2218 : * 177: Wear_Leveling_Count (Samsung/Crucial)
- 2219 : * 231: SSD_Life_Left (Kingston/WD)
- 2220 : * 233: Media_Wearout_Indicator (Intel)
- 2221 : */
- 2222 0 : if (norm <= 100) {
- 2223 0 : switch (id) {
- 2224 0 : case 177 :
- 2225 : case 233 :
- 2226 : case 231 :
- 2227 0 : smart[SMART_WEAR_LEVEL].raw = 100 - norm;
- 2228 0 : break;
- 2229 : }
- 2230 : }
- 2231 : }
- 2232 : }
- 2233 :
- 2234 0 : return 0;
- 2235 : }
- 2236 :
- 2237 25 : int smartctl_flush(FILE* f, const char* file, const char* name)
- 2238 : {
- 2239 : /* read the file */
- 2240 20 : while (1) {
- 2241 : char buf[256];
- 2242 : char* s;
- 2243 :
- 2244 25 : s = fgets(buf, sizeof(buf), f);
- 2245 25 : if (s == 0)
- 2246 5 : break;
- 2247 :
- 2248 : /* remove extraneous chars */
- 2249 20 : s = strpolish(buf);
- 2250 :
- 2251 20 : log_tag("smartctl:%s:%s:out: %s\n", file, name, s);
- 2252 : }
+ 2035 0 : else if (strcmp(inter, "iSCSI") == 0)
+ 2036 0 : strcpy(inter, "iSCSI");
+ 2037 0 : else if (strcmp(inter, "SAS (SPL-4)") == 0)
+ 2038 0 : strcpy(inter, "SAS");
+ 2039 0 : else if (strcmp(inter, "ADT") == 0)
+ 2040 0 : strcpy(inter, "SCSI");
+ 2041 0 : else if (strcmp(inter, "ATA (ACS-2)") == 0)
+ 2042 0 : strcpy(inter, "SATA");
+ 2043 0 : else if (strcmp(inter, "UAS") == 0)
+ 2044 0 : strcpy(inter, "USB");
+ 2045 0 : else if (strcmp(inter, "SOP") == 0)
+ 2046 0 : strcpy(inter, "NVMe");
+ 2047 0 : else if (strcmp(inter, "PCIe") == 0)
+ 2048 0 : strcpy(inter, "PCIe");
+ 2049 : else
+ 2050 0 : strcpy(inter, "SCSI");
+ 2051 : /* map generic attributes to SMART attr */
+ 2052 199 : } else if (sscanf(s, "Elements in grown defect list: %" SCNu64, &smart[SMART_REALLOCATED_SECTOR_COUNT].raw) == 1) {
+ 2053 0 : pathcpy(smart[SMART_REALLOCATED_SECTOR_COUNT].name, sizeof(smart[SMART_REALLOCATED_SECTOR_COUNT].name), "Elements_In_Grown_Defect_List");
+ 2054 199 : } else if (sscanf(s, "Current Drive Temperature: %" SCNu64, &smart[SMART_TEMPERATURE_CELSIUS].raw) == 1) {
+ 2055 0 : pathcpy(smart[SMART_TEMPERATURE_CELSIUS].name, sizeof(smart[SMART_TEMPERATURE_CELSIUS].name), "Current_Drive_Temperature");
+ 2056 199 : } else if (sscanf(s, "Drive Trip Temperature: %" SCNu64, &smart[SMART_AIRFLOW_TEMPERATURE_CELSIUS].raw) == 1) {
+ 2057 0 : pathcpy(smart[SMART_AIRFLOW_TEMPERATURE_CELSIUS].name, sizeof(smart[SMART_AIRFLOW_TEMPERATURE_CELSIUS].name), "Drive_Trip_Temperature");
+ 2058 199 : } else if (sscanf(s, "Accumulated start-stop cycles: %" SCNu64, &smart[SMART_START_STOP_COUNT].raw) == 1) {
+ 2059 0 : pathcpy(smart[SMART_START_STOP_COUNT].name, sizeof(smart[SMART_START_STOP_COUNT].name), "Accumulated_Start-Stop_Cycles");
+ 2060 199 : } else if (sscanf(s, "Accumulated load-unload cycles: %" SCNu64, &smart[SMART_LOAD_CYCLE_COUNT].raw) == 1) {
+ 2061 0 : pathcpy(smart[SMART_LOAD_CYCLE_COUNT].name, sizeof(smart[SMART_LOAD_CYCLE_COUNT].name), "Accumulated_Load-Unload_Cycles");
+ 2062 199 : } else if (sscanf(s, " number of hours powered up = %" SCNu64, &smart[SMART_POWER_ON_HOURS].raw) == 1) { /* note "n" of "number" lower case */
+ 2063 0 : pathcpy(smart[SMART_POWER_ON_HOURS].name, sizeof(smart[SMART_POWER_ON_HOURS].name), "Number_Of_Hours_Powered_Up");
+ 2064 : /* special entries */
+ 2065 199 : } else if (sscanf(s, "Non-medium error count: %" SCNu64, &raw) == 1) {
+ 2066 0 : smart[SMART_ERROR_PROTOCOL].raw = raw;
+ 2067 : /* ATA */
+ 2068 : /*
+ 2069 : ID# ATTRIBUTE_NAME FLAG VALUE WORST THRESH TYPE UPDATED WHEN_FAILED RAW_VALUE
+ 2070 : 1 Raw_Read_Error_Rate 0x002f 200 200 051 Pre-fail Always - 0
+ 2071 : 3 Spin_Up_Time 0x0027 172 169 021 Pre-fail Always - 8383
+ 2072 : 4 Start_Stop_Count 0x0032 100 100 000 Old_age Always - 24
+ 2073 : 5 Reallocated_Sector_Ct 0x0033 200 200 140 Pre-fail Always - 0
+ 2074 : 7 Seek_Error_Rate 0x002e 200 200 000 Old_age Always - 0
+ 2075 : 9 Power_On_Hours 0x0032 083 083 000 Old_age Always - 12471
+ 2076 : 10 Spin_Retry_Count 0x0032 100 253 000 Old_age Always - 0
+ 2077 : 11 Calibration_Retry_Count 0x0032 100 253 000 Old_age Always - 0
+ 2078 : 12 Power_Cycle_Count 0x0032 100 100 000 Old_age Always - 24
+ 2079 : 192 Power-Off_Retract_Count 0x0032 200 200 000 Old_age Always - 9
+ 2080 : 193 Load_Cycle_Count 0x0032 157 157 000 Old_age Always - 131565
+ 2081 : 194 Temperature_Celsius 0x0022 127 119 000 Old_age Always - 25
+ 2082 : 196 Reallocated_Event_Count 0x0032 200 200 000 Old_age Always - 0
+ 2083 : 197 Current_Pending_Sector 0x0032 200 200 000 Old_age Always - 0
+ 2084 : 198 Offline_Uncorrectable 0x0030 100 253 000 Old_age Offline - 0
+ 2085 : 199 UDMA_CRC_Error_Count 0x0032 200 200 000 Old_age Always - 0
+ 2086 : 200 Multi_Zone_Error_Rate 0x0008 200 200 000 Old_age Offline - 0
+ 2087 : */
+ 2088 199 : } else if (smatch(s, "ATA Version is:") == 0) {
+ 2089 2 : strcpy(inter, "ATA");
+ 2090 197 : } else if (smatch(s, "SATA Version is:") == 0) {
+ 2091 2 : strcpy(inter, "SATA");
+ 2092 195 : } else if (smatch(s, "Transport Type: PCIe") == 0) {
+ 2093 0 : strcpy(inter, "PCIe");
+ 2094 195 : } else if (smatch(s, "Transport Type: Parallel") == 0) {
+ 2095 0 : strcpy(inter, "PATA");
+ 2096 : /* special entries */
+ 2097 195 : } else if (smatch(s, "No Errors Logged") == 0) {
+ 2098 2 : smart[SMART_ERROR_PROTOCOL].raw = 0;
+ 2099 193 : } else if (sscanf(s, "ATA Error Count: %" SCNu64, &raw) == 1) {
+ 2100 0 : smart[SMART_ERROR_PROTOCOL].raw = raw;
+ 2101 : /* NVME */
+ 2102 : /*
+ 2103 : Critical Warning: 0x00
+ 2104 : Temperature: 55 Celsius
+ 2105 : Available Spare: 100%
+ 2106 : Available Spare Threshold: 10%
+ 2107 : Percentage Used: 8%
+ 2108 : Data Units Read: 213,006,510 [109 TB]
+ 2109 : Data Units Written: 549,370,112 [281 TB]
+ 2110 : Host Read Commands: 11,210,192,197
+ 2111 : Host Write Commands: 20,687,602,229
+ 2112 : Controller Busy Time: 14,055
+ 2113 : Power Cycles: 39
+ 2114 : Power On Hours: 4,204
+ 2115 : Unsafe Shutdowns: 9
+ 2116 : Media and Data Integrity Errors: 0
+ 2117 : Error Information Log Entries: 1,479,242
+ 2118 : Warning Comp. Temperature Time: 0
+ 2119 : Critical Comp. Temperature Time: 0
+ 2120 : Temperature Sensor 2: 75 Celsius
+ 2121 : Thermal Temp. 1 Total Time: 58745
+ 2122 : */
+ 2123 193 : } else if (smatch(s, "NVMe Version:") == 0) {
+ 2124 0 : strcpy(inter, "NVMe");
+ 2125 : /* special entries */
+ 2126 193 : } else if (scomma(s, "Media and Data Integrity Errors:", &raw) == 1) {
+ 2127 0 : smart[SMART_ERROR_MEDIUM].raw = raw;
+ 2128 193 : } else if (scomma(s, "Error Information Log Entries:", &raw) == 1) {
+ 2129 0 : smart[SMART_ERROR_PROTOCOL].raw = raw;
+ 2130 193 : } else if (sscanf(s, "Percentage Used: %" SCNu64 "%%", &raw) == 1) {
+ 2131 0 : smart[SMART_WEAR_LEVEL].raw = raw; /* take care that it can be greather than 100%, meaning that it's used over the expected lifetime */
+ 2132 : /* map generic attributes to SMART attr */
+ 2133 193 : } else if (sscanf(s, "Temperature: %" SCNu64, &smart[SMART_TEMPERATURE_CELSIUS].raw) == 1) {
+ 2134 0 : pathcpy(smart[SMART_TEMPERATURE_CELSIUS].name, sizeof(smart[SMART_TEMPERATURE_CELSIUS].name), "Temperature");
+ 2135 193 : } else if (scomma(s, "Power On Hours:", &smart[SMART_POWER_ON_HOURS].raw) == 1) {
+ 2136 0 : pathcpy(smart[SMART_POWER_ON_HOURS].name, sizeof(smart[SMART_POWER_ON_HOURS].name), "Power_On_Hours");
+ 2137 193 : } else if (scomma(s, "Power Cycles:", &smart[SMART_POWER_CYCLE_COUNT].raw) == 1) {
+ 2138 0 : pathcpy(smart[SMART_POWER_CYCLE_COUNT].name, sizeof(smart[SMART_POWER_CYCLE_COUNT].name), "Power_Cycles");
+ 2139 : /* map specific attributes to UNUSED SMART attr */
+ 2140 193 : } else if (sscanf(s, "Critical Warning: %" SCNx64, &smart[SMART_NVME_CRITICAL_WARNING].raw) == 1) {
+ 2141 0 : pathcpy(smart[SMART_NVME_CRITICAL_WARNING].name, sizeof(smart[SMART_NVME_CRITICAL_WARNING].name), "Critical_Warning");
+ 2142 193 : } else if (sscanf(s, "Available Spare: %" SCNu64 "%%", &smart[SMART_NVME_AVAILABLE_SPARE].raw) == 1) {
+ 2143 0 : pathcpy(smart[SMART_NVME_AVAILABLE_SPARE].name, sizeof(smart[SMART_NVME_AVAILABLE_SPARE].name), "Available_Spare");
+ 2144 193 : } else if (scomma(s, "Data Units Read:", &smart[SMART_NVME_DATA_UNITS_READ].raw) == 1) {
+ 2145 0 : pathcpy(smart[SMART_NVME_DATA_UNITS_READ].name, sizeof(smart[SMART_NVME_DATA_UNITS_READ].name), "Data_Units_Read");
+ 2146 193 : } else if (scomma(s, "Data Units Written:", &smart[SMART_NVME_DATA_UNITS_WRITTEN].raw) == 1) {
+ 2147 0 : pathcpy(smart[SMART_NVME_DATA_UNITS_WRITTEN].name, sizeof(smart[SMART_NVME_DATA_UNITS_WRITTEN].name), "Data_Units_Written");
+ 2148 193 : } else if (scomma(s, "Host Read Commands:", &smart[SMART_NVME_HOST_READ_COMMANDS].raw) == 1) {
+ 2149 0 : pathcpy(smart[SMART_NVME_HOST_READ_COMMANDS].name, sizeof(smart[SMART_NVME_HOST_READ_COMMANDS].name), "Host_Read_Commands");
+ 2150 193 : } else if (scomma(s, "Host Write Commands:", &smart[SMART_NVME_HOST_WRITE_COMMANDS].raw) == 1) {
+ 2151 0 : pathcpy(smart[SMART_NVME_HOST_WRITE_COMMANDS].name, sizeof(smart[SMART_NVME_HOST_WRITE_COMMANDS].name), "Host_Write_Commands");
+ 2152 193 : } else if (scomma(s, "Controller Busy Time:", &smart[SMART_NVME_CONTROLLER_BUSY_TIME].raw) == 1) {
+ 2153 0 : pathcpy(smart[SMART_NVME_CONTROLLER_BUSY_TIME].name, sizeof(smart[SMART_NVME_CONTROLLER_BUSY_TIME].name), "Controller_Busy_Time");
+ 2154 193 : } else if (scomma(s, "Unsafe Shutdowns:", &smart[SMART_NVME_UNSAFE_SHUTDOWNS].raw) == 1) {
+ 2155 0 : pathcpy(smart[SMART_NVME_UNSAFE_SHUTDOWNS].name, sizeof(smart[SMART_NVME_UNSAFE_SHUTDOWNS].name), "Unsafe_Shutdowns");
+ 2156 : /* smartctl doesn't print this with command, but %d */
+ 2157 193 : } else if (scomma(s, "Warning Comp. Temperature Time:", &smart[SMART_NVME_WARNING_COMP_TEMPERATURE_TIME].raw) == 1) {
+ 2158 0 : pathcpy(smart[SMART_NVME_WARNING_COMP_TEMPERATURE_TIME].name, sizeof(smart[SMART_NVME_WARNING_COMP_TEMPERATURE_TIME].name), "Warning_Comp_Temperature_Time");
+ 2159 : /* smartctl doesn't print this with command, but %d */
+ 2160 193 : } else if (scomma(s, "Critical Comp. Temperature Time:", &smart[SMART_NVME_CRITICAL_COMP_TEMPERATURE_TIME].raw) == 1) {
+ 2161 0 : pathcpy(smart[SMART_NVME_CRITICAL_COMP_TEMPERATURE_TIME].name, sizeof(smart[SMART_NVME_CRITICAL_COMP_TEMPERATURE_TIME].name), "Critical_Comp_Temperature_Time");
+ 2162 : /* ATA Attributes table */
+ 2163 193 : } else if (smatch(s, "ID#") == 0) {
+ 2164 2 : inside = 1;
+ 2165 191 : } else if (inside) {
+ 2166 31 : char id_name[128] = { 0 };
+ 2167 31 : char type[64] = { 0 };
+ 2168 31 : char updated[64] = { 0 };
+ 2169 31 : char when_failed[64] = { 0 };
+ 2170 : uint64_t min, max;
+ 2171 : int minmax;
+ 2172 : int flags;
+ 2173 :
+ 2174 31 : if (sscanf(s, "%u %127s %*s %" SCNu64 " %" SCNu64 " %" SCNu64 " %63s %63s %63s %" SCNu64 " (Min/Max %" SCNu64 "/%" SCNu64 ")", &id, id_name, &norm, &worst, &thresh, type, updated, when_failed, &raw, &min, &max) == 11) {
+ 2175 1 : minmax = 1;
+ 2176 30 : } else if (sscanf(s, "%u %127s %*s %" SCNu64 " %" SCNu64 " %" SCNu64 " %63s %63s %63s %" SCNu64, &id, id_name, &norm, &worst, &thresh, type, updated, when_failed, &raw) == 9) {
+ 2177 30 : minmax = 0;
+ 2178 : } else {
+ 2179 0 : log_fatal(EEXTERNAL, "Invalid smartctl line '%s'.\n", s);
+ 2180 0 : return -1;
+ 2181 : }
+ 2182 :
+ 2183 31 : if (id >= 256) {
+ 2184 : /* LCOV_EXCL_START */
+ 2185 : log_fatal(EEXTERNAL, "Invalid SMART id '%u'.\n", id);
+ 2186 : return -1;
+ 2187 : /* LCOV_EXCL_STOP */
+ 2188 : }
+ 2189 :
+ 2190 31 : flags = 0;
+ 2191 31 : if (strcmp(type, "Pre-fail") == 0)
+ 2192 11 : flags |= SMART_ATTR_TYPE_PREFAIL;
+ 2193 20 : else if (strcmp(type, "Old_age") == 0)
+ 2194 20 : flags |= SMART_ATTR_TYPE_OLDAGE;
+ 2195 31 : if (strcmp(updated, "Always") == 0)
+ 2196 28 : flags |= SMART_ATTR_UPDATE_ALWAYS;
+ 2197 3 : else if (strcmp(updated, "Offline") == 0)
+ 2198 3 : flags |= SMART_ATTR_UPDATE_OFFLINE;
+ 2199 31 : if (strcmp(when_failed, "FAILING_NOW") == 0)
+ 2200 0 : flags |= SMART_ATTR_WHEN_FAILED_NOW;
+ 2201 31 : else if (strcmp(when_failed, "In_the_past") == 0)
+ 2202 0 : flags |= SMART_ATTR_WHEN_FAILED_PAST;
+ 2203 31 : else if (strcmp(when_failed, "-") == 0)
+ 2204 31 : flags |= SMART_ATTR_WHEN_FAILED_NEVER;
+ 2205 :
+ 2206 : /* revert the min/max decoding done by smartctl */
+ 2207 31 : if (minmax
+ 2208 1 : && raw <= 0xFFFFUL
+ 2209 1 : && min <= 0xFFFFUL
+ 2210 1 : && max <= 0xFFFFUL) {
+ 2211 1 : raw |= min << 16;
+ 2212 1 : raw |= max << 32;
+ 2213 : }
+ 2214 :
+ 2215 31 : smart[id].raw = raw;
+ 2216 31 : smart[id].norm = norm;
+ 2217 31 : smart[id].worst = worst;
+ 2218 31 : smart[id].thresh = thresh;
+ 2219 31 : smart[id].flags = flags;
+ 2220 31 : pathcpy(smart[id].name, sizeof(smart[id].name), id_name);
+ 2221 :
+ 2222 : /*
+ 2223 : * Map normalized health percentage to our unified wear level for SSDs
+ 2224 : * 177: Wear_Leveling_Count (Samsung/Crucial)
+ 2225 : * 231: SSD_Life_Left (Kingston/WD)
+ 2226 : * 233: Media_Wearout_Indicator (Intel)
+ 2227 : */
+ 2228 31 : if (norm <= 100) {
+ 2229 25 : switch (id) {
+ 2230 1 : case 177 :
+ 2231 : case 233 :
+ 2232 : case 231 :
+ 2233 1 : smart[SMART_WEAR_LEVEL].raw = 100 - norm;
+ 2234 1 : break;
+ 2235 : }
+ 2236 : }
+ 2237 : }
+ 2238 : }
+ 2239 :
+ 2240 14 : return 0;
+ 2241 : }
+ 2242 :
+ 2243 25 : int smartctl_flush(FILE* f, const char* file, const char* name)
+ 2244 : {
+ 2245 : /* read the file */
+ 2246 20 : while (1) {
+ 2247 : char buf[256];
+ 2248 : char* s;
+ 2249 :
+ 2250 25 : s = fgets(buf, sizeof(buf), f);
+ 2251 25 : if (s == 0)
+ 2252 5 : break;
2253 :
- 2254 5 : return 0;
- 2255 : }
+ 2254 : /* remove extraneous chars */
+ 2255 20 : s = strpolish(buf);
2256 :
- 2257 145110 : int smart_temp(devinfo_t* devinfo)
- 2258 : {
- 2259 145110 : uint64_t t = devinfo->smart[SMART_TEMPERATURE_CELSIUS].raw;
- 2260 145110 : if (t == SMART_UNASSIGNED)
- 2261 0 : t = devinfo->smart[SMART_AIRFLOW_TEMPERATURE_CELSIUS].raw;
- 2262 145110 : if (t == SMART_UNASSIGNED)
- 2263 0 : return -1;
- 2264 :
- 2265 : /* mask out min/max values */
- 2266 145110 : t &= 0xFFFFUL;
- 2267 :
- 2268 145110 : if (t == 0)
- 2269 0 : return -1;
- 2270 145110 : if (t > 100)
- 2271 0 : return -1;
- 2272 :
- 2273 145110 : return t;
- 2274 : }
- 2275 :
- 2276 : /****************************************************************************/
- 2277 : /* thread */
+ 2257 20 : log_tag("smartctl:%s:%s:out: %s\n", file, name, s);
+ 2258 : }
+ 2259 :
+ 2260 5 : return 0;
+ 2261 : }
+ 2262 :
+ 2263 145124 : int smart_temp(devinfo_t* devinfo)
+ 2264 : {
+ 2265 145124 : uint64_t t = devinfo->smart[SMART_TEMPERATURE_CELSIUS].raw;
+ 2266 145124 : if (t == SMART_UNASSIGNED)
+ 2267 13 : t = devinfo->smart[SMART_AIRFLOW_TEMPERATURE_CELSIUS].raw;
+ 2268 145124 : if (t == SMART_UNASSIGNED)
+ 2269 12 : return -1;
+ 2270 :
+ 2271 : /* mask out min/max values */
+ 2272 145112 : t &= 0xFFFFUL;
+ 2273 :
+ 2274 145112 : if (t == 0)
+ 2275 0 : return -1;
+ 2276 145112 : if (t > 100)
+ 2277 0 : return -1;
2278 :
- 2279 : #if HAVE_THREAD
- 2280 3299 : void thread_mutex_init(thread_mutex_t* mutex)
- 2281 : {
- 2282 3299 : if (pthread_mutex_init(mutex, 0) != 0) {
- 2283 : /* LCOV_EXCL_START */
- 2284 : log_fatal(EINTERNAL, "Failed call to pthread_mutex_init().\n");
- 2285 : os_abort();
- 2286 : /* LCOV_EXCL_STOP */
- 2287 : }
- 2288 3299 : }
- 2289 :
- 2290 3167 : void thread_mutex_destroy(thread_mutex_t* mutex)
- 2291 : {
- 2292 3167 : if (pthread_mutex_destroy(mutex) != 0) {
- 2293 : /* LCOV_EXCL_START */
- 2294 : log_fatal(EINTERNAL, "Failed call to pthread_mutex_destroy().\n");
- 2295 : os_abort();
- 2296 : /* LCOV_EXCL_STOP */
- 2297 : }
- 2298 3167 : }
- 2299 :
- 2300 112510359 : void thread_mutex_lock(thread_mutex_t* mutex)
- 2301 : {
- 2302 112510359 : if (pthread_mutex_lock(mutex) != 0) {
- 2303 : /* LCOV_EXCL_START */
- 2304 : log_fatal(EINTERNAL, "Failed call to pthread_mutex_lock().\n");
- 2305 : os_abort();
- 2306 : /* LCOV_EXCL_STOP */
- 2307 : }
- 2308 112510359 : }
- 2309 :
- 2310 112510359 : void thread_mutex_unlock(thread_mutex_t* mutex)
- 2311 : {
- 2312 112510359 : if (pthread_mutex_unlock(mutex) != 0) {
- 2313 : /* LCOV_EXCL_START */
- 2314 : log_fatal(EINTERNAL, "Failed call to pthread_mutex_unlock().\n");
- 2315 : os_abort();
- 2316 : /* LCOV_EXCL_STOP */
- 2317 : }
- 2318 112510359 : }
- 2319 :
- 2320 404 : void thread_cond_init(thread_cond_t* cond)
- 2321 : {
- 2322 404 : if (pthread_cond_init(cond, 0) != 0) {
- 2323 : /* LCOV_EXCL_START */
- 2324 : log_fatal(EINTERNAL, "Failed call to pthread_cond_init().\n");
- 2325 : os_abort();
- 2326 : /* LCOV_EXCL_STOP */
- 2327 : }
- 2328 404 : }
- 2329 :
- 2330 404 : void thread_cond_destroy(thread_cond_t* cond)
- 2331 : {
- 2332 404 : if (pthread_cond_destroy(cond) != 0) {
- 2333 : /* LCOV_EXCL_START */
- 2334 : log_fatal(EINTERNAL, "Failed call to pthread_cond_destroy().\n");
- 2335 : os_abort();
- 2336 : /* LCOV_EXCL_STOP */
- 2337 : }
- 2338 404 : }
- 2339 :
- 2340 668 : void thread_cond_signal(thread_cond_t* cond)
- 2341 : {
- 2342 668 : if (pthread_cond_signal(cond) != 0) {
- 2343 : /* LCOV_EXCL_START */
- 2344 : log_fatal(EINTERNAL, "Failed call to pthread_cond_signal().\n");
- 2345 : os_abort();
- 2346 : /* LCOV_EXCL_STOP */
- 2347 : }
- 2348 668 : }
- 2349 :
- 2350 257671 : void thread_cond_broadcast(thread_cond_t* cond)
- 2351 : {
- 2352 257671 : if (pthread_cond_broadcast(cond) != 0) {
- 2353 : /* LCOV_EXCL_START */
- 2354 : log_fatal(EINTERNAL, "Failed call to pthread_cond_broadcast().\n");
- 2355 : os_abort();
- 2356 : /* LCOV_EXCL_STOP */
- 2357 : }
- 2358 257671 : }
- 2359 :
- 2360 1554330 : void thread_cond_wait(thread_cond_t* cond, thread_mutex_t* mutex)
- 2361 : {
- 2362 1554330 : if (pthread_cond_wait(cond, mutex) != 0) {
- 2363 : /* LCOV_EXCL_START */
- 2364 : log_fatal(EINTERNAL, "Failed call to pthread_cond_wait().\n");
- 2365 : os_abort();
- 2366 : /* LCOV_EXCL_STOP */
- 2367 : }
- 2368 1554330 : }
- 2369 :
- 2370 : /**
- 2371 : * Implementation note about conditional variables.
- 2372 : *
- 2373 : * The conditional variables can be signaled inside or outside the mutex,
- 2374 : * what is better it's debatable but in general doing that outside the mutex,
- 2375 : * reduces the number of context switches.
- 2376 : *
- 2377 : * But when testing with helgrind and drd, this disallows such tools to
- 2378 : * to see the dependency between the signal and the wait.
- 2379 : *
- 2380 : * To avoid it we signal everything inside the mutex. And we do this in both
- 2381 : * test mode (with CHECKER defined) and release mode (CHECKER not defined),
- 2382 : * to be on the safe side and avoid any difference in behaviour between test and
- 2383 : * release.
- 2384 : *
- 2385 : * Here some interesting discussion:
- 2386 : *
- 2387 : * Condvars: signal with mutex locked or not?
- 2388 : * http://www.domaigne.com/blog/computing/condvars-signal-with-mutex-locked-or-not/
- 2389 : *
- 2390 : * Calling pthread_cond_signal without locking mutex
- 2391 : * http://stackoverflow.com/questions/4544234/calling-pthread-cond-signal-without-locking-mutex/4544494#4544494
- 2392 : */
- 2393 :
- 2394 : /**
- 2395 : * Control when to signal the condition variables.
- 2396 : */
- 2397 : int thread_cond_signal_outside = 0;
- 2398 :
- 2399 668 : void thread_cond_signal_and_unlock(thread_cond_t* cond, thread_mutex_t* mutex)
- 2400 : {
- 2401 668 : if (thread_cond_signal_outside) {
- 2402 : /* without the thread checker unlock before signaling, */
- 2403 : /* this reduces the number of context switches */
- 2404 0 : thread_mutex_unlock(mutex);
- 2405 : }
- 2406 :
- 2407 668 : thread_cond_signal(cond);
- 2408 :
- 2409 668 : if (!thread_cond_signal_outside) {
- 2410 : /* with the thread checker unlock after signaling */
- 2411 : /* to make explicit the condition and mutex relation */
- 2412 668 : thread_mutex_unlock(mutex);
- 2413 : }
- 2414 668 : }
- 2415 :
- 2416 257469 : void thread_cond_broadcast_and_unlock(thread_cond_t* cond, thread_mutex_t* mutex)
- 2417 : {
- 2418 257469 : if (thread_cond_signal_outside) {
- 2419 : /* without the thread checker unlock before signaling, */
- 2420 : /* this reduces the number of context switches */
- 2421 0 : thread_mutex_unlock(mutex);
- 2422 : }
- 2423 :
- 2424 257469 : thread_cond_broadcast(cond);
- 2425 :
- 2426 257469 : if (!thread_cond_signal_outside) {
- 2427 : /* with the thread checker unlock after signaling */
- 2428 : /* to make explicit the condition and mutex relation */
- 2429 257469 : thread_mutex_unlock(mutex);
- 2430 : }
- 2431 257469 : }
- 2432 :
- 2433 2876 : void thread_create(thread_id_t* thread, void* (*func)(void*), void* arg)
- 2434 : {
- 2435 2876 : if (pthread_create(thread, 0, func, arg) != 0) {
- 2436 : /* LCOV_EXCL_START */
- 2437 : log_fatal(EINTERNAL, "Failed call to pthread_create().\n");
- 2438 : os_abort();
- 2439 : /* LCOV_EXCL_STOP */
- 2440 : }
- 2441 2876 : }
- 2442 :
- 2443 2876 : void thread_join(thread_id_t thread, void** retval)
- 2444 : {
- 2445 2876 : if (pthread_join(thread, retval) != 0) {
- 2446 : /* LCOV_EXCL_START */
- 2447 : log_fatal(EINTERNAL, "Failed call to pthread_join().\n");
- 2448 : os_abort();
- 2449 : /* LCOV_EXCL_STOP */
- 2450 : }
- 2451 2876 : }
- 2452 :
- 2453 105499 : void thread_yield(void)
- 2454 : {
- 2455 : #ifdef __MINGW32__
- 2456 : Sleep(0);
- 2457 : #else
- 2458 105499 : sched_yield();
- 2459 : #endif
- 2460 105499 : }
- 2461 : #endif
- 2462 :
- 2463 : /****************************************************************************/
- 2464 : /* wnmatch */
- 2465 :
- 2466 : /**
- 2467 : * Helper function for case-insensitive character comparison
- 2468 : */
- 2469 86982601 : static inline int char_match(char p, char t)
- 2470 : {
- 2471 : #ifdef WIN32
- 2472 : return tolower((unsigned char)p) == tolower((unsigned char)t);
- 2473 : #else
- 2474 86982601 : return p == t;
- 2475 : #endif
- 2476 : }
- 2477 :
- 2478 : /**
- 2479 : * Match character class [...]
- 2480 : * Return 0 if NOT matched
- 2481 : */
- 2482 28 : static const char* match_class(const char* p, char t)
- 2483 : {
- 2484 28 : int negate = 0;
- 2485 28 : int matched = 0;
- 2486 :
- 2487 28 : if (*p == '!' || *p == '^') {
- 2488 9 : negate = 1;
- 2489 9 : ++p;
- 2490 : }
- 2491 :
- 2492 77 : while (*p && *p != ']') {
- 2493 49 : if (p[1] == '-' && p[2] != ']' && p[2] != 0) {
- 2494 : /* range [a-z] */
- 2495 22 : char start = *p;
- 2496 22 : char end = p[2];
- 2497 : #ifdef WIN32
- 2498 : start = tolower((unsigned char)start);
- 2499 : end = tolower((unsigned char)end);
- 2500 : t = tolower((unsigned char)t);
- 2501 : #endif
- 2502 22 : if (t >= start && t <= end)
- 2503 10 : matched = 1;
- 2504 22 : p += 3;
- 2505 : } else {
- 2506 : /* single character */
- 2507 27 : if (char_match(*p, t))
- 2508 5 : matched = 1;
- 2509 27 : ++p;
- 2510 : }
- 2511 : }
- 2512 :
- 2513 28 : if (*p == ']')
- 2514 28 : ++p;
- 2515 :
- 2516 28 : if (negate)
- 2517 9 : matched = !matched;
- 2518 28 : if (!matched)
- 2519 14 : return 0;
- 2520 :
- 2521 14 : return p;
- 2522 : }
- 2523 :
- 2524 102260599 : int wnmatch(const char* p, const char* t)
- 2525 : {
- 2526 102260599 : char p1 = 0; /* previous char */
- 2527 105985464 : while (*p) {
- 2528 105852004 : char p0 = *p;
- 2529 105852004 : switch (p0) {
- 2530 20 : case '?' :
- 2531 : /* ? matches any single character except / */
- 2532 20 : if (*t == 0 || *t == '/')
- 2533 4 : return 1;
- 2534 16 : ++p;
- 2535 16 : ++t;
- 2536 16 : break;
- 2537 12656225 : case '*' :
- 2538 : /* check for ** */
- 2539 12656225 : if (p[1] == '*') {
- 2540 : /* skip the ** */
- 2541 104 : p += 2;
- 2542 :
- 2543 : /* munge all * */
- 2544 114 : while (*p == '*')
- 2545 10 : ++p;
- 2546 :
- 2547 : /* if its not near a slash, it's like a single * */
- 2548 104 : if (p1 == '/' || *p == '/') {
- 2549 : /* a ** at end matches everything */
- 2550 84 : if (*p == 0)
- 2551 10 : return 0;
+ 2279 145112 : return t;
+ 2280 : }
+ 2281 :
+ 2282 : /****************************************************************************/
+ 2283 : /* thread */
+ 2284 :
+ 2285 : #if HAVE_THREAD
+ 2286 3312 : void thread_mutex_init(thread_mutex_t* mutex)
+ 2287 : {
+ 2288 3312 : if (pthread_mutex_init(mutex, 0) != 0) {
+ 2289 : /* LCOV_EXCL_START */
+ 2290 : log_fatal(EINTERNAL, "Failed call to pthread_mutex_init().\n");
+ 2291 : os_abort();
+ 2292 : /* LCOV_EXCL_STOP */
+ 2293 : }
+ 2294 3312 : }
+ 2295 :
+ 2296 3180 : void thread_mutex_destroy(thread_mutex_t* mutex)
+ 2297 : {
+ 2298 3180 : if (pthread_mutex_destroy(mutex) != 0) {
+ 2299 : /* LCOV_EXCL_START */
+ 2300 : log_fatal(EINTERNAL, "Failed call to pthread_mutex_destroy().\n");
+ 2301 : os_abort();
+ 2302 : /* LCOV_EXCL_STOP */
+ 2303 : }
+ 2304 3180 : }
+ 2305 :
+ 2306 112377134 : void thread_mutex_lock(thread_mutex_t* mutex)
+ 2307 : {
+ 2308 112377134 : if (pthread_mutex_lock(mutex) != 0) {
+ 2309 : /* LCOV_EXCL_START */
+ 2310 : log_fatal(EINTERNAL, "Failed call to pthread_mutex_lock().\n");
+ 2311 : os_abort();
+ 2312 : /* LCOV_EXCL_STOP */
+ 2313 : }
+ 2314 112377134 : }
+ 2315 :
+ 2316 112377134 : void thread_mutex_unlock(thread_mutex_t* mutex)
+ 2317 : {
+ 2318 112377134 : if (pthread_mutex_unlock(mutex) != 0) {
+ 2319 : /* LCOV_EXCL_START */
+ 2320 : log_fatal(EINTERNAL, "Failed call to pthread_mutex_unlock().\n");
+ 2321 : os_abort();
+ 2322 : /* LCOV_EXCL_STOP */
+ 2323 : }
+ 2324 112377134 : }
+ 2325 :
+ 2326 404 : void thread_cond_init(thread_cond_t* cond)
+ 2327 : {
+ 2328 404 : if (pthread_cond_init(cond, 0) != 0) {
+ 2329 : /* LCOV_EXCL_START */
+ 2330 : log_fatal(EINTERNAL, "Failed call to pthread_cond_init().\n");
+ 2331 : os_abort();
+ 2332 : /* LCOV_EXCL_STOP */
+ 2333 : }
+ 2334 404 : }
+ 2335 :
+ 2336 404 : void thread_cond_destroy(thread_cond_t* cond)
+ 2337 : {
+ 2338 404 : if (pthread_cond_destroy(cond) != 0) {
+ 2339 : /* LCOV_EXCL_START */
+ 2340 : log_fatal(EINTERNAL, "Failed call to pthread_cond_destroy().\n");
+ 2341 : os_abort();
+ 2342 : /* LCOV_EXCL_STOP */
+ 2343 : }
+ 2344 404 : }
+ 2345 :
+ 2346 827 : void thread_cond_signal(thread_cond_t* cond)
+ 2347 : {
+ 2348 827 : if (pthread_cond_signal(cond) != 0) {
+ 2349 : /* LCOV_EXCL_START */
+ 2350 : log_fatal(EINTERNAL, "Failed call to pthread_cond_signal().\n");
+ 2351 : os_abort();
+ 2352 : /* LCOV_EXCL_STOP */
+ 2353 : }
+ 2354 827 : }
+ 2355 :
+ 2356 257545 : void thread_cond_broadcast(thread_cond_t* cond)
+ 2357 : {
+ 2358 257545 : if (pthread_cond_broadcast(cond) != 0) {
+ 2359 : /* LCOV_EXCL_START */
+ 2360 : log_fatal(EINTERNAL, "Failed call to pthread_cond_broadcast().\n");
+ 2361 : os_abort();
+ 2362 : /* LCOV_EXCL_STOP */
+ 2363 : }
+ 2364 257545 : }
+ 2365 :
+ 2366 1554290 : void thread_cond_wait(thread_cond_t* cond, thread_mutex_t* mutex)
+ 2367 : {
+ 2368 1554290 : if (pthread_cond_wait(cond, mutex) != 0) {
+ 2369 : /* LCOV_EXCL_START */
+ 2370 : log_fatal(EINTERNAL, "Failed call to pthread_cond_wait().\n");
+ 2371 : os_abort();
+ 2372 : /* LCOV_EXCL_STOP */
+ 2373 : }
+ 2374 1554290 : }
+ 2375 :
+ 2376 : /**
+ 2377 : * Implementation note about conditional variables.
+ 2378 : *
+ 2379 : * The conditional variables can be signaled inside or outside the mutex,
+ 2380 : * what is better it's debatable but in general doing that outside the mutex,
+ 2381 : * reduces the number of context switches.
+ 2382 : *
+ 2383 : * But when testing with helgrind and drd, this disallows such tools to
+ 2384 : * to see the dependency between the signal and the wait.
+ 2385 : *
+ 2386 : * To avoid it we signal everything inside the mutex. And we do this in both
+ 2387 : * test mode (with CHECKER defined) and release mode (CHECKER not defined),
+ 2388 : * to be on the safe side and avoid any difference in behaviour between test and
+ 2389 : * release.
+ 2390 : *
+ 2391 : * Here some interesting discussion:
+ 2392 : *
+ 2393 : * Condvars: signal with mutex locked or not?
+ 2394 : * http://www.domaigne.com/blog/computing/condvars-signal-with-mutex-locked-or-not/
+ 2395 : *
+ 2396 : * Calling pthread_cond_signal without locking mutex
+ 2397 : * http://stackoverflow.com/questions/4544234/calling-pthread-cond-signal-without-locking-mutex/4544494#4544494
+ 2398 : */
+ 2399 :
+ 2400 : /**
+ 2401 : * Control when to signal the condition variables.
+ 2402 : */
+ 2403 : int thread_cond_signal_outside = 0;
+ 2404 :
+ 2405 827 : void thread_cond_signal_and_unlock(thread_cond_t* cond, thread_mutex_t* mutex)
+ 2406 : {
+ 2407 827 : if (thread_cond_signal_outside) {
+ 2408 : /* without the thread checker unlock before signaling, */
+ 2409 : /* this reduces the number of context switches */
+ 2410 0 : thread_mutex_unlock(mutex);
+ 2411 : }
+ 2412 :
+ 2413 827 : thread_cond_signal(cond);
+ 2414 :
+ 2415 827 : if (!thread_cond_signal_outside) {
+ 2416 : /* with the thread checker unlock after signaling */
+ 2417 : /* to make explicit the condition and mutex relation */
+ 2418 827 : thread_mutex_unlock(mutex);
+ 2419 : }
+ 2420 827 : }
+ 2421 :
+ 2422 257343 : void thread_cond_broadcast_and_unlock(thread_cond_t* cond, thread_mutex_t* mutex)
+ 2423 : {
+ 2424 257343 : if (thread_cond_signal_outside) {
+ 2425 : /* without the thread checker unlock before signaling, */
+ 2426 : /* this reduces the number of context switches */
+ 2427 0 : thread_mutex_unlock(mutex);
+ 2428 : }
+ 2429 :
+ 2430 257343 : thread_cond_broadcast(cond);
+ 2431 :
+ 2432 257343 : if (!thread_cond_signal_outside) {
+ 2433 : /* with the thread checker unlock after signaling */
+ 2434 : /* to make explicit the condition and mutex relation */
+ 2435 257343 : thread_mutex_unlock(mutex);
+ 2436 : }
+ 2437 257343 : }
+ 2438 :
+ 2439 2883 : void thread_create(thread_id_t* thread, void* (*func)(void*), void* arg)
+ 2440 : {
+ 2441 2883 : if (pthread_create(thread, 0, func, arg) != 0) {
+ 2442 : /* LCOV_EXCL_START */
+ 2443 : log_fatal(EINTERNAL, "Failed call to pthread_create().\n");
+ 2444 : os_abort();
+ 2445 : /* LCOV_EXCL_STOP */
+ 2446 : }
+ 2447 2883 : }
+ 2448 :
+ 2449 2883 : void thread_join(thread_id_t thread, void** retval)
+ 2450 : {
+ 2451 2883 : if (pthread_join(thread, retval) != 0) {
+ 2452 : /* LCOV_EXCL_START */
+ 2453 : log_fatal(EINTERNAL, "Failed call to pthread_join().\n");
+ 2454 : os_abort();
+ 2455 : /* LCOV_EXCL_STOP */
+ 2456 : }
+ 2457 2883 : }
+ 2458 :
+ 2459 108112 : void thread_yield(void)
+ 2460 : {
+ 2461 : #ifdef __MINGW32__
+ 2462 : Sleep(0);
+ 2463 : #else
+ 2464 108112 : sched_yield();
+ 2465 : #endif
+ 2466 108112 : }
+ 2467 : #endif
+ 2468 :
+ 2469 : /****************************************************************************/
+ 2470 : /* wnmatch */
+ 2471 :
+ 2472 : /**
+ 2473 : * Helper function for case-insensitive character comparison
+ 2474 : */
+ 2475 86985273 : static inline int char_match(char p, char t)
+ 2476 : {
+ 2477 : #ifdef WIN32
+ 2478 : return tolower((unsigned char)p) == tolower((unsigned char)t);
+ 2479 : #else
+ 2480 86985273 : return p == t;
+ 2481 : #endif
+ 2482 : }
+ 2483 :
+ 2484 : /**
+ 2485 : * Match character class [...]
+ 2486 : * Return 0 if NOT matched
+ 2487 : */
+ 2488 28 : static const char* match_class(const char* p, char t)
+ 2489 : {
+ 2490 28 : int negate = 0;
+ 2491 28 : int matched = 0;
+ 2492 :
+ 2493 28 : if (*p == '!' || *p == '^') {
+ 2494 9 : negate = 1;
+ 2495 9 : ++p;
+ 2496 : }
+ 2497 :
+ 2498 77 : while (*p && *p != ']') {
+ 2499 49 : if (p[1] == '-' && p[2] != ']' && p[2] != 0) {
+ 2500 : /* range [a-z] */
+ 2501 22 : char start = *p;
+ 2502 22 : char end = p[2];
+ 2503 : #ifdef WIN32
+ 2504 : start = tolower((unsigned char)start);
+ 2505 : end = tolower((unsigned char)end);
+ 2506 : t = tolower((unsigned char)t);
+ 2507 : #endif
+ 2508 22 : if (t >= start && t <= end)
+ 2509 10 : matched = 1;
+ 2510 22 : p += 3;
+ 2511 : } else {
+ 2512 : /* single character */
+ 2513 27 : if (char_match(*p, t))
+ 2514 5 : matched = 1;
+ 2515 27 : ++p;
+ 2516 : }
+ 2517 : }
+ 2518 :
+ 2519 28 : if (*p == ']')
+ 2520 28 : ++p;
+ 2521 :
+ 2522 28 : if (negate)
+ 2523 9 : matched = !matched;
+ 2524 28 : if (!matched)
+ 2525 14 : return 0;
+ 2526 :
+ 2527 14 : return p;
+ 2528 : }
+ 2529 :
+ 2530 102263029 : int wnmatch(const char* p, const char* t)
+ 2531 : {
+ 2532 102263029 : char p1 = 0; /* previous char */
+ 2533 105988951 : while (*p) {
+ 2534 105855413 : char p0 = *p;
+ 2535 105855413 : switch (p0) {
+ 2536 20 : case '?' :
+ 2537 : /* ? matches any single character except / */
+ 2538 20 : if (*t == 0 || *t == '/')
+ 2539 4 : return 1;
+ 2540 16 : ++p;
+ 2541 16 : ++t;
+ 2542 16 : break;
+ 2543 12656765 : case '*' :
+ 2544 : /* check for ** */
+ 2545 12656765 : if (p[1] == '*') {
+ 2546 : /* skip the ** */
+ 2547 104 : p += 2;
+ 2548 :
+ 2549 : /* munge all * */
+ 2550 114 : while (*p == '*')
+ 2551 10 : ++p;
2552 :
- 2553 : /*
- 2554 : * In between slashes matches to nothing
- 2555 : *
- 2556 : * Check for /##/ or ^##/ (^ start of string)
- 2557 : *
- 2558 : * This is required for:
- 2559 : * "/##/file.txt" matching "/file.txt"
- 2560 : * "##/file.txt" matching "file.txt"
- 2561 : * "x##/file.txt" NOT matching "xfile.txt"
- 2562 : */
- 2563 74 : if (*p == '/' && (p1 == 0 || p1 == '/')) {
- 2564 : /* try reducing to nothing */
- 2565 71 : if (wnmatch(p + 1, t) == 0)
- 2566 27 : return 0;
- 2567 : /* otherwise / should match in the text */
- 2568 : }
- 2569 :
- 2570 : /* try matching with 0 or more characters */
- 2571 275 : while (*t) {
- 2572 263 : if (wnmatch(p, t) == 0)
- 2573 35 : return 0;
- 2574 228 : ++t;
- 2575 : }
- 2576 :
- 2577 : /* try matching at the end */
- 2578 12 : return wnmatch(p, t);
- 2579 : }
- 2580 : } else {
- 2581 : /* skip the * */
- 2582 12656121 : ++p;
- 2583 : }
- 2584 :
- 2585 : /* a * at end matches rest of segment */
- 2586 12656141 : if (*p == 0) {
- 2587 60 : while (*t && *t != '/')
- 2588 49 : ++t;
- 2589 11 : return *t != 0;
- 2590 : }
- 2591 :
- 2592 : /* try matching with 0 or more characters */
- 2593 89476178 : while (*t && *t != '/') {
- 2594 76944779 : if (wnmatch(p, t) == 0)
- 2595 124731 : return 0;
- 2596 76820048 : ++t;
- 2597 : }
- 2598 :
- 2599 : /* try matching at the end */
- 2600 12531399 : return wnmatch(p, t);
- 2601 31 : case '[' :
- 2602 : /* character class */
- 2603 31 : if (*t == 0 || *t == '/')
- 2604 3 : return 1;
- 2605 :
- 2606 28 : p = match_class(p + 1, *t);
- 2607 28 : if (!p)
- 2608 14 : return 1;
- 2609 :
- 2610 14 : ++t;
- 2611 14 : break;
- 2612 93195728 : default :
- 2613 : /* literal character */
- 2614 93195728 : if (*t == 0 || !char_match(*p, *t))
- 2615 89470893 : return 1;
- 2616 3724835 : ++p;
- 2617 3724835 : ++t;
- 2618 3724835 : break;
- 2619 : }
- 2620 3724865 : p1 = p0;
- 2621 : }
- 2622 :
- 2623 : /* match successful if we've consumed all text */
- 2624 133460 : return *t != 0;
- 2625 : }
- 2626 :
+ 2553 : /* if its not near a slash, it's like a single * */
+ 2554 104 : if (p1 == '/' || *p == '/') {
+ 2555 : /* a ** at end matches everything */
+ 2556 84 : if (*p == 0)
+ 2557 10 : return 0;
+ 2558 :
+ 2559 : /*
+ 2560 : * In between slashes matches to nothing
+ 2561 : *
+ 2562 : * Check for /##/ or ^##/ (^ start of string)
+ 2563 : *
+ 2564 : * This is required for:
+ 2565 : * "/##/file.txt" matching "/file.txt"
+ 2566 : * "##/file.txt" matching "file.txt"
+ 2567 : * "x##/file.txt" NOT matching "xfile.txt"
+ 2568 : */
+ 2569 74 : if (*p == '/' && (p1 == 0 || p1 == '/')) {
+ 2570 : /* try reducing to nothing */
+ 2571 71 : if (wnmatch(p + 1, t) == 0)
+ 2572 27 : return 0;
+ 2573 : /* otherwise / should match in the text */
+ 2574 : }
+ 2575 :
+ 2576 : /* try matching with 0 or more characters */
+ 2577 275 : while (*t) {
+ 2578 263 : if (wnmatch(p, t) == 0)
+ 2579 35 : return 0;
+ 2580 228 : ++t;
+ 2581 : }
+ 2582 :
+ 2583 : /* try matching at the end */
+ 2584 12 : return wnmatch(p, t);
+ 2585 : }
+ 2586 : } else {
+ 2587 : /* skip the * */
+ 2588 12656661 : ++p;
+ 2589 : }
+ 2590 :
+ 2591 : /* a * at end matches rest of segment */
+ 2592 12656681 : if (*p == 0) {
+ 2593 60 : while (*t && *t != '/')
+ 2594 49 : ++t;
+ 2595 11 : return *t != 0;
+ 2596 : }
+ 2597 :
+ 2598 : /* try matching with 0 or more characters */
+ 2599 89478068 : while (*t && *t != '/') {
+ 2600 76946207 : if (wnmatch(p, t) == 0)
+ 2601 124809 : return 0;
+ 2602 76821398 : ++t;
+ 2603 : }
+ 2604 :
+ 2605 : /* try matching at the end */
+ 2606 12531861 : return wnmatch(p, t);
+ 2607 31 : case '[' :
+ 2608 : /* character class */
+ 2609 31 : if (*t == 0 || *t == '/')
+ 2610 3 : return 1;
+ 2611 :
+ 2612 28 : p = match_class(p + 1, *t);
+ 2613 28 : if (!p)
+ 2614 14 : return 1;
+ 2615 :
+ 2616 14 : ++t;
+ 2617 14 : break;
+ 2618 93198597 : default :
+ 2619 : /* literal character */
+ 2620 93198597 : if (*t == 0 || !char_match(*p, *t))
+ 2621 89472705 : return 1;
+ 2622 3725892 : ++p;
+ 2623 3725892 : ++t;
+ 2624 3725892 : break;
+ 2625 : }
+ 2626 3725922 : p1 = p0;
+ 2627 : }
+ 2628 :
+ 2629 : /* match successful if we've consumed all text */
+ 2630 133538 : return *t != 0;
+ 2631 : }
+ 2632 :
diff --git a/cov/cmdline/support.h.func-sort-c.html b/cov/cmdline/support.h.func-sort-c.html
index 9991d0bb..6755a63b 100644
--- a/cov/cmdline/support.h.func-sort-c.html
+++ b/cov/cmdline/support.h.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,7 +61,7 @@
| esc_shell |
- 342153 |
+ 342322 |
diff --git a/cov/cmdline/support.h.func.html b/cov/cmdline/support.h.func.html
index e1796c7e..1647af1e 100644
--- a/cov/cmdline/support.h.func.html
+++ b/cov/cmdline/support.h.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,7 +61,7 @@
| esc_shell |
- 342153 |
+ 342322 |
diff --git a/cov/cmdline/support.h.gcov.html b/cov/cmdline/support.h.gcov.html
index 97b66087..aae9d877 100644
--- a/cov/cmdline/support.h.gcov.html
+++ b/cov/cmdline/support.h.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -328,9 +328,9 @@
266 : * \param buffer Preallocated buffer of ESC_MAX size.
267 : */
268 : const char* esc_shell_multi(const char** str_map, unsigned str_max, char* buffer);
- 269 342153 : static inline const char* esc_shell(const char* str, char* buffer)
+ 269 342322 : static inline const char* esc_shell(const char* str, char* buffer)
270 : {
- 271 342153 : return esc_shell_multi(&str, 1, buffer);
+ 271 342322 : return esc_shell_multi(&str, 1, buffer);
272 : }
273 :
274 : /**
diff --git a/cov/cmdline/sync.c.func-sort-c.html b/cov/cmdline/sync.c.func-sort-c.html
index 3546ca35..8e531515 100644
--- a/cov/cmdline/sync.c.func-sort-c.html
+++ b/cov/cmdline/sync.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -77,7 +77,7 @@
| failed_compare_by_index |
- 851 |
+ 852 |
| block_is_enabled |
@@ -85,11 +85,11 @@
| sync_parity_writer |
- 558683 |
+ 558371 |
| sync_data_reader |
- 694374 |
+ 693996 |
diff --git a/cov/cmdline/sync.c.func.html b/cov/cmdline/sync.c.func.html
index 9ca34905..33ebfd23 100644
--- a/cov/cmdline/sync.c.func.html
+++ b/cov/cmdline/sync.c.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -69,7 +69,7 @@
| failed_compare_by_index |
- 851 |
+ 852 |
| state_hash_process |
@@ -85,11 +85,11 @@
| sync_data_reader |
- 694374 |
+ 693996 |
| sync_parity_writer |
- 558683 |
+ 558371 |
diff --git a/cov/cmdline/sync.c.gcov.html b/cov/cmdline/sync.c.gcov.html
index 28bb9e42..2fa657a9 100644
--- a/cov/cmdline/sync.c.gcov.html
+++ b/cov/cmdline/sync.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -480,13 +480,13 @@
418 : /**
419 : * Comparison function for sorting by index.
420 : */
- 421 851 : int failed_compare_by_index(const void* void_a, const void* void_b)
+ 421 852 : int failed_compare_by_index(const void* void_a, const void* void_b)
422 : {
- 423 851 : const struct failed_struct* a = void_a;
- 424 851 : const struct failed_struct* b = void_b;
+ 423 852 : const struct failed_struct* a = void_a;
+ 424 852 : const struct failed_struct* b = void_b;
425 :
- 426 851 : if (a->index < b->index)
- 427 851 : return -1;
+ 426 852 : if (a->index < b->index)
+ 427 852 : return -1;
428 0 : if (a->index > b->index)
429 0 : return 1;
430 0 : return 0;
@@ -526,56 +526,56 @@
464 2488621 : one_valid = 1;
465 :
466 2631257 : if (block_has_invalid_parity(block) || plan->force_full)
- 467 377610 : one_invalid = 1;
+ 467 377555 : one_invalid = 1;
468 : }
469 :
470 : /* if none valid or none invalid, we don't need to update */
471 439324 : if (!one_invalid || !one_valid)
- 472 323595 : return 0;
+ 472 323658 : return 0;
473 :
- 474 115729 : return 1;
+ 474 115666 : return 1;
475 : }
476 :
- 477 694374 : static void sync_data_reader(struct snapraid_worker* worker, struct snapraid_task* task)
+ 477 693996 : static void sync_data_reader(struct snapraid_worker* worker, struct snapraid_task* task)
478 : {
- 479 694374 : struct snapraid_io* io = worker->io;
- 480 694374 : struct snapraid_state* state = io->state;
- 481 694374 : struct snapraid_handle* handle = worker->handle;
- 482 694374 : struct snapraid_disk* disk = handle->disk;
- 483 694374 : block_off_t blockcur = task->position;
- 484 694374 : unsigned char* buffer = task->buffer;
+ 479 693996 : struct snapraid_io* io = worker->io;
+ 480 693996 : struct snapraid_state* state = io->state;
+ 481 693996 : struct snapraid_handle* handle = worker->handle;
+ 482 693996 : struct snapraid_disk* disk = handle->disk;
+ 483 693996 : block_off_t blockcur = task->position;
+ 484 693996 : unsigned char* buffer = task->buffer;
485 : int ret;
486 : char esc_buffer[ESC_MAX];
487 :
488 : /* if the disk position is not used */
- 489 694374 : if (!disk) {
+ 489 693996 : if (!disk) {
490 : /* use an empty block */
491 0 : memset(buffer, 0, state->block_size);
492 0 : task->state = TASK_STATE_DONE;
- 493 107729 : return;
+ 493 107737 : return;
494 : }
495 :
496 : /* get the block */
- 497 694374 : task->block = fs_par2block_find(disk, blockcur);
+ 497 693996 : task->block = fs_par2block_find(disk, blockcur);
498 :
499 : /* if the block has no file, meaning that it's EMPTY or DELETED, */
500 : /* it doesn't participate in the new parity computation */
- 501 694374 : if (!block_has_file(task->block)) {
+ 501 693996 : if (!block_has_file(task->block)) {
502 : /* use an empty block */
- 503 107711 : memset(buffer, 0, state->block_size);
- 504 107711 : task->state = TASK_STATE_DONE;
- 505 107711 : return;
+ 503 107719 : memset(buffer, 0, state->block_size);
+ 504 107719 : task->state = TASK_STATE_DONE;
+ 505 107719 : return;
506 : }
507 :
508 : /* get the file of this block */
- 509 586663 : task->file = fs_par2file_get(disk, blockcur, &task->file_pos);
+ 509 586277 : task->file = fs_par2file_get(disk, blockcur, &task->file_pos);
510 :
511 : /* if the file is different than the current one, close it */
- 512 586663 : if (handle->file != 0 && handle->file != task->file) {
+ 512 586277 : if (handle->file != 0 && handle->file != task->file) {
513 : /* keep a pointer at the file we are going to close for error reporting */
- 514 240907 : struct snapraid_file* report = handle->file;
- 515 240907 : ret = handle_close(handle);
- 516 240907 : if (ret == -1) {
+ 514 240772 : struct snapraid_file* report = handle->file;
+ 515 240772 : ret = handle_close(handle);
+ 516 240772 : if (ret == -1) {
517 : /* LCOV_EXCL_START */
518 : /* This one is really an unexpected error, because we are only reading */
519 : /* and closing a descriptor should never fail */
@@ -593,8 +593,8 @@
531 : }
532 : }
533 :
- 534 586663 : ret = handle_open(handle, task->file, state->file_mode, log_error, log_error); /* output a message for missing files */
- 535 586663 : if (ret == -1) {
+ 534 586277 : ret = handle_open(handle, task->file, state->file_mode, log_error, log_error); /* output a message for missing files */
+ 535 586277 : if (ret == -1) {
536 12 : log_tag("%s:%u:%s:%s: Open error. %s.\n", es(errno), blockcur, disk->name, esc_tag(task->file->sub, esc_buffer), strerror(errno));
537 12 : if (errno == ENOENT) {
538 4 : log_error_errno(errno, disk->name);
@@ -628,10 +628,10 @@
566 : }
567 :
568 : /* check if the file is changed */
- 569 586651 : if (handle->st.st_size != task->file->size
- 570 586649 : || handle->st.st_mtime != task->file->mtime_sec
- 571 586647 : || STAT_NSEC(&handle->st) != task->file->mtime_nsec
- 572 586647 : || handle->st.st_ino != task->file->inode
+ 569 586265 : if (handle->st.st_size != task->file->size
+ 570 586263 : || handle->st.st_mtime != task->file->mtime_sec
+ 571 586261 : || STAT_NSEC(&handle->st) != task->file->mtime_nsec
+ 572 586261 : || handle->st.st_ino != task->file->inode
573 : ) {
574 6 : log_tag("error:%u:%s:%s: Unexpected attribute change\n", blockcur, disk->name, esc_tag(task->file->sub, esc_buffer));
575 6 : if (handle->st.st_size != task->file->size) {
@@ -650,8 +650,8 @@
588 6 : return;
589 : }
590 :
- 591 586645 : task->read_size = handle_read(handle, task->file_pos, buffer, state->block_size, log_error, 0);
- 592 586645 : if (task->read_size == -1) {
+ 591 586259 : task->read_size = handle_read(handle, task->file_pos, buffer, state->block_size, log_error, 0);
+ 592 586259 : if (task->read_size == -1) {
593 : /* LCOV_EXCL_START */
594 : log_tag("%s:%u:%s:%s: Read error at position %u. %s.\n", es(errno), blockcur, disk->name, esc_tag(task->file->sub, esc_buffer), task->file_pos, strerror(errno));
595 :
@@ -669,24 +669,24 @@
607 : }
608 :
609 : /* store the path of the opened file */
- 610 586645 : pathcpy(task->path, sizeof(task->path), handle->path);
+ 610 586259 : pathcpy(task->path, sizeof(task->path), handle->path);
611 :
- 612 586645 : task->state = TASK_STATE_DONE;
+ 612 586259 : task->state = TASK_STATE_DONE;
613 : }
614 :
- 615 558683 : static void sync_parity_writer(struct snapraid_worker* worker, struct snapraid_task* task)
+ 615 558371 : static void sync_parity_writer(struct snapraid_worker* worker, struct snapraid_task* task)
616 : {
- 617 558683 : struct snapraid_io* io = worker->io;
- 618 558683 : struct snapraid_state* state = io->state;
- 619 558683 : struct snapraid_parity_handle* parity_handle = worker->parity_handle;
- 620 558683 : unsigned level = parity_handle->level;
- 621 558683 : block_off_t blockcur = task->position;
- 622 558683 : unsigned char* buffer = task->buffer;
+ 617 558371 : struct snapraid_io* io = worker->io;
+ 618 558371 : struct snapraid_state* state = io->state;
+ 619 558371 : struct snapraid_parity_handle* parity_handle = worker->parity_handle;
+ 620 558371 : unsigned level = parity_handle->level;
+ 621 558371 : block_off_t blockcur = task->position;
+ 622 558371 : unsigned char* buffer = task->buffer;
623 : int ret;
624 :
625 : /* write parity */
- 626 558683 : ret = parity_write(parity_handle, blockcur, buffer, state->block_size);
- 627 558683 : if (ret == -1) {
+ 626 558371 : ret = parity_write(parity_handle, blockcur, buffer, state->block_size);
+ 627 558371 : if (ret == -1) {
628 : /* LCOV_EXCL_START */
629 : log_tag("parity_%s:%u:%s: Write error. %s.\n", es(errno), blockcur, lev_config_name(level), strerror(errno));
630 :
@@ -703,7 +703,7 @@
641 : /* LCOV_EXCL_STOP */
642 : }
643 :
- 644 558683 : task->state = TASK_STATE_DONE;
+ 644 558371 : task->state = TASK_STATE_DONE;
645 : }
646 :
647 88 : static int state_sync_process(struct snapraid_state* state, struct snapraid_parity_handle* parity_handle, block_off_t blockstart, block_off_t blockmax)
@@ -788,9 +788,9 @@
726 88 : block_enabled = calloc_nofail(1, bit_vect_size(blockmax)); /* preinitialize to 0 */
727 439412 : for (blockcur = blockstart; blockcur < blockmax; ++blockcur) {
728 439324 : if (!block_is_enabled(&plan, blockcur))
- 729 323595 : continue;
- 730 115729 : bit_vect_set(block_enabled, blockcur);
- 731 115729 : ++countmax;
+ 729 323658 : continue;
+ 730 115666 : bit_vect_set(block_enabled, blockcur);
+ 731 115666 : ++countmax;
732 : }
733 :
734 : /* compute the autosave size for all disk, even if not read */
@@ -817,7 +817,7 @@
755 88 : if (alert < 0)
756 0 : goto bail;
757 :
- 758 115729 : while (1) {
+ 758 115666 : while (1) {
759 : unsigned failed_count;
760 : int error_on_this_block;
761 : int silent_error_on_this_block;
@@ -831,31 +831,31 @@
769 : int writer_error[IO_WRITER_ERROR_MAX];
770 :
771 : /* go to the next block */
- 772 115817 : blockcur = io_read_next(&io, &buffer);
- 773 115817 : if (blockcur >= blockmax)
+ 772 115754 : blockcur = io_read_next(&io, &buffer);
+ 773 115754 : if (blockcur >= blockmax)
774 88 : break;
775 :
776 : /* until now is scheduling */
- 777 115729 : state_usage_sched(state);
+ 777 115666 : state_usage_sched(state);
778 :
779 : /* one more block processed for autosave */
- 780 115729 : ++autosavedone;
- 781 115729 : --autosavemissing;
+ 780 115666 : ++autosavedone;
+ 781 115666 : --autosavemissing;
782 :
783 : /* by default process the block, and skip it if something goes wrong */
- 784 115729 : error_on_this_block = 0;
- 785 115729 : silent_error_on_this_block = 0;
- 786 115729 : io_error_on_this_block = 0;
- 787 115729 : fixed_error_on_this_block = 0;
+ 784 115666 : error_on_this_block = 0;
+ 785 115666 : silent_error_on_this_block = 0;
+ 786 115666 : io_error_on_this_block = 0;
+ 787 115666 : fixed_error_on_this_block = 0;
788 :
789 : /* keep track of the number of failed blocks */
- 790 115729 : failed_count = 0;
+ 790 115666 : failed_count = 0;
791 :
792 : /* get block specific info */
- 793 115729 : info = info_get(&state->infoarr, blockcur);
+ 793 115666 : info = info_get(&state->infoarr, blockcur);
794 :
795 : /* if we have to use the old hash */
- 796 115729 : rehash = info_get_rehash(info);
+ 796 115666 : rehash = info_get_rehash(info);
797 :
798 : /* if the parity requires to be updated */
799 : /* It could happens that all the blocks are EMPTY/BLK and CHG but with the hash */
@@ -864,18 +864,18 @@
802 : /* Note that CHG/DELETED blocks already present in the content file loaded */
803 : /* have the hash cleared (::clear_past_hash flag), and then they won't never match the hash. */
804 : /* We are treating only CHG blocks created at runtime. */
- 805 115729 : parity_needs_to_be_updated = state->opt.force_full || state->opt.force_parity_update;
+ 805 115666 : parity_needs_to_be_updated = state->opt.force_full || state->opt.force_parity_update;
806 :
807 : /* if the parity is going to be updated */
- 808 115729 : parity_going_to_be_updated = 0;
+ 808 115666 : parity_going_to_be_updated = 0;
809 :
810 : /* if the block is marked as bad, we force the parity update */
811 : /* because the bad block may be the result of a wrong parity */
- 812 115729 : if (info_get_bad(info))
+ 812 115666 : if (info_get_bad(info))
813 0 : parity_needs_to_be_updated = 1;
814 :
815 : /* for each disk, process the block */
- 816 810103 : for (j = 0; j < diskmax; ++j) {
+ 816 809662 : for (j = 0; j < diskmax; ++j) {
817 : struct snapraid_task* task;
818 : int read_size;
819 : unsigned char hash[HASH_MAX];
@@ -887,47 +887,47 @@
825 : unsigned diskcur;
826 :
827 : /* until now is misc */
- 828 694374 : state_usage_misc(state);
+ 828 693996 : state_usage_misc(state);
829 :
- 830 694374 : task = io_data_read(&io, &diskcur, waiting_map, &waiting_mac);
+ 830 693996 : task = io_data_read(&io, &diskcur, waiting_map, &waiting_mac);
831 :
832 : /* until now is disk */
- 833 694374 : state_usage_disk(state, handle, waiting_map, waiting_mac);
+ 833 693996 : state_usage_disk(state, handle, waiting_map, waiting_mac);
834 :
835 : /* get the results */
- 836 694374 : disk = task->disk;
- 837 694374 : block = task->block;
- 838 694374 : file = task->file;
- 839 694374 : file_pos = task->file_pos;
- 840 694374 : read_size = task->read_size;
+ 836 693996 : disk = task->disk;
+ 837 693996 : block = task->block;
+ 838 693996 : file = task->file;
+ 839 693996 : file_pos = task->file_pos;
+ 840 693996 : read_size = task->read_size;
841 :
842 : /* by default no rehash in case of "continue" */
- 843 694374 : rehandle[diskcur].block = 0;
+ 843 693996 : rehandle[diskcur].block = 0;
844 :
845 : /* if the disk position is not used */
- 846 694374 : if (!disk)
- 847 108581 : continue;
+ 846 693996 : if (!disk)
+ 847 108590 : continue;
848 :
- 849 694374 : state_usage_file(state, disk, file);
+ 849 693996 : state_usage_file(state, disk, file);
850 :
851 : /* get the state of the block */
- 852 694374 : block_state = block_state_get(block);
+ 852 693996 : block_state = block_state_get(block);
853 :
854 : /* if the block has invalid parity, */
855 : /* we have to take care of it in case of recover */
- 856 694374 : if (block_has_invalid_parity(block)) {
+ 856 693996 : if (block_has_invalid_parity(block)) {
857 : /* store it in the failed set, because */
858 : /* the parity may be still computed with the previous content */
- 859 181710 : failed[failed_count].index = diskcur;
- 860 181710 : failed[failed_count].size = state->block_size;
- 861 181710 : failed[failed_count].block = block;
- 862 181710 : ++failed_count;
+ 859 181655 : failed[failed_count].index = diskcur;
+ 860 181655 : failed[failed_count].size = state->block_size;
+ 861 181655 : failed[failed_count].block = block;
+ 862 181655 : ++failed_count;
863 :
864 : /* if the block has invalid parity, we have to update the parity */
865 : /* to include this block change */
866 : /* This also apply to CHG blocks, but we are going to handle */
867 : /* later this case to do the updates only if really needed */
- 868 181710 : if (block_state != BLOCK_STATE_CHG)
+ 868 181655 : if (block_state != BLOCK_STATE_CHG)
869 89419 : parity_needs_to_be_updated = 1;
870 :
871 : /* note that DELETE blocks are skipped in the next check */
@@ -938,28 +938,28 @@
876 : }
877 :
878 : /* if the block is not used */
- 879 694374 : if (!block_has_file(block))
- 880 107711 : continue;
+ 879 693996 : if (!block_has_file(block))
+ 880 107719 : continue;
881 :
882 : /* handle error conditions */
- 883 586663 : if (task->state == TASK_STATE_IOERROR) {
+ 883 586277 : if (task->state == TASK_STATE_IOERROR) {
884 : /* LCOV_EXCL_START */
885 : ++io_error;
886 : goto bail;
887 : /* LCOV_EXCL_STOP */
888 : }
- 889 586663 : if (task->state == TASK_STATE_ERROR) {
+ 889 586277 : if (task->state == TASK_STATE_ERROR) {
890 : /* LCOV_EXCL_START */
891 : ++soft_error;
892 : goto bail;
893 : /* LCOV_EXCL_STOP */
894 : }
- 895 586663 : if (task->state == TASK_STATE_ERROR_CONTINUE) {
+ 895 586277 : if (task->state == TASK_STATE_ERROR_CONTINUE) {
896 18 : ++soft_error;
897 18 : error_on_this_block = 1;
898 18 : continue;
899 : }
- 900 586645 : if (task->state == TASK_STATE_IOERROR_CONTINUE) {
+ 900 586259 : if (task->state == TASK_STATE_IOERROR_CONTINUE) {
901 0 : ++io_error;
902 0 : if (io_error >= state->opt.io_error_limit) {
903 : /* LCOV_EXCL_START */
@@ -973,34 +973,34 @@
911 0 : io_error_on_this_block = 1;
912 0 : continue;
913 : }
- 914 586645 : if (task->state != TASK_STATE_DONE) {
+ 914 586259 : if (task->state != TASK_STATE_DONE) {
915 : /* LCOV_EXCL_START */
916 : log_fatal(EINTERNAL, "Internal inconsistency in task state\n");
917 : os_abort();
918 : /* LCOV_EXCL_STOP */
919 : }
920 :
- 921 586645 : countsize += read_size;
+ 921 586259 : countsize += read_size;
922 :
923 : /* now compute the hash */
- 924 586645 : if (rehash) {
+ 924 586259 : if (rehash) {
925 27243 : memhash(state->prevhash, state->prevhashseed, hash, buffer[diskcur], read_size);
926 :
927 : /* compute the new hash, and store it */
928 27243 : rehandle[diskcur].block = block;
929 27243 : memhash(state->hash, state->hashseed, rehandle[diskcur].hash, buffer[diskcur], read_size);
930 : } else {
- 931 559402 : memhash(state->hash, state->hashseed, hash, buffer[diskcur], read_size);
+ 931 559016 : memhash(state->hash, state->hashseed, hash, buffer[diskcur], read_size);
932 : }
933 :
934 : /* until now is hash */
- 935 586645 : state_usage_hash(state);
+ 935 586259 : state_usage_hash(state);
936 :
- 937 586645 : if (block_has_updated_hash(block)) {
+ 937 586259 : if (block_has_updated_hash(block)) {
938 : /* compare the hash */
- 939 494372 : if (memcmp(hash, block->hash, BLOCK_HASH_SIZE) != 0) {
+ 939 494041 : if (memcmp(hash, block->hash, BLOCK_HASH_SIZE) != 0) {
940 : /* if the file has invalid parity, it's a REP changed during the sync */
- 941 852 : if (block_has_invalid_parity(block)) {
+ 941 853 : if (block_has_invalid_parity(block)) {
942 1 : log_tag("error:%u:%s:%s: Unexpected data change\n", blockcur, disk->name, esc_tag(file->sub, esc_buffer));
943 1 : log_error(ESOFT, "Data change at file '%s' at position '%u'\n", task->path, file_pos);
944 1 : log_error(ESOFT, "WARNING! Unexpected data modification of a file without parity!\n");
@@ -1020,39 +1020,39 @@
958 : /* this isn't a serious error, so we skip this block, and continue with others */
959 1 : error_on_this_block = 1;
960 1 : continue;
- 961 851 : } else { /* otherwise it's a BLK with silent error */
- 962 851 : unsigned diff = memdiff(hash, block->hash, BLOCK_HASH_SIZE);
- 963 851 : log_tag("error_data:%u:%s:%s: Data error at position %u, diff hash bits %u/%u\n", blockcur, disk->name, esc_tag(file->sub, esc_buffer), file_pos, diff, BLOCK_HASH_SIZE * 8);
- 964 851 : log_error(EDATA, "Data error in file '%s' at position '%u', diff hash bits %u/%u\n", task->path, file_pos, diff, BLOCK_HASH_SIZE * 8);
+ 961 852 : } else { /* otherwise it's a BLK with silent error */
+ 962 852 : unsigned diff = memdiff(hash, block->hash, BLOCK_HASH_SIZE);
+ 963 852 : log_tag("error_data:%u:%s:%s: Data error at position %u, diff hash bits %u/%u\n", blockcur, disk->name, esc_tag(file->sub, esc_buffer), file_pos, diff, BLOCK_HASH_SIZE * 8);
+ 964 852 : log_error(EDATA, "Data error in file '%s' at position '%u', diff hash bits %u/%u\n", task->path, file_pos, diff, BLOCK_HASH_SIZE * 8);
965 :
966 : /* save the failed block for the fix */
- 967 851 : failed[failed_count].index = diskcur;
- 968 851 : failed[failed_count].size = read_size;
- 969 851 : failed[failed_count].block = block;
- 970 851 : ++failed_count;
+ 967 852 : failed[failed_count].index = diskcur;
+ 968 852 : failed[failed_count].size = read_size;
+ 969 852 : failed[failed_count].block = block;
+ 970 852 : ++failed_count;
971 :
972 : /* silent errors are very rare, and are not a signal that a disk */
973 : /* is going to fail. So, we just continue marking the block as bad */
974 : /* just like in scrub */
- 975 851 : ++silent_error;
- 976 851 : silent_error_on_this_block = 1;
- 977 851 : continue;
+ 975 852 : ++silent_error;
+ 976 852 : silent_error_on_this_block = 1;
+ 977 852 : continue;
978 : }
979 : }
980 : } else {
981 : /* if until now the parity doesn't need to be updated */
- 982 92273 : if (!parity_needs_to_be_updated) {
+ 982 92218 : if (!parity_needs_to_be_updated) {
983 : /* for sure it's a CHG block, because EMPTY are processed before with "continue" */
984 : /* and BLK and REP have "block_has_updated_hash()" as 1, and all the others */
985 : /* have "parity_needs_to_be_updated" already at 1 */
- 986 34999 : assert(block_state_get(block) == BLOCK_STATE_CHG);
+ 986 34944 : assert(block_state_get(block) == BLOCK_STATE_CHG);
987 :
988 : /* if the hash represents the data unequivocally */
- 989 34999 : if (hash_is_unique(block->hash)) {
+ 989 34944 : if (hash_is_unique(block->hash)) {
990 : /* check if the hash is changed */
- 991 6277 : if (memcmp(hash, block->hash, BLOCK_HASH_SIZE) != 0) {
+ 991 6222 : if (memcmp(hash, block->hash, BLOCK_HASH_SIZE) != 0) {
992 : /* the block is different, and we must update parity */
- 993 5157 : parity_needs_to_be_updated = 1;
+ 993 5105 : parity_needs_to_be_updated = 1;
994 : }
995 : } else {
996 : /* if the hash is already invalid, we update parity */
@@ -1062,7 +1062,7 @@
1000 :
1001 : /* copy the hash in the block, but doesn't mark the block as hashed */
1002 : /* this allow in case of skipped block to do not save the failed computation */
- 1003 92273 : memcpy(block->hash, hash, BLOCK_HASH_SIZE);
+ 1003 92218 : memcpy(block->hash, hash, BLOCK_HASH_SIZE);
1004 :
1005 : /* note that in case of rehash, this is the wrong hash, */
1006 : /* but it will be overwritten later */
@@ -1072,57 +1072,57 @@
1010 : /* if we have only silent errors we can try to fix them on-the-fly */
1011 : /* note the fix is not written to disk, but used only to */
1012 : /* compute the new parity */
- 1013 115729 : if (!error_on_this_block && !io_error_on_this_block && silent_error_on_this_block) {
+ 1013 115666 : if (!error_on_this_block && !io_error_on_this_block && silent_error_on_this_block) {
1014 : unsigned failed_mac;
- 1015 851 : int something_to_recover = 0;
+ 1015 852 : int something_to_recover = 0;
1016 :
1017 : /* sort the failed vector */
1018 : /* because with threads it may be in any order */
1019 : /* but RAID requires the indexes to be sorted */
- 1020 851 : qsort(failed, failed_count, sizeof(failed[0]), failed_compare_by_index);
+ 1020 852 : qsort(failed, failed_count, sizeof(failed[0]), failed_compare_by_index);
1021 :
1022 : /* setup the blocks to recover */
- 1023 851 : failed_mac = 0;
- 1024 2553 : for (j = 0; j < failed_count; ++j) {
- 1025 1702 : unsigned char* block_buffer = buffer[failed[j].index];
- 1026 1702 : unsigned char* block_copy = copy[failed[j].index];
- 1027 1702 : unsigned block_state = block_state_get(failed[j].block);
+ 1023 852 : failed_mac = 0;
+ 1024 2556 : for (j = 0; j < failed_count; ++j) {
+ 1025 1704 : unsigned char* block_buffer = buffer[failed[j].index];
+ 1026 1704 : unsigned char* block_copy = copy[failed[j].index];
+ 1027 1704 : unsigned block_state = block_state_get(failed[j].block);
1028 :
1029 : /* we try to recover only if at least one BLK is present */
- 1030 1702 : if (block_state == BLOCK_STATE_BLK)
- 1031 851 : something_to_recover = 1;
+ 1030 1704 : if (block_state == BLOCK_STATE_BLK)
+ 1031 852 : something_to_recover = 1;
1032 :
1033 : /* save a copy of the content just read */
1034 : /* that it's going to be overwritten by the recovering function */
- 1035 1702 : memcpy(block_copy, block_buffer, state->block_size);
+ 1035 1704 : memcpy(block_copy, block_buffer, state->block_size);
1036 :
- 1037 1702 : if (block_state == BLOCK_STATE_CHG
- 1038 851 : && hash_is_zero(failed[j].block->hash)
+ 1037 1704 : if (block_state == BLOCK_STATE_CHG
+ 1038 852 : && hash_is_zero(failed[j].block->hash)
1039 : ) {
1040 : /* if the block was filled with 0, restore this state */
1041 : /* and avoid to recover it */
1042 0 : memset(block_buffer, 0, state->block_size);
1043 : } else {
1044 : /* if we have too many failures, we cannot recover */
- 1045 1702 : if (failed_mac >= state->level)
+ 1045 1704 : if (failed_mac >= state->level)
1046 0 : break;
1047 :
1048 : /* otherwise it has to be recovered */
- 1049 1702 : failed_map[failed_mac++] = failed[j].index;
+ 1049 1704 : failed_map[failed_mac++] = failed[j].index;
1050 : }
1051 : }
1052 :
1053 : /* if we have something to recover and enough parity */
- 1054 851 : if (something_to_recover && j == failed_count) {
+ 1054 852 : if (something_to_recover && j == failed_count) {
1055 : /* until now is misc */
- 1056 851 : state_usage_misc(state);
+ 1056 852 : state_usage_misc(state);
1057 :
1058 : /* read the parity */
1059 : /* we are sure that parity exists because */
1060 : /* we have at least one BLK block */
- 1061 5957 : for (l = 0; l < state->level; ++l) {
- 1062 5106 : ret = parity_read(&parity_handle[l], blockcur, buffer[diskmax + l], state->block_size, log_error);
- 1063 5106 : if (ret == -1) {
+ 1061 5964 : for (l = 0; l < state->level; ++l) {
+ 1062 5112 : ret = parity_read(&parity_handle[l], blockcur, buffer[diskmax + l], state->block_size, log_error);
+ 1063 5112 : if (ret == -1) {
1064 : /* LCOV_EXCL_START */
1065 : log_tag("parity_%s:%u:%s: Read error. %s.\n", es(errno), blockcur, lev_config_name(l), strerror(errno));
1066 : if (is_hw(errno)) {
@@ -1147,103 +1147,103 @@
1085 : }
1086 :
1087 : /* until now is parity */
- 1088 5106 : state_usage_parity(state, &l, 1);
+ 1088 5112 : state_usage_parity(state, &l, 1);
1089 : }
1090 :
1091 : /* if no error in parity read */
- 1092 851 : if (!io_error_on_this_block) {
+ 1092 852 : if (!io_error_on_this_block) {
1093 : /* try to fix the data */
1094 : /* note that this is a simple fix algorithm, that doesn't take into */
1095 : /* account the case of a wrong parity */
1096 : /* only 'fix' supports the most advanced fixing */
- 1097 851 : raid_rec(failed_mac, failed_map, diskmax, state->level, state->block_size, buffer);
+ 1097 852 : raid_rec(failed_mac, failed_map, diskmax, state->level, state->block_size, buffer);
1098 :
1099 : /* until now is raid */
- 1100 851 : state_usage_raid(state);
+ 1100 852 : state_usage_raid(state);
1101 :
1102 : /* check the result and prepare the data */
- 1103 2553 : for (j = 0; j < failed_count; ++j) {
+ 1103 2556 : for (j = 0; j < failed_count; ++j) {
1104 : unsigned char hash[HASH_MAX];
- 1105 1702 : unsigned char* block_buffer = buffer[failed[j].index];
- 1106 1702 : unsigned char* block_copy = copy[failed[j].index];
- 1107 1702 : unsigned block_state = block_state_get(failed[j].block);
+ 1105 1704 : unsigned char* block_buffer = buffer[failed[j].index];
+ 1106 1704 : unsigned char* block_copy = copy[failed[j].index];
+ 1107 1704 : unsigned block_state = block_state_get(failed[j].block);
1108 :
- 1109 1702 : if (block_state == BLOCK_STATE_BLK) {
- 1110 851 : unsigned size = failed[j].size;
+ 1109 1704 : if (block_state == BLOCK_STATE_BLK) {
+ 1110 852 : unsigned size = failed[j].size;
1111 :
1112 : /* compute the hash of the recovered block */
- 1113 851 : if (rehash) {
+ 1113 852 : if (rehash) {
1114 0 : memhash(state->prevhash, state->prevhashseed, hash, block_buffer, size);
1115 : } else {
- 1116 851 : memhash(state->hash, state->hashseed, hash, block_buffer, size);
+ 1116 852 : memhash(state->hash, state->hashseed, hash, block_buffer, size);
1117 : }
1118 :
1119 : /* until now is hash */
- 1120 851 : state_usage_hash(state);
+ 1120 852 : state_usage_hash(state);
1121 :
1122 : /* if the hash doesn't match */
- 1123 851 : if (memcmp(hash, failed[j].block->hash, BLOCK_HASH_SIZE) != 0) {
+ 1123 852 : if (memcmp(hash, failed[j].block->hash, BLOCK_HASH_SIZE) != 0) {
1124 : /* we have not recovered */
1125 0 : break;
1126 : }
1127 :
1128 : /* pad with 0 if needed */
- 1129 851 : if (size < state->block_size)
- 1130 348 : memset(block_buffer + size, 0, state->block_size - size);
+ 1129 852 : if (size < state->block_size)
+ 1130 335 : memset(block_buffer + size, 0, state->block_size - size);
1131 : } else {
1132 : /* otherwise restore the content */
1133 : /* because we are not interested in the old state */
1134 : /* that it's recovered for CHG, REP and DELETED blocks */
- 1135 851 : memcpy(block_buffer, block_copy, state->block_size);
+ 1135 852 : memcpy(block_buffer, block_copy, state->block_size);
1136 : }
1137 : }
1138 :
1139 : /* if all is processed, we have fixed it */
- 1140 851 : if (j == failed_count)
- 1141 851 : fixed_error_on_this_block = 1;
+ 1140 852 : if (j == failed_count)
+ 1141 852 : fixed_error_on_this_block = 1;
1142 : }
1143 : }
1144 : }
1145 :
1146 : /* if we have read all the data required and it's correct, proceed with the parity */
- 1147 115729 : if (!error_on_this_block && !io_error_on_this_block
- 1148 115710 : && (!silent_error_on_this_block || fixed_error_on_this_block)
+ 1147 115666 : if (!error_on_this_block && !io_error_on_this_block
+ 1148 115647 : && (!silent_error_on_this_block || fixed_error_on_this_block)
1149 : ) {
1150 : /* update the parity only if really needed */
- 1151 115710 : if (parity_needs_to_be_updated) {
+ 1151 115647 : if (parity_needs_to_be_updated) {
1152 : /* compute the parity */
- 1153 114798 : raid_gen(diskmax, state->level, state->block_size, buffer);
+ 1153 114746 : raid_gen(diskmax, state->level, state->block_size, buffer);
1154 :
1155 : /* until now is raid */
- 1156 114798 : state_usage_raid(state);
+ 1156 114746 : state_usage_raid(state);
1157 :
1158 : /* mark that the parity is going to be written */
- 1159 114798 : parity_going_to_be_updated = 1;
+ 1159 114746 : parity_going_to_be_updated = 1;
1160 : }
1161 :
1162 : /* for each disk, mark the blocks as processed */
- 1163 809970 : for (j = 0; j < diskmax; ++j) {
+ 1163 809529 : for (j = 0; j < diskmax; ++j) {
1164 : struct snapraid_block* block;
1165 :
- 1166 694260 : if (!handle[j].disk)
+ 1166 693882 : if (!handle[j].disk)
1167 0 : continue;
1168 :
- 1169 694260 : block = fs_par2block_find(handle[j].disk, blockcur);
+ 1169 693882 : block = fs_par2block_find(handle[j].disk, blockcur);
1170 :
- 1171 694260 : if (block == BLOCK_NULL) {
+ 1171 693882 : if (block == BLOCK_NULL) {
1172 : /* nothing to do */
- 1173 96586 : continue;
+ 1173 96594 : continue;
1174 : }
1175 :
1176 : /* if it's a deleted block */
- 1177 597674 : if (block_state_get(block) == BLOCK_STATE_DELETED) {
+ 1177 597288 : if (block_state_get(block) == BLOCK_STATE_DELETED) {
1178 : /* the parity is now updated without this block, so it's now empty */
1179 11123 : fs_deallocate(handle[j].disk, blockcur);
1180 11123 : continue;
1181 : }
1182 :
1183 : /* now all the blocks have the hash and the parity computed */
- 1184 586551 : block_state_set(block, BLOCK_STATE_BLK);
+ 1184 586165 : block_state_set(block, BLOCK_STATE_BLK);
1185 : }
1186 :
1187 : /* we update the info block only if we really have updated the parity */
@@ -1251,11 +1251,11 @@
1189 : /* wrote the parity at this time */
1190 : /* we also update the info block only if no silent error was found */
1191 : /* because has no sense to refresh the time for data that we know bad */
- 1192 115710 : if (parity_needs_to_be_updated
- 1193 114798 : && !silent_error_on_this_block
+ 1192 115647 : if (parity_needs_to_be_updated
+ 1193 114746 : && !silent_error_on_this_block
1194 : ) {
1195 : /* if rehash is needed */
- 1196 113947 : if (rehash) {
+ 1196 113895 : if (rehash) {
1197 : /* store all the new hash already computed */
1198 32249 : for (j = 0; j < diskmax; ++j) {
1199 27642 : if (rehandle[j].block)
@@ -1265,43 +1265,43 @@
1203 :
1204 : /* update the time info of the block */
1205 : /* we are also clearing any previous bad and rehash flag */
- 1206 113947 : info_set(&state->infoarr, blockcur, info_make(now, 0, 0, 1));
+ 1206 113895 : info_set(&state->infoarr, blockcur, info_make(now, 0, 0, 1));
1207 : }
1208 : }
1209 :
1210 : /* if a silent (even if corrected) or input/output error was found */
1211 : /* mark the block as bad to have check/fix to handle it */
1212 : /* because our correction is in memory only and not yet written */
- 1213 115729 : if (silent_error_on_this_block || io_error_on_this_block) {
+ 1213 115666 : if (silent_error_on_this_block || io_error_on_this_block) {
1214 : /* set the error status keeping the other info */
- 1215 851 : info_set(&state->infoarr, blockcur, info_set_bad(info));
+ 1215 852 : info_set(&state->infoarr, blockcur, info_set_bad(info));
1216 : }
1217 :
1218 : /* finally schedule parity write */
1219 : /* Note that the calls to io_parity_write() are mandatory */
1220 : /* even if the parity doesn't need to be updated */
1221 : /* This because we want to keep track of the time usage */
- 1222 115729 : state_usage_misc(state);
+ 1222 115666 : state_usage_misc(state);
1223 :
1224 : /* write start */
- 1225 115729 : io_write_preset(&io, blockcur, !parity_going_to_be_updated);
+ 1225 115666 : io_write_preset(&io, blockcur, !parity_going_to_be_updated);
1226 :
1227 : /* write the parity */
- 1228 679998 : for (l = 0; l < state->level; ++l) {
+ 1228 679557 : for (l = 0; l < state->level; ++l) {
1229 : unsigned levcur;
1230 :
- 1231 564269 : io_parity_write(&io, &levcur, waiting_map, &waiting_mac);
+ 1231 563891 : io_parity_write(&io, &levcur, waiting_map, &waiting_mac);
1232 :
1233 : /* until now is parity */
- 1234 564269 : state_usage_parity(state, waiting_map, waiting_mac);
+ 1234 563891 : state_usage_parity(state, waiting_map, waiting_mac);
1235 : }
1236 :
1237 : /* write finished */
- 1238 115729 : io_write_next(&io, blockcur, !parity_going_to_be_updated, writer_error);
+ 1238 115666 : io_write_next(&io, blockcur, !parity_going_to_be_updated, writer_error);
1239 :
1240 : /* handle errors reported */
- 1241 578645 : for (j = 0; j < IO_WRITER_ERROR_MAX; ++j) {
- 1242 462916 : if (writer_error[j]) {
+ 1241 578330 : for (j = 0; j < IO_WRITER_ERROR_MAX; ++j) {
+ 1242 462664 : if (writer_error[j]) {
1243 0 : switch (j + IO_WRITER_ERROR_BASE) {
1244 0 : case TASK_STATE_IOERROR_CONTINUE :
1245 0 : ++io_error;
@@ -1331,20 +1331,20 @@
1269 : }
1270 :
1271 : /* mark the state as needing write */
- 1272 115729 : state->need_write = 1;
+ 1272 115666 : state->need_write = 1;
1273 :
1274 : /* count the number of processed block */
- 1275 115729 : ++countpos;
+ 1275 115666 : ++countpos;
1276 :
1277 : /* progress */
- 1278 115729 : if (state_progress(state, &io, blockcur, countpos, countmax, countsize)) {
+ 1278 115666 : if (state_progress(state, &io, blockcur, countpos, countmax, countsize)) {
1279 : /* LCOV_EXCL_START */
1280 : break;
1281 : /* LCOV_EXCL_STOP */
1282 : }
1283 :
1284 : /* thermal control */
- 1285 115729 : if (state_thermal_alarm(state)) {
+ 1285 115666 : if (state_thermal_alarm(state)) {
1286 : /* until now is misc */
1287 0 : state_usage_misc(state);
1288 :
@@ -1369,11 +1369,11 @@
1307 : }
1308 :
1309 : /* autosave */
- 1310 115729 : if ((state->autosave != 0
+ 1310 115666 : if ((state->autosave != 0
1311 26021 : && autosavedone >= autosavelimit /* if we have reached the limit */
1312 0 : && autosavemissing >= autosavelimit) /* if we have at least a full step to do */
1313 : /* or if we have a forced autosave at the specified block */
- 1314 115729 : || (state->opt.force_autosave_at != 0 && state->opt.force_autosave_at == blockcur)
+ 1314 115666 : || (state->opt.force_autosave_at != 0 && state->opt.force_autosave_at == blockcur)
1315 : ) {
1316 1 : autosavedone = 0; /* restart the counter */
1317 :
@@ -1422,7 +1422,7 @@
1360 : /* save the new state if required */
1361 88 : if (!state->opt.kill_after_sync) {
1362 78 : if ((state->need_write || state->opt.force_content_write))
- 1363 62 : state_write(state);
+ 1363 61 : state_write(state);
1364 : } else {
1365 10 : log_fatal(EUSER, "WARNING! Skipped writing state due to --test-kill-after-sync option.\n");
1366 : }
@@ -1437,7 +1437,7 @@
1375 : } else {
1376 : /* print the result only if processed something */
1377 76 : if (countpos != 0)
- 1378 58 : msg_status("Everything OK\n");
+ 1378 57 : msg_status("Everything OK\n");
1379 : }
1380 :
1381 88 : if (soft_error)
diff --git a/cov/cmdline/thermal.c.func-sort-c.html b/cov/cmdline/thermal.c.func-sort-c.html
index 73b12a34..d5c8aa27 100644
--- a/cov/cmdline/thermal.c.func-sort-c.html
+++ b/cov/cmdline/thermal.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -81,11 +81,11 @@
| state_thermal |
- 2614 |
+ 2613 |
| state_thermal_alarm |
- 1062627 |
+ 1062564 |
diff --git a/cov/cmdline/thermal.c.func.html b/cov/cmdline/thermal.c.func.html
index 28995b42..694ec2bb 100644
--- a/cov/cmdline/thermal.c.func.html
+++ b/cov/cmdline/thermal.c.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -65,11 +65,11 @@
| state_thermal |
- 2614 |
+ 2613 |
| state_thermal_alarm |
- 1062627 |
+ 1062564 |
| state_thermal_begin |
diff --git a/cov/cmdline/thermal.c.gcov.html b/cov/cmdline/thermal.c.gcov.html
index 845bcca9..f53c4f1d 100644
--- a/cov/cmdline/thermal.c.gcov.html
+++ b/cov/cmdline/thermal.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -184,7 +184,7 @@
122 30 : return model;
123 : }
124 :
- 125 2614 : void state_thermal(struct snapraid_state* state, time_t now)
+ 125 2613 : void state_thermal(struct snapraid_state* state, time_t now)
126 : {
127 : tommy_node* i;
128 : unsigned j;
@@ -192,8 +192,8 @@
130 : tommy_list low;
131 : int ret;
132 :
- 133 2614 : if (state->thermal_temperature_limit == 0)
- 134 198 : return;
+ 133 2613 : if (state->thermal_temperature_limit == 0)
+ 134 197 : return;
135 :
136 2416 : tommy_list_init(&high);
137 2416 : tommy_list_init(&low);
@@ -362,11 +362,11 @@
300 2416 : tommy_list_foreach(&low, free);
301 : }
302 :
- 303 1062627 : int state_thermal_alarm(struct snapraid_state* state)
+ 303 1062564 : int state_thermal_alarm(struct snapraid_state* state)
304 : {
305 : /* if no limit, there is no thermal support */
- 306 1062627 : if (state->thermal_temperature_limit == 0)
- 307 1060211 : return 0;
+ 306 1062564 : if (state->thermal_temperature_limit == 0)
+ 307 1060148 : return 0;
308 :
309 2416 : if (state->thermal_highest_temperature <= state->thermal_temperature_limit)
310 2416 : return 0;
diff --git a/cov/cmdline/touch.c.func-sort-c.html b/cov/cmdline/touch.c.func-sort-c.html
index dbfc39f1..c58b1e91 100644
--- a/cov/cmdline/touch.c.func-sort-c.html
+++ b/cov/cmdline/touch.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/cmdline/touch.c.func.html b/cov/cmdline/touch.c.func.html
index fb7a9feb..26a7b3be 100644
--- a/cov/cmdline/touch.c.func.html
+++ b/cov/cmdline/touch.c.func.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/cmdline/touch.c.gcov.html b/cov/cmdline/touch.c.gcov.html
index 1a7412ad..b724a670 100644
--- a/cov/cmdline/touch.c.gcov.html
+++ b/cov/cmdline/touch.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/cmdline/unix.c.func-sort-c.html b/cov/cmdline/unix.c.func-sort-c.html
index 3b92bb56..2d0c0a14 100644
--- a/cov/cmdline/unix.c.func-sort-c.html
+++ b/cov/cmdline/unix.c.func-sort-c.html
@@ -31,18 +31,18 @@
|
-
-
-
+
+
+
-
+
|
-
+
-
+
 |
@@ -60,27 +60,15 @@
Hit count  |
- | devattr |
+ devdownifup |
0 |
- | devdownifup |
+ devsmart |
0 |
- | devprobe |
- 0 |
-
-
- | devscan |
- 0 |
-
-
- | devsmart |
- 0 |
-
-
- | devuuid_blkid |
+ devuuid_blkid |
0 |
@@ -92,140 +80,152 @@
| 0 |
- | thread_probe |
+ thread_smart |
0 |
- | thread_smart |
+ thread_spindownifup |
0 |
- | thread_spindownifup |
- 0 |
-
-
- | ambient_temperature |
+ ambient_temperature |
1 |
- | os_clear |
+ devscan |
1 |
- | device_thread |
- 2 |
+ os_clear |
+ 1 |
- | devquery |
+ device_thread |
3 |
- | devdereference |
+ devdereference |
4 |
- | devresolve_proc |
+ devquery |
4 |
- | devdown |
+ devresolve_proc |
+ 4 |
+
+
+ | devdown |
5 |
- | find_smartctl |
+ thread_spindown |
5 |
- | thread_spindown |
- 5 |
-
-
- | direct_size |
+ direct_size |
7 |
- | sysattr |
- 12 |
+ devattr |
+ 14 |
- | devup |
+ devprobe |
+ 14 |
+
+
+ | thread_probe |
+ 14 |
+
+
+ | find_smartctl |
+ 19 |
+
+
+ | devup |
30 |
- | thread_spinup |
+ thread_spinup |
30 |
- | devstat |
- 65 |
+ sysattr |
+ 62 |
- | devread |
- 130 |
+ devstat |
+ 77 |
- | devtree |
- 130 |
+ devtree |
+ 154 |
- | devresolve |
- 165 |
+ devread |
+ 168 |
- | devresolve_sys |
- 165 |
+ devresolve |
+ 205 |
- | tagread |
- 165 |
+ devresolve_sys |
+ 205 |
+
+
+ | tagread |
+ 205 |
+
+
+ | os_done |
+ 273 |
+
+
+ | os_init |
+ 284 |
+
+
+ | randomize |
+ 295 |
| sysread |
- 242 |
+ 358 |
- | os_done |
- 272 |
+ tick_ms |
+ 3567 |
- | os_init |
- 283 |
-
-
- | randomize |
- 294 |
-
-
- | tick_ms |
- 3581 |
-
-
- | devuuid_label |
+ devuuid_label |
5759 |
- | fsinfo |
+ fsinfo |
6412 |
- | devuuid_dev |
- 10544 |
+ devuuid_dev |
+ 10556 |
- | devuuid |
- 10548 |
+ devuuid |
+ 10560 |
- | filephy |
+ filephy |
11432 |
| open_noatime |
- 1714013 |
+ 1713822 |
- | tick |
- 3817826 |
+ tick |
+ 3816139 |
diff --git a/cov/cmdline/unix.c.func.html b/cov/cmdline/unix.c.func.html
index da140618..bf6927b9 100644
--- a/cov/cmdline/unix.c.func.html
+++ b/cov/cmdline/unix.c.func.html
@@ -31,18 +31,18 @@
|
-
-
-
+
+
+
-
+
|
-
+
-
+
 |
@@ -60,91 +60,91 @@
Hit count  |
- | ambient_temperature |
+ ambient_temperature |
1 |
- | devattr |
- 0 |
+ devattr |
+ 14 |
- | devdereference |
+ devdereference |
4 |
- | devdown |
+ devdown |
5 |
- | devdownifup |
+ devdownifup |
0 |
- | device_thread |
- 2 |
-
-
- | devprobe |
- 0 |
-
-
- | devquery |
+ device_thread |
3 |
- | devread |
- 130 |
+ devprobe |
+ 14 |
- | devresolve |
- 165 |
-
-
- | devresolve_proc |
+ devquery |
4 |
- | devresolve_sys |
- 165 |
+ devread |
+ 168 |
- | devscan |
+ devresolve |
+ 205 |
+
+
+ | devresolve_proc |
+ 4 |
+
+
+ | devresolve_sys |
+ 205 |
+
+
+ | devscan |
+ 1 |
+
+
+ | devsmart |
0 |
- | devsmart |
- 0 |
+ devstat |
+ 77 |
- | devstat |
- 65 |
+ devtree |
+ 154 |
- | devtree |
- 130 |
-
-
- | devup |
+ devup |
30 |
- | devuuid |
- 10548 |
+ devuuid |
+ 10560 |
- | devuuid_blkid |
+ devuuid_blkid |
0 |
- | devuuid_dev |
- 10544 |
+ devuuid_dev |
+ 10556 |
- | devuuid_label |
+ devuuid_label |
5759 |
- | direct_size |
+ direct_size |
7 |
@@ -152,80 +152,80 @@
| 0 |
- | filephy |
+ filephy |
11432 |
| find_smartctl |
- 5 |
+ 19 |
- | fsinfo |
+ fsinfo |
6412 |
| open_noatime |
- 1714013 |
+ 1713822 |
- | os_clear |
+ os_clear |
1 |
- | os_done |
- 272 |
+ os_done |
+ 273 |
- | os_init |
- 283 |
+ os_init |
+ 284 |
- | randomize |
- 294 |
+ randomize |
+ 295 |
| stat_desc |
0 |
- | sysattr |
- 12 |
+ sysattr |
+ 62 |
| sysread |
- 242 |
+ 358 |
- | tagread |
- 165 |
+ tagread |
+ 205 |
- | thread_probe |
+ thread_probe |
+ 14 |
+
+
+ | thread_smart |
0 |
- | thread_smart |
- 0 |
-
-
- | thread_spindown |
+ thread_spindown |
5 |
- | thread_spindownifup |
+ thread_spindownifup |
0 |
- | thread_spinup |
+ thread_spinup |
30 |
- | tick |
- 3817826 |
+ tick |
+ 3816139 |
- | tick_ms |
- 3581 |
+ tick_ms |
+ 3567 |
diff --git a/cov/cmdline/unix.c.gcov.html b/cov/cmdline/unix.c.gcov.html
index 77993dca..374b6972 100644
--- a/cov/cmdline/unix.c.gcov.html
+++ b/cov/cmdline/unix.c.gcov.html
@@ -31,18 +31,18 @@
|
-
-
-
+
+
+
-
+
|
-
+
-
+
 |
@@ -90,15 +90,15 @@
28 : int exit_failure = 1;
29 : int exit_sync_needed = 2;
30 :
- 31 1714013 : int open_noatime(const char* file, int flags)
+ 31 1713822 : int open_noatime(const char* file, int flags)
32 : {
33 : #ifdef O_NOATIME
- 34 1714013 : int f = open(file, flags | O_NOATIME);
+ 34 1713822 : int f = open(file, flags | O_NOATIME);
35 :
36 : /* only root is allowed to use O_NOATIME, in case retry without it */
- 37 1714013 : if (f == -1 && errno == EPERM)
+ 37 1713822 : if (f == -1 && errno == EPERM)
38 0 : f = open(file, flags);
- 39 1714013 : return f;
+ 39 1713822 : return f;
40 : #else
41 : return open(file, flags);
42 : #endif
@@ -142,13 +142,13 @@
80 : 0
81 : };
82 :
- 83 5 : const char* find_smartctl(void)
+ 83 19 : const char* find_smartctl(void)
84 : {
85 : int i;
86 :
- 87 5 : for (i = 0; smartctl_paths[i]; ++i) {
- 88 5 : if (access(smartctl_paths[i], X_OK) == 0)
- 89 5 : return smartctl_paths[i];
+ 87 19 : for (i = 0; smartctl_paths[i]; ++i) {
+ 88 19 : if (access(smartctl_paths[i], X_OK) == 0)
+ 89 19 : return smartctl_paths[i];
90 : }
91 :
92 0 : return 0;
@@ -160,35 +160,35 @@
98 : * Return -1 on error, otherwise the size of data read
99 : */
100 : #if HAVE_LINUX_DEVICE
- 101 242 : static int sysread(const char* path, char* buf, size_t buf_size)
+ 101 358 : static int sysread(const char* path, char* buf, size_t buf_size)
102 : {
103 : int f;
104 : int ret;
105 : int len;
106 :
- 107 242 : f = open(path, O_RDONLY);
- 108 242 : if (f == -1) {
+ 107 358 : f = open(path, O_RDONLY);
+ 108 358 : if (f == -1) {
109 : /* LCOV_EXCL_START */
110 : return -1;
111 : /* LCOV_EXCL_STOP */
112 : }
113 :
- 114 242 : len = read(f, buf, buf_size);
- 115 242 : if (len < 0) {
+ 114 344 : len = read(f, buf, buf_size);
+ 115 344 : if (len < 0) {
116 : /* LCOV_EXCL_START */
117 : close(f);
118 : return -1;
119 : /* LCOV_EXCL_STOP */
120 : }
121 :
- 122 242 : ret = close(f);
- 123 242 : if (ret != 0) {
+ 122 344 : ret = close(f);
+ 123 344 : if (ret != 0) {
124 : /* LCOV_EXCL_START */
125 : return -1;
126 : /* LCOV_EXCL_STOP */
127 : }
128 :
- 129 242 : return len;
+ 129 344 : return len;
130 : }
131 : #endif
132 :
@@ -197,2408 +197,2402 @@
135 : * Trim spaces.
136 : * Always put an ending 0.
137 : * Do not report error on reading.
- 138 : *
- 139 : * Return 0 on error, otherwise a pointer to buf
- 140 : */
- 141 : #if HAVE_LINUX_DEVICE
- 142 12 : static char* sysattr(const char* path, char* buf, size_t buf_size)
- 143 : {
- 144 : int len;
- 145 :
- 146 12 : len = sysread(path, buf, buf_size);
- 147 12 : if (len < 0) {
- 148 : /* LCOV_EXCL_START */
- 149 : return 0;
- 150 : /* LCOV_EXCL_STOP */
- 151 : }
- 152 :
- 153 12 : if ((size_t)len + 1 > buf_size) {
- 154 : /* LCOV_EXCL_START */
- 155 : return 0;
- 156 : /* LCOV_EXCL_STOP */
- 157 : }
- 158 :
- 159 12 : buf[len] = 0;
- 160 :
- 161 12 : strtrim(buf);
- 162 :
- 163 12 : return buf;
- 164 : }
- 165 : #endif
- 166 :
- 167 : /**
- 168 : * Get the device file from the device number.
- 169 : *
- 170 : * It uses /proc/self/mountinfo.
- 171 : *
- 172 : * Null devices (major==0) are resolved to the device indicated in mountinfo.
- 173 : */
- 174 : #if HAVE_LINUX_DEVICE
- 175 4 : static int devresolve_proc(uint64_t device, char* path, size_t path_size)
- 176 : {
- 177 : FILE* f;
- 178 : char match[32];
- 179 :
- 180 : /* generate the matching string */
- 181 4 : snprintf(match, sizeof(match), "%u:%u", major(device), minor(device));
- 182 :
- 183 4 : f = fopen("/proc/self/mountinfo", "r");
- 184 4 : if (!f) {
- 185 0 : log_tag("resolve:proc:%u:%u: failed to open /proc/self/mountinfo\n", major(device), minor(device));
- 186 0 : return -1;
- 187 : }
- 188 :
- 189 : /*
- 190 : * mountinfo format
- 191 : * 0 - mount ID
- 192 : * 1 - parent ID
- 193 : * 2 - major:minor
- 194 : * 3 - root
- 195 : * 4 - mount point
- 196 : * 5 - options
- 197 : * 6 - "-" (separator)
- 198 : * 7 - fs
- 199 : * 8 - mount source - /dev/device
- 200 : */
- 201 :
- 202 192 : while (1) {
- 203 : char buf[256];
- 204 : char* first_map[8];
- 205 : unsigned first_mac;
- 206 : char* second_map[8];
- 207 : unsigned second_mac;
- 208 : char* s;
- 209 : struct stat st;
- 210 : char* separator;
- 211 : char* majorminor;
- 212 : char* mountpoint;
- 213 : char* fs;
- 214 : char* mountsource;
- 215 :
- 216 196 : s = fgets(buf, sizeof(buf), f);
- 217 196 : if (s == 0)
- 218 4 : break;
- 219 :
- 220 : /* find the separator position */
- 221 192 : separator = strstr(s, " - ");
- 222 192 : if (!separator)
- 223 0 : continue;
- 224 :
- 225 : /* skip the separator */
- 226 192 : *separator = 0;
- 227 192 : separator += 3;
- 228 :
- 229 : /* split the line */
- 230 192 : first_mac = strsplit(first_map, 8, s, " \t\r\n");
- 231 192 : second_mac = strsplit(second_map, 8, separator, " \t\r\n");
- 232 :
- 233 : /* if too short, it's the wrong line */
- 234 192 : if (first_mac < 5)
- 235 0 : continue;
- 236 192 : if (second_mac < 2)
- 237 0 : continue;
- 238 :
- 239 192 : majorminor = first_map[2];
- 240 192 : mountpoint = first_map[4];
- 241 192 : fs = second_map[0];
- 242 192 : mountsource = second_map[1];
- 243 :
- 244 : /* compare major:minor from mountinfo */
- 245 192 : if (strcmp(majorminor, match) == 0) {
- 246 : /*
- 247 : * Accept only /dev/... mountsource
- 248 : *
- 249 : * This excludes ZFS that uses a bare label for mountsource, like "tank".
- 250 : *
- 251 : * 410 408 0:193 / /XXX rw,relatime shared:217 - zfs tank/system/data/var/lib/docker/XXX rw,xattr,noacl
- 252 : *
- 253 : * Also excludes AUTOFS unmounted devices that point to a fake filesystem
- 254 : * used to remount them at the first use.
- 255 : *
- 256 : * 97 25 0:42 / /XXX rw,relatime shared:76 - autofs /etc/auto.seed rw,fd=6,pgrp=952,timeout=30,minproto=5,maxproto=5,indirect
- 257 : */
- 258 0 : if (strncmp(mountsource, "/dev/", 5) != 0) {
- 259 0 : log_tag("resolve:proc:%u:%u: match skipped for not /dev/ mountsource for %s %s\n", major(device), minor(device), fs, mountsource);
- 260 0 : continue;
- 261 : }
- 262 :
- 263 0 : pathcpy(path, path_size, mountsource);
- 264 :
- 265 0 : log_tag("resolve:proc:%u:%u: found device %s matching device %s\n", major(device), minor(device), path, match);
- 266 :
- 267 0 : fclose(f);
- 268 0 : return 0;
- 269 : }
- 270 :
- 271 : /* get the device of the mount point */
- 272 : /* in Btrfs it could be different than the one in mountinfo */
- 273 192 : if (stat(mountpoint, &st) == 0 && st.st_dev == device) {
- 274 0 : if (strncmp(mountsource, "/dev/", 5) != 0) {
- 275 0 : log_tag("resolve:proc:%u:%u: match skipped for not /dev/ mountsource for %s %s\n", major(device), minor(device), fs, mountsource);
- 276 0 : continue;
- 277 : }
- 278 :
- 279 0 : pathcpy(path, path_size, mountsource);
- 280 :
- 281 0 : log_tag("resolve:proc:%u:%u: found device %s matching mountpoint %s\n", major(device), minor(device), path, mountpoint);
- 282 :
- 283 0 : fclose(f);
- 284 0 : return 0;
- 285 : }
- 286 : }
- 287 :
- 288 4 : log_tag("resolve:proc:%u:%u: not found\n", major(device), minor(device));
- 289 :
- 290 4 : fclose(f);
- 291 4 : return -1;
- 292 : }
- 293 : #endif
- 294 :
- 295 : /**
- 296 : * Get the device of a virtual superblock.
- 297 : *
- 298 : * This is intended to resolve the case of Btrfs filesystems that
- 299 : * create a virtual superblock (major==0) not backed by any low
- 300 : * level device.
- 301 : *
- 302 : * See:
- 303 : * Bug 711881 - too funny btrfs st_dev numbers
- 304 : * https://bugzilla.redhat.com/show_bug.cgi?id=711881
- 305 : */
- 306 : #if HAVE_LINUX_DEVICE
- 307 4 : static int devdereference(uint64_t device, uint64_t* new_device)
- 308 : {
- 309 : char path[PATH_MAX];
- 310 : struct stat st;
- 311 :
- 312 : /* use the proc interface to get the device containing the filesystem */
- 313 4 : if (devresolve_proc(device, path, sizeof(path)) != 0) {
- 314 : /* LCOV_EXCL_START */
- 315 : return -1;
- 316 : /* LCOV_EXCL_STOP */
- 317 : }
- 318 :
- 319 : /* check the device */
- 320 0 : if (stat(path, &st) != 0) {
- 321 : /* LCOV_EXCL_START */
- 322 : log_tag("dereference:%u:%u: failed to stat %s\n", major(device), minor(device), path);
- 323 : return -1;
- 324 : /* LCOV_EXCL_STOP */
- 325 : }
- 326 :
- 327 0 : if (major(st.st_rdev) == 0) {
- 328 : /* LCOV_EXCL_START */
- 329 : log_tag("dereference:%u:%u: still null device %s -> %u:%u\n", major(device), minor(device), path, major(st.st_rdev), minor(st.st_rdev));
- 330 : return -1;
- 331 : /* LCOV_EXCL_STOP */
- 332 : }
- 333 :
- 334 0 : *new_device = st.st_rdev;
- 335 0 : log_tag("dereference:%u:%u: found %u:%u\n", major(device), minor(device), major(st.st_rdev), minor(st.st_rdev));
- 336 0 : return 0;
- 337 : }
- 338 : #endif
- 339 :
- 340 : /**
- 341 : * Read a file extracting the specified tag TAG=VALUE format.
- 342 : * Return !=0 on error.
- 343 : */
- 344 : #if HAVE_LINUX_DEVICE
- 345 165 : static int tagread(const char* path, const char* tag, char* value, size_t value_size)
- 346 : {
- 347 : int ret;
- 348 : char buf[512];
- 349 : size_t tag_len;
- 350 : char* i;
- 351 : char* e;
- 352 :
- 353 165 : ret = sysread(path, buf, sizeof(buf));
- 354 165 : if (ret < 0) {
- 355 : /* LCOV_EXCL_START */
- 356 : log_fatal(errno, "Failed to read '%s'.\n", path);
- 357 : return -1;
- 358 : /* LCOV_EXCL_STOP */
- 359 : }
- 360 165 : if ((size_t)ret + 1 > sizeof(buf)) {
- 361 : /* LCOV_EXCL_START */
- 362 : log_fatal(EEXTERNAL, "Too long read '%s'.\n", path);
- 363 : return -1;
- 364 : /* LCOV_EXCL_STOP */
- 365 : }
- 366 :
- 367 : /* ending 0 */
- 368 165 : buf[ret] = 0;
- 369 :
- 370 165 : tag_len = strlen(tag);
- 371 :
- 372 2870 : for (i = buf; *i; ++i) {
- 373 2870 : char* p = i;
- 374 :
- 375 : /* start with a space */
- 376 2870 : if (p != buf) {
- 377 2705 : if (!isspace(*p))
- 378 2375 : continue;
- 379 330 : ++p;
- 380 : }
- 381 :
- 382 495 : if (strncmp(p, tag, tag_len) != 0)
- 383 330 : continue;
- 384 165 : p += tag_len;
- 385 :
- 386 : /* end with a = */
- 387 165 : if (*p != '=')
- 388 0 : continue;
- 389 165 : ++p;
- 390 :
- 391 : /* found */
- 392 165 : i = p;
- 393 165 : break;
- 394 : }
- 395 165 : if (!*i) {
- 396 : /* LCOV_EXCL_START */
- 397 : log_fatal(EEXTERNAL, "Missing tag '%s' for '%s'.\n", tag, path);
- 398 : return -1;
- 399 : /* LCOV_EXCL_STOP */
- 400 : }
- 401 :
- 402 : /* terminate at the first space */
- 403 165 : e = i;
- 404 725 : while (*e != 0 && !isspace(*e))
- 405 560 : ++e;
- 406 165 : *e = 0;
- 407 :
- 408 165 : if (!*i) {
- 409 : /* LCOV_EXCL_START */
- 410 : log_fatal(EEXTERNAL, "Empty tag '%s' for '%s'.\n", tag, path);
- 411 : return -1;
- 412 : /* LCOV_EXCL_STOP */
- 413 : }
- 414 :
- 415 165 : pathprint(value, value_size, "%s", i);
- 416 :
- 417 165 : return 0;
- 418 : }
- 419 : #endif
- 420 :
- 421 : /**
- 422 : * Get the device file from the device number.
- 423 : *
- 424 : * It uses /sys/dev/block/.../uevent.
- 425 : *
- 426 : * For null device (major==0) it fails.
- 427 : */
- 428 : #if HAVE_LINUX_DEVICE
- 429 165 : static int devresolve_sys(dev_t device, char* path, size_t path_size)
- 430 : {
- 431 : struct stat st;
- 432 : char buf[PATH_MAX];
- 433 :
- 434 : /* default device path from device number */
- 435 165 : pathprint(path, path_size, "/sys/dev/block/%u:%u/uevent", major(device), minor(device));
- 436 :
- 437 165 : if (tagread(path, "DEVNAME", buf, sizeof(buf)) != 0) {
- 438 : /* LCOV_EXCL_START */
- 439 : log_tag("resolve:sys:%u:%u: failed to read DEVNAME tag '%s'\n", major(device), minor(device), path);
- 440 : return -1;
- 441 : /* LCOV_EXCL_STOP */
- 442 : }
- 443 :
- 444 : /* set the real device path */
- 445 165 : pathprint(path, path_size, "/dev/%s", buf);
- 446 :
- 447 : /* check the device */
- 448 165 : if (stat(path, &st) != 0) {
- 449 : /* LCOV_EXCL_START */
- 450 : log_tag("resolve:sys:%u:%u: failed to stat '%s'\n", major(device), minor(device), path);
- 451 : return -1;
- 452 : /* LCOV_EXCL_STOP */
- 453 : }
- 454 165 : if (st.st_rdev != device) {
- 455 : /* LCOV_EXCL_START */
- 456 : 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);
- 457 : return -1;
- 458 : /* LCOV_EXCL_STOP */
- 459 : }
- 460 :
- 461 165 : log_tag("resolve:sys:%u:%u:%s: found\n", major(device), minor(device), path);
- 462 :
- 463 165 : return 0;
- 464 : }
- 465 : #endif
- 466 :
- 467 : /**
- 468 : * Get the device file from the device number.
- 469 : */
- 470 : #if HAVE_LINUX_DEVICE
- 471 165 : static int devresolve(uint64_t device, char* path, size_t path_size)
- 472 : {
- 473 165 : if (devresolve_sys(device, path, path_size) == 0)
- 474 165 : return 0;
- 475 :
- 476 0 : return -1;
- 477 : }
- 478 : #endif
- 479 :
- 480 : /**
- 481 : * Cache used by blkid.
- 482 : */
- 483 : #if HAVE_BLKID
- 484 : static blkid_cache cache = 0;
- 485 : #endif
- 486 :
- 487 : /**
- 488 : * Get the UUID using the /dev/disk/by-uuid/ links.
- 489 : * It doesn't require root permission, and the uuid are always updated.
- 490 : * It doesn't work with Btrfs file-systems that don't export the main UUID
- 491 : * in /dev/disk/by-uuid/.
- 492 : */
- 493 : #if HAVE_LINUX_DEVICE
- 494 10544 : static int devuuid_dev(uint64_t device, char* uuid, size_t uuid_size)
- 495 : {
- 496 : int ret;
- 497 : DIR* d;
- 498 : struct dirent* dd;
- 499 : struct stat st;
- 500 :
- 501 : /* scan the UUID directory searching for the device */
- 502 10544 : d = opendir("/dev/disk/by-uuid");
- 503 10544 : if (!d) {
- 504 0 : log_tag("uuid:by-uuid:%u:%u: opendir(/dev/disk/by-uuid) failed, %s\n", major(device), minor(device), strerror(errno));
- 505 : /* directory missing?, likely we are not in Linux */
- 506 0 : return -1;
- 507 : }
- 508 :
- 509 10544 : int dir_fd = dirfd(d);
- 510 10544 : if (dir_fd == -1) {
- 511 0 : log_tag("uuid:by-uuid:%u:%u: dirfd(/dev/disk/by-uuid) failed, %s\n", major(device), minor(device), strerror(errno));
- 512 0 : return -1;
- 513 : }
- 514 :
- 515 168704 : while ((dd = readdir(d)) != 0) {
- 516 : /* skip "." and ".." files, UUIDs never start with '.' */
- 517 168704 : if (dd->d_name[0] == '.')
- 518 21088 : continue;
- 519 :
- 520 147616 : ret = fstatat(dir_fd, dd->d_name, &st, 0);
- 521 147616 : if (ret != 0) {
- 522 0 : log_tag("uuid:by-uuid:%u:%u: fstatat(%s) failed, %s\n", major(device), minor(device), dd->d_name, strerror(errno));
- 523 : /* generic error, ignore and continue the search */
- 524 0 : continue;
- 525 : }
- 526 :
- 527 : /* if it matches, we have the uuid */
- 528 147616 : if (S_ISBLK(st.st_mode) && st.st_rdev == (dev_t)device) {
- 529 : char buf[PATH_MAX];
- 530 : char path[PATH_MAX];
- 531 :
- 532 : /* resolve the link */
- 533 10544 : pathprint(path, sizeof(path), "/dev/disk/by-uuid/%s", dd->d_name);
- 534 10544 : ret = readlink(path, buf, sizeof(buf));
- 535 10544 : if (ret < 0 || ret >= PATH_MAX) {
- 536 0 : log_tag("uuid:by-uuid:%u:%u: readlink(/dev/disk/by-uuid/%s) failed, %s\n", major(device), minor(device), dd->d_name, strerror(errno));
- 537 : /* generic error, ignore and continue the search */
- 538 0 : continue;
- 539 : }
- 540 10544 : buf[ret] = 0;
- 541 :
- 542 : /* found */
- 543 10544 : pathcpy(uuid, uuid_size, dd->d_name);
- 544 :
- 545 10544 : log_tag("uuid:by-uuid:%u:%u:%s: found %s\n", major(device), minor(device), uuid, buf);
- 546 :
- 547 10544 : closedir(d);
- 548 10544 : return 0;
- 549 : }
- 550 : }
- 551 :
- 552 0 : log_tag("uuid:by-uuid:%u:%u: /dev/disk/by-uuid doesn't contain a matching block device\n", major(device), minor(device));
- 553 :
- 554 : /* not found */
- 555 0 : closedir(d);
- 556 0 : return -1;
- 557 : }
- 558 : #endif
- 559 :
- 560 : /**
- 561 : * Get the UUID using libblkid.
- 562 : * It uses a cache to work without root permission, resulting in UUID
- 563 : * not necessarily recent.
- 564 : * We could call blkid_probe_all() to refresh the UUID, but it would
- 565 : * require root permission to read the superblocks, and resulting in
- 566 : * all the disks spinning.
- 567 : */
- 568 : #if HAVE_BLKID
- 569 0 : static int devuuid_blkid(uint64_t device, char* uuid, size_t uuid_size)
- 570 : {
- 571 : char* devname;
- 572 : char* uuidname;
- 573 :
- 574 0 : devname = blkid_devno_to_devname(device);
- 575 0 : if (!devname) {
- 576 0 : log_tag("uuid:blkid:%u:%u: blkid_devno_to_devname() failed, %s\n", major(device), minor(device), strerror(errno));
- 577 : /* device mapping failed */
- 578 0 : return -1;
- 579 : }
- 580 :
- 581 0 : uuidname = blkid_get_tag_value(cache, "UUID", devname);
- 582 0 : if (!uuidname) {
- 583 0 : log_tag("uuid:blkid:%u:%u: blkid_get_tag_value(UUID,%s) failed, %s\n", major(device), minor(device), devname, strerror(errno));
- 584 : /* uuid mapping failed */
- 585 0 : free(devname);
- 586 0 : return -1;
- 587 : }
- 588 :
- 589 0 : pathcpy(uuid, uuid_size, uuidname);
- 590 :
- 591 0 : log_tag("uuid:blkid:%u:%u:%s: found %s\n", major(device), minor(device), uuid, devname);
- 592 :
- 593 0 : free(devname);
- 594 0 : free(uuidname);
- 595 0 : return 0;
- 596 : }
- 597 : #endif
- 598 :
+ 138 : * Return an error if truncated
+ 139 : *
+ 140 : * Return -1 on error, 0 on success
+ 141 : */
+ 142 : #if HAVE_LINUX_DEVICE
+ 143 62 : static int sysattr(const char* path, char* buf, size_t buf_size)
+ 144 : {
+ 145 : int len;
+ 146 :
+ 147 62 : len = sysread(path, buf, buf_size);
+ 148 62 : if (len < 0) {
+ 149 : /* LCOV_EXCL_START */
+ 150 : return -1;
+ 151 : /* LCOV_EXCL_STOP */
+ 152 : }
+ 153 :
+ 154 48 : if ((size_t)len + 1 > buf_size) {
+ 155 : /* LCOV_EXCL_START */
+ 156 : return -1;
+ 157 : /* LCOV_EXCL_STOP */
+ 158 : }
+ 159 :
+ 160 48 : buf[len] = 0;
+ 161 :
+ 162 48 : strtrim(buf);
+ 163 :
+ 164 48 : return 0;
+ 165 : }
+ 166 : #endif
+ 167 :
+ 168 : /**
+ 169 : * Get the device file from the device number.
+ 170 : *
+ 171 : * It uses /proc/self/mountinfo.
+ 172 : *
+ 173 : * Null devices (major==0) are resolved to the device indicated in mountinfo.
+ 174 : */
+ 175 : #if HAVE_LINUX_DEVICE
+ 176 4 : static int devresolve_proc(uint64_t device, char* path, size_t path_size)
+ 177 : {
+ 178 : FILE* f;
+ 179 : char match[32];
+ 180 :
+ 181 : /* generate the matching string */
+ 182 4 : snprintf(match, sizeof(match), "%u:%u", major(device), minor(device));
+ 183 :
+ 184 4 : f = fopen("/proc/self/mountinfo", "r");
+ 185 4 : if (!f) {
+ 186 0 : log_tag("resolve:proc:%u:%u: failed to open /proc/self/mountinfo\n", major(device), minor(device));
+ 187 0 : return -1;
+ 188 : }
+ 189 :
+ 190 : /*
+ 191 : * mountinfo format
+ 192 : * 0 - mount ID
+ 193 : * 1 - parent ID
+ 194 : * 2 - major:minor
+ 195 : * 3 - root
+ 196 : * 4 - mount point
+ 197 : * 5 - options
+ 198 : * 6 - "-" (separator)
+ 199 : * 7 - fs
+ 200 : * 8 - mount source - /dev/device
+ 201 : */
+ 202 :
+ 203 192 : while (1) {
+ 204 : char buf[256];
+ 205 : char* first_map[8];
+ 206 : unsigned first_mac;
+ 207 : char* second_map[8];
+ 208 : unsigned second_mac;
+ 209 : char* s;
+ 210 : struct stat st;
+ 211 : char* separator;
+ 212 : char* majorminor;
+ 213 : char* mountpoint;
+ 214 : char* fs;
+ 215 : char* mountsource;
+ 216 :
+ 217 196 : s = fgets(buf, sizeof(buf), f);
+ 218 196 : if (s == 0)
+ 219 4 : break;
+ 220 :
+ 221 : /* find the separator position */
+ 222 192 : separator = strstr(s, " - ");
+ 223 192 : if (!separator)
+ 224 0 : continue;
+ 225 :
+ 226 : /* skip the separator */
+ 227 192 : *separator = 0;
+ 228 192 : separator += 3;
+ 229 :
+ 230 : /* split the line */
+ 231 192 : first_mac = strsplit(first_map, 8, s, " \t\r\n");
+ 232 192 : second_mac = strsplit(second_map, 8, separator, " \t\r\n");
+ 233 :
+ 234 : /* if too short, it's the wrong line */
+ 235 192 : if (first_mac < 5)
+ 236 0 : continue;
+ 237 192 : if (second_mac < 2)
+ 238 0 : continue;
+ 239 :
+ 240 192 : majorminor = first_map[2];
+ 241 192 : mountpoint = first_map[4];
+ 242 192 : fs = second_map[0];
+ 243 192 : mountsource = second_map[1];
+ 244 :
+ 245 : /* compare major:minor from mountinfo */
+ 246 192 : if (strcmp(majorminor, match) == 0) {
+ 247 : /*
+ 248 : * Accept only /dev/... mountsource
+ 249 : *
+ 250 : * This excludes ZFS that uses a bare label for mountsource, like "tank".
+ 251 : *
+ 252 : * 410 408 0:193 / /XXX rw,relatime shared:217 - zfs tank/system/data/var/lib/docker/XXX rw,xattr,noacl
+ 253 : *
+ 254 : * Also excludes AUTOFS unmounted devices that point to a fake filesystem
+ 255 : * used to remount them at the first use.
+ 256 : *
+ 257 : * 97 25 0:42 / /XXX rw,relatime shared:76 - autofs /etc/auto.seed rw,fd=6,pgrp=952,timeout=30,minproto=5,maxproto=5,indirect
+ 258 : */
+ 259 0 : if (strncmp(mountsource, "/dev/", 5) != 0) {
+ 260 0 : log_tag("resolve:proc:%u:%u: match skipped for not /dev/ mountsource for %s %s\n", major(device), minor(device), fs, mountsource);
+ 261 0 : continue;
+ 262 : }
+ 263 :
+ 264 0 : pathcpy(path, path_size, mountsource);
+ 265 :
+ 266 0 : log_tag("resolve:proc:%u:%u: found device %s matching device %s\n", major(device), minor(device), path, match);
+ 267 :
+ 268 0 : fclose(f);
+ 269 0 : return 0;
+ 270 : }
+ 271 :
+ 272 : /* get the device of the mount point */
+ 273 : /* in Btrfs it could be different than the one in mountinfo */
+ 274 192 : if (stat(mountpoint, &st) == 0 && st.st_dev == device) {
+ 275 0 : if (strncmp(mountsource, "/dev/", 5) != 0) {
+ 276 0 : log_tag("resolve:proc:%u:%u: match skipped for not /dev/ mountsource for %s %s\n", major(device), minor(device), fs, mountsource);
+ 277 0 : continue;
+ 278 : }
+ 279 :
+ 280 0 : pathcpy(path, path_size, mountsource);
+ 281 :
+ 282 0 : log_tag("resolve:proc:%u:%u: found device %s matching mountpoint %s\n", major(device), minor(device), path, mountpoint);
+ 283 :
+ 284 0 : fclose(f);
+ 285 0 : return 0;
+ 286 : }
+ 287 : }
+ 288 :
+ 289 4 : log_tag("resolve:proc:%u:%u: not found\n", major(device), minor(device));
+ 290 :
+ 291 4 : fclose(f);
+ 292 4 : return -1;
+ 293 : }
+ 294 : #endif
+ 295 :
+ 296 : /**
+ 297 : * Get the device of a virtual superblock.
+ 298 : *
+ 299 : * This is intended to resolve the case of Btrfs filesystems that
+ 300 : * create a virtual superblock (major==0) not backed by any low
+ 301 : * level device.
+ 302 : *
+ 303 : * See:
+ 304 : * Bug 711881 - too funny btrfs st_dev numbers
+ 305 : * https://bugzilla.redhat.com/show_bug.cgi?id=711881
+ 306 : */
+ 307 : #if HAVE_LINUX_DEVICE
+ 308 4 : static int devdereference(uint64_t device, uint64_t* new_device)
+ 309 : {
+ 310 : char path[PATH_MAX];
+ 311 : struct stat st;
+ 312 :
+ 313 : /* use the proc interface to get the device containing the filesystem */
+ 314 4 : if (devresolve_proc(device, path, sizeof(path)) != 0) {
+ 315 : /* LCOV_EXCL_START */
+ 316 : return -1;
+ 317 : /* LCOV_EXCL_STOP */
+ 318 : }
+ 319 :
+ 320 : /* check the device */
+ 321 0 : if (stat(path, &st) != 0) {
+ 322 : /* LCOV_EXCL_START */
+ 323 : log_tag("dereference:%u:%u: failed to stat %s\n", major(device), minor(device), path);
+ 324 : return -1;
+ 325 : /* LCOV_EXCL_STOP */
+ 326 : }
+ 327 :
+ 328 0 : if (major(st.st_rdev) == 0) {
+ 329 : /* LCOV_EXCL_START */
+ 330 : log_tag("dereference:%u:%u: still null device %s -> %u:%u\n", major(device), minor(device), path, major(st.st_rdev), minor(st.st_rdev));
+ 331 : return -1;
+ 332 : /* LCOV_EXCL_STOP */
+ 333 : }
+ 334 :
+ 335 0 : *new_device = st.st_rdev;
+ 336 0 : log_tag("dereference:%u:%u: found %u:%u\n", major(device), minor(device), major(st.st_rdev), minor(st.st_rdev));
+ 337 0 : return 0;
+ 338 : }
+ 339 : #endif
+ 340 :
+ 341 : /**
+ 342 : * Read a file extracting the specified tag TAG=VALUE format.
+ 343 : * Return !=0 on error.
+ 344 : */
+ 345 : #if HAVE_LINUX_DEVICE
+ 346 205 : static int tagread(const char* path, const char* tag, char* value, size_t value_size)
+ 347 : {
+ 348 : int ret;
+ 349 : char buf[512];
+ 350 : size_t tag_len;
+ 351 : char* i;
+ 352 : char* e;
+ 353 :
+ 354 205 : ret = sysread(path, buf, sizeof(buf));
+ 355 205 : if (ret < 0) {
+ 356 : /* LCOV_EXCL_START */
+ 357 : log_fatal(errno, "Failed to read '%s'.\n", path);
+ 358 : return -1;
+ 359 : /* LCOV_EXCL_STOP */
+ 360 : }
+ 361 205 : if ((size_t)ret + 1 > sizeof(buf)) {
+ 362 : /* LCOV_EXCL_START */
+ 363 : log_fatal(EEXTERNAL, "Too long read '%s'.\n", path);
+ 364 : return -1;
+ 365 : /* LCOV_EXCL_STOP */
+ 366 : }
+ 367 :
+ 368 : /* ending 0 */
+ 369 205 : buf[ret] = 0;
+ 370 :
+ 371 205 : tag_len = strlen(tag);
+ 372 :
+ 373 3578 : for (i = buf; *i; ++i) {
+ 374 3578 : char* p = i;
+ 375 :
+ 376 : /* start with a space */
+ 377 3578 : if (p != buf) {
+ 378 3373 : if (!isspace(*p))
+ 379 2963 : continue;
+ 380 410 : ++p;
+ 381 : }
+ 382 :
+ 383 615 : if (strncmp(p, tag, tag_len) != 0)
+ 384 410 : continue;
+ 385 205 : p += tag_len;
+ 386 :
+ 387 : /* end with a = */
+ 388 205 : if (*p != '=')
+ 389 0 : continue;
+ 390 205 : ++p;
+ 391 :
+ 392 : /* found */
+ 393 205 : i = p;
+ 394 205 : break;
+ 395 : }
+ 396 205 : if (!*i) {
+ 397 : /* LCOV_EXCL_START */
+ 398 : log_fatal(EEXTERNAL, "Missing tag '%s' for '%s'.\n", tag, path);
+ 399 : return -1;
+ 400 : /* LCOV_EXCL_STOP */
+ 401 : }
+ 402 :
+ 403 : /* terminate at the first space */
+ 404 205 : e = i;
+ 405 901 : while (*e != 0 && !isspace(*e))
+ 406 696 : ++e;
+ 407 205 : *e = 0;
+ 408 :
+ 409 205 : if (!*i) {
+ 410 : /* LCOV_EXCL_START */
+ 411 : log_fatal(EEXTERNAL, "Empty tag '%s' for '%s'.\n", tag, path);
+ 412 : return -1;
+ 413 : /* LCOV_EXCL_STOP */
+ 414 : }
+ 415 :
+ 416 205 : pathprint(value, value_size, "%s", i);
+ 417 :
+ 418 205 : return 0;
+ 419 : }
+ 420 : #endif
+ 421 :
+ 422 : /**
+ 423 : * Get the device file from the device number.
+ 424 : *
+ 425 : * It uses /sys/dev/block/.../uevent.
+ 426 : *
+ 427 : * For null device (major==0) it fails.
+ 428 : */
+ 429 : #if HAVE_LINUX_DEVICE
+ 430 205 : static int devresolve_sys(dev_t device, char* path, size_t path_size)
+ 431 : {
+ 432 : struct stat st;
+ 433 : char buf[PATH_MAX];
+ 434 :
+ 435 : /* default device path from device number */
+ 436 205 : pathprint(path, path_size, "/sys/dev/block/%u:%u/uevent", major(device), minor(device));
+ 437 :
+ 438 205 : if (tagread(path, "DEVNAME", buf, sizeof(buf)) != 0) {
+ 439 : /* LCOV_EXCL_START */
+ 440 : log_tag("resolve:sys:%u:%u: failed to read DEVNAME tag '%s'\n", major(device), minor(device), path);
+ 441 : return -1;
+ 442 : /* LCOV_EXCL_STOP */
+ 443 : }
+ 444 :
+ 445 : /* set the real device path */
+ 446 205 : pathprint(path, path_size, "/dev/%s", buf);
+ 447 :
+ 448 : /* check the device */
+ 449 205 : if (stat(path, &st) != 0) {
+ 450 : /* LCOV_EXCL_START */
+ 451 : log_tag("resolve:sys:%u:%u: failed to stat '%s'\n", major(device), minor(device), path);
+ 452 : return -1;
+ 453 : /* LCOV_EXCL_STOP */
+ 454 : }
+ 455 205 : if (st.st_rdev != device) {
+ 456 : /* LCOV_EXCL_START */
+ 457 : 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);
+ 458 : return -1;
+ 459 : /* LCOV_EXCL_STOP */
+ 460 : }
+ 461 :
+ 462 205 : log_tag("resolve:sys:%u:%u:%s: found\n", major(device), minor(device), path);
+ 463 :
+ 464 205 : return 0;
+ 465 : }
+ 466 : #endif
+ 467 :
+ 468 : /**
+ 469 : * Get the device file from the device number.
+ 470 : */
+ 471 : #if HAVE_LINUX_DEVICE
+ 472 205 : static int devresolve(uint64_t device, char* path, size_t path_size)
+ 473 : {
+ 474 205 : if (devresolve_sys(device, path, path_size) == 0)
+ 475 205 : return 0;
+ 476 :
+ 477 0 : return -1;
+ 478 : }
+ 479 : #endif
+ 480 :
+ 481 : /**
+ 482 : * Cache used by blkid.
+ 483 : */
+ 484 : #if HAVE_BLKID
+ 485 : static blkid_cache cache = 0;
+ 486 : #endif
+ 487 :
+ 488 : /**
+ 489 : * Get the UUID using the /dev/disk/by-uuid/ links.
+ 490 : * It doesn't require root permission, and the uuid are always updated.
+ 491 : * It doesn't work with Btrfs file-systems that don't export the main UUID
+ 492 : * in /dev/disk/by-uuid/.
+ 493 : */
+ 494 : #if HAVE_LINUX_DEVICE
+ 495 10556 : static int devuuid_dev(uint64_t device, char* uuid, size_t uuid_size)
+ 496 : {
+ 497 : int ret;
+ 498 : DIR* d;
+ 499 : struct dirent* dd;
+ 500 : struct stat st;
+ 501 :
+ 502 : /* scan the UUID directory searching for the device */
+ 503 10556 : d = opendir("/dev/disk/by-uuid");
+ 504 10556 : if (!d) {
+ 505 0 : log_tag("uuid:by-uuid:%u:%u: opendir(/dev/disk/by-uuid) failed, %s\n", major(device), minor(device), strerror(errno));
+ 506 : /* directory missing?, likely we are not in Linux */
+ 507 0 : return -1;
+ 508 : }
+ 509 :
+ 510 10556 : int dir_fd = dirfd(d);
+ 511 10556 : if (dir_fd == -1) {
+ 512 0 : log_tag("uuid:by-uuid:%u:%u: dirfd(/dev/disk/by-uuid) failed, %s\n", major(device), minor(device), strerror(errno));
+ 513 0 : return -1;
+ 514 : }
+ 515 :
+ 516 168806 : while ((dd = readdir(d)) != 0) {
+ 517 : /* skip "." and ".." files, UUIDs never start with '.' */
+ 518 168806 : if (dd->d_name[0] == '.')
+ 519 21112 : continue;
+ 520 :
+ 521 147694 : ret = fstatat(dir_fd, dd->d_name, &st, 0);
+ 522 147694 : if (ret != 0) {
+ 523 0 : log_tag("uuid:by-uuid:%u:%u: fstatat(%s) failed, %s\n", major(device), minor(device), dd->d_name, strerror(errno));
+ 524 : /* generic error, ignore and continue the search */
+ 525 0 : continue;
+ 526 : }
+ 527 :
+ 528 : /* if it matches, we have the uuid */
+ 529 147694 : if (S_ISBLK(st.st_mode) && st.st_rdev == (dev_t)device) {
+ 530 : char buf[PATH_MAX];
+ 531 : char path[PATH_MAX];
+ 532 :
+ 533 : /* resolve the link */
+ 534 10556 : pathprint(path, sizeof(path), "/dev/disk/by-uuid/%s", dd->d_name);
+ 535 10556 : ret = readlink(path, buf, sizeof(buf));
+ 536 10556 : if (ret < 0 || ret >= PATH_MAX) {
+ 537 0 : log_tag("uuid:by-uuid:%u:%u: readlink(/dev/disk/by-uuid/%s) failed, %s\n", major(device), minor(device), dd->d_name, strerror(errno));
+ 538 : /* generic error, ignore and continue the search */
+ 539 0 : continue;
+ 540 : }
+ 541 10556 : buf[ret] = 0;
+ 542 :
+ 543 : /* found */
+ 544 10556 : pathcpy(uuid, uuid_size, dd->d_name);
+ 545 :
+ 546 10556 : log_tag("uuid:by-uuid:%u:%u:%s: found %s\n", major(device), minor(device), uuid, buf);
+ 547 :
+ 548 10556 : closedir(d);
+ 549 10556 : return 0;
+ 550 : }
+ 551 : }
+ 552 :
+ 553 0 : log_tag("uuid:by-uuid:%u:%u: /dev/disk/by-uuid doesn't contain a matching block device\n", major(device), minor(device));
+ 554 :
+ 555 : /* not found */
+ 556 0 : closedir(d);
+ 557 0 : return -1;
+ 558 : }
+ 559 : #endif
+ 560 :
+ 561 : /**
+ 562 : * Get the UUID using libblkid.
+ 563 : * It uses a cache to work without root permission, resulting in UUID
+ 564 : * not necessarily recent.
+ 565 : * We could call blkid_probe_all() to refresh the UUID, but it would
+ 566 : * require root permission to read the superblocks, and resulting in
+ 567 : * all the disks spinning.
+ 568 : */
+ 569 : #if HAVE_BLKID
+ 570 0 : static int devuuid_blkid(uint64_t device, char* uuid, size_t uuid_size)
+ 571 : {
+ 572 : char* devname;
+ 573 : char* uuidname;
+ 574 :
+ 575 0 : devname = blkid_devno_to_devname(device);
+ 576 0 : if (!devname) {
+ 577 0 : log_tag("uuid:blkid:%u:%u: blkid_devno_to_devname() failed, %s\n", major(device), minor(device), strerror(errno));
+ 578 : /* device mapping failed */
+ 579 0 : return -1;
+ 580 : }
+ 581 :
+ 582 0 : uuidname = blkid_get_tag_value(cache, "UUID", devname);
+ 583 0 : if (!uuidname) {
+ 584 0 : log_tag("uuid:blkid:%u:%u: blkid_get_tag_value(UUID,%s) failed, %s\n", major(device), minor(device), devname, strerror(errno));
+ 585 : /* uuid mapping failed */
+ 586 0 : free(devname);
+ 587 0 : return -1;
+ 588 : }
+ 589 :
+ 590 0 : pathcpy(uuid, uuid_size, uuidname);
+ 591 :
+ 592 0 : log_tag("uuid:blkid:%u:%u:%s: found %s\n", major(device), minor(device), uuid, devname);
+ 593 :
+ 594 0 : free(devname);
+ 595 0 : free(uuidname);
+ 596 0 : return 0;
+ 597 : }
+ 598 : #endif
599 :
- 600 : /**
- 601 : * Get the LABEL using libblkid.
- 602 : * It uses a cache to work without root permission, resulting in LABEL
- 603 : * not necessarily recent.
- 604 : */
- 605 : #if HAVE_BLKID
- 606 5759 : static int devuuid_label(uint64_t device, char* label, size_t label_size)
- 607 : {
- 608 : char* devname;
- 609 : char* labelname;
- 610 :
- 611 5759 : devname = blkid_devno_to_devname(device);
- 612 5759 : if (!devname) {
- 613 0 : log_tag("label:blkid:%u:%u: blkid_devno_to_devname() failed, %s\n", major(device), minor(device), strerror(errno));
- 614 : /* device mapping failed */
- 615 0 : return -1;
- 616 : }
- 617 :
- 618 5759 : labelname = blkid_get_tag_value(cache, "LABEL", devname);
- 619 5759 : if (!labelname) {
- 620 5759 : log_tag("label:blkid:%u:%u: blkid_get_tag_value(LABEL,%s) failed, %s\n", major(device), minor(device), devname, strerror(errno));
- 621 5759 : free(devname);
- 622 : /* label mapping failed */
- 623 5759 : return -1;
- 624 : }
- 625 :
- 626 0 : pathcpy(label, label_size, labelname);
- 627 :
- 628 0 : log_tag("label:blkid:%u:%u:%s: found %s\n", major(device), minor(device), label, devname);
- 629 :
- 630 0 : free(devname);
- 631 0 : free(labelname);
- 632 0 : return 0;
- 633 : }
- 634 : #endif
- 635 :
+ 600 :
+ 601 : /**
+ 602 : * Get the LABEL using libblkid.
+ 603 : * It uses a cache to work without root permission, resulting in LABEL
+ 604 : * not necessarily recent.
+ 605 : */
+ 606 : #if HAVE_BLKID
+ 607 5759 : static int devuuid_label(uint64_t device, char* label, size_t label_size)
+ 608 : {
+ 609 : char* devname;
+ 610 : char* labelname;
+ 611 :
+ 612 5759 : devname = blkid_devno_to_devname(device);
+ 613 5759 : if (!devname) {
+ 614 0 : log_tag("label:blkid:%u:%u: blkid_devno_to_devname() failed, %s\n", major(device), minor(device), strerror(errno));
+ 615 : /* device mapping failed */
+ 616 0 : return -1;
+ 617 : }
+ 618 :
+ 619 5759 : labelname = blkid_get_tag_value(cache, "LABEL", devname);
+ 620 5759 : if (!labelname) {
+ 621 5759 : log_tag("label:blkid:%u:%u: blkid_get_tag_value(LABEL,%s) failed, %s\n", major(device), minor(device), devname, strerror(errno));
+ 622 5759 : free(devname);
+ 623 : /* label mapping failed */
+ 624 5759 : return -1;
+ 625 : }
+ 626 :
+ 627 0 : pathcpy(label, label_size, labelname);
+ 628 :
+ 629 0 : log_tag("label:blkid:%u:%u:%s: found %s\n", major(device), minor(device), label, devname);
+ 630 :
+ 631 0 : free(devname);
+ 632 0 : free(labelname);
+ 633 0 : return 0;
+ 634 : }
+ 635 : #endif
636 :
- 637 : #ifdef __APPLE__
- 638 : static int devuuid_darwin(const char* path, char* uuid, size_t uuid_size)
- 639 : {
- 640 : CFStringRef path_apple = 0;
- 641 : DASessionRef session = 0;
- 642 : CFURLRef path_appler = 0;
- 643 : int result = -1;
- 644 :
- 645 : *uuid = 0;
- 646 :
- 647 : path_apple = CFStringCreateWithCString(kCFAllocatorDefault, path, kCFStringEncodingUTF8);
- 648 : if (!path_apple)
- 649 : goto bail;
- 650 :
- 651 : session = DASessionCreate(kCFAllocatorDefault);
- 652 : if (!session)
- 653 : goto bail;
- 654 :
- 655 : path_appler = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, path_apple, kCFURLPOSIXPathStyle, false);
- 656 : if (!path_appler)
- 657 : goto bail;
- 658 :
- 659 : /* find the mount point */
- 660 : DADiskRef disk = NULL;
- 661 : while (path_appler) {
- 662 : disk = DADiskCreateFromVolumePath(kCFAllocatorDefault, session, path_appler);
- 663 : if (disk)
- 664 : break;
- 665 :
- 666 : CFURLRef parent = CFURLCreateCopyDeletingLastPathComponent(kCFAllocatorDefault, path_appler);
- 667 : if (!parent)
- 668 : break;
- 669 :
- 670 : /* check if we hit the root (parent == child) */
- 671 : if (CFEqual(parent, path_appler)) {
- 672 : CFRelease(parent);
- 673 : break;
- 674 : }
- 675 :
- 676 : CFRelease(path_appler);
- 677 : path_appler = parent;
- 678 : }
- 679 :
- 680 : /* safely extract the UUID */
- 681 : if (disk) {
- 682 : CFDictionaryRef description = DADiskCopyDescription(disk);
- 683 : if (description) {
- 684 : /* key might not exist for NTFS/ExFAT on some drivers */
- 685 : const void* value = (CFUUIDRef)CFDictionaryGetValue(description, kDADiskDescriptionVolumeUUIDKey);
- 686 : CFStringRef uuid_string = NULL;
- 687 :
- 688 : if (value) {
- 689 : if (CFGetTypeID(value) == CFUUIDGetTypeID()) {
- 690 : uuid_string = CFUUIDCreateString(kCFAllocatorDefault, (CFUUIDRef)value);
- 691 : } else if (CFGetTypeID(value) == CFStringGetTypeID()) {
- 692 : /* if it's already a string, retain it so we can release it later consistently */
- 693 : uuid_string = (CFStringRef)CFRetain(value);
- 694 : }
- 695 : }
- 696 :
- 697 : if (uuid_string) {
- 698 : if (CFStringGetCString(uuid_string, uuid, uuid_size, kCFStringEncodingUTF8)) {
- 699 : result = 0; /* success */
- 700 : }
- 701 : CFRelease(uuid_string);
- 702 : }
- 703 :
- 704 : CFRelease(description);
- 705 : }
- 706 : CFRelease(disk);
- 707 : }
- 708 :
- 709 : bail:
- 710 : /* clean up */
- 711 : if (path_appler) CFRelease(path_appler);
- 712 : if (session) CFRelease(session);
- 713 : if (path_apple) CFRelease(path_apple);
- 714 :
- 715 : return result;
- 716 : }
- 717 : #endif
- 718 :
- 719 10548 : int devuuid(uint64_t device, const char* path, char* uuid, size_t uuid_size)
- 720 : {
- 721 : (void)path;
- 722 : (void)device;
- 723 :
- 724 : #ifdef __APPLE__
- 725 : if (devuuid_darwin(path, uuid, uuid_size) == 0)
- 726 : return 0;
- 727 : #endif
- 728 :
- 729 : #if HAVE_LINUX_DEVICE
- 730 : /* if the major is the null device */
- 731 10548 : if (major(device) == 0) {
- 732 : /* obtain the real device */
- 733 4 : if (devdereference(device, &device) != 0) {
- 734 : /* LCOV_EXCL_START */
- 735 : return -1;
- 736 : /* LCOV_EXCL_STOP */
- 737 : }
- 738 : }
- 739 : #endif
- 740 :
- 741 : /* first try with the /dev/disk/by-uuid version */
- 742 : #if HAVE_LINUX_DEVICE
- 743 10544 : if (devuuid_dev(device, uuid, uuid_size) == 0)
- 744 10544 : return 0;
- 745 : #else
- 746 : log_tag("uuid:by-uuid:%u:%u: by-uuid not supported\n", major(device), minor(device));
- 747 : #endif
- 748 :
- 749 : /* fall back to blkid for other cases */
- 750 : #if HAVE_BLKID
- 751 0 : if (devuuid_blkid(device, uuid, uuid_size) == 0)
- 752 0 : return 0;
- 753 : #else
- 754 : log_tag("uuid:blkid:%u:%u: blkid support not compiled in\n", major(device), minor(device));
- 755 : #endif
- 756 :
- 757 0 : log_tag("uuid:notfound:%u:%u:\n", major(device), minor(device));
- 758 :
- 759 : /* not supported */
- 760 : (void)uuid;
- 761 : (void)uuid_size;
- 762 0 : return -1;
- 763 : }
- 764 :
- 765 11432 : int filephy(const char* path, uint64_t size, uint64_t* physical)
- 766 : {
- 767 : #if HAVE_LINUX_FIEMAP_H
- 768 : /* In Linux get the real physical address of the file */
- 769 : /* Note that FIEMAP doesn't require root permission */
- 770 : int f;
- 771 : struct fiemap* fiemap;
- 772 : size_t fiemap_size;
- 773 : unsigned int blknum;
- 774 :
- 775 11432 : f = open(path, O_RDONLY);
- 776 11432 : if (f == -1) {
- 777 0 : return -1;
- 778 : }
- 779 :
- 780 : /* first try with FIEMAP */
- 781 : /* if works for ext2, ext3, ext4, xfs, btrfs */
- 782 11432 : fiemap_size = sizeof(struct fiemap) + sizeof(struct fiemap_extent);
- 783 11432 : fiemap = malloc_nofail(fiemap_size);
- 784 11432 : memset(fiemap, 0, fiemap_size);
- 785 11432 : fiemap->fm_start = 0;
- 786 11432 : fiemap->fm_length = ~0ULL;
- 787 11432 : fiemap->fm_flags = FIEMAP_FLAG_SYNC; /* required to ensure that just created files report a valid address and not 0 */
- 788 11432 : fiemap->fm_extent_count = 1; /* we are interested only at the first block */
- 789 :
- 790 11432 : if (ioctl(f, FS_IOC_FIEMAP, fiemap) != -1) {
- 791 11432 : uint32_t flags = fiemap->fm_extents[0].fe_flags;
- 792 11432 : uint64_t offset = fiemap->fm_extents[0].fe_physical;
- 793 :
- 794 : /* check some condition for validating the offset */
- 795 11432 : if (flags & FIEMAP_EXTENT_DATA_INLINE) {
- 796 : /* if the data is inline, we don't have an offset to report */
- 797 0 : *physical = FILEPHY_WITHOUT_OFFSET;
- 798 11432 : } else if (flags & FIEMAP_EXTENT_UNKNOWN) {
- 799 : /* if the offset is unknown, we don't have an offset to report */
- 800 0 : *physical = FILEPHY_WITHOUT_OFFSET;
- 801 11432 : } else if (offset == 0) {
- 802 : /* 0 is the general fallback for file-systems when */
- 803 : /* they don't have an offset to report */
- 804 14 : *physical = FILEPHY_WITHOUT_OFFSET;
- 805 : } else {
- 806 : /* finally report the real offset */
- 807 11418 : *physical = offset + FILEPHY_REAL_OFFSET;
- 808 : }
- 809 :
- 810 11432 : if (close(f) == -1)
- 811 0 : return -1;
- 812 11432 : return 0;
- 813 : }
- 814 :
- 815 0 : free(fiemap);
- 816 :
- 817 : /* if the file is empty, FIBMAP doesn't work, and we don't even try to use it */
- 818 0 : if (size == 0) {
- 819 0 : *physical = FILEPHY_WITHOUT_OFFSET;
- 820 0 : if (close(f) == -1)
- 821 0 : return -1;
- 822 0 : return 0;
- 823 : }
- 824 :
- 825 : /* then try with FIBMAP */
- 826 : /* it works for jfs, reiserfs, ntfs-3g */
- 827 : /* in exfat it always returns 0, that it's anyway better than the fake inodes */
- 828 0 : blknum = 0; /* first block */
- 829 0 : if (ioctl(f, FIBMAP, &blknum) != -1) {
- 830 0 : *physical = blknum + FILEPHY_REAL_OFFSET;
- 831 0 : if (close(f) == -1)
- 832 0 : return -1;
- 833 0 : return 0;
- 834 : }
- 835 :
- 836 : /* otherwise don't use anything, and keep the directory traversal order */
- 837 : /* at now this should happen only for vfat */
- 838 : /* and it's surely better than using fake inodes */
- 839 0 : *physical = FILEPHY_UNREPORTED_OFFSET;
- 840 0 : if (close(f) == -1)
- 841 0 : return -1;
- 842 : #else
- 843 : /* In a generic Unix use a dummy value for all the files */
- 844 : /* We don't want to risk to use the inode without knowing */
- 845 : /* if it really improves performance. */
- 846 : /* In this way we keep them in the directory traversal order */
- 847 : /* that at least keeps files in the same directory together. */
- 848 : /* Note also that in newer file-system with snapshot, like ZFS, */
- 849 : /* the inode doesn't represent even more the disk position, because files */
- 850 : /* are not overwritten in place, but rewritten in another location */
- 851 : /* of the disk. */
- 852 : *physical = FILEPHY_UNREPORTED_OFFSET;
- 853 :
- 854 : (void)path; /* not used here */
- 855 : (void)size;
- 856 : #endif
- 857 :
- 858 0 : return 0;
- 859 : }
- 860 :
- 861 : /* from man statfs */
- 862 : #define ADFS_SUPER_MAGIC 0xadf5
- 863 : #define AFFS_SUPER_MAGIC 0xADFF
- 864 : #define BDEVFS_MAGIC 0x62646576
- 865 : #define BEFS_SUPER_MAGIC 0x42465331
- 866 : #define BFS_MAGIC 0x1BADFACE
- 867 : #define BINFMTFS_MAGIC 0x42494e4d
- 868 : #define BTRFS_SUPER_MAGIC 0x9123683E
- 869 : #define CGROUP_SUPER_MAGIC 0x27e0eb
- 870 : #define CIFS_MAGIC_NUMBER 0xFF534D42
- 871 : #define CODA_SUPER_MAGIC 0x73757245
- 872 : #define COH_SUPER_MAGIC 0x012FF7B7
- 873 : #define CRAMFS_MAGIC 0x28cd3d45
- 874 : #define DEBUGFS_MAGIC 0x64626720
- 875 : #define DEVFS_SUPER_MAGIC 0x1373
- 876 : #define DEVPTS_SUPER_MAGIC 0x1cd1
- 877 : #define EFIVARFS_MAGIC 0xde5e81e4
- 878 : #define EFS_SUPER_MAGIC 0x00414A53
- 879 : #define EXT_SUPER_MAGIC 0x137D
- 880 : #define EXT2_OLD_SUPER_MAGIC 0xEF51
- 881 : #define EXT4_SUPER_MAGIC 0xEF53 /* also ext2/ext3 */
- 882 : #define FUSE_SUPER_MAGIC 0x65735546
- 883 : #define FUTEXFS_SUPER_MAGIC 0xBAD1DEA
- 884 : #define HFS_SUPER_MAGIC 0x4244
- 885 : #define HFSPLUS_SUPER_MAGIC 0x482b
- 886 : #define HOSTFS_SUPER_MAGIC 0x00c0ffee
- 887 : #define HPFS_SUPER_MAGIC 0xF995E849
- 888 : #define HUGETLBFS_MAGIC 0x958458f6
- 889 : #define ISOFS_SUPER_MAGIC 0x9660
- 890 : #define JFFS2_SUPER_MAGIC 0x72b6
- 891 : #define JFS_SUPER_MAGIC 0x3153464a
- 892 : #define MINIX_SUPER_MAGIC 0x137F
- 893 : #define MINIX_SUPER_MAGIC2 0x138F
- 894 : #define MINIX2_SUPER_MAGIC 0x2468
- 895 : #define MINIX2_SUPER_MAGIC2 0x2478
- 896 : #define MINIX3_SUPER_MAGIC 0x4d5a
- 897 : #define MQUEUE_MAGIC 0x19800202
- 898 : #define MSDOS_SUPER_MAGIC 0x4d44
- 899 : #define NCP_SUPER_MAGIC 0x564c
- 900 : #define NFS_SUPER_MAGIC 0x6969
- 901 : #define NILFS_SUPER_MAGIC 0x3434
- 902 : #define NTFS_SB_MAGIC 0x5346544e
- 903 : #define OCFS2_SUPER_MAGIC 0x7461636f
- 904 : #define OPENPROM_SUPER_MAGIC 0x9fa1
- 905 : #define PIPEFS_MAGIC 0x50495045
- 906 : #define PROC_SUPER_MAGIC 0x9fa0
- 907 : #define PSTOREFS_MAGIC 0x6165676C
- 908 : #define QNX4_SUPER_MAGIC 0x002f
- 909 : #define QNX6_SUPER_MAGIC 0x68191122
- 910 : #define RAMFS_MAGIC 0x858458f6
- 911 : #define REISERFS_SUPER_MAGIC 0x52654973
- 912 : #define ROMFS_MAGIC 0x7275
- 913 : #define SELINUX_MAGIC 0xf97cff8c
- 914 : #define SMACK_MAGIC 0x43415d53
- 915 : #define SMB_SUPER_MAGIC 0x517B
- 916 : #define SOCKFS_MAGIC 0x534F434B
- 917 : #define SQUASHFS_MAGIC 0x73717368
- 918 : #define SYSFS_MAGIC 0x62656572
- 919 : #define SYSV2_SUPER_MAGIC 0x012FF7B6
- 920 : #define SYSV4_SUPER_MAGIC 0x012FF7B5
- 921 : #define TMPFS_MAGIC 0x01021994
- 922 : #define UDF_SUPER_MAGIC 0x15013346
- 923 : #define UFS_MAGIC 0x00011954
- 924 : #define USBDEVICE_SUPER_MAGIC 0x9fa2
- 925 : #define V9FS_MAGIC 0x01021997
- 926 : #define VXFS_SUPER_MAGIC 0xa501FCF5
- 927 : #define XENFS_SUPER_MAGIC 0xabba1974
- 928 : #define XENIX_SUPER_MAGIC 0x012FF7B4
- 929 : #define XFS_SUPER_MAGIC 0x58465342
- 930 : #define _XIAFS_SUPER_MAGIC 0x012FD16D
- 931 : #define AFS_SUPER_MAGIC 0x5346414F
- 932 : #define AUFS_SUPER_MAGIC 0x61756673
- 933 : #define ANON_INODE_FS_SUPER_MAGIC 0x09041934
- 934 : #define CEPH_SUPER_MAGIC 0x00C36400
- 935 : #define ECRYPTFS_SUPER_MAGIC 0xF15F
- 936 : #define FAT_SUPER_MAGIC 0x4006
- 937 : #define FHGFS_SUPER_MAGIC 0x19830326
- 938 : #define FUSEBLK_SUPER_MAGIC 0x65735546
- 939 : #define FUSECTL_SUPER_MAGIC 0x65735543
- 940 : #define GFS_SUPER_MAGIC 0x1161970
- 941 : #define GPFS_SUPER_MAGIC 0x47504653
- 942 : #define MTD_INODE_FS_SUPER_MAGIC 0x11307854
- 943 : #define INOTIFYFS_SUPER_MAGIC 0x2BAD1DEA
- 944 : #define ISOFS_R_WIN_SUPER_MAGIC 0x4004
- 945 : #define ISOFS_WIN_SUPER_MAGIC 0x4000
- 946 : #define JFFS_SUPER_MAGIC 0x07C0
- 947 : #define KAFS_SUPER_MAGIC 0x6B414653
- 948 : #define LUSTRE_SUPER_MAGIC 0x0BD00BD0
- 949 : #define NFSD_SUPER_MAGIC 0x6E667364
- 950 : #define PANFS_SUPER_MAGIC 0xAAD7AAEA
- 951 : #define RPC_PIPEFS_SUPER_MAGIC 0x67596969
- 952 : #define SECURITYFS_SUPER_MAGIC 0x73636673
- 953 : #define UFS_BYTESWAPPED_SUPER_MAGIC 0x54190100
- 954 : #define VMHGFS_SUPER_MAGIC 0xBACBACBC
- 955 : #define VZFS_SUPER_MAGIC 0x565A4653
- 956 : #define ZFS_SUPER_MAGIC 0x2FC12FC1
- 957 :
- 958 : struct filesystem_entry {
- 959 : unsigned id;
- 960 : const char* name;
- 961 : int remote;
- 962 : } FILESYSTEMS[] = {
- 963 : { ADFS_SUPER_MAGIC, "adfs", 0 },
- 964 : { AFFS_SUPER_MAGIC, "affs", 0 },
- 965 : { AFS_SUPER_MAGIC, "afs", 1 },
- 966 : { AUFS_SUPER_MAGIC, "aufs", 1 },
- 967 : { BEFS_SUPER_MAGIC, "befs", 0 },
- 968 : { BDEVFS_MAGIC, "bdevfs", 0 },
- 969 : { BFS_MAGIC, "bfs", 0 },
- 970 : { BINFMTFS_MAGIC, "binfmt_misc", 0 },
- 971 : { BTRFS_SUPER_MAGIC, "btrfs", 0 },
- 972 : { CEPH_SUPER_MAGIC, "ceph", 1 },
- 973 : { CGROUP_SUPER_MAGIC, "cgroupfs", 0 },
- 974 : { CIFS_MAGIC_NUMBER, "cifs", 1 },
- 975 : { CODA_SUPER_MAGIC, "coda", 1 },
- 976 : { COH_SUPER_MAGIC, "coh", 0 },
- 977 : { CRAMFS_MAGIC, "cramfs", 0 },
- 978 : { DEBUGFS_MAGIC, "debugfs", 0 },
- 979 : { DEVFS_SUPER_MAGIC, "devfs", 0 },
- 980 : { DEVPTS_SUPER_MAGIC, "devpts", 0 },
- 981 : { ECRYPTFS_SUPER_MAGIC, "ecryptfs", 0 },
- 982 : { EFS_SUPER_MAGIC, "efs", 0 },
- 983 : { EXT_SUPER_MAGIC, "ext", 0 },
- 984 : { EXT4_SUPER_MAGIC, "ext4", 0 },
- 985 : { EXT2_OLD_SUPER_MAGIC, "ext2", 0 },
- 986 : { FAT_SUPER_MAGIC, "fat", 0 },
- 987 : { FHGFS_SUPER_MAGIC, "fhgfs", 1 },
- 988 : { FUSEBLK_SUPER_MAGIC, "fuseblk", 1 },
- 989 : { FUSECTL_SUPER_MAGIC, "fusectl", 1 },
- 990 : { FUTEXFS_SUPER_MAGIC, "futexfs", 0 },
- 991 : { GFS_SUPER_MAGIC, "gfs/gfs2", 1 },
- 992 : { GPFS_SUPER_MAGIC, "gpfs", 1 },
- 993 : { HFS_SUPER_MAGIC, "hfs", 0 },
- 994 : { HFSPLUS_SUPER_MAGIC, "hfsplus", 0 },
- 995 : { HPFS_SUPER_MAGIC, "hpfs", 0 },
- 996 : { HUGETLBFS_MAGIC, "hugetlbfs", 0 },
- 997 : { MTD_INODE_FS_SUPER_MAGIC, "inodefs", 0 },
- 998 : { INOTIFYFS_SUPER_MAGIC, "inotifyfs", 0 },
- 999 : { ISOFS_SUPER_MAGIC, "isofs", 0 },
- 1000 : { ISOFS_R_WIN_SUPER_MAGIC, "isofs", 0 },
- 1001 : { ISOFS_WIN_SUPER_MAGIC, "isofs", 0 },
- 1002 : { JFFS_SUPER_MAGIC, "jffs", 0 },
- 1003 : { JFFS2_SUPER_MAGIC, "jffs2", 0 },
- 1004 : { JFS_SUPER_MAGIC, "jfs", 0 },
- 1005 : { KAFS_SUPER_MAGIC, "k-afs", 1 },
- 1006 : { LUSTRE_SUPER_MAGIC, "lustre", 1 },
- 1007 : { MINIX_SUPER_MAGIC, "minix", 0 },
- 1008 : { MINIX_SUPER_MAGIC2, "minix", 0 },
- 1009 : { MINIX2_SUPER_MAGIC, "minix2", 0 },
- 1010 : { MINIX2_SUPER_MAGIC2, "minix2", 0 },
- 1011 : { MINIX3_SUPER_MAGIC, "minix3", 0 },
- 1012 : { MQUEUE_MAGIC, "mqueue", 0 },
- 1013 : { MSDOS_SUPER_MAGIC, "msdos", 0 },
- 1014 : { NCP_SUPER_MAGIC, "novell", 1 },
- 1015 : { NFS_SUPER_MAGIC, "nfs", 1 },
- 1016 : { NFSD_SUPER_MAGIC, "nfsd", 1 },
- 1017 : { NILFS_SUPER_MAGIC, "nilfs", 0 },
- 1018 : { NTFS_SB_MAGIC, "ntfs", 0 },
- 1019 : { OPENPROM_SUPER_MAGIC, "openprom", 0 },
- 1020 : { OCFS2_SUPER_MAGIC, "ocfs2", 1 },
- 1021 : { PANFS_SUPER_MAGIC, "panfs", 1 },
- 1022 : { PIPEFS_MAGIC, "pipefs", 1 },
- 1023 : { PROC_SUPER_MAGIC, "proc", 0 },
- 1024 : { PSTOREFS_MAGIC, "pstorefs", 0 },
- 1025 : { QNX4_SUPER_MAGIC, "qnx4", 0 },
- 1026 : { QNX6_SUPER_MAGIC, "qnx6", 0 },
- 1027 : { RAMFS_MAGIC, "ramfs", 0 },
- 1028 : { REISERFS_SUPER_MAGIC, "reiserfs", 0 },
- 1029 : { ROMFS_MAGIC, "romfs", 0 },
- 1030 : { RPC_PIPEFS_SUPER_MAGIC, "rpc_pipefs", 0 },
- 1031 : { SECURITYFS_SUPER_MAGIC, "securityfs", 0 },
- 1032 : { SELINUX_MAGIC, "selinux", 0 },
- 1033 : { SMB_SUPER_MAGIC, "smb", 1 },
- 1034 : { SOCKFS_MAGIC, "sockfs", 0 },
- 1035 : { SQUASHFS_MAGIC, "squashfs", 0 },
- 1036 : { SYSFS_MAGIC, "sysfs", 0 },
- 1037 : { SYSV2_SUPER_MAGIC, "sysv2", 0 },
- 1038 : { SYSV4_SUPER_MAGIC, "sysv4", 0 },
- 1039 : { TMPFS_MAGIC, "tmpfs", 0 },
- 1040 : { UDF_SUPER_MAGIC, "udf", 0 },
- 1041 : { UFS_MAGIC, "ufs", 0 },
- 1042 : { UFS_BYTESWAPPED_SUPER_MAGIC, "ufs", 0 },
- 1043 : { USBDEVICE_SUPER_MAGIC, "usbdevfs", 0 },
- 1044 : { V9FS_MAGIC, "v9fs", 0 },
- 1045 : { VMHGFS_SUPER_MAGIC, "vmhgfs", 1 },
- 1046 : { VXFS_SUPER_MAGIC, "vxfs", 0 },
- 1047 : { VZFS_SUPER_MAGIC, "vzfs", 0 },
- 1048 : { XENFS_SUPER_MAGIC, "xenfs", 0 },
- 1049 : { XENIX_SUPER_MAGIC, "xenix", 0 },
- 1050 : { XFS_SUPER_MAGIC, "xfs", 0 },
- 1051 : { _XIAFS_SUPER_MAGIC, "xia", 0 },
- 1052 : { ZFS_SUPER_MAGIC, "zfs", 0 },
- 1053 : { 0 }
- 1054 : };
- 1055 :
- 1056 6412 : int fsinfo(const char* path, int* has_persistent_inode, int* has_syncronized_hardlinks, uint64_t* total_space, uint64_t* free_space, char* fstype, size_t fstype_size, char* fslabel, size_t fslabel_size)
- 1057 : {
- 1058 : #if HAVE_STATFS
- 1059 : struct statfs st;
- 1060 :
- 1061 6412 : if (statfs(path, &st) != 0) {
- 1062 : char dir[PATH_MAX];
- 1063 : char* slash;
- 1064 :
- 1065 48 : if (errno != ENOENT) {
- 1066 0 : return -1;
- 1067 : }
- 1068 :
- 1069 : /* if it doesn't exist, we assume a file */
- 1070 : /* and we check for the containing dir */
- 1071 48 : if (strlen(path) + 1 > sizeof(dir)) {
- 1072 0 : errno = ENAMETOOLONG;
- 1073 0 : return -1;
- 1074 : }
- 1075 :
- 1076 48 : strcpy(dir, path);
- 1077 :
- 1078 48 : slash = strrchr(dir, '/');
- 1079 48 : if (!slash)
- 1080 0 : return -1;
- 1081 :
- 1082 48 : *slash = 0;
- 1083 48 : if (statfs(dir, &st) != 0)
- 1084 0 : return -1;
- 1085 : }
- 1086 : #endif
- 1087 :
- 1088 : /* to get the fs type check "man stat" or "stat -f -t FILE" */
- 1089 6412 : if (has_persistent_inode) {
- 1090 : #if HAVE_STATFS && HAVE_STRUCT_STATFS_F_TYPE
- 1091 605 : switch (st.f_type) {
- 1092 0 : case FUSEBLK_SUPER_MAGIC : /* FUSE, "fuseblk" in the stat command */
- 1093 : case MSDOS_SUPER_MAGIC : /* VFAT, "msdos" in the stat command */
- 1094 0 : *has_persistent_inode = 0;
- 1095 0 : break;
- 1096 605 : default :
- 1097 : /* by default assume yes */
- 1098 605 : *has_persistent_inode = 1;
- 1099 605 : break;
- 1100 : }
- 1101 : #else
- 1102 : /* in Unix inodes are persistent by default */
- 1103 : *has_persistent_inode = 1;
- 1104 : #endif
- 1105 : }
- 1106 :
- 1107 6412 : if (has_syncronized_hardlinks) {
- 1108 : #if HAVE_STATFS && HAVE_STRUCT_STATFS_F_TYPE
- 1109 605 : switch (st.f_type) {
- 1110 0 : case NTFS_SB_MAGIC : /* NTFS */
- 1111 : case MSDOS_SUPER_MAGIC : /* VFAT, "msdos" in the stat command */
- 1112 0 : *has_syncronized_hardlinks = 0;
- 1113 0 : break;
- 1114 605 : default :
- 1115 : /* by default assume yes */
- 1116 605 : *has_syncronized_hardlinks = 1;
- 1117 605 : break;
- 1118 : }
- 1119 : #else
- 1120 : /* in Unix hardlinks share the same metadata by default */
- 1121 : *has_syncronized_hardlinks = 1;
- 1122 : #endif
- 1123 : }
- 1124 :
- 1125 6412 : if (total_space) {
- 1126 : #if HAVE_STATFS
- 1127 5807 : *total_space = st.f_bsize * (uint64_t)st.f_blocks;
- 1128 : #else
- 1129 : *total_space = 0;
- 1130 : #endif
- 1131 : }
- 1132 :
- 1133 6412 : if (free_space) {
- 1134 : #if HAVE_STATFS
- 1135 5807 : *free_space = st.f_bsize * (uint64_t)st.f_bfree;
- 1136 : #else
- 1137 : *free_space = 0;
- 1138 : #endif
- 1139 : }
- 1140 :
- 1141 6412 : const char* ptype = 0;
- 1142 :
- 1143 : #if HAVE_STATFS && HAVE_STRUCT_STATFS_F_FSTYPENAME
- 1144 : /* get the filesystem type directly from the struct (Mac OS X) */
- 1145 : ptype = st.f_fstypename;
- 1146 : #elif HAVE_STATFS && HAVE_STRUCT_STATFS_F_TYPE
- 1147 : /* get the filesystem type from f_type (Linux) */
- 1148 : /* from: https://github.com/influxdata/gopsutil/blob/master/disk/disk_linux.go */
- 1149 141064 : for (int i = 0; FILESYSTEMS[i].id != 0; ++i) {
- 1150 141064 : if (st.f_type == FILESYSTEMS[i].id) {
- 1151 6412 : ptype = FILESYSTEMS[i].name;
- 1152 6412 : break;
- 1153 : }
- 1154 : }
- 1155 : #endif
- 1156 :
- 1157 6412 : if (fstype) {
- 1158 5807 : fstype[0] = 0;
- 1159 5807 : if (ptype)
- 1160 5807 : snprintf(fstype, fstype_size, "%s", ptype);
- 1161 : }
- 1162 :
- 1163 6412 : if (fslabel) {
- 1164 5807 : fslabel[0] = 0;
- 1165 : #if HAVE_BLKID
- 1166 : struct stat fst;
- 1167 5807 : if (stat(path, &fst) == 0)
- 1168 5759 : devuuid_label(fst.st_dev, fslabel, fslabel_size);
- 1169 : #else
- 1170 : (void)fslabel_size;
- 1171 : #endif
- 1172 : }
- 1173 :
- 1174 6412 : return 0;
- 1175 : }
- 1176 :
- 1177 3817826 : uint64_t tick(void)
- 1178 : {
- 1179 : #if HAVE_MACH_ABSOLUTE_TIME
- 1180 : /* for Mac OS X */
- 1181 : return mach_absolute_time();
- 1182 : #elif HAVE_CLOCK_GETTIME && (defined(CLOCK_MONOTONIC) || defined(CLOCK_MONOTONIC_RAW))
- 1183 : /* for Linux */
- 1184 : struct timespec tv;
- 1185 :
- 1186 : /* nanosecond precision with clock_gettime() */
- 1187 : #if defined(CLOCK_MONOTONIC_RAW)
- 1188 3817826 : if (clock_gettime(CLOCK_MONOTONIC_RAW, &tv) != 0) {
- 1189 : #else
- 1190 : if (clock_gettime(CLOCK_MONOTONIC, &tv) != 0) {
- 1191 : #endif
- 1192 0 : return 0;
- 1193 : }
- 1194 :
- 1195 3817826 : return tv.tv_sec * 1000000000ULL + tv.tv_nsec;
- 1196 : #else
- 1197 : /* other platforms */
- 1198 : struct timeval tv;
- 1199 :
- 1200 : /* microsecond precision with gettimeofday() */
- 1201 : if (gettimeofday(&tv, 0) != 0) {
- 1202 : return 0;
- 1203 : }
- 1204 :
- 1205 : return tv.tv_sec * 1000000ULL + tv.tv_usec;
- 1206 : #endif
- 1207 : }
- 1208 :
- 1209 3581 : uint64_t tick_ms(void)
- 1210 : {
- 1211 : struct timeval tv;
- 1212 :
- 1213 3581 : if (gettimeofday(&tv, 0) != 0)
- 1214 0 : return 0;
- 1215 :
- 1216 3581 : return tv.tv_sec * 1000ULL + tv.tv_usec / 1000;
- 1217 : }
- 1218 :
- 1219 294 : int randomize(void* ptr, size_t size)
- 1220 : {
- 1221 : int f;
- 1222 : ssize_t ret;
- 1223 :
- 1224 294 : f = open("/dev/urandom", O_RDONLY);
- 1225 294 : if (f == -1)
- 1226 0 : return -1;
- 1227 :
- 1228 294 : ret = read(f, ptr, size);
- 1229 294 : if (ret < 0 || (size_t)ret != size) {
- 1230 0 : close(f);
- 1231 0 : return -1;
- 1232 : }
- 1233 :
- 1234 294 : if (close(f) != 0)
- 1235 0 : return -1;
- 1236 :
- 1237 294 : return 0;
- 1238 : }
- 1239 :
- 1240 : /**
- 1241 : * Read a file extracting the contained device number in %u:%u format.
- 1242 : * Return 0 on error.
- 1243 : */
- 1244 : #if HAVE_LINUX_DEVICE
- 1245 130 : static dev_t devread(const char* path)
- 1246 : {
- 1247 : int f;
- 1248 : int ret;
- 1249 : int len;
- 1250 : char buf[64];
- 1251 : char* e;
- 1252 : unsigned ma;
- 1253 : unsigned mi;
- 1254 :
- 1255 130 : f = open(path, O_RDONLY);
- 1256 130 : if (f == -1) {
- 1257 : /* LCOV_EXCL_START */
- 1258 : log_fatal(errno, "Failed to open '%s'.\n", path);
- 1259 : return 0;
- 1260 : /* LCOV_EXCL_STOP */
- 1261 : }
- 1262 :
- 1263 130 : len = read(f, buf, sizeof(buf));
- 1264 130 : if (len < 0) {
- 1265 : /* LCOV_EXCL_START */
- 1266 : close(f);
- 1267 : log_fatal(errno, "Failed to read '%s'.\n", path);
- 1268 : return 0;
- 1269 : /* LCOV_EXCL_STOP */
- 1270 : }
- 1271 130 : if (len == sizeof(buf)) {
- 1272 : /* LCOV_EXCL_START */
- 1273 : close(f);
- 1274 : log_fatal(EEXTERNAL, "Too long read '%s'.\n", path);
- 1275 : return 0;
- 1276 : /* LCOV_EXCL_STOP */
- 1277 : }
- 1278 :
- 1279 130 : ret = close(f);
- 1280 130 : if (ret != 0) {
- 1281 : /* LCOV_EXCL_START */
- 1282 : log_fatal(errno, "Failed to close '%s'.\n", path);
- 1283 : return 0;
- 1284 : /* LCOV_EXCL_STOP */
- 1285 : }
- 1286 :
- 1287 130 : buf[len] = 0;
- 1288 :
- 1289 130 : ma = strtoul(buf, &e, 10);
- 1290 130 : if (*e != ':') {
- 1291 : /* LCOV_EXCL_START */
- 1292 : log_fatal(EEXTERNAL, "Invalid format in '%s' for '%s'.\n", path, buf);
- 1293 : return 0;
- 1294 : /* LCOV_EXCL_STOP */
- 1295 : }
- 1296 :
- 1297 130 : mi = strtoul(e + 1, &e, 10);
- 1298 130 : if (*e != 0 && !isspace(*e)) {
- 1299 : /* LCOV_EXCL_START */
- 1300 : log_fatal(EEXTERNAL, "Invalid format in '%s' for '%s'.\n", path, buf);
- 1301 : return 0;
- 1302 : /* LCOV_EXCL_STOP */
- 1303 : }
- 1304 :
- 1305 130 : return makedev(ma, mi);
- 1306 : }
- 1307 : #endif
- 1308 :
- 1309 : /**
- 1310 : * Read a device tree filling the specified list of disk_t entries.
- 1311 : */
- 1312 : #if HAVE_LINUX_DEVICE
- 1313 130 : static int devtree(devinfo_t* parent, dev_t device, tommy_list* list)
- 1314 : {
- 1315 : char path[PATH_MAX];
- 1316 : DIR* d;
- 1317 130 : int slaves = 0;
- 1318 :
- 1319 130 : pathprint(path, sizeof(path), "/sys/dev/block/%u:%u/slaves", major(device), minor(device));
- 1320 :
- 1321 : /* check if there is a slaves list */
- 1322 130 : d = opendir(path);
- 1323 130 : if (d != 0) {
- 1324 : struct dirent* dd;
- 1325 :
- 1326 260 : while ((dd = readdir(d)) != 0) {
- 1327 195 : if (dd->d_name[0] != '.') {
- 1328 : dev_t subdev;
- 1329 :
- 1330 : /* for each slave, expand the full potential tree */
- 1331 65 : pathprint(path, sizeof(path), "/sys/dev/block/%u:%u/slaves/%s/dev", major(device), minor(device), dd->d_name);
- 1332 :
- 1333 65 : subdev = devread(path);
- 1334 65 : if (!subdev) {
- 1335 : /* LCOV_EXCL_START */
- 1336 : closedir(d);
- 1337 : return -1;
- 1338 : /* LCOV_EXCL_STOP */
- 1339 : }
- 1340 :
- 1341 65 : if (devtree(parent, subdev, list) != 0) {
- 1342 : /* LCOV_EXCL_START */
- 1343 : closedir(d);
- 1344 : return -1;
- 1345 : /* LCOV_EXCL_STOP */
- 1346 : }
- 1347 :
- 1348 65 : ++slaves;
- 1349 : }
- 1350 : }
- 1351 :
- 1352 65 : closedir(d);
- 1353 : }
- 1354 :
- 1355 : /* if no slaves found */
- 1356 130 : if (!slaves) {
- 1357 : /* this is a raw device */
- 1358 : devinfo_t* devinfo;
- 1359 :
- 1360 : /* check if it's a real device */
- 1361 65 : pathprint(path, sizeof(path), "/sys/dev/block/%u:%u/device", major(device), minor(device));
- 1362 65 : if (access(path, F_OK) != 0) {
- 1363 : /* get the parent device */
- 1364 65 : pathprint(path, sizeof(path), "/sys/dev/block/%u:%u/../dev", major(device), minor(device));
- 1365 :
- 1366 65 : device = devread(path);
- 1367 65 : if (!device) {
- 1368 : /* LCOV_EXCL_START */
- 1369 : return -1;
- 1370 : /* LCOV_EXCL_STOP */
- 1371 : }
- 1372 : }
- 1373 :
- 1374 : /* get the device file */
- 1375 65 : if (devresolve(device, path, sizeof(path)) != 0) {
- 1376 : /* LCOV_EXCL_START */
- 1377 : log_fatal(EEXTERNAL, "Failed to resolve device '%u:%u'.\n", major(device), minor(device));
- 1378 : return -1;
- 1379 : /* LCOV_EXCL_STOP */
- 1380 : }
- 1381 :
- 1382 65 : devinfo = calloc_nofail(1, sizeof(devinfo_t));
- 1383 :
- 1384 65 : devinfo->device = device;
- 1385 65 : pathcpy(devinfo->name, sizeof(devinfo->name), parent->name);
- 1386 65 : pathcpy(devinfo->smartctl, sizeof(devinfo->smartctl), parent->smartctl);
- 1387 65 : memcpy(devinfo->smartignore, parent->smartignore, sizeof(devinfo->smartignore));
- 1388 65 : pathcpy(devinfo->file, sizeof(devinfo->file), path);
- 1389 65 : devinfo->parent = parent;
- 1390 :
- 1391 : /* insert in the list */
- 1392 65 : tommy_list_insert_tail(list, &devinfo->node, devinfo);
- 1393 : }
- 1394 :
- 1395 130 : return 0;
- 1396 : }
- 1397 : #endif
- 1398 :
- 1399 : /**
- 1400 : * Scan all the devices.
- 1401 : *
- 1402 : * If a device is already in, it's not added again.
- 1403 : */
- 1404 : #if HAVE_LINUX_DEVICE
- 1405 0 : static int devscan(tommy_list* list)
- 1406 : {
- 1407 : char dir[PATH_MAX];
- 1408 : DIR* d;
- 1409 : struct dirent* dd;
- 1410 :
- 1411 0 : pathprint(dir, sizeof(dir), "/sys/dev/block/");
- 1412 :
- 1413 : /* check if there is a slaves list */
- 1414 0 : d = opendir(dir);
- 1415 0 : if (d == 0) {
- 1416 : /* LCOV_EXCL_START */
- 1417 : log_fatal(errno, "Failed to open dir '%s'.\n", dir);
- 1418 : return -1;
- 1419 : /* LCOV_EXCL_STOP */
- 1420 : }
- 1421 :
- 1422 0 : while ((dd = readdir(d)) != 0) {
- 1423 : char path[PATH_MAX];
- 1424 : tommy_node* i;
- 1425 : dev_t device;
- 1426 : devinfo_t* devinfo;
- 1427 :
- 1428 0 : if (dd->d_name[0] == '.')
- 1429 0 : continue;
- 1430 :
- 1431 0 : pathprint(path, sizeof(path), "/sys/dev/block/%s/device", dd->d_name);
- 1432 :
- 1433 : /* check if it's a real device */
- 1434 0 : if (access(path, F_OK) != 0)
- 1435 0 : continue;
- 1436 :
- 1437 0 : pathprint(path, sizeof(path), "/sys/dev/block/%s/dev", dd->d_name);
- 1438 :
- 1439 0 : device = devread(path);
- 1440 0 : if (!device) {
- 1441 : /* LCOV_EXCL_START */
- 1442 : log_tag("scan:skip: Skipping device %s because failed to read its device number.\n", dd->d_name);
- 1443 : continue;
- 1444 : /* LCOV_EXCL_STOP */
- 1445 : }
- 1446 :
- 1447 : /* check if already present */
- 1448 0 : for (i = tommy_list_head(list); i != 0; i = i->next) {
- 1449 0 : devinfo = i->data;
- 1450 0 : if (devinfo->device == device)
- 1451 0 : break;
- 1452 : }
- 1453 :
- 1454 : /* if already present */
- 1455 0 : if (i != 0)
- 1456 0 : continue;
- 1457 :
- 1458 : /* get the device file */
- 1459 0 : if (devresolve(device, path, sizeof(path)) != 0) {
- 1460 : /* LCOV_EXCL_START */
- 1461 : log_tag("scan:skip: Skipping device %u:%u because failed to resolve.\n", major(device), minor(device));
- 1462 : continue;
- 1463 : /* LCOV_EXCL_STOP */
- 1464 : }
- 1465 :
- 1466 0 : devinfo = calloc_nofail(1, sizeof(devinfo_t));
- 1467 :
- 1468 0 : devinfo->device = device;
- 1469 0 : pathcpy(devinfo->file, sizeof(devinfo->file), path);
- 1470 :
- 1471 : /* insert in the list */
- 1472 0 : tommy_list_insert_tail(list, &devinfo->node, devinfo);
- 1473 : }
- 1474 :
- 1475 0 : closedir(d);
- 1476 0 : return 0;
- 1477 : }
- 1478 : #endif
- 1479 :
- 1480 : /**
- 1481 : * Get SMART attributes.
- 1482 : */
- 1483 : #if HAVE_LINUX_DEVICE
- 1484 0 : static int devsmart(dev_t device, const char* name, const char* smartctl, struct smart_attr* smart, uint64_t* info, char* serial, char* family, char* model, char* interface)
- 1485 : {
- 1486 : char cmd[PATH_MAX + 64];
- 1487 : char file[PATH_MAX];
- 1488 : FILE* f;
- 1489 : int ret;
- 1490 : const char* x;
- 1491 :
- 1492 0 : x = find_smartctl();
- 1493 0 : if (!x) {
- 1494 : /* LCOV_EXCL_START */
- 1495 : log_fatal(EEXTERNAL, "Cannot find smartctl.\n");
- 1496 : return -1;
- 1497 : /* LCOV_EXCL_STOP */
- 1498 : }
- 1499 :
- 1500 0 : if (devresolve(device, file, sizeof(file)) != 0) {
- 1501 : /* LCOV_EXCL_START */
- 1502 : log_fatal(EEXTERNAL, "Failed to resolve device '%u:%u'.\n", major(device), minor(device));
- 1503 : return -1;
- 1504 : /* LCOV_EXCL_STOP */
- 1505 : }
- 1506 :
- 1507 : /* if there is a custom smartctl command */
- 1508 0 : if (smartctl[0]) {
- 1509 : char option[PATH_MAX];
- 1510 0 : snprintf(option, sizeof(option), smartctl, file);
- 1511 0 : snprintf(cmd, sizeof(cmd), "%s -a %s", x, option);
- 1512 : } else {
- 1513 0 : snprintf(cmd, sizeof(cmd), "%s -a %s", x, file);
- 1514 : }
- 1515 :
- 1516 0 : log_tag("smartctl:%s:%s:run: %s\n", file, name, cmd);
- 1517 :
- 1518 0 : f = popen(cmd, "r");
- 1519 0 : if (!f) {
- 1520 : /* LCOV_EXCL_START */
- 1521 : log_tag("device:%s:%s:shell\n", file, name);
- 1522 : log_fatal(EEXTERNAL, "Failed to run '%s' (from popen).\n", cmd);
- 1523 : return -1;
- 1524 : /* LCOV_EXCL_STOP */
- 1525 : }
- 1526 :
- 1527 0 : if (smartctl_attribute(f, file, name, smart, info, serial, family, model, interface) != 0) {
- 1528 : /* LCOV_EXCL_START */
- 1529 : pclose(f);
- 1530 : log_tag("device:%s:%s:shell\n", file, name);
- 1531 : return -1;
- 1532 : /* LCOV_EXCL_STOP */
- 1533 : }
- 1534 :
- 1535 0 : ret = pclose(f);
- 1536 :
- 1537 0 : log_tag("smartctl:%s:%s:ret: %x\n", file, name, ret);
- 1538 :
- 1539 0 : if (!WIFEXITED(ret)) {
- 1540 : /* LCOV_EXCL_START */
- 1541 : log_tag("device:%s:%s:abort\n", file, name);
- 1542 : log_fatal(EEXTERNAL, "Failed to run '%s' (not exited).\n", cmd);
- 1543 : return -1;
- 1544 : /* LCOV_EXCL_STOP */
- 1545 : }
- 1546 0 : if (WEXITSTATUS(ret) == 127) {
- 1547 : /* LCOV_EXCL_START */
- 1548 : log_tag("device:%s:%s:shell\n", file, name);
- 1549 : log_fatal(EEXTERNAL, "Failed to run '%s' (from sh).\n", cmd);
- 1550 : return -1;
- 1551 : /* LCOV_EXCL_STOP */
- 1552 : }
- 1553 :
- 1554 : /* store the return smartctl return value */
- 1555 0 : smart[SMART_FLAGS].raw = WEXITSTATUS(ret);
- 1556 :
- 1557 0 : return 0;
- 1558 : }
- 1559 : #endif
- 1560 :
- 1561 : /**
- 1562 : * Compute disk usage by aggregating access statistics.
- 1563 : */
- 1564 : #if HAVE_LINUX_DEVICE
- 1565 65 : static int devstat(dev_t device, uint64_t* count)
- 1566 : {
- 1567 : char path[PATH_MAX];
- 1568 : char buf[512];
- 1569 : int token;
- 1570 : int ret;
- 1571 : char* i;
- 1572 :
- 1573 65 : *count = 0;
- 1574 :
- 1575 65 : pathprint(path, sizeof(path), "/sys/dev/block/%u:%u/stat", major(device), minor(device));
- 1576 :
- 1577 65 : ret = sysread(path, buf, sizeof(buf));
- 1578 65 : if (ret < 0) {
- 1579 : /* LCOV_EXCL_START */
- 1580 : log_fatal(errno, "Failed to read '%s'.\n", path);
- 1581 : return -1;
- 1582 : /* LCOV_EXCL_STOP */
- 1583 : }
- 1584 65 : if ((size_t)ret + 1 > sizeof(buf)) {
- 1585 : /* LCOV_EXCL_START */
- 1586 : log_fatal(EEXTERNAL, "Too long read '%s'.\n", path);
- 1587 : return -1;
- 1588 : /* LCOV_EXCL_STOP */
- 1589 : }
- 1590 :
- 1591 : /* ending 0 */
- 1592 65 : buf[ret] = 0;
- 1593 :
- 1594 65 : i = buf;
- 1595 65 : token = 1; /* token number */
- 1596 325 : while (*i) {
- 1597 : char* n;
- 1598 : char* e;
- 1599 : unsigned long long v;
- 1600 :
- 1601 : /* skip spaces */
- 1602 910 : while (*i && isspace(*i))
- 1603 585 : ++i;
- 1604 :
- 1605 : /* read digits */
- 1606 325 : n = i;
- 1607 2405 : while (*i && isdigit(*i))
- 1608 2080 : ++i;
- 1609 :
- 1610 325 : if (i == n) /* if no digit, abort */
- 1611 65 : break;
- 1612 325 : if (*i == 0 || !isspace(*i)) /* if no space, abort */
- 1613 : break;
- 1614 325 : *i++ = 0; /* put a terminator */
- 1615 :
- 1616 325 : v = strtoull(n, &e, 10);
- 1617 325 : if (*e != 0)
- 1618 0 : break;
- 1619 :
- 1620 : /* sum reads and writes completed */
- 1621 325 : if (token == 1 || token == 5) {
- 1622 130 : *count += v;
- 1623 130 : if (token == 5)
- 1624 65 : break; /* stop here */
- 1625 : }
- 1626 :
- 1627 260 : ++token;
- 1628 : }
- 1629 :
- 1630 65 : return 0;
- 1631 : }
- 1632 : #endif
- 1633 :
- 1634 : /**
- 1635 : * Get device attributes.
- 1636 : */
- 1637 : #if HAVE_LINUX_DEVICE
- 1638 0 : static void devattr(dev_t device, uint64_t* info, char* serial, char* family, char* model, char* interface)
- 1639 : {
- 1640 : char path[PATH_MAX];
- 1641 : char buf[512];
- 1642 : int ret;
- 1643 : char* attr;
+ 637 :
+ 638 : #ifdef __APPLE__
+ 639 : static int devuuid_darwin(const char* path, char* uuid, size_t uuid_size)
+ 640 : {
+ 641 : CFStringRef path_apple = 0;
+ 642 : DASessionRef session = 0;
+ 643 : CFURLRef path_appler = 0;
+ 644 : int result = -1;
+ 645 :
+ 646 : *uuid = 0;
+ 647 :
+ 648 : path_apple = CFStringCreateWithCString(kCFAllocatorDefault, path, kCFStringEncodingUTF8);
+ 649 : if (!path_apple)
+ 650 : goto bail;
+ 651 :
+ 652 : session = DASessionCreate(kCFAllocatorDefault);
+ 653 : if (!session)
+ 654 : goto bail;
+ 655 :
+ 656 : path_appler = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, path_apple, kCFURLPOSIXPathStyle, false);
+ 657 : if (!path_appler)
+ 658 : goto bail;
+ 659 :
+ 660 : /* find the mount point */
+ 661 : DADiskRef disk = NULL;
+ 662 : while (path_appler) {
+ 663 : disk = DADiskCreateFromVolumePath(kCFAllocatorDefault, session, path_appler);
+ 664 : if (disk)
+ 665 : break;
+ 666 :
+ 667 : CFURLRef parent = CFURLCreateCopyDeletingLastPathComponent(kCFAllocatorDefault, path_appler);
+ 668 : if (!parent)
+ 669 : break;
+ 670 :
+ 671 : /* check if we hit the root (parent == child) */
+ 672 : if (CFEqual(parent, path_appler)) {
+ 673 : CFRelease(parent);
+ 674 : break;
+ 675 : }
+ 676 :
+ 677 : CFRelease(path_appler);
+ 678 : path_appler = parent;
+ 679 : }
+ 680 :
+ 681 : /* safely extract the UUID */
+ 682 : if (disk) {
+ 683 : CFDictionaryRef description = DADiskCopyDescription(disk);
+ 684 : if (description) {
+ 685 : /* key might not exist for NTFS/ExFAT on some drivers */
+ 686 : const void* value = (CFUUIDRef)CFDictionaryGetValue(description, kDADiskDescriptionVolumeUUIDKey);
+ 687 : CFStringRef uuid_string = NULL;
+ 688 :
+ 689 : if (value) {
+ 690 : if (CFGetTypeID(value) == CFUUIDGetTypeID()) {
+ 691 : uuid_string = CFUUIDCreateString(kCFAllocatorDefault, (CFUUIDRef)value);
+ 692 : } else if (CFGetTypeID(value) == CFStringGetTypeID()) {
+ 693 : /* if it's already a string, retain it so we can release it later consistently */
+ 694 : uuid_string = (CFStringRef)CFRetain(value);
+ 695 : }
+ 696 : }
+ 697 :
+ 698 : if (uuid_string) {
+ 699 : if (CFStringGetCString(uuid_string, uuid, uuid_size, kCFStringEncodingUTF8)) {
+ 700 : result = 0; /* success */
+ 701 : }
+ 702 : CFRelease(uuid_string);
+ 703 : }
+ 704 :
+ 705 : CFRelease(description);
+ 706 : }
+ 707 : CFRelease(disk);
+ 708 : }
+ 709 :
+ 710 : bail:
+ 711 : /* clean up */
+ 712 : if (path_appler) CFRelease(path_appler);
+ 713 : if (session) CFRelease(session);
+ 714 : if (path_apple) CFRelease(path_apple);
+ 715 :
+ 716 : return result;
+ 717 : }
+ 718 : #endif
+ 719 :
+ 720 10560 : int devuuid(uint64_t device, const char* path, char* uuid, size_t uuid_size)
+ 721 : {
+ 722 : (void)path;
+ 723 : (void)device;
+ 724 :
+ 725 : #ifdef __APPLE__
+ 726 : if (devuuid_darwin(path, uuid, uuid_size) == 0)
+ 727 : return 0;
+ 728 : #endif
+ 729 :
+ 730 : #if HAVE_LINUX_DEVICE
+ 731 : /* if the major is the null device */
+ 732 10560 : if (major(device) == 0) {
+ 733 : /* obtain the real device */
+ 734 4 : if (devdereference(device, &device) != 0) {
+ 735 : /* LCOV_EXCL_START */
+ 736 : return -1;
+ 737 : /* LCOV_EXCL_STOP */
+ 738 : }
+ 739 : }
+ 740 : #endif
+ 741 :
+ 742 : /* first try with the /dev/disk/by-uuid version */
+ 743 : #if HAVE_LINUX_DEVICE
+ 744 10556 : if (devuuid_dev(device, uuid, uuid_size) == 0)
+ 745 10556 : return 0;
+ 746 : #else
+ 747 : log_tag("uuid:by-uuid:%u:%u: by-uuid not supported\n", major(device), minor(device));
+ 748 : #endif
+ 749 :
+ 750 : /* fall back to blkid for other cases */
+ 751 : #if HAVE_BLKID
+ 752 0 : if (devuuid_blkid(device, uuid, uuid_size) == 0)
+ 753 0 : return 0;
+ 754 : #else
+ 755 : log_tag("uuid:blkid:%u:%u: blkid support not compiled in\n", major(device), minor(device));
+ 756 : #endif
+ 757 :
+ 758 0 : log_tag("uuid:notfound:%u:%u:\n", major(device), minor(device));
+ 759 :
+ 760 : /* not supported */
+ 761 : (void)uuid;
+ 762 : (void)uuid_size;
+ 763 0 : return -1;
+ 764 : }
+ 765 :
+ 766 11432 : int filephy(const char* path, uint64_t size, uint64_t* physical)
+ 767 : {
+ 768 : #if HAVE_LINUX_FIEMAP_H
+ 769 : /* In Linux get the real physical address of the file */
+ 770 : /* Note that FIEMAP doesn't require root permission */
+ 771 : int f;
+ 772 : struct fiemap* fiemap;
+ 773 : size_t fiemap_size;
+ 774 : unsigned int blknum;
+ 775 :
+ 776 11432 : f = open(path, O_RDONLY);
+ 777 11432 : if (f == -1) {
+ 778 0 : return -1;
+ 779 : }
+ 780 :
+ 781 : /* first try with FIEMAP */
+ 782 : /* if works for ext2, ext3, ext4, xfs, btrfs */
+ 783 11432 : fiemap_size = sizeof(struct fiemap) + sizeof(struct fiemap_extent);
+ 784 11432 : fiemap = malloc_nofail(fiemap_size);
+ 785 11432 : memset(fiemap, 0, fiemap_size);
+ 786 11432 : fiemap->fm_start = 0;
+ 787 11432 : fiemap->fm_length = ~0ULL;
+ 788 11432 : fiemap->fm_flags = FIEMAP_FLAG_SYNC; /* required to ensure that just created files report a valid address and not 0 */
+ 789 11432 : fiemap->fm_extent_count = 1; /* we are interested only at the first block */
+ 790 :
+ 791 11432 : if (ioctl(f, FS_IOC_FIEMAP, fiemap) != -1) {
+ 792 11432 : uint32_t flags = fiemap->fm_extents[0].fe_flags;
+ 793 11432 : uint64_t offset = fiemap->fm_extents[0].fe_physical;
+ 794 :
+ 795 : /* check some condition for validating the offset */
+ 796 11432 : if (flags & FIEMAP_EXTENT_DATA_INLINE) {
+ 797 : /* if the data is inline, we don't have an offset to report */
+ 798 0 : *physical = FILEPHY_WITHOUT_OFFSET;
+ 799 11432 : } else if (flags & FIEMAP_EXTENT_UNKNOWN) {
+ 800 : /* if the offset is unknown, we don't have an offset to report */
+ 801 0 : *physical = FILEPHY_WITHOUT_OFFSET;
+ 802 11432 : } else if (offset == 0) {
+ 803 : /* 0 is the general fallback for file-systems when */
+ 804 : /* they don't have an offset to report */
+ 805 14 : *physical = FILEPHY_WITHOUT_OFFSET;
+ 806 : } else {
+ 807 : /* finally report the real offset */
+ 808 11418 : *physical = offset + FILEPHY_REAL_OFFSET;
+ 809 : }
+ 810 :
+ 811 11432 : if (close(f) == -1)
+ 812 0 : return -1;
+ 813 11432 : return 0;
+ 814 : }
+ 815 :
+ 816 0 : free(fiemap);
+ 817 :
+ 818 : /* if the file is empty, FIBMAP doesn't work, and we don't even try to use it */
+ 819 0 : if (size == 0) {
+ 820 0 : *physical = FILEPHY_WITHOUT_OFFSET;
+ 821 0 : if (close(f) == -1)
+ 822 0 : return -1;
+ 823 0 : return 0;
+ 824 : }
+ 825 :
+ 826 : /* then try with FIBMAP */
+ 827 : /* it works for jfs, reiserfs, ntfs-3g */
+ 828 : /* in exfat it always returns 0, that it's anyway better than the fake inodes */
+ 829 0 : blknum = 0; /* first block */
+ 830 0 : if (ioctl(f, FIBMAP, &blknum) != -1) {
+ 831 0 : *physical = blknum + FILEPHY_REAL_OFFSET;
+ 832 0 : if (close(f) == -1)
+ 833 0 : return -1;
+ 834 0 : return 0;
+ 835 : }
+ 836 :
+ 837 : /* otherwise don't use anything, and keep the directory traversal order */
+ 838 : /* at now this should happen only for vfat */
+ 839 : /* and it's surely better than using fake inodes */
+ 840 0 : *physical = FILEPHY_UNREPORTED_OFFSET;
+ 841 0 : if (close(f) == -1)
+ 842 0 : return -1;
+ 843 : #else
+ 844 : /* In a generic Unix use a dummy value for all the files */
+ 845 : /* We don't want to risk to use the inode without knowing */
+ 846 : /* if it really improves performance. */
+ 847 : /* In this way we keep them in the directory traversal order */
+ 848 : /* that at least keeps files in the same directory together. */
+ 849 : /* Note also that in newer file-system with snapshot, like ZFS, */
+ 850 : /* the inode doesn't represent even more the disk position, because files */
+ 851 : /* are not overwritten in place, but rewritten in another location */
+ 852 : /* of the disk. */
+ 853 : *physical = FILEPHY_UNREPORTED_OFFSET;
+ 854 :
+ 855 : (void)path; /* not used here */
+ 856 : (void)size;
+ 857 : #endif
+ 858 :
+ 859 0 : return 0;
+ 860 : }
+ 861 :
+ 862 : /* from man statfs */
+ 863 : #define ADFS_SUPER_MAGIC 0xadf5
+ 864 : #define AFFS_SUPER_MAGIC 0xADFF
+ 865 : #define BDEVFS_MAGIC 0x62646576
+ 866 : #define BEFS_SUPER_MAGIC 0x42465331
+ 867 : #define BFS_MAGIC 0x1BADFACE
+ 868 : #define BINFMTFS_MAGIC 0x42494e4d
+ 869 : #define BTRFS_SUPER_MAGIC 0x9123683E
+ 870 : #define CGROUP_SUPER_MAGIC 0x27e0eb
+ 871 : #define CIFS_MAGIC_NUMBER 0xFF534D42
+ 872 : #define CODA_SUPER_MAGIC 0x73757245
+ 873 : #define COH_SUPER_MAGIC 0x012FF7B7
+ 874 : #define CRAMFS_MAGIC 0x28cd3d45
+ 875 : #define DEBUGFS_MAGIC 0x64626720
+ 876 : #define DEVFS_SUPER_MAGIC 0x1373
+ 877 : #define DEVPTS_SUPER_MAGIC 0x1cd1
+ 878 : #define EFIVARFS_MAGIC 0xde5e81e4
+ 879 : #define EFS_SUPER_MAGIC 0x00414A53
+ 880 : #define EXT_SUPER_MAGIC 0x137D
+ 881 : #define EXT2_OLD_SUPER_MAGIC 0xEF51
+ 882 : #define EXT4_SUPER_MAGIC 0xEF53 /* also ext2/ext3 */
+ 883 : #define FUSE_SUPER_MAGIC 0x65735546
+ 884 : #define FUTEXFS_SUPER_MAGIC 0xBAD1DEA
+ 885 : #define HFS_SUPER_MAGIC 0x4244
+ 886 : #define HFSPLUS_SUPER_MAGIC 0x482b
+ 887 : #define HOSTFS_SUPER_MAGIC 0x00c0ffee
+ 888 : #define HPFS_SUPER_MAGIC 0xF995E849
+ 889 : #define HUGETLBFS_MAGIC 0x958458f6
+ 890 : #define ISOFS_SUPER_MAGIC 0x9660
+ 891 : #define JFFS2_SUPER_MAGIC 0x72b6
+ 892 : #define JFS_SUPER_MAGIC 0x3153464a
+ 893 : #define MINIX_SUPER_MAGIC 0x137F
+ 894 : #define MINIX_SUPER_MAGIC2 0x138F
+ 895 : #define MINIX2_SUPER_MAGIC 0x2468
+ 896 : #define MINIX2_SUPER_MAGIC2 0x2478
+ 897 : #define MINIX3_SUPER_MAGIC 0x4d5a
+ 898 : #define MQUEUE_MAGIC 0x19800202
+ 899 : #define MSDOS_SUPER_MAGIC 0x4d44
+ 900 : #define NCP_SUPER_MAGIC 0x564c
+ 901 : #define NFS_SUPER_MAGIC 0x6969
+ 902 : #define NILFS_SUPER_MAGIC 0x3434
+ 903 : #define NTFS_SB_MAGIC 0x5346544e
+ 904 : #define OCFS2_SUPER_MAGIC 0x7461636f
+ 905 : #define OPENPROM_SUPER_MAGIC 0x9fa1
+ 906 : #define PIPEFS_MAGIC 0x50495045
+ 907 : #define PROC_SUPER_MAGIC 0x9fa0
+ 908 : #define PSTOREFS_MAGIC 0x6165676C
+ 909 : #define QNX4_SUPER_MAGIC 0x002f
+ 910 : #define QNX6_SUPER_MAGIC 0x68191122
+ 911 : #define RAMFS_MAGIC 0x858458f6
+ 912 : #define REISERFS_SUPER_MAGIC 0x52654973
+ 913 : #define ROMFS_MAGIC 0x7275
+ 914 : #define SELINUX_MAGIC 0xf97cff8c
+ 915 : #define SMACK_MAGIC 0x43415d53
+ 916 : #define SMB_SUPER_MAGIC 0x517B
+ 917 : #define SOCKFS_MAGIC 0x534F434B
+ 918 : #define SQUASHFS_MAGIC 0x73717368
+ 919 : #define SYSFS_MAGIC 0x62656572
+ 920 : #define SYSV2_SUPER_MAGIC 0x012FF7B6
+ 921 : #define SYSV4_SUPER_MAGIC 0x012FF7B5
+ 922 : #define TMPFS_MAGIC 0x01021994
+ 923 : #define UDF_SUPER_MAGIC 0x15013346
+ 924 : #define UFS_MAGIC 0x00011954
+ 925 : #define USBDEVICE_SUPER_MAGIC 0x9fa2
+ 926 : #define V9FS_MAGIC 0x01021997
+ 927 : #define VXFS_SUPER_MAGIC 0xa501FCF5
+ 928 : #define XENFS_SUPER_MAGIC 0xabba1974
+ 929 : #define XENIX_SUPER_MAGIC 0x012FF7B4
+ 930 : #define XFS_SUPER_MAGIC 0x58465342
+ 931 : #define _XIAFS_SUPER_MAGIC 0x012FD16D
+ 932 : #define AFS_SUPER_MAGIC 0x5346414F
+ 933 : #define AUFS_SUPER_MAGIC 0x61756673
+ 934 : #define ANON_INODE_FS_SUPER_MAGIC 0x09041934
+ 935 : #define CEPH_SUPER_MAGIC 0x00C36400
+ 936 : #define ECRYPTFS_SUPER_MAGIC 0xF15F
+ 937 : #define FAT_SUPER_MAGIC 0x4006
+ 938 : #define FHGFS_SUPER_MAGIC 0x19830326
+ 939 : #define FUSEBLK_SUPER_MAGIC 0x65735546
+ 940 : #define FUSECTL_SUPER_MAGIC 0x65735543
+ 941 : #define GFS_SUPER_MAGIC 0x1161970
+ 942 : #define GPFS_SUPER_MAGIC 0x47504653
+ 943 : #define MTD_INODE_FS_SUPER_MAGIC 0x11307854
+ 944 : #define INOTIFYFS_SUPER_MAGIC 0x2BAD1DEA
+ 945 : #define ISOFS_R_WIN_SUPER_MAGIC 0x4004
+ 946 : #define ISOFS_WIN_SUPER_MAGIC 0x4000
+ 947 : #define JFFS_SUPER_MAGIC 0x07C0
+ 948 : #define KAFS_SUPER_MAGIC 0x6B414653
+ 949 : #define LUSTRE_SUPER_MAGIC 0x0BD00BD0
+ 950 : #define NFSD_SUPER_MAGIC 0x6E667364
+ 951 : #define PANFS_SUPER_MAGIC 0xAAD7AAEA
+ 952 : #define RPC_PIPEFS_SUPER_MAGIC 0x67596969
+ 953 : #define SECURITYFS_SUPER_MAGIC 0x73636673
+ 954 : #define UFS_BYTESWAPPED_SUPER_MAGIC 0x54190100
+ 955 : #define VMHGFS_SUPER_MAGIC 0xBACBACBC
+ 956 : #define VZFS_SUPER_MAGIC 0x565A4653
+ 957 : #define ZFS_SUPER_MAGIC 0x2FC12FC1
+ 958 :
+ 959 : struct filesystem_entry {
+ 960 : unsigned id;
+ 961 : const char* name;
+ 962 : int remote;
+ 963 : } FILESYSTEMS[] = {
+ 964 : { ADFS_SUPER_MAGIC, "adfs", 0 },
+ 965 : { AFFS_SUPER_MAGIC, "affs", 0 },
+ 966 : { AFS_SUPER_MAGIC, "afs", 1 },
+ 967 : { AUFS_SUPER_MAGIC, "aufs", 1 },
+ 968 : { BEFS_SUPER_MAGIC, "befs", 0 },
+ 969 : { BDEVFS_MAGIC, "bdevfs", 0 },
+ 970 : { BFS_MAGIC, "bfs", 0 },
+ 971 : { BINFMTFS_MAGIC, "binfmt_misc", 0 },
+ 972 : { BTRFS_SUPER_MAGIC, "btrfs", 0 },
+ 973 : { CEPH_SUPER_MAGIC, "ceph", 1 },
+ 974 : { CGROUP_SUPER_MAGIC, "cgroupfs", 0 },
+ 975 : { CIFS_MAGIC_NUMBER, "cifs", 1 },
+ 976 : { CODA_SUPER_MAGIC, "coda", 1 },
+ 977 : { COH_SUPER_MAGIC, "coh", 0 },
+ 978 : { CRAMFS_MAGIC, "cramfs", 0 },
+ 979 : { DEBUGFS_MAGIC, "debugfs", 0 },
+ 980 : { DEVFS_SUPER_MAGIC, "devfs", 0 },
+ 981 : { DEVPTS_SUPER_MAGIC, "devpts", 0 },
+ 982 : { ECRYPTFS_SUPER_MAGIC, "ecryptfs", 0 },
+ 983 : { EFS_SUPER_MAGIC, "efs", 0 },
+ 984 : { EXT_SUPER_MAGIC, "ext", 0 },
+ 985 : { EXT4_SUPER_MAGIC, "ext4", 0 },
+ 986 : { EXT2_OLD_SUPER_MAGIC, "ext2", 0 },
+ 987 : { FAT_SUPER_MAGIC, "fat", 0 },
+ 988 : { FHGFS_SUPER_MAGIC, "fhgfs", 1 },
+ 989 : { FUSEBLK_SUPER_MAGIC, "fuseblk", 1 },
+ 990 : { FUSECTL_SUPER_MAGIC, "fusectl", 1 },
+ 991 : { FUTEXFS_SUPER_MAGIC, "futexfs", 0 },
+ 992 : { GFS_SUPER_MAGIC, "gfs/gfs2", 1 },
+ 993 : { GPFS_SUPER_MAGIC, "gpfs", 1 },
+ 994 : { HFS_SUPER_MAGIC, "hfs", 0 },
+ 995 : { HFSPLUS_SUPER_MAGIC, "hfsplus", 0 },
+ 996 : { HPFS_SUPER_MAGIC, "hpfs", 0 },
+ 997 : { HUGETLBFS_MAGIC, "hugetlbfs", 0 },
+ 998 : { MTD_INODE_FS_SUPER_MAGIC, "inodefs", 0 },
+ 999 : { INOTIFYFS_SUPER_MAGIC, "inotifyfs", 0 },
+ 1000 : { ISOFS_SUPER_MAGIC, "isofs", 0 },
+ 1001 : { ISOFS_R_WIN_SUPER_MAGIC, "isofs", 0 },
+ 1002 : { ISOFS_WIN_SUPER_MAGIC, "isofs", 0 },
+ 1003 : { JFFS_SUPER_MAGIC, "jffs", 0 },
+ 1004 : { JFFS2_SUPER_MAGIC, "jffs2", 0 },
+ 1005 : { JFS_SUPER_MAGIC, "jfs", 0 },
+ 1006 : { KAFS_SUPER_MAGIC, "k-afs", 1 },
+ 1007 : { LUSTRE_SUPER_MAGIC, "lustre", 1 },
+ 1008 : { MINIX_SUPER_MAGIC, "minix", 0 },
+ 1009 : { MINIX_SUPER_MAGIC2, "minix", 0 },
+ 1010 : { MINIX2_SUPER_MAGIC, "minix2", 0 },
+ 1011 : { MINIX2_SUPER_MAGIC2, "minix2", 0 },
+ 1012 : { MINIX3_SUPER_MAGIC, "minix3", 0 },
+ 1013 : { MQUEUE_MAGIC, "mqueue", 0 },
+ 1014 : { MSDOS_SUPER_MAGIC, "msdos", 0 },
+ 1015 : { NCP_SUPER_MAGIC, "novell", 1 },
+ 1016 : { NFS_SUPER_MAGIC, "nfs", 1 },
+ 1017 : { NFSD_SUPER_MAGIC, "nfsd", 1 },
+ 1018 : { NILFS_SUPER_MAGIC, "nilfs", 0 },
+ 1019 : { NTFS_SB_MAGIC, "ntfs", 0 },
+ 1020 : { OPENPROM_SUPER_MAGIC, "openprom", 0 },
+ 1021 : { OCFS2_SUPER_MAGIC, "ocfs2", 1 },
+ 1022 : { PANFS_SUPER_MAGIC, "panfs", 1 },
+ 1023 : { PIPEFS_MAGIC, "pipefs", 1 },
+ 1024 : { PROC_SUPER_MAGIC, "proc", 0 },
+ 1025 : { PSTOREFS_MAGIC, "pstorefs", 0 },
+ 1026 : { QNX4_SUPER_MAGIC, "qnx4", 0 },
+ 1027 : { QNX6_SUPER_MAGIC, "qnx6", 0 },
+ 1028 : { RAMFS_MAGIC, "ramfs", 0 },
+ 1029 : { REISERFS_SUPER_MAGIC, "reiserfs", 0 },
+ 1030 : { ROMFS_MAGIC, "romfs", 0 },
+ 1031 : { RPC_PIPEFS_SUPER_MAGIC, "rpc_pipefs", 0 },
+ 1032 : { SECURITYFS_SUPER_MAGIC, "securityfs", 0 },
+ 1033 : { SELINUX_MAGIC, "selinux", 0 },
+ 1034 : { SMB_SUPER_MAGIC, "smb", 1 },
+ 1035 : { SOCKFS_MAGIC, "sockfs", 0 },
+ 1036 : { SQUASHFS_MAGIC, "squashfs", 0 },
+ 1037 : { SYSFS_MAGIC, "sysfs", 0 },
+ 1038 : { SYSV2_SUPER_MAGIC, "sysv2", 0 },
+ 1039 : { SYSV4_SUPER_MAGIC, "sysv4", 0 },
+ 1040 : { TMPFS_MAGIC, "tmpfs", 0 },
+ 1041 : { UDF_SUPER_MAGIC, "udf", 0 },
+ 1042 : { UFS_MAGIC, "ufs", 0 },
+ 1043 : { UFS_BYTESWAPPED_SUPER_MAGIC, "ufs", 0 },
+ 1044 : { USBDEVICE_SUPER_MAGIC, "usbdevfs", 0 },
+ 1045 : { V9FS_MAGIC, "v9fs", 0 },
+ 1046 : { VMHGFS_SUPER_MAGIC, "vmhgfs", 1 },
+ 1047 : { VXFS_SUPER_MAGIC, "vxfs", 0 },
+ 1048 : { VZFS_SUPER_MAGIC, "vzfs", 0 },
+ 1049 : { XENFS_SUPER_MAGIC, "xenfs", 0 },
+ 1050 : { XENIX_SUPER_MAGIC, "xenix", 0 },
+ 1051 : { XFS_SUPER_MAGIC, "xfs", 0 },
+ 1052 : { _XIAFS_SUPER_MAGIC, "xia", 0 },
+ 1053 : { ZFS_SUPER_MAGIC, "zfs", 0 },
+ 1054 : { 0 }
+ 1055 : };
+ 1056 :
+ 1057 6412 : int fsinfo(const char* path, int* has_persistent_inode, int* has_syncronized_hardlinks, uint64_t* total_space, uint64_t* free_space, char* fstype, size_t fstype_size, char* fslabel, size_t fslabel_size)
+ 1058 : {
+ 1059 : #if HAVE_STATFS
+ 1060 : struct statfs st;
+ 1061 :
+ 1062 6412 : if (statfs(path, &st) != 0) {
+ 1063 : char dir[PATH_MAX];
+ 1064 : char* slash;
+ 1065 :
+ 1066 48 : if (errno != ENOENT) {
+ 1067 0 : return -1;
+ 1068 : }
+ 1069 :
+ 1070 : /* if it doesn't exist, we assume a file */
+ 1071 : /* and we check for the containing dir */
+ 1072 48 : if (strlen(path) + 1 > sizeof(dir)) {
+ 1073 0 : errno = ENAMETOOLONG;
+ 1074 0 : return -1;
+ 1075 : }
+ 1076 :
+ 1077 48 : strcpy(dir, path);
+ 1078 :
+ 1079 48 : slash = strrchr(dir, '/');
+ 1080 48 : if (!slash)
+ 1081 0 : return -1;
+ 1082 :
+ 1083 48 : *slash = 0;
+ 1084 48 : if (statfs(dir, &st) != 0)
+ 1085 0 : return -1;
+ 1086 : }
+ 1087 : #endif
+ 1088 :
+ 1089 : /* to get the fs type check "man stat" or "stat -f -t FILE" */
+ 1090 6412 : if (has_persistent_inode) {
+ 1091 : #if HAVE_STATFS && HAVE_STRUCT_STATFS_F_TYPE
+ 1092 605 : switch (st.f_type) {
+ 1093 0 : case FUSEBLK_SUPER_MAGIC : /* FUSE, "fuseblk" in the stat command */
+ 1094 : case MSDOS_SUPER_MAGIC : /* VFAT, "msdos" in the stat command */
+ 1095 0 : *has_persistent_inode = 0;
+ 1096 0 : break;
+ 1097 605 : default :
+ 1098 : /* by default assume yes */
+ 1099 605 : *has_persistent_inode = 1;
+ 1100 605 : break;
+ 1101 : }
+ 1102 : #else
+ 1103 : /* in Unix inodes are persistent by default */
+ 1104 : *has_persistent_inode = 1;
+ 1105 : #endif
+ 1106 : }
+ 1107 :
+ 1108 6412 : if (has_syncronized_hardlinks) {
+ 1109 : #if HAVE_STATFS && HAVE_STRUCT_STATFS_F_TYPE
+ 1110 605 : switch (st.f_type) {
+ 1111 0 : case NTFS_SB_MAGIC : /* NTFS */
+ 1112 : case MSDOS_SUPER_MAGIC : /* VFAT, "msdos" in the stat command */
+ 1113 0 : *has_syncronized_hardlinks = 0;
+ 1114 0 : break;
+ 1115 605 : default :
+ 1116 : /* by default assume yes */
+ 1117 605 : *has_syncronized_hardlinks = 1;
+ 1118 605 : break;
+ 1119 : }
+ 1120 : #else
+ 1121 : /* in Unix hardlinks share the same metadata by default */
+ 1122 : *has_syncronized_hardlinks = 1;
+ 1123 : #endif
+ 1124 : }
+ 1125 :
+ 1126 6412 : if (total_space) {
+ 1127 : #if HAVE_STATFS
+ 1128 5807 : *total_space = st.f_bsize * (uint64_t)st.f_blocks;
+ 1129 : #else
+ 1130 : *total_space = 0;
+ 1131 : #endif
+ 1132 : }
+ 1133 :
+ 1134 6412 : if (free_space) {
+ 1135 : #if HAVE_STATFS
+ 1136 5807 : *free_space = st.f_bsize * (uint64_t)st.f_bfree;
+ 1137 : #else
+ 1138 : *free_space = 0;
+ 1139 : #endif
+ 1140 : }
+ 1141 :
+ 1142 6412 : const char* ptype = 0;
+ 1143 :
+ 1144 : #if HAVE_STATFS && HAVE_STRUCT_STATFS_F_FSTYPENAME
+ 1145 : /* get the filesystem type directly from the struct (Mac OS X) */
+ 1146 : ptype = st.f_fstypename;
+ 1147 : #elif HAVE_STATFS && HAVE_STRUCT_STATFS_F_TYPE
+ 1148 : /* get the filesystem type from f_type (Linux) */
+ 1149 : /* from: https://github.com/influxdata/gopsutil/blob/master/disk/disk_linux.go */
+ 1150 141064 : for (int i = 0; FILESYSTEMS[i].id != 0; ++i) {
+ 1151 141064 : if (st.f_type == FILESYSTEMS[i].id) {
+ 1152 6412 : ptype = FILESYSTEMS[i].name;
+ 1153 6412 : break;
+ 1154 : }
+ 1155 : }
+ 1156 : #endif
+ 1157 :
+ 1158 6412 : if (fstype) {
+ 1159 5807 : fstype[0] = 0;
+ 1160 5807 : if (ptype)
+ 1161 5807 : snprintf(fstype, fstype_size, "%s", ptype);
+ 1162 : }
+ 1163 :
+ 1164 6412 : if (fslabel) {
+ 1165 5807 : fslabel[0] = 0;
+ 1166 : #if HAVE_BLKID
+ 1167 : struct stat fst;
+ 1168 5807 : if (stat(path, &fst) == 0)
+ 1169 5759 : devuuid_label(fst.st_dev, fslabel, fslabel_size);
+ 1170 : #else
+ 1171 : (void)fslabel_size;
+ 1172 : #endif
+ 1173 : }
+ 1174 :
+ 1175 6412 : return 0;
+ 1176 : }
+ 1177 :
+ 1178 3816139 : uint64_t tick(void)
+ 1179 : {
+ 1180 : #if HAVE_MACH_ABSOLUTE_TIME
+ 1181 : /* for Mac OS X */
+ 1182 : return mach_absolute_time();
+ 1183 : #elif HAVE_CLOCK_GETTIME && (defined(CLOCK_MONOTONIC) || defined(CLOCK_MONOTONIC_RAW))
+ 1184 : /* for Linux */
+ 1185 : struct timespec tv;
+ 1186 :
+ 1187 : /* nanosecond precision with clock_gettime() */
+ 1188 : #if defined(CLOCK_MONOTONIC_RAW)
+ 1189 3816139 : if (clock_gettime(CLOCK_MONOTONIC_RAW, &tv) != 0) {
+ 1190 : #else
+ 1191 : if (clock_gettime(CLOCK_MONOTONIC, &tv) != 0) {
+ 1192 : #endif
+ 1193 0 : return 0;
+ 1194 : }
+ 1195 :
+ 1196 3816139 : return tv.tv_sec * 1000000000ULL + tv.tv_nsec;
+ 1197 : #else
+ 1198 : /* other platforms */
+ 1199 : struct timeval tv;
+ 1200 :
+ 1201 : /* microsecond precision with gettimeofday() */
+ 1202 : if (gettimeofday(&tv, 0) != 0) {
+ 1203 : return 0;
+ 1204 : }
+ 1205 :
+ 1206 : return tv.tv_sec * 1000000ULL + tv.tv_usec;
+ 1207 : #endif
+ 1208 : }
+ 1209 :
+ 1210 3567 : uint64_t tick_ms(void)
+ 1211 : {
+ 1212 : struct timeval tv;
+ 1213 :
+ 1214 3567 : if (gettimeofday(&tv, 0) != 0)
+ 1215 0 : return 0;
+ 1216 :
+ 1217 3567 : return tv.tv_sec * 1000ULL + tv.tv_usec / 1000;
+ 1218 : }
+ 1219 :
+ 1220 295 : int randomize(void* ptr, size_t size)
+ 1221 : {
+ 1222 : int f;
+ 1223 : ssize_t ret;
+ 1224 :
+ 1225 295 : f = open("/dev/urandom", O_RDONLY);
+ 1226 295 : if (f == -1)
+ 1227 0 : return -1;
+ 1228 :
+ 1229 295 : ret = read(f, ptr, size);
+ 1230 295 : if (ret < 0 || (size_t)ret != size) {
+ 1231 0 : close(f);
+ 1232 0 : return -1;
+ 1233 : }
+ 1234 :
+ 1235 295 : if (close(f) != 0)
+ 1236 0 : return -1;
+ 1237 :
+ 1238 295 : return 0;
+ 1239 : }
+ 1240 :
+ 1241 : /**
+ 1242 : * Read a file extracting the contained device number in %u:%u format.
+ 1243 : * Return 0 on error.
+ 1244 : */
+ 1245 : #if HAVE_LINUX_DEVICE
+ 1246 168 : static dev_t devread(const char* path)
+ 1247 : {
+ 1248 : int f;
+ 1249 : int ret;
+ 1250 : int len;
+ 1251 : char buf[64];
+ 1252 : char* e;
+ 1253 : unsigned ma;
+ 1254 : unsigned mi;
+ 1255 :
+ 1256 168 : f = open(path, O_RDONLY);
+ 1257 168 : if (f == -1) {
+ 1258 : /* LCOV_EXCL_START */
+ 1259 : log_fatal(errno, "Failed to open '%s'.\n", path);
+ 1260 : return 0;
+ 1261 : /* LCOV_EXCL_STOP */
+ 1262 : }
+ 1263 :
+ 1264 168 : len = read(f, buf, sizeof(buf));
+ 1265 168 : if (len < 0) {
+ 1266 : /* LCOV_EXCL_START */
+ 1267 : close(f);
+ 1268 : log_fatal(errno, "Failed to read '%s'.\n", path);
+ 1269 : return 0;
+ 1270 : /* LCOV_EXCL_STOP */
+ 1271 : }
+ 1272 168 : if (len == sizeof(buf)) {
+ 1273 : /* LCOV_EXCL_START */
+ 1274 : close(f);
+ 1275 : log_fatal(EEXTERNAL, "Too long read '%s'.\n", path);
+ 1276 : return 0;
+ 1277 : /* LCOV_EXCL_STOP */
+ 1278 : }
+ 1279 :
+ 1280 168 : ret = close(f);
+ 1281 168 : if (ret != 0) {
+ 1282 : /* LCOV_EXCL_START */
+ 1283 : log_fatal(errno, "Failed to close '%s'.\n", path);
+ 1284 : return 0;
+ 1285 : /* LCOV_EXCL_STOP */
+ 1286 : }
+ 1287 :
+ 1288 168 : buf[len] = 0;
+ 1289 :
+ 1290 168 : ma = strtoul(buf, &e, 10);
+ 1291 168 : if (*e != ':') {
+ 1292 : /* LCOV_EXCL_START */
+ 1293 : log_fatal(EEXTERNAL, "Invalid format in '%s' for '%s'.\n", path, buf);
+ 1294 : return 0;
+ 1295 : /* LCOV_EXCL_STOP */
+ 1296 : }
+ 1297 :
+ 1298 168 : mi = strtoul(e + 1, &e, 10);
+ 1299 168 : if (*e != 0 && !isspace(*e)) {
+ 1300 : /* LCOV_EXCL_START */
+ 1301 : log_fatal(EEXTERNAL, "Invalid format in '%s' for '%s'.\n", path, buf);
+ 1302 : return 0;
+ 1303 : /* LCOV_EXCL_STOP */
+ 1304 : }
+ 1305 :
+ 1306 168 : return makedev(ma, mi);
+ 1307 : }
+ 1308 : #endif
+ 1309 :
+ 1310 : /**
+ 1311 : * Read a device tree filling the specified list of disk_t entries.
+ 1312 : */
+ 1313 : #if HAVE_LINUX_DEVICE
+ 1314 154 : static int devtree(devinfo_t* parent, dev_t device, tommy_list* list)
+ 1315 : {
+ 1316 : char path[PATH_MAX];
+ 1317 : DIR* d;
+ 1318 154 : int slaves = 0;
+ 1319 :
+ 1320 154 : pathprint(path, sizeof(path), "/sys/dev/block/%u:%u/slaves", major(device), minor(device));
+ 1321 :
+ 1322 : /* check if there is a slaves list */
+ 1323 154 : d = opendir(path);
+ 1324 154 : if (d != 0) {
+ 1325 : struct dirent* dd;
+ 1326 :
+ 1327 308 : while ((dd = readdir(d)) != 0) {
+ 1328 231 : if (dd->d_name[0] != '.') {
+ 1329 : dev_t subdev;
+ 1330 :
+ 1331 : /* for each slave, expand the full potential tree */
+ 1332 77 : pathprint(path, sizeof(path), "/sys/dev/block/%u:%u/slaves/%s/dev", major(device), minor(device), dd->d_name);
+ 1333 :
+ 1334 77 : subdev = devread(path);
+ 1335 77 : if (!subdev) {
+ 1336 : /* LCOV_EXCL_START */
+ 1337 : closedir(d);
+ 1338 : return -1;
+ 1339 : /* LCOV_EXCL_STOP */
+ 1340 : }
+ 1341 :
+ 1342 77 : if (devtree(parent, subdev, list) != 0) {
+ 1343 : /* LCOV_EXCL_START */
+ 1344 : closedir(d);
+ 1345 : return -1;
+ 1346 : /* LCOV_EXCL_STOP */
+ 1347 : }
+ 1348 :
+ 1349 77 : ++slaves;
+ 1350 : }
+ 1351 : }
+ 1352 :
+ 1353 77 : closedir(d);
+ 1354 : }
+ 1355 :
+ 1356 : /* if no slaves found */
+ 1357 154 : if (!slaves) {
+ 1358 : /* this is a raw device */
+ 1359 : devinfo_t* devinfo;
+ 1360 :
+ 1361 : /* check if it's a real device */
+ 1362 77 : pathprint(path, sizeof(path), "/sys/dev/block/%u:%u/device", major(device), minor(device));
+ 1363 77 : if (access(path, F_OK) != 0) {
+ 1364 : /* get the parent device */
+ 1365 77 : pathprint(path, sizeof(path), "/sys/dev/block/%u:%u/../dev", major(device), minor(device));
+ 1366 :
+ 1367 77 : device = devread(path);
+ 1368 77 : if (!device) {
+ 1369 : /* LCOV_EXCL_START */
+ 1370 : return -1;
+ 1371 : /* LCOV_EXCL_STOP */
+ 1372 : }
+ 1373 : }
+ 1374 :
+ 1375 : /* get the device file */
+ 1376 77 : if (devresolve(device, path, sizeof(path)) != 0) {
+ 1377 : /* LCOV_EXCL_START */
+ 1378 : log_fatal(EEXTERNAL, "Failed to resolve device '%u:%u'.\n", major(device), minor(device));
+ 1379 : return -1;
+ 1380 : /* LCOV_EXCL_STOP */
+ 1381 : }
+ 1382 :
+ 1383 77 : devinfo = calloc_nofail(1, sizeof(devinfo_t));
+ 1384 :
+ 1385 77 : devinfo->device = device;
+ 1386 77 : pathcpy(devinfo->name, sizeof(devinfo->name), parent->name);
+ 1387 77 : pathcpy(devinfo->smartctl, sizeof(devinfo->smartctl), parent->smartctl);
+ 1388 77 : memcpy(devinfo->smartignore, parent->smartignore, sizeof(devinfo->smartignore));
+ 1389 77 : pathcpy(devinfo->file, sizeof(devinfo->file), path);
+ 1390 77 : devinfo->parent = parent;
+ 1391 :
+ 1392 : /* insert in the list */
+ 1393 77 : tommy_list_insert_tail(list, &devinfo->node, devinfo);
+ 1394 : }
+ 1395 :
+ 1396 154 : return 0;
+ 1397 : }
+ 1398 : #endif
+ 1399 :
+ 1400 : /**
+ 1401 : * Scan all the devices.
+ 1402 : *
+ 1403 : * If a device is already in, it's not added again.
+ 1404 : */
+ 1405 : #if HAVE_LINUX_DEVICE
+ 1406 1 : static int devscan(tommy_list* list)
+ 1407 : {
+ 1408 : char dir[PATH_MAX];
+ 1409 : DIR* d;
+ 1410 : struct dirent* dd;
+ 1411 :
+ 1412 1 : pathprint(dir, sizeof(dir), "/sys/dev/block/");
+ 1413 :
+ 1414 : /* check if there is a slaves list */
+ 1415 1 : d = opendir(dir);
+ 1416 1 : if (d == 0) {
+ 1417 : /* LCOV_EXCL_START */
+ 1418 : log_fatal(errno, "Failed to open dir '%s'.\n", dir);
+ 1419 : return -1;
+ 1420 : /* LCOV_EXCL_STOP */
+ 1421 : }
+ 1422 :
+ 1423 75 : while ((dd = readdir(d)) != 0) {
+ 1424 : char path[PATH_MAX];
+ 1425 : tommy_node* i;
+ 1426 : dev_t device;
+ 1427 : devinfo_t* devinfo;
+ 1428 :
+ 1429 74 : if (dd->d_name[0] == '.')
+ 1430 72 : continue;
+ 1431 :
+ 1432 72 : pathprint(path, sizeof(path), "/sys/dev/block/%s/device", dd->d_name);
+ 1433 :
+ 1434 : /* check if it's a real device */
+ 1435 72 : if (access(path, F_OK) != 0)
+ 1436 58 : continue;
+ 1437 :
+ 1438 14 : pathprint(path, sizeof(path), "/sys/dev/block/%s/dev", dd->d_name);
+ 1439 :
+ 1440 14 : device = devread(path);
+ 1441 14 : if (!device) {
+ 1442 : /* LCOV_EXCL_START */
+ 1443 : log_tag("scan:skip: Skipping device %s because failed to read its device number.\n", dd->d_name);
+ 1444 : continue;
+ 1445 : /* LCOV_EXCL_STOP */
+ 1446 : }
+ 1447 :
+ 1448 : /* check if already present */
+ 1449 105 : for (i = tommy_list_head(list); i != 0; i = i->next) {
+ 1450 103 : devinfo = i->data;
+ 1451 103 : if (devinfo->device == device)
+ 1452 12 : break;
+ 1453 : }
+ 1454 :
+ 1455 : /* if already present */
+ 1456 14 : if (i != 0)
+ 1457 12 : continue;
+ 1458 :
+ 1459 : /* get the device file */
+ 1460 2 : if (devresolve(device, path, sizeof(path)) != 0) {
+ 1461 : /* LCOV_EXCL_START */
+ 1462 : log_tag("scan:skip: Skipping device %u:%u because failed to resolve.\n", major(device), minor(device));
+ 1463 : continue;
+ 1464 : /* LCOV_EXCL_STOP */
+ 1465 : }
+ 1466 :
+ 1467 2 : devinfo = calloc_nofail(1, sizeof(devinfo_t));
+ 1468 :
+ 1469 2 : devinfo->device = device;
+ 1470 2 : pathcpy(devinfo->file, sizeof(devinfo->file), path);
+ 1471 :
+ 1472 : /* insert in the list */
+ 1473 2 : tommy_list_insert_tail(list, &devinfo->node, devinfo);
+ 1474 : }
+ 1475 :
+ 1476 1 : closedir(d);
+ 1477 1 : return 0;
+ 1478 : }
+ 1479 : #endif
+ 1480 :
+ 1481 : /**
+ 1482 : * Get SMART attributes.
+ 1483 : */
+ 1484 : #if HAVE_LINUX_DEVICE
+ 1485 0 : static int devsmart(dev_t device, const char* name, const char* smartctl, struct smart_attr* smart, uint64_t* info, char* serial, char* family, char* model, char* interface)
+ 1486 : {
+ 1487 : char cmd[PATH_MAX + 64];
+ 1488 : char file[PATH_MAX];
+ 1489 : FILE* f;
+ 1490 : int ret;
+ 1491 : const char* x;
+ 1492 :
+ 1493 0 : x = find_smartctl();
+ 1494 0 : if (!x) {
+ 1495 : /* LCOV_EXCL_START */
+ 1496 : log_fatal(EEXTERNAL, "Cannot find smartctl.\n");
+ 1497 : return -1;
+ 1498 : /* LCOV_EXCL_STOP */
+ 1499 : }
+ 1500 :
+ 1501 0 : if (devresolve(device, file, sizeof(file)) != 0) {
+ 1502 : /* LCOV_EXCL_START */
+ 1503 : log_fatal(EEXTERNAL, "Failed to resolve device '%u:%u'.\n", major(device), minor(device));
+ 1504 : return -1;
+ 1505 : /* LCOV_EXCL_STOP */
+ 1506 : }
+ 1507 :
+ 1508 : /* if there is a custom smartctl command */
+ 1509 0 : if (smartctl[0]) {
+ 1510 : char option[PATH_MAX];
+ 1511 0 : snprintf(option, sizeof(option), smartctl, file);
+ 1512 0 : snprintf(cmd, sizeof(cmd), "%s -a %s", x, option);
+ 1513 : } else {
+ 1514 0 : snprintf(cmd, sizeof(cmd), "%s -a %s", x, file);
+ 1515 : }
+ 1516 :
+ 1517 0 : log_tag("smartctl:%s:%s:run: %s\n", file, name, cmd);
+ 1518 :
+ 1519 0 : f = popen(cmd, "r");
+ 1520 0 : if (!f) {
+ 1521 : /* LCOV_EXCL_START */
+ 1522 : log_tag("device:%s:%s:shell\n", file, name);
+ 1523 : log_fatal(EEXTERNAL, "Failed to run '%s' (from popen).\n", cmd);
+ 1524 : return -1;
+ 1525 : /* LCOV_EXCL_STOP */
+ 1526 : }
+ 1527 :
+ 1528 0 : if (smartctl_attribute(f, file, name, smart, info, serial, family, model, interface) != 0) {
+ 1529 : /* LCOV_EXCL_START */
+ 1530 : pclose(f);
+ 1531 : log_tag("device:%s:%s:shell\n", file, name);
+ 1532 : return -1;
+ 1533 : /* LCOV_EXCL_STOP */
+ 1534 : }
+ 1535 :
+ 1536 0 : ret = pclose(f);
+ 1537 :
+ 1538 0 : log_tag("smartctl:%s:%s:ret: %x\n", file, name, ret);
+ 1539 :
+ 1540 0 : if (!WIFEXITED(ret)) {
+ 1541 : /* LCOV_EXCL_START */
+ 1542 : log_tag("device:%s:%s:abort\n", file, name);
+ 1543 : log_fatal(EEXTERNAL, "Failed to run '%s' (not exited).\n", cmd);
+ 1544 : return -1;
+ 1545 : /* LCOV_EXCL_STOP */
+ 1546 : }
+ 1547 0 : if (WEXITSTATUS(ret) == 127) {
+ 1548 : /* LCOV_EXCL_START */
+ 1549 : log_tag("device:%s:%s:shell\n", file, name);
+ 1550 : log_fatal(EEXTERNAL, "Failed to run '%s' (from sh).\n", cmd);
+ 1551 : return -1;
+ 1552 : /* LCOV_EXCL_STOP */
+ 1553 : }
+ 1554 :
+ 1555 : /* store the return smartctl return value */
+ 1556 0 : smart[SMART_FLAGS].raw = WEXITSTATUS(ret);
+ 1557 :
+ 1558 0 : return 0;
+ 1559 : }
+ 1560 : #endif
+ 1561 :
+ 1562 : /**
+ 1563 : * Compute disk usage by aggregating access statistics.
+ 1564 : */
+ 1565 : #if HAVE_LINUX_DEVICE
+ 1566 77 : static int devstat(dev_t device, uint64_t* count)
+ 1567 : {
+ 1568 : char path[PATH_MAX];
+ 1569 : char buf[512];
+ 1570 : int token;
+ 1571 : int ret;
+ 1572 : char* i;
+ 1573 :
+ 1574 77 : *count = 0;
+ 1575 :
+ 1576 77 : pathprint(path, sizeof(path), "/sys/dev/block/%u:%u/stat", major(device), minor(device));
+ 1577 :
+ 1578 77 : ret = sysread(path, buf, sizeof(buf));
+ 1579 77 : if (ret < 0) {
+ 1580 : /* LCOV_EXCL_START */
+ 1581 : log_fatal(errno, "Failed to read '%s'.\n", path);
+ 1582 : return -1;
+ 1583 : /* LCOV_EXCL_STOP */
+ 1584 : }
+ 1585 77 : if ((size_t)ret + 1 > sizeof(buf)) {
+ 1586 : /* LCOV_EXCL_START */
+ 1587 : log_fatal(EEXTERNAL, "Too long read '%s'.\n", path);
+ 1588 : return -1;
+ 1589 : /* LCOV_EXCL_STOP */
+ 1590 : }
+ 1591 :
+ 1592 : /* ending 0 */
+ 1593 77 : buf[ret] = 0;
+ 1594 :
+ 1595 77 : i = buf;
+ 1596 77 : token = 1; /* token number */
+ 1597 385 : while (*i) {
+ 1598 : char* n;
+ 1599 : char* e;
+ 1600 : unsigned long long v;
+ 1601 :
+ 1602 : /* skip spaces */
+ 1603 1119 : while (*i && isspace(*i))
+ 1604 734 : ++i;
+ 1605 :
+ 1606 : /* read digits */
+ 1607 385 : n = i;
+ 1608 2820 : while (*i && isdigit(*i))
+ 1609 2435 : ++i;
+ 1610 :
+ 1611 385 : if (i == n) /* if no digit, abort */
+ 1612 77 : break;
+ 1613 385 : if (*i == 0 || !isspace(*i)) /* if no space, abort */
+ 1614 : break;
+ 1615 385 : *i++ = 0; /* put a terminator */
+ 1616 :
+ 1617 385 : v = strtoull(n, &e, 10);
+ 1618 385 : if (*e != 0)
+ 1619 0 : break;
+ 1620 :
+ 1621 : /* sum reads and writes completed */
+ 1622 385 : if (token == 1 || token == 5) {
+ 1623 154 : *count += v;
+ 1624 154 : if (token == 5)
+ 1625 77 : break; /* stop here */
+ 1626 : }
+ 1627 :
+ 1628 308 : ++token;
+ 1629 : }
+ 1630 :
+ 1631 77 : return 0;
+ 1632 : }
+ 1633 : #endif
+ 1634 :
+ 1635 : /**
+ 1636 : * Get device attributes.
+ 1637 : */
+ 1638 : #if HAVE_LINUX_DEVICE
+ 1639 14 : static void devattr(dev_t device, uint64_t* info, char* serial, char* family, char* model, char* interface)
+ 1640 : {
+ 1641 : char path[PATH_MAX];
+ 1642 : char buf[512];
+ 1643 : int ret;
1644 :
1645 : (void)family; /* not available, smartctl uses an internal database to get it */
1646 :
- 1647 0 : if (info[INFO_SIZE] == SMART_UNASSIGNED) {
- 1648 0 : pathprint(path, sizeof(path), "/sys/dev/block/%u:%u/size", major(device), minor(device));
- 1649 0 : attr = sysattr(path, buf, sizeof(buf));
- 1650 0 : if (attr) {
- 1651 : char* e;
- 1652 : uint64_t v;
- 1653 0 : v = strtoul(attr, &e, 10);
- 1654 0 : if (*e == 0)
- 1655 0 : info[INFO_SIZE] = v * 512;
- 1656 : }
- 1657 : }
- 1658 :
- 1659 0 : if (info[INFO_ROTATION_RATE] == SMART_UNASSIGNED) {
- 1660 0 : pathprint(path, sizeof(path), "/sys/dev/block/%u:%u/queue/rotational", major(device), minor(device));
- 1661 0 : attr = sysattr(path, buf, sizeof(buf));
- 1662 0 : if (attr) {
- 1663 : char* e;
- 1664 : uint64_t v;
- 1665 0 : v = strtoul(attr, &e, 10);
- 1666 0 : if (*e == 0)
- 1667 0 : info[INFO_ROTATION_RATE] = v;
- 1668 : }
- 1669 : }
- 1670 :
- 1671 0 : if (*model == 0) {
- 1672 0 : pathprint(path, sizeof(path), "/sys/dev/block/%u:%u/device/model", major(device), minor(device));
- 1673 0 : attr = sysattr(path, buf, sizeof(buf));
- 1674 0 : if (attr && *attr) {
- 1675 0 : pathcpy(model, SMART_MAX, attr);
- 1676 0 : strtrim(model);
- 1677 : }
- 1678 : }
- 1679 :
- 1680 0 : if (*serial == 0) {
- 1681 0 : pathprint(path, sizeof(path), "/sys/dev/block/%u:%u/device/serial", major(device), minor(device));
- 1682 0 : attr = sysattr(path, buf, sizeof(buf));
- 1683 0 : if (attr && *attr) {
- 1684 0 : pathcpy(serial, SMART_MAX, attr);
- 1685 0 : strtrim(serial);
- 1686 : }
- 1687 : }
- 1688 :
- 1689 0 : if (*serial == 0) {
- 1690 : // --- Page 0x80: Unit Serial Number ---
- 1691 0 : pathprint(path, sizeof(path), "/sys/dev/block/%u:%u/device/vpd_pg80", major(device), minor(device));
- 1692 0 : ret = sysread(path, buf, sizeof(buf));
- 1693 0 : if (ret > 4) {
- 1694 0 : unsigned len = (unsigned char)buf[3];
- 1695 0 : if (4 + len <= (size_t)ret && 4 + len + 1 <= sizeof(buf)) {
- 1696 0 : attr = buf + 4;
- 1697 0 : attr[len] = 0;
- 1698 0 : strtrim(attr);
- 1699 0 : if (*attr) {
- 1700 0 : pathcpy(serial, SMART_MAX, attr);
- 1701 0 : strtrim(serial);
- 1702 : }
- 1703 : }
- 1704 : }
- 1705 : }
- 1706 :
- 1707 : /* always override interface if it's usb */
- 1708 0 : pathprint(path, sizeof(path), "/sys/dev/block/%u:%u", major(device), minor(device));
- 1709 0 : ret = readlink(path, buf, sizeof(buf));
- 1710 0 : if (ret > 0 && (unsigned)ret < sizeof(buf)) {
- 1711 0 : buf[ret] = 0;
- 1712 0 : if (strstr(buf, "usb") != 0)
- 1713 0 : strcpy(interface, "USB");
- 1714 : }
- 1715 0 : }
- 1716 : #endif
- 1717 :
- 1718 : /**
- 1719 : * Get POWER state.
- 1720 : */
- 1721 : #if HAVE_LINUX_DEVICE
- 1722 0 : static int devprobe(dev_t device, const char* name, const char* smartctl, int* power, struct smart_attr* smart, uint64_t* info, char* serial, char* family, char* model, char* interface)
- 1723 : {
- 1724 : char cmd[PATH_MAX + 64];
- 1725 : char file[PATH_MAX];
- 1726 : FILE* f;
- 1727 : int ret;
- 1728 : const char* x;
- 1729 :
- 1730 0 : x = find_smartctl();
- 1731 0 : if (!x) {
- 1732 : /* LCOV_EXCL_START */
- 1733 : log_fatal(EEXTERNAL, "Cannot find smartctl.\n");
- 1734 : return -1;
- 1735 : /* LCOV_EXCL_STOP */
- 1736 : }
- 1737 :
- 1738 0 : if (devresolve(device, file, sizeof(file)) != 0) {
- 1739 : /* LCOV_EXCL_START */
- 1740 : log_fatal(EEXTERNAL, "Failed to resolve device '%u:%u'.\n", major(device), minor(device));
- 1741 : return -1;
- 1742 : /* LCOV_EXCL_STOP */
- 1743 : }
- 1744 :
- 1745 : /* if there is a custom smartctl command */
- 1746 0 : if (smartctl[0]) {
- 1747 : char option[PATH_MAX];
- 1748 0 : snprintf(option, sizeof(option), smartctl, file);
- 1749 0 : snprintf(cmd, sizeof(cmd), "%s -n standby,3 -a %s", x, option);
- 1750 : } else {
- 1751 0 : snprintf(cmd, sizeof(cmd), "%s -n standby,3 -a %s", x, file);
- 1752 : }
- 1753 :
- 1754 0 : log_tag("smartctl:%s:%s:run: %s\n", file, name, cmd);
- 1755 :
- 1756 0 : f = popen(cmd, "r");
- 1757 0 : if (!f) {
- 1758 : /* LCOV_EXCL_START */
- 1759 : log_tag("device:%s:%s:shell\n", file, name);
- 1760 : log_fatal(EEXTERNAL, "Failed to run '%s' (from popen).\n", cmd);
- 1761 : return -1;
- 1762 : /* LCOV_EXCL_STOP */
- 1763 : }
- 1764 :
- 1765 0 : if (smartctl_attribute(f, file, name, smart, info, serial, family, model, interface) != 0) {
- 1766 : /* LCOV_EXCL_START */
- 1767 : pclose(f);
- 1768 : log_tag("device:%s:%s:shell\n", file, name);
- 1769 : return -1;
- 1770 : /* LCOV_EXCL_STOP */
- 1771 : }
- 1772 :
- 1773 0 : ret = pclose(f);
- 1774 :
- 1775 0 : log_tag("smartctl:%s:%s:ret: %x\n", file, name, ret);
- 1776 :
- 1777 0 : if (!WIFEXITED(ret)) {
- 1778 : /* LCOV_EXCL_START */
- 1779 : log_tag("device:%s:%s:abort\n", file, name);
- 1780 : log_fatal(EEXTERNAL, "Failed to run '%s' (not exited).\n", cmd);
- 1781 : return -1;
- 1782 : /* LCOV_EXCL_STOP */
- 1783 : }
- 1784 0 : if (WEXITSTATUS(ret) == 127) {
- 1785 : /* LCOV_EXCL_START */
- 1786 : log_tag("device:%s:%s:shell\n", file, name);
- 1787 : log_fatal(EEXTERNAL, "Failed to run '%s' (from sh).\n", cmd);
- 1788 : return -1;
- 1789 : /* LCOV_EXCL_STOP */
- 1790 : }
- 1791 :
- 1792 0 : if (WEXITSTATUS(ret) == 3) {
- 1793 0 : log_tag("attr:%s:%s:power:standby\n", file, name);
- 1794 0 : *power = POWER_STANDBY;
- 1795 : } else {
- 1796 0 : log_tag("attr:%s:%s:power:active\n", file, name);
- 1797 0 : *power = POWER_ACTIVE;
- 1798 :
- 1799 : /* store the smartctl return value */
- 1800 0 : if (smart)
- 1801 0 : smart[SMART_FLAGS].raw = WEXITSTATUS(ret);
- 1802 : }
- 1803 :
- 1804 0 : return 0;
- 1805 : }
- 1806 : #endif
- 1807 :
- 1808 : /**
- 1809 : * Spin down a specific device.
- 1810 : */
- 1811 : #if HAVE_LINUX_DEVICE
- 1812 5 : static int devdown(dev_t device, const char* name, const char* smartctl)
- 1813 : {
- 1814 : char cmd[PATH_MAX + 64];
- 1815 : char file[PATH_MAX];
- 1816 : FILE* f;
- 1817 : int ret;
- 1818 : const char* x;
- 1819 :
- 1820 5 : x = find_smartctl();
- 1821 5 : if (!x) {
- 1822 : /* LCOV_EXCL_START */
- 1823 : log_fatal(EEXTERNAL, "Cannot find smartctl.\n");
- 1824 : return -1;
- 1825 : /* LCOV_EXCL_STOP */
- 1826 : }
- 1827 :
- 1828 5 : if (devresolve(device, file, sizeof(file)) != 0) {
- 1829 : /* LCOV_EXCL_START */
- 1830 : log_fatal(EEXTERNAL, "Failed to resolve device '%u:%u'.\n", major(device), minor(device));
- 1831 : return -1;
- 1832 : /* LCOV_EXCL_STOP */
- 1833 : }
- 1834 :
- 1835 : /* if there is a custom smartctl command */
- 1836 5 : if (smartctl[0]) {
- 1837 : char option[PATH_MAX];
- 1838 5 : snprintf(option, sizeof(option), smartctl, file);
- 1839 5 : snprintf(cmd, sizeof(cmd), "%s -s standby,now %s", x, option);
- 1840 : } else {
- 1841 0 : snprintf(cmd, sizeof(cmd), "%s -s standby,now %s", x, file);
- 1842 : }
- 1843 :
- 1844 5 : log_tag("smartctl:%s:%s:run: %s\n", file, name, cmd);
- 1845 :
- 1846 5 : f = popen(cmd, "r");
- 1847 5 : if (!f) {
- 1848 : /* LCOV_EXCL_START */
- 1849 : log_tag("device:%s:%s:shell\n", file, name);
- 1850 : log_fatal(EEXTERNAL, "Failed to run '%s' (from popen).\n", cmd);
- 1851 : return -1;
- 1852 : /* LCOV_EXCL_STOP */
- 1853 : }
- 1854 :
- 1855 5 : if (smartctl_flush(f, file, name) != 0) {
- 1856 : /* LCOV_EXCL_START */
- 1857 : pclose(f);
- 1858 : log_tag("device:%s:%s:shell\n", file, name);
- 1859 : return -1;
- 1860 : /* LCOV_EXCL_STOP */
- 1861 : }
- 1862 :
- 1863 5 : ret = pclose(f);
- 1864 :
- 1865 5 : log_tag("smartctl:%s:%s:ret: %x\n", file, name, ret);
- 1866 :
- 1867 5 : if (!WIFEXITED(ret)) {
- 1868 : /* LCOV_EXCL_START */
- 1869 : log_tag("device:%s:%s:abort\n", file, name);
- 1870 : log_fatal(EEXTERNAL, "Failed to run '%s' (not exited).\n", cmd);
- 1871 : return -1;
- 1872 : /* LCOV_EXCL_STOP */
- 1873 : }
- 1874 5 : if (WEXITSTATUS(ret) == 127) {
- 1875 : /* LCOV_EXCL_START */
- 1876 : log_tag("device:%s:%s:shell\n", file, name);
- 1877 : log_fatal(EEXTERNAL, "Failed to run '%s' (from sh).\n", cmd);
- 1878 : return -1;
- 1879 : /* LCOV_EXCL_STOP */
- 1880 : }
- 1881 5 : if (WEXITSTATUS(ret) != 0) {
- 1882 : /* LCOV_EXCL_START */
- 1883 : log_tag("device:%s:%s:exit:%d\n", file, name, WEXITSTATUS(ret));
- 1884 : log_fatal(EEXTERNAL, "Failed to run '%s' with return code %xh.\n", cmd, WEXITSTATUS(ret));
- 1885 : return -1;
- 1886 : /* LCOV_EXCL_STOP */
- 1887 : }
+ 1647 14 : if (info[INFO_SIZE] == SMART_UNASSIGNED) {
+ 1648 12 : pathprint(path, sizeof(path), "/sys/dev/block/%u:%u/size", major(device), minor(device));
+ 1649 12 : if (sysattr(path, buf, sizeof(buf)) == 0) {
+ 1650 : char* e;
+ 1651 : uint64_t v;
+ 1652 12 : v = strtoul(buf, &e, 10);
+ 1653 12 : if (*e == 0)
+ 1654 12 : info[INFO_SIZE] = v * 512;
+ 1655 : }
+ 1656 : }
+ 1657 :
+ 1658 14 : if (info[INFO_ROTATION_RATE] == SMART_UNASSIGNED) {
+ 1659 12 : pathprint(path, sizeof(path), "/sys/dev/block/%u:%u/queue/rotational", major(device), minor(device));
+ 1660 12 : if (sysattr(path, buf, sizeof(buf)) == 0) {
+ 1661 : char* e;
+ 1662 : uint64_t v;
+ 1663 12 : v = strtoul(buf, &e, 10);
+ 1664 12 : if (*e == 0)
+ 1665 12 : info[INFO_ROTATION_RATE] = v;
+ 1666 : }
+ 1667 : }
+ 1668 :
+ 1669 14 : if (*model == 0) {
+ 1670 12 : pathprint(path, sizeof(path), "/sys/dev/block/%u:%u/device/model", major(device), minor(device));
+ 1671 12 : if (sysattr(path, buf, sizeof(buf)) == 0) {
+ 1672 12 : if (buf[0] != 0)
+ 1673 12 : pathcpy(model, SMART_MAX, buf);
+ 1674 : }
+ 1675 : }
+ 1676 :
+ 1677 14 : if (*serial == 0) {
+ 1678 14 : pathprint(path, sizeof(path), "/sys/dev/block/%u:%u/device/serial", major(device), minor(device));
+ 1679 14 : if (sysattr(path, buf, sizeof(buf)) == 0) {
+ 1680 0 : if (buf[0] != 0)
+ 1681 0 : pathcpy(serial, SMART_MAX, buf);
+ 1682 : }
+ 1683 : }
+ 1684 :
+ 1685 14 : if (*serial == 0) {
+ 1686 : // --- Page 0x80: Unit Serial Number ---
+ 1687 14 : pathprint(path, sizeof(path), "/sys/dev/block/%u:%u/device/vpd_pg80", major(device), minor(device));
+ 1688 14 : ret = sysread(path, buf, sizeof(buf));
+ 1689 14 : if (ret > 4) {
+ 1690 14 : unsigned len = (unsigned char)buf[3];
+ 1691 14 : if (4 + len <= (size_t)ret && 4 + len + 1 <= sizeof(buf)) {
+ 1692 14 : char* attr = buf + 4;
+ 1693 14 : attr[len] = 0;
+ 1694 14 : strtrim(attr);
+ 1695 14 : if (*attr)
+ 1696 14 : pathcpy(serial, SMART_MAX, attr);
+ 1697 : }
+ 1698 : }
+ 1699 : }
+ 1700 :
+ 1701 : /* always override interface if it's usb */
+ 1702 14 : pathprint(path, sizeof(path), "/sys/dev/block/%u:%u", major(device), minor(device));
+ 1703 14 : ret = readlink(path, buf, sizeof(buf));
+ 1704 14 : if (ret > 0 && (unsigned)ret < sizeof(buf)) {
+ 1705 14 : buf[ret] = 0;
+ 1706 14 : if (strstr(buf, "usb") != 0)
+ 1707 0 : strcpy(interface, "USB");
+ 1708 : }
+ 1709 14 : }
+ 1710 : #endif
+ 1711 :
+ 1712 : /**
+ 1713 : * Get POWER state.
+ 1714 : */
+ 1715 : #if HAVE_LINUX_DEVICE
+ 1716 14 : static int devprobe(dev_t device, const char* name, const char* smartctl, int* power, struct smart_attr* smart, uint64_t* info, char* serial, char* family, char* model, char* interface)
+ 1717 : {
+ 1718 : char cmd[PATH_MAX + 64];
+ 1719 : char file[PATH_MAX];
+ 1720 : FILE* f;
+ 1721 : int ret;
+ 1722 : const char* x;
+ 1723 :
+ 1724 14 : x = find_smartctl();
+ 1725 14 : if (!x) {
+ 1726 : /* LCOV_EXCL_START */
+ 1727 : log_fatal(EEXTERNAL, "Cannot find smartctl.\n");
+ 1728 : return -1;
+ 1729 : /* LCOV_EXCL_STOP */
+ 1730 : }
+ 1731 :
+ 1732 14 : if (devresolve(device, file, sizeof(file)) != 0) {
+ 1733 : /* LCOV_EXCL_START */
+ 1734 : log_fatal(EEXTERNAL, "Failed to resolve device '%u:%u'.\n", major(device), minor(device));
+ 1735 : return -1;
+ 1736 : /* LCOV_EXCL_STOP */
+ 1737 : }
+ 1738 :
+ 1739 : /* if there is a custom smartctl command */
+ 1740 14 : if (smartctl[0]) {
+ 1741 : char option[PATH_MAX];
+ 1742 0 : snprintf(option, sizeof(option), smartctl, file);
+ 1743 0 : snprintf(cmd, sizeof(cmd), "%s -n standby,3 -a %s", x, option);
+ 1744 : } else {
+ 1745 14 : snprintf(cmd, sizeof(cmd), "%s -n standby,3 -a %s", x, file);
+ 1746 : }
+ 1747 :
+ 1748 14 : log_tag("smartctl:%s:%s:run: %s\n", file, name, cmd);
+ 1749 :
+ 1750 14 : f = popen(cmd, "r");
+ 1751 14 : if (!f) {
+ 1752 : /* LCOV_EXCL_START */
+ 1753 : log_tag("device:%s:%s:shell\n", file, name);
+ 1754 : log_fatal(EEXTERNAL, "Failed to run '%s' (from popen).\n", cmd);
+ 1755 : return -1;
+ 1756 : /* LCOV_EXCL_STOP */
+ 1757 : }
+ 1758 :
+ 1759 14 : if (smartctl_attribute(f, file, name, smart, info, serial, family, model, interface) != 0) {
+ 1760 : /* LCOV_EXCL_START */
+ 1761 : pclose(f);
+ 1762 : log_tag("device:%s:%s:shell\n", file, name);
+ 1763 : return -1;
+ 1764 : /* LCOV_EXCL_STOP */
+ 1765 : }
+ 1766 :
+ 1767 14 : ret = pclose(f);
+ 1768 :
+ 1769 14 : log_tag("smartctl:%s:%s:ret: %x\n", file, name, ret);
+ 1770 :
+ 1771 14 : if (!WIFEXITED(ret)) {
+ 1772 : /* LCOV_EXCL_START */
+ 1773 : log_tag("device:%s:%s:abort\n", file, name);
+ 1774 : log_fatal(EEXTERNAL, "Failed to run '%s' (not exited).\n", cmd);
+ 1775 : return -1;
+ 1776 : /* LCOV_EXCL_STOP */
+ 1777 : }
+ 1778 14 : if (WEXITSTATUS(ret) == 127) {
+ 1779 : /* LCOV_EXCL_START */
+ 1780 : log_tag("device:%s:%s:shell\n", file, name);
+ 1781 : log_fatal(EEXTERNAL, "Failed to run '%s' (from sh).\n", cmd);
+ 1782 : return -1;
+ 1783 : /* LCOV_EXCL_STOP */
+ 1784 : }
+ 1785 :
+ 1786 14 : if (WEXITSTATUS(ret) == 3) {
+ 1787 12 : log_tag("attr:%s:%s:power:standby\n", file, name);
+ 1788 12 : *power = POWER_STANDBY;
+ 1789 : } else {
+ 1790 2 : log_tag("attr:%s:%s:power:active\n", file, name);
+ 1791 2 : *power = POWER_ACTIVE;
+ 1792 :
+ 1793 : /* store the smartctl return value */
+ 1794 2 : if (smart)
+ 1795 2 : smart[SMART_FLAGS].raw = WEXITSTATUS(ret);
+ 1796 : }
+ 1797 :
+ 1798 14 : return 0;
+ 1799 : }
+ 1800 : #endif
+ 1801 :
+ 1802 : /**
+ 1803 : * Spin down a specific device.
+ 1804 : */
+ 1805 : #if HAVE_LINUX_DEVICE
+ 1806 5 : static int devdown(dev_t device, const char* name, const char* smartctl)
+ 1807 : {
+ 1808 : char cmd[PATH_MAX + 64];
+ 1809 : char file[PATH_MAX];
+ 1810 : FILE* f;
+ 1811 : int ret;
+ 1812 : const char* x;
+ 1813 :
+ 1814 5 : x = find_smartctl();
+ 1815 5 : if (!x) {
+ 1816 : /* LCOV_EXCL_START */
+ 1817 : log_fatal(EEXTERNAL, "Cannot find smartctl.\n");
+ 1818 : return -1;
+ 1819 : /* LCOV_EXCL_STOP */
+ 1820 : }
+ 1821 :
+ 1822 5 : if (devresolve(device, file, sizeof(file)) != 0) {
+ 1823 : /* LCOV_EXCL_START */
+ 1824 : log_fatal(EEXTERNAL, "Failed to resolve device '%u:%u'.\n", major(device), minor(device));
+ 1825 : return -1;
+ 1826 : /* LCOV_EXCL_STOP */
+ 1827 : }
+ 1828 :
+ 1829 : /* if there is a custom smartctl command */
+ 1830 5 : if (smartctl[0]) {
+ 1831 : char option[PATH_MAX];
+ 1832 5 : snprintf(option, sizeof(option), smartctl, file);
+ 1833 5 : snprintf(cmd, sizeof(cmd), "%s -s standby,now %s", x, option);
+ 1834 : } else {
+ 1835 0 : snprintf(cmd, sizeof(cmd), "%s -s standby,now %s", x, file);
+ 1836 : }
+ 1837 :
+ 1838 5 : log_tag("smartctl:%s:%s:run: %s\n", file, name, cmd);
+ 1839 :
+ 1840 5 : f = popen(cmd, "r");
+ 1841 5 : if (!f) {
+ 1842 : /* LCOV_EXCL_START */
+ 1843 : log_tag("device:%s:%s:shell\n", file, name);
+ 1844 : log_fatal(EEXTERNAL, "Failed to run '%s' (from popen).\n", cmd);
+ 1845 : return -1;
+ 1846 : /* LCOV_EXCL_STOP */
+ 1847 : }
+ 1848 :
+ 1849 5 : if (smartctl_flush(f, file, name) != 0) {
+ 1850 : /* LCOV_EXCL_START */
+ 1851 : pclose(f);
+ 1852 : log_tag("device:%s:%s:shell\n", file, name);
+ 1853 : return -1;
+ 1854 : /* LCOV_EXCL_STOP */
+ 1855 : }
+ 1856 :
+ 1857 5 : ret = pclose(f);
+ 1858 :
+ 1859 5 : log_tag("smartctl:%s:%s:ret: %x\n", file, name, ret);
+ 1860 :
+ 1861 5 : if (!WIFEXITED(ret)) {
+ 1862 : /* LCOV_EXCL_START */
+ 1863 : log_tag("device:%s:%s:abort\n", file, name);
+ 1864 : log_fatal(EEXTERNAL, "Failed to run '%s' (not exited).\n", cmd);
+ 1865 : return -1;
+ 1866 : /* LCOV_EXCL_STOP */
+ 1867 : }
+ 1868 5 : if (WEXITSTATUS(ret) == 127) {
+ 1869 : /* LCOV_EXCL_START */
+ 1870 : log_tag("device:%s:%s:shell\n", file, name);
+ 1871 : log_fatal(EEXTERNAL, "Failed to run '%s' (from sh).\n", cmd);
+ 1872 : return -1;
+ 1873 : /* LCOV_EXCL_STOP */
+ 1874 : }
+ 1875 5 : if (WEXITSTATUS(ret) != 0) {
+ 1876 : /* LCOV_EXCL_START */
+ 1877 : log_tag("device:%s:%s:exit:%d\n", file, name, WEXITSTATUS(ret));
+ 1878 : log_fatal(EEXTERNAL, "Failed to run '%s' with return code %xh.\n", cmd, WEXITSTATUS(ret));
+ 1879 : return -1;
+ 1880 : /* LCOV_EXCL_STOP */
+ 1881 : }
+ 1882 :
+ 1883 0 : log_tag("attr:%s:%s:power:down\n", file, name);
+ 1884 :
+ 1885 0 : return 0;
+ 1886 : }
+ 1887 : #endif
1888 :
- 1889 0 : log_tag("attr:%s:%s:power:down\n", file, name);
- 1890 :
- 1891 0 : return 0;
- 1892 : }
- 1893 : #endif
- 1894 :
- 1895 : /**
- 1896 : * Spin down a specific device if it's up.
- 1897 : */
- 1898 : #if HAVE_LINUX_DEVICE
- 1899 0 : static int devdownifup(dev_t device, const char* name, const char* smartctl, int* power)
- 1900 : {
- 1901 0 : *power = POWER_UNKNOWN;
+ 1889 : /**
+ 1890 : * Spin down a specific device if it's up.
+ 1891 : */
+ 1892 : #if HAVE_LINUX_DEVICE
+ 1893 0 : static int devdownifup(dev_t device, const char* name, const char* smartctl, int* power)
+ 1894 : {
+ 1895 0 : *power = POWER_UNKNOWN;
+ 1896 :
+ 1897 0 : if (devprobe(device, name, smartctl, power, 0, 0, 0, 0, 0, 0) != 0)
+ 1898 0 : return -1;
+ 1899 :
+ 1900 0 : if (*power == POWER_ACTIVE)
+ 1901 0 : return devdown(device, name, smartctl);
1902 :
- 1903 0 : if (devprobe(device, name, smartctl, power, 0, 0, 0, 0, 0, 0) != 0)
- 1904 0 : return -1;
- 1905 :
- 1906 0 : if (*power == POWER_ACTIVE)
- 1907 0 : return devdown(device, name, smartctl);
- 1908 :
- 1909 0 : return 0;
- 1910 : }
- 1911 : #endif
- 1912 :
- 1913 : /**
- 1914 : * Spin up a specific device.
- 1915 : */
- 1916 : #if HAVE_LINUX_DEVICE
- 1917 30 : static int devup(dev_t device, const char* name)
- 1918 : {
- 1919 : char file[PATH_MAX];
- 1920 : int ret;
- 1921 : int f;
- 1922 : void* buf;
- 1923 : uint64_t size;
- 1924 : uint64_t offset;
- 1925 :
- 1926 30 : if (devresolve(device, file, sizeof(file)) != 0) {
- 1927 : /* LCOV_EXCL_START */
- 1928 : log_fatal(EEXTERNAL, "Failed to resolve device '%u:%u'.\n", major(device), minor(device));
- 1929 : return -1;
- 1930 : /* LCOV_EXCL_STOP */
- 1931 : }
- 1932 :
- 1933 : /* O_DIRECT requires memory aligned to the block size */
- 1934 30 : if (posix_memalign(&buf, 4096, 4096) != 0) {
- 1935 : /* LCOV_EXCL_START */
- 1936 : log_fatal(errno, "Failed to allocate aligned memory for device '%u:%u'.\n", major(device), minor(device));
- 1937 : return -1;
- 1938 : /* LCOV_EXCL_STOP */
- 1939 : }
- 1940 :
- 1941 30 : f = open(file, O_RDONLY | O_DIRECT);
- 1942 30 : if (f < 0) {
- 1943 : /* LCOV_EXCL_START */
- 1944 : free(buf);
- 1945 : log_tag("device:%s:%s:error:%d\n", file, name, errno);
- 1946 : log_fatal(errno, "Failed to open device '%u:%u'.\n", major(device), minor(device));
- 1947 : return -1;
- 1948 : /* LCOV_EXCL_STOP */
- 1949 : }
- 1950 :
- 1951 0 : if (ioctl(f, BLKGETSIZE64, &size) < 0) {
- 1952 : /* LCOV_EXCL_START */
- 1953 : close(f);
- 1954 : free(buf);
- 1955 : log_tag("device:%s:%s:error:%d\n", file, name, errno);
- 1956 : log_fatal(errno, "Failed to get device size '%u:%u'.\n", major(device), minor(device));
- 1957 : return -1;
- 1958 : /* LCOV_EXCL_STOP */
- 1959 : }
- 1960 :
- 1961 : /* select a random offset */
- 1962 0 : offset = (random_u64() % (size / 4096)) * 4096;
- 1963 :
- 1964 : #if HAVE_POSIX_FADVISE
- 1965 : /* clear cache */
- 1966 0 : ret = posix_fadvise(f, offset, 4096, POSIX_FADV_DONTNEED);
- 1967 0 : if (ret != 0) {
- 1968 : /* LCOV_EXCL_START */
- 1969 : close(f);
- 1970 : free(buf);
- 1971 : log_tag("device:%s:%s:error:%d\n", file, name, errno);
- 1972 : log_fatal(errno, "Failed to advise device '%u:%u'.\n", major(device), minor(device));
- 1973 : return -1;
- 1974 : /* LCOV_EXCL_STOP */
- 1975 : }
- 1976 : #endif
- 1977 :
- 1978 0 : ret = pread(f, buf, 4096, offset);
- 1979 0 : if (ret < 0) {
- 1980 : /* LCOV_EXCL_START */
- 1981 : close(f);
- 1982 : free(buf);
- 1983 : log_tag("device:%s:%s:error:%d\n", file, name, errno);
- 1984 : log_fatal(errno, "Failed to read device '%u:%u'.\n", major(device), minor(device));
- 1985 : return -1;
- 1986 : /* LCOV_EXCL_STOP */
- 1987 : }
- 1988 :
- 1989 0 : ret = close(f);
- 1990 0 : if (ret < 0) {
- 1991 : /* LCOV_EXCL_START */
- 1992 : free(buf);
- 1993 : log_tag("device:%s:%s:error:%d\n", file, name, errno);
- 1994 : log_fatal(errno, "Failed to close device '%u:%u'.\n", major(device), minor(device));
- 1995 : return -1;
- 1996 : /* LCOV_EXCL_STOP */
- 1997 : }
- 1998 :
- 1999 0 : log_tag("attr:%s:%s:power:up\n", file, name);
- 2000 :
- 2001 0 : free(buf);
- 2002 0 : return 0;
- 2003 : }
- 2004 : #endif
- 2005 :
- 2006 : /**
- 2007 : * Thread for spinning up.
- 2008 : *
- 2009 : * Note that filling up the devinfo object is done inside this thread,
- 2010 : * to avoid to block the main thread if the device need to be spin up
- 2011 : * to handle stat/resolve requests.
- 2012 : */
- 2013 30 : static void* thread_spinup(void* arg)
- 2014 : {
- 2015 : #if HAVE_LINUX_DEVICE
- 2016 30 : devinfo_t* devinfo = arg;
- 2017 : uint64_t start;
- 2018 :
- 2019 30 : start = tick_ms();
+ 1903 0 : return 0;
+ 1904 : }
+ 1905 : #endif
+ 1906 :
+ 1907 : /**
+ 1908 : * Spin up a specific device.
+ 1909 : */
+ 1910 : #if HAVE_LINUX_DEVICE
+ 1911 30 : static int devup(dev_t device, const char* name)
+ 1912 : {
+ 1913 : char file[PATH_MAX];
+ 1914 : int ret;
+ 1915 : int f;
+ 1916 : void* buf;
+ 1917 : uint64_t size;
+ 1918 : uint64_t offset;
+ 1919 :
+ 1920 30 : if (devresolve(device, file, sizeof(file)) != 0) {
+ 1921 : /* LCOV_EXCL_START */
+ 1922 : log_fatal(EEXTERNAL, "Failed to resolve device '%u:%u'.\n", major(device), minor(device));
+ 1923 : return -1;
+ 1924 : /* LCOV_EXCL_STOP */
+ 1925 : }
+ 1926 :
+ 1927 : /* O_DIRECT requires memory aligned to the block size */
+ 1928 30 : if (posix_memalign(&buf, 4096, 4096) != 0) {
+ 1929 : /* LCOV_EXCL_START */
+ 1930 : log_fatal(errno, "Failed to allocate aligned memory for device '%u:%u'.\n", major(device), minor(device));
+ 1931 : return -1;
+ 1932 : /* LCOV_EXCL_STOP */
+ 1933 : }
+ 1934 :
+ 1935 30 : f = open(file, O_RDONLY | O_DIRECT);
+ 1936 30 : if (f < 0) {
+ 1937 : /* LCOV_EXCL_START */
+ 1938 : free(buf);
+ 1939 : log_tag("device:%s:%s:error:%d\n", file, name, errno);
+ 1940 : log_fatal(errno, "Failed to open device '%u:%u'.\n", major(device), minor(device));
+ 1941 : return -1;
+ 1942 : /* LCOV_EXCL_STOP */
+ 1943 : }
+ 1944 :
+ 1945 0 : if (ioctl(f, BLKGETSIZE64, &size) < 0) {
+ 1946 : /* LCOV_EXCL_START */
+ 1947 : close(f);
+ 1948 : free(buf);
+ 1949 : log_tag("device:%s:%s:error:%d\n", file, name, errno);
+ 1950 : log_fatal(errno, "Failed to get device size '%u:%u'.\n", major(device), minor(device));
+ 1951 : return -1;
+ 1952 : /* LCOV_EXCL_STOP */
+ 1953 : }
+ 1954 :
+ 1955 : /* select a random offset */
+ 1956 0 : offset = (random_u64() % (size / 4096)) * 4096;
+ 1957 :
+ 1958 : #if HAVE_POSIX_FADVISE
+ 1959 : /* clear cache */
+ 1960 0 : ret = posix_fadvise(f, offset, 4096, POSIX_FADV_DONTNEED);
+ 1961 0 : if (ret != 0) {
+ 1962 : /* LCOV_EXCL_START */
+ 1963 : close(f);
+ 1964 : free(buf);
+ 1965 : log_tag("device:%s:%s:error:%d\n", file, name, errno);
+ 1966 : log_fatal(errno, "Failed to advise device '%u:%u'.\n", major(device), minor(device));
+ 1967 : return -1;
+ 1968 : /* LCOV_EXCL_STOP */
+ 1969 : }
+ 1970 : #endif
+ 1971 :
+ 1972 0 : ret = pread(f, buf, 4096, offset);
+ 1973 0 : if (ret < 0) {
+ 1974 : /* LCOV_EXCL_START */
+ 1975 : close(f);
+ 1976 : free(buf);
+ 1977 : log_tag("device:%s:%s:error:%d\n", file, name, errno);
+ 1978 : log_fatal(errno, "Failed to read device '%u:%u'.\n", major(device), minor(device));
+ 1979 : return -1;
+ 1980 : /* LCOV_EXCL_STOP */
+ 1981 : }
+ 1982 :
+ 1983 0 : ret = close(f);
+ 1984 0 : if (ret < 0) {
+ 1985 : /* LCOV_EXCL_START */
+ 1986 : free(buf);
+ 1987 : log_tag("device:%s:%s:error:%d\n", file, name, errno);
+ 1988 : log_fatal(errno, "Failed to close device '%u:%u'.\n", major(device), minor(device));
+ 1989 : return -1;
+ 1990 : /* LCOV_EXCL_STOP */
+ 1991 : }
+ 1992 :
+ 1993 0 : log_tag("attr:%s:%s:power:up\n", file, name);
+ 1994 :
+ 1995 0 : free(buf);
+ 1996 0 : return 0;
+ 1997 : }
+ 1998 : #endif
+ 1999 :
+ 2000 : /**
+ 2001 : * Thread for spinning up.
+ 2002 : *
+ 2003 : * Note that filling up the devinfo object is done inside this thread,
+ 2004 : * to avoid to block the main thread if the device need to be spin up
+ 2005 : * to handle stat/resolve requests.
+ 2006 : */
+ 2007 30 : static void* thread_spinup(void* arg)
+ 2008 : {
+ 2009 : #if HAVE_LINUX_DEVICE
+ 2010 30 : devinfo_t* devinfo = arg;
+ 2011 : uint64_t start;
+ 2012 :
+ 2013 30 : start = tick_ms();
+ 2014 :
+ 2015 30 : if (devup(devinfo->device, devinfo->name) != 0) {
+ 2016 : /* LCOV_EXCL_START */
+ 2017 : return (void*)-1;
+ 2018 : /* LCOV_EXCL_STOP */
+ 2019 : }
2020 :
- 2021 30 : if (devup(devinfo->device, devinfo->name) != 0) {
- 2022 : /* LCOV_EXCL_START */
- 2023 : return (void*)-1;
- 2024 : /* LCOV_EXCL_STOP */
- 2025 : }
- 2026 :
- 2027 0 : msg_status("Spunup device '%s' for disk '%s' in %" PRIu64 " ms.\n", devinfo->file, devinfo->name, tick_ms() - start);
- 2028 :
- 2029 : /* after the spin up, get SMART info */
- 2030 0 : if (devsmart(devinfo->device, devinfo->name, devinfo->smartctl, devinfo->smart, devinfo->info, devinfo->serial, devinfo->family, devinfo->model, devinfo->interf) != 0) {
- 2031 : /* LCOV_EXCL_START */
- 2032 : return (void*)-1;
- 2033 : /* LCOV_EXCL_STOP */
- 2034 : }
- 2035 :
- 2036 : /*
- 2037 : * Retrieve some attributes directly from the system.
- 2038 : *
- 2039 : * smartctl intentionally skips queries on devices in standby mode
- 2040 : * to prevent accidentally spinning them up.
- 2041 : */
- 2042 0 : devattr(devinfo->device, devinfo->info, devinfo->serial, devinfo->family, devinfo->model, devinfo->interf);
- 2043 :
- 2044 0 : return 0;
- 2045 : #else
- 2046 : (void)arg;
- 2047 : return (void*)-1;
- 2048 : #endif
- 2049 : }
- 2050 :
- 2051 : /**
- 2052 : * Thread for spinning down.
- 2053 : */
- 2054 5 : static void* thread_spindown(void* arg)
- 2055 : {
- 2056 : #if HAVE_LINUX_DEVICE
- 2057 5 : devinfo_t* devinfo = arg;
- 2058 : uint64_t start;
- 2059 :
- 2060 5 : start = tick_ms();
+ 2021 0 : msg_status("Spunup device '%s' for disk '%s' in %" PRIu64 " ms.\n", devinfo->file, devinfo->name, tick_ms() - start);
+ 2022 :
+ 2023 : /* after the spin up, get SMART info */
+ 2024 0 : if (devsmart(devinfo->device, devinfo->name, devinfo->smartctl, devinfo->smart, devinfo->info, devinfo->serial, devinfo->family, devinfo->model, devinfo->interf) != 0) {
+ 2025 : /* LCOV_EXCL_START */
+ 2026 : return (void*)-1;
+ 2027 : /* LCOV_EXCL_STOP */
+ 2028 : }
+ 2029 :
+ 2030 : /*
+ 2031 : * Retrieve some attributes directly from the system.
+ 2032 : *
+ 2033 : * smartctl intentionally skips queries on devices in standby mode
+ 2034 : * to prevent accidentally spinning them up.
+ 2035 : */
+ 2036 0 : devattr(devinfo->device, devinfo->info, devinfo->serial, devinfo->family, devinfo->model, devinfo->interf);
+ 2037 :
+ 2038 0 : return 0;
+ 2039 : #else
+ 2040 : (void)arg;
+ 2041 : return (void*)-1;
+ 2042 : #endif
+ 2043 : }
+ 2044 :
+ 2045 : /**
+ 2046 : * Thread for spinning down.
+ 2047 : */
+ 2048 5 : static void* thread_spindown(void* arg)
+ 2049 : {
+ 2050 : #if HAVE_LINUX_DEVICE
+ 2051 5 : devinfo_t* devinfo = arg;
+ 2052 : uint64_t start;
+ 2053 :
+ 2054 5 : start = tick_ms();
+ 2055 :
+ 2056 5 : if (devdown(devinfo->device, devinfo->name, devinfo->smartctl) != 0) {
+ 2057 : /* LCOV_EXCL_START */
+ 2058 : return (void*)-1;
+ 2059 : /* LCOV_EXCL_STOP */
+ 2060 : }
2061 :
- 2062 5 : if (devdown(devinfo->device, devinfo->name, devinfo->smartctl) != 0) {
- 2063 : /* LCOV_EXCL_START */
- 2064 : return (void*)-1;
- 2065 : /* LCOV_EXCL_STOP */
- 2066 : }
- 2067 :
- 2068 0 : msg_status("Spundown device '%s' for disk '%s' in %" PRIu64 " ms.\n", devinfo->file, devinfo->name, tick_ms() - start);
- 2069 :
- 2070 0 : return 0;
- 2071 : #else
- 2072 : (void)arg;
- 2073 : return (void*)-1;
- 2074 : #endif
- 2075 : }
- 2076 :
- 2077 : /**
- 2078 : * Thread for spinning down.
- 2079 : */
- 2080 0 : static void* thread_spindownifup(void* arg)
- 2081 : {
- 2082 : #if HAVE_LINUX_DEVICE
- 2083 0 : devinfo_t* devinfo = arg;
- 2084 : uint64_t start;
- 2085 : int power;
- 2086 :
- 2087 0 : start = tick_ms();
+ 2062 0 : msg_status("Spundown device '%s' for disk '%s' in %" PRIu64 " ms.\n", devinfo->file, devinfo->name, tick_ms() - start);
+ 2063 :
+ 2064 0 : return 0;
+ 2065 : #else
+ 2066 : (void)arg;
+ 2067 : return (void*)-1;
+ 2068 : #endif
+ 2069 : }
+ 2070 :
+ 2071 : /**
+ 2072 : * Thread for spinning down.
+ 2073 : */
+ 2074 0 : static void* thread_spindownifup(void* arg)
+ 2075 : {
+ 2076 : #if HAVE_LINUX_DEVICE
+ 2077 0 : devinfo_t* devinfo = arg;
+ 2078 : uint64_t start;
+ 2079 : int power;
+ 2080 :
+ 2081 0 : start = tick_ms();
+ 2082 :
+ 2083 0 : if (devdownifup(devinfo->device, devinfo->name, devinfo->smartctl, &power) != 0) {
+ 2084 : /* LCOV_EXCL_START */
+ 2085 : return (void*)-1;
+ 2086 : /* LCOV_EXCL_STOP */
+ 2087 : }
2088 :
- 2089 0 : if (devdownifup(devinfo->device, devinfo->name, devinfo->smartctl, &power) != 0) {
- 2090 : /* LCOV_EXCL_START */
- 2091 : return (void*)-1;
- 2092 : /* LCOV_EXCL_STOP */
- 2093 : }
- 2094 :
- 2095 0 : if (power == POWER_ACTIVE)
- 2096 0 : msg_status("Spundown device '%s' for disk '%s' in %" PRIu64 " ms.\n", devinfo->file, devinfo->name, tick_ms() - start);
- 2097 :
- 2098 0 : return 0;
- 2099 : #else
- 2100 : (void)arg;
- 2101 : return (void*)-1;
- 2102 : #endif
- 2103 : }
- 2104 :
- 2105 : /**
- 2106 : * Thread for getting smart info.
- 2107 : */
- 2108 0 : static void* thread_smart(void* arg)
- 2109 : {
- 2110 : #if HAVE_LINUX_DEVICE
- 2111 0 : devinfo_t* devinfo = arg;
+ 2089 0 : if (power == POWER_ACTIVE)
+ 2090 0 : msg_status("Spundown device '%s' for disk '%s' in %" PRIu64 " ms.\n", devinfo->file, devinfo->name, tick_ms() - start);
+ 2091 :
+ 2092 0 : return 0;
+ 2093 : #else
+ 2094 : (void)arg;
+ 2095 : return (void*)-1;
+ 2096 : #endif
+ 2097 : }
+ 2098 :
+ 2099 : /**
+ 2100 : * Thread for getting smart info.
+ 2101 : */
+ 2102 0 : static void* thread_smart(void* arg)
+ 2103 : {
+ 2104 : #if HAVE_LINUX_DEVICE
+ 2105 0 : devinfo_t* devinfo = arg;
+ 2106 :
+ 2107 0 : if (devsmart(devinfo->device, devinfo->name, devinfo->smartctl, devinfo->smart, devinfo->info, devinfo->serial, devinfo->family, devinfo->model, devinfo->interf) != 0) {
+ 2108 : /* LCOV_EXCL_START */
+ 2109 : return (void*)-1;
+ 2110 : /* LCOV_EXCL_STOP */
+ 2111 : }
2112 :
- 2113 0 : if (devsmart(devinfo->device, devinfo->name, devinfo->smartctl, devinfo->smart, devinfo->info, devinfo->serial, devinfo->family, devinfo->model, devinfo->interf) != 0) {
- 2114 : /* LCOV_EXCL_START */
- 2115 : return (void*)-1;
- 2116 : /* LCOV_EXCL_STOP */
- 2117 : }
- 2118 :
- 2119 : /*
- 2120 : * Retrieve some attributes directly from the system.
- 2121 : *
- 2122 : * smartctl intentionally skips queries on devices in standby mode
- 2123 : * to prevent accidentally spinning them up.
- 2124 : */
- 2125 0 : devattr(devinfo->device, devinfo->info, devinfo->serial, devinfo->family, devinfo->model, devinfo->interf);
- 2126 :
- 2127 0 : return 0;
- 2128 : #else
- 2129 : (void)arg;
- 2130 : return (void*)-1;
- 2131 : #endif
- 2132 : }
- 2133 :
- 2134 : /**
- 2135 : * Thread for getting power info.
- 2136 : */
- 2137 0 : static void* thread_probe(void* arg)
- 2138 : {
- 2139 : #if HAVE_LINUX_DEVICE
- 2140 0 : devinfo_t* devinfo = arg;
+ 2113 : /*
+ 2114 : * Retrieve some attributes directly from the system.
+ 2115 : *
+ 2116 : * smartctl intentionally skips queries on devices in standby mode
+ 2117 : * to prevent accidentally spinning them up.
+ 2118 : */
+ 2119 0 : devattr(devinfo->device, devinfo->info, devinfo->serial, devinfo->family, devinfo->model, devinfo->interf);
+ 2120 :
+ 2121 0 : return 0;
+ 2122 : #else
+ 2123 : (void)arg;
+ 2124 : return (void*)-1;
+ 2125 : #endif
+ 2126 : }
+ 2127 :
+ 2128 : /**
+ 2129 : * Thread for getting power info.
+ 2130 : */
+ 2131 14 : static void* thread_probe(void* arg)
+ 2132 : {
+ 2133 : #if HAVE_LINUX_DEVICE
+ 2134 14 : devinfo_t* devinfo = arg;
+ 2135 :
+ 2136 14 : if (devprobe(devinfo->device, devinfo->name, devinfo->smartctl, &devinfo->power, devinfo->smart, devinfo->info, devinfo->serial, devinfo->family, devinfo->model, devinfo->interf) != 0) {
+ 2137 : /* LCOV_EXCL_START */
+ 2138 : return (void*)-1;
+ 2139 : /* LCOV_EXCL_STOP */
+ 2140 : }
2141 :
- 2142 0 : if (devprobe(devinfo->device, devinfo->name, devinfo->smartctl, &devinfo->power, devinfo->smart, devinfo->info, devinfo->serial, devinfo->family, devinfo->model, devinfo->interf) != 0) {
- 2143 : /* LCOV_EXCL_START */
- 2144 : return (void*)-1;
- 2145 : /* LCOV_EXCL_STOP */
- 2146 : }
- 2147 :
- 2148 : /*
- 2149 : * Retrieve some attributes directly from the system.
- 2150 : *
- 2151 : * smartctl intentionally skips queries on devices in standby mode
- 2152 : * to prevent accidentally spinning them up.
- 2153 : */
- 2154 0 : devattr(devinfo->device, devinfo->info, devinfo->serial, devinfo->family, devinfo->model, devinfo->interf);
- 2155 :
- 2156 0 : return 0;
- 2157 : #else
- 2158 : (void)arg;
- 2159 : return (void*)-1;
- 2160 : #endif
- 2161 : }
- 2162 :
- 2163 2 : static int device_thread(tommy_list* list, void* (*func)(void* arg))
- 2164 : {
- 2165 2 : int fail = 0;
- 2166 : tommy_node* i;
- 2167 :
- 2168 : #if HAVE_THREAD
- 2169 : /* start all threads */
- 2170 37 : for (i = tommy_list_head(list); i != 0; i = i->next) {
- 2171 35 : devinfo_t* devinfo = i->data;
- 2172 :
- 2173 35 : thread_create(&devinfo->thread, func, devinfo);
- 2174 : }
- 2175 :
- 2176 : /* join all threads */
- 2177 37 : for (i = tommy_list_head(list); i != 0; i = i->next) {
- 2178 35 : devinfo_t* devinfo = i->data;
- 2179 : void* retval;
- 2180 :
- 2181 35 : thread_join(devinfo->thread, &retval);
- 2182 :
- 2183 35 : if (retval != 0)
- 2184 35 : ++fail;
- 2185 : }
- 2186 : #else
- 2187 : for (i = tommy_list_head(list); i != 0; i = i->next) {
- 2188 : devinfo_t* devinfo = i->data;
- 2189 :
- 2190 : if (func(devinfo) != 0)
- 2191 : ++fail;
+ 2142 : /*
+ 2143 : * Retrieve some attributes directly from the system.
+ 2144 : *
+ 2145 : * smartctl intentionally skips queries on devices in standby mode
+ 2146 : * to prevent accidentally spinning them up.
+ 2147 : */
+ 2148 14 : devattr(devinfo->device, devinfo->info, devinfo->serial, devinfo->family, devinfo->model, devinfo->interf);
+ 2149 :
+ 2150 14 : return 0;
+ 2151 : #else
+ 2152 : (void)arg;
+ 2153 : return (void*)-1;
+ 2154 : #endif
+ 2155 : }
+ 2156 :
+ 2157 3 : static int device_thread(tommy_list* list, void* (*func)(void* arg))
+ 2158 : {
+ 2159 3 : int fail = 0;
+ 2160 : tommy_node* i;
+ 2161 :
+ 2162 : #if HAVE_THREAD
+ 2163 : /* start all threads */
+ 2164 52 : for (i = tommy_list_head(list); i != 0; i = i->next) {
+ 2165 49 : devinfo_t* devinfo = i->data;
+ 2166 :
+ 2167 49 : thread_create(&devinfo->thread, func, devinfo);
+ 2168 : }
+ 2169 :
+ 2170 : /* join all threads */
+ 2171 52 : for (i = tommy_list_head(list); i != 0; i = i->next) {
+ 2172 49 : devinfo_t* devinfo = i->data;
+ 2173 : void* retval;
+ 2174 :
+ 2175 49 : thread_join(devinfo->thread, &retval);
+ 2176 :
+ 2177 49 : if (retval != 0)
+ 2178 35 : ++fail;
+ 2179 : }
+ 2180 : #else
+ 2181 : for (i = tommy_list_head(list); i != 0; i = i->next) {
+ 2182 : devinfo_t* devinfo = i->data;
+ 2183 :
+ 2184 : if (func(devinfo) != 0)
+ 2185 : ++fail;
+ 2186 : }
+ 2187 : #endif
+ 2188 3 : if (fail != 0) {
+ 2189 : /* LCOV_EXCL_START */
+ 2190 : return -1;
+ 2191 : /* LCOV_EXCL_STOP */
2192 : }
- 2193 : #endif
- 2194 2 : if (fail != 0) {
- 2195 : /* LCOV_EXCL_START */
- 2196 : return -1;
- 2197 : /* LCOV_EXCL_STOP */
- 2198 : }
- 2199 :
- 2200 0 : return 0;
- 2201 : }
- 2202 :
- 2203 3 : int devquery(tommy_list* high, tommy_list* low, int operation, int others)
- 2204 : {
- 2205 3 : void* (*func)(void* arg) = 0;
- 2206 :
- 2207 : #if HAVE_LINUX_DEVICE
- 2208 : tommy_node* i;
- 2209 : struct stat st;
- 2210 :
- 2211 : /* sysfs interface is required */
- 2212 3 : if (stat("/sys/dev/block", &st) != 0) {
- 2213 : /* LCOV_EXCL_START */
- 2214 : log_fatal(EEXTERNAL, "Missing interface /sys/dev/block.\n");
- 2215 : return -1;
- 2216 : /* LCOV_EXCL_STOP */
- 2217 : }
+ 2193 :
+ 2194 1 : return 0;
+ 2195 : }
+ 2196 :
+ 2197 4 : int devquery(tommy_list* high, tommy_list* low, int operation, int others)
+ 2198 : {
+ 2199 4 : void* (*func)(void* arg) = 0;
+ 2200 :
+ 2201 : #if HAVE_LINUX_DEVICE
+ 2202 : tommy_node* i;
+ 2203 : struct stat st;
+ 2204 :
+ 2205 : /* sysfs interface is required */
+ 2206 4 : if (stat("/sys/dev/block", &st) != 0) {
+ 2207 : /* LCOV_EXCL_START */
+ 2208 : log_fatal(EEXTERNAL, "Missing interface /sys/dev/block.\n");
+ 2209 : return -1;
+ 2210 : /* LCOV_EXCL_STOP */
+ 2211 : }
+ 2212 :
+ 2213 : /* for each device */
+ 2214 81 : for (i = tommy_list_head(high); i != 0; i = i->next) {
+ 2215 77 : devinfo_t* devinfo = i->data;
+ 2216 77 : uint64_t device = devinfo->device;
+ 2217 : uint64_t access_stat;
2218 :
- 2219 : /* for each device */
- 2220 68 : for (i = tommy_list_head(high); i != 0; i = i->next) {
- 2221 65 : devinfo_t* devinfo = i->data;
- 2222 65 : uint64_t device = devinfo->device;
- 2223 : uint64_t access_stat;
- 2224 :
- 2225 : #if HAVE_SYNCFS
- 2226 65 : if (operation == DEVICE_DOWN) {
- 2227 : /* flush the high level filesystem before spinning down */
- 2228 5 : int f = open(devinfo->mount, O_RDONLY);
- 2229 5 : if (f >= 0) {
- 2230 5 : syncfs(f);
- 2231 5 : close(f);
- 2232 : }
- 2233 : }
- 2234 : #endif
- 2235 :
- 2236 : /* if the major is the null device, find the real one */
- 2237 65 : if (major(device) == 0) {
- 2238 : /* obtain the real device */
- 2239 0 : if (devdereference(device, &device) != 0) {
- 2240 : /* LCOV_EXCL_START */
- 2241 : log_fatal(EEXTERNAL, "Failed to dereference device '%u:%u'.\n", major(device), minor(device));
- 2242 : return -1;
- 2243 : /* LCOV_EXCL_STOP */
- 2244 : }
- 2245 : }
- 2246 :
- 2247 : /* retrieve access stat for the high level device */
- 2248 65 : if (devstat(device, &access_stat) == 0) {
- 2249 : /* cumulate access stat in the first split */
- 2250 65 : if (devinfo->split)
- 2251 39 : devinfo->split->access_stat += access_stat;
- 2252 : else
- 2253 26 : devinfo->access_stat += access_stat;
- 2254 : }
- 2255 :
- 2256 : /* get the device file */
- 2257 65 : if (devresolve(device, devinfo->file, sizeof(devinfo->file)) != 0) {
- 2258 : /* LCOV_EXCL_START */
- 2259 : log_fatal(EEXTERNAL, "Failed to resolve device '%u:%u'.\n", major(device), minor(device));
- 2260 : return -1;
- 2261 : /* LCOV_EXCL_STOP */
- 2262 : }
- 2263 :
- 2264 : /* expand the tree of devices */
- 2265 65 : if (devtree(devinfo, device, low) != 0) {
- 2266 : /* LCOV_EXCL_START */
- 2267 : log_fatal(EEXTERNAL, "Failed to expand device '%u:%u'.\n", major(device), minor(device));
- 2268 : return -1;
- 2269 : /* LCOV_EXCL_STOP */
- 2270 : }
- 2271 : }
- 2272 :
- 2273 : /* add other devices */
- 2274 3 : if (others) {
- 2275 0 : if (devscan(low) != 0) {
- 2276 : /* LCOV_EXCL_START */
- 2277 : log_fatal(EEXTERNAL, "Failed to list other devices.\n");
- 2278 : return -1;
- 2279 : /* LCOV_EXCL_STOP */
- 2280 : }
- 2281 : }
- 2282 : #else
- 2283 : (void)high;
- 2284 : (void)others;
- 2285 : #endif
- 2286 :
- 2287 3 : switch (operation) {
- 2288 1 : case DEVICE_UP : func = thread_spinup; break;
- 2289 1 : case DEVICE_DOWN : func = thread_spindown; break;
- 2290 0 : case DEVICE_SMART : func = thread_smart; break;
- 2291 0 : case DEVICE_PROBE : func = thread_probe; break;
- 2292 0 : case DEVICE_DOWNIFUP : func = thread_spindownifup; break;
- 2293 : }
+ 2219 : #if HAVE_SYNCFS
+ 2220 77 : if (operation == DEVICE_DOWN) {
+ 2221 : /* flush the high level filesystem before spinning down */
+ 2222 5 : int f = open(devinfo->mount, O_RDONLY);
+ 2223 5 : if (f >= 0) {
+ 2224 5 : syncfs(f);
+ 2225 5 : close(f);
+ 2226 : }
+ 2227 : }
+ 2228 : #endif
+ 2229 :
+ 2230 : /* if the major is the null device, find the real one */
+ 2231 77 : if (major(device) == 0) {
+ 2232 : /* obtain the real device */
+ 2233 0 : if (devdereference(device, &device) != 0) {
+ 2234 : /* LCOV_EXCL_START */
+ 2235 : log_fatal(EEXTERNAL, "Failed to dereference device '%u:%u'.\n", major(device), minor(device));
+ 2236 : return -1;
+ 2237 : /* LCOV_EXCL_STOP */
+ 2238 : }
+ 2239 : }
+ 2240 :
+ 2241 : /* retrieve access stat for the high level device */
+ 2242 77 : if (devstat(device, &access_stat) == 0) {
+ 2243 : /* cumulate access stat in the first split */
+ 2244 77 : if (devinfo->split)
+ 2245 39 : devinfo->split->access_stat += access_stat;
+ 2246 : else
+ 2247 38 : devinfo->access_stat += access_stat;
+ 2248 : }
+ 2249 :
+ 2250 : /* get the device file */
+ 2251 77 : if (devresolve(device, devinfo->file, sizeof(devinfo->file)) != 0) {
+ 2252 : /* LCOV_EXCL_START */
+ 2253 : log_fatal(EEXTERNAL, "Failed to resolve device '%u:%u'.\n", major(device), minor(device));
+ 2254 : return -1;
+ 2255 : /* LCOV_EXCL_STOP */
+ 2256 : }
+ 2257 :
+ 2258 : /* expand the tree of devices */
+ 2259 77 : if (devtree(devinfo, device, low) != 0) {
+ 2260 : /* LCOV_EXCL_START */
+ 2261 : log_fatal(EEXTERNAL, "Failed to expand device '%u:%u'.\n", major(device), minor(device));
+ 2262 : return -1;
+ 2263 : /* LCOV_EXCL_STOP */
+ 2264 : }
+ 2265 : }
+ 2266 :
+ 2267 : /* add other devices */
+ 2268 4 : if (others) {
+ 2269 1 : if (devscan(low) != 0) {
+ 2270 : /* LCOV_EXCL_START */
+ 2271 : log_fatal(EEXTERNAL, "Failed to list other devices.\n");
+ 2272 : return -1;
+ 2273 : /* LCOV_EXCL_STOP */
+ 2274 : }
+ 2275 : }
+ 2276 : #else
+ 2277 : (void)high;
+ 2278 : (void)others;
+ 2279 : #endif
+ 2280 :
+ 2281 4 : switch (operation) {
+ 2282 1 : case DEVICE_UP : func = thread_spinup; break;
+ 2283 1 : case DEVICE_DOWN : func = thread_spindown; break;
+ 2284 0 : case DEVICE_SMART : func = thread_smart; break;
+ 2285 1 : case DEVICE_PROBE : func = thread_probe; break;
+ 2286 0 : case DEVICE_DOWNIFUP : func = thread_spindownifup; break;
+ 2287 : }
+ 2288 :
+ 2289 4 : if (!func)
+ 2290 1 : return 0;
+ 2291 :
+ 2292 3 : return device_thread(low, func);
+ 2293 : }
2294 :
- 2295 3 : if (!func)
- 2296 1 : return 0;
- 2297 :
- 2298 2 : return device_thread(low, func);
- 2299 : }
- 2300 :
- 2301 283 : void os_init(int opt)
- 2302 : {
- 2303 : #if HAVE_BLKID
- 2304 : int ret;
- 2305 283 : ret = blkid_get_cache(&cache, NULL);
- 2306 283 : if (ret != 0) {
- 2307 : /* LCOV_EXCL_START */
- 2308 : log_fatal(EEXTERNAL, "WARNING Failed to get blkid cache\n");
- 2309 : /* LCOV_EXCL_STOP */
- 2310 : }
- 2311 : #endif
- 2312 :
- 2313 : (void)opt;
- 2314 283 : }
- 2315 :
- 2316 272 : void os_done(void)
- 2317 : {
- 2318 : #if HAVE_BLKID
- 2319 272 : if (cache != 0)
- 2320 272 : blkid_put_cache(cache);
- 2321 : #endif
- 2322 272 : }
- 2323 :
- 2324 : /* LCOV_EXCL_START */
- 2325 : void os_abort(void)
- 2326 : {
- 2327 : #if HAVE_BACKTRACE && HAVE_BACKTRACE_SYMBOLS
- 2328 : void* stack[32];
- 2329 : char** messages;
- 2330 : size_t size;
- 2331 : unsigned i;
- 2332 : #endif
- 2333 :
- 2334 : printf("Stacktrace of " PACKAGE " v" VERSION);
- 2335 : #ifdef _linux
- 2336 : printf(", linux");
- 2337 : #endif
- 2338 : #ifdef __GNUC__
- 2339 : printf(", gcc " __VERSION__);
- 2340 : #endif
- 2341 : printf(", %d-bit", (int)sizeof(void*) * 8);
- 2342 : printf(", PATH_MAX=%d", PATH_MAX);
- 2343 : printf("\n");
- 2344 :
- 2345 : #if HAVE_BACKTRACE && HAVE_BACKTRACE_SYMBOLS
- 2346 : size = backtrace(stack, 32);
- 2347 :
- 2348 : messages = backtrace_symbols(stack, size);
- 2349 :
- 2350 : for (i = 1; i < size; ++i) {
- 2351 : const char* msg;
- 2352 :
- 2353 : if (messages)
- 2354 : msg = messages[i];
- 2355 : else
- 2356 : msg = "<unknown>";
- 2357 :
- 2358 : printf("[bt] %02u: %s\n", i, msg);
- 2359 :
- 2360 : if (messages) {
- 2361 : int ret;
- 2362 : char addr2line[1024];
- 2363 : size_t j = 0;
- 2364 : while (msg[j] != '(' && msg[j] != ' ' && msg[j] != 0)
- 2365 : ++j;
- 2366 :
- 2367 : snprintf(addr2line, sizeof(addr2line), "addr2line %p -e %.*s", stack[i], (unsigned)j, msg);
- 2368 :
- 2369 : ret = system(addr2line);
- 2370 : if (WIFEXITED(ret) && WEXITSTATUS(ret) != 0)
- 2371 : printf("exit:%d\n", WEXITSTATUS(ret));
- 2372 : if (WIFSIGNALED(ret))
- 2373 : printf("signal:%d\n", WTERMSIG(ret));
- 2374 : }
- 2375 : }
- 2376 : #endif
- 2377 :
- 2378 : printf("Please report this error to the SnapRAID Forum:\n");
- 2379 : printf("https://sourceforge.net/p/snapraid/discussion/1677233/\n");
- 2380 :
- 2381 : abort();
- 2382 : }
- 2383 : /* LCOV_EXCL_STOP */
- 2384 :
- 2385 1 : void os_clear(void)
- 2386 : {
- 2387 : /* ANSI codes */
- 2388 1 : printf("\033[H"); /* cursor at topleft */
- 2389 1 : printf("\033[2J"); /* clear screen */
- 2390 1 : }
+ 2295 284 : void os_init(int opt)
+ 2296 : {
+ 2297 : #if HAVE_BLKID
+ 2298 : int ret;
+ 2299 284 : ret = blkid_get_cache(&cache, NULL);
+ 2300 284 : if (ret != 0) {
+ 2301 : /* LCOV_EXCL_START */
+ 2302 : log_fatal(EEXTERNAL, "WARNING Failed to get blkid cache\n");
+ 2303 : /* LCOV_EXCL_STOP */
+ 2304 : }
+ 2305 : #endif
+ 2306 :
+ 2307 : (void)opt;
+ 2308 284 : }
+ 2309 :
+ 2310 273 : void os_done(void)
+ 2311 : {
+ 2312 : #if HAVE_BLKID
+ 2313 273 : if (cache != 0)
+ 2314 273 : blkid_put_cache(cache);
+ 2315 : #endif
+ 2316 273 : }
+ 2317 :
+ 2318 : /* LCOV_EXCL_START */
+ 2319 : void os_abort(void)
+ 2320 : {
+ 2321 : #if HAVE_BACKTRACE && HAVE_BACKTRACE_SYMBOLS
+ 2322 : void* stack[32];
+ 2323 : char** messages;
+ 2324 : size_t size;
+ 2325 : unsigned i;
+ 2326 : #endif
+ 2327 :
+ 2328 : printf("Stacktrace of " PACKAGE " v" VERSION);
+ 2329 : #ifdef _linux
+ 2330 : printf(", linux");
+ 2331 : #endif
+ 2332 : #ifdef __GNUC__
+ 2333 : printf(", gcc " __VERSION__);
+ 2334 : #endif
+ 2335 : printf(", %d-bit", (int)sizeof(void*) * 8);
+ 2336 : printf(", PATH_MAX=%d", PATH_MAX);
+ 2337 : printf("\n");
+ 2338 :
+ 2339 : #if HAVE_BACKTRACE && HAVE_BACKTRACE_SYMBOLS
+ 2340 : size = backtrace(stack, 32);
+ 2341 :
+ 2342 : messages = backtrace_symbols(stack, size);
+ 2343 :
+ 2344 : for (i = 1; i < size; ++i) {
+ 2345 : const char* msg;
+ 2346 :
+ 2347 : if (messages)
+ 2348 : msg = messages[i];
+ 2349 : else
+ 2350 : msg = "<unknown>";
+ 2351 :
+ 2352 : printf("[bt] %02u: %s\n", i, msg);
+ 2353 :
+ 2354 : if (messages) {
+ 2355 : int ret;
+ 2356 : char addr2line[1024];
+ 2357 : size_t j = 0;
+ 2358 : while (msg[j] != '(' && msg[j] != ' ' && msg[j] != 0)
+ 2359 : ++j;
+ 2360 :
+ 2361 : snprintf(addr2line, sizeof(addr2line), "addr2line %p -e %.*s", stack[i], (unsigned)j, msg);
+ 2362 :
+ 2363 : ret = system(addr2line);
+ 2364 : if (WIFEXITED(ret) && WEXITSTATUS(ret) != 0)
+ 2365 : printf("exit:%d\n", WEXITSTATUS(ret));
+ 2366 : if (WIFSIGNALED(ret))
+ 2367 : printf("signal:%d\n", WTERMSIG(ret));
+ 2368 : }
+ 2369 : }
+ 2370 : #endif
+ 2371 :
+ 2372 : printf("Please report this error to the SnapRAID Forum:\n");
+ 2373 : printf("https://sourceforge.net/p/snapraid/discussion/1677233/\n");
+ 2374 :
+ 2375 : abort();
+ 2376 : }
+ 2377 : /* LCOV_EXCL_STOP */
+ 2378 :
+ 2379 1 : void os_clear(void)
+ 2380 : {
+ 2381 : /* ANSI codes */
+ 2382 1 : printf("\033[H"); /* cursor at topleft */
+ 2383 1 : printf("\033[2J"); /* clear screen */
+ 2384 1 : }
+ 2385 :
+ 2386 7 : size_t direct_size(void)
+ 2387 : {
+ 2388 : long size;
+ 2389 :
+ 2390 7 : size = sysconf(_SC_PAGESIZE);
2391 :
- 2392 7 : size_t direct_size(void)
- 2393 : {
- 2394 : long size;
- 2395 :
- 2396 7 : size = sysconf(_SC_PAGESIZE);
- 2397 :
- 2398 7 : if (size == -1) {
- 2399 : /* LCOV_EXCL_START */
- 2400 : log_fatal(EEXTERNAL, "No page size\n");
- 2401 : exit(EXIT_FAILURE);
- 2402 : /* LCOV_EXCL_STOP */
- 2403 : }
- 2404 :
- 2405 7 : return size;
- 2406 : }
- 2407 :
- 2408 : #if HAVE_LINUX_DEVICE
- 2409 :
- 2410 : /* List of possible ambient temperature labels */
- 2411 : const char* AMBIENT_LABEL[] = {
- 2412 : "systin",
- 2413 : "auxtin",
- 2414 : "mb",
- 2415 : "m/b",
- 2416 : "board",
- 2417 : "motherboard",
- 2418 : "system",
- 2419 : "chassis",
- 2420 : "case",
- 2421 : "room",
- 2422 : "ambient",
- 2423 : 0
- 2424 : };
+ 2392 7 : if (size == -1) {
+ 2393 : /* LCOV_EXCL_START */
+ 2394 : log_fatal(EEXTERNAL, "No page size\n");
+ 2395 : exit(EXIT_FAILURE);
+ 2396 : /* LCOV_EXCL_STOP */
+ 2397 : }
+ 2398 :
+ 2399 7 : return size;
+ 2400 : }
+ 2401 :
+ 2402 : #if HAVE_LINUX_DEVICE
+ 2403 :
+ 2404 : /* List of possible ambient temperature labels */
+ 2405 : const char* AMBIENT_LABEL[] = {
+ 2406 : "systin",
+ 2407 : "auxtin",
+ 2408 : "mb",
+ 2409 : "m/b",
+ 2410 : "board",
+ 2411 : "motherboard",
+ 2412 : "system",
+ 2413 : "chassis",
+ 2414 : "case",
+ 2415 : "room",
+ 2416 : "ambient",
+ 2417 : 0
+ 2418 : };
+ 2419 :
+ 2420 1 : int ambient_temperature(void)
+ 2421 : {
+ 2422 : DIR* dir;
+ 2423 : struct dirent* entry;
+ 2424 1 : int lowest_temp = 0;
2425 :
- 2426 1 : int ambient_temperature(void)
- 2427 : {
- 2428 : DIR* dir;
- 2429 : struct dirent* entry;
- 2430 1 : int lowest_temp = 0;
- 2431 :
- 2432 1 : dir = opendir("/sys/class/hwmon");
- 2433 1 : if (!dir)
- 2434 0 : return 0;
+ 2426 1 : dir = opendir("/sys/class/hwmon");
+ 2427 1 : if (!dir)
+ 2428 0 : return 0;
+ 2429 :
+ 2430 : /* iterate through hwmon devices */
+ 2431 5 : while ((entry = readdir(dir)) != NULL) {
+ 2432 : char path[PATH_MAX];
+ 2433 : DIR* hwmon_dir;
+ 2434 : struct dirent* hwmon_entry;
2435 :
- 2436 : /* iterate through hwmon devices */
- 2437 5 : while ((entry = readdir(dir)) != NULL) {
- 2438 : char path[PATH_MAX];
- 2439 : DIR* hwmon_dir;
- 2440 : struct dirent* hwmon_entry;
- 2441 :
- 2442 4 : if (strncmp(entry->d_name, "hwmon", 5) != 0)
- 2443 2 : continue;
- 2444 :
- 2445 2 : pathprint(path, sizeof(path), "/sys/class/hwmon/%s", entry->d_name);
- 2446 :
- 2447 : /* iterate through temp*_input files */
- 2448 2 : hwmon_dir = opendir(path);
- 2449 2 : if (!hwmon_dir)
- 2450 0 : continue;
- 2451 :
- 2452 66 : while ((hwmon_entry = readdir(hwmon_dir)) != NULL) {
- 2453 : char value[128];
- 2454 : char name[128];
- 2455 : char label[128];
- 2456 : char* dash;
- 2457 : char* e;
- 2458 : int temp;
- 2459 :
- 2460 64 : if (strncmp(hwmon_entry->d_name, "temp", 4) != 0)
- 2461 63 : continue;
- 2462 :
- 2463 18 : dash = strrchr(hwmon_entry->d_name, '_');
- 2464 18 : if (dash == 0)
- 2465 0 : continue;
+ 2436 4 : if (strncmp(entry->d_name, "hwmon", 5) != 0)
+ 2437 2 : continue;
+ 2438 :
+ 2439 2 : pathprint(path, sizeof(path), "/sys/class/hwmon/%s", entry->d_name);
+ 2440 :
+ 2441 : /* iterate through temp*_input files */
+ 2442 2 : hwmon_dir = opendir(path);
+ 2443 2 : if (!hwmon_dir)
+ 2444 0 : continue;
+ 2445 :
+ 2446 66 : while ((hwmon_entry = readdir(hwmon_dir)) != NULL) {
+ 2447 : char value[128];
+ 2448 : char name[128];
+ 2449 : char label[128];
+ 2450 : char* dash;
+ 2451 : char* e;
+ 2452 : int temp;
+ 2453 :
+ 2454 64 : if (strncmp(hwmon_entry->d_name, "temp", 4) != 0)
+ 2455 63 : continue;
+ 2456 :
+ 2457 18 : dash = strrchr(hwmon_entry->d_name, '_');
+ 2458 18 : if (dash == 0)
+ 2459 0 : continue;
+ 2460 :
+ 2461 18 : if (strcmp(dash, "_input") != 0)
+ 2462 14 : continue;
+ 2463 :
+ 2464 : /* read the temperature */
+ 2465 4 : pathprint(path, sizeof(path), "/sys/class/hwmon/%s/%s", entry->d_name, hwmon_entry->d_name);
2466 :
- 2467 18 : if (strcmp(dash, "_input") != 0)
- 2468 14 : continue;
+ 2467 4 : if (sysattr(path, value, sizeof(value)) != 0)
+ 2468 0 : continue;
2469 :
- 2470 : /* read the temperature */
- 2471 4 : pathprint(path, sizeof(path), "/sys/class/hwmon/%s/%s", entry->d_name, hwmon_entry->d_name);
- 2472 :
- 2473 4 : if (!sysattr(path, value, sizeof(value)))
- 2474 0 : continue;
- 2475 :
- 2476 4 : temp = strtol(value, &e, 10) / 1000;
- 2477 4 : if (*e != 0 && !isspace(*e))
- 2478 0 : continue;
- 2479 :
- 2480 : /* cut the file name at "_input" */
- 2481 4 : *dash = 0;
- 2482 :
- 2483 : /* read the corresponding name */
- 2484 4 : pathprint(path, sizeof(path), "/sys/class/hwmon/%s/name", entry->d_name);
- 2485 4 : if (!sysattr(path, name, sizeof(name))) {
- 2486 : /* fallback to using the hwmon entry */
- 2487 0 : pathcpy(name, sizeof(name), entry->d_name);
- 2488 : }
- 2489 :
- 2490 : /* read the corresponding label file */
- 2491 4 : pathprint(path, sizeof(path), "/sys/class/hwmon/%s/%s_label", entry->d_name, hwmon_entry->d_name);
- 2492 4 : if (!sysattr(path, label, sizeof(label))) {
- 2493 : /* fallback to using the temp* name (e.g., temp1, temp2) */
- 2494 0 : pathcpy(label, sizeof(label), hwmon_entry->d_name);
- 2495 : }
+ 2470 4 : temp = strtol(value, &e, 10) / 1000;
+ 2471 4 : if (*e != 0 && !isspace(*e))
+ 2472 0 : continue;
+ 2473 :
+ 2474 : /* cut the file name at "_input" */
+ 2475 4 : *dash = 0;
+ 2476 :
+ 2477 : /* read the corresponding name */
+ 2478 4 : pathprint(path, sizeof(path), "/sys/class/hwmon/%s/name", entry->d_name);
+ 2479 4 : if (sysattr(path, name, sizeof(name)) != 0) {
+ 2480 : /* fallback to using the hwmon name */
+ 2481 0 : pathcpy(name, sizeof(name), entry->d_name);
+ 2482 : }
+ 2483 :
+ 2484 : /* read the corresponding label file */
+ 2485 4 : pathprint(path, sizeof(path), "/sys/class/hwmon/%s/%s_label", entry->d_name, hwmon_entry->d_name);
+ 2486 4 : if (sysattr(path, label, sizeof(label)) != 0) {
+ 2487 : /* fallback to using the temp* name (e.g., temp1, temp2) */
+ 2488 0 : pathcpy(label, sizeof(label), hwmon_entry->d_name);
+ 2489 : }
+ 2490 :
+ 2491 4 : log_tag("thermal:ambient:device:%s:%s:%s:%s:%d\n", entry->d_name, name, hwmon_entry->d_name, label, temp);
+ 2492 :
+ 2493 : /* check if temperature is in reasonable range */
+ 2494 4 : if (temp < 15 || temp > 40)
+ 2495 3 : continue;
2496 :
- 2497 4 : log_tag("thermal:ambient:device:%s:%s:%s:%s:%d\n", entry->d_name, name, hwmon_entry->d_name, label, temp);
- 2498 :
- 2499 : /* check if temperature is in reasonable range */
- 2500 4 : if (temp < 15 || temp > 40)
- 2501 3 : continue;
- 2502 :
- 2503 : /* lower case */
- 2504 1 : strlwr(label);
- 2505 :
- 2506 : /* check if label matches possible ambient labels */
- 2507 3 : for (int i = 0; AMBIENT_LABEL[i]; ++i) {
- 2508 3 : if (worddigitstr(label, AMBIENT_LABEL[i]) != 0) {
- 2509 1 : log_tag("thermal:ambient:candidate:%d\n", temp);
- 2510 1 : if (lowest_temp == 0 || lowest_temp > temp)
- 2511 1 : lowest_temp = temp;
- 2512 1 : break;
- 2513 : }
- 2514 : }
- 2515 :
- 2516 : /* accept also generic "temp1" */
- 2517 1 : if (strcmp(label, "temp1") == 0) {
- 2518 0 : log_tag("thermal:ambient:candidate:%d\n", temp);
- 2519 0 : if (lowest_temp == 0 || lowest_temp > temp)
- 2520 0 : lowest_temp = temp;
- 2521 : }
- 2522 : }
- 2523 :
- 2524 2 : closedir(hwmon_dir);
- 2525 : }
- 2526 :
- 2527 1 : closedir(dir);
- 2528 :
- 2529 1 : return lowest_temp;
- 2530 : }
- 2531 : #else
- 2532 : int ambient_temperature(void)
- 2533 : {
- 2534 : return 0;
- 2535 : }
- 2536 : #endif
- 2537 :
- 2538 : #endif
- 2539 :
+ 2497 : /* lower case */
+ 2498 1 : strlwr(label);
+ 2499 :
+ 2500 : /* check if label matches possible ambient labels */
+ 2501 3 : for (int i = 0; AMBIENT_LABEL[i]; ++i) {
+ 2502 3 : if (worddigitstr(label, AMBIENT_LABEL[i]) != 0) {
+ 2503 1 : log_tag("thermal:ambient:candidate:%d\n", temp);
+ 2504 1 : if (lowest_temp == 0 || lowest_temp > temp)
+ 2505 1 : lowest_temp = temp;
+ 2506 1 : break;
+ 2507 : }
+ 2508 : }
+ 2509 :
+ 2510 : /* accept also generic "temp1" */
+ 2511 1 : if (strcmp(label, "temp1") == 0) {
+ 2512 0 : log_tag("thermal:ambient:candidate:%d\n", temp);
+ 2513 0 : if (lowest_temp == 0 || lowest_temp > temp)
+ 2514 0 : lowest_temp = temp;
+ 2515 : }
+ 2516 : }
+ 2517 :
+ 2518 2 : closedir(hwmon_dir);
+ 2519 : }
+ 2520 :
+ 2521 1 : closedir(dir);
+ 2522 :
+ 2523 1 : return lowest_temp;
+ 2524 : }
+ 2525 : #else
+ 2526 : int ambient_temperature(void)
+ 2527 : {
+ 2528 : return 0;
+ 2529 : }
+ 2530 : #endif
+ 2531 :
+ 2532 : #endif
+ 2533 :
diff --git a/cov/cmdline/util.c.func-sort-c.html b/cov/cmdline/util.c.func-sort-c.html
index 2a205c44..1baa4e6c 100644
--- a/cov/cmdline/util.c.func-sort-c.html
+++ b/cov/cmdline/util.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -103,37 +103,37 @@
lock_unlock |
264 |
+
+ | crc32c_gen |
+ 265 |
+
| lock_lock |
273 |
| membesthash |
- 279 |
+ 280 |
| crc32c_init |
- 299 |
-
-
- | crc32c_gen |
- 313 |
+ 300 |
| muldiv |
- 1033 |
+ 1008 |
| fast_mtest_vector |
- 2026 |
+ 2019 |
| malloc_nofail_test |
- 2026 |
+ 2019 |
| mtest_vector |
- 2026 |
+ 2019 |
| malloc_nofail_vector_align |
@@ -141,47 +141,47 @@
| memdiff |
- 35593 |
+ 35908 |
| crc32c_x86 |
- 647248 |
+ 647112 |
| util_mum |
- 2100378 |
+ 2231474 |
| util_rotr64 |
- 3416264 |
+ 4202896 |
| memhash |
- 5919094 |
+ 5918991 |
| util_write64 |
- 7777674 |
+ 7777502 |
| util_write32 |
- 8121028 |
+ 8120960 |
| util_read32 |
- 8121160 |
+ 8121092 |
| util_read64 |
- 15388870 |
+ 16437322 |
| util_rotl64 |
- 510513033 |
+ 511275929 |
| util_rotl32 |
- 833601439 |
+ 833614949 |
diff --git a/cov/cmdline/util.c.func.html b/cov/cmdline/util.c.func.html
index e3488894..25f696bf 100644
--- a/cov/cmdline/util.c.func.html
+++ b/cov/cmdline/util.c.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,19 +61,19 @@
| crc32c_gen |
- 313 |
+ 265 |
| crc32c_init |
- 299 |
+ 300 |
| crc32c_x86 |
- 647248 |
+ 647112 |
| fast_mtest_vector |
- 2026 |
+ 2019 |
| hash_config_name |
@@ -97,7 +97,7 @@
| malloc_nofail_test |
- 2026 |
+ 2019 |
| malloc_nofail_vector_align |
@@ -109,15 +109,15 @@
| membesthash |
- 279 |
+ 280 |
| memdiff |
- 35593 |
+ 35908 |
| memhash |
- 5919094 |
+ 5918991 |
| memhashname |
@@ -125,11 +125,11 @@
| mtest_vector |
- 2026 |
+ 2019 |
| muldiv |
- 1033 |
+ 1008 |
| muldiv_upper |
@@ -137,7 +137,7 @@
| util_mum |
- 2100378 |
+ 2231474 |
| util_read16 |
@@ -145,11 +145,11 @@
| util_read32 |
- 8121160 |
+ 8121092 |
| util_read64 |
- 15388870 |
+ 16437322 |
| util_read8 |
@@ -157,11 +157,11 @@
| util_rotl32 |
- 833601439 |
+ 833614949 |
| util_rotl64 |
- 510513033 |
+ 511275929 |
| util_rotr32 |
@@ -169,7 +169,7 @@
| util_rotr64 |
- 3416264 |
+ 4202896 |
| util_selftest |
@@ -177,11 +177,11 @@
| util_write32 |
- 8121028 |
+ 8120960 |
| util_write64 |
- 7777674 |
+ 7777502 |
diff --git a/cov/cmdline/util.c.gcov.html b/cov/cmdline/util.c.gcov.html
index b934c9cd..798493ed 100644
--- a/cov/cmdline/util.c.gcov.html
+++ b/cov/cmdline/util.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -151,15 +151,15 @@
89 0 : return ptr;
90 : }
91 :
- 92 2026 : void* malloc_nofail_test(size_t size)
+ 92 2019 : void* malloc_nofail_test(size_t size)
93 : {
94 : void* ptr;
95 :
- 96 2026 : ptr = malloc_nofail(size);
+ 96 2019 : ptr = malloc_nofail(size);
97 :
- 98 2026 : mtest_vector(1, size, &ptr);
+ 98 2019 : mtest_vector(1, size, &ptr);
99 :
- 100 2026 : return ptr;
+ 100 2019 : 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 2026 : static int fast_mtest_vector(int n, size_t size, void** vv)
+ 109 2019 : 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 18234 : for (i = 0; i < 8; ++i) {
- 115 16208 : unsigned char value = 1 << i;
+ 114 18171 : for (i = 0; i < 8; ++i) {
+ 115 16152 : unsigned char value = 1 << i;
116 :
117 : /* fill first */
- 118 16208 : memset(vv[0], value, size);
+ 118 16152 : memset(vv[0], value, size);
119 :
120 : /* copy to the next */
- 121 16208 : for (j = 1; j < n; ++j)
+ 121 16152 : for (j = 1; j < n; ++j)
122 0 : memcpy(vv[j], vv[j - 1], size);
123 :
124 : /* compare with the previous */
- 125 32416 : for (j = 1; j <= n; ++j)
- 126 16208 : if (memcmp(vv[j % n], vv[j - 1], size) != 0)
+ 125 32304 : for (j = 1; j <= n; ++j)
+ 126 16152 : if (memcmp(vv[j % n], vv[j - 1], size) != 0)
127 0 : return -1;
128 : }
129 :
- 130 2026 : return 0;
+ 130 2019 : return 0;
131 : }
132 :
- 133 2026 : void mtest_vector(int n, size_t size, void** vv)
+ 133 2019 : void mtest_vector(int n, size_t size, void** vv)
134 : {
- 135 2026 : if (fast_mtest_vector(n, size, vv) != 0) {
+ 135 2019 : if (fast_mtest_vector(n, size, vv) != 0) {
136 : /* LCOV_EXCL_START */
137 : log_fatal(EINTERNAL, "DANGER! Your RAM memory is broken! DO NOT PROCEED UNTIL FIXED!\n");
138 : log_fatal(EINTERNAL, "Try running a memory test like http://www.memtest86.com/\n");
139 : exit(EXIT_FAILURE);
140 : /* LCOV_EXCL_STOP */
141 : }
- 142 2026 : }
+ 142 2019 : }
143 :
144 : /****************************************************************************/
145 : /* crc */
@@ -478,42 +478,42 @@
416 : int crc_x86;
417 : #endif
418 :
- 419 313 : uint32_t crc32c_gen(uint32_t crc, const unsigned char* ptr, unsigned size)
+ 419 265 : uint32_t crc32c_gen(uint32_t crc, const unsigned char* ptr, unsigned size)
420 : {
- 421 313 : crc ^= CRC_IV;
+ 421 265 : crc ^= CRC_IV;
422 :
- 423 313 : crc = crc32c_gen_plain(crc, ptr, size);
+ 423 265 : crc = crc32c_gen_plain(crc, ptr, size);
424 :
- 425 313 : crc ^= CRC_IV;
+ 425 265 : crc ^= CRC_IV;
426 :
- 427 313 : return crc;
+ 427 265 : return crc;
428 : }
429 :
430 : #if HAVE_SSE42
- 431 647248 : uint32_t crc32c_x86(uint32_t crc, const unsigned char* ptr, unsigned size)
+ 431 647112 : uint32_t crc32c_x86(uint32_t crc, const unsigned char* ptr, unsigned size)
432 : {
- 433 647248 : crc ^= CRC_IV;
+ 433 647112 : crc ^= CRC_IV;
434 :
- 435 647248 : crc = crc32c_x86_plain(crc, ptr, size);
+ 435 647112 : crc = crc32c_x86_plain(crc, ptr, size);
436 :
- 437 647248 : crc ^= CRC_IV;
+ 437 647112 : crc ^= CRC_IV;
438 :
- 439 647248 : return crc;
+ 439 647112 : return crc;
440 : }
441 : #endif
442 :
443 : uint32_t (*crc32c)(uint32_t crc, const unsigned char* ptr, unsigned size);
444 :
- 445 299 : void crc32c_init(void)
+ 445 300 : void crc32c_init(void)
446 : {
- 447 299 : crc32c = crc32c_gen;
+ 447 300 : crc32c = crc32c_gen;
448 : #if HAVE_SSE42
- 449 299 : if (raid_cpu_has_crc32()) {
- 450 297 : crc_x86 = 1;
- 451 297 : crc32c = crc32c_x86;
+ 449 300 : if (raid_cpu_has_crc32()) {
+ 450 298 : crc_x86 = 1;
+ 451 298 : crc32c = crc32c_x86;
452 : }
453 : #endif
- 454 299 : }
+ 454 300 : }
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 833601439 : static inline uint32_t util_rotl32(uint32_t x, int8_t r)
+ 463 833614949 : static inline uint32_t util_rotl32(uint32_t x, int8_t r)
464 : {
- 465 833601439 : return (x << r) | (x >> (32 - r));
+ 465 833614949 : return (x << r) | (x >> (32 - r));
466 : }
467 :
- 468 510513033 : static inline uint64_t util_rotl64(uint64_t x, int8_t r)
+ 468 511275929 : static inline uint64_t util_rotl64(uint64_t x, int8_t r)
469 : {
- 470 510513033 : return (x << r) | (x >> (64 - r));
+ 470 511275929 : return (x << r) | (x >> (64 - r));
471 : }
472 :
473 : /*
@@ -541,9 +541,9 @@
479 4 : return (x >> r) | (x << (32 - r));
480 : }
481 :
- 482 3416264 : static inline uint64_t util_rotr64(uint64_t x, int8_t r)
+ 482 4202896 : static inline uint64_t util_rotr64(uint64_t x, int8_t r)
483 : {
- 484 3416264 : return (x >> r) | (x << (64 - r));
+ 484 4202896 : return (x >> r) | (x << (64 - r));
485 : }
486 :
487 : /**
@@ -590,41 +590,41 @@
528 135 : return ptr[0] + (ptr[1] << 8);
529 : }
530 :
- 531 8121160 : static inline uint32_t util_read32(const void* ptr)
+ 531 8121092 : static inline uint32_t util_read32(const void* ptr)
532 : {
533 : uint32_t v;
- 534 8121160 : memcpy(&v, ptr, sizeof(v));
+ 534 8121092 : memcpy(&v, ptr, sizeof(v));
535 : #if WORDS_BIGENDIAN
536 : v = util_swap32(v);
537 : #endif
- 538 8121160 : return v;
+ 538 8121092 : return v;
539 : }
540 :
- 541 15388870 : static inline uint64_t util_read64(const void* ptr)
+ 541 16437322 : static inline uint64_t util_read64(const void* ptr)
542 : {
543 : uint64_t v;
- 544 15388870 : memcpy(&v, ptr, sizeof(v));
+ 544 16437322 : memcpy(&v, ptr, sizeof(v));
545 : #if WORDS_BIGENDIAN
546 : v = util_swap64(v);
547 : #endif
- 548 15388870 : return v;
+ 548 16437322 : return v;
549 : }
550 :
- 551 8121028 : static inline void util_write32(void* ptr, uint32_t v)
+ 551 8120960 : static inline void util_write32(void* ptr, uint32_t v)
552 : {
553 : #if WORDS_BIGENDIAN
554 : v = util_swap32(v);
555 : #endif
- 556 8121028 : memcpy(ptr, &v, sizeof(v));
- 557 8121028 : }
+ 556 8120960 : memcpy(ptr, &v, sizeof(v));
+ 557 8120960 : }
558 :
- 559 7777674 : static inline void util_write64(void* ptr, uint64_t v)
+ 559 7777502 : static inline void util_write64(void* ptr, uint64_t v)
560 : {
561 : #if WORDS_BIGENDIAN
562 : v = util_swap64(v);
563 : #endif
- 564 7777674 : memcpy(ptr, &v, sizeof(v));
- 565 7777674 : }
+ 564 7777502 : memcpy(ptr, &v, sizeof(v));
+ 565 7777502 : }
566 :
567 : /*
568 : * 64*64 -> 128bit multiply function.
@@ -638,22 +638,22 @@
576 : * Overwrites B contents with C's high 64 bits.
577 : */
578 : #if defined(__x86_64__) || defined(_M_X64)
- 579 2100378 : static inline void util_mum(uint64_t* A, uint64_t* B)
+ 579 2231474 : static inline void util_mum(uint64_t* A, uint64_t* B)
580 : {
- 581 2100378 : uint64_t a = *A;
- 582 2100378 : uint64_t b = *B;
+ 581 2231474 : uint64_t a = *A;
+ 582 2231474 : uint64_t b = *B;
583 : uint64_t low, high;
584 :
- 585 2100378 : __asm__ (
+ 585 2231474 : __asm__ (
586 : "mulq %3"
587 : : "=a" (low), "=d" (high)
588 : : "a" (a), "rm" (b)
589 : : "cc"
590 : );
591 :
- 592 2100378 : *A = low;
- 593 2100378 : *B = high;
- 594 2100378 : }
+ 592 2231474 : *A = low;
+ 593 2231474 : *B = high;
+ 594 2231474 : }
595 : #elif defined(__aarch64__) || defined(_M_ARM64)
596 : static inline void util_mum(uint64_t* A, uint64_t* B)
597 : {
@@ -775,13 +775,13 @@
713 0 : return 0;
714 : }
715 :
- 716 279 : unsigned membesthash(void)
+ 716 280 : unsigned membesthash(void)
717 : {
718 : #ifdef CONFIG_X86
719 : if (sizeof(void*) == 4 && !raid_cpu_has_slowmult())
720 : return HASH_MURMUR3;
721 : else
- 722 279 : return HASH_SPOOKY2;
+ 722 280 : return HASH_SPOOKY2;
723 : #else
724 : if (sizeof(void*) == 4)
725 : return HASH_MURMUR3;
@@ -795,21 +795,21 @@
733 : #include "metro.c"
734 : #include "museair.c"
735 :
- 736 5919094 : void memhash(unsigned kind, const unsigned char* seed, void* digest, const void* src, size_t size)
+ 736 5918991 : void memhash(unsigned kind, const unsigned char* seed, void* digest, const void* src, size_t size)
737 : {
- 738 5919094 : switch (kind) {
- 739 2030257 : case HASH_MURMUR3 :
- 740 2030257 : MurmurHash3_x86_128(src, size, seed, digest);
- 741 2030257 : break;
- 742 3888115 : case HASH_SPOOKY2 :
- 743 3888115 : SpookyHash128(src, size, seed, digest);
- 744 3888115 : break;
- 745 369 : case HASH_METRO :
- 746 369 : MetroHash128(src, size, seed, digest);
- 747 369 : break;
- 748 353 : case HASH_MUSEAIR :
- 749 353 : MuseAirLoong(src, size, seed, digest);
- 750 353 : break;
+ 738 5918991 : switch (kind) {
+ 739 2030240 : case HASH_MURMUR3 :
+ 740 2030240 : MurmurHash3_x86_128(src, size, seed, digest);
+ 741 2030240 : break;
+ 742 3887997 : case HASH_SPOOKY2 :
+ 743 3887997 : SpookyHash128(src, size, seed, digest);
+ 744 3887997 : break;
+ 745 393 : case HASH_METRO :
+ 746 393 : MetroHash128(src, size, seed, digest);
+ 747 393 : break;
+ 748 361 : case HASH_MUSEAIR :
+ 749 361 : MuseAirLoong(src, size, seed, digest);
+ 750 361 : break;
751 0 : default :
752 : /* LCOV_EXCL_START */
753 : log_fatal(EINTERNAL, "Internal inconsistency in hash function %u\n", kind);
@@ -817,7 +817,7 @@
755 : break;
756 : /* LCOV_EXCL_STOP */
757 : }
- 758 5919094 : }
+ 758 5918991 : }
759 :
760 45 : const char* hash_config_name(unsigned kind)
761 : {
@@ -833,23 +833,23 @@
771 : }
772 : }
773 :
- 774 35593 : unsigned memdiff(const unsigned char* data1, const unsigned char* data2, size_t size)
+ 774 35908 : unsigned memdiff(const unsigned char* data1, const unsigned char* data2, size_t size)
775 : {
776 : size_t i;
777 : unsigned count;
778 :
- 779 35593 : count = 0;
- 780 22025081 : for (i = 0; i < size; ++i) {
+ 779 35908 : count = 0;
+ 780 22020356 : for (i = 0; i < size; ++i) {
781 : unsigned j;
- 782 21989488 : unsigned char diff = data1[i] ^ data2[i];
- 783 197905392 : for (j = 0; j < 8; ++j) {
- 784 175915904 : if ((diff & 1) != 0)
- 785 76890098 : ++count;
- 786 175915904 : diff >>= 1;
+ 782 21984448 : unsigned char diff = data1[i] ^ data2[i];
+ 783 197860032 : for (j = 0; j < 8; ++j) {
+ 784 175875584 : if ((diff & 1) != 0)
+ 785 76878222 : ++count;
+ 786 175875584 : diff >>= 1;
787 : }
788 : }
789 :
- 790 35593 : return count;
+ 790 35908 : return count;
791 : }
792 :
793 : /****************************************************************************/
@@ -900,12 +900,12 @@
838 : /****************************************************************************/
839 : /* muldiv */
840 :
- 841 1033 : unsigned muldiv(uint64_t v, uint64_t mul, uint64_t div)
+ 841 1008 : unsigned muldiv(uint64_t v, uint64_t mul, uint64_t div)
842 : {
- 843 1033 : if (!div)
+ 843 1008 : if (!div)
844 49 : return 0;
845 :
- 846 984 : return (uint32_t)(v * mul / div);
+ 846 959 : return (uint32_t)(v * mul / div);
847 : }
848 :
849 7 : unsigned muldiv_upper(uint64_t v, uint64_t mul, uint64_t div)
diff --git a/cov/cmdline/util.h.func-sort-c.html b/cov/cmdline/util.h.func-sort-c.html
index 06e403b2..25ad8387 100644
--- a/cov/cmdline/util.h.func-sort-c.html
+++ b/cov/cmdline/util.h.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -65,11 +65,11 @@
| crc32c_gen_plain |
- 313 |
+ 265 |
| bit_vect_set |
- 1053109 |
+ 1053046 |
| bit_vect_test |
@@ -77,15 +77,15 @@
| crc32c_plain_char |
- 3968961 |
+ 3933071 |
| crc32c_plain |
- 21644594 |
+ 21434636 |
| crc32c_x86_plain |
- 22291842 |
+ 22081748 |
diff --git a/cov/cmdline/util.h.func.html b/cov/cmdline/util.h.func.html
index 00be9f96..8b118f23 100644
--- a/cov/cmdline/util.h.func.html
+++ b/cov/cmdline/util.h.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,7 +61,7 @@
| bit_vect_set |
- 1053109 |
+ 1053046 |
| bit_vect_size |
@@ -73,19 +73,19 @@
| crc32c_gen_plain |
- 313 |
+ 265 |
| crc32c_plain |
- 21644594 |
+ 21434636 |
| crc32c_plain_char |
- 3968961 |
+ 3933071 |
| crc32c_x86_plain |
- 22291842 |
+ 22081748 |
diff --git a/cov/cmdline/util.h.gcov.html b/cov/cmdline/util.h.gcov.html
index a9eac264..fa314463 100644
--- a/cov/cmdline/util.h.gcov.html
+++ b/cov/cmdline/util.h.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -145,12 +145,12 @@
83 : /**
84 : * Compute CRC-32 (Castagnoli) for a single byte without the IV.
85 : */
- 86 3968961 : static inline uint32_t crc32c_plain_char(uint32_t crc, unsigned char c)
+ 86 3933071 : static inline uint32_t crc32c_plain_char(uint32_t crc, unsigned char c)
87 : {
88 : #if HAVE_SSE42
- 89 3968961 : if (tommy_likely(crc_x86)) {
- 90 3968961 : asm ("crc32b %1, %0\n" : "+r" (crc) : "m" (c));
- 91 3968961 : return crc;
+ 89 3933071 : if (tommy_likely(crc_x86)) {
+ 90 3933071 : asm ("crc32b %1, %0\n" : "+r" (crc) : "m" (c));
+ 91 3933071 : return crc;
92 : }
93 : #endif
94 0 : return CRC32C_0[(crc ^ c) & 0xff] ^ (crc >> 8);
@@ -159,38 +159,38 @@
97 : /**
98 : * Compute the CRC-32 (Castagnoli) without the IV.
99 : */
- 100 313 : static inline uint32_t crc32c_gen_plain(uint32_t crc, const unsigned char* ptr, unsigned size)
+ 100 265 : static inline uint32_t crc32c_gen_plain(uint32_t crc, const unsigned char* ptr, unsigned size)
101 : {
- 102 19399136 : while (size >= 4) {
- 103 19398823 : crc ^= ptr[0] | (uint32_t)ptr[1] << 8 | (uint32_t)ptr[2] << 16 | (uint32_t)ptr[3] << 24;
- 104 19398823 : crc = CRC32C_3[crc & 0xff] ^ CRC32C_2[(crc >> 8) & 0xff] ^ CRC32C_1[(crc >> 16) & 0xff] ^ CRC32C_0[crc >> 24];
- 105 19398823 : ptr += 4;
- 106 19398823 : size -= 4;
+ 102 16253360 : while (size >= 4) {
+ 103 16253095 : crc ^= ptr[0] | (uint32_t)ptr[1] << 8 | (uint32_t)ptr[2] << 16 | (uint32_t)ptr[3] << 24;
+ 104 16253095 : crc = CRC32C_3[crc & 0xff] ^ CRC32C_2[(crc >> 8) & 0xff] ^ CRC32C_1[(crc >> 16) & 0xff] ^ CRC32C_0[crc >> 24];
+ 105 16253095 : ptr += 4;
+ 106 16253095 : size -= 4;
107 : }
108 :
- 109 322 : while (size) {
+ 109 274 : while (size) {
110 9 : crc = CRC32C_0[(crc ^ *ptr) & 0xff] ^ (crc >> 8);
111 9 : ++ptr;
112 9 : --size;
113 : }
114 :
- 115 313 : return crc;
+ 115 265 : return crc;
116 : }
117 :
118 : /**
119 : * Compute the CRC-32 (Castagnoli) without the IV.
120 : */
121 : #if HAVE_SSE42
- 122 22291842 : static inline uint32_t crc32c_x86_plain(uint32_t crc, const unsigned char* ptr, unsigned size)
+ 122 22081748 : static inline uint32_t crc32c_x86_plain(uint32_t crc, const unsigned char* ptr, unsigned size)
123 : {
124 : #ifdef CONFIG_X86_64
- 125 22291842 : uint64_t crc64 = crc;
- 126 219134388 : while (size >= 8) {
- 127 196842546 : asm ("crc32q %1, %0\n" : "+r" (crc64) : "m" (*(const uint64_t*)ptr));
- 128 196842546 : ptr += 8;
- 129 196842546 : size -= 8;
+ 125 22081748 : uint64_t crc64 = crc;
+ 126 219202533 : while (size >= 8) {
+ 127 197120785 : asm ("crc32q %1, %0\n" : "+r" (crc64) : "m" (*(const uint64_t*)ptr));
+ 128 197120785 : ptr += 8;
+ 129 197120785 : size -= 8;
130 : }
- 131 22291842 : crc = crc64;
+ 131 22081748 : crc = crc64;
132 : #else
133 : while (size >= 4) {
134 : asm ("crc32l %1, %0\n" : "+r" (crc) : "m" (*(const uint32_t*)ptr));
@@ -198,24 +198,24 @@
136 : size -= 4;
137 : }
138 : #endif
- 139 69745235 : while (size) {
- 140 47453393 : asm ("crc32b %1, %0\n" : "+r" (crc) : "m" (*ptr));
- 141 47453393 : ++ptr;
- 142 47453393 : --size;
+ 139 69279721 : while (size) {
+ 140 47197973 : asm ("crc32b %1, %0\n" : "+r" (crc) : "m" (*ptr));
+ 141 47197973 : ++ptr;
+ 142 47197973 : --size;
143 : }
144 :
- 145 22291842 : return crc;
+ 145 22081748 : return crc;
146 : }
147 : #endif
148 :
149 : /**
150 : * Compute CRC-32 (Castagnoli) without the IV.
151 : */
- 152 21644594 : static inline uint32_t crc32c_plain(uint32_t crc, const unsigned char* ptr, unsigned size)
+ 152 21434636 : static inline uint32_t crc32c_plain(uint32_t crc, const unsigned char* ptr, unsigned size)
153 : {
154 : #if HAVE_SSE42
- 155 21644594 : if (tommy_likely(crc_x86)) {
- 156 21644594 : return crc32c_x86_plain(crc, ptr, size);
+ 155 21434636 : if (tommy_likely(crc_x86)) {
+ 156 21434636 : return crc32c_x86_plain(crc, ptr, size);
157 : }
158 : #endif
159 0 : return crc32c_gen_plain(crc, ptr, size);
@@ -311,11 +311,11 @@
249 217 : return (max + BIT_VECT_SIZE - 1) / BIT_VECT_SIZE;
250 : }
251 :
- 252 1053109 : static inline void bit_vect_set(bit_vect_t* bit_vect, size_t off)
+ 252 1053046 : static inline void bit_vect_set(bit_vect_t* bit_vect, size_t off)
253 : {
- 254 1053109 : bit_vect_t mask = 1 << (off % BIT_VECT_SIZE);
- 255 1053109 : bit_vect[off / BIT_VECT_SIZE] |= mask;
- 256 1053109 : }
+ 254 1053046 : bit_vect_t mask = 1 << (off % BIT_VECT_SIZE);
+ 255 1053046 : bit_vect[off / BIT_VECT_SIZE] |= mask;
+ 256 1053046 : }
257 :
258 : static inline void bit_vect_clear(bit_vect_t* bit_vect, size_t off)
259 : {
diff --git a/cov/index-sort-f.html b/cov/index-sort-f.html
index aa67e618..04e7fb6a 100644
--- a/cov/index-sort-f.html
+++ b/cov/index-sort-f.html
@@ -31,18 +31,18 @@
|
-
-
-
+
+
+
-
+
|
-
+
-
+
 |
@@ -72,12 +72,12 @@
| cmdline |
-
+
|
- 86.4 % |
- 10504 / 12155 |
- 94.2 % |
- 565 / 600 |
+ 89.0 % |
+ 10781 / 12115 |
+ 95.5 % |
+ 573 / 600 |
| tommyds |
diff --git a/cov/index-sort-l.html b/cov/index-sort-l.html
index 0ca941b4..4c3db9f7 100644
--- a/cov/index-sort-l.html
+++ b/cov/index-sort-l.html
@@ -31,18 +31,18 @@
|
-
-
-
+
+
+
-
+
|
-
+
-
+
 |
@@ -72,12 +72,12 @@
| cmdline |
-
+
|
- 86.4 % |
- 10504 / 12155 |
- 94.2 % |
- 565 / 600 |
+ 89.0 % |
+ 10781 / 12115 |
+ 95.5 % |
+ 573 / 600 |
| raid |
diff --git a/cov/index.html b/cov/index.html
index a02b5ed1..dc3a46c9 100644
--- a/cov/index.html
+++ b/cov/index.html
@@ -31,18 +31,18 @@
|
-
-
-
+
+
+
-
+
|
-
+
-
+
 |
@@ -72,12 +72,12 @@
| cmdline |
-
+
|
- 86.4 % |
- 10504 / 12155 |
- 94.2 % |
- 565 / 600 |
+ 89.0 % |
+ 10781 / 12115 |
+ 95.5 % |
+ 573 / 600 |
| raid |
diff --git a/cov/raid/check.c.func-sort-c.html b/cov/raid/check.c.func-sort-c.html
index 6ac4218b..9e28f8c8 100644
--- a/cov/raid/check.c.func-sort-c.html
+++ b/cov/raid/check.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/raid/check.c.func.html b/cov/raid/check.c.func.html
index 9e08ecd4..23ea62b0 100644
--- a/cov/raid/check.c.func.html
+++ b/cov/raid/check.c.func.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/raid/check.c.gcov.html b/cov/raid/check.c.gcov.html
index f6a8c6ed..994c0588 100644
--- a/cov/raid/check.c.gcov.html
+++ b/cov/raid/check.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/raid/combo.h.func-sort-c.html b/cov/raid/combo.h.func-sort-c.html
index 7130295c..4ada51a6 100644
--- a/cov/raid/combo.h.func-sort-c.html
+++ b/cov/raid/combo.h.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/raid/combo.h.func.html b/cov/raid/combo.h.func.html
index 251d4d09..55c30efe 100644
--- a/cov/raid/combo.h.func.html
+++ b/cov/raid/combo.h.func.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/raid/combo.h.gcov.html b/cov/raid/combo.h.gcov.html
index c47a489e..1236a46a 100644
--- a/cov/raid/combo.h.gcov.html
+++ b/cov/raid/combo.h.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -170,11 +170,11 @@
108 : int i;
109 :
110 : (void)n; /* unused, but kept for clarity */
- 111 207791 : assert(0 < r && r <= n);
+ 111 207971 : assert(0 < r && r <= n);
112 :
- 113 689014 : for (i = 0; i < r; ++i)
- 114 481223 : c[i] = i;
- 115 207791 : }
+ 113 689369 : for (i = 0; i < r; ++i)
+ 114 481398 : c[i] = i;
+ 115 207971 : }
116 :
117 : /**
118 : * Get the next combination without repetition of r of n elements.
@@ -182,19 +182,19 @@
120 : */
121 : static __always_inline int combination_next(int r, int n, int *c)
122 : {
- 123 52198 : int i = r - 1; /* present position */
- 124 52198 : int h = n; /* high limit for this position */
+ 123 52228 : int i = r - 1; /* present position */
+ 124 52228 : int h = n; /* high limit for this position */
125 :
- 126 85071 : recurse:
+ 126 85101 : recurse:
127 : /* next element at position i */
- 128 85071 : ++c[i];
+ 128 85101 : ++c[i];
129 :
130 : /* if the position has reached the max */
- 131 85071 : if (c[i] >= h) {
+ 131 85101 : if (c[i] >= h) {
132 :
133 : /* if we are at the first level, we have finished */
- 134 45033 : if (i == 0)
- 135 12160 : return 0;
+ 134 45043 : if (i == 0)
+ 135 12170 : return 0;
136 :
137 : /* increase the previous position */
138 32873 : --i;
@@ -202,16 +202,16 @@
140 32873 : goto recurse;
141 : }
142 :
- 143 40038 : ++i;
+ 143 40058 : ++i;
144 :
145 : /* initialize all the next positions, if any */
- 146 62583 : while (i < r) {
+ 146 62603 : 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 40038 : return 1;
+ 152 40058 : 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 03c4d59e..62628524 100644
--- a/cov/raid/cpu.h.func-sort-c.html
+++ b/cov/raid/cpu.h.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -69,43 +69,43 @@
| raid_cpu_has_crc32 |
- 307 |
+ 308 |
| raid_cpu_has_sse2 |
- 319 |
+ 320 |
| raid_cpu_has_avx2 |
- 354 |
+ 355 |
| raid_cpu_match_avx |
- 354 |
+ 355 |
| raid_cpu_has_slowextendedreg |
- 569 |
+ 571 |
| raid_cpu_is_atom |
- 573 |
+ 575 |
| raid_cpu_info |
- 577 |
+ 579 |
| raid_cpu_has_ssse3 |
- 615 |
+ 617 |
| raid_cpu_match_sse |
- 1241 |
+ 1245 |
| raid_cpuid |
- 2780 |
+ 2789 |
diff --git a/cov/raid/cpu.h.func.html b/cov/raid/cpu.h.func.html
index 65099a9e..2a752f07 100644
--- a/cov/raid/cpu.h.func.html
+++ b/cov/raid/cpu.h.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,15 +61,15 @@
| raid_cpu_has_avx2 |
- 354 |
+ 355 |
| raid_cpu_has_crc32 |
- 307 |
+ 308 |
| raid_cpu_has_slowextendedreg |
- 569 |
+ 571 |
| raid_cpu_has_slowmult |
@@ -77,31 +77,31 @@
| raid_cpu_has_sse2 |
- 319 |
+ 320 |
| raid_cpu_has_ssse3 |
- 615 |
+ 617 |
| raid_cpu_info |
- 577 |
+ 579 |
| raid_cpu_is_atom |
- 573 |
+ 575 |
| raid_cpu_match_avx |
- 354 |
+ 355 |
| raid_cpu_match_sse |
- 1241 |
+ 1245 |
| raid_cpuid |
- 2780 |
+ 2789 |
| raid_xgetbv |
diff --git a/cov/raid/cpu.h.gcov.html b/cov/raid/cpu.h.gcov.html
index 5c0d6939..265789c7 100644
--- a/cov/raid/cpu.h.gcov.html
+++ b/cov/raid/cpu.h.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -79,9 +79,9 @@
17 :
18 : #ifdef CONFIG_X86
19 :
- 20 2780 : static inline void raid_cpuid(uint32_t func_eax, uint32_t sub_ecx, uint32_t *reg)
+ 20 2789 : static inline void raid_cpuid(uint32_t func_eax, uint32_t sub_ecx, uint32_t *reg)
21 : {
- 22 2780 : asm volatile (
+ 22 2789 : 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 2780 : : "=a" (reg[0]), "=b" (reg[1]), "=c" (reg[2]), "=d" (reg[3])
+ 32 2789 : : "=a" (reg[0]), "=b" (reg[1]), "=c" (reg[2]), "=d" (reg[3])
33 : : "0" (func_eax), "2" (sub_ecx)
34 : #endif
35 : );
- 36 2780 : }
+ 36 2789 : }
37 :
38 31 : static inline void raid_xgetbv(uint32_t* reg)
39 : {
@@ -112,26 +112,26 @@
50 :
51 : #define CPU_VENDOR_MAX 13
52 :
- 53 577 : static inline void raid_cpu_info(char *vendor, unsigned *family, unsigned *model)
+ 53 579 : 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 577 : raid_cpuid(0, 0, reg);
+ 58 579 : raid_cpuid(0, 0, reg);
59 :
- 60 577 : ((uint32_t*)vendor)[0] = reg[1];
- 61 577 : ((uint32_t*)vendor)[1] = reg[3];
- 62 577 : ((uint32_t*)vendor)[2] = reg[2];
- 63 577 : vendor[12] = 0;
+ 60 579 : ((uint32_t*)vendor)[0] = reg[1];
+ 61 579 : ((uint32_t*)vendor)[1] = reg[3];
+ 62 579 : ((uint32_t*)vendor)[2] = reg[2];
+ 63 579 : vendor[12] = 0;
64 :
- 65 577 : raid_cpuid(1, 0, reg);
+ 65 579 : raid_cpuid(1, 0, reg);
66 :
- 67 577 : f = (reg[0] >> 8) & 0xF;
- 68 577 : ef = (reg[0] >> 20) & 0xFF;
- 69 577 : m = (reg[0] >> 4) & 0xF;
- 70 577 : em = (reg[0] >> 16) & 0xF;
+ 67 579 : f = (reg[0] >> 8) & 0xF;
+ 68 579 : ef = (reg[0] >> 20) & 0xFF;
+ 69 579 : m = (reg[0] >> 4) & 0xF;
+ 70 579 : em = (reg[0] >> 16) & 0xF;
71 :
- 72 577 : if (strcmp(vendor, "AuthenticAMD") == 0) {
+ 72 579 : 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 577 : *family = f + ef;
- 82 577 : *model = m + (em << 4);
+ 81 579 : *family = f + ef;
+ 82 579 : *model = m + (em << 4);
83 : }
- 84 577 : }
+ 84 579 : }
85 :
- 86 1241 : static inline int raid_cpu_match_sse(uint32_t cpuid_1_ecx, uint32_t cpuid_1_edx)
+ 86 1245 : 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 1241 : raid_cpuid(1, 0, reg);
- 91 1241 : if ((reg[2] & cpuid_1_ecx) != cpuid_1_ecx)
+ 90 1245 : raid_cpuid(1, 0, reg);
+ 91 1245 : if ((reg[2] & cpuid_1_ecx) != cpuid_1_ecx)
92 18 : return 0;
- 93 1223 : if ((reg[3] & cpuid_1_edx) != cpuid_1_edx)
+ 93 1227 : if ((reg[3] & cpuid_1_edx) != cpuid_1_edx)
94 0 : return 0;
95 :
- 96 1223 : return 1;
+ 96 1227 : return 1;
97 : }
98 :
- 99 354 : static inline int raid_cpu_match_avx(uint32_t cpuid_1_ecx, uint32_t cpuid_7_ebx, uint32_t xcr0)
+ 99 355 : 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 354 : raid_cpuid(1, 0, reg);
- 104 354 : if ((reg[2] & cpuid_1_ecx) != cpuid_1_ecx)
- 105 323 : return 0;
+ 103 355 : raid_cpuid(1, 0, reg);
+ 104 355 : if ((reg[2] & cpuid_1_ecx) != cpuid_1_ecx)
+ 105 324 : return 0;
106 :
107 31 : raid_xgetbv(reg);
108 31 : if ((reg[0] & xcr0) != xcr0)
@@ -177,7 +177,7 @@
115 31 : return 1;
116 : }
117 :
- 118 319 : static inline int raid_cpu_has_sse2(void)
+ 118 320 : 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 319 : return raid_cpu_match_sse(
+ 132 320 : return raid_cpu_match_sse(
133 : 0,
134 : 1 << 26); /* SSE2 */
135 : }
136 :
- 137 615 : static inline int raid_cpu_has_ssse3(void)
+ 137 617 : 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 615 : return raid_cpu_match_sse(
+ 149 617 : return raid_cpu_match_sse(
150 : 1 << 9, /* SSSE3 */
151 : 1 << 26); /* SSE2 */
152 : }
153 :
- 154 307 : static inline int raid_cpu_has_crc32(void)
+ 154 308 : 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 307 : return raid_cpu_match_sse(
+ 165 308 : return raid_cpu_match_sse(
166 : 1 << 20, /* CRC32 */
167 : 0);
168 : }
169 :
- 170 354 : static inline int raid_cpu_has_avx2(void)
+ 170 355 : 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 354 : return raid_cpu_match_avx(
+ 187 355 : 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 573 : static inline int raid_cpu_is_atom(unsigned family, unsigned model)
+ 218 575 : static inline int raid_cpu_is_atom(unsigned family, unsigned model)
219 : {
- 220 573 : if (family != 6)
+ 220 575 : if (family != 6)
221 3 : return 0;
222 :
223 : /*
@@ -300,10 +300,10 @@
238 : * 4D (77) Atom 8C (22 nm) 4 MB L2 (AVN)
239 : * ?? Atom ?C (14 nm) ? MB L2 (DVN)
240 : */
- 241 570 : return model == 28 || model == 38 || model == 54
- 242 570 : || model == 39 || model == 53 || model == 74
- 243 570 : || model == 90 || model == 55 || model == 76
- 244 1140 : || model == 93 || model == 77;
+ 241 572 : return model == 28 || model == 38 || model == 54
+ 242 572 : || model == 39 || model == 53 || model == 74
+ 243 572 : || model == 90 || model == 55 || model == 76
+ 244 1144 : || model == 93 || model == 77;
245 : }
246 :
247 : /**
@@ -341,7 +341,7 @@
279 : * Check if the processor has a slow extended set of SSE registers.
280 : * If yes, it's better to limit the unroll to the firsrt 8 registers.
281 : */
- 282 569 : static inline int raid_cpu_has_slowextendedreg(void)
+ 282 571 : static inline int raid_cpu_has_slowextendedreg(void)
283 : {
284 : char vendor[CPU_VENDOR_MAX];
285 : unsigned family;
@@ -352,9 +352,9 @@
290 : * is a LITTLE slower than the one using only the first 8 registers.
291 : * This doesn't happen for PARZ.
292 : */
- 293 569 : raid_cpu_info(vendor, &family, &model);
+ 293 571 : raid_cpu_info(vendor, &family, &model);
294 :
- 295 569 : if (strcmp(vendor, "AuthenticAMD") == 0) {
+ 295 571 : if (strcmp(vendor, "AuthenticAMD") == 0) {
296 : /*
297 : * AMD Bulldozer
298 : * par2_sse2:4922 MB/s, par2_sse2e:4465 MB/s
@@ -363,7 +363,7 @@
301 0 : return 1;
302 : }
303 :
- 304 569 : if (strcmp(vendor, "GenuineIntel") == 0) {
+ 304 571 : if (strcmp(vendor, "GenuineIntel") == 0) {
305 : /*
306 : * Intel Atom (Model 77)
307 : * par2_sse2:5686 MB/s, par2_sse2e:5250 MB/s
@@ -381,11 +381,11 @@
319 : * par5_sse3:910 MB/s, par5_sse3e:675 MB/s
320 : * par6_sse3:720 MB/s, par6_sse3e:534 MB/s
321 : */
- 322 569 : if (raid_cpu_is_atom(family, model))
+ 322 571 : if (raid_cpu_is_atom(family, model))
323 0 : return 1;
324 : }
325 :
- 326 569 : return 0;
+ 326 571 : return 0;
327 : }
328 : #endif
329 :
diff --git a/cov/raid/gf.h.func-sort-c.html b/cov/raid/gf.h.func-sort-c.html
index 3b6821fc..c8f04224 100644
--- a/cov/raid/gf.h.func-sort-c.html
+++ b/cov/raid/gf.h.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/raid/gf.h.func.html b/cov/raid/gf.h.func.html
index fc183f91..2368980f 100644
--- a/cov/raid/gf.h.func.html
+++ b/cov/raid/gf.h.func.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/raid/gf.h.gcov.html b/cov/raid/gf.h.gcov.html
index eeb487db..670aa201 100644
--- a/cov/raid/gf.h.gcov.html
+++ b/cov/raid/gf.h.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -88,7 +88,7 @@
26 : */
27 : static __always_inline uint8_t mul(uint8_t a, uint8_t b)
28 : {
- 29 23792794 : return gfmul[a][b];
+ 29 23792730 : return gfmul[a][b];
30 : }
31 :
32 : /*
@@ -97,9 +97,9 @@
35 : */
36 : static __always_inline uint8_t inv(uint8_t v)
37 : {
- 38 635486 : BUG_ON(v == 0); /* division by zero */
+ 38 635498 : BUG_ON(v == 0); /* division by zero */
39 :
- 40 635486 : return gfinv[v];
+ 40 635498 : return gfinv[v];
41 : }
42 :
43 : /*
@@ -125,7 +125,7 @@
63 : */
64 : static __always_inline uint8_t A(int p, int d)
65 : {
- 66 2604612 : return gfgen[p][d];
+ 66 2604616 : 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 30283584 : uint32_t mask = v & 0x80808080U;
+ 89 31201088 : uint32_t mask = v & 0x80808080U;
90 :
- 91 30283584 : mask = (mask << 1) - (mask >> 7);
- 92 30283584 : v = (v << 1) & 0xfefefefeU;
- 93 30283584 : v ^= mask & 0x1d1d1d1dU;
- 94 30283584 : return v;
+ 91 31201088 : mask = (mask << 1) - (mask >> 7);
+ 92 31201088 : v = (v << 1) & 0xfefefefeU;
+ 93 31201088 : v ^= mask & 0x1d1d1d1dU;
+ 94 31201088 : return v;
95 : }
96 :
97 : /*
@@ -161,12 +161,12 @@
99 : */
100 : static __always_inline uint64_t x2_64(uint64_t v)
101 : {
- 102 30051232 : uint64_t mask = v & 0x8080808080808080ULL;
+ 102 29592480 : uint64_t mask = v & 0x8080808080808080ULL;
103 :
- 104 30051232 : mask = (mask << 1) - (mask >> 7);
- 105 30051232 : v = (v << 1) & 0xfefefefefefefefeULL;
- 106 30051232 : v ^= mask & 0x1d1d1d1d1d1d1d1dULL;
- 107 30051232 : return v;
+ 104 29592480 : mask = (mask << 1) - (mask >> 7);
+ 105 29592480 : v = (v << 1) & 0xfefefefefefefefeULL;
+ 106 29592480 : v ^= mask & 0x1d1d1d1d1d1d1d1dULL;
+ 107 29592480 : return v;
108 : }
109 :
110 : /*
@@ -187,12 +187,12 @@
125 : */
126 : static __always_inline uint64_t d2_64(uint64_t v)
127 : {
- 128 11240416 : uint64_t mask = v & 0x0101010101010101ULL;
+ 128 11699168 : uint64_t mask = v & 0x0101010101010101ULL;
129 :
- 130 11240416 : mask = (mask << 8) - mask;
- 131 11240416 : v = (v >> 1) & 0x7f7f7f7f7f7f7f7fULL;
- 132 11240416 : v ^= mask & 0x8e8e8e8e8e8e8e8eULL;
- 133 11240416 : return v;
+ 130 11699168 : mask = (mask << 8) - mask;
+ 131 11699168 : v = (v >> 1) & 0x7f7f7f7f7f7f7f7fULL;
+ 132 11699168 : v ^= mask & 0x8e8e8e8e8e8e8e8eULL;
+ 133 11699168 : return v;
134 : }
135 :
136 : #endif
diff --git a/cov/raid/helper.c.func-sort-c.html b/cov/raid/helper.c.func-sort-c.html
index e4c44c02..cb0e67f7 100644
--- a/cov/raid/helper.c.func-sort-c.html
+++ b/cov/raid/helper.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/raid/helper.c.func.html b/cov/raid/helper.c.func.html
index 52f96f2d..54647c3b 100644
--- a/cov/raid/helper.c.func.html
+++ b/cov/raid/helper.c.func.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/raid/helper.c.gcov.html b/cov/raid/helper.c.gcov.html
index 03e43de7..abf06a27 100644
--- a/cov/raid/helper.c.gcov.html
+++ b/cov/raid/helper.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/raid/index-sort-f.html b/cov/raid/index-sort-f.html
index f4c95883..f367d0dc 100644
--- a/cov/raid/index-sort-f.html
+++ b/cov/raid/index-sort-f.html
@@ -37,7 +37,7 @@
-
+
|
@@ -69,6 +69,16 @@
Line Coverage  |
Functions  |
+
+ | combo.h |
+
+
+ |
+ 100.0 % |
+ 36 / 36 |
+ - |
+ 0 / 0 |
+
| gf.h |
@@ -90,14 +100,14 @@
| 0 / 0 |
- | combo.h |
+ intz.c |
|
100.0 % |
- 36 / 36 |
- - |
- 0 / 0 |
+ 58 / 58 |
+ 100.0 % |
+ 2 / 2 |
| helper.c |
@@ -110,14 +120,14 @@
2 / 2 |
- | intz.c |
+ check.c |
|
100.0 % |
- 58 / 58 |
+ 60 / 60 |
100.0 % |
- 2 / 2 |
+ 3 / 3 |
| x86z.c |
@@ -129,16 +139,6 @@
100.0 % |
3 / 3 |
-
- | check.c |
-
-
- |
- 100.0 % |
- 60 / 60 |
- 100.0 % |
- 3 / 3 |
-
| memory.c |
@@ -149,16 +149,6 @@
| 100.0 % |
6 / 6 |
-
- | test.c |
-
-
- |
- 98.7 % |
- 153 / 155 |
- 100.0 % |
- 7 / 7 |
-
| module.c |
@@ -169,6 +159,16 @@
| 100.0 % |
7 / 7 |
+
+ | test.c |
+
+
+ |
+ 98.7 % |
+ 153 / 155 |
+ 100.0 % |
+ 7 / 7 |
+
| raid.c |
diff --git a/cov/raid/index-sort-l.html b/cov/raid/index-sort-l.html
index d320617e..1224a797 100644
--- a/cov/raid/index-sort-l.html
+++ b/cov/raid/index-sort-l.html
@@ -37,7 +37,7 @@
|
-
+
|
diff --git a/cov/raid/index.html b/cov/raid/index.html
index a50e3d9a..a948ee2f 100644
--- a/cov/raid/index.html
+++ b/cov/raid/index.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/raid/int.c.func-sort-c.html b/cov/raid/int.c.func-sort-c.html
index 29f3480e..ce835fac 100644
--- a/cov/raid/int.c.func-sort-c.html
+++ b/cov/raid/int.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -59,6 +59,10 @@
Function Name  |
Hit count  |
+
+ | raid_gen6_int8 |
+ 17 |
+
| raid_gen4_int8 |
18 |
@@ -67,25 +71,21 @@
raid_gen5_int8 |
18 |
-
- | raid_gen6_int8 |
- 18 |
-
| raid_gen3_int8 |
- 28 |
+ 27 |
| raid_gen2_int32 |
- 43 |
-
-
- | raid_gen2_int64 |
- 85 |
+ 45 |
| raid_gen1_int32 |
- 87 |
+ 81 |
+
+
+ | raid_gen2_int64 |
+ 81 |
| raid_rec1_int8 |
@@ -93,7 +93,7 @@
| raid_gen1_int64 |
- 170 |
+ 159 |
| raid_rec2_int8 |
diff --git a/cov/raid/int.c.func.html b/cov/raid/int.c.func.html
index a9dce16b..6814e454 100644
--- a/cov/raid/int.c.func.html
+++ b/cov/raid/int.c.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,23 +61,23 @@
| raid_gen1_int32 |
- 87 |
+ 81 |
| raid_gen1_int64 |
- 170 |
+ 159 |
| raid_gen2_int32 |
- 43 |
+ 45 |
| raid_gen2_int64 |
- 85 |
+ 81 |
| raid_gen3_int8 |
- 28 |
+ 27 |
| raid_gen4_int8 |
@@ -89,7 +89,7 @@
| raid_gen6_int8 |
- 18 |
+ 17 |
| raid_rec1_int8 |
diff --git a/cov/raid/int.c.gcov.html b/cov/raid/int.c.gcov.html
index 20a57576..d875b13f 100644
--- a/cov/raid/int.c.gcov.html
+++ b/cov/raid/int.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -80,9 +80,9 @@
18 : /*
19 : * GEN1 (RAID5 with xor) 32bit C implementation
20 : */
- 21 87 : void raid_gen1_int32(int nd, size_t size, void **vv)
+ 21 81 : void raid_gen1_int32(int nd, size_t size, void **vv)
22 : {
- 23 87 : uint8_t **v = (uint8_t **)vv;
+ 23 81 : 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 87 : l = nd - 1;
- 32 87 : p = v[nd];
+ 31 81 : l = nd - 1;
+ 32 81 : p = v[nd];
33 :
- 34 2752695 : for (i = 0; i < size; i += 8) {
- 35 2752608 : p0 = v_32(v[l][i]);
- 36 2752608 : p1 = v_32(v[l][i + 4]);
- 37 22022176 : for (d = l - 1; d >= 0; --d) {
- 38 19269568 : p0 ^= v_32(v[d][i]);
- 39 19269568 : p1 ^= v_32(v[d][i + 4]);
+ 34 2556081 : for (i = 0; i < size; i += 8) {
+ 35 2556000 : p0 = v_32(v[l][i]);
+ 36 2556000 : p1 = v_32(v[l][i + 4]);
+ 37 20449312 : for (d = l - 1; d >= 0; --d) {
+ 38 17893312 : p0 ^= v_32(v[d][i]);
+ 39 17893312 : p1 ^= v_32(v[d][i + 4]);
40 : }
- 41 2752608 : v_32(p[i]) = p0;
- 42 2752608 : v_32(p[i + 4]) = p1;
+ 41 2556000 : v_32(p[i]) = p0;
+ 42 2556000 : v_32(p[i + 4]) = p1;
43 : }
- 44 87 : }
+ 44 81 : }
45 :
46 : /*
47 : * GEN1 (RAID5 with xor) 64bit C implementation
48 : */
- 49 170 : void raid_gen1_int64(int nd, size_t size, void **vv)
+ 49 159 : void raid_gen1_int64(int nd, size_t size, void **vv)
50 : {
- 51 170 : uint8_t **v = (uint8_t **)vv;
+ 51 159 : uint8_t **v = (uint8_t **)vv;
52 : uint8_t *p;
53 : int d, l;
54 : size_t i;
@@ -118,27 +118,27 @@
56 : uint64_t p0;
57 : uint64_t p1;
58 :
- 59 170 : l = nd - 1;
- 60 170 : p = v[nd];
+ 59 159 : l = nd - 1;
+ 60 159 : p = v[nd];
61 :
- 62 2736346 : for (i = 0; i < size; i += 16) {
- 63 2736176 : p0 = v_64(v[l][i]);
- 64 2736176 : p1 = v_64(v[l][i + 8]);
- 65 21890064 : for (d = l - 1; d >= 0; --d) {
- 66 19153888 : p0 ^= v_64(v[d][i]);
- 67 19153888 : p1 ^= v_64(v[d][i + 8]);
+ 62 2556111 : for (i = 0; i < size; i += 16) {
+ 63 2555952 : p0 = v_64(v[l][i]);
+ 64 2555952 : p1 = v_64(v[l][i + 8]);
+ 65 20448272 : for (d = l - 1; d >= 0; --d) {
+ 66 17892320 : p0 ^= v_64(v[d][i]);
+ 67 17892320 : p1 ^= v_64(v[d][i + 8]);
68 : }
- 69 2736176 : v_64(p[i]) = p0;
- 70 2736176 : v_64(p[i + 8]) = p1;
+ 69 2555952 : v_64(p[i]) = p0;
+ 70 2555952 : v_64(p[i + 8]) = p1;
71 : }
- 72 170 : }
+ 72 159 : }
73 :
74 : /*
75 : * GEN2 (RAID6 with powers of 2) 32bit C implementation
76 : */
- 77 43 : void raid_gen2_int32(int nd, size_t size, void **vv)
+ 77 45 : void raid_gen2_int32(int nd, size_t size, void **vv)
78 : {
- 79 43 : uint8_t **v = (uint8_t **)vv;
+ 79 45 : uint8_t **v = (uint8_t **)vv;
80 : uint8_t *p;
81 : uint8_t *q;
82 : int d, l;
@@ -147,39 +147,39 @@
85 : uint32_t d0, q0, p0;
86 : uint32_t d1, q1, p1;
87 :
- 88 43 : l = nd - 1;
- 89 43 : p = v[nd];
- 90 43 : q = v[nd + 1];
+ 88 45 : l = nd - 1;
+ 89 45 : p = v[nd];
+ 90 45 : q = v[nd + 1];
91 :
- 92 1310859 : for (i = 0; i < size; i += 8) {
- 93 1310816 : q0 = p0 = v_32(v[l][i]);
- 94 1310816 : q1 = p1 = v_32(v[l][i + 4]);
- 95 10487840 : for (d = l - 1; d >= 0; --d) {
- 96 9177024 : d0 = v_32(v[d][i]);
- 97 9177024 : d1 = v_32(v[d][i + 4]);
+ 92 1376397 : for (i = 0; i < size; i += 8) {
+ 93 1376352 : q0 = p0 = v_32(v[l][i]);
+ 94 1376352 : q1 = p1 = v_32(v[l][i + 4]);
+ 95 11012128 : for (d = l - 1; d >= 0; --d) {
+ 96 9635776 : d0 = v_32(v[d][i]);
+ 97 9635776 : d1 = v_32(v[d][i + 4]);
98 :
- 99 9177024 : p0 ^= d0;
- 100 9177024 : p1 ^= d1;
+ 99 9635776 : p0 ^= d0;
+ 100 9635776 : p1 ^= d1;
101 :
- 102 9177024 : q0 = x2_32(q0);
- 103 9177024 : q1 = x2_32(q1);
+ 102 9635776 : q0 = x2_32(q0);
+ 103 9635776 : q1 = x2_32(q1);
104 :
- 105 9177024 : q0 ^= d0;
- 106 9177024 : q1 ^= d1;
+ 105 9635776 : q0 ^= d0;
+ 106 9635776 : q1 ^= d1;
107 : }
- 108 1310816 : v_32(p[i]) = p0;
- 109 1310816 : v_32(p[i + 4]) = p1;
- 110 1310816 : v_32(q[i]) = q0;
- 111 1310816 : v_32(q[i + 4]) = q1;
+ 108 1376352 : v_32(p[i]) = p0;
+ 109 1376352 : v_32(p[i + 4]) = p1;
+ 110 1376352 : v_32(q[i]) = q0;
+ 111 1376352 : v_32(q[i + 4]) = q1;
112 : }
- 113 43 : }
+ 113 45 : }
114 :
115 : /*
116 : * GEN2 (RAID6 with powers of 2) 64bit C implementation
117 : */
- 118 85 : void raid_gen2_int64(int nd, size_t size, void **vv)
+ 118 81 : void raid_gen2_int64(int nd, size_t size, void **vv)
119 : {
- 120 85 : uint8_t **v = (uint8_t **)vv;
+ 120 81 : 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 85 : l = nd - 1;
- 130 85 : p = v[nd];
- 131 85 : q = v[nd + 1];
+ 129 81 : l = nd - 1;
+ 130 81 : p = v[nd];
+ 131 81 : q = v[nd + 1];
132 :
- 133 1343621 : for (i = 0; i < size; i += 16) {
- 134 1343536 : q0 = p0 = v_64(v[l][i]);
- 135 1343536 : q1 = p1 = v_64(v[l][i + 8]);
- 136 10748944 : for (d = l - 1; d >= 0; --d) {
- 137 9405408 : d0 = v_64(v[d][i]);
- 138 9405408 : d1 = v_64(v[d][i + 8]);
+ 133 1278081 : for (i = 0; i < size; i += 16) {
+ 134 1278000 : q0 = p0 = v_64(v[l][i]);
+ 135 1278000 : q1 = p1 = v_64(v[l][i + 8]);
+ 136 10224656 : for (d = l - 1; d >= 0; --d) {
+ 137 8946656 : d0 = v_64(v[d][i]);
+ 138 8946656 : d1 = v_64(v[d][i + 8]);
139 :
- 140 9405408 : p0 ^= d0;
- 141 9405408 : p1 ^= d1;
+ 140 8946656 : p0 ^= d0;
+ 141 8946656 : p1 ^= d1;
142 :
- 143 9405408 : q0 = x2_64(q0);
- 144 9405408 : q1 = x2_64(q1);
+ 143 8946656 : q0 = x2_64(q0);
+ 144 8946656 : q1 = x2_64(q1);
145 :
- 146 9405408 : q0 ^= d0;
- 147 9405408 : q1 ^= d1;
+ 146 8946656 : q0 ^= d0;
+ 147 8946656 : q1 ^= d1;
148 : }
- 149 1343536 : v_64(p[i]) = p0;
- 150 1343536 : v_64(p[i + 8]) = p1;
- 151 1343536 : v_64(q[i]) = q0;
- 152 1343536 : v_64(q[i + 8]) = q1;
+ 149 1278000 : v_64(p[i]) = p0;
+ 150 1278000 : v_64(p[i + 8]) = p1;
+ 151 1278000 : v_64(q[i]) = q0;
+ 152 1278000 : v_64(q[i + 8]) = q1;
153 : }
- 154 85 : }
+ 154 81 : }
155 :
156 : /*
157 : * GEN3 (triple parity with Cauchy matrix) 8bit C implementation
@@ -223,9 +223,9 @@
161 : * But this is only a kind of reference function, and we are not really
162 : * interested in speed.
163 : */
- 164 28 : void raid_gen3_int8(int nd, size_t size, void **vv)
+ 164 27 : void raid_gen3_int8(int nd, size_t size, void **vv)
165 : {
- 166 28 : uint8_t **v = (uint8_t **)vv;
+ 166 27 : uint8_t **v = (uint8_t **)vv;
167 : uint8_t *p;
168 : uint8_t *q;
169 : uint8_t *r;
@@ -234,33 +234,33 @@
172 :
173 : uint8_t d0, r0, q0, p0;
174 :
- 175 28 : l = nd - 1;
- 176 28 : p = v[nd];
- 177 28 : q = v[nd + 1];
- 178 28 : r = v[nd + 2];
+ 175 27 : l = nd - 1;
+ 176 27 : p = v[nd];
+ 177 27 : q = v[nd + 1];
+ 178 27 : r = v[nd + 2];
179 :
- 180 6816284 : for (i = 0; i < size; i += 1) {
- 181 6816256 : p0 = q0 = r0 = 0;
- 182 54534400 : for (d = l; d > 0; --d) {
- 183 47718144 : d0 = v_8(v[d][i]);
+ 180 6554139 : for (i = 0; i < size; i += 1) {
+ 181 6554112 : p0 = q0 = r0 = 0;
+ 182 52437248 : for (d = l; d > 0; --d) {
+ 183 45883136 : d0 = v_8(v[d][i]);
184 :
- 185 47718144 : p0 ^= d0;
- 186 47718144 : q0 ^= gfmul[d0][gfgen[1][d]];
- 187 47718144 : r0 ^= gfmul[d0][gfgen[2][d]];
+ 185 45883136 : p0 ^= d0;
+ 186 45883136 : q0 ^= gfmul[d0][gfgen[1][d]];
+ 187 45883136 : r0 ^= gfmul[d0][gfgen[2][d]];
188 : }
189 :
190 : /* first disk with all coefficients at 1 */
- 191 6816256 : d0 = v_8(v[0][i]);
+ 191 6554112 : d0 = v_8(v[0][i]);
192 :
- 193 6816256 : p0 ^= d0;
- 194 6816256 : q0 ^= d0;
- 195 6816256 : r0 ^= d0;
+ 193 6554112 : p0 ^= d0;
+ 194 6554112 : q0 ^= d0;
+ 195 6554112 : r0 ^= d0;
196 :
- 197 6816256 : v_8(p[i]) = p0;
- 198 6816256 : v_8(q[i]) = q0;
- 199 6816256 : v_8(r[i]) = r0;
+ 197 6554112 : v_8(p[i]) = p0;
+ 198 6554112 : v_8(q[i]) = q0;
+ 199 6554112 : v_8(r[i]) = r0;
200 : }
- 201 28 : }
+ 201 27 : }
202 :
203 : /*
204 : * GEN4 (quad 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 18 : void raid_gen6_int8(int nd, size_t size, void **vv)
+ 320 17 : void raid_gen6_int8(int nd, size_t size, void **vv)
321 : {
- 322 18 : uint8_t **v = (uint8_t **)vv;
+ 322 17 : 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 18 : l = nd - 1;
- 335 18 : p = v[nd];
- 336 18 : q = v[nd + 1];
- 337 18 : r = v[nd + 2];
- 338 18 : s = v[nd + 3];
- 339 18 : t = v[nd + 4];
- 340 18 : u = v[nd + 5];
+ 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];
341 :
- 342 4194834 : for (i = 0; i < size; i += 1) {
- 343 4194816 : p0 = q0 = r0 = s0 = t0 = u0 = 0;
- 344 33562880 : for (d = l; d > 0; --d) {
- 345 29368064 : d0 = v_8(v[d][i]);
+ 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]);
346 :
- 347 29368064 : p0 ^= d0;
- 348 29368064 : q0 ^= gfmul[d0][gfgen[1][d]];
- 349 29368064 : r0 ^= gfmul[d0][gfgen[2][d]];
- 350 29368064 : s0 ^= gfmul[d0][gfgen[3][d]];
- 351 29368064 : t0 ^= gfmul[d0][gfgen[4][d]];
- 352 29368064 : u0 ^= gfmul[d0][gfgen[5][d]];
+ 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]];
353 : }
354 :
355 : /* first disk with all coefficients at 1 */
- 356 4194816 : d0 = v_8(v[0][i]);
+ 356 3932672 : d0 = v_8(v[0][i]);
357 :
- 358 4194816 : p0 ^= d0;
- 359 4194816 : q0 ^= d0;
- 360 4194816 : r0 ^= d0;
- 361 4194816 : s0 ^= d0;
- 362 4194816 : t0 ^= d0;
- 363 4194816 : u0 ^= d0;
+ 358 3932672 : p0 ^= d0;
+ 359 3932672 : q0 ^= d0;
+ 360 3932672 : r0 ^= d0;
+ 361 3932672 : s0 ^= d0;
+ 362 3932672 : t0 ^= d0;
+ 363 3932672 : u0 ^= d0;
364 :
- 365 4194816 : v_8(p[i]) = p0;
- 366 4194816 : v_8(q[i]) = q0;
- 367 4194816 : v_8(r[i]) = r0;
- 368 4194816 : v_8(s[i]) = s0;
- 369 4194816 : v_8(t[i]) = t0;
- 370 4194816 : v_8(u[i]) = u0;
+ 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;
371 : }
- 372 18 : }
+ 372 17 : }
373 :
374 : /*
375 : * Recover failure of one data block at index id[0] using parity at index
diff --git a/cov/raid/internal.h.func-sort-c.html b/cov/raid/internal.h.func-sort-c.html
index 2c544d80..22a993b8 100644
--- a/cov/raid/internal.h.func-sort-c.html
+++ b/cov/raid/internal.h.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/raid/internal.h.func.html b/cov/raid/internal.h.func.html
index def6d77b..10ed9b0a 100644
--- a/cov/raid/internal.h.func.html
+++ b/cov/raid/internal.h.func.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/raid/internal.h.gcov.html b/cov/raid/internal.h.gcov.html
index 3708373a..be8e1db7 100644
--- a/cov/raid/internal.h.gcov.html
+++ b/cov/raid/internal.h.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -286,7 +286,7 @@
224 : #ifdef CONFIG_SSE2
225 : static __always_inline void raid_sse_begin(void)
226 : {
- 227 1384907 : }
+ 227 1385012 : }
228 :
229 : static __always_inline void raid_sse_end(void)
230 : {
@@ -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 1384907 : asm volatile ("sfence" : : : "memory");
+ 235 1385012 : asm volatile ("sfence" : : : "memory");
236 :
237 : /* clobbers registers used in the asm code */
238 : /* this is required because in the Windows ABI, */
@@ -304,21 +304,21 @@
242 : /* we check for __SSE2_ because we require that the */
243 : /* compiler supports SSE2 registers in the clobber list */
244 : #ifdef __SSE2__
- 245 1384907 : asm volatile ("" : : : "%xmm0", "%xmm1", "%xmm2", "%xmm3");
- 246 1384907 : asm volatile ("" : : : "%xmm4", "%xmm5", "%xmm6", "%xmm7");
+ 245 1385012 : asm volatile ("" : : : "%xmm0", "%xmm1", "%xmm2", "%xmm3");
+ 246 1385012 : asm volatile ("" : : : "%xmm4", "%xmm5", "%xmm6", "%xmm7");
247 : #ifdef CONFIG_X86_64
- 248 1384907 : asm volatile ("" : : : "%xmm8", "%xmm9", "%xmm10", "%xmm11");
- 249 1384907 : asm volatile ("" : : : "%xmm12", "%xmm13", "%xmm14", "%xmm15");
+ 248 1385012 : asm volatile ("" : : : "%xmm8", "%xmm9", "%xmm10", "%xmm11");
+ 249 1385012 : asm volatile ("" : : : "%xmm12", "%xmm13", "%xmm14", "%xmm15");
250 : #endif
251 : #endif
- 252 1384907 : }
+ 252 1385012 : }
253 : #endif
254 :
255 : #ifdef CONFIG_AVX2
256 : static __always_inline void raid_avx_begin(void)
257 : {
258 : raid_sse_begin();
- 259 76343 : }
+ 259 76341 : }
260 :
261 : static __always_inline void raid_avx_end(void)
262 : {
@@ -327,8 +327,8 @@
265 : /* reset the upper part of the ymm registers */
266 : /* to avoid the 70 clocks penalty on the next */
267 : /* xmm register use */
- 268 76343 : asm volatile ("vzeroupper" : : : "memory");
- 269 76343 : }
+ 268 76341 : asm volatile ("vzeroupper" : : : "memory");
+ 269 76341 : }
270 : #endif
271 : #endif /* CONFIG_X86 */
272 :
diff --git a/cov/raid/intz.c.func-sort-c.html b/cov/raid/intz.c.func-sort-c.html
index 3ba5d52b..57b4d6ec 100644
--- a/cov/raid/intz.c.func-sort-c.html
+++ b/cov/raid/intz.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -65,7 +65,7 @@
| raid_genz_int64 |
- 50 |
+ 52 |
diff --git a/cov/raid/intz.c.func.html b/cov/raid/intz.c.func.html
index 312f1401..ab130941 100644
--- a/cov/raid/intz.c.func.html
+++ b/cov/raid/intz.c.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -65,7 +65,7 @@
| raid_genz_int64 |
- 50 |
+ 52 |
diff --git a/cov/raid/intz.c.gcov.html b/cov/raid/intz.c.gcov.html
index 1ad1506b..865608c8 100644
--- a/cov/raid/intz.c.gcov.html
+++ b/cov/raid/intz.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -131,9 +131,9 @@
69 : /*
70 : * GENz (triple parity with powers of 2^-1) 64bit C implementation
71 : */
- 72 50 : void raid_genz_int64(int nd, size_t size, void **vv)
+ 72 52 : void raid_genz_int64(int nd, size_t size, void **vv)
73 : {
- 74 50 : uint8_t **v = (uint8_t**)vv;
+ 74 52 : uint8_t **v = (uint8_t**)vv;
75 : uint8_t *p;
76 : uint8_t *q;
77 : uint8_t *r;
@@ -143,41 +143,41 @@
81 : uint64_t d0, r0, q0, p0;
82 : uint64_t d1, r1, q1, p1;
83 :
- 84 50 : l = nd - 1;
- 85 50 : p = v[nd];
- 86 50 : q = v[nd + 1];
- 87 50 : r = v[nd + 2];
+ 84 52 : l = nd - 1;
+ 85 52 : p = v[nd];
+ 86 52 : q = v[nd + 1];
+ 87 52 : r = v[nd + 2];
88 :
- 89 802882 : for (i = 0; i < size; i += 16) {
- 90 802832 : r0 = q0 = p0 = v_64(v[l][i]);
- 91 802832 : r1 = q1 = p1 = v_64(v[l][i + 8]);
- 92 6423040 : for (d = l - 1; d >= 0; --d) {
- 93 5620208 : d0 = v_64(v[d][i]);
- 94 5620208 : d1 = v_64(v[d][i + 8]);
+ 89 835652 : for (i = 0; i < size; i += 16) {
+ 90 835600 : r0 = q0 = p0 = v_64(v[l][i]);
+ 91 835600 : r1 = q1 = p1 = v_64(v[l][i + 8]);
+ 92 6685184 : for (d = l - 1; d >= 0; --d) {
+ 93 5849584 : d0 = v_64(v[d][i]);
+ 94 5849584 : d1 = v_64(v[d][i + 8]);
95 :
- 96 5620208 : p0 ^= d0;
- 97 5620208 : p1 ^= d1;
+ 96 5849584 : p0 ^= d0;
+ 97 5849584 : p1 ^= d1;
98 :
- 99 5620208 : q0 = x2_64(q0);
- 100 5620208 : q1 = x2_64(q1);
+ 99 5849584 : q0 = x2_64(q0);
+ 100 5849584 : q1 = x2_64(q1);
101 :
- 102 5620208 : q0 ^= d0;
- 103 5620208 : q1 ^= d1;
+ 102 5849584 : q0 ^= d0;
+ 103 5849584 : q1 ^= d1;
104 :
- 105 5620208 : r0 = d2_64(r0);
- 106 5620208 : r1 = d2_64(r1);
+ 105 5849584 : r0 = d2_64(r0);
+ 106 5849584 : r1 = d2_64(r1);
107 :
- 108 5620208 : r0 ^= d0;
- 109 5620208 : r1 ^= d1;
+ 108 5849584 : r0 ^= d0;
+ 109 5849584 : r1 ^= d1;
110 : }
- 111 802832 : v_64(p[i]) = p0;
- 112 802832 : v_64(p[i + 8]) = p1;
- 113 802832 : v_64(q[i]) = q0;
- 114 802832 : v_64(q[i + 8]) = q1;
- 115 802832 : v_64(r[i]) = r0;
- 116 802832 : v_64(r[i + 8]) = r1;
+ 111 835600 : v_64(p[i]) = p0;
+ 112 835600 : v_64(p[i + 8]) = p1;
+ 113 835600 : v_64(q[i]) = q0;
+ 114 835600 : v_64(q[i + 8]) = q1;
+ 115 835600 : v_64(r[i]) = r0;
+ 116 835600 : v_64(r[i + 8]) = r1;
117 : }
- 118 50 : }
+ 118 52 : }
119 :
diff --git a/cov/raid/memory.c.func-sort-c.html b/cov/raid/memory.c.func-sort-c.html
index 7ca2bab7..15d9d735 100644
--- a/cov/raid/memory.c.func-sort-c.html
+++ b/cov/raid/memory.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/raid/memory.c.func.html b/cov/raid/memory.c.func.html
index 9af16b33..71350f7e 100644
--- a/cov/raid/memory.c.func.html
+++ b/cov/raid/memory.c.func.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/raid/memory.c.gcov.html b/cov/raid/memory.c.gcov.html
index ef7529bc..80beed4b 100644
--- a/cov/raid/memory.c.gcov.html
+++ b/cov/raid/memory.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -94,7 +94,7 @@
32 13341 : offset = ((uintptr_t)ptr) % align_size;
33 :
34 13341 : if (offset != 0)
- 35 12532 : ptr += align_size - offset;
+ 35 12568 : ptr += align_size - offset;
36 :
37 13341 : return ptr;
38 : }
diff --git a/cov/raid/module.c.func-sort-c.html b/cov/raid/module.c.func-sort-c.html
index 3b26c283..80266f0d 100644
--- a/cov/raid/module.c.func-sort-c.html
+++ b/cov/raid/module.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -85,7 +85,7 @@
| raid_init |
- 283 |
+ 284 |
diff --git a/cov/raid/module.c.func.html b/cov/raid/module.c.func.html
index bb0ce76e..765ac923 100644
--- a/cov/raid/module.c.func.html
+++ b/cov/raid/module.c.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -65,7 +65,7 @@
| raid_init |
- 283 |
+ 284 |
| raid_selftest |
diff --git a/cov/raid/module.c.gcov.html b/cov/raid/module.c.gcov.html
index 6f816fb8..5abe522c 100644
--- a/cov/raid/module.c.gcov.html
+++ b/cov/raid/module.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -81,42 +81,42 @@
19 : /*
20 : * Initializes and selects the best algorithm.
21 : */
- 22 283 : void raid_init(void)
+ 22 284 : void raid_init(void)
23 : {
- 24 283 : raid_gen3_ptr = raid_gen3_int8;
- 25 283 : raid_gen_ptr[3] = raid_gen4_int8;
- 26 283 : raid_gen_ptr[4] = raid_gen5_int8;
- 27 283 : raid_gen_ptr[5] = raid_gen6_int8;
+ 24 284 : raid_gen3_ptr = raid_gen3_int8;
+ 25 284 : raid_gen_ptr[3] = raid_gen4_int8;
+ 26 284 : raid_gen_ptr[4] = raid_gen5_int8;
+ 27 284 : raid_gen_ptr[5] = raid_gen6_int8;
28 :
29 : if (sizeof(void *) == 4) {
30 : raid_gen_ptr[0] = raid_gen1_int32;
31 : raid_gen_ptr[1] = raid_gen2_int32;
32 : raid_genz_ptr = raid_genz_int32;
33 : } else {
- 34 283 : raid_gen_ptr[0] = raid_gen1_int64;
- 35 283 : raid_gen_ptr[1] = raid_gen2_int64;
- 36 283 : raid_genz_ptr = raid_genz_int64;
+ 34 284 : raid_gen_ptr[0] = raid_gen1_int64;
+ 35 284 : raid_gen_ptr[1] = raid_gen2_int64;
+ 36 284 : raid_genz_ptr = raid_genz_int64;
37 : }
38 :
- 39 283 : raid_rec_ptr[0] = raid_rec1_int8;
- 40 283 : raid_rec_ptr[1] = raid_rec2_int8;
- 41 283 : raid_rec_ptr[2] = raid_recX_int8;
- 42 283 : raid_rec_ptr[3] = raid_recX_int8;
- 43 283 : raid_rec_ptr[4] = raid_recX_int8;
- 44 283 : raid_rec_ptr[5] = raid_recX_int8;
+ 39 284 : raid_rec_ptr[0] = raid_rec1_int8;
+ 40 284 : raid_rec_ptr[1] = raid_rec2_int8;
+ 41 284 : raid_rec_ptr[2] = raid_recX_int8;
+ 42 284 : raid_rec_ptr[3] = raid_recX_int8;
+ 43 284 : raid_rec_ptr[4] = raid_recX_int8;
+ 44 284 : raid_rec_ptr[5] = raid_recX_int8;
45 :
46 : #ifdef CONFIG_X86
47 : #ifdef CONFIG_SSE2
- 48 283 : if (raid_cpu_has_sse2()) {
- 49 283 : raid_gen_ptr[0] = raid_gen1_sse2;
+ 48 284 : if (raid_cpu_has_sse2()) {
+ 49 284 : raid_gen_ptr[0] = raid_gen1_sse2;
50 : #ifdef CONFIG_X86_64
- 51 283 : if (raid_cpu_has_slowextendedreg()) {
+ 51 284 : if (raid_cpu_has_slowextendedreg()) {
52 0 : raid_gen_ptr[1] = raid_gen2_sse2;
53 : } else {
- 54 283 : raid_gen_ptr[1] = raid_gen2_sse2ext;
+ 54 284 : raid_gen_ptr[1] = raid_gen2_sse2ext;
55 : }
56 : /* note that raid_cpu_has_slowextendedreg() doesn't affect parz */
- 57 283 : raid_genz_ptr = raid_genz_sse2ext;
+ 57 284 : raid_genz_ptr = raid_genz_sse2ext;
58 : #else
59 : raid_gen_ptr[1] = raid_gen2_sse2;
60 : raid_genz_ptr = raid_genz_sse2;
@@ -125,18 +125,18 @@
63 : #endif
64 :
65 : #ifdef CONFIG_SSSE3
- 66 283 : if (raid_cpu_has_ssse3()) {
+ 66 284 : if (raid_cpu_has_ssse3()) {
67 : #ifdef CONFIG_X86_64
- 68 282 : if (raid_cpu_has_slowextendedreg()) {
+ 68 283 : if (raid_cpu_has_slowextendedreg()) {
69 0 : raid_gen3_ptr = raid_gen3_ssse3;
70 0 : raid_gen_ptr[3] = raid_gen4_ssse3;
71 0 : raid_gen_ptr[4] = raid_gen5_ssse3;
72 0 : raid_gen_ptr[5] = raid_gen6_ssse3;
73 : } else {
- 74 282 : raid_gen3_ptr = raid_gen3_ssse3ext;
- 75 282 : raid_gen_ptr[3] = raid_gen4_ssse3ext;
- 76 282 : raid_gen_ptr[4] = raid_gen5_ssse3ext;
- 77 282 : raid_gen_ptr[5] = raid_gen6_ssse3ext;
+ 74 283 : raid_gen3_ptr = raid_gen3_ssse3ext;
+ 75 283 : raid_gen_ptr[3] = raid_gen4_ssse3ext;
+ 76 283 : raid_gen_ptr[4] = raid_gen5_ssse3ext;
+ 77 283 : raid_gen_ptr[5] = raid_gen6_ssse3ext;
78 : }
79 : #else
80 : raid_gen3_ptr = raid_gen3_ssse3;
@@ -144,17 +144,17 @@
82 : raid_gen_ptr[4] = raid_gen5_ssse3;
83 : raid_gen_ptr[5] = raid_gen6_ssse3;
84 : #endif
- 85 282 : raid_rec_ptr[0] = raid_rec1_ssse3;
- 86 282 : raid_rec_ptr[1] = raid_rec2_ssse3;
- 87 282 : raid_rec_ptr[2] = raid_recX_ssse3;
- 88 282 : raid_rec_ptr[3] = raid_recX_ssse3;
- 89 282 : raid_rec_ptr[4] = raid_recX_ssse3;
- 90 282 : raid_rec_ptr[5] = raid_recX_ssse3;
+ 85 283 : raid_rec_ptr[0] = raid_rec1_ssse3;
+ 86 283 : raid_rec_ptr[1] = raid_rec2_ssse3;
+ 87 283 : raid_rec_ptr[2] = raid_recX_ssse3;
+ 88 283 : raid_rec_ptr[3] = raid_recX_ssse3;
+ 89 283 : raid_rec_ptr[4] = raid_recX_ssse3;
+ 90 283 : raid_rec_ptr[5] = raid_recX_ssse3;
91 : }
92 : #endif
93 :
94 : #ifdef CONFIG_AVX2
- 95 283 : if (raid_cpu_has_avx2()) {
+ 95 284 : 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 283 : raid_mode(RAID_MODE_CAUCHY);
- 117 283 : }
+ 116 284 : raid_mode(RAID_MODE_CAUCHY);
+ 117 284 : }
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 01a6dfd2..e4208e4e 100644
--- a/cov/raid/raid.c.func-sort-c.html
+++ b/cov/raid/raid.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -69,31 +69,31 @@
| raid_mode |
- 565 |
+ 567 |
| raid_rec |
- 869 |
+ 870 |
| raid_rec1of1 |
- 96873 |
+ 97058 |
| raid_delta_gen |
- 171489 |
+ 171505 |
| raid_invert |
- 172553 |
+ 172549 |
| raid_data |
- 210062 |
+ 210262 |
| raid_gen |
- 1232444 |
+ 1232542 |
diff --git a/cov/raid/raid.c.func.html b/cov/raid/raid.c.func.html
index 1d966ca9..f98041e6 100644
--- a/cov/raid/raid.c.func.html
+++ b/cov/raid/raid.c.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,31 +61,31 @@
| raid_data |
- 210062 |
+ 210262 |
| raid_delta_gen |
- 171489 |
+ 171505 |
| raid_gen |
- 1232444 |
+ 1232542 |
| raid_invert |
- 172553 |
+ 172549 |
| raid_mode |
- 565 |
+ 567 |
| raid_rec |
- 869 |
+ 870 |
| raid_rec1of1 |
- 96873 |
+ 97058 |
| raid_rec2of2_int8 |
diff --git a/cov/raid/raid.c.gcov.html b/cov/raid/raid.c.gcov.html
index 363afff5..90ae049a 100644
--- a/cov/raid/raid.c.gcov.html
+++ b/cov/raid/raid.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -274,16 +274,16 @@
212 : */
213 : const uint8_t (*raid_gfgen)[256];
214 :
- 215 565 : void raid_mode(int mode)
+ 215 567 : void raid_mode(int mode)
216 : {
- 217 565 : if (mode == RAID_MODE_VANDERMONDE) {
+ 217 567 : if (mode == RAID_MODE_VANDERMONDE) {
218 2 : raid_gen_ptr[2] = raid_genz_ptr;
219 2 : raid_gfgen = gfvandermonde;
220 : } else {
- 221 563 : raid_gen_ptr[2] = raid_gen3_ptr;
- 222 563 : raid_gfgen = gfcauchy;
+ 221 565 : raid_gen_ptr[2] = raid_gen3_ptr;
+ 222 565 : raid_gfgen = gfcauchy;
223 : }
- 224 565 : }
+ 224 567 : }
225 :
226 : /**
227 : * Buffer filled with 0 used in recovering.
@@ -321,17 +321,17 @@
259 : void (*raid_gen3_ptr)(int nd, size_t size, void **vv);
260 : void (*raid_genz_ptr)(int nd, size_t size, void **vv);
261 :
- 262 1232444 : void raid_gen(int nd, int np, size_t size, void **v)
+ 262 1232542 : void raid_gen(int nd, int np, size_t size, void **v)
263 : {
264 : /* enforce limit on size */
- 265 1232444 : BUG_ON(size % 64 != 0);
+ 265 1232542 : BUG_ON(size % 64 != 0);
266 :
267 : /* enforce limit on number of failures */
- 268 1232444 : BUG_ON(np < 1);
- 269 1232444 : BUG_ON(np > RAID_PARITY_MAX);
+ 268 1232542 : BUG_ON(np < 1);
+ 269 1232542 : BUG_ON(np > RAID_PARITY_MAX);
270 :
- 271 1232444 : raid_gen_ptr[np - 1](nd, size, v);
- 272 1232444 : }
+ 271 1232542 : raid_gen_ptr[np - 1](nd, size, v);
+ 272 1232542 : }
273 :
274 : /**
275 : * Inverts the square matrix M of size nxn into V.
@@ -344,44 +344,44 @@
282 : * @V Destination matrix where the result is put.
283 : * @n Number of rows and columns of the matrix.
284 : */
- 285 172553 : void raid_invert(uint8_t *M, uint8_t *V, int n)
+ 285 172549 : void raid_invert(uint8_t *M, uint8_t *V, int n)
286 : {
287 : int i, j, k;
288 :
289 : /* set the identity matrix in V */
- 290 797716 : for (i = 0; i < n; ++i)
- 291 3219716 : for (j = 0; j < n; ++j)
- 292 2594553 : V[i * n + j] = i == j;
+ 290 797704 : for (i = 0; i < n; ++i)
+ 291 3219692 : for (j = 0; j < n; ++j)
+ 292 2594537 : V[i * n + j] = i == j;
293 :
294 : /* for each element in the diagonal */
- 295 797716 : for (k = 0; k < n; ++k) {
+ 295 797704 : for (k = 0; k < n; ++k) {
296 : uint8_t f;
297 :
298 : /* the diagonal element cannot be 0 because */
299 : /* we are inverting matrices with all the square */
300 : /* submatrices not singular */
- 301 625163 : BUG_ON(M[k * n + k] == 0);
+ 301 625155 : BUG_ON(M[k * n + k] == 0);
302 :
303 : /* make the diagonal element to be 1 */
- 304 625163 : f = inv(M[k * n + k]);
- 305 3219716 : for (j = 0; j < n; ++j) {
- 306 2594553 : M[k * n + j] = mul(f, M[k * n + j]);
- 307 5189106 : V[k * n + j] = mul(f, V[k * n + j]);
+ 304 625155 : f = inv(M[k * n + k]);
+ 305 3219692 : for (j = 0; j < n; ++j) {
+ 306 2594537 : M[k * n + j] = mul(f, M[k * n + j]);
+ 307 5189074 : V[k * n + j] = mul(f, V[k * n + j]);
308 : }
309 :
310 : /* make all the elements over and under the diagonal */
311 : /* to be zero */
- 312 3219716 : for (i = 0; i < n; ++i) {
- 313 2594553 : if (i == k)
- 314 625163 : continue;
- 315 1969390 : f = M[i * n + k];
- 316 11271234 : for (j = 0; j < n; ++j) {
- 317 9301844 : M[i * n + j] ^= mul(f, M[k * n + j]);
- 318 18603688 : V[i * n + j] ^= mul(f, V[k * n + j]);
+ 312 3219692 : for (i = 0; i < n; ++i) {
+ 313 2594537 : if (i == k)
+ 314 625155 : continue;
+ 315 1969382 : f = M[i * n + k];
+ 316 11271210 : for (j = 0; j < n; ++j) {
+ 317 9301828 : M[i * n + j] ^= mul(f, M[k * n + j]);
+ 318 18603656 : V[i * n + j] ^= mul(f, V[k * n + j]);
319 : }
320 : }
321 : }
- 322 172553 : }
+ 322 172549 : }
323 :
324 : /**
325 : * Computes the parity without the missing data blocks
@@ -389,7 +389,7 @@
327 : *
328 : * This is the parity expressed as Pa,Qa,Ra,Sa,Ta,Ua in the equations.
329 : */
- 330 171489 : void raid_delta_gen(int nr, int *id, int *ip, int nd, size_t size, void **v)
+ 330 171505 : void raid_delta_gen(int nr, int *id, int *ip, int nd, size_t size, void **v)
331 : {
332 : void *p[RAID_PARITY_MAX];
333 : void *pa[RAID_PARITY_MAX];
@@ -399,17 +399,17 @@
337 :
338 : /* total number of parities we are going to process */
339 : /* they are both the used and the unused ones */
- 340 171489 : np = ip[nr - 1] + 1;
+ 340 171505 : np = ip[nr - 1] + 1;
341 :
342 : /* latest missing data block */
- 343 171489 : latest = v[id[nr - 1]];
+ 343 171505 : latest = v[id[nr - 1]];
344 :
345 : /* setup pointers for delta computation */
- 346 872987 : for (i = 0, j = 0; i < np; ++i) {
+ 346 873035 : for (i = 0, j = 0; i < np; ++i) {
347 : /* keep a copy of the original parity vector */
- 348 701498 : p[i] = v[nd + i];
+ 348 701530 : p[i] = v[nd + i];
349 :
- 350 701498 : if (ip[j] == i) {
+ 350 701530 : if (ip[j] == i) {
351 : /*
352 : * Set used parities to point to the missing
353 : * data blocks.
@@ -420,19 +420,19 @@
358 :
359 : /* the latest parity to use ends the for loop and */
360 : /* then it cannot happen to process more of them */
- 361 605425 : BUG_ON(j >= nr);
+ 361 605437 : BUG_ON(j >= nr);
362 :
363 : /* buffer for missing data blocks */
- 364 605425 : pa[j] = v[id[j]];
+ 364 605437 : pa[j] = v[id[j]];
365 :
366 : /* set at zero the missing data blocks */
- 367 605425 : v[id[j]] = raid_zero_block;
+ 367 605437 : v[id[j]] = raid_zero_block;
368 :
369 : /* compute the parity over the missing data blocks */
- 370 605425 : v[nd + i] = pa[j];
+ 370 605437 : v[nd + i] = pa[j];
371 :
372 : /* check for the next used entry */
- 373 605425 : ++j;
+ 373 605437 : ++j;
374 : } else {
375 : /*
376 : * Unused parities are going to be rewritten with
@@ -452,25 +452,25 @@
390 : * multiple times and only the latest write will
391 : * contain the correct data.
392 : */
- 393 96073 : v[nd + i] = latest;
+ 393 96093 : v[nd + i] = latest;
394 : }
395 : }
396 :
397 : /* all the parities have to be processed */
- 398 171489 : BUG_ON(j != nr);
+ 398 171505 : BUG_ON(j != nr);
399 :
400 : /* recompute the parity, note that np may be smaller than the */
401 : /* total number of parities available */
- 402 171489 : raid_gen(nd, np, size, v);
+ 402 171505 : raid_gen(nd, np, size, v);
403 :
404 : /* restore data buffers as before */
- 405 776914 : for (j = 0; j < nr; ++j)
- 406 605425 : v[id[j]] = pa[j];
+ 405 776942 : for (j = 0; j < nr; ++j)
+ 406 605437 : v[id[j]] = pa[j];
407 :
408 : /* restore parity buffers as before */
- 409 872987 : for (i = 0; i < np; ++i)
- 410 701498 : v[nd + i] = p[i];
- 411 171489 : }
+ 409 873035 : for (i = 0; i < np; ++i)
+ 410 701530 : v[nd + i] = p[i];
+ 411 171505 : }
412 :
413 : /**
414 : * Recover failure of one data block for PAR1.
@@ -483,29 +483,29 @@
421 : *
422 : * Dx = Pd
423 : */
- 424 96873 : void raid_rec1of1(int *id, int nd, size_t size, void **v)
+ 424 97058 : void raid_rec1of1(int *id, int nd, size_t size, void **v)
425 : {
426 : void *p;
427 : void *pa;
428 :
429 : /* for PAR1 we can directly compute the missing block */
430 : /* and we don't need to use the zero buffer */
- 431 96873 : p = v[nd];
- 432 96873 : pa = v[id[0]];
+ 431 97058 : p = v[nd];
+ 432 97058 : pa = v[id[0]];
433 :
434 : /* use the parity as missing data block */
- 435 96873 : v[id[0]] = p;
+ 435 97058 : v[id[0]] = p;
436 :
437 : /* compute the parity over the missing data block */
- 438 96873 : v[nd] = pa;
+ 438 97058 : v[nd] = pa;
439 :
440 : /* compute */
- 441 96873 : raid_gen(nd, 1, size, v);
+ 441 97058 : raid_gen(nd, 1, size, v);
442 :
443 : /* restore as before */
- 444 96873 : v[id[0]] = pa;
- 445 96873 : v[nd] = p;
- 446 96873 : }
+ 444 97058 : v[id[0]] = pa;
+ 445 97058 : v[nd] = p;
+ 446 97058 : }
447 :
448 : /**
449 : * Recover failure of two data blocks for PAR2.
@@ -593,97 +593,97 @@
531 : void (*raid_rec_ptr[RAID_PARITY_MAX])(
532 : int nr, int *id, int *ip, int nd, size_t size, void **vv);
533 :
- 534 869 : void raid_rec(int nr, int *ir, int nd, int np, size_t size, void **v)
+ 534 870 : void raid_rec(int nr, int *ir, int nd, int np, size_t size, void **v)
535 : {
536 : int nrd; /* number of data blocks to recover */
537 : int nrp; /* number of parity blocks to recover */
538 :
539 : /* enforce limit on size */
- 540 869 : BUG_ON(size % 64 != 0);
+ 540 870 : BUG_ON(size % 64 != 0);
541 :
542 : /* enforce limit on number of failures */
- 543 869 : BUG_ON(nr > np);
- 544 869 : BUG_ON(np > RAID_PARITY_MAX);
+ 543 870 : BUG_ON(nr > np);
+ 544 870 : BUG_ON(np > RAID_PARITY_MAX);
545 :
546 : /* enforce order in index vector */
- 547 869 : BUG_ON(nr >= 2 && ir[0] >= ir[1]);
- 548 869 : BUG_ON(nr >= 3 && ir[1] >= ir[2]);
- 549 869 : BUG_ON(nr >= 4 && ir[2] >= ir[3]);
- 550 869 : BUG_ON(nr >= 5 && ir[3] >= ir[4]);
- 551 869 : BUG_ON(nr >= 6 && ir[4] >= ir[5]);
+ 547 870 : BUG_ON(nr >= 2 && ir[0] >= ir[1]);
+ 548 870 : BUG_ON(nr >= 3 && ir[1] >= ir[2]);
+ 549 870 : BUG_ON(nr >= 4 && ir[2] >= ir[3]);
+ 550 870 : BUG_ON(nr >= 5 && ir[3] >= ir[4]);
+ 551 870 : BUG_ON(nr >= 6 && ir[4] >= ir[5]);
552 :
553 : /* enforce limit on index vector */
- 554 869 : BUG_ON(nr > 0 && ir[nr-1] >= nd + np);
+ 554 870 : BUG_ON(nr > 0 && ir[nr-1] >= nd + np);
555 :
556 : /* count the number of data blocks to recover */
- 557 869 : nrd = 0;
- 558 2610 : while (nrd < nr && ir[nrd] < nd)
- 559 1741 : ++nrd;
+ 557 870 : nrd = 0;
+ 558 2613 : while (nrd < nr && ir[nrd] < nd)
+ 559 1743 : ++nrd;
560 :
561 : /* all the remaining are parity */
- 562 869 : nrp = nr - nrd;
+ 562 870 : nrp = nr - nrd;
563 :
564 : /* enforce limit on number of failures */
- 565 869 : BUG_ON(nrd > nd);
- 566 869 : BUG_ON(nrp > np);
+ 565 870 : BUG_ON(nrd > nd);
+ 566 870 : BUG_ON(nrp > np);
567 :
568 : /* if failed data is present */
- 569 869 : if (nrd != 0) {
+ 569 870 : if (nrd != 0) {
570 : int ip[RAID_PARITY_MAX];
571 : int i, j, k;
572 :
573 : /* setup the vector of parities to use */
- 574 6034 : for (i = 0, j = 0, k = 0; i < np; ++i) {
- 575 5167 : if (j < nrp && ir[nrd + j] == nd + i) {
+ 574 6041 : for (i = 0, j = 0, k = 0; i < np; ++i) {
+ 575 5173 : if (j < nrp && ir[nrd + j] == nd + i) {
576 : /* this parity has to be recovered */
577 22 : ++j;
578 : } else {
579 : /* this parity is used for recovering */
- 580 5145 : ip[k] = i;
- 581 5145 : ++k;
+ 580 5151 : ip[k] = i;
+ 581 5151 : ++k;
582 : }
583 : }
584 :
585 : /* recover the nrd data blocks specified in ir[], */
586 : /* using the first nrd parity in ip[] for recovering */
- 587 867 : raid_rec_ptr[nrd - 1](nrd, ir, ip, nd, size, v);
+ 587 868 : raid_rec_ptr[nrd - 1](nrd, ir, ip, nd, size, v);
588 : }
589 :
590 : /* recompute all the parities up to the last bad one */
- 591 869 : if (nrp != 0)
+ 591 870 : if (nrp != 0)
592 12 : raid_gen(nd, ir[nr - 1] - nd + 1, size, v);
- 593 869 : }
+ 593 870 : }
594 :
- 595 210062 : void raid_data(int nr, int *id, int *ip, int nd, size_t size, void **v)
+ 595 210262 : void raid_data(int nr, int *id, int *ip, int nd, size_t size, void **v)
596 : {
597 : /* enforce limit on size */
- 598 210062 : BUG_ON(size % 64 != 0);
+ 598 210262 : BUG_ON(size % 64 != 0);
599 :
600 : /* enforce limit on number of failures */
- 601 210062 : BUG_ON(nr > nd);
- 602 210062 : BUG_ON(nr > RAID_PARITY_MAX);
+ 601 210262 : BUG_ON(nr > nd);
+ 602 210262 : BUG_ON(nr > RAID_PARITY_MAX);
603 :
604 : /* enforce order in index vector for data */
- 605 210062 : BUG_ON(nr >= 2 && id[0] >= id[1]);
- 606 210062 : BUG_ON(nr >= 3 && id[1] >= id[2]);
- 607 210062 : BUG_ON(nr >= 4 && id[2] >= id[3]);
- 608 210062 : BUG_ON(nr >= 5 && id[3] >= id[4]);
- 609 210062 : BUG_ON(nr >= 6 && id[4] >= id[5]);
+ 605 210262 : BUG_ON(nr >= 2 && id[0] >= id[1]);
+ 606 210262 : BUG_ON(nr >= 3 && id[1] >= id[2]);
+ 607 210262 : BUG_ON(nr >= 4 && id[2] >= id[3]);
+ 608 210262 : BUG_ON(nr >= 5 && id[3] >= id[4]);
+ 609 210262 : BUG_ON(nr >= 6 && id[4] >= id[5]);
610 :
611 : /* enforce limit on index vector for data */
- 612 210062 : BUG_ON(nr > 0 && id[nr-1] >= nd);
+ 612 210262 : BUG_ON(nr > 0 && id[nr-1] >= nd);
613 :
614 : /* enforce order in index vector for parity */
- 615 210062 : BUG_ON(nr >= 2 && ip[0] >= ip[1]);
- 616 210062 : BUG_ON(nr >= 3 && ip[1] >= ip[2]);
- 617 210062 : BUG_ON(nr >= 4 && ip[2] >= ip[3]);
- 618 210062 : BUG_ON(nr >= 5 && ip[3] >= ip[4]);
- 619 210062 : BUG_ON(nr >= 6 && ip[4] >= ip[5]);
+ 615 210262 : BUG_ON(nr >= 2 && ip[0] >= ip[1]);
+ 616 210262 : BUG_ON(nr >= 3 && ip[1] >= ip[2]);
+ 617 210262 : BUG_ON(nr >= 4 && ip[2] >= ip[3]);
+ 618 210262 : BUG_ON(nr >= 5 && ip[3] >= ip[4]);
+ 619 210262 : BUG_ON(nr >= 6 && ip[4] >= ip[5]);
620 :
621 : /* if failed data is present */
- 622 210062 : if (nr != 0)
- 623 210060 : raid_rec_ptr[nr - 1](nr, id, ip, nd, size, v);
- 624 210062 : }
+ 622 210262 : if (nr != 0)
+ 623 210260 : raid_rec_ptr[nr - 1](nr, id, ip, nd, size, v);
+ 624 210262 : }
625 :
diff --git a/cov/raid/tag.c.func-sort-c.html b/cov/raid/tag.c.func-sort-c.html
index 38a084fc..eff176fa 100644
--- a/cov/raid/tag.c.func-sort-c.html
+++ b/cov/raid/tag.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/raid/tag.c.func.html b/cov/raid/tag.c.func.html
index f4ede672..a883bca6 100644
--- a/cov/raid/tag.c.func.html
+++ b/cov/raid/tag.c.func.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/raid/tag.c.gcov.html b/cov/raid/tag.c.gcov.html
index 39e7393b..c47a4afb 100644
--- a/cov/raid/tag.c.gcov.html
+++ b/cov/raid/tag.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/raid/test.c.func-sort-c.html b/cov/raid/test.c.func-sort-c.html
index 178ea7a3..baa87ae2 100644
--- a/cov/raid/test.c.func-sort-c.html
+++ b/cov/raid/test.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/raid/test.c.func.html b/cov/raid/test.c.func.html
index 88f79097..ef8aecb1 100644
--- a/cov/raid/test.c.func.html
+++ b/cov/raid/test.c.func.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/raid/test.c.gcov.html b/cov/raid/test.c.gcov.html
index 6624295e..73fa39b5 100644
--- a/cov/raid/test.c.gcov.html
+++ b/cov/raid/test.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/raid/x86.c.func-sort-c.html b/cov/raid/x86.c.func-sort-c.html
index 7367a480..5c456d2e 100644
--- a/cov/raid/x86.c.func-sort-c.html
+++ b/cov/raid/x86.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -73,7 +73,7 @@
| raid_gen3_ssse3 |
- 11 |
+ 9 |
| raid_gen2_sse2 |
@@ -81,7 +81,7 @@
| raid_gen1_avx2 |
- 97 |
+ 96 |
| raid_rec1_avx2 |
@@ -89,7 +89,7 @@
| raid_gen2_avx2 |
- 510 |
+ 509 |
| raid_gen3_avx2ext |
@@ -129,7 +129,7 @@
| raid_rec2_ssse3 |
- 44102 |
+ 44098 |
| raid_recX_ssse3 |
@@ -137,19 +137,19 @@
| raid_rec1_ssse3 |
- 106666 |
+ 106871 |
| raid_gen2_sse2ext |
- 268615 |
+ 268631 |
| raid_gen1_sse2 |
- 284018 |
+ 284150 |
| raid_gen6_ssse3ext |
- 528480 |
+ 528427 |
diff --git a/cov/raid/x86.c.func.html b/cov/raid/x86.c.func.html
index a3f5c14e..1e887468 100644
--- a/cov/raid/x86.c.func.html
+++ b/cov/raid/x86.c.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,15 +61,15 @@
| raid_gen1_avx2 |
- 97 |
+ 96 |
| raid_gen1_sse2 |
- 284018 |
+ 284150 |
| raid_gen2_avx2 |
- 510 |
+ 509 |
| raid_gen2_sse2 |
@@ -77,7 +77,7 @@
| raid_gen2_sse2ext |
- 268615 |
+ 268631 |
| raid_gen3_avx2ext |
@@ -85,7 +85,7 @@
| raid_gen3_ssse3 |
- 11 |
+ 9 |
| raid_gen3_ssse3ext |
@@ -125,7 +125,7 @@
| raid_gen6_ssse3ext |
- 528480 |
+ 528427 |
| raid_rec1_avx2 |
@@ -133,7 +133,7 @@
| raid_rec1_ssse3 |
- 106666 |
+ 106871 |
| raid_rec2_avx2 |
@@ -141,7 +141,7 @@
| raid_rec2_ssse3 |
- 44102 |
+ 44098 |
| raid_recX_avx2 |
diff --git a/cov/raid/x86.c.gcov.html b/cov/raid/x86.c.gcov.html
index 22212d83..4311eff2 100644
--- a/cov/raid/x86.c.gcov.html
+++ b/cov/raid/x86.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -95,37 +95,37 @@
33 : * cache block, and processing 128 bytes doesn't increase performance, and in
34 : * some cases it even decreases it.
35 : */
- 36 284018 : void raid_gen1_sse2(int nd, size_t size, void **vv)
+ 36 284150 : void raid_gen1_sse2(int nd, size_t size, void **vv)
37 : {
- 38 284018 : uint8_t **v = (uint8_t **)vv;
+ 38 284150 : uint8_t **v = (uint8_t **)vv;
39 : uint8_t *p;
40 : int d, l;
41 : size_t i;
42 :
- 43 284018 : l = nd - 1;
- 44 284018 : p = v[nd];
+ 43 284150 : l = nd - 1;
+ 44 284150 : p = v[nd];
45 :
46 : raid_sse_begin();
47 :
- 48 5032270 : for (i = 0; i < size; i += 64) {
- 49 4748252 : asm volatile ("movdqa %0,%%xmm0" : : "m" (v[l][i]));
- 50 4748252 : asm volatile ("movdqa %0,%%xmm1" : : "m" (v[l][i + 16]));
- 51 4748252 : asm volatile ("movdqa %0,%%xmm2" : : "m" (v[l][i + 32]));
- 52 4748252 : asm volatile ("movdqa %0,%%xmm3" : : "m" (v[l][i + 48]));
- 53 28899300 : for (d = l - 1; d >= 0; --d) {
- 54 24151048 : asm volatile ("pxor %0,%%xmm0" : : "m" (v[d][i]));
- 55 24151048 : asm volatile ("pxor %0,%%xmm1" : : "m" (v[d][i + 16]));
- 56 24151048 : asm volatile ("pxor %0,%%xmm2" : : "m" (v[d][i + 32]));
- 57 24151048 : asm volatile ("pxor %0,%%xmm3" : : "m" (v[d][i + 48]));
+ 48 5026354 : for (i = 0; i < size; i += 64) {
+ 49 4742204 : asm volatile ("movdqa %0,%%xmm0" : : "m" (v[l][i]));
+ 50 4742204 : asm volatile ("movdqa %0,%%xmm1" : : "m" (v[l][i + 16]));
+ 51 4742204 : asm volatile ("movdqa %0,%%xmm2" : : "m" (v[l][i + 32]));
+ 52 4742204 : asm volatile ("movdqa %0,%%xmm3" : : "m" (v[l][i + 48]));
+ 53 28846628 : for (d = l - 1; d >= 0; --d) {
+ 54 24104424 : asm volatile ("pxor %0,%%xmm0" : : "m" (v[d][i]));
+ 55 24104424 : asm volatile ("pxor %0,%%xmm1" : : "m" (v[d][i + 16]));
+ 56 24104424 : asm volatile ("pxor %0,%%xmm2" : : "m" (v[d][i + 32]));
+ 57 24104424 : asm volatile ("pxor %0,%%xmm3" : : "m" (v[d][i + 48]));
58 : }
- 59 4748252 : asm volatile ("movntdq %%xmm0,%0" : "=m" (p[i]));
- 60 4748252 : asm volatile ("movntdq %%xmm1,%0" : "=m" (p[i + 16]));
- 61 4748252 : asm volatile ("movntdq %%xmm2,%0" : "=m" (p[i + 32]));
- 62 4748252 : asm volatile ("movntdq %%xmm3,%0" : "=m" (p[i + 48]));
+ 59 4742204 : asm volatile ("movntdq %%xmm0,%0" : "=m" (p[i]));
+ 60 4742204 : asm volatile ("movntdq %%xmm1,%0" : "=m" (p[i + 16]));
+ 61 4742204 : asm volatile ("movntdq %%xmm2,%0" : "=m" (p[i + 32]));
+ 62 4742204 : asm volatile ("movntdq %%xmm3,%0" : "=m" (p[i + 48]));
63 : }
64 :
65 : raid_sse_end();
- 66 284018 : }
+ 66 284150 : }
67 : #endif
68 :
69 : #if defined(CONFIG_X86) && defined(CONFIG_AVX2)
@@ -136,31 +136,31 @@
74 : * cache block, and processing 128 bytes doesn't increase performance, and in
75 : * some cases it even decreases it.
76 : */
- 77 97 : void raid_gen1_avx2(int nd, size_t size, void **vv)
+ 77 96 : void raid_gen1_avx2(int nd, size_t size, void **vv)
78 : {
- 79 97 : uint8_t **v = (uint8_t **)vv;
+ 79 96 : uint8_t **v = (uint8_t **)vv;
80 : uint8_t *p;
81 : int d, l;
82 : size_t i;
83 :
- 84 97 : l = nd - 1;
- 85 97 : p = v[nd];
+ 84 96 : l = nd - 1;
+ 85 96 : p = v[nd];
86 :
87 : raid_avx_begin();
88 :
- 89 50189 : for (i = 0; i < size; i += 64) {
- 90 50092 : asm volatile ("vmovdqa %0,%%ymm0" : : "m" (v[l][i]));
- 91 50092 : asm volatile ("vmovdqa %0,%%ymm1" : : "m" (v[l][i + 32]));
- 92 407172 : for (d = l - 1; d >= 0; --d) {
- 93 357080 : asm volatile ("vpxor %0,%%ymm0,%%ymm0" : : "m" (v[d][i]));
- 94 357080 : asm volatile ("vpxor %0,%%ymm1,%%ymm1" : : "m" (v[d][i + 32]));
+ 89 46092 : for (i = 0; i < size; i += 64) {
+ 90 45996 : asm volatile ("vmovdqa %0,%%ymm0" : : "m" (v[l][i]));
+ 91 45996 : asm volatile ("vmovdqa %0,%%ymm1" : : "m" (v[l][i + 32]));
+ 92 374404 : for (d = l - 1; d >= 0; --d) {
+ 93 328408 : asm volatile ("vpxor %0,%%ymm0,%%ymm0" : : "m" (v[d][i]));
+ 94 328408 : asm volatile ("vpxor %0,%%ymm1,%%ymm1" : : "m" (v[d][i + 32]));
95 : }
- 96 50092 : asm volatile ("vmovntdq %%ymm0,%0" : "=m" (p[i]));
- 97 50092 : asm volatile ("vmovntdq %%ymm1,%0" : "=m" (p[i + 32]));
+ 96 45996 : asm volatile ("vmovntdq %%ymm0,%0" : "=m" (p[i]));
+ 97 45996 : asm volatile ("vmovntdq %%ymm1,%0" : "=m" (p[i + 32]));
98 : }
99 :
100 : raid_avx_end();
- 101 97 : }
+ 101 96 : }
102 : #endif
103 :
104 : #if defined(CONFIG_X86) && defined(CONFIG_SSE2)
@@ -237,53 +237,53 @@
175 : /*
176 : * GEN2 (RAID6 with powers of 2) AVX2 implementation
177 : */
- 178 510 : void raid_gen2_avx2(int nd, size_t size, void **vv)
+ 178 509 : void raid_gen2_avx2(int nd, size_t size, void **vv)
179 : {
- 180 510 : uint8_t **v = (uint8_t **)vv;
+ 180 509 : uint8_t **v = (uint8_t **)vv;
181 : uint8_t *p;
182 : uint8_t *q;
183 : int d, l;
184 : size_t i;
185 :
- 186 510 : l = nd - 1;
- 187 510 : p = v[nd];
- 188 510 : q = v[nd + 1];
+ 186 509 : l = nd - 1;
+ 187 509 : p = v[nd];
+ 188 509 : q = v[nd + 1];
189 :
190 : raid_avx_begin();
191 :
- 192 510 : asm volatile ("vbroadcasti128 %0, %%ymm7" : : "m" (gfconst16.poly[0]));
- 193 510 : asm volatile ("vpxor %ymm6,%ymm6,%ymm6");
+ 192 509 : asm volatile ("vbroadcasti128 %0, %%ymm7" : : "m" (gfconst16.poly[0]));
+ 193 509 : asm volatile ("vpxor %ymm6,%ymm6,%ymm6");
194 :
- 195 113754 : for (i = 0; i < size; i += 64) {
- 196 113244 : asm volatile ("vmovdqa %0,%%ymm0" : : "m" (v[l][i]));
- 197 113244 : asm volatile ("vmovdqa %0,%%ymm1" : : "m" (v[l][i + 32]));
- 198 113244 : asm volatile ("vmovdqa %ymm0,%ymm2");
- 199 113244 : asm volatile ("vmovdqa %ymm1,%ymm3");
- 200 919748 : for (d = l - 1; d >= 0; --d) {
- 201 806504 : asm volatile ("vpcmpgtb %ymm2,%ymm6,%ymm4");
- 202 806504 : asm volatile ("vpcmpgtb %ymm3,%ymm6,%ymm5");
- 203 806504 : asm volatile ("vpaddb %ymm2,%ymm2,%ymm2");
- 204 806504 : asm volatile ("vpaddb %ymm3,%ymm3,%ymm3");
- 205 806504 : asm volatile ("vpand %ymm7,%ymm4,%ymm4");
- 206 806504 : asm volatile ("vpand %ymm7,%ymm5,%ymm5");
- 207 806504 : asm volatile ("vpxor %ymm4,%ymm2,%ymm2");
- 208 806504 : asm volatile ("vpxor %ymm5,%ymm3,%ymm3");
+ 195 109657 : for (i = 0; i < size; i += 64) {
+ 196 109148 : asm volatile ("vmovdqa %0,%%ymm0" : : "m" (v[l][i]));
+ 197 109148 : asm volatile ("vmovdqa %0,%%ymm1" : : "m" (v[l][i + 32]));
+ 198 109148 : asm volatile ("vmovdqa %ymm0,%ymm2");
+ 199 109148 : asm volatile ("vmovdqa %ymm1,%ymm3");
+ 200 886980 : for (d = l - 1; d >= 0; --d) {
+ 201 777832 : asm volatile ("vpcmpgtb %ymm2,%ymm6,%ymm4");
+ 202 777832 : asm volatile ("vpcmpgtb %ymm3,%ymm6,%ymm5");
+ 203 777832 : asm volatile ("vpaddb %ymm2,%ymm2,%ymm2");
+ 204 777832 : asm volatile ("vpaddb %ymm3,%ymm3,%ymm3");
+ 205 777832 : asm volatile ("vpand %ymm7,%ymm4,%ymm4");
+ 206 777832 : asm volatile ("vpand %ymm7,%ymm5,%ymm5");
+ 207 777832 : asm volatile ("vpxor %ymm4,%ymm2,%ymm2");
+ 208 777832 : asm volatile ("vpxor %ymm5,%ymm3,%ymm3");
209 :
- 210 806504 : asm volatile ("vmovdqa %0,%%ymm4" : : "m" (v[d][i]));
- 211 806504 : asm volatile ("vmovdqa %0,%%ymm5" : : "m" (v[d][i + 32]));
- 212 806504 : asm volatile ("vpxor %ymm4,%ymm0,%ymm0");
- 213 806504 : asm volatile ("vpxor %ymm5,%ymm1,%ymm1");
- 214 806504 : asm volatile ("vpxor %ymm4,%ymm2,%ymm2");
- 215 806504 : asm volatile ("vpxor %ymm5,%ymm3,%ymm3");
+ 210 777832 : asm volatile ("vmovdqa %0,%%ymm4" : : "m" (v[d][i]));
+ 211 777832 : asm volatile ("vmovdqa %0,%%ymm5" : : "m" (v[d][i + 32]));
+ 212 777832 : asm volatile ("vpxor %ymm4,%ymm0,%ymm0");
+ 213 777832 : asm volatile ("vpxor %ymm5,%ymm1,%ymm1");
+ 214 777832 : asm volatile ("vpxor %ymm4,%ymm2,%ymm2");
+ 215 777832 : asm volatile ("vpxor %ymm5,%ymm3,%ymm3");
216 : }
- 217 113244 : asm volatile ("vmovntdq %%ymm0,%0" : "=m" (p[i]));
- 218 113244 : asm volatile ("vmovntdq %%ymm1,%0" : "=m" (p[i + 32]));
- 219 113244 : asm volatile ("vmovntdq %%ymm2,%0" : "=m" (q[i]));
- 220 113244 : asm volatile ("vmovntdq %%ymm3,%0" : "=m" (q[i + 32]));
+ 217 109148 : asm volatile ("vmovntdq %%ymm0,%0" : "=m" (p[i]));
+ 218 109148 : asm volatile ("vmovntdq %%ymm1,%0" : "=m" (p[i + 32]));
+ 219 109148 : asm volatile ("vmovntdq %%ymm2,%0" : "=m" (q[i]));
+ 220 109148 : asm volatile ("vmovntdq %%ymm3,%0" : "=m" (q[i + 32]));
221 : }
222 :
223 : raid_avx_end();
- 224 510 : }
+ 224 509 : }
225 : #endif
226 :
227 : #if defined(CONFIG_X86_64) && defined(CONFIG_SSE2)
@@ -292,100 +292,100 @@
230 : *
231 : * Note that it uses 16 registers, meaning that x64 is required.
232 : */
- 233 268615 : void raid_gen2_sse2ext(int nd, size_t size, void **vv)
+ 233 268631 : void raid_gen2_sse2ext(int nd, size_t size, void **vv)
234 : {
- 235 268615 : uint8_t **v = (uint8_t **)vv;
+ 235 268631 : uint8_t **v = (uint8_t **)vv;
236 : uint8_t *p;
237 : uint8_t *q;
238 : int d, l;
239 : size_t i;
240 :
- 241 268615 : l = nd - 1;
- 242 268615 : p = v[nd];
- 243 268615 : q = v[nd + 1];
+ 241 268631 : l = nd - 1;
+ 242 268631 : p = v[nd];
+ 243 268631 : q = v[nd + 1];
244 :
245 : raid_sse_begin();
246 :
- 247 268615 : asm volatile ("movdqa %0,%%xmm15" : : "m" (gfconst16.poly[0]));
+ 247 268631 : asm volatile ("movdqa %0,%%xmm15" : : "m" (gfconst16.poly[0]));
248 :
- 249 4794899 : for (i = 0; i < size; i += 64) {
- 250 4526284 : asm volatile ("movdqa %0,%%xmm0" : : "m" (v[l][i]));
- 251 4526284 : asm volatile ("movdqa %0,%%xmm1" : : "m" (v[l][i + 16]));
- 252 4526284 : asm volatile ("movdqa %0,%%xmm2" : : "m" (v[l][i + 32]));
- 253 4526284 : asm volatile ("movdqa %0,%%xmm3" : : "m" (v[l][i + 48]));
- 254 4526284 : asm volatile ("movdqa %xmm0,%xmm4");
- 255 4526284 : asm volatile ("movdqa %xmm1,%xmm5");
- 256 4526284 : asm volatile ("movdqa %xmm2,%xmm6");
- 257 4526284 : asm volatile ("movdqa %xmm3,%xmm7");
- 258 27616644 : for (d = l - 1; d >= 0; --d) {
- 259 23090360 : asm volatile ("pxor %xmm8,%xmm8");
- 260 23090360 : asm volatile ("pxor %xmm9,%xmm9");
- 261 23090360 : asm volatile ("pxor %xmm10,%xmm10");
- 262 23090360 : asm volatile ("pxor %xmm11,%xmm11");
- 263 23090360 : asm volatile ("pcmpgtb %xmm4,%xmm8");
- 264 23090360 : asm volatile ("pcmpgtb %xmm5,%xmm9");
- 265 23090360 : asm volatile ("pcmpgtb %xmm6,%xmm10");
- 266 23090360 : asm volatile ("pcmpgtb %xmm7,%xmm11");
- 267 23090360 : asm volatile ("paddb %xmm4,%xmm4");
- 268 23090360 : asm volatile ("paddb %xmm5,%xmm5");
- 269 23090360 : asm volatile ("paddb %xmm6,%xmm6");
- 270 23090360 : asm volatile ("paddb %xmm7,%xmm7");
- 271 23090360 : asm volatile ("pand %xmm15,%xmm8");
- 272 23090360 : asm volatile ("pand %xmm15,%xmm9");
- 273 23090360 : asm volatile ("pand %xmm15,%xmm10");
- 274 23090360 : asm volatile ("pand %xmm15,%xmm11");
- 275 23090360 : asm volatile ("pxor %xmm8,%xmm4");
- 276 23090360 : asm volatile ("pxor %xmm9,%xmm5");
- 277 23090360 : asm volatile ("pxor %xmm10,%xmm6");
- 278 23090360 : asm volatile ("pxor %xmm11,%xmm7");
+ 249 4795171 : for (i = 0; i < size; i += 64) {
+ 250 4526540 : asm volatile ("movdqa %0,%%xmm0" : : "m" (v[l][i]));
+ 251 4526540 : asm volatile ("movdqa %0,%%xmm1" : : "m" (v[l][i + 16]));
+ 252 4526540 : asm volatile ("movdqa %0,%%xmm2" : : "m" (v[l][i + 32]));
+ 253 4526540 : asm volatile ("movdqa %0,%%xmm3" : : "m" (v[l][i + 48]));
+ 254 4526540 : asm volatile ("movdqa %xmm0,%xmm4");
+ 255 4526540 : asm volatile ("movdqa %xmm1,%xmm5");
+ 256 4526540 : asm volatile ("movdqa %xmm2,%xmm6");
+ 257 4526540 : asm volatile ("movdqa %xmm3,%xmm7");
+ 258 27618180 : for (d = l - 1; d >= 0; --d) {
+ 259 23091640 : asm volatile ("pxor %xmm8,%xmm8");
+ 260 23091640 : asm volatile ("pxor %xmm9,%xmm9");
+ 261 23091640 : asm volatile ("pxor %xmm10,%xmm10");
+ 262 23091640 : asm volatile ("pxor %xmm11,%xmm11");
+ 263 23091640 : asm volatile ("pcmpgtb %xmm4,%xmm8");
+ 264 23091640 : asm volatile ("pcmpgtb %xmm5,%xmm9");
+ 265 23091640 : asm volatile ("pcmpgtb %xmm6,%xmm10");
+ 266 23091640 : asm volatile ("pcmpgtb %xmm7,%xmm11");
+ 267 23091640 : asm volatile ("paddb %xmm4,%xmm4");
+ 268 23091640 : asm volatile ("paddb %xmm5,%xmm5");
+ 269 23091640 : asm volatile ("paddb %xmm6,%xmm6");
+ 270 23091640 : asm volatile ("paddb %xmm7,%xmm7");
+ 271 23091640 : asm volatile ("pand %xmm15,%xmm8");
+ 272 23091640 : asm volatile ("pand %xmm15,%xmm9");
+ 273 23091640 : asm volatile ("pand %xmm15,%xmm10");
+ 274 23091640 : asm volatile ("pand %xmm15,%xmm11");
+ 275 23091640 : asm volatile ("pxor %xmm8,%xmm4");
+ 276 23091640 : asm volatile ("pxor %xmm9,%xmm5");
+ 277 23091640 : asm volatile ("pxor %xmm10,%xmm6");
+ 278 23091640 : asm volatile ("pxor %xmm11,%xmm7");
279 :
- 280 23090360 : asm volatile ("movdqa %0,%%xmm8" : : "m" (v[d][i]));
- 281 23090360 : asm volatile ("movdqa %0,%%xmm9" : : "m" (v[d][i + 16]));
- 282 23090360 : asm volatile ("movdqa %0,%%xmm10" : : "m" (v[d][i + 32]));
- 283 23090360 : asm volatile ("movdqa %0,%%xmm11" : : "m" (v[d][i + 48]));
- 284 23090360 : asm volatile ("pxor %xmm8,%xmm0");
- 285 23090360 : asm volatile ("pxor %xmm9,%xmm1");
- 286 23090360 : asm volatile ("pxor %xmm10,%xmm2");
- 287 23090360 : asm volatile ("pxor %xmm11,%xmm3");
- 288 23090360 : asm volatile ("pxor %xmm8,%xmm4");
- 289 23090360 : asm volatile ("pxor %xmm9,%xmm5");
- 290 23090360 : asm volatile ("pxor %xmm10,%xmm6");
- 291 23090360 : asm volatile ("pxor %xmm11,%xmm7");
+ 280 23091640 : asm volatile ("movdqa %0,%%xmm8" : : "m" (v[d][i]));
+ 281 23091640 : asm volatile ("movdqa %0,%%xmm9" : : "m" (v[d][i + 16]));
+ 282 23091640 : asm volatile ("movdqa %0,%%xmm10" : : "m" (v[d][i + 32]));
+ 283 23091640 : asm volatile ("movdqa %0,%%xmm11" : : "m" (v[d][i + 48]));
+ 284 23091640 : asm volatile ("pxor %xmm8,%xmm0");
+ 285 23091640 : asm volatile ("pxor %xmm9,%xmm1");
+ 286 23091640 : asm volatile ("pxor %xmm10,%xmm2");
+ 287 23091640 : asm volatile ("pxor %xmm11,%xmm3");
+ 288 23091640 : asm volatile ("pxor %xmm8,%xmm4");
+ 289 23091640 : asm volatile ("pxor %xmm9,%xmm5");
+ 290 23091640 : asm volatile ("pxor %xmm10,%xmm6");
+ 291 23091640 : asm volatile ("pxor %xmm11,%xmm7");
292 : }
- 293 4526284 : asm volatile ("movntdq %%xmm0,%0" : "=m" (p[i]));
- 294 4526284 : asm volatile ("movntdq %%xmm1,%0" : "=m" (p[i + 16]));
- 295 4526284 : asm volatile ("movntdq %%xmm2,%0" : "=m" (p[i + 32]));
- 296 4526284 : asm volatile ("movntdq %%xmm3,%0" : "=m" (p[i + 48]));
- 297 4526284 : asm volatile ("movntdq %%xmm4,%0" : "=m" (q[i]));
- 298 4526284 : asm volatile ("movntdq %%xmm5,%0" : "=m" (q[i + 16]));
- 299 4526284 : asm volatile ("movntdq %%xmm6,%0" : "=m" (q[i + 32]));
- 300 4526284 : asm volatile ("movntdq %%xmm7,%0" : "=m" (q[i + 48]));
+ 293 4526540 : asm volatile ("movntdq %%xmm0,%0" : "=m" (p[i]));
+ 294 4526540 : asm volatile ("movntdq %%xmm1,%0" : "=m" (p[i + 16]));
+ 295 4526540 : asm volatile ("movntdq %%xmm2,%0" : "=m" (p[i + 32]));
+ 296 4526540 : asm volatile ("movntdq %%xmm3,%0" : "=m" (p[i + 48]));
+ 297 4526540 : asm volatile ("movntdq %%xmm4,%0" : "=m" (q[i]));
+ 298 4526540 : asm volatile ("movntdq %%xmm5,%0" : "=m" (q[i + 16]));
+ 299 4526540 : asm volatile ("movntdq %%xmm6,%0" : "=m" (q[i + 32]));
+ 300 4526540 : asm volatile ("movntdq %%xmm7,%0" : "=m" (q[i + 48]));
301 : }
302 :
303 : raid_sse_end();
- 304 268615 : }
+ 304 268631 : }
305 : #endif
306 :
307 : #if defined(CONFIG_X86) && defined(CONFIG_SSSE3)
308 : /*
309 : * GEN3 (triple parity with Cauchy matrix) SSSE3 implementation
310 : */
- 311 11 : void raid_gen3_ssse3(int nd, size_t size, void **vv)
+ 311 9 : void raid_gen3_ssse3(int nd, size_t size, void **vv)
312 : {
- 313 11 : uint8_t **v = (uint8_t **)vv;
+ 313 9 : 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 11 : l = nd - 1;
- 321 11 : p = v[nd];
- 322 11 : q = v[nd + 1];
- 323 11 : r = v[nd + 2];
+ 320 9 : l = nd - 1;
+ 321 9 : p = v[nd];
+ 322 9 : q = v[nd + 1];
+ 323 9 : r = v[nd + 2];
324 :
325 : /* special case with only one data disk */
- 326 11 : if (l == 0) {
+ 326 9 : if (l == 0) {
327 4 : for (i = 0; i < 3; ++i)
328 3 : memcpy(v[1 + i], v[0], size);
329 1 : return;
@@ -394,69 +394,69 @@
332 : raid_sse_begin();
333 :
334 : /* generic case with at least two data disks */
- 335 10 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfconst16.poly[0]));
- 336 10 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0]));
+ 335 8 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfconst16.poly[0]));
+ 336 8 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0]));
337 :
- 338 147482 : for (i = 0; i < size; i += 16) {
+ 338 114712 : for (i = 0; i < size; i += 16) {
339 : /* last disk without the by two multiplication */
- 340 147472 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[l][i]));
+ 340 114704 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[l][i]));
341 :
- 342 147472 : asm volatile ("movdqa %xmm4,%xmm0");
- 343 147472 : asm volatile ("movdqa %xmm4,%xmm1");
+ 342 114704 : asm volatile ("movdqa %xmm4,%xmm0");
+ 343 114704 : asm volatile ("movdqa %xmm4,%xmm1");
344 :
- 345 147472 : asm volatile ("movdqa %xmm4,%xmm5");
- 346 147472 : asm volatile ("psrlw $4,%xmm5");
- 347 147472 : asm volatile ("pand %xmm7,%xmm4");
- 348 147472 : asm volatile ("pand %xmm7,%xmm5");
+ 345 114704 : asm volatile ("movdqa %xmm4,%xmm5");
+ 346 114704 : asm volatile ("psrlw $4,%xmm5");
+ 347 114704 : asm volatile ("pand %xmm7,%xmm4");
+ 348 114704 : asm volatile ("pand %xmm7,%xmm5");
349 :
- 350 147472 : asm volatile ("movdqa %0,%%xmm2" : : "m" (gfgenpshufb[l][0][0][0]));
- 351 147472 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[l][0][1][0]));
- 352 147472 : asm volatile ("pshufb %xmm4,%xmm2");
- 353 147472 : asm volatile ("pshufb %xmm5,%xmm6");
- 354 147472 : asm volatile ("pxor %xmm6,%xmm2");
+ 350 114704 : asm volatile ("movdqa %0,%%xmm2" : : "m" (gfgenpshufb[l][0][0][0]));
+ 351 114704 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[l][0][1][0]));
+ 352 114704 : asm volatile ("pshufb %xmm4,%xmm2");
+ 353 114704 : asm volatile ("pshufb %xmm5,%xmm6");
+ 354 114704 : asm volatile ("pxor %xmm6,%xmm2");
355 :
356 : /* intermediate disks */
- 357 1032688 : for (d = l - 1; d > 0; --d) {
- 358 885216 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[d][i]));
+ 357 803312 : for (d = l - 1; d > 0; --d) {
+ 358 688608 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[d][i]));
359 :
- 360 885216 : asm volatile ("pxor %xmm5,%xmm5");
- 361 885216 : asm volatile ("pcmpgtb %xmm1,%xmm5");
- 362 885216 : asm volatile ("paddb %xmm1,%xmm1");
- 363 885216 : asm volatile ("pand %xmm3,%xmm5");
- 364 885216 : asm volatile ("pxor %xmm5,%xmm1");
+ 360 688608 : asm volatile ("pxor %xmm5,%xmm5");
+ 361 688608 : asm volatile ("pcmpgtb %xmm1,%xmm5");
+ 362 688608 : asm volatile ("paddb %xmm1,%xmm1");
+ 363 688608 : asm volatile ("pand %xmm3,%xmm5");
+ 364 688608 : asm volatile ("pxor %xmm5,%xmm1");
365 :
- 366 885216 : asm volatile ("pxor %xmm4,%xmm0");
- 367 885216 : asm volatile ("pxor %xmm4,%xmm1");
+ 366 688608 : asm volatile ("pxor %xmm4,%xmm0");
+ 367 688608 : asm volatile ("pxor %xmm4,%xmm1");
368 :
- 369 885216 : asm volatile ("movdqa %xmm4,%xmm5");
- 370 885216 : asm volatile ("psrlw $4,%xmm5");
- 371 885216 : asm volatile ("pand %xmm7,%xmm4");
- 372 885216 : asm volatile ("pand %xmm7,%xmm5");
+ 369 688608 : asm volatile ("movdqa %xmm4,%xmm5");
+ 370 688608 : asm volatile ("psrlw $4,%xmm5");
+ 371 688608 : asm volatile ("pand %xmm7,%xmm4");
+ 372 688608 : asm volatile ("pand %xmm7,%xmm5");
373 :
- 374 885216 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][0][0][0]));
- 375 885216 : asm volatile ("pshufb %xmm4,%xmm6");
- 376 885216 : asm volatile ("pxor %xmm6,%xmm2");
- 377 885216 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][0][1][0]));
- 378 885216 : asm volatile ("pshufb %xmm5,%xmm6");
- 379 885216 : asm volatile ("pxor %xmm6,%xmm2");
+ 374 688608 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][0][0][0]));
+ 375 688608 : asm volatile ("pshufb %xmm4,%xmm6");
+ 376 688608 : asm volatile ("pxor %xmm6,%xmm2");
+ 377 688608 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][0][1][0]));
+ 378 688608 : asm volatile ("pshufb %xmm5,%xmm6");
+ 379 688608 : asm volatile ("pxor %xmm6,%xmm2");
380 : }
381 :
382 : /* first disk with all coefficients at 1 */
- 383 147472 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[0][i]));
+ 383 114704 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[0][i]));
384 :
- 385 147472 : asm volatile ("pxor %xmm5,%xmm5");
- 386 147472 : asm volatile ("pcmpgtb %xmm1,%xmm5");
- 387 147472 : asm volatile ("paddb %xmm1,%xmm1");
- 388 147472 : asm volatile ("pand %xmm3,%xmm5");
- 389 147472 : asm volatile ("pxor %xmm5,%xmm1");
+ 385 114704 : asm volatile ("pxor %xmm5,%xmm5");
+ 386 114704 : asm volatile ("pcmpgtb %xmm1,%xmm5");
+ 387 114704 : asm volatile ("paddb %xmm1,%xmm1");
+ 388 114704 : asm volatile ("pand %xmm3,%xmm5");
+ 389 114704 : asm volatile ("pxor %xmm5,%xmm1");
390 :
- 391 147472 : asm volatile ("pxor %xmm4,%xmm0");
- 392 147472 : asm volatile ("pxor %xmm4,%xmm1");
- 393 147472 : asm volatile ("pxor %xmm4,%xmm2");
+ 391 114704 : asm volatile ("pxor %xmm4,%xmm0");
+ 392 114704 : asm volatile ("pxor %xmm4,%xmm1");
+ 393 114704 : asm volatile ("pxor %xmm4,%xmm2");
394 :
- 395 147472 : asm volatile ("movntdq %%xmm0,%0" : "=m" (p[i]));
- 396 147472 : asm volatile ("movntdq %%xmm1,%0" : "=m" (q[i]));
- 397 147472 : asm volatile ("movntdq %%xmm2,%0" : "=m" (r[i]));
+ 395 114704 : asm volatile ("movntdq %%xmm0,%0" : "=m" (p[i]));
+ 396 114704 : asm volatile ("movntdq %%xmm1,%0" : "=m" (q[i]));
+ 397 114704 : asm volatile ("movntdq %%xmm2,%0" : "=m" (r[i]));
398 : }
399 :
400 : raid_sse_end();
@@ -1751,9 +1751,9 @@
1689 : *
1690 : * Note that it uses 16 registers, meaning that x64 is required.
1691 : */
- 1692 528480 : void raid_gen6_ssse3ext(int nd, size_t size, void **vv)
+ 1692 528427 : void raid_gen6_ssse3ext(int nd, size_t size, void **vv)
1693 : {
- 1694 528480 : uint8_t **v = (uint8_t **)vv;
+ 1694 528427 : uint8_t **v = (uint8_t **)vv;
1695 : uint8_t *p;
1696 : uint8_t *q;
1697 : uint8_t *r;
@@ -1763,16 +1763,16 @@
1701 : int d, l;
1702 : size_t i;
1703 :
- 1704 528480 : l = nd - 1;
- 1705 528480 : p = v[nd];
- 1706 528480 : q = v[nd + 1];
- 1707 528480 : r = v[nd + 2];
- 1708 528480 : s = v[nd + 3];
- 1709 528480 : t = v[nd + 4];
- 1710 528480 : u = v[nd + 5];
+ 1704 528427 : l = nd - 1;
+ 1705 528427 : p = v[nd];
+ 1706 528427 : q = v[nd + 1];
+ 1707 528427 : r = v[nd + 2];
+ 1708 528427 : s = v[nd + 3];
+ 1709 528427 : t = v[nd + 4];
+ 1710 528427 : u = v[nd + 5];
1711 :
1712 : /* special case with only one data disk */
- 1713 528480 : if (l == 0) {
+ 1713 528427 : if (l == 0) {
1714 7 : for (i = 0; i < 6; ++i)
1715 6 : memcpy(v[1 + i], v[0], size);
1716 1 : return;
@@ -1781,114 +1781,114 @@
1719 : raid_sse_begin();
1720 :
1721 : /* generic case with at least two data disks */
- 1722 528479 : asm volatile ("movdqa %0,%%xmm14" : : "m" (gfconst16.poly[0]));
- 1723 528479 : asm volatile ("movdqa %0,%%xmm15" : : "m" (gfconst16.low4[0]));
+ 1722 528426 : asm volatile ("movdqa %0,%%xmm14" : : "m" (gfconst16.poly[0]));
+ 1723 528426 : asm volatile ("movdqa %0,%%xmm15" : : "m" (gfconst16.low4[0]));
1724 :
- 1725 34938607 : for (i = 0; i < size; i += 16) {
+ 1725 34918842 : for (i = 0; i < size; i += 16) {
1726 : /* last disk without the by two multiplication */
- 1727 34410128 : asm volatile ("movdqa %0,%%xmm10" : : "m" (v[l][i]));
+ 1727 34390416 : asm volatile ("movdqa %0,%%xmm10" : : "m" (v[l][i]));
1728 :
- 1729 34410128 : asm volatile ("movdqa %xmm10,%xmm0");
- 1730 34410128 : asm volatile ("movdqa %xmm10,%xmm1");
+ 1729 34390416 : asm volatile ("movdqa %xmm10,%xmm0");
+ 1730 34390416 : asm volatile ("movdqa %xmm10,%xmm1");
1731 :
- 1732 34410128 : asm volatile ("movdqa %xmm10,%xmm11");
- 1733 34410128 : asm volatile ("psrlw $4,%xmm11");
- 1734 34410128 : asm volatile ("pand %xmm15,%xmm10");
- 1735 34410128 : asm volatile ("pand %xmm15,%xmm11");
+ 1732 34390416 : asm volatile ("movdqa %xmm10,%xmm11");
+ 1733 34390416 : asm volatile ("psrlw $4,%xmm11");
+ 1734 34390416 : asm volatile ("pand %xmm15,%xmm10");
+ 1735 34390416 : asm volatile ("pand %xmm15,%xmm11");
1736 :
- 1737 34410128 : asm volatile ("movdqa %0,%%xmm2" : : "m" (gfgenpshufb[l][0][0][0]));
- 1738 34410128 : asm volatile ("movdqa %0,%%xmm13" : : "m" (gfgenpshufb[l][0][1][0]));
- 1739 34410128 : asm volatile ("pshufb %xmm10,%xmm2");
- 1740 34410128 : asm volatile ("pshufb %xmm11,%xmm13");
- 1741 34410128 : asm volatile ("pxor %xmm13,%xmm2");
+ 1737 34390416 : asm volatile ("movdqa %0,%%xmm2" : : "m" (gfgenpshufb[l][0][0][0]));
+ 1738 34390416 : asm volatile ("movdqa %0,%%xmm13" : : "m" (gfgenpshufb[l][0][1][0]));
+ 1739 34390416 : asm volatile ("pshufb %xmm10,%xmm2");
+ 1740 34390416 : asm volatile ("pshufb %xmm11,%xmm13");
+ 1741 34390416 : asm volatile ("pxor %xmm13,%xmm2");
1742 :
- 1743 34410128 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfgenpshufb[l][1][0][0]));
- 1744 34410128 : asm volatile ("movdqa %0,%%xmm13" : : "m" (gfgenpshufb[l][1][1][0]));
- 1745 34410128 : asm volatile ("pshufb %xmm10,%xmm3");
- 1746 34410128 : asm volatile ("pshufb %xmm11,%xmm13");
- 1747 34410128 : asm volatile ("pxor %xmm13,%xmm3");
+ 1743 34390416 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfgenpshufb[l][1][0][0]));
+ 1744 34390416 : asm volatile ("movdqa %0,%%xmm13" : : "m" (gfgenpshufb[l][1][1][0]));
+ 1745 34390416 : asm volatile ("pshufb %xmm10,%xmm3");
+ 1746 34390416 : asm volatile ("pshufb %xmm11,%xmm13");
+ 1747 34390416 : asm volatile ("pxor %xmm13,%xmm3");
1748 :
- 1749 34410128 : asm volatile ("movdqa %0,%%xmm4" : : "m" (gfgenpshufb[l][2][0][0]));
- 1750 34410128 : asm volatile ("movdqa %0,%%xmm13" : : "m" (gfgenpshufb[l][2][1][0]));
- 1751 34410128 : asm volatile ("pshufb %xmm10,%xmm4");
- 1752 34410128 : asm volatile ("pshufb %xmm11,%xmm13");
- 1753 34410128 : asm volatile ("pxor %xmm13,%xmm4");
+ 1749 34390416 : asm volatile ("movdqa %0,%%xmm4" : : "m" (gfgenpshufb[l][2][0][0]));
+ 1750 34390416 : asm volatile ("movdqa %0,%%xmm13" : : "m" (gfgenpshufb[l][2][1][0]));
+ 1751 34390416 : asm volatile ("pshufb %xmm10,%xmm4");
+ 1752 34390416 : asm volatile ("pshufb %xmm11,%xmm13");
+ 1753 34390416 : asm volatile ("pxor %xmm13,%xmm4");
1754 :
- 1755 34410128 : asm volatile ("movdqa %0,%%xmm5" : : "m" (gfgenpshufb[l][3][0][0]));
- 1756 34410128 : asm volatile ("movdqa %0,%%xmm13" : : "m" (gfgenpshufb[l][3][1][0]));
- 1757 34410128 : asm volatile ("pshufb %xmm10,%xmm5");
- 1758 34410128 : asm volatile ("pshufb %xmm11,%xmm13");
- 1759 34410128 : asm volatile ("pxor %xmm13,%xmm5");
+ 1755 34390416 : asm volatile ("movdqa %0,%%xmm5" : : "m" (gfgenpshufb[l][3][0][0]));
+ 1756 34390416 : asm volatile ("movdqa %0,%%xmm13" : : "m" (gfgenpshufb[l][3][1][0]));
+ 1757 34390416 : asm volatile ("pshufb %xmm10,%xmm5");
+ 1758 34390416 : asm volatile ("pshufb %xmm11,%xmm13");
+ 1759 34390416 : asm volatile ("pxor %xmm13,%xmm5");
1760 :
1761 : /* intermediate disks */
- 1762 173230704 : for (d = l - 1; d > 0; --d) {
- 1763 138820576 : asm volatile ("movdqa %0,%%xmm10" : : "m" (v[d][i]));
+ 1762 173099376 : for (d = l - 1; d > 0; --d) {
+ 1763 138708960 : asm volatile ("movdqa %0,%%xmm10" : : "m" (v[d][i]));
1764 :
- 1765 138820576 : asm volatile ("pxor %xmm11,%xmm11");
- 1766 138820576 : asm volatile ("pcmpgtb %xmm1,%xmm11");
- 1767 138820576 : asm volatile ("paddb %xmm1,%xmm1");
- 1768 138820576 : asm volatile ("pand %xmm14,%xmm11");
- 1769 138820576 : asm volatile ("pxor %xmm11,%xmm1");
+ 1765 138708960 : asm volatile ("pxor %xmm11,%xmm11");
+ 1766 138708960 : asm volatile ("pcmpgtb %xmm1,%xmm11");
+ 1767 138708960 : asm volatile ("paddb %xmm1,%xmm1");
+ 1768 138708960 : asm volatile ("pand %xmm14,%xmm11");
+ 1769 138708960 : asm volatile ("pxor %xmm11,%xmm1");
1770 :
- 1771 138820576 : asm volatile ("pxor %xmm10,%xmm0");
- 1772 138820576 : asm volatile ("pxor %xmm10,%xmm1");
+ 1771 138708960 : asm volatile ("pxor %xmm10,%xmm0");
+ 1772 138708960 : asm volatile ("pxor %xmm10,%xmm1");
1773 :
- 1774 138820576 : asm volatile ("movdqa %xmm10,%xmm11");
- 1775 138820576 : asm volatile ("psrlw $4,%xmm11");
- 1776 138820576 : asm volatile ("pand %xmm15,%xmm10");
- 1777 138820576 : asm volatile ("pand %xmm15,%xmm11");
+ 1774 138708960 : asm volatile ("movdqa %xmm10,%xmm11");
+ 1775 138708960 : asm volatile ("psrlw $4,%xmm11");
+ 1776 138708960 : asm volatile ("pand %xmm15,%xmm10");
+ 1777 138708960 : asm volatile ("pand %xmm15,%xmm11");
1778 :
- 1779 138820576 : asm volatile ("movdqa %0,%%xmm12" : : "m" (gfgenpshufb[d][0][0][0]));
- 1780 138820576 : asm volatile ("movdqa %0,%%xmm13" : : "m" (gfgenpshufb[d][0][1][0]));
- 1781 138820576 : asm volatile ("pshufb %xmm10,%xmm12");
- 1782 138820576 : asm volatile ("pshufb %xmm11,%xmm13");
- 1783 138820576 : asm volatile ("pxor %xmm12,%xmm2");
- 1784 138820576 : asm volatile ("pxor %xmm13,%xmm2");
+ 1779 138708960 : asm volatile ("movdqa %0,%%xmm12" : : "m" (gfgenpshufb[d][0][0][0]));
+ 1780 138708960 : asm volatile ("movdqa %0,%%xmm13" : : "m" (gfgenpshufb[d][0][1][0]));
+ 1781 138708960 : asm volatile ("pshufb %xmm10,%xmm12");
+ 1782 138708960 : asm volatile ("pshufb %xmm11,%xmm13");
+ 1783 138708960 : asm volatile ("pxor %xmm12,%xmm2");
+ 1784 138708960 : asm volatile ("pxor %xmm13,%xmm2");
1785 :
- 1786 138820576 : asm volatile ("movdqa %0,%%xmm12" : : "m" (gfgenpshufb[d][1][0][0]));
- 1787 138820576 : asm volatile ("movdqa %0,%%xmm13" : : "m" (gfgenpshufb[d][1][1][0]));
- 1788 138820576 : asm volatile ("pshufb %xmm10,%xmm12");
- 1789 138820576 : asm volatile ("pshufb %xmm11,%xmm13");
- 1790 138820576 : asm volatile ("pxor %xmm12,%xmm3");
- 1791 138820576 : asm volatile ("pxor %xmm13,%xmm3");
+ 1786 138708960 : asm volatile ("movdqa %0,%%xmm12" : : "m" (gfgenpshufb[d][1][0][0]));
+ 1787 138708960 : asm volatile ("movdqa %0,%%xmm13" : : "m" (gfgenpshufb[d][1][1][0]));
+ 1788 138708960 : asm volatile ("pshufb %xmm10,%xmm12");
+ 1789 138708960 : asm volatile ("pshufb %xmm11,%xmm13");
+ 1790 138708960 : asm volatile ("pxor %xmm12,%xmm3");
+ 1791 138708960 : asm volatile ("pxor %xmm13,%xmm3");
1792 :
- 1793 138820576 : asm volatile ("movdqa %0,%%xmm12" : : "m" (gfgenpshufb[d][2][0][0]));
- 1794 138820576 : asm volatile ("movdqa %0,%%xmm13" : : "m" (gfgenpshufb[d][2][1][0]));
- 1795 138820576 : asm volatile ("pshufb %xmm10,%xmm12");
- 1796 138820576 : asm volatile ("pshufb %xmm11,%xmm13");
- 1797 138820576 : asm volatile ("pxor %xmm12,%xmm4");
- 1798 138820576 : asm volatile ("pxor %xmm13,%xmm4");
+ 1793 138708960 : asm volatile ("movdqa %0,%%xmm12" : : "m" (gfgenpshufb[d][2][0][0]));
+ 1794 138708960 : asm volatile ("movdqa %0,%%xmm13" : : "m" (gfgenpshufb[d][2][1][0]));
+ 1795 138708960 : asm volatile ("pshufb %xmm10,%xmm12");
+ 1796 138708960 : asm volatile ("pshufb %xmm11,%xmm13");
+ 1797 138708960 : asm volatile ("pxor %xmm12,%xmm4");
+ 1798 138708960 : asm volatile ("pxor %xmm13,%xmm4");
1799 :
- 1800 138820576 : asm volatile ("movdqa %0,%%xmm12" : : "m" (gfgenpshufb[d][3][0][0]));
- 1801 138820576 : asm volatile ("movdqa %0,%%xmm13" : : "m" (gfgenpshufb[d][3][1][0]));
- 1802 138820576 : asm volatile ("pshufb %xmm10,%xmm12");
- 1803 138820576 : asm volatile ("pshufb %xmm11,%xmm13");
- 1804 138820576 : asm volatile ("pxor %xmm12,%xmm5");
- 1805 138820576 : asm volatile ("pxor %xmm13,%xmm5");
+ 1800 138708960 : asm volatile ("movdqa %0,%%xmm12" : : "m" (gfgenpshufb[d][3][0][0]));
+ 1801 138708960 : asm volatile ("movdqa %0,%%xmm13" : : "m" (gfgenpshufb[d][3][1][0]));
+ 1802 138708960 : asm volatile ("pshufb %xmm10,%xmm12");
+ 1803 138708960 : asm volatile ("pshufb %xmm11,%xmm13");
+ 1804 138708960 : asm volatile ("pxor %xmm12,%xmm5");
+ 1805 138708960 : asm volatile ("pxor %xmm13,%xmm5");
1806 : }
1807 :
1808 : /* first disk with all coefficients at 1 */
- 1809 34410128 : asm volatile ("movdqa %0,%%xmm10" : : "m" (v[0][i]));
+ 1809 34390416 : asm volatile ("movdqa %0,%%xmm10" : : "m" (v[0][i]));
1810 :
- 1811 34410128 : asm volatile ("pxor %xmm11,%xmm11");
- 1812 34410128 : asm volatile ("pcmpgtb %xmm1,%xmm11");
- 1813 34410128 : asm volatile ("paddb %xmm1,%xmm1");
- 1814 34410128 : asm volatile ("pand %xmm14,%xmm11");
- 1815 34410128 : asm volatile ("pxor %xmm11,%xmm1");
+ 1811 34390416 : asm volatile ("pxor %xmm11,%xmm11");
+ 1812 34390416 : asm volatile ("pcmpgtb %xmm1,%xmm11");
+ 1813 34390416 : asm volatile ("paddb %xmm1,%xmm1");
+ 1814 34390416 : asm volatile ("pand %xmm14,%xmm11");
+ 1815 34390416 : asm volatile ("pxor %xmm11,%xmm1");
1816 :
- 1817 34410128 : asm volatile ("pxor %xmm10,%xmm0");
- 1818 34410128 : asm volatile ("pxor %xmm10,%xmm1");
- 1819 34410128 : asm volatile ("pxor %xmm10,%xmm2");
- 1820 34410128 : asm volatile ("pxor %xmm10,%xmm3");
- 1821 34410128 : asm volatile ("pxor %xmm10,%xmm4");
- 1822 34410128 : asm volatile ("pxor %xmm10,%xmm5");
+ 1817 34390416 : asm volatile ("pxor %xmm10,%xmm0");
+ 1818 34390416 : asm volatile ("pxor %xmm10,%xmm1");
+ 1819 34390416 : asm volatile ("pxor %xmm10,%xmm2");
+ 1820 34390416 : asm volatile ("pxor %xmm10,%xmm3");
+ 1821 34390416 : asm volatile ("pxor %xmm10,%xmm4");
+ 1822 34390416 : asm volatile ("pxor %xmm10,%xmm5");
1823 :
- 1824 34410128 : asm volatile ("movntdq %%xmm0,%0" : "=m" (p[i]));
- 1825 34410128 : asm volatile ("movntdq %%xmm1,%0" : "=m" (q[i]));
- 1826 34410128 : asm volatile ("movntdq %%xmm2,%0" : "=m" (r[i]));
- 1827 34410128 : asm volatile ("movntdq %%xmm3,%0" : "=m" (s[i]));
- 1828 34410128 : asm volatile ("movntdq %%xmm4,%0" : "=m" (t[i]));
- 1829 34410128 : asm volatile ("movntdq %%xmm5,%0" : "=m" (u[i]));
+ 1824 34390416 : asm volatile ("movntdq %%xmm0,%0" : "=m" (p[i]));
+ 1825 34390416 : asm volatile ("movntdq %%xmm1,%0" : "=m" (q[i]));
+ 1826 34390416 : asm volatile ("movntdq %%xmm2,%0" : "=m" (r[i]));
+ 1827 34390416 : asm volatile ("movntdq %%xmm3,%0" : "=m" (s[i]));
+ 1828 34390416 : asm volatile ("movntdq %%xmm4,%0" : "=m" (t[i]));
+ 1829 34390416 : asm volatile ("movntdq %%xmm5,%0" : "=m" (u[i]));
1830 : }
1831 :
1832 : raid_sse_end();
@@ -2046,9 +2046,9 @@
1984 : /*
1985 : * RAID recovering for one disk SSSE3 implementation
1986 : */
- 1987 106666 : void raid_rec1_ssse3(int nr, int *id, int *ip, int nd, size_t size, void **vv)
+ 1987 106871 : void raid_rec1_ssse3(int nr, int *id, int *ip, int nd, size_t size, void **vv)
1988 : {
- 1989 106666 : uint8_t **v = (uint8_t **)vv;
+ 1989 106871 : 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 106666 : if (ip[0] == 0) {
- 2000 96819 : raid_rec1of1(id, nd, size, vv);
- 2001 96819 : return;
+ 1999 106871 : if (ip[0] == 0) {
+ 2000 97004 : raid_rec1of1(id, nd, size, vv);
+ 2001 97004 : return;
2002 : }
2003 :
2004 : /* setup the coefficients matrix */
- 2005 9847 : G = A(ip[0], id[0]);
+ 2005 9867 : G = A(ip[0], id[0]);
2006 :
2007 : /* invert it to solve the system of linear equations */
- 2008 9847 : V = inv(G);
+ 2008 9867 : V = inv(G);
2009 :
2010 : /* compute delta parity */
- 2011 9847 : raid_delta_gen(1, id, ip, nd, size, vv);
+ 2011 9867 : raid_delta_gen(1, id, ip, nd, size, vv);
2012 :
- 2013 9847 : p = v[nd + ip[0]];
- 2014 9847 : pa = v[id[0]];
+ 2013 9867 : p = v[nd + ip[0]];
+ 2014 9867 : pa = v[id[0]];
2015 :
2016 : raid_sse_begin();
2017 :
- 2018 9847 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0]));
- 2019 9847 : asm volatile ("movdqa %0,%%xmm4" : : "m" (gfmulpshufb[V][0][0]));
- 2020 9847 : asm volatile ("movdqa %0,%%xmm5" : : "m" (gfmulpshufb[V][1][0]));
+ 2018 9867 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0]));
+ 2019 9867 : asm volatile ("movdqa %0,%%xmm4" : : "m" (gfmulpshufb[V][0][0]));
+ 2020 9867 : asm volatile ("movdqa %0,%%xmm5" : : "m" (gfmulpshufb[V][1][0]));
2021 :
- 2022 1027703 : for (i = 0; i < size; i += 16) {
- 2023 1017856 : asm volatile ("movdqa %0,%%xmm0" : : "m" (p[i]));
- 2024 1017856 : asm volatile ("movdqa %0,%%xmm1" : : "m" (pa[i]));
- 2025 1017856 : asm volatile ("movdqa %xmm4,%xmm2");
- 2026 1017856 : asm volatile ("movdqa %xmm5,%xmm3");
- 2027 1017856 : asm volatile ("pxor %xmm0,%xmm1");
- 2028 1017856 : asm volatile ("movdqa %xmm1,%xmm0");
- 2029 1017856 : asm volatile ("psrlw $4,%xmm1");
- 2030 1017856 : asm volatile ("pand %xmm7,%xmm0");
- 2031 1017856 : asm volatile ("pand %xmm7,%xmm1");
- 2032 1017856 : asm volatile ("pshufb %xmm0,%xmm2");
- 2033 1017856 : asm volatile ("pshufb %xmm1,%xmm3");
- 2034 1017856 : asm volatile ("pxor %xmm3,%xmm2");
- 2035 1017856 : asm volatile ("movdqa %%xmm2,%0" : "=m" (pa[i]));
+ 2022 1029003 : for (i = 0; i < size; i += 16) {
+ 2023 1019136 : asm volatile ("movdqa %0,%%xmm0" : : "m" (p[i]));
+ 2024 1019136 : asm volatile ("movdqa %0,%%xmm1" : : "m" (pa[i]));
+ 2025 1019136 : asm volatile ("movdqa %xmm4,%xmm2");
+ 2026 1019136 : asm volatile ("movdqa %xmm5,%xmm3");
+ 2027 1019136 : asm volatile ("pxor %xmm0,%xmm1");
+ 2028 1019136 : asm volatile ("movdqa %xmm1,%xmm0");
+ 2029 1019136 : asm volatile ("psrlw $4,%xmm1");
+ 2030 1019136 : asm volatile ("pand %xmm7,%xmm0");
+ 2031 1019136 : asm volatile ("pand %xmm7,%xmm1");
+ 2032 1019136 : asm volatile ("pshufb %xmm0,%xmm2");
+ 2033 1019136 : asm volatile ("pshufb %xmm1,%xmm3");
+ 2034 1019136 : asm volatile ("pxor %xmm3,%xmm2");
+ 2035 1019136 : 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 44102 : void raid_rec2_ssse3(int nr, int *id, int *ip, int nd, size_t size, void **vv)
- 2047 44102 : {
- 2048 44102 : uint8_t **v = (uint8_t **)vv;
- 2049 44102 : const int N = 2;
- 2050 44102 : uint8_t *p[N];
- 2051 44102 : uint8_t *pa[N];
- 2052 44102 : uint8_t G[N * N];
- 2053 44102 : uint8_t V[N * N];
+ 2046 44098 : void raid_rec2_ssse3(int nr, int *id, int *ip, int nd, size_t size, void **vv)
+ 2047 44098 : {
+ 2048 44098 : uint8_t **v = (uint8_t **)vv;
+ 2049 44098 : const int N = 2;
+ 2050 44098 : uint8_t *p[N];
+ 2051 44098 : uint8_t *pa[N];
+ 2052 44098 : uint8_t G[N * N];
+ 2053 44098 : 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 132306 : for (j = 0; j < N; ++j)
- 2061 264612 : for (k = 0; k < N; ++k)
- 2062 352816 : G[j * N + k] = A(ip[j], id[k]);
+ 2060 132294 : for (j = 0; j < N; ++j)
+ 2061 264588 : for (k = 0; k < N; ++k)
+ 2062 352784 : G[j * N + k] = A(ip[j], id[k]);
2063 :
2064 : /* invert it to solve the system of linear equations */
- 2065 44102 : raid_invert(G, V, N);
+ 2065 44098 : raid_invert(G, V, N);
2066 :
2067 : /* compute delta parity */
- 2068 44102 : raid_delta_gen(N, id, ip, nd, size, vv);
+ 2068 44098 : raid_delta_gen(N, id, ip, nd, size, vv);
2069 :
- 2070 132306 : for (j = 0; j < N; ++j) {
- 2071 88204 : p[j] = v[nd + ip[j]];
- 2072 88204 : pa[j] = v[id[j]];
+ 2070 132294 : for (j = 0; j < N; ++j) {
+ 2071 88196 : p[j] = v[nd + ip[j]];
+ 2072 88196 : pa[j] = v[id[j]];
2073 : }
2074 :
2075 : raid_sse_begin();
2076 :
- 2077 44102 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0]));
+ 2077 44098 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0]));
2078 :
- 2079 3201286 : for (i = 0; i < size; i += 16) {
- 2080 3157184 : asm volatile ("movdqa %0,%%xmm0" : : "m" (p[0][i]));
- 2081 3157184 : asm volatile ("movdqa %0,%%xmm2" : : "m" (pa[0][i]));
- 2082 3157184 : asm volatile ("movdqa %0,%%xmm1" : : "m" (p[1][i]));
- 2083 3157184 : asm volatile ("movdqa %0,%%xmm3" : : "m" (pa[1][i]));
- 2084 3157184 : asm volatile ("pxor %xmm2,%xmm0");
- 2085 3157184 : asm volatile ("pxor %xmm3,%xmm1");
+ 2079 3201026 : for (i = 0; i < size; i += 16) {
+ 2080 3156928 : asm volatile ("movdqa %0,%%xmm0" : : "m" (p[0][i]));
+ 2081 3156928 : asm volatile ("movdqa %0,%%xmm2" : : "m" (pa[0][i]));
+ 2082 3156928 : asm volatile ("movdqa %0,%%xmm1" : : "m" (p[1][i]));
+ 2083 3156928 : asm volatile ("movdqa %0,%%xmm3" : : "m" (pa[1][i]));
+ 2084 3156928 : asm volatile ("pxor %xmm2,%xmm0");
+ 2085 3156928 : asm volatile ("pxor %xmm3,%xmm1");
2086 :
- 2087 3157184 : asm volatile ("pxor %xmm6,%xmm6");
+ 2087 3156928 : asm volatile ("pxor %xmm6,%xmm6");
2088 :
- 2089 3157184 : asm volatile ("movdqa %0,%%xmm2" : : "m" (gfmulpshufb[V[0]][0][0]));
- 2090 3157184 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfmulpshufb[V[0]][1][0]));
- 2091 3157184 : asm volatile ("movdqa %xmm0,%xmm4");
- 2092 3157184 : asm volatile ("movdqa %xmm0,%xmm5");
- 2093 3157184 : asm volatile ("psrlw $4,%xmm5");
- 2094 3157184 : asm volatile ("pand %xmm7,%xmm4");
- 2095 3157184 : asm volatile ("pand %xmm7,%xmm5");
- 2096 3157184 : asm volatile ("pshufb %xmm4,%xmm2");
- 2097 3157184 : asm volatile ("pshufb %xmm5,%xmm3");
- 2098 3157184 : asm volatile ("pxor %xmm2,%xmm6");
- 2099 3157184 : asm volatile ("pxor %xmm3,%xmm6");
+ 2089 3156928 : asm volatile ("movdqa %0,%%xmm2" : : "m" (gfmulpshufb[V[0]][0][0]));
+ 2090 3156928 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfmulpshufb[V[0]][1][0]));
+ 2091 3156928 : asm volatile ("movdqa %xmm0,%xmm4");
+ 2092 3156928 : asm volatile ("movdqa %xmm0,%xmm5");
+ 2093 3156928 : asm volatile ("psrlw $4,%xmm5");
+ 2094 3156928 : asm volatile ("pand %xmm7,%xmm4");
+ 2095 3156928 : asm volatile ("pand %xmm7,%xmm5");
+ 2096 3156928 : asm volatile ("pshufb %xmm4,%xmm2");
+ 2097 3156928 : asm volatile ("pshufb %xmm5,%xmm3");
+ 2098 3156928 : asm volatile ("pxor %xmm2,%xmm6");
+ 2099 3156928 : asm volatile ("pxor %xmm3,%xmm6");
2100 :
- 2101 3157184 : asm volatile ("movdqa %0,%%xmm2" : : "m" (gfmulpshufb[V[1]][0][0]));
- 2102 3157184 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfmulpshufb[V[1]][1][0]));
- 2103 3157184 : asm volatile ("movdqa %xmm1,%xmm4");
- 2104 3157184 : asm volatile ("movdqa %xmm1,%xmm5");
- 2105 3157184 : asm volatile ("psrlw $4,%xmm5");
- 2106 3157184 : asm volatile ("pand %xmm7,%xmm4");
- 2107 3157184 : asm volatile ("pand %xmm7,%xmm5");
- 2108 3157184 : asm volatile ("pshufb %xmm4,%xmm2");
- 2109 3157184 : asm volatile ("pshufb %xmm5,%xmm3");
- 2110 3157184 : asm volatile ("pxor %xmm2,%xmm6");
- 2111 3157184 : asm volatile ("pxor %xmm3,%xmm6");
+ 2101 3156928 : asm volatile ("movdqa %0,%%xmm2" : : "m" (gfmulpshufb[V[1]][0][0]));
+ 2102 3156928 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfmulpshufb[V[1]][1][0]));
+ 2103 3156928 : asm volatile ("movdqa %xmm1,%xmm4");
+ 2104 3156928 : asm volatile ("movdqa %xmm1,%xmm5");
+ 2105 3156928 : asm volatile ("psrlw $4,%xmm5");
+ 2106 3156928 : asm volatile ("pand %xmm7,%xmm4");
+ 2107 3156928 : asm volatile ("pand %xmm7,%xmm5");
+ 2108 3156928 : asm volatile ("pshufb %xmm4,%xmm2");
+ 2109 3156928 : asm volatile ("pshufb %xmm5,%xmm3");
+ 2110 3156928 : asm volatile ("pxor %xmm2,%xmm6");
+ 2111 3156928 : asm volatile ("pxor %xmm3,%xmm6");
2112 :
- 2113 3157184 : asm volatile ("movdqa %%xmm6,%0" : "=m" (pa[0][i]));
+ 2113 3156928 : asm volatile ("movdqa %%xmm6,%0" : "=m" (pa[0][i]));
2114 :
- 2115 3157184 : asm volatile ("pxor %xmm6,%xmm6");
+ 2115 3156928 : asm volatile ("pxor %xmm6,%xmm6");
2116 :
- 2117 3157184 : asm volatile ("movdqa %0,%%xmm2" : : "m" (gfmulpshufb[V[2]][0][0]));
- 2118 3157184 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfmulpshufb[V[2]][1][0]));
- 2119 3157184 : asm volatile ("movdqa %xmm0,%xmm4");
- 2120 3157184 : asm volatile ("movdqa %xmm0,%xmm5");
- 2121 3157184 : asm volatile ("psrlw $4,%xmm5");
- 2122 3157184 : asm volatile ("pand %xmm7,%xmm4");
- 2123 3157184 : asm volatile ("pand %xmm7,%xmm5");
- 2124 3157184 : asm volatile ("pshufb %xmm4,%xmm2");
- 2125 3157184 : asm volatile ("pshufb %xmm5,%xmm3");
- 2126 3157184 : asm volatile ("pxor %xmm2,%xmm6");
- 2127 3157184 : asm volatile ("pxor %xmm3,%xmm6");
+ 2117 3156928 : asm volatile ("movdqa %0,%%xmm2" : : "m" (gfmulpshufb[V[2]][0][0]));
+ 2118 3156928 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfmulpshufb[V[2]][1][0]));
+ 2119 3156928 : asm volatile ("movdqa %xmm0,%xmm4");
+ 2120 3156928 : asm volatile ("movdqa %xmm0,%xmm5");
+ 2121 3156928 : asm volatile ("psrlw $4,%xmm5");
+ 2122 3156928 : asm volatile ("pand %xmm7,%xmm4");
+ 2123 3156928 : asm volatile ("pand %xmm7,%xmm5");
+ 2124 3156928 : asm volatile ("pshufb %xmm4,%xmm2");
+ 2125 3156928 : asm volatile ("pshufb %xmm5,%xmm3");
+ 2126 3156928 : asm volatile ("pxor %xmm2,%xmm6");
+ 2127 3156928 : asm volatile ("pxor %xmm3,%xmm6");
2128 :
- 2129 3157184 : asm volatile ("movdqa %0,%%xmm2" : : "m" (gfmulpshufb[V[3]][0][0]));
- 2130 3157184 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfmulpshufb[V[3]][1][0]));
- 2131 3157184 : asm volatile ("movdqa %xmm1,%xmm4");
- 2132 3157184 : asm volatile ("movdqa %xmm1,%xmm5");
- 2133 3157184 : asm volatile ("psrlw $4,%xmm5");
- 2134 3157184 : asm volatile ("pand %xmm7,%xmm4");
- 2135 3157184 : asm volatile ("pand %xmm7,%xmm5");
- 2136 3157184 : asm volatile ("pshufb %xmm4,%xmm2");
- 2137 3157184 : asm volatile ("pshufb %xmm5,%xmm3");
- 2138 3157184 : asm volatile ("pxor %xmm2,%xmm6");
- 2139 3157184 : asm volatile ("pxor %xmm3,%xmm6");
+ 2129 3156928 : asm volatile ("movdqa %0,%%xmm2" : : "m" (gfmulpshufb[V[3]][0][0]));
+ 2130 3156928 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfmulpshufb[V[3]][1][0]));
+ 2131 3156928 : asm volatile ("movdqa %xmm1,%xmm4");
+ 2132 3156928 : asm volatile ("movdqa %xmm1,%xmm5");
+ 2133 3156928 : asm volatile ("psrlw $4,%xmm5");
+ 2134 3156928 : asm volatile ("pand %xmm7,%xmm4");
+ 2135 3156928 : asm volatile ("pand %xmm7,%xmm5");
+ 2136 3156928 : asm volatile ("pshufb %xmm4,%xmm2");
+ 2137 3156928 : asm volatile ("pshufb %xmm5,%xmm3");
+ 2138 3156928 : asm volatile ("pxor %xmm2,%xmm6");
+ 2139 3156928 : asm volatile ("pxor %xmm3,%xmm6");
2140 :
- 2141 3157184 : asm volatile ("movdqa %%xmm6,%0" : "=m" (pa[1][i]));
+ 2141 3156928 : asm volatile ("movdqa %%xmm6,%0" : "=m" (pa[1][i]));
2142 : }
2143 :
2144 : raid_sse_end();
- 2145 44102 : }
+ 2145 44098 : }
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 b3e1a7df..18507f8c 100644
--- a/cov/raid/x86z.c.func-sort-c.html
+++ b/cov/raid/x86z.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,7 +61,7 @@
| raid_genz_sse2 |
- 13 |
+ 11 |
| raid_genz_sse2ext |
diff --git a/cov/raid/x86z.c.func.html b/cov/raid/x86z.c.func.html
index 28ba68c6..252c5dff 100644
--- a/cov/raid/x86z.c.func.html
+++ b/cov/raid/x86z.c.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -65,7 +65,7 @@
| raid_genz_sse2 |
- 13 |
+ 11 |
| raid_genz_sse2ext |
diff --git a/cov/raid/x86z.c.gcov.html b/cov/raid/x86z.c.gcov.html
index 88d86f76..ffc8c5f5 100644
--- a/cov/raid/x86z.c.gcov.html
+++ b/cov/raid/x86z.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -102,58 +102,58 @@
40 : /*
41 : * GENz (triple parity with powers of 2^-1) SSE2 implementation
42 : */
- 43 13 : void raid_genz_sse2(int nd, size_t size, void **vv)
+ 43 11 : void raid_genz_sse2(int nd, size_t size, void **vv)
44 : {
- 45 13 : uint8_t **v = (uint8_t**)vv;
+ 45 11 : 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 13 : l = nd - 1;
- 53 13 : p = v[nd];
- 54 13 : q = v[nd + 1];
- 55 13 : r = v[nd + 2];
+ 52 11 : l = nd - 1;
+ 53 11 : p = v[nd];
+ 54 11 : q = v[nd + 1];
+ 55 11 : r = v[nd + 2];
56 :
57 : raid_sse_begin();
58 :
- 59 13 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfzconst16.poly[0]));
- 60 13 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfzconst16.half[0]));
- 61 13 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfzconst16.low7[0]));
+ 59 11 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfzconst16.poly[0]));
+ 60 11 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfzconst16.half[0]));
+ 61 11 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfzconst16.low7[0]));
62 :
- 63 196637 : for (i = 0; i < size; i += 16) {
- 64 196624 : asm volatile ("movdqa %0,%%xmm0" : : "m" (v[l][i]));
- 65 196624 : asm volatile ("movdqa %xmm0,%xmm1");
- 66 196624 : asm volatile ("movdqa %xmm0,%xmm2");
- 67 1573376 : for (d = l - 1; d >= 0; --d) {
- 68 1376752 : asm volatile ("pxor %xmm4,%xmm4");
- 69 1376752 : asm volatile ("pcmpgtb %xmm1,%xmm4");
- 70 1376752 : asm volatile ("paddb %xmm1,%xmm1");
- 71 1376752 : asm volatile ("pand %xmm7,%xmm4");
- 72 1376752 : asm volatile ("pxor %xmm4,%xmm1");
+ 63 163867 : for (i = 0; i < size; i += 16) {
+ 64 163856 : asm volatile ("movdqa %0,%%xmm0" : : "m" (v[l][i]));
+ 65 163856 : asm volatile ("movdqa %xmm0,%xmm1");
+ 66 163856 : asm volatile ("movdqa %xmm0,%xmm2");
+ 67 1311232 : for (d = l - 1; d >= 0; --d) {
+ 68 1147376 : asm volatile ("pxor %xmm4,%xmm4");
+ 69 1147376 : asm volatile ("pcmpgtb %xmm1,%xmm4");
+ 70 1147376 : asm volatile ("paddb %xmm1,%xmm1");
+ 71 1147376 : asm volatile ("pand %xmm7,%xmm4");
+ 72 1147376 : asm volatile ("pxor %xmm4,%xmm1");
73 :
- 74 1376752 : asm volatile ("movdqa %xmm2,%xmm4");
- 75 1376752 : asm volatile ("pxor %xmm5,%xmm5");
- 76 1376752 : asm volatile ("psllw $7,%xmm4");
- 77 1376752 : asm volatile ("psrlw $1,%xmm2");
- 78 1376752 : asm volatile ("pcmpgtb %xmm4,%xmm5");
- 79 1376752 : asm volatile ("pand %xmm6,%xmm2");
- 80 1376752 : asm volatile ("pand %xmm3,%xmm5");
- 81 1376752 : asm volatile ("pxor %xmm5,%xmm2");
+ 74 1147376 : asm volatile ("movdqa %xmm2,%xmm4");
+ 75 1147376 : asm volatile ("pxor %xmm5,%xmm5");
+ 76 1147376 : asm volatile ("psllw $7,%xmm4");
+ 77 1147376 : asm volatile ("psrlw $1,%xmm2");
+ 78 1147376 : asm volatile ("pcmpgtb %xmm4,%xmm5");
+ 79 1147376 : asm volatile ("pand %xmm6,%xmm2");
+ 80 1147376 : asm volatile ("pand %xmm3,%xmm5");
+ 81 1147376 : asm volatile ("pxor %xmm5,%xmm2");
82 :
- 83 1376752 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[d][i]));
- 84 1376752 : asm volatile ("pxor %xmm4,%xmm0");
- 85 1376752 : asm volatile ("pxor %xmm4,%xmm1");
- 86 1376752 : asm volatile ("pxor %xmm4,%xmm2");
+ 83 1147376 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[d][i]));
+ 84 1147376 : asm volatile ("pxor %xmm4,%xmm0");
+ 85 1147376 : asm volatile ("pxor %xmm4,%xmm1");
+ 86 1147376 : asm volatile ("pxor %xmm4,%xmm2");
87 : }
- 88 196624 : asm volatile ("movntdq %%xmm0,%0" : "=m" (p[i]));
- 89 196624 : asm volatile ("movntdq %%xmm1,%0" : "=m" (q[i]));
- 90 196624 : asm volatile ("movntdq %%xmm2,%0" : "=m" (r[i]));
+ 88 163856 : asm volatile ("movntdq %%xmm0,%0" : "=m" (p[i]));
+ 89 163856 : asm volatile ("movntdq %%xmm1,%0" : "=m" (q[i]));
+ 90 163856 : asm volatile ("movntdq %%xmm2,%0" : "=m" (r[i]));
91 : }
92 :
93 : raid_sse_end();
- 94 13 : }
+ 94 11 : }
95 : #endif
96 :
97 : #if defined(CONFIG_X86_64) && defined(CONFIG_SSE2)
diff --git a/cov/tommyds/index-sort-f.html b/cov/tommyds/index-sort-f.html
index 84c0d9aa..410dc457 100644
--- a/cov/tommyds/index-sort-f.html
+++ b/cov/tommyds/index-sort-f.html
@@ -37,7 +37,7 @@
-
+
|
@@ -89,16 +89,6 @@
100.0 % |
2 / 2 |
-
- | tommyhash.h |
-
-
- |
- 100.0 % |
- 18 / 18 |
- 100.0 % |
- 2 / 2 |
-
| tommyarrayblkof.h |
@@ -109,6 +99,16 @@
| 100.0 % |
2 / 2 |
+
+ | tommyhash.h |
+
+
+ |
+ 100.0 % |
+ 18 / 18 |
+ 100.0 % |
+ 2 / 2 |
+
| tommytypes.h |
@@ -139,16 +139,6 @@
| 100.0 % |
4 / 4 |
-
- | tommyhash.c |
-
-
- |
- 100.0 % |
- 115 / 115 |
- 100.0 % |
- 4 / 4 |
-
| tommyarray.c |
@@ -159,6 +149,16 @@
| 100.0 % |
4 / 4 |
+
+ | tommyhash.c |
+
+
+ |
+ 100.0 % |
+ 115 / 115 |
+ 100.0 % |
+ 4 / 4 |
+
| tommyarray.h |
diff --git a/cov/tommyds/index-sort-l.html b/cov/tommyds/index-sort-l.html
index 9aff068d..58c14186 100644
--- a/cov/tommyds/index-sort-l.html
+++ b/cov/tommyds/index-sort-l.html
@@ -37,7 +37,7 @@
|
-
+
|
@@ -79,16 +79,6 @@
100.0 % |
1 / 1 |
-
- | tommyarrayblkof.h |
-
-
- |
- 100.0 % |
- 6 / 6 |
- 100.0 % |
- 2 / 2 |
-
| tommytypes.h |
@@ -99,6 +89,16 @@
| 100.0 % |
3 / 3 |
+
+ | tommyarrayblkof.h |
+
+
+ |
+ 100.0 % |
+ 6 / 6 |
+ 100.0 % |
+ 2 / 2 |
+
| tommyhashdyn.h |
diff --git a/cov/tommyds/index.html b/cov/tommyds/index.html
index 04122e68..fa0de117 100644
--- a/cov/tommyds/index.html
+++ b/cov/tommyds/index.html
@@ -37,7 +37,7 @@
|
-
+
|
diff --git a/cov/tommyds/tommyarray.c.func-sort-c.html b/cov/tommyds/tommyarray.c.func-sort-c.html
index 565c176b..3c9c643f 100644
--- a/cov/tommyds/tommyarray.c.func-sort-c.html
+++ b/cov/tommyds/tommyarray.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -65,11 +65,11 @@
| tommy_array_done |
- 534 |
+ 535 |
| tommy_array_init |
- 546 |
+ 547 |
| tommy_array_grow |
diff --git a/cov/tommyds/tommyarray.c.func.html b/cov/tommyds/tommyarray.c.func.html
index f5c5f0be..53604583 100644
--- a/cov/tommyds/tommyarray.c.func.html
+++ b/cov/tommyds/tommyarray.c.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,7 +61,7 @@
| tommy_array_done |
- 534 |
+ 535 |
| tommy_array_grow |
@@ -69,7 +69,7 @@
| tommy_array_init |
- 546 |
+ 547 |
| tommy_array_memory_usage |
diff --git a/cov/tommyds/tommyarray.c.gcov.html b/cov/tommyds/tommyarray.c.gcov.html
index 9ffd3513..c742821e 100644
--- a/cov/tommyds/tommyarray.c.gcov.html
+++ b/cov/tommyds/tommyarray.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -92,30 +92,30 @@
30 : /******************************************************************************/
31 : /* array */
32 :
- 33 546 : TOMMY_API void tommy_array_init(tommy_array* array)
+ 33 547 : TOMMY_API void tommy_array_init(tommy_array* array)
34 : {
35 : tommy_uint_t i;
36 :
37 : /* fixed initial size */
- 38 546 : array->bucket_bit = TOMMY_ARRAY_BIT;
- 39 546 : array->bucket_max = (tommy_size_t)1 << array->bucket_bit;
- 40 546 : array->bucket[0] = tommy_cast(void**, tommy_calloc(array->bucket_max, sizeof(void*)));
- 41 3276 : for (i = 1; i < TOMMY_ARRAY_BIT; ++i)
- 42 2730 : array->bucket[i] = array->bucket[0];
+ 38 547 : array->bucket_bit = TOMMY_ARRAY_BIT;
+ 39 547 : array->bucket_max = (tommy_size_t)1 << array->bucket_bit;
+ 40 547 : array->bucket[0] = tommy_cast(void**, tommy_calloc(array->bucket_max, sizeof(void*)));
+ 41 3282 : for (i = 1; i < TOMMY_ARRAY_BIT; ++i)
+ 42 2735 : array->bucket[i] = array->bucket[0];
43 :
- 44 546 : array->count = 0;
- 45 546 : }
+ 44 547 : array->count = 0;
+ 45 547 : }
46 :
- 47 534 : TOMMY_API void tommy_array_done(tommy_array* array)
+ 47 535 : TOMMY_API void tommy_array_done(tommy_array* array)
48 : {
49 : tommy_uint_t i;
50 :
- 51 534 : tommy_free(array->bucket[0]);
- 52 536 : for (i = TOMMY_ARRAY_BIT; i < array->bucket_bit; ++i) {
+ 51 535 : tommy_free(array->bucket[0]);
+ 52 537 : 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 534 : }
+ 56 535 : }
57 :
58 2302 : TOMMY_API void tommy_array_grow(tommy_array* array, tommy_size_t count)
59 : {
diff --git a/cov/tommyds/tommyarray.h.func-sort-c.html b/cov/tommyds/tommyarray.h.func-sort-c.html
index 793d1f6b..fc67005b 100644
--- a/cov/tommyds/tommyarray.h.func-sort-c.html
+++ b/cov/tommyds/tommyarray.h.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -69,15 +69,15 @@
| tommy_array_size |
- 1635800 |
+ 1635801 |
| tommy_array_get |
- 8513524 |
+ 8494577 |
| tommy_array_ref |
- 8515825 |
+ 8496878 |
diff --git a/cov/tommyds/tommyarray.h.func.html b/cov/tommyds/tommyarray.h.func.html
index 7d572ce2..fd6107c7 100644
--- a/cov/tommyds/tommyarray.h.func.html
+++ b/cov/tommyds/tommyarray.h.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,7 +61,7 @@
| tommy_array_get |
- 8513524 |
+ 8494577 |
| tommy_array_insert |
@@ -69,7 +69,7 @@
| tommy_array_ref |
- 8515825 |
+ 8496878 |
| tommy_array_set |
@@ -77,7 +77,7 @@
| tommy_array_size |
- 1635800 |
+ 1635801 |
diff --git a/cov/tommyds/tommyarray.h.gcov.html b/cov/tommyds/tommyarray.h.gcov.html
index 44a38efd..ae841587 100644
--- a/cov/tommyds/tommyarray.h.gcov.html
+++ b/cov/tommyds/tommyarray.h.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -147,16 +147,16 @@
85 : * You must be sure that space for this position is already
86 : * allocated calling tommy_array_grow().
87 : */
- 88 8515825 : tommy_inline void** tommy_array_ref(tommy_array* array, tommy_size_t pos)
+ 88 8496878 : tommy_inline void** tommy_array_ref(tommy_array* array, tommy_size_t pos)
89 : {
90 : tommy_uint_t bsr;
91 :
- 92 8515825 : assert(pos < array->count);
+ 92 8496878 : assert(pos < array->count);
93 :
94 : /* get the highest bit set, in case of all 0, return 0 */
- 95 8515825 : bsr = tommy_ilog2(pos | 1);
+ 95 8496878 : bsr = tommy_ilog2(pos | 1);
96 :
- 97 8515825 : return &array->bucket[bsr][pos];
+ 97 8496878 : return &array->bucket[bsr][pos];
98 : }
99 :
100 : /**
@@ -174,9 +174,9 @@
112 : * You must be sure that space for this position is already
113 : * allocated calling tommy_array_grow().
114 : */
- 115 8513524 : tommy_inline void* tommy_array_get(tommy_array* array, tommy_size_t pos)
+ 115 8494577 : tommy_inline void* tommy_array_get(tommy_array* array, tommy_size_t pos)
116 : {
- 117 8513524 : return *tommy_array_ref(array, pos);
+ 117 8494577 : return *tommy_array_ref(array, pos);
118 : }
119 :
120 : /**
@@ -194,9 +194,9 @@
132 : /**
133 : * Gets the initialized size of the array.
134 : */
- 135 1635800 : tommy_inline tommy_size_t tommy_array_size(tommy_array* array)
+ 135 1635801 : tommy_inline tommy_size_t tommy_array_size(tommy_array* array)
136 : {
- 137 1635800 : return array->count;
+ 137 1635801 : return array->count;
138 : }
139 :
140 : /**
diff --git a/cov/tommyds/tommyarrayblkof.c.func-sort-c.html b/cov/tommyds/tommyarrayblkof.c.func-sort-c.html
index 5cac0cbe..3aae58f6 100644
--- a/cov/tommyds/tommyarrayblkof.c.func-sort-c.html
+++ b/cov/tommyds/tommyarrayblkof.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -65,15 +65,15 @@
| tommy_arrayblkof_done |
- 269 |
+ 270 |
| tommy_arrayblkof_init |
- 280 |
+ 281 |
| tommy_arrayblkof_grow |
- 1757830 |
+ 1757779 |
diff --git a/cov/tommyds/tommyarrayblkof.c.func.html b/cov/tommyds/tommyarrayblkof.c.func.html
index 2c9dc2fc..b07e59b5 100644
--- a/cov/tommyds/tommyarrayblkof.c.func.html
+++ b/cov/tommyds/tommyarrayblkof.c.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,15 +61,15 @@
| tommy_arrayblkof_done |
- 269 |
+ 270 |
| tommy_arrayblkof_grow |
- 1757830 |
+ 1757779 |
| tommy_arrayblkof_init |
- 280 |
+ 281 |
| tommy_arrayblkof_memory_usage |
diff --git a/cov/tommyds/tommyarrayblkof.c.gcov.html b/cov/tommyds/tommyarrayblkof.c.gcov.html
index 48e5a85c..31246f1a 100644
--- a/cov/tommyds/tommyarrayblkof.c.gcov.html
+++ b/cov/tommyds/tommyarrayblkof.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -92,31 +92,31 @@
30 : /******************************************************************************/
31 : /* array */
32 :
- 33 280 : TOMMY_API void tommy_arrayblkof_init(tommy_arrayblkof* array, tommy_size_t element_size)
+ 33 281 : TOMMY_API void tommy_arrayblkof_init(tommy_arrayblkof* array, tommy_size_t element_size)
34 : {
- 35 280 : tommy_array_init(&array->block);
+ 35 281 : tommy_array_init(&array->block);
36 :
- 37 280 : array->element_size = element_size;
- 38 280 : array->count = 0;
- 39 280 : }
+ 37 281 : array->element_size = element_size;
+ 38 281 : array->count = 0;
+ 39 281 : }
40 :
- 41 269 : TOMMY_API void tommy_arrayblkof_done(tommy_arrayblkof* array)
+ 41 270 : TOMMY_API void tommy_arrayblkof_done(tommy_arrayblkof* array)
42 : {
43 : tommy_size_t i;
44 :
- 45 837 : for (i = 0; i < tommy_array_size(&array->block); ++i)
+ 45 838 : for (i = 0; i < tommy_array_size(&array->block); ++i)
46 568 : tommy_free(tommy_array_get(&array->block, i));
47 :
- 48 269 : tommy_array_done(&array->block);
- 49 269 : }
+ 48 270 : tommy_array_done(&array->block);
+ 49 270 : }
50 :
- 51 1757830 : TOMMY_API void tommy_arrayblkof_grow(tommy_arrayblkof* array, tommy_size_t count)
+ 51 1757779 : TOMMY_API void tommy_arrayblkof_grow(tommy_arrayblkof* array, tommy_size_t count)
52 : {
53 : tommy_size_t block_max;
54 : tommy_size_t block_mac;
55 :
- 56 1757830 : if (array->count >= count)
- 57 122868 : return;
+ 56 1757779 : if (array->count >= count)
+ 57 122817 : return;
58 1634962 : array->count = count;
59 :
60 1634962 : block_max = (count + TOMMY_ARRAYBLKOF_SIZE - 1) / TOMMY_ARRAYBLKOF_SIZE;
diff --git a/cov/tommyds/tommyarrayblkof.h.func-sort-c.html b/cov/tommyds/tommyarrayblkof.h.func-sort-c.html
index 3d0874f7..6ce461bf 100644
--- a/cov/tommyds/tommyarrayblkof.h.func-sort-c.html
+++ b/cov/tommyds/tommyarrayblkof.h.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,11 +61,11 @@
| tommy_arrayblkof_size |
- 3171512 |
+ 3152579 |
| tommy_arrayblkof_ref |
- 4659100 |
+ 4640116 |
diff --git a/cov/tommyds/tommyarrayblkof.h.func.html b/cov/tommyds/tommyarrayblkof.h.func.html
index 29a7986f..6a37a67c 100644
--- a/cov/tommyds/tommyarrayblkof.h.func.html
+++ b/cov/tommyds/tommyarrayblkof.h.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,11 +61,11 @@
| tommy_arrayblkof_ref |
- 4659100 |
+ 4640116 |
| tommy_arrayblkof_size |
- 3171512 |
+ 3152579 |
diff --git a/cov/tommyds/tommyarrayblkof.h.gcov.html b/cov/tommyds/tommyarrayblkof.h.gcov.html
index 551752fd..f46ba300 100644
--- a/cov/tommyds/tommyarrayblkof.h.gcov.html
+++ b/cov/tommyds/tommyarrayblkof.h.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -148,23 +148,23 @@
86 : * You must be sure that space for this position is already
87 : * allocated calling tommy_arrayblkof_grow().
88 : */
- 89 4659100 : tommy_inline void* tommy_arrayblkof_ref(tommy_arrayblkof* array, tommy_size_t pos)
+ 89 4640116 : tommy_inline void* tommy_arrayblkof_ref(tommy_arrayblkof* array, tommy_size_t pos)
90 : {
91 : unsigned char* base;
92 :
- 93 4659100 : assert(pos < array->count);
+ 93 4640116 : assert(pos < array->count);
94 :
- 95 4659100 : base = tommy_cast(unsigned char*, tommy_array_get(&array->block, pos / TOMMY_ARRAYBLKOF_SIZE));
+ 95 4640116 : base = tommy_cast(unsigned char*, tommy_array_get(&array->block, pos / TOMMY_ARRAYBLKOF_SIZE));
96 :
- 97 4659100 : return base + (pos % TOMMY_ARRAYBLKOF_SIZE) * array->element_size;
+ 97 4640116 : return base + (pos % TOMMY_ARRAYBLKOF_SIZE) * array->element_size;
98 : }
99 :
100 : /**
101 : * Gets the initialized size of the array.
102 : */
- 103 3171512 : tommy_inline tommy_size_t tommy_arrayblkof_size(tommy_arrayblkof* array)
+ 103 3152579 : tommy_inline tommy_size_t tommy_arrayblkof_size(tommy_arrayblkof* array)
104 : {
- 105 3171512 : return array->count;
+ 105 3152579 : 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 77478aa4..f5e3678d 100644
--- a/cov/tommyds/tommychain.h.func-sort-c.html
+++ b/cov/tommyds/tommychain.h.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,23 +61,23 @@
| tommy_chain_mergesort |
- 2198 |
+ 2196 |
| tommy_chain_merge |
- 498587 |
+ 498640 |
| tommy_chain_concat |
- 1349545 |
+ 1349758 |
| tommy_chain_merge_degenerated |
- 1351364 |
+ 1351313 |
| tommy_chain_splice |
- 4749204 |
+ 4745891 |
diff --git a/cov/tommyds/tommychain.h.func.html b/cov/tommyds/tommychain.h.func.html
index 3840c72f..660d60d9 100644
--- a/cov/tommyds/tommychain.h.func.html
+++ b/cov/tommyds/tommychain.h.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,23 +61,23 @@
| tommy_chain_concat |
- 1349545 |
+ 1349758 |
| tommy_chain_merge |
- 498587 |
+ 498640 |
| tommy_chain_merge_degenerated |
- 1351364 |
+ 1351313 |
| tommy_chain_mergesort |
- 2198 |
+ 2196 |
| tommy_chain_splice |
- 4749204 |
+ 4745891 |
diff --git a/cov/tommyds/tommychain.h.gcov.html b/cov/tommyds/tommychain.h.gcov.html
index 165926a5..16a65703 100644
--- a/cov/tommyds/tommychain.h.gcov.html
+++ b/cov/tommyds/tommychain.h.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -123,30 +123,30 @@
61 : * \param second_head Head of the chain to splice in.
62 : * \param second_tail Tail of the chain to splice in.
63 : */
- 64 4749204 : tommy_inline void tommy_chain_splice(tommy_node* first_before, tommy_node* first_after, tommy_node* second_head, tommy_node* second_tail)
+ 64 4745891 : tommy_inline void tommy_chain_splice(tommy_node* first_before, tommy_node* first_after, tommy_node* second_head, tommy_node* second_tail)
65 : {
66 : /* set the prev list */
- 67 4749204 : first_after->prev = second_tail;
- 68 4749204 : second_head->prev = first_before;
+ 67 4745891 : first_after->prev = second_tail;
+ 68 4745891 : second_head->prev = first_before;
69 :
70 : /* set the next list */
- 71 4749204 : first_before->next = second_head;
- 72 4749204 : second_tail->next = first_after;
- 73 4749204 : }
+ 71 4745891 : first_before->next = second_head;
+ 72 4745891 : second_tail->next = first_after;
+ 73 4745891 : }
74 :
75 : /**
76 : * Concatenates two chains.
77 : * \param first_tail Tail of the first chain.
78 : * \param second_head Head of the second chain.
79 : */
- 80 1349545 : tommy_inline void tommy_chain_concat(tommy_node* first_tail, tommy_node* second_head)
+ 80 1349758 : tommy_inline void tommy_chain_concat(tommy_node* first_tail, tommy_node* second_head)
81 : {
82 : /* set the prev list */
- 83 1349545 : second_head->prev = first_tail;
+ 83 1349758 : second_head->prev = first_tail;
84 :
85 : /* set the next list */
- 86 1349545 : first_tail->next = second_head;
- 87 1349545 : }
+ 86 1349758 : first_tail->next = second_head;
+ 87 1349758 : }
88 :
89 : /**
90 : * Merges two chains.
@@ -154,34 +154,34 @@
92 : * \param second Second chain (will be empty after the merge).
93 : * \param cmp Comparison function.
94 : */
- 95 498587 : tommy_inline void tommy_chain_merge(tommy_chain* first, tommy_chain* second, tommy_compare_func* cmp)
+ 95 498640 : tommy_inline void tommy_chain_merge(tommy_chain* first, tommy_chain* second, tommy_compare_func* cmp)
96 : {
- 97 498587 : tommy_node* first_i = first->head;
- 98 498587 : tommy_node* second_i = second->head;
+ 97 498640 : tommy_node* first_i = first->head;
+ 98 498640 : tommy_node* second_i = second->head;
99 :
100 : /* merge */
101 : while (1) {
- 102 10347373 : if (cmp(first_i->data, second_i->data) > 0) {
- 103 4999216 : tommy_node* next = second_i->next;
- 104 4999216 : if (first_i == first->head) {
- 105 250012 : tommy_chain_concat(second_i, first_i);
- 106 250012 : first->head = second_i;
+ 102 10344008 : if (cmp(first_i->data, second_i->data) > 0) {
+ 103 4995826 : tommy_node* next = second_i->next;
+ 104 4995826 : if (first_i == first->head) {
+ 105 249935 : tommy_chain_concat(second_i, first_i);
+ 106 249935 : first->head = second_i;
107 : } else {
- 108 4749204 : tommy_chain_splice(first_i->prev, first_i, second_i, second_i);
+ 108 4745891 : tommy_chain_splice(first_i->prev, first_i, second_i, second_i);
109 : }
- 110 4999216 : if (second_i == second->tail)
- 111 251831 : break;
- 112 4747385 : second_i = next;
+ 110 4995826 : if (second_i == second->tail)
+ 111 251490 : break;
+ 112 4744336 : second_i = next;
113 : } else {
- 114 5348157 : if (first_i == first->tail) {
- 115 246756 : tommy_chain_concat(first_i, second_i);
- 116 246756 : first->tail = second->tail;
- 117 246756 : break;
+ 114 5348182 : if (first_i == first->tail) {
+ 115 247150 : tommy_chain_concat(first_i, second_i);
+ 116 247150 : first->tail = second->tail;
+ 117 247150 : break;
118 : }
- 119 5101401 : first_i = first_i->next;
+ 119 5101032 : first_i = first_i->next;
120 : }
121 : }
- 122 498587 : }
+ 122 498640 : }
123 :
124 : /**
125 : * Merges two chains managing special degenerated cases.
@@ -190,24 +190,24 @@
128 : * \param second Second chain (will be empty after the merge).
129 : * \param cmp Comparison function.
130 : */
- 131 1351364 : tommy_inline void tommy_chain_merge_degenerated(tommy_chain* first, tommy_chain* second, tommy_compare_func* cmp)
+ 131 1351313 : tommy_inline void tommy_chain_merge_degenerated(tommy_chain* first, tommy_chain* second, tommy_compare_func* cmp)
132 : {
133 : /* identify the condition first <= second */
- 134 1351364 : if (cmp(first->tail->data, second->head->data) <= 0) {
- 135 497826 : tommy_chain_concat(first->tail, second->head);
- 136 497826 : first->tail = second->tail;
- 137 497826 : return;
+ 134 1351313 : if (cmp(first->tail->data, second->head->data) <= 0) {
+ 135 497557 : tommy_chain_concat(first->tail, second->head);
+ 136 497557 : first->tail = second->tail;
+ 137 497557 : return;
138 : }
139 :
140 : /* identify the condition second < first */
141 : /* here we must be strict on comparison to keep the sort stable */
- 142 853538 : if (cmp(second->tail->data, first->head->data) < 0) {
- 143 354951 : tommy_chain_concat(second->tail, first->head);
- 144 354951 : first->head = second->head;
- 145 354951 : return;
+ 142 853756 : if (cmp(second->tail->data, first->head->data) < 0) {
+ 143 355116 : tommy_chain_concat(second->tail, first->head);
+ 144 355116 : first->head = second->head;
+ 145 355116 : return;
146 : }
147 :
- 148 498587 : tommy_chain_merge(first, second, cmp);
+ 148 498640 : tommy_chain_merge(first, second, cmp);
149 : }
150 :
151 : /**
@@ -225,7 +225,7 @@
163 : * \param chain Chain to sort.
164 : * \param cmp Comparison function.
165 : */
- 166 2198 : tommy_inline void tommy_chain_mergesort(tommy_chain* chain, tommy_compare_func* cmp)
+ 166 2196 : tommy_inline void tommy_chain_mergesort(tommy_chain* chain, tommy_compare_func* cmp)
167 : {
168 : /*
169 : * Bit buckets of chains.
@@ -240,57 +240,57 @@
178 : * It's used to know which bucket is empty or full.
179 : */
180 : tommy_size_t counter;
- 181 2198 : tommy_node* node = chain->head;
- 182 2198 : tommy_node* tail = chain->tail;
+ 181 2196 : tommy_node* node = chain->head;
+ 182 2196 : tommy_node* tail = chain->tail;
183 : tommy_size_t mask;
184 : tommy_size_t i;
185 :
- 186 2198 : counter = 0;
- 187 1351364 : while (1) {
+ 186 2196 : counter = 0;
+ 187 1351313 : while (1) {
188 : tommy_node* next;
189 : tommy_chain* last;
190 :
191 : /* carry bit to add */
- 192 1353562 : last = &bit[TOMMY_SIZE_BIT];
- 193 1353562 : bit[TOMMY_SIZE_BIT].head = node;
- 194 1353562 : bit[TOMMY_SIZE_BIT].tail = node;
- 195 1353562 : next = node->next;
+ 192 1353509 : last = &bit[TOMMY_SIZE_BIT];
+ 193 1353509 : bit[TOMMY_SIZE_BIT].head = node;
+ 194 1353509 : bit[TOMMY_SIZE_BIT].tail = node;
+ 195 1353509 : next = node->next;
196 :
197 : /* add the bit, propagating the carry */
- 198 1353562 : i = 0;
- 199 1353562 : mask = counter;
- 200 2698464 : while ((mask & 1) != 0) {
- 201 1344902 : tommy_chain_merge_degenerated(&bit[i], last, cmp);
- 202 1344902 : mask >>= 1;
- 203 1344902 : last = &bit[i];
- 204 1344902 : ++i;
+ 198 1353509 : i = 0;
+ 199 1353509 : mask = counter;
+ 200 2698356 : while ((mask & 1) != 0) {
+ 201 1344847 : tommy_chain_merge_degenerated(&bit[i], last, cmp);
+ 202 1344847 : mask >>= 1;
+ 203 1344847 : last = &bit[i];
+ 204 1344847 : ++i;
205 : }
206 :
207 : /* copy the carry in the first empty bit */
- 208 1353562 : bit[i] = *last;
+ 208 1353509 : bit[i] = *last;
209 :
210 : /* add the carry in the counter */
- 211 1353562 : ++counter;
+ 211 1353509 : ++counter;
212 :
- 213 1353562 : if (node == tail)
- 214 2198 : break;
- 215 1351364 : node = next;
+ 213 1353509 : if (node == tail)
+ 214 2196 : break;
+ 215 1351313 : node = next;
216 : }
217 :
218 : /* merge the buckets */
- 219 2198 : i = tommy_ctz(counter);
- 220 2198 : mask = counter >> i;
- 221 11800 : while (mask != 1) {
- 222 9602 : mask >>= 1;
- 223 9602 : if (mask & 1)
- 224 6462 : tommy_chain_merge_degenerated(&bit[i + 1], &bit[i], cmp);
+ 219 2196 : i = tommy_ctz(counter);
+ 220 2196 : mask = counter >> i;
+ 221 11795 : while (mask != 1) {
+ 222 9599 : mask >>= 1;
+ 223 9599 : if (mask & 1)
+ 224 6466 : tommy_chain_merge_degenerated(&bit[i + 1], &bit[i], cmp);
225 : else
- 226 3140 : bit[i + 1] = bit[i];
- 227 9602 : ++i;
+ 226 3133 : bit[i + 1] = bit[i];
+ 227 9599 : ++i;
228 : }
229 :
- 230 2198 : *chain = bit[i];
- 231 2198 : }
+ 230 2196 : *chain = bit[i];
+ 231 2196 : }
232 :
233 : #endif
diff --git a/cov/tommyds/tommyhash.c.func-sort-c.html b/cov/tommyds/tommyhash.c.func-sort-c.html
index 887b5365..c84c1192 100644
--- a/cov/tommyds/tommyhash.c.func-sort-c.html
+++ b/cov/tommyds/tommyhash.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -69,11 +69,11 @@
| tommy_hash_u32 |
- 4205922 |
+ 4205889 |
| tommy_le_uint32_read |
- 12197351 |
+ 12197247 |
diff --git a/cov/tommyds/tommyhash.c.func.html b/cov/tommyds/tommyhash.c.func.html
index fca233d6..240cac72 100644
--- a/cov/tommyds/tommyhash.c.func.html
+++ b/cov/tommyds/tommyhash.c.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,7 +61,7 @@
| tommy_hash_u32 |
- 4205922 |
+ 4205889 |
| tommy_hash_u64 |
@@ -69,7 +69,7 @@
| tommy_le_uint32_read |
- 12197351 |
+ 12197247 |
| tommy_strhash_u32 |
diff --git a/cov/tommyds/tommyhash.c.gcov.html b/cov/tommyds/tommyhash.c.gcov.html
index be57b01f..2bf99ba0 100644
--- a/cov/tommyds/tommyhash.c.gcov.html
+++ b/cov/tommyds/tommyhash.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -110,15 +110,15 @@
48 : }
49 : #endif
50 :
- 51 12197351 : tommy_inline tommy_uint32_t tommy_le_uint32_read(const void* ptr)
+ 51 12197247 : tommy_inline tommy_uint32_t tommy_le_uint32_read(const void* ptr)
52 : {
53 : tommy_uint32_t v;
- 54 12197351 : memcpy(&v, ptr, sizeof(v));
+ 54 12197247 : memcpy(&v, ptr, sizeof(v));
55 : #if defined(WORDS_BIGENDIAN) || defined(__BIG_ENDIAN__) || \
56 : (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
57 : v = tommy_swap32(v);
58 : #endif
- 59 12197351 : return v;
+ 59 12197247 : return v;
60 : }
61 :
62 : #define tommy_rot(x, k) \
@@ -145,53 +145,53 @@
83 : c ^= b; c -= tommy_rot(b, 24); \
84 : } while (0)
85 :
- 86 4205922 : TOMMY_API tommy_uint32_t tommy_hash_u32(tommy_uint32_t init_val, const void* void_key, tommy_size_t key_len)
+ 86 4205889 : TOMMY_API tommy_uint32_t tommy_hash_u32(tommy_uint32_t init_val, const void* void_key, tommy_size_t key_len)
87 : {
- 88 4205922 : const unsigned char* key = tommy_cast(const unsigned char*, void_key);
+ 88 4205889 : const unsigned char* key = tommy_cast(const unsigned char*, void_key);
89 : tommy_uint32_t a, b, c;
90 :
- 91 4205922 : a = b = c = 0xdeadbeef + ((tommy_uint32_t)key_len) + init_val;
+ 91 4205889 : a = b = c = 0xdeadbeef + ((tommy_uint32_t)key_len) + init_val;
92 :
- 93 6400524 : while (key_len > 12) {
- 94 2194602 : a += tommy_le_uint32_read(key + 0);
- 95 2194602 : b += tommy_le_uint32_read(key + 4);
- 96 2194602 : c += tommy_le_uint32_read(key + 8);
+ 93 6400465 : while (key_len > 12) {
+ 94 2194576 : a += tommy_le_uint32_read(key + 0);
+ 95 2194576 : b += tommy_le_uint32_read(key + 4);
+ 96 2194576 : c += tommy_le_uint32_read(key + 8);
97 :
- 98 2194602 : tommy_mix(a, b, c);
+ 98 2194576 : tommy_mix(a, b, c);
99 :
- 100 2194602 : key_len -= 12;
- 101 2194602 : key += 12;
+ 100 2194576 : key_len -= 12;
+ 101 2194576 : key += 12;
102 : }
103 :
- 104 4205922 : switch (key_len) {
+ 104 4205889 : switch (key_len) {
105 1 : case 0 :
106 1 : return c; /* used only when called with a zero length */
- 107 214636 : case 12 :
- 108 214636 : c += tommy_le_uint32_read(key + 8);
- 109 214636 : b += tommy_le_uint32_read(key + 4);
- 110 214636 : a += tommy_le_uint32_read(key + 0);
- 111 214636 : break;
- 112 224879 : case 11 : c += ((tommy_uint32_t)key[10]) << 16; /* fallthrough */
- 113 662895 : case 10 : c += ((tommy_uint32_t)key[9]) << 8; /* fallthrough */
- 114 1097631 : case 9 : c += key[8]; /* fallthrough */
- 115 1523522 : case 8 :
- 116 1523522 : b += tommy_le_uint32_read(key + 4);
- 117 1523522 : a += tommy_le_uint32_read(key + 0);
- 118 1523522 : break;
- 119 428407 : case 7 : b += ((tommy_uint32_t)key[6]) << 16; /* fallthrough */
- 120 842490 : case 6 : b += ((tommy_uint32_t)key[5]) << 8; /* fallthrough */
- 121 1274225 : case 5 : b += key[4]; /* fallthrough */
- 122 1721682 : case 4 :
- 123 1721682 : a += tommy_le_uint32_read(key + 0);
- 124 1721682 : break;
- 125 313312 : case 3 : a += ((tommy_uint32_t)key[2]) << 16; /* fallthrough */
- 126 528569 : case 2 : a += ((tommy_uint32_t)key[1]) << 8; /* fallthrough */
- 127 746081 : case 1 : a += key[0]; /* fallthrough */
+ 107 214618 : case 12 :
+ 108 214618 : c += tommy_le_uint32_read(key + 8);
+ 109 214618 : b += tommy_le_uint32_read(key + 4);
+ 110 214618 : a += tommy_le_uint32_read(key + 0);
+ 111 214618 : break;
+ 112 224880 : case 11 : c += ((tommy_uint32_t)key[10]) << 16; /* fallthrough */
+ 113 662911 : case 10 : c += ((tommy_uint32_t)key[9]) << 8; /* fallthrough */
+ 114 1097644 : case 9 : c += key[8]; /* fallthrough */
+ 115 1523549 : case 8 :
+ 116 1523549 : b += tommy_le_uint32_read(key + 4);
+ 117 1523549 : a += tommy_le_uint32_read(key + 0);
+ 118 1523549 : break;
+ 119 428404 : case 7 : b += ((tommy_uint32_t)key[6]) << 16; /* fallthrough */
+ 120 842492 : case 6 : b += ((tommy_uint32_t)key[5]) << 8; /* fallthrough */
+ 121 1274173 : case 5 : b += key[4]; /* fallthrough */
+ 122 1721656 : case 4 :
+ 123 1721656 : a += tommy_le_uint32_read(key + 0);
+ 124 1721656 : break;
+ 125 313308 : case 3 : a += ((tommy_uint32_t)key[2]) << 16; /* fallthrough */
+ 126 528545 : case 2 : a += ((tommy_uint32_t)key[1]) << 8; /* fallthrough */
+ 127 746065 : case 1 : a += key[0]; /* fallthrough */
128 : }
129 :
- 130 4205921 : tommy_final(a, b, c);
+ 130 4205888 : tommy_final(a, b, c);
131 :
- 132 4205921 : return c;
+ 132 4205888 : return c;
133 : }
134 :
135 19 : TOMMY_API 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 9177d23f..325e12f7 100644
--- a/cov/tommyds/tommyhash.h.func-sort-c.html
+++ b/cov/tommyds/tommyhash.h.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,11 +61,11 @@
| tommy_inthash_u64 |
- 5292402 |
+ 5276850 |
| tommy_inthash_u32 |
- 19170915 |
+ 19171890 |
diff --git a/cov/tommyds/tommyhash.h.func.html b/cov/tommyds/tommyhash.h.func.html
index 80297889..dd0802d6 100644
--- a/cov/tommyds/tommyhash.h.func.html
+++ b/cov/tommyds/tommyhash.h.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,11 +61,11 @@
| tommy_inthash_u32 |
- 19170915 |
+ 19171890 |
| tommy_inthash_u64 |
- 5292402 |
+ 5276850 |
diff --git a/cov/tommyds/tommyhash.h.gcov.html b/cov/tommyds/tommyhash.h.gcov.html
index 68d6e103..7d72ea35 100644
--- a/cov/tommyds/tommyhash.h.gcov.html
+++ b/cov/tommyds/tommyhash.h.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -162,17 +162,17 @@
100 : * Implementation of the Robert Jenkins "4-byte Integer Hashing",
101 : * from http://burtleburtle.net/bob/hash/integer.html
102 : */
- 103 19170915 : tommy_inline tommy_uint32_t tommy_inthash_u32(tommy_uint32_t key)
+ 103 19171890 : tommy_inline tommy_uint32_t tommy_inthash_u32(tommy_uint32_t key)
104 : {
- 105 19170915 : key -= key << 6;
- 106 19170915 : key ^= key >> 17;
- 107 19170915 : key -= key << 9;
- 108 19170915 : key ^= key << 4;
- 109 19170915 : key -= key << 3;
- 110 19170915 : key ^= key << 10;
- 111 19170915 : key ^= key >> 15;
+ 105 19171890 : key -= key << 6;
+ 106 19171890 : key ^= key >> 17;
+ 107 19171890 : key -= key << 9;
+ 108 19171890 : key ^= key << 4;
+ 109 19171890 : key -= key << 3;
+ 110 19171890 : key ^= key << 10;
+ 111 19171890 : key ^= key >> 15;
112 :
- 113 19170915 : return key;
+ 113 19171890 : return key;
114 : }
115 :
116 : /**
@@ -180,17 +180,17 @@
118 : * Implementation of the Thomas Wang "Integer Hash Function",
119 : * from http://web.archive.org/web/20071223173210/http://www.concentric.net/~Ttwang/tech/inthash.htm
120 : */
- 121 5292402 : tommy_inline tommy_uint64_t tommy_inthash_u64(tommy_uint64_t key)
+ 121 5276850 : tommy_inline tommy_uint64_t tommy_inthash_u64(tommy_uint64_t key)
122 : {
- 123 5292402 : key = ~key + (key << 21);
- 124 5292402 : key = key ^ (key >> 24);
- 125 5292402 : key = key + (key << 3) + (key << 8);
- 126 5292402 : key = key ^ (key >> 14);
- 127 5292402 : key = key + (key << 2) + (key << 4);
- 128 5292402 : key = key ^ (key >> 28);
- 129 5292402 : key = key + (key << 31);
+ 123 5276850 : key = ~key + (key << 21);
+ 124 5276850 : key = key ^ (key >> 24);
+ 125 5276850 : key = key + (key << 3) + (key << 8);
+ 126 5276850 : key = key ^ (key >> 14);
+ 127 5276850 : key = key + (key << 2) + (key << 4);
+ 128 5276850 : key = key ^ (key >> 28);
+ 129 5276850 : key = key + (key << 31);
130 :
- 131 5292402 : return key;
+ 131 5276850 : return key;
132 : }
133 :
134 : #endif
diff --git a/cov/tommyds/tommyhashdyn.c.func-sort-c.html b/cov/tommyds/tommyhashdyn.c.func-sort-c.html
index 4be71c95..ab483979 100644
--- a/cov/tommyds/tommyhashdyn.c.func-sort-c.html
+++ b/cov/tommyds/tommyhashdyn.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -73,39 +73,39 @@
| tommy_hashdyn_foreach |
- 275 |
+ 276 |
| tommy_hashdyn_to_list |
- 421 |
+ 420 |
| tommy_hashdyn_done |
- 9247 |
+ 9299 |
| tommy_hashdyn_init |
- 9581 |
+ 9633 |
| tommy_hashdyn_resize |
- 43338 |
+ 43341 |
| tommy_hashdyn_remove_existing |
- 280123 |
+ 280572 |
| hashdyn_shrink_step |
- 280251 |
+ 280700 |
| hashdyn_grow_step |
- 13595041 |
+ 13595618 |
| tommy_hashdyn_insert |
- 13595041 |
+ 13595618 |
diff --git a/cov/tommyds/tommyhashdyn.c.func.html b/cov/tommyds/tommyhashdyn.c.func.html
index a6284c18..00462fa3 100644
--- a/cov/tommyds/tommyhashdyn.c.func.html
+++ b/cov/tommyds/tommyhashdyn.c.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,19 +61,19 @@
| hashdyn_grow_step |
- 13595041 |
+ 13595618 |
| hashdyn_shrink_step |
- 280251 |
+ 280700 |
| tommy_hashdyn_done |
- 9247 |
+ 9299 |
| tommy_hashdyn_foreach |
- 275 |
+ 276 |
| tommy_hashdyn_foreach_arg |
@@ -81,11 +81,11 @@
| tommy_hashdyn_init |
- 9581 |
+ 9633 |
| tommy_hashdyn_insert |
- 13595041 |
+ 13595618 |
| tommy_hashdyn_memory_usage |
@@ -97,15 +97,15 @@
| tommy_hashdyn_remove_existing |
- 280123 |
+ 280572 |
| tommy_hashdyn_resize |
- 43338 |
+ 43341 |
| tommy_hashdyn_to_list |
- 421 |
+ 420 |
diff --git a/cov/tommyds/tommyhashdyn.c.gcov.html b/cov/tommyds/tommyhashdyn.c.gcov.html
index 7b23c703..8510055e 100644
--- a/cov/tommyds/tommyhashdyn.c.gcov.html
+++ b/cov/tommyds/tommyhashdyn.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -93,26 +93,26 @@
31 : /******************************************************************************/
32 : /* hashdyn */
33 :
- 34 9581 : TOMMY_API void tommy_hashdyn_init(tommy_hashdyn* hashdyn)
+ 34 9633 : TOMMY_API void tommy_hashdyn_init(tommy_hashdyn* hashdyn)
35 : {
36 : /* fixed initial size */
- 37 9581 : hashdyn->bucket_bit = TOMMY_HASHDYN_BIT;
- 38 9581 : hashdyn->bucket_max = (tommy_size_t)1 << hashdyn->bucket_bit;
- 39 9581 : hashdyn->bucket_mask = hashdyn->bucket_max - 1;
- 40 9581 : hashdyn->bucket = tommy_cast(tommy_hashdyn_node**, tommy_calloc(hashdyn->bucket_max, sizeof(tommy_hashdyn_node*)));
+ 37 9633 : hashdyn->bucket_bit = TOMMY_HASHDYN_BIT;
+ 38 9633 : hashdyn->bucket_max = (tommy_size_t)1 << hashdyn->bucket_bit;
+ 39 9633 : hashdyn->bucket_mask = hashdyn->bucket_max - 1;
+ 40 9633 : hashdyn->bucket = tommy_cast(tommy_hashdyn_node**, tommy_calloc(hashdyn->bucket_max, sizeof(tommy_hashdyn_node*)));
41 :
- 42 9581 : hashdyn->count = 0;
- 43 9581 : }
+ 42 9633 : hashdyn->count = 0;
+ 43 9633 : }
44 :
- 45 9247 : TOMMY_API void tommy_hashdyn_done(tommy_hashdyn* hashdyn)
+ 45 9299 : TOMMY_API void tommy_hashdyn_done(tommy_hashdyn* hashdyn)
46 : {
- 47 9247 : tommy_free(hashdyn->bucket);
- 48 9247 : }
+ 47 9299 : tommy_free(hashdyn->bucket);
+ 48 9299 : }
49 :
50 : /**
51 : * Resize the bucket vector.
52 : */
- 53 43338 : static void tommy_hashdyn_resize(tommy_hashdyn* hashdyn, tommy_uint_t new_bucket_bit)
+ 53 43341 : static void tommy_hashdyn_resize(tommy_hashdyn* hashdyn, tommy_uint_t new_bucket_bit)
54 : {
55 : tommy_size_t bucket_bit;
56 : tommy_size_t bucket_max;
@@ -120,38 +120,38 @@
58 : tommy_size_t new_bucket_mask;
59 : tommy_hashdyn_node** new_bucket;
60 :
- 61 43338 : bucket_bit = hashdyn->bucket_bit;
- 62 43338 : bucket_max = hashdyn->bucket_max;
+ 61 43341 : bucket_bit = hashdyn->bucket_bit;
+ 62 43341 : bucket_max = hashdyn->bucket_max;
63 :
- 64 43338 : new_bucket_max = (tommy_size_t)1 << new_bucket_bit;
- 65 43338 : new_bucket_mask = new_bucket_max - 1;
+ 64 43341 : new_bucket_max = (tommy_size_t)1 << new_bucket_bit;
+ 65 43341 : 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 43338 : new_bucket = tommy_cast(tommy_hashdyn_node**, tommy_malloc(new_bucket_max * sizeof(tommy_hashdyn_node*)));
+ 69 43341 : new_bucket = tommy_cast(tommy_hashdyn_node**, tommy_malloc(new_bucket_max * sizeof(tommy_hashdyn_node*)));
70 :
71 : /* reinsert all the elements */
- 72 43338 : if (new_bucket_bit > bucket_bit) {
+ 72 43341 : if (new_bucket_bit > bucket_bit) {
73 : tommy_size_t i;
74 :
75 : /* grow */
- 76 32995971 : for (i = 0; i < bucket_max; ++i) {
+ 76 32996166 : for (i = 0; i < bucket_max; ++i) {
77 : tommy_hashdyn_node* j;
78 :
79 : /* setup the new two buckets */
- 80 32952688 : new_bucket[i] = 0;
- 81 32952688 : new_bucket[i + bucket_max] = 0;
+ 80 32952880 : new_bucket[i] = 0;
+ 81 32952880 : new_bucket[i + bucket_max] = 0;
82 :
83 : /* reinsert the bucket */
- 84 32952688 : j = hashdyn->bucket[i];
- 85 49429032 : while (j) {
- 86 16476344 : tommy_hashdyn_node* j_next = j->next;
- 87 16476344 : tommy_size_t pos = j->index & new_bucket_mask;
- 88 16476344 : if (new_bucket[pos])
- 89 1933530 : tommy_list_insert_tail_not_empty(new_bucket[pos], j);
+ 84 32952880 : j = hashdyn->bucket[i];
+ 85 49429320 : while (j) {
+ 86 16476440 : tommy_hashdyn_node* j_next = j->next;
+ 87 16476440 : tommy_size_t pos = j->index & new_bucket_mask;
+ 88 16476440 : if (new_bucket[pos])
+ 89 1945137 : tommy_list_insert_tail_not_empty(new_bucket[pos], j);
90 : else
- 91 14542814 : tommy_list_insert_first(&new_bucket[pos], j);
- 92 16476344 : j = j_next;
+ 91 14531303 : tommy_list_insert_first(&new_bucket[pos], j);
+ 92 16476440 : j = j_next;
93 : }
94 : }
95 : } else {
@@ -167,59 +167,59 @@
105 : }
106 : }
107 :
- 108 43338 : tommy_free(hashdyn->bucket);
+ 108 43341 : tommy_free(hashdyn->bucket);
109 :
110 : /* setup */
- 111 43338 : hashdyn->bucket_bit = new_bucket_bit;
- 112 43338 : hashdyn->bucket_max = new_bucket_max;
- 113 43338 : hashdyn->bucket_mask = new_bucket_mask;
- 114 43338 : hashdyn->bucket = new_bucket;
- 115 43338 : }
+ 111 43341 : hashdyn->bucket_bit = new_bucket_bit;
+ 112 43341 : hashdyn->bucket_max = new_bucket_max;
+ 113 43341 : hashdyn->bucket_mask = new_bucket_mask;
+ 114 43341 : hashdyn->bucket = new_bucket;
+ 115 43341 : }
116 :
117 : /**
118 : * Grow.
119 : */
- 120 13595041 : tommy_inline void hashdyn_grow_step(tommy_hashdyn* hashdyn)
+ 120 13595618 : tommy_inline void hashdyn_grow_step(tommy_hashdyn* hashdyn)
121 : {
122 : /* grow if more than 50% full */
- 123 13595041 : if (hashdyn->count >= hashdyn->bucket_max / 2)
- 124 43283 : tommy_hashdyn_resize(hashdyn, hashdyn->bucket_bit + 1);
- 125 13595041 : }
+ 123 13595618 : if (hashdyn->count >= hashdyn->bucket_max / 2)
+ 124 43286 : tommy_hashdyn_resize(hashdyn, hashdyn->bucket_bit + 1);
+ 125 13595618 : }
126 :
127 : /**
128 : * Shrink.
129 : */
- 130 280251 : tommy_inline void hashdyn_shrink_step(tommy_hashdyn* hashdyn)
+ 130 280700 : tommy_inline void hashdyn_shrink_step(tommy_hashdyn* hashdyn)
131 : {
132 : /* shrink if less than 12.5% full */
- 133 280251 : if (hashdyn->count <= hashdyn->bucket_max / 8 && hashdyn->bucket_bit > TOMMY_HASHDYN_BIT)
+ 133 280700 : if (hashdyn->count <= hashdyn->bucket_max / 8 && hashdyn->bucket_bit > TOMMY_HASHDYN_BIT)
134 55 : tommy_hashdyn_resize(hashdyn, hashdyn->bucket_bit - 1);
- 135 280251 : }
+ 135 280700 : }
136 :
- 137 13595041 : TOMMY_API void tommy_hashdyn_insert(tommy_hashdyn* hashdyn, tommy_hashdyn_node* node, void* data, tommy_hash_t hash)
+ 137 13595618 : TOMMY_API void tommy_hashdyn_insert(tommy_hashdyn* hashdyn, tommy_hashdyn_node* node, void* data, tommy_hash_t hash)
138 : {
- 139 13595041 : tommy_size_t pos = hash & hashdyn->bucket_mask;
+ 139 13595618 : tommy_size_t pos = hash & hashdyn->bucket_mask;
140 :
- 141 13595041 : tommy_list_insert_tail(&hashdyn->bucket[pos], node, data);
+ 141 13595618 : tommy_list_insert_tail(&hashdyn->bucket[pos], node, data);
142 :
- 143 13595041 : node->index = hash;
+ 143 13595618 : node->index = hash;
144 :
- 145 13595041 : ++hashdyn->count;
+ 145 13595618 : ++hashdyn->count;
146 :
- 147 13595041 : hashdyn_grow_step(hashdyn);
- 148 13595041 : }
+ 147 13595618 : hashdyn_grow_step(hashdyn);
+ 148 13595618 : }
149 :
- 150 280123 : TOMMY_API void* tommy_hashdyn_remove_existing(tommy_hashdyn* hashdyn, tommy_hashdyn_node* node)
+ 150 280572 : TOMMY_API void* tommy_hashdyn_remove_existing(tommy_hashdyn* hashdyn, tommy_hashdyn_node* node)
151 : {
- 152 280123 : tommy_size_t pos = node->index & hashdyn->bucket_mask;
+ 152 280572 : tommy_size_t pos = node->index & hashdyn->bucket_mask;
153 :
- 154 280123 : tommy_list_remove_existing(&hashdyn->bucket[pos], node);
+ 154 280572 : tommy_list_remove_existing(&hashdyn->bucket[pos], node);
155 :
- 156 280123 : --hashdyn->count;
+ 156 280572 : --hashdyn->count;
157 :
- 158 280123 : hashdyn_shrink_step(hashdyn);
+ 158 280572 : hashdyn_shrink_step(hashdyn);
159 :
- 160 280123 : return node->data;
+ 160 280572 : return node->data;
161 : }
162 :
163 256 : TOMMY_API void* tommy_hashdyn_remove(tommy_hashdyn* hashdyn, tommy_search_func* cmp, const void* cmp_arg, tommy_hash_t hash)
@@ -244,22 +244,22 @@
182 128 : return 0;
183 : }
184 :
- 185 275 : TOMMY_API void tommy_hashdyn_foreach(tommy_hashdyn* hashdyn, tommy_foreach_func* func)
+ 185 276 : TOMMY_API void tommy_hashdyn_foreach(tommy_hashdyn* hashdyn, tommy_foreach_func* func)
186 : {
- 187 275 : tommy_size_t bucket_max = hashdyn->bucket_max;
- 188 275 : tommy_hashdyn_node** bucket = hashdyn->bucket;
+ 187 276 : tommy_size_t bucket_max = hashdyn->bucket_max;
+ 188 276 : tommy_hashdyn_node** bucket = hashdyn->bucket;
189 : tommy_size_t pos;
190 :
- 191 5813251 : for (pos = 0; pos < bucket_max; ++pos) {
- 192 5812976 : tommy_hashdyn_node* node = bucket[pos];
+ 191 5813268 : for (pos = 0; pos < bucket_max; ++pos) {
+ 192 5812992 : tommy_hashdyn_node* node = bucket[pos];
193 :
- 194 7674048 : while (node) {
- 195 1861072 : void* data = node->data;
- 196 1861072 : node = node->next;
- 197 1861072 : func(data);
+ 194 7674121 : while (node) {
+ 195 1861129 : void* data = node->data;
+ 196 1861129 : node = node->next;
+ 197 1861129 : func(data);
198 : }
199 : }
- 200 275 : }
+ 200 276 : }
201 :
202 4 : TOMMY_API void tommy_hashdyn_foreach_arg(tommy_hashdyn* hashdyn, tommy_foreach_arg_func* func, void* arg)
203 : {
@@ -321,27 +321,27 @@
259 : * \param hashdyn The dynamic hashtable to drain
260 : * \param list The list that will receive all the elements
261 : */
- 262 421 : TOMMY_API void tommy_hashdyn_to_list(tommy_hashdyn* hashdyn, tommy_list* list)
+ 262 420 : TOMMY_API void tommy_hashdyn_to_list(tommy_hashdyn* hashdyn, tommy_list* list)
263 : {
- 264 421 : tommy_size_t bucket_max = hashdyn->bucket_max;
- 265 421 : tommy_hashdyn_node** bucket = hashdyn->bucket;
+ 264 420 : tommy_size_t bucket_max = hashdyn->bucket_max;
+ 265 420 : tommy_hashdyn_node** bucket = hashdyn->bucket;
266 : tommy_size_t pos;
267 :
268 : /* move everything to the list */
- 269 7157 : for (pos = 0; pos < bucket_max; ++pos) {
- 270 6736 : tommy_hashdyn_node* node = bucket[pos];
+ 269 7140 : for (pos = 0; pos < bucket_max; ++pos) {
+ 270 6720 : tommy_hashdyn_node* node = bucket[pos];
271 :
- 272 7492 : while (node) {
- 273 756 : tommy_node* node_next = node->next;
- 274 756 : tommy_list_insert_tail(list, node, node->data);
- 275 756 : node = node_next;
+ 272 7436 : while (node) {
+ 273 716 : tommy_node* node_next = node->next;
+ 274 716 : tommy_list_insert_tail(list, node, node->data);
+ 275 716 : node = node_next;
276 : }
277 : }
278 :
279 : /* clear all */
- 280 421 : memset(hashdyn->bucket, 0, hashdyn->bucket_max * sizeof(tommy_hashdyn_node*));
- 281 421 : hashdyn->count = 0;
- 282 421 : }
+ 280 420 : memset(hashdyn->bucket, 0, hashdyn->bucket_max * sizeof(tommy_hashdyn_node*));
+ 281 420 : hashdyn->count = 0;
+ 282 420 : }
diff --git a/cov/tommyds/tommyhashdyn.h.func-sort-c.html b/cov/tommyds/tommyhashdyn.h.func-sort-c.html
index 70e1c5bf..35bd3f06 100644
--- a/cov/tommyds/tommyhashdyn.h.func-sort-c.html
+++ b/cov/tommyds/tommyhashdyn.h.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,15 +61,15 @@
| tommy_hashdyn_count |
- 424 |
+ 423 |
| tommy_hashdyn_search |
- 3175958 |
+ 3176368 |
| tommy_hashdyn_bucket |
- 3248010 |
+ 3232326 |
diff --git a/cov/tommyds/tommyhashdyn.h.func.html b/cov/tommyds/tommyhashdyn.h.func.html
index d7632067..63206825 100644
--- a/cov/tommyds/tommyhashdyn.h.func.html
+++ b/cov/tommyds/tommyhashdyn.h.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,15 +61,15 @@
| tommy_hashdyn_bucket |
- 3248010 |
+ 3232326 |
| tommy_hashdyn_count |
- 424 |
+ 423 |
| tommy_hashdyn_search |
- 3175958 |
+ 3176368 |
diff --git a/cov/tommyds/tommyhashdyn.h.gcov.html b/cov/tommyds/tommyhashdyn.h.gcov.html
index 54b99c47..0226753f 100644
--- a/cov/tommyds/tommyhashdyn.h.gcov.html
+++ b/cov/tommyds/tommyhashdyn.h.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -267,9 +267,9 @@
205 : * \param hash Hash of the element to find.
206 : * \return The head of the bucket, or 0 if empty.
207 : */
- 208 3248010 : tommy_inline tommy_hashdyn_node* tommy_hashdyn_bucket(tommy_hashdyn* hashdyn, tommy_hash_t hash)
+ 208 3232326 : tommy_inline tommy_hashdyn_node* tommy_hashdyn_bucket(tommy_hashdyn* hashdyn, tommy_hash_t hash)
209 : {
- 210 3248010 : return hashdyn->bucket[hash & hashdyn->bucket_mask];
+ 210 3232326 : 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 3175958 : tommy_inline void* tommy_hashdyn_search(tommy_hashdyn* hashdyn, tommy_search_func* cmp, const void* cmp_arg, tommy_hash_t hash)
+ 223 3176368 : tommy_inline void* tommy_hashdyn_search(tommy_hashdyn* hashdyn, tommy_search_func* cmp, const void* cmp_arg, tommy_hash_t hash)
224 : {
- 225 3175958 : tommy_hashdyn_node* i = tommy_hashdyn_bucket(hashdyn, hash);
+ 225 3176368 : tommy_hashdyn_node* i = tommy_hashdyn_bucket(hashdyn, hash);
226 :
- 227 3864355 : while (i) {
+ 227 3868088 : while (i) {
228 : /* we first check if the hash matches, as in the same bucket we may have multiple hash values */
- 229 1917649 : if (i->index == hash && cmp(cmp_arg, i->data) == 0)
- 230 1229252 : return i->data;
- 231 688397 : i = i->next;
+ 229 1923487 : if (i->index == hash && cmp(cmp_arg, i->data) == 0)
+ 230 1231767 : return i->data;
+ 231 691720 : i = i->next;
232 : }
- 233 1946706 : return 0;
+ 233 1944601 : return 0;
234 : }
235 :
236 : /**
@@ -343,9 +343,9 @@
281 : /**
282 : * Gets the number of elements.
283 : */
- 284 424 : tommy_inline tommy_size_t tommy_hashdyn_count(tommy_hashdyn* hashdyn)
+ 284 423 : tommy_inline tommy_size_t tommy_hashdyn_count(tommy_hashdyn* hashdyn)
285 : {
- 286 424 : return hashdyn->count;
+ 286 423 : return hashdyn->count;
287 : }
288 :
289 : /**
diff --git a/cov/tommyds/tommylist.c.func-sort-c.html b/cov/tommyds/tommylist.c.func-sort-c.html
index 9c7ad4b0..9a255f4a 100644
--- a/cov/tommyds/tommylist.c.func-sort-c.html
+++ b/cov/tommyds/tommylist.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,11 +61,11 @@
| tommy_list_set |
- 2198 |
+ 2196 |
| tommy_list_sort |
- 3052 |
+ 3051 |
diff --git a/cov/tommyds/tommylist.c.func.html b/cov/tommyds/tommylist.c.func.html
index 99238bf2..b59b484b 100644
--- a/cov/tommyds/tommylist.c.func.html
+++ b/cov/tommyds/tommylist.c.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,11 +61,11 @@
| tommy_list_set |
- 2198 |
+ 2196 |
| tommy_list_sort |
- 3052 |
+ 3051 |
diff --git a/cov/tommyds/tommylist.c.gcov.html b/cov/tommyds/tommylist.c.gcov.html
index c036b347..bae8f6cb 100644
--- a/cov/tommyds/tommylist.c.gcov.html
+++ b/cov/tommyds/tommylist.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -93,31 +93,31 @@
31 : /** \internal
32 : * Setup a list.
33 : */
- 34 2198 : tommy_inline void tommy_list_set(tommy_list* list, tommy_node* head, tommy_node* tail)
+ 34 2196 : tommy_inline void tommy_list_set(tommy_list* list, tommy_node* head, tommy_node* tail)
35 : {
- 36 2198 : head->prev = tail;
- 37 2198 : tail->next = 0;
- 38 2198 : *list = head;
- 39 2198 : }
+ 36 2196 : head->prev = tail;
+ 37 2196 : tail->next = 0;
+ 38 2196 : *list = head;
+ 39 2196 : }
40 :
- 41 3052 : TOMMY_API void tommy_list_sort(tommy_list* list, tommy_compare_func* cmp)
+ 41 3051 : TOMMY_API void tommy_list_sort(tommy_list* list, tommy_compare_func* cmp)
42 : {
43 : tommy_chain chain;
44 : tommy_node* head;
45 :
- 46 3052 : if (tommy_list_empty(list))
- 47 854 : return;
+ 46 3051 : if (tommy_list_empty(list))
+ 47 855 : return;
48 :
- 49 2198 : head = tommy_list_head(list);
+ 49 2196 : head = tommy_list_head(list);
50 :
51 : /* create a chain from the list */
- 52 2198 : chain.head = head;
- 53 2198 : chain.tail = head->prev;
+ 52 2196 : chain.head = head;
+ 53 2196 : chain.tail = head->prev;
54 :
- 55 2198 : tommy_chain_mergesort(&chain, cmp);
+ 55 2196 : tommy_chain_mergesort(&chain, cmp);
56 :
57 : /* restore the list */
- 58 2198 : tommy_list_set(list, chain.head, chain.tail);
+ 58 2196 : 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 22e8ad7a..97ad0d68 100644
--- a/cov/tommyds/tommylist.h.func-sort-c.html
+++ b/cov/tommyds/tommylist.h.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -73,15 +73,15 @@
| tommy_list_empty |
- 7447 |
+ 7444 |
| tommy_list_foreach |
- 14796 |
+ 14846 |
| tommy_list_init |
- 18934 |
+ 18984 |
| tommy_list_concat |
@@ -89,23 +89,23 @@
| tommy_list_remove_existing |
- 336440 |
+ 336876 |
| tommy_list_insert_tail_not_empty |
- 11532222 |
+ 11558516 |
| tommy_list_insert_tail |
- 19084521 |
+ 19085101 |
| tommy_list_insert_first |
- 24028643 |
+ 24003025 |
| tommy_list_head |
- 27439506 |
+ 27440663 |
diff --git a/cov/tommyds/tommylist.h.func.html b/cov/tommyds/tommylist.h.func.html
index 42cf83a0..6193477a 100644
--- a/cov/tommyds/tommylist.h.func.html
+++ b/cov/tommyds/tommylist.h.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -69,11 +69,11 @@
| tommy_list_empty |
- 7447 |
+ 7444 |
| tommy_list_foreach |
- 14796 |
+ 14846 |
| tommy_list_foreach_arg |
@@ -81,27 +81,27 @@
| tommy_list_head |
- 27439506 |
+ 27440663 |
| tommy_list_init |
- 18934 |
+ 18984 |
| tommy_list_insert_first |
- 24028643 |
+ 24003025 |
| tommy_list_insert_tail |
- 19084521 |
+ 19085101 |
| tommy_list_insert_tail_not_empty |
- 11532222 |
+ 11558516 |
| tommy_list_remove_existing |
- 336440 |
+ 336876 |
| tommy_list_tail |
diff --git a/cov/tommyds/tommylist.h.gcov.html b/cov/tommyds/tommylist.h.gcov.html
index 23f948b5..40632480 100644
--- a/cov/tommyds/tommylist.h.gcov.html
+++ b/cov/tommyds/tommylist.h.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -173,18 +173,18 @@
111 : * Initializes the list.
112 : * The list is completely inplace, so it doesn't need to be deinitialized.
113 : */
- 114 18934 : tommy_inline void tommy_list_init(tommy_list* list)
+ 114 18984 : tommy_inline void tommy_list_init(tommy_list* list)
115 : {
- 116 18934 : *list = 0;
- 117 18934 : }
+ 116 18984 : *list = 0;
+ 117 18984 : }
118 :
119 : /**
120 : * Gets the head of the list.
121 : * \return The head node. For empty lists 0 is returned.
122 : */
- 123 27439506 : tommy_inline tommy_node* tommy_list_head(tommy_list* list)
+ 123 27440663 : tommy_inline tommy_node* tommy_list_head(tommy_list* list)
124 : {
- 125 27439506 : return *list;
+ 125 27440663 : 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 24028643 : tommy_inline void tommy_list_insert_first(tommy_list* list, tommy_node* node)
+ 147 24003025 : tommy_inline void tommy_list_insert_first(tommy_list* list, tommy_node* node)
148 : {
149 : /* one element "circular" prev list */
- 150 24028643 : node->prev = node;
+ 150 24003025 : node->prev = node;
151 :
152 : /* one element "0 terminated" next list */
- 153 24028643 : node->next = 0;
+ 153 24003025 : node->next = 0;
154 :
- 155 24028643 : *list = node;
- 156 24028643 : }
+ 155 24003025 : *list = node;
+ 156 24003025 : }
157 :
158 : /** \internal
159 : * Inserts an element at the head of a non-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 11532222 : tommy_inline void tommy_list_insert_tail_not_empty(tommy_node* head, tommy_node* node)
+ 184 11558516 : tommy_inline void tommy_list_insert_tail_not_empty(tommy_node* head, tommy_node* node)
185 : {
186 : /* insert in the "circular" prev list */
- 187 11532222 : node->prev = head->prev;
- 188 11532222 : head->prev = node;
+ 187 11558516 : node->prev = head->prev;
+ 188 11558516 : head->prev = node;
189 :
190 : /* insert in the "0 terminated" next list */
- 191 11532222 : node->next = 0;
- 192 11532222 : node->prev->next = node;
- 193 11532222 : }
+ 191 11558516 : node->next = 0;
+ 192 11558516 : node->prev->next = node;
+ 193 11558516 : }
194 :
195 : /**
196 : * Inserts an element at the head of a list.
@@ -278,17 +278,17 @@
216 : * \param node The node to insert.
217 : * \param data The object containing the node. It's used to set the tommy_node::data field of the node.
218 : */
- 219 19084521 : tommy_inline void tommy_list_insert_tail(tommy_list* list, tommy_node* node, void* data)
+ 219 19085101 : tommy_inline void tommy_list_insert_tail(tommy_list* list, tommy_node* node, void* data)
220 : {
- 221 19084521 : tommy_node* head = tommy_list_head(list);
+ 221 19085101 : tommy_node* head = tommy_list_head(list);
222 :
- 223 19084521 : if (head)
- 224 9598692 : tommy_list_insert_tail_not_empty(head, node);
+ 223 19085101 : if (head)
+ 224 9613379 : tommy_list_insert_tail_not_empty(head, node);
225 : else
- 226 9485829 : tommy_list_insert_first(list, node);
+ 226 9471722 : tommy_list_insert_first(list, node);
227 :
- 228 19084521 : node->data = data;
- 229 19084521 : }
+ 228 19085101 : node->data = data;
+ 229 19085101 : }
230 :
231 : /**
232 : * Removes an element from the list.
@@ -299,23 +299,23 @@
237 : * \param node The node to remove. The node must be in the list.
238 : * \return The tommy_node::data field of the node removed.
239 : */
- 240 336440 : tommy_inline void* tommy_list_remove_existing(tommy_list* list, tommy_node* node)
+ 240 336876 : tommy_inline void* tommy_list_remove_existing(tommy_list* list, tommy_node* node)
241 : {
- 242 336440 : tommy_node* head = tommy_list_head(list);
+ 242 336876 : tommy_node* head = tommy_list_head(list);
243 :
244 : /* remove from the "circular" prev list */
- 245 336440 : if (node->next)
- 246 114378 : node->next->prev = node->prev;
+ 245 336876 : if (node->next)
+ 246 114609 : node->next->prev = node->prev;
247 : else
- 248 222062 : head->prev = node->prev; /* the last */
+ 248 222267 : head->prev = node->prev; /* the last */
249 :
250 : /* remove from the "0 terminated" next list */
- 251 336440 : if (head == node)
- 252 238235 : *list = node->next; /* the new head, in case 0 */
+ 251 336876 : if (head == node)
+ 252 238682 : *list = node->next; /* the new head, in case 0 */
253 : else
- 254 98205 : node->prev->next = node->next;
+ 254 98194 : node->prev->next = node->next;
255 :
- 256 336440 : return node->data;
+ 256 336876 : return node->data;
257 : }
258 :
259 : /**
@@ -334,24 +334,24 @@
272 : /* if the second is empty, nothing to do */
273 79280 : second_head = tommy_list_head(second);
274 79280 : if (second_head == 0)
- 275 69889 : return;
+ 275 70071 : return;
276 :
277 : /* if the first is empty, copy the second */
- 278 9391 : first_head = tommy_list_head(first);
- 279 9391 : if (first_head == 0) {
- 280 8317 : *first = *second;
- 281 8317 : return;
+ 278 9209 : first_head = tommy_list_head(first);
+ 279 9209 : if (first_head == 0) {
+ 280 8162 : *first = *second;
+ 281 8162 : return;
282 : }
283 :
284 : /* tail of the first list */
- 285 1074 : first_tail = first_head->prev;
+ 285 1047 : first_tail = first_head->prev;
286 :
287 : /* set the "circular" prev list */
- 288 1074 : first_head->prev = second_head->prev;
- 289 1074 : second_head->prev = first_tail;
+ 288 1047 : first_head->prev = second_head->prev;
+ 289 1047 : second_head->prev = first_tail;
290 :
291 : /* set the "0 terminated" next list */
- 292 1074 : first_tail->next = second_head;
+ 292 1047 : first_tail->next = second_head;
293 : }
294 :
295 : /**
@@ -367,9 +367,9 @@
305 : * Checks if empty.
306 : * \return If the list is empty.
307 : */
- 308 7447 : tommy_inline tommy_bool_t tommy_list_empty(tommy_list* list)
+ 308 7444 : tommy_inline tommy_bool_t tommy_list_empty(tommy_list* list)
309 : {
- 310 7447 : return tommy_list_head(list) == 0;
+ 310 7444 : return tommy_list_head(list) == 0;
311 : }
312 :
313 : /**
@@ -417,16 +417,16 @@
355 : * tommy_list_foreach(&list, free);
356 : * \endcode
357 : */
- 358 14796 : tommy_inline void tommy_list_foreach(tommy_list* list, tommy_foreach_func* func)
+ 358 14846 : tommy_inline void tommy_list_foreach(tommy_list* list, tommy_foreach_func* func)
359 : {
- 360 14796 : tommy_node* node = tommy_list_head(list);
+ 360 14846 : tommy_node* node = tommy_list_head(list);
361 :
- 362 4108729 : while (node) {
- 363 4093933 : void* data = node->data;
- 364 4093933 : node = node->next;
- 365 4093933 : func(data);
+ 362 4108770 : while (node) {
+ 363 4093924 : void* data = node->data;
+ 364 4093924 : node = node->next;
+ 365 4093924 : func(data);
366 : }
- 367 14796 : }
+ 367 14846 : }
368 :
369 : /**
370 : * 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 a21af37e..d6986d3b 100644
--- a/cov/tommyds/tommytree.c.func-sort-c.html
+++ b/cov/tommyds/tommytree.c.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -73,67 +73,67 @@
| tommy_tree_foreach |
- 1604 |
+ 1614 |
| tommy_tree_init |
- 3327 |
+ 3347 |
| tommy_tree_foreach_arg |
- 6241 |
+ 6229 |
| tommy_tree_remove |
- 76114 |
+ 76084 |
| tommy_tree_move_right |
- 175888 |
+ 175516 |
| tommy_tree_rotate_right |
- 184746 |
+ 183361 |
| tommy_tree_remove_node |
- 754198 |
+ 752904 |
| tommy_tree_foreach_node |
- 7539256 |
+ 7539142 |
| tommy_tree_insert |
- 7704289 |
+ 7704209 |
| tommy_tree_rotate_left |
- 7711736 |
+ 7710097 |
| tommy_tree_search_compare |
- 16671172 |
+ 16616314 |
| tommy_tree_foreach_arg_node |
- 27357453 |
+ 27289637 |
| tommy_tree_insert_node |
- 98881758 |
+ 98880309 |
| tommy_tree_balance |
- 107748419 |
+ 107739396 |
| tommy_tree_delta |
- 115475682 |
+ 115464816 |
| tommy_tree_search_node |
- 183509139 |
+ 182914273 |
diff --git a/cov/tommyds/tommytree.c.func.html b/cov/tommyds/tommytree.c.func.html
index fa6b3f2e..a7044193 100644
--- a/cov/tommyds/tommytree.c.func.html
+++ b/cov/tommyds/tommytree.c.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,39 +61,39 @@
| tommy_tree_balance |
- 107748419 |
+ 107739396 |
| tommy_tree_delta |
- 115475682 |
+ 115464816 |
| tommy_tree_foreach |
- 1604 |
+ 1614 |
| tommy_tree_foreach_arg |
- 6241 |
+ 6229 |
| tommy_tree_foreach_arg_node |
- 27357453 |
+ 27289637 |
| tommy_tree_foreach_node |
- 7539256 |
+ 7539142 |
| tommy_tree_init |
- 3327 |
+ 3347 |
| tommy_tree_insert |
- 7704289 |
+ 7704209 |
| tommy_tree_insert_node |
- 98881758 |
+ 98880309 |
| tommy_tree_memory_usage |
@@ -101,11 +101,11 @@
| tommy_tree_move_right |
- 175888 |
+ 175516 |
| tommy_tree_remove |
- 76114 |
+ 76084 |
| tommy_tree_remove_existing |
@@ -113,15 +113,15 @@
| tommy_tree_remove_node |
- 754198 |
+ 752904 |
| tommy_tree_rotate_left |
- 7711736 |
+ 7710097 |
| tommy_tree_rotate_right |
- 184746 |
+ 183361 |
| tommy_tree_search |
@@ -129,11 +129,11 @@
| tommy_tree_search_compare |
- 16671172 |
+ 16616314 |
| tommy_tree_search_node |
- 183509139 |
+ 182914273 |
diff --git a/cov/tommyds/tommytree.c.gcov.html b/cov/tommyds/tommytree.c.gcov.html
index 3839bed2..d1d9f4bc 100644
--- a/cov/tommyds/tommytree.c.gcov.html
+++ b/cov/tommyds/tommytree.c.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -94,104 +94,104 @@
32 : /******************************************************************************/
33 : /* tree */
34 :
- 35 3327 : TOMMY_API void tommy_tree_init(tommy_tree* tree, tommy_compare_func* cmp)
+ 35 3347 : TOMMY_API void tommy_tree_init(tommy_tree* tree, tommy_compare_func* cmp)
36 : {
- 37 3327 : tree->root = 0;
- 38 3327 : tree->count = 0;
- 39 3327 : tree->cmp = cmp;
- 40 3327 : }
+ 37 3347 : tree->root = 0;
+ 38 3347 : tree->count = 0;
+ 39 3347 : tree->cmp = cmp;
+ 40 3347 : }
41 :
- 42 115475682 : static tommy_ssize_t tommy_tree_delta(tommy_tree_node* root)
+ 42 115464816 : static tommy_ssize_t tommy_tree_delta(tommy_tree_node* root)
43 : {
- 44 115475682 : tommy_ssize_t left_height = root->prev ? root->prev->index : 0;
- 45 115475682 : tommy_ssize_t right_height = root->next ? root->next->index : 0;
+ 44 115464816 : tommy_ssize_t left_height = root->prev ? root->prev->index : 0;
+ 45 115464816 : tommy_ssize_t right_height = root->next ? root->next->index : 0;
46 :
- 47 115475682 : return left_height - right_height;
+ 47 115464816 : return left_height - right_height;
48 : }
49 :
50 : /* AVL tree operations */
51 : static tommy_tree_node* tommy_tree_balance(tommy_tree_node*);
52 :
- 53 7711736 : static tommy_tree_node* tommy_tree_rotate_left(tommy_tree_node* root)
+ 53 7710097 : static tommy_tree_node* tommy_tree_rotate_left(tommy_tree_node* root)
54 : {
- 55 7711736 : tommy_tree_node* next = root->next;
+ 55 7710097 : tommy_tree_node* next = root->next;
56 :
- 57 7711736 : root->next = next->prev;
+ 57 7710097 : root->next = next->prev;
58 :
- 59 7711736 : next->prev = tommy_tree_balance(root);
+ 59 7710097 : next->prev = tommy_tree_balance(root);
60 :
- 61 7711736 : return tommy_tree_balance(next);
+ 61 7710097 : return tommy_tree_balance(next);
62 : }
63 :
- 64 184746 : static tommy_tree_node* tommy_tree_rotate_right(tommy_tree_node* root)
+ 64 183361 : static tommy_tree_node* tommy_tree_rotate_right(tommy_tree_node* root)
65 : {
- 66 184746 : tommy_tree_node* prev = root->prev;
+ 66 183361 : tommy_tree_node* prev = root->prev;
67 :
- 68 184746 : root->prev = prev->next;
+ 68 183361 : root->prev = prev->next;
69 :
- 70 184746 : prev->next = tommy_tree_balance(root);
+ 70 183361 : prev->next = tommy_tree_balance(root);
71 :
- 72 184746 : return tommy_tree_balance(prev);
+ 72 183361 : return tommy_tree_balance(prev);
73 : }
74 :
- 75 175888 : static tommy_tree_node* tommy_tree_move_right(tommy_tree_node* root, tommy_tree_node* node)
+ 75 175516 : static tommy_tree_node* tommy_tree_move_right(tommy_tree_node* root, tommy_tree_node* node)
76 : {
- 77 175888 : if (!root)
- 78 75986 : return node;
+ 77 175516 : if (!root)
+ 78 75956 : return node;
79 :
- 80 99902 : root->next = tommy_tree_move_right(root->next, node);
+ 80 99560 : root->next = tommy_tree_move_right(root->next, node);
81 :
- 82 99902 : return tommy_tree_balance(root);
+ 82 99560 : return tommy_tree_balance(root);
83 : }
84 :
- 85 107748419 : static tommy_tree_node* tommy_tree_balance(tommy_tree_node* root)
+ 85 107739396 : static tommy_tree_node* tommy_tree_balance(tommy_tree_node* root)
86 : {
- 87 107748419 : tommy_ssize_t delta = tommy_tree_delta(root);
+ 87 107739396 : tommy_ssize_t delta = tommy_tree_delta(root);
88 :
- 89 107748419 : if (delta < -1) {
- 90 7586852 : if (tommy_tree_delta(root->next) > 0)
- 91 44335 : root->next = tommy_tree_rotate_right(root->next);
- 92 7586852 : return tommy_tree_rotate_left(root);
+ 89 107739396 : if (delta < -1) {
+ 90 7586146 : if (tommy_tree_delta(root->next) > 0)
+ 91 44087 : root->next = tommy_tree_rotate_right(root->next);
+ 92 7586146 : return tommy_tree_rotate_left(root);
93 : }
94 :
- 95 100161567 : if (delta > 1) {
- 96 140411 : if (tommy_tree_delta(root->prev) < 0)
- 97 124884 : root->prev = tommy_tree_rotate_left(root->prev);
- 98 140411 : return tommy_tree_rotate_right(root);
+ 95 100153250 : if (delta > 1) {
+ 96 139274 : if (tommy_tree_delta(root->prev) < 0)
+ 97 123951 : root->prev = tommy_tree_rotate_left(root->prev);
+ 98 139274 : return tommy_tree_rotate_right(root);
99 : }
100 :
101 : /* recompute key */
- 102 100021156 : root->index = 0;
+ 102 100013976 : root->index = 0;
103 :
- 104 100021156 : if (root->prev && root->prev->index > root->index)
- 105 80851276 : root->index = root->prev->index;
+ 104 100013976 : if (root->prev && root->prev->index > root->index)
+ 105 80844985 : root->index = root->prev->index;
106 :
- 107 100021156 : if (root->next && root->next->index > root->index)
- 108 46028890 : root->index = root->next->index;
+ 107 100013976 : if (root->next && root->next->index > root->index)
+ 108 46033228 : root->index = root->next->index;
109 :
110 : /* count itself */
- 111 100021156 : root->index += 1;
+ 111 100013976 : root->index += 1;
112 :
- 113 100021156 : return root;
+ 113 100013976 : return root;
114 : }
115 :
- 116 98881758 : static tommy_tree_node* tommy_tree_insert_node(tommy_compare_func* cmp, tommy_tree_node* root, tommy_tree_node** let)
+ 116 98880309 : 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 98881758 : if (!root)
- 121 7704288 : return *let;
+ 120 98880309 : if (!root)
+ 121 7704208 : return *let;
122 :
- 123 91177470 : c = cmp((*let)->data, root->data);
+ 123 91176101 : c = cmp((*let)->data, root->data);
124 :
- 125 91177470 : if (c < 0) {
- 126 1679959 : root->prev = tommy_tree_insert_node(cmp, root->prev, let);
- 127 1679959 : return tommy_tree_balance(root);
+ 125 91176101 : if (c < 0) {
+ 126 1671201 : root->prev = tommy_tree_insert_node(cmp, root->prev, let);
+ 127 1671201 : return tommy_tree_balance(root);
128 : }
129 :
- 130 89497511 : if (c > 0) {
- 131 89497510 : root->next = tommy_tree_insert_node(cmp, root->next, let);
- 132 89497510 : return tommy_tree_balance(root);
+ 130 89504900 : if (c > 0) {
+ 131 89504899 : root->next = tommy_tree_insert_node(cmp, root->next, let);
+ 132 89504899 : 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 7704289 : TOMMY_API void* tommy_tree_insert(tommy_tree* tree, tommy_tree_node* node, void* data)
+ 141 7704209 : TOMMY_API void* tommy_tree_insert(tommy_tree* tree, tommy_tree_node* node, void* data)
142 : {
- 143 7704289 : tommy_tree_node* insert = node;
+ 143 7704209 : tommy_tree_node* insert = node;
144 :
- 145 7704289 : insert->data = data;
- 146 7704289 : insert->prev = 0;
- 147 7704289 : insert->next = 0;
- 148 7704289 : insert->index = 0;
+ 145 7704209 : insert->data = data;
+ 146 7704209 : insert->prev = 0;
+ 147 7704209 : insert->next = 0;
+ 148 7704209 : insert->index = 0;
149 :
- 150 7704289 : tree->root = tommy_tree_insert_node(tree->cmp, tree->root, &insert);
+ 150 7704209 : tree->root = tommy_tree_insert_node(tree->cmp, tree->root, &insert);
151 :
- 152 7704289 : if (insert == node)
- 153 7704288 : ++tree->count;
+ 152 7704209 : if (insert == node)
+ 153 7704208 : ++tree->count;
154 :
- 155 7704289 : return insert->data;
+ 155 7704209 : return insert->data;
156 : }
157 :
- 158 754198 : static tommy_tree_node* tommy_tree_remove_node(tommy_compare_func* cmp, tommy_tree_node* root, void* data, tommy_tree_node** let)
+ 158 752904 : 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 754198 : if (!root)
+ 162 752904 : if (!root)
163 128 : return 0;
164 :
- 165 754070 : c = cmp(data, root->data);
+ 165 752776 : c = cmp(data, root->data);
166 :
- 167 754070 : if (c < 0) {
- 168 310729 : root->prev = tommy_tree_remove_node(cmp, root->prev, data, let);
- 169 310729 : return tommy_tree_balance(root);
+ 167 752776 : if (c < 0) {
+ 168 310920 : root->prev = tommy_tree_remove_node(cmp, root->prev, data, let);
+ 169 310920 : return tommy_tree_balance(root);
170 : }
171 :
- 172 443341 : if (c > 0) {
- 173 367355 : root->next = tommy_tree_remove_node(cmp, root->next, data, let);
- 174 367355 : return tommy_tree_balance(root);
+ 172 441856 : if (c > 0) {
+ 173 365900 : root->next = tommy_tree_remove_node(cmp, root->next, data, let);
+ 174 365900 : return tommy_tree_balance(root);
175 : }
176 :
177 : /* found */
- 178 75986 : *let = root;
+ 178 75956 : *let = root;
179 :
- 180 75986 : return tommy_tree_move_right(root->prev, root->next);
+ 180 75956 : return tommy_tree_move_right(root->prev, root->next);
181 : }
182 :
- 183 76114 : TOMMY_API void* tommy_tree_remove(tommy_tree* tree, void* data)
+ 183 76084 : TOMMY_API void* tommy_tree_remove(tommy_tree* tree, void* data)
184 : {
- 185 76114 : tommy_tree_node* node = 0;
+ 185 76084 : tommy_tree_node* node = 0;
186 :
- 187 76114 : tree->root = tommy_tree_remove_node(tree->cmp, tree->root, data, &node);
+ 187 76084 : tree->root = tommy_tree_remove_node(tree->cmp, tree->root, data, &node);
188 :
- 189 76114 : if (!node)
+ 189 76084 : if (!node)
190 128 : return 0;
191 :
- 192 75986 : --tree->count;
+ 192 75956 : --tree->count;
193 :
- 194 75986 : return node->data;
+ 194 75956 : return node->data;
195 : }
196 :
- 197 183509139 : static tommy_tree_node* tommy_tree_search_node(tommy_compare_func* cmp, tommy_tree_node* root, void* data)
+ 197 182914273 : static tommy_tree_node* tommy_tree_search_node(tommy_compare_func* cmp, tommy_tree_node* root, void* data)
198 : {
199 : int c;
200 :
- 201 183509139 : if (!root)
- 202 1927556 : return 0;
+ 201 182914273 : if (!root)
+ 202 1925494 : return 0;
203 :
- 204 181581583 : c = cmp(data, root->data);
+ 204 180988779 : c = cmp(data, root->data);
205 :
- 206 181581583 : if (c < 0)
- 207 67861047 : return tommy_tree_search_node(cmp, root->prev, data);
+ 206 180988779 : if (c < 0)
+ 207 67621145 : return tommy_tree_search_node(cmp, root->prev, data);
208 :
- 209 113720536 : if (c > 0)
- 210 98976918 : return tommy_tree_search_node(cmp, root->next, data);
+ 209 113367634 : if (c > 0)
+ 210 98676812 : return tommy_tree_search_node(cmp, root->next, data);
211 :
- 212 14743618 : return root;
+ 212 14690822 : return root;
213 : }
214 :
215 2 : TOMMY_API void* tommy_tree_search(tommy_tree* tree, void* data)
@@ -284,14 +284,14 @@
222 1 : return node->data;
223 : }
224 :
- 225 16671172 : TOMMY_API void* tommy_tree_search_compare(tommy_tree* tree, tommy_compare_func* cmp, void* cmp_arg)
+ 225 16616314 : TOMMY_API void* tommy_tree_search_compare(tommy_tree* tree, tommy_compare_func* cmp, void* cmp_arg)
226 : {
- 227 16671172 : tommy_tree_node* node = tommy_tree_search_node(cmp, tree->root, cmp_arg);
+ 227 16616314 : tommy_tree_node* node = tommy_tree_search_node(cmp, tree->root, cmp_arg);
228 :
- 229 16671172 : if (!node)
- 230 1927555 : return 0;
+ 229 16616314 : if (!node)
+ 230 1925493 : return 0;
231 :
- 232 14743617 : return node->data;
+ 232 14690821 : return node->data;
233 : }
234 :
235 128 : TOMMY_API void* tommy_tree_remove_existing(tommy_tree* tree, tommy_tree_node* node)
@@ -303,49 +303,49 @@
241 128 : return data;
242 : }
243 :
- 244 7539256 : static void tommy_tree_foreach_node(tommy_tree_node* root, tommy_foreach_func* func)
+ 244 7539142 : static void tommy_tree_foreach_node(tommy_tree_node* root, tommy_foreach_func* func)
245 : {
246 : tommy_tree_node* next;
247 :
- 248 7539256 : if (!root)
- 249 3770430 : return;
+ 248 7539142 : if (!root)
+ 249 3770378 : return;
250 :
- 251 3768826 : tommy_tree_foreach_node(root->prev, func);
+ 251 3768764 : tommy_tree_foreach_node(root->prev, func);
252 :
253 : /* make a copy in case func is free() */
- 254 3768826 : next = root->next;
+ 254 3768764 : next = root->next;
255 :
- 256 3768826 : func(root->data);
+ 256 3768764 : func(root->data);
257 :
- 258 3768826 : tommy_tree_foreach_node(next, func);
+ 258 3768764 : tommy_tree_foreach_node(next, func);
259 : }
260 :
- 261 1604 : TOMMY_API void tommy_tree_foreach(tommy_tree* tree, tommy_foreach_func* func)
+ 261 1614 : TOMMY_API void tommy_tree_foreach(tommy_tree* tree, tommy_foreach_func* func)
262 : {
- 263 1604 : tommy_tree_foreach_node(tree->root, func);
- 264 1604 : }
+ 263 1614 : tommy_tree_foreach_node(tree->root, func);
+ 264 1614 : }
265 :
- 266 27357453 : static void tommy_tree_foreach_arg_node(tommy_tree_node* root, tommy_foreach_arg_func* func, void* arg)
+ 266 27289637 : 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 27357453 : if (!root)
- 271 13681847 : return;
+ 270 27289637 : if (!root)
+ 271 13647933 : return;
272 :
- 273 13675606 : tommy_tree_foreach_arg_node(root->prev, func, arg);
+ 273 13641704 : tommy_tree_foreach_arg_node(root->prev, func, arg);
274 :
275 : /* make a copy in case func is free() */
- 276 13675606 : next = root->next;
+ 276 13641704 : next = root->next;
277 :
- 278 13675606 : func(arg, root->data);
+ 278 13641704 : func(arg, root->data);
279 :
- 280 13675606 : tommy_tree_foreach_arg_node(next, func, arg);
+ 280 13641704 : tommy_tree_foreach_arg_node(next, func, arg);
281 : }
282 :
- 283 6241 : TOMMY_API void tommy_tree_foreach_arg(tommy_tree* tree, tommy_foreach_arg_func* func, void* arg)
+ 283 6229 : TOMMY_API void tommy_tree_foreach_arg(tommy_tree* tree, tommy_foreach_arg_func* func, void* arg)
284 : {
- 285 6241 : tommy_tree_foreach_arg_node(tree->root, func, arg);
- 286 6241 : }
+ 285 6229 : tommy_tree_foreach_arg_node(tree->root, func, arg);
+ 286 6229 : }
287 :
288 1 : TOMMY_API tommy_size_t tommy_tree_memory_usage(tommy_tree* tree)
289 : {
diff --git a/cov/tommyds/tommytree.h.func-sort-c.html b/cov/tommyds/tommytree.h.func-sort-c.html
index 916e42d1..f366a29f 100644
--- a/cov/tommyds/tommytree.h.func-sort-c.html
+++ b/cov/tommyds/tommytree.h.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/tommyds/tommytree.h.func.html b/cov/tommyds/tommytree.h.func.html
index bd916045..a085e2ca 100644
--- a/cov/tommyds/tommytree.h.func.html
+++ b/cov/tommyds/tommytree.h.func.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/tommyds/tommytree.h.gcov.html b/cov/tommyds/tommytree.h.gcov.html
index 61fc0b63..a112cb4c 100644
--- a/cov/tommyds/tommytree.h.gcov.html
+++ b/cov/tommyds/tommytree.h.gcov.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/cov/tommyds/tommytypes.h.func-sort-c.html b/cov/tommyds/tommytypes.h.func-sort-c.html
index f63cc84d..e9841cf5 100644
--- a/cov/tommyds/tommytypes.h.func-sort-c.html
+++ b/cov/tommyds/tommytypes.h.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,7 +61,7 @@
| tommy_ctz_u64 |
- 2198 |
+ 2196 |
| tommy_haszero_u32 |
@@ -69,7 +69,7 @@
| tommy_ilog2_u64 |
- 8515825 |
+ 8496878 |
diff --git a/cov/tommyds/tommytypes.h.func.html b/cov/tommyds/tommytypes.h.func.html
index d6380a12..3a591bdc 100644
--- a/cov/tommyds/tommytypes.h.func.html
+++ b/cov/tommyds/tommytypes.h.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -61,7 +61,7 @@
| tommy_ctz_u64 |
- 2198 |
+ 2196 |
| tommy_haszero_u32 |
@@ -69,7 +69,7 @@
| tommy_ilog2_u64 |
- 8515825 |
+ 8496878 |
diff --git a/cov/tommyds/tommytypes.h.gcov.html b/cov/tommyds/tommytypes.h.gcov.html
index 147e00be..0424040f 100644
--- a/cov/tommyds/tommytypes.h.gcov.html
+++ b/cov/tommyds/tommytypes.h.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -462,14 +462,14 @@
400 : /**
401 : * Bit scan reverse or integer log2 for 64 bits.
402 : */
- 403 8515825 : tommy_inline tommy_uint_t tommy_ilog2_u64(tommy_uint64_t value)
+ 403 8496878 : tommy_inline tommy_uint_t tommy_ilog2_u64(tommy_uint64_t value)
404 : {
405 : #if defined(_MSC_VER)
406 : unsigned long count;
407 : _BitScanReverse64(&count, value);
408 : return count;
409 : #elif defined(__GNUC__)
- 410 8515825 : return __builtin_clzll(value) ^ 63;
+ 410 8496878 : return __builtin_clzll(value) ^ 63;
411 : #else
412 : tommy_uint32_t l = value & 0xFFFFFFFFU;
413 : tommy_uint32_t h = value >> 32;
@@ -513,14 +513,14 @@
451 : /**
452 : * Bit scan forward or trailing zero count for 64 bits.
453 : */
- 454 2198 : tommy_inline tommy_uint_t tommy_ctz_u64(tommy_uint64_t value)
+ 454 2196 : tommy_inline tommy_uint_t tommy_ctz_u64(tommy_uint64_t value)
455 : {
456 : #if defined(_MSC_VER)
457 : unsigned long count;
458 : _BitScanForward64(&count, value);
459 : return count;
460 : #elif defined(__GNUC__)
- 461 2198 : return __builtin_ctzll(value);
+ 461 2196 : return __builtin_ctzll(value);
462 : #else
463 : tommy_uint32_t l = value & 0xFFFFFFFFU;
464 : tommy_uint32_t h = value >> 32;