diff --git a/cov/cmdline/check.c.func-sort-c.html b/cov/cmdline/check.c.func-sort-c.html index 42c16119..f692495f 100644 --- a/cov/cmdline/check.c.func-sort-c.html +++ b/cov/cmdline/check.c.func-sort-c.html @@ -32,8 +32,8 @@ Lines: 709 - 781 - 90.8 % + 775 + 91.5 % Date: @@ -73,18 +73,18 @@ blockcmp - 473403 + 473381 repair_step - 252742 + 252815 is_hash_matching - 214689 + 214888 - state_check + state_check 120 diff --git a/cov/cmdline/check.c.func.html b/cov/cmdline/check.c.func.html index cade11b5..a78876cd 100644 --- a/cov/cmdline/check.c.func.html +++ b/cov/cmdline/check.c.func.html @@ -32,8 +32,8 @@ Lines: 709 - 781 - 90.8 % + 775 + 91.5 % Date: @@ -65,7 +65,7 @@ blockcmp - 473403 + 473381 file_post @@ -73,7 +73,7 @@ is_hash_matching - 214689 + 214888 is_parity_matching @@ -85,10 +85,10 @@ repair_step - 252742 + 252815 - state_check + state_check 120 diff --git a/cov/cmdline/check.c.gcov.html b/cov/cmdline/check.c.gcov.html index ba89f607..35bb07f2 100644 --- a/cov/cmdline/check.c.gcov.html +++ b/cov/cmdline/check.c.gcov.html @@ -32,8 +32,8 @@ Lines: 709 - 781 - 90.8 % + 775 + 91.5 % Date: @@ -129,64 +129,64 @@ 67 : * Check if a block hash matches the specified buffer. 68 : * Return ==0 if equal 69 : */ - 70 473403 : static int blockcmp(struct snapraid_state* state, int rehash, struct snapraid_block* block, unsigned pos_size, unsigned char* buffer, unsigned char* buffer_zero) + 70 473381 : static int blockcmp(struct snapraid_state* state, int rehash, struct snapraid_block* block, unsigned pos_size, unsigned char* buffer, unsigned char* buffer_zero) 71 : { 72 : unsigned char hash[HASH_MAX]; 73 : 74 : /* now compute the hash of the valid part */ - 75 473403 : if (rehash) { + 75 473381 : if (rehash) { 76 0 : memhash(state->prevhash, state->prevhashseed, hash, buffer, pos_size); 77 : } else { - 78 473403 : memhash(state->hash, state->hashseed, hash, buffer, pos_size); + 78 473381 : memhash(state->hash, state->hashseed, hash, buffer, pos_size); 79 : } 80 : 81 : /* compare the hash */ - 82 473403 : if (memcmp(hash, block->hash, BLOCK_HASH_SIZE) != 0) { - 83 19016 : return -1; + 82 473381 : if (memcmp(hash, block->hash, BLOCK_HASH_SIZE) != 0) { + 83 19034 : return -1; 84 : } 85 : 86 : /* compare to the end of the block */ - 87 454387 : if (pos_size < state->block_size) { - 88 187463 : if (memcmp(buffer + pos_size, buffer_zero + pos_size, state->block_size - pos_size) != 0) { - 89 36 : return -1; + 87 454347 : if (pos_size < state->block_size) { + 88 187568 : if (memcmp(buffer + pos_size, buffer_zero + pos_size, state->block_size - pos_size) != 0) { + 89 39 : return -1; 90 : } 91 : } 92 : - 93 454351 : return 0; + 93 454308 : return 0; 94 : } 95 : 96 : /** 97 : * Check if the hash of all the failed block we are expecting to recover are now matching. 98 : */ - 99 214689 : static int is_hash_matching(struct snapraid_state* state, int rehash, unsigned diskmax, struct failed_struct* failed, unsigned* failed_map, unsigned failed_count, void** buffer, void* buffer_zero) + 99 214888 : static int is_hash_matching(struct snapraid_state* state, int rehash, unsigned diskmax, struct failed_struct* failed, unsigned* failed_map, unsigned failed_count, void** buffer, void* buffer_zero) 100 : { 101 : unsigned j; 102 : int hash_checked; 103 : - 104 214689 : hash_checked = 0; /* keep track if we check at least one block */ + 104 214888 : hash_checked = 0; /* keep track if we check at least one block */ 105 : 106 : /* check if the recovered blocks are OK */ - 107 673562 : for (j = 0; j < failed_count; ++j) { + 107 673718 : for (j = 0; j < failed_count; ++j) { 108 : /* if we are expected to recover this block */ - 109 477925 : if (!failed[failed_map[j]].is_outofdate + 109 477903 : if (!failed[failed_map[j]].is_outofdate 110 : /* if the block has a hash to check */ - 111 473403 : && block_has_updated_hash(failed[failed_map[j]].block) + 111 473381 : && block_has_updated_hash(failed[failed_map[j]].block) 112 : ) { 113 : /* if a hash doesn't match, fail the check */ - 114 473403 : unsigned pos_size = file_block_size(failed[failed_map[j]].file, failed[failed_map[j]].file_pos, state->block_size); - 115 473403 : if (blockcmp(state, rehash, failed[failed_map[j]].block, pos_size, buffer[failed[failed_map[j]].index], buffer_zero) != 0) { - 116 19052 : log_tag("hash_error: Hash mismatch on entry %u\n", failed_map[j]); - 117 19052 : return 0; + 114 473381 : unsigned pos_size = file_block_size(failed[failed_map[j]].file, failed[failed_map[j]].file_pos, state->block_size); + 115 473381 : if (blockcmp(state, rehash, failed[failed_map[j]].block, pos_size, buffer[failed[failed_map[j]].index], buffer_zero) != 0) { + 116 19073 : log_tag("hash_error: Hash mismatch on entry %u\n", failed_map[j]); + 117 19073 : return 0; 118 : } 119 : - 120 454351 : hash_checked = 1; + 120 454308 : hash_checked = 1; 121 : } 122 : } 123 : 124 : /* if nothing checked, we reject it */ 125 : /* note that we are excluding this case at upper level */ 126 : /* but checking again doesn't hurt */ - 127 195637 : if (!hash_checked) { + 127 195815 : if (!hash_checked) { 128 : /* LCOV_EXCL_START */ 129 : return 0; 130 : /* LCOV_EXCL_STOP */ @@ -194,8 +194,8 @@ 132 : 133 : /* if we checked something, and no block failed the check */ 134 : /* recompute all the redundancy information */ - 135 195637 : raid_gen(diskmax, state->level, state->block_size, buffer); - 136 195637 : return 1; + 135 195815 : raid_gen(diskmax, state->level, state->block_size, buffer); + 136 195815 : return 1; 137 : } 138 : 139 : /** @@ -221,7 +221,7 @@ 159 : * Return <0 if failure for missing strategy, >0 if data is wrong and we cannot rebuild correctly, 0 on success. 160 : * If success, the parity are computed in the buffer variable. 161 : */ - 162 252742 : static int repair_step(struct snapraid_state* state, int rehash, unsigned pos, unsigned diskmax, struct failed_struct* failed, unsigned* failed_map, unsigned failed_count, void** buffer, void** buffer_recov, void* buffer_zero) + 162 252815 : static int repair_step(struct snapraid_state* state, int rehash, unsigned pos, unsigned diskmax, struct failed_struct* failed, unsigned* failed_map, unsigned failed_count, void** buffer, void** buffer_recov, void* buffer_zero) 163 : { 164 : unsigned i, n; 165 : int error; @@ -230,7 +230,7 @@ 168 : int ip[LEV_MAX]; 169 : 170 : /* no fix required, already checked at higher level, but just to be sure */ - 171 252742 : if (failed_count == 0) { + 171 252815 : if (failed_count == 0) { 172 : /* LCOV_EXCL_START */ 173 : /* recompute only the parity */ 174 : raid_gen(diskmax, state->level, state->block_size, buffer); @@ -238,28 +238,28 @@ 176 : /* LCOV_EXCL_STOP */ 177 : } 178 : - 179 252742 : n = state->level; - 180 252742 : error = 0; + 179 252815 : n = state->level; + 180 252815 : error = 0; 181 : 182 : /* setup vector of failed disk indexes */ - 183 892104 : for (i = 0; i < failed_count; ++i) - 184 639362 : id[i] = failed[failed_map[i]].index; + 183 891917 : for (i = 0; i < failed_count; ++i) + 184 639102 : id[i] = failed[failed_map[i]].index; 185 : 186 : /* check if there is at least a failed block that can be checked for correctness using the hash */ 187 : /* if there isn't, we have to sacrifice a parity block to check that the result is correct */ - 188 252742 : has_hash = 0; - 189 892104 : for (i = 0; i < failed_count; ++i) { + 188 252815 : has_hash = 0; + 189 891917 : for (i = 0; i < failed_count; ++i) { 190 : /* if we are expected to recover this block */ - 191 639362 : if (!failed[failed_map[i]].is_outofdate + 191 639102 : if (!failed[failed_map[i]].is_outofdate 192 : /* if the block has a hash to check */ - 193 630318 : && block_has_updated_hash(failed[failed_map[i]].block) + 193 630058 : && block_has_updated_hash(failed[failed_map[i]].block) 194 : ) - 195 630310 : has_hash = 1; + 195 630050 : has_hash = 1; 196 : } 197 : 198 : /* if we don't have a hash, but we have an extra parity */ 199 : /* (strictly-less failures than number of parities) */ - 200 252742 : if (!has_hash && failed_count < n) { + 200 252815 : if (!has_hash && failed_count < n) { 201 : /* number of parity to use, one more to check the recovering */ 202 8 : unsigned r = failed_count + 1; 203 : @@ -299,51 +299,51 @@ 237 : 238 : /* if we have a hash, and enough parities */ 239 : /* (less-or-equal failures than number of parities) */ - 240 252734 : if (has_hash && failed_count <= n) { + 240 252807 : if (has_hash && failed_count <= n) { 241 : /* number of parities to use equal at the number of failures */ - 242 204960 : unsigned r = failed_count; + 242 205145 : unsigned r = failed_count; 243 : 244 : /* all combinations (r of n) parities */ - 245 204960 : combination_first(r, n, ip); + 245 205145 : combination_first(r, n, ip); 246 : do { 247 : /* if a parity is missing, do nothing */ - 248 692614 : for (i = 0; i < r; ++i) { - 249 477925 : if (buffer_recov[ip[i]] == 0) + 248 692791 : for (i = 0; i < r; ++i) { + 249 477903 : if (buffer_recov[ip[i]] == 0) 250 0 : break; 251 : } - 252 214689 : if (i != r) + 252 214888 : if (i != r) 253 0 : continue; 254 : 255 : /* copy the parities to use */ - 256 692614 : for (i = 0; i < r; ++i) - 257 477925 : memcpy(buffer[diskmax + ip[i]], buffer_recov[ip[i]], state->block_size); + 256 692791 : for (i = 0; i < r; ++i) + 257 477903 : memcpy(buffer[diskmax + ip[i]], buffer_recov[ip[i]], state->block_size); 258 : 259 : /* recover */ - 260 214689 : raid_data(r, id, ip, diskmax, state->block_size, buffer); + 260 214888 : raid_data(r, id, ip, diskmax, state->block_size, buffer); 261 : 262 : /* use the hash to check the result */ - 263 214689 : if (is_hash_matching(state, rehash, diskmax, failed, failed_map, failed_count, buffer, buffer_zero)) - 264 195637 : return 0; + 263 214888 : if (is_hash_matching(state, rehash, diskmax, failed, failed_map, failed_count, buffer, buffer_zero)) + 264 195815 : return 0; 265 : 266 : /* log */ - 267 19052 : log_tag("parity_error:%u:", pos); - 268 38104 : for (i = 0; i < r; ++i) { - 269 19052 : if (i != 0) + 267 19073 : log_tag("parity_error:%u:", pos); + 268 38146 : for (i = 0; i < r; ++i) { + 269 19073 : if (i != 0) 270 0 : log_tag("/"); - 271 19052 : log_tag("%s", lev_config_name(ip[i])); + 271 19073 : log_tag("%s", lev_config_name(ip[i])); 272 : } - 273 19052 : log_tag(":hash: Hash mismatch\n"); - 274 19052 : ++error; - 275 38104 : } while (combination_next(r, n, ip)); + 273 19073 : log_tag(":hash: Hash mismatch\n"); + 274 19073 : ++error; + 275 38146 : } while (combination_next(r, n, ip)); 276 : } 277 : 278 : /* return the number of failed attempts, or -1 if no strategy */ - 279 57097 : if (error) - 280 9323 : return error; + 279 56992 : if (error) + 280 9330 : return error; 281 : - 282 47774 : log_tag("strategy_error:%u: No strategy to recover from %u failures with %u parity %s hash\n", + 282 47662 : log_tag("strategy_error:%u: No strategy to recover from %u failures with %u parity %s hash\n", 283 : pos, failed_count, n, has_hash ? "with" : "without"); - 284 47774 : return -1; + 284 47662 : return -1; 285 : } 286 : 287 870958 : static int repair(struct snapraid_state* state, int rehash, unsigned pos, unsigned diskmax, struct failed_struct* failed, unsigned* failed_map, unsigned failed_count, void** buffer, void** buffer_recov, void* buffer_zero) @@ -360,47 +360,47 @@ 298 : 299 : /* if nothing failed, just recompute the parity */ 300 870958 : if (failed_count == 0) { - 301 583304 : raid_gen(diskmax, state->level, state->block_size, buffer); - 302 583304 : return 0; + 301 583231 : raid_gen(diskmax, state->level, state->block_size, buffer); + 302 583231 : return 0; 303 : } 304 : 305 : /* logs the status */ - 306 1017035 : for (j = 0; j < failed_count; ++j) { + 306 1016848 : for (j = 0; j < failed_count; ++j) { 307 : const char* desc; 308 : const char* hash; 309 : const char* data; - 310 729381 : struct snapraid_block* block = failed[j].block; - 311 729381 : unsigned block_state = block_state_get(block); + 310 729121 : struct snapraid_block* block = failed[j].block; + 311 729121 : unsigned block_state = block_state_get(block); 312 : - 313 729381 : switch (block_state) { + 313 729121 : switch (block_state) { 314 18454 : case BLOCK_STATE_DELETED : desc = "delete"; break; 315 13851 : case BLOCK_STATE_CHG : desc = "change"; break; 316 62282 : case BLOCK_STATE_REP : desc = "replace"; break; - 317 634794 : case BLOCK_STATE_BLK : desc = "block"; break; + 317 634534 : case BLOCK_STATE_BLK : desc = "block"; break; 318 : /* LCOV_EXCL_START */ 319 : default : desc = "unknown"; break; 320 : /* LCOV_EXCL_STOP */ 321 : } 322 : - 323 729381 : if (hash_is_invalid(block->hash)) { + 323 729121 : if (hash_is_invalid(block->hash)) { 324 13843 : hash = "lost"; - 325 715538 : } else if (hash_is_zero(block->hash)) { + 325 715278 : } else if (hash_is_zero(block->hash)) { 326 8 : hash = "zero"; 327 : } else { - 328 715530 : hash = "known"; + 328 715270 : hash = "known"; 329 : } 330 : - 331 729381 : if (failed[j].is_bad) - 332 643656 : data = "bad"; + 331 729121 : if (failed[j].is_bad) + 332 643396 : data = "bad"; 333 : else 334 85725 : data = "good"; 335 : - 336 729381 : if (failed[j].file) { - 337 710927 : struct snapraid_disk* disk = failed[j].disk; - 338 710927 : struct snapraid_file* file = failed[j].file; - 339 710927 : block_off_t file_pos = failed[j].file_pos; + 336 729121 : if (failed[j].file) { + 337 710667 : struct snapraid_disk* disk = failed[j].disk; + 338 710667 : struct snapraid_file* file = failed[j].file; + 339 710667 : block_off_t file_pos = failed[j].file_pos; 340 : - 341 710927 : log_tag("entry:%u:%s:%s:%s:%s:%s:%u:\n", j, desc, hash, data, disk->name, esc_tag(file->sub, esc_buffer), file_pos); + 341 710667 : log_tag("entry:%u:%s:%s:%s:%s:%s:%u:\n", j, desc, hash, data, disk->name, esc_tag(file->sub, esc_buffer), file_pos); 342 : } else { 343 18454 : log_tag("entry:%u:%s:%s:%s:\n", j, desc, hash, data); 344 : } @@ -422,35 +422,35 @@ 360 : /* We are interested to recover BLK, REP and CHG blocks if they are marked as bad, */ 361 : /* but we are not interested in DELETED ones. */ 362 : - 363 287654 : n = 0; - 364 287654 : something_to_recover = 0; /* keep track if there is at least one block to fix */ - 365 1017035 : for (j = 0; j < failed_count; ++j) { - 366 729381 : if (failed[j].is_bad) { - 367 643656 : unsigned block_state = block_state_get(failed[j].block); + 363 287727 : n = 0; + 364 287727 : something_to_recover = 0; /* keep track if there is at least one block to fix */ + 365 1016848 : for (j = 0; j < failed_count; ++j) { + 366 729121 : if (failed[j].is_bad) { + 367 643396 : unsigned block_state = block_state_get(failed[j].block); 368 : - 369 643656 : assert(block_state != BLOCK_STATE_DELETED); /* we cannot have bad DELETED blocks */ + 369 643396 : assert(block_state != BLOCK_STATE_DELETED); /* we cannot have bad DELETED blocks */ 370 : 371 : /* if we have the hash for it */ - 372 643656 : if ((block_state == BLOCK_STATE_BLK || block_state == BLOCK_STATE_REP) + 372 643396 : if ((block_state == BLOCK_STATE_BLK || block_state == BLOCK_STATE_REP) 373 : /* try to fetch the block using the known hash */ - 374 643648 : && (state_import_fetch(state, rehash, failed[j].block, buffer[failed[j].index]) == 0 - 375 639176 : || state_search_fetch(state, rehash, failed[j].file, failed[j].file_pos, failed[j].block, buffer[failed[j].index]) == 0) + 374 643388 : && (state_import_fetch(state, rehash, failed[j].block, buffer[failed[j].index]) == 0 + 375 638916 : || state_search_fetch(state, rehash, failed[j].file, failed[j].file_pos, failed[j].block, buffer[failed[j].index]) == 0) 376 : ) { 377 : /* we already have corrected it! */ 378 22382 : log_tag("hash_import: Fixed entry %u\n", j); 379 : } else { 380 : /* otherwise try to recover it */ - 381 621274 : failed_map[n] = j; - 382 621274 : ++n; + 381 621014 : failed_map[n] = j; + 382 621014 : ++n; 383 : 384 : /* we have something to try to recover */ - 385 621274 : something_to_recover = 1; + 385 621014 : something_to_recover = 1; 386 : } 387 : } 388 : } 389 : 390 : /* if nothing to fix */ - 391 287654 : if (!something_to_recover) { + 391 287727 : if (!something_to_recover) { 392 43956 : log_tag("recover_sync:%u:%u: Skipped for already recovered\n", pos, n); 393 : 394 : /* recompute only the parity */ @@ -458,22 +458,22 @@ 396 43956 : return 0; 397 : } 398 : - 399 243698 : ret = repair_step(state, rehash, pos, diskmax, failed, failed_map, n, buffer, buffer_recov, buffer_zero); - 400 243698 : if (ret == 0) { + 399 243771 : ret = repair_step(state, rehash, pos, diskmax, failed, failed_map, n, buffer, buffer_recov, buffer_zero); + 400 243771 : if (ret == 0) { 401 : /* reprocess the CHG blocks, for which we don't have a hash to check */ 402 : /* if they were BAD we have to use some heuristics to ensure that we have recovered */ 403 : /* the state after the sync. If unsure, we assume the worst case */ 404 : - 405 667587 : for (j = 0; j < failed_count; ++j) { + 405 667722 : for (j = 0; j < failed_count; ++j) { 406 : /* we take care only of BAD blocks we have to write back */ - 407 476464 : if (failed[j].is_bad) { - 408 462992 : unsigned block_state = block_state_get(failed[j].block); + 407 476421 : if (failed[j].is_bad) { + 408 462949 : unsigned block_state = block_state_get(failed[j].block); 409 : 410 : /* BLK and REP blocks are always OK, because at this point */ 411 : /* we have already checked their hash */ - 412 462992 : if (block_state != BLOCK_STATE_CHG) { - 413 462984 : assert(block_state == BLOCK_STATE_BLK || block_state == BLOCK_STATE_REP); - 414 462984 : continue; + 412 462949 : if (block_state != BLOCK_STATE_CHG) { + 413 462941 : assert(block_state == BLOCK_STATE_BLK || block_state == BLOCK_STATE_REP); + 414 462941 : continue; 415 : } 416 : 417 : /* for CHG blocks we have to 'guess' if they are correct or not */ @@ -515,15 +515,15 @@ 453 : } 454 : } 455 : - 456 191123 : return 0; + 456 191301 : return 0; 457 : } - 458 52575 : if (ret > 0) - 459 9323 : error += ret; + 458 52470 : if (ret > 0) + 459 9330 : error += ret; 460 : - 461 52575 : if (ret < 0) - 462 43252 : log_tag("recover_sync:%u:%u: Failed with no attempts\n", pos, n); + 461 52470 : if (ret < 0) + 462 43140 : log_tag("recover_sync:%u:%u: Failed with no attempts\n", pos, n); 463 : else - 464 9323 : log_tag("recover_sync:%u:%u: Failed with %d attempts\n", pos, n, ret); + 464 9330 : log_tag("recover_sync:%u:%u: Failed with %d attempts\n", pos, n, ret); 465 : 466 : /* Now assume that the parity IS NOT updated at the current state, */ 467 : /* but still represent the state before the last 'sync' process. */ @@ -533,15 +533,15 @@ 471 : /* but we are not interested to recover CHG (new version) and REP (new version) blocks, */ 472 : /* even if marked as bad, because we don't have parity for them and it's just impossible, */ 473 : /* and we are not interested to recover DELETED ones. */ - 474 52575 : n = 0; - 475 52575 : something_to_recover = 0; /* keep track if there is at least one block to fix */ - 476 52575 : something_unsynced = 0; /* keep track if we have some unsynced info to process */ - 477 233056 : for (j = 0; j < failed_count; ++j) { - 478 180481 : unsigned block_state = block_state_get(failed[j].block); + 474 52470 : n = 0; + 475 52470 : something_to_recover = 0; /* keep track if there is at least one block to fix */ + 476 52470 : something_unsynced = 0; /* keep track if we have some unsynced info to process */ + 477 232734 : for (j = 0; j < failed_count; ++j) { + 478 180264 : unsigned block_state = block_state_get(failed[j].block); 479 : - 480 180481 : if (block_state == BLOCK_STATE_DELETED - 481 171437 : || block_state == BLOCK_STATE_CHG - 482 171437 : || block_state == BLOCK_STATE_REP + 480 180264 : if (block_state == BLOCK_STATE_DELETED + 481 171220 : || block_state == BLOCK_STATE_CHG + 482 171220 : || block_state == BLOCK_STATE_REP 483 : ) { 484 : /* If the block is CHG, REP or DELETED, we don't have the original content of block, */ 485 : /* and we must try to recover it. */ @@ -583,24 +583,24 @@ 521 : /* it also applies to CHG and DELETE blocks because we want to have */ 522 : /* a successful recovering only if a BLK one is matching */ 523 9044 : failed[j].is_outofdate = 1; - 524 171437 : } else if (failed[j].is_bad) { + 524 171220 : } else if (failed[j].is_bad) { 525 : /* If the block is bad we don't know its content, and we try to recover it */ 526 : /* At this point, we can have only BLK ones */ 527 : - 528 171437 : assert(block_state == BLOCK_STATE_BLK); + 528 171220 : assert(block_state == BLOCK_STATE_BLK); 529 : 530 : /* we have something we are interested to recover */ - 531 171437 : something_to_recover = 1; + 531 171220 : something_to_recover = 1; 532 : 533 : /* we try to recover it */ - 534 171437 : failed_map[n] = j; - 535 171437 : ++n; + 534 171220 : failed_map[n] = j; + 535 171220 : ++n; 536 : } 537 : } 538 : 539 : /* if nothing to fix, we just don't try */ 540 : /* if nothing unsynced we also don't retry, because it's the same try as before */ - 541 52575 : if (something_to_recover && something_unsynced) { + 541 52470 : if (something_to_recover && something_unsynced) { 542 9044 : ret = repair_step(state, rehash, pos, diskmax, failed, failed_map, n, buffer, buffer_recov, buffer_zero); 543 9044 : if (ret == 0) { 544 : /* reprocess the REP and CHG blocks, for which we have recovered and old state */ @@ -634,17 +634,17 @@ 572 : else 573 0 : log_tag("recover_unsync:%u:%u: Failed with %d attempts\n", pos, n, ret); 574 : } else { - 575 43531 : log_tag("recover_unsync:%u:%u: Skipped for%s%s\n", pos, n, + 575 43426 : log_tag("recover_unsync:%u:%u: Skipped for%s%s\n", pos, n, 576 : !something_to_recover ? " nothing to recover" : "", 577 : !something_unsynced ? " nothing unsynched" : "" 578 : ); 579 : } 580 : 581 : /* return the number of failed attempts, or -1 if no strategy */ - 582 48053 : if (error) - 583 4801 : return error; + 582 47948 : if (error) + 583 4808 : return error; 584 : else - 585 43252 : return -1; + 585 43140 : return -1; 586 : } 587 : 588 : /** @@ -718,12 +718,12 @@ 656 : /* rename it to .unrecoverable */ 657 : char path_to[PATH_MAX]; 658 : - 659 63283 : pathprint(path_to, sizeof(path_to), "%s%s.unrecoverable", disk->dir, file->sub); + 659 63287 : pathprint(path_to, sizeof(path_to), "%s%s.unrecoverable", disk->dir, file->sub); 660 : 661 : /* ensure to close the file before renaming */ - 662 63283 : if (handle[j].file == file) { - 663 63283 : ret = handle_close(&handle[j]); - 664 63283 : if (ret != 0) { + 662 63287 : if (handle[j].file == file) { + 663 63287 : ret = handle_close(&handle[j]); + 664 63287 : if (ret != 0) { 665 : /* LCOV_EXCL_START */ 666 : log_tag("error:%u:%s:%s: Close error. %s\n", i, disk->name, esc_tag(file->sub, esc_buffer), strerror(errno)); 667 : log_fatal("DANGER! Unexpected close error in a data disk.\n"); @@ -732,8 +732,8 @@ 670 : } 671 : } 672 : - 673 63283 : ret = rename(path, path_to); - 674 63283 : if (ret != 0) { + 673 63287 : ret = rename(path, path_to); + 674 63287 : if (ret != 0) { 675 : /* LCOV_EXCL_START */ 676 : log_fatal("Error renaming '%s' to '%s'. %s.\n", path, path_to, strerror(errno)); 677 : log_fatal("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n"); @@ -741,22 +741,22 @@ 679 : /* LCOV_EXCL_STOP */ 680 : } 681 : - 682 63283 : log_tag("status:unrecoverable:%s:%s\n", disk->name, esc_tag(file->sub, esc_buffer)); - 683 63283 : msg_info("unrecoverable %s\n", fmt_term(disk, file->sub, esc_buffer)); + 682 63287 : log_tag("status:unrecoverable:%s:%s\n", disk->name, esc_tag(file->sub, esc_buffer)); + 683 63287 : msg_info("unrecoverable %s\n", fmt_term(disk, file->sub, esc_buffer)); 684 : 685 : /* and do not set the time if damaged */ - 686 63283 : goto close_and_continue; + 686 63287 : goto close_and_continue; 687 : } 688 : 689 : /* if the file is not fixed, meaning that it is untouched */ - 690 693951 : if (!file_flag_has(file, FILE_IS_FIXED)) { + 690 693947 : if (!file_flag_has(file, FILE_IS_FIXED)) { 691 : /* nothing to do, but close the file */ - 692 574520 : goto close_and_continue; + 692 574476 : goto close_and_continue; 693 : } 694 : 695 : /* if the file is closed or different than the one expected, reopen it */ 696 : /* a different open file could happen when filtering for bad blocks */ - 697 119431 : if (handle[j].file != file) { + 697 119471 : if (handle[j].file != file) { 698 : /* close a potential different file */ 699 0 : ret = handle_close(&handle[j]); 700 0 : if (ret != 0) { @@ -779,13 +779,13 @@ 717 : } 718 : } 719 : - 720 119431 : log_tag("status:recovered:%s:%s\n", disk->name, esc_tag(file->sub, esc_buffer)); - 721 119431 : msg_info("recovered %s\n", fmt_term(disk, file->sub, esc_buffer)); + 720 119471 : log_tag("status:recovered:%s:%s\n", disk->name, esc_tag(file->sub, esc_buffer)); + 721 119471 : msg_info("recovered %s\n", fmt_term(disk, file->sub, esc_buffer)); 722 : - 723 119431 : inode = handle[j].st.st_ino; + 723 119471 : inode = handle[j].st.st_ino; 724 : 725 : /* search for the corresponding inode */ - 726 119431 : collide_file = tommy_hashdyn_search(&disk->inodeset, file_inode_compare_to_arg, &inode, file_inode_hash(inode)); + 726 119471 : collide_file = tommy_hashdyn_search(&disk->inodeset, file_inode_compare_to_arg, &inode, file_inode_hash(inode)); 727 : 728 : /* if the inode is already in the database and it refers at a different file name, */ 729 : /* we can fix the file time ONLY if the time and size allow to differentiate */ @@ -795,15 +795,15 @@ 733 : /* when recreating them the inodes may be reused in a different order, */ 734 : /* and at the next sync some files may have matching inode/size/time even if different name */ 735 : /* not allowing sync to detect that the file is changed and not renamed */ - 736 119431 : if (!collide_file /* if not in the database, there is no collision */ - 737 37411 : || strcmp(collide_file->sub, file->sub) == 0 /* if the name is the same, it's the right collision */ - 738 28341 : || collide_file->size != file->size /* if the size is different, the collision is identified */ + 736 119471 : if (!collide_file /* if not in the database, there is no collision */ + 737 37421 : || strcmp(collide_file->sub, file->sub) == 0 /* if the name is the same, it's the right collision */ + 738 28313 : || collide_file->size != file->size /* if the size is different, the collision is identified */ 739 9 : || collide_file->mtime_sec != file->mtime_sec /* if the mtime is different, the collision is identified */ 740 7 : || collide_file->mtime_nsec != file->mtime_nsec /* same for mtime_nsec */ 741 : ) { 742 : /* set the original modification time */ - 743 119431 : ret = handle_utime(&handle[j]); - 744 238862 : if (ret == -1) { + 743 119471 : ret = handle_utime(&handle[j]); + 744 238942 : if (ret == -1) { 745 : /* LCOV_EXCL_START */ 746 : /* mark the file as damaged */ 747 : file_flag_set(file, FILE_IS_DAMAGED); @@ -818,21 +818,21 @@ 756 : /* we are not fixing, but only checking */ 757 : /* print just the final status */ 758 1308032 : if (file_flag_has(file, FILE_IS_DAMAGED)) { - 759 9499 : if (state->opt.auditonly) { - 760 2799 : log_tag("status:damaged:%s:%s\n", disk->name, esc_tag(file->sub, esc_buffer)); - 761 2799 : msg_info("damaged %s\n", fmt_term(disk, file->sub, esc_buffer)); + 759 9468 : if (state->opt.auditonly) { + 760 2829 : log_tag("status:damaged:%s:%s\n", disk->name, esc_tag(file->sub, esc_buffer)); + 761 2829 : msg_info("damaged %s\n", fmt_term(disk, file->sub, esc_buffer)); 762 : } else { - 763 6700 : log_tag("status:unrecoverable:%s:%s\n", disk->name, esc_tag(file->sub, esc_buffer)); - 764 6700 : msg_info("unrecoverable %s\n", fmt_term(disk, file->sub, esc_buffer)); + 763 6639 : log_tag("status:unrecoverable:%s:%s\n", disk->name, esc_tag(file->sub, esc_buffer)); + 764 6639 : msg_info("unrecoverable %s\n", fmt_term(disk, file->sub, esc_buffer)); 765 : } - 766 1298533 : } else if (file_flag_has(file, FILE_IS_FIXED)) { - 767 76212 : log_tag("status:recoverable:%s:%s\n", disk->name, esc_tag(file->sub, esc_buffer)); - 768 76212 : msg_info("recoverable %s\n", fmt_term(disk, file->sub, esc_buffer)); + 766 1298564 : } else if (file_flag_has(file, FILE_IS_FIXED)) { + 767 76301 : log_tag("status:recoverable:%s:%s\n", disk->name, esc_tag(file->sub, esc_buffer)); + 768 76301 : msg_info("recoverable %s\n", fmt_term(disk, file->sub, esc_buffer)); 769 : } else { 770 : /* we don't use msg_verbose() because it also goes into the log */ - 771 1222321 : if (msg_level >= MSG_VERBOSE) { - 772 23229 : log_tag("status:correct:%s:%s\n", disk->name, esc_tag(file->sub, esc_buffer)); - 773 23229 : msg_info("correct %s\n", fmt_term(disk, file->sub, esc_buffer)); + 771 1222263 : if (msg_level >= MSG_VERBOSE) { + 772 23199 : log_tag("status:correct:%s:%s\n", disk->name, esc_tag(file->sub, esc_buffer)); + 773 23199 : msg_info("correct %s\n", fmt_term(disk, file->sub, esc_buffer)); 774 : } 775 : } 776 : } @@ -844,8 +844,8 @@ 782 2162259 : if (handle[j].file == file) { 783 : /* ensure to close the file just after finishing with it */ 784 : /* to avoid to keep it open without any possible use */ - 785 1978440 : ret = handle_close(&handle[j]); - 786 1978440 : if (ret != 0) { + 785 1978527 : ret = handle_close(&handle[j]); + 786 1978527 : if (ret != 0) { 787 : /* LCOV_EXCL_START */ 788 : log_tag("error:%u:%s:%s: Close error. %s\n", i, disk->name, esc_tag(file->sub, esc_buffer), strerror(errno)); 789 : log_fatal("DANGER! Unexpected close error in a data disk.\n"); @@ -971,1118 +971,1122 @@ 909 : /* post process the files */ 910 25246 : ret = file_post(state, fix, i, handle, diskmax); 911 25246 : if (ret == -1) { - 912 0 : log_fatal("Stopping at block %u\n", i); - 913 0 : ++unrecoverable_error; - 914 0 : goto bail; - 915 : } - 916 : - 917 : /* and now continue with the next block */ - 918 25246 : continue; - 919 : } - 920 : - 921 : /* If we have valid parity, and it makes sense to check its content. */ - 922 : /* If we already know that the parity is invalid, we just read the file */ - 923 : /* but we don't report parity errors */ - 924 : /* Note that with auditonly, we anyway skip the full parity check, */ - 925 : /* because we also don't read it at all */ - 926 910233 : valid_parity = 1; - 927 : - 928 : /* keep track of the number of failed blocks */ - 929 910233 : failed_count = 0; - 930 : - 931 : /* get block specific info */ - 932 910233 : info = info_get(&state->infoarr, i); - 933 : - 934 : /* if we have to use the old hash */ - 935 910233 : rehash = info_get_rehash(info); - 936 : - 937 : /* for each disk, process the block */ - 938 6371631 : for (j = 0; j < diskmax; ++j) { - 939 : int read_size; - 940 : unsigned char hash[HASH_MAX]; - 941 : struct snapraid_disk* disk; - 942 : struct snapraid_block* block; - 943 : struct snapraid_file* file; - 944 : block_off_t file_pos; - 945 : unsigned block_state; - 946 : - 947 : /* if the disk position is not used */ - 948 5461398 : disk = handle[j].disk; - 949 5461398 : if (!disk) { - 950 : /* use an empty block */ - 951 14061 : memset(buffer[j], 0, state->block_size); - 952 955462 : continue; - 953 : } - 954 : - 955 : /* if the disk block is not used */ - 956 5447337 : block = fs_par2block_find(disk, i); - 957 5447337 : if (block == BLOCK_NULL) { - 958 : /* use an empty block */ - 959 192063 : memset(buffer[j], 0, state->block_size); - 960 192063 : continue; - 961 : } - 962 : - 963 : /* get the state of the block */ - 964 5255274 : block_state = block_state_get(block); - 965 : - 966 : /* if the parity is not valid */ - 967 5255274 : if (block_has_invalid_parity(block)) { - 968 : /* mark the parity as invalid, and don't try to check/fix it */ - 969 : /* because it will be recomputed at the next sync */ - 970 94587 : valid_parity = 0; - 971 : /* follow */ - 972 : } - 973 : - 974 : /* if the block is DELETED */ - 975 5255274 : if (block_state == BLOCK_STATE_DELETED) { - 976 : /* use an empty block */ - 977 18454 : memset(buffer[j], 0, state->block_size); - 978 : - 979 : /* store it in the failed set, because potentially */ - 980 : /* the parity may be still computed with the previous content */ - 981 18454 : failed[failed_count].is_bad = 0; /* note that is_bad==0 <=> file==0 */ - 982 18454 : failed[failed_count].is_outofdate = 0; - 983 18454 : failed[failed_count].index = j; - 984 18454 : failed[failed_count].block = block; - 985 18454 : failed[failed_count].disk = disk; - 986 18454 : failed[failed_count].file = 0; - 987 18454 : failed[failed_count].file_pos = 0; - 988 18454 : failed[failed_count].handle = 0; - 989 18454 : ++failed_count; - 990 18454 : continue; - 991 : } - 992 : - 993 : /* get the file of this block */ - 994 5236820 : file = fs_par2file_get(disk, i, &file_pos); - 995 : - 996 : /* if we are only hashing, we can skip excluded files and don't even read them */ - 997 5236820 : if (state->opt.auditonly && file_flag_has(file, FILE_IS_EXCLUDED)) { - 998 : /* use an empty block */ - 999 : /* in true, this is unnecessary, because we are not checking any parity */ - 1000 : /* but we keep it for completeness */ - 1001 0 : memset(buffer[j], 0, state->block_size); - 1002 0 : continue; - 1003 : } - 1004 : - 1005 : /* if the file is closed or different than the current one */ - 1006 5236820 : if (handle[j].file == 0 || handle[j].file != file) { - 1007 : /* close the old one, if any */ - 1008 2260089 : ret = handle_close(&handle[j]); - 1009 2260089 : if (ret == -1) { - 1010 : /* LCOV_EXCL_START */ - 1011 : log_tag("error:%u:%s:%s: Close error. %s\n", i, disk->name, esc_tag(handle[j].file->sub, esc_buffer), strerror(errno)); - 1012 : log_fatal("DANGER! Unexpected close error in a data disk.\n"); - 1013 : log_fatal("Stopping at block %u\n", i); - 1014 : ++unrecoverable_error; - 1015 : goto bail; - 1016 : /* LCOV_EXCL_STOP */ - 1017 : } - 1018 : - 1019 : /* if fixing, and the file is not excluded, we must open for writing */ - 1020 2260089 : if (fix && !file_flag_has(file, FILE_IS_EXCLUDED)) { - 1021 : /* if fixing, create the file, open for writing and resize if required */ - 1022 771311 : ret = handle_create(&handle[j], file, state->file_mode); - 1023 771311 : if (ret == -1) { - 1024 : /* LCOV_EXCL_START */ - 1025 : if (errno == EACCES) { - 1026 : log_fatal("WARNING! Please give write permission to the file.\n"); - 1027 : } else { - 1028 : log_fatal("DANGER! Without a working data disk, it isn't possible to fix errors on it.\n"); - 1029 : } - 1030 : log_fatal("Stopping at block %u\n", i); - 1031 : ++unrecoverable_error; - 1032 : goto bail; - 1033 : /* LCOV_EXCL_STOP */ - 1034 : } - 1035 : - 1036 : /* check if the file was just created */ - 1037 1542622 : if (handle[j].created != 0) { - 1038 : /* if fragmented, it may be reopened, so remember that the file */ - 1039 : /* was originally missing */ - 1040 113135 : file_flag_set(file, FILE_IS_CREATED); - 1041 : } - 1042 : } else { - 1043 : /* open the file only for reading */ - 1044 1488778 : if (!file_flag_has(file, FILE_IS_MISSING)) - 1045 1372856 : ret = handle_open(&handle[j], file, state->file_mode, - 1046 1372856 : log_error, state->opt.expected_missing ? log_expected : 0); - 1047 : else - 1048 115922 : ret = -1; /* if the file is missing, we cannot open it */ - 1049 1488778 : if (ret == -1) { - 1050 : /* save the failed block for the check/fix */ - 1051 194661 : failed[failed_count].is_bad = 1; - 1052 194661 : failed[failed_count].is_outofdate = 0; - 1053 194661 : failed[failed_count].index = j; - 1054 194661 : failed[failed_count].block = block; - 1055 194661 : failed[failed_count].disk = disk; - 1056 194661 : failed[failed_count].file = file; - 1057 194661 : failed[failed_count].file_pos = file_pos; - 1058 194661 : failed[failed_count].handle = &handle[j]; - 1059 194661 : ++failed_count; - 1060 : - 1061 194661 : log_tag("error:%u:%s:%s: Open error at position %u\n", i, disk->name, esc_tag(file->sub, esc_buffer), file_pos); - 1062 194661 : ++error; - 1063 : - 1064 : /* mark the file as missing, to avoid to retry to open it again */ - 1065 : /* note that this can be done only if we are not fixing it */ - 1066 : /* otherwise, it could be recreated */ - 1067 194661 : file_flag_set(file, FILE_IS_MISSING); - 1068 194661 : continue; - 1069 : } - 1070 : } - 1071 : - 1072 : /* if it's the first open, and not excluded */ - 1073 2065428 : if (!file_flag_has(file, FILE_IS_OPENED) - 1074 2050067 : && !file_flag_has(file, FILE_IS_EXCLUDED)) { - 1075 : - 1076 : /* check if the file is changed */ - 1077 1998636 : if (handle[j].st.st_size != file->size - 1078 1805944 : || handle[j].st.st_mtime != file->mtime_sec - 1079 1781522 : || STAT_NSEC(&handle[j].st) != file->mtime_nsec - 1080 : /* don't check the inode to support file-system without persistent inodes */ - 1081 : ) { - 1082 : /* report that the file is not synced */ - 1083 217114 : file_flag_set(file, FILE_IS_UNSYNCED); - 1084 : } - 1085 : } - 1086 : - 1087 : /* if it's the first open, and not excluded and larger */ - 1088 2065428 : if (!file_flag_has(file, FILE_IS_OPENED) - 1089 2050067 : && !file_flag_has(file, FILE_IS_EXCLUDED) - 1090 1998636 : && !(state->opt.syncedonly && file_flag_has(file, FILE_IS_UNSYNCED)) - 1091 1998636 : && handle[j].st.st_size > file->size - 1092 : ) { - 1093 8724 : log_error("File '%s' is larger than expected.\n", handle[j].path); - 1094 8724 : log_tag("error:%u:%s:%s: Size error\n", i, disk->name, esc_tag(file->sub, esc_buffer)); - 1095 8724 : ++error; - 1096 : - 1097 8724 : if (fix) { - 1098 3222 : ret = handle_truncate(&handle[j], file); - 1099 3222 : if (ret == -1) { - 1100 : /* LCOV_EXCL_START */ - 1101 : log_fatal("DANGER! Unexpected truncate error in a data disk, it isn't possible to fix.\n"); - 1102 : log_fatal("Stopping at block %u\n", i); - 1103 : ++unrecoverable_error; - 1104 : goto bail; - 1105 : /* LCOV_EXCL_STOP */ - 1106 : } - 1107 : - 1108 3222 : log_tag("fixed:%u:%s:%s: Fixed size\n", i, disk->name, esc_tag(file->sub, esc_buffer)); - 1109 3222 : ++recovered_error; - 1110 : } - 1111 : } - 1112 : - 1113 : /* mark the file as opened at least one time */ - 1114 : /* this is used to avoid to check the unsynced and size */ - 1115 : /* more than one time, in case the file is reopened later */ - 1116 2065428 : file_flag_set(file, FILE_IS_OPENED); - 1117 : } - 1118 : - 1119 : /* read from the file */ - 1120 5042159 : read_size = handle_read(&handle[j], file_pos, buffer[j], state->block_size, - 1121 5042159 : log_error, state->opt.expected_missing ? log_expected : 0); - 1122 5042159 : if (read_size == -1) { - 1123 : /* save the failed block for the check/fix */ - 1124 442169 : failed[failed_count].is_bad = 1; /* it's bad because we cannot read it */ - 1125 442169 : failed[failed_count].is_outofdate = 0; - 1126 442169 : failed[failed_count].index = j; - 1127 442169 : failed[failed_count].block = block; - 1128 442169 : failed[failed_count].disk = disk; - 1129 442169 : failed[failed_count].file = file; - 1130 442169 : failed[failed_count].file_pos = file_pos; - 1131 442169 : failed[failed_count].handle = &handle[j]; - 1132 442169 : ++failed_count; - 1133 : - 1134 442169 : log_tag("error:%u:%s:%s: Read error at position %u\n", i, disk->name, esc_tag(file->sub, esc_buffer), file_pos); - 1135 442169 : ++error; - 1136 442169 : continue; - 1137 : } - 1138 : - 1139 4599990 : countsize += read_size; + 912 : /* LCOV_EXCL_START */ + 913 : log_fatal("Stopping at block %u\n", i); + 914 : ++unrecoverable_error; + 915 : goto bail; + 916 : /* LCOV_EXCL_STOP */ + 917 : } + 918 : + 919 : /* and now continue with the next block */ + 920 25246 : continue; + 921 : } + 922 : + 923 : /* If we have valid parity, and it makes sense to check its content. */ + 924 : /* If we already know that the parity is invalid, we just read the file */ + 925 : /* but we don't report parity errors */ + 926 : /* Note that with auditonly, we anyway skip the full parity check, */ + 927 : /* because we also don't read it at all */ + 928 910233 : valid_parity = 1; + 929 : + 930 : /* keep track of the number of failed blocks */ + 931 910233 : failed_count = 0; + 932 : + 933 : /* get block specific info */ + 934 910233 : info = info_get(&state->infoarr, i); + 935 : + 936 : /* if we have to use the old hash */ + 937 910233 : rehash = info_get_rehash(info); + 938 : + 939 : /* for each disk, process the block */ + 940 6371631 : for (j = 0; j < diskmax; ++j) { + 941 : int read_size; + 942 : unsigned char hash[HASH_MAX]; + 943 : struct snapraid_disk* disk; + 944 : struct snapraid_block* block; + 945 : struct snapraid_file* file; + 946 : block_off_t file_pos; + 947 : unsigned block_state; + 948 : + 949 : /* if the disk position is not used */ + 950 5461398 : disk = handle[j].disk; + 951 5461398 : if (!disk) { + 952 : /* use an empty block */ + 953 14061 : memset(buffer[j], 0, state->block_size); + 954 955271 : continue; + 955 : } + 956 : + 957 : /* if the disk block is not used */ + 958 5447337 : block = fs_par2block_find(disk, i); + 959 5447337 : if (block == BLOCK_NULL) { + 960 : /* use an empty block */ + 961 192063 : memset(buffer[j], 0, state->block_size); + 962 192063 : continue; + 963 : } + 964 : + 965 : /* get the state of the block */ + 966 5255274 : block_state = block_state_get(block); + 967 : + 968 : /* if the parity is not valid */ + 969 5255274 : if (block_has_invalid_parity(block)) { + 970 : /* mark the parity as invalid, and don't try to check/fix it */ + 971 : /* because it will be recomputed at the next sync */ + 972 94587 : valid_parity = 0; + 973 : /* follow */ + 974 : } + 975 : + 976 : /* if the block is DELETED */ + 977 5255274 : if (block_state == BLOCK_STATE_DELETED) { + 978 : /* use an empty block */ + 979 18454 : memset(buffer[j], 0, state->block_size); + 980 : + 981 : /* store it in the failed set, because potentially */ + 982 : /* the parity may be still computed with the previous content */ + 983 18454 : failed[failed_count].is_bad = 0; /* note that is_bad==0 <=> file==0 */ + 984 18454 : failed[failed_count].is_outofdate = 0; + 985 18454 : failed[failed_count].index = j; + 986 18454 : failed[failed_count].block = block; + 987 18454 : failed[failed_count].disk = disk; + 988 18454 : failed[failed_count].file = 0; + 989 18454 : failed[failed_count].file_pos = 0; + 990 18454 : failed[failed_count].handle = 0; + 991 18454 : ++failed_count; + 992 18454 : continue; + 993 : } + 994 : + 995 : /* get the file of this block */ + 996 5236820 : file = fs_par2file_get(disk, i, &file_pos); + 997 : + 998 : /* if we are only hashing, we can skip excluded files and don't even read them */ + 999 5236820 : if (state->opt.auditonly && file_flag_has(file, FILE_IS_EXCLUDED)) { + 1000 : /* use an empty block */ + 1001 : /* in true, this is unnecessary, because we are not checking any parity */ + 1002 : /* but we keep it for completeness */ + 1003 0 : memset(buffer[j], 0, state->block_size); + 1004 0 : continue; + 1005 : } + 1006 : + 1007 : /* if the file is closed or different than the current one */ + 1008 5236820 : if (handle[j].file == 0 || handle[j].file != file) { + 1009 : /* close the old one, if any */ + 1010 2259726 : ret = handle_close(&handle[j]); + 1011 2259726 : if (ret == -1) { + 1012 : /* LCOV_EXCL_START */ + 1013 : log_tag("error:%u:%s:%s: Close error. %s\n", i, disk->name, esc_tag(handle[j].file->sub, esc_buffer), strerror(errno)); + 1014 : log_fatal("DANGER! Unexpected close error in a data disk.\n"); + 1015 : log_fatal("Stopping at block %u\n", i); + 1016 : ++unrecoverable_error; + 1017 : goto bail; + 1018 : /* LCOV_EXCL_STOP */ + 1019 : } + 1020 : + 1021 : /* if fixing, and the file is not excluded, we must open for writing */ + 1022 2259726 : if (fix && !file_flag_has(file, FILE_IS_EXCLUDED)) { + 1023 : /* if fixing, create the file, open for writing and resize if required */ + 1024 771305 : ret = handle_create(&handle[j], file, state->file_mode); + 1025 771305 : if (ret == -1) { + 1026 : /* LCOV_EXCL_START */ + 1027 : if (errno == EACCES) { + 1028 : log_fatal("WARNING! Please give write permission to the file.\n"); + 1029 : } else { + 1030 : log_fatal("DANGER! Without a working data disk, it isn't possible to fix errors on it.\n"); + 1031 : } + 1032 : log_fatal("Stopping at block %u\n", i); + 1033 : ++unrecoverable_error; + 1034 : goto bail; + 1035 : /* LCOV_EXCL_STOP */ + 1036 : } + 1037 : + 1038 : /* check if the file was just created */ + 1039 1542610 : if (handle[j].created != 0) { + 1040 : /* if fragmented, it may be reopened, so remember that the file */ + 1041 : /* was originally missing */ + 1042 113067 : file_flag_set(file, FILE_IS_CREATED); + 1043 : } + 1044 : } else { + 1045 : /* open the file only for reading */ + 1046 1488421 : if (!file_flag_has(file, FILE_IS_MISSING)) + 1047 1372845 : ret = handle_open(&handle[j], file, state->file_mode, + 1048 1372845 : log_error, state->opt.expected_missing ? log_expected : 0); + 1049 : else + 1050 115576 : ret = -1; /* if the file is missing, we cannot open it */ + 1051 1488421 : if (ret == -1) { + 1052 : /* save the failed block for the check/fix */ + 1053 194224 : failed[failed_count].is_bad = 1; + 1054 194224 : failed[failed_count].is_outofdate = 0; + 1055 194224 : failed[failed_count].index = j; + 1056 194224 : failed[failed_count].block = block; + 1057 194224 : failed[failed_count].disk = disk; + 1058 194224 : failed[failed_count].file = file; + 1059 194224 : failed[failed_count].file_pos = file_pos; + 1060 194224 : failed[failed_count].handle = &handle[j]; + 1061 194224 : ++failed_count; + 1062 : + 1063 194224 : log_tag("error:%u:%s:%s: Open error at position %u\n", i, disk->name, esc_tag(file->sub, esc_buffer), file_pos); + 1064 194224 : ++error; + 1065 : + 1066 : /* mark the file as missing, to avoid to retry to open it again */ + 1067 : /* note that this can be done only if we are not fixing it */ + 1068 : /* otherwise, it could be recreated */ + 1069 194224 : file_flag_set(file, FILE_IS_MISSING); + 1070 194224 : continue; + 1071 : } + 1072 : } + 1073 : + 1074 : /* if it's the first open, and not excluded */ + 1075 2065502 : if (!file_flag_has(file, FILE_IS_OPENED) + 1076 2050149 : && !file_flag_has(file, FILE_IS_EXCLUDED)) { + 1077 : + 1078 : /* check if the file is changed */ + 1079 1998718 : if (handle[j].st.st_size != file->size + 1080 1805971 : || handle[j].st.st_mtime != file->mtime_sec + 1081 1781347 : || STAT_NSEC(&handle[j].st) != file->mtime_nsec + 1082 : /* don't check the inode to support file-system without persistent inodes */ + 1083 : ) { + 1084 : /* report that the file is not synced */ + 1085 217371 : file_flag_set(file, FILE_IS_UNSYNCED); + 1086 : } + 1087 : } + 1088 : + 1089 : /* if it's the first open, and not excluded and larger */ + 1090 2065502 : if (!file_flag_has(file, FILE_IS_OPENED) + 1091 2050149 : && !file_flag_has(file, FILE_IS_EXCLUDED) + 1092 1998718 : && !(state->opt.syncedonly && file_flag_has(file, FILE_IS_UNSYNCED)) + 1093 1998718 : && handle[j].st.st_size > file->size + 1094 : ) { + 1095 8628 : log_error("File '%s' is larger than expected.\n", handle[j].path); + 1096 8628 : log_tag("error:%u:%s:%s: Size error\n", i, disk->name, esc_tag(file->sub, esc_buffer)); + 1097 8628 : ++error; + 1098 : + 1099 8628 : if (fix) { + 1100 3180 : ret = handle_truncate(&handle[j], file); + 1101 3180 : if (ret == -1) { + 1102 : /* LCOV_EXCL_START */ + 1103 : log_fatal("DANGER! Unexpected truncate error in a data disk, it isn't possible to fix.\n"); + 1104 : log_fatal("Stopping at block %u\n", i); + 1105 : ++unrecoverable_error; + 1106 : goto bail; + 1107 : /* LCOV_EXCL_STOP */ + 1108 : } + 1109 : + 1110 3180 : log_tag("fixed:%u:%s:%s: Fixed size\n", i, disk->name, esc_tag(file->sub, esc_buffer)); + 1111 3180 : ++recovered_error; + 1112 : } + 1113 : } + 1114 : + 1115 : /* mark the file as opened at least one time */ + 1116 : /* this is used to avoid to check the unsynced and size */ + 1117 : /* more than one time, in case the file is reopened later */ + 1118 2065502 : file_flag_set(file, FILE_IS_OPENED); + 1119 : } + 1120 : + 1121 : /* read from the file */ + 1122 5042596 : read_size = handle_read(&handle[j], file_pos, buffer[j], state->block_size, + 1123 5042596 : log_error, state->opt.expected_missing ? log_expected : 0); + 1124 5042596 : if (read_size == -1) { + 1125 : /* save the failed block for the check/fix */ + 1126 442271 : failed[failed_count].is_bad = 1; /* it's bad because we cannot read it */ + 1127 442271 : failed[failed_count].is_outofdate = 0; + 1128 442271 : failed[failed_count].index = j; + 1129 442271 : failed[failed_count].block = block; + 1130 442271 : failed[failed_count].disk = disk; + 1131 442271 : failed[failed_count].file = file; + 1132 442271 : failed[failed_count].file_pos = file_pos; + 1133 442271 : failed[failed_count].handle = &handle[j]; + 1134 442271 : ++failed_count; + 1135 : + 1136 442271 : log_tag("error:%u:%s:%s: Read error at position %u\n", i, disk->name, esc_tag(file->sub, esc_buffer), file_pos); + 1137 442271 : ++error; + 1138 442271 : continue; + 1139 : } 1140 : - 1141 : /* always insert CHG blocks, the repair functions needs all of them */ - 1142 : /* because the parity may be still referring at the old state */ - 1143 : /* and the repair must be aware of it */ - 1144 4599990 : if (block_state == BLOCK_STATE_CHG) { - 1145 : /* we DO NOT mark them as bad to avoid to overwrite them with wrong data. */ - 1146 : /* if we don't have a hash, we always assume the first read of the block correct. */ - 1147 13843 : failed[failed_count].is_bad = 0; /* we assume the CHG block correct */ - 1148 13843 : failed[failed_count].is_outofdate = 0; - 1149 13843 : failed[failed_count].index = j; - 1150 13843 : failed[failed_count].block = block; - 1151 13843 : failed[failed_count].disk = disk; - 1152 13843 : failed[failed_count].file = file; - 1153 13843 : failed[failed_count].file_pos = file_pos; - 1154 13843 : failed[failed_count].handle = &handle[j]; - 1155 13843 : ++failed_count; - 1156 13843 : continue; - 1157 : } - 1158 : - 1159 4586147 : assert(block_state == BLOCK_STATE_BLK || block_state == BLOCK_STATE_REP); + 1141 4600325 : countsize += read_size; + 1142 : + 1143 : /* always insert CHG blocks, the repair functions needs all of them */ + 1144 : /* because the parity may be still referring at the old state */ + 1145 : /* and the repair must be aware of it */ + 1146 4600325 : if (block_state == BLOCK_STATE_CHG) { + 1147 : /* we DO NOT mark them as bad to avoid to overwrite them with wrong data. */ + 1148 : /* if we don't have a hash, we always assume the first read of the block correct. */ + 1149 13843 : failed[failed_count].is_bad = 0; /* we assume the CHG block correct */ + 1150 13843 : failed[failed_count].is_outofdate = 0; + 1151 13843 : failed[failed_count].index = j; + 1152 13843 : failed[failed_count].block = block; + 1153 13843 : failed[failed_count].disk = disk; + 1154 13843 : failed[failed_count].file = file; + 1155 13843 : failed[failed_count].file_pos = file_pos; + 1156 13843 : failed[failed_count].handle = &handle[j]; + 1157 13843 : ++failed_count; + 1158 13843 : continue; + 1159 : } 1160 : - 1161 : /* compute the hash of the block just read */ - 1162 4586147 : if (rehash) { - 1163 27243 : memhash(state->prevhash, state->prevhashseed, hash, buffer[j], read_size); - 1164 : } else { - 1165 4558904 : memhash(state->hash, state->hashseed, hash, buffer[j], read_size); - 1166 : } - 1167 : - 1168 : /* compare the hash */ - 1169 4586147 : if (memcmp(hash, block->hash, BLOCK_HASH_SIZE) != 0) { - 1170 12722 : unsigned diff = memdiff(hash, block->hash, BLOCK_HASH_SIZE); - 1171 : - 1172 : /* save the failed block for the check/fix */ - 1173 12722 : failed[failed_count].is_bad = 1; /* it's bad because the hash doesn't match */ - 1174 12722 : failed[failed_count].is_outofdate = 0; - 1175 12722 : failed[failed_count].index = j; - 1176 12722 : failed[failed_count].block = block; - 1177 12722 : failed[failed_count].disk = disk; - 1178 12722 : failed[failed_count].file = file; - 1179 12722 : failed[failed_count].file_pos = file_pos; - 1180 12722 : failed[failed_count].handle = &handle[j]; - 1181 12722 : ++failed_count; - 1182 : - 1183 12722 : log_tag("error:%u:%s:%s: Data error at position %u, diff bits %u\n", i, disk->name, esc_tag(file->sub, esc_buffer), file_pos, diff); - 1184 12722 : ++error; - 1185 12722 : continue; - 1186 : } - 1187 : - 1188 : /* always insert REP blocks, the repair functions needs all of them */ - 1189 : /* because the parity may be still referring at the old state */ - 1190 : /* and the repair must be aware of it */ - 1191 4573425 : if (block_state == BLOCK_STATE_REP) { - 1192 53428 : failed[failed_count].is_bad = 0; /* it's not bad */ - 1193 53428 : failed[failed_count].is_outofdate = 0; - 1194 53428 : failed[failed_count].index = j; - 1195 53428 : failed[failed_count].block = block; - 1196 53428 : failed[failed_count].disk = disk; - 1197 53428 : failed[failed_count].file = file; - 1198 53428 : failed[failed_count].file_pos = file_pos; - 1199 53428 : failed[failed_count].handle = &handle[j]; - 1200 53428 : ++failed_count; - 1201 53428 : continue; - 1202 : } - 1203 : } - 1204 : - 1205 : /* now read and check the parity if requested */ - 1206 910233 : if (!state->opt.auditonly) { - 1207 : void* buffer_recov[LEV_MAX]; - 1208 : void* buffer_zero; - 1209 : - 1210 : /* buffers for parity read and not computed */ - 1211 4170787 : for (l = 0; l < state->level; ++l) - 1212 3299829 : buffer_recov[l] = buffer[diskmax + state->level + l]; - 1213 2796877 : for (; l < LEV_MAX; ++l) - 1214 1925919 : buffer_recov[l] = 0; - 1215 : - 1216 : /* the zero buffer is the last one */ - 1217 870958 : buffer_zero = buffer[buffermax - 1]; - 1218 : - 1219 : /* read the parity */ - 1220 4170787 : for (l = 0; l < state->level; ++l) { - 1221 3299829 : if (parity[l]) { - 1222 3285927 : ret = parity_read(parity[l], i, buffer_recov[l], state->block_size, log_error); - 1223 3285927 : if (ret == -1) { - 1224 11360 : buffer_recov[l] = 0; /* no parity to use */ - 1225 : - 1226 11360 : log_tag("parity_error:%u:%s: Read error\n", i, lev_config_name(l)); - 1227 11360 : ++error; - 1228 : } - 1229 : } else { - 1230 13902 : buffer_recov[l] = 0; - 1231 : } - 1232 : } - 1233 : - 1234 : /* try all the recovering strategies */ - 1235 870958 : ret = repair(state, rehash, i, diskmax, failed, failed_map, failed_count, buffer, buffer_recov, buffer_zero); - 1236 870958 : if (ret != 0) { - 1237 : /* increment the number of errors */ - 1238 48053 : if (ret > 0) - 1239 4801 : error += ret; - 1240 48053 : ++unrecoverable_error; - 1241 : - 1242 : /* print a list of all the errors in files */ - 1243 219490 : for (j = 0; j < failed_count; ++j) { - 1244 171437 : if (failed[j].is_bad) - 1245 166915 : log_tag("unrecoverable:%u:%s:%s: Unrecoverable error at position %u\n", i, failed[j].disk->name, esc_tag(failed[j].file->sub, esc_buffer), failed[j].file_pos); - 1246 : } - 1247 : - 1248 : /* keep track of damaged files */ - 1249 219490 : for (j = 0; j < failed_count; ++j) { - 1250 171437 : if (failed[j].is_bad) - 1251 166915 : file_flag_set(failed[j].file, FILE_IS_DAMAGED); - 1252 : } - 1253 : } else { - 1254 : /* now counts partial recovers */ - 1255 : /* note that this could happen only when we have an incomplete 'sync' */ - 1256 : /* and that we have recovered is the state before the 'sync' */ - 1257 822905 : int partial_recover_error = 0; - 1258 : - 1259 : /* print a list of all the errors in files */ - 1260 1380849 : for (j = 0; j < failed_count; ++j) { - 1261 557944 : if (failed[j].is_bad && failed[j].is_outofdate) { - 1262 8 : ++partial_recover_error; - 1263 8 : log_tag("unrecoverable:%u:%s:%s: Unrecoverable unsynced error at position %u\n", i, failed[j].disk->name, esc_tag(failed[j].file->sub, esc_buffer), failed[j].file_pos); - 1264 : } - 1265 : } - 1266 822905 : if (partial_recover_error != 0) { - 1267 8 : error += partial_recover_error; - 1268 8 : ++unrecoverable_error; - 1269 : } - 1270 : - 1271 : /* now check parities, but only if all the blocks have it computed */ - 1272 : /* if you check/fix after a partial sync, it's OK to have parity errors on the blocks with invalid parity */ - 1273 : /* and doesn't make sense to try to fix it */ - 1274 822905 : if (valid_parity) { - 1275 : /* check the parity */ - 1276 3728710 : for (l = 0; l < state->level; ++l) { - 1277 2967390 : if (buffer_recov[l] != 0 && memcmp(buffer_recov[l], buffer[diskmax + l], state->block_size) != 0) { - 1278 78690 : unsigned diff = memdiff(buffer_recov[l], buffer[diskmax + l], state->block_size); - 1279 : - 1280 : /* mark that the read parity is wrong, setting ptr to 0 */ - 1281 78690 : buffer_recov[l] = 0; - 1282 : - 1283 78690 : log_tag("parity_error:%u:%s: Data error, diff bits %u\n", i, lev_config_name(l), diff); - 1284 78690 : ++error; - 1285 : } - 1286 : } - 1287 : } - 1288 : - 1289 : /* now write recovered files */ - 1290 822905 : if (fix) { - 1291 : /* update the fixed files */ - 1292 652804 : for (j = 0; j < failed_count; ++j) { - 1293 : /* nothing to do if it doesn't need recovering */ - 1294 338160 : if (!failed[j].is_bad) - 1295 40318 : continue; - 1296 : - 1297 : /* do not fix if the file is excluded */ - 1298 297842 : if (file_flag_has(failed[j].file, FILE_IS_EXCLUDED) - 1299 288562 : || (state->opt.syncedonly && file_flag_has(failed[j].file, FILE_IS_UNSYNCED))) - 1300 9280 : continue; - 1301 : - 1302 288562 : ret = handle_write(failed[j].handle, failed[j].file_pos, buffer[failed[j].index], state->block_size); - 1303 288562 : if (ret == -1) { - 1304 : /* LCOV_EXCL_START */ - 1305 : /* mark the file as damaged */ - 1306 : file_flag_set(failed[j].file, FILE_IS_DAMAGED); - 1307 : - 1308 : if (errno == EACCES) { - 1309 : log_fatal("WARNING! Please give write permission to the file.\n"); - 1310 : } else { - 1311 : /* we do not use DANGER because it could be ENOSPC which is not always correctly reported */ - 1312 : log_fatal("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n"); - 1313 : } - 1314 : log_fatal("Stopping at block %u\n", i); - 1315 : ++unrecoverable_error; - 1316 : goto bail; - 1317 : /* LCOV_EXCL_STOP */ - 1318 : } - 1319 : - 1320 : /* if we are not sure that the recovered content is uptodate */ - 1321 288562 : if (failed[j].is_outofdate) { - 1322 : /* mark the file as damaged */ - 1323 8 : file_flag_set(failed[j].file, FILE_IS_DAMAGED); - 1324 8 : continue; - 1325 : } - 1326 : - 1327 : /* mark the file as containing some fixes */ - 1328 : /* note that it could be also marked as damaged in other iterations */ - 1329 288554 : file_flag_set(failed[j].file, FILE_IS_FIXED); - 1330 : - 1331 288554 : log_tag("fixed:%u:%s:%s: Fixed data error at position %u\n", i, failed[j].disk->name, esc_tag(failed[j].file->sub, esc_buffer), failed[j].file_pos); - 1332 288554 : ++recovered_error; - 1333 : } - 1334 : - 1335 : /* update parity only if all the blocks have it computed */ - 1336 : /* if you check/fix after a partial sync, you do not want to fix parity */ - 1337 : /* for blocks that are going to have it computed in the sync completion */ - 1338 314644 : if (valid_parity) { - 1339 : /* update the parity */ - 1340 964013 : for (l = 0; l < state->level; ++l) { - 1341 : /* if the parity on disk is wrong */ - 1342 698549 : if (buffer_recov[l] == 0 - 1343 : /* and we have access at the parity */ - 1344 72150 : && parity[l] != 0 - 1345 : /* and the parity is not excluded */ - 1346 67463 : && !state->parity[l].is_excluded - 1347 : ) { - 1348 67463 : ret = parity_write(parity[l], i, buffer[diskmax + l], state->block_size); - 1349 67463 : if (ret == -1) { - 1350 : /* LCOV_EXCL_START */ - 1351 : /* we do not use DANGER because it could be ENOSPC which is not always correctly reported */ - 1352 : log_fatal("WARNING! Without a working %s disk, it isn't possible to fix errors on it.\n", lev_name(l)); - 1353 : log_fatal("Stopping at block %u\n", i); - 1354 : ++unrecoverable_error; - 1355 : goto bail; - 1356 : /* LCOV_EXCL_STOP */ - 1357 : } - 1358 : - 1359 67463 : log_tag("parity_fixed:%u:%s: Fixed data error\n", i, lev_config_name(l)); - 1360 67463 : ++recovered_error; - 1361 : } - 1362 : } - 1363 : } - 1364 : } else { - 1365 : /* if we are not fixing, we just set the FIXED flag */ - 1366 : /* meaning that we could fix this file if we try */ - 1367 728045 : for (j = 0; j < failed_count; ++j) { - 1368 219784 : if (failed[j].is_bad) { - 1369 178899 : file_flag_set(failed[j].file, FILE_IS_FIXED); - 1370 : } - 1371 : } - 1372 : } - 1373 : } - 1374 : } else { - 1375 : /* if we are not checking, we just set the DAMAGED flag */ - 1376 : /* to report that the file is damaged, and we don't know if we can fix it */ - 1377 45171 : for (j = 0; j < failed_count; ++j) { - 1378 5896 : if (failed[j].is_bad) { - 1379 5896 : file_flag_set(failed[j].file, FILE_IS_DAMAGED); - 1380 : } - 1381 : } - 1382 : } - 1383 : - 1384 : /* post process the files */ - 1385 910233 : ret = file_post(state, fix, i, handle, diskmax); - 1386 910233 : if (ret == -1) { - 1387 0 : log_fatal("Stopping at block %u\n", i); - 1388 0 : ++unrecoverable_error; - 1389 0 : goto bail; - 1390 : } - 1391 : - 1392 : /* count the number of processed block */ - 1393 910233 : ++countpos; - 1394 : - 1395 : /* progress */ - 1396 910233 : if (state_progress(state, 0, i, countpos, countmax, countsize)) { - 1397 : /* LCOV_EXCL_START */ - 1398 : break; - 1399 : /* LCOV_EXCL_STOP */ - 1400 : } - 1401 : } - 1402 : - 1403 : /* for each disk, recover empty files, symlinks and empty dirs */ - 1404 826 : for (i = 0; i < diskmax; ++i) { - 1405 : tommy_node* node; - 1406 : struct snapraid_disk* disk; - 1407 : - 1408 708 : if (!handle[i].disk) - 1409 3 : continue; - 1410 : - 1411 : /* for each empty file in the disk */ - 1412 705 : disk = handle[i].disk; - 1413 705 : node = disk->filelist; - 1414 2189135 : while (node) { - 1415 : char path[PATH_MAX]; - 1416 : struct stat st; - 1417 : struct snapraid_file* file; - 1418 2187725 : int unsuccesful = 0; - 1419 : - 1420 2187725 : file = node->data; - 1421 2187725 : node = node->next; /* next node */ - 1422 : - 1423 : /* if not empty, it's already checked and continue to the next one */ - 1424 2187725 : if (file->size != 0) { - 1425 4369715 : continue; - 1426 : } - 1427 : - 1428 : /* if excluded continue to the next one */ - 1429 2952 : if (file_flag_has(file, FILE_IS_EXCLUDED)) { - 1430 169 : continue; - 1431 : } - 1432 : - 1433 : /* stat the file */ - 1434 2783 : pathprint(path, sizeof(path), "%s%s", disk->dir, file->sub); - 1435 2783 : ret = stat(path, &st); - 1436 2783 : if (ret == -1) { - 1437 165 : unsuccesful = 1; - 1438 : - 1439 165 : log_error("Error stating empty file '%s'. %s.\n", path, strerror(errno)); - 1440 165 : log_tag("error:%s:%s: Empty file stat error\n", disk->name, esc_tag(file->sub, esc_buffer)); - 1441 165 : ++error; - 1442 2618 : } else if (!S_ISREG(st.st_mode)) { - 1443 0 : unsuccesful = 1; - 1444 : - 1445 0 : log_tag("error:%s:%s: Empty file error for not regular file\n", disk->name, esc_tag(file->sub, esc_buffer)); - 1446 0 : ++error; - 1447 2618 : } else if (st.st_size != 0) { - 1448 5 : unsuccesful = 1; - 1449 : - 1450 5 : log_tag("error:%s:%s: Empty file error for size '%" PRIu64 "'\n", disk->name, esc_tag(file->sub, esc_buffer), st.st_size); - 1451 5 : ++error; - 1452 : } + 1161 4586482 : assert(block_state == BLOCK_STATE_BLK || block_state == BLOCK_STATE_REP); + 1162 : + 1163 : /* compute the hash of the block just read */ + 1164 4586482 : if (rehash) { + 1165 27243 : memhash(state->prevhash, state->prevhashseed, hash, buffer[j], read_size); + 1166 : } else { + 1167 4559239 : memhash(state->hash, state->hashseed, hash, buffer[j], read_size); + 1168 : } + 1169 : + 1170 : /* compare the hash */ + 1171 4586482 : if (memcmp(hash, block->hash, BLOCK_HASH_SIZE) != 0) { + 1172 12866 : unsigned diff = memdiff(hash, block->hash, BLOCK_HASH_SIZE); + 1173 : + 1174 : /* save the failed block for the check/fix */ + 1175 12866 : failed[failed_count].is_bad = 1; /* it's bad because the hash doesn't match */ + 1176 12866 : failed[failed_count].is_outofdate = 0; + 1177 12866 : failed[failed_count].index = j; + 1178 12866 : failed[failed_count].block = block; + 1179 12866 : failed[failed_count].disk = disk; + 1180 12866 : failed[failed_count].file = file; + 1181 12866 : failed[failed_count].file_pos = file_pos; + 1182 12866 : failed[failed_count].handle = &handle[j]; + 1183 12866 : ++failed_count; + 1184 : + 1185 12866 : log_tag("error:%u:%s:%s: Data error at position %u, diff bits %u\n", i, disk->name, esc_tag(file->sub, esc_buffer), file_pos, diff); + 1186 12866 : ++error; + 1187 12866 : continue; + 1188 : } + 1189 : + 1190 : /* always insert REP blocks, the repair functions needs all of them */ + 1191 : /* because the parity may be still referring at the old state */ + 1192 : /* and the repair must be aware of it */ + 1193 4573616 : if (block_state == BLOCK_STATE_REP) { + 1194 53428 : failed[failed_count].is_bad = 0; /* it's not bad */ + 1195 53428 : failed[failed_count].is_outofdate = 0; + 1196 53428 : failed[failed_count].index = j; + 1197 53428 : failed[failed_count].block = block; + 1198 53428 : failed[failed_count].disk = disk; + 1199 53428 : failed[failed_count].file = file; + 1200 53428 : failed[failed_count].file_pos = file_pos; + 1201 53428 : failed[failed_count].handle = &handle[j]; + 1202 53428 : ++failed_count; + 1203 53428 : continue; + 1204 : } + 1205 : } + 1206 : + 1207 : /* now read and check the parity if requested */ + 1208 910233 : if (!state->opt.auditonly) { + 1209 : void* buffer_recov[LEV_MAX]; + 1210 : void* buffer_zero; + 1211 : + 1212 : /* buffers for parity read and not computed */ + 1213 4170787 : for (l = 0; l < state->level; ++l) + 1214 3299829 : buffer_recov[l] = buffer[diskmax + state->level + l]; + 1215 2796877 : for (; l < LEV_MAX; ++l) + 1216 1925919 : buffer_recov[l] = 0; + 1217 : + 1218 : /* the zero buffer is the last one */ + 1219 870958 : buffer_zero = buffer[buffermax - 1]; + 1220 : + 1221 : /* read the parity */ + 1222 4170787 : for (l = 0; l < state->level; ++l) { + 1223 3299829 : if (parity[l]) { + 1224 3285927 : ret = parity_read(parity[l], i, buffer_recov[l], state->block_size, log_error); + 1225 3285927 : if (ret == -1) { + 1226 11360 : buffer_recov[l] = 0; /* no parity to use */ + 1227 : + 1228 11360 : log_tag("parity_error:%u:%s: Read error\n", i, lev_config_name(l)); + 1229 11360 : ++error; + 1230 : } + 1231 : } else { + 1232 13902 : buffer_recov[l] = 0; + 1233 : } + 1234 : } + 1235 : + 1236 : /* try all the recovering strategies */ + 1237 870958 : ret = repair(state, rehash, i, diskmax, failed, failed_map, failed_count, buffer, buffer_recov, buffer_zero); + 1238 870958 : if (ret != 0) { + 1239 : /* increment the number of errors */ + 1240 47948 : if (ret > 0) + 1241 4808 : error += ret; + 1242 47948 : ++unrecoverable_error; + 1243 : + 1244 : /* print a list of all the errors in files */ + 1245 219168 : for (j = 0; j < failed_count; ++j) { + 1246 171220 : if (failed[j].is_bad) + 1247 166698 : log_tag("unrecoverable:%u:%s:%s: Unrecoverable error at position %u\n", i, failed[j].disk->name, esc_tag(failed[j].file->sub, esc_buffer), failed[j].file_pos); + 1248 : } + 1249 : + 1250 : /* keep track of damaged files */ + 1251 219168 : for (j = 0; j < failed_count; ++j) { + 1252 171220 : if (failed[j].is_bad) + 1253 166698 : file_flag_set(failed[j].file, FILE_IS_DAMAGED); + 1254 : } + 1255 : } else { + 1256 : /* now counts partial recovers */ + 1257 : /* note that this could happen only when we have an incomplete 'sync' */ + 1258 : /* and that we have recovered is the state before the 'sync' */ + 1259 823010 : int partial_recover_error = 0; + 1260 : + 1261 : /* print a list of all the errors in files */ + 1262 1380911 : for (j = 0; j < failed_count; ++j) { + 1263 557901 : if (failed[j].is_bad && failed[j].is_outofdate) { + 1264 8 : ++partial_recover_error; + 1265 8 : log_tag("unrecoverable:%u:%s:%s: Unrecoverable unsynced error at position %u\n", i, failed[j].disk->name, esc_tag(failed[j].file->sub, esc_buffer), failed[j].file_pos); + 1266 : } + 1267 : } + 1268 823010 : if (partial_recover_error != 0) { + 1269 8 : error += partial_recover_error; + 1270 8 : ++unrecoverable_error; + 1271 : } + 1272 : + 1273 : /* now check parities, but only if all the blocks have it computed */ + 1274 : /* if you check/fix after a partial sync, it's OK to have parity errors on the blocks with invalid parity */ + 1275 : /* and doesn't make sense to try to fix it */ + 1276 823010 : if (valid_parity) { + 1277 : /* check the parity */ + 1278 3728920 : for (l = 0; l < state->level; ++l) { + 1279 2967495 : if (buffer_recov[l] != 0 && memcmp(buffer_recov[l], buffer[diskmax + l], state->block_size) != 0) { + 1280 78683 : unsigned diff = memdiff(buffer_recov[l], buffer[diskmax + l], state->block_size); + 1281 : + 1282 : /* mark that the read parity is wrong, setting ptr to 0 */ + 1283 78683 : buffer_recov[l] = 0; + 1284 : + 1285 78683 : log_tag("parity_error:%u:%s: Data error, diff bits %u\n", i, lev_config_name(l), diff); + 1286 78683 : ++error; + 1287 : } + 1288 : } + 1289 : } + 1290 : + 1291 : /* now write recovered files */ + 1292 823010 : if (fix) { + 1293 : /* update the fixed files */ + 1294 652734 : for (j = 0; j < failed_count; ++j) { + 1295 : /* nothing to do if it doesn't need recovering */ + 1296 338081 : if (!failed[j].is_bad) + 1297 40318 : continue; + 1298 : + 1299 : /* do not fix if the file is excluded */ + 1300 297763 : if (file_flag_has(failed[j].file, FILE_IS_EXCLUDED) + 1301 288483 : || (state->opt.syncedonly && file_flag_has(failed[j].file, FILE_IS_UNSYNCED))) + 1302 9280 : continue; + 1303 : + 1304 288483 : ret = handle_write(failed[j].handle, failed[j].file_pos, buffer[failed[j].index], state->block_size); + 1305 288483 : if (ret == -1) { + 1306 : /* LCOV_EXCL_START */ + 1307 : /* mark the file as damaged */ + 1308 : file_flag_set(failed[j].file, FILE_IS_DAMAGED); + 1309 : + 1310 : if (errno == EACCES) { + 1311 : log_fatal("WARNING! Please give write permission to the file.\n"); + 1312 : } else { + 1313 : /* we do not use DANGER because it could be ENOSPC which is not always correctly reported */ + 1314 : log_fatal("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n"); + 1315 : } + 1316 : log_fatal("Stopping at block %u\n", i); + 1317 : ++unrecoverable_error; + 1318 : goto bail; + 1319 : /* LCOV_EXCL_STOP */ + 1320 : } + 1321 : + 1322 : /* if we are not sure that the recovered content is uptodate */ + 1323 288483 : if (failed[j].is_outofdate) { + 1324 : /* mark the file as damaged */ + 1325 8 : file_flag_set(failed[j].file, FILE_IS_DAMAGED); + 1326 8 : continue; + 1327 : } + 1328 : + 1329 : /* mark the file as containing some fixes */ + 1330 : /* note that it could be also marked as damaged in other iterations */ + 1331 288475 : file_flag_set(failed[j].file, FILE_IS_FIXED); + 1332 : + 1333 288475 : log_tag("fixed:%u:%s:%s: Fixed data error at position %u\n", i, failed[j].disk->name, esc_tag(failed[j].file->sub, esc_buffer), failed[j].file_pos); + 1334 288475 : ++recovered_error; + 1335 : } + 1336 : + 1337 : /* update parity only if all the blocks have it computed */ + 1338 : /* if you check/fix after a partial sync, you do not want to fix parity */ + 1339 : /* for blocks that are going to have it computed in the sync completion */ + 1340 314653 : if (valid_parity) { + 1341 : /* update the parity */ + 1342 964031 : for (l = 0; l < state->level; ++l) { + 1343 : /* if the parity on disk is wrong */ + 1344 698558 : if (buffer_recov[l] == 0 + 1345 : /* and we have access at the parity */ + 1346 72150 : && parity[l] != 0 + 1347 : /* and the parity is not excluded */ + 1348 67463 : && !state->parity[l].is_excluded + 1349 : ) { + 1350 67463 : ret = parity_write(parity[l], i, buffer[diskmax + l], state->block_size); + 1351 67463 : if (ret == -1) { + 1352 : /* LCOV_EXCL_START */ + 1353 : /* we do not use DANGER because it could be ENOSPC which is not always correctly reported */ + 1354 : log_fatal("WARNING! Without a working %s disk, it isn't possible to fix errors on it.\n", lev_name(l)); + 1355 : log_fatal("Stopping at block %u\n", i); + 1356 : ++unrecoverable_error; + 1357 : goto bail; + 1358 : /* LCOV_EXCL_STOP */ + 1359 : } + 1360 : + 1361 67463 : log_tag("parity_fixed:%u:%s: Fixed data error\n", i, lev_config_name(l)); + 1362 67463 : ++recovered_error; + 1363 : } + 1364 : } + 1365 : } + 1366 : } else { + 1367 : /* if we are not fixing, we just set the FIXED flag */ + 1368 : /* meaning that we could fix this file if we try */ + 1369 728177 : for (j = 0; j < failed_count; ++j) { + 1370 219820 : if (failed[j].is_bad) { + 1371 178935 : file_flag_set(failed[j].file, FILE_IS_FIXED); + 1372 : } + 1373 : } + 1374 : } + 1375 : } + 1376 : } else { + 1377 : /* if we are not checking, we just set the DAMAGED flag */ + 1378 : /* to report that the file is damaged, and we don't know if we can fix it */ + 1379 45240 : for (j = 0; j < failed_count; ++j) { + 1380 5965 : if (failed[j].is_bad) { + 1381 5965 : file_flag_set(failed[j].file, FILE_IS_DAMAGED); + 1382 : } + 1383 : } + 1384 : } + 1385 : + 1386 : /* post process the files */ + 1387 910233 : ret = file_post(state, fix, i, handle, diskmax); + 1388 910233 : if (ret == -1) { + 1389 : /* LCOV_EXCL_START */ + 1390 : log_fatal("Stopping at block %u\n", i); + 1391 : ++unrecoverable_error; + 1392 : goto bail; + 1393 : /* LCOV_EXCL_STOP */ + 1394 : } + 1395 : + 1396 : /* count the number of processed block */ + 1397 910233 : ++countpos; + 1398 : + 1399 : /* progress */ + 1400 910233 : if (state_progress(state, 0, i, countpos, countmax, countsize)) { + 1401 : /* LCOV_EXCL_START */ + 1402 : break; + 1403 : /* LCOV_EXCL_STOP */ + 1404 : } + 1405 : } + 1406 : + 1407 : /* for each disk, recover empty files, symlinks and empty dirs */ + 1408 826 : for (i = 0; i < diskmax; ++i) { + 1409 : tommy_node* node; + 1410 : struct snapraid_disk* disk; + 1411 : + 1412 708 : if (!handle[i].disk) + 1413 3 : continue; + 1414 : + 1415 : /* for each empty file in the disk */ + 1416 705 : disk = handle[i].disk; + 1417 705 : node = disk->filelist; + 1418 2189135 : while (node) { + 1419 : char path[PATH_MAX]; + 1420 : struct stat st; + 1421 : struct snapraid_file* file; + 1422 2187725 : int unsuccesful = 0; + 1423 : + 1424 2187725 : file = node->data; + 1425 2187725 : node = node->next; /* next node */ + 1426 : + 1427 : /* if not empty, it's already checked and continue to the next one */ + 1428 2187725 : if (file->size != 0) { + 1429 4369715 : continue; + 1430 : } + 1431 : + 1432 : /* if excluded continue to the next one */ + 1433 2952 : if (file_flag_has(file, FILE_IS_EXCLUDED)) { + 1434 169 : continue; + 1435 : } + 1436 : + 1437 : /* stat the file */ + 1438 2783 : pathprint(path, sizeof(path), "%s%s", disk->dir, file->sub); + 1439 2783 : ret = stat(path, &st); + 1440 2783 : if (ret == -1) { + 1441 167 : unsuccesful = 1; + 1442 : + 1443 167 : log_error("Error stating empty file '%s'. %s.\n", path, strerror(errno)); + 1444 167 : log_tag("error:%s:%s: Empty file stat error\n", disk->name, esc_tag(file->sub, esc_buffer)); + 1445 167 : ++error; + 1446 2616 : } else if (!S_ISREG(st.st_mode)) { + 1447 0 : unsuccesful = 1; + 1448 : + 1449 0 : log_tag("error:%s:%s: Empty file error for not regular file\n", disk->name, esc_tag(file->sub, esc_buffer)); + 1450 0 : ++error; + 1451 2616 : } else if (st.st_size != 0) { + 1452 3 : unsuccesful = 1; 1453 : - 1454 2783 : if (fix && unsuccesful) { - 1455 : int f; - 1456 : - 1457 : /* create the ancestor directories */ - 1458 154 : ret = mkancestor(path); - 1459 154 : if (ret != 0) { - 1460 : /* LCOV_EXCL_START */ - 1461 : log_fatal("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n"); - 1462 : log_fatal("Stopping\n"); - 1463 : ++unrecoverable_error; - 1464 : goto bail; - 1465 : /* LCOV_EXCL_STOP */ - 1466 : } - 1467 : - 1468 : /* create it */ - 1469 : /* O_NOFOLLOW: do not follow links to ensure to open the real file */ - 1470 154 : f = open(path, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_NOFOLLOW, 0600); - 1471 154 : if (f == -1) { - 1472 : /* LCOV_EXCL_START */ - 1473 : log_fatal("Error creating empty file '%s'. %s.\n", path, strerror(errno)); - 1474 : if (errno == EACCES) { - 1475 : log_fatal("WARNING! Please give write permission to the file.\n"); - 1476 : } else { - 1477 : /* we do not use DANGER because it could be ENOSPC which is not always correctly reported */ - 1478 : log_fatal("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n"); - 1479 : } - 1480 : log_fatal("Stopping\n"); - 1481 : ++unrecoverable_error; - 1482 : goto bail; - 1483 : /* LCOV_EXCL_STOP */ - 1484 : } - 1485 : - 1486 : /* set the original modification time */ - 1487 154 : ret = fmtime(f, file->mtime_sec, file->mtime_nsec); - 1488 154 : if (ret != 0) { - 1489 : /* LCOV_EXCL_START */ - 1490 : close(f); - 1491 : - 1492 : log_fatal("Error timing file '%s'. %s.\n", file->sub, strerror(errno)); - 1493 : log_fatal("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n"); - 1494 : log_fatal("Stopping\n"); - 1495 : ++unrecoverable_error; - 1496 : goto bail; - 1497 : /* LCOV_EXCL_STOP */ - 1498 : } - 1499 : - 1500 : /* close it */ - 1501 154 : ret = close(f); - 1502 154 : if (ret != 0) { - 1503 : /* LCOV_EXCL_START */ - 1504 : log_fatal("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n"); - 1505 : log_fatal("Stopping\n"); - 1506 : ++unrecoverable_error; - 1507 : goto bail; - 1508 : /* LCOV_EXCL_STOP */ - 1509 : } - 1510 : - 1511 154 : log_tag("fixed:%s:%s: Fixed empty file\n", disk->name, esc_tag(file->sub, esc_buffer)); - 1512 154 : ++recovered_error; - 1513 : - 1514 154 : log_tag("status:recovered:%s:%s\n", disk->name, esc_tag(file->sub, esc_buffer)); - 1515 154 : msg_info("recovered %s\n", fmt_term(disk, file->sub, esc_buffer)); - 1516 : } - 1517 : } - 1518 : - 1519 : /* for each link in the disk */ - 1520 705 : disk = handle[i].disk; - 1521 705 : node = disk->linklist; - 1522 71537 : while (node) { - 1523 : char path[PATH_MAX]; - 1524 : char pathto[PATH_MAX]; - 1525 : char linkto[PATH_MAX]; - 1526 : struct stat st; - 1527 : struct stat stto; - 1528 : struct snapraid_link* slink; - 1529 70127 : int unsuccesful = 0; - 1530 70127 : int unrecoverable = 0; - 1531 : - 1532 70127 : slink = node->data; - 1533 70127 : node = node->next; /* next node */ - 1534 : - 1535 : /* if excluded continue to the next one */ - 1536 70127 : if (link_flag_has(slink, FILE_IS_EXCLUDED)) { - 1537 3277 : continue; - 1538 : } - 1539 : - 1540 66850 : if (link_flag_has(slink, FILE_IS_HARDLINK)) { - 1541 : /* stat the link */ - 1542 318 : pathprint(path, sizeof(path), "%s%s", disk->dir, slink->sub); - 1543 318 : ret = stat(path, &st); - 1544 318 : if (ret == -1) { - 1545 36 : unsuccesful = 1; - 1546 : - 1547 36 : log_error("Error stating hardlink '%s'. %s.\n", path, strerror(errno)); - 1548 36 : log_tag("hardlink_error:%s:%s:%s: Hardlink stat error\n", disk->name, esc_tag(slink->sub, esc_buffer), esc_tag(slink->linkto, esc_buffer_alt)); - 1549 36 : ++error; - 1550 282 : } else if (!S_ISREG(st.st_mode)) { - 1551 0 : unsuccesful = 1; - 1552 : - 1553 0 : log_tag("hardlink_error:%s:%s:%s: Hardlink error for not regular file\n", disk->name, esc_tag(slink->sub, esc_buffer), esc_tag(slink->linkto, esc_buffer_alt)); - 1554 0 : ++error; - 1555 : } + 1454 3 : log_tag("error:%s:%s: Empty file error for size '%" PRIu64 "'\n", disk->name, esc_tag(file->sub, esc_buffer), st.st_size); + 1455 3 : ++error; + 1456 : } + 1457 : + 1458 2783 : if (fix && unsuccesful) { + 1459 : int f; + 1460 : + 1461 : /* create the ancestor directories */ + 1462 154 : ret = mkancestor(path); + 1463 154 : if (ret != 0) { + 1464 : /* LCOV_EXCL_START */ + 1465 : log_fatal("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n"); + 1466 : log_fatal("Stopping\n"); + 1467 : ++unrecoverable_error; + 1468 : goto bail; + 1469 : /* LCOV_EXCL_STOP */ + 1470 : } + 1471 : + 1472 : /* create it */ + 1473 : /* O_NOFOLLOW: do not follow links to ensure to open the real file */ + 1474 154 : f = open(path, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_NOFOLLOW, 0600); + 1475 154 : if (f == -1) { + 1476 : /* LCOV_EXCL_START */ + 1477 : log_fatal("Error creating empty file '%s'. %s.\n", path, strerror(errno)); + 1478 : if (errno == EACCES) { + 1479 : log_fatal("WARNING! Please give write permission to the file.\n"); + 1480 : } else { + 1481 : /* we do not use DANGER because it could be ENOSPC which is not always correctly reported */ + 1482 : log_fatal("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n"); + 1483 : } + 1484 : log_fatal("Stopping\n"); + 1485 : ++unrecoverable_error; + 1486 : goto bail; + 1487 : /* LCOV_EXCL_STOP */ + 1488 : } + 1489 : + 1490 : /* set the original modification time */ + 1491 154 : ret = fmtime(f, file->mtime_sec, file->mtime_nsec); + 1492 154 : if (ret != 0) { + 1493 : /* LCOV_EXCL_START */ + 1494 : close(f); + 1495 : + 1496 : log_fatal("Error timing file '%s'. %s.\n", file->sub, strerror(errno)); + 1497 : log_fatal("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n"); + 1498 : log_fatal("Stopping\n"); + 1499 : ++unrecoverable_error; + 1500 : goto bail; + 1501 : /* LCOV_EXCL_STOP */ + 1502 : } + 1503 : + 1504 : /* close it */ + 1505 154 : ret = close(f); + 1506 154 : if (ret != 0) { + 1507 : /* LCOV_EXCL_START */ + 1508 : log_fatal("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n"); + 1509 : log_fatal("Stopping\n"); + 1510 : ++unrecoverable_error; + 1511 : goto bail; + 1512 : /* LCOV_EXCL_STOP */ + 1513 : } + 1514 : + 1515 154 : log_tag("fixed:%s:%s: Fixed empty file\n", disk->name, esc_tag(file->sub, esc_buffer)); + 1516 154 : ++recovered_error; + 1517 : + 1518 154 : log_tag("status:recovered:%s:%s\n", disk->name, esc_tag(file->sub, esc_buffer)); + 1519 154 : msg_info("recovered %s\n", fmt_term(disk, file->sub, esc_buffer)); + 1520 : } + 1521 : } + 1522 : + 1523 : /* for each link in the disk */ + 1524 705 : disk = handle[i].disk; + 1525 705 : node = disk->linklist; + 1526 71537 : while (node) { + 1527 : char path[PATH_MAX]; + 1528 : char pathto[PATH_MAX]; + 1529 : char linkto[PATH_MAX]; + 1530 : struct stat st; + 1531 : struct stat stto; + 1532 : struct snapraid_link* slink; + 1533 70127 : int unsuccesful = 0; + 1534 70127 : int unrecoverable = 0; + 1535 : + 1536 70127 : slink = node->data; + 1537 70127 : node = node->next; /* next node */ + 1538 : + 1539 : /* if excluded continue to the next one */ + 1540 70127 : if (link_flag_has(slink, FILE_IS_EXCLUDED)) { + 1541 3277 : continue; + 1542 : } + 1543 : + 1544 66850 : if (link_flag_has(slink, FILE_IS_HARDLINK)) { + 1545 : /* stat the link */ + 1546 318 : pathprint(path, sizeof(path), "%s%s", disk->dir, slink->sub); + 1547 318 : ret = stat(path, &st); + 1548 318 : if (ret == -1) { + 1549 36 : unsuccesful = 1; + 1550 : + 1551 36 : log_error("Error stating hardlink '%s'. %s.\n", path, strerror(errno)); + 1552 36 : log_tag("hardlink_error:%s:%s:%s: Hardlink stat error\n", disk->name, esc_tag(slink->sub, esc_buffer), esc_tag(slink->linkto, esc_buffer_alt)); + 1553 36 : ++error; + 1554 282 : } else if (!S_ISREG(st.st_mode)) { + 1555 0 : unsuccesful = 1; 1556 : - 1557 : /* stat the "to" file */ - 1558 318 : pathprint(pathto, sizeof(pathto), "%s%s", disk->dir, slink->linkto); - 1559 318 : ret = stat(pathto, &stto); - 1560 318 : if (ret == -1) { - 1561 24 : unsuccesful = 1; - 1562 : - 1563 24 : if (errno == ENOENT) { - 1564 24 : unrecoverable = 1; - 1565 24 : if (fix) { - 1566 : /* if the target doesn't exist, it's unrecoverable */ - 1567 : /* because we cannot create an hardlink of a file that */ - 1568 : /* doesn't exists */ - 1569 12 : ++unrecoverable_error; - 1570 : } else { - 1571 : /* but in check, we can assume that fixing will recover */ - 1572 : /* such missing file, so we assume a less drastic error */ - 1573 12 : ++error; - 1574 : } - 1575 : } - 1576 : - 1577 24 : log_error("Error stating hardlink-to '%s'. %s.\n", pathto, strerror(errno)); - 1578 24 : log_tag("hardlink_error:%s:%s:%s: Hardlink to stat error\n", disk->name, esc_tag(slink->sub, esc_buffer), esc_tag(slink->linkto, esc_buffer_alt)); - 1579 24 : ++error; - 1580 294 : } else if (!S_ISREG(stto.st_mode)) { - 1581 0 : unsuccesful = 1; - 1582 : - 1583 0 : log_tag("hardlink_error:%s:%s:%s: Hardlink-to error for not regular file\n", disk->name, esc_tag(slink->sub, esc_buffer), esc_tag(slink->linkto, esc_buffer_alt)); - 1584 0 : ++error; - 1585 294 : } else if (!unsuccesful && st.st_ino != stto.st_ino) { - 1586 0 : unsuccesful = 1; - 1587 : - 1588 0 : log_error("Mismatch hardlink '%s' and '%s'. Different inode.\n", path, pathto); - 1589 0 : log_tag("hardlink_error:%s:%s:%s: Hardlink mismatch for different inode\n", disk->name, esc_tag(slink->sub, esc_buffer), esc_tag(slink->linkto, esc_buffer_alt)); - 1590 0 : ++error; - 1591 : } - 1592 : } else { - 1593 : /* read the symlink */ - 1594 66532 : pathprint(path, sizeof(path), "%s%s", disk->dir, slink->sub); - 1595 66532 : ret = readlink(path, linkto, sizeof(linkto)); - 1596 66532 : if (ret < 0) { - 1597 4292 : unsuccesful = 1; - 1598 : - 1599 4292 : log_error("Error reading symlink '%s'. %s.\n", path, strerror(errno)); - 1600 4292 : log_tag("symlink_error:%s:%s: Symlink read error\n", disk->name, esc_tag(slink->sub, esc_buffer)); - 1601 4292 : ++error; - 1602 62240 : } else if (ret >= PATH_MAX) { - 1603 0 : unsuccesful = 1; - 1604 : - 1605 0 : log_error("Error reading symlink '%s'. Symlink too long.\n", path); - 1606 0 : log_tag("symlink_error:%s:%s: Symlink read error\n", disk->name, esc_tag(slink->sub, esc_buffer)); - 1607 0 : ++error; - 1608 : } else { - 1609 62240 : linkto[ret] = 0; - 1610 : - 1611 62240 : if (strcmp(linkto, slink->linkto) != 0) { - 1612 544 : unsuccesful = 1; - 1613 : - 1614 544 : log_tag("symlink_error:%s:%s: Symlink data error '%s' instead of '%s'\n", disk->name, esc_tag(slink->sub, esc_buffer), linkto, slink->linkto); - 1615 544 : ++error; - 1616 : } - 1617 : } - 1618 : } - 1619 : - 1620 66850 : if (fix && unsuccesful && !unrecoverable) { - 1621 : /* create the ancestor directories */ - 1622 3942 : ret = mkancestor(path); - 1623 3942 : if (ret != 0) { - 1624 : /* LCOV_EXCL_START */ - 1625 : log_fatal("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n"); - 1626 : log_fatal("Stopping\n"); - 1627 : ++unrecoverable_error; - 1628 : goto bail; - 1629 : /* LCOV_EXCL_STOP */ - 1630 : } - 1631 : - 1632 : /* if it exists, it must be deleted before recreating */ - 1633 3942 : ret = remove(path); - 1634 3942 : if (ret != 0 && errno != ENOENT) { - 1635 : /* LCOV_EXCL_START */ - 1636 : log_fatal("Error removing '%s'. %s.\n", path, strerror(errno)); - 1637 : log_fatal("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n"); - 1638 : log_fatal("Stopping\n"); - 1639 : ++unrecoverable_error; - 1640 : goto bail; - 1641 : /* LCOV_EXCL_STOP */ - 1642 : } - 1643 : - 1644 : /* create it */ - 1645 3942 : if (link_flag_has(slink, FILE_IS_HARDLINK)) { - 1646 12 : ret = hardlink(pathto, path); - 1647 12 : if (ret != 0) { - 1648 : /* LCOV_EXCL_START */ - 1649 : log_fatal("Error writing hardlink '%s' to '%s'. %s.\n", path, pathto, strerror(errno)); - 1650 : if (errno == EACCES) { - 1651 : log_fatal("WARNING! Please give write permission to the hardlink.\n"); - 1652 : } else { - 1653 : /* we do not use DANGER because it could be ENOSPC which is not always correctly reported */ - 1654 : log_fatal("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n"); - 1655 : } - 1656 : log_fatal("Stopping\n"); - 1657 : ++unrecoverable_error; - 1658 : goto bail; - 1659 : /* LCOV_EXCL_STOP */ - 1660 : } - 1661 : - 1662 12 : log_tag("hardlink_fixed:%s:%s: Fixed hardlink error\n", disk->name, esc_tag(slink->sub, esc_buffer)); - 1663 12 : ++recovered_error; - 1664 : } else { - 1665 3930 : ret = symlink(slink->linkto, path); - 1666 3930 : if (ret != 0) { - 1667 : /* LCOV_EXCL_START */ - 1668 : log_fatal("Error writing symlink '%s' to '%s'. %s.\n", path, slink->linkto, strerror(errno)); - 1669 : if (errno == EACCES) { - 1670 : log_fatal("WARNING! Please give write permission to the symlink.\n"); - 1671 : } else { - 1672 : /* we do not use DANGER because it could be ENOSPC which is not always correctly reported */ - 1673 : log_fatal("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n"); - 1674 : } - 1675 : log_fatal("Stopping\n"); - 1676 : ++unrecoverable_error; - 1677 : goto bail; - 1678 : /* LCOV_EXCL_STOP */ - 1679 : } - 1680 : - 1681 3930 : log_tag("symlink_fixed:%s:%s: Fixed symlink error\n", disk->name, esc_tag(slink->sub, esc_buffer)); - 1682 3930 : ++recovered_error; - 1683 : } + 1557 0 : log_tag("hardlink_error:%s:%s:%s: Hardlink error for not regular file\n", disk->name, esc_tag(slink->sub, esc_buffer), esc_tag(slink->linkto, esc_buffer_alt)); + 1558 0 : ++error; + 1559 : } + 1560 : + 1561 : /* stat the "to" file */ + 1562 318 : pathprint(pathto, sizeof(pathto), "%s%s", disk->dir, slink->linkto); + 1563 318 : ret = stat(pathto, &stto); + 1564 318 : if (ret == -1) { + 1565 24 : unsuccesful = 1; + 1566 : + 1567 24 : if (errno == ENOENT) { + 1568 24 : unrecoverable = 1; + 1569 24 : if (fix) { + 1570 : /* if the target doesn't exist, it's unrecoverable */ + 1571 : /* because we cannot create an hardlink of a file that */ + 1572 : /* doesn't exists */ + 1573 12 : ++unrecoverable_error; + 1574 : } else { + 1575 : /* but in check, we can assume that fixing will recover */ + 1576 : /* such missing file, so we assume a less drastic error */ + 1577 12 : ++error; + 1578 : } + 1579 : } + 1580 : + 1581 24 : log_error("Error stating hardlink-to '%s'. %s.\n", pathto, strerror(errno)); + 1582 24 : log_tag("hardlink_error:%s:%s:%s: Hardlink to stat error\n", disk->name, esc_tag(slink->sub, esc_buffer), esc_tag(slink->linkto, esc_buffer_alt)); + 1583 24 : ++error; + 1584 294 : } else if (!S_ISREG(stto.st_mode)) { + 1585 0 : unsuccesful = 1; + 1586 : + 1587 0 : log_tag("hardlink_error:%s:%s:%s: Hardlink-to error for not regular file\n", disk->name, esc_tag(slink->sub, esc_buffer), esc_tag(slink->linkto, esc_buffer_alt)); + 1588 0 : ++error; + 1589 294 : } else if (!unsuccesful && st.st_ino != stto.st_ino) { + 1590 0 : unsuccesful = 1; + 1591 : + 1592 0 : log_error("Mismatch hardlink '%s' and '%s'. Different inode.\n", path, pathto); + 1593 0 : log_tag("hardlink_error:%s:%s:%s: Hardlink mismatch for different inode\n", disk->name, esc_tag(slink->sub, esc_buffer), esc_tag(slink->linkto, esc_buffer_alt)); + 1594 0 : ++error; + 1595 : } + 1596 : } else { + 1597 : /* read the symlink */ + 1598 66532 : pathprint(path, sizeof(path), "%s%s", disk->dir, slink->sub); + 1599 66532 : ret = readlink(path, linkto, sizeof(linkto)); + 1600 66532 : if (ret < 0) { + 1601 4267 : unsuccesful = 1; + 1602 : + 1603 4267 : log_error("Error reading symlink '%s'. %s.\n", path, strerror(errno)); + 1604 4267 : log_tag("symlink_error:%s:%s: Symlink read error\n", disk->name, esc_tag(slink->sub, esc_buffer)); + 1605 4267 : ++error; + 1606 62265 : } else if (ret >= PATH_MAX) { + 1607 0 : unsuccesful = 1; + 1608 : + 1609 0 : log_error("Error reading symlink '%s'. Symlink too long.\n", path); + 1610 0 : log_tag("symlink_error:%s:%s: Symlink read error\n", disk->name, esc_tag(slink->sub, esc_buffer)); + 1611 0 : ++error; + 1612 : } else { + 1613 62265 : linkto[ret] = 0; + 1614 : + 1615 62265 : if (strcmp(linkto, slink->linkto) != 0) { + 1616 566 : unsuccesful = 1; + 1617 : + 1618 566 : log_tag("symlink_error:%s:%s: Symlink data error '%s' instead of '%s'\n", disk->name, esc_tag(slink->sub, esc_buffer), linkto, slink->linkto); + 1619 566 : ++error; + 1620 : } + 1621 : } + 1622 : } + 1623 : + 1624 66850 : if (fix && unsuccesful && !unrecoverable) { + 1625 : /* create the ancestor directories */ + 1626 3941 : ret = mkancestor(path); + 1627 3941 : if (ret != 0) { + 1628 : /* LCOV_EXCL_START */ + 1629 : log_fatal("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n"); + 1630 : log_fatal("Stopping\n"); + 1631 : ++unrecoverable_error; + 1632 : goto bail; + 1633 : /* LCOV_EXCL_STOP */ + 1634 : } + 1635 : + 1636 : /* if it exists, it must be deleted before recreating */ + 1637 3941 : ret = remove(path); + 1638 3941 : if (ret != 0 && errno != ENOENT) { + 1639 : /* LCOV_EXCL_START */ + 1640 : log_fatal("Error removing '%s'. %s.\n", path, strerror(errno)); + 1641 : log_fatal("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n"); + 1642 : log_fatal("Stopping\n"); + 1643 : ++unrecoverable_error; + 1644 : goto bail; + 1645 : /* LCOV_EXCL_STOP */ + 1646 : } + 1647 : + 1648 : /* create it */ + 1649 3941 : if (link_flag_has(slink, FILE_IS_HARDLINK)) { + 1650 12 : ret = hardlink(pathto, path); + 1651 12 : if (ret != 0) { + 1652 : /* LCOV_EXCL_START */ + 1653 : log_fatal("Error writing hardlink '%s' to '%s'. %s.\n", path, pathto, strerror(errno)); + 1654 : if (errno == EACCES) { + 1655 : log_fatal("WARNING! Please give write permission to the hardlink.\n"); + 1656 : } else { + 1657 : /* we do not use DANGER because it could be ENOSPC which is not always correctly reported */ + 1658 : log_fatal("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n"); + 1659 : } + 1660 : log_fatal("Stopping\n"); + 1661 : ++unrecoverable_error; + 1662 : goto bail; + 1663 : /* LCOV_EXCL_STOP */ + 1664 : } + 1665 : + 1666 12 : log_tag("hardlink_fixed:%s:%s: Fixed hardlink error\n", disk->name, esc_tag(slink->sub, esc_buffer)); + 1667 12 : ++recovered_error; + 1668 : } else { + 1669 3929 : ret = symlink(slink->linkto, path); + 1670 3929 : if (ret != 0) { + 1671 : /* LCOV_EXCL_START */ + 1672 : log_fatal("Error writing symlink '%s' to '%s'. %s.\n", path, slink->linkto, strerror(errno)); + 1673 : if (errno == EACCES) { + 1674 : log_fatal("WARNING! Please give write permission to the symlink.\n"); + 1675 : } else { + 1676 : /* we do not use DANGER because it could be ENOSPC which is not always correctly reported */ + 1677 : log_fatal("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n"); + 1678 : } + 1679 : log_fatal("Stopping\n"); + 1680 : ++unrecoverable_error; + 1681 : goto bail; + 1682 : /* LCOV_EXCL_STOP */ + 1683 : } 1684 : - 1685 3942 : log_tag("status:recovered:%s:%s\n", disk->name, esc_tag(slink->sub, esc_buffer)); - 1686 3942 : msg_info("recovered %s\n", fmt_term(disk, slink->sub, esc_buffer)); - 1687 : } - 1688 : } - 1689 : - 1690 : /* for each dir in the disk */ - 1691 705 : disk = handle[i].disk; - 1692 705 : node = disk->dirlist; - 1693 1850 : while (node) { - 1694 : char path[PATH_MAX]; - 1695 : struct stat st; - 1696 : struct snapraid_dir* dir; - 1697 440 : int unsuccesful = 0; - 1698 : - 1699 440 : dir = node->data; - 1700 440 : node = node->next; /* next node */ - 1701 : - 1702 : /* if excluded continue to the next one */ - 1703 440 : if (dir_flag_has(dir, FILE_IS_EXCLUDED)) { - 1704 19 : continue; - 1705 : } - 1706 : - 1707 : /* stat the dir */ - 1708 421 : pathprint(path, sizeof(path), "%s%s", disk->dir, dir->sub); - 1709 421 : ret = stat(path, &st); - 1710 421 : if (ret == -1) { - 1711 23 : unsuccesful = 1; - 1712 : - 1713 23 : log_error("Error stating dir '%s'. %s.\n", path, strerror(errno)); - 1714 23 : log_tag("dir_error:%s:%s: Dir stat error\n", disk->name, esc_tag(dir->sub, esc_buffer)); - 1715 23 : ++error; - 1716 398 : } else if (!S_ISDIR(st.st_mode)) { - 1717 0 : unsuccesful = 1; - 1718 : - 1719 0 : log_tag("dir_error:%s:%s: Dir error for not directory\n", disk->name, esc_tag(dir->sub, esc_buffer)); - 1720 0 : ++error; - 1721 : } + 1685 3929 : log_tag("symlink_fixed:%s:%s: Fixed symlink error\n", disk->name, esc_tag(slink->sub, esc_buffer)); + 1686 3929 : ++recovered_error; + 1687 : } + 1688 : + 1689 3941 : log_tag("status:recovered:%s:%s\n", disk->name, esc_tag(slink->sub, esc_buffer)); + 1690 3941 : msg_info("recovered %s\n", fmt_term(disk, slink->sub, esc_buffer)); + 1691 : } + 1692 : } + 1693 : + 1694 : /* for each dir in the disk */ + 1695 705 : disk = handle[i].disk; + 1696 705 : node = disk->dirlist; + 1697 1850 : while (node) { + 1698 : char path[PATH_MAX]; + 1699 : struct stat st; + 1700 : struct snapraid_dir* dir; + 1701 440 : int unsuccesful = 0; + 1702 : + 1703 440 : dir = node->data; + 1704 440 : node = node->next; /* next node */ + 1705 : + 1706 : /* if excluded continue to the next one */ + 1707 440 : if (dir_flag_has(dir, FILE_IS_EXCLUDED)) { + 1708 19 : continue; + 1709 : } + 1710 : + 1711 : /* stat the dir */ + 1712 421 : pathprint(path, sizeof(path), "%s%s", disk->dir, dir->sub); + 1713 421 : ret = stat(path, &st); + 1714 421 : if (ret == -1) { + 1715 23 : unsuccesful = 1; + 1716 : + 1717 23 : log_error("Error stating dir '%s'. %s.\n", path, strerror(errno)); + 1718 23 : log_tag("dir_error:%s:%s: Dir stat error\n", disk->name, esc_tag(dir->sub, esc_buffer)); + 1719 23 : ++error; + 1720 398 : } else if (!S_ISDIR(st.st_mode)) { + 1721 0 : unsuccesful = 1; 1722 : - 1723 421 : if (fix && unsuccesful) { - 1724 : /* create the ancestor directories */ - 1725 21 : ret = mkancestor(path); - 1726 21 : if (ret != 0) { - 1727 : /* LCOV_EXCL_START */ - 1728 : log_fatal("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n"); - 1729 : log_fatal("Stopping\n"); - 1730 : ++unrecoverable_error; - 1731 : goto bail; - 1732 : /* LCOV_EXCL_STOP */ - 1733 : } - 1734 : - 1735 : /* create it */ - 1736 21 : ret = mkdir(path, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); - 1737 21 : if (ret != 0) { - 1738 : /* LCOV_EXCL_START */ - 1739 : log_fatal("Error creating dir '%s'. %s.\n", path, strerror(errno)); - 1740 : if (errno == EACCES) { - 1741 : log_fatal("WARNING! Please give write permission to the dir.\n"); - 1742 : } else { - 1743 : /* we do not use DANGER because it could be ENOSPC which is not always correctly reported */ - 1744 : log_fatal("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n"); - 1745 : } - 1746 : log_fatal("Stopping\n"); - 1747 : ++unrecoverable_error; - 1748 : goto bail; - 1749 : /* LCOV_EXCL_STOP */ - 1750 : } - 1751 : - 1752 21 : log_tag("dir_fixed:%s:%s: Fixed dir error\n", disk->name, esc_tag(dir->sub, esc_buffer)); - 1753 21 : ++recovered_error; - 1754 : - 1755 21 : log_tag("status:recovered:%s:%s\n", disk->name, esc_tag(dir->sub, esc_buffer)); - 1756 21 : msg_info("recovered %s\n", fmt_term(disk, dir->sub, esc_buffer)); - 1757 : } - 1758 : } - 1759 : } - 1760 : - 1761 118 : state_progress_end(state, countpos, countmax, countsize); - 1762 : - 1763 : bail: - 1764 : /* close all the files left open */ - 1765 826 : for (j = 0; j < diskmax; ++j) { - 1766 708 : struct snapraid_file* file = handle[j].file; - 1767 708 : struct snapraid_disk* disk = handle[j].disk; - 1768 708 : ret = handle_close(&handle[j]); - 1769 708 : if (ret == -1) { - 1770 : /* LCOV_EXCL_START */ - 1771 : log_tag("error:%u:%s:%s: Close error. %s\n", blockmax, disk->name, esc_tag(file->sub, esc_buffer), strerror(errno)); - 1772 : log_fatal("DANGER! Unexpected close error in a data disk.\n"); - 1773 : ++unrecoverable_error; - 1774 : /* continue, as we are already exiting */ - 1775 : /* LCOV_EXCL_STOP */ - 1776 : } - 1777 : } - 1778 : - 1779 : /* remove all the files created from scratch that have not finished the processing */ - 1780 : /* it happens only when aborting pressing Ctrl+C or other reason. */ - 1781 118 : if (fix) { - 1782 : /* for each disk */ - 1783 315 : for (i = 0; i < diskmax; ++i) { - 1784 : tommy_node* node; - 1785 : struct snapraid_disk* disk; - 1786 : - 1787 270 : if (!handle[i].disk) - 1788 1 : continue; - 1789 : - 1790 : /* for each file in the disk */ - 1791 269 : disk = handle[i].disk; - 1792 269 : node = disk->filelist; - 1793 870849 : while (node) { - 1794 : char path[PATH_MAX]; - 1795 : struct snapraid_file* file; - 1796 : - 1797 870311 : file = node->data; - 1798 870311 : node = node->next; /* next node */ - 1799 : - 1800 : /* if the file was not created, meaning that it was already existing */ - 1801 870311 : if (!file_flag_has(file, FILE_IS_CREATED)) { - 1802 : /* nothing to do */ - 1803 1627487 : continue; - 1804 : } - 1805 : - 1806 : /* if processing was finished */ - 1807 113135 : if (file_flag_has(file, FILE_IS_FINISHED)) { - 1808 : /* nothing to do */ - 1809 113135 : continue; - 1810 : } - 1811 : - 1812 : /* if the file was originally missing, and processing not yet finished */ - 1813 : /* we have to throw it away to ensure that at the next run we will retry */ - 1814 : /* to fix it, in case we select to undelete missing files */ - 1815 0 : pathprint(path, sizeof(path), "%s%s", disk->dir, file->sub); - 1816 : - 1817 0 : ret = remove(path); - 1818 0 : if (ret != 0) { - 1819 : /* LCOV_EXCL_START */ - 1820 : log_fatal("Error removing '%s'. %s.\n", path, strerror(errno)); - 1821 : log_fatal("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n"); - 1822 : ++unrecoverable_error; - 1823 : /* continue, as we are already exiting */ - 1824 : /* LCOV_EXCL_STOP */ - 1825 : } - 1826 : } - 1827 : } - 1828 : } - 1829 : - 1830 118 : if (error || recovered_error || unrecoverable_error) { - 1831 67 : msg_status("\n"); - 1832 67 : msg_status("%8u errors\n", error); - 1833 67 : if (fix) { - 1834 43 : msg_status("%8u recovered errors\n", recovered_error); - 1835 : } - 1836 134 : if (unrecoverable_error) { - 1837 13 : msg_status("%8u UNRECOVERABLE errors\n", unrecoverable_error); - 1838 : } else { - 1839 : /* without checking, we don't know if they are really recoverable or not */ - 1840 54 : if (!state->opt.auditonly) - 1841 52 : msg_status("%8u unrecoverable errors\n", unrecoverable_error); - 1842 54 : if (fix) - 1843 34 : msg_status("Everything OK\n"); - 1844 : } - 1845 : } else { - 1846 51 : msg_status("Everything OK\n"); - 1847 : } - 1848 : - 1849 118 : if (error && !fix) - 1850 24 : log_fatal("WARNING! There are errors!\n"); - 1851 118 : if (unrecoverable_error) - 1852 13 : log_fatal("DANGER! There are unrecoverable errors!\n"); - 1853 : - 1854 118 : log_tag("summary:error:%u\n", error); - 1855 118 : if (fix) - 1856 45 : log_tag("summary:error_recovered:%u\n", recovered_error); - 1857 118 : if (!state->opt.auditonly) - 1858 113 : log_tag("summary:error_unrecoverable:%u\n", unrecoverable_error); - 1859 118 : if (fix) { - 1860 45 : if (error + recovered_error + unrecoverable_error == 0) - 1861 2 : log_tag("summary:exit:ok\n"); - 1862 43 : else if (unrecoverable_error == 0) - 1863 34 : log_tag("summary:exit:recovered\n"); - 1864 : else - 1865 9 : log_tag("summary:exit:unrecoverable\n"); - 1866 73 : } else if (!state->opt.auditonly) { - 1867 68 : if (error + unrecoverable_error == 0) - 1868 46 : log_tag("summary:exit:ok\n"); - 1869 22 : else if (unrecoverable_error == 0) - 1870 18 : log_tag("summary:exit:recoverable\n"); - 1871 : else - 1872 4 : log_tag("summary:exit:unrecoverable\n"); - 1873 : } else { /* audit only */ - 1874 5 : if (error == 0) - 1875 3 : log_tag("summary:exit:ok\n"); - 1876 : else - 1877 2 : log_tag("summary:exit:error\n"); - 1878 : } - 1879 118 : log_flush(); - 1880 : - 1881 118 : free(failed); - 1882 118 : free(failed_map); - 1883 118 : free(handle); - 1884 118 : free(buffer_alloc); - 1885 118 : free(buffer); - 1886 : - 1887 : /* fail if some error are present after the run */ - 1888 118 : if (fix) { - 1889 45 : if (state->opt.expect_unrecoverable) { - 1890 9 : if (unrecoverable_error == 0) - 1891 0 : return -1; - 1892 : } else { - 1893 36 : if (unrecoverable_error != 0) - 1894 0 : return -1; - 1895 : } - 1896 : } else { - 1897 73 : if (state->opt.expect_unrecoverable) { - 1898 4 : if (unrecoverable_error == 0) - 1899 0 : return -1; - 1900 69 : } else if (state->opt.expect_recoverable) { - 1901 20 : if (unrecoverable_error != 0 || error == 0) - 1902 0 : return -1; - 1903 : } else { - 1904 49 : if (error != 0 || unrecoverable_error != 0) - 1905 0 : return -1; - 1906 : } - 1907 : } - 1908 : - 1909 118 : return 0; - 1910 : } - 1911 : - 1912 120 : int state_check(struct snapraid_state* state, int fix, block_off_t blockstart, block_off_t blockcount) - 1913 : { - 1914 : block_off_t blockmax; - 1915 : data_off_t size; - 1916 : int ret; - 1917 : struct snapraid_parity_handle parity[LEV_MAX]; - 1918 : struct snapraid_parity_handle* parity_ptr[LEV_MAX]; - 1919 : unsigned error; - 1920 : unsigned l; - 1921 : - 1922 120 : msg_progress("Initializing...\n"); - 1923 : - 1924 120 : blockmax = parity_allocated_size(state); - 1925 120 : size = blockmax * (data_off_t)state->block_size; - 1926 : - 1927 120 : if (blockstart > blockmax) { - 1928 : /* LCOV_EXCL_START */ - 1929 : log_fatal("Error in the specified starting block %u. It's bigger than the parity size %u.\n", blockstart, blockmax); - 1930 : exit(EXIT_FAILURE); - 1931 : /* LCOV_EXCL_STOP */ - 1932 : } - 1933 : - 1934 : /* adjust the number of block to process */ - 1935 120 : if (blockcount != 0 && blockstart + blockcount < blockmax) { - 1936 0 : blockmax = blockstart + blockcount; - 1937 : } - 1938 : - 1939 120 : if (fix) { - 1940 : /* if fixing, create the file and open for writing */ - 1941 : /* if it fails, we cannot continue */ - 1942 180 : for (l = 0; l < state->level; ++l) { - 1943 : /* skip parity disks that are not accessible */ - 1944 135 : if (state->parity[l].skip_access) { - 1945 1 : parity_ptr[l] = 0; - 1946 1 : continue; - 1947 : } - 1948 : - 1949 134 : parity_ptr[l] = &parity[l]; - 1950 134 : ret = parity_create(parity_ptr[l], &state->parity[l], l, state->file_mode, state->block_size, state->opt.parity_limit_size); - 1951 134 : if (ret == -1) { - 1952 : /* LCOV_EXCL_START */ - 1953 : log_fatal("WARNING! Without an accessible %s file, it isn't possible to fix any error.\n", lev_name(l)); - 1954 : exit(EXIT_FAILURE); - 1955 : /* LCOV_EXCL_STOP */ - 1956 : } - 1957 : - 1958 134 : ret = parity_chsize(parity_ptr[l], &state->parity[l], 0, size, state->block_size, state->opt.skip_fallocate, state->opt.skip_space_holder); - 1959 134 : if (ret == -1) { - 1960 : /* LCOV_EXCL_START */ - 1961 : log_fatal("WARNING! Without an accessible %s file, it isn't possible to sync.\n", lev_name(l)); - 1962 : exit(EXIT_FAILURE); - 1963 : /* LCOV_EXCL_STOP */ - 1964 : } - 1965 : } - 1966 75 : } else if (!state->opt.auditonly) { - 1967 : /* if checking, open the file for reading */ - 1968 : /* it may fail if the file doesn't exist, in this case we continue to check the files */ - 1969 393 : for (l = 0; l < state->level; ++l) { - 1970 324 : parity_ptr[l] = &parity[l]; - 1971 324 : ret = parity_open(parity_ptr[l], &state->parity[l], l, state->file_mode, state->block_size, state->opt.parity_limit_size); - 1972 324 : if (ret == -1) { - 1973 1 : msg_status("No accessible %s file, only files will be checked.\n", lev_name(l)); - 1974 : /* continue anyway */ - 1975 1 : parity_ptr[l] = 0; - 1976 : } - 1977 : } - 1978 : } else { - 1979 : /* otherwise don't use any parity */ - 1980 28 : for (l = 0; l < state->level; ++l) - 1981 22 : parity_ptr[l] = 0; - 1982 : } - 1983 : - 1984 120 : if (fix) - 1985 45 : msg_progress("Fixing...\n"); - 1986 75 : else if (!state->opt.auditonly) - 1987 69 : msg_progress("Checking...\n"); - 1988 : else - 1989 6 : msg_progress("Hashing...\n"); - 1990 : - 1991 120 : error = 0; - 1992 : - 1993 : /* skip degenerated cases of empty parity, or skipping all */ - 1994 120 : if (blockstart < blockmax) { - 1995 118 : ret = state_check_process(state, fix, parity_ptr, blockstart, blockmax); - 1996 118 : if (ret == -1) { - 1997 : /* LCOV_EXCL_START */ - 1998 : ++error; - 1999 : /* continue, as we are already exiting */ - 2000 : /* LCOV_EXCL_STOP */ - 2001 : } - 2002 : } - 2003 : - 2004 : /* try to close only if opened */ - 2005 601 : for (l = 0; l < state->level; ++l) { - 2006 481 : if (parity_ptr[l]) { - 2007 457 : ret = parity_close(parity_ptr[l]); - 2008 : /* LCOV_EXCL_START */ - 2009 : if (ret == -1) { - 2010 : log_fatal("DANGER! Unexpected close error in %s disk.\n", lev_name(l)); - 2011 : ++error; - 2012 : /* continue, as we are already exiting */ - 2013 : } - 2014 : /* LCOV_EXCL_STOP */ - 2015 : } - 2016 : } - 2017 : - 2018 : /* abort if error are present */ - 2019 120 : if (error != 0) - 2020 0 : return -1; - 2021 120 : return 0; - 2022 : } - 2023 : + 1723 0 : log_tag("dir_error:%s:%s: Dir error for not directory\n", disk->name, esc_tag(dir->sub, esc_buffer)); + 1724 0 : ++error; + 1725 : } + 1726 : + 1727 421 : if (fix && unsuccesful) { + 1728 : /* create the ancestor directories */ + 1729 21 : ret = mkancestor(path); + 1730 21 : if (ret != 0) { + 1731 : /* LCOV_EXCL_START */ + 1732 : log_fatal("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n"); + 1733 : log_fatal("Stopping\n"); + 1734 : ++unrecoverable_error; + 1735 : goto bail; + 1736 : /* LCOV_EXCL_STOP */ + 1737 : } + 1738 : + 1739 : /* create it */ + 1740 21 : ret = mkdir(path, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); + 1741 21 : if (ret != 0) { + 1742 : /* LCOV_EXCL_START */ + 1743 : log_fatal("Error creating dir '%s'. %s.\n", path, strerror(errno)); + 1744 : if (errno == EACCES) { + 1745 : log_fatal("WARNING! Please give write permission to the dir.\n"); + 1746 : } else { + 1747 : /* we do not use DANGER because it could be ENOSPC which is not always correctly reported */ + 1748 : log_fatal("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n"); + 1749 : } + 1750 : log_fatal("Stopping\n"); + 1751 : ++unrecoverable_error; + 1752 : goto bail; + 1753 : /* LCOV_EXCL_STOP */ + 1754 : } + 1755 : + 1756 21 : log_tag("dir_fixed:%s:%s: Fixed dir error\n", disk->name, esc_tag(dir->sub, esc_buffer)); + 1757 21 : ++recovered_error; + 1758 : + 1759 21 : log_tag("status:recovered:%s:%s\n", disk->name, esc_tag(dir->sub, esc_buffer)); + 1760 21 : msg_info("recovered %s\n", fmt_term(disk, dir->sub, esc_buffer)); + 1761 : } + 1762 : } + 1763 : } + 1764 : + 1765 118 : state_progress_end(state, countpos, countmax, countsize); + 1766 : + 1767 : bail: + 1768 : /* close all the files left open */ + 1769 826 : for (j = 0; j < diskmax; ++j) { + 1770 708 : struct snapraid_file* file = handle[j].file; + 1771 708 : struct snapraid_disk* disk = handle[j].disk; + 1772 708 : ret = handle_close(&handle[j]); + 1773 708 : if (ret == -1) { + 1774 : /* LCOV_EXCL_START */ + 1775 : log_tag("error:%u:%s:%s: Close error. %s\n", blockmax, disk->name, esc_tag(file->sub, esc_buffer), strerror(errno)); + 1776 : log_fatal("DANGER! Unexpected close error in a data disk.\n"); + 1777 : ++unrecoverable_error; + 1778 : /* continue, as we are already exiting */ + 1779 : /* LCOV_EXCL_STOP */ + 1780 : } + 1781 : } + 1782 : + 1783 : /* remove all the files created from scratch that have not finished the processing */ + 1784 : /* it happens only when aborting pressing Ctrl+C or other reason. */ + 1785 118 : if (fix) { + 1786 : /* for each disk */ + 1787 315 : for (i = 0; i < diskmax; ++i) { + 1788 : tommy_node* node; + 1789 : struct snapraid_disk* disk; + 1790 : + 1791 270 : if (!handle[i].disk) + 1792 1 : continue; + 1793 : + 1794 : /* for each file in the disk */ + 1795 269 : disk = handle[i].disk; + 1796 269 : node = disk->filelist; + 1797 870849 : while (node) { + 1798 : char path[PATH_MAX]; + 1799 : struct snapraid_file* file; + 1800 : + 1801 870311 : file = node->data; + 1802 870311 : node = node->next; /* next node */ + 1803 : + 1804 : /* if the file was not created, meaning that it was already existing */ + 1805 870311 : if (!file_flag_has(file, FILE_IS_CREATED)) { + 1806 : /* nothing to do */ + 1807 1627555 : continue; + 1808 : } + 1809 : + 1810 : /* if processing was finished */ + 1811 113067 : if (file_flag_has(file, FILE_IS_FINISHED)) { + 1812 : /* nothing to do */ + 1813 113067 : continue; + 1814 : } + 1815 : + 1816 : /* if the file was originally missing, and processing not yet finished */ + 1817 : /* we have to throw it away to ensure that at the next run we will retry */ + 1818 : /* to fix it, in case we select to undelete missing files */ + 1819 0 : pathprint(path, sizeof(path), "%s%s", disk->dir, file->sub); + 1820 : + 1821 0 : ret = remove(path); + 1822 0 : if (ret != 0) { + 1823 : /* LCOV_EXCL_START */ + 1824 : log_fatal("Error removing '%s'. %s.\n", path, strerror(errno)); + 1825 : log_fatal("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n"); + 1826 : ++unrecoverable_error; + 1827 : /* continue, as we are already exiting */ + 1828 : /* LCOV_EXCL_STOP */ + 1829 : } + 1830 : } + 1831 : } + 1832 : } + 1833 : + 1834 118 : if (error || recovered_error || unrecoverable_error) { + 1835 67 : msg_status("\n"); + 1836 67 : msg_status("%8u errors\n", error); + 1837 67 : if (fix) { + 1838 43 : msg_status("%8u recovered errors\n", recovered_error); + 1839 : } + 1840 134 : if (unrecoverable_error) { + 1841 13 : msg_status("%8u UNRECOVERABLE errors\n", unrecoverable_error); + 1842 : } else { + 1843 : /* without checking, we don't know if they are really recoverable or not */ + 1844 54 : if (!state->opt.auditonly) + 1845 52 : msg_status("%8u unrecoverable errors\n", unrecoverable_error); + 1846 54 : if (fix) + 1847 34 : msg_status("Everything OK\n"); + 1848 : } + 1849 : } else { + 1850 51 : msg_status("Everything OK\n"); + 1851 : } + 1852 : + 1853 118 : if (error && !fix) + 1854 24 : log_fatal("WARNING! There are errors!\n"); + 1855 118 : if (unrecoverable_error) + 1856 13 : log_fatal("DANGER! There are unrecoverable errors!\n"); + 1857 : + 1858 118 : log_tag("summary:error:%u\n", error); + 1859 118 : if (fix) + 1860 45 : log_tag("summary:error_recovered:%u\n", recovered_error); + 1861 118 : if (!state->opt.auditonly) + 1862 113 : log_tag("summary:error_unrecoverable:%u\n", unrecoverable_error); + 1863 118 : if (fix) { + 1864 45 : if (error + recovered_error + unrecoverable_error == 0) + 1865 2 : log_tag("summary:exit:ok\n"); + 1866 43 : else if (unrecoverable_error == 0) + 1867 34 : log_tag("summary:exit:recovered\n"); + 1868 : else + 1869 9 : log_tag("summary:exit:unrecoverable\n"); + 1870 73 : } else if (!state->opt.auditonly) { + 1871 68 : if (error + unrecoverable_error == 0) + 1872 46 : log_tag("summary:exit:ok\n"); + 1873 22 : else if (unrecoverable_error == 0) + 1874 18 : log_tag("summary:exit:recoverable\n"); + 1875 : else + 1876 4 : log_tag("summary:exit:unrecoverable\n"); + 1877 : } else { /* audit only */ + 1878 5 : if (error == 0) + 1879 3 : log_tag("summary:exit:ok\n"); + 1880 : else + 1881 2 : log_tag("summary:exit:error\n"); + 1882 : } + 1883 118 : log_flush(); + 1884 : + 1885 118 : free(failed); + 1886 118 : free(failed_map); + 1887 118 : free(handle); + 1888 118 : free(buffer_alloc); + 1889 118 : free(buffer); + 1890 : + 1891 : /* fail if some error are present after the run */ + 1892 118 : if (fix) { + 1893 45 : if (state->opt.expect_unrecoverable) { + 1894 9 : if (unrecoverable_error == 0) + 1895 0 : return -1; + 1896 : } else { + 1897 36 : if (unrecoverable_error != 0) + 1898 0 : return -1; + 1899 : } + 1900 : } else { + 1901 73 : if (state->opt.expect_unrecoverable) { + 1902 4 : if (unrecoverable_error == 0) + 1903 0 : return -1; + 1904 69 : } else if (state->opt.expect_recoverable) { + 1905 20 : if (unrecoverable_error != 0 || error == 0) + 1906 0 : return -1; + 1907 : } else { + 1908 49 : if (error != 0 || unrecoverable_error != 0) + 1909 0 : return -1; + 1910 : } + 1911 : } + 1912 : + 1913 118 : return 0; + 1914 : } + 1915 : + 1916 120 : int state_check(struct snapraid_state* state, int fix, block_off_t blockstart, block_off_t blockcount) + 1917 : { + 1918 : block_off_t blockmax; + 1919 : data_off_t size; + 1920 : int ret; + 1921 : struct snapraid_parity_handle parity[LEV_MAX]; + 1922 : struct snapraid_parity_handle* parity_ptr[LEV_MAX]; + 1923 : unsigned error; + 1924 : unsigned l; + 1925 : + 1926 120 : msg_progress("Initializing...\n"); + 1927 : + 1928 120 : blockmax = parity_allocated_size(state); + 1929 120 : size = blockmax * (data_off_t)state->block_size; + 1930 : + 1931 120 : if (blockstart > blockmax) { + 1932 : /* LCOV_EXCL_START */ + 1933 : log_fatal("Error in the specified starting block %u. It's bigger than the parity size %u.\n", blockstart, blockmax); + 1934 : exit(EXIT_FAILURE); + 1935 : /* LCOV_EXCL_STOP */ + 1936 : } + 1937 : + 1938 : /* adjust the number of block to process */ + 1939 120 : if (blockcount != 0 && blockstart + blockcount < blockmax) { + 1940 0 : blockmax = blockstart + blockcount; + 1941 : } + 1942 : + 1943 120 : if (fix) { + 1944 : /* if fixing, create the file and open for writing */ + 1945 : /* if it fails, we cannot continue */ + 1946 180 : for (l = 0; l < state->level; ++l) { + 1947 : /* skip parity disks that are not accessible */ + 1948 135 : if (state->parity[l].skip_access) { + 1949 1 : parity_ptr[l] = 0; + 1950 1 : continue; + 1951 : } + 1952 : + 1953 134 : parity_ptr[l] = &parity[l]; + 1954 134 : ret = parity_create(parity_ptr[l], &state->parity[l], l, state->file_mode, state->block_size, state->opt.parity_limit_size); + 1955 134 : if (ret == -1) { + 1956 : /* LCOV_EXCL_START */ + 1957 : log_fatal("WARNING! Without an accessible %s file, it isn't possible to fix any error.\n", lev_name(l)); + 1958 : exit(EXIT_FAILURE); + 1959 : /* LCOV_EXCL_STOP */ + 1960 : } + 1961 : + 1962 134 : ret = parity_chsize(parity_ptr[l], &state->parity[l], 0, size, state->block_size, state->opt.skip_fallocate, state->opt.skip_space_holder); + 1963 134 : if (ret == -1) { + 1964 : /* LCOV_EXCL_START */ + 1965 : log_fatal("WARNING! Without an accessible %s file, it isn't possible to sync.\n", lev_name(l)); + 1966 : exit(EXIT_FAILURE); + 1967 : /* LCOV_EXCL_STOP */ + 1968 : } + 1969 : } + 1970 75 : } else if (!state->opt.auditonly) { + 1971 : /* if checking, open the file for reading */ + 1972 : /* it may fail if the file doesn't exist, in this case we continue to check the files */ + 1973 393 : for (l = 0; l < state->level; ++l) { + 1974 324 : parity_ptr[l] = &parity[l]; + 1975 324 : ret = parity_open(parity_ptr[l], &state->parity[l], l, state->file_mode, state->block_size, state->opt.parity_limit_size); + 1976 324 : if (ret == -1) { + 1977 1 : msg_status("No accessible %s file, only files will be checked.\n", lev_name(l)); + 1978 : /* continue anyway */ + 1979 1 : parity_ptr[l] = 0; + 1980 : } + 1981 : } + 1982 : } else { + 1983 : /* otherwise don't use any parity */ + 1984 28 : for (l = 0; l < state->level; ++l) + 1985 22 : parity_ptr[l] = 0; + 1986 : } + 1987 : + 1988 120 : if (fix) + 1989 45 : msg_progress("Fixing...\n"); + 1990 75 : else if (!state->opt.auditonly) + 1991 69 : msg_progress("Checking...\n"); + 1992 : else + 1993 6 : msg_progress("Hashing...\n"); + 1994 : + 1995 120 : error = 0; + 1996 : + 1997 : /* skip degenerated cases of empty parity, or skipping all */ + 1998 120 : if (blockstart < blockmax) { + 1999 118 : ret = state_check_process(state, fix, parity_ptr, blockstart, blockmax); + 2000 118 : if (ret == -1) { + 2001 : /* LCOV_EXCL_START */ + 2002 : ++error; + 2003 : /* continue, as we are already exiting */ + 2004 : /* LCOV_EXCL_STOP */ + 2005 : } + 2006 : } + 2007 : + 2008 : /* try to close only if opened */ + 2009 601 : for (l = 0; l < state->level; ++l) { + 2010 481 : if (parity_ptr[l]) { + 2011 457 : ret = parity_close(parity_ptr[l]); + 2012 : /* LCOV_EXCL_START */ + 2013 : if (ret == -1) { + 2014 : log_fatal("DANGER! Unexpected close error in %s disk.\n", lev_name(l)); + 2015 : ++error; + 2016 : /* continue, as we are already exiting */ + 2017 : } + 2018 : /* LCOV_EXCL_STOP */ + 2019 : } + 2020 : } + 2021 : + 2022 : /* abort if error are present */ + 2023 120 : if (error != 0) + 2024 0 : return -1; + 2025 120 : return 0; + 2026 : } + 2027 : diff --git a/cov/cmdline/dry.c.func-sort-c.html b/cov/cmdline/dry.c.func-sort-c.html index 57c0a78f..3dc0963d 100644 --- a/cov/cmdline/dry.c.func-sort-c.html +++ b/cov/cmdline/dry.c.func-sort-c.html @@ -32,8 +32,8 @@ Lines: 120 - 165 - 72.7 % + 157 + 76.4 % Date: @@ -61,18 +61,18 @@ dry_parity_reader - 42604 + 42601 dry_data_reader - 42590 + 42596 block_is_enabled 7102 - state_dry + state_dry 2 diff --git a/cov/cmdline/dry.c.func.html b/cov/cmdline/dry.c.func.html index 141183a7..6a9299f2 100644 --- a/cov/cmdline/dry.c.func.html +++ b/cov/cmdline/dry.c.func.html @@ -32,8 +32,8 @@ Lines: 120 - 165 - 72.7 % + 157 + 76.4 % Date: @@ -65,14 +65,14 @@ dry_data_reader - 42590 + 42596 dry_parity_reader - 42604 + 42601 - state_dry + state_dry 2 diff --git a/cov/cmdline/dry.c.gcov.html b/cov/cmdline/dry.c.gcov.html index 52744e1f..a360ddef 100644 --- a/cov/cmdline/dry.c.gcov.html +++ b/cov/cmdline/dry.c.gcov.html @@ -32,8 +32,8 @@ Lines: 120 - 165 - 72.7 % + 157 + 76.4 % Date: @@ -101,30 +101,30 @@ 39 7102 : return 1; 40 : } 41 : - 42 42590 : static void dry_data_reader(struct snapraid_worker* worker, struct snapraid_task* task) + 42 42596 : static void dry_data_reader(struct snapraid_worker* worker, struct snapraid_task* task) 43 : { - 44 42590 : struct snapraid_io* io = worker->io; - 45 42590 : struct snapraid_state* state = io->state; - 46 42590 : struct snapraid_handle* handle = worker->handle; - 47 42590 : struct snapraid_disk* disk = handle->disk; - 48 42590 : block_off_t blockcur = task->position; - 49 42590 : unsigned char* buffer = task->buffer; + 44 42596 : struct snapraid_io* io = worker->io; + 45 42596 : struct snapraid_state* state = io->state; + 46 42596 : struct snapraid_handle* handle = worker->handle; + 47 42596 : struct snapraid_disk* disk = handle->disk; + 48 42596 : block_off_t blockcur = task->position; + 49 42596 : unsigned char* buffer = task->buffer; 50 : int ret; 51 : char esc_buffer[ESC_MAX]; 52 : 53 : /* if the disk position is not used */ - 54 42590 : if (!disk) { + 54 42596 : if (!disk) { 55 : /* use an empty block */ - 56 4686 : memset(buffer, 0, state->block_size); - 57 4686 : task->state = TASK_STATE_DONE; - 58 9916 : return; + 56 4687 : memset(buffer, 0, state->block_size); + 57 4687 : task->state = TASK_STATE_DONE; + 58 9918 : return; 59 : } 60 : 61 : /* get the block */ - 62 37904 : task->block = fs_par2block_find(disk, blockcur); + 62 37909 : task->block = fs_par2block_find(disk, blockcur); 63 : 64 : /* if the block is not used */ - 65 37878 : if (!block_has_file(task->block)) { + 65 37865 : if (!block_has_file(task->block)) { 66 : /* use an empty block */ 67 544 : memset(buffer, 0, state->block_size); 68 544 : task->state = TASK_STATE_DONE; @@ -132,14 +132,14 @@ 70 : } 71 : 72 : /* get the file of this block */ - 73 37320 : task->file = fs_par2file_get(disk, blockcur, &task->file_pos); + 73 37325 : task->file = fs_par2file_get(disk, blockcur, &task->file_pos); 74 : 75 : /* if the file is different than the current one, close it */ - 76 37335 : if (handle->file != 0 && handle->file != task->file) { + 76 37355 : if (handle->file != 0 && handle->file != task->file) { 77 : /* keep a pointer at the file we are going to close for error reporting */ - 78 15082 : struct snapraid_file* report = handle->file; - 79 15082 : ret = handle_close(handle); - 80 15071 : if (ret == -1) { + 78 15077 : struct snapraid_file* report = handle->file; + 79 15077 : ret = handle_close(handle); + 80 15079 : if (ret == -1) { 81 : /* LCOV_EXCL_START */ 82 : /* This one is really an unexpected error, because we are only reading */ 83 : /* and closing a descriptor should never fail */ @@ -162,8 +162,8 @@ 100 : } 101 : } 102 : - 103 37324 : ret = handle_open(handle, task->file, state->file_mode, log_error, 0); - 104 37350 : if (ret == -1) { + 103 37357 : ret = handle_open(handle, task->file, state->file_mode, log_error, 0); + 104 37369 : if (ret == -1) { 105 0 : if (errno == EIO) { 106 : /* LCOV_EXCL_START */ 107 : log_tag("error:%u:%s:%s: Open EIO error. %s\n", blockcur, disk->name, esc_tag(task->file->sub, esc_buffer), strerror(errno)); @@ -180,8 +180,8 @@ 118 0 : return; 119 : } 120 : - 121 37350 : task->read_size = handle_read(handle, task->file_pos, buffer, state->block_size, log_error, 0); - 122 37281 : if (task->read_size == -1) { + 121 37369 : task->read_size = handle_read(handle, task->file_pos, buffer, state->block_size, log_error, 0); + 122 37250 : if (task->read_size == -1) { 123 0 : if (errno == EIO) { 124 0 : log_tag("error:%u:%s:%s: Read EIO error at position %u. %s\n", blockcur, disk->name, esc_tag(task->file->sub, esc_buffer), task->file_pos, strerror(errno)); 125 0 : log_error("Input/Output error in file '%s' at position '%u'\n", handle->path, task->file_pos); @@ -195,24 +195,24 @@ 133 : } 134 : 135 : /* store the path of the opened file */ - 136 37281 : pathcpy(task->path, sizeof(task->path), handle->path); + 136 37250 : pathcpy(task->path, sizeof(task->path), handle->path); 137 : - 138 37299 : task->state = TASK_STATE_DONE; + 138 37319 : task->state = TASK_STATE_DONE; 139 : } 140 : - 141 42604 : static void dry_parity_reader(struct snapraid_worker* worker, struct snapraid_task* task) + 141 42601 : static void dry_parity_reader(struct snapraid_worker* worker, struct snapraid_task* task) 142 : { - 143 42604 : struct snapraid_io* io = worker->io; - 144 42604 : struct snapraid_state* state = io->state; - 145 42604 : struct snapraid_parity_handle* parity_handle = worker->parity_handle; - 146 42604 : unsigned level = parity_handle->level; - 147 42604 : block_off_t blockcur = task->position; - 148 42604 : unsigned char* buffer = task->buffer; + 143 42601 : struct snapraid_io* io = worker->io; + 144 42601 : struct snapraid_state* state = io->state; + 145 42601 : struct snapraid_parity_handle* parity_handle = worker->parity_handle; + 146 42601 : unsigned level = parity_handle->level; + 147 42601 : block_off_t blockcur = task->position; + 148 42601 : unsigned char* buffer = task->buffer; 149 : int ret; 150 : 151 : /* read the parity */ - 152 42604 : ret = parity_read(parity_handle, blockcur, buffer, state->block_size, log_error); - 153 42568 : if (ret == -1) { + 152 42601 : ret = parity_read(parity_handle, blockcur, buffer, state->block_size, log_error); + 153 42575 : if (ret == -1) { 154 0 : if (errno == EIO) { 155 0 : log_tag("parity_error:%u:%s: Read EIO error. %s\n", blockcur, lev_config_name(level), strerror(errno)); 156 0 : log_error("Input/Output error in parity '%s' at position '%u'\n", lev_config_name(level), blockcur); @@ -225,7 +225,7 @@ 163 0 : return; 164 : } 165 : - 166 42568 : task->state = TASK_STATE_DONE; + 166 42575 : task->state = TASK_STATE_DONE; 167 : } 168 : 169 2 : static int state_dry_process(struct snapraid_state* state, struct snapraid_parity_handle* parity_handle, block_off_t blockstart, block_off_t blockmax) @@ -316,210 +316,218 @@ 254 : 255 : /* handle error conditions */ 256 37380 : if (task->state == TASK_STATE_IOERROR) { - 257 0 : ++io_error; - 258 0 : goto bail; - 259 : } - 260 37380 : if (task->state == TASK_STATE_ERROR) { - 261 0 : ++error; - 262 0 : goto bail; - 263 : } - 264 37380 : if (task->state == TASK_STATE_ERROR_CONTINUE) { - 265 0 : ++error; - 266 0 : continue; + 257 : /* LCOV_EXCL_START */ + 258 : ++io_error; + 259 : goto bail; + 260 : /* LCOV_EXCL_STOP */ + 261 : } + 262 37380 : if (task->state == TASK_STATE_ERROR) { + 263 : /* LCOV_EXCL_START */ + 264 : ++error; + 265 : goto bail; + 266 : /* LCOV_EXCL_STOP */ 267 : } - 268 37380 : if (task->state == TASK_STATE_IOERROR_CONTINUE) { - 269 0 : ++io_error; - 270 0 : if (io_error >= state->opt.io_error_limit) { - 271 : /* LCOV_EXCL_START */ - 272 : log_fatal("DANGER! Too many input/output read error in a data disk, it isn't possible to scrub.\n"); - 273 : log_fatal("Ensure that disk '%s' is sane and that file '%s' can be accessed.\n", disk->dir, task->path); - 274 : log_fatal("Stopping at block %u\n", blockcur); - 275 : goto bail; - 276 : /* LCOV_EXCL_STOP */ - 277 : } - 278 : - 279 : /* otherwise continue */ - 280 0 : continue; - 281 : } - 282 37380 : if (task->state != TASK_STATE_DONE) { - 283 : /* LCOV_EXCL_START */ - 284 : log_fatal("Internal inconsistency in task state\n"); - 285 : os_abort(); - 286 : /* LCOV_EXCL_STOP */ - 287 : } - 288 : - 289 37380 : countsize += read_size; - 290 : } - 291 : - 292 : /* until now is misc */ - 293 7102 : state_usage_misc(state); - 294 : - 295 : /* read the parity */ - 296 49714 : for (l = 0; l < state->level; ++l) { - 297 : struct snapraid_task* task; - 298 : unsigned levcur; - 299 : - 300 42612 : task = io_parity_read(&io, &levcur, waiting_map, &waiting_mac); - 301 : - 302 : /* until now is parity */ - 303 42612 : state_usage_parity(state, waiting_map, waiting_mac); - 304 : - 305 : /* handle error conditions */ - 306 42612 : if (task->state == TASK_STATE_IOERROR) { - 307 0 : ++io_error; - 308 0 : goto bail; - 309 : } - 310 42612 : if (task->state == TASK_STATE_ERROR) { - 311 0 : ++error; - 312 0 : goto bail; - 313 : } - 314 42612 : if (task->state == TASK_STATE_ERROR_CONTINUE) { - 315 0 : ++error; - 316 0 : continue; - 317 : } - 318 42612 : if (task->state == TASK_STATE_IOERROR_CONTINUE) { - 319 0 : ++io_error; - 320 0 : if (io_error >= state->opt.io_error_limit) { - 321 : /* LCOV_EXCL_START */ - 322 : log_fatal("DANGER! Too many input/output read error in the %s disk, it isn't possible to scrub.\n", lev_name(levcur)); - 323 : log_fatal("Ensure that disk '%s' is sane and can be read.\n", lev_config_name(levcur)); - 324 : log_fatal("Stopping at block %u\n", blockcur); - 325 : goto bail; - 326 : /* LCOV_EXCL_STOP */ - 327 : } - 328 0 : continue; - 329 : } - 330 42612 : if (task->state != TASK_STATE_DONE) { - 331 : /* LCOV_EXCL_START */ - 332 : log_fatal("Internal inconsistency in task state\n"); - 333 : os_abort(); - 334 : /* LCOV_EXCL_STOP */ - 335 : } - 336 : } - 337 : - 338 : /* count the number of processed block */ - 339 7102 : ++countpos; - 340 : - 341 : /* progress */ - 342 7102 : if (state_progress(state, &io, blockcur, countpos, countmax, countsize)) { - 343 : /* LCOV_EXCL_START */ - 344 : break; - 345 : /* LCOV_EXCL_STOP */ - 346 : } - 347 7102 : } + 268 37380 : if (task->state == TASK_STATE_ERROR_CONTINUE) { + 269 0 : ++error; + 270 0 : continue; + 271 : } + 272 37380 : if (task->state == TASK_STATE_IOERROR_CONTINUE) { + 273 0 : ++io_error; + 274 0 : if (io_error >= state->opt.io_error_limit) { + 275 : /* LCOV_EXCL_START */ + 276 : log_fatal("DANGER! Too many input/output read error in a data disk, it isn't possible to scrub.\n"); + 277 : log_fatal("Ensure that disk '%s' is sane and that file '%s' can be accessed.\n", disk->dir, task->path); + 278 : log_fatal("Stopping at block %u\n", blockcur); + 279 : goto bail; + 280 : /* LCOV_EXCL_STOP */ + 281 : } + 282 : + 283 : /* otherwise continue */ + 284 0 : continue; + 285 : } + 286 37380 : if (task->state != TASK_STATE_DONE) { + 287 : /* LCOV_EXCL_START */ + 288 : log_fatal("Internal inconsistency in task state\n"); + 289 : os_abort(); + 290 : /* LCOV_EXCL_STOP */ + 291 : } + 292 : + 293 37380 : countsize += read_size; + 294 : } + 295 : + 296 : /* until now is misc */ + 297 7102 : state_usage_misc(state); + 298 : + 299 : /* read the parity */ + 300 49714 : for (l = 0; l < state->level; ++l) { + 301 : struct snapraid_task* task; + 302 : unsigned levcur; + 303 : + 304 42612 : task = io_parity_read(&io, &levcur, waiting_map, &waiting_mac); + 305 : + 306 : /* until now is parity */ + 307 42612 : state_usage_parity(state, waiting_map, waiting_mac); + 308 : + 309 : /* handle error conditions */ + 310 42612 : if (task->state == TASK_STATE_IOERROR) { + 311 : /* LCOV_EXCL_START */ + 312 : ++io_error; + 313 : goto bail; + 314 : /* LCOV_EXCL_STOP */ + 315 : } + 316 42612 : if (task->state == TASK_STATE_ERROR) { + 317 : /* LCOV_EXCL_START */ + 318 : ++error; + 319 : goto bail; + 320 : /* LCOV_EXCL_STOP */ + 321 : } + 322 42612 : if (task->state == TASK_STATE_ERROR_CONTINUE) { + 323 0 : ++error; + 324 0 : continue; + 325 : } + 326 42612 : if (task->state == TASK_STATE_IOERROR_CONTINUE) { + 327 0 : ++io_error; + 328 0 : if (io_error >= state->opt.io_error_limit) { + 329 : /* LCOV_EXCL_START */ + 330 : log_fatal("DANGER! Too many input/output read error in the %s disk, it isn't possible to scrub.\n", lev_name(levcur)); + 331 : log_fatal("Ensure that disk '%s' is sane and can be read.\n", lev_config_name(levcur)); + 332 : log_fatal("Stopping at block %u\n", blockcur); + 333 : goto bail; + 334 : /* LCOV_EXCL_STOP */ + 335 : } + 336 0 : continue; + 337 : } + 338 42612 : if (task->state != TASK_STATE_DONE) { + 339 : /* LCOV_EXCL_START */ + 340 : log_fatal("Internal inconsistency in task state\n"); + 341 : os_abort(); + 342 : /* LCOV_EXCL_STOP */ + 343 : } + 344 : } + 345 : + 346 : /* count the number of processed block */ + 347 7102 : ++countpos; 348 : - 349 2 : state_progress_end(state, countpos, countmax, countsize); - 350 : - 351 2 : state_usage_print(state); - 352 : - 353 : bail: - 354 : /* stop all the worker threads */ - 355 2 : io_stop(&io); + 349 : /* progress */ + 350 7102 : if (state_progress(state, &io, blockcur, countpos, countmax, countsize)) { + 351 : /* LCOV_EXCL_START */ + 352 : break; + 353 : /* LCOV_EXCL_STOP */ + 354 : } + 355 7102 : } 356 : - 357 14 : for (j = 0; j < diskmax; ++j) { - 358 12 : struct snapraid_file* file = handle[j].file; - 359 12 : struct snapraid_disk* disk = handle[j].disk; - 360 12 : ret = handle_close(&handle[j]); - 361 12 : if (ret == -1) { - 362 : /* LCOV_EXCL_START */ - 363 : log_tag("error:%u:%s:%s: Close error. %s\n", blockmax, disk->name, esc_tag(file->sub, esc_buffer), strerror(errno)); - 364 : log_fatal("DANGER! Unexpected close error in a data disk.\n"); - 365 : ++error; - 366 : /* continue, as we are already exiting */ - 367 : /* LCOV_EXCL_STOP */ - 368 : } - 369 : } - 370 : - 371 2 : if (error || io_error) { - 372 0 : msg_status("\n"); - 373 0 : msg_status("%8u file errors\n", error); - 374 0 : msg_status("%8u io errors\n", io_error); - 375 : } else { - 376 2 : msg_status("Everything OK\n"); + 357 2 : state_progress_end(state, countpos, countmax, countsize); + 358 : + 359 2 : state_usage_print(state); + 360 : + 361 : bail: + 362 : /* stop all the worker threads */ + 363 2 : io_stop(&io); + 364 : + 365 14 : for (j = 0; j < diskmax; ++j) { + 366 12 : struct snapraid_file* file = handle[j].file; + 367 12 : struct snapraid_disk* disk = handle[j].disk; + 368 12 : ret = handle_close(&handle[j]); + 369 12 : if (ret == -1) { + 370 : /* LCOV_EXCL_START */ + 371 : log_tag("error:%u:%s:%s: Close error. %s\n", blockmax, disk->name, esc_tag(file->sub, esc_buffer), strerror(errno)); + 372 : log_fatal("DANGER! Unexpected close error in a data disk.\n"); + 373 : ++error; + 374 : /* continue, as we are already exiting */ + 375 : /* LCOV_EXCL_STOP */ + 376 : } 377 : } 378 : - 379 2 : if (error) - 380 0 : log_fatal("DANGER! Unexpected errors!\n"); - 381 2 : if (io_error) - 382 0 : log_fatal("DANGER! Unexpected input/output errors!\n"); - 383 : - 384 2 : free(handle); - 385 2 : free(waiting_map); - 386 2 : io_done(&io); - 387 : - 388 2 : if (error + io_error != 0) - 389 0 : return -1; - 390 2 : return 0; - 391 : } - 392 : - 393 2 : void state_dry(struct snapraid_state* state, block_off_t blockstart, block_off_t blockcount) - 394 : { - 395 : block_off_t blockmax; - 396 : int ret; - 397 : struct snapraid_parity_handle parity_handle[LEV_MAX]; - 398 : unsigned error; - 399 : unsigned l; + 379 2 : if (error || io_error) { + 380 0 : msg_status("\n"); + 381 0 : msg_status("%8u file errors\n", error); + 382 0 : msg_status("%8u io errors\n", io_error); + 383 : } else { + 384 2 : msg_status("Everything OK\n"); + 385 : } + 386 : + 387 2 : if (error) + 388 0 : log_fatal("DANGER! Unexpected errors!\n"); + 389 2 : if (io_error) + 390 0 : log_fatal("DANGER! Unexpected input/output errors!\n"); + 391 : + 392 2 : free(handle); + 393 2 : free(waiting_map); + 394 2 : io_done(&io); + 395 : + 396 2 : if (error + io_error != 0) + 397 0 : return -1; + 398 2 : return 0; + 399 : } 400 : - 401 2 : msg_progress("Drying...\n"); - 402 : - 403 2 : blockmax = parity_allocated_size(state); - 404 : - 405 2 : if (blockstart > blockmax) { - 406 : /* LCOV_EXCL_START */ - 407 : log_fatal("Error in the specified starting block %u. It's bigger than the parity size %u.\n", blockstart, blockmax); - 408 : exit(EXIT_FAILURE); - 409 : /* LCOV_EXCL_STOP */ - 410 : } - 411 : - 412 : /* adjust the number of block to process */ - 413 2 : if (blockcount != 0 && blockstart + blockcount < blockmax) { - 414 0 : blockmax = blockstart + blockcount; - 415 : } - 416 : - 417 : /* open the file for reading */ - 418 : /* it may fail if the file doesn't exist, in this case we continue to dry the files */ - 419 14 : for (l = 0; l < state->level; ++l) { - 420 12 : ret = parity_open(&parity_handle[l], &state->parity[l], l, state->file_mode, state->block_size, state->opt.parity_limit_size); - 421 12 : if (ret == -1) { - 422 : /* LCOV_EXCL_START */ - 423 : log_fatal("WARNING! Without an accessible %s file, it isn't possible to dry.\n", lev_name(l)); - 424 : exit(EXIT_FAILURE); - 425 : /* LCOV_EXCL_STOP */ - 426 : } - 427 : } - 428 : - 429 2 : error = 0; - 430 : - 431 : /* skip degenerated cases of empty parity, or skipping all */ - 432 2 : if (blockstart < blockmax) { - 433 2 : ret = state_dry_process(state, parity_handle, blockstart, blockmax); - 434 2 : if (ret == -1) { - 435 : /* LCOV_EXCL_START */ - 436 : ++error; - 437 : /* continue, as we are already exiting */ - 438 : /* LCOV_EXCL_STOP */ - 439 : } - 440 : } - 441 : - 442 : /* try to close only if opened */ - 443 14 : for (l = 0; l < state->level; ++l) { - 444 12 : ret = parity_close(&parity_handle[l]); - 445 12 : if (ret == -1) { - 446 : /* LCOV_EXCL_START */ - 447 : ++error; - 448 : /* continue, as we are already exiting */ - 449 : /* LCOV_EXCL_STOP */ - 450 : } - 451 : } - 452 : - 453 : /* abort if required */ - 454 2 : if (error != 0) { - 455 : /* LCOV_EXCL_START */ - 456 : exit(EXIT_FAILURE); - 457 : /* LCOV_EXCL_STOP */ - 458 : } - 459 2 : } + 401 2 : void state_dry(struct snapraid_state* state, block_off_t blockstart, block_off_t blockcount) + 402 : { + 403 : block_off_t blockmax; + 404 : int ret; + 405 : struct snapraid_parity_handle parity_handle[LEV_MAX]; + 406 : unsigned error; + 407 : unsigned l; + 408 : + 409 2 : msg_progress("Drying...\n"); + 410 : + 411 2 : blockmax = parity_allocated_size(state); + 412 : + 413 2 : if (blockstart > blockmax) { + 414 : /* LCOV_EXCL_START */ + 415 : log_fatal("Error in the specified starting block %u. It's bigger than the parity size %u.\n", blockstart, blockmax); + 416 : exit(EXIT_FAILURE); + 417 : /* LCOV_EXCL_STOP */ + 418 : } + 419 : + 420 : /* adjust the number of block to process */ + 421 2 : if (blockcount != 0 && blockstart + blockcount < blockmax) { + 422 0 : blockmax = blockstart + blockcount; + 423 : } + 424 : + 425 : /* open the file for reading */ + 426 : /* it may fail if the file doesn't exist, in this case we continue to dry the files */ + 427 14 : for (l = 0; l < state->level; ++l) { + 428 12 : ret = parity_open(&parity_handle[l], &state->parity[l], l, state->file_mode, state->block_size, state->opt.parity_limit_size); + 429 12 : if (ret == -1) { + 430 : /* LCOV_EXCL_START */ + 431 : log_fatal("WARNING! Without an accessible %s file, it isn't possible to dry.\n", lev_name(l)); + 432 : exit(EXIT_FAILURE); + 433 : /* LCOV_EXCL_STOP */ + 434 : } + 435 : } + 436 : + 437 2 : error = 0; + 438 : + 439 : /* skip degenerated cases of empty parity, or skipping all */ + 440 2 : if (blockstart < blockmax) { + 441 2 : ret = state_dry_process(state, parity_handle, blockstart, blockmax); + 442 2 : if (ret == -1) { + 443 : /* LCOV_EXCL_START */ + 444 : ++error; + 445 : /* continue, as we are already exiting */ + 446 : /* LCOV_EXCL_STOP */ + 447 : } + 448 : } + 449 : + 450 : /* try to close only if opened */ + 451 14 : for (l = 0; l < state->level; ++l) { + 452 12 : ret = parity_close(&parity_handle[l]); + 453 12 : if (ret == -1) { + 454 : /* LCOV_EXCL_START */ + 455 : ++error; + 456 : /* continue, as we are already exiting */ + 457 : /* LCOV_EXCL_STOP */ + 458 : } + 459 : } 460 : + 461 : /* abort if required */ + 462 2 : if (error != 0) { + 463 : /* LCOV_EXCL_START */ + 464 : exit(EXIT_FAILURE); + 465 : /* LCOV_EXCL_STOP */ + 466 : } + 467 2 : } + 468 : diff --git a/cov/cmdline/elem.c.func-sort-c.html b/cov/cmdline/elem.c.func-sort-c.html index 37d36fef..adc5592a 100644 --- a/cov/cmdline/elem.c.func-sort-c.html +++ b/cov/cmdline/elem.c.func-sort-c.html @@ -61,71 +61,71 @@ extent_parity_inside_compare_unlock - 113816358 + 113835807 fs_lock - 53194369 + 53196480 fs_unlock - 53193869 + 53196096 extent_file_compare - 45007856 + 45007274 fs_file2block_get - 44945080 + 44946613 extent_parity_compare - 44511012 + 44510782 fs_par2extent_get_unlock - 39142093 + 39144459 fs_par2file_find - 39035232 + 39037806 fs_par2block_find - 27312315 + 27314040 extent_file_inside_compare_unlock - 21314053 + 21310663 filter_apply - 12456124 + 12456904 fs_file2extent_get_unlock - 10336325 + 10336351 fs_allocate - 9175619 + 9175524 file_block_size - 6823060 + 6823791 extent_file_check_foreach_unlock - 6584437 + 6584417 extent_parity_check_foreach_unlock - 6584437 + 6584417 filter_recurse - 6236157 + 6236559 file_block_is_last @@ -133,55 +133,55 @@ fs_file2par_find - 4869535 + 4869582 extent_alloc - 3735492 + 3735396 file_alloc - 3691209 + 3691126 extent_free - 3564805 + 3564840 file_free - 3543765 + 3543814 filter_element - 3332623 + 3332824 filter_path - 3329526 + 3329727 filter_content - 3173124 + 3173351 file_inode_compare_to_arg - 987050 + 987099 time_compare - 684987 + 684203 fmt_term - 356004 + 356075 file_path_compare - 189434 + 189486 filter_type - 125245 + 125255 link_alloc @@ -193,27 +193,27 @@ fs_deallocate - 106126 + 106308 file_path_compare_to_arg - 97552 + 97531 filter_existence 80691 - - file_physical_compare - 63430 - extent_disk_size_compare_unlock - 50483 + 50510 file_name - 47954 + 47922 + + + file_physical_compare + 44202 filter_correctness @@ -225,11 +225,11 @@ file_namestamp_compare - 23977 + 23961 file_name_compare - 23977 + 23961 file_stamp_compare @@ -241,11 +241,11 @@ file_dup - 22680 + 22687 fs_size - 4339 + 4351 link_alpha_compare @@ -257,19 +257,19 @@ fs_check - 2970 + 2982 disk_alloc - 1579 + 1585 map_alloc - 1549 + 1555 content_alloc - 1523 + 1525 disk_free @@ -297,7 +297,7 @@ filter_alloc_file - 532 + 534 filter_free diff --git a/cov/cmdline/elem.c.func.html b/cov/cmdline/elem.c.func.html index 4f769ce7..867b2c1f 100644 --- a/cov/cmdline/elem.c.func.html +++ b/cov/cmdline/elem.c.func.html @@ -61,7 +61,7 @@ content_alloc - 1523 + 1525 content_free @@ -81,7 +81,7 @@ disk_alloc - 1579 + 1585 disk_free @@ -89,7 +89,7 @@ extent_alloc - 3735492 + 3735396 extent_disk_empty_compare_unlock @@ -97,39 +97,39 @@ extent_disk_size_compare_unlock - 50483 + 50510 extent_file_check_foreach_unlock - 6584437 + 6584417 extent_file_compare - 45007856 + 45007274 extent_file_inside_compare_unlock - 21314053 + 21310663 extent_free - 3564805 + 3564840 extent_parity_check_foreach_unlock - 6584437 + 6584417 extent_parity_compare - 44511012 + 44510782 extent_parity_inside_compare_unlock - 113816358 + 113835807 file_alloc - 3691209 + 3691126 file_block_is_last @@ -137,7 +137,7 @@ file_block_size - 6823060 + 6823791 file_copy @@ -145,11 +145,11 @@ file_dup - 22680 + 22687 file_free - 3543765 + 3543814 file_inode_compare @@ -157,27 +157,27 @@ file_inode_compare_to_arg - 987050 + 987099 file_name - 47954 + 47922 file_name_compare - 23977 + 23961 file_namestamp_compare - 23977 + 23961 file_path_compare - 189434 + 189486 file_path_compare_to_arg - 97552 + 97531 file_pathstamp_compare @@ -185,7 +185,7 @@ file_physical_compare - 63430 + 44202 file_rename @@ -201,15 +201,15 @@ filter_alloc_file - 532 + 534 filter_apply - 12456124 + 12456904 filter_content - 3173124 + 3173351 filter_correctness @@ -217,7 +217,7 @@ filter_element - 3332623 + 3332824 filter_emptydir @@ -233,11 +233,11 @@ filter_path - 3329526 + 3329727 filter_recurse - 6236157 + 6236559 filter_subdir @@ -245,7 +245,7 @@ filter_type - 125245 + 125255 fmt_poll @@ -253,31 +253,31 @@ fmt_term - 356004 + 356075 fs_allocate - 9175619 + 9175524 fs_check - 2970 + 2982 fs_deallocate - 106126 + 106308 fs_file2block_get - 44945080 + 44946613 fs_file2extent_get_unlock - 10336325 + 10336351 fs_file2par_find - 4869535 + 4869582 fs_is_empty @@ -285,27 +285,27 @@ fs_lock - 53194369 + 53196480 fs_par2block_find - 27312315 + 27314040 fs_par2extent_get_unlock - 39142093 + 39144459 fs_par2file_find - 39035232 + 39037806 fs_size - 4339 + 4351 fs_unlock - 53193869 + 53196096 link_alloc @@ -325,7 +325,7 @@ map_alloc - 1549 + 1555 map_free @@ -333,7 +333,7 @@ time_compare - 684987 + 684203
diff --git a/cov/cmdline/elem.c.gcov.html b/cov/cmdline/elem.c.gcov.html index dec010b8..82da91c6 100644 --- a/cov/cmdline/elem.c.gcov.html +++ b/cov/cmdline/elem.c.gcov.html @@ -88,15 +88,15 @@ 26 : 27 : int BLOCK_HASH_SIZE = HASH_MAX; 28 : - 29 1523 : struct snapraid_content* content_alloc(const char* path, uint64_t dev) + 29 1525 : struct snapraid_content* content_alloc(const char* path, uint64_t dev) 30 : { 31 : struct snapraid_content* content; 32 : - 33 1523 : content = malloc_nofail(sizeof(struct snapraid_content)); - 34 1523 : pathimport(content->content, sizeof(content->content), path); - 35 1523 : content->device = dev; + 33 1525 : content = malloc_nofail(sizeof(struct snapraid_content)); + 34 1525 : pathimport(content->content, sizeof(content->content), path); + 35 1525 : content->device = dev; 36 : - 37 1523 : return content; + 37 1525 : return content; 38 : } 39 : 40 1386 : void content_free(struct snapraid_content* content) @@ -104,7 +104,7 @@ 42 1386 : free(content); 43 1386 : } 44 : - 45 532 : struct snapraid_filter* filter_alloc_file(int direction, const char* pattern) + 45 534 : struct snapraid_filter* filter_alloc_file(int direction, const char* pattern) 46 : { 47 : struct snapraid_filter* filter; 48 : char* i; @@ -113,18 +113,18 @@ 51 : int token_is_valid; 52 : int token_is_filled; 53 : - 54 532 : filter = malloc_nofail(sizeof(struct snapraid_filter)); - 55 532 : pathimport(filter->pattern, sizeof(filter->pattern), pattern); - 56 532 : filter->direction = direction; + 54 534 : filter = malloc_nofail(sizeof(struct snapraid_filter)); + 55 534 : pathimport(filter->pattern, sizeof(filter->pattern), pattern); + 56 534 : filter->direction = direction; 57 : 58 : /* find first and last slash */ - 59 532 : first = 0; - 60 532 : last = 0; + 59 534 : first = 0; + 60 534 : last = 0; 61 : /* reject invalid tokens, like "<empty>", ".", ".." and more dots */ - 62 532 : token_is_valid = 0; - 63 532 : token_is_filled = 0; - 64 6597 : for (i = filter->pattern; *i; ++i) { - 65 6066 : if (*i == '/') { + 62 534 : token_is_valid = 0; + 63 534 : token_is_filled = 0; + 64 6622 : for (i = filter->pattern; *i; ++i) { + 65 6089 : if (*i == '/') { 66 : /* reject invalid tokens, but accept an empty one as first */ 67 5 : if (!token_is_valid && (first != 0 || token_is_filled)) { 68 1 : free(filter); @@ -137,27 +137,27 @@ 75 4 : if (!first) 76 3 : first = i; 77 4 : last = i; - 78 6061 : } else if (*i != '.') { - 79 5533 : token_is_valid = 1; - 80 5533 : token_is_filled = 1; + 78 6084 : } else if (*i != '.') { + 79 5554 : token_is_valid = 1; + 80 5554 : token_is_filled = 1; 81 : } else { - 82 528 : token_is_filled = 1; + 82 530 : token_is_filled = 1; 83 : } 84 : } 85 : 86 : /* reject invalid tokens, but accept an empty one as last, but not if it's the only one */ - 87 531 : if (!token_is_valid && (first == 0 || token_is_filled)) { + 87 533 : if (!token_is_valid && (first == 0 || token_is_filled)) { 88 1 : free(filter); 89 1 : return 0; 90 : } 91 : 92 : /* it's a file filter */ - 93 530 : filter->is_disk = 0; + 93 532 : filter->is_disk = 0; 94 : - 95 530 : if (first == 0) { + 95 532 : if (first == 0) { 96 : /* no slash */ - 97 527 : filter->is_path = 0; - 98 527 : filter->is_dir = 0; + 97 529 : filter->is_path = 0; + 98 529 : filter->is_dir = 0; 99 3 : } else if (first == last && last[1] == 0) { 100 : /* one slash at the end */ 101 1 : filter->is_path = 0; @@ -180,7 +180,7 @@ 118 : } 119 : } 120 : - 121 529 : return filter; + 121 531 : return filter; 122 : } 123 : 124 10 : struct snapraid_filter* filter_alloc_disk(int direction, const char* pattern) @@ -212,96 +212,96 @@ 150 497 : free(filter); 151 497 : } 152 : - 153 125245 : const char* filter_type(struct snapraid_filter* filter, char* out, size_t out_size) + 153 125255 : const char* filter_type(struct snapraid_filter* filter, char* out, size_t out_size) 154 : { 155 : const char* direction; 156 : - 157 125245 : if (filter->direction < 0) - 158 124982 : direction = "exclude"; + 157 125255 : if (filter->direction < 0) + 158 124991 : direction = "exclude"; 159 : else - 160 263 : direction = "include"; + 160 264 : direction = "include"; 161 : - 162 125245 : if (filter->is_disk) + 162 125255 : if (filter->is_disk) 163 0 : pathprint(out, out_size, "%s %s:", direction, filter->pattern); - 164 125245 : else if (filter->is_dir) + 164 125255 : else if (filter->is_dir) 165 0 : pathprint(out, out_size, "%s %s/", direction, filter->pattern); 166 : else - 167 125245 : pathprint(out, out_size, "%s %s", direction, filter->pattern); + 167 125255 : pathprint(out, out_size, "%s %s", direction, filter->pattern); 168 : - 169 125245 : return out; + 169 125255 : return out; 170 : } 171 : - 172 12456124 : static int filter_apply(struct snapraid_filter* filter, struct snapraid_filter** reason, const char* path, const char* name, int is_dir) + 172 12456904 : static int filter_apply(struct snapraid_filter* filter, struct snapraid_filter** reason, const char* path, const char* name, int is_dir) 173 : { - 174 12456124 : int ret = 0; + 174 12456904 : int ret = 0; 175 : 176 : /* match dirs with dirs and files with files */ - 177 12456124 : if (filter->is_dir && !is_dir) + 177 12456904 : if (filter->is_dir && !is_dir) 178 2949 : return 0; - 179 12453175 : if (!filter->is_dir && is_dir) - 180 6223136 : return 0; + 179 12453955 : if (!filter->is_dir && is_dir) + 180 6223514 : return 0; 181 : - 182 6230039 : if (filter->is_path) { + 182 6230441 : if (filter->is_path) { 183 : /* skip initial slash, as always missing from the path */ 184 2949 : if (fnmatch(filter->pattern + 1, path, FNM_PATHNAME | FNM_CASEINSENSITIVE_FOR_WIN) == 0) 185 0 : ret = filter->direction; 186 : } else { - 187 6227090 : if (fnmatch(filter->pattern, name, FNM_CASEINSENSITIVE_FOR_WIN) == 0) - 188 127709 : ret = filter->direction; + 187 6227492 : if (fnmatch(filter->pattern, name, FNM_CASEINSENSITIVE_FOR_WIN) == 0) + 188 127717 : ret = filter->direction; 189 : } 190 : - 191 6230039 : if (reason != 0 && ret < 0) - 192 124719 : *reason = filter; + 191 6230441 : if (reason != 0 && ret < 0) + 192 124727 : *reason = filter; 193 : - 194 6230039 : return ret; + 194 6230441 : return ret; 195 : } 196 : - 197 6236157 : static int filter_recurse(struct snapraid_filter* filter, struct snapraid_filter** reason, const char* const_path, int is_dir) + 197 6236559 : static int filter_recurse(struct snapraid_filter* filter, struct snapraid_filter** reason, const char* const_path, int is_dir) 198 : { 199 : char path[PATH_MAX]; 200 : char* name; 201 : unsigned i; 202 : - 203 6236157 : pathcpy(path, sizeof(path), const_path); + 203 6236559 : pathcpy(path, sizeof(path), const_path); 204 : 205 : /* filter for all the directories */ - 206 6236157 : name = path; - 207 89818142 : for (i = 0; path[i] != 0; ++i) { - 208 83584975 : if (path[i] == '/') { + 206 6236559 : name = path; + 207 89823626 : for (i = 0; path[i] != 0; ++i) { + 208 83590057 : if (path[i] == '/') { 209 : /* set a terminator */ - 210 6222957 : path[i] = 0; + 210 6223335 : path[i] = 0; 211 : 212 : /* filter the directory */ - 213 6222957 : if (filter_apply(filter, reason, path, name, 1) != 0) + 213 6223335 : if (filter_apply(filter, reason, path, name, 1) != 0) 214 2990 : return filter->direction; 215 : 216 : /* restore the slash */ - 217 6219967 : path[i] = '/'; + 217 6220345 : path[i] = '/'; 218 : 219 : /* next name */ - 220 6219967 : name = path + i + 1; + 220 6220345 : name = path + i + 1; 221 : } 222 : } 223 : 224 : /* filter the final file */ - 225 6233167 : if (filter_apply(filter, reason, path, name, is_dir) != 0) - 226 124719 : return filter->direction; + 225 6233569 : if (filter_apply(filter, reason, path, name, is_dir) != 0) + 226 124727 : return filter->direction; 227 : - 228 6108448 : return 0; + 228 6108842 : return 0; 229 : } 230 : - 231 3332623 : static int filter_element(tommy_list* filterlist, struct snapraid_filter** reason, const char* disk, const char* sub, int is_dir, int is_def_include) + 231 3332824 : static int filter_element(tommy_list* filterlist, struct snapraid_filter** reason, const char* disk, const char* sub, int is_dir, int is_def_include) 232 : { 233 : tommy_node* i; 234 : - 235 3332623 : int direction = 1; /* by default include all */ + 235 3332824 : int direction = 1; /* by default include all */ 236 : 237 : /* for each filter */ - 238 9542379 : for (i = tommy_list_head(filterlist); i != 0; i = i->next) { + 238 9542974 : for (i = tommy_list_head(filterlist); i != 0; i = i->next) { 239 : int ret; - 240 6346145 : struct snapraid_filter* filter = i->data; + 240 6346547 : struct snapraid_filter* filter = i->data; 241 : - 242 6346145 : if (filter->is_disk) { + 242 6346547 : if (filter->is_disk) { 243 109988 : if (fnmatch(filter->pattern, disk, FNM_CASEINSENSITIVE_FOR_WIN) == 0) 244 8680 : ret = filter->direction; 245 : else @@ -309,39 +309,39 @@ 247 109988 : if (reason != 0 && ret < 0) 248 0 : *reason = filter; 249 : } else { - 250 6236157 : ret = filter_recurse(filter, reason, sub, is_dir); + 250 6236559 : ret = filter_recurse(filter, reason, sub, is_dir); 251 : } 252 : - 253 6346145 : if (ret > 0) { + 253 6346547 : if (ret > 0) { 254 : /* include the file */ 255 11670 : return 0; - 256 6334475 : } else if (ret < 0) { + 256 6334877 : } else if (ret < 0) { 257 : /* exclude the file */ - 258 124719 : return -1; + 258 124727 : return -1; 259 : } else { 260 : /* default is opposite of the last filter */ - 261 6209756 : direction = -filter->direction; - 262 6209756 : if (reason != 0 && direction < 0) - 263 3110665 : *reason = filter; + 261 6210150 : direction = -filter->direction; + 262 6210150 : if (reason != 0 && direction < 0) + 263 3110866 : *reason = filter; 264 : /* continue with the next one */ 265 : } 266 : } 267 : 268 : /* directories are always included by default, otherwise we cannot apply rules */ 269 : /* to the contained files */ - 270 3196234 : if (is_def_include) + 270 3196427 : if (is_def_include) 271 3052 : return 0; 272 : 273 : /* files are excluded/included depending of the last rule processed */ - 274 3193182 : if (direction < 0) + 274 3193375 : if (direction < 0) 275 57608 : return -1; 276 : - 277 3135574 : return 0; + 277 3135767 : return 0; 278 : } 279 : - 280 3329526 : int filter_path(tommy_list* filterlist, struct snapraid_filter** reason, const char* disk, const char* sub) + 280 3329727 : int filter_path(tommy_list* filterlist, struct snapraid_filter** reason, const char* disk, const char* sub) 281 : { - 282 3329526 : return filter_element(filterlist, reason, disk, sub, 0, 0); + 282 3329727 : return filter_element(filterlist, reason, disk, sub, 0, 0); 283 : } 284 : 285 3052 : int filter_subdir(tommy_list* filterlist, struct snapraid_filter** reason, const char* disk, const char* sub) @@ -387,103 +387,103 @@ 325 16098 : return 0; 326 : 327 : /* check each block of the file */ - 328 60655 : for (i = 0; i < file->blockmax; ++i) { - 329 46442 : block_off_t parity_pos = fs_file2par_get(disk, file, i); - 330 46442 : snapraid_info info = info_get(infoarr, parity_pos); + 328 60677 : for (i = 0; i < file->blockmax; ++i) { + 329 46455 : block_off_t parity_pos = fs_file2par_get(disk, file, i); + 330 46455 : snapraid_info info = info_get(infoarr, parity_pos); 331 : 332 : /* if the file has a bad block, don't exclude it */ - 333 46442 : if (info_get_bad(info)) - 334 8335 : return 0; + 333 46455 : if (info_get_bad(info)) + 334 8326 : return 0; 335 : } 336 : 337 : /* the file is correct, so we filter it out */ - 338 14213 : return 1; + 338 14222 : return 1; 339 : } 340 : - 341 3173124 : int filter_content(tommy_list* contentlist, const char* path) + 341 3173351 : int filter_content(tommy_list* contentlist, const char* path) 342 : { 343 : tommy_node* i; 344 : - 345 40911380 : for (i = tommy_list_head(contentlist); i != 0; i = i->next) { - 346 17282566 : struct snapraid_content* content = i->data; + 345 40912970 : for (i = tommy_list_head(contentlist); i != 0; i = i->next) { + 346 17283134 : struct snapraid_content* content = i->data; 347 : char tmp[PATH_MAX]; 348 : - 349 17282566 : if (pathcmp(content->content, path) == 0) + 349 17283134 : if (pathcmp(content->content, path) == 0) 350 0 : return -1; 351 : 352 : /* exclude also the ".tmp" copy used to save it */ - 353 17282566 : pathprint(tmp, sizeof(tmp), "%s.tmp", content->content); - 354 17282566 : if (pathcmp(tmp, path) == 0) + 353 17283134 : pathprint(tmp, sizeof(tmp), "%s.tmp", content->content); + 354 17283134 : if (pathcmp(tmp, path) == 0) 355 0 : return -1; 356 : 357 : /* exclude also the ".lock" file */ - 358 17282566 : pathprint(tmp, sizeof(tmp), "%s.lock", content->content); - 359 17282566 : if (pathcmp(tmp, path) == 0) + 358 17283134 : pathprint(tmp, sizeof(tmp), "%s.lock", content->content); + 359 17283134 : if (pathcmp(tmp, path) == 0) 360 0 : return -1; 361 : } 362 : - 363 3173124 : return 0; + 363 3173351 : return 0; 364 : } 365 : - 366 3691209 : struct snapraid_file* file_alloc(unsigned block_size, const char* sub, data_off_t size, uint64_t mtime_sec, int mtime_nsec, uint64_t inode, uint64_t physical) + 366 3691126 : struct snapraid_file* file_alloc(unsigned block_size, const char* sub, data_off_t size, uint64_t mtime_sec, int mtime_nsec, uint64_t inode, uint64_t physical) 367 : { 368 : struct snapraid_file* file; 369 : block_off_t i; 370 : - 371 3691209 : file = malloc_nofail(sizeof(struct snapraid_file)); - 372 3691209 : file->sub = strdup_nofail(sub); - 373 3691209 : file->size = size; - 374 3691209 : file->blockmax = (size + block_size - 1) / block_size; - 375 3691209 : file->mtime_sec = mtime_sec; - 376 3691209 : file->mtime_nsec = mtime_nsec; - 377 3691209 : file->inode = inode; - 378 3691209 : file->physical = physical; - 379 3691209 : file->flag = 0; - 380 3691209 : file->blockvec = malloc_nofail(file->blockmax * block_sizeof()); + 371 3691126 : file = malloc_nofail(sizeof(struct snapraid_file)); + 372 3691126 : file->sub = strdup_nofail(sub); + 373 3691126 : file->size = size; + 374 3691126 : file->blockmax = (size + block_size - 1) / block_size; + 375 3691126 : file->mtime_sec = mtime_sec; + 376 3691126 : file->mtime_nsec = mtime_nsec; + 377 3691126 : file->inode = inode; + 378 3691126 : file->physical = physical; + 379 3691126 : file->flag = 0; + 380 3691126 : file->blockvec = malloc_nofail(file->blockmax * block_sizeof()); 381 : - 382 12810920 : for (i = 0; i < file->blockmax; ++i) { - 383 9119711 : struct snapraid_block* block = file_block(file, i); - 384 9119711 : block_state_set(block, BLOCK_STATE_CHG); - 385 9119711 : hash_invalid_set(block->hash); + 382 12810682 : for (i = 0; i < file->blockmax; ++i) { + 383 9119556 : struct snapraid_block* block = file_block(file, i); + 384 9119556 : block_state_set(block, BLOCK_STATE_CHG); + 385 9119556 : hash_invalid_set(block->hash); 386 : } 387 : - 388 3691209 : return file; + 388 3691126 : return file; 389 : } 390 : - 391 22680 : struct snapraid_file* file_dup(struct snapraid_file* copy) + 391 22687 : struct snapraid_file* file_dup(struct snapraid_file* copy) 392 : { 393 : struct snapraid_file* file; 394 : block_off_t i; 395 : - 396 22680 : file = malloc_nofail(sizeof(struct snapraid_file)); - 397 22680 : file->sub = strdup_nofail(copy->sub); - 398 22680 : file->size = copy->size; - 399 22680 : file->blockmax = copy->blockmax; - 400 22680 : file->mtime_sec = copy->mtime_sec; - 401 22680 : file->mtime_nsec = copy->mtime_nsec; - 402 22680 : file->inode = copy->inode; - 403 22680 : file->physical = copy->physical; - 404 22680 : file->flag = copy->flag; - 405 22680 : file->blockvec = malloc_nofail(file->blockmax * block_sizeof()); + 396 22687 : file = malloc_nofail(sizeof(struct snapraid_file)); + 397 22687 : file->sub = strdup_nofail(copy->sub); + 398 22687 : file->size = copy->size; + 399 22687 : file->blockmax = copy->blockmax; + 400 22687 : file->mtime_sec = copy->mtime_sec; + 401 22687 : file->mtime_nsec = copy->mtime_nsec; + 402 22687 : file->inode = copy->inode; + 403 22687 : file->physical = copy->physical; + 404 22687 : file->flag = copy->flag; + 405 22687 : file->blockvec = malloc_nofail(file->blockmax * block_sizeof()); 406 : - 407 78592 : for (i = 0; i < file->blockmax; ++i) { - 408 55912 : struct snapraid_block* block = file_block(file, i); - 409 55912 : struct snapraid_block* copy_block = file_block(copy, i); - 410 55912 : block->state = copy_block->state; - 411 55912 : memcpy(block->hash, copy_block->hash, BLOCK_HASH_SIZE); + 407 78655 : for (i = 0; i < file->blockmax; ++i) { + 408 55968 : struct snapraid_block* block = file_block(file, i); + 409 55968 : struct snapraid_block* copy_block = file_block(copy, i); + 410 55968 : block->state = copy_block->state; + 411 55968 : memcpy(block->hash, copy_block->hash, BLOCK_HASH_SIZE); 412 : } 413 : - 414 22680 : return file; + 414 22687 : return file; 415 : } 416 : - 417 3543765 : void file_free(struct snapraid_file* file) + 417 3543814 : void file_free(struct snapraid_file* file) 418 : { - 419 3543765 : free(file->sub); - 420 3543765 : file->sub = 0; - 421 3543765 : free(file->blockvec); - 422 3543765 : file->blockvec = 0; - 423 3543765 : free(file); - 424 3543765 : } + 419 3543814 : free(file->sub); + 420 3543814 : file->sub = 0; + 421 3543814 : free(file->blockvec); + 422 3543814 : file->blockvec = 0; + 423 3543814 : free(file); + 424 3543814 : } 425 : 426 155 : void file_rename(struct snapraid_file* file, const char* sub) 427 : { @@ -527,31 +527,31 @@ 465 23636 : file_flag_set(dst_file, FILE_IS_COPY); 466 23636 : } 467 : - 468 47954 : const char* file_name(const struct snapraid_file* file) + 468 47922 : const char* file_name(const struct snapraid_file* file) 469 : { - 470 47954 : const char* r = strrchr(file->sub, '/'); + 470 47922 : const char* r = strrchr(file->sub, '/'); 471 : - 472 47954 : if (!r) + 472 47922 : if (!r) 473 78 : r = file->sub; 474 : else - 475 47876 : ++r; - 476 47954 : return r; + 475 47844 : ++r; + 476 47922 : return r; 477 : } 478 : - 479 6823060 : unsigned file_block_size(struct snapraid_file* file, block_off_t file_pos, unsigned block_size) + 479 6823791 : unsigned file_block_size(struct snapraid_file* file, block_off_t file_pos, unsigned block_size) 480 : { 481 : /* if it's the last block */ - 482 6823060 : if (file_pos + 1 == file->blockmax) { + 482 6823791 : if (file_pos + 1 == file->blockmax) { 483 : unsigned block_remainder; - 484 2775047 : if (file->size == 0) + 484 2775528 : if (file->size == 0) 485 0 : return 0; - 486 2775047 : block_remainder = file->size % block_size; - 487 2775047 : if (block_remainder == 0) - 488 3052 : block_remainder = block_size; - 489 2775047 : return block_remainder; + 486 2775528 : block_remainder = file->size % block_size; + 487 2775528 : if (block_remainder == 0) + 488 3039 : block_remainder = block_size; + 489 2775528 : return block_remainder; 490 : } 491 : - 492 4048013 : return block_size; + 492 4048263 : return block_size; 493 : } 494 : 495 5329167 : int file_block_is_last(struct snapraid_file* file, block_off_t file_pos) @@ -569,16 +569,16 @@ 507 5329167 : return file_pos == file->blockmax - 1; 508 : } 509 : - 510 987050 : int file_inode_compare_to_arg(const void* void_arg, const void* void_data) + 510 987099 : int file_inode_compare_to_arg(const void* void_arg, const void* void_data) 511 : { - 512 987050 : const uint64_t* arg = void_arg; - 513 987050 : const struct snapraid_file* file = void_data; + 512 987099 : const uint64_t* arg = void_arg; + 513 987099 : const struct snapraid_file* file = void_data; 514 : - 515 987050 : if (*arg < file->inode) + 515 987099 : if (*arg < file->inode) 516 0 : return -1; - 517 987050 : if (*arg > file->inode) + 517 987099 : if (*arg > file->inode) 518 0 : return 1; - 519 987050 : return 0; + 519 987099 : return 0; 520 : } 521 : 522 0 : int file_inode_compare(const void* void_a, const void* void_b) @@ -593,42 +593,42 @@ 531 0 : return 0; 532 : } 533 : - 534 189434 : int file_path_compare(const void* void_a, const void* void_b) + 534 189486 : int file_path_compare(const void* void_a, const void* void_b) 535 : { - 536 189434 : const struct snapraid_file* file_a = void_a; - 537 189434 : const struct snapraid_file* file_b = void_b; + 536 189486 : const struct snapraid_file* file_a = void_a; + 537 189486 : const struct snapraid_file* file_b = void_b; 538 : - 539 189434 : return strcmp(file_a->sub, file_b->sub); + 539 189486 : return strcmp(file_a->sub, file_b->sub); 540 : } 541 : - 542 63430 : int file_physical_compare(const void* void_a, const void* void_b) + 542 44202 : int file_physical_compare(const void* void_a, const void* void_b) 543 : { - 544 63430 : const struct snapraid_file* file_a = void_a; - 545 63430 : const struct snapraid_file* file_b = void_b; + 544 44202 : const struct snapraid_file* file_a = void_a; + 545 44202 : const struct snapraid_file* file_b = void_b; 546 : - 547 63430 : if (file_a->physical < file_b->physical) - 548 38882 : return -1; - 549 24548 : if (file_a->physical > file_b->physical) - 550 24546 : return 1; + 547 44202 : if (file_a->physical < file_b->physical) + 548 30758 : return -1; + 549 13444 : if (file_a->physical > file_b->physical) + 550 13442 : return 1; 551 2 : return 0; 552 : } 553 : - 554 97552 : int file_path_compare_to_arg(const void* void_arg, const void* void_data) + 554 97531 : int file_path_compare_to_arg(const void* void_arg, const void* void_data) 555 : { - 556 97552 : const char* arg = void_arg; - 557 97552 : const struct snapraid_file* file = void_data; + 556 97531 : const char* arg = void_arg; + 557 97531 : const struct snapraid_file* file = void_data; 558 : - 559 97552 : return strcmp(arg, file->sub); + 559 97531 : return strcmp(arg, file->sub); 560 : } 561 : - 562 23977 : int file_name_compare(const void* void_a, const void* void_b) + 562 23961 : int file_name_compare(const void* void_a, const void* void_b) 563 : { - 564 23977 : const struct snapraid_file* file_a = void_a; - 565 23977 : const struct snapraid_file* file_b = void_b; - 566 23977 : const char* name_a = file_name(file_a); - 567 23977 : const char* name_b = file_name(file_b); + 564 23961 : const struct snapraid_file* file_a = void_a; + 565 23961 : const struct snapraid_file* file_b = void_b; + 566 23961 : const char* name_a = file_name(file_a); + 567 23961 : const char* name_b = file_name(file_b); 568 : - 569 23977 : return strcmp(name_a, name_b); + 569 23961 : return strcmp(name_a, name_b); 570 : } 571 : 572 23670 : int file_stamp_compare(const void* void_a, const void* void_b) @@ -654,13 +654,13 @@ 592 23670 : return 0; 593 : } 594 : - 595 23977 : int file_namestamp_compare(const void* void_a, const void* void_b) + 595 23961 : int file_namestamp_compare(const void* void_a, const void* void_b) 596 : { 597 : int ret; 598 : - 599 23977 : ret = file_name_compare(void_a, void_b); - 600 23977 : if (ret != 0) - 601 307 : return ret; + 599 23961 : ret = file_name_compare(void_a, void_b); + 600 23961 : if (ret != 0) + 601 291 : return ret; 602 : 603 23670 : return file_stamp_compare(void_a, void_b); 604 : } @@ -676,66 +676,66 @@ 614 0 : return file_stamp_compare(void_a, void_b); 615 : } 616 : - 617 3735492 : struct snapraid_extent* extent_alloc(block_off_t parity_pos, struct snapraid_file* file, block_off_t file_pos, block_off_t count) + 617 3735396 : struct snapraid_extent* extent_alloc(block_off_t parity_pos, struct snapraid_file* file, block_off_t file_pos, block_off_t count) 618 : { 619 : struct snapraid_extent* extent; 620 : - 621 3735492 : if (count == 0) { + 621 3735396 : if (count == 0) { 622 : /* LCOV_EXCL_START */ 623 : log_fatal("Internal inconsistency when allocating empty extent for file '%s' at position '%u/%u'\n", file->sub, file_pos, file->blockmax); 624 : os_abort(); 625 : /* LCOV_EXCL_STOP */ 626 : } - 627 3735492 : if (file_pos + count > file->blockmax) { + 627 3735396 : if (file_pos + count > file->blockmax) { 628 : /* LCOV_EXCL_START */ 629 : log_fatal("Internal inconsistency when allocating overflowing extent for file '%s' at position '%u:%u/%u'\n", file->sub, file_pos, count, file->blockmax); 630 : os_abort(); 631 : /* LCOV_EXCL_STOP */ 632 : } 633 : - 634 3735492 : extent = malloc_nofail(sizeof(struct snapraid_extent)); - 635 3735492 : extent->parity_pos = parity_pos; - 636 3735492 : extent->file = file; - 637 3735492 : extent->file_pos = file_pos; - 638 3735492 : extent->count = count; + 634 3735396 : extent = malloc_nofail(sizeof(struct snapraid_extent)); + 635 3735396 : extent->parity_pos = parity_pos; + 636 3735396 : extent->file = file; + 637 3735396 : extent->file_pos = file_pos; + 638 3735396 : extent->count = count; 639 : - 640 3735492 : return extent; + 640 3735396 : return extent; 641 : } 642 : - 643 3564805 : void extent_free(struct snapraid_extent* extent) + 643 3564840 : void extent_free(struct snapraid_extent* extent) 644 : { - 645 3564805 : free(extent); - 646 3564805 : } + 645 3564840 : free(extent); + 646 3564840 : } 647 : - 648 44511012 : int extent_parity_compare(const void* void_a, const void* void_b) + 648 44510782 : int extent_parity_compare(const void* void_a, const void* void_b) 649 : { - 650 44511012 : const struct snapraid_extent* arg_a = void_a; - 651 44511012 : const struct snapraid_extent* arg_b = void_b; + 650 44510782 : const struct snapraid_extent* arg_a = void_a; + 651 44510782 : const struct snapraid_extent* arg_b = void_b; 652 : - 653 44511012 : if (arg_a->parity_pos < arg_b->parity_pos) - 654 959727 : return -1; - 655 43551285 : if (arg_a->parity_pos > arg_b->parity_pos) - 656 43511675 : return 1; + 653 44510782 : if (arg_a->parity_pos < arg_b->parity_pos) + 654 960328 : return -1; + 655 43550454 : if (arg_a->parity_pos > arg_b->parity_pos) + 656 43510787 : return 1; 657 : - 658 39610 : return 0; + 658 39667 : return 0; 659 : } 660 : - 661 45007856 : int extent_file_compare(const void* void_a, const void* void_b) + 661 45007274 : int extent_file_compare(const void* void_a, const void* void_b) 662 : { - 663 45007856 : const struct snapraid_extent* arg_a = void_a; - 664 45007856 : const struct snapraid_extent* arg_b = void_b; + 663 45007274 : const struct snapraid_extent* arg_a = void_a; + 664 45007274 : const struct snapraid_extent* arg_b = void_b; 665 : - 666 45007856 : if (arg_a->file < arg_b->file) - 667 879576 : return -1; - 668 44128280 : if (arg_a->file > arg_b->file) - 669 44057503 : return 1; + 666 45007274 : if (arg_a->file < arg_b->file) + 667 874179 : return -1; + 668 44133095 : if (arg_a->file > arg_b->file) + 669 44062303 : return 1; 670 : - 671 70777 : if (arg_a->file_pos < arg_b->file_pos) + 671 70792 : if (arg_a->file_pos < arg_b->file_pos) 672 208 : return -1; - 673 70569 : if (arg_a->file_pos > arg_b->file_pos) - 674 30959 : return 1; + 673 70584 : if (arg_a->file_pos > arg_b->file_pos) + 674 30917 : return 1; 675 : - 676 39610 : return 0; + 676 39667 : return 0; 677 : } 678 : 679 119522 : struct snapraid_link* link_alloc(const char* sub, const char* linkto, unsigned link_flag) @@ -798,50 +798,50 @@ 736 249 : return strcmp(arg, dir->sub); 737 : } 738 : - 739 1579 : struct snapraid_disk* disk_alloc(const char* name, const char* dir, uint64_t dev, const char* uuid, int skip) + 739 1585 : struct snapraid_disk* disk_alloc(const char* name, const char* dir, uint64_t dev, const char* uuid, int skip) 740 : { 741 : struct snapraid_disk* disk; 742 : - 743 1579 : disk = malloc_nofail(sizeof(struct snapraid_disk)); - 744 1579 : pathcpy(disk->name, sizeof(disk->name), name); - 745 1579 : pathimport(disk->dir, sizeof(disk->dir), dir); - 746 1579 : pathcpy(disk->uuid, sizeof(disk->uuid), uuid); + 743 1585 : disk = malloc_nofail(sizeof(struct snapraid_disk)); + 744 1585 : pathcpy(disk->name, sizeof(disk->name), name); + 745 1585 : pathimport(disk->dir, sizeof(disk->dir), dir); + 746 1585 : pathcpy(disk->uuid, sizeof(disk->uuid), uuid); 747 : 748 : /* ensure that the dir terminate with "/" if it isn't empty */ - 749 1579 : pathslash(disk->dir, sizeof(disk->dir)); + 749 1585 : pathslash(disk->dir, sizeof(disk->dir)); 750 : 751 : #if HAVE_PTHREAD - 752 1579 : thread_mutex_init(&disk->fs_mutex, 0); + 752 1585 : thread_mutex_init(&disk->fs_mutex, 0); 753 : #endif 754 : - 755 1579 : disk->smartctl[0] = 0; - 756 1579 : disk->device = dev; - 757 1579 : disk->tick = 0; - 758 1579 : disk->cached = 0; - 759 1579 : disk->total_blocks = 0; - 760 1579 : disk->free_blocks = 0; - 761 1579 : disk->first_free_block = 0; - 762 1579 : disk->has_volatile_inodes = 0; - 763 1579 : disk->has_unreliable_physical = 0; - 764 1579 : disk->has_different_uuid = 0; - 765 1579 : disk->has_unsupported_uuid = *uuid == 0; /* empty UUID means unsupported */ - 766 1579 : disk->had_empty_uuid = 0; - 767 1579 : disk->mapping_idx = -1; - 768 1579 : disk->skip_access = skip; - 769 1579 : tommy_list_init(&disk->filelist); - 770 1579 : tommy_list_init(&disk->deletedlist); - 771 1579 : tommy_hashdyn_init(&disk->inodeset); - 772 1579 : tommy_hashdyn_init(&disk->pathset); - 773 1579 : tommy_hashdyn_init(&disk->stampset); - 774 1579 : tommy_list_init(&disk->linklist); - 775 1579 : tommy_hashdyn_init(&disk->linkset); - 776 1579 : tommy_list_init(&disk->dirlist); - 777 1579 : tommy_hashdyn_init(&disk->dirset); - 778 1579 : tommy_tree_init(&disk->fs_parity, extent_parity_compare); - 779 1579 : tommy_tree_init(&disk->fs_file, extent_file_compare); - 780 1579 : disk->fs_last = 0; + 755 1585 : disk->smartctl[0] = 0; + 756 1585 : disk->device = dev; + 757 1585 : disk->tick = 0; + 758 1585 : disk->cached = 0; + 759 1585 : disk->total_blocks = 0; + 760 1585 : disk->free_blocks = 0; + 761 1585 : disk->first_free_block = 0; + 762 1585 : disk->has_volatile_inodes = 0; + 763 1585 : disk->has_unreliable_physical = 0; + 764 1585 : disk->has_different_uuid = 0; + 765 1585 : disk->has_unsupported_uuid = *uuid == 0; /* empty UUID means unsupported */ + 766 1585 : disk->had_empty_uuid = 0; + 767 1585 : disk->mapping_idx = -1; + 768 1585 : disk->skip_access = skip; + 769 1585 : tommy_list_init(&disk->filelist); + 770 1585 : tommy_list_init(&disk->deletedlist); + 771 1585 : tommy_hashdyn_init(&disk->inodeset); + 772 1585 : tommy_hashdyn_init(&disk->pathset); + 773 1585 : tommy_hashdyn_init(&disk->stampset); + 774 1585 : tommy_list_init(&disk->linklist); + 775 1585 : tommy_hashdyn_init(&disk->linkset); + 776 1585 : tommy_list_init(&disk->dirlist); + 777 1585 : tommy_hashdyn_init(&disk->dirset); + 778 1585 : tommy_tree_init(&disk->fs_parity, extent_parity_compare); + 779 1585 : tommy_tree_init(&disk->fs_file, extent_file_compare); + 780 1585 : disk->fs_last = 0; 781 : - 782 1579 : return disk; + 782 1585 : return disk; 783 : } 784 : 785 1453 : void disk_free(struct snapraid_disk* disk) @@ -864,23 +864,23 @@ 802 1453 : free(disk); 803 1453 : } 804 : - 805 53194369 : static inline void fs_lock(struct snapraid_disk* disk) + 805 53196480 : static inline void fs_lock(struct snapraid_disk* disk) 806 : { 807 : #if HAVE_PTHREAD - 808 53194369 : thread_mutex_lock(&disk->fs_mutex); + 808 53196480 : thread_mutex_lock(&disk->fs_mutex); 809 : #else 810 : (void)disk; 811 : #endif - 812 53194899 : } + 812 53197205 : } 813 : - 814 53193869 : static inline void fs_unlock(struct snapraid_disk* disk) + 814 53196096 : static inline void fs_unlock(struct snapraid_disk* disk) 815 : { 816 : #if HAVE_PTHREAD - 817 53193869 : thread_mutex_unlock(&disk->fs_mutex); + 817 53196096 : thread_mutex_unlock(&disk->fs_mutex); 818 : #else 819 : (void)disk; 820 : #endif - 821 53194703 : } + 821 53197239 : } 822 : 823 : struct extent_disk_empty { 824 : block_off_t blockmax; @@ -937,30 +937,30 @@ 875 : * 876 : * The maximum parity position is stored as size. 877 : */ - 878 50483 : static int extent_disk_size_compare_unlock(const void* void_a, const void* void_b) + 878 50510 : static int extent_disk_size_compare_unlock(const void* void_a, const void* void_b) 879 : { - 880 50483 : struct extent_disk_size* arg_a = (void*)void_a; - 881 50483 : const struct snapraid_extent* arg_b = void_b; + 880 50510 : struct extent_disk_size* arg_a = (void*)void_a; + 881 50510 : const struct snapraid_extent* arg_b = void_b; 882 : 883 : /* get the maximum size */ - 884 50483 : if (arg_a->size < arg_b->parity_pos + arg_b->count) - 885 50483 : arg_a->size = arg_b->parity_pos + arg_b->count; + 884 50510 : if (arg_a->size < arg_b->parity_pos + arg_b->count) + 885 50510 : arg_a->size = arg_b->parity_pos + arg_b->count; 886 : 887 : /* search always for a bigger one */ - 888 50483 : return 1; + 888 50510 : return 1; 889 : } 890 : - 891 4339 : block_off_t fs_size(struct snapraid_disk* disk) + 891 4351 : block_off_t fs_size(struct snapraid_disk* disk) 892 : { - 893 4339 : struct extent_disk_size arg = { 0 }; + 893 4351 : struct extent_disk_size arg = { 0 }; 894 : - 895 4339 : fs_lock(disk); + 895 4351 : fs_lock(disk); 896 : - 897 4339 : tommy_tree_search_compare(&disk->fs_parity, extent_disk_size_compare_unlock, &arg); + 897 4351 : tommy_tree_search_compare(&disk->fs_parity, extent_disk_size_compare_unlock, &arg); 898 : - 899 4339 : fs_unlock(disk); + 899 4351 : fs_unlock(disk); 900 : - 901 4339 : return arg.size; + 901 4351 : return arg.size; 902 : } 903 : 904 : struct extent_check { @@ -968,23 +968,23 @@ 906 : int result; 907 : }; 908 : - 909 6584437 : static void extent_parity_check_foreach_unlock(void* void_arg, void* void_obj) + 909 6584417 : static void extent_parity_check_foreach_unlock(void* void_arg, void* void_obj) 910 : { - 911 6584437 : struct extent_check* arg = void_arg; - 912 6584437 : const struct snapraid_extent* obj = void_obj; - 913 6584437 : const struct snapraid_extent* prev = arg->prev; + 911 6584417 : struct extent_check* arg = void_arg; + 912 6584417 : const struct snapraid_extent* obj = void_obj; + 913 6584417 : const struct snapraid_extent* prev = arg->prev; 914 : 915 : /* set the next previous block */ - 916 6584437 : arg->prev = obj; + 916 6584417 : arg->prev = obj; 917 : 918 : /* stop reporting if too many errors */ - 919 6584437 : if (arg->result > 100) { + 919 6584417 : if (arg->result > 100) { 920 : /* LCOV_EXCL_START */ 921 : return; 922 : /* LCOV_EXCL_STOP */ 923 : } 924 : - 925 6584437 : if (obj->count == 0) { + 925 6584417 : if (obj->count == 0) { 926 : /* LCOV_EXCL_START */ 927 : log_fatal("Internal inconsistency in parity count zero for file '%s' at '%u'\n", 928 : obj->file->sub, obj->parity_pos); @@ -994,11 +994,11 @@ 932 : } 933 : 934 : /* check only if there is a previous block */ - 935 6584437 : if (!prev) - 936 2708 : return; + 935 6584417 : if (!prev) + 936 2718 : return; 937 : 938 : /* check the order */ - 939 6581729 : if (prev->parity_pos >= obj->parity_pos) { + 939 6581699 : if (prev->parity_pos >= obj->parity_pos) { 940 : /* LCOV_EXCL_START */ 941 : log_fatal("Internal inconsistency in parity order for files '%s' at '%u:%u' and '%s' at '%u:%u'\n", 942 : prev->file->sub, prev->parity_pos, prev->count, obj->file->sub, obj->parity_pos, obj->count); @@ -1008,7 +1008,7 @@ 946 : } 947 : 948 : /* check that the extents don't overlap */ - 949 6581729 : if (prev->parity_pos + prev->count > obj->parity_pos) { + 949 6581699 : if (prev->parity_pos + prev->count > obj->parity_pos) { 950 : /* LCOV_EXCL_START */ 951 : log_fatal("Internal inconsistency for parity overlap for files '%s' at '%u:%u' and '%s' at '%u:%u'\n", 952 : prev->file->sub, prev->parity_pos, prev->count, obj->file->sub, obj->parity_pos, obj->count); @@ -1018,23 +1018,23 @@ 956 : } 957 : } 958 : - 959 6584437 : static void extent_file_check_foreach_unlock(void* void_arg, void* void_obj) + 959 6584417 : static void extent_file_check_foreach_unlock(void* void_arg, void* void_obj) 960 : { - 961 6584437 : struct extent_check* arg = void_arg; - 962 6584437 : const struct snapraid_extent* obj = void_obj; - 963 6584437 : const struct snapraid_extent* prev = arg->prev; + 961 6584417 : struct extent_check* arg = void_arg; + 962 6584417 : const struct snapraid_extent* obj = void_obj; + 963 6584417 : const struct snapraid_extent* prev = arg->prev; 964 : 965 : /* set the next previous block */ - 966 6584437 : arg->prev = obj; + 966 6584417 : arg->prev = obj; 967 : 968 : /* stop reporting if too many errors */ - 969 6584437 : if (arg->result > 100) { + 969 6584417 : if (arg->result > 100) { 970 : /* LCOV_EXCL_START */ 971 : return; 972 : /* LCOV_EXCL_STOP */ 973 : } 974 : - 975 6584437 : if (obj->count == 0) { + 975 6584417 : if (obj->count == 0) { 976 : /* LCOV_EXCL_START */ 977 : log_fatal("Internal inconsistency in file count zero for file '%s' at '%u'\n", 978 : obj->file->sub, obj->file_pos); @@ -1046,9 +1046,9 @@ 984 : /* note that for deleted files, some extents may be missing */ 985 : 986 : /* if the files are different */ - 987 6584437 : if (!prev || prev->file != obj->file) { - 988 6538233 : if (prev != 0) { - 989 6535525 : if (file_flag_has(prev->file, FILE_IS_DELETED)) { + 987 6584417 : if (!prev || prev->file != obj->file) { + 988 6538257 : if (prev != 0) { + 989 6535539 : if (file_flag_has(prev->file, FILE_IS_DELETED)) { 990 : /* check that the extent doesn't overflow the file */ 991 59759 : if (prev->file_pos + prev->count > prev->file->blockmax) { 992 : /* LCOV_EXCL_START */ @@ -1060,7 +1060,7 @@ 998 : } 999 : } else { 1000 : /* check that the extent ends the file */ - 1001 6475766 : if (prev->file_pos + prev->count != prev->file->blockmax) { + 1001 6475780 : if (prev->file_pos + prev->count != prev->file->blockmax) { 1002 : /* LCOV_EXCL_START */ 1003 : log_fatal("Internal inconsistency in file end for file '%s' at '%u:%u' instead of size '%u'\n", 1004 : prev->file->sub, prev->file_pos, prev->count, prev->file->blockmax); @@ -1071,7 +1071,7 @@ 1009 : } 1010 : } 1011 : - 1012 13076466 : if (file_flag_has(obj->file, FILE_IS_DELETED)) { + 1012 13076514 : if (file_flag_has(obj->file, FILE_IS_DELETED)) { 1013 : /* check that the extent doesn't overflow the file */ 1014 59842 : if (obj->file_pos + obj->count > obj->file->blockmax) { 1015 : /* LCOV_EXCL_START */ @@ -1083,7 +1083,7 @@ 1021 : } 1022 : } else { 1023 : /* check that the extent starts the file */ - 1024 6478391 : if (obj->file_pos != 0) { + 1024 6478415 : if (obj->file_pos != 0) { 1025 : /* LCOV_EXCL_START */ 1026 : log_fatal("Internal inconsistency in file start for file '%s' at '%u:%u'\n", 1027 : obj->file->sub, obj->file_pos, obj->count); @@ -1094,7 +1094,7 @@ 1032 : } 1033 : } else { 1034 : /* check the order */ - 1035 46204 : if (prev->file_pos >= obj->file_pos) { + 1035 46160 : if (prev->file_pos >= obj->file_pos) { 1036 : /* LCOV_EXCL_START */ 1037 : log_fatal("Internal inconsistency in file order for file '%s' at '%u:%u' and at '%u:%u'\n", 1038 : prev->file->sub, prev->file_pos, prev->count, obj->file_pos, obj->count); @@ -1103,7 +1103,7 @@ 1041 : /* LCOV_EXCL_STOP */ 1042 : } 1043 : - 1044 46204 : if (file_flag_has(obj->file, FILE_IS_DELETED)) { + 1044 46160 : if (file_flag_has(obj->file, FILE_IS_DELETED)) { 1045 : /* check that the extents don't overlap */ 1046 27 : if (prev->file_pos + prev->count > obj->file_pos) { 1047 : /* LCOV_EXCL_START */ @@ -1115,7 +1115,7 @@ 1053 : } 1054 : } else { 1055 : /* check that the extents are sequential */ - 1056 46177 : if (prev->file_pos + prev->count != obj->file_pos) { + 1056 46133 : if (prev->file_pos + prev->count != obj->file_pos) { 1057 : /* LCOV_EXCL_START */ 1058 : log_fatal("Internal inconsistency in file sequence for file '%s' at '%u:%u' and at '%u:%u'\n", 1059 : prev->file->sub, prev->file_pos, prev->count, obj->file_pos, obj->count); @@ -1127,29 +1127,29 @@ 1065 : } 1066 : } 1067 : - 1068 2970 : int fs_check(struct snapraid_disk* disk) + 1068 2982 : int fs_check(struct snapraid_disk* disk) 1069 : { 1070 : struct extent_check arg; 1071 : 1072 : /* error count starts from 0 */ - 1073 2970 : arg.result = 0; + 1073 2982 : arg.result = 0; 1074 : - 1075 2970 : fs_lock(disk); + 1075 2982 : fs_lock(disk); 1076 : 1077 : /* check parity sequence */ - 1078 2970 : arg.prev = 0; - 1079 2970 : tommy_tree_foreach_arg(&disk->fs_parity, extent_parity_check_foreach_unlock, &arg); + 1078 2982 : arg.prev = 0; + 1079 2982 : tommy_tree_foreach_arg(&disk->fs_parity, extent_parity_check_foreach_unlock, &arg); 1080 : 1081 : /* check file sequence */ - 1082 2970 : arg.prev = 0; - 1083 2970 : tommy_tree_foreach_arg(&disk->fs_file, extent_file_check_foreach_unlock, &arg); + 1082 2982 : arg.prev = 0; + 1083 2982 : tommy_tree_foreach_arg(&disk->fs_file, extent_file_check_foreach_unlock, &arg); 1084 : - 1085 2970 : fs_unlock(disk); + 1085 2982 : fs_unlock(disk); 1086 : - 1087 2970 : if (arg.result != 0) + 1087 2982 : if (arg.result != 0) 1088 0 : return -1; 1089 : - 1090 2970 : return 0; + 1090 2982 : return 0; 1091 : } 1092 : 1093 : struct extent_parity_inside { @@ -1159,17 +1159,17 @@ 1097 : /** 1098 : * Compare the extent if containing the specified parity position. 1099 : */ - 1100 113816358 : static int extent_parity_inside_compare_unlock(const void* void_a, const void* void_b) + 1100 113835807 : static int extent_parity_inside_compare_unlock(const void* void_a, const void* void_b) 1101 : { - 1102 113816358 : const struct extent_parity_inside* arg_a = void_a; - 1103 113816358 : const struct snapraid_extent* arg_b = void_b; + 1102 113835807 : const struct extent_parity_inside* arg_a = void_a; + 1103 113835807 : const struct snapraid_extent* arg_b = void_b; 1104 : - 1105 113816358 : if (arg_a->parity_pos < arg_b->parity_pos) - 1106 40236710 : return -1; - 1107 73579648 : if (arg_a->parity_pos >= arg_b->parity_pos + arg_b->count) - 1108 64869306 : return 1; + 1105 113835807 : if (arg_a->parity_pos < arg_b->parity_pos) + 1106 40242517 : return -1; + 1107 73593290 : if (arg_a->parity_pos >= arg_b->parity_pos + arg_b->count) + 1108 64881921 : return 1; 1109 : - 1110 8710342 : return 0; + 1110 8711369 : return 0; 1111 : } 1112 : 1113 : /** @@ -1177,28 +1177,28 @@ 1115 : * The search is optimized for sequential accesses. 1116 : * \return If not found return 0 1117 : */ - 1118 39142093 : static struct snapraid_extent* fs_par2extent_get_unlock(struct snapraid_disk* disk, struct snapraid_extent** fs_last, block_off_t parity_pos) + 1118 39144459 : static struct snapraid_extent* fs_par2extent_get_unlock(struct snapraid_disk* disk, struct snapraid_extent** fs_last, block_off_t parity_pos) 1119 : { 1120 : struct snapraid_extent* extent; 1121 : 1122 : /* check if the last accessed extent matches */ - 1123 39142093 : if (*fs_last - 1124 39123712 : && parity_pos >= (*fs_last)->parity_pos - 1125 38405576 : && parity_pos < (*fs_last)->parity_pos + (*fs_last)->count + 1123 39144459 : if (*fs_last + 1124 39126053 : && parity_pos >= (*fs_last)->parity_pos + 1125 38409539 : && parity_pos < (*fs_last)->parity_pos + (*fs_last)->count 1126 : ) { - 1127 28847581 : extent = *fs_last; + 1127 28848823 : extent = *fs_last; 1128 : } else { - 1129 10294512 : struct extent_parity_inside arg = { parity_pos }; - 1130 10294512 : extent = tommy_tree_search_compare(&disk->fs_parity, extent_parity_inside_compare_unlock, &arg); + 1129 10295636 : struct extent_parity_inside arg = { parity_pos }; + 1130 10295636 : extent = tommy_tree_search_compare(&disk->fs_parity, extent_parity_inside_compare_unlock, &arg); 1131 : } 1132 : - 1133 39141955 : if (!extent) - 1134 1584132 : return 0; + 1133 39144338 : if (!extent) + 1134 1584242 : return 0; 1135 : 1136 : /* store the last accessed extent */ - 1137 37557823 : *fs_last = extent; + 1137 37560096 : *fs_last = extent; 1138 : - 1139 37557823 : return extent; + 1139 37560096 : return extent; 1140 : } 1141 : 1142 : struct extent_file_inside { @@ -1209,22 +1209,22 @@ 1147 : /** 1148 : * Compare the extent if containing the specified file position. 1149 : */ - 1150 21314053 : static int extent_file_inside_compare_unlock(const void* void_a, const void* void_b) + 1150 21310663 : static int extent_file_inside_compare_unlock(const void* void_a, const void* void_b) 1151 : { - 1152 21314053 : const struct extent_file_inside* arg_a = void_a; - 1153 21314053 : const struct snapraid_extent* arg_b = void_b; + 1152 21310663 : const struct extent_file_inside* arg_a = void_a; + 1153 21310663 : const struct snapraid_extent* arg_b = void_b; 1154 : - 1155 21314053 : if (arg_a->file < arg_b->file) - 1156 8882877 : return -1; - 1157 12431176 : if (arg_a->file > arg_b->file) - 1158 10411547 : return 1; + 1155 21310663 : if (arg_a->file < arg_b->file) + 1156 8886240 : return -1; + 1157 12424423 : if (arg_a->file > arg_b->file) + 1158 10404719 : return 1; 1159 : - 1160 2019629 : if (arg_a->file_pos < arg_b->file_pos) - 1161 8339 : return -1; - 1162 2011290 : if (arg_a->file_pos >= arg_b->file_pos + arg_b->count) - 1163 7952 : return 1; + 1160 2019704 : if (arg_a->file_pos < arg_b->file_pos) + 1161 8320 : return -1; + 1162 2011384 : if (arg_a->file_pos >= arg_b->file_pos + arg_b->count) + 1163 7938 : return 1; 1164 : - 1165 2003338 : return 0; + 1165 2003446 : return 0; 1166 : } 1167 : 1168 : /** @@ -1232,88 +1232,88 @@ 1170 : * The search is optimized for sequential accesses. 1171 : * \return If not found return 0 1172 : */ - 1173 10336325 : static struct snapraid_extent* fs_file2extent_get_unlock(struct snapraid_disk* disk, struct snapraid_extent** fs_last, struct snapraid_file* file, block_off_t file_pos) + 1173 10336351 : static struct snapraid_extent* fs_file2extent_get_unlock(struct snapraid_disk* disk, struct snapraid_extent** fs_last, struct snapraid_file* file, block_off_t file_pos) 1174 : { 1175 : struct snapraid_extent* extent; 1176 : 1177 : /* check if the last accessed extent matches */ - 1178 10336325 : if (*fs_last - 1179 10312676 : && file == (*fs_last)->file - 1180 8347214 : && file_pos >= (*fs_last)->file_pos - 1181 8347214 : && file_pos < (*fs_last)->file_pos + (*fs_last)->count + 1178 10336351 : if (*fs_last + 1179 10312659 : && file == (*fs_last)->file + 1180 8347111 : && file_pos >= (*fs_last)->file_pos + 1181 8347111 : && file_pos < (*fs_last)->file_pos + (*fs_last)->count 1182 : ) { - 1183 8332979 : extent = *fs_last; + 1183 8332897 : extent = *fs_last; 1184 : } else { - 1185 2003346 : struct extent_file_inside arg = { file, file_pos }; - 1186 2003346 : extent = tommy_tree_search_compare(&disk->fs_file, extent_file_inside_compare_unlock, &arg); + 1185 2003454 : struct extent_file_inside arg = { file, file_pos }; + 1186 2003454 : extent = tommy_tree_search_compare(&disk->fs_file, extent_file_inside_compare_unlock, &arg); 1187 : } 1188 : - 1189 10336325 : if (!extent) + 1189 10336351 : if (!extent) 1190 8 : return 0; 1191 : 1192 : /* store the last accessed extent */ - 1193 10336317 : *fs_last = extent; + 1193 10336343 : *fs_last = extent; 1194 : - 1195 10336317 : return extent; + 1195 10336343 : return extent; 1196 : } 1197 : - 1198 39035232 : struct snapraid_file* fs_par2file_find(struct snapraid_disk* disk, block_off_t parity_pos, block_off_t* file_pos) + 1198 39037806 : struct snapraid_file* fs_par2file_find(struct snapraid_disk* disk, block_off_t parity_pos, block_off_t* file_pos) 1199 : { 1200 : struct snapraid_extent* extent; 1201 : struct snapraid_file* file; 1202 : - 1203 39035232 : fs_lock(disk); + 1203 39037806 : fs_lock(disk); 1204 : - 1205 39036374 : extent = fs_par2extent_get_unlock(disk, &disk->fs_last, parity_pos); + 1205 39038558 : extent = fs_par2extent_get_unlock(disk, &disk->fs_last, parity_pos); 1206 : - 1207 39035521 : if (!extent) { - 1208 1584134 : fs_unlock(disk); - 1209 1584150 : return 0; + 1207 39037687 : if (!extent) { + 1208 1584243 : fs_unlock(disk); + 1209 1584263 : return 0; 1210 : } 1211 : - 1212 37451387 : if (file_pos) - 1213 37106669 : *file_pos = extent->file_pos + (parity_pos - extent->parity_pos); + 1212 37453444 : if (file_pos) + 1213 37108755 : *file_pos = extent->file_pos + (parity_pos - extent->parity_pos); 1214 : - 1215 37451387 : file = extent->file; + 1215 37453444 : file = extent->file; 1216 : - 1217 37451387 : fs_unlock(disk); - 1218 37452141 : return file; + 1217 37453444 : fs_unlock(disk); + 1218 37454270 : return file; 1219 : } 1220 : - 1221 4869535 : block_off_t fs_file2par_find(struct snapraid_disk* disk, struct snapraid_file* file, block_off_t file_pos) + 1221 4869582 : block_off_t fs_file2par_find(struct snapraid_disk* disk, struct snapraid_file* file, block_off_t file_pos) 1222 : { 1223 : struct snapraid_extent* extent; 1224 : block_off_t ret; 1225 : - 1226 4869535 : fs_lock(disk); + 1226 4869582 : fs_lock(disk); 1227 : - 1228 4869535 : extent = fs_file2extent_get_unlock(disk, &disk->fs_last, file, file_pos); - 1229 4869535 : if (!extent) { + 1228 4869582 : extent = fs_file2extent_get_unlock(disk, &disk->fs_last, file, file_pos); + 1229 4869582 : if (!extent) { 1230 8 : fs_unlock(disk); 1231 8 : return POS_NULL; 1232 : } 1233 : - 1234 4869527 : ret = extent->parity_pos + (file_pos - extent->file_pos); + 1234 4869574 : ret = extent->parity_pos + (file_pos - extent->file_pos); 1235 : - 1236 4869527 : fs_unlock(disk); - 1237 4869527 : return ret; + 1236 4869574 : fs_unlock(disk); + 1237 4869574 : return ret; 1238 : } 1239 : - 1240 9175619 : void fs_allocate(struct snapraid_disk* disk, block_off_t parity_pos, struct snapraid_file* file, block_off_t file_pos) + 1240 9175524 : void fs_allocate(struct snapraid_disk* disk, block_off_t parity_pos, struct snapraid_file* file, block_off_t file_pos) 1241 : { 1242 : struct snapraid_extent* extent; 1243 : struct snapraid_extent* parity_extent; 1244 : struct snapraid_extent* file_extent; 1245 : - 1246 9175619 : fs_lock(disk); + 1246 9175524 : fs_lock(disk); 1247 : - 1248 9175619 : if (file_pos > 0) { + 1248 9175524 : if (file_pos > 0) { 1249 : /* search an existing extent for the previous file_pos */ - 1250 5466790 : extent = fs_file2extent_get_unlock(disk, &disk->fs_last, file, file_pos - 1); + 1250 5466769 : extent = fs_file2extent_get_unlock(disk, &disk->fs_last, file, file_pos - 1); 1251 : - 1252 5466790 : if (extent != 0 && parity_pos == extent->parity_pos + extent->count) { + 1252 5466769 : if (extent != 0 && parity_pos == extent->parity_pos + extent->count) { 1253 : /* ensure that we are extending the extent at the end */ - 1254 5440128 : if (file_pos != extent->file_pos + extent->count) { + 1254 5440129 : if (file_pos != extent->file_pos + extent->count) { 1255 : /* LCOV_EXCL_START */ 1256 : log_fatal("Internal inconsistency when allocating file '%s' at position '%u/%u' in the middle of extent '%u:%u' in disk '%s'\n", file->sub, file_pos, file->blockmax, extent->file_pos, extent->count, disk->name); 1257 : os_abort(); @@ -1321,21 +1321,21 @@ 1259 : } 1260 : 1261 : /* extend the existing extent */ - 1262 5440128 : ++extent->count; + 1262 5440129 : ++extent->count; 1263 : - 1264 5440128 : fs_unlock(disk); - 1265 14615747 : return; + 1264 5440129 : fs_unlock(disk); + 1265 14615653 : return; 1266 : } 1267 : } 1268 : 1269 : /* a extent doesn't exist, and we have to create a new one */ - 1270 3735491 : extent = extent_alloc(parity_pos, file, file_pos, 1); + 1270 3735395 : extent = extent_alloc(parity_pos, file, file_pos, 1); 1271 : 1272 : /* insert the extent in the trees */ - 1273 3735491 : parity_extent = tommy_tree_insert(&disk->fs_parity, &extent->parity_node, extent); - 1274 3735491 : file_extent = tommy_tree_insert(&disk->fs_file, &extent->file_node, extent); + 1273 3735395 : parity_extent = tommy_tree_insert(&disk->fs_parity, &extent->parity_node, extent); + 1274 3735395 : file_extent = tommy_tree_insert(&disk->fs_file, &extent->file_node, extent); 1275 : - 1276 3735491 : if (parity_extent != extent || file_extent != extent) { + 1276 3735395 : if (parity_extent != extent || file_extent != extent) { 1277 : /* LCOV_EXCL_START */ 1278 : log_fatal("Internal inconsistency when allocating file '%s' at position '%u/%u' for existing extent '%u:%u' in disk '%s'\n", file->sub, file_pos, file->blockmax, extent->file_pos, extent->count, disk->name); 1279 : os_abort(); @@ -1343,12 +1343,12 @@ 1281 : } 1282 : 1283 : /* store the last accessed extent */ - 1284 3735491 : disk->fs_last = extent; + 1284 3735395 : disk->fs_last = extent; 1285 : - 1286 3735491 : fs_unlock(disk); + 1286 3735395 : fs_unlock(disk); 1287 : } 1288 : - 1289 106126 : void fs_deallocate(struct snapraid_disk* disk, block_off_t parity_pos) + 1289 106308 : void fs_deallocate(struct snapraid_disk* disk, block_off_t parity_pos) 1290 : { 1291 : struct snapraid_extent* extent; 1292 : struct snapraid_extent* second_extent; @@ -1356,10 +1356,10 @@ 1294 : struct snapraid_extent* file_extent; 1295 : block_off_t first_count, second_count; 1296 : - 1297 106126 : fs_lock(disk); + 1297 106308 : fs_lock(disk); 1298 : - 1299 106126 : extent = fs_par2extent_get_unlock(disk, &disk->fs_last, parity_pos); - 1300 106126 : if (!extent) { + 1299 106308 : extent = fs_par2extent_get_unlock(disk, &disk->fs_last, parity_pos); + 1300 106308 : if (!extent) { 1301 : /* LCOV_EXCL_START */ 1302 : log_fatal("Internal inconsistency when deallocating parity position '%u' for not existing extent in disk '%s'\n", parity_pos, disk->name); 1303 : os_abort(); @@ -1367,29 +1367,29 @@ 1305 : } 1306 : 1307 : /* if it's the only block of the extent, delete it */ - 1308 106126 : if (extent->count == 1) { + 1308 106308 : if (extent->count == 1) { 1309 : /* remove from the trees */ - 1310 39610 : tommy_tree_remove(&disk->fs_parity, extent); - 1311 39610 : tommy_tree_remove(&disk->fs_file, extent); + 1310 39667 : tommy_tree_remove(&disk->fs_parity, extent); + 1311 39667 : tommy_tree_remove(&disk->fs_file, extent); 1312 : 1313 : /* deallocate */ - 1314 39610 : extent_free(extent); + 1314 39667 : extent_free(extent); 1315 : 1316 : /* clear the last accessed extent */ - 1317 39610 : disk->fs_last = 0; + 1317 39667 : disk->fs_last = 0; 1318 : - 1319 39610 : fs_unlock(disk); - 1320 39610 : return; + 1319 39667 : fs_unlock(disk); + 1320 39667 : return; 1321 : } 1322 : 1323 : /* if it's at the start of the extent, shrink the extent */ - 1324 66516 : if (parity_pos == extent->parity_pos) { - 1325 66514 : ++extent->parity_pos; - 1326 66514 : ++extent->file_pos; - 1327 66514 : --extent->count; + 1324 66641 : if (parity_pos == extent->parity_pos) { + 1325 66639 : ++extent->parity_pos; + 1326 66639 : ++extent->file_pos; + 1327 66639 : --extent->count; 1328 : - 1329 66514 : fs_unlock(disk); - 1330 66514 : return; + 1329 66639 : fs_unlock(disk); + 1330 66639 : return; 1331 : } 1332 : 1333 : /* if it's at the end of the extent, shrink the extent */ @@ -1427,42 +1427,42 @@ 1365 1 : fs_unlock(disk); 1366 : } 1367 : - 1368 44945080 : struct snapraid_block* fs_file2block_get(struct snapraid_file* file, block_off_t file_pos) + 1368 44946613 : struct snapraid_block* fs_file2block_get(struct snapraid_file* file, block_off_t file_pos) 1369 : { - 1370 44945080 : if (file_pos >= file->blockmax) { + 1370 44946613 : if (file_pos >= file->blockmax) { 1371 : /* LCOV_EXCL_START */ 1372 : log_fatal("Internal inconsistency when dereferencing file '%s' at position '%u/%u'\n", file->sub, file_pos, file->blockmax); 1373 : os_abort(); 1374 : /* LCOV_EXCL_STOP */ 1375 : } 1376 : - 1377 44945080 : return file_block(file, file_pos); + 1377 44946613 : return file_block(file, file_pos); 1378 : } 1379 : - 1380 27312315 : struct snapraid_block* fs_par2block_find(struct snapraid_disk* disk, block_off_t parity_pos) + 1380 27314040 : struct snapraid_block* fs_par2block_find(struct snapraid_disk* disk, block_off_t parity_pos) 1381 : { 1382 : struct snapraid_file* file; 1383 : block_off_t file_pos; 1384 : - 1385 27312315 : file = fs_par2file_find(disk, parity_pos, &file_pos); - 1386 27312544 : if (file == 0) - 1387 1584149 : return BLOCK_NULL; + 1385 27314040 : file = fs_par2file_find(disk, parity_pos, &file_pos); + 1386 27314201 : if (file == 0) + 1387 1584227 : return BLOCK_NULL; 1388 : - 1389 25728395 : return fs_file2block_get(file, file_pos); + 1389 25729974 : return fs_file2block_get(file, file_pos); 1390 : } 1391 : - 1392 1549 : struct snapraid_map* map_alloc(const char* name, unsigned position, block_off_t total_blocks, block_off_t free_blocks, const char* uuid) + 1392 1555 : struct snapraid_map* map_alloc(const char* name, unsigned position, block_off_t total_blocks, block_off_t free_blocks, const char* uuid) 1393 : { 1394 : struct snapraid_map* map; 1395 : - 1396 1549 : map = malloc_nofail(sizeof(struct snapraid_map)); - 1397 1549 : pathcpy(map->name, sizeof(map->name), name); - 1398 1549 : map->position = position; - 1399 1549 : map->total_blocks = total_blocks; - 1400 1549 : map->free_blocks = free_blocks; - 1401 1549 : pathcpy(map->uuid, sizeof(map->uuid), uuid); + 1396 1555 : map = malloc_nofail(sizeof(struct snapraid_map)); + 1397 1555 : pathcpy(map->name, sizeof(map->name), name); + 1398 1555 : map->position = position; + 1399 1555 : map->total_blocks = total_blocks; + 1400 1555 : map->free_blocks = free_blocks; + 1401 1555 : pathcpy(map->uuid, sizeof(map->uuid), uuid); 1402 : - 1403 1549 : return map; + 1403 1555 : return map; 1404 : } 1405 : 1406 1429 : void map_free(struct snapraid_map* map) @@ -1470,16 +1470,16 @@ 1408 1429 : free(map); 1409 1429 : } 1410 : - 1411 684987 : int time_compare(const void* void_a, const void* void_b) + 1411 684203 : int time_compare(const void* void_a, const void* void_b) 1412 : { - 1413 684987 : const time_t* time_a = void_a; - 1414 684987 : const time_t* time_b = void_b; + 1413 684203 : const time_t* time_a = void_a; + 1414 684203 : const time_t* time_b = void_b; 1415 : - 1416 684987 : if (*time_a < *time_b) - 1417 16532 : return -1; - 1418 668455 : if (*time_a > *time_b) - 1419 119824 : return 1; - 1420 548631 : return 0; + 1416 684203 : if (*time_a < *time_b) + 1417 16620 : return -1; + 1418 667583 : if (*time_a > *time_b) + 1419 119940 : return 1; + 1420 547643 : return 0; 1421 : } 1422 : 1423 : /****************************************************************************/ @@ -1499,14 +1499,14 @@ 1437 : /** 1438 : * Format a path name for terminal reference 1439 : */ - 1440 356004 : const char* fmt_term(const struct snapraid_disk* disk, const char* str, char* buffer) + 1440 356075 : const char* fmt_term(const struct snapraid_disk* disk, const char* str, char* buffer) 1441 : { 1442 : const char* out[3]; 1443 : - 1444 356004 : switch (FMT_MODE) { + 1444 356075 : switch (FMT_MODE) { 1445 : case FMT_FILE : 1446 : default : - 1447 331944 : return esc_shell(str, buffer); + 1447 332015 : return esc_shell(str, buffer); 1448 : case FMT_DISK : 1449 12030 : out[0] = disk->name; 1450 12030 : out[1] = ":"; diff --git a/cov/cmdline/elem.h.func-sort-c.html b/cov/cmdline/elem.h.func-sort-c.html index 6462c4b2..3a1b0405 100644 --- a/cov/cmdline/elem.h.func-sort-c.html +++ b/cov/cmdline/elem.h.func-sort-c.html @@ -61,99 +61,99 @@ block_sizeof - 58065323 + 58066767 file_block - 54351240 + 54352792 block_state_get - 52304798 + 52307392 file_flag_has - 34094547 + 34094426 block_state_set - 19117787 + 19118268 block_has_file - 14590544 + 14591728 block_has_invalid_parity - 12320061 + 12320606 fs_par2file_get - 11723736 + 11723986 hash_invalid_set - 9234472 + 9234413 file_stamp_hash - 6275914 + 6275808 file_flag_set - 5301349 + 5301067 info_get - 5098374 + 5098627 file_inode_hash - 5047846 + 5047758 fs_file2par_get - 4755380 + 4755371 file_path_hash - 3886074 + 3885977 filter_hidden - 3173124 + 3173351 block_has_past_hash - 2542743 + 2542370 block_has_updated_hash - 2217692 + 2218141 info_get_rehash - 2046653 + 2046724 info_set - 1697965 + 1698098 info_get_time - 883104 + 883015 hash_is_zero - 760617 + 760471 hash_is_invalid - 759156 + 759009 info_get_bad - 351943 + 351958 block_has_file_and_valid_parity @@ -161,11 +161,11 @@ link_flag_has - 209329 + 209328 info_make - 194583 + 194355 link_name_hash @@ -181,11 +181,11 @@ info_get_justsynced - 68535 + 68446 hash_is_unique - 44219 + 44333 link_flag_set @@ -193,7 +193,7 @@ file_flag_clear - 16739 + 16745 fs_par2block_get diff --git a/cov/cmdline/elem.h.func.html b/cov/cmdline/elem.h.func.html index db662b11..3407ad88 100644 --- a/cov/cmdline/elem.h.func.html +++ b/cov/cmdline/elem.h.func.html @@ -61,7 +61,7 @@ block_has_file - 14590544 + 14591728 block_has_file_and_valid_parity @@ -69,27 +69,27 @@ block_has_invalid_parity - 12320061 + 12320606 block_has_past_hash - 2542743 + 2542370 block_has_updated_hash - 2217692 + 2218141 block_sizeof - 58065323 + 58066767 block_state_get - 52304798 + 52307392 block_state_set - 19117787 + 19118268 dir_flag_has @@ -105,39 +105,39 @@ file_block - 54351240 + 54352792 file_flag_clear - 16739 + 16745 file_flag_has - 34094547 + 34094426 file_flag_set - 5301349 + 5301067 file_inode_hash - 5047846 + 5047758 file_path_hash - 3886074 + 3885977 file_stamp_hash - 6275914 + 6275808 filter_hidden - 3173124 + 3173351 fs_file2par_get - 4755380 + 4755371 fs_par2block_get @@ -145,23 +145,23 @@ fs_par2file_get - 11723736 + 11723986 hash_invalid_set - 9234472 + 9234413 hash_is_invalid - 759156 + 759009 hash_is_unique - 44219 + 44333 hash_is_zero - 760617 + 760471 hash_zero_set @@ -169,31 +169,31 @@ info_get - 5098374 + 5098627 info_get_bad - 351943 + 351958 info_get_justsynced - 68535 + 68446 info_get_rehash - 2046653 + 2046724 info_get_time - 883104 + 883015 info_make - 194583 + 194355 info_set - 1697965 + 1698098 info_set_bad @@ -209,7 +209,7 @@ link_flag_has - 209329 + 209328 link_flag_let diff --git a/cov/cmdline/elem.h.gcov.html b/cov/cmdline/elem.h.gcov.html index 724a4396..d182c9e5 100644 --- a/cov/cmdline/elem.h.gcov.html +++ b/cov/cmdline/elem.h.gcov.html @@ -571,13 +571,13 @@ 509 : * Filter hidden files. 510 : * Return !=0 if it matches and it should be excluded. 511 : */ - 512 3173124 : static inline int filter_hidden(int enable, struct dirent* dd) + 512 3173351 : static inline int filter_hidden(int enable, struct dirent* dd) 513 : { - 514 3173124 : if (enable && dirent_hidden(dd)) { + 514 3173351 : if (enable && dirent_hidden(dd)) { 515 0 : return 1; /* filter out */ 516 : } 517 : - 518 3173124 : return 0; + 518 3173351 : return 0; 519 : } 520 : 521 : /** @@ -628,19 +628,19 @@ 566 : * 567 : * If working with reduced hash lengths, this function always return 0. 568 : */ - 569 759156 : static inline int hash_is_invalid(const unsigned char* hash) + 569 759009 : static inline int hash_is_invalid(const unsigned char* hash) 570 : { 571 : int i; 572 : 573 : /* if the hash is reduced, we cannot grant that it's a specific kind of hash */ - 574 759156 : if (BLOCK_HASH_SIZE != HASH_MAX) + 574 759009 : if (BLOCK_HASH_SIZE != HASH_MAX) 575 0 : return 0; 576 : - 577 1179374 : for (i = 0; i < BLOCK_HASH_SIZE; ++i) - 578 1153310 : if (hash[i] != 0x00) - 579 733092 : return 0; + 577 1178755 : for (i = 0; i < BLOCK_HASH_SIZE; ++i) + 578 1152696 : if (hash[i] != 0x00) + 579 732950 : return 0; 580 : - 581 26064 : return 1; + 581 26059 : return 1; 582 : } 583 : 584 : /** @@ -650,19 +650,19 @@ 588 : * 589 : * If working with reduced hash lengths, this function always return 0. 590 : */ - 591 760617 : static inline int hash_is_zero(const unsigned char* hash) + 591 760471 : static inline int hash_is_zero(const unsigned char* hash) 592 : { 593 : int i; 594 : 595 : /* if the hash is reduced, we cannot grant that it's a specific kind of hash */ - 596 760617 : if (BLOCK_HASH_SIZE != HASH_MAX) + 596 760471 : if (BLOCK_HASH_SIZE != HASH_MAX) 597 0 : return 0; 598 : - 599 994968 : for (i = 0; i < BLOCK_HASH_SIZE; ++i) - 600 980500 : if (hash[i] != 0xFF) - 601 746149 : return 0; + 599 994894 : for (i = 0; i < BLOCK_HASH_SIZE; ++i) + 600 980425 : if (hash[i] != 0xFF) + 601 746002 : return 0; 602 : - 603 14468 : return 1; + 603 14469 : return 1; 604 : } 605 : 606 : /** @@ -670,22 +670,22 @@ 608 : * 609 : * If working with reduced hash lengths, this function always return 0. 610 : */ - 611 44219 : static inline int hash_is_unique(const unsigned char* hash) + 611 44333 : static inline int hash_is_unique(const unsigned char* hash) 612 : { 613 : /* if the hash is reduced, we cannot grant that it's a specific kind of hash */ - 614 44219 : if (BLOCK_HASH_SIZE != HASH_MAX) + 614 44333 : if (BLOCK_HASH_SIZE != HASH_MAX) 615 0 : return 0; 616 : - 617 44219 : return !hash_is_zero(hash) && !hash_is_invalid(hash); + 617 44333 : return !hash_is_zero(hash) && !hash_is_invalid(hash); 618 : } 619 : 620 : /** 621 : * Set the hash to the special INVALID value. 622 : */ - 623 9234472 : static inline void hash_invalid_set(unsigned char* hash) + 623 9234413 : static inline void hash_invalid_set(unsigned char* hash) 624 : { - 625 9234472 : memset(hash, 0x00, BLOCK_HASH_SIZE); - 626 9234472 : } + 625 9234413 : memset(hash, 0x00, BLOCK_HASH_SIZE); + 626 9234413 : } 627 : 628 : /** 629 : * Set the hash to the special ZERO value. @@ -698,9 +698,9 @@ 636 : /** 637 : * Allocated space for block. 638 : */ - 639 58065323 : static inline size_t block_sizeof(void) + 639 58066767 : static inline size_t block_sizeof(void) 640 : { - 641 58065323 : return 1 + BLOCK_HASH_SIZE; + 641 58066767 : return 1 + BLOCK_HASH_SIZE; 642 : } 643 : 644 : /** @@ -709,32 +709,32 @@ 647 : * For this function, it's allowed to pass a NULL block 648 : * pointer than results in the BLOCK_STATE_EMPTY state. 649 : */ - 650 52304798 : static inline unsigned block_state_get(const struct snapraid_block* block) + 650 52307392 : static inline unsigned block_state_get(const struct snapraid_block* block) 651 : { - 652 52304798 : if (block == BLOCK_NULL) - 653 1721706 : return BLOCK_STATE_EMPTY; + 652 52307392 : if (block == BLOCK_NULL) + 653 1721808 : return BLOCK_STATE_EMPTY; 654 : - 655 50583092 : return block->state; + 655 50585584 : return block->state; 656 : } 657 : 658 : /** 659 : * Set the state of the block. 660 : */ - 661 19117787 : static inline void block_state_set(struct snapraid_block* block, unsigned state) + 661 19118268 : static inline void block_state_set(struct snapraid_block* block, unsigned state) 662 : { - 663 19117787 : block->state = state; - 664 19117787 : } + 663 19118268 : block->state = state; + 664 19118268 : } 665 : 666 : /** 667 : * Check if the specified block has an updated hash. 668 : * 669 : * Note that EMPTY / CHG / DELETED return 0. 670 : */ - 671 2217692 : static inline int block_has_updated_hash(const struct snapraid_block* block) + 671 2218141 : static inline int block_has_updated_hash(const struct snapraid_block* block) 672 : { - 673 2217692 : unsigned state = block_state_get(block); + 673 2218141 : unsigned state = block_state_get(block); 674 : - 675 2217692 : return state == BLOCK_STATE_BLK || state == BLOCK_STATE_REP; + 675 2218141 : return state == BLOCK_STATE_BLK || state == BLOCK_STATE_REP; 676 : } 677 : 678 : /** @@ -743,11 +743,11 @@ 681 : * 682 : * Note that EMPTY / BLK / REP return 0. 683 : */ - 684 2542743 : static inline int block_has_past_hash(const struct snapraid_block* block) + 684 2542370 : static inline int block_has_past_hash(const struct snapraid_block* block) 685 : { - 686 2542743 : unsigned state = block_state_get(block); + 686 2542370 : unsigned state = block_state_get(block); 687 : - 688 2542743 : return state == BLOCK_STATE_CHG || state == BLOCK_STATE_DELETED; + 688 2542370 : return state == BLOCK_STATE_CHG || state == BLOCK_STATE_DELETED; 689 : } 690 : 691 : /** @@ -755,12 +755,12 @@ 693 : * 694 : * Note that EMPTY / DELETED return 0. 695 : */ - 696 14590544 : static inline int block_has_file(const struct snapraid_block* block) + 696 14591728 : static inline int block_has_file(const struct snapraid_block* block) 697 : { - 698 14590544 : unsigned state = block_state_get(block); + 698 14591728 : unsigned state = block_state_get(block); 699 : - 700 14590800 : return state == BLOCK_STATE_BLK - 701 14590800 : || state == BLOCK_STATE_CHG || state == BLOCK_STATE_REP; + 700 14591975 : return state == BLOCK_STATE_BLK + 701 14591975 : || state == BLOCK_STATE_CHG || state == BLOCK_STATE_REP; 702 : } 703 : 704 : /** @@ -768,12 +768,12 @@ 706 : * 707 : * Note that EMPTY / BLK return 0. 708 : */ - 709 12320061 : static inline int block_has_invalid_parity(const struct snapraid_block* block) + 709 12320606 : static inline int block_has_invalid_parity(const struct snapraid_block* block) 710 : { - 711 12320061 : unsigned state = block_state_get(block); + 711 12320606 : unsigned state = block_state_get(block); 712 : - 713 12320061 : return state == BLOCK_STATE_DELETED - 714 12320061 : || state == BLOCK_STATE_CHG || state == BLOCK_STATE_REP; + 713 12320606 : return state == BLOCK_STATE_DELETED + 714 12320606 : || state == BLOCK_STATE_CHG || state == BLOCK_STATE_REP; 715 : } 716 : 717 : /** @@ -788,20 +788,20 @@ 726 220959 : return state == BLOCK_STATE_BLK; 727 : } 728 : - 729 34094547 : static inline int file_flag_has(const struct snapraid_file* file, unsigned mask) + 729 34094426 : static inline int file_flag_has(const struct snapraid_file* file, unsigned mask) 730 : { - 731 34094547 : return (file->flag & mask) == mask; + 731 34094426 : return (file->flag & mask) == mask; 732 : } 733 : - 734 5301349 : static inline void file_flag_set(struct snapraid_file* file, unsigned mask) + 734 5301067 : static inline void file_flag_set(struct snapraid_file* file, unsigned mask) 735 : { - 736 5301349 : file->flag |= mask; - 737 5301349 : } + 736 5301067 : file->flag |= mask; + 737 5301067 : } 738 : - 739 16739 : static inline void file_flag_clear(struct snapraid_file* file, unsigned mask) + 739 16745 : static inline void file_flag_clear(struct snapraid_file* file, unsigned mask) 740 : { - 741 16739 : file->flag &= ~mask; - 742 16739 : } + 741 16745 : file->flag &= ~mask; + 742 16745 : } 743 : 744 : /** 745 : * Allocate a file. @@ -833,11 +833,11 @@ 771 : * 772 : * Note that the block size if a runtime value. 773 : */ - 774 54351240 : static inline struct snapraid_block* file_block(struct snapraid_file* file, size_t pos) + 774 54352792 : static inline struct snapraid_block* file_block(struct snapraid_file* file, size_t pos) 775 : { - 776 54351240 : unsigned char* ptr = (unsigned char*)file->blockvec; + 776 54352792 : unsigned char* ptr = (unsigned char*)file->blockvec; 777 : - 778 54351240 : return (struct snapraid_block*)(ptr + pos * block_sizeof()); + 778 54352792 : return (struct snapraid_block*)(ptr + pos * block_sizeof()); 779 : } 780 : 781 : /** @@ -879,9 +879,9 @@ 817 : /** 818 : * Compute the hash of a file inode. 819 : */ - 820 5047846 : static inline tommy_uint32_t file_inode_hash(uint64_t inode) + 820 5047758 : static inline tommy_uint32_t file_inode_hash(uint64_t inode) 821 : { - 822 5047846 : return (tommy_uint32_t)tommy_inthash_u64(inode); + 822 5047758 : return (tommy_uint32_t)tommy_inthash_u64(inode); 823 : } 824 : 825 : /** @@ -900,17 +900,17 @@ 838 : /** 839 : * Compute the hash of a file path. 840 : */ - 841 3886074 : static inline tommy_uint32_t file_path_hash(const char* sub) + 841 3885977 : static inline tommy_uint32_t file_path_hash(const char* sub) 842 : { - 843 3886074 : return tommy_hash_u32(0, sub, strlen(sub)); + 843 3885977 : return tommy_hash_u32(0, sub, strlen(sub)); 844 : } 845 : 846 : /** 847 : * Compute the hash of a file stamp. 848 : */ - 849 6275914 : static inline tommy_uint32_t file_stamp_hash(data_off_t size, int64_t mtime_sec, int mtime_nsec) + 849 6275808 : static inline tommy_uint32_t file_stamp_hash(data_off_t size, int64_t mtime_sec, int mtime_nsec) 850 : { - 851 6275914 : return tommy_inthash_u32((tommy_uint32_t)size ^ tommy_inthash_u32(mtime_sec ^ tommy_inthash_u32(mtime_nsec))); + 851 6275808 : return tommy_inthash_u32((tommy_uint32_t)size ^ tommy_inthash_u32(mtime_sec ^ tommy_inthash_u32(mtime_nsec))); 852 : } 853 : 854 : /** @@ -933,9 +933,9 @@ 871 : */ 872 : int extent_file_compare(const void* void_a, const void* void_b); 873 : - 874 209329 : static inline int link_flag_has(const struct snapraid_link* slink, unsigned mask) + 874 209328 : static inline int link_flag_has(const struct snapraid_link* slink, unsigned mask) 875 : { - 876 209329 : return (slink->flag & mask) == mask; + 876 209328 : return (slink->flag & mask) == mask; 877 : } 878 : 879 39461 : static inline void link_flag_set(struct snapraid_link* slink, unsigned mask) @@ -1088,19 +1088,19 @@ 1026 : /** 1027 : * Get the file position from the parity position. 1028 : */ - 1029 11723736 : static inline struct snapraid_file* fs_par2file_get(struct snapraid_disk* disk, block_off_t parity_pos, block_off_t* file_pos) + 1029 11723986 : static inline struct snapraid_file* fs_par2file_get(struct snapraid_disk* disk, block_off_t parity_pos, block_off_t* file_pos) 1030 : { 1031 : struct snapraid_file* ret; 1032 : - 1033 11723736 : ret = fs_par2file_find(disk, parity_pos, file_pos); - 1034 11723887 : if (ret == 0) { + 1033 11723986 : ret = fs_par2file_find(disk, parity_pos, file_pos); + 1034 11724450 : if (ret == 0) { 1035 : /* LCOV_EXCL_START */ 1036 : log_fatal("Internal inconsistency when deresolving parity to file at position '%u' in disk '%s'\n", parity_pos, disk->name); 1037 : os_abort(); 1038 : /* LCOV_EXCL_STOP */ 1039 : } 1040 : - 1041 11723887 : return ret; + 1041 11724450 : return ret; 1042 : } 1043 : 1044 : /** @@ -1112,19 +1112,19 @@ 1050 : /** 1051 : * Get the parity position from the file position. 1052 : */ - 1053 4755380 : static inline block_off_t fs_file2par_get(struct snapraid_disk* disk, struct snapraid_file* file, block_off_t file_pos) + 1053 4755371 : static inline block_off_t fs_file2par_get(struct snapraid_disk* disk, struct snapraid_file* file, block_off_t file_pos) 1054 : { 1055 : block_off_t ret; 1056 : - 1057 4755380 : ret = fs_file2par_find(disk, file, file_pos); - 1058 4755380 : if (ret == POS_NULL) { + 1057 4755371 : ret = fs_file2par_find(disk, file, file_pos); + 1058 4755371 : if (ret == POS_NULL) { 1059 : /* LCOV_EXCL_START */ 1060 : log_fatal("Internal inconsistency when resolving file '%s' at position '%u/%u' in disk '%s'\n", file->sub, file_pos, file->blockmax, disk->name); 1061 : os_abort(); 1062 : /* LCOV_EXCL_STOP */ 1063 : } 1064 : - 1065 4755380 : return ret; + 1065 4755371 : return ret; 1066 : } 1067 : 1068 : /** @@ -1172,18 +1172,18 @@ 1110 : /** 1111 : * Make an info. 1112 : */ - 1113 194583 : static inline snapraid_info info_make(time_t last_access, int error, int rehash, int justsynced) + 1113 194355 : static inline snapraid_info info_make(time_t last_access, int error, int rehash, int justsynced) 1114 : { 1115 : /* clear the lowest bits as reserved for other information */ - 1116 194583 : snapraid_info info = last_access & ~INFO_MASK; + 1116 194355 : snapraid_info info = last_access & ~INFO_MASK; 1117 : - 1118 194583 : if (error != 0) - 1119 5380 : info |= 0x1; - 1120 194583 : if (rehash != 0) + 1118 194355 : if (error != 0) + 1119 5306 : info |= 0x1; + 1120 194355 : if (rehash != 0) 1121 14426 : info |= 0x2; - 1122 194583 : if (justsynced != 0) - 1123 142978 : info |= 0x4; - 1124 194583 : return info; + 1122 194355 : if (justsynced != 0) + 1123 142922 : info |= 0x4; + 1124 194355 : return info; 1125 : } 1126 : 1127 : /** @@ -1191,36 +1191,36 @@ 1129 : * This is the last time when the block was know to be correct. 1130 : * The "scrubbed" info tells if the time is referreing at the latest sync or scrub. 1131 : */ - 1132 883104 : static inline time_t info_get_time(snapraid_info info) + 1132 883015 : static inline time_t info_get_time(snapraid_info info) 1133 : { - 1134 883104 : return info & ~INFO_MASK; + 1134 883015 : return info & ~INFO_MASK; 1135 : } 1136 : 1137 : /** 1138 : * Extract the error information. 1139 : * Report if the block address had some problem. 1140 : */ - 1141 351943 : static inline int info_get_bad(snapraid_info info) + 1141 351958 : static inline int info_get_bad(snapraid_info info) 1142 : { - 1143 351943 : return (info & 0x1) != 0; + 1143 351958 : return (info & 0x1) != 0; 1144 : } 1145 : 1146 : /** 1147 : * Extract the rehash information. 1148 : * Report if the block address is using the old hash and needs to be rehashed. 1149 : */ - 1150 2046653 : static inline int info_get_rehash(snapraid_info info) + 1150 2046724 : static inline int info_get_rehash(snapraid_info info) 1151 : { - 1152 2046653 : return (info & 0x2) != 0; + 1152 2046724 : return (info & 0x2) != 0; 1153 : } 1154 : 1155 : /** 1156 : * Extract the scrubbed information. 1157 : * Report if the block address was never scrubbed. 1158 : */ - 1159 68535 : static inline int info_get_justsynced(snapraid_info info) + 1159 68446 : static inline int info_get_justsynced(snapraid_info info) 1160 : { - 1161 68535 : return (info & 0x4) != 0; + 1161 68446 : return (info & 0x4) != 0; 1162 : } 1163 : 1164 : /** @@ -1243,27 +1243,27 @@ 1181 : * Set the info at the specified position. 1182 : * The position is allocated if not yet done. 1183 : */ - 1184 1697965 : static inline void info_set(tommy_arrayblkof* array, block_off_t pos, snapraid_info info) + 1184 1698098 : static inline void info_set(tommy_arrayblkof* array, block_off_t pos, snapraid_info info) 1185 : { - 1186 1697965 : tommy_arrayblkof_grow(array, pos + 1); + 1186 1698098 : tommy_arrayblkof_grow(array, pos + 1); 1187 : - 1188 1697965 : memcpy(tommy_arrayblkof_ref(array, pos), &info, sizeof(snapraid_info)); - 1189 1697965 : } + 1188 1698098 : memcpy(tommy_arrayblkof_ref(array, pos), &info, sizeof(snapraid_info)); + 1189 1698098 : } 1190 : 1191 : /** 1192 : * Get the info at the specified position. 1193 : * For not allocated position, 0 is returned. 1194 : */ - 1195 5098374 : static inline snapraid_info info_get(tommy_arrayblkof* array, block_off_t pos) + 1195 5098627 : static inline snapraid_info info_get(tommy_arrayblkof* array, block_off_t pos) 1196 : { 1197 : snapraid_info info; 1198 : - 1199 5098374 : if (pos >= tommy_arrayblkof_size(array)) + 1199 5098627 : if (pos >= tommy_arrayblkof_size(array)) 1200 262643 : return 0; 1201 : - 1202 4835731 : memcpy(&info, tommy_arrayblkof_ref(array, pos), sizeof(snapraid_info)); + 1202 4835984 : memcpy(&info, tommy_arrayblkof_ref(array, pos), sizeof(snapraid_info)); 1203 : - 1204 4835731 : return info; + 1204 4835984 : return info; 1205 : } 1206 : 1207 : /** diff --git a/cov/cmdline/handle.c.func-sort-c.html b/cov/cmdline/handle.c.func-sort-c.html index edff826c..ef921dc5 100644 --- a/cov/cmdline/handle.c.func-sort-c.html +++ b/cov/cmdline/handle.c.func-sort-c.html @@ -61,31 +61,31 @@ handle_read - 5855349 + 5856319 handle_close - 4647511 + 4647370 handle_open - 2185867 + 2186388 handle_create - 771311 + 771305 handle_write - 288562 + 288483 handle_utime - 119431 + 119471 handle_truncate - 3222 + 3180 handle_mapping diff --git a/cov/cmdline/handle.c.func.html b/cov/cmdline/handle.c.func.html index 6ead080c..f947889d 100644 --- a/cov/cmdline/handle.c.func.html +++ b/cov/cmdline/handle.c.func.html @@ -61,11 +61,11 @@ handle_close - 4647511 + 4647370 handle_create - 771311 + 771305 handle_mapping @@ -73,23 +73,23 @@ handle_open - 2185867 + 2186388 handle_read - 5855349 + 5856319 handle_truncate - 3222 + 3180 handle_utime - 119431 + 119471 handle_write - 288562 + 288483
diff --git a/cov/cmdline/handle.c.gcov.html b/cov/cmdline/handle.c.gcov.html index 98afa115..cbb1c184 100644 --- a/cov/cmdline/handle.c.gcov.html +++ b/cov/cmdline/handle.c.gcov.html @@ -86,64 +86,64 @@ 24 : /****************************************************************************/ 25 : /* handle */ 26 : - 27 771311 : int handle_create(struct snapraid_handle* handle, struct snapraid_file* file, int mode) + 27 771305 : int handle_create(struct snapraid_handle* handle, struct snapraid_file* file, int mode) 28 : { 29 : int ret; 30 : int flags; 31 : 32 : /* if it's the same file, and already opened, nothing to do */ - 33 771311 : if (handle->file == file && handle->f != -1) { + 33 771305 : if (handle->file == file && handle->f != -1) { 34 0 : return 0; 35 : } 36 : - 37 771311 : advise_init(&handle->advise, mode); - 38 771311 : pathprint(handle->path, sizeof(handle->path), "%s%s", handle->disk->dir, file->sub); + 37 771305 : advise_init(&handle->advise, mode); + 38 771305 : pathprint(handle->path, sizeof(handle->path), "%s%s", handle->disk->dir, file->sub); 39 : - 40 771311 : ret = mkancestor(handle->path); - 41 771311 : if (ret != 0) { + 40 771305 : ret = mkancestor(handle->path); + 41 771305 : if (ret != 0) { 42 : /* LCOV_EXCL_START */ 43 : return -1; 44 : /* LCOV_EXCL_STOP */ 45 : } 46 : 47 : /* initial values, changed later if required */ - 48 771311 : handle->created = 0; + 48 771305 : handle->created = 0; 49 : 50 : /* flags for opening */ 51 : /* O_BINARY: open as binary file (Windows only) */ 52 : /* O_NOFOLLOW: do not follow links to ensure to open the real file */ - 53 771311 : flags = O_BINARY | O_NOFOLLOW | advise_flags(&handle->advise); + 53 771305 : flags = O_BINARY | O_NOFOLLOW | advise_flags(&handle->advise); 54 : 55 : /* open for read write */ - 56 771311 : handle->f = open(handle->path, flags | O_RDWR); + 56 771305 : handle->f = open(handle->path, flags | O_RDWR); 57 : 58 : /* if failed for missing write permission */ - 59 771311 : if (handle->f == -1 && (errno == EACCES || errno == EROFS)) { + 59 771305 : if (handle->f == -1 && (errno == EACCES || errno == EROFS)) { 60 : /* open for real-only */ 61 0 : handle->f = open(handle->path, flags | O_RDONLY); 62 : } 63 : 64 : /* if failed for missing file */ - 65 771311 : if (handle->f == -1 && errno == ENOENT) { + 65 771305 : if (handle->f == -1 && errno == ENOENT) { 66 : char path_from[PATH_MAX]; 67 : 68 : /* check if exists a .unrecoverable copy, and rename to the real one */ - 69 176417 : pathprint(path_from, sizeof(path_from), "%s.unrecoverable", handle->path); + 69 176353 : pathprint(path_from, sizeof(path_from), "%s.unrecoverable", handle->path); 70 : - 71 176417 : if (rename(path_from, handle->path) == 0) { + 71 176353 : if (rename(path_from, handle->path) == 0) { 72 : /* open for read write */ - 73 63282 : handle->f = open(handle->path, flags | O_RDWR); + 73 63286 : handle->f = open(handle->path, flags | O_RDWR); 74 : } else { 75 : /* create it */ - 76 113135 : handle->f = open(handle->path, flags | O_RDWR | O_CREAT, 0600); - 77 113135 : if (handle->f != -1) { + 76 113067 : handle->f = open(handle->path, flags | O_RDWR | O_CREAT, 0600); + 77 113067 : if (handle->f != -1) { 78 : /* mark it as created if really done */ - 79 113135 : handle->created = 1; + 79 113067 : handle->created = 1; 80 : } 81 : } 82 : } 83 : - 84 771311 : if (handle->f == -1) { + 84 771305 : if (handle->f == -1) { 85 : /* LCOV_EXCL_START */ 86 : /* invalidate for error */ 87 : handle->file = 0; @@ -156,11 +156,11 @@ 94 : } 95 : 96 : /* just opened */ - 97 771311 : handle->file = file; + 97 771305 : handle->file = file; 98 : 99 : /* get the stat info */ - 100 771311 : ret = fstat(handle->f, &handle->st); - 101 771311 : if (ret != 0) { + 100 771305 : ret = fstat(handle->f, &handle->st); + 101 771305 : if (ret != 0) { 102 : /* LCOV_EXCL_START */ 103 : log_fatal("Error accessing file '%s'. %s.\n", handle->path, strerror(errno)); 104 : return -1; @@ -168,25 +168,25 @@ 106 : } 107 : 108 : /* get the size of the existing data */ - 109 771311 : handle->valid_size = handle->st.st_size; + 109 771305 : handle->valid_size = handle->st.st_size; 110 : - 111 771311 : ret = advise_open(&handle->advise, handle->f); - 112 771311 : if (ret != 0) { + 111 771305 : ret = advise_open(&handle->advise, handle->f); + 112 771305 : if (ret != 0) { 113 : /* LCOV_EXCL_START */ 114 : log_fatal("Error advising file '%s'. %s.\n", handle->path, strerror(errno)); 115 : return -1; 116 : /* LCOV_EXCL_STOP */ 117 : } 118 : - 119 771311 : return 0; + 119 771305 : return 0; 120 : } 121 : - 122 3222 : int handle_truncate(struct snapraid_handle* handle, struct snapraid_file* file) + 122 3180 : int handle_truncate(struct snapraid_handle* handle, struct snapraid_file* file) 123 : { 124 : int ret; 125 : - 126 3222 : ret = ftruncate(handle->f, file->size); - 127 3222 : if (ret != 0) { + 126 3180 : ret = ftruncate(handle->f, file->size); + 127 3180 : if (ret != 0) { 128 : /* LCOV_EXCL_START */ 129 : if (errno == EACCES) { 130 : log_fatal("Failed to truncate file '%s' for missing write permission.\n", handle->path); @@ -198,56 +198,56 @@ 136 : } 137 : 138 : /* adjust the size to the truncated size */ - 139 3222 : handle->valid_size = file->size; + 139 3180 : handle->valid_size = file->size; 140 : - 141 3222 : return 0; + 141 3180 : return 0; 142 : } 143 : - 144 2185867 : int handle_open(struct snapraid_handle* handle, struct snapraid_file* file, int mode, fptr* out, fptr* out_missing) + 144 2186388 : int handle_open(struct snapraid_handle* handle, struct snapraid_file* file, int mode, fptr* out, fptr* out_missing) 145 : { 146 : int ret; 147 : int flags; 148 : - 149 2185867 : if (!out_missing) - 150 2185464 : out_missing = out; + 149 2186388 : if (!out_missing) + 150 2185969 : out_missing = out; 151 : 152 : /* if already opened, nothing to do */ - 153 2185867 : if (handle->file == file && handle->file != 0 && handle->f != -1) { - 154 468345 : return 0; + 153 2186388 : if (handle->file == file && handle->file != 0 && handle->f != -1) { + 154 468756 : return 0; 155 : } 156 : - 157 1717522 : advise_init(&handle->advise, mode); - 158 1717676 : pathprint(handle->path, sizeof(handle->path), "%s%s", handle->disk->dir, file->sub); + 157 1717632 : advise_init(&handle->advise, mode); + 158 1717806 : pathprint(handle->path, sizeof(handle->path), "%s%s", handle->disk->dir, file->sub); 159 : 160 : /* for sure not created */ - 161 1717807 : handle->created = 0; + 161 1717916 : handle->created = 0; 162 : 163 : /* flags for opening */ 164 : /* O_BINARY: open as binary file (Windows only) */ 165 : /* O_NOFOLLOW: do not follow links to ensure to open the real file */ - 166 1717807 : flags = O_BINARY | O_NOFOLLOW | advise_flags(&handle->advise); + 166 1717916 : flags = O_BINARY | O_NOFOLLOW | advise_flags(&handle->advise); 167 : 168 : /* open for read */ - 169 1717764 : handle->f = open_noatime(handle->path, flags | O_RDONLY); - 170 1717748 : if (handle->f == -1) { + 169 1717861 : handle->f = open_noatime(handle->path, flags | O_RDONLY); + 170 1717874 : if (handle->f == -1) { 171 : /* invalidate for error */ - 172 78757 : handle->file = 0; - 173 78757 : handle->f = -1; - 174 78757 : handle->valid_size = 0; + 172 78666 : handle->file = 0; + 173 78666 : handle->f = -1; + 174 78666 : handle->valid_size = 0; 175 : - 176 78757 : if (errno == ENOENT) - 177 78745 : out_missing("Missing file '%s'.\n", handle->path); + 176 78666 : if (errno == ENOENT) + 177 78654 : out_missing("Missing file '%s'.\n", handle->path); 178 : else 179 12 : out("Error opening file '%s'. %s.\n", handle->path, strerror(errno)); - 180 78757 : return -1; + 180 78666 : return -1; 181 : } 182 : 183 : /* just opened */ - 184 1638991 : handle->file = file; + 184 1639208 : handle->file = file; 185 : 186 : /* get the stat info */ - 187 1638991 : ret = fstat(handle->f, &handle->st); - 188 1639031 : if (ret != 0) { + 187 1639208 : ret = fstat(handle->f, &handle->st); + 188 1639257 : if (ret != 0) { 189 : /* LCOV_EXCL_START */ 190 : out("Error accessing file '%s'. %s.\n", handle->path, strerror(errno)); 191 : return -1; @@ -255,27 +255,27 @@ 193 : } 194 : 195 : /* get the size of the existing data */ - 196 1639031 : handle->valid_size = handle->st.st_size; + 196 1639257 : handle->valid_size = handle->st.st_size; 197 : - 198 1639031 : ret = advise_open(&handle->advise, handle->f); - 199 1639026 : if (ret != 0) { + 198 1639257 : ret = advise_open(&handle->advise, handle->f); + 199 1639264 : if (ret != 0) { 200 : /* LCOV_EXCL_START */ 201 : out("Error advising file '%s'. %s.\n", handle->path, strerror(errno)); 202 : return -1; 203 : /* LCOV_EXCL_STOP */ 204 : } 205 : - 206 1639026 : return 0; + 206 1639264 : return 0; 207 : } 208 : - 209 4647511 : int handle_close(struct snapraid_handle* handle) + 209 4647370 : int handle_close(struct snapraid_handle* handle) 210 : { 211 : int ret; 212 : 213 : /* close if open */ - 214 4647511 : if (handle->f != -1) { - 215 2410343 : ret = close(handle->f); - 216 2410377 : if (ret != 0) { + 214 4647370 : if (handle->f != -1) { + 215 2410548 : ret = close(handle->f); + 216 2410591 : if (ret != 0) { 217 : /* LCOV_EXCL_START */ 218 : log_fatal("Error closing file '%s'. %s.\n", handle->file->sub, strerror(errno)); 219 : @@ -289,14 +289,14 @@ 227 : } 228 : 229 : /* reset the descriptor */ - 230 4647545 : handle->file = 0; - 231 4647545 : handle->f = -1; - 232 4647545 : handle->valid_size = 0; + 230 4647413 : handle->file = 0; + 231 4647413 : handle->f = -1; + 232 4647413 : handle->valid_size = 0; 233 : - 234 4647545 : return 0; + 234 4647413 : return 0; 235 : } 236 : - 237 5855349 : int handle_read(struct snapraid_handle* handle, block_off_t file_pos, unsigned char* block_buffer, unsigned block_size, fptr* out, fptr* out_missing) + 237 5856319 : int handle_read(struct snapraid_handle* handle, block_off_t file_pos, unsigned char* block_buffer, unsigned block_size, fptr* out, fptr* out_missing) 238 : { 239 : ssize_t read_ret; 240 : data_off_t offset; @@ -304,70 +304,70 @@ 242 : unsigned count; 243 : int ret; 244 : - 245 5855349 : offset = file_pos * (data_off_t)block_size; + 245 5856319 : offset = file_pos * (data_off_t)block_size; 246 : - 247 5855349 : if (!out_missing) - 248 5842393 : out_missing = out; + 247 5856319 : if (!out_missing) + 248 5843379 : out_missing = out; 249 : 250 : /* check if we are going to read only not initialized data */ - 251 5855349 : if (offset >= handle->valid_size) { + 251 5856319 : if (offset >= handle->valid_size) { 252 : /* if the file is missing, it's at 0 size, or it's rebuilt while reading */ - 253 433464 : if (offset == handle->valid_size || handle->valid_size == 0) - 254 432215 : out_missing("Reading data from missing file '%s' at offset %" PRIu64 ".\n", handle->path, offset); + 253 433352 : if (offset == handle->valid_size || handle->valid_size == 0) + 254 431991 : out_missing("Reading data from missing file '%s' at offset %" PRIu64 ".\n", handle->path, offset); 255 : else - 256 1249 : out("Reading missing data from file '%s' at offset %" PRIu64 ".\n", handle->path, offset); - 257 433464 : return -1; + 256 1361 : out("Reading missing data from file '%s' at offset %" PRIu64 ".\n", handle->path, offset); + 257 433352 : return -1; 258 : } 259 : - 260 5421885 : read_size = file_block_size(handle->file, file_pos, block_size); + 260 5422967 : read_size = file_block_size(handle->file, file_pos, block_size); 261 : - 262 5421858 : count = 0; + 262 5422979 : count = 0; 263 : do { 264 : /* read the full block to support O_DIRECT */ - 265 5430464 : read_ret = pread(handle->f, block_buffer + count, block_size - count, offset + count); - 266 5430098 : if (read_ret < 0) { + 265 5431676 : read_ret = pread(handle->f, block_buffer + count, block_size - count, offset + count); + 266 5431334 : if (read_ret < 0) { 267 : /* LCOV_EXCL_START */ 268 : out("Error reading file '%s' at offset %" PRIu64 " for size %u. %s.\n", handle->path, offset + count, block_size - count, strerror(errno)); 269 : return -1; 270 : /* LCOV_EXCL_STOP */ 271 : } - 272 5430098 : if (read_ret == 0) { - 273 8705 : out("Unexpected end of file '%s' at offset %" PRIu64 ". %s.\n", handle->path, offset, strerror(errno)); - 274 8705 : return -1; + 272 5431334 : if (read_ret == 0) { + 273 8919 : out("Unexpected end of file '%s' at offset %" PRIu64 ". %s.\n", handle->path, offset, strerror(errno)); + 274 8919 : return -1; 275 : } 276 : - 277 5421393 : count += read_ret; - 278 5421393 : } while (count < read_size); + 277 5422415 : count += read_ret; + 278 5422415 : } while (count < read_size); 279 : 280 : /* pad with 0 */ - 281 5412787 : if (read_size < block_size) { - 282 2188487 : memset(block_buffer + read_size, 0, block_size - read_size); + 281 5413718 : if (read_size < block_size) { + 282 2188617 : memset(block_buffer + read_size, 0, block_size - read_size); 283 : } 284 : - 285 5412787 : ret = advise_read(&handle->advise, handle->f, offset, block_size); - 286 5412784 : if (ret != 0) { + 285 5413718 : ret = advise_read(&handle->advise, handle->f, offset, block_size); + 286 5413674 : if (ret != 0) { 287 : /* LCOV_EXCL_START */ 288 : out("Error advising file '%s'. %s.\n", handle->path, strerror(errno)); 289 : return -1; 290 : /* LCOV_EXCL_STOP */ 291 : } 292 : - 293 5412784 : return read_size; + 293 5413674 : return read_size; 294 : } 295 : - 296 288562 : int handle_write(struct snapraid_handle* handle, block_off_t file_pos, unsigned char* block_buffer, unsigned block_size) + 296 288483 : int handle_write(struct snapraid_handle* handle, block_off_t file_pos, unsigned char* block_buffer, unsigned block_size) 297 : { 298 : ssize_t write_ret; 299 : data_off_t offset; 300 : unsigned write_size; 301 : int ret; 302 : - 303 288562 : offset = file_pos * (data_off_t)block_size; + 303 288483 : offset = file_pos * (data_off_t)block_size; 304 : - 305 288562 : write_size = file_block_size(handle->file, file_pos, block_size); + 305 288483 : write_size = file_block_size(handle->file, file_pos, block_size); 306 : - 307 288562 : write_ret = pwrite(handle->f, block_buffer, write_size, offset); - 308 288562 : if (write_ret != (ssize_t)write_size) { /* conversion is safe because block_size is always small */ + 307 288483 : write_ret = pwrite(handle->f, block_buffer, write_size, offset); + 308 288483 : if (write_ret != (ssize_t)write_size) { /* conversion is safe because block_size is always small */ 309 : /* LCOV_EXCL_START */ 310 : log_fatal("Error writing file '%s'. %s.\n", handle->path, strerror(errno)); 311 : return -1; @@ -375,39 +375,39 @@ 313 : } 314 : 315 : /* adjust the size of the valid data */ - 316 288562 : if (handle->valid_size < offset + write_size) { - 317 282510 : handle->valid_size = offset + write_size; + 316 288483 : if (handle->valid_size < offset + write_size) { + 317 282399 : handle->valid_size = offset + write_size; 318 : } 319 : - 320 288562 : ret = advise_write(&handle->advise, handle->f, offset, block_size); - 321 288562 : if (ret != 0) { + 320 288483 : ret = advise_write(&handle->advise, handle->f, offset, block_size); + 321 288483 : if (ret != 0) { 322 : /* LCOV_EXCL_START */ 323 : log_fatal("Error advising file '%s'. %s.\n", handle->path, strerror(errno)); 324 : return -1; 325 : /* LCOV_EXCL_STOP */ 326 : } 327 : - 328 288562 : return 0; + 328 288483 : return 0; 329 : } 330 : - 331 119431 : int handle_utime(struct snapraid_handle* handle) + 331 119471 : int handle_utime(struct snapraid_handle* handle) 332 : { 333 : int ret; 334 : 335 : /* do nothing if not opened */ - 336 119431 : if (handle->f == -1) + 336 119471 : if (handle->f == -1) 337 0 : return 0; 338 : - 339 119431 : ret = fmtime(handle->f, handle->file->mtime_sec, handle->file->mtime_nsec); + 339 119471 : ret = fmtime(handle->f, handle->file->mtime_sec, handle->file->mtime_nsec); 340 : - 341 119431 : if (ret != 0) { + 341 119471 : if (ret != 0) { 342 : /* LCOV_EXCL_START */ 343 : log_fatal("Error timing file '%s'. %s.\n", handle->file->sub, strerror(errno)); 344 : return -1; 345 : /* LCOV_EXCL_STOP */ 346 : } 347 : - 348 119431 : return 0; + 348 119471 : return 0; 349 : } 350 : 351 221 : struct snapraid_handle* handle_mapping(struct snapraid_state* state, unsigned* handlemax) diff --git a/cov/cmdline/import.c.func-sort-c.html b/cov/cmdline/import.c.func-sort-c.html index 9c1827ee..6b8d8469 100644 --- a/cov/cmdline/import.c.func-sort-c.html +++ b/cov/cmdline/import.c.func-sort-c.html @@ -61,11 +61,11 @@ import_block_hash - 657164 + 656904 state_import_fetch - 652692 + 652432 import_block_hash_compare diff --git a/cov/cmdline/import.c.func.html b/cov/cmdline/import.c.func.html index 8e60bbce..3c94845a 100644 --- a/cov/cmdline/import.c.func.html +++ b/cov/cmdline/import.c.func.html @@ -61,7 +61,7 @@ import_block_hash - 657164 + 656904 import_block_hash_compare @@ -89,7 +89,7 @@ state_import_fetch - 652692 + 652432
diff --git a/cov/cmdline/import.c.gcov.html b/cov/cmdline/import.c.gcov.html index f65eeec5..2c5e2abe 100644 --- a/cov/cmdline/import.c.gcov.html +++ b/cov/cmdline/import.c.gcov.html @@ -108,10 +108,10 @@ 46 : * Compute the hash of the hash for an import block. 47 : * We just use the first 32 bit of the hash itself. 48 : */ - 49 657164 : static inline tommy_uint32_t import_block_hash(const unsigned char* hash) + 49 656904 : static inline tommy_uint32_t import_block_hash(const unsigned char* hash) 50 : { 51 : /* the hash data is not aligned, and we cannot access it with a direct cast */ - 52 657164 : return hash[0] | ((uint32_t)hash[1] << 8) | ((uint32_t)hash[2] << 16) | ((uint32_t)hash[3] << 24); + 52 656904 : return hash[0] | ((uint32_t)hash[1] << 8) | ((uint32_t)hash[2] << 16) | ((uint32_t)hash[3] << 24); 53 : } 54 : 55 1750 : static void import_file(struct snapraid_state* state, const char* path, uint64_t size) @@ -207,24 +207,24 @@ 145 1750 : free(file); 146 1750 : } 147 : - 148 652692 : int state_import_fetch(struct snapraid_state* state, int rehash, struct snapraid_block* missing_block, unsigned char* buffer) + 148 652432 : int state_import_fetch(struct snapraid_state* state, int rehash, struct snapraid_block* missing_block, unsigned char* buffer) 149 : { 150 : struct snapraid_import_block* block; 151 : int ret; 152 : int f; - 153 652692 : const unsigned char* hash = missing_block->hash; - 154 652692 : unsigned block_size = state->block_size; + 153 652432 : const unsigned char* hash = missing_block->hash; + 154 652432 : unsigned block_size = state->block_size; 155 : unsigned read_size; 156 : unsigned char buffer_hash[HASH_MAX]; 157 : const char* path; 158 : - 159 652692 : if (rehash) { + 159 652432 : if (rehash) { 160 0 : block = tommy_hashdyn_search(&state->previmportset, import_block_prevhash_compare, hash, import_block_hash(hash)); 161 : } else { - 162 652692 : block = tommy_hashdyn_search(&state->importset, import_block_hash_compare, hash, import_block_hash(hash)); + 162 652432 : block = tommy_hashdyn_search(&state->importset, import_block_hash_compare, hash, import_block_hash(hash)); 163 : } - 164 652692 : if (!block) - 165 648220 : return -1; + 164 652432 : if (!block) + 165 647960 : return -1; 166 : 167 4472 : path = block->file->path; 168 4472 : read_size = block->size; diff --git a/cov/cmdline/index-sort-f.html b/cov/cmdline/index-sort-f.html index 598b0f01..41e4f2ef 100644 --- a/cov/cmdline/index-sort-f.html +++ b/cov/cmdline/index-sort-f.html @@ -31,9 +31,9 @@ lcov.info Lines: - 8598 - 9589 - 89.7 % + 8613 + 9548 + 90.2 % Date: @@ -122,10 +122,10 @@ parity.c -
85.8%85.8%
+
91.9%91.9%
- 85.8 % - 206 / 240 + 91.9 % + 217 / 236 94.7 % 18 / 19 @@ -292,10 +292,10 @@ dry.c -
72.7%72.7%
+
76.4%76.4%
- 72.7 % - 120 / 165 + 76.4 % + 120 / 157 100.0 % 5 / 5 @@ -312,10 +312,10 @@ scrub.c -
78.7%78.7%
+
80.5%80.5%
- 78.7 % - 281 / 357 + 80.5 % + 281 / 349 100.0 % 6 / 6 @@ -332,10 +332,10 @@ sync.c -
89.5%89.5%
+
91.9%91.9%
- 89.5 % - 502 / 561 + 91.9 % + 502 / 546 100.0 % 7 / 7 @@ -372,20 +372,20 @@ check.c -
90.8%90.8%
+
91.5%91.5%
- 90.8 % - 709 / 781 + 91.5 % + 709 / 775 100.0 % 9 / 9 snapraid.c -
91.1%91.1%
+
91.5%91.5%
- 91.1 % - 494 / 542 + 91.5 % + 496 / 542 100.0 % 9 / 9 @@ -402,10 +402,10 @@ scan.c -
89.2%89.2%
+
89.5%89.5%
- 89.2 % - 563 / 631 + 89.5 % + 565 / 631 100.0 % 23 / 23 diff --git a/cov/cmdline/index-sort-l.html b/cov/cmdline/index-sort-l.html index 6dc33db4..d6502fac 100644 --- a/cov/cmdline/index-sort-l.html +++ b/cov/cmdline/index-sort-l.html @@ -31,9 +31,9 @@ lcov.info Lines: - 8598 - 9589 - 89.7 % + 8613 + 9548 + 90.2 % Date: @@ -82,23 +82,13 @@ dry.c -
72.7%72.7%
+
76.4%76.4%
- 72.7 % - 120 / 165 + 76.4 % + 120 / 157 100.0 % 5 / 5 - - scrub.c - -
78.7%78.7%
- - 78.7 % - 281 / 357 - 100.0 % - 6 / 6 - support.c @@ -110,34 +100,24 @@ 60 / 62 - parity.c + scrub.c -
85.8%85.8%
+
80.5%80.5%
- 85.8 % - 206 / 240 - 94.7 % - 18 / 19 + 80.5 % + 281 / 349 + 100.0 % + 6 / 6 scan.c -
89.2%89.2%
- - 89.2 % - 563 / 631 - 100.0 % - 23 / 23 - - - sync.c - -
89.5%89.5%
+
89.5%89.5%
89.5 % - 502 / 561 + 565 / 631 100.0 % - 7 / 7 + 23 / 23 state.c @@ -169,16 +149,6 @@ 87.5 % 7 / 8 - - check.c - -
90.8%90.8%
- - 90.8 % - 709 / 781 - 100.0 % - 9 / 9 - stream.c @@ -200,15 +170,45 @@ 7 / 7 - snapraid.c + check.c -
91.1%91.1%
+
91.5%91.5%
- 91.1 % - 494 / 542 + 91.5 % + 709 / 775 100.0 % 9 / 9 + + snapraid.c + +
91.5%91.5%
+ + 91.5 % + 496 / 542 + 100.0 % + 9 / 9 + + + parity.c + +
91.9%91.9%
+ + 91.9 % + 217 / 236 + 94.7 % + 18 / 19 + + + sync.c + +
91.9%91.9%
+ + 91.9 % + 502 / 546 + 100.0 % + 7 / 7 + io.c diff --git a/cov/cmdline/index.html b/cov/cmdline/index.html index f74b2cb2..b4260d2c 100644 --- a/cov/cmdline/index.html +++ b/cov/cmdline/index.html @@ -31,9 +31,9 @@ lcov.info Lines: - 8598 - 9589 - 89.7 % + 8613 + 9548 + 90.2 % Date: @@ -72,10 +72,10 @@ check.c -
90.8%90.8%
+
91.5%91.5%
- 90.8 % - 709 / 781 + 91.5 % + 709 / 775 100.0 % 9 / 9 @@ -92,10 +92,10 @@ dry.c -
72.7%72.7%
+
76.4%76.4%
- 72.7 % - 120 / 165 + 76.4 % + 120 / 157 100.0 % 5 / 5 @@ -202,10 +202,10 @@ parity.c -
85.8%85.8%
+
91.9%91.9%
- 85.8 % - 206 / 240 + 91.9 % + 217 / 236 94.7 % 18 / 19 @@ -242,20 +242,20 @@ scan.c -
89.2%89.2%
+
89.5%89.5%
- 89.2 % - 563 / 631 + 89.5 % + 565 / 631 100.0 % 23 / 23 scrub.c -
78.7%78.7%
+
80.5%80.5%
- 78.7 % - 281 / 357 + 80.5 % + 281 / 349 100.0 % 6 / 6 @@ -282,10 +282,10 @@ snapraid.c -
91.1%91.1%
+
91.5%91.5%
- 91.1 % - 494 / 542 + 91.5 % + 496 / 542 100.0 % 9 / 9 @@ -372,10 +372,10 @@ sync.c -
89.5%89.5%
+
91.9%91.9%
- 89.5 % - 502 / 561 + 91.9 % + 502 / 546 100.0 % 7 / 7 diff --git a/cov/cmdline/io.c.func-sort-c.html b/cov/cmdline/io.c.func-sort-c.html index 5904027b..dde735d8 100644 --- a/cov/cmdline/io.c.func-sort-c.html +++ b/cov/cmdline/io.c.func-sort-c.html @@ -61,27 +61,27 @@ io_reader_step - 1162427 + 1163270 io_task_read_thread - 1081698 + 1082226 io_reader_worker - 1081680 + 1082209 io_data_read_thread - 870894 + 871422 io_writer_step - 553871 + 554398 io_parity_write_thread - 553420 + 553948 io_parity_read_thread @@ -89,27 +89,27 @@ io_position_next - 161997 + 162085 io_reader_sched - 161997 + 162085 io_read_next_thread - 145244 + 145332 io_writer_sched - 112401 + 112474 io_write_preset_thread - 110015 + 110103 io_write_next_thread - 110015 + 110103 io_task_read_mono @@ -137,11 +137,11 @@ io_writer_sched_empty - 2301 + 2316 io_reader_thread - 647 + 648 io_writer_thread diff --git a/cov/cmdline/io.c.func.html b/cov/cmdline/io.c.func.html index d5364ee0..75b86177 100644 --- a/cov/cmdline/io.c.func.html +++ b/cov/cmdline/io.c.func.html @@ -65,7 +65,7 @@ io_data_read_thread - 870894 + 871422 io_done @@ -89,11 +89,11 @@ io_parity_write_thread - 553420 + 553948 io_position_next - 161997 + 162085 io_read_next_mono @@ -101,23 +101,23 @@ io_read_next_thread - 145244 + 145332 io_reader_sched - 161997 + 162085 io_reader_step - 1162427 + 1163270 io_reader_thread - 647 + 648 io_reader_worker - 1081680 + 1082209 io_refresh_mono @@ -149,7 +149,7 @@ io_task_read_thread - 1081698 + 1082226 io_write_next_mono @@ -157,7 +157,7 @@ io_write_next_thread - 110015 + 110103 io_write_preset_mono @@ -165,19 +165,19 @@ io_write_preset_thread - 110015 + 110103 io_writer_sched - 112401 + 112474 io_writer_sched_empty - 2301 + 2316 io_writer_step - 553871 + 554398 io_writer_thread diff --git a/cov/cmdline/io.c.gcov.html b/cov/cmdline/io.c.gcov.html index 448aa441..295b5f22 100644 --- a/cov/cmdline/io.c.gcov.html +++ b/cov/cmdline/io.c.gcov.html @@ -84,103 +84,103 @@ 22 : /** 23 : * Get the next block position to process. 24 : */ - 25 161997 : static block_off_t io_position_next(struct snapraid_io* io) + 25 162085 : static block_off_t io_position_next(struct snapraid_io* io) 26 : { 27 : block_off_t blockcur; 28 : 29 : /* get the next position */ - 30 647430 : while (io->block_next < io->block_max && !io->block_is_enabled(io->block_arg, io->block_next)) - 31 323436 : ++io->block_next; + 30 647518 : while (io->block_next < io->block_max && !io->block_is_enabled(io->block_arg, io->block_next)) + 31 323348 : ++io->block_next; 32 : - 33 161997 : blockcur = io->block_next; + 33 162085 : blockcur = io->block_next; 34 : 35 : /* next block for the next call */ - 36 161997 : ++io->block_next; + 36 162085 : ++io->block_next; 37 : - 38 161997 : return blockcur; + 38 162085 : return blockcur; 39 : } 40 : 41 : /** 42 : * Setup the next pending task for all readers. 43 : */ - 44 161997 : static void io_reader_sched(struct snapraid_io* io, int task_index, block_off_t blockcur) + 44 162085 : static void io_reader_sched(struct snapraid_io* io, int task_index, block_off_t blockcur) 45 : { 46 : unsigned i; 47 : - 48 1354767 : for (i = 0; i < io->reader_max; ++i) { - 49 1192770 : struct snapraid_worker* worker = &io->reader_map[i]; - 50 1192770 : struct snapraid_task* task = &worker->task_map[task_index]; + 48 1355383 : for (i = 0; i < io->reader_max; ++i) { + 49 1193298 : struct snapraid_worker* worker = &io->reader_map[i]; + 50 1193298 : struct snapraid_task* task = &worker->task_map[task_index]; 51 : 52 : /* setup the new pending task */ - 53 1192770 : if (blockcur < io->block_max) - 54 1109820 : task->state = TASK_STATE_READY; + 53 1193298 : if (blockcur < io->block_max) + 54 1110348 : task->state = TASK_STATE_READY; 55 : else 56 82950 : task->state = TASK_STATE_EMPTY; 57 : - 58 1192770 : task->path[0] = 0; - 59 1192770 : if (worker->handle) - 60 971982 : task->disk = worker->handle->disk; + 58 1193298 : task->path[0] = 0; + 59 1193298 : if (worker->handle) + 60 972510 : task->disk = worker->handle->disk; 61 : else 62 220788 : task->disk = 0; - 63 1192770 : task->buffer = io->buffer_map[task_index][worker->buffer_skew + i]; - 64 1192770 : task->position = blockcur; - 65 1192770 : task->block = 0; - 66 1192770 : task->file = 0; - 67 1192770 : task->file_pos = 0; - 68 1192770 : task->read_size = 0; - 69 1192770 : task->is_timestamp_different = 0; + 63 1193298 : task->buffer = io->buffer_map[task_index][worker->buffer_skew + i]; + 64 1193298 : task->position = blockcur; + 65 1193298 : task->block = 0; + 66 1193298 : task->file = 0; + 67 1193298 : task->file_pos = 0; + 68 1193298 : task->read_size = 0; + 69 1193298 : task->is_timestamp_different = 0; 70 : } - 71 161997 : } + 71 162085 : } 72 : 73 : /** 74 : * Setup the next pending task for all writers. 75 : */ - 76 112401 : static void io_writer_sched(struct snapraid_io* io, int task_index, block_off_t blockcur) + 76 112474 : static void io_writer_sched(struct snapraid_io* io, int task_index, block_off_t blockcur) 77 : { 78 : unsigned i; 79 : - 80 656702 : for (i = 0; i < io->writer_max; ++i) { - 81 544301 : struct snapraid_worker* worker = &io->writer_map[i]; - 82 544301 : struct snapraid_task* task = &worker->task_map[task_index]; + 80 657213 : for (i = 0; i < io->writer_max; ++i) { + 81 544739 : struct snapraid_worker* worker = &io->writer_map[i]; + 82 544739 : struct snapraid_task* task = &worker->task_map[task_index]; 83 : 84 : /* setup the new pending task */ - 85 544301 : task->state = TASK_STATE_READY; - 86 544301 : task->path[0] = 0; - 87 544301 : task->disk = 0; - 88 544301 : task->buffer = io->buffer_map[task_index][worker->buffer_skew + i]; - 89 544301 : task->position = blockcur; - 90 544301 : task->block = 0; - 91 544301 : task->file = 0; - 92 544301 : task->file_pos = 0; - 93 544301 : task->read_size = 0; - 94 544301 : task->is_timestamp_different = 0; + 85 544739 : task->state = TASK_STATE_READY; + 86 544739 : task->path[0] = 0; + 87 544739 : task->disk = 0; + 88 544739 : task->buffer = io->buffer_map[task_index][worker->buffer_skew + i]; + 89 544739 : task->position = blockcur; + 90 544739 : task->block = 0; + 91 544739 : task->file = 0; + 92 544739 : task->file_pos = 0; + 93 544739 : task->read_size = 0; + 94 544739 : task->is_timestamp_different = 0; 95 : } - 96 112401 : } + 96 112474 : } 97 : 98 : /** 99 : * Setup an empty next pending task for all writers. 100 : */ - 101 2301 : static void io_writer_sched_empty(struct snapraid_io* io, int task_index, block_off_t blockcur) + 101 2316 : static void io_writer_sched_empty(struct snapraid_io* io, int task_index, block_off_t blockcur) 102 : { 103 : unsigned i; 104 : - 105 16107 : for (i = 0; i < io->writer_max; ++i) { - 106 13806 : struct snapraid_worker* worker = &io->writer_map[i]; - 107 13806 : struct snapraid_task* task = &worker->task_map[task_index]; + 105 16212 : for (i = 0; i < io->writer_max; ++i) { + 106 13896 : struct snapraid_worker* worker = &io->writer_map[i]; + 107 13896 : struct snapraid_task* task = &worker->task_map[task_index]; 108 : 109 : /* setup the new pending task */ - 110 13806 : task->state = TASK_STATE_EMPTY; - 111 13806 : task->path[0] = 0; - 112 13806 : task->disk = 0; - 113 13806 : task->buffer = 0; - 114 13806 : task->position = blockcur; - 115 13806 : task->block = 0; - 116 13806 : task->file = 0; - 117 13806 : task->file_pos = 0; - 118 13806 : task->read_size = 0; - 119 13806 : task->is_timestamp_different = 0; + 110 13896 : task->state = TASK_STATE_EMPTY; + 111 13896 : task->path[0] = 0; + 112 13896 : task->disk = 0; + 113 13896 : task->buffer = 0; + 114 13896 : task->position = blockcur; + 115 13896 : task->block = 0; + 116 13896 : task->file = 0; + 117 13896 : task->file_pos = 0; + 118 13896 : task->read_size = 0; + 119 13896 : task->is_timestamp_different = 0; 120 : } - 121 2301 : } + 121 2316 : } 122 : 123 : /*****************************************************************************/ 124 : /* mono thread */ @@ -331,55 +331,55 @@ 269 : * 270 : * This is the synchronization point for workers with the io. 271 : */ - 272 1162427 : static struct snapraid_task* io_reader_step(struct snapraid_worker* worker) + 272 1163270 : static struct snapraid_task* io_reader_step(struct snapraid_worker* worker) 273 : { - 274 1162427 : struct snapraid_io* io = worker->io; + 274 1163270 : struct snapraid_io* io = worker->io; 275 : 276 : /* the synchronization is protected by the io mutex */ - 277 1162427 : thread_mutex_lock(&io->io_mutex); + 277 1163270 : thread_mutex_lock(&io->io_mutex); 278 : 279 : while (1) { 280 : unsigned next_index; 281 : 282 : /* check if the worker has to exit */ 283 : /* even if there is work to do */ - 284 2113405 : if (io->done) { + 284 2115537 : if (io->done) { 285 648 : thread_mutex_unlock(&io->io_mutex); 286 648 : return 0; 287 : } 288 : 289 : /* get the next pending task */ - 290 2112757 : next_index = (worker->index + 1) % io->io_max; + 290 2114889 : next_index = (worker->index + 1) % io->io_max; 291 : 292 : /* if the queue of pending tasks is not empty */ - 293 2112757 : if (next_index != io->reader_index) { + 293 2114889 : if (next_index != io->reader_index) { 294 : struct snapraid_task* task; 295 : 296 : /* the index that the IO may be waiting for */ - 297 1162458 : unsigned waiting_index = io->reader_index; + 297 1163467 : unsigned waiting_index = io->reader_index; 298 : 299 : /* the index that worker just completed */ - 300 1162458 : unsigned done_index = worker->index; + 300 1163467 : unsigned done_index = worker->index; 301 : 302 : /* get the new working task */ - 303 1162458 : worker->index = next_index; - 304 1162458 : task = &worker->task_map[worker->index]; + 303 1163467 : worker->index = next_index; + 304 1163467 : task = &worker->task_map[worker->index]; 305 : 306 : /* if the just completed task is at this index */ - 307 1162458 : if (done_index == waiting_index) { + 307 1163467 : if (done_index == waiting_index) { 308 : /* notify the IO that a new read is complete */ - 309 2144 : thread_cond_signal_and_unlock(&io->read_done, &io->io_mutex); + 309 1460 : thread_cond_signal_and_unlock(&io->read_done, &io->io_mutex); 310 : } else { - 311 1160314 : thread_mutex_unlock(&io->io_mutex); + 311 1162007 : thread_mutex_unlock(&io->io_mutex); 312 : } 313 : 314 : /* return the new task */ - 315 1162363 : return task; + 315 1163329 : return task; 316 : } 317 : 318 : /* otherwise wait for a read_sched event */ - 319 950299 : thread_cond_wait(&io->read_sched, &io->io_mutex); - 320 950299 : } + 319 951422 : thread_cond_wait(&io->read_sched, &io->io_mutex); + 320 951422 : } 321 : } 322 : 323 : /** @@ -387,61 +387,61 @@ 325 : * 326 : * This is the synchronization point for workers with the io. 327 : */ - 328 553871 : static struct snapraid_task* io_writer_step(struct snapraid_worker* worker, int state) + 328 554398 : static struct snapraid_task* io_writer_step(struct snapraid_worker* worker, int state) 329 : { - 330 553871 : struct snapraid_io* io = worker->io; + 330 554398 : struct snapraid_io* io = worker->io; 331 : int error_index; 332 : 333 : /* the synchronization is protected by the io mutex */ - 334 553871 : thread_mutex_lock(&io->io_mutex); + 334 554398 : thread_mutex_lock(&io->io_mutex); 335 : 336 : /* counts the number of errors in the global state */ - 337 553882 : error_index = state - IO_WRITER_ERROR_BASE; - 338 553882 : if (error_index >= 0 && error_index < IO_WRITER_ERROR_MAX) + 337 554410 : error_index = state - IO_WRITER_ERROR_BASE; + 338 554410 : if (error_index >= 0 && error_index < IO_WRITER_ERROR_MAX) 339 0 : ++io->writer_error[error_index]; 340 : 341 : while (1) { 342 : unsigned next_index; 343 : 344 : /* get the next pending task */ - 345 630858 : next_index = (worker->index + 1) % io->io_max; + 345 631068 : next_index = (worker->index + 1) % io->io_max; 346 : 347 : /* if the queue of pending tasks is not empty */ - 348 630858 : if (next_index != io->writer_index) { + 348 631068 : if (next_index != io->writer_index) { 349 : struct snapraid_task* task; 350 : 351 : /* the index that the IO may be waiting for */ - 352 553420 : unsigned waiting_index = (io->writer_index + 1) % io->io_max; + 352 553948 : unsigned waiting_index = (io->writer_index + 1) % io->io_max; 353 : 354 : /* the index that worker just completed */ - 355 553420 : unsigned done_index = worker->index; + 355 553948 : unsigned done_index = worker->index; 356 : 357 : /* get the new working task */ - 358 553420 : worker->index = next_index; - 359 553420 : task = &worker->task_map[worker->index]; + 358 553948 : worker->index = next_index; + 359 553948 : task = &worker->task_map[worker->index]; 360 : 361 : /* if the just completed task is at this index */ - 362 553420 : if (done_index == waiting_index) { + 362 553948 : if (done_index == waiting_index) { 363 : /* notify the IO that a new write is complete */ - 364 82404 : thread_cond_signal_and_unlock(&io->write_done, &io->io_mutex); + 364 81705 : thread_cond_signal_and_unlock(&io->write_done, &io->io_mutex); 365 : } else { - 366 471016 : thread_mutex_unlock(&io->io_mutex); + 366 472243 : thread_mutex_unlock(&io->io_mutex); 367 : } 368 : 369 : /* return the new task */ - 370 553404 : return task; + 370 553938 : return task; 371 : } 372 : 373 : /* check if the worker has to exit */ 374 : /* but only if there is no work to do */ - 375 77438 : if (io->done) { + 375 77120 : if (io->done) { 376 462 : thread_mutex_unlock(&io->io_mutex); 377 462 : return 0; 378 : } 379 : 380 : /* otherwise wait for a write_sched event */ - 381 76976 : thread_cond_wait(&io->write_sched, &io->io_mutex); - 382 76976 : } + 381 76658 : thread_cond_wait(&io->write_sched, &io->io_mutex); + 382 76658 : } 383 : } 384 : 385 : /** @@ -449,87 +449,87 @@ 387 : * 388 : * This is the synchronization point for workers with the io. 389 : */ - 390 145244 : static block_off_t io_read_next_thread(struct snapraid_io* io, void*** buffer) + 390 145332 : static block_off_t io_read_next_thread(struct snapraid_io* io, void*** buffer) 391 : { 392 : block_off_t blockcur_schedule; 393 : block_off_t blockcur_caller; 394 : unsigned i; 395 : 396 : /* get the next parity position to process */ - 397 145244 : blockcur_schedule = io_position_next(io); + 397 145332 : blockcur_schedule = io_position_next(io); 398 : 399 : /* ensure that all data/parity was read */ - 400 145244 : assert(io->reader_list[0] == io->reader_max); + 400 145332 : assert(io->reader_list[0] == io->reader_max); 401 : 402 : /* setup the list of workers to process */ - 403 1372834 : for (i = 0; i <= io->reader_max; ++i) - 404 1227590 : io->reader_list[i] = i; + 403 1373538 : for (i = 0; i <= io->reader_max; ++i) + 404 1228206 : io->reader_list[i] = i; 405 : 406 : /* the synchronization is protected by the io mutex */ - 407 145244 : thread_mutex_lock(&io->io_mutex); + 407 145332 : thread_mutex_lock(&io->io_mutex); 408 : 409 : /* schedule the next read */ - 410 145244 : io_reader_sched(io, io->reader_index, blockcur_schedule); + 410 145332 : io_reader_sched(io, io->reader_index, blockcur_schedule); 411 : 412 : /* set the index for the tasks to return to the caller */ - 413 145244 : io->reader_index = (io->reader_index + 1) % io->io_max; + 413 145332 : io->reader_index = (io->reader_index + 1) % io->io_max; 414 : 415 : /* get the position to operate at high level from one task */ - 416 145244 : blockcur_caller = io->reader_map[0].task_map[io->reader_index].position; + 416 145332 : blockcur_caller = io->reader_map[0].task_map[io->reader_index].position; 417 : 418 : /* set the buffer to use */ - 419 145244 : *buffer = io->buffer_map[io->reader_index]; + 419 145332 : *buffer = io->buffer_map[io->reader_index]; 420 : 421 : /* signal all the workers that there is a new pending task */ - 422 145244 : thread_cond_broadcast_and_unlock(&io->read_sched, &io->io_mutex); + 422 145332 : thread_cond_broadcast_and_unlock(&io->read_sched, &io->io_mutex); 423 : - 424 145244 : return blockcur_caller; + 424 145332 : return blockcur_caller; 425 : } 426 : - 427 110015 : static void io_write_preset_thread(struct snapraid_io* io, block_off_t blockcur, int skip) + 427 110103 : static void io_write_preset_thread(struct snapraid_io* io, block_off_t blockcur, int skip) 428 : { 429 : (void)io; 430 : (void)blockcur; 431 : (void)skip; - 432 110015 : } + 432 110103 : } 433 : - 434 110015 : static void io_write_next_thread(struct snapraid_io* io, block_off_t blockcur, int skip, int* writer_error) + 434 110103 : static void io_write_next_thread(struct snapraid_io* io, block_off_t blockcur, int skip, int* writer_error) 435 : { 436 : unsigned i; 437 : 438 : /* ensure that all parity was written */ - 439 110015 : assert(io->writer_list[0] == io->writer_max); + 439 110103 : assert(io->writer_list[0] == io->writer_max); 440 : 441 : /* setup the list of workers to process */ - 442 773450 : for (i = 0; i <= io->writer_max; ++i) - 443 663435 : io->writer_list[i] = i; + 442 774154 : for (i = 0; i <= io->writer_max; ++i) + 443 664051 : io->writer_list[i] = i; 444 : 445 : /* the synchronization is protected by the io mutex */ - 446 110015 : thread_mutex_lock(&io->io_mutex); + 446 110103 : thread_mutex_lock(&io->io_mutex); 447 : 448 : /* report errors */ - 449 550075 : for (i = 0; i < IO_WRITER_ERROR_MAX; ++i) { - 450 440060 : writer_error[i] = io->writer_error[i]; - 451 440060 : io->writer_error[i] = 0; + 449 550515 : for (i = 0; i < IO_WRITER_ERROR_MAX; ++i) { + 450 440412 : writer_error[i] = io->writer_error[i]; + 451 440412 : io->writer_error[i] = 0; 452 : } 453 : - 454 110015 : if (skip) { + 454 110103 : if (skip) { 455 : /* skip the next write */ - 456 2301 : io_writer_sched_empty(io, io->writer_index, blockcur); + 456 2316 : io_writer_sched_empty(io, io->writer_index, blockcur); 457 : } else { 458 : /* schedule the next write */ - 459 107714 : io_writer_sched(io, io->writer_index, blockcur); + 459 107787 : io_writer_sched(io, io->writer_index, blockcur); 460 : } 461 : 462 : /* at this point the writers must be in sync with the readers */ - 463 110015 : assert(io->writer_index == io->reader_index); + 463 110103 : assert(io->writer_index == io->reader_index); 464 : 465 : /* set the index to be used for the next write */ - 466 110015 : io->writer_index = (io->writer_index + 1) % io->io_max; + 466 110103 : io->writer_index = (io->writer_index + 1) % io->io_max; 467 : 468 : /* signal all the workers that there is a new pending task */ - 469 110015 : thread_cond_broadcast_and_unlock(&io->write_sched, &io->io_mutex); - 470 110015 : } + 469 110103 : thread_cond_broadcast_and_unlock(&io->write_sched, &io->io_mutex); + 470 110103 : } 471 : 472 0 : static void io_refresh_thread(struct snapraid_io* io) 473 : { @@ -577,18 +577,18 @@ 515 0 : thread_mutex_unlock(&io->io_mutex); 516 0 : } 517 : - 518 1081698 : static struct snapraid_task* io_task_read_thread(struct snapraid_io* io, unsigned base, unsigned count, unsigned* pos, unsigned* waiting_map, unsigned* waiting_mac) + 518 1082226 : static struct snapraid_task* io_task_read_thread(struct snapraid_io* io, unsigned base, unsigned count, unsigned* pos, unsigned* waiting_map, unsigned* waiting_mac) 519 : { 520 : unsigned waiting_cycle; 521 : 522 : /* count the waiting cycle */ - 523 1081698 : waiting_cycle = 0; + 523 1082226 : waiting_cycle = 0; 524 : 525 : /* clear the waiting indexes */ - 526 1081698 : *waiting_mac = 0; + 526 1082226 : *waiting_mac = 0; 527 : 528 : /* the synchronization is protected by the io mutex */ - 529 1081698 : thread_mutex_lock(&io->io_mutex); + 529 1082226 : thread_mutex_lock(&io->io_mutex); 530 : 531 : while (1) { 532 : unsigned char* let; @@ -597,67 +597,67 @@ 535 : /* get the index the IO is using */ 536 : /* we must ensure that this index has not a read in progress */ 537 : /* to avoid a concurrent access */ - 538 1083699 : busy_index = io->reader_index; + 538 1083535 : busy_index = io->reader_index; 539 : 540 : /* search for a worker that has already finished */ - 541 1083699 : let = &io->reader_list[0]; + 541 1083535 : let = &io->reader_list[0]; 542 : while (1) { - 543 1091880 : unsigned i = *let; + 543 1090052 : unsigned i = *let; 544 : 545 : /* if we are at the end */ - 546 1091880 : if (i == io->reader_max) - 547 2001 : break; + 546 1090052 : if (i == io->reader_max) + 547 1309 : break; 548 : 549 : /* if it's in range */ - 550 1089879 : if (base <= i && i < base + count) { + 550 1088743 : if (base <= i && i < base + count) { 551 : struct snapraid_worker* worker; 552 : 553 : /* if it's the first cycle */ - 554 1088355 : if (waiting_cycle == 0) { + 554 1087753 : if (waiting_cycle == 0) { 555 : /* store the waiting indexes */ - 556 1085928 : waiting_map[(*waiting_mac)++] = i - base; + 556 1086091 : waiting_map[(*waiting_mac)++] = i - base; 557 : } 558 : - 559 1088355 : worker = &io->reader_map[i]; + 559 1087753 : worker = &io->reader_map[i]; 560 : 561 : /* if the worker has finished this index */ - 562 1088355 : if (busy_index != worker->index) { + 562 1087753 : if (busy_index != worker->index) { 563 : struct snapraid_task* task; 564 : - 565 1081698 : task = &worker->task_map[io->reader_index]; + 565 1082226 : task = &worker->task_map[io->reader_index]; 566 : - 567 1081698 : thread_mutex_unlock(&io->io_mutex); + 567 1082226 : thread_mutex_unlock(&io->io_mutex); 568 : 569 : /* mark the worker as processed */ 570 : /* setting the previous one to point at the next one */ - 571 1081698 : *let = io->reader_list[i + 1]; + 571 1082226 : *let = io->reader_list[i + 1]; 572 : 573 : /* return the position */ - 574 1081698 : *pos = i - base; + 574 1082226 : *pos = i - base; 575 : 576 : /* on the first cycle, no one is waiting */ - 577 1081698 : if (waiting_cycle == 0) - 578 1079732 : *waiting_mac = 0; + 577 1082226 : if (waiting_cycle == 0) + 578 1080944 : *waiting_mac = 0; 579 : - 580 2163396 : return task; + 580 2164452 : return task; 581 : } 582 : } 583 : 584 : /* next position to check */ - 585 8181 : let = &io->reader_list[i + 1]; - 586 8181 : } + 585 6517 : let = &io->reader_list[i + 1]; + 586 6517 : } 587 : 588 : /* if no worker is ready, wait for an event */ - 589 2001 : thread_cond_wait(&io->read_done, &io->io_mutex); + 589 1309 : thread_cond_wait(&io->read_done, &io->io_mutex); 590 : 591 : /* count the cycles */ - 592 2001 : ++waiting_cycle; - 593 2001 : } + 592 1309 : ++waiting_cycle; + 593 1309 : } 594 : } 595 : - 596 870894 : static struct snapraid_task* io_data_read_thread(struct snapraid_io* io, unsigned* pos, unsigned* waiting_map, unsigned* waiting_mac) + 596 871422 : static struct snapraid_task* io_data_read_thread(struct snapraid_io* io, unsigned* pos, unsigned* waiting_map, unsigned* waiting_mac) 597 : { - 598 870894 : return io_task_read_thread(io, io->data_base, io->data_count, pos, waiting_map, waiting_mac); + 598 871422 : return io_task_read_thread(io, io->data_base, io->data_count, pos, waiting_map, waiting_mac); 599 : } 600 : 601 210804 : static struct snapraid_task* io_parity_read_thread(struct snapraid_io* io, unsigned* pos, unsigned* waiting_map, unsigned* waiting_mac) @@ -665,18 +665,18 @@ 603 210804 : return io_task_read_thread(io, io->parity_base, io->parity_count, pos, waiting_map, waiting_mac); 604 : } 605 : - 606 553420 : static void io_parity_write_thread(struct snapraid_io* io, unsigned* pos, unsigned* waiting_map, unsigned* waiting_mac) + 606 553948 : static void io_parity_write_thread(struct snapraid_io* io, unsigned* pos, unsigned* waiting_map, unsigned* waiting_mac) 607 : { 608 : unsigned waiting_cycle; 609 : 610 : /* count the waiting cycle */ - 611 553420 : waiting_cycle = 0; + 611 553948 : waiting_cycle = 0; 612 : 613 : /* clear the waiting indexes */ - 614 553420 : *waiting_mac = 0; + 614 553948 : *waiting_mac = 0; 615 : 616 : /* the synchronization is protected by the io mutex */ - 617 553420 : thread_mutex_lock(&io->io_mutex); + 617 553948 : thread_mutex_lock(&io->io_mutex); 618 : 619 : while (1) { 620 : unsigned char* let; @@ -687,96 +687,96 @@ 625 : /* to avoid a concurrent access */ 626 : /* note that we are already sure that a write is not in progress */ 627 : /* at the index the IO is using at now */ - 628 619337 : busy_index = (io->writer_index + 1) % io->io_max; + 628 619618 : busy_index = (io->writer_index + 1) % io->io_max; 629 : 630 : /* search for a worker that has already finished */ - 631 619337 : let = &io->writer_list[0]; + 631 619618 : let = &io->writer_list[0]; 632 : while (1) { - 633 866114 : unsigned i = *let; + 633 802324 : unsigned i = *let; 634 : struct snapraid_worker* worker; 635 : 636 : /* if we are at the end */ - 637 866114 : if (i == io->writer_max) - 638 65917 : break; + 637 802324 : if (i == io->writer_max) + 638 65670 : break; 639 : 640 : /* if it's the first cycle */ - 641 800197 : if (waiting_cycle == 0) { + 641 736654 : if (waiting_cycle == 0) { 642 : /* store the waiting indexes */ - 643 733517 : waiting_map[(*waiting_mac)++] = i; + 643 670497 : waiting_map[(*waiting_mac)++] = i; 644 : } 645 : - 646 800197 : worker = &io->writer_map[i]; + 646 736654 : worker = &io->writer_map[i]; 647 : 648 : /* the two indexes cannot be equal */ - 649 800197 : assert(io->writer_index != worker->index); + 649 736654 : assert(io->writer_index != worker->index); 650 : 651 : /* if the worker has finished this index */ - 652 800197 : if (busy_index != worker->index) { - 653 553420 : thread_mutex_unlock(&io->io_mutex); + 652 736654 : if (busy_index != worker->index) { + 653 553948 : thread_mutex_unlock(&io->io_mutex); 654 : 655 : /* mark the worker as processed */ 656 : /* setting the previous one to point at the next one */ - 657 553420 : *let = io->writer_list[i + 1]; + 657 553948 : *let = io->writer_list[i + 1]; 658 : 659 : /* return the position */ - 660 553420 : *pos = i; + 660 553948 : *pos = i; 661 : 662 : /* on the first cycle, no one is waiting */ - 663 553420 : if (waiting_cycle == 0) - 664 487503 : *waiting_mac = 0; + 663 553948 : if (waiting_cycle == 0) + 664 488278 : *waiting_mac = 0; 665 : - 666 1106840 : return; + 666 1107896 : return; 667 : } 668 : 669 : /* next position to check */ - 670 246777 : let = &io->writer_list[i + 1]; - 671 246777 : } + 670 182706 : let = &io->writer_list[i + 1]; + 671 182706 : } 672 : 673 : /* if no worker is ready, wait for an event */ - 674 65917 : thread_cond_wait(&io->write_done, &io->io_mutex); + 674 65670 : thread_cond_wait(&io->write_done, &io->io_mutex); 675 : 676 : /* count the cycles */ - 677 65917 : ++waiting_cycle; - 678 65917 : } + 677 65670 : ++waiting_cycle; + 678 65670 : } 679 : } 680 : - 681 1081680 : static void io_reader_worker(struct snapraid_worker* worker, struct snapraid_task* task) + 681 1082209 : static void io_reader_worker(struct snapraid_worker* worker, struct snapraid_task* task) 682 : { 683 : /* if we reached the end */ - 684 1081680 : if (task->position >= worker->io->block_max) { + 684 1082209 : if (task->position >= worker->io->block_max) { 685 : /* complete a dummy task */ 686 120 : task->state = TASK_STATE_EMPTY; 687 : } else { - 688 1081560 : worker->func(worker, task); + 688 1082089 : worker->func(worker, task); 689 : } - 690 1081228 : } + 690 1081822 : } 691 : - 692 647 : static void* io_reader_thread(void* arg) + 692 648 : static void* io_reader_thread(void* arg) 693 : { - 694 647 : struct snapraid_worker* worker = arg; + 694 648 : struct snapraid_worker* worker = arg; 695 : 696 : /* force completion of the first task */ - 697 647 : io_reader_worker(worker, &worker->task_map[0]); + 697 648 : io_reader_worker(worker, &worker->task_map[0]); 698 : 699 : while (1) { 700 : struct snapraid_task* task; 701 : 702 : /* get the new task */ - 703 1162533 : task = io_reader_step(worker); + 703 1163504 : task = io_reader_step(worker); 704 : 705 : /* if no task, it means to exit */ - 706 1162963 : if (!task) + 706 1163910 : if (!task) 707 648 : break; 708 : 709 : /* nothing more to do */ - 710 1162315 : if (task->state == TASK_STATE_EMPTY) - 711 81255 : continue; + 710 1163262 : if (task->state == TASK_STATE_EMPTY) + 711 81670 : continue; 712 : - 713 1081060 : assert(task->state == TASK_STATE_READY); + 713 1081592 : assert(task->state == TASK_STATE_READY); 714 : 715 : /* work on the assigned task */ - 716 1081060 : io_reader_worker(worker, task); - 717 1161887 : } + 716 1081592 : io_reader_worker(worker, task); + 717 1162859 : } 718 : 719 648 : return 0; 720 : } @@ -790,26 +790,26 @@ 728 : struct snapraid_task* task; 729 : 730 : /* get the new task */ - 731 553873 : task = io_writer_step(worker, latest_state); + 731 554402 : task = io_writer_step(worker, latest_state); 732 : 733 : /* if no task, it means to exit */ - 734 553876 : if (!task) + 734 554405 : if (!task) 735 462 : break; 736 : 737 : /* nothing more to do */ - 738 553414 : if (task->state == TASK_STATE_EMPTY) { - 739 13808 : latest_state = TASK_STATE_DONE; - 740 13808 : continue; + 738 553943 : if (task->state == TASK_STATE_EMPTY) { + 739 13898 : latest_state = TASK_STATE_DONE; + 740 13898 : continue; 741 : } 742 : - 743 539606 : assert(task->state == TASK_STATE_READY); + 743 540045 : assert(task->state == TASK_STATE_READY); 744 : 745 : /* work on the assigned task */ - 746 539606 : worker->func(worker, task); + 746 540045 : worker->func(worker, task); 747 : 748 : /* save the resulting state */ - 749 539603 : latest_state = task->state; - 750 553411 : } + 749 540042 : latest_state = task->state; + 750 553940 : } 751 : 752 462 : return 0; 753 : } diff --git a/cov/cmdline/mktest.c.func-sort-c.html b/cov/cmdline/mktest.c.func-sort-c.html index 27d6466e..50149ba0 100644 --- a/cov/cmdline/mktest.c.func-sort-c.html +++ b/cov/cmdline/mktest.c.func-sort-c.html @@ -61,23 +61,23 @@ rnd - 56057797 + 56068924 rndnz - 55646605 + 55657385 file_cmp - 146556 + 146572 rndnz_range - 32690 + 32675 rnd_name - 26841 + 26852 cmd_generate @@ -93,19 +93,19 @@ cmd_write - 6226 + 6254 cmd_append - 3224 - - - cmd_delete - 3222 + 3181 cmd_truncate - 3082 + 3162 + + + cmd_delete + 3155 cmd_damage @@ -121,7 +121,7 @@ cmd_generate_symlink - 932 + 943 main diff --git a/cov/cmdline/mktest.c.func.html b/cov/cmdline/mktest.c.func.html index 18bde35a..8869dfc5 100644 --- a/cov/cmdline/mktest.c.func.html +++ b/cov/cmdline/mktest.c.func.html @@ -61,7 +61,7 @@ cmd_append - 3224 + 3181 cmd_change @@ -73,7 +73,7 @@ cmd_delete - 3222 + 3155 cmd_generate @@ -85,15 +85,15 @@ cmd_generate_symlink - 932 + 943 cmd_truncate - 3082 + 3162 cmd_write - 6226 + 6254 fallback @@ -101,7 +101,7 @@ file_cmp - 146556 + 146572 help @@ -113,15 +113,15 @@ rnd - 56057797 + 56068924 rnd_name - 26841 + 26852 rndnz - 55646605 + 55657385 rndnz_damage @@ -129,7 +129,7 @@ rndnz_range - 32690 + 32675
diff --git a/cov/cmdline/mktest.c.gcov.html b/cov/cmdline/mktest.c.gcov.html index 4c422f75..9de78039 100644 --- a/cov/cmdline/mktest.c.gcov.html +++ b/cov/cmdline/mktest.c.gcov.html @@ -89,28 +89,28 @@ 27 : */ 28 : unsigned long long seed = 0; 29 : - 30 56057797 : unsigned rnd(unsigned max) + 30 56068924 : unsigned rnd(unsigned max) 31 : { - 32 56057797 : seed = seed * 6364136223846793005LL + 1442695040888963407LL; + 32 56068924 : seed = seed * 6364136223846793005LL + 1442695040888963407LL; 33 : - 34 56057797 : return (seed >> 32) % max; + 34 56068924 : return (seed >> 32) % max; 35 : } 36 : - 37 55646605 : unsigned rndnz(unsigned max) + 37 55657385 : unsigned rndnz(unsigned max) 38 : { - 39 55646605 : if (max <= 1) + 39 55657385 : if (max <= 1) 40 2831 : return 1; 41 : else - 42 55643774 : return rnd(max - 1) + 1; + 42 55654554 : return rnd(max - 1) + 1; 43 : } 44 : - 45 32690 : void rndnz_range(unsigned char* data, int size) + 45 32675 : void rndnz_range(unsigned char* data, int size) 46 : { 47 : int i; 48 : - 49 55672532 : for (i = 0; i < size; ++i) - 50 55639842 : data[i] = rndnz(256); - 51 32690 : } + 49 55683297 : for (i = 0; i < size; ++i) + 50 55650622 : data[i] = rndnz(256); + 51 32675 : } 52 : 53 1821 : void rndnz_damage(unsigned char* data, int size) 54 : { @@ -131,23 +131,23 @@ 69 : char CHARSET[] = "qwertyuiopasdfghjklzxcvbnm1234567890 .-+"; 70 : #define CHARSET_LEN (sizeof(CHARSET) - 1) 71 : - 72 26841 : void rnd_name(char* file) + 72 26852 : void rnd_name(char* file) 73 : { - 74 26841 : int l = 1 + rnd(20); + 74 26852 : int l = 1 + rnd(20); 75 : - 76 335354 : while (l) { - 77 281672 : *file++ = CHARSET[rnd(CHARSET_LEN)]; - 78 281672 : --l; + 76 335716 : while (l) { + 77 282012 : *file++ = CHARSET[rnd(CHARSET_LEN)]; + 78 282012 : --l; 79 : } - 80 26841 : *file = 0; - 81 26841 : } + 80 26852 : *file = 0; + 81 26852 : } 82 : 83 : /****************************************************************************/ 84 : /* file */ 85 : - 86 146556 : int file_cmp(const void* a, const void* b) + 86 146572 : int file_cmp(const void* a, const void* b) 87 : { - 88 146556 : return strcmp(a, b); + 88 146572 : return strcmp(a, b); 89 : } 90 : 91 1821 : int fallback(int f, struct stat* st) @@ -259,11 +259,11 @@ 197 : * Create a symlink. 198 : * - If the file already exists, it's removed. 199 : */ - 200 932 : void cmd_generate_symlink(const char* path, const char* linkto) + 200 943 : void cmd_generate_symlink(const char* path, const char* linkto) 201 : { 202 : /* remove the existing file/symlink if any */ - 203 932 : if (remove(path) != 0) { - 204 911 : if (errno != ENOENT) { + 203 943 : if (remove(path) != 0) { + 204 922 : if (errno != ENOENT) { 205 : /* LCOV_EXCL_START */ 206 : log_fatal("Error removing file %s\n", path); 207 : exit(EXIT_FAILURE); @@ -271,13 +271,13 @@ 209 : } 210 : } 211 : - 212 932 : if (symlink(linkto, path) != 0) { + 212 943 : if (symlink(linkto, path) != 0) { 213 : /* LCOV_EXCL_START */ 214 : log_fatal("Error writing symlink %s\n", path); 215 : exit(EXIT_FAILURE); 216 : /* LCOV_EXCL_STOP */ 217 : } - 218 932 : } + 218 943 : } 219 : 220 : /** 221 : * Create a file or a symlink with a random name. @@ -350,68 +350,68 @@ 288 : * - The written data may be equal or not at the already existing one. 289 : * - If it's a symlink nothing is done. 290 : */ - 291 6226 : void cmd_write(const char* path, int size) + 291 6254 : void cmd_write(const char* path, int size) 292 : { 293 : struct stat st; 294 : - 295 6226 : if (lstat(path, &st) != 0) { + 295 6254 : if (lstat(path, &st) != 0) { 296 : /* LCOV_EXCL_START */ 297 : log_fatal("Error accessing %s\n", path); 298 : exit(EXIT_FAILURE); 299 : /* LCOV_EXCL_STOP */ 300 : } 301 : - 302 6226 : if (S_ISREG(st.st_mode)) { + 302 6254 : if (S_ISREG(st.st_mode)) { 303 : unsigned char* data; 304 : off_t off; 305 : int f; 306 : 307 : /* not over the end */ - 308 6199 : if (size > st.st_size) - 309 687 : size = st.st_size; + 308 6227 : if (size > st.st_size) + 309 716 : size = st.st_size; 310 : 311 : /* start at random position inside the file */ - 312 6199 : if (size < st.st_size) - 313 5511 : off = rnd(st.st_size - size); + 312 6227 : if (size < st.st_size) + 313 5510 : off = rnd(st.st_size - size); 314 : else - 315 688 : off = 0; + 315 717 : off = 0; 316 : - 317 6199 : data = malloc(size); + 317 6227 : data = malloc(size); 318 : - 319 6199 : rndnz_range(data, size); + 319 6227 : rndnz_range(data, size); 320 : - 321 6199 : f = open(path, O_WRONLY | O_BINARY | O_NOFOLLOW); - 322 6199 : if (f < 0) { + 321 6227 : f = open(path, O_WRONLY | O_BINARY | O_NOFOLLOW); + 322 6227 : if (f < 0) { 323 : /* LCOV_EXCL_START */ 324 : log_fatal("Error creating file %s\n", path); 325 : exit(EXIT_FAILURE); 326 : /* LCOV_EXCL_STOP */ 327 : } 328 : - 329 6199 : if (lseek(f, off, SEEK_SET) != off) { + 329 6227 : if (lseek(f, off, SEEK_SET) != off) { 330 : /* LCOV_EXCL_START */ 331 : log_fatal("Error seeking file %s\n", path); 332 : exit(EXIT_FAILURE); 333 : /* LCOV_EXCL_STOP */ 334 : } 335 : - 336 6199 : if (write(f, data, size) != size) { + 336 6227 : if (write(f, data, size) != size) { 337 : /* LCOV_EXCL_START */ 338 : log_fatal("Error writing file %s\n", path); 339 : exit(EXIT_FAILURE); 340 : /* LCOV_EXCL_STOP */ 341 : } 342 : - 343 6199 : if (close(f) != 0) { + 343 6227 : if (close(f) != 0) { 344 : /* LCOV_EXCL_START */ 345 : log_fatal("Error closing file %s\n", path); 346 : exit(EXIT_FAILURE); 347 : /* LCOV_EXCL_STOP */ 348 : } 349 : - 350 6199 : free(data); + 350 6227 : free(data); 351 : } - 352 6226 : } + 352 6254 : } 353 : 354 : /** 355 : * Damage a file. @@ -518,50 +518,50 @@ 456 : * - The file must exist. 457 : * - If it's a symlink nothing is done. 458 : */ - 459 3224 : void cmd_append(const char* path, int size) + 459 3181 : void cmd_append(const char* path, int size) 460 : { 461 : struct stat st; 462 : - 463 3224 : if (lstat(path, &st) != 0) { + 463 3181 : if (lstat(path, &st) != 0) { 464 : /* LCOV_EXCL_START */ 465 : log_fatal("Error accessing %s\n", path); 466 : exit(EXIT_FAILURE); 467 : /* LCOV_EXCL_STOP */ 468 : } 469 : - 470 3224 : if (S_ISREG(st.st_mode)) { + 470 3181 : if (S_ISREG(st.st_mode)) { 471 : unsigned char* data; 472 : int f; 473 : - 474 3224 : data = malloc(size); + 474 3181 : data = malloc(size); 475 : - 476 3224 : rndnz_range(data, size); + 476 3181 : rndnz_range(data, size); 477 : - 478 3224 : f = open(path, O_WRONLY | O_APPEND | O_BINARY | O_NOFOLLOW); - 479 3224 : if (f < 0) { + 478 3181 : f = open(path, O_WRONLY | O_APPEND | O_BINARY | O_NOFOLLOW); + 479 3181 : if (f < 0) { 480 : /* LCOV_EXCL_START */ 481 : log_fatal("Error opening file %s\n", path); 482 : exit(EXIT_FAILURE); 483 : /* LCOV_EXCL_STOP */ 484 : } 485 : - 486 3224 : if (write(f, data, size) != size) { + 486 3181 : if (write(f, data, size) != size) { 487 : /* LCOV_EXCL_START */ 488 : log_fatal("Error writing file %s\n", path); 489 : exit(EXIT_FAILURE); 490 : /* LCOV_EXCL_STOP */ 491 : } 492 : - 493 3224 : if (close(f) != 0) { + 493 3181 : if (close(f) != 0) { 494 : /* LCOV_EXCL_START */ 495 : log_fatal("Error closing file %s\n", path); 496 : exit(EXIT_FAILURE); 497 : /* LCOV_EXCL_STOP */ 498 : } 499 : - 500 3224 : free(data); + 500 3181 : free(data); 501 : } - 502 3224 : } + 502 3181 : } 503 : 504 : /** 505 : * Truncate a file. @@ -569,69 +569,69 @@ 507 : * - The file is NEVER truncated to 0. 508 : * - If it's a symlink nothing is done. 509 : */ - 510 3082 : void cmd_truncate(const char* path, int size) + 510 3162 : void cmd_truncate(const char* path, int size) 511 : { 512 : struct stat st; 513 : - 514 3082 : if (lstat(path, &st) != 0) { + 514 3162 : if (lstat(path, &st) != 0) { 515 : /* LCOV_EXCL_START */ 516 : log_fatal("Error accessing %s\n", path); 517 : exit(EXIT_FAILURE); 518 : /* LCOV_EXCL_STOP */ 519 : } 520 : - 521 3082 : if (S_ISREG(st.st_mode)) { + 521 3162 : if (S_ISREG(st.st_mode)) { 522 : off_t off; 523 : int f; 524 : 525 : /* if file is empty, just rewrite it */ - 526 3082 : if (st.st_size == 0) { - 527 7 : size = 0; + 526 3162 : if (st.st_size == 0) { + 527 4 : size = 0; 528 : } else { 529 : /* don't truncate files to 0 size to avoid ZERO file size protection */ - 530 3075 : if (size >= st.st_size) - 531 185 : size = st.st_size - 1; + 530 3158 : if (size >= st.st_size) + 531 209 : size = st.st_size - 1; 532 : } 533 : - 534 3082 : off = st.st_size - size; + 534 3162 : off = st.st_size - size; 535 : - 536 3082 : f = open(path, O_WRONLY | O_BINARY | O_NOFOLLOW); - 537 3082 : if (f < 0) { + 536 3162 : f = open(path, O_WRONLY | O_BINARY | O_NOFOLLOW); + 537 3162 : if (f < 0) { 538 : /* LCOV_EXCL_START */ 539 : log_fatal("Error opening file %s\n", path); 540 : exit(EXIT_FAILURE); 541 : /* LCOV_EXCL_STOP */ 542 : } 543 : - 544 3082 : if (ftruncate(f, off) != 0) { + 544 3162 : if (ftruncate(f, off) != 0) { 545 : /* LCOV_EXCL_START */ 546 : log_fatal("Error truncating file %s\n", path); 547 : exit(EXIT_FAILURE); 548 : /* LCOV_EXCL_STOP */ 549 : } 550 : - 551 3082 : if (close(f) != 0) { + 551 3162 : if (close(f) != 0) { 552 : /* LCOV_EXCL_START */ 553 : log_fatal("Error closing file %s\n", path); 554 : exit(EXIT_FAILURE); 555 : /* LCOV_EXCL_STOP */ 556 : } 557 : } - 558 3082 : } + 558 3162 : } 559 : 560 : /** 561 : * Delete a file. 562 : * - The file must exist. 563 : */ - 564 3222 : void cmd_delete(const char* path) + 564 3155 : void cmd_delete(const char* path) 565 : { - 566 3222 : if (remove(path) != 0) { + 566 3155 : if (remove(path) != 0) { 567 : /* LCOV_EXCL_START */ 568 : log_fatal("Error removing %s\n", path); 569 : exit(EXIT_FAILURE); 570 : /* LCOV_EXCL_STOP */ 571 : } - 572 3222 : } + 572 3155 : } 573 : 574 : /** 575 : * Change a file. Or deleted/truncated/append/created. @@ -642,20 +642,20 @@ 580 : struct stat st; 581 : 582 13128 : if (!size) - 583 13157 : return; + 583 13160 : return; 584 : - 585 13099 : if (lstat(path, &st) != 0) { + 585 13096 : if (lstat(path, &st) != 0) { 586 : /* LCOV_EXCL_START */ 587 : log_fatal("Error accessing %s\n", path); 588 : exit(EXIT_FAILURE); 589 : /* LCOV_EXCL_STOP */ 590 : } 591 : - 592 13099 : if (S_ISLNK(st.st_mode)) { + 592 13096 : if (S_ISLNK(st.st_mode)) { 593 : /* symlink */ - 594 394 : if (rnd(2) == 0) { + 594 393 : if (rnd(2) == 0) { 595 : /* delete */ - 596 195 : if (remove(path) != 0) { + 596 183 : if (remove(path) != 0) { 597 : /* LCOV_EXCL_START */ 598 : log_fatal("Error removing %s\n", path); 599 : exit(EXIT_FAILURE); @@ -665,30 +665,30 @@ 603 : /* recreate */ 604 : char linkto[PATH_MAX]; 605 : - 606 199 : if (remove(path) != 0) { + 606 210 : if (remove(path) != 0) { 607 : /* LCOV_EXCL_START */ 608 : log_fatal("Error removing %s\n", path); 609 : exit(EXIT_FAILURE); 610 : /* LCOV_EXCL_STOP */ 611 : } 612 : - 613 199 : rnd_name(linkto); + 613 210 : rnd_name(linkto); 614 : - 615 199 : cmd_generate_symlink(path, linkto); + 615 210 : cmd_generate_symlink(path, linkto); 616 : } - 617 12705 : } else if (S_ISREG(st.st_mode)) { + 617 12703 : } else if (S_ISREG(st.st_mode)) { 618 : int r; 619 : - 620 12705 : r = rnd(4); + 620 12703 : r = rnd(4); 621 : - 622 12705 : if (r == 0) { - 623 3177 : cmd_write(path, size); - 624 9528 : } else if (r == 1) { - 625 3224 : cmd_append(path, size); - 626 6304 : } else if (r == 2) { - 627 3082 : cmd_truncate(path, size); + 622 12703 : if (r == 0) { + 623 3205 : cmd_write(path, size); + 624 9498 : } else if (r == 1) { + 625 3181 : cmd_append(path, size); + 626 6317 : } else if (r == 2) { + 627 3162 : cmd_truncate(path, size); 628 : } else { - 629 3222 : cmd_delete(path); + 629 3155 : cmd_delete(path); 630 : } 631 : } 632 : } diff --git a/cov/cmdline/murmur3.c.func-sort-c.html b/cov/cmdline/murmur3.c.func-sort-c.html index db8791cf..36afb82e 100644 --- a/cov/cmdline/murmur3.c.func-sort-c.html +++ b/cov/cmdline/murmur3.c.func-sort-c.html @@ -61,11 +61,11 @@ fmix32 - 8307308 + 8307416 MurmurHash3_x86_128 - 2076827 + 2076854
diff --git a/cov/cmdline/murmur3.c.func.html b/cov/cmdline/murmur3.c.func.html index 502e4614..4b31437b 100644 --- a/cov/cmdline/murmur3.c.func.html +++ b/cov/cmdline/murmur3.c.func.html @@ -61,11 +61,11 @@ MurmurHash3_x86_128 - 2076827 + 2076854 fmix32 - 8307308 + 8307416
diff --git a/cov/cmdline/murmur3.c.gcov.html b/cov/cmdline/murmur3.c.gcov.html index 28177746..3d5c639f 100644 --- a/cov/cmdline/murmur3.c.gcov.html +++ b/cov/cmdline/murmur3.c.gcov.html @@ -91,14 +91,14 @@ 29 : // domain. The author hereby disclaims copyright to this source code. 30 : 31 : /* Finalization mix - force all bits of a hash block to avalanche */ - 32 8307308 : static inline uint32_t fmix32(uint32_t h) + 32 8307416 : static inline uint32_t fmix32(uint32_t h) 33 : { - 34 8307308 : h ^= h >> 16; - 35 8307308 : h *= 0x85ebca6b; - 36 8307308 : h ^= h >> 13; - 37 8307308 : h *= 0xc2b2ae35; - 38 8307308 : h ^= h >> 16; - 39 8307308 : return h; + 34 8307416 : h ^= h >> 16; + 35 8307416 : h *= 0x85ebca6b; + 36 8307416 : h ^= h >> 13; + 37 8307416 : h *= 0xc2b2ae35; + 38 8307416 : h ^= h >> 16; + 39 8307416 : return h; 40 : } 41 : 42 : /* @@ -137,17 +137,17 @@ 75 : uint32_t c3 = 0x38b34ae5; 76 : uint32_t c4 = 0xa1e38b93; 77 : - 78 2076827 : void MurmurHash3_x86_128(const void* data, size_t size, const uint8_t* seed, void* digest) + 78 2076854 : void MurmurHash3_x86_128(const void* data, size_t size, const uint8_t* seed, void* digest) 79 : { 80 : size_t nblocks; 81 : const uint32_t* blocks; 82 : const uint32_t* end; 83 : size_t size_remainder; 84 : - 85 2076827 : uint32_t h1 = ((const uint32_t*)seed)[0]; - 86 2076827 : uint32_t h2 = ((const uint32_t*)seed)[1]; - 87 2076827 : uint32_t h3 = ((const uint32_t*)seed)[2]; - 88 2076827 : uint32_t h4 = ((const uint32_t*)seed)[3]; + 85 2076854 : uint32_t h1 = ((const uint32_t*)seed)[0]; + 86 2076854 : uint32_t h2 = ((const uint32_t*)seed)[1]; + 87 2076854 : uint32_t h3 = ((const uint32_t*)seed)[2]; + 88 2076854 : uint32_t h4 = ((const uint32_t*)seed)[3]; 89 : 90 : #if WORDS_BIGENDIAN 91 : h1 = util_swap32(h1); @@ -156,16 +156,16 @@ 94 : h4 = util_swap32(h4); 95 : #endif 96 : - 97 2076827 : nblocks = size / 16; - 98 2076827 : blocks = data; - 99 2076827 : end = blocks + nblocks * 4; + 97 2076854 : nblocks = size / 16; + 98 2076854 : blocks = data; + 99 2076854 : end = blocks + nblocks * 4; 100 : 101 : /* body */ - 102 110683413 : while (blocks < end) { - 103 106529759 : uint32_t k1 = blocks[0]; - 104 106529759 : uint32_t k2 = blocks[1]; - 105 106529759 : uint32_t k3 = blocks[2]; - 106 106529759 : uint32_t k4 = blocks[3]; + 102 110685610 : while (blocks < end) { + 103 106531902 : uint32_t k1 = blocks[0]; + 104 106531902 : uint32_t k2 = blocks[1]; + 105 106531902 : uint32_t k3 = blocks[2]; + 106 106531902 : uint32_t k4 = blocks[3]; 107 : 108 : #if WORDS_BIGENDIAN 109 : k1 = util_swap32(k1); @@ -174,71 +174,71 @@ 112 : k4 = util_swap32(k4); 113 : #endif 114 : - 115 106529759 : k1 *= c1; k1 = util_rotl32(k1, 15); k1 *= c2; h1 ^= k1; + 115 106531902 : k1 *= c1; k1 = util_rotl32(k1, 15); k1 *= c2; h1 ^= k1; 116 : - 117 106529759 : h1 = util_rotl32(h1, 19); h1 += h2; h1 = h1 * 5 + 0x561ccd1b; + 117 106531902 : h1 = util_rotl32(h1, 19); h1 += h2; h1 = h1 * 5 + 0x561ccd1b; 118 : - 119 106529759 : k2 *= c2; k2 = util_rotl32(k2, 16); k2 *= c3; h2 ^= k2; + 119 106531902 : k2 *= c2; k2 = util_rotl32(k2, 16); k2 *= c3; h2 ^= k2; 120 : - 121 106529759 : h2 = util_rotl32(h2, 17); h2 += h3; h2 = h2 * 5 + 0x0bcaa747; + 121 106531902 : h2 = util_rotl32(h2, 17); h2 += h3; h2 = h2 * 5 + 0x0bcaa747; 122 : - 123 106529759 : k3 *= c3; k3 = util_rotl32(k3, 17); k3 *= c4; h3 ^= k3; + 123 106531902 : k3 *= c3; k3 = util_rotl32(k3, 17); k3 *= c4; h3 ^= k3; 124 : - 125 106529759 : h3 = util_rotl32(h3, 15); h3 += h4; h3 = h3 * 5 + 0x96cd1c35; + 125 106531902 : h3 = util_rotl32(h3, 15); h3 += h4; h3 = h3 * 5 + 0x96cd1c35; 126 : - 127 106529759 : k4 *= c4; k4 = util_rotl32(k4, 18); k4 *= c1; h4 ^= k4; + 127 106531902 : k4 *= c4; k4 = util_rotl32(k4, 18); k4 *= c1; h4 ^= k4; 128 : - 129 106529759 : h4 = util_rotl32(h4, 13); h4 += h1; h4 = h4 * 5 + 0x32ac3b17; + 129 106531902 : h4 = util_rotl32(h4, 13); h4 += h1; h4 = h4 * 5 + 0x32ac3b17; 130 : - 131 106529759 : blocks += 4; + 131 106531902 : blocks += 4; 132 : } 133 : 134 : /* tail */ - 135 2076827 : size_remainder = size & 15; - 136 2076827 : if (size_remainder != 0) { - 137 779267 : const uint8_t* tail = (const uint8_t*)blocks; + 135 2076854 : size_remainder = size & 15; + 136 2076854 : if (size_remainder != 0) { + 137 779239 : const uint8_t* tail = (const uint8_t*)blocks; 138 : - 139 779267 : uint32_t k1 = 0; - 140 779267 : uint32_t k2 = 0; - 141 779267 : uint32_t k3 = 0; - 142 779267 : uint32_t k4 = 0; + 139 779239 : uint32_t k1 = 0; + 140 779239 : uint32_t k2 = 0; + 141 779239 : uint32_t k3 = 0; + 142 779239 : uint32_t k4 = 0; 143 : - 144 779267 : switch (size_remainder) { - 145 51305 : case 15 : k4 ^= (uint32_t)tail[14] << 16; - 146 104040 : case 14 : k4 ^= (uint32_t)tail[13] << 8; - 147 156243 : case 13 : k4 ^= (uint32_t)tail[12] << 0; - 148 156243 : k4 *= c4; k4 = util_rotl32(k4, 18); k4 *= c1; h4 ^= k4; - 149 209005 : case 12 : k3 ^= (uint32_t)tail[11] << 24; - 150 261544 : case 11 : k3 ^= (uint32_t)tail[10] << 16; - 151 313728 : case 10 : k3 ^= (uint32_t)tail[ 9] << 8; - 152 367016 : case 9 : k3 ^= (uint32_t)tail[ 8] << 0; - 153 367016 : k3 *= c3; k3 = util_rotl32(k3, 17); k3 *= c4; h3 ^= k3; - 154 420940 : case 8 : k2 ^= (uint32_t)tail[ 7] << 24; - 155 470460 : case 7 : k2 ^= (uint32_t)tail[ 6] << 16; - 156 523118 : case 6 : k2 ^= (uint32_t)tail[ 5] << 8; - 157 573626 : case 5 : k2 ^= (uint32_t)tail[ 4] << 0; - 158 573626 : k2 *= c2; k2 = util_rotl32(k2, 16); k2 *= c3; h2 ^= k2; - 159 625593 : case 4 : k1 ^= (uint32_t)tail[ 3] << 24; - 160 675926 : case 3 : k1 ^= (uint32_t)tail[ 2] << 16; - 161 726993 : case 2 : k1 ^= (uint32_t)tail[ 1] << 8; - 162 779267 : case 1 : k1 ^= (uint32_t)tail[ 0] << 0; - 163 779267 : k1 *= c1; k1 = util_rotl32(k1, 15); k1 *= c2; h1 ^= k1; + 144 779239 : switch (size_remainder) { + 145 51287 : case 15 : k4 ^= (uint32_t)tail[14] << 16; + 146 104028 : case 14 : k4 ^= (uint32_t)tail[13] << 8; + 147 156205 : case 13 : k4 ^= (uint32_t)tail[12] << 0; + 148 156205 : k4 *= c4; k4 = util_rotl32(k4, 18); k4 *= c1; h4 ^= k4; + 149 208993 : case 12 : k3 ^= (uint32_t)tail[11] << 24; + 150 261517 : case 11 : k3 ^= (uint32_t)tail[10] << 16; + 151 313718 : case 10 : k3 ^= (uint32_t)tail[ 9] << 8; + 152 367026 : case 9 : k3 ^= (uint32_t)tail[ 8] << 0; + 153 367026 : k3 *= c3; k3 = util_rotl32(k3, 17); k3 *= c4; h3 ^= k3; + 154 420982 : case 8 : k2 ^= (uint32_t)tail[ 7] << 24; + 155 470474 : case 7 : k2 ^= (uint32_t)tail[ 6] << 16; + 156 523130 : case 6 : k2 ^= (uint32_t)tail[ 5] << 8; + 157 573642 : case 5 : k2 ^= (uint32_t)tail[ 4] << 0; + 158 573642 : k2 *= c2; k2 = util_rotl32(k2, 16); k2 *= c3; h2 ^= k2; + 159 625581 : case 4 : k1 ^= (uint32_t)tail[ 3] << 24; + 160 675936 : case 3 : k1 ^= (uint32_t)tail[ 2] << 16; + 161 726983 : case 2 : k1 ^= (uint32_t)tail[ 1] << 8; + 162 779239 : case 1 : k1 ^= (uint32_t)tail[ 0] << 0; + 163 779239 : k1 *= c1; k1 = util_rotl32(k1, 15); k1 *= c2; h1 ^= k1; 164 : } 165 : } 166 : 167 : /* finalization */ - 168 2076827 : h1 ^= size; h2 ^= size; h3 ^= size; h4 ^= size; + 168 2076854 : h1 ^= size; h2 ^= size; h3 ^= size; h4 ^= size; 169 : - 170 2076827 : h1 += h2; h1 += h3; h1 += h4; - 171 2076827 : h2 += h1; h3 += h1; h4 += h1; + 170 2076854 : h1 += h2; h1 += h3; h1 += h4; + 171 2076854 : h2 += h1; h3 += h1; h4 += h1; 172 : - 173 2076827 : h1 = fmix32(h1); - 174 2076827 : h2 = fmix32(h2); - 175 2076827 : h3 = fmix32(h3); - 176 2076827 : h4 = fmix32(h4); + 173 2076854 : h1 = fmix32(h1); + 174 2076854 : h2 = fmix32(h2); + 175 2076854 : h3 = fmix32(h3); + 176 2076854 : h4 = fmix32(h4); 177 : - 178 2076827 : h1 += h2; h1 += h3; h1 += h4; - 179 2076827 : h2 += h1; h3 += h1; h4 += h1; + 178 2076854 : h1 += h2; h1 += h3; h1 += h4; + 179 2076854 : h2 += h1; h3 += h1; h4 += h1; 180 : 181 : #if WORDS_BIGENDIAN 182 : h1 = util_swap32(h1); @@ -247,11 +247,11 @@ 185 : h4 = util_swap32(h4); 186 : #endif 187 : - 188 2076827 : ((uint32_t*)digest)[0] = h1; - 189 2076827 : ((uint32_t*)digest)[1] = h2; - 190 2076827 : ((uint32_t*)digest)[2] = h3; - 191 2076827 : ((uint32_t*)digest)[3] = h4; - 192 2076827 : } + 188 2076854 : ((uint32_t*)digest)[0] = h1; + 189 2076854 : ((uint32_t*)digest)[1] = h2; + 190 2076854 : ((uint32_t*)digest)[2] = h3; + 191 2076854 : ((uint32_t*)digest)[3] = h4; + 192 2076854 : } 193 : diff --git a/cov/cmdline/parity.c.func-sort-c.html b/cov/cmdline/parity.c.func-sort-c.html index 1dc217aa..83ea4f9a 100644 --- a/cov/cmdline/parity.c.func-sort-c.html +++ b/cov/cmdline/parity.c.func-sort-c.html @@ -31,9 +31,9 @@ lcov.info Lines: - 206 - 240 - 85.8 % + 217 + 236 + 91.9 % Date: @@ -60,16 +60,16 @@ Hit count Sort by hit count - parity_split_find - 4113567 + parity_split_find + 4114025 - parity_read + parity_read 3501825 - parity_write - 611751 + parity_write + 612195 parity_handle_chsize @@ -80,7 +80,7 @@ 2460 - parity_close + parity_close 1022 @@ -93,7 +93,7 @@ parity_allocated_size - 638 + 640 parity_create @@ -108,11 +108,11 @@ 487 - parity_sync + parity_sync 469 - parity_open + parity_open 402 @@ -129,7 +129,7 @@ parity_is_invalid - 1 + 2 parity_overflow diff --git a/cov/cmdline/parity.c.func.html b/cov/cmdline/parity.c.func.html index f1d24eff..fbee8fb6 100644 --- a/cov/cmdline/parity.c.func.html +++ b/cov/cmdline/parity.c.func.html @@ -31,9 +31,9 @@ lcov.info Lines: - 206 - 240 - 85.8 % + 217 + 236 + 91.9 % Date: @@ -65,14 +65,14 @@ parity_allocated_size - 638 + 640 parity_chsize 615 - parity_close + parity_close 1022 @@ -97,10 +97,10 @@ parity_is_invalid - 1 + 2 - parity_open + parity_open 402 @@ -108,7 +108,7 @@ 0 - parity_read + parity_read 3501825 @@ -116,15 +116,15 @@ 487 - parity_split_find - 4113567 + parity_split_find + 4114025 parity_split_is_fixed 2460 - parity_sync + parity_sync 469 @@ -132,8 +132,8 @@ 87 - parity_write - 611751 + parity_write + 612195
diff --git a/cov/cmdline/parity.c.gcov.html b/cov/cmdline/parity.c.gcov.html index 4ca2088e..d58b31ce 100644 --- a/cov/cmdline/parity.c.gcov.html +++ b/cov/cmdline/parity.c.gcov.html @@ -31,9 +31,9 @@ lcov.info Lines: - 206 - 240 - 85.8 % + 217 + 236 + 91.9 % Date: @@ -94,31 +94,31 @@ 32 : /****************************************************************************/ 33 : /* parity */ 34 : - 35 638 : block_off_t parity_allocated_size(struct snapraid_state* state) + 35 640 : block_off_t parity_allocated_size(struct snapraid_state* state) 36 : { 37 : block_off_t parity_block; 38 : tommy_node* i; 39 : 40 : /* compute the size of the parity file */ - 41 638 : parity_block = 0; - 42 4456 : for (i = state->disklist; i != 0; i = i->next) { - 43 3818 : struct snapraid_disk* disk = i->data; + 41 640 : parity_block = 0; + 42 4470 : for (i = state->disklist; i != 0; i = i->next) { + 43 3830 : struct snapraid_disk* disk = i->data; 44 : 45 : /* start from the declared size */ - 46 3818 : block_off_t block = fs_size(disk); + 46 3830 : block_off_t block = fs_size(disk); 47 : 48 : /* decrease the block until an allocated one, but part of a file */ 49 : /* we don't stop at deleted blocks, because we want to have them cleared */ 50 : /* if they are at the end of the parity */ - 51 190184 : while (block > parity_block && !block_has_file(fs_par2block_find(disk, block - 1))) + 51 190208 : while (block > parity_block && !block_has_file(fs_par2block_find(disk, block - 1))) 52 182548 : --block; 53 : 54 : /* get the highest value */ - 55 3818 : if (block > parity_block) - 56 2263 : parity_block = block; + 55 3830 : if (block > parity_block) + 56 2265 : parity_block = block; 57 : } 58 : - 59 638 : return parity_block; + 59 640 : return parity_block; 60 : } 61 : 62 87 : block_off_t parity_used_size(struct snapraid_state* state) @@ -146,34 +146,34 @@ 84 87 : return parity_block; 85 : } 86 : - 87 1 : int parity_is_invalid(struct snapraid_state* state) + 87 2 : int parity_is_invalid(struct snapraid_state* state) 88 : { 89 : block_off_t blockmax; 90 : block_off_t i; 91 : - 92 1 : blockmax = parity_allocated_size(state); + 92 2 : blockmax = parity_allocated_size(state); 93 : - 94 1 : for (i = 0; i < blockmax; ++i) { + 94 2 : for (i = 0; i < blockmax; ++i) { 95 : tommy_node* node_disk; 96 : int one_invalid; 97 : int one_valid; 98 : 99 : /* for each disk */ - 100 0 : one_invalid = 0; - 101 0 : one_valid = 0; - 102 0 : for (node_disk = state->disklist; node_disk != 0; node_disk = node_disk->next) { - 103 0 : struct snapraid_disk* disk = node_disk->data; - 104 0 : struct snapraid_block* block = fs_par2block_find(disk, i); + 100 1 : one_invalid = 0; + 101 1 : one_valid = 0; + 102 7 : for (node_disk = state->disklist; node_disk != 0; node_disk = node_disk->next) { + 103 6 : struct snapraid_disk* disk = node_disk->data; + 104 6 : struct snapraid_block* block = fs_par2block_find(disk, i); 105 : - 106 0 : if (block_has_file(block)) - 107 0 : one_valid = 1; - 108 0 : if (block_has_invalid_parity(block)) - 109 0 : one_invalid = 1; + 106 6 : if (block_has_file(block)) + 107 5 : one_valid = 1; + 108 6 : if (block_has_invalid_parity(block)) + 109 2 : one_invalid = 1; 110 : } 111 : 112 : /* if both valid and invalid, we need to update */ - 113 0 : if (one_invalid && one_valid) - 114 0 : return 1; + 113 1 : if (one_invalid && one_valid) + 114 1 : return 1; 115 : } 116 : 117 1 : return 0; @@ -592,339 +592,347 @@ 530 : /* mask of bits used by the block size */ 531 615 : block_mask = ((data_off_t)block_size) - 1; 532 : - 533 615 : if (size < 0) - 534 0 : return -1; - 535 : - 536 3075 : for (s = 0;s < handle->split_mac;++s) { - 537 2460 : struct snapraid_split_handle* split = &handle->split_map[s]; - 538 2460 : int is_fixed = parity_split_is_fixed(handle, s); - 539 : data_off_t run; - 540 : - 541 2460 : if (is_fixed) { - 542 : /* if the required size is smaller, we have to reduce also the file */ - 543 : /* ignoring the previous size */ - 544 611 : if (size <= split->size) { - 545 : /* mark it as not fixed anymore for the later check */ - 546 10 : is_fixed = 0; - 547 : - 548 10 : run = size; /* allocate only the needed size */ - 549 : } else { - 550 : /* if the size cannot be changed, use the fixed one */ - 551 601 : run = split->size; - 552 : - 553 601 : if ((run & block_mask) != 0) { - 554 : /* LCOV_EXCL_START */ - 555 : log_fatal("Internal inconsistency in split '%s' size with extra '%" PRIu64 "' bytes.\n", split->path, run & block_mask); - 556 : return -1; - 557 : /* LCOV_EXCL_STOP */ - 558 : } - 559 : } - 560 : } else { - 561 : /* otherwise tries to allocate all the needed remaining size */ - 562 1849 : run = size; - 563 : } - 564 : - 565 2460 : ret = parity_handle_chsize(split, run, block_size, skip_fallocate, skip_space_holder); - 566 2460 : if (ret != 0) - 567 0 : return -1; - 568 : - 569 2460 : if (split->st.st_size > run) { + 533 615 : if (size < 0) { + 534 : /* LCOV_EXCL_START */ + 535 : return -1; + 536 : /* LCOV_EXCL_STOP */ + 537 : } + 538 : + 539 3075 : for (s = 0;s < handle->split_mac;++s) { + 540 2460 : struct snapraid_split_handle* split = &handle->split_map[s]; + 541 2460 : int is_fixed = parity_split_is_fixed(handle, s); + 542 : data_off_t run; + 543 : + 544 2460 : if (is_fixed) { + 545 : /* if the required size is smaller, we have to reduce also the file */ + 546 : /* ignoring the previous size */ + 547 611 : if (size <= split->size) { + 548 : /* mark it as not fixed anymore for the later check */ + 549 10 : is_fixed = 0; + 550 : + 551 10 : run = size; /* allocate only the needed size */ + 552 : } else { + 553 : /* if the size cannot be changed, use the fixed one */ + 554 601 : run = split->size; + 555 : + 556 601 : if ((run & block_mask) != 0) { + 557 : /* LCOV_EXCL_START */ + 558 : log_fatal("Internal inconsistency in split '%s' size with extra '%" PRIu64 "' bytes.\n", split->path, run & block_mask); + 559 : return -1; + 560 : /* LCOV_EXCL_STOP */ + 561 : } + 562 : } + 563 : } else { + 564 : /* otherwise tries to allocate all the needed remaining size */ + 565 1849 : run = size; + 566 : } + 567 : + 568 2460 : ret = parity_handle_chsize(split, run, block_size, skip_fallocate, skip_space_holder); + 569 2460 : if (ret != 0) { 570 : /* LCOV_EXCL_START */ - 571 : log_fatal("Unexpected over resizing parity file '%s' to size %" PRIu64 " resulting in size %" PRIu64 ".\n", split->path, run, split->st.st_size); - 572 : return -1; - 573 : /* LCOV_EXCL_STOP */ - 574 2460 : } else if (is_fixed && split->st.st_size < run) { - 575 : /* LCOV_EXCL_START */ - 576 : log_fatal("Failed restoring parity file '%s' to size %" PRIu64 " resulting in size %" PRIu64 ".\n", split->path, run, split->st.st_size); - 577 : return -1; - 578 : /* LCOV_EXCL_STOP */ - 579 : } else { - 580 : /* here it's possible to get less than the requested size */ - 581 2460 : run = split->st.st_size; - 582 : - 583 2460 : if ((run & block_mask) != 0) { - 584 : /* LCOV_EXCL_START */ - 585 : log_fatal("Internal inconsistency in final parity size %" PRIu64 " with block size %u\n", run, block_size); - 586 : os_abort(); - 587 : /* LCOV_EXCL_STOP */ - 588 : } - 589 : - 590 : /* store what we have allocated */ - 591 2460 : split->size = run; - 592 : - 593 : /* decrease the remaining size */ - 594 2460 : size -= run; - 595 : } - 596 : } - 597 : - 598 : /* if we cannot allocate all the space */ - 599 615 : if (size != 0) { - 600 0 : log_fatal("Failed to allocate all the required parity space. You miss %" PRIu64 " bytes.\n", size); - 601 0 : return -1; + 571 : return -1; + 572 : /* LCOV_EXCL_STOP */ + 573 : } + 574 : + 575 2460 : if (split->st.st_size > run) { + 576 : /* LCOV_EXCL_START */ + 577 : log_fatal("Unexpected over resizing parity file '%s' to size %" PRIu64 " resulting in size %" PRIu64 ".\n", split->path, run, split->st.st_size); + 578 : return -1; + 579 : /* LCOV_EXCL_STOP */ + 580 2460 : } else if (is_fixed && split->st.st_size < run) { + 581 : /* LCOV_EXCL_START */ + 582 : log_fatal("Failed restoring parity file '%s' to size %" PRIu64 " resulting in size %" PRIu64 ".\n", split->path, run, split->st.st_size); + 583 : return -1; + 584 : /* LCOV_EXCL_STOP */ + 585 : } else { + 586 : /* here it's possible to get less than the requested size */ + 587 2460 : run = split->st.st_size; + 588 : + 589 2460 : if ((run & block_mask) != 0) { + 590 : /* LCOV_EXCL_START */ + 591 : log_fatal("Internal inconsistency in final parity size %" PRIu64 " with block size %u\n", run, block_size); + 592 : os_abort(); + 593 : /* LCOV_EXCL_STOP */ + 594 : } + 595 : + 596 : /* store what we have allocated */ + 597 2460 : split->size = run; + 598 : + 599 : /* decrease the remaining size */ + 600 2460 : size -= run; + 601 : } 602 : } 603 : - 604 : /* now copy the new size in the parity data */ - 605 615 : if (is_modified) - 606 481 : *is_modified = 0; - 607 : - 608 3075 : for (s = 0;s < handle->split_mac;++s) { - 609 2460 : struct snapraid_split_handle* split = &handle->split_map[s]; - 610 : - 611 2460 : if (parity->split_map[s].size != split->size) { - 612 320 : parity->split_map[s].size = split->size; - 613 320 : if (is_modified) - 614 264 : *is_modified = 1; - 615 : } - 616 : } - 617 : - 618 615 : return 0; - 619 : } - 620 : - 621 402 : int parity_open(struct snapraid_parity_handle* handle, const struct snapraid_parity* parity, unsigned level, int mode, uint32_t block_size, data_off_t limit_size) - 622 : { - 623 : unsigned s; - 624 : data_off_t block_mask; + 604 : /* if we cannot allocate all the space */ + 605 615 : if (size != 0) { + 606 : /* LCOV_EXCL_START */ + 607 : log_fatal("Failed to allocate all the required parity space. You miss %" PRIu64 " bytes.\n", size); + 608 : return -1; + 609 : /* LCOV_EXCL_STOP */ + 610 : } + 611 : + 612 : /* now copy the new size in the parity data */ + 613 615 : if (is_modified) + 614 481 : *is_modified = 0; + 615 : + 616 3075 : for (s = 0;s < handle->split_mac;++s) { + 617 2460 : struct snapraid_split_handle* split = &handle->split_map[s]; + 618 : + 619 2460 : if (parity->split_map[s].size != split->size) { + 620 320 : parity->split_map[s].size = split->size; + 621 320 : if (is_modified) + 622 264 : *is_modified = 1; + 623 : } + 624 : } 625 : - 626 402 : handle->level = level; - 627 402 : handle->split_mac = 0; + 626 615 : return 0; + 627 : } 628 : - 629 : /* mask of bits used by the block size */ - 630 402 : block_mask = ((data_off_t)block_size) - 1; - 631 : - 632 2006 : for (s = 0;s < parity->split_mac;++s) { - 633 1605 : struct snapraid_split_handle* split = &handle->split_map[s]; - 634 : int ret; - 635 : int flags; + 629 402 : int parity_open(struct snapraid_parity_handle* handle, const struct snapraid_parity* parity, unsigned level, int mode, uint32_t block_size, data_off_t limit_size) + 630 : { + 631 : unsigned s; + 632 : data_off_t block_mask; + 633 : + 634 402 : handle->level = level; + 635 402 : handle->split_mac = 0; 636 : - 637 1605 : advise_init(&split->advise, mode); - 638 1605 : pathcpy(split->path, sizeof(split->path), parity->split_map[s].path); - 639 1605 : split->size = parity->split_map[s].size; - 640 1605 : split->limit_size = PARITY_LIMIT(limit_size, s, level); - 641 : - 642 : /* open for read */ - 643 : /* O_NOATIME: do not change access time */ - 644 1605 : flags = O_RDONLY | O_BINARY | advise_flags(&split->advise); - 645 : - 646 1605 : split->f = open_noatime(split->path, flags); - 647 1605 : if (split->f == -1) { - 648 : /* LCOV_EXCL_START */ - 649 : log_fatal("Error opening parity file '%s'. %s.\n", split->path, strerror(errno)); - 650 : goto bail; - 651 : /* LCOV_EXCL_STOP */ - 652 : } + 637 : /* mask of bits used by the block size */ + 638 402 : block_mask = ((data_off_t)block_size) - 1; + 639 : + 640 2006 : for (s = 0;s < parity->split_mac;++s) { + 641 1605 : struct snapraid_split_handle* split = &handle->split_map[s]; + 642 : int ret; + 643 : int flags; + 644 : + 645 1605 : advise_init(&split->advise, mode); + 646 1605 : pathcpy(split->path, sizeof(split->path), parity->split_map[s].path); + 647 1605 : split->size = parity->split_map[s].size; + 648 1605 : split->limit_size = PARITY_LIMIT(limit_size, s, level); + 649 : + 650 : /* open for read */ + 651 : /* O_NOATIME: do not change access time */ + 652 1605 : flags = O_RDONLY | O_BINARY | advise_flags(&split->advise); 653 : - 654 : /* we have a valid file handle */ - 655 1604 : ++handle->split_mac; - 656 : - 657 : /* get the stat info */ - 658 1604 : ret = fstat(split->f, &split->st); - 659 1604 : if (ret != 0) { - 660 : /* LCOV_EXCL_START */ - 661 : log_fatal("Error accessing parity file '%s'. %s.\n", split->path, strerror(errno)); - 662 : goto bail; - 663 : /* LCOV_EXCL_STOP */ - 664 : } - 665 : - 666 : /** - 667 : * If the parity size is not yet set, set it now. - 668 : * This happens when expanding the number of parities, - 669 : * or when upgrading from a content file that has not split->size data. - 670 : */ - 671 1604 : if (split->size == PARITY_SIZE_INVALID) { - 672 40 : split->size = split->st.st_size; + 654 1605 : split->f = open_noatime(split->path, flags); + 655 1605 : if (split->f == -1) { + 656 : /* LCOV_EXCL_START */ + 657 : log_fatal("Error opening parity file '%s'. %s.\n", split->path, strerror(errno)); + 658 : goto bail; + 659 : /* LCOV_EXCL_STOP */ + 660 : } + 661 : + 662 : /* we have a valid file handle */ + 663 1604 : ++handle->split_mac; + 664 : + 665 : /* get the stat info */ + 666 1604 : ret = fstat(split->f, &split->st); + 667 1604 : if (ret != 0) { + 668 : /* LCOV_EXCL_START */ + 669 : log_fatal("Error accessing parity file '%s'. %s.\n", split->path, strerror(errno)); + 670 : goto bail; + 671 : /* LCOV_EXCL_STOP */ + 672 : } 673 : - 674 : /* ensure that the resulting size if block aligned */ - 675 40 : if ((split->size & block_mask) != 0) { - 676 : /* LCOV_EXCL_START */ - 677 : log_fatal("Error in preallocated size of parity file '%s' with size %" PRIu64 " and block %u .\n", split->path, split->size, block_size); - 678 : goto bail; - 679 : /* LCOV_EXCL_STOP */ - 680 : } - 681 : } - 682 : - 683 1604 : ret = advise_open(&split->advise, split->f); - 684 1604 : if (ret != 0) { - 685 : /* LCOV_EXCL_START */ - 686 : log_fatal("Error advising parity file '%s'. %s.\n", split->path, strerror(errno)); - 687 : goto bail; - 688 : /* LCOV_EXCL_STOP */ + 674 : /** + 675 : * If the parity size is not yet set, set it now. + 676 : * This happens when expanding the number of parities, + 677 : * or when upgrading from a content file that has not split->size data. + 678 : */ + 679 1604 : if (split->size == PARITY_SIZE_INVALID) { + 680 40 : split->size = split->st.st_size; + 681 : + 682 : /* ensure that the resulting size if block aligned */ + 683 40 : if ((split->size & block_mask) != 0) { + 684 : /* LCOV_EXCL_START */ + 685 : log_fatal("Error in preallocated size of parity file '%s' with size %" PRIu64 " and block %u .\n", split->path, split->size, block_size); + 686 : goto bail; + 687 : /* LCOV_EXCL_STOP */ + 688 : } 689 : } - 690 : } - 691 : - 692 401 : return 0; - 693 : - 694 : bail: - 695 : /* LCOV_EXCL_START */ - 696 : for (s = 0;s < handle->split_mac;++s) { - 697 : struct snapraid_split_handle* split = &handle->split_map[s]; - 698 : close(split->f); - 699 : split->f = -1; - 700 : } - 701 : return -1; - 702 : /* LCOV_EXCL_STOP */ - 703 : } - 704 : - 705 469 : int parity_sync(struct snapraid_parity_handle* handle) - 706 : { - 707 : #if HAVE_FSYNC - 708 : unsigned s; - 709 : - 710 2345 : for (s = 0;s < handle->split_mac;++s) { - 711 1876 : struct snapraid_split_handle* split = &handle->split_map[s]; - 712 : int ret; - 713 : - 714 : /* Ensure that data changes are written to disk. */ - 715 : /* This is required to ensure that parity is more updated than content */ - 716 : /* in case of a system crash. */ - 717 1876 : ret = fsync(split->f); - 718 1876 : if (ret != 0) { - 719 : /* LCOV_EXCL_START */ - 720 : log_fatal("Error synching parity file '%s'. %s.\n", split->path, strerror(errno)); - 721 : return -1; - 722 : /* LCOV_EXCL_STOP */ - 723 : } - 724 : } - 725 : #endif - 726 : - 727 469 : return 0; - 728 : } - 729 : - 730 1022 : int parity_close(struct snapraid_parity_handle* handle) - 731 : { - 732 : unsigned s; - 733 1022 : int f_ret = 0; + 690 : + 691 1604 : ret = advise_open(&split->advise, split->f); + 692 1604 : if (ret != 0) { + 693 : /* LCOV_EXCL_START */ + 694 : log_fatal("Error advising parity file '%s'. %s.\n", split->path, strerror(errno)); + 695 : goto bail; + 696 : /* LCOV_EXCL_STOP */ + 697 : } + 698 : } + 699 : + 700 401 : return 0; + 701 : + 702 : bail: + 703 : /* LCOV_EXCL_START */ + 704 : for (s = 0;s < handle->split_mac;++s) { + 705 : struct snapraid_split_handle* split = &handle->split_map[s]; + 706 : close(split->f); + 707 : split->f = -1; + 708 : } + 709 : return -1; + 710 : /* LCOV_EXCL_STOP */ + 711 : } + 712 : + 713 469 : int parity_sync(struct snapraid_parity_handle* handle) + 714 : { + 715 : #if HAVE_FSYNC + 716 : unsigned s; + 717 : + 718 2345 : for (s = 0;s < handle->split_mac;++s) { + 719 1876 : struct snapraid_split_handle* split = &handle->split_map[s]; + 720 : int ret; + 721 : + 722 : /* Ensure that data changes are written to disk. */ + 723 : /* This is required to ensure that parity is more updated than content */ + 724 : /* in case of a system crash. */ + 725 1876 : ret = fsync(split->f); + 726 1876 : if (ret != 0) { + 727 : /* LCOV_EXCL_START */ + 728 : log_fatal("Error synching parity file '%s'. %s.\n", split->path, strerror(errno)); + 729 : return -1; + 730 : /* LCOV_EXCL_STOP */ + 731 : } + 732 : } + 733 : #endif 734 : - 735 5110 : for (s = 0;s < handle->split_mac;++s) { - 736 4088 : struct snapraid_split_handle* split = &handle->split_map[s]; - 737 : int ret; - 738 : - 739 4088 : ret = close(split->f); - 740 4088 : if (ret != 0) { - 741 : /* LCOV_EXCL_START */ - 742 : /* This is a serious error, as it may be the result of a failed write */ - 743 : /* identified at later time. */ - 744 : /* In a normal file-system (not NFS) it should never happen */ - 745 : log_fatal("Error closing parity file '%s'. %s.\n", split->path, strerror(errno)); - 746 : f_ret = -1; - 747 : /* LCOV_EXCL_STOP */ - 748 : - 749 : /* continue to close the others */ - 750 : } - 751 : - 752 : /* reset the descriptor */ - 753 4088 : split->f = -1; - 754 : } - 755 : - 756 1022 : return f_ret; - 757 : } - 758 : - 759 4113567 : struct snapraid_split_handle* parity_split_find(struct snapraid_parity_handle* handle, data_off_t* offset) - 760 : { - 761 : unsigned s; - 762 : - 763 4113567 : if (*offset < 0) - 764 0 : return 0; - 765 : - 766 6501737 : for (s = 0;s < handle->split_mac;++s) { - 767 6490377 : struct snapraid_split_handle* split = &handle->split_map[s]; - 768 : - 769 6490377 : if (*offset < split->size) - 770 4102207 : return split; - 771 : - 772 2388170 : *offset -= split->size; - 773 : } - 774 : - 775 11360 : return 0; - 776 : } - 777 : - 778 611751 : int parity_write(struct snapraid_parity_handle* handle, block_off_t pos, unsigned char* block_buffer, unsigned block_size) - 779 : { - 780 : ssize_t write_ret; - 781 : data_off_t offset; - 782 : struct snapraid_split_handle* split; - 783 : int ret; - 784 : - 785 611751 : offset = pos * (data_off_t)block_size; - 786 : - 787 611751 : split = parity_split_find(handle, &offset); - 788 611746 : if (!split) { - 789 : /* LCOV_EXCL_START */ - 790 : log_fatal("Writing parity data outside range at extra offset %" PRIu64 ".\n", offset); - 791 : return -1; - 792 : /* LCOV_EXCL_STOP */ - 793 : } + 735 469 : return 0; + 736 : } + 737 : + 738 1022 : int parity_close(struct snapraid_parity_handle* handle) + 739 : { + 740 : unsigned s; + 741 1022 : int f_ret = 0; + 742 : + 743 5110 : for (s = 0;s < handle->split_mac;++s) { + 744 4088 : struct snapraid_split_handle* split = &handle->split_map[s]; + 745 : int ret; + 746 : + 747 4088 : ret = close(split->f); + 748 4088 : if (ret != 0) { + 749 : /* LCOV_EXCL_START */ + 750 : /* This is a serious error, as it may be the result of a failed write */ + 751 : /* identified at later time. */ + 752 : /* In a normal file-system (not NFS) it should never happen */ + 753 : log_fatal("Error closing parity file '%s'. %s.\n", split->path, strerror(errno)); + 754 : f_ret = -1; + 755 : /* LCOV_EXCL_STOP */ + 756 : + 757 : /* continue to close the others */ + 758 : } + 759 : + 760 : /* reset the descriptor */ + 761 4088 : split->f = -1; + 762 : } + 763 : + 764 1022 : return f_ret; + 765 : } + 766 : + 767 4114025 : struct snapraid_split_handle* parity_split_find(struct snapraid_parity_handle* handle, data_off_t* offset) + 768 : { + 769 : unsigned s; + 770 : + 771 4114025 : if (*offset < 0) + 772 0 : return 0; + 773 : + 774 6502383 : for (s = 0;s < handle->split_mac;++s) { + 775 6491023 : struct snapraid_split_handle* split = &handle->split_map[s]; + 776 : + 777 6491023 : if (*offset < split->size) + 778 4102665 : return split; + 779 : + 780 2388358 : *offset -= split->size; + 781 : } + 782 : + 783 11360 : return 0; + 784 : } + 785 : + 786 612195 : int parity_write(struct snapraid_parity_handle* handle, block_off_t pos, unsigned char* block_buffer, unsigned block_size) + 787 : { + 788 : ssize_t write_ret; + 789 : data_off_t offset; + 790 : struct snapraid_split_handle* split; + 791 : int ret; + 792 : + 793 612195 : offset = pos * (data_off_t)block_size; 794 : - 795 611746 : write_ret = pwrite(split->f, block_buffer, block_size, offset); - 796 611756 : if (write_ret != (ssize_t)block_size) { /* conversion is safe because block_size is always small */ + 795 612195 : split = parity_split_find(handle, &offset); + 796 612196 : if (!split) { 797 : /* LCOV_EXCL_START */ - 798 : if (errno == ENOSPC) { - 799 : log_fatal("Failed to grow parity file '%s' using write due lack of space.\n", split->path); - 800 : } else { - 801 : log_fatal("Error writing file '%s'. %s.\n", split->path, strerror(errno)); - 802 : } - 803 : return -1; - 804 : /* LCOV_EXCL_STOP */ - 805 : } - 806 : - 807 611756 : ret = advise_write(&split->advise, split->f, offset, block_size); - 808 611756 : if (ret != 0) { - 809 : /* LCOV_EXCL_START */ - 810 : log_fatal("Error advising parity file '%s'. %s.\n", split->path, strerror(errno)); + 798 : log_fatal("Writing parity data outside range at extra offset %" PRIu64 ".\n", offset); + 799 : return -1; + 800 : /* LCOV_EXCL_STOP */ + 801 : } + 802 : + 803 612196 : write_ret = pwrite(split->f, block_buffer, block_size, offset); + 804 612199 : if (write_ret != (ssize_t)block_size) { /* conversion is safe because block_size is always small */ + 805 : /* LCOV_EXCL_START */ + 806 : if (errno == ENOSPC) { + 807 : log_fatal("Failed to grow parity file '%s' using write due lack of space.\n", split->path); + 808 : } else { + 809 : log_fatal("Error writing file '%s'. %s.\n", split->path, strerror(errno)); + 810 : } 811 : return -1; 812 : /* LCOV_EXCL_STOP */ 813 : } 814 : - 815 611756 : return 0; - 816 : } - 817 : - 818 3501825 : int parity_read(struct snapraid_parity_handle* handle, block_off_t pos, unsigned char* block_buffer, unsigned block_size, fptr* out) - 819 : { - 820 : ssize_t read_ret; - 821 : data_off_t offset; - 822 : unsigned count; - 823 : struct snapraid_split_handle* split; - 824 : int ret; + 815 612199 : ret = advise_write(&split->advise, split->f, offset, block_size); + 816 612194 : if (ret != 0) { + 817 : /* LCOV_EXCL_START */ + 818 : log_fatal("Error advising parity file '%s'. %s.\n", split->path, strerror(errno)); + 819 : return -1; + 820 : /* LCOV_EXCL_STOP */ + 821 : } + 822 : + 823 612194 : return 0; + 824 : } 825 : - 826 3501825 : offset = pos * (data_off_t)block_size; - 827 : - 828 3501825 : split = parity_split_find(handle, &offset); - 829 3501816 : if (!split) { - 830 : /* LCOV_EXCL_START */ - 831 : out("Reading parity data outside range at extra offset %" PRIu64 ".\n", offset); - 832 : return -1; - 833 : /* LCOV_EXCL_STOP */ - 834 : } + 826 3501825 : int parity_read(struct snapraid_parity_handle* handle, block_off_t pos, unsigned char* block_buffer, unsigned block_size, fptr* out) + 827 : { + 828 : ssize_t read_ret; + 829 : data_off_t offset; + 830 : unsigned count; + 831 : struct snapraid_split_handle* split; + 832 : int ret; + 833 : + 834 3501825 : offset = pos * (data_off_t)block_size; 835 : - 836 3490456 : count = 0; - 837 : do { - 838 3490442 : read_ret = pread(split->f, block_buffer + count, block_size - count, offset + count); - 839 3490403 : if (read_ret < 0) { - 840 : /* LCOV_EXCL_START */ - 841 : out("Error reading file '%s' at offset %" PRIu64 " for size %u. %s.\n", split->path, offset + count, block_size - count, strerror(errno)); - 842 : return -1; - 843 : /* LCOV_EXCL_STOP */ - 844 : } - 845 3490403 : if (read_ret == 0) { - 846 : /* LCOV_EXCL_START */ - 847 : out("Unexpected end of file '%s' at offset %" PRIu64 ". %s.\n", split->path, offset, strerror(errno)); - 848 : return -1; - 849 : /* LCOV_EXCL_STOP */ - 850 : } - 851 : - 852 3490403 : count += read_ret; - 853 3490403 : } while (count < block_size); - 854 : - 855 3490417 : ret = advise_read(&split->advise, split->f, offset, block_size); - 856 3490399 : if (ret != 0) { - 857 : /* LCOV_EXCL_START */ - 858 : out("Error advising parity file '%s'. %s.\n", split->path, strerror(errno)); - 859 : return -1; - 860 : /* LCOV_EXCL_STOP */ - 861 : } + 836 3501825 : split = parity_split_find(handle, &offset); + 837 3501814 : if (!split) { + 838 : /* LCOV_EXCL_START */ + 839 : out("Reading parity data outside range at extra offset %" PRIu64 ".\n", offset); + 840 : return -1; + 841 : /* LCOV_EXCL_STOP */ + 842 : } + 843 : + 844 3490454 : count = 0; + 845 : do { + 846 3490458 : read_ret = pread(split->f, block_buffer + count, block_size - count, offset + count); + 847 3490424 : if (read_ret < 0) { + 848 : /* LCOV_EXCL_START */ + 849 : out("Error reading file '%s' at offset %" PRIu64 " for size %u. %s.\n", split->path, offset + count, block_size - count, strerror(errno)); + 850 : return -1; + 851 : /* LCOV_EXCL_STOP */ + 852 : } + 853 3490424 : if (read_ret == 0) { + 854 : /* LCOV_EXCL_START */ + 855 : out("Unexpected end of file '%s' at offset %" PRIu64 ". %s.\n", split->path, offset, strerror(errno)); + 856 : return -1; + 857 : /* LCOV_EXCL_STOP */ + 858 : } + 859 : + 860 3490424 : count += read_ret; + 861 3490424 : } while (count < block_size); 862 : - 863 3490399 : return block_size; - 864 : } - 865 : + 863 3490420 : ret = advise_read(&split->advise, split->f, offset, block_size); + 864 3490421 : if (ret != 0) { + 865 : /* LCOV_EXCL_START */ + 866 : out("Error advising parity file '%s'. %s.\n", split->path, strerror(errno)); + 867 : return -1; + 868 : /* LCOV_EXCL_STOP */ + 869 : } + 870 : + 871 3490421 : return block_size; + 872 : } + 873 : diff --git a/cov/cmdline/scan.c.func-sort-c.html b/cov/cmdline/scan.c.func-sort-c.html index 13da2ec3..a2a7949d 100644 --- a/cov/cmdline/scan.c.func-sort-c.html +++ b/cov/cmdline/scan.c.func-sort-c.html @@ -31,9 +31,9 @@ lcov.info Lines: - 563 + 565 631 - 89.2 % + 89.5 % Date: @@ -61,23 +61,23 @@ dd_name_compare - 11526102 + 11526118 dstat - 1106198 + 1106210 scan_file - 1104927 + 1104939 scan_file_keep - 1025576 + 1025539 file_is_full_invalid_parity_and_stable - 1025576 + 1025539 dd_ino_compare @@ -85,27 +85,27 @@ scan_file_delayed_allocate - 101836 + 101892 scan_file_insert - 101836 + 101892 scan_file_allocate - 101836 + 101892 scan_file_refresh - 79156 + 79205 scan_file_remove - 56970 + 57026 scan_file_deallocate - 56970 + 57026 scan_link @@ -121,7 +121,7 @@ scan_dir - 1840 + 1846 scan_link_remove @@ -133,7 +133,7 @@ state_diffscan - 95 + 96 state_scan @@ -145,7 +145,7 @@ state_diff - 7 + 8 scan_emptydir_remove diff --git a/cov/cmdline/scan.c.func.html b/cov/cmdline/scan.c.func.html index b1d3ee83..9105ea85 100644 --- a/cov/cmdline/scan.c.func.html +++ b/cov/cmdline/scan.c.func.html @@ -31,9 +31,9 @@ lcov.info Lines: - 563 + 565 631 - 89.2 % + 89.5 % Date: @@ -65,11 +65,11 @@ dd_name_compare - 11526102 + 11526118 dstat - 1106198 + 1106210 file_is_full_hashed_and_stable @@ -77,11 +77,11 @@ file_is_full_invalid_parity_and_stable - 1025576 + 1025539 scan_dir - 1840 + 1846 scan_emptydir @@ -97,35 +97,35 @@ scan_file - 1104927 + 1104939 scan_file_allocate - 101836 + 101892 scan_file_deallocate - 56970 + 57026 scan_file_delayed_allocate - 101836 + 101892 scan_file_insert - 101836 + 101892 scan_file_keep - 1025576 + 1025539 scan_file_refresh - 79156 + 79205 scan_file_remove - 56970 + 57026 scan_link @@ -141,11 +141,11 @@ state_diff - 7 + 8 state_diffscan - 95 + 96 state_scan diff --git a/cov/cmdline/scan.c.gcov.html b/cov/cmdline/scan.c.gcov.html index d00d9cd4..4e68bddc 100644 --- a/cov/cmdline/scan.c.gcov.html +++ b/cov/cmdline/scan.c.gcov.html @@ -31,9 +31,9 @@ lcov.info Lines: - 563 + 565 631 - 89.2 % + 89.5 % Date: @@ -220,72 +220,72 @@ 158 : /** 159 : * Insert the specified file in the parity. 160 : */ - 161 101836 : static void scan_file_allocate(struct snapraid_scan* scan, struct snapraid_file* file) + 161 101892 : static void scan_file_allocate(struct snapraid_scan* scan, struct snapraid_file* file) 162 : { - 163 101836 : struct snapraid_state* state = scan->state; - 164 101836 : struct snapraid_disk* disk = scan->disk; + 163 101892 : struct snapraid_state* state = scan->state; + 164 101892 : struct snapraid_disk* disk = scan->disk; 165 : block_off_t i; 166 : block_off_t parity_pos; 167 : 168 : /* state changed */ - 169 101836 : state->need_write = 1; + 169 101892 : state->need_write = 1; 170 : 171 : /* allocate the blocks of the file */ - 172 101836 : parity_pos = disk->first_free_block; - 173 352922 : for (i = 0; i < file->blockmax; ++i) { + 172 101892 : parity_pos = disk->first_free_block; + 173 353160 : for (i = 0; i < file->blockmax; ++i) { 174 : struct snapraid_block* block; 175 : struct snapraid_block* over_block; 176 : snapraid_info info; 177 : 178 : /* increment the position until the first really free block */ - 179 1022464 : while (block_has_file(fs_par2block_find(disk, parity_pos))) - 180 520292 : ++parity_pos; + 179 1022825 : while (block_has_file(fs_par2block_find(disk, parity_pos))) + 180 520289 : ++parity_pos; 181 : 182 : /* get block we are going to overwrite, if any */ - 183 251086 : over_block = fs_par2block_find(disk, parity_pos); + 183 251268 : over_block = fs_par2block_find(disk, parity_pos); 184 : 185 : /* deallocate it */ - 186 251086 : if (over_block != BLOCK_NULL) - 187 95173 : fs_deallocate(disk, parity_pos); + 186 251268 : if (over_block != BLOCK_NULL) + 187 95355 : fs_deallocate(disk, parity_pos); 188 : 189 : /* get block specific info */ - 190 251086 : info = info_get(&state->infoarr, parity_pos); + 190 251268 : info = info_get(&state->infoarr, parity_pos); 191 : 192 : /* get the new block we are going to write */ - 193 251086 : block = fs_file2block_get(file, i); + 193 251268 : block = fs_file2block_get(file, i); 194 : 195 : /* if the file block already has an updated hash without rehash */ - 196 251086 : if (block_has_updated_hash(block) && !info_get_rehash(info)) { + 196 251268 : if (block_has_updated_hash(block) && !info_get_rehash(info)) { 197 : /* the only possible case is for REP blocks */ - 198 86199 : assert(block_state_get(block) == BLOCK_STATE_REP); + 198 86215 : assert(block_state_get(block) == BLOCK_STATE_REP); 199 : 200 : /* convert to a REP block */ - 201 86199 : block_state_set(block, BLOCK_STATE_REP); + 201 86215 : block_state_set(block, BLOCK_STATE_REP); 202 : 203 : /* and keep the hash as it's */ 204 : } else { 205 : unsigned over_state; 206 : 207 : /* convert to a CHG block */ - 208 164887 : block_state_set(block, BLOCK_STATE_CHG); + 208 165053 : block_state_set(block, BLOCK_STATE_CHG); 209 : 210 : /* state of the block we are going to overwrite */ - 211 164887 : over_state = block_state_get(over_block); + 211 165053 : over_state = block_state_get(over_block); 212 : 213 : /* if the block is an empty one */ - 214 164887 : if (over_state == BLOCK_STATE_EMPTY) { + 214 165053 : if (over_state == BLOCK_STATE_EMPTY) { 215 : /* the block was empty and filled with zeros */ 216 : /* set the hash to the special ZERO value */ 217 115543 : hash_zero_set(block->hash); 218 : } else { 219 : /* otherwise it's a DELETED one */ - 220 49344 : assert(over_state == BLOCK_STATE_DELETED); + 220 49510 : assert(over_state == BLOCK_STATE_DELETED); 221 : 222 : /* copy the past hash of the block */ - 223 49344 : memcpy(block->hash, over_block->hash, BLOCK_HASH_SIZE); + 223 49510 : memcpy(block->hash, over_block->hash, BLOCK_HASH_SIZE); 224 : 225 : /* if we have not already cleared the past hash */ - 226 49344 : if (!state->clear_past_hash) { + 226 49510 : if (!state->clear_past_hash) { 227 : /* in this case we don't know if the old state is still the one */ 228 : /* stored inside the parity, because after an aborted sync, the parity */ 229 : /* may be or may be not have been updated with the new data */ @@ -296,21 +296,21 @@ 234 : /* but without saving the content file representing this new state. */ 235 : /* - Another file is added again (exactly here) */ 236 : /* with the hash of DELETED block not representing the real parity state */ - 237 381 : hash_invalid_set(block->hash); + 237 421 : hash_invalid_set(block->hash); 238 : } 239 : } 240 : } 241 : 242 : /* store in the disk map, after invalidating all the other blocks */ - 243 251086 : fs_allocate(disk, parity_pos, file, i); + 243 251268 : fs_allocate(disk, parity_pos, file, i); 244 : 245 : /* set the new free position */ - 246 251086 : disk->first_free_block = parity_pos + 1; + 246 251268 : disk->first_free_block = parity_pos + 1; 247 : } 248 : 249 : /* insert in the list of contained files */ - 250 101836 : tommy_list_insert_tail(&disk->filelist, &file->nodelist, file); - 251 101836 : } + 250 101892 : tommy_list_insert_tail(&disk->filelist, &file->nodelist, file); + 251 101892 : } 252 : 253 : /** 254 : * Delete the specified file from the parity. @@ -319,23 +319,23 @@ 257 : * The file is then inserted in the deleted set, and it should not be deallocated, 258 : * as the parity still references it. 259 : */ - 260 56970 : static void scan_file_deallocate(struct snapraid_scan* scan, struct snapraid_file* file) + 260 57026 : static void scan_file_deallocate(struct snapraid_scan* scan, struct snapraid_file* file) 261 : { - 262 56970 : struct snapraid_state* state = scan->state; - 263 56970 : struct snapraid_disk* disk = scan->disk; + 262 57026 : struct snapraid_state* state = scan->state; + 263 57026 : struct snapraid_disk* disk = scan->disk; 264 : block_off_t i; 265 : 266 : /* remove from the list of contained files */ - 267 56970 : tommy_list_remove_existing(&disk->filelist, &file->nodelist); + 267 57026 : tommy_list_remove_existing(&disk->filelist, &file->nodelist); 268 : 269 : /* state changed */ - 270 56970 : state->need_write = 1; + 270 57026 : state->need_write = 1; 271 : 272 : /* here we are supposed to adjust the ::first_free_block position */ 273 : /* with the parity position we are deleting */ 274 : /* but we also know that we do only delayed insert, after all the deletion, */ 275 : /* so at this point ::first_free_block is always at 0, and we don't need to update it */ - 276 56970 : if (disk->first_free_block != 0) { + 276 57026 : if (disk->first_free_block != 0) { 277 : /* LCOV_EXCL_START */ 278 : log_fatal("Internal inconsistency for first free position at '%u' deallocating file '%s'\n", disk->first_free_block, file->sub); 279 : os_abort(); @@ -343,20 +343,20 @@ 281 : } 282 : 283 : /* free all the blocks of the file */ - 284 197441 : for (i = 0; i < file->blockmax; ++i) { - 285 140471 : struct snapraid_block* block = fs_file2block_get(file, i); + 284 197679 : for (i = 0; i < file->blockmax; ++i) { + 285 140653 : struct snapraid_block* block = fs_file2block_get(file, i); 286 : unsigned block_state; 287 : 288 : /* in case we scan after an aborted sync, */ 289 : /* we could get also intermediate states */ - 290 140471 : block_state = block_state_get(block); - 291 140471 : switch (block_state) { + 290 140653 : block_state = block_state_get(block); + 291 140653 : switch (block_state) { 292 : case BLOCK_STATE_BLK : 293 : /* we keep the hash making it an "old" hash, because the parity is still containing data for it */ - 294 35530 : break; + 294 35656 : break; 295 : case BLOCK_STATE_CHG : 296 : /* if we have not already cleared the past hash */ - 297 28000 : if (!state->clear_past_hash) { + 297 28040 : if (!state->clear_past_hash) { 298 : /* in these cases we don't know if the old state is still the one */ 299 : /* stored inside the parity, because after an aborted sync, the parity */ 300 : /* may be or may be not have been updated with the data that it's now */ @@ -368,13 +368,13 @@ 306 : /* - File is now deleted after the aborted sync */ 307 : /* - Sync again, deleting the blocks (exactly here) */ 308 : /* with the hash of CHG block not representing the real parity state */ - 309 0 : hash_invalid_set(block->hash); + 309 40 : hash_invalid_set(block->hash); 310 : } - 311 28000 : break; + 311 28040 : break; 312 : case BLOCK_STATE_REP : 313 : /* we just don't know the old hash, and then we set it to invalid */ - 314 76941 : hash_invalid_set(block->hash); - 315 76941 : break; + 314 76957 : hash_invalid_set(block->hash); + 315 76957 : break; 316 : default : 317 : /* LCOV_EXCL_START */ 318 : log_fatal("Internal inconsistency in file '%s' deallocating block '%u:%u' state %u\n", file->sub, i, file->blockmax, block_state); @@ -383,23 +383,23 @@ 321 : } 322 : 323 : /* set the block as deleted */ - 324 140471 : block_state_set(block, BLOCK_STATE_DELETED); + 324 140653 : block_state_set(block, BLOCK_STATE_DELETED); 325 : } 326 : 327 : /* mark the file as deleted */ - 328 56970 : file_flag_set(file, FILE_IS_DELETED); + 328 57026 : file_flag_set(file, FILE_IS_DELETED); 329 : 330 : /* insert it in the list of deleted blocks */ - 331 56970 : tommy_list_insert_tail(&disk->deletedlist, &file->nodelist, file); - 332 56970 : } + 331 57026 : tommy_list_insert_tail(&disk->deletedlist, &file->nodelist, file); + 332 57026 : } 333 : - 334 101836 : static void scan_file_delayed_allocate(struct snapraid_scan* scan, struct snapraid_file* file) + 334 101892 : static void scan_file_delayed_allocate(struct snapraid_scan* scan, struct snapraid_file* file) 335 : { - 336 101836 : struct snapraid_state* state = scan->state; - 337 101836 : struct snapraid_disk* disk = scan->disk; + 336 101892 : struct snapraid_state* state = scan->state; + 337 101892 : struct snapraid_disk* disk = scan->disk; 338 : 339 : /* if we sort for physical offsets we have to read them for new files */ - 340 101836 : if (state->opt.force_order == SORT_PHYSICAL + 340 101892 : if (state->opt.force_order == SORT_PHYSICAL 341 11432 : && file->physical == FILEPHY_UNREAD_OFFSET 342 : ) { 343 : char path_next[PATH_MAX]; @@ -415,30 +415,30 @@ 353 : } 354 : 355 : /* insert in the delayed list */ - 356 101836 : tommy_list_insert_tail(&scan->file_insert_list, &file->nodelist, file); - 357 101836 : } + 356 101892 : tommy_list_insert_tail(&scan->file_insert_list, &file->nodelist, file); + 357 101892 : } 358 : 359 : /** 360 : * Check if a file is completely formed of blocks with invalid parity, 361 : * and no rehash is tagged, and if it has at least one block. 362 : */ - 363 1025576 : static int file_is_full_invalid_parity_and_stable(struct snapraid_state* state, struct snapraid_disk* disk, struct snapraid_file* file) + 363 1025539 : static int file_is_full_invalid_parity_and_stable(struct snapraid_state* state, struct snapraid_disk* disk, struct snapraid_file* file) 364 : { 365 : block_off_t i; 366 : 367 : /* with no block, it never has an invalid parity */ - 368 1025576 : if (file->blockmax == 0) - 369 1436 : return 0; + 368 1025539 : if (file->blockmax == 0) + 369 1437 : return 0; 370 : 371 : /* check all blocks */ - 372 1080052 : for (i = 0; i < file->blockmax; ++i) { + 372 1080070 : for (i = 0; i < file->blockmax; ++i) { 373 : snapraid_info info; - 374 1057372 : struct snapraid_block* block = fs_file2block_get(file, i); + 374 1057383 : struct snapraid_block* block = fs_file2block_get(file, i); 375 : block_off_t parity_pos; 376 : 377 : /* exclude blocks with parity */ - 378 1057372 : if (!block_has_invalid_parity(block)) - 379 1001460 : return 0; + 378 1057383 : if (!block_has_invalid_parity(block)) + 379 1001415 : return 0; 380 : 381 : /* 382 : * Get the parity position. @@ -448,20 +448,20 @@ 386 : * 387 : * Anyway, checking for POS_NULL doesn't hurt. 388 : */ - 389 55912 : parity_pos = fs_file2par_find(disk, file, i); + 389 55968 : parity_pos = fs_file2par_find(disk, file, i); 390 : 391 : /* if it's not mapped, it cannot have rehash */ - 392 55912 : if (parity_pos != POS_NULL) { + 392 55968 : if (parity_pos != POS_NULL) { 393 : /* get block specific info */ - 394 55912 : info = info_get(&state->infoarr, parity_pos); + 394 55968 : info = info_get(&state->infoarr, parity_pos); 395 : 396 : /* if rehash fails */ - 397 55912 : if (info_get_rehash(info)) + 397 55968 : if (info_get_rehash(info)) 398 0 : return 0; 399 : } 400 : } 401 : - 402 22680 : return 1; + 402 22687 : return 1; 403 : } 404 : 405 : /** @@ -525,7 +525,7 @@ 463 : * 464 : * If this happens, we read also the physical offset, to avoid to read it later. 465 : */ - 466 79156 : static void scan_file_refresh(struct snapraid_scan* scan, const char* sub, struct stat* st, uint64_t* physical) + 466 79205 : static void scan_file_refresh(struct snapraid_scan* scan, const char* sub, struct stat* st, uint64_t* physical) 467 : { 468 : #if HAVE_LSTAT_SYNC 469 : struct snapraid_state* state = scan->state; @@ -597,43 +597,43 @@ 535 : (void)st; 536 : (void)physical; 537 : #endif - 538 79156 : } + 538 79205 : } 539 : 540 : /** 541 : * Insert the file in the data set. 542 : */ - 543 101836 : static void scan_file_insert(struct snapraid_scan* scan, struct snapraid_file* file) + 543 101892 : static void scan_file_insert(struct snapraid_scan* scan, struct snapraid_file* file) 544 : { - 545 101836 : struct snapraid_disk* disk = scan->disk; + 545 101892 : struct snapraid_disk* disk = scan->disk; 546 : 547 : /* insert the file in the containers */ - 548 101836 : if (!file_flag_has(file, FILE_IS_WITHOUT_INODE)) - 549 101836 : tommy_hashdyn_insert(&disk->inodeset, &file->nodeset, file, file_inode_hash(file->inode)); - 550 101836 : tommy_hashdyn_insert(&disk->pathset, &file->pathset, file, file_path_hash(file->sub)); - 551 101836 : tommy_hashdyn_insert(&disk->stampset, &file->stampset, file, file_stamp_hash(file->size, file->mtime_sec, file->mtime_nsec)); + 548 101892 : if (!file_flag_has(file, FILE_IS_WITHOUT_INODE)) + 549 101892 : tommy_hashdyn_insert(&disk->inodeset, &file->nodeset, file, file_inode_hash(file->inode)); + 550 101892 : tommy_hashdyn_insert(&disk->pathset, &file->pathset, file, file_path_hash(file->sub)); + 551 101892 : tommy_hashdyn_insert(&disk->stampset, &file->stampset, file, file_stamp_hash(file->size, file->mtime_sec, file->mtime_nsec)); 552 : 553 : /* delayed allocation of the parity */ - 554 101836 : scan_file_delayed_allocate(scan, file); - 555 101836 : } + 554 101892 : scan_file_delayed_allocate(scan, file); + 555 101892 : } 556 : 557 : /** 558 : * Remove the file from the data set. 559 : * 560 : * File is then deleted. 561 : */ - 562 56970 : static void scan_file_remove(struct snapraid_scan* scan, struct snapraid_file* file) + 562 57026 : static void scan_file_remove(struct snapraid_scan* scan, struct snapraid_file* file) 563 : { - 564 56970 : struct snapraid_disk* disk = scan->disk; + 564 57026 : struct snapraid_disk* disk = scan->disk; 565 : 566 : /* remove the file from the containers */ - 567 56970 : if (!file_flag_has(file, FILE_IS_WITHOUT_INODE)) - 568 56918 : tommy_hashdyn_remove_existing(&disk->inodeset, &file->nodeset); - 569 56970 : tommy_hashdyn_remove_existing(&disk->pathset, &file->pathset); - 570 56970 : tommy_hashdyn_remove_existing(&disk->stampset, &file->stampset); + 567 57026 : if (!file_flag_has(file, FILE_IS_WITHOUT_INODE)) + 568 56974 : tommy_hashdyn_remove_existing(&disk->inodeset, &file->nodeset); + 569 57026 : tommy_hashdyn_remove_existing(&disk->pathset, &file->pathset); + 570 57026 : tommy_hashdyn_remove_existing(&disk->stampset, &file->stampset); 571 : 572 : /* deallocate the file from the parity */ - 573 56970 : scan_file_deallocate(scan, file); - 574 56970 : } + 573 57026 : scan_file_deallocate(scan, file); + 574 57026 : } 575 : 576 : /** 577 : * Keep the file as it's (or with only a name/inode modification). @@ -646,29 +646,29 @@ 584 : * This could happen after a failed sync, when some other files are deleted, 585 : * and then new ones can be moved backward to fill the hole created. 586 : */ - 587 1025576 : static void scan_file_keep(struct snapraid_scan* scan, struct snapraid_file* file) + 587 1025539 : static void scan_file_keep(struct snapraid_scan* scan, struct snapraid_file* file) 588 : { - 589 1025576 : struct snapraid_disk* disk = scan->disk; + 589 1025539 : struct snapraid_disk* disk = scan->disk; 590 : 591 : /* if the file is full invalid, schedule a reinsert at later stage */ - 592 1025576 : if (file_is_full_invalid_parity_and_stable(scan->state, disk, file)) { - 593 22680 : struct snapraid_file* copy = file_dup(file); + 592 1025539 : if (file_is_full_invalid_parity_and_stable(scan->state, disk, file)) { + 593 22687 : struct snapraid_file* copy = file_dup(file); 594 : 595 : /* remove the file */ - 596 22680 : scan_file_remove(scan, file); + 596 22687 : scan_file_remove(scan, file); 597 : 598 : /* reinsert the copy in the delayed list */ - 599 22680 : scan_file_insert(scan, copy); + 599 22687 : scan_file_insert(scan, copy); 600 : } - 601 1025576 : } + 601 1025539 : } 602 : 603 : /** 604 : * Process a file. 605 : */ - 606 1104927 : static void scan_file(struct snapraid_scan* scan, int is_diff, const char* sub, struct stat* st, uint64_t physical) + 606 1104939 : static void scan_file(struct snapraid_scan* scan, int is_diff, const char* sub, struct stat* st, uint64_t physical) 607 : { - 608 1104927 : struct snapraid_state* state = scan->state; - 609 1104927 : struct snapraid_disk* disk = scan->disk; + 608 1104939 : struct snapraid_state* state = scan->state; + 609 1104939 : struct snapraid_disk* disk = scan->disk; 610 : struct snapraid_file* file; 611 : tommy_node* i; 612 : int is_original_file_size_different_than_zero; @@ -706,28 +706,28 @@ 644 : * This ensures that no file is found with a past inode, but at the same time, 645 : * it allows to find new files with the same inode, to identify them as hardlinks. 646 : */ - 647 1104927 : int has_past_inodes = !disk->has_volatile_inodes && !disk->has_different_uuid && !disk->has_unsupported_uuid; + 647 1104939 : int has_past_inodes = !disk->has_volatile_inodes && !disk->has_different_uuid && !disk->has_unsupported_uuid; 648 : 649 : /* always search with the new inode, in the all new inodes found until now, */ 650 : /* with the eventual presence of also the past inodes */ - 651 1104927 : uint64_t inode = st->st_ino; + 651 1104939 : uint64_t inode = st->st_ino; 652 : - 653 1104927 : file = tommy_hashdyn_search(&disk->inodeset, file_inode_compare_to_arg, &inode, file_inode_hash(inode)); + 653 1104939 : file = tommy_hashdyn_search(&disk->inodeset, file_inode_compare_to_arg, &inode, file_inode_hash(inode)); 654 : 655 : /* identify moved files with past inodes and hardlinks with the new inodes */ - 656 1104927 : if (file) { + 656 1104939 : if (file) { 657 : /* check if the file is not changed */ - 658 949639 : if (file->size == st->st_size - 659 935884 : && file->mtime_sec == st->st_mtime - 660 932864 : && (file->mtime_nsec == STAT_NSEC(st) + 658 949678 : if (file->size == st->st_size + 659 935913 : && file->mtime_sec == st->st_mtime + 660 932896 : && (file->mtime_nsec == STAT_NSEC(st) 661 : /* always accept the stored value if it's STAT_NSEC_INVALID */ 662 : /* it happens when upgrading from an old version of SnapRAID */ 663 : /* not yet supporting the nanosecond field */ - 664 2 : || file->mtime_nsec == STAT_NSEC_INVALID + 664 1 : || file->mtime_nsec == STAT_NSEC_INVALID 665 : ) 666 : ) { 667 : /* check if multiple files have the same inode */ - 668 932862 : if (file_flag_has(file, FILE_IS_PRESENT)) { + 668 932895 : if (file_flag_has(file, FILE_IS_PRESENT)) { 669 : #if HAVE_STRUCT_STAT_ST_NLINK 670 195 : if (st->st_nlink <= 1) { 671 : /* LCOV_EXCL_START */ @@ -742,11 +742,11 @@ 680 : } 681 : 682 : /* mark as present */ - 683 932667 : file_flag_set(file, FILE_IS_PRESENT); + 683 932700 : file_flag_set(file, FILE_IS_PRESENT); 684 : 685 : /* update the nanoseconds mtime only if different */ 686 : /* to avoid unneeded updates */ - 687 932667 : if (file->mtime_nsec == STAT_NSEC_INVALID + 687 932700 : if (file->mtime_nsec == STAT_NSEC_INVALID 688 0 : && STAT_NSEC(st) != file->mtime_nsec 689 : ) { 690 0 : file->mtime_nsec = STAT_NSEC(st); @@ -755,7 +755,7 @@ 693 0 : state->need_write = 1; 694 : } 695 : - 696 932667 : if (strcmp(file->sub, sub) != 0) { + 696 932700 : if (strcmp(file->sub, sub) != 0) { 697 : /* if the path is different, it means a moved file with the same inode */ 698 155 : ++scan->count_move; 699 : @@ -777,18 +777,18 @@ 715 155 : state->need_write = 1; 716 : } else { 717 : /* otherwise it's equal */ - 718 932512 : ++scan->count_equal; + 718 932545 : ++scan->count_equal; 719 : - 720 932512 : if (state->opt.gui) { - 721 22599 : log_tag("scan:equal:%s:%s\n", disk->name, esc_tag(file->sub, esc_buffer)); + 720 932545 : if (state->opt.gui) { + 721 22611 : log_tag("scan:equal:%s:%s\n", disk->name, esc_tag(file->sub, esc_buffer)); 722 : } 723 : } 724 : 725 : /* mark the file as kept */ - 726 932667 : scan_file_keep(scan, file); + 726 932700 : scan_file_keep(scan, file); 727 : 728 : /* nothing more to do */ - 729 932667 : return; + 729 932700 : return; 730 : } 731 : 732 : /* here the file matches the inode, but not the other info */ @@ -797,7 +797,7 @@ 735 : /* or a file-system with not persistent inodes */ 736 : 737 : /* for sure it cannot be already present */ - 738 16777 : if (file_flag_has(file, FILE_IS_PRESENT)) { + 738 16783 : if (file_flag_has(file, FILE_IS_PRESENT)) { 739 : /* LCOV_EXCL_START */ 740 : log_fatal("Internal inode '%" PRIu64 "' inconsistency for files '%s%s' and '%s%s' matching and already present but different\n", file->inode, disk->dir, sub, disk->dir, file->sub); 741 : os_abort(); @@ -810,44 +810,44 @@ 748 : /* otherwise, it will get removed */ 749 : 750 : /* remove from the inode set */ - 751 16777 : tommy_hashdyn_remove_existing(&disk->inodeset, &file->nodeset); + 751 16783 : tommy_hashdyn_remove_existing(&disk->inodeset, &file->nodeset); 752 : 753 : /* clear the inode */ 754 : /* this is not really needed for correct functionality */ 755 : /* because we are going to set FILE_IS_WITHOUT_INODE */ 756 : /* but it's easier for debugging to have invalid inodes set to 0 */ - 757 16777 : file->inode = 0; + 757 16783 : file->inode = 0; 758 : 759 : /* mark as missing inode */ - 760 16777 : file_flag_set(file, FILE_IS_WITHOUT_INODE); + 760 16783 : file_flag_set(file, FILE_IS_WITHOUT_INODE); 761 : 762 : /* go further to find it by name */ 763 : } 764 : 765 : /* initialize for later overwrite */ - 766 172065 : is_file_reported = 0; - 767 172065 : is_original_file_size_different_than_zero = 0; + 766 172044 : is_file_reported = 0; + 767 172044 : is_original_file_size_different_than_zero = 0; 768 : 769 : /* then try finding it by name */ - 770 172065 : file = tommy_hashdyn_search(&disk->pathset, file_path_compare_to_arg, sub, file_path_hash(sub)); + 770 172044 : file = tommy_hashdyn_search(&disk->pathset, file_path_compare_to_arg, sub, file_path_hash(sub)); 771 : 772 : /* keep track if the file already exists */ - 773 172065 : is_file_already_present = file != 0; + 773 172044 : is_file_already_present = file != 0; 774 : - 775 172065 : if (is_file_already_present) { + 775 172044 : if (is_file_already_present) { 776 : /* if the file is without an inode */ - 777 97552 : if (file_flag_has(file, FILE_IS_WITHOUT_INODE)) { + 777 97531 : if (file_flag_has(file, FILE_IS_WITHOUT_INODE)) { 778 : /* set it now */ - 779 16739 : file->inode = st->st_ino; + 779 16745 : file->inode = st->st_ino; 780 : 781 : /* insert in the set */ - 782 16739 : tommy_hashdyn_insert(&disk->inodeset, &file->nodeset, file, file_inode_hash(file->inode)); + 782 16745 : tommy_hashdyn_insert(&disk->inodeset, &file->nodeset, file, file_inode_hash(file->inode)); 783 : 784 : /* unmark as missing inode */ - 785 16739 : file_flag_clear(file, FILE_IS_WITHOUT_INODE); + 785 16745 : file_flag_clear(file, FILE_IS_WITHOUT_INODE); 786 : } else { 787 : /* here the inode has to be different, otherwise we would have found it before */ - 788 80813 : if (file->inode == st->st_ino) { + 788 80786 : if (file->inode == st->st_ino) { 789 : /* LCOV_EXCL_START */ 790 : log_fatal("Internal inconsistency in inode '%" PRIu64 "' for files '%s%s' as unexpected matching\n", file->inode, disk->dir, sub); 791 : os_abort(); @@ -856,7 +856,7 @@ 794 : } 795 : 796 : /* for sure it cannot be already present */ - 797 97552 : if (file_flag_has(file, FILE_IS_PRESENT)) { + 797 97531 : if (file_flag_has(file, FILE_IS_PRESENT)) { 798 : /* LCOV_EXCL_START */ 799 : log_fatal("Internal inconsistency in path for file '%s%s' matching and already present\n", disk->dir, sub); 800 : os_abort(); @@ -864,9 +864,9 @@ 802 : } 803 : 804 : /* check if the file is not changed */ - 805 97552 : if (file->size == st->st_size - 806 96956 : && file->mtime_sec == st->st_mtime - 807 92909 : && (file->mtime_nsec == STAT_NSEC(st) + 805 97531 : if (file->size == st->st_size + 806 96935 : && file->mtime_sec == st->st_mtime + 807 92839 : && (file->mtime_nsec == STAT_NSEC(st) 808 : /* always accept the stored value if it's STAT_NSEC_INVALID */ 809 : /* it happens when upgrading from an old version of SnapRAID */ 810 : /* not yet supporting the nanosecond field */ @@ -874,11 +874,11 @@ 812 : ) 813 : ) { 814 : /* mark as present */ - 815 92909 : file_flag_set(file, FILE_IS_PRESENT); + 815 92839 : file_flag_set(file, FILE_IS_PRESENT); 816 : 817 : /* update the nano seconds mtime only if different */ 818 : /* to avoid unneeded updates */ - 819 92909 : if (file->mtime_nsec == STAT_NSEC_INVALID + 819 92839 : if (file->mtime_nsec == STAT_NSEC_INVALID 820 0 : && STAT_NSEC(st) != STAT_NSEC_INVALID 821 : ) { 822 0 : file->mtime_nsec = STAT_NSEC(st); @@ -888,30 +888,30 @@ 826 : } 827 : 828 : /* if when processing the disk we used the past inodes values */ - 829 92909 : if (has_past_inodes) { + 829 92839 : if (has_past_inodes) { 830 : /* if persistent inodes are supported, we are sure that the inode number */ 831 : /* is now different, because otherwise the file would have been found */ 832 : /* when searching by inode. */ 833 : /* if the inode is different, it means a rewritten file with the same path */ 834 : /* like when restoring a backup that restores also the timestamp */ - 835 92895 : ++scan->count_restore; + 835 92825 : ++scan->count_restore; 836 : - 837 92895 : log_tag("scan:restore:%s:%s\n", disk->name, esc_tag(sub, esc_buffer)); - 838 92895 : if (is_diff) { + 837 92825 : log_tag("scan:restore:%s:%s\n", disk->name, esc_tag(sub, esc_buffer)); + 838 92825 : if (is_diff) { 839 0 : printf("restore %s\n", fmt_term(disk, sub, esc_buffer)); 840 : } 841 : 842 : /* remove from the inode set */ - 843 92895 : tommy_hashdyn_remove_existing(&disk->inodeset, &file->nodeset); + 843 92825 : tommy_hashdyn_remove_existing(&disk->inodeset, &file->nodeset); 844 : 845 : /* save the new inode */ - 846 92895 : file->inode = st->st_ino; + 846 92825 : file->inode = st->st_ino; 847 : 848 : /* reinsert in the inode set */ - 849 92895 : tommy_hashdyn_insert(&disk->inodeset, &file->nodeset, file, file_inode_hash(file->inode)); + 849 92825 : tommy_hashdyn_insert(&disk->inodeset, &file->nodeset, file, file_inode_hash(file->inode)); 850 : 851 : /* we have to save the new inode */ - 852 92895 : state->need_write = 1; + 852 92825 : state->need_write = 1; 853 : } else { 854 : /* otherwise it's the case of not persistent inode, where doesn't */ 855 : /* matter if the inode is different or equal, because they have no */ @@ -924,24 +924,24 @@ 862 : } 863 : 864 : /* mark the file as kept */ - 865 92909 : scan_file_keep(scan, file); + 865 92839 : scan_file_keep(scan, file); 866 : 867 : /* nothing more to do */ - 868 92909 : return; + 868 92839 : return; 869 : } 870 : 871 : /* here if the file is changed but with the correct name */ 872 : 873 : /* save the info for later printout */ - 874 4643 : file_already_present_size = file->size; - 875 4643 : file_already_present_mtime_sec = file->mtime_sec; - 876 4643 : file_already_present_mtime_nsec = file->mtime_nsec; + 874 4692 : file_already_present_size = file->size; + 875 4692 : file_already_present_mtime_sec = file->mtime_sec; + 876 4692 : file_already_present_mtime_nsec = file->mtime_nsec; 877 : 878 : /* keep track if the original file was not of zero size */ - 879 4643 : is_original_file_size_different_than_zero = file->size != 0; + 879 4692 : is_original_file_size_different_than_zero = file->size != 0; 880 : 881 : /* remove it, and continue to insert it again */ - 882 4643 : scan_file_remove(scan, file); + 882 4692 : scan_file_remove(scan, file); 883 : 884 : /* and continue to insert it again */ 885 : } else { @@ -953,13 +953,13 @@ 891 : /* refresh the info, to ensure that they are synced, */ 892 : /* note that we refresh only the info of the new or modified files */ 893 : /* because this is slow operation */ - 894 79156 : scan_file_refresh(scan, sub, st, &physical); + 894 79205 : scan_file_refresh(scan, sub, st, &physical); 895 : 896 : #ifndef _WIN32 897 : /* do a safety check to ensure that the common ext4 case of zeroing */ 898 : /* the size of a file after a crash doesn't propagate to the backup */ 899 : /* this check is specific for Linux, so we disable it on Windows */ - 900 79156 : if (is_original_file_size_different_than_zero && st->st_size == 0) { + 900 79205 : if (is_original_file_size_different_than_zero && st->st_size == 0) { 901 0 : if (!state->opt.force_zero) { 902 : /* LCOV_EXCL_START */ 903 : log_fatal("The file '%s%s' has unexpected zero size!\n", disk->dir, sub); @@ -978,33 +978,33 @@ 916 : #endif 917 : 918 : /* insert it */ - 919 79156 : file = file_alloc(state->block_size, sub, st->st_size, st->st_mtime, STAT_NSEC(st), st->st_ino, physical); + 919 79205 : file = file_alloc(state->block_size, sub, st->st_size, st->st_mtime, STAT_NSEC(st), st->st_ino, physical); 920 : 921 : /* mark it as present */ - 922 79156 : file_flag_set(file, FILE_IS_PRESENT); + 922 79205 : file_flag_set(file, FILE_IS_PRESENT); 923 : 924 : /* if copy detection is enabled */ 925 : /* note that the copy detection is tried also for updated files */ 926 : /* this makes sense because it may happen to have two different copies */ 927 : /* of the same file, and we move the right one over the wrong one */ 928 : /* in such case we have a "copy" over an "update" */ - 929 79156 : if (!state->opt.force_nocopy) { - 930 79156 : tommy_uint32_t hash = file_stamp_hash(file->size, file->mtime_sec, file->mtime_nsec); + 929 79205 : if (!state->opt.force_nocopy) { + 930 79205 : tommy_uint32_t hash = file_stamp_hash(file->size, file->mtime_sec, file->mtime_nsec); 931 : 932 : /* search for a file with the same name and stamp in all the disks */ - 933 423144 : for (i = state->disklist; i != 0; i = i->next) { - 934 367624 : struct snapraid_disk* other_disk = i->data; + 933 423487 : for (i = state->disklist; i != 0; i = i->next) { + 934 367918 : struct snapraid_disk* other_disk = i->data; 935 : struct snapraid_file* other_file; 936 : 937 : /* if the nanosecond part of the time stamp is valid, search */ 938 : /* for name and stamp, otherwise for path and stamp */ - 939 367624 : if (file->mtime_nsec != 0 && file->mtime_nsec != STAT_NSEC_INVALID) - 940 367516 : other_file = tommy_hashdyn_search(&other_disk->stampset, file_namestamp_compare, file, hash); + 939 367918 : if (file->mtime_nsec != 0 && file->mtime_nsec != STAT_NSEC_INVALID) + 940 367810 : other_file = tommy_hashdyn_search(&other_disk->stampset, file_namestamp_compare, file, hash); 941 : else 942 108 : other_file = tommy_hashdyn_search(&other_disk->stampset, file_pathstamp_compare, file, hash); 943 : 944 : /* if found, and it's a fully hashed file */ - 945 367624 : if (other_file && file_is_full_hashed_and_stable(scan->state, other_disk, other_file)) { + 945 367918 : if (other_file && file_is_full_hashed_and_stable(scan->state, other_disk, other_file)) { 946 : /* assume that the file is a copy, and reuse the hash */ 947 23636 : file_copy(other_file, file); 948 : @@ -1027,16 +1027,16 @@ 965 : 966 : /* if not yet reported, do it now */ 967 : /* we postpone this to avoid to print two times the copied files */ - 968 79156 : if (!is_file_reported) { - 969 55520 : if (is_file_already_present) { - 970 4643 : ++scan->count_change; + 968 79205 : if (!is_file_reported) { + 969 55569 : if (is_file_already_present) { + 970 4692 : ++scan->count_change; 971 : - 972 13929 : log_tag("scan:update:%s:%s: %" PRIu64 " %" PRIu64 ".%d -> %" PRIu64 " %" PRIu64 ".%d\n", disk->name, esc_tag(sub, esc_buffer), + 972 14076 : log_tag("scan:update:%s:%s: %" PRIu64 " %" PRIu64 ".%d -> %" PRIu64 " %" PRIu64 ".%d\n", disk->name, esc_tag(sub, esc_buffer), 973 : (uint64_t)file_already_present_size, (uint64_t)file_already_present_mtime_sec, file_already_present_mtime_nsec, - 974 9286 : (uint64_t)file->size, (uint64_t)file->mtime_sec, file->mtime_nsec + 974 9384 : (uint64_t)file->size, (uint64_t)file->mtime_sec, file->mtime_nsec 975 : ); 976 : - 977 4643 : if (is_diff) { + 977 4692 : if (is_diff) { 978 118 : printf("update %s\n", fmt_term(disk, sub, esc_buffer)); 979 : } 980 : } else { @@ -1050,7 +1050,7 @@ 988 : } 989 : 990 : /* insert the file in the delayed list */ - 991 79156 : scan_file_insert(scan, file); + 991 79205 : scan_file_insert(scan, file); 992 : } 993 : 994 : /** @@ -1157,12 +1157,12 @@ 1095 : } 1096 : #endif 1097 : - 1098 11526102 : static int dd_name_compare(const void* void_a, const void* void_b) + 1098 11526118 : static int dd_name_compare(const void* void_a, const void* void_b) 1099 : { - 1100 11526102 : const struct dirent_sorted* a = void_a; - 1101 11526102 : const struct dirent_sorted* b = void_b; + 1100 11526118 : const struct dirent_sorted* a = void_a; + 1101 11526118 : const struct dirent_sorted* b = void_b; 1102 : - 1103 11526102 : return strcmp(a->d_name, b->d_name); + 1103 11526118 : return strcmp(a->d_name, b->d_name); 1104 : } 1105 : 1106 : /** @@ -1176,15 +1176,15 @@ 1114 : } 1115 : #else 1116 : #define DSTAT(file, dd, buf) dstat(file, buf) - 1117 1106198 : struct stat* dstat(const char* file, struct stat* st) + 1117 1106210 : struct stat* dstat(const char* file, struct stat* st) 1118 : { - 1119 1106198 : if (lstat(file, st) != 0) { + 1119 1106210 : if (lstat(file, st) != 0) { 1120 : /* LCOV_EXCL_START */ 1121 : log_fatal("Error in stat file/directory '%s'. %s.\n", file, strerror(errno)); 1122 : exit(EXIT_FAILURE); 1123 : /* LCOV_EXCL_STOP */ 1124 : } - 1125 1106198 : return st; + 1125 1106210 : return st; 1126 : } 1127 : #endif 1128 : @@ -1192,19 +1192,19 @@ 1130 : * Process a directory. 1131 : * Return != 0 if at least one file or link is processed. 1132 : */ - 1133 1840 : static int scan_dir(struct snapraid_scan* scan, int level, int is_diff, const char* dir, const char* sub) + 1133 1846 : static int scan_dir(struct snapraid_scan* scan, int level, int is_diff, const char* dir, const char* sub) 1134 : { - 1135 1840 : struct snapraid_state* state = scan->state; - 1136 1840 : struct snapraid_disk* disk = scan->disk; - 1137 1840 : int processed = 0; + 1135 1846 : struct snapraid_state* state = scan->state; + 1136 1846 : struct snapraid_disk* disk = scan->disk; + 1137 1846 : int processed = 0; 1138 : DIR* d; 1139 : tommy_list list; 1140 : tommy_node* node; 1141 : - 1142 1840 : tommy_list_init(&list); + 1142 1846 : tommy_list_init(&list); 1143 : - 1144 1840 : d = opendir(dir); - 1145 1840 : if (!d) { + 1144 1846 : d = opendir(dir); + 1145 1846 : if (!d) { 1146 : /* LCOV_EXCL_START */ 1147 : log_fatal("Error opening directory '%s'. %s.\n", dir, strerror(errno)); 1148 : if (level == 0) @@ -1231,29 +1231,29 @@ 1169 : * "If the end of the directory stream is reached, NULL is returned and errno is not changed. 1170 : * If an error occurs, NULL is returned and errno is set appropriately." 1171 : */ - 1172 1147707 : errno = 0; - 1173 1147707 : dd = readdir(d); - 1174 1147707 : if (dd == 0 && errno != 0) { + 1172 1147737 : errno = 0; + 1173 1147737 : dd = readdir(d); + 1174 1147737 : if (dd == 0 && errno != 0) { 1175 : /* LCOV_EXCL_START */ 1176 : log_fatal("Error reading directory '%s'. %s.\n", dir, strerror(errno)); 1177 : log_fatal("You can exclude it in the config file with:\n\texclude /%s\n", sub); 1178 : exit(EXIT_FAILURE); 1179 : /* LCOV_EXCL_STOP */ 1180 : } - 1181 1147707 : if (dd == 0) { - 1182 1840 : break; /* finished */ + 1181 1147737 : if (dd == 0) { + 1182 1846 : break; /* finished */ 1183 : } 1184 : 1185 : /* skip "." and ".." files */ - 1186 1145867 : name = dd->d_name; - 1187 1145867 : if (name[0] == '.' && (name[1] == 0 || (name[1] == '.' && name[2] == 0))) - 1188 7360 : continue; + 1186 1145891 : name = dd->d_name; + 1187 1145891 : if (name[0] == '.' && (name[1] == 0 || (name[1] == '.' && name[2] == 0))) + 1188 7384 : continue; 1189 : - 1190 1142187 : pathprint(path_next, sizeof(path_next), "%s%s", dir, name); - 1191 1142187 : pathprint(sub_next, sizeof(sub_next), "%s%s", sub, name); + 1190 1142199 : pathprint(path_next, sizeof(path_next), "%s%s", dir, name); + 1191 1142199 : pathprint(sub_next, sizeof(sub_next), "%s%s", sub, name); 1192 : 1193 : /* check for not supported file names */ - 1194 1142187 : if (name[0] == 0) { + 1194 1142199 : if (name[0] == 0) { 1195 : /* LCOV_EXCL_START */ 1196 : log_fatal("Unsupported name '%s' in file '%s'.\n", name, path_next); 1197 : exit(EXIT_FAILURE); @@ -1261,26 +1261,26 @@ 1199 : } 1200 : 1201 : /* exclude hidden files even before calling lstat() */ - 1202 1142187 : if (filter_hidden(state->filter_hidden, dd) != 0) { + 1202 1142199 : if (filter_hidden(state->filter_hidden, dd) != 0) { 1203 0 : msg_verbose("Excluding hidden '%s'\n", path_next); 1204 0 : continue; 1205 : } 1206 : 1207 : /* exclude content files even before calling lstat() */ - 1208 1142187 : if (filter_content(&state->contentlist, path_next) != 0) { + 1208 1142199 : if (filter_content(&state->contentlist, path_next) != 0) { 1209 0 : msg_verbose("Excluding content '%s'\n", path_next); 1210 0 : continue; 1211 : } 1212 : - 1213 1142187 : name_len = strlen(dd->d_name); - 1214 1142187 : entry = malloc_nofail(sizeof(struct dirent_sorted) + name_len + 1); + 1213 1142199 : name_len = strlen(dd->d_name); + 1214 1142199 : entry = malloc_nofail(sizeof(struct dirent_sorted) + name_len + 1); 1215 : 1216 : /* copy the dir entry */ 1217 : #if HAVE_STRUCT_DIRENT_D_INO - 1218 1142187 : entry->d_ino = dd->d_ino; + 1218 1142199 : entry->d_ino = dd->d_ino; 1219 : #endif 1220 : #if HAVE_STRUCT_DIRENT_D_TYPE - 1221 1142187 : entry->d_type = dd->d_type; + 1221 1142199 : entry->d_type = dd->d_type; 1222 : #endif 1223 : #if HAVE_STRUCT_DIRENT_D_STAT 1224 : /* convert dirent to lstat result */ @@ -1288,24 +1288,24 @@ 1226 : 1227 : /* note that at this point the st_mode may be 0 */ 1228 : #endif - 1229 1142187 : memcpy(entry->d_name, dd->d_name, name_len + 1); + 1229 1142199 : memcpy(entry->d_name, dd->d_name, name_len + 1); 1230 : 1231 : /* insert in the list */ - 1232 1142187 : tommy_list_insert_tail(&list, &entry->node, entry); - 1233 1145867 : } + 1232 1142199 : tommy_list_insert_tail(&list, &entry->node, entry); + 1233 1145891 : } 1234 : - 1235 1840 : if (closedir(d) != 0) { + 1235 1846 : if (closedir(d) != 0) { 1236 : /* LCOV_EXCL_START */ 1237 : log_fatal("Error closing directory '%s'. %s.\n", dir, strerror(errno)); 1238 : exit(EXIT_FAILURE); 1239 : /* LCOV_EXCL_STOP */ 1240 : } 1241 : - 1242 1840 : if (state->opt.force_order == SORT_ALPHA) { + 1242 1846 : if (state->opt.force_order == SORT_ALPHA) { 1243 : /* if requested sort alphabetically */ 1244 : /* this is mainly done for testing to ensure to always */ 1245 : /* process in the same way in different platforms */ - 1246 1804 : tommy_list_sort(&list, dd_name_compare); + 1246 1810 : tommy_list_sort(&list, dd_name_compare); 1247 : } 1248 : #if HAVE_STRUCT_DIRENT_D_INO 1249 36 : else if (!disk->has_volatile_inodes) { @@ -1317,32 +1317,32 @@ 1255 : #endif 1256 : 1257 : /* process the sorted dir entries */ - 1258 1840 : node = list; - 1259 1145867 : while (node != 0) { + 1258 1846 : node = list; + 1259 1145891 : while (node != 0) { 1260 : char path_next[PATH_MAX]; 1261 : char sub_next[PATH_MAX]; 1262 : char out[PATH_MAX]; - 1263 1142187 : struct snapraid_filter* reason = 0; - 1264 1142187 : struct dirent_sorted* dd = node->data; - 1265 1142187 : const char* name = dd->d_name; + 1263 1142199 : struct snapraid_filter* reason = 0; + 1264 1142199 : struct dirent_sorted* dd = node->data; + 1265 1142199 : const char* name = dd->d_name; 1266 : struct stat* st; 1267 : int type; 1268 : #if !HAVE_STRUCT_DIRENT_D_STAT 1269 : struct stat st_buf; 1270 : #endif 1271 : - 1272 1142187 : pathprint(path_next, sizeof(path_next), "%s%s", dir, name); - 1273 1142187 : pathprint(sub_next, sizeof(sub_next), "%s%s", sub, name); + 1272 1142199 : pathprint(path_next, sizeof(path_next), "%s%s", dir, name); + 1273 1142199 : pathprint(sub_next, sizeof(sub_next), "%s%s", sub, name); 1274 : 1275 : /* start with an unknown type */ - 1276 1142187 : type = -1; - 1277 1142187 : st = 0; + 1276 1142199 : type = -1; + 1277 1142199 : st = 0; 1278 : 1279 : /* if dirent has the type, use it */ 1280 : #if HAVE_STRUCT_DIRENT_D_TYPE - 1281 1142187 : switch (dd->d_type) { + 1281 1142199 : switch (dd->d_type) { 1282 0 : case DT_UNKNOWN : break; - 1283 1104927 : case DT_REG : type = 0; break; + 1283 1104939 : case DT_REG : type = 0; break; 1284 35989 : case DT_LNK : type = 1; break; 1285 1271 : case DT_DIR : type = 2; break; 1286 0 : default : type = 3; break; @@ -1350,7 +1350,7 @@ 1288 : #endif 1289 : 1290 : /* if type is still unknown */ - 1291 1142187 : if (type < 0) { + 1291 1142199 : if (type < 0) { 1292 : /* get the type from stat */ 1293 0 : st = DSTAT(path_next, dd, &st_buf); 1294 : @@ -1380,12 +1380,12 @@ 1318 0 : type = 3; 1319 : } 1320 : - 1321 1142187 : if (type == 0) { /* REG */ - 1322 1104927 : if (filter_path(&state->filterlist, &reason, disk->name, sub_next) == 0) { + 1321 1142199 : if (type == 0) { /* REG */ + 1322 1104939 : if (filter_path(&state->filterlist, &reason, disk->name, sub_next) == 0) { 1323 : 1324 : /* late stat, if not yet called */ - 1325 1104927 : if (!st) - 1326 1104927 : st = DSTAT(path_next, dd, &st_buf); + 1325 1104939 : if (!st) + 1326 1104939 : st = DSTAT(path_next, dd, &st_buf); 1327 : 1328 : #if HAVE_LSTAT_SYNC 1329 : /* if the st_ino field is missing, takes care to fill it using the extended lstat() */ @@ -1400,8 +1400,8 @@ 1338 : } 1339 : #endif 1340 : - 1341 1104927 : scan_file(scan, is_diff, sub_next, st, FILEPHY_UNREAD_OFFSET); - 1342 1104927 : processed = 1; + 1341 1104939 : scan_file(scan, is_diff, sub_next, st, FILEPHY_UNREAD_OFFSET); + 1342 1104939 : processed = 1; 1343 : } else { 1344 0 : msg_verbose("Excluding file '%s' for rule '%s'\n", path_next, filter_type(reason, out, sizeof(out))); 1345 : } @@ -1478,16 +1478,16 @@ 1416 : } 1417 : 1418 : /* next entry */ - 1419 1142187 : node = node->next; + 1419 1142199 : node = node->next; 1420 : 1421 : /* free the present one */ - 1422 1142187 : free(dd); + 1422 1142199 : free(dd); 1423 : } 1424 : - 1425 1840 : return processed; + 1425 1846 : return processed; 1426 : } 1427 : - 1428 95 : static int state_diffscan(struct snapraid_state* state, int is_diff) + 1428 96 : static int state_diffscan(struct snapraid_state* state, int is_diff) 1429 : { 1430 : tommy_node* i; 1431 : tommy_node* j; @@ -1498,58 +1498,58 @@ 1436 : int no_difference; 1437 : char esc_buffer[ESC_MAX]; 1438 : - 1439 95 : tommy_list_init(&scanlist); + 1439 96 : tommy_list_init(&scanlist); 1440 : - 1441 95 : if (is_diff) - 1442 7 : msg_progress("Comparing...\n"); + 1441 96 : if (is_diff) + 1442 8 : msg_progress("Comparing...\n"); 1443 : 1444 : /* first scan all the directory and find new and deleted files */ - 1445 664 : for (i = state->disklist; i != 0; i = i->next) { - 1446 569 : struct snapraid_disk* disk = i->data; + 1445 671 : for (i = state->disklist; i != 0; i = i->next) { + 1446 575 : struct snapraid_disk* disk = i->data; 1447 : struct snapraid_scan* scan; 1448 : tommy_node* node; 1449 : int ret; 1450 : int has_persistent_inode; 1451 : - 1452 569 : scan = malloc_nofail(sizeof(struct snapraid_scan)); - 1453 569 : scan->state = state; - 1454 569 : scan->disk = disk; - 1455 569 : scan->count_equal = 0; - 1456 569 : scan->count_move = 0; - 1457 569 : scan->count_copy = 0; - 1458 569 : scan->count_restore = 0; - 1459 569 : scan->count_change = 0; - 1460 569 : scan->count_remove = 0; - 1461 569 : scan->count_insert = 0; - 1462 569 : tommy_list_init(&scan->file_insert_list); - 1463 569 : tommy_list_init(&scan->link_insert_list); - 1464 569 : tommy_list_init(&scan->dir_insert_list); + 1452 575 : scan = malloc_nofail(sizeof(struct snapraid_scan)); + 1453 575 : scan->state = state; + 1454 575 : scan->disk = disk; + 1455 575 : scan->count_equal = 0; + 1456 575 : scan->count_move = 0; + 1457 575 : scan->count_copy = 0; + 1458 575 : scan->count_restore = 0; + 1459 575 : scan->count_change = 0; + 1460 575 : scan->count_remove = 0; + 1461 575 : scan->count_insert = 0; + 1462 575 : tommy_list_init(&scan->file_insert_list); + 1463 575 : tommy_list_init(&scan->link_insert_list); + 1464 575 : tommy_list_init(&scan->dir_insert_list); 1465 : - 1466 569 : tommy_list_insert_tail(&scanlist, &scan->node, scan); + 1466 575 : tommy_list_insert_tail(&scanlist, &scan->node, scan); 1467 : - 1468 569 : if (!is_diff) + 1468 575 : if (!is_diff) 1469 527 : msg_progress("Scanning disk %s...\n", disk->name); 1470 : 1471 : /* check if the disk supports persistent inodes */ - 1472 569 : ret = fsinfo(disk->dir, &has_persistent_inode, 0, 0); - 1473 569 : if (ret < 0) { + 1472 575 : ret = fsinfo(disk->dir, &has_persistent_inode, 0, 0); + 1473 575 : if (ret < 0) { 1474 : /* LCOV_EXCL_START */ 1475 : log_fatal("Error accessing disk '%s' to get file-system info. %s.\n", disk->dir, strerror(errno)); 1476 : exit(EXIT_FAILURE); 1477 : /* LCOV_EXCL_STOP */ 1478 : } - 1479 569 : if (!has_persistent_inode) { + 1479 575 : if (!has_persistent_inode) { 1480 0 : disk->has_volatile_inodes = 1; 1481 : } 1482 : 1483 : /* if inodes or UUID are not persistent/changed/unsupported */ - 1484 569 : if (disk->has_volatile_inodes || disk->has_different_uuid || disk->has_unsupported_uuid) { + 1484 575 : if (disk->has_volatile_inodes || disk->has_different_uuid || disk->has_unsupported_uuid) { 1485 : /* remove all the inodes from the inode collection */ 1486 : /* if they are not persistent, all of them could be changed now */ 1487 : /* and we don't want to find false matching ones */ 1488 : /* see scan_file() for more details */ - 1489 93 : node = disk->filelist; - 1490 200 : while (node) { + 1489 94 : node = disk->filelist; + 1490 202 : while (node) { 1491 14 : struct snapraid_file* file = node->data; 1492 : 1493 14 : node = node->next; @@ -1565,7 +1565,7 @@ 1503 : } 1504 : } 1505 : - 1506 569 : scan_dir(scan, 0, is_diff, disk->dir, ""); + 1506 575 : scan_dir(scan, 0, is_diff, disk->dir, ""); 1507 : } 1508 : 1509 : /* we split the search in two phases because to detect files */ @@ -1573,9 +1573,9 @@ 1511 : /* only when all disks have all the new files found */ 1512 : 1513 : /* now process all the new and deleted files */ - 1514 664 : for (i = scanlist; i != 0; i = i->next) { - 1515 569 : struct snapraid_scan* scan = i->data; - 1516 569 : struct snapraid_disk* disk = scan->disk; + 1514 671 : for (i = scanlist; i != 0; i = i->next) { + 1515 575 : struct snapraid_scan* scan = i->data; + 1516 575 : struct snapraid_disk* disk = scan->disk; 1517 : tommy_node* node; 1518 : unsigned phy_count; 1519 : unsigned phy_dup; @@ -1583,15 +1583,15 @@ 1521 : struct snapraid_file* phy_file_last; 1522 : 1523 : /* check for removed files */ - 1524 569 : node = disk->filelist; - 1525 1033681 : while (node) { - 1526 1032543 : struct snapraid_file* file = node->data; + 1524 575 : node = disk->filelist; + 1525 1033649 : while (node) { + 1526 1032499 : struct snapraid_file* file = node->data; 1527 : 1528 : /* next node */ - 1529 1032543 : node = node->next; + 1529 1032499 : node = node->next; 1530 : 1531 : /* remove if not present */ - 1532 1032543 : if (!file_flag_has(file, FILE_IS_PRESENT)) { + 1532 1032499 : if (!file_flag_has(file, FILE_IS_PRESENT)) { 1533 29647 : ++scan->count_remove; 1534 : 1535 29647 : log_tag("scan:remove:%s:%s\n", disk->name, esc_tag(file->sub, esc_buffer)); @@ -1604,8 +1604,8 @@ 1542 : } 1543 : 1544 : /* check for removed links */ - 1545 569 : node = disk->linklist; - 1546 35821 : while (node) { + 1545 575 : node = disk->linklist; + 1546 35833 : while (node) { 1547 34683 : struct snapraid_link* slink = node->data; 1548 : 1549 : /* next node */ @@ -1625,8 +1625,8 @@ 1563 : } 1564 : 1565 : /* check for removed dirs */ - 1566 569 : node = disk->dirlist; - 1567 1389 : while (node) { + 1566 575 : node = disk->dirlist; + 1567 1401 : while (node) { 1568 251 : struct snapraid_dir* dir = node->data; 1569 : 1570 : /* next node */ @@ -1641,7 +1641,7 @@ 1579 : /* sort the files before inserting them */ 1580 : /* we use a stable sort to ensure that if the reported physical offset/inode */ 1581 : /* are always 0, we keep at least the directory order */ - 1582 569 : switch (state->opt.force_order) { + 1582 575 : switch (state->opt.force_order) { 1583 : case SORT_PHYSICAL : 1584 12 : tommy_list_sort(&scan->file_insert_list, file_physical_compare); 1585 12 : break; @@ -1649,8 +1649,8 @@ 1587 0 : tommy_list_sort(&scan->file_insert_list, file_inode_compare); 1588 0 : break; 1589 : case SORT_ALPHA : - 1590 557 : tommy_list_sort(&scan->file_insert_list, file_path_compare); - 1591 557 : break; + 1590 563 : tommy_list_sort(&scan->file_insert_list, file_path_compare); + 1591 563 : break; 1592 : case SORT_DIR : 1593 : /* already in order */ 1594 0 : break; @@ -1659,16 +1659,16 @@ 1597 : /* insert all the new files, we insert them only after the deletion */ 1598 : /* to reuse the just freed space */ 1599 : /* also check if the physical offset reported are fakes or not */ - 1600 569 : node = scan->file_insert_list; - 1601 569 : phy_count = 0; - 1602 569 : phy_dup = 0; - 1603 569 : phy_last = FILEPHY_UNREAD_OFFSET; - 1604 569 : phy_file_last = 0; - 1605 102974 : while (node) { - 1606 101836 : struct snapraid_file* file = node->data; + 1600 575 : node = scan->file_insert_list; + 1601 575 : phy_count = 0; + 1602 575 : phy_dup = 0; + 1603 575 : phy_last = FILEPHY_UNREAD_OFFSET; + 1604 575 : phy_file_last = 0; + 1605 103042 : while (node) { + 1606 101892 : struct snapraid_file* file = node->data; 1607 : 1608 : /* if the file is not empty, count duplicate physical offsets */ - 1609 101836 : if (state->opt.force_order == SORT_PHYSICAL && file->size != 0) { + 1609 101892 : if (state->opt.force_order == SORT_PHYSICAL && file->size != 0) { 1610 11418 : if (phy_file_last != 0 && file->physical == phy_last 1611 : /* files without offset are expected to have duplicates */ 1612 0 : && phy_last != FILEPHY_WITHOUT_OFFSET @@ -1686,21 +1686,21 @@ 1624 : } 1625 : 1626 : /* next node */ - 1627 101836 : node = node->next; + 1627 101892 : node = node->next; 1628 : 1629 : /* insert in the parity */ - 1630 101836 : scan_file_allocate(scan, file); + 1630 101892 : scan_file_allocate(scan, file); 1631 : } 1632 : 1633 : /* mark the disk without reliable physical offset if it has duplicates */ 1634 : /* here it should never happen because we already sorted out hardlinks */ - 1635 569 : if (state->opt.force_order == SORT_PHYSICAL && phy_dup > 0) { + 1635 575 : if (state->opt.force_order == SORT_PHYSICAL && phy_dup > 0) { 1636 0 : disk->has_unreliable_physical = 1; 1637 : } 1638 : 1639 : /* insert all the new links */ - 1640 569 : node = scan->link_insert_list; - 1641 3595 : while (node) { + 1640 575 : node = scan->link_insert_list; + 1641 3607 : while (node) { 1642 2457 : struct snapraid_link* slink = node->data; 1643 : 1644 : /* next node */ @@ -1711,8 +1711,8 @@ 1649 : } 1650 : 1651 : /* insert all the new dirs */ - 1652 569 : node = scan->dir_insert_list; - 1653 1148 : while (node) { + 1652 575 : node = scan->dir_insert_list; + 1653 1160 : while (node) { 1654 10 : struct snapraid_dir* dir = node->data; 1655 : 1656 : /* next node */ @@ -1724,18 +1724,18 @@ 1662 : } 1663 : 1664 : /* check for disks where all the previously existing files where removed */ - 1665 95 : if (!state->opt.force_empty) { - 1666 89 : int all_missing = 0; - 1667 89 : int all_rewritten = 0; - 1668 89 : done = 0; - 1669 622 : for (i = state->disklist, j = scanlist; i != 0; i = i->next, j = j->next) { - 1670 533 : struct snapraid_disk* disk = i->data; - 1671 533 : struct snapraid_scan* scan = j->data; + 1665 96 : if (!state->opt.force_empty) { + 1666 90 : int all_missing = 0; + 1667 90 : int all_rewritten = 0; + 1668 90 : done = 0; + 1669 629 : for (i = state->disklist, j = scanlist; i != 0; i = i->next, j = j->next) { + 1670 539 : struct snapraid_disk* disk = i->data; + 1671 539 : struct snapraid_scan* scan = j->data; 1672 : - 1673 533 : if (scan->count_equal == 0 - 1674 73 : && scan->count_move == 0 - 1675 73 : && scan->count_restore == 0 - 1676 73 : && (scan->count_remove != 0 || scan->count_change != 0) + 1673 539 : if (scan->count_equal == 0 + 1674 74 : && scan->count_move == 0 + 1675 74 : && scan->count_restore == 0 + 1676 74 : && (scan->count_remove != 0 || scan->count_change != 0) 1677 : ) { 1678 1 : if (!done) { 1679 1 : done = 1; @@ -1753,7 +1753,7 @@ 1691 0 : all_rewritten = 1; 1692 : } 1693 : } - 1694 89 : if (done) { + 1694 90 : if (done) { 1695 1 : log_fatal("\nare now missing or rewritten!\n"); 1696 1 : if (all_rewritten) { 1697 0 : log_fatal("This could happen when restoring a disk with a backup\n"); @@ -1771,7 +1771,7 @@ 1709 : } 1710 : 1711 : /* check for disks without the physical offset support */ - 1712 94 : if (state->opt.force_order == SORT_PHYSICAL) { + 1712 95 : if (state->opt.force_order == SORT_PHYSICAL) { 1713 2 : done = 0; 1714 14 : for (i = state->disklist; i != 0; i = i->next) { 1715 12 : struct snapraid_disk* disk = i->data; @@ -1791,11 +1791,11 @@ 1729 : } 1730 : 1731 : /* check for disks without persistent inodes */ - 1732 94 : done = 0; - 1733 657 : for (i = state->disklist; i != 0; i = i->next) { - 1734 563 : struct snapraid_disk* disk = i->data; + 1732 95 : done = 0; + 1733 664 : for (i = state->disklist; i != 0; i = i->next) { + 1734 569 : struct snapraid_disk* disk = i->data; 1735 : - 1736 563 : if (disk->has_volatile_inodes) { + 1736 569 : if (disk->has_volatile_inodes) { 1737 0 : if (!done) { 1738 0 : done = 1; 1739 0 : log_fatal("WARNING! Inodes are not persistent for disks: '%s'", disk->name); @@ -1804,20 +1804,20 @@ 1742 : } 1743 : } 1744 : } - 1745 94 : if (done) { + 1745 95 : if (done) { 1746 0 : log_fatal(". Move operations won't be optimal.\n"); 1747 : } 1748 : 1749 : /* check for disks with changed UUID */ - 1750 94 : done = 0; - 1751 657 : for (i = state->disklist; i != 0; i = i->next) { - 1752 563 : struct snapraid_disk* disk = i->data; + 1750 95 : done = 0; + 1751 664 : for (i = state->disklist; i != 0; i = i->next) { + 1752 569 : struct snapraid_disk* disk = i->data; 1753 : 1754 : /* don't print the message if the UUID changed because before */ 1755 : /* it was no set. */ 1756 : /* this is the normal condition for an empty disk because it */ 1757 : /* isn't stored */ - 1758 563 : if (disk->has_different_uuid && !disk->had_empty_uuid) { + 1758 569 : if (disk->has_different_uuid && !disk->had_empty_uuid) { 1759 4 : if (!done) { 1760 2 : done = 1; 1761 2 : log_fatal("WARNING! UUID is changed for disks: '%s'", disk->name); @@ -1826,16 +1826,16 @@ 1764 : } 1765 : } 1766 : } - 1767 94 : if (done) { + 1767 95 : if (done) { 1768 2 : log_fatal(". Move operations won't be optimal.\n"); 1769 : } 1770 : 1771 : /* check for disks with unsupported UUID */ - 1772 94 : done = 0; - 1773 657 : for (i = state->disklist; i != 0; i = i->next) { - 1774 563 : struct snapraid_disk* disk = i->data; + 1772 95 : done = 0; + 1773 664 : for (i = state->disklist; i != 0; i = i->next) { + 1774 569 : struct snapraid_disk* disk = i->data; 1775 : - 1776 563 : if (disk->has_unsupported_uuid) { + 1776 569 : if (disk->has_unsupported_uuid) { 1777 0 : if (!done) { 1778 0 : done = 1; 1779 0 : log_fatal("WARNING! UUID is unsupported for disks: '%s'", disk->name); @@ -1844,7 +1844,7 @@ 1782 : } 1783 : } 1784 : } - 1785 94 : if (done) { + 1785 95 : if (done) { 1786 0 : log_fatal(". Move operations won't be optimal.\n"); 1787 : #if defined(_linux) && !HAVE_BLKID 1788 : log_fatal("The 'blkid' library is not linked in SnapRAID!\n"); @@ -1852,87 +1852,87 @@ 1790 : #endif 1791 : } 1792 : - 1793 94 : total.count_equal = 0; - 1794 94 : total.count_move = 0; - 1795 94 : total.count_copy = 0; - 1796 94 : total.count_restore = 0; - 1797 94 : total.count_change = 0; - 1798 94 : total.count_remove = 0; - 1799 94 : total.count_insert = 0; + 1793 95 : total.count_equal = 0; + 1794 95 : total.count_move = 0; + 1795 95 : total.count_copy = 0; + 1796 95 : total.count_restore = 0; + 1797 95 : total.count_change = 0; + 1798 95 : total.count_remove = 0; + 1799 95 : total.count_insert = 0; 1800 : - 1801 657 : for (i = scanlist; i != 0; i = i->next) { - 1802 563 : struct snapraid_scan* scan = i->data; - 1803 563 : total.count_equal += scan->count_equal; - 1804 563 : total.count_move += scan->count_move; - 1805 563 : total.count_copy += scan->count_copy; - 1806 563 : total.count_restore += scan->count_restore; - 1807 563 : total.count_change += scan->count_change; - 1808 563 : total.count_remove += scan->count_remove; - 1809 563 : total.count_insert += scan->count_insert; + 1801 664 : for (i = scanlist; i != 0; i = i->next) { + 1802 569 : struct snapraid_scan* scan = i->data; + 1803 569 : total.count_equal += scan->count_equal; + 1804 569 : total.count_move += scan->count_move; + 1805 569 : total.count_copy += scan->count_copy; + 1806 569 : total.count_restore += scan->count_restore; + 1807 569 : total.count_change += scan->count_change; + 1808 569 : total.count_remove += scan->count_remove; + 1809 569 : total.count_insert += scan->count_insert; 1810 : } 1811 : - 1812 94 : if (is_diff) { - 1813 7 : msg_status("\n"); - 1814 7 : msg = msg_status; + 1812 95 : if (is_diff) { + 1813 8 : msg_status("\n"); + 1814 8 : msg = msg_status; 1815 : } else { 1816 87 : msg = msg_verbose; 1817 : } 1818 : - 1819 94 : msg("%8u equal\n", total.count_equal); - 1820 94 : msg("%8u added\n", total.count_insert); - 1821 94 : msg("%8u removed\n", total.count_remove); - 1822 94 : msg("%8u updated\n", total.count_change); - 1823 94 : msg("%8u moved\n", total.count_move); - 1824 94 : msg("%8u copied\n", total.count_copy); - 1825 94 : msg("%8u restored\n", total.count_restore); + 1819 95 : msg("%8u equal\n", total.count_equal); + 1820 95 : msg("%8u added\n", total.count_insert); + 1821 95 : msg("%8u removed\n", total.count_remove); + 1822 95 : msg("%8u updated\n", total.count_change); + 1823 95 : msg("%8u moved\n", total.count_move); + 1824 95 : msg("%8u copied\n", total.count_copy); + 1825 95 : msg("%8u restored\n", total.count_restore); 1826 : - 1827 94 : log_tag("summary:equal:%u\n", total.count_equal); - 1828 94 : log_tag("summary:added:%u\n", total.count_insert); - 1829 94 : log_tag("summary:removed:%u\n", total.count_remove); - 1830 94 : log_tag("summary:updated:%u\n", total.count_change); - 1831 94 : log_tag("summary:moved:%u\n", total.count_move); - 1832 94 : log_tag("summary:copied:%u\n", total.count_copy); - 1833 94 : log_tag("summary:restored:%u\n", total.count_restore); + 1827 95 : log_tag("summary:equal:%u\n", total.count_equal); + 1828 95 : log_tag("summary:added:%u\n", total.count_insert); + 1829 95 : log_tag("summary:removed:%u\n", total.count_remove); + 1830 95 : log_tag("summary:updated:%u\n", total.count_change); + 1831 95 : log_tag("summary:moved:%u\n", total.count_move); + 1832 95 : log_tag("summary:copied:%u\n", total.count_copy); + 1833 95 : log_tag("summary:restored:%u\n", total.count_restore); 1834 : - 1835 281 : no_difference = !total.count_move && !total.count_copy && !total.count_restore - 1836 157 : && !total.count_change && !total.count_remove && !total.count_insert; + 1835 284 : no_difference = !total.count_move && !total.count_copy && !total.count_restore + 1836 159 : && !total.count_change && !total.count_remove && !total.count_insert; 1837 : - 1838 94 : if (is_diff) { - 1839 7 : if (no_difference) { - 1840 1 : msg_status("No differences\n"); + 1838 95 : if (is_diff) { + 1839 8 : if (no_difference) { + 1840 2 : msg_status("No differences\n"); 1841 : } else { 1842 6 : msg_status("There are differences!\n"); 1843 : } 1844 : } 1845 : - 1846 94 : if (no_difference) { - 1847 19 : log_tag("summary:exit:equal\n"); + 1846 95 : if (no_difference) { + 1847 20 : log_tag("summary:exit:equal\n"); 1848 : } else { 1849 75 : log_tag("summary:exit:diff\n"); 1850 : } - 1851 94 : log_flush(); + 1851 95 : log_flush(); 1852 : - 1853 94 : tommy_list_foreach(&scanlist, (tommy_foreach_func*)free); + 1853 95 : tommy_list_foreach(&scanlist, (tommy_foreach_func*)free); 1854 : 1855 : /* check the file-system on all disks */ - 1856 94 : state_fscheck(state, "after scan"); + 1856 95 : state_fscheck(state, "after scan"); 1857 : - 1858 94 : if (is_diff) { + 1858 95 : if (is_diff) { 1859 : /* check for file difference */ - 1860 7 : if (!no_difference) + 1860 8 : if (!no_difference) 1861 6 : return 1; 1862 : 1863 : /* check also for incomplete "sync" */ - 1864 1 : if (parity_is_invalid(state)) - 1865 0 : return 1; + 1864 2 : if (parity_is_invalid(state)) + 1865 1 : return 1; 1866 : } 1867 : 1868 88 : return 0; 1869 : } 1870 : - 1871 7 : int state_diff(struct snapraid_state* state) + 1871 8 : int state_diff(struct snapraid_state* state) 1872 : { - 1873 7 : return state_diffscan(state, 1); + 1873 8 : return state_diffscan(state, 1); 1874 : } 1875 : 1876 88 : void state_scan(struct snapraid_state* state) diff --git a/cov/cmdline/scrub.c.func-sort-c.html b/cov/cmdline/scrub.c.func-sort-c.html index 30aeecf9..b33d4412 100644 --- a/cov/cmdline/scrub.c.func-sort-c.html +++ b/cov/cmdline/scrub.c.func-sort-c.html @@ -32,8 +32,8 @@ Lines: 281 - 357 - 78.7 % + 349 + 80.5 % Date: @@ -61,11 +61,11 @@ scrub_parity_reader - 168183 + 168187 scrub_data_reader - 168180 + 168181 block_is_enabled @@ -76,11 +76,11 @@ 11 - state_scrub + state_scrub 11 - md + md 2 diff --git a/cov/cmdline/scrub.c.func.html b/cov/cmdline/scrub.c.func.html index 3d33634a..1095dd1c 100644 --- a/cov/cmdline/scrub.c.func.html +++ b/cov/cmdline/scrub.c.func.html @@ -32,8 +32,8 @@ Lines: 281 - 357 - 78.7 % + 349 + 80.5 % Date: @@ -64,19 +64,19 @@ 112170 - md + md 2 scrub_data_reader - 168180 + 168181 scrub_parity_reader - 168183 + 168187 - state_scrub + state_scrub 11 diff --git a/cov/cmdline/scrub.c.gcov.html b/cov/cmdline/scrub.c.gcov.html index e2b44b96..7e95cfe0 100644 --- a/cov/cmdline/scrub.c.gcov.html +++ b/cov/cmdline/scrub.c.gcov.html @@ -32,8 +32,8 @@ Lines: 281 - 357 - 78.7 % + 349 + 80.5 % Date: @@ -146,16 +146,16 @@ 84 56244 : blocktime = info_get_time(info); 85 56244 : if (blocktime > plan->timelimit) { 86 : /* skip it */ - 87 9582 : return 0; + 87 9574 : return 0; 88 : } 89 : 90 : /* if the time is less than the limit, always include */ 91 : /* otherwise, check if we reached the last limit count */ - 92 46662 : if (blocktime == plan->timelimit) { + 92 46670 : if (blocktime == plan->timelimit) { 93 : /* if we reached the count limit */ - 94 30124 : if (plan->countlast >= plan->lastlimit) { + 94 30132 : if (plan->countlast >= plan->lastlimit) { 95 : /* skip it */ - 96 24932 : return 0; + 96 24940 : return 0; 97 : } 98 : 99 5192 : ++plan->countlast; @@ -164,19 +164,19 @@ 102 21730 : return 1; 103 : } 104 : - 105 168180 : static void scrub_data_reader(struct snapraid_worker* worker, struct snapraid_task* task) + 105 168181 : static void scrub_data_reader(struct snapraid_worker* worker, struct snapraid_task* task) 106 : { - 107 168180 : struct snapraid_io* io = worker->io; - 108 168180 : struct snapraid_state* state = io->state; - 109 168180 : struct snapraid_handle* handle = worker->handle; - 110 168180 : struct snapraid_disk* disk = handle->disk; - 111 168180 : block_off_t blockcur = task->position; - 112 168180 : unsigned char* buffer = task->buffer; + 107 168181 : struct snapraid_io* io = worker->io; + 108 168181 : struct snapraid_state* state = io->state; + 109 168181 : struct snapraid_handle* handle = worker->handle; + 110 168181 : struct snapraid_disk* disk = handle->disk; + 111 168181 : block_off_t blockcur = task->position; + 112 168181 : unsigned char* buffer = task->buffer; 113 : int ret; 114 : char esc_buffer[ESC_MAX]; 115 : 116 : /* if the disk position is not used */ - 117 168180 : if (!disk) { + 117 168181 : if (!disk) { 118 : /* use an empty block */ 119 0 : memset(buffer, 0, state->block_size); 120 0 : task->state = TASK_STATE_DONE; @@ -184,10 +184,10 @@ 122 : } 123 : 124 : /* get the block */ - 125 168180 : task->block = fs_par2block_find(disk, blockcur); + 125 168181 : task->block = fs_par2block_find(disk, blockcur); 126 : 127 : /* if the block is not used */ - 128 168136 : if (!block_has_file(task->block)) { + 128 168157 : if (!block_has_file(task->block)) { 129 : /* use an empty block */ 130 1585 : memset(buffer, 0, state->block_size); 131 1585 : task->state = TASK_STATE_DONE; @@ -195,14 +195,14 @@ 133 : } 134 : 135 : /* get the file of this block */ - 136 166540 : task->file = fs_par2file_get(disk, blockcur, &task->file_pos); + 136 166558 : task->file = fs_par2file_get(disk, blockcur, &task->file_pos); 137 : 138 : /* if the file is different than the current one, close it */ - 139 166578 : if (handle->file != 0 && handle->file != task->file) { + 139 166581 : if (handle->file != 0 && handle->file != task->file) { 140 : /* keep a pointer at the file we are going to close for error reporting */ - 141 78089 : struct snapraid_file* report = handle->file; - 142 78089 : ret = handle_close(handle); - 143 78065 : if (ret == -1) { + 141 78085 : struct snapraid_file* report = handle->file; + 142 78085 : ret = handle_close(handle); + 143 78044 : if (ret == -1) { 144 : /* LCOV_EXCL_START */ 145 : /* This one is really an unexpected error, because we are only reading */ 146 : /* and closing a descriptor should never fail */ @@ -225,8 +225,8 @@ 163 : } 164 : } 165 : - 166 166554 : ret = handle_open(handle, task->file, state->file_mode, log_error, 0); - 167 166583 : if (ret == -1) { + 166 166540 : ret = handle_open(handle, task->file, state->file_mode, log_error, 0); + 167 166589 : if (ret == -1) { 168 0 : if (errno == EIO) { 169 : /* LCOV_EXCL_START */ 170 : log_tag("error:%u:%s:%s: Open EIO error. %s\n", blockcur, disk->name, esc_tag(task->file->sub, esc_buffer), strerror(errno)); @@ -244,9 +244,9 @@ 182 : } 183 : 184 : /* check if the file is changed */ - 185 166583 : if (handle->st.st_size != task->file->size - 186 166586 : || handle->st.st_mtime != task->file->mtime_sec - 187 160991 : || STAT_NSEC(&handle->st) != task->file->mtime_nsec + 185 166589 : if (handle->st.st_size != task->file->size + 186 166587 : || handle->st.st_mtime != task->file->mtime_sec + 187 160995 : || STAT_NSEC(&handle->st) != task->file->mtime_nsec 188 : /* don't check the inode to support filesystem without persistent inodes */ 189 : ) { 190 : /* report that the block and the file are not synced */ @@ -258,8 +258,8 @@ 196 : /* from the last sync, as we are expected to return errors if running */ 197 : /* in an unsynced array. This is just like the check command. */ 198 : - 199 166583 : task->read_size = handle_read(handle, task->file_pos, buffer, state->block_size, log_error, 0); - 200 166516 : if (task->read_size == -1) { + 199 166589 : task->read_size = handle_read(handle, task->file_pos, buffer, state->block_size, log_error, 0); + 200 166506 : if (task->read_size == -1) { 201 0 : if (errno == EIO) { 202 0 : log_tag("error:%u:%s:%s: Read EIO error at position %u. %s\n", blockcur, disk->name, esc_tag(task->file->sub, esc_buffer), task->file_pos, strerror(errno)); 203 0 : log_error("Input/Output error in file '%s' at position '%u'\n", handle->path, task->file_pos); @@ -273,24 +273,24 @@ 211 : } 212 : 213 : /* store the path of the opened file */ - 214 166516 : pathcpy(task->path, sizeof(task->path), handle->path); + 214 166506 : pathcpy(task->path, sizeof(task->path), handle->path); 215 : - 216 166573 : task->state = TASK_STATE_DONE; + 216 166569 : task->state = TASK_STATE_DONE; 217 : } 218 : - 219 168183 : static void scrub_parity_reader(struct snapraid_worker* worker, struct snapraid_task* task) + 219 168187 : static void scrub_parity_reader(struct snapraid_worker* worker, struct snapraid_task* task) 220 : { - 221 168183 : struct snapraid_io* io = worker->io; - 222 168183 : struct snapraid_state* state = io->state; - 223 168183 : struct snapraid_parity_handle* parity_handle = worker->parity_handle; - 224 168183 : unsigned level = parity_handle->level; - 225 168183 : block_off_t blockcur = task->position; - 226 168183 : unsigned char* buffer = task->buffer; + 221 168187 : struct snapraid_io* io = worker->io; + 222 168187 : struct snapraid_state* state = io->state; + 223 168187 : struct snapraid_parity_handle* parity_handle = worker->parity_handle; + 224 168187 : unsigned level = parity_handle->level; + 225 168187 : block_off_t blockcur = task->position; + 226 168187 : unsigned char* buffer = task->buffer; 227 : int ret; 228 : 229 : /* read the parity */ - 230 168183 : ret = parity_read(parity_handle, blockcur, buffer, state->block_size, log_error); - 231 167659 : if (ret == -1) { + 230 168187 : ret = parity_read(parity_handle, blockcur, buffer, state->block_size, log_error); + 231 168166 : if (ret == -1) { 232 0 : if (errno == EIO) { 233 0 : log_tag("parity_error:%u:%s: Read EIO error. %s\n", blockcur, lev_config_name(level), strerror(errno)); 234 0 : log_error("Input/Output error in parity '%s' at position '%u'\n", lev_config_name(level), blockcur); @@ -303,7 +303,7 @@ 241 0 : return; 242 : } 243 : - 244 167659 : task->state = TASK_STATE_DONE; + 244 168166 : task->state = TASK_STATE_DONE; 245 : } 246 : 247 11 : static int state_scrub_process(struct snapraid_state* state, struct snapraid_parity_handle* parity_handle, block_off_t blockstart, block_off_t blockmax, struct snapraid_plan* plan, time_t now) @@ -476,482 +476,490 @@ 414 : 415 : /* handle error conditions */ 416 166607 : if (task->state == TASK_STATE_IOERROR) { - 417 0 : ++io_error; - 418 0 : goto bail; - 419 : } - 420 166607 : if (task->state == TASK_STATE_ERROR) { - 421 0 : ++error; - 422 0 : goto bail; - 423 : } - 424 166607 : if (task->state == TASK_STATE_ERROR_CONTINUE) { - 425 0 : ++error; - 426 0 : error_on_this_block = 1; - 427 0 : continue; - 428 : } - 429 166607 : if (task->state == TASK_STATE_IOERROR_CONTINUE) { - 430 0 : ++io_error; - 431 0 : if (io_error >= state->opt.io_error_limit) { - 432 : /* LCOV_EXCL_START */ - 433 : log_fatal("DANGER! Too many input/output read error in a data disk, it isn't possible to scrub.\n"); - 434 : log_fatal("Ensure that disk '%s' is sane and that file '%s' can be accessed.\n", disk->dir, task->path); - 435 : log_fatal("Stopping at block %u\n", blockcur); - 436 : goto bail; - 437 : /* LCOV_EXCL_STOP */ - 438 : } - 439 : - 440 : /* otherwise continue */ - 441 0 : io_error_on_this_block = 1; - 442 0 : continue; - 443 : } - 444 166607 : if (task->state != TASK_STATE_DONE) { - 445 : /* LCOV_EXCL_START */ - 446 : log_fatal("Internal inconsistency in task state\n"); - 447 : os_abort(); - 448 : /* LCOV_EXCL_STOP */ - 449 : } - 450 : - 451 166607 : countsize += read_size; - 452 : - 453 : /* now compute the hash */ - 454 166607 : if (rehash) { - 455 27247 : memhash(state->prevhash, state->prevhashseed, hash, buffer[diskcur], read_size); + 417 : /* LCOV_EXCL_START */ + 418 : ++io_error; + 419 : goto bail; + 420 : /* LCOV_EXCL_STOP */ + 421 : } + 422 166607 : if (task->state == TASK_STATE_ERROR) { + 423 : /* LCOV_EXCL_START */ + 424 : ++error; + 425 : goto bail; + 426 : /* LCOV_EXCL_STOP */ + 427 : } + 428 166607 : if (task->state == TASK_STATE_ERROR_CONTINUE) { + 429 0 : ++error; + 430 0 : error_on_this_block = 1; + 431 0 : continue; + 432 : } + 433 166607 : if (task->state == TASK_STATE_IOERROR_CONTINUE) { + 434 0 : ++io_error; + 435 0 : if (io_error >= state->opt.io_error_limit) { + 436 : /* LCOV_EXCL_START */ + 437 : log_fatal("DANGER! Too many input/output read error in a data disk, it isn't possible to scrub.\n"); + 438 : log_fatal("Ensure that disk '%s' is sane and that file '%s' can be accessed.\n", disk->dir, task->path); + 439 : log_fatal("Stopping at block %u\n", blockcur); + 440 : goto bail; + 441 : /* LCOV_EXCL_STOP */ + 442 : } + 443 : + 444 : /* otherwise continue */ + 445 0 : io_error_on_this_block = 1; + 446 0 : continue; + 447 : } + 448 166607 : if (task->state != TASK_STATE_DONE) { + 449 : /* LCOV_EXCL_START */ + 450 : log_fatal("Internal inconsistency in task state\n"); + 451 : os_abort(); + 452 : /* LCOV_EXCL_STOP */ + 453 : } + 454 : + 455 166607 : countsize += read_size; 456 : - 457 : /* compute the new hash, and store it */ - 458 27247 : rehandle[diskcur].block = block; - 459 27247 : memhash(state->hash, state->hashseed, rehandle[diskcur].hash, buffer[diskcur], read_size); - 460 : } else { - 461 139360 : memhash(state->hash, state->hashseed, hash, buffer[diskcur], read_size); - 462 : } - 463 : - 464 : /* until now is hash */ - 465 166607 : state_usage_hash(state); - 466 : - 467 166607 : if (block_has_updated_hash(block)) { - 468 : /* compare the hash */ - 469 166607 : if (memcmp(hash, block->hash, BLOCK_HASH_SIZE) != 0) { - 470 920 : unsigned diff = memdiff(hash, block->hash, BLOCK_HASH_SIZE); - 471 : - 472 920 : log_tag("error:%u:%s:%s: Data error at position %u, diff bits %u\n", blockcur, disk->name, esc_tag(file->sub, esc_buffer), file_pos, diff); - 473 : - 474 : /* it's a silent error only if we are dealing with synced files */ - 475 920 : if (file_is_unsynced) { - 476 0 : ++error; - 477 0 : error_on_this_block = 1; - 478 : } else { - 479 920 : log_error("Data error in file '%s' at position '%u', diff bits %u\n", task->path, file_pos, diff); - 480 920 : ++silent_error; - 481 920 : silent_error_on_this_block = 1; - 482 : } - 483 920 : continue; - 484 : } - 485 : } - 486 : } - 487 : - 488 : /* buffers for parity read and not computed */ - 489 196224 : for (l = 0; l < state->level; ++l) - 490 168192 : buffer_recov[l] = buffer[diskmax + state->level + l]; - 491 28032 : for (; l < LEV_MAX; ++l) - 492 0 : buffer_recov[l] = 0; - 493 : - 494 : /* until now is misc */ - 495 28032 : state_usage_misc(state); - 496 : - 497 : /* read the parity */ - 498 196224 : for (l = 0; l < state->level; ++l) { - 499 : struct snapraid_task* task; - 500 : unsigned levcur; - 501 : - 502 168192 : task = io_parity_read(&io, &levcur, waiting_map, &waiting_mac); - 503 : - 504 : /* until now is parity */ - 505 168192 : state_usage_parity(state, waiting_map, waiting_mac); - 506 : - 507 : /* handle error conditions */ - 508 168192 : if (task->state == TASK_STATE_IOERROR) { - 509 0 : ++io_error; - 510 0 : goto bail; - 511 : } - 512 168192 : if (task->state == TASK_STATE_ERROR) { - 513 0 : ++error; - 514 0 : goto bail; - 515 : } - 516 168192 : if (task->state == TASK_STATE_ERROR_CONTINUE) { - 517 0 : ++error; - 518 0 : error_on_this_block = 1; - 519 : - 520 : /* if continuing on error, clear the missing buffer */ - 521 0 : buffer_recov[levcur] = 0; - 522 0 : continue; + 457 : /* now compute the hash */ + 458 166607 : if (rehash) { + 459 27247 : memhash(state->prevhash, state->prevhashseed, hash, buffer[diskcur], read_size); + 460 : + 461 : /* compute the new hash, and store it */ + 462 27247 : rehandle[diskcur].block = block; + 463 27247 : memhash(state->hash, state->hashseed, rehandle[diskcur].hash, buffer[diskcur], read_size); + 464 : } else { + 465 139360 : memhash(state->hash, state->hashseed, hash, buffer[diskcur], read_size); + 466 : } + 467 : + 468 : /* until now is hash */ + 469 166607 : state_usage_hash(state); + 470 : + 471 166607 : if (block_has_updated_hash(block)) { + 472 : /* compare the hash */ + 473 166607 : if (memcmp(hash, block->hash, BLOCK_HASH_SIZE) != 0) { + 474 920 : unsigned diff = memdiff(hash, block->hash, BLOCK_HASH_SIZE); + 475 : + 476 920 : log_tag("error:%u:%s:%s: Data error at position %u, diff bits %u\n", blockcur, disk->name, esc_tag(file->sub, esc_buffer), file_pos, diff); + 477 : + 478 : /* it's a silent error only if we are dealing with synced files */ + 479 920 : if (file_is_unsynced) { + 480 0 : ++error; + 481 0 : error_on_this_block = 1; + 482 : } else { + 483 920 : log_error("Data error in file '%s' at position '%u', diff bits %u\n", task->path, file_pos, diff); + 484 920 : ++silent_error; + 485 920 : silent_error_on_this_block = 1; + 486 : } + 487 920 : continue; + 488 : } + 489 : } + 490 : } + 491 : + 492 : /* buffers for parity read and not computed */ + 493 196224 : for (l = 0; l < state->level; ++l) + 494 168192 : buffer_recov[l] = buffer[diskmax + state->level + l]; + 495 28032 : for (; l < LEV_MAX; ++l) + 496 0 : buffer_recov[l] = 0; + 497 : + 498 : /* until now is misc */ + 499 28032 : state_usage_misc(state); + 500 : + 501 : /* read the parity */ + 502 196224 : for (l = 0; l < state->level; ++l) { + 503 : struct snapraid_task* task; + 504 : unsigned levcur; + 505 : + 506 168192 : task = io_parity_read(&io, &levcur, waiting_map, &waiting_mac); + 507 : + 508 : /* until now is parity */ + 509 168192 : state_usage_parity(state, waiting_map, waiting_mac); + 510 : + 511 : /* handle error conditions */ + 512 168192 : if (task->state == TASK_STATE_IOERROR) { + 513 : /* LCOV_EXCL_START */ + 514 : ++io_error; + 515 : goto bail; + 516 : /* LCOV_EXCL_STOP */ + 517 : } + 518 168192 : if (task->state == TASK_STATE_ERROR) { + 519 : /* LCOV_EXCL_START */ + 520 : ++error; + 521 : goto bail; + 522 : /* LCOV_EXCL_STOP */ 523 : } - 524 168192 : if (task->state == TASK_STATE_IOERROR_CONTINUE) { - 525 0 : ++io_error; - 526 0 : if (io_error >= state->opt.io_error_limit) { - 527 : /* LCOV_EXCL_START */ - 528 : log_fatal("DANGER! Too many input/output read error in the %s disk, it isn't possible to scrub.\n", lev_name(levcur)); - 529 : log_fatal("Ensure that disk '%s' is sane and can be read.\n", lev_config_name(levcur)); - 530 : log_fatal("Stopping at block %u\n", blockcur); - 531 : goto bail; - 532 : /* LCOV_EXCL_STOP */ - 533 : } - 534 : - 535 : /* otherwise continue */ - 536 0 : io_error_on_this_block = 1; - 537 : - 538 : /* if continuing on error, clear the missing buffer */ - 539 0 : buffer_recov[levcur] = 0; - 540 0 : continue; - 541 : } - 542 168192 : if (task->state != TASK_STATE_DONE) { - 543 : /* LCOV_EXCL_START */ - 544 : log_fatal("Internal inconsistency in task state\n"); - 545 : os_abort(); - 546 : /* LCOV_EXCL_STOP */ - 547 : } - 548 : } - 549 : - 550 : /* if we have read all the data required and it's correct, proceed with the parity check */ - 551 28032 : if (!error_on_this_block && !silent_error_on_this_block && !io_error_on_this_block) { - 552 : - 553 : /* compute the parity */ - 554 27112 : raid_gen(diskmax, state->level, state->block_size, buffer); - 555 : - 556 : /* compare the parity */ - 557 189784 : for (l = 0; l < state->level; ++l) { - 558 162672 : if (buffer_recov[l] && memcmp(buffer[diskmax + l], buffer_recov[l], state->block_size) != 0) { - 559 0 : unsigned diff = memdiff(buffer[diskmax + l], buffer_recov[l], state->block_size); + 524 168192 : if (task->state == TASK_STATE_ERROR_CONTINUE) { + 525 0 : ++error; + 526 0 : error_on_this_block = 1; + 527 : + 528 : /* if continuing on error, clear the missing buffer */ + 529 0 : buffer_recov[levcur] = 0; + 530 0 : continue; + 531 : } + 532 168192 : if (task->state == TASK_STATE_IOERROR_CONTINUE) { + 533 0 : ++io_error; + 534 0 : if (io_error >= state->opt.io_error_limit) { + 535 : /* LCOV_EXCL_START */ + 536 : log_fatal("DANGER! Too many input/output read error in the %s disk, it isn't possible to scrub.\n", lev_name(levcur)); + 537 : log_fatal("Ensure that disk '%s' is sane and can be read.\n", lev_config_name(levcur)); + 538 : log_fatal("Stopping at block %u\n", blockcur); + 539 : goto bail; + 540 : /* LCOV_EXCL_STOP */ + 541 : } + 542 : + 543 : /* otherwise continue */ + 544 0 : io_error_on_this_block = 1; + 545 : + 546 : /* if continuing on error, clear the missing buffer */ + 547 0 : buffer_recov[levcur] = 0; + 548 0 : continue; + 549 : } + 550 168192 : if (task->state != TASK_STATE_DONE) { + 551 : /* LCOV_EXCL_START */ + 552 : log_fatal("Internal inconsistency in task state\n"); + 553 : os_abort(); + 554 : /* LCOV_EXCL_STOP */ + 555 : } + 556 : } + 557 : + 558 : /* if we have read all the data required and it's correct, proceed with the parity check */ + 559 28032 : if (!error_on_this_block && !silent_error_on_this_block && !io_error_on_this_block) { 560 : - 561 0 : log_tag("parity_error:%u:%s: Data error, diff bits %u\n", blockcur, lev_config_name(l), diff); - 562 : - 563 : /* it's a silent error only if we are dealing with synced blocks */ - 564 0 : if (block_is_unsynced) { - 565 0 : ++error; - 566 0 : error_on_this_block = 1; - 567 : } else { - 568 0 : log_fatal("Data error in parity '%s' at position '%u', diff bits %u\n", lev_config_name(l), blockcur, diff); - 569 0 : ++silent_error; - 570 0 : silent_error_on_this_block = 1; - 571 : } - 572 : } - 573 : } - 574 : - 575 : /* until now is raid */ - 576 27112 : state_usage_raid(state); - 577 : } - 578 : - 579 28032 : if (silent_error_on_this_block || io_error_on_this_block) { - 580 : /* set the error status keeping other info */ - 581 920 : info_set(&state->infoarr, blockcur, info_set_bad(info)); - 582 27112 : } else if (error_on_this_block) { - 583 : /* do nothing, as this is a generic error */ - 584 : /* likely caused by a not synced array */ - 585 : } else { - 586 : /* if rehash is needed */ - 587 27112 : if (rehash) { - 588 : /* store all the new hash already computed */ - 589 32256 : for (j = 0; j < diskmax; ++j) { - 590 27648 : if (rehandle[j].block) - 591 27247 : memcpy(rehandle[j].block->hash, rehandle[j].hash, BLOCK_HASH_SIZE); - 592 : } - 593 : } - 594 : - 595 : /* update the time info of the block */ - 596 : /* and clear any other flag */ - 597 27112 : info_set(&state->infoarr, blockcur, info_make(now, 0, 0, 0)); - 598 : } - 599 : - 600 : /* mark the state as needing write */ - 601 28032 : state->need_write = 1; + 561 : /* compute the parity */ + 562 27112 : raid_gen(diskmax, state->level, state->block_size, buffer); + 563 : + 564 : /* compare the parity */ + 565 189784 : for (l = 0; l < state->level; ++l) { + 566 162672 : if (buffer_recov[l] && memcmp(buffer[diskmax + l], buffer_recov[l], state->block_size) != 0) { + 567 0 : unsigned diff = memdiff(buffer[diskmax + l], buffer_recov[l], state->block_size); + 568 : + 569 0 : log_tag("parity_error:%u:%s: Data error, diff bits %u\n", blockcur, lev_config_name(l), diff); + 570 : + 571 : /* it's a silent error only if we are dealing with synced blocks */ + 572 0 : if (block_is_unsynced) { + 573 0 : ++error; + 574 0 : error_on_this_block = 1; + 575 : } else { + 576 0 : log_fatal("Data error in parity '%s' at position '%u', diff bits %u\n", lev_config_name(l), blockcur, diff); + 577 0 : ++silent_error; + 578 0 : silent_error_on_this_block = 1; + 579 : } + 580 : } + 581 : } + 582 : + 583 : /* until now is raid */ + 584 27112 : state_usage_raid(state); + 585 : } + 586 : + 587 28032 : if (silent_error_on_this_block || io_error_on_this_block) { + 588 : /* set the error status keeping other info */ + 589 920 : info_set(&state->infoarr, blockcur, info_set_bad(info)); + 590 27112 : } else if (error_on_this_block) { + 591 : /* do nothing, as this is a generic error */ + 592 : /* likely caused by a not synced array */ + 593 : } else { + 594 : /* if rehash is needed */ + 595 27112 : if (rehash) { + 596 : /* store all the new hash already computed */ + 597 32256 : for (j = 0; j < diskmax; ++j) { + 598 27648 : if (rehandle[j].block) + 599 27247 : memcpy(rehandle[j].block->hash, rehandle[j].hash, BLOCK_HASH_SIZE); + 600 : } + 601 : } 602 : - 603 : /* count the number of processed block */ - 604 28032 : ++countpos; - 605 : - 606 : /* progress */ - 607 28032 : if (state_progress(state, &io, blockcur, countpos, countmax, countsize)) { - 608 : /* LCOV_EXCL_START */ - 609 : break; - 610 : /* LCOV_EXCL_STOP */ - 611 : } - 612 : - 613 : /* autosave */ - 614 28032 : if (state->autosave != 0 - 615 0 : && autosavedone >= autosavelimit /* if we have reached the limit */ - 616 0 : && autosavemissing >= autosavelimit /* if we have at least a full step to do */ - 617 : ) { - 618 0 : autosavedone = 0; /* restart the counter */ - 619 : - 620 : /* until now is misc */ - 621 0 : state_usage_misc(state); - 622 : - 623 0 : state_progress_stop(state); - 624 : - 625 0 : msg_progress("Autosaving...\n"); - 626 0 : state_write(state); + 603 : /* update the time info of the block */ + 604 : /* and clear any other flag */ + 605 27112 : info_set(&state->infoarr, blockcur, info_make(now, 0, 0, 0)); + 606 : } + 607 : + 608 : /* mark the state as needing write */ + 609 28032 : state->need_write = 1; + 610 : + 611 : /* count the number of processed block */ + 612 28032 : ++countpos; + 613 : + 614 : /* progress */ + 615 28032 : if (state_progress(state, &io, blockcur, countpos, countmax, countsize)) { + 616 : /* LCOV_EXCL_START */ + 617 : break; + 618 : /* LCOV_EXCL_STOP */ + 619 : } + 620 : + 621 : /* autosave */ + 622 28032 : if (state->autosave != 0 + 623 0 : && autosavedone >= autosavelimit /* if we have reached the limit */ + 624 0 : && autosavemissing >= autosavelimit /* if we have at least a full step to do */ + 625 : ) { + 626 0 : autosavedone = 0; /* restart the counter */ 627 : - 628 0 : state_progress_restart(state); - 629 : - 630 : /* drop until now */ - 631 0 : state_usage_waste(state); - 632 : } - 633 28032 : } - 634 : - 635 11 : state_progress_end(state, countpos, countmax, countsize); - 636 : - 637 11 : state_usage_print(state); - 638 : - 639 11 : if (error || silent_error || io_error) { - 640 1 : msg_status("\n"); - 641 1 : msg_status("%8u file errors\n", error); - 642 1 : msg_status("%8u io errors\n", io_error); - 643 1 : msg_status("%8u data errors\n", silent_error); - 644 : } else { - 645 : /* print the result only if processed something */ - 646 10 : if (countpos != 0) - 647 9 : msg_status("Everything OK\n"); - 648 : } - 649 : - 650 11 : if (error) - 651 0 : log_fatal("WARNING! Unexpected file errors!\n"); - 652 11 : if (io_error) - 653 0 : log_fatal("DANGER! Unexpected input/output errors! The failing blocks are now marked as bad!\n"); - 654 11 : if (silent_error) - 655 1 : log_fatal("DANGER! Unexpected data errors! The failing blocks are now marked as bad!\n"); - 656 11 : if (io_error || silent_error) { - 657 1 : log_fatal("Use 'snapraid status' to list the bad blocks.\n"); - 658 1 : log_fatal("Use 'snapraid -e fix' to recover.\n"); - 659 : } - 660 : - 661 11 : log_tag("summary:error_file:%u\n", error); - 662 11 : log_tag("summary:error_io:%u\n", io_error); - 663 11 : log_tag("summary:error_data:%u\n", silent_error); - 664 11 : if (error + silent_error + io_error == 0) - 665 10 : log_tag("summary:exit:ok\n"); - 666 : else - 667 1 : log_tag("summary:exit:error\n"); - 668 11 : log_flush(); - 669 : - 670 : bail: - 671 : /* stop all the worker threads */ - 672 11 : io_stop(&io); - 673 : - 674 77 : for (j = 0; j < diskmax; ++j) { - 675 66 : struct snapraid_file* file = handle[j].file; - 676 66 : struct snapraid_disk* disk = handle[j].disk; - 677 66 : ret = handle_close(&handle[j]); - 678 66 : if (ret == -1) { - 679 : /* LCOV_EXCL_START */ - 680 : log_tag("error:%u:%s:%s: Close error. %s\n", blockcur, disk->name, esc_tag(file->sub, esc_buffer), strerror(errno)); - 681 : log_fatal("DANGER! Unexpected close error in a data disk.\n"); - 682 : ++error; - 683 : /* continue, as we are already exiting */ - 684 : /* LCOV_EXCL_STOP */ - 685 : } - 686 : } - 687 : - 688 11 : free(handle); - 689 11 : free(rehandle_alloc); - 690 11 : free(waiting_map); - 691 11 : io_done(&io); - 692 : - 693 11 : if (state->opt.expect_recoverable) { - 694 1 : if (error + silent_error + io_error == 0) - 695 0 : return -1; - 696 : } else { - 697 10 : if (error + silent_error + io_error != 0) - 698 0 : return -1; - 699 : } - 700 11 : return 0; - 701 : } - 702 : - 703 : /** - 704 : * Return a * b / c approximated to the upper value. - 705 : */ - 706 2 : static uint32_t md(uint32_t a, uint32_t b, uint32_t c) - 707 : { - 708 2 : uint64_t v = a; - 709 : - 710 2 : v *= b; - 711 2 : v += c - 1; - 712 2 : v /= c; - 713 : - 714 2 : return v; - 715 : } - 716 : - 717 11 : int state_scrub(struct snapraid_state* state, int plan, int olderthan) - 718 : { - 719 : block_off_t blockmax; - 720 : block_off_t countlimit; - 721 : block_off_t i; - 722 : block_off_t count; - 723 : time_t recentlimit; - 724 : int ret; - 725 : struct snapraid_parity_handle parity_handle[LEV_MAX]; - 726 : struct snapraid_plan ps; - 727 : time_t* timemap; - 728 : unsigned error; - 729 : time_t now; - 730 : unsigned l; - 731 : - 732 : /* get the present time */ - 733 11 : now = time(0); - 734 : - 735 11 : msg_progress("Initializing...\n"); - 736 : - 737 11 : if ((plan == SCRUB_BAD || plan == SCRUB_NEW || plan == SCRUB_FULL) - 738 4 : && olderthan >= 0) { - 739 : /* LCOV_EXCL_START */ - 740 : log_fatal("You can specify -o, --older-than only with a numeric percentage.\n"); - 741 : exit(EXIT_FAILURE); - 742 : /* LCOV_EXCL_STOP */ - 743 : } + 628 : /* until now is misc */ + 629 0 : state_usage_misc(state); + 630 : + 631 0 : state_progress_stop(state); + 632 : + 633 0 : msg_progress("Autosaving...\n"); + 634 0 : state_write(state); + 635 : + 636 0 : state_progress_restart(state); + 637 : + 638 : /* drop until now */ + 639 0 : state_usage_waste(state); + 640 : } + 641 28032 : } + 642 : + 643 11 : state_progress_end(state, countpos, countmax, countsize); + 644 : + 645 11 : state_usage_print(state); + 646 : + 647 11 : if (error || silent_error || io_error) { + 648 1 : msg_status("\n"); + 649 1 : msg_status("%8u file errors\n", error); + 650 1 : msg_status("%8u io errors\n", io_error); + 651 1 : msg_status("%8u data errors\n", silent_error); + 652 : } else { + 653 : /* print the result only if processed something */ + 654 10 : if (countpos != 0) + 655 9 : msg_status("Everything OK\n"); + 656 : } + 657 : + 658 11 : if (error) + 659 0 : log_fatal("WARNING! Unexpected file errors!\n"); + 660 11 : if (io_error) + 661 0 : log_fatal("DANGER! Unexpected input/output errors! The failing blocks are now marked as bad!\n"); + 662 11 : if (silent_error) + 663 1 : log_fatal("DANGER! Unexpected data errors! The failing blocks are now marked as bad!\n"); + 664 11 : if (io_error || silent_error) { + 665 1 : log_fatal("Use 'snapraid status' to list the bad blocks.\n"); + 666 1 : log_fatal("Use 'snapraid -e fix' to recover.\n"); + 667 : } + 668 : + 669 11 : log_tag("summary:error_file:%u\n", error); + 670 11 : log_tag("summary:error_io:%u\n", io_error); + 671 11 : log_tag("summary:error_data:%u\n", silent_error); + 672 11 : if (error + silent_error + io_error == 0) + 673 10 : log_tag("summary:exit:ok\n"); + 674 : else + 675 1 : log_tag("summary:exit:error\n"); + 676 11 : log_flush(); + 677 : + 678 : bail: + 679 : /* stop all the worker threads */ + 680 11 : io_stop(&io); + 681 : + 682 77 : for (j = 0; j < diskmax; ++j) { + 683 66 : struct snapraid_file* file = handle[j].file; + 684 66 : struct snapraid_disk* disk = handle[j].disk; + 685 66 : ret = handle_close(&handle[j]); + 686 66 : if (ret == -1) { + 687 : /* LCOV_EXCL_START */ + 688 : log_tag("error:%u:%s:%s: Close error. %s\n", blockcur, disk->name, esc_tag(file->sub, esc_buffer), strerror(errno)); + 689 : log_fatal("DANGER! Unexpected close error in a data disk.\n"); + 690 : ++error; + 691 : /* continue, as we are already exiting */ + 692 : /* LCOV_EXCL_STOP */ + 693 : } + 694 : } + 695 : + 696 11 : free(handle); + 697 11 : free(rehandle_alloc); + 698 11 : free(waiting_map); + 699 11 : io_done(&io); + 700 : + 701 11 : if (state->opt.expect_recoverable) { + 702 1 : if (error + silent_error + io_error == 0) + 703 0 : return -1; + 704 : } else { + 705 10 : if (error + silent_error + io_error != 0) + 706 0 : return -1; + 707 : } + 708 11 : return 0; + 709 : } + 710 : + 711 : /** + 712 : * Return a * b / c approximated to the upper value. + 713 : */ + 714 2 : static uint32_t md(uint32_t a, uint32_t b, uint32_t c) + 715 : { + 716 2 : uint64_t v = a; + 717 : + 718 2 : v *= b; + 719 2 : v += c - 1; + 720 2 : v /= c; + 721 : + 722 2 : return v; + 723 : } + 724 : + 725 11 : int state_scrub(struct snapraid_state* state, int plan, int olderthan) + 726 : { + 727 : block_off_t blockmax; + 728 : block_off_t countlimit; + 729 : block_off_t i; + 730 : block_off_t count; + 731 : time_t recentlimit; + 732 : int ret; + 733 : struct snapraid_parity_handle parity_handle[LEV_MAX]; + 734 : struct snapraid_plan ps; + 735 : time_t* timemap; + 736 : unsigned error; + 737 : time_t now; + 738 : unsigned l; + 739 : + 740 : /* get the present time */ + 741 11 : now = time(0); + 742 : + 743 11 : msg_progress("Initializing...\n"); 744 : - 745 11 : blockmax = parity_allocated_size(state); - 746 : - 747 : /* preinitialize to avoid warnings */ - 748 11 : countlimit = 0; - 749 11 : recentlimit = 0; - 750 : - 751 11 : ps.state = state; - 752 11 : if (state->opt.force_scrub_even) { - 753 1 : ps.plan = SCRUB_EVEN; - 754 10 : } else if (plan == SCRUB_FULL) { - 755 2 : ps.plan = SCRUB_FULL; - 756 8 : } else if (plan == SCRUB_NEW) { - 757 1 : ps.plan = SCRUB_NEW; - 758 7 : } else if (plan == SCRUB_BAD) { - 759 1 : ps.plan = SCRUB_BAD; - 760 6 : } else if (state->opt.force_scrub_at) { - 761 : /* scrub the specified amount of blocks */ - 762 4 : ps.plan = SCRUB_AUTO; - 763 4 : countlimit = state->opt.force_scrub_at; - 764 4 : recentlimit = now; - 765 : } else { - 766 2 : ps.plan = SCRUB_AUTO; - 767 2 : if (plan >= 0) { - 768 1 : countlimit = md(blockmax, plan, 100); - 769 : } else { - 770 : /* by default scrub 8.33% of the array (100/12=8.(3)) */ - 771 1 : countlimit = md(blockmax, 1, 12); - 772 : } - 773 : - 774 2 : if (olderthan >= 0) { - 775 1 : recentlimit = now - olderthan * 24 * 3600; - 776 : } else { - 777 : /* by default use a 10 day time limit */ - 778 1 : recentlimit = now - 10 * 24 * 3600; - 779 : } - 780 : } + 745 11 : if ((plan == SCRUB_BAD || plan == SCRUB_NEW || plan == SCRUB_FULL) + 746 4 : && olderthan >= 0) { + 747 : /* LCOV_EXCL_START */ + 748 : log_fatal("You can specify -o, --older-than only with a numeric percentage.\n"); + 749 : exit(EXIT_FAILURE); + 750 : /* LCOV_EXCL_STOP */ + 751 : } + 752 : + 753 11 : blockmax = parity_allocated_size(state); + 754 : + 755 : /* preinitialize to avoid warnings */ + 756 11 : countlimit = 0; + 757 11 : recentlimit = 0; + 758 : + 759 11 : ps.state = state; + 760 11 : if (state->opt.force_scrub_even) { + 761 1 : ps.plan = SCRUB_EVEN; + 762 10 : } else if (plan == SCRUB_FULL) { + 763 2 : ps.plan = SCRUB_FULL; + 764 8 : } else if (plan == SCRUB_NEW) { + 765 1 : ps.plan = SCRUB_NEW; + 766 7 : } else if (plan == SCRUB_BAD) { + 767 1 : ps.plan = SCRUB_BAD; + 768 6 : } else if (state->opt.force_scrub_at) { + 769 : /* scrub the specified amount of blocks */ + 770 4 : ps.plan = SCRUB_AUTO; + 771 4 : countlimit = state->opt.force_scrub_at; + 772 4 : recentlimit = now; + 773 : } else { + 774 2 : ps.plan = SCRUB_AUTO; + 775 2 : if (plan >= 0) { + 776 1 : countlimit = md(blockmax, plan, 100); + 777 : } else { + 778 : /* by default scrub 8.33% of the array (100/12=8.(3)) */ + 779 1 : countlimit = md(blockmax, 1, 12); + 780 : } 781 : - 782 : /* identify the time limit */ - 783 : /* we sort all the block times, and we identify the time limit for which we reach the quota */ - 784 : /* this allow to process first the oldest blocks */ - 785 11 : timemap = malloc_nofail(blockmax * sizeof(time_t)); - 786 : - 787 : /* copy the info in the temp vector */ - 788 11 : count = 0; - 789 11 : log_tag("block_count:%u\n", blockmax); - 790 56096 : for (i = 0; i < blockmax; ++i) { - 791 56085 : snapraid_info info = info_get(&state->infoarr, i); - 792 : - 793 : /* skip unused blocks */ - 794 56085 : if (info == 0) - 795 0 : continue; - 796 : - 797 56085 : timemap[count++] = info_get_time(info); - 798 : } - 799 : - 800 11 : if (!count) { - 801 : /* LCOV_EXCL_START */ - 802 : log_fatal("The array appears to be empty.\n"); - 803 : exit(EXIT_FAILURE); - 804 : /* LCOV_EXCL_STOP */ - 805 : } - 806 : - 807 : /* sort it */ - 808 11 : qsort(timemap, count, sizeof(time_t), time_compare); - 809 : - 810 : /* output the info map */ - 811 11 : i = 0; - 812 11 : log_tag("info_count:%u\n", count); - 813 43 : while (i < count) { - 814 21 : unsigned j = i + 1; - 815 56106 : while (j < count && timemap[i] == timemap[j]) - 816 56064 : ++j; - 817 21 : log_tag("info_time:%" PRIu64 ":%u\n", (uint64_t)timemap[i], j - i); - 818 21 : i = j; - 819 : } - 820 : - 821 : /* compute the limits from count/recentlimit */ - 822 11 : if (ps.plan == SCRUB_AUTO) { - 823 : /* no more than the full count */ - 824 6 : if (countlimit > count) - 825 2 : countlimit = count; - 826 : - 827 : /* decrease until we reach the specific recentlimit */ - 828 59 : while (countlimit > 0 && timemap[countlimit - 1] > recentlimit) - 829 47 : --countlimit; - 830 : - 831 : /* if there is something to scrub */ - 832 6 : if (countlimit > 0) { - 833 : /* get the most recent time we want to scrub */ - 834 5 : ps.timelimit = timemap[countlimit - 1]; - 835 : - 836 : /* count how many entries for this exact time we have to scrub */ - 837 : /* if the blocks have all the same time, we end with countlimit == lastlimit */ - 838 5 : ps.lastlimit = 1; - 839 2601 : while (countlimit > ps.lastlimit && timemap[countlimit - ps.lastlimit - 1] == ps.timelimit) - 840 2591 : ++ps.lastlimit; - 841 : } else { - 842 : /* if nothing to scrub, disable also other limits */ - 843 1 : ps.timelimit = 0; - 844 1 : ps.lastlimit = 0; - 845 : } - 846 : - 847 6 : log_tag("count_limit:%u\n", countlimit); - 848 6 : log_tag("time_limit:%" PRIu64 "\n", (uint64_t)ps.timelimit); - 849 6 : log_tag("last_limit:%u\n", ps.lastlimit); - 850 : } - 851 : - 852 : /* free the temp vector */ - 853 11 : free(timemap); + 782 2 : if (olderthan >= 0) { + 783 1 : recentlimit = now - olderthan * 24 * 3600; + 784 : } else { + 785 : /* by default use a 10 day time limit */ + 786 1 : recentlimit = now - 10 * 24 * 3600; + 787 : } + 788 : } + 789 : + 790 : /* identify the time limit */ + 791 : /* we sort all the block times, and we identify the time limit for which we reach the quota */ + 792 : /* this allow to process first the oldest blocks */ + 793 11 : timemap = malloc_nofail(blockmax * sizeof(time_t)); + 794 : + 795 : /* copy the info in the temp vector */ + 796 11 : count = 0; + 797 11 : log_tag("block_count:%u\n", blockmax); + 798 56096 : for (i = 0; i < blockmax; ++i) { + 799 56085 : snapraid_info info = info_get(&state->infoarr, i); + 800 : + 801 : /* skip unused blocks */ + 802 56085 : if (info == 0) + 803 0 : continue; + 804 : + 805 56085 : timemap[count++] = info_get_time(info); + 806 : } + 807 : + 808 11 : if (!count) { + 809 : /* LCOV_EXCL_START */ + 810 : log_fatal("The array appears to be empty.\n"); + 811 : exit(EXIT_FAILURE); + 812 : /* LCOV_EXCL_STOP */ + 813 : } + 814 : + 815 : /* sort it */ + 816 11 : qsort(timemap, count, sizeof(time_t), time_compare); + 817 : + 818 : /* output the info map */ + 819 11 : i = 0; + 820 11 : log_tag("info_count:%u\n", count); + 821 41 : while (i < count) { + 822 19 : unsigned j = i + 1; + 823 56104 : while (j < count && timemap[i] == timemap[j]) + 824 56066 : ++j; + 825 19 : log_tag("info_time:%" PRIu64 ":%u\n", (uint64_t)timemap[i], j - i); + 826 19 : i = j; + 827 : } + 828 : + 829 : /* compute the limits from count/recentlimit */ + 830 11 : if (ps.plan == SCRUB_AUTO) { + 831 : /* no more than the full count */ + 832 6 : if (countlimit > count) + 833 2 : countlimit = count; + 834 : + 835 : /* decrease until we reach the specific recentlimit */ + 836 59 : while (countlimit > 0 && timemap[countlimit - 1] > recentlimit) + 837 47 : --countlimit; + 838 : + 839 : /* if there is something to scrub */ + 840 6 : if (countlimit > 0) { + 841 : /* get the most recent time we want to scrub */ + 842 5 : ps.timelimit = timemap[countlimit - 1]; + 843 : + 844 : /* count how many entries for this exact time we have to scrub */ + 845 : /* if the blocks have all the same time, we end with countlimit == lastlimit */ + 846 5 : ps.lastlimit = 1; + 847 2601 : while (countlimit > ps.lastlimit && timemap[countlimit - ps.lastlimit - 1] == ps.timelimit) + 848 2591 : ++ps.lastlimit; + 849 : } else { + 850 : /* if nothing to scrub, disable also other limits */ + 851 1 : ps.timelimit = 0; + 852 1 : ps.lastlimit = 0; + 853 : } 854 : - 855 : /* open the file for reading */ - 856 77 : for (l = 0; l < state->level; ++l) { - 857 66 : ret = parity_open(&parity_handle[l], &state->parity[l], l, state->file_mode, state->block_size, state->opt.parity_limit_size); - 858 66 : if (ret == -1) { - 859 : /* LCOV_EXCL_START */ - 860 : log_fatal("WARNING! Without an accessible %s file, it isn't possible to scrub.\n", lev_name(l)); - 861 : exit(EXIT_FAILURE); - 862 : /* LCOV_EXCL_STOP */ - 863 : } - 864 : } - 865 : - 866 11 : msg_progress("Scrubbing...\n"); - 867 : - 868 11 : error = 0; - 869 : - 870 11 : ret = state_scrub_process(state, parity_handle, 0, blockmax, &ps, now); - 871 11 : if (ret == -1) { - 872 0 : ++error; - 873 : /* continue, as we are already exiting */ - 874 : } + 855 6 : log_tag("count_limit:%u\n", countlimit); + 856 6 : log_tag("time_limit:%" PRIu64 "\n", (uint64_t)ps.timelimit); + 857 6 : log_tag("last_limit:%u\n", ps.lastlimit); + 858 : } + 859 : + 860 : /* free the temp vector */ + 861 11 : free(timemap); + 862 : + 863 : /* open the file for reading */ + 864 77 : for (l = 0; l < state->level; ++l) { + 865 66 : ret = parity_open(&parity_handle[l], &state->parity[l], l, state->file_mode, state->block_size, state->opt.parity_limit_size); + 866 66 : if (ret == -1) { + 867 : /* LCOV_EXCL_START */ + 868 : log_fatal("WARNING! Without an accessible %s file, it isn't possible to scrub.\n", lev_name(l)); + 869 : exit(EXIT_FAILURE); + 870 : /* LCOV_EXCL_STOP */ + 871 : } + 872 : } + 873 : + 874 11 : msg_progress("Scrubbing...\n"); 875 : - 876 77 : for (l = 0; l < state->level; ++l) { - 877 66 : ret = parity_close(&parity_handle[l]); - 878 66 : if (ret == -1) { - 879 : /* LCOV_EXCL_START */ - 880 : log_fatal("DANGER! Unexpected close error in %s disk.\n", lev_name(l)); - 881 : ++error; - 882 : /* continue, as we are already exiting */ - 883 : /* LCOV_EXCL_STOP */ - 884 : } - 885 : } - 886 : - 887 : /* abort if required */ - 888 11 : if (error != 0) - 889 0 : return -1; - 890 11 : return 0; - 891 : } - 892 : + 876 11 : error = 0; + 877 : + 878 11 : ret = state_scrub_process(state, parity_handle, 0, blockmax, &ps, now); + 879 11 : if (ret == -1) { + 880 0 : ++error; + 881 : /* continue, as we are already exiting */ + 882 : } + 883 : + 884 77 : for (l = 0; l < state->level; ++l) { + 885 66 : ret = parity_close(&parity_handle[l]); + 886 66 : if (ret == -1) { + 887 : /* LCOV_EXCL_START */ + 888 : log_fatal("DANGER! Unexpected close error in %s disk.\n", lev_name(l)); + 889 : ++error; + 890 : /* continue, as we are already exiting */ + 891 : /* LCOV_EXCL_STOP */ + 892 : } + 893 : } + 894 : + 895 : /* abort if required */ + 896 11 : if (error != 0) + 897 0 : return -1; + 898 11 : return 0; + 899 : } + 900 : diff --git a/cov/cmdline/search.c.func-sort-c.html b/cov/cmdline/search.c.func-sort-c.html index 02721bee..80b5a3f0 100644 --- a/cov/cmdline/search.c.func-sort-c.html +++ b/cov/cmdline/search.c.func-sort-c.html @@ -61,19 +61,19 @@ search_file - 1843728 + 1843909 search_file_free - 1843728 + 1843909 state_search_fetch - 639176 + 638916 search_file_compare - 20130 + 20183 search_dir diff --git a/cov/cmdline/search.c.func.html b/cov/cmdline/search.c.func.html index fe7f744e..2dfdb1be 100644 --- a/cov/cmdline/search.c.func.html +++ b/cov/cmdline/search.c.func.html @@ -65,15 +65,15 @@ search_file - 1843728 + 1843909 search_file_compare - 20130 + 20183 search_file_free - 1843728 + 1843909 state_search @@ -85,7 +85,7 @@ state_search_fetch - 639176 + 638916
diff --git a/cov/cmdline/search.c.gcov.html b/cov/cmdline/search.c.gcov.html index fcd3b596..86339e03 100644 --- a/cov/cmdline/search.c.gcov.html +++ b/cov/cmdline/search.c.gcov.html @@ -85,27 +85,27 @@ 23 : /****************************************************************************/ 24 : /* search */ 25 : - 26 1843728 : static void search_file(struct snapraid_state* state, const char* path, data_off_t size, int64_t mtime_sec, int mtime_nsec) + 26 1843909 : static void search_file(struct snapraid_state* state, const char* path, data_off_t size, int64_t mtime_sec, int mtime_nsec) 27 : { 28 : struct snapraid_search_file* file; 29 : tommy_uint32_t file_hash; 30 : - 31 1843728 : file = malloc_nofail(sizeof(struct snapraid_search_file)); - 32 1843728 : file->path = strdup_nofail(path); - 33 1843728 : file->size = size; - 34 1843728 : file->mtime_sec = mtime_sec; - 35 1843728 : file->mtime_nsec = mtime_nsec; + 31 1843909 : file = malloc_nofail(sizeof(struct snapraid_search_file)); + 32 1843909 : file->path = strdup_nofail(path); + 33 1843909 : file->size = size; + 34 1843909 : file->mtime_sec = mtime_sec; + 35 1843909 : file->mtime_nsec = mtime_nsec; 36 : - 37 1843728 : file_hash = file_stamp_hash(file->size, file->mtime_sec, file->mtime_nsec); + 37 1843909 : file_hash = file_stamp_hash(file->size, file->mtime_sec, file->mtime_nsec); 38 : - 39 1843728 : tommy_hashdyn_insert(&state->searchset, &file->node, file, file_hash); - 40 1843728 : } + 39 1843909 : tommy_hashdyn_insert(&state->searchset, &file->node, file, file_hash); + 40 1843909 : } 41 : - 42 1843728 : void search_file_free(struct snapraid_search_file* file) + 42 1843909 : void search_file_free(struct snapraid_search_file* file) 43 : { - 44 1843728 : free(file->path); - 45 1843728 : free(file); - 46 1843728 : } + 44 1843909 : free(file->path); + 45 1843909 : free(file); + 46 1843909 : } 47 : 48 : struct search_file_compare_arg { 49 : const struct snapraid_state* state; @@ -117,29 +117,29 @@ 55 : int prevhash; 56 : }; 57 : - 58 20130 : int search_file_compare(const void* void_arg, const void* void_data) + 58 20183 : int search_file_compare(const void* void_arg, const void* void_data) 59 : { - 60 20130 : const struct search_file_compare_arg* arg = void_arg; - 61 20130 : const struct snapraid_search_file* file = void_data; - 62 20130 : const struct snapraid_state* state = arg->state; + 60 20183 : const struct search_file_compare_arg* arg = void_arg; + 61 20183 : const struct snapraid_search_file* file = void_data; + 62 20183 : const struct snapraid_state* state = arg->state; 63 : unsigned char buffer_hash[HASH_MAX]; - 64 20130 : const char* path = file->path; + 64 20183 : const char* path = file->path; 65 : int f; 66 : ssize_t ret; 67 : 68 : /* compare file info */ - 69 20130 : if (arg->file->size != file->size) + 69 20183 : if (arg->file->size != file->size) 70 0 : return -1; 71 : - 72 20130 : if (arg->file->mtime_sec != file->mtime_sec) + 72 20183 : if (arg->file->mtime_sec != file->mtime_sec) 73 0 : return -1; 74 : - 75 20130 : if (arg->file->mtime_nsec != file->mtime_nsec) + 75 20183 : if (arg->file->mtime_nsec != file->mtime_nsec) 76 0 : return -1; 77 : 78 : /* read the block and compare the hash */ - 79 20130 : f = open(path, O_RDONLY | O_BINARY); - 80 20130 : if (f == -1) { + 79 20183 : f = open(path, O_RDONLY | O_BINARY); + 80 20183 : if (f == -1) { 81 : /* LCOV_EXCL_START */ 82 : if (errno == ENOENT) { 83 : log_fatal("DANGER! file '%s' disappeared.\n", path); @@ -151,16 +151,16 @@ 89 : /* LCOV_EXCL_STOP */ 90 : } 91 : - 92 20130 : ret = pread(f, arg->buffer, arg->read_size, arg->offset); - 93 20130 : if (ret < 0 || (unsigned)ret != arg->read_size) { + 92 20183 : ret = pread(f, arg->buffer, arg->read_size, arg->offset); + 93 20183 : if (ret < 0 || (unsigned)ret != arg->read_size) { 94 : /* LCOV_EXCL_START */ 95 : log_fatal("Error reading file '%s'. %s.\n", path, strerror(errno)); 96 : exit(EXIT_FAILURE); 97 : /* LCOV_EXCL_STOP */ 98 : } 99 : - 100 20130 : ret = close(f); - 101 20130 : if (ret != 0) { + 100 20183 : ret = close(f); + 101 20183 : if (ret != 0) { 102 : /* LCOV_EXCL_START */ 103 : log_fatal("Error closing file '%s'. %s.\n", path, strerror(errno)); 104 : exit(EXIT_FAILURE); @@ -168,14 +168,14 @@ 106 : } 107 : 108 : /* compute the hash */ - 109 20130 : if (arg->prevhash) + 109 20183 : if (arg->prevhash) 110 0 : memhash(state->prevhash, state->prevhashseed, buffer_hash, arg->buffer, arg->read_size); 111 : else - 112 20130 : memhash(state->hash, state->hashseed, buffer_hash, arg->buffer, arg->read_size); + 112 20183 : memhash(state->hash, state->hashseed, buffer_hash, arg->buffer, arg->read_size); 113 : 114 : /* check if the hash is matching */ - 115 20130 : if (memcmp(buffer_hash, arg->block->hash, BLOCK_HASH_SIZE) != 0) - 116 2220 : return -1; + 115 20183 : if (memcmp(buffer_hash, arg->block->hash, BLOCK_HASH_SIZE) != 0) + 116 2273 : return -1; 117 : 118 17910 : if (arg->read_size != state->block_size) { 119 : /* fill the remaining with 0 */ @@ -185,26 +185,26 @@ 123 17910 : return 0; 124 : } 125 : - 126 639176 : int state_search_fetch(struct snapraid_state* state, int prevhash, struct snapraid_file* missing_file, block_off_t missing_file_pos, struct snapraid_block* missing_block, unsigned char* buffer) + 126 638916 : int state_search_fetch(struct snapraid_state* state, int prevhash, struct snapraid_file* missing_file, block_off_t missing_file_pos, struct snapraid_block* missing_block, unsigned char* buffer) 127 : { 128 : struct snapraid_search_file* file; 129 : tommy_uint32_t file_hash; 130 : struct search_file_compare_arg arg; 131 : - 132 639176 : arg.state = state; - 133 639176 : arg.block = missing_block; - 134 639176 : arg.file = missing_file; - 135 639176 : arg.buffer = buffer; - 136 639176 : arg.offset = state->block_size * (data_off_t)missing_file_pos; - 137 639176 : arg.read_size = file_block_size(missing_file, missing_file_pos, state->block_size); - 138 639176 : arg.prevhash = prevhash; + 132 638916 : arg.state = state; + 133 638916 : arg.block = missing_block; + 134 638916 : arg.file = missing_file; + 135 638916 : arg.buffer = buffer; + 136 638916 : arg.offset = state->block_size * (data_off_t)missing_file_pos; + 137 638916 : arg.read_size = file_block_size(missing_file, missing_file_pos, state->block_size); + 138 638916 : arg.prevhash = prevhash; 139 : - 140 639176 : file_hash = file_stamp_hash(arg.file->size, arg.file->mtime_sec, arg.file->mtime_nsec); + 140 638916 : file_hash = file_stamp_hash(arg.file->size, arg.file->mtime_sec, arg.file->mtime_nsec); 141 : 142 : /* search in the hashtable, and also check if the data matches the hash */ - 143 639176 : file = tommy_hashdyn_search(&state->searchset, search_file_compare, &arg, file_hash); - 144 639176 : if (!file) - 145 621266 : return -1; + 143 638916 : file = tommy_hashdyn_search(&state->searchset, search_file_compare, &arg, file_hash); + 144 638916 : if (!file) + 145 621006 : return -1; 146 : 147 : /* if found, buffer is already set with data */ 148 17910 : return 0; @@ -226,40 +226,40 @@ 164 : char path_next[PATH_MAX]; 165 : char sub_next[PATH_MAX]; 166 : char out[PATH_MAX]; - 167 2040132 : struct snapraid_filter* reason = 0; + 167 2040347 : struct snapraid_filter* reason = 0; 168 : struct stat st; 169 : const char* name; 170 : struct dirent* dd; 171 : 172 : /* clear errno to detect erroneous conditions */ - 173 2040132 : errno = 0; - 174 2040132 : dd = readdir(d); - 175 2040132 : if (dd == 0 && errno != 0) { + 173 2040347 : errno = 0; + 174 2040347 : dd = readdir(d); + 175 2040347 : if (dd == 0 && errno != 0) { 176 : /* LCOV_EXCL_START */ 177 : log_fatal("Error reading directory '%s'. %s.\n", dir, strerror(errno)); 178 : exit(EXIT_FAILURE); 179 : /* LCOV_EXCL_STOP */ 180 : } - 181 2040132 : if (dd == 0) { + 181 2040347 : if (dd == 0) { 182 2462 : break; /* finished */ 183 : } 184 : 185 : /* skip "." and ".." files */ - 186 2037670 : name = dd->d_name; - 187 2037670 : if (name[0] == '.' && (name[1] == 0 || (name[1] == '.' && name[2] == 0))) + 186 2037885 : name = dd->d_name; + 187 2037885 : if (name[0] == '.' && (name[1] == 0 || (name[1] == '.' && name[2] == 0))) 188 9848 : continue; 189 : - 190 2032746 : pathprint(path_next, sizeof(path_next), "%s%s", dir, name); - 191 2032746 : pathprint(sub_next, sizeof(sub_next), "%s%s", sub, name); + 190 2032961 : pathprint(path_next, sizeof(path_next), "%s%s", dir, name); + 191 2032961 : pathprint(sub_next, sizeof(sub_next), "%s%s", sub, name); 192 : 193 : /* exclude hidden files even before calling lstat() */ - 194 2032746 : if (disk != 0 && filter_hidden(state->filter_hidden, dd) != 0) { + 194 2032961 : if (disk != 0 && filter_hidden(state->filter_hidden, dd) != 0) { 195 0 : msg_verbose("Excluding hidden '%s'\n", path_next); 196 0 : continue; 197 : } 198 : 199 : /* exclude content files even before calling lstat() */ - 200 2032746 : if (disk != 0 && filter_content(&state->contentlist, path_next) != 0) { + 200 2032961 : if (disk != 0 && filter_content(&state->contentlist, path_next) != 0) { 201 0 : msg_verbose("Excluding content '%s'\n", path_next); 202 0 : continue; 203 : } @@ -283,7 +283,7 @@ 221 : } 222 : #else 223 : /* get lstat info about the file */ - 224 2032746 : if (lstat(path_next, &st) != 0) { + 224 2032961 : if (lstat(path_next, &st) != 0) { 225 : /* LCOV_EXCL_START */ 226 : log_fatal("Error in stat file/directory '%s'. %s.\n", path_next, strerror(errno)); 227 : exit(EXIT_FAILURE); @@ -291,13 +291,13 @@ 229 : } 230 : #endif 231 : - 232 2032746 : if (S_ISREG(st.st_mode)) { - 233 1968447 : if (disk == 0 || filter_path(&state->filterlist, &reason, disk->name, sub_next) == 0) { - 234 1843728 : search_file(state, path_next, st.st_size, st.st_mtime, STAT_NSEC(&st)); + 232 2032961 : if (S_ISREG(st.st_mode)) { + 233 1968636 : if (disk == 0 || filter_path(&state->filterlist, &reason, disk->name, sub_next) == 0) { + 234 1843909 : search_file(state, path_next, st.st_size, st.st_mtime, STAT_NSEC(&st)); 235 : } else { - 236 124719 : msg_verbose("Excluding link '%s' for rule '%s'\n", path_next, filter_type(reason, out, sizeof(out))); + 236 124727 : msg_verbose("Excluding link '%s' for rule '%s'\n", path_next, filter_type(reason, out, sizeof(out))); 237 : } - 238 64299 : } else if (S_ISDIR(st.st_mode)) { + 238 64325 : } else if (S_ISDIR(st.st_mode)) { 239 1781 : if (disk == 0 || filter_subdir(&state->filterlist, &reason, disk->name, sub_next) == 0) { 240 1781 : pathslash(path_next, sizeof(path_next)); 241 1781 : pathslash(sub_next, sizeof(sub_next)); @@ -306,7 +306,7 @@ 244 0 : msg_verbose("Excluding directory '%s' for rule '%s'\n", path_next, filter_type(reason, out, sizeof(out))); 245 : } 246 : } - 247 2037670 : } + 247 2037885 : } 248 : 249 2462 : if (closedir(d) != 0) { 250 : /* LCOV_EXCL_START */ diff --git a/cov/cmdline/snapraid.c.func-sort-c.html b/cov/cmdline/snapraid.c.func-sort-c.html index 287d95e5..44738806 100644 --- a/cov/cmdline/snapraid.c.func-sort-c.html +++ b/cov/cmdline/snapraid.c.func-sort-c.html @@ -31,9 +31,9 @@ lcov.info Lines: - 494 + 496 542 - 91.1 % + 91.5 % Date: @@ -61,19 +61,19 @@ test - 275 + 276 main - 275 + 276 config - 274 + 275 log_open - 264 + 265 log_close diff --git a/cov/cmdline/snapraid.c.func.html b/cov/cmdline/snapraid.c.func.html index 66557d82..3ea7476c 100644 --- a/cov/cmdline/snapraid.c.func.html +++ b/cov/cmdline/snapraid.c.func.html @@ -31,9 +31,9 @@ lcov.info Lines: - 494 + 496 542 - 91.1 % + 91.5 % Date: @@ -61,7 +61,7 @@ config - 274 + 275 log_close @@ -69,11 +69,11 @@ log_open - 264 + 265 main - 275 + 276 memory @@ -85,7 +85,7 @@ test - 275 + 276 usage diff --git a/cov/cmdline/snapraid.c.gcov.html b/cov/cmdline/snapraid.c.gcov.html index ea9d1eae..c470bc51 100644 --- a/cov/cmdline/snapraid.c.gcov.html +++ b/cov/cmdline/snapraid.c.gcov.html @@ -31,9 +31,9 @@ lcov.info Lines: - 494 + 496 542 - 91.1 % + 91.5 % Date: @@ -152,14 +152,14 @@ 90 237 : msg_progress("Using %u MiB of memory for the FileSystem.\n", (unsigned)(malloc_counter_get() / MEBI)); 91 237 : } 92 : - 93 275 : void test(int argc, char* argv[]) + 93 276 : void test(int argc, char* argv[]) 94 : { 95 : int i; 96 : char buffer[ESC_MAX]; 97 : 98 : /* special testing code for quoting */ - 99 275 : if (argc < 2 || strcmp(argv[1], "test") != 0) - 100 548 : return; + 99 276 : if (argc < 2 || strcmp(argv[1], "test") != 0) + 100 550 : return; 101 : 102 1 : for (i = 2; i < argc; ++i) { 103 0 : printf("argv[%d]\n", i); @@ -185,7 +185,7 @@ 123 : /****************************************************************************/ 124 : /* log */ 125 : - 126 264 : void log_open(const char* file) + 126 265 : void log_open(const char* file) 127 : { 128 : char path[PATH_MAX]; 129 : const char* mode; @@ -195,8 +195,8 @@ 133 : struct tm* tm; 134 : 135 : /* leave stdlog at 0 if not specified */ - 136 264 : if (file == 0) - 137 374 : return; + 136 265 : if (file == 0) + 137 376 : return; 138 : 139 80 : t = time(0); 140 80 : tm = localtime(&t); @@ -286,7 +286,7 @@ 224 : /****************************************************************************/ 225 : /* config */ 226 : - 227 274 : void config(char* conf, size_t conf_size, const char* argv0) + 227 275 : void config(char* conf, size_t conf_size, const char* argv0) 228 : { 229 : #ifdef _WIN32 230 : char* slash; @@ -303,9 +303,9 @@ 241 : #else 242 : (void)argv0; 243 : - 244 274 : pathcpy(conf, conf_size, "/etc/" PACKAGE ".conf"); + 244 275 : pathcpy(conf, conf_size, "/etc/" PACKAGE ".conf"); 245 : #endif - 246 274 : } + 246 275 : } 247 : 248 : /****************************************************************************/ 249 : /* main */ @@ -580,7 +580,7 @@ 518 : #define OPERATION_DEVICES 16 519 : #define OPERATION_SMART 17 520 : - 521 275 : int main(int argc, char* argv[]) + 521 276 : int main(int argc, char* argv[]) 522 : { 523 : int c; 524 : struct snapraid_option opt; @@ -610,43 +610,43 @@ 548 : struct tm* tm; 549 : int i; 550 : - 551 275 : test(argc, argv); + 551 276 : test(argc, argv); 552 : - 553 274 : lock_init(); + 553 275 : lock_init(); 554 : 555 : /* defaults */ - 556 274 : config(conf, sizeof(conf), argv[0]); - 557 274 : memset(&opt, 0, sizeof(opt)); - 558 274 : opt.io_error_limit = 100; - 559 274 : blockstart = 0; - 560 274 : blockcount = 0; - 561 274 : tommy_list_init(&filterlist_file); - 562 274 : tommy_list_init(&filterlist_disk); - 563 274 : period = 1000; - 564 274 : filter_missing = 0; - 565 274 : filter_error = 0; - 566 274 : plan = SCRUB_AUTO; - 567 274 : olderthan = SCRUB_AUTO; - 568 274 : import_timestamp = 0; - 569 274 : import_content = 0; - 570 274 : log_file = 0; - 571 274 : lock = 0; - 572 274 : gen_conf = 0; - 573 274 : speedtest = 0; - 574 274 : run = 0; + 556 275 : config(conf, sizeof(conf), argv[0]); + 557 275 : memset(&opt, 0, sizeof(opt)); + 558 275 : opt.io_error_limit = 100; + 559 275 : blockstart = 0; + 560 275 : blockcount = 0; + 561 275 : tommy_list_init(&filterlist_file); + 562 275 : tommy_list_init(&filterlist_disk); + 563 275 : period = 1000; + 564 275 : filter_missing = 0; + 565 275 : filter_error = 0; + 566 275 : plan = SCRUB_AUTO; + 567 275 : olderthan = SCRUB_AUTO; + 568 275 : import_timestamp = 0; + 569 275 : import_content = 0; + 570 275 : log_file = 0; + 571 275 : lock = 0; + 572 275 : gen_conf = 0; + 573 275 : speedtest = 0; + 574 275 : run = 0; 575 : - 576 274 : opterr = 0; - 577 3450 : while ((c = + 576 275 : opterr = 0; + 577 3463 : while ((c = 578 : #if HAVE_GETOPT_LONG 579 : getopt_long(argc, argv, OPTIONS, long_options, 0)) 580 : #else 581 : getopt(argc, argv, OPTIONS)) 582 : #endif 583 : != EOF) { - 584 2907 : switch (c) { + 584 2918 : switch (c) { 585 : case 'c' : - 586 267 : pathimport(conf, sizeof(conf), optarg); - 587 267 : break; + 586 268 : pathimport(conf, sizeof(conf), optarg); + 587 268 : break; 588 : case 'f' : { 589 6 : struct snapraid_filter* filter = filter_alloc_file(1, optarg); 590 6 : if (!filter) { @@ -787,14 +787,14 @@ 725 7 : opt.prehash = 1; 726 7 : break; 727 : case 'v' : - 728 25 : ++msg_level; - 729 25 : break; + 728 26 : ++msg_level; + 729 26 : break; 730 : case 'q' : 731 726 : --msg_level; 732 726 : break; 733 : case 'G' : - 734 25 : opt.gui = 1; - 735 25 : break; + 734 26 : opt.gui = 1; + 735 26 : break; 736 : case 'H' : 737 1 : usage(); 738 1 : exit(EXIT_SUCCESS); @@ -817,8 +817,8 @@ 755 23 : opt.expect_recoverable = 1; 756 23 : break; 757 : case OPT_TEST_SKIP_SELF : - 758 267 : opt.skip_self = 1; - 759 267 : break; + 758 268 : opt.skip_self = 1; + 759 268 : break; 760 : case OPT_TEST_SKIP_SIGN : 761 0 : opt.skip_sign = 1; 762 0 : break; @@ -826,9 +826,9 @@ 764 1 : opt.skip_fallocate = 1; 765 1 : break; 766 : case OPT_TEST_SKIP_DEVICE : - 767 274 : opt.skip_device = 1; - 768 274 : period = 50; /* reduce period of the speed test */ - 769 274 : break; + 767 275 : opt.skip_device = 1; + 768 275 : period = 50; /* reduce period of the speed test */ + 769 275 : break; 770 : case OPT_TEST_SKIP_CONTENT_CHECK : 771 0 : opt.skip_content_check = 1; 772 0 : break; @@ -854,8 +854,8 @@ 792 0 : opt.force_order = SORT_INODE; 793 0 : break; 794 : case OPT_TEST_FORCE_ORDER_ALPHA : - 795 265 : opt.force_order = SORT_ALPHA; - 796 265 : break; + 795 266 : opt.force_order = SORT_ALPHA; + 796 266 : break; 797 : case OPT_TEST_FORCE_ORDER_DIR : 798 0 : opt.force_order = SORT_DIR; 799 0 : break; @@ -875,9 +875,9 @@ 813 19 : break; 814 : case OPT_TEST_EXPECT_NEED_SYNC : 815 : /* invert the exit codes */ - 816 6 : exit_success = 1; - 817 6 : exit_sync_needed = 0; - 818 6 : break; + 816 7 : exit_success = 1; + 817 7 : exit_sync_needed = 0; + 818 7 : break; 819 : case OPT_TEST_RUN : 820 10 : run = optarg; 821 10 : break; @@ -885,8 +885,8 @@ 823 0 : opt.force_scan_winfind = 1; 824 0 : break; 825 : case OPT_TEST_FORCE_PROGRESS : - 826 267 : opt.force_progress = 1; - 827 267 : break; + 826 268 : opt.force_progress = 1; + 827 268 : break; 828 : case OPT_TEST_FORCE_AUTOSAVE_AT : 829 1 : opt.force_autosave_at = atoi(optarg); 830 1 : break; @@ -894,8 +894,8 @@ 832 1 : opt.fake_device = 1; 833 1 : break; 834 : case OPT_NO_WARNINGS : - 835 268 : opt.no_warnings = 1; - 836 268 : break; + 835 269 : opt.no_warnings = 1; + 836 269 : break; 837 : case OPT_TEST_FAKE_UUID : 838 1 : opt.fake_uuid = 2; 839 1 : break; @@ -915,8 +915,8 @@ 853 : } 854 1 : break; 855 : case OPT_TEST_IO_STATS : - 856 0 : opt.force_stats = 1; - 857 0 : break; + 856 1 : opt.force_stats = 1; + 857 1 : break; 858 : case OPT_TEST_COND_SIGNAL_OUTSIDE : 859 : #if HAVE_PTHREAD 860 0 : thread_cond_signal_outside = 1; @@ -944,8 +944,8 @@ 882 0 : opt.file_mode = ADVISE_DIRECT; 883 0 : break; 884 : case OPT_TEST_PARITY_LIMIT : - 885 267 : opt.parity_limit_size = atoll(optarg); - 886 267 : break; + 885 268 : opt.parity_limit_size = atoll(optarg); + 886 268 : break; 887 : case OPT_TEST_SKIP_CONTENT_WRITE : 888 0 : opt.skip_content_write = 1; 889 0 : break; @@ -974,32 +974,32 @@ 912 : } 913 : } 914 : - 915 269 : os_init(opt.force_scan_winfind); - 916 269 : raid_init(); - 917 269 : crc32c_init(); + 915 270 : os_init(opt.force_scan_winfind); + 916 270 : raid_init(); + 917 270 : crc32c_init(); 918 : - 919 269 : if (speedtest != 0) { + 919 270 : if (speedtest != 0) { 920 4 : speed(period); 921 4 : os_done(); 922 4 : exit(EXIT_SUCCESS); 923 : } 924 : - 925 265 : if (gen_conf != 0) { + 925 266 : if (gen_conf != 0) { 926 1 : generate_configuration(gen_conf); 927 1 : os_done(); 928 1 : exit(EXIT_SUCCESS); 929 : } 930 : - 931 264 : if (optind + 1 != argc) { + 931 265 : if (optind + 1 != argc) { 932 : /* LCOV_EXCL_START */ 933 : usage(); 934 : exit(EXIT_FAILURE); 935 : /* LCOV_EXCL_STOP */ 936 : } 937 : - 938 264 : command = argv[optind]; - 939 264 : if (strcmp(command, "diff") == 0) { - 940 7 : operation = OPERATION_DIFF; + 938 265 : command = argv[optind]; + 939 265 : if (strcmp(command, "diff") == 0) { + 940 8 : operation = OPERATION_DIFF; 941 257 : } else if (strcmp(argv[optind], "sync") == 0) { 942 89 : operation = OPERATION_SYNC; 943 168 : } else if (strcmp(argv[optind], "check") == 0) { @@ -1042,11 +1042,11 @@ 980 : } 981 : 982 : /* check options compatibility */ - 983 264 : switch (operation) { + 983 265 : switch (operation) { 984 : case OPERATION_CHECK : 985 75 : break; 986 : default : - 987 189 : if (opt.auditonly) { + 987 190 : if (opt.auditonly) { 988 : /* LCOV_EXCL_START */ 989 : log_fatal("You cannot use -a, --audit-only with the '%s' command\n", command); 990 : exit(EXIT_FAILURE); @@ -1054,12 +1054,12 @@ 992 : } 993 : } 994 : - 995 264 : switch (operation) { + 995 265 : switch (operation) { 996 : case OPERATION_FIX : 997 : case OPERATION_CHECK : 998 121 : break; 999 : default : - 1000 143 : if (opt.force_device) { + 1000 144 : if (opt.force_device) { 1001 : /* LCOV_EXCL_START */ 1002 : log_fatal("You cannot use -D, --force-device with the '%s' command\n", command); 1003 : exit(EXIT_FAILURE); @@ -1067,13 +1067,13 @@ 1005 : } 1006 : } 1007 : - 1008 264 : switch (operation) { + 1008 265 : switch (operation) { 1009 : case OPERATION_SYNC : 1010 : case OPERATION_CHECK : 1011 : case OPERATION_FIX : 1012 210 : break; 1013 : default : - 1014 54 : if (opt.force_nocopy) { + 1014 55 : if (opt.force_nocopy) { 1015 : /* LCOV_EXCL_START */ 1016 : log_fatal("You cannot use -N, --force-nocopy with the '%s' command\n", command); 1017 : exit(EXIT_FAILURE); @@ -1081,25 +1081,25 @@ 1019 : } 1020 : } 1021 : - 1022 264 : switch (operation) { + 1022 265 : switch (operation) { 1023 : case OPERATION_SYNC : 1024 89 : break; 1025 : default : - 1026 175 : if (opt.prehash) { + 1026 176 : if (opt.prehash) { 1027 : /* LCOV_EXCL_START */ 1028 : log_fatal("You cannot use -h, --pre-hash with the '%s' command\n", command); 1029 : exit(EXIT_FAILURE); 1030 : /* LCOV_EXCL_STOP */ 1031 : } 1032 : - 1033 175 : if (opt.force_full) { + 1033 176 : if (opt.force_full) { 1034 : /* LCOV_EXCL_START */ 1035 : log_fatal("You cannot use -F, --force-full with the '%s' command\n", command); 1036 : exit(EXIT_FAILURE); 1037 : /* LCOV_EXCL_STOP */ 1038 : } 1039 : - 1040 175 : if (opt.force_realloc) { + 1040 176 : if (opt.force_realloc) { 1041 : /* LCOV_EXCL_START */ 1042 : log_fatal("You cannot use -R, --force-realloc with the '%s' command\n", command); 1043 : exit(EXIT_FAILURE); @@ -1107,41 +1107,41 @@ 1045 : } 1046 : } 1047 : - 1048 264 : if (opt.force_full && opt.force_nocopy) { + 1048 265 : if (opt.force_full && opt.force_nocopy) { 1049 : /* LCOV_EXCL_START */ 1050 : log_fatal("You cannot use the -F, --force-full and -N, --force-nocopy options at the same time\n"); 1051 : exit(EXIT_FAILURE); 1052 : /* LCOV_EXCL_STOP */ 1053 : } 1054 : - 1055 264 : if (opt.force_realloc && opt.force_nocopy) { + 1055 265 : if (opt.force_realloc && opt.force_nocopy) { 1056 : /* LCOV_EXCL_START */ 1057 : log_fatal("You cannot use the -R, --force-realloc and -N, --force-nocopy options at the same time\n"); 1058 : exit(EXIT_FAILURE); 1059 : /* LCOV_EXCL_STOP */ 1060 : } 1061 : - 1062 264 : if (opt.force_realloc && opt.force_full) { + 1062 265 : if (opt.force_realloc && opt.force_full) { 1063 : /* LCOV_EXCL_START */ 1064 : log_fatal("You cannot use the -R, --force-realloc and -F, --force-full options at the same time\n"); 1065 : exit(EXIT_FAILURE); 1066 : /* LCOV_EXCL_STOP */ 1067 : } 1068 : - 1069 264 : if (opt.prehash && opt.force_nocopy) { + 1069 265 : if (opt.prehash && opt.force_nocopy) { 1070 : /* LCOV_EXCL_START */ 1071 : log_fatal("You cannot use the -h, --pre-hash and -N, --force-nocopy options at the same time\n"); 1072 : exit(EXIT_FAILURE); 1073 : /* LCOV_EXCL_STOP */ 1074 : } 1075 : - 1076 264 : switch (operation) { + 1076 265 : switch (operation) { 1077 : case OPERATION_CHECK : 1078 : case OPERATION_FIX : 1079 : case OPERATION_DRY : 1080 123 : break; 1081 : default : - 1082 139 : if (!tommy_list_empty(&filterlist_disk)) { + 1082 140 : if (!tommy_list_empty(&filterlist_disk)) { 1083 : /* LCOV_EXCL_START */ 1084 : log_fatal("You cannot use -d, --filter-disk with the '%s' command\n", command); 1085 : exit(EXIT_FAILURE); @@ -1150,19 +1150,19 @@ 1088 : /* follow */ 1089 : case OPERATION_SPINUP : 1090 : case OPERATION_SPINDOWN : - 1091 141 : if (!tommy_list_empty(&filterlist_file)) { + 1091 142 : if (!tommy_list_empty(&filterlist_file)) { 1092 : /* LCOV_EXCL_START */ 1093 : log_fatal("You cannot use -f, --filter with the '%s' command\n", command); 1094 : exit(EXIT_FAILURE); 1095 : /* LCOV_EXCL_STOP */ 1096 : } - 1097 141 : if (filter_missing != 0) { + 1097 142 : if (filter_missing != 0) { 1098 : /* LCOV_EXCL_START */ 1099 : log_fatal("You cannot use -m, --filter-missing with the '%s' command\n", command); 1100 : exit(EXIT_FAILURE); 1101 : /* LCOV_EXCL_STOP */ 1102 : } - 1103 141 : if (filter_error != 0) { + 1103 142 : if (filter_error != 0) { 1104 : /* LCOV_EXCL_START */ 1105 : log_fatal("You cannot use -e, --filter-error with the '%s' command\n", command); 1106 : exit(EXIT_FAILURE); @@ -1172,19 +1172,19 @@ 1110 : 1111 : /* errors must be always fixed on all disks */ 1112 : /* because we don't keep the information on what disk is the error */ - 1113 264 : if (filter_error != 0 && !tommy_list_empty(&filterlist_disk)) { + 1113 265 : if (filter_error != 0 && !tommy_list_empty(&filterlist_disk)) { 1114 : /* LCOV_EXCL_START */ 1115 : log_fatal("You cannot use -e, --filter-error and -d, --filter-disk at the same time\n"); 1116 : exit(EXIT_FAILURE); 1117 : /* LCOV_EXCL_STOP */ 1118 : } 1119 : - 1120 264 : switch (operation) { + 1120 265 : switch (operation) { 1121 : case OPERATION_CHECK : 1122 : case OPERATION_FIX : 1123 121 : break; 1124 : default : - 1125 143 : if (import_timestamp != 0 || import_content != 0) { + 1125 144 : if (import_timestamp != 0 || import_content != 0) { 1126 : /* LCOV_EXCL_START */ 1127 : log_fatal("You cannot import with the '%s' command\n", command); 1128 : exit(EXIT_FAILURE); @@ -1192,7 +1192,7 @@ 1130 : } 1131 : } 1132 : - 1133 264 : switch (operation) { + 1133 265 : switch (operation) { 1134 : case OPERATION_LIST : 1135 : case OPERATION_DUP : 1136 : case OPERATION_STATUS : @@ -1205,7 +1205,7 @@ 1143 26 : break; 1144 : } 1145 : - 1146 264 : switch (operation) { + 1146 265 : switch (operation) { 1147 : case OPERATION_DIFF : 1148 : case OPERATION_LIST : 1149 : case OPERATION_DUP : @@ -1217,11 +1217,11 @@ 1155 : case OPERATION_TOUCH : 1156 : case OPERATION_SPINUP : /* we want to do it in different threads to avoid blocking */ 1157 : /* avoid to check and access parity disks if not needed */ - 1158 37 : opt.skip_parity_access = 1; - 1159 37 : break; + 1158 38 : opt.skip_parity_access = 1; + 1159 38 : break; 1160 : } 1161 : - 1162 264 : switch (operation) { + 1162 265 : switch (operation) { 1163 : case OPERATION_FIX : 1164 : case OPERATION_CHECK : 1165 : /* avoid to stop processing if a content file is not accessible */ @@ -1229,7 +1229,7 @@ 1167 121 : break; 1168 : } 1169 : - 1170 264 : switch (operation) { + 1170 265 : switch (operation) { 1171 : case OPERATION_DIFF : 1172 : case OPERATION_LIST : 1173 : case OPERATION_DUP : @@ -1239,11 +1239,11 @@ 1177 : case OPERATION_SPINDOWN : 1178 : case OPERATION_DEVICES : 1179 : case OPERATION_SMART : - 1180 24 : opt.skip_self = 1; - 1181 24 : break; + 1180 25 : opt.skip_self = 1; + 1181 25 : break; 1182 : } 1183 : - 1184 264 : switch (operation) { + 1184 265 : switch (operation) { 1185 : #if HAVE_DIRECT_IO 1186 : case OPERATION_SYNC : 1187 : case OPERATION_SCRUB : @@ -1252,12 +1252,12 @@ 1190 : #endif 1191 : default: 1192 : /* we allow direct IO only on some commands */ - 1193 162 : if (opt.file_mode == ADVISE_DIRECT) + 1193 163 : if (opt.file_mode == ADVISE_DIRECT) 1194 0 : opt.file_mode = ADVISE_SEQUENTIAL; - 1195 162 : break; + 1195 163 : break; 1196 : } 1197 : - 1198 264 : switch (operation) { + 1198 265 : switch (operation) { 1199 : case OPERATION_DEVICES : 1200 : case OPERATION_SMART : 1201 : /* we may need to use these commands during operations */ @@ -1265,7 +1265,7 @@ 1203 3 : break; 1204 : } 1205 : - 1206 264 : switch (operation) { + 1206 265 : switch (operation) { 1207 : case OPERATION_SMART : 1208 : /* allow to run without configuration file */ 1209 2 : opt.auto_conf = 1; @@ -1273,39 +1273,39 @@ 1211 : } 1212 : 1213 : /* open the log file */ - 1214 264 : log_open(log_file); + 1214 265 : log_open(log_file); 1215 : 1216 : /* print generic info into the log */ - 1217 264 : t = time(0); - 1218 264 : tm = localtime(&t); - 1219 264 : log_tag("version:%s\n", PACKAGE_VERSION); - 1220 264 : log_tag("unixtime:%" PRIi64 "\n", (int64_t)t); - 1221 264 : if (tm) { + 1217 265 : t = time(0); + 1218 265 : tm = localtime(&t); + 1219 265 : log_tag("version:%s\n", PACKAGE_VERSION); + 1220 265 : log_tag("unixtime:%" PRIi64 "\n", (int64_t)t); + 1221 265 : if (tm) { 1222 : char datetime[64]; - 1223 264 : strftime(datetime, sizeof(datetime), "%Y-%m-%d %H:%M:%S", tm); - 1224 264 : log_tag("time:%s\n", datetime); + 1223 265 : strftime(datetime, sizeof(datetime), "%Y-%m-%d %H:%M:%S", tm); + 1224 265 : log_tag("time:%s\n", datetime); 1225 : } - 1226 264 : log_tag("command:%s\n", command); - 1227 4037 : for (i = 0; i < argc; ++i) - 1228 3773 : log_tag("argv:%u:%s\n", i, argv[i]); - 1229 264 : log_flush(); + 1226 265 : log_tag("command:%s\n", command); + 1227 4052 : for (i = 0; i < argc; ++i) + 1228 3787 : log_tag("argv:%u:%s\n", i, argv[i]); + 1229 265 : log_flush(); 1230 : - 1231 264 : if (!opt.skip_self) + 1231 265 : if (!opt.skip_self) 1232 1 : selftest(); 1233 : - 1234 264 : state_init(&state); + 1234 265 : state_init(&state); 1235 : 1236 : /* read the configuration file */ - 1237 264 : state_config(&state, conf, command, &opt, &filterlist_disk); + 1237 265 : state_config(&state, conf, command, &opt, &filterlist_disk); 1238 : 1239 : /* set the raid mode */ - 1240 263 : raid_mode(state.raid_mode); + 1240 264 : raid_mode(state.raid_mode); 1241 : 1242 : #if HAVE_LOCKFILE 1243 : /* create the lock file */ - 1244 263 : if (!opt.skip_lock && state.lockfile[0]) { - 1245 260 : lock = lock_lock(state.lockfile); - 1246 260 : if (lock == -1) { + 1244 264 : if (!opt.skip_lock && state.lockfile[0]) { + 1245 261 : lock = lock_lock(state.lockfile); + 1246 261 : if (lock == -1) { 1247 : /* LCOV_EXCL_START */ 1248 : if (errno != EWOULDBLOCK) { 1249 : log_fatal("Error creating the lock file '%s'. %s.\n", state.lockfile, strerror(errno)); @@ -1321,14 +1321,14 @@ 1259 : (void)lock; 1260 : #endif 1261 : - 1262 263 : if (operation == OPERATION_DIFF) { - 1263 7 : state_read(&state); + 1262 264 : if (operation == OPERATION_DIFF) { + 1263 8 : state_read(&state); 1264 : - 1265 7 : ret = state_diff(&state); + 1265 8 : ret = state_diff(&state); 1266 : 1267 : /* abort if sync needed */ - 1268 7 : if (ret > 0) - 1269 6 : exit(EXIT_SYNC_NEEDED); + 1268 8 : if (ret > 0) + 1269 7 : exit(EXIT_SYNC_NEEDED); 1270 256 : } else if (operation == OPERATION_SYNC) { 1271 : 1272 : /* in the next state read ensures to clear all the past hashes in case */ diff --git a/cov/cmdline/speed.c.func-sort-c.html b/cov/cmdline/speed.c.func-sort-c.html index cf9aeb8c..e9db88b7 100644 --- a/cov/cmdline/speed.c.func-sort-c.html +++ b/cov/cmdline/speed.c.func-sort-c.html @@ -61,7 +61,7 @@ diffgettimeofday - 1840 + 1834 speed diff --git a/cov/cmdline/speed.c.func.html b/cov/cmdline/speed.c.func.html index 5fd0a53c..dc809ae1 100644 --- a/cov/cmdline/speed.c.func.html +++ b/cov/cmdline/speed.c.func.html @@ -61,7 +61,7 @@ diffgettimeofday - 1840 + 1834 speed diff --git a/cov/cmdline/speed.c.gcov.html b/cov/cmdline/speed.c.gcov.html index 53e5330e..e039e006 100644 --- a/cov/cmdline/speed.c.gcov.html +++ b/cov/cmdline/speed.c.gcov.html @@ -100,14 +100,14 @@ 38 : /** 39 : * Differential us of two timeval. 40 : */ - 41 1840 : static int64_t diffgettimeofday(struct timeval *start, struct timeval *stop) + 41 1834 : static int64_t diffgettimeofday(struct timeval *start, struct timeval *stop) 42 : { 43 : int64_t d; 44 : - 45 1840 : d = 1000000LL * (stop->tv_sec - start->tv_sec); - 46 1840 : d += stop->tv_usec - start->tv_usec; + 45 1834 : d = 1000000LL * (stop->tv_sec - start->tv_sec); + 46 1834 : d += stop->tv_usec - start->tv_usec; 47 : - 48 1840 : return d; + 48 1834 : return d; 49 : } 50 : 51 : /** @@ -232,10 +232,10 @@ 170 4 : printf("%8s", "memset"); 171 4 : fflush(stdout); 172 : - 173 380 : SPEED_START { - 174 3384 : for (j = 0; j < nd; ++j) - 175 3008 : memset(v[j], j, size); - 176 376 : } SPEED_STOP + 173 386 : SPEED_START { + 174 3438 : for (j = 0; j < nd; ++j) + 175 3056 : memset(v[j], j, size); + 176 382 : } SPEED_STOP 177 : 178 4 : printf("%8" PRIu64, ds / dt); 179 4 : printf("\n"); @@ -247,10 +247,10 @@ 185 4 : printf("%8s", "table"); 186 4 : fflush(stdout); 187 : - 188 47 : SPEED_START { - 189 387 : for (j = 0; j < nd; ++j) - 190 344 : side_effect += crc32c_gen(0, v[j], size); - 191 43 : } SPEED_STOP + 188 45 : SPEED_START { + 189 369 : for (j = 0; j < nd; ++j) + 190 328 : side_effect += crc32c_gen(0, v[j], size); + 191 41 : } SPEED_STOP 192 : 193 4 : printf("%8" PRIu64, ds / dt); 194 4 : printf("\n"); @@ -260,10 +260,10 @@ 198 : 199 : #if HAVE_SSE42 200 4 : if (raid_cpu_has_crc32()) { - 201 60 : SPEED_START { - 202 522 : for (j = 0; j < nd; ++j) - 203 464 : side_effect += crc32c_x86(0, v[j], size); - 204 58 : } SPEED_STOP + 201 59 : SPEED_START { + 202 513 : for (j = 0; j < nd; ++j) + 203 456 : side_effect += crc32c_x86(0, v[j], size); + 204 57 : } SPEED_STOP 205 : 206 2 : printf("%8" PRIu64, ds / dt); 207 : } @@ -341,16 +341,16 @@ 279 : 280 4 : printf("%8s", ""); 281 : - 282 113 : SPEED_START { - 283 109 : raid_gen1_int32(nd, size, v); - 284 109 : } SPEED_STOP + 282 118 : SPEED_START { + 283 114 : raid_gen1_int32(nd, size, v); + 284 114 : } SPEED_STOP 285 : 286 4 : printf("%8" PRIu64, ds / dt); 287 4 : fflush(stdout); 288 : - 289 185 : SPEED_START { - 290 181 : raid_gen1_int64(nd, size, v); - 291 181 : } SPEED_STOP + 289 183 : SPEED_START { + 290 179 : raid_gen1_int64(nd, size, v); + 291 179 : } SPEED_STOP 292 : 293 4 : printf("%8" PRIu64, ds / dt); 294 4 : fflush(stdout); @@ -358,9 +358,9 @@ 296 : #ifdef CONFIG_X86 297 : #ifdef CONFIG_SSE2 298 4 : if (raid_cpu_has_sse2()) { - 299 303 : SPEED_START { - 300 299 : raid_gen1_sse2(nd, size, v); - 301 299 : } SPEED_STOP + 299 304 : SPEED_START { + 300 300 : raid_gen1_sse2(nd, size, v); + 301 300 : } SPEED_STOP 302 : 303 4 : printf("%8" PRIu64, ds / dt); 304 4 : fflush(stdout); @@ -401,9 +401,9 @@ 339 4 : printf("%8" PRIu64, ds / dt); 340 4 : fflush(stdout); 341 : - 342 48 : SPEED_START { - 343 44 : raid_gen2_int64(nd, size, v); - 344 44 : } SPEED_STOP + 342 46 : SPEED_START { + 343 42 : raid_gen2_int64(nd, size, v); + 344 42 : } SPEED_STOP 345 : 346 4 : printf("%8" PRIu64, ds / dt); 347 4 : fflush(stdout); @@ -411,9 +411,9 @@ 349 : #ifdef CONFIG_X86 350 : #ifdef CONFIG_SSE2 351 4 : if (raid_cpu_has_sse2()) { - 352 144 : SPEED_START { - 353 140 : raid_gen2_sse2(nd, size, v); - 354 140 : } SPEED_STOP + 352 141 : SPEED_START { + 353 137 : raid_gen2_sse2(nd, size, v); + 354 137 : } SPEED_STOP 355 : 356 4 : printf("%8" PRIu64, ds / dt); 357 4 : fflush(stdout); @@ -453,9 +453,9 @@ 391 : 392 4 : printf("%8s", ""); 393 : - 394 32 : SPEED_START { - 395 28 : raid_genz_int32(nd, size, v); - 396 28 : } SPEED_STOP + 394 31 : SPEED_START { + 395 27 : raid_genz_int32(nd, size, v); + 396 27 : } SPEED_STOP 397 : 398 4 : printf("%8" PRIu64, ds / dt); 399 4 : fflush(stdout); @@ -470,9 +470,9 @@ 408 : #ifdef CONFIG_X86 409 : #ifdef CONFIG_SSE2 410 4 : if (raid_cpu_has_sse2()) { - 411 86 : SPEED_START { - 412 82 : raid_genz_sse2(nd, size, v); - 413 82 : } SPEED_STOP + 411 85 : SPEED_START { + 412 81 : raid_genz_sse2(nd, size, v); + 413 81 : } SPEED_STOP 414 : 415 4 : printf("%8" PRIu64, ds / dt); 416 4 : fflush(stdout); @@ -537,9 +537,9 @@ 475 : #ifdef CONFIG_X86 476 : #ifdef CONFIG_SSSE3 477 4 : if (raid_cpu_has_ssse3()) { - 478 53 : SPEED_START { - 479 50 : raid_gen3_ssse3(nd, size, v); - 480 50 : } SPEED_STOP + 478 52 : SPEED_START { + 479 49 : raid_gen3_ssse3(nd, size, v); + 480 49 : } SPEED_STOP 481 : 482 3 : printf("%8" PRIu64, ds / dt); 483 3 : fflush(stdout); @@ -602,9 +602,9 @@ 540 : #ifdef CONFIG_X86 541 : #ifdef CONFIG_SSSE3 542 4 : if (raid_cpu_has_ssse3()) { - 543 36 : SPEED_START { - 544 33 : raid_gen4_ssse3(nd, size, v); - 545 33 : } SPEED_STOP + 543 35 : SPEED_START { + 544 32 : raid_gen4_ssse3(nd, size, v); + 545 32 : } SPEED_STOP 546 : 547 3 : printf("%8" PRIu64, ds / dt); 548 3 : fflush(stdout); @@ -642,9 +642,9 @@ 580 4 : printf("%8s", raid_gen5_tag()); 581 4 : fflush(stdout); 582 : - 583 12 : SPEED_START { - 584 8 : raid_gen5_int8(nd, size, v); - 585 8 : } SPEED_STOP + 583 11 : SPEED_START { + 584 7 : raid_gen5_int8(nd, size, v); + 585 7 : } SPEED_STOP 586 : 587 4 : printf("%8" PRIu64, ds / dt); 588 4 : fflush(stdout); @@ -667,9 +667,9 @@ 605 : #ifdef CONFIG_X86 606 : #ifdef CONFIG_SSSE3 607 4 : if (raid_cpu_has_ssse3()) { - 608 25 : SPEED_START { - 609 22 : raid_gen5_ssse3(nd, size, v); - 610 22 : } SPEED_STOP + 608 24 : SPEED_START { + 609 21 : raid_gen5_ssse3(nd, size, v); + 610 21 : } SPEED_STOP 611 : 612 3 : printf("%8" PRIu64, ds / dt); 613 3 : fflush(stdout); @@ -707,9 +707,9 @@ 645 4 : printf("%8s", raid_gen6_tag()); 646 4 : fflush(stdout); 647 : - 648 11 : SPEED_START { - 649 7 : raid_gen6_int8(nd, size, v); - 650 7 : } SPEED_STOP + 648 9 : SPEED_START { + 649 5 : raid_gen6_int8(nd, size, v); + 650 5 : } SPEED_STOP 651 : 652 4 : printf("%8" PRIu64, ds / dt); 653 4 : fflush(stdout); diff --git a/cov/cmdline/spooky2.c.func-sort-c.html b/cov/cmdline/spooky2.c.func-sort-c.html index 6c0e404b..41e92e89 100644 --- a/cov/cmdline/spooky2.c.func-sort-c.html +++ b/cov/cmdline/spooky2.c.func-sort-c.html @@ -61,7 +61,7 @@ SpookyHash128 - 3860981 + 3861869
diff --git a/cov/cmdline/spooky2.c.func.html b/cov/cmdline/spooky2.c.func.html index 3324da70..09b225e7 100644 --- a/cov/cmdline/spooky2.c.func.html +++ b/cov/cmdline/spooky2.c.func.html @@ -61,7 +61,7 @@ SpookyHash128 - 3860981 + 3861869
diff --git a/cov/cmdline/spooky2.c.gcov.html b/cov/cmdline/spooky2.c.gcov.html index 4af0687c..6fe692aa 100644 --- a/cov/cmdline/spooky2.c.gcov.html +++ b/cov/cmdline/spooky2.c.gcov.html @@ -170,7 +170,7 @@ 108 : // 109 : #define sc_const 0xdeadbeefdeadbeefLL 110 : - 111 3860981 : void SpookyHash128(const void* data, size_t size, const uint8_t* seed, uint8_t* digest) + 111 3861869 : void SpookyHash128(const void* data, size_t size, const uint8_t* seed, uint8_t* digest) 112 : { 113 : uint64_t h0, h1, h2, h3, h4, h5, h6, h7, h8, h9, h10, h11; 114 : uint64_t buf[sc_numVars]; @@ -183,39 +183,39 @@ 121 : unsigned i; 122 : #endif 123 : - 124 3860981 : h9 = ((const uint64_t*)seed)[0]; - 125 3860981 : h10 = ((const uint64_t*)seed)[1]; + 124 3861869 : h9 = ((const uint64_t*)seed)[0]; + 125 3861869 : h10 = ((const uint64_t*)seed)[1]; 126 : 127 : #if WORDS_BIGENDIAN 128 : h9 = util_swap64(h9); 129 : h10 = util_swap64(h10); 130 : #endif 131 : - 132 3860981 : h0 = h3 = h6 = h9; - 133 3860981 : h1 = h4 = h7 = h10; - 134 3860981 : h2 = h5 = h8 = h11 = sc_const; + 132 3861869 : h0 = h3 = h6 = h9; + 133 3861869 : h1 = h4 = h7 = h10; + 134 3861869 : h2 = h5 = h8 = h11 = sc_const; 135 : - 136 3860981 : nblocks = size / sc_blockSize; - 137 3860981 : blocks = data; - 138 3860981 : end = blocks + nblocks * sc_numVars; + 136 3861869 : nblocks = size / sc_blockSize; + 137 3861869 : blocks = data; + 138 3861869 : end = blocks + nblocks * sc_numVars; 139 : 140 : /* body */ - 141 38823778 : while (blocks < end) { + 141 38833261 : while (blocks < end) { 142 : #if WORDS_BIGENDIAN 143 : for (i = 0; i < sc_numVars; ++i) 144 : buf[i] = util_swap64(blocks[i]); 145 : Mix(buf, h0, h1, h2, h3, h4, h5, h6, h7, h8, h9, h10, h11); 146 : #else - 147 31101816 : Mix(blocks, h0, h1, h2, h3, h4, h5, h6, h7, h8, h9, h10, h11); + 147 31109523 : Mix(blocks, h0, h1, h2, h3, h4, h5, h6, h7, h8, h9, h10, h11); 148 : #endif - 149 31101816 : blocks += sc_numVars; + 149 31109523 : blocks += sc_numVars; 150 : } 151 : 152 : /* tail */ - 153 3860981 : size_remainder = (size - ((const uint8_t*)end - (const uint8_t*)data)); - 154 3860981 : memcpy(buf, end, size_remainder); - 155 3860981 : memset(((uint8_t*)buf) + size_remainder, 0, sc_blockSize - size_remainder); - 156 3860981 : ((uint8_t*)buf)[sc_blockSize - 1] = size_remainder; + 153 3861869 : size_remainder = (size - ((const uint8_t*)end - (const uint8_t*)data)); + 154 3861869 : memcpy(buf, end, size_remainder); + 155 3861869 : memset(((uint8_t*)buf) + size_remainder, 0, sc_blockSize - size_remainder); + 156 3861869 : ((uint8_t*)buf)[sc_blockSize - 1] = size_remainder; 157 : 158 : /* finalization */ 159 : #if WORDS_BIGENDIAN @@ -223,16 +223,16 @@ 161 : buf[i] = util_swap64(buf[i]); 162 : #endif 163 : - 164 3860981 : End(buf, h0, h1, h2, h3, h4, h5, h6, h7, h8, h9, h10, h11); + 164 3861869 : End(buf, h0, h1, h2, h3, h4, h5, h6, h7, h8, h9, h10, h11); 165 : 166 : #if WORDS_BIGENDIAN 167 : h0 = util_swap64(h0); 168 : h1 = util_swap64(h1); 169 : #endif 170 : - 171 3860981 : ((uint64_t*)digest)[0] = h0; - 172 3860981 : ((uint64_t*)digest)[1] = h1; - 173 3860981 : } + 171 3861869 : ((uint64_t*)digest)[0] = h0; + 172 3861869 : ((uint64_t*)digest)[1] = h1; + 173 3861869 : } 174 : diff --git a/cov/cmdline/state.c.func-sort-c.html b/cov/cmdline/state.c.func-sort-c.html index 69b487d1..a21de965 100644 --- a/cov/cmdline/state.c.func-sort-c.html +++ b/cov/cmdline/state.c.func-sort-c.html @@ -65,27 +65,27 @@ fs_info_is_required - 1547811 + 1547867 state_progress - 1073409 + 1073497 state_usage_misc - 1063055 + 1063671 state_usage_disk - 912357 + 912885 state_usage_hash - 776808 + 777357 state_usage_parity - 774023 + 774551 fs_position_is_required @@ -93,23 +93,23 @@ lev_config_name - 186548 + 186570 state_usage_sched - 149836 + 149924 state_usage_raid - 140365 + 140438 find_disk_by_name - 7021 + 7037 lev_config_scan - 6301 + 6318 state_verify_thread @@ -117,11 +117,11 @@ state_fscheck - 496 + 498 state_progress_latest - 495 + 477 validate_smartctl @@ -129,35 +129,35 @@ state_init - 265 + 266 state_config - 264 + 265 lev_raid_name - 263 + 264 state_config_check - 263 + 264 state_read - 259 + 260 state_map - 258 + 259 state_read_content - 252 + 253 state_content_check - 251 + 252 state_done diff --git a/cov/cmdline/state.c.func.html b/cov/cmdline/state.c.func.html index 4ee01dd6..e633e134 100644 --- a/cov/cmdline/state.c.func.html +++ b/cov/cmdline/state.c.func.html @@ -65,7 +65,7 @@ find_disk_by_name - 7021 + 7037 find_disk_by_uuid @@ -73,7 +73,7 @@ fs_info_is_required - 1547811 + 1547867 fs_is_block_deleted @@ -93,11 +93,11 @@ lev_config_name - 186548 + 186570 lev_config_scan - 6301 + 6318 lev_name @@ -105,19 +105,19 @@ lev_raid_name - 263 - - - state_config 264 + + state_config + 265 + state_config_check - 263 + 264 state_content_check - 251 + 252 state_done @@ -129,19 +129,19 @@ state_fscheck - 496 + 498 state_init - 265 + 266 state_map - 258 + 259 state_progress - 1073409 + 1073497 state_progress_begin @@ -157,7 +157,7 @@ state_progress_latest - 495 + 477 state_progress_restart @@ -169,11 +169,11 @@ state_read - 259 + 260 state_read_content - 252 + 253 state_refresh @@ -189,19 +189,19 @@ state_usage_disk - 912357 + 912885 state_usage_hash - 776808 + 777357 state_usage_misc - 1063055 + 1063671 state_usage_parity - 774023 + 774551 state_usage_print @@ -209,11 +209,11 @@ state_usage_raid - 140365 + 140438 state_usage_sched - 149836 + 149924 state_usage_waste diff --git a/cov/cmdline/state.c.gcov.html b/cov/cmdline/state.c.gcov.html index c9beeecb..b088ec7a 100644 --- a/cov/cmdline/state.c.gcov.html +++ b/cov/cmdline/state.c.gcov.html @@ -125,10 +125,10 @@ 63 0 : return 0; 64 : } 65 : - 66 186548 : const char* lev_config_name(unsigned l) + 66 186570 : const char* lev_config_name(unsigned l) 67 : { - 68 186548 : switch (l) { - 69 86846 : case 0 : return "parity"; + 68 186570 : switch (l) { + 69 86868 : case 0 : return "parity"; 70 60620 : case 1 : return "2-parity"; 71 9810 : case 2 : return "3-parity"; 72 9785 : case 3 : return "4-parity"; @@ -139,52 +139,52 @@ 77 0 : return 0; 78 : } 79 : - 80 6301 : static int lev_config_scan(const char* s, unsigned* level, unsigned* mode) + 80 6318 : static int lev_config_scan(const char* s, unsigned* level, unsigned* mode) 81 : { - 82 6301 : if (strcmp(s, "parity") == 0 || strcmp(s, "1-parity") == 0) { - 83 446 : *level = 0; - 84 446 : return 0; + 82 6318 : if (strcmp(s, "parity") == 0 || strcmp(s, "1-parity") == 0) { + 83 447 : *level = 0; + 84 447 : return 0; 85 : } 86 : - 87 5855 : if (strcmp(s, "q-parity") == 0 || strcmp(s, "2-parity") == 0) { + 87 5871 : if (strcmp(s, "q-parity") == 0 || strcmp(s, "2-parity") == 0) { 88 224 : *level = 1; 89 224 : return 0; 90 : } 91 : - 92 5631 : if (strcmp(s, "r-parity") == 0 || strcmp(s, "3-parity") == 0) { + 92 5647 : if (strcmp(s, "r-parity") == 0 || strcmp(s, "3-parity") == 0) { 93 199 : *level = 2; 94 199 : return 0; 95 : } 96 : - 97 5432 : if (strcmp(s, "4-parity") == 0) { + 97 5448 : if (strcmp(s, "4-parity") == 0) { 98 196 : *level = 3; 99 196 : return 0; 100 : } 101 : - 102 5236 : if (strcmp(s, "5-parity") == 0) { + 102 5252 : if (strcmp(s, "5-parity") == 0) { 103 193 : *level = 4; 104 193 : return 0; 105 : } 106 : - 107 5043 : if (strcmp(s, "6-parity") == 0) { + 107 5059 : if (strcmp(s, "6-parity") == 0) { 108 189 : *level = 5; 109 189 : return 0; 110 : } 111 : - 112 4854 : if (strcmp(s, "z-parity") == 0) { + 112 4870 : if (strcmp(s, "z-parity") == 0) { 113 0 : *level = 2; 114 0 : if (mode) 115 0 : *mode = RAID_MODE_VANDERMONDE; 116 0 : return 0; 117 : } 118 : - 119 4854 : return -1; + 119 4870 : return -1; 120 : } 121 : - 122 263 : const char* lev_raid_name(unsigned mode, unsigned n) + 122 264 : const char* lev_raid_name(unsigned mode, unsigned n) 123 : { - 124 263 : switch (n) { - 125 40 : case 1 : return "par1"; + 124 264 : switch (n) { + 125 41 : case 1 : return "par1"; 126 25 : case 2 : return "par2"; 127 3 : case 3 : if (mode == RAID_MODE_CAUCHY) 128 3 : return "par3"; @@ -198,58 +198,58 @@ 136 0 : return 0; 137 : } 138 : - 139 265 : void state_init(struct snapraid_state* state) + 139 266 : void state_init(struct snapraid_state* state) 140 : { 141 : unsigned l, s; 142 : - 143 265 : memset(&state->opt, 0, sizeof(state->opt)); - 144 265 : state->filter_hidden = 0; - 145 265 : state->autosave = 0; - 146 265 : state->need_write = 0; - 147 265 : state->checked_read = 0; - 148 265 : state->block_size = 256 * KIBI; /* default 256 KiB */ - 149 265 : state->raid_mode = RAID_MODE_CAUCHY; - 150 265 : state->file_mode = ADVISE_DEFAULT; - 151 1855 : for (l = 0; l < LEV_MAX; ++l) { - 152 1590 : state->parity[l].split_mac = 0; - 153 14310 : for (s = 0; s < SPLIT_MAX; ++s) { - 154 12720 : state->parity[l].split_map[s].path[0] = 0; - 155 12720 : state->parity[l].split_map[s].uuid[0] = 0; - 156 12720 : state->parity[l].split_map[s].size = PARITY_SIZE_INVALID; - 157 12720 : state->parity[l].split_map[s].device = 0; + 143 266 : memset(&state->opt, 0, sizeof(state->opt)); + 144 266 : state->filter_hidden = 0; + 145 266 : state->autosave = 0; + 146 266 : state->need_write = 0; + 147 266 : state->checked_read = 0; + 148 266 : state->block_size = 256 * KIBI; /* default 256 KiB */ + 149 266 : state->raid_mode = RAID_MODE_CAUCHY; + 150 266 : state->file_mode = ADVISE_DEFAULT; + 151 1862 : for (l = 0; l < LEV_MAX; ++l) { + 152 1596 : state->parity[l].split_mac = 0; + 153 14364 : for (s = 0; s < SPLIT_MAX; ++s) { + 154 12768 : state->parity[l].split_map[s].path[0] = 0; + 155 12768 : state->parity[l].split_map[s].uuid[0] = 0; + 156 12768 : state->parity[l].split_map[s].size = PARITY_SIZE_INVALID; + 157 12768 : state->parity[l].split_map[s].device = 0; 158 : } - 159 1590 : state->parity[l].smartctl[0] = 0; - 160 1590 : state->parity[l].total_blocks = 0; - 161 1590 : state->parity[l].free_blocks = 0; - 162 1590 : state->parity[l].skip_access = 0; - 163 1590 : state->parity[l].tick = 0; - 164 1590 : state->parity[l].cached = 0; - 165 1590 : state->parity[l].is_excluded = 0; + 159 1596 : state->parity[l].smartctl[0] = 0; + 160 1596 : state->parity[l].total_blocks = 0; + 161 1596 : state->parity[l].free_blocks = 0; + 162 1596 : state->parity[l].skip_access = 0; + 163 1596 : state->parity[l].tick = 0; + 164 1596 : state->parity[l].cached = 0; + 165 1596 : state->parity[l].is_excluded = 0; 166 : } - 167 265 : state->tick_io = 0; - 168 265 : state->tick_misc = 0; - 169 265 : state->tick_sched = 0; - 170 265 : state->tick_raid = 0; - 171 265 : state->tick_hash = 0; - 172 265 : state->tick_last = tick(); - 173 265 : state->share[0] = 0; - 174 265 : state->pool[0] = 0; - 175 265 : state->pool_device = 0; - 176 265 : state->lockfile[0] = 0; - 177 265 : state->level = 1; /* default is the lowest protection */ - 178 265 : state->clear_past_hash = 0; - 179 265 : state->no_conf = 0; + 167 266 : state->tick_io = 0; + 168 266 : state->tick_misc = 0; + 169 266 : state->tick_sched = 0; + 170 266 : state->tick_raid = 0; + 171 266 : state->tick_hash = 0; + 172 266 : state->tick_last = tick(); + 173 266 : state->share[0] = 0; + 174 266 : state->pool[0] = 0; + 175 266 : state->pool_device = 0; + 176 266 : state->lockfile[0] = 0; + 177 266 : state->level = 1; /* default is the lowest protection */ + 178 266 : state->clear_past_hash = 0; + 179 266 : state->no_conf = 0; 180 : - 181 265 : tommy_list_init(&state->disklist); - 182 265 : tommy_list_init(&state->maplist); - 183 265 : tommy_list_init(&state->contentlist); - 184 265 : tommy_list_init(&state->filterlist); - 185 265 : tommy_list_init(&state->importlist); - 186 265 : tommy_hashdyn_init(&state->importset); - 187 265 : tommy_hashdyn_init(&state->previmportset); - 188 265 : tommy_hashdyn_init(&state->searchset); - 189 265 : tommy_arrayblkof_init(&state->infoarr, sizeof(snapraid_info)); - 190 265 : } + 181 266 : tommy_list_init(&state->disklist); + 182 266 : tommy_list_init(&state->maplist); + 183 266 : tommy_list_init(&state->contentlist); + 184 266 : tommy_list_init(&state->filterlist); + 185 266 : tommy_list_init(&state->importlist); + 186 266 : tommy_hashdyn_init(&state->importset); + 187 266 : tommy_hashdyn_init(&state->previmportset); + 188 266 : tommy_hashdyn_init(&state->searchset); + 189 266 : tommy_arrayblkof_init(&state->infoarr, sizeof(snapraid_info)); + 190 266 : } 191 : 192 243 : void state_done(struct snapraid_state* state) 193 : { @@ -268,13 +268,13 @@ 206 : /** 207 : * Check the configuration. 208 : */ - 209 263 : static void state_config_check(struct snapraid_state* state, const char* path, tommy_list* filterlist_disk) + 209 264 : static void state_config_check(struct snapraid_state* state, const char* path, tommy_list* filterlist_disk) 210 : { 211 : tommy_node* i; 212 : unsigned l, s; 213 : 214 : /* check for parity level */ - 215 263 : if (state->raid_mode == RAID_MODE_VANDERMONDE) { + 215 264 : if (state->raid_mode == RAID_MODE_VANDERMONDE) { 216 0 : if (state->level > 3) { 217 : /* LCOV_EXCL_START */ 218 : log_fatal("If you use the z-parity you cannot have more than 3 parities.\n"); @@ -292,7 +292,7 @@ 230 : } 231 : } 232 : - 233 263 : if (tommy_list_empty(&state->contentlist)) { + 233 264 : if (tommy_list_empty(&state->contentlist)) { 234 : /* LCOV_EXCL_START */ 235 : log_fatal("No 'content' specification in '%s'\n", path); 236 : exit(EXIT_FAILURE); @@ -300,12 +300,12 @@ 238 : } 239 : 240 : /* check for equal paths */ - 241 1785 : for (i = state->contentlist; i != 0; i = i->next) { - 242 1522 : struct snapraid_content* content = i->data; + 241 1788 : for (i = state->contentlist; i != 0; i = i->next) { + 242 1524 : struct snapraid_content* content = i->data; 243 : - 244 9864 : for (l = 0; l < state->level; ++l) { - 245 41710 : for (s = 0; s < state->parity[l].split_mac; ++s) { - 246 33368 : if (pathcmp(state->parity[l].split_map[s].path, content->content) == 0) { + 244 9868 : for (l = 0; l < state->level; ++l) { + 245 41720 : for (s = 0; s < state->parity[l].split_mac; ++s) { + 246 33376 : if (pathcmp(state->parity[l].split_map[s].path, content->content) == 0) { 247 : /* LCOV_EXCL_START */ 248 : log_fatal("Same path used for '%s' and 'content' as '%s'\n", lev_config_name(l), content->content); 249 : exit(EXIT_FAILURE); @@ -316,7 +316,7 @@ 254 : } 255 : 256 : /* check device of data disks */ - 257 263 : if (!state->opt.skip_device && !state->opt.skip_disk_access) { + 257 264 : if (!state->opt.skip_device && !state->opt.skip_disk_access) { 258 0 : for (i = state->disklist; i != 0; i = i->next) { 259 : tommy_node* j; 260 0 : struct snapraid_disk* disk = i->data; @@ -401,7 +401,7 @@ 339 : } 340 : 341 : /* check device of parity disks */ - 342 263 : if (!state->opt.skip_device && !state->opt.skip_parity_access) { + 342 264 : if (!state->opt.skip_device && !state->opt.skip_parity_access) { 343 0 : for (l = 0; l < state->level; ++l) { 344 0 : for (s = 0; s < state->parity[l].split_mac; ++s) { 345 : unsigned j,t; @@ -481,7 +481,7 @@ 419 : #endif 420 : 421 : /* count the content files */ - 422 263 : if (!state->opt.skip_device && !state->opt.skip_content_access) { + 422 264 : if (!state->opt.skip_device && !state->opt.skip_content_access) { 423 : unsigned content_count; 424 : 425 0 : content_count = 0; @@ -514,7 +514,7 @@ 452 : 453 : /* check for speed */ 454 : #ifdef CONFIG_X86 - 455 263 : if (!raid_cpu_has_ssse3()) + 455 264 : if (!raid_cpu_has_ssse3()) 456 : #endif 457 0 : if (state->raid_mode == RAID_MODE_CAUCHY && !state->opt.no_warnings) { 458 0 : if (state->level == 3) { @@ -527,7 +527,7 @@ 465 : } 466 : 467 : /* ensure that specified filter disks are valid ones */ - 468 273 : for (i = tommy_list_head(filterlist_disk); i != 0; i = i->next) { + 468 274 : for (i = tommy_list_head(filterlist_disk); i != 0; i = i->next) { 469 : tommy_node* j; 470 10 : struct snapraid_filter* filter = i->data; 471 51 : for (j = state->disklist; j != 0; j = j->next) { @@ -548,7 +548,7 @@ 486 : } 487 : } 488 : } - 489 263 : } + 489 264 : } 490 : 491 : /** 492 : * Validate the smartctl command. @@ -580,7 +580,7 @@ 518 364 : return 0; 519 : } 520 : - 521 264 : void state_config(struct snapraid_state* state, const char* path, const char* command, struct snapraid_option* opt, tommy_list* filterlist_disk) + 521 265 : void state_config(struct snapraid_state* state, const char* path, const char* command, struct snapraid_option* opt, tommy_list* filterlist_disk) 522 : { 523 : STREAM* f; 524 : unsigned line; @@ -588,27 +588,27 @@ 526 : unsigned l, s; 527 : 528 : /* copy the options */ - 529 264 : state->opt = *opt; + 529 265 : state->opt = *opt; 530 : 531 : /* if unset, sort by physical order */ - 532 264 : if (!state->opt.force_order) + 532 265 : if (!state->opt.force_order) 533 1 : state->opt.force_order = SORT_PHYSICAL; 534 : 535 : /* adjust file mode */ - 536 264 : if (state->opt.file_mode != ADVISE_DEFAULT) { + 536 265 : if (state->opt.file_mode != ADVISE_DEFAULT) { 537 4 : state->file_mode = state->opt.file_mode; 538 : } else { 539 : /* default mode, if nothing is specified */ - 540 260 : state->file_mode = ADVISE_FLUSH; + 540 261 : state->file_mode = ADVISE_FLUSH; 541 : } 542 : 543 : /* store current command */ - 544 264 : state->command = command; + 544 265 : state->command = command; 545 : - 546 264 : log_tag("conf:file:%s\n", path); + 546 265 : log_tag("conf:file:%s\n", path); 547 : - 548 264 : f = sopen_read(path); - 549 264 : if (!f) { + 548 265 : f = sopen_read(path); + 549 265 : if (!f) { 550 : /* LCOV_EXCL_START */ 551 : if (errno == ENOENT) { 552 : if (state->opt.auto_conf) { @@ -629,7 +629,7 @@ 567 : /* LCOV_EXCL_STOP */ 568 : } 569 : - 570 264 : line = 1; + 570 265 : line = 1; 571 : while (1) { 572 : char tag[PATH_MAX]; 573 : char buffer[PATH_MAX]; @@ -638,11 +638,11 @@ 576 : unsigned level; 577 : 578 : /* skip initial spaces */ - 579 6201 : sgetspace(f); + 579 6219 : sgetspace(f); 580 : 581 : /* read the command */ - 582 6201 : ret = sgettok(f, tag, sizeof(tag)); - 583 6201 : if (ret < 0) { + 582 6219 : ret = sgettok(f, tag, sizeof(tag)); + 583 6219 : if (ret < 0) { 584 : /* LCOV_EXCL_START */ 585 : log_fatal("Error reading the configuration file '%s' at line %u\n", path, line); 586 : exit(EXIT_FAILURE); @@ -650,40 +650,40 @@ 588 : } 589 : 590 : /* skip spaces after the command */ - 591 6201 : sgetspace(f); + 591 6219 : sgetspace(f); 592 : - 593 6201 : if (strcmp(tag, "blocksize") == 0 + 593 6219 : if (strcmp(tag, "blocksize") == 0 594 : /* block_size is the old format of the option */ - 595 5937 : || strcmp(tag, "block_size") == 0) { + 595 5954 : || strcmp(tag, "block_size") == 0) { 596 : - 597 264 : ret = sgetu32(f, &state->block_size); - 598 264 : if (ret < 0) { + 597 265 : ret = sgetu32(f, &state->block_size); + 598 265 : if (ret < 0) { 599 : /* LCOV_EXCL_START */ 600 : log_fatal("Invalid 'blocksize' specification in '%s' at line %u\n", path, line); 601 : exit(EXIT_FAILURE); 602 : /* LCOV_EXCL_STOP */ 603 : } - 604 264 : if (state->block_size < 1) { + 604 265 : if (state->block_size < 1) { 605 : /* LCOV_EXCL_START */ 606 : log_fatal("Too small 'blocksize' specification in '%s' at line %u\n", path, line); 607 : exit(EXIT_FAILURE); 608 : /* LCOV_EXCL_STOP */ 609 : } - 610 264 : if (state->block_size > 16 * KIBI) { + 610 265 : if (state->block_size > 16 * KIBI) { 611 : /* LCOV_EXCL_START */ 612 : log_fatal("Too big 'blocksize' specification in '%s' at line %u\n", path, line); 613 : exit(EXIT_FAILURE); 614 : /* LCOV_EXCL_STOP */ 615 : } 616 : /* check if it's a power of 2 */ - 617 264 : if ((state->block_size & (state->block_size - 1)) != 0) { + 617 265 : if ((state->block_size & (state->block_size - 1)) != 0) { 618 : /* LCOV_EXCL_START */ 619 : log_fatal("Not power of 2 'blocksize' specification in '%s' at line %u\n", path, line); 620 : exit(EXIT_FAILURE); 621 : /* LCOV_EXCL_STOP */ 622 : } - 623 264 : state->block_size *= KIBI; - 624 5937 : } else if (strcmp(tag, "hash_size") == 0) { + 623 265 : state->block_size *= KIBI; + 624 5954 : } else if (strcmp(tag, "hash_size") == 0) { 625 : uint32_t hash_size; 626 : 627 0 : ret = sgetu32(f, &hash_size); @@ -714,7 +714,7 @@ 652 : } 653 : 654 0 : BLOCK_HASH_SIZE = hash_size; - 655 5937 : } else if (lev_config_scan(tag, &level, &state->raid_mode) == 0) { + 655 5954 : } else if (lev_config_scan(tag, &level, &state->raid_mode) == 0) { 656 : char device[PATH_MAX]; 657 : char* split_map[SPLIT_MAX+1]; 658 : unsigned split_mac; @@ -722,43 +722,43 @@ 660 : uint64_t dev; 661 : int skip_access; 662 : - 663 1265 : if (state->parity[level].split_mac != 0) { + 663 1266 : if (state->parity[level].split_mac != 0) { 664 : /* LCOV_EXCL_START */ 665 : log_fatal("Multiple '%s' specification in '%s' at line %u\n", tag, path, line); 666 : exit(EXIT_FAILURE); 667 : /* LCOV_EXCL_STOP */ 668 : } 669 : - 670 1265 : ret = sgetlasttok(f, buffer, sizeof(buffer)); - 671 1265 : if (ret < 0) { + 670 1266 : ret = sgetlasttok(f, buffer, sizeof(buffer)); + 671 1266 : if (ret < 0) { 672 : /* LCOV_EXCL_START */ 673 : log_fatal("Invalid '%s' specification in '%s' at line %u\n", tag, path, line); 674 : exit(EXIT_FAILURE); 675 : /* LCOV_EXCL_STOP */ 676 : } 677 : - 678 1265 : if (!*buffer) { + 678 1266 : if (!*buffer) { 679 : /* LCOV_EXCL_START */ 680 : log_fatal("Empty '%s' specification in '%s' at line %u\n", tag, path, line); 681 : exit(EXIT_FAILURE); 682 : /* LCOV_EXCL_STOP */ 683 : } 684 : - 685 1265 : split_mac = strsplit(split_map, SPLIT_MAX+1, buffer, ","); + 685 1266 : split_mac = strsplit(split_map, SPLIT_MAX+1, buffer, ","); 686 : - 687 1265 : if (split_mac > SPLIT_MAX) { + 687 1266 : if (split_mac > SPLIT_MAX) { 688 : /* LCOV_EXCL_START */ 689 : log_fatal("Too many files in '%s' specification in '%s' at line %u\n", tag, path, line); 690 : exit(EXIT_FAILURE); 691 : /* LCOV_EXCL_STOP */ 692 : } 693 : - 694 1265 : skip_access = 0; - 695 1265 : state->parity[level].split_mac = split_mac; - 696 6321 : for (s = 0; s < split_mac; ++s) { - 697 5057 : pathimport(state->parity[level].split_map[s].path, sizeof(state->parity[level].split_map[s].path), split_map[s]); + 694 1266 : skip_access = 0; + 695 1266 : state->parity[level].split_mac = split_mac; + 696 6326 : for (s = 0; s < split_mac; ++s) { + 697 5061 : pathimport(state->parity[level].split_map[s].path, sizeof(state->parity[level].split_map[s].path), split_map[s]); 698 : - 699 5057 : if (!state->opt.skip_parity_access) { + 699 5061 : if (!state->opt.skip_parity_access) { 700 : struct stat st; 701 : 702 : /* get the device of the directory containing the parity file */ @@ -792,101 +792,101 @@ 730 : } 731 : } else { 732 : /* use a fake device */ - 733 708 : dev = 0; + 733 712 : dev = 0; 734 : } 735 : - 736 5056 : state->parity[level].split_map[s].device = dev; + 736 5060 : state->parity[level].split_map[s].device = dev; 737 : } 738 : 739 : /* store the global parity skip_access */ - 740 1264 : state->parity[level].skip_access = skip_access; + 740 1265 : state->parity[level].skip_access = skip_access; 741 : 742 : /* adjust the level */ - 743 1264 : if (state->level < level + 1) + 743 1265 : if (state->level < level + 1) 744 1000 : state->level = level + 1; - 745 4672 : } else if (strcmp(tag, "share") == 0) { - 746 40 : if (*state->share) { + 745 4688 : } else if (strcmp(tag, "share") == 0) { + 746 41 : if (*state->share) { 747 : /* LCOV_EXCL_START */ 748 : log_fatal("Multiple 'share' specification in '%s' at line %u\n", path, line); 749 : exit(EXIT_FAILURE); 750 : /* LCOV_EXCL_STOP */ 751 : } 752 : - 753 40 : ret = sgetlasttok(f, buffer, sizeof(buffer)); - 754 40 : if (ret < 0) { + 753 41 : ret = sgetlasttok(f, buffer, sizeof(buffer)); + 754 41 : if (ret < 0) { 755 : /* LCOV_EXCL_START */ 756 : log_fatal("Invalid 'share' specification in '%s' at line %u\n", path, line); 757 : exit(EXIT_FAILURE); 758 : /* LCOV_EXCL_STOP */ 759 : } 760 : - 761 40 : if (!*buffer) { + 761 41 : if (!*buffer) { 762 : /* LCOV_EXCL_START */ 763 : log_fatal("Empty 'share' specification in '%s' at line %u\n", path, line); 764 : exit(EXIT_FAILURE); 765 : /* LCOV_EXCL_STOP */ 766 : } 767 : - 768 40 : pathimport(state->share, sizeof(state->share), buffer); - 769 4632 : } else if (strcmp(tag, "pool") == 0) { + 768 41 : pathimport(state->share, sizeof(state->share), buffer); + 769 4647 : } else if (strcmp(tag, "pool") == 0) { 770 : struct stat st; 771 : - 772 40 : if (*state->pool) { + 772 41 : if (*state->pool) { 773 : /* LCOV_EXCL_START */ 774 : log_fatal("Multiple 'pool' specification in '%s' at line %u\n", path, line); 775 : exit(EXIT_FAILURE); 776 : /* LCOV_EXCL_STOP */ 777 : } 778 : - 779 40 : ret = sgetlasttok(f, buffer, sizeof(buffer)); - 780 40 : if (ret < 0) { + 779 41 : ret = sgetlasttok(f, buffer, sizeof(buffer)); + 780 41 : if (ret < 0) { 781 : /* LCOV_EXCL_START */ 782 : log_fatal("Invalid 'pool' specification in '%s' at line %u\n", path, line); 783 : exit(EXIT_FAILURE); 784 : /* LCOV_EXCL_STOP */ 785 : } 786 : - 787 40 : if (!*buffer) { + 787 41 : if (!*buffer) { 788 : /* LCOV_EXCL_START */ 789 : log_fatal("Empty 'pool' specification in '%s' at line %u\n", path, line); 790 : exit(EXIT_FAILURE); 791 : /* LCOV_EXCL_STOP */ 792 : } 793 : - 794 40 : pathimport(state->pool, sizeof(state->pool), buffer); + 794 41 : pathimport(state->pool, sizeof(state->pool), buffer); 795 : 796 : /* get the device of the directory containing the pool tree */ - 797 40 : if (stat(buffer, &st) != 0) { + 797 41 : if (stat(buffer, &st) != 0) { 798 : /* LCOV_EXCL_START */ 799 : log_fatal("Error accessing 'pool' dir '%s' specification in '%s' at line %u\n", buffer, path, line); 800 : exit(EXIT_FAILURE); 801 : /* LCOV_EXCL_STOP */ 802 : } 803 : - 804 40 : state->pool_device = st.st_dev; - 805 4592 : } else if (strcmp(tag, "content") == 0) { + 804 41 : state->pool_device = st.st_dev; + 805 4606 : } else if (strcmp(tag, "content") == 0) { 806 : struct snapraid_content* content; 807 : char device[PATH_MAX]; 808 : char* slash; 809 : struct stat st; 810 : uint64_t dev; 811 : - 812 1522 : ret = sgetlasttok(f, buffer, sizeof(buffer)); - 813 1522 : if (ret < 0) { + 812 1524 : ret = sgetlasttok(f, buffer, sizeof(buffer)); + 813 1524 : if (ret < 0) { 814 : /* LCOV_EXCL_START */ 815 : log_fatal("Invalid 'content' specification in '%s' at line %u\n", path, line); 816 : exit(EXIT_FAILURE); 817 : /* LCOV_EXCL_STOP */ 818 : } 819 : - 820 1522 : if (pathcmp(buffer, "/dev/null") == 0 || pathcmp(buffer, "NUL") == 0) { + 820 1524 : if (pathcmp(buffer, "/dev/null") == 0 || pathcmp(buffer, "NUL") == 0) { 821 : /* LCOV_EXCL_START */ 822 : log_fatal("You cannot use the null device as 'content' specification in '%s' at line %u\n", path, line); 823 : exit(EXIT_FAILURE); 824 : /* LCOV_EXCL_STOP */ 825 : } 826 : - 827 1522 : if (!*buffer) { + 827 1524 : if (!*buffer) { 828 : /* LCOV_EXCL_START */ 829 : log_fatal("Empty 'content' specification in '%s' at line %u\n", path, line); 830 : exit(EXIT_FAILURE); @@ -894,12 +894,12 @@ 832 : } 833 : 834 : /* check if the content file is already specified */ - 835 5693 : for (i = state->contentlist; i != 0; i = i->next) { - 836 4171 : content = i->data; - 837 4171 : if (pathcmp(content->content, buffer) == 0) + 835 5696 : for (i = state->contentlist; i != 0; i = i->next) { + 836 4172 : content = i->data; + 837 4172 : if (pathcmp(content->content, buffer) == 0) 838 0 : break; 839 : } - 840 1522 : if (i) { + 840 1524 : if (i) { 841 : /* LCOV_EXCL_START */ 842 : log_fatal("Duplicate 'content' specification in '%s' at line %u\n", path, line); 843 : exit(EXIT_FAILURE); @@ -907,14 +907,14 @@ 845 : } 846 : 847 : /* get the device of the directory containing the content file */ - 848 1522 : pathimport(device, sizeof(device), buffer); - 849 1522 : slash = strrchr(device, '/'); - 850 1522 : if (slash) - 851 1522 : *slash = 0; + 848 1524 : pathimport(device, sizeof(device), buffer); + 849 1524 : slash = strrchr(device, '/'); + 850 1524 : if (slash) + 851 1524 : *slash = 0; 852 : else 853 0 : pathcpy(device, sizeof(device), "."); - 854 1522 : if (stat(device, &st) == 0) { - 855 1521 : dev = st.st_dev; + 854 1524 : if (stat(device, &st) == 0) { + 855 1523 : dev = st.st_dev; 856 : } else { 857 1 : if (state->opt.skip_content_access) { 858 : /* use a fake device */ @@ -929,15 +929,15 @@ 867 : } 868 : 869 : /* set the lock file at the first accessible content file */ - 870 1522 : if (state->lockfile[0] == 0 && dev != 0) { - 871 263 : pathcpy(state->lockfile, sizeof(state->lockfile), buffer); - 872 263 : pathcat(state->lockfile, sizeof(state->lockfile), ".lock"); + 870 1524 : if (state->lockfile[0] == 0 && dev != 0) { + 871 264 : pathcpy(state->lockfile, sizeof(state->lockfile), buffer); + 872 264 : pathcat(state->lockfile, sizeof(state->lockfile), ".lock"); 873 : } 874 : - 875 1522 : content = content_alloc(buffer, dev); + 875 1524 : content = content_alloc(buffer, dev); 876 : - 877 1522 : tommy_list_insert_tail(&state->contentlist, &content->node, content); - 878 4643 : } else if (strcmp(tag, "data") == 0 || strcmp(tag, "disk") == 0) { + 877 1524 : tommy_list_insert_tail(&state->contentlist, &content->node, content); + 878 4661 : } else if (strcmp(tag, "data") == 0 || strcmp(tag, "disk") == 0) { 879 : /* "disk" is the deprecated name up to SnapRAID 9.x */ 880 : char dir[PATH_MAX]; 881 : char device[PATH_MAX]; @@ -946,32 +946,32 @@ 884 : uint64_t dev; 885 : int skip_access; 886 : - 887 1573 : ret = sgettok(f, buffer, sizeof(buffer)); - 888 1573 : if (ret < 0) { + 887 1579 : ret = sgettok(f, buffer, sizeof(buffer)); + 888 1579 : if (ret < 0) { 889 : /* LCOV_EXCL_START */ 890 : log_fatal("Invalid 'data' name specification in '%s' at line %u\n", path, line); 891 : exit(EXIT_FAILURE); 892 : /* LCOV_EXCL_STOP */ 893 : } 894 : - 895 1573 : if (!*buffer) { + 895 1579 : if (!*buffer) { 896 : /* LCOV_EXCL_START */ 897 : log_fatal("Empty 'data' name specification in '%s' at line %u\n", path, line); 898 : exit(EXIT_FAILURE); 899 : /* LCOV_EXCL_STOP */ 900 : } 901 : - 902 1573 : sgetspace(f); + 902 1579 : sgetspace(f); 903 : - 904 1573 : ret = sgetlasttok(f, dir, sizeof(dir)); - 905 1573 : if (ret < 0) { + 904 1579 : ret = sgetlasttok(f, dir, sizeof(dir)); + 905 1579 : if (ret < 0) { 906 : /* LCOV_EXCL_START */ 907 : log_fatal("Invalid 'data' dir specification in '%s' at line %u\n", path, line); 908 : exit(EXIT_FAILURE); 909 : /* LCOV_EXCL_STOP */ 910 : } 911 : - 912 1573 : if (!*dir) { + 912 1579 : if (!*dir) { 913 : /* LCOV_EXCL_START */ 914 : log_fatal("Empty 'data' dir specification in '%s' at line %u\n", path, line); 915 : exit(EXIT_FAILURE); @@ -979,15 +979,15 @@ 917 : } 918 : 919 : /* get the device of the dir */ - 920 1573 : pathimport(device, sizeof(device), dir); + 920 1579 : pathimport(device, sizeof(device), dir); 921 : 922 : /* check if the disk name already exists */ - 923 5493 : for (i = state->disklist; i != 0; i = i->next) { - 924 3920 : disk = i->data; - 925 3920 : if (strcmp(disk->name, buffer) == 0) + 923 5514 : for (i = state->disklist; i != 0; i = i->next) { + 924 3935 : disk = i->data; + 925 3935 : if (strcmp(disk->name, buffer) == 0) 926 0 : break; 927 : } - 928 1573 : if (i) { + 928 1579 : if (i) { 929 : /* LCOV_EXCL_START */ 930 : log_fatal("Duplicate 'data' name '%s' at line %u\n", buffer, line); 931 : exit(EXIT_FAILURE); @@ -995,20 +995,20 @@ 933 : } 934 : 935 : /* if the disk has to be present */ - 936 1573 : skip_access = 0; - 937 1573 : if (!state->opt.skip_disk_access) { + 936 1579 : skip_access = 0; + 937 1579 : if (!state->opt.skip_disk_access) { 938 : struct stat st; 939 : - 940 1417 : if (stat(device, &st) == 0) { - 941 1416 : dev = st.st_dev; + 940 1423 : if (stat(device, &st) == 0) { + 941 1422 : dev = st.st_dev; 942 : 943 : /* read the uuid, if unsupported use an empty one */ - 944 1416 : if (devuuid(dev, uuid, sizeof(uuid)) != 0) { + 944 1422 : if (devuuid(dev, uuid, sizeof(uuid)) != 0) { 945 0 : *uuid = 0; 946 : } 947 : 948 : /* fake a different UUID when testing */ - 949 1416 : if (state->opt.fake_uuid) { + 949 1422 : if (state->opt.fake_uuid) { 950 2 : snprintf(uuid, sizeof(uuid), "fake-uuid-%d", state->opt.fake_uuid); 951 2 : --state->opt.fake_uuid; 952 : } @@ -1038,10 +1038,10 @@ 976 156 : *uuid = 0; 977 : } 978 : - 979 1573 : disk = disk_alloc(buffer, dir, dev, uuid, skip_access); + 979 1579 : disk = disk_alloc(buffer, dir, dev, uuid, skip_access); 980 : - 981 1573 : tommy_list_insert_tail(&state->disklist, &disk->node, disk); - 982 1497 : } else if (strcmp(tag, "smartctl") == 0) { + 981 1579 : tommy_list_insert_tail(&state->disklist, &disk->node, disk); + 982 1503 : } else if (strcmp(tag, "smartctl") == 0) { 983 : char custom[PATH_MAX]; 984 : 985 364 : ret = sgettok(f, buffer, sizeof(buffer)); @@ -1118,83 +1118,83 @@ 1056 : 1057 182 : pathcpy(disk->smartctl, sizeof(disk->smartctl), custom); 1058 : } - 1059 1133 : } else if (strcmp(tag, "nohidden") == 0) { + 1059 1139 : } else if (strcmp(tag, "nohidden") == 0) { 1060 0 : state->filter_hidden = 1; - 1061 1133 : } else if (strcmp(tag, "exclude") == 0) { + 1061 1139 : } else if (strcmp(tag, "exclude") == 0) { 1062 : struct snapraid_filter* filter; 1063 : - 1064 263 : ret = sgetlasttok(f, buffer, sizeof(buffer)); - 1065 263 : if (ret < 0) { + 1064 264 : ret = sgetlasttok(f, buffer, sizeof(buffer)); + 1065 264 : if (ret < 0) { 1066 : /* LCOV_EXCL_START */ 1067 : log_fatal("Invalid 'exclude' specification in '%s' at line %u\n", path, line); 1068 : exit(EXIT_FAILURE); 1069 : /* LCOV_EXCL_STOP */ 1070 : } 1071 : - 1072 263 : if (!*buffer) { + 1072 264 : if (!*buffer) { 1073 : /* LCOV_EXCL_START */ 1074 : log_fatal("Empty 'exclude' specification in '%s' at line %u\n", path, line); 1075 : exit(EXIT_FAILURE); 1076 : /* LCOV_EXCL_STOP */ 1077 : } 1078 : - 1079 263 : filter = filter_alloc_file(-1, buffer); - 1080 263 : if (!filter) { + 1079 264 : filter = filter_alloc_file(-1, buffer); + 1080 264 : if (!filter) { 1081 : /* LCOV_EXCL_START */ 1082 : log_fatal("Invalid 'exclude' specification '%s' in '%s' at line %u\n", buffer, path, line); 1083 : log_fatal("Filters using relative paths are not supported. Ensure to add an initial slash\n"); 1084 : exit(EXIT_FAILURE); 1085 : /* LCOV_EXCL_STOP */ 1086 : } - 1087 263 : tommy_list_insert_tail(&state->filterlist, &filter->node, filter); - 1088 870 : } else if (strcmp(tag, "include") == 0) { + 1087 264 : tommy_list_insert_tail(&state->filterlist, &filter->node, filter); + 1088 875 : } else if (strcmp(tag, "include") == 0) { 1089 : struct snapraid_filter* filter; 1090 : - 1091 263 : ret = sgetlasttok(f, buffer, sizeof(buffer)); - 1092 263 : if (ret < 0) { + 1091 264 : ret = sgetlasttok(f, buffer, sizeof(buffer)); + 1092 264 : if (ret < 0) { 1093 : /* LCOV_EXCL_START */ 1094 : log_fatal("Invalid 'include' specification in '%s' at line %u\n", path, line); 1095 : exit(EXIT_FAILURE); 1096 : /* LCOV_EXCL_STOP */ 1097 : } 1098 : - 1099 263 : if (!*buffer) { + 1099 264 : if (!*buffer) { 1100 : /* LCOV_EXCL_START */ 1101 : log_fatal("Empty 'include' specification in '%s' at line %u\n", path, line); 1102 : exit(EXIT_FAILURE); 1103 : /* LCOV_EXCL_STOP */ 1104 : } 1105 : - 1106 263 : filter = filter_alloc_file(1, buffer); - 1107 263 : if (!filter) { + 1106 264 : filter = filter_alloc_file(1, buffer); + 1107 264 : if (!filter) { 1108 : /* LCOV_EXCL_START */ 1109 : log_fatal("Invalid 'include' specification '%s' in '%s' at line %u\n", buffer, path, line); 1110 : log_fatal("Filters using relative paths are not supported. Ensure to add an initial slash\n"); 1111 : exit(EXIT_FAILURE); 1112 : /* LCOV_EXCL_STOP */ 1113 : } - 1114 263 : tommy_list_insert_tail(&state->filterlist, &filter->node, filter); - 1115 607 : } else if (strcmp(tag, "autosave") == 0) { + 1114 264 : tommy_list_insert_tail(&state->filterlist, &filter->node, filter); + 1115 611 : } else if (strcmp(tag, "autosave") == 0) { 1116 : char* e; 1117 : - 1118 40 : ret = sgetlasttok(f, buffer, sizeof(buffer)); - 1119 40 : if (ret < 0) { + 1118 41 : ret = sgetlasttok(f, buffer, sizeof(buffer)); + 1119 41 : if (ret < 0) { 1120 : /* LCOV_EXCL_START */ 1121 : log_fatal("Invalid 'autosave' specification in '%s' at line %u\n", path, line); 1122 : exit(EXIT_FAILURE); 1123 : /* LCOV_EXCL_STOP */ 1124 : } 1125 : - 1126 40 : if (!*buffer) { + 1126 41 : if (!*buffer) { 1127 : /* LCOV_EXCL_START */ 1128 : log_fatal("Empty 'autosave' specification in '%s' at line %u\n", path, line); 1129 : exit(EXIT_FAILURE); 1130 : /* LCOV_EXCL_STOP */ 1131 : } 1132 : - 1133 40 : state->autosave = strtoul(buffer, &e, 0); + 1133 41 : state->autosave = strtoul(buffer, &e, 0); 1134 : - 1135 40 : if (!e || *e) { + 1135 41 : if (!e || *e) { 1136 : /* LCOV_EXCL_START */ 1137 : log_fatal("Invalid 'autosave' specification in '%s' at line %u\n", path, line); 1138 : exit(EXIT_FAILURE); @@ -1202,12 +1202,12 @@ 1140 : } 1141 : 1142 : /* convert to GB */ - 1143 40 : state->autosave *= GIGA; - 1144 567 : } else if (tag[0] == 0) { + 1143 41 : state->autosave *= GIGA; + 1144 570 : } else if (tag[0] == 0) { 1145 : /* allow empty lines */ - 1146 40 : } else if (tag[0] == '#') { - 1147 40 : ret = sgetline(f, buffer, sizeof(buffer)); - 1148 40 : if (ret < 0) { + 1146 41 : } else if (tag[0] == '#') { + 1147 41 : ret = sgetline(f, buffer, sizeof(buffer)); + 1148 41 : if (ret < 0) { 1149 : /* LCOV_EXCL_START */ 1150 : log_fatal("Invalid comment in '%s' at line %u\n", path, line); 1151 : exit(EXIT_FAILURE); @@ -1221,42 +1221,42 @@ 1159 : } 1160 : 1161 : /* skip final spaces */ - 1162 6200 : sgetspace(f); + 1162 6218 : sgetspace(f); 1163 : 1164 : /* next line */ - 1165 6200 : c = sgeteol(f); - 1166 6200 : if (c == EOF) { - 1167 263 : break; + 1165 6218 : c = sgeteol(f); + 1166 6218 : if (c == EOF) { + 1167 264 : break; 1168 : } - 1169 5937 : if (c != '\n') { + 1169 5954 : if (c != '\n') { 1170 : /* LCOV_EXCL_START */ 1171 : log_fatal("Extra data in '%s' at line %u\n", path, line); 1172 : exit(EXIT_FAILURE); 1173 : /* LCOV_EXCL_STOP */ 1174 : } - 1175 5937 : ++line; - 1176 5937 : } + 1175 5954 : ++line; + 1176 5954 : } 1177 : - 1178 263 : if (serror(f)) { + 1178 264 : if (serror(f)) { 1179 : /* LCOV_EXCL_START */ 1180 : log_fatal("Error reading the configuration file '%s' at line %u\n", path, line); 1181 : exit(EXIT_FAILURE); 1182 : /* LCOV_EXCL_STOP */ 1183 : } 1184 : - 1185 263 : sclose(f); + 1185 264 : sclose(f); 1186 : - 1187 263 : state_config_check(state, path, filterlist_disk); + 1187 264 : state_config_check(state, path, filterlist_disk); 1188 : 1189 : /* select the default hash */ - 1190 263 : if (state->opt.force_murmur3) { + 1190 264 : if (state->opt.force_murmur3) { 1191 1 : state->besthash = HASH_MURMUR3; - 1192 262 : } else if (state->opt.force_spooky2) { + 1192 263 : } else if (state->opt.force_spooky2) { 1193 1 : state->besthash = HASH_SPOOKY2; 1194 : } else { 1195 : #ifdef CONFIG_X86 - 1196 261 : if (sizeof(void*) == 4 && !raid_cpu_has_slowmult()) - 1197 261 : state->besthash = HASH_MURMUR3; + 1196 262 : if (sizeof(void*) == 4 && !raid_cpu_has_slowmult()) + 1197 262 : state->besthash = HASH_MURMUR3; 1198 : else 1199 0 : state->besthash = HASH_SPOOKY2; 1200 : #else @@ -1268,10 +1268,10 @@ 1206 : } 1207 : 1208 : /* by default use the best hash */ - 1209 263 : state->hash = state->besthash; + 1209 264 : state->hash = state->besthash; 1210 : 1211 : /* by default use a random hash seed */ - 1212 263 : if (randomize(state->hashseed, HASH_MAX) != 0) { + 1212 264 : if (randomize(state->hashseed, HASH_MAX) != 0) { 1213 : /* LCOV_EXCL_START */ 1214 : log_fatal("Failed to get random values.\n"); 1215 : exit(EXIT_FAILURE); @@ -1279,47 +1279,47 @@ 1217 : } 1218 : 1219 : /* no previous hash by default */ - 1220 263 : state->prevhash = HASH_UNDEFINED; + 1220 264 : state->prevhash = HASH_UNDEFINED; 1221 : 1222 : /* intentionally not set the prevhashseed, if used valgrind will warn about it */ 1223 : - 1224 263 : log_tag("blocksize:%u\n", state->block_size); - 1225 1836 : for (i = state->disklist; i != 0; i = i->next) { - 1226 1573 : struct snapraid_disk* disk = i->data; - 1227 1573 : log_tag("data:%s:%s\n", disk->name, disk->dir); + 1224 264 : log_tag("blocksize:%u\n", state->block_size); + 1225 1843 : for (i = state->disklist; i != 0; i = i->next) { + 1226 1579 : struct snapraid_disk* disk = i->data; + 1227 1579 : log_tag("data:%s:%s\n", disk->name, disk->dir); 1228 : } 1229 : - 1230 263 : log_tag("mode:%s\n", lev_raid_name(state->raid_mode, state->level)); - 1231 1522 : for (l = 0; l < state->level; ++l) - 1232 6295 : for (s = 0; s < state->parity[l].split_mac; ++s) - 1233 5036 : log_tag("%s:%u:%s\n", lev_config_name(l), s, state->parity[l].split_map[s].path); - 1234 263 : if (state->pool[0] != 0) - 1235 40 : log_tag("pool:%s\n", state->pool); - 1236 263 : if (state->share[0] != 0) - 1237 40 : log_tag("share:%s\n", state->share); - 1238 263 : if (state->autosave != 0) - 1239 40 : log_tag("autosave:%" PRIu64 "\n", state->autosave); - 1240 789 : for (i = tommy_list_head(&state->filterlist); i != 0; i = i->next) { + 1230 264 : log_tag("mode:%s\n", lev_raid_name(state->raid_mode, state->level)); + 1231 1524 : for (l = 0; l < state->level; ++l) + 1232 6300 : for (s = 0; s < state->parity[l].split_mac; ++s) + 1233 5040 : log_tag("%s:%u:%s\n", lev_config_name(l), s, state->parity[l].split_map[s].path); + 1234 264 : if (state->pool[0] != 0) + 1235 41 : log_tag("pool:%s\n", state->pool); + 1236 264 : if (state->share[0] != 0) + 1237 41 : log_tag("share:%s\n", state->share); + 1238 264 : if (state->autosave != 0) + 1239 41 : log_tag("autosave:%" PRIu64 "\n", state->autosave); + 1240 792 : for (i = tommy_list_head(&state->filterlist); i != 0; i = i->next) { 1241 : char out[PATH_MAX]; - 1242 526 : struct snapraid_filter* filter = i->data; - 1243 526 : log_tag("filter:%s\n", filter_type(filter, out, sizeof(out))); + 1242 528 : struct snapraid_filter* filter = i->data; + 1243 528 : log_tag("filter:%s\n", filter_type(filter, out, sizeof(out))); 1244 : } - 1245 263 : if (state->filter_hidden) + 1245 264 : if (state->filter_hidden) 1246 0 : log_tag("filter:nohidden:\n"); - 1247 263 : log_flush(); + 1247 264 : log_flush(); 1248 : } 1249 : 1250 : /** 1251 : * Find a disk by name. 1252 : */ - 1253 7021 : static struct snapraid_disk* find_disk_by_name(struct snapraid_state* state, const char* name) + 1253 7037 : static struct snapraid_disk* find_disk_by_name(struct snapraid_state* state, const char* name) 1254 : { 1255 : tommy_node* i; 1256 : - 1257 24503 : for (i = state->disklist; i != 0; i = i->next) { - 1258 24495 : struct snapraid_disk* disk = i->data; - 1259 24495 : if (strcmp(disk->name, name) == 0) - 1260 7013 : return disk; + 1257 24556 : for (i = state->disklist; i != 0; i = i->next) { + 1258 24548 : struct snapraid_disk* disk = i->data; + 1259 24548 : if (strcmp(disk->name, name) == 0) + 1260 7029 : return disk; 1261 : } 1262 : 1263 8 : if (state->no_conf) { @@ -1372,7 +1372,7 @@ 1310 : /** 1311 : * Update the disk mapping if required. 1312 : */ - 1313 258 : static void state_map(struct snapraid_state* state) + 1313 259 : static void state_map(struct snapraid_state* state) 1314 : { 1315 : unsigned hole; 1316 : tommy_node* i; @@ -1384,16 +1384,16 @@ 1322 : /* this happens when a disk is removed from the configuration file */ 1323 : /* From SnapRAID 4.0 mappings are automatically removed if a disk is not used */ 1324 : /* when saving the content file, but we keep this code to import older content files. */ - 1325 1903 : for (i = state->maplist; i != 0; ) { - 1326 1387 : struct snapraid_map* map = i->data; + 1325 1910 : for (i = state->maplist; i != 0; ) { + 1326 1392 : struct snapraid_map* map = i->data; 1327 : struct snapraid_disk* disk; 1328 : - 1329 1387 : disk = find_disk_by_name(state, map->name); + 1329 1392 : disk = find_disk_by_name(state, map->name); 1330 : 1331 : /* go to the next mapping before removing */ - 1332 1387 : i = i->next; + 1332 1392 : i = i->next; 1333 : - 1334 1387 : if (disk == 0) { + 1334 1392 : if (disk == 0) { 1335 : /* disk not found, remove the mapping */ 1336 0 : tommy_list_remove_existing(&state->maplist, &map->node); 1337 0 : map_free(map); @@ -1402,104 +1402,104 @@ 1340 : 1341 : /* maps each unmapped disk present in the configuration file in the first available hole */ 1342 : /* this happens when you add disks for the first time in the configuration file */ - 1343 258 : hole = 0; /* first position to try */ - 1344 1801 : for (i = state->disklist; i != 0; i = i->next) { - 1345 1543 : struct snapraid_disk* disk = i->data; + 1343 259 : hole = 0; /* first position to try */ + 1344 1808 : for (i = state->disklist; i != 0; i = i->next) { + 1345 1549 : struct snapraid_disk* disk = i->data; 1346 : struct snapraid_map* map; 1347 : tommy_node* j; 1348 : 1349 : /* check if the disk is already mapped */ - 1350 5388 : for (j = state->maplist; j != 0; j = j->next) { - 1351 5232 : map = j->data; - 1352 5232 : if (strcmp(disk->name, map->name) == 0) { + 1350 5409 : for (j = state->maplist; j != 0; j = j->next) { + 1351 5252 : map = j->data; + 1352 5252 : if (strcmp(disk->name, map->name) == 0) { 1353 : /* mapping found */ - 1354 1387 : break; + 1354 1392 : break; 1355 : } 1356 : } - 1357 1543 : if (j != 0) { + 1357 1549 : if (j != 0) { 1358 : /* mapping is present, then copy the free blocks into to disk */ - 1359 1387 : disk->total_blocks = map->total_blocks; - 1360 1387 : disk->free_blocks = map->free_blocks; - 1361 1387 : continue; + 1359 1392 : disk->total_blocks = map->total_blocks; + 1360 1392 : disk->free_blocks = map->free_blocks; + 1361 1392 : continue; 1362 : } 1363 : 1364 : /* mapping not found, search for an hole */ 1365 : while (1) { - 1366 1060 : for (j = state->maplist; j != 0; j = j->next) { - 1367 904 : map = j->data; - 1368 904 : if (map->position == hole) { + 1366 1080 : for (j = state->maplist; j != 0; j = j->next) { + 1367 923 : map = j->data; + 1368 923 : if (map->position == hole) { 1369 : /* position already used */ - 1370 150 : break; + 1370 154 : break; 1371 : } 1372 : } - 1373 306 : if (j == 0) { + 1373 311 : if (j == 0) { 1374 : /* hole found */ - 1375 156 : break; + 1375 157 : break; 1376 : } 1377 : 1378 : /* try with the next one */ - 1379 150 : ++hole; - 1380 150 : } + 1379 154 : ++hole; + 1380 154 : } 1381 : 1382 : /* insert the new mapping */ - 1383 156 : map = map_alloc(disk->name, hole, 0, 0, ""); + 1383 157 : map = map_alloc(disk->name, hole, 0, 0, ""); 1384 : - 1385 156 : tommy_list_insert_tail(&state->maplist, &map->node, map); + 1385 157 : tommy_list_insert_tail(&state->maplist, &map->node, map); 1386 : } 1387 : 1388 : /* without configuration don't check for number of data disks or uuid changes */ - 1389 258 : if (state->no_conf) - 1390 259 : return; + 1389 259 : if (state->no_conf) + 1390 260 : return; 1391 : 1392 : /* counter for the number of UUID mismatches */ - 1393 257 : uuid_mismatch = 0; + 1393 258 : uuid_mismatch = 0; 1394 : 1395 : /* check if mapping match the disk uuid */ - 1396 257 : if (!state->opt.skip_disk_access) { - 1397 1619 : for (i = state->maplist; i != 0; i = i->next) { - 1398 1387 : struct snapraid_map* map = i->data; + 1396 258 : if (!state->opt.skip_disk_access) { + 1397 1626 : for (i = state->maplist; i != 0; i = i->next) { + 1398 1393 : struct snapraid_map* map = i->data; 1399 : struct snapraid_disk* disk; 1400 : - 1401 1387 : disk = find_disk_by_name(state, map->name); - 1402 1387 : if (disk == 0) { + 1401 1393 : disk = find_disk_by_name(state, map->name); + 1402 1393 : if (disk == 0) { 1403 : /* LCOV_EXCL_START */ 1404 : log_fatal("Internal inconsistency for mapping '%s'\n", map->name); 1405 : os_abort(); 1406 : /* LCOV_EXCL_STOP */ 1407 : } 1408 : - 1409 1387 : if (disk->has_unsupported_uuid) { + 1409 1393 : if (disk->has_unsupported_uuid) { 1410 : /* if uuid is not available, skip this one */ 1411 1 : continue; 1412 : } 1413 : 1414 : /* if the uuid is changed */ - 1415 1386 : if (strcmp(disk->uuid, map->uuid) != 0) { + 1415 1392 : if (strcmp(disk->uuid, map->uuid) != 0) { 1416 : /* mark the disk as with an UUID change */ - 1417 112 : disk->has_different_uuid = 1; + 1417 113 : disk->has_different_uuid = 1; 1418 : 1419 : /* if the previous uuid is available */ - 1420 112 : if (map->uuid[0] != 0) { + 1420 113 : if (map->uuid[0] != 0) { 1421 : /* count the number of uuid change */ 1422 4 : ++uuid_mismatch; 1423 4 : log_fatal("UUID change for disk '%s' from '%s' to '%s'\n", disk->name, map->uuid, disk->uuid); 1424 : } else { 1425 : /* no message here, because having a disk without */ 1426 : /* UUID is the normal state of an empty disk */ - 1427 108 : disk->had_empty_uuid = 1; + 1427 109 : disk->had_empty_uuid = 1; 1428 : } 1429 : 1430 : /* update the uuid in the mapping, */ - 1431 112 : pathcpy(map->uuid, sizeof(map->uuid), disk->uuid); + 1431 113 : pathcpy(map->uuid, sizeof(map->uuid), disk->uuid); 1432 : 1433 : /* write the new state with the new uuid */ - 1434 112 : state->need_write = 1; + 1434 113 : state->need_write = 1; 1435 : } 1436 : } 1437 : } 1438 : 1439 : /* check the parity uuid */ - 1440 257 : if (!state->opt.skip_parity_access) { + 1440 258 : if (!state->opt.skip_parity_access) { 1441 1273 : for (l = 0; l < state->level; ++l) { 1442 5260 : for (s = 0; s < state->parity[l].split_mac; ++s) { 1443 : char uuid[UUID_MAX]; @@ -1530,7 +1530,7 @@ 1468 : } 1469 : } 1470 : - 1471 257 : if (!state->opt.force_uuid && uuid_mismatch > state->level) { + 1471 258 : if (!state->opt.force_uuid && uuid_mismatch > state->level) { 1472 : /* LCOV_EXCL_START */ 1473 : log_fatal("Too many disks have UUID changed from the latest 'sync'.\n"); 1474 : log_fatal("If this happens because you really replaced them,\n"); @@ -1542,16 +1542,16 @@ 1480 : } 1481 : 1482 : /* count the number of data disks, including holes left after removing some */ - 1483 257 : diskcount = 0; - 1484 1794 : for (i = state->maplist; i != 0; i = i->next) { - 1485 1537 : struct snapraid_map* map = i->data; + 1483 258 : diskcount = 0; + 1484 1801 : for (i = state->maplist; i != 0; i = i->next) { + 1485 1543 : struct snapraid_map* map = i->data; 1486 : - 1487 1537 : if (map->position + 1 > diskcount) - 1488 1365 : diskcount = map->position + 1; + 1487 1543 : if (map->position + 1 > diskcount) + 1488 1366 : diskcount = map->position + 1; 1489 : } 1490 : 1491 : /* ensure to don't go over the limit of the RAID engine */ - 1492 257 : if (diskcount > RAID_DATA_MAX) { + 1492 258 : if (diskcount > RAID_DATA_MAX) { 1493 : /* LCOV_EXCL_START */ 1494 : log_fatal("Too many data disks. No more than %u.\n", RAID_DATA_MAX); 1495 : exit(EXIT_FAILURE); @@ -1559,10 +1559,10 @@ 1497 : } 1498 : 1499 : /* now count the real number of data disks, excluding holes left after removing some */ - 1500 257 : diskcount = tommy_list_count(&state->maplist); + 1500 258 : diskcount = tommy_list_count(&state->maplist); 1501 : 1502 : /* recommend number of parities */ - 1503 257 : if (!state->opt.no_warnings) { + 1503 258 : if (!state->opt.no_warnings) { 1504 1 : if (diskcount >= 36 && state->level < 6) { 1505 0 : log_fatal("WARNING! With %u disks it's recommended to use six parity levels.\n", diskcount); 1506 1 : } else if (diskcount >= 29 && state->level < 5) { @@ -1647,23 +1647,23 @@ 1585 : /** 1586 : * Check the content. 1587 : */ - 1588 251 : static void state_content_check(struct snapraid_state* state, const char* path) + 1588 252 : static void state_content_check(struct snapraid_state* state, const char* path) 1589 : { 1590 : tommy_node* i; 1591 : 1592 : /* check that any map has different name and position */ - 1593 1752 : for (i = state->maplist; i != 0; i = i->next) { - 1594 1501 : struct snapraid_map* map = i->data; + 1593 1759 : for (i = state->maplist; i != 0; i = i->next) { + 1594 1507 : struct snapraid_map* map = i->data; 1595 : tommy_node* j; - 1596 5241 : for (j = i->next; j != 0; j = j->next) { - 1597 3740 : struct snapraid_map* other = j->data; - 1598 3740 : if (strcmp(map->name, other->name) == 0) { + 1596 5262 : for (j = i->next; j != 0; j = j->next) { + 1597 3755 : struct snapraid_map* other = j->data; + 1598 3755 : if (strcmp(map->name, other->name) == 0) { 1599 : /* LCOV_EXCL_START */ 1600 : log_fatal("Colliding 'map' disk specification in '%s'\n", path); 1601 : exit(EXIT_FAILURE); 1602 : /* LCOV_EXCL_STOP */ 1603 : } - 1604 3740 : if (map->position == other->position) { + 1604 3755 : if (map->position == other->position) { 1605 : /* LCOV_EXCL_START */ 1606 : log_fatal("Colliding 'map' index specification in '%s'\n", path); 1607 : exit(EXIT_FAILURE); @@ -1671,7 +1671,7 @@ 1609 : } 1610 : } 1611 : } - 1612 251 : } + 1612 252 : } 1613 : 1614 : /** 1615 : * Check if the position is REQUIRED, or we can completely clear it from the state. @@ -1707,21 +1707,21 @@ 1645 : * Note also that not requiring an info block, doesn't mean that if present it 1646 : * can be discarded. 1647 : */ - 1648 1547811 : static int fs_info_is_required(struct snapraid_state* state, block_off_t pos) + 1648 1547867 : static int fs_info_is_required(struct snapraid_state* state, block_off_t pos) 1649 : { 1650 : tommy_node* i; 1651 : 1652 : /* check for each disk */ - 1653 2047992 : for (i = state->disklist; i != 0; i = i->next) { - 1654 1989291 : struct snapraid_disk* disk = i->data; - 1655 1989291 : struct snapraid_block* block = fs_par2block_find(disk, pos); + 1653 2048240 : for (i = state->disklist; i != 0; i = i->next) { + 1654 1989507 : struct snapraid_disk* disk = i->data; + 1655 1989507 : struct snapraid_block* block = fs_par2block_find(disk, pos); 1656 : 1657 : /* if we have at least one synced file, the info is required */ - 1658 1989291 : if (block_state_get(block) == BLOCK_STATE_BLK) - 1659 1489110 : return 1; + 1658 1989507 : if (block_state_get(block) == BLOCK_STATE_BLK) + 1659 1489134 : return 1; 1660 : } 1661 : - 1662 58701 : return 0; + 1662 58733 : return 0; 1663 : } 1664 : 1665 0 : static void fs_position_clear_deleted(struct snapraid_state* state, block_off_t pos) @@ -1803,7 +1803,7 @@ 1741 : } 1742 0 : } 1743 : - 1744 252 : static void state_read_content(struct snapraid_state* state, const char* path, STREAM* f) + 1744 253 : static void state_read_content(struct snapraid_state* state, const char* path, STREAM* f) 1745 : { 1746 : block_off_t blockmax; 1747 : unsigned count_file; @@ -1816,17 +1816,17 @@ 1754 : tommy_array disk_mapping; 1755 : uint32_t mapping_max; 1756 : - 1757 252 : blockmax = 0; - 1758 252 : count_file = 0; - 1759 252 : count_hardlink = 0; - 1760 252 : count_symlink = 0; - 1761 252 : count_dir = 0; - 1762 252 : crc_checked = 0; - 1763 252 : mapping_max = 0; - 1764 252 : tommy_array_init(&disk_mapping); + 1757 253 : blockmax = 0; + 1758 253 : count_file = 0; + 1759 253 : count_hardlink = 0; + 1760 253 : count_symlink = 0; + 1761 253 : count_dir = 0; + 1762 253 : crc_checked = 0; + 1763 253 : mapping_max = 0; + 1764 253 : tommy_array_init(&disk_mapping); 1765 : - 1766 252 : ret = sread(f, buffer, 12); - 1767 252 : if (ret < 0) { + 1766 253 : ret = sread(f, buffer, 12); + 1767 253 : if (ret < 0) { 1768 : /* LCOV_EXCL_START */ 1769 : decoding_error(path, f); 1770 : log_fatal("Invalid header!\n"); @@ -1844,9 +1844,9 @@ 1782 : * - SNAPCNT3/SnapRAID 11.0 Adds entry 'Q' for multi parity file. 1783 : * The previous 'P' entry is now deprecated, but supported for importing. 1784 : */ - 1785 252 : if (memcmp(buffer, "SNAPCNT1\n\3\0\0", 12) != 0 - 1786 252 : && memcmp(buffer, "SNAPCNT2\n\3\0\0", 12) != 0 - 1787 252 : && memcmp(buffer, "SNAPCNT3\n\3\0\0", 12) != 0 + 1785 253 : if (memcmp(buffer, "SNAPCNT1\n\3\0\0", 12) != 0 + 1786 253 : && memcmp(buffer, "SNAPCNT2\n\3\0\0", 12) != 0 + 1787 253 : && memcmp(buffer, "SNAPCNT3\n\3\0\0", 12) != 0 1788 : ) { 1789 : /* LCOV_EXCL_START */ 1790 : if (memcmp(buffer, "SNAPCNT", 7) != 0) { @@ -1864,12 +1864,12 @@ 1802 : int c; 1803 : 1804 : /* read the command */ - 1805 3735825 : c = sgetc(f); - 1806 3735825 : if (c == EOF) { - 1807 251 : break; + 1805 3735717 : c = sgetc(f); + 1806 3735717 : if (c == EOF) { + 1807 252 : break; 1808 : } 1809 : - 1810 3735574 : if (c == 'f') { + 1810 3735465 : if (c == 'f') { 1811 : /* file */ 1812 : char sub[PATH_MAX]; 1813 : uint64_t v_size; @@ -1881,25 +1881,25 @@ 1819 : struct snapraid_disk* disk; 1820 : uint32_t mapping; 1821 : - 1822 3612018 : ret = sgetb32(f, &mapping); - 1823 3612018 : if (ret < 0 || mapping >= mapping_max) { + 1822 3611886 : ret = sgetb32(f, &mapping); + 1823 3611886 : if (ret < 0 || mapping >= mapping_max) { 1824 : /* LCOV_EXCL_START */ 1825 : decoding_error(path, f); 1826 : log_fatal("Internal inconsistency in mapping index!\n"); 1827 : os_abort(); 1828 : /* LCOV_EXCL_STOP */ 1829 : } - 1830 3612018 : disk = tommy_array_get(&disk_mapping, mapping); + 1830 3611886 : disk = tommy_array_get(&disk_mapping, mapping); 1831 : - 1832 3612018 : ret = sgetb64(f, &v_size); - 1833 3612018 : if (ret < 0) { + 1832 3611886 : ret = sgetb64(f, &v_size); + 1833 3611886 : if (ret < 0) { 1834 : /* LCOV_EXCL_START */ 1835 : decoding_error(path, f); 1836 : os_abort(); 1837 : /* LCOV_EXCL_STOP */ 1838 : } 1839 : - 1840 3612018 : if (state->block_size == 0) { + 1840 3611886 : if (state->block_size == 0) { 1841 : /* LCOV_EXCL_START */ 1842 : decoding_error(path, f); 1843 : log_fatal("Internal incosistency due zero blocksize!\n"); @@ -1908,7 +1908,7 @@ 1846 : } 1847 : 1848 : /* check for impossible file size to avoid to crash for a too big allocation */ - 1849 3612018 : if (v_size / state->block_size > blockmax) { + 1849 3611886 : if (v_size / state->block_size > blockmax) { 1850 : /* LCOV_EXCL_START */ 1851 : decoding_error(path, f); 1852 : log_fatal("Internal inconsistency in file size too big!\n"); @@ -1916,16 +1916,16 @@ 1854 : /* LCOV_EXCL_STOP */ 1855 : } 1856 : - 1857 3612018 : ret = sgetb64(f, &v_mtime_sec); - 1858 3612018 : if (ret < 0) { + 1857 3611886 : ret = sgetb64(f, &v_mtime_sec); + 1858 3611886 : if (ret < 0) { 1859 : /* LCOV_EXCL_START */ 1860 : decoding_error(path, f); 1861 : os_abort(); 1862 : /* LCOV_EXCL_STOP */ 1863 : } 1864 : - 1865 3612018 : ret = sgetb32(f, &v_mtime_nsec); - 1866 3612018 : if (ret < 0) { + 1865 3611886 : ret = sgetb32(f, &v_mtime_nsec); + 1866 3611886 : if (ret < 0) { 1867 : /* LCOV_EXCL_START */ 1868 : decoding_error(path, f); 1869 : os_abort(); @@ -1933,27 +1933,27 @@ 1871 : } 1872 : 1873 : /* STAT_NSEC_INVALID is encoded as 0 */ - 1874 3612018 : if (v_mtime_nsec == 0) + 1874 3611886 : if (v_mtime_nsec == 0) 1875 0 : v_mtime_nsec = STAT_NSEC_INVALID; 1876 : else - 1877 3612018 : --v_mtime_nsec; + 1877 3611886 : --v_mtime_nsec; 1878 : - 1879 3612018 : ret = sgetb64(f, &v_inode); - 1880 3612018 : if (ret < 0) { + 1879 3611886 : ret = sgetb64(f, &v_inode); + 1880 3611886 : if (ret < 0) { 1881 : /* LCOV_EXCL_START */ 1882 : decoding_error(path, f); 1883 : os_abort(); 1884 : /* LCOV_EXCL_STOP */ 1885 : } 1886 : - 1887 3612018 : ret = sgetbs(f, sub, sizeof(sub)); - 1888 3612018 : if (ret < 0) { + 1887 3611886 : ret = sgetbs(f, sub, sizeof(sub)); + 1888 3611886 : if (ret < 0) { 1889 : /* LCOV_EXCL_START */ 1890 : decoding_error(path, f); 1891 : os_abort(); 1892 : /* LCOV_EXCL_STOP */ 1893 : } - 1894 3612018 : if (!*sub) { + 1894 3611886 : if (!*sub) { 1895 : /* LCOV_EXCL_START */ 1896 : decoding_error(path, f); 1897 : log_fatal("Internal inconsistency for null file!\n"); @@ -1962,40 +1962,40 @@ 1900 : } 1901 : 1902 : /* allocate the file */ - 1903 3612018 : file = file_alloc(state->block_size, sub, v_size, v_mtime_sec, v_mtime_nsec, v_inode, 0); + 1903 3611886 : file = file_alloc(state->block_size, sub, v_size, v_mtime_sec, v_mtime_nsec, v_inode, 0); 1904 : 1905 : /* insert the file in the file containers */ - 1906 3612018 : tommy_hashdyn_insert(&disk->inodeset, &file->nodeset, file, file_inode_hash(file->inode)); - 1907 3612018 : tommy_hashdyn_insert(&disk->pathset, &file->pathset, file, file_path_hash(file->sub)); - 1908 3612018 : tommy_hashdyn_insert(&disk->stampset, &file->stampset, file, file_stamp_hash(file->size, file->mtime_sec, file->mtime_nsec)); - 1909 3612018 : tommy_list_insert_tail(&disk->filelist, &file->nodelist, file); + 1906 3611886 : tommy_hashdyn_insert(&disk->inodeset, &file->nodeset, file, file_inode_hash(file->inode)); + 1907 3611886 : tommy_hashdyn_insert(&disk->pathset, &file->pathset, file, file_path_hash(file->sub)); + 1908 3611886 : tommy_hashdyn_insert(&disk->stampset, &file->stampset, file, file_stamp_hash(file->size, file->mtime_sec, file->mtime_nsec)); + 1909 3611886 : tommy_list_insert_tail(&disk->filelist, &file->nodelist, file); 1910 : 1911 : /* read all the blocks */ - 1912 3612018 : v_idx = 0; - 1913 10856725 : while (v_idx < file->blockmax) { + 1912 3611886 : v_idx = 0; + 1913 10856319 : while (v_idx < file->blockmax) { 1914 : block_off_t v_pos; 1915 : uint32_t v_count; 1916 : 1917 : /* get the "subcommand */ - 1918 3632690 : c = sgetc(f); + 1918 3632547 : c = sgetc(f); 1919 : - 1920 3632690 : ret = sgetb32(f, &v_pos); - 1921 3632690 : if (ret < 0) { + 1920 3632547 : ret = sgetb32(f, &v_pos); + 1921 3632547 : if (ret < 0) { 1922 : /* LCOV_EXCL_START */ 1923 : decoding_error(path, f); 1924 : os_abort(); 1925 : /* LCOV_EXCL_STOP */ 1926 : } 1927 : - 1928 3632690 : ret = sgetb32(f, &v_count); - 1929 3632690 : if (ret < 0) { + 1928 3632547 : ret = sgetb32(f, &v_count); + 1929 3632547 : if (ret < 0) { 1930 : /* LCOV_EXCL_START */ 1931 : decoding_error(path, f); 1932 : os_abort(); 1933 : /* LCOV_EXCL_STOP */ 1934 : } 1935 : - 1936 3632690 : if (v_idx + v_count > file->blockmax) { + 1936 3632547 : if (v_idx + v_count > file->blockmax) { 1937 : /* LCOV_EXCL_START */ 1938 : decoding_error(path, f); 1939 : log_fatal("Internal inconsistency in block number!\n"); @@ -2003,7 +2003,7 @@ 1941 : /* LCOV_EXCL_STOP */ 1942 : } 1943 : - 1944 3632689 : if (v_pos + v_count > blockmax) { + 1944 3632547 : if (v_pos + v_count > blockmax) { 1945 : /* LCOV_EXCL_START */ 1946 : decoding_error(path, f); 1947 : log_fatal("Internal inconsistency in block size %u/%u!\n", blockmax, v_pos + v_count); @@ -2038,9 +2038,9 @@ 1976 : } 1977 : 1978 : /* read the hash only for 'blk/chg/rep', and not for 'new' */ - 1979 8896647 : if (c != 'n') { - 1980 8896647 : ret = sread(f, block->hash, BLOCK_HASH_SIZE); - 1981 8896647 : if (ret < 0) { + 1979 8896370 : if (c != 'n') { + 1980 8896370 : ret = sread(f, block->hash, BLOCK_HASH_SIZE); + 1981 8896370 : if (ret < 0) { 1982 : /* LCOV_EXCL_START */ 1983 : decoding_error(path, f); 1984 : os_abort(); @@ -2053,8 +2053,8 @@ 1991 : 1992 : /* if the block contains a hash of past data */ 1993 : /* and we are clearing such indeterminate hashes */ - 1994 8896647 : if (state->clear_past_hash - 1995 2542743 : && block_has_past_hash(block) + 1994 8896370 : if (state->clear_past_hash + 1995 2542370 : && block_has_past_hash(block) 1996 : ) { 1997 : /* set the hash value to INVALID */ 1998 28006 : hash_invalid_set(block->hash); @@ -2065,8 +2065,8 @@ 2003 : /* in other sync commands */ 2004 : /* note that this is required only in sync, and we detect */ 2005 : /* this using the clear_past_hash flag */ - 2006 8896647 : if (state->clear_past_hash - 2007 2542743 : && state->opt.force_nocopy + 2006 8896370 : if (state->clear_past_hash + 2007 2542370 : && state->opt.force_nocopy 2008 14195 : && block_state_get(block) == BLOCK_STATE_REP 2009 : ) { 2010 : /* set the hash value to INVALID */ @@ -2078,40 +2078,40 @@ 2016 : /* if we want a full reallocation, marks block as invalid parity */ 2017 : /* note that we do this after the force_nocopy option */ 2018 : /* to avoid to mixup the two things */ - 2019 8896647 : if (state->opt.force_realloc + 2019 8896370 : if (state->opt.force_realloc 2020 27826 : && block_state_get(block) == BLOCK_STATE_BLK) { 2021 : /* convert from BLK to REP */ 2022 27826 : block_state_set(block, BLOCK_STATE_REP); 2023 : } 2024 : 2025 : /* set the parity association */ - 2026 8896647 : fs_allocate(disk, v_pos, file, v_idx); + 2026 8896370 : fs_allocate(disk, v_pos, file, v_idx); 2027 : 2028 : /* go to the next block */ - 2029 8896647 : ++v_idx; - 2030 8896647 : ++v_pos; - 2031 8896647 : --v_count; + 2029 8896370 : ++v_idx; + 2030 8896370 : ++v_pos; + 2031 8896370 : --v_count; 2032 : } 2033 : } 2034 : 2035 : /* stat */ - 2036 3612017 : ++count_file; - 2037 123556 : } else if (c == 'i') { + 2036 3611886 : ++count_file; + 2037 123579 : } else if (c == 'i') { 2038 : /* "inf" command */ 2039 : snapraid_info info; 2040 : uint32_t v_pos; 2041 : uint32_t v_oldest; 2042 : - 2043 251 : ret = sgetb32(f, &v_oldest); - 2044 251 : if (ret < 0) { + 2043 252 : ret = sgetb32(f, &v_oldest); + 2044 252 : if (ret < 0) { 2045 : /* LCOV_EXCL_START */ 2046 : decoding_error(path, f); 2047 : os_abort(); 2048 : /* LCOV_EXCL_STOP */ 2049 : } 2050 : - 2051 251 : v_pos = 0; - 2052 55933 : while (v_pos < blockmax) { + 2051 252 : v_pos = 0; + 2052 55630 : while (v_pos < blockmax) { 2053 : int bad; 2054 : int rehash; 2055 : int justsynced; @@ -2119,15 +2119,15 @@ 2057 : uint32_t flag; 2058 : uint32_t v_count; 2059 : - 2060 55431 : ret = sgetb32(f, &v_count); - 2061 55431 : if (ret < 0) { + 2060 55126 : ret = sgetb32(f, &v_count); + 2061 55126 : if (ret < 0) { 2062 : /* LCOV_EXCL_START */ 2063 : decoding_error(path, f); 2064 : os_abort(); 2065 : /* LCOV_EXCL_STOP */ 2066 : } 2067 : - 2068 55431 : if (v_pos + v_count > blockmax) { + 2068 55126 : if (v_pos + v_count > blockmax) { 2069 : /* LCOV_EXCL_START */ 2070 : decoding_error(path, f); 2071 : log_fatal("Internal inconsistency in info size %u/%u!\n", blockmax, v_pos + v_count); @@ -2135,8 +2135,8 @@ 2073 : /* LCOV_EXCL_STOP */ 2074 : } 2075 : - 2076 55431 : ret = sgetb32(f, &flag); - 2077 55431 : if (ret < 0) { + 2076 55126 : ret = sgetb32(f, &flag); + 2077 55126 : if (ret < 0) { 2078 : /* LCOV_EXCL_START */ 2079 : decoding_error(path, f); 2080 : os_abort(); @@ -2144,10 +2144,10 @@ 2082 : } 2083 : 2084 : /* if there is an info */ - 2085 55431 : if ((flag & 1) != 0) { + 2085 55126 : if ((flag & 1) != 0) { 2086 : /* read the time */ - 2087 55416 : ret = sgetb32(f, &t); - 2088 55416 : if (ret < 0) { + 2087 55111 : ret = sgetb32(f, &t); + 2088 55111 : if (ret < 0) { 2089 : /* LCOV_EXCL_START */ 2090 : decoding_error(path, f); 2091 : os_abort(); @@ -2155,11 +2155,11 @@ 2093 : } 2094 : 2095 : /* analyze the flags */ - 2096 55416 : bad = (flag & 2) != 0; - 2097 55416 : rehash = (flag & 4) != 0; - 2098 55416 : justsynced = (flag & 8) != 0; + 2096 55111 : bad = (flag & 2) != 0; + 2097 55111 : rehash = (flag & 4) != 0; + 2098 55111 : justsynced = (flag & 8) != 0; 2099 : - 2100 55416 : if (rehash && state->prevhash == HASH_UNDEFINED) { + 2100 55111 : if (rehash && state->prevhash == HASH_UNDEFINED) { 2101 : /* LCOV_EXCL_START */ 2102 : decoding_error(path, f); 2103 : log_fatal("Internal inconsistency for missing previous checksum!\n"); @@ -2167,18 +2167,18 @@ 2105 : /* LCOV_EXCL_STOP */ 2106 : } 2107 : - 2108 55416 : info = info_make(t + v_oldest, bad, rehash, justsynced); + 2108 55111 : info = info_make(t + v_oldest, bad, rehash, justsynced); 2109 : } else { 2110 15 : info = 0; 2111 : } 2112 : - 2113 1658673 : while (v_count) { + 2113 1658119 : while (v_count) { 2114 : /* insert the info in the array */ - 2115 1547811 : info_set(&state->infoarr, v_pos, info); + 2115 1547867 : info_set(&state->infoarr, v_pos, info); 2116 : 2117 : /* ensure that an info is present only for used positions */ - 2118 1547811 : if (fs_info_is_required(state, v_pos)) { - 2119 1489110 : if (!info) { + 2118 1547867 : if (fs_info_is_required(state, v_pos)) { + 2119 1489134 : if (!info) { 2120 : /* LCOV_EXCL_START */ 2121 : decoding_error(path, f); 2122 : log_fatal("Internal inconsistency for missing info!\n"); @@ -2191,41 +2191,41 @@ 2129 : } 2130 : 2131 : /* go to next block */ - 2132 1547811 : ++v_pos; - 2133 1547811 : --v_count; + 2132 1547867 : ++v_pos; + 2133 1547867 : --v_count; 2134 : } 2135 : } - 2136 123305 : } else if (c == 'h') { + 2136 123327 : } else if (c == 'h') { 2137 : /* hole */ 2138 : uint32_t v_pos; 2139 : struct snapraid_disk* disk; 2140 : uint32_t mapping; 2141 : - 2142 1387 : ret = sgetb32(f, &mapping); - 2143 1387 : if (ret < 0 || mapping >= mapping_max) { + 2142 1392 : ret = sgetb32(f, &mapping); + 2143 1392 : if (ret < 0 || mapping >= mapping_max) { 2144 : /* LCOV_EXCL_START */ 2145 : decoding_error(path, f); 2146 : log_fatal("Internal inconsistency in mapping index!\n"); 2147 : os_abort(); 2148 : /* LCOV_EXCL_STOP */ 2149 : } - 2150 1387 : disk = tommy_array_get(&disk_mapping, mapping); + 2150 1392 : disk = tommy_array_get(&disk_mapping, mapping); 2151 : - 2152 1387 : v_pos = 0; - 2153 4227 : while (v_pos < blockmax) { + 2152 1392 : v_pos = 0; + 2153 4242 : while (v_pos < blockmax) { 2154 : uint32_t v_idx; 2155 : uint32_t v_count; 2156 : struct snapraid_file* deleted; 2157 : - 2158 1453 : ret = sgetb32(f, &v_count); - 2159 1453 : if (ret < 0) { + 2158 1458 : ret = sgetb32(f, &v_count); + 2159 1458 : if (ret < 0) { 2160 : /* LCOV_EXCL_START */ 2161 : decoding_error(path, f); 2162 : os_abort(); 2163 : /* LCOV_EXCL_STOP */ 2164 : } 2165 : - 2166 1453 : if (v_pos + v_count > blockmax) { + 2166 1458 : if (v_pos + v_count > blockmax) { 2167 : /* LCOV_EXCL_START */ 2168 : decoding_error(path, f); 2169 : log_fatal("Internal inconsistency in hole size %u/%u!\n", blockmax, v_pos + v_count); @@ -2234,9 +2234,9 @@ 2172 : } 2173 : 2174 : /* get the sub-command */ - 2175 1453 : c = sgetc(f); + 2175 1458 : c = sgetc(f); 2176 : - 2177 1453 : switch (c) { + 2177 1458 : switch (c) { 2178 : case 'o' : 2179 : /* if it's a run of deleted blocks */ 2180 : @@ -2283,8 +2283,8 @@ 2221 35 : break; 2222 : case 'O' : 2223 : /* go to the next run */ - 2224 1418 : v_pos += v_count; - 2225 1418 : break; + 2224 1423 : v_pos += v_count; + 2225 1423 : break; 2226 : default : 2227 : /* LCOV_EXCL_START */ 2228 : decoding_error(path, f); @@ -2293,7 +2293,7 @@ 2231 : /* LCOV_EXCL_STOP */ 2232 : } 2233 : } - 2234 121918 : } else if (c == 's') { + 2234 121935 : } else if (c == 's') { 2235 : /* symlink */ 2236 : char sub[PATH_MAX]; 2237 : char linkto[PATH_MAX]; @@ -2344,7 +2344,7 @@ 2282 : 2283 : /* stat */ 2284 116468 : ++count_symlink; - 2285 5450 : } else if (c == 'a') { + 2285 5467 : } else if (c == 'a') { 2286 : /* hardlink */ 2287 : char sub[PATH_MAX]; 2288 : char linkto[PATH_MAX]; @@ -2403,7 +2403,7 @@ 2341 : 2342 : /* stat */ 2343 597 : ++count_hardlink; - 2344 4853 : } else if (c == 'r') { + 2344 4870 : } else if (c == 'r') { 2345 : /* dir */ 2346 : char sub[PATH_MAX]; 2347 : struct snapraid_dir* dir; @@ -2445,14 +2445,14 @@ 2383 : 2384 : /* stat */ 2385 790 : ++count_dir; - 2386 4063 : } else if (c == 'c') { + 2386 4080 : } else if (c == 'c') { 2387 : /* get the subcommand */ - 2388 252 : c = sgetc(f); + 2388 253 : c = sgetc(f); 2389 : - 2390 252 : switch (c) { + 2390 253 : switch (c) { 2391 : case 'u' : - 2392 164 : state->hash = HASH_MURMUR3; - 2393 164 : break; + 2392 165 : state->hash = HASH_MURMUR3; + 2393 165 : break; 2394 : case 'k' : 2395 88 : state->hash = HASH_SPOOKY2; 2396 88 : break; @@ -2465,14 +2465,14 @@ 2403 : } 2404 : 2405 : /* read the seed */ - 2406 252 : ret = sread(f, state->hashseed, HASH_MAX); - 2407 252 : if (ret < 0) { + 2406 253 : ret = sread(f, state->hashseed, HASH_MAX); + 2407 253 : if (ret < 0) { 2408 : /* LCOV_EXCL_START */ 2409 : decoding_error(path, f); 2410 : os_abort(); 2411 : /* LCOV_EXCL_STOP */ 2412 : } - 2413 3811 : } else if (c == 'C') { + 2413 3827 : } else if (c == 'C') { 2414 : /* get the sub-command */ 2415 4 : c = sgetc(f); 2416 : @@ -2499,18 +2499,18 @@ 2437 : os_abort(); 2438 : /* LCOV_EXCL_STOP */ 2439 : } - 2440 3807 : } else if (c == 'z') { + 2440 3823 : } else if (c == 'z') { 2441 : uint32_t block_size; 2442 : - 2443 252 : ret = sgetb32(f, &block_size); - 2444 252 : if (ret < 0) { + 2443 253 : ret = sgetb32(f, &block_size); + 2444 253 : if (ret < 0) { 2445 : /* LCOV_EXCL_START */ 2446 : decoding_error(path, f); 2447 : os_abort(); 2448 : /* LCOV_EXCL_STOP */ 2449 : } 2450 : - 2451 252 : if (block_size == 0) { + 2451 253 : if (block_size == 0) { 2452 : /* LCOV_EXCL_START */ 2453 : decoding_error(path, f); 2454 : log_fatal("Zero 'blocksize' specification in the content file!\n"); @@ -2519,11 +2519,11 @@ 2457 : } 2458 : 2459 : /* without configuration, auto assign the block size */ - 2460 252 : if (state->no_conf) { + 2460 253 : if (state->no_conf) { 2461 1 : state->block_size = block_size; 2462 : } 2463 : - 2464 252 : if (block_size != state->block_size) { + 2464 253 : if (block_size != state->block_size) { 2465 : /* LCOV_EXCL_START */ 2466 : decoding_error(path, f); 2467 : log_fatal("Mismatching 'blocksize' specification in the content file!\n"); @@ -2531,18 +2531,18 @@ 2469 : exit(EXIT_FAILURE); 2470 : /* LCOV_EXCL_STOP */ 2471 : } - 2472 3555 : } else if (c == 'y') { + 2472 3570 : } else if (c == 'y') { 2473 : uint32_t hash_size; 2474 : - 2475 252 : ret = sgetb32(f, &hash_size); - 2476 252 : if (ret < 0) { + 2475 253 : ret = sgetb32(f, &hash_size); + 2476 253 : if (ret < 0) { 2477 : /* LCOV_EXCL_START */ 2478 : decoding_error(path, f); 2479 : os_abort(); 2480 : /* LCOV_EXCL_STOP */ 2481 : } 2482 : - 2483 252 : if (hash_size < 2 || hash_size > HASH_MAX) { + 2483 253 : if (hash_size < 2 || hash_size > HASH_MAX) { 2484 : /* LCOV_EXCL_START */ 2485 : decoding_error(path, f); 2486 : log_fatal("Invalid 'hashsize' specification in the content file!\n"); @@ -2551,11 +2551,11 @@ 2489 : } 2490 : 2491 : /* without configuration, auto assign the block size */ - 2492 252 : if (state->no_conf) { + 2492 253 : if (state->no_conf) { 2493 1 : BLOCK_HASH_SIZE = hash_size; 2494 : } 2495 : - 2496 252 : if ((int)hash_size != BLOCK_HASH_SIZE) { + 2496 253 : if ((int)hash_size != BLOCK_HASH_SIZE) { 2497 : /* LCOV_EXCL_START */ 2498 : decoding_error(path, f); 2499 : log_fatal("Mismatching 'hashsize' specification in the content file!\n"); @@ -2563,15 +2563,15 @@ 2501 : exit(EXIT_FAILURE); 2502 : /* LCOV_EXCL_STOP */ 2503 : } - 2504 3303 : } else if (c == 'x') { - 2505 252 : ret = sgetb32(f, &blockmax); - 2506 252 : if (ret < 0) { + 2504 3317 : } else if (c == 'x') { + 2505 253 : ret = sgetb32(f, &blockmax); + 2506 253 : if (ret < 0) { 2507 : /* LCOV_EXCL_START */ 2508 : decoding_error(path, f); 2509 : os_abort(); 2510 : /* LCOV_EXCL_STOP */ 2511 : } - 2512 4444 : } else if (c == 'm' || c == 'M') { + 2512 4462 : } else if (c == 'm' || c == 'M') { 2513 : struct snapraid_map* map; 2514 : char uuid[UUID_MAX]; 2515 : uint32_t v_pos; @@ -2579,16 +2579,16 @@ 2517 : uint32_t v_free_blocks; 2518 : struct snapraid_disk* disk; 2519 : - 2520 1393 : ret = sgetbs(f, buffer, sizeof(buffer)); - 2521 1393 : if (ret < 0) { + 2520 1398 : ret = sgetbs(f, buffer, sizeof(buffer)); + 2521 1398 : if (ret < 0) { 2522 : /* LCOV_EXCL_START */ 2523 : decoding_error(path, f); 2524 : os_abort(); 2525 : /* LCOV_EXCL_STOP */ 2526 : } 2527 : - 2528 1393 : ret = sgetb32(f, &v_pos); - 2529 1393 : if (ret < 0) { + 2528 1398 : ret = sgetb32(f, &v_pos); + 2529 1398 : if (ret < 0) { 2530 : /* LCOV_EXCL_START */ 2531 : decoding_error(path, f); 2532 : os_abort(); @@ -2596,17 +2596,17 @@ 2534 : } 2535 : 2536 : /* from SnapRAID 7.0 the 'M' command includes the free space */ - 2537 1393 : if (c == 'M') { - 2538 1393 : ret = sgetb32(f, &v_total_blocks); - 2539 1393 : if (ret < 0) { + 2537 1398 : if (c == 'M') { + 2538 1398 : ret = sgetb32(f, &v_total_blocks); + 2539 1398 : if (ret < 0) { 2540 : /* LCOV_EXCL_START */ 2541 : decoding_error(path, f); 2542 : os_abort(); 2543 : /* LCOV_EXCL_STOP */ 2544 : } 2545 : - 2546 1393 : ret = sgetb32(f, &v_free_blocks); - 2547 1393 : if (ret < 0) { + 2546 1398 : ret = sgetb32(f, &v_free_blocks); + 2547 1398 : if (ret < 0) { 2548 : /* LCOV_EXCL_START */ 2549 : decoding_error(path, f); 2550 : os_abort(); @@ -2618,8 +2618,8 @@ 2556 : } 2557 : 2558 : /* read the uuid */ - 2559 1393 : ret = sgetbs(f, uuid, sizeof(uuid)); - 2560 1393 : if (ret < 0) { + 2559 1398 : ret = sgetbs(f, uuid, sizeof(uuid)); + 2560 1398 : if (ret < 0) { 2561 : /* LCOV_EXCL_START */ 2562 : decoding_error(path, f); 2563 : os_abort(); @@ -2627,8 +2627,8 @@ 2565 : } 2566 : 2567 : /* find the disk */ - 2568 1393 : disk = find_disk_by_name(state, buffer); - 2569 1393 : if (!disk) { + 2568 1398 : disk = find_disk_by_name(state, buffer); + 2569 1398 : if (!disk) { 2570 : /* search by UUID if renamed */ 2571 2 : disk = find_disk_by_uuid(state, uuid); 2572 2 : if (disk) { @@ -2638,7 +2638,7 @@ 2576 2 : state->need_write = 1; 2577 : } 2578 : } - 2579 1393 : if (!disk) { + 2579 1398 : if (!disk) { 2580 : /* LCOV_EXCL_START */ 2581 : decoding_error(path, f); 2582 : log_fatal("Disk '%s' with uuid '%s' not present in the configuration file!\n", buffer, uuid); @@ -2650,15 +2650,15 @@ 2588 : /* LCOV_EXCL_STOP */ 2589 : } 2590 : - 2591 1393 : map = map_alloc(disk->name, v_pos, v_total_blocks, v_free_blocks, uuid); + 2591 1398 : map = map_alloc(disk->name, v_pos, v_total_blocks, v_free_blocks, uuid); 2592 : - 2593 1393 : tommy_list_insert_tail(&state->maplist, &map->node, map); + 2593 1398 : tommy_list_insert_tail(&state->maplist, &map->node, map); 2594 : 2595 : /* insert in the mapping vector */ - 2596 1393 : tommy_array_grow(&disk_mapping, mapping_max + 1); - 2597 1393 : tommy_array_set(&disk_mapping, mapping_max, disk); - 2598 1393 : ++mapping_max; - 2599 1658 : } else if (c == 'P') { + 2596 1398 : tommy_array_grow(&disk_mapping, mapping_max + 1); + 2597 1398 : tommy_array_set(&disk_mapping, mapping_max, disk); + 2598 1398 : ++mapping_max; + 2599 1666 : } else if (c == 'P') { 2600 : /* from SnapRAID 7.0 the 'P' command includes the free space */ 2601 : /* from SnapRAID 11.0 the 'P' command is deprecated by 'Q' */ 2602 : char v_uuid[UUID_MAX]; @@ -2720,7 +2720,7 @@ 2658 0 : state->parity[v_level].total_blocks = v_total_blocks; 2659 0 : state->parity[v_level].free_blocks = v_free_blocks; 2660 : } - 2661 1658 : } else if (c == 'Q') { + 2661 1666 : } else if (c == 'Q') { 2662 : /* from SnapRAID 11.0 the 'Q' command include size info and multi file support */ 2663 : uint32_t v_level; 2664 : uint32_t v_total_blocks; @@ -2728,39 +2728,39 @@ 2666 : uint32_t v_split_mac; 2667 : unsigned s; 2668 : - 2669 1407 : ret = sgetb32(f, &v_level); - 2670 1407 : if (ret < 0) { + 2669 1414 : ret = sgetb32(f, &v_level); + 2670 1414 : if (ret < 0) { 2671 : /* LCOV_EXCL_START */ 2672 : decoding_error(path, f); 2673 : os_abort(); 2674 : /* LCOV_EXCL_STOP */ 2675 : } 2676 : - 2677 1407 : ret = sgetb32(f, &v_total_blocks); - 2678 1407 : if (ret < 0) { + 2677 1414 : ret = sgetb32(f, &v_total_blocks); + 2678 1414 : if (ret < 0) { 2679 : /* LCOV_EXCL_START */ 2680 : decoding_error(path, f); 2681 : os_abort(); 2682 : /* LCOV_EXCL_STOP */ 2683 : } 2684 : - 2685 1407 : ret = sgetb32(f, &v_free_blocks); - 2686 1407 : if (ret < 0) { + 2685 1414 : ret = sgetb32(f, &v_free_blocks); + 2686 1414 : if (ret < 0) { 2687 : /* LCOV_EXCL_START */ 2688 : decoding_error(path, f); 2689 : os_abort(); 2690 : /* LCOV_EXCL_STOP */ 2691 : } 2692 : - 2693 1407 : ret = sgetb32(f, &v_split_mac); - 2694 1407 : if (ret < 0) { + 2693 1414 : ret = sgetb32(f, &v_split_mac); + 2694 1414 : if (ret < 0) { 2695 : /* LCOV_EXCL_START */ 2696 : decoding_error(path, f); 2697 : os_abort(); 2698 : /* LCOV_EXCL_STOP */ 2699 : } 2700 : - 2701 1407 : if (v_level >= LEV_MAX) { + 2701 1414 : if (v_level >= LEV_MAX) { 2702 : /* LCOV_EXCL_START */ 2703 : decoding_error(path, f); 2704 : log_fatal("Invalid parity level '%u' in the configuration file!\n", v_level); @@ -2769,7 +2769,7 @@ 2707 : } 2708 : 2709 : /* auto configure if configuration is missing */ - 2710 1407 : if (state->no_conf) { + 2710 1414 : if (state->no_conf) { 2711 6 : if (v_level >= state->level) 2712 5 : state->level = v_level + 1; 2713 6 : if (state->parity[v_level].split_mac < v_split_mac) @@ -2777,35 +2777,35 @@ 2715 : } 2716 : 2717 : /* if we use this parity entry */ - 2718 1407 : if (v_level < state->level) { + 2718 1414 : if (v_level < state->level) { 2719 : /* set the parity info */ - 2720 1153 : state->parity[v_level].total_blocks = v_total_blocks; - 2721 1153 : state->parity[v_level].free_blocks = v_free_blocks; + 2720 1155 : state->parity[v_level].total_blocks = v_total_blocks; + 2721 1155 : state->parity[v_level].free_blocks = v_free_blocks; 2722 : } 2723 : - 2724 7035 : for (s = 0; s < v_split_mac; ++s) { + 2724 7066 : for (s = 0; s < v_split_mac; ++s) { 2725 : char v_path[PATH_MAX]; 2726 : char v_uuid[UUID_MAX]; 2727 : uint64_t v_size; 2728 : - 2729 5628 : ret = sgetbs(f, v_path, sizeof(v_path)); - 2730 5628 : if (ret < 0) { + 2729 5653 : ret = sgetbs(f, v_path, sizeof(v_path)); + 2730 5653 : if (ret < 0) { 2731 : /* LCOV_EXCL_START */ 2732 : decoding_error(path, f); 2733 : os_abort(); 2734 : /* LCOV_EXCL_STOP */ 2735 : } 2736 : - 2737 5628 : ret = sgetbs(f, v_uuid, sizeof(v_uuid)); - 2738 5628 : if (ret < 0) { + 2737 5652 : ret = sgetbs(f, v_uuid, sizeof(v_uuid)); + 2738 5652 : if (ret < 0) { 2739 : /* LCOV_EXCL_START */ 2740 : decoding_error(path, f); 2741 : os_abort(); 2742 : /* LCOV_EXCL_STOP */ 2743 : } 2744 : - 2745 5628 : ret = sgetb64(f, &v_size); - 2746 5628 : if (ret < 0) { + 2745 5652 : ret = sgetb64(f, &v_size); + 2746 5652 : if (ret < 0) { 2747 : /* LCOV_EXCL_START */ 2748 : decoding_error(path, f); 2749 : os_abort(); @@ -2813,9 +2813,9 @@ 2751 : } 2752 : 2753 : /* if we use this parity entry */ - 2754 5628 : if (v_level < state->level) { + 2754 5652 : if (v_level < state->level) { 2755 : /* if this split was removed from the configuration */ - 2756 4612 : if (s >= state->parity[v_level].split_mac) { + 2756 4616 : if (s >= state->parity[v_level].split_mac) { 2757 : /* if the file is used, we really need it */ 2758 0 : if (v_size != 0) { 2759 : /* LCOV_EXCL_START */ @@ -2830,30 +2830,30 @@ 2768 0 : log_fatal("WARNING! Dropping from '%s' unused split '%u'\n", lev_config_name(v_level), s); 2769 : } else { 2770 : /* we copy the path only if without configuration file */ - 2771 4612 : if (state->no_conf) + 2771 4616 : if (state->no_conf) 2772 24 : pathcpy(state->parity[v_level].split_map[s].path, sizeof(state->parity[v_level].split_map[s].path), v_path); 2773 : 2774 : /* set the split info */ - 2775 4612 : pathcpy(state->parity[v_level].split_map[s].uuid, sizeof(state->parity[v_level].split_map[s].uuid), v_uuid); - 2776 4612 : state->parity[v_level].split_map[s].size = v_size; + 2775 4616 : pathcpy(state->parity[v_level].split_map[s].uuid, sizeof(state->parity[v_level].split_map[s].uuid), v_uuid); + 2776 4616 : state->parity[v_level].split_map[s].size = v_size; 2777 : 2778 : /* log the info read from the content file */ - 2779 9224 : log_tag("content:%s:%u:%s:%s:%" PRIi64 "\n", lev_config_name(v_level), s, - 2780 4612 : state->parity[v_level].split_map[s].path, - 2781 4612 : state->parity[v_level].split_map[s].uuid, + 2779 9232 : log_tag("content:%s:%u:%s:%s:%" PRIi64 "\n", lev_config_name(v_level), s, + 2780 4616 : state->parity[v_level].split_map[s].path, + 2781 4616 : state->parity[v_level].split_map[s].uuid, 2782 : state->parity[v_level].split_map[s].size); 2783 : } 2784 : } 2785 : } - 2786 251 : } else if (c == 'N') { + 2786 252 : } else if (c == 'N') { 2787 : uint32_t crc_stored; 2788 : uint32_t crc_computed; 2789 : 2790 : /* get the crc before reading it from the file */ - 2791 251 : crc_computed = scrc(f); + 2791 252 : crc_computed = scrc(f); 2792 : - 2793 251 : ret = sgetble32(f, &crc_stored); - 2794 251 : if (ret < 0) { + 2793 252 : ret = sgetble32(f, &crc_stored); + 2794 252 : if (ret < 0) { 2795 : /* LCOV_EXCL_START */ 2796 : /* here don't call decoding_error() because it's too late to get the crc */ 2797 : log_fatal("Error reading the CRC in '%s' at offset %" PRIi64 "\n", path, stell(f)); @@ -2862,7 +2862,7 @@ 2800 : /* LCOV_EXCL_STOP */ 2801 : } 2802 : - 2803 251 : if (crc_stored != crc_computed) { + 2803 252 : if (crc_stored != crc_computed) { 2804 : /* LCOV_EXCL_START */ 2805 : /* here don't call decoding_error() because it's too late to get the crc */ 2806 : log_fatal("Mismatching CRC in '%s'\n", path); @@ -2871,7 +2871,7 @@ 2809 : /* LCOV_EXCL_STOP */ 2810 : } 2811 : - 2812 251 : crc_checked = 1; + 2812 252 : crc_checked = 1; 2813 : } else { 2814 : /* LCOV_EXCL_START */ 2815 : decoding_error(path, f); @@ -2879,18 +2879,18 @@ 2817 : os_abort(); 2818 : /* LCOV_EXCL_STOP */ 2819 : } - 2820 3735573 : } + 2820 3735464 : } 2821 : - 2822 251 : tommy_array_done(&disk_mapping); + 2822 252 : tommy_array_done(&disk_mapping); 2823 : - 2824 251 : if (serror(f)) { + 2824 252 : if (serror(f)) { 2825 : /* LCOV_EXCL_START */ 2826 : log_fatal("Error reading the content file '%s' at offset %" PRIi64 "\n", path, stell(f)); 2827 : exit(EXIT_FAILURE); 2828 : /* LCOV_EXCL_STOP */ 2829 : } 2830 : - 2831 251 : if (!crc_checked) { + 2831 252 : if (!crc_checked) { 2832 : /* LCOV_EXCL_START */ 2833 : log_fatal("Finished reading '%s' without finding the CRC\n", path); 2834 : log_fatal("This content file is truncated or damaged! Use an alternate copy.\n"); @@ -2899,10 +2899,10 @@ 2837 : } 2838 : 2839 : /* check the file-system on all disks */ - 2840 251 : state_fscheck(state, "after read"); + 2840 252 : state_fscheck(state, "after read"); 2841 : 2842 : /* check that the stored parity size matches the loaded state */ - 2843 251 : if (blockmax != parity_allocated_size(state)) { + 2843 252 : if (blockmax != parity_allocated_size(state)) { 2844 : /* LCOV_EXCL_START */ 2845 : log_fatal("Internal inconsistency in parity size %u/%u in '%s' at offset %" PRIi64 "\n", blockmax, parity_allocated_size(state), path, stell(f)); 2846 : if (state->opt.skip_content_check) { @@ -2914,11 +2914,11 @@ 2852 : /* LCOV_EXCL_STOP */ 2853 : } 2854 : - 2855 251 : msg_verbose("%8u files\n", count_file); - 2856 251 : msg_verbose("%8u hardlinks\n", count_hardlink); - 2857 251 : msg_verbose("%8u symlinks\n", count_symlink); - 2858 251 : msg_verbose("%8u empty dirs\n", count_dir); - 2859 251 : } + 2855 252 : msg_verbose("%8u files\n", count_file); + 2856 252 : msg_verbose("%8u hardlinks\n", count_hardlink); + 2857 252 : msg_verbose("%8u symlinks\n", count_symlink); + 2858 252 : msg_verbose("%8u empty dirs\n", count_dir); + 2859 252 : } 2860 : 2861 : struct state_write_thread_context { 2862 : struct snapraid_state* state; @@ -3141,30 +3141,30 @@ 3079 : 3080 : /* for all the blocks of the file */ 3081 1770884 : begin = 0; - 3082 5322967 : while (begin < file->blockmax) { - 3083 1781199 : unsigned v_state = block_state_get(fs_file2block_get(file, begin)); - 3084 1781199 : block_off_t v_pos = fs_file2par_get(disk, file, begin); + 3082 5322945 : while (begin < file->blockmax) { + 3083 1781177 : unsigned v_state = block_state_get(fs_file2block_get(file, begin)); + 3084 1781177 : block_off_t v_pos = fs_file2par_get(disk, file, begin); 3085 : uint32_t v_count; 3086 : 3087 : block_off_t end; 3088 : 3089 : /* find the end of run of blocks */ - 3090 1781199 : end = begin + 1; - 3091 6146339 : while (end < file->blockmax) { + 3090 1781177 : end = begin + 1; + 3091 6146317 : while (end < file->blockmax) { 3092 2596728 : if (v_state != block_state_get(fs_file2block_get(file, end))) 3093 12 : break; 3094 2596716 : if (v_pos + (end - begin) != fs_file2par_get(disk, file, end)) - 3095 12775 : break; - 3096 2583941 : ++end; + 3095 12753 : break; + 3096 2583963 : ++end; 3097 : } 3098 : - 3099 1781199 : switch (v_state) { + 3099 1781177 : switch (v_state) { 3100 : case BLOCK_STATE_BLK : - 3101 1678581 : sputc('b', f); - 3102 1678581 : break; + 3101 1678520 : sputc('b', f); + 3102 1678520 : break; 3103 : case BLOCK_STATE_CHG : - 3104 67700 : sputc('g', f); - 3105 67700 : break; + 3104 67739 : sputc('g', f); + 3105 67739 : break; 3106 : case BLOCK_STATE_REP : 3107 34918 : sputc('p', f); 3108 34918 : break; @@ -3175,19 +3175,19 @@ 3113 : /* LCOV_EXCL_STOP */ 3114 : } 3115 : - 3116 1781199 : sputb32(v_pos, f); + 3116 1781177 : sputb32(v_pos, f); 3117 : - 3118 1781199 : v_count = end - begin; - 3119 1781199 : sputb32(v_count, f); + 3118 1781177 : v_count = end - begin; + 3119 1781177 : sputb32(v_count, f); 3120 : 3121 : /* write hashes */ - 3122 6146339 : for (idx = begin; idx < end; ++idx) { + 3122 6146317 : for (idx = begin; idx < end; ++idx) { 3123 4365140 : struct snapraid_block* block = fs_file2block_get(file, idx); 3124 : 3125 4365140 : swrite(block->hash, BLOCK_HASH_SIZE, f); 3126 : } 3127 : - 3128 1781199 : if (serror(f)) { + 3128 1781177 : if (serror(f)) { 3129 : /* LCOV_EXCL_START */ 3130 : log_fatal("Error writing the content file '%s'. %s.\n", serrorfile(f), strerror(errno)); 3131 : return context; @@ -3195,7 +3195,7 @@ 3133 : } 3134 : 3135 : /* next begin position */ - 3136 1781199 : begin = end; + 3136 1781177 : begin = end; 3137 : } 3138 : 3139 1770884 : ++count_file; @@ -3304,44 +3304,44 @@ 3242 151 : sputc('i', f); 3243 151 : sputb32(info_oldest, f); 3244 151 : begin = 0; - 3245 19734 : while (begin < blockmax) { + 3245 19645 : while (begin < blockmax) { 3246 : snapraid_info info; 3247 : block_off_t end; 3248 : time_t t; 3249 : unsigned flag; 3250 : - 3251 19432 : info = info_get(&state->infoarr, begin); + 3251 19343 : info = info_get(&state->infoarr, begin); 3252 : 3253 : /* find the end of run of blocks */ - 3254 19432 : end = begin + 1; - 3255 775531 : while (end < blockmax + 3254 19343 : end = begin + 1; + 3255 775442 : while (end < blockmax 3256 755951 : && info == info_get(&state->infoarr, end) 3257 : ) { - 3258 736667 : ++end; + 3258 736756 : ++end; 3259 : } 3260 : - 3261 19432 : sputb32(end - begin, f); + 3261 19343 : sputb32(end - begin, f); 3262 : 3263 : /* if there is info */ - 3264 19432 : if (info) { + 3264 19343 : if (info) { 3265 : /* other flags */ - 3266 19409 : flag = 1; /* info is present */ - 3267 19409 : if (info_get_bad(info)) - 3268 1358 : flag |= 2; - 3269 19409 : if (info_get_rehash(info)) + 3266 19320 : flag = 1; /* info is present */ + 3267 19320 : if (info_get_bad(info)) + 3268 1340 : flag |= 2; + 3269 19320 : if (info_get_rehash(info)) 3270 5212 : flag |= 4; - 3271 19409 : if (info_get_justsynced(info)) - 3272 12050 : flag |= 8; - 3273 19409 : sputb32(flag, f); + 3271 19320 : if (info_get_justsynced(info)) + 3272 12001 : flag |= 8; + 3273 19320 : sputb32(flag, f); 3274 : - 3275 19409 : t = info_get_time(info) - info_oldest; - 3276 19409 : sputb32(t, f); + 3275 19320 : t = info_get_time(info) - info_oldest; + 3276 19320 : sputb32(t, f); 3277 : } else { 3278 : /* write a special 0 flag to mark missing info */ 3279 23 : sputb32(0, f); 3280 : } 3281 : - 3282 19432 : if (serror(f)) { + 3282 19343 : if (serror(f)) { 3283 : /* LCOV_EXCL_START */ 3284 : log_fatal("Error writing the content file '%s'. %s.\n", serrorfile(f), strerror(errno)); 3285 : return context; @@ -3349,7 +3349,7 @@ 3287 : } 3288 : 3289 : /* next begin position */ - 3290 19432 : begin = end; + 3290 19343 : begin = end; 3291 : } 3292 : 3293 151 : sputc('N', f); @@ -3438,7 +3438,7 @@ 3376 711614 : time_t info_time = info_get_time(info); 3377 : 3378 711614 : if (!info_oldest || info_time < info_oldest) - 3379 150 : info_oldest = info_time; + 3379 151 : info_oldest = info_time; 3380 : 3381 711614 : if (info_get_rehash(info)) 3382 13822 : info_has_rehash = 1; @@ -3689,7 +3689,7 @@ 3627 151 : *out_crc = crc; 3628 151 : } 3629 : - 3630 259 : void state_read(struct snapraid_state* state) + 3630 260 : void state_read(struct snapraid_state* state) 3631 : { 3632 : STREAM* f; 3633 : char path[PATH_MAX]; @@ -3699,22 +3699,22 @@ 3637 : int c; 3638 : 3639 : /* iterate over all the available content files and load the first one present */ - 3640 259 : f = 0; - 3641 259 : node = tommy_list_head(&state->contentlist); - 3642 568 : while (node) { - 3643 302 : struct snapraid_content* content = node->data; - 3644 302 : pathcpy(path, sizeof(path), content->content); + 3640 260 : f = 0; + 3641 260 : node = tommy_list_head(&state->contentlist); + 3642 570 : while (node) { + 3643 303 : struct snapraid_content* content = node->data; + 3644 303 : pathcpy(path, sizeof(path), content->content); 3645 : - 3646 302 : if (!state->no_conf) { - 3647 301 : log_tag("content:%s\n", path); - 3648 301 : log_flush(); + 3646 303 : if (!state->no_conf) { + 3647 302 : log_tag("content:%s\n", path); + 3648 302 : log_flush(); 3649 : } - 3650 302 : msg_progress("Loading state from %s...\n", path); + 3650 303 : msg_progress("Loading state from %s...\n", path); 3651 : - 3652 302 : f = sopen_read(path); - 3653 302 : if (f != 0) { + 3652 303 : f = sopen_read(path); + 3653 303 : if (f != 0) { 3654 : /* if opened stop the search */ - 3655 252 : break; + 3655 253 : break; 3656 : } else { 3657 : /* if it's real error of an existing file, abort */ 3658 50 : if (errno != ENOENT) { @@ -3738,17 +3738,17 @@ 3676 : } 3677 : 3678 : /* if not found, assume empty */ - 3679 259 : if (!f) { + 3679 260 : if (!f) { 3680 7 : log_fatal("No content file found. Assuming empty.\n"); 3681 : 3682 : /* create the initial mapping */ 3683 7 : state_map(state); - 3684 265 : return; + 3684 266 : return; 3685 : } 3686 : 3687 : /* get the stat of the content file */ - 3688 252 : ret = fstat(shandle(f), &st); - 3689 252 : if (ret != 0) { + 3688 253 : ret = fstat(shandle(f), &st); + 3689 253 : if (ret != 0) { 3690 : /* LCOV_EXCL_START */ 3691 : log_fatal("Error stating the content file '%s'. %s.\n", path, strerror(errno)); 3692 : exit(EXIT_FAILURE); @@ -3756,14 +3756,14 @@ 3694 : } 3695 : 3696 : /* go further to check other content files */ - 3697 1942 : while (node) { + 3697 1946 : while (node) { 3698 : char other_path[PATH_MAX]; 3699 : struct stat other_st; - 3700 1438 : struct snapraid_content* content = node->data; - 3701 1438 : pathcpy(other_path, sizeof(other_path), content->content); + 3700 1440 : struct snapraid_content* content = node->data; + 3701 1440 : pathcpy(other_path, sizeof(other_path), content->content); 3702 : - 3703 1438 : ret = stat(other_path, &other_st); - 3704 1438 : if (ret != 0) { + 3703 1440 : ret = stat(other_path, &other_st); + 3704 1440 : if (ret != 0) { 3705 : /* allow missing content files, but not any other kind of error */ 3706 1 : if (errno != ENOENT) { 3707 : /* LCOV_EXCL_START */ @@ -3776,7 +3776,7 @@ 3714 1 : state->need_write = 1; 3715 : } else { 3716 : /* if the size is different */ - 3717 1437 : if (other_st.st_size != st.st_size) { + 3717 1439 : if (other_st.st_size != st.st_size) { 3718 39 : log_fatal("WARNING! Content files '%s' and '%s' have a different size!\n", path, other_path); 3719 39 : log_fatal("Likely one of the two is broken!\n"); 3720 : @@ -3786,28 +3786,28 @@ 3724 : } 3725 : 3726 : /* next content file */ - 3727 1438 : node = node->next; + 3727 1440 : node = node->next; 3728 : } 3729 : 3730 : /* start with a undefined default. */ 3731 : /* it's for compatibility with version 1.0 where MD5 was implicit. */ - 3732 252 : state->hash = HASH_UNDEFINED; + 3732 253 : state->hash = HASH_UNDEFINED; 3733 : 3734 : /* start with a zero seed, it was the default in old versions */ - 3735 252 : memset(state->hashseed, 0, HASH_MAX); + 3735 253 : memset(state->hashseed, 0, HASH_MAX); 3736 : 3737 : /* previous hash, start with an undefined value */ - 3738 252 : state->prevhash = HASH_UNDEFINED; + 3738 253 : state->prevhash = HASH_UNDEFINED; 3739 : 3740 : /* intentionally not set the prevhashseed, if used valgrind will warn about it */ 3741 : 3742 : /* get the first char to detect the file type */ - 3743 252 : c = sgetc(f); - 3744 252 : sungetc(c, f); + 3743 253 : c = sgetc(f); + 3744 253 : sungetc(c, f); 3745 : 3746 : /* guess the file type from the first char */ - 3747 252 : if (c == 'S') { - 3748 252 : state_read_content(state, path, f); + 3747 253 : if (c == 'S') { + 3748 253 : state_read_content(state, path, f); 3749 : } else { 3750 : /* LCOV_EXCL_START */ 3751 : log_fatal("From SnapRAID v9.0 the text content file is not supported anymore.\n"); @@ -3816,9 +3816,9 @@ 3754 : /* LCOV_EXCL_STOP */ 3755 : } 3756 : - 3757 251 : sclose(f); + 3757 252 : sclose(f); 3758 : - 3759 251 : if (state->hash == HASH_UNDEFINED) { + 3759 252 : if (state->hash == HASH_UNDEFINED) { 3760 : /* LCOV_EXCL_START */ 3761 : log_fatal("The checksum to use is not specified.\n"); 3762 : log_fatal("This happens because you are likely upgrading from SnapRAID 1.0.\n"); @@ -3829,12 +3829,12 @@ 3767 : } 3768 : 3769 : /* update the mapping */ - 3770 251 : state_map(state); + 3770 252 : state_map(state); 3771 : - 3772 251 : state_content_check(state, path); + 3772 252 : state_content_check(state, path); 3773 : 3774 : /* mark that we read the content file, and it passed all the checks */ - 3775 251 : state->checked_read = 1; + 3775 252 : state->checked_read = 1; 3776 : } 3777 : 3778 : struct state_verify_thread_context { @@ -3866,9 +3866,9 @@ 3804 : } 3805 : 3806 : /* get the stored crc from the last four bytes */ - 3807 1012 : crc_stored = buf[0] | (uint32_t)buf[1] << 8 | (uint32_t)buf[2] << 16 | (uint32_t)buf[3] << 24; + 3807 1010 : crc_stored = buf[0] | (uint32_t)buf[1] << 8 | (uint32_t)buf[2] << 16 | (uint32_t)buf[3] << 24; 3808 : - 3809 1012 : if (crc_stored != context->crc) { + 3809 1010 : if (crc_stored != context->crc) { 3810 : /* LCOV_EXCL_START */ 3811 : log_fatal("DANGER! Wrong stored CRC in '%s'\n", serrorfile(f)); 3812 : return context; @@ -3876,7 +3876,7 @@ 3814 : } 3815 : 3816 : /* get the computed crc */ - 3817 1012 : crc_computed = scrc(f); + 3817 1010 : crc_computed = scrc(f); 3818 : 3819 : /* adjust the stored crc to include itself */ 3820 1012 : crc_stored = crc32c(crc_stored, buf, 4); @@ -4089,7 +4089,7 @@ 4027 78138 : || filter_existence(filter_missing, disk->dir, file->sub) != 0 4028 38646 : || filter_correctness(filter_error, &state->infoarr, disk, file) != 0 4029 : ) { - 4030 109457 : file_flag_set(file, FILE_IS_EXCLUDED); + 4030 109466 : file_flag_set(file, FILE_IS_EXCLUDED); 4031 : } 4032 : } 4033 : @@ -4229,23 +4229,23 @@ 4167 : /** 4168 : * Set the latest tick data in the progress vector. 4169 : */ - 4170 495 : static void state_progress_latest(struct snapraid_state* state) + 4170 477 : static void state_progress_latest(struct snapraid_state* state) 4171 : { 4172 : tommy_node* i; 4173 : unsigned l; 4174 : - 4175 495 : state->progress_tick_misc[state->progress_ptr] = state->tick_misc; - 4176 495 : state->progress_tick_sched[state->progress_ptr] = state->tick_sched; - 4177 495 : state->progress_tick_raid[state->progress_ptr] = state->tick_raid; - 4178 495 : state->progress_tick_hash[state->progress_ptr] = state->tick_hash; - 4179 495 : state->progress_tick_io[state->progress_ptr] = state->tick_io; - 4180 3457 : for (i = state->disklist; i != 0; i = i->next) { - 4181 2962 : struct snapraid_disk* disk = i->data; - 4182 2962 : disk->progress_tick[state->progress_ptr] = disk->tick; + 4175 477 : state->progress_tick_misc[state->progress_ptr] = state->tick_misc; + 4176 477 : state->progress_tick_sched[state->progress_ptr] = state->tick_sched; + 4177 477 : state->progress_tick_raid[state->progress_ptr] = state->tick_raid; + 4178 477 : state->progress_tick_hash[state->progress_ptr] = state->tick_hash; + 4179 477 : state->progress_tick_io[state->progress_ptr] = state->tick_io; + 4180 3331 : for (i = state->disklist; i != 0; i = i->next) { + 4181 2854 : struct snapraid_disk* disk = i->data; + 4182 2854 : disk->progress_tick[state->progress_ptr] = disk->tick; 4183 : } - 4184 2811 : for (l = 0; l < state->level; ++l) - 4185 2316 : state->parity[l].progress_tick[state->progress_ptr] = state->parity[l].tick; - 4186 495 : } + 4184 2740 : for (l = 0; l < state->level; ++l) + 4185 2263 : state->parity[l].progress_tick[state->progress_ptr] = state->parity[l].tick; + 4186 477 : } 4187 : 4188 : /** 4189 : * Number of columns @@ -4395,45 +4395,45 @@ 4333 1 : printf("\n"); 4334 : } 4335 : - 4336 1073409 : int state_progress(struct snapraid_state* state, struct snapraid_io* io, block_off_t blockpos, block_off_t countpos, block_off_t countmax, data_off_t countsize) + 4336 1073497 : int state_progress(struct snapraid_state* state, struct snapraid_io* io, block_off_t blockpos, block_off_t countpos, block_off_t countmax, data_off_t countsize) 4337 : { 4338 : time_t now; 4339 : int pred; 4340 : - 4341 1073409 : now = time(0); + 4341 1073497 : now = time(0); 4342 : 4343 : /* previous position */ - 4344 1073409 : pred = state->progress_ptr + PROGRESS_MAX - 1; - 4345 1073409 : if (pred >= PROGRESS_MAX) - 4346 1073210 : pred -= PROGRESS_MAX; + 4344 1073497 : pred = state->progress_ptr + PROGRESS_MAX - 1; + 4345 1073497 : if (pred >= PROGRESS_MAX) + 4346 1073298 : pred -= PROGRESS_MAX; 4347 : 4348 : /* if the previous measure is different */ - 4349 1073409 : if (state->progress_tick == 0 - 4350 1073210 : || state->progress_time[pred] != now + 4349 1073497 : if (state->progress_tick == 0 + 4350 1073298 : || state->progress_time[pred] != now 4351 : ) { 4352 : time_t elapsed; - 4353 399 : unsigned out_perc = 0; - 4354 399 : unsigned out_speed = 0; - 4355 399 : unsigned out_cpu = 0; - 4356 399 : unsigned out_eta = 0; - 4357 399 : int out_computed = 0; + 4353 381 : unsigned out_perc = 0; + 4354 381 : unsigned out_speed = 0; + 4355 381 : unsigned out_cpu = 0; + 4356 381 : unsigned out_eta = 0; + 4357 381 : int out_computed = 0; 4358 : 4359 : /* store the new measure */ - 4360 399 : state->progress_time[state->progress_ptr] = now; - 4361 399 : state->progress_pos[state->progress_ptr] = countpos; - 4362 399 : state->progress_size[state->progress_ptr] = countsize; - 4363 399 : state_progress_latest(state); + 4360 381 : state->progress_time[state->progress_ptr] = now; + 4361 381 : state->progress_pos[state->progress_ptr] = countpos; + 4362 381 : state->progress_size[state->progress_ptr] = countsize; + 4363 381 : state_progress_latest(state); 4364 : - 4365 399 : elapsed = now - state->progress_whole_start - state->progress_wasted; + 4365 381 : elapsed = now - state->progress_whole_start - state->progress_wasted; 4366 : 4367 : /* completion percentage */ - 4368 399 : if (countmax) - 4369 399 : out_perc = countpos * 100 / countmax; + 4368 381 : if (countmax) + 4369 381 : out_perc = countpos * 100 / countmax; 4370 : 4371 : /* if we have at least 5 measures */ - 4372 399 : if (state->progress_tick >= 5 + 4372 381 : if (state->progress_tick >= 5 4373 : /* or if we are running in test mode, with at least one measure */ - 4374 378 : || (state->opt.force_progress && state->progress_tick >= 1) + 4374 365 : || (state->opt.force_progress && state->progress_tick >= 1) 4375 : ) { 4376 : int oldest; 4377 : int past; @@ -4448,88 +4448,88 @@ 4386 : uint64_t oldest_tick_total; 4387 : 4388 : /* number of past measures */ - 4389 200 : past = state->progress_tick; + 4389 182 : past = state->progress_tick; 4390 : 4391 : /* drop the oldest ones, to promptly */ 4392 : /* skip the startup phase */ - 4393 200 : past -= past / 5; + 4393 182 : past -= past / 5; 4394 : 4395 : /* check how much we can go in the past */ - 4396 200 : if (past >= PROGRESS_MAX - 1) { + 4396 182 : if (past >= PROGRESS_MAX - 1) { 4397 : /* the vector is filled, so we are already in position */ 4398 : /* to get the possible oldest one */ 4399 0 : oldest = state->progress_ptr + 1; 4400 : } else { 4401 : /* go backward the number of positions selected */ - 4402 200 : oldest = state->progress_ptr + PROGRESS_MAX - past; + 4402 182 : oldest = state->progress_ptr + PROGRESS_MAX - past; 4403 : } - 4404 200 : if (oldest >= PROGRESS_MAX) - 4405 200 : oldest -= PROGRESS_MAX; + 4404 182 : if (oldest >= PROGRESS_MAX) + 4405 182 : oldest -= PROGRESS_MAX; 4406 : - 4407 400 : tick_cpu = state->progress_tick_misc[state->progress_ptr] - 4408 200 : + state->progress_tick_sched[state->progress_ptr] - 4409 200 : + state->progress_tick_raid[state->progress_ptr] - 4410 200 : + state->progress_tick_hash[state->progress_ptr]; - 4411 200 : tick_total = tick_cpu + state->progress_tick_io[state->progress_ptr]; + 4407 364 : tick_cpu = state->progress_tick_misc[state->progress_ptr] + 4408 182 : + state->progress_tick_sched[state->progress_ptr] + 4409 182 : + state->progress_tick_raid[state->progress_ptr] + 4410 182 : + state->progress_tick_hash[state->progress_ptr]; + 4411 182 : tick_total = tick_cpu + state->progress_tick_io[state->progress_ptr]; 4412 : - 4413 400 : oldest_tick_cpu = state->progress_tick_misc[oldest] - 4414 200 : + state->progress_tick_sched[oldest] - 4415 200 : + state->progress_tick_raid[oldest] - 4416 200 : + state->progress_tick_hash[oldest]; - 4417 200 : oldest_tick_total = oldest_tick_cpu + state->progress_tick_io[oldest]; + 4413 364 : oldest_tick_cpu = state->progress_tick_misc[oldest] + 4414 182 : + state->progress_tick_sched[oldest] + 4415 182 : + state->progress_tick_raid[oldest] + 4416 182 : + state->progress_tick_hash[oldest]; + 4417 182 : oldest_tick_total = oldest_tick_cpu + state->progress_tick_io[oldest]; 4418 : - 4419 200 : delta_time = now - state->progress_time[oldest]; - 4420 200 : delta_pos = countpos - state->progress_pos[oldest]; - 4421 200 : delta_size = countsize - state->progress_size[oldest]; - 4422 200 : delta_tick_cpu = tick_cpu - oldest_tick_cpu; - 4423 200 : delta_tick_total = tick_total - oldest_tick_total; + 4419 182 : delta_time = now - state->progress_time[oldest]; + 4420 182 : delta_pos = countpos - state->progress_pos[oldest]; + 4421 182 : delta_size = countsize - state->progress_size[oldest]; + 4422 182 : delta_tick_cpu = tick_cpu - oldest_tick_cpu; + 4423 182 : delta_tick_total = tick_total - oldest_tick_total; 4424 : 4425 : /* estimate the speed in MB/s */ - 4426 200 : if (delta_time != 0) - 4427 200 : out_speed = (unsigned)(delta_size / MEGA / delta_time); + 4426 182 : if (delta_time != 0) + 4427 182 : out_speed = (unsigned)(delta_size / MEGA / delta_time); 4428 : 4429 : /* estimate the cpu usage percentage */ - 4430 200 : if (delta_tick_total != 0) - 4431 82 : out_cpu = (unsigned)(delta_tick_cpu * 100U / delta_tick_total); + 4430 182 : if (delta_tick_total != 0) + 4431 77 : out_cpu = (unsigned)(delta_tick_cpu * 100U / delta_tick_total); 4432 : 4433 : /* estimate the remaining time in minutes */ - 4434 200 : if (delta_pos != 0) - 4435 200 : out_eta = (countmax - countpos) * delta_time / (60 * delta_pos); + 4434 182 : if (delta_pos != 0) + 4435 182 : out_eta = (countmax - countpos) * delta_time / (60 * delta_pos); 4436 : - 4437 200 : if (state->opt.force_stats) { + 4437 182 : if (state->opt.force_stats) { 4438 0 : os_clear(); 4439 0 : state_progress_graph(state, io, state->progress_ptr, oldest); 4440 : } 4441 : 4442 : /* we have the output value */ - 4443 200 : out_computed = 1; + 4443 182 : out_computed = 1; 4444 : } 4445 : - 4446 399 : if (state->opt.gui) { - 4447 6 : log_tag("run:pos:%u:%u:%" PRIu64 ":%u:%u:%u:%u:%" PRIu64 "\n", blockpos, countpos, countsize, out_perc, out_eta, out_speed, out_cpu, (uint64_t)elapsed); - 4448 6 : log_flush(); + 4446 381 : if (state->opt.gui) { + 4447 8 : log_tag("run:pos:%u:%u:%" PRIu64 ":%u:%u:%u:%u:%" PRIu64 "\n", blockpos, countpos, countsize, out_perc, out_eta, out_speed, out_cpu, (uint64_t)elapsed); + 4448 8 : log_flush(); 4449 : } else { - 4450 393 : msg_bar("%u%%, %u MB", out_perc, (unsigned)(countsize / MEGA)); - 4451 393 : if (out_computed) { - 4452 199 : msg_bar(", %u MB/s", out_speed); - 4453 199 : msg_bar(", CPU %u%%", out_cpu); - 4454 199 : msg_bar(", %u:%02u ETA", out_eta / 60, out_eta % 60); + 4450 373 : msg_bar("%u%%, %u MB", out_perc, (unsigned)(countsize / MEGA)); + 4451 373 : if (out_computed) { + 4452 179 : msg_bar(", %u MB/s", out_speed); + 4453 179 : msg_bar(", CPU %u%%", out_cpu); + 4454 179 : msg_bar(", %u:%02u ETA", out_eta / 60, out_eta % 60); 4455 : } - 4456 393 : msg_bar("%s\r", PROGRESS_CLEAR); - 4457 393 : msg_flush(); + 4456 373 : msg_bar("%s\r", PROGRESS_CLEAR); + 4457 373 : msg_flush(); 4458 : } 4459 : 4460 : /* next position to fill */ - 4461 399 : ++state->progress_ptr; - 4462 399 : if (state->progress_ptr >= PROGRESS_MAX) + 4461 381 : ++state->progress_ptr; + 4462 381 : if (state->progress_ptr >= PROGRESS_MAX) 4463 0 : state->progress_ptr -= PROGRESS_MAX; 4464 : 4465 : /* one more measure */ - 4466 399 : ++state->progress_tick; + 4466 381 : ++state->progress_tick; 4467 : } 4468 : 4469 : /* stop if requested */ - 4470 1073409 : if (global_interrupt) { + 4470 1073497 : if (global_interrupt) { 4471 : /* LCOV_EXCL_START */ 4472 : if (!state->opt.gui) { 4473 : log_fatal("\n"); @@ -4541,7 +4541,7 @@ 4479 : /* LCOV_EXCL_STOP */ 4480 : } 4481 : - 4482 1073409 : return 0; + 4482 1073497 : return 0; 4483 : } 4484 : 4485 104 : void state_usage_waste(struct snapraid_state* state) @@ -4551,83 +4551,83 @@ 4489 104 : state->tick_last = now; 4490 104 : } 4491 : - 4492 1063055 : void state_usage_misc(struct snapraid_state* state) + 4492 1063671 : void state_usage_misc(struct snapraid_state* state) 4493 : { - 4494 1063055 : uint64_t now = tick(); - 4495 1063055 : uint64_t delta = now - state->tick_last; + 4494 1063671 : uint64_t now = tick(); + 4495 1063671 : uint64_t delta = now - state->tick_last; 4496 : 4497 : /* increment the time spent in computations */ - 4498 1063055 : state->tick_misc += delta; + 4498 1063671 : state->tick_misc += delta; 4499 : - 4500 1063055 : state->tick_last = now; - 4501 1063055 : } + 4500 1063671 : state->tick_last = now; + 4501 1063671 : } 4502 : - 4503 149836 : void state_usage_sched(struct snapraid_state* state) + 4503 149924 : void state_usage_sched(struct snapraid_state* state) 4504 : { - 4505 149836 : uint64_t now = tick(); - 4506 149836 : uint64_t delta = now - state->tick_last; + 4505 149924 : uint64_t now = tick(); + 4506 149924 : uint64_t delta = now - state->tick_last; 4507 : 4508 : /* increment the time spent in computations */ - 4509 149836 : state->tick_sched += delta; + 4509 149924 : state->tick_sched += delta; 4510 : - 4511 149836 : state->tick_last = now; - 4512 149836 : } + 4511 149924 : state->tick_last = now; + 4512 149924 : } 4513 : - 4514 140365 : void state_usage_raid(struct snapraid_state* state) + 4514 140438 : void state_usage_raid(struct snapraid_state* state) 4515 : { - 4516 140365 : uint64_t now = tick(); - 4517 140365 : uint64_t delta = now - state->tick_last; + 4516 140438 : uint64_t now = tick(); + 4517 140438 : uint64_t delta = now - state->tick_last; 4518 : 4519 : /* increment the time spent in computations */ - 4520 140365 : state->tick_raid += delta; + 4520 140438 : state->tick_raid += delta; 4521 : - 4522 140365 : state->tick_last = now; - 4523 140365 : } + 4522 140438 : state->tick_last = now; + 4523 140438 : } 4524 : - 4525 776808 : void state_usage_hash(struct snapraid_state* state) + 4525 777357 : void state_usage_hash(struct snapraid_state* state) 4526 : { - 4527 776808 : uint64_t now = tick(); - 4528 776808 : uint64_t delta = now - state->tick_last; + 4527 777357 : uint64_t now = tick(); + 4528 777357 : uint64_t delta = now - state->tick_last; 4529 : 4530 : /* increment the time spent in computations */ - 4531 776808 : state->tick_hash += delta; + 4531 777357 : state->tick_hash += delta; 4532 : - 4533 776808 : state->tick_last = now; - 4534 776808 : } + 4533 777357 : state->tick_last = now; + 4534 777357 : } 4535 : - 4536 912357 : void state_usage_disk(struct snapraid_state* state, struct snapraid_handle* handle_map, unsigned* waiting_map, unsigned waiting_mac) + 4536 912885 : void state_usage_disk(struct snapraid_state* state, struct snapraid_handle* handle_map, unsigned* waiting_map, unsigned waiting_mac) 4537 : { - 4538 912357 : uint64_t now = tick(); - 4539 912357 : uint64_t delta = now - state->tick_last; + 4538 912885 : uint64_t now = tick(); + 4539 912885 : uint64_t delta = now - state->tick_last; 4540 : unsigned i; 4541 : 4542 : /* increment the time spent in the data disks */ - 4543 956230 : for (i = 0; i < waiting_mac; ++i) { - 4544 43873 : struct snapraid_disk* disk = handle_map[waiting_map[i]].disk; + 4543 955948 : for (i = 0; i < waiting_mac; ++i) { + 4544 43063 : struct snapraid_disk* disk = handle_map[waiting_map[i]].disk; 4545 : - 4546 43873 : if (!disk) - 4547 6 : continue; + 4546 43063 : if (!disk) + 4547 16 : continue; 4548 : - 4549 43867 : disk->tick += delta; + 4549 43047 : disk->tick += delta; 4550 : } - 4551 912357 : state->tick_io += delta; + 4551 912885 : state->tick_io += delta; 4552 : - 4553 912357 : state->tick_last = now; - 4554 912357 : } + 4553 912885 : state->tick_last = now; + 4554 912885 : } 4555 : - 4556 774023 : void state_usage_parity(struct snapraid_state* state, unsigned* waiting_map, unsigned waiting_mac) + 4556 774551 : void state_usage_parity(struct snapraid_state* state, unsigned* waiting_map, unsigned waiting_mac) 4557 : { - 4558 774023 : uint64_t now = tick(); - 4559 774023 : uint64_t delta = now - state->tick_last; + 4558 774551 : uint64_t now = tick(); + 4559 774551 : uint64_t delta = now - state->tick_last; 4560 : unsigned i; 4561 : 4562 : /* increment the time spent in the parity disk */ - 4563 851328 : for (i = 0; i < waiting_mac; ++i) - 4564 77305 : state->parity[waiting_map[i]].tick += delta; - 4565 774023 : state->tick_io += delta; + 4563 851244 : for (i = 0; i < waiting_mac; ++i) + 4564 76693 : state->parity[waiting_map[i]].tick += delta; + 4565 774551 : state->tick_io += delta; 4566 : - 4567 774023 : state->tick_last = now; - 4568 774023 : } + 4567 774551 : state->tick_last = now; + 4568 774551 : } 4569 : 4570 96 : void state_usage_print(struct snapraid_state* state) 4571 : { @@ -4641,22 +4641,22 @@ 4579 1 : state_progress_graph(state, 0, state->progress_ptr, PROGRESS_MAX); 4580 : } 4581 : - 4582 496 : void state_fscheck(struct snapraid_state* state, const char* ope) + 4582 498 : void state_fscheck(struct snapraid_state* state, const char* ope) 4583 : { 4584 : tommy_node* i; 4585 : 4586 : /* check the file-system on all disks */ - 4587 3466 : for (i = state->disklist; i != 0; i = i->next) { - 4588 2970 : struct snapraid_disk* disk = i->data; + 4587 3480 : for (i = state->disklist; i != 0; i = i->next) { + 4588 2982 : struct snapraid_disk* disk = i->data; 4589 : - 4590 2970 : if (fs_check(disk) != 0) { + 4590 2982 : if (fs_check(disk) != 0) { 4591 : /* LCOV_EXCL_START */ 4592 : log_fatal("Internal inconsistency in file-system for disk '%s' %s\n", disk->name, ope); 4593 : os_abort(); 4594 : /* LCOV_EXCL_STOP */ 4595 : } 4596 : } - 4597 496 : } + 4597 498 : } 4598 : 4599 1 : void generate_configuration(const char* path) 4600 : { diff --git a/cov/cmdline/status.c.gcov.html b/cov/cmdline/status.c.gcov.html index 6945eda7..1d1e972c 100644 --- a/cov/cmdline/status.c.gcov.html +++ b/cov/cmdline/status.c.gcov.html @@ -395,10 +395,10 @@ 333 39752 : scrub_time = info_get_time(info); 334 : 335 39752 : if (info_get_justsynced(info)) { - 336 20453 : ++unscrubbed_blocks; + 336 20456 : ++unscrubbed_blocks; 337 : 338 : /* mark the time as not scrubbed */ - 339 20453 : scrub_time |= TIME_NEW; + 339 20456 : scrub_time |= TIME_NEW; 340 : } 341 : 342 39752 : timemap[count++] = scrub_time; @@ -430,16 +430,16 @@ 368 : /* output the info map */ 369 8 : i = 0; 370 8 : log_tag("info_count:%u\n", count); - 371 35 : while (i < count) { - 372 19 : unsigned j = i + 1; - 373 39771 : while (j < count && timemap[i] == timemap[j]) - 374 39733 : ++j; - 375 19 : if ((timemap[i] & TIME_NEW) == 0) { + 371 33 : while (i < count) { + 372 17 : unsigned j = i + 1; + 373 39769 : while (j < count && timemap[i] == timemap[j]) + 374 39735 : ++j; + 375 17 : if ((timemap[i] & TIME_NEW) == 0) { 376 7 : log_tag("info_time:%" PRIu64 ":%u:scrubbed\n", (uint64_t)timemap[i], j - i); 377 : } else { - 378 12 : log_tag("info_time:%" PRIu64 ":%u:new\n", (uint64_t)(timemap[i] & ~TIME_NEW), j - i); + 378 10 : log_tag("info_time:%" PRIu64 ":%u:new\n", (uint64_t)(timemap[i] & ~TIME_NEW), j - i); 379 : } - 380 19 : i = j; + 380 17 : i = j; 381 : } 382 : 383 8 : oldest = timemap[0]; @@ -462,9 +462,9 @@ 400 560 : step_new = 0; 401 40872 : while (barpos < count && timemap[barpos] <= limit) { 402 39752 : if ((timemap[barpos] & TIME_NEW) != 0) - 403 20453 : ++step_new; + 403 20456 : ++step_new; 404 : else - 405 19299 : ++step_scrubbed; + 405 19296 : ++step_scrubbed; 406 39752 : ++barpos; 407 : } 408 : @@ -494,20 +494,20 @@ 432 8400 : unsigned scrubbed = bar_scrubbed[x]; 433 : 434 8400 : if (both > pivot_upper) { - 435 145 : if (scrubbed > pivot_lower) + 435 144 : if (scrubbed > pivot_lower) 436 63 : printf("*"); 437 : else - 438 82 : printf("o"); - 439 8255 : } else if (both > pivot_lower) { - 440 19 : if (scrubbed == both) + 438 81 : printf("o"); + 439 8256 : } else if (both > pivot_lower) { + 440 17 : if (scrubbed == both) 441 7 : printf("*"); 442 : else - 443 12 : printf("o"); + 443 10 : printf("o"); 444 : } else { - 445 8236 : if (y == GRAPH_ROW - 1) - 446 541 : printf("_"); + 445 8239 : if (y == GRAPH_ROW - 1) + 446 543 : printf("_"); 447 : else - 448 7695 : printf(" "); + 448 7696 : printf(" "); 449 : } 450 : } 451 120 : printf("\n"); @@ -559,19 +559,19 @@ 497 : 498 : /* print some of the errors */ 499 2 : bad_print = 0; - 500 720 : for (i = 0; i < blockmax; ++i) { - 501 720 : snapraid_info info = info_get(&state->infoarr, i); + 500 723 : for (i = 0; i < blockmax; ++i) { + 501 723 : snapraid_info info = info_get(&state->infoarr, i); 502 : 503 : /* skip unused blocks */ - 504 720 : if (info == 0) + 504 723 : if (info == 0) 505 0 : continue; 506 : - 507 720 : if (info_get_bad(info)) { + 507 723 : if (info_get_bad(info)) { 508 202 : printf(" %u", i); 509 202 : ++bad_print; 510 : } 511 : - 512 720 : if (bad_print > 100) { + 512 723 : if (bad_print > 100) { 513 2 : printf(" and %u more...", bad - bad_print); 514 2 : break; 515 : } diff --git a/cov/cmdline/stream.c.func-sort-c.html b/cov/cmdline/stream.c.func-sort-c.html index 7f51850b..4f39cf2c 100644 --- a/cov/cmdline/stream.c.func-sort-c.html +++ b/cov/cmdline/stream.c.func-sort-c.html @@ -61,23 +61,23 @@ swrite - 20725275 + 20724964 sgetb32 - 18668535 + 18667054 sread - 12810720 + 12810372 sgetb64 - 10849874 + 10849502 sputb32 - 9127648 + 9127337 sputb64 @@ -85,7 +85,7 @@ sgetbs - 3877236 + 3877163 sputbs @@ -93,11 +93,11 @@ sfill - 607111 + 607122 sgetc_uncached - 298847 + 298855 sflush @@ -105,31 +105,31 @@ sgettok - 8138 + 8162 sgetline - 5410 + 5425 sgetlasttok - 5370 + 5384 sclose - 1949 + 1951 sopen_read - 1834 + 1836 scrc - 1687 + 1688 sdeplete - 1142 + 1144 sopen_multi_file @@ -137,15 +137,15 @@ sgetble32 - 379 + 380 sgetu32 - 264 + 265 shandle - 252 + 253 scrc_stream diff --git a/cov/cmdline/stream.c.func.html b/cov/cmdline/stream.c.func.html index 8191ded9..4739e4bf 100644 --- a/cov/cmdline/stream.c.func.html +++ b/cov/cmdline/stream.c.func.html @@ -61,11 +61,11 @@ sclose - 1949 + 1951 scrc - 1687 + 1688 scrc_stream @@ -73,11 +73,11 @@ sdeplete - 1142 + 1144 sfill - 607111 + 607122 sflush @@ -85,43 +85,43 @@ sgetb32 - 18668535 + 18667054 sgetb64 - 10849874 + 10849502 sgetble32 - 379 + 380 sgetbs - 3877236 + 3877163 sgetc_uncached - 298847 + 298855 sgetlasttok - 5370 + 5384 sgetline - 5410 + 5425 sgettok - 8138 + 8162 sgetu32 - 264 + 265 shandle - 252 + 253 sopen_multi_file @@ -133,7 +133,7 @@ sopen_read - 1834 + 1836 sopen_write @@ -141,7 +141,7 @@ sputb32 - 9127648 + 9127337 sputb64 @@ -157,7 +157,7 @@ sread - 12810720 + 12810372 ssync @@ -169,7 +169,7 @@ swrite - 20725275 + 20724964
diff --git a/cov/cmdline/stream.c.gcov.html b/cov/cmdline/stream.c.gcov.html index ddbc7331..bec8536c 100644 --- a/cov/cmdline/stream.c.gcov.html +++ b/cov/cmdline/stream.c.gcov.html @@ -88,19 +88,19 @@ 26 : 27 : unsigned STREAM_SIZE = 64 * 1024; 28 : - 29 1834 : STREAM* sopen_read(const char* file) + 29 1836 : STREAM* sopen_read(const char* file) 30 : { 31 : #if HAVE_POSIX_FADVISE 32 : int ret; 33 : #endif - 34 1834 : STREAM* s = malloc_nofail(sizeof(STREAM)); + 34 1836 : STREAM* s = malloc_nofail(sizeof(STREAM)); 35 : - 36 1834 : s->handle_size = 1; - 37 1834 : s->handle = malloc_nofail(sizeof(struct stream_handle)); + 36 1836 : s->handle_size = 1; + 37 1836 : s->handle = malloc_nofail(sizeof(struct stream_handle)); 38 : - 39 1834 : pathcpy(s->handle[0].path, sizeof(s->handle[0].path), file); - 40 1834 : s->handle[0].f = open(file, O_RDONLY | O_BINARY | O_SEQUENTIAL); - 41 1834 : if (s->handle[0].f == -1) { + 39 1836 : pathcpy(s->handle[0].path, sizeof(s->handle[0].path), file); + 40 1836 : s->handle[0].f = open(file, O_RDONLY | O_BINARY | O_SEQUENTIAL); + 41 1836 : if (s->handle[0].f == -1) { 42 50 : free(s->handle); 43 50 : free(s); 44 50 : return 0; @@ -108,13 +108,13 @@ 46 : 47 : #if HAVE_POSIX_FADVISE 48 : /* advise sequential access */ - 49 1784 : ret = posix_fadvise(s->handle[0].f, 0, 0, POSIX_FADV_SEQUENTIAL); - 50 1784 : if (ret == ENOSYS) { + 49 1786 : ret = posix_fadvise(s->handle[0].f, 0, 0, POSIX_FADV_SEQUENTIAL); + 50 1786 : if (ret == ENOSYS) { 51 0 : log_fatal("WARNING! fadvise() is not supported in this platform. Performance may not be optimal!\n"); 52 : /* call is not supported, like in armhf, see posix_fadvise manpage */ 53 0 : ret = 0; 54 : } - 55 1784 : if (ret != 0) { + 55 1786 : if (ret != 0) { 56 : /* LCOV_EXCL_START */ 57 : close(s->handle[0].f); 58 : free(s->handle); @@ -125,18 +125,18 @@ 63 : } 64 : #endif 65 : - 66 1784 : s->buffer = malloc_nofail_test(STREAM_SIZE); - 67 1784 : s->pos = s->buffer; - 68 1784 : s->end = s->buffer; - 69 1784 : s->state = STREAM_STATE_READ; - 70 1784 : s->state_index = 0; - 71 1784 : s->offset = 0; - 72 1784 : s->offset_uncached = 0; - 73 1784 : s->crc = 0; - 74 1784 : s->crc_uncached = 0; - 75 1784 : s->crc_stream = CRC_IV; + 66 1786 : s->buffer = malloc_nofail_test(STREAM_SIZE); + 67 1786 : s->pos = s->buffer; + 68 1786 : s->end = s->buffer; + 69 1786 : s->state = STREAM_STATE_READ; + 70 1786 : s->state_index = 0; + 71 1786 : s->offset = 0; + 72 1786 : s->offset_uncached = 0; + 73 1786 : s->crc = 0; + 74 1786 : s->crc_uncached = 0; + 75 1786 : s->crc_stream = CRC_IV; 76 : - 77 1784 : return s; + 77 1786 : return s; 78 : } 79 : 80 167 : STREAM* sopen_multi_write(unsigned count) @@ -214,12 +214,12 @@ 152 0 : return s; 153 : } 154 : - 155 1949 : int sclose(STREAM* s) + 155 1951 : int sclose(STREAM* s) 156 : { - 157 1949 : int fail = 0; + 157 1951 : int fail = 0; 158 : unsigned i; 159 : - 160 1949 : if (s->state == STREAM_STATE_WRITE) { + 160 1951 : if (s->state == STREAM_STATE_WRITE) { 161 167 : if (sflush(s) != 0) { 162 : /* LCOV_EXCL_START */ 163 : fail = 1; @@ -227,102 +227,102 @@ 165 : } 166 : } 167 : - 168 4871 : for (i = 0; i < s->handle_size; ++i) { - 169 2922 : if (close(s->handle[i].f) != 0) { + 168 4875 : for (i = 0; i < s->handle_size; ++i) { + 169 2924 : if (close(s->handle[i].f) != 0) { 170 : /* LCOV_EXCL_START */ 171 : fail = 1; 172 : /* LCOV_EXCL_STOP */ 173 : } 174 : } 175 : - 176 1949 : free(s->handle); - 177 1949 : free(s->buffer); - 178 1949 : free(s); + 176 1951 : free(s->handle); + 177 1951 : free(s->buffer); + 178 1951 : free(s); 179 : - 180 1949 : if (fail) { + 180 1951 : if (fail) { 181 : /* LCOV_EXCL_START */ 182 : return -1; 183 : /* LCOV_EXCL_STOP */ 184 : } 185 : - 186 1949 : return 0; + 186 1951 : return 0; 187 : } 188 : - 189 252 : int shandle(STREAM* s) + 189 253 : int shandle(STREAM* s) 190 : { - 191 252 : if (!s->handle_size) { + 191 253 : if (!s->handle_size) { 192 : /* LCOV_EXCL_START */ 193 : return -1; 194 : /* LCOV_EXCL_STOP */ 195 : } 196 : - 197 252 : return s->handle[0].f; + 197 253 : return s->handle[0].f; 198 : } 199 : 200 : /** 201 : * Fill the read stream buffer. 202 : * \return 0 if at least on char is read, or EOF on error. 203 : */ - 204 607111 : static int sfill(STREAM* s) + 204 607122 : static int sfill(STREAM* s) 205 : { 206 : ssize_t ret; 207 : - 208 607111 : if (s->state != STREAM_STATE_READ) { + 208 607122 : if (s->state != STREAM_STATE_READ) { 209 : /* LCOV_EXCL_START */ 210 : return EOF; 211 : /* LCOV_EXCL_STOP */ 212 : } 213 : - 214 606059 : ret = read(s->handle[0].f, s->buffer, STREAM_SIZE); + 214 606066 : ret = read(s->handle[0].f, s->buffer, STREAM_SIZE); 215 : - 216 606062 : if (ret < 0) { + 216 606066 : if (ret < 0) { 217 : /* LCOV_EXCL_START */ 218 : s->state = STREAM_STATE_ERROR; 219 : return EOF; 220 : /* LCOV_EXCL_STOP */ 221 : } - 222 606062 : if (ret == 0) { - 223 1655 : s->state = STREAM_STATE_EOF; - 224 1655 : return EOF; + 222 606066 : if (ret == 0) { + 223 1657 : s->state = STREAM_STATE_EOF; + 224 1657 : return EOF; 225 : } 226 : 227 : /* update the crc */ - 228 604407 : s->crc_uncached = s->crc; - 229 604407 : s->crc = crc32c(s->crc, s->buffer, ret); + 228 604409 : s->crc_uncached = s->crc; + 229 604409 : s->crc = crc32c(s->crc, s->buffer, ret); 230 : 231 : /* update the offset */ - 232 604404 : s->offset_uncached = s->offset; - 233 604404 : s->offset += ret; + 232 604407 : s->offset_uncached = s->offset; + 233 604407 : s->offset += ret; 234 : - 235 604404 : s->pos = s->buffer; - 236 604404 : s->end = s->buffer + ret; + 235 604407 : s->pos = s->buffer; + 236 604407 : s->end = s->buffer + ret; 237 : - 238 604404 : return 0; + 238 604407 : return 0; 239 : } 240 : - 241 1142 : int sdeplete(STREAM* s, unsigned char* last) + 241 1144 : int sdeplete(STREAM* s, unsigned char* last) 242 : { 243 : /* last four bytes */ - 244 1142 : last[0] = 0; - 245 1142 : last[1] = 0; - 246 1142 : last[2] = 0; - 247 1142 : last[3] = 0; + 244 1144 : last[0] = 0; + 245 1144 : last[1] = 0; + 246 1144 : last[2] = 0; + 247 1144 : last[3] = 0; 248 : 249 : while (1) { 250 : /* increase the position up to 4 bytes before the end */ - 251 308265 : if (s->pos + 4 <= s->end) + 251 308267 : if (s->pos + 4 <= s->end) 252 148388 : s->pos = s->end - 4; 253 : 254 : /* insert the last 4 bytes */ - 255 1469850 : while (s->pos < s->end) { - 256 853320 : last[0] = last[1]; - 257 853320 : last[1] = last[2]; - 258 853320 : last[2] = last[3]; - 259 853320 : last[3] = *s->pos++; + 255 1469851 : while (s->pos < s->end) { + 256 853317 : last[0] = last[1]; + 257 853317 : last[1] = last[2]; + 258 853317 : last[2] = last[3]; + 259 853317 : last[3] = *s->pos++; 260 : } 261 : 262 : /* fill again the buffer until the end of the file */ - 263 308265 : if (sfill(s) != 0) { + 263 308267 : if (sfill(s) != 0) { 264 : /* on error fail */ 265 1141 : if (serror(s)) { 266 : /* LCOV_EXCL_START */ @@ -331,11 +331,11 @@ 269 : } 270 : 271 : /* on EOF terminate */ - 272 1141 : break; + 272 1140 : break; 273 : } 274 307123 : } 275 : - 276 1141 : return 0; + 276 1140 : return 0; 277 : } 278 : 279 39049 : int sflush(STREAM* s) @@ -390,9 +390,9 @@ 328 1 : return s->offset_uncached + (s->pos - s->buffer); 329 : } 330 : - 331 1687 : uint32_t scrc(STREAM*s) + 331 1688 : uint32_t scrc(STREAM*s) 332 : { - 333 1687 : return crc32c(s->crc_uncached, s->buffer, s->pos - s->buffer); + 333 1688 : return crc32c(s->crc_uncached, s->buffer, s->pos - s->buffer); 334 : } 335 : 336 167 : uint32_t scrc_stream(STREAM*s) @@ -400,90 +400,90 @@ 338 167 : return s->crc_stream ^ CRC_IV; 339 : } 340 : - 341 298847 : int sgetc_uncached(STREAM* s) + 341 298855 : int sgetc_uncached(STREAM* s) 342 : { 343 : /* if at the end of the buffer, fill it */ - 344 298847 : if (s->pos == s->end && sfill(s) != 0) - 345 1566 : return EOF; - 346 297281 : return *s->pos++; + 344 298855 : if (s->pos == s->end && sfill(s) != 0) + 345 1572 : return EOF; + 346 297283 : return *s->pos++; 347 : } 348 : - 349 8138 : int sgettok(STREAM* f, char* str, int size) + 349 8162 : int sgettok(STREAM* f, char* str, int size) 350 : { - 351 8138 : char* i = str; - 352 8138 : char* send = str + size; + 351 8162 : char* i = str; + 352 8162 : char* send = str + size; 353 : int c; 354 : 355 : while (1) { - 356 54240 : c = sgetc(f); - 357 54240 : if (c == EOF) { - 358 263 : break; + 356 54379 : c = sgetc(f); + 357 54379 : if (c == EOF) { + 358 264 : break; 359 : } - 360 53977 : if (c == ' ' || c == '\t') { - 361 7611 : sungetc(c, f); - 362 7611 : break; + 360 54115 : if (c == ' ' || c == '\t') { + 361 7633 : sungetc(c, f); + 362 7633 : break; 363 : } - 364 46366 : if (c == '\n') { + 364 46482 : if (c == '\n') { 365 : /* remove ending carrige return to support the Windows CR+LF format */ - 366 264 : if (i != str && i[-1] == '\r') + 366 265 : if (i != str && i[-1] == '\r') 367 0 : --i; - 368 264 : sungetc(c, f); - 369 264 : break; + 368 265 : sungetc(c, f); + 369 265 : break; 370 : } 371 : - 372 46102 : *i++ = c; + 372 46217 : *i++ = c; 373 : - 374 46102 : if (i == send) { + 374 46217 : if (i == send) { 375 : /* LCOV_EXCL_START */ 376 : return -1; 377 : /* LCOV_EXCL_STOP */ 378 : } - 379 46102 : } + 379 46217 : } 380 : - 381 8138 : *i = 0; + 381 8162 : *i = 0; 382 : - 383 8138 : return i - str; + 383 8162 : return i - str; 384 : } 385 : - 386 12810720 : int sread(STREAM* f, void* void_data, unsigned size) + 386 12810372 : int sread(STREAM* f, void* void_data, unsigned size) 387 : { - 388 12810720 : unsigned char* data = void_data; + 388 12810372 : unsigned char* data = void_data; 389 : 390 : /* if there is enough space in memory */ - 391 12810720 : if (sptrlookup(f, size)) { + 391 12810372 : if (sptrlookup(f, size)) { 392 : /* optimized version with all the data in memory */ - 393 12784282 : unsigned char* pos = sptrget(f); + 393 12784238 : unsigned char* pos = sptrget(f); 394 : 395 : /* copy it */ - 396 217726263 : while (size--) - 397 192157699 : *data++ = *pos++; + 396 217725604 : while (size--) + 397 192157128 : *data++ = *pos++; 398 : - 399 12784282 : sptrset(f, pos); + 399 12784238 : sptrset(f, pos); 400 : } else { 401 : /* standard version using sgetc() */ - 402 1380323 : while (size--) { - 403 1327447 : int c = sgetc(f); - 404 1327447 : if (c == EOF) { + 402 1375577 : while (size--) { + 403 1323309 : int c = sgetc(f); + 404 1323309 : if (c == EOF) { 405 : /* LCOV_EXCL_START */ 406 : return -1; 407 : /* LCOV_EXCL_STOP */ 408 : } 409 : - 410 1327447 : *data++ = c; + 410 1323309 : *data++ = c; 411 : } 412 : } 413 : - 414 12810720 : return 0; + 414 12810372 : return 0; 415 : } 416 : - 417 5410 : int sgetline(STREAM* f, char* str, int size) + 417 5425 : int sgetline(STREAM* f, char* str, int size) 418 : { - 419 5410 : char* i = str; - 420 5410 : char* send = str + size; + 419 5425 : char* i = str; + 420 5425 : char* send = str + size; 421 : int c; 422 : 423 : /* if there is enough data in memory */ - 424 5410 : if (sptrlookup(f, size)) { + 424 5425 : if (sptrlookup(f, size)) { 425 : /* optimized version with all the data in memory */ 426 0 : unsigned char* pos = sptrget(f); 427 : @@ -509,75 +509,75 @@ 447 0 : sptrset(f, pos); 448 : } else { 449 : while (1) { - 450 139082 : c = sgetc(f); - 451 139082 : if (c == EOF) { + 450 139326 : c = sgetc(f); + 451 139326 : if (c == EOF) { 452 : /* LCOV_EXCL_START */ 453 : break; 454 : /* LCOV_EXCL_STOP */ 455 : } - 456 139082 : if (c == '\n') { + 456 139326 : if (c == '\n') { 457 : /* remove ending carrige return to support the Windows CR+LF format */ - 458 5410 : if (i != str && i[-1] == '\r') + 458 5425 : if (i != str && i[-1] == '\r') 459 0 : --i; - 460 5410 : sungetc(c, f); - 461 5410 : break; + 460 5425 : sungetc(c, f); + 461 5425 : break; 462 : } 463 : - 464 133672 : *i++ = c; + 464 133901 : *i++ = c; 465 : - 466 133672 : if (i == send) { + 466 133901 : if (i == send) { 467 : /* LCOV_EXCL_START */ 468 : return -1; 469 : /* LCOV_EXCL_STOP */ 470 : } - 471 133672 : } + 471 133901 : } 472 : } 473 : - 474 5410 : *i = 0; + 474 5425 : *i = 0; 475 : - 476 5410 : return i - str; + 476 5425 : return i - str; 477 : } 478 : - 479 5370 : int sgetlasttok(STREAM* f, char* str, int size) + 479 5384 : int sgetlasttok(STREAM* f, char* str, int size) 480 : { 481 : int ret; 482 : - 483 5370 : ret = sgetline(f, str, size); - 484 5370 : if (ret < 0) { + 483 5384 : ret = sgetline(f, str, size); + 484 5384 : if (ret < 0) { 485 : /* LCOV_EXCL_START */ 486 : return ret; 487 : /* LCOV_EXCL_STOP */ 488 : } 489 : - 490 10740 : while (ret > 0 && (str[ret - 1] == ' ' || str[ret - 1] == '\t')) + 490 10768 : while (ret > 0 && (str[ret - 1] == ' ' || str[ret - 1] == '\t')) 491 0 : --ret; 492 : - 493 5370 : str[ret] = 0; + 493 5384 : str[ret] = 0; 494 : - 495 5370 : return ret; + 495 5384 : return ret; 496 : } 497 : - 498 264 : int sgetu32(STREAM* f, uint32_t* value) + 498 265 : int sgetu32(STREAM* f, uint32_t* value) 499 : { 500 : int c; 501 : - 502 264 : c = sgetc(f); - 503 264 : if (c >= '0' && c <= '9') { + 502 265 : c = sgetc(f); + 503 265 : if (c >= '0' && c <= '9') { 504 : uint32_t v; 505 : - 506 264 : v = c - '0'; + 506 265 : v = c - '0'; 507 : - 508 264 : c = sgetc(f); - 509 528 : while (c >= '0' && c <= '9') { + 508 265 : c = sgetc(f); + 509 530 : while (c >= '0' && c <= '9') { 510 0 : v *= 10; 511 0 : v += c - '0'; 512 0 : c = sgetc(f); 513 : } 514 : - 515 264 : *value = v; + 515 265 : *value = v; 516 : - 517 264 : sungetc(c, f); - 518 264 : return 0; + 517 265 : sungetc(c, f); + 518 265 : return 0; 519 : } else { 520 : /* LCOV_EXCL_START */ 521 : /* nothing read */ @@ -586,122 +586,122 @@ 524 : } 525 : } 526 : - 527 18668535 : int sgetb32(STREAM* f, uint32_t* value) + 527 18667054 : int sgetb32(STREAM* f, uint32_t* value) 528 : { 529 : uint32_t v; 530 : unsigned char b; 531 : unsigned char s; 532 : int c; 533 : - 534 18668535 : v = 0; - 535 18668535 : s = 0; + 534 18667054 : v = 0; + 535 18667054 : s = 0; 536 : loop: - 537 36576764 : c = sgetc(f); - 538 36576764 : if (c == EOF) { + 537 35516819 : c = sgetc(f); + 538 35516819 : if (c == EOF) { 539 : /* LCOV_EXCL_START */ 540 : return -1; 541 : /* LCOV_EXCL_STOP */ 542 : } 543 : - 544 36576764 : b = (unsigned char)c; - 545 36576764 : if ((b & 0x80) == 0) { - 546 17908229 : v |= (uint32_t)b << s; - 547 17908229 : s += 7; - 548 17908229 : if (s >= 32) { + 544 35516819 : b = (unsigned char)c; + 545 35516819 : if ((b & 0x80) == 0) { + 546 16849766 : v |= (uint32_t)b << s; + 547 16849766 : s += 7; + 548 16849766 : if (s >= 32) { 549 : /* LCOV_EXCL_START */ 550 : return -1; 551 : /* LCOV_EXCL_STOP */ 552 : } - 553 17908229 : goto loop; + 553 16849765 : goto loop; 554 : } 555 : - 556 18668535 : v |= (uint32_t)(b & 0x7f) << s; + 556 18667053 : v |= (uint32_t)(b & 0x7f) << s; 557 : - 558 18668535 : *value = v; + 558 18667053 : *value = v; 559 : - 560 18668535 : return 0; + 560 18667053 : return 0; 561 : } 562 : - 563 10849874 : int sgetb64(STREAM* f, uint64_t* value) + 563 10849502 : int sgetb64(STREAM* f, uint64_t* value) 564 : { 565 : uint64_t v; 566 : unsigned char b; 567 : unsigned char s; 568 : int c; 569 : - 570 10849874 : v = 0; - 571 10849874 : s = 0; + 570 10849502 : v = 0; + 571 10849502 : s = 0; 572 : loop: - 573 39668034 : c = sgetc(f); - 574 39668034 : if (c == EOF) { + 573 39666625 : c = sgetc(f); + 574 39666625 : if (c == EOF) { 575 : /* LCOV_EXCL_START */ 576 : return -1; 577 : /* LCOV_EXCL_STOP */ 578 : } 579 : - 580 39668034 : b = (unsigned char)c; - 581 39668034 : if ((b & 0x80) == 0) { - 582 28818160 : v |= (uint64_t)b << s; - 583 28818160 : s += 7; - 584 28818160 : if (s >= 64) { + 580 39666625 : b = (unsigned char)c; + 581 39666625 : if ((b & 0x80) == 0) { + 582 28817123 : v |= (uint64_t)b << s; + 583 28817123 : s += 7; + 584 28817123 : if (s >= 64) { 585 : /* LCOV_EXCL_START */ 586 : return -1; 587 : /* LCOV_EXCL_STOP */ 588 : } - 589 28818160 : goto loop; + 589 28817123 : goto loop; 590 : } 591 : - 592 10849874 : v |= (uint64_t)(b & 0x7f) << s; + 592 10849502 : v |= (uint64_t)(b & 0x7f) << s; 593 : - 594 10849874 : *value = v; + 594 10849502 : *value = v; 595 : - 596 10849874 : return 0; + 596 10849502 : return 0; 597 : } 598 : - 599 379 : int sgetble32(STREAM* f, uint32_t* value) + 599 380 : int sgetble32(STREAM* f, uint32_t* value) 600 : { 601 : unsigned char buf[4]; 602 : - 603 379 : if (sread(f, buf, 4) != 0) { + 603 380 : if (sread(f, buf, 4) != 0) { 604 : /* LCOV_EXCL_START */ 605 : return -1; 606 : /* LCOV_EXCL_STOP */ 607 : } 608 : - 609 379 : *value = buf[0] | (uint32_t)buf[1] << 8 | (uint32_t)buf[2] << 16 | (uint32_t)buf[3] << 24; + 609 380 : *value = buf[0] | (uint32_t)buf[1] << 8 | (uint32_t)buf[2] << 16 | (uint32_t)buf[3] << 24; 610 : - 611 379 : return 0; + 611 380 : return 0; 612 : } 613 : - 614 3877236 : int sgetbs(STREAM* f, char* str, int size) + 614 3877163 : int sgetbs(STREAM* f, char* str, int size) 615 : { 616 : uint32_t len; 617 : - 618 3877236 : if (sgetb32(f, &len) < 0) { + 618 3877163 : if (sgetb32(f, &len) < 0) { 619 : /* LCOV_EXCL_START */ 620 : return -1; 621 : /* LCOV_EXCL_STOP */ 622 : } 623 : - 624 3877236 : if (len + 1 > (uint32_t)size) { + 624 3877162 : if (len + 1 > (uint32_t)size) { 625 : /* LCOV_EXCL_START */ 626 : return -1; 627 : /* LCOV_EXCL_STOP */ 628 : } 629 : - 630 3877236 : str[len] = 0; + 630 3877162 : str[len] = 0; 631 : - 632 3877236 : return sread(f, str, (int)len); + 632 3877162 : return sread(f, str, (int)len); 633 : } 634 : - 635 20725275 : int swrite(const void* void_data, unsigned size, STREAM* f) + 635 20724964 : int swrite(const void* void_data, unsigned size, STREAM* f) 636 : { - 637 20725275 : const unsigned char* data = void_data; + 637 20724964 : const unsigned char* data = void_data; 638 : 639 : /* if there is enough space in memory */ - 640 20725275 : if (sptrlookup(f, size)) { + 640 20724964 : if (sptrlookup(f, size)) { 641 : /* optimized version with all the data in memory */ - 642 20719102 : unsigned char* pos = sptrget(f); + 642 20718802 : unsigned char* pos = sptrget(f); 643 : 644 : /** 645 : * Update the crc *before* writing the data in the buffer @@ -710,17 +710,17 @@ 648 : * to be able to detect memory errors on the buffer, 649 : * happening before we write it on the file. 650 : */ - 651 20719102 : f->crc_stream = crc32c_plain(f->crc_stream, data, size); + 651 20718802 : f->crc_stream = crc32c_plain(f->crc_stream, data, size); 652 : 653 : /* copy it */ - 654 173066513 : while (size--) - 655 131628309 : *pos++ = *data++; + 654 172634823 : while (size--) + 655 131197219 : *pos++ = *data++; 656 : - 657 20719102 : sptrset(f, pos); + 657 20718802 : sptrset(f, pos); 658 : } else { 659 : /* standard version using sputc() */ - 660 202070 : while (size--) { - 661 189724 : if (sputc(*data++, f) != 0) { + 660 201254 : while (size--) { + 661 188930 : if (sputc(*data++, f) != 0) { 662 : /* LCOV_EXCL_START */ 663 : return -1; 664 : /* LCOV_EXCL_STOP */ @@ -728,28 +728,28 @@ 666 : } 667 : } 668 : - 669 20725275 : return 0; + 669 20724964 : return 0; 670 : } 671 : - 672 9127648 : int sputb32(uint32_t value, STREAM* s) + 672 9127337 : int sputb32(uint32_t value, STREAM* s) 673 : { 674 : unsigned char b; 675 : unsigned char buf[16]; 676 : unsigned i; 677 : - 678 9127648 : i = 0; + 678 9127337 : i = 0; 679 : loop: - 680 17909297 : b = value & 0x7f; - 681 17909297 : value >>= 7; + 680 17477413 : b = value & 0x7f; + 681 17477413 : value >>= 7; 682 : - 683 17909297 : if (value) { - 684 8781649 : buf[i++] = b; - 685 8781649 : goto loop; + 683 17477413 : if (value) { + 684 8350076 : buf[i++] = b; + 685 8350076 : goto loop; 686 : } 687 : - 688 9127648 : buf[i++] = b | 0x80; + 688 9127337 : buf[i++] = b | 0x80; 689 : - 690 9127648 : return swrite(buf, i, s); + 690 9127337 : return swrite(buf, i, s); 691 : } 692 : 693 5317120 : int sputb64(uint64_t value, STREAM* s) diff --git a/cov/cmdline/stream.h.func-sort-c.html b/cov/cmdline/stream.h.func-sort-c.html index 75f8a41a..48c4ad62 100644 --- a/cov/cmdline/stream.h.func-sort-c.html +++ b/cov/cmdline/stream.h.func-sort-c.html @@ -61,39 +61,39 @@ sgetc - 85203689 + 84138438 sptrlookup - 33541405 + 33540761 sptrset - 33503384 + 33503040 sptrget - 33503384 + 33503040 sputc - 3808841 + 3808025 serror - 3635503 + 3635393 sungetc - 34340 + 34440 sgetspace - 20539 + 20599 sgeteol - 6200 + 6218 seof diff --git a/cov/cmdline/stream.h.func.html b/cov/cmdline/stream.h.func.html index 713353fa..fe9477a4 100644 --- a/cov/cmdline/stream.h.func.html +++ b/cov/cmdline/stream.h.func.html @@ -65,7 +65,7 @@ serror - 3635503 + 3635393 serrorfile @@ -73,35 +73,35 @@ sgetc - 85203689 + 84138438 sgeteol - 6200 + 6218 sgetspace - 20539 + 20599 sptrget - 33503384 + 33503040 sptrlookup - 33541405 + 33540761 sptrset - 33503384 + 33503040 sputc - 3808841 + 3808025 sungetc - 34340 + 34440
diff --git a/cov/cmdline/stream.h.gcov.html b/cov/cmdline/stream.h.gcov.html index 28434aaf..ecdcc42c 100644 --- a/cov/cmdline/stream.h.gcov.html +++ b/cov/cmdline/stream.h.gcov.html @@ -221,33 +221,33 @@ 159 : /** 160 : * Check if the buffer has enough data loaded. 161 : */ - 162 33541405 : static inline int sptrlookup(STREAM* s, int size) + 162 33540761 : static inline int sptrlookup(STREAM* s, int size) 163 : { - 164 33541405 : return s->pos + size <= s->end; + 164 33540761 : return s->pos + size <= s->end; 165 : } 166 : 167 : /** 168 : * Get the current stream ptr. 169 : */ - 170 33503384 : static inline unsigned char* sptrget(STREAM* s) + 170 33503040 : static inline unsigned char* sptrget(STREAM* s) 171 : { - 172 33503384 : return s->pos; + 172 33503040 : return s->pos; 173 : } 174 : 175 : /** 176 : * Set the current stream ptr. 177 : */ - 178 33503384 : static inline void sptrset(STREAM* s, unsigned char* ptr) + 178 33503040 : static inline void sptrset(STREAM* s, unsigned char* ptr) 179 : { - 180 33503384 : s->pos = ptr; - 181 33503384 : } + 180 33503040 : s->pos = ptr; + 181 33503040 : } 182 : 183 : /** 184 : * Check the error status. Like ferror(). 185 : */ - 186 3635503 : static inline int serror(STREAM* s) + 186 3635393 : static inline int serror(STREAM* s) 187 : { - 188 3635503 : return s->state == STREAM_STATE_ERROR; + 188 3635393 : return s->state == STREAM_STATE_ERROR; 189 : } 190 : 191 : /** @@ -291,22 +291,22 @@ 229 : /** 230 : * Read a char. Like fgetc(). 231 : */ - 232 85203689 : static inline int sgetc(STREAM* s) + 232 84138438 : static inline int sgetc(STREAM* s) 233 : { - 234 85203689 : if (tommy_unlikely(s->pos == s->end)) - 235 298847 : return sgetc_uncached(s); - 236 84904842 : return *s->pos++; + 234 84138438 : if (tommy_unlikely(s->pos == s->end)) + 235 298855 : return sgetc_uncached(s); + 236 83839583 : return *s->pos++; 237 : } 238 : 239 : /** 240 : * Unread a char. 241 : * Like ungetc() but you have to unget the same char read. 242 : */ - 243 34340 : static inline void sungetc(int c, STREAM* s) + 243 34440 : static inline void sungetc(int c, STREAM* s) 244 : { - 245 34340 : if (c != EOF) - 246 33551 : --s->pos; - 247 34340 : } + 245 34440 : if (c != EOF) + 246 33648 : --s->pos; + 247 34440 : } 248 : 249 : /** 250 : * Read a fixed amount of chars. @@ -317,34 +317,34 @@ 255 : /** 256 : * Get a char from a stream, ignoring one '\r'. 257 : */ - 258 6200 : static inline int sgeteol(STREAM* f) + 258 6218 : static inline int sgeteol(STREAM* f) 259 : { 260 : int c; 261 : - 262 6200 : c = sgetc(f); - 263 6200 : if (c == '\r') + 262 6218 : c = sgetc(f); + 263 6218 : if (c == '\r') 264 0 : c = sgetc(f); 265 : - 266 6200 : return c; + 266 6218 : return c; 267 : } 268 : 269 : /** 270 : * Read all the spaces and tabs. 271 : * Return the number of spaces and tabs read. 272 : */ - 273 20539 : static inline int sgetspace(STREAM* f) + 273 20599 : static inline int sgetspace(STREAM* f) 274 : { - 275 20539 : int count = 0; + 275 20599 : int count = 0; 276 : int c; 277 : - 278 20539 : c = sgetc(f); - 279 48689 : while (c == ' ' || c == '\t') { - 280 7611 : ++count; - 281 7611 : c = sgetc(f); + 278 20599 : c = sgetc(f); + 279 48831 : while (c == ' ' || c == '\t') { + 280 7633 : ++count; + 281 7633 : c = sgetc(f); 282 : } 283 : - 284 20539 : sungetc(c, f); - 285 20539 : return count; + 284 20599 : sungetc(c, f); + 285 20599 : return count; 286 : } 287 : 288 : /** @@ -407,9 +407,9 @@ 345 : * Write a char. Like fputc(). 346 : * Return 0 on success or -1 on error. 347 : */ - 348 3808841 : static inline int sputc(int c, STREAM* s) + 348 3808025 : static inline int sputc(int c, STREAM* s) 349 : { - 350 3808841 : if (s->pos == s->end) { + 350 3808025 : if (s->pos == s->end) { 351 38580 : if (sflush(s) != 0) 352 0 : return -1; 353 : } @@ -421,11 +421,11 @@ 359 : * to be able to detect memory errors on the buffer, 360 : * happening before we write it on the file. 361 : */ - 362 3808841 : s->crc_stream = crc32c_plain_char(s->crc_stream, c); + 362 3808025 : s->crc_stream = crc32c_plain_char(s->crc_stream, c); 363 : - 364 3808841 : *s->pos++ = c; + 364 3808025 : *s->pos++ = c; 365 : - 366 3808841 : return 0; + 366 3808025 : return 0; 367 : } 368 : 369 : /** diff --git a/cov/cmdline/support.c.func-sort-c.html b/cov/cmdline/support.c.func-sort-c.html index e2b16089..a64cfac2 100644 --- a/cov/cmdline/support.c.func-sort-c.html +++ b/cov/cmdline/support.c.func-sort-c.html @@ -61,123 +61,123 @@ thread_mutex_unlock - 80857847 + 80862235 thread_mutex_lock - 80853291 + 80858327 pathcmp - 51888281 + 51889998 pathprint - 51562554 + 51564205 unlock_memory - 20174119 + 20174230 lock_memory - 20174119 + 20174230 malloc_counter_inc - 20173645 + 20173756 malloc_nofail - 14364256 + 14364226 advise_read - 8903012 + 8903872 pathcpy - 7891437 + 7892425 strdup_nofail - 5799372 - - - unlock_msg - 3888570 + 5799477 lock_msg - 3888569 + 3887429 + + + unlock_msg + 3887429 log_tag - 2908990 + 2907978 advise_flags - 2494931 + 2495042 advise_init - 2494857 + 2494967 esc_tag - 2429566 + 2428739 advise_open - 2416121 + 2416234 thread_cond_wait - 1095193 + 1095059 advise_write - 900323 + 900676 mkancestor - 793097 + 793090 log_error - 536153 + 536045 esc_shell_multi - 356012 + 356083 msg_info - 295787 + 295858 thread_cond_broadcast - 255449 + 255625 thread_cond_broadcast_and_unlock - 255259 + 255435 msg_verbose - 126951 + 126963 fmtime - 119601 + 119641 thread_cond_signal - 84548 + 83165 thread_cond_signal_and_unlock - 84548 + 83165 pathexport @@ -185,7 +185,7 @@ pathimport - 16494 + 16519 log_expected @@ -193,19 +193,19 @@ calloc_nofail - 10017 + 10053 pathslash - 7693 + 7699 msg_progress - 4445 + 4447 thread_mutex_init - 2268 + 2276 thread_create @@ -221,15 +221,15 @@ msg_bar - 1778 + 1678 strsplit - 1465 + 1466 log_flush - 1190 + 1196 log_fatal @@ -241,11 +241,11 @@ msg_status - 616 + 625 msg_flush - 591 + 571 malloc_counter_get @@ -261,11 +261,11 @@ lock_init - 297 + 298 pathcat - 265 + 266 lock_done diff --git a/cov/cmdline/support.c.func.html b/cov/cmdline/support.c.func.html index decef537..d22e86c9 100644 --- a/cov/cmdline/support.c.func.html +++ b/cov/cmdline/support.c.func.html @@ -61,39 +61,39 @@ advise_flags - 2494931 + 2495042 advise_init - 2494857 + 2494967 advise_open - 2416121 + 2416234 advise_read - 8903012 + 8903872 advise_write - 900323 + 900676 calloc_nofail - 10017 + 10053 esc_shell_multi - 356012 + 356083 esc_tag - 2429566 + 2428739 fmtime - 119601 + 119641 lock_done @@ -101,19 +101,19 @@ lock_init - 297 + 298 lock_memory - 20174119 + 20174230 lock_msg - 3888569 + 3887429 log_error - 536153 + 536045 log_expected @@ -125,11 +125,11 @@ log_flush - 1190 + 1196 log_tag - 2908990 + 2907978 malloc_counter_get @@ -137,43 +137,43 @@ malloc_counter_inc - 20173645 + 20173756 malloc_nofail - 14364256 + 14364226 mkancestor - 793097 + 793090 msg_bar - 1778 + 1678 msg_flush - 591 + 571 msg_info - 295787 + 295858 msg_progress - 4445 + 4447 msg_status - 616 + 625 msg_verbose - 126951 + 126963 pathcat - 265 + 266 pathcatc @@ -181,11 +181,11 @@ pathcmp - 51888281 + 51889998 pathcpy - 7891437 + 7892425 pathcut @@ -197,15 +197,15 @@ pathimport - 16494 + 16519 pathprint - 51562554 + 51564205 pathslash - 7693 + 7699 printc @@ -237,7 +237,7 @@ strdup_nofail - 5799372 + 5799477 strpolish @@ -245,15 +245,15 @@ strsplit - 1465 + 1466 thread_cond_broadcast - 255449 + 255625 thread_cond_broadcast_and_unlock - 255259 + 255435 thread_cond_destroy @@ -265,15 +265,15 @@ thread_cond_signal - 84548 + 83165 thread_cond_signal_and_unlock - 84548 + 83165 thread_cond_wait - 1095193 + 1095059 thread_create @@ -289,23 +289,23 @@ thread_mutex_init - 2268 + 2276 thread_mutex_lock - 80853291 + 80858327 thread_mutex_unlock - 80857847 + 80862235 unlock_memory - 20174119 + 20174230 unlock_msg - 3888570 + 3887429
diff --git a/cov/cmdline/support.c.gcov.html b/cov/cmdline/support.c.gcov.html index 41f959a4..96cd8100 100644 --- a/cov/cmdline/support.c.gcov.html +++ b/cov/cmdline/support.c.gcov.html @@ -92,42 +92,42 @@ 30 : static pthread_mutex_t memory_lock; 31 : #endif 32 : - 33 3888569 : void lock_msg(void) + 33 3887429 : void lock_msg(void) 34 : { 35 : #if HAVE_PTHREAD - 36 3888569 : thread_mutex_lock(&msg_lock); + 36 3887429 : thread_mutex_lock(&msg_lock); 37 : #endif - 38 3888570 : } + 38 3887429 : } 39 : - 40 3888570 : void unlock_msg(void) + 40 3887429 : void unlock_msg(void) 41 : { 42 : #if HAVE_PTHREAD - 43 3888570 : thread_mutex_unlock(&msg_lock); + 43 3887429 : thread_mutex_unlock(&msg_lock); 44 : #endif - 45 3888570 : } + 45 3887429 : } 46 : - 47 20174119 : void lock_memory(void) + 47 20174230 : void lock_memory(void) 48 : { 49 : #if HAVE_PTHREAD - 50 20174119 : thread_mutex_lock(&memory_lock); + 50 20174230 : thread_mutex_lock(&memory_lock); 51 : #endif - 52 20174119 : } + 52 20174230 : } 53 : - 54 20174119 : void unlock_memory(void) + 54 20174230 : void unlock_memory(void) 55 : { 56 : #if HAVE_PTHREAD - 57 20174119 : thread_mutex_unlock(&memory_lock); + 57 20174230 : thread_mutex_unlock(&memory_lock); 58 : #endif - 59 20174119 : } + 59 20174230 : } 60 : - 61 297 : void lock_init(void) + 61 298 : void lock_init(void) 62 : { 63 : #if HAVE_PTHREAD 64 : /* initialize the locks as first operation as log_fatal depends on them */ - 65 297 : thread_mutex_init(&msg_lock, 0); - 66 297 : thread_mutex_init(&memory_lock, 0); + 65 298 : thread_mutex_init(&msg_lock, 0); + 66 298 : thread_mutex_init(&memory_lock, 0); 67 : #endif - 68 297 : } + 68 298 : } 69 : 70 263 : void lock_done(void) 71 : { @@ -176,18 +176,18 @@ 114 809 : unlock_msg(); 115 809 : } 116 : - 117 536153 : void log_error(const char* format, ...) + 117 536045 : void log_error(const char* format, ...) 118 : { 119 : va_list ap; 120 : - 121 536153 : lock_msg(); + 121 536045 : lock_msg(); 122 : - 123 536153 : if (stdlog) { - 124 534273 : va_start(ap, format); - 125 534273 : fprintf(stdlog, "msg:error: "); - 126 534273 : vfprintf(stdlog, format, ap); - 127 534273 : fflush(stdlog); - 128 534273 : va_end(ap); + 123 536045 : if (stdlog) { + 124 534165 : va_start(ap, format); + 125 534165 : fprintf(stdlog, "msg:error: "); + 126 534165 : vfprintf(stdlog, format, ap); + 127 534165 : fflush(stdlog); + 128 534165 : va_end(ap); 129 : } else { 130 1880 : va_start(ap, format); 131 1880 : vfprintf(stderr, format, ap); @@ -195,8 +195,8 @@ 133 1880 : va_end(ap); 134 : } 135 : - 136 536153 : unlock_msg(); - 137 536153 : } + 136 536045 : unlock_msg(); + 137 536045 : } 138 : 139 11259 : void log_expected(const char* format, ...) 140 : { @@ -215,42 +215,42 @@ 153 11259 : unlock_msg(); 154 11259 : } 155 : - 156 2908990 : void log_tag(const char* format, ...) + 156 2907978 : void log_tag(const char* format, ...) 157 : { 158 : va_list ap; 159 : - 160 2908990 : lock_msg(); + 160 2907978 : lock_msg(); 161 : - 162 2908991 : if (stdlog) { - 163 2573555 : va_start(ap, format); - 164 2573555 : vfprintf(stdlog, format, ap); + 162 2907978 : if (stdlog) { + 163 2572493 : va_start(ap, format); + 164 2572493 : vfprintf(stdlog, format, ap); 165 : /* here we intentionally don't flush */ 166 : /* to make the output faster */ - 167 2573555 : va_end(ap); + 167 2572493 : va_end(ap); 168 : } 169 : - 170 2908991 : unlock_msg(); - 171 2908991 : } + 170 2907978 : unlock_msg(); + 171 2907978 : } 172 : - 173 1190 : void log_flush(void) + 173 1196 : void log_flush(void) 174 : { - 175 1190 : lock_msg(); + 175 1196 : lock_msg(); 176 : - 177 1190 : if (stdlog) - 178 338 : fflush(stdlog); - 179 1190 : fflush(stdout); - 180 1190 : fflush(stderr); + 177 1196 : if (stdlog) + 178 339 : fflush(stdlog); + 179 1196 : fflush(stdout); + 180 1196 : fflush(stderr); 181 : - 182 1190 : unlock_msg(); - 183 1190 : } + 182 1196 : unlock_msg(); + 183 1196 : } 184 : - 185 616 : void msg_status(const char* format, ...) + 185 625 : void msg_status(const char* format, ...) 186 : { 187 : va_list ap; 188 : - 189 616 : lock_msg(); + 189 625 : lock_msg(); 190 : - 191 616 : if (stdlog) { + 191 625 : if (stdlog) { 192 275 : va_start(ap, format); 193 275 : fprintf(stdlog, "msg:status: "); 194 275 : vfprintf(stdlog, format, ap); @@ -258,42 +258,42 @@ 196 275 : va_end(ap); 197 : } 198 : - 199 616 : if (msg_level >= MSG_STATUS) { - 200 616 : va_start(ap, format); - 201 616 : vfprintf(stdout, format, ap); - 202 616 : fflush(stdout); - 203 616 : va_end(ap); + 199 625 : if (msg_level >= MSG_STATUS) { + 200 625 : va_start(ap, format); + 201 625 : vfprintf(stdout, format, ap); + 202 625 : fflush(stdout); + 203 625 : va_end(ap); 204 : } 205 : - 206 616 : unlock_msg(); - 207 616 : } + 206 625 : unlock_msg(); + 207 625 : } 208 : - 209 295787 : void msg_info(const char* format, ...) + 209 295858 : void msg_info(const char* format, ...) 210 : { 211 : va_list ap; 212 : - 213 295787 : lock_msg(); + 213 295858 : lock_msg(); 214 : 215 : /* don't output in stdlog as these messages */ 216 : /* are always paired with a msg_tag() call */ 217 : - 218 295787 : if (msg_level >= MSG_INFO) { - 219 28811 : va_start(ap, format); - 220 28811 : vfprintf(stdout, format, ap); - 221 28811 : fflush(stdout); - 222 28811 : va_end(ap); + 218 295858 : if (msg_level >= MSG_INFO) { + 219 28841 : va_start(ap, format); + 220 28841 : vfprintf(stdout, format, ap); + 221 28841 : fflush(stdout); + 222 28841 : va_end(ap); 223 : } 224 : - 225 295787 : unlock_msg(); - 226 295787 : } + 225 295858 : unlock_msg(); + 226 295858 : } 227 : - 228 4445 : void msg_progress(const char* format, ...) + 228 4447 : void msg_progress(const char* format, ...) 229 : { 230 : va_list ap; 231 : - 232 4445 : lock_msg(); + 232 4447 : lock_msg(); 233 : - 234 4445 : if (stdlog) { + 234 4447 : if (stdlog) { 235 819 : va_start(ap, format); 236 819 : fprintf(stdlog, "msg:progress: "); 237 819 : vfprintf(stdlog, format, ap); @@ -301,68 +301,68 @@ 239 819 : va_end(ap); 240 : } 241 : - 242 4445 : if (msg_level >= MSG_PROGRESS) { - 243 159 : va_start(ap, format); - 244 159 : vfprintf(stdout, format, ap); - 245 159 : fflush(stdout); - 246 159 : va_end(ap); + 242 4447 : if (msg_level >= MSG_PROGRESS) { + 243 161 : va_start(ap, format); + 244 161 : vfprintf(stdout, format, ap); + 245 161 : fflush(stdout); + 246 161 : va_end(ap); 247 : } 248 : - 249 4445 : unlock_msg(); - 250 4445 : } + 249 4447 : unlock_msg(); + 250 4447 : } 251 : - 252 1778 : void msg_bar(const char* format, ...) + 252 1678 : void msg_bar(const char* format, ...) 253 : { 254 : va_list ap; 255 : - 256 1778 : lock_msg(); + 256 1678 : lock_msg(); 257 : 258 : /* don't output in stdlog as these messages */ 259 : /* are intended for screen only */ 260 : /* also don't flush stdout as they are intended to be partial messages */ 261 : - 262 1778 : if (msg_level >= MSG_BAR) { + 262 1678 : if (msg_level >= MSG_BAR) { 263 0 : va_start(ap, format); 264 0 : vfprintf(stdout, format, ap); 265 0 : va_end(ap); 266 : } 267 : - 268 1778 : unlock_msg(); - 269 1778 : } + 268 1678 : unlock_msg(); + 269 1678 : } 270 : - 271 126951 : void msg_verbose(const char* format, ...) + 271 126963 : void msg_verbose(const char* format, ...) 272 : { 273 : va_list ap; 274 : - 275 126951 : lock_msg(); + 275 126963 : lock_msg(); 276 : - 277 126951 : if (stdlog) { - 278 125093 : va_start(ap, format); - 279 125093 : fprintf(stdlog, "msg:verbose: "); - 280 125093 : vfprintf(stdlog, format, ap); - 281 125093 : fflush(stdlog); - 282 125093 : va_end(ap); + 277 126963 : if (stdlog) { + 278 125101 : va_start(ap, format); + 279 125101 : fprintf(stdlog, "msg:verbose: "); + 280 125101 : vfprintf(stdlog, format, ap); + 281 125101 : fflush(stdlog); + 282 125101 : va_end(ap); 283 : } 284 : - 285 126951 : if (msg_level >= MSG_VERBOSE) { - 286 87 : va_start(ap, format); - 287 87 : vfprintf(stdout, format, ap); - 288 87 : fflush(stdout); - 289 87 : va_end(ap); + 285 126963 : if (msg_level >= MSG_VERBOSE) { + 286 91 : va_start(ap, format); + 287 91 : vfprintf(stdout, format, ap); + 288 91 : fflush(stdout); + 289 91 : va_end(ap); 290 : } 291 : - 292 126951 : unlock_msg(); - 293 126951 : } + 292 126963 : unlock_msg(); + 293 126963 : } 294 : - 295 591 : void msg_flush(void) + 295 571 : void msg_flush(void) 296 : { - 297 591 : lock_msg(); + 297 571 : lock_msg(); 298 : - 299 591 : fflush(stdout); - 300 591 : fflush(stderr); + 299 571 : fflush(stdout); + 300 571 : fflush(stderr); 301 : - 302 591 : unlock_msg(); - 303 591 : } + 302 571 : unlock_msg(); + 303 571 : } 304 : 305 64 : void printc(char c, size_t pad) 306 : { @@ -451,17 +451,17 @@ 389 : *p++ = to; \ 390 : break 391 : - 392 2429566 : const char* esc_tag(const char* str, char* buffer) + 392 2428739 : const char* esc_tag(const char* str, char* buffer) 393 : { - 394 2429566 : char* begin = buffer; - 395 2429566 : char* end = begin + ESC_MAX; - 396 2429566 : char* p = begin; + 394 2428739 : char* begin = buffer; + 395 2428739 : char* end = begin + ESC_MAX; + 396 2428739 : char* p = begin; 397 : 398 : /* copy string with escaping */ - 399 36399361 : while (*str) { - 400 31540229 : char c = *str; + 399 36388202 : while (*str) { + 400 31530724 : char c = *str; 401 : - 402 31540229 : switch (c) { + 402 31530724 : switch (c) { 403 : 404 0 : ESCAPE('\n', '\\', 'n'); 405 0 : ESCAPE('\r', '\\', 'r'); @@ -469,21 +469,21 @@ 407 0 : ESCAPE('\\', '\\', '\\'); 408 : 409 : default: - 410 31540229 : if (p == end) + 410 31530724 : if (p == end) 411 0 : goto bail; - 412 31540229 : *p++ = c; - 413 31540229 : break; + 412 31530724 : *p++ = c; + 413 31530724 : break; 414 : } 415 : - 416 31540229 : ++str; + 416 31530724 : ++str; 417 : } 418 : 419 : /* put final 0 */ - 420 2429566 : if (p == end) + 420 2428739 : if (p == end) 421 0 : goto bail; - 422 2429566 : *p = 0; + 422 2428739 : *p = 0; 423 : - 424 4859132 : return begin; + 424 4857478 : return begin; 425 : 426 : bail: 427 : /* LCOV_EXCL_START */ @@ -492,11 +492,11 @@ 430 : /* LCOV_EXCL_STOP */ 431 : } 432 : - 433 356012 : const char* esc_shell_multi(const char** str_map, unsigned str_max, char* buffer) + 433 356083 : const char* esc_shell_multi(const char** str_map, unsigned str_max, char* buffer) 434 : { - 435 356012 : char* begin = buffer; - 436 356012 : char* end = begin + ESC_MAX; - 437 356012 : char* p = begin; + 435 356083 : char* begin = buffer; + 436 356083 : char* end = begin + ESC_MAX; + 437 356083 : char* p = begin; 438 : unsigned str_mac; 439 : const char* str; 440 : @@ -517,24 +517,24 @@ 455 : #endif 456 : 457 : /* copy string with escaping */ - 458 356012 : str_mac = 0; - 459 356012 : str = str_map[str_mac]; + 458 356083 : str_mac = 0; + 459 356083 : str = str_map[str_mac]; 460 : while (1) { 461 : /* get the next char */ - 462 5124568 : char c = *str; + 462 5126024 : char c = *str; 463 : 464 : /* if one string is finished, go to the next */ - 465 10285226 : while (c == 0 && str_mac + 1 < str_max) { + 465 10288138 : while (c == 0 && str_mac + 1 < str_max) { 466 36090 : ++str_mac; 467 36090 : str = str_map[str_mac]; 468 36090 : c = *str; 469 : } 470 : 471 : /* if we read all the strings, stop */ - 472 5124568 : if (!c) - 473 356012 : break; + 472 5126024 : if (!c) + 473 356083 : break; 474 : - 475 4768556 : switch (c) { + 475 4769941 : switch (c) { 476 : #ifdef _WIN32 477 : /* 478 : * Windows shell escape @@ -609,24 +609,24 @@ 547 : case '/' : 548 : case '-' : 549 : /* safe chars for all shells, unquoted */ - 550 4689540 : if (p == end) + 550 4690836 : if (p == end) 551 0 : goto bail; - 552 4689540 : *p++ = c; - 553 4689540 : break; + 552 4690836 : *p++ = c; + 553 4690836 : break; 554 : default : 555 : /* all the others are quoted with \ */ - 556 79016 : if (p == end) + 556 79105 : if (p == end) 557 0 : goto bail; - 558 79016 : *p++ = '\\'; - 559 79016 : if (p == end) + 558 79105 : *p++ = '\\'; + 559 79105 : if (p == end) 560 0 : goto bail; - 561 79016 : *p++ = c; - 562 79016 : break; + 561 79105 : *p++ = c; + 562 79105 : break; 563 : #endif 564 : } 565 : - 566 4768556 : ++str; - 567 4768556 : } + 566 4769941 : ++str; + 567 4769941 : } 568 : 569 : #ifdef _WIN32 570 : if (has_quote) { @@ -637,11 +637,11 @@ 575 : #endif 576 : 577 : /* put final 0 */ - 578 356012 : if (p == end) + 578 356083 : if (p == end) 579 0 : goto bail; - 580 356012 : *p = 0; + 580 356083 : *p = 0; 581 : - 582 712024 : return begin; + 582 712166 : return begin; 583 : 584 : bail: 585 : /* LCOV_EXCL_START */ @@ -663,63 +663,63 @@ 601 0 : return s; 602 : } 603 : - 604 1465 : unsigned strsplit(char** split_map, unsigned split_max, char* str, const char* delimiters) + 604 1466 : unsigned strsplit(char** split_map, unsigned split_max, char* str, const char* delimiters) 605 : { - 606 1465 : unsigned mac = 0; + 606 1466 : unsigned mac = 0; 607 : 608 : /* skip initial delimiters */ - 609 1465 : str += strspn(str, delimiters); + 609 1466 : str += strspn(str, delimiters); 610 : - 611 8890 : while (*str != 0 || mac == split_max) { + 611 8896 : while (*str != 0 || mac == split_max) { 612 : /* start of the token */ - 613 5960 : split_map[mac] = str; - 614 5960 : ++mac; + 613 5964 : split_map[mac] = str; + 614 5964 : ++mac; 615 : 616 : /* find the first delimiter or the end of the string */ - 617 5960 : str += strcspn(str, delimiters); + 617 5964 : str += strcspn(str, delimiters); 618 : 619 : /* put the final terminator if missing */ - 620 5960 : if (*str != 0) - 621 4595 : *str++ = 0; + 620 5964 : if (*str != 0) + 621 4598 : *str++ = 0; 622 : 623 : /* skip trailing delimiters */ - 624 5960 : str += strspn(str, delimiters); + 624 5964 : str += strspn(str, delimiters); 625 : } 626 : - 627 1465 : return mac; + 627 1466 : return mac; 628 : } 629 : 630 : /****************************************************************************/ 631 : /* path */ 632 : - 633 7891437 : void pathcpy(char* dst, size_t size, const char* src) + 633 7892425 : void pathcpy(char* dst, size_t size, const char* src) 634 : { - 635 7891437 : size_t len = strlen(src); + 635 7892425 : size_t len = strlen(src); 636 : - 637 7891437 : if (len + 1 > size) { + 637 7892425 : if (len + 1 > size) { 638 : /* LCOV_EXCL_START */ 639 : log_fatal("Path too long '%s'\n", src); 640 : os_abort(); 641 : /* LCOV_EXCL_STOP */ 642 : } 643 : - 644 7891437 : memcpy(dst, src, len + 1); - 645 7891437 : } + 644 7892425 : memcpy(dst, src, len + 1); + 645 7892425 : } 646 : - 647 265 : void pathcat(char* dst, size_t size, const char* src) + 647 266 : void pathcat(char* dst, size_t size, const char* src) 648 : { - 649 265 : size_t dst_len = strlen(dst); - 650 265 : size_t src_len = strlen(src); + 649 266 : size_t dst_len = strlen(dst); + 650 266 : size_t src_len = strlen(src); 651 : - 652 265 : if (dst_len + src_len + 1 > size) { + 652 266 : if (dst_len + src_len + 1 > size) { 653 : /* LCOV_EXCL_START */ 654 : log_fatal("Path too long '%s%s'\n", dst, src); 655 : os_abort(); 656 : /* LCOV_EXCL_STOP */ 657 : } 658 : - 659 265 : memcpy(dst + dst_len, src, src_len + 1); - 660 265 : } + 659 266 : memcpy(dst + dst_len, src, src_len + 1); + 660 266 : } 661 : 662 788 : void pathcatc(char* dst, size_t size, char c) 663 : { @@ -736,9 +736,9 @@ 674 788 : dst[dst_len + 1] = 0; 675 788 : } 676 : - 677 16494 : void pathimport(char* dst, size_t size, const char* src) + 677 16519 : void pathimport(char* dst, size_t size, const char* src) 678 : { - 679 16494 : pathcpy(dst, size, src); + 679 16519 : pathcpy(dst, size, src); 680 : 681 : #ifdef _WIN32 682 : /* convert the Windows dir separator '\' to C '/', */ @@ -755,7 +755,7 @@ 693 : ++dst; 694 : } 695 : #endif - 696 16494 : } + 696 16519 : } 697 : 698 17589 : void pathexport(char* dst, size_t size, const char* src) 699 : { @@ -777,16 +777,16 @@ 715 : #endif 716 17589 : } 717 : - 718 51562554 : void pathprint(char* dst, size_t size, const char* format, ...) + 718 51564205 : void pathprint(char* dst, size_t size, const char* format, ...) 719 : { 720 : size_t len; 721 : va_list ap; 722 : - 723 51562554 : va_start(ap, format); - 724 51562554 : len = vsnprintf(dst, size, format, ap); - 725 51562554 : va_end(ap); + 723 51564205 : va_start(ap, format); + 724 51564205 : len = vsnprintf(dst, size, format, ap); + 725 51564205 : va_end(ap); 726 : - 727 51562554 : if (len >= size) { + 727 51564205 : if (len >= size) { 728 : /* LCOV_EXCL_START */ 729 : if (size > 0) { 730 : dst[size - 1] = 0; @@ -797,13 +797,13 @@ 735 : os_abort(); 736 : /* LCOV_EXCL_STOP */ 737 : } - 738 51562554 : } + 738 51564205 : } 739 : - 740 7693 : void pathslash(char* dst, size_t size) + 740 7699 : void pathslash(char* dst, size_t size) 741 : { - 742 7693 : size_t len = strlen(dst); + 742 7699 : size_t len = strlen(dst); 743 : - 744 7693 : if (len > 0 && dst[len - 1] != '/') { + 744 7699 : if (len > 0 && dst[len - 1] != '/') { 745 6114 : if (len + 2 >= size) { 746 : /* LCOV_EXCL_START */ 747 : log_fatal("Path too long '%s/'\n", dst); @@ -814,7 +814,7 @@ 752 6114 : dst[len] = '/'; 753 6114 : dst[len + 1] = 0; 754 : } - 755 7693 : } + 755 7699 : } 756 : 757 100 : void pathcut(char* dst) 758 : { @@ -826,7 +826,7 @@ 764 0 : dst[0] = 0; 765 100 : } 766 : - 767 51888281 : int pathcmp(const char* a, const char* b) + 767 51889998 : int pathcmp(const char* a, const char* b) 768 : { 769 : #ifdef _WIN32 770 : char ai[PATH_MAX]; @@ -839,32 +839,32 @@ 777 : /* case insensitive compare in Windows */ 778 : return stricmp(ai, bi); 779 : #else - 780 51888281 : return strcmp(a, b); + 780 51889998 : return strcmp(a, b); 781 : #endif 782 : } 783 : 784 : /****************************************************************************/ 785 : /* file-system */ 786 : - 787 793097 : int mkancestor(const char* file) + 787 793090 : int mkancestor(const char* file) 788 : { 789 : char dir[PATH_MAX]; 790 : struct stat st; 791 : char* c; 792 : - 793 793097 : pathcpy(dir, sizeof(dir), file); + 793 793090 : pathcpy(dir, sizeof(dir), file); 794 : - 795 793097 : c = strrchr(dir, '/'); - 796 793097 : if (!c) { + 795 793090 : c = strrchr(dir, '/'); + 796 793090 : if (!c) { 797 : /* no ancestor */ 798 0 : return 0; 799 : } 800 : 801 : /* clear the file */ - 802 793097 : *c = 0; + 802 793090 : *c = 0; 803 : 804 : /* if it's the root dir */ - 805 793097 : if (*dir == 0) { + 805 793090 : if (*dir == 0) { 806 : /* nothing more to do */ 807 0 : return 0; 808 : } @@ -887,9 +887,9 @@ 825 : * Also in Windows it's better to use lstat() than stat() because it 826 : * doesn't need to open the dir with CreateFile(). 827 : */ - 828 793097 : if (lstat(dir, &st) == 0) { + 828 793090 : if (lstat(dir, &st) == 0) { 829 : /* it already exists */ - 830 793017 : return 0; + 830 793010 : return 0; 831 : } 832 : 833 : /* recursively create them all */ @@ -910,7 +910,7 @@ 848 80 : return 0; 849 : } 850 : - 851 119601 : int fmtime(int f, int64_t mtime_sec, int mtime_nsec) + 851 119641 : int fmtime(int f, int64_t mtime_sec, int mtime_nsec) 852 : { 853 : #if HAVE_FUTIMENS 854 : struct timespec tv[2]; @@ -920,15 +920,15 @@ 858 : int ret; 859 : 860 : #if HAVE_FUTIMENS /* futimens() is preferred because it gives nanosecond precision */ - 861 119601 : tv[0].tv_sec = mtime_sec; - 862 119601 : if (mtime_nsec != STAT_NSEC_INVALID) - 863 119601 : tv[0].tv_nsec = mtime_nsec; + 861 119641 : tv[0].tv_sec = mtime_sec; + 862 119641 : if (mtime_nsec != STAT_NSEC_INVALID) + 863 119641 : tv[0].tv_nsec = mtime_nsec; 864 : else 865 0 : tv[0].tv_nsec = 0; - 866 119601 : tv[1].tv_sec = tv[0].tv_sec; - 867 119601 : tv[1].tv_nsec = tv[0].tv_nsec; + 866 119641 : tv[1].tv_sec = tv[0].tv_sec; + 867 119641 : tv[1].tv_nsec = tv[0].tv_nsec; 868 : - 869 119601 : ret = futimens(f, tv); + 869 119641 : ret = futimens(f, tv); 870 : #elif HAVE_FUTIMES /* fallback to futimes() if nanosecond precision is not available */ 871 : tv[0].tv_sec = mtime_sec; 872 : if (mtime_nsec != STAT_NSEC_INVALID) @@ -953,47 +953,47 @@ 891 : #error No function available to set file timestamps with sub-second precision 892 : #endif 893 : - 894 119601 : return ret; + 894 119641 : return ret; 895 : } 896 : 897 : /****************************************************************************/ 898 : /* advise */ 899 : - 900 2494857 : void advise_init(struct advise_struct* advise, int mode) + 900 2494967 : void advise_init(struct advise_struct* advise, int mode) 901 : { - 902 2494857 : advise->mode = mode; - 903 2494857 : advise->dirty_begin = 0; - 904 2494857 : advise->dirty_end = 0; - 905 2494857 : } + 902 2494967 : advise->mode = mode; + 903 2494967 : advise->dirty_begin = 0; + 904 2494967 : advise->dirty_end = 0; + 905 2494967 : } 906 : - 907 2494931 : int advise_flags(struct advise_struct* advise) + 907 2495042 : int advise_flags(struct advise_struct* advise) 908 : { - 909 2494931 : int flags = 0; + 909 2495042 : int flags = 0; 910 : - 911 2494931 : if (advise->mode == ADVISE_SEQUENTIAL - 912 2483486 : || advise->mode == ADVISE_FLUSH + 911 2495042 : if (advise->mode == ADVISE_SEQUENTIAL + 912 2483696 : || advise->mode == ADVISE_FLUSH 913 34023 : || advise->mode == ADVISE_FLUSH_WINDOW - 914 22684 : || advise->mode == ADVISE_DISCARD - 915 22684 : || advise->mode == ADVISE_DISCARD_WINDOW + 914 22683 : || advise->mode == ADVISE_DISCARD + 915 22683 : || advise->mode == ADVISE_DISCARD_WINDOW 916 : ) - 917 2483585 : flags |= O_SEQUENTIAL; + 917 2483698 : flags |= O_SEQUENTIAL; 918 : 919 : #if HAVE_DIRECT_IO - 920 2494931 : if (advise->mode == ADVISE_DIRECT) + 920 2495042 : if (advise->mode == ADVISE_DIRECT) 921 0 : flags |= O_DIRECT; 922 : #endif 923 : - 924 2494931 : return flags; + 924 2495042 : return flags; 925 : } 926 : - 927 2416121 : int advise_open(struct advise_struct* advise, int f) + 927 2416234 : int advise_open(struct advise_struct* advise, int f) 928 : { 929 : (void)advise; 930 : (void)f; 931 : 932 : #if HAVE_POSIX_FADVISE - 933 2416121 : if (advise->mode == ADVISE_SEQUENTIAL - 934 2404826 : || advise->mode == ADVISE_FLUSH + 933 2416234 : if (advise->mode == ADVISE_SEQUENTIAL + 934 2405052 : || advise->mode == ADVISE_FLUSH 935 34025 : || advise->mode == ADVISE_FLUSH_WINDOW 936 22684 : || advise->mode == ADVISE_DISCARD 937 22684 : || advise->mode == ADVISE_DISCARD_WINDOW @@ -1001,12 +1001,12 @@ 939 : int ret; 940 : 941 : /* advise sequential access */ - 942 2404810 : ret = posix_fadvise(f, 0, 0, POSIX_FADV_SEQUENTIAL); - 943 2404853 : if (ret == ENOSYS) { + 942 2404908 : ret = posix_fadvise(f, 0, 0, POSIX_FADV_SEQUENTIAL); + 943 2405073 : if (ret == ENOSYS) { 944 : /* call is not supported, like in armhf, see posix_fadvise manpage */ 945 0 : ret = 0; 946 : } - 947 2404853 : if (ret != 0) { + 947 2405073 : if (ret != 0) { 948 : /* LCOV_EXCL_START */ 949 : errno = ret; /* posix_fadvise return the error code */ 950 : return -1; @@ -1015,10 +1015,10 @@ 953 : } 954 : #endif 955 : - 956 2416164 : return 0; + 956 2416399 : return 0; 957 : } 958 : - 959 900323 : int advise_write(struct advise_struct* advise, int f, data_off_t offset, data_off_t size) + 959 900676 : int advise_write(struct advise_struct* advise, int f, data_off_t offset, data_off_t size) 960 : { 961 : data_off_t flush_offset; 962 : data_off_t flush_size; @@ -1031,10 +1031,10 @@ 969 : (void)discard_offset; 970 : (void)discard_size; 971 : - 972 900323 : flush_offset = 0; - 973 900323 : flush_size = 0; - 974 900323 : discard_offset = 0; - 975 900323 : discard_size = 0; + 972 900676 : flush_offset = 0; + 973 900676 : flush_size = 0; + 974 900676 : discard_offset = 0; + 975 900676 : discard_size = 0; 976 : 977 : /* 978 : * Follow Linus recommendations about fast writes. @@ -1089,11 +1089,11 @@ 1027 : * --- 1028 : */ 1029 : - 1030 900323 : switch (advise->mode) { + 1030 900676 : switch (advise->mode) { 1031 : case ADVISE_FLUSH : - 1032 881574 : flush_offset = offset; - 1033 881574 : flush_size = size; - 1034 881574 : break; + 1032 881928 : flush_offset = offset; + 1033 881928 : flush_size = size; + 1034 881928 : break; 1035 : case ADVISE_DISCARD : 1036 0 : discard_offset = offset; 1037 0 : discard_size = size; @@ -1155,12 +1155,12 @@ 1093 : } 1094 : 1095 : #if HAVE_SYNC_FILE_RANGE - 1096 900323 : if (flush_size != 0) { + 1096 900676 : if (flush_size != 0) { 1097 : int ret; 1098 : 1099 : /* start writing immediately */ - 1100 881575 : ret = sync_file_range(f, flush_offset, flush_size, SYNC_FILE_RANGE_WRITE); - 1101 881569 : if (ret != 0) { + 1100 881932 : ret = sync_file_range(f, flush_offset, flush_size, SYNC_FILE_RANGE_WRITE); + 1101 881933 : if (ret != 0) { 1102 : /* LCOV_EXCL_START */ 1103 : return -1; 1104 : /* LCOV_EXCL_STOP */ @@ -1169,7 +1169,7 @@ 1107 : #endif 1108 : 1109 : #if HAVE_SYNC_FILE_RANGE && HAVE_POSIX_FADVISE - 1110 900317 : if (discard_size != 0) { + 1110 900677 : if (discard_size != 0) { 1111 : int ret; 1112 : 1113 : /* send the data to the disk and wait until it's written */ @@ -1192,10 +1192,10 @@ 1130 : } 1131 : #endif 1132 : - 1133 900317 : return 0; + 1133 900677 : return 0; 1134 : } 1135 : - 1136 8903012 : int advise_read(struct advise_struct* advise, int f, data_off_t offset, data_off_t size) + 1136 8903872 : int advise_read(struct advise_struct* advise, int f, data_off_t offset, data_off_t size) 1137 : { 1138 : (void)advise; 1139 : (void)f; @@ -1203,15 +1203,15 @@ 1141 : (void)size; 1142 : 1143 : #if HAVE_POSIX_FADVISE - 1144 8903012 : if (advise->mode == ADVISE_DISCARD - 1145 8903128 : || advise->mode == ADVISE_DISCARD_WINDOW + 1144 8903872 : if (advise->mode == ADVISE_DISCARD + 1145 8904012 : || advise->mode == ADVISE_DISCARD_WINDOW 1146 : ) { 1147 : int ret; 1148 : 1149 : /* flush the data from the cache */ - 1150 27677 : ret = posix_fadvise(f, offset, size, POSIX_FADV_DONTNEED); + 1150 27735 : ret = posix_fadvise(f, offset, size, POSIX_FADV_DONTNEED); 1151 : /* for POSIX_FADV_DONTNEED we don't allow failure with ENOSYS */ - 1152 27824 : if (ret != 0) { + 1152 27825 : if (ret != 0) { 1153 : /* LCOV_EXCL_START */ 1154 : errno = ret; /* posix_fadvise return the error code */ 1155 : return -1; @@ -1258,7 +1258,7 @@ 1196 : * --- 1197 : */ 1198 : - 1199 8903159 : return 0; + 1199 8903962 : return 0; 1200 : } 1201 : 1202 : /****************************************************************************/ @@ -1282,14 +1282,14 @@ 1220 474 : return ret; 1221 : } 1222 : - 1223 20173645 : void malloc_counter_inc(size_t inc) + 1223 20173756 : void malloc_counter_inc(size_t inc) 1224 : { - 1225 20173645 : lock_memory(); + 1225 20173756 : lock_memory(); 1226 : - 1227 20173645 : mcounter += inc; + 1227 20173756 : mcounter += inc; 1228 : - 1229 20173645 : unlock_memory(); - 1230 20173645 : } + 1229 20173756 : unlock_memory(); + 1230 20173756 : } 1231 : 1232 : /* LCOV_EXCL_START */ 1233 : static ssize_t malloc_print(int f, const char* str) @@ -1341,11 +1341,11 @@ 1279 : } 1280 : /* LCOV_EXCL_STOP */ 1281 : - 1282 14364256 : void* malloc_nofail(size_t size) + 1282 14364226 : void* malloc_nofail(size_t size) 1283 : { - 1284 14364256 : void* ptr = malloc(size); + 1284 14364226 : void* ptr = malloc(size); 1285 : - 1286 14364256 : if (!ptr) { + 1286 14364226 : if (!ptr) { 1287 : /* LCOV_EXCL_START */ 1288 : malloc_fail(size); 1289 : exit(EXIT_FAILURE); @@ -1359,58 +1359,58 @@ 1297 : /* Filling the memory doesn't ensure to disable OOM, but it increase a lot the chances to */ 1298 : /* get a real error from malloc() instead than a process killed. */ 1299 : /* Note that calloc() doesn't have the same effect. */ - 1300 14364256 : memset(ptr, 0xA5, size); + 1300 14364226 : memset(ptr, 0xA5, size); 1301 : #endif 1302 : - 1303 14364256 : malloc_counter_inc(size); + 1303 14364226 : malloc_counter_inc(size); 1304 : - 1305 14364256 : return ptr; + 1305 14364226 : return ptr; 1306 : } 1307 : - 1308 10017 : void* calloc_nofail(size_t count, size_t size) + 1308 10053 : void* calloc_nofail(size_t count, size_t size) 1309 : { 1310 : void* ptr; 1311 : - 1312 10017 : size *= count; + 1312 10053 : size *= count; 1313 : 1314 : /* see the note in malloc_nofail() of why we don't use calloc() */ - 1315 10017 : ptr = malloc(size); + 1315 10053 : ptr = malloc(size); 1316 : - 1317 10017 : if (!ptr) { + 1317 10053 : if (!ptr) { 1318 : /* LCOV_EXCL_START */ 1319 : malloc_fail(size); 1320 : exit(EXIT_FAILURE); 1321 : /* LCOV_EXCL_STOP */ 1322 : } 1323 : - 1324 10017 : memset(ptr, 0, size); + 1324 10053 : memset(ptr, 0, size); 1325 : - 1326 10017 : malloc_counter_inc(size); + 1326 10053 : malloc_counter_inc(size); 1327 : - 1328 10017 : return ptr; + 1328 10053 : return ptr; 1329 : } 1330 : - 1331 5799372 : char* strdup_nofail(const char* str) + 1331 5799477 : char* strdup_nofail(const char* str) 1332 : { 1333 : size_t size; 1334 : char* ptr; 1335 : - 1336 5799372 : size = strlen(str) + 1; + 1336 5799477 : size = strlen(str) + 1; 1337 : - 1338 5799372 : ptr = malloc(size); + 1338 5799477 : ptr = malloc(size); 1339 : - 1340 5799372 : if (!ptr) { + 1340 5799477 : if (!ptr) { 1341 : /* LCOV_EXCL_START */ 1342 : malloc_fail(size); 1343 : exit(EXIT_FAILURE); 1344 : /* LCOV_EXCL_STOP */ 1345 : } 1346 : - 1347 5799372 : memcpy(ptr, str, size); + 1347 5799477 : memcpy(ptr, str, size); 1348 : - 1349 5799372 : malloc_counter_inc(size); + 1349 5799477 : malloc_counter_inc(size); 1350 : - 1351 5799372 : return ptr; + 1351 5799477 : return ptr; 1352 : } 1353 : 1354 : /****************************************************************************/ @@ -1552,15 +1552,15 @@ 1490 : /* thread */ 1491 : 1492 : #if HAVE_PTHREAD - 1493 2268 : void thread_mutex_init(pthread_mutex_t* mutex, pthread_mutexattr_t* attr) + 1493 2276 : void thread_mutex_init(pthread_mutex_t* mutex, pthread_mutexattr_t* attr) 1494 : { - 1495 2268 : if (pthread_mutex_init(mutex, attr) != 0) { + 1495 2276 : if (pthread_mutex_init(mutex, attr) != 0) { 1496 : /* LCOV_EXCL_START */ 1497 : log_fatal("Failed call to pthread_mutex_init().\n"); 1498 : os_abort(); 1499 : /* LCOV_EXCL_STOP */ 1500 : } - 1501 2268 : } + 1501 2276 : } 1502 : 1503 2074 : void thread_mutex_destroy(pthread_mutex_t* mutex) 1504 : { @@ -1572,25 +1572,25 @@ 1510 : } 1511 2074 : } 1512 : - 1513 80853291 : void thread_mutex_lock(pthread_mutex_t* mutex) + 1513 80858327 : void thread_mutex_lock(pthread_mutex_t* mutex) 1514 : { - 1515 80853291 : if (pthread_mutex_lock(mutex) != 0) { + 1515 80858327 : if (pthread_mutex_lock(mutex) != 0) { 1516 : /* LCOV_EXCL_START */ 1517 : log_fatal("Failed call to pthread_mutex_lock().\n"); 1518 : os_abort(); 1519 : /* LCOV_EXCL_STOP */ 1520 : } - 1521 80859260 : } + 1521 80863166 : } 1522 : - 1523 80857847 : void thread_mutex_unlock(pthread_mutex_t* mutex) + 1523 80862235 : void thread_mutex_unlock(pthread_mutex_t* mutex) 1524 : { - 1525 80857847 : if (pthread_mutex_unlock(mutex) != 0) { + 1525 80862235 : if (pthread_mutex_unlock(mutex) != 0) { 1526 : /* LCOV_EXCL_START */ 1527 : log_fatal("Failed call to pthread_mutex_unlock().\n"); 1528 : os_abort(); 1529 : /* LCOV_EXCL_STOP */ 1530 : } - 1531 80860763 : } + 1531 80864541 : } 1532 : 1533 380 : void thread_cond_init(pthread_cond_t* cond, pthread_condattr_t* attr) 1534 : { @@ -1612,35 +1612,35 @@ 1550 : } 1551 380 : } 1552 : - 1553 84548 : void thread_cond_signal(pthread_cond_t* cond) + 1553 83165 : void thread_cond_signal(pthread_cond_t* cond) 1554 : { - 1555 84548 : if (pthread_cond_signal(cond) != 0) { + 1555 83165 : if (pthread_cond_signal(cond) != 0) { 1556 : /* LCOV_EXCL_START */ 1557 : log_fatal("Failed call to pthread_cond_signal().\n"); 1558 : os_abort(); 1559 : /* LCOV_EXCL_STOP */ 1560 : } - 1561 84548 : } + 1561 83165 : } 1562 : - 1563 255449 : void thread_cond_broadcast(pthread_cond_t* cond) + 1563 255625 : void thread_cond_broadcast(pthread_cond_t* cond) 1564 : { - 1565 255449 : if (pthread_cond_broadcast(cond) != 0) { + 1565 255625 : if (pthread_cond_broadcast(cond) != 0) { 1566 : /* LCOV_EXCL_START */ 1567 : log_fatal("Failed call to pthread_cond_broadcast().\n"); 1568 : os_abort(); 1569 : /* LCOV_EXCL_STOP */ 1570 : } - 1571 255449 : } + 1571 255625 : } 1572 : - 1573 1095193 : void thread_cond_wait(pthread_cond_t* cond, pthread_mutex_t* mutex) + 1573 1095059 : void thread_cond_wait(pthread_cond_t* cond, pthread_mutex_t* mutex) 1574 : { - 1575 1095193 : if (pthread_cond_wait(cond, mutex) != 0) { + 1575 1095059 : if (pthread_cond_wait(cond, mutex) != 0) { 1576 : /* LCOV_EXCL_START */ 1577 : log_fatal("Failed call to pthread_cond_wait().\n"); 1578 : os_abort(); 1579 : /* LCOV_EXCL_STOP */ 1580 : } - 1581 1095193 : } + 1581 1095059 : } 1582 : 1583 : /** 1584 : * Implementation note about conditional variables. @@ -1671,39 +1671,39 @@ 1609 : */ 1610 : int thread_cond_signal_outside = 0; 1611 : - 1612 84548 : void thread_cond_signal_and_unlock(pthread_cond_t* cond, pthread_mutex_t* mutex) + 1612 83165 : void thread_cond_signal_and_unlock(pthread_cond_t* cond, pthread_mutex_t* mutex) 1613 : { - 1614 84548 : if (thread_cond_signal_outside) { + 1614 83165 : if (thread_cond_signal_outside) { 1615 : /* without the thread checker unlock before signaling, */ 1616 : /* this reduces the number of context switches */ 1617 0 : thread_mutex_unlock(mutex); 1618 : } 1619 : - 1620 84548 : thread_cond_signal(cond); + 1620 83165 : thread_cond_signal(cond); 1621 : - 1622 84548 : if (!thread_cond_signal_outside) { + 1622 83165 : if (!thread_cond_signal_outside) { 1623 : /* with the thread checker unlock after signaling */ 1624 : /* to make explicit the condition and mutex relation */ - 1625 84548 : thread_mutex_unlock(mutex); + 1625 83165 : thread_mutex_unlock(mutex); 1626 : } - 1627 84548 : } + 1627 83165 : } 1628 : - 1629 255259 : void thread_cond_broadcast_and_unlock(pthread_cond_t* cond, pthread_mutex_t* mutex) + 1629 255435 : void thread_cond_broadcast_and_unlock(pthread_cond_t* cond, pthread_mutex_t* mutex) 1630 : { - 1631 255259 : if (thread_cond_signal_outside) { + 1631 255435 : if (thread_cond_signal_outside) { 1632 : /* without the thread checker unlock before signaling, */ 1633 : /* this reduces the number of context switches */ 1634 0 : thread_mutex_unlock(mutex); 1635 : } 1636 : - 1637 255259 : thread_cond_broadcast(cond); + 1637 255435 : thread_cond_broadcast(cond); 1638 : - 1639 255259 : if (!thread_cond_signal_outside) { + 1639 255435 : if (!thread_cond_signal_outside) { 1640 : /* with the thread checker unlock after signaling */ 1641 : /* to make explicit the condition and mutex relation */ - 1642 255259 : thread_mutex_unlock(mutex); + 1642 255435 : thread_mutex_unlock(mutex); 1643 : } - 1644 255259 : } + 1644 255435 : } 1645 : 1646 2200 : void thread_create(pthread_t* thread, pthread_attr_t* attr, void *(* func)(void *), void *arg) 1647 : { diff --git a/cov/cmdline/support.h.func-sort-c.html b/cov/cmdline/support.h.func-sort-c.html index 67aa7b3e..cc007315 100644 --- a/cov/cmdline/support.h.func-sort-c.html +++ b/cov/cmdline/support.h.func-sort-c.html @@ -61,7 +61,7 @@ esc_shell - 331952 + 332023
diff --git a/cov/cmdline/support.h.func.html b/cov/cmdline/support.h.func.html index c53895e0..64a447e5 100644 --- a/cov/cmdline/support.h.func.html +++ b/cov/cmdline/support.h.func.html @@ -61,7 +61,7 @@ esc_shell - 331952 + 332023
diff --git a/cov/cmdline/support.h.gcov.html b/cov/cmdline/support.h.gcov.html index ba314b1d..b31be071 100644 --- a/cov/cmdline/support.h.gcov.html +++ b/cov/cmdline/support.h.gcov.html @@ -291,9 +291,9 @@ 229 : * \param buffer Preallocated buffer of ESC_MAX size. 230 : */ 231 : const char* esc_shell_multi(const char** str_map, unsigned str_max, char* buffer); - 232 331952 : static inline const char* esc_shell(const char* str, char* buffer) + 232 332023 : static inline const char* esc_shell(const char* str, char* buffer) 233 : { - 234 331952 : return esc_shell_multi(&str, 1, buffer); + 234 332023 : return esc_shell_multi(&str, 1, buffer); 235 : } 236 : 237 : /** diff --git a/cov/cmdline/sync.c.func-sort-c.html b/cov/cmdline/sync.c.func-sort-c.html index acebb02b..c9708a58 100644 --- a/cov/cmdline/sync.c.func-sort-c.html +++ b/cov/cmdline/sync.c.func-sort-c.html @@ -32,8 +32,8 @@ Lines: 502 - 561 - 89.5 % + 546 + 91.9 % Date: @@ -65,18 +65,18 @@ sync_data_reader - 688117 + 688658 sync_parity_writer - 544283 + 544725 failed_compare_by_index 852 - state_sync + state_sync 87 diff --git a/cov/cmdline/sync.c.func.html b/cov/cmdline/sync.c.func.html index be0b406f..78e40ea7 100644 --- a/cov/cmdline/sync.c.func.html +++ b/cov/cmdline/sync.c.func.html @@ -32,8 +32,8 @@ Lines: 502 - 561 - 89.5 % + 546 + 91.9 % Date: @@ -72,7 +72,7 @@ 7 - state_sync + state_sync 87 @@ -81,11 +81,11 @@ sync_data_reader - 688117 + 688658 sync_parity_writer - 544283 + 544725
diff --git a/cov/cmdline/sync.c.gcov.html b/cov/cmdline/sync.c.gcov.html index e35cac7e..2387de92 100644 --- a/cov/cmdline/sync.c.gcov.html +++ b/cov/cmdline/sync.c.gcov.html @@ -32,8 +32,8 @@ Lines: 502 - 561 - 89.5 % + 546 + 91.9 % Date: @@ -483,9 +483,9 @@ 421 852 : const struct failed_struct* b = void_b; 422 : 423 852 : if (a->index < b->index) - 424 852 : return -1; - 425 0 : if (a->index > b->index) - 426 0 : return 1; + 424 850 : return -1; + 425 2 : if (a->index > b->index) + 426 2 : return 1; 427 0 : return 0; 428 : } 429 : @@ -524,56 +524,56 @@ 462 4688742 : one_valid = 1; 463 : 464 4911646 : if (block_has_invalid_parity(block) || plan->force_full) - 465 753140 : one_invalid = 1; + 465 753392 : one_invalid = 1; 466 : } 467 : 468 : /* if none valid or none invalid, we don't need to update */ 469 820170 : if (!one_invalid || !one_valid) - 470 590766 : return 0; + 470 590590 : return 0; 471 : - 472 229404 : return 1; + 472 229580 : return 1; 473 : } 474 : - 475 688117 : static void sync_data_reader(struct snapraid_worker* worker, struct snapraid_task* task) + 475 688658 : static void sync_data_reader(struct snapraid_worker* worker, struct snapraid_task* task) 476 : { - 477 688117 : struct snapraid_io* io = worker->io; - 478 688117 : struct snapraid_state* state = io->state; - 479 688117 : struct snapraid_handle* handle = worker->handle; - 480 688117 : struct snapraid_disk* disk = handle->disk; - 481 688117 : block_off_t blockcur = task->position; - 482 688117 : unsigned char* buffer = task->buffer; + 477 688658 : struct snapraid_io* io = worker->io; + 478 688658 : struct snapraid_state* state = io->state; + 479 688658 : struct snapraid_handle* handle = worker->handle; + 480 688658 : struct snapraid_disk* disk = handle->disk; + 481 688658 : block_off_t blockcur = task->position; + 482 688658 : unsigned char* buffer = task->buffer; 483 : int ret; 484 : char esc_buffer[ESC_MAX]; 485 : 486 : /* if the disk position is not used */ - 487 688117 : if (!disk) { + 487 688658 : if (!disk) { 488 : /* use an empty block */ - 489 1 : memset(buffer, 0, state->block_size); - 490 1 : task->state = TASK_STATE_DONE; - 491 92173 : return; + 489 0 : memset(buffer, 0, state->block_size); + 490 0 : task->state = TASK_STATE_DONE; + 491 92152 : return; 492 : } 493 : 494 : /* get the block */ - 495 688116 : task->block = fs_par2block_find(disk, blockcur); + 495 688660 : task->block = fs_par2block_find(disk, blockcur); 496 : 497 : /* if the block has no file, meaning that it's EMPTY or DELETED, */ 498 : /* it doesn't participate in the new parity computation */ - 499 688081 : if (!block_has_file(task->block)) { + 499 688584 : if (!block_has_file(task->block)) { 500 : /* use an empty block */ - 501 92153 : memset(buffer, 0, state->block_size); - 502 92153 : task->state = TASK_STATE_DONE; - 503 92153 : return; + 501 92138 : memset(buffer, 0, state->block_size); + 502 92138 : task->state = TASK_STATE_DONE; + 503 92138 : return; 504 : } 505 : 506 : /* get the file of this block */ - 507 595895 : task->file = fs_par2file_get(disk, blockcur, &task->file_pos); + 507 596414 : task->file = fs_par2file_get(disk, blockcur, &task->file_pos); 508 : 509 : /* if the file is different than the current one, close it */ - 510 595951 : if (handle->file != 0 && handle->file != task->file) { + 510 596497 : if (handle->file != 0 && handle->file != task->file) { 511 : /* keep a pointer at the file we are going to close for error reporting */ - 512 245994 : struct snapraid_file* report = handle->file; - 513 245994 : ret = handle_close(handle); - 514 245950 : if (ret == -1) { + 512 246140 : struct snapraid_file* report = handle->file; + 513 246140 : ret = handle_close(handle); + 514 246086 : if (ret == -1) { 515 : /* LCOV_EXCL_START */ 516 : /* This one is really an unexpected error, because we are only reading */ 517 : /* and closing a descriptor should never fail */ @@ -596,8 +596,8 @@ 534 : } 535 : } 536 : - 537 595907 : ret = handle_open(handle, task->file, state->file_mode, log_error, 0); - 538 595847 : if (ret == -1) { + 537 596443 : ret = handle_open(handle, task->file, state->file_mode, log_error, 0); + 538 596385 : if (ret == -1) { 539 12 : if (errno == EIO) { 540 : /* LCOV_EXCL_START */ 541 : log_tag("error:%u:%s:%s: Open EIO error. %s\n", blockcur, disk->name, esc_tag(task->file->sub, esc_buffer), strerror(errno)); @@ -641,12 +641,12 @@ 579 : } 580 : 581 : /* check if the file is changed */ - 582 595835 : if (handle->st.st_size != task->file->size - 583 595862 : || handle->st.st_mtime != task->file->mtime_sec - 584 595897 : || STAT_NSEC(&handle->st) != task->file->mtime_nsec - 585 595892 : || handle->st.st_ino != task->file->inode + 582 596373 : if (handle->st.st_size != task->file->size + 583 596414 : || handle->st.st_mtime != task->file->mtime_sec + 584 596446 : || STAT_NSEC(&handle->st) != task->file->mtime_nsec + 585 596437 : || handle->st.st_ino != task->file->inode 586 : ) { - 587 66 : log_tag("error:%u:%s:%s: Unexpected attribute change\n", blockcur, disk->name, esc_tag(task->file->sub, esc_buffer)); + 587 50 : log_tag("error:%u:%s:%s: Unexpected attribute change\n", blockcur, disk->name, esc_tag(task->file->sub, esc_buffer)); 588 6 : if (handle->st.st_size != task->file->size) { 589 2 : log_error("Unexpected size change at file '%s' from %" PRIu64 " to %" PRIu64 ".\n", handle->path, task->file->size, handle->st.st_size); 590 4 : } else if (handle->st.st_mtime != task->file->mtime_sec @@ -663,8 +663,8 @@ 601 6 : return; 602 : } 603 : - 604 595769 : task->read_size = handle_read(handle, task->file_pos, buffer, state->block_size, log_error, 0); - 605 595561 : if (task->read_size == -1) { + 604 596323 : task->read_size = handle_read(handle, task->file_pos, buffer, state->block_size, log_error, 0); + 605 596119 : if (task->read_size == -1) { 606 : /* LCOV_EXCL_START */ 607 : if (errno == EIO) { 608 : log_tag("error:%u:%s:%s: Read EIO error at position %u. %s\n", blockcur, disk->name, esc_tag(task->file->sub, esc_buffer), task->file_pos, strerror(errno)); @@ -683,24 +683,24 @@ 621 : } 622 : 623 : /* store the path of the opened file */ - 624 595561 : pathcpy(task->path, sizeof(task->path), handle->path); + 624 596119 : pathcpy(task->path, sizeof(task->path), handle->path); 625 : - 626 595834 : task->state = TASK_STATE_DONE; + 626 596393 : task->state = TASK_STATE_DONE; 627 : } 628 : - 629 544283 : static void sync_parity_writer(struct snapraid_worker* worker, struct snapraid_task* task) + 629 544725 : static void sync_parity_writer(struct snapraid_worker* worker, struct snapraid_task* task) 630 : { - 631 544283 : struct snapraid_io* io = worker->io; - 632 544283 : struct snapraid_state* state = io->state; - 633 544283 : struct snapraid_parity_handle* parity_handle = worker->parity_handle; - 634 544283 : unsigned level = parity_handle->level; - 635 544283 : block_off_t blockcur = task->position; - 636 544283 : unsigned char* buffer = task->buffer; + 631 544725 : struct snapraid_io* io = worker->io; + 632 544725 : struct snapraid_state* state = io->state; + 633 544725 : struct snapraid_parity_handle* parity_handle = worker->parity_handle; + 634 544725 : unsigned level = parity_handle->level; + 635 544725 : block_off_t blockcur = task->position; + 636 544725 : unsigned char* buffer = task->buffer; 637 : int ret; 638 : 639 : /* write parity */ - 640 544283 : ret = parity_write(parity_handle, blockcur, buffer, state->block_size); - 641 544291 : if (ret == -1) { + 640 544725 : ret = parity_write(parity_handle, blockcur, buffer, state->block_size); + 641 544729 : if (ret == -1) { 642 : /* LCOV_EXCL_START */ 643 : if (errno == EIO) { 644 : log_tag("parity_error:%u:%s: Write EIO error. %s\n", blockcur, lev_config_name(level), strerror(errno)); @@ -718,7 +718,7 @@ 656 : /* LCOV_EXCL_STOP */ 657 : } 658 : - 659 544291 : task->state = TASK_STATE_DONE; + 659 544729 : task->state = TASK_STATE_DONE; 660 : } 661 : 662 83 : static int state_sync_process(struct snapraid_state* state, struct snapraid_parity_handle* parity_handle, block_off_t blockstart, block_off_t blockmax) @@ -799,8 +799,8 @@ 737 83 : plan.force_full = state->opt.force_full; 738 410168 : for (blockcur = blockstart; blockcur < blockmax; ++blockcur) { 739 410085 : if (!block_is_enabled(&plan, blockcur)) - 740 295383 : continue; - 741 114702 : ++countmax; + 740 295295 : continue; + 741 114790 : ++countmax; 742 : } 743 : 744 : /* compute the autosave size for all disk, even if not read */ @@ -836,31 +836,31 @@ 774 : int writer_error[IO_WRITER_ERROR_MAX]; 775 : 776 : /* go to the next block */ - 777 114785 : blockcur = io_read_next(&io, &buffer); - 778 114785 : if (blockcur >= blockmax) + 777 114873 : blockcur = io_read_next(&io, &buffer); + 778 114873 : if (blockcur >= blockmax) 779 166 : break; 780 : 781 : /* until now is scheduling */ - 782 114702 : state_usage_sched(state); + 782 114790 : state_usage_sched(state); 783 : 784 : /* one more block processed for autosave */ - 785 114702 : ++autosavedone; - 786 114702 : --autosavemissing; + 785 114790 : ++autosavedone; + 786 114790 : --autosavemissing; 787 : 788 : /* by default process the block, and skip it if something goes wrong */ - 789 114702 : error_on_this_block = 0; - 790 114702 : silent_error_on_this_block = 0; - 791 114702 : io_error_on_this_block = 0; - 792 114702 : fixed_error_on_this_block = 0; + 789 114790 : error_on_this_block = 0; + 790 114790 : silent_error_on_this_block = 0; + 791 114790 : io_error_on_this_block = 0; + 792 114790 : fixed_error_on_this_block = 0; 793 : 794 : /* keep track of the number of failed blocks */ - 795 114702 : failed_count = 0; + 795 114790 : failed_count = 0; 796 : 797 : /* get block specific info */ - 798 114702 : info = info_get(&state->infoarr, blockcur); + 798 114790 : info = info_get(&state->infoarr, blockcur); 799 : 800 : /* if we have to use the old hash */ - 801 114702 : rehash = info_get_rehash(info); + 801 114790 : rehash = info_get_rehash(info); 802 : 803 : /* if the parity requires to be updated */ 804 : /* It could happens that all the blocks are EMPTY/BLK and CHG but with the hash */ @@ -869,18 +869,18 @@ 807 : /* Note that CHG/DELETED blocks already present in the content file loaded */ 808 : /* have the hash cleared (::clear_past_hash flag), and then they won't never match the hash. */ 809 : /* We are treating only CHG blocks created at runtime. */ - 810 114702 : parity_needs_to_be_updated = state->opt.force_full || state->opt.force_parity_update; + 810 114790 : parity_needs_to_be_updated = state->opt.force_full || state->opt.force_parity_update; 811 : 812 : /* if the parity is going to be updated */ - 813 114702 : parity_going_to_be_updated = 0; + 813 114790 : parity_going_to_be_updated = 0; 814 : 815 : /* if the block is marked as bad, we force the parity update */ 816 : /* because the bad block may be the result of a wrong parity */ - 817 114702 : if (info_get_bad(info)) + 817 114790 : if (info_get_bad(info)) 818 0 : parity_needs_to_be_updated = 1; 819 : 820 : /* for each disk, process the block */ - 821 802914 : for (j = 0; j < diskmax; ++j) { + 821 803530 : for (j = 0; j < diskmax; ++j) { 822 : struct snapraid_task* task; 823 : int read_size; 824 : unsigned char hash[HASH_MAX]; @@ -892,45 +892,45 @@ 830 : unsigned diskcur; 831 : 832 : /* until now is misc */ - 833 688212 : state_usage_misc(state); + 833 688740 : state_usage_misc(state); 834 : - 835 688212 : task = io_data_read(&io, &diskcur, waiting_map, &waiting_mac); + 835 688740 : task = io_data_read(&io, &diskcur, waiting_map, &waiting_mac); 836 : 837 : /* until now is disk */ - 838 688212 : state_usage_disk(state, handle, waiting_map, waiting_mac); + 838 688740 : state_usage_disk(state, handle, waiting_map, waiting_mac); 839 : 840 : /* get the results */ - 841 688212 : disk = task->disk; - 842 688212 : block = task->block; - 843 688212 : file = task->file; - 844 688212 : file_pos = task->file_pos; - 845 688212 : read_size = task->read_size; + 841 688740 : disk = task->disk; + 842 688740 : block = task->block; + 843 688740 : file = task->file; + 844 688740 : file_pos = task->file_pos; + 845 688740 : read_size = task->read_size; 846 : 847 : /* by default no rehash in case of "continue" */ - 848 688212 : rehandle[diskcur].block = 0; + 848 688740 : rehandle[diskcur].block = 0; 849 : 850 : /* if the disk position is not used */ - 851 688212 : if (!disk) - 852 93057 : continue; + 851 688740 : if (!disk) + 852 93036 : continue; 853 : 854 : /* get the state of the block */ - 855 688212 : block_state = block_state_get(block); + 855 688740 : block_state = block_state_get(block); 856 : 857 : /* if the block has invalid parity, */ 858 : /* we have to take care of it in case of recover */ - 859 688212 : if (block_has_invalid_parity(block)) { + 859 688740 : if (block_has_invalid_parity(block)) { 860 : /* store it in the failed set, because */ 861 : /* the parity may be still computed with the previous content */ - 862 182772 : failed[failed_count].index = diskcur; - 863 182772 : failed[failed_count].size = state->block_size; - 864 182772 : failed[failed_count].block = block; - 865 182772 : ++failed_count; + 862 182898 : failed[failed_count].index = diskcur; + 863 182898 : failed[failed_count].size = state->block_size; + 864 182898 : failed[failed_count].block = block; + 865 182898 : ++failed_count; 866 : 867 : /* if the block has invalid parity, we have to update the parity */ 868 : /* to include this block change */ 869 : /* This also apply to CHG blocks, but we are going to handle */ 870 : /* later this case to do the updates only if really needed */ - 871 182772 : if (block_state != BLOCK_STATE_CHG) + 871 182898 : if (block_state != BLOCK_STATE_CHG) 872 88225 : parity_needs_to_be_updated = 1; 873 : 874 : /* note that DELETE blocks are skipped in the next check */ @@ -941,719 +941,731 @@ 879 : } 880 : 881 : /* if the block is not used */ - 882 688212 : if (!block_has_file(block)) - 883 92186 : continue; + 882 688740 : if (!block_has_file(block)) + 883 92165 : continue; 884 : 885 : /* handle error conditions */ - 886 596026 : if (task->state == TASK_STATE_IOERROR) { - 887 0 : ++io_error; - 888 0 : goto bail; - 889 : } - 890 596026 : if (task->state == TASK_STATE_ERROR) { - 891 0 : ++error; - 892 0 : goto bail; - 893 : } - 894 596026 : if (task->state == TASK_STATE_ERROR_CONTINUE) { - 895 18 : ++error; - 896 18 : error_on_this_block = 1; - 897 18 : continue; - 898 : } - 899 596008 : if (task->state == TASK_STATE_IOERROR_CONTINUE) { - 900 0 : ++io_error; - 901 0 : if (io_error >= state->opt.io_error_limit) { - 902 0 : log_fatal("DANGER! Unexpected input/output read error in a data disk, it isn't possible to sync.\n"); - 903 0 : log_fatal("Ensure that disk '%s' is sane and that file '%s' can be read.\n", disk->dir, task->path); - 904 0 : log_fatal("Stopping at block %u\n", blockcur); - 905 0 : goto bail; - 906 : } - 907 : - 908 : /* otherwise continue */ - 909 0 : io_error_on_this_block = 1; - 910 0 : continue; - 911 : } - 912 596008 : if (task->state != TASK_STATE_DONE) { - 913 : /* LCOV_EXCL_START */ - 914 : log_fatal("Internal inconsistency in task state\n"); - 915 : os_abort(); - 916 : /* LCOV_EXCL_STOP */ + 886 596575 : if (task->state == TASK_STATE_IOERROR) { + 887 : /* LCOV_EXCL_START */ + 888 : ++io_error; + 889 : goto bail; + 890 : /* LCOV_EXCL_STOP */ + 891 : } + 892 596575 : if (task->state == TASK_STATE_ERROR) { + 893 : /* LCOV_EXCL_START */ + 894 : ++error; + 895 : goto bail; + 896 : /* LCOV_EXCL_STOP */ + 897 : } + 898 596575 : if (task->state == TASK_STATE_ERROR_CONTINUE) { + 899 18 : ++error; + 900 18 : error_on_this_block = 1; + 901 18 : continue; + 902 : } + 903 596557 : if (task->state == TASK_STATE_IOERROR_CONTINUE) { + 904 0 : ++io_error; + 905 0 : if (io_error >= state->opt.io_error_limit) { + 906 : /* LCOV_EXCL_START */ + 907 : log_fatal("DANGER! Unexpected input/output read error in a data disk, it isn't possible to sync.\n"); + 908 : log_fatal("Ensure that disk '%s' is sane and that file '%s' can be read.\n", disk->dir, task->path); + 909 : log_fatal("Stopping at block %u\n", blockcur); + 910 : goto bail; + 911 : /* LCOV_EXCL_STOP */ + 912 : } + 913 : + 914 : /* otherwise continue */ + 915 0 : io_error_on_this_block = 1; + 916 0 : continue; 917 : } - 918 : - 919 596008 : countsize += read_size; - 920 : - 921 : /* now compute the hash */ - 922 596008 : if (rehash) { - 923 27243 : memhash(state->prevhash, state->prevhashseed, hash, buffer[diskcur], read_size); + 918 596557 : if (task->state != TASK_STATE_DONE) { + 919 : /* LCOV_EXCL_START */ + 920 : log_fatal("Internal inconsistency in task state\n"); + 921 : os_abort(); + 922 : /* LCOV_EXCL_STOP */ + 923 : } 924 : - 925 : /* compute the new hash, and store it */ - 926 27243 : rehandle[diskcur].block = block; - 927 27243 : memhash(state->hash, state->hashseed, rehandle[diskcur].hash, buffer[diskcur], read_size); - 928 : } else { - 929 568765 : memhash(state->hash, state->hashseed, hash, buffer[diskcur], read_size); - 930 : } - 931 : - 932 : /* until now is hash */ - 933 596008 : state_usage_hash(state); - 934 : - 935 596008 : if (block_has_updated_hash(block)) { - 936 : /* compare the hash */ - 937 501479 : if (memcmp(hash, block->hash, BLOCK_HASH_SIZE) != 0) { - 938 : /* if the file has invalid parity, it's a REP changed during the sync */ - 939 853 : if (block_has_invalid_parity(block)) { - 940 1 : log_tag("error:%u:%s:%s: Unexpected data change\n", blockcur, disk->name, esc_tag(file->sub, esc_buffer)); - 941 1 : log_error("Data change at file '%s' at position '%u'\n", task->path, file_pos); - 942 1 : log_error("WARNING! Unexpected data modification of a file without parity!\n"); - 943 : - 944 1 : if (file_flag_has(file, FILE_IS_COPY)) { - 945 0 : log_error("This file was detected as a copy of another file with the same name, size,\n"); - 946 0 : log_error("and timestamp, but the file data isn't matching the assumed copy.\n"); - 947 0 : log_error("If this is a false positive, and the files are expected to be different,\n"); - 948 0 : log_error("you can 'sync' anyway using 'snapraid --force-nocopy sync'\n"); - 949 : } else { - 950 1 : log_error("Try removing the file from the array and rerun the 'sync' command!\n"); - 951 : } - 952 : - 953 1 : ++error; - 954 : - 955 : /* if the file is changed, it means that it was modified during sync */ - 956 : /* this isn't a serious error, so we skip this block, and continue with others */ - 957 1 : error_on_this_block = 1; - 958 1 : continue; - 959 : } else { /* otherwise it's a BLK with silent error */ - 960 852 : unsigned diff = memdiff(hash, block->hash, BLOCK_HASH_SIZE); - 961 852 : log_tag("error:%u:%s:%s: Data error at position %u, diff bits %u\n", blockcur, disk->name, esc_tag(file->sub, esc_buffer), file_pos, diff); - 962 852 : log_error("Data error in file '%s' at position '%u', diff bits %u\n", task->path, file_pos, diff); - 963 : - 964 : /* save the failed block for the fix */ - 965 852 : failed[failed_count].index = diskcur; - 966 852 : failed[failed_count].size = read_size; - 967 852 : failed[failed_count].block = block; - 968 852 : ++failed_count; + 925 596557 : countsize += read_size; + 926 : + 927 : /* now compute the hash */ + 928 596557 : if (rehash) { + 929 27243 : memhash(state->prevhash, state->prevhashseed, hash, buffer[diskcur], read_size); + 930 : + 931 : /* compute the new hash, and store it */ + 932 27243 : rehandle[diskcur].block = block; + 933 27243 : memhash(state->hash, state->hashseed, rehandle[diskcur].hash, buffer[diskcur], read_size); + 934 : } else { + 935 569314 : memhash(state->hash, state->hashseed, hash, buffer[diskcur], read_size); + 936 : } + 937 : + 938 : /* until now is hash */ + 939 596557 : state_usage_hash(state); + 940 : + 941 596557 : if (block_has_updated_hash(block)) { + 942 : /* compare the hash */ + 943 501902 : if (memcmp(hash, block->hash, BLOCK_HASH_SIZE) != 0) { + 944 : /* if the file has invalid parity, it's a REP changed during the sync */ + 945 853 : if (block_has_invalid_parity(block)) { + 946 1 : log_tag("error:%u:%s:%s: Unexpected data change\n", blockcur, disk->name, esc_tag(file->sub, esc_buffer)); + 947 1 : log_error("Data change at file '%s' at position '%u'\n", task->path, file_pos); + 948 1 : log_error("WARNING! Unexpected data modification of a file without parity!\n"); + 949 : + 950 1 : if (file_flag_has(file, FILE_IS_COPY)) { + 951 0 : log_error("This file was detected as a copy of another file with the same name, size,\n"); + 952 0 : log_error("and timestamp, but the file data isn't matching the assumed copy.\n"); + 953 0 : log_error("If this is a false positive, and the files are expected to be different,\n"); + 954 0 : log_error("you can 'sync' anyway using 'snapraid --force-nocopy sync'\n"); + 955 : } else { + 956 1 : log_error("Try removing the file from the array and rerun the 'sync' command!\n"); + 957 : } + 958 : + 959 1 : ++error; + 960 : + 961 : /* if the file is changed, it means that it was modified during sync */ + 962 : /* this isn't a serious error, so we skip this block, and continue with others */ + 963 1 : error_on_this_block = 1; + 964 1 : continue; + 965 : } else { /* otherwise it's a BLK with silent error */ + 966 852 : unsigned diff = memdiff(hash, block->hash, BLOCK_HASH_SIZE); + 967 852 : log_tag("error:%u:%s:%s: Data error at position %u, diff bits %u\n", blockcur, disk->name, esc_tag(file->sub, esc_buffer), file_pos, diff); + 968 852 : log_error("Data error in file '%s' at position '%u', diff bits %u\n", task->path, file_pos, diff); 969 : - 970 : /* silent errors are very rare, and are not a signal that a disk */ - 971 : /* is going to fail. So, we just continue marking the block as bad */ - 972 : /* just like in scrub */ - 973 852 : ++silent_error; - 974 852 : silent_error_on_this_block = 1; - 975 852 : continue; - 976 : } - 977 : } - 978 : } else { - 979 : /* if until now the parity doesn't need to be updated */ - 980 94529 : if (!parity_needs_to_be_updated) { - 981 : /* for sure it's a CHG block, because EMPTY are processed before with "continue" */ - 982 : /* and BLK and REP have "block_has_updated_hash()" as 1, and all the others */ - 983 : /* have "parity_needs_to_be_updated" already at 1 */ - 984 35175 : assert(block_state_get(block) == BLOCK_STATE_CHG); - 985 : - 986 : /* if the hash represents the data unequivocally */ - 987 35175 : if (hash_is_unique(block->hash)) { - 988 : /* check if the hash is changed */ - 989 8502 : if (memcmp(hash, block->hash, BLOCK_HASH_SIZE) != 0) { - 990 : /* the block is different, and we must update parity */ - 991 6003 : parity_needs_to_be_updated = 1; - 992 : } - 993 : } else { - 994 : /* if the hash is already invalid, we update parity */ - 995 26673 : parity_needs_to_be_updated = 1; - 996 : } - 997 : } - 998 : - 999 : /* copy the hash in the block, but doesn't mark the block as hashed */ - 1000 : /* this allow in case of skipped block to do not save the failed computation */ - 1001 94529 : memcpy(block->hash, hash, BLOCK_HASH_SIZE); - 1002 : - 1003 : /* note that in case of rehash, this is the wrong hash, */ - 1004 : /* but it will be overwritten later */ - 1005 : } - 1006 : } - 1007 : - 1008 : /* if we have only silent errors we can try to fix them on-the-fly */ - 1009 : /* note the the fix is not written to disk, but used only to */ - 1010 : /* compute the new parity */ - 1011 114702 : if (!error_on_this_block && !io_error_on_this_block && silent_error_on_this_block) { - 1012 : unsigned failed_mac; - 1013 852 : int something_to_recover = 0; - 1014 : - 1015 : /* sort the failed vector */ - 1016 : /* because with threads it may be in any order */ - 1017 : /* but RAID requires the indexes to be sorted */ - 1018 852 : qsort(failed, failed_count, sizeof(failed[0]), failed_compare_by_index); - 1019 : - 1020 : /* setup the blocks to recover */ - 1021 852 : failed_mac = 0; - 1022 2556 : for (j = 0; j < failed_count; ++j) { - 1023 1704 : unsigned char* block_buffer = buffer[failed[j].index]; - 1024 1704 : unsigned char* block_copy = copy[failed[j].index]; - 1025 1704 : unsigned block_state = block_state_get(failed[j].block); - 1026 : - 1027 : /* we try to recover only if at least one BLK is present */ - 1028 1704 : if (block_state == BLOCK_STATE_BLK) - 1029 852 : something_to_recover = 1; - 1030 : - 1031 : /* save a copy of the content just read */ - 1032 : /* that it's going to be overwritten by the recovering function */ - 1033 1704 : memcpy(block_copy, block_buffer, state->block_size); - 1034 : - 1035 1704 : if (block_state == BLOCK_STATE_CHG - 1036 852 : && hash_is_zero(failed[j].block->hash) - 1037 : ) { - 1038 : /* if the block was filled with 0, restore this state */ - 1039 : /* and avoid to recover it */ - 1040 0 : memset(block_buffer, 0, state->block_size); - 1041 : } else { - 1042 : /* if we have too many failures, we cannot recover */ - 1043 1704 : if (failed_mac >= state->level) - 1044 0 : break; - 1045 : - 1046 : /* otherwise it has to be recovered */ - 1047 1704 : failed_map[failed_mac++] = failed[j].index; - 1048 : } - 1049 : } - 1050 : - 1051 : /* if we have something to recover and enough parity */ - 1052 852 : if (something_to_recover && j == failed_count) { - 1053 : /* until now is misc */ - 1054 852 : state_usage_misc(state); - 1055 : - 1056 : /* read the parity */ - 1057 : /* we are sure that parity exists because */ - 1058 : /* we have at least one BLK block */ - 1059 5964 : for (l = 0; l < state->level; ++l) { - 1060 5112 : ret = parity_read(&parity_handle[l], blockcur, buffer[diskmax + l], state->block_size, log_error); - 1061 5112 : if (ret == -1) { - 1062 : /* LCOV_EXCL_START */ - 1063 : if (errno == EIO) { - 1064 : log_tag("parity_error:%u:%s: Read EIO error. %s\n", blockcur, lev_config_name(l), strerror(errno)); - 1065 : if (io_error >= state->opt.io_error_limit) { - 1066 : log_fatal("DANGER! Unexpected input/output read error in the %s disk, it isn't possible to sync.\n", lev_name(l)); - 1067 : log_fatal("Ensure that disk '%s' is sane and can be read.\n", lev_config_name(l)); - 1068 : log_fatal("Stopping at block %u\n", blockcur); - 1069 : ++io_error; - 1070 : goto bail; - 1071 : } - 1072 : - 1073 : log_error("Input/Output error in parity '%s' at position '%u'\n", lev_config_name(l), blockcur); - 1074 : ++io_error; - 1075 : io_error_on_this_block = 1; - 1076 : continue; - 1077 : } + 970 : /* save the failed block for the fix */ + 971 852 : failed[failed_count].index = diskcur; + 972 852 : failed[failed_count].size = read_size; + 973 852 : failed[failed_count].block = block; + 974 852 : ++failed_count; + 975 : + 976 : /* silent errors are very rare, and are not a signal that a disk */ + 977 : /* is going to fail. So, we just continue marking the block as bad */ + 978 : /* just like in scrub */ + 979 852 : ++silent_error; + 980 852 : silent_error_on_this_block = 1; + 981 852 : continue; + 982 : } + 983 : } + 984 : } else { + 985 : /* if until now the parity doesn't need to be updated */ + 986 94655 : if (!parity_needs_to_be_updated) { + 987 : /* for sure it's a CHG block, because EMPTY are processed before with "continue" */ + 988 : /* and BLK and REP have "block_has_updated_hash()" as 1, and all the others */ + 989 : /* have "parity_needs_to_be_updated" already at 1 */ + 990 35289 : assert(block_state_get(block) == BLOCK_STATE_CHG); + 991 : + 992 : /* if the hash represents the data unequivocally */ + 993 35289 : if (hash_is_unique(block->hash)) { + 994 : /* check if the hash is changed */ + 995 8620 : if (memcmp(hash, block->hash, BLOCK_HASH_SIZE) != 0) { + 996 : /* the block is different, and we must update parity */ + 997 6075 : parity_needs_to_be_updated = 1; + 998 : } + 999 : } else { + 1000 : /* if the hash is already invalid, we update parity */ + 1001 26669 : parity_needs_to_be_updated = 1; + 1002 : } + 1003 : } + 1004 : + 1005 : /* copy the hash in the block, but doesn't mark the block as hashed */ + 1006 : /* this allow in case of skipped block to do not save the failed computation */ + 1007 94655 : memcpy(block->hash, hash, BLOCK_HASH_SIZE); + 1008 : + 1009 : /* note that in case of rehash, this is the wrong hash, */ + 1010 : /* but it will be overwritten later */ + 1011 : } + 1012 : } + 1013 : + 1014 : /* if we have only silent errors we can try to fix them on-the-fly */ + 1015 : /* note the the fix is not written to disk, but used only to */ + 1016 : /* compute the new parity */ + 1017 114790 : if (!error_on_this_block && !io_error_on_this_block && silent_error_on_this_block) { + 1018 : unsigned failed_mac; + 1019 852 : int something_to_recover = 0; + 1020 : + 1021 : /* sort the failed vector */ + 1022 : /* because with threads it may be in any order */ + 1023 : /* but RAID requires the indexes to be sorted */ + 1024 852 : qsort(failed, failed_count, sizeof(failed[0]), failed_compare_by_index); + 1025 : + 1026 : /* setup the blocks to recover */ + 1027 852 : failed_mac = 0; + 1028 2556 : for (j = 0; j < failed_count; ++j) { + 1029 1704 : unsigned char* block_buffer = buffer[failed[j].index]; + 1030 1704 : unsigned char* block_copy = copy[failed[j].index]; + 1031 1704 : unsigned block_state = block_state_get(failed[j].block); + 1032 : + 1033 : /* we try to recover only if at least one BLK is present */ + 1034 1704 : if (block_state == BLOCK_STATE_BLK) + 1035 852 : something_to_recover = 1; + 1036 : + 1037 : /* save a copy of the content just read */ + 1038 : /* that it's going to be overwritten by the recovering function */ + 1039 1704 : memcpy(block_copy, block_buffer, state->block_size); + 1040 : + 1041 1704 : if (block_state == BLOCK_STATE_CHG + 1042 852 : && hash_is_zero(failed[j].block->hash) + 1043 : ) { + 1044 : /* if the block was filled with 0, restore this state */ + 1045 : /* and avoid to recover it */ + 1046 0 : memset(block_buffer, 0, state->block_size); + 1047 : } else { + 1048 : /* if we have too many failures, we cannot recover */ + 1049 1704 : if (failed_mac >= state->level) + 1050 0 : break; + 1051 : + 1052 : /* otherwise it has to be recovered */ + 1053 1704 : failed_map[failed_mac++] = failed[j].index; + 1054 : } + 1055 : } + 1056 : + 1057 : /* if we have something to recover and enough parity */ + 1058 852 : if (something_to_recover && j == failed_count) { + 1059 : /* until now is misc */ + 1060 852 : state_usage_misc(state); + 1061 : + 1062 : /* read the parity */ + 1063 : /* we are sure that parity exists because */ + 1064 : /* we have at least one BLK block */ + 1065 5964 : for (l = 0; l < state->level; ++l) { + 1066 5112 : ret = parity_read(&parity_handle[l], blockcur, buffer[diskmax + l], state->block_size, log_error); + 1067 5112 : if (ret == -1) { + 1068 : /* LCOV_EXCL_START */ + 1069 : if (errno == EIO) { + 1070 : log_tag("parity_error:%u:%s: Read EIO error. %s\n", blockcur, lev_config_name(l), strerror(errno)); + 1071 : if (io_error >= state->opt.io_error_limit) { + 1072 : log_fatal("DANGER! Unexpected input/output read error in the %s disk, it isn't possible to sync.\n", lev_name(l)); + 1073 : log_fatal("Ensure that disk '%s' is sane and can be read.\n", lev_config_name(l)); + 1074 : log_fatal("Stopping at block %u\n", blockcur); + 1075 : ++io_error; + 1076 : goto bail; + 1077 : } 1078 : - 1079 : log_tag("parity_error:%u:%s: Read error. %s\n", blockcur, lev_config_name(l), strerror(errno)); - 1080 : log_fatal("WARNING! Unexpected read error in the %s disk, it isn't possible to sync.\n", lev_name(l)); - 1081 : log_fatal("Ensure that disk '%s' can be read.\n", lev_config_name(l)); - 1082 : log_fatal("Stopping at block %u\n", blockcur); - 1083 : ++error; - 1084 : goto bail; - 1085 : /* LCOV_EXCL_STOP */ - 1086 : } - 1087 : - 1088 : /* until now is parity */ - 1089 5112 : state_usage_parity(state, &l, 1); - 1090 : } - 1091 : - 1092 : /* if no error in parity read */ - 1093 852 : if (!io_error_on_this_block) { - 1094 : /* try to fix the data */ - 1095 : /* note that this is a simple fix algorithm, that doesn't take into */ - 1096 : /* account the case of a wrong parity */ - 1097 : /* only 'fix' supports the most advanced fixing */ - 1098 852 : raid_rec(failed_mac, failed_map, diskmax, state->level, state->block_size, buffer); - 1099 : - 1100 : /* until now is raid */ - 1101 852 : state_usage_raid(state); - 1102 : - 1103 : /* check the result and prepare the data */ - 1104 5112 : for (j = 0; j < failed_count; ++j) { - 1105 : unsigned char hash[HASH_MAX]; - 1106 1704 : unsigned char* block_buffer = buffer[failed[j].index]; - 1107 1704 : unsigned char* block_copy = copy[failed[j].index]; - 1108 1704 : unsigned block_state = block_state_get(failed[j].block); - 1109 : - 1110 1704 : if (block_state == BLOCK_STATE_BLK) { - 1111 852 : unsigned size = failed[j].size; - 1112 : - 1113 : /* compute the hash of the recovered block */ - 1114 852 : if (rehash) { - 1115 0 : memhash(state->prevhash, state->prevhashseed, hash, block_buffer, size); - 1116 : } else { - 1117 852 : memhash(state->hash, state->hashseed, hash, block_buffer, size); - 1118 : } - 1119 : - 1120 : /* until now is hash */ - 1121 852 : state_usage_hash(state); - 1122 : - 1123 : /* if the hash doesn't match */ - 1124 852 : if (memcmp(hash, failed[j].block->hash, BLOCK_HASH_SIZE) != 0) { - 1125 : /* we have not recovered */ - 1126 0 : break; - 1127 : } + 1079 : log_error("Input/Output error in parity '%s' at position '%u'\n", lev_config_name(l), blockcur); + 1080 : ++io_error; + 1081 : io_error_on_this_block = 1; + 1082 : continue; + 1083 : } + 1084 : + 1085 : log_tag("parity_error:%u:%s: Read error. %s\n", blockcur, lev_config_name(l), strerror(errno)); + 1086 : log_fatal("WARNING! Unexpected read error in the %s disk, it isn't possible to sync.\n", lev_name(l)); + 1087 : log_fatal("Ensure that disk '%s' can be read.\n", lev_config_name(l)); + 1088 : log_fatal("Stopping at block %u\n", blockcur); + 1089 : ++error; + 1090 : goto bail; + 1091 : /* LCOV_EXCL_STOP */ + 1092 : } + 1093 : + 1094 : /* until now is parity */ + 1095 5112 : state_usage_parity(state, &l, 1); + 1096 : } + 1097 : + 1098 : /* if no error in parity read */ + 1099 852 : if (!io_error_on_this_block) { + 1100 : /* try to fix the data */ + 1101 : /* note that this is a simple fix algorithm, that doesn't take into */ + 1102 : /* account the case of a wrong parity */ + 1103 : /* only 'fix' supports the most advanced fixing */ + 1104 852 : raid_rec(failed_mac, failed_map, diskmax, state->level, state->block_size, buffer); + 1105 : + 1106 : /* until now is raid */ + 1107 852 : state_usage_raid(state); + 1108 : + 1109 : /* check the result and prepare the data */ + 1110 5112 : for (j = 0; j < failed_count; ++j) { + 1111 : unsigned char hash[HASH_MAX]; + 1112 1704 : unsigned char* block_buffer = buffer[failed[j].index]; + 1113 1704 : unsigned char* block_copy = copy[failed[j].index]; + 1114 1704 : unsigned block_state = block_state_get(failed[j].block); + 1115 : + 1116 1704 : if (block_state == BLOCK_STATE_BLK) { + 1117 852 : unsigned size = failed[j].size; + 1118 : + 1119 : /* compute the hash of the recovered block */ + 1120 852 : if (rehash) { + 1121 0 : memhash(state->prevhash, state->prevhashseed, hash, block_buffer, size); + 1122 : } else { + 1123 852 : memhash(state->hash, state->hashseed, hash, block_buffer, size); + 1124 : } + 1125 : + 1126 : /* until now is hash */ + 1127 852 : state_usage_hash(state); 1128 : - 1129 : /* pad with 0 if needed */ - 1130 852 : if (size < state->block_size) - 1131 349 : memset(block_buffer + size, 0, state->block_size - size); - 1132 : } else { - 1133 : /* otherwise restore the content */ - 1134 : /* because we are not interested in the old state */ - 1135 : /* that it's recovered for CHG, REP and DELETED blocks */ - 1136 852 : memcpy(block_buffer, block_copy, state->block_size); - 1137 : } - 1138 : } - 1139 : - 1140 : /* if all is processed, we have fixed it */ - 1141 852 : if (j == failed_count) - 1142 852 : fixed_error_on_this_block = 1; - 1143 : } - 1144 : } - 1145 : } - 1146 : - 1147 : /* if we have read all the data required and it's correct, proceed with the parity */ - 1148 114702 : if (!error_on_this_block && !io_error_on_this_block - 1149 114683 : && (!silent_error_on_this_block || fixed_error_on_this_block) - 1150 : ) { - 1151 : /* update the parity only if really needed */ - 1152 114683 : if (parity_needs_to_be_updated) { - 1153 : /* compute the parity */ - 1154 112401 : raid_gen(diskmax, state->level, state->block_size, buffer); - 1155 : - 1156 : /* until now is raid */ - 1157 112401 : state_usage_raid(state); - 1158 : - 1159 : /* mark that the parity is going to be written */ - 1160 112401 : parity_going_to_be_updated = 1; - 1161 : } - 1162 : - 1163 : /* for each disk, mark the blocks as processed */ - 1164 802781 : for (j = 0; j < diskmax; ++j) { - 1165 : struct snapraid_block* block; - 1166 : - 1167 688098 : if (!handle[j].disk) - 1168 0 : continue; - 1169 : - 1170 688098 : block = fs_par2block_find(handle[j].disk, blockcur); - 1171 : - 1172 688098 : if (block == BLOCK_NULL) { - 1173 : /* nothing to do */ - 1174 81231 : continue; - 1175 : } - 1176 : - 1177 : /* if it's a deleted block */ - 1178 606867 : if (block_state_get(block) == BLOCK_STATE_DELETED) { - 1179 : /* the parity is now updated without this block, so it's now empty */ - 1180 10953 : fs_deallocate(handle[j].disk, blockcur); - 1181 10953 : continue; - 1182 : } - 1183 : - 1184 : /* now all the blocks have the hash and the parity computed */ - 1185 595914 : block_state_set(block, BLOCK_STATE_BLK); - 1186 : } - 1187 : - 1188 : /* we update the info block only if we really have updated the parity */ - 1189 : /* because otherwise the time/justsynced info would be misleading as we didn't */ - 1190 : /* wrote the parity at this time */ - 1191 : /* we also update the info block only if no silent error was found */ - 1192 : /* because has no sense to refresh the time for data that we know bad */ - 1193 114683 : if (parity_needs_to_be_updated - 1194 112401 : && !silent_error_on_this_block - 1195 : ) { - 1196 : /* if rehash is needed */ - 1197 112055 : if (rehash) { - 1198 : /* store all the new hash already computed */ - 1199 32249 : for (j = 0; j < diskmax; ++j) { - 1200 27642 : if (rehandle[j].block) - 1201 27243 : memcpy(rehandle[j].block->hash, rehandle[j].hash, BLOCK_HASH_SIZE); - 1202 : } - 1203 : } - 1204 : - 1205 : /* update the time info of the block */ - 1206 : /* we are also clearing any previous bad and rehash flag */ - 1207 112055 : info_set(&state->infoarr, blockcur, info_make(now, 0, 0, 1)); - 1208 : } - 1209 : } + 1129 : /* if the hash doesn't match */ + 1130 852 : if (memcmp(hash, failed[j].block->hash, BLOCK_HASH_SIZE) != 0) { + 1131 : /* we have not recovered */ + 1132 0 : break; + 1133 : } + 1134 : + 1135 : /* pad with 0 if needed */ + 1136 852 : if (size < state->block_size) + 1137 345 : memset(block_buffer + size, 0, state->block_size - size); + 1138 : } else { + 1139 : /* otherwise restore the content */ + 1140 : /* because we are not interested in the old state */ + 1141 : /* that it's recovered for CHG, REP and DELETED blocks */ + 1142 852 : memcpy(block_buffer, block_copy, state->block_size); + 1143 : } + 1144 : } + 1145 : + 1146 : /* if all is processed, we have fixed it */ + 1147 852 : if (j == failed_count) + 1148 852 : fixed_error_on_this_block = 1; + 1149 : } + 1150 : } + 1151 : } + 1152 : + 1153 : /* if we have read all the data required and it's correct, proceed with the parity */ + 1154 114790 : if (!error_on_this_block && !io_error_on_this_block + 1155 114771 : && (!silent_error_on_this_block || fixed_error_on_this_block) + 1156 : ) { + 1157 : /* update the parity only if really needed */ + 1158 114771 : if (parity_needs_to_be_updated) { + 1159 : /* compute the parity */ + 1160 112474 : raid_gen(diskmax, state->level, state->block_size, buffer); + 1161 : + 1162 : /* until now is raid */ + 1163 112474 : state_usage_raid(state); + 1164 : + 1165 : /* mark that the parity is going to be written */ + 1166 112474 : parity_going_to_be_updated = 1; + 1167 : } + 1168 : + 1169 : /* for each disk, mark the blocks as processed */ + 1170 803397 : for (j = 0; j < diskmax; ++j) { + 1171 : struct snapraid_block* block; + 1172 : + 1173 688626 : if (!handle[j].disk) + 1174 0 : continue; + 1175 : + 1176 688626 : block = fs_par2block_find(handle[j].disk, blockcur); + 1177 : + 1178 688626 : if (block == BLOCK_NULL) { + 1179 : /* nothing to do */ + 1180 81210 : continue; + 1181 : } + 1182 : + 1183 : /* if it's a deleted block */ + 1184 607416 : if (block_state_get(block) == BLOCK_STATE_DELETED) { + 1185 : /* the parity is now updated without this block, so it's now empty */ + 1186 10953 : fs_deallocate(handle[j].disk, blockcur); + 1187 10953 : continue; + 1188 : } + 1189 : + 1190 : /* now all the blocks have the hash and the parity computed */ + 1191 596463 : block_state_set(block, BLOCK_STATE_BLK); + 1192 : } + 1193 : + 1194 : /* we update the info block only if we really have updated the parity */ + 1195 : /* because otherwise the time/justsynced info would be misleading as we didn't */ + 1196 : /* wrote the parity at this time */ + 1197 : /* we also update the info block only if no silent error was found */ + 1198 : /* because has no sense to refresh the time for data that we know bad */ + 1199 114771 : if (parity_needs_to_be_updated + 1200 112474 : && !silent_error_on_this_block + 1201 : ) { + 1202 : /* if rehash is needed */ + 1203 112132 : if (rehash) { + 1204 : /* store all the new hash already computed */ + 1205 32249 : for (j = 0; j < diskmax; ++j) { + 1206 27642 : if (rehandle[j].block) + 1207 27243 : memcpy(rehandle[j].block->hash, rehandle[j].hash, BLOCK_HASH_SIZE); + 1208 : } + 1209 : } 1210 : - 1211 : /* if a silent (even if corrected) or input/output error was found */ - 1212 : /* mark the block as bad to have check/fix to handle it */ - 1213 : /* because our correction is in memory only and not yet written */ - 1214 114702 : if (silent_error_on_this_block || io_error_on_this_block) { - 1215 : /* set the error status keeping the other info */ - 1216 852 : info_set(&state->infoarr, blockcur, info_set_bad(info)); - 1217 : } - 1218 : - 1219 : /* finally schedule parity write */ - 1220 : /* Note that the calls to io_parity_write() are mandatory */ - 1221 : /* even if the parity doesn't need to be updated */ - 1222 : /* This because we want to keep track of the time usage */ - 1223 114702 : state_usage_misc(state); + 1211 : /* update the time info of the block */ + 1212 : /* we are also clearing any previous bad and rehash flag */ + 1213 112132 : info_set(&state->infoarr, blockcur, info_make(now, 0, 0, 1)); + 1214 : } + 1215 : } + 1216 : + 1217 : /* if a silent (even if corrected) or input/output error was found */ + 1218 : /* mark the block as bad to have check/fix to handle it */ + 1219 : /* because our correction is in memory only and not yet written */ + 1220 114790 : if (silent_error_on_this_block || io_error_on_this_block) { + 1221 : /* set the error status keeping the other info */ + 1222 852 : info_set(&state->infoarr, blockcur, info_set_bad(info)); + 1223 : } 1224 : - 1225 : /* write start */ - 1226 114702 : io_write_preset(&io, blockcur, !parity_going_to_be_updated); - 1227 : - 1228 : /* write the parity */ - 1229 672809 : for (l = 0; l < state->level; ++l) { - 1230 : unsigned levcur; - 1231 : - 1232 558107 : io_parity_write(&io, &levcur, waiting_map, &waiting_mac); + 1225 : /* finally schedule parity write */ + 1226 : /* Note that the calls to io_parity_write() are mandatory */ + 1227 : /* even if the parity doesn't need to be updated */ + 1228 : /* This because we want to keep track of the time usage */ + 1229 114790 : state_usage_misc(state); + 1230 : + 1231 : /* write start */ + 1232 114790 : io_write_preset(&io, blockcur, !parity_going_to_be_updated); 1233 : - 1234 : /* until now is parity */ - 1235 558107 : state_usage_parity(state, waiting_map, waiting_mac); - 1236 : } + 1234 : /* write the parity */ + 1235 673425 : for (l = 0; l < state->level; ++l) { + 1236 : unsigned levcur; 1237 : - 1238 : /* write finished */ - 1239 114702 : io_write_next(&io, blockcur, !parity_going_to_be_updated, writer_error); - 1240 : - 1241 : /* handle errors reported */ - 1242 573510 : for (j = 0; j < IO_WRITER_ERROR_MAX; ++j) { - 1243 458808 : if (writer_error[j]) { - 1244 0 : switch (j + IO_WRITER_ERROR_BASE) { - 1245 : case TASK_STATE_IOERROR_CONTINUE : - 1246 0 : ++io_error; - 1247 0 : if (io_error >= state->opt.io_error_limit) { - 1248 0 : log_fatal("DANGER! Unexpected input/output write error in a parity disk, it isn't possible to sync.\n"); - 1249 0 : log_fatal("Stopping at block %u\n", blockcur); - 1250 0 : goto bail; - 1251 : } - 1252 0 : break; - 1253 : case TASK_STATE_ERROR_CONTINUE : - 1254 0 : ++error; - 1255 0 : break; - 1256 : case TASK_STATE_IOERROR : - 1257 0 : ++io_error; - 1258 0 : goto bail; - 1259 : case TASK_STATE_ERROR : - 1260 0 : ++error; - 1261 0 : goto bail; - 1262 : } - 1263 : } - 1264 : } - 1265 : - 1266 : /* mark the state as needing write */ - 1267 114702 : state->need_write = 1; - 1268 : - 1269 : /* count the number of processed block */ - 1270 114702 : ++countpos; - 1271 : - 1272 : /* progress */ - 1273 114702 : if (state_progress(state, &io, blockcur, countpos, countmax, countsize)) { - 1274 : /* LCOV_EXCL_START */ - 1275 : break; - 1276 : /* LCOV_EXCL_STOP */ - 1277 : } - 1278 : - 1279 : /* autosave */ - 1280 114702 : if ((state->autosave != 0 - 1281 26021 : && autosavedone >= autosavelimit /* if we have reached the limit */ - 1282 0 : && autosavemissing >= autosavelimit) /* if we have at least a full step to do */ - 1283 : /* or if we have a forced autosave at the specified block */ - 1284 114702 : || (state->opt.force_autosave_at != 0 && state->opt.force_autosave_at == blockcur) - 1285 : ) { - 1286 1 : autosavedone = 0; /* restart the counter */ - 1287 : - 1288 : /* until now is misc */ - 1289 1 : state_usage_misc(state); + 1238 558635 : io_parity_write(&io, &levcur, waiting_map, &waiting_mac); + 1239 : + 1240 : /* until now is parity */ + 1241 558635 : state_usage_parity(state, waiting_map, waiting_mac); + 1242 : } + 1243 : + 1244 : /* write finished */ + 1245 114790 : io_write_next(&io, blockcur, !parity_going_to_be_updated, writer_error); + 1246 : + 1247 : /* handle errors reported */ + 1248 573950 : for (j = 0; j < IO_WRITER_ERROR_MAX; ++j) { + 1249 459160 : if (writer_error[j]) { + 1250 0 : switch (j + IO_WRITER_ERROR_BASE) { + 1251 : case TASK_STATE_IOERROR_CONTINUE : + 1252 0 : ++io_error; + 1253 0 : if (io_error >= state->opt.io_error_limit) { + 1254 : /* LCOV_EXCL_START */ + 1255 : log_fatal("DANGER! Unexpected input/output write error in a parity disk, it isn't possible to sync.\n"); + 1256 : log_fatal("Stopping at block %u\n", blockcur); + 1257 : goto bail; + 1258 : /* LCOV_EXCL_STOP */ + 1259 : } + 1260 0 : break; + 1261 : case TASK_STATE_ERROR_CONTINUE : + 1262 0 : ++error; + 1263 0 : break; + 1264 : case TASK_STATE_IOERROR : + 1265 : /* LCOV_EXCL_START */ + 1266 : ++io_error; + 1267 : goto bail; + 1268 : /* LCOV_EXCL_STOP */ + 1269 : case TASK_STATE_ERROR : + 1270 : /* LCOV_EXCL_START */ + 1271 : ++error; + 1272 : goto bail; + 1273 : /* LCOV_EXCL_STOP */ + 1274 : } + 1275 : } + 1276 : } + 1277 : + 1278 : /* mark the state as needing write */ + 1279 114790 : state->need_write = 1; + 1280 : + 1281 : /* count the number of processed block */ + 1282 114790 : ++countpos; + 1283 : + 1284 : /* progress */ + 1285 114790 : if (state_progress(state, &io, blockcur, countpos, countmax, countsize)) { + 1286 : /* LCOV_EXCL_START */ + 1287 : break; + 1288 : /* LCOV_EXCL_STOP */ + 1289 : } 1290 : - 1291 1 : state_progress_stop(state); - 1292 : - 1293 1 : msg_progress("Autosaving...\n"); - 1294 : - 1295 : /* before writing the new content file we ensure that */ - 1296 : /* the parity is really written flushing the disk cache */ - 1297 7 : for (l = 0; l < state->level; ++l) { - 1298 6 : ret = parity_sync(&parity_handle[l]); - 1299 6 : if (ret == -1) { - 1300 : /* LCOV_EXCL_START */ - 1301 : log_tag("parity_error:%u:%s: Sync error\n", blockcur, lev_config_name(l)); - 1302 : log_fatal("DANGER! Unexpected sync error in %s disk.\n", lev_name(l)); - 1303 : log_fatal("Ensure that disk '%s' is sane.\n", lev_config_name(l)); - 1304 : log_fatal("Stopping at block %u\n", blockcur); - 1305 : ++error; - 1306 : goto bail; - 1307 : /* LCOV_EXCL_STOP */ - 1308 : } - 1309 : } - 1310 : - 1311 : /* now we can safely write the content file */ - 1312 1 : state_write(state); - 1313 : - 1314 1 : state_progress_restart(state); - 1315 : - 1316 : /* drop until now */ - 1317 1 : state_usage_waste(state); - 1318 : } - 1319 114702 : } - 1320 : - 1321 : end: - 1322 83 : state_progress_end(state, countpos, countmax, countsize); - 1323 : - 1324 83 : state_usage_print(state); + 1291 : /* autosave */ + 1292 114790 : if ((state->autosave != 0 + 1293 26021 : && autosavedone >= autosavelimit /* if we have reached the limit */ + 1294 0 : && autosavemissing >= autosavelimit) /* if we have at least a full step to do */ + 1295 : /* or if we have a forced autosave at the specified block */ + 1296 114790 : || (state->opt.force_autosave_at != 0 && state->opt.force_autosave_at == blockcur) + 1297 : ) { + 1298 1 : autosavedone = 0; /* restart the counter */ + 1299 : + 1300 : /* until now is misc */ + 1301 1 : state_usage_misc(state); + 1302 : + 1303 1 : state_progress_stop(state); + 1304 : + 1305 1 : msg_progress("Autosaving...\n"); + 1306 : + 1307 : /* before writing the new content file we ensure that */ + 1308 : /* the parity is really written flushing the disk cache */ + 1309 7 : for (l = 0; l < state->level; ++l) { + 1310 6 : ret = parity_sync(&parity_handle[l]); + 1311 6 : if (ret == -1) { + 1312 : /* LCOV_EXCL_START */ + 1313 : log_tag("parity_error:%u:%s: Sync error\n", blockcur, lev_config_name(l)); + 1314 : log_fatal("DANGER! Unexpected sync error in %s disk.\n", lev_name(l)); + 1315 : log_fatal("Ensure that disk '%s' is sane.\n", lev_config_name(l)); + 1316 : log_fatal("Stopping at block %u\n", blockcur); + 1317 : ++error; + 1318 : goto bail; + 1319 : /* LCOV_EXCL_STOP */ + 1320 : } + 1321 : } + 1322 : + 1323 : /* now we can safely write the content file */ + 1324 1 : state_write(state); 1325 : - 1326 : /* before returning we ensure that */ - 1327 : /* the parity is really written flushing the disk cache */ - 1328 546 : for (l = 0; l < state->level; ++l) { - 1329 463 : ret = parity_sync(&parity_handle[l]); - 1330 463 : if (ret == -1) { - 1331 : /* LCOV_EXCL_START */ - 1332 : log_tag("parity_error:%u:%s: Sync error\n", blockcur, lev_config_name(l)); - 1333 : log_fatal("DANGER! Unexpected sync error in %s disk.\n", lev_name(l)); - 1334 : log_fatal("Ensure that disk '%s' is sane.\n", lev_config_name(l)); - 1335 : log_fatal("Stopping at block %u\n", blockcur); - 1336 : ++error; - 1337 : goto bail; - 1338 : /* LCOV_EXCL_STOP */ - 1339 : } - 1340 : } - 1341 : - 1342 83 : if (error || silent_error || io_error) { - 1343 12 : msg_status("\n"); - 1344 12 : msg_status("%8u file errors\n", error); - 1345 12 : msg_status("%8u io errors\n", io_error); - 1346 12 : msg_status("%8u data errors\n", silent_error); - 1347 : } else { - 1348 : /* print the result only if processed something */ - 1349 71 : if (countpos != 0) - 1350 53 : msg_status("Everything OK\n"); - 1351 : } - 1352 : - 1353 83 : if (error) - 1354 11 : log_fatal("WARNING! Unexpected file errors!\n"); - 1355 83 : if (io_error) - 1356 0 : log_fatal("DANGER! Unexpected input/output errors! The failing blocks are now marked as bad!\n"); - 1357 83 : if (silent_error) - 1358 1 : log_fatal("DANGER! Unexpected data errors! The failing blocks are now marked as bad!\n"); - 1359 83 : if (io_error || silent_error) { - 1360 1 : log_fatal("Use 'snapraid status' to list the bad blocks.\n"); - 1361 1 : log_fatal("Use 'snapraid -e fix' to recover.\n"); - 1362 : } - 1363 : - 1364 83 : log_tag("summary:error_file:%u\n", error); - 1365 83 : log_tag("summary:error_io:%u\n", io_error); - 1366 83 : log_tag("summary:error_data:%u\n", silent_error); - 1367 83 : if (error + silent_error + io_error == 0) - 1368 71 : log_tag("summary:exit:ok\n"); - 1369 : else - 1370 12 : log_tag("summary:exit:error\n"); - 1371 83 : log_flush(); - 1372 : - 1373 : bail: - 1374 : /* stop all the worker threads */ - 1375 83 : io_stop(&io); - 1376 : - 1377 581 : for (j = 0; j < diskmax; ++j) { - 1378 498 : struct snapraid_file* file = handle[j].file; - 1379 498 : struct snapraid_disk* disk = handle[j].disk; - 1380 498 : ret = handle_close(&handle[j]); - 1381 498 : if (ret == -1) { - 1382 : /* LCOV_EXCL_START */ - 1383 : log_tag("error:%u:%s:%s: Close error. %s\n", blockcur, disk->name, esc_tag(file->sub, esc_buffer), strerror(errno)); - 1384 : log_fatal("DANGER! Unexpected close error in a data disk.\n"); - 1385 : ++error; - 1386 : /* continue, as we are already exiting */ - 1387 : /* LCOV_EXCL_STOP */ - 1388 : } - 1389 : } - 1390 : - 1391 83 : free(handle); - 1392 83 : free(zero_alloc); - 1393 83 : free(copy_alloc); - 1394 83 : free(copy); - 1395 83 : free(rehandle_alloc); - 1396 83 : free(failed); - 1397 83 : free(failed_map); - 1398 83 : free(waiting_map); - 1399 83 : io_done(&io); - 1400 : - 1401 83 : if (state->opt.expect_recoverable) { - 1402 1 : if (error + silent_error + io_error == 0) - 1403 0 : return -1; - 1404 : } else { - 1405 82 : if (error + silent_error + io_error != 0) - 1406 11 : return -1; - 1407 : } - 1408 72 : return 0; - 1409 : } - 1410 : - 1411 87 : int state_sync(struct snapraid_state* state, block_off_t blockstart, block_off_t blockcount) - 1412 : { - 1413 : block_off_t blockmax; - 1414 : block_off_t used_paritymax; - 1415 : block_off_t file_paritymax; - 1416 : data_off_t size; - 1417 : int ret; - 1418 : struct snapraid_parity_handle parity_handle[LEV_MAX]; - 1419 : unsigned unrecoverable_error; - 1420 : unsigned l; - 1421 87 : int skip_sync = 0; + 1326 1 : state_progress_restart(state); + 1327 : + 1328 : /* drop until now */ + 1329 1 : state_usage_waste(state); + 1330 : } + 1331 114790 : } + 1332 : + 1333 : end: + 1334 83 : state_progress_end(state, countpos, countmax, countsize); + 1335 : + 1336 83 : state_usage_print(state); + 1337 : + 1338 : /* before returning we ensure that */ + 1339 : /* the parity is really written flushing the disk cache */ + 1340 546 : for (l = 0; l < state->level; ++l) { + 1341 463 : ret = parity_sync(&parity_handle[l]); + 1342 463 : if (ret == -1) { + 1343 : /* LCOV_EXCL_START */ + 1344 : log_tag("parity_error:%u:%s: Sync error\n", blockcur, lev_config_name(l)); + 1345 : log_fatal("DANGER! Unexpected sync error in %s disk.\n", lev_name(l)); + 1346 : log_fatal("Ensure that disk '%s' is sane.\n", lev_config_name(l)); + 1347 : log_fatal("Stopping at block %u\n", blockcur); + 1348 : ++error; + 1349 : goto bail; + 1350 : /* LCOV_EXCL_STOP */ + 1351 : } + 1352 : } + 1353 : + 1354 83 : if (error || silent_error || io_error) { + 1355 12 : msg_status("\n"); + 1356 12 : msg_status("%8u file errors\n", error); + 1357 12 : msg_status("%8u io errors\n", io_error); + 1358 12 : msg_status("%8u data errors\n", silent_error); + 1359 : } else { + 1360 : /* print the result only if processed something */ + 1361 71 : if (countpos != 0) + 1362 53 : msg_status("Everything OK\n"); + 1363 : } + 1364 : + 1365 83 : if (error) + 1366 11 : log_fatal("WARNING! Unexpected file errors!\n"); + 1367 83 : if (io_error) + 1368 0 : log_fatal("DANGER! Unexpected input/output errors! The failing blocks are now marked as bad!\n"); + 1369 83 : if (silent_error) + 1370 1 : log_fatal("DANGER! Unexpected data errors! The failing blocks are now marked as bad!\n"); + 1371 83 : if (io_error || silent_error) { + 1372 1 : log_fatal("Use 'snapraid status' to list the bad blocks.\n"); + 1373 1 : log_fatal("Use 'snapraid -e fix' to recover.\n"); + 1374 : } + 1375 : + 1376 83 : log_tag("summary:error_file:%u\n", error); + 1377 83 : log_tag("summary:error_io:%u\n", io_error); + 1378 83 : log_tag("summary:error_data:%u\n", silent_error); + 1379 83 : if (error + silent_error + io_error == 0) + 1380 71 : log_tag("summary:exit:ok\n"); + 1381 : else + 1382 12 : log_tag("summary:exit:error\n"); + 1383 83 : log_flush(); + 1384 : + 1385 : bail: + 1386 : /* stop all the worker threads */ + 1387 83 : io_stop(&io); + 1388 : + 1389 581 : for (j = 0; j < diskmax; ++j) { + 1390 498 : struct snapraid_file* file = handle[j].file; + 1391 498 : struct snapraid_disk* disk = handle[j].disk; + 1392 498 : ret = handle_close(&handle[j]); + 1393 498 : if (ret == -1) { + 1394 : /* LCOV_EXCL_START */ + 1395 : log_tag("error:%u:%s:%s: Close error. %s\n", blockcur, disk->name, esc_tag(file->sub, esc_buffer), strerror(errno)); + 1396 : log_fatal("DANGER! Unexpected close error in a data disk.\n"); + 1397 : ++error; + 1398 : /* continue, as we are already exiting */ + 1399 : /* LCOV_EXCL_STOP */ + 1400 : } + 1401 : } + 1402 : + 1403 83 : free(handle); + 1404 83 : free(zero_alloc); + 1405 83 : free(copy_alloc); + 1406 83 : free(copy); + 1407 83 : free(rehandle_alloc); + 1408 83 : free(failed); + 1409 83 : free(failed_map); + 1410 83 : free(waiting_map); + 1411 83 : io_done(&io); + 1412 : + 1413 83 : if (state->opt.expect_recoverable) { + 1414 1 : if (error + silent_error + io_error == 0) + 1415 0 : return -1; + 1416 : } else { + 1417 82 : if (error + silent_error + io_error != 0) + 1418 11 : return -1; + 1419 : } + 1420 72 : return 0; + 1421 : } 1422 : - 1423 87 : msg_progress("Initializing...\n"); - 1424 : - 1425 87 : blockmax = parity_allocated_size(state); - 1426 87 : size = blockmax * (data_off_t)state->block_size; - 1427 : - 1428 : /* minimum size of the parity files we expect */ - 1429 87 : used_paritymax = parity_used_size(state); - 1430 : - 1431 : /* effective size of the parity files */ - 1432 87 : file_paritymax = 0; - 1433 : - 1434 87 : if (blockstart > blockmax) { - 1435 : /* LCOV_EXCL_START */ - 1436 : log_fatal("Error in the starting block %u. It's bigger than the parity size %u.\n", blockstart, blockmax); - 1437 : exit(EXIT_FAILURE); - 1438 : /* LCOV_EXCL_STOP */ - 1439 : } - 1440 : - 1441 : /* adjust the number of block to process */ - 1442 87 : if (blockcount != 0 && blockstart + blockcount < blockmax) { - 1443 6 : blockmax = blockstart + blockcount; - 1444 : } + 1423 87 : int state_sync(struct snapraid_state* state, block_off_t blockstart, block_off_t blockcount) + 1424 : { + 1425 : block_off_t blockmax; + 1426 : block_off_t used_paritymax; + 1427 : block_off_t file_paritymax; + 1428 : data_off_t size; + 1429 : int ret; + 1430 : struct snapraid_parity_handle parity_handle[LEV_MAX]; + 1431 : unsigned unrecoverable_error; + 1432 : unsigned l; + 1433 87 : int skip_sync = 0; + 1434 : + 1435 87 : msg_progress("Initializing...\n"); + 1436 : + 1437 87 : blockmax = parity_allocated_size(state); + 1438 87 : size = blockmax * (data_off_t)state->block_size; + 1439 : + 1440 : /* minimum size of the parity files we expect */ + 1441 87 : used_paritymax = parity_used_size(state); + 1442 : + 1443 : /* effective size of the parity files */ + 1444 87 : file_paritymax = 0; 1445 : - 1446 574 : for (l = 0; l < state->level; ++l) { - 1447 : data_off_t out_size; - 1448 : block_off_t parityblocks; - 1449 : - 1450 : /* create the file and open for writing */ - 1451 487 : ret = parity_create(&parity_handle[l], &state->parity[l], l, state->file_mode, state->block_size, state->opt.parity_limit_size); - 1452 487 : if (ret == -1) { - 1453 : /* LCOV_EXCL_START */ - 1454 : log_fatal("WARNING! Without an accessible %s file, it isn't possible to sync.\n", lev_name(l)); - 1455 : exit(EXIT_FAILURE); - 1456 : /* LCOV_EXCL_STOP */ - 1457 : } - 1458 : - 1459 : /* number of block in the parity file */ - 1460 487 : parity_size(&parity_handle[l], &out_size); - 1461 487 : parityblocks = out_size / state->block_size; - 1462 : - 1463 : /* if the file is too small */ - 1464 487 : if (parityblocks < used_paritymax) { - 1465 0 : log_fatal("WARNING! The %s parity has data only %u blocks instead of %u.\n", lev_name(l), parityblocks, used_paritymax); - 1466 : } - 1467 : - 1468 : /* keep the smallest parity number of blocks */ - 1469 487 : if (l == 0 || file_paritymax > parityblocks) - 1470 87 : file_paritymax = parityblocks; - 1471 : } - 1472 : - 1473 : /* if we do a full parity realloc or computation, having a wrong parity size is expected */ - 1474 87 : if (!state->opt.force_realloc && !state->opt.force_full) { - 1475 : /* if the parities are too small */ - 1476 80 : if (file_paritymax < used_paritymax) { - 1477 : /* LCOV_EXCL_START */ - 1478 : log_fatal("DANGER! One or more the parity files are smaller than expected!\n"); - 1479 : if (file_paritymax != 0) { - 1480 : log_fatal("If this happens because you are using an old content file,\n"); - 1481 : log_fatal("you can 'sync' anyway using 'snapraid --force-full sync'\n"); - 1482 : log_fatal("to force a full rebuild of the parity.\n"); - 1483 : } else { - 1484 : log_fatal("It's possible that the parity disks are not mounted.\n"); - 1485 : log_fatal("If instead you are adding a new parity level, you can 'sync' using\n"); - 1486 : log_fatal("'snapraid --force-full sync' to force a full rebuild of the parity.\n"); - 1487 : } - 1488 : exit(EXIT_FAILURE); - 1489 : /* LCOV_EXCL_STOP */ - 1490 : } - 1491 : } - 1492 : - 1493 87 : unrecoverable_error = 0; - 1494 : - 1495 87 : if (state->opt.prehash) { - 1496 7 : msg_progress("Hashing...\n"); - 1497 : - 1498 7 : ret = state_hash_process(state, blockstart, blockmax, &skip_sync); - 1499 7 : if (ret == -1) { - 1500 : /* LCOV_EXCL_START */ - 1501 : ++unrecoverable_error; - 1502 : /* continue, in case also doing the sync if ::skip_sync is not set */ - 1503 : /* LCOV_EXCL_STOP */ - 1504 : } - 1505 : } + 1446 87 : if (blockstart > blockmax) { + 1447 : /* LCOV_EXCL_START */ + 1448 : log_fatal("Error in the starting block %u. It's bigger than the parity size %u.\n", blockstart, blockmax); + 1449 : exit(EXIT_FAILURE); + 1450 : /* LCOV_EXCL_STOP */ + 1451 : } + 1452 : + 1453 : /* adjust the number of block to process */ + 1454 87 : if (blockcount != 0 && blockstart + blockcount < blockmax) { + 1455 6 : blockmax = blockstart + blockcount; + 1456 : } + 1457 : + 1458 574 : for (l = 0; l < state->level; ++l) { + 1459 : data_off_t out_size; + 1460 : block_off_t parityblocks; + 1461 : + 1462 : /* create the file and open for writing */ + 1463 487 : ret = parity_create(&parity_handle[l], &state->parity[l], l, state->file_mode, state->block_size, state->opt.parity_limit_size); + 1464 487 : if (ret == -1) { + 1465 : /* LCOV_EXCL_START */ + 1466 : log_fatal("WARNING! Without an accessible %s file, it isn't possible to sync.\n", lev_name(l)); + 1467 : exit(EXIT_FAILURE); + 1468 : /* LCOV_EXCL_STOP */ + 1469 : } + 1470 : + 1471 : /* number of block in the parity file */ + 1472 487 : parity_size(&parity_handle[l], &out_size); + 1473 487 : parityblocks = out_size / state->block_size; + 1474 : + 1475 : /* if the file is too small */ + 1476 487 : if (parityblocks < used_paritymax) { + 1477 0 : log_fatal("WARNING! The %s parity has data only %u blocks instead of %u.\n", lev_name(l), parityblocks, used_paritymax); + 1478 : } + 1479 : + 1480 : /* keep the smallest parity number of blocks */ + 1481 487 : if (l == 0 || file_paritymax > parityblocks) + 1482 87 : file_paritymax = parityblocks; + 1483 : } + 1484 : + 1485 : /* if we do a full parity realloc or computation, having a wrong parity size is expected */ + 1486 87 : if (!state->opt.force_realloc && !state->opt.force_full) { + 1487 : /* if the parities are too small */ + 1488 80 : if (file_paritymax < used_paritymax) { + 1489 : /* LCOV_EXCL_START */ + 1490 : log_fatal("DANGER! One or more the parity files are smaller than expected!\n"); + 1491 : if (file_paritymax != 0) { + 1492 : log_fatal("If this happens because you are using an old content file,\n"); + 1493 : log_fatal("you can 'sync' anyway using 'snapraid --force-full sync'\n"); + 1494 : log_fatal("to force a full rebuild of the parity.\n"); + 1495 : } else { + 1496 : log_fatal("It's possible that the parity disks are not mounted.\n"); + 1497 : log_fatal("If instead you are adding a new parity level, you can 'sync' using\n"); + 1498 : log_fatal("'snapraid --force-full sync' to force a full rebuild of the parity.\n"); + 1499 : } + 1500 : exit(EXIT_FAILURE); + 1501 : /* LCOV_EXCL_STOP */ + 1502 : } + 1503 : } + 1504 : + 1505 87 : unrecoverable_error = 0; 1506 : - 1507 87 : if (!skip_sync) { - 1508 86 : msg_progress("Resizing...\n"); + 1507 87 : if (state->opt.prehash) { + 1508 7 : msg_progress("Hashing...\n"); 1509 : - 1510 : /* now change the size of all parities */ - 1511 567 : for (l = 0; l < state->level; ++l) { - 1512 : int is_modified; - 1513 : - 1514 : /* change the size of the parity file, truncating or extending it */ - 1515 : /* from this point all the DELETED blocks after the end of the parity are invalid */ - 1516 : /* and they are automatically removed when we save the new content file */ - 1517 481 : ret = parity_chsize(&parity_handle[l], &state->parity[l], &is_modified, size, state->block_size, state->opt.skip_fallocate, state->opt.skip_space_holder); - 1518 481 : if (ret == -1) { - 1519 : /* LCOV_EXCL_START */ - 1520 : data_off_t out_size; - 1521 : parity_size(&parity_handle[l], &out_size); - 1522 : parity_overflow(state, out_size); - 1523 : log_fatal("WARNING! Without an unsable %s file, it isn't possible to sync.\n", lev_name(l)); - 1524 : exit(EXIT_FAILURE); - 1525 : /* LCOV_EXCL_STOP */ - 1526 : } - 1527 : - 1528 481 : if (is_modified) - 1529 175 : state->need_write = 1; - 1530 : } - 1531 : - 1532 : /* after resizing parity files, refresh again the free info */ - 1533 86 : state_refresh(state); - 1534 : - 1535 : /** - 1536 : * Save the new state before the sync but after the hashing phase - 1537 : * - 1538 : * This allows to recover after an aborted sync, and at the same time - 1539 : * it allows to recover broken copied/moved files identified in the - 1540 : * hashing phase. - 1541 : * - 1542 : * For example, think at this case: - 1543 : * - Add some files at the array - 1544 : * - Run a sync command, it will recompute the parity adding the new files - 1545 : * - Abort the sync command before it stores the new content file - 1546 : * - Delete the not yet synced files from the array - 1547 : * - Run a new sync command - 1548 : * - 1549 : * The sync command has no way to know that the parity file was modified - 1550 : * because the files triggering these changes are now deleted and they aren't - 1551 : * listed in the content file. - 1552 : * Instead, saving the new content file in advance, keeps track of all the parity - 1553 : * that may be modified. - 1554 : */ - 1555 86 : if (!state->opt.skip_content_write) { - 1556 86 : if (state->need_write) - 1557 79 : state_write(state); - 1558 : } else { - 1559 0 : log_fatal("WARNING! Skipped state write for --test-skip-content-write option.\n"); - 1560 : } - 1561 : - 1562 86 : msg_progress("Syncing...\n"); - 1563 : - 1564 : /* skip degenerated cases of empty parity, or skipping all */ - 1565 86 : if (blockstart < blockmax) { - 1566 83 : ret = state_sync_process(state, parity_handle, blockstart, blockmax); - 1567 83 : if (ret == -1) { - 1568 : /* LCOV_EXCL_START */ - 1569 : ++unrecoverable_error; - 1570 : /* continue, as we are already exiting */ - 1571 : /* LCOV_EXCL_STOP */ - 1572 : } - 1573 : } else { - 1574 3 : msg_status("Nothing to do\n"); - 1575 : } - 1576 : } - 1577 : - 1578 574 : for (l = 0; l < state->level; ++l) { - 1579 487 : ret = parity_close(&parity_handle[l]); - 1580 487 : if (ret == -1) { - 1581 : /* LCOV_EXCL_START */ - 1582 : log_fatal("DANGER! Unexpected close error in %s disk.\n", lev_name(l)); - 1583 : ++unrecoverable_error; - 1584 : /* continue, as we are already exiting */ - 1585 : /* LCOV_EXCL_STOP */ - 1586 : } - 1587 : } - 1588 : - 1589 : /* abort if required */ - 1590 87 : if (unrecoverable_error != 0) - 1591 12 : return -1; - 1592 75 : return 0; - 1593 : } - 1594 : + 1510 7 : ret = state_hash_process(state, blockstart, blockmax, &skip_sync); + 1511 7 : if (ret == -1) { + 1512 : /* LCOV_EXCL_START */ + 1513 : ++unrecoverable_error; + 1514 : /* continue, in case also doing the sync if ::skip_sync is not set */ + 1515 : /* LCOV_EXCL_STOP */ + 1516 : } + 1517 : } + 1518 : + 1519 87 : if (!skip_sync) { + 1520 86 : msg_progress("Resizing...\n"); + 1521 : + 1522 : /* now change the size of all parities */ + 1523 567 : for (l = 0; l < state->level; ++l) { + 1524 : int is_modified; + 1525 : + 1526 : /* change the size of the parity file, truncating or extending it */ + 1527 : /* from this point all the DELETED blocks after the end of the parity are invalid */ + 1528 : /* and they are automatically removed when we save the new content file */ + 1529 481 : ret = parity_chsize(&parity_handle[l], &state->parity[l], &is_modified, size, state->block_size, state->opt.skip_fallocate, state->opt.skip_space_holder); + 1530 481 : if (ret == -1) { + 1531 : /* LCOV_EXCL_START */ + 1532 : data_off_t out_size; + 1533 : parity_size(&parity_handle[l], &out_size); + 1534 : parity_overflow(state, out_size); + 1535 : log_fatal("WARNING! Without an unsable %s file, it isn't possible to sync.\n", lev_name(l)); + 1536 : exit(EXIT_FAILURE); + 1537 : /* LCOV_EXCL_STOP */ + 1538 : } + 1539 : + 1540 481 : if (is_modified) + 1541 175 : state->need_write = 1; + 1542 : } + 1543 : + 1544 : /* after resizing parity files, refresh again the free info */ + 1545 86 : state_refresh(state); + 1546 : + 1547 : /** + 1548 : * Save the new state before the sync but after the hashing phase + 1549 : * + 1550 : * This allows to recover after an aborted sync, and at the same time + 1551 : * it allows to recover broken copied/moved files identified in the + 1552 : * hashing phase. + 1553 : * + 1554 : * For example, think at this case: + 1555 : * - Add some files at the array + 1556 : * - Run a sync command, it will recompute the parity adding the new files + 1557 : * - Abort the sync command before it stores the new content file + 1558 : * - Delete the not yet synced files from the array + 1559 : * - Run a new sync command + 1560 : * + 1561 : * The sync command has no way to know that the parity file was modified + 1562 : * because the files triggering these changes are now deleted and they aren't + 1563 : * listed in the content file. + 1564 : * Instead, saving the new content file in advance, keeps track of all the parity + 1565 : * that may be modified. + 1566 : */ + 1567 86 : if (!state->opt.skip_content_write) { + 1568 86 : if (state->need_write) + 1569 79 : state_write(state); + 1570 : } else { + 1571 0 : log_fatal("WARNING! Skipped state write for --test-skip-content-write option.\n"); + 1572 : } + 1573 : + 1574 86 : msg_progress("Syncing...\n"); + 1575 : + 1576 : /* skip degenerated cases of empty parity, or skipping all */ + 1577 86 : if (blockstart < blockmax) { + 1578 83 : ret = state_sync_process(state, parity_handle, blockstart, blockmax); + 1579 83 : if (ret == -1) { + 1580 : /* LCOV_EXCL_START */ + 1581 : ++unrecoverable_error; + 1582 : /* continue, as we are already exiting */ + 1583 : /* LCOV_EXCL_STOP */ + 1584 : } + 1585 : } else { + 1586 3 : msg_status("Nothing to do\n"); + 1587 : } + 1588 : } + 1589 : + 1590 574 : for (l = 0; l < state->level; ++l) { + 1591 487 : ret = parity_close(&parity_handle[l]); + 1592 487 : if (ret == -1) { + 1593 : /* LCOV_EXCL_START */ + 1594 : log_fatal("DANGER! Unexpected close error in %s disk.\n", lev_name(l)); + 1595 : ++unrecoverable_error; + 1596 : /* continue, as we are already exiting */ + 1597 : /* LCOV_EXCL_STOP */ + 1598 : } + 1599 : } + 1600 : + 1601 : /* abort if required */ + 1602 87 : if (unrecoverable_error != 0) + 1603 12 : return -1; + 1604 75 : return 0; + 1605 : } + 1606 : diff --git a/cov/cmdline/unix.c.func-sort-c.html b/cov/cmdline/unix.c.func-sort-c.html index 9a1a9433..d6c41af0 100644 --- a/cov/cmdline/unix.c.func-sort-c.html +++ b/cov/cmdline/unix.c.func-sort-c.html @@ -61,11 +61,11 @@ tick - 3816813 + 3819196 open_noatime - 1719371 + 1719485 filephy @@ -73,23 +73,23 @@ devuuid - 5624 + 5630 devuuid_dev - 5620 + 5626 fsinfo - 5477 + 5483 randomize - 280 + 281 os_init - 269 + 270 os_done @@ -100,12 +100,12 @@ 191 - devresolve + devresolve_sys 191 - devresolve_sys - 191 + devresolve + 172 devread diff --git a/cov/cmdline/unix.c.func.html b/cov/cmdline/unix.c.func.html index 0abc1827..6f1fae44 100644 --- a/cov/cmdline/unix.c.func.html +++ b/cov/cmdline/unix.c.func.html @@ -81,7 +81,7 @@ devresolve - 191 + 172 devresolve_proc @@ -109,7 +109,7 @@ devuuid - 5624 + 5630 devuuid_blkid @@ -117,7 +117,7 @@ devuuid_dev - 5620 + 5626 direct_size @@ -133,11 +133,11 @@ fsinfo - 5477 + 5483 open_noatime - 1719371 + 1719485 os_clear @@ -149,11 +149,11 @@ os_init - 269 + 270 randomize - 280 + 281 stat_desc @@ -177,7 +177,7 @@ tick - 3816813 + 3819196 tick_ms diff --git a/cov/cmdline/unix.c.gcov.html b/cov/cmdline/unix.c.gcov.html index 4f7defe9..8cf5fd09 100644 --- a/cov/cmdline/unix.c.gcov.html +++ b/cov/cmdline/unix.c.gcov.html @@ -90,15 +90,15 @@ 28 : int exit_failure = 1; 29 : int exit_sync_needed = 2; 30 : - 31 1719371 : int open_noatime(const char* file, int flags) + 31 1719485 : int open_noatime(const char* file, int flags) 32 : { 33 : #ifdef O_NOATIME - 34 1719371 : int f = open(file, flags | O_NOATIME); + 34 1719485 : int f = open(file, flags | O_NOATIME); 35 : 36 : /* only root is allowed to use O_NOATIME, in case retry without it */ - 37 1719426 : if (f == -1 && errno == EPERM) + 37 1719550 : if (f == -1 && errno == EPERM) 38 0 : f = open(file, flags); - 39 1719420 : return f; + 39 1719558 : return f; 40 : #else 41 : return open(file, flags); 42 : #endif @@ -324,23 +324,23 @@ 262 : } 263 : 264 191 : ret = close(f); - 265 190 : if (ret != 0) { + 265 191 : if (ret != 0) { 266 : /* LCOV_EXCL_START */ 267 : log_fatal("Failed to close '%s'.\n", path); 268 : return -1; 269 : /* LCOV_EXCL_STOP */ 270 : } 271 : - 272 190 : buf[len] = 0; - 273 190 : tag_len = strlen(tag); + 272 191 : buf[len] = 0; + 273 191 : tag_len = strlen(tag); 274 : - 275 3321 : for (i = buf; *i; ++i) { - 276 3321 : char* p = i; + 275 3324 : for (i = buf; *i; ++i) { + 276 3324 : char* p = i; 277 : 278 : /* start with a space */ - 279 3321 : if (p != buf) { - 280 3130 : if (!isspace(*p)) - 281 2749 : continue; + 279 3324 : if (p != buf) { + 280 3133 : if (!isspace(*p)) + 281 2751 : continue; 282 382 : ++p; 283 : } 284 : @@ -368,18 +368,18 @@ 306 191 : e = i; 307 1020 : while (*e != 0 && !isspace(*e)) 308 638 : ++e; - 309 190 : *e = 0; + 309 191 : *e = 0; 310 : - 311 190 : if (!*i) { + 311 191 : if (!*i) { 312 : /* LCOV_EXCL_START */ 313 : log_fatal("Empty tag '%s' for '%s'.\n", tag, path); 314 : return -1; 315 : /* LCOV_EXCL_STOP */ 316 : } 317 : - 318 190 : pathprint(value, value_size, "%s", i); + 318 191 : pathprint(value, value_size, "%s", i); 319 : - 320 190 : return 0; + 320 191 : return 0; 321 : } 322 : #endif 323 : @@ -407,7 +407,7 @@ 345 : } 346 : 347 : /* set the real device path */ - 348 190 : pathprint(path, path_size, "/dev/%s", buf); + 348 191 : pathprint(path, path_size, "/dev/%s", buf); 349 : 350 : /* check the device */ 351 191 : if (stat(path, &st) != 0) { @@ -416,14 +416,14 @@ 354 : return -1; 355 : /* LCOV_EXCL_STOP */ 356 : } - 357 190 : if (st.st_rdev != device) { + 357 191 : if (st.st_rdev != device) { 358 : /* LCOV_EXCL_START */ 359 : log_tag("resolve:sys:%u:%u: unexpected device '%u:%u' for '%s'.\n", major(device), minor(device), major(st.st_rdev), minor(st.st_rdev), path); 360 : return -1; 361 : /* LCOV_EXCL_STOP */ 362 : } 363 : - 364 190 : log_tag("resolve:sys:%u:%u:%s: found\n", major(device), minor(device), path); + 364 191 : log_tag("resolve:sys:%u:%u:%s: found\n", major(device), minor(device), path); 365 : 366 191 : return 0; 367 : } @@ -433,9 +433,9 @@ 371 : * Get the device file from the device number. 372 : */ 373 : #if HAVE_LINUX_DEVICE - 374 191 : static int devresolve(uint64_t device, char* path, size_t path_size) + 374 172 : static int devresolve(uint64_t device, char* path, size_t path_size) 375 : { - 376 191 : if (devresolve_sys(device, path, path_size) == 0) + 376 172 : if (devresolve_sys(device, path, path_size) == 0) 377 191 : return 0; 378 : 379 0 : return -1; @@ -456,7 +456,7 @@ 394 : * in /dev/disk/by-uuid/. 395 : */ 396 : #if HAVE_LINUX_DEVICE - 397 5620 : static int devuuid_dev(uint64_t device, char* uuid, size_t uuid_size) + 397 5626 : static int devuuid_dev(uint64_t device, char* uuid, size_t uuid_size) 398 : { 399 : int ret; 400 : DIR* d; @@ -464,47 +464,47 @@ 402 : struct stat st; 403 : 404 : /* scan the UUID directory searching for the device */ - 405 5620 : d = opendir("/dev/disk/by-uuid"); - 406 5620 : if (!d) { + 405 5626 : d = opendir("/dev/disk/by-uuid"); + 406 5626 : if (!d) { 407 0 : log_tag("uuid:by-uuidd:%u:%u: opendir(/dev/disk/by-uuid) failed, %s\n", major(device), minor(device), strerror(errno)); 408 : /* directory missing?, likely we are not in Linux */ 409 0 : return -1; 410 : } 411 : - 412 95540 : while ((dd = readdir(d)) != 0) { + 412 95642 : while ((dd = readdir(d)) != 0) { 413 : /* skip "." and ".." files, UUIDs never start with '.' */ - 414 89920 : if (dd->d_name[0] == '.') - 415 11240 : continue; + 414 90016 : if (dd->d_name[0] == '.') + 415 11252 : continue; 416 : - 417 78680 : ret = fstatat(dirfd(d), dd->d_name, &st, 0); - 418 78680 : if (ret != 0) { + 417 78764 : ret = fstatat(dirfd(d), dd->d_name, &st, 0); + 418 78764 : if (ret != 0) { 419 0 : log_tag("uuid:by-uuidd:%u:%u: fstatat(%s) failed, %s\n", major(device), minor(device), dd->d_name, strerror(errno)); 420 : /* generic error, ignore and continue the search */ 421 0 : continue; 422 : } 423 : 424 : /* if it matches, we have the uuid */ - 425 78680 : if (S_ISBLK(st.st_mode) && st.st_rdev == (dev_t)device) { + 425 78764 : if (S_ISBLK(st.st_mode) && st.st_rdev == (dev_t)device) { 426 : char buf[PATH_MAX]; 427 : char path[PATH_MAX]; 428 : 429 : /* resolve the link */ - 430 5620 : pathprint(path, sizeof(path), "/dev/disk/by-uuid/%s", dd->d_name); - 431 5620 : ret = readlink(path, buf, sizeof(buf)); - 432 5620 : if (ret < 0 || ret == sizeof(buf)) { + 430 5626 : pathprint(path, sizeof(path), "/dev/disk/by-uuid/%s", dd->d_name); + 431 5626 : ret = readlink(path, buf, sizeof(buf)); + 432 5626 : if (ret < 0 || ret == sizeof(buf)) { 433 0 : log_tag("uuid:by-uuidd:%u:%u: readlink(/dev/disk/by-uuid/%s) failed, %s\n", major(device), minor(device), dd->d_name, strerror(errno)); 434 : /* generic error, ignore and continue the search */ 435 0 : continue; 436 : } - 437 5620 : buf[ret] = 0; + 437 5626 : buf[ret] = 0; 438 : 439 : /* found */ - 440 5620 : pathcpy(uuid, uuid_size, dd->d_name); + 440 5626 : pathcpy(uuid, uuid_size, dd->d_name); 441 : - 442 5620 : log_tag("uuid:by-uuid:%u:%u:%s: found %s\n", major(device), minor(device), uuid, buf); + 442 5626 : log_tag("uuid:by-uuid:%u:%u:%s: found %s\n", major(device), minor(device), uuid, buf); 443 : - 444 5620 : closedir(d); - 445 5620 : return 0; + 444 5626 : closedir(d); + 445 5626 : return 0; 446 : } 447 : } 448 : @@ -555,11 +555,11 @@ 493 : } 494 : #endif 495 : - 496 5624 : int devuuid(uint64_t device, char* uuid, size_t uuid_size) + 496 5630 : int devuuid(uint64_t device, char* uuid, size_t uuid_size) 497 : { 498 : #if HAVE_LINUX_DEVICE 499 : /* if the major is the null device */ - 500 5624 : if (major(device) == 0) { + 500 5630 : if (major(device) == 0) { 501 : /* obtain the real device */ 502 4 : if (devdereference(device, &device) != 0) { 503 : /* LCOV_EXCL_START */ @@ -571,8 +571,8 @@ 509 : 510 : /* first try with the /dev/disk/by-uuid version */ 511 : #if HAVE_LINUX_DEVICE - 512 5620 : if (devuuid_dev(device, uuid, uuid_size) == 0) - 513 5620 : return 0; + 512 5626 : if (devuuid_dev(device, uuid, uuid_size) == 0) + 513 5626 : return 0; 514 : #else 515 : log_tag("uuid:by-uuidd:%u:%u: by-uuid not supported\n", major(device), minor(device)); 516 : #endif @@ -687,7 +687,7 @@ 625 0 : return 0; 626 : } 627 : - 628 5477 : int fsinfo(const char* path, int* has_persistent_inode, uint64_t* total_space, uint64_t* free_space) + 628 5483 : int fsinfo(const char* path, int* has_persistent_inode, uint64_t* total_space, uint64_t* free_space) 629 : { 630 : char type[64]; 631 : const char* ptype; @@ -695,7 +695,7 @@ 633 : #if HAVE_STATFS 634 : struct statfs st; 635 : - 636 5477 : if (statfs(path, &st) != 0) { + 636 5483 : if (statfs(path, &st) != 0) { 637 : char dir[PATH_MAX]; 638 : char* slash; 639 : @@ -723,17 +723,17 @@ 661 : #endif 662 : 663 : /* to get the fs type check "man stat" or "stat -f -t FILE" */ - 664 5477 : if (has_persistent_inode) { + 664 5483 : if (has_persistent_inode) { 665 : #if HAVE_STATFS && HAVE_STRUCT_STATFS_F_TYPE - 666 569 : switch (st.f_type) { + 666 575 : switch (st.f_type) { 667 : case 0x65735546 : /* FUSE, "fuseblk" in the stat command */ 668 : case 0x4d44 : /* VFAT, "msdos" in the stat command */ 669 0 : *has_persistent_inode = 0; 670 0 : break; 671 : default : 672 : /* by default assume yes */ - 673 569 : *has_persistent_inode = 1; - 674 569 : break; + 673 575 : *has_persistent_inode = 1; + 674 575 : break; 675 : } 676 : #else 677 : /* by default assume yes */ @@ -741,7 +741,7 @@ 679 : #endif 680 : } 681 : - 682 5477 : if (total_space) { + 682 5483 : if (total_space) { 683 : #if HAVE_STATFS 684 4908 : *total_space = st.f_bsize * (uint64_t)st.f_blocks; 685 : #else @@ -749,7 +749,7 @@ 687 : #endif 688 : } 689 : - 690 5477 : if (free_space) { + 690 5483 : if (free_space) { 691 : #if HAVE_STATFS 692 4908 : *free_space = st.f_bsize * (uint64_t)st.f_bfree; 693 : #else @@ -764,10 +764,10 @@ 702 : #elif HAVE_STATFS && HAVE_STRUCT_STATFS_F_TYPE 703 : /* get the filesystem type from f_type (Linux) */ 704 : /* from: https://github.com/influxdata/gopsutil/blob/master/disk/disk_linux.go */ - 705 5477 : switch (st.f_type) { + 705 5483 : switch (st.f_type) { 706 0 : case 0x65735546 : ptype = "fuseblk"; break; 707 0 : case 0x4D44 : ptype = "vfat/msdos"; break; - 708 5477 : case 0xEF53 : ptype = "ext2/3/4"; break; + 708 5483 : case 0xEF53 : ptype = "ext2/3/4"; break; 709 0 : case 0x6969 : ptype = "nfs"; break; /* remote */ 710 0 : case 0x6E667364 : ptype = "nfsd"; break; /* remote */ 711 0 : case 0x517B : ptype = "smb"; break; /* remote */ @@ -786,12 +786,12 @@ 724 : ptype = "unknown"; 725 : #endif 726 : - 727 5477 : log_tag("statfs:%s: %s \n", ptype, path); + 727 5483 : log_tag("statfs:%s: %s \n", ptype, path); 728 : - 729 5477 : return 0; + 729 5483 : return 0; 730 : } 731 : - 732 3816813 : uint64_t tick(void) + 732 3819196 : uint64_t tick(void) 733 : { 734 : #if HAVE_MACH_ABSOLUTE_TIME 735 : /* for Mac OS X */ @@ -802,14 +802,14 @@ 740 : 741 : /* nanosecond precision with clock_gettime() */ 742 : #if defined(CLOCK_MONOTONIC_RAW) - 743 3816813 : if (clock_gettime(CLOCK_MONOTONIC_RAW, &tv) != 0) { + 743 3819196 : if (clock_gettime(CLOCK_MONOTONIC_RAW, &tv) != 0) { 744 : #else 745 : if (clock_gettime(CLOCK_MONOTONIC, &tv) != 0) { 746 : #endif 747 0 : return 0; 748 : } 749 : - 750 3816813 : return tv.tv_sec * 1000000000ULL + tv.tv_nsec; + 750 3819196 : return tv.tv_sec * 1000000000ULL + tv.tv_nsec; 751 : #else 752 : /* other platforms */ 753 : struct timeval tv; @@ -833,25 +833,25 @@ 771 65 : return tv.tv_sec * 1000ULL + tv.tv_usec / 1000; 772 : } 773 : - 774 280 : int randomize(void* ptr, size_t size) + 774 281 : int randomize(void* ptr, size_t size) 775 : { 776 : int f; 777 : ssize_t ret; 778 : - 779 280 : f = open("/dev/urandom", O_RDONLY); - 780 280 : if (f == -1) + 779 281 : f = open("/dev/urandom", O_RDONLY); + 780 281 : if (f == -1) 781 0 : return -1; 782 : - 783 280 : ret = read(f, ptr, size); - 784 280 : if (ret < 0 || (size_t)ret != size) { + 783 281 : ret = read(f, ptr, size); + 784 281 : if (ret < 0 || (size_t)ret != size) { 785 0 : close(f); 786 0 : return -1; 787 : } 788 : - 789 280 : if (close(f) != 0) + 789 281 : if (close(f) != 0) 790 0 : return -1; 791 : - 792 280 : return 0; + 792 281 : return 0; 793 : } 794 : 795 : /** @@ -1477,12 +1477,12 @@ 1415 3 : return device_thread(low, func); 1416 : } 1417 : - 1418 269 : void os_init(int opt) + 1418 270 : void os_init(int opt) 1419 : { 1420 : #if HAVE_BLKID 1421 : int ret; - 1422 269 : ret = blkid_get_cache(&cache, NULL); - 1423 269 : if (ret != 0) { + 1422 270 : ret = blkid_get_cache(&cache, NULL); + 1423 270 : if (ret != 0) { 1424 : /* LCOV_EXCL_START */ 1425 : log_fatal("WARNING Failed to get blkid cache\n"); 1426 : /* LCOV_EXCL_STOP */ @@ -1490,7 +1490,7 @@ 1428 : #endif 1429 : 1430 : (void)opt; - 1431 269 : } + 1431 270 : } 1432 : 1433 247 : void os_done(void) 1434 : { diff --git a/cov/cmdline/util.c.func-sort-c.html b/cov/cmdline/util.c.func-sort-c.html index 54bd9b21..9b60f2aa 100644 --- a/cov/cmdline/util.c.func-sort-c.html +++ b/cov/cmdline/util.c.func-sort-c.html @@ -61,23 +61,23 @@ util_rotl32 - 854114224 + 854131328 util_rotl64 - 512217108 + 512341560 memhash - 5937808 + 5938723 crc32c_x86 - 646614 + 646609 memdiff - 93184 + 93321 malloc_nofail_vector_align @@ -85,27 +85,27 @@ mtest_vector - 1951 + 1953 malloc_nofail_test - 1951 + 1953 fast_mtest_vector - 1951 + 1953 crc32c_gen - 361 + 345 crc32c_init - 285 + 286 lock_lock - 260 + 261 lock_unlock diff --git a/cov/cmdline/util.c.func.html b/cov/cmdline/util.c.func.html index d471f99a..f2fb5161 100644 --- a/cov/cmdline/util.c.func.html +++ b/cov/cmdline/util.c.func.html @@ -61,19 +61,19 @@ crc32c_gen - 361 + 345 crc32c_init - 285 + 286 crc32c_x86 - 646614 + 646609 fast_mtest_vector - 1951 + 1953 hash_config_name @@ -81,7 +81,7 @@ lock_lock - 260 + 261 lock_unlock @@ -97,7 +97,7 @@ malloc_nofail_test - 1951 + 1953 malloc_nofail_vector_align @@ -109,23 +109,23 @@ memdiff - 93184 + 93321 memhash - 5937808 + 5938723 mtest_vector - 1951 + 1953 util_rotl32 - 854114224 + 854131328 util_rotl64 - 512217108 + 512341560
diff --git a/cov/cmdline/util.c.gcov.html b/cov/cmdline/util.c.gcov.html index 050d6610..467c0b8d 100644 --- a/cov/cmdline/util.c.gcov.html +++ b/cov/cmdline/util.c.gcov.html @@ -151,15 +151,15 @@ 89 0 : return ptr; 90 : } 91 : - 92 1951 : void* malloc_nofail_test(size_t size) + 92 1953 : void* malloc_nofail_test(size_t size) 93 : { 94 : void* ptr; 95 : - 96 1951 : ptr = malloc_nofail(size); + 96 1953 : ptr = malloc_nofail(size); 97 : - 98 1951 : mtest_vector(1, size, &ptr); + 98 1953 : mtest_vector(1, size, &ptr); 99 : - 100 1951 : return ptr; + 100 1953 : return ptr; 101 : } 102 : 103 : /** @@ -168,40 +168,40 @@ 106 : * It's similar at raid_mtest_vector() but faster because 107 : * we have a lot of buffers to verify. 108 : */ - 109 1951 : static int fast_mtest_vector(int n, size_t size, void** vv) + 109 1953 : static int fast_mtest_vector(int n, size_t size, void** vv) 110 : { 111 : int i, j; 112 : 113 : /* test with all the bits */ - 114 17559 : for (i = 0; i < 8; ++i) { - 115 15608 : unsigned char value = 1 << i; + 114 17577 : for (i = 0; i < 8; ++i) { + 115 15624 : unsigned char value = 1 << i; 116 : 117 : /* fill first */ - 118 15608 : memset(vv[0], value, size); + 118 15624 : memset(vv[0], value, size); 119 : 120 : /* copy to the next */ - 121 15608 : for (j = 1; j < n; ++j) + 121 15624 : for (j = 1; j < n; ++j) 122 0 : memcpy(vv[j], vv[j - 1], size); 123 : 124 : /* compare with the previous */ - 125 31216 : for (j = 1; j <= n; ++j) - 126 15608 : if (memcmp(vv[j % n], vv[j - 1], size) != 0) + 125 31248 : for (j = 1; j <= n; ++j) + 126 15624 : if (memcmp(vv[j % n], vv[j - 1], size) != 0) 127 0 : return -1; 128 : } 129 : - 130 1951 : return 0; + 130 1953 : return 0; 131 : } 132 : - 133 1951 : void mtest_vector(int n, size_t size, void** vv) + 133 1953 : void mtest_vector(int n, size_t size, void** vv) 134 : { - 135 1951 : if (fast_mtest_vector(n, size, vv) != 0) { + 135 1953 : if (fast_mtest_vector(n, size, vv) != 0) { 136 : /* LCOV_EXCL_START */ 137 : log_fatal("DANGER! Your RAM memory is broken! DO NOT PROCEED UNTIL FIXED!\n"); 138 : log_fatal("Try running a memory test like http://www.memtest86.com/\n"); 139 : exit(EXIT_FAILURE); 140 : /* LCOV_EXCL_STOP */ 141 : } - 142 1951 : } + 142 1953 : } 143 : 144 : /****************************************************************************/ 145 : /* crc */ @@ -478,42 +478,42 @@ 416 : int crc_x86; 417 : #endif 418 : - 419 361 : uint32_t crc32c_gen(uint32_t crc, const unsigned char* ptr, unsigned size) + 419 345 : uint32_t crc32c_gen(uint32_t crc, const unsigned char* ptr, unsigned size) 420 : { - 421 361 : crc ^= CRC_IV; + 421 345 : crc ^= CRC_IV; 422 : - 423 361 : crc = crc32c_gen_plain(crc, ptr, size); + 423 345 : crc = crc32c_gen_plain(crc, ptr, size); 424 : - 425 361 : crc ^= CRC_IV; + 425 345 : crc ^= CRC_IV; 426 : - 427 361 : return crc; + 427 345 : return crc; 428 : } 429 : 430 : #if HAVE_SSE42 - 431 646614 : uint32_t crc32c_x86(uint32_t crc, const unsigned char* ptr, unsigned size) + 431 646609 : uint32_t crc32c_x86(uint32_t crc, const unsigned char* ptr, unsigned size) 432 : { - 433 646614 : crc ^= CRC_IV; + 433 646609 : crc ^= CRC_IV; 434 : - 435 646614 : crc = crc32c_x86_plain(crc, ptr, size); + 435 646609 : crc = crc32c_x86_plain(crc, ptr, size); 436 : - 437 646610 : crc ^= CRC_IV; + 437 646607 : crc ^= CRC_IV; 438 : - 439 646610 : return crc; + 439 646607 : return crc; 440 : } 441 : #endif 442 : 443 : uint32_t (*crc32c)(uint32_t crc, const unsigned char* ptr, unsigned size); 444 : - 445 285 : void crc32c_init(void) + 445 286 : void crc32c_init(void) 446 : { - 447 285 : crc32c = crc32c_gen; + 447 286 : crc32c = crc32c_gen; 448 : #if HAVE_SSE42 - 449 285 : if (raid_cpu_has_crc32()) { - 450 283 : crc_x86 = 1; - 451 283 : crc32c = crc32c_x86; + 449 286 : if (raid_cpu_has_crc32()) { + 450 284 : crc_x86 = 1; + 451 284 : crc32c = crc32c_x86; 452 : } 453 : #endif - 454 285 : } + 454 286 : } 455 : 456 : /****************************************************************************/ 457 : /* byte operations */ @@ -522,14 +522,14 @@ 460 : * Rotate left. 461 : * In x86/x64 they are optimized with a single assembler instruction. 462 : */ - 463 854114224 : static inline uint32_t util_rotl32(uint32_t x, int8_t r) + 463 854131328 : static inline uint32_t util_rotl32(uint32_t x, int8_t r) 464 : { - 465 854114224 : return (x << r) | (x >> (32 - r)); + 465 854131328 : return (x << r) | (x >> (32 - r)); 466 : } 467 : - 468 512217108 : static inline uint64_t util_rotl64(uint64_t x, int8_t r) + 468 512341560 : static inline uint64_t util_rotl64(uint64_t x, int8_t r) 469 : { - 470 512217108 : return (x << r) | (x >> (64 - r)); + 470 512341560 : return (x << r) | (x >> (64 - r)); 471 : } 472 : 473 : /** @@ -570,15 +570,15 @@ 508 : #include "murmur3.c" 509 : #include "spooky2.c" 510 : - 511 5937808 : void memhash(unsigned kind, const unsigned char* seed, void* digest, const void* src, size_t size) + 511 5938723 : void memhash(unsigned kind, const unsigned char* seed, void* digest, const void* src, size_t size) 512 : { - 513 5937808 : switch (kind) { + 513 5938723 : switch (kind) { 514 : case HASH_MURMUR3 : - 515 2076827 : MurmurHash3_x86_128(src, size, seed, digest); - 516 2076827 : break; + 515 2076854 : MurmurHash3_x86_128(src, size, seed, digest); + 516 2076854 : break; 517 : case HASH_SPOOKY2 : - 518 3860981 : SpookyHash128(src, size, seed, digest); - 519 3860981 : break; + 518 3861869 : SpookyHash128(src, size, seed, digest); + 519 3861869 : break; 520 : default : 521 : /* LCOV_EXCL_START */ 522 : log_fatal("Internal inconsistency in hash function %u\n", kind); @@ -586,7 +586,7 @@ 524 : break; 525 : /* LCOV_EXCL_STOP */ 526 : } - 527 5937808 : } + 527 5938723 : } 528 : 529 42 : const char* hash_config_name(unsigned kind) 530 : { @@ -601,49 +601,49 @@ 539 : } 540 : } 541 : - 542 93184 : unsigned memdiff(const unsigned char* data1, const unsigned char* data2, size_t size) + 542 93321 : unsigned memdiff(const unsigned char* data1, const unsigned char* data2, size_t size) 543 : { 544 : size_t i; 545 : unsigned count; 546 : - 547 93184 : count = 0; - 548 80903648 : for (i = 0; i < size; ++i) { + 547 93321 : count = 0; + 548 80898921 : for (i = 0; i < size; ++i) { 549 : unsigned j; - 550 80810464 : unsigned char diff = data1[i] ^ data2[i]; - 551 727294176 : for (j = 0; j < 8; ++j) { - 552 646483712 : if ((diff & 1) != 0) - 553 311410983 : ++count; - 554 646483712 : diff >>= 1; + 550 80805600 : unsigned char diff = data1[i] ^ data2[i]; + 551 727250400 : for (j = 0; j < 8; ++j) { + 552 646444800 : if ((diff & 1) != 0) + 553 311410136 : ++count; + 554 646444800 : diff >>= 1; 555 : } 556 : } 557 : - 558 93184 : return count; + 558 93321 : return count; 559 : } 560 : 561 : /****************************************************************************/ 562 : /* lock */ 563 : 564 : #if HAVE_LOCKFILE - 565 260 : int lock_lock(const char* file) + 565 261 : int lock_lock(const char* file) 566 : { 567 : int f; 568 : - 569 260 : f = open(file, O_CREAT | O_TRUNC | O_WRONLY, 0600); - 570 260 : if (f == -1) { + 569 261 : f = open(file, O_CREAT | O_TRUNC | O_WRONLY, 0600); + 570 261 : if (f == -1) { 571 : /* LCOV_EXCL_START */ 572 : return -1; 573 : /* LCOV_EXCL_STOP */ 574 : } 575 : 576 : /* exclusive lock, not blocking */ - 577 260 : if (flock(f, LOCK_EX | LOCK_NB) == -1) { + 577 261 : if (flock(f, LOCK_EX | LOCK_NB) == -1) { 578 : /* LCOV_EXCL_START */ 579 : close(f); 580 : return -1; 581 : /* LCOV_EXCL_STOP */ 582 : } 583 : - 584 260 : return f; + 584 261 : return f; 585 : } 586 : #endif 587 : diff --git a/cov/cmdline/util.h.func-sort-c.html b/cov/cmdline/util.h.func-sort-c.html index 5f32bb8e..0fdb5fd3 100644 --- a/cov/cmdline/util.h.func-sort-c.html +++ b/cov/cmdline/util.h.func-sort-c.html @@ -61,19 +61,19 @@ crc32c_x86_plain - 21365714 + 21365408 crc32c_plain - 20719102 + 20718802 crc32c_plain_char - 3808841 + 3808025 crc32c_gen_plain - 361 + 345
diff --git a/cov/cmdline/util.h.func.html b/cov/cmdline/util.h.func.html index bbede01b..2da812ac 100644 --- a/cov/cmdline/util.h.func.html +++ b/cov/cmdline/util.h.func.html @@ -61,19 +61,19 @@ crc32c_gen_plain - 361 + 345 crc32c_plain - 20719102 + 20718802 crc32c_plain_char - 3808841 + 3808025 crc32c_x86_plain - 21365714 + 21365408
diff --git a/cov/cmdline/util.h.gcov.html b/cov/cmdline/util.h.gcov.html index 89321798..ec697472 100644 --- a/cov/cmdline/util.h.gcov.html +++ b/cov/cmdline/util.h.gcov.html @@ -144,12 +144,12 @@ 82 : /** 83 : * Compute CRC-32 (Castagnoli) for a single byte without the IV. 84 : */ - 85 3808841 : static inline uint32_t crc32c_plain_char(uint32_t crc, unsigned char c) + 85 3808025 : static inline uint32_t crc32c_plain_char(uint32_t crc, unsigned char c) 86 : { 87 : #if HAVE_SSE42 - 88 3808841 : if (tommy_likely(crc_x86)) { - 89 3808841 : asm("crc32b %1, %0\n" : "+r" (crc) : "m" (c)); - 90 3808841 : return crc; + 88 3808025 : if (tommy_likely(crc_x86)) { + 89 3808025 : asm("crc32b %1, %0\n" : "+r" (crc) : "m" (c)); + 90 3808025 : return crc; 91 : } 92 : #endif 93 0 : return CRC32C_0[(crc ^ c) & 0xff] ^ (crc >> 8); @@ -158,29 +158,29 @@ 96 : /** 97 : * Compute the CRC-32 (Castagnoli) without the IV. 98 : */ - 99 361 : static inline uint32_t crc32c_gen_plain(uint32_t crc, const unsigned char* ptr, unsigned size) + 99 345 : static inline uint32_t crc32c_gen_plain(uint32_t crc, const unsigned char* ptr, unsigned size) 100 : { - 101 22545273 : while (size >= 4) { - 102 22544551 : crc ^= ptr[0] | (uint32_t)ptr[1] << 8 | (uint32_t)ptr[2] << 16 | (uint32_t)ptr[3] << 24; - 103 22544551 : crc = CRC32C_3[crc & 0xff] ^ CRC32C_2[(crc >> 8) & 0xff] ^ CRC32C_1[(crc >> 16) & 0xff] ^ CRC32C_0[crc >> 24]; - 104 22544551 : ptr += 4; - 105 22544551 : size -= 4; + 101 21496665 : while (size >= 4) { + 102 21495975 : crc ^= ptr[0] | (uint32_t)ptr[1] << 8 | (uint32_t)ptr[2] << 16 | (uint32_t)ptr[3] << 24; + 103 21495975 : crc = CRC32C_3[crc & 0xff] ^ CRC32C_2[(crc >> 8) & 0xff] ^ CRC32C_1[(crc >> 16) & 0xff] ^ CRC32C_0[crc >> 24]; + 104 21495975 : ptr += 4; + 105 21495975 : size -= 4; 106 : } 107 : - 108 731 : while (size) { + 108 699 : while (size) { 109 9 : crc = CRC32C_0[(crc ^ *ptr) & 0xff] ^ (crc >> 8); 110 9 : ++ptr; 111 9 : --size; 112 : } 113 : - 114 361 : return crc; + 114 345 : return crc; 115 : } 116 : 117 : /** 118 : * Compute the CRC-32 (Castagnoli) without the IV. 119 : */ 120 : #if HAVE_SSE42 - 121 21365714 : static inline uint32_t crc32c_x86_plain(uint32_t crc, const unsigned char* ptr, unsigned size) + 121 21365408 : static inline uint32_t crc32c_x86_plain(uint32_t crc, const unsigned char* ptr, unsigned size) 122 : { 123 : #ifdef CONFIG_X86_64 124 : uint64_t crc64 = crc; @@ -191,30 +191,30 @@ 129 : } 130 : crc = crc64; 131 : #else - 132 387175791 : while (size >= 4) { - 133 344444363 : asm("crc32l %1, %0\n" : "+r" (crc) : "m" (*(const uint32_t*)ptr)); - 134 344444363 : ptr += 4; - 135 344444363 : size -= 4; + 132 381730335 : while (size >= 4) { + 133 338999519 : asm("crc32l %1, %0\n" : "+r" (crc) : "m" (*(const uint32_t*)ptr)); + 134 338999519 : ptr += 4; + 135 338999519 : size -= 4; 136 : } 137 : #endif - 138 62479703 : while (size) { - 139 19748275 : asm("crc32b %1, %0\n" : "+r" (crc) : "m" (*ptr)); - 140 19748275 : ++ptr; - 141 19748275 : --size; + 138 62071545 : while (size) { + 139 19340729 : asm("crc32b %1, %0\n" : "+r" (crc) : "m" (*ptr)); + 140 19340729 : ++ptr; + 141 19340729 : --size; 142 : } 143 : - 144 21365714 : return crc; + 144 21365408 : return crc; 145 : } 146 : #endif 147 : 148 : /** 149 : * Compute CRC-32 (Castagnoli) without the IV. 150 : */ - 151 20719102 : static inline uint32_t crc32c_plain(uint32_t crc, const unsigned char* ptr, unsigned size) + 151 20718802 : static inline uint32_t crc32c_plain(uint32_t crc, const unsigned char* ptr, unsigned size) 152 : { 153 : #if HAVE_SSE42 - 154 20719102 : if (tommy_likely(crc_x86)) { - 155 20719102 : return crc32c_x86_plain(crc, ptr, size); + 154 20718802 : if (tommy_likely(crc_x86)) { + 155 20718802 : return crc32c_x86_plain(crc, ptr, size); 156 : } 157 : #endif 158 0 : return crc32c_gen_plain(crc, ptr, size); diff --git a/cov/index-sort-f.html b/cov/index-sort-f.html index 369519f1..dc826957 100644 --- a/cov/index-sort-f.html +++ b/cov/index-sort-f.html @@ -31,9 +31,9 @@ lcov.info Lines: - 10929 - 11932 - 91.6 % + 10944 + 11891 + 92.0 % Date: @@ -72,10 +72,10 @@ cmdline -
89.7%89.7%
+
90.2%90.2%
- 89.7 % - 8598 / 9589 + 90.2 % + 8613 / 9548 96.6 % 482 / 499 diff --git a/cov/index-sort-l.html b/cov/index-sort-l.html index 8df6ac86..593255cc 100644 --- a/cov/index-sort-l.html +++ b/cov/index-sort-l.html @@ -31,9 +31,9 @@ lcov.info Lines: - 10929 - 11932 - 91.6 % + 10944 + 11891 + 92.0 % Date: @@ -72,10 +72,10 @@ cmdline -
89.7%89.7%
+
90.2%90.2%
- 89.7 % - 8598 / 9589 + 90.2 % + 8613 / 9548 96.6 % 482 / 499 diff --git a/cov/index.html b/cov/index.html index aa99f509..e06fe00f 100644 --- a/cov/index.html +++ b/cov/index.html @@ -31,9 +31,9 @@ lcov.info Lines: - 10929 - 11932 - 91.6 % + 10944 + 11891 + 92.0 % Date: @@ -72,10 +72,10 @@ cmdline -
89.7%89.7%
+
90.2%90.2%
- 89.7 % - 8598 / 9589 + 90.2 % + 8613 / 9548 96.6 % 482 / 499 diff --git a/cov/raid/combo.h.gcov.html b/cov/raid/combo.h.gcov.html index 8e4fbb08..d55520f8 100644 --- a/cov/raid/combo.h.gcov.html +++ b/cov/raid/combo.h.gcov.html @@ -170,10 +170,10 @@ 108 : int i; 109 : 110 : (void)n; /* unused, but kept for clarity */ - 111 207805 : assert(0 < r && r <= n); + 111 207990 : assert(0 < r && r <= n); 112 : - 113 689192 : for (i = 0; i < r; ++i) - 114 481387 : c[i] = i; + 113 689341 : for (i = 0; i < r; ++i) + 114 481351 : c[i] = i; 115 : } 116 : 117 : /** @@ -182,19 +182,19 @@ 120 : */ 121 : static __always_inline int combination_next(int r, int n, int *c) 122 : { - 123 52183 : int i = r - 1; /* present position */ - 124 52183 : int h = n; /* high limit for this position */ + 123 52204 : int i = r - 1; /* present position */ + 124 52204 : int h = n; /* high limit for this position */ 125 : 126 : recurse: 127 : /* next element at position i */ - 128 85056 : ++c[i]; + 128 85077 : ++c[i]; 129 : 130 : /* if the position has reached the max */ - 131 85056 : if (c[i] >= h) { + 131 85077 : if (c[i] >= h) { 132 : 133 : /* if we are at the first level, we have finished */ - 134 45028 : if (i == 0) - 135 12155 : return 0; + 134 45035 : if (i == 0) + 135 12162 : return 0; 136 : 137 : /* increase the previous position */ 138 32873 : --i; @@ -202,16 +202,16 @@ 140 : goto recurse; 141 : } 142 : - 143 40028 : ++i; + 143 40042 : ++i; 144 : 145 : /* initialize all the next positions, if any */ - 146 62573 : while (i < r) { + 146 62587 : while (i < r) { 147 : /* each position start at the next value of the previous one */ 148 22545 : c[i] = c[i - 1] + 1; 149 22545 : ++i; 150 : } 151 : - 152 40028 : return 1; + 152 40042 : return 1; 153 : } 154 : #endif 155 : diff --git a/cov/raid/cpu.h.func-sort-c.html b/cov/raid/cpu.h.func-sort-c.html index de749704..a6582f10 100644 --- a/cov/raid/cpu.h.func-sort-c.html +++ b/cov/raid/cpu.h.func-sort-c.html @@ -61,43 +61,43 @@ raid_cpuid - 2079 + 2086 raid_cpu_match_sse - 1185 + 1189 raid_cpu_has_ssse3 - 587 + 589 raid_cpu_match_avx - 317 + 318 raid_cpu_has_avx2 - 317 + 318 raid_cpu_has_sse2 - 305 + 306 raid_cpu_has_crc32 - 293 + 294 raid_cpu_info - 277 + 278 raid_cpu_is_atom - 273 + 274 raid_cpu_has_slowmult - 269 + 270 raid_xgetbv diff --git a/cov/raid/cpu.h.func.html b/cov/raid/cpu.h.func.html index f6f349fc..70b343e1 100644 --- a/cov/raid/cpu.h.func.html +++ b/cov/raid/cpu.h.func.html @@ -61,11 +61,11 @@ raid_cpu_has_avx2 - 317 + 318 raid_cpu_has_crc32 - 293 + 294 raid_cpu_has_slowextendedreg @@ -73,35 +73,35 @@ raid_cpu_has_slowmult - 269 + 270 raid_cpu_has_sse2 - 305 + 306 raid_cpu_has_ssse3 - 587 + 589 raid_cpu_info - 277 + 278 raid_cpu_is_atom - 273 + 274 raid_cpu_match_avx - 317 + 318 raid_cpu_match_sse - 1185 + 1189 raid_cpuid - 2079 + 2086 raid_xgetbv diff --git a/cov/raid/cpu.h.gcov.html b/cov/raid/cpu.h.gcov.html index b0e1b857..27729847 100644 --- a/cov/raid/cpu.h.gcov.html +++ b/cov/raid/cpu.h.gcov.html @@ -79,9 +79,9 @@ 17 : 18 : #ifdef CONFIG_X86 19 : - 20 2079 : static inline void raid_cpuid(uint32_t func_eax, uint32_t sub_ecx, uint32_t *reg) + 20 2086 : static inline void raid_cpuid(uint32_t func_eax, uint32_t sub_ecx, uint32_t *reg) 21 : { - 22 2079 : asm volatile ( + 22 2086 : asm volatile ( 23 : #if defined(__i386__) && defined(__PIC__) 24 : /* allow compilation in PIC mode saving ebx */ 25 : "xchgl %%ebx, %1\n" @@ -91,11 +91,11 @@ 29 : : "0" (func_eax), "2" (sub_ecx) 30 : #else 31 : "cpuid\n" - 32 2079 : : "=a" (reg[0]), "=b" (reg[1]), "=c" (reg[2]), "=d" (reg[3]) + 32 2086 : : "=a" (reg[0]), "=b" (reg[1]), "=c" (reg[2]), "=d" (reg[3]) 33 : : "0" (func_eax), "2" (sub_ecx) 34 : #endif 35 : ); - 36 2079 : } + 36 2086 : } 37 : 38 23 : static inline void raid_xgetbv(uint32_t* reg) 39 : { @@ -112,26 +112,26 @@ 50 : 51 : #define CPU_VENDOR_MAX 13 52 : - 53 277 : static inline void raid_cpu_info(char *vendor, unsigned *family, unsigned *model) + 53 278 : static inline void raid_cpu_info(char *vendor, unsigned *family, unsigned *model) 54 : { 55 : uint32_t reg[4]; 56 : unsigned f, ef, m, em; 57 : - 58 277 : raid_cpuid(0, 0, reg); + 58 278 : raid_cpuid(0, 0, reg); 59 : - 60 277 : ((uint32_t*)vendor)[0] = reg[1]; - 61 277 : ((uint32_t*)vendor)[1] = reg[3]; - 62 277 : ((uint32_t*)vendor)[2] = reg[2]; - 63 277 : vendor[12] = 0; + 60 278 : ((uint32_t*)vendor)[0] = reg[1]; + 61 278 : ((uint32_t*)vendor)[1] = reg[3]; + 62 278 : ((uint32_t*)vendor)[2] = reg[2]; + 63 278 : vendor[12] = 0; 64 : - 65 277 : raid_cpuid(1, 0, reg); + 65 278 : raid_cpuid(1, 0, reg); 66 : - 67 277 : f = (reg[0] >> 8) & 0xF; - 68 277 : ef = (reg[0] >> 20) & 0xFF; - 69 277 : m = (reg[0] >> 4) & 0xF; - 70 277 : em = (reg[0] >> 16) & 0xF; + 67 278 : f = (reg[0] >> 8) & 0xF; + 68 278 : ef = (reg[0] >> 20) & 0xFF; + 69 278 : m = (reg[0] >> 4) & 0xF; + 70 278 : em = (reg[0] >> 16) & 0xF; 71 : - 72 277 : if (strcmp(vendor, "AuthenticAMD") == 0) { + 72 278 : if (strcmp(vendor, "AuthenticAMD") == 0) { 73 0 : if (f < 15) { 74 0 : *family = f; 75 0 : *model = m; @@ -140,31 +140,31 @@ 78 0 : *model = m + (em << 4); 79 : } 80 : } else { - 81 277 : *family = f + ef; - 82 277 : *model = m + (em << 4); + 81 278 : *family = f + ef; + 82 278 : *model = m + (em << 4); 83 : } - 84 277 : } + 84 278 : } 85 : - 86 1185 : static inline int raid_cpu_match_sse(uint32_t cpuid_1_ecx, uint32_t cpuid_1_edx) + 86 1189 : static inline int raid_cpu_match_sse(uint32_t cpuid_1_ecx, uint32_t cpuid_1_edx) 87 : { 88 : uint32_t reg[4]; 89 : - 90 1185 : raid_cpuid(1, 0, reg); - 91 1185 : if ((reg[2] & cpuid_1_ecx) != cpuid_1_ecx) + 90 1189 : raid_cpuid(1, 0, reg); + 91 1189 : if ((reg[2] & cpuid_1_ecx) != cpuid_1_ecx) 92 18 : return 0; - 93 1167 : if ((reg[3] & cpuid_1_edx) != cpuid_1_edx) + 93 1171 : if ((reg[3] & cpuid_1_edx) != cpuid_1_edx) 94 0 : return 0; 95 : - 96 1167 : return 1; + 96 1171 : return 1; 97 : } 98 : - 99 317 : static inline int raid_cpu_match_avx(uint32_t cpuid_1_ecx, uint32_t cpuid_7_ebx, uint32_t xcr0) + 99 318 : static inline int raid_cpu_match_avx(uint32_t cpuid_1_ecx, uint32_t cpuid_7_ebx, uint32_t xcr0) 100 : { 101 : uint32_t reg[4]; 102 : - 103 317 : raid_cpuid(1, 0, reg); - 104 317 : if ((reg[2] & cpuid_1_ecx) != cpuid_1_ecx) - 105 294 : return 0; + 103 318 : raid_cpuid(1, 0, reg); + 104 318 : if ((reg[2] & cpuid_1_ecx) != cpuid_1_ecx) + 105 295 : return 0; 106 : 107 23 : raid_xgetbv(reg); 108 23 : if ((reg[0] & xcr0) != xcr0) @@ -177,7 +177,7 @@ 115 23 : return 1; 116 : } 117 : - 118 305 : static inline int raid_cpu_has_sse2(void) + 118 306 : static inline int raid_cpu_has_sse2(void) 119 : { 120 : /* 121 : * Intel® 64 and IA-32 Architectures Software Developer's Manual @@ -191,12 +191,12 @@ 129 : * 2. Check that the processor supports the SSE and/or SSE2 extensions (true if 130 : * CPUID.01H:EDX.SSE[bit 25] = 1 and/or CPUID.01H:EDX.SSE2[bit 26] = 1). 131 : */ - 132 305 : return raid_cpu_match_sse( + 132 306 : return raid_cpu_match_sse( 133 : 0, 134 : 1 << 26); /* SSE2 */ 135 : } 136 : - 137 587 : static inline int raid_cpu_has_ssse3(void) + 137 589 : static inline int raid_cpu_has_ssse3(void) 138 : { 139 : /* 140 : * Intel® 64 and IA-32 Architectures Software Developer's Manual @@ -208,12 +208,12 @@ 146 : * Next, use the additional step provided below: 147 : * Check that the processor supports SSSE3 (if CPUID.01H:ECX.SSSE3[bit 9] = 1). 148 : */ - 149 587 : return raid_cpu_match_sse( + 149 589 : return raid_cpu_match_sse( 150 : 1 << 9, /* SSSE3 */ 151 : 1 << 26); /* SSE2 */ 152 : } 153 : - 154 293 : static inline int raid_cpu_has_crc32(void) + 154 294 : static inline int raid_cpu_has_crc32(void) 155 : { 156 : /* 157 : * Intel® 64 and IA-32 Architectures Software Developer's Manual @@ -224,12 +224,12 @@ 162 : * Before an application attempts to use the CRC32 instruction, it must check 163 : * that the processor supports SSE4.2 (if CPUID.01H:ECX.SSE4_2[bit 20] = 1). 164 : */ - 165 293 : return raid_cpu_match_sse( + 165 294 : return raid_cpu_match_sse( 166 : 1 << 20, /* CRC32 */ 167 : 0); 168 : } 169 : - 170 317 : static inline int raid_cpu_has_avx2(void) + 170 318 : static inline int raid_cpu_has_avx2(void) 171 : { 172 : /* 173 : * Intel Architecture Instruction Set Extensions Programming Reference @@ -246,7 +246,7 @@ 184 : * Application Software must identify that hardware supports AVX, after that it must 185 : * also detect support for AVX2 by checking CPUID.(EAX=07H, ECX=0H):EBX.AVX2[bit 5]. 186 : */ - 187 317 : return raid_cpu_match_avx( + 187 318 : return raid_cpu_match_avx( 188 : (1 << 27) | (1 << 28), /* OSXSAVE and AVX */ 189 : 1 << 5, /* AVX2 */ 190 : 3 << 1); /* OS saves XMM and YMM registers */ @@ -277,9 +277,9 @@ 215 : /** 216 : * Check if it's an Intel Atom CPU. 217 : */ - 218 273 : static inline int raid_cpu_is_atom(unsigned family, unsigned model) + 218 274 : static inline int raid_cpu_is_atom(unsigned family, unsigned model) 219 : { - 220 273 : if (family != 6) + 220 274 : if (family != 6) 221 3 : return 0; 222 : 223 : /* @@ -300,17 +300,17 @@ 238 : * 4D (77) Atom 8C (22 nm) 4 MB L2 (AVN) 239 : * ?? Atom ?C (14 nm) ? MB L2 (DVN) 240 : */ - 241 540 : return model == 28 || model == 38 || model == 54 - 242 270 : || model == 39 || model == 53 || model == 74 - 243 270 : || model == 90 || model == 55 || model == 76 - 244 540 : || model == 93 || model == 77; + 241 542 : return model == 28 || model == 38 || model == 54 + 242 271 : || model == 39 || model == 53 || model == 74 + 243 271 : || model == 90 || model == 55 || model == 76 + 244 542 : || model == 93 || model == 77; 245 : } 246 : 247 : /** 248 : * Check if the processor has a slow MULT implementation. 249 : * If yes, it's better to use a hash not based on multiplication. 250 : */ - 251 269 : static inline int raid_cpu_has_slowmult(void) + 251 270 : static inline int raid_cpu_has_slowmult(void) 252 : { 253 : char vendor[CPU_VENDOR_MAX]; 254 : unsigned family; @@ -320,9 +320,9 @@ 258 : * In some cases Murmur3 based on MUL instruction, 259 : * is a LOT slower than Spooky2 based on SHIFTs. 260 : */ - 261 269 : raid_cpu_info(vendor, &family, &model); + 261 270 : raid_cpu_info(vendor, &family, &model); 262 : - 263 269 : if (strcmp(vendor, "GenuineIntel") == 0) { + 263 270 : if (strcmp(vendor, "GenuineIntel") == 0) { 264 : /* 265 : * Intel Atom (Model 28) 266 : * murmur3:378 MB/s, spooky2:3413 MB/s (x86) @@ -330,11 +330,11 @@ 268 : * Intel Atom (Model 77) 269 : * murmur3:1311 MB/s, spooky2:4056 MB/s (x64) 270 : */ - 271 269 : if (raid_cpu_is_atom(family, model)) + 271 270 : if (raid_cpu_is_atom(family, model)) 272 0 : return 1; 273 : } 274 : - 275 269 : return 0; + 275 270 : return 0; 276 : } 277 : 278 : /** diff --git a/cov/raid/gf.h.gcov.html b/cov/raid/gf.h.gcov.html index 7e9160c7..4eb56dc0 100644 --- a/cov/raid/gf.h.gcov.html +++ b/cov/raid/gf.h.gcov.html @@ -88,7 +88,7 @@ 26 : */ 27 : static __always_inline uint8_t mul(uint8_t a, uint8_t b) 28 : { - 29 23795594 : return gfmul[a][b]; + 29 23792058 : return gfmul[a][b]; 30 : } 31 : 32 : /* @@ -97,9 +97,9 @@ 35 : */ 36 : static __always_inline uint8_t inv(uint8_t v) 37 : { - 38 635882 : BUG_ON(v == 0); /* division by zero */ + 38 635454 : BUG_ON(v == 0); /* division by zero */ 39 : - 40 635882 : return gfinv[v]; + 40 635454 : return gfinv[v]; 41 : } 42 : 43 : /* @@ -125,7 +125,7 @@ 63 : */ 64 : static __always_inline uint8_t A(int p, int d) 65 : { - 66 2605358 : return gfgen[p][d]; + 66 2604488 : return gfgen[p][d]; 67 : } 68 : 69 : /* @@ -148,12 +148,12 @@ 86 : */ 87 : static __always_inline uint32_t x2_32(uint32_t v) 88 : { - 89 33036096 : uint32_t mask = v & 0x80808080U; + 89 32577344 : uint32_t mask = v & 0x80808080U; 90 : - 91 33036096 : mask = (mask << 1) - (mask >> 7); - 92 33036096 : v = (v << 1) & 0xfefefefeU; - 93 33036096 : v ^= mask & 0x1d1d1d1dU; - 94 33036096 : return v; + 91 32577344 : mask = (mask << 1) - (mask >> 7); + 92 32577344 : v = (v << 1) & 0xfefefefeU; + 93 32577344 : v ^= mask & 0x1d1d1d1dU; + 94 32577344 : return v; 95 : } 96 : 97 : /* @@ -161,12 +161,12 @@ 99 : */ 100 : static __always_inline uint64_t x2_64(uint64_t v) 101 : { - 102 16518048 : uint64_t mask = v & 0x8080808080808080ULL; + 102 16059296 : uint64_t mask = v & 0x8080808080808080ULL; 103 : - 104 16518048 : mask = (mask << 1) - (mask >> 7); - 105 16518048 : v = (v << 1) & 0xfefefefefefefefeULL; - 106 16518048 : v ^= mask & 0x1d1d1d1d1d1d1d1dULL; - 107 16518048 : return v; + 104 16059296 : mask = (mask << 1) - (mask >> 7); + 105 16059296 : v = (v << 1) & 0xfefefefefefefefeULL; + 106 16059296 : v ^= mask & 0x1d1d1d1d1d1d1d1dULL; + 107 16059296 : return v; 108 : } 109 : 110 : /* @@ -174,12 +174,12 @@ 112 : */ 113 : static __always_inline uint32_t d2_32(uint32_t v) 114 : { - 115 12847040 : uint32_t mask = v & 0x01010101U; + 115 12388288 : uint32_t mask = v & 0x01010101U; 116 : - 117 12847040 : mask = (mask << 8) - mask; - 118 12847040 : v = (v >> 1) & 0x7f7f7f7fU; - 119 12847040 : v ^= mask & 0x8e8e8e8eU; - 120 12847040 : return v; + 117 12388288 : mask = (mask << 8) - mask; + 118 12388288 : v = (v >> 1) & 0x7f7f7f7fU; + 119 12388288 : v ^= mask & 0x8e8e8e8eU; + 120 12388288 : return v; 121 : } 122 : 123 : /* diff --git a/cov/raid/int.c.func-sort-c.html b/cov/raid/int.c.func-sort-c.html index 47981ef9..ae0ae4fb 100644 --- a/cov/raid/int.c.func-sort-c.html +++ b/cov/raid/int.c.func-sort-c.html @@ -69,7 +69,7 @@ raid_gen1_int64 - 184 + 182 raid_rec1_int8 @@ -77,16 +77,16 @@ raid_gen1_int32 - 112 - - - raid_gen2_int64 - 47 + 117 raid_gen2_int32 47 + + raid_gen2_int64 + 45 + raid_gen3_int8 26 @@ -97,11 +97,11 @@ raid_gen5_int8 - 18 + 17 raid_gen6_int8 - 17 + 15
diff --git a/cov/raid/int.c.func.html b/cov/raid/int.c.func.html index e7929128..1fff2bee 100644 --- a/cov/raid/int.c.func.html +++ b/cov/raid/int.c.func.html @@ -61,11 +61,11 @@ raid_gen1_int32 - 112 + 117 raid_gen1_int64 - 184 + 182 raid_gen2_int32 @@ -73,7 +73,7 @@ raid_gen2_int64 - 47 + 45 raid_gen3_int8 @@ -85,11 +85,11 @@ raid_gen5_int8 - 18 + 17 raid_gen6_int8 - 17 + 15 raid_rec1_int8 diff --git a/cov/raid/int.c.gcov.html b/cov/raid/int.c.gcov.html index 268fab74..0dbb07c5 100644 --- a/cov/raid/int.c.gcov.html +++ b/cov/raid/int.c.gcov.html @@ -80,9 +80,9 @@ 18 : /* 19 : * GEN1 (RAID5 with xor) 32bit C implementation 20 : */ - 21 112 : void raid_gen1_int32(int nd, size_t size, void **vv) + 21 117 : void raid_gen1_int32(int nd, size_t size, void **vv) 22 : { - 23 112 : uint8_t **v = (uint8_t **)vv; + 23 117 : uint8_t **v = (uint8_t **)vv; 24 : uint8_t *p; 25 : int d, l; 26 : size_t i; @@ -90,27 +90,27 @@ 28 : uint32_t p0; 29 : uint32_t p1; 30 : - 31 112 : l = nd - 1; - 32 112 : p = v[nd]; + 31 117 : l = nd - 1; + 32 117 : p = v[nd]; 33 : - 34 3571920 : for (i = 0; i < size; i += 8) { - 35 3571808 : p0 = v_32(v[l][i]); - 36 3571808 : p1 = v_32(v[l][i + 4]); - 37 28575776 : for (d = l - 1; d >= 0; --d) { - 38 25003968 : p0 ^= v_32(v[d][i]); - 39 25003968 : p1 ^= v_32(v[d][i + 4]); + 34 3735765 : for (i = 0; i < size; i += 8) { + 35 3735648 : p0 = v_32(v[l][i]); + 36 3735648 : p1 = v_32(v[l][i + 4]); + 37 29886496 : for (d = l - 1; d >= 0; --d) { + 38 26150848 : p0 ^= v_32(v[d][i]); + 39 26150848 : p1 ^= v_32(v[d][i + 4]); 40 : } - 41 3571808 : v_32(p[i]) = p0; - 42 3571808 : v_32(p[i + 4]) = p1; + 41 3735648 : v_32(p[i]) = p0; + 42 3735648 : v_32(p[i + 4]) = p1; 43 : } - 44 112 : } + 44 117 : } 45 : 46 : /* 47 : * GEN1 (RAID5 with xor) 64bit C implementation 48 : */ - 49 184 : void raid_gen1_int64(int nd, size_t size, void **vv) + 49 182 : void raid_gen1_int64(int nd, size_t size, void **vv) 50 : { - 51 184 : uint8_t **v = (uint8_t **)vv; + 51 182 : uint8_t **v = (uint8_t **)vv; 52 : uint8_t *p; 53 : int d, l; 54 : size_t i; @@ -118,20 +118,20 @@ 56 : uint64_t p0; 57 : uint64_t p1; 58 : - 59 184 : l = nd - 1; - 60 184 : p = v[nd]; + 59 182 : l = nd - 1; + 60 182 : p = v[nd]; 61 : - 62 2965736 : for (i = 0; i < size; i += 16) { - 63 2965552 : p0 = v_64(v[l][i]); - 64 2965552 : p1 = v_64(v[l][i + 8]); - 65 23725072 : for (d = l - 1; d >= 0; --d) { - 66 20759520 : p0 ^= v_64(v[d][i]); - 67 20759520 : p1 ^= v_64(v[d][i + 8]); + 62 2932966 : for (i = 0; i < size; i += 16) { + 63 2932784 : p0 = v_64(v[l][i]); + 64 2932784 : p1 = v_64(v[l][i + 8]); + 65 23462928 : for (d = l - 1; d >= 0; --d) { + 66 20530144 : p0 ^= v_64(v[d][i]); + 67 20530144 : p1 ^= v_64(v[d][i + 8]); 68 : } - 69 2965552 : v_64(p[i]) = p0; - 70 2965552 : v_64(p[i + 8]) = p1; + 69 2932784 : v_64(p[i]) = p0; + 70 2932784 : v_64(p[i + 8]) = p1; 71 : } - 72 184 : } + 72 182 : } 73 : 74 : /* 75 : * GEN2 (RAID6 with powers of 2) 32bit C implementation @@ -177,9 +177,9 @@ 115 : /* 116 : * GEN2 (RAID6 with powers of 2) 64bit C implementation 117 : */ - 118 47 : void raid_gen2_int64(int nd, size_t size, void **vv) + 118 45 : void raid_gen2_int64(int nd, size_t size, void **vv) 119 : { - 120 47 : uint8_t **v = (uint8_t **)vv; + 120 45 : uint8_t **v = (uint8_t **)vv; 121 : uint8_t *p; 122 : uint8_t *q; 123 : int d, l; @@ -188,32 +188,32 @@ 126 : uint64_t d0, q0, p0; 127 : uint64_t d1, q1, p1; 128 : - 129 47 : l = nd - 1; - 130 47 : p = v[nd]; - 131 47 : q = v[nd + 1]; + 129 45 : l = nd - 1; + 130 45 : p = v[nd]; + 131 45 : q = v[nd + 1]; 132 : - 133 720991 : for (i = 0; i < size; i += 16) { - 134 720944 : q0 = p0 = v_64(v[l][i]); - 135 720944 : q1 = p1 = v_64(v[l][i + 8]); - 136 5768208 : for (d = l - 1; d >= 0; --d) { - 137 5047264 : d0 = v_64(v[d][i]); - 138 5047264 : d1 = v_64(v[d][i + 8]); + 133 688221 : for (i = 0; i < size; i += 16) { + 134 688176 : q0 = p0 = v_64(v[l][i]); + 135 688176 : q1 = p1 = v_64(v[l][i + 8]); + 136 5506064 : for (d = l - 1; d >= 0; --d) { + 137 4817888 : d0 = v_64(v[d][i]); + 138 4817888 : d1 = v_64(v[d][i + 8]); 139 : - 140 5047264 : p0 ^= d0; - 141 5047264 : p1 ^= d1; + 140 4817888 : p0 ^= d0; + 141 4817888 : p1 ^= d1; 142 : - 143 5047264 : q0 = x2_64(q0); - 144 5047264 : q1 = x2_64(q1); + 143 4817888 : q0 = x2_64(q0); + 144 4817888 : q1 = x2_64(q1); 145 : - 146 5047264 : q0 ^= d0; - 147 5047264 : q1 ^= d1; + 146 4817888 : q0 ^= d0; + 147 4817888 : q1 ^= d1; 148 : } - 149 720944 : v_64(p[i]) = p0; - 150 720944 : v_64(p[i + 8]) = p1; - 151 720944 : v_64(q[i]) = q0; - 152 720944 : v_64(q[i + 8]) = q1; + 149 688176 : v_64(p[i]) = p0; + 150 688176 : v_64(p[i + 8]) = p1; + 151 688176 : v_64(q[i]) = q0; + 152 688176 : v_64(q[i + 8]) = q1; 153 : } - 154 47 : } + 154 45 : } 155 : 156 : /* 157 : * GEN3 (triple parity with Cauchy matrix) 8bit C implementation @@ -322,9 +322,9 @@ 260 : * But this is only a kind of reference function, and we are not really 261 : * interested in speed. 262 : */ - 263 18 : void raid_gen5_int8(int nd, size_t size, void **vv) + 263 17 : void raid_gen5_int8(int nd, size_t size, void **vv) 264 : { - 265 18 : uint8_t **v = (uint8_t **)vv; + 265 17 : uint8_t **v = (uint8_t **)vv; 266 : uint8_t *p; 267 : uint8_t *q; 268 : uint8_t *r; @@ -335,41 +335,41 @@ 273 : 274 : uint8_t d0, t0, s0, r0, q0, p0; 275 : - 276 18 : l = nd - 1; - 277 18 : p = v[nd]; - 278 18 : q = v[nd + 1]; - 279 18 : r = v[nd + 2]; - 280 18 : s = v[nd + 3]; - 281 18 : t = v[nd + 4]; + 276 17 : l = nd - 1; + 277 17 : p = v[nd]; + 278 17 : q = v[nd + 1]; + 279 17 : r = v[nd + 2]; + 280 17 : s = v[nd + 3]; + 281 17 : t = v[nd + 4]; 282 : - 283 4194834 : for (i = 0; i < size; i += 1) { - 284 4194816 : p0 = q0 = r0 = s0 = t0 = 0; - 285 33562880 : for (d = l; d > 0; --d) { - 286 29368064 : d0 = v_8(v[d][i]); + 283 3932689 : for (i = 0; i < size; i += 1) { + 284 3932672 : p0 = q0 = r0 = s0 = t0 = 0; + 285 31465728 : for (d = l; d > 0; --d) { + 286 27533056 : d0 = v_8(v[d][i]); 287 : - 288 29368064 : p0 ^= d0; - 289 29368064 : q0 ^= gfmul[d0][gfgen[1][d]]; - 290 29368064 : r0 ^= gfmul[d0][gfgen[2][d]]; - 291 29368064 : s0 ^= gfmul[d0][gfgen[3][d]]; - 292 29368064 : t0 ^= gfmul[d0][gfgen[4][d]]; + 288 27533056 : p0 ^= d0; + 289 27533056 : q0 ^= gfmul[d0][gfgen[1][d]]; + 290 27533056 : r0 ^= gfmul[d0][gfgen[2][d]]; + 291 27533056 : s0 ^= gfmul[d0][gfgen[3][d]]; + 292 27533056 : t0 ^= gfmul[d0][gfgen[4][d]]; 293 : } 294 : 295 : /* first disk with all coefficients at 1 */ - 296 4194816 : d0 = v_8(v[0][i]); + 296 3932672 : d0 = v_8(v[0][i]); 297 : - 298 4194816 : p0 ^= d0; - 299 4194816 : q0 ^= d0; - 300 4194816 : r0 ^= d0; - 301 4194816 : s0 ^= d0; - 302 4194816 : t0 ^= d0; + 298 3932672 : p0 ^= d0; + 299 3932672 : q0 ^= d0; + 300 3932672 : r0 ^= d0; + 301 3932672 : s0 ^= d0; + 302 3932672 : t0 ^= d0; 303 : - 304 4194816 : v_8(p[i]) = p0; - 305 4194816 : v_8(q[i]) = q0; - 306 4194816 : v_8(r[i]) = r0; - 307 4194816 : v_8(s[i]) = s0; - 308 4194816 : v_8(t[i]) = t0; + 304 3932672 : v_8(p[i]) = p0; + 305 3932672 : v_8(q[i]) = q0; + 306 3932672 : v_8(r[i]) = r0; + 307 3932672 : v_8(s[i]) = s0; + 308 3932672 : v_8(t[i]) = t0; 309 : } - 310 18 : } + 310 17 : } 311 : 312 : /* 313 : * GEN6 (hexa parity with Cauchy matrix) 8bit C implementation @@ -379,9 +379,9 @@ 317 : * But this is only a kind of reference function, and we are not really 318 : * interested in speed. 319 : */ - 320 17 : void raid_gen6_int8(int nd, size_t size, void **vv) + 320 15 : void raid_gen6_int8(int nd, size_t size, void **vv) 321 : { - 322 17 : uint8_t **v = (uint8_t **)vv; + 322 15 : uint8_t **v = (uint8_t **)vv; 323 : uint8_t *p; 324 : uint8_t *q; 325 : uint8_t *r; @@ -393,45 +393,45 @@ 331 : 332 : uint8_t d0, u0, t0, s0, r0, q0, p0; 333 : - 334 17 : l = nd - 1; - 335 17 : p = v[nd]; - 336 17 : q = v[nd + 1]; - 337 17 : r = v[nd + 2]; - 338 17 : s = v[nd + 3]; - 339 17 : t = v[nd + 4]; - 340 17 : u = v[nd + 5]; + 334 15 : l = nd - 1; + 335 15 : p = v[nd]; + 336 15 : q = v[nd + 1]; + 337 15 : r = v[nd + 2]; + 338 15 : s = v[nd + 3]; + 339 15 : t = v[nd + 4]; + 340 15 : u = v[nd + 5]; 341 : - 342 3932689 : for (i = 0; i < size; i += 1) { - 343 3932672 : p0 = q0 = r0 = s0 = t0 = u0 = 0; - 344 31465728 : for (d = l; d > 0; --d) { - 345 27533056 : d0 = v_8(v[d][i]); + 342 3408399 : for (i = 0; i < size; i += 1) { + 343 3408384 : p0 = q0 = r0 = s0 = t0 = u0 = 0; + 344 27271424 : for (d = l; d > 0; --d) { + 345 23863040 : d0 = v_8(v[d][i]); 346 : - 347 27533056 : p0 ^= d0; - 348 27533056 : q0 ^= gfmul[d0][gfgen[1][d]]; - 349 27533056 : r0 ^= gfmul[d0][gfgen[2][d]]; - 350 27533056 : s0 ^= gfmul[d0][gfgen[3][d]]; - 351 27533056 : t0 ^= gfmul[d0][gfgen[4][d]]; - 352 27533056 : u0 ^= gfmul[d0][gfgen[5][d]]; + 347 23863040 : p0 ^= d0; + 348 23863040 : q0 ^= gfmul[d0][gfgen[1][d]]; + 349 23863040 : r0 ^= gfmul[d0][gfgen[2][d]]; + 350 23863040 : s0 ^= gfmul[d0][gfgen[3][d]]; + 351 23863040 : t0 ^= gfmul[d0][gfgen[4][d]]; + 352 23863040 : u0 ^= gfmul[d0][gfgen[5][d]]; 353 : } 354 : 355 : /* first disk with all coefficients at 1 */ - 356 3932672 : d0 = v_8(v[0][i]); + 356 3408384 : d0 = v_8(v[0][i]); 357 : - 358 3932672 : p0 ^= d0; - 359 3932672 : q0 ^= d0; - 360 3932672 : r0 ^= d0; - 361 3932672 : s0 ^= d0; - 362 3932672 : t0 ^= d0; - 363 3932672 : u0 ^= d0; + 358 3408384 : p0 ^= d0; + 359 3408384 : q0 ^= d0; + 360 3408384 : r0 ^= d0; + 361 3408384 : s0 ^= d0; + 362 3408384 : t0 ^= d0; + 363 3408384 : u0 ^= d0; 364 : - 365 3932672 : v_8(p[i]) = p0; - 366 3932672 : v_8(q[i]) = q0; - 367 3932672 : v_8(r[i]) = r0; - 368 3932672 : v_8(s[i]) = s0; - 369 3932672 : v_8(t[i]) = t0; - 370 3932672 : v_8(u[i]) = u0; + 365 3408384 : v_8(p[i]) = p0; + 366 3408384 : v_8(q[i]) = q0; + 367 3408384 : v_8(r[i]) = r0; + 368 3408384 : v_8(s[i]) = s0; + 369 3408384 : v_8(t[i]) = t0; + 370 3408384 : v_8(u[i]) = u0; 371 : } - 372 17 : } + 372 15 : } 373 : 374 : /* 375 : * Recover failure of one data block at index id[0] using parity at index diff --git a/cov/raid/internal.h.gcov.html b/cov/raid/internal.h.gcov.html index 2810fbf1..afad0a9c 100644 --- a/cov/raid/internal.h.gcov.html +++ b/cov/raid/internal.h.gcov.html @@ -169,11 +169,11 @@ 107 : */ 108 : static __always_inline void *__align_ptr(void *ptr, uintptr_t size) 109 : { - 110 711847 : uintptr_t offset = (uintptr_t)ptr; + 110 711919 : uintptr_t offset = (uintptr_t)ptr; 111 : - 112 711847 : offset = (offset + size - 1U) & ~(size - 1U); + 112 711919 : offset = (offset + size - 1U) & ~(size - 1U); 113 : - 114 711847 : return (void *)offset; + 114 711919 : return (void *)offset; 115 : } 116 : 117 : /* @@ -294,7 +294,7 @@ 232 : /* that use a weak memory model. To ensure that other processors */ 233 : /* see correctly the data written, we use a store-store memory */ 234 : /* barrier at the end of the asm code */ - 235 1388678 : asm volatile ("sfence" : : : "memory"); + 235 1388842 : asm volatile ("sfence" : : : "memory"); 236 : 237 : /* clobbers registers used in the asm code */ 238 : /* this is required because in the Windows ABI, */ diff --git a/cov/raid/intz.c.func-sort-c.html b/cov/raid/intz.c.func-sort-c.html index f0eebc82..ffbcc252 100644 --- a/cov/raid/intz.c.func-sort-c.html +++ b/cov/raid/intz.c.func-sort-c.html @@ -65,7 +65,7 @@ raid_genz_int32 - 29 + 28
diff --git a/cov/raid/intz.c.func.html b/cov/raid/intz.c.func.html index d03542db..6d2291be 100644 --- a/cov/raid/intz.c.func.html +++ b/cov/raid/intz.c.func.html @@ -61,7 +61,7 @@ raid_genz_int32 - 29 + 28 raid_genz_int64 diff --git a/cov/raid/intz.c.gcov.html b/cov/raid/intz.c.gcov.html index 90778a8f..635e0eb1 100644 --- a/cov/raid/intz.c.gcov.html +++ b/cov/raid/intz.c.gcov.html @@ -80,9 +80,9 @@ 18 : /* 19 : * GENz (triple parity with powers of 2^-1) 32bit C implementation 20 : */ - 21 29 : void raid_genz_int32(int nd, size_t size, void **vv) + 21 28 : void raid_genz_int32(int nd, size_t size, void **vv) 22 : { - 23 29 : uint8_t **v = (uint8_t**)vv; + 23 28 : uint8_t **v = (uint8_t**)vv; 24 : uint8_t *p; 25 : uint8_t *q; 26 : uint8_t *r; @@ -92,41 +92,41 @@ 30 : uint32_t d0, r0, q0, p0; 31 : uint32_t d1, r1, q1, p1; 32 : - 33 29 : l = nd - 1; - 34 29 : p = v[nd]; - 35 29 : q = v[nd + 1]; - 36 29 : r = v[nd + 2]; + 33 28 : l = nd - 1; + 34 28 : p = v[nd]; + 35 28 : q = v[nd + 1]; + 36 28 : r = v[nd + 2]; 37 : - 38 917565 : for (i = 0; i < size; i += 8) { - 39 917536 : r0 = q0 = p0 = v_32(v[l][i]); - 40 917536 : r1 = q1 = p1 = v_32(v[l][i + 4]); - 41 7341056 : for (d = l - 1; d >= 0; --d) { - 42 6423520 : d0 = v_32(v[d][i]); - 43 6423520 : d1 = v_32(v[d][i + 4]); + 38 884796 : for (i = 0; i < size; i += 8) { + 39 884768 : r0 = q0 = p0 = v_32(v[l][i]); + 40 884768 : r1 = q1 = p1 = v_32(v[l][i + 4]); + 41 7078912 : for (d = l - 1; d >= 0; --d) { + 42 6194144 : d0 = v_32(v[d][i]); + 43 6194144 : d1 = v_32(v[d][i + 4]); 44 : - 45 6423520 : p0 ^= d0; - 46 6423520 : p1 ^= d1; + 45 6194144 : p0 ^= d0; + 46 6194144 : p1 ^= d1; 47 : - 48 6423520 : q0 = x2_32(q0); - 49 6423520 : q1 = x2_32(q1); + 48 6194144 : q0 = x2_32(q0); + 49 6194144 : q1 = x2_32(q1); 50 : - 51 6423520 : q0 ^= d0; - 52 6423520 : q1 ^= d1; + 51 6194144 : q0 ^= d0; + 52 6194144 : q1 ^= d1; 53 : - 54 6423520 : r0 = d2_32(r0); - 55 6423520 : r1 = d2_32(r1); + 54 6194144 : r0 = d2_32(r0); + 55 6194144 : r1 = d2_32(r1); 56 : - 57 6423520 : r0 ^= d0; - 58 6423520 : r1 ^= d1; + 57 6194144 : r0 ^= d0; + 58 6194144 : r1 ^= d1; 59 : } - 60 917536 : v_32(p[i]) = p0; - 61 917536 : v_32(p[i + 4]) = p1; - 62 917536 : v_32(q[i]) = q0; - 63 917536 : v_32(q[i + 4]) = q1; - 64 917536 : v_32(r[i]) = r0; - 65 917536 : v_32(r[i + 4]) = r1; + 60 884768 : v_32(p[i]) = p0; + 61 884768 : v_32(p[i + 4]) = p1; + 62 884768 : v_32(q[i]) = q0; + 63 884768 : v_32(q[i + 4]) = q1; + 64 884768 : v_32(r[i]) = r0; + 65 884768 : v_32(r[i + 4]) = r1; 66 : } - 67 29 : } + 67 28 : } 68 : 69 : /* 70 : * GENz (triple parity with powers of 2^-1) 64bit C implementation diff --git a/cov/raid/memory.c.gcov.html b/cov/raid/memory.c.gcov.html index 36942cce..c141cae2 100644 --- a/cov/raid/memory.c.gcov.html +++ b/cov/raid/memory.c.gcov.html @@ -94,7 +94,7 @@ 32 12558 : offset = ((uintptr_t)ptr) % align_size; 33 : 34 12558 : if (offset != 0) - 35 12172 : ptr += align_size - offset; + 35 12171 : ptr += align_size - offset; 36 : 37 12558 : return ptr; 38 : } diff --git a/cov/raid/module.c.func-sort-c.html b/cov/raid/module.c.func-sort-c.html index 39519b44..185903de 100644 --- a/cov/raid/module.c.func-sort-c.html +++ b/cov/raid/module.c.func-sort-c.html @@ -61,7 +61,7 @@ raid_init - 269 + 270 raid_test_rec diff --git a/cov/raid/module.c.func.html b/cov/raid/module.c.func.html index ec058144..7d71c214 100644 --- a/cov/raid/module.c.func.html +++ b/cov/raid/module.c.func.html @@ -65,7 +65,7 @@ raid_init - 269 + 270 raid_selftest diff --git a/cov/raid/module.c.gcov.html b/cov/raid/module.c.gcov.html index 3264dd75..4b69d7ae 100644 --- a/cov/raid/module.c.gcov.html +++ b/cov/raid/module.c.gcov.html @@ -81,34 +81,34 @@ 19 : /* 20 : * Initializes and selects the best algorithm. 21 : */ - 22 269 : void raid_init(void) + 22 270 : void raid_init(void) 23 : { - 24 269 : raid_gen3_ptr = raid_gen3_int8; - 25 269 : raid_gen_ptr[3] = raid_gen4_int8; - 26 269 : raid_gen_ptr[4] = raid_gen5_int8; - 27 269 : raid_gen_ptr[5] = raid_gen6_int8; + 24 270 : raid_gen3_ptr = raid_gen3_int8; + 25 270 : raid_gen_ptr[3] = raid_gen4_int8; + 26 270 : raid_gen_ptr[4] = raid_gen5_int8; + 27 270 : raid_gen_ptr[5] = raid_gen6_int8; 28 : 29 : if (sizeof(void *) == 4) { - 30 269 : raid_gen_ptr[0] = raid_gen1_int32; - 31 269 : raid_gen_ptr[1] = raid_gen2_int32; - 32 269 : raid_genz_ptr = raid_genz_int32; + 30 270 : raid_gen_ptr[0] = raid_gen1_int32; + 31 270 : raid_gen_ptr[1] = raid_gen2_int32; + 32 270 : raid_genz_ptr = raid_genz_int32; 33 : } else { 34 : raid_gen_ptr[0] = raid_gen1_int64; 35 : raid_gen_ptr[1] = raid_gen2_int64; 36 : raid_genz_ptr = raid_genz_int64; 37 : } 38 : - 39 269 : raid_rec_ptr[0] = raid_rec1_int8; - 40 269 : raid_rec_ptr[1] = raid_rec2_int8; - 41 269 : raid_rec_ptr[2] = raid_recX_int8; - 42 269 : raid_rec_ptr[3] = raid_recX_int8; - 43 269 : raid_rec_ptr[4] = raid_recX_int8; - 44 269 : raid_rec_ptr[5] = raid_recX_int8; + 39 270 : raid_rec_ptr[0] = raid_rec1_int8; + 40 270 : raid_rec_ptr[1] = raid_rec2_int8; + 41 270 : raid_rec_ptr[2] = raid_recX_int8; + 42 270 : raid_rec_ptr[3] = raid_recX_int8; + 43 270 : raid_rec_ptr[4] = raid_recX_int8; + 44 270 : raid_rec_ptr[5] = raid_recX_int8; 45 : 46 : #ifdef CONFIG_X86 47 : #ifdef CONFIG_SSE2 - 48 269 : if (raid_cpu_has_sse2()) { - 49 269 : raid_gen_ptr[0] = raid_gen1_sse2; + 48 270 : if (raid_cpu_has_sse2()) { + 49 270 : raid_gen_ptr[0] = raid_gen1_sse2; 50 : #ifdef CONFIG_X86_64 51 : if (raid_cpu_has_slowextendedreg()) { 52 : raid_gen_ptr[1] = raid_gen2_sse2; @@ -118,14 +118,14 @@ 56 : /* note that raid_cpu_has_slowextendedreg() doesn't affect parz */ 57 : raid_genz_ptr = raid_genz_sse2ext; 58 : #else - 59 269 : raid_gen_ptr[1] = raid_gen2_sse2; - 60 269 : raid_genz_ptr = raid_genz_sse2; + 59 270 : raid_gen_ptr[1] = raid_gen2_sse2; + 60 270 : raid_genz_ptr = raid_genz_sse2; 61 : #endif 62 : } 63 : #endif 64 : 65 : #ifdef CONFIG_SSSE3 - 66 269 : if (raid_cpu_has_ssse3()) { + 66 270 : if (raid_cpu_has_ssse3()) { 67 : #ifdef CONFIG_X86_64 68 : if (raid_cpu_has_slowextendedreg()) { 69 : raid_gen3_ptr = raid_gen3_ssse3; @@ -139,22 +139,22 @@ 77 : raid_gen_ptr[5] = raid_gen6_ssse3ext; 78 : } 79 : #else - 80 268 : raid_gen3_ptr = raid_gen3_ssse3; - 81 268 : raid_gen_ptr[3] = raid_gen4_ssse3; - 82 268 : raid_gen_ptr[4] = raid_gen5_ssse3; - 83 268 : raid_gen_ptr[5] = raid_gen6_ssse3; + 80 269 : raid_gen3_ptr = raid_gen3_ssse3; + 81 269 : raid_gen_ptr[3] = raid_gen4_ssse3; + 82 269 : raid_gen_ptr[4] = raid_gen5_ssse3; + 83 269 : raid_gen_ptr[5] = raid_gen6_ssse3; 84 : #endif - 85 268 : raid_rec_ptr[0] = raid_rec1_ssse3; - 86 268 : raid_rec_ptr[1] = raid_rec2_ssse3; - 87 268 : raid_rec_ptr[2] = raid_recX_ssse3; - 88 268 : raid_rec_ptr[3] = raid_recX_ssse3; - 89 268 : raid_rec_ptr[4] = raid_recX_ssse3; - 90 268 : raid_rec_ptr[5] = raid_recX_ssse3; + 85 269 : raid_rec_ptr[0] = raid_rec1_ssse3; + 86 269 : raid_rec_ptr[1] = raid_rec2_ssse3; + 87 269 : raid_rec_ptr[2] = raid_recX_ssse3; + 88 269 : raid_rec_ptr[3] = raid_recX_ssse3; + 89 269 : raid_rec_ptr[4] = raid_recX_ssse3; + 90 269 : raid_rec_ptr[5] = raid_recX_ssse3; 91 : } 92 : #endif 93 : 94 : #ifdef CONFIG_AVX2 - 95 269 : if (raid_cpu_has_avx2()) { + 95 270 : if (raid_cpu_has_avx2()) { 96 2 : raid_gen_ptr[0] = raid_gen1_avx2; 97 2 : raid_gen_ptr[1] = raid_gen2_avx2; 98 : #ifdef CONFIG_X86_64 @@ -175,8 +175,8 @@ 113 : #endif /* CONFIG_X86 */ 114 : 115 : /* set the default mode */ - 116 269 : raid_mode(RAID_MODE_CAUCHY); - 117 269 : } + 116 270 : raid_mode(RAID_MODE_CAUCHY); + 117 270 : } 118 : 119 : /* 120 : * Reference parity computation. diff --git a/cov/raid/raid.c.func-sort-c.html b/cov/raid/raid.c.func-sort-c.html index 96d13cb1..1f035c3f 100644 --- a/cov/raid/raid.c.func-sort-c.html +++ b/cov/raid/raid.c.func-sort-c.html @@ -61,23 +61,23 @@ raid_gen - 1235540 + 1235917 raid_data - 214715 + 214914 raid_invert - 172728 + 172507 raid_delta_gen - 171710 + 171503 raid_rec1of1 - 101386 + 101792 raid_rec @@ -85,7 +85,7 @@ raid_mode - 537 + 539 raid_zero diff --git a/cov/raid/raid.c.func.html b/cov/raid/raid.c.func.html index 90b2af40..1758cd6d 100644 --- a/cov/raid/raid.c.func.html +++ b/cov/raid/raid.c.func.html @@ -61,23 +61,23 @@ raid_data - 214715 + 214914 raid_delta_gen - 171710 + 171503 raid_gen - 1235540 + 1235917 raid_invert - 172728 + 172507 raid_mode - 537 + 539 raid_rec @@ -85,7 +85,7 @@ raid_rec1of1 - 101386 + 101792 raid_rec2of2_int8 diff --git a/cov/raid/raid.c.gcov.html b/cov/raid/raid.c.gcov.html index 3319701e..9923f537 100644 --- a/cov/raid/raid.c.gcov.html +++ b/cov/raid/raid.c.gcov.html @@ -235,16 +235,16 @@ 173 : */ 174 : const uint8_t (*raid_gfgen)[256]; 175 : - 176 537 : void raid_mode(int mode) + 176 539 : void raid_mode(int mode) 177 : { - 178 537 : if (mode == RAID_MODE_VANDERMONDE) { + 178 539 : if (mode == RAID_MODE_VANDERMONDE) { 179 2 : raid_gen_ptr[2] = raid_genz_ptr; 180 2 : raid_gfgen = gfvandermonde; 181 : } else { - 182 535 : raid_gen_ptr[2] = raid_gen3_ptr; - 183 535 : raid_gfgen = gfcauchy; + 182 537 : raid_gen_ptr[2] = raid_gen3_ptr; + 183 537 : raid_gfgen = gfcauchy; 184 : } - 185 537 : } + 185 539 : } 186 : 187 : /** 188 : * Buffer filled with 0 used in recovering. @@ -282,17 +282,17 @@ 220 : void (*raid_gen3_ptr)(int nd, size_t size, void **vv); 221 : void (*raid_genz_ptr)(int nd, size_t size, void **vv); 222 : - 223 1235540 : void raid_gen(int nd, int np, size_t size, void **v) + 223 1235917 : void raid_gen(int nd, int np, size_t size, void **v) 224 : { 225 : /* enforce limit on size */ - 226 1235540 : BUG_ON(size % 64 != 0); + 226 1235917 : BUG_ON(size % 64 != 0); 227 : 228 : /* enforce limit on number of failures */ - 229 1235540 : BUG_ON(np < 1); - 230 1235540 : BUG_ON(np > RAID_PARITY_MAX); + 229 1235917 : BUG_ON(np < 1); + 230 1235917 : BUG_ON(np > RAID_PARITY_MAX); 231 : - 232 1235540 : raid_gen_ptr[np - 1](nd, size, v); - 233 1235540 : } + 232 1235917 : raid_gen_ptr[np - 1](nd, size, v); + 233 1235917 : } 234 : 235 : /** 236 : * Inverts the square matrix M of size nxn into V. @@ -305,44 +305,44 @@ 243 : * @V Destination matrix where the result is put. 244 : * @n Number of rows and columns of the matrix. 245 : */ - 246 172728 : void raid_invert(uint8_t *M, uint8_t *V, int n) + 246 172507 : void raid_invert(uint8_t *M, uint8_t *V, int n) 247 : { 248 : int i, j, k; 249 : 250 : /* set the identity matrix in V */ - 251 798241 : for (i = 0; i < n; ++i) - 252 3220766 : for (j = 0; j < n; ++j) - 253 2595253 : V[i * n + j] = i == j; + 251 797578 : for (i = 0; i < n; ++i) + 252 3219440 : for (j = 0; j < n; ++j) + 253 2594369 : V[i * n + j] = i == j; 254 : 255 : /* for each element in the diagonal */ - 256 798241 : for (k = 0; k < n; ++k) { + 256 797578 : for (k = 0; k < n; ++k) { 257 : uint8_t f; 258 : 259 : /* the diagonal element cannot be 0 because */ 260 : /* we are inverting matrices with all the square */ 261 : /* submatrices not singular */ - 262 625513 : BUG_ON(M[k * n + k] == 0); + 262 625071 : BUG_ON(M[k * n + k] == 0); 263 : 264 : /* make the diagonal element to be 1 */ - 265 1251026 : f = inv(M[k * n + k]); - 266 3220766 : for (j = 0; j < n; ++j) { - 267 5190506 : M[k * n + j] = mul(f, M[k * n + j]); - 268 5190506 : V[k * n + j] = mul(f, V[k * n + j]); + 265 1250142 : f = inv(M[k * n + k]); + 266 3219440 : for (j = 0; j < n; ++j) { + 267 5188738 : M[k * n + j] = mul(f, M[k * n + j]); + 268 5188738 : V[k * n + j] = mul(f, V[k * n + j]); 269 : } 270 : 271 : /* make all the elements over and under the diagonal */ 272 : /* to be zero */ - 273 3220766 : for (i = 0; i < n; ++i) { - 274 2595253 : if (i == k) - 275 625513 : continue; - 276 1969740 : f = M[i * n + k]; - 277 11272284 : for (j = 0; j < n; ++j) { - 278 18605088 : M[i * n + j] ^= mul(f, M[k * n + j]); - 279 18605088 : V[i * n + j] ^= mul(f, V[k * n + j]); + 273 3219440 : for (i = 0; i < n; ++i) { + 274 2594369 : if (i == k) + 275 625071 : continue; + 276 1969298 : f = M[i * n + k]; + 277 11270958 : for (j = 0; j < n; ++j) { + 278 18603320 : M[i * n + j] ^= mul(f, M[k * n + j]); + 279 18603320 : V[i * n + j] ^= mul(f, V[k * n + j]); 280 : } 281 : } 282 : } - 283 172728 : } + 283 172507 : } 284 : 285 : /** 286 : * Computes the parity without the missing data blocks @@ -350,7 +350,7 @@ 288 : * 289 : * This is the parity expressed as Pa,Qa,Ra,Sa,Ta,Ua in the equations. 290 : */ - 291 171710 : void raid_delta_gen(int nr, int *id, int *ip, int nd, size_t size, void **v) + 291 171503 : void raid_delta_gen(int nr, int *id, int *ip, int nd, size_t size, void **v) 292 : { 293 : void *p[RAID_PARITY_MAX]; 294 : void *pa[RAID_PARITY_MAX]; @@ -360,17 +360,17 @@ 298 : 299 : /* total number of parities we are going to process */ 300 : /* they are both the used and the unused ones */ - 301 171710 : np = ip[nr - 1] + 1; + 301 171503 : np = ip[nr - 1] + 1; 302 : 303 : /* latest missing data block */ - 304 171710 : latest = v[id[nr - 1]]; + 304 171503 : latest = v[id[nr - 1]]; 305 : 306 : /* setup pointers for delta computation */ - 307 873674 : for (i = 0, j = 0; i < np; ++i) { + 307 873053 : for (i = 0, j = 0; i < np; ++i) { 308 : /* keep a copy of the original parity vector */ - 309 701964 : p[i] = v[nd + i]; + 309 701550 : p[i] = v[nd + i]; 310 : - 311 701964 : if (ip[j] == i) { + 311 701550 : if (ip[j] == i) { 312 : /* 313 : * Set used parities to point to the missing 314 : * data blocks. @@ -381,19 +381,19 @@ 319 : 320 : /* the latest parity to use ends the for loop and */ 321 : /* then it cannot happen to process more of them */ - 322 605821 : BUG_ON(j >= nr); + 322 605393 : BUG_ON(j >= nr); 323 : 324 : /* buffer for missing data blocks */ - 325 605821 : pa[j] = v[id[j]]; + 325 605393 : pa[j] = v[id[j]]; 326 : 327 : /* set at zero the missing data blocks */ - 328 605821 : v[id[j]] = raid_zero_block; + 328 605393 : v[id[j]] = raid_zero_block; 329 : 330 : /* compute the parity over the missing data blocks */ - 331 605821 : v[nd + i] = pa[j]; + 331 605393 : v[nd + i] = pa[j]; 332 : 333 : /* check for the next used entry */ - 334 605821 : ++j; + 334 605393 : ++j; 335 : } else { 336 : /* 337 : * Unused parities are going to be rewritten with @@ -413,25 +413,25 @@ 351 : * multiple times and only the latest write will 352 : * contain the correct data. 353 : */ - 354 96143 : v[nd + i] = latest; + 354 96157 : v[nd + i] = latest; 355 : } 356 : } 357 : 358 : /* all the parities have to be processed */ - 359 171710 : BUG_ON(j != nr); + 359 171503 : BUG_ON(j != nr); 360 : 361 : /* recompute the parity, note that np may be smaller than the */ 362 : /* total number of parities available */ - 363 171710 : raid_gen(nd, np, size, v); + 363 171503 : raid_gen(nd, np, size, v); 364 : 365 : /* restore data buffers as before */ - 366 777531 : for (j = 0; j < nr; ++j) - 367 605821 : v[id[j]] = pa[j]; + 366 776896 : for (j = 0; j < nr; ++j) + 367 605393 : v[id[j]] = pa[j]; 368 : 369 : /* restore parity buffers as before */ - 370 873674 : for (i = 0; i < np; ++i) - 371 701964 : v[nd + i] = p[i]; - 372 171710 : } + 370 873053 : for (i = 0; i < np; ++i) + 371 701550 : v[nd + i] = p[i]; + 372 171503 : } 373 : 374 : /** 375 : * Recover failure of one data block for PAR1. @@ -444,29 +444,29 @@ 382 : * 383 : * Dx = Pd 384 : */ - 385 101386 : void raid_rec1of1(int *id, int nd, size_t size, void **v) + 385 101792 : void raid_rec1of1(int *id, int nd, size_t size, void **v) 386 : { 387 : void *p; 388 : void *pa; 389 : 390 : /* for PAR1 we can directly compute the missing block */ 391 : /* and we don't need to use the zero buffer */ - 392 101386 : p = v[nd]; - 393 101386 : pa = v[id[0]]; + 392 101792 : p = v[nd]; + 393 101792 : pa = v[id[0]]; 394 : 395 : /* use the parity as missing data block */ - 396 101386 : v[id[0]] = p; + 396 101792 : v[id[0]] = p; 397 : 398 : /* compute the parity over the missing data block */ - 399 101386 : v[nd] = pa; + 399 101792 : v[nd] = pa; 400 : 401 : /* compute */ - 402 101386 : raid_gen(nd, 1, size, v); + 402 101792 : raid_gen(nd, 1, size, v); 403 : 404 : /* restore as before */ - 405 101386 : v[id[0]] = pa; - 406 101386 : v[nd] = p; - 407 101386 : } + 405 101792 : v[id[0]] = pa; + 406 101792 : v[nd] = p; + 407 101792 : } 408 : 409 : /** 410 : * Recover failure of two data blocks for PAR2. @@ -615,36 +615,36 @@ 553 12 : raid_gen(nd, ir[nr - 1] - nd + 1, size, v); 554 870 : } 555 : - 556 214715 : void raid_data(int nr, int *id, int *ip, int nd, size_t size, void **v) + 556 214914 : void raid_data(int nr, int *id, int *ip, int nd, size_t size, void **v) 557 : { 558 : /* enforce limit on size */ - 559 214715 : BUG_ON(size % 64 != 0); + 559 214914 : BUG_ON(size % 64 != 0); 560 : 561 : /* enforce limit on number of failures */ - 562 214715 : BUG_ON(nr > nd); - 563 214715 : BUG_ON(nr > RAID_PARITY_MAX); + 562 214914 : BUG_ON(nr > nd); + 563 214914 : BUG_ON(nr > RAID_PARITY_MAX); 564 : 565 : /* enforce order in index vector for data */ - 566 214715 : BUG_ON(nr >= 2 && id[0] >= id[1]); - 567 214715 : BUG_ON(nr >= 3 && id[1] >= id[2]); - 568 214715 : BUG_ON(nr >= 4 && id[2] >= id[3]); - 569 214715 : BUG_ON(nr >= 5 && id[3] >= id[4]); - 570 214715 : BUG_ON(nr >= 6 && id[4] >= id[5]); + 566 214914 : BUG_ON(nr >= 2 && id[0] >= id[1]); + 567 214914 : BUG_ON(nr >= 3 && id[1] >= id[2]); + 568 214914 : BUG_ON(nr >= 4 && id[2] >= id[3]); + 569 214914 : BUG_ON(nr >= 5 && id[3] >= id[4]); + 570 214914 : BUG_ON(nr >= 6 && id[4] >= id[5]); 571 : 572 : /* enforce limit on index vector for data */ - 573 214715 : BUG_ON(nr > 0 && id[nr-1] >= nd); + 573 214914 : BUG_ON(nr > 0 && id[nr-1] >= nd); 574 : 575 : /* enforce order in index vector for parity */ - 576 214715 : BUG_ON(nr >= 2 && ip[0] >= ip[1]); - 577 214715 : BUG_ON(nr >= 3 && ip[1] >= ip[2]); - 578 214715 : BUG_ON(nr >= 4 && ip[2] >= ip[3]); - 579 214715 : BUG_ON(nr >= 5 && ip[3] >= ip[4]); - 580 214715 : BUG_ON(nr >= 6 && ip[4] >= ip[5]); + 576 214914 : BUG_ON(nr >= 2 && ip[0] >= ip[1]); + 577 214914 : BUG_ON(nr >= 3 && ip[1] >= ip[2]); + 578 214914 : BUG_ON(nr >= 4 && ip[2] >= ip[3]); + 579 214914 : BUG_ON(nr >= 5 && ip[3] >= ip[4]); + 580 214914 : BUG_ON(nr >= 6 && ip[4] >= ip[5]); 581 : 582 : /* if failed data is present */ - 583 214715 : if (nr != 0) - 584 214713 : raid_rec_ptr[nr - 1](nr, id, ip, nd, size, v); - 585 214715 : } + 583 214914 : if (nr != 0) + 584 214912 : raid_rec_ptr[nr - 1](nr, id, ip, nd, size, v); + 585 214914 : } 586 : diff --git a/cov/raid/x86.c.func-sort-c.html b/cov/raid/x86.c.func-sort-c.html index f981eaff..52148a1e 100644 --- a/cov/raid/x86.c.func-sort-c.html +++ b/cov/raid/x86.c.func-sort-c.html @@ -61,19 +61,19 @@ raid_gen6_ssse3 - 564140 + 564213 raid_gen1_sse2 - 288654 + 289166 raid_gen2_sse2 - 268936 + 268726 raid_rec1_ssse3 - 111201 + 111621 raid_recX_ssse3 @@ -81,19 +81,19 @@ raid_gen5_ssse3 - 50654 + 50653 raid_rec2_ssse3 - 44277 + 44056 raid_gen4_ssse3 - 32471 + 32470 raid_gen3_ssse3 - 29543 + 29542 raid_recX_avx2 diff --git a/cov/raid/x86.c.func.html b/cov/raid/x86.c.func.html index 2309dbdc..e0e39976 100644 --- a/cov/raid/x86.c.func.html +++ b/cov/raid/x86.c.func.html @@ -65,7 +65,7 @@ raid_gen1_sse2 - 288654 + 289166 raid_gen2_avx2 @@ -73,23 +73,23 @@ raid_gen2_sse2 - 268936 + 268726 raid_gen3_ssse3 - 29543 + 29542 raid_gen4_ssse3 - 32471 + 32470 raid_gen5_ssse3 - 50654 + 50653 raid_gen6_ssse3 - 564140 + 564213 raid_rec1_avx2 @@ -97,7 +97,7 @@ raid_rec1_ssse3 - 111201 + 111621 raid_rec2_avx2 @@ -105,7 +105,7 @@ raid_rec2_ssse3 - 44277 + 44056 raid_recX_avx2 diff --git a/cov/raid/x86.c.gcov.html b/cov/raid/x86.c.gcov.html index 0722716b..04aeec56 100644 --- a/cov/raid/x86.c.gcov.html +++ b/cov/raid/x86.c.gcov.html @@ -95,37 +95,37 @@ 33 : * cache block, and processing 128 bytes doesn't increase performance, and in 34 : * some cases it even decreases it. 35 : */ - 36 288654 : void raid_gen1_sse2(int nd, size_t size, void **vv) + 36 289166 : void raid_gen1_sse2(int nd, size_t size, void **vv) 37 : { - 38 288654 : uint8_t **v = (uint8_t **)vv; + 38 289166 : uint8_t **v = (uint8_t **)vv; 39 : uint8_t *p; 40 : int d, l; 41 : size_t i; 42 : - 43 288654 : l = nd - 1; - 44 288654 : p = v[nd]; + 43 289166 : l = nd - 1; + 44 289166 : p = v[nd]; 45 : 46 : raid_sse_begin(); 47 : - 48 6127002 : for (i = 0; i < size; i += 64) { - 49 5838348 : asm volatile ("movdqa %0,%%xmm0" : : "m" (v[l][i])); - 50 5838348 : asm volatile ("movdqa %0,%%xmm1" : : "m" (v[l][i + 16])); - 51 5838348 : asm volatile ("movdqa %0,%%xmm2" : : "m" (v[l][i + 32])); - 52 5838348 : asm volatile ("movdqa %0,%%xmm3" : : "m" (v[l][i + 48])); - 53 37479684 : for (d = l - 1; d >= 0; --d) { - 54 31641336 : asm volatile ("pxor %0,%%xmm0" : : "m" (v[d][i])); - 55 31641336 : asm volatile ("pxor %0,%%xmm1" : : "m" (v[d][i + 16])); - 56 31641336 : asm volatile ("pxor %0,%%xmm2" : : "m" (v[d][i + 32])); - 57 31641336 : asm volatile ("pxor %0,%%xmm3" : : "m" (v[d][i + 48])); + 48 6139786 : for (i = 0; i < size; i += 64) { + 49 5850620 : asm volatile ("movdqa %0,%%xmm0" : : "m" (v[l][i])); + 50 5850620 : asm volatile ("movdqa %0,%%xmm1" : : "m" (v[l][i + 16])); + 51 5850620 : asm volatile ("movdqa %0,%%xmm2" : : "m" (v[l][i + 32])); + 52 5850620 : asm volatile ("movdqa %0,%%xmm3" : : "m" (v[l][i + 48])); + 53 37561508 : for (d = l - 1; d >= 0; --d) { + 54 31710888 : asm volatile ("pxor %0,%%xmm0" : : "m" (v[d][i])); + 55 31710888 : asm volatile ("pxor %0,%%xmm1" : : "m" (v[d][i + 16])); + 56 31710888 : asm volatile ("pxor %0,%%xmm2" : : "m" (v[d][i + 32])); + 57 31710888 : asm volatile ("pxor %0,%%xmm3" : : "m" (v[d][i + 48])); 58 : } - 59 5838348 : asm volatile ("movntdq %%xmm0,%0" : "=m" (p[i])); - 60 5838348 : asm volatile ("movntdq %%xmm1,%0" : "=m" (p[i + 16])); - 61 5838348 : asm volatile ("movntdq %%xmm2,%0" : "=m" (p[i + 32])); - 62 5838348 : asm volatile ("movntdq %%xmm3,%0" : "=m" (p[i + 48])); + 59 5850620 : asm volatile ("movntdq %%xmm0,%0" : "=m" (p[i])); + 60 5850620 : asm volatile ("movntdq %%xmm1,%0" : "=m" (p[i + 16])); + 61 5850620 : asm volatile ("movntdq %%xmm2,%0" : "=m" (p[i + 32])); + 62 5850620 : asm volatile ("movntdq %%xmm3,%0" : "=m" (p[i + 48])); 63 : } 64 : 65 : raid_sse_end(); - 66 288654 : } + 66 289166 : } 67 : #endif 68 : 69 : #if defined(CONFIG_X86) && defined(CONFIG_AVX2) @@ -183,54 +183,54 @@ 121 : /* 122 : * GEN2 (RAID6 with powers of 2) SSE2 implementation 123 : */ - 124 268936 : void raid_gen2_sse2(int nd, size_t size, void **vv) + 124 268726 : void raid_gen2_sse2(int nd, size_t size, void **vv) 125 : { - 126 268936 : uint8_t **v = (uint8_t **)vv; + 126 268726 : uint8_t **v = (uint8_t **)vv; 127 : uint8_t *p; 128 : uint8_t *q; 129 : int d, l; 130 : size_t i; 131 : - 132 268936 : l = nd - 1; - 133 268936 : p = v[nd]; - 134 268936 : q = v[nd + 1]; + 132 268726 : l = nd - 1; + 133 268726 : p = v[nd]; + 134 268726 : q = v[nd + 1]; 135 : 136 : raid_sse_begin(); 137 : - 138 268936 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.poly[0])); + 138 268726 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.poly[0])); 139 : - 140 10800576 : for (i = 0; i < size; i += 32) { - 141 10531640 : asm volatile ("movdqa %0,%%xmm0" : : "m" (v[l][i])); - 142 10531640 : asm volatile ("movdqa %0,%%xmm1" : : "m" (v[l][i + 16])); - 143 10531640 : asm volatile ("movdqa %xmm0,%xmm2"); - 144 10531640 : asm volatile ("movdqa %xmm1,%xmm3"); - 145 67056840 : for (d = l - 1; d >= 0; --d) { - 146 56525200 : asm volatile ("pxor %xmm4,%xmm4"); - 147 56525200 : asm volatile ("pxor %xmm5,%xmm5"); - 148 56525200 : asm volatile ("pcmpgtb %xmm2,%xmm4"); - 149 56525200 : asm volatile ("pcmpgtb %xmm3,%xmm5"); - 150 56525200 : asm volatile ("paddb %xmm2,%xmm2"); - 151 56525200 : asm volatile ("paddb %xmm3,%xmm3"); - 152 56525200 : asm volatile ("pand %xmm7,%xmm4"); - 153 56525200 : asm volatile ("pand %xmm7,%xmm5"); - 154 56525200 : asm volatile ("pxor %xmm4,%xmm2"); - 155 56525200 : asm volatile ("pxor %xmm5,%xmm3"); + 140 10769166 : for (i = 0; i < size; i += 32) { + 141 10500440 : asm volatile ("movdqa %0,%%xmm0" : : "m" (v[l][i])); + 142 10500440 : asm volatile ("movdqa %0,%%xmm1" : : "m" (v[l][i + 16])); + 143 10500440 : asm volatile ("movdqa %xmm0,%xmm2"); + 144 10500440 : asm volatile ("movdqa %xmm1,%xmm3"); + 145 66820488 : for (d = l - 1; d >= 0; --d) { + 146 56320048 : asm volatile ("pxor %xmm4,%xmm4"); + 147 56320048 : asm volatile ("pxor %xmm5,%xmm5"); + 148 56320048 : asm volatile ("pcmpgtb %xmm2,%xmm4"); + 149 56320048 : asm volatile ("pcmpgtb %xmm3,%xmm5"); + 150 56320048 : asm volatile ("paddb %xmm2,%xmm2"); + 151 56320048 : asm volatile ("paddb %xmm3,%xmm3"); + 152 56320048 : asm volatile ("pand %xmm7,%xmm4"); + 153 56320048 : asm volatile ("pand %xmm7,%xmm5"); + 154 56320048 : asm volatile ("pxor %xmm4,%xmm2"); + 155 56320048 : asm volatile ("pxor %xmm5,%xmm3"); 156 : - 157 56525200 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[d][i])); - 158 56525200 : asm volatile ("movdqa %0,%%xmm5" : : "m" (v[d][i + 16])); - 159 56525200 : asm volatile ("pxor %xmm4,%xmm0"); - 160 56525200 : asm volatile ("pxor %xmm5,%xmm1"); - 161 56525200 : asm volatile ("pxor %xmm4,%xmm2"); - 162 56525200 : asm volatile ("pxor %xmm5,%xmm3"); + 157 56320048 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[d][i])); + 158 56320048 : asm volatile ("movdqa %0,%%xmm5" : : "m" (v[d][i + 16])); + 159 56320048 : asm volatile ("pxor %xmm4,%xmm0"); + 160 56320048 : asm volatile ("pxor %xmm5,%xmm1"); + 161 56320048 : asm volatile ("pxor %xmm4,%xmm2"); + 162 56320048 : asm volatile ("pxor %xmm5,%xmm3"); 163 : } - 164 10531640 : asm volatile ("movntdq %%xmm0,%0" : "=m" (p[i])); - 165 10531640 : asm volatile ("movntdq %%xmm1,%0" : "=m" (p[i + 16])); - 166 10531640 : asm volatile ("movntdq %%xmm2,%0" : "=m" (q[i])); - 167 10531640 : asm volatile ("movntdq %%xmm3,%0" : "=m" (q[i + 16])); + 164 10500440 : asm volatile ("movntdq %%xmm0,%0" : "=m" (p[i])); + 165 10500440 : asm volatile ("movntdq %%xmm1,%0" : "=m" (p[i + 16])); + 166 10500440 : asm volatile ("movntdq %%xmm2,%0" : "=m" (q[i])); + 167 10500440 : asm volatile ("movntdq %%xmm3,%0" : "=m" (q[i + 16])); 168 : } 169 : 170 : raid_sse_end(); - 171 268936 : } + 171 268726 : } 172 : #endif 173 : 174 : #if defined(CONFIG_X86) && defined(CONFIG_AVX2) @@ -370,93 +370,93 @@ 308 : /* 309 : * GEN3 (triple parity with Cauchy matrix) SSSE3 implementation 310 : */ - 311 29543 : void raid_gen3_ssse3(int nd, size_t size, void **vv) + 311 29542 : void raid_gen3_ssse3(int nd, size_t size, void **vv) 312 : { - 313 29543 : uint8_t **v = (uint8_t **)vv; + 313 29542 : uint8_t **v = (uint8_t **)vv; 314 : uint8_t *p; 315 : uint8_t *q; 316 : uint8_t *r; 317 : int d, l; 318 : size_t i; 319 : - 320 29543 : l = nd - 1; - 321 29543 : p = v[nd]; - 322 29543 : q = v[nd + 1]; - 323 29543 : r = v[nd + 2]; + 320 29542 : l = nd - 1; + 321 29542 : p = v[nd]; + 322 29542 : q = v[nd + 1]; + 323 29542 : r = v[nd + 2]; 324 : 325 : /* special case with only one data disk */ - 326 29543 : if (l == 0) { + 326 29542 : if (l == 0) { 327 4 : for (i = 0; i < 3; ++i) 328 3 : memcpy(v[1 + i], v[0], size); - 329 29544 : return; + 329 29543 : return; 330 : } 331 : 332 : raid_sse_begin(); 333 : 334 : /* generic case with at least two data disks */ - 335 29542 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfconst16.poly[0])); - 336 29542 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0])); + 335 29541 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfconst16.poly[0])); + 336 29541 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0])); 337 : - 338 4905206 : for (i = 0; i < size; i += 16) { + 338 4888821 : for (i = 0; i < size; i += 16) { 339 : /* last disk without the by two multiplication */ - 340 4875664 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[l][i])); + 340 4859280 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[l][i])); 341 : - 342 4875664 : asm volatile ("movdqa %xmm4,%xmm0"); - 343 4875664 : asm volatile ("movdqa %xmm4,%xmm1"); + 342 4859280 : asm volatile ("movdqa %xmm4,%xmm0"); + 343 4859280 : asm volatile ("movdqa %xmm4,%xmm1"); 344 : - 345 4875664 : asm volatile ("movdqa %xmm4,%xmm5"); - 346 4875664 : asm volatile ("psrlw $4,%xmm5"); - 347 4875664 : asm volatile ("pand %xmm7,%xmm4"); - 348 4875664 : asm volatile ("pand %xmm7,%xmm5"); + 345 4859280 : asm volatile ("movdqa %xmm4,%xmm5"); + 346 4859280 : asm volatile ("psrlw $4,%xmm5"); + 347 4859280 : asm volatile ("pand %xmm7,%xmm4"); + 348 4859280 : asm volatile ("pand %xmm7,%xmm5"); 349 : - 350 4875664 : asm volatile ("movdqa %0,%%xmm2" : : "m" (gfgenpshufb[l][0][0][0])); - 351 4875664 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[l][0][1][0])); - 352 4875664 : asm volatile ("pshufb %xmm4,%xmm2"); - 353 4875664 : asm volatile ("pshufb %xmm5,%xmm6"); - 354 4875664 : asm volatile ("pxor %xmm6,%xmm2"); + 350 4859280 : asm volatile ("movdqa %0,%%xmm2" : : "m" (gfgenpshufb[l][0][0][0])); + 351 4859280 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[l][0][1][0])); + 352 4859280 : asm volatile ("pshufb %xmm4,%xmm2"); + 353 4859280 : asm volatile ("pshufb %xmm5,%xmm6"); + 354 4859280 : asm volatile ("pxor %xmm6,%xmm2"); 355 : 356 : /* intermediate disks */ - 357 30604016 : for (d = l - 1; d > 0; --d) { - 358 25728352 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[d][i])); + 357 30489328 : for (d = l - 1; d > 0; --d) { + 358 25630048 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[d][i])); 359 : - 360 25728352 : asm volatile ("pxor %xmm5,%xmm5"); - 361 25728352 : asm volatile ("pcmpgtb %xmm1,%xmm5"); - 362 25728352 : asm volatile ("paddb %xmm1,%xmm1"); - 363 25728352 : asm volatile ("pand %xmm3,%xmm5"); - 364 25728352 : asm volatile ("pxor %xmm5,%xmm1"); + 360 25630048 : asm volatile ("pxor %xmm5,%xmm5"); + 361 25630048 : asm volatile ("pcmpgtb %xmm1,%xmm5"); + 362 25630048 : asm volatile ("paddb %xmm1,%xmm1"); + 363 25630048 : asm volatile ("pand %xmm3,%xmm5"); + 364 25630048 : asm volatile ("pxor %xmm5,%xmm1"); 365 : - 366 25728352 : asm volatile ("pxor %xmm4,%xmm0"); - 367 25728352 : asm volatile ("pxor %xmm4,%xmm1"); + 366 25630048 : asm volatile ("pxor %xmm4,%xmm0"); + 367 25630048 : asm volatile ("pxor %xmm4,%xmm1"); 368 : - 369 25728352 : asm volatile ("movdqa %xmm4,%xmm5"); - 370 25728352 : asm volatile ("psrlw $4,%xmm5"); - 371 25728352 : asm volatile ("pand %xmm7,%xmm4"); - 372 25728352 : asm volatile ("pand %xmm7,%xmm5"); + 369 25630048 : asm volatile ("movdqa %xmm4,%xmm5"); + 370 25630048 : asm volatile ("psrlw $4,%xmm5"); + 371 25630048 : asm volatile ("pand %xmm7,%xmm4"); + 372 25630048 : asm volatile ("pand %xmm7,%xmm5"); 373 : - 374 25728352 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][0][0][0])); - 375 25728352 : asm volatile ("pshufb %xmm4,%xmm6"); - 376 25728352 : asm volatile ("pxor %xmm6,%xmm2"); - 377 25728352 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][0][1][0])); - 378 25728352 : asm volatile ("pshufb %xmm5,%xmm6"); - 379 25728352 : asm volatile ("pxor %xmm6,%xmm2"); + 374 25630048 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][0][0][0])); + 375 25630048 : asm volatile ("pshufb %xmm4,%xmm6"); + 376 25630048 : asm volatile ("pxor %xmm6,%xmm2"); + 377 25630048 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][0][1][0])); + 378 25630048 : asm volatile ("pshufb %xmm5,%xmm6"); + 379 25630048 : asm volatile ("pxor %xmm6,%xmm2"); 380 : } 381 : 382 : /* first disk with all coefficients at 1 */ - 383 4875664 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[0][i])); + 383 4859280 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[0][i])); 384 : - 385 4875664 : asm volatile ("pxor %xmm5,%xmm5"); - 386 4875664 : asm volatile ("pcmpgtb %xmm1,%xmm5"); - 387 4875664 : asm volatile ("paddb %xmm1,%xmm1"); - 388 4875664 : asm volatile ("pand %xmm3,%xmm5"); - 389 4875664 : asm volatile ("pxor %xmm5,%xmm1"); + 385 4859280 : asm volatile ("pxor %xmm5,%xmm5"); + 386 4859280 : asm volatile ("pcmpgtb %xmm1,%xmm5"); + 387 4859280 : asm volatile ("paddb %xmm1,%xmm1"); + 388 4859280 : asm volatile ("pand %xmm3,%xmm5"); + 389 4859280 : asm volatile ("pxor %xmm5,%xmm1"); 390 : - 391 4875664 : asm volatile ("pxor %xmm4,%xmm0"); - 392 4875664 : asm volatile ("pxor %xmm4,%xmm1"); - 393 4875664 : asm volatile ("pxor %xmm4,%xmm2"); + 391 4859280 : asm volatile ("pxor %xmm4,%xmm0"); + 392 4859280 : asm volatile ("pxor %xmm4,%xmm1"); + 393 4859280 : asm volatile ("pxor %xmm4,%xmm2"); 394 : - 395 4875664 : asm volatile ("movntdq %%xmm0,%0" : "=m" (p[i])); - 396 4875664 : asm volatile ("movntdq %%xmm1,%0" : "=m" (q[i])); - 397 4875664 : asm volatile ("movntdq %%xmm2,%0" : "=m" (r[i])); + 395 4859280 : asm volatile ("movntdq %%xmm0,%0" : "=m" (p[i])); + 396 4859280 : asm volatile ("movntdq %%xmm1,%0" : "=m" (q[i])); + 397 4859280 : asm volatile ("movntdq %%xmm2,%0" : "=m" (r[i])); 398 : } 399 : 400 : raid_sse_end(); @@ -741,9 +741,9 @@ 679 : /* 680 : * GEN4 (quad parity with Cauchy matrix) SSSE3 implementation 681 : */ - 682 32471 : void raid_gen4_ssse3(int nd, size_t size, void **vv) + 682 32470 : void raid_gen4_ssse3(int nd, size_t size, void **vv) 683 : { - 684 32471 : uint8_t **v = (uint8_t **)vv; + 684 32470 : uint8_t **v = (uint8_t **)vv; 685 : uint8_t *p; 686 : uint8_t *q; 687 : uint8_t *r; @@ -751,102 +751,102 @@ 689 : int d, l; 690 : size_t i; 691 : - 692 32471 : l = nd - 1; - 693 32471 : p = v[nd]; - 694 32471 : q = v[nd + 1]; - 695 32471 : r = v[nd + 2]; - 696 32471 : s = v[nd + 3]; + 692 32470 : l = nd - 1; + 693 32470 : p = v[nd]; + 694 32470 : q = v[nd + 1]; + 695 32470 : r = v[nd + 2]; + 696 32470 : s = v[nd + 3]; 697 : 698 : /* special case with only one data disk */ - 699 32471 : if (l == 0) { + 699 32470 : if (l == 0) { 700 5 : for (i = 0; i < 4; ++i) 701 4 : memcpy(v[1 + i], v[0], size); - 702 32472 : return; + 702 32471 : return; 703 : } 704 : 705 : raid_sse_begin(); 706 : 707 : /* generic case with at least two data disks */ - 708 3367574 : for (i = 0; i < size; i += 16) { + 708 3351189 : for (i = 0; i < size; i += 16) { 709 : /* last disk without the by two multiplication */ - 710 3335104 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0])); - 711 3335104 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[l][i])); + 710 3318720 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0])); + 711 3318720 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[l][i])); 712 : - 713 3335104 : asm volatile ("movdqa %xmm4,%xmm0"); - 714 3335104 : asm volatile ("movdqa %xmm4,%xmm1"); + 713 3318720 : asm volatile ("movdqa %xmm4,%xmm0"); + 714 3318720 : asm volatile ("movdqa %xmm4,%xmm1"); 715 : - 716 3335104 : asm volatile ("movdqa %xmm4,%xmm5"); - 717 3335104 : asm volatile ("psrlw $4,%xmm5"); - 718 3335104 : asm volatile ("pand %xmm7,%xmm4"); - 719 3335104 : asm volatile ("pand %xmm7,%xmm5"); + 716 3318720 : asm volatile ("movdqa %xmm4,%xmm5"); + 717 3318720 : asm volatile ("psrlw $4,%xmm5"); + 718 3318720 : asm volatile ("pand %xmm7,%xmm4"); + 719 3318720 : asm volatile ("pand %xmm7,%xmm5"); 720 : - 721 3335104 : asm volatile ("movdqa %0,%%xmm2" : : "m" (gfgenpshufb[l][0][0][0])); - 722 3335104 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][0][1][0])); - 723 3335104 : asm volatile ("pshufb %xmm4,%xmm2"); - 724 3335104 : asm volatile ("pshufb %xmm5,%xmm7"); - 725 3335104 : asm volatile ("pxor %xmm7,%xmm2"); + 721 3318720 : asm volatile ("movdqa %0,%%xmm2" : : "m" (gfgenpshufb[l][0][0][0])); + 722 3318720 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][0][1][0])); + 723 3318720 : asm volatile ("pshufb %xmm4,%xmm2"); + 724 3318720 : asm volatile ("pshufb %xmm5,%xmm7"); + 725 3318720 : asm volatile ("pxor %xmm7,%xmm2"); 726 : - 727 3335104 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfgenpshufb[l][1][0][0])); - 728 3335104 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][1][1][0])); - 729 3335104 : asm volatile ("pshufb %xmm4,%xmm3"); - 730 3335104 : asm volatile ("pshufb %xmm5,%xmm7"); - 731 3335104 : asm volatile ("pxor %xmm7,%xmm3"); + 727 3318720 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfgenpshufb[l][1][0][0])); + 728 3318720 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][1][1][0])); + 729 3318720 : asm volatile ("pshufb %xmm4,%xmm3"); + 730 3318720 : asm volatile ("pshufb %xmm5,%xmm7"); + 731 3318720 : asm volatile ("pxor %xmm7,%xmm3"); 732 : 733 : /* intermediate disks */ - 734 20000768 : for (d = l - 1; d > 0; --d) { - 735 16665664 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.poly[0])); - 736 16665664 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[d][i])); + 734 19886080 : for (d = l - 1; d > 0; --d) { + 735 16567360 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.poly[0])); + 736 16567360 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[d][i])); 737 : - 738 16665664 : asm volatile ("pxor %xmm5,%xmm5"); - 739 16665664 : asm volatile ("pcmpgtb %xmm1,%xmm5"); - 740 16665664 : asm volatile ("paddb %xmm1,%xmm1"); - 741 16665664 : asm volatile ("pand %xmm7,%xmm5"); - 742 16665664 : asm volatile ("pxor %xmm5,%xmm1"); + 738 16567360 : asm volatile ("pxor %xmm5,%xmm5"); + 739 16567360 : asm volatile ("pcmpgtb %xmm1,%xmm5"); + 740 16567360 : asm volatile ("paddb %xmm1,%xmm1"); + 741 16567360 : asm volatile ("pand %xmm7,%xmm5"); + 742 16567360 : asm volatile ("pxor %xmm5,%xmm1"); 743 : - 744 16665664 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0])); + 744 16567360 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0])); 745 : - 746 16665664 : asm volatile ("pxor %xmm4,%xmm0"); - 747 16665664 : asm volatile ("pxor %xmm4,%xmm1"); + 746 16567360 : asm volatile ("pxor %xmm4,%xmm0"); + 747 16567360 : asm volatile ("pxor %xmm4,%xmm1"); 748 : - 749 16665664 : asm volatile ("movdqa %xmm4,%xmm5"); - 750 16665664 : asm volatile ("psrlw $4,%xmm5"); - 751 16665664 : asm volatile ("pand %xmm7,%xmm4"); - 752 16665664 : asm volatile ("pand %xmm7,%xmm5"); + 749 16567360 : asm volatile ("movdqa %xmm4,%xmm5"); + 750 16567360 : asm volatile ("psrlw $4,%xmm5"); + 751 16567360 : asm volatile ("pand %xmm7,%xmm4"); + 752 16567360 : asm volatile ("pand %xmm7,%xmm5"); 753 : - 754 16665664 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][0][0][0])); - 755 16665664 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][0][1][0])); - 756 16665664 : asm volatile ("pshufb %xmm4,%xmm6"); - 757 16665664 : asm volatile ("pshufb %xmm5,%xmm7"); - 758 16665664 : asm volatile ("pxor %xmm6,%xmm2"); - 759 16665664 : asm volatile ("pxor %xmm7,%xmm2"); + 754 16567360 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][0][0][0])); + 755 16567360 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][0][1][0])); + 756 16567360 : asm volatile ("pshufb %xmm4,%xmm6"); + 757 16567360 : asm volatile ("pshufb %xmm5,%xmm7"); + 758 16567360 : asm volatile ("pxor %xmm6,%xmm2"); + 759 16567360 : asm volatile ("pxor %xmm7,%xmm2"); 760 : - 761 16665664 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][1][0][0])); - 762 16665664 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][1][1][0])); - 763 16665664 : asm volatile ("pshufb %xmm4,%xmm6"); - 764 16665664 : asm volatile ("pshufb %xmm5,%xmm7"); - 765 16665664 : asm volatile ("pxor %xmm6,%xmm3"); - 766 16665664 : asm volatile ("pxor %xmm7,%xmm3"); + 761 16567360 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][1][0][0])); + 762 16567360 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][1][1][0])); + 763 16567360 : asm volatile ("pshufb %xmm4,%xmm6"); + 764 16567360 : asm volatile ("pshufb %xmm5,%xmm7"); + 765 16567360 : asm volatile ("pxor %xmm6,%xmm3"); + 766 16567360 : asm volatile ("pxor %xmm7,%xmm3"); 767 : } 768 : 769 : /* first disk with all coefficients at 1 */ - 770 3335104 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.poly[0])); - 771 3335104 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[0][i])); + 770 3318720 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.poly[0])); + 771 3318720 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[0][i])); 772 : - 773 3335104 : asm volatile ("pxor %xmm5,%xmm5"); - 774 3335104 : asm volatile ("pcmpgtb %xmm1,%xmm5"); - 775 3335104 : asm volatile ("paddb %xmm1,%xmm1"); - 776 3335104 : asm volatile ("pand %xmm7,%xmm5"); - 777 3335104 : asm volatile ("pxor %xmm5,%xmm1"); + 773 3318720 : asm volatile ("pxor %xmm5,%xmm5"); + 774 3318720 : asm volatile ("pcmpgtb %xmm1,%xmm5"); + 775 3318720 : asm volatile ("paddb %xmm1,%xmm1"); + 776 3318720 : asm volatile ("pand %xmm7,%xmm5"); + 777 3318720 : asm volatile ("pxor %xmm5,%xmm1"); 778 : - 779 3335104 : asm volatile ("pxor %xmm4,%xmm0"); - 780 3335104 : asm volatile ("pxor %xmm4,%xmm1"); - 781 3335104 : asm volatile ("pxor %xmm4,%xmm2"); - 782 3335104 : asm volatile ("pxor %xmm4,%xmm3"); + 779 3318720 : asm volatile ("pxor %xmm4,%xmm0"); + 780 3318720 : asm volatile ("pxor %xmm4,%xmm1"); + 781 3318720 : asm volatile ("pxor %xmm4,%xmm2"); + 782 3318720 : asm volatile ("pxor %xmm4,%xmm3"); 783 : - 784 3335104 : asm volatile ("movntdq %%xmm0,%0" : "=m" (p[i])); - 785 3335104 : asm volatile ("movntdq %%xmm1,%0" : "=m" (q[i])); - 786 3335104 : asm volatile ("movntdq %%xmm2,%0" : "=m" (r[i])); - 787 3335104 : asm volatile ("movntdq %%xmm3,%0" : "=m" (s[i])); + 784 3318720 : asm volatile ("movntdq %%xmm0,%0" : "=m" (p[i])); + 785 3318720 : asm volatile ("movntdq %%xmm1,%0" : "=m" (q[i])); + 786 3318720 : asm volatile ("movntdq %%xmm2,%0" : "=m" (r[i])); + 787 3318720 : asm volatile ("movntdq %%xmm3,%0" : "=m" (s[i])); 788 : } 789 : 790 : raid_sse_end(); @@ -1191,9 +1191,9 @@ 1129 : /* 1130 : * GEN5 (penta parity with Cauchy matrix) SSSE3 implementation 1131 : */ - 1132 50654 : void raid_gen5_ssse3(int nd, size_t size, void **vv) + 1132 50653 : void raid_gen5_ssse3(int nd, size_t size, void **vv) 1133 : { - 1134 50654 : uint8_t **v = (uint8_t **)vv; + 1134 50653 : uint8_t **v = (uint8_t **)vv; 1135 : uint8_t *p; 1136 : uint8_t *q; 1137 : uint8_t *r; @@ -1202,122 +1202,122 @@ 1140 : int d, l; 1141 : size_t i; 1142 : uint8_t buffer[16+16]; - 1143 50654 : uint8_t *pd = __align_ptr(buffer, 16); + 1143 50653 : uint8_t *pd = __align_ptr(buffer, 16); 1144 : - 1145 50654 : l = nd - 1; - 1146 50654 : p = v[nd]; - 1147 50654 : q = v[nd + 1]; - 1148 50654 : r = v[nd + 2]; - 1149 50654 : s = v[nd + 3]; - 1150 50654 : t = v[nd + 4]; + 1145 50653 : l = nd - 1; + 1146 50653 : p = v[nd]; + 1147 50653 : q = v[nd + 1]; + 1148 50653 : r = v[nd + 2]; + 1149 50653 : s = v[nd + 3]; + 1150 50653 : t = v[nd + 4]; 1151 : 1152 : /* special case with only one data disk */ - 1153 50654 : if (l == 0) { + 1153 50653 : if (l == 0) { 1154 6 : for (i = 0; i < 5; ++i) 1155 5 : memcpy(v[1 + i], v[0], size); - 1156 50655 : return; + 1156 50654 : return; 1157 : } 1158 : 1159 : raid_sse_begin(); 1160 : 1161 : /* generic case with at least two data disks */ - 1162 3937517 : for (i = 0; i < size; i += 16) { + 1162 3921132 : for (i = 0; i < size; i += 16) { 1163 : /* last disk without the by two multiplication */ - 1164 3886864 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[l][i])); + 1164 3870480 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[l][i])); 1165 : - 1166 3886864 : asm volatile ("movdqa %xmm4,%xmm0"); - 1167 3886864 : asm volatile ("movdqa %%xmm4,%0" : "=m" (pd[0])); + 1166 3870480 : asm volatile ("movdqa %xmm4,%xmm0"); + 1167 3870480 : asm volatile ("movdqa %%xmm4,%0" : "=m" (pd[0])); 1168 : - 1169 3886864 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0])); - 1170 3886864 : asm volatile ("movdqa %xmm4,%xmm5"); - 1171 3886864 : asm volatile ("psrlw $4,%xmm5"); - 1172 3886864 : asm volatile ("pand %xmm7,%xmm4"); - 1173 3886864 : asm volatile ("pand %xmm7,%xmm5"); + 1169 3870480 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0])); + 1170 3870480 : asm volatile ("movdqa %xmm4,%xmm5"); + 1171 3870480 : asm volatile ("psrlw $4,%xmm5"); + 1172 3870480 : asm volatile ("pand %xmm7,%xmm4"); + 1173 3870480 : asm volatile ("pand %xmm7,%xmm5"); 1174 : - 1175 3886864 : asm volatile ("movdqa %0,%%xmm1" : : "m" (gfgenpshufb[l][0][0][0])); - 1176 3886864 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][0][1][0])); - 1177 3886864 : asm volatile ("pshufb %xmm4,%xmm1"); - 1178 3886864 : asm volatile ("pshufb %xmm5,%xmm7"); - 1179 3886864 : asm volatile ("pxor %xmm7,%xmm1"); + 1175 3870480 : asm volatile ("movdqa %0,%%xmm1" : : "m" (gfgenpshufb[l][0][0][0])); + 1176 3870480 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][0][1][0])); + 1177 3870480 : asm volatile ("pshufb %xmm4,%xmm1"); + 1178 3870480 : asm volatile ("pshufb %xmm5,%xmm7"); + 1179 3870480 : asm volatile ("pxor %xmm7,%xmm1"); 1180 : - 1181 3886864 : asm volatile ("movdqa %0,%%xmm2" : : "m" (gfgenpshufb[l][1][0][0])); - 1182 3886864 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][1][1][0])); - 1183 3886864 : asm volatile ("pshufb %xmm4,%xmm2"); - 1184 3886864 : asm volatile ("pshufb %xmm5,%xmm7"); - 1185 3886864 : asm volatile ("pxor %xmm7,%xmm2"); + 1181 3870480 : asm volatile ("movdqa %0,%%xmm2" : : "m" (gfgenpshufb[l][1][0][0])); + 1182 3870480 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][1][1][0])); + 1183 3870480 : asm volatile ("pshufb %xmm4,%xmm2"); + 1184 3870480 : asm volatile ("pshufb %xmm5,%xmm7"); + 1185 3870480 : asm volatile ("pxor %xmm7,%xmm2"); 1186 : - 1187 3886864 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfgenpshufb[l][2][0][0])); - 1188 3886864 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][2][1][0])); - 1189 3886864 : asm volatile ("pshufb %xmm4,%xmm3"); - 1190 3886864 : asm volatile ("pshufb %xmm5,%xmm7"); - 1191 3886864 : asm volatile ("pxor %xmm7,%xmm3"); + 1187 3870480 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfgenpshufb[l][2][0][0])); + 1188 3870480 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][2][1][0])); + 1189 3870480 : asm volatile ("pshufb %xmm4,%xmm3"); + 1190 3870480 : asm volatile ("pshufb %xmm5,%xmm7"); + 1191 3870480 : asm volatile ("pxor %xmm7,%xmm3"); 1192 : 1193 : /* intermediate disks */ - 1194 23263984 : for (d = l - 1; d > 0; --d) { - 1195 19377120 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[d][i])); - 1196 19377120 : asm volatile ("movdqa %0,%%xmm6" : : "m" (pd[0])); - 1197 19377120 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.poly[0])); + 1194 23149296 : for (d = l - 1; d > 0; --d) { + 1195 19278816 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[d][i])); + 1196 19278816 : asm volatile ("movdqa %0,%%xmm6" : : "m" (pd[0])); + 1197 19278816 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.poly[0])); 1198 : - 1199 19377120 : asm volatile ("pxor %xmm5,%xmm5"); - 1200 19377120 : asm volatile ("pcmpgtb %xmm0,%xmm5"); - 1201 19377120 : asm volatile ("paddb %xmm0,%xmm0"); - 1202 19377120 : asm volatile ("pand %xmm7,%xmm5"); - 1203 19377120 : asm volatile ("pxor %xmm5,%xmm0"); + 1199 19278816 : asm volatile ("pxor %xmm5,%xmm5"); + 1200 19278816 : asm volatile ("pcmpgtb %xmm0,%xmm5"); + 1201 19278816 : asm volatile ("paddb %xmm0,%xmm0"); + 1202 19278816 : asm volatile ("pand %xmm7,%xmm5"); + 1203 19278816 : asm volatile ("pxor %xmm5,%xmm0"); 1204 : - 1205 19377120 : asm volatile ("pxor %xmm4,%xmm0"); - 1206 19377120 : asm volatile ("pxor %xmm4,%xmm6"); - 1207 19377120 : asm volatile ("movdqa %%xmm6,%0" : "=m" (pd[0])); + 1205 19278816 : asm volatile ("pxor %xmm4,%xmm0"); + 1206 19278816 : asm volatile ("pxor %xmm4,%xmm6"); + 1207 19278816 : asm volatile ("movdqa %%xmm6,%0" : "=m" (pd[0])); 1208 : - 1209 19377120 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0])); - 1210 19377120 : asm volatile ("movdqa %xmm4,%xmm5"); - 1211 19377120 : asm volatile ("psrlw $4,%xmm5"); - 1212 19377120 : asm volatile ("pand %xmm7,%xmm4"); - 1213 19377120 : asm volatile ("pand %xmm7,%xmm5"); + 1209 19278816 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0])); + 1210 19278816 : asm volatile ("movdqa %xmm4,%xmm5"); + 1211 19278816 : asm volatile ("psrlw $4,%xmm5"); + 1212 19278816 : asm volatile ("pand %xmm7,%xmm4"); + 1213 19278816 : asm volatile ("pand %xmm7,%xmm5"); 1214 : - 1215 19377120 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][0][0][0])); - 1216 19377120 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][0][1][0])); - 1217 19377120 : asm volatile ("pshufb %xmm4,%xmm6"); - 1218 19377120 : asm volatile ("pshufb %xmm5,%xmm7"); - 1219 19377120 : asm volatile ("pxor %xmm6,%xmm1"); - 1220 19377120 : asm volatile ("pxor %xmm7,%xmm1"); + 1215 19278816 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][0][0][0])); + 1216 19278816 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][0][1][0])); + 1217 19278816 : asm volatile ("pshufb %xmm4,%xmm6"); + 1218 19278816 : asm volatile ("pshufb %xmm5,%xmm7"); + 1219 19278816 : asm volatile ("pxor %xmm6,%xmm1"); + 1220 19278816 : asm volatile ("pxor %xmm7,%xmm1"); 1221 : - 1222 19377120 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][1][0][0])); - 1223 19377120 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][1][1][0])); - 1224 19377120 : asm volatile ("pshufb %xmm4,%xmm6"); - 1225 19377120 : asm volatile ("pshufb %xmm5,%xmm7"); - 1226 19377120 : asm volatile ("pxor %xmm6,%xmm2"); - 1227 19377120 : asm volatile ("pxor %xmm7,%xmm2"); + 1222 19278816 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][1][0][0])); + 1223 19278816 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][1][1][0])); + 1224 19278816 : asm volatile ("pshufb %xmm4,%xmm6"); + 1225 19278816 : asm volatile ("pshufb %xmm5,%xmm7"); + 1226 19278816 : asm volatile ("pxor %xmm6,%xmm2"); + 1227 19278816 : asm volatile ("pxor %xmm7,%xmm2"); 1228 : - 1229 19377120 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][2][0][0])); - 1230 19377120 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][2][1][0])); - 1231 19377120 : asm volatile ("pshufb %xmm4,%xmm6"); - 1232 19377120 : asm volatile ("pshufb %xmm5,%xmm7"); - 1233 19377120 : asm volatile ("pxor %xmm6,%xmm3"); - 1234 19377120 : asm volatile ("pxor %xmm7,%xmm3"); + 1229 19278816 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][2][0][0])); + 1230 19278816 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][2][1][0])); + 1231 19278816 : asm volatile ("pshufb %xmm4,%xmm6"); + 1232 19278816 : asm volatile ("pshufb %xmm5,%xmm7"); + 1233 19278816 : asm volatile ("pxor %xmm6,%xmm3"); + 1234 19278816 : asm volatile ("pxor %xmm7,%xmm3"); 1235 : } 1236 : 1237 : /* first disk with all coefficients at 1 */ - 1238 3886864 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[0][i])); - 1239 3886864 : asm volatile ("movdqa %0,%%xmm6" : : "m" (pd[0])); - 1240 3886864 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.poly[0])); + 1238 3870480 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[0][i])); + 1239 3870480 : asm volatile ("movdqa %0,%%xmm6" : : "m" (pd[0])); + 1240 3870480 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.poly[0])); 1241 : - 1242 3886864 : asm volatile ("pxor %xmm5,%xmm5"); - 1243 3886864 : asm volatile ("pcmpgtb %xmm0,%xmm5"); - 1244 3886864 : asm volatile ("paddb %xmm0,%xmm0"); - 1245 3886864 : asm volatile ("pand %xmm7,%xmm5"); - 1246 3886864 : asm volatile ("pxor %xmm5,%xmm0"); + 1242 3870480 : asm volatile ("pxor %xmm5,%xmm5"); + 1243 3870480 : asm volatile ("pcmpgtb %xmm0,%xmm5"); + 1244 3870480 : asm volatile ("paddb %xmm0,%xmm0"); + 1245 3870480 : asm volatile ("pand %xmm7,%xmm5"); + 1246 3870480 : asm volatile ("pxor %xmm5,%xmm0"); 1247 : - 1248 3886864 : asm volatile ("pxor %xmm4,%xmm0"); - 1249 3886864 : asm volatile ("pxor %xmm4,%xmm1"); - 1250 3886864 : asm volatile ("pxor %xmm4,%xmm2"); - 1251 3886864 : asm volatile ("pxor %xmm4,%xmm3"); - 1252 3886864 : asm volatile ("pxor %xmm4,%xmm6"); + 1248 3870480 : asm volatile ("pxor %xmm4,%xmm0"); + 1249 3870480 : asm volatile ("pxor %xmm4,%xmm1"); + 1250 3870480 : asm volatile ("pxor %xmm4,%xmm2"); + 1251 3870480 : asm volatile ("pxor %xmm4,%xmm3"); + 1252 3870480 : asm volatile ("pxor %xmm4,%xmm6"); 1253 : - 1254 3886864 : asm volatile ("movntdq %%xmm6,%0" : "=m" (p[i])); - 1255 3886864 : asm volatile ("movntdq %%xmm0,%0" : "=m" (q[i])); - 1256 3886864 : asm volatile ("movntdq %%xmm1,%0" : "=m" (r[i])); - 1257 3886864 : asm volatile ("movntdq %%xmm2,%0" : "=m" (s[i])); - 1258 3886864 : asm volatile ("movntdq %%xmm3,%0" : "=m" (t[i])); + 1254 3870480 : asm volatile ("movntdq %%xmm6,%0" : "=m" (p[i])); + 1255 3870480 : asm volatile ("movntdq %%xmm0,%0" : "=m" (q[i])); + 1256 3870480 : asm volatile ("movntdq %%xmm1,%0" : "=m" (r[i])); + 1257 3870480 : asm volatile ("movntdq %%xmm2,%0" : "=m" (s[i])); + 1258 3870480 : asm volatile ("movntdq %%xmm3,%0" : "=m" (t[i])); 1259 : } 1260 : 1261 : raid_sse_end(); @@ -1591,9 +1591,9 @@ 1529 : /* 1530 : * GEN6 (hexa parity with Cauchy matrix) SSSE3 implementation 1531 : */ - 1532 564140 : void raid_gen6_ssse3(int nd, size_t size, void **vv) + 1532 564213 : void raid_gen6_ssse3(int nd, size_t size, void **vv) 1533 : { - 1534 564140 : uint8_t **v = (uint8_t **)vv; + 1534 564213 : uint8_t **v = (uint8_t **)vv; 1535 : uint8_t *p; 1536 : uint8_t *q; 1537 : uint8_t *r; @@ -1603,142 +1603,142 @@ 1541 : int d, l; 1542 : size_t i; 1543 : uint8_t buffer[2*16+16]; - 1544 564140 : uint8_t *pd = __align_ptr(buffer, 16); + 1544 564213 : uint8_t *pd = __align_ptr(buffer, 16); 1545 : - 1546 564140 : l = nd - 1; - 1547 564140 : p = v[nd]; - 1548 564140 : q = v[nd + 1]; - 1549 564140 : r = v[nd + 2]; - 1550 564140 : s = v[nd + 3]; - 1551 564140 : t = v[nd + 4]; - 1552 564140 : u = v[nd + 5]; + 1546 564213 : l = nd - 1; + 1547 564213 : p = v[nd]; + 1548 564213 : q = v[nd + 1]; + 1549 564213 : r = v[nd + 2]; + 1550 564213 : s = v[nd + 3]; + 1551 564213 : t = v[nd + 4]; + 1552 564213 : u = v[nd + 5]; 1553 : 1554 : /* special case with only one data disk */ - 1555 564140 : if (l == 0) { + 1555 564213 : if (l == 0) { 1556 7 : for (i = 0; i < 6; ++i) 1557 6 : memcpy(v[1 + i], v[0], size); - 1558 564141 : return; + 1558 564214 : return; 1559 : } 1560 : 1561 : raid_sse_begin(); 1562 : 1563 : /* generic case with at least two data disks */ - 1564 36095675 : for (i = 0; i < size; i += 16) { + 1564 36100420 : for (i = 0; i < size; i += 16) { 1565 : /* last disk without the by two multiplication */ - 1566 35531536 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[l][i])); + 1566 35536208 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[l][i])); 1567 : - 1568 35531536 : asm volatile ("movdqa %%xmm4,%0" : "=m" (pd[0])); - 1569 35531536 : asm volatile ("movdqa %%xmm4,%0" : "=m" (pd[16])); + 1568 35536208 : asm volatile ("movdqa %%xmm4,%0" : "=m" (pd[0])); + 1569 35536208 : asm volatile ("movdqa %%xmm4,%0" : "=m" (pd[16])); 1570 : - 1571 35531536 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0])); - 1572 35531536 : asm volatile ("movdqa %xmm4,%xmm5"); - 1573 35531536 : asm volatile ("psrlw $4,%xmm5"); - 1574 35531536 : asm volatile ("pand %xmm7,%xmm4"); - 1575 35531536 : asm volatile ("pand %xmm7,%xmm5"); + 1571 35536208 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0])); + 1572 35536208 : asm volatile ("movdqa %xmm4,%xmm5"); + 1573 35536208 : asm volatile ("psrlw $4,%xmm5"); + 1574 35536208 : asm volatile ("pand %xmm7,%xmm4"); + 1575 35536208 : asm volatile ("pand %xmm7,%xmm5"); 1576 : - 1577 35531536 : asm volatile ("movdqa %0,%%xmm0" : : "m" (gfgenpshufb[l][0][0][0])); - 1578 35531536 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][0][1][0])); - 1579 35531536 : asm volatile ("pshufb %xmm4,%xmm0"); - 1580 35531536 : asm volatile ("pshufb %xmm5,%xmm7"); - 1581 35531536 : asm volatile ("pxor %xmm7,%xmm0"); + 1577 35536208 : asm volatile ("movdqa %0,%%xmm0" : : "m" (gfgenpshufb[l][0][0][0])); + 1578 35536208 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][0][1][0])); + 1579 35536208 : asm volatile ("pshufb %xmm4,%xmm0"); + 1580 35536208 : asm volatile ("pshufb %xmm5,%xmm7"); + 1581 35536208 : asm volatile ("pxor %xmm7,%xmm0"); 1582 : - 1583 35531536 : asm volatile ("movdqa %0,%%xmm1" : : "m" (gfgenpshufb[l][1][0][0])); - 1584 35531536 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][1][1][0])); - 1585 35531536 : asm volatile ("pshufb %xmm4,%xmm1"); - 1586 35531536 : asm volatile ("pshufb %xmm5,%xmm7"); - 1587 35531536 : asm volatile ("pxor %xmm7,%xmm1"); + 1583 35536208 : asm volatile ("movdqa %0,%%xmm1" : : "m" (gfgenpshufb[l][1][0][0])); + 1584 35536208 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][1][1][0])); + 1585 35536208 : asm volatile ("pshufb %xmm4,%xmm1"); + 1586 35536208 : asm volatile ("pshufb %xmm5,%xmm7"); + 1587 35536208 : asm volatile ("pxor %xmm7,%xmm1"); 1588 : - 1589 35531536 : asm volatile ("movdqa %0,%%xmm2" : : "m" (gfgenpshufb[l][2][0][0])); - 1590 35531536 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][2][1][0])); - 1591 35531536 : asm volatile ("pshufb %xmm4,%xmm2"); - 1592 35531536 : asm volatile ("pshufb %xmm5,%xmm7"); - 1593 35531536 : asm volatile ("pxor %xmm7,%xmm2"); + 1589 35536208 : asm volatile ("movdqa %0,%%xmm2" : : "m" (gfgenpshufb[l][2][0][0])); + 1590 35536208 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][2][1][0])); + 1591 35536208 : asm volatile ("pshufb %xmm4,%xmm2"); + 1592 35536208 : asm volatile ("pshufb %xmm5,%xmm7"); + 1593 35536208 : asm volatile ("pxor %xmm7,%xmm2"); 1594 : - 1595 35531536 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfgenpshufb[l][3][0][0])); - 1596 35531536 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][3][1][0])); - 1597 35531536 : asm volatile ("pshufb %xmm4,%xmm3"); - 1598 35531536 : asm volatile ("pshufb %xmm5,%xmm7"); - 1599 35531536 : asm volatile ("pxor %xmm7,%xmm3"); + 1595 35536208 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfgenpshufb[l][3][0][0])); + 1596 35536208 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][3][1][0])); + 1597 35536208 : asm volatile ("pshufb %xmm4,%xmm3"); + 1598 35536208 : asm volatile ("pshufb %xmm5,%xmm7"); + 1599 35536208 : asm volatile ("pxor %xmm7,%xmm3"); 1600 : 1601 : /* intermediate disks */ - 1602 183662576 : for (d = l - 1; d > 0; --d) { - 1603 148131040 : asm volatile ("movdqa %0,%%xmm5" : : "m" (pd[0])); - 1604 148131040 : asm volatile ("movdqa %0,%%xmm6" : : "m" (pd[16])); - 1605 148131040 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.poly[0])); + 1602 183685936 : for (d = l - 1; d > 0; --d) { + 1603 148149728 : asm volatile ("movdqa %0,%%xmm5" : : "m" (pd[0])); + 1604 148149728 : asm volatile ("movdqa %0,%%xmm6" : : "m" (pd[16])); + 1605 148149728 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.poly[0])); 1606 : - 1607 148131040 : asm volatile ("pxor %xmm4,%xmm4"); - 1608 148131040 : asm volatile ("pcmpgtb %xmm6,%xmm4"); - 1609 148131040 : asm volatile ("paddb %xmm6,%xmm6"); - 1610 148131040 : asm volatile ("pand %xmm7,%xmm4"); - 1611 148131040 : asm volatile ("pxor %xmm4,%xmm6"); + 1607 148149728 : asm volatile ("pxor %xmm4,%xmm4"); + 1608 148149728 : asm volatile ("pcmpgtb %xmm6,%xmm4"); + 1609 148149728 : asm volatile ("paddb %xmm6,%xmm6"); + 1610 148149728 : asm volatile ("pand %xmm7,%xmm4"); + 1611 148149728 : asm volatile ("pxor %xmm4,%xmm6"); 1612 : - 1613 148131040 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[d][i])); + 1613 148149728 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[d][i])); 1614 : - 1615 148131040 : asm volatile ("pxor %xmm4,%xmm5"); - 1616 148131040 : asm volatile ("pxor %xmm4,%xmm6"); - 1617 148131040 : asm volatile ("movdqa %%xmm5,%0" : "=m" (pd[0])); - 1618 148131040 : asm volatile ("movdqa %%xmm6,%0" : "=m" (pd[16])); + 1615 148149728 : asm volatile ("pxor %xmm4,%xmm5"); + 1616 148149728 : asm volatile ("pxor %xmm4,%xmm6"); + 1617 148149728 : asm volatile ("movdqa %%xmm5,%0" : "=m" (pd[0])); + 1618 148149728 : asm volatile ("movdqa %%xmm6,%0" : "=m" (pd[16])); 1619 : - 1620 148131040 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0])); - 1621 148131040 : asm volatile ("movdqa %xmm4,%xmm5"); - 1622 148131040 : asm volatile ("psrlw $4,%xmm5"); - 1623 148131040 : asm volatile ("pand %xmm7,%xmm4"); - 1624 148131040 : asm volatile ("pand %xmm7,%xmm5"); + 1620 148149728 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0])); + 1621 148149728 : asm volatile ("movdqa %xmm4,%xmm5"); + 1622 148149728 : asm volatile ("psrlw $4,%xmm5"); + 1623 148149728 : asm volatile ("pand %xmm7,%xmm4"); + 1624 148149728 : asm volatile ("pand %xmm7,%xmm5"); 1625 : - 1626 148131040 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][0][0][0])); - 1627 148131040 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][0][1][0])); - 1628 148131040 : asm volatile ("pshufb %xmm4,%xmm6"); - 1629 148131040 : asm volatile ("pshufb %xmm5,%xmm7"); - 1630 148131040 : asm volatile ("pxor %xmm6,%xmm0"); - 1631 148131040 : asm volatile ("pxor %xmm7,%xmm0"); + 1626 148149728 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][0][0][0])); + 1627 148149728 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][0][1][0])); + 1628 148149728 : asm volatile ("pshufb %xmm4,%xmm6"); + 1629 148149728 : asm volatile ("pshufb %xmm5,%xmm7"); + 1630 148149728 : asm volatile ("pxor %xmm6,%xmm0"); + 1631 148149728 : asm volatile ("pxor %xmm7,%xmm0"); 1632 : - 1633 148131040 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][1][0][0])); - 1634 148131040 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][1][1][0])); - 1635 148131040 : asm volatile ("pshufb %xmm4,%xmm6"); - 1636 148131040 : asm volatile ("pshufb %xmm5,%xmm7"); - 1637 148131040 : asm volatile ("pxor %xmm6,%xmm1"); - 1638 148131040 : asm volatile ("pxor %xmm7,%xmm1"); + 1633 148149728 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][1][0][0])); + 1634 148149728 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][1][1][0])); + 1635 148149728 : asm volatile ("pshufb %xmm4,%xmm6"); + 1636 148149728 : asm volatile ("pshufb %xmm5,%xmm7"); + 1637 148149728 : asm volatile ("pxor %xmm6,%xmm1"); + 1638 148149728 : asm volatile ("pxor %xmm7,%xmm1"); 1639 : - 1640 148131040 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][2][0][0])); - 1641 148131040 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][2][1][0])); - 1642 148131040 : asm volatile ("pshufb %xmm4,%xmm6"); - 1643 148131040 : asm volatile ("pshufb %xmm5,%xmm7"); - 1644 148131040 : asm volatile ("pxor %xmm6,%xmm2"); - 1645 148131040 : asm volatile ("pxor %xmm7,%xmm2"); + 1640 148149728 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][2][0][0])); + 1641 148149728 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][2][1][0])); + 1642 148149728 : asm volatile ("pshufb %xmm4,%xmm6"); + 1643 148149728 : asm volatile ("pshufb %xmm5,%xmm7"); + 1644 148149728 : asm volatile ("pxor %xmm6,%xmm2"); + 1645 148149728 : asm volatile ("pxor %xmm7,%xmm2"); 1646 : - 1647 148131040 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][3][0][0])); - 1648 148131040 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][3][1][0])); - 1649 148131040 : asm volatile ("pshufb %xmm4,%xmm6"); - 1650 148131040 : asm volatile ("pshufb %xmm5,%xmm7"); - 1651 148131040 : asm volatile ("pxor %xmm6,%xmm3"); - 1652 148131040 : asm volatile ("pxor %xmm7,%xmm3"); + 1647 148149728 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][3][0][0])); + 1648 148149728 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][3][1][0])); + 1649 148149728 : asm volatile ("pshufb %xmm4,%xmm6"); + 1650 148149728 : asm volatile ("pshufb %xmm5,%xmm7"); + 1651 148149728 : asm volatile ("pxor %xmm6,%xmm3"); + 1652 148149728 : asm volatile ("pxor %xmm7,%xmm3"); 1653 : } 1654 : 1655 : /* first disk with all coefficients at 1 */ - 1656 35531536 : asm volatile ("movdqa %0,%%xmm5" : : "m" (pd[0])); - 1657 35531536 : asm volatile ("movdqa %0,%%xmm6" : : "m" (pd[16])); - 1658 35531536 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.poly[0])); + 1656 35536208 : asm volatile ("movdqa %0,%%xmm5" : : "m" (pd[0])); + 1657 35536208 : asm volatile ("movdqa %0,%%xmm6" : : "m" (pd[16])); + 1658 35536208 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.poly[0])); 1659 : - 1660 35531536 : asm volatile ("pxor %xmm4,%xmm4"); - 1661 35531536 : asm volatile ("pcmpgtb %xmm6,%xmm4"); - 1662 35531536 : asm volatile ("paddb %xmm6,%xmm6"); - 1663 35531536 : asm volatile ("pand %xmm7,%xmm4"); - 1664 35531536 : asm volatile ("pxor %xmm4,%xmm6"); + 1660 35536208 : asm volatile ("pxor %xmm4,%xmm4"); + 1661 35536208 : asm volatile ("pcmpgtb %xmm6,%xmm4"); + 1662 35536208 : asm volatile ("paddb %xmm6,%xmm6"); + 1663 35536208 : asm volatile ("pand %xmm7,%xmm4"); + 1664 35536208 : asm volatile ("pxor %xmm4,%xmm6"); 1665 : - 1666 35531536 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[0][i])); - 1667 35531536 : asm volatile ("pxor %xmm4,%xmm0"); - 1668 35531536 : asm volatile ("pxor %xmm4,%xmm1"); - 1669 35531536 : asm volatile ("pxor %xmm4,%xmm2"); - 1670 35531536 : asm volatile ("pxor %xmm4,%xmm3"); - 1671 35531536 : asm volatile ("pxor %xmm4,%xmm5"); - 1672 35531536 : asm volatile ("pxor %xmm4,%xmm6"); + 1666 35536208 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[0][i])); + 1667 35536208 : asm volatile ("pxor %xmm4,%xmm0"); + 1668 35536208 : asm volatile ("pxor %xmm4,%xmm1"); + 1669 35536208 : asm volatile ("pxor %xmm4,%xmm2"); + 1670 35536208 : asm volatile ("pxor %xmm4,%xmm3"); + 1671 35536208 : asm volatile ("pxor %xmm4,%xmm5"); + 1672 35536208 : asm volatile ("pxor %xmm4,%xmm6"); 1673 : - 1674 35531536 : asm volatile ("movntdq %%xmm5,%0" : "=m" (p[i])); - 1675 35531536 : asm volatile ("movntdq %%xmm6,%0" : "=m" (q[i])); - 1676 35531536 : asm volatile ("movntdq %%xmm0,%0" : "=m" (r[i])); - 1677 35531536 : asm volatile ("movntdq %%xmm1,%0" : "=m" (s[i])); - 1678 35531536 : asm volatile ("movntdq %%xmm2,%0" : "=m" (t[i])); - 1679 35531536 : asm volatile ("movntdq %%xmm3,%0" : "=m" (u[i])); + 1674 35536208 : asm volatile ("movntdq %%xmm5,%0" : "=m" (p[i])); + 1675 35536208 : asm volatile ("movntdq %%xmm6,%0" : "=m" (q[i])); + 1676 35536208 : asm volatile ("movntdq %%xmm0,%0" : "=m" (r[i])); + 1677 35536208 : asm volatile ("movntdq %%xmm1,%0" : "=m" (s[i])); + 1678 35536208 : asm volatile ("movntdq %%xmm2,%0" : "=m" (t[i])); + 1679 35536208 : asm volatile ("movntdq %%xmm3,%0" : "=m" (u[i])); 1680 : } 1681 : 1682 : raid_sse_end(); @@ -2046,9 +2046,9 @@ 1984 : /* 1985 : * RAID recovering for one disk SSSE3 implementation 1986 : */ - 1987 111201 : void raid_rec1_ssse3(int nr, int *id, int *ip, int nd, size_t size, void **vv) + 1987 111621 : void raid_rec1_ssse3(int nr, int *id, int *ip, int nd, size_t size, void **vv) 1988 : { - 1989 111201 : uint8_t **v = (uint8_t **)vv; + 1989 111621 : uint8_t **v = (uint8_t **)vv; 1990 : uint8_t *p; 1991 : uint8_t *pa; 1992 : uint8_t G; @@ -2058,43 +2058,43 @@ 1996 : (void)nr; /* unused, it's always 1 */ 1997 : 1998 : /* if it's RAID5 uses the faster function */ - 1999 111201 : if (ip[0] == 0) { - 2000 101332 : raid_rec1of1(id, nd, size, vv); - 2001 212533 : return; + 1999 111621 : if (ip[0] == 0) { + 2000 101738 : raid_rec1of1(id, nd, size, vv); + 2001 213359 : return; 2002 : } 2003 : 2004 : /* setup the coefficients matrix */ - 2005 19738 : G = A(ip[0], id[0]); + 2005 19766 : G = A(ip[0], id[0]); 2006 : 2007 : /* invert it to solve the system of linear equations */ - 2008 19738 : V = inv(G); + 2008 19766 : V = inv(G); 2009 : 2010 : /* compute delta parity */ - 2011 9869 : raid_delta_gen(1, id, ip, nd, size, vv); + 2011 9883 : raid_delta_gen(1, id, ip, nd, size, vv); 2012 : - 2013 9869 : p = v[nd + ip[0]]; - 2014 9869 : pa = v[id[0]]; + 2013 9883 : p = v[nd + ip[0]]; + 2014 9883 : pa = v[id[0]]; 2015 : 2016 : raid_sse_begin(); 2017 : - 2018 9869 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0])); - 2019 9869 : asm volatile ("movdqa %0,%%xmm4" : : "m" (gfmulpshufb[V][0][0])); - 2020 9869 : asm volatile ("movdqa %0,%%xmm5" : : "m" (gfmulpshufb[V][1][0])); + 2018 9883 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0])); + 2019 9883 : asm volatile ("movdqa %0,%%xmm4" : : "m" (gfmulpshufb[V][0][0])); + 2020 9883 : asm volatile ("movdqa %0,%%xmm5" : : "m" (gfmulpshufb[V][1][0])); 2021 : - 2022 1551373 : for (i = 0; i < size; i += 16) { - 2023 1541504 : asm volatile ("movdqa %0,%%xmm0" : : "m" (p[i])); - 2024 1541504 : asm volatile ("movdqa %0,%%xmm1" : : "m" (pa[i])); - 2025 1541504 : asm volatile ("movdqa %xmm4,%xmm2"); - 2026 1541504 : asm volatile ("movdqa %xmm5,%xmm3"); - 2027 1541504 : asm volatile ("pxor %xmm0,%xmm1"); - 2028 1541504 : asm volatile ("movdqa %xmm1,%xmm0"); - 2029 1541504 : asm volatile ("psrlw $4,%xmm1"); - 2030 1541504 : asm volatile ("pand %xmm7,%xmm0"); - 2031 1541504 : asm volatile ("pand %xmm7,%xmm1"); - 2032 1541504 : asm volatile ("pshufb %xmm0,%xmm2"); - 2033 1541504 : asm volatile ("pshufb %xmm1,%xmm3"); - 2034 1541504 : asm volatile ("pxor %xmm3,%xmm2"); - 2035 1541504 : asm volatile ("movdqa %%xmm2,%0" : "=m" (pa[i])); + 2022 1552283 : for (i = 0; i < size; i += 16) { + 2023 1542400 : asm volatile ("movdqa %0,%%xmm0" : : "m" (p[i])); + 2024 1542400 : asm volatile ("movdqa %0,%%xmm1" : : "m" (pa[i])); + 2025 1542400 : asm volatile ("movdqa %xmm4,%xmm2"); + 2026 1542400 : asm volatile ("movdqa %xmm5,%xmm3"); + 2027 1542400 : asm volatile ("pxor %xmm0,%xmm1"); + 2028 1542400 : asm volatile ("movdqa %xmm1,%xmm0"); + 2029 1542400 : asm volatile ("psrlw $4,%xmm1"); + 2030 1542400 : asm volatile ("pand %xmm7,%xmm0"); + 2031 1542400 : asm volatile ("pand %xmm7,%xmm1"); + 2032 1542400 : asm volatile ("pshufb %xmm0,%xmm2"); + 2033 1542400 : asm volatile ("pshufb %xmm1,%xmm3"); + 2034 1542400 : asm volatile ("pxor %xmm3,%xmm2"); + 2035 1542400 : asm volatile ("movdqa %%xmm2,%0" : "=m" (pa[i])); 2036 : } 2037 : 2038 : raid_sse_end(); @@ -2105,106 +2105,106 @@ 2043 : /* 2044 : * RAID recovering for two disks SSSE3 implementation 2045 : */ - 2046 44277 : void raid_rec2_ssse3(int nr, int *id, int *ip, int nd, size_t size, void **vv) + 2046 44056 : void raid_rec2_ssse3(int nr, int *id, int *ip, int nd, size_t size, void **vv) 2047 : { - 2048 44277 : uint8_t **v = (uint8_t **)vv; - 2049 44277 : const int N = 2; - 2050 44277 : uint8_t *p[N]; - 2051 44277 : uint8_t *pa[N]; - 2052 44277 : uint8_t G[N * N]; - 2053 44277 : uint8_t V[N * N]; + 2048 44056 : uint8_t **v = (uint8_t **)vv; + 2049 44056 : const int N = 2; + 2050 44056 : uint8_t *p[N]; + 2051 44056 : uint8_t *pa[N]; + 2052 44056 : uint8_t G[N * N]; + 2053 44056 : uint8_t V[N * N]; 2054 : size_t i; 2055 : int j, k; 2056 : 2057 : (void)nr; /* unused, it's always 2 */ 2058 : 2059 : /* setup the coefficients matrix */ - 2060 132831 : for (j = 0; j < N; ++j) - 2061 265662 : for (k = 0; k < N; ++k) - 2062 354216 : G[j * N + k] = A(ip[j], id[k]); + 2060 132168 : for (j = 0; j < N; ++j) + 2061 264336 : for (k = 0; k < N; ++k) + 2062 352448 : G[j * N + k] = A(ip[j], id[k]); 2063 : 2064 : /* invert it to solve the system of linear equations */ - 2065 44277 : raid_invert(G, V, N); + 2065 44056 : raid_invert(G, V, N); 2066 : 2067 : /* compute delta parity */ - 2068 44277 : raid_delta_gen(N, id, ip, nd, size, vv); + 2068 44056 : raid_delta_gen(N, id, ip, nd, size, vv); 2069 : - 2070 132831 : for (j = 0; j < N; ++j) { - 2071 88554 : p[j] = v[nd + ip[j]]; - 2072 88554 : pa[j] = v[id[j]]; + 2070 132168 : for (j = 0; j < N; ++j) { + 2071 88112 : p[j] = v[nd + ip[j]]; + 2072 88112 : pa[j] = v[id[j]]; 2073 : } 2074 : 2075 : raid_sse_begin(); 2076 : - 2077 44277 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0])); + 2077 44056 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0])); 2078 : - 2079 3604341 : for (i = 0; i < size; i += 16) { - 2080 3560064 : asm volatile ("movdqa %0,%%xmm0" : : "m" (p[0][i])); - 2081 3560064 : asm volatile ("movdqa %0,%%xmm2" : : "m" (pa[0][i])); - 2082 3560064 : asm volatile ("movdqa %0,%%xmm1" : : "m" (p[1][i])); - 2083 3560064 : asm volatile ("movdqa %0,%%xmm3" : : "m" (pa[1][i])); - 2084 3560064 : asm volatile ("pxor %xmm2,%xmm0"); - 2085 3560064 : asm volatile ("pxor %xmm3,%xmm1"); + 2079 3589976 : for (i = 0; i < size; i += 16) { + 2080 3545920 : asm volatile ("movdqa %0,%%xmm0" : : "m" (p[0][i])); + 2081 3545920 : asm volatile ("movdqa %0,%%xmm2" : : "m" (pa[0][i])); + 2082 3545920 : asm volatile ("movdqa %0,%%xmm1" : : "m" (p[1][i])); + 2083 3545920 : asm volatile ("movdqa %0,%%xmm3" : : "m" (pa[1][i])); + 2084 3545920 : asm volatile ("pxor %xmm2,%xmm0"); + 2085 3545920 : asm volatile ("pxor %xmm3,%xmm1"); 2086 : - 2087 3560064 : asm volatile ("pxor %xmm6,%xmm6"); + 2087 3545920 : asm volatile ("pxor %xmm6,%xmm6"); 2088 : - 2089 3560064 : asm volatile ("movdqa %0,%%xmm2" : : "m" (gfmulpshufb[V[0]][0][0])); - 2090 3560064 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfmulpshufb[V[0]][1][0])); - 2091 3560064 : asm volatile ("movdqa %xmm0,%xmm4"); - 2092 3560064 : asm volatile ("movdqa %xmm0,%xmm5"); - 2093 3560064 : asm volatile ("psrlw $4,%xmm5"); - 2094 3560064 : asm volatile ("pand %xmm7,%xmm4"); - 2095 3560064 : asm volatile ("pand %xmm7,%xmm5"); - 2096 3560064 : asm volatile ("pshufb %xmm4,%xmm2"); - 2097 3560064 : asm volatile ("pshufb %xmm5,%xmm3"); - 2098 3560064 : asm volatile ("pxor %xmm2,%xmm6"); - 2099 3560064 : asm volatile ("pxor %xmm3,%xmm6"); + 2089 3545920 : asm volatile ("movdqa %0,%%xmm2" : : "m" (gfmulpshufb[V[0]][0][0])); + 2090 3545920 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfmulpshufb[V[0]][1][0])); + 2091 3545920 : asm volatile ("movdqa %xmm0,%xmm4"); + 2092 3545920 : asm volatile ("movdqa %xmm0,%xmm5"); + 2093 3545920 : asm volatile ("psrlw $4,%xmm5"); + 2094 3545920 : asm volatile ("pand %xmm7,%xmm4"); + 2095 3545920 : asm volatile ("pand %xmm7,%xmm5"); + 2096 3545920 : asm volatile ("pshufb %xmm4,%xmm2"); + 2097 3545920 : asm volatile ("pshufb %xmm5,%xmm3"); + 2098 3545920 : asm volatile ("pxor %xmm2,%xmm6"); + 2099 3545920 : asm volatile ("pxor %xmm3,%xmm6"); 2100 : - 2101 3560064 : asm volatile ("movdqa %0,%%xmm2" : : "m" (gfmulpshufb[V[1]][0][0])); - 2102 3560064 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfmulpshufb[V[1]][1][0])); - 2103 3560064 : asm volatile ("movdqa %xmm1,%xmm4"); - 2104 3560064 : asm volatile ("movdqa %xmm1,%xmm5"); - 2105 3560064 : asm volatile ("psrlw $4,%xmm5"); - 2106 3560064 : asm volatile ("pand %xmm7,%xmm4"); - 2107 3560064 : asm volatile ("pand %xmm7,%xmm5"); - 2108 3560064 : asm volatile ("pshufb %xmm4,%xmm2"); - 2109 3560064 : asm volatile ("pshufb %xmm5,%xmm3"); - 2110 3560064 : asm volatile ("pxor %xmm2,%xmm6"); - 2111 3560064 : asm volatile ("pxor %xmm3,%xmm6"); + 2101 3545920 : asm volatile ("movdqa %0,%%xmm2" : : "m" (gfmulpshufb[V[1]][0][0])); + 2102 3545920 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfmulpshufb[V[1]][1][0])); + 2103 3545920 : asm volatile ("movdqa %xmm1,%xmm4"); + 2104 3545920 : asm volatile ("movdqa %xmm1,%xmm5"); + 2105 3545920 : asm volatile ("psrlw $4,%xmm5"); + 2106 3545920 : asm volatile ("pand %xmm7,%xmm4"); + 2107 3545920 : asm volatile ("pand %xmm7,%xmm5"); + 2108 3545920 : asm volatile ("pshufb %xmm4,%xmm2"); + 2109 3545920 : asm volatile ("pshufb %xmm5,%xmm3"); + 2110 3545920 : asm volatile ("pxor %xmm2,%xmm6"); + 2111 3545920 : asm volatile ("pxor %xmm3,%xmm6"); 2112 : - 2113 3560064 : asm volatile ("movdqa %%xmm6,%0" : "=m" (pa[0][i])); + 2113 3545920 : asm volatile ("movdqa %%xmm6,%0" : "=m" (pa[0][i])); 2114 : - 2115 3560064 : asm volatile ("pxor %xmm6,%xmm6"); + 2115 3545920 : asm volatile ("pxor %xmm6,%xmm6"); 2116 : - 2117 3560064 : asm volatile ("movdqa %0,%%xmm2" : : "m" (gfmulpshufb[V[2]][0][0])); - 2118 3560064 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfmulpshufb[V[2]][1][0])); - 2119 3560064 : asm volatile ("movdqa %xmm0,%xmm4"); - 2120 3560064 : asm volatile ("movdqa %xmm0,%xmm5"); - 2121 3560064 : asm volatile ("psrlw $4,%xmm5"); - 2122 3560064 : asm volatile ("pand %xmm7,%xmm4"); - 2123 3560064 : asm volatile ("pand %xmm7,%xmm5"); - 2124 3560064 : asm volatile ("pshufb %xmm4,%xmm2"); - 2125 3560064 : asm volatile ("pshufb %xmm5,%xmm3"); - 2126 3560064 : asm volatile ("pxor %xmm2,%xmm6"); - 2127 3560064 : asm volatile ("pxor %xmm3,%xmm6"); + 2117 3545920 : asm volatile ("movdqa %0,%%xmm2" : : "m" (gfmulpshufb[V[2]][0][0])); + 2118 3545920 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfmulpshufb[V[2]][1][0])); + 2119 3545920 : asm volatile ("movdqa %xmm0,%xmm4"); + 2120 3545920 : asm volatile ("movdqa %xmm0,%xmm5"); + 2121 3545920 : asm volatile ("psrlw $4,%xmm5"); + 2122 3545920 : asm volatile ("pand %xmm7,%xmm4"); + 2123 3545920 : asm volatile ("pand %xmm7,%xmm5"); + 2124 3545920 : asm volatile ("pshufb %xmm4,%xmm2"); + 2125 3545920 : asm volatile ("pshufb %xmm5,%xmm3"); + 2126 3545920 : asm volatile ("pxor %xmm2,%xmm6"); + 2127 3545920 : asm volatile ("pxor %xmm3,%xmm6"); 2128 : - 2129 3560064 : asm volatile ("movdqa %0,%%xmm2" : : "m" (gfmulpshufb[V[3]][0][0])); - 2130 3560064 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfmulpshufb[V[3]][1][0])); - 2131 3560064 : asm volatile ("movdqa %xmm1,%xmm4"); - 2132 3560064 : asm volatile ("movdqa %xmm1,%xmm5"); - 2133 3560064 : asm volatile ("psrlw $4,%xmm5"); - 2134 3560064 : asm volatile ("pand %xmm7,%xmm4"); - 2135 3560064 : asm volatile ("pand %xmm7,%xmm5"); - 2136 3560064 : asm volatile ("pshufb %xmm4,%xmm2"); - 2137 3560064 : asm volatile ("pshufb %xmm5,%xmm3"); - 2138 3560064 : asm volatile ("pxor %xmm2,%xmm6"); - 2139 3560064 : asm volatile ("pxor %xmm3,%xmm6"); + 2129 3545920 : asm volatile ("movdqa %0,%%xmm2" : : "m" (gfmulpshufb[V[3]][0][0])); + 2130 3545920 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfmulpshufb[V[3]][1][0])); + 2131 3545920 : asm volatile ("movdqa %xmm1,%xmm4"); + 2132 3545920 : asm volatile ("movdqa %xmm1,%xmm5"); + 2133 3545920 : asm volatile ("psrlw $4,%xmm5"); + 2134 3545920 : asm volatile ("pand %xmm7,%xmm4"); + 2135 3545920 : asm volatile ("pand %xmm7,%xmm5"); + 2136 3545920 : asm volatile ("pshufb %xmm4,%xmm2"); + 2137 3545920 : asm volatile ("pshufb %xmm5,%xmm3"); + 2138 3545920 : asm volatile ("pxor %xmm2,%xmm6"); + 2139 3545920 : asm volatile ("pxor %xmm3,%xmm6"); 2140 : - 2141 3560064 : asm volatile ("movdqa %%xmm6,%0" : "=m" (pa[1][i])); + 2141 3545920 : asm volatile ("movdqa %%xmm6,%0" : "=m" (pa[1][i])); 2142 : } 2143 : 2144 : raid_sse_end(); - 2145 44277 : } + 2145 44056 : } 2146 : #endif 2147 : 2148 : #if defined(CONFIG_X86) && defined(CONFIG_SSSE3) diff --git a/cov/raid/x86z.c.func-sort-c.html b/cov/raid/x86z.c.func-sort-c.html index 66ea680d..1631ce5f 100644 --- a/cov/raid/x86z.c.func-sort-c.html +++ b/cov/raid/x86z.c.func-sort-c.html @@ -61,7 +61,7 @@ raid_genz_sse2 - 1175 + 1174
diff --git a/cov/raid/x86z.c.func.html b/cov/raid/x86z.c.func.html index 35e764a4..4a83023c 100644 --- a/cov/raid/x86z.c.func.html +++ b/cov/raid/x86z.c.func.html @@ -61,7 +61,7 @@ raid_genz_sse2 - 1175 + 1174
diff --git a/cov/raid/x86z.c.gcov.html b/cov/raid/x86z.c.gcov.html index 98fd341d..74725de8 100644 --- a/cov/raid/x86z.c.gcov.html +++ b/cov/raid/x86z.c.gcov.html @@ -102,58 +102,58 @@ 40 : /* 41 : * GENz (triple parity with powers of 2^-1) SSE2 implementation 42 : */ - 43 1175 : void raid_genz_sse2(int nd, size_t size, void **vv) + 43 1174 : void raid_genz_sse2(int nd, size_t size, void **vv) 44 : { - 45 1175 : uint8_t **v = (uint8_t**)vv; + 45 1174 : uint8_t **v = (uint8_t**)vv; 46 : uint8_t *p; 47 : uint8_t *q; 48 : uint8_t *r; 49 : int d, l; 50 : size_t i; 51 : - 52 1175 : l = nd - 1; - 53 1175 : p = v[nd]; - 54 1175 : q = v[nd + 1]; - 55 1175 : r = v[nd + 2]; + 52 1174 : l = nd - 1; + 53 1174 : p = v[nd]; + 54 1174 : q = v[nd + 1]; + 55 1174 : r = v[nd + 2]; 56 : 57 : raid_sse_begin(); 58 : - 59 1175 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfzconst16.poly[0])); - 60 1175 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfzconst16.half[0])); - 61 1175 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfzconst16.low7[0])); + 59 1174 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfzconst16.poly[0])); + 60 1174 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfzconst16.half[0])); + 61 1174 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfzconst16.low7[0])); 62 : - 63 1362151 : for (i = 0; i < size; i += 16) { - 64 1360976 : asm volatile ("movdqa %0,%%xmm0" : : "m" (v[l][i])); - 65 1360976 : asm volatile ("movdqa %xmm0,%xmm1"); - 66 1360976 : asm volatile ("movdqa %xmm0,%xmm2"); - 67 10958080 : for (d = l - 1; d >= 0; --d) { - 68 9597104 : asm volatile ("pxor %xmm4,%xmm4"); - 69 9597104 : asm volatile ("pcmpgtb %xmm1,%xmm4"); - 70 9597104 : asm volatile ("paddb %xmm1,%xmm1"); - 71 9597104 : asm volatile ("pand %xmm7,%xmm4"); - 72 9597104 : asm volatile ("pxor %xmm4,%xmm1"); + 63 1345766 : for (i = 0; i < size; i += 16) { + 64 1344592 : asm volatile ("movdqa %0,%%xmm0" : : "m" (v[l][i])); + 65 1344592 : asm volatile ("movdqa %xmm0,%xmm1"); + 66 1344592 : asm volatile ("movdqa %xmm0,%xmm2"); + 67 10827008 : for (d = l - 1; d >= 0; --d) { + 68 9482416 : asm volatile ("pxor %xmm4,%xmm4"); + 69 9482416 : asm volatile ("pcmpgtb %xmm1,%xmm4"); + 70 9482416 : asm volatile ("paddb %xmm1,%xmm1"); + 71 9482416 : asm volatile ("pand %xmm7,%xmm4"); + 72 9482416 : asm volatile ("pxor %xmm4,%xmm1"); 73 : - 74 9597104 : asm volatile ("movdqa %xmm2,%xmm4"); - 75 9597104 : asm volatile ("pxor %xmm5,%xmm5"); - 76 9597104 : asm volatile ("psllw $7,%xmm4"); - 77 9597104 : asm volatile ("psrlw $1,%xmm2"); - 78 9597104 : asm volatile ("pcmpgtb %xmm4,%xmm5"); - 79 9597104 : asm volatile ("pand %xmm6,%xmm2"); - 80 9597104 : asm volatile ("pand %xmm3,%xmm5"); - 81 9597104 : asm volatile ("pxor %xmm5,%xmm2"); + 74 9482416 : asm volatile ("movdqa %xmm2,%xmm4"); + 75 9482416 : asm volatile ("pxor %xmm5,%xmm5"); + 76 9482416 : asm volatile ("psllw $7,%xmm4"); + 77 9482416 : asm volatile ("psrlw $1,%xmm2"); + 78 9482416 : asm volatile ("pcmpgtb %xmm4,%xmm5"); + 79 9482416 : asm volatile ("pand %xmm6,%xmm2"); + 80 9482416 : asm volatile ("pand %xmm3,%xmm5"); + 81 9482416 : asm volatile ("pxor %xmm5,%xmm2"); 82 : - 83 9597104 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[d][i])); - 84 9597104 : asm volatile ("pxor %xmm4,%xmm0"); - 85 9597104 : asm volatile ("pxor %xmm4,%xmm1"); - 86 9597104 : asm volatile ("pxor %xmm4,%xmm2"); + 83 9482416 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[d][i])); + 84 9482416 : asm volatile ("pxor %xmm4,%xmm0"); + 85 9482416 : asm volatile ("pxor %xmm4,%xmm1"); + 86 9482416 : asm volatile ("pxor %xmm4,%xmm2"); 87 : } - 88 1360976 : asm volatile ("movntdq %%xmm0,%0" : "=m" (p[i])); - 89 1360976 : asm volatile ("movntdq %%xmm1,%0" : "=m" (q[i])); - 90 1360976 : asm volatile ("movntdq %%xmm2,%0" : "=m" (r[i])); + 88 1344592 : asm volatile ("movntdq %%xmm0,%0" : "=m" (p[i])); + 89 1344592 : asm volatile ("movntdq %%xmm1,%0" : "=m" (q[i])); + 90 1344592 : asm volatile ("movntdq %%xmm2,%0" : "=m" (r[i])); 91 : } 92 : 93 : raid_sse_end(); - 94 1175 : } + 94 1174 : } 95 : #endif 96 : 97 : #if defined(CONFIG_X86_64) && defined(CONFIG_SSE2) diff --git a/cov/tommyds/tommyarray.c.func-sort-c.html b/cov/tommyds/tommyarray.c.func-sort-c.html index 30dfbc0e..e115e780 100644 --- a/cov/tommyds/tommyarray.c.func-sort-c.html +++ b/cov/tommyds/tommyarray.c.func-sort-c.html @@ -61,15 +61,15 @@ tommy_array_grow - 2202 + 2208 tommy_array_init - 519 + 521 tommy_array_done - 496 + 497 tommy_array_memory_usage diff --git a/cov/tommyds/tommyarray.c.func.html b/cov/tommyds/tommyarray.c.func.html index 5d86fce0..7c16efad 100644 --- a/cov/tommyds/tommyarray.c.func.html +++ b/cov/tommyds/tommyarray.c.func.html @@ -61,15 +61,15 @@ tommy_array_done - 496 + 497 tommy_array_grow - 2202 + 2208 tommy_array_init - 519 + 521 tommy_array_memory_usage diff --git a/cov/tommyds/tommyarray.c.gcov.html b/cov/tommyds/tommyarray.c.gcov.html index a9f1e57f..0a0f2952 100644 --- a/cov/tommyds/tommyarray.c.gcov.html +++ b/cov/tommyds/tommyarray.c.gcov.html @@ -92,38 +92,38 @@ 30 : /******************************************************************************/ 31 : /* array */ 32 : - 33 519 : void tommy_array_init(tommy_array* array) + 33 521 : void tommy_array_init(tommy_array* array) 34 : { 35 : tommy_uint_t i; 36 : 37 : /* fixed initial size */ - 38 519 : array->bucket_bit = TOMMY_ARRAY_BIT; - 39 519 : array->bucket_max = 1 << array->bucket_bit; - 40 519 : array->bucket[0] = tommy_cast(void**, tommy_calloc(array->bucket_max, sizeof(void*))); - 41 3114 : for (i = 1; i < TOMMY_ARRAY_BIT; ++i) - 42 2595 : array->bucket[i] = array->bucket[0]; + 38 521 : array->bucket_bit = TOMMY_ARRAY_BIT; + 39 521 : array->bucket_max = 1 << array->bucket_bit; + 40 521 : array->bucket[0] = tommy_cast(void**, tommy_calloc(array->bucket_max, sizeof(void*))); + 41 3126 : for (i = 1; i < TOMMY_ARRAY_BIT; ++i) + 42 2605 : array->bucket[i] = array->bucket[0]; 43 : - 44 519 : array->count = 0; - 45 519 : } + 44 521 : array->count = 0; + 45 521 : } 46 : - 47 496 : void tommy_array_done(tommy_array* array) + 47 497 : void tommy_array_done(tommy_array* array) 48 : { 49 : tommy_uint_t i; 50 : - 51 496 : tommy_free(array->bucket[0]); - 52 498 : for (i = TOMMY_ARRAY_BIT; i < array->bucket_bit; ++i) { + 51 497 : tommy_free(array->bucket[0]); + 52 499 : for (i = TOMMY_ARRAY_BIT; i < array->bucket_bit; ++i) { 53 2 : void** segment = array->bucket[i]; 54 2 : tommy_free(&segment[((tommy_ptrdiff_t)1) << i]); 55 : } - 56 496 : } + 56 497 : } 57 : - 58 2202 : void tommy_array_grow(tommy_array* array, tommy_count_t count) + 58 2208 : void tommy_array_grow(tommy_array* array, tommy_count_t count) 59 : { - 60 2202 : if (array->count >= count) - 61 2202 : return; - 62 2202 : array->count = count; + 60 2208 : if (array->count >= count) + 61 2208 : return; + 62 2208 : array->count = count; 63 : - 64 4406 : while (count > array->bucket_max) { + 64 4418 : while (count > array->bucket_max) { 65 : void** segment; 66 : 67 : /* allocate one more segment */ diff --git a/cov/tommyds/tommyarray.h.func-sort-c.html b/cov/tommyds/tommyarray.h.func-sort-c.html index 5c231686..95ea2d0e 100644 --- a/cov/tommyds/tommyarray.h.func-sort-c.html +++ b/cov/tommyds/tommyarray.h.func-sort-c.html @@ -61,19 +61,19 @@ tommy_array_ref - 10268450 + 10268715 tommy_array_get - 10266248 + 10266507 tommy_array_size - 1575664 + 1575720 tommy_array_set - 2202 + 2208 tommy_array_insert diff --git a/cov/tommyds/tommyarray.h.func.html b/cov/tommyds/tommyarray.h.func.html index 81a02afe..cf45dc82 100644 --- a/cov/tommyds/tommyarray.h.func.html +++ b/cov/tommyds/tommyarray.h.func.html @@ -61,7 +61,7 @@ tommy_array_get - 10266248 + 10266507 tommy_array_insert @@ -69,15 +69,15 @@ tommy_array_ref - 10268450 + 10268715 tommy_array_set - 2202 + 2208 tommy_array_size - 1575664 + 1575720
diff --git a/cov/tommyds/tommyarray.h.gcov.html b/cov/tommyds/tommyarray.h.gcov.html index c6b33ddb..1015219a 100644 --- a/cov/tommyds/tommyarray.h.gcov.html +++ b/cov/tommyds/tommyarray.h.gcov.html @@ -152,16 +152,16 @@ 90 : * You must be sure that space for this position is already 91 : * allocated calling tommy_array_grow(). 92 : */ - 93 10268450 : tommy_inline void** tommy_array_ref(tommy_array* array, tommy_count_t pos) + 93 10268715 : tommy_inline void** tommy_array_ref(tommy_array* array, tommy_count_t pos) 94 : { 95 : tommy_uint_t bsr; 96 : - 97 10268450 : assert(pos < array->count); + 97 10268715 : assert(pos < array->count); 98 : 99 : /* get the highest bit set, in case of all 0, return 0 */ - 100 10268450 : bsr = tommy_ilog2_u32(pos | 1); + 100 10268715 : bsr = tommy_ilog2_u32(pos | 1); 101 : - 102 10268450 : return &array->bucket[bsr][pos]; + 102 10268715 : return &array->bucket[bsr][pos]; 103 : } 104 : 105 : /** @@ -169,19 +169,19 @@ 107 : * You must be sure that space for this position is already 108 : * allocated calling tommy_array_grow(). 109 : */ - 110 2202 : tommy_inline void tommy_array_set(tommy_array* array, tommy_count_t pos, void* element) + 110 2208 : tommy_inline void tommy_array_set(tommy_array* array, tommy_count_t pos, void* element) 111 : { - 112 2202 : *tommy_array_ref(array, pos) = element; - 113 2202 : } + 112 2208 : *tommy_array_ref(array, pos) = element; + 113 2208 : } 114 : 115 : /** 116 : * Gets the element at the specified position. 117 : * You must be sure that space for this position is already 118 : * allocated calling tommy_array_grow(). 119 : */ - 120 10266248 : tommy_inline void* tommy_array_get(tommy_array* array, tommy_count_t pos) + 120 10266507 : tommy_inline void* tommy_array_get(tommy_array* array, tommy_count_t pos) 121 : { - 122 10266248 : return *tommy_array_ref(array, pos); + 122 10266507 : return *tommy_array_ref(array, pos); 123 : } 124 : 125 : /** @@ -199,9 +199,9 @@ 137 : /** 138 : * Gets the initialized size of the array. 139 : */ - 140 1575664 : tommy_inline tommy_count_t tommy_array_size(tommy_array* array) + 140 1575720 : tommy_inline tommy_count_t tommy_array_size(tommy_array* array) 141 : { - 142 1575664 : return array->count; + 142 1575720 : return array->count; 143 : } 144 : 145 : /** diff --git a/cov/tommyds/tommyarrayblkof.c.func-sort-c.html b/cov/tommyds/tommyarrayblkof.c.func-sort-c.html index 3eaf9665..1655a127 100644 --- a/cov/tommyds/tommyarrayblkof.c.func-sort-c.html +++ b/cov/tommyds/tommyarrayblkof.c.func-sort-c.html @@ -61,11 +61,11 @@ tommy_arrayblkof_grow - 1698221 + 1698354 tommy_arrayblkof_init - 266 + 267 tommy_arrayblkof_done diff --git a/cov/tommyds/tommyarrayblkof.c.func.html b/cov/tommyds/tommyarrayblkof.c.func.html index 2887d111..0298d5a6 100644 --- a/cov/tommyds/tommyarrayblkof.c.func.html +++ b/cov/tommyds/tommyarrayblkof.c.func.html @@ -65,11 +65,11 @@ tommy_arrayblkof_grow - 1698221 + 1698354 tommy_arrayblkof_init - 266 + 267 tommy_arrayblkof_memory_usage diff --git a/cov/tommyds/tommyarrayblkof.c.gcov.html b/cov/tommyds/tommyarrayblkof.c.gcov.html index e03fe466..86df9035 100644 --- a/cov/tommyds/tommyarrayblkof.c.gcov.html +++ b/cov/tommyds/tommyarrayblkof.c.gcov.html @@ -92,13 +92,13 @@ 30 : /******************************************************************************/ 31 : /* array */ 32 : - 33 266 : void tommy_arrayblkof_init(tommy_arrayblkof* array, tommy_size_t element_size) + 33 267 : void tommy_arrayblkof_init(tommy_arrayblkof* array, tommy_size_t element_size) 34 : { - 35 266 : tommy_array_init(&array->block); + 35 267 : tommy_array_init(&array->block); 36 : - 37 266 : array->element_size = element_size; - 38 266 : array->count = 0; - 39 266 : } + 37 267 : array->element_size = element_size; + 38 267 : array->count = 0; + 39 267 : } 40 : 41 244 : void tommy_arrayblkof_done(tommy_arrayblkof* array) 42 : { @@ -110,30 +110,30 @@ 48 244 : tommy_array_done(&array->block); 49 244 : } 50 : - 51 1698221 : void tommy_arrayblkof_grow(tommy_arrayblkof* array, tommy_count_t count) + 51 1698354 : void tommy_arrayblkof_grow(tommy_arrayblkof* array, tommy_count_t count) 52 : { 53 : tommy_count_t block_max; 54 : tommy_count_t block_mac; 55 : - 56 1698221 : if (array->count >= count) - 57 1821547 : return; - 58 1574895 : array->count = count; + 56 1698354 : if (array->count >= count) + 57 1821757 : return; + 58 1574951 : array->count = count; 59 : - 60 1574895 : block_max = (count + TOMMY_ARRAYBLKOF_SIZE - 1) / TOMMY_ARRAYBLKOF_SIZE; - 61 1574895 : block_mac = tommy_array_size(&array->block); + 60 1574951 : block_max = (count + TOMMY_ARRAYBLKOF_SIZE - 1) / TOMMY_ARRAYBLKOF_SIZE; + 61 1574951 : block_mac = tommy_array_size(&array->block); 62 : - 63 1574895 : if (block_mac < block_max) { + 63 1574951 : if (block_mac < block_max) { 64 : /* grow the block array */ - 65 553 : tommy_array_grow(&array->block, block_max); + 65 554 : tommy_array_grow(&array->block, block_max); 66 : 67 : /* allocate new blocks */ - 68 1659 : while (block_mac < block_max) { - 69 553 : void** ptr = tommy_cast(void**, tommy_calloc(TOMMY_ARRAYBLKOF_SIZE, array->element_size)); + 68 1662 : while (block_mac < block_max) { + 69 554 : void** ptr = tommy_cast(void**, tommy_calloc(TOMMY_ARRAYBLKOF_SIZE, array->element_size)); 70 : 71 : /* set the new block */ - 72 553 : tommy_array_set(&array->block, block_mac, ptr); + 72 554 : tommy_array_set(&array->block, block_mac, ptr); 73 : - 74 553 : ++block_mac; + 74 554 : ++block_mac; 75 : } 76 : } 77 : } diff --git a/cov/tommyds/tommyarrayblkof.h.func-sort-c.html b/cov/tommyds/tommyarrayblkof.h.func-sort-c.html index 5225e0d5..671bddbe 100644 --- a/cov/tommyds/tommyarrayblkof.h.func-sort-c.html +++ b/cov/tommyds/tommyarrayblkof.h.func-sort-c.html @@ -61,11 +61,11 @@ tommy_arrayblkof_ref - 6534208 + 6534594 tommy_arrayblkof_size - 5098374 + 5098627
diff --git a/cov/tommyds/tommyarrayblkof.h.func.html b/cov/tommyds/tommyarrayblkof.h.func.html index 5a41dd06..254995bd 100644 --- a/cov/tommyds/tommyarrayblkof.h.func.html +++ b/cov/tommyds/tommyarrayblkof.h.func.html @@ -61,11 +61,11 @@ tommy_arrayblkof_ref - 6534208 + 6534594 tommy_arrayblkof_size - 5098374 + 5098627
diff --git a/cov/tommyds/tommyarrayblkof.h.gcov.html b/cov/tommyds/tommyarrayblkof.h.gcov.html index 4116fde7..edffddf2 100644 --- a/cov/tommyds/tommyarrayblkof.h.gcov.html +++ b/cov/tommyds/tommyarrayblkof.h.gcov.html @@ -148,23 +148,23 @@ 86 : * You must be sure that space for this position is already 87 : * allocated calling tommy_arrayblkof_grow(). 88 : */ - 89 6534208 : tommy_inline void* tommy_arrayblkof_ref(tommy_arrayblkof* array, tommy_count_t pos) + 89 6534594 : tommy_inline void* tommy_arrayblkof_ref(tommy_arrayblkof* array, tommy_count_t pos) 90 : { 91 : unsigned char* base; 92 : - 93 6534208 : assert(pos < array->count); + 93 6534594 : assert(pos < array->count); 94 : - 95 6534208 : base = tommy_cast(unsigned char*, tommy_array_get(&array->block, pos / TOMMY_ARRAYBLKOF_SIZE)); + 95 6534594 : base = tommy_cast(unsigned char*, tommy_array_get(&array->block, pos / TOMMY_ARRAYBLKOF_SIZE)); 96 : - 97 6534208 : return base + (pos % TOMMY_ARRAYBLKOF_SIZE) * array->element_size; + 97 6534594 : return base + (pos % TOMMY_ARRAYBLKOF_SIZE) * array->element_size; 98 : } 99 : 100 : /** 101 : * Gets the initialized size of the array. 102 : */ - 103 5098374 : tommy_inline tommy_count_t tommy_arrayblkof_size(tommy_arrayblkof* array) + 103 5098627 : tommy_inline tommy_count_t tommy_arrayblkof_size(tommy_arrayblkof* array) 104 : { - 105 5098374 : return array->count; + 105 5098627 : return array->count; 106 : } 107 : 108 : /** diff --git a/cov/tommyds/tommychain.h.func-sort-c.html b/cov/tommyds/tommychain.h.func-sort-c.html index aff5319b..cd51b466 100644 --- a/cov/tommyds/tommychain.h.func-sort-c.html +++ b/cov/tommyds/tommychain.h.func-sort-c.html @@ -61,23 +61,23 @@ tommy_chain_splice - 4502405 + 4492296 tommy_chain_merge_degenerated - 1283232 + 1283291 tommy_chain_concat - 1276403 + 1276680 tommy_chain_merge - 471088 + 470675 tommy_chain_mergesort - 1684 + 1693
diff --git a/cov/tommyds/tommychain.h.func.html b/cov/tommyds/tommychain.h.func.html index 9025ad4e..7584db51 100644 --- a/cov/tommyds/tommychain.h.func.html +++ b/cov/tommyds/tommychain.h.func.html @@ -61,23 +61,23 @@ tommy_chain_concat - 1276403 + 1276680 tommy_chain_merge - 471088 + 470675 tommy_chain_merge_degenerated - 1283232 + 1283291 tommy_chain_mergesort - 1684 + 1693 tommy_chain_splice - 4502405 + 4492296
diff --git a/cov/tommyds/tommychain.h.gcov.html b/cov/tommyds/tommychain.h.gcov.html index d8fd9841..ac4fc97a 100644 --- a/cov/tommyds/tommychain.h.gcov.html +++ b/cov/tommyds/tommychain.h.gcov.html @@ -119,83 +119,83 @@ 57 : /** 58 : * Splices a chain in the middle of another chain. 59 : */ - 60 4502405 : tommy_inline void tommy_chain_splice(tommy_node* first_before, tommy_node* first_after, tommy_node* second_head, tommy_node* second_tail) + 60 4492296 : tommy_inline void tommy_chain_splice(tommy_node* first_before, tommy_node* first_after, tommy_node* second_head, tommy_node* second_tail) 61 : { 62 : /* set the prev list */ - 63 4502405 : first_after->prev = second_tail; - 64 4502405 : second_head->prev = first_before; + 63 4492296 : first_after->prev = second_tail; + 64 4492296 : second_head->prev = first_before; 65 : 66 : /* set the next list */ - 67 4502405 : first_before->next = second_head; - 68 4502405 : second_tail->next = first_after; - 69 4502405 : } + 67 4492296 : first_before->next = second_head; + 68 4492296 : second_tail->next = first_after; + 69 4492296 : } 70 : 71 : /** 72 : * Concats two chains. 73 : */ - 74 1276403 : tommy_inline void tommy_chain_concat(tommy_node* first_tail, tommy_node* second_head) + 74 1276680 : tommy_inline void tommy_chain_concat(tommy_node* first_tail, tommy_node* second_head) 75 : { 76 : /* set the prev list */ - 77 1276403 : second_head->prev = first_tail; + 77 1276680 : second_head->prev = first_tail; 78 : 79 : /* set the next list */ - 80 1276403 : first_tail->next = second_head; - 81 1276403 : } + 80 1276680 : first_tail->next = second_head; + 81 1276680 : } 82 : 83 : /** 84 : * Merges two chains. 85 : */ - 86 471088 : tommy_inline void tommy_chain_merge(tommy_chain* first, tommy_chain* second, tommy_compare_func* cmp) + 86 470675 : tommy_inline void tommy_chain_merge(tommy_chain* first, tommy_chain* second, tommy_compare_func* cmp) 87 : { - 88 471088 : tommy_node* first_i = first->head; - 89 471088 : tommy_node* second_i = second->head; + 88 470675 : tommy_node* first_i = first->head; + 89 470675 : tommy_node* second_i = second->head; 90 : 91 : /* merge */ 92 : while (1) { - 93 9796567 : if (cmp(first_i->data, second_i->data) > 0) { - 94 4734738 : tommy_node* next = second_i->next; - 95 4734738 : if (first_i == first->head) { - 96 232333 : tommy_chain_concat(second_i, first_i); - 97 232333 : first->head = second_i; + 93 9777862 : if (cmp(first_i->data, second_i->data) > 0) { + 94 4724569 : tommy_node* next = second_i->next; + 95 4724569 : if (first_i == first->head) { + 96 232273 : tommy_chain_concat(second_i, first_i); + 97 232273 : first->head = second_i; 98 : } else { - 99 4502405 : tommy_chain_splice(first_i->prev, first_i, second_i, second_i); + 99 4492296 : tommy_chain_splice(first_i->prev, first_i, second_i, second_i); 100 : } - 101 4734738 : if (second_i == second->tail) - 102 239162 : break; - 103 4495576 : second_i = next; + 101 4724569 : if (second_i == second->tail) + 102 238884 : break; + 103 4485685 : second_i = next; 104 : } else { - 105 5061829 : if (first_i == first->tail) { - 106 231926 : tommy_chain_concat(first_i, second_i); - 107 231926 : first->tail = second->tail; - 108 231926 : break; + 105 5053293 : if (first_i == first->tail) { + 106 231791 : tommy_chain_concat(first_i, second_i); + 107 231791 : first->tail = second->tail; + 108 231791 : break; 109 : } - 110 4829903 : first_i = first_i->next; + 110 4821502 : first_i = first_i->next; 111 : } - 112 9325479 : } - 113 471088 : } + 112 9307187 : } + 113 470675 : } 114 : 115 : /** 116 : * Merges two chains managing special degenerated cases. 117 : * It's funtionally equivalent at tommy_chain_merge() but faster with already ordered chains. 118 : */ - 119 1283232 : tommy_inline void tommy_chain_merge_degenerated(tommy_chain* first, tommy_chain* second, tommy_compare_func* cmp) + 119 1283291 : tommy_inline void tommy_chain_merge_degenerated(tommy_chain* first, tommy_chain* second, tommy_compare_func* cmp) 120 : { 121 : /* identify the condition first <= second */ - 122 1283232 : if (cmp(first->tail->data, second->head->data) <= 0) { - 123 477330 : tommy_chain_concat(first->tail, second->head); - 124 477330 : first->tail = second->tail; - 125 477330 : return; + 122 1283291 : if (cmp(first->tail->data, second->head->data) <= 0) { + 123 477903 : tommy_chain_concat(first->tail, second->head); + 124 477903 : first->tail = second->tail; + 125 477903 : return; 126 : } 127 : 128 : /* identify the condition second < first */ 129 : /* here we must be strict on comparison to keep the sort stable */ - 130 805902 : if (cmp(second->tail->data, first->head->data) < 0) { - 131 334814 : tommy_chain_concat(second->tail, first->head); - 132 334814 : first->head = second->head; - 133 334814 : return; + 130 805388 : if (cmp(second->tail->data, first->head->data) < 0) { + 131 334713 : tommy_chain_concat(second->tail, first->head); + 132 334713 : first->head = second->head; + 133 334713 : return; 134 : } 135 : - 136 471088 : tommy_chain_merge(first, second, cmp); + 136 470675 : tommy_chain_merge(first, second, cmp); 137 : } 138 : 139 : /** @@ -215,7 +215,7 @@ 153 : * Linux Kernel lib/list_sort.c 154 : * http://lxr.linux.no/#linux+v2.6.36/lib/list_sort.c 155 : */ - 156 1684 : tommy_inline void tommy_chain_mergesort(tommy_chain* chain, tommy_compare_func* cmp) + 156 1693 : tommy_inline void tommy_chain_mergesort(tommy_chain* chain, tommy_compare_func* cmp) 157 : { 158 : /* 159 : * Bit buckets of chains. @@ -230,57 +230,57 @@ 168 : * It's used to know which bucket is empty of full. 169 : */ 170 : tommy_count_t counter; - 171 1684 : tommy_node* node = chain->head; - 172 1684 : tommy_node* tail = chain->tail; + 171 1693 : tommy_node* node = chain->head; + 172 1693 : tommy_node* tail = chain->tail; 173 : tommy_count_t mask; 174 : tommy_count_t i; 175 : - 176 1684 : counter = 0; + 176 1693 : counter = 0; 177 : while (1) { 178 : tommy_node* next; 179 : tommy_chain* last; 180 : 181 : /* carry bit to add */ - 182 1284916 : last = &bit[TOMMY_CHAIN_BIT_MAX]; - 183 1284916 : bit[TOMMY_CHAIN_BIT_MAX].head = node; - 184 1284916 : bit[TOMMY_CHAIN_BIT_MAX].tail = node; - 185 1284916 : next = node->next; + 182 1284984 : last = &bit[TOMMY_CHAIN_BIT_MAX]; + 183 1284984 : bit[TOMMY_CHAIN_BIT_MAX].head = node; + 184 1284984 : bit[TOMMY_CHAIN_BIT_MAX].tail = node; + 185 1284984 : next = node->next; 186 : 187 : /* add the bit, propagating the carry */ - 188 1284916 : i = 0; - 189 1284916 : mask = counter; - 190 3847013 : while ((mask & 1) != 0) { - 191 1277181 : tommy_chain_merge_degenerated(&bit[i], last, cmp); - 192 1277181 : mask >>= 1; - 193 1277181 : last = &bit[i]; - 194 1277181 : ++i; + 188 1284984 : i = 0; + 189 1284984 : mask = counter; + 190 3847206 : while ((mask & 1) != 0) { + 191 1277238 : tommy_chain_merge_degenerated(&bit[i], last, cmp); + 192 1277238 : mask >>= 1; + 193 1277238 : last = &bit[i]; + 194 1277238 : ++i; 195 : } 196 : 197 : /* copy the carry in the first empty bit */ - 198 1284916 : bit[i] = *last; + 198 1284984 : bit[i] = *last; 199 : 200 : /* add the carry in the counter */ - 201 1284916 : ++counter; + 201 1284984 : ++counter; 202 : - 203 1284916 : if (node == tail) - 204 1684 : break; - 205 1283232 : node = next; - 206 1283232 : } + 203 1284984 : if (node == tail) + 204 1693 : break; + 205 1283291 : node = next; + 206 1283291 : } 207 : 208 : /* merge the buckets */ - 209 1684 : i = tommy_ctz_u32(counter); - 210 1684 : mask = counter >> i; - 211 12396 : while (mask != 1) { - 212 9028 : mask >>= 1; - 213 9028 : if (mask & 1) - 214 6051 : tommy_chain_merge_degenerated(&bit[i + 1], &bit[i], cmp); + 209 1693 : i = tommy_ctz_u32(counter); + 210 1693 : mask = counter >> i; + 211 12413 : while (mask != 1) { + 212 9027 : mask >>= 1; + 213 9027 : if (mask & 1) + 214 6053 : tommy_chain_merge_degenerated(&bit[i + 1], &bit[i], cmp); 215 : else - 216 2977 : bit[i + 1] = bit[i]; - 217 9028 : ++i; + 216 2974 : bit[i + 1] = bit[i]; + 217 9027 : ++i; 218 : } 219 : - 220 1684 : *chain = bit[i]; - 221 1684 : } + 220 1693 : *chain = bit[i]; + 221 1693 : } 222 : 223 : #endif 224 : diff --git a/cov/tommyds/tommyhash.c.func-sort-c.html b/cov/tommyds/tommyhash.c.func-sort-c.html index 0e1009a9..d59abafe 100644 --- a/cov/tommyds/tommyhash.c.func-sort-c.html +++ b/cov/tommyds/tommyhash.c.func-sort-c.html @@ -61,11 +61,11 @@ tommy_le_uint32_read - 11587716 + 11587314 tommy_hash_u32 - 4059834 + 4059737 tommy_strhash_u32 diff --git a/cov/tommyds/tommyhash.c.func.html b/cov/tommyds/tommyhash.c.func.html index 1dc814cc..217f4d7a 100644 --- a/cov/tommyds/tommyhash.c.func.html +++ b/cov/tommyds/tommyhash.c.func.html @@ -61,7 +61,7 @@ tommy_hash_u32 - 4059834 + 4059737 tommy_hash_u64 @@ -69,7 +69,7 @@ tommy_le_uint32_read - 11587716 + 11587314 tommy_strhash_u32 diff --git a/cov/tommyds/tommyhash.c.gcov.html b/cov/tommyds/tommyhash.c.gcov.html index 9fd8bf6e..998b4290 100644 --- a/cov/tommyds/tommyhash.c.gcov.html +++ b/cov/tommyds/tommyhash.c.gcov.html @@ -92,12 +92,12 @@ 30 : /******************************************************************************/ 31 : /* hash */ 32 : - 33 11587716 : tommy_inline tommy_uint32_t tommy_le_uint32_read(const void* ptr) + 33 11587314 : tommy_inline tommy_uint32_t tommy_le_uint32_read(const void* ptr) 34 : { 35 : /* allow unaligned read on Intel x86 and x86_64 platforms */ 36 : #if defined(__i386__) || defined(_M_IX86) || defined(_X86_) || defined(__x86_64__) || defined(_M_X64) 37 : /* defines from http://predef.sourceforge.net/ */ - 38 11587716 : return *(const tommy_uint32_t*)ptr; + 38 11587314 : return *(const tommy_uint32_t*)ptr; 39 : #else 40 : const unsigned char* ptr8 = tommy_cast(const unsigned char*, ptr); 41 : return ptr8[0] + ((tommy_uint32_t)ptr8[1] << 8) + ((tommy_uint32_t)ptr8[2] << 16) + ((tommy_uint32_t)ptr8[3] << 24); @@ -128,53 +128,53 @@ 66 : c ^= b; c -= tommy_rot(b, 24); \ 67 : } while (0) 68 : - 69 4059834 : tommy_uint32_t tommy_hash_u32(tommy_uint32_t init_val, const void* void_key, tommy_size_t key_len) + 69 4059737 : tommy_uint32_t tommy_hash_u32(tommy_uint32_t init_val, const void* void_key, tommy_size_t key_len) 70 : { - 71 4059834 : const unsigned char* key = tommy_cast(const unsigned char*, void_key); + 71 4059737 : const unsigned char* key = tommy_cast(const unsigned char*, void_key); 72 : tommy_uint32_t a, b, c; 73 : - 74 4059834 : a = b = c = 0xdeadbeef + ((tommy_uint32_t)key_len) + init_val; + 74 4059737 : a = b = c = 0xdeadbeef + ((tommy_uint32_t)key_len) + init_val; 75 : - 76 10239927 : while (key_len > 12) { - 77 2120259 : a += tommy_le_uint32_read(key + 0); - 78 2120259 : b += tommy_le_uint32_read(key + 4); - 79 2120259 : c += tommy_le_uint32_read(key + 8); + 76 10239675 : while (key_len > 12) { + 77 2120201 : a += tommy_le_uint32_read(key + 0); + 78 2120201 : b += tommy_le_uint32_read(key + 4); + 79 2120201 : c += tommy_le_uint32_read(key + 8); 80 : - 81 2120259 : tommy_mix(a, b, c); + 81 2120201 : tommy_mix(a, b, c); 82 : - 83 2120259 : key_len -= 12; - 84 2120259 : key += 12; + 83 2120201 : key_len -= 12; + 84 2120201 : key += 12; 85 : } 86 : - 87 4059834 : switch (key_len) { + 87 4059737 : switch (key_len) { 88 : case 0 : 89 1 : return c; /* used only when called with a zero length */ 90 : case 12 : - 91 207749 : c += tommy_le_uint32_read(key + 8); - 92 207749 : b += tommy_le_uint32_read(key + 4); - 93 207749 : a += tommy_le_uint32_read(key + 0); - 94 207749 : break; - 95 217406 : case 11 : c += ((tommy_uint32_t)key[10]) << 16; - 96 640298 : case 10 : c += ((tommy_uint32_t)key[9]) << 8; - 97 1060028 : case 9 : c += key[8]; + 91 207727 : c += tommy_le_uint32_read(key + 8); + 92 207727 : b += tommy_le_uint32_read(key + 4); + 93 207727 : a += tommy_le_uint32_read(key + 0); + 94 207727 : break; + 95 217400 : case 11 : c += ((tommy_uint32_t)key[10]) << 16; + 96 640250 : case 10 : c += ((tommy_uint32_t)key[9]) << 8; + 97 1059946 : case 9 : c += key[8]; 98 : case 8 : - 99 1470945 : b += tommy_le_uint32_read(key + 4); - 100 1470945 : a += tommy_le_uint32_read(key + 0); - 101 1470945 : break; - 102 413147 : case 7 : b += ((tommy_uint32_t)key[6]) << 16; - 103 812922 : case 6 : b += ((tommy_uint32_t)key[5]) << 8; - 104 1229617 : case 5 : b += key[4]; + 99 1470855 : b += tommy_le_uint32_read(key + 4); + 100 1470855 : a += tommy_le_uint32_read(key + 0); + 101 1470855 : break; + 102 413128 : case 7 : b += ((tommy_uint32_t)key[6]) << 16; + 103 812916 : case 6 : b += ((tommy_uint32_t)key[5]) << 8; + 104 1229635 : case 5 : b += key[4]; 105 : case 4 : - 106 1661668 : a += tommy_le_uint32_read(key + 0); - 107 1661668 : break; - 108 301716 : case 3 : a += ((tommy_uint32_t)key[2]) << 16; - 109 509499 : case 2 : a += ((tommy_uint32_t)key[1]) << 8; - 110 719471 : case 1 : a += key[0]; + 106 1661686 : a += tommy_le_uint32_read(key + 0); + 107 1661686 : break; + 108 301707 : case 3 : a += ((tommy_uint32_t)key[2]) << 16; + 109 509493 : case 2 : a += ((tommy_uint32_t)key[1]) << 8; + 110 719468 : case 1 : a += key[0]; 111 : } 112 : - 113 4059833 : tommy_final(a, b, c); + 113 4059736 : tommy_final(a, b, c); 114 : - 115 4059833 : return c; + 115 4059736 : return c; 116 : } 117 : 118 19 : tommy_uint64_t tommy_hash_u64(tommy_uint64_t init_val, const void* void_key, tommy_size_t key_len) diff --git a/cov/tommyds/tommyhash.h.func-sort-c.html b/cov/tommyds/tommyhash.h.func-sort-c.html index cd71c362..16a1ee22 100644 --- a/cov/tommyds/tommyhash.h.func-sort-c.html +++ b/cov/tommyds/tommyhash.h.func-sort-c.html @@ -61,11 +61,11 @@ tommy_inthash_u32 - 18827742 + 18827424 tommy_inthash_u64 - 5047846 + 5047758
diff --git a/cov/tommyds/tommyhash.h.func.html b/cov/tommyds/tommyhash.h.func.html index 85bde6e0..1933c0e3 100644 --- a/cov/tommyds/tommyhash.h.func.html +++ b/cov/tommyds/tommyhash.h.func.html @@ -61,11 +61,11 @@ tommy_inthash_u32 - 18827742 + 18827424 tommy_inthash_u64 - 5047846 + 5047758
diff --git a/cov/tommyds/tommyhash.h.gcov.html b/cov/tommyds/tommyhash.h.gcov.html index 0f8705fe..12405e14 100644 --- a/cov/tommyds/tommyhash.h.gcov.html +++ b/cov/tommyds/tommyhash.h.gcov.html @@ -167,17 +167,17 @@ 105 : * Implementation of the Robert Jenkins "4-byte Integer Hashing", 106 : * from http://burtleburtle.net/bob/hash/integer.html 107 : */ - 108 18827742 : tommy_inline tommy_uint32_t tommy_inthash_u32(tommy_uint32_t key) + 108 18827424 : tommy_inline tommy_uint32_t tommy_inthash_u32(tommy_uint32_t key) 109 : { - 110 18827742 : key -= key << 6; - 111 18827742 : key ^= key >> 17; - 112 18827742 : key -= key << 9; - 113 18827742 : key ^= key << 4; - 114 18827742 : key -= key << 3; - 115 18827742 : key ^= key << 10; - 116 18827742 : key ^= key >> 15; + 110 18827424 : key -= key << 6; + 111 18827424 : key ^= key >> 17; + 112 18827424 : key -= key << 9; + 113 18827424 : key ^= key << 4; + 114 18827424 : key -= key << 3; + 115 18827424 : key ^= key << 10; + 116 18827424 : key ^= key >> 15; 117 : - 118 18827742 : return key; + 118 18827424 : return key; 119 : } 120 : 121 : /** @@ -185,17 +185,17 @@ 123 : * Implementation of the Thomas Wang "Integer Hash Function", 124 : * from http://web.archive.org/web/20071223173210/http://www.concentric.net/~Ttwang/tech/inthash.htm 125 : */ - 126 5047846 : tommy_inline tommy_uint64_t tommy_inthash_u64(tommy_uint64_t key) + 126 5047758 : tommy_inline tommy_uint64_t tommy_inthash_u64(tommy_uint64_t key) 127 : { - 128 5047846 : key = ~key + (key << 21); - 129 5047846 : key = key ^ (key >> 24); - 130 5047846 : key = key + (key << 3) + (key << 8); - 131 5047846 : key = key ^ (key >> 14); - 132 5047846 : key = key + (key << 2) + (key << 4); - 133 5047846 : key = key ^ (key >> 28); - 134 5047846 : key = key + (key << 31); + 128 5047758 : key = ~key + (key << 21); + 129 5047758 : key = key ^ (key >> 24); + 130 5047758 : key = key + (key << 3) + (key << 8); + 131 5047758 : key = key ^ (key >> 14); + 132 5047758 : key = key + (key << 2) + (key << 4); + 133 5047758 : key = key ^ (key >> 28); + 134 5047758 : key = key + (key << 31); 135 : - 136 5047846 : return key; + 136 5047758 : return key; 137 : } 138 : 139 : #endif diff --git a/cov/tommyds/tommyhashdyn.c.func-sort-c.html b/cov/tommyds/tommyhashdyn.c.func-sort-c.html index 5ef41753..543ff5f0 100644 --- a/cov/tommyds/tommyhashdyn.c.func-sort-c.html +++ b/cov/tommyds/tommyhashdyn.c.func-sort-c.html @@ -61,27 +61,27 @@ hashdyn_grow_step - 13237087 + 13236976 tommy_hashdyn_insert - 13237087 + 13236976 hashdyn_shrink_step - 281913 + 282017 tommy_hashdyn_remove_existing - 281785 + 281889 tommy_hashdyn_resize - 41541 + 41538 tommy_hashdyn_init - 8694 + 8727 tommy_hashdyn_done diff --git a/cov/tommyds/tommyhashdyn.c.func.html b/cov/tommyds/tommyhashdyn.c.func.html index b5f91fa9..ef5510c7 100644 --- a/cov/tommyds/tommyhashdyn.c.func.html +++ b/cov/tommyds/tommyhashdyn.c.func.html @@ -61,11 +61,11 @@ hashdyn_grow_step - 13237087 + 13236976 hashdyn_shrink_step - 281913 + 282017 tommy_hashdyn_done @@ -81,11 +81,11 @@ tommy_hashdyn_init - 8694 + 8727 tommy_hashdyn_insert - 13237087 + 13236976 tommy_hashdyn_memory_usage @@ -97,11 +97,11 @@ tommy_hashdyn_remove_existing - 281785 + 281889 tommy_hashdyn_resize - 41541 + 41538
diff --git a/cov/tommyds/tommyhashdyn.c.gcov.html b/cov/tommyds/tommyhashdyn.c.gcov.html index c8b02295..e0494f88 100644 --- a/cov/tommyds/tommyhashdyn.c.gcov.html +++ b/cov/tommyds/tommyhashdyn.c.gcov.html @@ -93,16 +93,16 @@ 31 : /******************************************************************************/ 32 : /* hashdyn */ 33 : - 34 8694 : void tommy_hashdyn_init(tommy_hashdyn* hashdyn) + 34 8727 : void tommy_hashdyn_init(tommy_hashdyn* hashdyn) 35 : { 36 : /* fixed initial size */ - 37 8694 : hashdyn->bucket_bit = TOMMY_HASHDYN_BIT; - 38 8694 : hashdyn->bucket_max = 1 << hashdyn->bucket_bit; - 39 8694 : hashdyn->bucket_mask = hashdyn->bucket_max - 1; - 40 8694 : hashdyn->bucket = tommy_cast(tommy_hashdyn_node**, tommy_calloc(hashdyn->bucket_max, sizeof(tommy_hashdyn_node*))); + 37 8727 : hashdyn->bucket_bit = TOMMY_HASHDYN_BIT; + 38 8727 : hashdyn->bucket_max = 1 << hashdyn->bucket_bit; + 39 8727 : hashdyn->bucket_mask = hashdyn->bucket_max - 1; + 40 8727 : hashdyn->bucket = tommy_cast(tommy_hashdyn_node**, tommy_calloc(hashdyn->bucket_max, sizeof(tommy_hashdyn_node*))); 41 : - 42 8694 : hashdyn->count = 0; - 43 8694 : } + 42 8727 : hashdyn->count = 0; + 43 8727 : } 44 : 45 7998 : void tommy_hashdyn_done(tommy_hashdyn* hashdyn) 46 : { @@ -112,7 +112,7 @@ 50 : /** 51 : * Resize the bucket vector. 52 : */ - 53 41541 : static void tommy_hashdyn_resize(tommy_hashdyn* hashdyn, tommy_count_t new_bucket_bit) + 53 41538 : static void tommy_hashdyn_resize(tommy_hashdyn* hashdyn, tommy_count_t new_bucket_bit) 54 : { 55 : tommy_count_t bucket_bit; 56 : tommy_count_t bucket_max; @@ -120,38 +120,38 @@ 58 : tommy_count_t new_bucket_mask; 59 : tommy_hashdyn_node** new_bucket; 60 : - 61 41541 : bucket_bit = hashdyn->bucket_bit; - 62 41541 : bucket_max = hashdyn->bucket_max; + 61 41538 : bucket_bit = hashdyn->bucket_bit; + 62 41538 : bucket_max = hashdyn->bucket_max; 63 : - 64 41541 : new_bucket_max = 1 << new_bucket_bit; - 65 41541 : new_bucket_mask = new_bucket_max - 1; + 64 41538 : new_bucket_max = 1 << new_bucket_bit; + 65 41538 : new_bucket_mask = new_bucket_max - 1; 66 : 67 : /* allocate the new vector using malloc() and not calloc() */ 68 : /* because data is fully initialized in the update process */ - 69 41541 : new_bucket = tommy_cast(tommy_hashdyn_node**, tommy_malloc(new_bucket_max * sizeof(tommy_hashdyn_node*))); + 69 41538 : new_bucket = tommy_cast(tommy_hashdyn_node**, tommy_malloc(new_bucket_max * sizeof(tommy_hashdyn_node*))); 70 : 71 : /* reinsert all the elements */ - 72 41541 : if (new_bucket_bit > bucket_bit) { + 72 41538 : if (new_bucket_bit > bucket_bit) { 73 : tommy_count_t i; 74 : 75 : /* grow */ - 76 32198548 : for (i = 0; i < bucket_max; ++i) { + 76 32197009 : for (i = 0; i < bucket_max; ++i) { 77 : tommy_hashdyn_node* j; 78 : 79 : /* setup the new two buckets */ - 80 32157056 : new_bucket[i] = 0; - 81 32157056 : new_bucket[i + bucket_max] = 0; + 80 32155520 : new_bucket[i] = 0; + 81 32155520 : new_bucket[i + bucket_max] = 0; 82 : 83 : /* reinsert the bucket */ - 84 32157056 : j = hashdyn->bucket[i]; - 85 80392640 : while (j) { - 86 16078528 : tommy_hashdyn_node* j_next = j->next; - 87 16078528 : tommy_count_t pos = j->key & new_bucket_mask; - 88 16078528 : if (new_bucket[pos]) - 89 1915427 : tommy_list_insert_tail_not_empty(new_bucket[pos], j); + 84 32155520 : j = hashdyn->bucket[i]; + 85 80388800 : while (j) { + 86 16077760 : tommy_hashdyn_node* j_next = j->next; + 87 16077760 : tommy_count_t pos = j->key & new_bucket_mask; + 88 16077760 : if (new_bucket[pos]) + 89 1915117 : tommy_list_insert_tail_not_empty(new_bucket[pos], j); 90 : else - 91 14163101 : tommy_list_insert_first(&new_bucket[pos], j); - 92 16078528 : j = j_next; + 91 14162643 : tommy_list_insert_first(&new_bucket[pos], j); + 92 16077760 : j = j_next; 93 : } 94 : } 95 : } else { @@ -167,59 +167,59 @@ 105 : } 106 : } 107 : - 108 41541 : tommy_free(hashdyn->bucket); + 108 41538 : tommy_free(hashdyn->bucket); 109 : 110 : /* setup */ - 111 41541 : hashdyn->bucket_bit = new_bucket_bit; - 112 41541 : hashdyn->bucket_max = new_bucket_max; - 113 41541 : hashdyn->bucket_mask = new_bucket_mask; - 114 41541 : hashdyn->bucket = new_bucket; - 115 41541 : } + 111 41538 : hashdyn->bucket_bit = new_bucket_bit; + 112 41538 : hashdyn->bucket_max = new_bucket_max; + 113 41538 : hashdyn->bucket_mask = new_bucket_mask; + 114 41538 : hashdyn->bucket = new_bucket; + 115 41538 : } 116 : 117 : /** 118 : * Grow. 119 : */ - 120 13237087 : tommy_inline void hashdyn_grow_step(tommy_hashdyn* hashdyn) + 120 13236976 : tommy_inline void hashdyn_grow_step(tommy_hashdyn* hashdyn) 121 : { 122 : /* grow if more than 50% full */ - 123 13237087 : if (hashdyn->count >= hashdyn->bucket_max / 2) - 124 41492 : tommy_hashdyn_resize(hashdyn, hashdyn->bucket_bit + 1); - 125 13237087 : } + 123 13236976 : if (hashdyn->count >= hashdyn->bucket_max / 2) + 124 41489 : tommy_hashdyn_resize(hashdyn, hashdyn->bucket_bit + 1); + 125 13236976 : } 126 : 127 : /** 128 : * Shrink. 129 : */ - 130 281913 : tommy_inline void hashdyn_shrink_step(tommy_hashdyn* hashdyn) + 130 282017 : tommy_inline void hashdyn_shrink_step(tommy_hashdyn* hashdyn) 131 : { 132 : /* shrink if less than 12.5% full */ - 133 281913 : if (hashdyn->count <= hashdyn->bucket_max / 8 && hashdyn->bucket_bit > TOMMY_HASHDYN_BIT) + 133 282017 : if (hashdyn->count <= hashdyn->bucket_max / 8 && hashdyn->bucket_bit > TOMMY_HASHDYN_BIT) 134 49 : tommy_hashdyn_resize(hashdyn, hashdyn->bucket_bit - 1); - 135 281913 : } + 135 282017 : } 136 : - 137 13237087 : void tommy_hashdyn_insert(tommy_hashdyn* hashdyn, tommy_hashdyn_node* node, void* data, tommy_hash_t hash) + 137 13236976 : void tommy_hashdyn_insert(tommy_hashdyn* hashdyn, tommy_hashdyn_node* node, void* data, tommy_hash_t hash) 138 : { - 139 13237087 : tommy_count_t pos = hash & hashdyn->bucket_mask; + 139 13236976 : tommy_count_t pos = hash & hashdyn->bucket_mask; 140 : - 141 13237087 : tommy_list_insert_tail(&hashdyn->bucket[pos], node, data); + 141 13236976 : tommy_list_insert_tail(&hashdyn->bucket[pos], node, data); 142 : - 143 13237087 : node->key = hash; + 143 13236976 : node->key = hash; 144 : - 145 13237087 : ++hashdyn->count; + 145 13236976 : ++hashdyn->count; 146 : - 147 13237087 : hashdyn_grow_step(hashdyn); - 148 13237087 : } + 147 13236976 : hashdyn_grow_step(hashdyn); + 148 13236976 : } 149 : - 150 281785 : void* tommy_hashdyn_remove_existing(tommy_hashdyn* hashdyn, tommy_hashdyn_node* node) + 150 281889 : void* tommy_hashdyn_remove_existing(tommy_hashdyn* hashdyn, tommy_hashdyn_node* node) 151 : { - 152 281785 : tommy_count_t pos = node->key & hashdyn->bucket_mask; + 152 281889 : tommy_count_t pos = node->key & hashdyn->bucket_mask; 153 : - 154 281785 : tommy_list_remove_existing(&hashdyn->bucket[pos], node); + 154 281889 : tommy_list_remove_existing(&hashdyn->bucket[pos], node); 155 : - 156 281785 : --hashdyn->count; + 156 281889 : --hashdyn->count; 157 : - 158 281785 : hashdyn_shrink_step(hashdyn); + 158 281889 : hashdyn_shrink_step(hashdyn); 159 : - 160 281785 : return node->data; + 160 281889 : return node->data; 161 : } 162 : 163 256 : void* tommy_hashdyn_remove(tommy_hashdyn* hashdyn, tommy_search_func* cmp, const void* cmp_arg, tommy_hash_t hash) @@ -253,10 +253,10 @@ 191 5812535 : for (pos = 0; pos < bucket_max; ++pos) { 192 5812288 : tommy_hashdyn_node* node = bucket[pos]; 193 : - 194 13485518 : while (node) { - 195 1860942 : void* data = node->data; - 196 1860942 : node = node->next; - 197 1860942 : func(data); + 194 13485699 : while (node) { + 195 1861123 : void* data = node->data; + 196 1861123 : node = node->next; + 197 1861123 : func(data); 198 : } 199 : } 200 247 : } diff --git a/cov/tommyds/tommyhashdyn.h.func-sort-c.html b/cov/tommyds/tommyhashdyn.h.func-sort-c.html index c86e887e..f39065be 100644 --- a/cov/tommyds/tommyhashdyn.h.func-sort-c.html +++ b/cov/tommyds/tommyhashdyn.h.func-sort-c.html @@ -61,11 +61,11 @@ tommy_hashdyn_bucket - 3109334 + 3109139 tommy_hashdyn_search - 3109334 + 3109139 tommy_hashdyn_count diff --git a/cov/tommyds/tommyhashdyn.h.func.html b/cov/tommyds/tommyhashdyn.h.func.html index adf7080e..79320b42 100644 --- a/cov/tommyds/tommyhashdyn.h.func.html +++ b/cov/tommyds/tommyhashdyn.h.func.html @@ -61,7 +61,7 @@ tommy_hashdyn_bucket - 3109334 + 3109139 tommy_hashdyn_count @@ -69,7 +69,7 @@ tommy_hashdyn_search - 3109334 + 3109139
diff --git a/cov/tommyds/tommyhashdyn.h.gcov.html b/cov/tommyds/tommyhashdyn.h.gcov.html index f1320b97..713bad9b 100644 --- a/cov/tommyds/tommyhashdyn.h.gcov.html +++ b/cov/tommyds/tommyhashdyn.h.gcov.html @@ -267,9 +267,9 @@ 205 : * \param hash Hash of the element to find. 206 : * \return The head of the bucket, or 0 if empty. 207 : */ - 208 3109334 : tommy_inline tommy_hashdyn_node* tommy_hashdyn_bucket(tommy_hashdyn* hashdyn, tommy_hash_t hash) + 208 3109139 : tommy_inline tommy_hashdyn_node* tommy_hashdyn_bucket(tommy_hashdyn* hashdyn, tommy_hash_t hash) 209 : { - 210 3109334 : return hashdyn->bucket[hash & hashdyn->bucket_mask]; + 210 3109139 : return hashdyn->bucket[hash & hashdyn->bucket_mask]; 211 : } 212 : 213 : /** @@ -282,17 +282,17 @@ 220 : * \param hash Hash of the element to find. 221 : * \return The first element found, or 0 if none. 222 : */ - 223 3109334 : tommy_inline void* tommy_hashdyn_search(tommy_hashdyn* hashdyn, tommy_search_func* cmp, const void* cmp_arg, tommy_hash_t hash) + 223 3109139 : tommy_inline void* tommy_hashdyn_search(tommy_hashdyn* hashdyn, tommy_search_func* cmp, const void* cmp_arg, tommy_hash_t hash) 224 : { - 225 3109334 : tommy_hashdyn_node* i = tommy_hashdyn_bucket(hashdyn, hash); + 225 3109139 : tommy_hashdyn_node* i = tommy_hashdyn_bucket(hashdyn, hash); 226 : - 227 6902625 : while (i) { + 227 6897799 : while (i) { 228 : /* we first check if the hash matches, as in the same bucket we may have multiples hash values */ - 229 1848605 : if (i->key == hash && cmp(cmp_arg, i->data) == 0) - 230 1164648 : return i->data; - 231 683957 : i = i->next; + 229 1844197 : if (i->key == hash && cmp(cmp_arg, i->data) == 0) + 230 1164676 : return i->data; + 231 679521 : i = i->next; 232 : } - 233 1944686 : return 0; + 233 1944463 : return 0; 234 : } 235 : 236 : /** diff --git a/cov/tommyds/tommylist.c.func-sort-c.html b/cov/tommyds/tommylist.c.func-sort-c.html index c7f7ae85..fbb6a7a9 100644 --- a/cov/tommyds/tommylist.c.func-sort-c.html +++ b/cov/tommyds/tommylist.c.func-sort-c.html @@ -61,11 +61,11 @@ tommy_list_sort - 2469 + 2481 tommy_list_set - 1684 + 1693
diff --git a/cov/tommyds/tommylist.c.func.html b/cov/tommyds/tommylist.c.func.html index 1d205156..9a83a9d4 100644 --- a/cov/tommyds/tommylist.c.func.html +++ b/cov/tommyds/tommylist.c.func.html @@ -61,11 +61,11 @@ tommy_list_set - 1684 + 1693 tommy_list_sort - 2469 + 2481
diff --git a/cov/tommyds/tommylist.c.gcov.html b/cov/tommyds/tommylist.c.gcov.html index 05b56801..a168b925 100644 --- a/cov/tommyds/tommylist.c.gcov.html +++ b/cov/tommyds/tommylist.c.gcov.html @@ -93,31 +93,31 @@ 31 : /** \internal 32 : * Setup a list. 33 : */ - 34 1684 : tommy_inline void tommy_list_set(tommy_list* list, tommy_node* head, tommy_node* tail) + 34 1693 : tommy_inline void tommy_list_set(tommy_list* list, tommy_node* head, tommy_node* tail) 35 : { - 36 1684 : head->prev = tail; - 37 1684 : tail->next = 0; - 38 1684 : *list = head; - 39 1684 : } + 36 1693 : head->prev = tail; + 37 1693 : tail->next = 0; + 38 1693 : *list = head; + 39 1693 : } 40 : - 41 2469 : void tommy_list_sort(tommy_list* list, tommy_compare_func* cmp) + 41 2481 : void tommy_list_sort(tommy_list* list, tommy_compare_func* cmp) 42 : { 43 : tommy_chain chain; 44 : tommy_node* head; 45 : - 46 2469 : if (tommy_list_empty(list)) - 47 3254 : return; + 46 2481 : if (tommy_list_empty(list)) + 47 3269 : return; 48 : - 49 1684 : head = tommy_list_head(list); + 49 1693 : head = tommy_list_head(list); 50 : 51 : /* create a chain from the list */ - 52 1684 : chain.head = head; - 53 1684 : chain.tail = head->prev; + 52 1693 : chain.head = head; + 53 1693 : chain.tail = head->prev; 54 : - 55 1684 : tommy_chain_mergesort(&chain, cmp); + 55 1693 : tommy_chain_mergesort(&chain, cmp); 56 : 57 : /* restore the list */ - 58 1684 : tommy_list_set(list, chain.head, chain.tail); + 58 1693 : tommy_list_set(list, chain.head, chain.tail); 59 : } 60 : diff --git a/cov/tommyds/tommylist.h.func-sort-c.html b/cov/tommyds/tommylist.h.func-sort-c.html index e3c06b4f..2f8e1e22 100644 --- a/cov/tommyds/tommylist.h.func-sort-c.html +++ b/cov/tommyds/tommylist.h.func-sort-c.html @@ -61,23 +61,23 @@ tommy_list_head - 25314296 + 25314845 tommy_list_insert_first - 23369043 + 23362955 tommy_list_insert_tail - 18382517 + 18382476 tommy_list_insert_tail_not_empty - 11092002 + 11097281 tommy_list_remove_existing - 339841 + 340001 tommy_list_concat @@ -85,19 +85,19 @@ tommy_list_init - 11842 + 11898 tommy_list_foreach - 7613 + 7614 tommy_list_empty - 4369 + 4384 tommy_list_count - 258 + 259 tommy_list_tail diff --git a/cov/tommyds/tommylist.h.func.html b/cov/tommyds/tommylist.h.func.html index a181f52a..9e435b68 100644 --- a/cov/tommyds/tommylist.h.func.html +++ b/cov/tommyds/tommylist.h.func.html @@ -65,39 +65,39 @@ tommy_list_count - 258 + 259 tommy_list_empty - 4369 + 4384 tommy_list_foreach - 7613 + 7614 tommy_list_head - 25314296 + 25314845 tommy_list_init - 11842 + 11898 tommy_list_insert_first - 23369043 + 23362955 tommy_list_insert_tail - 18382517 + 18382476 tommy_list_insert_tail_not_empty - 11092002 + 11097281 tommy_list_remove_existing - 339841 + 340001 tommy_list_tail diff --git a/cov/tommyds/tommylist.h.gcov.html b/cov/tommyds/tommylist.h.gcov.html index 147bca17..f7401298 100644 --- a/cov/tommyds/tommylist.h.gcov.html +++ b/cov/tommyds/tommylist.h.gcov.html @@ -173,18 +173,18 @@ 111 : * Initializes the list. 112 : * The list is completely inplace, so it doesn't need to be deinitialized. 113 : */ - 114 11842 : tommy_inline void tommy_list_init(tommy_list* list) + 114 11898 : tommy_inline void tommy_list_init(tommy_list* list) 115 : { - 116 11842 : *list = 0; - 117 11842 : } + 116 11898 : *list = 0; + 117 11898 : } 118 : 119 : /** 120 : * Gets the head of the list. 121 : * \return The head node. For empty lists 0 is returned. 122 : */ - 123 25314296 : tommy_inline tommy_node* tommy_list_head(tommy_list* list) + 123 25314845 : tommy_inline tommy_node* tommy_list_head(tommy_list* list) 124 : { - 125 25314296 : return *list; + 125 25314845 : return *list; 126 : } 127 : 128 : /** @@ -206,16 +206,16 @@ 144 : * \param list The list to initialize. 145 : * \param node The node to insert. 146 : */ - 147 23369043 : tommy_inline void tommy_list_insert_first(tommy_list* list, tommy_node* node) + 147 23362955 : tommy_inline void tommy_list_insert_first(tommy_list* list, tommy_node* node) 148 : { 149 : /* one element "circular" prev list */ - 150 23369043 : node->prev = node; + 150 23362955 : node->prev = node; 151 : 152 : /* one element "0 terminated" next list */ - 153 23369043 : node->next = 0; + 153 23362955 : node->next = 0; 154 : - 155 23369043 : *list = node; - 156 23369043 : } + 155 23362955 : *list = node; + 156 23362955 : } 157 : 158 : /** \internal 159 : * Inserts an element at the head of a not empty list. @@ -243,16 +243,16 @@ 181 : * \param head The node at the list head. It cannot be 0. 182 : * \param node The node to insert. 183 : */ - 184 11092002 : tommy_inline void tommy_list_insert_tail_not_empty(tommy_node* head, tommy_node* node) + 184 11097281 : tommy_inline void tommy_list_insert_tail_not_empty(tommy_node* head, tommy_node* node) 185 : { 186 : /* insert in the "circular" prev list */ - 187 11092002 : node->prev = head->prev; - 188 11092002 : head->prev = node; + 187 11097281 : node->prev = head->prev; + 188 11097281 : head->prev = node; 189 : 190 : /* insert in the "0 terminated" next list */ - 191 11092002 : node->next = 0; - 192 11092002 : node->prev->next = node; - 193 11092002 : } + 191 11097281 : node->next = 0; + 192 11097281 : node->prev->next = node; + 193 11097281 : } 194 : 195 : /** 196 : * Inserts an element at the head of a list. @@ -276,17 +276,17 @@ 214 : * \param node The node to insert. 215 : * \param data The object containing the node. It's used to set the tommy_node::data field of the node. 216 : */ - 217 18382517 : tommy_inline void tommy_list_insert_tail(tommy_list* list, tommy_node* node, void* data) + 217 18382476 : tommy_inline void tommy_list_insert_tail(tommy_list* list, tommy_node* node, void* data) 218 : { - 219 18382517 : tommy_node* head = tommy_list_head(list); + 219 18382476 : tommy_node* head = tommy_list_head(list); 220 : - 221 18382517 : if (head) - 222 9176575 : tommy_list_insert_tail_not_empty(head, node); + 221 18382476 : if (head) + 222 9182164 : tommy_list_insert_tail_not_empty(head, node); 223 : else - 224 9205942 : tommy_list_insert_first(list, node); + 224 9200312 : tommy_list_insert_first(list, node); 225 : - 226 18382517 : node->data = data; - 227 18382517 : } + 226 18382476 : node->data = data; + 227 18382476 : } 228 : 229 : /** \internal 230 : * Removes an element from the head of a not empty list. @@ -314,23 +314,23 @@ 252 : * \param node The node to remove. The node must be in the list. 253 : * \return The tommy_node::data field of the node removed. 254 : */ - 255 339841 : tommy_inline void* tommy_list_remove_existing(tommy_list* list, tommy_node* node) + 255 340001 : tommy_inline void* tommy_list_remove_existing(tommy_list* list, tommy_node* node) 256 : { - 257 339841 : tommy_node* head = tommy_list_head(list); + 257 340001 : tommy_node* head = tommy_list_head(list); 258 : 259 : /* remove from the "circular" prev list */ - 260 339841 : if (node->next) - 261 116843 : node->next->prev = node->prev; + 260 340001 : if (node->next) + 261 117029 : node->next->prev = node->prev; 262 : else - 263 222998 : head->prev = node->prev; /* the last */ + 263 222972 : head->prev = node->prev; /* the last */ 264 : 265 : /* remove from the "0 terminated" next list */ - 266 339841 : if (head == node) - 267 237549 : *list = node->next; /* the new head, in case 0 */ + 266 340001 : if (head == node) + 267 237639 : *list = node->next; /* the new head, in case 0 */ 268 : else - 269 102292 : node->prev->next = node->next; + 269 102362 : node->prev->next = node->next; 270 : - 271 339841 : return node->data; + 271 340001 : return node->data; 272 : } 273 : 274 : /** @@ -349,24 +349,24 @@ 287 : /* if the second is empty, nothing to do */ 288 63152 : second_head = tommy_list_head(second); 289 63152 : if (second_head == 0) - 290 55791 : return; + 290 55818 : return; 291 : 292 : /* if the first is empty, copy the second */ - 293 7361 : first_head = tommy_list_head(first); - 294 7361 : if (first_head == 0) { - 295 6496 : *first = *second; - 296 6496 : return; + 293 7334 : first_head = tommy_list_head(first); + 294 7334 : if (first_head == 0) { + 295 6443 : *first = *second; + 296 6443 : return; 297 : } 298 : 299 : /* tail of the first list */ - 300 865 : first_tail = first_head->prev; + 300 891 : first_tail = first_head->prev; 301 : 302 : /* set the "circular" prev list */ - 303 865 : first_head->prev = second_head->prev; - 304 865 : second_head->prev = first_tail; + 303 891 : first_head->prev = second_head->prev; + 304 891 : second_head->prev = first_tail; 305 : 306 : /* set the "0 terminated" next list */ - 307 865 : first_tail->next = second_head; + 307 891 : first_tail->next = second_head; 308 : } 309 : 310 : /** @@ -382,26 +382,26 @@ 320 : * Checks if empty. 321 : * \return If the list is empty. 322 : */ - 323 4369 : tommy_inline tommy_bool_t tommy_list_empty(tommy_list* list) + 323 4384 : tommy_inline tommy_bool_t tommy_list_empty(tommy_list* list) 324 : { - 325 4369 : return tommy_list_head(list) == 0; + 325 4384 : return tommy_list_head(list) == 0; 326 : } 327 : 328 : /** 329 : * Gets the number of elements. 330 : * \note This operation is O(n). 331 : */ - 332 258 : tommy_inline tommy_count_t tommy_list_count(tommy_list* list) + 332 259 : tommy_inline tommy_count_t tommy_list_count(tommy_list* list) 333 : { - 334 258 : tommy_count_t count = 0; - 335 258 : tommy_node* i = tommy_list_head(list); + 334 259 : tommy_count_t count = 0; + 335 259 : tommy_node* i = tommy_list_head(list); 336 : - 337 2059 : while (i) { - 338 1543 : ++count; - 339 1543 : i = i->next; + 337 2067 : while (i) { + 338 1549 : ++count; + 339 1549 : i = i->next; 340 : } 341 : - 342 258 : return count; + 342 259 : return count; 343 : } 344 : 345 : /** @@ -432,16 +432,16 @@ 370 : * tommy_list_foreach(&list, free); 371 : * \endcode 372 : */ - 373 7613 : tommy_inline void tommy_list_foreach(tommy_list* list, tommy_foreach_func* func) + 373 7614 : tommy_inline void tommy_list_foreach(tommy_list* list, tommy_foreach_func* func) 374 : { - 375 7613 : tommy_node* node = tommy_list_head(list); + 375 7614 : tommy_node* node = tommy_list_head(list); 376 : - 377 3679790 : while (node) { - 378 3664564 : void* data = node->data; - 379 3664564 : node = node->next; - 380 3664564 : func(data); + 377 3679847 : while (node) { + 378 3664619 : void* data = node->data; + 379 3664619 : node = node->next; + 380 3664619 : func(data); 381 : } - 382 7613 : } + 382 7614 : } 383 : 384 : /** 385 : * Calls the specified function with an argument for each element in the list. diff --git a/cov/tommyds/tommytree.c.func-sort-c.html b/cov/tommyds/tommytree.c.func-sort-c.html index 7d9ddaea..027f2e99 100644 --- a/cov/tommyds/tommytree.c.func-sort-c.html +++ b/cov/tommyds/tommytree.c.func-sort-c.html @@ -61,63 +61,63 @@ tommy_tree_search_node - 136763359 + 136779062 tommy_tree_delta - 112389685 + 112389261 tommy_tree_balance - 104883364 + 104882737 tommy_tree_insert_node - 96203762 + 96201715 tommy_tree_foreach_arg_node - 26344201 + 26344145 tommy_tree_search_compare - 12302451 + 12303747 tommy_tree_rotate_left - 7494888 + 7495135 tommy_tree_insert - 7471241 + 7471049 tommy_tree_foreach_node - 7052356 + 7052312 tommy_tree_remove_node - 790764 + 791807 tommy_tree_move_right - 186865 + 187170 tommy_tree_rotate_right - 171259 + 171066 tommy_tree_remove - 79604 + 79718 tommy_tree_foreach_arg - 5941 + 5965 tommy_tree_init - 3159 + 3171 tommy_tree_foreach diff --git a/cov/tommyds/tommytree.c.func.html b/cov/tommyds/tommytree.c.func.html index df90989b..36001430 100644 --- a/cov/tommyds/tommytree.c.func.html +++ b/cov/tommyds/tommytree.c.func.html @@ -61,11 +61,11 @@ tommy_tree_balance - 104883364 + 104882737 tommy_tree_delta - 112389685 + 112389261 tommy_tree_foreach @@ -73,27 +73,27 @@ tommy_tree_foreach_arg - 5941 + 5965 tommy_tree_foreach_arg_node - 26344201 + 26344145 tommy_tree_foreach_node - 7052356 + 7052312 tommy_tree_init - 3159 + 3171 tommy_tree_insert - 7471241 + 7471049 tommy_tree_insert_node - 96203762 + 96201715 tommy_tree_memory_usage @@ -101,11 +101,11 @@ tommy_tree_move_right - 186865 + 187170 tommy_tree_remove - 79604 + 79718 tommy_tree_remove_existing @@ -113,15 +113,15 @@ tommy_tree_remove_node - 790764 + 791807 tommy_tree_rotate_left - 7494888 + 7495135 tommy_tree_rotate_right - 171259 + 171066 tommy_tree_search @@ -129,11 +129,11 @@ tommy_tree_search_compare - 12302451 + 12303747 tommy_tree_search_node - 136763359 + 136779062
diff --git a/cov/tommyds/tommytree.c.gcov.html b/cov/tommyds/tommytree.c.gcov.html index cfbcb983..ffe0c07f 100644 --- a/cov/tommyds/tommytree.c.gcov.html +++ b/cov/tommyds/tommytree.c.gcov.html @@ -94,104 +94,104 @@ 32 : /******************************************************************************/ 33 : /* tree */ 34 : - 35 3159 : void tommy_tree_init(tommy_tree* tree, tommy_compare_func* cmp) + 35 3171 : void tommy_tree_init(tommy_tree* tree, tommy_compare_func* cmp) 36 : { - 37 3159 : tree->root = 0; - 38 3159 : tree->count = 0; - 39 3159 : tree->cmp = cmp; - 40 3159 : } + 37 3171 : tree->root = 0; + 38 3171 : tree->count = 0; + 39 3171 : tree->cmp = cmp; + 40 3171 : } 41 : - 42 112389685 : static int tommy_tree_delta(tommy_tree_node* root) + 42 112389261 : static int tommy_tree_delta(tommy_tree_node* root) 43 : { - 44 112389685 : int left_height = root->prev ? root->prev->key : 0; - 45 112389685 : int right_height = root->next ? root->next->key : 0; + 44 112389261 : int left_height = root->prev ? root->prev->key : 0; + 45 112389261 : int right_height = root->next ? root->next->key : 0; 46 : - 47 112389685 : return left_height - right_height; + 47 112389261 : return left_height - right_height; 48 : } 49 : 50 : /* AVL tree operations */ 51 : static tommy_tree_node* tommy_tree_balance(tommy_tree_node*); 52 : - 53 7494888 : static tommy_tree_node* tommy_tree_rotate_left(tommy_tree_node* root) + 53 7495135 : static tommy_tree_node* tommy_tree_rotate_left(tommy_tree_node* root) 54 : { - 55 7494888 : tommy_tree_node* next = root->next; + 55 7495135 : tommy_tree_node* next = root->next; 56 : - 57 7494888 : root->next = next->prev; + 57 7495135 : root->next = next->prev; 58 : - 59 7494888 : next->prev = tommy_tree_balance(root); + 59 7495135 : next->prev = tommy_tree_balance(root); 60 : - 61 7494888 : return tommy_tree_balance(next); + 61 7495135 : return tommy_tree_balance(next); 62 : } 63 : - 64 171259 : static tommy_tree_node* tommy_tree_rotate_right(tommy_tree_node* root) + 64 171066 : static tommy_tree_node* tommy_tree_rotate_right(tommy_tree_node* root) 65 : { - 66 171259 : tommy_tree_node* prev = root->prev; + 66 171066 : tommy_tree_node* prev = root->prev; 67 : - 68 171259 : root->prev = prev->next; + 68 171066 : root->prev = prev->next; 69 : - 70 171259 : prev->next = tommy_tree_balance(root); + 70 171066 : prev->next = tommy_tree_balance(root); 71 : - 72 171259 : return tommy_tree_balance(prev); + 72 171066 : return tommy_tree_balance(prev); 73 : } 74 : - 75 186865 : static tommy_tree_node* tommy_tree_move_right(tommy_tree_node* root, tommy_tree_node* node) + 75 187170 : static tommy_tree_node* tommy_tree_move_right(tommy_tree_node* root, tommy_tree_node* node) 76 : { - 77 186865 : if (!root) - 78 79476 : return node; + 77 187170 : if (!root) + 78 79590 : return node; 79 : - 80 107389 : root->next = tommy_tree_move_right(root->next, node); + 80 107580 : root->next = tommy_tree_move_right(root->next, node); 81 : - 82 107389 : return tommy_tree_balance(root); + 82 107580 : return tommy_tree_balance(root); 83 : } 84 : - 85 104883364 : static tommy_tree_node* tommy_tree_balance(tommy_tree_node* root) + 85 104882737 : static tommy_tree_node* tommy_tree_balance(tommy_tree_node* root) 86 : { - 87 104883364 : int delta = tommy_tree_delta(root); + 87 104882737 : int delta = tommy_tree_delta(root); 88 : - 89 104883364 : if (delta < -1) { - 90 7377984 : if (tommy_tree_delta(root->next) > 0) - 91 42922 : root->next = tommy_tree_rotate_right(root->next); - 92 7377984 : return tommy_tree_rotate_left(root); + 89 104882737 : if (delta < -1) { + 90 7378375 : if (tommy_tree_delta(root->next) > 0) + 91 42917 : root->next = tommy_tree_rotate_right(root->next); + 92 7378375 : return tommy_tree_rotate_left(root); 93 : } 94 : - 95 97505380 : if (delta > 1) { - 96 128337 : if (tommy_tree_delta(root->prev) < 0) - 97 116904 : root->prev = tommy_tree_rotate_left(root->prev); - 98 128337 : return tommy_tree_rotate_right(root); + 95 97504362 : if (delta > 1) { + 96 128149 : if (tommy_tree_delta(root->prev) < 0) + 97 116760 : root->prev = tommy_tree_rotate_left(root->prev); + 98 128149 : return tommy_tree_rotate_right(root); 99 : } 100 : 101 : /* recompute key */ - 102 97377043 : root->key = 0; + 102 97376213 : root->key = 0; 103 : - 104 97377043 : if (root->prev && root->prev->key > root->key) - 105 78773858 : root->key = root->prev->key; + 104 97376213 : if (root->prev && root->prev->key > root->key) + 105 78773173 : root->key = root->prev->key; 106 : - 107 97377043 : if (root->next && root->next->key > root->key) - 108 44909116 : root->key = root->next->key; + 107 97376213 : if (root->next && root->next->key > root->key) + 108 44912285 : root->key = root->next->key; 109 : 110 : /* count itself */ - 111 97377043 : root->key += 1; + 111 97376213 : root->key += 1; 112 : - 113 97377043 : return root; + 113 97376213 : return root; 114 : } 115 : - 116 96203762 : static tommy_tree_node* tommy_tree_insert_node(tommy_compare_func* cmp, tommy_tree_node* root, tommy_tree_node** let) + 116 96201715 : static tommy_tree_node* tommy_tree_insert_node(tommy_compare_func* cmp, tommy_tree_node* root, tommy_tree_node** let) 117 : { 118 : int c; 119 : - 120 96203762 : if (!root) - 121 7471240 : return *let; + 120 96201715 : if (!root) + 121 7471048 : return *let; 122 : - 123 88732522 : c = cmp((*let)->data, root->data); + 123 88730667 : c = cmp((*let)->data, root->data); 124 : - 125 88732522 : if (c < 0) { - 126 1537706 : root->prev = tommy_tree_insert_node(cmp, root->prev, let); - 127 1537706 : return tommy_tree_balance(root); + 125 88730667 : if (c < 0) { + 126 1532013 : root->prev = tommy_tree_insert_node(cmp, root->prev, let); + 127 1532013 : return tommy_tree_balance(root); 128 : } 129 : - 130 87194816 : if (c > 0) { - 131 87194815 : root->next = tommy_tree_insert_node(cmp, root->next, let); - 132 87194815 : return tommy_tree_balance(root); + 130 87198654 : if (c > 0) { + 131 87198653 : root->next = tommy_tree_insert_node(cmp, root->next, let); + 132 87198653 : return tommy_tree_balance(root); 133 : } 134 : 135 : /* already present, set the return pointer */ @@ -200,78 +200,78 @@ 138 1 : return root; 139 : } 140 : - 141 7471241 : void* tommy_tree_insert(tommy_tree* tree, tommy_tree_node* node, void* data) + 141 7471049 : void* tommy_tree_insert(tommy_tree* tree, tommy_tree_node* node, void* data) 142 : { - 143 7471241 : tommy_tree_node* insert = node; + 143 7471049 : tommy_tree_node* insert = node; 144 : - 145 7471241 : insert->data = data; - 146 7471241 : insert->prev = 0; - 147 7471241 : insert->next = 0; - 148 7471241 : insert->key = 0; + 145 7471049 : insert->data = data; + 146 7471049 : insert->prev = 0; + 147 7471049 : insert->next = 0; + 148 7471049 : insert->key = 0; 149 : - 150 7471241 : tree->root = tommy_tree_insert_node(tree->cmp, tree->root, &insert); + 150 7471049 : tree->root = tommy_tree_insert_node(tree->cmp, tree->root, &insert); 151 : - 152 7471241 : if (insert == node) - 153 7471240 : ++tree->count; + 152 7471049 : if (insert == node) + 153 7471048 : ++tree->count; 154 : - 155 7471241 : return insert->data; + 155 7471049 : return insert->data; 156 : } 157 : - 158 790764 : static tommy_tree_node* tommy_tree_remove_node(tommy_compare_func* cmp, tommy_tree_node* root, void* data, tommy_tree_node** let) + 158 791807 : static tommy_tree_node* tommy_tree_remove_node(tommy_compare_func* cmp, tommy_tree_node* root, void* data, tommy_tree_node** let) 159 : { 160 : int c; 161 : - 162 790764 : if (!root) + 162 791807 : if (!root) 163 128 : return 0; 164 : - 165 790636 : c = cmp(data, root->data); + 165 791679 : c = cmp(data, root->data); 166 : - 167 790636 : if (c < 0) { - 168 303798 : root->prev = tommy_tree_remove_node(cmp, root->prev, data, let); - 169 303798 : return tommy_tree_balance(root); + 167 791679 : if (c < 0) { + 168 304695 : root->prev = tommy_tree_remove_node(cmp, root->prev, data, let); + 169 304695 : return tommy_tree_balance(root); 170 : } 171 : - 172 486838 : if (c > 0) { - 173 407362 : root->next = tommy_tree_remove_node(cmp, root->next, data, let); - 174 407362 : return tommy_tree_balance(root); + 172 486984 : if (c > 0) { + 173 407394 : root->next = tommy_tree_remove_node(cmp, root->next, data, let); + 174 407394 : return tommy_tree_balance(root); 175 : } 176 : 177 : /* found */ - 178 79476 : *let = root; + 178 79590 : *let = root; 179 : - 180 79476 : return tommy_tree_move_right(root->prev, root->next); + 180 79590 : return tommy_tree_move_right(root->prev, root->next); 181 : } 182 : - 183 79604 : void* tommy_tree_remove(tommy_tree* tree, void* data) + 183 79718 : void* tommy_tree_remove(tommy_tree* tree, void* data) 184 : { - 185 79604 : tommy_tree_node* node = 0; + 185 79718 : tommy_tree_node* node = 0; 186 : - 187 79604 : tree->root = tommy_tree_remove_node(tree->cmp, tree->root, data, &node); + 187 79718 : tree->root = tommy_tree_remove_node(tree->cmp, tree->root, data, &node); 188 : - 189 79604 : if (!node) + 189 79718 : if (!node) 190 128 : return 0; 191 : - 192 79476 : --tree->count; + 192 79590 : --tree->count; 193 : - 194 79476 : return node->data; + 194 79590 : return node->data; 195 : } 196 : - 197 136763359 : static tommy_tree_node* tommy_tree_search_node(tommy_compare_func* cmp, tommy_tree_node* root, void* data) + 197 136779062 : static tommy_tree_node* tommy_tree_search_node(tommy_compare_func* cmp, tommy_tree_node* root, void* data) 198 : { 199 : int c; 200 : - 201 136763359 : if (!root) - 202 1588540 : return 0; + 201 136779062 : if (!root) + 202 1588658 : return 0; 203 : - 204 135174819 : c = cmp(data, root->data); + 204 135190404 : c = cmp(data, root->data); 205 : - 206 135179988 : if (c < 0) - 207 49127582 : return tommy_tree_search_node(cmp, root->prev, data); + 206 135195696 : if (c < 0) + 207 49136499 : return tommy_tree_search_node(cmp, root->prev, data); 208 : - 209 86052406 : if (c > 0) - 210 75338711 : return tommy_tree_search_node(cmp, root->next, data); + 209 86059197 : if (c > 0) + 210 75344385 : return tommy_tree_search_node(cmp, root->next, data); 211 : - 212 10713695 : return root; + 212 10714812 : return root; 213 : } 214 : 215 2 : void* tommy_tree_search(tommy_tree* tree, void* data) @@ -284,14 +284,14 @@ 222 1 : return node->data; 223 : } 224 : - 225 12302451 : void* tommy_tree_search_compare(tommy_tree* tree, tommy_compare_func* cmp, void* cmp_arg) + 225 12303747 : void* tommy_tree_search_compare(tommy_tree* tree, tommy_compare_func* cmp, void* cmp_arg) 226 : { - 227 12302451 : tommy_tree_node* node = tommy_tree_search_node(cmp, tree->root, cmp_arg); + 227 12303747 : tommy_tree_node* node = tommy_tree_search_node(cmp, tree->root, cmp_arg); 228 : - 229 12302205 : if (!node) - 230 1588572 : return 0; + 229 12303453 : if (!node) + 230 1588690 : return 0; 231 : - 232 10713633 : return node->data; + 232 10714763 : return node->data; 233 : } 234 : 235 128 : void* tommy_tree_remove_existing(tommy_tree* tree, tommy_tree_node* node) @@ -303,21 +303,21 @@ 241 128 : return data; 242 : } 243 : - 244 7052356 : static void tommy_tree_foreach_node(tommy_tree_node* root, tommy_foreach_func* func) + 244 7052312 : static void tommy_tree_foreach_node(tommy_tree_node* root, tommy_foreach_func* func) 245 : { 246 : tommy_tree_node* next; 247 : - 248 7052356 : if (!root) - 249 10579261 : return; + 248 7052312 : if (!root) + 249 10579195 : return; 250 : - 251 3525451 : tommy_tree_foreach_node(root->prev, func); + 251 3525429 : tommy_tree_foreach_node(root->prev, func); 252 : 253 : /* make a copy in case func is free() */ - 254 3525451 : next = root->next; + 254 3525429 : next = root->next; 255 : - 256 3525451 : func(root->data); + 256 3525429 : func(root->data); 257 : - 258 3525451 : tommy_tree_foreach_node(next, func); + 258 3525429 : tommy_tree_foreach_node(next, func); 259 : } 260 : 261 1454 : void tommy_tree_foreach(tommy_tree* tree, tommy_foreach_func* func) @@ -325,27 +325,27 @@ 263 1454 : tommy_tree_foreach_node(tree->root, func); 264 1454 : } 265 : - 266 26344201 : static void tommy_tree_foreach_arg_node(tommy_tree_node* root, tommy_foreach_arg_func* func, void* arg) + 266 26344145 : static void tommy_tree_foreach_arg_node(tommy_tree_node* root, tommy_foreach_arg_func* func, void* arg) 267 : { 268 : tommy_tree_node* next; 269 : - 270 26344201 : if (!root) - 271 39519272 : return; + 270 26344145 : if (!root) + 271 39519200 : return; 272 : - 273 13169130 : tommy_tree_foreach_arg_node(root->prev, func, arg); + 273 13169090 : tommy_tree_foreach_arg_node(root->prev, func, arg); 274 : 275 : /* make a copy in case func is free() */ - 276 13169130 : next = root->next; + 276 13169090 : next = root->next; 277 : - 278 13169130 : func(arg, root->data); + 278 13169090 : func(arg, root->data); 279 : - 280 13169130 : tommy_tree_foreach_arg_node(next, func, arg); + 280 13169090 : tommy_tree_foreach_arg_node(next, func, arg); 281 : } 282 : - 283 5941 : void tommy_tree_foreach_arg(tommy_tree* tree, tommy_foreach_arg_func* func, void* arg) + 283 5965 : void tommy_tree_foreach_arg(tommy_tree* tree, tommy_foreach_arg_func* func, void* arg) 284 : { - 285 5941 : tommy_tree_foreach_arg_node(tree->root, func, arg); - 286 5941 : } + 285 5965 : tommy_tree_foreach_arg_node(tree->root, func, arg); + 286 5965 : } 287 : 288 1 : tommy_size_t tommy_tree_memory_usage(tommy_tree* tree) 289 : { diff --git a/cov/tommyds/tommytypes.h.func-sort-c.html b/cov/tommyds/tommytypes.h.func-sort-c.html index 0eadd42d..b3aeebb1 100644 --- a/cov/tommyds/tommytypes.h.func-sort-c.html +++ b/cov/tommyds/tommytypes.h.func-sort-c.html @@ -61,11 +61,11 @@ tommy_ilog2_u32 - 10268450 + 10268715 tommy_ctz_u32 - 1684 + 1693 tommy_haszero_u32 diff --git a/cov/tommyds/tommytypes.h.func.html b/cov/tommyds/tommytypes.h.func.html index 94c5e7af..c63029e2 100644 --- a/cov/tommyds/tommytypes.h.func.html +++ b/cov/tommyds/tommytypes.h.func.html @@ -61,7 +61,7 @@ tommy_ctz_u32 - 1684 + 1693 tommy_haszero_u32 @@ -69,7 +69,7 @@ tommy_ilog2_u32 - 10268450 + 10268715
diff --git a/cov/tommyds/tommytypes.h.gcov.html b/cov/tommyds/tommytypes.h.gcov.html index 7eedf268..6244d621 100644 --- a/cov/tommyds/tommytypes.h.gcov.html +++ b/cov/tommyds/tommytypes.h.gcov.html @@ -390,7 +390,7 @@ 328 : * \param value Value to scan. 0 is not allowed. 329 : * \return The index of the most significant bit set. 330 : */ - 331 10268450 : tommy_inline tommy_uint_t tommy_ilog2_u32(tommy_uint32_t value) + 331 10268715 : tommy_inline tommy_uint_t tommy_ilog2_u32(tommy_uint32_t value) 332 : { 333 : #if defined(_MSC_VER) 334 : unsigned long count; @@ -406,7 +406,7 @@ 344 : * So we write "__builtin_clz(x) ^ 31" instead of "31 - __builtin_clz(x)", 345 : * to allow the double xor to be optimized out. 346 : */ - 347 10268450 : return __builtin_clz(value) ^ 31; + 347 10268715 : return __builtin_clz(value) ^ 31; 348 : #else 349 : /* Find the log base 2 of an N-bit integer in O(lg(N)) operations with multiply and lookup */ 350 : /* from http://graphics.stanford.edu/~seander/bithacks.html */ @@ -433,14 +433,14 @@ 371 : * \param value Value to scan. 0 is not allowed. 372 : * \return The index of the least significant bit set. 373 : */ - 374 1684 : tommy_inline tommy_uint_t tommy_ctz_u32(tommy_uint32_t value) + 374 1693 : tommy_inline tommy_uint_t tommy_ctz_u32(tommy_uint32_t value) 375 : { 376 : #if defined(_MSC_VER) 377 : unsigned long count; 378 : _BitScanForward(&count, value); 379 : return count; 380 : #elif defined(__GNUC__) - 381 1684 : return __builtin_ctz(value); + 381 1693 : return __builtin_ctz(value); 382 : #else 383 : /* Count the consecutive zero bits (trailing) on the right with multiply and lookup */ 384 : /* from http://graphics.stanford.edu/~seander/bithacks.html */